Home | History | Annotate | Download | only in minikin
      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 <vector>
     23 
     24 #include <minikin/FontCollection.h>
     25 #include <minikin/MinikinFontFreeType.h>
     26 
     27 namespace minikin {
     28 
     29 // The Bitmap class is for debugging. We'll probably move it out
     30 // of here into a separate lightweight software rendering module
     31 // (optional, as we'd hope most clients would do their own)
     32 class Bitmap {
     33 public:
     34     Bitmap(int width, int height);
     35     ~Bitmap();
     36     void writePnm(std::ofstream& o) const;
     37     void drawGlyph(const android::GlyphBitmap& bitmap, int x, int y);
     38 private:
     39     int width;
     40     int height;
     41     uint8_t* buf;
     42 };
     43 
     44 } // namespace minikin
     45 
     46 namespace android {
     47 
     48 struct LayoutGlyph {
     49     // index into mFaces and mHbFonts vectors. We could imagine
     50     // moving this into a run length representation, because it's
     51     // more efficient for long strings, and we'll probably need
     52     // something like that for paint attributes (color, underline,
     53     // fake b/i, etc), as having those per-glyph is bloated.
     54     int font_ix;
     55 
     56     unsigned int glyph_id;
     57     float x;
     58     float y;
     59 };
     60 
     61 // Internal state used during layout operation
     62 struct LayoutContext;
     63 
     64 enum {
     65     kBidi_LTR = 0,
     66     kBidi_RTL = 1,
     67     kBidi_Default_LTR = 2,
     68     kBidi_Default_RTL = 3,
     69     kBidi_Force_LTR = 4,
     70     kBidi_Force_RTL = 5,
     71 
     72     kBidi_Mask = 0x7
     73 };
     74 
     75 // Lifecycle and threading assumptions for Layout:
     76 // The object is assumed to be owned by a single thread; multiple threads
     77 // may not mutate it at the same time.
     78 // The lifetime of the FontCollection set through setFontCollection must
     79 // extend through the lifetime of the Layout object.
     80 class Layout {
     81 public:
     82 
     83     Layout() : mGlyphs(), mAdvances(), mCollection(0), mFaces(), mAdvance(0), mBounds() {
     84         mBounds.setEmpty();
     85     }
     86 
     87     // Clears layout, ready to be used again
     88     void reset();
     89 
     90     void dump() const;
     91     void setFontCollection(const FontCollection* collection);
     92 
     93     void doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
     94         int bidiFlags, const FontStyle &style, const MinikinPaint &paint);
     95 
     96     static float measureText(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
     97         int bidiFlags, const FontStyle &style, const MinikinPaint &paint,
     98         const FontCollection* collection, float* advances);
     99 
    100     void draw(minikin::Bitmap*, int x0, int y0, float size) const;
    101 
    102     // Deprecated. Nont needed. Remove when callers are removed.
    103     static void init();
    104 
    105     // public accessors
    106     size_t nGlyphs() const;
    107     // Does not bump reference; ownership is still layout
    108     MinikinFont *getFont(int i) const;
    109     FontFakery getFakery(int i) const;
    110     unsigned int getGlyphId(int i) const;
    111     float getX(int i) const;
    112     float getY(int i) const;
    113 
    114     float getAdvance() const;
    115 
    116     // Get advances, copying into caller-provided buffer. The size of this
    117     // buffer must match the length of the string (count arg to doLayout).
    118     void getAdvances(float* advances);
    119 
    120     // The i parameter is an offset within the buf relative to start, it is < count, where
    121     // start and count are the parameters to doLayout
    122     float getCharAdvance(size_t i) const { return mAdvances[i]; }
    123 
    124     void getBounds(MinikinRect* rect);
    125 
    126     // Purge all caches, useful in low memory conditions
    127     static void purgeCaches();
    128 
    129 private:
    130     friend class LayoutCacheKey;
    131 
    132     // Find a face in the mFaces vector, or create a new entry
    133     int findFace(FakedFont face, LayoutContext* ctx);
    134 
    135     // Lay out a single bidi run
    136     // When layout is not null, layout info will be stored in the object.
    137     // When advances is not null, measurement results will be stored in the array.
    138     static float doLayoutRunCached(const uint16_t* buf, size_t runStart, size_t runLength,
    139         size_t bufSize, bool isRtl, LayoutContext* ctx, size_t dstStart,
    140         const FontCollection* collection, Layout* layout, float* advances);
    141 
    142     // Lay out a single word
    143     static float doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
    144         bool isRtl, LayoutContext* ctx, size_t bufStart, const FontCollection* collection,
    145         Layout* layout, float* advances);
    146 
    147     // Lay out a single bidi run
    148     void doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
    149         bool isRtl, LayoutContext* ctx);
    150 
    151     // Append another layout (for example, cached value) into this one
    152     void appendLayout(Layout* src, size_t start);
    153 
    154     std::vector<LayoutGlyph> mGlyphs;
    155     std::vector<float> mAdvances;
    156 
    157     const FontCollection* mCollection;
    158     std::vector<FakedFont> mFaces;
    159     float mAdvance;
    160     MinikinRect mBounds;
    161 };
    162 
    163 }  // namespace android
    164 
    165 #endif  // MINIKIN_LAYOUT_H
    166