Add runtime text shadow support

This commit is contained in:
gem
2026-06-09 11:49:24 +08:00
parent 8d2c97269a
commit 5e6a4877f4
12 changed files with 167 additions and 0 deletions

View File

@@ -33,6 +33,10 @@ void main() {
'color': '#112233',
'fontSize': 18,
'textAlign': 'left',
'textShadowColor': '#80000000',
'textShadowOffsetX': 2,
'textShadowOffsetY': 3,
'textShadowBlur': 4,
'radius': 10,
'strokeWidth': 3,
'value': 0.6,
@@ -91,6 +95,10 @@ void main() {
expect(node.color, const Color(0xff112233));
expect(node.fontSize, 18);
expect(node.textAlign, 'left');
expect(node.textShadowColor, const Color(0x80000000));
expect(node.textShadowOffsetX, 2);
expect(node.textShadowOffsetY, 3);
expect(node.textShadowBlur, 4);
expect(node.radius, 10);
expect(node.strokeWidth, 3);
expect(node.value, 0.6);
@@ -135,6 +143,10 @@ void main() {
expect(node.rotation, 0);
expect(node.loop, isTrue);
expect(node.textAlign, 'center');
expect(node.textShadowColor, isNull);
expect(node.textShadowOffsetX, isNull);
expect(node.textShadowOffsetY, isNull);
expect(node.textShadowBlur, isNull);
expect(node.scrollbarVisible, isTrue);
expect(node.paddingLeft, 0);
expect(node.paddingTop, 0);
@@ -175,6 +187,10 @@ void main() {
'scrollX': 90,
'scrollY': 80,
'textAlign': 'right',
'textShadowColor': '#40000000',
'textShadowOffsetX': 1,
'textShadowOffsetY': 2,
'textShadowBlur': 3,
'preset': 'trail',
'count': 12,
});
@@ -202,6 +218,10 @@ void main() {
expect(updated.scrollX, 68);
expect(updated.scrollY, 60);
expect(updated.textAlign, 'right');
expect(updated.textShadowColor, const Color(0x40000000));
expect(updated.textShadowOffsetX, 1);
expect(updated.textShadowOffsetY, 2);
expect(updated.textShadowBlur, 3);
expect(updated.preset, 'trail');
expect(updated.count, 12);
});
@@ -243,6 +263,14 @@ void main() {
}),
throwsFormatException,
);
expect(
() => RuntimeNode.fromMap({
'id': 'a',
'type': 'text',
'textShadowBlur': -1,
}),
throwsFormatException,
);
expect(
() =>
RuntimeNode.fromMap({'id': 'a', 'type': 'listView', 'scrollY': -1}),

View File

@@ -138,6 +138,31 @@ void main() {
);
});
test('applies text shadow style', () {
final component = RuntimeComponent(
node: const RuntimeNode(
id: 'text',
type: RuntimeNodeType.text,
text: 'Shadowed',
alpha: 0.5,
textShadowColor: Color(0x80000000),
textShadowOffsetX: 2,
textShadowOffsetY: 3,
textShadowBlur: 4,
),
resources: GameResourceManager(),
onNodeTap: (_, __) {},
);
final text = component.children.whereType<TextComponent>().single;
final style = (text.textRenderer as TextPaint).style;
final shadow = style.shadows!.single;
expect(shadow.color.a, closeTo(0.25, 0.003));
expect(shadow.offset.dx, 2);
expect(shadow.offset.dy, 3);
expect(shadow.blurRadius, 4);
});
test('multi-line non-button text is top aligned', () {
final component = RuntimeComponent(
node: const RuntimeNode(