| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkGlyphCache.h" | 10 #include "SkGlyphCache.h" |
| 11 #include "SkGlyphCache_Globals.h" | 11 #include "SkGlyphCache_Globals.h" |
| 12 #include "SkDistanceFieldGen.h" |
| 12 #include "SkGraphics.h" | 13 #include "SkGraphics.h" |
| 13 #include "SkPaint.h" | 14 #include "SkPaint.h" |
| 14 #include "SkPath.h" | 15 #include "SkPath.h" |
| 15 #include "SkTemplates.h" | 16 #include "SkTemplates.h" |
| 16 #include "SkTLS.h" | 17 #include "SkTLS.h" |
| 17 #include "SkTypeface.h" | 18 #include "SkTypeface.h" |
| 18 | 19 |
| 19 //#define SPEW_PURGE_STATUS | 20 //#define SPEW_PURGE_STATUS |
| 20 //#define RECORD_HASH_EFFICIENCY | 21 //#define RECORD_HASH_EFFICIENCY |
| 21 | 22 |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 } else { | 322 } else { |
| 322 SkASSERT(kFull_MetricsType == mtype); | 323 SkASSERT(kFull_MetricsType == mtype); |
| 323 fScalerContext->getMetrics(glyph); | 324 fScalerContext->getMetrics(glyph); |
| 324 } | 325 } |
| 325 | 326 |
| 326 return glyph; | 327 return glyph; |
| 327 } | 328 } |
| 328 | 329 |
| 329 const void* SkGlyphCache::findImage(const SkGlyph& glyph) { | 330 const void* SkGlyphCache::findImage(const SkGlyph& glyph) { |
| 330 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) { | 331 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) { |
| 331 if (glyph.fImage == NULL) { | 332 if (NULL == glyph.fImage) { |
| 332 size_t size = glyph.computeImageSize(); | 333 size_t size = glyph.computeImageSize(); |
| 333 const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size, | 334 const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size, |
| 334 SkChunkAlloc::kReturnNil_AllocFailType); | 335 SkChunkAlloc::kReturnNil_AllocFailType); |
| 335 // check that alloc() actually succeeded | 336 // check that alloc() actually succeeded |
| 336 if (glyph.fImage) { | 337 if (NULL != glyph.fImage) { |
| 337 fScalerContext->getImage(glyph); | 338 fScalerContext->getImage(glyph); |
| 338 // TODO: the scaler may have changed the maskformat during | 339 // TODO: the scaler may have changed the maskformat during |
| 339 // getImage (e.g. from AA or LCD to BW) which means we may have | 340 // getImage (e.g. from AA or LCD to BW) which means we may have |
| 340 // overallocated the buffer. Check if the new computedImageSize | 341 // overallocated the buffer. Check if the new computedImageSize |
| 341 // is smaller, and if so, strink the alloc size in fImageAlloc. | 342 // is smaller, and if so, strink the alloc size in fImageAlloc. |
| 342 fMemoryUsed += size; | 343 fMemoryUsed += size; |
| 343 } | 344 } |
| 344 } | 345 } |
| 345 } | 346 } |
| 346 return glyph.fImage; | 347 return glyph.fImage; |
| 347 } | 348 } |
| 348 | 349 |
| 349 const SkPath* SkGlyphCache::findPath(const SkGlyph& glyph) { | 350 const SkPath* SkGlyphCache::findPath(const SkGlyph& glyph) { |
| 350 if (glyph.fWidth) { | 351 if (glyph.fWidth) { |
| 351 if (glyph.fPath == NULL) { | 352 if (glyph.fPath == NULL) { |
| 352 const_cast<SkGlyph&>(glyph).fPath = SkNEW(SkPath); | 353 const_cast<SkGlyph&>(glyph).fPath = SkNEW(SkPath); |
| 353 fScalerContext->getPath(glyph, glyph.fPath); | 354 fScalerContext->getPath(glyph, glyph.fPath); |
| 354 fMemoryUsed += sizeof(SkPath) + | 355 fMemoryUsed += sizeof(SkPath) + |
| 355 glyph.fPath->countPoints() * sizeof(SkPoint); | 356 glyph.fPath->countPoints() * sizeof(SkPoint); |
| 356 } | 357 } |
| 357 } | 358 } |
| 358 return glyph.fPath; | 359 return glyph.fPath; |
| 359 } | 360 } |
| 360 | 361 |
| 362 const void* SkGlyphCache::findDistanceField(const SkGlyph& glyph) { |
| 363 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) { |
| 364 if (NULL == glyph.fDistanceField) { |
| 365 size_t size = SkComputeDistanceFieldSize(glyph.fWidth, glyph.fHeigh
t); |
| 366 if (size == 0) { |
| 367 return NULL; |
| 368 } |
| 369 const void* image = this->findImage(glyph); |
| 370 // now generate the distance field |
| 371 if (NULL != image) { |
| 372 const_cast<SkGlyph&>(glyph).fDistanceField = fGlyphAlloc.alloc(s
ize, |
| 373 SkChunkAlloc::kReturnNil_AllocFailTy
pe); |
| 374 if (NULL != glyph.fDistanceField) { |
| 375 SkMask::Format maskFormat = static_cast<SkMask::Format>(glyp
h.fMaskFormat); |
| 376 if (SkMask::kA8_Format == maskFormat) { |
| 377 // make the distance field from the image |
| 378 SkGenerateDistanceFieldFromA8Image((unsigned char*)glyph
.fDistanceField, |
| 379 (unsigned char*)glyph
.fImage, |
| 380 glyph.fWidth, glyph.f
Height, |
| 381 glyph.rowBytes()); |
| 382 fMemoryUsed += size; |
| 383 } else if (SkMask::kBW_Format == maskFormat) { |
| 384 // make the distance field from the image |
| 385 SkGenerateDistanceFieldFromBWImage((unsigned char*)glyph
.fDistanceField, |
| 386 (unsigned char*)glyph
.fImage, |
| 387 glyph.fWidth, glyph.f
Height, |
| 388 glyph.rowBytes()); |
| 389 fMemoryUsed += size; |
| 390 } else { |
| 391 fGlyphAlloc.unalloc(glyph.fDistanceField); |
| 392 const_cast<SkGlyph&>(glyph).fDistanceField = NULL; |
| 393 } |
| 394 } |
| 395 } |
| 396 } |
| 397 } |
| 398 return glyph.fDistanceField; |
| 399 } |
| 400 |
| 361 /////////////////////////////////////////////////////////////////////////////// | 401 /////////////////////////////////////////////////////////////////////////////// |
| 362 | 402 |
| 363 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const { | 403 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const { |
| 364 const AuxProcRec* rec = fAuxProcList; | 404 const AuxProcRec* rec = fAuxProcList; |
| 365 while (rec) { | 405 while (rec) { |
| 366 if (rec->fProc == proc) { | 406 if (rec->fProc == proc) { |
| 367 if (dataPtr) { | 407 if (dataPtr) { |
| 368 *dataPtr = rec->fData; | 408 *dataPtr = rec->fData; |
| 369 } | 409 } |
| 370 return true; | 410 return true; |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 void SkGlyphCache::validate() const { | 682 void SkGlyphCache::validate() const { |
| 643 #ifdef SK_DEBUG_GLYPH_CACHE | 683 #ifdef SK_DEBUG_GLYPH_CACHE |
| 644 int count = fGlyphArray.count(); | 684 int count = fGlyphArray.count(); |
| 645 for (int i = 0; i < count; i++) { | 685 for (int i = 0; i < count; i++) { |
| 646 const SkGlyph* glyph = fGlyphArray[i]; | 686 const SkGlyph* glyph = fGlyphArray[i]; |
| 647 SkASSERT(glyph); | 687 SkASSERT(glyph); |
| 648 SkASSERT(fGlyphAlloc.contains(glyph)); | 688 SkASSERT(fGlyphAlloc.contains(glyph)); |
| 649 if (glyph->fImage) { | 689 if (glyph->fImage) { |
| 650 SkASSERT(fGlyphAlloc.contains(glyph->fImage)); | 690 SkASSERT(fGlyphAlloc.contains(glyph->fImage)); |
| 651 } | 691 } |
| 692 if (glyph->fDistanceField) { |
| 693 SkASSERT(fGlyphAlloc.contains(glyph->fDistanceField)); |
| 694 } |
| 652 } | 695 } |
| 653 #endif | 696 #endif |
| 654 } | 697 } |
| 655 | 698 |
| 656 void SkGlyphCache_Globals::validate() const { | 699 void SkGlyphCache_Globals::validate() const { |
| 657 size_t computedBytes = 0; | 700 size_t computedBytes = 0; |
| 658 int computedCount = 0; | 701 int computedCount = 0; |
| 659 | 702 |
| 660 const SkGlyphCache* head = fHead; | 703 const SkGlyphCache* head = fHead; |
| 661 while (head != NULL) { | 704 while (head != NULL) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 return tls ? tls->getCacheSizeLimit() : 0; | 752 return tls ? tls->getCacheSizeLimit() : 0; |
| 710 } | 753 } |
| 711 | 754 |
| 712 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { | 755 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { |
| 713 if (0 == bytes) { | 756 if (0 == bytes) { |
| 714 SkGlyphCache_Globals::DeleteTLS(); | 757 SkGlyphCache_Globals::DeleteTLS(); |
| 715 } else { | 758 } else { |
| 716 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes); | 759 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes); |
| 717 } | 760 } |
| 718 } | 761 } |
| OLD | NEW |