1#include "SampleCode.h" 2#include "SkView.h" 3#include "SkCanvas.h" 4#include "SkGradientShader.h" 5#include "SkGraphics.h" 6#include "SkImageDecoder.h" 7#include "SkPackBits.h" 8#include "SkPath.h" 9#include "SkPathMeasure.h" 10#include "SkRandom.h" 11#include "SkRegion.h" 12#include "SkShader.h" 13#include "SkUtils.h" 14#include "SkColorPriv.h" 15#include "SkColorFilter.h" 16#include "SkTypeface.h" 17#include "SkAvoidXfermode.h" 18 19#define REPEAT_COUNT 0 20 21static const char gText[] = "Hamburgefons"; 22 23static bool gDevKern; 24 25static void rand_text(char text[], SkRandom& rand, size_t count) { 26 for (size_t i = 0; i < count; i++) { 27 text[i] = rand.nextU() & 0x7F; 28 } 29} 30 31static SkScalar sum_widths(const SkScalar widths[], int count) { 32 SkScalar w = 0; 33 for (int i = 0; i < count; i++) { 34 w += widths[i]; 35 } 36 return w; 37} 38 39static void test_measure(const SkPaint& paint) { 40 char text[256]; 41 SkScalar widths[256]; 42 SkRect rects[256]; 43 SkRect bounds; 44 int count = 256; 45 46 SkRandom rand; 47 48 for (int i = 0; i < 100; i++) { 49 rand_text(text, rand, 256); 50 paint.getTextWidths(text, count, widths, NULL); 51 SkDEBUGCODE(SkScalar tw0 = sum_widths(widths, count);) 52 paint.getTextWidths(text, count, widths, rects); 53 SkDEBUGCODE(SkScalar tw1 = sum_widths(widths, count);) 54 SkASSERT(tw0 == tw1); 55 56 SkDEBUGCODE(SkScalar w0 = paint.measureText(text, count, NULL);) 57 SkDEBUGCODE(SkScalar w1 = paint.measureText(text, count, &bounds);) 58 SkASSERT(w0 == w1); 59 SkASSERT(w0 == tw0); 60 61 SkRect r = rects[0]; 62 SkScalar x = 0; 63 for (int j = 1; j < count; j++) { 64 x += widths[j-1]; 65 rects[j].offset(x, 0); 66 r.join(rects[j]); 67 } 68 SkASSERT(r == bounds); 69 70 if (r != bounds) { 71 printf("flags=%x i=%d [%g %g %g %g] [%g %g %g %g]\n", 72 paint.getFlags(), i, 73 SkScalarToFloat(r.fLeft), 74 SkScalarToFloat(r.fTop), 75 SkScalarToFloat(r.fRight), 76 SkScalarToFloat(r.fBottom), 77 SkScalarToFloat(bounds.fLeft), 78 SkScalarToFloat(bounds.fTop), 79 SkScalarToFloat(bounds.fRight), 80 SkScalarToFloat(bounds.fBottom)); 81 } 82 } 83} 84 85static void test_measure() { 86 SkPaint paint; 87 88 for (int i = 0; i <= SkPaint::kAllFlags; i++) { 89 paint.setFlags(i); 90 test_measure(paint); 91 } 92} 93 94////////////////////////////////////////////////////////////////////////////// 95 96static void test_textBounds(SkCanvas* canvas) { 97// canvas->scale(SK_Scalar1/2, SK_Scalar1/2); 98 99// canvas->rotate(SkIntToScalar(30)); 100 101 gDevKern = !gDevKern; 102 103 SkScalar x = SkIntToScalar(50); 104 SkScalar y = SkIntToScalar(150); 105 SkScalar w[100]; 106 SkRect r[100], bounds; 107 108 SkPaint paint; 109 paint.setTextSize(SkIntToScalar(64)); 110 paint.setAntiAlias(true); 111 paint.setDevKernText(gDevKern); 112 113 (void)paint.measureText(gText, strlen(gText), &bounds, NULL); 114 paint.setColor(SK_ColorGREEN); 115 bounds.offset(x, y); 116 canvas->drawRect(bounds, paint); 117 118 int count = paint.getTextWidths(gText, strlen(gText), w, r); 119 120 paint.setColor(SK_ColorRED); 121 for (int i = 0; i < count; i++) { 122 r[i].offset(x, y); 123 canvas->drawRect(r[i], paint); 124 x += w[i]; 125 } 126 x = SkIntToScalar(50); 127 paint.setColor(gDevKern ? SK_ColorDKGRAY : SK_ColorBLACK); 128 canvas->drawText(gText, strlen(gText), x, y, paint); 129} 130 131static void create_src(SkBitmap* bitmap, SkBitmap::Config config) { 132 bitmap->setConfig(config, 100, 100); 133 bitmap->allocPixels(); 134 bitmap->eraseColor(0); 135 136 SkCanvas canvas(*bitmap); 137 SkPaint paint; 138 139 paint.setAntiAlias(true); 140 canvas.drawCircle(SkIntToScalar(50), SkIntToScalar(50), 141 SkIntToScalar(50), paint); 142} 143 144static void blur(SkBitmap* dst, const SkBitmap& src, SkScalar radius) { 145 *dst = src; 146} 147 148static void test_bitmap_blur(SkCanvas* canvas) { 149 SkBitmap src, dst; 150 151 create_src(&src, SkBitmap::kARGB_8888_Config); 152 blur(&dst, src, SkIntToScalar(4)); 153 154 SkPaint paint; 155 156 paint.setColor(SK_ColorRED); 157 158 canvas->drawBitmap(dst, SkIntToScalar(30), SkIntToScalar(60), &paint); 159} 160 161static SkScalar getpathlen(const SkPath& path) { 162 SkPathMeasure meas(path, false); 163 return meas.getLength(); 164} 165 166static void test_textpathmatrix(SkCanvas* canvas) { 167 SkPaint paint; 168 SkPath path; 169 SkMatrix matrix; 170 171 path.moveTo(SkIntToScalar(200), SkIntToScalar(300)); 172 path.quadTo(SkIntToScalar(400), SkIntToScalar(100), 173 SkIntToScalar(600), SkIntToScalar(300)); 174 175 paint.setAntiAlias(true); 176 177 paint.setStyle(SkPaint::kStroke_Style); 178 // canvas->drawPath(path, paint); 179 paint.setStyle(SkPaint::kFill_Style); 180 paint.setTextSize(SkIntToScalar(48)); 181 paint.setTextAlign(SkPaint::kRight_Align); 182 183 const char* text = "Reflection"; 184 size_t len = strlen(text); 185 SkScalar pathLen = getpathlen(path); 186 187 canvas->drawTextOnPath(text, len, path, NULL, paint); 188 189 paint.setColor(SK_ColorRED); 190 matrix.setScale(-SK_Scalar1, SK_Scalar1); 191 matrix.postTranslate(pathLen, 0); 192 canvas->drawTextOnPath(text, len, path, &matrix, paint); 193 194 paint.setColor(SK_ColorBLUE); 195 matrix.setScale(SK_Scalar1, -SK_Scalar1); 196 canvas->drawTextOnPath(text, len, path, &matrix, paint); 197 198 paint.setColor(SK_ColorGREEN); 199 matrix.setScale(-SK_Scalar1, -SK_Scalar1); 200 matrix.postTranslate(pathLen, 0); 201 canvas->drawTextOnPath(text, len, path, &matrix, paint); 202} 203 204class TextOnPathView : public SampleView { 205public: 206 SkPath fPath; 207 SkScalar fHOffset; 208 209 TextOnPathView() { 210 SkRect r; 211 r.set(SkIntToScalar(100), SkIntToScalar(100), 212 SkIntToScalar(300), SkIntToScalar(300)); 213 fPath.addOval(r); 214 fPath.offset(SkIntToScalar(200), 0); 215 216 fHOffset = SkIntToScalar(50); 217 } 218 219protected: 220 // overrides from SkEventSink 221 virtual bool onQuery(SkEvent* evt) { 222 if (SampleCode::TitleQ(*evt)) { 223 SampleCode::TitleR(evt, "Text On Path"); 224 return true; 225 } 226 return this->INHERITED::onQuery(evt); 227 } 228 229 virtual void onDrawContent(SkCanvas* canvas) { 230 SkPaint paint; 231 232 paint.setAntiAlias(true); 233 paint.setTextSize(SkIntToScalar(50)); 234 235 for (int j = 0; j < REPEAT_COUNT; j++) { 236 SkScalar x = fHOffset; 237 238 paint.setColor(SK_ColorBLACK); 239 canvas->drawTextOnPathHV(gText, sizeof(gText)-1, fPath, 240 x, paint.getTextSize()/2, paint); 241 242 paint.setColor(SK_ColorRED); 243 canvas->drawTextOnPathHV(gText, sizeof(gText)-1, fPath, 244 x + SkIntToScalar(50), 0, paint); 245 246 paint.setColor(SK_ColorBLUE); 247 canvas->drawTextOnPathHV(gText, sizeof(gText)-1, fPath, 248 x + SkIntToScalar(100), -paint.getTextSize()/2, paint); 249 } 250 251 paint.setColor(SK_ColorGREEN); 252 paint.setStyle(SkPaint::kStroke_Style); 253// canvas->drawPath(fPath, paint); 254 255 canvas->translate(0, SkIntToScalar(100)); 256 test_textpathmatrix(canvas); 257 258 if (REPEAT_COUNT > 1) 259 this->inval(NULL); 260 } 261 262 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { 263 fHints += 1; 264 this->inval(NULL); 265 return this->INHERITED::onFindClickHandler(x, y); 266 } 267 268 virtual bool onClick(Click* click) { 269 return this->INHERITED::onClick(click); 270 } 271 272private: 273 int fHints; 274 typedef SampleView INHERITED; 275}; 276 277////////////////////////////////////////////////////////////////////////////// 278 279static SkView* MyFactory() { 280 return new TextOnPathView; 281} 282 283static SkViewRegister reg(MyFactory); 284 285