1/*
2 * Copyright 2017 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#ifndef SkAtlasTextTarget_DEFINED
9#define SkAtlasTextTarget_DEFINED
10
11#include <memory>
12#include "SkDeque.h"
13#include "SkRefCnt.h"
14#include "SkScalar.h"
15
16class SkAtlasTextContext;
17class SkAtlasTextFont;
18class SkMatrix;
19struct SkPoint;
20
21/** Represents a client-created renderable surface and is used to draw text into the surface. */
22class SK_API SkAtlasTextTarget {
23public:
24    virtual ~SkAtlasTextTarget();
25
26    /**
27     * Creates a text drawing target. ‘handle’ is used to identify this rendering surface when
28     * draws are flushed to the SkAtlasTextContext's SkAtlasTextRenderer.
29     */
30    static std::unique_ptr<SkAtlasTextTarget> Make(sk_sp<SkAtlasTextContext>, int width, int height,
31                                                   void* handle);
32
33    /**
34     * Enqueues a text draw in the target. The caller provides an array of glyphs and their
35     * positions. The meaning of 'color' here is interpreted by the client's SkAtlasTextRenderer
36     * when it actually renders the text.
37     */
38    virtual void drawText(const SkGlyphID[], const SkPoint[], int glyphCnt, uint32_t color,
39                          const SkAtlasTextFont&) = 0;
40
41    /** Issues all queued text draws to SkAtlasTextRenderer. */
42    virtual void flush() = 0;
43
44    int width() const { return fWidth; }
45    int height() const { return fHeight; }
46
47    void* handle() const { return fHandle; }
48
49    SkAtlasTextContext* context() const { return fContext.get(); }
50
51    /** Saves the current matrix in a stack. Returns the prior depth of the saved matrix stack. */
52    int save();
53    /** Pops the top matrix on the stack if the stack is not empty. */
54    void restore();
55    /**
56     * Pops the matrix stack until the stack depth is count. Does nothing if the depth is already
57     * less than count.
58     */
59    void restoreToCount(int count);
60
61    /** Pre-translates the current CTM. */
62    void translate(SkScalar dx, SkScalar dy);
63    /** Pre-scales the current CTM. */
64    void scale(SkScalar sx, SkScalar sy);
65    /** Pre-rotates the current CTM about the origin. */
66    void rotate(SkScalar degrees);
67    /** Pre-rotates the current CTM about the (px, py). */
68    void rotate(SkScalar degrees, SkScalar px, SkScalar py);
69    /** Pre-skews the current CTM. */
70    void skew(SkScalar sx, SkScalar sy);
71    /** Pre-concats the current CTM. */
72    void concat(const SkMatrix& matrix);
73
74protected:
75    SkAtlasTextTarget(sk_sp<SkAtlasTextContext>, int width, int height, void* handle);
76
77    const SkMatrix& ctm() const { return *static_cast<const SkMatrix*>(fMatrixStack.back()); }
78
79    void* const fHandle;
80    const sk_sp<SkAtlasTextContext> fContext;
81    const int fWidth;
82    const int fHeight;
83
84private:
85    SkDeque fMatrixStack;
86    int fSaveCnt;
87
88    SkMatrix* accessCTM() const {
89        return static_cast<SkMatrix*>(const_cast<void*>(fMatrixStack.back()));
90    }
91
92    SkAtlasTextTarget() = delete;
93    SkAtlasTextTarget(const SkAtlasTextContext&) = delete;
94    SkAtlasTextTarget& operator=(const SkAtlasTextContext&) = delete;
95};
96
97#endif
98