#1 2024-05-14 13:42:27

jonjbar
Member
Registered: 2012-12-27
Posts: 37

Regression: simple EMF file is drawn with an overlapping/missing rect

Hi,
The latest version of SynPDF2 seem to have a regression which wasn't present in SynPDF1: a part of the content is not drawn.
Screenshot: https://snipboard.io/a7T6tn.jpg
Sample project with source WMF, generate PDF and screenshot of the problem: https://we.tl/t-bLUC4A84kA
I'm using Delphi 12 in 32/64-bit mode with latest SynPDF2 from Git.
I thought I'd post it here before I open a bug on GitHub but I can do so if you wish.
Thank you for any help.

Last edited by jonjbar (2024-05-14 13:44:44)

Offline

#2 2024-05-14 13:59:55

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Did you try with a previous version of mORMot 2?

Did you try e.g. BEFORE https://github.com/synopse/mORMot2/comm … ca832a5931 ?
or BEFORE https://github.com/synopse/mORMot2/comm … 928c8b882b ?

My guess is that it is, once again, a regression introduced by a pull request from external source...
sad

Offline

#3 2024-05-14 14:34:51

jonjbar
Member
Registered: 2012-12-27
Posts: 37

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Thank you very much for your help.
I can confirm that this commit introduces the problem: https://github.com/synopse/mORMot2/comm … 928c8b882b
I see that is has been discussed in that thread so I'll post there: https://synopse.info/forum/viewtopic.php?pid=40358

Offline

#4 2024-05-14 15:21:44

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

The interpretation of the EMR_EXTSELECTCLIPRGN inside the WMF indeed seems to cut away the wrong part in the PDF.

R0109: [034] EMR_RESTOREDC    (s=12)    {iRelative(-1)}
R0110: [030] EMR_INTERSECTCLIPRECT    (s=24)    {rclClip(16,82,776,113)}
R0111: [037] EMR_SELECTOBJECT    (s=12)    {Stock object: 13=OBJ_FONT}
R0112: [040] EMR_DELETEOBJECT    (s=12)    {ihObject(6)}
R0113: [037] EMR_SELECTOBJECT    (s=12)    {Table object: 4=OBJ_FONT}
R0114: [024] EMR_SETTEXTCOLOR    (s=12)    {0x00000000}
R0115: [022] EMR_SETTEXTALIGN    (s=12)    {iMode(24= TA_BASELINE)}
R0116: [075] EMR_EXTSELECTCLIPRGN    (s=64)    {iMode(5=RGN_COPY), RGNDATA[ptr:0x071d0cb8, size:48, box(110,176,882,314)]}
R0117: [022] EMR_SETTEXTALIGN    (s=12)    {iMode(24= TA_BASELINE)}
R0118: [022] EMR_SETTEXTALIGN    (s=12)    {iMode(24= TA_BASELINE)}
R0119: [022] EMR_SETTEXTALIGN    (s=12)    {iMode(24= TA_BASELINE)}

This could be fixed by reverting back to just removing the complete TPdfEnum.ExtSelectClipRgn() to do nothing (putting an exit above fixes it).
But that's not a real solution of course.
Better would be to find out why the values (110,176,882,314) are interpreted wrong.

I'll try to see how this is done with the other (more developed solutions) for GDI rendering.

Offline

#5 2024-05-14 16:27:01

jonjbar
Member
Registered: 2012-12-27
Posts: 37

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

So I've added debug code to visualize the clipping rectangle and it looks like it is simply offset by the PDF page's margins! Could we simply subtract the margins from there ? How to get them ?
Screenshot: https://snipboard.io/MxHLvX.jpg

Test code:

procedure TPdfEnum.ExtSelectClipRgn(data: PEMRExtSelectClipRgn);
var
  RGNs: PRgnData;
  i: Integer;
  RCT: TRect;
  ClipRect: TPdfBox;
