IText font not subsetting or embedding - itext

I am on the mainframe platform and uploaded the arial.ttf from Windows. I used the following code for the font, but the font does not show SUBSETTED or EMBEDDED in Adobe. I even tried to add font.getBaseFont to force it to embed.
Any reason why it would not embed or subset?
String font1 = "arial.ttf";
FontFactory.register(font1,"myfont");
BaseFont bf = BaseFont.createFont(font1, BaseFont.IDENTITY_H, true);
Font font = FontFactory.getFont("arial");
font.getBaseFont().setSubset(true);
Adobe doc show the following font information:
Type truetype
Encoding Ansi
Actual Font: ArialMT
Actual Font type: TrueType

You create a BaseFont object bf, but you aren't doing anything with it. One would expect that you do this:
BaseFont bf = BaseFont.createFont(pathToFont, BaseFont.IDENTITY_H, true);
Font font = new Font(bf, 12);
In this case, font would make sure that a subset of the font is embedded because the encoding is Identity-H and iText always embeds a subset of a font with that encoding.
As you aren't doing anything with bf, it is as if the line isn't present. In that case, we are left with:
String font1 = "arial.ttf";
FontFactory.register(font1,"myfont");
Font font = FontFactory.getFont("arial");
Assuming that the path to arial.ttf is correct, and that the alias of that font is "arial", you are now creating a font with the default encoding (Ansi), the default font size (12) and the default embedding (false).
That is in line with what is shown in Adobe Reader. If you want a subset of the font to be embedded, you need at least:
Font font = FontFactory.getFont("arial", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
In answer to your question: the reason why the font is not embedded by iText is the fact that you are not telling iText to embed the font.

Related

Creating PdfFont in IText7

We are evaluating Itext7 (hence I am fairly new to IText7) and would like to change the font in a table. Of course changing the font on the table is easy once I have the font, however creating the font is challenging. I have found simple examples
font = PdfFontFactory.createFont(FontConstants.TIMES_ITALIC, PdfEncodings.WINANSI);
but I would like to control the size, family, etc. of the font as well. I have found examples for previous versions of Itext that seem pretty straightforward.
BaseFont helvetica = BaseFont.createFont(HELVETICA, CP1252, EMBEDDED);
Font font = new Font(helvetica, 12, Font.NORMAL);
Thanks for any help.
iText 7 is fairly new. There's iText 7: Jump-Start tutorial to get you started, but we still need to write many tutorials about specific aspects of iText 7.
Fortunatly, the question you've posted has already been dealt with in the second iText 7 tutorial iText 7: Building Blocks. The information you need is in Chapter 1: Introducing the PdfFont class.
When you read this chapter, you'll understand that the size of the font shouldn't be a property of the PdfFont class. Instead, you define the font size at the level of the object that uses this font.
For instance:
Text title1 = new Text("The Strange Case of ").setFontSize(12);
Text title2 = new Text("Dr. Jekyll and Mr. Hyde").setFontSize(16);
Text author = new Text("Robert Louis Stevenson");
Paragraph p = new Paragraph().setFontSize(8)
.add(title1).add(title2).add(" by ").add(author);
document.add(p);
In this case, "The Strange Case of " has a font size of 12; "Dr. Jekyll and Mr. Hyde" has a font size of 16; " by " and "Robert Louis Stevenson" have a font size of 8, because that size is defined at the level of the Paragraph. The font size of " by " is the font size of the Paragraph. No font size was defined for "Robert Louis Stevenson", which means that this Text object inherited the font size of the Paragraph to which it belongs.
I'm currently working on chapter 2. You'll notice that iText 7 now allows you to change the default font size for a Document by defining the font at the Document level. This is one of the many improvements of iText 7.

How to print characters not existing in a font using iText 2.1.3

I am writing an application that generates a PDF file using iText 2.1.3. When printing a Unicode text that contains characters not in the font used, the characters simply vanishes in the output.
I have read that the way to solve that is to use a FontSelector something like this:
public void createPdf(final String filename, final String text)
throws IOException, DocumentException {
// Get at document for printing.
final Document document = new Document(...);
PdfWriter.getInstance(document, new FileOutputStream(filename));
document.open();
// Create a FontSelector with multiple fonts.
final FontSelector selector = new FontSelector();
final Font f1 = ...; // Covers e.g. Western glyphs
selector.addFont(f1);
final Font f2 = ...; // Covers e.g. Chinese glyphs
selector.addFont(f2);
// Phrase contains of chunks each using an approriate font
// for rendering part of the text.
final Phrase ph = selector.process(text);
document.add(new Paragraph(ph));
document.close();
}
(Example rewritten from this example.)
However, there might still be some characters in the text that are not covered by any of the available fonts.
Is there a way to tell iText 2.1.3 to print e.g. the Unicode Replacement Character (U+FFFD aka �) for such characters?
Using the Unicode Consortium Last Resort Font as the last font to search by the FontSelector there will be a glyph for every possible Unicode character.
The Last Resort Font is a special font that has different glyphs for different character categories giving a good hint about which kind of characters your font does not support.
So instead of getting � glyphs, the glyphs shown here will be displayed in the PDF.

JZOS and iText on z/OS

I am trying to create a PDF on z/OS using JZOS and iText.
I have tried so many combinations for the font as well as the DefaultPlatformEncoding but I just don't seem to be able to get the Arabic characters to display in the PDF. They display as Latin characters. When I turn the PDF compression off and display the hex characters, I see the EBCDIC hex codes.
The input file on z/OS is IBM-420 and the output PDF should have Cp1256 or Windows-1256 for display on Windows.
Here is the snippet of the code:
// Open the input dataset
ZFile zFilein = new ZFile("//DD:INDS", "rb,type=record,noseek");
// Open the output PDF file
PdfWriter writer = PdfWriter.getInstance(document,
FileFactory.newBufferedOutputStream("//DD:OUTPDF"));
document.open();
// Font cf = new Font(Font.FontFamily.COURIER, Font.DEFAULTSIZE, Font.NORMAL);
// Font cf = FontFactory.getFont("Courier","Cp1256", true);
Font cf = FontFactory.getFont("Arial", BaseFont.IDENTITY_H, true, Font.DEFAULTSIZE, Font.NORMAL);
Paragraph paragraph = new Paragraph();
paragraph.setFont(cf);
String encoding = ZUtil.getDefaultPlatformEncoding();
// String encoding = "Cp1256";
String line = new String(recBuf,1,nRead-1,encoding);
paragraph.add(line);
I tried the following options but still unable to get the PDF to display correctly and also
the PDF Font information does not show the font as EMBEDDED. Anything else I missed?
Note: arial.ttf was uploaded from WINDOWS
Option 1
FontFactory.register("arial.ttf");
Font cf = FontFactory.getFont("Arial", 8);
paragraph = new Paragraph(line, cf);
The FONT information in the PDF displays the following:
ArialMT
Type: TrueType
Encoding: Ansi
Actual Font: ArialMT
Actual Font Type: TrueType
Option 2
BaseFont bf = BaseFont.createFont(font1, BaseFont.IDENTITY_H, true);
Font cf = new Font(bf, 10);
paragraph = new Paragraph(line, cf);
Viewing the PDF display the following error:
Cannot extract the embedded font 'ZQRNLC+ArialMT'. Some characters may not display or
print correctly.
Viewing the source of the PDF in an editor I can see the following:
R/FontName/ZQRNLC+ArialMT/
The FONT in the PDF displays the following information:
ArialMT
Type: TrueType(CID)
Encoding: Identity-H
Actual Font: Unknown
Your question is a duplicate of several other questions.
This line of code may be problematic:
Font cf = FontFactory.getFont("Arial", BaseFont.IDENTITY_H, true, Font.DEFAULTSIZE, Font.NORMAL);
This won't give you the font Arial unless you have registered an Arial font program as explained in my answer to the question
"Why doesn't FontFactory.GetFont("Known Font Name", floatSize) work?"
I don't know z/OS (never heard of it), but if it uses EBCDIC, it's doing something wrong. Your strings need to be in UNICODE. It is very important that the String values you are using are in the right encoding as explained in my answer to the question "getBytes() doesn't work for Cyrillic letters". In your case, you are reading the content from a file, but there is no guarantee that the encoding you use to read the file matches the encoding that was used to store the file. When you say that the glyphs are shown in EBCDIC, I think that you're mistaken and that you experience the same problem as explained in "getBytes() doesn't work for Cyrillic letters". You really need Unicode.
You say that you want to create text in Arabic, but I don't see you using the RTL setting anywhere. This is explained in my answer to this question: "how to create persian content in pdf using eclipse".
Please download the free ebook "The Best iText Questions on StackOverflow" and you'll notice that all these problems have been asked and answered before. I would like to close your question as a duplicate of how to create persian content in pdf using eclipse, but unfortunately, that answer wasn't accepted and it didn't receive an upvote, so it can't be used as an original question to mark another question as a duplicate.

Missing character in custom font

We are using iTextSharp to create PDF's using a custom font and I am running into an issue with the unicode character 2120 (SM, Service Mark). The problem is the glyph is not in the custom font. Is there a way I can specify a fallback font for a field in a PDF? We tried adding a text field with Verdana so that the form had the secondary font embedded in it but that didn't seem to help.
First you need to find a font (ttf, otf,...) that has the character you need. Then you can use the FontSelector class and add the different fonts you want to use to this selector (see the FontSelectionExample). Now you can process every string:
FontSelector selector = new FontSelector();
selector.addFont(f1);
selector.addFont(f2);
Phrase ph = selector.process(some_string);
The FontSelector will return a phrase that consists of Chunks with font f1 for all the glyphs that are available in the first font, and Chunks with font f2 for the glyphs that couldn't be font in f1, but that are present in f2.
If you want the C# port of this example, please consult chapter 11.
Update
Using a FontSelector also works in the context of forms (as long as we're talking about AcroForm technology). It's really easy: you just need to add substitutions fonts to the form:
AcroFields form = stamper.getAcroFields();
form.addSubstitutionFont(bf1);
form.addSubstitutionFont(bf2);
Now the font defined in the form has preference, but if that font can't show a specific glyph, it will look at bf1, then at bf2 and so on. You can find an example demonstrating this functionality here.
Note that there's a difference between the first and the second example. In the first example we use a Font object, in the second, we use a BaseFont object.

Font Conversion From TrueType to Postscript Type 1

I have a TrueType Font and I want to merge it with a Postscript Font File. When I am merging using fontforge I am getting an error:
TrueType font file is 2 byte Encoded and Postscript is 1 byte
I want to know whether there is any method by which we can merge 2-byte encoded Font files to 1-byte encoded files or is there any way we can convert TrueType fonts (2-byte encoding) to a Postscript File (1-byte encoding)? For example, a Korean font file is 2-byte encoding and I want to merge it with a 1-byte encoded Postscript file.
If you are using more than 255 glyphs, then you would need to convert the TrueType font into a CIDFont with TrueType outlines, and supply a suitable CMap to map from character codes to CIDs.
Alternatively, or if you only want to use up to 255 glyphs, you can convert the font into a PostScript Type 42 font which is a PostScript method for wrapping a TrueType font so that it can be used. If you want to sue more than 255 glyphs using this method then you need to split the original TrueType font into multiple type 42 fonts and switch font as required to use the glyphs.
But basically you can't combine a TrueType font and a type 1 (or CFF) font succesfully, the technologies are quite different.
Why do you want to do this anyway ?