1 /***************************************************************************
2 * Copyright (C) 2005 by Dominik Seichter *
3 * domseichter@web.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU Library General Public License as *
7 * published by the Free Software Foundation; either version 2 of the *
8 * License, or (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU Library General Public *
16 * License along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 * *
20 * In addition, as a special exception, the copyright holders give *
21 * permission to link the code of portions of this program with the *
22 * OpenSSL library under certain conditions as described in each *
23 * individual source file, and distribute linked combinations *
24 * including the two. *
25 * You must obey the GNU General Public License in all respects *
26 * for all of the code used other than OpenSSL. If you modify *
27 * file(s) with this exception, you may extend this exception to your *
28 * version of the file(s), but you are not obligated to do so. If you *
29 * do not wish to do so, delete this exception statement from your *
30 * version. If you delete this exception statement from all source *
31 * files in the program, then also delete it here. *
32 ***************************************************************************/
33
34 #ifndef _PDF_FONT_METRICS_H_
35 #define _PDF_FONT_METRICS_H_
36
37 #include "podofo/base/PdfDefines.h"
38 #include "podofo/base/Pdf3rdPtyForwardDecl.h"
39 #include "podofo/base/PdfString.h"
40 #include "podofo/base/PdfEncoding.h"
41
42 namespace PoDoFo {
43
44 class PdfArray;
45 class PdfObject;
46 class PdfVariant;
47
48 /**
49 * This abstract class provides access
50 * to fontmetrics informations.
51 */
52 class PODOFO_DOC_API PdfFontMetrics {
53 public:
54 PdfFontMetrics( EPdfFontType eFontType, const char* pszFilename, const char* pszSubsetPrefix );
55
56
57 virtual ~PdfFontMetrics();
58
59 /** Create a width array for this font which is a required part
60 * of every font dictionary.
61 * \param var the final width array is written to this PdfVariant
62 * \param nFirst first character to be in the array
63 * \param nLast last character code to be in the array
64 * \param pEncoding encoding for correct character widths. If not passed default (latin1) encoding is used
65 */
66 virtual void GetWidthArray( PdfVariant & var, unsigned int nFirst, unsigned int nLast, const PdfEncoding* pEncoding = NULL ) const = 0;
67
68 /** Get the width of a single glyph id
69 *
70 * \param nGlyphId id of the glyph
71 * \returns the width of a single glyph id
72 */
73 virtual double GetGlyphWidth( int nGlyphId ) const = 0;
74
75 /** Get the width of a single named glyph
76 *
77 * \param pszGlyphname name of the glyph
78 * \returns the width of a single named glyph
79 */
80 virtual double GetGlyphWidth( const char* pszGlyphname ) const = 0;
81
82 /** Create the bounding box array as required by the PDF reference
83 * so that it can be written directly to a PDF file.
84 *
85 * \param array write the bounding box to this array.
86 */
87 virtual void GetBoundingBox( PdfArray & array ) const = 0;
88
89 /** Retrieve the width of a given text string in PDF units when
90 * drawn with the current font
91 * \param rsString a PdfString from which the width shall be calculated
92 * \returns the width in PDF units
93 *
94 * This is an overloaded method for your convinience!
95 */
96 inline double StringWidth( const PdfString & rsString ) const;
97
98 /** Retrieve the width of a given text string in PDF units when
99 * drawn with the current font
100 * \param pszText a text string of which the width should be calculated
101 * \param nLength if != 0 only the width of the nLength first characters is calculated
102 * \returns the width in PDF units
103 */
104 double StringWidth( const char* pszText, pdf_long nLength = 0 ) const;
105
106 /** Retrieve the width of a given text string in PDF units when
107 * drawn with the current font
108 * \param pszText a text string of which the width should be calculated
109 * \param nLength if != 0 only the width of the nLength first characters is calculated
110 * \returns the width in PDF units
111 */
112 double StringWidth( const pdf_utf16be* pszText, unsigned int nLength = 0 ) const;
113
114 #ifndef _WCHAR_T_DEFINED
115 #if defined(_MSC_VER) && _MSC_VER <= 1200 // not for MS Visual Studio 6
116 #else
117 /** Retrieve the width of a given text string in PDF units when
118 * drawn with the current font
119 * \param pszText a text string of which the width should be calculated
120 * \param nLength if != 0 only the width of the nLength first characters is calculated
121 * \returns the width in PDF units
122 */
123 double StringWidth( const wchar_t* pszText, unsigned int nLength = 0 ) const;
124 #endif
125 #endif
126
127 /** Retrieve the width of a given text string in 1/1000th mm when
128 * drawn with the current font
129 * \param pszText a text string of which the width should be calculated
130 * \param nLength if != 0 only the width of the nLength first characters is calculated
131 * \returns the width in 1/1000th mm
132 */
133 inline unsigned long StringWidthMM( const char* pszText, unsigned int nLength = 0 ) const;
134
135 /** Retrieve the width of a given text string in 1/1000th mm when
136 * drawn with the current font
137 * \param pszText a text string of which the width should be calculated
138 * \param nLength if != 0 only the width of the nLength first characters is calculated
139 * \returns the width in 1/1000th mm
140 */
141 inline unsigned long StringWidthMM( const pdf_utf16be* pszText, unsigned int nLength = 0 ) const;
142
143 #ifndef _WCHAR_T_DEFINED
144 #if defined(_MSC_VER) && _MSC_VER <= 1200 // not for MS Visual Studio 6
145 #else
146 /** Retrieve the width of a given text string in 1/1000th mm when
147 * drawn with the current font
148 * \param pszText a text string of which the width should be calculated
149 * \param nLength if != 0 only the width of the nLength first characters is calculated
150 * \returns the width in 1/1000th mm
151 */
152 inline unsigned long StringWidthMM( const wchar_t* pszText, unsigned int nLength = 0 ) const;
153 #endif
154 #endif
155
156 /** Retrieve the width of the given character in PDF units in the current font
157 * \param c character
158 * \returns the width in PDF units
159 */
160 virtual double CharWidth( unsigned char c ) const = 0;
161
162 // Peter Petrov 20 March 2009
163 /** Retrieve the width of the given character in PDF units in the current font
164 * \param c character
165 * \returns the width in PDF units
166 */
167 virtual double UnicodeCharWidth( unsigned short c ) const = 0;
168
169 /** Retrieve the width of the given character in 1/1000th mm in the current font
170 * \param c character
171 * \returns the width in 1/1000th mm
172 */
173 inline unsigned long CharWidthMM( unsigned char c ) const;
174
175 /** Retrieve the line spacing for this font
176 * \returns the linespacing in PDF units
177 */
178 virtual double GetLineSpacing() const = 0;
179
180 /** Retrieve the line spacing for this font
181 * \returns the linespacing in 1/1000th mm
182 */
183 inline unsigned long GetLineSpacingMM() const;
184
185 /** Get the width of the underline for the current
186 * font size in PDF units
187 * \returns the thickness of the underline in PDF units
188 */
189 virtual double GetUnderlineThickness() const = 0;
190
191 /** Get the width of the underline for the current
192 * font size in 1/1000th mm
193 * \returns the thickness of the underline in 1/1000th mm
194 */
195 inline unsigned long GetUnderlineThicknessMM() const;
196
197 /** Return the position of the underline for the current font
198 * size in PDF units
199 * \returns the underline position in PDF units
200 */
201 virtual double GetUnderlinePosition() const = 0;
202
203 /** Return the position of the underline for the current font
204 * size in 1/1000th mm
205 * \returns the underline position in 1/1000th mm
206 */
207 inline long GetUnderlinePositionMM() const;
208
209 /** Return the position of the strikeout for the current font
210 * size in PDF units
211 * \returns the underline position in PDF units
212 */
213 virtual double GetStrikeOutPosition() const = 0;
214
215 /** Return the position of the strikeout for the current font
216 * size in 1/1000th mm
217 * \returns the underline position in 1/1000th mm
218 */
219 inline unsigned long GetStrikeOutPositionMM() const;
220
221 /** Get the width of the strikeout for the current
222 * font size in PDF units
223 * \returns the thickness of the strikeout in PDF units
224 */
225 virtual double GetStrikeoutThickness() const = 0;
226
227 /** Get the width of the strikeout for the current
228 * font size in 1/1000th mm
229 * \returns the thickness of the strikeout in 1/1000th mm
230 */
231 inline unsigned long GetStrikeoutThicknessMM() const;
232
233 /** Get a pointer to the path of the font file.
234 * \returns a zero terminated string containing the filename of the font file
235 */
236 inline const char* GetFilename() const;
237
238 /** Get a pointer to the actual font data - if it was loaded from memory.
239 * \returns a binary buffer of data containing the font data
240 */
241 virtual const char* GetFontData() const = 0;
242
243 /** Get the length of the actual font data - if it was loaded from memory.
244 * \returns a the length of the font data
245 */
246 virtual pdf_long GetFontDataLen() const = 0;
247
248 /** Get a string with the postscript name of the font.
249 * \returns the postscript name of the font or NULL string if no postscript name is available.
250 */
251 virtual const char* GetFontname() const = 0;
252
253 /**
254 * \returns NULL or a 6 uppercase letter and "+" sign prefix
255 * used for font subsets
256 */
257 inline const char* GetSubsetFontnamePrefix() const;
258
259 /** Get the weight of this font.
260 * Used to build the font dictionay
261 * \returns the weight of this font (500 is normal).
262 */
263 virtual unsigned int GetWeight() const = 0;
264
265 /** Get the ascent of this font in PDF
266 * units for the current font size.
267 *
268 * \returns the ascender for this font
269 *
270 * \see GetPdfAscent
271 */
272 virtual double GetAscent() const = 0;
273
274 /** Get the ascent of this font
275 * Used to build the font dictionay
276 * \returns the ascender for this font
277 *
278 * \see GetAscent
279 */
280 virtual double GetPdfAscent() const = 0;
281
282 /** Get the descent of this font in PDF
283 * units for the current font size.
284 * This value is usually negative!
285 *
286 * \returns the descender for this font
287 *
288 * \see GetPdfDescent
289 */
290 virtual double GetDescent() const = 0;
291
292 /** Get the descent of this font
293 * Used to build the font dictionay
294 * \returns the descender for this font
295 *
296 * \see GetDescent
297 */
298 virtual double GetPdfDescent() const = 0;
299
300 /** Get the italic angle of this font.
301 * Used to build the font dictionay
302 * \returns the italic angle of this font.
303 */
304 virtual int GetItalicAngle() const = 0;
305
306 /** Set the font size of this metrics object for width and height
307 * calculations.
308 * This is typically called from PdfFont for you.
309 *
310 * \param fSize font size in points
311 */
312 inline void SetFontSize( float fSize );
313
314 /** Retrieve the current font size of this metrics object
315 * \returns the current font size
316 */
317 inline float GetFontSize() const;
318
319 /** Set the horizontal scaling of the font for compressing (< 100) and expanding (>100)
320 * This is typically called from PdfFont for you.
321 *
322 * \param fScale scaling in percent
323 */
324 inline void SetFontScale( float fScale );
325
326 /** Retrieve the current horizontal scaling of this metrics object
327 * \returns the current font scaling
328 */
329 inline float GetFontScale() const;
330
331 /** Set the character spacing of this metrics object
332 * \param fCharSpace character spacing in percent
333 */
334 inline void SetFontCharSpace( float fCharSpace );
335
336 /** Retrieve the current character spacing of this metrics object
337 * \returns the current font character spacing
338 */
339 inline float GetFontCharSpace() const;
340
341 /** Set the word spacing of this metrics object
342 * \param fWordSpace word spacing in PDF units
343 */
344 inline void SetWordSpace( float fWordSpace );
345
346 /** Retrieve the current word spacing of this metrics object
347 * \returns the current font word spacing in PDF units
348 */
349 inline float GetWordSpace() const;
350
351 /**
352 * \returns the fonttype of the loaded font
353 */
354 inline EPdfFontType GetFontType() const;
355
356 /** Get the glyph id for a unicode character
357 * in the current font.
358 *
359 * \param lUnicode the unicode character value
360 * \returns the glyhph id for the character or 0 if the glyph was not found.
361 */
362 virtual long GetGlyphId( long lUnicode ) const = 0;
363
364 /** Symbol fonts do need special treatment in a few cases.
365 * Use this method to check if the current font is a symbol
366 * font. Symbold fonts are detected by checking
367 * if they use FT_ENCODING_MS_SYMBOL as internal encoding.
368 *
369 * \returns true if this is a symbol font
370 */
371 virtual bool IsSymbol() const = 0;
372
373 /** Try to detect the internal fonttype from
374 * the file extension of a fontfile.
375 *
376 * \param pszFilename must be the filename of a font file
377 *
378 * \return font type
379 */
380 static EPdfFontType FontTypeFromFilename( const char* pszFilename );
381
382 protected:
383 /**
384 * Set the fonttype.
385 * \param eFontType fonttype
386 */
387 inline void SetFontType(EPdfFontType eFontType);
388
389 protected:
390 std::string m_sFilename;
391 float m_fFontSize;
392 float m_fFontScale;
393 float m_fFontCharSpace;
394 float m_fWordSpace;
395
396 std::vector<double> m_vecWidth;
397
398 EPdfFontType m_eFontType;
399 std::string m_sFontSubsetPrefix;
400 };
401
402 // -----------------------------------------------------
403 //
404 // -----------------------------------------------------
CharWidthMM(unsigned char c)405 unsigned long PdfFontMetrics::CharWidthMM( unsigned char c ) const
406 {
407 return static_cast<unsigned long>(this->CharWidth( c ) / PODOFO_CONVERSION_CONSTANT);
408 }
409
410 // -----------------------------------------------------
411 //
412 // -----------------------------------------------------
StringWidth(const PdfString & rsString)413 double PdfFontMetrics::StringWidth( const PdfString & rsString ) const
414 {
415 return (rsString.IsUnicode() ? this->StringWidth( rsString.GetUnicode() ) : this->StringWidth( rsString.GetString() ));
416 }
417
418 // -----------------------------------------------------
419 //
420 // -----------------------------------------------------
StringWidthMM(const char * pszText,unsigned int nLength)421 unsigned long PdfFontMetrics::StringWidthMM( const char* pszText, unsigned int nLength ) const
422 {
423 return static_cast<unsigned long>(this->StringWidth( pszText, nLength ) / PODOFO_CONVERSION_CONSTANT);
424 }
425
426 // -----------------------------------------------------
427 //
428 // -----------------------------------------------------
StringWidthMM(const pdf_utf16be * pszText,unsigned int nLength)429 unsigned long PdfFontMetrics::StringWidthMM( const pdf_utf16be* pszText, unsigned int nLength ) const
430 {
431 return static_cast<unsigned long>(this->StringWidth( pszText, nLength ) / PODOFO_CONVERSION_CONSTANT);
432 }
433
434 // -----------------------------------------------------
435 //
436 // -----------------------------------------------------
437 #ifndef _WCHAR_T_DEFINED
438 #if defined(_MSC_VER) && _MSC_VER <= 1200 // not for MS Visual Studio 6
439 #else
StringWidthMM(const wchar_t * pszText,unsigned int nLength)440 unsigned long PdfFontMetrics::StringWidthMM( const wchar_t* pszText, unsigned int nLength ) const
441 {
442 return static_cast<unsigned long>(this->StringWidth( pszText, nLength ) / PODOFO_CONVERSION_CONSTANT);
443 }
444 #endif
445 #endif
446
447 // -----------------------------------------------------
448 //
449 // -----------------------------------------------------
GetLineSpacingMM()450 unsigned long PdfFontMetrics::GetLineSpacingMM() const
451 {
452 return static_cast<unsigned long>(this->GetLineSpacing() / PODOFO_CONVERSION_CONSTANT);
453 }
454
455 // -----------------------------------------------------
456 //
457 // -----------------------------------------------------
GetUnderlinePositionMM()458 long PdfFontMetrics::GetUnderlinePositionMM() const
459 {
460 return static_cast<long>(this->GetUnderlinePosition() / PODOFO_CONVERSION_CONSTANT);
461 }
462
463 // -----------------------------------------------------
464 //
465 // -----------------------------------------------------
GetStrikeOutPositionMM()466 unsigned long PdfFontMetrics::GetStrikeOutPositionMM() const
467 {
468 return static_cast<long>(this->GetStrikeOutPosition() / PODOFO_CONVERSION_CONSTANT);
469 }
470
471 // -----------------------------------------------------
472 //
473 // -----------------------------------------------------
GetUnderlineThicknessMM()474 unsigned long PdfFontMetrics::GetUnderlineThicknessMM() const
475 {
476 return static_cast<unsigned long>(this->GetUnderlineThickness() / PODOFO_CONVERSION_CONSTANT);
477 }
478
479 // -----------------------------------------------------
480 //
481 // -----------------------------------------------------
GetStrikeoutThicknessMM()482 unsigned long PdfFontMetrics::GetStrikeoutThicknessMM() const
483 {
484 return static_cast<unsigned long>(this->GetStrikeoutThickness() / PODOFO_CONVERSION_CONSTANT);
485 }
486
487 // -----------------------------------------------------
488 //
489 // -----------------------------------------------------
GetFilename()490 const char* PdfFontMetrics::GetFilename() const
491 {
492 return m_sFilename.c_str();
493 }
494
495 // -----------------------------------------------------
496 //
497 // -----------------------------------------------------
GetFontType()498 EPdfFontType PdfFontMetrics::GetFontType() const
499 {
500 return m_eFontType;
501 }
502
503 // -----------------------------------------------------
504 //
505 // -----------------------------------------------------
SetFontType(EPdfFontType eFontType)506 void PdfFontMetrics::SetFontType(EPdfFontType eFontType)
507 {
508 m_eFontType = eFontType;
509 }
510
511 // -----------------------------------------------------
512 //
513 // -----------------------------------------------------
GetFontSize()514 float PdfFontMetrics::GetFontSize() const
515 {
516 return m_fFontSize;
517 }
518
519 // -----------------------------------------------------
520 //
521 // -----------------------------------------------------
SetFontSize(float fSize)522 void PdfFontMetrics::SetFontSize( float fSize )
523 {
524 m_fFontSize = fSize;
525 }
526
527 // -----------------------------------------------------
528 //
529 // -----------------------------------------------------
GetFontScale()530 float PdfFontMetrics::GetFontScale() const
531 {
532 return m_fFontScale;
533 }
534
535 // -----------------------------------------------------
536 //
537 // -----------------------------------------------------
GetFontCharSpace()538 float PdfFontMetrics::GetFontCharSpace() const
539 {
540 return m_fFontCharSpace;
541 }
542
543 // -----------------------------------------------------
544 //
545 // -----------------------------------------------------
GetWordSpace()546 inline float PdfFontMetrics::GetWordSpace() const
547 {
548 return m_fWordSpace;
549 }
550
551 // -----------------------------------------------------
552 //
553 // -----------------------------------------------------
GetSubsetFontnamePrefix()554 const char* PdfFontMetrics::GetSubsetFontnamePrefix() const
555 {
556 return m_sFontSubsetPrefix.c_str();
557 }
558
559 // -----------------------------------------------------
560 //
561 // -----------------------------------------------------
SetFontScale(float fScale)562 void PdfFontMetrics::SetFontScale( float fScale )
563 {
564 m_fFontScale = fScale;
565 }
566
567 // -----------------------------------------------------
568 //
569 // -----------------------------------------------------
SetFontCharSpace(float fCharSpace)570 void PdfFontMetrics::SetFontCharSpace( float fCharSpace )
571 {
572 m_fFontCharSpace = fCharSpace;
573 }
574
575 // -----------------------------------------------------
576 //
577 // -----------------------------------------------------
SetWordSpace(float fWordSpace)578 inline void PdfFontMetrics::SetWordSpace( float fWordSpace )
579 {
580 m_fWordSpace = fWordSpace;
581 }
582
583
584 };
585
586 #endif // _PDF_FONT_METRICS_H_
587
588