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     /**
135      *  Provides a Skia SkCanvas interface that acts as a proxy to this Canvas.
136      *  It is useful for testing and clients (e.g. Picture/Movie) that expect to
137      *  draw their contents into an SkCanvas.
138      *
139      *  The SkCanvas returned is *only* valid until another Canvas call is made
140      *  that would change state (e.g. matrix or clip). Clients of asSkCanvas()
141      *  are responsible for *not* persisting this pointer.
142      *
143      *  Further, the returned SkCanvas should NOT be unref'd and is valid until
144      *  this canvas is destroyed or a new bitmap is set.
145      */
146     virtual SkCanvas* asSkCanvas() = 0;
147 
148     virtual void setBitmap(const SkBitmap& bitmap) = 0;
149 
150     virtual bool isOpaque() = 0;
151     virtual int width() = 0;
152     virtual int height() = 0;
153 
154     // ----------------------------------------------------------------------------
155     // View System operations (not exposed in public Canvas API)
156     // ----------------------------------------------------------------------------
157 
158     virtual void resetRecording(int width, int height,
159                                 uirenderer::RenderNode* renderNode = nullptr) = 0;
160     virtual uirenderer::DisplayList* finishRecording() = 0;
161     virtual void insertReorderBarrier(bool enableReorder) = 0;
162 
isHighContrastText()163     bool isHighContrastText() const { return uirenderer::Properties::enableHighContrastText; }
164 
165     virtual void drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
166                                uirenderer::CanvasPropertyPrimitive* top,
167                                uirenderer::CanvasPropertyPrimitive* right,
168                                uirenderer::CanvasPropertyPrimitive* bottom,
169                                uirenderer::CanvasPropertyPrimitive* rx,
170                                uirenderer::CanvasPropertyPrimitive* ry,
171                                uirenderer::CanvasPropertyPaint* paint) = 0;
172     virtual void drawCircle(uirenderer::CanvasPropertyPrimitive* x,
173                             uirenderer::CanvasPropertyPrimitive* y,
174                             uirenderer::CanvasPropertyPrimitive* radius,
175                             uirenderer::CanvasPropertyPaint* paint) = 0;
176 
177     virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) = 0;
178     virtual void drawRenderNode(uirenderer::RenderNode* renderNode) = 0;
179     virtual void callDrawGLFunction(Functor* functor,
180                                     uirenderer::GlFunctorLifecycleListener* listener) = 0;
drawWebViewFunctor(int)181     virtual void drawWebViewFunctor(int /*functor*/) {
182         LOG_ALWAYS_FATAL("Not supported");
183     }
184 
185     // ----------------------------------------------------------------------------
186     // Canvas state operations
187     // ----------------------------------------------------------------------------
188 
189     // Save (layer)
190     virtual int getSaveCount() const = 0;
191     virtual int save(SaveFlags::Flags flags) = 0;
192     virtual void restore() = 0;
193     virtual void restoreToCount(int saveCount) = 0;
194     virtual void restoreUnclippedLayer(int saveCount, const SkPaint& paint) = 0;
195 
196     virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
197                           SaveFlags::Flags flags) = 0;
198     virtual int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
199                                SaveFlags::Flags flags) = 0;
200     virtual int saveUnclippedLayer(int, int, int, int) = 0;
201 
202     // Matrix
203     virtual void getMatrix(SkMatrix* outMatrix) const = 0;
204     virtual void setMatrix(const SkMatrix& matrix) = 0;
205 
206     virtual void concat(const SkMatrix& matrix) = 0;
207     virtual void rotate(float degrees) = 0;
208     virtual void scale(float sx, float sy) = 0;
209     virtual void skew(float sx, float sy) = 0;
210     virtual void translate(float dx, float dy) = 0;
211 
212     // clip
213     virtual bool getClipBounds(SkRect* outRect) const = 0;
214     virtual bool quickRejectRect(float left, float top, float right, float bottom) const = 0;
215     virtual bool quickRejectPath(const SkPath& path) const = 0;
216 
217     virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) = 0;
218     virtual bool clipPath(const SkPath* path, SkClipOp op) = 0;
219 
220     // filters
221     virtual PaintFilter* getPaintFilter() = 0;
222     virtual void setPaintFilter(sk_sp<PaintFilter> paintFilter) = 0;
223 
224     // WebView only
captureCanvasState()225     virtual SkCanvasState* captureCanvasState() const { return nullptr; }
226 
227     // ----------------------------------------------------------------------------
228     // Canvas draw operations
229     // ----------------------------------------------------------------------------
230     virtual void drawColor(int color, SkBlendMode mode) = 0;
231     virtual void drawPaint(const SkPaint& paint) = 0;
232 
233     // Geometry
234     virtual void drawPoint(float x, float y, const SkPaint& paint) = 0;
235     virtual void drawPoints(const float* points, int floatCount, const SkPaint& paint) = 0;
236     virtual void drawLine(float startX, float startY, float stopX, float stopY,
237                           const SkPaint& paint) = 0;
238     virtual void drawLines(const float* points, int floatCount, const SkPaint& paint) = 0;
239     virtual void drawRect(float left, float top, float right, float bottom,
240                           const SkPaint& paint) = 0;
241     virtual void drawRegion(const SkRegion& region, const SkPaint& paint) = 0;
242     virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
243                                const SkPaint& paint) = 0;
244     virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
245                                 const SkPaint& paint) = 0;
246     virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) = 0;
247     virtual void drawOval(float left, float top, float right, float bottom,
248                           const SkPaint& paint) = 0;
249     virtual void drawArc(float left, float top, float right, float bottom, float startAngle,
250                          float sweepAngle, bool useCenter, const SkPaint& paint) = 0;
251     virtual void drawPath(const SkPath& path, const SkPaint& paint) = 0;
252     virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint) = 0;
253 
254     // Bitmap-based
255     virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) = 0;
256     virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) = 0;
257     virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
258                             float srcBottom, float dstLeft, float dstTop, float dstRight,
259                             float dstBottom, const SkPaint* paint) = 0;
260     virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
261                                 const float* vertices, const int* colors, const SkPaint* paint) = 0;
262     virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk, float dstLeft,
263                                float dstTop, float dstRight, float dstBottom,
264                                const SkPaint* paint) = 0;
265 
266     virtual double drawAnimatedImage(AnimatedImageDrawable* imgDrawable) = 0;
267 
268     /**
269      * Specifies if the positions passed to ::drawText are absolute or relative
270      * to the (x,y) value provided.
271      *
272      * If true the (x,y) values are ignored. Otherwise, those (x,y) values need
273      * to be added to each glyph's position to get its absolute position.
274      */
275     virtual bool drawTextAbsolutePos() const = 0;
276 
277     /**
278      * Draws a VectorDrawable onto the canvas.
279      */
280     virtual void drawVectorDrawable(VectorDrawableRoot* tree) = 0;
281 
282     /**
283      * Converts utf16 text to glyphs, calculating position and boundary,
284      * and delegating the final draw to virtual drawGlyphs method.
285      */
286     void drawText(const uint16_t* text, int textSize, int start, int count, int contextStart,
287                   int contextCount, float x, float y, minikin::Bidi bidiFlags,
288                   const Paint& origPaint, const Typeface* typeface, minikin::MeasuredText* mt);
289 
290     void drawTextOnPath(const uint16_t* text, int count, minikin::Bidi bidiFlags,
291                         const SkPath& path, float hOffset, float vOffset, const Paint& paint,
292                         const Typeface* typeface);
293 
294     void drawDoubleRoundRectXY(float outerLeft, float outerTop, float outerRight,
295                                 float outerBottom, float outerRx, float outerRy, float innerLeft,
296                                 float innerTop, float innerRight, float innerBottom, float innerRx,
297                                 float innerRy, const SkPaint& paint);
298 
299     void drawDoubleRoundRectRadii(float outerLeft, float outerTop, float outerRight,
300                                 float outerBottom, const float* outerRadii, float innerLeft,
301                                 float innerTop, float innerRight, float innerBottom,
302                                 const float* innerRadii, const SkPaint& paint);
303 
GetApiLevel()304     static int GetApiLevel() { return sApiLevel; }
305 
306 protected:
307     void drawTextDecorations(float x, float y, float length, const Paint& paint);
308 
309     /**
310      * glyphFunc: valid only for the duration of the call and should not be cached.
311      * drawText: count is of glyphs
312      * totalAdvance: used to define width of text decorations (underlines, strikethroughs).
313      */
314     virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const Paint& paint, float x,
315                             float y, float boundsLeft, float boundsTop, float boundsRight,
316                             float boundsBottom, float totalAdvance) = 0;
317     virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
318                                   const Paint& paint, const SkPath& path, size_t start,
319                                   size_t end) = 0;
320     static int sApiLevel;
321 
322     friend class DrawTextFunctor;
323     friend class DrawTextOnPathFunctor;
324 };
325 
326 }  // namespace android
327