Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2013 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 "gm.h"
      9 
     10 #include "Resources.h"
     11 #include "SkCanvas.h"
     12 #include "SkGradientShader.h"
     13 #include "SkStream.h"
     14 #include "SkTextBlob.h"
     15 #include "SkTypeface.h"
     16 
     17 namespace skiagm {
     18 
     19 static void draw_blob(SkCanvas* canvas, const SkTextBlob* blob, const SkPaint& skPaint,
     20                       const SkRect& clipRect) {
     21     SkPaint clipHairline;
     22     clipHairline.setColor(SK_ColorWHITE);
     23     clipHairline.setStyle(SkPaint::kStroke_Style);
     24 
     25     SkPaint paint(skPaint);
     26     canvas->save();
     27     canvas->drawRect(clipRect, clipHairline);
     28     paint.setAlpha(0x20);
     29     canvas->drawTextBlob(blob, 0, 0, paint);
     30     canvas->clipRect(clipRect);
     31     paint.setAlpha(0xFF);
     32     canvas->drawTextBlob(blob, 0, 0, paint);
     33     canvas->restore();
     34 }
     35 
     36 class MixedTextBlobsGM : public GM {
     37 public:
     38     MixedTextBlobsGM() { }
     39 
     40 protected:
     41     void onOnceBeforeDraw() override {
     42         sk_tool_utils::emoji_typeface(&fEmojiTypeface);
     43         fEmojiText = sk_tool_utils::emoji_sample_text();
     44         fReallyBigATypeface.reset(GetResourceAsTypeface("/fonts/ReallyBigA.ttf"));
     45 
     46         SkTextBlobBuilder builder;
     47 
     48         // make textblob
     49         // Text so large we draw as paths
     50         SkPaint paint;
     51         paint.setTextSize(385);
     52         const char* text = "O";
     53         sk_tool_utils::set_portable_typeface(&paint);
     54 
     55         SkRect bounds;
     56         paint.measureText(text, strlen(text), &bounds);
     57 
     58         SkScalar yOffset = bounds.height();
     59         sk_tool_utils::add_to_text_blob(&builder, text, paint, 10, yOffset);
     60         SkScalar corruptedAx = bounds.width();
     61         SkScalar corruptedAy = yOffset;
     62 
     63         const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
     64         const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
     65 
     66         SkScalar xOffset = boundsHalfWidth;
     67         yOffset = boundsHalfHeight;
     68 
     69         // LCD
     70         paint.setTextSize(32);
     71         text = "LCD!!!!!";
     72         paint.setAntiAlias(true);
     73         paint.setSubpixelText(true);
     74         paint.setLCDRenderText(true);
     75         paint.measureText(text, strlen(text), &bounds);
     76         sk_tool_utils::add_to_text_blob(&builder, text, paint, xOffset - bounds.width() * 0.25f,
     77                                         yOffset - bounds.height() * 0.5f);
     78         yOffset += bounds.height();
     79 
     80         // color emoji
     81         if (fEmojiTypeface) {
     82             paint.setAntiAlias(false);
     83             paint.setSubpixelText(false);
     84             paint.setLCDRenderText(false);
     85             paint.setTypeface(fEmojiTypeface);
     86             text = fEmojiText;
     87             paint.measureText(text, strlen(text), &bounds);
     88             sk_tool_utils::add_to_text_blob(&builder, text, paint, xOffset - bounds.width() * 0.3f,
     89                                             yOffset);
     90         }
     91 
     92         // Corrupted font
     93         paint.setTextSize(12);
     94         text = "aA";
     95         paint.setTypeface(fReallyBigATypeface);
     96         sk_tool_utils::add_to_text_blob(&builder, text, paint, corruptedAx, corruptedAy);
     97         fBlob.reset(builder.build());
     98     }
     99 
    100     SkString onShortName() override {
    101         SkString name("mixedtextblobs");
    102         name.append(sk_tool_utils::platform_os_emoji());
    103         return name;
    104     }
    105 
    106     SkISize onISize() override {
    107         return SkISize::Make(kWidth, kHeight);
    108     }
    109 
    110     void onDraw(SkCanvas* canvas) override {
    111 
    112         canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorGRAY));
    113 
    114         SkPaint paint;
    115 
    116         // setup work needed to draw text with different clips
    117         paint.setColor(SK_ColorBLACK);
    118         canvas->translate(10, 40);
    119 
    120         paint.setTextSize(40);
    121 
    122         // compute the bounds of the text and setup some clips
    123         SkRect bounds = fBlob->bounds();
    124 
    125         const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
    126         const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
    127         const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf;
    128         const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf;
    129 
    130         SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(),
    131                                                 boundsHalfWidth, boundsHalfHeight);
    132         SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.centerY(),
    133                                                  boundsHalfWidth, boundsHalfHeight);
    134         SkRect interiorClip = bounds;
    135         interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight);
    136 
    137         const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip};
    138 
    139         size_t count = sizeof(clipRects) / sizeof(SkRect);
    140         for (size_t x = 0; x < count; ++x) {
    141             draw_blob(canvas, fBlob, paint, clipRects[x]);
    142             if (x == (count >> 1) - 1) {
    143                 canvas->translate(SkScalarFloorToScalar(bounds.width() + SkIntToScalar(25)),
    144                                   -(x * SkScalarFloorToScalar(bounds.height() +
    145                                     SkIntToScalar(25))));
    146             } else {
    147                 canvas->translate(0, SkScalarFloorToScalar(bounds.height() + SkIntToScalar(25)));
    148             }
    149         }
    150     }
    151 
    152 private:
    153     SkAutoTUnref<SkTypeface> fEmojiTypeface;
    154     SkAutoTUnref<SkTypeface> fReallyBigATypeface;
    155     const char* fEmojiText;
    156     SkAutoTUnref<const SkTextBlob> fBlob;
    157 
    158     static const int kWidth = 1250;
    159     static const int kHeight = 700;
    160 
    161     typedef GM INHERITED;
    162 };
    163 
    164 //////////////////////////////////////////////////////////////////////////////
    165 
    166 DEF_GM(return new MixedTextBlobsGM;)
    167 }
    168