Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2014 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #ifndef SkTextBlob_DEFINED | |
| 9 #define SkTextBlob_DEFINED | |
| 10 | |
| 11 #include "SkPaint.h" | |
| 12 #include "SkRefCnt.h" | |
| 13 #include "SkTArray.h" | |
| 14 #include "SkTDArray.h" | |
| 15 | |
| 16 /** \class SkTextBlob | |
| 17 | |
| 18 SkTextBlob combines multiple text runs into an immutable, ref-counted struct ure. | |
| 19 */ | |
| 20 class SkTextBlob : public SkRefCnt { | |
| 21 public: | |
| 22 virtual ~SkTextBlob(); | |
| 23 | |
| 24 /** Specifies the glyph positioning mode. | |
| 25 */ | |
| 26 enum Positioning { | |
| 27 kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph. | |
| 28 kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar p er glyph. | |
| 29 kFull_Positioning = 2 // Point positioning -- two scalars per g lyph. | |
| 30 }; | |
| 31 | |
| 32 /** \struct RunInfo | |
| 33 | |
| 34 A run is a sequence of (optionally positioned) glyphs sharing the same f ont metrics | |
| 35 and positioning mode. | |
| 36 */ | |
| 37 struct RunInfo { | |
| 38 uint32_t glyphCount; | |
| 39 Positioning positioning; | |
| 40 const uint16_t* glyphs; | |
| 41 const SkScalar* pos; | |
| 42 const SkPaint* font; | |
|
jbroman
2014/08/19 17:39:16
nit: Why not "const SkPaint&"? Is this a sign that
f(malita)
2014/08/20 01:21:57
Good point -- done.
| |
| 43 | |
| 44 RunInfo(uint32_t c, Positioning m, const uint16_t* g, const SkScalar* p, const SkPaint *f) | |
| 45 : glyphCount(c), positioning(m), glyphs(g), pos(p), font(f) { } | |
| 46 }; | |
| 47 | |
| 48 /** | |
| 49 * Returns the blob bounding box. | |
| 50 */ | |
| 51 const SkRect& bounds() const { return fBounds; } | |
| 52 | |
| 53 /** | |
| 54 * Return a non-zero, unique value representing the text blob. | |
| 55 */ | |
| 56 uint32_t uniqueID() const; | |
| 57 | |
| 58 /** | |
| 59 * Returns the number of runs in this blob. | |
| 60 */ | |
| 61 unsigned runs() const { return fRuns ? fRuns->count() : 0; } | |
| 62 | |
| 63 /** | |
| 64 * Returns a RunInfo struct for the given run index. | |
| 65 */ | |
| 66 const RunInfo runInfo(unsigned runIndex) const; | |
|
jbroman
2014/08/19 17:39:16
Returning a const struct is meaningless (it's the
f(malita)
2014/08/20 01:21:57
Removed from the API.
| |
| 67 | |
| 68 private: | |
|
robertphillips
2014/08/19 15:06:47
// This is ... ?
f(malita)
2014/08/20 01:21:57
Done.
| |
| 69 struct Run { | |
| 70 uint32_t count; | |
| 71 uint32_t glyphStart; // index into fGlyphBuffer | |
| 72 uint32_t posStart; // index into fPosBuffer | |
| 73 SkPaint font; | |
| 74 Positioning positioning; | |
| 75 }; | |
| 76 | |
| 77 SkTextBlob(const uint16_t* glyphs, const SkScalar* pos, const SkTArray<Run>* runs, | |
| 78 const SkRect& bounds); | |
| 79 friend class SkTextBlobBuilder; | |
| 80 | |
| 81 const uint16_t* fGlyphBuffer; | |
|
jbroman
2014/08/19 17:39:16
Any reason not to use SkAutoTMalloc or something s
f(malita)
2014/08/20 01:21:57
Done.
| |
| 82 const SkScalar* fPosBuffer; | |
| 83 const SkTArray<Run>* fRuns; | |
| 84 const SkRect fBounds; | |
| 85 | |
| 86 mutable uint32_t fUniqueID; | |
|
jbroman
2014/08/19 17:39:16
Why "mutable"? Making this lazy kind of scares me
f(malita)
2014/08/20 01:21:58
(this is the same pattern used by other Skia ID-ed
| |
| 87 }; | |
| 88 | |
| 89 /** \class SkTextBlobBuilder | |
| 90 | |
| 91 Helper class for constructing SkTextBlobs. | |
|
robertphillips
2014/08/19 15:06:47
// Expected use is:
// SkTextBlobBuilder tbb;
| |
| 92 */ | |
| 93 class SkTextBlobBuilder { | |
| 94 private: | |
|
robertphillips
2014/08/19 15:06:47
// This class ...
specifically what sort of API i
f(malita)
2014/08/20 01:21:57
Removed.
| |
| 95 class RunBuilderBase { | |
| 96 public: | |
| 97 RunBuilderBase(SkTextBlobBuilder* blobBuilder) : fBlobBuilder(blobBuilde r) { } | |
| 98 | |
| 99 protected: | |
| 100 SkTextBlobBuilder* fBlobBuilder; | |
| 101 }; | |
| 102 | |
| 103 public: | |
| 104 /** | |
| 105 * @param runs The number of runs to be added, if known. This is a storage hint and | |
| 106 * not a limit. | |
| 107 */ | |
| 108 SkTextBlobBuilder(unsigned runs = 0); | |
| 109 | |
| 110 ~SkTextBlobBuilder(); | |
| 111 | |
| 112 template <SkTextBlob::Positioning> | |
| 113 class RunBuilder : public RunBuilderBase { }; | |
| 114 | |
| 115 /** | |
| 116 * Start a text run for the given font and positioning mode. | |
| 117 * | |
| 118 * @param glyphCount The number of glyphs in this run, if known. This is a storage hint | |
| 119 * and not a limit. | |
| 120 * @param bounds The bounding box for this run, if known. If non-null, it will be used | |
| 121 * in the blob bounding box computation -- otherwise the builder will | |
| 122 * measure the run. | |
| 123 * @return A specialized builder for this run. The run builder is only valid | |
| 124 * until the next startRun() or build() call. | |
| 125 */ | |
| 126 template <SkTextBlob::Positioning POS> | |
| 127 RunBuilder<POS> startRun(const SkPaint& font, unsigned glyphCount = 0, | |
|
jbroman
2014/08/19 17:39:15
What do we get by making this a two-step process (
jbroman
2014/08/19 17:39:16
Why document the glyphCount and bounds arguments,
f(malita)
2014/08/20 01:21:57
Done.
f(malita)
2014/08/20 01:21:57
The latter forces clients to format data in a Skia
| |
| 128 const SkRect* bounds = NULL) { | |
|
robertphillips
2014/08/19 15:06:47
this->
f(malita)
2014/08/20 01:21:57
Done.
| |
| 129 ensureRun(font, POS, glyphCount, bounds); | |
| 130 return RunBuilder<POS>(this); | |
| 131 } | |
| 132 | |
| 133 /** | |
| 134 * Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and | |
| 135 * can be reused. | |
| 136 */ | |
| 137 const SkTextBlob* build(); | |
| 138 | |
| 139 private: | |
| 140 void ensureRun(const SkPaint& font, SkTextBlob::Positioning positioning, uns igned count, | |
| 141 const SkRect* runBounds); | |
| 142 void updateRunBounds(); | |
| 143 | |
| 144 SkTDArray<uint16_t> fGlyphBuffer; | |
| 145 SkTDArray<SkScalar> fPosBuffer; | |
| 146 SkTArray<SkTextBlob::Run>* fRuns; | |
| 147 | |
| 148 SkRect fBounds; | |
| 149 bool fDeferredRunBounds; | |
| 150 }; | |
| 151 | |
| 152 template<> | |
| 153 class SkTextBlobBuilder::RunBuilder<SkTextBlob::kDefault_Positioning> : public R unBuilderBase { | |
| 154 public: | |
| 155 RunBuilder(SkTextBlobBuilder* blobBuilder) : RunBuilderBase(blobBuilder) { } | |
| 156 | |
| 157 void addGlyph(uint16_t glyph); | |
| 158 void addGlyphs(const uint16_t glyphs[], size_t count); | |
| 159 }; | |
| 160 | |
|
robertphillips
2014/08/19 15:06:47
// The Y-value will be supplied in the using SkCan
| |
| 161 template<> | |
| 162 class SkTextBlobBuilder::RunBuilder<SkTextBlob::kHorizontal_Positioning> : publi c RunBuilderBase { | |
| 163 public: | |
| 164 RunBuilder(SkTextBlobBuilder* blobBuilder) : RunBuilderBase(blobBuilder) { } | |
| 165 | |
| 166 void addGlyph(uint16_t glyph, SkScalar x); | |
|
jbroman
2014/08/19 17:39:16
Would we ever want to add a singular glyph? If it'
| |
| 167 void addGlyphs(const uint16_t glyphs[], const SkScalar xPos[], size_t count) ; | |
| 168 }; | |
| 169 | |
|
robertphillips
2014/08/19 15:06:47
// All the supplied positions are relative to the
| |
| 170 template<> | |
| 171 class SkTextBlobBuilder::RunBuilder<SkTextBlob::kFull_Positioning> : public RunB uilderBase { | |
| 172 public: | |
| 173 RunBuilder(SkTextBlobBuilder* blobBuilder) : RunBuilderBase(blobBuilder) { } | |
| 174 | |
| 175 void addGlyph(uint16_t glyph, SkScalar x, SkScalar y); | |
|
robertphillips
2014/08/19 15:06:48
const SkPoint&
| |
| 176 void addGlyph(uint16_t glyph, SkPoint pos); | |
| 177 void addGlyphs(const uint16_t glyphs[], const SkScalar xPos[], const SkScala r yPos[], | |
| 178 size_t count); | |
|
robertphillips
2014/08/19 15:06:47
pox ?
| |
| 179 void addGlyphs(const uint16_t glyphs[], const SkPoint pox[], size_t count); | |
|
jbroman
2014/08/19 17:39:16
What does this method do, given this is the "full
| |
| 180 }; | |
| 181 | |
| 182 #endif // SkTextBlob_DEFINED | |
| OLD | NEW |