mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-10-31 08:56:01 +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
	 Luan Nico
					Luan Nico