1eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt/* 2eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt * Copyright 2013 Google Inc. 3eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt * 4eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt * Use of this source code is governed by a BSD-style license that can be 5eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt * found in the LICENSE file. 6eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt */ 7eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 8eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt#include "gm.h" 9eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 10eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt#include "Resources.h" 11eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt#include "SkCanvas.h" 12eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt#include "SkGradientShader.h" 13eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt#include "SkStream.h" 14eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt#include "SkTextBlob.h" 15eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt#include "SkTypeface.h" 16eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 17eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualittnamespace skiagm { 18eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 19eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualittstatic void draw_blob(SkCanvas* canvas, const SkTextBlob* blob, const SkPaint& skPaint, 20eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt const SkRect& clipRect) { 21eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkPaint clipHairline; 22eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt clipHairline.setColor(SK_ColorWHITE); 23eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt clipHairline.setStyle(SkPaint::kStroke_Style); 24eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 25eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkPaint paint(skPaint); 26eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt canvas->save(); 27eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt canvas->drawRect(clipRect, clipHairline); 28eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setAlpha(0x20); 29eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt canvas->drawTextBlob(blob, 0, 0, paint); 30eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt canvas->clipRect(clipRect); 31eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setAlpha(0xFF); 32eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt canvas->drawTextBlob(blob, 0, 0, paint); 33eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt canvas->restore(); 34eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt} 35eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 36eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualittclass MixedTextBlobsGM : public GM { 37eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualittpublic: 38eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt MixedTextBlobsGM() { } 39eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 40eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualittprotected: 41eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt void onOnceBeforeDraw() override { 42eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt#ifndef SK_BUILD_FOR_MAC 433ffa126066542590dc7430514a1174e49191b875bungeman fEmojiTypeface.reset(GetResourceAsTypeface("/fonts/Funkster.ttf")); 44eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt fEmojiText = "Emoji!!!"; 45eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt#else 46eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt fEmojiTypeface.reset(SkTypeface::CreateFromName("Apple Color Emoji", SkTypeface::kNormal)); 47eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt fEmojiText = "\xF0\x9F\x92\xB0" "\xF0\x9F\x8F\xA1" "\xF0\x9F\x8E\x85" // 48eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt "\xF0\x9F\x8D\xAA" "\xF0\x9F\x8D\x95" "\xF0\x9F\x9A\x80"; // 49eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt#endif 503ffa126066542590dc7430514a1174e49191b875bungeman fReallyBigATypeface.reset(GetResourceAsTypeface("/fonts/ReallyBigA.ttf")); 51eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 52eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkTextBlobBuilder builder; 53eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 54eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt // make textblob 55eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt // Text so large we draw as paths 56eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkPaint paint; 57eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setTextSize(384); 58eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt const char* text = "O"; 59eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt sk_tool_utils::set_portable_typeface(&paint); 60eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 61eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkRect bounds; 62eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.measureText(text, strlen(text), &bounds); 63eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 64eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkScalar yOffset = bounds.height(); 659e36c1a9306f052331550dab4728b9875127bfb5joshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, 10, yOffset); 66eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkScalar corruptedAx = bounds.width(); 67eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkScalar corruptedAy = yOffset; 68eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 69eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf; 70eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf; 71eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 72eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkScalar xOffset = boundsHalfWidth; 73eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt yOffset = boundsHalfHeight; 74eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 75eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt // LCD 76eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setTextSize(32); 77eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt text = "LCD!!!!!"; 78eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setSubpixelText(true); 79eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setLCDRenderText(true); 80eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.measureText(text, strlen(text), &bounds); 819e36c1a9306f052331550dab4728b9875127bfb5joshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, xOffset - bounds.width() * 0.25f, 829e36c1a9306f052331550dab4728b9875127bfb5joshualitt yOffset - bounds.height() * 0.5f); 83eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt yOffset += bounds.height(); 84eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 85eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt // color emoji 86eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setSubpixelText(false); 87eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setLCDRenderText(false); 88eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setTypeface(fEmojiTypeface); 89eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt text = fEmojiText; 90eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.measureText(text, strlen(text), &bounds); 919e36c1a9306f052331550dab4728b9875127bfb5joshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, xOffset - bounds.width() * 0.3f, 929e36c1a9306f052331550dab4728b9875127bfb5joshualitt yOffset); 93eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 94eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt // Corrupted font 95eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setTextSize(12); 96eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt text = "aA"; 97eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setTypeface(fReallyBigATypeface); 989e36c1a9306f052331550dab4728b9875127bfb5joshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, corruptedAx, corruptedAy); 99eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt fBlob.reset(builder.build()); 100eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt } 101eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 102eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkString onShortName() override { 103eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt return SkString("mixedtextblobs"); 104eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt } 105eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 106eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkISize onISize() override { 107eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt return SkISize::Make(kWidth, kHeight); 108eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt } 109eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 110eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt void onDraw(SkCanvas* canvas) override { 111eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 112eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt canvas->drawColor(SK_ColorGRAY); 113eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 114eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkPaint paint; 115eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 116eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt // setup work needed to draw text with different clips 117eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setColor(SK_ColorBLACK); 118eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt canvas->translate(10, 40); 119eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 120eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt paint.setTextSize(40); 121eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 122eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt // compute the bounds of the text and setup some clips 123eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkRect bounds = fBlob->bounds(); 124eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 125eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf; 126eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf; 127eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf; 128eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf; 129eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 130eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(), 131eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt boundsHalfWidth, boundsHalfHeight); 132eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.centerY(), 133eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt boundsHalfWidth, boundsHalfHeight); 134eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkRect interiorClip = bounds; 135eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight); 136eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 137eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip}; 138eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 139eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt size_t count = sizeof(clipRects) / sizeof(SkRect); 140eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt for (size_t x = 0; x < count; ++x) { 141eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt draw_blob(canvas, fBlob, paint, clipRects[x]); 142eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt if (x == (count >> 1) - 1) { 143eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt canvas->translate(SkScalarFloorToScalar(bounds.width() + SkIntToScalar(25)), 144eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt -(x * SkScalarFloorToScalar(bounds.height() + 145eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkIntToScalar(25)))); 146eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt } else { 147eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt canvas->translate(0, SkScalarFloorToScalar(bounds.height() + SkIntToScalar(25))); 148eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt } 149eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt } 150eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt } 151eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 152eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualittprivate: 153eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkAutoTUnref<SkTypeface> fEmojiTypeface; 154eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkAutoTUnref<SkTypeface> fReallyBigATypeface; 155eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt const char* fEmojiText; 156eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt SkAutoTUnref<const SkTextBlob> fBlob; 157eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 158eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt static const int kWidth = 1250; 159eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt static const int kHeight = 700; 160eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 161eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt typedef GM INHERITED; 162eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt}; 163eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 164eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt////////////////////////////////////////////////////////////////////////////// 165eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt 166eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualittDEF_GM( return SkNEW(MixedTextBlobsGM); ) 167eef5b3eb12d5aaf55f43762110af250c79cb0a45joshualitt} 168