minigui:基于GetTabbedTextExtentPoint 计算多行文本显示的矩形尺寸

23 篇文章 3 订阅
23 篇文章 11 订阅

当我们想知道一个字符串在屏幕上显示所占的区域大小,该怎么实现呢?
minigui提供了GetTabbedTextExtentPoint函数用于计算一个字符串在屏幕显示的时候实际的显示区域大小.下面是GetTabbedTextExtentPoint 的函数声明(declared in minigui/gdi.h)

MG_EXPORT int GUIAPI GetTabbedTextExtentPoint (HDC hdc, 
                const char* text, int len, int max_extent, 
                int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size);

其中max_extent用于指定显示的最大宽度,如果字符串太长超过这个长度,那么size.cx就是这个值。GetTabbedTextExtentPoint的返回值是实际显示的字符数。
比如字符串”hello,world”,指定max_extent=40,则函数返回值为5,代表对于40像素的宽度限制,只能显示前5个字符。返回的SIZE值为cx=40,cy=16,代表屏幕显示宽度为40,高度为16(一行的高度)。

    HDC hdc = GetDC(HWND_DESKTOP);
    SIZE ls;
    const char*pstr = "hello,world";
    int offset = GetTabbedTextExtentPoint (hdc, "hello,world", strlen(pstr),
                    40, NULL, NULL, NULL, &ls);
    // offset = 5, ls = {40,16}
    ReleaseDC(hdc);

根据这个函数提供的功能,就可以实现计算多行文本显示区域大小(gnu c编译)。

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
// 计算文本显示需要的屏幕尺寸
// text 显示的文本,不可为NULL
// max_width 显示文本的最大屏幕宽度
// size 返回计算结果
// log_font 指定显示字体,为NULL使用缺省字体
// 计算成功返回值 TRUE,否则返回FALSE
BOOL compute_text_rect(const char*text,int max_width,SIZE *size,PLOGFONT log_font){
    if (!size) {
        return FALSE;
    }
    // 获取屏幕DC
    HDC hdc = GetDC(HWND_DESKTOP);
    PLOGFONT of = NULL;
    // gnu c内置函数用于返回时释放DC
    BOOL do_finally(BOOL ret)
    {
        if( HDC_SCREEN == hdc){
                SelectFont(hdc,of);
            }
        ReleaseDC(hdc); 
        return ret;
    }
    if(log_font){
        // 设置字体
        of =SelectFont(hdc,log_font);
    }
    size->cx=0,size->cy=0;
    // max_width 至少要大于一个字符宽度
    if(!(max_width >= GetMaxFontWidth(hdc))){
        return do_finally(FALSE);
    }
    SIZE ls;
    const char *pstr = text ? text : "";
    int offset = 0;
    while(strlen(pstr += offset)){
        // 计算一行的显示区域输出到ls,offset为实际输出了多少个字符
        offset = GetTabbedTextExtentPoint (hdc, pstr, strlen(pstr),
                max_width, NULL, NULL, NULL, &ls);
        // 显示区域宽度为所有行的最大宽度      
        size->cx = MAX(size->cx,ls.cx);
        // 显示区域高度累加一行的高度
        size->cy += ls.cy;
        // 继续处理剩下的字符
        offset = MIN(offset,strlen(pstr));
    }
    return do_finally(TRUE);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值