#1 Re: PDF Engine » Problem with resaving an encrypted PDF » Yesterday 07:05:55

rvk
jfchidalgo wrote:

Hi! I'm having the same problem. Did you found a solution?

No. The only solution I have is using this:

SynPdfReport.ExportPDFEncryptionPermissions := PDF_PERMISSION_NOMODIF;

So... without the option of epFillingForms and epAuthoringComment.

#2 Re: PDF Engine » Need help/direction for WMF file. » 2025-04-22 12:38:27

rvk

That's weird. If I look in the WMF with EMFexplorer I do get some font info, but maybe not for all objects:

Multiple lines with
EMR_EXTCREATEFONTINDIRECTW    (s=368)    {ihFont(2) ELF[name() style() vendor(0x072DDF38)] LOG[face(Arial), style(Bold), charset(0),family(0),precision(0), height(-100), width(0)]}

But it's also weird that some text is correct. For me... every WMF/EMF renderer I used (emfexplorer, gimp, paint and irfanview) do give somewhat correct result (although some give different font results). So they do fall back to a "correct" font as where SynPDF falls back to NO font (giving overlapping characters).

y0mzKIg.png

#3 Re: PDF Engine » Need help/direction for WMF file. » 2025-04-22 10:49:19

rvk

If I use pdf.Canvas.SetFont before using pdf.VCLCanvas.Draw or RenderMetaFile() it works better. In that case the overlapped letters are gone. Not perfect because it seems SynPDF still doesn't take the correct font but it is doable because now the fallback is to that 'default' font.

I'll wait on OP if help is still needed.

sy8lUqd.png

#4 Re: PDF Engine » Need help/direction for WMF file. » 2025-04-22 08:44:41

rvk

No, it's just Arial in the WMF.
When I trace through the code I get in TPdfCanvas.SetPdfFont where is skips the code because of the "// check if this font is already the current font".

But when I look in the actual PDF you get to the point for P.O.No. where there is no "/F1 9.95 Tf" set.
And I can't see that there is any "default" font set for the (or a) PDF.

Q
q
BT
39.67 676.56 Td
(P. O. No:) Tj
ET
Q
q

while above it is this for CUSTOMER

q
/F2 9.95 Tf
BT
39.67 694.54 Td
(CUSTOMER:) Tj
ET
Q
q

All the text which is printed overlapped seem to be missing the font setting. It may be due to some recursive problem where SynPDF thinks there is a current font set while there is not... But since I don't know if the OP has the same issue (in the older SynPDF) I'm not sure if it's worth investigating.

(BTW Rendering this though RenderMetaFile() it actually produces a corrupt PDF. Doing this with Draw(), which used some of the same code, gives above result. So there is also something wrong when doing it through RenderMetaFile)

#5 Re: PDF Engine » Need help/direction for WMF file. » 2025-04-22 08:27:15

rvk

Not sure if more help is needed. It seems that the overlap of letters is due to SynPDF thinking the current font is already set while it is not.
Because I don't know if you have the same issue, I'll let this rest until you indicate this.

#6 Re: PDF Engine » Need help/direction for WMF file. » 2025-04-19 15:54:54

rvk

Links are correct now (I guess it was the extra slash at the end).

The GDI+ implementation of SynPDF is far from perfect. It probably lacks some features used which results in a 'corrupt' PDF.

I did notice you used SynPDF. I don't have that installed anymore and the old SynPDF isn't updated anymore. For a more recent version you would need to use mormot.ui.pdf in mORMot2.

With that one I got a 'corrupt' pdf trying to do RenderMetaFile(pdf.Canvas, aMeta, 0.58, 1.30, 0, 0);

When I did pdf.VCLCanvas.Draw(0, 0, aMeta); I did get all the images. But the text wasn't exactly correct.

LmYClIY.png

But I can't speak for the older SynPDF.

#7 Re: PDF Engine » Need help/direction for WMF file. » 2025-04-19 07:42:30

rvk

You might want to fix your links.
They give "Incomplete or wrong Download URL."

#8 Re: PDF Engine » DrawMeta is not drawing correct image. » 2025-03-17 09:21:40

rvk

You might want to provide an example for this. Without it, it would be hard to diagnose the problem.
(You can provide larger parts of code via github gist)

#9 Re: PDF Engine » Does SynPdf support drawing polygons with brushes with Bitmaps ? » 2025-03-17 09:09:36

rvk

The metafile renderer is (probably) still not complete.
See this post: https://synopse.info/forum/viewtopic.php?pid=1549#p1549

It might also depend on what source you are using. The latest SynPDF is in mORMot2 (mormot.ui.pdf.pas). If you are still using the older SynPDF sources, that one isn't updated anymore.

Either way... without any example EMF file we can't even begin to look at the problem.

#10 Re: PDF Engine » Differences with PDF generation on different computers » 2025-02-10 16:32:19

rvk
moctes wrote:

Sorry for the delay in answering, thanks for your advice, I will implement it although the problem seems to have come from somewhere else, my client had to restart his computer due to operating system updates and after the

(BTW. I meant Adobe reader as reader, not Adobe full suite.)

