Commit ef0fe443 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Implement SelectFont as a standard driver entry point.

parent 885a4a5c
......@@ -459,7 +459,7 @@ static HBRUSH nulldrv_SelectBrush( PHYSDEV dev, HBRUSH brush )
return brush;
}
static HFONT nulldrv_SelectFont( PHYSDEV dev, HFONT font, HANDLE gdi_font )
static HFONT nulldrv_SelectFont( PHYSDEV dev, HFONT font )
{
return 0;
}
......
......@@ -110,7 +110,7 @@ extern BOOL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom,
extern HBITMAP EMFDRV_SelectBitmap( PHYSDEV dev, HBITMAP handle ) DECLSPEC_HIDDEN;
extern HBRUSH EMFDRV_SelectBrush( PHYSDEV dev, HBRUSH handle ) DECLSPEC_HIDDEN;
extern BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) DECLSPEC_HIDDEN;
extern HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT handle, HANDLE gdiFont ) DECLSPEC_HIDDEN;
extern HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT handle ) DECLSPEC_HIDDEN;
extern HPEN EMFDRV_SelectPen( PHYSDEV dev, HPEN handle ) DECLSPEC_HIDDEN;
extern HPALETTE EMFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPal, BOOL force ) DECLSPEC_HIDDEN;
extern INT EMFDRV_SetArcDirection( PHYSDEV dev, INT arcDirection ) DECLSPEC_HIDDEN;
......
......@@ -310,14 +310,14 @@ static BOOL EMFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont )
/***********************************************************************
* EMFDRV_SelectFont
*/
HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, HANDLE gdiFont )
HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTOBJECT emr;
DWORD index;
int i;
if (physDev->restoring) return 0; /* don't output SelectObject records during RestoreDC */
if (physDev->restoring) goto done; /* don't output SelectObject records during RestoreDC */
/* If the object is a stock font object, do not need to create it.
* See definitions in wingdi.h for range of stock fonts.
......@@ -337,7 +337,7 @@ HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, HANDLE gdiFont )
if((index = EMFDRV_FindObject(dev, hFont)) != 0)
goto found;
if (!(index = EMFDRV_CreateFontIndirect(dev, hFont ))) return HGDI_ERROR;
if (!(index = EMFDRV_CreateFontIndirect(dev, hFont ))) return 0;
GDI_hdc_using_object(hFont, dev->hdc);
found:
......@@ -345,8 +345,11 @@ HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, HANDLE gdiFont )
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return HGDI_ERROR;
return 0;
return 0;
done:
dev = GET_NEXT_PHYSDEV( dev, pSelectFont );
dev->funcs->pSelectFont( dev, hFont );
return hFont;
}
......
......@@ -521,14 +521,6 @@ static void update_font_code_page( DC *dc )
/***********************************************************************
* FONT_SelectObject
*
* If the driver supports vector fonts we create a gdi font first and
* then call the driver to give it a chance to supply its own device
* font. If the driver wants to do this it returns TRUE and we can
* delete the gdi font, if the driver wants to use the gdi font it
* should return FALSE, to signal an error return GDI_ERROR. For
* drivers that don't support vector fonts they must supply their own
* font.
*/
static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, HDC hdc )
{
......@@ -544,26 +536,16 @@ static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, HDC hdc )
return 0;
}
if (GetDeviceCaps( dc->hSelf, TEXTCAPS ) & TC_VA_ABLE)
dc->gdiFont = WineEngCreateFontInstance( dc, handle );
physdev = GET_DC_PHYSDEV( dc, pSelectFont );
ret = physdev->funcs->pSelectFont( physdev, handle, dc->gdiFont );
if (ret && dc->gdiFont) dc->gdiFont = 0;
if (ret == HGDI_ERROR)
{
GDI_dec_ref_count( handle );
ret = 0; /* SelectObject returns 0 on error */
}
else
if (physdev->funcs->pSelectFont( physdev, handle ))
{
ret = dc->hFont;
dc->hFont = handle;
update_font_code_page( dc );
GDI_dec_ref_count( ret );
}
else GDI_dec_ref_count( handle );
release_dc_ptr( dc );
return ret;
}
......
......@@ -378,6 +378,7 @@ static struct list font_list = LIST_INIT(font_list);
struct freetype_physdev
{
struct gdi_physdev dev;
GdiFont *font;
};
static inline struct freetype_physdev *get_freetype_dev( PHYSDEV dev )
......@@ -3813,11 +3814,11 @@ static BOOL freetype_DeleteDC( PHYSDEV dev )
/*************************************************************
* WineEngCreateFontInstance
*
* freetype_SelectFont
*/
GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
static HFONT freetype_SelectFont( PHYSDEV dev, HFONT hfont )
{
struct freetype_physdev *physdev = get_freetype_dev( dev );
GdiFont *ret;
Face *face, *best, *best_bitmap;
Family *family, *last_resort_family;
......@@ -3831,11 +3832,20 @@ GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
HFONTLIST *hflist;
FMAT2 dcmat;
FontSubst *psub = NULL;
DC *dc = get_dc_ptr( dev->hdc );
if (!hfont) /* notification that the font has been changed by another driver */
{
dc->gdiFont = NULL;
physdev->font = NULL;
release_dc_ptr( dc );
return 0;
}
if (!GetObjectW( hfont, sizeof(lf), &lf )) return NULL;
GetObjectW( hfont, sizeof(lf), &lf );
lf.lfWidth = abs(lf.lfWidth);
can_use_bitmap = GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_RA_ABLE;
can_use_bitmap = GetDeviceCaps(dev->hdc, TEXTCAPS) & TC_RA_ABLE;
TRACE("%s, h=%d, it=%d, weight=%d, PandF=%02x, charset=%d orient %d escapement %d\n",
debugstr_w(lf.lfFaceName), lf.lfHeight, lf.lfItalic,
......@@ -3869,18 +3879,16 @@ GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
/* check the cache first */
if((ret = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap)) != NULL) {
TRACE("returning cached gdiFont(%p) for hFont %p\n", ret, hfont);
LeaveCriticalSection( &freetype_cs );
return ret;
goto done;
}
TRACE("not in cache\n");
if(list_empty(&font_list)) /* No fonts installed */
{
TRACE("No fonts installed\n");
LeaveCriticalSection( &freetype_cs );
return NULL;
goto done;
}
TRACE("not in cache\n");
ret = alloc_font();
ret->font_desc.matrix = dcmat;
......@@ -4067,8 +4075,8 @@ GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
if(!last_resort_family) {
FIXME("can't find a single appropriate font - bailing\n");
free_font(ret);
LeaveCriticalSection( &freetype_cs );
return NULL;
ret = NULL;
goto done;
}
WARN("could only find a bitmap font - this will probably look awful!\n");
......@@ -4154,8 +4162,8 @@ found_face:
if((cachedfont = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap)) != NULL) {
TRACE("Found cached font after non-scalable matrix rescale!\n");
free_font( ret );
LeaveCriticalSection( &freetype_cs );
return cachedfont;
ret = cachedfont;
goto done;
}
calc_hash(&ret->font_desc);
......@@ -4182,8 +4190,8 @@ found_face:
if (!ret->ft_face)
{
free_font( ret );
LeaveCriticalSection( &freetype_cs );
return 0;
ret = NULL;
goto done;
}
ret->ntmFlags = face->ntmFlags;
......@@ -4219,8 +4227,15 @@ found_face:
TRACE("caching: gdiFont=%p hfont=%p\n", ret, hfont);
add_to_cache(ret);
done:
if (ret)
{
dc->gdiFont = ret;
physdev->font = ret;
}
LeaveCriticalSection( &freetype_cs );
return ret;
release_dc_ptr( dc );
return ret ? hfont : 0;
}
static void dump_gdi_font_list(void)
......@@ -7099,7 +7114,7 @@ static const struct gdi_dc_funcs freetype_funcs =
NULL, /* pSelectBitmap */
NULL, /* pSelectBrush */
NULL, /* pSelectClipPath */
NULL, /* pSelectFont */
freetype_SelectFont, /* pSelectFont */
NULL, /* pSelectPalette */
NULL, /* pSelectPen */
NULL, /* pSetArcDirection */
......@@ -7149,10 +7164,6 @@ BOOL WineEngInit(void)
{
return FALSE;
}
GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
{
return NULL;
}
BOOL WineEngDestroyFontInstance(HFONT hfont)
{
return FALSE;
......
......@@ -291,7 +291,6 @@ typedef struct
extern INT WineEngAddFontResourceEx(LPCWSTR, DWORD, PVOID) DECLSPEC_HIDDEN;
extern HANDLE WineEngAddFontMemResourceEx(PVOID, DWORD, PVOID, LPDWORD) DECLSPEC_HIDDEN;
extern GdiFont* WineEngCreateFontInstance(DC*, HFONT) DECLSPEC_HIDDEN;
extern BOOL WineEngDestroyFontInstance(HFONT handle) DECLSPEC_HIDDEN;
extern DWORD WineEngEnumFonts(LPLOGFONTW, FONTENUMPROCW, LPARAM) DECLSPEC_HIDDEN;
extern BOOL WineEngGetCharABCWidths(GdiFont *font, UINT firstChar,
......
......@@ -105,7 +105,7 @@ extern BOOL MFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
extern HBITMAP MFDRV_SelectBitmap( PHYSDEV dev, HBITMAP handle ) DECLSPEC_HIDDEN;
extern HBRUSH MFDRV_SelectBrush( PHYSDEV dev, HBRUSH handle ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) DECLSPEC_HIDDEN;
extern HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT handle, HANDLE gdiFont ) DECLSPEC_HIDDEN;
extern HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT handle ) DECLSPEC_HIDDEN;
extern HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN handle ) DECLSPEC_HIDDEN;
extern HPALETTE MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground) DECLSPEC_HIDDEN;
extern UINT MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL primary) DECLSPEC_HIDDEN;
......
......@@ -328,7 +328,7 @@ static UINT16 MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONTW *logfo
/***********************************************************************
* MFDRV_SelectFont
*/
HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT hfont )
{
LOGFONTW font;
INT16 index;
......@@ -337,13 +337,13 @@ HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
if( index < 0 )
{
if (!GetObjectW( hfont, sizeof(font), &font ))
return HGDI_ERROR;
return 0;
index = MFDRV_CreateFontIndirect(dev, hfont, &font);
if( index < 0 )
return HGDI_ERROR;
return 0;
GDI_hdc_using_object(hfont, dev->hdc);
}
return MFDRV_SelectObject( dev, index ) ? hfont : HGDI_ERROR;
return MFDRV_SelectObject( dev, index ) ? hfont : 0;
}
/******************************************************************
......
......@@ -36,14 +36,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
/***********************************************************************
* SelectFont (WINEPS.@)
*/
HFONT PSDRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
HFONT PSDRV_SelectFont( PHYSDEV dev, HFONT hfont )
{
PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectFont );
HFONT ret;
LOGFONTW lf;
BOOL subst = FALSE;
char FaceName[LF_FACESIZE];
if (!GetObjectW( hfont, sizeof(lf), &lf )) return HGDI_ERROR;
if (!GetObjectW( hfont, sizeof(lf), &lf )) return 0;
TRACE("FaceName = %s Height = %d Italic = %d Weight = %d\n",
debugstr_w(lf.lfFaceName), lf.lfHeight, lf.lfItalic,
......@@ -112,13 +114,15 @@ HFONT PSDRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
physDev->font.escapement = lf.lfEscapement;
physDev->font.set = FALSE;
if(gdiFont && !subst) {
if(PSDRV_SelectDownloadFont(dev))
return 0; /* use gdi font */
if (!subst && ((ret = next->funcs->pSelectFont( next, hfont ))))
{
PSDRV_SelectDownloadFont(dev);
return ret;
}
PSDRV_SelectBuiltinFont(dev, hfont, &lf, FaceName);
return (HFONT)1; /* use device font */
next->funcs->pSelectFont( next, 0 ); /* tell next driver that we selected a device font */
return hfont;
}
/***********************************************************************
......
......@@ -451,7 +451,7 @@ extern BOOL PSDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT ell_width, INT ell_height ) DECLSPEC_HIDDEN;
extern HBRUSH PSDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush ) DECLSPEC_HIDDEN;
extern HBRUSH PSDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush ) DECLSPEC_HIDDEN;
extern HFONT PSDRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont ) DECLSPEC_HIDDEN;
extern HFONT PSDRV_SelectFont( PHYSDEV dev, HFONT hfont ) DECLSPEC_HIDDEN;
extern HPEN PSDRV_SelectPen( PHYSDEV dev, HPEN hpen ) DECLSPEC_HIDDEN;
extern COLORREF PSDRV_SetBkColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern COLORREF PSDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
......
......@@ -222,7 +222,7 @@ extern BOOL X11DRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bot
INT ell_width, INT ell_height ) DECLSPEC_HIDDEN;
extern HBITMAP X11DRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern HBRUSH X11DRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush ) DECLSPEC_HIDDEN;
extern HFONT X11DRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont ) DECLSPEC_HIDDEN;
extern HFONT X11DRV_SelectFont( PHYSDEV dev, HFONT hfont ) DECLSPEC_HIDDEN;
extern HPEN X11DRV_SelectPen( PHYSDEV dev, HPEN hpen ) DECLSPEC_HIDDEN;
extern COLORREF X11DRV_SetBkColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern COLORREF X11DRV_SetDCBrushColor( PHYSDEV dev, COLORREF crColor ) DECLSPEC_HIDDEN;
......
......@@ -3226,24 +3226,32 @@ XFontStruct* XFONT_GetFontStruct( X_PHYSFONT pFont )
/***********************************************************************
* SelectFont (X11DRV.@)
*/
HFONT X11DRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
HFONT X11DRV_SelectFont( PHYSDEV dev, HFONT hfont )
{
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectFont );
fontObject *pfo = XFONT_GetFontObject( physDev->font );
LOGFONTW logfont;
LOGFONT16 lf;
HFONT ret;
TRACE("hdc=%p, hfont=%p\n", dev->hdc, hfont);
if (!GetObjectW( hfont, sizeof(logfont), &logfont )) return HGDI_ERROR;
if (using_client_side_fonts && ((ret = next->funcs->pSelectFont( next, hfont ))))
{
if (pfo) XFONT_ReleaseCacheEntry( pfo );
physDev->font = 0;
physDev->has_gdi_font = TRUE;
return ret;
}
TRACE("gdiFont = %p\n", gdiFont);
GetObjectW( hfont, sizeof(logfont), &logfont );
EnterCriticalSection( &crtsc_fonts_X11 );
if(fontList == NULL) X11DRV_FONT_InitX11Metrics();
if( CHECK_PFONT(physDev->font) )
XFONT_ReleaseCacheEntry( __PFONT(physDev->font) );
if (pfo) XFONT_ReleaseCacheEntry( pfo );
FONT_LogFontWTo16(&logfont, &lf);
......@@ -3306,7 +3314,8 @@ HFONT X11DRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
LeaveCriticalSection( &crtsc_fonts_X11 );
physDev->has_gdi_font = FALSE;
return (HFONT)1; /* Use a device font */
next->funcs->pSelectFont( next, 0 ); /* tell next driver that we selected a device font */
return hfont;
}
......
......@@ -1096,42 +1096,50 @@ void X11DRV_XRender_Finalize(void)
/**********************************************************************
* xrenderdrv_SelectFont
*/
static HFONT xrenderdrv_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
static HFONT xrenderdrv_SelectFont( PHYSDEV dev, HFONT hfont )
{
struct xrender_physdev *physdev = get_xrender_dev( dev );
LFANDSIZE lfsz;
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectFont );
HFONT ret = next->funcs->pSelectFont( next, hfont );
if (!GetObjectW( hfont, sizeof(lfsz.lf), &lfsz.lf )) return HGDI_ERROR;
if (!ret) return 0;
if (!gdiFont)
if (physdev->x11dev->has_gdi_font)
{
dev = GET_NEXT_PHYSDEV( dev, pSelectFont );
return dev->funcs->pSelectFont( dev, hfont, gdiFont );
}
LFANDSIZE lfsz;
TRACE("h=%d w=%d weight=%d it=%d charset=%d name=%s\n",
lfsz.lf.lfHeight, lfsz.lf.lfWidth, lfsz.lf.lfWeight,
lfsz.lf.lfItalic, lfsz.lf.lfCharSet, debugstr_w(lfsz.lf.lfFaceName));
lfsz.lf.lfWidth = abs( lfsz.lf.lfWidth );
lfsz.devsize.cx = X11DRV_XWStoDS( dev->hdc, lfsz.lf.lfWidth );
lfsz.devsize.cy = X11DRV_YWStoDS( dev->hdc, lfsz.lf.lfHeight );
GetObjectW( hfont, sizeof(lfsz.lf), &lfsz.lf );
GetTransform( dev->hdc, 0x204, &lfsz.xform );
TRACE("font transform %f %f %f %f\n", lfsz.xform.eM11, lfsz.xform.eM12,
lfsz.xform.eM21, lfsz.xform.eM22);
TRACE("h=%d w=%d weight=%d it=%d charset=%d name=%s\n",
lfsz.lf.lfHeight, lfsz.lf.lfWidth, lfsz.lf.lfWeight,
lfsz.lf.lfItalic, lfsz.lf.lfCharSet, debugstr_w(lfsz.lf.lfFaceName));
lfsz.lf.lfWidth = abs( lfsz.lf.lfWidth );
lfsz.devsize.cx = X11DRV_XWStoDS( dev->hdc, lfsz.lf.lfWidth );
lfsz.devsize.cy = X11DRV_YWStoDS( dev->hdc, lfsz.lf.lfHeight );
/* Not used fields, would break hashing */
lfsz.xform.eDx = lfsz.xform.eDy = 0;
GetTransform( dev->hdc, 0x204, &lfsz.xform );
TRACE("font transform %f %f %f %f\n", lfsz.xform.eM11, lfsz.xform.eM12,
lfsz.xform.eM21, lfsz.xform.eM22);
lfsz_calc_hash(&lfsz);
/* Not used fields, would break hashing */
lfsz.xform.eDx = lfsz.xform.eDy = 0;
EnterCriticalSection(&xrender_cs);
if (physdev->cache_index != -1)
dec_ref_cache( physdev->cache_index );
physdev->cache_index = GetCacheEntry( dev->hdc, &lfsz );
LeaveCriticalSection(&xrender_cs);
physdev->x11dev->has_gdi_font = TRUE;
return 0;
lfsz_calc_hash(&lfsz);
EnterCriticalSection(&xrender_cs);
if (physdev->cache_index != -1)
dec_ref_cache( physdev->cache_index );
physdev->cache_index = GetCacheEntry( dev->hdc, &lfsz );
LeaveCriticalSection(&xrender_cs);
}
else
{
EnterCriticalSection( &xrender_cs );
if (physdev->cache_index != -1) dec_ref_cache( physdev->cache_index );
physdev->cache_index = -1;
LeaveCriticalSection( &xrender_cs );
}
return ret;
}
static BOOL create_xrender_dc( PHYSDEV *pdev, enum wxr_format format )
......
......@@ -134,7 +134,7 @@ struct gdi_dc_funcs
HBITMAP (*pSelectBitmap)(PHYSDEV,HBITMAP);
HBRUSH (*pSelectBrush)(PHYSDEV,HBRUSH);
BOOL (*pSelectClipPath)(PHYSDEV,INT);
HFONT (*pSelectFont)(PHYSDEV,HFONT,HANDLE);
HFONT (*pSelectFont)(PHYSDEV,HFONT);
HPALETTE (*pSelectPalette)(PHYSDEV,HPALETTE,BOOL);
HPEN (*pSelectPen)(PHYSDEV,HPEN);
INT (*pSetArcDirection)(PHYSDEV,INT);
......@@ -190,7 +190,7 @@ struct gdi_dc_funcs
};
/* increment this when you change the DC function table */
#define WINE_GDI_DRIVER_VERSION 14
#define WINE_GDI_DRIVER_VERSION 15
static inline PHYSDEV get_physdev_entry_point( PHYSDEV dev, size_t offset )
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment