Skip to content

Commit b3007c1

Browse files
rtobarawesomekling
authored andcommitted
LibPDF: Allow operators to receive optional resources
Operators usually assume that the resources its operations will require will be the Page's. This assumption breaks however when XObjects with their own resources come into the picture (and maybe other cases too). In that case, the XObject's resources take precedence, but they should also contain the Page's resources. Because of this, one can safely use the XObject resources alone when given, and default to the Page's if not. This commit adds all operator calls an extra argument with optional resources, which will be fed by XObjects as necessary.
1 parent e58165e commit b3007c1

File tree

2 files changed

+17
-16
lines changed

2 files changed

+17
-16
lines changed

Userland/Libraries/LibPDF/Renderer.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include <LibPDF/Renderer.h>
1111

1212
#define RENDERER_HANDLER(name) \
13-
PDFErrorOr<void> Renderer::handle_##name([[maybe_unused]] Vector<Value> const& args)
13+
PDFErrorOr<void> Renderer::handle_##name([[maybe_unused]] Vector<Value> const& args, [[maybe_unused]] Optional<NonnullRefPtr<DictObject>> extra_resources)
1414

1515
#define RENDERER_TODO(name) \
1616
RENDERER_HANDLER(name) \
@@ -118,20 +118,20 @@ PDFErrorOr<void> Renderer::render()
118118
return {};
119119
}
120120

121-
PDFErrorOr<void> Renderer::handle_operator(Operator const& op)
121+
PDFErrorOr<void> Renderer::handle_operator(Operator const& op, Optional<NonnullRefPtr<DictObject>> extra_resources)
122122
{
123123
switch (op.type()) {
124-
#define V(name, snake_name, symbol) \
125-
case OperatorType::name: \
126-
TRY(handle_##snake_name(op.arguments())); \
124+
#define V(name, snake_name, symbol) \
125+
case OperatorType::name: \
126+
MUST(handle_##snake_name(op.arguments(), extra_resources)); \
127127
break;
128128
ENUMERATE_OPERATORS(V)
129129
#undef V
130130
case OperatorType::TextNextLineShowString:
131-
TRY(handle_text_next_line_show_string(op.arguments()));
131+
MUST(handle_text_next_line_show_string(op.arguments()));
132132
break;
133133
case OperatorType::TextNextLineShowStringSetSpacing:
134-
TRY(handle_text_next_line_show_string_set_spacing(op.arguments()));
134+
MUST(handle_text_next_line_show_string_set_spacing(op.arguments()));
135135
break;
136136
}
137137

@@ -204,9 +204,9 @@ RENDERER_TODO(set_flatness_tolerance)
204204

205205
RENDERER_HANDLER(set_graphics_state_from_dict)
206206
{
207-
VERIFY(m_page.resources->contains(CommonNames::ExtGState));
207+
auto resources = extra_resources.value_or(m_page.resources);
208208
auto dict_name = MUST(m_document->resolve_to<NameObject>(args[0]))->name();
209-
auto ext_gstate_dict = MUST(m_page.resources->get_dict(m_document, CommonNames::ExtGState));
209+
auto ext_gstate_dict = MUST(resources->get_dict(m_document, CommonNames::ExtGState));
210210
auto target_dict = MUST(ext_gstate_dict->get_dict(m_document, dict_name));
211211
TRY(set_graphics_state_from_dict(target_dict));
212212
return {};
@@ -421,8 +421,9 @@ RENDERER_HANDLER(text_set_leading)
421421

422422
RENDERER_HANDLER(text_set_font)
423423
{
424+
auto resources = extra_resources.value_or(m_page.resources);
424425
auto target_font_name = MUST(m_document->resolve_to<NameObject>(args[0]))->name();
425-
auto fonts_dictionary = MUST(m_page.resources->get_dict(m_document, CommonNames::Font));
426+
auto fonts_dictionary = MUST(resources->get_dict(m_document, CommonNames::Font));
426427
auto font_dictionary = MUST(fonts_dictionary->get_dict(m_document, target_font_name));
427428

428429
text_state().font_size = args[1].to_float();
@@ -527,14 +528,14 @@ RENDERER_TODO(type3_font_set_glyph_width_and_bbox)
527528

528529
RENDERER_HANDLER(set_stroking_space)
529530
{
530-
state().stroke_color_space = TRY(get_color_space(args[0], m_page.resources));
531+
state().stroke_color_space = TRY(get_color_space(args[0], extra_resources.value_or(m_page.resources)));
531532
VERIFY(state().stroke_color_space);
532533
return {};
533534
}
534535

535536
RENDERER_HANDLER(set_painting_space)
536537
{
537-
state().paint_color_space = TRY(get_color_space(args[0], m_page.resources));
538+
state().paint_color_space = TRY(get_color_space(args[0], extra_resources.value_or(m_page.resources)));
538539
VERIFY(state().paint_color_space);
539540
return {};
540541
}

Userland/Libraries/LibPDF/Renderer.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,13 @@ class Renderer {
9797

9898
PDFErrorOr<void> render();
9999

100-
PDFErrorOr<void> handle_operator(Operator const&);
100+
PDFErrorOr<void> handle_operator(Operator const&, Optional<NonnullRefPtr<DictObject>> = {});
101101
#define V(name, snake_name, symbol) \
102-
PDFErrorOr<void> handle_##snake_name(Vector<Value> const& args);
102+
PDFErrorOr<void> handle_##snake_name(Vector<Value> const& args, Optional<NonnullRefPtr<DictObject>> = {});
103103
ENUMERATE_OPERATORS(V)
104104
#undef V
105-
PDFErrorOr<void> handle_text_next_line_show_string(Vector<Value> const& args);
106-
PDFErrorOr<void> handle_text_next_line_show_string_set_spacing(Vector<Value> const& args);
105+
PDFErrorOr<void> handle_text_next_line_show_string(Vector<Value> const& args, Optional<NonnullRefPtr<DictObject>> = {});
106+
PDFErrorOr<void> handle_text_next_line_show_string_set_spacing(Vector<Value> const& args, Optional<NonnullRefPtr<DictObject>> = {});
107107

108108
void begin_path_paint();
109109
void end_path_paint();

0 commit comments

Comments
 (0)