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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 } | 311 } |
312 } | 312 } |
313 | 313 |
314 void SkTextBlobBuilder::updateDeferredBounds() { | 314 void SkTextBlobBuilder::updateDeferredBounds() { |
315 SkASSERT(!fDeferredBounds || fRunCount > 0); | 315 SkASSERT(!fDeferredBounds || fRunCount > 0); |
316 | 316 |
317 if (!fDeferredBounds) { | 317 if (!fDeferredBounds) { |
318 return; | 318 return; |
319 } | 319 } |
320 | 320 |
321 // FIXME: measure the current run & union bounds | 321 SkASSERT(fLastRun >= sizeof(SkTextBlob)); |
| 322 SkTextBlob::RunRecord* run = reinterpret_cast<SkTextBlob::RunRecord*>(fStora
ge.get() + |
| 323 fLastR
un); |
| 324 SkASSERT(SkPaint::kGlyphID_TextEncoding == run->font().getTextEncoding()); |
| 325 |
| 326 SkRect runBounds = SkRect::MakeEmpty(); |
| 327 if (SkTextBlob::kDefault_Positioning == run->positioning()) { |
| 328 run->font().measureText(run->glyphBuffer(), |
| 329 run->glyphCount() * sizeof(uint16_t), |
| 330 &runBounds); |
| 331 } else { |
| 332 SkASSERT(SkTextBlob::kFull_Positioning == run->positioning() || |
| 333 SkTextBlob::kHorizontal_Positioning == run->positioning()); |
| 334 |
| 335 SkAutoSTArray<16, SkRect> glyphBounds(run->glyphCount()); |
| 336 run->font().getTextWidths(run->glyphBuffer(), |
| 337 run->glyphCount() * sizeof(uint16_t), |
| 338 NULL, |
| 339 glyphBounds.get()); |
| 340 |
| 341 SkScalar* glyphOffset = run->posBuffer(); |
| 342 for (unsigned i = 0; i < run->glyphCount(); ++i) { |
| 343 if (SkTextBlob::kFull_Positioning == run->positioning()) { |
| 344 // [ x, y, x, y... ] |
| 345 glyphBounds[i].offset(glyphOffset[0], glyphOffset[1]); |
| 346 SkASSERT(2 == SkTextBlob::ScalarsPerGlyph(run->positioning())); |
| 347 glyphOffset += 2; |
| 348 } else { |
| 349 // [ x, x, x... ], const y applied by runBounds.offset(run->offs
et()) later. |
| 350 glyphBounds[i].offset(glyphOffset[0], 0); |
| 351 SkASSERT(1 == SkTextBlob::ScalarsPerGlyph(run->positioning())); |
| 352 glyphOffset += 1; |
| 353 } |
| 354 |
| 355 runBounds.join(glyphBounds[i]); |
| 356 } |
| 357 |
| 358 SkASSERT((void*)glyphOffset <= SkTextBlob::RunRecord::Next(run)); |
| 359 } |
| 360 |
| 361 runBounds.offset(run->offset()); |
| 362 |
| 363 fBounds.join(runBounds); |
322 fDeferredBounds = false; | 364 fDeferredBounds = false; |
323 } | 365 } |
324 | 366 |
325 void SkTextBlobBuilder::reserve(size_t size) { | 367 void SkTextBlobBuilder::reserve(size_t size) { |
326 // We don't currently pre-allocate, but maybe someday... | 368 // We don't currently pre-allocate, but maybe someday... |
327 if (fStorageUsed + size <= fStorageSize) { | 369 if (fStorageUsed + size <= fStorageSize) { |
328 return; | 370 return; |
329 } | 371 } |
330 | 372 |
331 if (0 == fRunCount) { | 373 if (0 == fRunCount) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 return true; | 434 return true; |
393 } | 435 } |
394 | 436 |
395 void SkTextBlobBuilder::allocInternal(const SkPaint &font, | 437 void SkTextBlobBuilder::allocInternal(const SkPaint &font, |
396 SkTextBlob::GlyphPositioning positioning, | 438 SkTextBlob::GlyphPositioning positioning, |
397 int count, SkPoint offset, const SkRect* b
ounds) { | 439 int count, SkPoint offset, const SkRect* b
ounds) { |
398 SkASSERT(count > 0); | 440 SkASSERT(count > 0); |
399 SkASSERT(SkPaint::kGlyphID_TextEncoding == font.getTextEncoding()); | 441 SkASSERT(SkPaint::kGlyphID_TextEncoding == font.getTextEncoding()); |
400 | 442 |
401 if (!this->mergeRun(font, positioning, count, offset)) { | 443 if (!this->mergeRun(font, positioning, count, offset)) { |
402 updateDeferredBounds(); | 444 this->updateDeferredBounds(); |
403 | 445 |
404 size_t runSize = SkTextBlob::RunRecord::StorageSize(count, positioning); | 446 size_t runSize = SkTextBlob::RunRecord::StorageSize(count, positioning); |
405 this->reserve(runSize); | 447 this->reserve(runSize); |
406 | 448 |
407 SkASSERT(fStorageUsed >= sizeof(SkTextBlob)); | 449 SkASSERT(fStorageUsed >= sizeof(SkTextBlob)); |
408 SkASSERT(fStorageUsed + runSize <= fStorageSize); | 450 SkASSERT(fStorageUsed + runSize <= fStorageSize); |
409 | 451 |
410 SkTextBlob::RunRecord* run = new (fStorage.get() + fStorageUsed) | 452 SkTextBlob::RunRecord* run = new (fStorage.get() + fStorageUsed) |
411 SkTextBlob::RunRecord(count, offset, fo
nt, positioning); | 453 SkTextBlob::RunRecord(count, offset, fo
nt, positioning); |
412 | 454 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 | 524 |
483 fStorageUsed = 0; | 525 fStorageUsed = 0; |
484 fStorageSize = 0; | 526 fStorageSize = 0; |
485 fRunCount = 0; | 527 fRunCount = 0; |
486 fLastRun = 0; | 528 fLastRun = 0; |
487 fBounds.setEmpty(); | 529 fBounds.setEmpty(); |
488 | 530 |
489 return blob; | 531 return blob; |
490 } | 532 } |
491 | 533 |
OLD | NEW |