Tengo un drama con los fonts en directX. En realidad, mi problema radica en calcular el ancho en DirectX 8.1 de cada uno de los caracteres. En 9.0 anda perfecto. El código es el siguiente:
#ifndef USING_DIRECTX81
TEXTMETRIC textmetric;
_pDefDXFont->GetTextMetrics(&textmetric);
// si textmetric dice que es truetype tengo que hacer otra cosa
HDC device = _pDefDXFont->GetDC();
GetCharWidth32(device, 32, 255, _characterWidth);
#else
static HDC hdc;
hdc = CreateCompatibleDC(NULL);
SelectObject(hdc, _pDefDXFont);
GetCharWidth32(hdc, 32, 255, _characterWidth);
DeleteDC(hdc);
#endif
El tema es que me devuelve valores completamente diferentes en el arreglo de enteros _characterWidth en el caso de usar DX 9.0 contra DX 8.1.
El código completo es el siguiente:
bool Widget::SetFont(ZAK_FONT_TYPES ft, int size)
{
static wstring strFt;
switch (ft)
{
case FT_ARIAL:
strFt = L"Arial";
break;
case FT_COURIER:
strFt = L"Courier New";
break;
case FT_TIMES:
strFt = L"Times New Roman";
break;
case FT_VERDANA:
strFt = L"Verdana";
break;
case FT_TAHOMA:
strFt = L"Tahoma";
break;
default:
Log.Trace("%s: %d", Message::getMessage(Message::CantCreateFont).c_str(), strFt.c_str());
return false;
break;
}
_pDefDXFontType = ft;
#ifdef USING_DIRECTX81
LOGFONTW fontDesc = { size, // Alto (px)
0, // Ancho (px)
0,
0,
FW_DONTCARE,
FALSE,
FALSE,
FALSE,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH,
L""};
wcscpy(fontDesc.lfFaceName, strFt.c_str());
#else
D3DXFONT_DESC fontDesc = { size, // Alto (px)
0, // Ancho (px)
FW_DONTCARE, // Grosor (número de 0 a 1000)
1, // MipLevels (normalmente 1 o D3DX_DEFAULT)
FALSE, // Itálica
DEFAULT_CHARSET, // Set de caracteres
OUT_DEFAULT_PRECIS, // Precisión
DEFAULT_QUALITY, // Calidad (influye en velocidad de render)
DEFAULT_PITCH, // Pitch
L""}; // Nombre de la fuente
wcscpy(fontDesc.FaceName, strFt.c_str());
#endif
// Si ya existe una fuente creada en _pDefDXFont, la libero
if (_pDefDXFont != NULL)
_pDefDXFont->Release();
HRESULT hr = D3DXCreateFontIndirect(g_renderer.GetDevice(), &fontDesc, &_pDefDXFont);
if (FAILED(hr))
{
// No se pudo crear la fuente
Log.Trace("%s: %s", Message::getMessage(Message::CantCreateFont).c_str(), strFt.c_str());
return false;
}
if (_characterWidth)
delete [] _characterWidth;
_characterWidth = new INT[255];
#ifndef USING_DIRECTX81
TEXTMETRIC textmetric;
_pDefDXFont->GetTextMetrics(&textmetric);
// si textmetric dice que es truetype tengo que hacer otra cosa
HDC device = _pDefDXFont->GetDC();
GetCharWidth32(device, 32, 255, _characterWidth);
#else
static HDC hdc;
hdc = CreateCompatibleDC(NULL);
SelectObject(hdc, _pDefDXFont);
GetCharWidth32(hdc, 32, 255, _characterWidth);
DeleteDC(hdc);
#endif
if (FAILED(hr))
{
// No se pudo crear la fuente
Log.Trace("%s: %s", Message::getMessage(Message::CantCreateFont).c_str(), strFt.c_str());
return false;
}
_size = size;
return true;
}
Si alguien tuvo el drama, si me puede comentar qué es lo que debo hacer para DX 8.1, estaría genial.
Gracias!!!!
Aunque ya te respondi en los foros de ADVA pero por si alguien mas tuviese la misma duda :)
Se pueden calcular las dimensiones del texto a dibujar con la propia funcion de dibujo de texto de DirectX. Yo lo hago asi en dx_lib32:
Dim TextSize As RECT '// Almacena la region que ocupara el texto a dibujar.
'// Calculamos el espacio que ocupara el texto en pantalla:
Call D3DX.DrawText(D3DFont.D3D_Font, 0, Text, TextSize, DT_CALCRECT)
El truco esta en usar la constante DT_CALCRECT en la llamada de dibujo ya que te calcula la region que ocupara el texto a dibujar. Mas preciso y mas comodo. Un detalle importate a tener en cuenta es que con esta constante no se dibuja el texto, solo calcula.
Salu2...