SDL中文论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3573|回复: 4
打印 上一主题 下一主题

[gui2] 图文混排

[复制链接]

187

主题

346

帖子

2450

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2450
跳转到指定楼层
楼主
发表于 2017-5-20 21:35:45 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 ancientcc 于 2017-5-20 21:43 编辑





tintegrate::add_text_item中三个显示时执行、可编辑器时不执行
1、“execptions,”和“please”之间那个空行,在换行前即使有空格,只是为显示的话可以不显示。

2、该行剩余空间容得下“detailed”却容不下“ detailed”,则意味着接下一定要换行。既然要换行,只是显示的话,可以去掉之前空格。
first_word_before = " detailed"
first_word_after = "detailed"

3、判断第一个单词是否可以继续写在该行,如果不能写意味着一定要下行开始,这样可以不显示第一个单词的第一个空格。
“ detailed”一定得下行开始,那么第一个空格就可以不显示了。

<img>标签
curr_loc_:在创建单元项建使用的、用于指示当前输入位置的坐标(单位:像素)。下一单元将从该坐标开始。
get_min_x(const int y, const int height)。
get_y_for_floating_img(width, xpos, ypos)

  1. 语法:<img>src="" align=left|middle|right|back|here float=yes|no box=yes|no<img>
复制代码

  • align:指示如何对齐。所有值都会影响水平方向,BACK还会影响垂直方向。
    • HERE:继续从当前放置点(curr_loc_)放置。
    • LEFT:放置在该行左侧,如果不能放置在右侧,像放置位置的x已不是0,那要新起一行。
    • MIDDLE:放置在该行中间。如果不能放置在中间,像放置位置的x已在中央之后,那要新起一行。
    • RIGHT:放置在该行右侧。如果不能放置在右侧,像放置位置之后再接它要超过宽度,那要新起一行。
    • BACK:在上个单元的左上角处放置。它须必存在上个单元。如果不存在上个单元,它将被等于同HERE。
  • box:指示是否要在该图像周周围放置一个矩形框。矩形框的四条边框度都是2,一旦放置,该图像所占区域的宽度将增加4、高度增加4。
  • float:指示是否浮动。不浮动时,单元将以align计算出的为放置坐标;浮动时,


  • 每个单元有两种矩形:绘画矩形、布局矩形。绘画矩形是单元绘画在的矩形;布局矩形是布局时把某一块认为是它的矩形。绘画矩形总是布局矩形的子集。
  • 文本单元后紧跟的“\n”属于该单元,它计入src_size但不计入text;图像单元紧跟的“\n”属于该单元,但不计入src_size。
  • calculate_cursor计算出的光标位置是放在以src_pos为索引的字符之前。
  • 调整一行内各单元高度逻辑。1)分析每一个单元,直到一行结束,计算出这些单元最大高度curr_row_height_;2)根据curr_row_height_和特定单元高度调整该单元要放置y坐标(tintegrate::adjust_last_row)。
回复

使用道具 举报

187

主题

346

帖子

2450

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2450
沙发
 楼主| 发表于 2017-5-21 16:33:59 | 只看该作者

text_box、scrollbar_text_box

本帖最后由 ancientcc 于 2017-5-21 16:38 编辑

did_cursor_moved
只有tscroll_text_box会处理这事件,app不须要。当改变了光标位置时会调用这函数。功能:根据光标到达的位置,有必要的话修正item_position。

(1)当光标落在1)行时,由于顶部有一小部分没在视区,did_cursor_moved会修正item_position,以让那部分出现在视区。(2)(1)当光标落在4)行时,由于底部有一小部分没在视区,did_cursor_moved会修正item_position,以让那部分出现在视区。
回复 支持 反对

使用道具 举报

187

主题

346

帖子

2450

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2450
板凳
 楼主| 发表于 2017-9-15 11:42:26 | 只看该作者
本帖最后由 ancientcc 于 2017-9-16 15:49 编辑

