@react-native-ohos/react-native-svg 15.12.1-rc.5 → 15.12.1-rc.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Use these variables when you tailor your ArkTS code. They must be of the const type.
3
3
  */
4
- export const HAR_VERSION = '15.12.1-rc.2';
4
+ export const HAR_VERSION = '15.12.1-rc.5';
5
5
  export const BUILD_MODE_NAME = 'debug';
6
6
  export const DEBUG = true;
7
7
  export const TARGET_NAME = 'default';
@@ -6,7 +6,7 @@
6
6
  name: '@react-native-ohos/react-native-svg',
7
7
  type: 'module',
8
8
  main: 'index.ets',
9
- version: '15.12.1-rc.5',
9
+ version: '15.12.1-rc.7',
10
10
  dependencies: {
11
11
  "@rnoh/react-native-openharmony": "file:../../node_modules/@react-native-oh/react-native-harmony/harmony/react_native_openharmony.har"
12
12
  },
@@ -23,7 +23,7 @@ target_link_libraries(rnoh_svg PUBLIC libimage_packer.so)
23
23
  target_link_libraries(rnoh_svg PUBLIC librawfile.z.so)
24
24
  target_link_libraries(rnoh_svg PUBLIC librcp_c.so)
25
25
  target_link_libraries(rnoh_svg PUBLIC libohfileuri.so)
26
-
26
+ target_link_libraries(rnoh_svg PUBLIC libdeviceinfo_ndk.z.so)
27
27
 
28
28
  if("${OHOS_ARCH}" STREQUAL "arm64-v8a")
29
29
  target_link_directories(rnoh_svg PUBLIC ${HMOS_SDK_NATIVE}/sysroot/usr/lib/aarch64-linux-ohos)
@@ -8,6 +8,7 @@
8
8
 
9
9
  #include "RNOH/arkui/ArkUINode.h"
10
10
  #include "SvgForeignObjectNodeDelegate.h"
11
+ #include "SvgForeignProps.h"
11
12
  #include "SvgHost.h"
12
13
  #include "SvgNode.h"
13
14
  #include "arkui/native_node.h"
@@ -39,8 +40,7 @@ public:
39
40
  void SetGroupNode(const std::weak_ptr<SvgNode> &node) { _groupNode = node; }
40
41
  void ResetNodeHandle() {}
41
42
  void AddChild(ArkUINode &node);
42
- void SetForeignObject(OH_PixelmapNative *pixelMap, float w, float h, float x, float y) {
43
- ForeignProps foreignProps = {std::move(pixelMap), w, h, x, y};
43
+ void SetForeignObject(ForeignProps foreignProps) {
44
44
  if (auto groupNode = _groupNode.lock()) {
45
45
  groupNode->SetForeignObject(std::move(foreignProps));
46
46
  }
@@ -40,11 +40,11 @@ SvgForeignObjectNode::~SvgForeignObjectNode() {
40
40
  }
41
41
  void SvgForeignObjectNode::insertChild(ArkUINode &child, std::size_t index) { mStackNode.insertChild(child, index); }
42
42
 
43
- void SvgForeignObjectNode::SetSnapHeight(float height) { _height = height; }
43
+ void SvgForeignObjectNode::SetSnapHeight(Dimension height) { _height = height; }
44
44
 
45
- void SvgForeignObjectNode::SetSnapWidth(float width) { _width = width; }
45
+ void SvgForeignObjectNode::SetSnapWidth(Dimension width) { _width = width; }
46
46
 
47
- void SvgForeignObjectNode::SetSnapPosition(float x, float y) {
47
+ void SvgForeignObjectNode::SetSnapPosition(Dimension x, Dimension y) {
48
48
  _positionX = x;
49
49
  _positionY = y;
50
50
  }
@@ -58,17 +58,17 @@ void SvgForeignObjectNode::onNodeEvent(ArkUI_NodeEventType eventType, EventArgs
58
58
  return;
59
59
  }
60
60
  _isGeneratedPixelMap = false;
61
- m_NodeDelegate->onDrawForeignImage(pixelMap, _width, _height, _positionX, _positionY);
61
+ ForeignProps foreignProps = {pixelMap, _width, _height, _positionX,
62
+ _positionY, _path, _clipRule, _mask, pointScaleFactor_, transform_};
63
+ m_NodeDelegate->onDrawForeignImage(foreignProps);
62
64
  }
63
65
  }
64
66
  }
65
67
 
