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