begin
  // see http://www.codeproject.com/Articles/1944/Guide-to-WIN-Regions
  if data^.iMode <> RGN_COPY then exit; // we are handling RGN_COPY (5) only..
  if not DC[nDC].ClipRgnNull then // if current clip then finish
  begin
    Canvas.GRestore;
    Canvas.NewPath;
    Canvas.fNewPath := False;
    DC[nDC].ClipRgnNull := True;
    fFillColor := -1;
  end;
  if Data^.cbRgnData > 0 then
  begin
    Canvas.GSave;
    Canvas.NewPath;
    DC[nDC].ClipRgnNull := False;
    RGNs := @Data^.RgnData;
    for i := 0 to RGNs^.rdh.nCount - 1 do
    begin
      Move(RGNs^.Buffer[i * SizeOf(TRect)], RCT, SizeOf(RCT));
      Inc(RCT.Bottom);
      Inc(RCT.Right);
      ClipRect := Canvas.BoxI(RCT, false);

      // Draw the clipping rectangle for debugging
      Canvas.SetRGBStrokeColor($55FF00FF); // Set a distinct color for the clipping rectangle
      Canvas.Rectangle(ClipRect.Left,ClipRect.Top,ClipRect.Width,ClipRect.Height);
      Canvas.Stroke; // Draw the outline of the rectangle

      // Apply the clipping path
      Canvas.NewPath;
      Canvas.Rectangle(ClipRect.Left, ClipRect.Top, ClipRect.Width, ClipRect.Height);
    end;
    Canvas.Closepath;
    Canvas.Clip;
    Canvas.NewPath;
    Canvas.FNewPath := False;
  end;
end;

Offline

#6 2024-05-14 16:33:41

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Yes, I also found it is the Canvas.BoxI translation that goes wrong.

MtwStark had a lot of changes to the GDI and clipping code.
But apparently the changes where so big, with several regression errors, it was chosen to revert instead of fixing those problems (which is a shame).

That code is here:
https://synopse.info/forum/viewtopic.ph … 786#p25786

There the TPdfEnum.ExtSelectClipRgn uses an adjusted BoxI() function. Namely Canvas.absBoxI().

      // MTW 2017-11-22 - Logical units to Device units with absolute reference to page origin
      // used for EMF clipping functions, region data coordinats are absolute (not relative to WorldTransform)
      // Inc(RCT.Bottom);
      //ClipRect := Canvas.BoxI(RCT, False);
      // need normalization for winding rule
      ClipRect := Canvas.absBoxI(RCT, true);
      Canvas.Rectangle(ClipRect.Left, ClipRect.Top, ClipRect.Width,
        ClipRect.Height);

Still need to figure out if this can be compressed to just a few simple changes (like you mentioned about offset or size).
Without changing too much in the complete rest of the code.

Offline

#7 2024-05-14 18:29:40

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

This will draw the rectangle correctly:

      RCT.Left := RCT.Left + round(Canvas.fWinOrg.X * Canvas.fViewSize.cx / Canvas.fWinSize.cx);
      RCT.Right := RCT.Right + round(Canvas.fWinOrg.X * Canvas.fViewSize.cx / Canvas.fWinSize.cx);
      RCT.Top := RCT.Top + round(Canvas.fWinOrg.Y * Canvas.fViewSize.cy / Canvas.fWinSize.cy);
      RCT.Bottom := RCT.Bottom + round(Canvas.fWinOrg.Y * Canvas.fViewSize.cy / Canvas.fWinSize.cy);
      ClipRect := Canvas.BoxI(RCT, false);

That corrects the I2X/I2Y to not use fWinOrg.X/Y.

But the comment from the other source is:

Logical units to Device units with absolute reference to page origin used for EMF clipping functions, region data coordinats are absolute (not relative to WorldTransform)

Which seems to suggest it does need to be relative to fWinOrg but not to fWorldOffsetX.

(But in the WMF the WinOrg.X/Y is -100/-100. I'll need to readup on this as to what it actually should be.)

Last edited by rvk (2024-05-14 18:30:57)

Offline

#8 2024-05-15 08:30:49

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Looks like it's just absolute coordinates.

So should be something like this:

      ClipRect.Left   := RCT.Left * Canvas.fDevScaleX;
      ClipRect.Top    := Canvas.fPage.GetPageHeight - (RCT.Top * Canvas.fDevScaleX);
      ClipRect.Width  := (RCT.Right - RCT.Left) * Canvas.fDevScaleX;
      ClipRect.Height := -(RCT.Bottom - RCT.Top) * Canvas.fDevScaleY; // Origin is bottom left so reversed

      // ClipRect := Canvas.BoxI(RCT, false);

The problem now is that we don't have a set of EMF/WMF files with complex and diverse structures to test this with.

From the other topic (from which my patch came) the fix worked perfectly for me.
But somehow, in your code, the fWinOrg is (-100,-100) which throws things off.

Maybe there are other possible problems with other complex EMF files (like when Canvas.fViewSize.cx isn't 1, for which we don't have an example to test with).

For example... in this topic on another forum, you can download a A.EMF and B.EMF.
https://www.vbforums.com/showthread.php … ing-Issues

It seems that SynPDF also has problems with A.EMF to place the objects correctly (namely the big blue ball).
And there is also a small artifact at te right bottom half of that ball.

This has nothing to do with this clipping code but it shows there are more problems with coordinates in the GDI+/EMF translation of SynPDF.

ubi4qdl.png

Last edited by rvk (2024-05-15 08:41:46)

Offline

#9 2024-05-15 09:05:52

jonjbar
Member
Registered: 2012-12-27
Posts: 37

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Excellent work ? Both of your updates fixes the specific problem for this EMF file.
I'm even more confident that this is the correct fix because LibreOffice also fixed EMR_EXTSELECTCLIPRGN this way: https://github.com/LibreOffice/core/com … 60a101f661
See these lines: https://github.com/LibreOffice/core/blo … r.cxx#L372

@rvk Do you believe that this is good enough for a pull request ?

@ab Would you accept those changes in the main repository ?

Offline

#10 2024-05-15 09:11:27

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

jonjbar wrote:

I'm even more confident that this is the correct fix because LibreOffice also fixed EMR_EXTSELECTCLIPRGN this way: https://github.com/LibreOffice/core/com … 60a101f661
See these lines: https://github.com/LibreOffice/core/blo … r.cxx#L372

But that's the really strange part.

It says:

Make EMR_EXTSELECTCLIPRGN factor in WinOrg coordinates

But... the current code DOES factor in fWinOrg.
But I think this is wrong.

If you look at my last changes

      ClipRect.Left   := RCT.Left * Canvas.fDevScaleX;
      ClipRect.Top    := Canvas.fPage.GetPageHeight - (RCT.Top * Canvas.fDevScaleX);
      ClipRect.Width  := (RCT.Right - RCT.Left) * Canvas.fDevScaleX;
      ClipRect.Height := -(RCT.Bottom - RCT.Top) * Canvas.fDevScaleY; // Origin is bottom left so reversed
      // ClipRect := Canvas.BoxI(RCT, false);

You see it doesn't use fWinOrg at all.
It just uses the coordinates without translating it with WinOrg at all.

Weird...

Offline

#11 2024-05-15 09:16:48

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Ha, if you look at the code in LibreOffice... this fix was not for NOT for RegionMode::RGN_COPY but for everything else.

So for RGN_COPY it is absolute coordinates... and for anything else, that fix you point at, translates with WinOrg.

case EMR_EXTSELECTCLIPRGN :
                    {
                        sal_uInt32 nRemainingRecSize = nRecSize - 8;
                        if (nRemainingRecSize < 8)
                            bStatus = false;
                        else
                        {
                            sal_Int32 nClippingMode(0), cbRgnData(0);
                            mpInputStream->ReadInt32(cbRgnData);
                            mpInputStream->ReadInt32(nClippingMode);
                            nRemainingRecSize -= 8;

                            // This record's region data should be ignored if mode
                            // is RGN_COPY - see EMF spec section 2.3.2.2
                            if (static_cast<RegionMode>(nClippingMode) == RegionMode::RGN_COPY)
                            {
                                SetDefaultClipPath();
                            }
                            else
                            {
                                basegfx::B2DPolyPolygon aPolyPoly;
                                if (cbRgnData)
                                    ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize, GetWinOrg());
                                const tools::PolyPolygon aPolyPolygon(aPolyPoly);
                                SetClipPath(aPolyPolygon, static_cast<RegionMode>(nClippingMode), false);
                            }
                        }

For this individual issue... this might work correctly.
(And if anything pops up, we should fix it at the spot)

Last edited by rvk (2024-05-15 09:17:52)

Offline

#12 2024-05-15 09:25:18

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

I now have this.
But I wonder if now the inc for r.bottom and r.right are still needed. Need to check this.

      r := pr^;
      inc(r.Bottom); //?????????
      inc(r.Right); //?????????

      ClipRect.Left   := r.Left * Canvas.fDevScaleX;
      ClipRect.Top    := Canvas.fPage.GetPageHeight - (r.Top * Canvas.fDevScaleX);
      ClipRect.Width  := (r.Right - r.Left) * Canvas.fDevScaleX;
      ClipRect.Height := -(r.Bottom - r.Top) * Canvas.fDevScaleY; // Origin is bottom left so reversed

      // with Canvas.BoxI(r, false) do
      with ClipRect do
         Canvas.Rectangle(Left, Top, Width, Height);

      inc(pr);

Offline

#13 2024-05-15 09:36:12

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Yep. Just checked.
My original is this (this is an image with a lot of clip-data):

SU3CMHS.png

With the adjusted code I get this (see the white pixels at the lower right edges):

B2U9Nj2.png

Then with commenting out the 2 inc() lines it's correct again:

BCxIRSp.png

So now I have this:

var
  ClipRect: TPdfBox;
//...
      r := pr^;
      // inc(r.Bottom);
      // inc(r.Right);
      ClipRect.Left   := r.Left * Canvas.fDevScaleX;
      ClipRect.Top    := Canvas.fPage.GetPageHeight - (r.Top * Canvas.fDevScaleX);
      ClipRect.Width  := (r.Right - r.Left) * Canvas.fDevScaleX;
      ClipRect.Height := -(r.Bottom - r.Top) * Canvas.fDevScaleY; // Origin is bottom left so reversed
      // with Canvas.BoxI(r, false) do
      with ClipRect do
         Canvas.Rectangle(Left, Top, Width, Height);
      inc(pr);

Now it's still the question if this all still works correctly if there is another fWorldOffsetX and fWorldFactorX.
For that we need more diverse EMF files.

Last edited by rvk (2024-05-15 09:39:28)

Offline

#14 2024-05-15 16:36:32

jonjbar
Member
Registered: 2012-12-27
Posts: 37

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

This program can be used to create EMF files with various clipping regions operations (RGN_AND, RGN_COPY, RGN_DIFF...). It could be a useful base for testing purposes:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Windows, SysUtils, Classes, Vcl.Graphics;

procedure CreateEMFWithClipRegion(const FileName: string; Mode: Integer);
var
  DC: HDC;
  MetaFileDC: HDC;
  MetaFile: HENHMETAFILE;
  aRect: TRect;
  RectRgn, TriangleRgn, CombinedRgn: HRGN;
  Brush: HBRUSH;
  Pen: HPEN;
  Points: array[0..2] of TPoint;
begin
  // Create a device context for the screen
  DC := GetDC(0);
  try
    // Define the bounding rectangle for the metafile
    aRect := Rect(0, 0, 300, 300);

    // Create an enhanced metafile device context
    MetaFileDC := CreateEnhMetaFile(DC, PChar(FileName), @aRect, nil);
    try
      // Draw a colored background
      Brush := CreateSolidBrush(RGB(240, 240, 240)); // Light gray background
      Pen := CreatePen(PS_SOLID, 1, RGB(240, 240, 240)); // Light gray pen
      SelectObject(MetaFileDC, Brush);
      SelectObject(MetaFileDC, Pen);
      Rectangle(MetaFileDC, aRect.Left, aRect.Top, aRect.Right, aRect.Bottom);

      // Define a rectangle clipping region in the middle
      RectRgn := CreateRectRgn(75, 75, 225, 225);

      // Define a triangle region
      Points[0] := Point(50, 250);
      Points[1] := Point(150, 50);
      Points[2] := Point(250, 250);
      TriangleRgn := CreatePolygonRgn(Points, Length(Points), WINDING);

      // Combine the rectangle region and the triangle region
      CombinedRgn := CreateRectRgn(0, 0, 0, 0); // Create an empty region
      CombineRgn(CombinedRgn, RectRgn, TriangleRgn, Mode);

      // Select the combined region with the specified mode
      ExtSelectClipRgn(MetaFileDC, CombinedRgn, RGN_COPY);

      // Draw a green rectangle
      Brush := CreateSolidBrush(RGB(0, 255, 0)); // Green brush
      Pen := CreatePen(PS_SOLID, 1, RGB(0, 255, 0)); // Green pen
      SelectObject(MetaFileDC, Brush);
      SelectObject(MetaFileDC, Pen);
      Rectangle(MetaFileDC, 30, 30, 200, 200);

      // Draw a red circle
      Brush := CreateSolidBrush(RGB(255, 0, 0)); // Red brush
      Pen := CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); // Red pen
      SelectObject(MetaFileDC, Brush);
      SelectObject(MetaFileDC, Pen);
      Ellipse(MetaFileDC, 100, 100, 270, 270);

      // Deselect the clipping region
      SelectClipRgn(MetaFileDC, 0);

      // Clean up the brush, pen, and regions
      DeleteObject(Brush);
      DeleteObject(Pen);
      DeleteObject(RectRgn);
      DeleteObject(TriangleRgn);
      DeleteObject(CombinedRgn);

    finally
      // Close the metafile and get the handle
      MetaFile := CloseEnhMetaFile(MetaFileDC);
    end;

    // Save the metafile to a file
    if MetaFile <> 0 then
    begin
      DeleteEnhMetaFile(MetaFile);
    end;
  finally
    // Release the screen device context
    ReleaseDC(0, DC);
  end;
end;


procedure TestCreateEMF;
begin
  CreateEMFWithClipRegion('C:\Tmp\_meta\Metafile_RGN_AND.emf', RGN_AND);
  CreateEMFWithClipRegion('C:\Tmp\_meta\Metafile_RGN_COPY.emf', RGN_COPY);
  CreateEMFWithClipRegion('C:\Tmp\_meta\Metafile_RGN_DIFF.emf', RGN_DIFF);
  CreateEMFWithClipRegion('C:\Tmp\_meta\Metafile_RGN_OR.emf', RGN_OR);
  CreateEMFWithClipRegion('C:\Tmp\_meta\Metafile_RGN_XOR.emf', RGN_XOR);
end;

begin
  TestCreateEMF;
end.

Offline

#15 2024-05-15 17:09:57

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

jonjbar wrote:

This program can be used to create EMF files with various clipping regions operations (RGN_AND, RGN_COPY, RGN_DIFF...). It could be a useful base for testing purposes:

I'm not sure what should be visible.
With EMFexplorer, nothing is really shown.

Also... in paint and IrfanView, nothing is shown. (I see in both that the actual image is just 11x11 pixels ?

B6rUUbZ.png

Offline

#16 2024-05-15 17:19:22

jonjbar
Member
Registered: 2012-12-27
Posts: 37

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Illustrator seems to work. Perhaps InkScape too?

Offline

#17 2024-05-15 17:25:27

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

AFAIR IrfanView is using the Windows GDI rendering directly.
So if it can't display anything, there is something wrong with the content.

A simple VCL app should be able to display this EMF.

Offline

#18 2024-05-15 17:25:41

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

I think CreateEnhMetaFile takes .01-millimeter unit as size, not pixels.
https://learn.microsoft.com/en-us/windo … hmetafilea

300*0.01 = 3mm which is 11 pixels at 96 dpi.
(according to https://pixelcalculator.com/en)

You can also see here that it needs mm measurements.
https://github.com/synopse/mORMot/blob/ … taFile.pas

Offline

#19 2024-05-15 17:32:26

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Something like this:

    aRect := Rect(0, 0, (300 * 2540) div 96, (300 * 2540) div 96);

But that results in 295x295 for me... ?
(and 96 needs to be the dpi for DC(0))

jonjbar wrote:

This program can be used to create EMF files with various clipping regions operations (RGN_AND, RGN_COPY, RGN_DIFF...). It could be a useful base for testing purposes:

BTW. That test project doesn't create a EMF which contains an offset WinOrg or non-standard scale, like your original code from this topic does.
So it wouldn't detect the regression for which you opened this topic lol

Last edited by rvk (2024-05-15 17:49:40)

Offline

#20 2024-05-15 18:31:33

jonjbar
Member
Registered: 2012-12-27
Posts: 37

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

ab wrote:

AFAIR IrfanView is using the Windows GDI rendering directly.
So if it can't display anything, there is something wrong with the content.

A simple VCL app should be able to display this EMF.

You're right. I could see the result in Illustrator so I though it was good enough for a quick and dirty first test. I'll see if that can be improved.

rvk wrote:

BTW. That test project doesn't create a EMF which contains an offset WinOrg or non-standard scale, like your original code from this topic does.
So it wouldn't detect the regression for which you opened this topic lol

That was just a quick and dirty first try to produce sample EMF files for testing purposes as you said previously: "For that we need more diverse EMF files."
I believe that it would be perfectly possible to generate the WinOrg using something like this at the beginning of the process:

      // Set the window origin
      SetWindowOrgEx(MetaFileDC, XOrigin, YOrigin, nil);

Offline

#21 2024-05-16 07:50:24

rvk
Member
Registered: 2022-04-14
Posts: 115

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

I adjusted the test project a bit to include creating a pdf directly after generating the PDF (with correct dimensions).
Also included a SetWindowOrgEx() line. That indeed shows my previous changes work correctly for offset window but I'm still unsure if it needs adjusting at other places.

I also noticed that the test for RGN_AND, RGN_DIFF, RGN_OR and RGN_XOR also worked correctly in PDF.
But that's because it doesn't test for those modes in EMR_EXTSELECTCLIPRGN but only in CombineRgn.

And using CombineRgn() doesn't actually put that mode RGN_AND etc in the metafile !!!
(it just buffers it and exports the final EMR_EXTSELECTCLIPRGN with RGN_COPY (which is done in the ExtSelectClipRgn() line.)

(edit: sorry for posting the code... moved to gist...)

For adjusted testproject:
https://gist.github.com/rvk01/60453f5bd … 8d75bba8fa

Last edited by rvk (2024-05-16 07:58:33)

Offline

#22 2024-05-16 07:55:41

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Please follow the forum rules and refrain to publish code source directly in the forum posts.
Use e.g. gist or a source repo for it.

Offline

#23 2024-05-16 08:29:43

jonjbar
Member
Registered: 2012-12-27
Posts: 37

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

Great! Meanwhile, I've greatly updated the EMF sample generator to produce 84 variations of valid metafiles for testing purposes. It can produce variations with different values for:
- SetWindowOrgEx (on or off)
- SetWorldTransform (including none, normal, scale, translate, rotate, shear, reflect)
- Clipping regions (on or off)

Metafiles are visible in IrfanView: RO714yu.png

Source code: https://gist.github.com/jonjbar/5e32409 … 349c66ff07

Hopefully, this could help test and enhance the SynPDF producer in the future.

Offline

#24 2024-05-28 15:23:54

jonjbar
Member
Registered: 2012-12-27
Posts: 37

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

rvk wrote:
var
  ClipRect: TPdfBox;
//...
      r := pr^;
      // inc(r.Bottom);
      // inc(r.Right);
      ClipRect.Left   := r.Left * Canvas.fDevScaleX;
      ClipRect.Top    := Canvas.fPage.GetPageHeight - (r.Top * Canvas.fDevScaleX);
      ClipRect.Width  := (r.Right - r.Left) * Canvas.fDevScaleX;
      ClipRect.Height := -(r.Bottom - r.Top) * Canvas.fDevScaleY; // Origin is bottom left so reversed
      // with Canvas.BoxI(r, false) do
      with ClipRect do
         Canvas.Rectangle(Left, Top, Width, Height);
      inc(pr);

I can confirm that this patch fixes the clipping problem. @ab could it be added to the official repository ? Would you accept a PR ? If so @rvk would you like to do it as I don't want to "steal" your code.
Thank you.

Offline

#25 2024-05-28 16:18:12

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Regression: simple EMF file is drawn with an overlapping/missing rect

We could accept of course a PR.

But I am almost sure that it would break some existing solution.

Offline

Board footer

Powered by FluxBB