Implement GetTextExtentPointI and add support for ETO_GLYPH_INDEX.

This commit is contained in:
Huw D M Davies 2002-04-03 22:08:27 +00:00 committed by Alexandre Julliard
parent e1e51f9922
commit 5b01b50631
7 changed files with 158 additions and 19 deletions

View File

@ -1723,6 +1723,33 @@ BOOL WineEngGetTextExtentPoint(GdiFont font, LPCWSTR wstr, INT count,
return TRUE;
}
/*************************************************************
* WineEngGetTextExtentPointI
*
*/
BOOL WineEngGetTextExtentPointI(GdiFont font, const WORD *indices, INT count,
LPSIZE size)
{
UINT idx;
GLYPHMETRICS gm;
TEXTMETRICW tm;
TRACE("%p, %p, %d, %p\n", font, indices, count, size);
size->cx = 0;
WineEngGetTextMetrics(font, &tm);
size->cy = tm.tmHeight;
for(idx = 0; idx < count; idx++) {
WineEngGetGlyphOutline(font, indices[idx],
GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL,
NULL);
size->cx += font->gm[indices[idx]].adv;
}
TRACE("return %ld,%ld\n", size->cx, size->cy);
return TRUE;
}
/*************************************************************
* WineEngGetFontData
*
@ -1824,6 +1851,13 @@ BOOL WineEngGetTextExtentPoint(GdiFont font, LPCWSTR wstr, INT count,
return FALSE;
}
BOOL WineEngGetTextExtentPointI(GdiFont font, LPWORD indices, INT count,
LPSIZE size)
{
ERR("called but we don't have FreeType\n");
return FALSE;
}
DWORD WineEngGetFontData(GdiFont font, DWORD table, DWORD offset, LPVOID buf,
DWORD cbData)
{

View File

@ -273,10 +273,11 @@ debug_channels (bitblt bitmap clipping dc ddraw driver enhmetafile font gdi
@ stdcall GetTextColor(long) GetTextColor
@ stdcall GetTextExtentExPointA(long str long long ptr ptr ptr) GetTextExtentExPointA
@ stdcall GetTextExtentExPointW(long wstr long long ptr ptr ptr) GetTextExtentExPointW
@ stdcall GetTextExtentPoint32A(long ptr long ptr) GetTextExtentPoint32A
@ stdcall GetTextExtentPoint32W(long ptr long ptr) GetTextExtentPoint32W
@ stdcall GetTextExtentPointA(long ptr long ptr) GetTextExtentPointA
@ stdcall GetTextExtentPointW(long ptr long ptr) GetTextExtentPointW
@ stdcall GetTextExtentPoint32A(long str long ptr) GetTextExtentPoint32A
@ stdcall GetTextExtentPoint32W(long wstr long ptr) GetTextExtentPoint32W
@ stdcall GetTextExtentPointA(long str long ptr) GetTextExtentPointA
@ stdcall GetTextExtentPointI(long ptr long ptr) GetTextExtentPointI
@ stdcall GetTextExtentPointW(long wstr long ptr) GetTextExtentPointW
@ stdcall GetTextFaceA(long long ptr) GetTextFaceA
@ stdcall GetTextFaceW(long long ptr) GetTextFaceW
@ stdcall GetTextMetricsA(long ptr) GetTextMetricsA

View File

@ -365,7 +365,7 @@ void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev)
return;
}
static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, WCHAR glyph)
static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, int glyph)
{
int buflen;
char *buf;
@ -373,7 +373,7 @@ static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, WCHAR glyph)
GLYPHMETRICS gm;
XGlyphInfo gi;
gsCacheEntry *entry = physDev->xrender->cacheEntry;
UINT ggo_format;
UINT ggo_format = GGO_GLYPH_INDEX;
BOOL aa;
if(entry->nrealized <= glyph) {
@ -387,10 +387,10 @@ static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, WCHAR glyph)
if(entry->font_format->depth == 8) {
aa = TRUE;
ggo_format = WINE_GGO_GRAY16_BITMAP;
ggo_format |= WINE_GGO_GRAY16_BITMAP;
} else {
aa = FALSE;
ggo_format = GGO_BITMAP;
ggo_format |= GGO_BITMAP;
}
buflen = GetGlyphOutlineW(physDev->hdc, glyph, ggo_format, &gm, 0, NULL,
@ -490,11 +490,20 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
XGCValues xgcval;
LOGFONTW lf;
int render_op = PictOpOver;
WORD *glyphs;
HDC hdc = physDev->hdc;
DC *dc = physDev->dc;
TRACE("%04x, %d, %d, %08x, %p, %s, %d, %p)\n", hdc, x, y, flags,
lprect, debugstr_wn(wstr, count), count, lpDx);
if(flags & ETO_GLYPH_INDEX)
glyphs = (LPWORD)wstr;
else {
glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR));
GetGlyphIndicesW(hdc, wstr, count, glyphs, 0);
}
if(lprect)
TRACE("rect: %d,%d - %d,%d\n", lprect->left, lprect->top, lprect->right,
lprect->bottom);
@ -517,7 +526,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
if(flags & (ETO_CLIPPED | ETO_OPAQUE)) {
if(!lprect) {
if(flags & ETO_CLIPPED) return FALSE;
GetTextExtentPointW(hdc, wstr, count, &sz);
GetTextExtentPointI(hdc, glyphs, count, &sz);
done_extents = TRUE;
rc.left = x;
rc.top = y;
@ -567,7 +576,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
width += lpDx[idx];
} else {
if(!done_extents) {
GetTextExtentPointW(hdc, wstr, count, &sz);
GetTextExtentPointI(hdc, glyphs, count, &sz);
done_extents = TRUE;
}
width = sz.cx;
@ -746,9 +755,9 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
render_op = PictOpOutReverse; /* This gives us 'black' text */
for(idx = 0; idx < count; idx++) {
if(wstr[idx] >= physDev->xrender->cacheEntry->nrealized ||
physDev->xrender->cacheEntry->realized[wstr[idx]] == FALSE) {
UploadGlyph(physDev, wstr[idx]);
if(glyphs[idx] >= physDev->xrender->cacheEntry->nrealized ||
physDev->xrender->cacheEntry->realized[glyphs[idx]] == FALSE) {
UploadGlyph(physDev, glyphs[idx]);
}
}
@ -761,8 +770,8 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
physDev->xrender->pict,
physDev->xrender->cacheEntry->font_format,
physDev->xrender->cacheEntry->glyphset,
0, 0, dc->DCOrgX + x, dc->DCOrgY + y, (unsigned short *)wstr,
count);
0, 0, dc->DCOrgX + x, dc->DCOrgY + y,
glyphs, count);
else {
INT offset = 0, xoff = 0, yoff = 0;
@ -774,7 +783,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
physDev->xrender->cacheEntry->glyphset,
0, 0, dc->DCOrgX + x + xoff,
dc->DCOrgY + y + yoff,
(unsigned short *)wstr + idx, 1);
glyphs + idx, 1);
offset += INTERNAL_XWSTODS(dc, lpDx[idx]);
xoff = offset * cosEsc;
yoff = offset * -sinEsc;
@ -791,6 +800,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
RestoreVisRgn16( hdc );
X11DRV_UnlockDIBSection( physDev, TRUE );
if(glyphs != wstr) HeapFree(GetProcessHeap(), 0, glyphs);
return TRUE;
}

