Rank: Member
Groups: Registered
Joined: 7/26/2016(UTC) Posts: 25  Location: Somerset Thanks: 5 times
|
Hi,
I'm pleased to see that the latest version of Pdfium (3.34.2704) contains new API to add embedded fonts, about which I would be grateful for some extra information.
First, can I add a subsetted TrueType font to a PDF?
Second, if I have a Unicode-based TrueType font file (called, say, 'fontfile.ttf') installed in the Windows fonts directory ('C:\Windows\Fonts'), how can I embed a subset of this font in order to display the contents of a C# Unicode string (say, 'string displayTxt;') in the PDF? A code snippet illustrating how to use the new API would be very useful.
Many thanks for your help.
Terry.
|
|
|
|
|
|
Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,138
Thanks: 10 times Was thanked: 133 time(s) in 130 post(s)
|
My understanding is that you can pass the entire of TTF file as byte array to the PdfFont.CreateEmbeddedFont. For example to embed the font called calist with Bold Italic face you may pass content of calist BI.ttf file Code: var doc = pdfViewer1.Document;
byte[] fontData = System.IO.File.ReadAllBytes(@"c:\windows\fonts\CALISTBI.TTF");
PdfFont font = PdfFont.CreateEmbeddedFont(doc, fontData, FontCharSet.ANSI_CHARSET, false);
var txt = PdfTextObject.Create("This is a test string", 10, 480, font, 13);
pdfViewer1.CurrentPage.PageObjects.Add(txt);
pdfViewer1.ClearRenderBuffer();
pdfViewer1.Invalidate();
The second point of my understanding is that OpenType PS fonts (.OTF) may be used as well. For example the following code is valid too Code: byte[] fontData = System.IO.File.ReadAllBytes(@"d:\0\11\Pecita.otf");
PdfFont font = PdfFont.CreateEmbeddedFont(doc, fontData, FontCharSet.ANSI_CHARSET, false);
But if you want to embed only a certain subset of characters from an existing TrueType/OpenType font, you need to extract the appropriate data from the ttf / otf file yourself. Edited by user Monday, August 6, 2018 11:29:50 PM(UTC)
| Reason: Not specified
|
|
|
|
|
|
Rank: Member
Groups: Registered
Joined: 7/26/2016(UTC) Posts: 25  Location: Somerset Thanks: 5 times
|
Hi Paul,
Many thanks for your reply.
It would be useful if Pdfium itself created the font subset (since it is quite complicated), however I understand that .NET provides some help for doing this, which I am currently investigating. I'll let you know how I get on, or if I have any further questions!
Regards, Terry.
|
|
|
|
|
|
Rank: Member
Groups: Registered
Joined: 7/26/2016(UTC) Posts: 25  Location: Somerset Thanks: 5 times
|
Hi Paul,
Can you please explain how to embed a font with the 'Identity-H' encoding? I have played around with the 'FontCharSet' parameter of method 'CreateEmbeddedFont', but none of the available values seems appropriate when I want to display in the PDF a totally generic C# Unicode string using a Unicode-based TrueType font that is capable of displaying a wide range of non-Ansi glyphs from many different non-Latin languages.
(In such cases, other PDF libraries I have used created a font dictionary with 'Encoding' value 'Identity-H', 'Subtype' value 'Type0', a 'ToUnicode' stream link, and a 'DescendantFonts' array containing a font dictionary of type 'CIDFontType0' or 'CIDFontType2' and with keys 'CIDSystemInfo', 'FontDescriptor', etc.)
Thanks for your help.
Terry.
|
|
|
|
|
|
Rank: Member
Groups: Registered
Joined: 7/26/2016(UTC) Posts: 25  Location: Somerset Thanks: 5 times
|
Paul, as a concrete example, how should I embed a Unicode font, say 'Arial Unicode MS', to display a C# string containing both Russian and Japanese, say "версия - 署名理由"? Thanks. Edited by user Tuesday, August 14, 2018 2:09:20 AM(UTC)
| Reason: Not specified
|
|
|
|
|
|
Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,138
Thanks: 10 times Was thanked: 133 time(s) in 130 post(s)
|
In this case you should create two separate text objects with different fonts.
|
|
|
|
|
|
Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,138
Thanks: 10 times Was thanked: 133 time(s) in 130 post(s)
|
I have following example Code: int fontType = 1;// 0 - windows, 1 - crossplatform, 2 - embedded
var doc = pdfViewer1.Document;
float y = 480;
byte[] fontData = System.IO.File.ReadAllBytes(@"c:\windows\fonts\ARIALUNI.TTF");
for (int i = 0; i < 14; i++)
{
FontCharSet ch = FontCharSet.DEFAULT_CHARSET;
string text = "";
switch (i)
{
case 0: ch = FontCharSet.HANGEUL_CHARSET; text = "이것은 한국어 텍스트입니다."; break;
case 1: ch = FontCharSet.SHIFTJIS_CHARSET; text = "これは韓国語のテキストです"; break;
case 2: ch = FontCharSet.HEBREW_CHARSET; text = "זהו טקסט קוריאני"; break;
case 3: ch = FontCharSet.ARABIC_CHARSET; text = "هذا هو النص الكوري"; break;
case 4: ch = FontCharSet.CHINESEBIG5_CHARSET; text = "這是韓文"; break;
case 5: ch = FontCharSet.GB2312_CHARSET; text = "这是韩文"; break;
case 6: ch = FontCharSet.RUSSIAN_CHARSET; text = "Это русский текст"; break;
case 7: ch = FontCharSet.ANSI_CHARSET; text = "This is a test string"; break;
case 8: ch = FontCharSet.BALTIC_CHARSET; text = "Vienkārša testa līnija"; break;
case 9: ch = FontCharSet.EASTEUROPE_CHARSET; text = "Jednoduchá zkušební linka"; break;
case 10: ch = FontCharSet.GREEK_CHARSET; text = "Απλή γραμμή δοκιμής"; break;
case 11: ch = FontCharSet.THAI_CHARSET; text = "สายทดสอบง่าย"; break;
case 12: ch = FontCharSet.TURKISH_CHARSET; text = "Basit test hattı"; break;
case 13: ch = FontCharSet.VIETNAMESE_CHARSET; text = "Kiểm tra đơn giản"; break;
}
PdfFont font;
LOGFONT lf = new LOGFONT() { lfFaceName = "Arial Unicode MS", lfCharSet = ch, lfPitchAndFamily = LOGFONT.FontPitchAndFamily.DEFAULT_PITCH | LOGFONT.FontPitchAndFamily.FF_ROMAN, lfWeight = FontWeight.FW_NORMAL };
if (fontType == 0)
font = PdfFont.CreateWindowsFont(doc, lf, false, false);
else if (fontType == 2)
font = PdfFont.CreateEmbeddedFont(doc, fontData, ch, false);
else
font = PdfFont.CreateFont(doc, lf.lfFaceName, true, 0, lf.lfWeight, 0, lf.lfCharSet, false);
var txt = PdfTextObject.Create(text, 10, y, font, 13);
pdfViewer1.CurrentPage.PageObjects.Add(txt);
y -= 30;
}
pdfViewer1.ClearRenderBuffer();
pdfViewer1.Invalidate();
But i'm not sure that exactly should be embedded in the case when Chinese, Korean and Japanese are used. Looks like only used glyphs should be embedded.
|
|
|
|
|
|
Rank: Member
Groups: Registered
Joined: 7/26/2016(UTC) Posts: 25  Location: Somerset Thanks: 5 times
|
Thanks for replying, however this should not be necessary since 'Arial Unicode MS' is capable of representing both Russian and Japanese. Also, in my case the strings are entered interactively by a user and so I do not know the character sets in advance. A user may enter a single string containing mixed Russian, Japanese, Chinese, German, Polish, etc.
|
|
|
|
|
|
Rank: Member
Groups: Registered
Joined: 7/26/2016(UTC) Posts: 25  Location: Somerset Thanks: 5 times
|
Hi Paul,
Thanks for your second reply (containing the example code), and you are correct that "only used glyphs should be embedded." I'm investigating the problem of creating a font subset separately using native Windows & .NET API, but first I wanted to prove to myself that the new Pdfium API was capable of embedding an entire Unicode font to display a generic Unicode string, but this does not appear to be possible at the moment. So I will have to investigate an alternative approach.
Thanks for your help.
Terry.
|
|
|
|
|
|
Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,138
Thanks: 10 times Was thanked: 133 time(s) in 130 post(s)
|
FOXIT Phantom PDF splits such text to the separate objects  Untitled.pdf_decoded.pdf (30kb) downloaded 3 time(s).Quote:0 0 0 rg 0 0 0 RG 0 w /FXF1 12 Tf 1 0 0 1 0 0 Tm 96.911 757.479 TD[(This is a sample text with Russian)]TJ /FXF2 12 Tf 1 0 0 1 0 0 Tm 277.511 757.479 TD[( \n )]TJ /FXF3 12 Tf 1 0 0 1 0 0 Tm 397.175 757.479 TD[(АМ°НАє ЗС±№ѕо ЕШЅєЖ®АФґПґЩ.)]TJ /FXF1 12 Tf 1 0 0 1 0 0 Tm 551.147 757.479 TD[( )]TJ Probably somehow it can be done with a single object, but the original Pdfium API does not assume this and I do not know how to do this. I could look for a solution, in analogy with Windows fonts. Does anyone know how a similar line could be drawn in Windows GDI? How do I set the LOGFONT parameters in Windows to display a similar string?
|
|
|
|
|
|
Rank: Member
Groups: Registered
Joined: 7/26/2016(UTC) Posts: 25  Location: Somerset Thanks: 5 times
|
Thanks for the information Paul, very interesting. I'm surprised that Foxit Phantom PDF splits the text in this manner. Previously I used iText (with Java) and Pdftron's Pdfnet (with C++) to insert such text into a PDF and in both cases the mixed character set text was inserted as a single object and a single subsetted font was embedded containing only the glyphs actually present in the text.
I understand that the Foxit/Debenu Quick PDF library also inserts such text as a single object, but I have yet to test this myself - I intend to investigate this now, so will let you know the outcome.
I should also mention that I want to insert the text into a Form XObject (which is referenced in the appearance stream of a widget annotation), not into the content stream of a page, so I'm not sure whether I can use the Pdfium 'PdfTextObject' to do this. At the moment I'm explicitly inserting all the low-level text and font operators ('BT', 'Tf', 'Td', 'Tj', 'ET', etc) myself, but this is a separate issue.
Terry.
|
|
|
|
|
|
Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,138
Thanks: 10 times Was thanked: 133 time(s) in 130 post(s)
|
Originally Posted by: Terry  I should also mention that I want to insert the text into a Form XObject (which is referenced in the appearance stream of a widget annotation), not into the content stream of a page, so I'm not sure whether I can use the Pdfium 'PdfTextObject' to do this. At the moment I'm explicitly inserting all the low-level text and font operators ('BT', 'Tf', 'Td', 'Tj', 'ET', etc) myself, but this is a separate issue.
Pdfium.Net SDK contains tools that greatly facilitate this task. For example, the following code generates the stream with the following text. All resources will be contained in the stream dictionary, so you can directly use this one as an appearance stream of widget annotation. Code:var form = PdfFormObject.Create(doc.Pages[0]);
var textObj = PdfTextObject.Create("Sample Text", 0, 0, PdfFont.CreateStock(doc, FontStockNames.Arial), 15.0f);
form.PageObjects.Add(textObj);
var stream = PdfTypeStream.Create();
bool b = Pdfium.FPDF_GenerateContentToStream(doc.Handle, form.PageObjects.Handle, stream.Handle, IntPtr.Zero);
Note:q /FXE1 gs BT 1 0 0 1 0 0 Tm 0 0 TD 0 Tr 0 Tc 0 Tw /FXF1 15 Tf [(Sample Text)]TJ ET Q  imgFormAnnot.png (18kb) downloaded 7 time(s). imgFormAnnot2.png (28kb) downloaded 6 time(s).
|
 1 user thanked Paul Rayman for this useful post.
|
|
|
|
Rank: Member
Groups: Registered
Joined: 7/26/2016(UTC) Posts: 25  Location: Somerset Thanks: 5 times
|
That's a useful tip Paul, thanks. I was not aware of the 'FPDF_GenerateContentToStream()' method. Will investigate this further once I have solved my fonts problem!
Thanks for your continuing help.
Terry.
|
|
|
|
|
|
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.
Important Information:
The Patagames Software Support Forum uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close