textspan_lut.c 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. /// @file
  2. /// @ingroup common_render
  3. #include <assert.h>
  4. #include <cgraph/gv_ctype.h>
  5. #include <common/render.h>
  6. #include <common/textspan_lut.h>
  7. #include <common/types.h>
  8. #include <common/utils.h>
  9. #include <ctype.h>
  10. #include <math.h>
  11. #include <stddef.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <util/agxbuf.h>
  15. // Currently we just store the width of every ASCII character, which seems to
  16. // produce good enough results. We could also store kerning metrics and line
  17. // heights for each font if we want to be more thorough.
  18. struct FontFamilyMetrics {
  19. // A case-insensitive NULL-terminated list of font family names which these
  20. // metrics correspond to. If multiple font families are listed, they should be
  21. // metrically equivalent.
  22. const char **font_name;
  23. // Widths are stored in (units_per_em * 1) pt. (that is how TrueType works
  24. // internally). A value of -1 indicates that the width for that character is
  25. // unknown.
  26. double units_per_em;
  27. short widths_regular[128];
  28. short widths_bold[128];
  29. short widths_italic[128];
  30. short widths_bold_italic[128];
  31. };
  32. static const struct FontFamilyMetrics all_font_metrics[] = {
  33. // Times_New_Roman.ttf (+ variants) from ttf-mscorefonts-installer.
  34. {
  35. (const char *[]){"times", "timesroman", "timesnewroman", "freeserif",
  36. "liberationserif", "nimbusroman", "texgyretermes",
  37. "tinos", "thorndale", NULL},
  38. 2048,
  39. {
  40. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  41. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  42. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 512,
  43. 682, 836, 1024, 1024, 1706, 1593, 369, 682, 682, 1024, 1155,
  44. 512, 682, 512, 569, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
  45. 1024, 1024, 1024, 569, 569, 1155, 1155, 1155, 909, 1886, 1479,
  46. 1366, 1366, 1479, 1251, 1139, 1479, 1479, 682, 797, 1479, 1251,
  47. 1821, 1479, 1479, 1139, 1479, 1366, 1139, 1251, 1479, 1479, 1933,
  48. 1479, 1479, 1251, 682, 569, 682, 961, 1024, 682, 909, 1024,
  49. 909, 1024, 909, 682, 1024, 1024, 569, 569, 1024, 569, 1593,
  50. 1024, 1024, 1024, 1024, 682, 797, 569, 1024, 1024, 1479, 1024,
  51. 1024, 909, 983, 410, 983, 1108, -1,
  52. },
  53. {
  54. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  55. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  56. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 512,
  57. 682, 1137, 1024, 1024, 2048, 1706, 569, 682, 682, 1024, 1167,
  58. 512, 682, 512, 569, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
  59. 1024, 1024, 1024, 682, 682, 1167, 1167, 1167, 1024, 1905, 1479,
  60. 1366, 1479, 1479, 1366, 1251, 1593, 1593, 797, 1024, 1593, 1366,
  61. 1933, 1479, 1593, 1251, 1593, 1479, 1139, 1366, 1479, 1479, 2048,
  62. 1479, 1479, 1366, 682, 569, 682, 1190, 1024, 682, 1024, 1139,
  63. 909, 1139, 909, 682, 1024, 1139, 569, 682, 1139, 569, 1706,
  64. 1139, 1024, 1139, 1139, 909, 797, 682, 1139, 1024, 1479, 1024,
  65. 1024, 909, 807, 451, 807, 1065, -1,
  66. },
  67. {
  68. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  69. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  70. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 512,
  71. 682, 860, 1024, 1024, 1706, 1593, 438, 682, 682, 1024, 1382,
  72. 512, 682, 512, 569, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
  73. 1024, 1024, 1024, 682, 682, 1382, 1382, 1382, 1024, 1884, 1251,
  74. 1251, 1366, 1479, 1251, 1251, 1479, 1479, 682, 909, 1366, 1139,
  75. 1706, 1366, 1479, 1251, 1479, 1251, 1024, 1139, 1479, 1251, 1706,
  76. 1251, 1139, 1139, 797, 569, 797, 864, 1024, 682, 1024, 1024,
  77. 909, 1024, 909, 569, 1024, 1024, 569, 569, 909, 569, 1479,
  78. 1024, 1024, 1024, 1024, 797, 797, 569, 1024, 909, 1366, 909,
  79. 909, 797, 819, 563, 819, 1108, -1,
  80. },
  81. {
  82. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  83. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  84. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 512,
  85. 797, 1137, 1024, 1024, 1706, 1593, 569, 682, 682, 1024, 1167,
  86. 512, 682, 512, 569, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
  87. 1024, 1024, 1024, 682, 682, 1167, 1167, 1167, 1024, 1704, 1366,
  88. 1366, 1366, 1479, 1366, 1366, 1479, 1593, 797, 1024, 1366, 1251,
  89. 1821, 1479, 1479, 1251, 1479, 1366, 1139, 1251, 1479, 1366, 1821,
  90. 1366, 1251, 1251, 682, 569, 682, 1167, 1024, 682, 1024, 1024,
  91. 909, 1024, 909, 682, 1024, 1139, 569, 569, 1024, 569, 1593,
  92. 1139, 1024, 1024, 1024, 797, 797, 569, 1139, 909, 1366, 1024,
  93. 909, 797, 713, 451, 713, 1167, -1,
  94. },
  95. },
  96. // Arial.ttf (+ variants) from ttf-mscorefonts-installer.
  97. {
  98. (const char *[]){"helvetica", "arial", "arialmt", "freesans",
  99. "liberationsans", "arimo", "albany", "nimbussans",
  100. "nimbussansa", "texgyreheros", "albany", "arimo",
  101. NULL},
  102. 2048,
  103. {
  104. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  105. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  106. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 569,
  107. 569, 727, 1139, 1139, 1821, 1366, 391, 682, 682, 797, 1196,
  108. 569, 682, 569, 569, 1139, 1139, 1139, 1139, 1139, 1139, 1139,
  109. 1139, 1139, 1139, 569, 569, 1196, 1196, 1196, 1139, 2079, 1366,
  110. 1366, 1479, 1479, 1366, 1251, 1593, 1479, 569, 1024, 1366, 1139,
  111. 1706, 1479, 1593, 1366, 1593, 1479, 1366, 1251, 1479, 1366, 1933,
  112. 1366, 1366, 1251, 569, 569, 569, 961, 1139, 682, 1139, 1139,
  113. 1024, 1139, 1139, 569, 1139, 1139, 455, 455, 1024, 455, 1706,
  114. 1139, 1139, 1139, 1139, 682, 1024, 569, 1139, 1024, 1479, 1024,
  115. 1024, 1024, 684, 532, 684, 1196, -1,
  116. },
  117. {
  118. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  119. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  120. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 569,
  121. 682, 971, 1139, 1139, 1821, 1479, 487, 682, 682, 797, 1196,
  122. 569, 682, 569, 569, 1139, 1139, 1139, 1139, 1139, 1139, 1139,
  123. 1139, 1139, 1139, 682, 682, 1196, 1196, 1196, 1251, 1997, 1479,
  124. 1479, 1479, 1479, 1366, 1251, 1593, 1479, 569, 1139, 1479, 1251,
  125. 1706, 1479, 1593, 1366, 1593, 1479, 1366, 1251, 1479, 1366, 1933,
  126. 1366, 1366, 1251, 682, 569, 682, 1196, 1139, 682, 1139, 1251,
  127. 1139, 1251, 1139, 682, 1251, 1251, 569, 569, 1139, 569, 1821,
  128. 1251, 1251, 1251, 1251, 797, 1139, 682, 1251, 1139, 1593, 1139,
  129. 1139, 1024, 797, 573, 797, 1196, -1,
  130. },
  131. {
  132. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  133. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  134. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 569,
  135. 569, 727, 1139, 1139, 1821, 1366, 391, 682, 682, 797, 1196,
  136. 569, 682, 569, 569, 1139, 1139, 1139, 1139, 1139, 1139, 1139,
  137. 1139, 1139, 1139, 569, 569, 1196, 1196, 1196, 1139, 2079, 1366,
  138. 1366, 1479, 1479, 1366, 1251, 1593, 1479, 569, 1024, 1366, 1139,
  139. 1706, 1479, 1593, 1366, 1593, 1479, 1366, 1251, 1479, 1366, 1933,
  140. 1366, 1366, 1251, 569, 569, 569, 961, 1139, 682, 1139, 1139,
  141. 1024, 1139, 1139, 569, 1139, 1139, 455, 455, 1024, 455, 1706,
  142. 1139, 1139, 1139, 1139, 682, 1024, 569, 1139, 1024, 1479, 1024,
  143. 1024, 1024, 684, 532, 684, 1196, -1,
  144. },
  145. {
  146. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  147. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  148. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 569,
  149. 682, 971, 1139, 1139, 1821, 1479, 487, 682, 682, 797, 1196,
  150. 569, 682, 569, 569, 1139, 1139, 1139, 1139, 1139, 1139, 1139,
  151. 1139, 1139, 1139, 682, 682, 1196, 1196, 1196, 1251, 1997, 1479,
  152. 1479, 1479, 1479, 1366, 1251, 1593, 1479, 569, 1139, 1479, 1251,
  153. 1706, 1479, 1593, 1366, 1593, 1479, 1366, 1251, 1479, 1366, 1933,
  154. 1366, 1366, 1251, 682, 569, 682, 1196, 1139, 682, 1139, 1251,
  155. 1139, 1251, 1139, 682, 1251, 1251, 569, 569, 1139, 569, 1821,
  156. 1251, 1251, 1251, 1251, 797, 1139, 682, 1251, 1139, 1593, 1139,
  157. 1139, 1024, 797, 573, 797, 1196, -1,
  158. },
  159. },
  160. // Courier_New.ttf (+ variants) from ttf-mscorefonts-installer.
  161. {
  162. (const char *[]){"cour", "courier", "couriernew", "nimbusmono",
  163. "texgyrecursor", "freemono", "liberationmono",
  164. "cousine", "cumberland", NULL},
  165. 2048,
  166. {
  167. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  168. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  169. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1229,
  170. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  171. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  172. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  173. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  174. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  175. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  176. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  177. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  178. 1229, 1229, 1229, 1229, 1229, 1229, -1,
  179. },
  180. {
  181. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  182. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  183. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1229,
  184. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  185. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  186. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  187. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  188. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  189. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  190. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  191. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  192. 1229, 1229, 1229, 1229, 1229, 1229, -1,
  193. },
  194. {
  195. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  196. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  197. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1229,
  198. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  199. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  200. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  201. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  202. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  203. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  204. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  205. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  206. 1229, 1229, 1229, 1229, 1229, 1229, -1,
  207. },
  208. {
  209. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  210. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  211. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1229,
  212. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  213. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  214. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  215. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  216. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  217. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  218. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  219. 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229,
  220. 1229, 1229, 1229, 1229, 1229, 1229, -1,
  221. },
  222. },
  223. // https://fonts.google.com/specimen/Nunito
  224. {
  225. (const char *[]){"Nunito", NULL},
  226. 1000,
  227. {
  228. 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  229. 258, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  230. -1, -1, -1, -1, -1, -1, 258, 228, 392, 600, 600, 930, 693,
  231. 221, 317, 317, 450, 600, 228, 424, 228, 283, 600, 600, 600, 600,
  232. 600, 600, 600, 600, 600, 600, 228, 228, 600, 600, 600, 443, 946,
  233. 729, 676, 673, 742, 583, 548, 726, 761, 257, 324, 625, 543, 855,
  234. 740, 767, 633, 767, 669, 615, 602, 728, 689, 1101, 650, 596, 589,
  235. 315, 283, 315, 600, 500, 500, 530, 583, 463, 583, 532, 333, 586,
  236. 568, 232, 236, 500, 296, 856, 568, 556, 583, 583, 358, 481, 350,
  237. 561, 515, 841, 525, 514, 463, 352, 265, 352, 600, -1,
  238. },
  239. {
  240. 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  241. 271, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  242. -1, -1, -1, -1, -1, -1, 271, 248, 448, 600, 600, 945, 726,
  243. 243, 358, 358, 453, 600, 248, 434, 248, 313, 600, 600, 600, 600,
  244. 600, 600, 600, 600, 600, 600, 248, 248, 600, 600, 600, 459, 950,
  245. 744, 688, 680, 762, 597, 562, 736, 773, 282, 354, 665, 562, 868,
  246. 748, 785, 652, 785, 686, 631, 621, 738, 713, 1113, 672, 618, 605,
  247. 354, 313, 354, 600, 500, 500, 547, 600, 472, 600, 542, 364, 604,
  248. 585, 255, 259, 536, 319, 877, 585, 576, 600, 600, 392, 488, 384,
  249. 579, 527, 853, 546, 526, 474, 391, 288, 391, 600, -1,
  250. },
  251. {
  252. 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  253. 258, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  254. -1, -1, -1, -1, -1, -1, 258, 228, 392, 600, 600, 930, 693,
  255. 221, 317, 317, 450, 600, 228, 424, 228, 283, 600, 600, 600, 600,
  256. 600, 600, 600, 600, 600, 600, 228, 228, 600, 600, 600, 443, 946,
  257. 729, 676, 673, 742, 583, 548, 726, 761, 257, 324, 625, 543, 856,
  258. 739, 767, 633, 767, 669, 615, 602, 728, 688, 1101, 650, 596, 589,
  259. 315, 283, 315, 600, 500, 500, 530, 583, 463, 583, 532, 333, 586,
  260. 568, 232, 236, 500, 296, 856, 568, 556, 583, 583, 358, 481, 350,
  261. 561, 515, 841, 525, 514, 463, 352, 265, 352, 600, -1,
  262. },
  263. {
  264. 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  265. 271, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  266. -1, -1, -1, -1, -1, -1, 271, 248, 448, 600, 600, 945, 726,
  267. 243, 358, 358, 453, 600, 248, 434, 248, 313, 600, 600, 600, 600,
  268. 600, 600, 600, 600, 600, 600, 248, 248, 600, 600, 600, 459, 950,
  269. 744, 688, 680, 762, 597, 562, 736, 773, 282, 354, 664, 562, 869,
  270. 747, 785, 652, 785, 686, 631, 621, 738, 713, 1113, 672, 618, 605,
  271. 354, 313, 354, 600, 500, 500, 547, 600, 472, 600, 542, 364, 604,
  272. 585, 255, 259, 536, 319, 877, 585, 576, 600, 600, 392, 488, 384,
  273. 579, 527, 853, 546, 526, 474, 391, 288, 391, 600, -1,
  274. },
  275. },
  276. // Based on DejaVuSans, DejaVuSans-Bold, DejaVuSans-Oblique and
  277. // DejaVuSans-BoldOblique (as opposed to italic)
  278. {
  279. (const char *[]){"dejavusans", NULL},
  280. 2048,
  281. {
  282. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  283. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  284. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 651,
  285. 821, 942, 1716, 1303, 1946, 1597, 563, 799, 799, 1024, 1716,
  286. 651, 739, 651, 690, 1303, 1303, 1303, 1303, 1303, 1303, 1303,
  287. 1303, 1303, 1303, 690, 690, 1716, 1716, 1716, 1087, 2048, 1401,
  288. 1405, 1430, 1577, 1294, 1178, 1587, 1540, 604, 604, 1343, 1141,
  289. 1767, 1532, 1612, 1235, 1612, 1423, 1300, 1251, 1499, 1401, 2025,
  290. 1403, 1251, 1403, 799, 690, 799, 1716, 1024, 1024, 1255, 1300,
  291. 1126, 1300, 1260, 721, 1300, 1298, 569, 569, 1186, 569, 1995,
  292. 1298, 1253, 1300, 1300, 842, 1067, 803, 1298, 1212, 1675, 1212,
  293. 1212, 1075, 1303, 690, 1303, 1716, -1,
  294. },
  295. {
  296. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  297. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  298. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 713,
  299. 934, 1067, 1716, 1425, 2052, 1786, 627, 936, 936, 1071, 1716,
  300. 778, 850, 778, 748, 1425, 1425, 1425, 1425, 1425, 1425, 1425,
  301. 1425, 1425, 1425, 819, 819, 1716, 1716, 1716, 1188, 2048, 1585,
  302. 1561, 1503, 1700, 1399, 1399, 1681, 1714, 762, 762, 1587, 1305,
  303. 2038, 1714, 1741, 1501, 1741, 1577, 1475, 1397, 1663, 1585, 2259,
  304. 1579, 1483, 1485, 936, 748, 936, 1716, 1024, 1024, 1382, 1466,
  305. 1214, 1466, 1389, 891, 1466, 1458, 702, 702, 1362, 702, 2134,
  306. 1458, 1407, 1466, 1466, 1010, 1219, 979, 1458, 1335, 1892, 1321,
  307. 1335, 1192, 1458, 748, 1458, 1716, -1,
  308. },
  309. {
  310. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  311. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  312. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 651,
  313. 821, 942, 1716, 1303, 1946, 1597, 563, 799, 799, 1024, 1716,
  314. 651, 739, 651, 690, 1303, 1303, 1303, 1303, 1303, 1303, 1303,
  315. 1303, 1303, 1303, 690, 690, 1716, 1716, 1716, 1087, 2048, 1401,
  316. 1405, 1430, 1577, 1294, 1178, 1587, 1540, 604, 604, 1343, 1141,
  317. 1767, 1532, 1612, 1235, 1612, 1423, 1300, 1251, 1499, 1401, 2025,
  318. 1403, 1251, 1403, 799, 690, 799, 1716, 1024, 1024, 1255, 1300,
  319. 1126, 1300, 1260, 721, 1300, 1298, 569, 569, 1186, 569, 1995,
  320. 1298, 1253, 1300, 1300, 842, 1067, 803, 1298, 1212, 1675, 1212,
  321. 1212, 1075, 1303, 690, 1303, 1716, -1,
  322. },
  323. {
  324. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  325. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  326. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 713,
  327. 934, 1067, 1425, 1425, 2052, 1786, 627, 936, 936, 1071, 1716,
  328. 778, 850, 778, 748, 1425, 1425, 1425, 1425, 1425, 1425, 1425,
  329. 1425, 1425, 1425, 819, 819, 1716, 1716, 1716, 1188, 2048, 1585,
  330. 1561, 1503, 1700, 1399, 1399, 1681, 1714, 762, 762, 1587, 1305,
  331. 2038, 1714, 1741, 1501, 1741, 1577, 1475, 1397, 1663, 1585, 2259,
  332. 1579, 1483, 1485, 936, 748, 936, 1716, 1024, 1024, 1382, 1466,
  333. 1214, 1466, 1389, 891, 1466, 1458, 702, 702, 1362, 702, 2134,
  334. 1458, 1407, 1466, 1466, 1010, 1219, 979, 1458, 1335, 1892, 1321,
  335. 1335, 1192, 1458, 748, 1458, 1716, -1,
  336. },
  337. },
  338. {
  339. (const char *[]){"consola", "consolas", NULL},
  340. 2048,
  341. {
  342. 1126, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  343. -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1,
  344. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1126,
  345. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  346. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  347. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  348. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  349. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  350. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  351. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  352. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  353. 1126, 1126, 1126, 1126, 1126, 1126, -1,
  354. },
  355. {
  356. 1126, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  357. -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1,
  358. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1126,
  359. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  360. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  361. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  362. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  363. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  364. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  365. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  366. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  367. 1126, 1126, 1126, 1126, 1126, 1126, -1,
  368. },
  369. {
  370. 1126, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  371. -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1,
  372. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1126,
  373. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  374. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  375. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  376. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  377. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  378. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  379. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  380. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  381. 1126, 1126, 1126, 1126, 1126, 1126, -1,
  382. },
  383. {
  384. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  385. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  386. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1126,
  387. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  388. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  389. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  390. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  391. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  392. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  393. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  394. 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
  395. 1126, 1126, 1126, 1126, 1126, 1126, -1,
  396. },
  397. },
  398. {
  399. (const char *[]){"Trebuchet MS", "Trebuchet", NULL},
  400. 2048,
  401. {
  402. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  403. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  404. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 617,
  405. 752, 665, 1074, 1074, 1229, 1446, 327, 752, 752, 752, 1074,
  406. 752, 752, 752, 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1074,
  407. 1074, 1074, 1074, 752, 752, 1074, 1074, 1074, 752, 1578, 1208,
  408. 1159, 1225, 1256, 1097, 1075, 1385, 1340, 570, 976, 1179, 1037,
  409. 1453, 1307, 1380, 1142, 1384, 1192, 985, 1189, 1328, 1203, 1745,
  410. 1140, 1168, 1127, 752, 728, 752, 1074, 1074, 1074, 1076, 1141,
  411. 1014, 1141, 1117, 757, 1028, 1119, 584, 751, 1033, 604, 1700,
  412. 1119, 1099, 1141, 1141, 796, 829, 812, 1119, 1003, 1524, 1026,
  413. 1010, 972, 752, 1074, 752, 1074, -1,
  414. },
  415. {
  416. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  417. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  418. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 617,
  419. 752, 751, 1200, 1200, 1401, 1446, 470, 752, 752, 885, 1200,
  420. 752, 752, 752, 799, 1200, 1200, 1200, 1200, 1200, 1200, 1200,
  421. 1200, 1200, 1200, 752, 752, 1200, 1200, 1200, 897, 1578, 1297,
  422. 1219, 1253, 1316, 1165, 1195, 1375, 1400, 570, 1091, 1264, 1132,
  423. 1526, 1367, 1440, 1202, 1452, 1251, 1047, 1253, 1388, 1273, 1810,
  424. 1230, 1256, 1147, 823, 728, 823, 1200, 1200, 1200, 1091, 1191,
  425. 1048, 1189, 1177, 757, 1028, 1214, 611, 751, 1122, 604, 1760,
  426. 1209, 1159, 1193, 1196, 875, 882, 812, 1210, 1080, 1605, 1131,
  427. 1093, 1082, 888, 1200, 888, 1200, -1,
  428. },
  429. {
  430. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  431. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  432. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 617,
  433. 752, 665, 1074, 985, 1229, 1446, 327, 752, 752, 752, 1074,
  434. 752, 752, 752, 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1074,
  435. 1074, 1074, 1074, 752, 752, 1074, 1074, 1074, 752, 1578, 1251,
  436. 1159, 1225, 1256, 1097, 1075, 1385, 1340, 570, 976, 1179, 1037,
  437. 1559, 1307, 1380, 1113, 1380, 1192, 985, 1189, 1328, 1203, 1745,
  438. 1140, 1168, 1127, 752, 728, 752, 1074, 1074, 1074, 1076, 1141,
  439. 942, 1141, 1100, 822, 1028, 1141, 628, 751, 1033, 656, 1700,
  440. 1119, 1099, 1141, 1141, 853, 829, 860, 1140, 1003, 1524, 1026,
  441. 1010, 972, 752, 1074, 752, 1074, -1,
  442. },
  443. {
  444. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  445. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  446. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 617,
  447. 752, 800, 1200, 1200, 1500, 1446, 617, 752, 752, 885, 1200,
  448. 752, 752, 752, 813, 1200, 1200, 1200, 1200, 1200, 1200, 1200,
  449. 1200, 1200, 1200, 752, 752, 1200, 1200, 1200, 813, 1578, 1257,
  450. 1208, 1255, 1295, 1215, 1199, 1385, 1389, 570, 1021, 1331, 1082,
  451. 1610, 1352, 1438, 1195, 1576, 1277, 1027, 1403, 1355, 1399, 1897,
  452. 1345, 1400, 1252, 994, 978, 994, 1200, 1200, 1200, 1214, 1215,
  453. 1009, 1215, 1130, 840, 1096, 1151, 669, 794, 1105, 655, 1700,
  454. 1151, 1167, 1226, 1226, 915, 940, 897, 1141, 1131, 1584, 1179,
  455. 1155, 1091, 994, 1200, 994, 1200, -1,
  456. },
  457. },
  458. {
  459. (const char *[]){"Verdana", NULL},
  460. 2048,
  461. {
  462. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  463. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  464. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 720,
  465. 806, 940, 1676, 1302, 2204, 1488, 550, 930, 930, 1302, 1676,
  466. 745, 930, 745, 930, 1302, 1302, 1302, 1302, 1302, 1302, 1302,
  467. 1302, 1302, 1302, 930, 930, 1676, 1676, 1676, 1117, 2048, 1400,
  468. 1404, 1430, 1578, 1295, 1177, 1588, 1539, 862, 931, 1419, 1140,
  469. 1726, 1532, 1612, 1235, 1612, 1424, 1400, 1262, 1499, 1400, 2025,
  470. 1403, 1260, 1403, 930, 930, 930, 1676, 1302, 1302, 1230, 1276,
  471. 1067, 1276, 1220, 720, 1276, 1296, 562, 705, 1212, 562, 1992,
  472. 1296, 1243, 1276, 1276, 874, 1067, 807, 1296, 1212, 1676, 1212,
  473. 1212, 1076, 1300, 930, 1300, 1676, -1,
  474. },
  475. {
  476. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  477. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  478. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 700,
  479. 824, 1203, 1776, 1456, 2605, 1766, 680, 1113, 1113, 1456, 1776,
  480. 740, 983, 740, 1412, 1456, 1456, 1456, 1456, 1456, 1456, 1456,
  481. 1456, 1456, 1456, 824, 824, 1776, 1776, 1776, 1263, 1974, 1590,
  482. 1560, 1482, 1700, 1399, 1332, 1661, 1715, 1118, 1137, 1579, 1305,
  483. 1941, 1734, 1741, 1501, 1741, 1602, 1455, 1396, 1663, 1564, 2311,
  484. 1564, 1509, 1417, 1113, 1412, 1113, 1776, 1456, 1456, 1368, 1432,
  485. 1205, 1432, 1360, 865, 1432, 1459, 700, 825, 1374, 700, 2167,
  486. 1459, 1406, 1432, 1432, 1018, 1215, 933, 1459, 1331, 2006, 1370,
  487. 1333, 1222, 1456, 1113, 1456, 1776, -1,
  488. },
  489. {
  490. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  491. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  492. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 720,
  493. 806, 940, 1676, 1302, 2204, 1488, 550, 930, 930, 1302, 1676,
  494. 745, 930, 745, 930, 1302, 1302, 1302, 1302, 1302, 1302, 1302,
  495. 1302, 1302, 1302, 930, 930, 1676, 1676, 1676, 1117, 2048, 1398,
  496. 1404, 1430, 1568, 1295, 1177, 1588, 1539, 862, 931, 1419, 1140,
  497. 1726, 1532, 1612, 1235, 1612, 1424, 1400, 1262, 1499, 1398, 2028,
  498. 1403, 1260, 1403, 930, 930, 930, 1676, 1302, 1302, 1230, 1276,
  499. 1067, 1276, 1220, 720, 1273, 1296, 562, 705, 1202, 562, 1993,
  500. 1296, 1243, 1276, 1276, 874, 1067, 807, 1296, 1210, 1676, 1212,
  501. 1210, 1076, 1300, 930, 1300, 1676, -1,
  502. },
  503. {
  504. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  505. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  506. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 700,
  507. 824, 1203, 1776, 1456, 2605, 1766, 680, 1113, 1113, 1456, 1776,
  508. 740, 983, 740, 1412, 1456, 1456, 1456, 1456, 1456, 1456, 1456,
  509. 1456, 1456, 1456, 824, 824, 1776, 1776, 1776, 1263, 1974, 1590,
  510. 1560, 1482, 1700, 1399, 1332, 1661, 1715, 1118, 1137, 1579, 1305,
  511. 1941, 1734, 1741, 1501, 1741, 1602, 1455, 1396, 1663, 1564, 2311,
  512. 1564, 1509, 1417, 1113, 1412, 1113, 1776, 1456, 1456, 1368, 1432,
  513. 1205, 1432, 1360, 865, 1432, 1459, 700, 825, 1374, 700, 2167,
  514. 1459, 1404, 1432, 1432, 1018, 1215, 933, 1459, 1329, 2006, 1370,
  515. 1333, 1222, 1456, 1113, 1456, 1776, -1,
  516. },
  517. },
  518. {
  519. (const char *[]){"OpenSans", NULL},
  520. 2048,
  521. {
  522. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  523. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  524. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 532,
  525. 547, 821, 1323, 1171, 1686, 1495, 453, 606, 606, 1130, 1171,
  526. 502, 659, 545, 752, 1171, 1171, 1171, 1171, 1171, 1171, 1171,
  527. 1171, 1171, 1171, 545, 545, 1171, 1171, 1171, 879, 1841, 1296,
  528. 1327, 1292, 1493, 1139, 1057, 1491, 1511, 571, 547, 1257, 1063,
  529. 1849, 1544, 1595, 1233, 1595, 1266, 1124, 1133, 1491, 1219, 1896,
  530. 1182, 1147, 1169, 674, 752, 674, 1110, 918, 1182, 1139, 1255,
  531. 975, 1255, 1149, 694, 1122, 1257, 518, 518, 1075, 518, 1905,
  532. 1257, 1237, 1255, 1255, 836, 977, 723, 1257, 1026, 1593, 1073,
  533. 1032, 958, 776, 1128, 776, 1171, -1,
  534. },
  535. {
  536. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  537. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  538. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 532,
  539. 586, 967, 1323, 1169, 1845, 1536, 545, 694, 694, 1116, 1169,
  540. 594, 659, 584, 846, 1169, 1169, 1169, 1169, 1169, 1169, 1169,
  541. 1169, 1169, 1169, 584, 594, 1169, 1169, 1169, 977, 1837, 1413,
  542. 1376, 1305, 1516, 1147, 1124, 1483, 1567, 678, 678, 1360, 1157,
  543. 1931, 1665, 1630, 1286, 1630, 1352, 1128, 1186, 1548, 1331, 1980,
  544. 1366, 1278, 1186, 678, 846, 678, 1090, 842, 1243, 1237, 1296,
  545. 1053, 1296, 1210, 793, 1157, 1346, 625, 625, 1270, 625, 2011,
  546. 1346, 1268, 1296, 1296, 930, 1018, 889, 1346, 1165, 1753, 1184,
  547. 1165, 999, 807, 1128, 807, 1169, -1,
  548. },
  549. {
  550. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  551. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  552. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 532,
  553. 530, 791, 1323, 1128, 1624, 1372, 444, 584, 584, 1130, 1128,
  554. 492, 639, 518, 717, 1128, 1128, 1128, 1128, 1128, 1128, 1128,
  555. 1128, 1128, 1128, 518, 518, 1128, 1128, 1128, 874, 1735, 1137,
  556. 1225, 1198, 1364, 1047, 967, 1386, 1389, 559, 547, 1141, 971,
  557. 1714, 1438, 1475, 1159, 1475, 1165, 1028, 1020, 1384, 1122, 1745,
  558. 1063, 1030, 1087, 586, 717, 586, 1059, 807, 1135, 1157, 1182,
  559. 922, 1182, 1010, 641, 1026, 1182, 520, 520, 999, 520, 1786,
  560. 1182, 1149, 1182, 1182, 811, 877, 664, 1182, 946, 1468, 979,
  561. 946, 909, 715, 1128, 715, 1128, -1,
  562. },
  563. {
  564. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  565. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  566. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 532,
  567. 586, 928, 1323, 1128, 1753, 1450, 522, 694, 694, 1116, 1128,
  568. 569, 659, 584, 862, 1128, 1128, 1128, 1128, 1128, 1128, 1128,
  569. 1128, 1128, 1128, 584, 584, 1128, 1128, 1128, 940, 1753, 1286,
  570. 1270, 1253, 1386, 1110, 1087, 1413, 1434, 659, 678, 1255, 1061,
  571. 1802, 1546, 1495, 1188, 1495, 1247, 1085, 1087, 1415, 1208, 1831,
  572. 1241, 1155, 1098, 678, 862, 678, 1081, 819, 1135, 1217, 1219,
  573. 989, 1217, 1141, 764, 1108, 1237, 608, 608, 1163, 608, 1853,
  574. 1237, 1198, 1219, 1217, 862, 969, 840, 1237, 1049, 1614, 1087,
  575. 1063, 932, 727, 1128, 727, 1128, -1,
  576. },
  577. },
  578. {
  579. (const char *[]){"Georgia", NULL},
  580. 2048,
  581. {
  582. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  583. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  584. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 494,
  585. 678, 843, 1317, 1249, 1674, 1455, 441, 768, 768, 967, 1317,
  586. 552, 766, 552, 960, 1257, 880, 1144, 1130, 1157, 1082, 1159,
  587. 1029, 1221, 1159, 640, 640, 1317, 1317, 1317, 980, 1902, 1374,
  588. 1339, 1315, 1534, 1338, 1227, 1485, 1669, 798, 1060, 1422, 1236,
  589. 1899, 1571, 1524, 1249, 1524, 1437, 1149, 1267, 1549, 1365, 1998,
  590. 1455, 1260, 1232, 768, 960, 768, 1317, 1317, 1024, 1032, 1147,
  591. 930, 1176, 990, 666, 1043, 1192, 600, 598, 1097, 586, 1804,
  592. 1210, 1104, 1170, 1146, 839, 885, 707, 1178, 1017, 1510, 1034,
  593. 1008, 909, 881, 768, 881, 1317, -1,
  594. },
  595. {
  596. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  597. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  598. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 520,
  599. 771, 1044, 1440, 1312, 1801, 1637, 551, 915, 915, 987, 1440,
  600. 672, 776, 672, 966, 1436, 1003, 1283, 1279, 1330, 1227, 1327,
  601. 1135, 1385, 1327, 752, 752, 1440, 1440, 1440, 1123, 1980, 1553,
  602. 1551, 1465, 1708, 1477, 1375, 1653, 1870, 913, 1219, 1673, 1404,
  603. 2096, 1719, 1679, 1436, 1679, 1633, 1329, 1401, 1707, 1561, 2307,
  604. 1656, 1499, 1412, 915, 966, 915, 1440, 1440, 1024, 1220, 1322,
  605. 1088, 1358, 1171, 805, 1181, 1392, 724, 709, 1294, 705, 2080,
  606. 1413, 1302, 1347, 1328, 1065, 1050, 814, 1386, 1161, 1768, 1204,
  607. 1151, 1076, 1024, 794, 1024, 1440, -1,
  608. },
  609. {
  610. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  611. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  612. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 494,
  613. 678, 843, 1317, 1249, 1674, 1455, 441, 768, 768, 967, 1317,
  614. 552, 766, 552, 960, 1257, 880, 1144, 1130, 1157, 1082, 1159,
  615. 1017, 1221, 1159, 786, 786, 1317, 1317, 1317, 980, 1902, 1374,
  616. 1339, 1315, 1534, 1338, 1227, 1485, 1669, 798, 1060, 1422, 1236,
  617. 1899, 1571, 1496, 1249, 1496, 1437, 1149, 1267, 1549, 1365, 1998,
  618. 1455, 1260, 1232, 768, 960, 768, 1317, 1317, 1024, 1173, 1134,
  619. 929, 1178, 966, 673, 1173, 1152, 609, 596, 1081, 584, 1801,
  620. 1208, 1100, 1184, 1137, 945, 883, 711, 1178, 1102, 1684, 1026,
  621. 1146, 909, 881, 768, 881, 1317, -1,
  622. },
  623. {
  624. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  625. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  626. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 520,
  627. 771, 1044, 1440, 1312, 1801, 1637, 551, 915, 915, 987, 1440,
  628. 672, 776, 672, 966, 1436, 1003, 1283, 1279, 1330, 1227, 1327,
  629. 1160, 1385, 1327, 752, 752, 1440, 1440, 1440, 1123, 1980, 1553,
  630. 1555, 1465, 1708, 1477, 1375, 1653, 1870, 923, 1219, 1673, 1404,
  631. 2116, 1699, 1679, 1446, 1679, 1633, 1337, 1401, 1707, 1561, 2307,
  632. 1643, 1499, 1412, 915, 966, 915, 1440, 1440, 1024, 1352, 1329,
  633. 1097, 1357, 1141, 780, 1330, 1383, 749, 747, 1313, 726, 2052,
  634. 1413, 1302, 1357, 1331, 1093, 1059, 854, 1403, 1254, 1912, 1195,
  635. 1371, 1059, 1024, 794, 1024, 1440, -1,
  636. },
  637. },
  638. {
  639. (const char *[]){"Calibri", NULL},
  640. 2048,
  641. {
  642. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  643. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  644. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 463,
  645. 667, 821, 1020, 1038, 1464, 1397, 452, 621, 621, 1020, 1020,
  646. 511, 627, 517, 791, 1038, 1038, 1038, 1038, 1038, 1038, 1038,
  647. 1038, 1038, 1038, 548, 548, 1020, 1020, 1020, 949, 1831, 1185,
  648. 1114, 1092, 1260, 1000, 941, 1292, 1276, 516, 653, 1064, 861,
  649. 1751, 1322, 1356, 1058, 1378, 1112, 941, 998, 1314, 1162, 1822,
  650. 1063, 998, 959, 628, 791, 628, 1020, 1020, 596, 981, 1076,
  651. 866, 1076, 1019, 625, 964, 1076, 470, 490, 931, 470, 1636,
  652. 1076, 1080, 1076, 1076, 714, 801, 686, 1076, 925, 1464, 887,
  653. 927, 809, 644, 943, 644, 1020, -1,
  654. },
  655. {
  656. 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  657. -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1,
  658. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 463,
  659. 667, 898, 1020, 1038, 1493, 1443, 478, 638, 638, 1020, 1020,
  660. 528, 627, 547, 880, 1038, 1038, 1038, 1038, 1038, 1038, 1038,
  661. 1038, 1038, 1038, 565, 565, 1020, 1020, 1020, 949, 1840, 1241,
  662. 1148, 1084, 1291, 999, 940, 1305, 1292, 546, 678, 1120, 866,
  663. 1790, 1349, 1385, 1090, 1405, 1153, 968, 1014, 1337, 1211, 1856,
  664. 1128, 1064, 979, 665, 880, 665, 1020, 1020, 615, 1011, 1099,
  665. 857, 1099, 1031, 648, 971, 1099, 503, 523, 983, 503, 1666,
  666. 1099, 1101, 1099, 1099, 728, 817, 710, 1099, 969, 1526, 941,
  667. 970, 814, 704, 973, 704, 1020, -1,
  668. },
  669. {
  670. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  671. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  672. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 463,
  673. 667, 821, 1020, 1038, 1464, 1397, 452, 621, 621, 1020, 1020,
  674. 511, 627, 517, 794, 1038, 1038, 1038, 1038, 1038, 1038, 1038,
  675. 1038, 1038, 1038, 548, 548, 1020, 1020, 1020, 949, 1831, 1185,
  676. 1114, 1070, 1260, 1000, 941, 1292, 1276, 516, 653, 1064, 861,
  677. 1751, 1320, 1340, 1058, 1360, 1112, 926, 998, 1314, 1162, 1823,
  678. 1063, 998, 959, 628, 787, 628, 1020, 1020, 596, 1053, 1053,
  679. 852, 1053, 978, 625, 1053, 1053, 470, 490, 931, 470, 1620,
  680. 1053, 1051, 1053, 1053, 702, 797, 686, 1053, 913, 1464, 887,
  681. 916, 809, 644, 943, 644, 1020, -1,
  682. },
  683. {
  684. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  685. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  686. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 463,
  687. 667, 898, 1020, 1038, 1493, 1443, 478, 638, 638, 1020, 1020,
  688. 528, 627, 547, 889, 1038, 1038, 1038, 1038, 1038, 1038, 1038,
  689. 1038, 1038, 1038, 565, 565, 1020, 1020, 1020, 949, 1840, 1241,
  690. 1148, 1062, 1291, 999, 940, 1305, 1292, 546, 678, 1120, 866,
  691. 1790, 1344, 1369, 1090, 1387, 1153, 953, 1014, 1337, 1211, 1857,
  692. 1128, 1064, 979, 665, 870, 665, 1020, 1020, 615, 1081, 1081,
  693. 843, 1081, 1006, 648, 1081, 1080, 503, 523, 983, 503, 1646,
  694. 1080, 1080, 1081, 1081, 721, 807, 710, 1080, 961, 1526, 941,
  695. 963, 814, 704, 973, 704, 1020, -1,
  696. },
  697. },
  698. };
  699. static const size_t all_font_metrics_len =
  700. sizeof(all_font_metrics) / sizeof(all_font_metrics[0]);
  701. /// Compares two font names for equality, ignoring case and all characters
  702. /// except ASCII letters
  703. ///
  704. /// E.g. "timesroman", "Times-Roman", "times ROMAN", "times_roman" and
  705. /// "tim8esroman" are all considered equal to each other, but not equal to
  706. /// "Times New Roman".
  707. static bool font_name_equal_permissive(const char *a, const char *b) {
  708. size_t b_length = strlen(b);
  709. size_t a_length = strlen(a);
  710. size_t a_pos = 0;
  711. size_t b_pos = 0;
  712. while (a_pos != a_length && b_pos != b_length) {
  713. if (!gv_isalpha(a[a_pos])) {
  714. ++a_pos;
  715. continue;
  716. }
  717. if (!gv_isalpha(b[b_pos])) {
  718. ++b_pos;
  719. continue;
  720. }
  721. if (tolower(a[a_pos]) != tolower(b[b_pos])) {
  722. return false;
  723. }
  724. ++a_pos;
  725. ++b_pos;
  726. }
  727. while (a_pos != a_length) {
  728. if (gv_isalpha(a[a_pos])) {
  729. return false;
  730. }
  731. ++a_pos;
  732. }
  733. while (b_pos != b_length) {
  734. if (gv_isalpha(b[b_pos])) {
  735. return false;
  736. }
  737. ++b_pos;
  738. }
  739. return true;
  740. }
  741. /// Checks whether a font name is in a list of font names, ignoring case and
  742. /// special characters.
  743. ///
  744. /// E.g. "Times-Roman" and "TimesNewRoman" are both in
  745. /// {"times", "timesroman", "timesnewroman", NULL}, but "Arial" is not.
  746. static bool font_in_list_permissive(const char *value, const char **list) {
  747. assert(value && strlen(value));
  748. assert(list && list[0] != NULL);
  749. for (size_t i = 0; list[i] != NULL; ++i) {
  750. if (font_name_equal_permissive(value, list[i])) {
  751. return true;
  752. }
  753. }
  754. return false;
  755. }
  756. static const struct FontFamilyMetrics *
  757. get_metrics_for_font_family(const char *font_name) {
  758. for (size_t i = 0; i < all_font_metrics_len; i++) {
  759. if (font_in_list_permissive(font_name, all_font_metrics[i].font_name)) {
  760. return &all_font_metrics[i];
  761. }
  762. }
  763. agxbuf warning = {0};
  764. agxbprint(&warning,
  765. "Warning: no hard-coded metrics for '%s'. Falling back to 'Times' "
  766. "metrics\n",
  767. font_name);
  768. char *warning_text = agxbuse(&warning);
  769. if (emit_once(warning_text)) {
  770. agwarningf("%s", warning_text);
  771. }
  772. agxbfree(&warning);
  773. return get_metrics_for_font_family("Times");
  774. }
  775. static const short *
  776. get_metrics_for_font_variant(const struct FontFamilyMetrics *family_metrics,
  777. bool bold, bool italic) {
  778. if (bold && italic) {
  779. return family_metrics->widths_bold_italic;
  780. }
  781. if (bold) {
  782. return family_metrics->widths_bold;
  783. }
  784. if (italic) {
  785. return family_metrics->widths_italic;
  786. }
  787. return family_metrics->widths_regular;
  788. }
  789. /// @returns the width of the character in (units_per_em * 1) points.
  790. static unsigned short
  791. estimate_character_width_canonical(const short variant_metrics[128],
  792. unsigned character) {
  793. if (character >= 128) {
  794. static bool warning_already_reported = false;
  795. if (!warning_already_reported) { // stderr spam prevention
  796. warning_already_reported = true;
  797. agwarningf(
  798. "Warning: no value for width of non-ASCII character %u. Falling "
  799. "back to width of space character\n",
  800. character);
  801. }
  802. character = ' ';
  803. }
  804. short width = variant_metrics[character];
  805. if (width == -1) {
  806. static bool warning_already_reported = false;
  807. if (!warning_already_reported) { // stderr spam prevention
  808. warning_already_reported = true;
  809. agwarningf(
  810. "Warning: no value for width of ASCII character %u. Falling back "
  811. "to 0\n",
  812. character);
  813. }
  814. width = 0;
  815. }
  816. assert(width >= 0);
  817. return (unsigned short)width;
  818. }
  819. double estimate_text_width_1pt(const char *font_name, const char *text,
  820. bool bold, bool italic) {
  821. assert(font_name);
  822. assert(text);
  823. const struct FontFamilyMetrics *family_metrics =
  824. get_metrics_for_font_family(font_name);
  825. const short *variant_metrics =
  826. get_metrics_for_font_variant(family_metrics, bold, italic);
  827. unsigned text_width_canonical = 0;
  828. for (const char *c = text; *c != '\0'; c++) {
  829. text_width_canonical +=
  830. estimate_character_width_canonical(variant_metrics, (unsigned char)*c);
  831. }
  832. return (double)text_width_canonical / family_metrics->units_per_em;
  833. }