Convert from Unicode to ANSI in GetTextMetricsA()

svn path=/trunk/; revision=4692
This commit is contained in:
Gé van Geldorp 2003-05-16 18:55:27 +00:00
parent 389d19a1e3
commit 1e77c45603

View file

@ -51,6 +51,40 @@ SetTextColor(HDC hDC, COLORREF color)
return(W32kSetTextColor(hDC, color)); return(W32kSetTextColor(hDC, color));
} }
static BOOL
MetricsCharConvert(WCHAR w, BCHAR *b)
{
UNICODE_STRING WString;
WCHAR WBuf[2];
ANSI_STRING AString;
CHAR ABuf[2];
NTSTATUS Status;
if (L'\0' == w)
{
*b = '\0';
}
else
{
WBuf[0] = w;
WBuf[1] = L'\0';
RtlInitUnicodeString(&WString, WBuf);
ABuf[0] = '*';
ABuf[1] = L'\0';
RtlInitAnsiString(&AString, ABuf);
Status = RtlUnicodeStringToAnsiString(&AString, &WString, FALSE);
if (! NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
*b = ABuf[0];
}
return TRUE;
}
BOOL BOOL
STDCALL STDCALL
GetTextMetricsA( GetTextMetricsA(
@ -58,7 +92,107 @@ GetTextMetricsA(
LPTEXTMETRICA tm LPTEXTMETRICA tm
) )
{ {
return W32kGetTextMetrics(hdc, (LPTEXTMETRICW) tm); TEXTMETRICW tmw;
UNICODE_STRING WString;
WCHAR WBuf[256];
ANSI_STRING AString;
CHAR ABuf[256];
UINT Letter;
NTSTATUS Status;
if (! W32kGetTextMetrics(hdc, &tmw))
{
return FALSE;
}
tm->tmHeight = tmw.tmHeight;
tm->tmAscent = tmw.tmAscent;
tm->tmDescent = tmw.tmDescent;
tm->tmInternalLeading = tmw.tmInternalLeading;
tm->tmExternalLeading = tmw.tmExternalLeading;
tm->tmAveCharWidth = tmw.tmAveCharWidth;
tm->tmMaxCharWidth = tmw.tmMaxCharWidth;
tm->tmWeight = tmw.tmWeight;
tm->tmOverhang = tmw.tmOverhang;
tm->tmDigitizedAspectX = tmw.tmDigitizedAspectX;
tm->tmDigitizedAspectY = tmw.tmDigitizedAspectY;
/* The Unicode FirstChar/LastChar need not correspond to the ANSI
FirstChar/LastChar. For example, if the font contains glyphs for
letters A-Z and an accented version of the letter e, the Unicode
FirstChar would be A and the Unicode LastChar would be the accented
e. If you just translate those to ANSI, the range would become
letters A-E instead of A-Z.
We translate all possible ANSI chars to Unicode and find the first
and last translated character which fall into the Unicode FirstChar/
LastChar range and return the corresponding ANSI char. */
/* Setup an Ansi string containing all possible letters (note: skip '\0' at
the beginning since that would be interpreted as end-of-string, handle
'\0' special later */
for (Letter = 1; Letter < 256; Letter++)
{
ABuf[Letter - 1] = (CHAR) Letter;
WBuf[Letter - 1] = L' ';
}
ABuf[255] = '\0';
WBuf[255] = L'\0';
RtlInitAnsiString(&AString, ABuf);
RtlInitUnicodeString(&WString, WBuf);
/* Find the corresponding Unicode characters */
Status = RtlAnsiStringToUnicodeString(&WString, &AString, FALSE);
if (! NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
/* Scan for the first ANSI character which maps to an Unicode character
in the range */
tm->tmFirstChar = '\0';
if (L'\0' != tmw.tmFirstChar)
{
for (Letter = 1; Letter < 256; Letter++)
{
if (tmw.tmFirstChar <= WBuf[Letter - 1] &&
WBuf[Letter - 1] <= tmw.tmLastChar)
{
tm->tmFirstChar = (CHAR) Letter;
break;
}
}
}
/* Scan for the last ANSI character which maps to an Unicode character
in the range */
tm->tmLastChar = '\0';
if (L'\0' != tmw.tmLastChar)
{
for (Letter = 255; 0 < Letter; Letter--)
{
if (tmw.tmFirstChar <= WBuf[Letter - 1] &&
WBuf[Letter - 1] <= tmw.tmLastChar)
{
tm->tmLastChar = (CHAR) Letter;
break;
}
}
}
if (! MetricsCharConvert(tmw.tmDefaultChar, &tm->tmDefaultChar) ||
! MetricsCharConvert(tmw.tmBreakChar, &tm->tmBreakChar))
{
return FALSE;
}
tm->tmItalic = tmw.tmItalic;
tm->tmUnderlined = tmw.tmUnderlined;
tm->tmStruckOut = tmw.tmStruckOut;
tm->tmPitchAndFamily = tmw.tmPitchAndFamily;
tm->tmCharSet = tmw.tmCharSet;
return TRUE;
} }
BOOL BOOL