Browse Source

LibPDF: Implement CFF built-in Standard and Expert encodings

With this, all tables from the spec appendixes are in CFF.cpp.

This fixes a crash reading page 2 (and onward) of
2ThestructureoftheCIE1997ColourAppearanceModelCIECAM97s.pdf in
the pdffiles repo.
Nico Weber 1 year ago
parent
commit
cb961101c7
1 changed files with 48 additions and 2 deletions
  1. 48 2
      Userland/Libraries/LibPDF/Fonts/CFF.cpp

+ 48 - 2
Userland/Libraries/LibPDF/Fonts/CFF.cpp

@@ -17,6 +17,48 @@
 
 namespace PDF {
 
+// The built-in encodings map codes to SIDs.
+
+// CFF spec, "Appendix B Predefined Encodings, Standard Encoding"
+// clang-format off
+static constexpr Array s_predefined_encoding_standard {
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,
+     11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,
+     32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,
+     61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
+     90,  91,  92,  93,  94,  95,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,   0, 111, 112,
+    113, 114,   0, 115, 116, 117, 118, 119, 120, 121, 122,   0, 123,   0, 124, 125, 126, 127, 128, 129, 130, 131,   0, 132, 133,   0, 134, 135, 136,
+    137,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 138,   0, 139,   0,   0,   0,   0, 140, 141, 142, 143,   0,
+      0,   0,   0,   0, 144,   0,   0,
+      0, 145,   0,   0, 146, 147, 148,
+    149,   0,   0,   0,   0,
+};
+static_assert(s_predefined_encoding_standard.size() == 256);
+// clang-format on
+
+// CFF spec, "Appendix B Predefined Encodings, Expert Encoding"
+// clang-format off
+static constexpr Array s_predefined_encoding_expert {
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1, 229, 230,   0,
+    231, 232, 233, 234, 235, 236, 237, 238,  13,  14,  15,  99, 239, 240, 241, 242, 243, 244,
+    245, 246, 247, 248,  27,  28, 249, 250, 251, 252,   0, 253, 254, 255, 256, 257,   0,   0,   0, 258,   0,   0, 259, 260, 261, 262,   0,   0, 263,
+    264, 265,   0, 266, 109, 110, 267, 268, 269,   0, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288,
+    289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 304, 305, 306,   0,   0, 307, 308, 309, 310,
+    311,   0, 312,   0,   0, 313,   0,   0, 314, 315,   0,   0, 316, 317, 318,   0,   0,   0, 158, 155, 163, 319, 320, 321, 322, 323, 324, 325,   0,
+      0, 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350,
+    351, 352, 353, 354, 355, 356, 357, 358, 359, 360,
+    361, 362, 363, 364, 365, 366, 367, 368, 369, 370,
+    371, 372, 373, 374, 375, 376, 377, 378,
+};
+static_assert(s_predefined_encoding_expert.size() == 256);
+// clang-format on
+
+// Charsets map GIDs to SIDs.
+
 // CFF spec, "Appendix C Predefined Charsets, Expert"
 // clang-format off
 static constexpr Array s_predefined_charset_expert {
@@ -177,10 +219,14 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
     HashMap<Card8, SID> encoding_supplemental; // Maps codepoint to SID.
     switch (encoding_offset) {
     case 0:
-        dbgln("CFF: Built-in Standard Encoding not yet implemented");
+        dbgln_if(CFF_DEBUG, "CFF predefined encoding Standard");
+        for (size_t i = 1; i < s_predefined_encoding_standard.size(); ++i)
+            TRY(encoding_supplemental.try_set(i, s_predefined_encoding_standard[i]));
         break;
     case 1:
-        dbgln("CFF: Built-in Expert Encoding not yet implemented");
+        dbgln_if(CFF_DEBUG, "CFF predefined encoding Expert");
+        for (size_t i = 1; i < s_predefined_encoding_expert.size(); ++i)
+            TRY(encoding_supplemental.try_set(i, s_predefined_encoding_expert[i]));
         break;
     default:
         encoding_codes = TRY(parse_encoding(Reader(cff_bytes.slice(encoding_offset)), encoding_supplemental));