1/*
2 * Copyright 2016 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 "SkCanvas.h"
12#include "SkTextBlob.h"
13
14namespace skiagm {
15class TextBlobBlockReordering : public GM {
16public:
17    // This gm tests that textblobs translate properly when their draw order is different from their
18    // flush order
19    TextBlobBlockReordering() { }
20
21protected:
22    void onOnceBeforeDraw() override {
23        SkTextBlobBuilder builder;
24
25        // make textblob
26        // Large text is used to trigger atlas eviction
27        SkPaint paint;
28        paint.setTextSize(56);
29        const char* text = "AB";
30        sk_tool_utils::set_portable_typeface(&paint);
31
32        SkRect bounds;
33        paint.measureText(text, strlen(text), &bounds);
34
35        SkScalar yOffset = bounds.height();
36        sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset - 30);
37
38        // build
39        fBlob = builder.make();
40    }
41
42    SkString onShortName() override {
43        return SkString("textblobblockreordering");
44    }
45
46    SkISize onISize() override {
47        return SkISize::Make(kWidth, kHeight);
48    }
49
50    // This draws the same text blob 3 times.  The second draw used a different xfer mode so its
51    // GrDrawOp doesn't get combined with the first and third. Ultimately, they will be flushed in
52    // the order first, third, and then second.
53    void onDraw(SkCanvas* canvas) override {
54        canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorGRAY));
55
56        SkPaint paint;
57        canvas->translate(10, 40);
58
59        SkRect bounds = fBlob->bounds();
60        const int yDelta = SkScalarFloorToInt(bounds.height()) + 20;
61        const int xDelta = SkScalarFloorToInt(bounds.width());
62
63        canvas->drawTextBlob(fBlob, 0, 0, paint);
64
65        canvas->translate(SkIntToScalar(xDelta), SkIntToScalar(yDelta));
66
67        // Draw a rect where the text should be, and then twiddle the xfermode so we don't combine.
68        SkPaint redPaint;
69        redPaint.setColor(SK_ColorRED);
70        canvas->drawRect(bounds, redPaint);
71        SkPaint srcInPaint(paint);
72        srcInPaint.setBlendMode(SkBlendMode::kSrcIn);
73        canvas->drawTextBlob(fBlob, 0, 0, srcInPaint);
74
75        canvas->translate(SkIntToScalar(xDelta), SkIntToScalar(yDelta));
76        canvas->drawTextBlob(fBlob, 0, 0, paint);
77    }
78
79private:
80    sk_sp<SkTextBlob> fBlob;
81
82    static constexpr int kWidth = 275;
83    static constexpr int kHeight = 200;
84
85    typedef GM INHERITED;
86};
87
88//////////////////////////////////////////////////////////////////////////////
89
90DEF_GM(return new TextBlobBlockReordering;)
91}
92