I don't use any Adobe products, for the reader, all browsers have support to view PDF files and in cases where I need a PDF reader ( on Windows ) I use Sumatra reader which is the lightest PDF reading software I could find

In Sumatra reader you can press CTRL+D for properties (or use the menu) and then use "Get Fonts Info". There you can see which fonts are used and which are embedded.

It's advisable to always embed the fonts (at least a subset of the fonts) that are not default on all systems.
Calibri is widely used but there are some systems that don't have them.

(Maybe not a problem for you at the moment, if you know what fonts are on the systems, but you should keep it in mind wink )

moctes wrote:

Sorry for the delay in answering, thanks for your advice, I will implement it although the problem seems to have come from somewhere else, my client had to restart his computer due to operating system updates and after the restart everything went back to normal, the PDF is generated correctly again.

Glad to hear it was just a glitch in the system and all it took was a restart.

#11 Re: PDF Engine » Differences with PDF generation on different computers » 2025-02-07 19:06:08

rvk
moctes wrote:

PDF.EmbeddedTtf := True;
I don't have it but I can do that

Yes, not sure what fonts you used but if it's not one of the few which are default on all systems, it's best to embed the fonts.

pdf.EmbeddedTTF := true;
pdf.EmbeddedTTFIgnore.Text := RawUTF8('Arial'#13#10'Times New Roman'#13#10'Courier New'#13#10'Symbol'#13#10'WingDings');;
pdf.EmbeddedWholeTTF := false; // I use this so not the whole font-data is included

The EmbeddedTTFIgnore are the fonts which are usually on all systems.
For Windows the list is a bit bigger (see MSWINDOWS_DEFAULT_FONTS in the source) but I only used these.

(BTW. I meant Adobe reader as reader, not Adobe full suite.)

#12 Re: PDF Engine » Differences with PDF generation on different computers » 2025-02-07 17:50:21

rvk

Did you embed the used fonts?
(See ctrl+d in Adobe and then fonts tab)

#13 Re: PDF Engine » Converting EMF content containing the Calibri font to PDF » 2025-02-07 12:59:02

rvk
Juergen_Bauer wrote:

I use the current SynPDF version (1.18).

The SynPDF version isn't developed actively anymore. For that you need the mormot.ui.pdf.pas in https://github.com/synopse/mORMot2/tree/master/src/ui.

But I do use mORMot2 and here the problem is the same (see previous post to @ab).
So there is indeed a problem with retrieving the Glyph for Unicodes (that ſt) used in the EMF.

#14 Re: PDF Engine » Converting EMF content containing the Calibri font to PDF » 2025-02-07 12:41:43

rvk

Note for @ab
I did a bit of digging and found that in TPdfWrite.AddGlyphs the TPdfFontTrueType.GetAndMarkGlyphAsUsed is called.
For the unicode character U+FB05 ſt this function returns 0 because it can't find that character in fUsedWide.

Why doesn't it add the (unicode) character to the Glyph map when not found?

There is a FindOrAddUsedWideChar in there but that's only used when the Glyph is found in fUsedWide (in which case the add seems a little pointless).

#15 Re: PDF Engine » Converting EMF content containing the Calibri font to PDF » 2025-02-07 11:25:35

rvk

The problem seems to be in this line:

R0035: [084] EMR_EXTTEXTOUTW	(s=112)	{ TXT=[?O?AO] [exScale(0.283008) eyScale(0.281890) iGraphicsMode(1), Bounds(88,84,136,102)] TxOPT[fOptions(16|ETO_GLYPH_INDEX), nChars(6), offDx(88), ptlRef(1320,1256), rcl(0,0,-1,-1)] Spacing[139,126,148,79,115,113 => Total(720) =>xPtRefRight(2039)]}

(used EMFexplorer)

I see there is nChar(6). That means the string should be 6 characters. But Auftrag is 7 characters.
Could it be that the tf in Auftraf is one character?

U+FB05 (ſt) – LATIN SMALL LIGATURE LONG S AND T

I'm not sure why the EMFexplorer renders this correctly. Maybe the unicode gets lost in SynPDF (although I do see tmp is WideChar in TPdfEnum.TextOut).

BTW. You say it is printed via ExtTextout. Where do you see that?
Are you using the old deprecated SynPDF or the newer mORMot PDF engine?

#16 Re: PDF Engine » [Ignore] Drawing. Wmf containing image » 2025-02-07 10:48:29

rvk

@sameerpandit Sorry. I can't help if I can't reproduce it.
And without code and used wmf, I can't reproduce it.

Pointing to some half ready code and no wmf doesn't help with that.

Maybe @ab can be more helpful (but my guess is not without actual being able to reproduce it too).

#17 Re: PDF Engine » [Ignore] Drawing. Wmf containing image » 2025-02-07 08:01:51

rvk

@sameerpandit Can you show code that reproduces that?

A small code sample is always recommended so everyone can try it and trace where the problem is. Otherwise it's just guessing while the problem could also just be in your code

#18 Re: PDF Engine » Bookmarks example » 2024-11-01 15:15:50

rvk
Kaiser wrote:

I tried creating bookmarks:
...
When I open the pdf, there are no bookmarks. Do I need to call another function to enable the bookmarks?

Yeah... 'Bookmarks' is really confusing in PDF/Adobe. Although it's called Bookmarks in the sidebar, they are actually Outlines. It's also called outlines in the PDF specs, so looking for Bookmarks will only confuse you wink

If you do TPdfDocument.CreateOutline() you can create 'Bookmarks' in the PDF (also had to dive into the sourcecode to find that out wink ).

function TPdfDocument.CreateOutline(const Title: string; Level: integer; TopPosition: single): TPdfOutlineEntry;

You can create several levels. 0 is the root and 1 etc are levels under it.

For example:

// pdf.addpage etc
pdf.CreateOutline('Test-page-1- root', 0, 1);
pdf.CreateOutline('Sub bookmark', 1, 20{?});
// pdf.addpage etc
pdf.CreateOutline('Test-page-2-root', 0, 1);

BTW. You do need to use AUseOutlines to true when creating TPdfDocumentGDI, otherwise outline doesn't work.

pdf := TPdfDocumentGDI.Create(true); // <- AUseOutlines = true

#19 Re: PDF Engine » mORMot2 export PDF file output Chinese string prompt error problem. » 2024-09-27 08:21:06

rvk

Yes, there seems to be some problems with Chinese characters (widestring conversion?) in mORMot2 in Lazarus.

This seems to work fine in Delphi (both Canvas.TextOut and Windows.TextOutW):

var
  pdf: TPdfDocumentGDI;
  S: WideString;
begin
  pdf := TPdfDocumentGDI.Create;
  try
    pdf.AddPage;

    // pdf.UseUniscribe := True; // not needed?
    // pdf.AddTrueTypeFont('SimSun'); // not needed?

    pdf.VCLCanvas.Font.Name := 'SimSun'; // 宋体
    pdf.VCLCanvas.Font.size := 20;
    S := WideString('测试内容');

    pdf.VCLCanvas.TextOut(200, 120, S);

    Windows.TextOutW(pdf.VCLCanvas.Handle, 200, 160, PWidechar(S), Length(S));

    pdf.SaveToFile(ExtractFilePath(Application.ExeName) + 'ceshi.pdf');
    ShellExecute(Application.Handle, 'open', pChar(ExtractFilePath(Application.ExeName) + 'ceshi.pdf'), '', '', SW_SHOWNORMAL);
  finally
      pdf.Free;
  end;

end;

I thought I'd try direct TPdfDocument, skipping the GDI entirely... but that also only works in Delphi and crashes on Lazarus.
(With TextOut instead of TextOutW it works but produces garbage characters logically)

var
  pdf: TPdfDocument;
  S: WideString;
begin
  pdf := TPdfDocument.Create;
  try
    pdf.AddPage;

    S := '发现双引号不正确“问题”';
    pdf.Canvas.SetFont('SimSun', 12, []);
    Pdf.Canvas.TextOutW(100, 600, PWideChar(S));

    pdf.SaveToFile(ExtractFilePath(Application.ExeName) + 'ceshi.pdf');
    ShellExecute(Application.Handle, 'open', pChar(ExtractFilePath(Application.ExeName) + 'ceshi.pdf'), '', '', SW_SHOWNORMAL);
  finally
      pdf.Free;
  end;
end;

So yes, definitely a problem with that code on Lazarus.

#20 Re: PDF Engine » Bookmarks example » 2024-09-13 12:19:32

rvk

Do you mean the bookmarks at the right of the PDF?
Have you tried using CreateBookMark yet?

If you search on this forum there are several examples of CreateBookMark (just calling it after page creation).

#21 Re: PDF Engine » Graphics are distorted when DrawMeta function is used in GDIPages » 2024-09-13 12:14:04

rvk

I don't think we can help without a more complete reproduceable example.
(including the metafiles if not generated by the example)

#22 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-16 07:50:24

rvk

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

#23 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-15 17:32:26

rvk

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

#24 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-15 17:25:41

rvk

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

#25 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-15 17:09:57

rvk
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

#26 Re: PDF Engine » Automated PDF testing » 2024-05-15 10:52:31

rvk

In follow up on the other topic... I found a directory here with lots of EMF files to test.
https://github.com/kakwa/libemf2svg/tre … ources/emf

When putting this in the bugreport directory from the other topic... and changing the following.
It will create all the pdf files in that emf directory.
There are lots of pdf that end up corrupt.

And others have strange result. 000 and 015 doesn't have the axes. and 040 also has lots of things wrong.
It indeed shows the need for automated test wink

BTW. comparing images extracted from pdf from a testrun with baseline images would be very hard I imagine. They would never be pixel perfect.
And before that... you would first need to fix all the problems that already exist with the above emf's before using these for regression testing wink

uses
  mormot.ui.pdf, ShellApi, System.IOUtils, System.Types;

procedure TForm1.Button1Click(Sender: TObject);

  procedure ProcessAllFilesInDirectory(const Directory: string);
  var
    Files: TStringDynArray;
    FileName: string;
  begin
    if not TDirectory.Exists(Directory) then exit;
    Files := TDirectory.GetFiles(Directory, '*.emf', TSearchOption.soAllDirectories);
    for FileName in Files do
    begin
      Self.DoConvertMetafileToPdf(Filename, ChangeFileExt(Filename, '.pdf'));
    end;
  end;

begin
  ProcessAllFilesInDirectory(ExtractFilePath(Application.ExeName) + 'emf');
  //Self.DoConvertMetafileToPdf(ExtractFilePath(Application.ExeName) + 'bogus.wmf', ExtractFilePath(Application.ExeName) + 'bogus.pdf');
end;

test-040.pdf
ViYSlwT.png

test-015.pdf
DciMuVV.png

#27 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-15 09:36:12

rvk

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.

#28 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-15 09:25:18

rvk

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);

