You are not logged in.
Hello!
I create PDF from metafile (using RenderMetaFile function) which contains cyrillic text.
If PDF created under Window 7 everything is OK, but under Windows XP (SP3) it's shown using east-european symbols.
I compared embedded fonts (in Acrobat Reader) and found out that PDF created under Windows 7 contains one font more, to be exact:
TimesNewRoman,Bold
Type: TrueType(CID)
Encoding: Identity-H
Actual font: TimesNewRoman,Bold
while PDF created under Windows XP only:
TimesNewRoman,Bold
Type: TrueType
Encoding: Ansi
Actual font: TimesNewRomanPS-BoldMT
Switching properties like EmbeddedTTF, EmbeddedWholeTTF etc. and setting CodePage has no effect.
Can you help me? What else should I try to force SynPDF generate the right files under Windows XP?
P.S. I'm using Delphi 7 and the latest "unstable" version of SynPDF from code repository.
Thank you in advance!
Last edited by MrHide (2014-01-23 14:12:41)
Offline
Yes, I tried both, still no effect.
Offline
Here the test files:
Test metafile - https://www.dropbox.com/s/mpu4haw9j0k4yuk/text.emf
PDF created in Win7 - https://www.dropbox.com/s/1frm048a1q08j5h/text_win7.pdf
PDF created in WinXP - https://www.dropbox.com/s/p39k76v1utghh … _winXP.pdf
and code:
procedure TForm1.Button1Click(Sender: TObject);
const
InputFileName = 'text.emf';
OutputFileName = 'text_win7.pdf';
var
Pdf: TPDFDocumentGDI;
Emf: TMetafile;
begin
Emf := TMetafile.Create;
try
Emf.LoadFromFile(InputFileName);
Pdf := TPdfDocumentGDI.Create;
try
Pdf.AddPage;
Pdf.Canvas.RenderMetaFile(Emf, 1, 0, 0, tpExactTextCharacterPositining);
Pdf.SaveToFile(OutputFileName);
finally
Pdf.Free;
end;
finally
Emf.Free;
end;
end;
Check the embedded fonts in both PDFs.
What do you think?
Offline
Checked it on another XP machine - OK! Even on Win2K is OK!
Thus, the problem is not in the OS used.
I decided to debug thru PDF engine and to compare variables and arrays content, and finally found out - the difference is in how MultiByteToWideChar works, which is used in TSynAnsiConvert.AnsiBufferToUnicode function (in SynCommons.pas).
Any ideas how to fix this problem?
Offline
We have enhanced TSynAnsiConvert.AnsiBufferToUnicode() function.
Perhaps the default flags is not compatible...
Offline
Thank you for response! Will try on Monday (problem PC is at work).
BTW, I encountered one more bug - "Access violation" on EMF with one specific non-standard font. I have located place in code where violation occurs, but can't understand how to change code to avoid this error.
Can I send you test EMF and problem font?
Thank you!
Offline
I've tested with new version of SynCommons - the problem still persists.
Here is dump of fAnsiToWide array after executing this code:
constructor TSynAnsiFixedWidth.Create(aCodePage: cardinal);
.........
if PtrInt(inherited AnsiBufferToUnicode(U256,A256,256))-PtrInt(@U256)<>512 then
raise ESynException.CreateFmt('OS error for %s.Create(%d)',[ClassName,aCodePage]);
move(U256,fAnsiToWide[0],256*2);
..........
when result PDF is OK:
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 8364, 129, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 141, 381, 143, 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 157, 382, 376, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255)
and on problem machine:
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 1026, 1027, 8218, 1107, 8222, 8230, 8224, 8225, 8364, 8240, 1033, 8249, 1034, 1036, 1035, 1039, 1106, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 152, 8482, 1113, 8250, 1114, 1116, 1115, 1119, 160, 1038, 1118, 1032, 164, 1168, 166, 167, 1025, 169, 1028, 171, 172, 173, 174, 1031, 176, 177, 1030, 1110, 1169, 181, 182, 183, 1105, 8470, 1108, 187, 1112, 1029, 1109, 1111, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103)
Hope this information will be useful.
Last edited by MrHide (2014-01-27 12:43:35)
Offline
This problem arises in case of reassignment of code pages in the register:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage]
"1252" = "c_1251.nls"
Offline
So, as far as you point out, AnsiBufferToUnicode() does not return the same?
If you are using the following code instead:
function TSynAnsiConvert.AnsiBufferToUnicode(Dest: PWideChar;
Source: PAnsiChar; SourceChars: Cardinal): PWideChar;
begin
if SourceChars=0 then
result := Dest else begin
result := Dest+MultiByteToWideChar(
fCodePage,MB_PRECOMPOSED,Source,SourceChars,Dest,SourceChars);
if result=Dest then
TSynLogTestLog.DebuggerNotify([GetLastError,CodePage],'Error % on CodePage %');
end;
result^ := #0;
end;
If the returned content is not the same, I'm afraid the issue is really at OS level.
Otherwise, which version of Delphi are you using? Perhaps UnicodeFromLocaleChars() low-level RTL function is buggy...
Offline
OS WinXP SP3. I use Delphi 7.0. But a problem not in Delphi and not in WinAPI. As I wrote above, a problem in the wrong code pages in the register:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage]
"1252" = "c_1251.nls"
Such changes in the register meet on some computers the Russian local settings and Russian language for compatibility with some badly localized programs.
If in the register of control of code pages to return to an initial state (as at the OS installation -> "1252" = "c_1252.nls"), the problem disappears.
Excuse for my bad English. It is machine translation.
Offline
So what could we do?
Hardcode the 1252 code page?
If people just blow up their own system with such abusive changes, what do we expect?
http://www.fas.harvard.edu/~chgis/data/ … illic.html
Offline
Solving one problems thus (copying in the register of control of code pages), users create others problems. In this case the main thing it that the reason is found, now it is necessary to find the solution of this problem. I think the decision somewhere in elimination of dependence on code page 1252.
Offline
In fact, code page 1252 is a standard known PDF encoding.
This is the reason why we use it internaly in the unit.
The only fix I think about is to hardcode the 1252 code page within SynCommons.pas...
Weird, but should work...
See http://synopse.info/fossil/info/da68b56f616d3d
Offline
The problem is solved! Thanks a lot for the help!!!
Offline
My problem is solved too! And I can confirm that the reason was in wrong codepage assignment "1252" = "c_1251.nls", as edward_1 posted above.
Thanks a lot!
Offline