Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

font.c 6.9 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. * libcucul Canvas for ultrafast compositing of Unicode letters
  3. * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the Do What The Fuck You Want To
  8. * Public License, Version 2, as published by Sam Hocevar. See
  9. * http://sam.zoy.org/wtfpl/COPYING for more details.
  10. */
  11. /** \file font.c
  12. * \version \$Id$
  13. * \author Sam Hocevar <sam@zoy.org>
  14. * \brief Colour handling
  15. *
  16. * This file contains font handling functions.
  17. */
  18. #include "config.h"
  19. #if !defined(__KERNEL__)
  20. # if defined(HAVE_ENDIAN_H)
  21. # include <endian.h>
  22. # endif
  23. # include <stdio.h>
  24. # include <stdlib.h>
  25. # include <string.h>
  26. # include <arpa/inet.h>
  27. #endif
  28. #include "cucul.h"
  29. #include "cucul_internals.h"
  30. /* Internal fonts */
  31. uint8_t const font_monospace9[] =
  32. #include "font_monospace9.h"
  33. ;
  34. struct font_header
  35. {
  36. uint32_t control_size, data_size;
  37. uint16_t version, blocks;
  38. uint32_t glyphs;
  39. uint16_t bpp, width, height, flags;
  40. };
  41. struct block_info
  42. {
  43. uint32_t start, stop, index;
  44. };
  45. struct glyph_info
  46. {
  47. uint16_t width, height;
  48. uint32_t data_offset;
  49. };
  50. struct cucul_font
  51. {
  52. struct font_header header;
  53. struct block_info *block_list;
  54. struct glyph_info *glyph_list;
  55. uint8_t *font_data;
  56. uint8_t *private;
  57. };
  58. struct cucul_font *cucul_load_font(void *data, unsigned int size)
  59. {
  60. struct cucul_font *f;
  61. unsigned int i;
  62. f = malloc(sizeof(struct cucul_font));
  63. f->private = data;
  64. memcpy(&f->header, f->private + 8, sizeof(struct font_header));
  65. f->header.control_size = htonl(f->header.control_size);
  66. f->header.data_size = htonl(f->header.data_size);
  67. f->header.version = htons(f->header.version);
  68. f->header.blocks = htons(f->header.blocks);
  69. f->header.glyphs = htonl(f->header.glyphs);
  70. f->header.bpp = htons(f->header.bpp);
  71. f->header.width = htons(f->header.width);
  72. f->header.height = htons(f->header.height);
  73. f->header.flags = htons(f->header.flags);
  74. f->block_list = malloc(f->header.blocks * sizeof(struct block_info));
  75. memcpy(f->block_list,
  76. f->private + 8 + sizeof(struct font_header),
  77. f->header.blocks * sizeof(struct block_info));
  78. for(i = 0; i < f->header.blocks; i++)
  79. {
  80. f->block_list[i].start = htonl(f->block_list[i].start);
  81. f->block_list[i].stop = htonl(f->block_list[i].stop);
  82. f->block_list[i].index = htonl(f->block_list[i].index);
  83. }
  84. f->glyph_list = malloc(f->header.glyphs * sizeof(struct glyph_info));
  85. memcpy(f->glyph_list,
  86. f->private + 8 + sizeof(struct font_header)
  87. + f->header.blocks * sizeof(struct block_info),
  88. f->header.glyphs * sizeof(struct glyph_info));
  89. for(i = 0; i < f->header.glyphs; i++)
  90. {
  91. f->glyph_list[i].width = htons(f->glyph_list[i].width);
  92. f->glyph_list[i].height = htons(f->glyph_list[i].height);
  93. f->glyph_list[i].data_offset = htonl(f->glyph_list[i].data_offset);
  94. }
  95. f->font_data = f->private + 8 + f->header.control_size;
  96. return f;
  97. }
  98. void cucul_free_font(struct cucul_font *f)
  99. {
  100. free(f->glyph_list);
  101. free(f->block_list);
  102. free(f);
  103. }
  104. void cucul_render_canvas(cucul_t *qq, struct cucul_font *f)
  105. {
  106. uint8_t *buf = malloc(qq->width * f->header.width * qq->height * f->header.height);
  107. unsigned int x, y, i, j;
  108. for(y = 0; y < qq->height; y++)
  109. {
  110. for(x = 0; x < qq->width; x++)
  111. {
  112. unsigned int starty = y * f->header.height;
  113. unsigned int startx = x * f->header.width;
  114. uint32_t ch = qq->chars[y * qq->width + x];
  115. unsigned int b;
  116. struct glyph_info *g;
  117. /* Find the Unicode block where our glyph lies */
  118. for(b = 0; b < f->header.blocks; b++)
  119. {
  120. if(ch < f->block_list[b].start)
  121. {
  122. b = f->header.blocks;
  123. break;
  124. }
  125. if(ch < f->block_list[b].stop)
  126. break;
  127. }
  128. /* Glyph not in font? Skip it. */
  129. if(b == f->header.blocks)
  130. continue;
  131. g = &f->glyph_list[f->block_list[b].index
  132. + ch - f->block_list[b].start];
  133. for(j = 0; j < g->height; j++)
  134. {
  135. for(i = 0; i < g->width; i++)
  136. {
  137. /* FIXME: this is 8 bit only */
  138. buf[(starty + j) * qq->width * f->header.width
  139. + startx + i] = f->font_data[g->data_offset + j * g->width + i];
  140. }
  141. }
  142. }
  143. }
  144. for(y = 0; y < qq->height * f->header.height; y++)
  145. {
  146. for(x = 0; x < qq->width * f->header.width; x++)
  147. {
  148. printf("%.02x", buf[y * qq->width * f->header.width + x]);
  149. }
  150. printf("\n");
  151. }
  152. }
  153. /*
  154. * The libcaca font format, version 1
  155. * ----------------------------------
  156. *
  157. * All types are big endian.
  158. *
  159. * struct
  160. * {
  161. * uint8_t caca_header[4]; // "CACA"
  162. * uint8_t caca_file_type[4]; // "FONT"
  163. *
  164. * font_header:
  165. * uint32_t control_size; // Control size (font_data - font_header)
  166. * uint32_t data_size; // Data size (EOF - font_data)
  167. *
  168. * uint16_t version; // Font format version
  169. * // bit 0: set to 1 if font is compatible
  170. * // with version 1 of the format
  171. * // bits 1-15: unused yet, must be 0
  172. *
  173. * uint16_t blocks; // Number of blocks in the font
  174. * uint32_t glyphs; // Total number of glyphs in the font
  175. *
  176. * uint16_t bpp; // Bits per pixel for glyph data (valid
  177. * // Values are 1, 2, 4 and 8)
  178. * uint16_t width; // Maximum glyph width
  179. * uint16_t height; // Maximum glyph height
  180. *
  181. * uint16_t flags; // Feature flags
  182. * // bit 0: set to 1 if font is fixed width
  183. * // bits 1-15: unused yet, must be 0
  184. *
  185. * block_info:
  186. * struct
  187. * {
  188. * uint32_t start; // Unicode index of the first glyph
  189. * uint32_t stop; // Unicode index of the last glyph + 1
  190. * uint32_t index; // Glyph info index of the first glyph
  191. * }
  192. * block_list[blocks];
  193. *
  194. * glyph_info:
  195. * struct
  196. * {
  197. * uint16_t width; // Glyph width in pixels
  198. * uint16_t height; // Glyph height in pixels
  199. * uint32_t data_offset; // Offset (starting from data) to the data
  200. * // for the first character
  201. * }
  202. * glyph_list[glyphs];
  203. *
  204. * extension_1:
  205. * extension_2:
  206. * ...
  207. * extension_N:
  208. * ... // reserved for future use
  209. *
  210. * font_data:
  211. * uint8_t data[data_size]; // glyph data
  212. * };
  213. */