View File

@ -99,6 +99,7 @@ extern DWORD WineEngGetGlyphOutline(GdiFont, UINT glyph, UINT format,
const MAT2*);
extern UINT WineEngGetOutlineTextMetrics(GdiFont, UINT, LPOUTLINETEXTMETRICW);
extern BOOL WineEngGetTextExtentPoint(GdiFont, LPCWSTR, INT, LPSIZE);
extern BOOL WineEngGetTextExtentPointI(GdiFont, const WORD *, INT, LPSIZE);
extern BOOL WineEngGetTextMetrics(GdiFont, LPTEXTMETRICW);
extern BOOL WineEngInit(void);

View File

@ -493,6 +493,58 @@ static inline INT WINE_UNUSED INTERNAL_YWSTODS(DC *dc, INT height)
}
/* Device -> World size conversion */
/* Performs a device to world transformation on the specified width (which
* is in floating point format).
*/
static inline void INTERNAL_XDSTOWS_FLOAT(DC *dc, FLOAT *width)
{
/* Perform the transformation */
*width = *width * dc->xformVport2World.eM11;
}
/* Performs a device to world transformation on the specified width (which
* is in integer format).
*/
static inline INT INTERNAL_XDSTOWS(DC *dc, INT width)
{
FLOAT floatWidth;
/* Perform operation with floating point */
floatWidth = (FLOAT)width;
INTERNAL_XDSTOWS_FLOAT(dc, &floatWidth);
/* Round to integers */
return GDI_ROUND(floatWidth);
}
/* Performs a device to world transformation on the specified size (which
* is in floating point format).
*/
static inline void INTERNAL_YDSTOWS_FLOAT(DC *dc, FLOAT *height)
{
/* Perform the transformation */
*height = *height * dc->xformVport2World.eM22;
}
/* Performs a device to world transformation on the specified size (which
* is in integer format).
*/
static inline INT INTERNAL_YDSTOWS(DC *dc, INT height)
{
FLOAT floatHeight;
/* Perform operation with floating point */
floatHeight = (FLOAT)height;
INTERNAL_YDSTOWS_FLOAT(dc, &floatHeight);
/* Round to integers */
return GDI_ROUND(floatHeight);
}
/* Device <-> logical size conversion */
#define XDSTOLS(dc,x) \