#29 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-15 09:16:48

rvk

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)

#30 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-15 09:11:27

rvk
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...

#31 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-15 08:30:49

rvk

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

#32 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-14 18:29:40

rvk

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.)

#33 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-14 16:33:41

rvk

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.

#34 Re: PDF Engine » Regression: simple EMF file is drawn with an overlapping/missing rect » 2024-05-14 15:21:44

rvk

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.

#35 Re: PDF Engine » SynPdf library 1.18 Delphi QuickReport 6 Pro and ExpBarChart error » 2024-05-09 17:20:14

rvk

O, and the i + 1 should just be i in your case smile
(You start at 1, not 0)

#36 Re: PDF Engine » SynPdf library 1.18 Delphi QuickReport 6 Pro and ExpBarChart error » 2024-05-08 18:17:56

rvk

In your current code you can put a line like this:

meta.SaveToFile(format('c:\temp\meta-%d.emf', [i + 1])); // this saves the meta to c:\temp
// draw the page content
RenderMetaFile(Pdf.Canvas, aMeta,1,1,0,0); // <-- this is the old line

After that you can test with:

procedure TestMetaToPdf;
var
  Pdf: TPdfDocument;
  aMeta: TMetaFile;
begin
  Pdf := TPdfDocument.Create;
  try
    Pdf.Info.CreationDate  := Now;
    Pdf.Info.Creator := 'meme';
    Pdf.DefaultPaperSize := psA4;
    Pdf.AddPage;
    aMeta := TMetaFile.Create;
    try
      aMeta.LoadFromFile('c:\temp\meta-1.emf');
      // draw the page content
      RenderMetaFile(Pdf.Canvas, aMeta,1,1,0,0);
    finally
      aMeta.Free;
    end;

    try
      Pdf.SaveToFile('c:\temp\test9.pdf');
    finally
      // Send to ...
    end;

  finally
    Pdf.free;
  end;
