freetype.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #include <lib9.h>
  2. #include <kernel.h>
  3. #include "interp.h"
  4. #include "isa.h"
  5. #include "runt.h"
  6. #include "raise.h"
  7. #include "freetypemod.h"
  8. #include "freetype.h"
  9. typedef struct Face Face;
  10. struct Face {
  11. Freetype_Face freetypeface; /* limbo part */
  12. FTface ftface; /* private parts */
  13. };
  14. Type* TMatrix;
  15. Type* TVector;
  16. Type* TFace;
  17. Type* TGlyph;
  18. static uchar Matrixmap[] = Freetype_Matrix_map;
  19. static uchar Vectormap[] = Freetype_Vector_map;
  20. static uchar Facemap[] = Freetype_Face_map;
  21. static uchar Glyphmap[] = Freetype_Glyph_map;
  22. static void freeface(Heap*, int);
  23. static Face* ckface(Freetype_Face*);
  24. void
  25. freetypemodinit(void)
  26. {
  27. builtinmod("$Freetype", Freetypemodtab, Freetypemodlen);
  28. TMatrix = dtype(freeheap, sizeof(Freetype_Matrix), Matrixmap, sizeof(Matrixmap));
  29. TVector = dtype(freeheap, sizeof(Freetype_Vector), Vectormap, sizeof(Vectormap));
  30. TFace = dtype(freeface, sizeof(Face), Facemap, sizeof(Facemap));
  31. TGlyph = dtype(freeheap, sizeof(Freetype_Glyph), Glyphmap, sizeof(Glyphmap));
  32. }
  33. void
  34. Face_haschar(void *fp)
  35. {
  36. F_Face_haschar *f = fp;
  37. Face *face;
  38. *f->ret = 0;
  39. face = ckface(f->face);
  40. release();
  41. *f->ret = fthaschar(face->ftface, f->c);
  42. acquire();
  43. }
  44. void
  45. Face_loadglyph(void *fp)
  46. {
  47. F_Face_loadglyph *f = fp;
  48. Heap *h;
  49. Face *face;
  50. Freetype_Glyph *g;
  51. FTglyph ftg;
  52. int n, i, s1bpr, s2bpr;
  53. char *err;
  54. face = ckface(f->face);
  55. destroy(*f->ret);
  56. *f->ret = H;
  57. release();
  58. err = ftloadglyph(face->ftface, f->c, &ftg);
  59. acquire();
  60. if (err != nil) {
  61. kwerrstr(err);
  62. return;
  63. }
  64. h = heap(TGlyph);
  65. if (h == H) {
  66. kwerrstr(exNomem);
  67. return;
  68. }
  69. g = H2D(Freetype_Glyph*, h);
  70. n = ftg.width*ftg.height;
  71. h = heaparray(&Tbyte, n);
  72. if (h == H) {
  73. destroy(g);
  74. kwerrstr(exNomem);
  75. return;
  76. }
  77. g->bitmap = H2D(Array*, h);
  78. g->top = ftg.top;
  79. g->left = ftg.left;
  80. g->height = ftg.height;
  81. g->width = ftg.width;
  82. g->advance.x = ftg.advx;
  83. g->advance.y = ftg.advy;
  84. s1bpr = ftg.width;
  85. s2bpr = ftg.bpr;
  86. for (i = 0; i < ftg.height; i++)
  87. memcpy(g->bitmap->data+(i*s1bpr), ftg.bitmap+(i*s2bpr), s1bpr);
  88. *f->ret = g;
  89. }
  90. void
  91. Freetype_newface(void *fp)
  92. {
  93. F_Freetype_newface *f = fp;
  94. Heap *h;
  95. Face *face;
  96. Freetype_Face *limboface;
  97. FTfaceinfo finfo;
  98. char *path;
  99. char *err;
  100. destroy(*f->ret);
  101. *f->ret = H;
  102. h = heapz(TFace);
  103. if (h == H) {
  104. kwerrstr(exNomem);
  105. return;
  106. }
  107. face = H2D(Face*, h);
  108. limboface = (Freetype_Face*)face;
  109. *f->ret = limboface;
  110. path = strdup(string2c(f->path)); /* string2c() can call error() */
  111. release();
  112. err = ftnewface(path, f->index, &face->ftface, &finfo);
  113. acquire();
  114. free(path);
  115. if (err != nil) {
  116. *f->ret = H;
  117. destroy(face);
  118. kwerrstr(err);
  119. return;
  120. }
  121. limboface->nfaces = finfo.nfaces;
  122. limboface->index = finfo.index;
  123. limboface->style = finfo.style;
  124. limboface->height = finfo.height;
  125. limboface->ascent = finfo.ascent;
  126. limboface->familyname = c2string(finfo.familyname, strlen(finfo.familyname));
  127. limboface->stylename = c2string(finfo.stylename, strlen(finfo.stylename));
  128. *f->ret = limboface;
  129. }
  130. void
  131. Freetype_newmemface(void *fp)
  132. {
  133. F_Freetype_newmemface *f = fp;
  134. destroy(*f->ret);
  135. *f->ret = H;
  136. kwerrstr("not implemented");
  137. }
  138. void
  139. Face_setcharsize(void *fp)
  140. {
  141. F_Face_setcharsize *f = fp;
  142. Face *face;
  143. Freetype_Face *limboface;
  144. FTfaceinfo finfo;
  145. char *err;
  146. face = ckface(f->face);
  147. limboface = (Freetype_Face*)face;
  148. release();
  149. err = ftsetcharsize(face->ftface, f->pts, f->hdpi, f->vdpi, &finfo);
  150. acquire();
  151. if (err == nil) {
  152. limboface->height = finfo.height;
  153. limboface->ascent = finfo.ascent;
  154. }
  155. retstr(err, f->ret);
  156. }
  157. void
  158. Face_settransform(void *fp)
  159. {
  160. F_Face_settransform *f = fp;
  161. FTmatrix *m = nil;
  162. FTvector *v = nil;
  163. Face *face;
  164. face = ckface(f->face);
  165. /*
  166. * ftsettransform() has no error return
  167. * we have one for consistency - but always nil for now
  168. */
  169. destroy(*f->ret);
  170. *f->ret = H;
  171. if (f->m != H)
  172. m = (FTmatrix*)(f->m);
  173. if (f->v != H)
  174. v = (FTvector*)(f->v);
  175. release();
  176. ftsettransform(face->ftface, m, v);
  177. acquire();
  178. }
  179. static void
  180. freeface(Heap *h, int swept)
  181. {
  182. Face *face = H2D(Face*, h);
  183. if (!swept) {
  184. destroy(face->freetypeface.familyname);
  185. destroy(face->freetypeface.stylename);
  186. }
  187. release();
  188. ftdoneface(face->ftface);
  189. acquire();
  190. memset(&face->ftface, 0, sizeof(face->ftface));
  191. }
  192. static Face*
  193. ckface(Freetype_Face *face)
  194. {
  195. if (face == nil || face == H)
  196. error("nil Face");
  197. if (D2H(face)->t != TFace)
  198. error(exType);
  199. return (Face*)face;
  200. }