• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "base/utils/utils.h"
17 #include "bridge/declarative_frontend/engine/bindings.h"
18 #include "bridge/declarative_frontend/jsview/js_offscreen_canvas.h"
19 
20 namespace OHOS::Ace::Framework {
JSBind(BindingTarget globalObj)21 void JSOffscreenCanvas::JSBind(BindingTarget globalObj)
22 {
23     JSClass<JSOffscreenCanvas>::Declare("OffscreenCanvas");
24     JSClass<JSOffscreenCanvas>::CustomProperty("width", &JSOffscreenCanvas::JsGetWidth,
25         &JSOffscreenCanvas::JsSetWidth);
26     JSClass<JSOffscreenCanvas>::CustomProperty("height", &JSOffscreenCanvas::JsGetHeight,
27         &JSOffscreenCanvas::JsSetHeight);
28     JSClass<JSOffscreenCanvas>::CustomMethod("transferToImageBitmap",
29         &JSOffscreenCanvas::JsTransferToImageBitmap);
30     JSClass<JSOffscreenCanvas>::CustomMethod("getContext", &JSOffscreenCanvas::JsGetContext);
31 
32     JSClass<JSOffscreenCanvas>::CustomMethod("createRadialGradient",
33         &JSOffscreenCanvas::JsCreateRadialGradient);
34     JSClass<JSOffscreenCanvas>::CustomMethod("fillRect", &JSOffscreenCanvas::JsFillRect);
35     JSClass<JSOffscreenCanvas>::CustomMethod("strokeRect", &JSOffscreenCanvas::JsStrokeRect);
36     JSClass<JSOffscreenCanvas>::CustomMethod("clearRect", &JSOffscreenCanvas::JsClearRect);
37     JSClass<JSOffscreenCanvas>::CustomMethod("createLinearGradient",
38         &JSOffscreenCanvas::JsCreateLinearGradient);
39     JSClass<JSOffscreenCanvas>::CustomMethod("fillText", &JSOffscreenCanvas::JsFillText);
40     JSClass<JSOffscreenCanvas>::CustomMethod("strokeText", &JSOffscreenCanvas::JsStrokeText);
41     JSClass<JSOffscreenCanvas>::CustomMethod("measureText", &JSOffscreenCanvas::JsMeasureText);
42     JSClass<JSOffscreenCanvas>::CustomMethod("moveTo", &JSOffscreenCanvas::JsMoveTo);
43     JSClass<JSOffscreenCanvas>::CustomMethod("lineTo", &JSOffscreenCanvas::JsLineTo);
44     JSClass<JSOffscreenCanvas>::CustomMethod("bezierCurveTo", &JSOffscreenCanvas::JsBezierCurveTo);
45     JSClass<JSOffscreenCanvas>::CustomMethod("quadraticCurveTo", &JSOffscreenCanvas::JsQuadraticCurveTo);
46     JSClass<JSOffscreenCanvas>::CustomMethod("arcTo", &JSOffscreenCanvas::JsArcTo);
47     JSClass<JSOffscreenCanvas>::CustomMethod("arc", &JSOffscreenCanvas::JsArc);
48     JSClass<JSOffscreenCanvas>::CustomMethod("ellipse", &JSOffscreenCanvas::JsEllipse);
49     JSClass<JSOffscreenCanvas>::CustomMethod("fill", &JSOffscreenCanvas::JsFill);
50     JSClass<JSOffscreenCanvas>::CustomMethod("stroke", &JSOffscreenCanvas::JsStroke);
51     JSClass<JSOffscreenCanvas>::CustomMethod("clip", &JSOffscreenCanvas::JsClip);
52     JSClass<JSOffscreenCanvas>::CustomMethod("rect", &JSOffscreenCanvas::JsRect);
53     JSClass<JSOffscreenCanvas>::CustomMethod("beginPath", &JSOffscreenCanvas::JsBeginPath);
54     JSClass<JSOffscreenCanvas>::CustomMethod("closePath", &JSOffscreenCanvas::JsClosePath);
55     JSClass<JSOffscreenCanvas>::CustomMethod("restore", &JSOffscreenCanvas::JsRestore);
56     JSClass<JSOffscreenCanvas>::CustomMethod("save", &JSOffscreenCanvas::JsSave);
57     JSClass<JSOffscreenCanvas>::CustomMethod("rotate", &JSOffscreenCanvas::JsRotate);
58     JSClass<JSOffscreenCanvas>::CustomMethod("scale", &JSOffscreenCanvas::JsScale);
59     JSClass<JSOffscreenCanvas>::CustomMethod("getTransform", &JSOffscreenCanvas::JsGetTransform);
60     JSClass<JSOffscreenCanvas>::CustomMethod("setTransform", &JSOffscreenCanvas::JsSetTransform);
61     JSClass<JSOffscreenCanvas>::CustomMethod("resetTransform", &JSOffscreenCanvas::JsResetTransform);
62     JSClass<JSOffscreenCanvas>::CustomMethod("transform", &JSOffscreenCanvas::JsTransform);
63     JSClass<JSOffscreenCanvas>::CustomMethod("translate", &JSOffscreenCanvas::JsTranslate);
64     JSClass<JSOffscreenCanvas>::CustomMethod("setLineDash", &JSOffscreenCanvas::JsSetLineDash);
65     JSClass<JSOffscreenCanvas>::CustomMethod("getLineDash", &JSOffscreenCanvas::JsGetLineDash);
66     JSClass<JSOffscreenCanvas>::CustomMethod("drawImage", &JSOffscreenCanvas::JsDrawImage);
67     JSClass<JSOffscreenCanvas>::CustomMethod("createPattern", &JSOffscreenCanvas::JsCreatePattern);
68     JSClass<JSOffscreenCanvas>::CustomMethod("createImageData", &JSOffscreenCanvas::JsCreateImageData);
69     JSClass<JSOffscreenCanvas>::CustomMethod("putImageData", &JSOffscreenCanvas::JsPutImageData);
70     JSClass<JSOffscreenCanvas>::CustomMethod("getImageData", &JSOffscreenCanvas::JsGetImageData);
71     JSClass<JSOffscreenCanvas>::CustomMethod("getJsonData", &JSOffscreenCanvas::JsGetJsonData);
72     JSClass<JSOffscreenCanvas>::CustomMethod("getPixelMap", &JSOffscreenCanvas::JsGetPixelMap);
73     JSClass<JSOffscreenCanvas>::CustomMethod("setPixelMap", &JSOffscreenCanvas::JsSetPixelMap);
74     JSClass<JSOffscreenCanvas>::CustomMethod("createConicGradient", &JSOffscreenCanvas::JsCreateConicGradient);
75     JSClass<JSOffscreenCanvas>::CustomMethod("transferFromImageBitmap", &JSOffscreenCanvas::JSTransferFromImageBitmap);
76     JSClass<JSOffscreenCanvas>::CustomProperty("filter", &JSOffscreenCanvas::JsGetFilter,
77         &JSOffscreenCanvas::JsSetFilter);
78     JSClass<JSOffscreenCanvas>::CustomProperty("direction", &JSOffscreenCanvas::JsGetDirection,
79         &JSOffscreenCanvas::JsSetDirection);
80     JSClass<JSOffscreenCanvas>::CustomProperty("fillStyle", &JSOffscreenCanvas::JsGetFillStyle,
81         &JSOffscreenCanvas::JsSetFillStyle);
82     JSClass<JSOffscreenCanvas>::CustomProperty("strokeStyle", &JSOffscreenCanvas::JsGetStrokeStyle,
83         &JSOffscreenCanvas::JsSetStrokeStyle);
84     JSClass<JSOffscreenCanvas>::CustomProperty("lineCap", &JSOffscreenCanvas::JsGetLineCap,
85         &JSOffscreenCanvas::JsSetLineCap);
86     JSClass<JSOffscreenCanvas>::CustomProperty("lineJoin", &JSOffscreenCanvas::JsGetLineJoin,
87         &JSOffscreenCanvas::JsSetLineJoin);
88     JSClass<JSOffscreenCanvas>::CustomProperty("miterLimit", &JSOffscreenCanvas::JsGetMiterLimit,
89         &JSOffscreenCanvas::JsSetMiterLimit);
90     JSClass<JSOffscreenCanvas>::CustomProperty("lineWidth", &JSOffscreenCanvas::JsGetLineWidth,
91         &JSOffscreenCanvas::JsSetLineWidth);
92     JSClass<JSOffscreenCanvas>::CustomProperty("font", &JSOffscreenCanvas::JsGetFont,
93         &JSOffscreenCanvas::JsSetFont);
94     JSClass<JSOffscreenCanvas>::CustomProperty("textAlign", &JSOffscreenCanvas::JsGetTextAlign,
95         &JSOffscreenCanvas::JsSetTextAlign);
96     JSClass<JSOffscreenCanvas>::CustomProperty("textBaseline", &JSOffscreenCanvas::JsGetTextBaseline,
97         &JSOffscreenCanvas::JsSetTextBaseline);
98     JSClass<JSOffscreenCanvas>::CustomProperty("globalAlpha", &JSOffscreenCanvas::JsGetGlobalAlpha,
99         &JSOffscreenCanvas::JsSetGlobalAlpha);
100     JSClass<JSOffscreenCanvas>::CustomProperty("globalCompositeOperation",
101         &JSOffscreenCanvas::JsGetGlobalCompositeOperation, &JSOffscreenCanvas::JsSetGlobalCompositeOperation);
102     JSClass<JSOffscreenCanvas>::CustomProperty("lineDashOffset", &JSOffscreenCanvas::JsGetLineDashOffset,
103         &JSOffscreenCanvas::JsSetLineDashOffset);
104     JSClass<JSOffscreenCanvas>::CustomProperty("shadowBlur", &JSOffscreenCanvas::JsGetShadowBlur,
105         &JSOffscreenCanvas::JsSetShadowBlur);
106     JSClass<JSOffscreenCanvas>::CustomProperty("shadowColor", &JSOffscreenCanvas::JsGetShadowColor,
107         &JSOffscreenCanvas::JsSetShadowColor);
108     JSClass<JSOffscreenCanvas>::CustomProperty("shadowOffsetX", &JSOffscreenCanvas::JsGetShadowOffsetX,
109         &JSOffscreenCanvas::JsSetShadowOffsetX);
110     JSClass<JSOffscreenCanvas>::CustomProperty("shadowOffsetY", &JSOffscreenCanvas::JsGetShadowOffsetY,
111         &JSOffscreenCanvas::JsSetShadowOffsetY);
112     JSClass<JSOffscreenCanvas>::CustomProperty("imageSmoothingEnabled",
113         &JSOffscreenCanvas::JsGetImageSmoothingEnabled, &JSOffscreenCanvas::JsSetImageSmoothingEnabled);
114     JSClass<JSOffscreenCanvas>::CustomProperty("imageSmoothingQuality",
115         &JSOffscreenCanvas::JsGetImageSmoothingQuality, &JSOffscreenCanvas::JsSetImageSmoothingQuality);
116     JSClass<JSOffscreenCanvas>::Bind(globalObj, JSOffscreenCanvas::Constructor, JSOffscreenCanvas::Destructor);
117 }
118 
Constructor(const JSCallbackInfo & args)119 void JSOffscreenCanvas::Constructor(const JSCallbackInfo& args)
120 {
121     if (args.Length() < 2) {
122         LOGE("The arg is wrong, it is supposed to have at least 2 argument");
123         return;
124     }
125     if (Container::IsCurrentUseNewPipeline() && args[0]->IsNumber() && args[1]->IsNumber()) {
126         auto offscreenCanvas = Referenced::MakeRefPtr<JSOffscreenCanvas>();
127         CHECK_NULL_VOID(offscreenCanvas);
128         offscreenCanvas->IncRefCount();
129         double fWidth = 0.0;
130         double fHeight = 0.0;
131         if (JSViewAbstract::ParseJsDouble(args[0], fWidth)) {
132             fWidth = SystemProperties::Vp2Px(fWidth);
133             offscreenCanvas->SetWidth(round(fWidth));
134         }
135         if (JSViewAbstract::ParseJsDouble(args[1], fHeight)) {
136             fHeight = SystemProperties::Vp2Px(fHeight);
137             offscreenCanvas->SetHeight(round(fHeight));
138         }
139         args.SetReturnValue(Referenced::RawPtr(offscreenCanvas));
140     }
141 }
142 
Destructor(JSOffscreenCanvas * context)143 void JSOffscreenCanvas::Destructor(JSOffscreenCanvas* context)
144 {
145     if (context != nullptr) {
146         context->DecRefCount();
147     } else {
148         LOGE("context is null");
149         return;
150     }
151 }
152 
JsGetWidth(const JSCallbackInfo & info)153 void JSOffscreenCanvas::JsGetWidth(const JSCallbackInfo& info)
154 {
155     double fWidth = SystemProperties::Px2Vp(GetWidth());
156     auto returnValue = JSVal(ToJSValue(fWidth));
157     auto returnPtr = JSRef<JSVal>::Make(returnValue);
158     info.SetReturnValue(returnPtr);
159 }
160 
JsGetHeight(const JSCallbackInfo & info)161 void JSOffscreenCanvas::JsGetHeight(const JSCallbackInfo& info)
162 {
163     double fHeight = SystemProperties::Px2Vp(GetHeight());
164     auto returnValue = JSVal(ToJSValue(fHeight));
165     auto returnPtr = JSRef<JSVal>::Make(returnValue);
166     info.SetReturnValue(returnPtr);
167 }
168 
JsSetWidth(const JSCallbackInfo & info)169 void JSOffscreenCanvas::JsSetWidth(const JSCallbackInfo& info)
170 {
171     if (info.Length() != 1) {
172         LOGE("The arg is wrong, it is supposed to have 1 argument");
173         return;
174     }
175     if (info[0]->IsUndefined() || info[0]->IsNull()) {
176         return;
177     }
178     double width = 0.0;
179     if (JSViewAbstract::ParseJsDouble(info[0], width)) {
180         width_ = SystemProperties::Vp2Px(width);
181     } else {
182         return;
183     }
184 
185     if (contextType_ == ContextType::CONTEXT_2D) {
186         CreateContext2d(width_, GetHeight());
187     }
188     return;
189 }
190 
JsSetHeight(const JSCallbackInfo & info)191 void JSOffscreenCanvas::JsSetHeight(const JSCallbackInfo& info)
192 {
193     if (info.Length() != 1) {
194         LOGE("The arg is wrong, it is supposed to have 1 argument");
195         return;
196     }
197 
198     if (info[0]->IsUndefined() || info[0]->IsNull()) {
199         return;
200     }
201     double height = 0.0;
202     if (JSViewAbstract::ParseJsDouble(info[0], height)) {
203         height_ = SystemProperties::Vp2Px(height);
204     } else {
205         return;
206     }
207 
208     if (contextType_ == ContextType::CONTEXT_2D) {
209         CreateContext2d(GetWidth(), height_);
210     }
211     return;
212 }
213 
JsTransferToImageBitmap(const JSCallbackInfo & info)214 void JSOffscreenCanvas::JsTransferToImageBitmap(const JSCallbackInfo& info)
215 {
216     if (Container::IsCurrentUseNewPipeline()) {
217         CHECK_NULL_VOID(offscreenCanvasContext_);
218         CHECK_NULL_VOID(offscreenCanvasPattern_);
219         auto final_height = static_cast<uint32_t>(GetHeight());
220         auto final_width = static_cast<uint32_t>(GetWidth());
221         JSRef<JSObject> renderImage = JSRef<JSObject>::New();
222         renderImage->SetProperty("__type", "ImageBitmap");
223         renderImage->SetProperty("__id", offscreenCanvasContext_->GetId());
224         renderImage->SetProperty("height", final_height);
225         renderImage->SetProperty("width", final_width);
226         info.SetReturnValue(renderImage);
227     }
228 }
229 
JsGetContext(const JSCallbackInfo & info)230 void JSOffscreenCanvas::JsGetContext(const JSCallbackInfo& info)
231 {
232     if (info.Length() < 1 || info.Length() > 2) {
233         LOGE("The arg is wrong, it is supposed to have at least 1 argument and at most 2 arguments");
234         return;
235     }
236     if (info[0]->IsUndefined() || info[0]->IsNull()) {
237         LOGE("Invalid arguments.");
238         return;
239     }
240     if (!Container::IsCurrentUseNewPipeline()) {
241         return;
242     }
243 
244     if (info[0]->IsString()) {
245         std::string ruleStr;
246         JSViewAbstract::ParseJsString(info[0], ruleStr);
247         if (ruleStr == "2d") {
248             contextType_ = ContextType::CONTEXT_2D;
249             auto contextObj = CreateContext2d(GetWidth(), GetHeight());
250             if (contextObj->IsEmpty()) {
251                 return;
252             }
253             JSRef<JSVal> isSucceed = contextObj->GetProperty("__isSucceed");
254             if (isSucceed->IsBoolean() && !isSucceed->ToBoolean()) {
255                 return;
256             }
257             if (info[1]->IsObject()) {
258                 offscreenCanvasSettings_ = JSRef<JSObject>::Cast(info[1])->Unwrap<JSRenderingContextSettings>();
259                 CHECK_NULL_VOID(offscreenCanvasSettings_);
260                 bool anti = offscreenCanvasSettings_->GetAntialias();
261                 offscreenCanvasContext_->SetAnti(anti);
262                 offscreenCanvasContext_->SetAntiAlias();
263             }
264             info.SetReturnValue(contextObj);
265         }
266     }
267 }
268 
CreateContext2d(double width,double height)269 JSRef<JSObject> JSOffscreenCanvas::CreateContext2d(double width, double height)
270 {
271     JSRef<JSObject> contextObj = JSClass<JSOffscreenRenderingContext>::NewInstance();
272     if (contextObj->IsEmpty()) {
273         return contextObj;
274     }
275     contextObj->SetProperty("__type", "OffscreenCanvasRenderingContext2D");
276     offscreenCanvasContext_ = Referenced::Claim(contextObj->Unwrap<JSOffscreenRenderingContext>());
277     offscreenCanvasPattern_ = AceType::MakeRefPtr<NG::OffscreenCanvasPattern>(
278         static_cast<int32_t>(width), static_cast<int32_t>(height));
279     CHECK_NULL_RETURN(offscreenCanvasPattern_, contextObj);
280     if (!offscreenCanvasPattern_->IsSucceed()) {
281         contextObj->SetProperty("__isSucceed", false);
282         return contextObj;
283     }
284     contextObj->SetProperty("__isSucceed", true);
285     offscreenCanvasContext_->SetOffscreenPattern(offscreenCanvasPattern_);
286     offscreenCanvasContext_->AddOffscreenCanvasPattern(offscreenCanvasPattern_);
287     CHECK_NULL_RETURN(offscreenCanvasSettings_, contextObj);
288     bool anti = offscreenCanvasSettings_->GetAntialias();
289     offscreenCanvasContext_->SetAnti(anti);
290     offscreenCanvasContext_->SetAntiAlias();
291     return contextObj;
292 }
293 } // namespace OHOS::Ace::Framework
294