Patch: font capability detection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



--=-cEXAg+CC2NG7/dfxRmse
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi,
I guess the fontconfig bugzilla isn't around anymore (or at least no
obvious links or google for it).

Anyway, here is the patch I was working on for detection of silgraphite
fonts and opentype layout scripts.

Regards,
Daniel

--=-cEXAg+CC2NG7/dfxRmse
Content-Disposition: attachment; filename=fc1.diff
Content-Type: text/x-patch; name=fc1.diff; charset=UTF-8
Content-Transfer-Encoding: 7bit

Index: fontconfig/fontconfig.h
===================================================================
RCS file: /cvs/fontconfig/fontconfig/fontconfig/fontconfig.h,v
retrieving revision 1.50
diff -u -w -r1.50 fontconfig.h
--- fontconfig/fontconfig.h	27 Oct 2003 10:47:53 -0000	1.50
+++ fontconfig/fontconfig.h	7 Nov 2003 19:36:31 -0000
@@ -1,7 +1,7 @@
 /*
  * $RCSId: xc/lib/fontconfig/fontconfig/fontconfig.h,v 1.30 2002/09/26 00:17:27 keithp Exp $
  *
- * Copyright © 2001 Keith Packard
+ * Copyright  2001 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -89,6 +89,7 @@
 #define FC_CHARSET	    "charset"		/* CharSet */
 #define FC_LANG		    "lang"		/* String RFC 3066 langs */
 #define FC_FONTVERSION	    "fontversion"	/* Int from 'head' table */
+#define FC_FONTCAP	    "fontcap"		/* String */
 
 #define FC_DIR_CACHE_FILE	    "fonts.cache-"FC_CACHE_VERSION
 #define FC_USER_CACHE_FILE	    ".fonts.cache-"FC_CACHE_VERSION
