From 2903ca1bbb531a57c2aaf942e31e7c9832806b55 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Wed, 3 Apr 2002 20:41:14 +0000 Subject: [PATCH] Implement GetGlyphIndices. Tweak GetCharacterPlacement to use it. --- dlls/gdi/freetype.c | 22 ++++++++ dlls/gdi/gdi32.spec | 2 + include/font.h | 2 + include/wingdi.h | 6 +++ objects/font.c | 129 ++++++++++++++++++++++++++++++-------------- 5 files changed, 120 insertions(+), 41 deletions(-) diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c index 4bcf6f5641f..2b6f2d3c43c 100644 --- a/dlls/gdi/freetype.c +++ b/dlls/gdi/freetype.c @@ -1008,6 +1008,22 @@ static FT_UInt get_glyph_index(GdiFont font, UINT glyph) return pFT_Get_Char_Index(font->ft_face, glyph); } +/************************************************************* + * WineEngGetGlyphIndices + * + * FIXME: add support for GGI_MARK_NONEXISTING_GLYPHS + */ +DWORD WineEngGetGlyphIndices(GdiFont font, LPCWSTR lpstr, INT count, + LPWORD pgi, DWORD flags) +{ + INT i; + + for(i = 0; i < count; i++) + pgi[i] = get_glyph_index(font, lpstr[i]); + + return count; +} + /************************************************************* * WineEngGetGlyphOutline * @@ -1603,6 +1619,12 @@ DWORD WineEngEnumFonts(LPLOGFONTW plf, DEVICEFONTENUMPROC proc, LPARAM lparam) return 1; } +DWORD WineEngGetGlyphIndices(GdiFont font, LPCWSTR lpstr, INT count, + LPWORD pgi, DWORD flags) +{ + return GDI_ERROR; +} + DWORD WineEngGetGlyphOutline(GdiFont font, UINT glyph, UINT format, LPGLYPHMETRICS lpgm, DWORD buflen, LPVOID buf, const MAT2* lpmat) diff --git a/dlls/gdi/gdi32.spec b/dlls/gdi/gdi32.spec index 3f15020929e..256db66e3d2 100644 --- a/dlls/gdi/gdi32.spec +++ b/dlls/gdi/gdi32.spec @@ -223,6 +223,8 @@ debug_channels (bitblt bitmap clipping dc ddraw driver enhmetafile font gdi @ stdcall GetFontLanguageInfo(long) GetFontLanguageInfo @ stub GetFontResourceInfo @ stub GetFontResourceInfoW +@ stdcall GetGlyphIndicesA(long ptr long ptr long) GetGlyphIndicesA +@ stdcall GetGlyphIndicesW(long ptr long ptr long) GetGlyphIndicesW @ stub GetGlyphOutline @ stdcall GetGlyphOutlineA(long long long ptr long ptr ptr) GetGlyphOutlineA @ stdcall GetGlyphOutlineW(long long long ptr long ptr ptr) GetGlyphOutlineW diff --git a/include/font.h b/include/font.h index 93a754976fc..d6e6495eb63 100644 --- a/include/font.h +++ b/include/font.h @@ -92,6 +92,8 @@ extern BOOL WineEngDestroyFontInstance(HFONT handle); extern DWORD WineEngEnumFonts(LPLOGFONTW, DEVICEFONTENUMPROC, LPARAM); extern BOOL WineEngGetCharWidth(GdiFont, UINT, UINT, LPINT); extern DWORD WineEngGetFontData(GdiFont, DWORD, DWORD, LPVOID, DWORD); +extern DWORD WineEngGetGlyphIndices(GdiFont font, LPCWSTR lpstr, INT count, + LPWORD pgi, DWORD flags); extern DWORD WineEngGetGlyphOutline(GdiFont, UINT glyph, UINT format, LPGLYPHMETRICS, DWORD buflen, LPVOID buf, const MAT2*); diff --git a/include/wingdi.h b/include/wingdi.h index be65455d854..47eb2a98c8a 100644 --- a/include/wingdi.h +++ b/include/wingdi.h @@ -1219,6 +1219,9 @@ typedef VOID (CALLBACK *LINEDDAPROC)(INT,INT,LPARAM); #define ASPECT_FILTERING 0x0001 + /* for GetGlyphIndices() */ +#define GGI_MARK_NONEXISTING_GLYPHS 0x0001 + typedef struct { UINT gmBlackBoxX; @@ -3214,6 +3217,9 @@ UINT WINAPI GetEnhMetaFileHeader(HENHMETAFILE,UINT,LPENHMETAHEADER); UINT WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE,UINT,LPPALETTEENTRY); DWORD WINAPI GetFontData(HDC,DWORD,DWORD,LPVOID,DWORD); DWORD WINAPI GetFontLanguageInfo(HDC); +DWORD WINAPI GetGlyphIndicesA(HDC,LPCSTR,INT,LPWORD,DWORD); +DWORD WINAPI GetGlyphIndicesW(HDC,LPCWSTR,INT,LPWORD,DWORD); +#define GetGlyphIndices WINELIB_NAME_AW(GetGlyphIndices) DWORD WINAPI GetGlyphOutlineA(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*); DWORD WINAPI GetGlyphOutlineW(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*); #define GetGlyphOutline WINELIB_NAME_AW(GetGlyphOutline) diff --git a/objects/font.c b/objects/font.c index 924d74af5c0..f61f416594a 100644 --- a/objects/font.c +++ b/objects/font.c @@ -1776,7 +1776,7 @@ DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat, DC *dc = DC_GetDCPtr(hdc); DWORD ret; - TRACE("(%04x, '%c', %04x, %p, %ld, %p, %p)\n", + TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n", hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 ); if(!dc) return GDI_ERROR; @@ -1999,6 +1999,47 @@ DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset, return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData); } +/************************************************************************* + * GetGlyphIndicesA [GDI32.@] + */ +DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count, + LPWORD pgi, DWORD flags) +{ + DWORD ret; + WCHAR *lpstrW; + INT countW; + + TRACE("(%04x, %s, %d, %p, 0x%lx)\n", + hdc, debugstr_an(lpstr, count), count, pgi, flags); + + lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL); + ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags); + HeapFree(GetProcessHeap(), 0, lpstrW); + + return ret; +} + +/************************************************************************* + * GetGlyphIndicesW [GDI32.@] + */ +DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count, + LPWORD pgi, DWORD flags) +{ + DC *dc = DC_GetDCPtr(hdc); + DWORD ret = GDI_ERROR; + + TRACE("(%04x, %s, %d, %p, 0x%lx)\n", + hdc, debugstr_wn(lpstr, count), count, pgi, flags); + + if(!dc) return GDI_ERROR; + + if(dc->gdiFont) + ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags); + + GDI_ReleaseObj(hdc); + return ret; +} + /************************************************************************* * GetCharacterPlacementA [GDI32.@] * @@ -2010,41 +2051,32 @@ GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount, INT nMaxExtent, GCP_RESULTSA *lpResults, DWORD dwFlags) { - DWORD ret=0; - SIZE size; + WCHAR *lpStringW; + INT uCountW; + GCP_RESULTSW resultsW; + DWORD ret; + UINT font_cp; - TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n", - debugstr_a(lpString), uCount, nMaxExtent, dwFlags); + TRACE("%s, %d, %d, 0x%08lx\n", + debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags); - TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p " - "lpOutString=%p lpGlyphs=%p\n", - lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos, - lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs); + /* both structs are equal in size */ + memcpy(&resultsW, lpResults, sizeof(resultsW)); - if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags); - if(lpResults->lpOrder) FIXME("reordering not implemented\n"); - if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n"); - if(lpResults->lpClass) FIXME("classes not implemented\n"); - if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n"); - - /* copy will do if the GCP_REORDER flag is not set */ + lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp); if(lpResults->lpOutString) - { - lstrcpynA(lpResults->lpOutString, lpString, uCount); - } + resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW); + else + resultsW.lpOutString = NULL; - if (lpResults->lpDx) - { - int i, c; - for (i=0; ilpDx[i]= c; - } - } + ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags); - if (GetTextExtentPoint32A(hdc, lpString, uCount, &size)) - ret = MAKELONG(size.cx, size.cy); + if(lpResults->lpOutString) + WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW, + lpResults->lpOutString, uCount, NULL, NULL ); + + HeapFree(GetProcessHeap(), 0, lpStringW); + HeapFree(GetProcessHeap(), 0, resultsW.lpOutString); return ret; } @@ -2059,37 +2091,52 @@ GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount, { DWORD ret=0; SIZE size; + UINT i, nSet; - TRACE("%s 0x%08x 0x%08x 0x%08lx:partial stub!\n", - debugstr_w(lpString), uCount, nMaxExtent, dwFlags); + TRACE("%s, %d, %d, 0x%08lx\n", + debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags); - TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p " - "lpOutString=%p lpGlyphs=%p\n", - lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos, - lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs); + TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n" + "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n", + lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder, + lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass, + lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit); if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags); - if(lpResults->lpOrder) FIXME("reordering not implemented\n"); if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n"); if(lpResults->lpClass) FIXME("classes not implemented\n"); - if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n"); + /* FIXME: reordering not implemented */ /* copy will do if the GCP_REORDER flag is not set */ if(lpResults->lpOutString) - { lstrcpynW(lpResults->lpOutString, lpString, uCount); + + nSet = (UINT)uCount; + if(nSet > lpResults->nGlyphs) + nSet = lpResults->nGlyphs; + + /* return number of initialized fields */ + lpResults->nGlyphs = nSet; + + if(lpResults->lpOrder) + { + for(i = 0; i < nSet; i++) + lpResults->lpOrder[i] = i; } if (lpResults->lpDx) { - int i, c; - for (i=0; ilpDx[i]= c; } } + if(lpResults->lpGlyphs) + GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0); + if (GetTextExtentPoint32W(hdc, lpString, uCount, &size)) ret = MAKELONG(size.cx, size.cy);