word_wrap_text
处理字符串,在不超过max_width容许宽度下自动插入换行符(\n)生成多行字符串。

语法
  1. std::string word_wrap_text(const std::string& unwrapped_text, int font_sz, int max_width, int max_lines, const int attention_min_chars)
复制代码


参数
unwrapped_text要处理的字符串
font_sz字号
max_width最大容许宽度。必须>0
max_lines如果设置了>0,生成字符串只要有了它指定的行数,就可以结束处理了。split_in_width就设置1,使得只需得到一行,免得一定要处理整串unwrapped_text
attention_min_chars必须>0。它指的是一个“字”中一旦超过这个字符数,那要开始调用line_size进行计算,而不是说一个“字”最多只能有的这么个字符数。详细作用参考注释。


返回值
返回被换行后的字符串。注意,一旦设了max_lines,返回的可能不是和unwrapped_text对应的整串字符。由于换行符“\n”要等到有下一行有效时才追加,所有返回值的最后字符不会是追加的“\n”。举个例子,当max_lines=1时,它返回的只是第一行内容,不会有追加的“\n”。

当内容中有换行符时,这换行符被放在了下一行。举个例子,有这么个输入字符串“where are you form?\nI' am from.”,那第一行是“where are you from?”,不包括那个换行符。

范例
  1. <Example>
复制代码


注释
说下一个概念:“字”。在处理时“字”中字符串将做为一个整体,理论上它们将不能被分割。那什么样的是一个“字”?一)被“空格”、“\n”隔开的。二)前面已有字符串,但又遇到这么个字符,同时满足了1)它可以和前面隔开,而已有字符中最后一个字符允许和后面隔开,2)已有字符中的最后一个字符允许和后面隔开,它可以和前面隔开。

如果严格按“字”的长度去截断,可能会存在由于“字”太长(举个例子,故意输入没有空格的纯英文字符串)超过了参数限定的最大容许宽度(max_width),而满足max_width的优先级要高于“字”。为此采用方法是在形成“字”的过程中,要实时计算该“字”长度,一旦超过max_width,强制截断。这里就有个效率问题,如果“字”每加一个字符都计算一次长度,这会增加计算量,于是增加了叫attention_min_chars参数,只有“字”中字符数超过了attention_min_chars,才会去调用line_size计算字长。也就是说,一旦内容中存在着字符数<=attention_min_chars的“字”,而它又超过max_width,本函数将产生异常。那如何设置attention_min_chars?
  1. int attention_min_chars = width / font_size;
  2. if (attention_min_chars <= 0) {
  3.         attention_min_chars = 10;
  4. } else if (attention_min_chars > 20) {
  5.         attention_min_chars = 20;
  6. }
复制代码

直观看上,font_size约等于字高,假设以全是“正方”字符(“%”)去对待,那width下最多能让出现的就是width/font_size。

相关类、函数
bool no_break_before(const wchart_t ch)。指示ch是否能和前面的字符串分开,true表示不能隔开,false表示可以。那什么样的字符是属于要返回true的字符?像“、”、“。”、“}”。

bool no_break_after(const wchar_t ch)。它类似no_break_before,指示ch是否能和后面的字符串分开,true表示不能隔开,false表示可以。那什么样的字符是属于要返回true的字符?像“<”、“[”、“{”。

bool is_cjk_char(const wchar_t ch)。指示ch是否是中日韩汉字,true表示是中日韩汉字,false则不是。一旦是中日韩汉字,那意味着它可以单独成“字”,即可以和前面断开,也可以和后面断开。
回复 支持 反对

使用道具 举报

187

主题

346

帖子

2450

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2450
地板
 楼主| 发表于 2017-9-29 21:22:26 | 只看该作者
tintegrate在编辑状态时,要强制去掉“\r”,为什么?\r会占一个字符,会使得处理编辑框变得复杂。举个例子,backspace,1)光标在是下一行头处,在删除上一行的\n同时应该删除\r。2)光标在本行尾处,除了要删除前面那字符,还须要删除紧跟的\r。3)在Windows,SDL会保证复制到剪贴板内容都含有\r。

