gdevpsfu.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /* Copyright (C) 2000 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: gdevpsfu.c,v 1.12 2004/11/19 04:39:11 ray Exp $ */
  14. /* PostScript/PDF font writing utilities */
  15. #include "memory_.h"
  16. #include <stdlib.h> /* for qsort */
  17. #include "gx.h"
  18. #include "gserrors.h"
  19. #include "gsmatrix.h" /* for gxfont.h */
  20. #include "gxfont.h"
  21. #include "gdevpsf.h"
  22. /* Begin enumerating the glyphs in a font or a font subset. */
  23. private int
  24. enumerate_font_next(psf_glyph_enum_t *ppge, gs_glyph *pglyph)
  25. {
  26. gs_font *font = ppge->font;
  27. int index = (int)ppge->index;
  28. int code = font->procs.enumerate_glyph(font, &index,
  29. ppge->glyph_space, pglyph);
  30. ppge->index = index;
  31. return (index == 0 ? 1 : code < 0 ? code : 0);
  32. }
  33. private int
  34. enumerate_glyphs_next(psf_glyph_enum_t *ppge, gs_glyph *pglyph)
  35. {
  36. if (ppge->index >= ppge->subset.size)
  37. return 1;
  38. *pglyph = ppge->subset.selected.list[ppge->index++];
  39. return 0;
  40. }
  41. private int
  42. enumerate_range_next(psf_glyph_enum_t *ppge, gs_glyph *pglyph)
  43. {
  44. if (ppge->index >= ppge->subset.size)
  45. return 1;
  46. *pglyph = (gs_glyph)(ppge->index++ + gs_min_cid_glyph);
  47. return 0;
  48. }
  49. void
  50. psf_enumerate_list_begin(psf_glyph_enum_t *ppge, gs_font *font,
  51. const gs_glyph *subset_list, uint subset_size,
  52. gs_glyph_space_t glyph_space)
  53. {
  54. ppge->font = font;
  55. ppge->subset.selected.list = subset_list;
  56. ppge->subset.size = subset_size;
  57. ppge->glyph_space = glyph_space;
  58. ppge->enumerate_next =
  59. (subset_list ? enumerate_glyphs_next :
  60. subset_size ? enumerate_range_next : enumerate_font_next);
  61. psf_enumerate_glyphs_reset(ppge);
  62. }
  63. /* Begin enumerating CID or TT glyphs in a subset given by a bit vector. */
  64. private int
  65. enumerate_bits_next(psf_glyph_enum_t *ppge, gs_glyph *pglyph)
  66. {
  67. for (; ppge->index < ppge->subset.size; ppge->index++)
  68. if (ppge->subset.selected.bits[ppge->index >> 3] & (0x80 >> (ppge->index & 7))) {
  69. *pglyph = (gs_glyph)(ppge->index++ + gs_min_cid_glyph);
  70. return 0;
  71. }
  72. return 1;
  73. }
  74. void
  75. psf_enumerate_bits_begin(psf_glyph_enum_t *ppge, gs_font *font,
  76. const byte *subset_bits, uint subset_size,
  77. gs_glyph_space_t glyph_space)
  78. {
  79. ppge->font = font;
  80. ppge->subset.selected.bits = subset_bits;
  81. ppge->subset.size = subset_size;
  82. ppge->glyph_space = glyph_space;
  83. ppge->enumerate_next =
  84. (subset_bits ? enumerate_bits_next :
  85. subset_size ? enumerate_range_next : enumerate_font_next);
  86. psf_enumerate_glyphs_reset(ppge);
  87. }
  88. /* Reset a glyph enumeration. */
  89. void
  90. psf_enumerate_glyphs_reset(psf_glyph_enum_t *ppge)
  91. {
  92. ppge->index = 0;
  93. }
  94. /* Enumerate the next glyph in a font or a font subset. */
  95. /* Return 0 if more glyphs, 1 if done, <0 if error. */
  96. int
  97. psf_enumerate_glyphs_next(psf_glyph_enum_t *ppge, gs_glyph *pglyph)
  98. {
  99. return ppge->enumerate_next(ppge, pglyph);
  100. }
  101. /*
  102. * Add composite glyph pieces to a list of glyphs. Does not sort or
  103. * remove duplicates. max_pieces is the maximum number of pieces that a
  104. * single glyph can have: if this value is not known, the caller should
  105. * use max_count.
  106. */
  107. int
  108. psf_add_subset_pieces(gs_glyph *glyphs, uint *pcount, uint max_count,
  109. uint max_pieces, gs_font *font)
  110. {
  111. uint i;
  112. uint count = *pcount;
  113. for (i = 0; i < count; ++i) {
  114. gs_glyph_info_t info;
  115. int code;
  116. if (count + max_pieces > max_count) {
  117. /* Check first to make sure there is enough room. */
  118. code = font->procs.glyph_info(font, glyphs[i], NULL,
  119. GLYPH_INFO_NUM_PIECES, &info);
  120. if (code < 0)
  121. continue;
  122. if (count + info.num_pieces > max_count)
  123. return_error(gs_error_rangecheck);
  124. }
  125. info.pieces = &glyphs[count];
  126. code = font->procs.glyph_info(font, glyphs[i], NULL,
  127. GLYPH_INFO_NUM_PIECES |
  128. GLYPH_INFO_PIECES, &info);
  129. if (code >= 0)
  130. count += info.num_pieces;
  131. }
  132. *pcount = count;
  133. return 0;
  134. }
  135. /*
  136. * Sort a list of glyphs and remove duplicates. Return the number of glyphs
  137. * in the result.
  138. */
  139. private int
  140. compare_glyphs(const void *pg1, const void *pg2)
  141. {
  142. gs_glyph g1 = *(const gs_glyph *)pg1, g2 = *(const gs_glyph *)pg2;
  143. return (g1 < g2 ? -1 : g1 > g2 ? 1 : 0);
  144. }
  145. int
  146. psf_sort_glyphs(gs_glyph *glyphs, int count)
  147. {
  148. int i, n;
  149. qsort(glyphs, count, sizeof(*glyphs), compare_glyphs);
  150. for (i = n = 0; i < count; ++i)
  151. if (i == 0 || glyphs[i] != glyphs[i - 1])
  152. glyphs[n++] = glyphs[i];
  153. return n;
  154. }
  155. /*
  156. * Return the index of a given glyph in a sorted list of glyphs, or -1
  157. * if the glyph is not present.
  158. */
  159. int
  160. psf_sorted_glyphs_index_of(const gs_glyph *glyphs, int count, gs_glyph glyph)
  161. {
  162. int lo = 0, hi = count - 1;
  163. if (hi < 0)
  164. return -1;
  165. if (glyph < glyphs[0] || glyph > glyphs[hi])
  166. return -1;
  167. /*
  168. * Loop invariants: hi > lo;
  169. * glyphs[lo] <= glyph <= glyphs[hi].
  170. */
  171. while (hi - lo > 1) {
  172. int mid = (lo + hi) >> 1;
  173. if (glyph >= glyphs[mid])
  174. lo = mid;
  175. else
  176. hi = mid;
  177. }
  178. return (glyph == glyphs[lo] ? lo : glyph == glyphs[hi] ? hi : -1);
  179. }
  180. /* Determine whether a sorted list of glyphs includes a given glyph. */
  181. bool
  182. psf_sorted_glyphs_include(const gs_glyph *glyphs, int count, gs_glyph glyph)
  183. {
  184. return psf_sorted_glyphs_index_of(glyphs, count, glyph) >= 0;
  185. }
  186. /* Check that all selected glyphs can be written. */
  187. int
  188. psf_check_outline_glyphs(gs_font_base *pfont, psf_glyph_enum_t *ppge,
  189. glyph_data_proc_t glyph_data)
  190. {
  191. uint members = GLYPH_INFO_WIDTH0 << pfont->WMode;
  192. gs_glyph glyph;
  193. int code;
  194. while ((code = psf_enumerate_glyphs_next(ppge, &glyph)) != 1) {
  195. gs_glyph_data_t gdata;
  196. gs_font_type1 *ignore_font;
  197. gs_glyph_info_t info;
  198. if (code < 0)
  199. return code;
  200. gdata.memory = pfont->memory;
  201. code = glyph_data(pfont, glyph, &gdata, &ignore_font);
  202. /*
  203. * If the glyph isn't defined by a CharString, glyph_data will
  204. * return a typecheck error. But if there's merely a glyph in
  205. * in the Encoding that isn't defined, glyph_data will return an
  206. * undefined error, which is OK.
  207. */
  208. if (code < 0) {
  209. if (code == gs_error_undefined)
  210. continue;
  211. return code;
  212. }
  213. gs_glyph_data_free(&gdata, "psf_check_outline_glyphs");
  214. /*
  215. * If the font has a CDevProc or calls a non-standard OtherSubr,
  216. * glyph_info will return a rangecheck error.
  217. */
  218. code = pfont->procs.glyph_info((gs_font *)pfont, glyph, NULL,
  219. members, &info);
  220. if (code < 0)
  221. return code;
  222. }
  223. return 0;
  224. }
  225. /* Gather glyph information for a Type 1 or Type 2 font. */
  226. int
  227. psf_get_outline_glyphs(psf_outline_glyphs_t *pglyphs, gs_font_base *pfont,
  228. gs_glyph *orig_subset_glyphs, uint orig_subset_size,
  229. glyph_data_proc_t glyph_data)
  230. {
  231. gs_glyph notdef = gs_no_glyph;
  232. gs_glyph *subset_glyphs = orig_subset_glyphs;
  233. uint subset_size = orig_subset_size;
  234. if (subset_glyphs) {
  235. if (subset_size > countof(pglyphs->subset_data))
  236. return_error(gs_error_limitcheck);
  237. memcpy(pglyphs->subset_data, orig_subset_glyphs,
  238. sizeof(gs_glyph) * subset_size);
  239. subset_glyphs = pglyphs->subset_data;
  240. }
  241. {
  242. /*
  243. * Make sure that this font can be written out. Specifically, it
  244. * must have no CharStrings defined by PostScript procedures, no
  245. * non-standard OtherSubrs, and no CDevProc.
  246. */
  247. psf_glyph_enum_t genum;
  248. int code;
  249. psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont, subset_glyphs,
  250. (subset_glyphs ? subset_size : 0),
  251. GLYPH_SPACE_NAME);
  252. code = psf_check_outline_glyphs(pfont, &genum, glyph_data);
  253. if (code < 0)
  254. return code;
  255. }
  256. {
  257. /*
  258. * Detect the .notdef glyph, needed for subset fonts and to
  259. * eliminate unnecessary Encoding assignments.
  260. */
  261. psf_glyph_enum_t genum;
  262. gs_glyph glyph;
  263. int code;
  264. psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont, NULL, 0,
  265. GLYPH_SPACE_NAME);
  266. while ((code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1) {
  267. if (gs_font_glyph_is_notdef(pfont, glyph)) {
  268. notdef = glyph;
  269. break;
  270. }
  271. }
  272. }
  273. if (subset_glyphs) {
  274. /*
  275. * For subset fonts, we must ensure that characters referenced
  276. * by seac are also included. Note that seac creates at most
  277. * 2 pieces.
  278. */
  279. int code = psf_add_subset_pieces(subset_glyphs, &subset_size,
  280. countof(pglyphs->subset_data) - 1, 2,
  281. (gs_font *)pfont);
  282. uint keep_size, i;
  283. if (code < 0)
  284. return code;
  285. /* Subset fonts require .notdef. */
  286. if (notdef == gs_no_glyph)
  287. return_error(gs_error_rangecheck);
  288. /* Remove undefined glyphs. */
  289. for (i = 0, keep_size = 0; i < subset_size; ++i) {
  290. gs_glyph_info_t info;
  291. gs_glyph glyph = subset_glyphs[i];
  292. /*
  293. * The documentation for the glyph_info procedure says that
  294. * using members = 0 is an inexpensive way to find out
  295. * whether a given glyph exists, but the implementations
  296. * don't actually do this. Request an inexpensive value.
  297. */
  298. if (pfont->procs.glyph_info((gs_font *)pfont, glyph, NULL,
  299. GLYPH_INFO_NUM_PIECES, &info) >= 0)
  300. subset_glyphs[keep_size++] = glyph;
  301. }
  302. subset_size = keep_size;
  303. /* Sort the glyphs. Make sure .notdef is included. */
  304. subset_glyphs[subset_size++] = notdef;
  305. subset_size = psf_sort_glyphs(subset_glyphs, subset_size);
  306. }
  307. pglyphs->notdef = notdef;
  308. pglyphs->subset_glyphs = subset_glyphs;
  309. pglyphs->subset_size = subset_size;
  310. return 0;
  311. }