123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- /*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "gm/gm.h"
- #include "include/core/SkCanvas.h"
- #include "include/core/SkColor.h"
- #include "include/core/SkFont.h"
- #include "include/core/SkFontStyle.h"
- #include "include/core/SkFontTypes.h"
- #include "include/core/SkPaint.h"
- #include "include/core/SkPoint.h"
- #include "include/core/SkRect.h"
- #include "include/core/SkRefCnt.h"
- #include "include/core/SkScalar.h"
- #include "include/core/SkSize.h"
- #include "include/core/SkString.h"
- #include "include/core/SkTypeface.h"
- #include "include/core/SkTypes.h"
- #include "include/utils/SkRandom.h"
- #include "tools/ToolUtils.h"
- /**
- * Draws text with random parameters. The text draws each get their own clip rect. It is also
- * used as a bench to measure how well the GPU backend combines draw ops for text draws.
- */
- class VariedTextGM : public skiagm::GM {
- public:
- VariedTextGM(bool effectiveClip, bool lcd)
- : fEffectiveClip(effectiveClip)
- , fLCD(lcd) {
- }
- protected:
- SkString onShortName() override {
- SkString name("varied_text");
- if (fEffectiveClip) {
- name.append("_clipped");
- } else {
- name.append("_ignorable_clip");
- }
- if (fLCD) {
- name.append("_lcd");
- } else {
- name.append("_no_lcd");
- }
- return name;
- }
- SkISize onISize() override {
- return SkISize::Make(640, 480);
- }
- void onOnceBeforeDraw() override {
- fPaint.setAntiAlias(true);
- fFont.setEdging(fLCD ? SkFont::Edging::kSubpixelAntiAlias : SkFont::Edging::kAntiAlias);
- SkISize size = this->getISize();
- SkScalar w = SkIntToScalar(size.fWidth);
- SkScalar h = SkIntToScalar(size.fHeight);
- static_assert(4 == SK_ARRAY_COUNT(fTypefaces), "typeface_cnt");
- fTypefaces[0] = ToolUtils::create_portable_typeface("sans-serif", SkFontStyle());
- fTypefaces[1] = ToolUtils::create_portable_typeface("sans-serif", SkFontStyle::Bold());
- fTypefaces[2] = ToolUtils::create_portable_typeface("serif", SkFontStyle());
- fTypefaces[3] = ToolUtils::create_portable_typeface("serif", SkFontStyle::Bold());
- SkRandom random;
- for (int i = 0; i < kCnt; ++i) {
- int length = random.nextRangeU(kMinLength, kMaxLength);
- char text[kMaxLength];
- for (int j = 0; j < length; ++j) {
- text[j] = (char)random.nextRangeU('!', 'z');
- }
- fStrings[i].set(text, length);
- fColors[i] = random.nextU();
- fColors[i] |= 0xFF000000;
- fColors[i] = ToolUtils::color_to_565(fColors[i]);
- constexpr SkScalar kMinPtSize = 8.f;
- constexpr SkScalar kMaxPtSize = 32.f;
- fPtSizes[i] = random.nextRangeScalar(kMinPtSize, kMaxPtSize);
- fTypefaceIndices[i] = random.nextULessThan(SK_ARRAY_COUNT(fTypefaces));
- SkRect r;
- fPaint.setColor(fColors[i]);
- fFont.setTypeface(fTypefaces[fTypefaceIndices[i]]);
- fFont.setSize(fPtSizes[i]);
- fFont.measureText(fStrings[i].c_str(), fStrings[i].size(), SkTextEncoding::kUTF8, &r);
- // safeRect is set of x,y positions where we can draw the string without hitting
- // the GM's border.
- SkRect safeRect = SkRect::MakeLTRB(-r.fLeft, -r.fTop, w - r.fRight, h - r.fBottom);
- if (safeRect.isEmpty()) {
- // If we don't fit then just don't worry about how we get cliped to the device
- // border.
- safeRect = SkRect::MakeWH(w, h);
- }
- fPositions[i].fX = random.nextRangeScalar(safeRect.fLeft, safeRect.fRight);
- fPositions[i].fY = random.nextRangeScalar(safeRect.fTop, safeRect.fBottom);
- fClipRects[i] = r;
- fClipRects[i].offset(fPositions[i].fX, fPositions[i].fY);
- fClipRects[i].outset(2.f, 2.f);
- if (fEffectiveClip) {
- fClipRects[i].fRight -= 0.25f * fClipRects[i].width();
- }
- }
- }
- void onDraw(SkCanvas* canvas) override {
- for (int i = 0; i < kCnt; ++i) {
- fPaint.setColor(fColors[i]);
- fFont.setSize(fPtSizes[i]);
- fFont.setTypeface(fTypefaces[fTypefaceIndices[i]]);
- canvas->save();
- canvas->clipRect(fClipRects[i]);
- canvas->translate(fPositions[i].fX, fPositions[i].fY);
- canvas->drawSimpleText(fStrings[i].c_str(), fStrings[i].size(), SkTextEncoding::kUTF8,
- 0, 0, fFont, fPaint);
- canvas->restore();
- }
- // Visualize the clips, but not in bench mode.
- if (kBench_Mode != this->getMode()) {
- SkPaint wirePaint;
- wirePaint.setAntiAlias(true);
- wirePaint.setStrokeWidth(0);
- wirePaint.setStyle(SkPaint::kStroke_Style);
- for (int i = 0; i < kCnt; ++i) {
- canvas->drawRect(fClipRects[i], wirePaint);
- }
- }
- }
- bool runAsBench() const override { return true; }
- private:
- static constexpr int kCnt = 30;
- static constexpr int kMinLength = 15;
- static constexpr int kMaxLength = 40;
- bool fEffectiveClip;
- bool fLCD;
- sk_sp<SkTypeface> fTypefaces[4];
- SkPaint fPaint;
- SkFont fFont;
- // precomputed for each text draw
- SkString fStrings[kCnt];
- SkColor fColors[kCnt];
- SkScalar fPtSizes[kCnt];
- int fTypefaceIndices[kCnt];
- SkPoint fPositions[kCnt];
- SkRect fClipRects[kCnt];
- typedef skiagm::GM INHERITED;
- };
- DEF_GM(return new VariedTextGM(false, false);)
- DEF_GM(return new VariedTextGM(true, false);)
- DEF_GM(return new VariedTextGM(false, true);)
- DEF_GM(return new VariedTextGM(true, true);)
|