diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 12d56de35d9..f825562b37f 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -5976,93 +5976,27 @@ done: } /************************************************************************* - * GetKerningPairsA (GDI32.@) + * NtGdiGetKerningPairsW (win32u.@) */ -DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs, - LPKERNINGPAIR kern_pairA ) -{ - UINT cp; - CPINFO cpi; - DWORD i, total_kern_pairs, kern_pairs_copied = 0; - KERNINGPAIR *kern_pairW; - - if (!cPairs && kern_pairA) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - cp = GdiGetCodePage(hDC); - - /* GetCPInfo() will fail on CP_SYMBOL, and WideCharToMultiByte is supposed - * to fail on an invalid character for CP_SYMBOL. - */ - cpi.DefaultChar[0] = 0; - if (cp != CP_SYMBOL && !GetCPInfo(cp, &cpi)) - { - FIXME("Can't find codepage %u info\n", cp); - return 0; - } - - total_kern_pairs = GetKerningPairsW(hDC, 0, NULL); - if (!total_kern_pairs) return 0; - - kern_pairW = HeapAlloc(GetProcessHeap(), 0, total_kern_pairs * sizeof(*kern_pairW)); - GetKerningPairsW(hDC, total_kern_pairs, kern_pairW); - - for (i = 0; i < total_kern_pairs; i++) - { - char first, second; - - if (!WideCharToMultiByte(cp, 0, &kern_pairW[i].wFirst, 1, &first, 1, NULL, NULL)) - continue; - - if (!WideCharToMultiByte(cp, 0, &kern_pairW[i].wSecond, 1, &second, 1, NULL, NULL)) - continue; - - if (first == cpi.DefaultChar[0] || second == cpi.DefaultChar[0]) - continue; - - if (kern_pairA) - { - if (kern_pairs_copied >= cPairs) break; - - kern_pairA->wFirst = (BYTE)first; - kern_pairA->wSecond = (BYTE)second; - kern_pairA->iKernAmount = kern_pairW[i].iKernAmount; - kern_pairA++; - } - kern_pairs_copied++; - } - - HeapFree(GetProcessHeap(), 0, kern_pairW); - - return kern_pairs_copied; -} - -/************************************************************************* - * GetKerningPairsW (GDI32.@) - */ -DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs, - LPKERNINGPAIR lpKerningPairs ) +DWORD WINAPI NtGdiGetKerningPairsW( HDC hdc, DWORD count, KERNINGPAIR *kern_pair ) { DC *dc; DWORD ret; PHYSDEV dev; - TRACE("(%p,%d,%p)\n", hDC, cPairs, lpKerningPairs); + TRACE( "(%p,%d,%p)\n", hdc, count, kern_pair ); - if (!cPairs && lpKerningPairs) + if (!count && kern_pair) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError( ERROR_INVALID_PARAMETER ); return 0; } - dc = get_dc_ptr(hDC); + dc = get_dc_ptr( hdc ); if (!dc) return 0; dev = GET_DC_PHYSDEV( dc, pGetKerningPairs ); - ret = dev->funcs->pGetKerningPairs( dev, cPairs, lpKerningPairs ); + ret = dev->funcs->pGetKerningPairs( dev, count, kern_pair ); release_dc_ptr( dc ); return ret; } @@ -6147,7 +6081,7 @@ DWORD WINAPI GetFontLanguageInfo(HDC hdc) if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 ) result|=GCP_LIGATE; - if( GetKerningPairsW( hdc, 0, NULL ) ) + if( NtGdiGetKerningPairsW( hdc, 0, NULL ) ) result|=GCP_USEKERNING; /* this might need a test for a HEBREW- or ARABIC_CHARSET as well */ diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec index 5bddcd26de6..7862a5c3077 100644 --- a/dlls/gdi32/gdi32.spec +++ b/dlls/gdi32/gdi32.spec @@ -309,7 +309,7 @@ @ stdcall GetICMProfileW(long ptr ptr) @ stdcall GetKerningPairs(long long ptr) GetKerningPairsA @ stdcall GetKerningPairsA(long long ptr) -@ stdcall GetKerningPairsW(long long ptr) +@ stdcall GetKerningPairsW(long long ptr) NtGdiGetKerningPairsW @ stdcall GetLayout(long) @ stdcall GetLogColorSpaceA(long ptr long) @ stdcall GetLogColorSpaceW(long ptr long) diff --git a/dlls/gdi32/text.c b/dlls/gdi32/text.c index 7e9b882bdb1..ba86a1a3b1d 100644 --- a/dlls/gdi32/text.c +++ b/dlls/gdi32/text.c @@ -1049,7 +1049,7 @@ static int *kern_string( HDC hdc, const WCHAR *str, int len, int *kern_total ) ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(*ret) ); if (!ret) return NULL; - count = GetKerningPairsW( hdc, 0, NULL ); + count = NtGdiGetKerningPairsW( hdc, 0, NULL ); if (count) { kern = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*kern) ); @@ -1059,7 +1059,7 @@ static int *kern_string( HDC hdc, const WCHAR *str, int len, int *kern_total ) return NULL; } - GetKerningPairsW( hdc, count, kern ); + NtGdiGetKerningPairsW( hdc, count, kern ); } for (i = 0; i < len - 1; i++) @@ -1786,3 +1786,66 @@ DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT ch, UINT format, GLYPHMETRICS *metr { return NtGdiGetGlyphOutlineW( hdc, ch, format, metrics, size, buffer, mat2, FALSE ); } + +/************************************************************************* + * GetKerningPairsA (GDI32.@) + */ +DWORD WINAPI GetKerningPairsA( HDC hdc, DWORD count, KERNINGPAIR *kern_pairA ) +{ + DWORD i, total_kern_pairs, kern_pairs_copied = 0; + KERNINGPAIR *kern_pairW; + CPINFO cpi; + UINT cp; + + if (!count && kern_pairA) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0; + } + + cp = GdiGetCodePage( hdc ); + + /* GetCPInfo() will fail on CP_SYMBOL, and WideCharToMultiByte is supposed + * to fail on an invalid character for CP_SYMBOL. + */ + cpi.DefaultChar[0] = 0; + if (cp != CP_SYMBOL && !GetCPInfo( cp, &cpi )) + { + FIXME( "Can't find codepage %u info\n", cp ); + return 0; + } + + total_kern_pairs = NtGdiGetKerningPairsW( hdc, 0, NULL ); + if (!total_kern_pairs) return 0; + + kern_pairW = HeapAlloc( GetProcessHeap(), 0, total_kern_pairs * sizeof(*kern_pairW) ); + NtGdiGetKerningPairsW( hdc, total_kern_pairs, kern_pairW ); + + for (i = 0; i < total_kern_pairs; i++) + { + char first, second; + + if (!WideCharToMultiByte( cp, 0, &kern_pairW[i].wFirst, 1, &first, 1, NULL, NULL )) + continue; + + if (!WideCharToMultiByte( cp, 0, &kern_pairW[i].wSecond, 1, &second, 1, NULL, NULL )) + continue; + + if (first == cpi.DefaultChar[0] || second == cpi.DefaultChar[0]) + continue; + + if (kern_pairA) + { + if (kern_pairs_copied >= count) break; + + kern_pairA->wFirst = (BYTE)first; + kern_pairA->wSecond = (BYTE)second; + kern_pairA->iKernAmount = kern_pairW[i].iKernAmount; + kern_pairA++; + } + kern_pairs_copied++; + } + + HeapFree( GetProcessHeap(), 0, kern_pairW ); + return kern_pairs_copied; +} diff --git a/include/ntgdi.h b/include/ntgdi.h index c8958cf83c9..f9ad9da2060 100644 --- a/include/ntgdi.h +++ b/include/ntgdi.h @@ -225,6 +225,8 @@ BOOL WINAPI NtGdiFillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush ); INT WINAPI NtGdiExtEscape( HDC hdc, WCHAR *driver, INT driver_id, INT escape, INT input_size, const char *input, INT output_size, char *output ); BOOL WINAPI NtGdiExtFloodFill( HDC hdc, INT x, INT y, COLORREF color, UINT type ); +BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *rect, + const WCHAR *str, UINT count, const INT *dx, DWORD cp ); BOOL WINAPI NtGdiFrameRgn( HDC hdc, HRGN hrgn, HBRUSH brush, INT width, INT height ); BOOL WINAPI NtGdiFillPath( HDC hdc ); @@ -243,8 +245,7 @@ BOOL WINAPI NtGdiGetDeviceGammaRamp( HDC hdc, void *ptr ); DWORD WINAPI NtGdiGetGlyphOutlineW( HDC hdc, UINT ch, UINT format, GLYPHMETRICS *metrics, DWORD size, void *buffer, const MAT2 *mat2, BOOL ignore_rotation ); -BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *rect, - const WCHAR *str, UINT count, const INT *dx, DWORD cp ); +DWORD WINAPI NtGdiGetKerningPairsW( HDC hdc, DWORD count, KERNINGPAIR *kern_pair ); BOOL WINAPI NtGdiGetMiterLimit( HDC hdc, FLOAT *limit ); COLORREF WINAPI NtGdiGetNearestColor( HDC hdc, COLORREF color ); UINT WINAPI NtGdiGetNearestPaletteIndex( HPALETTE hpalette, COLORREF color );