- 在定义一种控件时,各个[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) | 脚本中字号值/偏差/宏 |
smaller | SIZE_SMALLER(12/9) | 998/-2/GUI_FONT_SIZE__SMALLER |
small | SIZE_SMALL(14/11) | 999/-1/GUI_FONT_SIZE__SMALL |
default | SIZE_DEFAULT(16/13) | 1000/0/GUI_FONT_SIZE__DEFAULT |
large | SIZE_LARGE(18/15) | 1001/1/GUI_FONT_SIZE__LARGE |
larger | SIZE_LARGER(20/17) | 1002/2/GUI_FONT_SIZE__LARGER |
举个例子,gui脚本填的是1000(宏:GUI_FONT_SIZE__DEFAULT)时,手机最后算出的是16,PC算出的是13。填998时,手机算出的是12,PC是9。这套机制要实现两个目标。
- 统一gui脚本和C/C++代码这两个系统的字号。
- 做到了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; }
小结如何计算最后出来的字号
- 控件定义使用了非default参考字号,具有第一优先级。
- 如果使用控件块中出现了非零text_font_size,具有第二优先级。
- 以上两项都不是的话,使用default字号。
从上面也能知道,一个控件想让内中字号可被外面使用修改的话,必须把字号定义成default。
为什么有些控件中的字号不想被修改,即不定义成default。让看vertical_node风格的按钮。它上面是图像,下面是文本,界面要突出的是图像,于是要没意外,底下文本会要求使用small。为避免开发者每遇到这种按钮都要修改字号,在verical_node配置中就写了让文本是small。
对定义时使用非default字号的控件,一旦改了它,极可能就不美观了。