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