Index: src/fcfreetype.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fcfreetype.c,v
retrieving revision 1.41
diff -u -w -r1.41 fcfreetype.c
--- src/fcfreetype.c	6 Sep 2003 19:40:41 -0000	1.41
+++ src/fcfreetype.c	7 Nov 2003 19:36:41 -0000
@@ -1,7 +1,7 @@
 /*
  * $RCSId: xc/lib/fontconfig/src/fcfreetype.c,v 1.11 2002/08/31 22:17:32 keithp Exp $
  *
- * Copyright © 2001 Keith Packard
+ * Copyright  2001 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -23,7 +23,7 @@
  */
 
 /*
-  Copyright © 2002-2003 by Juliusz Chroboczek
+  Copyright  2002-2003 by Juliusz Chroboczek
 
   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
@@ -50,6 +50,8 @@
 #include "fcint.h"
 #include <freetype/freetype.h>
 #include <freetype/internal/ftobjs.h>
+#include <freetype/internal/sfnt.h>
+#include <freetype/internal/ftstream.h>
 #include <freetype/tttables.h>
 #include <freetype/ftsnames.h>
 #include <freetype/ttnameid.h>
@@ -360,6 +362,7 @@
     FT_Library	    ftLibrary;
     FcChar8	    *family = 0;
     FcChar8	    *style = 0;
+	 FcChar8	    *complex = 0;
     const FcChar8   *foundry = 0;
     int		    spacing;
     TT_OS2	    *os2;
@@ -375,6 +378,7 @@
     FT_UInt    	    snamei, snamec;
     FcBool	    family_allocated = FcFalse;
     FcBool	    style_allocated = FcFalse;
+	 FcBool	    complex_allocated = FcFalse;
     int		    family_prio = 0;
     int		    style_prio = 0;
 
@@ -795,6 +799,12 @@
 	case 9:	width = FC_WIDTH_ULTRAEXPANDED; break;
 	}
     }
+    if (os2 && FcFontCapabilities(face, &complex))
+    {
+    	complex_allocated = FcTrue;
+	if (!FcPatternAddString (pat, FC_FONTCAP, complex))
+	    goto bail1;
+    }
 
     /*
      * Type 1: Check for FontInfo dictionary information
@@ -1050,6 +1060,9 @@
 	free (family);
     if (style_allocated)
 	free (style);
+    if (complex_allocated)
+	free (complex);
+
     
     FT_Done_Face (face);
     FT_Done_FreeType (ftLibrary);
@@ -2042,3 +2055,178 @@
 
     return FcFreeTypeCharSetAndSpacing (face, blanks, &spacing);
 }
+
+
+#define TTAG_GPOS  FT_MAKE_TAG( 'G', 'P', 'O', 'S' )
+#define TTAG_GSUB  FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
+#define TTAG_SILF  FT_MAKE_TAG( 'S', 'i', 'l', 'f')
+#define TT_Err_Ok FT_Err_Ok
+#define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle
+#define TTO_Err_Empty_Script              0x1005
+#define TTO_Err_Invalid_SubTable          0x1001
+
+
+void addtag(FcChar8 *complex, FT_ULong tag)
+{
+    FcChar8 tagstring[15];
+    sprintf (tagstring, "otlayout:%c%c%c%c ",
+       (unsigned char)(tag >> 24),
+       (unsigned char)((tag & 0xff0000) >> 16),
+       (unsigned char)((tag & 0xff00) >> 8),
+       (unsigned char)(tag & 0xff));
+    strncat(complex, tagstring, 14);
+}
+
+static int compareulong (const void *a, const void *b)
+{
+    const FT_ULong *ua = (const FT_ULong *) a;
+    const FT_ULong *ub = (const FT_ULong *) b;
+    return *ua - *ub;
+}
+
+
+FT_Error GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *script_count)
+{
+    FT_ULong         cur_offset, new_offset, base_offset;
+    FT_UShort        i, num_lookups;
+    TT_Face          tt_face = (TT_Face)face;
+    FT_Stream  stream = face->stream;
+    FT_Error   error;
+    FT_UShort          n, p;
+    FT_Memory  memory = stream->memory;
+
+    if ( !stream )
+      return TT_Err_Invalid_Face_Handle;
+
+    if (( error = tt_face->goto_table( tt_face, tabletag, stream, 0 ) ))
+      return error;
+
+    base_offset = FT_STREAM_POS();
+
+    /* skip version */
+
+    if ( FT_STREAM_SEEK( base_offset + 4L ) ||
+         FT_FRAME_ENTER( 2L ) )
+      return error;
+
+    new_offset = FT_GET_USHORT() + base_offset;
+
+    FT_FRAME_EXIT();
+
+    cur_offset = FT_STREAM_POS();
+
+    if ( FT_STREAM_SEEK( new_offset ) != TT_Err_Ok )
+      return error;
+
+    base_offset = FT_STREAM_POS();
+
+    if ( FT_FRAME_ENTER( 2L ) )
+      return error;
+
+    *script_count = FT_GET_USHORT();
+
+    FT_FRAME_EXIT();
+
+    if ( FT_SET_ERROR (FT_MEM_ALLOC_ARRAY( *stags, *script_count, FT_ULong )) )
+      return error;
+
+    p = 0;
+    for ( n = 0; n < *script_count; n++ )
+    {
+      if ( FT_FRAME_ENTER( 6L ) )
+        goto Fail;
+
+      (*stags)[p] = FT_GET_ULONG();
+      new_offset = FT_GET_USHORT() + base_offset;
+
+      FT_FRAME_EXIT();
+
+      cur_offset = FT_STREAM_POS();
+
+      if ( FT_STREAM_SEEK( new_offset ) )
+	goto Fail;
+
+      if ( error == TT_Err_Ok )
+        p++;
+      else if ( error != TTO_Err_Empty_Script )
+	goto Fail;
+
+      (void)FT_STREAM_SEEK( cur_offset );
+    }
+
+    if (!p)
+    {
+      error = TTO_Err_Invalid_SubTable;
+      goto Fail;
+    }
+
+    // sort the tag list before returning it
+    qsort(*stags, *script_count, sizeof(FT_ULong), compareulong);
+
+    return TT_Err_Ok;
+
+  Fail:
+    FT_FREE( *stags );
+    return error;
+}
+
+
+FcBool FcFontCapabilities(FT_Face face, FcChar8 **complex)
+{
+    FcBool issilgraphitefont = 0;
+    FT_Error err;
+    FT_ULong len = 0;
+    FT_ULong *gsubtags=NULL, *gpostags=NULL;
+    FT_UShort gsub_count=0, gpos_count=0, maxsize;
+    FT_Memory  memory = face->stream->memory;
+
+    if (*complex)
+    {
+    	free(*complex);
+	*complex = 0;
+    }
+    err = FT_Load_Sfnt_Table(face, TTAG_SILF, 0, 0, &len);
+    issilgraphitefont = ( err == FT_Err_Ok);
+
+    err = GetScriptTags(face, TTAG_GPOS, &gpostags, &gpos_count);
+    err = GetScriptTags(face, TTAG_GSUB, &gsubtags, &gsub_count);
+    if (!issilgraphitefont && !gsub_count && !gpos_count)
+    {
+    	goto bail;
+    }
+
+    maxsize = ((gpos_count + gsub_count) * 15) + (issilgraphitefont ? 13 : 0);
+    *complex = (FcChar8 *) malloc (sizeof (FcChar8) * maxsize);
+    if (issilgraphitefont)
+    {
+        strcpy(*complex, "ttable:Silf ");
+    }
+    else
+    {
+        strcpy(*complex, "");
+    }
+
+   int indx1 = 0, indx2 = 0;
+      while ((indx1 < gsub_count) || (indx2 < gpos_count)) {
+         if (indx1 == gsub_count) {
+            addtag(*complex, gpostags[indx2]);
+            indx2++;
+         } else if ((indx2 == gpos_count) || (gsubtags[indx1] < gpostags[indx2])) {
+            addtag(*complex, gsubtags[indx1]);
+            indx1++;
+         } else if (gsubtags[indx1] == gpostags[indx2]) {
+            addtag(*complex, gsubtags[indx1]);
+            indx1++;
+            indx2++;
+         } else {
+            addtag(*complex, gpostags[indx2]);
+            indx2++;
+         }
+      }
+      if (FcDebug () & FC_DBG_PARSE)
+	printf("complex features in this font: %s\n", *complex);
+bail:
+    FT_FREE(gsubtags);
+    FT_FREE(gpostags);
+    return (*complex)!=NULL;
+}
Index: src/fcname.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fcname.c,v
retrieving revision 1.21
diff -u -w -r1.21 fcname.c
--- src/fcname.c	23 Sep 2003 20:12:20 -0000	1.21
+++ src/fcname.c	7 Nov 2003 19:36:44 -0000
@@ -1,7 +1,7 @@
 /*
  * $RCSId: xc/lib/fontconfig/src/fcname.c,v 1.15 2002/09/26 00:17:28 keithp Exp $
  *
- * Copyright © 2000 Keith Packard
+ * Copyright  2000 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -63,6 +63,7 @@
     { FC_CHARSET,	FcTypeCharSet },
     { FC_LANG,		FcTypeLangSet },
     { FC_FONTVERSION,	FcTypeInteger },
+	 { FC_FONTCAP,	FcTypeString },
 };
 
 #define NUM_OBJECT_TYPES    (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0])

--=-cEXAg+CC2NG7/dfxRmse--




[Index of Archives]     [Fedora Fonts]     [Fedora Users]     [Fedora Cloud]     [Kernel]     [Fedora Packaging]     [Fedora Desktop]     [PAM]     [Gimp Graphics Editor]     [Yosemite News]

  Powered by Linux