Chromium Code Reviews| Index: include/core/SkTextBlob.h |
| diff --git a/include/core/SkTextBlob.h b/include/core/SkTextBlob.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4b490ff69fe0ec72a2442dc5c99ba801cb6513db |
| --- /dev/null |
| +++ b/include/core/SkTextBlob.h |
| @@ -0,0 +1,123 @@ |
| +/* |
| + * 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 "SkRect.h" |
| +#include "SkRefCnt.h" |
| +#include "SkTDArray.h" |
| + |
| +class SkBaseDevice; |
| +class SkDraw; |
| +struct SkPoint; |
| + |
| +/** \class SkTextChunk |
| + |
| + A text chunk is a sequence of (optionally positioned glyphs) sharing the same |
| + font data/metrics. |
| +*/ |
| +class SK_API SkTextChunk { |
| +public: |
| + static const SkTextChunk* Create(const uint16_t* glyphs, size_t count, const SkPaint& paint, |
| + const SkRect* bounds = NULL); |
| + static const SkTextChunk* Create(const uint16_t* glyphs, size_t count, const SkScalar* pos, |
|
mtklein
2014/08/14 14:00:42
Doesn't this need another SkScalar for the shared
f(malita)
2014/08/14 14:29:26
I'm hoping most blobs will be relocatable (at leas
|
| + const SkPaint& paint, const SkRect* bounds = NULL); |
| + static const SkTextChunk* Create(const uint16_t* glyphs, size_t count, const SkPoint* pos, |
| + const SkPaint& paint, const SkRect* bounds = NULL); |
| + |
| + ~SkTextChunk(); |
| + |
| + void draw(SkBaseDevice*, const SkDraw&, const SkPaint&) const; |
| + |
| + const SkRect& bounds() const; |
| + |
| +private: |
| + SkTextChunk(const uint16_t* glyphs, size_t count, const SkPaint& paint, const SkRect* bounds); |
| + SkTextChunk(const uint16_t* glyphs, size_t count, const SkScalar* pos, const SkPaint& paint, |
| + const SkRect* bounds); |
| + SkTextChunk(const uint16_t* glyphs, size_t count, const SkPoint* pos, const SkPaint& paint, |
| + const SkRect* bounds); |
| + |
| + void init(const uint16_t*, size_t, const SkRect*, const SkScalar*); |
| + |
| + friend class SkPictureRecord; |
| + |
| + size_t fGlyphCount; |
| + uint16_t* fGlyphs; |
| + SkScalar* fPos; // FIXME: merge glyphs/pos storage? |
| + |
| + SkPaint fFont; // FIXME: SkFont |
| + |
| + mutable SkRect fBounds; |
|
mtklein
2014/08/14 14:00:42
We create TextChunks all at once right? If so, le
f(malita)
2014/08/14 14:29:26
It's not completely clear whether we *always* need
mtklein
2014/08/14 14:38:45
I'm going to try have pictures start querying the
f(malita)
2014/08/14 16:13:36
Awesome, that settles it :)
I think it also makes
|
| + mutable bool fBoundsDirty : 1; |
|
mtklein
2014/08/14 14:00:42
I'd drop the bit packing for now? It's particular
f(malita)
2014/08/14 14:29:26
Done.
|
| + |
| + unsigned fScalarsPerPos : 2; |
| +}; |
| + |
| +/** \class SkTextBlob |
| + |
| + SkTextBlob combines multiple text chunks into an immutable, ref-counted structure. |
| +*/ |
| +class SK_API SkTextBlob : public SkRefCnt { |
| +public: |
| + static const SkTextBlob* Create(const SkTextChunk* chunk); |
| + static const SkTextBlob* Create(const SkTDArray<const SkTextChunk*>& chunks); |
| + |
| + ~SkTextBlob(); |
| + |
| + uint32_t uniqueID() const; |
| + |
| + class SK_API Iter { |
| + public: |
| + Iter(const SkTextBlob* blob) : fBlob(blob), fIndex(0) { SkASSERT(blob); } |
| + const SkTextChunk* next() { |
| + return (fIndex < fBlob->fChunks.count()) ? fBlob->fChunks[fIndex++] : NULL; |
| + } |
| + |
| + private: |
| + const SkTextBlob* fBlob; |
| + int fIndex; |
| + }; |
| + |
| +private: |
| + SkTextBlob(const SkTDArray<const SkTextChunk*>& chunks); |
| + |
| + const SkTDArray<const SkTextChunk*> fChunks; |
| + mutable uint32_t fUniqueID; |
| +}; |
| + |
| +/** \class SkTextBlobBuilder |
| + |
| + Helper class for constructing SkTextBlobs. |
| +*/ |
| +class SK_API SkTextBlobBuilder { |
| +public: |
| + SkTextBlobBuilder(); |
| + ~SkTextBlobBuilder(); |
| + |
| + void addChunk(const SkTextChunk* chunk); |
| + |
| + // FIXME: should we support glyph-wise ops? Not sure whether this is interesting |
| + // for clients at this point -- they likely have a better idea of chunking. |
| + /* |
| + void addGlyph(uint16_t glyph, const SkPaint& font, const SkRect* bounds = NULL); |
| + void addGlyph(uint16_t glyph, const SkScalar pos, const SkPaint& font, |
| + const SkRect* bounds = NULL); |
| + void addGlyph(uint16_t glyph, const SkPoint pos, const SkPaint& font, |
| + const SkRect* bounds = NULL); |
| + */ |
| + |
| + const SkTextBlob* build(); |
|
jbroman
2014/08/14 14:46:02
nit: If SkTextBlobs are always immutable, why the
f(malita)
2014/08/14 16:13:36
In general, I would actually find that desirable:
mtklein
2014/08/14 16:22:23
I'm in (perhaps, am?) the the-more-const-the-bette
|
| + |
| +private: |
| + |
| + SkTDArray<const SkTextChunk*> fChunks; |
|
jbroman
2014/08/14 14:46:02
Random thought: pros/cons of having this approach
f(malita)
2014/08/14 16:13:36
The reason it turned out this way is trying to avo
|
| +}; |
| + |
| +#endif // SkTextBlob_DEFINED |