gdi32: Move the realized font handle allocation out of freetype.c.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a6e589bc52
commit
d7a54394d4
|
@ -331,10 +331,82 @@ static inline BOOL is_dbcs_ansi_cp(UINT ansi_cp)
|
|||
|| ansi_cp == 950 ); /* CP950 for Chinese Traditional */
|
||||
}
|
||||
|
||||
/* realized font objects */
|
||||
|
||||
#define FIRST_FONT_HANDLE 1
|
||||
#define MAX_FONT_HANDLES 256
|
||||
|
||||
struct font_handle_entry
|
||||
{
|
||||
struct gdi_font *font;
|
||||
WORD generation; /* generation count for reusing handle values */
|
||||
};
|
||||
|
||||
static struct font_handle_entry font_handles[MAX_FONT_HANDLES];
|
||||
static struct font_handle_entry *next_free;
|
||||
static struct font_handle_entry *next_unused = font_handles;
|
||||
|
||||
static struct font_handle_entry *handle_entry( DWORD handle )
|
||||
{
|
||||
unsigned int idx = LOWORD(handle) - FIRST_FONT_HANDLE;
|
||||
|
||||
if (idx < MAX_FONT_HANDLES)
|
||||
{
|
||||
if (!HIWORD( handle ) || HIWORD( handle ) == font_handles[idx].generation)
|
||||
return &font_handles[idx];
|
||||
}
|
||||
if (handle) WARN( "invalid handle 0x%08x\n", handle );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct gdi_font *get_font_from_handle( DWORD handle )
|
||||
{
|
||||
struct font_handle_entry *entry = handle_entry( handle );
|
||||
|
||||
if (entry) return entry->font;
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static DWORD alloc_font_handle( struct gdi_font *font )
|
||||
{
|
||||
struct font_handle_entry *entry;
|
||||
|
||||
entry = next_free;
|
||||
if (entry)
|
||||
next_free = (struct font_handle_entry *)entry->font;
|
||||
else if (next_unused < font_handles + MAX_FONT_HANDLES)
|
||||
entry = next_unused++;
|
||||
else
|
||||
{
|
||||
ERR( "out of realized font handles\n" );
|
||||
return 0;
|
||||
}
|
||||
entry->font = font;
|
||||
if (++entry->generation == 0xffff) entry->generation = 1;
|
||||
return MAKELONG( entry - font_handles + FIRST_FONT_HANDLE, entry->generation );
|
||||
}
|
||||
|
||||
static void free_font_handle( DWORD handle )
|
||||
{
|
||||
struct font_handle_entry *entry;
|
||||
|
||||
if ((entry = handle_entry( handle )))
|
||||
{
|
||||
entry->font = (struct gdi_font *)next_free;
|
||||
next_free = entry;
|
||||
}
|
||||
}
|
||||
|
||||
struct gdi_font *alloc_gdi_font(void)
|
||||
{
|
||||
struct gdi_font *font = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*font) );
|
||||
|
||||
if (!(font->handle = alloc_font_handle( font )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, font );
|
||||
return NULL;
|
||||
}
|
||||
if (font_funcs && !font_funcs->alloc_font( font ))
|
||||
{
|
||||
free_gdi_font( font );
|
||||
|
@ -346,6 +418,7 @@ struct gdi_font *alloc_gdi_font(void)
|
|||
void free_gdi_font( struct gdi_font *font )
|
||||
{
|
||||
if (font->private) font_funcs->destroy_font( font );
|
||||
free_font_handle( font->handle );
|
||||
HeapFree( GetProcessHeap(), 0, font );
|
||||
}
|
||||
|
||||
|
@ -4986,8 +5059,10 @@ BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
|
|||
*/
|
||||
BOOL WINAPI GetFontFileData( DWORD instance_id, DWORD unknown, UINT64 offset, void *buff, DWORD buff_size )
|
||||
{
|
||||
if (!font_funcs) return FALSE;
|
||||
return font_funcs->pGetFontFileData( instance_id, unknown, offset, buff, buff_size );
|
||||
struct gdi_font *font = get_font_from_handle( instance_id );
|
||||
|
||||
if (!font_funcs || !font) return FALSE;
|
||||
return font_funcs->pGetFontFileData( font, unknown, offset, buff, buff_size );
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -4996,12 +5071,17 @@ BOOL WINAPI GetFontFileData( DWORD instance_id, DWORD unknown, UINT64 offset, vo
|
|||
BOOL WINAPI GetFontFileInfo( DWORD instance_id, DWORD unknown, struct font_fileinfo *info,
|
||||
SIZE_T size, SIZE_T *needed )
|
||||
{
|
||||
if (!font_funcs)
|
||||
SIZE_T required_size;
|
||||
struct gdi_font *font = get_font_from_handle( instance_id );
|
||||
|
||||
if (!needed) needed = &required_size;
|
||||
|
||||
if (!font_funcs || !font)
|
||||
{
|
||||
*needed = 0;
|
||||
return FALSE;
|
||||
}
|
||||
return font_funcs->pGetFontFileInfo( instance_id, unknown, info, size, needed );
|
||||
return font_funcs->pGetFontFileInfo( font, unknown, info, size, needed );
|
||||
}
|
||||
|
||||
struct realization_info
|
||||
|
|
|
@ -324,68 +324,6 @@ typedef struct {
|
|||
|
||||
typedef struct tagGdiFont GdiFont;
|
||||
|
||||
#define FIRST_FONT_HANDLE 1
|
||||
#define MAX_FONT_HANDLES 256
|
||||
|
||||
struct font_handle_entry
|
||||
{
|
||||
void *obj;
|
||||
WORD generation; /* generation count for reusing handle values */
|
||||
};
|
||||
|
||||
static struct font_handle_entry font_handles[MAX_FONT_HANDLES];
|
||||
static struct font_handle_entry *next_free;
|
||||
static struct font_handle_entry *next_unused = font_handles;
|
||||
|
||||
static inline DWORD entry_to_handle( struct font_handle_entry *entry )
|
||||
{
|
||||
unsigned int idx = entry - font_handles + FIRST_FONT_HANDLE;
|
||||
return idx | (entry->generation << 16);
|
||||
}
|
||||
|
||||
static inline struct font_handle_entry *handle_entry( DWORD handle )
|
||||
{
|
||||
unsigned int idx = LOWORD(handle) - FIRST_FONT_HANDLE;
|
||||
|
||||
if (idx < MAX_FONT_HANDLES)
|
||||
{
|
||||
if (!HIWORD( handle ) || HIWORD( handle ) == font_handles[idx].generation)
|
||||
return &font_handles[idx];
|
||||
}
|
||||
if (handle) WARN( "invalid handle 0x%08x\n", handle );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static DWORD alloc_font_handle( void *obj )
|
||||
{
|
||||
struct font_handle_entry *entry;
|
||||
|
||||
entry = next_free;
|
||||
if (entry)
|
||||
next_free = entry->obj;
|
||||
else if (next_unused < font_handles + MAX_FONT_HANDLES)
|
||||
entry = next_unused++;
|
||||
else
|
||||
{
|
||||
ERR( "out of realized font handles\n" );
|
||||
return 0;
|
||||
}
|
||||
entry->obj = obj;
|
||||
if (++entry->generation == 0xffff) entry->generation = 1;
|
||||
return entry_to_handle( entry );
|
||||
}
|
||||
|
||||
static void free_font_handle( DWORD handle )
|
||||
{
|
||||
struct font_handle_entry *entry;
|
||||
|
||||
if ((entry = handle_entry( handle )))
|
||||
{
|
||||
entry->obj = next_free;
|
||||
next_free = entry;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
struct list entry;
|
||||
Face *face;
|
||||
|
@ -429,7 +367,6 @@ struct tagGdiFont {
|
|||
const VOID *vert_feature;
|
||||
ULONG ttc_item_offset; /* 0 if font is not a part of TrueType collection */
|
||||
DWORD cache_num;
|
||||
DWORD instance_id;
|
||||
struct font_fileinfo *fileinfo;
|
||||
};
|
||||
|
||||
|
@ -4174,7 +4111,6 @@ static BOOL CDECL freetype_alloc_font( struct gdi_font *font )
|
|||
ret->font_desc.matrix.eM11 = ret->font_desc.matrix.eM22 = 1.0;
|
||||
ret->total_kern_pairs = (DWORD)-1;
|
||||
ret->kern_pairs = NULL;
|
||||
ret->instance_id = alloc_font_handle(ret);
|
||||
list_init(&ret->child_fonts);
|
||||
ret->gdi_font = font;
|
||||
font->private = ret;
|
||||
|
@ -4200,7 +4136,6 @@ static void CDECL freetype_destroy_font( struct gdi_font *gdi_font )
|
|||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, font->fileinfo);
|
||||
free_font_handle(font->instance_id);
|
||||
if (font->ft_face) pFT_Done_Face(font->ft_face);
|
||||
if (font->mapping) unmap_font_file( font->mapping );
|
||||
HeapFree(GetProcessHeap(), 0, font->kern_pairs);
|
||||
|
@ -4544,7 +4479,7 @@ static void calc_hash(FONT_DESC *pfd)
|
|||
pfd->hash = hash;
|
||||
}
|
||||
|
||||
static GdiFont *find_in_cache(HFONT hfont, const LOGFONTW *plf, const FMAT2 *pmat, BOOL can_use_bitmap)
|
||||
static GdiFont *find_in_cache(const LOGFONTW *plf, const FMAT2 *pmat, BOOL can_use_bitmap)
|
||||
{
|
||||
GdiFont *ret;
|
||||
FONT_DESC fd;
|
||||
|
@ -5058,7 +4993,7 @@ static struct gdi_font * CDECL freetype_SelectFont( struct gdi_font *prev, DC *d
|
|||
EnterCriticalSection( &freetype_cs );
|
||||
|
||||
/* check the cache first */
|
||||
if((ret = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap)) != NULL) {
|
||||
if((ret = find_in_cache(&lf, &dcmat, can_use_bitmap)) != NULL) {
|
||||
TRACE("returning cached gdiFont(%p) for hFont %p\n", ret, hfont);
|
||||
goto done;
|
||||
}
|
||||
|
@ -5350,7 +5285,7 @@ found_face:
|
|||
dcmat.eM11 = dcmat.eM22 = 1.0;
|
||||
/* As we changed the matrix, we need to search the cache for the font again,
|
||||
* otherwise we might explode the cache. */
|
||||
if((cachedfont = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap)) != NULL) {
|
||||
if((cachedfont = find_in_cache(&lf, &dcmat, can_use_bitmap)) != NULL) {
|
||||
TRACE("Found cached font after non-scalable matrix rescale!\n");
|
||||
free_gdi_font( ret->gdi_font );
|
||||
ret = cachedfont;
|
||||
|
@ -8125,7 +8060,7 @@ static BOOL CDECL freetype_GetFontRealizationInfo( struct gdi_font *gdi_font, st
|
|||
info->flags |= 2;
|
||||
|
||||
info->cache_num = font->cache_num;
|
||||
info->instance_id = font->instance_id;
|
||||
info->instance_id = gdi_font->handle;
|
||||
if (info->size == sizeof(*info))
|
||||
{
|
||||
info->unk = 0;
|
||||
|
@ -8143,20 +8078,12 @@ static BOOL CDECL freetype_GetFontRealizationInfo( struct gdi_font *gdi_font, st
|
|||
/*************************************************************************
|
||||
* freetype_GetFontFileData
|
||||
*/
|
||||
static BOOL CDECL freetype_GetFontFileData( DWORD instance_id, DWORD unknown, UINT64 offset,
|
||||
static BOOL CDECL freetype_GetFontFileData( struct gdi_font *gdi_font, DWORD unknown, UINT64 offset,
|
||||
void *buff, DWORD buff_size )
|
||||
{
|
||||
struct font_handle_entry *entry = handle_entry( instance_id );
|
||||
DWORD tag = 0, size;
|
||||
GdiFont *font;
|
||||
GdiFont *font = get_font_ptr( gdi_font );
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
font = entry->obj;
|
||||
if (font->ttc_item_offset)
|
||||
tag = MS_TTCF_TAG;
|
||||
|
||||
|
@ -8174,23 +8101,11 @@ static BOOL CDECL freetype_GetFontFileData( DWORD instance_id, DWORD unknown, UI
|
|||
/*************************************************************************
|
||||
* freetype_GetFontFileInfo
|
||||
*/
|
||||
static BOOL CDECL freetype_GetFontFileInfo( DWORD instance_id, DWORD unknown,
|
||||
static BOOL CDECL freetype_GetFontFileInfo( struct gdi_font *gdi_font, DWORD unknown,
|
||||
struct font_fileinfo *info, SIZE_T size, SIZE_T *needed )
|
||||
{
|
||||
struct font_handle_entry *entry = handle_entry( instance_id );
|
||||
SIZE_T required_size;
|
||||
const GdiFont *font;
|
||||
const GdiFont *font = get_font_ptr( gdi_font );
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!needed)
|
||||
needed = &required_size;
|
||||
|
||||
font = entry->obj;
|
||||
*needed = sizeof(*info) + strlenW(font->fileinfo->path) * sizeof(WCHAR);
|
||||
if (*needed > size)
|
||||
{
|
||||
|
|
|
@ -312,6 +312,7 @@ struct font_fileinfo
|
|||
struct gdi_font
|
||||
{
|
||||
void *private; /* font backend private data */
|
||||
DWORD handle;
|
||||
};
|
||||
|
||||
struct font_backend_funcs
|
||||
|
@ -342,9 +343,9 @@ struct font_backend_funcs
|
|||
HANDLE (CDECL *pAddFontMemResourceEx)( void *font, DWORD size, PVOID pdv, DWORD *count );
|
||||
BOOL (CDECL *pCreateScalableFontResource)( DWORD hidden, LPCWSTR resource,
|
||||
LPCWSTR font_file, LPCWSTR font_path );
|
||||
BOOL (CDECL *pGetFontFileData)( DWORD instance_id, DWORD unknown, UINT64 offset,
|
||||
BOOL (CDECL *pGetFontFileData)( struct gdi_font *font, DWORD unknown, UINT64 offset,
|
||||
void *buff, DWORD buff_size );
|
||||
BOOL (CDECL *pGetFontFileInfo)( DWORD instance_id, DWORD unknown,
|
||||
BOOL (CDECL *pGetFontFileInfo)( struct gdi_font *font, DWORD unknown,
|
||||
struct font_fileinfo *info, SIZE_T size, SIZE_T *needed );
|
||||
|
||||
BOOL (CDECL *alloc_font)( struct gdi_font *font );
|
||||
|
|
Loading…
Reference in New Issue