From 4be86e70e0245704045fe6a42a993e23fbd26e6d Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 6 Nov 2007 07:12:45 +0000 Subject: [PATCH] - Implement GetGlyphIndicesA/W with update changes ported from Wine. - Tested with Abiword 2.4.1. I think the text file did not load the first time, now it does load. svn path=/trunk/; revision=30212 --- reactos/dll/win32/gdi32/misc/stubsa.c | 18 --- reactos/dll/win32/gdi32/misc/stubsw.c | 18 --- reactos/dll/win32/gdi32/objects/font.c | 46 +++++-- .../subsystems/win32/win32k/objects/text.c | 115 ++++++++++++++++++ reactos/subsystems/win32/win32k/stubs/stubs.c | 17 --- 5 files changed, 151 insertions(+), 63 deletions(-) diff --git a/reactos/dll/win32/gdi32/misc/stubsa.c b/reactos/dll/win32/gdi32/misc/stubsa.c index b43f3407858..60e5e902910 100644 --- a/reactos/dll/win32/gdi32/misc/stubsa.c +++ b/reactos/dll/win32/gdi32/misc/stubsa.c @@ -235,24 +235,6 @@ UpdateICMRegKeyA( return FALSE; } -/* - * @unimplemented - */ -DWORD -STDCALL -GetGlyphIndicesA( - HDC hdc, - LPCSTR lpstr, - int c, - LPWORD pgi, - DWORD fl -) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - /* * @implemented */ diff --git a/reactos/dll/win32/gdi32/misc/stubsw.c b/reactos/dll/win32/gdi32/misc/stubsw.c index 50639f813f6..944330ee344 100644 --- a/reactos/dll/win32/gdi32/misc/stubsw.c +++ b/reactos/dll/win32/gdi32/misc/stubsw.c @@ -297,24 +297,6 @@ bMakePathNameW(LPWSTR lpBuffer,LPCWSTR lpFileName,LPWSTR *lpFilePart,DWORD unkno return 0; } -/* - * @unimplemented - */ -DWORD -STDCALL -GetGlyphIndicesW( - HDC hdc, - LPCWSTR lpstr, - int c, - LPWORD pgi, - DWORD fl -) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - /* * @implemented */ diff --git a/reactos/dll/win32/gdi32/objects/font.c b/reactos/dll/win32/gdi32/objects/font.c index 7a62a4cbe27..dd397df1e6f 100644 --- a/reactos/dll/win32/gdi32/objects/font.c +++ b/reactos/dll/win32/gdi32/objects/font.c @@ -90,15 +90,18 @@ static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA ) /*********************************************************************** * 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. + * Returns a Unicode translation of str using the charset of the + * currently selected font in hdc. 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. If pCP is non-NULL, on + * return it will point to the codepage used in the conversion. The + * caller should free the returned LPWSTR from the process heap + * itself. */ -static LPWSTR FONT_mbtowc(LPCSTR str, INT count, INT *plenW) +static LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP) { - UINT cp = CP_ACP; + UINT cp = CP_ACP; // GdiGetCodePage( hdc ); INT lenW; LPWSTR strW; @@ -108,6 +111,7 @@ static LPWSTR FONT_mbtowc(LPCSTR str, INT count, INT *plenW) MultiByteToWideChar(cp, 0, str, count, strW, lenW); DPRINT1("mapped %s -> %s \n", str, strW); if(plenW) *plenW = lenW; + if(pCP) *pCP = cp; return strW; } @@ -458,7 +462,7 @@ DPRINT1("GCW32A iFirstChar %x\n",iFirstChar); for(i = 0; i < count; i++) str[i] = (BYTE)(iFirstChar + i); - wstr = FONT_mbtowc(str, count, &wlen); + wstr = FONT_mbtowc(NULL, str, count, &wlen, NULL); for(i = 0; i < wlen; i++) { @@ -570,7 +574,7 @@ GetCharacterPlacementW( } /*if(lpResults->lpGlyphs) - GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);*/ + NtGdiGetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);*/ if (GetTextExtentPoint32W(hdc, lpString, uCount, &size)) ret = MAKELONG(size.cx, size.cy); @@ -632,6 +636,28 @@ DPRINT1("GCABCWFA iFirstChar %x\n",iFirstChar); return NtGdiGetCharABCWidthsFloat ( hdc, iFirstChar, iLastChar, lpABCF ); } +/* + * @implemented + */ +DWORD +STDCALL +GetGlyphIndicesA( + HDC hdc, + LPCSTR lpstr, + INT count, + LPWORD pgi, + DWORD flags + ) +{ + DWORD Ret; + WCHAR *lpstrW; + INT countW; + + lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL); + Ret = NtGdiGetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags); + HeapFree(GetProcessHeap(), 0, lpstrW); + return Ret; +} /* * @implemented @@ -664,7 +690,7 @@ GetGlyphOutlineA( len = 1; mbchs[0] = (uChar & 0xff); } - p = FONT_mbtowc(mbchs, len, NULL); + p = FONT_mbtowc(NULL, mbchs, len, NULL, NULL); c = p[0]; } else c = uChar; diff --git a/reactos/subsystems/win32/win32k/objects/text.c b/reactos/subsystems/win32/win32k/objects/text.c index 3ef929f734a..09b96bb152e 100644 --- a/reactos/subsystems/win32/win32k/objects/text.c +++ b/reactos/subsystems/win32/win32k/objects/text.c @@ -2391,6 +2391,121 @@ NtGdiGetFontLanguageInfo(HDC hDC) return 0; } + /* + * @implemented + */ +DWORD +STDCALL +NtGdiGetGlyphIndicesW( + IN HDC hdc, + IN OPTIONAL LPWSTR UnSafepwc, + IN INT cwc, + OUT OPTIONAL LPWORD UnSafepgi, + IN DWORD iMode) +{ + PDC dc; + PTEXTOBJ TextObj; + PFONTGDI FontGDI; + HFONT hFont = 0; + NTSTATUS Status = STATUS_SUCCESS; + OUTLINETEXTMETRICW *potm; + INT i; + FT_Face face; + WCHAR DefChar = 0, tmDefaultChar; + PWSTR Buffer = NULL; + ULONG Size; + + if ((!UnSafepwc) && (!UnSafepgi)) return cwc; + + dc = DC_LockDc(hdc); + if (!dc) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return GDI_ERROR; + } + hFont = dc->Dc_Attr.hlfntNew; + TextObj = TEXTOBJ_LockText(hFont); + DC_UnlockDc(dc); + if (!TextObj) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return GDI_ERROR; + } + + FontGDI = ObjToGDI(TextObj->Font, FONT); + TEXTOBJ_UnlockText(TextObj); + + Buffer = ExAllocatePoolWithTag(PagedPool, cwc*sizeof(WORD), TAG_GDITEXT); + if (!Buffer) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return GDI_ERROR; + } + + Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL); + potm = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT); + if (!potm) + { + Status = ERROR_NOT_ENOUGH_MEMORY; + goto ErrorRet; + } + IntGetOutlineTextMetrics(FontGDI, Size, potm); + tmDefaultChar = potm->otmTextMetrics.tmDefaultChar; // May need this. + ExFreePool(potm); + + if (iMode & GGI_MARK_NONEXISTING_GLYPHS) DefChar = 0x001f; /* Indicate non existence */ + + _SEH_TRY + { + ProbeForRead(UnSafepwc, + sizeof(PWSTR), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) goto ErrorRet; + + IntLockFreeType; + face = FontGDI->face; + + for (i = 0; i < cwc; i++) + { + Buffer[i] = FT_Get_Char_Index(face, UnSafepwc[i]); + if (Buffer[i] == 0) + { + if (!DefChar) DefChar = tmDefaultChar; + Buffer[i] = DefChar; + } + } + + IntUnLockFreeType; + + _SEH_TRY + { + ProbeForWrite(UnSafepgi, + sizeof(WORD), + 1); + RtlCopyMemory(UnSafepgi, + Buffer, + cwc*sizeof(WORD)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + +ErrorRet: + ExFreePool(Buffer); + if (NT_SUCCESS(Status)) return cwc; + SetLastWin32Error(Status); + return GDI_ERROR; +} + static void FTVectorToPOINTFX(FT_Vector *vec, POINTFX *pt) diff --git a/reactos/subsystems/win32/win32k/stubs/stubs.c b/reactos/subsystems/win32/win32k/stubs/stubs.c index b6e71b5ae29..d26628594f1 100644 --- a/reactos/subsystems/win32/win32k/stubs/stubs.c +++ b/reactos/subsystems/win32/win32k/stubs/stubs.c @@ -2658,23 +2658,6 @@ NtGdiGetSpoolMessage( DWORD u1, return 0; } - - /* - * @unimplemented - */ -DWORD -STDCALL -NtGdiGetGlyphIndicesW( - IN HDC hdc, - IN OPTIONAL LPWSTR pwc, - IN INT cwc, - OUT OPTIONAL LPWORD pgi, - IN DWORD iMode) -{ - UNIMPLEMENTED; - return 0; -} - /* * @unimplemented */