#1 Re: PDF Engine » EMF file Image not rendered » 2022-06-14 13:03:00

In your EMF the bitmap is rendered with transparency (AlphaBlend) and it's not yet supported in SynPDF

You can try to produce the EMF with a bitmap without AlphaChannel or without transparency.

#2 Re: PDF Engine » VCLCanvas and ExtCreatePen » 2022-06-13 11:21:44

Dicki wrote:

I would like to define a line style using "ExtCreatePen". Why can't I add this "VCLCanvas"?
Is this even possible?


Hi Dicki, I have slight expanded the support for the ExtCreatePen, you can try my code PDFEngine Clipping Implementation + Output stream optimizations and see if it solves your problems.

#3 Re: PDF Engine » Render Metafile created by TChart » 2022-06-13 11:15:07

DmitryBerin wrote:

Hello!
I have problem to render metafile created from TChart.
Filled areas are missing in PDF file, but other programs show metafile correctly

Metafile i want to render: https://dropmefiles.com/AjOyy

Your metafile is no longer accessible, can you repost it?

I had same problems using TChart, you can try my code PDFEngine Clipping Implementation + Output stream optimizations and see if it solves your problems.

#4 Re: PDF Engine » PDFEngine Clipping Implementation + Output stream optimizations » 2022-06-13 11:01:34

ab wrote:

My concern is that almost every time I merge some pull request in SynPdf which pleases some users, there is a regression for others...

So I usually un-merge it a few days later...

I know that it's not so simple to merge work from others in main trunk, especially when the proposed solution is only partial and not a full solution,
but I think that something could be useful to many other users.