end;

#37 Re: PDF Engine » SynPdf library 1.18 Delphi QuickReport 6 Pro and ExpBarChart error » 2024-05-08 17:51:26

rvk
HansVM wrote:

I still get the error on the quickreport.TQRExpBarChart in Delphi 10.2 and QReport V6 Pro.

If you are using the latest mORMot2, can you save the metafile to file and try loading it in a separate procedure.
If it still gives you problems maybe you can share that metafile.

(Just to rule out any potential problems in combination with TQRExpBarChart)

I used meta.LoadFromFile and RenderMetaFile() and that worked fine.

#38 Re: PDF Engine » SynPdf library 1.18 Delphi QuickReport 6 Pro and ExpBarChart error » 2024-05-08 16:27:44

rvk
HansVM wrote:

Ok I have installet the mORMot2.

But it will not have this line Pdf.Canvas.RenderMetaFile(aMeta,1,1,0,0);

No, there is no TPDFCanvas.RenderMetaFile.
But you should use procedure RenderMetaFile() for that.
It's in mormot.ui.pdf so you can just call it.

You pass your Pdf.Canvas as first parameter. Rest is the same.

procedure RenderMetaFile(C: TPdfCanvas; MF: TMetaFile; ScaleX: single = 1.0;
  ScaleY: single = 0.0; XOff: single = 0.0; YOff: single = 0.0;
  TextPositioning: TPdfCanvasRenderMetaFileTextPositioning = tpSetTextJustification;
  KerningHScaleBottom: single = 99.0; KerningHScaleTop: single = 101.0;
  TextClipping: TPdfCanvasRenderMetaFileTextClipping = tcAlwaysClip);

#39 Re: PDF Engine » SynPdf library 1.18 Delphi QuickReport 6 Pro and ExpBarChart error » 2024-05-08 09:50:06

rvk

You are using the older SynPDF? (Newer source is in mORMot2)

I can't spot the problem exactly... but you have a Pdf.CleanupInstance.
TObject.CleanupInstance should never be called directly.

The aMeta.Clear also seems useless (because that should also be done in aMeta.Free).

Remove those two lines and see if it helps.
Although the error doesn't seem to point to those places, it could be because of the try/finally (and exception handling).

Something like this:

