xfa_fonts.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /* Copyright 2021 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. import {
  16. CalibriBoldFactors,
  17. CalibriBoldItalicFactors,
  18. CalibriBoldItalicMetrics,
  19. CalibriBoldMetrics,
  20. CalibriItalicFactors,
  21. CalibriItalicMetrics,
  22. CalibriRegularFactors,
  23. CalibriRegularMetrics,
  24. } from "./calibri_factors.js";
  25. import { Dict, Name } from "./primitives.js";
  26. import {
  27. HelveticaBoldFactors,
  28. HelveticaBoldItalicFactors,
  29. HelveticaBoldItalicMetrics,
  30. HelveticaBoldMetrics,
  31. HelveticaItalicFactors,
  32. HelveticaItalicMetrics,
  33. HelveticaRegularFactors,
  34. HelveticaRegularMetrics,
  35. } from "./helvetica_factors.js";
  36. import {
  37. LiberationSansBoldItalicMapping,
  38. LiberationSansBoldItalicWidths,
  39. LiberationSansBoldMapping,
  40. LiberationSansBoldWidths,
  41. LiberationSansItalicMapping,
  42. LiberationSansItalicWidths,
  43. LiberationSansRegularMapping,
  44. LiberationSansRegularWidths,
  45. } from "./liberationsans_widths.js";
  46. import {
  47. MyriadProBoldFactors,
  48. MyriadProBoldItalicFactors,
  49. MyriadProBoldItalicMetrics,
  50. MyriadProBoldMetrics,
  51. MyriadProItalicFactors,
  52. MyriadProItalicMetrics,
  53. MyriadProRegularFactors,
  54. MyriadProRegularMetrics,
  55. } from "./myriadpro_factors.js";
  56. import {
  57. SegoeuiBoldFactors,
  58. SegoeuiBoldItalicFactors,
  59. SegoeuiBoldItalicMetrics,
  60. SegoeuiBoldMetrics,
  61. SegoeuiItalicFactors,
  62. SegoeuiItalicMetrics,
  63. SegoeuiRegularFactors,
  64. SegoeuiRegularMetrics,
  65. } from "./segoeui_factors.js";
  66. import { getLookupTableFactory } from "./core_utils.js";
  67. import { normalizeFontName } from "./fonts_utils.js";
  68. const getXFAFontMap = getLookupTableFactory(function (t) {
  69. t["MyriadPro-Regular"] = t["PdfJS-Fallback-Regular"] = {
  70. name: "LiberationSans-Regular",
  71. factors: MyriadProRegularFactors,
  72. baseWidths: LiberationSansRegularWidths,
  73. baseMapping: LiberationSansRegularMapping,
  74. metrics: MyriadProRegularMetrics,
  75. };
  76. t["MyriadPro-Bold"] = t["PdfJS-Fallback-Bold"] = {
  77. name: "LiberationSans-Bold",
  78. factors: MyriadProBoldFactors,
  79. baseWidths: LiberationSansBoldWidths,
  80. baseMapping: LiberationSansBoldMapping,
  81. metrics: MyriadProBoldMetrics,
  82. };
  83. t["MyriadPro-It"] =
  84. t["MyriadPro-Italic"] =
  85. t["PdfJS-Fallback-Italic"] =
  86. {
  87. name: "LiberationSans-Italic",
  88. factors: MyriadProItalicFactors,
  89. baseWidths: LiberationSansItalicWidths,
  90. baseMapping: LiberationSansItalicMapping,
  91. metrics: MyriadProItalicMetrics,
  92. };
  93. t["MyriadPro-BoldIt"] =
  94. t["MyriadPro-BoldItalic"] =
  95. t["PdfJS-Fallback-BoldItalic"] =
  96. {
  97. name: "LiberationSans-BoldItalic",
  98. factors: MyriadProBoldItalicFactors,
  99. baseWidths: LiberationSansBoldItalicWidths,
  100. baseMapping: LiberationSansBoldItalicMapping,
  101. metrics: MyriadProBoldItalicMetrics,
  102. };
  103. t.ArialMT =
  104. t.Arial =
  105. t["Arial-Regular"] =
  106. {
  107. name: "LiberationSans-Regular",
  108. baseWidths: LiberationSansRegularWidths,
  109. baseMapping: LiberationSansRegularMapping,
  110. };
  111. t["Arial-BoldMT"] = t["Arial-Bold"] = {
  112. name: "LiberationSans-Bold",
  113. baseWidths: LiberationSansBoldWidths,
  114. baseMapping: LiberationSansBoldMapping,
  115. };
  116. t["Arial-ItalicMT"] = t["Arial-Italic"] = {
  117. name: "LiberationSans-Italic",
  118. baseWidths: LiberationSansItalicWidths,
  119. baseMapping: LiberationSansItalicMapping,
  120. };
  121. t["Arial-BoldItalicMT"] = t["Arial-BoldItalic"] = {
  122. name: "LiberationSans-BoldItalic",
  123. baseWidths: LiberationSansBoldItalicWidths,
  124. baseMapping: LiberationSansBoldItalicMapping,
  125. };
  126. t["Calibri-Regular"] = {
  127. name: "LiberationSans-Regular",
  128. factors: CalibriRegularFactors,
  129. baseWidths: LiberationSansRegularWidths,
  130. baseMapping: LiberationSansRegularMapping,
  131. metrics: CalibriRegularMetrics,
  132. };
  133. t["Calibri-Bold"] = {
  134. name: "LiberationSans-Bold",
  135. factors: CalibriBoldFactors,
  136. baseWidths: LiberationSansBoldWidths,
  137. baseMapping: LiberationSansBoldMapping,
  138. metrics: CalibriBoldMetrics,
  139. };
  140. t["Calibri-Italic"] = {
  141. name: "LiberationSans-Italic",
  142. factors: CalibriItalicFactors,
  143. baseWidths: LiberationSansItalicWidths,
  144. baseMapping: LiberationSansItalicMapping,
  145. metrics: CalibriItalicMetrics,
  146. };
  147. t["Calibri-BoldItalic"] = {
  148. name: "LiberationSans-BoldItalic",
  149. factors: CalibriBoldItalicFactors,
  150. baseWidths: LiberationSansBoldItalicWidths,
  151. baseMapping: LiberationSansBoldItalicMapping,
  152. metrics: CalibriBoldItalicMetrics,
  153. };
  154. t["Segoeui-Regular"] = {
  155. name: "LiberationSans-Regular",
  156. factors: SegoeuiRegularFactors,
  157. baseWidths: LiberationSansRegularWidths,
  158. baseMapping: LiberationSansRegularMapping,
  159. metrics: SegoeuiRegularMetrics,
  160. };
  161. t["Segoeui-Bold"] = {
  162. name: "LiberationSans-Bold",
  163. factors: SegoeuiBoldFactors,
  164. baseWidths: LiberationSansBoldWidths,
  165. baseMapping: LiberationSansBoldMapping,
  166. metrics: SegoeuiBoldMetrics,
  167. };
  168. t["Segoeui-Italic"] = {
  169. name: "LiberationSans-Italic",
  170. factors: SegoeuiItalicFactors,
  171. baseWidths: LiberationSansItalicWidths,
  172. baseMapping: LiberationSansItalicMapping,
  173. metrics: SegoeuiItalicMetrics,
  174. };
  175. t["Segoeui-BoldItalic"] = {
  176. name: "LiberationSans-BoldItalic",
  177. factors: SegoeuiBoldItalicFactors,
  178. baseWidths: LiberationSansBoldItalicWidths,
  179. baseMapping: LiberationSansBoldItalicMapping,
  180. metrics: SegoeuiBoldItalicMetrics,
  181. };
  182. t["Helvetica-Regular"] = t.Helvetica = {
  183. name: "LiberationSans-Regular",
  184. factors: HelveticaRegularFactors,
  185. baseWidths: LiberationSansRegularWidths,
  186. baseMapping: LiberationSansRegularMapping,
  187. metrics: HelveticaRegularMetrics,
  188. };
  189. t["Helvetica-Bold"] = {
  190. name: "LiberationSans-Bold",
  191. factors: HelveticaBoldFactors,
  192. baseWidths: LiberationSansBoldWidths,
  193. baseMapping: LiberationSansBoldMapping,
  194. metrics: HelveticaBoldMetrics,
  195. };
  196. t["Helvetica-Italic"] = {
  197. name: "LiberationSans-Italic",
  198. factors: HelveticaItalicFactors,
  199. baseWidths: LiberationSansItalicWidths,
  200. baseMapping: LiberationSansItalicMapping,
  201. metrics: HelveticaItalicMetrics,
  202. };
  203. t["Helvetica-BoldItalic"] = {
  204. name: "LiberationSans-BoldItalic",
  205. factors: HelveticaBoldItalicFactors,
  206. baseWidths: LiberationSansBoldItalicWidths,
  207. baseMapping: LiberationSansBoldItalicMapping,
  208. metrics: HelveticaBoldItalicMetrics,
  209. };
  210. });
  211. function getXfaFontName(name) {
  212. const fontName = normalizeFontName(name);
  213. const fontMap = getXFAFontMap();
  214. return fontMap[fontName];
  215. }
  216. function getXfaFontWidths(name) {
  217. const info = getXfaFontName(name);
  218. if (!info) {
  219. return null;
  220. }
  221. const { baseWidths, baseMapping, factors } = info;
  222. let rescaledBaseWidths;
  223. if (!factors) {
  224. rescaledBaseWidths = baseWidths;
  225. } else {
  226. rescaledBaseWidths = baseWidths.map((w, i) => w * factors[i]);
  227. }
  228. let currentCode = -2;
  229. let currentArray;
  230. // Widths array for composite font is:
  231. // CharCode1 [10, 20, 30] ...
  232. // which means:
  233. // - CharCode1 has a width equal to 10
  234. // - CharCode1+1 has a width equal to 20
  235. // - CharCode1+2 has a width equal to 30
  236. //
  237. // The baseMapping array contains a map for glyph index to unicode.
  238. // So from baseMapping we'll get sorted unicodes and their positions
  239. // (i.e. glyph indices) and then we put widths in an array for the
  240. // the consecutive unicodes.
  241. const newWidths = [];
  242. for (const [unicode, glyphIndex] of baseMapping
  243. .map(
  244. (charUnicode, index) => [
  245. charUnicode,
  246. index,
  247. ] /* collect unicode and glyph index */
  248. )
  249. .sort(
  250. ([unicode1], [unicode2]) =>
  251. unicode1 - unicode2 /* order by unicode only */
  252. )) {
  253. if (unicode === -1) {
  254. continue;
  255. }
  256. if (unicode === currentCode + 1) {
  257. currentArray.push(rescaledBaseWidths[glyphIndex]);
  258. currentCode += 1;
  259. } else {
  260. currentCode = unicode;
  261. currentArray = [rescaledBaseWidths[glyphIndex]];
  262. newWidths.push(unicode, currentArray);
  263. }
  264. }
  265. return newWidths;
  266. }
  267. function getXfaFontDict(name) {
  268. const widths = getXfaFontWidths(name);
  269. const dict = new Dict(null);
  270. dict.set("BaseFont", Name.get(name));
  271. dict.set("Type", Name.get("Font"));
  272. dict.set("Subtype", Name.get("CIDFontType2"));
  273. dict.set("Encoding", Name.get("Identity-H"));
  274. dict.set("CIDToGIDMap", Name.get("Identity"));
  275. dict.set("W", widths);
  276. dict.set("FirstChar", widths[0]);
  277. dict.set("LastChar", widths.at(-2) + widths.at(-1).length - 1);
  278. const descriptor = new Dict(null);
  279. dict.set("FontDescriptor", descriptor);
  280. const systemInfo = new Dict(null);
  281. systemInfo.set("Ordering", "Identity");
  282. systemInfo.set("Registry", "Adobe");
  283. systemInfo.set("Supplement", 0);
  284. dict.set("CIDSystemInfo", systemInfo);
  285. return dict;
  286. }
  287. export { getXfaFontDict, getXfaFontName };