1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SampleCode.h" 9 #include "SkView.h" 10 #include "SkCanvas.h" 11 #include "SkReadBuffer.h" 12 #include "SkWriteBuffer.h" 13 #include "SkGradientShader.h" 14 #include "SkGraphics.h" 15 #include "SkImageDecoder.h" 16 #include "SkPath.h" 17 #include "SkRandom.h" 18 #include "SkRegion.h" 19 #include "SkShader.h" 20 #include "SkUtils.h" 21 #include "SkColorPriv.h" 22 #include "SkColorFilter.h" 23 #include "SkTime.h" 24 #include "SkTypeface.h" 25 #include "SkXfermode.h" 26 27 #include "SkStream.h" 28 #include "SkXMLParser.h" 29 30 static void test_breakText() { 31 SkPaint paint; 32 const char* text = "sdfkljAKLDFJKEWkldfjlk#$%&sdfs.dsj"; 33 size_t length = strlen(text); 34 SkScalar width = paint.measureText(text, length); 35 36 SkScalar mm = 0; 37 SkScalar nn = 0; 38 for (SkScalar w = 0; w <= width; w += SK_Scalar1) { 39 SkScalar m; 40 size_t n = paint.breakText(text, length, w, &m, 41 SkPaint::kBackward_TextBufferDirection); 42 43 SkASSERT(n <= length); 44 SkASSERT(m <= width); 45 46 if (n == 0) { 47 SkASSERT(m == 0); 48 } else { 49 // now assert that we're monotonic 50 if (n == nn) { 51 SkASSERT(m == mm); 52 } else { 53 SkASSERT(n > nn); 54 SkASSERT(m > mm); 55 } 56 } 57 nn = SkIntToScalar((unsigned int)n); 58 mm = m; 59 } 60 61 SkDEBUGCODE(size_t length2 =) paint.breakText(text, length, width, &mm); 62 SkASSERT(length2 == length); 63 SkASSERT(mm == width); 64 } 65 66 static const struct { 67 const char* fName; 68 uint32_t fFlags; 69 bool fFlushCache; 70 } gHints[] = { 71 { "Linear", SkPaint::kLinearText_Flag, false }, 72 { "Normal", 0, true }, 73 { "Subpixel", SkPaint::kSubpixelText_Flag, true } 74 }; 75 76 static void DrawTheText(SkCanvas* canvas, const char text[], size_t length, SkScalar x, SkScalar y, 77 const SkPaint& paint, SkScalar clickX) { 78 SkPaint p(paint); 79 80 #if 0 81 canvas->drawText(text, length, x, y, paint); 82 #else 83 { 84 SkPoint pts[1000]; 85 SkScalar xpos = x; 86 SkASSERT(length <= SK_ARRAY_COUNT(pts)); 87 for (size_t i = 0; i < length; i++) { 88 pts[i].set(xpos, y), xpos += paint.getTextSize(); 89 } 90 canvas->drawPosText(text, length, pts, paint); 91 } 92 #endif 93 94 p.setSubpixelText(true); 95 x += SkIntToScalar(180); 96 canvas->drawText(text, length, x, y, p); 97 98 #ifdef SK_DEBUG 99 if (true) { 100 p.setSubpixelText(false); 101 p.setLinearText(true); 102 x += SkIntToScalar(180); 103 canvas->drawText(text, length, x, y, p); 104 } 105 #endif 106 } 107 108 class TextSpeedView : public SampleView { 109 public: 110 TextSpeedView() { 111 fHints = 0; 112 fClickX = 0; 113 114 test_breakText(); 115 } 116 117 protected: 118 // overrides from SkEventSink 119 virtual bool onQuery(SkEvent* evt) { 120 if (SampleCode::TitleQ(*evt)) { 121 SampleCode::TitleR(evt, "Text"); 122 return true; 123 } 124 return this->INHERITED::onQuery(evt); 125 } 126 127 static void make_textstrip(SkBitmap* bm) { 128 bm->allocPixels(SkImageInfo::Make(200, 18, kRGB_565_SkColorType, 129 kOpaque_SkAlphaType)); 130 bm->eraseColor(SK_ColorWHITE); 131 132 SkCanvas canvas(*bm); 133 SkPaint paint; 134 const char* s = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit"; 135 136 paint.setFlags(paint.getFlags() | SkPaint::kAntiAlias_Flag 137 | SkPaint::kDevKernText_Flag); 138 paint.setTextSize(SkIntToScalar(14)); 139 canvas.drawText(s, strlen(s), SkIntToScalar(8), SkIntToScalar(14), paint); 140 } 141 142 static void fill_pts(SkPoint pts[], size_t n, SkRandom* rand) { 143 for (size_t i = 0; i < n; i++) 144 pts[i].set(rand->nextUScalar1() * 640, rand->nextUScalar1() * 480); 145 } 146 147 virtual void onDrawContent(SkCanvas* canvas) { 148 SkAutoCanvasRestore restore(canvas, false); 149 { 150 SkRect r; 151 r.set(0, 0, SkIntToScalar(1000), SkIntToScalar(20)); 152 // canvas->saveLayer(&r, NULL, SkCanvas::kHasAlphaLayer_SaveFlag); 153 } 154 155 SkPaint paint; 156 // const uint16_t glyphs[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 }; 157 int index = fHints % SK_ARRAY_COUNT(gHints); 158 index = 1; 159 // const char* style = gHints[index].fName; 160 161 // canvas->translate(0, SkIntToScalar(50)); 162 163 // canvas->drawText(style, strlen(style), SkIntToScalar(20), SkIntToScalar(20), paint); 164 165 SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromFile("/skimages/samplefont.ttf"))); 166 paint.setAntiAlias(true); 167 paint.setFlags(paint.getFlags() | gHints[index].fFlags); 168 169 SkRect clip; 170 clip.set(SkIntToScalar(25), SkIntToScalar(34), SkIntToScalar(88), SkIntToScalar(155)); 171 172 const char* text = "Hamburgefons"; 173 size_t length = strlen(text); 174 175 SkScalar y = SkIntToScalar(0); 176 for (int i = 9; i <= 24; i++) { 177 paint.setTextSize(SkIntToScalar(i) /*+ (gRand.nextU() & 0xFFFF)*/); 178 for (SkScalar dx = 0; dx <= SkIntToScalar(3)/4; 179 dx += SkIntToScalar(1) /* /4 */) { 180 y += paint.getFontSpacing(); 181 DrawTheText(canvas, text, length, SkIntToScalar(20) + dx, y, paint, fClickX); 182 } 183 } 184 if (gHints[index].fFlushCache) { 185 // SkGraphics::SetFontCacheUsed(0); 186 } 187 } 188 189 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, 190 unsigned modi) SK_OVERRIDE { 191 fClickX = x; 192 this->inval(NULL); 193 return this->INHERITED::onFindClickHandler(x, y, modi); 194 } 195 196 virtual bool onClick(Click* click) { 197 return this->INHERITED::onClick(click); 198 } 199 200 private: 201 int fHints; 202 SkScalar fClickX; 203 204 typedef SampleView INHERITED; 205 }; 206 207 ////////////////////////////////////////////////////////////////////////////// 208 209 static SkView* MyFactory() { return new TextSpeedView; } 210 static SkViewRegister reg(MyFactory); 211