[PATCH] Refactor AddFontToList to clarify function, and to expose a CreateWineFace function needed for CreateScalableFontResource
Jeremy White
jwhite at codeweavers.com
Thu Oct 9 13:11:29 CDT 2008
---
dlls/gdi32/freetype.c | 351 +++++++++++++++++++++++++++----------------------
1 files changed, 195 insertions(+), 156 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 0baf822..8b4809a 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1311,23 +1311,194 @@ static Family *GetFamily(FT_Face ft_face, char *family_name, char *fake_family)
return family;
}
+static void FreeFace(Face *face)
+{
+ HeapFree(GetProcessHeap(), 0, face->file);
+ HeapFree(GetProcessHeap(), 0, face->StyleName);
+ HeapFree(GetProcessHeap(), 0, face);
+}
-static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, char *fake_family, const WCHAR *target_family, DWORD flags)
+static BOOL FaceExists(Face *newface, Family *family, char *fake_family, Face **face_to_replace)
{
- FT_Face ft_face;
- TT_OS2 *pOS2;
+ struct list *face_elem_ptr;
+ Face *face;
+
+ *face_to_replace = NULL;
+
+ face_elem_ptr = list_head(&family->faces);
+ while(face_elem_ptr) {
+ face = LIST_ENTRY(face_elem_ptr, Face, entry);
+ face_elem_ptr = list_next(&family->faces, face_elem_ptr);
+ if(!strcmpW(face->StyleName, newface->StyleName) &&
+ (newface->scalable || ((newface->size.y_ppem == face->size.y_ppem) &&
+ !memcmp(&newface->fs, &face->fs, sizeof(face->fs)) ))) {
+ TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n",
+ debugstr_w(family->FamilyName), debugstr_w(newface->StyleName),
+ face->font_version, newface->font_version);
+
+ if(fake_family) {
+ TRACE("This font is a replacement but the original really exists, so we'll skip the replacement\n");
+ return TRUE;
+ }
+ if(newface->font_version <= face->font_version) {
+ TRACE("Original font is newer so skipping this one\n");
+ return TRUE;
+ } else {
+ *face_to_replace = face;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+static Face * CreateWineFace(FT_Face ft_face,
+ const char *file, void *font_data_ptr, DWORD font_data_size,
+ DWORD flags, FT_Long face_index, int bitmap_num, Family *family)
+{
+ My_FT_Bitmap_Size *size = NULL;
TT_Header *pHeader = NULL;
- WCHAR *StyleW;
DWORD len;
- Family *family;
- Face *face;
- struct list *face_elem_ptr;
- FT_Long face_index = 0, num_faces;
+ Face * face;
+ FT_ULong tmp_size;
+ WCHAR *StyleW;
+ int i;
+ int internal_leading;
+ FONTSIGNATURE fs;
+ TT_OS2 *pOS2;
#ifdef HAVE_FREETYPE_FTWINFNT_H
FT_WinFNT_HeaderRec winfnt_header;
#endif
- int i, bitmap_num, internal_leading;
- FONTSIGNATURE fs;
+
+ if(FT_IS_SFNT(ft_face))
+ pHeader = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_head);
+
+ if(!FT_IS_SCALABLE(ft_face))
+ size = (My_FT_Bitmap_Size *)ft_face->available_sizes + bitmap_num;
+
+ len = MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, NULL, 0);
+ StyleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, StyleW, len);
+
+ internal_leading = 0;
+ memset(&fs, 0, sizeof(fs));
+
+ pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
+ if(pOS2) {
+ fs.fsCsb[0] = pOS2->ulCodePageRange1;
+ fs.fsCsb[1] = pOS2->ulCodePageRange2;
+ fs.fsUsb[0] = pOS2->ulUnicodeRange1;
+ fs.fsUsb[1] = pOS2->ulUnicodeRange2;
+ fs.fsUsb[2] = pOS2->ulUnicodeRange3;
+ fs.fsUsb[3] = pOS2->ulUnicodeRange4;
+ if(pOS2->version == 0) {
+ FT_UInt dummy;
+
+ if(!pFT_Get_First_Char || (pFT_Get_First_Char( ft_face, &dummy ) < 0x100))
+ fs.fsCsb[0] |= FS_LATIN1;
+ else
+ fs.fsCsb[0] |= FS_SYMBOL;
+ }
+ }
+#ifdef HAVE_FREETYPE_FTWINFNT_H
+ else if(pFT_Get_WinFNT_Header && !pFT_Get_WinFNT_Header(ft_face, &winfnt_header)) {
+ CHARSETINFO csi;
+ TRACE("pix_h %d charset %d dpi %dx%d pt %d\n", winfnt_header.pixel_height, winfnt_header.charset,
+ winfnt_header.vertical_resolution,winfnt_header.horizontal_resolution, winfnt_header.nominal_point_size);
+ if(TranslateCharsetInfo((DWORD*)(UINT_PTR)winfnt_header.charset, &csi, TCI_SRCCHARSET))
+ fs = csi.fs;
+ internal_leading = winfnt_header.internal_leading;
+ }
+#endif
+
+ face = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
+ face->cached_enum_data = NULL;
+ face->StyleName = StyleW;
+ if (file)
+ {
+ face->file = strdupA(file);
+ face->font_data_ptr = NULL;
+ face->font_data_size = 0;
+ }
+ else
+ {
+ face->file = NULL;
+ face->font_data_ptr = font_data_ptr;
+ face->font_data_size = font_data_size;
+ }
+ face->face_index = face_index;
+ face->ntmFlags = 0;
+ if (ft_face->style_flags & FT_STYLE_FLAG_ITALIC)
+ face->ntmFlags |= NTM_ITALIC;
+ if (ft_face->style_flags & FT_STYLE_FLAG_BOLD)
+ face->ntmFlags |= NTM_BOLD;
+ if (face->ntmFlags == 0) face->ntmFlags = NTM_REGULAR;
+ face->font_version = pHeader ? pHeader->Font_Revision : 0;
+ face->family = family;
+ face->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
+ face->fs = fs;
+ memset(&face->fs_links, 0, sizeof(face->fs_links));
+
+ if(FT_IS_SCALABLE(ft_face)) {
+ memset(&face->size, 0, sizeof(face->size));
+ face->scalable = TRUE;
+ } else {
+ TRACE("Adding bitmap size h %d w %d size %ld x_ppem %ld y_ppem %ld\n",
+ size->height, size->width, size->size >> 6,
+ size->x_ppem >> 6, size->y_ppem >> 6);
+ face->size.height = size->height;
+ face->size.width = size->width;
+ face->size.size = size->size;
+ face->size.x_ppem = size->x_ppem;
+ face->size.y_ppem = size->y_ppem;
+ face->size.internal_leading = internal_leading;
+ face->scalable = FALSE;
+ }
+
+ /* check for the presence of the 'CFF ' table to check if the font is Type1 */
+ tmp_size = 0;
+ if (pFT_Load_Sfnt_Table && !pFT_Load_Sfnt_Table(ft_face, FT_MAKE_TAG('C','F','F',' '), 0, NULL, &tmp_size))
+ {
+ TRACE("Font %s/%p is OTF Type1\n", wine_dbgstr_a(file), font_data_ptr);
+ face->ntmFlags |= NTM_PS_OPENTYPE;
+ }
+
+ TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n",
+ face->fs.fsCsb[0], face->fs.fsCsb[1],
+ face->fs.fsUsb[0], face->fs.fsUsb[1],
+ face->fs.fsUsb[2], face->fs.fsUsb[3]);
+
+
+ if(face->fs.fsCsb[0] == 0) { /* let's see if we can find any interesting cmaps */
+ for(i = 0; i < ft_face->num_charmaps; i++) {
+ switch(ft_face->charmaps[i]->encoding) {
+ case FT_ENCODING_UNICODE:
+ case FT_ENCODING_APPLE_ROMAN:
+ face->fs.fsCsb[0] |= FS_LATIN1;
+ break;
+ case FT_ENCODING_MS_SYMBOL:
+ face->fs.fsCsb[0] |= FS_SYMBOL;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return face;
+}
+
+
+static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, char *fake_family, const WCHAR *target_family, DWORD flags)
+{
+ FT_Face ft_face;
+ Family *family;
+ Face *face;
+ Face *face_to_replace;
+ FT_Long face_index = 0, num_faces;
+ int bitmap_num;
/* we always load external fonts from files - otherwise we would get a crash in update_reg_entries */
assert(file || !(flags & ADDFONT_EXTERNAL_FONT));
@@ -1360,9 +1531,6 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
return 0;
num_faces = ft_face->num_faces;
- if(FT_IS_SFNT(ft_face))
- pHeader = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_head);
-
if (target_family)
{
WCHAR *localised_family;
@@ -1382,151 +1550,22 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
bitmap_num = 0;
do {
- My_FT_Bitmap_Size *size = NULL;
- FT_ULong tmp_size;
-
- if(!FT_IS_SCALABLE(ft_face))
- size = (My_FT_Bitmap_Size *)ft_face->available_sizes + bitmap_num;
-
family = GetFamily(ft_face, family_name, fake_family);
- len = MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, NULL, 0);
- StyleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, StyleW, len);
-
- internal_leading = 0;
- memset(&fs, 0, sizeof(fs));
-
- pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
- if(pOS2) {
- fs.fsCsb[0] = pOS2->ulCodePageRange1;
- fs.fsCsb[1] = pOS2->ulCodePageRange2;
- fs.fsUsb[0] = pOS2->ulUnicodeRange1;
- fs.fsUsb[1] = pOS2->ulUnicodeRange2;
- fs.fsUsb[2] = pOS2->ulUnicodeRange3;
- fs.fsUsb[3] = pOS2->ulUnicodeRange4;
- if(pOS2->version == 0) {
- FT_UInt dummy;
-
- if(!pFT_Get_First_Char || (pFT_Get_First_Char( ft_face, &dummy ) < 0x100))
- fs.fsCsb[0] |= FS_LATIN1;
- else
- fs.fsCsb[0] |= FS_SYMBOL;
- }
- }
-#ifdef HAVE_FREETYPE_FTWINFNT_H
- else if(pFT_Get_WinFNT_Header && !pFT_Get_WinFNT_Header(ft_face, &winfnt_header)) {
- CHARSETINFO csi;
- TRACE("pix_h %d charset %d dpi %dx%d pt %d\n", winfnt_header.pixel_height, winfnt_header.charset,
- winfnt_header.vertical_resolution,winfnt_header.horizontal_resolution, winfnt_header.nominal_point_size);
- if(TranslateCharsetInfo((DWORD*)(UINT_PTR)winfnt_header.charset, &csi, TCI_SRCCHARSET))
- fs = csi.fs;
- internal_leading = winfnt_header.internal_leading;
- }
-#endif
-
- face_elem_ptr = list_head(&family->faces);
- while(face_elem_ptr) {
- face = LIST_ENTRY(face_elem_ptr, Face, entry);
- face_elem_ptr = list_next(&family->faces, face_elem_ptr);
- if(!strcmpW(face->StyleName, StyleW) &&
- (FT_IS_SCALABLE(ft_face) || ((size->y_ppem == face->size.y_ppem) && !memcmp(&fs, &face->fs, sizeof(fs)) ))) {
- TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n",
- debugstr_w(family->FamilyName), debugstr_w(StyleW),
- face->font_version, pHeader ? pHeader->Font_Revision : 0);
-
- if(fake_family) {
- TRACE("This font is a replacement but the original really exists, so we'll skip the replacement\n");
- HeapFree(GetProcessHeap(), 0, StyleW);
- pFT_Done_Face(ft_face);
- return 1;
- }
- if(!pHeader || pHeader->Font_Revision <= face->font_version) {
- TRACE("Original font is newer so skipping this one\n");
- HeapFree(GetProcessHeap(), 0, StyleW);
- pFT_Done_Face(ft_face);
- return 1;
- } else {
- TRACE("Replacing original with this one\n");
- list_remove(&face->entry);
- HeapFree(GetProcessHeap(), 0, face->file);
- HeapFree(GetProcessHeap(), 0, face->StyleName);
- HeapFree(GetProcessHeap(), 0, face);
- break;
- }
- }
- }
- face = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
- face->cached_enum_data = NULL;
- face->StyleName = StyleW;
- if (file)
- {
- face->file = strdupA(file);
- face->font_data_ptr = NULL;
- face->font_data_size = 0;
- }
- else
- {
- face->file = NULL;
- face->font_data_ptr = font_data_ptr;
- face->font_data_size = font_data_size;
- }
- face->face_index = face_index;
- face->ntmFlags = 0;
- if (ft_face->style_flags & FT_STYLE_FLAG_ITALIC)
- face->ntmFlags |= NTM_ITALIC;
- if (ft_face->style_flags & FT_STYLE_FLAG_BOLD)
- face->ntmFlags |= NTM_BOLD;
- if (face->ntmFlags == 0) face->ntmFlags = NTM_REGULAR;
- face->font_version = pHeader ? pHeader->Font_Revision : 0;
- face->family = family;
- face->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
- face->fs = fs;
- memset(&face->fs_links, 0, sizeof(face->fs_links));
-
- if(FT_IS_SCALABLE(ft_face)) {
- memset(&face->size, 0, sizeof(face->size));
- face->scalable = TRUE;
- } else {
- TRACE("Adding bitmap size h %d w %d size %ld x_ppem %ld y_ppem %ld\n",
- size->height, size->width, size->size >> 6,
- size->x_ppem >> 6, size->y_ppem >> 6);
- face->size.height = size->height;
- face->size.width = size->width;
- face->size.size = size->size;
- face->size.x_ppem = size->x_ppem;
- face->size.y_ppem = size->y_ppem;
- face->size.internal_leading = internal_leading;
- face->scalable = FALSE;
- }
-
- /* check for the presence of the 'CFF ' table to check if the font is Type1 */
- tmp_size = 0;
- if (pFT_Load_Sfnt_Table && !pFT_Load_Sfnt_Table(ft_face, FT_MAKE_TAG('C','F','F',' '), 0, NULL, &tmp_size))
+ face = CreateWineFace(ft_face, file, font_data_ptr, font_data_size, flags, face_index, bitmap_num, family);
+ if (FaceExists(face, family, fake_family, &face_to_replace))
{
- TRACE("Font %s/%p is OTF Type1\n", wine_dbgstr_a(file), font_data_ptr);
- face->ntmFlags |= NTM_PS_OPENTYPE;
- }
-
- TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n",
- face->fs.fsCsb[0], face->fs.fsCsb[1],
- face->fs.fsUsb[0], face->fs.fsUsb[1],
- face->fs.fsUsb[2], face->fs.fsUsb[3]);
-
-
- if(face->fs.fsCsb[0] == 0) { /* let's see if we can find any interesting cmaps */
- for(i = 0; i < ft_face->num_charmaps; i++) {
- switch(ft_face->charmaps[i]->encoding) {
- case FT_ENCODING_UNICODE:
- case FT_ENCODING_APPLE_ROMAN:
- face->fs.fsCsb[0] |= FS_LATIN1;
- break;
- case FT_ENCODING_MS_SYMBOL:
- face->fs.fsCsb[0] |= FS_SYMBOL;
- break;
- default:
- break;
- }
+ if (face_to_replace)
+ {
+ TRACE("Replacing original face %s with this one %s\n", debugstr_w(face_to_replace->StyleName), debugstr_w(face->StyleName));
+ list_remove(&face_to_replace->entry);
+ FreeFace(face_to_replace);
+ }
+ else
+ {
+ pFT_Done_Face(ft_face);
+ FreeFace(face);
+ return 1;
}
}
@@ -1539,7 +1578,7 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
pFT_Done_Face(ft_face);
TRACE("Added font %s %s\n", debugstr_w(family->FamilyName),
- debugstr_w(StyleW));
+ debugstr_w(face->StyleName));
} while(num_faces > ++face_index);
return num_faces;
}
--
1.5.3.6
--------------090801060605020700020201--
More information about the wine-devel
mailing list