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