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 #include "sk_tool_utils.h"
     10 
     11 #include "Resources.h"
     12 #include "SkCanvas.h"
     13 #include "SkGradientShader.h"
     14 #include "SkStream.h"
     15 #include "SkTextBlob.h"
     16 #include "SkTypeface.h"
     17 
     18 namespace skiagm {
     19 
     20 static void draw_blob(SkCanvas* canvas, const SkTextBlob* blob, const SkPaint& skPaint,
     21                       const SkRect& clipRect) {
     22     SkPaint clipHairline;
     23     clipHairline.setColor(SK_ColorWHITE);
     24     clipHairline.setStyle(SkPaint::kStroke_Style);
     25 
     26     SkPaint paint(skPaint);
     27     canvas->save();
     28     canvas->drawRect(clipRect, clipHairline);
     29     paint.setAlpha(0x20);
     30     canvas->drawTextBlob(blob, 0, 0, paint);
     31     canvas->clipRect(clipRect);
     32     paint.setAlpha(0xFF);
     33     canvas->drawTextBlob(blob, 0, 0, paint);
     34     canvas->restore();
     35 }
     36 
     37 class MixedTextBlobsGM : public GM {
     38 public:
     39     MixedTextBlobsGM() { }
     40 
     41 protected:
     42     void onOnceBeforeDraw() override {
     43         fEmojiTypeface = sk_tool_utils::emoji_typeface();
     44         fEmojiText = sk_tool_utils::emoji_sample_text();
     45         fReallyBigATypeface = MakeResourceAsTypeface("fonts/ReallyBigA.ttf");
     46 
     47         SkTextBlobBuilder builder;
     48 
     49         // make textblob
     50         // Text so large we draw as paths
     51         SkPaint paint;
     52         paint.setTextSize(385);
     53         const char* text = "O";
     54         sk_tool_utils::set_portable_typeface(&paint);
     55 
     56         SkRect bounds;
     57         paint.measureText(text, strlen(text), &bounds);
     58 
     59         SkScalar yOffset = bounds.height();
     60         sk_tool_utils::add_to_text_blob(&builder, text, paint, 10, yOffset);
     61         SkScalar corruptedAx = bounds.width();
     62         SkScalar corruptedAy = yOffset;
     63 
     64         const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
     65         const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
     66 
     67         SkScalar xOffset = boundsHalfWidth;
     68         yOffset = boundsHalfHeight;
     69 
     70         // LCD
     71         paint.setTextSize(32);
     72         text = "LCD!!!!!";
     73         paint.setAntiAlias(true);
     74         paint.setSubpixelText(true);
     75         paint.setLCDRenderText(true);
     76         paint.measureText(text, strlen(text), &bounds);
     77         sk_tool_utils::add_to_text_blob(&builder, text, paint, xOffset - bounds.width() * 0.25f,
     78                                         yOffset - bounds.height() * 0.5f);
     79         yOffset += bounds.height();
     80 
     81         // color emoji
     82         if (fEmojiTypeface) {
     83             paint.setAntiAlias(false);
     84             paint.setSubpixelText(false);
     85             paint.setLCDRenderText(false);
     86             paint.setTypeface(fEmojiTypeface);
     87             text = fEmojiText;
     88             paint.measureText(text, strlen(text), &bounds);
     89             sk_tool_utils::add_to_text_blob(&builder, text, paint, xOffset - bounds.width() * 0.3f,
     90                                             yOffset);
     91         }
     92 
     93         // Corrupted font
     94         paint.setTextSize(12);
     95         text = "aA";
     96         paint.setTypeface(fReallyBigATypeface);
     97         sk_tool_utils::add_to_text_blob(&builder, text, paint, corruptedAx, corruptedAy);
     98         fBlob = builder.make();
     99     }
    100 
    101     SkString onShortName() override {
    102         return SkStringPrintf("mixedtextblobs%s",
    103                               sk_tool_utils::platform_font_manager());
    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.get(), 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     sk_sp<SkTypeface> fEmojiTypeface;
    154     sk_sp<SkTypeface> fReallyBigATypeface;
    155     const char* fEmojiText;
    156     sk_sp<SkTextBlob> fBlob;
    157 
    158     static constexpr int kWidth = 1250;
    159     static constexpr int kHeight = 700;
    160 
    161     typedef GM INHERITED;
    162 };
    163 
    164 //////////////////////////////////////////////////////////////////////////////
    165 
    166 DEF_GM(return new MixedTextBlobsGM;)
    167 }
    168