mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-11-23 23:21:05 +00:00
drawable svg mask
Signed-off-by: xiexiyun <xiexiyun@huawei.com> Change-Id: I1bb1aa1b08fa66a614d0d56ad7284ff2d16fd013
This commit is contained in:
parent
a44619b4e7
commit
4ebff90979
@ -89,6 +89,7 @@ template("libace_static") {
|
||||
deps += [
|
||||
"$ace_root/frameworks/bridge/declarative_frontend:declarative_js_engine_ark_$platform",
|
||||
"$ace_root/frameworks/bridge/js_frontend/engine:js_engine_ark_$platform",
|
||||
"$ace_root/frameworks/core/interfaces/native/svg:ace_core_interfaces_native_svg_$platform",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
65
frameworks/core/interfaces/native/svg/BUILD.gn
Normal file
65
frameworks/core/interfaces/native/svg/BUILD.gn
Normal file
@ -0,0 +1,65 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
import("//foundation/arkui/ace_engine/ace_config.gni")
|
||||
|
||||
template("ace_core_interfaces_native_svg") {
|
||||
forward_variables_from(invoker, "*")
|
||||
|
||||
ohos_source_set(target_name) {
|
||||
subsystem_name = ace_engine_subsystem
|
||||
part_name = ace_engine_part
|
||||
defines += invoker.defines
|
||||
configs = [ "$ace_root:ace_config" ]
|
||||
if (ace_use_rosen_drawing) {
|
||||
defines += [ "NEW_SKIA" ]
|
||||
}
|
||||
external_deps = [
|
||||
"graphic_2d:2d_graphics",
|
||||
"graphic_2d:librender_service_base",
|
||||
"graphic_2d:librender_service_client",
|
||||
"graphic_2d:rosen_text",
|
||||
]
|
||||
|
||||
sources = [ "svg_draw.cpp" ]
|
||||
include_dirs = [ "//third_party/skia" ]
|
||||
|
||||
cflags_cc = []
|
||||
cflags_cc += invoker.cflags_cc
|
||||
}
|
||||
}
|
||||
|
||||
foreach(item, ace_platforms) {
|
||||
ace_core_interfaces_native_svg(
|
||||
"ace_core_interfaces_native_svg_" + item.name) {
|
||||
if (defined(item.config)) {
|
||||
config = item.config
|
||||
} else {
|
||||
config = {
|
||||
}
|
||||
}
|
||||
|
||||
if (defined(config.defines)) {
|
||||
defines = config.defines
|
||||
} else {
|
||||
defines = []
|
||||
}
|
||||
|
||||
if (defined(config.cflags_cc)) {
|
||||
cflags_cc = config.cflags_cc
|
||||
} else {
|
||||
cflags_cc = []
|
||||
}
|
||||
}
|
||||
}
|
50
frameworks/core/interfaces/native/svg/svg_draw.cpp
Normal file
50
frameworks/core/interfaces/native/svg/svg_draw.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "base/log/log.h"
|
||||
#include "core/components_ng/image_provider/adapter/rosen/drawing_image_data.h"
|
||||
#include "core/components_ng/image_provider/adapter/skia_svg_dom.h"
|
||||
#include "core/components_ng/render/drawing_forward.h"
|
||||
#include "core/components_ng/svg/svg_dom.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
namespace {
|
||||
void Draw(RSCanvas* canvas, const uint8_t* data, size_t dataLen, const Size& size)
|
||||
{
|
||||
CHECK_NULL_VOID(canvas);
|
||||
#ifdef USE_ROSEN_DRAWING
|
||||
auto drawingData = std::make_shared<RSData>();
|
||||
drawingData->BuildWithCopy(data, dataLen);
|
||||
auto drawingImageData = AceType::MakeRefPtr<NG::DrawingImageData>(drawingData);
|
||||
auto svgDom = drawingImageData->MakeSvgDom(std::nullopt);
|
||||
CHECK_NULL_VOID(svgDom);
|
||||
svgDom->DrawImage(*canvas, ImageFit::COVER, size);
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
extern "C" {
|
||||
|
||||
ACE_FORCE_EXPORT void OHOS_ACE_DrawSVG(void* canvas, uint8_t* data, size_t dataLen, float width, float height)
|
||||
{
|
||||
#ifdef USE_ROSEN_DRAWING
|
||||
CHECK_NULL_VOID(data);
|
||||
CHECK_NULL_VOID(dataLen != 0);
|
||||
auto rsCanvas = reinterpret_cast<RSCanvas*>(canvas);
|
||||
CHECK_NULL_VOID(rsCanvas);
|
||||
Draw(rsCanvas, data, dataLen, Size(width, height));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // namespace OHOS::Ace::NG
|
@ -19,18 +19,22 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "third_party/cJSON/cJSON.h"
|
||||
#include "include/core/SkSamplingOptions.h"
|
||||
#include "third_party/cJSON/cJSON.h"
|
||||
|
||||
#include "base/utils/string_utils.h"
|
||||
#include "base/utils/utils.h"
|
||||
#ifndef PREVIEW
|
||||
#include "image_source.h"
|
||||
#endif
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkImage.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
#include "include/core/SkPath.h"
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkStream.h"
|
||||
|
||||
// 区分此函数是在Windows环境调用还是Linux/mac环境调用
|
||||
// used to distinguish platform
|
||||
#ifdef PREVIEW
|
||||
#ifdef WINDOWS_PLATFORM
|
||||
#include <direct.h>
|
||||
@ -48,8 +52,7 @@ namespace {
|
||||
const char DRAWABLEDESCRIPTOR_JSON_KEY_BACKGROUND[] = "background";
|
||||
const char DRAWABLEDESCRIPTOR_JSON_KEY_FOREGROUND[] = "foreground";
|
||||
#endif
|
||||
constexpr float SIDE = 192.0;
|
||||
|
||||
constexpr float SIDE = 192.0f;
|
||||
// define for get resource path in preview scenes
|
||||
const static char PREVIEW_LOAD_RESOURCE_ID[] = "ohos_drawable_descriptor_path";
|
||||
#ifdef PREVIEW
|
||||
@ -63,6 +66,63 @@ constexpr static char PREVIEW_LOAD_RESOURCE_PATH[] = "/resources/entry/resources
|
||||
const static size_t MAX_PATH_LEN = 255;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using SvgRenderFunc = void (*)(void* canvas, uint8_t* data, size_t dataLen, float width, float height);
|
||||
#if defined(WINDOWS_PLATFORM)
|
||||
#include <windows.h>
|
||||
void* FindModule()
|
||||
{
|
||||
HMODULE result = nullptr;
|
||||
const char libname[] = "libace_compatible.dll";
|
||||
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, libname, &result);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
HILOG_WARN("Cannot find module libace_compatible");
|
||||
return nullptr;
|
||||
}
|
||||
void* FindFunction(void* library, const char* name)
|
||||
{
|
||||
return (void*)GetProcAddress(reinterpret_cast<HMODULE>(library), name);
|
||||
}
|
||||
#else
|
||||
#ifdef USE_ROSEN_DRAWING
|
||||
#include <dlfcn.h>
|
||||
void* FindModule()
|
||||
{
|
||||
const char libname[] = "libace_compatible.z.so";
|
||||
void* result = dlopen(libname, RTLD_LAZY | RTLD_LOCAL);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
HILOG_WARN("Cannot load libace_compatible: %{public}s", dlerror());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* FindFunction(void* library, const char* name)
|
||||
{
|
||||
return dlsym(library, name);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_ROSEN_DRAWING
|
||||
void RenderSVGMask(
|
||||
Rosen::Drawing::Canvas* canvas, std::unique_ptr<uint8_t[]>& data, size_t dataLen, float width, float height)
|
||||
{
|
||||
void* module = FindModule();
|
||||
if (module == nullptr) {
|
||||
HILOG_WARN("Failed to get module");
|
||||
return;
|
||||
}
|
||||
auto svgRenderer = reinterpret_cast<SvgRenderFunc>(FindFunction(module, "OHOS_ACE_DrawSVG"));
|
||||
if (!svgRenderer) {
|
||||
HILOG_WARN("Cannot find OHOS_ACE_DrawSVG()");
|
||||
return;
|
||||
}
|
||||
(*svgRenderer)(canvas, data.get(), dataLen, width, height);
|
||||
}
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
DrawableItem LayeredDrawableDescriptor::PreGetDrawableItem(
|
||||
@ -133,6 +193,22 @@ void LayeredDrawableDescriptor::InitialResource(const std::shared_ptr<Global::Re
|
||||
}
|
||||
}
|
||||
|
||||
void LayeredDrawableDescriptor::InitialSVGResource(
|
||||
const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr)
|
||||
{
|
||||
CHECK_NULL_VOID(resourceMgr);
|
||||
// preprocess get default svg mask
|
||||
const std::string defaultSVGMaskName = "ohos_icon_mask_svg";
|
||||
resourceMgr->GetMediaDataByName(defaultSVGMaskName.c_str(), defaultSVGMaskDataLength_, defaultSVGMaskData_);
|
||||
// preprocess get background and foreground
|
||||
if (!PreGetPixelMapFromJsonBuf(resourceMgr, true)) {
|
||||
HILOG_WARN("Create svg background Item imageSource from json buffer failed");
|
||||
}
|
||||
if (!PreGetPixelMapFromJsonBuf(resourceMgr, false)) {
|
||||
HILOG_WARN("Create svg foreground Item imageSource from json buffer failed");
|
||||
}
|
||||
}
|
||||
|
||||
bool DrawableDescriptor::GetPixelMapFromBuffer()
|
||||
{
|
||||
Media::SourceOptions opts;
|
||||
@ -226,8 +302,7 @@ bool LayeredDrawableDescriptor::GetDefaultMask()
|
||||
Media::SourceOptions opts;
|
||||
uint32_t errorCode = 0;
|
||||
std::unique_ptr<Media::ImageSource> imageSource =
|
||||
Media::ImageSource::CreateImageSource(
|
||||
defaultMaskData_.get(), defaultMaskDataLength_, opts, errorCode);
|
||||
Media::ImageSource::CreateImageSource(defaultMaskData_.get(), defaultMaskDataLength_, opts, errorCode);
|
||||
Media::DecodeOptions decodeOpts;
|
||||
decodeOpts.desiredPixelFormat = Media::PixelFormat::BGRA_8888;
|
||||
if (imageSource) {
|
||||
@ -241,21 +316,21 @@ bool LayeredDrawableDescriptor::GetDefaultMask()
|
||||
return true;
|
||||
}
|
||||
|
||||
void LayeredDrawableDescriptor::InitLayeredParam(std::pair<std::unique_ptr<uint8_t[]>, size_t> &foregroundInfo,
|
||||
std::pair<std::unique_ptr<uint8_t[]>, size_t> &backgroundInfo)
|
||||
void LayeredDrawableDescriptor::InitLayeredParam(std::pair<std::unique_ptr<uint8_t[]>, size_t>& foregroundInfo,
|
||||
std::pair<std::unique_ptr<uint8_t[]>, size_t>& backgroundInfo)
|
||||
{
|
||||
Media::SourceOptions opts;
|
||||
uint32_t errorCode = 0;
|
||||
auto foreground = Media::ImageSource::CreateImageSource(foregroundInfo.first.get(), foregroundInfo.second, opts,
|
||||
errorCode);
|
||||
auto foreground =
|
||||
Media::ImageSource::CreateImageSource(foregroundInfo.first.get(), foregroundInfo.second, opts, errorCode);
|
||||
if (errorCode == 0) {
|
||||
Media::DecodeOptions decodeOpts;
|
||||
decodeOpts.desiredPixelFormat = Media::PixelFormat::BGRA_8888;
|
||||
auto pixelMapPtr = foreground->CreatePixelMap(decodeOpts, errorCode);
|
||||
foreground_ = std::shared_ptr<Media::PixelMap>(pixelMapPtr.release());
|
||||
}
|
||||
auto background = Media::ImageSource::CreateImageSource(backgroundInfo.first.get(), backgroundInfo.second, opts,
|
||||
errorCode);
|
||||
auto background =
|
||||
Media::ImageSource::CreateImageSource(backgroundInfo.first.get(), backgroundInfo.second, opts, errorCode);
|
||||
if (errorCode == 0) {
|
||||
Media::DecodeOptions decodeOpts;
|
||||
decodeOpts.desiredPixelFormat = Media::PixelFormat::BGRA_8888;
|
||||
@ -272,8 +347,7 @@ bool LayeredDrawableDescriptor::GetMaskByPath()
|
||||
}
|
||||
Media::SourceOptions opts;
|
||||
uint32_t errorCode = 0;
|
||||
std::unique_ptr<Media::ImageSource> imageSource =
|
||||
Media::ImageSource::CreateImageSource(maskPath_, opts, errorCode);
|
||||
std::unique_ptr<Media::ImageSource> imageSource = Media::ImageSource::CreateImageSource(maskPath_, opts, errorCode);
|
||||
Media::DecodeOptions decodeOpts;
|
||||
decodeOpts.desiredPixelFormat = Media::PixelFormat::BGRA_8888;
|
||||
if (imageSource) {
|
||||
@ -448,7 +522,7 @@ bool LayeredDrawableDescriptor::CreatePixelMap()
|
||||
if (foreground_.has_value() || GetPixelMapFromJsonBuf(false)) {
|
||||
foreground = ImageConverter::PixelMapToBitmap(foreground_.value());
|
||||
} else {
|
||||
HILOG_INFO("Get pixelMap of foreground failed.");
|
||||
HILOG_WARN("Get pixelMap of foreground failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -456,15 +530,7 @@ bool LayeredDrawableDescriptor::CreatePixelMap()
|
||||
if (background_.has_value() || GetPixelMapFromJsonBuf(true)) {
|
||||
background = ImageConverter::PixelMapToBitmap(background_.value());
|
||||
} else {
|
||||
HILOG_ERROR("Get pixelMap of background failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<Rosen::Drawing::Bitmap> mask;
|
||||
if (mask_.has_value() || GetMaskByPath() || GetDefaultMask()) {
|
||||
mask = ImageConverter::PixelMapToBitmap(mask_.value());
|
||||
} else {
|
||||
HILOG_ERROR("Get pixelMap of mask failed.");
|
||||
HILOG_WARN("Get pixelMap of background failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -482,10 +548,20 @@ bool LayeredDrawableDescriptor::CreatePixelMap()
|
||||
bitmapCanvas.AttachBrush(brush);
|
||||
DrawOntoCanvas(background, SIDE, SIDE, bitmapCanvas);
|
||||
bitmapCanvas.DetachBrush();
|
||||
|
||||
brush.SetBlendMode(Rosen::Drawing::BlendMode::DST_ATOP);
|
||||
bitmapCanvas.AttachBrush(brush);
|
||||
DrawOntoCanvas(mask, SIDE, SIDE, bitmapCanvas);
|
||||
Rosen::Drawing::Bitmap maskBitmap;
|
||||
auto maskBitmapPtr = std::make_shared<Rosen::Drawing::Bitmap>(maskBitmap);
|
||||
auto maskImageInfo = Rosen::Drawing::ImageInfo::MakeN32Premul(SIDE, SIDE);
|
||||
maskBitmap.Build(maskImageInfo);
|
||||
Rosen::Drawing::Canvas maskBitmapCanvas;
|
||||
maskBitmapCanvas.Bind(maskBitmap);
|
||||
maskBitmapCanvas.Clear(SK_ColorTRANSPARENT);
|
||||
RenderSVGMask(&maskBitmapCanvas, defaultSVGMaskData_, defaultSVGMaskDataLength_, SIDE, SIDE);
|
||||
DrawOntoCanvas(maskBitmapPtr, SIDE, SIDE, bitmapCanvas);
|
||||
bitmapCanvas.DetachBrush();
|
||||
|
||||
brush.SetBlendMode(Rosen::Drawing::BlendMode::SRC_ATOP);
|
||||
bitmapCanvas.AttachBrush(brush);
|
||||
DrawOntoCanvas(foreground, SIDE, SIDE, bitmapCanvas);
|
||||
|
@ -46,6 +46,9 @@
|
||||
|
||||
namespace OHOS::Ace::Napi {
|
||||
using OptionalPixelMap = std::optional<std::shared_ptr<Media::PixelMap>>;
|
||||
#ifdef USE_ROSEN_DRAWING
|
||||
using OptionalBitMap = std::optional<std::shared_ptr<Rosen::Drawing::Bitmap>>;
|
||||
#endif
|
||||
struct DrawableItem {
|
||||
using RState = Global::Resource::RState;
|
||||
std::unique_ptr<uint8_t[]> data_;
|
||||
@ -81,6 +84,7 @@ public:
|
||||
: jsonBuf_(std::move(jsonBuf)), len_(len)
|
||||
{
|
||||
InitialResource(resourceMgr);
|
||||
InitialSVGResource(resourceMgr);
|
||||
};
|
||||
LayeredDrawableDescriptor(std::unique_ptr<uint8_t[]> jsonBuf, size_t len,
|
||||
const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr, std::string path, uint32_t iconType,
|
||||
@ -88,6 +92,7 @@ public:
|
||||
: jsonBuf_(std::move(jsonBuf)), len_(len), maskPath_(std::move(path)), iconType_(iconType), density_(density)
|
||||
{
|
||||
InitialResource(resourceMgr);
|
||||
InitialSVGResource(resourceMgr);
|
||||
};
|
||||
LayeredDrawableDescriptor(std::unique_ptr<uint8_t[]> jsonBuf, size_t len,
|
||||
const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr, std::string path, uint32_t iconType,
|
||||
@ -97,6 +102,7 @@ public:
|
||||
{
|
||||
InitLayeredParam(foregroundInfo, backgroundInfo);
|
||||
InitialResource(resourceMgr);
|
||||
InitialSVGResource(resourceMgr);
|
||||
};
|
||||
|
||||
~LayeredDrawableDescriptor() override = default;
|
||||
@ -111,6 +117,7 @@ public:
|
||||
private:
|
||||
friend class ImageConverter;
|
||||
void InitialResource(const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr);
|
||||
void InitialSVGResource(const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr);
|
||||
bool PreGetPixelMapFromJsonBuf(
|
||||
const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr, bool isBackground);
|
||||
DrawableItem PreGetDrawableItem(
|
||||
@ -131,6 +138,8 @@ private:
|
||||
|
||||
std::unique_ptr<uint8_t[]> defaultMaskData_;
|
||||
size_t defaultMaskDataLength_ = 0;
|
||||
std::unique_ptr<uint8_t[]> defaultSVGMaskData_;
|
||||
size_t defaultSVGMaskDataLength_ = 0;
|
||||
DrawableItem backgroundItem_;
|
||||
DrawableItem foregroundItem_;
|
||||
std::unique_ptr<uint8_t[]> jsonBuf_;
|
||||
@ -142,6 +151,9 @@ private:
|
||||
OptionalPixelMap background_;
|
||||
OptionalPixelMap mask_;
|
||||
OptionalPixelMap layeredPixelMap_;
|
||||
#ifdef USE_ROSEN_DRAWING
|
||||
OptionalBitMap svgMaskBitMap_;
|
||||
#endif
|
||||
};
|
||||
|
||||
class DrawableDescriptorFactory {
|
||||
|
Loading…
Reference in New Issue
Block a user