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 |