I use this metafile to test source code test_libuemf_ref.emf and the differencies are not limited to clipping.
(It's not a virus although google drive warns about it, you can proceed with download)

Everyone can feel free to use my work for their needs, keeping credits to the original developer and a greeting message would be very appreciated.

#5 Re: PDF Engine » Some additional features » 2019-11-22 14:18:03

Hi jeanmilost,
about your function TPdfDocument.GetFontFallBackNames
I have added a check for validity of the font index to avoid AV in case of mispelled or not installed font.

function TPdfDocument.GetFontFallBackNames: string;
var
    i, count: Integer;
begin
    Result := '';
    // get font fallback count
    count := Length(fFontFallBackIndexes);
    // no font fallback defined?
    if (count = 0) then
        Exit;
    for i := 0 to count - 1 do begin
        // first font?
        if (i > 0) then
            // add separator
            Result := Result + ',';

        // add next font
{$IFDEF TMW_TEST_NEW_FONT_FALLBACK}        
        if fFontFallBackIndexes[i] < 0 then  // ------------------------------->>> avoid AV if font name was not found ;)
            Continue;
{$ENDIF}
        Result := Result + UTF8ToString(FTrueTypeFonts[fFontFallBackIndexes[i]]);
    end;
end;

Thank you for sharing your work

#6 Re: PDF Engine » Some additional features » 2019-11-20 14:58:38

Hi jeanmilost,
I use your FontFallBackNames feature in SynPDF.pas and I think I have found a little problem.

In TPdfCanvas.SetFont() function You have changed original code to look for a default font in FontFallBackIndexes but I think You have inverted the boolean test.

                        for i := 0 to count - 1 do begin
                            FontIndex := FDoc.fFontFallBackIndexes[i];
{$IFDEF TMW_TEST_NEW_FONT_FALLBACK}
                            if FontIndex >= 0 then    // this way better
{$ELSE}
                            if FontIndex < 0 then    // ??
{$ENDIF}
                                break;
                        end;

Can you confirm this?
Thank you

#7 Re: PDF Engine » Underlines in rich text » 2019-11-20 14:45:52

Hi Ratay,
I think I had a similar problem with underlined text in RichEdit,
I found that the underline was produced with a new EMR_BITBLT metafile record and maybe the coordinates for this emulated line falls out of the RichEdit

I had already changed my EMR_BITBLT for a similar reason

{$IFDEF TMW_TEST_NEW_GDI}
    E.FillRectangle(Rect(xDest - 1, yDest - 1, xDest + cxDest, yDest + cyDest), true);
{$ELSE}
    E.FillRectangle(Rect(xDest, yDest, xDest + cxDest, yDest + cyDest), true);
{$ENDIF}

If you have sources of your report engine, you can take a look also at the AutoSize procedure for RichEdit, maybe a simple +1 in CalcHeight will fix wink

#8 Re: PDF Engine » line width in pdf » 2019-11-20 14:35:12

Hi viki,
I think I have solved that problem..

There are many changes involving the pen, you can start looking at my old code SynPDF.pas,
look for ExtCreatePen function called by EMR_EXTCREATEPEN metafile record

Also, in SelectObjectFromIndex

in NULL_PEN case I have changed

{$IFDEF TMW_TEST_NEW_PENNULL}
    pen.style := (pen.style and not PS_STYLE_MASK) or PS_NULL;
{$ELSE}
    pen.style := PS_NULL;
{$ENDIF}

and in OBJ_PEN case I have changed

{$IFDEF TMW_TEST_NEW_PENNULL}
    pen.null := (PenWidth < 0) or ((PenStyle and PS_STYLE_MASK) = PS_NULL); // !! 0 means as thick as possible
{$ELSE}
    pen.null := (PenWidth < 0) or (PenStyle = PS_NULL); // !! 0 means as thick as possible
{$ENDIF}

I hope this will help

#9 Re: PDF Engine » Clipping Problem » 2019-11-20 14:14:20

Hi ajtom,
I have fixed many problems about clipping in SynPDF

Take a look at this post PDFEngine Clipping Implementation + Output stream optimizations
You will find a link to download my version of SynPDF.pas. This is not my last version but you can check if it solves your clipping problems.
Read through the post to see updates.


MtwStark

#10 Re: PDF Engine » Runtime error 216 in SynGdiPlus Finalization » 2018-04-04 10:18:01

you are welcome smile

I'm happy to hear you have solved

#11 Re: PDF Engine » Runtime error 216 in SynGdiPlus Finalization » 2018-04-03 08:08:45

Try to download the last print preview source code, TGDIPlusSubset Create/Destroy are slight different, maybe this was a known problem.

http://www.delphiarea.com/downloads/?dl … ch=PREVIEW

#12 Re: PDF Engine » Runtime error 216 in SynGdiPlus Finalization » 2018-03-29 08:11:42

you are welcome.
Are you sure the error is raised on fStartupHook.UnHook(fStartupHookToken), and not on Shutdown(fToken)?
In any case, I think the problem could be related to gdi objects not released before the TGDIPlus.Destroy
Shutdown procedure must be called only after all gdi objects are released...
Try to place a breakpoint in TPrintPreview.Destroy, TThumbnailPreview.Destroy and TPaperPreview.Destroy and see if the runtime error is raised before the destroy of you "Print Preview" component.
If it does not release all gdi objects before destruction it could bring to this kind of problems.

I have taken a brief look into preview.pas and I see it has its own gdiplus support.. maybe the problem is a conflict between the two.
In preview.pas, I would check also TGDIPlusSubset.Create and _gdiPlus.Free in finalization (TGDIPlusSubset.Destroy)

Finally..
I'm still using Delphi 2007 so, I'm not sure about that, but I have read here that in XE2 the calls to “GdiplusStartup” and “GdiplusShutdown” are only performed if not IsLibrary is True to avoid hangs in shutdown..

#13 Re: PDF Engine » Runtime error 216 in SynGdiPlus Finalization » 2018-03-28 09:51:51

Looking the Gdiplus Startup Output structure documentation it says that using the wrong token in the unhook function will cause resource leaks, cleaned up when the process exits.
This should not produce a runtime error.

I think the problem could be in the TGDIPlus.Create, maybe the token received in the hook function was invalid?
The hook function should returns a status (TGdipStatus) but it is not tested in TGDIPlus.Create

it is possible that the call of Startup(fToken,Input,fStartupHook) returns an error (<>stOk) but puts something dirt in fStartupHook?
In this case during the Destroy the fStartupHook.UnHook could result Assigned (<>nil) but invalid.
Try to clear the fStartupHook record when Startup fails in the TGDIPlus.Create:

  if Startup(fToken,Input,fStartupHook)<>stOk then begin
    FillChar(fStartupHook, SizeOf(fStartupHook), 0); // MTW 2018-03-28 - Be sure Hook/UnHook are unassigned
    fToken := 0;
    UnLoad;
    exit;
  end;

#14 Re: PDF Engine » Runtime error 216 in SynGdiPlus Finalization » 2018-03-27 09:41:07

Are you building/working with an ISAPI?
In this case your initializations/finalizations can be called for each execution (thread) but global vars are shared across the DLL so gdip could be freed when it is already free.

try to change finalization with:

finalization
  if Gdip<>nil then
    FreeAndNil(Gdip);
  Windows.DeleteCriticalSection(GdipCS);
end.

#15 Re: PDF Engine » Bitmap with height 1 pixel results in a corrupted file » 2018-03-22 17:06:14

Hi Marsh,
the problem is not the BoxI function, but the starting rect R.

It should be 1px bigger than bitmap because the BoxI expect a rect with right and bottom border excluded.

change:

R := Rect(xd, yd, wd + xd, hd + yd);

in:

R := Rect(xd, yd, wd + xd + 1, hd + yd + 1);

With images larger or higher than 1px, you do not see the problem because the image is not "truncated" for the missing pixel but it is painted a (very) little stretched

If you try placing two normal bitmaps one over the other,
you should notice that with inflated rect, the draw will reach the correct right-bottom corner.

If you prefer not to modify existing behaviour for all pictures you can simply use:

if wd=1 then Inc(wd);
if hd=1 then Inc(hd);
R := Rect(xd, yd, wd + xd, hd + yd);

have a nice day

#16 Re: PDF Engine » Wrong rendering of TeeChart Metafile » 2017-12-13 13:03:39

I use TeeChart and print them on PDF with SynPDF

MyChart.SaveToMetafileEnh(Filename);

saves a valid EMF file.

#17 Re: PDF Engine » Wrong text placement, ARC DIRECTION etc. » 2017-12-13 12:56:12

Hi, toshe
I had a similar problem handling texts from RichEdit an I solved in his way:

            if (font.Align and TA_CENTER) = TA_CENTER then
                W := W / 2 // center x
            else if (font.Align and TA_CENTER) = TA_LEFT then
                W := 0; // left x
            // V Align mask = TA_BASELINE or TA_BOTTOM or TA_TOP = TA_BASELINE
            if (font.Align and TA_BASELINE) = TA_BASELINE then
                // always zero ?
                H := Abs(font.LogFont.lfHeight) - Abs(font.spec.cell) // center y
            else if (font.Align and TA_BASELINE) = TA_BOTTOM then
                H := Abs(font.spec.descent) // bottom y
            end else begin
                //H := -abs(font.spec.ascent); // top
                H := -abs(2 * font.spec.cell) + abs(font.spec.descent) + abs(font.spec.ascent) - 1; // top MTW
            end;

Mine does not handle rotated text but I noticed a certain similarity in our two formulas for H

#18 PDF Engine » PDFEngine Clipping Implementation + Output stream optimizations » 2017-12-07 17:48:30

MtwStark
Replies: 8
UPDATE 2022-06-09

I have released an updated version to current release (1.18.6395) for anyone with clipping problems.
It's not the final solution but it addresses many cases.
SynPDF_MTW_1.18.6395

UPDATE 2018-02-02

I have released a new version to solve problems about nested clipping (thanks to Tom for support and testing)
I have also added support for LineJoin


Hi all,
good news, I have finally made a somewhat big step ahead in clipping implementation.

It is a quite long explanation.. posting code.. functions.. would be difficult, so I share my entire SynPDF.pas
You can test output using test_libuemf_ref.emf and HRVPSDPrintForm.emf

I have problems sharing the reference emf, google drive thinks it contains a virus (but it doesn't) and warns the user before download

There are some differences from standard version, but I think that who is interested will find it useful.

I quote some people involved, hoping they will be notified and come to see:

Marsh wrote:

But I also noticed that clipping for EMF is not supported. So far I managed to get around with a hack, but now I'm looking for a proper solution.

Tom wrote:

But when converting a small EMF file to PDF I encountered a clipping problem, and I don't know how to solve it.

jeanmilost wrote:

But I recently tried the latest SynPdf version, and I noticed that the above code no longer works, as my page is drawn without clipping at all.

kalwados wrote:

with some small adjustments as mentioned where by MtwStark: Test for iMode == RGN_COPY. Now everything works fine, again.

Fritz wrote:

After investigate the clipping in SynPDF i must say there are a lot of problems with it. I will spend some more time to find a proper solution.

WBTeam wrote:

... the clipping issue is still not solved. I'm hoping for someone to take care of this, I'll try myself, but I'm no expert.

jkelley wrote:

I spent some time playing around with ExtSelectClipRgn to see if I could fix the problem, but unfortunately, I'm having trouble figuring out my way around the codebase.

davidheffernan wrote:

I'm seeing nothing at all in the generated PDF, or sometimes just a couple of parts of one of the metafiles.

I think that also davidheffernan problem with multiple metafiles, could be related to clipping, because in my HRVPSDPrintForm.emf test I had a similar problem..

Use it as you like, I got a great improvement with this, I hope that someone else will get it too.

Feel free to ask for explanations if something is not clear, any comment are welcome.


Essentially it is the standard version 1.18.4051 of 2017-12-06 (yesterday) with some differences:

In december 2015 I implemented my function to handle EMR_ARC, EMR_CHORD, EMR_PIE, EMR_ARCTO and I still have not replaced it with ProHolz version
In november 2016 I have integrated some code from JeanMilost about FontFallBackNames and KerningHHorzScale and some code from Niki about dynamic load of UNISCRIBE

All other differences are mine, you will find:

a new set of functions absI2X, absI2Y, absRectI, absBoxI to calc I2X coordinates with absolute reference to page origin (not using WorldTransform), used in ExtSelectClipRgn

a new procedure RectangleClockWise handy for special fill/clip operations with different winding rules

a new InPath flag in TPdfEnumState, to handle operations between EMR_BEGINPATH and EMR_ENDPATH

MetaRgn and ClipRgn in TPdfEnumState and also fInitMetaRgn in TPdfEnum are now TRect instead of TPdfBox to handle clipping objects in logical units

I have also defined the types for brush (TPdfEnumStateBrush) and font (TPdfEnumStateFont) outside TPdfEnumState

some properties and changed some property setter for some internal variable, in SetFillColor(), SetStrokeColor(), SetPenWidth() added test for invalid value -1 before to write to pdf, SetInLined() handles Stroke if needed;

procedure RestoreDC now handles the DC number parameter and (most important) clear the Clip Path if restored DC had a NULL Clip Path;

a new procedure ResetClipPath to clear the Clip Path on PDF and invalidate colors, styles and font, you can't enlarge Clip path on PDF, only reduce it, so the only solution is to restore the NULL Clip Path and apply a new one;

a new procedure InvalidateColorsAndStyle, just a wrapper for fFillColor := -1; fStrokeColor := -1; fPenStyle := -1; fPenWidth := -1;

a new procedure ExtCreatePen to handle a little more the EMR_EXTCREATEPEN record, added basic support for PenStyle = PS_USERSTYLE (emulated with PS_DASH), sets a default pen color black if brush style not in [BS_SOLID, BS_HATCHED] (should use patterns..), sets a default pen width = 1 if brush style in [BS_DIBPATTERN, BS_DIBPATTERNPT, BS_HATCHED, BS_PATTERN], sets pen style to PS_NULL if brush style = BS_NULL

procedure SetMetaRgn now clear the Clip Path on PDF and updates MetaRgn variable


Now let's see the clipping core functions:

IntersectClipRect: now updates the Clip Path on PDF intersecting the rect passed and updates the internal ClipRgn variable
ExcludeClipRect: Added support for EMR_EXCLUDECLIPRECT, updates the Clip Path on PDF excluding the rect passed but does not update the internal ClipRgn (we keep the largest bound rect)
SelectClipPath: Added support for EMR_SELECTCLIPPATH (mode RGN_AND), updates the Clip Path on PDF with the path plotted (but still not painted), but    does not update the internal ClipRgn (because we have no info on path applied)
ExtSelectClipRgn: Added support for EMR_EXTSELECTCLIPRGN (modes RGN_COPY and RGN_AND), intersect or replace the Clip Path on PDF with the rect list passed and updates the internal ClipRgn variable


some changes in procedure TextOut:

  • excluded the test on white brush color for opaque background, because white is not transparent;

  • inverted the test on font background color, I think it was wrong;

  • forced the brush color to font background color for opaque background;

  • changed the dimensions of background rectangle because in some cases there was uncovered zones, I have tried to make it automatic but it can be improved and it should be tested with many other fonts styles and dimensions;

  • deleted some uselse commands for clip rectangle;

  • added silent paint (NewPath) after the Canvas.Clip command, but (WARNING!!) deleted it from FillRectangle();

  • deleted the entire block who save graphic state, change clipping, restore graphic state.. if nothing put marks on pdf between clip and restore.. all of this is useless

some changes to EnumEMFFunc function:

EMR_LINETO:
- set Moved to true instead of false because LineTo does move the current position on PDF
- tested the new property InLined for Stroke management

EMR_POLYGON, EMR_POLYLINE, EMR_POLYGON16, EMR_POLYLINE16:
- set Moved to true instead of false because LineTo does move the current position on PDF
- tested the new property InLined to avoid the paint (stroke or fill or silent)

EMR_POLYBEZIER, EMR_POLYBEZIER16, EMR_POLYBEZIERTO, EMR_POLYBEZIERTO16, EMR_POLYLINETO, EMR_POLYLINETO16, EMR_POLYDRAW, EMR_POLYDRAW16:
- set Moved to true instead of false because LineTo does move the current position on PDF

EMR_BEGINPATH, EMR_ENDPATH:
- management of new flag InPath true/false

EMR_FILLPATH:
- forced ClosePath before fill, unfortunately doesn't exists a direct PDF command for Close + Fill

EMR_STROKEPATH:
- made silent paint alternative to Stroke

EMR_STROKEANDFILLPATH:
- forced ClosePath before paint (stroke or fill or silent), unfortunately doesn't exists a direct PDF command for Close + Fill
- made silent paint alternative to Stroke and/or Fill

and finally a little optimization in TextRect()
- repaced MoveTo, LineTo, LineTo, LineTo and CloePath with Rectangle

Merry Christmas from Italy
MtwStark cool

P.S.
sorry for poor english or bad code.. wink

#19 Re: PDF Engine » SynPDF over ISAPI » 2017-05-25 09:07:32

CarlosM wrote:

Hello,

When try to use SynPDF + FastReport on ISAPI, it does not work.

Any suggerence ?

regards


Hi CarlosM,
I have finally understood and solved the problem of SynPDF inside ISAPI using {$DEFINE USE_SYNZIP}

The problem is that the internal SynZip.CompressStream() function allocates 256Kb on the stack and inside an ISAPI this throws a StackOverflow exception, because your thread is not using your delphi defined stack size but the host worker default stack size, and (at least in IIS) it is probably 256Kb overall.

It is not an easy task to overwrite default stack size used by your threads but it is possible!

I have used a Detours Library to intercept the BeginThread and then inside the derouted function overwritten the stacksize.

Here it is my solution in my WebModule:

var
  TrampolineBeginThread: function(SecurityAttributes: Pointer; StackSize: LongWord;
    ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; var ThreadId: TThreadID): THandle = nil;

function InterceptBeginThread(SecurityAttributes: Pointer; StackSize: LongWord;
  ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord;
  var ThreadId: TThreadID): THandle;
const
  STACK_SIZE_PARAM_IS_A_RESERVATION = $00010000; // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx
begin
    CreationFlags := CreationFlags or STACK_SIZE_PARAM_IS_A_RESERVATION;
    StackSize := $100000; // 1Mb Stack size
    result := TrampolineBeginThread(SecurityAttributes, StackSize, ThreadFunc, Parameter, CreationFlags, ThreadId);
end;

initialization

  TrampolineBeginThread := InterceptCreate(@BeginThread, @InterceptBeginThread);

finalization

  InterceptRemove(@TrampolineBeginThread);

I have used old version (v1) of Delphi Detours Library

I hope this helps

bye

#20 Re: PDF Engine » SynPDF over ISAPI » 2017-05-22 16:01:27

I have same issue..

The error generates in the TPdfStream.InternalWriteTo() when calling the CompressionStream function (Stack Overflow)

If compiled in normal Forms.TApplication instead of WebBroker.TWebApplication then USE_SYNZIP works just fine.

Anyone knows if it is possible to use SynZIP within an ISAPI? or the reason why it doesn't in ISAPI?

#21 Re: PDF Engine » Latest SynPdf version breaks the clipping » 2016-11-16 11:23:55

Hi jeanmilost,
please take a look at my post for the same problem here

I have solved adding this test to the beginning of ExtSelectClipRgn procedure:

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

#22 Re: PDF Engine » Last SynPdf version corrupts clipping ranges » 2016-10-05 11:14:05

Hello everybody

finally I discovered that the problem was that the type of clip applied was not the one to apply.

I try to explain better:

in TPdfEnum.ExtSelectClipRgn we receive a EMRExtSelectClipRgn structure.
this structure contains the iMode field which determines the type of clip to apply to current clip region and received region.

Currently the procedure only handles the RGN_COPY (replace) type of clipping.
Using the region passed, to replace the current clip region with different clip types (RGN_AND, RGN_DIFF, RGN_OR, or RGN_XOR) is not correct and will bring to unespected (wrong) results.

I have added a test for iMode to exit for types different from RGN_COPY.

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

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

  if not DC[nDC].ClipRgnNull then 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);
      ClipRect := Canvas.BoxI(RCT, False);
      Canvas.Rectangle(ClipRect.Left, ClipRect.Top, ClipRect.Width, ClipRect.Height);
    end;
    Canvas.Closepath;
    Canvas.Clip;
    Canvas.NewPath;
    Canvas.FNewPath := False;
  end;
end;

this avoids overwrite of clip regions with wrong ones.


P.S.
do not consider the code posted in 1st post

#23 Re: PDF Engine » Last SynPdf version corrupts clipping ranges » 2016-09-26 13:49:02

Hello everyone,
after some other tests I had to revert to the old version before enhanced clipping process by Achim Kalwa

I would like to open some points to discuss with the Forum because a few things are not really clear to me:

1) SetMetaRgn is now implemented to return the intersection of Current Meta Region and Current Clip Region.
reading the  SetMetaRgn function reference I ask myself if it should return their union (combined region) instead of their intersection

