diff --git a/fontconfig/fcprivate.h b/fontconfig/fcprivate.h index ec964fc..e71e58b 100644 --- a/fontconfig/fcprivate.h +++ b/fontconfig/fcprivate.h @@ -67,6 +67,9 @@ case FcTypeMatrix: \ __v__.u.m = va_arg (va, const FcMatrix *); \ break; \ + case FcTypePanose: \ + __v__.u.m = va_arg (va, const FcPanose *); \ + break; \ case FcTypeCharSet: \ __v__.u.c = va_arg (va, const FcCharSet *); \ break; \ diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index c9f20cc..67d1433 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -111,6 +111,8 @@ typedef int FcBool; #define FC_EMBEDDED_BITMAP "embeddedbitmap" /* Bool - true to enable embedded bitmaps */ #define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */ #define FC_LCD_FILTER "lcdfilter" /* Int */ +#define FC_OS2_FAMILYCLASS "familyclass" /* Int (16bit) */ +#define FC_OS2_PANOSE "panose" /* FcPanose */ #define FC_CACHE_SUFFIX ".cache-"FC_CACHE_VERSION #define FC_DIR_CACHE_FILE "fonts.cache-"FC_CACHE_VERSION @@ -187,7 +189,8 @@ typedef enum _FcType { FcTypeMatrix, FcTypeCharSet, FcTypeFTFace, - FcTypeLangSet + FcTypeLangSet, + FcTypePanose } FcType; typedef struct _FcMatrix { @@ -197,6 +200,11 @@ typedef struct _FcMatrix { #define FcMatrixInit(m) ((m)->xx = (m)->yy = 1, \ (m)->xy = (m)->yx = 0) +typedef struct _FcPanose { + FcChar8 b[10]; +} FcPanose; + + /* * A data structure to represent the available glyphs in a font. * This is represented as a sparse boolean btree. @@ -235,6 +243,7 @@ typedef struct _FcValue { const FcCharSet *c; void *f; const FcLangSet *l; + const FcPanose *panose; } u; } FcValue; @@ -709,6 +718,13 @@ FcMatrixScale (FcMatrix *m, double sx, double sy); FcPublic void FcMatrixShear (FcMatrix *m, double sh, double sv); +/* fcpanose.c */ +FcPanose * +FcPanoseCopy (const FcPanose *panose_src); + +FcBool +FcPanoseEqual (const FcPanose *panose1, const FcPanose *panose2); + /* fcname.c */ FcPublic FcBool @@ -800,6 +816,9 @@ FcPublic FcBool FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s); FcPublic FcBool +FcPatternAddPanose (FcPattern *p, const char *object, const FcPanose *panose); + +FcPublic FcBool FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c); FcPublic FcBool @@ -821,6 +840,9 @@ FcPublic FcResult FcPatternGetMatrix (const FcPattern *p, const char *object, int n, FcMatrix **s); FcPublic FcResult +FcPatternGetPanose (const FcPattern *p, const char *object, int n, FcPanose **panose); + +FcPublic FcResult FcPatternGetCharSet (const FcPattern *p, const char *object, int n, FcCharSet **c); FcPublic FcResult diff --git a/src/Makefile.am b/src/Makefile.am index 406e85e..9287253 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -116,6 +116,7 @@ libfontconfig_la_SOURCES = \ fcmatch.c \ fcmatrix.c \ fcname.c \ + fcpanose.c \ fcpat.c \ fcserialize.c \ fcstr.c \ diff --git a/src/fccfg.c b/src/fccfg.c index fc06220..eb7f927 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -681,6 +681,13 @@ FcConfigPromote (FcValue v, FcValue u) v.u.m = &FcIdentityMatrix; v.type = FcTypeMatrix; } +#if 0 /* XXX no need? */ + else if (v.type == FcTypeVoid && u.type == FcTypePanose) + { + v.u.panose = &FcPanoseAllAny; + v.type = FcTypePanose; + } +#endif else if (v.type == FcTypeString && u.type == FcTypeLangSet) { v.u.l = FcLangSetPromote (v.u.s); @@ -781,6 +788,21 @@ FcConfigCompareValue (const FcValue *left_o, break; } break; + case FcTypePanose: + switch (op) { + case FcOpEqual: + case FcOpContains: /* XXX: equal is not enough */ + case FcOpListing: + ret = FcPanoseEqual (left.u.panose, right.u.panose); + break; + case FcOpNotEqual: + case FcOpNotContains: /* XXX: equal is not enough */ + ret = !FcPanoseEqual (left.u.panose, right.u.panose); + break; + default: + break; + } + break; case FcTypeCharSet: switch (op) { case FcOpContains: @@ -892,6 +914,13 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) v.u.m = e->u.mval; v = FcValueSave (v); break; +#if 0 /* XXX: evaluation for Panose is not implemented */ + case FcOpPanose: + v.type = FcTypePanose; + v.u.panose = e->u.panoseval; + v = FcValueSave (v); + break; +#endif case FcOpCharSet: v.type = FcTypeCharSet; v.u.c = e->u.cval; @@ -1036,6 +1065,11 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) break; } break; +#if 0 /* XXX: calculation for Panose is not implemented */ + case FcTypePanose: + v.type = FcTypePanose; + break; +#endif default: v.type = FcTypeVoid; break; diff --git a/src/fcdbg.c b/src/fcdbg.c index bdb8fa2..30fbbfb 100644 --- a/src/fcdbg.c +++ b/src/fcdbg.c @@ -48,6 +48,19 @@ FcValuePrint (const FcValue v) case FcTypeMatrix: printf (" (%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); break; + case FcTypePanose: + printf (" (%x %x %x %x %x %x %x %x %x %x)", + v.u.panose->b[0], + v.u.panose->b[1], + v.u.panose->b[2], + v.u.panose->b[3], + v.u.panose->b[4], + v.u.panose->b[5], + v.u.panose->b[6], + v.u.panose->b[7], + v.u.panose->b[8], + v.u.panose->b[9]); + break; case FcTypeCharSet: /* XXX */ printf (" "); FcCharSetPrint (v.u.c); diff --git a/src/fcfreetype.c b/src/fcfreetype.c index 0eb7710..f6fad5c 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -1500,6 +1500,13 @@ FcFreeTypeQueryFace (const FT_Face face, } free (complex_); } + if (os2) + { + if (!FcPatternAddInteger (pat, FC_OS2_FAMILYCLASS, os2->sFamilyClass)) + goto bail1; + if (!FcPatternAddPanose (pat, FC_OS2_PANOSE, (FcPanose *)(os2->panose))) + goto bail1; + } /* * Type 1: Check for FontInfo dictionary information diff --git a/src/fcint.h b/src/fcint.h index 46b6ddd..1041b2c 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -104,8 +104,9 @@ #define FC_MEM_ATTR 27 #define FC_MEM_PSTACK 28 #define FC_MEM_STATICSTR 29 +#define FC_MEM_PANOSE 30 -#define FC_MEM_NUM 30 +#define FC_MEM_NUM 31 #define FC_MIN(a,b) ((a) < (b) ? (a) : (b)) #define FC_MAX(a,b) ((a) > (b) ? (a) : (b)) @@ -171,6 +172,7 @@ typedef enum _FcValueBinding { #define FcValueString(v) FcPointerMember(v,u.s,FcChar8) #define FcValueCharSet(v) FcPointerMember(v,u.c,const FcCharSet) #define FcValueLangSet(v) FcPointerMember(v,u.l,const FcLangSet) +#define FcValuePanose(v) FcPointerMember(v,u.panose,const FcPanose) typedef struct _FcValueList *FcValueListPtr; @@ -911,6 +913,9 @@ FcPrivate FcBool FcPatternObjectAddMatrix (FcPattern *p, FcObject object, const FcMatrix *s); FcPrivate FcBool +FcPatternObjectAddPanose (FcPattern *p, FcObject object, const FcPanose *panose); + +FcPrivate FcBool FcPatternObjectAddCharSet (FcPattern *p, FcObject object, const FcCharSet *c); FcPrivate FcBool @@ -935,6 +940,9 @@ FcPrivate FcResult FcPatternObjectGetCharSet (const FcPattern *p, FcObject object, int n, FcCharSet **c); FcPrivate FcResult +FcPatternObjectGetPanose (const FcPattern *p, FcObject object, int n, FcPanose **panose); + +FcPrivate FcResult FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b); FcPrivate FcResult @@ -973,6 +981,22 @@ extern FcPrivate const FcMatrix FcIdentityMatrix; FcPrivate void FcMatrixFree (FcMatrix *mat); +/* fcpanose.c */ + +extern FcPrivate const FcPanose FcPanoseAllAny; + +void +FcPanoseFree (FcPanose *panose); + +FcChar32 +FcPanoseHash (const FcPanose *panose); + +FcBool +FcPanoseSerializeAlloc (FcSerialize *serialize, const FcPanose *panose); + +FcPanose * +FcPanoseSerialize (FcSerialize *serialize, const FcPanose *panose); + /* fcstr.c */ FcPrivate void FcStrSetSort (FcStrSet * set); diff --git a/src/fclist.c b/src/fclist.c index 040d0d9..c4052a0 100644 --- a/src/fclist.c +++ b/src/fclist.c @@ -251,6 +251,8 @@ FcListValueHash (FcValue *value) return (FcChar32) v.u.b; case FcTypeMatrix: return FcListMatrixHash (v.u.m); + case FcTypePanose: + return FcPanoseHash (v.u.panose); case FcTypeCharSet: return FcCharSetCount (v.u.c); case FcTypeFTFace: diff --git a/src/fcname.c b/src/fcname.c index 5b0a932..1c633c8 100644 --- a/src/fcname.c +++ b/src/fcname.c @@ -76,6 +76,8 @@ static const FcObjectType _FcBaseObjectTypes[] = { { FC_EMBEDDED_BITMAP, FcTypeBool }, { FC_DECORATIVE, FcTypeBool }, { FC_LCD_FILTER, FcTypeInteger }, /* 41 */ + { FC_OS2_FAMILYCLASS, FcTypeInteger }, /* 42 */ + { FC_OS2_PANOSE, FcTypePanose }, /* 43 */ }; #define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0]) @@ -808,6 +810,22 @@ FcNameUnparseValue (FcStrBuf *buf, sprintf ((char *) temp, "%g %g %g %g", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); return FcNameUnparseString (buf, temp, 0); + case FcTypePanose: + if (v.u.panose) + sprintf ((char *) temp, "%x %x %x %x %x %x %x %x %x %x", + v.u.panose->b[0], + v.u.panose->b[1], + v.u.panose->b[2], + v.u.panose->b[3], + v.u.panose->b[4], + v.u.panose->b[5], + v.u.panose->b[6], + v.u.panose->b[7], + v.u.panose->b[8], + v.u.panose->b[9]); + else + sprintf ((char *) temp, "(NULL)"); + return FcNameUnparseString (buf, temp, 0); case FcTypeCharSet: return FcNameUnparseCharSet (buf, v.u.c); case FcTypeLangSet: diff --git a/src/fcpanose.c b/src/fcpanose.c new file mode 100644 index 0000000..55ce98f --- /dev/null +++ b/src/fcpanose.c @@ -0,0 +1,106 @@ +/* + * fontconfig/src/fcpanose.c + * + * Copyright © 2010 suzuki toshiya + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of suzuki toshiya not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. suzuki toshiya makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SUZUKI TOSHIYA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUZUKI TOSHIYA BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "fcint.h" +#include +#include +#include + +#include +#include FT_FREETYPE_H +#include FT_TRUETYPE_TABLES_H + +const FcPanose FcPanoseAllAny = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +FcPanose * +FcPanoseCopy (const FcPanose *panose_src) +{ + FcPanose *panose_cpy; + panose_cpy = (FcPanose *) malloc (sizeof (FcPanose) ); + if (!panose_cpy) + return NULL; + FcMemAlloc (FC_MEM_PANOSE, sizeof (FcPanose)); + *panose_cpy = *panose_src; + return panose_cpy; +} + +void +FcPanoseFree (FcPanose *panose) +{ + if (!panose) + return; + + if (&FcPanoseAllAny == panose) + return; + + FcMemFree (FC_MEM_PANOSE, sizeof (FcPanose)); + free (panose); +} + +FcChar32 +FcPanoseHash (const FcPanose *panose) +{ + FcChar32 ret = 0; + int i; + + for ( i = 9; i >= 0; i-- ) + ret = (ret << 3) ^ (ret >> 5) ^ panose->b[i]; + + return ret; +} + +FcBool +FcPanoseEqual (const FcPanose *panose1, const FcPanose *panose2) +{ + int i; + + if(panose1 == panose2) return FcTrue; + if(panose1 == 0 || panose2 == 0) return FcFalse; + for (i = 0; i < 10; i++) + if ( panose1->b[i] != panose2->b[i] ) + return FcFalse; + return FcTrue; +} + +FcBool +FcPanoseSerializeAlloc (FcSerialize *serialize, const FcPanose *panose) +{ + return FcSerializeAlloc (serialize, panose, sizeof (FcPanose)); +} + +FcPanose * +FcPanoseSerialize (FcSerialize *serialize, const FcPanose *panose) +{ + int i; + FcPanose *p_serialized = FcSerializePtr (serialize, panose); + + if (!p_serialized) + return NULL; + for ( i = 0; i < 10; i++ ) + p_serialized->b[i] = panose->b[i]; + return p_serialized; +} +#define __fcpanose__ +#include "fcaliastail.h" +#undef __fcpanose__ diff --git a/src/fcpat.c b/src/fcpat.c index 06b2f4a..82b8e44 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -56,6 +56,9 @@ FcValueDestroy (FcValue v) case FcTypeMatrix: FcMatrixFree ((FcMatrix *) v.u.m); break; + case FcTypePanose: + FcPanoseFree ((FcPanose *) v.u.panose); + break; case FcTypeCharSet: FcCharSetDestroy ((FcCharSet *) v.u.c); break; @@ -86,6 +89,10 @@ FcValueCanonicalize (const FcValue *v) new.u.l = FcValueLangSet(v); new.type = FcTypeLangSet; break; + case FcTypePanose: + new.u.panose = FcValuePanose(v); + new.type = FcTypePanose; + break; default: new = *v; break; @@ -107,6 +114,11 @@ FcValueSave (FcValue v) if (!v.u.m) v.type = FcTypeVoid; break; + case FcTypePanose: + v.u.panose = FcPanoseCopy (v.u.panose); + if (!v.u.panose) + v.type = FcTypeVoid; + break; case FcTypeCharSet: v.u.c = FcCharSetCopy ((FcCharSet *) v.u.c); if (!v.u.c) @@ -137,6 +149,9 @@ FcValueListDestroy (FcValueListPtr l) case FcTypeMatrix: FcMatrixFree ((FcMatrix *)l->value.u.m); break; + case FcTypePanose: + FcPanoseFree ((FcPanose *)l->value.u.panose); + break; case FcTypeCharSet: FcCharSetDestroy ((FcCharSet *) (l->value.u.c)); @@ -185,6 +200,8 @@ FcValueEqual (FcValue va, FcValue vb) return va.u.b == vb.u.b; case FcTypeMatrix: return FcMatrixEqual (va.u.m, vb.u.m); + case FcTypePanose: + return FcPanoseEqual (va.u.panose, vb.u.panose); case FcTypeCharSet: return FcCharSetEqual (va.u.c, vb.u.c); case FcTypeFTFace: @@ -236,6 +253,8 @@ FcValueHash (const FcValue *v) FcDoubleHash (v->u.m->xy) ^ FcDoubleHash (v->u.m->yx) ^ FcDoubleHash (v->u.m->yy)); + case FcTypePanose: + return FcPanoseHash (v->u.panose); case FcTypeCharSet: return (FcChar32) FcValueCharSet(v)->num; case FcTypeFTFace: @@ -672,6 +691,15 @@ FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s) return FcPatternAdd (p, object, v, FcTrue); } +FcBool +FcPatternAddPanose (FcPattern *p, const char *object, const FcPanose *panose) +{ + FcValue v; + + v.type = FcTypePanose; + v.u.panose = panose; + return FcPatternAdd (p, object, v, FcTrue); +} FcBool FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b) @@ -840,6 +868,20 @@ FcPatternGetMatrix(const FcPattern *p, const char *object, int id, FcMatrix **m) return FcResultMatch; } +FcResult +FcPatternGetPanose(const FcPattern *p, const char *object, int id, FcPanose **panose) +{ + FcValue v; + FcResult r; + + r = FcPatternGet (p, object, id, &v); + if (r != FcResultMatch) + return r; + if (v.type != FcTypePanose) + return FcResultTypeMismatch; + *panose = (FcPanose *)v.u.panose; + return FcResultMatch; +} FcResult FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b) @@ -1168,6 +1210,10 @@ FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *vl) if (!FcStrSerializeAlloc (serialize, vl->value.u.s)) return FcFalse; break; + case FcTypePanose: + if (!FcPanoseSerializeAlloc (serialize, vl->value.u.panose)) + return FcFalse; + break; case FcTypeCharSet: if (!FcCharSetSerializeAlloc (serialize, vl->value.u.c)) return FcFalse; @@ -1190,6 +1236,7 @@ FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl) FcValueList *vl_serialized; FcChar8 *s_serialized; FcCharSet *c_serialized; + FcPanose *panose_serialized; FcLangSet *l_serialized; FcValueList *head_serialized = NULL; FcValueList *prev_serialized = NULL; @@ -1230,6 +1277,14 @@ FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl) case FcTypeMatrix: /* can't happen */ break; + case FcTypePanose: + panose_serialized = FcPanoseSerialize (serialize, vl->value.u.panose); + if (!panose_serialized) + return NULL; + vl_serialized->value.u.panose = FcPtrToEncodedOffset (&vl_serialized->value, + panose_serialized, + FcPanose); + break; case FcTypeCharSet: c_serialized = FcCharSetSerialize (serialize, vl->value.u.c); if (!c_serialized)