View File

@ -1343,7 +1343,7 @@ typedef struct tagGCP_RESULTSW
UINT *lpOrder;
INT *lpDx;
INT *lpCaretPos;
LPWSTR lpClass;
LPSTR lpClass;
LPWSTR lpGlyphs;
UINT nGlyphs;
UINT nMaxFit;
@ -3270,13 +3270,15 @@ BOOL WINAPI GetTextExtentExPointA(HDC,LPCSTR,INT,INT,
LPINT,LPINT,LPSIZE);
BOOL WINAPI GetTextExtentExPointW(HDC,LPCWSTR,INT,INT,
LPINT,LPINT,LPSIZE);
#define GetTextExtentExPoint WINELIB_NAME_AW(GetTextExtentExPoint)
BOOL WINAPI GetTextExtentPointA(HDC,LPCSTR,INT,LPSIZE);
BOOL WINAPI GetTextExtentPointW(HDC,LPCWSTR,INT,LPSIZE);
#define GetTextExtentPoint WINELIB_NAME_AW(GetTextExtentPoint)
BOOL WINAPI GetTextExtentPoint32A(HDC,LPCSTR,INT,LPSIZE);
BOOL WINAPI GetTextExtentPoint32W(HDC,LPCWSTR,INT,LPSIZE);
#define GetTextExtentPoint32 WINELIB_NAME_AW(GetTextExtentPoint32)
#define GetTextExtentExPoint WINELIB_NAME_AW(GetTextExtentExPoint)
BOOL WINAPI GetTextExtentExPointI(HDC,const WORD*,INT,INT,LPINT,LPINT,LPSIZE);
BOOL WINAPI GetTextExtentPointI(HDC,const WORD*,INT,LPSIZE);
INT WINAPI GetTextFaceA(HDC,INT,LPSTR);
INT WINAPI GetTextFaceW(HDC,INT,LPWSTR);
#define GetTextFace WINELIB_NAME_AW(GetTextFace)

View File

@ -1084,8 +1084,11 @@ BOOL WINAPI GetTextExtentPoint32W(
DC * dc = DC_GetDCPtr( hdc );
if (!dc) return FALSE;
if(dc->gdiFont)
if(dc->gdiFont) {
ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
}
else if(dc->funcs->pGetTextExtentPoint)
ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
@ -1096,6 +1099,42 @@ BOOL WINAPI GetTextExtentPoint32W(
return ret;
}
/***********************************************************************
* GetTextExtentPointI [GDI32.@]
*
* Computes width and height of the array of glyph indices.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI GetTextExtentPointI(
HDC hdc, /* [in] Handle of device context */
const WORD *indices, /* [in] Address of glyph index array */
INT count, /* [in] Number of glyphs in array */
LPSIZE size) /* [out] Address of structure for string size */
{
BOOL ret = FALSE;
DC * dc = DC_GetDCPtr( hdc );
if (!dc) return FALSE;
if(dc->gdiFont) {
ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
}
else if(dc->funcs->pGetTextExtentPoint) {
FIXME("calling GetTextExtentPoint\n");
ret = dc->funcs->pGetTextExtentPoint( dc, (LPCWSTR)indices, count, size );
}
GDI_ReleaseObj( hdc );
TRACE("(%08x %p %d %p): returning %ld x %ld\n",
hdc, indices, count, size, size->cx, size->cy );
return ret;
}
/***********************************************************************
* GetTextExtentPointA (GDI32.@)