/* * Copyright 2017 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkAtlasTextTarget_DEFINED #define SkAtlasTextTarget_DEFINED #include <memory> #include "SkDeque.h" #include "SkRefCnt.h" #include "SkScalar.h" class SkAtlasTextContext; class SkAtlasTextFont; class SkMatrix; struct SkPoint; /** Represents a client-created renderable surface and is used to draw text into the surface. */ class SK_API SkAtlasTextTarget { public: virtual ~SkAtlasTextTarget(); /** * Creates a text drawing target. ‘handle’ is used to identify this rendering surface when * draws are flushed to the SkAtlasTextContext's SkAtlasTextRenderer. */ static std::unique_ptr<SkAtlasTextTarget> Make(sk_sp<SkAtlasTextContext>, int width, int height, void* handle); /** * Enqueues a text draw in the target. The caller provides an array of glyphs and their * positions. The meaning of 'color' here is interpreted by the client's SkAtlasTextRenderer * when it actually renders the text. */ virtual void drawText(const SkGlyphID[], const SkPoint[], int glyphCnt, uint32_t color, const SkAtlasTextFont&) = 0; /** Issues all queued text draws to SkAtlasTextRenderer. */ virtual void flush() = 0; int width() const { return fWidth; } int height() const { return fHeight; } void* handle() const { return fHandle; } SkAtlasTextContext* context() const { return fContext.get(); } /** Saves the current matrix in a stack. Returns the prior depth of the saved matrix stack. */ int save(); /** Pops the top matrix on the stack if the stack is not empty. */ void restore(); /** * Pops the matrix stack until the stack depth is count. Does nothing if the depth is already * less than count. */ void restoreToCount(int count); /** Pre-translates the current CTM. */ void translate(SkScalar dx, SkScalar dy); /** Pre-scales the current CTM. */ void scale(SkScalar sx, SkScalar sy); /** Pre-rotates the current CTM about the origin. */ void rotate(SkScalar degrees); /** Pre-rotates the current CTM about the (px, py). */ void rotate(SkScalar degrees, SkScalar px, SkScalar py); /** Pre-skews the current CTM. */ void skew(SkScalar sx, SkScalar sy); /** Pre-concats the current CTM. */ void concat(const SkMatrix& matrix); protected: SkAtlasTextTarget(sk_sp<SkAtlasTextContext>, int width, int height, void* handle); const SkMatrix& ctm() const { return *static_cast<const SkMatrix*>(fMatrixStack.back()); } void* const fHandle; const sk_sp<SkAtlasTextContext> fContext; const int fWidth; const int fHeight; private: SkDeque fMatrixStack; int fSaveCnt; SkMatrix* accessCTM() const { return static_cast<SkMatrix*>(const_cast<void*>(fMatrixStack.back())); } SkAtlasTextTarget() = delete; SkAtlasTextTarget(const SkAtlasTextContext&) = delete; SkAtlasTextTarget& operator=(const SkAtlasTextContext&) = delete; }; #endif