#1 Re: mORMot 2 » wrong Iso8601ToDateTime conversion » 2026-02-25 21:13:52

rvk
ab wrote:

Values before TDateTime = 0 are just not supported.

In that case you might want to add an assert (or other check/exception) for that ?
(That would be the easiest)

Maybe someone can suggest a patch for TDateTime < 0 if needed and accepted.

#2 Re: mORMot 2 » Database connection (too many connections) » 2026-02-16 09:58:59

rvk
anouri wrote:

but I think problem is not there.

Then you might want to find out how many connections there are (at that point) and why the pool isn't releasing them if they are outdated.

And if there are too many, is this because this is a new thread each time, or that there is something wrong with releasing or reusing the connections in the pool?

You can't really see that from this snippet of code so you might have to explain exactly how fast, how many times, and in what context this is called (i.e. how this code is used).

And if ThreadingMode is set at tmMainConnection then it shouldn't even create new connections at all (and reuse the main connection).

#3 Re: mORMot 2 » Database connection (too many connections) » 2026-02-16 09:12:51

rvk

I can't really comment on the use of mORMot (I only use a small portion of it).
But I do see some issues with your code.

*) On line 10 in GetConnection.pas you get a pmoConnection. Line 11 sets result to true if pmoConnection is not nil.
       But.... if it is nil, it does execute line 12 where you access pmoConnection.IsConnected. If pmoConnection is nil this will result in an (silent?) exception (access violation) which you don't catch.

*) On line 8 of SaleOrderService.pas you do GetConnection(). GetConnection is a function which returns a boolean result. You don't check if this was successful and go on in the code as if it was. You need to exit the function if it was unsuccessful. Because the out of GetConnection could be nil (so LDBConn would be nil). This can also cause silent exceptions (also access violation).

I'm not sure if these 2 problems could cause your issue over time but it's something to fix wink

#4 Re: PDF Engine » Clipping problem after image » 2026-02-06 08:27:57

rvk

I see I still need to make these changes after each update to trunk to fix the clipping of text after an image with GDI+ rendering.

procedure TPdfEnum.RestoreDC;
begin
   Assert(nDC > 0);
+  Canvas.GRestore;
   dec(nDC);
end;

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

Luckily I could find back my notes... (I knew these changes had a reason wink )

rvk wrote:

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.

#5 Re: mORMot 2 » Could not compile used unit 'mormot.core.unicode.pas' at commit 671855 » 2026-02-05 12:17:20

rvk

I can confirm this. I also just mentioned it in another topic.
There is also an syntax error in mormot.ui.pdf.pas
https://synopse.info/forum/viewtopic.ph … 125#p45125

#6 Re: mORMot 2 » TRestHttpServer mormot.core.text.pas IsInvalidHttpHeader » 2026-02-05 09:42:22

rvk

I can't even compile the current trunk/master on Delphi 10.2.

First I get an error regarding UnCamelCase.
[dcc32 Error] mormot.core.rtti.pas(6253): E2250 There is no overloaded version of 'UnCamelCase' that can be called with these arguments

After fixing that (with a related fix) I get an error in this line:
[dcc32 Error] mormot.ui.pdf.pas(12254): E2029 'THEN' expected but ')' found

        if w < Trunc(R.rclBounds.Right - R.rclBounds.Left) / Canvas.fFactorX) then

This latest source from that file is from januari 27th so...
https://github.com/synopse/mORMot2/blob … pas#L12254

It's amazing how you can compile the latest mORMot2 without any problems wink wink

About the IsInvalidHttpHeader from this topic... I also couldn't reproduce this under Delphi 10.2 win64.
So hopefully @slan2026 can provide more information about the problem and debug exactly on what line the error occurs.

#7 Re: mORMot 2 » TRestHttpServer mormot.core.text.pas IsInvalidHttpHeader » 2026-02-04 09:22:24

rvk

I wonder why that IsInvalidHttpHeader changed so much?

It used to be a simple lineair search for invalid line-breaks.
If you look at it now... it became so much more complex (and prone to errors and bugs, as is now the case).

This is the old version:
https://github.com/synopse/mORMot2/blob … .pas#L5473

This is the newer expanded version:
https://github.com/synopse/mORMot2/blob … pas#L10862

It's also strange that searching for IsInvalidHttpHeader on github doesn't give you the location of this function, while it is in the repository.

#8 Re: mORMot 2 » How set LineSpacing inside Header and Footer » 2026-02-02 21:22:17

