| #include "SampleCode.h" | 
 | #include "SkView.h" | 
 | #include "SkCanvas.h" | 
 | #include "SkGradientShader.h" | 
 | #include "SkGraphics.h" | 
 | #include "SkImageDecoder.h" | 
 | #include "SkPackBits.h" | 
 | #include "SkPath.h" | 
 | #include "SkPathMeasure.h" | 
 | #include "SkRandom.h" | 
 | #include "SkRegion.h" | 
 | #include "SkShader.h" | 
 | #include "SkUtils.h" | 
 | #include "SkColorPriv.h" | 
 | #include "SkColorFilter.h" | 
 | #include "SkTypeface.h" | 
 | #include "SkAvoidXfermode.h" | 
 |  | 
 | #define REPEAT_COUNT    0 | 
 |  | 
 | static const char gText[] = "Hamburgefons"; | 
 |  | 
 | static bool gDevKern; | 
 |  | 
 | static void rand_text(char text[], SkRandom& rand, size_t count) { | 
 |     for (size_t i = 0; i < count; i++) { | 
 |         text[i] = rand.nextU() & 0x7F; | 
 |     } | 
 | } | 
 |  | 
 | static SkScalar sum_widths(const SkScalar widths[], int count) { | 
 |     SkScalar w = 0; | 
 |     for (int i = 0; i < count; i++) { | 
 |         w += widths[i]; | 
 |     } | 
 |     return w; | 
 | } | 
 |  | 
 | static void test_measure(const SkPaint& paint) { | 
 |     char        text[256]; | 
 |     SkScalar    widths[256]; | 
 |     SkRect      rects[256]; | 
 |     SkRect      bounds; | 
 |     int         count = 256; | 
 |      | 
 |     SkRandom rand; | 
 |      | 
 |     for (int i = 0; i < 100; i++) { | 
 |         rand_text(text, rand, 256); | 
 |         paint.getTextWidths(text, count, widths, NULL); | 
 |         SkDEBUGCODE(SkScalar tw0 = sum_widths(widths, count);) | 
 |         paint.getTextWidths(text, count, widths, rects); | 
 |         SkDEBUGCODE(SkScalar tw1 = sum_widths(widths, count);) | 
 |         SkASSERT(tw0 == tw1); | 
 |  | 
 |         SkDEBUGCODE(SkScalar w0 = paint.measureText(text, count, NULL);) | 
 |         SkDEBUGCODE(SkScalar w1 = paint.measureText(text, count, &bounds);) | 
 |         SkASSERT(w0 == w1); | 
 |         SkASSERT(w0 == tw0); | 
 |          | 
 |         SkRect r = rects[0]; | 
 |         SkScalar x = 0; | 
 |         for (int j = 1; j < count; j++) { | 
 |             x += widths[j-1]; | 
 |             rects[j].offset(x, 0); | 
 |             r.join(rects[j]); | 
 |         } | 
 |         SkASSERT(r == bounds); | 
 |          | 
 |         if (r != bounds) { | 
 |             printf("flags=%x i=%d [%g %g %g %g] [%g %g %g %g]\n", | 
 |                    paint.getFlags(), i, | 
 |                    SkScalarToFloat(r.fLeft), | 
 |                    SkScalarToFloat(r.fTop), | 
 |                    SkScalarToFloat(r.fRight), | 
 |                    SkScalarToFloat(r.fBottom), | 
 |                    SkScalarToFloat(bounds.fLeft), | 
 |                    SkScalarToFloat(bounds.fTop), | 
 |                    SkScalarToFloat(bounds.fRight), | 
 |                    SkScalarToFloat(bounds.fBottom)); | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | static void test_measure() { | 
 |     SkPaint paint; | 
 |      | 
 |     for (int i = 0; i <= SkPaint::kAllFlags; i++) { | 
 |         paint.setFlags(i); | 
 |         test_measure(paint); | 
 |     } | 
 | } | 
 |  | 
 | ////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | static void test_textBounds(SkCanvas* canvas) { | 
 | //    canvas->scale(SK_Scalar1/2, SK_Scalar1/2); | 
 |      | 
 | //    canvas->rotate(SkIntToScalar(30)); | 
 |  | 
 |     gDevKern = !gDevKern; | 
 |  | 
 |     SkScalar x = SkIntToScalar(50); | 
 |     SkScalar y = SkIntToScalar(150); | 
 |     SkScalar w[100]; | 
 |     SkRect   r[100], bounds; | 
 |      | 
 |     SkPaint paint; | 
 |     paint.setTextSize(SkIntToScalar(64)); | 
 |     paint.setAntiAlias(true); | 
 |     paint.setDevKernText(gDevKern); | 
 |      | 
 |     (void)paint.measureText(gText, strlen(gText), &bounds, NULL); | 
 |     paint.setColor(SK_ColorGREEN); | 
 |     bounds.offset(x, y); | 
 |     canvas->drawRect(bounds, paint); | 
 |  | 
 |     int count = paint.getTextWidths(gText, strlen(gText), w, r); | 
 |  | 
 |     paint.setColor(SK_ColorRED); | 
 |     for (int i = 0; i < count; i++) { | 
 |         r[i].offset(x, y); | 
 |         canvas->drawRect(r[i], paint); | 
 |         x += w[i]; | 
 |     } | 
 |     x = SkIntToScalar(50); | 
 |     paint.setColor(gDevKern ? SK_ColorDKGRAY : SK_ColorBLACK); | 
 |     canvas->drawText(gText, strlen(gText), x, y, paint); | 
 | } | 
 |  | 
 | static void create_src(SkBitmap* bitmap, SkBitmap::Config config) { | 
 |     bitmap->setConfig(config, 100, 100); | 
 |     bitmap->allocPixels(); | 
 |     bitmap->eraseColor(0); | 
 |      | 
 |     SkCanvas    canvas(*bitmap); | 
 |     SkPaint     paint; | 
 |  | 
 |     paint.setAntiAlias(true); | 
 |     canvas.drawCircle(SkIntToScalar(50), SkIntToScalar(50), | 
 |                       SkIntToScalar(50), paint); | 
 | } | 
 |  | 
 | static void blur(SkBitmap* dst, const SkBitmap& src, SkScalar radius) { | 
 |     *dst = src; | 
 | } | 
 |  | 
 | static void test_bitmap_blur(SkCanvas* canvas) { | 
 |     SkBitmap    src, dst; | 
 |      | 
 |     create_src(&src, SkBitmap::kARGB_8888_Config); | 
 |     blur(&dst, src, SkIntToScalar(4)); | 
 |      | 
 |     SkPaint paint; | 
 |      | 
 |     paint.setColor(SK_ColorRED); | 
 |  | 
 |     canvas->drawBitmap(dst, SkIntToScalar(30), SkIntToScalar(60), &paint); | 
 | } | 
 |  | 
 | static SkScalar getpathlen(const SkPath& path) { | 
 |     SkPathMeasure   meas(path, false); | 
 |     return meas.getLength(); | 
 | } | 
 |  | 
 | static void test_textpathmatrix(SkCanvas* canvas) { | 
 |     SkPaint paint; | 
 |     SkPath  path; | 
 |     SkMatrix matrix; | 
 |      | 
 |     path.moveTo(SkIntToScalar(200), SkIntToScalar(300)); | 
 |     path.quadTo(SkIntToScalar(400), SkIntToScalar(100), | 
 |                 SkIntToScalar(600), SkIntToScalar(300)); | 
 |  | 
 |     paint.setAntiAlias(true); | 
 |      | 
 |     paint.setStyle(SkPaint::kStroke_Style); | 
 |  //   canvas->drawPath(path, paint); | 
 |     paint.setStyle(SkPaint::kFill_Style); | 
 |     paint.setTextSize(SkIntToScalar(48)); | 
 |     paint.setTextAlign(SkPaint::kRight_Align); | 
 |      | 
 |     const char* text = "Reflection"; | 
 |     size_t      len = strlen(text); | 
 |     SkScalar    pathLen = getpathlen(path); | 
 |  | 
 |     canvas->drawTextOnPath(text, len, path, NULL, paint); | 
 |      | 
 |     paint.setColor(SK_ColorRED); | 
 |     matrix.setScale(-SK_Scalar1, SK_Scalar1); | 
 |     matrix.postTranslate(pathLen, 0); | 
 |     canvas->drawTextOnPath(text, len, path, &matrix, paint); | 
 |      | 
 |     paint.setColor(SK_ColorBLUE); | 
 |     matrix.setScale(SK_Scalar1, -SK_Scalar1); | 
 |     canvas->drawTextOnPath(text, len, path, &matrix, paint); | 
 |      | 
 |     paint.setColor(SK_ColorGREEN); | 
 |     matrix.setScale(-SK_Scalar1, -SK_Scalar1); | 
 |     matrix.postTranslate(pathLen, 0); | 
 |     canvas->drawTextOnPath(text, len, path, &matrix, paint); | 
 | } | 
 |  | 
 | class TextOnPathView : public SampleView { | 
 | public: | 
 |     SkPath      fPath; | 
 |     SkScalar    fHOffset; | 
 |  | 
 | 	TextOnPathView() { | 
 |         SkRect r; | 
 |         r.set(SkIntToScalar(100), SkIntToScalar(100), | 
 |               SkIntToScalar(300), SkIntToScalar(300)); | 
 |         fPath.addOval(r); | 
 |         fPath.offset(SkIntToScalar(200), 0); | 
 |  | 
 |         fHOffset = SkIntToScalar(50); | 
 |     } | 
 |  | 
 | protected: | 
 |     // overrides from SkEventSink | 
 |     virtual bool onQuery(SkEvent* evt) { | 
 |         if (SampleCode::TitleQ(*evt)) { | 
 |             SampleCode::TitleR(evt, "Text On Path"); | 
 |             return true; | 
 |         } | 
 |         return this->INHERITED::onQuery(evt); | 
 |     } | 
 |      | 
 |     virtual void onDrawContent(SkCanvas* canvas) { | 
 |         SkPaint paint; | 
 |          | 
 |         paint.setAntiAlias(true); | 
 |         paint.setTextSize(SkIntToScalar(50)); | 
 |  | 
 |         for (int j = 0; j < REPEAT_COUNT; j++) { | 
 |             SkScalar x = fHOffset; | 
 |  | 
 |             paint.setColor(SK_ColorBLACK); | 
 |             canvas->drawTextOnPathHV(gText, sizeof(gText)-1, fPath, | 
 |                                      x, paint.getTextSize()/2, paint); | 
 |  | 
 |             paint.setColor(SK_ColorRED); | 
 |             canvas->drawTextOnPathHV(gText, sizeof(gText)-1, fPath, | 
 |                                      x + SkIntToScalar(50), 0, paint); | 
 |  | 
 |             paint.setColor(SK_ColorBLUE); | 
 |             canvas->drawTextOnPathHV(gText, sizeof(gText)-1, fPath, | 
 |                          x + SkIntToScalar(100), -paint.getTextSize()/2, paint); | 
 |         } | 
 |          | 
 |         paint.setColor(SK_ColorGREEN); | 
 |         paint.setStyle(SkPaint::kStroke_Style); | 
 | //        canvas->drawPath(fPath, paint); | 
 |          | 
 |         canvas->translate(0, SkIntToScalar(100)); | 
 |         test_textpathmatrix(canvas); | 
 |          | 
 |         if (REPEAT_COUNT > 1) | 
 |             this->inval(NULL); | 
 |     } | 
 |      | 
 |     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { | 
 |         fHints += 1; | 
 |         this->inval(NULL); | 
 |         return this->INHERITED::onFindClickHandler(x, y); | 
 |     } | 
 |      | 
 |     virtual bool onClick(Click* click) { | 
 |         return this->INHERITED::onClick(click); | 
 |     } | 
 |      | 
 | private: | 
 |     int fHints; | 
 |     typedef SampleView INHERITED; | 
 | }; | 
 |  | 
 | ////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | static SkView* MyFactory() { | 
 |     return new TextOnPathView; | 
 | } | 
 |  | 
 | static SkViewRegister reg(MyFactory); | 
 |  |