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