1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cutils/compiler.h>
20 #include <utils/Functor.h>
21 
22 #include <androidfw/ResourceTypes.h>
23 #include "GlFunctorLifecycleListener.h"
24 #include "Properties.h"
25 #include "utils/Macros.h"
26 
27 #include <SkBitmap.h>
28 #include <SkCanvas.h>
29 #include <SkMatrix.h>
30 
31 class SkAnimatedImage;
32 class SkCanvasState;
33 class SkVertices;
34 
35 namespace minikin {
36 class Layout;
37 class MeasuredText;
38 enum class Bidi : uint8_t;
39 }
40 
41 namespace android {
42 class PaintFilter;
43 
44 namespace uirenderer {
45 class CanvasPropertyPaint;
46 class CanvasPropertyPrimitive;
47 class DeferredLayerUpdater;
48 class RenderNode;
49 
50 namespace skiapipeline {
51 class SkiaDisplayList;
52 }
53 
54 /**
55  * Data structure that holds the list of commands used in display list stream
56  */
57 using DisplayList = skiapipeline::SkiaDisplayList;
58 }
59 
60 namespace SaveFlags {
61 
62 // These must match the corresponding Canvas API constants.
63 enum {
64     Matrix = 0x01,
65     Clip = 0x02,
66     HasAlphaLayer = 0x04,
67     ClipToLayer = 0x10,
68 
69     // Helper constant
70     MatrixClip = Matrix | Clip,
71 };
72 typedef uint32_t Flags;
73 
74 }  // namespace SaveFlags
75 
76 namespace uirenderer {
77 namespace VectorDrawable {
78 class Tree;
79 }
80 }
81 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
82 
83 typedef std::function<void(uint16_t* text, float* positions)> ReadGlyphFunc;
84 
85 class AnimatedImageDrawable;
86 class Bitmap;
87 class Paint;
88 struct Typeface;
89 
90 class ANDROID_API Canvas {
91 public:
~Canvas()92     virtual ~Canvas(){};
93 
94     static Canvas* create_canvas(const SkBitmap& bitmap);
95 
96     /**
97      *  Create a new Canvas object that records view system drawing operations for deferred
98      *  rendering. A canvas returned by this call supports calls to the resetRecording(...) and
99      *  finishRecording() calls.  The latter call returns a DisplayList that is specific to the
100      *  RenderPipeline defined by Properties::getRenderPipelineType().
101      *
102      *  @param width of the requested Canvas.
103      *  @param height of the requested Canvas.
104      *  @param renderNode is an optional parameter that specifies the node that will consume the
105      *      DisplayList produced by the returned Canvas.  This enables the reuse of select C++
106      *      objects as a speed optimization.
107      *  @return new non-null Canvas Object.  The type of DisplayList produced by this canvas is
108             determined based on Properties::getRenderPipelineType().
109      *
110      */
111     static WARN_UNUSED_RESULT Canvas* create_recording_canvas(
112             int width, int height, uirenderer::RenderNode* renderNode = nullptr);
113 
114     /**
115      *  Create a new Canvas object which delegates to an SkCanvas.
116      *
117      *  @param skiaCanvas Must not be NULL. All drawing calls will be
118      *      delegated to this object. This function will call ref() on the
119      *      SkCanvas, and the returned Canvas will unref() it upon
120      *      destruction.
121      *  @return new non-null Canvas Object.  The type of DisplayList produced by this canvas is
122      *      determined based on  Properties::getRenderPipelineType().
123      */
124     static Canvas* create_canvas(SkCanvas* skiaCanvas);
125 
126     /**
127      *  Sets the target SDK version used to build the app.
128      *
129      *  @param apiLevel API level
130      *
131      */
132     static void setCompatibilityVersion(int apiLevel);
133 
134     virtual void setBitmap(const SkBitmap& bitmap) = 0;
135 
136     virtual bool isOpaque() = 0;
137     virtual int width() = 0;
138     virtual int height() = 0;
139 
140     // ----------------------------------------------------------------------------
141     // View System operations (not exposed in public Canvas API)
142     // ----------------------------------------------------------------------------
143 
144     virtual void resetRecording(int width, int height,
145                                 uirenderer::RenderNode* renderNode = nullptr) = 0;
146     virtual uirenderer::DisplayList* finishRecording() = 0;
147     virtual void insertReorderBarrier(bool enableReorder) = 0;
148 
isHighContrastText()149     bool isHighContrastText() const { return uirenderer::Properties::enableHighContrastText; }
150 
151     virtual void drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
152                                uirenderer::CanvasPropertyPrimitive* top,
153                                uirenderer::CanvasPropertyPrimitive* right,
154                                uirenderer::CanvasPropertyPrimitive* bottom,
155                                uirenderer::CanvasPropertyPrimitive* rx,
156                                uirenderer::CanvasPropertyPrimitive* ry,
157                                uirenderer::CanvasPropertyPaint* paint) = 0;
158     virtual void drawCircle(uirenderer::CanvasPropertyPrimitive* x,
159                             uirenderer::CanvasPropertyPrimitive* y,
160                             uirenderer::CanvasPropertyPrimitive* radius,
161                             uirenderer::CanvasPropertyPaint* paint) = 0;
162 
163     virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) = 0;
164     virtual void drawRenderNode(uirenderer::RenderNode* renderNode) = 0;
165     virtual void callDrawGLFunction(Functor* functor,
166                                     uirenderer::GlFunctorLifecycleListener* listener) = 0;
drawWebViewFunctor(int)167     virtual void drawWebViewFunctor(int /*functor*/) {
168         LOG_ALWAYS_FATAL("Not supported");
169     }
170 
171     // ----------------------------------------------------------------------------
172     // Canvas state operations
173     // ----------------------------------------------------------------------------
174 
175     // Save (layer)
176     virtual int getSaveCount() const = 0;
177     virtual int save(SaveFlags::Flags flags) = 0;
178     virtual void restore() = 0;
179     virtual void restoreToCount(int saveCount) = 0;
180     virtual void restoreUnclippedLayer(int saveCount, const SkPaint& paint) = 0;
181 
182     virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
183                           SaveFlags::Flags flags) = 0;
184     virtual int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
185                                SaveFlags::Flags flags) = 0;
186     virtual int saveUnclippedLayer(int, int, int, int) = 0;
187 
188     // Matrix
189     virtual void getMatrix(SkMatrix* outMatrix) const = 0;
190     virtual void setMatrix(const SkMatrix& matrix) = 0;
191 
192     virtual void concat(const SkMatrix& matrix) = 0;
193     virtual void rotate(float degrees) = 0;
194     virtual void scale(float sx, float sy) = 0;
195     virtual void skew(float sx, float sy) = 0;
196     virtual void translate(float dx, float dy) = 0;
197 
198     // clip
199     virtual bool getClipBounds(SkRect* outRect) const = 0;
200     virtual bool quickRejectRect(float left, float top, float right, float bottom) const = 0;
201     virtual bool quickRejectPath(const SkPath& path) const = 0;
202 
203     virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) = 0;
204     virtual bool clipPath(const SkPath* path, SkClipOp op) = 0;
205 
206     // filters
207     virtual PaintFilter* getPaintFilter() = 0;
208     virtual void setPaintFilter(sk_sp<PaintFilter> paintFilter) = 0;
209 
210     // WebView only
captureCanvasState()211     virtual SkCanvasState* captureCanvasState() const { return nullptr; }
212 
213     // ----------------------------------------------------------------------------
214     // Canvas draw operations
215     // ----------------------------------------------------------------------------
216     virtual void drawColor(int color, SkBlendMode mode) = 0;
217     virtual void drawPaint(const SkPaint& paint) = 0;
218 
219     // Geometry
220     virtual void drawPoint(float x, float y, const Paint& paint) = 0;
221     virtual void drawPoints(const float* points, int floatCount, const Paint& paint) = 0;
222     virtual void drawLine(float startX, float startY, float stopX, float stopY,
223                           const Paint& paint) = 0;
224     virtual void drawLines(const float* points, int floatCount, const Paint& paint) = 0;
225     virtual void drawRect(float left, float top, float right, float bottom,
226                           const Paint& paint) = 0;
227     virtual void drawRegion(const SkRegion& region, const Paint& paint) = 0;
228     virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
229                                const Paint& paint) = 0;
230     virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
231                                 const Paint& paint) = 0;
232     virtual void drawCircle(float x, float y, float radius, const Paint& paint) = 0;
233     virtual void drawOval(float left, float top, float right, float bottom,
234                           const Paint& paint) = 0;
235     virtual void drawArc(float left, float top, float right, float bottom, float startAngle,
236                          float sweepAngle, bool useCenter, const Paint& paint) = 0;
237     virtual void drawPath(const SkPath& path, const Paint& paint) = 0;
238     virtual void drawVertices(const SkVertices*, SkBlendMode, const Paint& paint) = 0;
239 
240     // Bitmap-based
241     virtual void drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) = 0;
242     virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const Paint* paint) = 0;
243     virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
244                             float srcBottom, float dstLeft, float dstTop, float dstRight,
245                             float dstBottom, const Paint* paint) = 0;
246     virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
247                                 const float* vertices, const int* colors, const Paint* paint) = 0;
248     virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk, float dstLeft,
249                                float dstTop, float dstRight, float dstBottom,
250                                const Paint* paint) = 0;
251 
252     virtual double drawAnimatedImage(AnimatedImageDrawable* imgDrawable) = 0;
253     virtual void drawPicture(const SkPicture& picture) = 0;
254 
255     /**
256      * Draws a VectorDrawable onto the canvas.
257      */
258     virtual void drawVectorDrawable(VectorDrawableRoot* tree) = 0;
259 
260     /**
261      * Converts utf16 text to glyphs, calculating position and boundary,
262      * and delegating the final draw to virtual drawGlyphs method.
263      */
264     void drawText(const uint16_t* text, int textSize, int start, int count, int contextStart,
265                   int contextCount, float x, float y, minikin::Bidi bidiFlags,
266                   const Paint& origPaint, const Typeface* typeface, minikin::MeasuredText* mt);
267 
268     void drawTextOnPath(const uint16_t* text, int count, minikin::Bidi bidiFlags,
269                         const SkPath& path, float hOffset, float vOffset, const Paint& paint,
270                         const Typeface* typeface);
271 
272     void drawDoubleRoundRectXY(float outerLeft, float outerTop, float outerRight,
273                                 float outerBottom, float outerRx, float outerRy, float innerLeft,
274                                 float innerTop, float innerRight, float innerBottom, float innerRx,
275                                 float innerRy, const Paint& paint);
276 
277     void drawDoubleRoundRectRadii(float outerLeft, float outerTop, float outerRight,
278                                 float outerBottom, const float* outerRadii, float innerLeft,
279                                 float innerTop, float innerRight, float innerBottom,
280                                 const float* innerRadii, const Paint& paint);
281 
GetApiLevel()282     static int GetApiLevel() { return sApiLevel; }
283 
284 protected:
285     void drawTextDecorations(float x, float y, float length, const Paint& paint);
286 
287     /**
288      * glyphFunc: valid only for the duration of the call and should not be cached.
289      * drawText: count is of glyphs
290      * totalAdvance: used to define width of text decorations (underlines, strikethroughs).
291      */
292     virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const Paint& paint, float x,
293                             float y, float boundsLeft, float boundsTop, float boundsRight,
294                             float boundsBottom, float totalAdvance) = 0;
295     virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
296                                   const Paint& paint, const SkPath& path, size_t start,
297                                   size_t end) = 0;
298     static int sApiLevel;
299 
300     friend class DrawTextFunctor;
301     friend class DrawTextOnPathFunctor;
302 };
303 
304 }  // namespace android
305