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