CFF.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * Copyright (c) 2023, Rodrigo Tobar <rtobarc@gmail.com>.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Tuple.h>
  8. #include <AK/Types.h>
  9. #include <LibPDF/Error.h>
  10. #include <LibPDF/Fonts/Type1FontProgram.h>
  11. namespace PDF {
  12. class Reader;
  13. // CFF spec: https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf
  14. class CFF : public Type1FontProgram {
  15. private:
  16. // CFF spec, "Table 9 Top DICT Operator Entries"
  17. enum class TopDictOperator {
  18. Version = 0,
  19. Notice,
  20. FullName,
  21. FamilyName,
  22. Weight,
  23. FontBBox,
  24. UniqueID = 13,
  25. XUID,
  26. Charset = 15,
  27. Encoding,
  28. CharStrings,
  29. Private,
  30. Copyright = (12 << 8),
  31. IsFixedPitch,
  32. ItalicAngle,
  33. UnderlinePosition,
  34. UnderlineThickness,
  35. PaintType,
  36. CharstringType,
  37. FontMatrix,
  38. StrokeWidth,
  39. SyntheticBase = (12 << 8 | 20),
  40. PostScript,
  41. BaseFontName,
  42. BaseFontBlend,
  43. // CFF spec, "Table 10 CIDFont Operator Extensions"
  44. RegistryOrderingSupplement = (12 << 8 | 30),
  45. CIDFontVersion,
  46. CIDFontRevision,
  47. CIDFontType,
  48. CIDCount,
  49. UIDBase,
  50. FDArray,
  51. FDSelect,
  52. FontName,
  53. };
  54. // CFF spec, "Table 23 Private DICT Operators"
  55. enum class PrivDictOperator {
  56. BlueValues = 6,
  57. OtherBlues,
  58. FamilyBlues,
  59. FamilyOtherBlues,
  60. BlueScale = (12 << 8 | 9),
  61. BlueShift,
  62. BlueFuzz,
  63. StdHW = 10,
  64. StdVW,
  65. StemSnapH = (12 << 8 | 12),
  66. StemSnapV,
  67. ForceBold,
  68. LanguageGroup = (12 << 8 | 17),
  69. ExpansionFactor,
  70. InitialRandomSeed,
  71. Subrs = 19,
  72. DefaultWidthX,
  73. NominalWidthX,
  74. };
  75. public:
  76. static PDFErrorOr<NonnullRefPtr<CFF>> create(ReadonlyBytes const&, RefPtr<Encoding> encoding);
  77. // to private
  78. using Card8 = u8;
  79. using Card16 = u16;
  80. using Offset = i32;
  81. using OffSize = u8;
  82. using SID = u16;
  83. using DictOperand = Variant<int, float>;
  84. static float to_number(DictOperand operand)
  85. {
  86. if (operand.has<int>())
  87. return operand.get<int>();
  88. return operand.get<float>();
  89. }
  90. static int load_int_dict_operand(u8 b0, Reader&);
  91. static float load_float_dict_operand(Reader&);
  92. static PDFErrorOr<DictOperand> load_dict_operand(u8, Reader&);
  93. using IndexDataHandler = Function<PDFErrorOr<void>(ReadonlyBytes const&)>;
  94. static PDFErrorOr<void> parse_index(Reader& reader, IndexDataHandler&&);
  95. static PDFErrorOr<void> parse_index_data(OffSize offset_size, Card16 count, Reader& reader, IndexDataHandler&);
  96. template<typename OperatorT>
  97. using DictEntryHandler = Function<PDFErrorOr<void>(OperatorT, Vector<DictOperand> const&)>;
  98. template<typename OperatorT>
  99. static PDFErrorOr<void> parse_dict(Reader& reader, DictEntryHandler<OperatorT>&& handler);
  100. template<typename OperatorT>
  101. static PDFErrorOr<OperatorT> parse_dict_operator(u8, Reader&);
  102. // CFF spec, "8 Top DICT INDEX"
  103. struct TopDict {
  104. int charset_offset = 0;
  105. int encoding_offset = 0;
  106. int charstrings_offset = 0;
  107. Vector<ByteBuffer> local_subroutines;
  108. Optional<float> defaultWidthX;
  109. Optional<float> nominalWidthX;
  110. bool is_cid_keyed = false;
  111. int fdselect_offset = 0;
  112. int fdarray_offset = 0;
  113. };
  114. static PDFErrorOr<Vector<TopDict>> parse_top_dicts(Reader&, ReadonlyBytes const& cff_bytes);
  115. static PDFErrorOr<Vector<StringView>> parse_strings(Reader&);
  116. static PDFErrorOr<Vector<CFF::Glyph>> parse_charstrings(Reader&&, Vector<ByteBuffer> const& local_subroutines, Vector<ByteBuffer> const& global_subroutines);
  117. static DeprecatedFlyString resolve_sid(SID, Vector<StringView> const&);
  118. static PDFErrorOr<Vector<SID>> parse_charset(Reader&&, size_t);
  119. static PDFErrorOr<Vector<u8>> parse_fdselect(Reader&&, size_t);
  120. static PDFErrorOr<Vector<u8>> parse_encoding(Reader&&, HashMap<Card8, SID>& supplemental);
  121. };
  122. }