From ab1736fca5914e365ad9b2bb968cd3c034b6f65f Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Sat, 20 Apr 2024 12:34:23 +0000 Subject: [PATCH] Improve the performance of the cross-linguistic calling. Signed-off-by: ZhangYu Change-Id: Ie46b2fb6d8483e83f4e467e3b846d55db3b6ed53 --- .../engine/jsi/jsi_types.cpp | 30 ++ .../engine/jsi/jsi_types.h | 6 + .../engine/jsi/jsi_types.inl | 10 + .../jsview/js_canvas_path.cpp | 255 ++++------- .../jsview/js_canvas_renderer.cpp | 410 ++++++------------ .../declarative_frontend/jsview/js_path2d.cpp | 26 +- 6 files changed, 288 insertions(+), 449 deletions(-) diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.cpp index 31d2ec80f3b..e46135a5aeb 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.cpp @@ -422,6 +422,36 @@ void JsiCallbackInfo::ReturnSelf() const retVal_ = thisObj; } +bool JsiCallbackInfo::GetBooleanArg(size_t index, bool& value) const +{ + auto arg = info_->GetCallArgRef(index); + if (arg.IsEmpty() || !arg->IsBoolean()) { + return false; + } + value = arg->ToBoolean(info_->GetVM())->Value(); + return true; +} + +bool JsiCallbackInfo::GetDoubleArg(size_t index, double& value) const +{ + auto arg = info_->GetCallArgRef(index); + if (arg.IsEmpty() || !arg->IsNumber()) { + return false; + } + value = arg->ToNumber(info_->GetVM())->Value(); + return true; +} + +bool JsiCallbackInfo::GetStringArg(size_t index, std::string& value) const +{ + auto arg = info_->GetCallArgRef(index); + if (arg.IsEmpty() || !arg->IsString()) { + return false; + } + value = arg->ToString(info_->GetVM())->ToString(); + return true; +} + // ----------------------- // Implementation of JsiString // ----------------------- diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.h b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.h index be89bee5baf..072cca956f4 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.h +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.h @@ -286,6 +286,12 @@ public: return size_; } + template + T* UnwrapArg(size_t index) const; + bool GetBooleanArg(size_t index, bool& value) const; + bool GetDoubleArg(size_t index, double& value) const; + bool GetStringArg(size_t index, std::string& value) const; + private: mutable size_t size_ = 0; panda::JsiRuntimeCallInfo* info_ = nullptr; diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.inl b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.inl index 43c3dbe9791..2ee051981c8 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.inl +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.inl @@ -193,6 +193,16 @@ void JsiCallbackInfo::SetReturnValue(JsiRef val) const retVal_ = panda::CopyableGlobal(val.Get().GetHandle()); } +template +T* JsiCallbackInfo::UnwrapArg(size_t index) const +{ + auto arg = info_->GetCallArgRef(index); + if (arg.IsEmpty() || !arg->IsObject()) { + return nullptr; + } + return static_cast(arg->ToObject(info_->GetVM())->GetNativePointerField(0)); +} + template void JsiException::Throw(const char* format, Args... args) { diff --git a/frameworks/bridge/declarative_frontend/jsview/js_canvas_path.cpp b/frameworks/bridge/declarative_frontend/jsview/js_canvas_path.cpp index ee5a7675a3a..3e966c1db49 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_canvas_path.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_canvas_path.cpp @@ -14,6 +14,7 @@ */ #include "bridge/declarative_frontend/jsview/js_canvas_path.h" + #include "bridge/declarative_frontend/jsview/js_rendering_context.h" #include "bridge/declarative_frontend/jsview/js_view_common_def.h" @@ -24,213 +25,149 @@ JSCanvasPath::JSCanvasPath() = default; void JSCanvasPath::JsPath2DSetTransform(const JSCallbackInfo& info) { - if (info.Length() == 6) { - if (info[0]->IsNumber()) { - double scaleX = 0.0; - double skewX = 0.0; - double skewY = 0.0; - double scaleY = 0.0; - double translateX = 0.0; - double translateY = 0.0; - JSViewAbstract::ParseJsDouble(info[0], scaleX); - JSViewAbstract::ParseJsDouble(info[1], skewX); - JSViewAbstract::ParseJsDouble(info[2], skewY); - JSViewAbstract::ParseJsDouble(info[3], scaleY); - JSViewAbstract::ParseJsDouble(info[4], translateX); - JSViewAbstract::ParseJsDouble(info[5], translateY); - translateX = PipelineBase::Vp2PxWithCurrentDensity(translateX); - translateY = PipelineBase::Vp2PxWithCurrentDensity(translateY); - path2d_->SetTransform(scaleX, skewX, skewY, scaleY, translateX, translateY); - SetPathSize(info); - } + double scaleX = 0.0; + double skewX = 0.0; + double skewY = 0.0; + double scaleY = 0.0; + double translateX = 0.0; + double translateY = 0.0; + if (info.GetDoubleArg(0, scaleX) && info.GetDoubleArg(1, skewX) && info.GetDoubleArg(2, skewY) && + info.GetDoubleArg(3, scaleY) && info.GetDoubleArg(4, translateX) && info.GetDoubleArg(5, translateY)) { + auto density = PipelineBase::GetCurrentDensity(); + path2d_->SetTransform(scaleX, skewX, skewY, scaleY, translateX * density, translateY * density); + SetPathSize(info); } } +// moveTo(x: number, y: number): void void JSCanvasPath::JsPath2DMoveTo(const JSCallbackInfo& info) { - if (info.Length() == 2) { - if (info[0]->IsNumber()) { - double X = 0.0; - double Y = 0.0; - JSViewAbstract::ParseJsDouble(info[0], X); - JSViewAbstract::ParseJsDouble(info[1], Y); - X = PipelineBase::Vp2PxWithCurrentDensity(X); - Y = PipelineBase::Vp2PxWithCurrentDensity(Y); - path2d_->MoveTo(X, Y); - SetPathSize(info); - } + double x = 0.0; + double y = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y)) { + auto density = PipelineBase::GetCurrentDensity(); + path2d_->MoveTo(x * density, y * density); + SetPathSize(info); } } +// lineTo(x: number, y: number): void void JSCanvasPath::JsPath2DLineTo(const JSCallbackInfo& info) { - if (info.Length() == 2) { - if (info[0]->IsNumber()) { - double X = 0.0; - double Y = 0.0; - JSViewAbstract::ParseJsDouble(info[0], X); - JSViewAbstract::ParseJsDouble(info[1], Y); - X = PipelineBase::Vp2PxWithCurrentDensity(X); - Y = PipelineBase::Vp2PxWithCurrentDensity(Y); - path2d_->LineTo(X, Y); - SetPathSize(info); - } + double x = 0.0; + double y = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y)) { + auto density = PipelineBase::GetCurrentDensity(); + path2d_->LineTo(x * density, y * density); + SetPathSize(info); } } +// arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void void JSCanvasPath::JsPath2DArc(const JSCallbackInfo& info) { - if (info.Length() == 5 || info.Length() == 6) { - if (info[0]->IsNumber()) { - double X = 0.0; - double Y = 0.0; - double radius = 0.0; - double startAngle = 0.0; - double endAngle = 0.0; - bool anticlockwise = false; - JSViewAbstract::ParseJsDouble(info[0], X); - JSViewAbstract::ParseJsDouble(info[1], Y); - JSViewAbstract::ParseJsDouble(info[2], radius); - JSViewAbstract::ParseJsDouble(info[3], startAngle); - JSViewAbstract::ParseJsDouble(info[4], endAngle); - X = PipelineBase::Vp2PxWithCurrentDensity(X); - Y = PipelineBase::Vp2PxWithCurrentDensity(Y); - radius = PipelineBase::Vp2PxWithCurrentDensity(radius); - if (info.Length() == 6) { - JSViewAbstract::ParseJsBool(info[5], anticlockwise); - } - path2d_->Arc(X, Y, radius, startAngle, endAngle, anticlockwise); - SetPathSize(info); - } + double x = 0.0; + double y = 0.0; + double radius = 0.0; + double startAngle = 0.0; + double endAngle = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y) && info.GetDoubleArg(2, radius) && + info.GetDoubleArg(3, startAngle) && info.GetDoubleArg(4, endAngle)) { + bool anticlockwise = false; + info.GetBooleanArg(5, anticlockwise); + auto density = PipelineBase::GetCurrentDensity(); + path2d_->Arc(x * density, y * density, radius * density, startAngle, endAngle, anticlockwise); + SetPathSize(info); } } +// arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void void JSCanvasPath::JsPath2DArcTo(const JSCallbackInfo& info) { - if (info.Length() == 5) { - if (info[0]->IsNumber()) { - double x1 = 0.0; - double y1 = 0.0; - double x2 = 0.0; - double y2 = 0.0; - double radius = 0.0; - JSViewAbstract::ParseJsDouble(info[0], x1); - JSViewAbstract::ParseJsDouble(info[1], y1); - JSViewAbstract::ParseJsDouble(info[2], x2); - JSViewAbstract::ParseJsDouble(info[3], y2); - JSViewAbstract::ParseJsDouble(info[4], radius); - x1 = PipelineBase::Vp2PxWithCurrentDensity(x1); - y1 = PipelineBase::Vp2PxWithCurrentDensity(y1); - x2 = PipelineBase::Vp2PxWithCurrentDensity(x2); - y2 = PipelineBase::Vp2PxWithCurrentDensity(y2); - radius = PipelineBase::Vp2PxWithCurrentDensity(radius); - path2d_->ArcTo(x1, y1, x2, y2, radius); - SetPathSize(info); - } + double x1 = 0.0; + double y1 = 0.0; + double x2 = 0.0; + double y2 = 0.0; + double radius = 0.0; + if (info.GetDoubleArg(0, x1) && info.GetDoubleArg(1, y1) && info.GetDoubleArg(2, x2) && info.GetDoubleArg(3, y2) && + info.GetDoubleArg(4, radius)) { + auto density = PipelineBase::GetCurrentDensity(); + path2d_->ArcTo(x1 * density, y1 * density, x2 * density, y2 * density, radius * density); + SetPathSize(info); } } +// quadraticCurveTo(cpx: number, cpy: number, x: number ,y: number): void void JSCanvasPath::JsPath2DQuadraticCurveTo(const JSCallbackInfo& info) { - if (info[0]->IsNumber()) { - double cpx = 0.0; - double cpy = 0.0; - double x = 0.0; - double y = 0.0; - JSViewAbstract::ParseJsDouble(info[0], cpx); - JSViewAbstract::ParseJsDouble(info[1], cpy); - JSViewAbstract::ParseJsDouble(info[2], x); - JSViewAbstract::ParseJsDouble(info[3], y); - cpx = PipelineBase::Vp2PxWithCurrentDensity(cpx); - cpy = PipelineBase::Vp2PxWithCurrentDensity(cpy); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - path2d_->QuadraticCurveTo(cpx, cpy, x, y); + double cpx = 0.0; + double cpy = 0.0; + double x = 0.0; + double y = 0.0; + if (info.GetDoubleArg(0, cpx) && info.GetDoubleArg(1, cpy) && info.GetDoubleArg(2, x) && info.GetDoubleArg(3, y)) { + auto density = PipelineBase::GetCurrentDensity(); + path2d_->QuadraticCurveTo(cpx * density, cpy * density, x * density, y * density); SetPathSize(info); } } +// bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void void JSCanvasPath::JsPath2DBezierCurveTo(const JSCallbackInfo& info) { - if (info[0]->IsNumber()) { - double cp1x = 0.0; - double cp1y = 0.0; - double cp2x = 0.0; - double cp2y = 0.0; - double x = 0.0; - double y = 0.0; - JSViewAbstract::ParseJsDouble(info[0], cp1x); - JSViewAbstract::ParseJsDouble(info[1], cp1y); - JSViewAbstract::ParseJsDouble(info[2], cp2x); - JSViewAbstract::ParseJsDouble(info[3], cp2y); - JSViewAbstract::ParseJsDouble(info[4], x); - JSViewAbstract::ParseJsDouble(info[5], y); - cp1x = PipelineBase::Vp2PxWithCurrentDensity(cp1x); - cp1y = PipelineBase::Vp2PxWithCurrentDensity(cp1y); - cp2x = PipelineBase::Vp2PxWithCurrentDensity(cp2x); - cp2y = PipelineBase::Vp2PxWithCurrentDensity(cp2y); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - path2d_->BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); + double cp1x = 0.0; + double cp1y = 0.0; + double cp2x = 0.0; + double cp2y = 0.0; + double x = 0.0; + double y = 0.0; + if (info.GetDoubleArg(0, cp1x) && info.GetDoubleArg(1, cp1y) && info.GetDoubleArg(2, cp2x) && + info.GetDoubleArg(3, cp2y) && info.GetDoubleArg(4, x) && info.GetDoubleArg(5, y)) { + auto density = PipelineBase::GetCurrentDensity(); + path2d_->BezierCurveTo( + cp1x * density, cp1y * density, cp2x * density, cp2y * density, x * density, y * density); SetPathSize(info); } } +// ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, +// endAngle: number, counterclockwise?: boolean): void void JSCanvasPath::JsPath2DEllipse(const JSCallbackInfo& info) { - if (info[0]->IsNumber()) { - double X = 0.0; - double Y = 0.0; - double radiusX = 0.0; - double radiusY = 0.0; - double rotation = 0.0; - double startAngle = 0.0; - double endAngle = 0.0; - - JSViewAbstract::ParseJsDouble(info[0], X); - JSViewAbstract::ParseJsDouble(info[1], Y); - JSViewAbstract::ParseJsDouble(info[2], radiusX); - JSViewAbstract::ParseJsDouble(info[3], radiusY); - JSViewAbstract::ParseJsDouble(info[4], rotation); - JSViewAbstract::ParseJsDouble(info[5], startAngle); - JSViewAbstract::ParseJsDouble(info[6], endAngle); - X = PipelineBase::Vp2PxWithCurrentDensity(X); - Y = PipelineBase::Vp2PxWithCurrentDensity(Y); - radiusX = PipelineBase::Vp2PxWithCurrentDensity(radiusX); - radiusY = PipelineBase::Vp2PxWithCurrentDensity(radiusY); - + double x = 0.0; + double y = 0.0; + double radiusX = 0.0; + double radiusY = 0.0; + double rotation = 0.0; + double startAngle = 0.0; + double endAngle = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y) && info.GetDoubleArg(2, radiusX) && + info.GetDoubleArg(3, radiusY) && info.GetDoubleArg(4, rotation) && info.GetDoubleArg(5, startAngle) && + info.GetDoubleArg(6, endAngle)) { bool anticlockwise = false; - - if (info.Length() == 8) { - JSViewAbstract::ParseJsBool(info[7], anticlockwise); - } - - path2d_->Ellipse(X, Y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise); + info.GetBooleanArg(7, anticlockwise); + auto density = PipelineBase::GetCurrentDensity(); + path2d_->Ellipse(x * density, y * density, radiusX * density, radiusY * density, rotation, startAngle, endAngle, + anticlockwise); SetPathSize(info); } } +// rect(x: number, y: number, w: number, h: number): void void JSCanvasPath::JsPath2DRect(const JSCallbackInfo& info) { - if (info[0]->IsNumber()) { - double x = 0.0; - double y = 0.0; - double width = 0.0; - double height = 0.0; - JSViewAbstract::ParseJsDouble(info[0], x); - JSViewAbstract::ParseJsDouble(info[1], y); - JSViewAbstract::ParseJsDouble(info[2], width); - JSViewAbstract::ParseJsDouble(info[3], height); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - width = PipelineBase::Vp2PxWithCurrentDensity(width); - height = PipelineBase::Vp2PxWithCurrentDensity(height); - - path2d_->Rect(x, y, width, height); + double x = 0.0; + double y = 0.0; + double width = 0.0; + double height = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y) && info.GetDoubleArg(2, width) && + info.GetDoubleArg(3, height)) { + auto density = PipelineBase::GetCurrentDensity(); + path2d_->Rect(x * density, y * density, width * density, height * density); SetPathSize(info); } } +// closePath(): void void JSCanvasPath::JsPath2DClosePath(const JSCallbackInfo& info) { path2d_->ClosePath(); diff --git a/frameworks/bridge/declarative_frontend/jsview/js_canvas_renderer.cpp b/frameworks/bridge/declarative_frontend/jsview/js_canvas_renderer.cpp index e955733f372..f735f6f5183 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_canvas_renderer.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_canvas_renderer.cpp @@ -56,29 +56,6 @@ inline T ConvertStrToEnum(const char* key, const LinearMapNode* map, size_t l return index != -1 ? map[index].value : defaultValue; } -inline Rect GetJsRectParam(const JSCallbackInfo& info) -{ - // 4 parameters: rect(x, y, width, height) - if (info.Length() != 4) { - return Rect(); - } - double x = 0.0; - double y = 0.0; - double width = 0.0; - double height = 0.0; - JSViewAbstract::ParseJsDouble(info[0], x); - JSViewAbstract::ParseJsDouble(info[1], y); - JSViewAbstract::ParseJsDouble(info[2], width); - JSViewAbstract::ParseJsDouble(info[3], height); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - width = PipelineBase::Vp2PxWithCurrentDensity(width); - height = PipelineBase::Vp2PxWithCurrentDensity(height); - - Rect rect = Rect(x, y, width, height); - return rect; -} - inline bool ParseJsDoubleArray(const JSRef& jsValue, std::vector& result) { if (!jsValue->IsArray() && !jsValue->IsObject()) { @@ -315,79 +292,43 @@ void JSCanvasRenderer::JsCreateConicGradient(const JSCallbackInfo& info) info.SetReturnValue(pasteObj); } +// fillText(text: string, x: number, y: number, maxWidth?: number): void void JSCanvasRenderer::JsFillText(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() < 1) { - return; - } - - if (info[0]->IsString() && info[1]->IsNumber() && info[2]->IsNumber()) { - double x = 0.0; - double y = 0.0; - std::string text = ""; - JSViewAbstract::ParseJsString(info[0], text); - JSViewAbstract::ParseJsDouble(info[1], x); - JSViewAbstract::ParseJsDouble(info[2], y); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - std::optional maxWidth; + FillTextInfo textInfo; + if (info.GetStringArg(0, textInfo.text) && info.GetDoubleArg(1, textInfo.x) && info.GetDoubleArg(2, textInfo.y)) { + ContainerScope scope(instanceId_); + auto density = PipelineBase::GetCurrentDensity(); + textInfo.x *= density; + textInfo.y *= density; if (info.Length() >= 4) { - double width = 0.0; - if (info[3]->IsUndefined()) { - width = FLT_MAX; - } else if (info[3]->IsNumber()) { - JSViewAbstract::ParseJsDouble(info[3], width); - width = PipelineBase::Vp2PxWithCurrentDensity(width); + double maxWidth = FLT_MAX; + if (info.GetDoubleArg(3, maxWidth)) { + maxWidth *= density; } - maxWidth = width; + textInfo.maxWidth = maxWidth; } - - FillTextInfo fillTextInfo; - fillTextInfo.text = text; - fillTextInfo.x = x; - fillTextInfo.y = y; - fillTextInfo.maxWidth = maxWidth; - - renderingContext2DModel_->SetFillText(paintState_, fillTextInfo); + renderingContext2DModel_->SetFillText(paintState_, textInfo); } } +// strokeText(text: string, x: number, y: number, maxWidth?:number): void void JSCanvasRenderer::JsStrokeText(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() < 1) { - return; - } - - if (info[0]->IsString() && info[1]->IsNumber() && info[2]->IsNumber()) { - double x = 0.0; - double y = 0.0; - std::string text = ""; - JSViewAbstract::ParseJsString(info[0], text); - JSViewAbstract::ParseJsDouble(info[1], x); - JSViewAbstract::ParseJsDouble(info[2], y); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - std::optional maxWidth; + FillTextInfo textInfo; + if (info.GetStringArg(0, textInfo.text) && info.GetDoubleArg(1, textInfo.x) && info.GetDoubleArg(2, textInfo.y)) { + ContainerScope scope(instanceId_); + auto density = PipelineBase::GetCurrentDensity(); + textInfo.x *= density; + textInfo.y *= density; if (info.Length() >= 4) { - double width = 0.0; - if (info[3]->IsUndefined()) { - width = FLT_MAX; - } else if (info[3]->IsNumber()) { - JSViewAbstract::ParseJsDouble(info[3], width); - width = PipelineBase::Vp2PxWithCurrentDensity(width); + double maxWidth = FLT_MAX; + if (info.GetDoubleArg(3, maxWidth)) { + maxWidth *= density; } - maxWidth = width; + textInfo.maxWidth = maxWidth; } - - FillTextInfo fillTextInfo; - fillTextInfo.text = text; - fillTextInfo.x = x; - fillTextInfo.y = y; - fillTextInfo.maxWidth = maxWidth; - - renderingContext2DModel_->SetStrokeText(paintState_, fillTextInfo); + renderingContext2DModel_->SetStrokeText(paintState_, textInfo); } } @@ -1459,64 +1400,44 @@ void JSCanvasRenderer::JsSetImageSmoothingQuality(const JSCallbackInfo& info) } } +// moveTo(x: number, y: number): void void JSCanvasRenderer::JsMoveTo(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() < 1) { - return; - } - - if (info[0]->IsNumber() && info[1]->IsNumber()) { - double x = 0.0; - double y = 0.0; - JSViewAbstract::ParseJsDouble(info[0], x); - JSViewAbstract::ParseJsDouble(info[1], y); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - renderingContext2DModel_->MoveTo(x, y); + double x = 0.0; + double y = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y)) { + ContainerScope scope(instanceId_); + auto density = PipelineBase::GetCurrentDensity(); + renderingContext2DModel_->MoveTo(x * density, y * density); } } +// lineTo(x: number, y: number): void void JSCanvasRenderer::JsLineTo(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() < 1) { - return; - } - - if (info[0]->IsNumber() && info[1]->IsNumber()) { - double x = 0.0; - double y = 0.0; - JSViewAbstract::ParseJsDouble(info[0], x); - JSViewAbstract::ParseJsDouble(info[1], y); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - renderingContext2DModel_->LineTo(x, y); + double x = 0.0; + double y = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y)) { + ContainerScope scope(instanceId_); + auto density = PipelineBase::GetCurrentDensity(); + renderingContext2DModel_->LineTo(x * density, y * density); } } +// bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void void JSCanvasRenderer::JsBezierCurveTo(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() < 1) { - return; - } - - if (info[0]->IsNumber() && info[1]->IsNumber() && info[2]->IsNumber() && info[3]->IsNumber() && - info[4]->IsNumber() && info[5]->IsNumber()) { - BezierCurveParam param; - JSViewAbstract::ParseJsDouble(info[0], param.cp1x); - JSViewAbstract::ParseJsDouble(info[1], param.cp1y); - JSViewAbstract::ParseJsDouble(info[2], param.cp2x); - JSViewAbstract::ParseJsDouble(info[3], param.cp2y); - JSViewAbstract::ParseJsDouble(info[4], param.x); - JSViewAbstract::ParseJsDouble(info[5], param.y); - param.cp1x = PipelineBase::Vp2PxWithCurrentDensity(param.cp1x); - param.cp1y = PipelineBase::Vp2PxWithCurrentDensity(param.cp1y); - param.cp2x = PipelineBase::Vp2PxWithCurrentDensity(param.cp2x); - param.cp2y = PipelineBase::Vp2PxWithCurrentDensity(param.cp2y); - param.x = PipelineBase::Vp2PxWithCurrentDensity(param.x); - param.y = PipelineBase::Vp2PxWithCurrentDensity(param.y); + BezierCurveParam param; + if (info.GetDoubleArg(0, param.cp1x) && info.GetDoubleArg(1, param.cp1y) && info.GetDoubleArg(2, param.cp2x) && + info.GetDoubleArg(3, param.cp2y) && info.GetDoubleArg(4, param.x) && info.GetDoubleArg(5, param.y)) { + ContainerScope scope(instanceId_); + auto density = PipelineBase::GetCurrentDensity(); + param.cp1x *= density; + param.cp1y *= density; + param.cp2x *= density; + param.cp2y *= density; + param.x *= density; + param.y *= density; renderingContext2DModel_->BezierCurveTo(param); } } @@ -1623,50 +1544,36 @@ void JSCanvasRenderer::JsEllipse(const JSCallbackInfo& info) void JSCanvasRenderer::JsFill(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - std::string ruleStr = ""; - if (info.Length() == 1 && info[0]->IsString()) { - // fill(rule) uses fillRule specified by the application developers - JSViewAbstract::ParseJsString(info[0], ruleStr); - } else if (info.Length() == 2) { - // fill(path, rule) uses fillRule specified by the application developers - JSViewAbstract::ParseJsString(info[1], ruleStr); - } + std::string ruleStr; auto fillRule = CanvasFillRule::NONZERO; - if (ruleStr == "nonzero") { - fillRule = CanvasFillRule::NONZERO; - } else if (ruleStr == "evenodd") { - fillRule = CanvasFillRule::EVENODD; - } - if (info.Length() == 0 || (info.Length() == 1 && info[0]->IsString())) { + + // clip(fillRule?: CanvasFillRule): void + if (info.Length() == 0 || info.GetStringArg(0, ruleStr)) { + fillRule = ruleStr == "evenodd" ? CanvasFillRule::EVENODD : CanvasFillRule::NONZERO; renderingContext2DModel_->SetFillRuleForPath(fillRule); - } else if (info.Length() == 2 || (info.Length() == 1 && info[0]->IsObject())) { - JSPath2D* jsCanvasPath = JSRef::Cast(info[0])->Unwrap(); - if (jsCanvasPath == nullptr) { - return; - } - auto path = jsCanvasPath->GetCanvasPath2d(); + return; + } - renderingContext2DModel_->SetFillRuleForPath2D(fillRule, path); + // clip(path: Path2D, fillRule?: CanvasFillRule): void + JSPath2D* jsCanvasPath = info.UnwrapArg(0); + CHECK_NULL_VOID(jsCanvasPath); + auto path = jsCanvasPath->GetCanvasPath2d(); + if (info.GetStringArg(1, ruleStr) && ruleStr == "evenodd") { + fillRule = CanvasFillRule::EVENODD; } + renderingContext2DModel_->SetFillRuleForPath2D(fillRule, path); } +// stroke(path?: Path2D): void void JSCanvasRenderer::JsStroke(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - // stroke always uses non-zero fillRule - auto fillRule = CanvasFillRule::NONZERO; - if (info.Length() == 1) { - JSPath2D* jsCanvasPath = JSRef::Cast(info[0])->Unwrap(); - if (jsCanvasPath == nullptr) { - return; - } + auto* jsCanvasPath = info.UnwrapArg(0); + if (jsCanvasPath) { auto path = jsCanvasPath->GetCanvasPath2d(); - renderingContext2DModel_->SetStrokeRuleForPath2D(fillRule, path); + renderingContext2DModel_->SetStrokeRuleForPath2D(CanvasFillRule::NONZERO, path); return; } - - renderingContext2DModel_->SetStrokeRuleForPath(fillRule); + renderingContext2DModel_->SetStrokeRuleForPath(CanvasFillRule::NONZERO); } void JSCanvasRenderer::JsClip(const JSCallbackInfo& info) @@ -1698,46 +1605,43 @@ void JSCanvasRenderer::JsClip(const JSCallbackInfo& info) } } +// rect(x: number, y: number, w: number, h: number): void void JSCanvasRenderer::JsRect(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - Rect rect = GetJsRectParam(info); - renderingContext2DModel_->AddRect(rect); + double x = 0.0; + double y = 0.0; + double width = 0.0; + double height = 0.0; + double density = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y) && info.GetDoubleArg(2, width) && + info.GetDoubleArg(3, height)) { + ContainerScope scope(instanceId_); + density = PipelineBase::GetCurrentDensity(); + } + renderingContext2DModel_->AddRect(Rect(x, y, width, height) * density); } +// beginPath(): void void JSCanvasRenderer::JsBeginPath(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() != 0) { - return; - } renderingContext2DModel_->BeginPath(); } +// closePath(): void void JSCanvasRenderer::JsClosePath(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() != 0) { - return; - } renderingContext2DModel_->ClosePath(); } +// restore(): void void JSCanvasRenderer::JsRestore(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() != 0) { - return; - } renderingContext2DModel_->Restore(); } +// save(): void void JSCanvasRenderer::JsSave(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() != 0) { - return; - } renderingContext2DModel_->CanvasRendererSave(); } @@ -1954,119 +1858,77 @@ void JSCanvasRenderer::JsSetTextBaseline(const JSCallbackInfo& info) } } +// measureText(text: string): TextMetrics void JSCanvasRenderer::JsMeasureText(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - std::string text = ""; + std::string text; paintState_.SetTextStyle(style_); - double width = 0.0; - double height = 0.0; - TextMetrics textMetrics; - if (info[0]->IsString()) { - JSViewAbstract::ParseJsString(info[0], text); - width = renderingContext2DModel_->GetMeasureTextWidth(paintState_, text); - height = renderingContext2DModel_->GetMeasureTextHeight(paintState_, text); - textMetrics = renderingContext2DModel_->GetMeasureTextMetrics(paintState_, text); - + ContainerScope scope(instanceId_); + auto density = PipelineBase::GetCurrentDensity(); + if (Positive(density) && info.GetStringArg(0, text)) { + double width = renderingContext2DModel_->GetMeasureTextWidth(paintState_, text); + double height = renderingContext2DModel_->GetMeasureTextHeight(paintState_, text); + TextMetrics textMetrics = renderingContext2DModel_->GetMeasureTextMetrics(paintState_, text); auto retObj = JSRef::New(); - retObj->SetProperty("width", PipelineBase::Px2VpWithCurrentDensity(width)); - retObj->SetProperty("height", PipelineBase::Px2VpWithCurrentDensity(height)); - retObj->SetProperty( - "actualBoundingBoxLeft", PipelineBase::Px2VpWithCurrentDensity(textMetrics.actualBoundingBoxLeft)); - retObj->SetProperty( - "actualBoundingBoxRight", PipelineBase::Px2VpWithCurrentDensity(textMetrics.actualBoundingBoxRight)); - retObj->SetProperty( - "actualBoundingBoxAscent", PipelineBase::Px2VpWithCurrentDensity(textMetrics.actualBoundingBoxAscent)); - retObj->SetProperty( - "actualBoundingBoxDescent", PipelineBase::Px2VpWithCurrentDensity(textMetrics.actualBoundingBoxDescent)); - retObj->SetProperty("hangingBaseline", PipelineBase::Px2VpWithCurrentDensity(textMetrics.hangingBaseline)); - retObj->SetProperty( - "alphabeticBaseline", PipelineBase::Px2VpWithCurrentDensity(textMetrics.alphabeticBaseline)); - retObj->SetProperty( - "ideographicBaseline", PipelineBase::Px2VpWithCurrentDensity(textMetrics.ideographicBaseline)); - retObj->SetProperty("emHeightAscent", PipelineBase::Px2VpWithCurrentDensity(textMetrics.emHeightAscent)); - retObj->SetProperty("emHeightDescent", PipelineBase::Px2VpWithCurrentDensity(textMetrics.emHeightDescent)); - retObj->SetProperty( - "fontBoundingBoxAscent", PipelineBase::Px2VpWithCurrentDensity(textMetrics.fontBoundingBoxAscent)); - retObj->SetProperty( - "fontBoundingBoxDescent", PipelineBase::Px2VpWithCurrentDensity(textMetrics.fontBoundingBoxDescent)); + retObj->SetProperty("width", width / density); + retObj->SetProperty("height", height / density); + retObj->SetProperty("actualBoundingBoxLeft", textMetrics.actualBoundingBoxLeft / density); + retObj->SetProperty("actualBoundingBoxRight", textMetrics.actualBoundingBoxRight / density); + retObj->SetProperty("actualBoundingBoxAscent", textMetrics.actualBoundingBoxAscent / density); + retObj->SetProperty("actualBoundingBoxDescent", textMetrics.actualBoundingBoxDescent / density); + retObj->SetProperty("hangingBaseline", textMetrics.hangingBaseline / density); + retObj->SetProperty("alphabeticBaseline", textMetrics.alphabeticBaseline / density); + retObj->SetProperty("ideographicBaseline", textMetrics.ideographicBaseline / density); + retObj->SetProperty("emHeightAscent", textMetrics.emHeightAscent / density); + retObj->SetProperty("emHeightDescent", textMetrics.emHeightDescent / density); + retObj->SetProperty("fontBoundingBoxAscent", textMetrics.fontBoundingBoxAscent / density); + retObj->SetProperty("fontBoundingBoxDescent", textMetrics.fontBoundingBoxDescent / density); info.SetReturnValue(retObj); } } +// fillRect(x: number, y: number, w: number, h: number): void void JSCanvasRenderer::JsFillRect(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() < 4) { - return; - } - - if (info[0]->IsNumber() && info[1]->IsNumber() && info[2]->IsNumber() && info[3]->IsNumber()) { - double x = 0.0; - double y = 0.0; - double width = 0.0; - double height = 0.0; - JSViewAbstract::ParseJsDouble(info[0], x); - JSViewAbstract::ParseJsDouble(info[1], y); - JSViewAbstract::ParseJsDouble(info[2], width); - JSViewAbstract::ParseJsDouble(info[3], height); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - width = PipelineBase::Vp2PxWithCurrentDensity(width); - height = PipelineBase::Vp2PxWithCurrentDensity(height); - - Rect rect = Rect(x, y, width, height); - renderingContext2DModel_->FillRect(rect); + double x = 0.0; + double y = 0.0; + double width = 0.0; + double height = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y) && info.GetDoubleArg(2, width) && + info.GetDoubleArg(3, height)) { + ContainerScope scope(instanceId_); + auto density = PipelineBase::GetCurrentDensity(); + renderingContext2DModel_->FillRect(Rect(x, y, width, height) * density); } } +// strokeRect(x: number, y: number, w: number, h: number): void void JSCanvasRenderer::JsStrokeRect(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() < 4) { - return; - } - - if (info[0]->IsNumber() && info[1]->IsNumber() && info[2]->IsNumber() && info[3]->IsNumber()) { - double x = 0.0; - double y = 0.0; - double width = 0.0; - double height = 0.0; - JSViewAbstract::ParseJsDouble(info[0], x); - JSViewAbstract::ParseJsDouble(info[1], y); - JSViewAbstract::ParseJsDouble(info[2], width); - JSViewAbstract::ParseJsDouble(info[3], height); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - width = PipelineBase::Vp2PxWithCurrentDensity(width); - height = PipelineBase::Vp2PxWithCurrentDensity(height); - - Rect rect = Rect(x, y, width, height); - renderingContext2DModel_->StrokeRect(rect); + double x = 0.0; + double y = 0.0; + double width = 0.0; + double height = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y) && info.GetDoubleArg(2, width) && + info.GetDoubleArg(3, height)) { + ContainerScope scope(instanceId_); + auto density = PipelineBase::GetCurrentDensity(); + renderingContext2DModel_->StrokeRect(Rect(x, y, width, height) * density); } } +// clearRect(x: number, y: number, w: number, h: number): void void JSCanvasRenderer::JsClearRect(const JSCallbackInfo& info) { - ContainerScope scope(instanceId_); - if (info.Length() < 4) { - return; - } - - if (info[0]->IsNumber() && info[1]->IsNumber() && info[2]->IsNumber() && info[3]->IsNumber()) { - double x = 0.0; - double y = 0.0; - double width = 0.0; - double height = 0.0; - JSViewAbstract::ParseJsDouble(info[0], x); - JSViewAbstract::ParseJsDouble(info[1], y); - JSViewAbstract::ParseJsDouble(info[2], width); - JSViewAbstract::ParseJsDouble(info[3], height); - x = PipelineBase::Vp2PxWithCurrentDensity(x); - y = PipelineBase::Vp2PxWithCurrentDensity(y); - width = PipelineBase::Vp2PxWithCurrentDensity(width); - height = PipelineBase::Vp2PxWithCurrentDensity(height); - renderingContext2DModel_->ClearRect(Rect(x, y, width, height)); + double x = 0.0; + double y = 0.0; + double width = 0.0; + double height = 0.0; + if (info.GetDoubleArg(0, x) && info.GetDoubleArg(1, y) && info.GetDoubleArg(2, width) && + info.GetDoubleArg(3, height)) { + ContainerScope scope(instanceId_); + auto density = PipelineBase::GetCurrentDensity(); + renderingContext2DModel_->ClearRect(Rect(x, y, width, height) * density); } } diff --git a/frameworks/bridge/declarative_frontend/jsview/js_path2d.cpp b/frameworks/bridge/declarative_frontend/jsview/js_path2d.cpp index 874168be434..bf15278ac6a 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_path2d.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_path2d.cpp @@ -14,14 +14,13 @@ */ #include "bridge/declarative_frontend/jsview/js_path2d.h" + +#include "base/utils/utils.h" #include "bridge/declarative_frontend/jsview/js_canvas_renderer.h" #include "bridge/declarative_frontend/jsview/js_view_common_def.h" namespace OHOS::Ace::Framework { -constexpr int JS_PATH2D_PARAMETER_COUNTS = 2; -JSPath2D::JSPath2D() -{ -} +JSPath2D::JSPath2D() {} void JSPath2D::Constructor(const JSCallbackInfo& args) { @@ -61,25 +60,20 @@ void JSPath2D::JSBind(BindingTarget globalObj) JSClass::Bind(globalObj, JSPath2D::Constructor, JSPath2D::Destructor); } +// addPath(path: path2D, transform?:Matrix2D): void void JSPath2D::JsPath2DAddPath(const JSCallbackInfo& args) { - if (args.Length() < 1 || !args[0]->IsObject()) { - return; - } - auto* jsPath2d = JSRef::Cast(args[0])->Unwrap(); - if (jsPath2d == nullptr) { - return; - } + // one parameter + auto* jsPath2d = args.UnwrapArg(0); + CHECK_NULL_VOID(jsPath2d); auto canvasPath2D = jsPath2d->GetCanvasPath2d(); path2d_->AddPath(canvasPath2D); SetPathSize(args); - if (args.Length() != JS_PATH2D_PARAMETER_COUNTS) { - return; - } + // two parameters if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) { - auto* jsMatrix2d = JSRef::Cast(args[1])->Unwrap(); - if (jsMatrix2d != nullptr) { + auto* jsMatrix2d = args.UnwrapArg(1); + if (jsMatrix2d) { path2d_->SetTransform(jsMatrix2d->JsGetScaleX(), jsMatrix2d->JsGetRotateX(), jsMatrix2d->JsGetRotateY(), jsMatrix2d->JsGetScaleY(), jsMatrix2d->JsGetTranslateX(), jsMatrix2d->JsGetTranslateY()); SetPathSize(args); -- Gitee