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
29 static 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
73 void
74 FcValuePrintFile (FILE *f, const FcValue v)
75 {
76 fprintf (f, " ");
77 _FcValuePrintFile (f, v);
78 }
79
80 void
81 FcValuePrint (const FcValue v)
82 {
83 printf (" ");
84 _FcValuePrintFile (stdout, v);
85 }
86
87 void
88 FcValuePrintWithPosition (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
97 static void
98 FcValueBindingPrint (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
117 void
118 FcValueListPrintWithPosition (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
129 void
130 FcValueListPrint (FcValueListPtr l)
131 {
132 for (; l != NULL; l = FcValueListNext(l))
133 {
134 FcValuePrint (FcValueCanonicalize (&l->value));
135 FcValueBindingPrint (l);
136 }
137 }
138
139 void
140 FcLangSetPrint (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
153 void
154 FcCharSetPrint (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
187 void
188 FcPatternPrint (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
215 void
216 FcPatternPrint2 (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
293 void
294 FcOpPrint (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
344 void
345 FcExprPrint (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
468 void
469 FcTestPrint (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
506 void
507 FcEditPrint (const FcEdit *edit)
508 {
509 printf ("Edit %s ", FcObjectName (edit->object));
510 FcOpPrint (edit->op);
511 printf (" ");
512 FcExprPrint (edit->expr);
513 }
514
515 void
516 FcRulePrint (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
553 void
554 FcFontSetPrint (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
566 int FcDebugVal;
567
568 void
569 FcInitDebug (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__