1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef GFX_HARFBUZZSHAPER_H 7 #define GFX_HARFBUZZSHAPER_H 8 9 #include "gfxFont.h" 10 11 #include "harfbuzz/hb.h" 12 #include "nsUnicodeProperties.h" 13 #include "mozilla/gfx/2D.h" 14 15 class gfxHarfBuzzShaper : public gfxFontShaper { 16 public: 17 explicit gfxHarfBuzzShaper(gfxFont *aFont); 18 virtual ~gfxHarfBuzzShaper(); 19 20 /* 21 * For HarfBuzz font callback functions, font_data is a ptr to a 22 * FontCallbackData struct 23 */ 24 struct FontCallbackData { 25 gfxHarfBuzzShaper* mShaper; 26 mozilla::gfx::DrawTarget* mDrawTarget; 27 }; 28 29 bool Initialize(); 30 virtual bool ShapeText(DrawTarget *aDrawTarget, 31 const char16_t *aText, 32 uint32_t aOffset, 33 uint32_t aLength, 34 Script aScript, 35 bool aVertical, 36 gfxShapedText *aShapedText); 37 38 // get a given font table in harfbuzz blob form 39 hb_blob_t * GetFontTable(hb_tag_t aTag) const; 40 41 // map unicode character to glyph ID 42 hb_codepoint_t GetNominalGlyph(hb_codepoint_t unicode) const; 43 hb_codepoint_t GetVariationGlyph(hb_codepoint_t unicode, 44 hb_codepoint_t variation_selector) const; 45 46 // get harfbuzz glyph advance, in font design units 47 hb_position_t GetGlyphHAdvance(hb_codepoint_t glyph) const; 48 49 hb_position_t GetGlyphVAdvance(hb_codepoint_t glyph) const; 50 51 void GetGlyphVOrigin(hb_codepoint_t aGlyph, 52 hb_position_t *aX, hb_position_t *aY) const; 53 54 // get harfbuzz horizontal advance in 16.16 fixed point format. 55 static hb_position_t 56 HBGetGlyphHAdvance(hb_font_t *font, void *font_data, 57 hb_codepoint_t glyph, void *user_data); 58 59 // get harfbuzz vertical advance in 16.16 fixed point format. 60 static hb_position_t 61 HBGetGlyphVAdvance(hb_font_t *font, void *font_data, 62 hb_codepoint_t glyph, void *user_data); 63 64 static hb_bool_t 65 HBGetGlyphVOrigin(hb_font_t *font, void *font_data, 66 hb_codepoint_t glyph, 67 hb_position_t *x, hb_position_t *y, 68 void *user_data); 69 70 hb_position_t GetHKerning(uint16_t aFirstGlyph, 71 uint16_t aSecondGlyph) const; 72 73 hb_bool_t GetGlyphExtents(hb_codepoint_t aGlyph, 74 hb_glyph_extents_t *aExtents) const; 75 UseVerticalPresentationForms()76 bool UseVerticalPresentationForms() const 77 { 78 return mUseVerticalPresentationForms; 79 } 80 81 static hb_script_t GetHBScriptUsedForShaping(Script aScript)82 GetHBScriptUsedForShaping(Script aScript) { 83 // Decide what harfbuzz script code will be used for shaping 84 hb_script_t hbScript; 85 if (aScript <= Script::INHERITED) { 86 // For unresolved "common" or "inherited" runs, 87 // default to Latin for now. 88 hbScript = HB_SCRIPT_LATIN; 89 } else { 90 hbScript = 91 hb_script_t(mozilla::unicode::GetScriptTagForCode(aScript)); 92 } 93 return hbScript; 94 } 95 96 protected: 97 nsresult SetGlyphsFromRun(DrawTarget *aDrawTarget, 98 gfxShapedText *aShapedText, 99 uint32_t aOffset, 100 uint32_t aLength, 101 const char16_t *aText, 102 hb_buffer_t *aBuffer, 103 bool aVertical); 104 105 // retrieve glyph positions, applying advance adjustments and attachments 106 // returns results in appUnits 107 nscoord GetGlyphPositions(gfxContext *aContext, 108 hb_buffer_t *aBuffer, 109 nsTArray<nsPoint>& aPositions, 110 uint32_t aAppUnitsPerDevUnit); 111 112 bool InitializeVertical(); 113 bool LoadHmtxTable(); 114 115 struct Glyf { // we only need the bounding-box at the beginning 116 // of the glyph record, not the actual outline data 117 AutoSwap_PRInt16 numberOfContours; 118 AutoSwap_PRInt16 xMin; 119 AutoSwap_PRInt16 yMin; 120 AutoSwap_PRInt16 xMax; 121 AutoSwap_PRInt16 yMax; 122 }; 123 124 const Glyf *FindGlyf(hb_codepoint_t aGlyph, bool *aEmptyGlyf) const; 125 126 // harfbuzz face object: we acquire a reference from the font entry 127 // on shaper creation, and release it in our destructor 128 hb_face_t *mHBFace; 129 130 // size-specific font object, owned by the gfxHarfBuzzShaper 131 hb_font_t *mHBFont; 132 133 FontCallbackData mCallbackData; 134 135 // Following table references etc are declared "mutable" because the 136 // harfbuzz callback functions take a const ptr to the shaper, but 137 // wish to cache tables here to avoid repeatedly looking them up 138 // in the font. 139 140 // Old-style TrueType kern table, if we're not doing GPOS kerning 141 mutable hb_blob_t *mKernTable; 142 143 // Cached copy of the hmtx table. 144 mutable hb_blob_t *mHmtxTable; 145 146 // For vertical fonts, cached vmtx and VORG table, if present. 147 mutable hb_blob_t *mVmtxTable; 148 mutable hb_blob_t *mVORGTable; 149 // And for vertical TrueType (not CFF) fonts that have vmtx, 150 // we also use loca and glyf to get glyph bounding boxes. 151 mutable hb_blob_t *mLocaTable; 152 mutable hb_blob_t *mGlyfTable; 153 154 // Cached pointer to cmap subtable to be used for char-to-glyph mapping. 155 // This comes from GetFontTablePtr; if it is non-null, our destructor 156 // must call ReleaseFontTablePtr to avoid permanently caching the table. 157 mutable hb_blob_t *mCmapTable; 158 mutable int32_t mCmapFormat; 159 mutable uint32_t mSubtableOffset; 160 mutable uint32_t mUVSTableOffset; 161 162 // Cached copy of numLongMetrics field from the hhea table, 163 // for use when looking up glyph metrics; initialized to 0 by the 164 // constructor so we can tell it hasn't been set yet. 165 // This is a signed value so that we can use -1 to indicate 166 // an error (if the hhea table was not available). 167 mutable int32_t mNumLongHMetrics; 168 // Similarly for vhea if it's a vertical font. 169 mutable int32_t mNumLongVMetrics; 170 171 // Whether the font implements GetGlyph, or we should read tables 172 // directly 173 bool mUseFontGetGlyph; 174 // Whether the font implements GetGlyphWidth, or we should read tables 175 // directly to get ideal widths 176 bool mUseFontGlyphWidths; 177 178 bool mInitialized; 179 bool mVerticalInitialized; 180 181 // Whether to use vertical presentation forms for CJK characters 182 // when available (only set if the 'vert' feature is not available). 183 bool mUseVerticalPresentationForms; 184 185 // these are set from the FindGlyf callback on first use of the glyf data 186 mutable bool mLoadedLocaGlyf; 187 mutable bool mLocaLongOffsets; 188 }; 189 190 #endif /* GFX_HARFBUZZSHAPER_H */ 191