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