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 INT EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode );
|
||||||
extern BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y,
|
extern BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y,
|
||||||
UINT flags, const RECT *lprect, LPCWSTR str,
|
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_FillPath( PHYSDEV dev );
|
||||||
extern BOOL EMFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush );
|
extern BOOL EMFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush );
|
||||||
extern BOOL EMFDRV_FlattenPath( PHYSDEV dev );
|
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,
|
BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
||||||
const RECT *lprect, LPCWSTR str, UINT count,
|
const RECT *lprect, LPCWSTR str, UINT count,
|
||||||
const INT *lpDx, INT breakExtra )
|
const INT *lpDx )
|
||||||
{
|
{
|
||||||
EMREXTTEXTOUTW *pemr;
|
EMREXTTEXTOUTW *pemr;
|
||||||
DWORD nSize;
|
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);
|
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 HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
|
||||||
static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
|
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 )
|
const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
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 );
|
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("called on an open path\n");
|
||||||
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);
|
|
||||||
}
|
|
||||||
GDI_ReleaseObj( hdc );
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ typedef struct tagDC_FUNCS
|
||||||
INT (*pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID);
|
INT (*pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID);
|
||||||
BOOL (*pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
|
BOOL (*pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
|
||||||
INT (*pExtSelectClipRgn)(PHYSDEV,HRGN,INT);
|
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 (*pFillPath)(PHYSDEV);
|
||||||
BOOL (*pFillRgn)(PHYSDEV,HRGN,HBRUSH);
|
BOOL (*pFillRgn)(PHYSDEV,HRGN,HBRUSH);
|
||||||
BOOL (*pFlattenPath)(PHYSDEV);
|
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 INT MFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode );
|
||||||
extern BOOL MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y,
|
extern BOOL MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y,
|
||||||
UINT flags, const RECT *lprect, LPCWSTR str,
|
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_FillPath( PHYSDEV dev );
|
||||||
extern BOOL MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush );
|
extern BOOL MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush );
|
||||||
extern BOOL MFDRV_FlattenPath( PHYSDEV dev );
|
extern BOOL MFDRV_FlattenPath( PHYSDEV dev );
|
||||||
|
|
|
@ -74,7 +74,7 @@ static BOOL MFDRV_MetaExtTextOut( PHYSDEV dev, short x, short y, UINT16 flags,
|
||||||
BOOL
|
BOOL
|
||||||
MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
||||||
const RECT *lprect, LPCWSTR str, UINT count,
|
const RECT *lprect, LPCWSTR str, UINT count,
|
||||||
const INT *lpDx, INT breakExtra )
|
const INT *lpDx )
|
||||||
{
|
{
|
||||||
RECT16 rect16;
|
RECT16 rect16;
|
||||||
LPINT16 lpdx16 = NULL;
|
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,
|
BOOL TTYDRV_DC_ExtTextOut(TTYDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||||
const RECT *lpRect, LPCWSTR str, UINT count,
|
const RECT *lpRect, LPCWSTR str, UINT count,
|
||||||
const INT *lpDx, INT breakExtra )
|
const INT *lpDx )
|
||||||
{
|
{
|
||||||
#ifdef WINE_CURSES
|
#ifdef WINE_CURSES
|
||||||
INT row, col;
|
INT row, col;
|
||||||
LPSTR ascii;
|
LPSTR ascii;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
POINT pt;
|
|
||||||
UINT text_align = GetTextAlign( physDev->hdc );
|
|
||||||
|
|
||||||
TRACE("(%p, %d, %d, 0x%08x, %p, %s, %d, %p)\n",
|
TRACE("(%p, %d, %d, 0x%08x, %p, %s, %d, %p)\n",
|
||||||
physDev->hdc, x, y, flags, lpRect, debugstr_wn(str, count), count, lpDx);
|
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)
|
if(!physDev->window)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pt.x = x;
|
row = (physDev->org.y + y) / physDev->cellHeight;
|
||||||
pt.y = y;
|
col = (physDev->org.x + x) / physDev->cellWidth;
|
||||||
/* 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;
|
|
||||||
len = WideCharToMultiByte( CP_ACP, 0, str, count, NULL, 0, NULL, NULL );
|
len = WideCharToMultiByte( CP_ACP, 0, str, count, NULL, 0, NULL, NULL );
|
||||||
ascii = HeapAlloc( GetProcessHeap(), 0, len );
|
ascii = HeapAlloc( GetProcessHeap(), 0, len );
|
||||||
WideCharToMultiByte( CP_ACP, 0, str, count, ascii, len, NULL, NULL );
|
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 );
|
HeapFree( GetProcessHeap(), 0, ascii );
|
||||||
wrefresh(physDev->window);
|
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;
|
return TRUE;
|
||||||
#else /* defined(WINE_CURSES) */
|
#else /* defined(WINE_CURSES) */
|
||||||
FIXME("(%p, %d, %d, 0x%08x, %p, %s, %d, %p): stub\n",
|
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_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_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_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 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);
|
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 Ellipse(ptr long long long long) TTYDRV_DC_Ellipse
|
||||||
@ cdecl ExtEscape(ptr long long ptr long ptr) TTYDRV_ExtEscape
|
@ cdecl ExtEscape(ptr long long ptr long ptr) TTYDRV_ExtEscape
|
||||||
@ cdecl ExtFloodFill(ptr long long long long) TTYDRV_DC_ExtFloodFill
|
@ 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 GetBitmapBits(long ptr long) TTYDRV_GetBitmapBits
|
||||||
@ cdecl GetCharWidth(ptr long long ptr) TTYDRV_DC_GetCharWidth
|
@ cdecl GetCharWidth(ptr long long ptr) TTYDRV_DC_GetCharWidth
|
||||||
@ cdecl GetDCOrgEx(ptr ptr) TTYDRV_GetDCOrgEx
|
@ 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 INT PSDRV_EndPage( PSDRV_PDEVICE *physDev );
|
||||||
extern BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
extern BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||||
const RECT *lprect, LPCWSTR str, UINT count,
|
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,
|
extern BOOL PSDRV_GetCharWidth( PSDRV_PDEVICE *physDev, UINT firstChar, UINT lastChar,
|
||||||
LPINT buffer );
|
LPINT buffer );
|
||||||
extern BOOL PSDRV_GetTextExtentPoint( PSDRV_PDEVICE *physDev, LPCWSTR str, INT count,
|
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,
|
BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||||
const RECT *lprect, LPCWSTR str, UINT count,
|
const RECT *lprect, LPCWSTR str, UINT count,
|
||||||
const INT *lpDx, INT breakExtra )
|
const INT *lpDx )
|
||||||
{
|
{
|
||||||
BOOL bResult = TRUE;
|
BOOL bResult = TRUE;
|
||||||
BOOL bClipped = FALSE;
|
BOOL bClipped = FALSE;
|
||||||
BOOL bOpaque = FALSE;
|
BOOL bOpaque = FALSE;
|
||||||
RECT rect;
|
|
||||||
|
|
||||||
TRACE("(x=%d, y=%d, flags=0x%08x, str=%s, count=%d, lpDx=%p)\n", x, y,
|
TRACE("(x=%d, y=%d, flags=0x%08x, str=%s, count=%d, lpDx=%p)\n", x, y,
|
||||||
flags, debugstr_wn(str, count), count, lpDx);
|
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 */
|
/* set clipping and/or draw background */
|
||||||
if ((flags & (ETO_CLIPPED | ETO_OPAQUE)) && (lprect != NULL))
|
if ((flags & (ETO_CLIPPED | ETO_OPAQUE)) && (lprect != NULL))
|
||||||
{
|
{
|
||||||
rect = *lprect;
|
|
||||||
LPtoDP( physDev->hdc, (POINT *)&rect, 2 );
|
|
||||||
PSDRV_WriteGSave(physDev);
|
PSDRV_WriteGSave(physDev);
|
||||||
PSDRV_WriteRectangle(physDev, rect.left, rect.top, rect.right - rect.left,
|
PSDRV_WriteRectangle(physDev, lprect->left, lprect->top, lprect->right - lprect->left,
|
||||||
rect.bottom - rect.top);
|
lprect->bottom - lprect->top);
|
||||||
|
|
||||||
if (flags & ETO_OPAQUE)
|
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,
|
static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, LPCWSTR str,
|
||||||
UINT count, BOOL bDrawBackground, const INT *lpDx)
|
UINT count, BOOL bDrawBackground, const INT *lpDx)
|
||||||
{
|
{
|
||||||
SIZE sz;
|
|
||||||
TEXTMETRICW tm;
|
|
||||||
POINT pt;
|
|
||||||
INT ascent, descent;
|
|
||||||
WORD *glyphs = NULL;
|
WORD *glyphs = NULL;
|
||||||
UINT align = GetTextAlign( physDev->hdc );
|
|
||||||
INT char_extra;
|
|
||||||
INT *deltas = NULL;
|
|
||||||
double cosEsc, sinEsc;
|
double cosEsc, sinEsc;
|
||||||
LOGFONTW lf;
|
LOGFONTW lf;
|
||||||
|
|
||||||
|
@ -120,127 +110,12 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, LPCWSTR
|
||||||
sinEsc = 0;
|
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)
|
if(physDev->font.fontloc == Download)
|
||||||
GetTextExtentPointI(physDev->hdc, glyphs, count, &sz);
|
glyphs = (LPWORD)str;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
PSDRV_WriteMoveTo(physDev, x, y);
|
PSDRV_WriteMoveTo(physDev, x, y);
|
||||||
|
|
||||||
if(!deltas) {
|
if(!lpDx) {
|
||||||
if(physDev->font.fontloc == Download)
|
if(physDev->font.fontloc == Download)
|
||||||
PSDRV_WriteDownloadGlyphShow(physDev, glyphs, count);
|
PSDRV_WriteDownloadGlyphShow(physDev, glyphs, count);
|
||||||
else
|
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 cos_theta = cos(physDev->font.escapement * M_PI / 1800.0);
|
||||||
float sin_theta = sin(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++) {
|
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)
|
if(physDev->font.fontloc == Download)
|
||||||
PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
|
PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
|
||||||
else
|
else
|
||||||
PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
|
PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
|
||||||
dx += deltas[i] * cos_theta;
|
dx += lpDx[i] * cos_theta;
|
||||||
dy -= deltas[i] * sin_theta;
|
dy -= lpDx[i] * sin_theta;
|
||||||
PSDRV_WriteMoveTo(physDev, x + PSDRV_XWStoDS(physDev, dx),
|
PSDRV_WriteMoveTo(physDev, x + dx, y + dy);
|
||||||
y + PSDRV_YWStoDS(physDev, dy));
|
|
||||||
}
|
}
|
||||||
if(physDev->font.fontloc == Download)
|
if(physDev->font.fontloc == Download)
|
||||||
PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
|
PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
|
||||||
else
|
else
|
||||||
PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
@ cdecl EnumDeviceFonts(ptr ptr ptr long) PSDRV_EnumDeviceFonts
|
@ cdecl EnumDeviceFonts(ptr ptr ptr long) PSDRV_EnumDeviceFonts
|
||||||
@ cdecl ExtDeviceMode(ptr long ptr ptr ptr ptr ptr long) PSDRV_ExtDeviceMode
|
@ cdecl ExtDeviceMode(ptr long ptr ptr ptr ptr ptr long) PSDRV_ExtDeviceMode
|
||||||
@ cdecl ExtEscape(ptr long long ptr long ptr) PSDRV_ExtEscape
|
@ 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 GetCharWidth(ptr long long ptr) PSDRV_GetCharWidth
|
||||||
@ cdecl GetDeviceCaps(ptr long) PSDRV_GetDeviceCaps
|
@ cdecl GetDeviceCaps(ptr long) PSDRV_GetDeviceCaps
|
||||||
@ cdecl GetTextExtentPoint(ptr ptr long ptr) PSDRV_GetTextExtentPoint
|
@ cdecl GetTextExtentPoint(ptr ptr long ptr) PSDRV_GetTextExtentPoint
|
||||||
|
|
|
@ -42,93 +42,36 @@ WINE_DEFAULT_DEBUG_CHANNEL(text);
|
||||||
BOOL
|
BOOL
|
||||||
X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||||
const RECT *lprect, LPCWSTR wstr, UINT count,
|
const RECT *lprect, LPCWSTR wstr, UINT count,
|
||||||
const INT *lpDx, INT breakExtra )
|
const INT *lpDx )
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
fontObject* pfo;
|
fontObject* pfo;
|
||||||
INT width, ascent, descent, xwidth, ywidth;
|
|
||||||
XFontStruct* font;
|
XFontStruct* font;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
char dfBreakChar, lfUnderline, lfStrikeOut;
|
|
||||||
BOOL rotated = FALSE;
|
BOOL rotated = FALSE;
|
||||||
XChar2b *str2b = NULL;
|
XChar2b *str2b = NULL;
|
||||||
BOOL dibUpdateFlag = FALSE;
|
BOOL dibUpdateFlag = FALSE;
|
||||||
BOOL result = TRUE;
|
BOOL result = TRUE;
|
||||||
HRGN saved_region = 0;
|
HRGN saved_region = 0;
|
||||||
POINT pt;
|
|
||||||
UINT align;
|
|
||||||
INT charExtra;
|
|
||||||
|
|
||||||
if(physDev->has_gdi_font)
|
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;
|
if (!X11DRV_SetupGCForText( physDev )) return TRUE;
|
||||||
|
|
||||||
align = GetTextAlign( physDev->hdc );
|
|
||||||
charExtra = GetTextCharacterExtra( physDev->hdc );
|
|
||||||
|
|
||||||
pfo = XFONT_GetFontObject( physDev->font );
|
pfo = XFONT_GetFontObject( physDev->font );
|
||||||
font = pfo->fs;
|
font = pfo->fs;
|
||||||
|
|
||||||
if (pfo->lf.lfEscapement && pfo->lpX11Trans)
|
if (pfo->lf.lfEscapement && pfo->lpX11Trans)
|
||||||
rotated = TRUE;
|
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",
|
TRACE("hdc=%p df=%04x %d,%d %s, %d flags=%d lpDx=%p\n",
|
||||||
physDev->hdc, (UINT16)(physDev->font), x, y,
|
physDev->hdc, (UINT16)(physDev->font), x, y,
|
||||||
debugstr_wn (wstr, count), count, flags, lpDx);
|
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",
|
if (lprect != NULL) TRACE("\trect=(%ld,%ld - %ld,%ld)\n",
|
||||||
lprect->left, lprect->top,
|
lprect->left, lprect->top,
|
||||||
lprect->right, lprect->bottom );
|
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 */
|
/* 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 */
|
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 */
|
/* Set the clip region */
|
||||||
|
|
||||||
if (flags & ETO_CLIPPED)
|
if (flags & ETO_CLIPPED)
|
||||||
{
|
{
|
||||||
HRGN clip_region;
|
HRGN clip_region;
|
||||||
RECT clip_rect = *lprect;
|
|
||||||
|
|
||||||
LPtoDP( physDev->hdc, (POINT *)&clip_rect, 2 );
|
clip_region = CreateRectRgnIndirect( lprect );
|
||||||
clip_region = CreateRectRgnIndirect( &clip_rect );
|
|
||||||
/* make a copy of the current device region */
|
/* make a copy of the current device region */
|
||||||
saved_region = CreateRectRgn( 0, 0, 0, 0 );
|
saved_region = CreateRectRgn( 0, 0, 0, 0 );
|
||||||
CombineRgn( saved_region, physDev->region, 0, RGN_COPY );
|
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;
|
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) */
|
/* Draw the text (count > 0 verified) */
|
||||||
if (!(str2b = X11DRV_cptable[pfo->fi->cptable].punicode_to_char2b( pfo, wstr, count )))
|
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();
|
wine_tsx11_unlock();
|
||||||
if(!rotated)
|
if(!rotated)
|
||||||
{
|
{
|
||||||
if (!charExtra && !breakExtra && !lpDx)
|
if (!lpDx)
|
||||||
{
|
{
|
||||||
X11DRV_cptable[pfo->fi->cptable].pDrawString(
|
X11DRV_cptable[pfo->fi->cptable].pDrawString(
|
||||||
pfo, gdi_display, physDev->drawable, physDev->gc,
|
pfo, gdi_display, physDev->drawable, physDev->gc,
|
||||||
physDev->org.x + x, physDev->org.y + y, str2b, count );
|
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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XTextItem16 *items, *pitem;
|
||||||
|
|
||||||
X11DRV_cptable[pfo->fi->cptable].pDrawText( pfo, gdi_display,
|
pitem = items = HeapAlloc( GetProcessHeap(), 0,
|
||||||
physDev->drawable, physDev->gc,
|
count * sizeof(XTextItem16) );
|
||||||
physDev->org.x + x, physDev->org.y + y, items, pitem - items );
|
if(items == NULL) goto FAIL;
|
||||||
HeapFree( GetProcessHeap(), 0, items );
|
|
||||||
}
|
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 */
|
else /* rotated */
|
||||||
{
|
{
|
||||||
/* have to render character by character. */
|
/* have to render character by character. */
|
||||||
double offset = 0.0;
|
double offset = 0.0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<count; i++)
|
for (i=0; i<count; i++)
|
||||||
{
|
{
|
||||||
int char_metric_offset = str2b[i].byte2 + (str2b[i].byte1 << 8)
|
int char_metric_offset = str2b[i].byte2 + (str2b[i].byte1 << 8)
|
||||||
- font->min_char_or_byte2;
|
- font->min_char_or_byte2;
|
||||||
int x_i = IROUND((double) (physDev->org.x + x) + offset *
|
int x_i = IROUND((double) (physDev->org.x + x) + offset *
|
||||||
pfo->lpX11Trans->a / pfo->lpX11Trans->pixelsize );
|
pfo->lpX11Trans->a / pfo->lpX11Trans->pixelsize );
|
||||||
int y_i = IROUND((double) (physDev->org.y + y) - offset *
|
int y_i = IROUND((double) (physDev->org.y + y) - offset *
|
||||||
pfo->lpX11Trans->b / pfo->lpX11Trans->pixelsize );
|
pfo->lpX11Trans->b / pfo->lpX11Trans->pixelsize );
|
||||||
|
|
||||||
X11DRV_cptable[pfo->fi->cptable].pDrawString(
|
X11DRV_cptable[pfo->fi->cptable].pDrawString(
|
||||||
pfo, gdi_display, physDev->drawable, physDev->gc,
|
pfo, gdi_display, physDev->drawable, physDev->gc,
|
||||||
x_i, y_i, &str2b[i], 1);
|
x_i, y_i, &str2b[i], 1);
|
||||||
if (lpDx)
|
if (lpDx)
|
||||||
{
|
{
|
||||||
offset += X11DRV_XWStoDS(physDev, lpDx[i]);
|
offset += lpDx[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset += (double) (font->per_char ?
|
offset += (double) (font->per_char ?
|
||||||
font->per_char[char_metric_offset].attributes:
|
font->per_char[char_metric_offset].attributes:
|
||||||
font->min_bounds.attributes)
|
font->min_bounds.attributes)
|
||||||
* pfo->lpX11Trans->pixelsize / 1000.0;
|
* pfo->lpX11Trans->pixelsize / 1000.0;
|
||||||
offset += charExtra;
|
}
|
||||||
if (str2b[i].byte2 == (char)dfBreakChar)
|
}
|
||||||
offset += breakExtra;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
HeapFree( GetProcessHeap(), 0, str2b );
|
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)
|
if (flags & ETO_CLIPPED)
|
||||||
{
|
{
|
||||||
/* restore the device region */
|
/* restore the device region */
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
@ cdecl EnumDeviceFonts(ptr ptr ptr long) X11DRV_EnumDeviceFonts
|
@ cdecl EnumDeviceFonts(ptr ptr ptr long) X11DRV_EnumDeviceFonts
|
||||||
@ cdecl ExtEscape(ptr long long ptr long ptr) X11DRV_ExtEscape
|
@ cdecl ExtEscape(ptr long long ptr long ptr) X11DRV_ExtEscape
|
||||||
@ cdecl ExtFloodFill(ptr long long long long) X11DRV_ExtFloodFill
|
@ 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 GetBitmapBits(long ptr long) X11DRV_GetBitmapBits
|
||||||
@ cdecl GetCharWidth(ptr long long ptr) X11DRV_GetCharWidth
|
@ cdecl GetCharWidth(ptr long long ptr) X11DRV_GetCharWidth
|
||||||
@ cdecl GetDCOrgEx(ptr ptr) X11DRV_GetDCOrgEx
|
@ 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 );
|
COLORREF color, UINT fillType );
|
||||||
extern BOOL X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y,
|
extern BOOL X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y,
|
||||||
UINT flags, const RECT *lprect,
|
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 LONG X11DRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count );
|
||||||
extern void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn );
|
extern void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn );
|
||||||
extern INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest,
|
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 void X11DRV_XRender_DeleteDC(X11DRV_PDEVICE*);
|
||||||
extern BOOL X11DRV_XRender_ExtTextOut(X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
extern BOOL X11DRV_XRender_ExtTextOut(X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||||
const RECT *lprect, LPCWSTR wstr,
|
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 void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev);
|
||||||
|
|
||||||
extern XVisualInfo *X11DRV_setup_opengl_visual(Display *display);
|
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,
|
BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||||
const RECT *lprect, LPCWSTR wstr, UINT count,
|
const RECT *lprect, LPCWSTR wstr, UINT count,
|
||||||
const INT *lpDx, INT breakExtra )
|
const INT *lpDx )
|
||||||
{
|
{
|
||||||
XRenderColor col;
|
XRenderColor col;
|
||||||
unsigned int idx;
|
|
||||||
TEXTMETRICW tm;
|
|
||||||
RGNDATA *data;
|
RGNDATA *data;
|
||||||
SIZE sz;
|
|
||||||
RECT rc;
|
|
||||||
BOOL done_extents = FALSE;
|
|
||||||
INT width, xwidth, ywidth;
|
|
||||||
double cosEsc, sinEsc;
|
|
||||||
XGCValues xgcval;
|
XGCValues xgcval;
|
||||||
LOGFONTW lf;
|
|
||||||
int render_op = PictOpOver;
|
int render_op = PictOpOver;
|
||||||
const WORD *glyphs;
|
|
||||||
POINT pt;
|
|
||||||
gsCacheEntry *entry;
|
gsCacheEntry *entry;
|
||||||
gsCacheEntryFormat *formatEntry;
|
gsCacheEntryFormat *formatEntry;
|
||||||
BOOL retv = FALSE;
|
BOOL retv = FALSE;
|
||||||
HDC hdc = physDev->hdc;
|
HDC hdc = physDev->hdc;
|
||||||
int textPixel, backgroundPixel;
|
int textPixel, backgroundPixel;
|
||||||
INT *deltas = NULL, char_extra;
|
|
||||||
HRGN saved_region = 0;
|
HRGN saved_region = 0;
|
||||||
UINT align = GetTextAlign( hdc );
|
|
||||||
BOOL disable_antialias = FALSE;
|
BOOL disable_antialias = FALSE;
|
||||||
AA_Type antialias = AA_None;
|
AA_Type antialias = AA_None;
|
||||||
DIBSECTION bmp;
|
DIBSECTION bmp;
|
||||||
|
unsigned int idx;
|
||||||
|
double cosEsc, sinEsc;
|
||||||
|
LOGFONTW lf;
|
||||||
|
|
||||||
/* Do we need to disable antialiasing because of palette mode? */
|
/* Do we need to disable antialiasing because of palette mode? */
|
||||||
if( !physDev->bitmap || GetObjectW( physDev->bitmap->hbitmap, sizeof(bmp), &bmp ) != sizeof(bmp) ) {
|
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;
|
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.function = GXcopy;
|
||||||
xgcval.background = physDev->backgroundPixel;
|
xgcval.background = physDev->backgroundPixel;
|
||||||
xgcval.fill_style = FillSolid;
|
xgcval.fill_style = FillSolid;
|
||||||
|
@ -1118,114 +1054,37 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
||||||
backgroundPixel = physDev->backgroundPixel;
|
backgroundPixel = physDev->backgroundPixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flags & ETO_OPAQUE) {
|
if(flags & ETO_OPAQUE)
|
||||||
|
{
|
||||||
wine_tsx11_lock();
|
wine_tsx11_lock();
|
||||||
XSetForeground( gdi_display, physDev->gc, backgroundPixel );
|
XSetForeground( gdi_display, physDev->gc, backgroundPixel );
|
||||||
XFillRectangle( gdi_display, physDev->drawable, physDev->gc,
|
XFillRectangle( gdi_display, physDev->drawable, physDev->gc,
|
||||||
physDev->org.x + rc.left, physDev->org.y + rc.top,
|
physDev->org.x + lprect->left, physDev->org.y + lprect->top,
|
||||||
rc.right - rc.left, rc.bottom - rc.top );
|
lprect->right - lprect->left, lprect->bottom - lprect->top );
|
||||||
wine_tsx11_unlock();
|
wine_tsx11_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(count == 0) {
|
if(count == 0)
|
||||||
retv = TRUE;
|
{
|
||||||
|
retv = TRUE;
|
||||||
goto done_unlock;
|
goto done_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
pt.x = x;
|
|
||||||
pt.y = y;
|
GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
|
||||||
LPtoDP(hdc, &pt, 1);
|
if(lf.lfEscapement != 0) {
|
||||||
x = pt.x;
|
cosEsc = cos(lf.lfEscapement * M_PI / 1800);
|
||||||
y = pt.y;
|
sinEsc = sin(lf.lfEscapement * M_PI / 1800);
|
||||||
|
|
||||||
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];
|
|
||||||
} else {
|
} else {
|
||||||
if(!done_extents) {
|
cosEsc = 1;
|
||||||
GetTextExtentPointI(hdc, glyphs, count, &sz);
|
sinEsc = 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & ETO_CLIPPED)
|
if (flags & ETO_CLIPPED)
|
||||||
{
|
{
|
||||||
HRGN clip_region;
|
HRGN clip_region;
|
||||||
RECT clip_rect = *lprect;
|
|
||||||
|
|
||||||
LPtoDP( hdc, (POINT *)&clip_rect, 2 );
|
clip_region = CreateRectRgnIndirect( lprect );
|
||||||
clip_region = CreateRectRgnIndirect( &clip_rect );
|
|
||||||
/* make a copy of the current device region */
|
/* make a copy of the current device region */
|
||||||
saved_region = CreateRectRgn( 0, 0, 0, 0 );
|
saved_region = CreateRectRgn( 0, 0, 0, 0 );
|
||||||
CombineRgn( saved_region, physDev->region, 0, RGN_COPY );
|
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) {
|
if(X11DRV_XRender_Installed) {
|
||||||
/* Create a 1x1 pixmap to tile over the font mask */
|
/* Create a 1x1 pixmap to tile over the font mask */
|
||||||
if(!physDev->xrender->tile_xpm) {
|
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++) {
|
for(idx = 0; idx < count; idx++) {
|
||||||
if( !formatEntry ) {
|
if( !formatEntry ) {
|
||||||
UploadGlyph(physDev, glyphs[idx], antialias);
|
UploadGlyph(physDev, wstr[idx], antialias);
|
||||||
formatEntry = entry->format[antialias];
|
formatEntry = entry->format[antialias];
|
||||||
} else if( glyphs[idx] >= formatEntry->nrealized || formatEntry->realized[glyphs[idx]] == FALSE) {
|
} else if( wstr[idx] >= formatEntry->nrealized || formatEntry->realized[wstr[idx]] == FALSE) {
|
||||||
UploadGlyph(physDev, glyphs[idx], antialias);
|
UploadGlyph(physDev, wstr[idx], antialias);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(formatEntry);
|
assert(formatEntry);
|
||||||
|
@ -1358,14 +1203,13 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
||||||
|
|
||||||
if(X11DRV_XRender_Installed) {
|
if(X11DRV_XRender_Installed) {
|
||||||
wine_tsx11_lock();
|
wine_tsx11_lock();
|
||||||
if(!deltas)
|
if(!lpDx)
|
||||||
pXRenderCompositeString16(gdi_display, render_op,
|
pXRenderCompositeString16(gdi_display, render_op,
|
||||||
physDev->xrender->tile_pict,
|
physDev->xrender->tile_pict,
|
||||||
physDev->xrender->pict,
|
physDev->xrender->pict,
|
||||||
formatEntry->font_format, formatEntry->glyphset,
|
formatEntry->font_format, formatEntry->glyphset,
|
||||||
0, 0, physDev->org.x + x, physDev->org.y + y,
|
0, 0, physDev->org.x + x, physDev->org.y + y,
|
||||||
glyphs, count);
|
wstr, count);
|
||||||
|
|
||||||
else {
|
else {
|
||||||
INT offset = 0, xoff = 0, yoff = 0;
|
INT offset = 0, xoff = 0, yoff = 0;
|
||||||
for(idx = 0; idx < count; idx++) {
|
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,
|
formatEntry->font_format, formatEntry->glyphset,
|
||||||
0, 0, physDev->org.x + x + xoff,
|
0, 0, physDev->org.x + x + xoff,
|
||||||
physDev->org.y + y + yoff,
|
physDev->org.y + y + yoff,
|
||||||
glyphs + idx, 1);
|
wstr + idx, 1);
|
||||||
offset += X11DRV_XWStoDS(physDev, deltas[idx]);
|
offset += lpDx[idx];
|
||||||
xoff = offset * cosEsc;
|
xoff = offset * cosEsc;
|
||||||
yoff = offset * -sinEsc;
|
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++) {
|
for(idx = 0; idx < count; idx++) {
|
||||||
SharpGlyphMono(physDev, physDev->org.x + x + xoff,
|
SharpGlyphMono(physDev, physDev->org.x + x + xoff,
|
||||||
physDev->org.y + y + yoff,
|
physDev->org.y + y + yoff,
|
||||||
formatEntry->bitmaps[glyphs[idx]],
|
formatEntry->bitmaps[wstr[idx]],
|
||||||
&formatEntry->gis[glyphs[idx]]);
|
&formatEntry->gis[wstr[idx]]);
|
||||||
if(deltas) {
|
if(lpDx) {
|
||||||
offset += X11DRV_XWStoDS(physDev, deltas[idx]);
|
offset += lpDx[idx];
|
||||||
xoff = offset * cosEsc;
|
xoff = offset * cosEsc;
|
||||||
yoff = offset * -sinEsc;
|
yoff = offset * -sinEsc;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
xoff += formatEntry->gis[glyphs[idx]].xOff;
|
xoff += formatEntry->gis[wstr[idx]].xOff;
|
||||||
yoff += formatEntry->gis[glyphs[idx]].yOff;
|
yoff += formatEntry->gis[wstr[idx]].yOff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(physDev->depth == 1) {
|
} else if(physDev->depth == 1) {
|
||||||
for(idx = 0; idx < count; idx++) {
|
for(idx = 0; idx < count; idx++) {
|
||||||
SharpGlyphGray(physDev, physDev->org.x + x + xoff,
|
SharpGlyphGray(physDev, physDev->org.x + x + xoff,
|
||||||
physDev->org.y + y + yoff,
|
physDev->org.y + y + yoff,
|
||||||
formatEntry->bitmaps[glyphs[idx]],
|
formatEntry->bitmaps[wstr[idx]],
|
||||||
&formatEntry->gis[glyphs[idx]]);
|
&formatEntry->gis[wstr[idx]]);
|
||||||
if(deltas) {
|
if(lpDx) {
|
||||||
offset += X11DRV_XWStoDS(physDev, deltas[idx]);
|
offset += lpDx[idx];
|
||||||
xoff = offset * cosEsc;
|
xoff = offset * cosEsc;
|
||||||
yoff = offset * -sinEsc;
|
yoff = offset * -sinEsc;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
xoff += formatEntry->gis[glyphs[idx]].xOff;
|
xoff += formatEntry->gis[wstr[idx]].xOff;
|
||||||
yoff += formatEntry->gis[glyphs[idx]].yOff;
|
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);
|
TRACE("drawable %dx%d\n", w, h);
|
||||||
|
|
||||||
for(idx = 0; idx < count; idx++) {
|
for(idx = 0; idx < count; idx++) {
|
||||||
if(extents.left > cur.x - formatEntry->gis[glyphs[idx]].x)
|
if(extents.left > cur.x - formatEntry->gis[wstr[idx]].x)
|
||||||
extents.left = cur.x - formatEntry->gis[glyphs[idx]].x;
|
extents.left = cur.x - formatEntry->gis[wstr[idx]].x;
|
||||||
if(extents.top > cur.y - formatEntry->gis[glyphs[idx]].y)
|
if(extents.top > cur.y - formatEntry->gis[wstr[idx]].y)
|
||||||
extents.top = cur.y - formatEntry->gis[glyphs[idx]].y;
|
extents.top = cur.y - formatEntry->gis[wstr[idx]].y;
|
||||||
if(extents.right < cur.x - formatEntry->gis[glyphs[idx]].x + formatEntry->gis[glyphs[idx]].width)
|
if(extents.right < cur.x - formatEntry->gis[wstr[idx]].x + formatEntry->gis[wstr[idx]].width)
|
||||||
extents.right = cur.x - formatEntry->gis[glyphs[idx]].x + formatEntry->gis[glyphs[idx]].width;
|
extents.right = cur.x - formatEntry->gis[wstr[idx]].x + formatEntry->gis[wstr[idx]].width;
|
||||||
if(extents.bottom < cur.y - formatEntry->gis[glyphs[idx]].y + formatEntry->gis[glyphs[idx]].height)
|
if(extents.bottom < cur.y - formatEntry->gis[wstr[idx]].y + formatEntry->gis[wstr[idx]].height)
|
||||||
extents.bottom = cur.y - formatEntry->gis[glyphs[idx]].y + formatEntry->gis[glyphs[idx]].height;
|
extents.bottom = cur.y - formatEntry->gis[wstr[idx]].y + formatEntry->gis[wstr[idx]].height;
|
||||||
if(deltas) {
|
if(lpDx) {
|
||||||
offset += X11DRV_XWStoDS(physDev, deltas[idx]);
|
offset += lpDx[idx];
|
||||||
cur.x = offset * cosEsc;
|
cur.x = offset * cosEsc;
|
||||||
cur.y = offset * -sinEsc;
|
cur.y = offset * -sinEsc;
|
||||||
} else {
|
} else {
|
||||||
cur.x += formatEntry->gis[glyphs[idx]].xOff;
|
cur.x += formatEntry->gis[wstr[idx]].xOff;
|
||||||
cur.y += formatEntry->gis[glyphs[idx]].yOff;
|
cur.y += formatEntry->gis[wstr[idx]].yOff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRACE("glyph extents %ld,%ld - %ld,%ld drawable x,y %ld,%ld\n", extents.left, extents.top,
|
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++) {
|
for(idx = 0; idx < count; idx++) {
|
||||||
SmoothGlyphGray(image, xoff + image_off_x - extents.left,
|
SmoothGlyphGray(image, xoff + image_off_x - extents.left,
|
||||||
yoff + image_off_y - extents.top,
|
yoff + image_off_y - extents.top,
|
||||||
formatEntry->bitmaps[glyphs[idx]],
|
formatEntry->bitmaps[wstr[idx]],
|
||||||
&formatEntry->gis[glyphs[idx]],
|
&formatEntry->gis[wstr[idx]],
|
||||||
physDev->textPixel);
|
physDev->textPixel);
|
||||||
if(deltas) {
|
if(lpDx) {
|
||||||
offset += X11DRV_XWStoDS(physDev, deltas[idx]);
|
offset += lpDx[idx];
|
||||||
xoff = offset * cosEsc;
|
xoff = offset * cosEsc;
|
||||||
yoff = offset * -sinEsc;
|
yoff = offset * -sinEsc;
|
||||||
} else {
|
} else {
|
||||||
xoff += formatEntry->gis[glyphs[idx]].xOff;
|
xoff += formatEntry->gis[wstr[idx]].xOff;
|
||||||
yoff += formatEntry->gis[glyphs[idx]].yOff;
|
yoff += formatEntry->gis[wstr[idx]].yOff;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
XPutImage(gdi_display, physDev->drawable, physDev->gc, image, 0, 0,
|
XPutImage(gdi_display, physDev->drawable, physDev->gc, image, 0, 0,
|
||||||
image_x, image_y, image_w, image_h);
|
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);
|
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)
|
if (flags & ETO_CLIPPED)
|
||||||
{
|
{
|
||||||
/* restore the device region */
|
/* restore the device region */
|
||||||
|
@ -1608,8 +1392,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
||||||
|
|
||||||
done_unlock:
|
done_unlock:
|
||||||
X11DRV_UnlockDIBSection( physDev, TRUE );
|
X11DRV_UnlockDIBSection( physDev, TRUE );
|
||||||
done:
|
|
||||||
if(glyphs != wstr) HeapFree(GetProcessHeap(), 0, (WORD*)glyphs);
|
|
||||||
return retv;
|
return retv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue