blob: 50bb8fdc9c34cd83eaf81ea0b37620a0b7d1a80f [file] [log] [blame]
Jim Van Verth39129482023-01-19 17:20:15 -05001/*
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 "gm/gm.h"
9#include "include/core/SkCanvas.h"
10#include "include/core/SkColor.h"
11#include "include/core/SkFont.h"
12#include "include/core/SkFontStyle.h"
13#include "include/core/SkFontTypes.h"
14#include "include/core/SkMatrix.h"
15#include "include/core/SkPaint.h"
16#include "include/core/SkPoint.h"
17#include "include/core/SkRect.h"
18#include "include/core/SkScalar.h"
19#include "include/core/SkString.h"
20#include "include/core/SkTypeface.h"
21#include "include/core/SkTypes.h"
Kevin Lubick0d4d1142023-02-13 09:13:10 -050022#include "include/private/base/SkTemplates.h"
Jim Van Verth39129482023-01-19 17:20:15 -050023#include "include/private/base/SkTo.h"
24#include "src/core/SkMatrixPriv.h"
25#include "tools/ToolUtils.h"
Kevin Lubicke836c3a2023-10-20 06:55:35 -040026#include "tools/fonts/FontToolUtils.h"
Jim Van Verth39129482023-01-19 17:20:15 -050027
28#include <string.h>
29
30class PerspTextGM : public skiagm::GM {
31public:
Jim Van Verth3e6cf402023-01-25 14:09:54 -050032 PerspTextGM(bool minimal) : fMinimal(minimal) {
Jim Van Verth39129482023-01-19 17:20:15 -050033 this->setBGColor(0xFFFFFFFF);
34 }
35
36protected:
Leandro Lovisolo24fa2112023-08-15 19:05:17 +000037 SkString getName() const override {
Jim Van Verth3e6cf402023-01-25 14:09:54 -050038 return SkString(fMinimal ? "persptext_minimal" : "persptext");
Jim Van Verth39129482023-01-19 17:20:15 -050039 }
40
Leandro Lovisolo8f023882023-08-15 21:13:52 +000041 SkISize getISize() override { return SkISize::Make(1024, 768); }
Jim Van Verth39129482023-01-19 17:20:15 -050042
Leandro Lovisolo8f023882023-08-15 21:13:52 +000043 // #define TEST_PERSP_CHECK
Jim Van Verth3e6cf402023-01-25 14:09:54 -050044
Jim Van Verth39129482023-01-19 17:20:15 -050045 void onDraw(SkCanvas* canvas) override {
46
47 canvas->clear(0xffffffff);
48
49 SkPaint paint;
50 paint.setAntiAlias(true);
51
Kevin Lubicke836c3a2023-10-20 06:55:35 -040052 SkFont font(ToolUtils::CreatePortableTypeface("serif", SkFontStyle()));
Jim Van Verth39129482023-01-19 17:20:15 -050053 font.setSubpixel(true);
54 font.setSize(32);
Jim Van Verth3e6cf402023-01-25 14:09:54 -050055 font.setBaselineSnap(false);
Jim Van Verth39129482023-01-19 17:20:15 -050056
57 const char* text = "Hamburgefons";
58 const size_t textLen = strlen(text);
59
60 SkScalar textWidth = font.measureText(text, textLen, SkTextEncoding::kUTF8,
61 nullptr, nullptr);
62 SkScalar textHeight = font.getMetrics(nullptr);
63
64 SkScalar x = 10, y = textHeight + 5.f;
65 const int kSteps = 8;
Jim Van Verth3e6cf402023-01-25 14:09:54 -050066 float kMinimalFactor = fMinimal ? 32.f : 1.f;
Jim Van Verth39129482023-01-19 17:20:15 -050067 for (auto pm : {PerspMode::kX, PerspMode::kY, PerspMode::kXY}) {
68 for (int i = 0; i < kSteps; ++i) {
69 canvas->save();
Jim Van Verth3e6cf402023-01-25 14:09:54 -050070#ifdef TEST_PERSP_CHECK
71 // draw non-perspective text in the background for comparison
72 paint.setColor(SK_ColorRED);
73 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, x, y, font, paint);
74#endif
75
Jim Van Verth39129482023-01-19 17:20:15 -050076 SkMatrix persp = SkMatrix::I();
77 switch (pm) {
78 case PerspMode::kX:
Jim Van Verth3e6cf402023-01-25 14:09:54 -050079 if (fMinimal) {
80 persp.setPerspX(i*0.0005f/kSteps/kMinimalFactor);
81 } else {
82 persp.setPerspX(i*0.00025f/kSteps);
83 }
Jim Van Verth39129482023-01-19 17:20:15 -050084 break;
85 case PerspMode::kY:
Jim Van Verth3e6cf402023-01-25 14:09:54 -050086 persp.setPerspY(i*0.0025f/kSteps/kMinimalFactor);
Jim Van Verth39129482023-01-19 17:20:15 -050087 break;
88 case PerspMode::kXY:
Jim Van Verth3e6cf402023-01-25 14:09:54 -050089 persp.setPerspX(i*-0.00025f/kSteps/kMinimalFactor);
90 persp.setPerspY(i*-0.00125f/kSteps/kMinimalFactor);
Jim Van Verth39129482023-01-19 17:20:15 -050091 break;
92 }
93 persp = SkMatrix::Concat(persp, SkMatrix::Translate(-x, -y));
94 persp = SkMatrix::Concat(SkMatrix::Translate(x, y), persp);
95 canvas->concat(persp);
96
97 paint.setColor(SK_ColorBLACK);
Jim Van Verth3e6cf402023-01-25 14:09:54 -050098#ifdef TEST_PERSP_CHECK
99 // Draw text as red if it is nearly affine
100 SkRect bounds = SkRect::MakeXYWH(0, -textHeight, textWidth, textHeight);
101 bounds.offset(x, y);
102 if (SkMatrixPriv::NearlyAffine(persp, bounds, SK_Scalar1/(1 << 4))) {
103 paint.setColor(SK_ColorRED);
104 }
105#endif
Jim Van Verth39129482023-01-19 17:20:15 -0500106 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, x, y, font, paint);
107
108 y += textHeight + 5.f;
109 canvas->restore();
110 }
111
112 x += textWidth + 10.f;
113 y = textHeight + 5.f;
114 }
115
116 }
117
118private:
119 enum class PerspMode { kX, kY, kXY };
Jim Van Verth3e6cf402023-01-25 14:09:54 -0500120 bool fMinimal;
Jim Van Verth39129482023-01-19 17:20:15 -0500121};
122
Jim Van Verth3e6cf402023-01-25 14:09:54 -0500123DEF_GM(return new PerspTextGM(true);)
124DEF_GM(return new PerspTextGM(false);)