#include <Descriptor.hh>
this is the PDF font descriptor class. according to the PDF spec, a font descriptor "specifies metrics and other atrributes of a simple font or a CIDFont as a whole". they are used to "provide information that enables a viewer application to synthesize a substitute font or select a similar font when the font program is unavaiable". in other words, they are required.
the interface of this class is simple: given a truetype font program, get the font descriptor. its constructor will be given the font filename; and the Write() function will create a font descriptor PDF object.
note that only truetype font is supported; type 1 font is not supported. it is assume that all information of font descriptor is available is the font file.
all units are in glyph space, according to the PDF specs. the glyph space is defined as 1/1000 of text space. text space is by default the same as user space, which is 72DPI.
|
max width. optional create a font descriptor given a truetype font file.
00062 : m_filename( filename ) 00063 { 00064 // cannot initialize the member in the initializer, 00065 // because they are not so easy. 00066 freetype::CLibrary library ; 00067 freetype::CFace face( &library, filename, index ) ; 00068 00069 FromFont( face, flag ) ; 00070 } |
|
this function will calculate all required font metrics from the freetype font data structure. the calculated values are stored inside the member variables.
00095 { 00096 using namespace std ; 00097 using namespace boost ; 00098 00099 // use the postscript name as basename 00100 m_name = face.PSName( ) ; 00101 00102 // ascent and descent can be get directly 00103 m_ascent = EM2Glyph( face.Ascent( ), face ) ; 00104 m_descent = EM2Glyph( face.Decent( ), face ) ; 00105 00106 // bounding box can be get directly 00107 face.BoundBox( m_bbox ) ; 00108 transform( m_bbox, m_bbox + 4, m_bbox, 00109 bind( &CDescriptor::EM2Glyph, _1, ref( face ) ) ) ; 00110 00111 // italic angle can be get directly 00112 m_italic_angle = face.ItalicAngle( ) ; 00113 00114 // calculate the bit flags 00115 m_flags = CFlags( face, flag ).Flags( ) ; 00116 00117 // size is set to 72DPI also, such that one pixel in the font is 00118 // equal to one user space. 00119 // since glyph space is 1/1000 of text space, we use a 1000 pt 00120 // font and its size will be in glyph space 00121 face.SetSize( 0, 1000, 72, 72 ) ; 00122 00123 // CapHeight is treated as the height of the capital letter 'X' 00124 freetype::CGlyph cap_x( &face, face.GetGlyphCode( 'X' ) ) ; 00125 m_cap_height = static_cast<int>( cap_x.Height( ) ) ; 00126 00127 // stem vectical width is treated as the width of small letter 'l' 00128 freetype::CGlyph small_l( &face, face.GetGlyphCode( 'l' ) ) ; 00129 m_stem_v = static_cast<int>( small_l.Width( ) ) ; 00130 00131 // get the horizonal advance for all glyphs from the font 00132 for ( int i = 0 ; i < char_count ; i++ ) 00133 { 00134 freetype::CGlyph glyph( &face, face.GetGlyphCode( i ) ) ; 00135 m_widths[i] = static_cast<int>( glyph.HoriAdvance( ) ) ; 00136 } 00137 } |
|
this function will write out the font metric data to a PDF dictionary according to the PDF spec. the font program stream is added to the file in here.
00144 { 00145 using namespace core ; 00146 using namespace std ; 00147 00148 CDictionary *dict = new CDictionary ; 00149 dict->AddPair( "Type", "FontDescriptor" ) ; 00150 dict->AddPair( "FontName", m_name ) ; 00151 dict->AddPair( "Flags", new CNumber( m_flags ) ) ; 00152 dict->AddPair( "FontBBox", new CArray( m_bbox, m_bbox + 4 ) ) ; 00153 dict->AddPair( "ItalicAngle", new CNumber( m_italic_angle ) ) ; 00154 dict->AddPair( "Ascent", new CNumber( m_ascent ) ) ; 00155 dict->AddPair( "Descent", new CNumber( m_descent ) ) ; 00156 dict->AddPair( "CapHeight", new CNumber( m_cap_height ) ) ; 00157 dict->AddPair( "StemV", new CNumber( m_stem_v ) ) ; 00158 00159 WidthPair widths = Widths( ) ; 00160 int avg_width = accumulate( widths.first, widths.second, 0 ) / char_count ; 00161 int max_width = *max_element( widths.first, widths.second ) ; 00162 00163 dict->AddPair( "AvgWidth", new CNumber( avg_width ) ) ; 00164 dict->AddPair( "MaxWidth", new CNumber( max_width ) ) ; 00165 00166 CProgStream *prog_stream = new CProgStream( m_filename ) ; 00167 dict->AddPair( "FontFile2", file.AddObj( prog_stream ).Dup( ) ) ; 00168 00169 return file.AddObj( dict ) ; 00170 } |
|
return the width (horizonal advance of a glyph) of a specific glyph. unit is in PDF glyph space (1/1000 text space, which is 1/72 inchs by default).
00189 { 00190 if ( glyph >= 0 && glyph < char_count ) 00191 return m_widths[glyph] ; 00192 else 00193 return 0.0f ; 00194 } |
|
this function translate EM units (used in CFace) into PDF glyph spaces. glyph space is 1/1000 of text space, which is equal to user space (1/72 inchs) by default.
00177 { 00178 double temp = em_unit * 1000.0 / face.UnitsPerEM( ) ; 00179 00180 // round off! 00181 return static_cast<int>( em_unit > 0 ? temp + 0.5 : temp - 0.5 ) ; 00182 } |
|
FontName.
|
|
Flags.
|
|
FontBBox, bounding box. [ llx lly urx ury ].
|
|
ItalicAngle. degrees couterclockwise from vertical.
|
|
Ascent.
|
|
Descent.
|
|
CapHeight.
|
|
StemV, thickness of domainant vertical stems.
|
|
FontFile2. filename of font program of truetype font.
|
|
number of character whose width will be stored
|
|
although its name is "width", it should be the horizonal advance in the truetype font. |