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