• 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   // libtxt extension: record the cluster (character index) that corresponds
42   // to this glyph
43   uint32_t cluster;
44 };
45 
46 // Internal state used during layout operation
47 struct LayoutContext;
48 
49 enum {
50   kBidi_LTR = 0,
51   kBidi_RTL = 1,
52   kBidi_Default_LTR = 2,
53   kBidi_Default_RTL = 3,
54   kBidi_Force_LTR = 4,
55   kBidi_Force_RTL = 5,
56 
57   kBidi_Mask = 0x7
58 };
59 
60 // Lifecycle and threading assumptions for Layout:
61 // The object is assumed to be owned by a single thread; multiple threads
62 // may not mutate it at the same time.
63 class Layout {
64  public:
Layout()65   Layout() : mGlyphs(), mAdvances(), mFaces(), mAdvance(0), mBounds() {
66     mBounds.setEmpty();
67   }
68 
69   Layout(Layout&& layout) = default;
70 
71   // Forbid copying and assignment.
72   Layout(const Layout&) = delete;
73   void operator=(const Layout&) = delete;
74 
75   void dump() const;
76 
77   void doLayout(const uint16_t* buf,
78                 size_t start,
79                 size_t count,
80                 size_t bufSize,
81                 bool isRtl,
82                 const FontStyle& style,
83                 const MinikinPaint& paint,
84                 const std::shared_ptr<FontCollection>& collection);
85 
86   static float measureText(const uint16_t* buf,
87                            size_t start,
88                            size_t count,
89                            size_t bufSize,
90                            bool isRtl,
91                            const FontStyle& style,
92                            const MinikinPaint& paint,
93                            const std::shared_ptr<FontCollection>& collection,
94                            float* advances);
95 
96   // public accessors
97   size_t nGlyphs() const;
98   const MinikinFont* getFont(int i) const;
99   FontFakery getFakery(int i) const;
100   unsigned int getGlyphId(int i) const;
101   uint32_t getGlyphCluster(int i) const;  // libtxt extension
102   float getX(int i) const;
103   float getY(int i) const;
104 
105   float getAdvance() const;
106 
107   // Get advances, copying into caller-provided buffer. The size of this
108   // buffer must match the length of the string (count arg to doLayout).
109   void getAdvances(float* advances);
110 
111   // The i parameter is an offset within the buf relative to start, it is <
112   // count, where start and count are the parameters to doLayout
getCharAdvance(size_t i)113   float getCharAdvance(size_t i) const { return mAdvances[i]; }
114 
115   void getBounds(MinikinRect* rect) const;
116 
117   // Purge all caches, useful in low memory conditions
118   static void purgeCaches();
119 
120  private:
121   friend class LayoutCacheKey;
122 
123   // Find a face in the mFaces vector, or create a new entry
124   int findFace(const FakedFont& face, LayoutContext* ctx);
125 
126   // Clears layout, ready to be used again
127   void reset();
128 
129   // Lay out a single bidi run
130   // When layout is not null, layout info will be stored in the object.
131   // When advances is not null, measurement results will be stored in the array.
132   static float doLayoutRunCached(
133       const uint16_t* buf,
134       size_t runStart,
135       size_t runLength,
136       size_t bufSize,
137       bool isRtl,
138       LayoutContext* ctx,
139       size_t dstStart,
140       const std::shared_ptr<FontCollection>& collection,
141       Layout* layout,
142       float* advances);
143 
144   // Lay out a single word
145   static float doLayoutWord(const uint16_t* buf,
146                             size_t start,
147                             size_t count,
148                             size_t bufSize,
149                             bool isRtl,
150                             LayoutContext* ctx,
151                             size_t bufStart,
152                             const std::shared_ptr<FontCollection>& collection,
153                             Layout* layout,
154                             float* advances);
155 
156   // Lay out a single bidi run
157   void doLayoutRun(const uint16_t* buf,
158                    size_t start,
159                    size_t count,
160                    size_t bufSize,
161                    bool isRtl,
162                    LayoutContext* ctx,
163                    const std::shared_ptr<FontCollection>& collection);
164 
165   // Append another layout (for example, cached value) into this one
166   void appendLayout(Layout* src, size_t start, float extraAdvance);
167 
168   std::vector<LayoutGlyph> mGlyphs;
169   std::vector<float> mAdvances;
170 
171   std::vector<FakedFont> mFaces;
172   float mAdvance;
173   MinikinRect mBounds;
174 };
175 
176 }  // namespace minikin
177 
178 #endif  // MINIKIN_LAYOUT_H
179