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