From 1e77c4560338383e1be89d5aaa8ed6616b24808b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Fri, 16 May 2003 18:55:27 +0000 Subject: [PATCH] Convert from Unicode to ANSI in GetTextMetricsA() svn path=/trunk/; revision=4692 --- reactos/lib/gdi32/objects/text.c | 136 ++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) diff --git a/reactos/lib/gdi32/objects/text.c b/reactos/lib/gdi32/objects/text.c index 3a9977e3e06..4ad23c93dca 100644 --- a/reactos/lib/gdi32/objects/text.c +++ b/reactos/lib/gdi32/objects/text.c @@ -51,6 +51,40 @@ SetTextColor(HDC hDC, COLORREF 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 STDCALL GetTextMetricsA( @@ -58,7 +92,107 @@ GetTextMetricsA( 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