Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fill region bugs in SynPDF #423

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions SynPdf.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1664,6 +1664,7 @@ TPdfCanvas = class(TObject)
// property getters
function GetDoc: TPdfDocument; {$ifdef HASINLINE}inline;{$endif}
function GetPage: TPdfPage; {$ifdef HASINLINE}inline;{$endif}
function RectExcludeBottomRight(ARect: TRect): TRect;
public
/// create the PDF canvas instance
constructor Create(APdfDoc: TPdfDocument);
Expand Down Expand Up @@ -7518,12 +7519,20 @@ procedure NormalizeRect(var Rect: TPdfRect); overload;
end;
end;

function TPdfCanvas.RectExcludeBottomRight(ARect: TRect): TRect;
begin
Result.Left := ARect.Left;
Result.Top := ARect.Top;
Result.Right := ARect.Right - 1;
Result.Bottom := ARect.Bottom - 1;
end;

function TPdfCanvas.RectI(Rect: TRect; Normalize: boolean): TPdfRect;
begin
result.Left := I2X(Rect.Left);
result.Right := I2X(Rect.Right-1);
result.Right := I2X(Rect.Right);
result.Top := I2Y(Rect.Top);
result.Bottom := I2Y(Rect.Bottom-1);
result.Bottom := I2Y(Rect.Bottom);
if Normalize then
NormalizeRect(result);
end;
Expand Down Expand Up @@ -8945,6 +8954,12 @@ TPdfEnumStatePen = record
width: Single;
end;

TPdfEnumStateBrush = record
null: boolean;
color: integer;
style: integer;
end;

/// a state of the EMF enumeration engine, for the PDF canvas
// - used also for the SaveDC/RestoreDC stack
TPdfEnumState = record
Expand All @@ -8964,11 +8979,7 @@ TPdfEnumState = record
// current selected pen
pen: TPdfEnumStatePen;
// current selected brush
brush: record
null: boolean;
color: integer;
style: integer;
end;
brush: TPdfEnumStateBrush;
// current selected font
font: record
color: integer;
Expand Down Expand Up @@ -9058,6 +9069,9 @@ function EnumEMFFunc(DC: HDC; var Table: THandleTable; R: PEnhMetaRecord;
var i: integer;
InitTransX: XForm;
polytypes: PByteArray;
RegionData: PRgnData;
PtrRect: PRect;
CurrentBrush: TPdfEnumStateBrush;
begin
result := true;
with E.DC[E.nDC] do
Expand Down Expand Up @@ -9224,9 +9238,16 @@ function EnumEMFFunc(DC: HDC; var Table: THandleTable; R: PEnhMetaRecord;
end;
{$endif USE_ARC}
EMR_FILLRGN: begin
MoveFast(E.DC[E.nDC].brush, CurrentBrush, SizeOf(TPdfEnumStateBrush));
E.SelectObjectFromIndex(PEMRFillRgn(R)^.ihBrush);
E.NeedBrushAndPen;
E.FillRectangle(PRgnDataHeader(@PEMRFillRgn(R)^.RgnData[0])^.rcBound,false);
RegionData := PRgnData(@PEMRFillRgn(R)^.RgnData[0]);
PtrRect := PRect(@RegionData.Buffer[0]);
for I := 0 to RegionData.rdh.nCount - 1 do begin
E.FillRectangle(PtrRect^, False);
Inc(PtrRect);
end;
MoveFast(CurrentBrush, E.DC[E.nDC].brush, SizeOf(TPdfEnumStateBrush));
end;
EMR_POLYGON, EMR_POLYLINE, EMR_POLYGON16, EMR_POLYLINE16:
if not brush.null or not pen.null then begin
Expand Down Expand Up @@ -9534,7 +9555,8 @@ function EnumEMFFunc(DC: HDC; var Table: THandleTable; R: PEnhMetaRecord;
EMR_EXTSELECTCLIPRGN:
E.ExtSelectClipRgn(@PEMRExtSelectClipRgn(R)^.RgnData[0],PEMRExtSelectClipRgn(R)^.iMode);
EMR_INTERSECTCLIPRECT:
ClipRgn := E.IntersectClipRect(E.Canvas.BoxI(PEMRIntersectClipRect(r)^.rclClip,true),ClipRgn);
ClipRgn := E.IntersectClipRect(
E.Canvas.BoxI(E.Canvas.RectExcludeBottomRight(PEMRIntersectClipRect(r)^.rclClip), true), ClipRgn);
EMR_SETMAPMODE:
MappingMode := PEMRSetMapMode(R)^.iMode;
EMR_BEGINPATH: begin
Expand Down Expand Up @@ -10278,7 +10300,7 @@ procedure TPdfEnum.ExtSelectClipRgn(data: PRgnDataHeader; iMode: DWord);
var ExtClip: TRect;
begin
try
ExtClip := data^.rcBound;
ExtClip := Canvas.RectExcludeBottomRight(data^.rcBound);
with DC[nDC] do
case iMode of
RGN_COPY: begin
Expand Down