SampleText.cpp revision 54924243c1b65b3ee6d8fa064b50a9b1bb2a19a5
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "Sk64.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGraphics.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkImageDecoder.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkKernel33MaskFilter.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRandom.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h" 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTime.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypeface.h" 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h" 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h" 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXMLParser.h" 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const int gKernel[3][3] = { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// { -1, -2, -1 }, { -2, 12, -2 }, { -1, -2, -1 } 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1, 2, 1 }, { 2, 64-12, 2 }, { 1, 2, 1 } 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const int gShift = 6; 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass ReduceNoise : public SkKernel33ProcMaskFilter { 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ReduceNoise(int percent256) : SkKernel33ProcMaskFilter(percent256) {} 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual uint8_t computeValue(uint8_t* const* srcRows) 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int c = srcRows[1][1]; 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int min = 255, max = 0; 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 3; i++) 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int j = 0; j < 3; j++) 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (i != 1 || j != 1) 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int v = srcRows[i][j]; 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (max < v) 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com max = v; 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (min > v) 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com min = v; 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (c > max) c = max; 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if (c < min) c = min; 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return c; 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 57ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(ReduceNoise) 58ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ReduceNoise(SkFlattenableReadBuffer& rb) : SkKernel33ProcMaskFilter(rb) {} 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Darken : public SkKernel33ProcMaskFilter { 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Darken(int percent256) : SkKernel33ProcMaskFilter(percent256) {} 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual uint8_t computeValue(uint8_t* const* srcRows) 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int c = srcRows[1][1]; 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com float f = c / 255.f; 7082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 719e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com if (c >= 0) { 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com f = sqrtf(f); 739e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com } else { 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com f *= f; 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(f >= 0 && f <= 1); 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (int)(f * 255); 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 79ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Darken) 80ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Darken(SkFlattenableReadBuffer& rb) : SkKernel33ProcMaskFilter(rb) {} 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkMaskFilter* makemf() { return new Darken(0x30); } 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 879e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.comstatic void test_breakText() { 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = "sdfkljAKLDFJKEWkldfjlk#$%&sdfs.dsj"; 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t length = strlen(text); 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar width = paint.measureText(text, length); 9282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar mm = 0; 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar nn = 0; 959e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com for (SkScalar w = 0; w <= width; w += SK_Scalar1) { 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar m; 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t n = paint.breakText(text, length, w, &m, 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint::kBackward_TextBufferDirection); 9982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(n <= length); 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(m <= width); 10282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 1039e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com if (n == 0) { 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(m == 0); 1059e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com } else { 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now assert that we're monotonic 1079e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com if (n == nn) { 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(m == mm); 1099e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com } else { 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(n > nn); 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(m > mm); 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 114261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com nn = SkIntToScalar(n); 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mm = m; 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11864cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org SkDEBUGCODE(size_t length2 =) paint.breakText(text, length, width, &mm); 119261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com SkASSERT(length2 == length); 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(mm == width); 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkRandom gRand; 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkPowerMode : public SkXfermode { 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPowerMode(SkScalar exponent) { this->init(exponent); } 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1299e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count, 1309e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com const SkAlpha aa[]); 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&); 13382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 134ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPowerMode) 13582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar fExp; // user's value 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint8_t fTable[256]; // cache 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void init(SkScalar exponent); 14154924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com SkPowerMode(SkFlattenableReadBuffer& b) : INHERITED(b) { 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // read the exponent 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->init(SkFixedToScalar(b.readS32())); 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14554924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com virtual void flatten(SkFlattenableWriteBuffer& b) const SK_OVERRIDE { 14654924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com this->INHERITED::flatten(b); 14754924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com b.write32(SkScalarToFixed(fExp)); 14854924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com } 14982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkXfermode INHERITED; 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1539e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.comvoid SkPowerMode::init(SkScalar e) { 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fExp = e; 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com float ee = SkScalarToFloat(e); 15682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com printf("------ %g\n", ee); 1589e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com for (int i = 0; i < 256; i++) { 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com float x = i / 255.f; 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // printf(" %d %g", i, x); 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x = powf(x, ee); 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // printf(" %g", x); 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int xx = SkScalarRound(SkFloatToScalar(x * 255)); 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // printf(" %d\n", xx); 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTable[i] = SkToU8(xx); 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1699e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.comvoid SkPowerMode::xfer16(uint16_t dst[], const SkPMColor src[], int count, 1709e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com const SkAlpha aa[]) { 1719e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com for (int i = 0; i < count; i++) { 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor c = src[i]; 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int r = SkGetPackedR32(c); 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int g = SkGetPackedG32(c); 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int b = SkGetPackedB32(c); 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r = fTable[r]; 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = fTable[g]; 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com b = fTable[b]; 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dst[i] = SkPack888ToRGB16(r, g, b); 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const struct { 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fName; 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t fFlags; 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool fFlushCache; 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} gHints[] = { 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "Linear", SkPaint::kLinearText_Flag, false }, 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "Normal", 0, true }, 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { "Subpixel", SkPaint::kSubpixelText_Flag, true } 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1939e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.comstatic int count_char_points(const SkPaint& paint, char c) { 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 19582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.getTextPath(&c, 1, 0, 0, &path); 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return path.getPoints(NULL, 0); 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic int gOld, gNew, gCount; 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2029e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.comstatic void dump(int c, int oldc, int newc) { 2039e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com if (oldc != newc) { 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gOld += oldc; 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gNew += newc; 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gCount += 1; 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com printf("char %c: old = %3d, new = %3d, reduction %g%%\n", c, oldc, newc, 100. * (oldc - newc) / oldc); 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2119e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.comstatic void tab(int n) { 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// printf("[%d] ", n); return; 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(n >= 0); 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < n; i++) 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com printf(" "); 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2189e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.comstatic void draw_rgn(const SkRegion& rgn, SkCanvas* canvas, const SkPaint& paint) { 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::Iterator iter(rgn); 22182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2229e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com for (; !iter.done(); iter.next()) { 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(iter.rect()); 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawRect(r, paint); 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void test_break(SkCanvas* canvas, const char text[], size_t length, 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x, SkScalar y, const SkPaint& paint, 2309e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com SkScalar clickX) { 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint linePaint; 23282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com linePaint.setAntiAlias(true); 23482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar measured; 23682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2379e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com if (paint.breakText(text, length, clickX - x, &measured, 2389e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com SkPaint::kForward_TextBufferDirection)) { 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com linePaint.setColor(SK_ColorRED); 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawLine(x, y, x + measured, y, linePaint); 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += paint.measureText(text, length); 2449e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com if (paint.breakText(text, length, x - clickX, &measured, 2459e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com SkPaint::kBackward_TextBufferDirection)) { 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com linePaint.setColor(SK_ColorBLUE); 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawLine(x - measured, y, x, y, linePaint); 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void DrawTheText(SkCanvas* canvas, const char text[], size_t length, 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x, SkScalar y, const SkPaint& paint, 2539e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com SkScalar clickX, SkMaskFilter* mf) { 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint p(paint); 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawText(text, length, x, y, paint); 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[1000]; 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar xpos = x; 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(length <= SK_ARRAY_COUNT(pts)); 2639e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com for (size_t i = 0; i < length; i++) { 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[i].set(xpos, y), xpos += paint.getTextSize(); 2659e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com } 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawPosText(text, length, pts, paint); 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com p.setSubpixelText(true); 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += SkIntToScalar(180); 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawText(text, length, x, y, p); 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2759e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com if (true) { 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // p.setMaskFilter(mf); 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com p.setSubpixelText(false); 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com p.setLinearText(true); 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += SkIntToScalar(180); 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawText(text, length, x, y, p); 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2859e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.comclass TextSpeedView : public SampleView { 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2879e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com TextSpeedView() { 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMF = makemf(); 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fHints = 0; 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClickX = 0; 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com test_breakText(); 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2969e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com virtual ~TextSpeedView() { 29782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fMF); 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected: 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overrides from SkEventSink 3029e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com virtual bool onQuery(SkEvent* evt) { 3039e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com if (SampleCode::TitleQ(*evt)) { 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SampleCode::TitleR(evt, "Text"); 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->INHERITED::onQuery(evt); 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 30982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3109e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com static void make_textstrip(SkBitmap* bm) { 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bm->setConfig(SkBitmap::kRGB_565_Config, 200, 18); 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bm->allocPixels(); 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bm->eraseColor(SK_ColorWHITE); 31482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas canvas(*bm); 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* s = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit"; 31882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setFlags(paint.getFlags() | SkPaint::kAntiAlias_Flag 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com | SkPaint::kDevKernText_Flag); 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setTextSize(SkIntToScalar(14)); 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas.drawText(s, strlen(s), SkIntToScalar(8), SkIntToScalar(14), paint); 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 32482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3259e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com static void fill_pts(SkPoint pts[], size_t n, SkRandom* rand) { 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (size_t i = 0; i < n; i++) 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[i].set(rand->nextUScalar1() * 640, rand->nextUScalar1() * 480); 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 32982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3309e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com virtual void onDrawContent(SkCanvas* canvas) { 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoCanvasRestore restore(canvas, false); 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(0, 0, SkIntToScalar(1000), SkIntToScalar(20)); 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // canvas->saveLayer(&r, NULL, SkCanvas::kHasAlphaLayer_SaveFlag); 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// const uint16_t glyphs[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 }; 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = fHints % SK_ARRAY_COUNT(gHints); 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com index = 1; 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// const char* style = gHints[index].fName; 34382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// canvas->translate(0, SkIntToScalar(50)); 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // canvas->drawText(style, strlen(style), SkIntToScalar(20), SkIntToScalar(20), paint); 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34804d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromFile("/skimages/samplefont.ttf"))); 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setAntiAlias(true); 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setFlags(paint.getFlags() | gHints[index].fFlags); 35182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect clip; 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com clip.set(SkIntToScalar(25), SkIntToScalar(34), SkIntToScalar(88), SkIntToScalar(155)); 35482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = "Hamburgefons"; 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t length = strlen(text); 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3582f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com SkScalar y = SkIntToScalar(0); 3592f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com for (int i = 9; i <= 24; i++) { 3602f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com paint.setTextSize(SkIntToScalar(i) /*+ (gRand.nextU() & 0xFFFF)*/); 3619e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com for (SkScalar dx = 0; dx <= SkIntToScalar(3)/4; 3629e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com dx += SkIntToScalar(1) /* /4 */) { 3632f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com y += paint.getFontSpacing(); 3649e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com DrawTheText(canvas, text, length, SkIntToScalar(20) + dx, y, 3659e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com paint, fClickX, fMF); 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3682f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com if (gHints[index].fFlushCache) { 3692f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com// SkGraphics::SetFontCacheUsed(0); 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 37282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3739e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClickX = x; 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->inval(NULL); 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->INHERITED::onFindClickHandler(x, y); 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 37882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3799e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com virtual bool onClick(Click* click) { 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->INHERITED::onClick(click); 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 38282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int fHints; 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar fClickX; 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMaskFilter* fMF; 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3889e39bb3603ee33e7753ee66eb76ebcfc412396f1reed@google.com typedef SampleView INHERITED; 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkView* MyFactory() { return new TextSpeedView; } 3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkViewRegister reg(MyFactory); 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 396