1 /* 2 * Copyright 2018 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkFontPriv_DEFINED 9 #define SkFontPriv_DEFINED 10 11 #include "SkFont.h" 12 #include "SkMatrix.h" 13 #include "SkTypeface.h" 14 15 class SkReadBuffer; 16 class SkWriteBuffer; 17 18 class SkFontPriv { 19 public: 20 /* This is the size we use when we ask for a glyph's path. We then 21 * post-transform it as we draw to match the request. 22 * This is done to try to re-use cache entries for the path. 23 * 24 * This value is somewhat arbitrary. In theory, it could be 1, since 25 * we store paths as floats. However, we get the path from the font 26 * scaler, and it may represent its paths as fixed-point (or 26.6), 27 * so we shouldn't ask for something too big (might overflow 16.16) 28 * or too small (underflow 26.6). 29 * 30 * This value could track kMaxSizeForGlyphCache, assuming the above 31 * constraints, but since we ask for unhinted paths, the two values 32 * need not match per-se. 33 */ 34 static constexpr int kCanonicalTextSizeForPaths = 64; 35 36 static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM, SkScalar maxLimit); 37 38 static SkScalar MaxCacheSize2(SkScalar maxLimit); 39 40 /** 41 * Return a matrix that applies the paint's text values: size, scale, skew 42 */ MakeTextMatrix(SkScalar size,SkScalar scaleX,SkScalar skewX)43 static SkMatrix MakeTextMatrix(SkScalar size, SkScalar scaleX, SkScalar skewX) { 44 SkMatrix m = SkMatrix::MakeScale(size * scaleX, size); 45 if (skewX) { 46 m.postSkew(skewX, 0); 47 } 48 return m; 49 } 50 MakeTextMatrix(const SkFont & font)51 static SkMatrix MakeTextMatrix(const SkFont& font) { 52 return MakeTextMatrix(font.getSize(), font.getScaleX(), font.getSkewX()); 53 } 54 55 static void ScaleFontMetrics(SkFontMetrics*, SkScalar); 56 57 // returns -1 if buffer is invalid for specified encoding 58 static int ValidCountText(const void* text, size_t length, SkTextEncoding); 59 60 /** 61 Returns the union of bounds of all glyphs. 62 Returned dimensions are computed by font manager from font data, 63 ignoring SkPaint::Hinting. Includes font metrics, but not fake bold or SkPathEffect. 64 65 If text size is large, text scale is one, and text skew is zero, 66 returns the bounds as: 67 { SkFontMetrics::fXMin, SkFontMetrics::fTop, SkFontMetrics::fXMax, SkFontMetrics::fBottom }. 68 69 @return union of bounds of all glyphs 70 */ 71 static SkRect GetFontBounds(const SkFont&); 72 IsFinite(const SkFont & font)73 static bool IsFinite(const SkFont& font) { 74 return SkScalarIsFinite(font.fSize) && 75 SkScalarIsFinite(font.fScaleX) && 76 SkScalarIsFinite(font.fSkewX); 77 } 78 79 // Returns the number of elements (characters or glyphs) in the array. 80 static int CountTextElements(const void* text, size_t byteLength, SkTextEncoding); 81 82 static void GlyphsToUnichars(const SkFont&, const uint16_t glyphs[], int count, SkUnichar[]); 83 84 static void Flatten(const SkFont&, SkWriteBuffer& buffer); 85 static bool Unflatten(SkFont*, SkReadBuffer& buffer); 86 }; 87 88 class SkAutoToGlyphs { 89 public: SkAutoToGlyphs(const SkFont & font,const void * text,size_t length,SkTextEncoding encoding)90 SkAutoToGlyphs(const SkFont& font, const void* text, size_t length, SkTextEncoding encoding) { 91 if (encoding == kGlyphID_SkTextEncoding || length == 0) { 92 fGlyphs = reinterpret_cast<const uint16_t*>(text); 93 fCount = length >> 1; 94 } else { 95 fCount = font.countText(text, length, encoding); 96 fStorage.reset(fCount); 97 font.textToGlyphs(text, length, encoding, fStorage.get(), fCount); 98 fGlyphs = fStorage.get(); 99 } 100 } 101 count()102 int count() const { return fCount; } glyphs()103 const uint16_t* glyphs() const { return fGlyphs; } 104 105 private: 106 SkAutoSTArray<32, uint16_t> fStorage; 107 const uint16_t* fGlyphs; 108 int fCount; 109 }; 110 111 #endif 112