EDIT
1.5) IntersectClipRect
EMR_INTERSECTCLIPRECT Reference tells that it would set a new clip region to the intersection between passed region and Current Clip Region.
Now, if the passed region is empty (width or height = 0) the clip region is unaffected (exit), I think it should be set to null.

2) Coordinates are always handled as WorldTransform relative in clipping functions.
In some cases it seems to me they should be in Device Units, other in Logical Units. Something is odd with region coordinates..

3) EMR_EXTSELECTCLIPRGN
The RegionMode parameter is not handled at all, maybe it would be better to test RegionMode = RGN_COPY before clipping.

4) EMR_EXCLUDECLIPRECT is missing
it should be almost the same code of EMR_EXTSELECTCLIPRGN in RGN_DIFF mode, so implementing it will be like to kill two birds with one stone.

5) EMR_SELECTCLIPPATH is missing
maybe not too much important but I think it should be easy to implement, redirecting the call to ExtSelectClipRgn.

6) EMR_OFFSETCLIPRGN is missing
still not found in any document, but it shouldn't be too hard to implement.

Anybody have worked with this stuff?
any comment appreciated

regards

#24 PDF Engine » Last SynPdf version corrupts clipping ranges » 2016-09-22 14:45:22

MtwStark
Replies: 2

EDIT: Jump to the end of the page this post is superseeded! smile

