mirror of
https://github.com/flame-engine/flame.git
synced 2025-10-31 00:48:47 +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(
|
||||
'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'),
|
||||
info: RichTextExample.description,
|
||||
);
|
||||
|
||||
@ -4,6 +4,10 @@ import 'package:flame/text.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
|
||||
class RichTextExample extends FlameGame {
|
||||
final TextAlign textAlign;
|
||||
|
||||
RichTextExample({this.textAlign = TextAlign.left});
|
||||
|
||||
static const String description =
|
||||
'A non-interactive example of how to render rich text in Flame.';
|
||||
|
||||
@ -23,11 +27,15 @@ class RichTextExample extends FlameGame {
|
||||
),
|
||||
paragraph: BlockStyle(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||
textAlign: textAlign,
|
||||
background: BackgroundStyle(
|
||||
color: const Color(0xFF004D40),
|
||||
borderColor: const Color(0xFFAAAAAA),
|
||||
),
|
||||
),
|
||||
header1: BlockStyle(
|
||||
textAlign: textAlign,
|
||||
),
|
||||
);
|
||||
final document = DocumentRoot([
|
||||
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/elements/group_element.dart';
|
||||
import 'package:flame/text.dart';
|
||||
@ -26,6 +28,7 @@ abstract class TextBlockNode extends BlockNode {
|
||||
final lines = <InlineTextElement>[];
|
||||
final horizontalOffset = style.padding.left;
|
||||
var verticalOffset = style.padding.top;
|
||||
final textAlign = style.textAlign ?? TextAlign.left;
|
||||
while (!layoutBuilder.isDone) {
|
||||
final element = layoutBuilder.layOutNextLine(contentWidth);
|
||||
if (element == null) {
|
||||
@ -36,7 +39,12 @@ abstract class TextBlockNode extends BlockNode {
|
||||
} else {
|
||||
final metrics = element.metrics;
|
||||
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);
|
||||
verticalOffset += metrics.height;
|
||||
}
|
||||
@ -50,4 +58,19 @@ abstract class TextBlockNode extends BlockNode {
|
||||
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,
|
||||
this.background,
|
||||
this.text,
|
||||
this.textAlign,
|
||||
}) : _margin = margin,
|
||||
_padding = padding;
|
||||
|
||||
@ -18,6 +19,7 @@ class BlockStyle extends FlameTextStyle {
|
||||
final EdgeInsets? _padding;
|
||||
final BackgroundStyle? background;
|
||||
final InlineTextStyle? text;
|
||||
final TextAlign? textAlign;
|
||||
|
||||
EdgeInsets get margin => _margin ?? EdgeInsets.zero;
|
||||
EdgeInsets get padding => _padding ?? EdgeInsets.zero;
|
||||
@ -29,6 +31,7 @@ class BlockStyle extends FlameTextStyle {
|
||||
padding: other._padding ?? _padding,
|
||||
background: other.background ?? background,
|
||||
text: FlameTextStyle.merge(text, other.text),
|
||||
textAlign: other.textAlign ?? textAlign,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user