学习CEGUI亟待解决问题一:文本控件的格式问题

为了配合工作,所以定点突破文本控件的格式管理问题。

Day1:

      了解了文本控件根据格式绘制的具体流程。如下:

      1在TextDemo的formatChangedHandler(const CEGUI::EventArgs& e)里面调用PropertySet::setProperty(const String& name,const String& value)函数来传入属性字符串以及属性值字符串来设置对应的属性。

      2利用泛型机制调用到FalagardStaticText类的setVerticalFormatting函数。

      3在setVerticalFormattinghan里面调用configureScrollbars来设置我们需要绘制的文本区域的大小。以及是否存在滚动条等等。

      4在configureScrollbars里面调用getDocumentSize来计算文本区域的大小。其中,使用getFormattedLineCount来计算行数,再乘以每行的高度,即为全部区域的高度。而使用getFormattedTextExtent得到绘制区域的最大宽度。

      5特别提一下getFormattedLineCount计算字符串的行数的问题。这个接口实现考虑到了多行文本的问题,可以借鉴下。

      6之后是getFormattedTextExtent得到最宽的那一行的宽度。使用getWrappedTextExtent来得到最宽的那行字符串的宽度。

      上面是设置文本的一些属性,以下为绘制:

      1.在FalagardStaticText::render()里面调用renderScrolledText();

      2.这里要说的是绘制字符串是在RenderCache::render这个函数里面完成的。该函数将d_cachedImages里面所有的图片均draw出来,将d_cachedTexts里面所有的字符串也绘制出来。

      3.在这里搞不明白的就是size_t Font::drawText(const String& text, const Rect& draw_area, float z, const Rect& clip_rect, TextFormatting fmt, const ColourRect& colours, float x_scale, float y_scale)这个函数为什么在绘制的时候又将文本的分行规律计算了一遍,个人觉得类似这样的计算完全只需要计算一遍就可以了哩。

      4.在size_t Font::drawWrappedText(const String& text, const Rect& draw_area, float z, const Rect& clip_rect, TextFormatting fmt, const ColourRect& colours, float x_scale, float y_scale)里面计算了分行的规律。然后按照该规律来依次画字。

      明天要将计算换行的机制搞清楚,为什么在设置文本的时候需要计算一次,而在绘制的时候又计算了一次。

Day2:

      今天MS感冒了,上个班累死。还好上班的时候研究了下。发现其不但所有的Image对象、所有的字符串对象,都是被RenderCache类里面的d_cachedImages以及d_cachedTexts容器管理起来的。甚至连所有的绘制区域都是使用一个d_quadlist的容器来管理的。这样的管理对象的思想是不是值得借鉴下哩,又该如何借鉴哩,考虑下。不过上屏的时候仍然是d_quadlist里面所有的成员都要上屏的,也就是说局部刷新MS没有在CEGUI里面实现。也不能说绝对,比方说鼠标在界面上移动的时候,MS仅仅只绘制了鼠标图片。在DirectX9Renderer类的addQuad函数里有renderQuadDirect直接绘制,而不是insert到d_quadlist里面。明天继续研究。

 Day3:

      今天主要分析下Font类里面的drawWrappedText函数。MS在帮助文档里面暂时还找不到该函数的解释。字面上来理解应该是绘制换行文本的意思。我拿了一个右对齐的单行文本做例子传进去。

/*************************************************************************
    draws wrapped text
*************************************************************************/
size_t Font::drawWrappedText(const String& text, const Rect& draw_area, float z, const Rect& clip_rect, TextFormatting fmt, const ColourRect& colours, float x_scale, float y_scale)
{
    size_t line_count = 0;
    Rect dest_area(draw_area);//绘制文字的区域
    float wrap_width = draw_area.getWidth();//区域的宽度,用来比较是否需要新开一行

    String  whitespace = TextUtils::DefaultWhitespace;
    String thisLine, thisWord;
    size_t currpos = 0;

    // get first word.
    currpos += getNextWord(text, currpos, thisLine);//得到第一个单词的字母个数(到第一个分隔符默认为空格处为止)

    // while there are words left in the string...
    while (String::npos != text.find_first_not_of(whitespace, currpos))//只要存在字符
    {
        // get next word of the string...
        currpos += getNextWord(text, currpos, thisWord);//再得到下一个单词的长度

        // if the new word would make the string too long
        if ((getTextExtent(thisLine, x_scale) + getTextExtent(thisWord, x_scale)) > wrap_width)//如果当前行的单词加上下一个单词的宽度要大于绘制区域宽度的话
        {
            // output what we had until this new word
            line_count += drawText(thisLine, dest_area, z, clip_rect, fmt, colours, x_scale, y_scale);//仅仅绘制当前行已经存在的单词

            // remove whitespace from next word - it will form start of next line
            thisWord = thisWord.substr(thisWord.find_first_not_of(whitespace));//之后的字符串之前的空格符

            // reset for a new line.
            thisLine.clear();//当前行清空

            // update y co-ordinate for next line
            dest_area.d_top += getLineSpacing(y_scale);//绘制区域下移一行字的高度
        }

        // add the next word to the line
        thisLine += thisWord;//如果没有达到换行的要求的话则继续往后加
    }

    // Last line is left aligned
    TextFormatting last_fmt = (fmt == Justified ? LeftAligned : fmt);
    // output last bit of string
    line_count += drawText(thisLine, dest_area, z, clip_rect, last_fmt, colours, x_scale, y_scale);//绘制最后一行

    return line_count;
}

      

原文地址:https://www.cnblogs.com/bobox/p/1434336.html