• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/base/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 
67     /** Return the approximate largest dimension of typical text when transformed by the matrix.
68      *
69      * @param matrix  used to transform size
70      * @param textLocation  location of the text prior to matrix transformation. Used if the
71      *                      matrix has perspective.
72      * @return  typical largest dimension
73      */
74     static SkScalar ApproximateTransformedTextSize(const SkFont& font, const SkMatrix& matrix,
75                                                    const SkPoint& textLocation);
76 
IsFinite(const SkFont & font)77     static bool IsFinite(const SkFont& font) {
78         return SkScalarIsFinite(font.getSize()) &&
79                SkScalarIsFinite(font.getScaleX()) &&
80                SkScalarIsFinite(font.getSkewX());
81     }
82 
83     // Returns the number of elements (characters or glyphs) in the array.
84     static int CountTextElements(const void* text, size_t byteLength, SkTextEncoding);
85 
86     static void GlyphsToUnichars(const SkFont&, const uint16_t glyphs[], int count, SkUnichar[]);
87 
88     static void Flatten(const SkFont&, SkWriteBuffer& buffer);
89     static bool Unflatten(SkFont*, SkReadBuffer& buffer);
90 
Flags(const SkFont & font)91     static inline uint8_t Flags(const SkFont& font) { return font.fFlags; }
92 };
93 
94 class SkAutoToGlyphs {
95 public:
SkAutoToGlyphs(const SkFont & font,const void * text,size_t length,SkTextEncoding encoding)96     SkAutoToGlyphs(const SkFont& font, const void* text, size_t length, SkTextEncoding encoding) {
97         if (encoding == SkTextEncoding::kGlyphID || length == 0) {
98             fGlyphs = reinterpret_cast<const uint16_t*>(text);
99             fCount = SkToInt(length >> 1);
100         } else {
101             fCount = font.countText(text, length, encoding);
102             if (fCount < 0) {
103                 fCount = 0;
104             }
105             fStorage.reset(fCount);
106             font.textToGlyphs(text, length, encoding, fStorage.get(), fCount);
107             fGlyphs = fStorage.get();
108         }
109     }
110 
count()111     int count() const { return fCount; }
glyphs()112     const uint16_t* glyphs() const { return fGlyphs; }
113 
114 private:
115     skia_private::AutoSTArray<32, uint16_t> fStorage;
116     const uint16_t* fGlyphs;
117     int             fCount;
118 };
119 
120 #endif
121