字号

  • 在定义一种控件时,各个[text]使用的字号必须一样,即一个控件在各种状态下只能使用一种字号。既然必须一样,字号不是写在[text]内,而是[resolution]层的text_font_size。
  • 定义控件用default字号的话,可以省略text_font_size字段,否则必须写。
  • 一个控件想让内中字号可被外面使用修改,必须把字号定义成default。

 

使用文字的场合分为两种,一是gui脚本,二是C/C++代码,为关联它们,引入个叫参考字号的变量。

 

一、在Rose Studio如何修改字号

对可以在使用时修改字号的控件,它会提供修改界面。

label类控件是可修改字号的,在“控件设置”的“高级”页选择要使用的字号,smaller、small、default、large或larger。

 

二、两套字号、参考字号

#define font_cfg_reference_size	1000
#define font_max_cfg_size_diff	2
#define font_min_cfg_size	(font_cfg_reference_size - 2)

int font_hdpi_size_from_cfg_size(int cfg_size) {
	int diff = cfg_size - font_cfg_reference_size;
	VALIDATE(posix_abs(diff) <= font_max_cfg_size_diff, null_str);
	if (diff == 0) { return font::SIZE_DEFAULT;	}
	if (diff == -1) { return font::SIZE_SMALL;}
	if (diff == -2) { return font::SIZE_SMALLER; }
	if (diff == 1) { return font::SIZE_LARGE; }
	return font::SIZE_LARGER;
}

font_hdpi_size_from_cfg_size()用于从脚本字号转换为C代码字号,变量font_cfg_reference_size就是参考字号,值须要是个正常字号不可能出现的数字:1000。SIZE_DEFAULT等5个大写变量是C代码在用的常见字号,是融合hdpi_scale后绝对值。这函数实现了下面映射。

易记名C代码中字号变量(手机/PC)脚本中字号值/偏差/宏
smallerSIZE_SMALLER(12/9)998/-2/GUI_FONT_SIZE__SMALLER 
smallSIZE_SMALL(14/11)999/-1/GUI_FONT_SIZE__SMALL
defaultSIZE_DEFAULT(16/13)1000/0/GUI_FONT_SIZE__DEFAULT
largeSIZE_LARGE(18/15)1001/1/GUI_FONT_SIZE__LARGE
largerSIZE_LARGER(20/17)1002/2/GUI_FONT_SIZE__LARGER

举个例子,gui脚本填的是1000(宏:GUI_FONT_SIZE__DEFAULT)时,手机最后算出的是16,PC算出的是13。填998时,手机算出的是12,PC是9。这套机制要实现两个目标。

  1. 统一gui脚本和C/C++代码这两个系统的字号。
  2. 做到了gui脚本中字号和设备无关,它只要记住1000是默认,至于1000对应哪个字号则由C/C++代码根据具体设备去设定。

gui脚本只能使用5种字号,须要其它字号时,像天气app要用个极大号数字显示当前气温,可用track,或blits风格的image等控件,然后C/C++代码自画。

gui脚本中不要让出现绝对字号,像13、14,绝对字号出来的界面太依赖特定设备。

 

三、gui脚本中字号

gui脚本会在两个地方出现字号,它们是使用控件块和定义控件的[resolution]层。

两个地方之一:使用控件块

[label]
	definition="default"
	id="client_ip"
	state=1
	text_font_size=998
[/label]

使用控件块中有个text_font_size字段,用于定义字号。

两个地方之二:[resolution]层text_font_size

[label_definition]
	[resolution]
		text_font_size = 1000
		[state_enabled]
			...
		[/state_enabled]
	[/resolution]
[/label_definition]

因为规则:各个[text]使用的字号必须一样,即一个控件在各种状态下只能使用一种字号。那字号没必要写在[text]块内,写在了[resolution]层text_font_size。

 

2.1 计算最后出来的字号

<librose>/gui/auxiliary/canvas.cpp
------
void ttext::draw(texture& canvas, const int canvas_width, const int canvas_height, 
    const game_logic::map_formula_callable& variables, std::vector<SDL_Rect>& drawn_rects)
{
	int font_size = default_font_size_;
	VALIDATE(font_size, _("Text has a font size of 0."));
        ......
}

ttext::draw用来最后渲染文字,可看到字号来自default_font_size_,它来自tcontrol::get_text_font_size()。

<librose>/gui/widgets/control.cpp
------
int tcontrol::get_text_font_size() const
{
	int ret = 0;
	if (config_->text_font_size != 0 && config_->text_font_size != font_cfg_reference_size) {
		ret = config_->text_font_size;
	}
	if (ret == 0 && text_font_size_ != 0) {
		ret = text_font_size_;
	}
	if (ret == 0) {
		ret = font::SIZE_DEFAULT;
	}

config_->text_font_size值等于[resolution]层text_font_size,非default字号时,具有第一优先级。

text_font_size_是使用控件块的中的text_font_size,具有第二优先级。

以上两项都不是的话,那就是使用default字号。

	if (ret >= font_min_cfg_size) {
		ret = font_hdpi_size_from_cfg_size(ret);
	}
	return ret;
}

小结如何计算最后出来的字号

  1. 控件定义使用了非default参考字号,具有第一优先级。
  2. 如果使用控件块中出现了非零text_font_size,具有第二优先级。
  3. 以上两项都不是的话,使用default字号。

从上面也能知道,一个控件想让内中字号可被外面使用修改的话,必须把字号定义成default。

为什么有些控件中的字号不想被修改,即不定义成default。让看vertical_node风格的按钮。它上面是图像,下面是文本,界面要突出的是图像,于是要没意外,底下文本会要求使用small。为避免开发者每遇到这种按钮都要修改字号,在verical_node配置中就写了让文本是small。

对定义时使用非default字号的控件,一旦改了它,极可能就不美观了。

全部评论: 0

    写评论: