Move a bunch of common code from the drivers into gdi.
This commit is contained in:
parent
868921648f
commit
3433676fd7
|
@ -78,7 +78,7 @@ extern BOOL EMFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color,
|
|||
extern INT EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode );
|
||||
extern BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y,
|
||||
UINT flags, const RECT *lprect, LPCWSTR str,
|
||||
UINT count, const INT *lpDx, INT breakExtra );
|
||||
UINT count, const INT *lpDx );
|
||||
extern BOOL EMFDRV_FillPath( PHYSDEV dev );
|
||||
extern BOOL EMFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush );
|
||||
extern BOOL EMFDRV_FlattenPath( PHYSDEV dev );
|
||||
|
|
|
@ -710,7 +710,7 @@ EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
|
|||
*/
|
||||
BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
||||
const RECT *lprect, LPCWSTR str, UINT count,
|
||||
const INT *lpDx, INT breakExtra )
|
||||
const INT *lpDx )
|
||||
{
|
||||
EMREXTTEXTOUTW *pemr;
|
||||
DWORD nSize;
|
||||
|
|
358
dlls/gdi/font.c
358
dlls/gdi/font.c
|
@ -68,6 +68,25 @@ static inline INT INTERNAL_YDSTOWS(DC *dc, INT height)
|
|||
return GDI_ROUND(floatHeight);
|
||||
}
|
||||
|
||||
static inline INT INTERNAL_XWSTODS(DC *dc, INT width)
|
||||
{
|
||||
POINT pt[2];
|
||||
pt[0].x = pt[0].y = 0;
|
||||
pt[1].x = width;
|
||||
pt[1].y = 0;
|
||||
LPtoDP(dc->hSelf, pt, 2);
|
||||
return pt[1].x - pt[0].x;
|
||||
}
|
||||
|
||||
static inline INT INTERNAL_YWSTODS(DC *dc, INT height)
|
||||
{
|
||||
POINT pt[2];
|
||||
pt[0].x = pt[0].y = 0;
|
||||
pt[1].x = 0;
|
||||
pt[1].y = height;
|
||||
LPtoDP(dc->hSelf, pt, 2);
|
||||
return pt[1].y - pt[0].y;
|
||||
}
|
||||
|
||||
static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
|
||||
static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
|
||||
|
@ -1718,39 +1737,320 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
|
|||
const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
LPWSTR reordered_string = (LPWSTR)str;
|
||||
|
||||
LPWSTR reordered_str = (LPWSTR)str;
|
||||
const WORD *glyphs = NULL;
|
||||
UINT align = GetTextAlign( hdc );
|
||||
POINT pt;
|
||||
TEXTMETRICW tm;
|
||||
LOGFONTW lf;
|
||||
double cosEsc, sinEsc;
|
||||
INT *deltas = NULL, char_extra;
|
||||
SIZE sz;
|
||||
RECT rc;
|
||||
BOOL done_extents = FALSE;
|
||||
INT width, xwidth, ywidth;
|
||||
DWORD type;
|
||||
DC * dc = DC_GetDCUpdate( hdc );
|
||||
if (dc)
|
||||
|
||||
if (!dc) return FALSE;
|
||||
|
||||
if (flags & (ETO_NUMERICSLOCAL | ETO_NUMERICSLATIN | ETO_PDY))
|
||||
FIXME("flags ETO_NUMERICSLOCAL | ETO_NUMERICSLATIN | ETO_PDY unimplemented\n");
|
||||
|
||||
if(PATH_IsPathOpen(dc->path))
|
||||
{
|
||||
if (flags&(ETO_NUMERICSLOCAL|ETO_NUMERICSLATIN|ETO_PDY))
|
||||
FIXME("flags ETO_NUMERICSLOCAL|ETO_NUMERICSLATIN|ETO_PDY unimplemented\n");
|
||||
|
||||
if(PATH_IsPathOpen(dc->path))
|
||||
FIXME("called on an open path\n");
|
||||
else if(dc->funcs->pExtTextOut)
|
||||
{
|
||||
if( !(flags&(ETO_GLYPH_INDEX|ETO_IGNORELANGUAGE)) && BidiAvail && count>0 )
|
||||
{
|
||||
/* The caller did not specify that language processing was already done.
|
||||
*/
|
||||
reordered_string = HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
|
||||
|
||||
BIDI_Reorder( str, count, GCP_REORDER,
|
||||
((flags&ETO_RTLREADING)!=0 || (GetTextAlign(hdc)&TA_RTLREADING)!=0)?
|
||||
WINE_GCPW_FORCE_RTL:WINE_GCPW_FORCE_LTR,
|
||||
reordered_string, count, NULL );
|
||||
|
||||
flags |= ETO_IGNORELANGUAGE;
|
||||
}
|
||||
ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags,lprect,reordered_string,count,
|
||||
lpDx,dc->breakExtra);
|
||||
|
||||
if(reordered_string != str)
|
||||
HeapFree(GetProcessHeap(), 0, reordered_string);
|
||||
}
|
||||
FIXME("called on an open path\n");
|
||||
GDI_ReleaseObj( hdc );
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(!dc->funcs->pExtTextOut)
|
||||
{
|
||||
GDI_ReleaseObj( hdc );
|
||||
return ret;
|
||||
}
|
||||
|
||||
type = GetObjectType(hdc);
|
||||
if(type == OBJ_METADC || type == OBJ_ENHMETADC)
|
||||
{
|
||||
ret = dc->funcs->pExtTextOut(dc->physDev, x, y, flags, lprect, str, count, lpDx);
|
||||
GDI_ReleaseObj( hdc );
|
||||
return ret;
|
||||
}
|
||||
|
||||
if( !(flags & (ETO_GLYPH_INDEX | ETO_IGNORELANGUAGE)) && BidiAvail && count > 0 )
|
||||
{
|
||||
reordered_str = HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
|
||||
|
||||
BIDI_Reorder( str, count, GCP_REORDER,
|
||||
((flags&ETO_RTLREADING)!=0 || (GetTextAlign(hdc)&TA_RTLREADING)!=0)?
|
||||
WINE_GCPW_FORCE_RTL:WINE_GCPW_FORCE_LTR,
|
||||
reordered_str, count, NULL );
|
||||
|
||||
flags |= ETO_IGNORELANGUAGE;
|
||||
}
|
||||
|
||||
TRACE("%p, %d, %d, %08x, %p, %s, %d, %p)\n", hdc, x, y, flags,
|
||||
lprect, debugstr_wn(str, count), count, lpDx);
|
||||
|
||||
if(flags & ETO_GLYPH_INDEX)
|
||||
glyphs = (const WORD*)reordered_str;
|
||||
else if(dc->gdiFont)
|
||||
{
|
||||
glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR));
|
||||
GetGlyphIndicesW(hdc, reordered_str, count, (WORD*)glyphs, 0);
|
||||
flags |= ETO_GLYPH_INDEX;
|
||||
}
|
||||
|
||||
if(lprect)
|
||||
TRACE("rect: %ld,%ld - %ld,%ld\n", lprect->left, lprect->top, lprect->right,
|
||||
lprect->bottom);
|
||||
TRACE("align = %x bkmode = %x mapmode = %x\n", align, GetBkMode(hdc), GetMapMode(hdc));
|
||||
|
||||
if(align & TA_UPDATECP)
|
||||
{
|
||||
GetCurrentPositionEx( hdc, &pt );
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
}
|
||||
|
||||
GetTextMetricsW(hdc, &tm);
|
||||
GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf);
|
||||
|
||||
if(!(tm.tmPitchAndFamily & TMPF_VECTOR)) /* Non-scalable fonts shouldn't be rotated */
|
||||
lf.lfEscapement = 0;
|
||||
|
||||
if(lf.lfEscapement != 0)
|
||||
{
|
||||
cosEsc = cos(lf.lfEscapement * M_PI / 1800);
|
||||
sinEsc = sin(lf.lfEscapement * M_PI / 1800);
|
||||
}
|
||||
else
|
||||
{
|
||||
cosEsc = 1;
|
||||
sinEsc = 0;
|
||||
}
|
||||
|
||||
if(flags & (ETO_CLIPPED | ETO_OPAQUE))
|
||||
{
|
||||
if(!lprect)
|
||||
{
|
||||
if(flags & ETO_CLIPPED) goto done;
|
||||
if(flags & ETO_GLYPH_INDEX)
|
||||
GetTextExtentPointI(hdc, glyphs, count, &sz);
|
||||
else
|
||||
GetTextExtentPointW(hdc, reordered_str, count, &sz);
|
||||
|
||||
done_extents = TRUE;
|
||||
rc.left = x;
|
||||
rc.top = y;
|
||||
rc.right = x + sz.cx;
|
||||
rc.bottom = y + sz.cy;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = *lprect;
|
||||
}
|
||||
|
||||
LPtoDP(hdc, (POINT*)&rc, 2);
|
||||
|
||||
if(rc.left > rc.right) {INT tmp = rc.left; rc.left = rc.right; rc.right = tmp;}
|
||||
if(rc.top > rc.bottom) {INT tmp = rc.top; rc.top = rc.bottom; rc.bottom = tmp;}
|
||||
}
|
||||
|
||||
if(flags & ETO_OPAQUE)
|
||||
dc->funcs->pExtTextOut(dc->physDev, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
|
||||
|
||||
if(count == 0)
|
||||
goto done;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
LPtoDP(hdc, &pt, 1);
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
|
||||
char_extra = GetTextCharacterExtra(hdc);
|
||||
width = 0;
|
||||
if(char_extra || dc->breakExtra || lpDx)
|
||||
{
|
||||
UINT i;
|
||||
SIZE tmpsz;
|
||||
deltas = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
if(lpDx)
|
||||
deltas[i] = lpDx[i] + char_extra;
|
||||
else
|
||||
{
|
||||
if(flags & ETO_GLYPH_INDEX)
|
||||
GetTextExtentPointI(hdc, glyphs + i, 1, &tmpsz);
|
||||
else
|
||||
GetTextExtentPointW(hdc, reordered_str + i, 1, &tmpsz);
|
||||
|
||||
deltas[i] = tmpsz.cx;
|
||||
}
|
||||
|
||||
if (dc->breakExtra && reordered_str[i] == tm.tmBreakChar)
|
||||
{
|
||||
deltas[i] = deltas[i] + dc->breakExtra;
|
||||
}
|
||||
deltas[i] = INTERNAL_XWSTODS(dc, deltas[i]);
|
||||
width += deltas[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!done_extents)
|
||||
{
|
||||
if(flags & ETO_GLYPH_INDEX)
|
||||
GetTextExtentPointI(hdc, glyphs, count, &sz);
|
||||
else
|
||||
GetTextExtentPointW(hdc, reordered_str, count, &sz);
|
||||
done_extents = TRUE;
|
||||
}
|
||||
width = INTERNAL_XWSTODS(dc, sz.cx);
|
||||
}
|
||||
xwidth = width * cosEsc;
|
||||
ywidth = width * sinEsc;
|
||||
|
||||
tm.tmAscent = abs(INTERNAL_YWSTODS(dc, tm.tmAscent));
|
||||
tm.tmDescent = abs(INTERNAL_YWSTODS(dc, tm.tmDescent));
|
||||
switch( align & (TA_LEFT | TA_RIGHT | TA_CENTER) )
|
||||
{
|
||||
case TA_LEFT:
|
||||
if (align & TA_UPDATECP)
|
||||
{
|
||||
pt.x = x + xwidth;
|
||||
pt.y = y - ywidth;
|
||||
DPtoLP(hdc, &pt, 1);
|
||||
MoveToEx(hdc, pt.x, pt.y, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case TA_CENTER:
|
||||
x -= xwidth / 2;
|
||||
y += ywidth / 2;
|
||||
break;
|
||||
|
||||
case TA_RIGHT:
|
||||
x -= xwidth;
|
||||
y += ywidth;
|
||||
if (align & TA_UPDATECP)
|
||||
{
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
DPtoLP(hdc, &pt, 1);
|
||||
MoveToEx(hdc, pt.x, pt.y, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch( align & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
|
||||
{
|
||||
case TA_TOP:
|
||||
y += tm.tmAscent * cosEsc;
|
||||
x += tm.tmAscent * sinEsc;
|
||||
break;
|
||||
|
||||
case TA_BOTTOM:
|
||||
y -= tm.tmDescent * cosEsc;
|
||||
x -= tm.tmDescent * sinEsc;
|
||||
break;
|
||||
|
||||
case TA_BASELINE:
|
||||
break;
|
||||
}
|
||||
|
||||
if(GetBkMode(hdc) != TRANSPARENT)
|
||||
{
|
||||
if(!((flags & ETO_CLIPPED) && (flags & ETO_OPAQUE)))
|
||||
{
|
||||
if(!(flags & ETO_OPAQUE) || x < rc.left || x + width >= rc.right ||
|
||||
y - tm.tmAscent < rc.top || y + tm.tmDescent >= rc.bottom)
|
||||
{
|
||||
RECT rc;
|
||||
rc.left = x;
|
||||
rc.right = x + width;
|
||||
rc.top = y - tm.tmAscent;
|
||||
rc.bottom = y + tm.tmDescent;
|
||||
dc->funcs->pExtTextOut(dc->physDev, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = dc->funcs->pExtTextOut(dc->physDev, x, y, (flags & ~ETO_OPAQUE), &rc,
|
||||
(flags & ETO_GLYPH_INDEX) ? glyphs: reordered_str, count, deltas);
|
||||
|
||||
if (lf.lfUnderline || lf.lfStrikeOut)
|
||||
{
|
||||
int underlinePos, strikeoutPos;
|
||||
int underlineWidth, strikeoutWidth;
|
||||
UINT nMetricsSize = GetOutlineTextMetricsW(hdc, 0, NULL);
|
||||
OUTLINETEXTMETRICW* otm = NULL;
|
||||
|
||||
if(!nMetricsSize)
|
||||
{
|
||||
TEXTMETRICW tm;
|
||||
GetTextMetricsW(hdc, &tm);
|
||||
underlinePos = 0;
|
||||
underlineWidth = tm.tmAscent / 20 + 1;
|
||||
strikeoutPos = tm.tmAscent / 2;
|
||||
strikeoutWidth = underlineWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
otm = HeapAlloc(GetProcessHeap(), 0, nMetricsSize);
|
||||
if (!otm) goto done;
|
||||
|
||||
GetOutlineTextMetricsW(hdc, nMetricsSize, otm);
|
||||
underlinePos = otm->otmsUnderscorePosition;
|
||||
underlineWidth = otm->otmsUnderscoreSize;
|
||||
strikeoutPos = otm->otmsStrikeoutPosition;
|
||||
strikeoutWidth = otm->otmsStrikeoutSize;
|
||||
}
|
||||
|
||||
if(lf.lfUnderline)
|
||||
{
|
||||
POINT pts[2], oldpt;
|
||||
HPEN hpen = CreatePen(PS_SOLID, underlineWidth, dc->textColor);
|
||||
hpen = SelectObject(hdc, hpen);
|
||||
pts[0].x = x;
|
||||
pts[0].y = y;
|
||||
pts[1].x = x + xwidth;
|
||||
pts[1].y = y - ywidth;
|
||||
DPtoLP(hdc, pts, 2);
|
||||
MoveToEx(hdc, pts[0].x - underlinePos * sinEsc, pts[0].y - underlinePos * cosEsc, &oldpt);
|
||||
LineTo(hdc, pts[1].x - underlinePos * sinEsc, pts[1].y - underlinePos * cosEsc);
|
||||
MoveToEx(hdc, oldpt.x, oldpt.y, NULL);
|
||||
DeleteObject(SelectObject(hdc, hpen));
|
||||
}
|
||||
|
||||
if(lf.lfStrikeOut)
|
||||
{
|
||||
POINT pts[2], oldpt;
|
||||
HPEN hpen = CreatePen(PS_SOLID, strikeoutWidth, dc->textColor);
|
||||
hpen = SelectObject(hdc, hpen);
|
||||
pts[0].x = x;
|
||||
pts[0].y = y;
|
||||
pts[1].x = x + xwidth;
|
||||
pts[1].y = y - ywidth;
|
||||
DPtoLP(hdc, pts, 2);
|
||||
MoveToEx(hdc, pts[0].x - strikeoutPos * sinEsc, pts[0].y - strikeoutPos * cosEsc, &oldpt);
|
||||
LineTo(hdc, pts[1].x - strikeoutPos * sinEsc, pts[1].y - strikeoutPos * cosEsc);
|
||||
MoveToEx(hdc, oldpt.x, oldpt.y, NULL);
|
||||
DeleteObject(SelectObject(hdc, hpen));
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
HeapFree(GetProcessHeap(), 0, deltas);
|
||||
if(glyphs && glyphs != reordered_str)
|
||||
HeapFree(GetProcessHeap(), 0, (WORD*)glyphs);
|
||||
if(reordered_str != str)
|
||||
HeapFree(GetProcessHeap(), 0, reordered_str);
|
||||
|
||||
GDI_ReleaseObj( hdc );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ typedef struct tagDC_FUNCS
|
|||
INT (*pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID);
|
||||
BOOL (*pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
|
||||
INT (*pExtSelectClipRgn)(PHYSDEV,HRGN,INT);
|
||||
BOOL (*pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*,INT);
|
||||
BOOL (*pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
|
||||
BOOL (*pFillPath)(PHYSDEV);
|
||||
BOOL (*pFillRgn)(PHYSDEV,HRGN,HBRUSH);
|
||||
BOOL (*pFlattenPath)(PHYSDEV);
|
||||
|
|
|
@ -84,7 +84,7 @@ extern BOOL MFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT
|
|||
extern INT MFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode );
|
||||
extern BOOL MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y,
|
||||
UINT flags, const RECT *lprect, LPCWSTR str,
|
||||
UINT count, const INT *lpDx, INT breakExtra );
|
||||
UINT count, const INT *lpDx );
|
||||
extern BOOL MFDRV_FillPath( PHYSDEV dev );
|
||||
extern BOOL MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush );
|
||||
extern BOOL MFDRV_FlattenPath( PHYSDEV dev );
|
||||
|
|
|
@ -74,7 +74,7 @@ static BOOL MFDRV_MetaExtTextOut( PHYSDEV dev, short x, short y, UINT16 flags,
|
|||
BOOL
|
||||
MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
||||
const RECT *lprect, LPCWSTR str, UINT count,
|
||||
const INT *lpDx, INT breakExtra )
|
||||
const INT *lpDx )
|
||||
{
|
||||
RECT16 rect16;
|
||||
LPINT16 lpdx16 = NULL;
|
||||
|
|
|
@ -338,14 +338,12 @@ BOOL TTYDRV_DC_StretchBlt(TTYDRV_PDEVICE *physDevDst, INT xDst, INT yDst,
|
|||
*/
|
||||
BOOL TTYDRV_DC_ExtTextOut(TTYDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||
const RECT *lpRect, LPCWSTR str, UINT count,
|
||||
const INT *lpDx, INT breakExtra )
|
||||
const INT *lpDx )
|
||||
{
|
||||
#ifdef WINE_CURSES
|
||||
INT row, col;
|
||||
LPSTR ascii;
|
||||
DWORD len;
|
||||
POINT pt;
|
||||
UINT text_align = GetTextAlign( physDev->hdc );
|
||||
|
||||
TRACE("(%p, %d, %d, 0x%08x, %p, %s, %d, %p)\n",
|
||||
physDev->hdc, x, y, flags, lpRect, debugstr_wn(str, count), count, lpDx);
|
||||
|
@ -353,14 +351,8 @@ BOOL TTYDRV_DC_ExtTextOut(TTYDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
|||
if(!physDev->window)
|
||||
return FALSE;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
/* FIXME: Is this really correct? */
|
||||
if(text_align & TA_UPDATECP) GetCurrentPositionEx( physDev->hdc, &pt );
|
||||
|
||||
LPtoDP( physDev->hdc, &pt, 1 );
|
||||
row = (physDev->org.y + pt.y) / physDev->cellHeight;
|
||||
col = (physDev->org.x + pt.x) / physDev->cellWidth;
|
||||
row = (physDev->org.y + y) / physDev->cellHeight;
|
||||
col = (physDev->org.x + x) / physDev->cellWidth;
|
||||
len = WideCharToMultiByte( CP_ACP, 0, str, count, NULL, 0, NULL, NULL );
|
||||
ascii = HeapAlloc( GetProcessHeap(), 0, len );
|
||||
WideCharToMultiByte( CP_ACP, 0, str, count, ascii, len, NULL, NULL );
|
||||
|
@ -368,14 +360,6 @@ BOOL TTYDRV_DC_ExtTextOut(TTYDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
|||
HeapFree( GetProcessHeap(), 0, ascii );
|
||||
wrefresh(physDev->window);
|
||||
|
||||
if(text_align & TA_UPDATECP)
|
||||
{
|
||||
pt.x += count * physDev->cellWidth;
|
||||
pt.y += physDev->cellHeight;
|
||||
DPtoLP( physDev->hdc, &pt, 1 );
|
||||
MoveToEx( physDev->hdc, pt.x, pt.y, NULL );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#else /* defined(WINE_CURSES) */
|
||||
FIXME("(%p, %d, %d, 0x%08x, %p, %s, %d, %p): stub\n",
|
||||
|
|
|
@ -76,7 +76,7 @@ extern BOOL TTYDRV_DC_BitBlt(TTYDRV_PDEVICE *physDevDst, INT xDst, INT yDst, INT
|
|||
extern BOOL TTYDRV_DC_Chord(TTYDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
|
||||
extern BOOL TTYDRV_DC_Ellipse(TTYDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom);
|
||||
extern BOOL TTYDRV_DC_ExtFloodFill(TTYDRV_PDEVICE *physDev, INT x, INT y, COLORREF color, UINT fillType);
|
||||
extern BOOL TTYDRV_DC_ExtTextOut(TTYDRV_PDEVICE *physDev, INT x, INT y, UINT flags, const RECT *lpRect, LPCWSTR str, UINT count, const INT *lpDx, INT breakExtra);
|
||||
extern BOOL TTYDRV_DC_ExtTextOut(TTYDRV_PDEVICE *physDev, INT x, INT y, UINT flags, const RECT *lpRect, LPCWSTR str, UINT count, const INT *lpDx);
|
||||
extern BOOL TTYDRV_DC_GetCharWidth(TTYDRV_PDEVICE *physDev, UINT firstChar, UINT lastChar, LPINT buffer);
|
||||
extern COLORREF TTYDRV_DC_GetPixel(TTYDRV_PDEVICE *physDev, INT x, INT y);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
@ cdecl Ellipse(ptr long long long long) TTYDRV_DC_Ellipse
|
||||
@ cdecl ExtEscape(ptr long long ptr long ptr) TTYDRV_ExtEscape
|
||||
@ cdecl ExtFloodFill(ptr long long long long) TTYDRV_DC_ExtFloodFill
|
||||
@ cdecl ExtTextOut(ptr long long long ptr ptr long ptr long) TTYDRV_DC_ExtTextOut
|
||||
@ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) TTYDRV_DC_ExtTextOut
|
||||
@ cdecl GetBitmapBits(long ptr long) TTYDRV_GetBitmapBits
|
||||
@ cdecl GetCharWidth(ptr long long ptr) TTYDRV_DC_GetCharWidth
|
||||
@ cdecl GetDCOrgEx(ptr ptr) TTYDRV_GetDCOrgEx
|
||||
|
|
|
@ -469,7 +469,7 @@ extern INT PSDRV_EndDoc( PSDRV_PDEVICE *physDev );
|
|||
extern INT PSDRV_EndPage( PSDRV_PDEVICE *physDev );
|
||||
extern BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||
const RECT *lprect, LPCWSTR str, UINT count,
|
||||
const INT *lpDx, INT breakExtra );
|
||||
const INT *lpDx );
|
||||
extern BOOL PSDRV_GetCharWidth( PSDRV_PDEVICE *physDev, UINT firstChar, UINT lastChar,
|
||||
LPINT buffer );
|
||||
extern BOOL PSDRV_GetTextExtentPoint( PSDRV_PDEVICE *physDev, LPCWSTR str, INT count,
|
||||
|
|
|
@ -40,12 +40,11 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
|||
*/
|
||||
BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||
const RECT *lprect, LPCWSTR str, UINT count,
|
||||
const INT *lpDx, INT breakExtra )
|
||||
const INT *lpDx )
|
||||
{
|
||||
BOOL bResult = TRUE;
|
||||
BOOL bClipped = FALSE;
|
||||
BOOL bOpaque = FALSE;
|
||||
RECT rect;
|
||||
|
||||
TRACE("(x=%d, y=%d, flags=0x%08x, str=%s, count=%d, lpDx=%p)\n", x, y,
|
||||
flags, debugstr_wn(str, count), count, lpDx);
|
||||
|
@ -58,11 +57,9 @@ BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
|||
/* set clipping and/or draw background */
|
||||
if ((flags & (ETO_CLIPPED | ETO_OPAQUE)) && (lprect != NULL))
|
||||
{
|
||||
rect = *lprect;
|
||||
LPtoDP( physDev->hdc, (POINT *)&rect, 2 );
|
||||
PSDRV_WriteGSave(physDev);
|
||||
PSDRV_WriteRectangle(physDev, rect.left, rect.top, rect.right - rect.left,
|
||||
rect.bottom - rect.top);
|
||||
PSDRV_WriteRectangle(physDev, lprect->left, lprect->top, lprect->right - lprect->left,
|
||||
lprect->bottom - lprect->top);
|
||||
|
||||
if (flags & ETO_OPAQUE)
|
||||
{
|
||||
|
@ -97,14 +94,7 @@ BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
|||
static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, LPCWSTR str,
|
||||
UINT count, BOOL bDrawBackground, const INT *lpDx)
|
||||
{
|
||||
SIZE sz;
|
||||
TEXTMETRICW tm;
|
||||
POINT pt;
|
||||
INT ascent, descent;
|
||||
WORD *glyphs = NULL;
|
||||
UINT align = GetTextAlign( physDev->hdc );
|
||||
INT char_extra;
|
||||
INT *deltas = NULL;
|
||||
double cosEsc, sinEsc;
|
||||
LOGFONTW lf;
|
||||
|
||||
|
@ -120,127 +110,12 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, LPCWSTR
|
|||
sinEsc = 0;
|
||||
}
|
||||
|
||||
if(physDev->font.fontloc == Download) {
|
||||
if(flags & ETO_GLYPH_INDEX)
|
||||
glyphs = (LPWORD)str;
|
||||
else {
|
||||
glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WORD));
|
||||
GetGlyphIndicesW(physDev->hdc, str, count, glyphs, 0);
|
||||
}
|
||||
}
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
if(align & TA_UPDATECP) GetCurrentPositionEx( physDev->hdc, &pt );
|
||||
LPtoDP(physDev->hdc, &pt, 1);
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
|
||||
if(physDev->font.fontloc == Download)
|
||||
GetTextExtentPointI(physDev->hdc, glyphs, count, &sz);
|
||||
else
|
||||
GetTextExtentPoint32W(physDev->hdc, str, count, &sz);
|
||||
|
||||
if((char_extra = GetTextCharacterExtra(physDev->hdc)) != 0) {
|
||||
UINT i;
|
||||
SIZE tmpsz;
|
||||
|
||||
deltas = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
|
||||
for(i = 0; i < count; i++) {
|
||||
if(lpDx)
|
||||
deltas[i] = lpDx[i] + char_extra;
|
||||
else {
|
||||
if(physDev->font.fontloc == Download)
|
||||
GetTextExtentPointI(physDev->hdc, glyphs + i, 1, &tmpsz);
|
||||
else
|
||||
GetTextExtentPoint32W(physDev->hdc, str + i, 1, &tmpsz);
|
||||
deltas[i] = tmpsz.cx;
|
||||
}
|
||||
}
|
||||
} else if(lpDx)
|
||||
deltas = (INT*)lpDx;
|
||||
|
||||
if(deltas) {
|
||||
SIZE tmpsz;
|
||||
UINT i;
|
||||
/* Get the width of the last char and add on all the offsets */
|
||||
if(physDev->font.fontloc == Download)
|
||||
GetTextExtentPointI(physDev->hdc, glyphs + count - 1, 1, &tmpsz);
|
||||
else
|
||||
GetTextExtentPoint32W(physDev->hdc, str + count - 1, 1, &tmpsz);
|
||||
for(i = 0; i < count-1; i++)
|
||||
tmpsz.cx += deltas[i];
|
||||
sz.cx = tmpsz.cx; /* sz.cy remains untouched */
|
||||
}
|
||||
|
||||
sz.cx = PSDRV_XWStoDS(physDev, sz.cx);
|
||||
sz.cy = PSDRV_YWStoDS(physDev, sz.cy);
|
||||
|
||||
GetTextMetricsW(physDev->hdc, &tm);
|
||||
ascent = abs(PSDRV_YWStoDS(physDev, tm.tmAscent));
|
||||
descent = abs(PSDRV_YWStoDS(physDev, tm.tmDescent));
|
||||
|
||||
TRACE("textAlign = %x\n", align);
|
||||
switch(align & (TA_LEFT | TA_CENTER | TA_RIGHT) ) {
|
||||
case TA_LEFT:
|
||||
if(align & TA_UPDATECP)
|
||||
{
|
||||
POINT pt;
|
||||
pt.x = x + sz.cx * cosEsc;
|
||||
pt.y = y - sz.cx * sinEsc;
|
||||
DPtoLP( physDev->hdc, &pt, 1 );
|
||||
MoveToEx( physDev->hdc, pt.x, pt.y, NULL );
|
||||
}
|
||||
break;
|
||||
|
||||
case TA_CENTER:
|
||||
x -= sz.cx * cosEsc / 2;
|
||||
y += sz.cx * sinEsc / 2;
|
||||
break;
|
||||
|
||||
case TA_RIGHT:
|
||||
x -= sz.cx * cosEsc;
|
||||
y += sz.cx * sinEsc;
|
||||
if(align & TA_UPDATECP)
|
||||
{
|
||||
POINT pt;
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
DPtoLP( physDev->hdc, &pt, 1 );
|
||||
MoveToEx( physDev->hdc, pt.x, pt.y, NULL );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch(align & (TA_TOP | TA_BASELINE | TA_BOTTOM) ) {
|
||||
case TA_TOP:
|
||||
y += ascent * cosEsc;
|
||||
x += ascent * sinEsc;
|
||||
break;
|
||||
|
||||
case TA_BASELINE:
|
||||
break;
|
||||
|
||||
case TA_BOTTOM:
|
||||
y -= descent * cosEsc;
|
||||
x -= descent * sinEsc;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((GetBkMode( physDev->hdc ) != TRANSPARENT) && bDrawBackground)
|
||||
{
|
||||
PSDRV_WriteGSave(physDev);
|
||||
PSDRV_WriteNewPath(physDev);
|
||||
PSDRV_WriteRectangle(physDev, x, y - ascent, sz.cx,
|
||||
ascent + descent);
|
||||
PSDRV_WriteSetColor(physDev, &physDev->bkColor);
|
||||
PSDRV_WriteFill(physDev);
|
||||
PSDRV_WriteGRestore(physDev);
|
||||
}
|
||||
glyphs = (LPWORD)str;
|
||||
|
||||
PSDRV_WriteMoveTo(physDev, x, y);
|
||||
|
||||
if(!deltas) {
|
||||
if(!lpDx) {
|
||||
if(physDev->font.fontloc == Download)
|
||||
PSDRV_WriteDownloadGlyphShow(physDev, glyphs, count);
|
||||
else
|
||||
|
@ -252,87 +127,20 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, LPCWSTR
|
|||
float cos_theta = cos(physDev->font.escapement * M_PI / 1800.0);
|
||||
float sin_theta = sin(physDev->font.escapement * M_PI / 1800.0);
|
||||
for(i = 0; i < count-1; i++) {
|
||||
TRACE("lpDx[%d] = %d\n", i, deltas[i]);
|
||||
TRACE("lpDx[%d] = %d\n", i, lpDx[i]);
|
||||
if(physDev->font.fontloc == Download)
|
||||
PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
|
||||
else
|
||||
PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
|
||||
dx += deltas[i] * cos_theta;
|
||||
dy -= deltas[i] * sin_theta;
|
||||
PSDRV_WriteMoveTo(physDev, x + PSDRV_XWStoDS(physDev, dx),
|
||||
y + PSDRV_YWStoDS(physDev, dy));
|
||||
dx += lpDx[i] * cos_theta;
|
||||
dy -= lpDx[i] * sin_theta;
|
||||
PSDRV_WriteMoveTo(physDev, x + dx, y + dy);
|
||||
}
|
||||
if(physDev->font.fontloc == Download)
|
||||
PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
|
||||
else
|
||||
PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
|
||||
if(deltas != lpDx)
|
||||
HeapFree(GetProcessHeap(), 0, deltas);
|
||||
}
|
||||
|
||||
/*
|
||||
* Underline and strikeout attributes.
|
||||
*/
|
||||
if ((tm.tmUnderlined) || (tm.tmStruckOut)) {
|
||||
|
||||
/* Get the thickness and the position for the underline attribute */
|
||||
/* We'll use the same thickness for the strikeout attribute */
|
||||
|
||||
INT escapement = physDev->font.escapement;
|
||||
|
||||
/* Do the underline */
|
||||
|
||||
if (tm.tmUnderlined) {
|
||||
PSDRV_WriteNewPath(physDev); /* will be closed by WriteRectangle */
|
||||
if (escapement != 0) /* rotated text */
|
||||
{
|
||||
PSDRV_WriteGSave(physDev); /* save the graphics state */
|
||||
PSDRV_WriteMoveTo(physDev, x, y); /* move to the start */
|
||||
|
||||
/* temporarily rotate the coord system */
|
||||
PSDRV_WriteRotate(physDev, -escapement/10);
|
||||
|
||||
/* draw the underline relative to the starting point */
|
||||
PSDRV_WriteRRectangle(physDev, 0, -physDev->font.underlinePosition,
|
||||
sz.cx, physDev->font.underlineThickness);
|
||||
}
|
||||
else
|
||||
PSDRV_WriteRectangle(physDev, x, y - physDev->font.underlinePosition,
|
||||
sz.cx, physDev->font.underlineThickness);
|
||||
|
||||
PSDRV_WriteFill(physDev);
|
||||
|
||||
if (escapement != 0) /* rotated text */
|
||||
PSDRV_WriteGRestore(physDev); /* restore the graphics state */
|
||||
}
|
||||
|
||||
/* Do the strikeout */
|
||||
|
||||
if (tm.tmStruckOut) {
|
||||
PSDRV_WriteNewPath(physDev); /* will be closed by WriteRectangle */
|
||||
if (escapement != 0) /* rotated text */
|
||||
{
|
||||
PSDRV_WriteGSave(physDev); /* save the graphics state */
|
||||
PSDRV_WriteMoveTo(physDev, x, y); /* move to the start */
|
||||
|
||||
/* temporarily rotate the coord system */
|
||||
PSDRV_WriteRotate(physDev, -escapement/10);
|
||||
|
||||
/* draw the line relative to the starting point */
|
||||
PSDRV_WriteRRectangle(physDev, 0, -physDev->font.strikeoutPosition,
|
||||
sz.cx, physDev->font.strikeoutThickness);
|
||||
}
|
||||
else
|
||||
PSDRV_WriteRectangle(physDev, x, y - physDev->font.strikeoutPosition,
|
||||
sz.cx, physDev->font.strikeoutThickness);
|
||||
|
||||
PSDRV_WriteFill(physDev);
|
||||
|
||||
if (escapement != 0) /* rotated text */
|
||||
PSDRV_WriteGRestore(physDev); /* restore the graphics state */
|
||||
}
|
||||
}
|
||||
|
||||
if(glyphs && glyphs != str) HeapFree(GetProcessHeap(), 0, glyphs);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
@ cdecl EnumDeviceFonts(ptr ptr ptr long) PSDRV_EnumDeviceFonts
|
||||
@ cdecl ExtDeviceMode(ptr long ptr ptr ptr ptr ptr long) PSDRV_ExtDeviceMode
|
||||
@ cdecl ExtEscape(ptr long long ptr long ptr) PSDRV_ExtEscape
|
||||
@ cdecl ExtTextOut(ptr long long long ptr ptr long ptr long) PSDRV_ExtTextOut
|
||||
@ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) PSDRV_ExtTextOut
|
||||
@ cdecl GetCharWidth(ptr long long ptr) PSDRV_GetCharWidth
|
||||
@ cdecl GetDeviceCaps(ptr long) PSDRV_GetDeviceCaps
|
||||
@ cdecl GetTextExtentPoint(ptr ptr long ptr) PSDRV_GetTextExtentPoint
|
||||
|
|
|
@ -42,93 +42,36 @@ WINE_DEFAULT_DEBUG_CHANNEL(text);
|
|||
BOOL
|
||||
X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||
const RECT *lprect, LPCWSTR wstr, UINT count,
|
||||
const INT *lpDx, INT breakExtra )
|
||||
const INT *lpDx )
|
||||
{
|
||||
unsigned int i;
|
||||
fontObject* pfo;
|
||||
INT width, ascent, descent, xwidth, ywidth;
|
||||
XFontStruct* font;
|
||||
RECT rect;
|
||||
char dfBreakChar, lfUnderline, lfStrikeOut;
|
||||
BOOL rotated = FALSE;
|
||||
XChar2b *str2b = NULL;
|
||||
BOOL dibUpdateFlag = FALSE;
|
||||
BOOL result = TRUE;
|
||||
HRGN saved_region = 0;
|
||||
POINT pt;
|
||||
UINT align;
|
||||
INT charExtra;
|
||||
|
||||
if(physDev->has_gdi_font)
|
||||
return X11DRV_XRender_ExtTextOut(physDev, x, y, flags, lprect, wstr, count, lpDx, breakExtra);
|
||||
return X11DRV_XRender_ExtTextOut(physDev, x, y, flags, lprect, wstr, count, lpDx);
|
||||
|
||||
if (!X11DRV_SetupGCForText( physDev )) return TRUE;
|
||||
|
||||
align = GetTextAlign( physDev->hdc );
|
||||
charExtra = GetTextCharacterExtra( physDev->hdc );
|
||||
|
||||
pfo = XFONT_GetFontObject( physDev->font );
|
||||
font = pfo->fs;
|
||||
|
||||
if (pfo->lf.lfEscapement && pfo->lpX11Trans)
|
||||
rotated = TRUE;
|
||||
dfBreakChar = (char)pfo->fi->df.dfBreakChar;
|
||||
lfUnderline = (pfo->fo_flags & FO_SYNTH_UNDERLINE) ? 1 : 0;
|
||||
lfStrikeOut = (pfo->fo_flags & FO_SYNTH_STRIKEOUT) ? 1 : 0;
|
||||
|
||||
TRACE("hdc=%p df=%04x %d,%d %s, %d flags=%d lpDx=%p\n",
|
||||
physDev->hdc, (UINT16)(physDev->font), x, y,
|
||||
debugstr_wn (wstr, count), count, flags, lpDx);
|
||||
|
||||
/* some strings sent here end in a newline for whatever reason. I have no
|
||||
clue what the right treatment should be in general, but ignoring
|
||||
terminating newlines seems ok. MW, April 1998. */
|
||||
if (count > 0 && wstr[count - 1] == '\n') count--;
|
||||
|
||||
if (lprect != NULL) TRACE("\trect=(%ld,%ld - %ld,%ld)\n",
|
||||
lprect->left, lprect->top,
|
||||
lprect->right, lprect->bottom );
|
||||
/* Setup coordinates */
|
||||
|
||||
if (align & TA_UPDATECP)
|
||||
{
|
||||
GetCurrentPositionEx( physDev->hdc, &pt );
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
}
|
||||
|
||||
if (flags & (ETO_OPAQUE | ETO_CLIPPED)) /* there's a rectangle */
|
||||
{
|
||||
if (!lprect) /* not always */
|
||||
{
|
||||
SIZE sz;
|
||||
if (flags & ETO_CLIPPED) /* Can't clip with no rectangle */
|
||||
return FALSE;
|
||||
if (!X11DRV_GetTextExtentPoint( physDev, wstr, count, &sz ))
|
||||
return FALSE;
|
||||
rect.left = x;
|
||||
rect.right = x + sz.cx;
|
||||
rect.top = y;
|
||||
rect.bottom = y + sz.cy;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect = *lprect;
|
||||
}
|
||||
LPtoDP(physDev->hdc, (POINT*)&rect, 2);
|
||||
|
||||
if (rect.right < rect.left) SWAP_INT( rect.left, rect.right );
|
||||
if (rect.bottom < rect.top) SWAP_INT( rect.top, rect.bottom );
|
||||
}
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
LPtoDP(physDev->hdc, &pt, 1);
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
|
||||
TRACE("\treal coord: x=%i, y=%i, rect=(%ld,%ld - %ld,%ld)\n",
|
||||
x, y, rect.left, rect.top, rect.right, rect.bottom);
|
||||
|
||||
/* Draw the rectangle */
|
||||
|
||||
|
@ -145,83 +88,14 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
|||
}
|
||||
if (!count) goto END; /* Nothing more to do */
|
||||
|
||||
/* Compute text starting position */
|
||||
|
||||
if (lpDx) /* have explicit character cell x offsets in logical coordinates */
|
||||
{
|
||||
for (i = width = 0; i < count; i++) width += lpDx[i];
|
||||
width = X11DRV_XWStoDS(physDev, width);
|
||||
}
|
||||
else
|
||||
{
|
||||
SIZE sz;
|
||||
if (!X11DRV_GetTextExtentPoint( physDev, wstr, count, &sz ))
|
||||
{
|
||||
result = FALSE;
|
||||
goto END;
|
||||
}
|
||||
width = X11DRV_XWStoDS(physDev, sz.cx);
|
||||
}
|
||||
ascent = pfo->lpX11Trans ? pfo->lpX11Trans->ascent : font->ascent;
|
||||
descent = pfo->lpX11Trans ? pfo->lpX11Trans->descent : font->descent;
|
||||
xwidth = pfo->lpX11Trans ? width * pfo->lpX11Trans->a /
|
||||
pfo->lpX11Trans->pixelsize : width;
|
||||
ywidth = pfo->lpX11Trans ? width * pfo->lpX11Trans->b /
|
||||
pfo->lpX11Trans->pixelsize : 0;
|
||||
|
||||
switch( align & (TA_LEFT | TA_RIGHT | TA_CENTER) )
|
||||
{
|
||||
case TA_LEFT:
|
||||
if (align & TA_UPDATECP) {
|
||||
pt.x = x + xwidth;
|
||||
pt.y = y - ywidth;
|
||||
DPtoLP(physDev->hdc, &pt, 1);
|
||||
MoveToEx(physDev->hdc, pt.x, pt.y, NULL);
|
||||
}
|
||||
break;
|
||||
case TA_RIGHT:
|
||||
x -= xwidth;
|
||||
y += ywidth;
|
||||
if (align & TA_UPDATECP) {
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
DPtoLP(physDev->hdc, &pt, 1);
|
||||
MoveToEx(physDev->hdc, pt.x, pt.y, NULL);
|
||||
}
|
||||
break;
|
||||
case TA_CENTER:
|
||||
x -= xwidth / 2;
|
||||
y += ywidth / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
switch( align & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
|
||||
{
|
||||
case TA_TOP:
|
||||
x -= pfo->lpX11Trans ? ascent * pfo->lpX11Trans->c /
|
||||
pfo->lpX11Trans->pixelsize : 0;
|
||||
y += pfo->lpX11Trans ? ascent * pfo->lpX11Trans->d /
|
||||
pfo->lpX11Trans->pixelsize : ascent;
|
||||
break;
|
||||
case TA_BOTTOM:
|
||||
x += pfo->lpX11Trans ? descent * pfo->lpX11Trans->c /
|
||||
pfo->lpX11Trans->pixelsize : 0;
|
||||
y -= pfo->lpX11Trans ? descent * pfo->lpX11Trans->d /
|
||||
pfo->lpX11Trans->pixelsize : descent;
|
||||
break;
|
||||
case TA_BASELINE:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the clip region */
|
||||
|
||||
if (flags & ETO_CLIPPED)
|
||||
{
|
||||
HRGN clip_region;
|
||||
RECT clip_rect = *lprect;
|
||||
|
||||
LPtoDP( physDev->hdc, (POINT *)&clip_rect, 2 );
|
||||
clip_region = CreateRectRgnIndirect( &clip_rect );
|
||||
clip_region = CreateRectRgnIndirect( lprect );
|
||||
/* make a copy of the current device region */
|
||||
saved_region = CreateRectRgn( 0, 0, 0, 0 );
|
||||
CombineRgn( saved_region, physDev->region, 0, RGN_COPY );
|
||||
|
@ -237,28 +111,6 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
|||
dibUpdateFlag = TRUE;
|
||||
}
|
||||
|
||||
if (GetBkMode( physDev->hdc ) != TRANSPARENT)
|
||||
{
|
||||
/* If rectangle is opaque and clipped, do nothing */
|
||||
if (!(flags & ETO_CLIPPED) || !(flags & ETO_OPAQUE))
|
||||
{
|
||||
/* Only draw if rectangle is not opaque or if some */
|
||||
/* text is outside the rectangle */
|
||||
if (!(flags & ETO_OPAQUE) ||
|
||||
(x < rect.left) ||
|
||||
(x + width >= rect.right) ||
|
||||
(y - ascent < rect.top) ||
|
||||
(y + descent >= rect.bottom))
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
XSetForeground( gdi_display, physDev->gc, physDev->backgroundPixel );
|
||||
XFillRectangle( gdi_display, physDev->drawable, physDev->gc,
|
||||
physDev->org.x + x, physDev->org.y + y - ascent,
|
||||
width, ascent + descent );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the text (count > 0 verified) */
|
||||
if (!(str2b = X11DRV_cptable[pfo->fi->cptable].punicode_to_char2b( pfo, wstr, count )))
|
||||
|
@ -269,155 +121,68 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
|||
wine_tsx11_unlock();
|
||||
if(!rotated)
|
||||
{
|
||||
if (!charExtra && !breakExtra && !lpDx)
|
||||
{
|
||||
X11DRV_cptable[pfo->fi->cptable].pDrawString(
|
||||
pfo, gdi_display, physDev->drawable, physDev->gc,
|
||||
physDev->org.x + x, physDev->org.y + y, str2b, count );
|
||||
}
|
||||
else /* Now the fun begins... */
|
||||
{
|
||||
XTextItem16 *items, *pitem;
|
||||
int delta;
|
||||
|
||||
/* allocate max items */
|
||||
|
||||
pitem = items = HeapAlloc( GetProcessHeap(), 0,
|
||||
count * sizeof(XTextItem16) );
|
||||
if(items == NULL) goto FAIL;
|
||||
delta = i = 0;
|
||||
if( lpDx ) /* explicit character widths */
|
||||
{
|
||||
long ve_we;
|
||||
unsigned short err = 0;
|
||||
|
||||
ve_we = X11DRV_XWStoDS( physDev, 0x10000 );
|
||||
|
||||
while (i < count)
|
||||
{
|
||||
/* initialize text item with accumulated delta */
|
||||
|
||||
long sum;
|
||||
long fSum;
|
||||
sum = 0;
|
||||
pitem->chars = str2b + i;
|
||||
pitem->delta = delta;
|
||||
pitem->nchars = 0;
|
||||
pitem->font = None;
|
||||
delta = 0;
|
||||
|
||||
/* add characters to the same XTextItem
|
||||
* until new delta becomes non-zero */
|
||||
|
||||
do
|
||||
{
|
||||
sum += lpDx[i];
|
||||
fSum = sum*ve_we+err;
|
||||
delta = (short)HIWORD(fSum)
|
||||
- X11DRV_cptable[pfo->fi->cptable].pTextWidth(
|
||||
pfo, pitem->chars, pitem->nchars+1);
|
||||
pitem->nchars++;
|
||||
} while ((++i < count) && !delta);
|
||||
pitem++;
|
||||
err = LOWORD(fSum);
|
||||
}
|
||||
}
|
||||
else /* charExtra or breakExtra */
|
||||
{
|
||||
while (i < count)
|
||||
{
|
||||
pitem->chars = str2b + i;
|
||||
pitem->delta = delta;
|
||||
pitem->nchars = 0;
|
||||
pitem->font = None;
|
||||
delta = 0;
|
||||
|
||||
do
|
||||
{
|
||||
delta += charExtra;
|
||||
if (str2b[i].byte2 == (char)dfBreakChar)
|
||||
delta += breakExtra;
|
||||
pitem->nchars++;
|
||||
} while ((++i < count) && !delta);
|
||||
pitem++;
|
||||
}
|
||||
if (!lpDx)
|
||||
{
|
||||
X11DRV_cptable[pfo->fi->cptable].pDrawString(
|
||||
pfo, gdi_display, physDev->drawable, physDev->gc,
|
||||
physDev->org.x + x, physDev->org.y + y, str2b, count );
|
||||
}
|
||||
else
|
||||
{
|
||||
XTextItem16 *items, *pitem;
|
||||
|
||||
X11DRV_cptable[pfo->fi->cptable].pDrawText( pfo, gdi_display,
|
||||
physDev->drawable, physDev->gc,
|
||||
physDev->org.x + x, physDev->org.y + y, items, pitem - items );
|
||||
HeapFree( GetProcessHeap(), 0, items );
|
||||
}
|
||||
pitem = items = HeapAlloc( GetProcessHeap(), 0,
|
||||
count * sizeof(XTextItem16) );
|
||||
if(items == NULL) goto FAIL;
|
||||
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
pitem->chars = str2b + i;
|
||||
pitem->delta = lpDx[i];
|
||||
pitem->nchars = 1;
|
||||
pitem->font = None;
|
||||
pitem++;
|
||||
}
|
||||
|
||||
X11DRV_cptable[pfo->fi->cptable].pDrawText( pfo, gdi_display,
|
||||
physDev->drawable, physDev->gc,
|
||||
physDev->org.x + x, physDev->org.y + y, items, pitem - items );
|
||||
HeapFree( GetProcessHeap(), 0, items );
|
||||
}
|
||||
}
|
||||
else /* rotated */
|
||||
{
|
||||
/* have to render character by character. */
|
||||
double offset = 0.0;
|
||||
int i;
|
||||
/* have to render character by character. */
|
||||
double offset = 0.0;
|
||||
int i;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
int char_metric_offset = str2b[i].byte2 + (str2b[i].byte1 << 8)
|
||||
- font->min_char_or_byte2;
|
||||
int x_i = IROUND((double) (physDev->org.x + x) + offset *
|
||||
pfo->lpX11Trans->a / pfo->lpX11Trans->pixelsize );
|
||||
int y_i = IROUND((double) (physDev->org.y + y) - offset *
|
||||
pfo->lpX11Trans->b / pfo->lpX11Trans->pixelsize );
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
int char_metric_offset = str2b[i].byte2 + (str2b[i].byte1 << 8)
|
||||
- font->min_char_or_byte2;
|
||||
int x_i = IROUND((double) (physDev->org.x + x) + offset *
|
||||
pfo->lpX11Trans->a / pfo->lpX11Trans->pixelsize );
|
||||
int y_i = IROUND((double) (physDev->org.y + y) - offset *
|
||||
pfo->lpX11Trans->b / pfo->lpX11Trans->pixelsize );
|
||||
|
||||
X11DRV_cptable[pfo->fi->cptable].pDrawString(
|
||||
pfo, gdi_display, physDev->drawable, physDev->gc,
|
||||
x_i, y_i, &str2b[i], 1);
|
||||
if (lpDx)
|
||||
{
|
||||
offset += X11DRV_XWStoDS(physDev, lpDx[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset += (double) (font->per_char ?
|
||||
font->per_char[char_metric_offset].attributes:
|
||||
font->min_bounds.attributes)
|
||||
* pfo->lpX11Trans->pixelsize / 1000.0;
|
||||
offset += charExtra;
|
||||
if (str2b[i].byte2 == (char)dfBreakChar)
|
||||
offset += breakExtra;
|
||||
}
|
||||
}
|
||||
X11DRV_cptable[pfo->fi->cptable].pDrawString(
|
||||
pfo, gdi_display, physDev->drawable, physDev->gc,
|
||||
x_i, y_i, &str2b[i], 1);
|
||||
if (lpDx)
|
||||
{
|
||||
offset += lpDx[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
offset += (double) (font->per_char ?
|
||||
font->per_char[char_metric_offset].attributes:
|
||||
font->min_bounds.attributes)
|
||||
* pfo->lpX11Trans->pixelsize / 1000.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, str2b );
|
||||
|
||||
/* Draw underline and strike-out if needed */
|
||||
|
||||
wine_tsx11_lock();
|
||||
if (lfUnderline)
|
||||
{
|
||||
long linePos, lineWidth;
|
||||
|
||||
if (!XGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
|
||||
linePos = descent - 1;
|
||||
if (!XGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
|
||||
lineWidth = 0;
|
||||
else if (lineWidth == 1) lineWidth = 0;
|
||||
XSetLineAttributes( gdi_display, physDev->gc, lineWidth,
|
||||
LineSolid, CapRound, JoinBevel );
|
||||
XDrawLine( gdi_display, physDev->drawable, physDev->gc,
|
||||
physDev->org.x + x, physDev->org.y + y + linePos,
|
||||
physDev->org.x + x + width, physDev->org.y + y + linePos );
|
||||
}
|
||||
if (lfStrikeOut)
|
||||
{
|
||||
long lineAscent, lineDescent;
|
||||
if (!XGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
|
||||
lineAscent = ascent / 2;
|
||||
if (!XGetFontProperty( font, XA_STRIKEOUT_DESCENT, &lineDescent ))
|
||||
lineDescent = -lineAscent * 2 / 3;
|
||||
XSetLineAttributes( gdi_display, physDev->gc, lineAscent + lineDescent,
|
||||
LineSolid, CapRound, JoinBevel );
|
||||
XDrawLine( gdi_display, physDev->drawable, physDev->gc,
|
||||
physDev->org.x + x, physDev->org.y + y - lineAscent,
|
||||
physDev->org.x + x + width, physDev->org.y + y - lineAscent );
|
||||
}
|
||||
wine_tsx11_unlock();
|
||||
|
||||
if (flags & ETO_CLIPPED)
|
||||
{
|
||||
/* restore the device region */
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
@ cdecl EnumDeviceFonts(ptr ptr ptr long) X11DRV_EnumDeviceFonts
|
||||
@ cdecl ExtEscape(ptr long long ptr long ptr) X11DRV_ExtEscape
|
||||
@ cdecl ExtFloodFill(ptr long long long long) X11DRV_ExtFloodFill
|
||||
@ cdecl ExtTextOut(ptr long long long ptr ptr long ptr long) X11DRV_ExtTextOut
|
||||
@ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) X11DRV_ExtTextOut
|
||||
@ cdecl GetBitmapBits(long ptr long) X11DRV_GetBitmapBits
|
||||
@ cdecl GetCharWidth(ptr long long ptr) X11DRV_GetCharWidth
|
||||
@ cdecl GetDCOrgEx(ptr ptr) X11DRV_GetDCOrgEx
|
||||
|
|
|
@ -211,7 +211,7 @@ extern BOOL X11DRV_ExtFloodFill( X11DRV_PDEVICE *physDev, INT x, INT y,
|
|||
COLORREF color, UINT fillType );
|
||||
extern BOOL X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y,
|
||||
UINT flags, const RECT *lprect,
|
||||
LPCWSTR str, UINT count, const INT *lpDx, INT breakExtra );
|
||||
LPCWSTR str, UINT count, const INT *lpDx );
|
||||
extern LONG X11DRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count );
|
||||
extern void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn );
|
||||
extern INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest,
|
||||
|
@ -271,7 +271,7 @@ extern BOOL X11DRV_XRender_SelectFont(X11DRV_PDEVICE*, HFONT);
|
|||
extern void X11DRV_XRender_DeleteDC(X11DRV_PDEVICE*);
|
||||
extern BOOL X11DRV_XRender_ExtTextOut(X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||
const RECT *lprect, LPCWSTR wstr,
|
||||
UINT count, const INT *lpDx, INT breakExtra);
|
||||
UINT count, const INT *lpDx);
|
||||
extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev);
|
||||
|
||||
extern XVisualInfo *X11DRV_setup_opengl_visual(Display *display);
|
||||
|
|
|
@ -1004,33 +1004,24 @@ static int XRenderErrorHandler(Display *dpy, XErrorEvent *event, void *arg)
|
|||
*/
|
||||
BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||
const RECT *lprect, LPCWSTR wstr, UINT count,
|
||||
const INT *lpDx, INT breakExtra )
|
||||
const INT *lpDx )
|
||||
{
|
||||
XRenderColor col;
|
||||
unsigned int idx;
|
||||
TEXTMETRICW tm;
|
||||
RGNDATA *data;
|
||||
SIZE sz;
|
||||
RECT rc;
|
||||
BOOL done_extents = FALSE;
|
||||
INT width, xwidth, ywidth;
|
||||
double cosEsc, sinEsc;
|
||||
XGCValues xgcval;
|
||||
LOGFONTW lf;
|
||||
int render_op = PictOpOver;
|
||||
const WORD *glyphs;
|
||||
POINT pt;
|
||||
gsCacheEntry *entry;
|
||||
gsCacheEntryFormat *formatEntry;
|
||||
BOOL retv = FALSE;
|
||||
HDC hdc = physDev->hdc;
|
||||
int textPixel, backgroundPixel;
|
||||
INT *deltas = NULL, char_extra;
|
||||
HRGN saved_region = 0;
|
||||
UINT align = GetTextAlign( hdc );
|
||||
BOOL disable_antialias = FALSE;
|
||||
AA_Type antialias = AA_None;
|
||||
DIBSECTION bmp;
|
||||
unsigned int idx;
|
||||
double cosEsc, sinEsc;
|
||||
LOGFONTW lf;
|
||||
|
||||
/* Do we need to disable antialiasing because of palette mode? */
|
||||
if( !physDev->bitmap || GetObjectW( physDev->bitmap->hbitmap, sizeof(bmp), &bmp ) != sizeof(bmp) ) {
|
||||
|
@ -1041,61 +1032,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
disable_antialias = TRUE;
|
||||
}
|
||||
|
||||
TRACE("%p, %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 = (const WORD*)wstr;
|
||||
else {
|
||||
glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR));
|
||||
GetGlyphIndicesW(hdc, wstr, count, (WORD*)glyphs, 0);
|
||||
}
|
||||
|
||||
if(lprect)
|
||||
TRACE("rect: %ld,%ld - %ld,%ld\n", lprect->left, lprect->top, lprect->right,
|
||||
lprect->bottom);
|
||||
TRACE("align = %x bkmode = %x mapmode = %x\n", align, GetBkMode(hdc), GetMapMode(hdc));
|
||||
|
||||
if(align & TA_UPDATECP)
|
||||
{
|
||||
GetCurrentPositionEx( hdc, &pt );
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
}
|
||||
|
||||
GetTextMetricsW(hdc, &tm);
|
||||
GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf);
|
||||
|
||||
if(!(tm.tmPitchAndFamily & TMPF_VECTOR)) /* Non-scalable fonts shouldn't be rotated */
|
||||
lf.lfEscapement = 0;
|
||||
|
||||
if(lf.lfEscapement != 0) {
|
||||
cosEsc = cos(lf.lfEscapement * M_PI / 1800);
|
||||
sinEsc = sin(lf.lfEscapement * M_PI / 1800);
|
||||
} else {
|
||||
cosEsc = 1;
|
||||
sinEsc = 0;
|
||||
}
|
||||
|
||||
if(flags & (ETO_CLIPPED | ETO_OPAQUE)) {
|
||||
if(!lprect) {
|
||||
if(flags & ETO_CLIPPED) goto done;
|
||||
GetTextExtentPointI(hdc, glyphs, count, &sz);
|
||||
done_extents = TRUE;
|
||||
rc.left = x;
|
||||
rc.top = y;
|
||||
rc.right = x + sz.cx;
|
||||
rc.bottom = y + sz.cy;
|
||||
} else {
|
||||
rc = *lprect;
|
||||
}
|
||||
|
||||
LPtoDP(hdc, (POINT*)&rc, 2);
|
||||
|
||||
if(rc.left > rc.right) {INT tmp = rc.left; rc.left = rc.right; rc.right = tmp;}
|
||||
if(rc.top > rc.bottom) {INT tmp = rc.top; rc.top = rc.bottom; rc.bottom = tmp;}
|
||||
}
|
||||
|
||||
xgcval.function = GXcopy;
|
||||
xgcval.background = physDev->backgroundPixel;
|
||||
xgcval.fill_style = FillSolid;
|
||||
|
@ -1118,114 +1054,37 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
backgroundPixel = physDev->backgroundPixel;
|
||||
}
|
||||
|
||||
if(flags & ETO_OPAQUE) {
|
||||
if(flags & ETO_OPAQUE)
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
XSetForeground( gdi_display, physDev->gc, backgroundPixel );
|
||||
XFillRectangle( gdi_display, physDev->drawable, physDev->gc,
|
||||
physDev->org.x + rc.left, physDev->org.y + rc.top,
|
||||
rc.right - rc.left, rc.bottom - rc.top );
|
||||
physDev->org.x + lprect->left, physDev->org.y + lprect->top,
|
||||
lprect->right - lprect->left, lprect->bottom - lprect->top );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
|
||||
if(count == 0) {
|
||||
retv = TRUE;
|
||||
if(count == 0)
|
||||
{
|
||||
retv = TRUE;
|
||||
goto done_unlock;
|
||||
}
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
LPtoDP(hdc, &pt, 1);
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
|
||||
TRACE("real x,y %d,%d\n", x, y);
|
||||
|
||||
char_extra = GetTextCharacterExtra(hdc);
|
||||
if(char_extra || breakExtra) {
|
||||
UINT i;
|
||||
SIZE tmpsz;
|
||||
deltas = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
|
||||
for(i = 0; i < count; i++) {
|
||||
if(lpDx)
|
||||
deltas[i] = lpDx[i] + char_extra;
|
||||
else {
|
||||
GetTextExtentPointI(hdc, glyphs + i, 1, &tmpsz);
|
||||
deltas[i] = tmpsz.cx;
|
||||
}
|
||||
|
||||
if (breakExtra && wstr[i] == tm.tmBreakChar) {
|
||||
deltas[i] = deltas[i] + breakExtra;
|
||||
}
|
||||
}
|
||||
} else if(lpDx)
|
||||
deltas = (INT*)lpDx;
|
||||
|
||||
if(deltas) {
|
||||
width = 0;
|
||||
for(idx = 0; idx < count; idx++)
|
||||
width += deltas[idx];
|
||||
|
||||
GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
|
||||
if(lf.lfEscapement != 0) {
|
||||
cosEsc = cos(lf.lfEscapement * M_PI / 1800);
|
||||
sinEsc = sin(lf.lfEscapement * M_PI / 1800);
|
||||
} else {
|
||||
if(!done_extents) {
|
||||
GetTextExtentPointI(hdc, glyphs, count, &sz);
|
||||
done_extents = TRUE;
|
||||
}
|
||||
width = sz.cx;
|
||||
}
|
||||
width = X11DRV_XWStoDS(physDev, width);
|
||||
xwidth = width * cosEsc;
|
||||
ywidth = width * sinEsc;
|
||||
|
||||
tm.tmAscent = abs(X11DRV_YWStoDS(physDev, tm.tmAscent));
|
||||
tm.tmDescent = abs(X11DRV_YWStoDS(physDev, tm.tmDescent));
|
||||
switch( align & (TA_LEFT | TA_RIGHT | TA_CENTER) ) {
|
||||
case TA_LEFT:
|
||||
if (align & TA_UPDATECP) {
|
||||
pt.x = x + xwidth;
|
||||
pt.y = y - ywidth;
|
||||
DPtoLP(hdc, &pt, 1);
|
||||
MoveToEx(hdc, pt.x, pt.y, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case TA_CENTER:
|
||||
x -= xwidth / 2;
|
||||
y += ywidth / 2;
|
||||
break;
|
||||
|
||||
case TA_RIGHT:
|
||||
x -= xwidth;
|
||||
y += ywidth;
|
||||
if (align & TA_UPDATECP) {
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
DPtoLP(hdc, &pt, 1);
|
||||
MoveToEx(hdc, pt.x, pt.y, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch( align & (TA_TOP | TA_BOTTOM | TA_BASELINE) ) {
|
||||
case TA_TOP:
|
||||
y += tm.tmAscent * cosEsc;
|
||||
x += tm.tmAscent * sinEsc;
|
||||
break;
|
||||
|
||||
case TA_BOTTOM:
|
||||
y -= tm.tmDescent * cosEsc;
|
||||
x -= tm.tmDescent * sinEsc;
|
||||
break;
|
||||
|
||||
case TA_BASELINE:
|
||||
break;
|
||||
cosEsc = 1;
|
||||
sinEsc = 0;
|
||||
}
|
||||
|
||||
if (flags & ETO_CLIPPED)
|
||||
{
|
||||
HRGN clip_region;
|
||||
RECT clip_rect = *lprect;
|
||||
|
||||
LPtoDP( hdc, (POINT *)&clip_rect, 2 );
|
||||
clip_region = CreateRectRgnIndirect( &clip_rect );
|
||||
clip_region = CreateRectRgnIndirect( lprect );
|
||||
/* make a copy of the current device region */
|
||||
saved_region = CreateRectRgn( 0, 0, 0, 0 );
|
||||
CombineRgn( saved_region, physDev->region, 0, RGN_COPY );
|
||||
|
@ -1264,20 +1123,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
}
|
||||
}
|
||||
|
||||
if(GetBkMode(hdc) != TRANSPARENT) {
|
||||
if(!((flags & ETO_CLIPPED) && (flags & ETO_OPAQUE))) {
|
||||
if(!(flags & ETO_OPAQUE) || x < rc.left || x + width >= rc.right ||
|
||||
y - tm.tmAscent < rc.top || y + tm.tmDescent >= rc.bottom) {
|
||||
wine_tsx11_lock();
|
||||
XSetForeground( gdi_display, physDev->gc, backgroundPixel );
|
||||
XFillRectangle( gdi_display, physDev->drawable, physDev->gc,
|
||||
physDev->org.x + x, physDev->org.y + y - tm.tmAscent,
|
||||
width, tm.tmAscent + tm.tmDescent );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(X11DRV_XRender_Installed) {
|
||||
/* Create a 1x1 pixmap to tile over the font mask */
|
||||
if(!physDev->xrender->tile_xpm) {
|
||||
|
@ -1345,10 +1190,10 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
|
||||
for(idx = 0; idx < count; idx++) {
|
||||
if( !formatEntry ) {
|
||||
UploadGlyph(physDev, glyphs[idx], antialias);
|
||||
UploadGlyph(physDev, wstr[idx], antialias);
|
||||
formatEntry = entry->format[antialias];
|
||||
} else if( glyphs[idx] >= formatEntry->nrealized || formatEntry->realized[glyphs[idx]] == FALSE) {
|
||||
UploadGlyph(physDev, glyphs[idx], antialias);
|
||||
} else if( wstr[idx] >= formatEntry->nrealized || formatEntry->realized[wstr[idx]] == FALSE) {
|
||||
UploadGlyph(physDev, wstr[idx], antialias);
|
||||
}
|
||||
}
|
||||
assert(formatEntry);
|
||||
|
@ -1358,14 +1203,13 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
|
||||
if(X11DRV_XRender_Installed) {
|
||||
wine_tsx11_lock();
|
||||
if(!deltas)
|
||||
if(!lpDx)
|
||||
pXRenderCompositeString16(gdi_display, render_op,
|
||||
physDev->xrender->tile_pict,
|
||||
physDev->xrender->pict,
|
||||
formatEntry->font_format, formatEntry->glyphset,
|
||||
0, 0, physDev->org.x + x, physDev->org.y + y,
|
||||
glyphs, count);
|
||||
|
||||
wstr, count);
|
||||
else {
|
||||
INT offset = 0, xoff = 0, yoff = 0;
|
||||
for(idx = 0; idx < count; idx++) {
|
||||
|
@ -1375,8 +1219,8 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
formatEntry->font_format, formatEntry->glyphset,
|
||||
0, 0, physDev->org.x + x + xoff,
|
||||
physDev->org.y + y + yoff,
|
||||
glyphs + idx, 1);
|
||||
offset += X11DRV_XWStoDS(physDev, deltas[idx]);
|
||||
wstr + idx, 1);
|
||||
offset += lpDx[idx];
|
||||
xoff = offset * cosEsc;
|
||||
yoff = offset * -sinEsc;
|
||||
}
|
||||
|
@ -1392,32 +1236,30 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
for(idx = 0; idx < count; idx++) {
|
||||
SharpGlyphMono(physDev, physDev->org.x + x + xoff,
|
||||
physDev->org.y + y + yoff,
|
||||
formatEntry->bitmaps[glyphs[idx]],
|
||||
&formatEntry->gis[glyphs[idx]]);
|
||||
if(deltas) {
|
||||
offset += X11DRV_XWStoDS(physDev, deltas[idx]);
|
||||
formatEntry->bitmaps[wstr[idx]],
|
||||
&formatEntry->gis[wstr[idx]]);
|
||||
if(lpDx) {
|
||||
offset += lpDx[idx];
|
||||
xoff = offset * cosEsc;
|
||||
yoff = offset * -sinEsc;
|
||||
|
||||
} else {
|
||||
xoff += formatEntry->gis[glyphs[idx]].xOff;
|
||||
yoff += formatEntry->gis[glyphs[idx]].yOff;
|
||||
xoff += formatEntry->gis[wstr[idx]].xOff;
|
||||
yoff += formatEntry->gis[wstr[idx]].yOff;
|
||||
}
|
||||
}
|
||||
} else if(physDev->depth == 1) {
|
||||
for(idx = 0; idx < count; idx++) {
|
||||
SharpGlyphGray(physDev, physDev->org.x + x + xoff,
|
||||
physDev->org.y + y + yoff,
|
||||
formatEntry->bitmaps[glyphs[idx]],
|
||||
&formatEntry->gis[glyphs[idx]]);
|
||||
if(deltas) {
|
||||
offset += X11DRV_XWStoDS(physDev, deltas[idx]);
|
||||
formatEntry->bitmaps[wstr[idx]],
|
||||
&formatEntry->gis[wstr[idx]]);
|
||||
if(lpDx) {
|
||||
offset += lpDx[idx];
|
||||
xoff = offset * cosEsc;
|
||||
yoff = offset * -sinEsc;
|
||||
|
||||
} else {
|
||||
xoff += formatEntry->gis[glyphs[idx]].xOff;
|
||||
yoff += formatEntry->gis[glyphs[idx]].yOff;
|
||||
xoff += formatEntry->gis[wstr[idx]].xOff;
|
||||
yoff += formatEntry->gis[wstr[idx]].yOff;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1436,21 +1278,21 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
TRACE("drawable %dx%d\n", w, h);
|
||||
|
||||
for(idx = 0; idx < count; idx++) {
|
||||
if(extents.left > cur.x - formatEntry->gis[glyphs[idx]].x)
|
||||
extents.left = cur.x - formatEntry->gis[glyphs[idx]].x;
|
||||
if(extents.top > cur.y - formatEntry->gis[glyphs[idx]].y)
|
||||
extents.top = cur.y - formatEntry->gis[glyphs[idx]].y;
|
||||
if(extents.right < cur.x - formatEntry->gis[glyphs[idx]].x + formatEntry->gis[glyphs[idx]].width)
|
||||
extents.right = cur.x - formatEntry->gis[glyphs[idx]].x + formatEntry->gis[glyphs[idx]].width;
|
||||
if(extents.bottom < cur.y - formatEntry->gis[glyphs[idx]].y + formatEntry->gis[glyphs[idx]].height)
|
||||
extents.bottom = cur.y - formatEntry->gis[glyphs[idx]].y + formatEntry->gis[glyphs[idx]].height;
|
||||
if(deltas) {
|
||||
offset += X11DRV_XWStoDS(physDev, deltas[idx]);
|
||||
if(extents.left > cur.x - formatEntry->gis[wstr[idx]].x)
|
||||
extents.left = cur.x - formatEntry->gis[wstr[idx]].x;
|
||||
if(extents.top > cur.y - formatEntry->gis[wstr[idx]].y)
|
||||
extents.top = cur.y - formatEntry->gis[wstr[idx]].y;
|
||||
if(extents.right < cur.x - formatEntry->gis[wstr[idx]].x + formatEntry->gis[wstr[idx]].width)
|
||||
extents.right = cur.x - formatEntry->gis[wstr[idx]].x + formatEntry->gis[wstr[idx]].width;
|
||||
if(extents.bottom < cur.y - formatEntry->gis[wstr[idx]].y + formatEntry->gis[wstr[idx]].height)
|
||||
extents.bottom = cur.y - formatEntry->gis[wstr[idx]].y + formatEntry->gis[wstr[idx]].height;
|
||||
if(lpDx) {
|
||||
offset += lpDx[idx];
|
||||
cur.x = offset * cosEsc;
|
||||
cur.y = offset * -sinEsc;
|
||||
} else {
|
||||
cur.x += formatEntry->gis[glyphs[idx]].xOff;
|
||||
cur.y += formatEntry->gis[glyphs[idx]].yOff;
|
||||
cur.x += formatEntry->gis[wstr[idx]].xOff;
|
||||
cur.y += formatEntry->gis[wstr[idx]].yOff;
|
||||
}
|
||||
}
|
||||
TRACE("glyph extents %ld,%ld - %ld,%ld drawable x,y %ld,%ld\n", extents.left, extents.top,
|
||||
|
@ -1518,18 +1360,17 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
for(idx = 0; idx < count; idx++) {
|
||||
SmoothGlyphGray(image, xoff + image_off_x - extents.left,
|
||||
yoff + image_off_y - extents.top,
|
||||
formatEntry->bitmaps[glyphs[idx]],
|
||||
&formatEntry->gis[glyphs[idx]],
|
||||
formatEntry->bitmaps[wstr[idx]],
|
||||
&formatEntry->gis[wstr[idx]],
|
||||
physDev->textPixel);
|
||||
if(deltas) {
|
||||
offset += X11DRV_XWStoDS(physDev, deltas[idx]);
|
||||
if(lpDx) {
|
||||
offset += lpDx[idx];
|
||||
xoff = offset * cosEsc;
|
||||
yoff = offset * -sinEsc;
|
||||
} else {
|
||||
xoff += formatEntry->gis[glyphs[idx]].xOff;
|
||||
yoff += formatEntry->gis[glyphs[idx]].yOff;
|
||||
xoff += formatEntry->gis[wstr[idx]].xOff;
|
||||
yoff += formatEntry->gis[wstr[idx]].yOff;
|
||||
}
|
||||
|
||||
}
|
||||
XPutImage(gdi_display, physDev->drawable, physDev->gc, image, 0, 0,
|
||||
image_x, image_y, image_w, image_h);
|
||||
|
@ -1540,63 +1381,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
}
|
||||
LeaveCriticalSection(&xrender_cs);
|
||||
|
||||
if (lf.lfUnderline || lf.lfStrikeOut) {
|
||||
int underlinePos, strikeoutPos;
|
||||
int underlineWidth, strikeoutWidth;
|
||||
UINT nMetricsSize = GetOutlineTextMetricsW(hdc, 0, NULL);
|
||||
OUTLINETEXTMETRICW* otm = NULL;
|
||||
|
||||
if(!nMetricsSize) {
|
||||
underlinePos = 0;
|
||||
underlineWidth = tm.tmAscent / 20 + 1;
|
||||
strikeoutPos = tm.tmAscent / 2;
|
||||
strikeoutWidth = underlineWidth;
|
||||
} else {
|
||||
otm = HeapAlloc(GetProcessHeap(), 0, nMetricsSize);
|
||||
if (!otm) goto done_unlock;
|
||||
|
||||
GetOutlineTextMetricsW(hdc, nMetricsSize, otm);
|
||||
underlinePos = otm->otmsUnderscorePosition;
|
||||
underlineWidth = otm->otmsUnderscoreSize;
|
||||
strikeoutPos = otm->otmsStrikeoutPosition;
|
||||
strikeoutWidth = otm->otmsStrikeoutSize;
|
||||
}
|
||||
|
||||
wine_tsx11_lock();
|
||||
XSetForeground( gdi_display, physDev->gc, physDev->textPixel );
|
||||
|
||||
if (lf.lfUnderline) {
|
||||
underlinePos = X11DRV_YWStoDS(physDev, underlinePos);
|
||||
underlineWidth = X11DRV_YWStoDS(physDev, underlineWidth);
|
||||
|
||||
XSetLineAttributes( gdi_display, physDev->gc, underlineWidth,
|
||||
LineSolid, CapProjecting, JoinBevel );
|
||||
XDrawLine( gdi_display, physDev->drawable, physDev->gc,
|
||||
physDev->org.x + x - underlinePos * sinEsc,
|
||||
physDev->org.y + y - underlinePos * cosEsc,
|
||||
physDev->org.x + x + width * cosEsc - underlinePos * sinEsc,
|
||||
physDev->org.y + y - width * sinEsc - underlinePos * cosEsc );
|
||||
}
|
||||
|
||||
if (lf.lfStrikeOut) {
|
||||
strikeoutPos = X11DRV_YWStoDS(physDev, strikeoutPos);
|
||||
strikeoutWidth = X11DRV_YWStoDS(physDev, strikeoutWidth);
|
||||
|
||||
XSetLineAttributes( gdi_display, physDev->gc, strikeoutWidth,
|
||||
LineSolid, CapProjecting, JoinBevel );
|
||||
XDrawLine( gdi_display, physDev->drawable, physDev->gc,
|
||||
physDev->org.x + x - strikeoutPos * sinEsc,
|
||||
physDev->org.y + y - strikeoutPos * cosEsc,
|
||||
physDev->org.x + x + width * cosEsc - strikeoutPos * sinEsc,
|
||||
physDev->org.y + y - width * sinEsc - strikeoutPos * cosEsc);
|
||||
}
|
||||
wine_tsx11_unlock();
|
||||
HeapFree(GetProcessHeap(), 0, otm);
|
||||
}
|
||||
|
||||
if(deltas && deltas != lpDx)
|
||||
HeapFree(GetProcessHeap(), 0, deltas);
|
||||
|
||||
if (flags & ETO_CLIPPED)
|
||||
{
|
||||
/* restore the device region */
|
||||
|
@ -1608,8 +1392,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
|||
|
||||
done_unlock:
|
||||
X11DRV_UnlockDIBSection( physDev, TRUE );
|
||||
done:
|
||||
if(glyphs != wstr) HeapFree(GetProcessHeap(), 0, (WORD*)glyphs);
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue