• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_LAYOUT_H
18 #define MINIKIN_LAYOUT_H
19 
20 #include <hb.h>
21 
22 #include <memory>
23 #include <vector>
24 
25 #include <minikin/FontCollection.h>
26 
27 namespace minikin {
28 
29 struct LayoutGlyph {
30     // index into mFaces and mHbFonts vectors. We could imagine
31     // moving this into a run length representation, because it's
32     // more efficient for long strings, and we'll probably need
33     // something like that for paint attributes (color, underline,
34     // fake b/i, etc), as having those per-glyph is bloated.
35     int font_ix;
36 
37     unsigned int glyph_id;
38     float x;
39     float y;
40 };
41 
42 // Internal state used during layout operation
43 struct LayoutContext;
44 
45 enum {
46     kBidi_LTR = 0,
47     kBidi_RTL = 1,
48     kBidi_Default_LTR = 2,
49     kBidi_Default_RTL = 3,
50     kBidi_Force_LTR = 4,
51     kBidi_Force_RTL = 5,
52 
53     kBidi_Mask = 0x7
54 };
55 
56 // Lifecycle and threading assumptions for Layout:
57 // The object is assumed to be owned by a single thread; multiple threads
58 // may not mutate it at the same time.
59 class Layout {
60 public:
61 
Layout()62     Layout() : mGlyphs(), mAdvances(), mFaces(), mAdvance(0), mBounds() {
63         mBounds.setEmpty();
64     }
65 
66     Layout(Layout&& layout) = default;
67 
68     // Forbid copying and assignment.
69     Layout(const Layout&) = delete;
70     void operator=(const Layout&) = delete;
71 
72     void dump() const;
73 
74     void doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
75         int bidiFlags, const FontStyle &style, const MinikinPaint &paint,
76         const std::shared_ptr<FontCollection>& collection);
77 
78     static float measureText(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
79         int bidiFlags, const FontStyle &style, const MinikinPaint &paint,
80         const std::shared_ptr<FontCollection>& collection, float* advances);
81 
82     // public accessors
83     size_t nGlyphs() const;
84     const MinikinFont* getFont(int i) const;
85     FontFakery getFakery(int i) const;
86     unsigned int getGlyphId(int i) const;
87     float getX(int i) const;
88     float getY(int i) const;
89 
90     float getAdvance() const;
91 
92     // Get advances, copying into caller-provided buffer. The size of this
93     // buffer must match the length of the string (count arg to doLayout).
94     void getAdvances(float* advances);
95 
96     // The i parameter is an offset within the buf relative to start, it is < count, where
97     // start and count are the parameters to doLayout
getCharAdvance(size_t i)98     float getCharAdvance(size_t i) const { return mAdvances[i]; }
99 
100     void getBounds(MinikinRect* rect) const;
101 
102     // Purge all caches, useful in low memory conditions
103     static void purgeCaches();
104 
105 private:
106     friend class LayoutCacheKey;
107 
108     // Find a face in the mFaces vector, or create a new entry
109     int findFace(const FakedFont& face, LayoutContext* ctx);
110 
111     // Clears layout, ready to be used again
112     void reset();
113 
114     // Lay out a single bidi run
115     // When layout is not null, layout info will be stored in the object.
116     // When advances is not null, measurement results will be stored in the array.
117     static float doLayoutRunCached(const uint16_t* buf, size_t runStart, size_t runLength,
118         size_t bufSize, bool isRtl, LayoutContext* ctx, size_t dstStart,
119         const std::shared_ptr<FontCollection>& collection, Layout* layout, float* advances);
120 
121     // Lay out a single word
122     static float doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
123         bool isRtl, LayoutContext* ctx, size_t bufStart,
124         const std::shared_ptr<FontCollection>& collection, Layout* layout, float* advances);
125 
126     // Lay out a single bidi run
127     void doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
128         bool isRtl, LayoutContext* ctx, const std::shared_ptr<FontCollection>& collection);
129 
130     // Append another layout (for example, cached value) into this one
131     void appendLayout(Layout* src, size_t start, float extraAdvance);
132 
133     std::vector<LayoutGlyph> mGlyphs;
134     std::vector<float> mAdvances;
135 
136     std::vector<FakedFont> mFaces;
137     float mAdvance;
138     MinikinRect mBounds;
139 };
140 
141 }  // namespace minikin
142 
143 #endif  // MINIKIN_LAYOUT_H
144