【Godot4.2】CanvasItem绘图函数全解析 - 6.TextLine和TextParagraph详解

概述

上一节讲述了CanvasItem内置文本绘制函数,以及TextLineTextParagraph类,绘制单行和多行文本的基础内容。
但是实际上TextLineTextParagraph类比我们想象的要功能丰富和强大的多。本节就来详细介绍一下。

系列目录

TextLine详解

制表位的使用

TextLine提供了tab_align()方法,可以直接将单行文本与指定的制表位对齐。这也就是制表符和制表位原始的含义和用法。

extends Node2D

var font = ThemeDB.fallback_font
var pos := Vector2(200,200)                # 绘制位置 - 表格左上角点

func _draw() -> void:
	# 构造TextLine
	var text = TextLine.new()
	text.add_string("序号\t姓名\t性别\t年龄",font,16)
	text.tab_align([50,60,60,200])
	# 绘制
	text.draw(get_canvas_item(),pos)

在上面的代码中:

  • 我们将字符串"序号\t姓名\t性别\t年龄"添加给TextLine实例
  • 然后为tab_align()传入[50,60,60,200],也就是每列的列宽。

绘制的效果如下:
image.png

图文混排

  • 当你看到TextLine使用add_string()而不是类似text的属性,你就知道问题不简单。
  • 实际上,TextLine确实可以用add_string()以类似数组的append()末尾追加的方式分几次构成一个完整的字符串,但是更重要的是配合add_object()方法,实现图文混排

以下面的代码为例:

extends Node2D

var font = ThemeDB.fallback_font
var pos := Vector2(200,200)                # 绘制位置 - 表格左上角点
const img0 = preload("res://imgs/0.png")
func _draw() -> void:
	# 构造TextLine
	var text = TextLine.new()
	text.add_string("前面的文字",font,16)
	text.add_object(img0,Vector2(36,36),INLINE_ALIGNMENT_BOTTOM,1)
	text.add_string("后面的文字",font,16)
	# 绘制
	text.draw(get_canvas_item(),pos)
	var rect = text.get_object_rect(img0) # 获取占位矩形大小
	rect.position += pos
	draw_texture_rect(img0,rect,false)  # 绘制图片

上面的代码中:

  • 我们首先用add_string()添加了"前面的文字"
  • 然后用add_object()添加了一个(36,36)大小的图片占位
  • 然后又用add_string()添加了"后面的文字"
  • 之后先绘制了文本
  • 然后通过get_object_rect()获取文本占位的矩形,然后利用draw_texture_rect()将图片绘制到了占位的矩形处,从而实现最终的图文混排效果

绘制效果:
image.png

添加和处理多个图片

  • add_string()一样,我们也可以反复多次使用add_object(),来创建一个图文混排的单行文本。
  • 然后通过get_objects()可以获取所有已经添加的占位对象构成的数组,并遍历和绘制。
extends Node2D

var font = ThemeDB.fallback_font
var pos := Vector2(200,200)                # 绘制位置 - 表格左上角点
const img0 = preload("res://imgs/0.png")
const img1 = preload("res://imgs/1.png")
func _draw() -> void:
	# 构造TextLine
	var text = TextLine.new()
	#text.add_string("前面的文字",font,16)
	text.add_object(img0,Vector2(36,36),INLINE_ALIGNMENT_BOTTOM,1)
	text.add_string("后面的文字",font,16)
	text.add_object(img1,Vector2(16,16),INLINE_ALIGNMENT_BOTTOM,1)
	text.add_string("后面的文字",font,16)
	# 绘制
	text.draw(get_canvas_item(),pos)
	
	var objs = text.get_objects()
	for obj in objs:
		var rect = text.get_object_rect(obj) # 获取占位矩形大小
		rect.position += pos
		draw_texture_rect(obj,rect,false)  # 绘制图片

绘制的效果:
image.png

绘制下划线

extends Node2D

