#1 2023-09-07 10:28:56

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

CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

I'm trying my hand again at the clipping problem when printing a bitmap in GDI+ with clipping.

Here are two images. One is from the the generated EMF and the other from the PDF generated with the latest mormot2.

It seems that clipping in PDF is only restricted to a box, and not to a complete non-square region.
Is this true?

Or is clipping even supported for EnumEMFFunc() for GDI+?

Seeing that ClipRgn and MetaRgn are TPdfBox it seems that it couldn't even do a region but only a box.

If it should be supported then I can investigate further why it doesn't work correctly.
(otherwise I would be wasting a lot of time wink )

EMF
FDiRYHN.png

PDF
vrxzbqU.png

Last edited by rvk (2023-09-07 11:04:06)

Offline

#2 2023-09-07 11:37:45

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

Hmmmm, Yeah, definitely not supported.

Size of region data from GDI is 208 bytes.

      EMR_EXTSELECTCLIPRGN:
      begin
        dum1 := PEMRExtSelectClipRgn(R)^.cbRgnData;        // <---- has a block of 208 bytes
        E.ExtSelectClipRgn(@PEMRExtSelectClipRgn(R)^.RgnData[0],
          PEMRExtSelectClipRgn(R)^.iMode);
      end;

But the function ExtSelectClipRgn() doesn't seem to do much with the data parameter??

procedure TPdfEnum.ExtSelectClipRgn(data: PRgnDataHeader; iMode: DWord);
begin
  try
    with DC[nDC] do
      case iMode of
        RGN_COPY:
          begin
            ClipRgn := MetaRgn; // where is the data parameter used??
            ClipRgnNull := false;
          end;
      end;
  except
    on e: Exception do
      ; // ignore any error (continue EMF enumeration)
  end;
end;

Any ideas?

Was this meant to be functional or is it still in development?

Did this work in the past ???
Seeing this post: https://synopse.info/forum/viewtopic.ph … 071#p20071

Edit:
The code from that old topic (which was once in SynPDF) seems to be working much better. (no anti-alias but that might be fixed.)
Why was that code removed?

q6cDhkt.png

Last edited by rvk (2023-09-07 11:54:32)

Offline

#3 2023-09-07 12:07:29

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

Clipping is not supported yet in our PDF engine.

This code was removed because it introduced regression to a lot of users already using the library.
It is sadly an usual pattern: to please some specific conditions for 1% of the users, it breaks 50% of the others.

If clipping is to be supported, it should be properly.

Offline

#4 2023-09-07 13:28:46

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

I couldn't find that many problems with the old code on the forum.

No problem... I added the old code back with the addition of checking for data^.iMode is RGN_COPY in the ExtSelectClipRgn (which was mentioned in that topic).

// we are handling RGN_COPY (5) only..
if data^.iMode <> RGN_COPY then exit;

For me that works for now. If there are any problems I will mention them here.

Offline

#5 2023-09-07 15:28:42

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

You can send a pull request with your patched code, I could make a look at it, and probably merge it.

Offline

#6 2023-09-07 15:32:19

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

The code is almost identical with the old code (with the check for iMode added).

But I will test this some more (we wouldn't want a bad patch wink ) and create a pull request with patch (once I know how to do that smile )

Offline

#7 2023-09-07 16:26:32

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

ab wrote:

You can send a pull request with your patched code, I could make a look at it, and probably merge it.

BTW. Do you have some reference (link, documentation or description) for the problems many of those users had with the old clipping code?

(So I could test this and see if there is an alternative fix is this still exists in current code.)

Offline

#8 2023-09-08 05:49:39

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

There is no such reference, unless you google in this forum.

But I bet you already got the main info.

Offline

#9 2023-09-08 14:22:15

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

Grrr. translating these coordinates is really hard.

Still not perfect.
It's also not just adding or substracting a value because the ratio/proportions are also off when using BoxI().
I can't figure out what other translation then BoxI() should be done.

The larger the image, the more deviation.

Hryy7y6.png

Vj3tsw8.png

(There is also a big bug in PDF Engine when dealing with bitmaps of size 7x7 (very small). It crashes, even without the clipping stuff.)

Last edited by rvk (2023-09-08 14:57:03)

Offline

#10 2023-09-08 15:25:58

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

YES, PERFECT. I think I found a problem in the drawing of the DrawBitmap() in the PDF Engine.

For the old ExtSelectClipRgn code there was a correction of bottom (and I added right) of +1.
This was because in BoxI() there is I2Y(Rect.Bottom - 1) and I2X(Rect.Right - 1) in the correction to coordinates and size.

For the correct handling you would also need to do the Bottom + 1 and Right + 1 in the DrawBitmap() (same as in ExtSelectClipRgn).
So the bitmap is now drawn always 1 bitmap pixel too small (???).

Can you comment on why the BoxI() has the - 1 for Bottom and Right ??
There might be other places where this is a problem and because this is outside of the clipping problem I thought you might have some comments.

I can correct those before calling BoxI() in DrawBitmap() and ExtSelectClipRgn() and the outcome is perfect now:

      R := TRect(Rect(xd, yd, wd + xd, hd + yd));
      NormalizeRect(R);
      Inc(R.Bottom); // <----- these 2 lines
      Inc(R.Right);   // <----- these 2 lines
      box := BoxI(R, true);
      clp := GetClipRect;
      if (clp.Width > 0) and
         (clp.Height > 0) then
        Doc.CreateOrGetImage(bmp, @box, @clp) // use cliping
      else
        Doc.CreateOrGetImage(bmp, @box, nil);
      // Doc.CreateOrGetImage() will reuse any matching TPdfImage
      // don't send bmi and bits parameters here, because of StretchDIBits above

8MlFHSJ.png


47FiQoA.png

KhdSXMd.png

And this now seems pixel perfect with the EMF Explorer (which is this one):
UIg7UZO.png

Last edited by rvk (2023-09-08 15:28:28)

Offline

#11 2023-09-08 15:39:38

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

IIRC it was because the coordinates was excluding the border, or something like that.

Offline

#12 2023-09-08 16:09:13

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

Ok, here is another proof that the bitmap was drawn too small.

I added a FillRectangle of 1x1 at coordinates 0,0  1,1 and 4,6.

You see clearly that in the original drawing of bitmap with 2x4 pixels (drawn at 2,2), the lower right is not connected to the FillRectangle.

So, or all the BoxI() for FillRect etc. is not correct (but they seems to be places correctly) or the code for DrawBitmap is incorrect (too small).

After some further testing I will prepare a pull request for the ExtSelectClipRgn with the addition of corrected bottom/right in DrawBitmap.
(After that, when I get the time I'll see if I can tackle the EMR_SELECTCLIPPATH, which is completely missing now).

FdtqgnK.png

When corrected:
D8aEvBq.png

Offline

#13 2023-09-08 18:46:04

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

I searched back to where these changes were reverted.
Here are some references (for documentation and futures sake).

Original commit in SynPDF and mORMot was on 2015-11-09
https://github.com/synopse/SynPDF/commi … 55924c4d9c
https://github.com/synopse/mORMot/commi … b4077dc725

The revert in mORMot was done here on 2017-01-13 (and SynPdf on 2017-01-18):
https://github.com/synopse/mORMot/commi … 215790822e
https://github.com/synopse/SynPDF/commi … 8388dc689a

It points to this topic: https://synopse.info/forum/viewtopic.php?pid=22968

The strange thing is that this is discussed earlier (in 2016) but then this change wouldn't have happened yet.
https://synopse.info/forum/viewtopic.ph … 071#p20071

On the commit on SynPDF there are some comments in 2022 where it's mentioned the code was good (but was never followed upon):
https://github.com/synopse/SynPDF/commi … a#comments
https://github.com/synopse/SynPDF/commi … #r84370305

I've created a pull request (my first wink ) with the changes (including the check on iMode = 5).
I also fixed the DrawBitmap() to add 1 for Bottom and Right (the bitmap was actually drawn too small).

"Reintroduce SelectClipRgn support for GDI+ and fix DrawBitmap()"

Hopefully nobody has problems with it (otherwise I'm willing to help, with a problem .emf, to find the problem).

Offline

#14 2023-09-08 19:14:43

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

This is great!

I will look into your Pull Request tomorrow.

Thanks a lot for sharing!

Offline

#15 2023-09-09 07:26:23

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

I have merged (and slightly refactored) your pull request.
https://github.com/synopse/mORMot2/pull/221

Thanks a lot for sharing!

Offline

#16 2023-09-09 10:36:11

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

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

Thanks for the merge.

When looking for the word "clipping" here on the forum I came across this topic from MtwStark.
https://synopse.info/forum/viewtopic.php?id=4276

It seems (s)he made a lot (and I mean A LOT) of changes to SynPDF regarding the clipping-code.

I couldn't find a pull request (or even fixes on github).

I understand that those changes were a LOT to just merge with the existing code (and it wasn't even as fix for mORMot2) and was left behind because of this.

If I have any other fixes I'll try to keep them small and clearly understandable smile

Offline

#17 2023-09-09 20:55:43

tbo
Member
Registered: 2015-04-20
Posts: 335

Re: CreateRegion and SelectClipRgn support in PDF (EMR_EXTSELECTCLIPRGN)

rvk wrote:

When looking for the word "clipping" here on the forum I came across this topic from MtwStark.

I don't know if my hint is helpful. I haven't used SynPDF yet and only skimmed the thread, but when I hear the word "clipping" I immediately think of Angus Johnson Clipper2 library, which is also used with Image32. The older Clipper1 library can be found here.

With best regards
Thomas

Offline

Board footer

Powered by FluxBB