66
68
  OH_PixelmapNative *SvgForeignObjectNode::GetNodePixelMap() {
67
- DLOG(INFO) << "[svgForeignNode] OH_CURRENT_API_VERSION:" << OH_CURRENT_API_VERSION
68
- << ";ROM SDK:" << OH_GetSdkApiVersion();
69
-
70
- #if OH_CURRENT_API_VERSION >= 15
71
- if (OH_GetSdkApiVersion() < 15) {
69
+ #ifdef OH_CURRENT_API_VERSION
70
+ if (OH_CURRENT_API_VERSION < 15 || OH_GetSdkApiVersion() < 15) {
71
+ LOG(ERROR) << "[svgForeignNode] current sdk or rom cannot support ForeignObject";
72
72
  return nullptr;
73
73
  }
74
74
  OH_PixelmapNative *pixelMap;
@@ -24,6 +24,7 @@
24
24
  #include "RNOH/arkui/ArkUINode.h"
25
25
  #include "RNOH/arkui/StackNode.h"
26
26
  #include "SvgForeignObjectNodeDelegate.h"
27
+ #include "properties/Dimension.h"
27
28
 
28
29
  namespace rnoh {
29
30
  namespace svg {
@@ -34,21 +35,44 @@ public:
34
35
  void onNodeEvent(ArkUI_NodeEventType eventType, EventArgs &eventArgs) override;
35
36
  StackNode &getSnapNode() { return mStackNode; }
36
37
  void insertChild(ArkUINode &child, std::size_t index);
37
- void SetSnapPosition(float x, float y);
38
- void SetSnapWidth(float width);
39
- void SetSnapHeight(float height);
38
+ void SetSnapPosition(Dimension x, Dimension y);
39
+ void SetSnapWidth(Dimension width);
40
+ void SetSnapHeight(Dimension height);
41
+ void SetPointScaleFactor(float pointScaleFactor) {
42
+ pointScaleFactor_ = pointScaleFactor;
43
+ }
44
+ void SetTransform(std::vector<double> transform) {
45
+ transform_ = transform;
46
+ }
47
+ void setNodeSize(float w, float h){
48
+ mStackNode.setSize({w, h});
49
+ }
40
50
  OH_PixelmapNative *GetNodePixelMap();
41
51
  void SetForeignNodeDelegate(SvgForeignObjectNodeDelegate *delegate) { m_NodeDelegate = delegate; };
42
52
  void SetGeneratedPixelMap(bool isNeed) {
43
53
  _isGeneratedPixelMap = isNeed;
44
54
  }
55
+
56
+ void SetClipPath(std::string path,int clipRule) {
57
+ _path = path;
58
+ _clipRule = clipRule;
59
+ }
60
+ void SetMask(std::string mask) {
61
+ _mask = mask;
62
+ }
63
+
45
64
  private:
46
65
  StackNode mStackNode;
47
66
  SvgForeignObjectNodeDelegate *m_NodeDelegate;
48
- float _width{0};
49
- float _height{0};
50
- float _positionX{0};
51
- float _positionY{0};
67
+ Dimension _width{0};
68
+ Dimension _height{0};
69
+ Dimension _positionX{0};
70
+ Dimension _positionY{0};
71
+ std::string _path{""};
72
+ std::string _mask{""};
73
+ std::vector<double> transform_;
74
+ int _clipRule{0};
75
+ float pointScaleFactor_{0};
52
76
  bool _isGeneratedPixelMap{false}; //防止快照生成多次,导致性能影响
53
77
  };
54
78
 
@@ -21,10 +21,10 @@
21
21
 
22
22
  #ifndef HARMONY_SVGFOREIGNOBJECTNODEDELEGATE_H
23
23
  #define HARMONY_SVGFOREIGNOBJECTNODEDELEGATE_H
24
- #include <multimedia/image_framework/image/pixelmap_native.h>
24
+ #include "SvgForeignProps.h"
25
25
  class SvgForeignObjectNodeDelegate {
26
26
  public:
27
27
  virtual ~SvgForeignObjectNodeDelegate() = default;
28
- virtual void onDrawForeignImage(OH_PixelmapNative *foreignPixelMap,float width,float height,float x,float y){};
28
+ virtual void onDrawForeignImage(ForeignProps props){};
29
29
  };
30
30
  #endif //HARMONY_SVGFOREIGNOBJECTNODEDELEGATE_H
@@ -0,0 +1,39 @@
1
+ /*
2
+ * Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
3
+ * Use of this source code is governed by a MIT license that can be
4
+ * found in the LICENSE file.
5
+ *
6
+ * This file incorporates from the OpenHarmony project, licensed under
7
+ * the Apache License, Version 2.0. Specifically:
8
+ * - [OpenHarmony/arkui_ace_engine] (https://gitee.com/openharmony/arkui_ace_engine)
9
+ *
10
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
11
+ * use this file except in compliance with the License. You may obtain a copy
12
+ * of the License at:
13
+ * http://www.apache.org/licenses/LICENSE-2.0
14
+ *
15
+ * Unless required by applicable law or agreed to in writing, software
16
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18
+ * License for the specific language governing permissions and limitations
19
+ * under the License.
20
+ */
21
+
22
+ #ifndef HARMONY_FOREIGNPROPS_H
23
+ #define HARMONY_FOREIGNPROPS_H
24
+ #include "properties/Dimension.h"
25
+ #include <multimedia/image_framework/image/pixelmap_native.h>
26
+ #include <string>
27
+ struct ForeignProps {
28
+ OH_PixelmapNative *foreignPixelMap{nullptr};
29
+ rnoh::svg::Dimension width;
30
+ rnoh::svg::Dimension height;
31
+ rnoh::svg::Dimension x;
32
+ rnoh::svg::Dimension y;
33
+ std::string path;
34
+ int clipRule;
35
+ std::string mask;
36
+ float pointScaleFactor;
37
+ std::vector<double> transform;
38
+ };
39
+ #endif //HARMONY_FOREIGNPROPS_H
@@ -141,9 +141,8 @@ void SvgNode::OnMask(OH_Drawing_Canvas *canvas) {
141
141
  refMask->Draw(canvas);
142
142
  }
143
143
 
144
- void SvgNode::OnTransform(OH_Drawing_Canvas *canvas) {
144
+ void SvgNode::OnTransform(OH_Drawing_Canvas *canvas, std::vector<double> transform) {
145
145
  // input transfrom: (float scaleX, float skewY, float skewX, float scaleY, float transX, float transY)
146
- const auto &transform = attributes_.transform;
147
146
  /* (OH_Drawing_Matrix* , float scaleX, float skewX, float transX, float skewY, float scaleY, float transY, float
148
147
  persp0, float persp1, float persp2 )
149
148
  */
@@ -192,7 +191,7 @@ void SvgNode::Draw(OH_Drawing_Canvas *canvas) {
192
191
  const auto count = OH_Drawing_CanvasGetSaveCount(canvas);
193
192
  OH_Drawing_CanvasSave(canvas);
194
193
  if (!attributes_.transform.empty()) {
195
- OnTransform(canvas);
194
+ OnTransform(canvas, attributes_.transform);
196
195
  }
197
196
  if (!hrefClipPath_.empty()) {
198
197
  OnClipPath(canvas);
@@ -296,12 +295,55 @@ double SvgNode::getCanvasDiagonal() {
296
295
  return canvasDiagonal_;
297
296
  }
298
297
 
298
+ void SvgNode::DrawForeignClip(OH_Drawing_Canvas *canvas,const std::string &id,int clipRule) {
299
+ if (!context_) {
300
+ DLOG(INFO) << "[svgForeignNode] NO CONTEXT";
301
+ return;
302
+ }
303
+ auto refSvgNode = context_->GetSvgNodeById(id);
304
+ if (!refSvgNode) {
305
+ DLOG(WARNING) << "[svgForeignNode] clipPath: SvgNode is null!";
306
+ return;
307
+ };
308
+ auto clipPath = refSvgNode->AsPath();
309
+ drawing::Path::FillType fillType = clipRule == 0
310
+ ? OH_Drawing_PathFillType::PATH_FILL_TYPE_EVEN_ODD
311
+ : OH_Drawing_PathFillType::PATH_FILL_TYPE_WINDING;
312
+ clipPath.SetFillType(fillType);
313
+ OH_Drawing_CanvasClipPath(canvas, clipPath.get(), OH_Drawing_CanvasClipOp::INTERSECT, true);
314
+ }
315
+
316
+ void SvgNode::DrawForeignMask(OH_Drawing_Canvas *canvas, const std::string &id) {
317
+ if (!context_) {
318
+ DLOG(INFO) << "[svgForeignNode] NO CONTEXT";
319
+ return;
320
+ }
321
+ auto refMask = context_->GetSvgNodeById(id);
322
+ if (!refMask) {
323
+ return;
324
+ };
325
+ refMask->Draw(canvas);
326
+ }
327
+
299
328
  void SvgNode::DrawForeignPixelMap(OH_Drawing_Canvas *canvas, ForeignProps _foreignProps) {
300
329
  if (!_foreignProps.foreignPixelMap) {
301
330
  DLOG(INFO) << "[svgForeignNode] foreignPixelMap is null";
302
331
  return;
303
332
  }
304
- DLOG(INFO) << "[svgForeignNode] DrawForeignPixelMap start , width:" << _foreignProps.width;
333
+ if (!_foreignProps.transform.empty()) {
334
+ OnTransform(canvas, _foreignProps.transform);
335
+ }
336
+ if (!_foreignProps.path.empty()) {
337
+ DrawForeignClip(canvas,_foreignProps.path, _foreignProps.clipRule);
338
+ }
339
+
340
+ if (!_foreignProps.mask.empty()) {
341
+ DrawForeignMask(canvas,_foreignProps.mask);
342
+ }
343
+ double postionX = _foreignProps.x.ParsePropsToPx(OH_Drawing_CanvasGetWidth(canvas), _foreignProps.pointScaleFactor);
344
+ double postionY = _foreignProps.y.ParsePropsToPx(OH_Drawing_CanvasGetHeight(canvas), _foreignProps.pointScaleFactor);
345
+ double foreignW = _foreignProps.width.ParsePropsToPx(OH_Drawing_CanvasGetWidth(canvas), _foreignProps.pointScaleFactor);
346
+ double foreignH = _foreignProps.height.ParsePropsToPx(OH_Drawing_CanvasGetHeight(canvas), _foreignProps.pointScaleFactor);
305
347
  OH_Pixelmap_ImageInfo *imageInfo;
306
348
  OH_PixelmapImageInfo_Create(&imageInfo);
307
349
 
@@ -316,7 +358,9 @@ void SvgNode::DrawForeignPixelMap(OH_Drawing_Canvas *canvas, ForeignProps _forei
316
358
  OH_PixelmapNative_Release(_foreignProps.foreignPixelMap);
317
359
  return;
318
360
  }
319
-
361
+ float originalRelWidth = originalWidth > foreignW ? foreignW : originalWidth;
362
+ float originalRelHeight = originalHeight > foreignH ? foreignH : originalHeight;
363
+ DLOG(INFO) << "[svgForeignNode] DrawForeignPixelMap start , foreignH:" << foreignH << ";originalHeight:" << originalHeight <<";originalRelHeight:" << originalRelHeight;
320
364
  OH_Drawing_PixelMap *ohPixelMap = OH_Drawing_PixelMapGetFromOhPixelMapNative(_foreignProps.foreignPixelMap);
321
365
  if (!ohPixelMap) {
322
366
  DLOG(WARNING) << "[svgForeignNode] Failed to get OH_Drawing_PixelMap";
@@ -326,15 +370,12 @@ void SvgNode::DrawForeignPixelMap(OH_Drawing_Canvas *canvas, ForeignProps _forei
326
370
 
327
371
  OH_Drawing_CanvasSave(canvas);
328
372
 
329
- OH_Drawing_CanvasTranslate(canvas, _foreignProps.x, _foreignProps.y);
330
-
331
-
332
- float scaleX = static_cast<float>(_foreignProps.width) / originalWidth;
333
- float scaleY = static_cast<float>(_foreignProps.height) / originalHeight;
373
+ OH_Drawing_CanvasTranslate(canvas, postionX, postionY);
374
+
334
375
  OH_Drawing_CanvasScale(canvas, 1, 1);
335
376
 
336
- OH_Drawing_Rect *srcRect = OH_Drawing_RectCreate(0, 0, originalWidth, originalHeight);
337
- OH_Drawing_Rect *dstRect = OH_Drawing_RectCreate(0, 0, originalWidth, originalHeight);
377
+ OH_Drawing_Rect *srcRect = OH_Drawing_RectCreate(0, 0, originalRelWidth, originalRelHeight);
378
+ OH_Drawing_Rect *dstRect = OH_Drawing_RectCreate(0, 0, originalRelWidth, originalRelHeight);
338
379
  OH_Drawing_SamplingOptions *sampling = OH_Drawing_SamplingOptionsCreate(FILTER_MODE_LINEAR, MIPMAP_MODE_LINEAR);
339
380
  OH_Drawing_CanvasDrawPixelMapRect(canvas, ohPixelMap, srcRect, dstRect, sampling);
340
381
 
@@ -28,6 +28,7 @@
28
28
  #include <type_traits>
29
29
  #include "SvgBaseAttribute.h"
30
30
  #include "SvgContext.h"
31
+ #include "SvgForeignProps.h"
31
32
  #include "properties/Decoration.h"
32
33
  #include "properties/Dimension.h"
33
34
  #include "properties/Size.h"
@@ -44,15 +45,6 @@
44
45
  namespace rnoh {
45
46
  namespace svg {
46
47
 
47
- struct ForeignProps {
48
- OH_PixelmapNative *foreignPixelMap{nullptr};
49
- float width;
50
- float height;
51
- float x;
52
- float y;
53
- };
54
-
55
-
56
48
  constexpr int INHERIT_TYPE = 2;
57
49
 
58
50
  class SvgNode : public std::enable_shared_from_this<SvgNode> {
@@ -306,6 +298,7 @@ public:
306
298
  void SetForeignObject(ForeignProps foreignProps) {
307
299
  _foreignPropsArray.emplace_back(foreignProps);
308
300
  }
301
+
309
302
 
310
303
  protected:
311
304
  // override as need by derived class
@@ -318,7 +311,7 @@ protected:
318
311
  virtual void OnDrawTraversed(OH_Drawing_Canvas *canvas);
319
312
  void OnClipPath(OH_Drawing_Canvas *canvas);
320
313
  void OnMask(OH_Drawing_Canvas *canvas);
321
- void OnTransform(OH_Drawing_Canvas *canvas);
314
+ void OnTransform(OH_Drawing_Canvas *canvas, std::vector<double> transform);
322
315
 
323
316
  const Rect &GetRootViewBox() const;
324
317
 
@@ -329,6 +322,9 @@ protected:
329
322
 
330
323
  std::shared_ptr<PatternAttr> GetPatternAttr(const std::string &href);
331
324
  void DrawForeignPixelMap(OH_Drawing_Canvas *canvas,ForeignProps _foreignProps);
325
+ void DrawForeignMask(OH_Drawing_Canvas *canvas, const std::string &id);
326
+ void DrawForeignClip(OH_Drawing_Canvas *canvas, const std::string &id, int clipRule);
327
+
332
328
  void InitNoneFlag() {
333
329
  hrefFill_ = false;
334
330
  hrefRender_ = false;
@@ -33,24 +33,52 @@ RNSVGForeignObjectComponentInstance::RNSVGForeignObjectComponentInstance(Context
33
33
 
34
34
 
35
35
  RNSVGForeignObjectComponentInstance::~RNSVGForeignObjectComponentInstance() {
36
- NativeNodeApi::getInstance()->unregisterNodeEvent(mForeignStackNode.getArkUINodeHandle(), NODE_EVENT_ON_AREA_CHANGE);
36
+ NativeNodeApi::getInstance()->unregisterNodeEvent(mForeignStackNode.getArkUINodeHandle(),
37
+ NODE_EVENT_ON_AREA_CHANGE);
37
38
  }
38
39
 
39
40
  void RNSVGForeignObjectComponentInstance::onFinalizeUpdates() {
40
41
  ComponentInstance::onFinalizeUpdates();
41
42
  if (m_props) {
42
- float pointScaleFactor = getLayoutMetrics().pointScaleFactor;
43
- mForeignStackNode.SetSnapPosition(pointScaleFactor * std::stof(DynamicUtils::DynamicToString(m_props->x)),
44
- pointScaleFactor * std::stof(DynamicUtils::DynamicToString(m_props->y)));
45
- mForeignStackNode.SetSnapWidth(pointScaleFactor * std::stof(DynamicUtils::DynamicToString(m_props->width)));
46
- mForeignStackNode.SetSnapHeight(pointScaleFactor * std::stof(DynamicUtils::DynamicToString(m_props->height)));
43
+ mForeignStackNode.SetPointScaleFactor(getLayoutMetrics().pointScaleFactor);
44
+ mForeignStackNode.SetSnapPosition(propsConversionValue(m_props->x), propsConversionValue(m_props->y));
45
+ mForeignStackNode.SetSnapWidth(propsConversionValue(m_props->width));
46
+ mForeignStackNode.SetSnapHeight(propsConversionValue(m_props->height));
47
+
48
+ mForeignStackNode.SetClipPath(m_props->clipPath, m_props->clipRule);
49
+ mForeignStackNode.SetMask(m_props->mask);
50
+ mForeignStackNode.SetTransform(m_props->matrix);
51
+ auto childs = getChildren();
52
+ if (childs.size() > 0) {
53
+ for (ComponentInstance::Shared c : childs) {
54
+ if ((m_props->opacity > 0 && m_props->opacity != 1)) {
55
+ setOpacity(c->getLocalRootArkUINode(), m_props->opacity);
56
+ }
57
+ }
58
+ }
47
59
  mForeignStackNode.SetGeneratedPixelMap(true);
48
60
  }
49
61
  }
50
62
 
63
+ Dimension RNSVGForeignObjectComponentInstance::propsConversionValue(const folly::dynamic &d) {
64
+ if (d.isNull()) {
65
+ return Dimension(0, DimensionUnit::INVALID);
66
+ }
67
+ return StringUtils::StringToDimension(d.asString(), true);
68
+ }
69
+
70
+ void RNSVGForeignObjectComponentInstance::setOpacity(ArkUINode &node, float op) {
71
+ if (op != 1) {
72
+ node.setOpacity(m_props->opacity);
73
+ }
74
+ }
75
+
51
76
  void RNSVGForeignObjectComponentInstance::onChildInserted(ComponentInstance::Shared const &childComponentInstance,
52
77
  std::size_t index) {
53
78
  CppComponentInstance::onChildInserted(childComponentInstance, index);
79
+ float width = childComponentInstance->getLayoutMetrics().frame.size.width;
80
+ float height = childComponentInstance->getLayoutMetrics().frame.size.height;
81
+ mForeignStackNode.setNodeSize(width, height);
54
82
  node.insertChild(childComponentInstance->getLocalRootArkUINode(), index);
55
83
  }
56
84
 
@@ -27,6 +27,8 @@
27
27
  #include "RNOH/arkui/ColumnNode.h"
28
28
  #include "RNOH/arkui/NativeNodeApi.h"
29
29
  #include "utils/DynamicUtils.h"
30
+ #include "properties/Dimension.h"
31
+ #include "utils/StringUtils.h"
30
32
  namespace rnoh {
31
33
  namespace svg {
32
34
  class RNSVGForeignObjectComponentInstance : public CppComponentInstance<facebook::react::RNSVGForeignObjectShadowNode> {
@@ -40,7 +42,10 @@ public:
40
42
  void onChildRemoved(ComponentInstance::Shared const &childComponentInstance) override;
41
43
 
42
44
  SvgForeignObjectNode &getLocalRootArkUINode() override;
43
-
45
+
46
+ void setOpacity(ArkUINode &node, float op);
47
+
48
+ Dimension propsConversionValue(const folly::dynamic& d);
44
49
  private:
45
50
  SvgForeignObjectNode mForeignStackNode;
46
51
  ColumnNode node;
@@ -47,12 +47,11 @@ void RNSVGSvgViewComponentInstance::onFinalizeUpdates() {
47
47
  getLocalRootArkUINode().markDirty();
48
48
  }
49
49
 
50
- void RNSVGSvgViewComponentInstance::onDrawForeignImage(OH_PixelmapNative *foreignPixelMap, float width, float height,
51
- float x, float y) {
52
- if (foreignPixelMap) {
53
- DLOG(INFO) << "[svgForeignNode] RNSVGSvgViewComponentInstance OH_PixelmapNative is not null, position:{ x:" << x
54
- << ",y:" << y << "},width:" << width << ";height:" << height;
55
- m_svgArkUINode.SetForeignObject(foreignPixelMap, width, height, x, y);
50
+ void RNSVGSvgViewComponentInstance::onDrawForeignImage(ForeignProps foreignProps) {
51
+ if (foreignProps.foreignPixelMap) {
52
+ DLOG(INFO) << "[svgForeignNode] RNSVGSvgViewComponentInstance OH_PixelmapNative is not null, position:{ x:" << foreignProps.x.Value()
53
+ << ",y:" << foreignProps.y.Value() << "},width:" << foreignProps.width.Value() << ";height:" << foreignProps.height.Value();
54
+ m_svgArkUINode.SetForeignObject(foreignProps);
56
55
  m_svgArkUINode.markDirty();
57
56
  } else {
58
57
  DLOG(INFO) << "RNSVGSvgViewComponentInstance OH_PixelmapNative is null";
@@ -31,7 +31,7 @@ public:
31
31
  ~RNSVGSvgViewComponentInstance();
32
32
 
33
33
  void onFinalizeUpdates() override;
34
- void onDrawForeignImage(OH_PixelmapNative *foreignPixelMap,float width,float height,float x,float y) override;
34
+ void onDrawForeignImage(ForeignProps foreignProps) override;
35
35
  // get SvgNode from childComponentInstance and set it to root_
36
36
  void onChildInserted(ComponentInstance::Shared const &childComponentInstance, std::size_t index) override;
37
37
 
@@ -44,9 +44,30 @@ void ResponseCallback(void *usrCtx, Rcp_Response *response, uint32_t errCode) {
44
44
  }
45
45
 
46
46
  void HttpTaskProcessor::createParentPath(const fs::path &filePath) {
47
- fs::path parentPath = filePath.parent_path();
48
- if (!parentPath.empty() && !fs::exists(parentPath)) {
49
- fs::create_directories(parentPath);
47
+ try {
48
+ fs::path parentPath = filePath.parent_path();
49
+ if (!parentPath.empty() && !fs::exists(parentPath)) {
50
+ // 检查路径的有效性
51
+ if (parentPath.is_relative()) {
52
+ LOG(ERROR) << "[SVGImage] Invalid parent path (relative path): " << parentPath;
53
+ return;
54
+ }
55
+ // 尝试创建目录,并捕获可能的异常
56
+ auto result = fs::create_directories(parentPath);
57
+ if (result) {
58
+ LOG(INFO) << "[SVGImage] Successfully created parent directories: " << parentPath;
59
+ } else {
60
+ LOG(ERROR) << "[SVGImage] Failed to create parent directories: " << parentPath;
61
+ }
62
+ }
63
+ } catch (const fs::filesystem_error& e) {
64
+ LOG(ERROR) << "[SVGImage] Filesystem error in createParentPath: " << e.what()
65
+ << " for path: " << filePath;
66
+ } catch (const std::exception& e) {
67
+ LOG(ERROR) << "[SVGImage] Standard exception in createParentPath: " << e.what()
68
+ << " for path: " << filePath;
69
+ } catch (...) {
70
+ LOG(ERROR) << "[SVGImage] Unknown exception in createParentPath for path: " << filePath;
50
71
  }
51
72
  }
52
73
 
@@ -54,14 +75,52 @@ size_t HttpTaskProcessor::saveImage(const char *buffer, uint32_t length) {
54
75
  size_t status = 0;
55
76
  if (filePath_ == "")
56
77
  return status;
57
- createParentPath(filePath_);
58
- fp_ = fopen(filePath_.c_str(), "w");
59
- if (fp_) {
60
- status = fwrite(buffer, sizeof(char), length, fp_);
61
- fclose(fp_);
62
- } else {
63
- LOG(ERROR) << "[SVGImage] write to file failed: " << filePath_;
78
+
79
+ // 验证输入参数
80
+ if (buffer == nullptr || length == 0) {
81
+ LOG(ERROR) << "[SVGImage] Invalid buffer or length in saveImage";
82
+ return status;
83
+ }
84
+
85
+ try {
86
+ // 先创建父目录
87
+ createParentPath(filePath_);
88
+
89
+ // 验证文件路径的合理性
90
+ fs::path filePath(filePath_);
91
+ if (filePath.has_filename()) {
92
+ LOG(INFO) << "[SVGImage] Attempting to save image to: " << filePath_;
93
+ } else {
94
+ LOG(ERROR) << "[SVGImage] Invalid file path (no filename): " << filePath_;
95
+ return status;
96
+ }
97
+
98
+ // 打开文件进行写入
99
+ fp_ = fopen(filePath_.c_str(), "w");
100
+ if (fp_) {
101
+ status = fwrite(buffer, sizeof(char), length, fp_);
102
+ fclose(fp_);
103
+
104
+ if (status == length) {
105
+ LOG(INFO) << "[SVGImage] Successfully saved image: " << filePath_
106
+ << " (size: " << length << " bytes)";
107
+ } else {
108
+ LOG(ERROR) << "[SVGImage] Partial write error. Expected: " << length
109
+ << ", wrote: " << status;
110
+ status = 0; // 返回0表示失败
111
+ }
112
+ } else {
113
+ LOG(ERROR) << "[SVGImage] Failed to open file for writing: " << filePath_
114
+ << " (errno: " << errno << ")";
115
+ }
116
+ } catch (const std::exception& e) {
117
+ LOG(ERROR) << "[SVGImage] Exception in saveImage: " << e.what();
118
+ status = 0;
119
+ } catch (...) {
120
+ LOG(ERROR) << "[SVGImage] Unknown exception in saveImage";
121
+ status = 0;
64
122
  }
123
+
65
124
  return status;
66
125
  }
67
126
 
@@ -141,6 +141,20 @@ public:
141
141
  return 0.0;
142
142
  };
143
143
 
144
+ double ParsePropsToPx(double relative, float pointScaleFactor){
145
+ if (unit_ == DimensionUnit::NONE) {
146
+ return value_*pointScaleFactor;
147
+ }
148
+ if (unit_ == DimensionUnit::PERCENT) {
149
+ return value_*relative - pointScaleFactor;
150
+ }
151
+ if (unit_ == DimensionUnit::VP) {
152
+ return value_*pointScaleFactor;
153
+ } else {
154
+ return value_;
155
+ }
156
+ }
157
+
144
158
  double GetNativeValue(DimensionUnit unit, double scale) const {
145
159
  if (unit_ == unit) {
146
160
  return value_;
@@ -20,6 +20,35 @@ RNSVGImageModule::RNSVGImageModule(const ArkTSTurboModule::Context ctx, const st
20
20
  // 获取缓存路径前缀
21
21
  auto cache = this->callSync("getCacheDir", {});
22
22
  m_fileCacheDir = cache.asString() + "/";
23
+
24
+ // 确保缓存目录存在
25
+ try {
26
+ fs::path cachePath(m_fileCacheDir);
27
+ if (!fs::exists(cachePath)) {
28
+ if (auto result = fs::create_directories(cachePath)) {
29
+ LOG(INFO) << "[SVGImage] Created cache directory: " << m_fileCacheDir;
30
+ } else {
31
+ LOG(WARNING) << "[SVGImage] Failed to create cache directory: " << m_fileCacheDir;
32
+ }
33
+ } else if (!fs::is_directory(cachePath)) {
34
+ LOG(ERROR) << "[SVGImage] Cache path exists but is not a directory: " << m_fileCacheDir;
35
+ // 尝试创建备份目录
36
+ std::string backupDir = m_fileCacheDir + "_backup";
37
+ fs::create_directories(backupDir);
38
+ m_fileCacheDir = backupDir + "/";
39
+ LOG(INFO) << "[SVGImage] Using backup cache directory: " << m_fileCacheDir;
40
+ }
41
+ } catch (const std::exception& e) {
42
+ LOG(ERROR) << "[SVGImage] Error creating/validating cache directory: " << e.what();
43
+ // 使用临时目录作为后备方案
44
+ m_fileCacheDir = "/data/local/tmp/rnsvg_cache/";
45
+ try {
46
+ fs::create_directories(m_fileCacheDir);
47
+ } catch (...) {
48
+ LOG(ERROR) << "[SVGImage] Failed to create temp cache directory";
49
+ }
50
+ }
51
+
23
52
  m_imageSourceResolver = std::make_shared<ImageSourceResolver>(m_fileCacheDir);
24
53
 
25
54
  fs::path directoryPath = m_fileCacheDir;
package/harmony/svg.har CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native-ohos/react-native-svg",
3
- "version": "15.12.1-rc.5",
3
+ "version": "15.12.1-rc.7",
4
4
  "description": "",
5
5
  "react-native": "src/index",
6
6
  "main": "lib/commonjs/index",
@@ -21,7 +21,6 @@
21
21
  "react-native-svg": "15.12.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@ohos/hvigor-ohos-plugin": "^6.20.0",
25
24
  "@react-native-community/cli": "15.0.1",
26
25
  "@tsconfig/react-native": "^3.0.0",
27
26
  "@types/jest": "^29.5.1",
@@ -29,7 +28,7 @@
29
28
  "@types/react": "^19.1.7",
30
29
  "@types/react-native": "^0.71.6",
31
30
  "react-native-builder-bob": "^0.20.4",
32
- "typescript": "^5.2.2"
31
+ "typescript": "^5.8.3"
33
32
  },
34
33
  "harmony": {
35
34
  "alias": "react-native-svg",
package/tsconfig.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "@tsconfig/react-native/tsconfig.json",
4
4
  ],
5
5
  "compilerOptions": {
6
- "noEmit": false,
6
+ "noEmit": false
7
7
  },
8
8
  "exclude": [
9
9
  "lib",