Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: src/core/SkTextBlob.cpp

Issue 499413002: SkTextBlob plumbing (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkTextBlob.h" 8 #include "SkTextBlob.h"
9 9
10 #include "SkReadBuffer.h"
11 #include "SkWriteBuffer.h"
12
10 SkTextBlob::SkTextBlob(uint16_t *glyphs, SkScalar *pos, const SkTArray<Run> *run s, 13 SkTextBlob::SkTextBlob(uint16_t *glyphs, SkScalar *pos, const SkTArray<Run> *run s,
11 const SkRect& bounds) 14 const SkRect& bounds)
12 : fGlyphBuffer(glyphs) 15 : fGlyphBuffer(glyphs)
13 , fPosBuffer(pos) 16 , fPosBuffer(pos)
14 , fRuns(runs) 17 , fRuns(runs)
15 , fBounds(bounds) { 18 , fBounds(bounds) {
16 } 19 }
17 20
18 uint32_t SkTextBlob::uniqueID() const { 21 uint32_t SkTextBlob::uniqueID() const {
19 static int32_t gTextBlobGenerationID; // = 0; 22 static int32_t gTextBlobGenerationID; // = 0;
20 23
21 // loop in case our global wraps around, as we never want to return SK_Inval idGenID 24 // loop in case our global wraps around, as we never want to return SK_Inval idGenID
22 while (SK_InvalidGenID == fUniqueID) { 25 while (SK_InvalidGenID == fUniqueID) {
23 fUniqueID = sk_atomic_inc(&gTextBlobGenerationID) + 1; 26 fUniqueID = sk_atomic_inc(&gTextBlobGenerationID) + 1;
24 } 27 }
25 28
26 return fUniqueID; 29 return fUniqueID;
27 } 30 }
28 31
32 unsigned SkTextBlob::ScalarsPerGlyph(GlyphPositioning pos) {
33 // GlyphPositioning values are directly mapped to scalars-per-glyph.
34 SkASSERT(pos <= 2);
35 return pos;
36 }
37
38 void SkTextBlob::flatten(SkWriteBuffer& buffer) const {
39 int runCount = (NULL == fRuns.get()) ? 0 : fRuns->count();
40
41 buffer.write32(runCount);
42 buffer.writeRect(fBounds);
43
44 size_t glyphBufferCount = 0;
45 size_t posBufferCount = 0;
46
47 for (int i = 0; i < runCount; ++i) {
48 const Run& run = (*fRuns)[i];
49 SkASSERT(run.count > 0);
50
51 buffer.write32(run.count);
52 buffer.write32(run.glyphStart);
53 buffer.write32(run.posStart);
54 buffer.writePoint(run.offset);
55 buffer.writePaint(run.font);
56 buffer.write32(run.positioning);
57
58 glyphBufferCount += run.count;
59 posBufferCount += run.count * ScalarsPerGlyph(run.positioning);
60 }
61
62 buffer.writeByteArray(fGlyphBuffer, glyphBufferCount * sizeof(uint16_t));
63 buffer.writeByteArray(fPosBuffer, posBufferCount * sizeof(SkScalar));
64 }
65
66 const SkTextBlob* SkTextBlob::CreateFromBuffer(SkReadBuffer& buffer) {
67 int runCount = buffer.read32();
68 if (runCount <= 0) {
69 return NULL;
70 }
71
72 SkRect bounds;
73 buffer.readRect(&bounds);
74
75 size_t glyphBufferCount = 0;
76 size_t posBufferCount = 0;
77 SkAutoTDelete<SkTArray<Run> > runs(SkNEW_ARGS(SkTArray<Run>, (runCount)));
78 for (int i = 0; i < runCount; ++i) {
79 Run& run = runs->push_back();
80
81 run.count = buffer.read32();
82 if (0 == run.count) {
83 return NULL;
84 }
85
86 run.glyphStart = buffer.read32();
87 run.posStart = buffer.read32();
88 if (run.glyphStart != glyphBufferCount || run.posStart != posBufferCount ) {
89 return NULL;
90 }
91
92 buffer.readPoint(&run.offset);
93 buffer.readPaint(&run.font);
94
95 run.positioning = static_cast<GlyphPositioning>(buffer.read32());
96 if (run.positioning > 2) {
97 return NULL;
98 }
99
100 glyphBufferCount += run.count;
101 posBufferCount += run.count * ScalarsPerGlyph(run.positioning);
102 }
103
104 SkTDArray<uint16_t> glyphBuffer;
105 SkTDArray<SkScalar> posBuffer;
106
107 buffer.readByteArray(glyphBuffer.append(glyphBufferCount),
108 glyphBufferCount * sizeof(uint16_t));
109 buffer.readByteArray(posBuffer.append(posBufferCount),
110 posBufferCount * sizeof(SkScalar));
111
112 return SkNEW_ARGS(SkTextBlob, (glyphBuffer.detach(),
113 posBuffer.detach(),
114 runs.detach(),
115 bounds));
116 }
117
29 SkTextBlob::RunIterator::RunIterator(const SkTextBlob* blob) 118 SkTextBlob::RunIterator::RunIterator(const SkTextBlob* blob)
30 : fBlob(blob) 119 : fBlob(blob)
31 , fIndex(0) { 120 , fIndex(0) {
32 SkASSERT(NULL != blob); 121 SkASSERT(NULL != blob);
33 } 122 }
34 123
35 bool SkTextBlob::RunIterator::done() const { 124 bool SkTextBlob::RunIterator::done() const {
36 return NULL == fBlob->fRuns.get() || fIndex >= fBlob->fRuns->count(); 125 return NULL == fBlob->fRuns.get() || fIndex >= fBlob->fRuns->count();
37 } 126 }
38 127
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 newRun.positioning = pos; 243 newRun.positioning = pos;
155 } 244 }
156 245
157 void SkTextBlobBuilder::allocInternal(const SkPaint &font, 246 void SkTextBlobBuilder::allocInternal(const SkPaint &font,
158 SkTextBlob::GlyphPositioning positioning, 247 SkTextBlob::GlyphPositioning positioning,
159 int count, SkPoint offset, const SkRect* b ounds) { 248 int count, SkPoint offset, const SkRect* b ounds) {
160 SkASSERT(count > 0); 249 SkASSERT(count > 0);
161 250
162 this->ensureRun(font, positioning, offset); 251 this->ensureRun(font, positioning, offset);
163 252
164 // SkTextBlob::GlyphPositioning values are directly mapped to scalars-per-gl yph. 253 unsigned posScalarsPerGlyph = SkTextBlob::ScalarsPerGlyph(positioning);
165 unsigned posScalarsPerGlyph = positioning;
166 SkASSERT(posScalarsPerGlyph <= 2);
167 254
168 fGlyphBuffer.append(count); 255 fGlyphBuffer.append(count);
169 fPosBuffer.append(count * posScalarsPerGlyph); 256 fPosBuffer.append(count * posScalarsPerGlyph);
170 257
171 SkASSERT(NULL != fRuns && !fRuns->empty()); 258 SkASSERT(NULL != fRuns && !fRuns->empty());
172 SkTextBlob::Run& run = fRuns->back(); 259 SkTextBlob::Run& run = fRuns->back();
173 260
174 run.count += count; 261 run.count += count;
175 262
176 // The current run might have been merged, so the start offset may point to prev run data. 263 // The current run might have been merged, so the start offset may point to prev run data.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 // empty blob 322 // empty blob
236 SkASSERT(NULL == fRuns || fRuns->empty()); 323 SkASSERT(NULL == fRuns || fRuns->empty());
237 SkASSERT(fBounds.isEmpty()); 324 SkASSERT(fBounds.isEmpty());
238 325
239 blob = SkNEW_ARGS(SkTextBlob, (NULL, NULL, NULL, SkRect::MakeEmpty())); 326 blob = SkNEW_ARGS(SkTextBlob, (NULL, NULL, NULL, SkRect::MakeEmpty()));
240 } 327 }
241 328
242 return blob; 329 return blob;
243 } 330 }
244 331
OLDNEW
« samplecode/SampleApp.cpp ('K') | « src/core/SkRecorder.h ('k') | src/pipe/SkGPipePriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698