1 /* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FOUNDATION_ACE_FRAMEWORK_JAVASCRIPT_BRIDGE_JS_VIEW_JS_CANVAS_RENDERER_H 17 #define FOUNDATION_ACE_FRAMEWORK_JAVASCRIPT_BRIDGE_JS_VIEW_JS_CANVAS_RENDERER_H 18 19 #include "base/memory/referenced.h" 20 #include "bridge/common/utils/utils.h" 21 #include "bridge/declarative_frontend/engine/bindings_defines.h" 22 #include "bridge/declarative_frontend/jsview/canvas/js_canvas_gradient.h" 23 #include "bridge/declarative_frontend/jsview/canvas/js_canvas_image_data.h" 24 #include "bridge/declarative_frontend/jsview/canvas/js_canvas_path.h" 25 #include "bridge/declarative_frontend/jsview/canvas/js_matrix2d.h" 26 #include "bridge/declarative_frontend/jsview/canvas/js_path2d.h" 27 #include "bridge/declarative_frontend/jsview/canvas/js_rendering_context_base.h" 28 #include "bridge/declarative_frontend/jsview/canvas/js_render_image.h" 29 #include "bridge/declarative_frontend/jsview/js_container_base.h" 30 #include "bridge/declarative_frontend/jsview/js_view_abstract.h" 31 #include "core/components_ng/pattern/canvas/rendering_context_2d_model.h" 32 33 namespace OHOS::Ace::Framework { 34 35 class JSCanvasRenderer : public JSRenderingContextBase { 36 DECLARE_ACE_TYPE(JSCanvasRenderer, JSRenderingContextBase) 37 public: 38 JSCanvasRenderer(); 39 ~JSCanvasRenderer() override; 40 41 enum class FunctionCode { 42 FILL_RECT = 0, 43 STROKE_RECT, 44 CLEAR_RECT, 45 FILL_TEXT, 46 STROKE_TEXT, 47 FILL_STYLE_SETTER, 48 STROKE_STYLE_SETTER, 49 }; 50 51 static RefPtr<CanvasPath2D> JsMakePath2D(const JSCallbackInfo& info); 52 void SetAntiAlias() override; 53 void SetDensity() override; 54 55 void ParseImageData(const JSCallbackInfo& info, ImageData& imageData); 56 void JsCloseImageBitmap(const std::string& src); 57 58 void JsFillRect(const JSCallbackInfo& info); 59 void JsStrokeRect(const JSCallbackInfo& info); 60 void JsClearRect(const JSCallbackInfo& info); 61 void JsFillText(const JSCallbackInfo& info); 62 void JsStrokeText(const JSCallbackInfo& info); 63 void JsMeasureText(const JSCallbackInfo& info); 64 void JsMoveTo(const JSCallbackInfo& info); 65 void JsLineTo(const JSCallbackInfo& info); 66 void JsBezierCurveTo(const JSCallbackInfo& info); 67 void JsQuadraticCurveTo(const JSCallbackInfo& info); 68 void JsArcTo(const JSCallbackInfo& info); 69 void JsArc(const JSCallbackInfo& info); 70 void JsEllipse(const JSCallbackInfo& info); 71 void JsFill(const JSCallbackInfo& info); 72 void JsStroke(const JSCallbackInfo& info); 73 void JsClip(const JSCallbackInfo& info); 74 void JsRect(const JSCallbackInfo& info); 75 void JsBeginPath(const JSCallbackInfo& info); 76 void JsClosePath(const JSCallbackInfo& info); 77 void JsRestore(const JSCallbackInfo& info); 78 void JsSave(const JSCallbackInfo& info); 79 void JsRotate(const JSCallbackInfo& info); 80 void JsScale(const JSCallbackInfo& info); 81 void JsGetTransform(const JSCallbackInfo& info); 82 void JsSetTransform(const JSCallbackInfo& info); 83 void JsResetTransform(const JSCallbackInfo& info); 84 void JsTransform(const JSCallbackInfo& info); 85 void JsTranslate(const JSCallbackInfo& info); 86 void JsSetLineDash(const JSCallbackInfo& info); 87 void JsGetLineDash(const JSCallbackInfo& info); 88 void JsToDataUrl(const JSCallbackInfo& info); 89 void JsCreateLinearGradient(const JSCallbackInfo& info); 90 void JsCreateRadialGradient(const JSCallbackInfo& info); 91 void JsCreateConicGradient(const JSCallbackInfo& info); 92 void JsSaveLayer(const JSCallbackInfo& info); 93 void JsRestoreLayer(const JSCallbackInfo& info); 94 void JsSetFont(const JSCallbackInfo& info); 95 void JsSetFillStyle(const JSCallbackInfo& info); 96 void JsSetStrokeStyle(const JSCallbackInfo& info); 97 void JsSetLineCap(const JSCallbackInfo& info); 98 void JsSetLineJoin(const JSCallbackInfo& info); 99 void JsSetMiterLimit(const JSCallbackInfo& info); 100 void JsSetLineWidth(const JSCallbackInfo& info); 101 void JsSetGlobalAlpha(const JSCallbackInfo& info); 102 void JsSetGlobalCompositeOperation(const JSCallbackInfo& info); 103 void JsSetLineDashOffset(const JSCallbackInfo& info); 104 void JsSetShadowBlur(const JSCallbackInfo& info); 105 void JsSetShadowColor(const JSCallbackInfo& info); 106 void JsSetShadowOffsetX(const JSCallbackInfo& info); 107 void JsSetShadowOffsetY(const JSCallbackInfo& info); 108 void JsSetImageSmoothingEnabled(const JSCallbackInfo& info); 109 void JsDrawImage(const JSCallbackInfo& info); 110 void JsCreatePattern(const JSCallbackInfo& info); 111 void JsCreateImageData(const JSCallbackInfo& info); 112 void JsPutImageData(const JSCallbackInfo& info); 113 void JsGetImageData(const JSCallbackInfo& info); 114 void JsGetJsonData(const JSCallbackInfo& info); 115 void JsSetTextAlign(const JSCallbackInfo& info); 116 void JsSetTextBaseline(const JSCallbackInfo& info); 117 void JsSetImageSmoothingQuality(const JSCallbackInfo& info); 118 void JsGetPixelMap(const JSCallbackInfo& info); 119 void JsSetPixelMap(const JSCallbackInfo& info); 120 void JsDrawBitmapMesh(const JSCallbackInfo& info); 121 void JsSetFilter(const JSCallbackInfo& info); 122 void JsSetDirection(const JSCallbackInfo& info); 123 void JsReset(const JSCallbackInfo& info); 124 void JsSetLetterSpacing(const JSCallbackInfo& info); 125 JSGetEmpty(const JSCallbackInfo & info)126 void JSGetEmpty(const JSCallbackInfo& info) 127 { 128 return; 129 } 130 SetCanvasPattern(const RefPtr<AceType> & canvas)131 void SetCanvasPattern(const RefPtr<AceType>& canvas) override 132 { 133 renderingContext2DModel_->SetPattern(canvas); 134 if (isInitializeShadow_) { 135 return; 136 } 137 isInitializeShadow_ = true; 138 renderingContext2DModel_->SetShadowColor(Color::TRANSPARENT); 139 } 140 SetOffscreenPattern(const RefPtr<AceType> & offscreenCanvas)141 void SetOffscreenPattern(const RefPtr<AceType>& offscreenCanvas) 142 { 143 offscreenPattern_ = offscreenCanvas; 144 renderingContext2DModel_->SetPattern(offscreenCanvas); 145 if (isOffscreenInitializeShadow_) { 146 return; 147 } 148 isOffscreenInitializeShadow_ = true; 149 renderingContext2DModel_->SetShadowColor(Color::TRANSPARENT); 150 } 151 SetAnti(bool anti)152 void SetAnti(bool anti) 153 { 154 anti_ = anti; 155 } 156 GetAnti()157 bool GetAnti() 158 { 159 return anti_; 160 } 161 SetUnit(CanvasUnit unit)162 void SetUnit(CanvasUnit unit) 163 { 164 unit_ = unit; 165 } 166 GetUnit()167 CanvasUnit GetUnit() 168 { 169 return unit_; 170 } 171 172 inline double GetDensity(bool useSystemDensity = false) 173 { 174 if (useSystemDensity) { 175 return !NearZero(density_) ? density_ : 1.0; 176 } else { 177 return ((GetUnit() == CanvasUnit::DEFAULT) && !NearZero(density_)) ? density_ : 1.0; 178 } 179 } 180 SetInstanceId(int32_t id)181 void SetInstanceId(int32_t id) override 182 { 183 instanceId_ = id; 184 } 185 186 void SetTransform(unsigned int id, const TransformParam&); 187 188 void ResetPaintState(); 189 ACE_DISALLOW_COPY_AND_MOVE(JSCanvasRenderer); 190 191 protected: 192 void ParseFillGradient(const JSCallbackInfo& info); 193 void ParseFillPattern(const JSCallbackInfo& info); 194 void ParseStorkeGradient(const JSCallbackInfo& info); 195 void ParseStrokePattern(const JSCallbackInfo& info); 196 JSRenderImage* UnwrapNapiImage(const JSRef<JSObject> jsObject); 197 198 protected: 199 bool isJudgeSpecialValue_ = false; 200 RefPtr<RenderingContext2DModel> renderingContext2DModel_; 201 bool anti_ = false; 202 203 RefPtr<AceType> offscreenPattern_; 204 205 int32_t instanceId_ = INSTANCE_ID_UNDEFINED; 206 207 int32_t apiVersion_ = 0; 208 209 private: 210 void ExtractInfoToImage(CanvasImage& image, const JSCallbackInfo& info, bool isImage); 211 JSRef<JSObject> createGradientObj(const std::shared_ptr<Gradient>& gradient); 212 void DrawSvgImage(const JSCallbackInfo& info, JSRenderImage* jsImage); 213 void DrawImage(const JSCallbackInfo& info, JSRenderImage* jsImage); 214 void DrawPixelMap(const JSCallbackInfo& info); 215 216 PaintState paintState_; 217 std::vector<PaintState> savePaintState_; 218 static std::unordered_map<int32_t, std::shared_ptr<Pattern>> pattern_; 219 static unsigned int patternCount_; 220 std::weak_ptr<Ace::Pattern> GetPatternNG(int32_t id); 221 Pattern GetPattern(unsigned int id); 222 std::shared_ptr<Pattern> GetPatternPtr(int32_t id); 223 bool isInitializeShadow_ = false; 224 bool isOffscreenInitializeShadow_ = false; 225 Dimension GetDimensionValue(const std::string& str); 226 bool IsCustomFont(const std::string& fontName); 227 bool IsValidLetterSpacing(const std::string& letterSpacing); 228 CanvasUnit unit_ = CanvasUnit::DEFAULT; 229 double density_ = 1.0; 230 int32_t densityCallbackId_ = 0; 231 }; 232 233 } // namespace OHOS::Ace::Framework 234 235 #endif // FOUNDATION_ACE_FRAMEWORK_JAVASCRIPT_BRIDGE_JS_VIEW_JS_CANVAS_RENDERER_H 236