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