From 8f9a18cfff136354fc4fd411b887e5c8bc6ef45c Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Fri, 22 Sep 2006 21:45:35 +0000 Subject: [PATCH] Merge 24219-24222, and 24209 from trunk. svn path=/branches/ros-branch-0_3_1/; revision=24230 --- reactos/dll/win32/gdi32/objects/font.c | 120 ++++++++++++++++++++++--- reactos/dll/win32/ws2_32/misc/ns.c | 21 +++-- 2 files changed, 126 insertions(+), 15 deletions(-) diff --git a/reactos/dll/win32/gdi32/objects/font.c b/reactos/dll/win32/gdi32/objects/font.c index 96e59690635..d4e5139bd27 100644 --- a/reactos/dll/win32/gdi32/objects/font.c +++ b/reactos/dll/win32/gdi32/objects/font.c @@ -42,6 +42,31 @@ static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA ) ptmA->tmCharSet = ptmW->tmCharSet; } +/*********************************************************************** + * FONT_mbtowc + * + * Returns a Unicode translation of str. If count is -1 then str is + * assumed to be '\0' terminated, otherwise it contains the number of + * bytes to convert. If plenW is non-NULL, on return it will point to + * the number of WCHARs that have been written. The caller should free + * the returned LPWSTR from the process heap itself. + */ +static LPWSTR FONT_mbtowc(LPCSTR str, INT count, INT *plenW) +{ + UINT cp = CP_ACP; + INT lenW; + LPWSTR strW; + + if(count == -1) count = strlen(str); + lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0); + strW = HeapAlloc(GetProcessHeap(), 0, lenW*sizeof(WCHAR)); + MultiByteToWideChar(cp, 0, str, count, strW, lenW); + DPRINT1("mapped %s -> %s \n", str, strW); + if(plenW) *plenW = lenW; + return strW; +} + + static BOOL FASTCALL MetricsCharConvert(WCHAR w, UCHAR *b) { @@ -358,6 +383,8 @@ GetCharWidthA ( LPINT lpBuffer ) { +DPRINT1("GCWA iFirstChar %x\n",iFirstChar); + return GetCharWidth32A ( hdc, iFirstChar, iLastChar, lpBuffer ); } @@ -374,8 +401,35 @@ GetCharWidth32A( LPINT lpBuffer ) { - /* FIXME should be NtGdiGetCharWidthW */ - return NtGdiGetCharWidth32(hdc, iFirstChar, iLastChar, lpBuffer); + INT i, wlen, count = (INT)(iLastChar - iFirstChar + 1); + LPSTR str; + LPWSTR wstr; + BOOL ret = TRUE; +DPRINT1("GCW32A iFirstChar %x\n",iFirstChar); + + if(count <= 0) return FALSE; + + str = HeapAlloc(GetProcessHeap(), 0, count); + for(i = 0; i < count; i++) + str[i] = (BYTE)(iFirstChar + i); + + wstr = FONT_mbtowc(str, count, &wlen); + + for(i = 0; i < wlen; i++) + { + /* FIXME should be NtGdiGetCharWidthW */ + if(!NtGdiGetCharWidth32 (hdc, wstr[i], wstr[i], lpBuffer)) + { + ret = FALSE; + break; + } + lpBuffer++; + } + + HeapFree(GetProcessHeap(), 0, str); + HeapFree(GetProcessHeap(), 0, wstr); + + return ret; } @@ -391,6 +445,8 @@ GetCharWidthW ( LPINT lpBuffer ) { +DPRINT1("GCW32w uFirstChar %x\n",iFirstChar); + /* FIXME should be NtGdiGetCharWidthW */ return NtGdiGetCharWidth32 ( hdc, iFirstChar, iLastChar, lpBuffer ); } @@ -496,7 +552,7 @@ GetCharWidthFloatA( /* - * @unimplemented + * @implemented */ BOOL APIENTRY @@ -507,8 +563,9 @@ GetCharABCWidthsA( LPABC lpabc ) { - /* FIXME what to do with uFirstChar and uLastChar ??? */ - return NtGdiGetCharABCWidths ( hdc, uFirstChar, uLastChar, lpabc ); +DPRINT1("GCABCWA uFirstChar %x\n",uFirstChar); + +return NtGdiGetCharABCWidths(hdc, uFirstChar, uLastChar, lpabc); } @@ -524,6 +581,8 @@ GetCharABCWidthsFloatA( LPABCFLOAT lpABCF ) { +DPRINT1("GCABCWFA iFirstChar %x\n",iFirstChar); + /* FIXME what to do with iFirstChar and iLastChar ??? */ return NtGdiGetCharABCWidthsFloat ( hdc, iFirstChar, iLastChar, lpABCF ); } @@ -544,9 +603,32 @@ GetGlyphOutlineA( CONST MAT2 *lpmat2 ) { - return NtGdiGetGlyphOutline ( hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); + + LPWSTR p = NULL; + DWORD ret; + UINT c; + DPRINT1("GetGlyphOutlineA uChar %x\n", uChar); + if(!(uFormat & GGO_GLYPH_INDEX)) { + int len; + char mbchs[2]; + if(uChar > 0xff) { /* but, 2 bytes character only */ + len = 2; + mbchs[0] = (uChar & 0xff00) >> 8; + mbchs[1] = (uChar & 0xff); + } else { + len = 1; + mbchs[0] = (uChar & 0xff); + } + p = FONT_mbtowc(mbchs, len, NULL); + c = p[0]; + } else + c = uChar; + ret = NtGdiGetGlyphOutline(hdc, c, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); + HeapFree(GetProcessHeap(), 0, p); + return ret; } + /* * @implemented */ @@ -562,6 +644,7 @@ GetGlyphOutlineW( CONST MAT2 *lpmat2 ) { + DPRINT1("GetGlyphOutlineW uChar %x\n", uChar); return NtGdiGetGlyphOutline ( hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); } @@ -696,6 +779,20 @@ GetOutlineTextMetricsA( if(output != lpOTM) { memcpy(lpOTM, output, cbData); HeapFree(GetProcessHeap(), 0, output); + + /* check if the string offsets really fit into the provided size */ + /* FIXME: should we check string length as well? */ + if ((UINT_PTR)lpOTM->otmpFamilyName >= lpOTM->otmSize) + lpOTM->otmpFamilyName = 0; /* doesn't fit */ + + if ((UINT_PTR)lpOTM->otmpFaceName >= lpOTM->otmSize) + lpOTM->otmpFaceName = 0; /* doesn't fit */ + + if ((UINT_PTR)lpOTM->otmpStyleName >= lpOTM->otmSize) + lpOTM->otmpStyleName = 0; /* doesn't fit */ + + if ((UINT_PTR)lpOTM->otmpFullName >= lpOTM->otmSize) + lpOTM->otmpFullName = 0; /* doesn't fit */ } end: @@ -731,10 +828,13 @@ CreateFontIndirectA( ) { LOGFONTW tlf; - - LogFontA2W(&tlf, lplf); - - return NtGdiCreateFontIndirect(&tlf); + + if (lplf) + { + LogFontA2W(&tlf, lplf); + return NtGdiCreateFontIndirect(&tlf); + } + else return NtGdiCreateFontIndirect(NULL); } diff --git a/reactos/dll/win32/ws2_32/misc/ns.c b/reactos/dll/win32/ws2_32/misc/ns.c index 9e166e65ef8..f6103b09c14 100644 --- a/reactos/dll/win32/ws2_32/misc/ns.c +++ b/reactos/dll/win32/ws2_32/misc/ns.c @@ -488,7 +488,10 @@ void populate_hostent(struct hostent *he, char* name, DNS_A_DATA addr) name, MAX_HOSTNAME_LEN); - he->h_aliases = 0; + if( !he->h_aliases ) { + he->h_aliases = HeapAlloc(GlobalHeap, 0, sizeof(char *)); + he->h_aliases[0] = 0; + } he->h_addrtype = AF_INET; he->h_length = sizeof(IN_ADDR); //sizeof(struct in_addr); @@ -518,12 +521,20 @@ void free_hostent(struct hostent *he) { if(he) { + char *next = 0; HFREE(he->h_name); - char *next = he->h_aliases[0]; - while(next) { HFREE(next); next++; } - next = he->h_addr_list[0]; - while(next) { HFREE(next); next++; } + if(he->h_aliases) + { + next = he->h_aliases[0]; + while(next) { HFREE(next); next++; } + } + if(he->h_addr_list) + { + next = he->h_addr_list[0]; + while(next) { HFREE(next); next++; } + } HFREE(he->h_addr_list); + HFREE(he->h_aliases); HFREE(he); } }