专栏首页10km的专栏minigui:基于GetTabbedTextExtentPoint 计算多行文本显示的矩形尺寸

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

版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net/10km/article/details/80984339

当我们想知道一个字符串在屏幕上显示所占的区域大小,该怎么实现呢? 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);
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • cmake/gcc:strip缩减程序体积

    版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net...

    用户1148648
  • cmake:FindLIBCONFIG.cmake查找libconfig的脚本find_package脚本

    版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net...

    用户1148648
  • opencl:提高kernel有效并发约束(Effective concurrency constraint)的一点心得

    版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net...

    用户1148648
  • ArrayList源码完全分析

    导语: 这里分析的ArrayList是使用的JDK1.8里面的类,AndroidSDK里面的ArrayList基本和这个一样。 分析的方式是逐个API进行解析 ...

    MelonTeam
  • ArrayList源码解析,老哥,来一起复习一哈?

    JDK源码解析系列文章,都是基于JDK8分析的,虽然JDK14已经出来,但是JDK8我还不会,我…

    敖丙
  • 算法:Solutions for the Maximum Subsequence Sum Problem

    The maximum subarray problem is the task of finding the contiguous subarray wit...

    s1mba
  • (c#解法)题解洛谷P1004(c++解法)方格取数

    ①先看一下出题日期(毕竟是NOIP的题目,有一定的水准),然后发现是2000年的普及第四题

    w4979的博客
  • [golang][hugo]使用Hugo搭建静态站点

    hugo下载地址:https://github.com/gohugoio/hugo

    landv
  • PHP图片文字合成居中

    PHP使用GD库创建和处理包括GIF,PNG,jpef,wbmp以及xpm在内的多种格式的图像。

    仙士可
  • 使用Apache Hudi构建大规模、事务性数据湖

    一个近期由Hudi PMC & Uber Senior Engineering Manager Nishith Agarwal分享的Talk

    大数据技术架构

扫码关注云+社区

领取腾讯云代金券