1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MINIKIN_FONT_H
18 #define MINIKIN_FONT_H
19 
20 #include <string>
21 
22 #include "minikin/FontFamily.h"
23 #include "minikin/Hyphenator.h"
24 
25 // An abstraction for platform fonts, allowing Minikin to be used with
26 // multiple actual implementations of fonts.
27 
28 namespace minikin {
29 
30 class FontCollection;
31 class MinikinFont;
32 
33 // Possibly move into own .h file?
34 // Note: if you add a field here, either add it to LayoutCacheKey or to skipCache()
35 struct MinikinPaint {
MinikinPaintMinikinPaint36     MinikinPaint(const std::shared_ptr<FontCollection>& font)
37             : size(0),
38               scaleX(0),
39               skewX(0),
40               letterSpacing(0),
41               wordSpacing(0),
42               paintFlags(0),
43               localeListId(0),
44               familyVariant(FontFamily::Variant::DEFAULT),
45               fontFeatureSettings(),
46               font(font) {}
47 
skipCacheMinikinPaint48     bool skipCache() const { return !fontFeatureSettings.empty(); }
49 
50     float size;
51     float scaleX;
52     float skewX;
53     float letterSpacing;
54     float wordSpacing;
55     uint32_t paintFlags;
56     uint32_t localeListId;
57     FontStyle fontStyle;
58     FontFamily::Variant familyVariant;
59     std::string fontFeatureSettings;
60     std::shared_ptr<FontCollection> font;
61 
copyFromMinikinPaint62     void copyFrom(const MinikinPaint& paint) { *this = paint; }
63 
64     MinikinPaint(MinikinPaint&&) = default;
65     MinikinPaint& operator=(MinikinPaint&&) = default;
66 
67     inline bool operator==(const MinikinPaint& paint) {
68         return size == paint.size && scaleX == paint.scaleX && skewX == paint.skewX &&
69                letterSpacing == paint.letterSpacing && wordSpacing == paint.wordSpacing &&
70                paintFlags == paint.paintFlags && localeListId == paint.localeListId &&
71                fontStyle == paint.fontStyle && familyVariant == paint.familyVariant &&
72                fontFeatureSettings == paint.fontFeatureSettings && font.get() == paint.font.get();
73     }
74 
75 private:
76     // Forbid implicit copy and assign. Use copyFrom instead.
77     MinikinPaint(const MinikinPaint&) = default;
78     MinikinPaint& operator=(const MinikinPaint&) = default;
79 };
80 
81 // Only a few flags affect layout, but those that do should have values
82 // consistent with Android's paint flags.
83 enum MinikinPaintFlags {
84     LinearTextFlag = 0x40,
85 };
86 
87 struct MinikinRect {
88     float mLeft = 0.0;
89     float mTop = 0.0;
90     float mRight = 0.0;
91     float mBottom = 0.0;
isEmptyMinikinRect92     bool isEmpty() const { return mLeft == mRight || mTop == mBottom; }
setMinikinRect93     void set(const MinikinRect& r) {
94         mLeft = r.mLeft;
95         mTop = r.mTop;
96         mRight = r.mRight;
97         mBottom = r.mBottom;
98     }
offsetMinikinRect99     void offset(float dx, float dy) {
100         mLeft += dx;
101         mTop += dy;
102         mRight += dx;
103         mBottom += dy;
104     }
setEmptyMinikinRect105     void setEmpty() { mLeft = mTop = mRight = mBottom = 0.0; }
106     void join(const MinikinRect& r);
107 };
108 
109 // For holding vertical extents.
110 struct MinikinExtent {
111     float ascent = 0.0;    // negative
112     float descent = 0.0;   // positive
113     float line_gap = 0.0;  // positive
114 
resetMinikinExtent115     void reset() { ascent = descent = line_gap = 0.0; }
116 
extendByMinikinExtent117     void extendBy(const MinikinExtent& e) {
118         ascent = std::min(ascent, e.ascent);
119         descent = std::max(descent, e.descent);
120         line_gap = std::max(line_gap, e.line_gap);
121     }
122 };
123 
124 class MinikinFont {
125 public:
MinikinFont(int32_t uniqueId)126     explicit MinikinFont(int32_t uniqueId) : mUniqueId(uniqueId) {}
127 
~MinikinFont()128     virtual ~MinikinFont() {}
129 
130     virtual float GetHorizontalAdvance(uint32_t glyph_id, const MinikinPaint& paint,
131                                        const FontFakery& fakery) const = 0;
132 
133     virtual void GetBounds(MinikinRect* bounds, uint32_t glyph_id, const MinikinPaint& paint,
134                            const FontFakery& fakery) const = 0;
135 
136     virtual void GetFontExtent(MinikinExtent* extent, const MinikinPaint& paint,
137                                const FontFakery& fakery) const = 0;
138 
139     // Override if font can provide access to raw data
GetFontData()140     virtual const void* GetFontData() const { return nullptr; }
141 
142     // Override if font can provide access to raw data
GetFontSize()143     virtual size_t GetFontSize() const { return 0; }
144 
145     // Override if font can provide access to raw data.
146     // Returns index within OpenType collection
GetFontIndex()147     virtual int GetFontIndex() const { return 0; }
148 
149     virtual const std::vector<minikin::FontVariation>& GetAxes() const = 0;
150 
createFontWithVariation(const std::vector<FontVariation> &)151     virtual std::shared_ptr<MinikinFont> createFontWithVariation(
152             const std::vector<FontVariation>&) const {
153         return nullptr;
154     }
155 
MakeTag(char c1,char c2,char c3,char c4)156     static uint32_t MakeTag(char c1, char c2, char c3, char c4) {
157         return ((uint32_t)c1 << 24) | ((uint32_t)c2 << 16) | ((uint32_t)c3 << 8) | (uint32_t)c4;
158     }
159 
GetUniqueId()160     int32_t GetUniqueId() const { return mUniqueId; }
161 
162 private:
163     const int32_t mUniqueId;
164 };
165 
166 }  // namespace minikin
167 
168 #endif  // MINIKIN_FONT_H
169