procedure TfPrinterOptions.ExportAsPdf(QuickRep: TQRCompositeReport; aFileName, aDescription: String);
var
  Pdf: TPdfDocument;
  aMeta: TMetaFile;
  i: integer;
  pdfFilter: TQRPDFDocumentFilter;
begin

  if NOT dmVA.aQryVAPraktice.Active then
    dmVA.aQryVAPraktice.Active := True;
  dmVA.aQryVAPraktice.Active := False;
  QuickRep.Prepare;

  Pdf := TPdfDocument.Create;
  try
    Pdf.Info.CreationDate  := Now;
    Pdf.Info.Creator := dmVA.aQryVAPraktice.FieldByName('PrakticeName').AsString;
    Pdf.DefaultPaperSize := psA4;

    for i := 1 to QuickRep.QRPrinter.PageCount do
    begin
      Pdf.AddPage;
      aMeta := QuickRep.QRPrinter.GetPage(i);
      try
        // draw the page content
        Pdf.Canvas.RenderMetaFile(aMeta,1,1,0,0);
      finally
        aMeta.Free;
      end;
    end;
    
    try
      Pdf.SaveToFile(aFileName); // Error Access violation at address 004C4620 in module ...
    finally
      // Send to ...
    end;

  finally
    Pdf.free;
  end;
end;

#40 Re: PDF Engine » Clipping problem after image » 2024-04-26 09:36:13

rvk
ab wrote:

I agree it should be reset, but not always.
Adding GRestore/GSave always would pollute the output with a lot of q and Q commands for no benefit if clipping is not involved.
Those GRestore/GSave should be done only when needed.

Yes, probably. But I rather have a lot of q/Q than clipping in the wrong place where text (and in my case even an amount/currency column) is clipped wink

That being said... shouldn't EMR_RESTOREDC always do a restore Q in PDF? It's not for nothing EMR_RESTOREDC is in the EMF.

