• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "bridge/declarative_frontend/engine/bindings.h"
17 #include "bridge/declarative_frontend/jsview/js_offscreen_rendering_context.h"
18 #include "core/components_ng/pattern/custom_paint/offscreen_canvas_pattern.h"
19 
20 namespace OHOS::Ace::Framework {
21 std::unordered_map<uint32_t, RefPtr<OffscreenCanvas>> JSOffscreenRenderingContext::offscreenCanvasMap_;
22 std::unordered_map<uint32_t, RefPtr<NG::OffscreenCanvasPattern>>
23     JSOffscreenRenderingContext::offscreenCanvasPatternMap_;
24 uint32_t JSOffscreenRenderingContext::offscreenCanvasCount_ = 0;
25 uint32_t JSOffscreenRenderingContext::offscreenCanvasPatternCount_ = 0;
26 std::mutex JSOffscreenRenderingContext::mutex_;
27 
JSOffscreenRenderingContext()28 JSOffscreenRenderingContext::JSOffscreenRenderingContext()
29 {
30     if (Container::IsCurrentUseNewPipeline()) {
31         id = offscreenCanvasPatternCount_;
32     } else {
33         id = offscreenCanvasCount_;
34     }
35 }
36 
JSBind(BindingTarget globalObj)37 void JSOffscreenRenderingContext::JSBind(BindingTarget globalObj)
38 {
39     JSClass<JSOffscreenRenderingContext>::Declare("OffscreenCanvasRenderingContext2D");
40 
41     JSClass<JSOffscreenRenderingContext>::CustomMethod("transferToImageBitmap",
42         &JSOffscreenRenderingContext::JsTransferToImageBitmap);
43     JSClass<JSOffscreenRenderingContext>::CustomMethod("toDataURL", &JSCanvasRenderer::JsToDataUrl);
44     JSClass<JSOffscreenRenderingContext>::CustomMethod("createRadialGradient",
45         &JSCanvasRenderer::JsCreateRadialGradient);
46     JSClass<JSOffscreenRenderingContext>::CustomMethod("fillRect", &JSCanvasRenderer::JsFillRect);
47     JSClass<JSOffscreenRenderingContext>::CustomMethod("strokeRect", &JSCanvasRenderer::JsStrokeRect);
48     JSClass<JSOffscreenRenderingContext>::CustomMethod("clearRect", &JSCanvasRenderer::JsClearRect);
49     JSClass<JSOffscreenRenderingContext>::CustomMethod("createLinearGradient",
50         &JSCanvasRenderer::JsCreateLinearGradient);
51     JSClass<JSOffscreenRenderingContext>::CustomMethod("fillText", &JSCanvasRenderer::JsFillText);
52     JSClass<JSOffscreenRenderingContext>::CustomMethod("strokeText", &JSCanvasRenderer::JsStrokeText);
53     JSClass<JSOffscreenRenderingContext>::CustomMethod("measureText", &JSCanvasRenderer::JsMeasureText);
54     JSClass<JSOffscreenRenderingContext>::CustomMethod("moveTo", &JSCanvasRenderer::JsMoveTo);
55     JSClass<JSOffscreenRenderingContext>::CustomMethod("lineTo", &JSCanvasRenderer::JsLineTo);
56     JSClass<JSOffscreenRenderingContext>::CustomMethod("bezierCurveTo", &JSCanvasRenderer::JsBezierCurveTo);
57     JSClass<JSOffscreenRenderingContext>::CustomMethod("quadraticCurveTo", &JSCanvasRenderer::JsQuadraticCurveTo);
58     JSClass<JSOffscreenRenderingContext>::CustomMethod("arcTo", &JSCanvasRenderer::JsArcTo);
59     JSClass<JSOffscreenRenderingContext>::CustomMethod("arc", &JSCanvasRenderer::JsArc);
60     JSClass<JSOffscreenRenderingContext>::CustomMethod("ellipse", &JSCanvasRenderer::JsEllipse);
61     JSClass<JSOffscreenRenderingContext>::CustomMethod("fill", &JSCanvasRenderer::JsFill);
62     JSClass<JSOffscreenRenderingContext>::CustomMethod("stroke", &JSCanvasRenderer::JsStroke);
63     JSClass<JSOffscreenRenderingContext>::CustomMethod("clip", &JSCanvasRenderer::JsClip);
64     JSClass<JSOffscreenRenderingContext>::CustomMethod("rect", &JSCanvasRenderer::JsRect);
65     JSClass<JSOffscreenRenderingContext>::CustomMethod("beginPath", &JSCanvasRenderer::JsBeginPath);
66     JSClass<JSOffscreenRenderingContext>::CustomMethod("closePath", &JSCanvasRenderer::JsClosePath);
67     JSClass<JSOffscreenRenderingContext>::CustomMethod("restore", &JSCanvasRenderer::JsRestore);
68     JSClass<JSOffscreenRenderingContext>::CustomMethod("save", &JSCanvasRenderer::JsSave);
69     JSClass<JSOffscreenRenderingContext>::CustomMethod("rotate", &JSCanvasRenderer::JsRotate);
70     JSClass<JSOffscreenRenderingContext>::CustomMethod("scale", &JSCanvasRenderer::JsScale);
71     JSClass<JSOffscreenRenderingContext>::CustomMethod("getTransform", &JSCanvasRenderer::JsGetTransform);
72     JSClass<JSOffscreenRenderingContext>::CustomMethod("setTransform", &JSCanvasRenderer::JsSetTransform);
73     JSClass<JSOffscreenRenderingContext>::CustomMethod("resetTransform", &JSCanvasRenderer::JsResetTransform);
74     JSClass<JSOffscreenRenderingContext>::CustomMethod("transform", &JSCanvasRenderer::JsTransform);
75     JSClass<JSOffscreenRenderingContext>::CustomMethod("translate", &JSCanvasRenderer::JsTranslate);
76     JSClass<JSOffscreenRenderingContext>::CustomMethod("setLineDash", &JSCanvasRenderer::JsSetLineDash);
77     JSClass<JSOffscreenRenderingContext>::CustomMethod("getLineDash", &JSCanvasRenderer::JsGetLineDash);
78     JSClass<JSOffscreenRenderingContext>::CustomMethod("drawImage", &JSCanvasRenderer::JsDrawImage);
79     JSClass<JSOffscreenRenderingContext>::CustomMethod("createPattern", &JSCanvasRenderer::JsCreatePattern);
80     JSClass<JSOffscreenRenderingContext>::CustomMethod("createImageData", &JSCanvasRenderer::JsCreateImageData);
81     JSClass<JSOffscreenRenderingContext>::CustomMethod("putImageData", &JSCanvasRenderer::JsPutImageData);
82     JSClass<JSOffscreenRenderingContext>::CustomMethod("getImageData", &JSCanvasRenderer::JsGetImageData);
83     JSClass<JSOffscreenRenderingContext>::CustomMethod("getJsonData", &JSCanvasRenderer::JsGetJsonData);
84     JSClass<JSOffscreenRenderingContext>::CustomMethod("getPixelMap", &JSCanvasRenderer::JsGetPixelMap);
85     JSClass<JSOffscreenRenderingContext>::CustomMethod("setPixelMap", &JSCanvasRenderer::JsSetPixelMap);
86     JSClass<JSOffscreenRenderingContext>::CustomMethod("filter", &JSCanvasRenderer::JsFilter);
87     JSClass<JSOffscreenRenderingContext>::CustomMethod("direction", &JSCanvasRenderer::JsDirection);
88 
89     JSClass<JSOffscreenRenderingContext>::CustomProperty("fillStyle", &JSCanvasRenderer::JsGetFillStyle,
90         &JSCanvasRenderer::JsSetFillStyle);
91     JSClass<JSOffscreenRenderingContext>::CustomProperty("strokeStyle", &JSCanvasRenderer::JsGetStrokeStyle,
92         &JSCanvasRenderer::JsSetStrokeStyle);
93     JSClass<JSOffscreenRenderingContext>::CustomProperty("lineCap", &JSCanvasRenderer::JsGetLineCap,
94         &JSCanvasRenderer::JsSetLineCap);
95     JSClass<JSOffscreenRenderingContext>::CustomProperty("lineJoin", &JSCanvasRenderer::JsGetLineJoin,
96         &JSCanvasRenderer::JsSetLineJoin);
97     JSClass<JSOffscreenRenderingContext>::CustomProperty("miterLimit", &JSCanvasRenderer::JsGetMiterLimit,
98         &JSCanvasRenderer::JsSetMiterLimit);
99     JSClass<JSOffscreenRenderingContext>::CustomProperty("lineWidth", &JSCanvasRenderer::JsGetLineWidth,
100         &JSCanvasRenderer::JsSetLineWidth);
101     JSClass<JSOffscreenRenderingContext>::CustomProperty("font", &JSCanvasRenderer::JsGetFont,
102         &JSCanvasRenderer::JsSetFont);
103     JSClass<JSOffscreenRenderingContext>::CustomProperty("textAlign", &JSCanvasRenderer::JsGetTextAlign,
104         &JSCanvasRenderer::JsSetTextAlign);
105     JSClass<JSOffscreenRenderingContext>::CustomProperty("textBaseline", &JSCanvasRenderer::JsGetTextBaseline,
106         &JSCanvasRenderer::JsSetTextBaseline);
107     JSClass<JSOffscreenRenderingContext>::CustomProperty("globalAlpha", &JSCanvasRenderer::JsGetGlobalAlpha,
108         &JSCanvasRenderer::JsSetGlobalAlpha);
109     JSClass<JSOffscreenRenderingContext>::CustomProperty("globalCompositeOperation",
110         &JSCanvasRenderer::JsGetGlobalCompositeOperation, &JSCanvasRenderer::JsSetGlobalCompositeOperation);
111     JSClass<JSOffscreenRenderingContext>::CustomProperty("lineDashOffset", &JSCanvasRenderer::JsGetLineDashOffset,
112         &JSCanvasRenderer::JsSetLineDashOffset);
113     JSClass<JSOffscreenRenderingContext>::CustomProperty("shadowBlur", &JSCanvasRenderer::JsGetShadowBlur,
114         &JSCanvasRenderer::JsSetShadowBlur);
115     JSClass<JSOffscreenRenderingContext>::CustomProperty("shadowColor", &JSCanvasRenderer::JsGetShadowColor,
116         &JSCanvasRenderer::JsSetShadowColor);
117     JSClass<JSOffscreenRenderingContext>::CustomProperty("shadowOffsetX", &JSCanvasRenderer::JsGetShadowOffsetX,
118         &JSCanvasRenderer::JsSetShadowOffsetX);
119     JSClass<JSOffscreenRenderingContext>::CustomProperty("shadowOffsetY", &JSCanvasRenderer::JsGetShadowOffsetY,
120         &JSCanvasRenderer::JsSetShadowOffsetY);
121     JSClass<JSOffscreenRenderingContext>::CustomProperty("imageSmoothingEnabled",
122         &JSCanvasRenderer::JsGetImageSmoothingEnabled, &JSCanvasRenderer::JsSetImageSmoothingEnabled);
123     JSClass<JSOffscreenRenderingContext>::CustomProperty("imageSmoothingQuality",
124         &JSCanvasRenderer::JsGetImageSmoothingQuality, &JSCanvasRenderer::JsSetImageSmoothingQuality);
125 
126     JSClass<JSOffscreenRenderingContext>::Bind(globalObj, JSOffscreenRenderingContext::Constructor,
127         JSOffscreenRenderingContext::Destructor);
128 }
129 
Constructor(const JSCallbackInfo & args)130 void JSOffscreenRenderingContext::Constructor(const JSCallbackInfo& args)
131 {
132     auto jsRenderContext = Referenced::MakeRefPtr<JSOffscreenRenderingContext>();
133     jsRenderContext->IncRefCount();
134     args.SetReturnValue(Referenced::RawPtr(jsRenderContext));
135 
136     if (args.Length() < 3) {
137         LOGE("The arg is wrong, it is supposed to have atleast 3 arguments");
138         return;
139     }
140     if (args[0]->IsNumber() && args[1]->IsNumber()) {
141         double fWidth = 0.0;
142         double fHeight = 0.0;
143         int width = 0;
144         int height = 0;
145         JSViewAbstract::ParseJsDouble(args[0], fWidth);
146         JSViewAbstract::ParseJsDouble(args[1], fHeight);
147 
148         fWidth = SystemProperties::Vp2Px(fWidth);
149         fHeight = SystemProperties::Vp2Px(fHeight);
150         width = round(fWidth);
151         height = round(fHeight);
152 
153         auto container = Container::Current();
154         CHECK_NULL_VOID(container);
155         if (Container::IsCurrentUseNewPipeline()) {
156             auto offscreenCanvasPattern = AceType::MakeRefPtr<NG::OffscreenCanvasPattern>(width, height);
157             jsRenderContext->SetOffscreenCanvasPattern(offscreenCanvasPattern);
158             LOGI("SetOffscreenCanvasPattern successfully");
159             std::lock_guard<std::mutex> lock(mutex_);
160             offscreenCanvasPatternMap_[offscreenCanvasPatternCount_++] = offscreenCanvasPattern;
161         } else {
162             auto context = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
163             CHECK_NULL_VOID(context);
164             auto offscreenCanvas = context->CreateOffscreenCanvas(width, height);
165             jsRenderContext->SetOffscreenCanvas(offscreenCanvas);
166             LOGI("SetOffscreenCanvas successfully");
167             std::lock_guard<std::mutex> lock(mutex_);
168             offscreenCanvasMap_[offscreenCanvasCount_++] = offscreenCanvas;
169         }
170     }
171     if (args[2]->IsObject()) {
172         JSRenderingContextSettings* jsContextSetting
173             = JSRef<JSObject>::Cast(args[2])->Unwrap<JSRenderingContextSettings>();
174         if (jsContextSetting == nullptr) {
175             LOGE("jsContextSetting is null");
176             return;
177         }
178         bool anti = jsContextSetting->GetAntialias();
179         jsRenderContext->SetAnti(anti);
180         jsRenderContext->SetAntiAlias();
181     }
182 }
183 
Destructor(JSOffscreenRenderingContext * context)184 void JSOffscreenRenderingContext::Destructor(JSOffscreenRenderingContext* context)
185 {
186     uint32_t contextId;
187     if (context != nullptr) {
188         contextId = context->GetId();
189         context->DecRefCount();
190     } else {
191         LOGE("comtext is null");
192         return;
193     }
194     std::lock_guard<std::mutex> lock(mutex_);
195     offscreenCanvasMap_.erase(contextId);
196     if (Container::IsCurrentUseNewPipeline()) {
197         offscreenCanvasPatternMap_.erase(contextId);
198     }
199 }
200 
JsTransferToImageBitmap(const JSCallbackInfo & info)201 void JSOffscreenRenderingContext::JsTransferToImageBitmap(const JSCallbackInfo& info)
202 {
203     auto retObj = JSRef<JSObject>::New();
204     retObj->SetProperty("__id", id);
205     info.SetReturnValue(retObj);
206 }
207 
208 } // namespace OHOS::Ace::Framework
209