fcdbg.c revision a32e9e42
1/*
2 * fontconfig/src/fcdbg.c
3 *
4 * Copyright © 2000 Keith Packard
5 *
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 the author(s) not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission.  The authors make no
13 * representations about the suitability of this software for any purpose.  It
14 * is provided "as is" without express or implied warranty.
15 *
16 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL THE AUTHOR(S) 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.
23 */
24
25#include "fcint.h"
26#include <stdio.h>
27#include <stdlib.h>
28
29static void
30_FcValuePrintFile (FILE *f, const FcValue v)
31{
32    switch (v.type) {
33    case FcTypeUnknown:
34	fprintf (f, "<unknown>");
35	break;
36    case FcTypeVoid:
37	fprintf (f, "<void>");
38	break;
39    case FcTypeInteger:
40	fprintf (f, "%d(i)", v.u.i);
41	break;
42    case FcTypeDouble:
43	fprintf (f, "%g(f)", v.u.d);
44	break;
45    case FcTypeString:
46	fprintf (f, "\"%s\"", v.u.s);
47	break;
48    case FcTypeBool:
49	fprintf (f,
50		 v.u.b == FcTrue  ? "True" :
51		 v.u.b == FcFalse ? "False" :
52				    "DontCare");
53	break;
54    case FcTypeMatrix:
55	fprintf (f, "[%g %g; %g %g]", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
56	break;
57    case FcTypeCharSet:	/* XXX */
58	if (f == stdout)
59	    FcCharSetPrint (v.u.c);
60	break;
61    case FcTypeLangSet:
62	FcLangSetPrint (v.u.l);
63	break;
64    case FcTypeFTFace:
65	fprintf (f, "face");
66	break;
67    case FcTypeRange:
68	fprintf (f, "[%g %g]", v.u.r->begin, v.u.r->end);
69	break;
70    }
71}
72
73void
74FcValuePrintFile (FILE *f, const FcValue v)
75{
76    fprintf (f, " ");
77    _FcValuePrintFile (f, v);
78}
79
80void
81FcValuePrint (const FcValue v)
82{
83    printf (" ");
84    _FcValuePrintFile (stdout, v);
85}
86
87void
88FcValuePrintWithPosition (const FcValue v, FcBool show_pos_mark)
89{
90    if (show_pos_mark)
91	printf (" [marker] ");
92    else
93	printf (" ");
94    _FcValuePrintFile (stdout, v);
95}
96
97static void
98FcValueBindingPrint (const FcValueListPtr l)
99{
100    switch (l->binding) {
101    case FcValueBindingWeak:
102	printf ("(w)");
103	break;
104    case FcValueBindingStrong:
105	printf ("(s)");
106	break;
107    case FcValueBindingSame:
108	printf ("(=)");
109	break;
110    default:
111	/* shouldn't be reached */
112	printf ("(?)");
113	break;
114    }
115}
116
117void
118FcValueListPrintWithPosition (FcValueListPtr l, const FcValueListPtr pos)
119{
120    for (; l != NULL; l = FcValueListNext(l))
121    {
122	FcValuePrintWithPosition (FcValueCanonicalize (&l->value), pos != NULL && l == pos);
123	FcValueBindingPrint (l);
124    }
125    if (!pos)
126	printf (" [marker]");
127}
128
129void
130FcValueListPrint (FcValueListPtr l)
131{
132    for (; l != NULL; l = FcValueListNext(l))
133    {
134	FcValuePrint (FcValueCanonicalize (&l->value));
135	FcValueBindingPrint (l);
136    }
137}
138
139void
140FcLangSetPrint (const FcLangSet *ls)
141{
142    FcStrBuf	buf;
143    FcChar8	init_buf[1024];
144
145    FcStrBufInit (&buf, init_buf, sizeof (init_buf));
146    if (FcNameUnparseLangSet (&buf, ls) && FcStrBufChar (&buf,'\0'))
147       printf ("%s", buf.buf);
148    else
149       printf ("langset (alloc error)");
150    FcStrBufDestroy (&buf);
151}
152
153void
154FcCharSetPrint (const FcCharSet *c)
155{
156    int	i, j;
157    intptr_t	*leaves = FcCharSetLeaves (c);
158    FcChar16	*numbers = FcCharSetNumbers (c);
159
160#if 0
161    printf ("CharSet  0x%x\n", (intptr_t) c);
162    printf ("Leaves:  +%d = 0x%x\n", c->leaves_offset, (intptr_t) leaves);
163    printf ("Numbers: +%d = 0x%x\n", c->numbers_offset, (intptr_t) numbers);
164
165    for (i = 0; i < c->num; i++)
166    {
167	printf ("Page %d: %04x +%d = 0x%x\n",
168		i, numbers[i], leaves[i],
169		(intptr_t) FcOffsetToPtr (leaves, leaves[i], FcCharLeaf));
170    }
171#endif
172
173    printf ("\n");
174    for (i = 0; i < c->num; i++)
175    {
176	intptr_t	leaf_offset = leaves[i];
177	FcCharLeaf	*leaf = FcOffsetToPtr (leaves, leaf_offset, FcCharLeaf);
178
179	printf ("\t");
180	printf ("%04x:", numbers[i]);
181	for (j = 0; j < 256/32; j++)
182	    printf (" %08x", leaf->map[j]);
183	printf ("\n");
184    }
185}
186
187void
188FcPatternPrint (const FcPattern *p)
189{
190    FcPatternIter iter;
191
192    if (!p)
193    {
194	printf ("Null pattern\n");
195	return;
196    }
197    printf ("Pattern has %d elts (size %d)\n", FcPatternObjectCount (p), p->size);
198    FcPatternIterStart (p, &iter);
199    do
200    {
201	printf ("\t%s:", FcPatternIterGetObject (p, &iter));
202	FcValueListPrint (FcPatternIterGetValues (p, &iter));
203	printf ("\n");
204    } while (FcPatternIterNext (p, &iter));
205    printf ("\n");
206}
207
208#define FcOpFlagsPrint(_o_)		\
209    {					\
210	int f = FC_OP_GET_FLAGS (_o_);	\
211	if (f & FcOpFlagIgnoreBlanks)	\
212	    printf ("(ignore blanks)");	\
213    }
214
215void
216FcPatternPrint2 (FcPattern         *pp1,
217		 FcPattern         *pp2,
218		 const FcObjectSet *os)
219{
220    int i, j, k, pos;
221    FcPatternElt *e1, *e2;
222    FcPattern *p1, *p2;
223
224    if (os)
225    {
226	p1 = FcPatternFilter (pp1, os);
227	p2 = FcPatternFilter (pp2, os);
228    }
229    else
230    {
231	p1 = pp1;
232	p2 = pp2;
233    }
234    printf ("Pattern has %d elts (size %d), %d elts (size %d)\n",
235	    p1->num, p1->size, p2->num, p2->size);
236    for (i = 0, j = 0; i < p1->num; i++)
237    {
238	e1 = &FcPatternElts(p1)[i];
239	e2 = &FcPatternElts(p2)[j];
240	if (!e2 || e1->object != e2->object)
241	{
242	    pos = FcPatternPosition (p2, FcObjectName (e1->object));
243	    if (pos >= 0)
244	    {
245		for (k = j; k < pos; k++)
246		{
247		    e2 = &FcPatternElts(p2)[k];
248		    printf ("\t%s: (None) -> ", FcObjectName (e2->object));
249		    FcValueListPrint (FcPatternEltValues (e2));
250		    printf ("\n");
251		}
252		j = pos;
253		goto cont;
254	    }
255	    else
256	    {
257		printf ("\t%s:", FcObjectName (e1->object));
258		FcValueListPrint (FcPatternEltValues (e1));
259		printf (" -> (None)\n");
260	    }
261	}
262	else
263	{
264	cont:
265	    printf ("\t%s:", FcObjectName (e1->object));
266	    FcValueListPrint (FcPatternEltValues (e1));
267	    printf (" -> ");
268	    e2 = &FcPatternElts(p2)[j];
269	    FcValueListPrint (FcPatternEltValues (e2));
270	    printf ("\n");
271	    j++;
272	}
273    }
274    if (j < p2->num)
275    {
276	for (k = j; k < p2->num; k++)
277	{
278	    e2 = &FcPatternElts(p2)[k];
279	    if (FcObjectName (e2->object))
280	    {
281		printf ("\t%s: (None) -> ", FcObjectName (e2->object));
282		FcValueListPrint (FcPatternEltValues (e2));
283		printf ("\n");
284	    }
285	}
286    }
287    if (p1 != pp1)
288	FcPatternDestroy (p1);
289    if (p2 != pp2)
290	FcPatternDestroy (p2);
291}
292
293void
294FcOpPrint (FcOp op_)
295{
296    FcOp op = FC_OP_GET_OP (op_);
297
298    switch (op) {
299    case FcOpInteger: printf ("Integer"); break;
300    case FcOpDouble: printf ("Double"); break;
301    case FcOpString: printf ("String"); break;
302    case FcOpMatrix: printf ("Matrix"); break;
303    case FcOpRange: printf ("Range"); break;
304    case FcOpBool: printf ("Bool"); break;
305    case FcOpCharSet: printf ("CharSet"); break;
306    case FcOpLangSet: printf ("LangSet"); break;
307    case FcOpField: printf ("Field"); break;
308    case FcOpConst: printf ("Const"); break;
309    case FcOpAssign: printf ("Assign"); break;
310    case FcOpAssignReplace: printf ("AssignReplace"); break;
311    case FcOpPrepend: printf ("Prepend"); break;
312    case FcOpPrependFirst: printf ("PrependFirst"); break;
313    case FcOpAppend: printf ("Append"); break;
314    case FcOpAppendLast: printf ("AppendLast"); break;
315    case FcOpDelete: printf ("Delete"); break;
316    case FcOpDeleteAll: printf ("DeleteAll"); break;
317    case FcOpQuest: printf ("Quest"); break;
318    case FcOpOr: printf ("Or"); break;
319    case FcOpAnd: printf ("And"); break;
320    case FcOpEqual: printf ("Equal"); FcOpFlagsPrint (op_); break;
321    case FcOpNotEqual: printf ("NotEqual"); FcOpFlagsPrint (op_); break;
322    case FcOpLess: printf ("Less"); break;
323    case FcOpLessEqual: printf ("LessEqual"); break;
324    case FcOpMore: printf ("More"); break;
325    case FcOpMoreEqual: printf ("MoreEqual"); break;
326    case FcOpContains: printf ("Contains"); break;
327    case FcOpNotContains: printf ("NotContains"); break;
328    case FcOpPlus: printf ("Plus"); break;
329    case FcOpMinus: printf ("Minus"); break;
330    case FcOpTimes: printf ("Times"); break;
331    case FcOpDivide: printf ("Divide"); break;
332    case FcOpNot: printf ("Not"); break;
333    case FcOpNil: printf ("Nil"); break;
334    case FcOpComma: printf ("Comma"); break;
335    case FcOpFloor: printf ("Floor"); break;
336    case FcOpCeil: printf ("Ceil"); break;
337    case FcOpRound: printf ("Round"); break;
338    case FcOpTrunc: printf ("Trunc"); break;
339    case FcOpListing: printf ("Listing"); FcOpFlagsPrint (op_); break;
340    case FcOpInvalid: printf ("Invalid"); break;
341    }
342}
343
344void
345FcExprPrint (const FcExpr *expr)
346{
347    if (!expr) printf ("none");
348    else switch (FC_OP_GET_OP (expr->op)) {
349    case FcOpInteger: printf ("%d", expr->u.ival); break;
350    case FcOpDouble: printf ("%g", expr->u.dval); break;
351    case FcOpString: printf ("\"%s\"", expr->u.sval); break;
352    case FcOpMatrix:
353	printf ("[");
354	FcExprPrint (expr->u.mexpr->xx);
355	printf (" ");
356	FcExprPrint (expr->u.mexpr->xy);
357	printf ("; ");
358	FcExprPrint (expr->u.mexpr->yx);
359	printf (" ");
360	FcExprPrint (expr->u.mexpr->yy);
361	printf ("]");
362	break;
363    case FcOpRange:
364	printf ("(%g, %g)", expr->u.rval->begin, expr->u.rval->end);
365	break;
366    case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
367    case FcOpCharSet: printf ("charset\n"); break;
368    case FcOpLangSet:
369	printf ("langset:");
370	FcLangSetPrint(expr->u.lval);
371	printf ("\n");
372	break;
373    case FcOpNil: printf ("nil\n"); break;
374    case FcOpField: printf ("%s ", FcObjectName(expr->u.name.object));
375      switch ((int) expr->u.name.kind) {
376      case FcMatchPattern:
377	  printf ("(pattern) ");
378	  break;
379      case FcMatchFont:
380	  printf ("(font) ");
381	  break;
382      }
383      break;
384    case FcOpConst: printf ("%s", expr->u.constant); break;
385    case FcOpQuest:
386	FcExprPrint (expr->u.tree.left);
387	printf (" quest ");
388	FcExprPrint (expr->u.tree.right->u.tree.left);
389	printf (" colon ");
390	FcExprPrint (expr->u.tree.right->u.tree.right);
391	break;
392    case FcOpAssign:
393    case FcOpAssignReplace:
394    case FcOpPrependFirst:
395    case FcOpPrepend:
396    case FcOpAppend:
397    case FcOpAppendLast:
398    case FcOpOr:
399    case FcOpAnd:
400    case FcOpEqual:
401    case FcOpNotEqual:
402    case FcOpLess:
403    case FcOpLessEqual:
404    case FcOpMore:
405    case FcOpMoreEqual:
406    case FcOpContains:
407    case FcOpListing:
408    case FcOpNotContains:
409    case FcOpPlus:
410    case FcOpMinus:
411    case FcOpTimes:
412    case FcOpDivide:
413    case FcOpComma:
414	FcExprPrint (expr->u.tree.left);
415	printf (" ");
416	switch (FC_OP_GET_OP (expr->op)) {
417	case FcOpAssign: printf ("Assign"); break;
418	case FcOpAssignReplace: printf ("AssignReplace"); break;
419	case FcOpPrependFirst: printf ("PrependFirst"); break;
420	case FcOpPrepend: printf ("Prepend"); break;
421	case FcOpAppend: printf ("Append"); break;
422	case FcOpAppendLast: printf ("AppendLast"); break;
423	case FcOpOr: printf ("Or"); break;
424	case FcOpAnd: printf ("And"); break;
425	case FcOpEqual: printf ("Equal"); FcOpFlagsPrint (expr->op); break;
426	case FcOpNotEqual: printf ("NotEqual"); FcOpFlagsPrint (expr->op); break;
427	case FcOpLess: printf ("Less"); break;
428	case FcOpLessEqual: printf ("LessEqual"); break;
429	case FcOpMore: printf ("More"); break;
430	case FcOpMoreEqual: printf ("MoreEqual"); break;
431	case FcOpContains: printf ("Contains"); break;
432	case FcOpListing: printf ("Listing"); FcOpFlagsPrint (expr->op); break;
433	case FcOpNotContains: printf ("NotContains"); break;
434	case FcOpPlus: printf ("Plus"); break;
435	case FcOpMinus: printf ("Minus"); break;
436	case FcOpTimes: printf ("Times"); break;
437	case FcOpDivide: printf ("Divide"); break;
438	case FcOpComma: printf ("Comma"); break;
439	default: break;
440	}
441	printf (" ");
442	FcExprPrint (expr->u.tree.right);
443	break;
444    case FcOpNot:
445	printf ("Not ");
446	FcExprPrint (expr->u.tree.left);
447	break;
448    case FcOpFloor:
449	printf ("Floor ");
450	FcExprPrint (expr->u.tree.left);
451	break;
452    case FcOpCeil:
453	printf ("Ceil ");
454	FcExprPrint (expr->u.tree.left);
455	break;
456    case FcOpRound:
457	printf ("Round ");
458	FcExprPrint (expr->u.tree.left);
459	break;
460    case FcOpTrunc:
461	printf ("Trunc ");
462	FcExprPrint (expr->u.tree.left);
463	break;
464    case FcOpInvalid: printf ("Invalid"); break;
465    }
466}
467
468void
469FcTestPrint (const FcTest *test)
470{
471    switch (test->kind) {
472    case FcMatchPattern:
473	printf ("pattern ");
474	break;
475    case FcMatchFont:
476	printf ("font ");
477	break;
478    case FcMatchScan:
479	printf ("scan ");
480	break;
481    case FcMatchKindEnd:
482	/* shouldn't be reached */
483	return;
484    }
485    switch (test->qual) {
486    case FcQualAny:
487	printf ("any ");
488	break;
489    case FcQualAll:
490	printf ("all ");
491	break;
492    case FcQualFirst:
493	printf ("first ");
494	break;
495    case FcQualNotFirst:
496	printf ("not_first ");
497	break;
498    }
499    printf ("%s ", FcObjectName (test->object));
500    FcOpPrint (test->op);
501    printf (" ");
502    FcExprPrint (test->expr);
503    printf ("\n");
504}
505
506void
507FcEditPrint (const FcEdit *edit)
508{
509    printf ("Edit %s ", FcObjectName (edit->object));
510    FcOpPrint (edit->op);
511    printf (" ");
512    FcExprPrint (edit->expr);
513}
514
515void
516FcRulePrint (const FcRule *rule)
517{
518    FcRuleType last_type = FcRuleUnknown;
519    const FcRule *r;
520
521    for (r = rule; r; r = r->next)
522    {
523	if (last_type != r->type)
524	{
525	    switch (r->type) {
526	    case FcRuleTest:
527		printf ("[test]\n");
528		break;
529	    case FcRuleEdit:
530		printf ("[edit]\n");
531		break;
532	    default:
533		break;
534	    }
535	    last_type = r->type;
536	}
537	printf ("\t");
538	switch (r->type) {
539	case FcRuleTest:
540	    FcTestPrint (r->u.test);
541	    break;
542	case FcRuleEdit:
543	    FcEditPrint (r->u.edit);
544	    printf (";\n");
545	    break;
546	default:
547	    break;
548	}
549    }
550    printf ("\n");
551}
552
553void
554FcFontSetPrint (const FcFontSet *s)
555{
556    int	    i;
557
558    printf ("FontSet %d of %d\n", s->nfont, s->sfont);
559    for (i = 0; i < s->nfont; i++)
560    {
561	printf ("Font %d ", i);
562	FcPatternPrint (s->fonts[i]);
563    }
564}
565
566int FcDebugVal;
567
568void
569FcInitDebug (void)
570{
571    if (!FcDebugVal) {
572	char    *e;
573
574	e = getenv ("FC_DEBUG");
575	if (e)
576	{
577	    printf ("FC_DEBUG=%s\n", e);
578	    FcDebugVal = atoi (e);
579	    if (FcDebugVal < 0)
580		FcDebugVal = 0;
581	}
582    }
583}
584#define __fcdbg__
585#include "fcaliastail.h"
586#undef __fcdbg__
587