The q/Q are for pushing/restoring the graphical state. But Line Width/Brush etc. are also part of the graphical state (PDF1.7 4.3.1).
So when SAVEDC/RESTOREDC is called in EMF, it's only logical to (ALWAYS) do the same in PDF, regardless if it's needed (because you can't possibly determine the actual need to do so without evaluating everything that comes before it).

GDI

The SaveDC function saves the current state of the specified device context (DC) by copying data describing selected objects and graphic modes (such as the bitmap, brush, palette, font, pen, region, drawing mode, and mapping mode) to a context stack.

PDF

These operators can be used to encapsulate a graphical element so that it can modify parameters of the graphics state and later restore them to their previous values.

I think with the adjustments of MtwStark, it will also always save/restore on SaveDC/RestoreDC. But those where developing adjustments.

In llPDFEMF.pas it seems to set a Clipping := true on EMR_EXTSELECTCLIPRGN and only does FCanvas.GStateRestore in RestoreDC when that Clipping is set.
It seems clipping is a lot more 'mature' in that code. But that was already known.

ab wrote:

But to me it sounds like if GStateRestore is not called always, but only within text processing.

It looks like most calls to GStateRestore are done when Clipping is true (so not only within text processing).

But as stated before... in EMF... even a simple SAVEDC, set Line Width to 100, do nothing else and RESTOREDC, should restore the line width.
I don't think that's being done now when translating this to PDF.

So I don't think lot's of q/Q is polluting the PDF... it's just following the EMF.
You could check the complete graphical stack (not only clipping, but also bitmap, brush, palette, font, pen, region, drawing mode, and mapping mode) and see if that's changed. If it's not changed, you could omit the q/Q. But that seems like a lot of work. Besides IsClipping you would need IsLineWidthSet, IsBrushSet, IfFontSet etc. etc. Just doing a q/Q would be much simpler (and it follows the EMF).

(If I got some time I'll check some other EMF->PDF converters. Until then I'll test the stability of adding the q/Q)

#41 Re: PDF Engine » Clipping problem after image » 2024-04-26 06:54:39

rvk

Shoutout to @everyone...
Does anyone have more experience with rendering metafiles through GDI to PDF via mORMot2 ?

I have emf streams/files (created via TJvRichEdit) with images.
In those emf streams, after the image is drawn with EMR_STRETCHDIBITS.
Followed by a EMR_EXTSELECTCLIPRGN to clip the drawn region to size.
And again followed by several EMR_RESTOREDC.

But in mORMot2 (SynPdf), the clipped region isn't reset when calling RestoreDC.
As a result... everything after this, is clipped away.

My feeling is, that in EMR_SAVEDC/EMR_RESTOREDC (so in Canvas.GSave/Canvas.GRestore), the clipping region should also be reset.

I changed my code here to include GSave/GRestore inside and that does seems to do the job.
But I'm unsure if this is the whole solution. Maybe the other GSave/GRestores can be removed because it should already be done in the emf itself.

(BTW. A small look at llPDFLib DoRestoreDC I see it does the same.)

procedure TPdfEnum.RestoreDC;
begin
  Assert(nDC > 0);
  Canvas.GRestore; // <--- add this
  dec(nDC);
end;

procedure TPdfEnum.SaveDC;
begin
  Assert(nDC < high(DC));
  Canvas.GSave; // <--- add this
  DC[nDC + 1] := DC[nDC];
  inc(nDC);
end;

I will change this in my code and see how it does in production. But maybe someone with more experience can confirm my findings.
@MtwStark @ArnoBrinkman ??

Edit: Ha, I now see MtwStark was already working on that.

procedure TPdfEnum.SaveDC;
begin
  Assert(nDC < high(DC));
  DC[nDC + 1] := DC[nDC];
  inc(nDC);
{$IFDEF TMW_TEST_NEW_CLIPRGN}
  // MTW 2018-01-30 - the problem wasn't GRestore/GSave, but was the invalidation of graphic state parameters
  Canvas.GSave;
{$ENDIF}
end;

https://synopse.info/forum/viewtopic.ph … 786#p25786

It's a real shame more extensive GDI support isn't implemented in mORMot2 itself over the years.


R0141: [037] EMR_SELECTOBJECT	(s=12)	{Table object: 6=OBJ_FONT}
R0142: [033] EMR_SAVEDC	(s=8)
R0143: [022] EMR_SETTEXTALIGN	(s=12)	{iMode(0= TA_LEFT TA_TOP)}
R0144: [033] EMR_SAVEDC	(s=8)
R0145: [030] EMR_INTERSECTCLIPRECT	(s=24)	{rclClip(118,222,131,262)}
R0146: [033] EMR_SAVEDC	(s=8)
R0147: [030] EMR_INTERSECTCLIPRECT	(s=24)	{rclClip(118,242,131,255)}
R0148: [017] EMR_SETMAPMODE	(s=12)	{iMode(8=MM_ANISOTROPIC)}
R0149: [012] EMR_SETVIEWPORTORGEX	(s=16)	{ptlOrigin(118,242)}
R0150: [011] EMR_SETVIEWPORTEXTEX	(s=16)	{szlExtent(13,13)}
R0151: [010] EMR_SETWINDOWORGEX	(s=16)	{ptlOrigin(0,0)}
R0152: [009] EMR_SETWINDOWEXTEX	(s=16)	{szlExtent(106,106)}
R0153: [081] EMR_STRETCHDIBITS	(s=168)	{rclBounds(118,242,130,254), Dest[x:0, y:0, cx:106, cy:106)], dwRop(0x00CC0020), Src[x:0, y:0, cx:4, cy:4, iUsage:0, offBmi:80, Bmi:40, offBits:120, Bits:48] BmiHeader[biSize:40, biWidth:4, biHeight:4, biPlanes:1, biBitCount:24, biCompression:0, biSizeImage:48, biXPelsPerMeter:3779, biYPelsPerMeter:3779, biClrUsed:0, biClrImportant:0]}
R0154: [037] EMR_SELECTOBJECT	(s=12)	{Table object: 2=OBJ_PEN.(PS_SOLID | COSMETIC)}
R0155: [037] EMR_SELECTOBJECT	(s=12)	{Table object: 3=OBJ_BRUSH.(BS_SOLID)}
R0156: [048] EMR_SELECTPALETTE	(s=12)	{ihPal(Stock object: 15)}
R0157: [075] EMR_EXTSELECTCLIPRGN	(s=64)	{iMode(5=RGN_COPY), RGNDATA[ptr:0x066b12f0, size:48, box(118,242,131,255)]}
R0158: [034] EMR_RESTOREDC	(s=12)	{iRelative(-1)}
R0159: [034] EMR_RESTOREDC	(s=12)	{iRelative(-1)}
R0160: [034] EMR_RESTOREDC	(s=12)	{iRelative(-1)}
R0161: [037] EMR_SELECTOBJECT	(s=12)	{Table object: 5=OBJ_FONT}
R0162: [084] EMR_EXTTEXTOUTW	(s=76)	{ TXT=[] [exScale(8.458333) eyScale(8.467624) iGraphicsMode(1), Bounds(0,0,-1,-1)] TxOPT[fOptions(0), nChars(0), offDx(76), ptlRef(131,213), rcl(0,0,-1,-1)] Spacing[84 => Total(84) =>xPtRefRight(214)]}
R0163: [084] EMR_EXTTEXTOUTW	(s=76)	{ TXT=[] [exScale(8.458333) eyScale(8.467624) iGraphicsMode(1), Bounds(0,0,-1,-1)] TxOPT[fOptions(16|ETO_GLYPH_INDEX), nChars(0), offDx(76), ptlRef(131,213), rcl(0,0,-1,-1)] Spacing[84 => Total(84) =>xPtRefRight(214)]}
R0164: [084] EMR_EXTTEXTOUTW	(s=76)	{ TXT=[] [exScale(8.458333) eyScale(8.467624) iGraphicsMode(1), Bounds(0,0,-1,-1)] TxOPT[fOptions(0), nChars(0), offDx(76), ptlRef(118,262), rcl(0,0,-1,-1)] Spacing[84 => Total(84) =>xPtRefRight(201)]}
R0165: [084] EMR_EXTTEXTOUTW	(s=76)	{ TXT=[] [exScale(8.458333) eyScale(8.467624) iGraphicsMode(1), Bounds(0,0,-1,-1)] TxOPT[fOptions(16|ETO_GLYPH_INDEX), nChars(0), offDx(76), ptlRef(118,262), rcl(0,0,-1,-1)] Spacing[37 => Total(37) =>xPtRefRight(154)]}

#42 Re: PDF Engine » Clipping problem after image » 2024-04-23 20:30:40

rvk

Clipping works perfectly in synpdf with an image in TJvRichedit.
I use the TPdfDocumentGDI and it enumerates perfectly through the EMR_STRETCHDIBITS for the image.

After that the richedit/Windows does the clipping for transparency through EMR_EXTSELECTCLIPRGN. That also works perfectly for my hand signature as image in the richedit.

It's just that any text after it is also clipped.
Or seems like the TPdfEnum.ExtSelectClipRgn leaves the clipping in a wrong state.

But I'll investigate this further. I have a feeling it's just a minor bug which can be fixed really easy but I was hoping you would have some more expertise as to how that newpath worked and would spot the bug more easily. But I'll get into it and report back when I find something.

After my last pull request the clipping works very good, at least for the RGN_COPY part. It just that the clipping seems to be left in a wrong state (on?).

#43 Re: PDF Engine » Clipping problem after image » 2024-04-23 17:31:31

rvk

Argh. I do need the NewPath line there. Otherwise the clipping mechanisme doesn't work for my other part of the PDF (for my signature where the clipping needs to be on another background pdf with pdftk).

So the question remains... why does the the clipping continue after an image (as shown in Image 2)?

You can load the meta.emf in emfexplorer.exe and see what happens there.
Also... rendering it on screen works correctly.
It's just creating a PDF from it, it hides everything after the image.

#44 PDF Engine » Clipping problem after image » 2024-04-23 17:21:49

rvk
Replies: 6

I have a clipping problem in the resulting PDF after rendering an image (GDI).
I have a TJvRichEdit with an image. Everything after the image is clipped away. It is still there (I can select it in Adobe reader and copy it to a text-editor) but it seems to be clipped away.

I can create a meta file in which the problem isn't present.
Loading the emf in a TMetaFile and rendering it to TPdfDocumentGDI with RenderMetaFile() the problem is that everything after the image doesn't show.

The EMR_STRETCHDIBITS is done correctly. But directly after that is a small EMR_EXTSELECTCLIPRGN block, which doesn't seem to close the clipping path correctly (??)

I can trace the problem to TPdfEnum.ExtSelectClipRgn.

All the way at the bottom there, there is the following.

    Canvas.Closepath;
    Canvas.Clip;
    Canvas.NewPath; // <----
    Canvas.FNewPath := false;

If I comment out the Canvas.NewPath there, it works correctly (see first image).
I'm not familiar with the NewPath and FNewPath mechanisme but I'm guessing there goes something wrong at that point (second image).
So the problem is that I don't know if I can leave that NewPath out, without causing other problems.
(and why is it causing the problem)

Code:

function ExecAssociatedApp(const FileName: string; Action: string = ''): boolean;
var
  rs: Word;
  Shw: integer;
begin
  Shw := SW_SHOW;
  rs := Winapi.ShellAPI.ShellExecute(0, pchar(Action), pchar(FileName), nil, nil, Shw);
  Result := rs > 32;
end;

procedure TestClip;
var
  FileTemp: string;
  meta: TMetaFile;
  pdf: TPdfDocumentGDI;
begin
  FileTemp := 'C:\Temp\Test1.pdf';
  meta := TMetaFile.Create;
  pdf := TPdfDocumentGDI.Create;
  try
    pdf.UseOptionalContent := true;
    pdf.Info.Title := 'Title name';
    pdf.Info.Author := 'User name';
    pdf.Info.Creator := 'Software name';
    pdf.Info.subject := 'Auto generated document';

    { page := } pdf.AddPage;

    meta.LoadFromFile('c:\temp\meta.emf');
    RenderMetaFile(pdf.Canvas, meta);

    pdf.SaveToFile(FileTemp);
    ExecAssociatedApp(FileTemp);

  finally
    meta.Free;
  end;
end;

Metafile (temporarily)
https://www.graficalc.nl/meta.emf

Correct (with the NewPath commented out):
2024-04-23-19-02-58-Test1-pdf.png

Incorrect (original code, with NewPath intact):
2024-04-23-19-04-10-Test1-pdf.png

#45 Re: PDF Engine » TGDIPages.AppendRichEdit() doesn't import some PNG images » 2024-04-23 16:55:19

rvk

I'm not sure about Delphi 11 (I'm still on 10.2) but TJvRichEdit supports images. They have Ole callback stuff which is probably needed to render the images to the metastream.

