您的位置:首页 > 产品设计 > UI/UE

PD4ML Cookbook PDF and True Type fonts(2)

2017-09-29 17:46 591 查看
As a rule PDF viewers include a set of built-in Type1 fonts like Times, Helvetica, Courier. It is guaranteeed, that PDFs with the fonts are shown correctly on any platform.
Despite the fact, the fonts include most of UNICODE glyphs, PD4ML only addresses Latin subset of the fonts (ISO-8859-1). There are some technical issues behind the restriction.
The built-in Type1 fonts are the only fonts, you can use with PD4ML Std.
PD4ML Pro and derived licenses allow you to use all UNICODE space of custom TTF/OTF fonts in PDFs (if the fonts are not buggy and are compatible with Java runtime environment).
In order to do that, PD4ML requires you to configure and to use 
4000
TTF embedding feature (http://pd4ml.com/reference.htm#7.1)

The way TTF embedding is implemented by PD4ML may look overcomplicated at first glance. On practice it is not so; also there are reasons why TTF usage is not as transparent as in regular Java applications.

In Java you may easily instantiate Font object for any font face name and to use it for text output. But for PDF generation PD4ML needs an access not only to java.awt.Font objects, but to the corresponding physical .ttf
files (to parse them and to extract a subset of used glyphs). Unfortunately Java does not offer a way to locate TTF file for a particular java.awt.Font object.

For that reason we introduced the font face -> font file mapping appraoch (with pd4fonts.properties).

The needed actions are straightforward:

create fonts/ directory (i.e /path/to/my/fonts/) and copy needed TTFs into it.
run pd4font.properties generation command 
java -jar pd4ml.jar -configure.fonts /path/to/my/fonts/

(as a result it should produce /path/to/my/fonts/pd4font.properties)
reference /path/to/my/fonts/ directory from your Java/JSP/... code.

If you want to avoid binding to a local directory, you may pack the fonts/ directory into a JAR, place it to classpath and access them via classloader.

http://pd4ml.com/examples.zip (~2MB) contains chinese_ttf sample,
which illustrates how to do that.
 
pd4fonts.properties supports a special entry ttf.fonts.dir, which makes possible to store pd4fonts.properties separately
from the font files. For example in a case you have no permission to write anything to the system font directory:
ttf.fonts.dir=c:/windows/fonts

You do not need to add the entry manually. You may add second -configure.fonts parameter with a desired pd4fonts.properties location.
java -jar pd4ml.jar -configure.fonts   c:/windows/fonts   c:/work/fontmappings/

or even more specific
java -jar pd4ml.jar -configure.fonts   c:/windows/fonts   c:/work/fontmappings/myfontmapping.properties
In the case PD4ML will insert automatically ttf.fonts.dir, points to the given font directory.
Note: in the second command-line example above, it produces .properties file with an arbitrary name: myfontmapping.properties. That would
require explicit file name in useTTF() call (or in the call equivalents):
pd4ml.useTTF( "/work/fontmappings/myfontmapping.properties", true );
 
Very often there is no necessity to support multiple font faces, but missing of special characters (like δ, « ...) or charsets (like Cyrillic, Arabic) support
is critical.

For the case we created a "quick hack" solution with easy-to-use TTF embedding. 

There is a JAR with 3 fonts for serif, sansserif and monospaced types (the fonts do not contain CJK glyphs): 

http://pd4ml.com/i/easyfonts/fonts.jar (~2MB)

Add the JAR to application's classpath (or put to WEB-INF/lib in webapp scenarios), address the fonts via Java classloader and specify, that the 3 fonts should be used as defaults:

view plaincopy
to clipboardprint?

pd4ml.useTTF( "java:fonts", true );  

pd4ml.setDefaultTTFs("Times New Roman", "Arial", "Courier New");  

(Full Java API example: http://pd4ml.com/i/easyfonts/EasyFonts.java)

JSP equivalent:

view plaincopy
to clipboardprint?

<pd4ml:usettf from="java:fonts" serif="Times New Roman" sansserif="Arial" monospace="Courier New">  

The same for the PHP wrapper (assuming that fonts.jar is
in the same dir where pd4ml(_demo).jar is):

view plaincopy
to clipboardprint?

passthru('java -Xmx512m -Djava.awt.headless=true -cp .:pd4ml_demo.jar:fonts.jar Pd4Php \'' .   

                   $_POST['url'] . '\' 800 A4 -ttf java:fonts 2>>stderr.txt');  

   

// Win32 version  

// passthru('java -Xmx512m -cp .;pd4ml_demo.jar;fonts.jar Pd4Cmd ' .   

//                 $_POST['url'] . ' 800 A4 -ttf fonts:jar');  

 
1. What happens if HTML references a font like Comic Sans MS, but the font name-to-file mapping is missing in pd4fonts.properties?
In the case PD4ML tries to determine which group the font belongs to: Serif, SansSerif or Monospace. (For Comic Sans MS it
is SansSerif).
After that it tries to load default group font: Times New RomanArial or Courier New (or corresponding fonts, overridden
with pd4ml.setDefaultTTFs())
If the fonts are missing as well, PD4ML walks so-called fallback tables to find any present font of the group to be used as a substitution.
Here are the substitution tables:

view plaincopy
to clipboardprint?

private static String[] serifFallback = new String[] {  

    "Times New Roman",  

    "MS Mincho",  

    "MingLiU",  

    "SimSun",  

    "Mangal",  

    "David",  

    "Batang",  

    "Wingdings",  

    "Symbol",  

    "Lucida Sans Regular",  

};  

          

private static String[] sansFallback = new String[] {  

    "Arial",  

    "MS Gothic",  

    "MingLiU",  

    "SimSun",  

    "Mangal",  

    "David",  

    "Gulim",  

    "Wingdings",  

    "Symbol",  

    "Lucida Sans Regular",  

};  

          

private static String[] monoFallback = new String[] {  

    "Courier New",  

    "MS Gothic",  

    "MingLiU",  

    "SimSun",  

    "Mangal",  

    "David",  

    "GulimChe",  

    "Wingdings",  

    "Symbol",  

    "Lucida Sans Regular",  

};  

If nothing found, it uses corresponding built-in Type1 font.
2. What happens, when Chinese text is styled to be shown with Arial, however Arial font does not define CJK glyphs?
PD4ML performs a test if a particular content can be displayed with a chosen font. If not, it splits the text into smaller portions, differ by UNICODE group. It again checks
each portion if it can be displayed with Arial; if not, it walks sansFallback table in order to find a font, that has needed glyphs and applies the font.
3. Can I override a fallback table with font faces of my choice?
No. But there is a workaround. The names in the fallback tables refer to font face names in pd4fonts.properties. So you may override the mapping in the .properties file.
For example, usually Arial is mapped to arial.ttf
Arial=arial.ttf
If you change the entry in the .properties file to
Arial=comic.ttf
It will always use another font (Comic Sans MS) instead of Arial.
4. How font styles (bold/italic) correlate with TTF embedding logic?
TTF font files as a rule implement only one font style. For example arial.ttf - regular Arial, arialbd.ttf - Arial Bold. That means there
is a separate mapping in pd4fonts.properties for each existing font style.

view plaincopy
to clipboardprint?

Arial=arial.ttf  

Arial\ Italic=ariali.ttf  

Arial\ Bold=arialbd.ttf  

Arial\ Bold\ Italic=arialbi.ttf  

(spaces in font face names or style separating spaces are escaped with a backslash)
The above notation means, for <font face="Arial"><b>Text</b></font> PD4ML looks up "Arial Bold" entry in pd4fonts.properties

for <font face="Arial"><i><b>Text</b></i></font> is is "Arial Bold Italic".
(Note: <font face="Arial Bold">Text</font> and <font face="Arial Bold Italic">Text</font> would take the same effect, but it is not a
portable solution and it is not recommended in general).
There are some special cases.
For example Copperplate Gothic Bold has only one known style - bold. That means <font face="Copperplate Gothic"><b>Text</b></font> code
correctly refers the font, but <font face="Copperplate Gothic">Text</font> will fail, and a substitution font will be used.
Some fonts have only regular (not Bold, not Italic) style - it is true for most of CJK fonts. If there is no matching substitution, PD4ML emulates missing styles. Italic
is emulated by an area tilt, Bold is by a font glyph stroke out.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: