1 /*
2 * Copyright (c) 2021-2022 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 #include "js_rendering_context.h"
17
18 #include "bridge/declarative_frontend/engine/bindings.h"
19 #include "bridge/declarative_frontend/jsview/js_offscreen_rendering_context.h"
20 #include "frameworks/bridge/declarative_frontend/jsview/models/rendering_context_model_impl.h"
21 #include "frameworks/core/components_ng/pattern/rendering_context/rendering_context_model_ng.h"
22
23 namespace OHOS::Ace {
24 std::unique_ptr<RenderingContextModel> RenderingContextModel::instance_ = nullptr;
25 std::mutex RenderingContextModel::mutex_;
GetInstance()26 RenderingContextModel* RenderingContextModel::GetInstance()
27 {
28 if (!instance_) {
29 std::lock_guard<std::mutex> lock(mutex_);
30 if (!instance_) {
31 #ifdef NG_BUILD
32 instance_.reset(new NG::RenderingContextModelNG());
33 #else
34 if (Container::IsCurrentUseNewPipeline()) {
35 instance_.reset(new NG::RenderingContextModelNG());
36 } else {
37 instance_.reset(new Framework::RenderingContextModelImpl());
38 }
39 #endif
40 }
41 }
42 return instance_.get();
43 }
44 } // namespace OHOS::Ace
45
46 namespace OHOS::Ace::Framework {
47
JSRenderingContext()48 JSRenderingContext::JSRenderingContext() {}
49
JSBind(BindingTarget globalObj)50 void JSRenderingContext::JSBind(BindingTarget globalObj)
51 {
52 JSClass<JSRenderingContext>::Declare("CanvasRenderingContext2D");
53
54 JSClass<JSRenderingContext>::CustomMethod("toDataURL", &JSCanvasRenderer::JsToDataUrl);
55 JSClass<JSRenderingContext>::CustomProperty(
56 "width", &JSRenderingContext::JsGetWidth, &JSRenderingContext::JsSetWidth);
57 JSClass<JSRenderingContext>::CustomProperty(
58 "height", &JSRenderingContext::JsGetHeight, &JSRenderingContext::JsSetHeight);
59 JSClass<JSRenderingContext>::CustomMethod("createRadialGradient", &JSCanvasRenderer::JsCreateRadialGradient);
60 JSClass<JSRenderingContext>::CustomMethod("fillRect", &JSCanvasRenderer::JsFillRect);
61 JSClass<JSRenderingContext>::CustomMethod("strokeRect", &JSCanvasRenderer::JsStrokeRect);
62 JSClass<JSRenderingContext>::CustomMethod("clearRect", &JSCanvasRenderer::JsClearRect);
63 JSClass<JSRenderingContext>::CustomMethod("createLinearGradient", &JSCanvasRenderer::JsCreateLinearGradient);
64 JSClass<JSRenderingContext>::CustomMethod("fillText", &JSCanvasRenderer::JsFillText);
65 JSClass<JSRenderingContext>::CustomMethod("strokeText", &JSCanvasRenderer::JsStrokeText);
66 JSClass<JSRenderingContext>::CustomMethod("measureText", &JSCanvasRenderer::JsMeasureText);
67 JSClass<JSRenderingContext>::CustomMethod("moveTo", &JSCanvasRenderer::JsMoveTo);
68 JSClass<JSRenderingContext>::CustomMethod("lineTo", &JSCanvasRenderer::JsLineTo);
69 JSClass<JSRenderingContext>::CustomMethod("bezierCurveTo", &JSCanvasRenderer::JsBezierCurveTo);
70 JSClass<JSRenderingContext>::CustomMethod("quadraticCurveTo", &JSCanvasRenderer::JsQuadraticCurveTo);
71 JSClass<JSRenderingContext>::CustomMethod("arcTo", &JSCanvasRenderer::JsArcTo);
72 JSClass<JSRenderingContext>::CustomMethod("arc", &JSCanvasRenderer::JsArc);
73 JSClass<JSRenderingContext>::CustomMethod("ellipse", &JSCanvasRenderer::JsEllipse);
74 JSClass<JSRenderingContext>::CustomMethod("fill", &JSCanvasRenderer::JsFill);
75 JSClass<JSRenderingContext>::CustomMethod("stroke", &JSCanvasRenderer::JsStroke);
76 JSClass<JSRenderingContext>::CustomMethod("clip", &JSCanvasRenderer::JsClip);
77 JSClass<JSRenderingContext>::CustomMethod("rect", &JSCanvasRenderer::JsRect);
78 JSClass<JSRenderingContext>::CustomMethod("beginPath", &JSCanvasRenderer::JsBeginPath);
79 JSClass<JSRenderingContext>::CustomMethod("closePath", &JSCanvasRenderer::JsClosePath);
80 JSClass<JSRenderingContext>::CustomMethod("restore", &JSCanvasRenderer::JsRestore);
81 JSClass<JSRenderingContext>::CustomMethod("save", &JSCanvasRenderer::JsSave);
82 JSClass<JSRenderingContext>::CustomMethod("rotate", &JSCanvasRenderer::JsRotate);
83 JSClass<JSRenderingContext>::CustomMethod("scale", &JSCanvasRenderer::JsScale);
84 JSClass<JSRenderingContext>::CustomMethod("getTransform", &JSCanvasRenderer::JsGetTransform);
85 JSClass<JSRenderingContext>::CustomMethod("setTransform", &JSCanvasRenderer::JsSetTransform);
86 JSClass<JSRenderingContext>::CustomMethod("resetTransform", &JSCanvasRenderer::JsResetTransform);
87 JSClass<JSRenderingContext>::CustomMethod("transform", &JSCanvasRenderer::JsTransform);
88 JSClass<JSRenderingContext>::CustomMethod("translate", &JSCanvasRenderer::JsTranslate);
89 JSClass<JSRenderingContext>::CustomMethod("setLineDash", &JSCanvasRenderer::JsSetLineDash);
90 JSClass<JSRenderingContext>::CustomMethod("getLineDash", &JSCanvasRenderer::JsGetLineDash);
91 JSClass<JSRenderingContext>::CustomMethod("drawImage", &JSCanvasRenderer::JsDrawImage);
92 JSClass<JSRenderingContext>::CustomMethod("createPattern", &JSCanvasRenderer::JsCreatePattern);
93 JSClass<JSRenderingContext>::CustomMethod("createImageData", &JSCanvasRenderer::JsCreateImageData);
94 JSClass<JSRenderingContext>::CustomMethod("putImageData", &JSCanvasRenderer::JsPutImageData);
95 JSClass<JSRenderingContext>::CustomMethod("getImageData", &JSCanvasRenderer::JsGetImageData);
96 JSClass<JSRenderingContext>::CustomMethod("getJsonData", &JSCanvasRenderer::JsGetJsonData);
97 JSClass<JSRenderingContext>::CustomMethod("getPixelMap", &JSCanvasRenderer::JsGetPixelMap);
98 JSClass<JSRenderingContext>::CustomMethod("setPixelMap", &JSCanvasRenderer::JsSetPixelMap);
99 JSClass<JSRenderingContext>::CustomMethod("drawBitmapMesh", &JSCanvasRenderer::JsDrawBitmapMesh);
100 JSClass<JSRenderingContext>::CustomProperty(
101 "filter", &JSCanvasRenderer::JsGetFilter, &JSCanvasRenderer::JsSetFilter);
102 JSClass<JSRenderingContext>::CustomProperty(
103 "direction", &JSCanvasRenderer::JsGetDirection, &JSCanvasRenderer::JsSetDirection);
104
105 JSClass<JSRenderingContext>::CustomProperty(
106 "fillStyle", &JSCanvasRenderer::JsGetFillStyle, &JSCanvasRenderer::JsSetFillStyle);
107 JSClass<JSRenderingContext>::CustomProperty(
108 "strokeStyle", &JSCanvasRenderer::JsGetStrokeStyle, &JSCanvasRenderer::JsSetStrokeStyle);
109 JSClass<JSRenderingContext>::CustomProperty(
110 "lineCap", &JSCanvasRenderer::JsGetLineCap, &JSCanvasRenderer::JsSetLineCap);
111 JSClass<JSRenderingContext>::CustomProperty(
112 "lineJoin", &JSCanvasRenderer::JsGetLineJoin, &JSCanvasRenderer::JsSetLineJoin);
113 JSClass<JSRenderingContext>::CustomProperty(
114 "miterLimit", &JSCanvasRenderer::JsGetMiterLimit, &JSCanvasRenderer::JsSetMiterLimit);
115 JSClass<JSRenderingContext>::CustomProperty(
116 "lineWidth", &JSCanvasRenderer::JsGetLineWidth, &JSCanvasRenderer::JsSetLineWidth);
117 JSClass<JSRenderingContext>::CustomProperty("font", &JSCanvasRenderer::JsGetFont, &JSCanvasRenderer::JsSetFont);
118 JSClass<JSRenderingContext>::CustomProperty(
119 "textAlign", &JSCanvasRenderer::JsGetTextAlign, &JSCanvasRenderer::JsSetTextAlign);
120 JSClass<JSRenderingContext>::CustomProperty(
121 "textBaseline", &JSCanvasRenderer::JsGetTextBaseline, &JSCanvasRenderer::JsSetTextBaseline);
122 JSClass<JSRenderingContext>::CustomProperty(
123 "globalAlpha", &JSCanvasRenderer::JsGetGlobalAlpha, &JSCanvasRenderer::JsSetGlobalAlpha);
124 JSClass<JSRenderingContext>::CustomProperty("globalCompositeOperation",
125 &JSCanvasRenderer::JsGetGlobalCompositeOperation, &JSCanvasRenderer::JsSetGlobalCompositeOperation);
126 JSClass<JSRenderingContext>::CustomProperty(
127 "lineDashOffset", &JSCanvasRenderer::JsGetLineDashOffset, &JSCanvasRenderer::JsSetLineDashOffset);
128 JSClass<JSRenderingContext>::CustomProperty(
129 "shadowBlur", &JSCanvasRenderer::JsGetShadowBlur, &JSCanvasRenderer::JsSetShadowBlur);
130 JSClass<JSRenderingContext>::CustomProperty(
131 "shadowColor", &JSCanvasRenderer::JsGetShadowColor, &JSCanvasRenderer::JsSetShadowColor);
132 JSClass<JSRenderingContext>::CustomProperty(
133 "shadowOffsetX", &JSCanvasRenderer::JsGetShadowOffsetX, &JSCanvasRenderer::JsSetShadowOffsetX);
134 JSClass<JSRenderingContext>::CustomProperty(
135 "shadowOffsetY", &JSCanvasRenderer::JsGetShadowOffsetY, &JSCanvasRenderer::JsSetShadowOffsetY);
136 JSClass<JSRenderingContext>::CustomProperty("imageSmoothingEnabled", &JSCanvasRenderer::JsGetImageSmoothingEnabled,
137 &JSCanvasRenderer::JsSetImageSmoothingEnabled);
138 JSClass<JSRenderingContext>::CustomProperty("imageSmoothingQuality", &JSCanvasRenderer::JsGetImageSmoothingQuality,
139 &JSCanvasRenderer::JsSetImageSmoothingQuality);
140 JSClass<JSRenderingContext>::CustomMethod(
141 "transferFromImageBitmap", &JSRenderingContext::JsTransferFromImageBitmap);
142
143 JSClass<JSRenderingContext>::CustomMethod("createConicGradient", &JSCanvasRenderer::JsCreateConicGradient);
144
145 JSClass<JSRenderingContext>::Bind(globalObj, JSRenderingContext::Constructor, JSRenderingContext::Destructor);
146 }
147
Constructor(const JSCallbackInfo & args)148 void JSRenderingContext::Constructor(const JSCallbackInfo& args)
149 {
150 auto jsRenderContext = Referenced::MakeRefPtr<JSRenderingContext>();
151 jsRenderContext->IncRefCount();
152 args.SetReturnValue(Referenced::RawPtr(jsRenderContext));
153
154 if (args.Length() != 0) {
155 if (args[0]->IsObject()) {
156 JSRenderingContextSettings* jsContextSetting =
157 JSRef<JSObject>::Cast(args[0])->Unwrap<JSRenderingContextSettings>();
158 if (jsContextSetting == nullptr) {
159 LOGE("jsContextSetting is null");
160 return;
161 }
162 bool anti = jsContextSetting->GetAntialias();
163 jsRenderContext->SetAnti(anti);
164 }
165 }
166 }
167
Destructor(JSRenderingContext * controller)168 void JSRenderingContext::Destructor(JSRenderingContext* controller)
169 {
170 if (controller != nullptr) {
171 controller->DecRefCount();
172 }
173 }
174
JsGetWidth(const JSCallbackInfo & info)175 void JSRenderingContext::JsGetWidth(const JSCallbackInfo& info)
176 {
177 double width = 0.0;
178 RenderingContextModel::GetInstance()->GetWidth(canvasPattern_, width);
179
180 width = SystemProperties::Px2Vp(width);
181 auto returnValue = JSVal(ToJSValue(width));
182 auto returnPtr = JSRef<JSVal>::Make(returnValue);
183 info.SetReturnValue(returnPtr);
184 }
185
JsSetWidth(const JSCallbackInfo & info)186 void JSRenderingContext::JsSetWidth(const JSCallbackInfo& info)
187 {
188 return;
189 }
190
JsSetHeight(const JSCallbackInfo & info)191 void JSRenderingContext::JsSetHeight(const JSCallbackInfo& info)
192 {
193 return;
194 }
195
JsGetHeight(const JSCallbackInfo & info)196 void JSRenderingContext::JsGetHeight(const JSCallbackInfo& info)
197 {
198 double height = 0.0;
199 RenderingContextModel::GetInstance()->GetHeight(canvasPattern_, height);
200
201 height = SystemProperties::Px2Vp(height);
202 auto returnValue = JSVal(ToJSValue(height));
203 auto returnPtr = JSRef<JSVal>::Make(returnValue);
204 info.SetReturnValue(returnPtr);
205 }
206
JsTransferFromImageBitmap(const JSCallbackInfo & info)207 void JSRenderingContext::JsTransferFromImageBitmap(const JSCallbackInfo& info)
208 {
209 if (info.Length() == 0) {
210 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
211 return;
212 }
213 if (!info[0]->IsObject()) {
214 LOGE("The arg is not Object or String.");
215 return;
216 }
217 uint32_t id = 0;
218 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
219 JSRef<JSVal> widthId = obj->GetProperty("__id");
220 JSViewAbstract::ParseJsInteger(widthId, id);
221 RefPtr<AceType> offscreenPattern = JSOffscreenRenderingContext::GetOffscreenPattern(id);
222 RenderingContextModel::GetInstance()->SetTransferFromImageBitmap(
223 canvasPattern_, offscreenPattern);
224 }
225 } // namespace OHOS::Ace::Framework
226