(I currently do have a small problem with images, not showing text after an image, but I'll open a new topic for that)

#46 Re: PDF Engine » PDF Info (title etc) not saved in PDF version >1.3 » 2023-12-28 16:08:11

rvk
padule wrote:

Is this normal?

Works fine for me (with latest mORMot 2 sources).

What version of code are you using?
(otherwise a small sample would be helpful)

This works for me (generates a 1.5 PDF):

procedure MakePdfSynPdf;
var
  FileTemp: string;
  pdf: TPdfDocumentGDI;
begin
  FileTemp := 'C:\Temp\Test1.pdf';
  pdf := TPdfDocumentGDI.Create;
  try
    pdf.UseOptionalContent := true;
    pdf.Info.Title := 'Title name';
    pdf.Info.Author := 'User name';
    pdf.Info.Creator := 'Software name';
    pdf.Info.subject := 'Auto generated document';

    // page 1
    { page := } pdf.AddPage;
    pdf.VCLCanvas.Font.Name := 'Times New Roman';
    pdf.VCLCanvas.Font.size := 24;
    pdf.VCLCanvas.TextOut(100, 100, 'some text on page 1');

    // page 2
    { page := } pdf.AddPage;
    pdf.VCLCanvas.Font.Name := 'Times New Roman';
    pdf.VCLCanvas.Font.size := 24;
    pdf.VCLCanvas.TextOut(100, 100, 'some text on page 2');

    // back to page 1
    pdf.Canvas.SetPage(pdf.RawPages[0]);
    pdf.VCLCanvas.Font.Name := 'Times New Roman';
    pdf.VCLCanvas.Font.size := 24;
    pdf.VCLCanvas.TextOut(200, 200, 'some extra text on page 1');

    pdf.SaveToFile(FileTemp);

    ExecAssociatedApp(FileTemp);

  finally
      pdf.Free;
  end;

end;

#47 Re: PDF Engine » Compile SynPdf error » 2023-11-22 20:55:46

rvk
ab wrote:

You are right, mormot2ui does not install any component - there is no component installed with Lazarus packages anway IIRC.

No, components are installed via packages in Lazarus. Same as with Delphi. Only when you click Install the whole IDE (lazarus) gets re-compiled.

Now the mormot2ui package is made as an install (design-time) package which recompiles the IDE while this shouldn't be necessary because there is no components installed. So it can just be a non-design package (same as the mormot2).

It does work as it is now but "Install" wouldn't be needed I think.
Unless components are added.

BTW. In Delphi only the path is added to the project after which everything gets compiled automatically. This could also be done the same way with Lazarus or FPC. But a package could add that path automatically which is easier. But I think the package could also just contain all the needed paths without adding all the files specifically (but somehow that doesn't work correctly now). I will look into that.

ab wrote:

Note that mormot.ui.pdf would work on Windows only, as documented in the unit.

Ah, yeah, I didn't look at that. I think FPC has its own fcl-pdf package anyway.

#48 Re: PDF Engine » Compile SynPdf error » 2023-11-22 19:34:04

rvk
ab wrote:

At least the mORMot 2 unit (should) compile with FPC and Windows.

You probably just want the complete mORMot 2 package. Compiling just the mormot.ui.pdf.pas will pull in everything else anyway.

Compiling mORMot 2 on Lazarus/FPC trunk (from 2 months ago) works fine.

I only had to include mormot.ui.pdf.pas and mormot.lib.uniscribe as files in my console project because they are not in the mormot2ui.lpk.
(mormot.ui.report.pas is missing there too)

I did get this message during install of mormot2ui.lpk.

Suspicious include path
The package mormot2ui 2.0.1 adds the path "$(PkgIncPath)" to the include path of the IDE.
This is probably a misconfiguration of the package.

It probably doesn't add the path to the include path.
The path is in the package but somehow it doesn't get included automatically to the project when adding mormot2ui as requirement.

Manually setting "mORMot2\src\ui;mORMot2\src\lib" as "Other unit files" in projects options works too.

After that, creating a PDF with TPdfDocumentGDI isn't a problem.

Can't speak about the rest of mORMot 2 wink

But overall, using mormot.ui.pdf shouldn't be too hard on Lazarus (Windows, I didn't test Linux).

BTW. mormot2ui should install designtime components, shouldn't it?
I don't think it does. It does have the "Install" button but I don't think it really installs anything.
(or I'm just looking in the wrong place)

Edit: Ah, this probably answers it wink

// do-nothing-unit on non Delphi + Windows system
// = not yet compatible with FPC/LCL due to a lot of Windowsims and VCLisms :(
procedure Register;
begin
end;

#49 Re: PDF Engine » Compile SynPdf error » 2023-11-22 13:58:38

rvk

@loadymf. In addition... you might want to try mORMot 2 which includes src/ui/mormot.ui.pdf.pas with the latest changes to the PDF engine. It might give you more luck.

#50 Re: PDF Engine » PDF:AddXObject is slow and out of memory! » 2023-10-15 13:38:12

rvk
Flashcqxg wrote:

I test with the TPdfDocumentGdi , and set the i from 1 to 70000,it out of memory!

With the latest version of mormot2.ui.pdf your code works fine for me (in Delphi 10.2 and 32 bit app) and results in a pdf of 25MB with 70.000 pages.
So you might want to use the latest version (the mormot2 one, not the synpdf one).

Board footer

Powered by FluxBB