From a89595a259b6748e461ea0b731ccf7f73a01014f Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 26 Oct 2020 11:37:03 +0100 Subject: [PATCH] gdi32: Set the font file name directly at creation time. Signed-off-by: Alexandre Julliard --- dlls/gdi32/font.c | 64 ++++++++++++++++++++-------------------- dlls/gdi32/freetype.c | 52 ++++++++++++++++---------------- dlls/gdi32/gdi_private.h | 8 +++-- 3 files changed, 63 insertions(+), 61 deletions(-) diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 9c4fec88e1a..8db5c9b1719 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -417,14 +417,32 @@ static void free_font_handle( DWORD handle ) } } -struct gdi_font *alloc_gdi_font(void) +struct gdi_font *alloc_gdi_font( const WCHAR *file, void *data_ptr, SIZE_T data_size ) { - struct gdi_font *font = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*font) ); + UINT len = file ? strlenW(file) : 0; + struct gdi_font *font = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + offsetof( struct gdi_font, file[len + 1] )); font->refcount = 1; font->matrix.eM11 = font->matrix.eM22 = 1.0; font->scale_y = 1.0; + if (file) + { + WIN32_FILE_ATTRIBUTE_DATA info; + if (GetFileAttributesExW( file, GetFileExInfoStandard, &info )) + { + font->writetime = info.ftLastWriteTime; + font->data_size = (LONGLONG)info.nFileSizeHigh << 32 | info.nFileSizeLow; + memcpy( font->file, file, len * sizeof(WCHAR) ); + } + } + else + { + font->data_ptr = data_ptr; + font->data_size = data_size; + } + if (!(font->handle = alloc_font_handle( font ))) { HeapFree( GetProcessHeap(), 0, font ); @@ -447,7 +465,6 @@ void free_gdi_font( struct gdi_font *font ) for (i = 0; i < font->gm_size; i++) HeapFree( GetProcessHeap(), 0, font->gm[i] ); HeapFree( GetProcessHeap(), 0, font->gm ); HeapFree( GetProcessHeap(), 0, font->name ); - HeapFree( GetProcessHeap(), 0, font->fileinfo ); HeapFree( GetProcessHeap(), 0, font ); } @@ -456,33 +473,6 @@ void set_gdi_font_name( struct gdi_font *font, const WCHAR *name ) font->name = strdupW( name ); } -/* Undocumented structure filled in by GetFontFileInfo */ -struct font_fileinfo -{ - FILETIME writetime; - LARGE_INTEGER size; - WCHAR path[1]; -}; - -void set_gdi_font_file_info( struct gdi_font *font, const WCHAR *file, SIZE_T data_size ) -{ - WIN32_FILE_ATTRIBUTE_DATA info; - int len = 0; - - if (file) len = strlenW( file ); - if (!(font->fileinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - offsetof( struct font_fileinfo, path[len + 1] )))) - return; - - if (file && GetFileAttributesExW( file, GetFileExInfoStandard, &info )) - { - font->fileinfo->writetime = info.ftLastWriteTime; - font->fileinfo->size.QuadPart = (LONGLONG)info.nFileSizeHigh << 32 | info.nFileSizeLow; - strcpyW( font->fileinfo->path, file ); - } - else font->fileinfo->size.QuadPart = data_size; -} - struct glyph_metrics { GLYPHMETRICS gm; @@ -5468,6 +5458,14 @@ BOOL WINAPI GetFontFileData( DWORD instance_id, DWORD unknown, UINT64 offset, vo return ret; } +/* Undocumented structure filled in by GetFontFileInfo */ +struct font_fileinfo +{ + FILETIME writetime; + LARGE_INTEGER size; + WCHAR path[1]; +}; + /************************************************************************* * GetFontFileInfo (GDI32.@) */ @@ -5482,10 +5480,12 @@ BOOL WINAPI GetFontFileInfo( DWORD instance_id, DWORD unknown, struct font_filei if ((font = get_font_from_handle( instance_id ))) { - required_size = sizeof(*info) + strlenW( font->fileinfo->path ) * sizeof(WCHAR); + required_size = sizeof(*info) + strlenW( font->file ) * sizeof(WCHAR); if (required_size <= size) { - memcpy( info, font->fileinfo, required_size ); + info->writetime = font->writetime; + info->size.QuadPart = font->data_size; + strcpyW( info->path, font->file ); ret = TRUE; } else SetLastError( ERROR_INSUFFICIENT_BUFFER ); diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index cf8b2c66e22..5e41ef8bdb1 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -4724,14 +4724,6 @@ static struct gdi_font * CDECL freetype_SelectFont( DC *dc, HFONT hfont, UINT *a goto done; } - TRACE("not in cache\n"); - gdi_font = alloc_gdi_font(); - ret = get_font_ptr( gdi_font ); - - gdi_font->matrix = dcmat; - gdi_font->lf = lf; - gdi_font->can_use_bitmap = can_use_bitmap; - /* If lfFaceName is "Symbol" then Windows fixes up lfCharSet to SYMBOL_CHARSET so that Symbol gets picked irrespective of the original value lfCharSet. Note this is a special case for @@ -4740,6 +4732,9 @@ static struct gdi_font * CDECL freetype_SelectFont( DC *dc, HFONT hfont, UINT *a if(!strcmpiW(lf.lfFaceName, SymbolW)) lf.lfCharSet = SYMBOL_CHARSET; + it = !!lf.lfItalic; + bd = lf.lfWeight > 550; + if(!TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet, &csi, TCI_SRCCHARSET)) { switch(lf.lfCharSet) { case DEFAULT_CHARSET: @@ -4922,7 +4917,6 @@ static struct gdi_font * CDECL freetype_SelectFont( DC *dc, HFONT hfont, UINT *a } if(!last_resort_family) { FIXME("can't find a single appropriate font - bailing\n"); - free_gdi_font(gdi_font); return NULL; } @@ -4931,8 +4925,6 @@ static struct gdi_font * CDECL freetype_SelectFont( DC *dc, HFONT hfont, UINT *a csi.fs.fsCsb[0] = 0; found: - it = lf.lfItalic ? 1 : 0; - bd = lf.lfWeight > 550 ? 1 : 0; height = lf.lfHeight; @@ -4977,12 +4969,19 @@ found: } if(best) face = best->scalable ? best : best_bitmap; - gdi_font->fake_italic = (it && !(face->ntmFlags & NTM_ITALIC)); - gdi_font->fake_bold = (bd && !(face->ntmFlags & NTM_BOLD)); found_face: height = lf.lfHeight; + TRACE("not in cache\n"); + gdi_font = alloc_gdi_font( face->file, face->font_data_ptr, face->font_data_size ); + ret = get_font_ptr( gdi_font ); + + gdi_font->matrix = dcmat; + gdi_font->lf = lf; + gdi_font->can_use_bitmap = can_use_bitmap; + gdi_font->fake_italic = (it && !(face->ntmFlags & NTM_ITALIC)); + gdi_font->fake_bold = (bd && !(face->ntmFlags & NTM_BOLD)); gdi_font->fs = face->fs; if(csi.fs.fsCsb[0]) { @@ -5042,7 +5041,6 @@ found_face: return NULL; } - set_gdi_font_file_info( gdi_font, face->file, face->font_data_size ); gdi_font->ntmFlags = face->ntmFlags; gdi_font->aa_flags = HIWORD( face->flags ); @@ -5242,7 +5240,7 @@ static void GetEnumStructs(Face *face, const WCHAR *family_name, LPENUMLOGFONTEX return; } - gdi_font = alloc_gdi_font(); + gdi_font = alloc_gdi_font( face->file, face->font_data_ptr, face->font_data_size ); font = get_font_ptr( gdi_font ); if(face->scalable) { @@ -7355,6 +7353,7 @@ static UINT CDECL freetype_GetOutlineTextMetrics( struct gdi_font *gdi_font, UIN static BOOL load_child_font(GdiFont *font, CHILD_FONT *child) { struct gdi_font *gdi_font = font->gdi_font; + struct gdi_font *child_font; const struct list *face_list; Face *child_face = NULL, *best_face = NULL; UINT penalty = 0, new_penalty = 0; @@ -7377,24 +7376,25 @@ static BOOL load_child_font(GdiFont *font, CHILD_FONT *child) } child_face = best_face ? best_face : child->face; - child->font = get_font_ptr( alloc_gdi_font() ); + child_font = alloc_gdi_font( child_face->file, child_face->font_data_ptr, child_face->font_data_size ); + child->font = get_font_ptr( child_font ); child->font->ft_face = OpenFontFace( child->font, child_face, 0, -gdi_font->ppem ); if(!child->font->ft_face) { - free_gdi_font(child->font->gdi_font); + free_gdi_font(child_font); child->font = NULL; return FALSE; } - child->font->gdi_font->fake_italic = italic && !( child_face->ntmFlags & NTM_ITALIC ); - child->font->gdi_font->fake_bold = bold && !( child_face->ntmFlags & NTM_BOLD ); - child->font->gdi_font->lf = gdi_font->lf; - child->font->gdi_font->matrix = gdi_font->matrix; - child->font->gdi_font->can_use_bitmap = gdi_font->can_use_bitmap; - child->font->gdi_font->ntmFlags = child_face->ntmFlags; - child->font->gdi_font->aa_flags = HIWORD( child_face->flags ); - child->font->gdi_font->scale_y = gdi_font->scale_y; - set_gdi_font_name( child->font->gdi_font, child_face->family->family_name ); + child_font->fake_italic = italic && !( child_face->ntmFlags & NTM_ITALIC ); + child_font->fake_bold = bold && !( child_face->ntmFlags & NTM_BOLD ); + child_font->lf = gdi_font->lf; + child_font->matrix = gdi_font->matrix; + child_font->can_use_bitmap = gdi_font->can_use_bitmap; + child_font->ntmFlags = child_face->ntmFlags; + child_font->aa_flags = HIWORD( child_face->flags ); + child_font->scale_y = gdi_font->scale_y; + set_gdi_font_name( child_font, child_face->family->family_name ); child->font->base_font = font; TRACE("created child font %p for base %p\n", child->font, font); return TRUE; diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 6d1caf6c65e..c35028e89cb 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -338,7 +338,10 @@ struct gdi_font BOOL fake_bold : 1; BOOL scalable : 1; WCHAR *name; - struct font_fileinfo *fileinfo; + void *data_ptr; + SIZE_T data_size; + FILETIME writetime; + WCHAR file[1]; }; #define MS_MAKE_TAG(ch1,ch2,ch3,ch4) \ @@ -377,13 +380,12 @@ struct font_backend_funcs void (CDECL *destroy_font)( struct gdi_font *font ); }; -extern struct gdi_font *alloc_gdi_font(void) DECLSPEC_HIDDEN; +extern struct gdi_font *alloc_gdi_font( const WCHAR *file, void *data_ptr, SIZE_T data_size ) DECLSPEC_HIDDEN; extern void free_gdi_font( struct gdi_font *font ) DECLSPEC_HIDDEN; extern void cache_gdi_font( struct gdi_font *font ) DECLSPEC_HIDDEN; extern struct gdi_font *find_cached_gdi_font( const LOGFONTW *lf, const FMAT2 *matrix, BOOL can_use_bitmap ) DECLSPEC_HIDDEN; extern void set_gdi_font_name( struct gdi_font *font, const WCHAR *name ) DECLSPEC_HIDDEN; -extern void set_gdi_font_file_info( struct gdi_font *font, const WCHAR *file, SIZE_T data_size ) DECLSPEC_HIDDEN; extern BOOL get_gdi_font_glyph_metrics( struct gdi_font *font, UINT index, GLYPHMETRICS *gm, ABC *abc ) DECLSPEC_HIDDEN; extern void set_gdi_font_glyph_metrics( struct gdi_font *font, UINT index,