rvk

Did you set OnStartPageHeader := MyReportHeader ??
It should trigger when doing the header.

I do see the line
  if (fHeaderLines.Count = 0) then exit;
So it will only trigger if you have at least added one line the usual way (it may be just a line with one space).

(This might be considered a 'bug' because it should also trigger when you didn't add a line via add header.)

#9 Re: mORMot 2 » How set LineSpacing inside Header and Footer » 2026-02-02 20:38:58

rvk

I can't find any documentation or complete example. So you just have to use it.
Like this:

ab wrote:

You have to set OnStartPageHeader and OnEndPageHeader event handlers of the TGDIPages instance with your own methods.

procedure MyReportHeader(Sender: TObject);
var Report: TGdiPages;
begin
  Report := Sender as TGdiPages;
  Report.DrawBMP(....);
end;

......
   with TGdiPages.Create(self) do
   try
     OnStartPageHeader := MyReportHeader;
....

 
Hope it helps.

#10 Re: mORMot 2 » How set LineSpacing inside Header and Footer » 2026-02-02 20:20:09

rvk
ab wrote:

See the OnStartPageHeader and OnEndPageHeader event handlers.
The Sender is the current TGDIPages instance.

You can easily add a bitmap to every header using one of those events.

https://synopse.info/forum/viewtopic.php?id=598

#11 Re: mORMot 2 » How set LineSpacing inside Header and Footer » 2026-02-02 09:33:46

rvk

As far as I could see the Header/Footer in mormot.ui.report is just printed as is, separate lines with no special layout. You can't even position text.

I had some specific requirements of other parts of the "report" mechanisme... so I took the whole TGdiPages and stripped out everything I didn't need (which was a lot). Ended up with just under 700 lines of code. So that might be the way to go if you need something special from Header and Footer. Or try to inherit TGdiPages and change the things you need (but I'm not sure how far you can go with that). You could also just generate the headers and footers yourself.

#12 Re: mORMot 2 » How Draw a paragraph only 50% of page with TGDIPages » 2026-01-28 11:39:31

rvk
Sapiem wrote:

Sorry another doubt: is it possible to display the pages one after another instead of a single one, and switch between them one by one using the buttons in the upper corners?

As far as I can see, the page navigation is build in the TGDIPages component, so my guess is that you can't show a continues page layout.

#13 Re: mORMot 2 » How Draw a paragraph only 50% of page with TGDIPages » 2026-01-27 10:16:36

rvk
Sapiem wrote:

It doesn't justify

Your code does justify on break characters.

BUT... did you check what the break character for the font Segoe UI is ???
It's not "space" wink

Change your code to use 'Arial' as font and you see the justify is done correctly on the break character (which is space for Arial).

Otherwise use the GetTextMetrics function to find out what the break character is for Segoe UI.

When using Justify, there is extra space added to certain "break characters" (usually this is the space character for normal fonts).
If the break character is different, then you won't get justify on space and the justification doesn't work.

See the documentation for more information about justify and break characters.
https://learn.microsoft.com/en-us/windo … tification

Edit: BTW, just check the break character for Segoe UI. It's #13, not #32. So that's the reason for it not justifying.

procedure GetFontBreakChar(Canvas: TCanvas; out BreakChar: WideChar);
var
  Metrics: TTextMetric;
begin
  GetTextMetrics(Canvas.Handle, Metrics);
  BreakChar := Metrics.tmBreakChar;
end;

#14 Re: PDF Engine » Clipping of a large metafile when outputing to a PDF » 2025-12-18 09:21:26

rvk
Georgi wrote:

I'm using the latest SynPDF (downloaded from here https://github.com/synopse/SynPDF), source code bellow.

Yeah, that could be the reason.

I now tried it with the ScreenLogPixels and the result here is this (and you see that clipping is done correctly):
https://i.imgur.com/BWCFI5q.png

In your PrintToPDF there seems to be a missing footer?
It's printed slightly larger, so the footer is cut off.

Also... in the PrintToPDF, the line above the boxes at the right and the line above the lower right box seem to run against the overall border-line. But this isn't the case in the original EMF, is it? In the PDF from mORMot2, this is done correctly.

But... in mORMot2, the line of the boxes seem to be dotted instead of solid.
And the CH3 aren't placed correctly at the end of the lines.
https://i.imgur.com/8cAzoxg.png

Those last misplacements could be some small bugs in the GDI+ positioning in the mORMot2 code (which can be fixed if needed).

#15 Re: PDF Engine » Clipping of a large metafile when outputing to a PDF » 2025-12-17 14:43:18

rvk

If I use EMFexplorer I also see the run-off (so no clipping).
If I disable "Use GDI+" there (via Document, uncheck "Use GDI+"), the clipping does occur correctly.

In mormot.ui.pdf there is a RenderMetaFile() function (with EnumEnhMetaFile and a clipping parameter).
Did you try that?

What is the code to print after aMeta.LoadFromFile because I couldn't get the dimensions correct?
With factor scaling 0.1 the result I got here is this: https://i.imgur.com/afa83Iy.png
Which seems to be correct regarding the clipping.

Did you use the latest mormot2 (and not the old SynPdf source) ?

#16 Re: mORMot 2 » mORMot2 (2.3 stable) fail to create x64 package » 2025-11-27 19:50:17

rvk
imperyal wrote:

Sorry, how do I get that trunk?

Link here at the top of the forum "mORMot2"
or go to https://github.com/synopse/mORMot2.

Click the green "Code" button and download the zip or use git with the git url. That's always the latest development version ('trunk').

#17 Re: mORMot 2 » memory leak that I can't find » 2025-11-21 09:49:22

rvk
anouri wrote:

how can I find location of memory leak?
madexcept shows line number and unit name. what about fastmm

The default fastmm is very basic in Delphi and it doesn't show the line number etc. It just shows the leaked memory. Often you can see what type of record is leaked. But if you can't you will need something stronger.

You could use the full FastMM4 library. It would involve adding a dll to your exe directory and putting 3 files (2 pas and 1 inc) in your source directory. Defining FullDebugMode in the inc and running it with a debugger on, it will provide you with a txt file which shows the location the leaked memory was created.

See for more info: https://stackoverflow.com/a/1130506

This would show something like (from your example, so the GetMem would be on line 8 of test):

--------------------------------2025/11/21 10:46:05--------------------------------
A memory block has been leaked. The size is: 12

This block was allocated by thread 0x4004, and the stack trace (return addresses) at the time was:
4046BE [System.pas][System][System.@GetMem][4749]
42155E [test][test.test][8]
76B1FCC9 [BaseThreadInitThunk]
77DE82AE [RtlGetAppContainerNamedObjectPath]
77DE827E [RtlGetAppContainerNamedObjectPath]

The block is currently used for an object of class: Unknown

The allocation number is: 111
<snip_and_more>

#18 Re: mORMot 2 » Converting all datetime values in a record to localtime » 2025-11-21 08:46:03

rvk

For completeness, here is a example changing all TDateTime in a record using TRttiContext in Delphi:

https://gist.github.com/rvk01/6a1cba7da … f4dc5ed407

#19 Re: mORMot 2 » memory leak that I can't find » 2025-11-19 15:55:25

rvk
anouri wrote:

without madexcept or urokalog how can I find memory leaks?

If you're using the default Memory Manager (FastMM) then you can also just use the Delphi method.

Put this in the .dpr below the Application.Initialize line.

{$WARN SYMBOL_PLATFORM OFF}
  ReportMemoryLeaksOnShutdown := DebugHook <> 0;
{$WARN SYMBOL_PLATFORM ON}

https://docwiki.embarcadero.com/Librari … OnShutdown

And now if you run with debugger on (DebugHook > 0) then it will popup a message when closing your app if there is a memory leak.
You can also just set it to true but I like to always have it when I'm running with debugger (not as user).

#20 Re: PDF Engine » different Fonts with enbedded PDF viewer in EDGE » 2025-07-31 10:52:14

rvk

Are you using one of the standard fonts? Or using another font?
If you use another font you need to fully (or partially) embed that font.

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;

Do you have an example PDF?

#21 Re: PDF Engine » PDF as Background Image » 2025-07-11 16:52:25

rvk
etwoss wrote:

Is there no complete example on how to add a watermark? I'm new to SyncPDF

(maybe this should have been a separate question...)

What do you mean by watermark? Just text is the easiest. With GDI you can just write the text at an angle with a grayscale.

Small example (I hope this is ok here instead of a external clip-site):
Make sure to call the watermark text first before writing anything else to the page so it appears in the background.

// call with WriteTextAngled(pdf, 100, 600, 'CONFIDENTIAL');

