]>
git.wh0rd.org - fontconfig.git/blob - src/fcmatch.c
4 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
31 FcCompareInteger (char *object
, FcValue value1
, FcValue value2
)
35 if (value2
.type
!= FcTypeInteger
|| value1
.type
!= FcTypeInteger
)
37 v
= value2
.u
.i
- value1
.u
.i
;
44 FcCompareString (char *object
, FcValue value1
, FcValue value2
)
46 if (value2
.type
!= FcTypeString
|| value1
.type
!= FcTypeString
)
48 return (double) FcStrCmpIgnoreCase (value1
.u
.s
, value2
.u
.s
) != 0;
52 FcCompareBool (char *object
, FcValue value1
, FcValue value2
)
54 if (value2
.type
!= FcTypeBool
|| value1
.type
!= FcTypeBool
)
56 return (double) value2
.u
.b
!= value1
.u
.b
;
60 FcCompareCharSet (char *object
, FcValue value1
, FcValue value2
)
62 if (value2
.type
!= FcTypeCharSet
|| value1
.type
!= FcTypeCharSet
)
64 return (double) FcCharSetSubtractCount (value1
.u
.c
, value2
.u
.c
);
68 FcCompareSize (char *object
, FcValue value1
, FcValue value2
)
72 switch (value1
.type
) {
82 switch (value2
.type
) {
101 * Order is significant, it defines the precedence of
102 * each value, earlier values are more significant than
105 static FcMatcher _FcMatchers
[] = {
106 { FC_FOUNDRY
, FcCompareString
, },
107 { FC_CHARSET
, FcCompareCharSet
},
108 { FC_ANTIALIAS
, FcCompareBool
, },
109 { FC_LANG
, FcCompareString
},
110 { FC_FAMILY
, FcCompareString
, },
111 { FC_SPACING
, FcCompareInteger
, },
112 { FC_PIXEL_SIZE
, FcCompareSize
, },
113 { FC_STYLE
, FcCompareString
, },
114 { FC_SLANT
, FcCompareInteger
, },
115 { FC_WEIGHT
, FcCompareInteger
, },
116 { FC_RASTERIZER
, FcCompareString
, },
117 { FC_OUTLINE
, FcCompareBool
, },
120 #define NUM_MATCHER (sizeof _FcMatchers / sizeof _FcMatchers[0])
123 FcCompareValueList (const char *object
,
124 FcValueList
*v1orig
, /* pattern */
125 FcValueList
*v2orig
, /* target */
130 FcValueList
*v1
, *v2
;
135 for (i
= 0; i
< NUM_MATCHER
; i
++)
137 if (!FcStrCmpIgnoreCase (_FcMatchers
[i
].object
, object
))
140 if (i
== NUM_MATCHER
)
143 *bestValue
= v2orig
->value
;
149 for (v1
= v1orig
; v1
; v1
= v1
->next
)
151 for (v2
= v2orig
; v2
; v2
= v2
->next
)
153 v
= (*_FcMatchers
[i
].compare
) (_FcMatchers
[i
].object
,
158 *result
= FcResultTypeMismatch
;
161 if (FcDebug () & FC_DBG_MATCHV
)
162 printf (" v %g j %d ", v
, j
);
167 *bestValue
= v2
->value
;
173 if (FcDebug () & FC_DBG_MATCHV
)
175 printf (" %s: %g ", object
, best
);
176 FcValueListPrint (v1orig
);
178 FcValueListPrint (v2orig
);
186 * Return a value indicating the distance between the two lists of
191 FcCompare (FcPattern
*pat
,
198 for (i
= 0; i
< NUM_MATCHER
; i
++)
201 for (i1
= 0; i1
< pat
->num
; i1
++)
203 for (i2
= 0; i2
< fnt
->num
; i2
++)
205 if (!FcStrCmpIgnoreCase (pat
->elts
[i1
].object
,
206 fnt
->elts
[i2
].object
))
208 if (!FcCompareValueList (pat
->elts
[i1
].object
,
209 pat
->elts
[i1
].values
,
210 fnt
->elts
[i2
].values
,
220 * Overspecified patterns are slightly penalized in
221 * case some other font includes the requested field
225 for (i2
= 0; i2
< NUM_MATCHER
; i2
++)
227 if (!FcStrCmpIgnoreCase (_FcMatchers
[i2
].object
,
228 pat
->elts
[i1
].object
))
241 FcFontMatch (FcConfig
*config
,
245 double score
[NUM_MATCHER
], bestscore
[NUM_MATCHER
];
250 FcPatternElt
*fe
, *pe
;
255 for (i
= 0; i
< NUM_MATCHER
; i
++)
258 if (FcDebug () & FC_DBG_MATCH
)
265 config
= FcConfigGetCurrent ();
269 for (set
= FcSetSystem
; set
<= FcSetApplication
; set
++)
271 s
= config
->fonts
[set
];
274 for (f
= 0; f
< s
->nfont
; f
++)
276 if (FcDebug () & FC_DBG_MATCHV
)
278 printf ("Font %d ", f
);
279 FcPatternPrint (s
->fonts
[f
]);
281 if (!FcCompare (p
, s
->fonts
[f
], score
, result
))
283 if (FcDebug () & FC_DBG_MATCHV
)
286 for (i
= 0; i
< NUM_MATCHER
; i
++)
288 printf (" %g", score
[i
]);
292 for (i
= 0; i
< NUM_MATCHER
; i
++)
294 if (best
&& bestscore
[i
] < score
[i
])
296 if (!best
|| score
[i
] < bestscore
[i
])
298 for (i
= 0; i
< NUM_MATCHER
; i
++)
299 bestscore
[i
] = score
[i
];
306 if (FcDebug () & FC_DBG_MATCH
)
308 printf ("Best score");
309 for (i
= 0; i
< NUM_MATCHER
; i
++)
310 printf (" %g", bestscore
[i
]);
311 FcPatternPrint (best
);
315 *result
= FcResultNoMatch
;
318 new = FcPatternCreate ();
321 for (i
= 0; i
< best
->num
; i
++)
324 pe
= FcPatternFind (p
, fe
->object
, FcFalse
);
327 if (!FcCompareValueList (pe
->object
, pe
->values
,
328 fe
->values
, &v
, score
, result
))
330 FcPatternDestroy (new);
335 v
= fe
->values
->value
;
336 FcPatternAdd (new, fe
->object
, v
, FcTrue
);
338 for (i
= 0; i
< p
->num
; i
++)
341 fe
= FcPatternFind (best
, pe
->object
, FcFalse
);
343 FcPatternAdd (new, pe
->object
, pe
->values
->value
, FcTrue
);
345 FcConfigSubstitute (config
, new, FcMatchFont
);