草庐IT

windows - 如何为不同的语言自动选择最合适的字体?

coder 2024-06-09 原文

我需要为不同的语言找到最合适的字体。因此,我可以在不使用 GDI 文本输出 API(例如 TextOut)的情况下绘制不同语言的文本。

实际上,API TextOut 可以做到这一点。

    HFONT hFont = NULL;
    LOGFONT lg = {0};
    lg.lfHeight = 14;
    lg.lfWeight = FW_NORMAL;
    wcscpy_s(lg.lfFaceName, LF_FACESIZE ,L"Arial");
    hFont = CreateFontIndirect(&lg);
    SelectObject(hdc,hFont);
    TextOut(hdc, 0, 50, L"abc我爱", 5);

因为Arial字体不支持中文,所以TextOut应该是画不出中文“我爱”的。但它会为它选择合适的字体,普通字体而不是某种艺术字体。

我如何模拟 TextOut 的功能,或者是否有任何其他方法可以在 Windows 下找出最适合一种语言的字体?

最佳答案

是的,这是可以做到的。这是 chrome 项目中经过轻微修改的代码片段,

// Callback to |EnumEnhMetaFile()| to intercept font creation.
int CALLBACK MetaFileEnumProc(HDC hdc,
                              HANDLETABLE* table,
                              CONST ENHMETARECORD* record,
                              int table_entries,
                              LPARAM log_font)
{
    if (record->iType == EMR_EXTCREATEFONTINDIRECTW) {
        const EMREXTCREATEFONTINDIRECTW* create_font_record =
            reinterpret_cast<const EMREXTCREATEFONTINDIRECTW*>(record);
        *reinterpret_cast<LOGFONT*>(log_font) = create_font_record->elfw.elfLogFont;
    }
    return 1;
}

// Finds a fallback font to use to render the specified |text| with respect to
// an initial |font|. Returns the resulting font via out param |result|. Returns
// |true| if a fallback font was found.
// Adapted from WebKit's |FontCache::GetFontDataForCharacters()|.
// TODO(asvitkine): This should be moved to font_fallback_win.cc.
bool ChooseFallbackFont(HDC hdc,
                        HFONT font,
                        const wchar_t* text,
                        int text_length,
                        LOGFONT* result)
{
    // Use a meta file to intercept the fallback font chosen by Uniscribe.
    HDC meta_file_dc = CreateEnhMetaFile(hdc, NULL, NULL, NULL);
    if (!meta_file_dc)
        return false;

    if (font)
        SelectObject(meta_file_dc, font);

    SCRIPT_STRING_ANALYSIS script_analysis;
    HRESULT hresult =
        ScriptStringAnalyse(meta_file_dc, text, text_length, 0, -1,
        SSA_METAFILE | SSA_FALLBACK | SSA_GLYPHS | SSA_LINK,
        0, NULL, NULL, NULL, NULL, NULL, &script_analysis);

    if (SUCCEEDED(hresult)) {
        hresult = ScriptStringOut(script_analysis, 0, 0, 0, NULL, 0, 0, FALSE);
        ScriptStringFree(&script_analysis);
    }

    bool found_fallback = false;
    HENHMETAFILE meta_file = CloseEnhMetaFile(meta_file_dc);
    if (SUCCEEDED(hresult)) {
        LOGFONT log_font;
        log_font.lfFaceName[0] = 0;
        EnumEnhMetaFile(0, meta_file, MetaFileEnumProc, &log_font, NULL);
        if (log_font.lfFaceName[0]) {
            *result = log_font;
            found_fallback = true;
        }
    }
    DeleteEnhMetaFile(meta_file);

    return found_fallback;
}

示例代码:

                std::wstring arabicStr = L"ششش";
        hdc = BeginPaint(hWnd, &ps);
        LOGFONT logFont = {0};
        wcscpy_s(logFont.lfFaceName, L"微软雅黑");
        HFONT hFont = CreateFontIndirect(&logFont);
        ChooseFallbackFont(hdc, hFont, arabicStr.c_str(), arabicStr.length(), &logFont);
        ATLTRACE(logFont.lfFaceName);
        HFONT hFontNew = CreateFontIndirect(&logFont);
        HFONT hFontOld = (HFONT)SelectObject(hdc, hFontNew);
        wchar_t glyphs[10] = {0}; 
        GCP_RESULTS gcpRet = {0};
        gcpRet.lStructSize = sizeof(gcpRet);
        gcpRet.lpGlyphs = glyphs;
        gcpRet.nGlyphs = 10;
        ATLASSERT(GetCharacterPlacement(hdc, arabicStr.c_str(), arabicStr.length(), GCP_MAXEXTENT, &gcpRet, 
            GCP_DISPLAYZWG | GCP_GLYPHSHAPE | GCP_REORDER ));
        RECT rcClient;
        GetClientRect(hWnd, &rcClient);
        ExtTextOut(hdc, 200, 200, ETO_GLYPH_INDEX | ETO_RTLREADING, &rcClient, gcpRet.lpGlyphs, gcpRet.nGlyphs, NULL);
        SelectObject(hdc, hFontOld);
        DeleteObject(hFontNew);
        DeleteObject(hFont);
        EndPaint(hWnd, &ps);

微软雅黑是一种不支持阿拉伯语的字体,所以我们需要一个阿拉伯语的后备字体。在我的框中,GDI 自动为阿拉伯语选择 Microsoft Sans Serif

关于windows - 如何为不同的语言自动选择最合适的字体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16828868/

有关windows - 如何为不同的语言自动选择最合适的字体?的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby - 如何为 emacs 安装 ruby​​-mode - 2

    我刚刚为fedora安装了emacs。我想用emacs编写ruby。为ruby​​提供代码提示、代码完成类型功能所需的工具、扩展是什么? 最佳答案 ruby-mode已经包含在Emacs23之后的版本中。不过,它也可以通过ELPA获得。您可能感兴趣的其他一些事情是集成RVM、feature-mode(Cucumber)、rspec-mode、ruby-electric、inf-ruby、rinari(用于Rails)等。这是我当前用于Ruby开发的Emacs配置:https://github.com/citizen428/emacs

  5. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  6. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  7. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  8. ruby - Rails 3 的 RGB 颜色选择器 - 2

    状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基

  9. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  10. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

随机推荐