Esta es la primera vez, en años de experiencia usando la API de Windows, que enfrento una situación en la que necesito hacer algo, que no puedo, con la interfaz de programación actual de Windows.¿Por qué MS no tiene en su win32api una función que devuelve el nombre del archivo de fuente, dado el identificador de fuente?
Según mi investigación, el tipo de letra "Arial Negro" utiliza el archivo arialblk.ttf
y no hay archivo para el tipo de letra "Arial Negro cursiva", ni por el tipo de letra "Arial Negro Bold", al menos en mi ordenador con a Windows 7.
Inserté debajo de un programa para mostrar unas líneas de texto usando la fuente "Arial Black", por sí mismo, y luego con cursiva y negrita. Para mi sorpresa, el texto en cursiva se hizo con normalidad y el texto en negrita se representó como si fuera solo "Arial Black". Entonces me di cuenta de que pasa lo mismo con MS Word. También inserté una captura de pantalla de un documento de Word, superpuesto por el resultado del código a continuación. Que esta pasando aqui ? ¿Tengo que adivinar qué archivo de fuente se usa en cada caso? Aparentemente, la API de Windows no me da la posibilidad de una respuesta. ¿Por qué el misterio?
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, UINT, LONG);
int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int nCmdShow)
{
WNDCLASSEX wndclassx;
wndclassx.cbSize = sizeof(WNDCLASSEX);
wndclassx.style = CS_HREDRAW | CS_VREDRAW;
wndclassx.lpfnWndProc = WndProc;
wndclassx.cbClsExtra = 0;
wndclassx.cbWndExtra = 0;
wndclassx.hInstance = hInstance;
wndclassx.hIcon = nullptr;
wndclassx.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclassx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wndclassx.lpszMenuName = nullptr;
wndclassx.lpszClassName = L"WndProc";
wndclassx.hIconSm = nullptr;
if(!RegisterClassEx(&wndclassx)) return 0;
HWND hWnd = CreateWindow(L"WndProc", nullptr, WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
ShowWindow(hWnd, SW_MAXIMIZE);
UpdateWindow(hWnd);
MSG msg;
while(GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
static HFONT s_hArialBlack, s_hArialBlackItalic, s_hArialBlackBold;
switch (message)
{
case WM_CREATE:
{
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = -MulDiv(20, 96, 72);
wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Arial Black");
if(!(s_hArialBlack = CreateFontIndirect(&lf))) return -1;
lf.lfItalic = true;
if(!(s_hArialBlackItalic = CreateFontIndirect(&lf)))
{
DeleteObject(s_hArialBlack);
return -1;
}
lf.lfWeight = FW_BOLD;
lf.lfItalic = false;
if(!(s_hArialBlackBold = CreateFontIndirect(&lf)))
{
DeleteObject(s_hArialBlackItalic);
DeleteObject(s_hArialBlack);
return -1;
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
HFONT hFont = (HFONT)SelectObject(ps.hdc, s_hArialBlack);
TextOut(ps.hdc, 20, 10, L"Font Arial Black", 16);
SelectObject(ps.hdc, s_hArialBlackItalic);
TextOut(ps.hdc, 20, 50, L"Font Arial Black Italic", 23);
SelectObject(ps.hdc, s_hArialBlackBold);
TextOut(ps.hdc, 20, 90, L"Font Arial Black Bold", 21);
SelectObject(ps.hdc, hFont);
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
DeleteObject(s_hArialBlackBold);
DeleteObject(s_hArialBlackItalic);
DeleteObject(s_hArialBlack);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
Esta es la captura de pantalla que me he referido anteriormente:
¿Hay alguna razón por la que necesita saber el nombre del archivo de fuente, cuando sabe qué tipo de letra desea? – crashmstr
No me gustaría entrar en este detalle. Pero Windows tiene que hacer eso. Por ejemplo, cuando un programa llama a GetFontData(), donde el primer argumento de la función es un controlador de DC, Windows debe determinar el nombre del archivo de fuente, según la fuente seleccionada en el DC. ¿Por qué tal función no existe en la API de Windows? – WaldB
Es posible que el renderizador de fuentes simplemente esté sesgando y engrosando la fuente, en lugar de usar una definición TTF. Soy especialmente sospechoso de la versión en cursiva, pero no soy un tipo de letra, así que no puedo decirlo con certeza. –