Do you own a Debenu Quick PDF Library version 7, 8, 9, 10, 11, 12, 13 or iSEDQuickPDF license? Upgrade to Debenu Quick PDF Library 14 today!

Debenu Quick PDF Library - PDF SDK Community Forum Homepage
Forum Home Forum Home > For Users of the Library > I need help - I can help
  New Posts New Posts RSS Feed - SetClippingPathEvenOdd
  FAQ FAQ  Forum Search   Register Register  Login Login

SetClippingPathEvenOdd

 Post Reply Post Reply
Author
Message
fellafoo View Drop Down
Team Player
Team Player


Joined: 21 May 22
Location: Simsbury, CT
Status: Offline
Points: 21
Post Options Post Options   Thanks (0) Thanks(0)   Quote fellafoo Quote  Post ReplyReply Direct Link To This Post Topic: SetClippingPathEvenOdd
    Posted: 21 May 22 at 3:58PM
Hello Forum Members:

Do any of you have experience with SetClippingPath/EvenOdd?

I am able to create a path, set a clipping path, and draw a bitmap over it and have it clipped to the outer boundary of the path. However, I also need to handle voids. I've tried drawing the perimeter, setting the clipping path, then drawing the interior void and setting the clipping path, but the bitmap always gets clipped to the 'smaller' path. The EvenOdd options seems to make no difference.

Here's the gist of my code:

  if Pipe.ToPlotter then
    PrinterPDF.SaveState; { Save current clipping path (there should be none at this point). }

  { PrinterPDF Clipping Path }
  { Convert point array for clipping path }
  PDF_Pnts := PntsArr;
  PDF_Cnts := PolyCounts;
  for i := 0 to Pred(Num_Contours) do begin { x Polygons }
    SetLength(iePtsArr, PDF_Cnts^); { No. Points in curr. Polygon }
    for j := 0 to Pred(PDF_Cnts^) do begin
      iePtsArr[j] := PDF_Pnts^; { Array of points in curr. Polygon. }
      Inc(PDF_Pnts);
    end;
    Inc(PDF_Cnts);

    X1 := iePtsArr[0].X / 600; { Convert printer canvas coordinate to inches }
    Y1 := iePtsArr[0].Y / 600;
    PrinterPDF.StartPath(X1, Y1);
    for k := 1 to High(iePtsArr) do begin
      X2 := iePtsArr[k].X / 600;
      Y2 := iePtsArr[k].Y / 600;
      PrinterPDF.AddLineToPath(X2, Y2);
    end;
    //PrinterPDF.SetClippingPath;
    PrinterPDF.SetClippingPathEvenOdd;
  end;

  ImageID := PrinterPDF.AddImageFromFile(ImgFName, 6);
  if (ImageID <> 0) then begin
    PrinterPDF.SelectImage(ImageID);
    PrinterPDF.DrawRotatedImage(PDF_ImgLeft, PDF_ImgTop, PDF_ImgWidth, PDF_ImgHeight, 270);
    PrinterPDF.ReleaseImage(ImageID);
    //PrinterPDF.ClearImage(ImageID);
  end;
  PrinterPDF.LoadState; { Restore clipping path (there should be none after this point). }

Thank You,

MFM
Back to Top
kevinqpl View Drop Down
Beginner
Beginner


Joined: 19 May 22
Status: Offline
Points: 3
Post Options Post Options   Thanks (0) Thanks(0)   Quote kevinqpl Quote  Post ReplyReply Direct Link To This Post Posted: 23 May 22 at 9:17PM
Hello MFM,

I could be mistaken but I think the different clipping path modes are related to the direction of the "inner" path, in other words if the points are clockwise or anticlockwise compared to the direction of the outer curve. Although maybe it's to do with paths that overlap themselves?

In any case, the following code shows how to have a void in a clipping path. The trick is to close the outer path, then move to the start of your inner path, and close that path when its done. Finally, set the clipping path depending on the direction.

You can change AntiClockwise to True or False and it will have the same effect as the direction of the inner curve is changed.

    QP.StartPath(100, 700);
    QP.AddLineToPath(500, 700);
    QP.AddLineToPath(500, 300);
    QP.AddLineToPath(100, 300);
    QP.AddLineToPath(100, 700);
    QP.ClosePath;

    AntiClockwise := False;

    if (AntiClockwise) then
    begin
      QP.MovePath(120, 320);
      QP.AddLineToPath(480, 320);
      QP.AddLineToPath(300, 680);
      QP.ClosePath;
      QP.SetClippingPath;
    end else
    begin
      QP.MovePath(120, 320);
      QP.AddLineToPath(300, 680);
      QP.AddLineToPath(480, 320);
      QP.ClosePath;
      QP.SetClippingPathEvenOdd;
    end;

    QP.SetFillColor(1, 0, 0);
    QP.DrawCircle(300, 500, 250, 1);

Back to Top
fellafoo View Drop Down
Team Player
Team Player


Joined: 21 May 22
Location: Simsbury, CT
Status: Offline
Points: 21
Post Options Post Options   Thanks (0) Thanks(0)   Quote fellafoo Quote  Post ReplyReply Direct Link To This Post Posted: 24 May 22 at 1:18PM
Thanks Kevin,

I'll need to do some more experimenting. I was looking for a way to start a new path before setting the clipping path but assumed MovePath was for actually moving the path not an equivalent to MoveTo. So at least I've got that part straightened out.

My point arrays / loops are closed (i.e., the first and last points are the same) so I don't think I need to call ClosePath. Section '8.5.3.3 Filling' of the PDF 1.7 document describes the Nonzero Winding Number and Even-Odd rules. The point order is considered in the first case but not the second.

MFM
Back to Top
fellafoo View Drop Down
Team Player
Team Player


Joined: 21 May 22
Location: Simsbury, CT
Status: Offline
Points: 21
Post Options Post Options   Thanks (0) Thanks(0)   Quote fellafoo Quote  Post ReplyReply Direct Link To This Post Posted: 24 May 22 at 2:04PM
I've got this working as expected now. I was starting my loop at 1 instead of 0. So this is compatible with the logic I use to create polygons and clipping regions with Windows.PolyPolygon. As in...
  BeginPath(aDC);
  PolyPolygon(aDC, aPtArr^, aPtCount^, aPlyCount);
  EndPath(aDC);

  Rgn := PathToRegion(aDC);
  SelectClipRgn(aDC, Rgn);
...and what I was hoping for.
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 11.01
Copyright ©2001-2014 Web Wiz Ltd.

Copyright © 2017 Debenu. Debenu Quick PDF Library is a PDF SDK. All rights reserved. AboutContactBlogSupportOnline Store