Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/core/SkPaint.cpp

Issue 1737693006: Change type of SkGlyph::fAdvance[XY] to float. (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Should be float, not SkScalar. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkGlyph.h ('k') | src/core/SkTextToPathIter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkAutoKern.h" 9 #include "SkAutoKern.h"
10 #include "SkChecksum.h" 10 #include "SkChecksum.h"
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 SkTLazy<SkPaint> fLazy; 726 SkTLazy<SkPaint> fLazy;
727 }; 727 };
728 728
729 static void set_bounds(const SkGlyph& g, SkRect* bounds) { 729 static void set_bounds(const SkGlyph& g, SkRect* bounds) {
730 bounds->set(SkIntToScalar(g.fLeft), 730 bounds->set(SkIntToScalar(g.fLeft),
731 SkIntToScalar(g.fTop), 731 SkIntToScalar(g.fTop),
732 SkIntToScalar(g.fLeft + g.fWidth), 732 SkIntToScalar(g.fLeft + g.fWidth),
733 SkIntToScalar(g.fTop + g.fHeight)); 733 SkIntToScalar(g.fTop + g.fHeight));
734 } 734 }
735 735
736 static void join_bounds_x(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx) { 736 static void join_bounds_x(const SkGlyph& g, SkRect* bounds, SkScalar dx) {
737 SkScalar sx = Sk48Dot16ToScalar(dx); 737 bounds->join(SkIntToScalar(g.fLeft) + dx,
738 bounds->join(SkIntToScalar(g.fLeft) + sx,
739 SkIntToScalar(g.fTop), 738 SkIntToScalar(g.fTop),
740 SkIntToScalar(g.fLeft + g.fWidth) + sx, 739 SkIntToScalar(g.fLeft + g.fWidth) + dx,
741 SkIntToScalar(g.fTop + g.fHeight)); 740 SkIntToScalar(g.fTop + g.fHeight));
742 } 741 }
743 742
744 static void join_bounds_y(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dy) { 743 static void join_bounds_y(const SkGlyph& g, SkRect* bounds, SkScalar dy) {
745 SkScalar sy = Sk48Dot16ToScalar(dy);
746 bounds->join(SkIntToScalar(g.fLeft), 744 bounds->join(SkIntToScalar(g.fLeft),
747 SkIntToScalar(g.fTop) + sy, 745 SkIntToScalar(g.fTop) + dy,
748 SkIntToScalar(g.fLeft + g.fWidth), 746 SkIntToScalar(g.fLeft + g.fWidth),
749 SkIntToScalar(g.fTop + g.fHeight) + sy); 747 SkIntToScalar(g.fTop + g.fHeight) + dy);
750 } 748 }
751 749
752 typedef void (*JoinBoundsProc)(const SkGlyph&, SkRect*, Sk48Dot16); 750 typedef void (*JoinBoundsProc)(const SkGlyph&, SkRect*, SkScalar);
753 751
754 // xyIndex is 0 for fAdvanceX or 1 for fAdvanceY 752 // xyIndex is 0 for fAdvanceX or 1 for fAdvanceY
755 static SkFixed advance(const SkGlyph& glyph, int xyIndex) { 753 static SkScalar advance(const SkGlyph& glyph, int xyIndex) {
756 SkASSERT(0 == xyIndex || 1 == xyIndex); 754 SkASSERT(0 == xyIndex || 1 == xyIndex);
757 return (&glyph.fAdvanceX)[xyIndex]; 755 return SkFloatToScalar((&glyph.fAdvanceX)[xyIndex]);
758 } 756 }
759 757
760 SkScalar SkPaint::measure_text(SkGlyphCache* cache, 758 SkScalar SkPaint::measure_text(SkGlyphCache* cache,
761 const char* text, size_t byteLength, 759 const char* text, size_t byteLength,
762 int* count, SkRect* bounds) const { 760 int* count, SkRect* bounds) const {
763 SkASSERT(count); 761 SkASSERT(count);
764 if (byteLength == 0) { 762 if (byteLength == 0) {
765 *count = 0; 763 *count = 0;
766 if (bounds) { 764 if (bounds) {
767 bounds->setEmpty(); 765 bounds->setEmpty();
768 } 766 }
769 return 0; 767 return 0;
770 } 768 }
771 769
772 GlyphCacheProc glyphCacheProc = this->getGlyphCacheProc(nullptr != bounds); 770 GlyphCacheProc glyphCacheProc = this->getGlyphCacheProc(nullptr != bounds);
773 771
774 int xyIndex; 772 int xyIndex;
775 JoinBoundsProc joinBoundsProc; 773 JoinBoundsProc joinBoundsProc;
776 if (this->isVerticalText()) { 774 if (this->isVerticalText()) {
777 xyIndex = 1; 775 xyIndex = 1;
778 joinBoundsProc = join_bounds_y; 776 joinBoundsProc = join_bounds_y;
779 } else { 777 } else {
780 xyIndex = 0; 778 xyIndex = 0;
781 joinBoundsProc = join_bounds_x; 779 joinBoundsProc = join_bounds_x;
782 } 780 }
783 781
784 int n = 1; 782 int n = 1;
785 const char* stop = (const char*)text + byteLength; 783 const char* stop = (const char*)text + byteLength;
786 const SkGlyph* g = &glyphCacheProc(cache, &text); 784 const SkGlyph* g = &glyphCacheProc(cache, &text);
787 // our accumulated fixed-point advances might overflow 16.16, so we use 785 SkScalar x = advance(*g, xyIndex);
788 // a 48.16 (64bit) accumulator, and then convert that to scalar at the
789 // very end.
790 Sk48Dot16 x = advance(*g, xyIndex);
791
792 SkAutoKern autokern;
793 786
794 if (nullptr == bounds) { 787 if (nullptr == bounds) {
795 if (this->isDevKernText()) { 788 if (this->isDevKernText()) {
796 int rsb;
797 for (; text < stop; n++) { 789 for (; text < stop; n++) {
798 rsb = g->fRsbDelta; 790 const int rsb = g->fRsbDelta;
799 g = &glyphCacheProc(cache, &text); 791 g = &glyphCacheProc(cache, &text);
800 x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + advance(*g, xyIndex ); 792 x += SkAutoKern_Adjust(rsb, g->fLsbDelta) + advance(*g, xyIndex) ;
801 } 793 }
802 } else { 794 } else {
803 for (; text < stop; n++) { 795 for (; text < stop; n++) {
804 x += advance(glyphCacheProc(cache, &text), xyIndex); 796 x += advance(glyphCacheProc(cache, &text), xyIndex);
805 } 797 }
806 } 798 }
807 } else { 799 } else {
808 set_bounds(*g, bounds); 800 set_bounds(*g, bounds);
809 if (this->isDevKernText()) { 801 if (this->isDevKernText()) {
810 int rsb;
811 for (; text < stop; n++) { 802 for (; text < stop; n++) {
812 rsb = g->fRsbDelta; 803 const int rsb = g->fRsbDelta;
813 g = &glyphCacheProc(cache, &text); 804 g = &glyphCacheProc(cache, &text);
814 x += SkAutoKern_AdjustF(rsb, g->fLsbDelta); 805 x += SkAutoKern_Adjust(rsb, g->fLsbDelta);
815 joinBoundsProc(*g, bounds, x); 806 joinBoundsProc(*g, bounds, x);
816 x += advance(*g, xyIndex); 807 x += advance(*g, xyIndex);
817 } 808 }
818 } else { 809 } else {
819 for (; text < stop; n++) { 810 for (; text < stop; n++) {
820 g = &glyphCacheProc(cache, &text); 811 g = &glyphCacheProc(cache, &text);
821 joinBoundsProc(*g, bounds, x); 812 joinBoundsProc(*g, bounds, x);
822 x += advance(*g, xyIndex); 813 x += advance(*g, xyIndex);
823 } 814 }
824 } 815 }
825 } 816 }
826 SkASSERT(text == stop); 817 SkASSERT(text == stop);
827 818
828 *count = n; 819 *count = n;
829 return Sk48Dot16ToScalar(x); 820 return x;
830 } 821 }
831 822
832 SkScalar SkPaint::measureText(const void* textData, size_t length, SkRect* bound s) const { 823 SkScalar SkPaint::measureText(const void* textData, size_t length, SkRect* bound s) const {
833 const char* text = (const char*)textData; 824 const char* text = (const char*)textData;
834 SkASSERT(text != nullptr || length == 0); 825 SkASSERT(text != nullptr || length == 0);
835 826
836 SkCanonicalizePaint canon(*this); 827 SkCanonicalizePaint canon(*this);
837 const SkPaint& paint = canon.getPaint(); 828 const SkPaint& paint = canon.getPaint();
838 SkScalar scale = canon.getScale(); 829 SkScalar scale = canon.getScale();
839 830
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 // adjust max in case we changed the textSize in paint 880 // adjust max in case we changed the textSize in paint
890 if (scale) { 881 if (scale) {
891 maxWidth /= scale; 882 maxWidth /= scale;
892 } 883 }
893 884
894 SkAutoGlyphCache autoCache(paint, nullptr, nullptr); 885 SkAutoGlyphCache autoCache(paint, nullptr, nullptr);
895 SkGlyphCache* cache = autoCache.getCache(); 886 SkGlyphCache* cache = autoCache.getCache();
896 887
897 GlyphCacheProc glyphCacheProc = paint.getGlyphCacheProc(false); 888 GlyphCacheProc glyphCacheProc = paint.getGlyphCacheProc(false);
898 const int xyIndex = paint.isVerticalText() ? 1 : 0; 889 const int xyIndex = paint.isVerticalText() ? 1 : 0;
899 // use 64bits for our accumulator, to avoid overflowing 16.16 890 SkScalar width = 0;
900 Sk48Dot16 max = SkScalarTo48Dot16(maxWidth);
901 Sk48Dot16 width = 0;
902
903 SkAutoKern autokern;
904 891
905 if (this->isDevKernText()) { 892 if (this->isDevKernText()) {
906 int rsb = 0; 893 int rsb = 0;
907 while (text < stop) { 894 while (text < stop) {
908 const char* curr = text; 895 const char* curr = text;
909 const SkGlyph& g = glyphCacheProc(cache, &text); 896 const SkGlyph& g = glyphCacheProc(cache, &text);
910 SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + advance(g, xyInde x); 897 SkScalar x = SkAutoKern_Adjust(rsb, g.fLsbDelta) + advance(g, xyInde x);
911 if ((width += x) > max) { 898 if ((width += x) > maxWidth) {
912 width -= x; 899 width -= x;
913 text = curr; 900 text = curr;
914 break; 901 break;
915 } 902 }
916 rsb = g.fRsbDelta; 903 rsb = g.fRsbDelta;
917 } 904 }
918 } else { 905 } else {
919 while (text < stop) { 906 while (text < stop) {
920 const char* curr = text; 907 const char* curr = text;
921 SkFixed x = advance(glyphCacheProc(cache, &text), xyIndex); 908 SkScalar x = advance(glyphCacheProc(cache, &text), xyIndex);
922 if ((width += x) > max) { 909 if ((width += x) > maxWidth) {
923 width -= x; 910 width -= x;
924 text = curr; 911 text = curr;
925 break; 912 break;
926 } 913 }
927 } 914 }
928 } 915 }
929 916
930 if (measuredWidth) { 917 if (measuredWidth) {
931 SkScalar scalarWidth = Sk48Dot16ToScalar(width);
932 if (scale) { 918 if (scale) {
933 scalarWidth = SkScalarMul(scalarWidth, scale); 919 width *= scale;
934 } 920 }
935 *measuredWidth = scalarWidth; 921 *measuredWidth = width;
936 } 922 }
937 923
938 // return the number of bytes measured 924 // return the number of bytes measured
939 return text - stop + length; 925 return text - stop + length;
940 } 926 }
941 927
942 /////////////////////////////////////////////////////////////////////////////// 928 ///////////////////////////////////////////////////////////////////////////////
943 929
944 static bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) { 930 static bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) {
945 *(SkPaint::FontMetrics*)context = cache->getFontMetrics(); 931 *(SkPaint::FontMetrics*)context = cache->getFontMetrics();
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 GlyphCacheProc glyphCacheProc = paint.getGlyphCacheProc(nullptr != boun ds); 1001 GlyphCacheProc glyphCacheProc = paint.getGlyphCacheProc(nullptr != boun ds);
1016 1002
1017 const char* text = (const char*)textData; 1003 const char* text = (const char*)textData;
1018 const char* stop = text + byteLength; 1004 const char* stop = text + byteLength;
1019 int count = 0; 1005 int count = 0;
1020 const int xyIndex = paint.isVerticalText() ? 1 : 0; 1006 const int xyIndex = paint.isVerticalText() ? 1 : 0;
1021 1007
1022 if (this->isDevKernText()) { 1008 if (this->isDevKernText()) {
1023 // we adjust the widths returned here through auto-kerning 1009 // we adjust the widths returned here through auto-kerning
1024 SkAutoKern autokern; 1010 SkAutoKern autokern;
1025 SkFixed prevWidth = 0; 1011 SkScalar prevWidth = 0;
1026 1012
1027 if (scale) { 1013 if (scale) {
1028 while (text < stop) { 1014 while (text < stop) {
1029 const SkGlyph& g = glyphCacheProc(cache, &text); 1015 const SkGlyph& g = glyphCacheProc(cache, &text);
1030 if (widths) { 1016 if (widths) {
1031 SkFixed adjust = autokern.adjust(g); 1017 SkScalar adjust = autokern.adjust(g);
1032 1018
1033 if (count > 0) { 1019 if (count > 0) {
1034 SkScalar w = SkFixedToScalar(prevWidth + adjust); 1020 *widths++ = SkScalarMul(prevWidth + adjust, scale);
1035 *widths++ = SkScalarMul(w, scale);
1036 } 1021 }
1037 prevWidth = advance(g, xyIndex); 1022 prevWidth = advance(g, xyIndex);
1038 } 1023 }
1039 if (bounds) { 1024 if (bounds) {
1040 set_bounds(g, bounds++, scale); 1025 set_bounds(g, bounds++, scale);
1041 } 1026 }
1042 ++count; 1027 ++count;
1043 } 1028 }
1044 if (count > 0 && widths) { 1029 if (count > 0 && widths) {
1045 *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale); 1030 *widths = SkScalarMul(prevWidth, scale);
1046 } 1031 }
1047 } else { 1032 } else {
1048 while (text < stop) { 1033 while (text < stop) {
1049 const SkGlyph& g = glyphCacheProc(cache, &text); 1034 const SkGlyph& g = glyphCacheProc(cache, &text);
1050 if (widths) { 1035 if (widths) {
1051 SkFixed adjust = autokern.adjust(g); 1036 SkScalar adjust = autokern.adjust(g);
1052 1037
1053 if (count > 0) { 1038 if (count > 0) {
1054 *widths++ = SkFixedToScalar(prevWidth + adjust); 1039 *widths++ = prevWidth + adjust;
1055 } 1040 }
1056 prevWidth = advance(g, xyIndex); 1041 prevWidth = advance(g, xyIndex);
1057 } 1042 }
1058 if (bounds) { 1043 if (bounds) {
1059 set_bounds(g, bounds++); 1044 set_bounds(g, bounds++);
1060 } 1045 }
1061 ++count; 1046 ++count;
1062 } 1047 }
1063 if (count > 0 && widths) { 1048 if (count > 0 && widths) {
1064 *widths = SkFixedToScalar(prevWidth); 1049 *widths = prevWidth;
1065 } 1050 }
1066 } 1051 }
1067 } else { // no devkern 1052 } else { // no devkern
1068 if (scale) { 1053 if (scale) {
1069 while (text < stop) { 1054 while (text < stop) {
1070 const SkGlyph& g = glyphCacheProc(cache, &text); 1055 const SkGlyph& g = glyphCacheProc(cache, &text);
1071 if (widths) { 1056 if (widths) {
1072 *widths++ = SkScalarMul(SkFixedToScalar(advance(g, xyIndex)) , 1057 *widths++ = SkScalarMul(advance(g, xyIndex),
1073 scale); 1058 scale);
1074 } 1059 }
1075 if (bounds) { 1060 if (bounds) {
1076 set_bounds(g, bounds++, scale); 1061 set_bounds(g, bounds++, scale);
1077 } 1062 }
1078 ++count; 1063 ++count;
1079 } 1064 }
1080 } else { 1065 } else {
1081 while (text < stop) { 1066 while (text < stop) {
1082 const SkGlyph& g = glyphCacheProc(cache, &text); 1067 const SkGlyph& g = glyphCacheProc(cache, &text);
1083 if (widths) { 1068 if (widths) {
1084 *widths++ = SkFixedToScalar(advance(g, xyIndex)); 1069 *widths++ = advance(g, xyIndex);
1085 } 1070 }
1086 if (bounds) { 1071 if (bounds) {
1087 set_bounds(g, bounds++); 1072 set_bounds(g, bounds++);
1088 } 1073 }
1089 ++count; 1074 ++count;
1090 } 1075 }
1091 } 1076 }
1092 } 1077 }
1093 1078
1094 SkASSERT(text == stop); 1079 SkASSERT(text == stop);
(...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after
2290 } 2275 }
2291 2276
2292 SkTextBaseIter::~SkTextBaseIter() { 2277 SkTextBaseIter::~SkTextBaseIter() {
2293 SkGlyphCache::AttachCache(fCache); 2278 SkGlyphCache::AttachCache(fCache);
2294 } 2279 }
2295 2280
2296 bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) { 2281 bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) {
2297 if (fText < fStop) { 2282 if (fText < fStop) {
2298 const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); 2283 const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
2299 2284
2300 fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(gly ph)), fScale); 2285 fXPos += SkScalarMul(fPrevAdvance + fAutoKern.adjust(glyph), fScale);
2301 fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking() ; 2286 fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking() ;
2302 2287
2303 if (glyph.fWidth) { 2288 if (glyph.fWidth) {
2304 if (path) { 2289 if (path) {
2305 *path = fCache->findPath(glyph); 2290 *path = fCache->findPath(glyph);
2306 } 2291 }
2307 } else { 2292 } else {
2308 if (path) { 2293 if (path) {
2309 *path = nullptr; 2294 *path = nullptr;
2310 } 2295 }
2311 } 2296 }
2312 if (xpos) { 2297 if (xpos) {
2313 *xpos = fXPos; 2298 *xpos = fXPos;
2314 } 2299 }
2315 return true; 2300 return true;
2316 } 2301 }
2317 return false; 2302 return false;
2318 } 2303 }
2319 2304
2320 bool SkTextInterceptsIter::next(SkScalar* array, int* count) { 2305 bool SkTextInterceptsIter::next(SkScalar* array, int* count) {
2321 const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); 2306 const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
2322 fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)) , fScale); 2307 fXPos += SkScalarMul(fPrevAdvance + fAutoKern.adjust(glyph), fScale);
2323 fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); 2308 fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking();
2324 if (fCache->findPath(glyph)) { 2309 if (fCache->findPath(glyph)) {
2325 fCache->findIntercepts(fBounds, fScale, fXPos, SkToBool(fXYIndex), 2310 fCache->findIntercepts(fBounds, fScale, fXPos, SkToBool(fXYIndex),
2326 const_cast<SkGlyph*>(&glyph), array, count); 2311 const_cast<SkGlyph*>(&glyph), array, count);
2327 } 2312 }
2328 return fText < fStop; 2313 return fText < fStop;
2329 } 2314 }
2330 2315
2331 /////////////////////////////////////////////////////////////////////////////// 2316 ///////////////////////////////////////////////////////////////////////////////
2332 2317
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2368 } 2353 }
2369 2354
2370 uint32_t SkPaint::getHash() const { 2355 uint32_t SkPaint::getHash() const {
2371 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB itfields, 2356 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB itfields,
2372 // so fBitfields should be 10 pointers and 6 32-bit values from the start. 2357 // so fBitfields should be 10 pointers and 6 32-bit values from the start.
2373 static_assert(offsetof(SkPaint, fBitfields) == 9 * sizeof(void*) + 6 * sizeo f(uint32_t), 2358 static_assert(offsetof(SkPaint, fBitfields) == 9 * sizeof(void*) + 6 * sizeo f(uint32_t),
2374 "SkPaint_notPackedTightly"); 2359 "SkPaint_notPackedTightly");
2375 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), 2360 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this),
2376 offsetof(SkPaint, fBitfields) + sizeof(fBitfields )); 2361 offsetof(SkPaint, fBitfields) + sizeof(fBitfields ));
2377 } 2362 }
OLDNEW
« no previous file with comments | « src/core/SkGlyph.h ('k') | src/core/SkTextToPathIter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698