buildfont.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. static char*
  5. skip(char *s)
  6. {
  7. while(*s==' ' || *s=='\n' || *s=='\t')
  8. s++;
  9. return s;
  10. }
  11. Font*
  12. buildfont(Display *d, char *buf, char *name)
  13. {
  14. Font *fnt;
  15. Cachefont *c;
  16. char *s, *t;
  17. ulong min, max;
  18. int offset;
  19. char badform[] = "bad font format: number expected (char position %d)";
  20. s = buf;
  21. fnt = malloc(sizeof(Font));
  22. if(fnt == 0)
  23. return 0;
  24. memset(fnt, 0, sizeof(Font));
  25. fnt->display = d;
  26. fnt->name = strdup(name);
  27. fnt->ncache = NFCACHE+NFLOOK;
  28. fnt->nsubf = NFSUBF;
  29. fnt->cache = malloc(fnt->ncache * sizeof(fnt->cache[0]));
  30. fnt->subf = malloc(fnt->nsubf * sizeof(fnt->subf[0]));
  31. if(fnt->name==0 || fnt->cache==0 || fnt->subf==0){
  32. Err2:
  33. free(fnt->name);
  34. free(fnt->cache);
  35. free(fnt->subf);
  36. free(fnt->sub);
  37. free(fnt);
  38. return 0;
  39. }
  40. fnt->height = strtol(s, &s, 0);
  41. s = skip(s);
  42. fnt->ascent = strtol(s, &s, 0);
  43. s = skip(s);
  44. if(fnt->height<=0 || fnt->ascent<=0){
  45. werrstr("bad height or ascent in font file");
  46. goto Err2;
  47. }
  48. fnt->width = 0;
  49. fnt->nsub = 0;
  50. fnt->sub = 0;
  51. memset(fnt->subf, 0, fnt->nsubf * sizeof(fnt->subf[0]));
  52. memset(fnt->cache, 0, fnt->ncache*sizeof(fnt->cache[0]));
  53. fnt->age = 1;
  54. do{
  55. /* must be looking at a number now */
  56. if(*s<'0' || '9'<*s){
  57. werrstr(badform, s-buf);
  58. goto Err3;
  59. }
  60. min = strtol(s, &s, 0);
  61. s = skip(s);
  62. /* must be looking at a number now */
  63. if(*s<'0' || '9'<*s){
  64. werrstr(badform, s-buf);
  65. goto Err3;
  66. }
  67. max = strtol(s, &s, 0);
  68. s = skip(s);
  69. if(*s==0 || min>=65536 || max>=65536 || min>max){
  70. werrstr("illegal subfont range");
  71. Err3:
  72. freefont(fnt);
  73. return 0;
  74. }
  75. t = s;
  76. offset = strtol(s, &t, 0);
  77. if(t>s && (*t==' ' || *t=='\t' || *t=='\n'))
  78. s = skip(t);
  79. else
  80. offset = 0;
  81. fnt->sub = realloc(fnt->sub, (fnt->nsub+1)*sizeof(Cachefont*));
  82. if(fnt->sub == 0){
  83. /* realloc manual says fnt->sub may have been destroyed */
  84. fnt->nsub = 0;
  85. goto Err3;
  86. }
  87. c = malloc(sizeof(Cachefont));
  88. if(c == 0)
  89. goto Err3;
  90. fnt->sub[fnt->nsub] = c;
  91. c->min = min;
  92. c->max = max;
  93. c->offset = offset;
  94. t = s;
  95. while(*s && *s!=' ' && *s!='\n' && *s!='\t')
  96. s++;
  97. *s++ = 0;
  98. c->subfontname = 0;
  99. c->name = strdup(t);
  100. if(c->name == 0){
  101. free(c);
  102. goto Err3;
  103. }
  104. s = skip(s);
  105. fnt->nsub++;
  106. }while(*s);
  107. return fnt;
  108. }
  109. void
  110. freefont(Font *f)
  111. {
  112. int i;
  113. Cachefont *c;
  114. Subfont *s;
  115. if(f == 0)
  116. return;
  117. for(i=0; i<f->nsub; i++){
  118. c = f->sub[i];
  119. free(c->subfontname);
  120. free(c->name);
  121. free(c);
  122. }
  123. for(i=0; i<f->nsubf; i++){
  124. s = f->subf[i].f;
  125. if(s && s!=display->defaultsubfont)
  126. freesubfont(s);
  127. }
  128. freeimage(f->cacheimage);
  129. free(f->name);
  130. free(f->cache);
  131. free(f->subf);
  132. free(f->sub);
  133. free(f);
  134. }