のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

MesureText

   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     // our accumulated fixed-point advances might overflow 16.16, so we use
    935     // a 48.16 (64bit) accumulator, and then convert that to scalar at the
    936     // very end.
    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         // this gets restored by restore
   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     // use 64bits for our accumulator, to avoid overflowing 16.16
   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     // return the number of bytes measured
   1122     return (kForward_TextBufferDirection == tbd) ?
   1123                 text - stop + length : stop - text + length;
   1124 }