Operator.h 9.3 KB

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