| /* | |
| * Copyright 2014 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef SkTextBlob_DEFINED | |
| #define SkTextBlob_DEFINED | |
| #include "SkPaint.h" | |
| #include "SkRefCnt.h" | |
| #include "SkTArray.h" | |
| #include "SkTDArray.h" | |
| class SkReadBuffer; | |
| class SkWriteBuffer; | |
| /** \class SkTextBlob | |
| SkTextBlob combines multiple text runs into an immutable, ref-counted structure. | |
| */ | |
| class SK_API SkTextBlob : public SkRefCnt { | |
| public: | |
| /** | |
| * Returns a conservative blob bounding box. | |
| */ | |
| const SkRect& bounds() const { return fBounds; } | |
| /** | |
| * Return a non-zero, unique value representing the text blob. | |
| */ | |
| uint32_t uniqueID() const { return fUniqueID; } | |
| /** | |
| * Serialize to a buffer. | |
| */ | |
| void flatten(SkWriteBuffer&) const; | |
| /** | |
| * Recreate an SkTextBlob that was serialized into a buffer. | |
| * | |
| * @param SkReadBuffer Serialized blob data. | |
| * @return A new SkTextBlob representing the serialized data, or NULL if the buffer is | |
| * invalid. | |
| */ | |
| static const SkTextBlob* CreateFromBuffer(SkReadBuffer&); | |
| enum GlyphPositioning { | |
| kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph. | |
| kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph. | |
| kFull_Positioning = 2 // Point positioning -- two scalars per glyph. | |
| }; | |
| private: | |
| class RunRecord; | |
| SkTextBlob(int runCount, const SkRect& bounds); | |
| virtual ~SkTextBlob(); | |
| // Memory for objects of this class is created with sk_malloc rather than operator new and must | |
| // be freed with sk_free. | |
| void operator delete(void* p) { sk_free(p); } | |
| void* operator new(size_t) { | |
| SkFAIL("All blobs are created by placement new."); | |
| return sk_malloc_throw(0); | |
| } | |
| void* operator new(size_t, void* p) { return p; } | |
| static unsigned ScalarsPerGlyph(GlyphPositioning pos); | |
| friend class SkTextBlobBuilder; | |
| friend class SkTextBlobRunIterator; | |
| const int fRunCount; | |
| const SkRect fBounds; | |
| const uint32_t fUniqueID; | |
| SkDEBUGCODE(size_t fStorageSize;) | |
| // The actual payload resides in externally-managed storage, following the object. | |
| // (see the .cpp for more details) | |
| typedef SkRefCnt INHERITED; | |
| }; | |
| /** \class SkTextBlobBuilder | |
| Helper class for constructing SkTextBlobs. | |
| */ | |
| class SK_API SkTextBlobBuilder { | |
| public: | |
| SkTextBlobBuilder(); | |
| ~SkTextBlobBuilder(); | |
| /** | |
| * Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and | |
| * can be reused. | |
| */ | |
| const SkTextBlob* build(); | |
| /** | |
| * Glyph and position buffers associated with a run. | |
| * | |
| * A run is a sequence of glyphs sharing the same font metrics and positioning mode. | |
| */ | |
| struct RunBuffer { | |
| uint16_t* glyphs; | |
| SkScalar* pos; | |
| }; | |
| /** | |
| * Allocates a new default-positioned run and returns its writable glyph buffer | |
| * for direct manipulation. | |
| * | |
| * @param font The font to be used for this run. | |
| * @param count Number of glyphs. | |
| * @param x,y Position within the blob. | |
| * @param bounds Optional run bounding box. If known in advance (!= NULL), it will | |
| * be used when computing the blob bounds, to avoid re-measuring. | |
| * | |
| * @return A writable glyph buffer, valid until the next allocRun() or | |
| * build() call. The buffer is guaranteed to hold @count@ glyphs. | |
| */ | |
| const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y, | |
| const SkRect* bounds = NULL); | |
| /** | |
| * Allocates a new horizontally-positioned run and returns its writable glyph and position | |
| * buffers for direct manipulation. | |
| * | |
| * @param font The font to be used for this run. | |
| * @param count Number of glyphs. | |
| * @param y Vertical offset within the blob. | |
| * @param bounds Optional run bounding box. If known in advance (!= NULL), it will | |
| * be used when computing the blob bounds, to avoid re-measuring. | |
| * | |
| * @return Writable glyph and position buffers, valid until the next allocRun() | |
| * or build() call. The buffers are guaranteed to hold @count@ elements. | |
| */ | |
| const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y, | |
| const SkRect* bounds = NULL); | |
| /** | |
| * Allocates a new fully-positioned run and returns its writable glyph and position | |
| * buffers for direct manipulation. | |
| * | |
| * @param font The font to be used for this run. | |
| * @param count Number of glyphs. | |
| * @param bounds Optional run bounding box. If known in advance (!= NULL), it will | |
| * be used when computing the blob bounds, to avoid re-measuring. | |
| * | |
| * @return Writable glyph and position buffers, valid until the next allocRun() | |
| * or build() call. The glyph buffer and position buffer are | |
| * guaranteed to hold @count@ and 2 * @count@ elements, respectively. | |
| */ | |
| const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL); | |
| private: | |
| void reserve(size_t size); | |
| void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning, | |
| int count, SkPoint offset, const SkRect* bounds); | |
| bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning, | |
| int count, SkPoint offset); | |
| void updateDeferredBounds(); | |
| static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&); | |
| static SkRect TightRunBounds(const SkTextBlob::RunRecord&); | |
| SkAutoTMalloc<uint8_t> fStorage; | |
| size_t fStorageSize; | |
| size_t fStorageUsed; | |
| SkRect fBounds; | |
| int fRunCount; | |
| bool fDeferredBounds; | |
| size_t fLastRun; // index into fStorage | |
| RunBuffer fCurrentRunBuffer; | |
| }; | |
| #endif // SkTextBlob_DEFINED |