mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-01 19:12:31 +08:00
feat: Support text align on new text rendering pipeline (#3147)
Support text align on new text rendering pipeline.  
This commit is contained in:
@ -67,7 +67,15 @@ void addRenderingStories(Dashbook dashbook) {
|
|||||||
)
|
)
|
||||||
..add(
|
..add(
|
||||||
'Rich Text',
|
'Rich Text',
|
||||||
(_) => GameWidget(game: RichTextExample()),
|
(context) => GameWidget(
|
||||||
|
game: RichTextExample(
|
||||||
|
textAlign: context.listProperty(
|
||||||
|
'Text align',
|
||||||
|
TextAlign.left,
|
||||||
|
TextAlign.values,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
codeLink: baseLink('rendering/rich_text_example.dart'),
|
codeLink: baseLink('rendering/rich_text_example.dart'),
|
||||||
info: RichTextExample.description,
|
info: RichTextExample.description,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -4,6 +4,10 @@ import 'package:flame/text.dart';
|
|||||||
import 'package:flutter/painting.dart';
|
import 'package:flutter/painting.dart';
|
||||||
|
|
||||||
class RichTextExample extends FlameGame {
|
class RichTextExample extends FlameGame {
|
||||||
|
final TextAlign textAlign;
|
||||||
|
|
||||||
|
RichTextExample({this.textAlign = TextAlign.left});
|
||||||
|
|
||||||
static const String description =
|
static const String description =
|
||||||
'A non-interactive example of how to render rich text in Flame.';
|
'A non-interactive example of how to render rich text in Flame.';
|
||||||
|
|
||||||
@ -23,11 +27,15 @@ class RichTextExample extends FlameGame {
|
|||||||
),
|
),
|
||||||
paragraph: BlockStyle(
|
paragraph: BlockStyle(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||||
|
textAlign: textAlign,
|
||||||
background: BackgroundStyle(
|
background: BackgroundStyle(
|
||||||
color: const Color(0xFF004D40),
|
color: const Color(0xFF004D40),
|
||||||
borderColor: const Color(0xFFAAAAAA),
|
borderColor: const Color(0xFFAAAAAA),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
header1: BlockStyle(
|
||||||
|
textAlign: textAlign,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
final document = DocumentRoot([
|
final document = DocumentRoot([
|
||||||
HeaderNode.simple('1984', level: 1),
|
HeaderNode.simple('1984', level: 1),
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flame/src/text/common/utils.dart';
|
import 'package:flame/src/text/common/utils.dart';
|
||||||
import 'package:flame/src/text/elements/group_element.dart';
|
import 'package:flame/src/text/elements/group_element.dart';
|
||||||
import 'package:flame/text.dart';
|
import 'package:flame/text.dart';
|
||||||
@ -26,6 +28,7 @@ abstract class TextBlockNode extends BlockNode {
|
|||||||
final lines = <InlineTextElement>[];
|
final lines = <InlineTextElement>[];
|
||||||
final horizontalOffset = style.padding.left;
|
final horizontalOffset = style.padding.left;
|
||||||
var verticalOffset = style.padding.top;
|
var verticalOffset = style.padding.top;
|
||||||
|
final textAlign = style.textAlign ?? TextAlign.left;
|
||||||
while (!layoutBuilder.isDone) {
|
while (!layoutBuilder.isDone) {
|
||||||
final element = layoutBuilder.layOutNextLine(contentWidth);
|
final element = layoutBuilder.layOutNextLine(contentWidth);
|
||||||
if (element == null) {
|
if (element == null) {
|
||||||
@ -36,7 +39,12 @@ abstract class TextBlockNode extends BlockNode {
|
|||||||
} else {
|
} else {
|
||||||
final metrics = element.metrics;
|
final metrics = element.metrics;
|
||||||
assert(metrics.left == 0 && metrics.baseline == 0);
|
assert(metrics.left == 0 && metrics.baseline == 0);
|
||||||
element.translate(horizontalOffset, verticalOffset + metrics.ascent);
|
|
||||||
|
final dx = horizontalOffset +
|
||||||
|
(contentWidth - metrics.width) * _relativeOffset(textAlign);
|
||||||
|
final dy = verticalOffset + metrics.ascent;
|
||||||
|
element.translate(dx, dy);
|
||||||
|
|
||||||
lines.add(element);
|
lines.add(element);
|
||||||
verticalOffset += metrics.height;
|
verticalOffset += metrics.height;
|
||||||
}
|
}
|
||||||
@ -50,4 +58,19 @@ abstract class TextBlockNode extends BlockNode {
|
|||||||
children: elements,
|
children: elements,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double _relativeOffset(TextAlign textAlign) {
|
||||||
|
return switch (textAlign) {
|
||||||
|
TextAlign.left => 0,
|
||||||
|
TextAlign.right => 1,
|
||||||
|
TextAlign.center => 0.5,
|
||||||
|
// NOTE: we do not support non-LRT text directions
|
||||||
|
TextAlign.start => 0,
|
||||||
|
TextAlign.end => 1,
|
||||||
|
// Not supported by Flame
|
||||||
|
TextAlign.justify => throw UnimplementedError(
|
||||||
|
'The text rendering pipeline cannot justify text.',
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ class BlockStyle extends FlameTextStyle {
|
|||||||
EdgeInsets? padding,
|
EdgeInsets? padding,
|
||||||
this.background,
|
this.background,
|
||||||
this.text,
|
this.text,
|
||||||
|
this.textAlign,
|
||||||
}) : _margin = margin,
|
}) : _margin = margin,
|
||||||
_padding = padding;
|
_padding = padding;
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ class BlockStyle extends FlameTextStyle {
|
|||||||
final EdgeInsets? _padding;
|
final EdgeInsets? _padding;
|
||||||
final BackgroundStyle? background;
|
final BackgroundStyle? background;
|
||||||
final InlineTextStyle? text;
|
final InlineTextStyle? text;
|
||||||
|
final TextAlign? textAlign;
|
||||||
|
|
||||||
EdgeInsets get margin => _margin ?? EdgeInsets.zero;
|
EdgeInsets get margin => _margin ?? EdgeInsets.zero;
|
||||||
EdgeInsets get padding => _padding ?? EdgeInsets.zero;
|
EdgeInsets get padding => _padding ?? EdgeInsets.zero;
|
||||||
@ -29,6 +31,7 @@ class BlockStyle extends FlameTextStyle {
|
|||||||
padding: other._padding ?? _padding,
|
padding: other._padding ?? _padding,
|
||||||
background: other.background ?? background,
|
background: other.background ?? background,
|
||||||
text: FlameTextStyle.merge(text, other.text),
|
text: FlameTextStyle.merge(text, other.text),
|
||||||
|
textAlign: other.textAlign ?? textAlign,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user