Seigo Nonaka dfbc6e3742 Remove MinikinRefCounted and use shared_ptr instead
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
2017-02-24 17:11:32 +09:00

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