905 SkScalar SkPaint::measure_text(SkGlyphCache* cache,
906 const char* text, size_t byteLength,
907 int* count, SkRect* bounds) const {
908 SkASSERT(count);
909 if (byteLength == 0) {
910 *count = 0;
911 if (bounds) {
912 bounds->setEmpty();
913 }
914 return 0;
915 }
916
917 SkMeasureCacheProc glyphCacheProc;
918 glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
919 NULL != bounds);
920
921 int xyIndex;
922 JoinBoundsProc joinBoundsProc;
923 if (this->isVerticalText()) {
924 xyIndex = 1;
925 joinBoundsProc = join_bounds_y;
926 } else {
927 xyIndex = 0;
928 joinBoundsProc = join_bounds_x;
929 }
930
931 int n = 1;
932 const char* stop = (const char*)text + byteLength;
933 const SkGlyph* g = &glyphCacheProc(cache, &text);
934
935
936
937 Sk48Dot16 x = advance(*g, xyIndex);
938
939 SkAutoKern autokern;
940
941 if (NULL == bounds) {
942 if (this->isDevKernText()) {
943 int rsb;
944 for (; text < stop; n++) {
945 rsb = g->fRsbDelta;
946 g = &glyphCacheProc(cache, &text);
947 x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + advance(*g, xyIndex);
948 }
949 } else {
950 for (; text < stop; n++) {
951 x += advance(glyphCacheProc(cache, &text), xyIndex);
952 }
953 }
954 } else {
955 set_bounds(*g, bounds);
956 if (this->isDevKernText()) {
957 int rsb;
958 for (; text < stop; n++) {
959 rsb = g->fRsbDelta;
960 g = &glyphCacheProc(cache, &text);
961 x += SkAutoKern_AdjustF(rsb, g->fLsbDelta);
962 joinBoundsProc(*g, bounds, x);
963 x += advance(*g, xyIndex);
964 }
965 } else {
966 for (; text < stop; n++) {
967 g = &glyphCacheProc(cache, &text);
968 joinBoundsProc(*g, bounds, x);
969 x += advance(*g, xyIndex);
970 }
971 }
972 }
973 SkASSERT(text == stop);
974
975 *count = n;
976 return Sk48Dot16ToScalar(x);
977 }
1045 size_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth,
1046 SkScalar* measuredWidth,
1047 TextBufferDirection tbd) const {
1048 if (0 == length || 0 >= maxWidth) {
1049 if (measuredWidth) {
1050 *measuredWidth = 0;
1051 }
1052 return 0;
1053 }
1054
1055 if (0 == fTextSize) {
1056 if (measuredWidth) {
1057 *measuredWidth = 0;
1058 }
1059 return length;
1060 }
1061
1062 SkASSERT(textD != NULL);
1063 const char* text = (const char*)textD;
1064
1065 SkScalar scale = 0;
1066 SkAutoRestorePaintTextSizeAndFrame restore(this);
1067
1068 if (this->isLinearText()) {
1069 scale = fTextSize / kCanonicalTextSizeForPaths;
1070 maxWidth = SkScalarMulDiv(maxWidth, kCanonicalTextSizeForPaths, fTextSize);
1071
1072 ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
1073 }
1074
1075 SkAutoGlyphCache autoCache(*this, NULL);
1076 SkGlyphCache* cache = autoCache.getCache();
1077
1078 SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(tbd, false); <==========
1079 const char* stop;
1080 SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop);
1081 const int xyIndex = this->isVerticalText() ? 1 : 0;
1082
1083 Sk48Dot16 max = SkScalarToFixed(maxWidth);
1084 Sk48Dot16 width = 0;
1085
1086 SkAutoKern autokern;
1087
1088 if (this->isDevKernText()) {
1089 int rsb = 0;
1090 while (pred(text, stop)) {
1091 const char* curr = text;
1092 const SkGlyph& g = glyphCacheProc(cache, &text);
1093 SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + advance(g, xyIndex);
1094 if ((width += x) > max) {
1095 width -= x;
1096 text = curr;
1097 break;
1098 }
1099 rsb = g.fRsbDelta;
1100 }
1101 } else {
1102 while (pred(text, stop)) {
1103 const char* curr = text;
1104 SkFixed x = advance(glyphCacheProc(cache, &text), xyIndex);
1105 if ((width += x) > max) {
1106 width -= x;
1107 text = curr;
1108 break;
1109 }
1110 }
1111 }
1112
1113 if (measuredWidth) {
1114 SkScalar scalarWidth = Sk48Dot16ToScalar(width);
1115 if (scale) {
1116 scalarWidth = SkScalarMul(scalarWidth, scale);
1117 }
1118 *measuredWidth = scalarWidth;
1119 }
1120
1121
1122 return (kForward_TextBufferDirection == tbd) ?
1123 text - stop + length : stop - text + length;
1124 }