OLD | NEW |
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" | 10 #include "SkReadBuffer.h" |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 | 237 |
238 it.next(); | 238 it.next(); |
239 SkDEBUGCODE(runCount--); | 239 SkDEBUGCODE(runCount--); |
240 } | 240 } |
241 SkASSERT(0 == runCount); | 241 SkASSERT(0 == runCount); |
242 } | 242 } |
243 | 243 |
244 const SkTextBlob* SkTextBlob::CreateFromBuffer(SkReadBuffer& reader) { | 244 const SkTextBlob* SkTextBlob::CreateFromBuffer(SkReadBuffer& reader) { |
245 int runCount = reader.read32(); | 245 int runCount = reader.read32(); |
246 if (runCount < 0) { | 246 if (runCount < 0) { |
247 return NULL; | 247 return nullptr; |
248 } | 248 } |
249 | 249 |
250 SkRect bounds; | 250 SkRect bounds; |
251 reader.readRect(&bounds); | 251 reader.readRect(&bounds); |
252 | 252 |
253 SkTextBlobBuilder blobBuilder; | 253 SkTextBlobBuilder blobBuilder; |
254 for (int i = 0; i < runCount; ++i) { | 254 for (int i = 0; i < runCount; ++i) { |
255 int glyphCount = reader.read32(); | 255 int glyphCount = reader.read32(); |
256 GlyphPositioning pos = static_cast<GlyphPositioning>(reader.read32()); | 256 GlyphPositioning pos = static_cast<GlyphPositioning>(reader.read32()); |
257 if (glyphCount <= 0 || pos > kFull_Positioning) { | 257 if (glyphCount <= 0 || pos > kFull_Positioning) { |
258 return NULL; | 258 return nullptr; |
259 } | 259 } |
260 | 260 |
261 SkPoint offset; | 261 SkPoint offset; |
262 reader.readPoint(&offset); | 262 reader.readPoint(&offset); |
263 SkPaint font; | 263 SkPaint font; |
264 reader.readPaint(&font); | 264 reader.readPaint(&font); |
265 | 265 |
266 const SkTextBlobBuilder::RunBuffer* buf = NULL; | 266 const SkTextBlobBuilder::RunBuffer* buf = nullptr; |
267 switch (pos) { | 267 switch (pos) { |
268 case kDefault_Positioning: | 268 case kDefault_Positioning: |
269 buf = &blobBuilder.allocRun(font, glyphCount, offset.x(), offset.y()
, &bounds); | 269 buf = &blobBuilder.allocRun(font, glyphCount, offset.x(), offset.y()
, &bounds); |
270 break; | 270 break; |
271 case kHorizontal_Positioning: | 271 case kHorizontal_Positioning: |
272 buf = &blobBuilder.allocRunPosH(font, glyphCount, offset.y(), &bound
s); | 272 buf = &blobBuilder.allocRunPosH(font, glyphCount, offset.y(), &bound
s); |
273 break; | 273 break; |
274 case kFull_Positioning: | 274 case kFull_Positioning: |
275 buf = &blobBuilder.allocRunPos(font, glyphCount, &bounds); | 275 buf = &blobBuilder.allocRunPos(font, glyphCount, &bounds); |
276 break; | 276 break; |
277 default: | 277 default: |
278 return NULL; | 278 return nullptr; |
279 } | 279 } |
280 | 280 |
281 if (!reader.readByteArray(buf->glyphs, glyphCount * sizeof(uint16_t)) || | 281 if (!reader.readByteArray(buf->glyphs, glyphCount * sizeof(uint16_t)) || |
282 !reader.readByteArray(buf->pos, | 282 !reader.readByteArray(buf->pos, |
283 glyphCount * sizeof(SkScalar) * ScalarsPerGlyp
h(pos))) { | 283 glyphCount * sizeof(SkScalar) * ScalarsPerGlyp
h(pos))) { |
284 return NULL; | 284 return nullptr; |
285 } | 285 } |
286 } | 286 } |
287 | 287 |
288 return blobBuilder.build(); | 288 return blobBuilder.build(); |
289 } | 289 } |
290 | 290 |
291 unsigned SkTextBlob::ScalarsPerGlyph(GlyphPositioning pos) { | 291 unsigned SkTextBlob::ScalarsPerGlyph(GlyphPositioning pos) { |
292 // GlyphPositioning values are directly mapped to scalars-per-glyph. | 292 // GlyphPositioning values are directly mapped to scalars-per-glyph. |
293 SkASSERT(pos <= 2); | 293 SkASSERT(pos <= 2); |
294 return pos; | 294 return pos; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 SkTextBlobBuilder::SkTextBlobBuilder() | 352 SkTextBlobBuilder::SkTextBlobBuilder() |
353 : fStorageSize(0) | 353 : fStorageSize(0) |
354 , fStorageUsed(0) | 354 , fStorageUsed(0) |
355 , fRunCount(0) | 355 , fRunCount(0) |
356 , fDeferredBounds(false) | 356 , fDeferredBounds(false) |
357 , fLastRun(0) { | 357 , fLastRun(0) { |
358 fBounds.setEmpty(); | 358 fBounds.setEmpty(); |
359 } | 359 } |
360 | 360 |
361 SkTextBlobBuilder::~SkTextBlobBuilder() { | 361 SkTextBlobBuilder::~SkTextBlobBuilder() { |
362 if (NULL != fStorage.get()) { | 362 if (nullptr != fStorage.get()) { |
363 // We are abandoning runs and must destruct the associated font data. | 363 // We are abandoning runs and must destruct the associated font data. |
364 // The easiest way to accomplish that is to use the blob destructor. | 364 // The easiest way to accomplish that is to use the blob destructor. |
365 build()->unref(); | 365 build()->unref(); |
366 } | 366 } |
367 } | 367 } |
368 | 368 |
369 SkRect SkTextBlobBuilder::TightRunBounds(const SkTextBlob::RunRecord& run) { | 369 SkRect SkTextBlobBuilder::TightRunBounds(const SkTextBlob::RunRecord& run) { |
370 SkASSERT(SkTextBlob::kDefault_Positioning == run.positioning()); | 370 SkASSERT(SkTextBlob::kDefault_Positioning == run.positioning()); |
371 | 371 |
372 SkRect bounds; | 372 SkRect bounds; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 fDeferredBounds = false; | 440 fDeferredBounds = false; |
441 } | 441 } |
442 | 442 |
443 void SkTextBlobBuilder::reserve(size_t size) { | 443 void SkTextBlobBuilder::reserve(size_t size) { |
444 // We don't currently pre-allocate, but maybe someday... | 444 // We don't currently pre-allocate, but maybe someday... |
445 if (fStorageUsed + size <= fStorageSize) { | 445 if (fStorageUsed + size <= fStorageSize) { |
446 return; | 446 return; |
447 } | 447 } |
448 | 448 |
449 if (0 == fRunCount) { | 449 if (0 == fRunCount) { |
450 SkASSERT(NULL == fStorage.get()); | 450 SkASSERT(nullptr == fStorage.get()); |
451 SkASSERT(0 == fStorageSize); | 451 SkASSERT(0 == fStorageSize); |
452 SkASSERT(0 == fStorageUsed); | 452 SkASSERT(0 == fStorageUsed); |
453 | 453 |
454 // the first allocation also includes blob storage | 454 // the first allocation also includes blob storage |
455 fStorageUsed += sizeof(SkTextBlob); | 455 fStorageUsed += sizeof(SkTextBlob); |
456 } | 456 } |
457 | 457 |
458 fStorageSize = fStorageUsed + size; | 458 fStorageSize = fStorageUsed + size; |
459 // FYI: This relies on everything we store being relocatable, particularly S
kPaint. | 459 // FYI: This relies on everything we store being relocatable, particularly S
kPaint. |
460 fStorage.realloc(fStorageSize); | 460 fStorage.realloc(fStorageSize); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 } | 566 } |
567 | 567 |
568 const SkTextBlobBuilder::RunBuffer& SkTextBlobBuilder::allocRunPos(const SkPaint
& font, int count, | 568 const SkTextBlobBuilder::RunBuffer& SkTextBlobBuilder::allocRunPos(const SkPaint
& font, int count, |
569 const SkRect
*bounds) { | 569 const SkRect
*bounds) { |
570 this->allocInternal(font, SkTextBlob::kFull_Positioning, count, SkPoint::Mak
e(0, 0), bounds); | 570 this->allocInternal(font, SkTextBlob::kFull_Positioning, count, SkPoint::Mak
e(0, 0), bounds); |
571 | 571 |
572 return fCurrentRunBuffer; | 572 return fCurrentRunBuffer; |
573 } | 573 } |
574 | 574 |
575 const SkTextBlob* SkTextBlobBuilder::build() { | 575 const SkTextBlob* SkTextBlobBuilder::build() { |
576 SkASSERT((fRunCount > 0) == (NULL != fStorage.get())); | 576 SkASSERT((fRunCount > 0) == (nullptr != fStorage.get())); |
577 | 577 |
578 this->updateDeferredBounds(); | 578 this->updateDeferredBounds(); |
579 | 579 |
580 if (0 == fRunCount) { | 580 if (0 == fRunCount) { |
581 SkASSERT(NULL == fStorage.get()); | 581 SkASSERT(nullptr == fStorage.get()); |
582 fStorageUsed = sizeof(SkTextBlob); | 582 fStorageUsed = sizeof(SkTextBlob); |
583 fStorage.realloc(fStorageUsed); | 583 fStorage.realloc(fStorageUsed); |
584 } | 584 } |
585 | 585 |
586 SkDEBUGCODE( | 586 SkDEBUGCODE( |
587 size_t validateSize = sizeof(SkTextBlob); | 587 size_t validateSize = sizeof(SkTextBlob); |
588 const SkTextBlob::RunRecord* run = | 588 const SkTextBlob::RunRecord* run = |
589 SkTextBlob::RunRecord::First(reinterpret_cast<const SkTextBlob*>(fSt
orage.get())); | 589 SkTextBlob::RunRecord::First(reinterpret_cast<const SkTextBlob*>(fSt
orage.get())); |
590 for (int i = 0; i < fRunCount; ++i) { | 590 for (int i = 0; i < fRunCount; ++i) { |
591 validateSize += SkTextBlob::RunRecord::StorageSize(run->fCount, run-
>fPositioning); | 591 validateSize += SkTextBlob::RunRecord::StorageSize(run->fCount, run-
>fPositioning); |
592 run->validate(fStorage.get() + fStorageUsed); | 592 run->validate(fStorage.get() + fStorageUsed); |
593 run = SkTextBlob::RunRecord::Next(run); | 593 run = SkTextBlob::RunRecord::Next(run); |
594 } | 594 } |
595 SkASSERT(validateSize == fStorageUsed); | 595 SkASSERT(validateSize == fStorageUsed); |
596 ) | 596 ) |
597 | 597 |
598 const SkTextBlob* blob = new (fStorage.detach()) SkTextBlob(fRunCount, fBoun
ds); | 598 const SkTextBlob* blob = new (fStorage.detach()) SkTextBlob(fRunCount, fBoun
ds); |
599 SkDEBUGCODE(const_cast<SkTextBlob*>(blob)->fStorageSize = fStorageSize;) | 599 SkDEBUGCODE(const_cast<SkTextBlob*>(blob)->fStorageSize = fStorageSize;) |
600 | 600 |
601 fStorageUsed = 0; | 601 fStorageUsed = 0; |
602 fStorageSize = 0; | 602 fStorageSize = 0; |
603 fRunCount = 0; | 603 fRunCount = 0; |
604 fLastRun = 0; | 604 fLastRun = 0; |
605 fBounds.setEmpty(); | 605 fBounds.setEmpty(); |
606 | 606 |
607 return blob; | 607 return blob; |
608 } | 608 } |
609 | 609 |
OLD | NEW |