123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- {
- Free Pascal port of the OpenPTC C++ library.
- Copyright (C) 2001-2003 Nikolay Nikolov ([email protected])
- Original C++ version by Glenn Fiedler ([email protected])
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- }
- { $INLINE ON}
- Class Function TPTCClipper.clip(Const _area, _clip : TPTCArea) : TPTCArea;
- Var
- left, top, right, bottom : Integer;
- clip_left, clip_top, clip_right, clip_bottom : Integer;
- Begin
- { get in coordinates }
- left := _area.left;
- top := _area.top;
- right := _area.right;
- bottom := _area.bottom;
- { get clip coordinates }
- clip_left := _clip.left;
- clip_top := _clip.top;
- clip_right := _clip.right;
- clip_bottom := _clip.bottom;
- { clip left }
- If left < clip_left Then
- left := clip_left;
- If left > clip_right Then
- left := clip_right;
- { clip top }
- If top < clip_top Then
- top := clip_top;
- If top > clip_bottom Then
- top := clip_bottom;
- { clip right }
- If right < clip_left Then
- right := clip_left;
- If right > clip_right Then
- right := clip_right;
- { clip bottom }
- If bottom < clip_top Then
- bottom := clip_top;
- If bottom > clip_bottom Then
- bottom := clip_bottom;
- clip := TPTCArea.Create(left, top, right, bottom);
- End;
- { clip floating point area against a floating point clip area }
- Procedure TPTCClipper_clip(Var left, top, right, bottom : Real;
- clip_left, clip_top, clip_right, clip_bottom : Real);{ Inline;}
- Begin
- { clip left }
- If left < clip_left Then
- left := clip_left;
- If left > clip_right Then
- left := clip_right;
- { clip top }
- If top < clip_top Then
- top := clip_top;
- If top > clip_bottom Then
- top := clip_bottom;
- { clip right }
- If right < clip_left Then
- right := clip_left;
- If right > clip_right Then
- right := clip_right;
- { clip bottom }
- If bottom < clip_top Then
- bottom := clip_top;
- If bottom > clip_bottom Then
- bottom := clip_bottom;
- End;
- { clip floating point area against clip area }
- Procedure TPTCClipper_clip(Var left, top, right, bottom : Real; Const _clip : TPTCArea);{ Inline;}
- Var
- clip_left, clip_top, clip_right, clip_bottom : Real;
- Begin
- { get floating point clip area }
- clip_left := _clip.left;
- clip_top := _clip.top;
- clip_right := _clip.right;
- clip_bottom := _clip.bottom;
- { clip floating point area against floating point clip area }
- TPTCClipper_clip(left, top, right, bottom, clip_left, clip_top, clip_right, clip_bottom);
- End;
- { snap a floating point area to integer coordinates }
- Procedure TPTCClipper_round(Var left, top, right, bottom : Real);{ Inline;}
- Begin
- left := Round(left);
- top := Round(top);
- right := Round(right);
- bottom := Round(bottom);
- End;
- Class Procedure TPTCClipper.clip(Const source, clip_source, clipped_source,
- destination, clip_destination,
- clipped_destination : TPTCArea);
- Var
- tmp1, tmp2 : TPTCArea;
- source_left, source_top, source_right, source_bottom : Real;
- clipped_source_left, clipped_source_top, clipped_source_right,
- clipped_source_bottom : Real;
- source_delta_left, source_delta_top, source_delta_right,
- source_delta_bottom : Real;
- source_to_destination_x, source_to_destination_y : Real;
- destination_left, destination_top, destination_right,
- destination_bottom : Real;
- adjusted_destination_left, adjusted_destination_top,
- adjusted_destination_right, adjusted_destination_bottom : Real;
- clipped_destination_left, clipped_destination_top,
- clipped_destination_right, clipped_destination_bottom : Real;
- destination_delta_left, destination_delta_top, destination_delta_right,
- destination_delta_bottom : Real;
- destination_to_source_x, destination_to_source_y : Real;
- adjusted_source_left, adjusted_source_top, adjusted_source_right,
- adjusted_source_bottom : Real;
- Begin
- tmp1 := Nil;
- tmp2 := Nil;
- Try
- { expand source area to floating point }
- source_left := source.left;
- source_top := source.top;
- source_right := source.right;
- source_bottom := source.bottom;
- { setup clipped source area }
- clipped_source_left := source_left;
- clipped_source_top := source_top;
- clipped_source_right := source_right;
- clipped_source_bottom := source_bottom;
- { perform clipping on floating point source area }
- TPTCClipper_clip(clipped_source_left, clipped_source_top, clipped_source_right,
- clipped_source_bottom, clip_source);
- { check for early source area clipping exit }
- If (clipped_source_left = clipped_source_right) Or
- (clipped_source_top = clipped_source_bottom) Then
- Begin
- { clipped area is zero }
- tmp1 := TPTCArea.Create(0, 0, 0, 0);
- clipped_source.ASSign(tmp1);
- clipped_destination.ASSign(tmp1);
- Exit;
- End;
- { calculate deltas in source clip }
- source_delta_left := clipped_source_left - source_left;
- source_delta_top := clipped_source_top - source_top;
- source_delta_right := clipped_source_right - source_right;
- source_delta_bottom := clipped_source_bottom - source_bottom;
- { calculate ratio of source area to destination area }
- source_to_destination_x := destination.width / source.width;
- source_to_destination_y := destination.height / source.height;
- { expand destination area to floating point }
- destination_left := destination.left;
- destination_top := destination.top;
- destination_right := destination.right;
- destination_bottom := destination.bottom;
- { calculate adjusted destination area }
- adjusted_destination_left := destination_left + source_delta_left * source_to_destination_x;
- adjusted_destination_top := destination_top + source_delta_top * source_to_destination_y;
- adjusted_destination_right := destination_right + source_delta_right * source_to_destination_x;
- adjusted_destination_bottom := destination_bottom + source_delta_bottom * source_to_destination_y;
- { setup clipped destination area }
- clipped_destination_left := adjusted_destination_left;
- clipped_destination_top := adjusted_destination_top;
- clipped_destination_right := adjusted_destination_right;
- clipped_destination_bottom := adjusted_destination_bottom;
- { perform clipping on floating point destination area }
- TPTCClipper_clip(clipped_destination_left, clipped_destination_top,
- clipped_destination_right, clipped_destination_bottom, clip_destination);
- { check for early destination area clipping exit }
- If (clipped_destination_left = clipped_destination_right) Or
- (clipped_destination_top = clipped_destination_bottom)
- Then
- Begin
- { clipped area is zero }
- tmp1 := TPTCArea.Create(0, 0, 0, 0);
- clipped_source.ASSign(tmp1);
- clipped_destination.ASSign(tmp1);
- Exit;
- End;
- { calculate deltas in destination clip }
- destination_delta_left := clipped_destination_left - adjusted_destination_left;
- destination_delta_top := clipped_destination_top - adjusted_destination_top;
- destination_delta_right := clipped_destination_right - adjusted_destination_right;
- destination_delta_bottom := clipped_destination_bottom - adjusted_destination_bottom;
- { calculate ratio of destination area to source area }
- destination_to_source_x := 1 / source_to_destination_x;
- destination_to_source_y := 1 / source_to_destination_y;
- { calculate adjusted source area }
- adjusted_source_left := clipped_source_left + destination_delta_left * destination_to_source_x;
- adjusted_source_top := clipped_source_top + destination_delta_top * destination_to_source_y;
- adjusted_source_right := clipped_source_right + destination_delta_right * destination_to_source_x;
- adjusted_source_bottom := clipped_source_bottom + destination_delta_bottom * destination_to_source_y;
- { assign adjusted source to clipped source }
- clipped_source_left := adjusted_source_left;
- clipped_source_top := adjusted_source_top;
- clipped_source_right := adjusted_source_right;
- clipped_source_bottom := adjusted_source_bottom;
- { round clipped areas to integer coordinates }
- TPTCClipper_round(clipped_source_left, clipped_source_top,
- clipped_source_right, clipped_source_bottom);
- TPTCClipper_round(clipped_destination_left, clipped_destination_top,
- clipped_destination_right, clipped_destination_bottom);
- { construct clipped area rectangles from rounded floating point areas }
- tmp1 := TPTCArea.Create(Trunc(clipped_source_left),
- Trunc(clipped_source_top),
- Trunc(clipped_source_right),
- Trunc(clipped_source_bottom));
- tmp2 := TPTCArea.Create(Trunc(clipped_destination_left),
- Trunc(clipped_destination_top),
- Trunc(clipped_destination_right),
- Trunc(clipped_destination_bottom));
- clipped_source.ASSign(tmp1);
- clipped_destination.ASSign(tmp2);
- Finally
- tmp1.Free;
- tmp2.Free;
- End;
- End;
|