1 /** \file lvfreetypeface.h 2 \brief FreeType font interface 3 4 CoolReader Engine 5 6 7 (c) Vadim Lopatin, 2000-2006 8 This source code is distributed under the terms of 9 GNU General Public License. 10 11 See LICENSE file for details. 12 13 */ 14 15 #ifndef __LV_FREETYPEFACE_H_INCLUDED__ 16 #define __LV_FREETYPEFACE_H_INCLUDED__ 17 18 19 #include "../../include/crsetup.h" 20 #include "../../include/lvfont.h" 21 #include "../../include/lvthread.h" 22 #include "lvfontglyphcache.h" 23 #include "lvfontdef.h" 24 #include "lvfontcache.h" 25 26 // define to filter out all fonts except .ttf 27 //#define LOAD_TTF_FONTS_ONLY 28 // DEBUG ONLY 29 #if 0 30 #define USE_FREETYPE 1 31 #define USE_FONTCONFIG 1 32 //#define DEBUG_FONT_SYNTHESIS 1 33 //#define DEBUG_FONT_MAN 1 34 //#define DEBUG_FONT_MAN_LOG_FILE "/tmp/font_man.log" 35 #endif 36 37 #if (USE_FREETYPE == 1) 38 39 #include <ft2build.h> 40 #include FT_FREETYPE_H 41 42 #if USE_HARFBUZZ == 1 43 44 #include <hb.h> 45 #include <hb-ft.h> 46 #include "../../include/lvhashtable.h" 47 48 #endif 49 50 // Use Freetype embolden API instead of LVFontBoldTransform to 51 // make fake bold (for fonts that do not provide a bold face). 52 // This gives a chance to get them working with Harfbuzz, even if 53 // they won't look as nice as if they came with a real bold font. 54 #define USE_FT_EMBOLDEN 55 56 #define CACHED_UNSIGNED_METRIC_NOT_SET 0xFFFF 57 class LVFontGlyphUnsignedMetricCache 58 { 59 private: 60 static const int COUNT = 360; 61 lUInt16 * ptrs[COUNT]; //support up to 0X2CFFF=360*512-1 62 public: get(lChar32 ch)63 lUInt16 get( lChar32 ch ) 64 { 65 FONT_GLYPH_CACHE_GUARD 66 int inx = (ch>>9) & 0x1ff; 67 if (inx >= COUNT) return CACHED_UNSIGNED_METRIC_NOT_SET; 68 lUInt16 * ptr = ptrs[inx]; 69 if ( !ptr ) 70 return CACHED_UNSIGNED_METRIC_NOT_SET; 71 return ptr[ch & 0x1FF ]; 72 } put(lChar32 ch,lUInt16 m)73 void put( lChar32 ch, lUInt16 m ) 74 { 75 FONT_GLYPH_CACHE_GUARD 76 int inx = (ch>>9) & 0x1ff; 77 if (inx >= COUNT) return; 78 lUInt16 * ptr = ptrs[inx]; 79 if ( !ptr ) { 80 ptr = new lUInt16[512]; 81 ptrs[inx] = ptr; 82 memset( ptr, CACHED_UNSIGNED_METRIC_NOT_SET, sizeof(lUInt16) * 512 ); 83 } 84 ptr[ ch & 0x1FF ] = m; 85 } clear()86 void clear() 87 { 88 FONT_GLYPH_CACHE_GUARD 89 for ( int i=0; i<360; i++ ) { 90 if ( ptrs[i] ) 91 delete [] ptrs[i]; 92 ptrs[i] = NULL; 93 } 94 } LVFontGlyphUnsignedMetricCache()95 LVFontGlyphUnsignedMetricCache() 96 { 97 memset( ptrs, 0, 360*sizeof(lUInt16*) ); 98 } ~LVFontGlyphUnsignedMetricCache()99 ~LVFontGlyphUnsignedMetricCache() 100 { 101 clear(); 102 } 103 }; 104 105 #define CACHED_SIGNED_METRIC_NOT_SET 0x7FFF 106 #define CACHED_SIGNED_METRIC_SHIFT 0x8000 107 class LVFontGlyphSignedMetricCache : public LVFontGlyphUnsignedMetricCache 108 { 109 public: get(lChar32 ch)110 lInt16 get( lChar32 ch ) 111 { 112 return (lInt16) ( LVFontGlyphUnsignedMetricCache::get(ch) - CACHED_SIGNED_METRIC_SHIFT ); 113 } put(lChar32 ch,lInt16 m)114 void put( lChar32 ch, lInt16 m ) 115 { 116 LVFontGlyphUnsignedMetricCache::put(ch, (lUInt16)( m + CACHED_SIGNED_METRIC_SHIFT) ); 117 } 118 }; 119 120 class LVFreeTypeFace : public LVFont { 121 protected: 122 LVMutex &_mutex; 123 lString8 _fileName; 124 lString8 _faceName; 125 css_font_family_t _fontFamily; 126 FT_Library _library; 127 FT_Face _face; 128 FT_GlyphSlot _slot; 129 FT_Matrix _matrix; // helper matrix for fake italic metrics 130 int _size; // caracter height in pixels 131 int _height; // full line height in pixels 132 int _hyphen_width; 133 int _baseline; 134 int _weight; 135 int _italic; 136 LVFontGlyphUnsignedMetricCache _wcache; 137 LVFontGlyphSignedMetricCache _lsbcache; // glyph left side bearing cache 138 LVFontGlyphSignedMetricCache _rsbcache; // glyph right side bearing cache 139 LVFontLocalGlyphCache _glyph_cache; 140 bool _drawMonochrome; 141 hinting_mode_t _hintingMode; 142 shaping_mode_t _shapingMode; 143 bool _fallbackFontIsSet; 144 LVFontRef _fallbackFont; 145 /** 146 * @brief Fallback mask for this fallback font. 147 * 0 - for normal (not fallback) font 148 * <any> - A mask with only one bit set, the number of which corresponds to the number in the fallback font chain. 149 */ 150 lUInt32 _fallback_mask; 151 bool _embolden; // fake/synthetized bold 152 bool _allowKerning; 153 FT_Pos _embolden_half_strength; // for emboldening with Harfbuzz 154 int _features; // requested OpenType features bitmap 155 #if USE_HARFBUZZ == 1 156 hb_font_t *_hb_font; 157 hb_buffer_t *_hb_buffer; 158 LVArray<hb_feature_t> _hb_features; 159 // For use with SHAPING_MODE_HARFBUZZ: 160 LVFontLocalGlyphCache _glyph_cache2; 161 // For use with SHAPING_MODE_HARFBUZZ_LIGHT: 162 LVHashTable<struct LVCharTriplet, struct LVCharPosInfo> _width_cache2; 163 #endif 164 public: 165 166 // fallback font support 167 getFallbackMask()168 virtual lUInt32 getFallbackMask() const { 169 return _fallback_mask; 170 } 171 setFallbackMask(lUInt32 mask)172 virtual void setFallbackMask(lUInt32 mask) { 173 _fallback_mask = mask; 174 } 175 176 /// set fallback font for this font 177 virtual void setFallbackFont(LVFontRef font); 178 179 /// get fallback font for this font 180 virtual LVFont *getFallbackFont(lUInt32 fallbackPassMask); 181 182 /// returns font weight getWeight()183 virtual int getWeight() const { return _weight; } 184 185 /// returns italic flag getItalic()186 virtual int getItalic() const { return _italic; } 187 188 /// sets face name setFaceName(lString8 face)189 virtual void setFaceName(lString8 face) { _faceName = face; } 190 getMutex()191 LVMutex &getMutex() { return _mutex; } 192 getLibrary()193 FT_Library getLibrary() { return _library; } 194 195 LVFreeTypeFace(LVMutex &mutex, FT_Library library, LVFontGlobalGlyphCache *globalCache); 196 197 virtual ~LVFreeTypeFace(); 198 199 virtual void clearCache(); 200 201 virtual int getHyphenWidth(); 202 203 /// get kerning mode: true==ON, false=OFF getKerning()204 virtual bool getKerning() const { return _allowKerning; } 205 206 /// set kerning mode: true==ON, false=OFF 207 virtual void setKerning(bool kerningEnabled); 208 209 /// sets current hinting mode 210 virtual void setHintingMode(hinting_mode_t mode); 211 212 /// returns current hinting mode getHintingMode()213 virtual hinting_mode_t getHintingMode() const { return _hintingMode; } 214 215 /// sets current shaping mode 216 virtual void setShapingMode( shaping_mode_t shapingMode ); 217 218 /// returns current kerning mode getShapingMode()219 virtual shaping_mode_t getShapingMode() const { return _shapingMode; } 220 221 /// get bitmap mode (true=bitmap, false=antialiased) getBitmapMode()222 virtual bool getBitmapMode() { return _drawMonochrome; } 223 224 /// set bitmap mode (true=bitmap, false=antialiased) 225 virtual void setBitmapMode(bool drawBitmap); 226 227 /// get OpenType features (bitmap) getFeatures()228 virtual int getFeatures() const { return _features; } 229 230 /// set OpenType features (bitmap) 231 virtual void setFeatures( int features ); 232 233 void setEmbolden(); 234 235 bool loadFromBuffer(LVByteArrayRef buf, int index, int size, css_font_family_t fontFamily, 236 bool monochrome, bool italicize); 237 238 bool loadFromFile(const char *fname, int index, int size, css_font_family_t fontFamily, 239 bool monochrome, bool italicize); 240 241 /** \brief get glyph info 242 \param glyph is pointer to glyph_info_t struct to place retrieved info 243 \return true if glyh was found 244 */ 245 virtual bool getGlyphInfo(lUInt32 code, glyph_info_t *glyph, lChar32 def_char = 0, lUInt32 fallbackPassMask = 0); 246 /* 247 // USE GET_CHAR_FLAGS instead 248 inline int calcCharFlags( lChar32 ch ) 249 { 250 switch ( ch ) { 251 case 0x0020: 252 return LCHAR_IS_SPACE | LCHAR_ALLOW_WRAP_AFTER; 253 case UNICODE_SOFT_HYPHEN_CODE: 254 return LCHAR_ALLOW_WRAP_AFTER; 255 case '-': 256 return LCHAR_DEPRECATED_WRAP_AFTER; 257 case '\r': 258 case '\n': 259 return LCHAR_IS_SPACE | LCHAR_IS_EOL | LCHAR_ALLOW_WRAP_AFTER; 260 default: 261 return 0; 262 } 263 } 264 */ 265 266 /** 267 * @brief Check font for compatibility with language with langCode 268 * @param langCode language code, for example, "en" - English, "ru" - Russian 269 * @return true if font contains all glyphs for given language, false otherwise. 270 */ 271 virtual bool checkFontLangCompat(const lString8 &langCode); 272 273 /** \brief measure text 274 \param text is text string pointer 275 \param len is number of characters to measure 276 \return number of characters before max_width reached 277 */ 278 virtual lUInt16 measureText( 279 const lChar32 *text, int len, 280 lUInt16 *widths, 281 lUInt8 *flags, 282 int max_width, 283 lChar32 def_char, 284 TextLangCfg * lang_cfg = NULL, 285 int letter_spacing = 0, 286 bool allow_hyphenation = true, 287 lUInt32 hints = 0, 288 lUInt32 fallbackPassMask = 0 289 ); 290 291 /** \brief measure text 292 \param text is text string pointer 293 \param len is number of characters to measure 294 \return width of specified string 295 */ 296 virtual lUInt32 getTextWidth( 297 const lChar32 *text, int len, TextLangCfg * lang_cfg = NULL 298 ); 299 300 /** \brief get glyph item 301 \param code is unicode character 302 \return glyph pointer if glyph was found, NULL otherwise 303 */ 304 virtual LVFontGlyphCacheItem *getGlyph(lUInt32 ch, lChar32 def_char = 0, lUInt32 fallbackPassMask = 0); 305 306 // /** \brief get glyph image in 1 byte per pixel format 307 // \param code is unicode character 308 // \param buf is buffer [width*height] to place glyph data 309 // \return true if glyph was found 310 // */ 311 // virtual bool getGlyphImage(lUInt16 ch, lUInt8 * bmp, lChar32 def_char=0) 312 // { 313 // LVFontGlyphCacheItem * item = getGlyph(ch); 314 // if ( item ) 315 // memcpy( bmp, item->bmp, item->bmp_width * item->bmp_height ); 316 // return item; 317 // } 318 319 /// returns font baseline offset getBaseline()320 virtual int getBaseline() { 321 return _baseline; 322 } 323 324 /// returns font height getHeight()325 virtual int getHeight() const { 326 return _height; 327 } 328 329 /// returns font character size getSize()330 virtual int getSize() const { 331 return _size; 332 } 333 334 /// returns char width 335 virtual int getCharWidth(lChar32 ch, lChar32 def_char = '?'); 336 337 /// returns char glyph left side bearing 338 int getLeftSideBearing( lChar32 ch, bool negative_only=false, bool italic_only=false ); 339 340 /// returns char glyph right side bearing 341 virtual int getRightSideBearing( lChar32 ch, bool negative_only=false, bool italic_only=false ); 342 343 /// retrieves font handle GetHandle()344 virtual void *GetHandle() { 345 return NULL; 346 } 347 348 /// returns font typeface name getTypeFace()349 virtual lString8 getTypeFace() const { 350 return _faceName; 351 } 352 353 /// returns font family id getFontFamily()354 virtual css_font_family_t getFontFamily() const { 355 return _fontFamily; 356 } 357 kerningEnabled()358 virtual bool kerningEnabled() { 359 #if (ALLOW_KERNING==1) 360 #if USE_HARFBUZZ==1 361 return _allowKerning; 362 #else 363 return _allowKerning && FT_HAS_KERNING( _face ); 364 #endif 365 #else 366 return false; 367 #endif 368 } 369 370 /// draws text string 371 virtual int DrawTextString(LVDrawBuf *buf, int x, int y, 372 const lChar32 *text, int len, 373 lChar32 def_char, lUInt32 *palette = NULL, 374 bool addHyphen = false, TextLangCfg * lang_cfg = NULL, 375 lUInt32 flags = 0, int letter_spacing = 0, int width=-1, 376 int text_decoration_back_gap = 0, 377 lUInt32 fallbackPassMask = 0); 378 379 /// returns true if font is empty IsNull()380 virtual bool IsNull() const { 381 return _face == NULL; 382 } 383 384 virtual bool operator!() const { 385 return _face == NULL; 386 } 387 388 virtual void Clear(); 389 protected: 390 void updateTransform(); 391 FT_UInt getCharIndex(lUInt32 code, lChar32 def_char); 392 #if USE_HARFBUZZ==1 393 LVFontGlyphCacheItem *getGlyphByIndex(lUInt32 index); 394 lChar32 filterChar(lChar32 code, lChar32 def_char=0); 395 bool hbCalcCharWidth(struct LVCharPosInfo *posInfo, const struct LVCharTriplet &triplet, 396 lChar32 def_char, lUInt32 fallbackPassMask); 397 bool setHBFeatureValue(const char * tag, uint32_t value); 398 bool addHBFeature(const char * tag); 399 bool delHBFeature(const char * tag); 400 void setupHBFeatures(); 401 #endif 402 }; 403 404 #endif // (USE_FREETYPE==1) 405 406 #endif // __LV_FREETYPEFACE_H_INCLUDED__ 407