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