1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2011 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontStyle.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontTypes.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h" 23*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h" 24*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkMatrixPriv.h" 25*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h" 26*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h" 27*c8dee2aaSAndroid Build Coastguard Worker 28*c8dee2aaSAndroid Build Coastguard Worker #include <string.h> 29*c8dee2aaSAndroid Build Coastguard Worker 30*c8dee2aaSAndroid Build Coastguard Worker class PerspTextGM : public skiagm::GM { 31*c8dee2aaSAndroid Build Coastguard Worker public: PerspTextGM(bool minimal)32*c8dee2aaSAndroid Build Coastguard Worker PerspTextGM(bool minimal) : fMinimal(minimal) { 33*c8dee2aaSAndroid Build Coastguard Worker this->setBGColor(0xFFFFFFFF); 34*c8dee2aaSAndroid Build Coastguard Worker } 35*c8dee2aaSAndroid Build Coastguard Worker 36*c8dee2aaSAndroid Build Coastguard Worker protected: getName() const37*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { 38*c8dee2aaSAndroid Build Coastguard Worker return SkString(fMinimal ? "persptext_minimal" : "persptext"); 39*c8dee2aaSAndroid Build Coastguard Worker } 40*c8dee2aaSAndroid Build Coastguard Worker getISize()41*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(1024, 768); } 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker // #define TEST_PERSP_CHECK 44*c8dee2aaSAndroid Build Coastguard Worker onDraw(SkCanvas * canvas)45*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override { 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker canvas->clear(0xffffffff); 48*c8dee2aaSAndroid Build Coastguard Worker 49*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 50*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 51*c8dee2aaSAndroid Build Coastguard Worker 52*c8dee2aaSAndroid Build Coastguard Worker SkFont font(ToolUtils::CreatePortableTypeface("serif", SkFontStyle())); 53*c8dee2aaSAndroid Build Coastguard Worker font.setSubpixel(true); 54*c8dee2aaSAndroid Build Coastguard Worker font.setSize(32); 55*c8dee2aaSAndroid Build Coastguard Worker font.setBaselineSnap(false); 56*c8dee2aaSAndroid Build Coastguard Worker 57*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Hamburgefons"; 58*c8dee2aaSAndroid Build Coastguard Worker const size_t textLen = strlen(text); 59*c8dee2aaSAndroid Build Coastguard Worker 60*c8dee2aaSAndroid Build Coastguard Worker SkScalar textWidth = font.measureText(text, textLen, SkTextEncoding::kUTF8, 61*c8dee2aaSAndroid Build Coastguard Worker nullptr, nullptr); 62*c8dee2aaSAndroid Build Coastguard Worker SkScalar textHeight = font.getMetrics(nullptr); 63*c8dee2aaSAndroid Build Coastguard Worker 64*c8dee2aaSAndroid Build Coastguard Worker SkScalar x = 10, y = textHeight + 5.f; 65*c8dee2aaSAndroid Build Coastguard Worker const int kSteps = 8; 66*c8dee2aaSAndroid Build Coastguard Worker float kMinimalFactor = fMinimal ? 32.f : 1.f; 67*c8dee2aaSAndroid Build Coastguard Worker for (auto pm : {PerspMode::kX, PerspMode::kY, PerspMode::kXY}) { 68*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kSteps; ++i) { 69*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 70*c8dee2aaSAndroid Build Coastguard Worker #ifdef TEST_PERSP_CHECK 71*c8dee2aaSAndroid Build Coastguard Worker // draw non-perspective text in the background for comparison 72*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorRED); 73*c8dee2aaSAndroid Build Coastguard Worker canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, x, y, font, paint); 74*c8dee2aaSAndroid Build Coastguard Worker #endif 75*c8dee2aaSAndroid Build Coastguard Worker 76*c8dee2aaSAndroid Build Coastguard Worker SkMatrix persp = SkMatrix::I(); 77*c8dee2aaSAndroid Build Coastguard Worker switch (pm) { 78*c8dee2aaSAndroid Build Coastguard Worker case PerspMode::kX: 79*c8dee2aaSAndroid Build Coastguard Worker if (fMinimal) { 80*c8dee2aaSAndroid Build Coastguard Worker persp.setPerspX(i*0.0005f/kSteps/kMinimalFactor); 81*c8dee2aaSAndroid Build Coastguard Worker } else { 82*c8dee2aaSAndroid Build Coastguard Worker persp.setPerspX(i*0.00025f/kSteps); 83*c8dee2aaSAndroid Build Coastguard Worker } 84*c8dee2aaSAndroid Build Coastguard Worker break; 85*c8dee2aaSAndroid Build Coastguard Worker case PerspMode::kY: 86*c8dee2aaSAndroid Build Coastguard Worker persp.setPerspY(i*0.0025f/kSteps/kMinimalFactor); 87*c8dee2aaSAndroid Build Coastguard Worker break; 88*c8dee2aaSAndroid Build Coastguard Worker case PerspMode::kXY: 89*c8dee2aaSAndroid Build Coastguard Worker persp.setPerspX(i*-0.00025f/kSteps/kMinimalFactor); 90*c8dee2aaSAndroid Build Coastguard Worker persp.setPerspY(i*-0.00125f/kSteps/kMinimalFactor); 91*c8dee2aaSAndroid Build Coastguard Worker break; 92*c8dee2aaSAndroid Build Coastguard Worker } 93*c8dee2aaSAndroid Build Coastguard Worker persp = SkMatrix::Concat(persp, SkMatrix::Translate(-x, -y)); 94*c8dee2aaSAndroid Build Coastguard Worker persp = SkMatrix::Concat(SkMatrix::Translate(x, y), persp); 95*c8dee2aaSAndroid Build Coastguard Worker canvas->concat(persp); 96*c8dee2aaSAndroid Build Coastguard Worker 97*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorBLACK); 98*c8dee2aaSAndroid Build Coastguard Worker #ifdef TEST_PERSP_CHECK 99*c8dee2aaSAndroid Build Coastguard Worker // Draw text as red if it is nearly affine 100*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds = SkRect::MakeXYWH(0, -textHeight, textWidth, textHeight); 101*c8dee2aaSAndroid Build Coastguard Worker bounds.offset(x, y); 102*c8dee2aaSAndroid Build Coastguard Worker if (SkMatrixPriv::NearlyAffine(persp, bounds, SK_Scalar1/(1 << 4))) { 103*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorRED); 104*c8dee2aaSAndroid Build Coastguard Worker } 105*c8dee2aaSAndroid Build Coastguard Worker #endif 106*c8dee2aaSAndroid Build Coastguard Worker canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, x, y, font, paint); 107*c8dee2aaSAndroid Build Coastguard Worker 108*c8dee2aaSAndroid Build Coastguard Worker y += textHeight + 5.f; 109*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 110*c8dee2aaSAndroid Build Coastguard Worker } 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker x += textWidth + 10.f; 113*c8dee2aaSAndroid Build Coastguard Worker y = textHeight + 5.f; 114*c8dee2aaSAndroid Build Coastguard Worker } 115*c8dee2aaSAndroid Build Coastguard Worker 116*c8dee2aaSAndroid Build Coastguard Worker } 117*c8dee2aaSAndroid Build Coastguard Worker 118*c8dee2aaSAndroid Build Coastguard Worker private: 119*c8dee2aaSAndroid Build Coastguard Worker enum class PerspMode { kX, kY, kXY }; 120*c8dee2aaSAndroid Build Coastguard Worker bool fMinimal; 121*c8dee2aaSAndroid Build Coastguard Worker }; 122*c8dee2aaSAndroid Build Coastguard Worker 123*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new PerspTextGM(true);) 124*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new PerspTextGM(false);) 125