mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Let's use shared_ptr since manual ref counting can be a bug-prone and using the global mutex inside destructor is not useful for some time. To remove raw pointer manipulation, needed to change Layout constructors. Layout is no longer copyable and need to pass FontCollection to constructor. Bug: 28119474 Test: minikin_tests passed Test: hwui_unit_tests passed Test: No performance regression in minikin_perftest. Change-Id: I8824593206ecba74cbc9731e298f045e1ae442a3
163 lines
5.2 KiB
C++
163 lines
5.2 KiB
C++
/*
|
|
* Copyright (C) 2013 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef MINIKIN_LAYOUT_H
|
|
#define MINIKIN_LAYOUT_H
|
|
|
|
#include <hb.h>
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include <minikin/FontCollection.h>
|
|
#include <minikin/MinikinFontFreeType.h>
|
|
|
|
namespace minikin {
|
|
|
|
// The Bitmap class is for debugging. We'll probably move it out
|
|
// of here into a separate lightweight software rendering module
|
|
// (optional, as we'd hope most clients would do their own)
|
|
class Bitmap {
|
|
public:
|
|
Bitmap(int width, int height);
|
|
~Bitmap();
|
|
void writePnm(std::ofstream& o) const;
|
|
void drawGlyph(const GlyphBitmap& bitmap, int x, int y);
|
|
private:
|
|
int width;
|
|
int height;
|
|
uint8_t* buf;
|
|
};
|
|
|
|
struct LayoutGlyph {
|
|
// index into mFaces and mHbFonts vectors. We could imagine
|
|
// moving this into a run length representation, because it's
|
|
// more efficient for long strings, and we'll probably need
|
|
// something like that for paint attributes (color, underline,
|
|
// fake b/i, etc), as having those per-glyph is bloated.
|
|
int font_ix;
|
|
|
|
unsigned int glyph_id;
|
|
float x;
|
|
float y;
|
|
};
|
|
|
|
// Internal state used during layout operation
|
|
struct LayoutContext;
|
|
|
|
enum {
|
|
kBidi_LTR = 0,
|
|
kBidi_RTL = 1,
|
|
kBidi_Default_LTR = 2,
|
|
kBidi_Default_RTL = 3,
|
|
kBidi_Force_LTR = 4,
|
|
kBidi_Force_RTL = 5,
|
|
|
|
kBidi_Mask = 0x7
|
|
};
|
|
|
|
// Lifecycle and threading assumptions for Layout:
|
|
// The object is assumed to be owned by a single thread; multiple threads
|
|
// may not mutate it at the same time.
|
|
class Layout {
|
|
public:
|
|
|
|
Layout(const std::shared_ptr<FontCollection>& collection)
|
|
: mGlyphs(), mAdvances(), mCollection(collection), mFaces(), mAdvance(0), mBounds() {
|
|
mBounds.setEmpty();
|
|
}
|
|
|
|
Layout(Layout&& layout) = default;
|
|
|
|
// Forbid copying and assignment.
|
|
Layout(const Layout&) = delete;
|
|
void operator=(const Layout&) = delete;
|
|
|
|
void dump() const;
|
|
|
|
void doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
|
int bidiFlags, const FontStyle &style, const MinikinPaint &paint);
|
|
|
|
static float measureText(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
|
int bidiFlags, const FontStyle &style, const MinikinPaint &paint,
|
|
const std::shared_ptr<FontCollection>& collection, float* advances);
|
|
|
|
void draw(minikin::Bitmap*, int x0, int y0, float size) const;
|
|
|
|
// public accessors
|
|
size_t nGlyphs() const;
|
|
const MinikinFont* getFont(int i) const;
|
|
FontFakery getFakery(int i) const;
|
|
unsigned int getGlyphId(int i) const;
|
|
float getX(int i) const;
|
|
float getY(int i) const;
|
|
|
|
float getAdvance() const;
|
|
|
|
// Get advances, copying into caller-provided buffer. The size of this
|
|
// buffer must match the length of the string (count arg to doLayout).
|
|
void getAdvances(float* advances);
|
|
|
|
// The i parameter is an offset within the buf relative to start, it is < count, where
|
|
// start and count are the parameters to doLayout
|
|
float getCharAdvance(size_t i) const { return mAdvances[i]; }
|
|
|
|
void getBounds(MinikinRect* rect) const;
|
|
|
|
// Purge all caches, useful in low memory conditions
|
|
static void purgeCaches();
|
|
|
|
private:
|
|
friend class LayoutCacheKey;
|
|
|
|
// Find a face in the mFaces vector, or create a new entry
|
|
int findFace(const FakedFont& face, LayoutContext* ctx);
|
|
|
|
// Clears layout, ready to be used again
|
|
void reset();
|
|
|
|
// Lay out a single bidi run
|
|
// When layout is not null, layout info will be stored in the object.
|
|
// When advances is not null, measurement results will be stored in the array.
|
|
static float doLayoutRunCached(const uint16_t* buf, size_t runStart, size_t runLength,
|
|
size_t bufSize, bool isRtl, LayoutContext* ctx, size_t dstStart,
|
|
const std::shared_ptr<FontCollection>& collection, Layout* layout, float* advances);
|
|
|
|
// Lay out a single word
|
|
static float doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
|
bool isRtl, LayoutContext* ctx, size_t bufStart,
|
|
const std::shared_ptr<FontCollection>& collection, Layout* layout, float* advances);
|
|
|
|
// Lay out a single bidi run
|
|
void doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
|
bool isRtl, LayoutContext* ctx);
|
|
|
|
// Append another layout (for example, cached value) into this one
|
|
void appendLayout(Layout* src, size_t start, float extraAdvance);
|
|
|
|
std::vector<LayoutGlyph> mGlyphs;
|
|
std::vector<float> mAdvances;
|
|
|
|
std::shared_ptr<FontCollection> mCollection;
|
|
std::vector<FakedFont> mFaces;
|
|
float mAdvance;
|
|
MinikinRect mBounds;
|
|
};
|
|
|
|
} // namespace minikin
|
|
|
|
#endif // MINIKIN_LAYOUT_H
|