Home | History | Annotate | Download | only in samplecode
      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 SkRandom gRand;
     67 
     68 class SkPowerMode : public SkXfermode {
     69 public:
     70     SkPowerMode(SkScalar exponent) { this->init(exponent); }
     71 
     72     virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
     73                         const SkAlpha aa[]) const SK_OVERRIDE;
     74 
     75     typedef SkFlattenable* (*Factory)(SkReadBuffer&);
     76 
     77     SK_TO_STRING_OVERRIDE()
     78     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPowerMode)
     79 
     80 private:
     81     SkScalar fExp;          // user's value
     82     uint8_t fTable[256];    // cache
     83 
     84     void init(SkScalar exponent);
     85     SkPowerMode(SkReadBuffer& b) : INHERITED(b) {
     86         // read the exponent
     87         this->init(SkFixedToScalar(b.readFixed()));
     88     }
     89     virtual void flatten(SkWriteBuffer& b) const SK_OVERRIDE {
     90         this->INHERITED::flatten(b);
     91         b.writeFixed(SkScalarToFixed(fExp));
     92     }
     93 
     94     typedef SkXfermode INHERITED;
     95 };
     96 
     97 void SkPowerMode::init(SkScalar e) {
     98     fExp = e;
     99     float ee = SkScalarToFloat(e);
    100 
    101     printf("------ %g\n", ee);
    102     for (int i = 0; i < 256; i++) {
    103         float x = i / 255.f;
    104      //   printf(" %d %g", i, x);
    105         x = powf(x, ee);
    106      //   printf(" %g", x);
    107         int xx = SkScalarRoundToInt(x * 255);
    108      //   printf(" %d\n", xx);
    109         fTable[i] = SkToU8(xx);
    110     }
    111 }
    112 
    113 void SkPowerMode::xfer16(uint16_t dst[], const SkPMColor src[], int count,
    114                          const SkAlpha aa[]) const {
    115     for (int i = 0; i < count; i++) {
    116         SkPMColor c = src[i];
    117         int r = SkGetPackedR32(c);
    118         int g = SkGetPackedG32(c);
    119         int b = SkGetPackedB32(c);
    120         r = fTable[r];
    121         g = fTable[g];
    122         b = fTable[b];
    123         dst[i] = SkPack888ToRGB16(r, g, b);
    124     }
    125 }
    126 
    127 #ifndef SK_IGNORE_TO_STRING
    128 void SkPowerMode::toString(SkString* str) const {
    129     str->append("SkPowerMode: exponent ");
    130     str->appendScalar(fExp);
    131 }
    132 #endif
    133 
    134 static const struct {
    135     const char* fName;
    136     uint32_t    fFlags;
    137     bool        fFlushCache;
    138 } gHints[] = {
    139     { "Linear", SkPaint::kLinearText_Flag,     false },
    140     { "Normal",   0,                           true },
    141     { "Subpixel", SkPaint::kSubpixelText_Flag, true }
    142 };
    143 
    144 static void DrawTheText(SkCanvas* canvas, const char text[], size_t length, SkScalar x, SkScalar y,
    145                         const SkPaint& paint, SkScalar clickX) {
    146     SkPaint p(paint);
    147 
    148 #if 0
    149     canvas->drawText(text, length, x, y, paint);
    150 #else
    151     {
    152         SkPoint pts[1000];
    153         SkScalar xpos = x;
    154         SkASSERT(length <= SK_ARRAY_COUNT(pts));
    155         for (size_t i = 0; i < length; i++) {
    156             pts[i].set(xpos, y), xpos += paint.getTextSize();
    157         }
    158         canvas->drawPosText(text, length, pts, paint);
    159     }
    160 #endif
    161 
    162     p.setSubpixelText(true);
    163     x += SkIntToScalar(180);
    164     canvas->drawText(text, length, x, y, p);
    165 
    166 #ifdef SK_DEBUG
    167     if (true) {
    168         p.setSubpixelText(false);
    169         p.setLinearText(true);
    170         x += SkIntToScalar(180);
    171         canvas->drawText(text, length, x, y, p);
    172     }
    173 #endif
    174 }
    175 
    176 class TextSpeedView : public SampleView {
    177 public:
    178     TextSpeedView() {
    179         fHints = 0;
    180         fClickX = 0;
    181 
    182         test_breakText();
    183     }
    184 
    185 protected:
    186     // overrides from SkEventSink
    187     virtual bool onQuery(SkEvent* evt) {
    188         if (SampleCode::TitleQ(*evt)) {
    189             SampleCode::TitleR(evt, "Text");
    190             return true;
    191         }
    192         return this->INHERITED::onQuery(evt);
    193     }
    194 
    195     static void make_textstrip(SkBitmap* bm) {
    196         bm->allocPixels(SkImageInfo::Make(200, 18, kRGB_565_SkColorType,
    197                                           kOpaque_SkAlphaType));
    198         bm->eraseColor(SK_ColorWHITE);
    199 
    200         SkCanvas    canvas(*bm);
    201         SkPaint     paint;
    202         const char* s = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit";
    203 
    204         paint.setFlags(paint.getFlags() | SkPaint::kAntiAlias_Flag
    205                                         | SkPaint::kDevKernText_Flag);
    206         paint.setTextSize(SkIntToScalar(14));
    207         canvas.drawText(s, strlen(s), SkIntToScalar(8), SkIntToScalar(14), paint);
    208     }
    209 
    210     static void fill_pts(SkPoint pts[], size_t n, SkRandom* rand) {
    211         for (size_t i = 0; i < n; i++)
    212             pts[i].set(rand->nextUScalar1() * 640, rand->nextUScalar1() * 480);
    213     }
    214 
    215     virtual void onDrawContent(SkCanvas* canvas) {
    216         SkAutoCanvasRestore restore(canvas, false);
    217         {
    218             SkRect r;
    219             r.set(0, 0, SkIntToScalar(1000), SkIntToScalar(20));
    220        //     canvas->saveLayer(&r, NULL, SkCanvas::kHasAlphaLayer_SaveFlag);
    221         }
    222 
    223         SkPaint paint;
    224 //        const uint16_t glyphs[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 };
    225         int         index = fHints % SK_ARRAY_COUNT(gHints);
    226         index = 1;
    227 //        const char* style = gHints[index].fName;
    228 
    229 //        canvas->translate(0, SkIntToScalar(50));
    230 
    231   //      canvas->drawText(style, strlen(style), SkIntToScalar(20), SkIntToScalar(20), paint);
    232 
    233         SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromFile("/skimages/samplefont.ttf")));
    234         paint.setAntiAlias(true);
    235         paint.setFlags(paint.getFlags() | gHints[index].fFlags);
    236 
    237         SkRect clip;
    238         clip.set(SkIntToScalar(25), SkIntToScalar(34), SkIntToScalar(88), SkIntToScalar(155));
    239 
    240         const char* text = "Hamburgefons";
    241         size_t length = strlen(text);
    242 
    243         SkScalar y = SkIntToScalar(0);
    244         for (int i = 9; i <= 24; i++) {
    245             paint.setTextSize(SkIntToScalar(i) /*+ (gRand.nextU() & 0xFFFF)*/);
    246             for (SkScalar dx = 0; dx <= SkIntToScalar(3)/4;
    247                                             dx += SkIntToScalar(1) /* /4 */) {
    248                 y += paint.getFontSpacing();
    249                 DrawTheText(canvas, text, length, SkIntToScalar(20) + dx, y, paint, fClickX);
    250             }
    251         }
    252         if (gHints[index].fFlushCache) {
    253 //                SkGraphics::SetFontCacheUsed(0);
    254         }
    255     }
    256 
    257     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
    258                                               unsigned modi) SK_OVERRIDE {
    259         fClickX = x;
    260         this->inval(NULL);
    261         return this->INHERITED::onFindClickHandler(x, y, modi);
    262     }
    263 
    264     virtual bool onClick(Click* click) {
    265         return this->INHERITED::onClick(click);
    266     }
    267 
    268 private:
    269     int fHints;
    270     SkScalar fClickX;
    271 
    272     typedef SampleView INHERITED;
    273 };
    274 
    275 //////////////////////////////////////////////////////////////////////////////
    276 
    277 static SkView* MyFactory() { return new TextSpeedView; }
    278 static SkViewRegister reg(MyFactory);
    279