From f614ec4d60ed72a41246cd8cd19fd010892bf02b Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Thu, 3 Aug 2023 11:08:23 +0300 Subject: [PATCH] Add FC_FONT_WRAPPER Currently detects only SFNT wrappers: - WOFF: if it is FreeType says it is an SFNT font the file starts with wOFF tag - WOFF2: the same but tag is wOF2 - SFNT: for any other SFNT font (which helps distinguishing standalone CFF fonts from CFF in SFNT aka OTF) Fixes #375 --- doc/fontconfig-devel.sgml | 1 + doc/fontconfig-user.sgml | 2 ++ fontconfig/fontconfig.h | 1 + src/fcfreetype.c | 25 +++++++++++++++++++++++++ src/fcmatch.c | 1 + src/fcobjs.h | 1 + 6 files changed, 31 insertions(+) diff --git a/doc/fontconfig-devel.sgml b/doc/fontconfig-devel.sgml index 2d83d13..d0ff66b 100644 --- a/doc/fontconfig-devel.sgml +++ b/doc/fontconfig-devel.sgml @@ -216,6 +216,7 @@ convenience for the application's rendering mechanism. order FC_ORDER Int Order number of the font desktop FC_DESKTOP_NAME String Current desktop name namedinstance FC_NAMED_INSTANCE Bool Whether font is a named instance + fontwarapper FC_FONT_WRAPPER String The font wrapper format diff --git a/doc/fontconfig-user.sgml b/doc/fontconfig-user.sgml index 917bec7..f24794d 100644 --- a/doc/fontconfig-user.sgml +++ b/doc/fontconfig-user.sgml @@ -148,6 +148,8 @@ fonthashint Bool Whether the font has hinting order Int Order number of the font desktop String Current desktop name namedinstance Bool Whether font is a named instance +fontwarapper String The font wrapper format, current values are WOFF, WOFF2, + and SFNT for any other SFNT font. diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index 28d5866..3911ca1 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -130,6 +130,7 @@ typedef int FcBool; #define FC_ORDER "order" /* Integer */ #define FC_DESKTOP_NAME "desktop" /* String */ #define FC_NAMED_INSTANCE "namedinstance" /* Bool - true if font is named instance */ +#define FC_FONT_WRAPPER "fontwrapper" /* String */ #define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION #define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION diff --git a/src/fcfreetype.c b/src/fcfreetype.c index 6e3aab1..27b72ea 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include FT_FREETYPE_H #include FT_ADVANCES_H @@ -2178,6 +2179,30 @@ FcFreeTypeQueryFaceInternal (const FT_Face face, if (!FcPatternObjectAddBool (pat, FC_NAMED_INSTANCE_OBJECT, !!(id > 0xffff))) goto bail2; + if (face->face_flags & FT_FACE_FLAG_SFNT) + { + /* If this is an SFNT wrapper, try to sniff the SFNT tag which is the + * first 4 bytes, to see if it is a WOFF or WOFF2 wrapper. */ + FcChar8* wrapper = (FcChar8*) "SFNT"; + + char buf[4]; + int fd = FcOpen ((char *) file, O_RDONLY); + if (fd != -1 && read (fd, buf, 4)) + { + if (buf[0] == 'w' && buf[1] == 'O' && buf[2] == 'F') + { + if (buf[3] == 'F') + wrapper = (FcChar8*) "WOFF"; + else if (buf[3] == '2') + wrapper = (FcChar8*) "WOFF2"; + } + } + close (fd); + + if (!FcPatternObjectAddString (pat, FC_FONT_WRAPPER_OBJECT, wrapper)) + goto bail2; + } + /* * Drop our reference to the charset */ diff --git a/src/fcmatch.c b/src/fcmatch.c index a1a40c8..27074d4 100644 --- a/src/fcmatch.c +++ b/src/fcmatch.c @@ -322,6 +322,7 @@ typedef enum _FcMatcherPriorityDummy { typedef enum _FcMatcherPriority { PRI1(FILE), + PRI1(FONT_WRAPPER), PRI1(FONTFORMAT), PRI1(VARIABLE), PRI1(NAMED_INSTANCE), diff --git a/src/fcobjs.h b/src/fcobjs.h index 833a68f..ae3e4c5 100644 --- a/src/fcobjs.h +++ b/src/fcobjs.h @@ -76,4 +76,5 @@ FC_OBJECT (FONT_HAS_HINT, FcTypeBool, FcCompareBool) FC_OBJECT (ORDER, FcTypeInteger, FcCompareNumber) FC_OBJECT (DESKTOP_NAME, FcTypeString, NULL) FC_OBJECT (NAMED_INSTANCE, FcTypeBool, FcCompareBool) +FC_OBJECT (FONT_WRAPPER, FcTypeString, FcCompareString) /* ^-------------- Add new objects here. */