procedure WriteTextAngled(pdf: TPdfDocumentGDI; x, Y: Integer; Text: string);
var
  LogFont: TLogFont;
  Font: HFONT;
  OldFont: HFONT;
  OldBkMode: Integer;
  OldColor: COLORREF;
begin
  FillChar(LogFont, SizeOf(LogFont), 0);
  LogFont.lfFaceName := 'Arial';
  LogFont.lfHeight := -60; // Font size
  LogFont.lfEscapement := 60 { angle } * 10; // Rotation in tenths of a degree
  LogFont.lfOrientation := LogFont.lfEscapement;
  LogFont.lfQuality := ANTIALIASED_QUALITY;
  Font := CreateFontIndirect(LogFont);
  OldFont := SelectObject(pdf.VCLCanvas.Handle, Font);
  OldBkMode := SetBkMode(pdf.VCLCanvas.Handle, TRANSPARENT);
  OldColor := SetTextColor(pdf.VCLCanvas.Handle, RGB(180, 180, 180));
  pdf.VCLCanvas.TextOut(x, Y, Text);
  SelectObject(pdf.VCLCanvas.Handle, OldFont);
  SetBkMode(pdf.VCLCanvas.Handle, OldBkMode);
  SetTextColor(pdf.VCLCanvas.Handle, OldColor);
  DeleteObject(Font);
end;

2025-07-11-18-48-21.png

#22 Re: PDF Engine » ChatGPT gives non compiling results ,what is wrong? » 2025-07-10 07:06:39

rvk
etwoss wrote:

This part does not compile, why??

That's because ChatGPT is NOT a programmer and if it doesn't know something... it just makes stuff up (which often doesn't work).

If you want encryption search this forum for TPdfEncryption and check out the examples as to how it's done correctly.

#23 Re: PDF Engine » Need help/direction for WMF file. » 2025-06-24 15:18:36

rvk
sameerpandit wrote:

I am NOT facing any text issues without the Setfont. Not in mORMot1. Not in mORMot2. I get correct PDFs using both as far as text objects are concerned.

You ARE having issues other than font issues.

You have a problem with images.
I'm just saying setting the font might resolve this (as it did with me). I also didn't have font issues but corruption issues. Nothing to do with font. But setting setfont fixed that for me.

#24 Re: PDF Engine » Need help/direction for WMF file. » 2025-06-24 13:05:52

rvk
sameerpandit wrote:

However, I am not facing any text issues using SynPdf for past multiple years.

You are STILL missing the point.
Without the setfont... I get a corrupted pdf.
It doesn't have anything to do with the actual text.

Only with the setfont I get a correct pdf.

If it doesn't work for you (even with adding that one line) then it must be something with D7 (I'm using D20.2).

(Didn't test with Lazarus yet)

#25 Re: PDF Engine » Need help/direction for WMF file. » 2025-06-24 12:22:23

rvk
sameerpandit wrote:

Text issue I shall manage. I need a solution for images at bottom of page being skipped.

You're missing the point. For me, without the setfont, there is a corrupt pdf created. The resulting pdf doesn't show everything. Maybe for you it then doesn't show the images. That's why I asked if you did the setfont.

But I can't help you any further because for me it works (if I do the setfont as in my code).

#26 Re: PDF Engine » Need help/direction for WMF file. » 2025-06-24 12:02:38

rvk

@sameerpandit did you add the setfont line as I showed?
For me it works here.

(I also linked to my code)

#27 Re: PDF Engine » Need help/direction for WMF file. » 2025-06-24 07:45:26

rvk

I'm not sure why the VCLCanvas.Draw doesn't work for you... but for me it does show the images at the bottom.

I do need to use pdf.Canvas.SetFont otherwise I get an error message in Adobe reader as below. Not sure why you don't get that with your code.

Here is the code I used.
https://gist.github.com/rvk01/9e20e728d … b35107dfbf
Result: https://limewire.com/d/UkxBW#QGNBuFNvep

So make sure you use the pdf.Canvas.SetFont. Do the images at the bottom show up then for you???

2025-06-24-09-30-10-test-pdf-Adobe-Acrobat-Reader-64-bit.png

#28 Re: PDF Engine » Problem with resaving an encrypted PDF » 2025-05-08 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.

#29 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

#30 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

#31 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)

#32 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.

#33 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.

#34 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."

#35 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)

#36 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.

#37 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.

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

#39 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)

#40 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.

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

#42 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?

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

#44 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

#45 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

#46 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.

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

#48 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)

#49 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

#50 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

Board footer

Powered by FluxBB