gdi32: Use NtGdiGetOutlineTextMetricsInternalW for GetOutlineTextMetrics.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
75786478c6
commit
0669b6cd48
|
@ -4737,188 +4737,10 @@ BOOL WINAPI NtGdiGetTextMetricsW( HDC hdc, TEXTMETRICW *metrics, ULONG flags )
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GetOutlineTextMetricsA (GDI32.@)
|
* NtGdiGetOutlineTextMetricsInternalW (win32u.@)
|
||||||
* Gets metrics for TrueType fonts.
|
|
||||||
*
|
|
||||||
* NOTES
|
|
||||||
* If the supplied buffer isn't big enough Windows partially fills it up to
|
|
||||||
* its given length and returns that length.
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* Success: Non-zero or size of required buffer
|
|
||||||
* Failure: 0
|
|
||||||
*/
|
*/
|
||||||
UINT WINAPI GetOutlineTextMetricsA(
|
UINT WINAPI NtGdiGetOutlineTextMetricsInternalW( HDC hdc, UINT cbData,
|
||||||
HDC hdc, /* [in] Handle of device context */
|
OUTLINETEXTMETRICW *lpOTM, ULONG opts )
|
||||||
UINT cbData, /* [in] Size of metric data array */
|
|
||||||
LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
|
|
||||||
{
|
|
||||||
char buf[512], *ptr;
|
|
||||||
UINT ret, needed;
|
|
||||||
OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
|
|
||||||
OUTLINETEXTMETRICA *output = lpOTM;
|
|
||||||
INT left, len;
|
|
||||||
|
|
||||||
if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
|
|
||||||
return 0;
|
|
||||||
if(ret > sizeof(buf))
|
|
||||||
lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
|
|
||||||
GetOutlineTextMetricsW(hdc, ret, lpOTMW);
|
|
||||||
|
|
||||||
needed = sizeof(OUTLINETEXTMETRICA);
|
|
||||||
if(lpOTMW->otmpFamilyName)
|
|
||||||
needed += WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
(WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
|
|
||||||
NULL, 0, NULL, NULL);
|
|
||||||
if(lpOTMW->otmpFaceName)
|
|
||||||
needed += WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
(WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
|
|
||||||
NULL, 0, NULL, NULL);
|
|
||||||
if(lpOTMW->otmpStyleName)
|
|
||||||
needed += WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
(WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
|
|
||||||
NULL, 0, NULL, NULL);
|
|
||||||
if(lpOTMW->otmpFullName)
|
|
||||||
needed += WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
(WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
|
|
||||||
NULL, 0, NULL, NULL);
|
|
||||||
|
|
||||||
if(!lpOTM) {
|
|
||||||
ret = needed;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("needed = %d\n", needed);
|
|
||||||
if(needed > cbData)
|
|
||||||
/* Since the supplied buffer isn't big enough, we'll alloc one
|
|
||||||
that is and memcpy the first cbData bytes into the lpOTM at
|
|
||||||
the end. */
|
|
||||||
output = HeapAlloc(GetProcessHeap(), 0, needed);
|
|
||||||
|
|
||||||
ret = output->otmSize = min(needed, cbData);
|
|
||||||
FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &output->otmTextMetrics );
|
|
||||||
output->otmFiller = 0;
|
|
||||||
output->otmPanoseNumber = lpOTMW->otmPanoseNumber;
|
|
||||||
output->otmfsSelection = lpOTMW->otmfsSelection;
|
|
||||||
output->otmfsType = lpOTMW->otmfsType;
|
|
||||||
output->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
|
|
||||||
output->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
|
|
||||||
output->otmItalicAngle = lpOTMW->otmItalicAngle;
|
|
||||||
output->otmEMSquare = lpOTMW->otmEMSquare;
|
|
||||||
output->otmAscent = lpOTMW->otmAscent;
|
|
||||||
output->otmDescent = lpOTMW->otmDescent;
|
|
||||||
output->otmLineGap = lpOTMW->otmLineGap;
|
|
||||||
output->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
|
|
||||||
output->otmsXHeight = lpOTMW->otmsXHeight;
|
|
||||||
output->otmrcFontBox = lpOTMW->otmrcFontBox;
|
|
||||||
output->otmMacAscent = lpOTMW->otmMacAscent;
|
|
||||||
output->otmMacDescent = lpOTMW->otmMacDescent;
|
|
||||||
output->otmMacLineGap = lpOTMW->otmMacLineGap;
|
|
||||||
output->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
|
|
||||||
output->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
|
|
||||||
output->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
|
|
||||||
output->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
|
|
||||||
output->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
|
|
||||||
output->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
|
|
||||||
output->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
|
|
||||||
output->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
|
|
||||||
output->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
|
|
||||||
|
|
||||||
|
|
||||||
ptr = (char*)(output + 1);
|
|
||||||
left = needed - sizeof(*output);
|
|
||||||
|
|
||||||
if(lpOTMW->otmpFamilyName) {
|
|
||||||
output->otmpFamilyName = (LPSTR)(ptr - (char*)output);
|
|
||||||
len = WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
(WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
|
|
||||||
ptr, left, NULL, NULL);
|
|
||||||
left -= len;
|
|
||||||
ptr += len;
|
|
||||||
} else
|
|
||||||
output->otmpFamilyName = 0;
|
|
||||||
|
|
||||||
if(lpOTMW->otmpFaceName) {
|
|
||||||
output->otmpFaceName = (LPSTR)(ptr - (char*)output);
|
|
||||||
len = WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
(WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
|
|
||||||
ptr, left, NULL, NULL);
|
|
||||||
left -= len;
|
|
||||||
ptr += len;
|
|
||||||
} else
|
|
||||||
output->otmpFaceName = 0;
|
|
||||||
|
|
||||||
if(lpOTMW->otmpStyleName) {
|
|
||||||
output->otmpStyleName = (LPSTR)(ptr - (char*)output);
|
|
||||||
len = WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
(WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
|
|
||||||
ptr, left, NULL, NULL);
|
|
||||||
left -= len;
|
|
||||||
ptr += len;
|
|
||||||
} else
|
|
||||||
output->otmpStyleName = 0;
|
|
||||||
|
|
||||||
if(lpOTMW->otmpFullName) {
|
|
||||||
output->otmpFullName = (LPSTR)(ptr - (char*)output);
|
|
||||||
len = WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
(WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
|
|
||||||
ptr, left, NULL, NULL);
|
|
||||||
left -= len;
|
|
||||||
} else
|
|
||||||
output->otmpFullName = 0;
|
|
||||||
|
|
||||||
assert(left == 0);
|
|
||||||
|
|
||||||
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? */
|
|
||||||
/* make sure that we don't read/write beyond the provided buffer */
|
|
||||||
if (lpOTM->otmSize >= FIELD_OFFSET(OUTLINETEXTMETRICA, otmpFamilyName) + sizeof(LPSTR))
|
|
||||||
{
|
|
||||||
if ((UINT_PTR)lpOTM->otmpFamilyName >= lpOTM->otmSize)
|
|
||||||
lpOTM->otmpFamilyName = 0; /* doesn't fit */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure that we don't read/write beyond the provided buffer */
|
|
||||||
if (lpOTM->otmSize >= FIELD_OFFSET(OUTLINETEXTMETRICA, otmpFaceName) + sizeof(LPSTR))
|
|
||||||
{
|
|
||||||
if ((UINT_PTR)lpOTM->otmpFaceName >= lpOTM->otmSize)
|
|
||||||
lpOTM->otmpFaceName = 0; /* doesn't fit */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure that we don't read/write beyond the provided buffer */
|
|
||||||
if (lpOTM->otmSize >= FIELD_OFFSET(OUTLINETEXTMETRICA, otmpStyleName) + sizeof(LPSTR))
|
|
||||||
{
|
|
||||||
if ((UINT_PTR)lpOTM->otmpStyleName >= lpOTM->otmSize)
|
|
||||||
lpOTM->otmpStyleName = 0; /* doesn't fit */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure that we don't read/write beyond the provided buffer */
|
|
||||||
if (lpOTM->otmSize >= FIELD_OFFSET(OUTLINETEXTMETRICA, otmpFullName) + sizeof(LPSTR))
|
|
||||||
{
|
|
||||||
if ((UINT_PTR)lpOTM->otmpFullName >= lpOTM->otmSize)
|
|
||||||
lpOTM->otmpFullName = 0; /* doesn't fit */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
|
|
||||||
HeapFree(GetProcessHeap(), 0, lpOTMW);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* GetOutlineTextMetricsW [GDI32.@]
|
|
||||||
*/
|
|
||||||
UINT WINAPI GetOutlineTextMetricsW(
|
|
||||||
HDC hdc, /* [in] Handle of device context */
|
|
||||||
UINT cbData, /* [in] Size of metric data array */
|
|
||||||
LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
|
|
||||||
{
|
{
|
||||||
DC *dc = get_dc_ptr( hdc );
|
DC *dc = get_dc_ptr( hdc );
|
||||||
OUTLINETEXTMETRICW *output = lpOTM;
|
OUTLINETEXTMETRICW *output = lpOTM;
|
||||||
|
@ -5702,7 +5524,7 @@ done:
|
||||||
{
|
{
|
||||||
int underlinePos, strikeoutPos;
|
int underlinePos, strikeoutPos;
|
||||||
int underlineWidth, strikeoutWidth;
|
int underlineWidth, strikeoutWidth;
|
||||||
UINT size = GetOutlineTextMetricsW(hdc, 0, NULL);
|
UINT size = NtGdiGetOutlineTextMetricsInternalW( hdc, 0, NULL, 0 );
|
||||||
OUTLINETEXTMETRICW* otm = NULL;
|
OUTLINETEXTMETRICW* otm = NULL;
|
||||||
POINT pts[5];
|
POINT pts[5];
|
||||||
HPEN hpen = NtGdiSelectPen(hdc, GetStockObject(NULL_PEN));
|
HPEN hpen = NtGdiSelectPen(hdc, GetStockObject(NULL_PEN));
|
||||||
|
@ -5720,7 +5542,7 @@ done:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
otm = HeapAlloc(GetProcessHeap(), 0, size);
|
otm = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
GetOutlineTextMetricsW(hdc, size, otm);
|
NtGdiGetOutlineTextMetricsInternalW( hdc, size, otm, 0 );
|
||||||
underlinePos = abs( INTERNAL_YWSTODS( dc, otm->otmsUnderscorePosition ));
|
underlinePos = abs( INTERNAL_YWSTODS( dc, otm->otmsUnderscorePosition ));
|
||||||
if (otm->otmsUnderscorePosition < 0) underlinePos = -underlinePos;
|
if (otm->otmsUnderscorePosition < 0) underlinePos = -underlinePos;
|
||||||
underlineWidth = get_line_width( dc, otm->otmsUnderscoreSize );
|
underlineWidth = get_line_width( dc, otm->otmsUnderscoreSize );
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
@ -1388,3 +1389,184 @@ BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
|
||||||
text_metric_WtoA( &tm32, metrics );
|
text_metric_WtoA( &tm32, metrics );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetOutlineTextMetricsA (GDI32.@)
|
||||||
|
*
|
||||||
|
* Gets metrics for TrueType fonts.
|
||||||
|
*
|
||||||
|
* NOTES
|
||||||
|
* If the supplied buffer isn't big enough Windows partially fills it up to
|
||||||
|
* its given length and returns that length.
|
||||||
|
*/
|
||||||
|
UINT WINAPI GetOutlineTextMetricsA( HDC hdc, UINT size, OUTLINETEXTMETRICA *otm )
|
||||||
|
{
|
||||||
|
char buf[512], *ptr;
|
||||||
|
UINT ret, needed;
|
||||||
|
OUTLINETEXTMETRICW *otmW = (OUTLINETEXTMETRICW *)buf;
|
||||||
|
OUTLINETEXTMETRICA *output = otm;
|
||||||
|
INT left, len;
|
||||||
|
|
||||||
|
if ((ret = GetOutlineTextMetricsW( hdc, 0, NULL )) == 0) return 0;
|
||||||
|
if (ret > sizeof(buf) && !(otmW = HeapAlloc( GetProcessHeap(), 0, ret )))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
GetOutlineTextMetricsW( hdc, ret, otmW );
|
||||||
|
|
||||||
|
needed = sizeof(OUTLINETEXTMETRICA);
|
||||||
|
if (otmW->otmpFamilyName)
|
||||||
|
needed += WideCharToMultiByte( CP_ACP, 0,
|
||||||
|
(WCHAR *)((char *)otmW + (ptrdiff_t)otmW->otmpFamilyName),
|
||||||
|
-1, NULL, 0, NULL, NULL );
|
||||||
|
if (otmW->otmpFaceName)
|
||||||
|
needed += WideCharToMultiByte( CP_ACP, 0,
|
||||||
|
(WCHAR *)((char *)otmW + (ptrdiff_t)otmW->otmpFaceName),
|
||||||
|
-1, NULL, 0, NULL, NULL );
|
||||||
|
if (otmW->otmpStyleName)
|
||||||
|
needed += WideCharToMultiByte( CP_ACP, 0,
|
||||||
|
(WCHAR *)((char *)otmW + (ptrdiff_t)otmW->otmpStyleName),
|
||||||
|
-1, NULL, 0, NULL, NULL );
|
||||||
|
if (otmW->otmpFullName)
|
||||||
|
needed += WideCharToMultiByte( CP_ACP, 0,
|
||||||
|
(WCHAR *)((char *)otmW + (ptrdiff_t)otmW->otmpFullName),
|
||||||
|
-1, NULL, 0, NULL, NULL );
|
||||||
|
|
||||||
|
if (!otm)
|
||||||
|
{
|
||||||
|
ret = needed;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE( "needed = %d\n", needed );
|
||||||
|
if (needed > size)
|
||||||
|
/* Since the supplied buffer isn't big enough, we'll alloc one
|
||||||
|
that is and memcpy the first size bytes into the otm at
|
||||||
|
the end. */
|
||||||
|
output = HeapAlloc( GetProcessHeap(), 0, needed );
|
||||||
|
|
||||||
|
ret = output->otmSize = min( needed, size );
|
||||||
|
text_metric_WtoA( &otmW->otmTextMetrics, &output->otmTextMetrics );
|
||||||
|
output->otmFiller = 0;
|
||||||
|
output->otmPanoseNumber = otmW->otmPanoseNumber;
|
||||||
|
output->otmfsSelection = otmW->otmfsSelection;
|
||||||
|
output->otmfsType = otmW->otmfsType;
|
||||||
|
output->otmsCharSlopeRise = otmW->otmsCharSlopeRise;
|
||||||
|
output->otmsCharSlopeRun = otmW->otmsCharSlopeRun;
|
||||||
|
output->otmItalicAngle = otmW->otmItalicAngle;
|
||||||
|
output->otmEMSquare = otmW->otmEMSquare;
|
||||||
|
output->otmAscent = otmW->otmAscent;
|
||||||
|
output->otmDescent = otmW->otmDescent;
|
||||||
|
output->otmLineGap = otmW->otmLineGap;
|
||||||
|
output->otmsCapEmHeight = otmW->otmsCapEmHeight;
|
||||||
|
output->otmsXHeight = otmW->otmsXHeight;
|
||||||
|
output->otmrcFontBox = otmW->otmrcFontBox;
|
||||||
|
output->otmMacAscent = otmW->otmMacAscent;
|
||||||
|
output->otmMacDescent = otmW->otmMacDescent;
|
||||||
|
output->otmMacLineGap = otmW->otmMacLineGap;
|
||||||
|
output->otmusMinimumPPEM = otmW->otmusMinimumPPEM;
|
||||||
|
output->otmptSubscriptSize = otmW->otmptSubscriptSize;
|
||||||
|
output->otmptSubscriptOffset = otmW->otmptSubscriptOffset;
|
||||||
|
output->otmptSuperscriptSize = otmW->otmptSuperscriptSize;
|
||||||
|
output->otmptSuperscriptOffset = otmW->otmptSuperscriptOffset;
|
||||||
|
output->otmsStrikeoutSize = otmW->otmsStrikeoutSize;
|
||||||
|
output->otmsStrikeoutPosition = otmW->otmsStrikeoutPosition;
|
||||||
|
output->otmsUnderscoreSize = otmW->otmsUnderscoreSize;
|
||||||
|
output->otmsUnderscorePosition = otmW->otmsUnderscorePosition;
|
||||||
|
|
||||||
|
ptr = (char *)(output + 1);
|
||||||
|
left = needed - sizeof(*output);
|
||||||
|
|
||||||
|
if (otmW->otmpFamilyName)
|
||||||
|
{
|
||||||
|
output->otmpFamilyName = (char *)(ptr - (char *)output);
|
||||||
|
len = WideCharToMultiByte( CP_ACP, 0,
|
||||||
|
(WCHAR *)((char *)otmW + (ptrdiff_t)otmW->otmpFamilyName),
|
||||||
|
-1, ptr, left, NULL, NULL );
|
||||||
|
left -= len;
|
||||||
|
ptr += len;
|
||||||
|
}
|
||||||
|
else output->otmpFamilyName = 0;
|
||||||
|
|
||||||
|
if (otmW->otmpFaceName)
|
||||||
|
{
|
||||||
|
output->otmpFaceName = (char *)(ptr - (char *)output);
|
||||||
|
len = WideCharToMultiByte( CP_ACP, 0,
|
||||||
|
(WCHAR *)((char *)otmW + (ptrdiff_t)otmW->otmpFaceName),
|
||||||
|
-1, ptr, left, NULL, NULL );
|
||||||
|
left -= len;
|
||||||
|
ptr += len;
|
||||||
|
}
|
||||||
|
else output->otmpFaceName = 0;
|
||||||
|
|
||||||
|
if (otmW->otmpStyleName)
|
||||||
|
{
|
||||||
|
output->otmpStyleName = (char *)(ptr - (char *)output);
|
||||||
|
len = WideCharToMultiByte( CP_ACP, 0,
|
||||||
|
(WCHAR *)((char *)otmW + (ptrdiff_t)otmW->otmpStyleName),
|
||||||
|
-1, ptr, left, NULL, NULL);
|
||||||
|
left -= len;
|
||||||
|
ptr += len;
|
||||||
|
}
|
||||||
|
else output->otmpStyleName = 0;
|
||||||
|
|
||||||
|
if (otmW->otmpFullName)
|
||||||
|
{
|
||||||
|
output->otmpFullName = (char *)(ptr - (char *)output);
|
||||||
|
len = WideCharToMultiByte( CP_ACP, 0,
|
||||||
|
(WCHAR *)((char *)otmW + (ptrdiff_t)otmW->otmpFullName),
|
||||||
|
-1, ptr, left, NULL, NULL );
|
||||||
|
left -= len;
|
||||||
|
}
|
||||||
|
else output->otmpFullName = 0;
|
||||||
|
|
||||||
|
assert( left == 0 );
|
||||||
|
|
||||||
|
if (output != otm)
|
||||||
|
{
|
||||||
|
memcpy( otm, output, size );
|
||||||
|
HeapFree( GetProcessHeap(), 0, output );
|
||||||
|
|
||||||
|
/* check if the string offsets really fit into the provided size */
|
||||||
|
/* FIXME: should we check string length as well? */
|
||||||
|
/* make sure that we don't read/write beyond the provided buffer */
|
||||||
|
if (otm->otmSize >= FIELD_OFFSET(OUTLINETEXTMETRICA, otmpFamilyName) + sizeof(char *))
|
||||||
|
{
|
||||||
|
if ((UINT_PTR)otm->otmpFamilyName >= otm->otmSize)
|
||||||
|
otm->otmpFamilyName = 0; /* doesn't fit */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure that we don't read/write beyond the provided buffer */
|
||||||
|
if (otm->otmSize >= FIELD_OFFSET(OUTLINETEXTMETRICA, otmpFaceName) + sizeof(char *))
|
||||||
|
{
|
||||||
|
if ((UINT_PTR)otm->otmpFaceName >= otm->otmSize)
|
||||||
|
otm->otmpFaceName = 0; /* doesn't fit */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure that we don't read/write beyond the provided buffer */
|
||||||
|
if (otm->otmSize >= FIELD_OFFSET(OUTLINETEXTMETRICA, otmpStyleName) + sizeof(char *))
|
||||||
|
{
|
||||||
|
if ((UINT_PTR)otm->otmpStyleName >= otm->otmSize)
|
||||||
|
otm->otmpStyleName = 0; /* doesn't fit */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure that we don't read/write beyond the provided buffer */
|
||||||
|
if (otm->otmSize >= FIELD_OFFSET(OUTLINETEXTMETRICA, otmpFullName) + sizeof(char *))
|
||||||
|
{
|
||||||
|
if ((UINT_PTR)otm->otmpFullName >= otm->otmSize)
|
||||||
|
otm->otmpFullName = 0; /* doesn't fit */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (otmW != (OUTLINETEXTMETRICW *)buf)
|
||||||
|
HeapFree(GetProcessHeap(), 0, otmW);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetOutlineTextMetricsW [GDI32.@]
|
||||||
|
*/
|
||||||
|
UINT WINAPI GetOutlineTextMetricsW( HDC hdc, UINT size, OUTLINETEXTMETRICW *otm )
|
||||||
|
{
|
||||||
|
return NtGdiGetOutlineTextMetricsInternalW( hdc, size, otm, 0 );
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue