Commit 3cd573fc authored by Akira TAGOH's avatar Akira TAGOH

Bug 71287 - size specific design selection support in OS/2 table version 5

This feature requires the FreeType 2.5.1 or later at the build time.

Besides <range> element allows <double> elements with this changes.

This may breaks the cache but not bumping in this change sets at this moment.
please be aware if you want to try it and run fc-cache before/after to
avoid the weird thing against it.
parent 9260b7ec
......@@ -321,6 +321,10 @@ AC_CHECK_MEMBER(FT_Bitmap_Size.y_ppem,
#include FT_FREETYPE_H])
AC_DEFINE_UNQUOTED(HAVE_FT_BITMAP_SIZE_Y_PPEM,$HAVE_FT_BITMAP_SIZE_Y_PPEM,
[FT_Bitmap_Size structure includes y_ppem field])
AC_CHECK_MEMBERS([TT_OS2.usLowerOpticalPointSize, TT_OS2.usUpperOpticalPointSize], [], [], [[
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TRUETYPE_TABLES_H]])
CFLAGS="$fontconfig_save_cflags"
LIBS="$fontconfig_save_libs"
......
......@@ -77,6 +77,9 @@
case FcTypeLangSet: \
__v__.u.l = va_arg (va, const FcLangSet *); \
break; \
case FcTypeRange: \
__v__.u.r = va_arg (va, const FcRange *); \
break; \
} \
if (!FcPatternAdd (__p__, __o__, __v__, FcTrue)) \
goto _FcPatternVapBuild_bail1; \
......
......@@ -75,7 +75,7 @@ typedef int FcBool;
#define FC_STYLE "style" /* String */
#define FC_SLANT "slant" /* Int */
#define FC_WEIGHT "weight" /* Int */
#define FC_SIZE "size" /* Double */
#define FC_SIZE "size" /* Range (double) */
#define FC_ASPECT "aspect" /* Double */
#define FC_PIXEL_SIZE "pixelsize" /* Double */
#define FC_SPACING "spacing" /* Int */
......@@ -194,7 +194,8 @@ typedef enum _FcType {
FcTypeMatrix,
FcTypeCharSet,
FcTypeFTFace,
FcTypeLangSet
FcTypeLangSet,
FcTypeRange
} FcType;
typedef struct _FcMatrix {
......@@ -231,6 +232,8 @@ typedef struct _FcPattern FcPattern;
typedef struct _FcLangSet FcLangSet;
typedef struct _FcRange FcRange;
typedef struct _FcValue {
FcType type;
union {
......@@ -242,6 +245,7 @@ typedef struct _FcValue {
const FcCharSet *c;
void *f;
const FcLangSet *l;
const FcRange *r;
} u;
} FcValue;
......@@ -853,6 +857,9 @@ FcPatternAddBool (FcPattern *p, const char *object, FcBool b);
FcPublic FcBool
FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls);
FcPublic FcBool
FcPatternAddRange (FcPattern *p, const char *object, const FcRange *r);
FcPublic FcResult
FcPatternGetInteger (const FcPattern *p, const char *object, int n, int *i);
......@@ -874,6 +881,9 @@ FcPatternGetBool (const FcPattern *p, const char *object, int n, FcBool *b);
FcPublic FcResult
FcPatternGetLangSet (const FcPattern *p, const char *object, int n, FcLangSet **ls);
FcPublic FcResult
FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r);
FcPublic FcPattern *
FcPatternVaBuild (FcPattern *p, va_list va);
......@@ -883,6 +893,20 @@ FcPatternBuild (FcPattern *p, ...) FC_ATTRIBUTE_SENTINEL(0);
FcPublic FcChar8 *
FcPatternFormat (FcPattern *pat, const FcChar8 *format);
/* fcrange.c */
FcPublic FcRange *
FcRangeCreateDouble (double begin, double end);
FcPublic FcRange *
FcRangeCreateInteger (FcChar32 begin, FcChar32 end);
FcPublic void
FcRangeDestroy (FcRange *range);
FcPublic FcRange *
FcRangeCopy (const FcRange *r);
/* fcstr.c */
FcPublic FcChar8 *
......
......@@ -151,6 +151,7 @@ libfontconfig_la_SOURCES = \
fcobjs.h \
fcobjshash.h \
fcpat.c \
fcrange.c \
fcserialize.c \
fcstat.c \
fcstr.c \
......
......@@ -722,6 +722,11 @@ FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf)
v.u.l = FcLangSetPromote (v.u.s, buf);
v.type = FcTypeLangSet;
}
if (buf && v.type == FcTypeDouble && u.type == FcTypeRange)
{
v.u.r = FcRangePromote (v.u.d, buf);
v.type = FcTypeRange;
}
return v;
}
......@@ -894,6 +899,9 @@ FcConfigCompareValue (const FcValue *left_o,
break;
}
break;
case FcTypeRange:
ret = FcRangeCompare (op, left.u.r, right.u.r);
break;
}
}
else
......@@ -915,10 +923,11 @@ FcConfigCompareValue (const FcValue *left_o,
static FcValue
FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
{
FcValue v, vl, vr;
FcValue v, vl, vr, vle, vre;
FcMatrix *m;
FcChar8 *str;
FcOp op = FC_OP_GET_OP (e->op);
FcValuePromotionBuffer buf1, buf2;
switch ((int) op) {
case FcOpInteger:
......@@ -967,6 +976,11 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
v.u.l = e->u.lval;
v = FcValueSave (v);
break;
case FcOpRange:
v.type = FcTypeRange;
v.u.r = e->u.rval;
v = FcValueSave (v);
break;
case FcOpBool:
v.type = FcTypeBool;
v.u.b = e->u.bval;
......@@ -1033,28 +1047,28 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
case FcOpDivide:
vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
vr = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right);
vl = FcConfigPromote (vl, vr, NULL);
vr = FcConfigPromote (vr, vl, NULL);
if (vl.type == vr.type)
vle = FcConfigPromote (vl, vr, &buf1);
vre = FcConfigPromote (vr, vle, &buf2);
if (vle.type == vre.type)
{
switch ((int) vl.type) {
switch ((int) vle.type) {
case FcTypeDouble:
switch ((int) op) {
case FcOpPlus:
v.type = FcTypeDouble;
v.u.d = vl.u.d + vr.u.d;
v.u.d = vle.u.d + vre.u.d;
break;
case FcOpMinus:
v.type = FcTypeDouble;
v.u.d = vl.u.d - vr.u.d;
v.u.d = vle.u.d - vre.u.d;
break;
case FcOpTimes:
v.type = FcTypeDouble;
v.u.d = vl.u.d * vr.u.d;
v.u.d = vle.u.d * vre.u.d;
break;
case FcOpDivide:
v.type = FcTypeDouble;
v.u.d = vl.u.d / vr.u.d;
v.u.d = vle.u.d / vre.u.d;
break;
default:
v.type = FcTypeVoid;
......@@ -1071,11 +1085,11 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
switch ((int) op) {
case FcOpOr:
v.type = FcTypeBool;
v.u.b = vl.u.b || vr.u.b;
v.u.b = vle.u.b || vre.u.b;
break;
case FcOpAnd:
v.type = FcTypeBool;
v.u.b = vl.u.b && vr.u.b;
v.u.b = vle.u.b && vre.u.b;
break;
default:
v.type = FcTypeVoid;
......@@ -1086,7 +1100,7 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
switch ((int) op) {
case FcOpPlus:
v.type = FcTypeString;
str = FcStrPlus (vl.u.s, vr.u.s);
str = FcStrPlus (vle.u.s, vre.u.s);
v.u.s = FcStrdup (str);
FcStrFree (str);
......@@ -1105,7 +1119,7 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
m = malloc (sizeof (FcMatrix));
if (m)
{
FcMatrixMultiply (m, vl.u.m, vr.u.m);
FcMatrixMultiply (m, vle.u.m, vre.u.m);
v.u.m = m;
}
else
......@@ -1122,13 +1136,13 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
switch ((int) op) {
case FcOpPlus:
v.type = FcTypeCharSet;
v.u.c = FcCharSetUnion (vl.u.c, vr.u.c);
v.u.c = FcCharSetUnion (vle.u.c, vre.u.c);
if (!v.u.c)
v.type = FcTypeVoid;
break;
case FcOpMinus:
v.type = FcTypeCharSet;
v.u.c = FcCharSetSubtract (vl.u.c, vr.u.c);
v.u.c = FcCharSetSubtract (vle.u.c, vre.u.c);
if (!v.u.c)
v.type = FcTypeVoid;
break;
......@@ -1141,13 +1155,13 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
switch ((int) op) {
case FcOpPlus:
v.type = FcTypeLangSet;
v.u.l = FcLangSetUnion (vl.u.l, vr.u.l);
v.u.l = FcLangSetUnion (vle.u.l, vre.u.l);
if (!v.u.l)
v.type = FcTypeVoid;
break;
case FcOpMinus:
v.type = FcTypeLangSet;
v.u.l = FcLangSetSubtract (vl.u.l, vr.u.l);
v.u.l = FcLangSetSubtract (vle.u.l, vre.u.l);
if (!v.u.l)
v.type = FcTypeVoid;
break;
......
......@@ -29,6 +29,8 @@
static void
_FcValuePrintFile (FILE *f, const FcValue v)
{
FcRange r;
switch (v.type) {
case FcTypeUnknown:
fprintf (f, "<unknown>");
......@@ -61,6 +63,10 @@ _FcValuePrintFile (FILE *f, const FcValue v)
case FcTypeFTFace:
fprintf (f, "face");
break;
case FcTypeRange:
r = FcRangeCanonicalize (v.u.r);
fprintf (f, "(%g, %g)", r.u.d.begin, r.u.d.end);
break;
}
}
......@@ -261,6 +267,8 @@ FcOpPrint (FcOp op_)
void
FcExprPrint (const FcExpr *expr)
{
FcRange r;
if (!expr) printf ("none");
else switch (FC_OP_GET_OP (expr->op)) {
case FcOpInteger: printf ("%d", expr->u.ival); break;
......@@ -277,7 +285,10 @@ FcExprPrint (const FcExpr *expr)
FcExprPrint (expr->u.mexpr->yy);
printf ("]");
break;
case FcOpRange: break;
case FcOpRange:
r = FcRangeCanonicalize (expr->u.rval);
printf ("(%g, %g)", r.u.d.begin, r.u.d.end);
break;
case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
case FcOpCharSet: printf ("charset\n"); break;
case FcOpLangSet:
......
......@@ -219,6 +219,7 @@ FcDefaultSubstitute (FcPattern *pattern)
{
FcValue v, namelang, v2;
int i;
double dpi, size, scale, pixelsize;
if (FcPatternObjectGet (pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch )
FcPatternObjectAddInteger (pattern, FC_WEIGHT_OBJECT, FC_WEIGHT_NORMAL);
......@@ -233,32 +234,30 @@ FcDefaultSubstitute (FcPattern *pattern)
if (FcPatternObjectGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch)
FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value);
if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) == FcResultNoMatch)
{
double dpi, size, scale;
if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch)
size = 12.0L;
if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch)
scale = 1.0;
if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch)
dpi = 75.0;
if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch)
{
size = 12.0;
(void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT);
FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size);
}
if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch)
{
scale = 1.0;
(void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT);
FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale);
}
size *= scale;
if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch)
{
dpi = 75.0;
(void) FcPatternObjectDel (pattern, FC_DPI_OBJECT);
FcPatternObjectAddDouble (pattern, FC_DPI_OBJECT, dpi);
}
size *= dpi / 72.0;
FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, size);
if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) != FcResultMatch)
{
(void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT);
FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale);
pixelsize = size * scale;
(void) FcPatternObjectDel (pattern, FC_DPI_OBJECT);
FcPatternObjectAddDouble (pattern, FC_DPI_OBJECT, dpi);
pixelsize *= dpi / 72.0;
FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, pixelsize);
}
else
{
size = v.u.d;
size = size / dpi * 72.0 / scale;
}
(void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT);
FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size);
if (FcPatternObjectGet (pattern, FC_FONTVERSION_OBJECT, 0, &v) == FcResultNoMatch)
{
......
......@@ -1107,6 +1107,11 @@ FcFreeTypeQueryFace (const FT_Face face,
FcChar8 *hashstr = NULL;
FT_Error err;
FT_ULong len = 0, alen;
FcRange *r = NULL;
#if defined (HAVE_TT_OS2_USUPPEROPTICALPOINTSIZE) && defined (HAVE_TT_OS2_USLOWEROPTICALPOINTSIZE)
double lower_size = 0.0L, upper_size = DBL_MAX;
#endif
pat = FcPatternCreate ();
if (!pat)
......@@ -1514,6 +1519,39 @@ FcFreeTypeQueryFace (const FT_Face face,
free (complex_);
}
#if defined (HAVE_TT_OS2_USUPPEROPTICALPOINTSIZE) && defined (HAVE_TT_OS2_USLOWEROPTICALPOINTSIZE)
if (os2 && os2->version >= 0x0005 && os2->version != 0xffff)
{
/* usLowerPointSize and usUpperPointSize is actually twips */
lower_size = os2->usLowerOpticalPointSize / 20.0L;
upper_size = os2->usUpperOpticalPointSize / 20.0L;
}
#endif
if (os2)
{
r = FcRangeCreateDouble (lower_size, upper_size);
if (!FcPatternAddRange (pat, FC_SIZE, r))
{
FcRangeDestroy (r);
goto bail1;
}
FcRangeDestroy (r);
}
else
{
for (i = 0; i < face->num_fixed_sizes; i++)
{
double d = FcGetPixelSize (face, i);
r = FcRangeCreateDouble (d, d);
if (!FcPatternAddRange (pat, FC_SIZE, r))
{
FcRangeDestroy (r);
goto bail1;
}
FcRangeDestroy (r);
}
}
/*
* Type 1: Check for FontInfo dictionary information
* Code from g2@magestudios.net (Gerard Escalante)
......
......@@ -38,6 +38,8 @@
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <float.h>
#include <math.h>
#include <unistd.h>
#include <stddef.h>
#include <sys/types.h>
......@@ -94,6 +96,11 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA;
#define FC_MAX(a,b) ((a) > (b) ? (a) : (b))
#define FC_ABS(a) ((a) < 0 ? -(a) : (a))
#define FcDoubleIsZero(a) (fabs ((a)) <= DBL_EPSILON)
#define FcDoubleCmpEQ(a,b) (fabs ((a) - (b)) <= DBL_EPSILON)
#define FcDoubleCmpGE(a,b) (FcDoubleCmpEQ (a, b) || (a) > (b))
#define FcDoubleCmpLE(a,b) (FcDoubleCmpEQ (a, b) || (a) < (b))
/* slim_internal.h */
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
#define FcPrivate __attribute__((__visibility__("hidden")))
......@@ -161,6 +168,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 FcValueRange(v) FcPointerMember(v,u.r,const FcRange)
typedef struct _FcValueList *FcValueListPtr;
......@@ -244,20 +252,38 @@ typedef struct _FcExprName {
FcMatchKind kind;
} FcExprName;
typedef struct _FcRangeInt {
FcChar32 begin;
FcChar32 end;
} FcRangeInt;
typedef struct _FcRangeDouble {
double begin;
double end;
} FcRangeDouble;
struct _FcRange {
FcBool is_double;
FcBool is_inclusive;
union {
FcRangeInt i;
FcRangeDouble d;
} u;
};
typedef struct _FcExpr {
FcOp op;
union {
int ival;
double dval;
const FcChar8 *sval;
FcExprMatrix *mexpr;
FcBool bval;
FcCharSet *cval;
FcLangSet *lval;
FcExprName name;
const FcChar8 *constant;
int ival;
double dval;
const FcChar8 *sval;
FcExprMatrix *mexpr;
FcBool bval;
FcCharSet *cval;
FcLangSet *lval;
FcRange *rval;
FcExprName name;
const FcChar8 *constant;
struct {
struct _FcExpr *left, *right;
} tree;
......@@ -532,13 +558,6 @@ typedef struct _FcFileTime {
typedef struct _FcCharMap FcCharMap;
typedef struct _FcRange FcRange;
struct _FcRange {
FcChar32 begin;
FcChar32 end;
};
typedef struct _FcStatFS FcStatFS;
struct _FcStatFS {
......@@ -1008,6 +1027,9 @@ FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b);
FcPrivate FcBool
FcPatternObjectAddLangSet (FcPattern *p, FcObject object, const FcLangSet *ls);
FcPrivate FcBool
FcPatternObjectAddRange (FcPattern *p, FcObject object, const FcRange *r);
FcPrivate FcResult
FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int n, int *i);
......@@ -1029,6 +1051,9 @@ FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b);
FcPrivate FcResult
FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet **ls);
FcPrivate FcResult
FcPatternObjectGetRange (const FcPattern *p, FcObject object, int id, FcRange **r);
FcPrivate FcBool
FcPatternAppend (FcPattern *p, FcPattern *s);
......@@ -1056,6 +1081,32 @@ extern FcPrivate const FcMatrix FcIdentityMatrix;
FcPrivate void
FcMatrixFree (FcMatrix *mat);
/* fcrange.c */
FcPrivate FcRange
FcRangeCanonicalize (const FcRange *range);
FcPrivate FcRange *
FcRangePromote (double v, FcValuePromotionBuffer *vbuf);
FcPrivate FcBool
FcRangeIsZero (const FcRange *r);
FcPrivate FcBool
FcRangeIsInRange (const FcRange *a, const FcRange *b);
FcPrivate FcBool
FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b);
FcPrivate FcChar32
FcRangeHash (const FcRange *r);
FcPrivate FcBool
FcRangeSerializeAlloc (FcSerialize *serialize, const FcRange *r);
FcPrivate FcRange *
FcRangeSerialize (FcSerialize *serialize, const FcRange *r);
/* fcstat.c */
FcPrivate int
......
......@@ -273,6 +273,8 @@ FcListValueHash (FcValue *value)
return (long) v.u.f;
case FcTypeLangSet:
return FcLangSetHash (v.u.l);
case FcTypeRange:
return FcRangeHash (v.u.r);
}
return 0;
}
......
......@@ -188,6 +188,49 @@ FcCompareSize (FcValue *value1, FcValue *value2)
return v;
}
static double
FcCompareSizeRange (FcValue *v1, FcValue *v2)
{
FcValue value1 = FcValueCanonicalize (v1);
FcValue value2 = FcValueCanonicalize (v2);
FcRange *r1 = NULL, *r2 = NULL;
double ret = -1.0;
switch ((int) value1.type) {
case FcTypeDouble:
r1 = FcRangeCreateDouble (value1.u.d, value1.u.d);
break;
case FcTypeRange:
r1 = FcRangeCopy (value1.u.r);
break;
default:
goto bail;
}
switch ((int) value2.type) {
case FcTypeDouble:
r2 = FcRangeCreateDouble (value2.u.d, value2.u.d);
break;
case FcTypeRange:
r2 = FcRangeCopy (value2.u.r);
break;
default:
goto bail;
}
if (FcRangeIsInRange (r1, r2))
ret = 0.0;
else
ret = FC_MIN (fabs (r1->u.d.end - r2->u.d.begin), fabs (r1->u.d.begin - r2->u.d.end));
bail:
if (r1)
FcRangeDestroy (r1);
if (r2)
FcRangeDestroy (r2);
return ret;
}
static double
FcCompareFilename (FcValue *v1, FcValue *v2)
{
......@@ -227,6 +270,7 @@ FcCompareHash (FcValue *v1, FcValue *v2)
#define PRI_FcCompareLang(n) PRI1(n)
#define PRI_FcComparePostScript(n) PRI1(n)
#define PRI_FcCompareHash(n) PRI1(n)
#define PRI_FcCompareSizeRange(n) PRI1(n)
#define FC_OBJECT(NAME, Type, Cmp) PRI_##Cmp(NAME)
......@@ -255,6 +299,7 @@ typedef enum _FcMatcherPriority {
PRI_FAMILY_WEAK,
PRI_POSTSCRIPT_NAME_WEAK,
PRI1(SPACING),
PRI1(SIZE),
PRI1(PIXEL_SIZE),
PRI1(STYLE),
PRI1(SLANT),
......
......@@ -87,6 +87,10 @@ FcObjectValidType (FcObject object, FcType type)
if (type == FcTypeLangSet || type == FcTypeString)
return FcTrue;
break;
case FcTypeRange:
if (type == FcTypeRange || type == FcTypeDouble)
return FcTrue;
break;
default:
if (type == t->type)
return FcTrue;
......@@ -273,6 +277,8 @@ FcNameConvert (FcType type, FcChar8 *string)
{
FcValue v;
FcMatrix m;
double b, e;
char *p;
v.type = type;
switch ((int) v.type) {
......@@ -307,6 +313,20 @@ FcNameConvert (FcType type, FcChar8 *string)
if (!v.u.l)
v.type = FcTypeVoid;
break;
case FcTypeRange:
if (sscanf ((char *) string, "(%lg %lg)", &b, &e) != 2)
{
v.u.d = strtod ((char *) string, &p);
if (p != NULL && p[0] != 0)
{
v.type = FcTypeVoid;
break;
}
v.type = FcTypeDouble;
}
else
v.u.r = FcRangeCreateDouble (b, e);
break;
default:
break;
}
......@@ -476,6 +496,7 @@ FcNameUnparseValue (FcStrBuf *buf,
{
FcChar8 temp[1024];
FcValue v = FcValueCanonicalize(v0);
FcRange r;
switch (v.type) {
case FcTypeUnknown:
......@@ -501,6 +522,18 @@ FcNameUnparseValue (FcStrBuf *buf,
return FcNameUnparseLangSet (buf, v.u.l);
case FcTypeFTFace:
return FcTrue;
case FcTypeRange:
r = FcRangeCanonicalize (v.u.r);
if (!FcDoubleIsZero (r.u.d.begin) || !FcDoubleIsZero (r.u.d.end))
{
if (FcDoubleCmpEQ (r.u.d.begin, r.u.d.end))
sprintf ((char *) temp, "%g", r.u.d.begin);
else
sprintf ((char *) temp, "(%g %g)", r.u.d.begin, r.u.d.end);
return FcNameUnparseString (buf, temp, 0);
}
else
return FcTrue;
}
return FcFalse;
}
......@@ -533,12 +566,13 @@ FcNameUnparse (FcPattern *pat)
FcChar8 *
FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
{
FcStrBuf buf;
FcChar8 buf_static[8192];
FcStrBuf buf, buf2;
FcChar8 buf_static[8192], buf2_static[256];
int i;
FcPatternElt *e;
FcStrBufInit (&buf, buf_static, sizeof (buf_static));
FcStrBufInit (&buf2, buf2_static, sizeof (buf2_static));
e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT);
if (e)
{
......@@ -548,10 +582,17 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT);
if (e)
{
if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0))
FcChar8 *p;
if (!FcNameUnparseString (&buf2, (FcChar8 *) "-", 0))
goto bail0;
if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
if (!FcNameUnparseValueList (&buf2, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
goto bail0;
p = FcStrBufDoneStatic (&buf2);
FcStrBufDestroy (&buf2);
if (strlen ((const char *)p) > 1)
if (!FcStrBufString (&buf, p))
goto bail0;
}
for (i = 0; i < NUM_OBJECT_TYPES; i++)
{
......
......@@ -31,7 +31,7 @@ FC_OBJECT (FULLNAMELANG, FcTypeString, NULL)
FC_OBJECT (SLANT, FcTypeInteger, FcCompareNumber)
FC_OBJECT (WEIGHT, FcTypeInteger, FcCompareNumber)
FC_OBJECT (WIDTH, FcTypeInteger, FcCompareNumber)
FC_OBJECT (SIZE, FcTypeDouble, NULL)
FC_OBJECT (SIZE, FcTypeRange, FcCompareSizeRange)
FC_OBJECT (ASPECT, FcTypeDouble, NULL)
FC_OBJECT (PIXEL_SIZE, FcTypeDouble, FcCompareSize)
FC_OBJECT (SPACING, FcTypeInteger, FcCompareNumber)
......
......@@ -57,6 +57,9 @@ FcValueDestroy (FcValue v)
case FcTypeLangSet:
FcLangSetDestroy ((FcLangSet *) v.u.l);
break;
case FcTypeRange: