You are not logged in.
I used SynPdf to create my document in PDF format, but found that the Chinese symbol output was incorrect。
var
lPdf: TPdfDocumentGDI;
begin
lPdf := TPdfDocumentGDI.Create;
try
lPdf.ScreenLogPixels := 96;
lPdf.DefaultPaperSize := TPDFPaperSize.psA4;
lPDF.AddPage;
lPdf.VCLCanvas.Brush.Style := bsClear;
lPdf.VCLCanvas.Font.Name := '宋体'; // 注释掉正常
lPdf.VCLCanvas.TextOut(20, 20, '发现双引号不正确“问题”');
lPdf.SaveToFile('c:\Syntest.pdf');
finally
lPdf.Free;
end;
end;
Offline
thanks,I tried it, but the problem still exists.
var
lPdf: TPdfDocumentGDI;
begin
lPdf := TPdfDocumentGDI.Create;
try
lPdf.UseUniscribe := True; //
lPdf.ScreenLogPixels := 96;
lPdf.DefaultPaperSize := TPDFPaperSize.psA4;
lPDF.AddPage;
lPdf.VCLCanvas.Brush.Style := bsClear;
lPdf.VCLCanvas.Font.Name := '宋体'; // 注释掉正常
lPdf.VCLCanvas.TextOut(20, 20, '发现双引号不正确“问题”');
lPdf.SaveToFile('c:\Syntest.pdf');
finally
lPdf.Free;
end;
Offline
XE3:
var
lPdf: TPdfDocumentGDI;
begin
lPdf := TPdfDocumentGDI.Create;
try
//lPdf.UseUniscribe := True;
lPdf.ScreenLogPixels := 96;
lPdf.DefaultPaperSize := psA4;
lPDF.AddPage;
lPdf.VCLCanvas.Brush.Style := bsClear;
lPdf.VCLCanvas.Font.Name := 'SimSun'; // 宋体
lPdf.VCLCanvas.TextOut( 20, 20, '发现双引号不正确“问题”' );
lPdf.SaveToFile('%TEMP%\SynPdfTest.pdf');
finally
lPdf.Free;
end;
end;
D7:
var
lStr: WideString;
lLen: integer;
lPdf: TPdfDocumentGDI;
begin
lStr := TntEdit1.Text; // Tnt Delphi Unicode Controls
lLen := Length('TextOutW: ' + lStr);
lPdf := TPdfDocumentGDI.Create;
try
//lPdf.UseUniscribe := True;
lPdf.ScreenLogPixels := 96;
lPdf.DefaultPaperSize := psA4;
lPDF.AddPage;
lPdf.VCLCanvas.Brush.Style := bsClear;
lPdf.VCLCanvas.Font.Name := 'SimSun'; // 宋体
lPdf.VCLCanvas.TextOut( 20, 20, 'TextOutA: ' + lStr );
TextOutW( lPdf.VCLCanvas.Handle, 20, 40, PWideChar('TextOutW: ' + lStr), lLen );
lPdf.SaveToFile( '%TEMP%\SynPdfTest.pdf' );
finally
lPdf.Free;
end;
end;
Offline
@5c4f394a,Thank you, I've tried your code, the symbol is correct, but the font is not SimSun
Offline
I found the cause of the problem(i'm poor english),the reason for the font style failure is:
in function TPdfDocument.TTFFontPostcriptName
Result := TrueTypeFontName(aFontName,AStyle); // get font name and style
// if chinese font (CJK font?)
Rec := @name^.FirstNameRecord;
for i := 0 to name^.count-1 do
if (Rec^.nameID=NAME_POSTCRIPT) and (Rec^.platformID=TTFCFP_MS_PLATFORMID)
and (Rec^.encodingID=1) and (Rec^.languageID=$409) then
begin
...
SetLength(Result,L); // here,L is font name length,lost above style
// so i add rejudging style after to solve this problem
if pfsItalic in AStyle then
if pfsBold in AStyle then
Result := Result + ',BoldItalic'
else
Result := Result + ',Italic'
else
if pfsBold in AStyle then
Result := Result + ',Bold';
Offline
the problem of chinese symbols(E.g “ unicode #8220) is:
TSynAnsiFixedWidth.Create
for i := 127 to 255 do
if (fAnsiToWide[ii]<>0) and (fAnsiToWide[ii]<>ord('?')) then
fWideToAnsi[fAnsiToWide[ii]] := i;
// fAnsiToWide[147] = 8220, fWideToAnsi[8220] = 147, witch “(chinese symbol) becomes "(english symbol),but ” and " display widths are different,causes display problems after generating pdf,so i remove three lines
The above are the problems and solutions I found, which may be inaccurate. If there is a better way, you can notify me, thank you, thank you synpdf.
Last edited by 18114532@qq.com (2020-03-06 03:27:04)
Offline
I have included - with some small refactoring - your TPdfDocument.TTFFontPostcriptName fix.
Please check https://github.com/synopse/mORMot/commi … 162eb90d37
But I don't understand well why TSynAnsiFixedWidth.Create is involved here.
Please report back if you find something better.
Thanks a lot for your feedback!
Online
because “ and " are different in unicode,“ unicode is #8220, " ansi is 147
TSynAnsiFixedWidth.Create
for i := 127 to 255 do
if (fAnsiToWide[ii]<>0) and (fAnsiToWide[ii]<>ord('?')) then
fWideToAnsi[fAnsiToWide[ii]] := i; // i = 147, fAnsiToWide[147] = 8220, fWideToAnsi[8220] = 147, ”="
“ and " are different in unicode, In the same font, “ is wider than ",So it should not be the same
Last edited by 18114532@qq.com (2020-03-06 15:02:41)
Offline
I don't understand.
WinAnsi #147 (=#8220 Unicode) and " will have different glyph, so different width in SynPDF, because they are not the same character, even in WinAnsi.
Online
WinAnsi #147 is "
Unicode #8220 is “
“ should not be equal to ", but becomes equal by fWideToAnsi[fAnsiToWide[ii]] := i where i = 147
Last edited by 18114532@qq.com (2020-03-06 15:24:05)
Offline
sorry,I did not notice WinAnsi #147 is not “ (Unicode #8220) in chinese font,
i test in Delphi7(because it's use ANSI) and Delphi2010(unicode),i set edit1's font name 宋体(a chinese font alias simsun)
Delphi7
edit1.Text := Char(#147); i get empty
edit1.Text := Char(#34); i get "
Delphi2010
edit1.Text := Char(#147); i get ?
edit1.Text := Char(#34); i get "
edit1.Text := Char(#8220); i get “
I haven't found the cause of this phenomenon yet
Last edited by 18114532@qq.com (2020-03-06 15:58:12)
Offline
This is as expected.
Your Windows uses MBCS for ANSI API I guess. It doesn't use WinAnsi, but a Chinese Code Page.
So under Delphi 7 - which uses the ANSI Windows API, Char=AnsiChar so Char(#147) is not enough in MBCS, so it is not converted.
Whereas in Delphi 2010, Char=WideChar so Char(#147)=Unicode 147 which doesn't exist.
But WideChar(#8220) does exist in UTF-16 so is displayed.
Online
yes, my windows is Simplified Chinese, code page(936) and GBK for ANSI API,so I use MultiByteToWideChar modified it to
TSynAnsiFixedWidth.Create
...
SetLength(fWideToAnsi, 65536);
for i := 1 to 126 do
fWideToAnsi[ii] := i;
FillcharFast(fWideToAnsi[127], 65536 - 127, ord('?')); // '?' for unknown char
GetMem(vPWideChar, SizeOf(WideChar));
try
for i := 127 to 255 do
if (fAnsiToWide[ii] <> 0) and (fAnsiToWide[ii] <> ord('?')) then
begin
vLen := MultiByteToWideChar(DefaultSystemCodePage, 0, @AnsiChar(i), 1, nil, 0);
if vLen > 0 then
begin
vLen := MultiByteToWideChar(DefaultSystemCodePage, 0, @AnsiChar(i), 1, vPWideChar, vLen);
fWideToAnsi[fAnsiToWide[ii]] := Ord(vPWideChar^);
end;
end;
finally
FreeMem(vPWideChar);
end;
// fixed width Ansi will never be bigger than UTF-8
fAnsiCharShift := 0;
Is this the most appropriate way to modify it?
Offline
Online