OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 "SkPaint.h" | 8 #include "SkPaint.h" |
9 #include "SkAnnotation.h" | 9 #include "SkAnnotation.h" |
10 #include "SkAutoKern.h" | 10 #include "SkAutoKern.h" |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 SkASSERT(cache != nullptr); | 675 SkASSERT(cache != nullptr); |
676 SkASSERT(text != nullptr); | 676 SkASSERT(text != nullptr); |
677 | 677 |
678 const uint16_t* ptr = *(const uint16_t**)text; | 678 const uint16_t* ptr = *(const uint16_t**)text; |
679 unsigned glyphID = *ptr; | 679 unsigned glyphID = *ptr; |
680 ptr += 1; | 680 ptr += 1; |
681 *text = (const char*)ptr; | 681 *text = (const char*)ptr; |
682 return cache->getGlyphIDAdvance(glyphID); | 682 return cache->getGlyphIDAdvance(glyphID); |
683 } | 683 } |
684 | 684 |
685 SkMeasureCacheProc SkPaint::getMeasureCacheProc(bool needFullMetrics) const { | 685 SkPaint::GlyphCacheProc SkPaint::getGlyphCacheProc(bool needFullMetrics) const { |
686 static const SkMeasureCacheProc gMeasureCacheProcs[] = { | 686 static const GlyphCacheProc gGlyphCacheProcs[] = { |
687 sk_getMetrics_utf8_next, | 687 sk_getMetrics_utf8_next, |
688 sk_getMetrics_utf16_next, | 688 sk_getMetrics_utf16_next, |
689 sk_getMetrics_utf32_next, | 689 sk_getMetrics_utf32_next, |
690 sk_getMetrics_glyph_next, | 690 sk_getMetrics_glyph_next, |
691 | 691 |
692 sk_getAdvance_utf8_next, | 692 sk_getAdvance_utf8_next, |
693 sk_getAdvance_utf16_next, | 693 sk_getAdvance_utf16_next, |
694 sk_getAdvance_utf32_next, | 694 sk_getAdvance_utf32_next, |
695 sk_getAdvance_glyph_next, | 695 sk_getAdvance_glyph_next, |
696 }; | 696 }; |
697 | 697 |
698 unsigned index = this->getTextEncoding(); | 698 unsigned index = this->getTextEncoding(); |
699 | 699 |
700 if (!needFullMetrics && !this->isDevKernText()) { | 700 if (!needFullMetrics && !this->isDevKernText()) { |
701 index += 4; | 701 index += 4; |
702 } | 702 } |
703 | 703 |
704 SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs)); | 704 SkASSERT(index < SK_ARRAY_COUNT(gGlyphCacheProcs)); |
705 return gMeasureCacheProcs[index]; | 705 return gGlyphCacheProcs[index]; |
706 } | 706 } |
707 | 707 |
708 /////////////////////////////////////////////////////////////////////////////// | 708 /////////////////////////////////////////////////////////////////////////////// |
709 | |
710 static const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache, | |
711 const char** text, SkFixed, SkFixed) { | |
712 SkASSERT(cache != nullptr); | |
713 SkASSERT(text != nullptr); | |
714 | |
715 return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); | |
716 } | |
717 | |
718 static const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache, | |
719 const char** text, SkFixed x, SkFixed y) { | |
720 SkASSERT(cache != nullptr); | |
721 SkASSERT(text != nullptr); | |
722 | |
723 return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y); | |
724 } | |
725 | |
726 static const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, | |
727 const char** text, SkFixed, SkFixed) { | |
728 SkASSERT(cache != nullptr); | |
729 SkASSERT(text != nullptr); | |
730 | |
731 return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text))
; | |
732 } | |
733 | |
734 static const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache, | |
735 const char** text, SkFixed x, SkFixed y) { | |
736 SkASSERT(cache != nullptr); | |
737 SkASSERT(text != nullptr); | |
738 | |
739 return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text), | |
740 x, y); | |
741 } | |
742 | |
743 static const SkGlyph& sk_getMetrics_utf32_00(SkGlyphCache* cache, | |
744 const char** text, SkFixed, SkFixed) { | |
745 SkASSERT(cache != nullptr); | |
746 SkASSERT(text != nullptr); | |
747 | |
748 const int32_t* ptr = *(const int32_t**)text; | |
749 SkUnichar uni = *ptr++; | |
750 *text = (const char*)ptr; | |
751 return cache->getUnicharMetrics(uni); | |
752 } | |
753 | |
754 static const SkGlyph& sk_getMetrics_utf32_xy(SkGlyphCache* cache, | |
755 const char** text, SkFixed x, SkFixed y) { | |
756 SkASSERT(cache != nullptr); | |
757 SkASSERT(text != nullptr); | |
758 | |
759 const int32_t* ptr = *(const int32_t**)text; | |
760 SkUnichar uni = *ptr++; | |
761 *text = (const char*)ptr; | |
762 return cache->getUnicharMetrics(uni, x, y); | |
763 } | |
764 | |
765 static const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, | |
766 const char** text, SkFixed, SkFixed) { | |
767 SkASSERT(cache != nullptr); | |
768 SkASSERT(text != nullptr); | |
769 | |
770 const uint16_t* ptr = *(const uint16_t**)text; | |
771 unsigned glyphID = *ptr; | |
772 ptr += 1; | |
773 *text = (const char*)ptr; | |
774 return cache->getGlyphIDMetrics(glyphID); | |
775 } | |
776 | |
777 static const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache, | |
778 const char** text, SkFixed x, SkFixed y) { | |
779 SkASSERT(cache != nullptr); | |
780 SkASSERT(text != nullptr); | |
781 | |
782 const uint16_t* ptr = *(const uint16_t**)text; | |
783 unsigned glyphID = *ptr; | |
784 ptr += 1; | |
785 *text = (const char*)ptr; | |
786 return cache->getGlyphIDMetrics(glyphID, x, y); | |
787 } | |
788 | |
789 SkDrawCacheProc SkPaint::getDrawCacheProc() const { | |
790 static const SkDrawCacheProc gDrawCacheProcs[] = { | |
791 sk_getMetrics_utf8_00, | |
792 sk_getMetrics_utf16_00, | |
793 sk_getMetrics_utf32_00, | |
794 sk_getMetrics_glyph_00, | |
795 | |
796 sk_getMetrics_utf8_xy, | |
797 sk_getMetrics_utf16_xy, | |
798 sk_getMetrics_utf32_xy, | |
799 sk_getMetrics_glyph_xy | |
800 }; | |
801 | |
802 unsigned index = this->getTextEncoding(); | |
803 if (fBitfields.fFlags & kSubpixelText_Flag) { | |
804 index += 4; | |
805 } | |
806 | |
807 SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs)); | |
808 return gDrawCacheProcs[index]; | |
809 } | |
810 | |
811 /////////////////////////////////////////////////////////////////////////////// | |
812 | 709 |
813 #define TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE ( \ | 710 #define TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE ( \ |
814 SkPaint::kDevKernText_Flag | \ | 711 SkPaint::kDevKernText_Flag | \ |
815 SkPaint::kLinearText_Flag | \ | 712 SkPaint::kLinearText_Flag | \ |
816 SkPaint::kLCDRenderText_Flag | \ | 713 SkPaint::kLCDRenderText_Flag | \ |
817 SkPaint::kEmbeddedBitmapText_Flag | \ | 714 SkPaint::kEmbeddedBitmapText_Flag | \ |
818 SkPaint::kAutoHinting_Flag | \ | 715 SkPaint::kAutoHinting_Flag | \ |
819 SkPaint::kGenA8FromLCD_Flag ) | 716 SkPaint::kGenA8FromLCD_Flag ) |
820 | 717 |
821 SkScalar SkPaint::setupForAsPaths() { | 718 SkScalar SkPaint::setupForAsPaths() { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 int* count, SkRect* bounds) const { | 790 int* count, SkRect* bounds) const { |
894 SkASSERT(count); | 791 SkASSERT(count); |
895 if (byteLength == 0) { | 792 if (byteLength == 0) { |
896 *count = 0; | 793 *count = 0; |
897 if (bounds) { | 794 if (bounds) { |
898 bounds->setEmpty(); | 795 bounds->setEmpty(); |
899 } | 796 } |
900 return 0; | 797 return 0; |
901 } | 798 } |
902 | 799 |
903 SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(nullptr != bou
nds); | 800 GlyphCacheProc glyphCacheProc = this->getGlyphCacheProc(nullptr != bounds); |
904 | 801 |
905 int xyIndex; | 802 int xyIndex; |
906 JoinBoundsProc joinBoundsProc; | 803 JoinBoundsProc joinBoundsProc; |
907 if (this->isVerticalText()) { | 804 if (this->isVerticalText()) { |
908 xyIndex = 1; | 805 xyIndex = 1; |
909 joinBoundsProc = join_bounds_y; | 806 joinBoundsProc = join_bounds_y; |
910 } else { | 807 } else { |
911 xyIndex = 0; | 808 xyIndex = 0; |
912 joinBoundsProc = join_bounds_x; | 809 joinBoundsProc = join_bounds_x; |
913 } | 810 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 SkScalar scale = canon.getScale(); | 915 SkScalar scale = canon.getScale(); |
1019 | 916 |
1020 // adjust max in case we changed the textSize in paint | 917 // adjust max in case we changed the textSize in paint |
1021 if (scale) { | 918 if (scale) { |
1022 maxWidth /= scale; | 919 maxWidth /= scale; |
1023 } | 920 } |
1024 | 921 |
1025 SkAutoGlyphCache autoCache(paint, nullptr, nullptr); | 922 SkAutoGlyphCache autoCache(paint, nullptr, nullptr); |
1026 SkGlyphCache* cache = autoCache.getCache(); | 923 SkGlyphCache* cache = autoCache.getCache(); |
1027 | 924 |
1028 SkMeasureCacheProc glyphCacheProc = paint.getMeasureCacheProc(false); | 925 GlyphCacheProc glyphCacheProc = paint.getGlyphCacheProc(false); |
1029 const int xyIndex = paint.isVerticalText() ? 1 : 0; | 926 const int xyIndex = paint.isVerticalText() ? 1 : 0; |
1030 // use 64bits for our accumulator, to avoid overflowing 16.16 | 927 // use 64bits for our accumulator, to avoid overflowing 16.16 |
1031 Sk48Dot16 max = SkScalarToFixed(maxWidth); | 928 Sk48Dot16 max = SkScalarToFixed(maxWidth); |
1032 Sk48Dot16 width = 0; | 929 Sk48Dot16 width = 0; |
1033 | 930 |
1034 SkAutoKern autokern; | 931 SkAutoKern autokern; |
1035 | 932 |
1036 if (this->isDevKernText()) { | 933 if (this->isDevKernText()) { |
1037 int rsb = 0; | 934 int rsb = 0; |
1038 while (text < stop) { | 935 while (text < stop) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1136 if (nullptr == widths && nullptr == bounds) { | 1033 if (nullptr == widths && nullptr == bounds) { |
1137 return this->countText(textData, byteLength); | 1034 return this->countText(textData, byteLength); |
1138 } | 1035 } |
1139 | 1036 |
1140 SkCanonicalizePaint canon(*this); | 1037 SkCanonicalizePaint canon(*this); |
1141 const SkPaint& paint = canon.getPaint(); | 1038 const SkPaint& paint = canon.getPaint(); |
1142 SkScalar scale = canon.getScale(); | 1039 SkScalar scale = canon.getScale(); |
1143 | 1040 |
1144 SkAutoGlyphCache autoCache(paint, nullptr, nullptr); | 1041 SkAutoGlyphCache autoCache(paint, nullptr, nullptr); |
1145 SkGlyphCache* cache = autoCache.getCache(); | 1042 SkGlyphCache* cache = autoCache.getCache(); |
1146 SkMeasureCacheProc glyphCacheProc; | 1043 GlyphCacheProc glyphCacheProc = paint.getGlyphCacheProc(nullptr != boun
ds); |
1147 glyphCacheProc = paint.getMeasureCacheProc(nullptr != bounds); | |
1148 | 1044 |
1149 const char* text = (const char*)textData; | 1045 const char* text = (const char*)textData; |
1150 const char* stop = text + byteLength; | 1046 const char* stop = text + byteLength; |
1151 int count = 0; | 1047 int count = 0; |
1152 const int xyIndex = paint.isVerticalText() ? 1 : 0; | 1048 const int xyIndex = paint.isVerticalText() ? 1 : 0; |
1153 | 1049 |
1154 if (this->isDevKernText()) { | 1050 if (this->isDevKernText()) { |
1155 // we adjust the widths returned here through auto-kerning | 1051 // we adjust the widths returned here through auto-kerning |
1156 SkAutoKern autokern; | 1052 SkAutoKern autokern; |
1157 SkFixed prevWidth = 0; | 1053 SkFixed prevWidth = 0; |
(...skipping 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2390 | 2286 |
2391 static bool has_thick_frame(const SkPaint& paint) { | 2287 static bool has_thick_frame(const SkPaint& paint) { |
2392 return paint.getStrokeWidth() > 0 && | 2288 return paint.getStrokeWidth() > 0 && |
2393 paint.getStyle() != SkPaint::kFill_Style; | 2289 paint.getStyle() != SkPaint::kFill_Style; |
2394 } | 2290 } |
2395 | 2291 |
2396 SkTextBaseIter::SkTextBaseIter(const char text[], size_t length, | 2292 SkTextBaseIter::SkTextBaseIter(const char text[], size_t length, |
2397 const SkPaint& paint, | 2293 const SkPaint& paint, |
2398 bool applyStrokeAndPathEffects) | 2294 bool applyStrokeAndPathEffects) |
2399 : fPaint(paint) { | 2295 : fPaint(paint) { |
2400 fGlyphCacheProc = paint.getMeasureCacheProc(true); | 2296 fGlyphCacheProc = paint.getGlyphCacheProc(true); |
2401 | 2297 |
2402 fPaint.setLinearText(true); | 2298 fPaint.setLinearText(true); |
2403 fPaint.setMaskFilter(nullptr); // don't want this affecting our path-cache
lookup | 2299 fPaint.setMaskFilter(nullptr); // don't want this affecting our path-cache
lookup |
2404 | 2300 |
2405 if (fPaint.getPathEffect() == nullptr && !has_thick_frame(fPaint)) { | 2301 if (fPaint.getPathEffect() == nullptr && !has_thick_frame(fPaint)) { |
2406 applyStrokeAndPathEffects = false; | 2302 applyStrokeAndPathEffects = false; |
2407 } | 2303 } |
2408 | 2304 |
2409 // can't use our canonical size if we need to apply patheffects | 2305 // can't use our canonical size if we need to apply patheffects |
2410 if (fPaint.getPathEffect() == nullptr) { | 2306 if (fPaint.getPathEffect() == nullptr) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2535 } | 2431 } |
2536 | 2432 |
2537 uint32_t SkPaint::getHash() const { | 2433 uint32_t SkPaint::getHash() const { |
2538 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, | 2434 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, |
2539 // so fBitfields should be 10 pointers and 6 32-bit values from the start. | 2435 // so fBitfields should be 10 pointers and 6 32-bit values from the start. |
2540 static_assert(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 * size
of(uint32_t), | 2436 static_assert(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 * size
of(uint32_t), |
2541 "SkPaint_notPackedTightly"); | 2437 "SkPaint_notPackedTightly"); |
2542 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), | 2438 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), |
2543 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); | 2439 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); |
2544 } | 2440 } |
OLD | NEW |