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 <SaveFlags.h> 20 #include <SkBitmap.h> 21 #include <SkCanvas.h> 22 #include <SkMatrix.h> 23 #include <androidfw/ResourceTypes.h> 24 #include <cutils/compiler.h> 25 #include <utils/Functor.h> 26 27 #include "Properties.h" 28 #include "pipeline/skia/AnimatedDrawables.h" 29 #include "utils/Macros.h" 30 31 class SkAnimatedImage; 32 enum class SkBlendMode; 33 class SkCanvasState; 34 class SkRRect; 35 class SkRuntimeShaderBuilder; 36 class SkVertices; 37 38 namespace minikin { 39 class Font; 40 class Layout; 41 class MeasuredText; 42 enum class Bidi : uint8_t; 43 } 44 45 namespace android { 46 class PaintFilter; 47 48 namespace uirenderer { 49 class CanvasPropertyPaint; 50 class CanvasPropertyPrimitive; 51 class DeferredLayerUpdater; 52 class RenderNode; 53 namespace VectorDrawable { 54 class Tree; 55 } 56 } 57 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot; 58 59 typedef std::function<void(uint16_t* text, float* positions)> ReadGlyphFunc; 60 61 class AnimatedImageDrawable; 62 class Bitmap; 63 class Mesh; 64 class Paint; 65 struct Typeface; 66 67 enum class DrawTextBlobMode { 68 Normal, 69 HctOutline, 70 HctInner, 71 }; 72 73 inline DrawTextBlobMode gDrawTextBlobMode = DrawTextBlobMode::Normal; 74 75 class ANDROID_API Canvas { 76 public: ~Canvas()77 virtual ~Canvas(){}; 78 79 static Canvas* create_canvas(const SkBitmap& bitmap); 80 81 /** 82 * Create a new Canvas object that records view system drawing operations for deferred 83 * rendering. A canvas returned by this call supports calls to the resetRecording(...) and 84 * finishRecording() calls. The latter call returns a DisplayList that is specific to the 85 * RenderPipeline defined by Properties::getRenderPipelineType(). 86 * 87 * @param width of the requested Canvas. 88 * @param height of the requested Canvas. 89 * @param renderNode is an optional parameter that specifies the node that will consume the 90 * DisplayList produced by the returned Canvas. This enables the reuse of select C++ 91 * objects as a speed optimization. 92 * @return new non-null Canvas Object. The type of DisplayList produced by this canvas is 93 determined based on Properties::getRenderPipelineType(). 94 * 95 */ 96 static WARN_UNUSED_RESULT Canvas* create_recording_canvas( 97 int width, int height, uirenderer::RenderNode* renderNode = nullptr); 98 99 /** 100 * Create a new Canvas object which delegates to an SkCanvas. 101 * 102 * @param skiaCanvas Must not be NULL. All drawing calls will be 103 * delegated to this object. This function will call ref() on the 104 * SkCanvas, and the returned Canvas will unref() it upon 105 * destruction. 106 * @return new non-null Canvas Object. The type of DisplayList produced by this canvas is 107 * determined based on Properties::getRenderPipelineType(). 108 */ 109 static Canvas* create_canvas(SkCanvas* skiaCanvas); 110 111 /** 112 * Sets the target SDK version used to build the app. 113 * 114 * @param apiLevel API level 115 * 116 */ 117 static void setCompatibilityVersion(int apiLevel); 118 119 virtual void setBitmap(const SkBitmap& bitmap) = 0; 120 121 virtual bool isOpaque() = 0; 122 virtual int width() = 0; 123 virtual int height() = 0; 124 125 // ---------------------------------------------------------------------------- 126 // View System operations (not exposed in public Canvas API) 127 // ---------------------------------------------------------------------------- 128 129 virtual void resetRecording(int width, int height, 130 uirenderer::RenderNode* renderNode = nullptr) = 0; 131 virtual void finishRecording(uirenderer::RenderNode* destination) = 0; 132 virtual void enableZ(bool enableZ) = 0; 133 isHighContrastText()134 bool isHighContrastText() const { return uirenderer::Properties::enableHighContrastText; } 135 136 virtual void drawRoundRect(uirenderer::CanvasPropertyPrimitive* left, 137 uirenderer::CanvasPropertyPrimitive* top, 138 uirenderer::CanvasPropertyPrimitive* right, 139 uirenderer::CanvasPropertyPrimitive* bottom, 140 uirenderer::CanvasPropertyPrimitive* rx, 141 uirenderer::CanvasPropertyPrimitive* ry, 142 uirenderer::CanvasPropertyPaint* paint) = 0; 143 virtual void drawCircle(uirenderer::CanvasPropertyPrimitive* x, 144 uirenderer::CanvasPropertyPrimitive* y, 145 uirenderer::CanvasPropertyPrimitive* radius, 146 uirenderer::CanvasPropertyPaint* paint) = 0; 147 virtual void drawRipple(const uirenderer::skiapipeline::RippleDrawableParams& params) = 0; 148 149 virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) = 0; 150 virtual void drawRenderNode(uirenderer::RenderNode* renderNode) = 0; 151 drawWebViewFunctor(int)152 virtual void drawWebViewFunctor(int /*functor*/) { 153 LOG_ALWAYS_FATAL("Not supported"); 154 } 155 156 virtual void punchHole(const SkRRect& rect, float alpha) = 0; 157 158 // ---------------------------------------------------------------------------- 159 // Canvas state operations 160 // ---------------------------------------------------------------------------- 161 162 // Save (layer) 163 virtual int getSaveCount() const = 0; 164 virtual int save(SaveFlags::Flags flags) = 0; 165 virtual void restore() = 0; 166 virtual void restoreToCount(int saveCount) = 0; 167 virtual void restoreUnclippedLayer(int saveCount, const Paint& paint) = 0; 168 169 virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint) = 0; 170 virtual int saveLayerAlpha(float left, float top, float right, float bottom, int alpha) = 0; 171 virtual int saveUnclippedLayer(int, int, int, int) = 0; 172 173 // Matrix 174 virtual void getMatrix(SkMatrix* outMatrix) const = 0; 175 virtual void setMatrix(const SkMatrix& matrix) = 0; 176 177 virtual void concat(const SkMatrix& matrix) = 0; 178 virtual void concat(const SkM44& matrix) = 0; 179 virtual void rotate(float degrees) = 0; 180 virtual void scale(float sx, float sy) = 0; 181 virtual void skew(float sx, float sy) = 0; 182 virtual void translate(float dx, float dy) = 0; 183 184 // clip 185 virtual bool getClipBounds(SkRect* outRect) const = 0; 186 virtual bool quickRejectRect(float left, float top, float right, float bottom) const = 0; 187 virtual bool quickRejectPath(const SkPath& path) const = 0; 188 189 virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) = 0; 190 virtual bool clipPath(const SkPath* path, SkClipOp op) = 0; 191 virtual void clipShader(sk_sp<SkShader> shader, SkClipOp op) = 0; 192 // Resets clip to wide open, used to emulate the now-removed SkClipOp::kReplace on 193 // apps with compatibility < P. Canvases for version P and later are restricted to 194 // intersect and difference at the Java level, matching SkClipOp's definition. 195 // NOTE: These functions are deprecated and will be removed in a future release 196 virtual bool replaceClipRect_deprecated(float left, float top, float right, float bottom) = 0; 197 virtual bool replaceClipPath_deprecated(const SkPath* path) = 0; 198 199 // filters 200 virtual PaintFilter* getPaintFilter() = 0; 201 virtual void setPaintFilter(sk_sp<PaintFilter> paintFilter) = 0; 202 203 // WebView only captureCanvasState()204 virtual SkCanvasState* captureCanvasState() const { return nullptr; } 205 206 // ---------------------------------------------------------------------------- 207 // Canvas draw operations 208 // ---------------------------------------------------------------------------- 209 virtual void drawColor(int color, SkBlendMode mode) = 0; 210 virtual void drawPaint(const Paint& paint) = 0; 211 212 // Geometry 213 virtual void drawPoint(float x, float y, const Paint& paint) = 0; 214 virtual void drawPoints(const float* points, int floatCount, const Paint& paint) = 0; 215 virtual void drawLine(float startX, float startY, float stopX, float stopY, 216 const Paint& paint) = 0; 217 virtual void drawLines(const float* points, int floatCount, const Paint& paint) = 0; 218 virtual void drawRect(float left, float top, float right, float bottom, 219 const Paint& paint) = 0; 220 virtual void drawRegion(const SkRegion& region, const Paint& paint) = 0; 221 virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, 222 const Paint& paint) = 0; 223 virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner, 224 const Paint& paint) = 0; 225 virtual void drawCircle(float x, float y, float radius, const Paint& paint) = 0; 226 virtual void drawOval(float left, float top, float right, float bottom, 227 const Paint& paint) = 0; 228 virtual void drawArc(float left, float top, float right, float bottom, float startAngle, 229 float sweepAngle, bool useCenter, const Paint& paint) = 0; 230 virtual void drawPath(const SkPath& path, const Paint& paint) = 0; 231 virtual void drawVertices(const SkVertices*, SkBlendMode, const Paint& paint) = 0; 232 virtual void drawMesh(const Mesh& mesh, sk_sp<SkBlender>, const Paint& paint) = 0; 233 234 // Bitmap-based 235 virtual void drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) = 0; 236 virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const Paint* paint) = 0; 237 virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight, 238 float srcBottom, float dstLeft, float dstTop, float dstRight, 239 float dstBottom, const Paint* paint) = 0; 240 virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight, 241 const float* vertices, const int* colors, const Paint* paint) = 0; 242 virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk, float dstLeft, 243 float dstTop, float dstRight, float dstBottom, 244 const Paint* paint) = 0; 245 246 virtual double drawAnimatedImage(AnimatedImageDrawable* imgDrawable) = 0; 247 virtual void drawPicture(const SkPicture& picture) = 0; 248 249 /** 250 * Draws a VectorDrawable onto the canvas. 251 */ 252 virtual void drawVectorDrawable(VectorDrawableRoot* tree) = 0; 253 254 void drawGlyphs(const minikin::Font& font, const int* glyphIds, const float* positions, 255 int glyphCount, const Paint& paint); 256 257 /** 258 * Converts utf16 text to glyphs, calculating position and boundary, 259 * and delegating the final draw to virtual drawGlyphs method. 260 */ 261 void drawText(const uint16_t* text, int textSize, int start, int count, int contextStart, 262 int contextCount, float x, float y, minikin::Bidi bidiFlags, 263 const Paint& origPaint, const Typeface* typeface, minikin::MeasuredText* mt); 264 265 void drawTextOnPath(const uint16_t* text, int count, minikin::Bidi bidiFlags, 266 const SkPath& path, float hOffset, float vOffset, const Paint& paint, 267 const Typeface* typeface); 268 269 void drawDoubleRoundRectXY(float outerLeft, float outerTop, float outerRight, 270 float outerBottom, float outerRx, float outerRy, float innerLeft, 271 float innerTop, float innerRight, float innerBottom, float innerRx, 272 float innerRy, const Paint& paint); 273 274 void drawDoubleRoundRectRadii(float outerLeft, float outerTop, float outerRight, 275 float outerBottom, const float* outerRadii, float innerLeft, 276 float innerTop, float innerRight, float innerBottom, 277 const float* innerRadii, const Paint& paint); 278 GetApiLevel()279 static int GetApiLevel() { return sApiLevel; } 280 281 protected: 282 void drawTextDecorations(float x, float y, float length, const Paint& paint); 283 284 /** 285 * glyphFunc: valid only for the duration of the call and should not be cached. 286 * drawText: count is of glyphs 287 * totalAdvance: used to define width of text decorations (underlines, strikethroughs). 288 */ 289 virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const Paint& paint, float x, 290 float y, float totalAdvance) = 0; 291 virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset, 292 const Paint& paint, const SkPath& path, size_t start, 293 size_t end) = 0; 294 static int sApiLevel; 295 296 friend class DrawTextFunctor; 297 friend class DrawTextOnPathFunctor; 298 }; 299 300 } // namespace android 301