簡體   English   中英

如何通過WinAPI使用沒有連字的字體?

[英]How to use font without ligatures via WinAPI?

我正在嘗試使用自定義輸出創建簡單的應用程序。 我正在使用CreateFont函數來加載具有特定選項的等寬字體。 結果,已使用諸如fi的連字繪制了文本(DrawText)。

如何禁用它?

我為我的英語不好對不起

創建字體

normal = CreateFont(char_height, 0, 0, 0, FW_NORMAL, 0, 0, 0,
                    RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, 
                    CLIP_DEFAULT_PRECIS, 5, 
                    FIXED_PITCH | FF_DONTCARE, "Menlo");
bold = CreateFont(char_height, 0, 0, 0, FW_BOLD, 0, 0, 0,
                  RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, 
                  CLIP_DEFAULT_PRECIS, 5, 
                  FIXED_PITCH | FF_DONTCARE, "Menlo");

印花

void Console::Print(string text, int color, int weight) {
    RECT r;
    r.top    = padding + temp_y * (char_height + space_y);
    r.bottom = r.top   + char_height;
    r.left   = padding + temp_x * char_width;
    r.right  = padding + length();
    HDC hdc = GetDC(hwnd);
    SetTextColor(hdc, color);
    SetBkColor(hdc, RGB(43, 48, 59));
    SelectObject(GetDC(hwnd), weight == WEIGHT_NORMAL ? normal : bold);
    DrawText(GetDC(hwnd), text.c_str(), text.length(), &r, DT_LEFT);

    temp_x += text.length();
}

當前輸出(請注意單詞“ offline” ):

電流輸出

所需的輸出:

所需的輸出

根本問題似乎在於您的字體已損壞。 我不確定為什么等寬字體(定距)字體會有連字信息。

解決方案1

ExtTextOutWETO_IGNORELANGUAGE一起ETO_IGNORELANGUAGE 您可能會失去其他功能(如雙向,數字替換,復雜腳本的整形),但它似乎確實可以防止字距調整和連接,因此它可能適合您的目的。

::ExtTextOutW(hdc, x, y, ETO_IGNORELANGUAGE, &rc, msg.c_str(), msg.size(), nullptr);

由於沒有Menlo或Meslo,因此我測試了Gabriola字體。 Gabriola是一種可變螺距字體,但具有獨特的連字格式,易於識別,尤其是fi

解決方案2

第二種方法具有相同的缺點,它是通過循環使用TextOut逐個字符地繪制字符串。 這有點棘手,因為您必須擔心Unicode代理對,剪切和更新當前位置。

const auto old_alignment = ::SetTextAlign(hdc, TA_UPDATECP);
const auto old_mode = ::SetBkMode(hdc, TRANSPARENT);
::MoveToEx(hdc, x, y, nullptr);
// Loop simplified for demo.  This doesn't handle Unicode surrogate pairs.
for (auto ch : msg) {
    ::TextOutW(hdc, 0, 0, &ch, 1);
}
::SetBkMode(hdc, old_mode);
::SetTextAlign(hdc, old_alignment);

這產生了與第一種解決方案相同的結果。

非解決方案

請注意,我剛才的主意,用GetCharacterPlacement沒有GCP_LIGATE標志和隨后的ExtTextOut與ETO_GLYPH_INDEX不起作用。 即使沒有GCP_LIGATE標志,從GetCharacterPlacement返回的字形仍包含連字。

// DOES NOT WORK
GCP_RESULTSW results = {sizeof(results)};
WCHAR modified[64] = L"";  // FIXED BUFFER LENGTHS JUST FOR TESTING
results.lpOutString = modified;
int deltas[64] = {0};
results.lpDx = deltas;
WCHAR glyphs[64] = L"";
glyphs[0] = 1;
results.lpGlyphs = glyphs;
results.nGlyphs = ARRAYSIZE(glyphs);

const DWORD flags = GCP_REORDER;  // but not GCP_LIGATE or GCP_USEKERNING
::GetCharacterPlacementW(hdc, msg.c_str(), msg.size(), 0, &results, flags);
::ExtTextOutW(hdc, x, y, ETO_GLYPH_INDEX, &rc, glyphs, results.nGlyphs, deltas);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM