pdf-font.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673
  1. // Copyright (C) 2004-2025 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. #include "mupdf/fitz.h"
  23. #include "mupdf/pdf.h"
  24. #include <assert.h>
  25. #include <ft2build.h>
  26. #include FT_FREETYPE_H
  27. #include FT_ADVANCES_H
  28. #ifdef FT_FONT_FORMATS_H
  29. #include FT_FONT_FORMATS_H
  30. #else
  31. #include FT_XFREE86_H
  32. #endif
  33. #include FT_TRUETYPE_TABLES_H
  34. #ifndef FT_SFNT_HEAD
  35. #define FT_SFNT_HEAD ft_sfnt_head
  36. #endif
  37. void
  38. pdf_load_encoding(const char **estrings, const char *encoding)
  39. {
  40. const char * const *bstrings = NULL;
  41. int i;
  42. if (!strcmp(encoding, "StandardEncoding"))
  43. bstrings = fz_glyph_name_from_adobe_standard;
  44. if (!strcmp(encoding, "MacRomanEncoding"))
  45. bstrings = fz_glyph_name_from_mac_roman;
  46. if (!strcmp(encoding, "MacExpertEncoding"))
  47. bstrings = fz_glyph_name_from_mac_expert;
  48. if (!strcmp(encoding, "WinAnsiEncoding"))
  49. bstrings = fz_glyph_name_from_win_ansi;
  50. if (bstrings)
  51. for (i = 0; i < 256; i++)
  52. estrings[i] = bstrings[i];
  53. }
  54. static void pdf_load_font_descriptor(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontdesc, pdf_obj *dict,
  55. const char *collection, const char *basefont, int iscidfont);
  56. static const char *base_font_names[][10] =
  57. {
  58. { "Courier", "CourierNew", "CourierNewPSMT", NULL },
  59. { "Courier-Bold", "CourierNew,Bold", "Courier,Bold",
  60. "CourierNewPS-BoldMT", "CourierNew-Bold", NULL },
  61. { "Courier-Oblique", "CourierNew,Italic", "Courier,Italic",
  62. "CourierNewPS-ItalicMT", "CourierNew-Italic", NULL },
  63. { "Courier-BoldOblique", "CourierNew,BoldItalic", "Courier,BoldItalic",
  64. "CourierNewPS-BoldItalicMT", "CourierNew-BoldItalic", NULL },
  65. { "Helvetica", "ArialMT", "Arial", NULL },
  66. { "Helvetica-Bold", "Arial-BoldMT", "Arial,Bold", "Arial-Bold",
  67. "Helvetica,Bold", NULL },
  68. { "Helvetica-Oblique", "Arial-ItalicMT", "Arial,Italic", "Arial-Italic",
  69. "Helvetica,Italic", "Helvetica-Italic", NULL },
  70. { "Helvetica-BoldOblique", "Arial-BoldItalicMT",
  71. "Arial,BoldItalic", "Arial-BoldItalic",
  72. "Helvetica,BoldItalic", "Helvetica-BoldItalic", NULL },
  73. { "Times-Roman", "TimesNewRomanPSMT", "TimesNewRoman",
  74. "TimesNewRomanPS", NULL },
  75. { "Times-Bold", "TimesNewRomanPS-BoldMT", "TimesNewRoman,Bold",
  76. "TimesNewRomanPS-Bold", "TimesNewRoman-Bold", NULL },
  77. { "Times-Italic", "TimesNewRomanPS-ItalicMT", "TimesNewRoman,Italic",
  78. "TimesNewRomanPS-Italic", "TimesNewRoman-Italic", NULL },
  79. { "Times-BoldItalic", "TimesNewRomanPS-BoldItalicMT",
  80. "TimesNewRoman,BoldItalic", "TimesNewRomanPS-BoldItalic",
  81. "TimesNewRoman-BoldItalic", NULL },
  82. { "Symbol", "Symbol,Italic", "Symbol,Bold", "Symbol,BoldItalic",
  83. "SymbolMT", "SymbolMT,Italic", "SymbolMT,Bold", "SymbolMT,BoldItalic", NULL },
  84. { "ZapfDingbats", NULL }
  85. };
  86. const unsigned char *
  87. pdf_lookup_substitute_font(fz_context *ctx, int mono, int serif, int bold, int italic, int *len)
  88. {
  89. if (mono) {
  90. if (bold) {
  91. if (italic) return fz_lookup_base14_font(ctx, "Courier-BoldOblique", len);
  92. else return fz_lookup_base14_font(ctx, "Courier-Bold", len);
  93. } else {
  94. if (italic) return fz_lookup_base14_font(ctx, "Courier-Oblique", len);
  95. else return fz_lookup_base14_font(ctx, "Courier", len);
  96. }
  97. } else if (serif) {
  98. if (bold) {
  99. if (italic) return fz_lookup_base14_font(ctx, "Times-BoldItalic", len);
  100. else return fz_lookup_base14_font(ctx, "Times-Bold", len);
  101. } else {
  102. if (italic) return fz_lookup_base14_font(ctx, "Times-Italic", len);
  103. else return fz_lookup_base14_font(ctx, "Times-Roman", len);
  104. }
  105. } else {
  106. if (bold) {
  107. if (italic) return fz_lookup_base14_font(ctx, "Helvetica-BoldOblique", len);
  108. else return fz_lookup_base14_font(ctx, "Helvetica-Bold", len);
  109. } else {
  110. if (italic) return fz_lookup_base14_font(ctx, "Helvetica-Oblique", len);
  111. else return fz_lookup_base14_font(ctx, "Helvetica", len);
  112. }
  113. }
  114. }
  115. static int is_dynalab(char *name)
  116. {
  117. if (strstr(name, "HuaTian"))
  118. return 1;
  119. if (strstr(name, "MingLi"))
  120. return 1;
  121. if ((strstr(name, "DF") == name) || strstr(name, "+DF"))
  122. return 1;
  123. if ((strstr(name, "DLC") == name) || strstr(name, "+DLC"))
  124. return 1;
  125. return 0;
  126. }
  127. static int strcmp_ignore_space(const char *a, const char *b)
  128. {
  129. while (1)
  130. {
  131. while (*a == ' ')
  132. a++;
  133. while (*b == ' ')
  134. b++;
  135. if (*a != *b)
  136. return 1;
  137. if (*a == 0)
  138. return *a != *b;
  139. if (*b == 0)
  140. return *a != *b;
  141. a++;
  142. b++;
  143. }
  144. }
  145. const char *pdf_clean_font_name(const char *fontname)
  146. {
  147. int i, k;
  148. for (i = 0; i < (int)nelem(base_font_names); i++)
  149. for (k = 0; base_font_names[i][k]; k++)
  150. if (!strcmp_ignore_space(base_font_names[i][k], fontname))
  151. return base_font_names[i][0];
  152. return fontname;
  153. }
  154. /*
  155. * FreeType and Rendering glue
  156. */
  157. enum { UNKNOWN, TYPE1, TRUETYPE };
  158. static int ft_kind(fz_context *ctx, FT_Face face)
  159. {
  160. const char *kind;
  161. fz_ft_lock(ctx);
  162. #ifdef FT_FONT_FORMATS_H
  163. kind = FT_Get_Font_Format(face);
  164. #else
  165. kind = FT_Get_X11_Font_Format(face);
  166. #endif
  167. fz_ft_unlock(ctx);
  168. if (!strcmp(kind, "TrueType")) return TRUETYPE;
  169. if (!strcmp(kind, "Type 1")) return TYPE1;
  170. if (!strcmp(kind, "CFF")) return TYPE1;
  171. if (!strcmp(kind, "CID Type 1")) return TYPE1;
  172. return UNKNOWN;
  173. }
  174. static int ft_cid_to_gid(pdf_font_desc *fontdesc, int cid)
  175. {
  176. if (fontdesc->to_ttf_cmap)
  177. {
  178. cid = pdf_lookup_cmap(fontdesc->to_ttf_cmap, cid);
  179. /* vertical presentation forms */
  180. if (fontdesc->font->flags.ft_substitute && fontdesc->wmode)
  181. {
  182. switch (cid)
  183. {
  184. case 0x0021: cid = 0xFE15; break; /* ! */
  185. case 0x0028: cid = 0xFE35; break; /* ( */
  186. case 0x0029: cid = 0xFE36; break; /* ) */
  187. case 0x002C: cid = 0xFE10; break; /* , */
  188. case 0x003A: cid = 0xFE13; break; /* : */
  189. case 0x003B: cid = 0xFE14; break; /* ; */
  190. case 0x003F: cid = 0xFE16; break; /* ? */
  191. case 0x005B: cid = 0xFE47; break; /* [ */
  192. case 0x005D: cid = 0xFE48; break; /* ] */
  193. case 0x005F: cid = 0xFE33; break; /* _ */
  194. case 0x007B: cid = 0xFE37; break; /* { */
  195. case 0x007D: cid = 0xFE38; break; /* } */
  196. case 0x2013: cid = 0xFE32; break; /* EN DASH */
  197. case 0x2014: cid = 0xFE31; break; /* EM DASH */
  198. case 0x2025: cid = 0xFE30; break; /* TWO DOT LEADER */
  199. case 0x2026: cid = 0xFE19; break; /* HORIZONTAL ELLIPSIS */
  200. case 0x3001: cid = 0xFE11; break; /* IDEOGRAPHIC COMMA */
  201. case 0x3002: cid = 0xFE12; break; /* IDEOGRAPHIC FULL STOP */
  202. case 0x3008: cid = 0xFE3F; break; /* OPENING ANGLE BRACKET */
  203. case 0x3009: cid = 0xFE40; break; /* CLOSING ANGLE BRACKET */
  204. case 0x300A: cid = 0xFE3D; break; /* LEFT DOUBLE ANGLE BRACKET */
  205. case 0x300B: cid = 0xFE3E; break; /* RIGHT DOUBLE ANGLE BRACKET */
  206. case 0x300C: cid = 0xFE41; break; /* LEFT CORNER BRACKET */
  207. case 0x300D: cid = 0xFE42; break; /* RIGHT CORNER BRACKET */
  208. case 0x300E: cid = 0xFE43; break; /* LEFT WHITE CORNER BRACKET */
  209. case 0x300F: cid = 0xFE44; break; /* RIGHT WHITE CORNER BRACKET */
  210. case 0x3010: cid = 0xFE3B; break; /* LEFT BLACK LENTICULAR BRACKET */
  211. case 0x3011: cid = 0xFE3C; break; /* RIGHT BLACK LENTICULAR BRACKET */
  212. case 0x3014: cid = 0xFE39; break; /* LEFT TORTOISE SHELL BRACKET */
  213. case 0x3015: cid = 0xFE3A; break; /* RIGHT TORTOISE SHELL BRACKET */
  214. case 0x3016: cid = 0xFE17; break; /* LEFT WHITE LENTICULAR BRACKET */
  215. case 0x3017: cid = 0xFE18; break; /* RIGHT WHITE LENTICULAR BRACKET */
  216. case 0xFF01: cid = 0xFE15; break; /* FULLWIDTH EXCLAMATION MARK */
  217. case 0xFF08: cid = 0xFE35; break; /* FULLWIDTH LEFT PARENTHESIS */
  218. case 0xFF09: cid = 0xFE36; break; /* FULLWIDTH RIGHT PARENTHESIS */
  219. case 0xFF0C: cid = 0xFE10; break; /* FULLWIDTH COMMA */
  220. case 0xFF1A: cid = 0xFE13; break; /* FULLWIDTH COLON */
  221. case 0xFF1B: cid = 0xFE14; break; /* FULLWIDTH SEMICOLON */
  222. case 0xFF1F: cid = 0xFE16; break; /* FULLWIDTH QUESTION MARK */
  223. case 0xFF3B: cid = 0xFE47; break; /* FULLWIDTH LEFT SQUARE BRACKET */
  224. case 0xFF3D: cid = 0xFE48; break; /* FULLWIDTH RIGHT SQUARE BRACKET */
  225. case 0xFF3F: cid = 0xFE33; break; /* FULLWIDTH LOW LINE */
  226. case 0xFF5B: cid = 0xFE37; break; /* FULLWIDTH LEFT CURLY BRACKET */
  227. case 0xFF5D: cid = 0xFE38; break; /* FULLWIDTH RIGHT CURLY BRACKET */
  228. case 0x30FC: cid = 0xFE31; break; /* KATAKANA-HIRAGANA PROLONGED SOUND MARK */
  229. case 0xFF0D: cid = 0xFE31; break; /* FULLWIDTH HYPHEN-MINUS */
  230. }
  231. }
  232. return ft_char_index(fontdesc->font->ft_face, cid);
  233. }
  234. if (fontdesc->cid_to_gid && (size_t)cid < fontdesc->cid_to_gid_len && cid >= 0)
  235. return fontdesc->cid_to_gid[cid];
  236. return cid;
  237. }
  238. int
  239. pdf_font_cid_to_gid(fz_context *ctx, pdf_font_desc *fontdesc, int cid)
  240. {
  241. if (fontdesc->font->ft_face)
  242. {
  243. int gid;
  244. fz_ft_lock(ctx);
  245. gid = ft_cid_to_gid(fontdesc, cid);
  246. fz_ft_unlock(ctx);
  247. return gid;
  248. }
  249. return cid;
  250. }
  251. static int ft_width(fz_context *ctx, pdf_font_desc *fontdesc, int cid)
  252. {
  253. int mask = FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM;
  254. int gid = ft_cid_to_gid(fontdesc, cid);
  255. FT_Fixed adv = 0;
  256. int fterr;
  257. FT_Face face = fontdesc->font->ft_face;
  258. FT_UShort units_per_EM;
  259. fterr = FT_Get_Advance(face, gid, mask, &adv);
  260. if (fterr && fterr != FT_Err_Invalid_Argument)
  261. fz_warn(ctx, "FT_Get_Advance(%d): %s", gid, ft_error_string(fterr));
  262. units_per_EM = face->units_per_EM;
  263. if (units_per_EM == 0)
  264. units_per_EM = 2048;
  265. return adv * 1000 / units_per_EM;
  266. }
  267. static const struct { int code; const char *name; } mre_diff_table[] =
  268. {
  269. { 173, "notequal" },
  270. { 176, "infinity" },
  271. { 178, "lessequal" },
  272. { 179, "greaterequal" },
  273. { 182, "partialdiff" },
  274. { 183, "summation" },
  275. { 184, "product" },
  276. { 185, "pi" },
  277. { 186, "integral" },
  278. { 189, "Omega" },
  279. { 195, "radical" },
  280. { 197, "approxequal" },
  281. { 198, "Delta" },
  282. { 215, "lozenge" },
  283. { 219, "Euro" },
  284. { 240, "apple" },
  285. };
  286. static int lookup_mre_code(const char *name)
  287. {
  288. int i;
  289. for (i = 0; i < (int)nelem(mre_diff_table); ++i)
  290. if (!strcmp(name, mre_diff_table[i].name))
  291. return mre_diff_table[i].code;
  292. for (i = 0; i < 256; i++)
  293. if (fz_glyph_name_from_mac_roman[i] && !strcmp(name, fz_glyph_name_from_mac_roman[i]))
  294. return i;
  295. return -1;
  296. }
  297. static int ft_find_glyph_by_unicode_name(FT_Face face, const char *name)
  298. {
  299. int unicode, glyph;
  300. /* Prefer exact unicode match if available. */
  301. unicode = fz_unicode_from_glyph_name_strict(name);
  302. if (unicode > 0)
  303. {
  304. glyph = ft_char_index(face, unicode);
  305. if (glyph > 0)
  306. return glyph;
  307. }
  308. /* Fall back to font glyph name if we can. */
  309. glyph = ft_name_index(face, name);
  310. if (glyph > 0)
  311. return glyph;
  312. /* Fuzzy unicode match as last attempt. */
  313. unicode = fz_unicode_from_glyph_name(name);
  314. if (unicode > 0)
  315. return ft_char_index(face, unicode);
  316. /* Failed. */
  317. return 0;
  318. }
  319. /*
  320. * Load font files.
  321. */
  322. static void
  323. pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, const char *fontname, int has_descriptor)
  324. {
  325. FT_Face face;
  326. const char *clean_name = pdf_clean_font_name(fontname);
  327. if (clean_name == fontname)
  328. clean_name = "Times-Roman";
  329. fontdesc->font = fz_load_system_font(ctx, fontname, 0, 0, !has_descriptor);
  330. if (!fontdesc->font)
  331. {
  332. const unsigned char *data;
  333. int len;
  334. data = fz_lookup_base14_font(ctx, clean_name, &len);
  335. if (!data)
  336. fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot find builtin font: '%s'", fontname);
  337. fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1);
  338. fontdesc->font->flags.is_serif = !!strstr(clean_name, "Times");
  339. }
  340. if (!strcmp(clean_name, "Symbol") || !strcmp(clean_name, "ZapfDingbats"))
  341. fontdesc->flags |= PDF_FD_SYMBOLIC;
  342. face = fontdesc->font->ft_face;
  343. fontdesc->ascent = 1000.0f * face->ascender / face->units_per_EM;
  344. fontdesc->descent = 1000.0f * face->descender / face->units_per_EM;
  345. }
  346. static void
  347. pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, const char *fontname, int mono, int serif, int bold, int italic)
  348. {
  349. fontdesc->font = fz_load_system_font(ctx, fontname, bold, italic, 0);
  350. if (!fontdesc->font)
  351. {
  352. const unsigned char *data;
  353. int len;
  354. data = pdf_lookup_substitute_font(ctx, mono, serif, bold, italic, &len);
  355. if (!data)
  356. fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot find substitute font");
  357. fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1);
  358. fontdesc->font->flags.fake_bold = bold && !fontdesc->font->flags.is_bold;
  359. fontdesc->font->flags.fake_italic = italic && !fontdesc->font->flags.is_italic;
  360. fontdesc->font->flags.is_mono = mono;
  361. fontdesc->font->flags.is_serif = serif;
  362. fontdesc->font->flags.is_bold = bold;
  363. fontdesc->font->flags.is_italic = italic;
  364. }
  365. fontdesc->font->flags.ft_substitute = 1;
  366. fontdesc->font->flags.ft_stretch = 1;
  367. }
  368. static void
  369. pdf_load_substitute_cjk_font(fz_context *ctx, pdf_font_desc *fontdesc, const char *fontname, int ros, int serif)
  370. {
  371. fontdesc->font = fz_load_system_cjk_font(ctx, fontname, ros, serif);
  372. if (!fontdesc->font)
  373. {
  374. const unsigned char *data;
  375. int size;
  376. int subfont;
  377. data = fz_lookup_cjk_font(ctx, ros, &size, &subfont);
  378. if (!data)
  379. fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot find builtin CJK font");
  380. /* A glyph bbox cache is too big for CJK fonts. */
  381. fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, size, subfont, 0);
  382. }
  383. fontdesc->font->flags.ft_substitute = 1;
  384. fontdesc->font->flags.ft_stretch = 0;
  385. fontdesc->font->flags.cjk = 1;
  386. fontdesc->font->flags.cjk_lang = ros;
  387. }
  388. static struct { int ros, serif; const char *name; } known_cjk_fonts[] = {
  389. { FZ_ADOBE_GB, 1, "SimFang" },
  390. { FZ_ADOBE_GB, 0, "SimHei" },
  391. { FZ_ADOBE_GB, 1, "SimKai" },
  392. { FZ_ADOBE_GB, 1, "SimLi" },
  393. { FZ_ADOBE_GB, 1, "SimSun" },
  394. { FZ_ADOBE_GB, 1, "Song" },
  395. { FZ_ADOBE_CNS, 1, "MingLiU" },
  396. { FZ_ADOBE_JAPAN, 0, "Gothic" },
  397. { FZ_ADOBE_JAPAN, 1, "Mincho" },
  398. { FZ_ADOBE_KOREA, 1, "Batang" },
  399. { FZ_ADOBE_KOREA, 0, "Gulim" },
  400. { FZ_ADOBE_KOREA, 0, "Dotum" },
  401. };
  402. static int match_font_name(const char *s, const char *ref)
  403. {
  404. return !!strstr(s, ref);
  405. }
  406. static void
  407. pdf_load_system_font(fz_context *ctx, pdf_font_desc *fontdesc, const char *fontname, const char *collection)
  408. {
  409. int bold = 0;
  410. int italic = 0;
  411. int serif = 0;
  412. int mono = 0;
  413. if (strstr(fontname, "Bold"))
  414. bold = 1;
  415. if (strstr(fontname, "Italic"))
  416. italic = 1;
  417. if (strstr(fontname, "Oblique"))
  418. italic = 1;
  419. if (fontdesc->flags & PDF_FD_FIXED_PITCH)
  420. mono = 1;
  421. if (fontdesc->flags & PDF_FD_SERIF)
  422. serif = 1;
  423. if (fontdesc->flags & PDF_FD_ITALIC)
  424. italic = 1;
  425. if (fontdesc->flags & PDF_FD_FORCE_BOLD)
  426. bold = 1;
  427. if (collection)
  428. {
  429. if (!strcmp(collection, "Adobe-CNS1"))
  430. pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, FZ_ADOBE_CNS, serif);
  431. else if (!strcmp(collection, "Adobe-GB1"))
  432. pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, FZ_ADOBE_GB, serif);
  433. else if (!strcmp(collection, "Adobe-Japan1"))
  434. pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, FZ_ADOBE_JAPAN, serif);
  435. else if (!strcmp(collection, "Adobe-Korea1"))
  436. pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, FZ_ADOBE_KOREA, serif);
  437. else
  438. {
  439. size_t i;
  440. if (strcmp(collection, "Adobe-Identity") != 0)
  441. fz_warn(ctx, "unknown cid collection: %s", collection);
  442. // Recognize common CJK fonts when using Identity or other non-CJK CMap
  443. for (i = 0; i < nelem(known_cjk_fonts); ++i)
  444. {
  445. if (match_font_name(fontname, known_cjk_fonts[i].name))
  446. {
  447. pdf_load_substitute_cjk_font(ctx, fontdesc, fontname,
  448. known_cjk_fonts[i].ros, known_cjk_fonts[i].serif);
  449. return;
  450. }
  451. }
  452. pdf_load_substitute_font(ctx, fontdesc, fontname, mono, serif, bold, italic);
  453. }
  454. }
  455. else
  456. {
  457. pdf_load_substitute_font(ctx, fontdesc, fontname, mono, serif, bold, italic);
  458. }
  459. }
  460. #define TTF_U16(p) ((uint16_t) ((p)[0]<<8) | ((p)[1]))
  461. #define TTF_U32(p) ((uint32_t) ((p)[0]<<24) | ((p)[1]<<16) | ((p)[2]<<8) | ((p)[3]))
  462. static fz_buffer *
  463. pdf_extract_cff_subtable(fz_context *ctx, unsigned char *data, size_t size)
  464. {
  465. size_t num_tables = TTF_U16(data + 4);
  466. size_t i;
  467. if (12 + num_tables * 16 > size)
  468. fz_throw(ctx, FZ_ERROR_SYNTAX, "invalid TTF header");
  469. for (i = 0; i < num_tables; ++i)
  470. {
  471. unsigned char *record = data + 12 + i * 16;
  472. if (!memcmp("CFF ", record, 4))
  473. {
  474. uint64_t offset = TTF_U32(record + 8);
  475. uint64_t length = TTF_U32(record + 12);
  476. uint64_t end = offset + length;
  477. if (end > size)
  478. fz_throw(ctx, FZ_ERROR_SYNTAX, "invalid TTF subtable offset/length");
  479. return fz_new_buffer_from_copied_data(ctx, data + offset, length);
  480. }
  481. }
  482. return NULL;
  483. }
  484. static void
  485. pdf_load_embedded_font(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontdesc, const char *fontname, pdf_obj *stmref)
  486. {
  487. fz_buffer *buf;
  488. unsigned char *data;
  489. size_t size;
  490. fz_var(buf);
  491. buf = pdf_load_stream(ctx, stmref);
  492. fz_try(ctx)
  493. {
  494. /* Extract CFF subtable for OpenType fonts: */
  495. size = fz_buffer_storage(ctx, buf, &data);
  496. if (size > 12) {
  497. if (!memcmp("OTTO", data, 4)) {
  498. fz_buffer *cff = pdf_extract_cff_subtable(ctx, data, size);
  499. if (cff)
  500. {
  501. fz_drop_buffer(ctx, buf);
  502. buf = cff;
  503. }
  504. }
  505. }
  506. fontdesc->font = fz_new_font_from_buffer(ctx, fontname, buf, 0, 1);
  507. }
  508. fz_always(ctx)
  509. fz_drop_buffer(ctx, buf);
  510. fz_catch(ctx)
  511. fz_rethrow(ctx);
  512. fontdesc->size += fz_buffer_storage(ctx, buf, NULL);
  513. fontdesc->is_embedded = 1;
  514. }
  515. /*
  516. * Create and destroy
  517. */
  518. pdf_font_desc *
  519. pdf_keep_font(fz_context *ctx, pdf_font_desc *fontdesc)
  520. {
  521. return fz_keep_storable(ctx, &fontdesc->storable);
  522. }
  523. void
  524. pdf_drop_font(fz_context *ctx, pdf_font_desc *fontdesc)
  525. {
  526. fz_drop_storable(ctx, &fontdesc->storable);
  527. }
  528. static int
  529. pdf_font_is_droppable(fz_context *ctx, fz_storable *fontdesc)
  530. {
  531. /* If we aren't holding the FT lock, then we can drop. */
  532. return !fz_ft_lock_held(ctx);
  533. }
  534. static void
  535. pdf_drop_font_imp(fz_context *ctx, fz_storable *fontdesc_)
  536. {
  537. pdf_font_desc *fontdesc = (pdf_font_desc *)fontdesc_;
  538. fz_drop_font(ctx, fontdesc->font);
  539. pdf_drop_cmap(ctx, fontdesc->encoding);
  540. pdf_drop_cmap(ctx, fontdesc->to_ttf_cmap);
  541. pdf_drop_cmap(ctx, fontdesc->to_unicode);
  542. fz_free(ctx, fontdesc->cid_to_gid);
  543. fz_free(ctx, fontdesc->cid_to_ucs);
  544. fz_free(ctx, fontdesc->hmtx);
  545. fz_free(ctx, fontdesc->vmtx);
  546. fz_free(ctx, fontdesc);
  547. }
  548. pdf_font_desc *
  549. pdf_new_font_desc(fz_context *ctx)
  550. {
  551. pdf_font_desc *fontdesc;
  552. fontdesc = fz_malloc_struct(ctx, pdf_font_desc);
  553. FZ_INIT_AWKWARD_STORABLE(fontdesc, 1, pdf_drop_font_imp, pdf_font_is_droppable);
  554. fontdesc->size = sizeof(pdf_font_desc);
  555. fontdesc->font = NULL;
  556. fontdesc->flags = 0;
  557. fontdesc->italic_angle = 0;
  558. fontdesc->ascent = 800;
  559. fontdesc->descent = -200;
  560. fontdesc->cap_height = 800;
  561. fontdesc->x_height = 500;
  562. fontdesc->missing_width = 0;
  563. fontdesc->encoding = NULL;
  564. fontdesc->to_ttf_cmap = NULL;
  565. fontdesc->cid_to_gid_len = 0;
  566. fontdesc->cid_to_gid = NULL;
  567. fontdesc->to_unicode = NULL;
  568. fontdesc->cid_to_ucs_len = 0;
  569. fontdesc->cid_to_ucs = NULL;
  570. fontdesc->wmode = 0;
  571. fontdesc->hmtx_cap = 0;
  572. fontdesc->vmtx_cap = 0;
  573. fontdesc->hmtx_len = 0;
  574. fontdesc->vmtx_len = 0;
  575. fontdesc->hmtx = NULL;
  576. fontdesc->vmtx = NULL;
  577. fontdesc->dhmtx.lo = 0x0000;
  578. fontdesc->dhmtx.hi = 0xFFFF;
  579. fontdesc->dhmtx.w = 1000;
  580. fontdesc->dvmtx.lo = 0x0000;
  581. fontdesc->dvmtx.hi = 0xFFFF;
  582. fontdesc->dvmtx.x = 0;
  583. fontdesc->dvmtx.y = 880;
  584. fontdesc->dvmtx.w = -1000;
  585. fontdesc->is_embedded = 0;
  586. return fontdesc;
  587. }
  588. /*
  589. * Simple fonts (Type1 and TrueType)
  590. */
  591. static FT_CharMap
  592. select_type1_cmap(FT_Face face)
  593. {
  594. int i;
  595. for (i = 0; i < face->num_charmaps; i++)
  596. if (face->charmaps[i]->platform_id == 7)
  597. return face->charmaps[i];
  598. if (face->num_charmaps > 0)
  599. return face->charmaps[0];
  600. return NULL;
  601. }
  602. static FT_CharMap
  603. select_truetype_cmap(fz_context *ctx, FT_Face face, int symbolic)
  604. {
  605. int i;
  606. /* First look for a Microsoft symbolic cmap, if applicable */
  607. if (symbolic)
  608. {
  609. for (i = 0; i < face->num_charmaps; i++)
  610. if (face->charmaps[i]->platform_id == 3 && face->charmaps[i]->encoding_id == 0)
  611. return face->charmaps[i];
  612. }
  613. fz_ft_lock(ctx);
  614. /* Then look for a Microsoft Unicode cmap */
  615. for (i = 0; i < face->num_charmaps; i++)
  616. if (face->charmaps[i]->platform_id == 3 && face->charmaps[i]->encoding_id == 1)
  617. if (FT_Get_CMap_Format(face->charmaps[i]) != -1)
  618. {
  619. fz_ft_unlock(ctx);
  620. return face->charmaps[i];
  621. }
  622. /* Finally look for an Apple MacRoman cmap */
  623. for (i = 0; i < face->num_charmaps; i++)
  624. if (face->charmaps[i]->platform_id == 1 && face->charmaps[i]->encoding_id == 0)
  625. if (FT_Get_CMap_Format(face->charmaps[i]) != -1)
  626. {
  627. fz_ft_unlock(ctx);
  628. return face->charmaps[i];
  629. }
  630. if (face->num_charmaps > 0)
  631. if (FT_Get_CMap_Format(face->charmaps[0]) != -1)
  632. {
  633. fz_ft_unlock(ctx);
  634. return face->charmaps[0];
  635. }
  636. fz_ft_unlock(ctx);
  637. return NULL;
  638. }
  639. static FT_CharMap
  640. select_unknown_cmap(FT_Face face)
  641. {
  642. if (face->num_charmaps > 0)
  643. return face->charmaps[0];
  644. return NULL;
  645. }
  646. static int use_s22pdf_workaround(fz_context *ctx, pdf_obj *dict, pdf_obj *descriptor)
  647. {
  648. if (descriptor)
  649. {
  650. if (pdf_dict_get(ctx, dict, PDF_NAME(Encoding)) != PDF_NAME(WinAnsiEncoding))
  651. return 0;
  652. if (pdf_dict_get_int(ctx, descriptor, PDF_NAME(Flags)) != 4)
  653. return 0;
  654. return 1;
  655. }
  656. return 0;
  657. }
  658. static pdf_font_desc *
  659. pdf_load_simple_font(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
  660. {
  661. const char *basefont;
  662. pdf_obj *descriptor;
  663. pdf_obj *encoding;
  664. pdf_obj *widths;
  665. unsigned short *etable = NULL;
  666. pdf_font_desc *fontdesc = NULL;
  667. pdf_obj *subtype;
  668. FT_Face face;
  669. FT_CharMap cmap;
  670. int symbolic;
  671. int kind;
  672. int glyph;
  673. const char *estrings[256];
  674. char ebuffer[256][32];
  675. int i, k, n;
  676. int fterr;
  677. int has_lock = 0;
  678. fz_var(fontdesc);
  679. fz_var(etable);
  680. fz_var(has_lock);
  681. /* Load font file */
  682. fz_try(ctx)
  683. {
  684. fontdesc = pdf_new_font_desc(ctx);
  685. basefont = pdf_dict_get_name(ctx, dict, PDF_NAME(BaseFont));
  686. descriptor = pdf_dict_get(ctx, dict, PDF_NAME(FontDescriptor));
  687. if (descriptor)
  688. pdf_load_font_descriptor(ctx, doc, fontdesc, descriptor, NULL, basefont, 0);
  689. else
  690. pdf_load_builtin_font(ctx, fontdesc, basefont, 0);
  691. /* Some chinese documents mistakenly consider WinAnsiEncoding to be codepage 936 */
  692. if (use_s22pdf_workaround(ctx, dict, descriptor))
  693. {
  694. char *cp936fonts[] = {
  695. "\xCB\xCE\xCC\xE5", "SimSun,Regular",
  696. "\xBA\xDA\xCC\xE5", "SimHei,Regular",
  697. "\xBF\xAC\xCC\xE5_GB2312", "SimKai,Regular",
  698. "\xB7\xC2\xCB\xCE_GB2312", "SimFang,Regular",
  699. "\xC1\xA5\xCA\xE9", "SimLi,Regular",
  700. NULL
  701. };
  702. for (i = 0; cp936fonts[i]; i += 2)
  703. if (!strcmp(basefont, cp936fonts[i]))
  704. break;
  705. if (cp936fonts[i])
  706. {
  707. fz_warn(ctx, "workaround for S22PDF lying about chinese font encodings");
  708. pdf_drop_font(ctx, fontdesc);
  709. fontdesc = NULL;
  710. fontdesc = pdf_new_font_desc(ctx);
  711. pdf_load_font_descriptor(ctx, doc, fontdesc, descriptor, "Adobe-GB1", cp936fonts[i+1], 0);
  712. fontdesc->encoding = pdf_load_system_cmap(ctx, "GBK-EUC-H");
  713. fontdesc->to_unicode = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2");
  714. fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2");
  715. goto skip_encoding;
  716. }
  717. }
  718. face = fontdesc->font->ft_face;
  719. kind = ft_kind(ctx, face);
  720. /* Encoding */
  721. symbolic = fontdesc->flags & 4;
  722. /* Bug 703273: If non-symbolic, we're not symbolic. */
  723. if (fontdesc->flags & 32)
  724. symbolic = 0;
  725. if (kind == TYPE1)
  726. cmap = select_type1_cmap(face);
  727. else if (kind == TRUETYPE)
  728. cmap = select_truetype_cmap(ctx, face, symbolic);
  729. else
  730. cmap = select_unknown_cmap(face);
  731. if (cmap)
  732. {
  733. fz_ft_lock(ctx);
  734. fterr = FT_Set_Charmap(face, cmap);
  735. fz_ft_unlock(ctx);
  736. if (fterr)
  737. fz_warn(ctx, "freetype could not set cmap: %s", ft_error_string(fterr));
  738. }
  739. else
  740. fz_warn(ctx, "freetype could not find any cmaps");
  741. /* FIXME: etable may leak on error. */
  742. etable = Memento_label(fz_malloc_array(ctx, 256, unsigned short), "cid_to_gid");
  743. fontdesc->size += 256 * sizeof(unsigned short);
  744. for (i = 0; i < 256; i++)
  745. {
  746. estrings[i] = NULL;
  747. etable[i] = 0;
  748. }
  749. encoding = pdf_dict_get(ctx, dict, PDF_NAME(Encoding));
  750. if (encoding)
  751. {
  752. if (pdf_is_name(ctx, encoding))
  753. pdf_load_encoding(estrings, pdf_to_name(ctx, encoding));
  754. if (pdf_is_dict(ctx, encoding))
  755. {
  756. pdf_obj *base, *diff, *item;
  757. base = pdf_dict_get(ctx, encoding, PDF_NAME(BaseEncoding));
  758. if (pdf_is_name(ctx, base))
  759. pdf_load_encoding(estrings, pdf_to_name(ctx, base));
  760. else if (!fontdesc->is_embedded && !symbolic)
  761. pdf_load_encoding(estrings, "StandardEncoding");
  762. diff = pdf_dict_get(ctx, encoding, PDF_NAME(Differences));
  763. if (pdf_is_array(ctx, diff))
  764. {
  765. n = pdf_array_len(ctx, diff);
  766. k = 0;
  767. for (i = 0; i < n; i++)
  768. {
  769. item = pdf_array_get(ctx, diff, i);
  770. if (pdf_is_int(ctx, item))
  771. k = pdf_to_int(ctx, item);
  772. if (pdf_is_name(ctx, item) && k >= 0 && k < (int)nelem(estrings))
  773. estrings[k++] = pdf_to_name(ctx, item);
  774. }
  775. }
  776. }
  777. }
  778. else if (!fontdesc->is_embedded && !symbolic)
  779. pdf_load_encoding(estrings, "StandardEncoding");
  780. fz_ft_lock(ctx);
  781. has_lock = 1;
  782. /* start with the builtin encoding */
  783. for (i = 0; i < 256; i++)
  784. etable[i] = ft_char_index(face, i);
  785. /* built-in and substitute fonts may be a different type than what the document expects */
  786. subtype = pdf_dict_get(ctx, dict, PDF_NAME(Subtype));
  787. if (pdf_name_eq(ctx, subtype, PDF_NAME(Type1)))
  788. kind = TYPE1;
  789. else if (pdf_name_eq(ctx, subtype, PDF_NAME(MMType1)))
  790. kind = TYPE1;
  791. else if (pdf_name_eq(ctx, subtype, PDF_NAME(TrueType)))
  792. kind = TRUETYPE;
  793. else if (pdf_name_eq(ctx, subtype, PDF_NAME(CIDFontType0)))
  794. kind = TYPE1;
  795. else if (pdf_name_eq(ctx, subtype, PDF_NAME(CIDFontType2)))
  796. kind = TRUETYPE;
  797. /* encode by glyph name where we can */
  798. if (kind == TYPE1)
  799. {
  800. for (i = 0; i < 256; i++)
  801. {
  802. if (estrings[i])
  803. {
  804. glyph = ft_name_index(face, estrings[i]);
  805. if (glyph > 0)
  806. etable[i] = glyph;
  807. }
  808. }
  809. }
  810. /* encode by glyph name where we can */
  811. if (kind == TRUETYPE)
  812. {
  813. /* Unicode cmap */
  814. if (!symbolic && face->charmap && face->charmap->platform_id == 3)
  815. {
  816. for (i = 0; i < 256; i++)
  817. {
  818. if (estrings[i])
  819. {
  820. glyph = ft_find_glyph_by_unicode_name(face, estrings[i]);
  821. if (glyph > 0)
  822. etable[i] = glyph;
  823. }
  824. }
  825. }
  826. /* MacRoman cmap */
  827. else if (!symbolic && face->charmap && face->charmap->platform_id == 1)
  828. {
  829. for (i = 0; i < 256; i++)
  830. {
  831. if (estrings[i])
  832. {
  833. int mrcode = lookup_mre_code(estrings[i]);
  834. glyph = 0;
  835. if (mrcode > 0)
  836. glyph = ft_char_index(face, mrcode);
  837. if (glyph == 0)
  838. glyph = ft_name_index(face, estrings[i]);
  839. if (glyph > 0)
  840. etable[i] = glyph;
  841. }
  842. }
  843. }
  844. /* Symbolic cmap */
  845. else if (!face->charmap || face->charmap->encoding != FT_ENCODING_MS_SYMBOL)
  846. {
  847. for (i = 0; i < 256; i++)
  848. {
  849. if (estrings[i])
  850. {
  851. glyph = ft_name_index(face, estrings[i]);
  852. if (glyph > 0)
  853. etable[i] = glyph;
  854. }
  855. }
  856. }
  857. }
  858. /* try to reverse the glyph names from the builtin encoding */
  859. for (i = 0; i < 256; i++)
  860. {
  861. if (etable[i] && !estrings[i])
  862. {
  863. if (FT_HAS_GLYPH_NAMES(face))
  864. {
  865. fterr = FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32);
  866. if (fterr)
  867. fz_warn(ctx, "freetype get glyph name (gid %d): %s", etable[i], ft_error_string(fterr));
  868. if (ebuffer[i][0])
  869. estrings[i] = ebuffer[i];
  870. }
  871. else
  872. {
  873. estrings[i] = (char*) fz_glyph_name_from_win_ansi[i]; /* discard const */
  874. }
  875. }
  876. }
  877. /* symbolic Type 1 fonts with an implicit encoding and non-standard glyph names */
  878. if (kind == TYPE1 && symbolic)
  879. {
  880. for (i = 0; i < 256; i++)
  881. if (etable[i] && estrings[i] && !fz_unicode_from_glyph_name(estrings[i]))
  882. estrings[i] = (char*) fz_glyph_name_from_adobe_standard[i];
  883. }
  884. fz_ft_unlock(ctx);
  885. has_lock = 0;
  886. fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1);
  887. fontdesc->size += pdf_cmap_size(ctx, fontdesc->encoding);
  888. fontdesc->cid_to_gid_len = 256;
  889. fontdesc->cid_to_gid = etable;
  890. fz_try(ctx)
  891. {
  892. pdf_load_to_unicode(ctx, doc, fontdesc, estrings, NULL, pdf_dict_get(ctx, dict, PDF_NAME(ToUnicode)));
  893. }
  894. fz_catch(ctx)
  895. {
  896. fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
  897. fz_rethrow_if(ctx, FZ_ERROR_SYSTEM);
  898. fz_report_error(ctx);
  899. fz_warn(ctx, "cannot load ToUnicode CMap");
  900. }
  901. skip_encoding:
  902. /* Widths */
  903. pdf_set_default_hmtx(ctx, fontdesc, fontdesc->missing_width);
  904. widths = pdf_dict_get(ctx, dict, PDF_NAME(Widths));
  905. if (widths)
  906. {
  907. int first, last;
  908. first = pdf_dict_get_int(ctx, dict, PDF_NAME(FirstChar));
  909. last = pdf_dict_get_int(ctx, dict, PDF_NAME(LastChar));
  910. if (first < 0 || last > 255 || first > last)
  911. first = last = 0;
  912. for (i = 0; i < last - first + 1; i++)
  913. {
  914. int wid = pdf_array_get_int(ctx, widths, i);
  915. pdf_add_hmtx(ctx, fontdesc, i + first, i + first, wid);
  916. }
  917. }
  918. else
  919. {
  920. fz_ft_lock(ctx);
  921. has_lock = 1;
  922. for (i = 0; i < 256; i++)
  923. pdf_add_hmtx(ctx, fontdesc, i, i, ft_width(ctx, fontdesc, i));
  924. fz_ft_unlock(ctx);
  925. has_lock = 0;
  926. }
  927. pdf_end_hmtx(ctx, fontdesc);
  928. }
  929. fz_catch(ctx)
  930. {
  931. if (has_lock)
  932. fz_ft_unlock(ctx);
  933. if (fontdesc && etable != fontdesc->cid_to_gid)
  934. fz_free(ctx, etable);
  935. pdf_drop_font(ctx, fontdesc);
  936. fz_rethrow(ctx);
  937. }
  938. return fontdesc;
  939. }
  940. static int
  941. hail_mary_make_hash_key(fz_context *ctx, fz_store_hash *hash, void *key_)
  942. {
  943. hash->u.pi.i = 0;
  944. hash->u.pi.ptr = NULL;
  945. return 1;
  946. }
  947. static void *
  948. hail_mary_keep_key(fz_context *ctx, void *key)
  949. {
  950. return key;
  951. }
  952. static void
  953. hail_mary_drop_key(fz_context *ctx, void *key)
  954. {
  955. }
  956. static int
  957. hail_mary_cmp_key(fz_context *ctx, void *k0, void *k1)
  958. {
  959. return k0 == k1;
  960. }
  961. static void
  962. hail_mary_format_key(fz_context *ctx, char *s, size_t n, void *key_)
  963. {
  964. fz_strlcpy(s, "(hail mary font)", n);
  965. }
  966. static int hail_mary_store_key; /* Dummy */
  967. static const fz_store_type hail_mary_store_type =
  968. {
  969. "hail-mary",
  970. hail_mary_make_hash_key,
  971. hail_mary_keep_key,
  972. hail_mary_drop_key,
  973. hail_mary_cmp_key,
  974. hail_mary_format_key,
  975. NULL
  976. };
  977. pdf_font_desc *
  978. pdf_load_hail_mary_font(fz_context *ctx, pdf_document *doc)
  979. {
  980. pdf_font_desc *fontdesc;
  981. pdf_font_desc *existing;
  982. if ((fontdesc = fz_find_item(ctx, pdf_drop_font_imp, &hail_mary_store_key, &hail_mary_store_type)) != NULL)
  983. {
  984. return fontdesc;
  985. }
  986. /* FIXME: Get someone with a clue about fonts to fix this */
  987. fontdesc = pdf_load_simple_font(ctx, doc, NULL);
  988. existing = fz_store_item(ctx, &hail_mary_store_key, fontdesc, fontdesc->size, &hail_mary_store_type);
  989. assert(existing == NULL);
  990. (void)existing; /* Silence warning in release builds */
  991. return fontdesc;
  992. }
  993. /*
  994. * CID Fonts
  995. */
  996. static pdf_font_desc *
  997. load_cid_font(fz_context *ctx, pdf_document *doc, pdf_obj *dict, pdf_obj *encoding, pdf_obj *to_unicode)
  998. {
  999. pdf_obj *widths;
  1000. pdf_obj *descriptor;
  1001. pdf_font_desc *fontdesc = NULL;
  1002. fz_buffer *buf = NULL;
  1003. pdf_cmap *cmap;
  1004. FT_Face face;
  1005. char collection[256];
  1006. const char *basefont;
  1007. int i, k, fterr;
  1008. pdf_obj *cidtogidmap;
  1009. pdf_obj *obj;
  1010. int dw;
  1011. fz_var(fontdesc);
  1012. fz_var(buf);
  1013. fz_try(ctx)
  1014. {
  1015. /* Get font name and CID collection */
  1016. basefont = pdf_dict_get_name(ctx, dict, PDF_NAME(BaseFont));
  1017. {
  1018. pdf_obj *cidinfo;
  1019. const char *reg, *ord;
  1020. cidinfo = pdf_dict_get(ctx, dict, PDF_NAME(CIDSystemInfo));
  1021. if (cidinfo)
  1022. {
  1023. reg = pdf_dict_get_string(ctx, cidinfo, PDF_NAME(Registry), NULL);
  1024. ord = pdf_dict_get_string(ctx, cidinfo, PDF_NAME(Ordering), NULL);
  1025. fz_snprintf(collection, sizeof collection, "%s-%s", reg, ord);
  1026. }
  1027. else
  1028. {
  1029. fz_warn(ctx, "CIDFont is missing CIDSystemInfo dictionary; assuming Adobe-Identity");
  1030. fz_strlcpy(collection, "Adobe-Identity", sizeof collection);
  1031. }
  1032. }
  1033. /* Encoding */
  1034. if (pdf_is_name(ctx, encoding))
  1035. {
  1036. cmap = pdf_load_system_cmap(ctx, pdf_to_name(ctx, encoding));
  1037. }
  1038. else if (pdf_is_indirect(ctx, encoding))
  1039. {
  1040. cmap = pdf_load_embedded_cmap(ctx, doc, encoding);
  1041. }
  1042. else
  1043. {
  1044. fz_throw(ctx, FZ_ERROR_SYNTAX, "font missing encoding");
  1045. }
  1046. /* Load font file */
  1047. fontdesc = pdf_new_font_desc(ctx);
  1048. fontdesc->encoding = cmap;
  1049. fontdesc->size += pdf_cmap_size(ctx, fontdesc->encoding);
  1050. pdf_set_font_wmode(ctx, fontdesc, pdf_cmap_wmode(ctx, fontdesc->encoding));
  1051. descriptor = pdf_dict_get(ctx, dict, PDF_NAME(FontDescriptor));
  1052. if (!descriptor)
  1053. fz_throw(ctx, FZ_ERROR_SYNTAX, "missing font descriptor");
  1054. pdf_load_font_descriptor(ctx, doc, fontdesc, descriptor, collection, basefont, 1);
  1055. face = fontdesc->font->ft_face;
  1056. /* Apply encoding */
  1057. cidtogidmap = pdf_dict_get(ctx, dict, PDF_NAME(CIDToGIDMap));
  1058. if (pdf_is_stream(ctx, cidtogidmap))
  1059. {
  1060. size_t z, len;
  1061. unsigned char *data;
  1062. buf = pdf_load_stream(ctx, cidtogidmap);
  1063. len = fz_buffer_storage(ctx, buf, &data);
  1064. fontdesc->cid_to_gid_len = len / 2;
  1065. fontdesc->cid_to_gid = Memento_label(fz_malloc_array(ctx, fontdesc->cid_to_gid_len, unsigned short), "cid_to_gid_map");
  1066. fontdesc->size += fontdesc->cid_to_gid_len * sizeof(unsigned short);
  1067. for (z = 0; z < fontdesc->cid_to_gid_len; z++)
  1068. fontdesc->cid_to_gid[z] = (data[z * 2] << 8) + data[z * 2 + 1];
  1069. }
  1070. else if (cidtogidmap && !pdf_name_eq(ctx, PDF_NAME(Identity), cidtogidmap))
  1071. {
  1072. fz_warn(ctx, "ignoring unknown CIDToGIDMap entry");
  1073. }
  1074. /* if font is external, cidtogidmap should not be identity */
  1075. /* so we map from cid to unicode and then map that through the (3 1) */
  1076. /* unicode cmap to get a glyph id */
  1077. else if (fontdesc->font->flags.ft_substitute)
  1078. {
  1079. fz_ft_lock(ctx);
  1080. fterr = FT_Select_Charmap(face, ft_encoding_unicode);
  1081. fz_ft_unlock(ctx);
  1082. if (fterr)
  1083. fz_throw(ctx, FZ_ERROR_SYNTAX, "no unicode cmap when emulating CID font: %s", ft_error_string(fterr));
  1084. if (!strcmp(collection, "Adobe-CNS1"))
  1085. fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-CNS1-UCS2");
  1086. else if (!strcmp(collection, "Adobe-GB1"))
  1087. fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2");
  1088. else if (!strcmp(collection, "Adobe-Japan1"))
  1089. fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-Japan1-UCS2");
  1090. else if (!strcmp(collection, "Adobe-Japan2"))
  1091. fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-Japan2-UCS2");
  1092. else if (!strcmp(collection, "Adobe-Korea1"))
  1093. fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-Korea1-UCS2");
  1094. }
  1095. pdf_load_to_unicode(ctx, doc, fontdesc, NULL, collection, to_unicode);
  1096. /* If we have an identity encoding, we're supposed to use the glyph ids directly.
  1097. * If we only have a substitute font, that won't work.
  1098. * Make a last ditch attempt by using
  1099. * the ToUnicode table if it exists to map via the substitute font's cmap. */
  1100. if (strstr(fontdesc->encoding->cmap_name, "Identity-") && fontdesc->font->flags.ft_substitute)
  1101. {
  1102. if (!fontdesc->to_ttf_cmap)
  1103. {
  1104. if (fontdesc->to_unicode)
  1105. {
  1106. // Use ToUnicode from PDF file if possible.
  1107. fontdesc->to_ttf_cmap = pdf_keep_cmap(ctx, fontdesc->to_unicode);
  1108. }
  1109. else
  1110. {
  1111. // Attempt a generic ToUnicode (default MacRoman ordering for TrueType)
  1112. fontdesc->to_ttf_cmap = pdf_load_builtin_cmap(ctx, "TrueType-UCS2");
  1113. }
  1114. }
  1115. if (fontdesc->to_ttf_cmap)
  1116. {
  1117. fz_warn(ctx, "non-embedded font using identity encoding: %s (mapping via %s)", basefont, fontdesc->to_ttf_cmap->cmap_name);
  1118. if (!fontdesc->to_unicode)
  1119. fontdesc->to_unicode = pdf_keep_cmap(ctx, fontdesc->to_ttf_cmap);
  1120. }
  1121. else
  1122. fz_warn(ctx, "non-embedded font using identity encoding: %s", basefont);
  1123. }
  1124. /* Horizontal */
  1125. dw = pdf_dict_get_int_default(ctx, dict, PDF_NAME(DW), 1000);
  1126. pdf_set_default_hmtx(ctx, fontdesc, dw);
  1127. widths = pdf_dict_get(ctx, dict, PDF_NAME(W));
  1128. if (widths)
  1129. {
  1130. int c0, c1, w, n, m;
  1131. n = pdf_array_len(ctx, widths);
  1132. for (i = 0; i < n; )
  1133. {
  1134. c0 = pdf_array_get_int(ctx, widths, i);
  1135. obj = pdf_array_get(ctx, widths, i + 1);
  1136. if (pdf_is_array(ctx, obj))
  1137. {
  1138. m = pdf_array_len(ctx, obj);
  1139. for (k = 0; k < m; k++)
  1140. {
  1141. w = pdf_array_get_int(ctx, obj, k);
  1142. pdf_add_hmtx(ctx, fontdesc, c0 + k, c0 + k, w);
  1143. }
  1144. i += 2;
  1145. }
  1146. else
  1147. {
  1148. c1 = pdf_to_int(ctx, obj);
  1149. w = pdf_array_get_int(ctx, widths, i + 2);
  1150. pdf_add_hmtx(ctx, fontdesc, c0, c1, w);
  1151. i += 3;
  1152. }
  1153. }
  1154. }
  1155. pdf_end_hmtx(ctx, fontdesc);
  1156. /* Vertical */
  1157. if (pdf_cmap_wmode(ctx, fontdesc->encoding) == 1)
  1158. {
  1159. int dw2y = 880;
  1160. int dw2w = -1000;
  1161. obj = pdf_dict_get(ctx, dict, PDF_NAME(DW2));
  1162. if (obj)
  1163. {
  1164. dw2y = pdf_array_get_int(ctx, obj, 0);
  1165. dw2w = pdf_array_get_int(ctx, obj, 1);
  1166. }
  1167. pdf_set_default_vmtx(ctx, fontdesc, dw2y, dw2w);
  1168. widths = pdf_dict_get(ctx, dict, PDF_NAME(W2));
  1169. if (widths)
  1170. {
  1171. int c0, c1, w, x, y, n;
  1172. n = pdf_array_len(ctx, widths);
  1173. for (i = 0; i < n; )
  1174. {
  1175. c0 = pdf_array_get_int(ctx, widths, i);
  1176. obj = pdf_array_get(ctx, widths, i + 1);
  1177. if (pdf_is_array(ctx, obj))
  1178. {
  1179. int m = pdf_array_len(ctx, obj);
  1180. for (k = 0; k * 3 < m; k ++)
  1181. {
  1182. w = pdf_array_get_int(ctx, obj, k * 3 + 0);
  1183. x = pdf_array_get_int(ctx, obj, k * 3 + 1);
  1184. y = pdf_array_get_int(ctx, obj, k * 3 + 2);
  1185. pdf_add_vmtx(ctx, fontdesc, c0 + k, c0 + k, x, y, w);
  1186. }
  1187. i += 2;
  1188. }
  1189. else
  1190. {
  1191. c1 = pdf_to_int(ctx, obj);
  1192. w = pdf_array_get_int(ctx, widths, i + 2);
  1193. x = pdf_array_get_int(ctx, widths, i + 3);
  1194. y = pdf_array_get_int(ctx, widths, i + 4);
  1195. pdf_add_vmtx(ctx, fontdesc, c0, c1, x, y, w);
  1196. i += 5;
  1197. }
  1198. }
  1199. }
  1200. pdf_end_vmtx(ctx, fontdesc);
  1201. }
  1202. }
  1203. fz_always(ctx)
  1204. fz_drop_buffer(ctx, buf);
  1205. fz_catch(ctx)
  1206. {
  1207. pdf_drop_font(ctx, fontdesc);
  1208. fz_rethrow(ctx);
  1209. }
  1210. return fontdesc;
  1211. }
  1212. static pdf_font_desc *
  1213. pdf_load_type0_font(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
  1214. {
  1215. pdf_obj *dfonts;
  1216. pdf_obj *dfont;
  1217. pdf_obj *subtype;
  1218. pdf_obj *encoding;
  1219. pdf_obj *to_unicode;
  1220. dfonts = pdf_dict_get(ctx, dict, PDF_NAME(DescendantFonts));
  1221. if (!dfonts)
  1222. fz_throw(ctx, FZ_ERROR_SYNTAX, "cid font is missing descendant fonts");
  1223. dfont = pdf_array_get(ctx, dfonts, 0);
  1224. subtype = pdf_dict_get(ctx, dfont, PDF_NAME(Subtype));
  1225. encoding = pdf_dict_get(ctx, dict, PDF_NAME(Encoding));
  1226. to_unicode = pdf_dict_get(ctx, dict, PDF_NAME(ToUnicode));
  1227. if (pdf_is_name(ctx, subtype) && pdf_name_eq(ctx, subtype, PDF_NAME(CIDFontType0)))
  1228. return load_cid_font(ctx, doc, dfont, encoding, to_unicode);
  1229. if (pdf_is_name(ctx, subtype) && pdf_name_eq(ctx, subtype, PDF_NAME(CIDFontType2)))
  1230. return load_cid_font(ctx, doc, dfont, encoding, to_unicode);
  1231. fz_throw(ctx, FZ_ERROR_SYNTAX, "unknown cid font type");
  1232. }
  1233. /*
  1234. * FontDescriptor
  1235. */
  1236. static void
  1237. pdf_load_font_descriptor(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontdesc, pdf_obj *dict,
  1238. const char *collection, const char *basefont, int iscidfont)
  1239. {
  1240. pdf_obj *obj1, *obj2, *obj3, *obj;
  1241. const char *fontname;
  1242. FT_Face face;
  1243. /* Prefer BaseFont; don't bother with FontName */
  1244. fontname = basefont;
  1245. fontdesc->flags = pdf_dict_get_int(ctx, dict, PDF_NAME(Flags));
  1246. fontdesc->italic_angle = pdf_dict_get_real(ctx, dict, PDF_NAME(ItalicAngle));
  1247. /* fontdesc->ascent and descent have already been set to sane defaults */
  1248. fontdesc->cap_height = pdf_dict_get_real(ctx, dict, PDF_NAME(CapHeight));
  1249. fontdesc->x_height = pdf_dict_get_real(ctx, dict, PDF_NAME(XHeight));
  1250. fontdesc->missing_width = pdf_dict_get_real(ctx, dict, PDF_NAME(MissingWidth));
  1251. obj1 = pdf_dict_get(ctx, dict, PDF_NAME(FontFile));
  1252. obj2 = pdf_dict_get(ctx, dict, PDF_NAME(FontFile2));
  1253. obj3 = pdf_dict_get(ctx, dict, PDF_NAME(FontFile3));
  1254. obj = obj1 ? obj1 : obj2 ? obj2 : obj3;
  1255. if (pdf_is_indirect(ctx, obj))
  1256. {
  1257. fz_try(ctx)
  1258. {
  1259. pdf_load_embedded_font(ctx, doc, fontdesc, fontname, obj);
  1260. }
  1261. fz_catch(ctx)
  1262. {
  1263. fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
  1264. fz_rethrow_if(ctx, FZ_ERROR_SYSTEM);
  1265. fz_report_error(ctx);
  1266. fz_warn(ctx, "ignored error when loading embedded font; attempting to load system font");
  1267. if (!iscidfont && fontname != pdf_clean_font_name(fontname))
  1268. pdf_load_builtin_font(ctx, fontdesc, fontname, 1);
  1269. else
  1270. pdf_load_system_font(ctx, fontdesc, fontname, collection);
  1271. }
  1272. }
  1273. else
  1274. {
  1275. if (!iscidfont && fontname != pdf_clean_font_name(fontname))
  1276. pdf_load_builtin_font(ctx, fontdesc, fontname, 1);
  1277. else
  1278. pdf_load_system_font(ctx, fontdesc, fontname, collection);
  1279. }
  1280. /* Check for DynaLab fonts that must use hinting */
  1281. face = fontdesc->font->ft_face;
  1282. if (ft_kind(ctx, face) == TRUETYPE)
  1283. {
  1284. /* FreeType's own 'tricky' font detection needs a bit of help */
  1285. if (is_dynalab(fontdesc->font->name))
  1286. face->face_flags |= FT_FACE_FLAG_TRICKY;
  1287. fontdesc->ascent = 1000.0f * face->ascender / face->units_per_EM;
  1288. fontdesc->descent = 1000.0f * face->descender / face->units_per_EM;
  1289. }
  1290. /* Prefer FontDescriptor Ascent/Descent values to embedded font's */
  1291. fontdesc->ascent = pdf_dict_get_real_default(ctx, dict, PDF_NAME(Ascent), fontdesc->ascent);
  1292. fontdesc->descent = pdf_dict_get_real_default(ctx, dict, PDF_NAME(Descent), fontdesc->descent);
  1293. /* Allow for naughty producers that give us a positive descent. */
  1294. if (fontdesc->descent > 0)
  1295. fontdesc->descent = -fontdesc->descent;
  1296. if (fontdesc->ascent <= 0 || fontdesc->ascent > FZ_MAX_TRUSTWORTHY_ASCENT * 1000 ||
  1297. fontdesc->descent < FZ_MAX_TRUSTWORTHY_DESCENT * 1000)
  1298. {
  1299. fz_warn(ctx, "bogus font ascent/descent values (%g / %g)", fontdesc->ascent, fontdesc->descent);
  1300. fontdesc->font->ascender = 0.8f;
  1301. fontdesc->font->descender = -0.2f;
  1302. fontdesc->font->ascdesc_src = FZ_ASCDESC_DEFAULT;
  1303. }
  1304. else
  1305. {
  1306. fontdesc->font->ascender = fontdesc->ascent / 1000.0f;
  1307. fontdesc->font->descender = fontdesc->descent / 1000.0f;
  1308. fontdesc->font->ascdesc_src = FZ_ASCDESC_FROM_FONT;
  1309. }
  1310. }
  1311. static void
  1312. pdf_make_width_table(fz_context *ctx, pdf_font_desc *fontdesc)
  1313. {
  1314. fz_font *font = fontdesc->font;
  1315. int i, k, n, cid, gid;
  1316. n = 0;
  1317. for (i = 0; i < fontdesc->hmtx_len; i++)
  1318. {
  1319. for (k = fontdesc->hmtx[i].lo; k <= fontdesc->hmtx[i].hi; k++)
  1320. {
  1321. cid = pdf_lookup_cmap(fontdesc->encoding, k);
  1322. gid = pdf_font_cid_to_gid(ctx, fontdesc, cid);
  1323. if (gid > n)
  1324. n = gid;
  1325. }
  1326. }
  1327. font->width_count = n + 1;
  1328. font->width_table = Memento_label(fz_malloc_array(ctx, font->width_count, short), "font_widths");
  1329. fontdesc->size += font->width_count * sizeof(short);
  1330. font->width_default = fontdesc->dhmtx.w;
  1331. for (i = 0; i < font->width_count; i++)
  1332. font->width_table[i] = -1;
  1333. for (i = 0; i < fontdesc->hmtx_len; i++)
  1334. {
  1335. for (k = fontdesc->hmtx[i].lo; k <= fontdesc->hmtx[i].hi; k++)
  1336. {
  1337. cid = pdf_lookup_cmap(fontdesc->encoding, k);
  1338. gid = pdf_font_cid_to_gid(ctx, fontdesc, cid);
  1339. if (gid >= 0 && gid < font->width_count)
  1340. font->width_table[gid] = fz_maxi(fontdesc->hmtx[i].w, font->width_table[gid]);
  1341. }
  1342. }
  1343. for (i = 0; i < font->width_count; i++)
  1344. if (font->width_table[i] == -1)
  1345. font->width_table[i] = font->width_default;
  1346. }
  1347. pdf_font_desc *
  1348. pdf_load_font(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *dict)
  1349. {
  1350. pdf_obj *subtype;
  1351. pdf_obj *dfonts;
  1352. pdf_obj *charprocs;
  1353. pdf_font_desc *fontdesc = NULL;
  1354. int type3 = 0;
  1355. if ((fontdesc = pdf_find_item(ctx, pdf_drop_font_imp, dict)) != NULL)
  1356. {
  1357. if (fontdesc->t3loading)
  1358. {
  1359. pdf_drop_font(ctx, fontdesc);
  1360. fz_throw(ctx, FZ_ERROR_SYNTAX, "recursive type3 font");
  1361. }
  1362. return fontdesc;
  1363. }
  1364. subtype = pdf_dict_get(ctx, dict, PDF_NAME(Subtype));
  1365. dfonts = pdf_dict_get(ctx, dict, PDF_NAME(DescendantFonts));
  1366. charprocs = pdf_dict_get(ctx, dict, PDF_NAME(CharProcs));
  1367. if (pdf_name_eq(ctx, subtype, PDF_NAME(Type0)))
  1368. fontdesc = pdf_load_type0_font(ctx, doc, dict);
  1369. else if (pdf_name_eq(ctx, subtype, PDF_NAME(Type1)))
  1370. fontdesc = pdf_load_simple_font(ctx, doc, dict);
  1371. else if (pdf_name_eq(ctx, subtype, PDF_NAME(MMType1)))
  1372. fontdesc = pdf_load_simple_font(ctx, doc, dict);
  1373. else if (pdf_name_eq(ctx, subtype, PDF_NAME(TrueType)))
  1374. fontdesc = pdf_load_simple_font(ctx, doc, dict);
  1375. else if (pdf_name_eq(ctx, subtype, PDF_NAME(Type3)))
  1376. {
  1377. fontdesc = pdf_load_type3_font(ctx, doc, rdb, dict);
  1378. type3 = 1;
  1379. }
  1380. else if (charprocs)
  1381. {
  1382. fz_warn(ctx, "unknown font format, guessing type3.");
  1383. fontdesc = pdf_load_type3_font(ctx, doc, rdb, dict);
  1384. type3 = 1;
  1385. }
  1386. else if (dfonts)
  1387. {
  1388. fz_warn(ctx, "unknown font format, guessing type0.");
  1389. fontdesc = pdf_load_type0_font(ctx, doc, dict);
  1390. }
  1391. else
  1392. {
  1393. fz_warn(ctx, "unknown font format, guessing type1 or truetype.");
  1394. fontdesc = pdf_load_simple_font(ctx, doc, dict);
  1395. }
  1396. fz_try(ctx)
  1397. {
  1398. /* Create glyph width table for stretching substitute fonts and text extraction. */
  1399. pdf_make_width_table(ctx, fontdesc);
  1400. pdf_store_item(ctx, dict, fontdesc, fontdesc->size);
  1401. /* Load CharProcs */
  1402. if (type3)
  1403. {
  1404. fontdesc->t3loading = 1;
  1405. fz_try(ctx)
  1406. pdf_load_type3_glyphs(ctx, doc, fontdesc);
  1407. fz_always(ctx)
  1408. fontdesc->t3loading = 0;
  1409. fz_catch(ctx)
  1410. {
  1411. pdf_remove_item(ctx, fontdesc->storable.drop, dict);
  1412. fz_rethrow(ctx);
  1413. }
  1414. }
  1415. }
  1416. fz_catch(ctx)
  1417. {
  1418. pdf_drop_font(ctx, fontdesc);
  1419. fz_rethrow(ctx);
  1420. }
  1421. return fontdesc;
  1422. }
  1423. void
  1424. pdf_print_font(fz_context *ctx, fz_output *out, pdf_font_desc *fontdesc)
  1425. {
  1426. int i;
  1427. fz_write_printf(ctx, out, "fontdesc {\n");
  1428. if (fontdesc->font->ft_face)
  1429. fz_write_printf(ctx, out, "\tfreetype font\n");
  1430. if (fontdesc->font->t3procs)
  1431. fz_write_printf(ctx, out, "\ttype3 font\n");
  1432. fz_write_printf(ctx, out, "\twmode %d\n", fontdesc->wmode);
  1433. fz_write_printf(ctx, out, "\tDW %d\n", fontdesc->dhmtx.w);
  1434. fz_write_printf(ctx, out, "\tW {\n");
  1435. for (i = 0; i < fontdesc->hmtx_len; i++)
  1436. fz_write_printf(ctx, out, "\t\t<%04x> <%04x> %d\n",
  1437. fontdesc->hmtx[i].lo, fontdesc->hmtx[i].hi, fontdesc->hmtx[i].w);
  1438. fz_write_printf(ctx, out, "\t}\n");
  1439. if (fontdesc->wmode)
  1440. {
  1441. fz_write_printf(ctx, out, "\tDW2 [%d %d]\n", fontdesc->dvmtx.y, fontdesc->dvmtx.w);
  1442. fz_write_printf(ctx, out, "\tW2 {\n");
  1443. for (i = 0; i < fontdesc->vmtx_len; i++)
  1444. fz_write_printf(ctx, out, "\t\t<%04x> <%04x> %d %d %d\n", fontdesc->vmtx[i].lo, fontdesc->vmtx[i].hi,
  1445. fontdesc->vmtx[i].x, fontdesc->vmtx[i].y, fontdesc->vmtx[i].w);
  1446. fz_write_printf(ctx, out, "\t}\n");
  1447. }
  1448. }