Skip to content

Commit 917adb0

Browse files
authored
Merge pull request #3 from ywenjing/ohos-compose-ywjing
Ohos compose ywjing
1 parent f2b2658 commit 917adb0

9 files changed

Lines changed: 151 additions & 37 deletions

File tree

compose/ui/ui-arkui/src/ohosArm64Main/cpp/compose/src/main/cpp/compose/canvas/oh_native_canvas_export.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ void androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawRect(OHNativeCanvas
5151
LOGI("androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawRect");
5252
}
5353

54+
void androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawRoundRect(OHNativeCanvasProxy_Handle proxy, float left, float top, float right, float bottom, float radiusX, float radiusY, OHComposeNativePaint_Handle paint) {
55+
LOGI("androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawRoundRect: start");
56+
auto nativePaint = reinterpret_cast<androidx::compose::ui::arkui::utils::OHComposeNativePaint *>(paint);
57+
auto canvasProxy = reinterpret_cast<androidx::compose::ui::arkui::utils::OHNativeCanvasProxy *>(proxy);
58+
canvasProxy->drawRoundRect(left, top, right, bottom, radiusX, radiusY, nativePaint);
59+
}
60+
5461
void androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawLine(OHNativeCanvasProxy_Handle proxy, float x1, float y1, float x2, float y2, OHComposeNativePaint_Handle paint) {
5562
auto nativePaint = reinterpret_cast<androidx::compose::ui::arkui::utils::OHComposeNativePaint *>(paint);
5663
auto canvasProxy = reinterpret_cast<androidx::compose::ui::arkui::utils::OHNativeCanvasProxy *>(proxy);

compose/ui/ui-arkui/src/ohosArm64Main/cpp/compose/src/main/cpp/compose/canvas/oh_native_canvas_export.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_setParent(OHNativeCanva
5353
void androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawLine(OHNativeCanvasProxy_Handle proxy, float x1, float y1, float x2, float y2, OHComposeNativePaint_Handle paint);
5454
void androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawLayerWithSubproxy(OHNativeCanvasProxy_Handle proxy, OHNativeCanvasProxy_Handle subProxy);
5555
void androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_clipRect(OHNativeCanvasProxy_Handle proxy, float left, float top, float right, float bottom, uint32_t clipOp);
56+
void androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawRoundRect(OHNativeCanvasProxy_Handle proxy, float left, float top, float right, float bottom, float radiusX, float radiusY, OHComposeNativePaint_Handle paint);
5657

5758
// OHComposeNativePaint set paint properties
5859
void androidx_compose_ui_arkui_utils_OHComposeNativePaint_setAlpha(OHComposeNativePaint_Handle paint, float alpha);

compose/ui/ui-arkui/src/ohosArm64Main/cpp/compose/src/main/cpp/compose/canvas/oh_native_canvas_layer_drawer.cpp

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,49 @@ void OHRenderNodeDrawClipRect(float left, float top, float right, float bottom,
130130
}
131131
}
132132

133+
void OHRenderNodeDrawRoundRect(float left, float top, float right, float bottom,
134+
float radiusX, float radiusY,
135+
NativeBasicShader* shader,
136+
const RenderNodeSaveState* saveState,
137+
BaseRenderNode* renderNodeForDrawing,
138+
androidx::compose::ui::arkui::utils::OHComposeNativePaint* paint) {
139+
const float strokeWidth = paint->strokeWidth;
140+
int32_t x = (left + strokeWidth);
141+
int32_t y = (top + strokeWidth);
142+
143+
int32_t width = (right - left + strokeWidth);
144+
int32_t height = (bottom - top + strokeWidth);
145+
146+
renderNodeForDrawing
147+
->setTransform(const_cast<float*>(saveState->transform.data()))
148+
->setTranslate(saveState->translateX, saveState->translateY)
149+
->setPosition(x, y)
150+
->setSize(width, height)
151+
->setBorderCornerRadius(radiusX);
152+
if (!shader) {
153+
//TODO:setMask(0)会导致不显示,需要了解具体怎么传值
154+
//renderNodeForDrawing->setMask(0);
155+
if (paint->style == OH_Native_Draw_PaintingStyle::OH_NATIVE_PAINTING_STYLE_STROKE) {
156+
renderNodeForDrawing
157+
->setBorderWidth(strokeWidth)
158+
->setBorderColor(paint->color)
159+
->setBackgroundColor(CLEAR_COLOR);
160+
} else {
161+
renderNodeForDrawing->setBorderWidth(0)
162+
//TODO:需要通过paint获取颜色
163+
->setBackgroundColor(paint->color);
164+
}
165+
} else {
166+
167+
}
168+
}
169+
133170
void OHRenderNodeDrawLine(float x1, float y1, float x2, float y2,
134-
OH_Drawing_ShaderEffect *shader,
171+
NativeBasicShader* shader,
135172
const RenderNodeSaveState *saveState,
136-
BaseRenderNode *renderNodeForDrawing) {
173+
BaseRenderNode *renderNodeForDrawing,
174+
androidx::compose::ui::arkui::utils::OHComposeNativePaint* paint) {
175+
const float strokeWidth = paint->strokeWidth;
137176
int32_t x = std::min(x1, x2);
138177
int32_t y = std::min(y1, y2);
139178
int32_t width = abs(x2 - x1);
@@ -146,15 +185,7 @@ void OHRenderNodeDrawLine(float x1, float y1, float x2, float y2,
146185
->setSize(width, height);
147186

148187
if (!shader) {
149-
renderNodeForDrawing->drawLine(x1, y1, x2, y2);
150-
// [(TMMNativeLineLayer *)layerForDrawing drawWithPointX1:pointX1
151-
// pointY1:pointY1
152-
// pointX2:pointX2
153-
// pointY2:pointY2
154-
// lineWidth:[paint strokeWidth]
155-
// lineColor:[paint colorFromColorValue]
156-
// strokeCap:[paint strokeCap]
157-
// density:density];
188+
renderNodeForDrawing->drawLine(x1, y1, x2, y2, strokeWidth, paint->color, paint->strokeCap);
158189
} else {
159190
// [(TMMNativeLineGradientLayer *)layerForDrawing drawWithPointX1:pointX1
160191
// pointY1:pointY1

compose/ui/ui-arkui/src/ohosArm64Main/cpp/compose/src/main/cpp/compose/canvas/oh_native_canvas_layer_drawer.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,18 @@ void OHRenderNodeDrawRect(float left, float top, float right, float bottom,
1515
BaseRenderNode *renderNodeForDrawing,
1616
androidx::compose::ui::arkui::utils::OHComposeNativePaint *paint);
1717

18+
void OHRenderNodeDrawRoundRect(float left, float top, float right, float bottom,
19+
float roundX, float roundY,
20+
NativeBasicShader* shader,
21+
const RenderNodeSaveState *saveState,
22+
BaseRenderNode* renderNodeForDrawing,
23+
androidx::compose::ui::arkui::utils::OHComposeNativePaint* paint);
24+
1825
void OHRenderNodeDrawLine(float x1, float y1, float x2, float y2,
1926
NativeBasicShader *shader,
2027
const RenderNodeSaveState *saveState,
21-
BaseRenderNode *renderNodeForDrawing);
28+
BaseRenderNode *renderNodeForDrawing,
29+
androidx::compose::ui::arkui::utils::OHComposeNativePaint* paint);
2230

2331
void OHRenderNodeDrawClipRect(float left, float top, float right, float bottom,
2432
const RenderNodeSaveState *saveState,

compose/ui/ui-arkui/src/ohosArm64Main/cpp/compose/src/main/cpp/compose/canvas/oh_native_canvas_proxy.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,22 @@ namespace androidx::compose::ui::arkui::utils {
145145
}
146146
}
147147

148+
void OHNativeCanvasProxy::drawRoundRect(float left, float top, float right, float bottom, float radiusX, float radiusY, OHComposeNativePaint* paint) {
149+
LOGI("OHNativeCanvasProxy::drawRoundRect: start");
150+
OH::NativeBasicShader* shader = paint->shader;
151+
const OH::OHNativeDrawingType drawingType = shader ? OH::OHNativeDrawingType::ShaderRect : OH::OHNativeDrawingType::Rect;
152+
// const uint64_t preHash = hashMerge(TMMNativeDataHashFromPaint(paint), drawingType);
153+
const uint64_t preHash = 0;
154+
const uint64_t drawingContentHash = OH::hashCombineSequential(left, top, right, bottom, static_cast<float>(preHash));
155+
OH::PictureRecorderUpdateInfo updateItem = _pictureRecorder.draw(drawingType, drawingContentHash);
156+
bool isDirty = updateItem.isDirty;
157+
OH::BaseRenderNode *renderNodeForDrawing = nullptr;
158+
if (isDirty) {
159+
renderNodeForDrawing = _pictureRecorder.getOrCreateRenderNodeForDrawing(updateItem.drawingType, updateItem.itemHash);
160+
OH::OHRenderNodeDrawRoundRect(left, top, right, bottom, radiusX, radiusY, shader, &(updateItem.saveState), renderNodeForDrawing, paint);
161+
}
162+
}
163+
148164
void OHNativeCanvasProxy::drawLine(float x1, float y1, float x2, float y2, OHComposeNativePaint* paint) {
149165
LOGI("OHNativeCanvasProxy::drawLine: start");
150166
//TODO:需要paint
@@ -158,8 +174,8 @@ namespace androidx::compose::ui::arkui::utils {
158174
bool isDirty = updateItem.isDirty;
159175
OH::BaseRenderNode *renderNodeForDrawing = nullptr;
160176
if (isDirty) {
161-
renderNodeForDrawing = _pictureRecorder.getOrCreateLayerForDrawing(updateItem.drawingType, updateItem.itemHash);
162-
OH::OHRenderNodeDrawLine(x1, y1, x2, y2, paint->shader, &(updateItem.saveState), renderNodeForDrawing);
177+
renderNodeForDrawing = _pictureRecorder.getOrCreateRenderNodeForDrawing(updateItem.drawingType, updateItem.itemHash);
178+
OH::OHRenderNodeDrawLine(x1, y1, x2, y2, paint->shader, &(updateItem.saveState), renderNodeForDrawing, paint);
163179
}
164180
}
165181

compose/ui/ui-arkui/src/ohosArm64Main/cpp/compose/src/main/cpp/compose/canvas/oh_native_canvas_proxy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class OHNativeCanvasProxy {
2828
void setOpacity(float opacity);
2929

3030
void drawRect(float left, float top, float right, float bottom, OHComposeNativePaint* paint);
31+
void drawRoundRect(float left, float top, float right, float bottom, float radiusX, float radiusY, OHComposeNativePaint* paint);
3132
void drawLine(float x1, float y1, float x2, float y2, OHComposeNativePaint* paint);
3233
void drawLayer(OH::BaseRenderNode* renderNode);
3334
void clipRect(float left, float top, float right, float bottom, OH_Native_Draw_ClipOp clipOp);

compose/ui/ui-arkui/src/ohosArm64Main/cpp/compose/src/main/cpp/compose/render_node/oh_base_render_node.h

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <native_drawing/drawing_pen.h>
1111
#include <native_drawing/drawing_canvas.h>
1212
#include "../xcomponent_log.h"
13+
#include "../canvas/oh_native_enums.h"
1314

1415
namespace OH {
1516
class BaseRenderNode {
@@ -166,39 +167,79 @@ namespace OH {
166167
return this;
167168
}
168169

169-
BaseRenderNode* drawLine(float x1, float y1, float x2, float y2) {
170-
struct UserData {
171-
float x1;
172-
float y1;
173-
float x2;
174-
float y2;
170+
BaseRenderNode *drawLine(float x1, float y1, float x2, float y2, float lineWidth,
171+
uint32_t lineColor, OH_Native_Draw_StrokeCap stokeCap) {
172+
// Property的作用是触发set更新,同步更新modifier的Draw方法。
173+
struct AnimatableUserData {
174+
ArkUI_Vector2AnimatablePropertyHandle p1;
175+
ArkUI_Vector2AnimatablePropertyHandle p2;
176+
ArkUI_FloatAnimatablePropertyHandle width;
177+
ArkUI_ColorAnimatablePropertyHandle color;
178+
OH_Native_Draw_StrokeCap capStyle;
175179
};
176-
UserData* data = new UserData{
177-
.x1 = x1,
178-
.y1 = y1,
179-
.x2 = x2,
180-
.y2 = y2
181-
};
182-
//ArkUI_RenderContentModifierHandle
180+
// 设置基础值。
181+
AnimatableUserData *userData1 = new AnimatableUserData;
182+
auto vectorAnimP1 = OH_ArkUI_RenderNodeUtils_CreateVector2AnimatableProperty(x1, y1);
183+
userData1->p1 = vectorAnimP1;
184+
auto vectorAnimP2 = OH_ArkUI_RenderNodeUtils_CreateVector2AnimatableProperty(x2, y2);
185+
userData1->p2 = vectorAnimP2;
186+
auto widthP = OH_ArkUI_RenderNodeUtils_CreateFloatAnimatableProperty(lineWidth);
187+
userData1->width = widthP;
188+
auto colorP = OH_ArkUI_RenderNodeUtils_CreateColorAnimatableProperty(lineColor);
189+
userData1->color = colorP;
190+
userData1->capStyle = stokeCap;
191+
// 关联组件和多个modifier。
183192
auto modifier = OH_ArkUI_RenderNodeUtils_CreateContentModifier();
184-
185193
maybeThrow(OH_ArkUI_RenderNodeUtils_AttachContentModifier(nodeHandle_, modifier));
186-
maybeThrow(OH_ArkUI_RenderNodeUtils_SetContentModifierOnDraw(modifier, data, [](ArkUI_DrawContext *context, void *userData) {
187-
UserData* data = static_cast<UserData*>(userData);
194+
// 关联modifier和property。
195+
OH_ArkUI_RenderNodeUtils_AttachVector2AnimatableProperty(modifier, vectorAnimP1);
196+
OH_ArkUI_RenderNodeUtils_AttachVector2AnimatableProperty(modifier, vectorAnimP2);
197+
OH_ArkUI_RenderNodeUtils_AttachFloatAnimatableProperty(modifier, widthP);
198+
OH_ArkUI_RenderNodeUtils_AttachColorAnimatableProperty(modifier, colorP);
199+
maybeThrow(OH_ArkUI_RenderNodeUtils_SetContentModifierOnDraw(modifier, userData1,
200+
[](ArkUI_DrawContext *context,void *userData) {
201+
AnimatableUserData *data = static_cast<AnimatableUserData *>(userData);
188202
auto *canvas1 = OH_ArkUI_DrawContext_GetCanvas(context);
189203
OH_Drawing_Canvas *canvas = reinterpret_cast<OH_Drawing_Canvas *>(canvas1);
190204

191205
auto path = OH_Drawing_PathCreate();
192-
OH_Drawing_PathMoveTo(path, data -> x1, data -> y1);
193-
OH_Drawing_PathLineTo(path, data -> x2, data -> y2);
206+
float x1F = 0;
207+
float y1F = 0;
208+
float x2F = 0;
209+
float y2F = 0;
210+
float widthF = 0;
211+
uint32_t lineColor = 0;
212+
OH_Drawing_PenLineCapStyle lineCapStyle = OH_Drawing_PenLineCapStyle::LINE_FLAT_CAP;
213+
214+
ArkUI_Vector2AnimatablePropertyHandle p1 = data->p1;
215+
ArkUI_Vector2AnimatablePropertyHandle p2 = data->p2;
216+
ArkUI_FloatAnimatablePropertyHandle width = data->width;
217+
ArkUI_ColorAnimatablePropertyHandle cp = data->color;
218+
OH_Native_Draw_StrokeCap nativeStokeCap = data->capStyle;
219+
220+
221+
OH_ArkUI_RenderNodeUtils_GetVector2AnimatablePropertyValue(p1, &x1F, &y1F);
222+
OH_ArkUI_RenderNodeUtils_GetVector2AnimatablePropertyValue(p2, &x2F, &y2F);
223+
OH_ArkUI_RenderNodeUtils_GetFloatAnimatablePropertyValue(width, &widthF);
224+
OH_ArkUI_RenderNodeUtils_GetColorAnimatablePropertyValue(cp, &lineColor);
225+
if (nativeStokeCap == OH_Native_Draw_StrokeCap::OH_NATIVE_STROKE_CAP_ROUND) {
226+
lineCapStyle = OH_Drawing_PenLineCapStyle::LINE_ROUND_CAP;
227+
} else if(nativeStokeCap == OH_Native_Draw_StrokeCap::OH_NATIVE_STROKE_CAP_SQUARE) {
228+
lineCapStyle = OH_Drawing_PenLineCapStyle::LINE_SQUARE_CAP;
229+
}
230+
231+
OH_Drawing_PathMoveTo(path, x1F,y1F);
232+
OH_Drawing_PathLineTo(path, x2F,y2F);
194233
OH_Drawing_PathClose(path);
234+
195235
auto pen = OH_Drawing_PenCreate();
196-
//TODO:暂时写死
197-
OH_Drawing_PenSetWidth(pen, 10);
198-
OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
236+
OH_Drawing_PenSetWidth(pen, widthF);
237+
OH_Drawing_PenSetColor(pen, lineColor);
238+
OH_Drawing_PenSetCap(pen, lineCapStyle);
199239
OH_Drawing_CanvasAttachPen(canvas, pen);
200240
OH_Drawing_CanvasDrawPath(canvas, path);
201-
}));
241+
}));
242+
return this;
202243
}
203244

204245
uint32_t getHash() const {

compose/ui/ui/src/ohosArm64Main/kotlin/androidx/compose/ui/platform/nativefoundation/AdaptiveCanvas.ohos.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,8 @@ internal class AdaptiveCanvas(factory: COpaquePointer) : OHOSNativeCanvas {
244244
radiusY: Float,
245245
paint: Paint
246246
) {
247-
// TODO("Not yet implemented")
247+
nativePaint.sync(paint)
248+
nativeCanvasProxy.drawRoundRect(left, top, right, bottom, radiusX, radiusY, nativePaint)
248249
LogPrintUtil.verbose(
249250
"AdaptiveCanvas::drawRoundRect, " +
250251
"left: $left, top: $top, right: $right, bottom: $bottom, " +

compose/ui/ui/src/ohosArm64Main/kotlin/androidx/compose/ui/platform/nativefoundation/OHNativeCanvasProxy.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import androidx.compose.ui.arkui.utils.androidx_compose_ui_arkui_utils_OHNativeC
1212
import androidx.compose.ui.arkui.utils.androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawLayerWithSubproxy
1313
import androidx.compose.ui.arkui.utils.androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_setParent
1414
import androidx.compose.ui.arkui.utils.androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawLine
15+
import androidx.compose.ui.arkui.utils.androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawRoundRect
1516
import androidx.compose.ui.arkui.utils.androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_restore
1617
import androidx.compose.ui.arkui.utils.androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_save
1718
import androidx.compose.ui.arkui.utils.androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_setBounds
@@ -146,6 +147,13 @@ class OHNativeCanvasProxy(private val handle: OHNativeCanvasProxy_Handle?) {
146147
}
147148
}
148149

150+
/**
151+
* 绘制圆角矩形
152+
*/
153+
fun drawRoundRect(left: Float, top: Float, right: Float, bottom: Float, radiusX: Float, radiusY: Float, nativePaint: OHComposeNativePaint) {
154+
handle?.let { androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawRoundRect(it, left, top, right, bottom, radiusX, radiusY, nativePaint.handle) }
155+
}
156+
149157
fun drawLine(x1: Float, y1: Float, x2: Float, y2: Float, nativePaint: OHComposeNativePaint) {
150158
handle?.let {
151159
androidx_compose_ui_arkui_utils_OHNativeCanvasProxy_drawLine(

0 commit comments

Comments
 (0)