2V0-g: port the .fnt font pipeline over a FreeType GDI emulation

CGraphicText, CGraphicFontTexture and CGraphicDib are the 40250 bodies
verbatim; CGraphicTextInstance is verbatim except that its D3D draws become
UI render commands (one image quad per glyph, Bar for cursor/underline).

- platform/Win32Gdi.cpp: the GDI subset those files call, over vendored
  FreeType 2.13.3, following GDI's LOGFONT cell height, win metrics and gasp
  rules; system font lookup with substitute and CJK fallback faces
- Win32Crt: MultiByteToWideChar / WideCharToMultiByte (UTF-8 and 1252 by
  hand, other code pages through iconv)
- CGraphicImageTexture memory textures: glyph pages reach Godot as
  "mem:<id>@<revision>"; Metin2PythonHost.memory_texture + Canvas cache
- Util.cpp code page / font face table, SetDefaultCodePage at boot,
  DefaultFont_* block, fnt resource type, GetMaxTextureWidth/Height
- TextTag, StringCodec, Arabic, Vietnamese copied from 40250
- tests: port.text (Tahoma 12 metrics, alignment, CP949), port.app_loop
  and python_host_test.gd now check glyph quads instead of text commands

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-23 14:17:25 +09:00
co-authored by Claude Opus 5.5
parent 141206cb69
commit afe63bfa61
272 changed files with 137097 additions and 316 deletions
@@ -1,10 +1,13 @@
#pragma once
// Shim for <windows.h> on non-Windows targets: the Win32 scalar types and CRT spellings
// 40250 sources use (common/Win32Types.h, common/Win32Crt.h), plus the headers the real one pulls
// in that 40250 relies on transitively (winnt.h brings <string.h> for memcpy/memset).
// in that 40250 relies on transitively (winnt.h brings <string.h> for memcpy/memset, and <wchar.h>
// for wcslen).
#include <string.h>
#include <wchar.h>
#include "../../Win32Types.h"
#include "../../Win32Crt.h"
#include "wingdi.h"
// winuser.h / wingdi.h constants named in 40250 declarations (default arguments).
#define WS_OVERLAPPED 0x00000000L
@@ -0,0 +1,64 @@
#pragma once
// Shim for the <wingdi.h> subset the 40250 font path uses (EterLib/GrpDIB, GrpFontTexture, Util).
// The calls are implemented by the platform layer over FreeType (platform/Win32Gdi.cpp): one DIB
// per memory DC, glyphs rendered the way GDI lays out a TrueType face for a LOGFONT cell height.
#include "../../Win32Types.h"
typedef DWORD COLORREF;
typedef void* HGDIOBJ;
#define RGB(r, g, b) ((COLORREF)(((BYTE)(r) | ((WORD)((BYTE)(g)) << 8)) | (((DWORD)(BYTE)(b)) << 16)))
typedef struct _ABCFLOAT
{
FLOAT abcfA;
FLOAT abcfB;
FLOAT abcfC;
} ABCFLOAT, *LPABCFLOAT;
#define TRANSPARENT 1
#define OPAQUE 2
#define FW_NORMAL 400
#define FW_BOLD 700
#define OUT_DEFAULT_PRECIS 0
#define CLIP_DEFAULT_PRECIS 0
#define DEFAULT_QUALITY 0
#define NONANTIALIASED_QUALITY 3
#define ANTIALIASED_QUALITY 4
#define DEFAULT_PITCH 0
#define ANSI_CHARSET 0
#define DEFAULT_CHARSET 1
#define SHIFTJIS_CHARSET 128
#define HANGUL_CHARSET 129
#define GB2312_CHARSET 134
#define CHINESEBIG5_CHARSET 136
#define GREEK_CHARSET 161
#define TURKISH_CHARSET 162
#define VIETNAMESE_CHARSET 163
#define HEBREW_CHARSET 177
#define ARABIC_CHARSET 178
#define BALTIC_CHARSET 186
#define RUSSIAN_CHARSET 204
#define THAI_CHARSET 222
#define EASTEUROPE_CHARSET 238
#define BI_RGB 0L
#define DIB_RGB_COLORS 0
HDC CreateCompatibleDC(HDC hdc);
BOOL DeleteDC(HDC hdc);
HBITMAP CreateDIBSection(HDC hdc, const BITMAPINFO* pbmi, UINT usage, void** ppvBits, HANDLE hSection, DWORD offset);
int SetDIBitsToDevice(HDC hdc, int xDest, int yDest, DWORD w, DWORD h, int xSrc, int ySrc, UINT StartScan,
UINT cLines, const void* lpvBits, const BITMAPINFO* lpbmi, UINT ColorUse);
HFONT CreateFontIndirect(const LOGFONT* lplf);
BOOL DeleteObject(HGDIOBJ ho);
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ h);
COLORREF SetTextColor(HDC hdc, COLORREF color);
COLORREF SetBkColor(HDC hdc, COLORREF color);
int SetBkMode(HDC hdc, int mode);
BOOL GetTextExtentPoint32W(HDC hdc, LPCWSTR lpString, int c, LPSIZE psizl);
BOOL GetCharABCWidthsFloatW(HDC hdc, UINT iFirst, UINT iLast, LPABCFLOAT lpABC);
BOOL TextOutW(HDC hdc, int x, int y, LPCWSTR lpString, int c);
BOOL TextOutA(HDC hdc, int x, int y, LPCSTR lpString, int c);
#define TextOut TextOutA