tintegrate内部会把src解析到items_(std::list<titem>),以下是产生items_的逻辑。
一、不断枚举字符,一直到超过了max_width或遇到标签,之前遍历的内容形成一个titem。
二、继续步骤一,直到枚举到完所有字符。
三、最后个字符是“\n”,会出一个额外的titem,该item的src_size是0,pos是src_长度,text是空。

如何区分一个titem是本身有换行符产生的,还是由自动换行产生的?last_row_指示该行已经解析出的titem,当遇到“\n”,此时它是empty意味着该“\n”是该行第一个titem。


get_first_word:返回字符串的第一个单词。对英文:单词间已空隔分开,对中文测是一个汉字。

makeup_pos、pos、text、src_size
text。字符串缓存。不管是max_width导致的换行还是内容有换行符导致的换行,text末尾都不包括那个换行符。为不什么不包括?——省空间。
markup_pos。此个item在源字符串中的偏移。
pos。此个item的text部分在源字符串中的偏移。
src_size。只有编辑状态时才会生成。1)是text类型的titem时,此个item在源字符串中对应的字符数(包括后面的“\n”)。
markup_pos src_size
0,  43
43, 52
95, 47
142, 3
145, 38
183, 52
235, 37
272, 3
275, 2
277, 44
item[n+1].markup_pos = item[n].markup_pos + item[n].src_size
假设M是最后项,那item[M].markup_pos + item[M].src_size = src.size()
对src_size,重点注意它对应的是源字符串,不会增、减源字符串。所以可得出这么些结论,1)因为超过max_width导致的换行,src_size不会计入那个换行符,原因是这换行符原字符串是没有的。2)当内容中有转义符时,src_size要累加转义符“\”,原因是源字符串中有“\”。

quote_require_escape:指示内容区出现“"”时是否要加转义符。
1、quote_require_escape=true的src_中,内容中的“"”前面要加转义符。内容不包括前后两个“"”。
2、操作编辑框,向quote_require_escape=true的titem插入字符时,补转义符的操作是tintegrate::insert_str执行,不是ttext_box层(目的是让ttext_box透明,ttext_box不知道此刻的titem中quote_require_escape是true还是false)。
3、app调用set_label时,字符串参数是需要转义符过的。
4、ttext_box调用insert_str时,要用tintegrate::insert_str的返回值,而不是根据原字符串+插入字符串自动计算。
5、密码框不允许出现markup。因而密码框不存在转义问题。

在titem内部,quote_require_escape和指示该titem是否是text类的markup是等价的。


回复 支持 反对

使用道具 举报

187

主题

346

帖子

2450

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2450
5#
 楼主| 发表于 2017-9-29 21:22:36 | 只看该作者
本帖最后由 ancientcc 于 2017-9-29 21:24 编辑

从src_提取一串连续字符。

语法
  1. std::string tintegrate::substr_from_src(int from, int to) const
复制代码


参数
from基于titem.text角度看的起始偏移
to基于titem.text角度看的结束偏移,不包括to指向的字符。默认是1048576,即提取from开始的所有数据。


返回值
从src_提取出的字符串,[from, to),一定是连续的。

范例
  1. <Example>
复制代码


注释
from、to由两部分组成,titem.pos + titem.text内偏移。正是因为这两部分是分散的,第二个参数用表示偏移位置的to,而不是size。

如果from所在的titem是markup,而且from落在了标识辅助字节上,这时分两种情况,1)落在前半部分,像<format>,那后向跳到本titem的pos处。2)落在后半部分,像</format>,那落在下一个titem的pos处。——总之都是向后跳到最近一个的pos。to在这方面不作修正,当不使用1048576时,调用程序需确保该参数值。

相关类、函数
<Relative class, function>
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|丽谷软件|libsdl.cn

GMT+8, 2024-5-20 00:48 , Processed in 0.062804 second(s), 22 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表