var font = ThemeDB.fallback_font
var pos := Vector2(200,200)                # 绘制位置 - 表格左上角点
const img0 = preload("res://imgs/0.png")
func _draw() -> void:
	# 构造TextLine
	var text = TextLine.new()
	#text.add_string("前面的文字",font,16)
	text.add_object(img0,Vector2(36,36),INLINE_ALIGNMENT_BOTTOM,1)
	text.add_string("后面的文字",font,16)
	# 绘制
	text.draw(get_canvas_item(),pos)
	text.draw_outline(get_canvas_item(),pos,1,Color.BLACK)
	
	# 获取和计算下划线位置
	var y1 = text.get_size().y + text.get_line_underline_position()
	var p1 = pos + Vector2(0,y1)
	var p2 = p1 + Vector2(text.get_line_width(),0)
	# 绘制下划线
	draw_line(p1,p2,Color.RED,2)
	
	var rect = text.get_object_rect(img0) # 获取占位矩形大小
	rect.position += pos
	draw_texture_rect(img0,rect,false)  # 绘制图片

image.png

TextParagraph详解

TextParagraph可以看做是TextLine的可自动换行版本。使用方法和思路几乎如出一辙。

图文混排

TextParagraph也可以实现图文混排。

extends Node2D


var font = ThemeDB.fallback_font
var pos := Vector2(200,200)                # 绘制位置 - 表格左上角点
const img0 = preload("res://imgs/0.png")
const img1 = preload("res://imgs/1.png")
const img2 = preload("res://imgs/2.png")

func _draw() -> void:
	# 构造TextLine
	var text = TextParagraph.new()
	text.width = 150
	#text.add_string("前面的文字",font,16)
	text.add_object(img0,Vector2(36,36),INLINE_ALIGNMENT_BOTTOM)
	text.add_string("后面的文字",font,16)
	text.add_object(img1,Vector2(16,16),INLINE_ALIGNMENT_BOTTOM)
	text.add_string("后面的文字",font,16)
	text.add_object(img2,Vector2(48,48),INLINE_ALIGNMENT_BOTTOM)
	text.draw(get_canvas_item(),pos)
	
	for l in text.get_line_count():
		var objs = text.get_line_objects(l)
		for obj in objs:
			var rect = text.get_line_object_rect(l,obj) # 获取占位矩形大小
			rect.position += pos
			draw_texture_rect(obj,rect,false)  # 绘制图片

绘制的效果:
image.png

逐行绘制

TextParagraph的本意是文本段落。而不是单纯多行文本的并列。
段落是一个整体,可以因为宽度限制而自动换行。而此时段落就是由多行组成。
TextParagraph提供了段落层面的操作,也提供了具体行层面的操作。
draw_line是绘制单行。因此我们可以单独挑选段落中的某一行进行显示,也可以逐行绘制,且设定不同的颜色。

extends Node2D


var font = ThemeDB.fallback_font
var pos := Vector2(200,200)                # 绘制位置 - 表格左上角点

func _draw() -> void:
	# 构造TextLine
	var textP = TextParagraph.new()
	#textP.break_flags = 4
	textP.width = 150
	textP.add_string("白日依山尽,黄河入海流。欲穷千里目,更上一层楼。",font,16)
	
	# 逐行绘制
	for l in textP.get_line_count():
		# 计算累计的行高
		var h = 0
		for i in range(l):
			h += textP.get_line_size(i).y
		# 构造随机字色
		var font_color = Color(randf(),randf(),randf(),1)
		# 绘制当前行
		textP.draw_line(get_canvas_item(),pos + Vector2(0,h),l,font_color)

逐行绘制效果:
image.png

绘制表格数据

TextLine一样,TextParagraph也提供了tab_align()方法,可以实现将带有制表符\t的文本渲染为指定列宽的表格形式。

extends Node2D


var font = ThemeDB.fallback_font
var pos := Vector2(200,200)                # 绘制位置 - 表格左上角点

var table = """
姓名	性别	年龄
张三	男	35
李四	男	45
"""

func _draw() -> void:
	# 构造TextParagraph
	var textP = TextParagraph.new()
	textP.add_string(table,font,16)
	textP.tab_align([100,100,100])
	# 绘制
	textP.draw(get_canvas_item(),pos)

上面代码中:

  • table变量存储了多行文本数据,每行字段和数据之间用Tab键分割,在Godot的代码编辑器中它是以制表符对齐显示的

image.png

  • 同样通过tab_align设定三列的宽度

绘制效果:
image.png

总结

  • 本节简单补充了一下TextLineTextParagraph的细节功能,包括图文混排和制表这两个非常重要的功能。
  • 其实add_object()不仅仅可以添加图片站位来实现图文混排,实际上也可以将控件或某些节点混合到文字中国
  • 对于绘制表格,如果想要更细节的控制则不能单单使用tab_align和制表符实现。对于更好的表格绘制,可以见后续文章
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巽星石

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值