Layout.h revision 22e41754f6470ff1f4c0e0a56d01f7f555b59e21
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/*
25778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Copyright (C) 2013 The Android Open Source Project
35778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
45778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
55778822d86b0337407514b9372562b86edfa91cdAndreas Huber * you may not use this file except in compliance with the License.
65778822d86b0337407514b9372562b86edfa91cdAndreas Huber * You may obtain a copy of the License at
75778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
85778822d86b0337407514b9372562b86edfa91cdAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
95778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
105778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Unless required by applicable law or agreed to in writing, software
115778822d86b0337407514b9372562b86edfa91cdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
125778822d86b0337407514b9372562b86edfa91cdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135778822d86b0337407514b9372562b86edfa91cdAndreas Huber * See the License for the specific language governing permissions and
145778822d86b0337407514b9372562b86edfa91cdAndreas Huber * limitations under the License.
155778822d86b0337407514b9372562b86edfa91cdAndreas Huber */
165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
175778822d86b0337407514b9372562b86edfa91cdAndreas Huber#ifndef MINIKIN_LAYOUT_H
185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define MINIKIN_LAYOUT_H
195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
205778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <hb.h>
215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
225778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <vector>
235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber#include <minikin/CssParse.h>
251608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber#include <minikin/FontCollection.h>
265778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <minikin/MinikinFontFreeType.h>
275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
285778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
305778822d86b0337407514b9372562b86edfa91cdAndreas Huber// The Bitmap class is for debugging. We'll probably move it out
31918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber// of here into a separate lightweight software rendering module
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber// (optional, as we'd hope most clients would do their own)
335778822d86b0337407514b9372562b86edfa91cdAndreas Huberclass Bitmap {
345778822d86b0337407514b9372562b86edfa91cdAndreas Huberpublic:
355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Bitmap(int width, int height);
365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ~Bitmap();
375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void writePnm(std::ofstream& o) const;
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void drawGlyph(const GlyphBitmap& bitmap, int x, int y);
395778822d86b0337407514b9372562b86edfa91cdAndreas Huberprivate:
405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int width;
415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int height;
42a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    uint8_t* buf;
43a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber};
44a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
45a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberstruct LayoutGlyph {
465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // index into mFaces and mHbFonts vectors. We could imagine
475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // moving this into a run length representation, because it's
485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // more efficient for long strings, and we'll probably need
495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // something like that for paint attributes (color, underline,
505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // fake b/i, etc), as having those per-glyph is bloated.
515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int font_ix;
525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    unsigned int glyph_id;
545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float x;
555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float y;
565778822d86b0337407514b9372562b86edfa91cdAndreas Huber};
575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
585778822d86b0337407514b9372562b86edfa91cdAndreas Huber// Internal state used during layout operation
595778822d86b0337407514b9372562b86edfa91cdAndreas Huberclass LayoutContext;
60918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
61918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber// Lifecycle and threading assumptions for Layout:
62dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber// The object is assumed to be owned by a single thread; multiple threads
63dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber// may not mutate it at the same time.
64918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber// The lifetime of the FontCollection set through setFontCollection must
65918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber// extend through the lifetime of the Layout object.
66918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huberclass Layout {
67918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huberpublic:
681608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    void dump() const;
691608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    void setFontCollection(const FontCollection* collection);
705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // deprecated - missing functionality
725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void doLayout(const uint16_t* buf, size_t nchars);
735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
75a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        const std::string& css);
761608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
771608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    void draw(Bitmap*, int x0, int y0, float size) const;
781608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
791608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    // deprecated - pass as argument to doLayout instead
801608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    void setProperties(const std::string& css);
811608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
821608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    // This must be called before any invocations.
831608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber	// TODO: probably have a factory instead
841608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    static void init();
851608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
861608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    // public accessors
871608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    size_t nGlyphs() const;
881608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    // Does not bump reference; ownership is still layout
891608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    MinikinFont *getFont(int i) const;
901608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    FontFakery getFakery(int i) const;
911608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    unsigned int getGlyphId(int i) const;
92a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    float getX(int i) const;
931608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    float getY(int i) const;
941608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
951608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    float getAdvance() const;
965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Get advances, copying into caller-provided buffer. The size of this
985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // buffer must match the length of the string (nchars arg to doLayout).
995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void getAdvances(float* advances);
1005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10194c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    void getBounds(MinikinRect* rect);
10294c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber
10394c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    // Purge all caches, useful in low memory conditions
10494c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    static void purgeCaches();
10594c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber
10694c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huberprivate:
10794c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    // Find a face in the mFaces vector, or create a new entry
10894c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    int findFace(FakedFont face, LayoutContext* ctx);
10994c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber
11094c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    // Lay out a single bidi run
11194c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    void doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
11294c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        bool isRtl, LayoutContext* ctx, size_t dstStart);
1133499e2d178960ca3392855716c963eec7403a089James Dong
1143499e2d178960ca3392855716c963eec7403a089James Dong    // Lay out a single word
1153499e2d178960ca3392855716c963eec7403a089James Dong    void doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
1163499e2d178960ca3392855716c963eec7403a089James Dong        bool isRtl, LayoutContext* ctx, size_t bufStart);
1173499e2d178960ca3392855716c963eec7403a089James Dong
1183499e2d178960ca3392855716c963eec7403a089James Dong    // Lay out a single bidi run
11994c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    void doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
12094c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        bool isRtl, LayoutContext* ctx);
121a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
122a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    // Append another layout (for example, cached value) into this one
123a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    void appendLayout(Layout* src, size_t start);
124a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
1255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // deprecated - remove when setProperties is removed
1265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    std::string mCssString;
1275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
128918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    std::vector<LayoutGlyph> mGlyphs;
129dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    std::vector<float> mAdvances;
130dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
131918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    const FontCollection* mCollection;
132918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    std::vector<FakedFont> mFaces;
133918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    float mAdvance;
134918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    MinikinRect mBounds;
135918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber};
136918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
137918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber}  // namespace android
138918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
139918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber#endif  // MINIKIN_LAYOUT_H
140918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber