Operator.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Format.h>
  8. #include <AK/StringBuilder.h>
  9. #include <AK/Vector.h>
  10. #include <LibPDF/Value.h>
  11. #define ENUMERATE_OPERATORS(V) \
  12. V(SaveState, save_state, q) \
  13. V(RestoreState, restore_state, Q) \
  14. V(ConcatenateMatrix, concatenate_matrix, cm) \
  15. V(SetLineWidth, set_line_width, w) \
  16. V(SetLineCap, set_line_cap, J) \
  17. V(SetLineJoin, set_line_join, j) \
  18. V(SetMiterLimit, set_miter_limit, M) \
  19. V(SetDashPattern, set_dash_pattern, d) \
  20. V(SetColorRenderingIntent, set_color_rendering_intent, ri) \
  21. V(SetFlatnessTolerance, set_flatness_tolerance, i) \
  22. V(SetGraphicsStateFromDict, set_graphics_state_from_dict, gs) \
  23. V(PathMove, path_move, m) \
  24. V(PathLine, path_line, l) \
  25. V(PathCubicBezierCurve, path_cubic_bezier_curve, c) \
  26. V(PathCubicBezierCurveNoFirstControl, path_cubic_bezier_curve_no_first_control, v) \
  27. V(PathCubicBezierCurveNoSecondControl, path_cubic_bezier_curve_no_second_control, y) \
  28. V(PathClose, path_close, h) \
  29. V(PathAppendRect, path_append_rect, re) \
  30. V(PathStroke, path_stroke, S) \
  31. V(PathCloseAndStroke, path_close_and_stroke, s) \
  32. V(PathFillNonZero, path_fill_nonzero, f) \
  33. V(PathFillNonZeroDeprecated, path_fill_nonzero_deprecated, F) \
  34. V(PathFillEvenOdd, path_fill_evenodd, f*) \
  35. V(PathFillStrokeNonZero, path_fill_stroke_nonzero, B) \
  36. V(PathFillStrokeEvenOdd, path_fill_stroke_evenodd, B*) \
  37. V(PathCloseFillStrokeNonZero, path_close_fill_stroke_nonzero, b) \
  38. V(PathCloseFillStrokeEvenOdd, path_close_fill_stroke_evenodd, b*) \
  39. V(PathEnd, path_end, n) \
  40. V(PathIntersectClipNonZero, path_intersect_clip_nonzero, W) \
  41. V(PathIntersectClipEvenOdd, path_intersect_clip_evenodd, W*) \
  42. V(TextBegin, text_begin, BT) \
  43. V(TextEnd, text_end, ET) \
  44. V(TextSetCharSpace, text_set_char_space, Tc) \
  45. V(TextSetWordSpace, text_set_word_space, Tw) \
  46. V(TextSetHorizontalScale, text_set_horizontal_scale, Tz) \
  47. V(TextSetLeading, text_set_leading, TL) \
  48. V(TextSetFont, text_set_font, Tf) \
  49. V(TextSetRenderingMode, text_set_rendering_mode, Tr) \
  50. V(TextSetRise, text_set_rise, Ts) \
  51. V(TextNextLineOffset, text_next_line_offset, Td) \
  52. V(TextNextLineAndSetLeading, text_next_line_and_set_leading, TD) \
  53. V(TextSetMatrixAndLineMatrix, text_set_matrix_and_line_matrix, Tm) \
  54. V(TextNextLine, text_next_line, T*) \
  55. V(TextShowString, text_show_string, Tj) \
  56. V(TextShowStringArray, text_show_string_array, TJ) \
  57. V(Type3FontSetGlyphWidth, type3_font_set_glyph_width, d0) \
  58. V(Type3FontSetGlyphWidthAndBBox, type3_font_set_glyph_width_and_bbox, d1) \
  59. V(SetStrokingSpace, set_stroking_space, CS) \
  60. V(SetPaintingSpace, set_painting_space, cs) \
  61. V(SetStrokingColor, set_stroking_color, SC) \
  62. V(SetStrokingColorExtended, set_stroking_color_extended, SCN) \
  63. V(SetPaintingColor, set_painting_color, sc) \
  64. V(SetPaintingColorExtended, set_painting_color_extended, scn) \
  65. V(SetStrokingColorAndSpaceToGray, set_stroking_color_and_space_to_gray, G) \
  66. V(SetPaintingColorAndSpaceToGray, set_painting_color_and_space_to_gray, g) \
  67. V(SetStrokingColorAndSpaceToRGB, set_stroking_color_and_space_to_rgb, RG) \
  68. V(SetPaintingColorAndSpaceToRGB, set_painting_color_and_space_to_rgb, rg) \
  69. V(SetStrokingColorAndSpaceToCMYK, set_stroking_color_and_space_to_cmyk, K) \
  70. V(SetPaintingColorAndSpaceToCMYK, set_painting_color_and_space_to_cmyk, k) \
  71. V(Shade, shade, sh) \
  72. V(InlineImageBegin, inline_image_begin, BI) \
  73. V(InlineImageBeginData, inline_image_begin_data, ID) \
  74. V(InlineImageEnd, inline_image_end, EI) \
  75. V(PaintXObject, paint_xobject, Do) \
  76. V(MarkedContentPoint, marked_content_point, MP) \
  77. V(MarkedContentDesignate, marked_content_designate, DP) \
  78. V(MarkedContentBegin, marked_content_begin, BMC) \
  79. V(MarkedContentBeginWithPropertyList, marked_content_begin_with_property_list, BDC) \
  80. V(MarkedContentEnd, marked_content_end, EMC) \
  81. V(CompatibilityBegin, compatibility_begin, BX) \
  82. V(CompatibilityEnd, compatibility_end, EX)
  83. namespace PDF {
  84. enum class OperatorType {
  85. #define V(name, snake_name, symbol) name,
  86. ENUMERATE_OPERATORS(V)
  87. #undef V
  88. TextNextLineShowString,
  89. TextNextLineShowStringSetSpacing,
  90. };
  91. class Operator {
  92. public:
  93. static OperatorType operator_type_from_symbol(StringView symbol_string)
  94. {
  95. #define V(name, snake_name, symbol) \
  96. if (symbol_string == #symbol) \
  97. return OperatorType::name;
  98. ENUMERATE_OPERATORS(V)
  99. #undef V
  100. if (symbol_string == "'")
  101. return OperatorType::TextNextLineShowString;
  102. if (symbol_string == "\"")
  103. return OperatorType::TextNextLineShowStringSetSpacing;
  104. dbgln("unsupported graphics symbol {}", symbol_string);
  105. VERIFY_NOT_REACHED();
  106. }
  107. static char const* operator_name(OperatorType operator_type)
  108. {
  109. #define V(name, snake_name, symbol) \
  110. if (operator_type == OperatorType::name) \
  111. return #name;
  112. ENUMERATE_OPERATORS(V)
  113. #undef V
  114. if (operator_type == OperatorType::TextNextLineShowString)
  115. return "TextNextLineShowString";
  116. if (operator_type == OperatorType::TextNextLineShowStringSetSpacing)
  117. return "TextNextLineShowStringSetSpacing";
  118. VERIFY_NOT_REACHED();
  119. }
  120. static char const* operator_symbol(OperatorType operator_type)
  121. {
  122. #define V(name, snake_name, symbol) \
  123. if (operator_type == OperatorType::name) \
  124. return #symbol;
  125. ENUMERATE_OPERATORS(V)
  126. #undef V
  127. if (operator_type == OperatorType::TextNextLineShowString)
  128. return "'";
  129. if (operator_type == OperatorType::TextNextLineShowStringSetSpacing)
  130. return "\"";
  131. VERIFY_NOT_REACHED();
  132. }
  133. Operator(OperatorType operator_type, Vector<Value> arguments)
  134. : m_operator_type(operator_type)
  135. , m_arguments(move(arguments))
  136. {
  137. }
  138. [[nodiscard]] ALWAYS_INLINE OperatorType type() const { return m_operator_type; }
  139. [[nodiscard]] ALWAYS_INLINE Vector<Value> const& arguments() const { return m_arguments; }
  140. private:
  141. OperatorType m_operator_type;
  142. Vector<Value> m_arguments;
  143. };
  144. }
  145. namespace AK {
  146. template<>
  147. struct Formatter<PDF::Operator> : Formatter<StringView> {
  148. ErrorOr<void> format(FormatBuilder& format_builder, PDF::Operator const& op)
  149. {
  150. StringBuilder builder;
  151. builder.appendff("{} ({})",
  152. PDF::Operator::operator_name(op.type()),
  153. PDF::Operator::operator_symbol(op.type()));
  154. if (!op.arguments().is_empty()) {
  155. builder.append(" ["sv);
  156. for (auto& argument : op.arguments())
  157. builder.appendff(" {}", argument);
  158. builder.append(" ]"sv);
  159. }
  160. return Formatter<StringView>::format(format_builder, builder.to_byte_string());
  161. }
  162. };
  163. }