You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RnQ/for.RnQ/Graphics32/GR32_DrawingEx.pas

111 lines
3.1 KiB
Plaintext

unit GR32_DrawingEx;
(* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1 or LGPL 2.1 with linking exception
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Alternatively, the contents of this file may be used under the terms of the
* Free Pascal modified version of the GNU Lesser General Public License
* Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
* of this license are applicable instead of those above.
* Please see the file LICENSE.txt for additional information concerning this
* license.
*
* The Original Code is Graphics32
*
* The Initial Developer of the Original Code is
* Alex A. Denisov
*
* Portions created by the Initial Developer are Copyright (C) 2000-2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
interface
{$I GR32.inc}
uses
{$IFDEF FPC}
LCLIntf,
{$ELSE}
Windows,
{$ENDIF}
GR32, SysUtils;
{ ClipLine }
{ Clips the (X1, Y1)-(X2,Y2) line to the rectangle using Sutherland-Cohen Line
Clipping Algorithm }
function ClipLine(var X1, Y1, X2, Y2: Integer; MinX, MinY, MaxX, MaxY: Integer): Boolean;
type
TBlendLineProc = procedure(Src, Dst: PColor32; Count: Integer);
implementation
uses
GR32_LowLevel, GR32_Blend, GR32_Math;
function ClipLine(var X1, Y1, X2, Y2: Integer; MinX, MinY, MaxX, MaxY: Integer): Boolean;
var
C1, C2: Integer;
V: Integer;
begin
{ Get edge codes }
C1 := Ord(X1 < MinX) + Ord(X1 > MaxX) shl 1 + Ord(Y1 < MinY) shl 2 + Ord(Y1 > MaxY) shl 3;
C2 := Ord(X2 < MinX) + Ord(X2 > MaxX) shl 1 + Ord(Y2 < MinY) shl 2 + Ord(Y2 > MaxY) shl 3;
if ((C1 and C2) = 0) and ((C1 or C2) <> 0) then
begin
if (C1 and 12) <> 0 then
begin
if C1 < 8 then V := MinY else V := MaxY;
Inc(X1, MulDiv(V - Y1, X2 - X1, Y2 - Y1));
Y1 := V;
C1 := Ord(X1 < MinX) + Ord(X1 > MaxX) shl 1;
end;
if (C2 and 12) <> 0 then
begin
if C2 < 8 then V := MinY else V := MaxY;
Inc(X2, MulDiv(V - Y2, X2 - X1, Y2 - Y1));
Y2 := V;
C2 := Ord(X2 < MinX) + Ord(X2 > MaxX) shl 1;
end;
if ((C1 and C2) = 0) and ((C1 or C2) <> 0) then
begin
if C1 <> 0 then
begin
if C1 = 1 then V := MinX else V := MaxX;
Inc(Y1, MulDiv(V - X1, Y2 - Y1, X2 - X1));
X1 := V;
C1 := 0;
end;
if C2 <> 0 then
begin
if C2 = 1 then V := MinX else V := MaxX;
Inc(Y2, MulDiv(V - X2, Y2 - Y1, X2 - X1));
X2 := V;
C2 := 0;
end;
end;
end;
Result := (C1 or C2) = 0;
end;
end.