You are not logged in.
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.
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).
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 ![]()
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
)
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.
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
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) thenThis 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
![]()
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.
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.
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.)
I can't find any documentation or complete example. So you just have to use it.
Like this:
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.
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.
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.
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.
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" ![]()
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;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).
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) ?
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').
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>For completeness, here is a example changing all TDateTime in a record using TRttiContext in Delphi:
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).
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?
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;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.
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.
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)
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).
@sameerpandit did you add the setfont line as I showed?
For me it works here.
(I also linked to my code)
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???
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.
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).

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.

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
qwhile above it is this for CUSTOMER
q
/F2 9.95 Tf
BT
39.67 694.54 Td
(CUSTOMER:) Tj
ET
Q
qAll 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)
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.
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.

But I can't speak for the older SynPDF.
You might want to fix your links.
They give "Incomplete or wrong Download URL."
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)
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.
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
)
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.
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 includedThe 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.)
Did you embed the used fonts?
(See ctrl+d in Adobe and then fonts tab)
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.
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).
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?
@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).
@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
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 ![]()
If you do TPdfDocument.CreateOutline() you can create 'Bookmarks' in the PDF (also had to dive into the sourcecode to find that out
).
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 = trueYes, 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.
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).
I don't think we can help without a more complete reproduceable example.
(including the metafiles if not generated by the example)
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
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))
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 ![]()