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
16class SkReadBuffer;
17class SkWriteBuffer;
18
19class SkFontPriv {
20public:
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 static constexpr int kCanonicalTextSizeForPaths = 64;
36
37 /**
38 * Return a matrix that applies the paint's text values: size, scale, skew
39 */
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
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 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
81 static inline uint8_t Flags(const SkFont& font) { return font.fFlags; }
82};
83
84class SkAutoToGlyphs {
85public:
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
101 int count() const { return fCount; }
102 const uint16_t* glyphs() const { return fGlyphs; }
103
104private:
105 SkAutoSTArray<32, uint16_t> fStorage;
106 const uint16_t* fGlyphs;
107 int fCount;
108};
109
110#endif
111