| 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 |