C++ 计算用于渲染文本的线偏移(自定义编辑控件)

C++ 计算用于渲染文本的线偏移(自定义编辑控件),c++,winapi,text-rendering,C++,Winapi,Text Rendering,我按照第二个答案创建了自定义编辑控件,但问题是,我将每个字母单独渲染,因此可以使用不同的文本颜色。对于每个渲染调用,我必须计算文本偏移量才能从屏幕顶部开始渲染(0,0),所以我不必渲染整个文本。若我有一个200kB的文件,并滚动到文件的底部(并在那个里进行一些编辑),那个么会有太多的延迟,因为我必须遍历所有的文本并找到所有的“\n”(表示行号)作为偏移量 渲染功能: int Screen_X = 0, Screen_Y = 0; size_t Text_YOffset = Calc_TextYP

我按照第二个答案创建了自定义编辑控件,但问题是,我将每个字母单独渲染,因此可以使用不同的文本颜色。对于每个渲染调用,我必须计算文本偏移量才能从屏幕顶部开始渲染(0,0),所以我不必渲染整个文本。若我有一个200kB的文件,并滚动到文件的底部(并在那个里进行一些编辑),那个么会有太多的延迟,因为我必须遍历所有的文本并找到所有的“\n”(表示行号)作为偏移量

渲染功能:

int Screen_X = 0, Screen_Y = 0;
size_t Text_YOffset = Calc_TextYPos(m_Screen_YOff);  //Screen pos(0,0) to text
size_t Text_Size = m_Text.size();
COLORREF Text_ColorOld = 0;
for (size_t pos = Text_YOffset; pos < Text_Size; pos++) {
    if (m_Text.at(pos) == L'\n') {
        Screen_Y++; Screen_X = 0;
        continue;
    }

    if (Screen_X < m_Screen_XOff) { Screen_X++; continue; }
    if (m_Screen_MaxX < Screen_X) continue;
    if (m_Screen_MaxY < Screen_Y) break;

    if (m_Text_Color.at(pos) != Text_ColorOld) {
        Text_ColorOld = m_Text_Color.at(pos);
        if (SetTextColor(hDC, Text_ColorOld) == CLR_INVALID) {
            MB_ERR("'SetTextColor' Failed!");
            PostQuitMessage(-1);
       }
   }

    CHECK_ERR(TextOut(hDC, (Screen_X - m_Screen_XOff) * m_Char_Width, Screen_Y * m_Char_Height, &m_Text.at(pos), 1), ERR_MSG_TEXT_OUT);
    Screen_X++;
}
我是不是走错了路,应该使用“不同的算法”来呈现不同颜色的文本(),或者如果不是,我该如何优化代码?我喜欢这种方法(用于插入符号),因为选择文本非常简单


我也遇到过,但它没有回答我的问题。它只提到渲染函数(
ExtTextOut
),但我不需要它。我需要一种快速的方法来计算大字符串上的行偏移量。

可以使用TextOut来渲染文本。这种缓慢并不是来自TextOut。它来自于你计算坐标的算法。特别是,
Calc\u TextYPos
函数读取整个字符串,查找
\n
字符和200KB字符串,这将花费很长时间。您需要使自己的代码更高效。TextOut不是性能瓶颈所在。@RaymondChen我知道,但我不知道
Calc\u TextYPos
应该是什么样子(你应该重新表述这个问题,因为它的编写方式要求更快的渲染速度,但你的问题是你花了太多时间思考而没有渲染。设计高性能编辑控件是一个复杂的主题,可能对本网站来说太广泛了。你可以从预先计算线偏移量开始,以便更快地查找。
size_t Edit_Control::Calc_TextYPos(int Screen_y) {
    if (Screen_y == 0) return 0;
    size_t Offset = 0;

    size_t Text_Size = m_Text.size();
    for (size_t pos = 0; pos < Text_Size; pos++) {
        if (m_Text.at(pos) == L'\n' && Screen_y != 0) {
            Screen_y--;
            Offset = pos + 1;
        }
        if (Screen_y == 0) return Offset;
    }

    return Offset;
}