Hello,
I recently had this problem, with introduction of enhanced clipping process by Achim Kalwa, I noticed invalid clipping when rendering metafiles.

They are now partially clipped out without reason, with previous version the clipping of same files was correct.

I have digged a bit and found that the problem is the new ExtSelectClipRgn function because of the transformation of clipping regions using WorldTransform in functions I2X and I2Y

I think that clipping regions are absolute (Window relative?) and they do not need to be shifted/rotated/scaled.

in ExtSelectClipRgn there is a call to BoxI function who calls RectI who calls I2X and I2Y where the clip region is shifted and scaled using FWorldOffsetX/Y and GetWorldFactorX/Y

the resulting clipping region is not correct.

I have simply avoided the BoxI call and calculated the CliptRect manually and it works fine.
This is the modified loop in the ExtSelectClipRgn:

    for i := 0 to RGNs^.rdh.nCount - 1 do begin
      Move(Rgns^.Buffer[i * SizeOf(TRect)], RCT, SizeOf(RCT));
      Inc(RCT.Bottom);
{$IFDEF TMW_TEST_NEW_CLIPRGN}

      // MTW WRONG ORIGIN AND SCALING OF CLIP REGIONS
      // seems that clip region is window relative, not world relative

      with Canvas do begin
        ClipRect.Left := FOffsetXDef + ViewOffsetX(RCT.Left) * FDevScaleX ;//*
        ClipRect.Top := FPage.GetPageHeight - FOffsetYDef - ViewOffsetY(RCT.Top) * FDevScaleY;
        ClipRect.Width := (ViewOffsetX(RCT.Right - 1) - ViewOffsetX(RCT.Left)) * FDevScaleX  ;//*
        ClipRect.Height := (ViewOffsetY(RCT.Top) - ViewOffsetY(RCT.Bottom - 1) ) * FDevScaleY;
      end;

{$ELSE}
      ClipRect := Canvas.BoxI(RCT, False);
{$ENDIF}
      Canvas.Rectangle(ClipRect.Left, ClipRect.Top, ClipRect.Width, ClipRect.Height);
    end;

if the problem is spread across other portions of library it could be interesting to add a flag with default to BoxI, RectI, I2X and I2Y, to exclude WorldOffset and WorldFactor from the calc.

I hope this could be of any help for someone.

Has anyone had my same problem and can confirm my intuition?

thanks
regards

#25 Re: PDF Engine » PieChart in PDF? » 2016-06-07 09:41:10

Marcelo Economatica wrote:

I have started use the PDF Engine last week to allow one existing application generate PDF reports.

One of the reports I am working have a piechart generated using TCanvas.Pie(). The resulting PDF lacks the piechart.

After some debugging, I found that the TPdfCanvas.RenderMetaFile() does not handle the PIE record on the metafile.

I have no experience with PDF. Is there anything I could do so the piechart appears on the PDF?

TIA
Marcelo


Hello Marcelo, I have added handling of EMR_ARC, EMR_CHORD and EMR_PIE in TPdfCanvas.RenderMetaFile()
If you still need it, I can send you the modified SynPDF.pas

#26 Re: PDF Engine » EMF clipping problem » 2016-06-07 09:23:17

** UP **

Can anyone correct the EoClip function?

'w*' means nothing in PDF reference, it should be 'W*'

thanks

#27 Re: PDF Engine » EMF clipping problem » 2016-04-19 11:33:20

Marsh wrote:

Furthermore, I noticed a bug in TPdfCanvas.EoClip, instead of upper case W, lower case w should be added to the stream, so:

procedure TPdfCanvas.EoClip;
begin
  if FContents <> nil then
    // FContents.Writer.Add('W*'#10);
    FContents.Writer.Add('w*'#10);
end;
Tom wrote:

Hello Marsh

Thanks for your patch.

I tried it but unfortunately the changes in EnumEMFFunc leads to a corrupt PDF.

Sorry Marsh but in current PDF Reference 1.7 EoClip MUST be 'W*' (uppercase)
maybe this could be the cause of your EMR_INTERSECTCLIPRECT bringing to corrupted pdf?

Tom, could you test it with 'W*' instead of 'w*' in EoClip?

kind regards

Board footer

Powered by FluxBB