From 1238e65d3093de8958ebe8cd8eedcce5331f76a8 Mon Sep 17 00:00:00 2001 From: Matthew Olsson Date: Thu, 24 Mar 2022 10:08:08 -0700 Subject: [PATCH] LibPDF: Move color space creation from Renderer to ColorSpace --- Userland/Libraries/LibPDF/ColorSpace.cpp | 36 +++++++++++++++++++++++- Userland/Libraries/LibPDF/ColorSpace.h | 23 +++++++++------ Userland/Libraries/LibPDF/Renderer.cpp | 34 ++-------------------- 3 files changed, 52 insertions(+), 41 deletions(-) diff --git a/Userland/Libraries/LibPDF/ColorSpace.cpp b/Userland/Libraries/LibPDF/ColorSpace.cpp index d9f7179f3a..184361f645 100644 --- a/Userland/Libraries/LibPDF/ColorSpace.cpp +++ b/Userland/Libraries/LibPDF/ColorSpace.cpp @@ -6,10 +6,44 @@ #include #include +#include #include namespace PDF { +PDFErrorOr> ColorSpace::create(Document* document, FlyString const& name, Page const& page) +{ + // Simple color spaces with no parameters, which can be specified directly + if (name == CommonNames::DeviceGray) + return DeviceGrayColorSpace::the(); + if (name == CommonNames::DeviceRGB) + return DeviceRGBColorSpace::the(); + if (name == CommonNames::DeviceCMYK) + return DeviceCMYKColorSpace::the(); + if (name == CommonNames::Pattern) + TODO(); + + // The color space is a complex color space with parameters that resides in + // the resource dictionary + auto color_space_resource_dict = TRY(page.resources->get_dict(document, CommonNames::ColorSpace)); + if (!color_space_resource_dict->contains(name)) + TODO(); + + auto color_space_array = TRY(color_space_resource_dict->get_array(document, name)); + auto color_space_name = TRY(color_space_array->get_name_at(document, 0))->name(); + + Vector parameters; + parameters.ensure_capacity(color_space_array->size() - 1); + for (size_t i = 1; i < color_space_array->size(); i++) + parameters.unchecked_append(color_space_array->at(i)); + + if (color_space_name == CommonNames::CalRGB) + return TRY(CalRGBColorSpace::create(document, move(parameters))); + + dbgln("Unknown color space: {}", color_space_name); + TODO(); +} + NonnullRefPtr DeviceGrayColorSpace::the() { static auto instance = adopt_ref(*new DeviceGrayColorSpace()); @@ -54,7 +88,7 @@ Color DeviceCMYKColorSpace::color(Vector const& arguments) const return Color::from_cmyk(c, m, y, k); } -PDFErrorOr> CalRGBColorSpace::create(RefPtr document, Vector&& parameters) +PDFErrorOr> CalRGBColorSpace::create(Document* document, Vector&& parameters) { if (parameters.size() != 1) return Error { Error::Type::MalformedPDF, "RGB color space expects one parameter" }; diff --git a/Userland/Libraries/LibPDF/ColorSpace.h b/Userland/Libraries/LibPDF/ColorSpace.h index 87f1fe90f8..b4d011c091 100644 --- a/Userland/Libraries/LibPDF/ColorSpace.h +++ b/Userland/Libraries/LibPDF/ColorSpace.h @@ -25,8 +25,12 @@ namespace PDF { +class Page; + class ColorSpace : public RefCounted { public: + static PDFErrorOr> create(Document*, FlyString const& name, Page const& page); + virtual ~ColorSpace() = default; virtual Color color(Vector const& arguments) const = 0; @@ -36,9 +40,9 @@ class DeviceGrayColorSpace final : public ColorSpace { public: static NonnullRefPtr the(); - virtual ~DeviceGrayColorSpace() override = default; + ~DeviceGrayColorSpace() override = default; - virtual Color color(Vector const& arguments) const override; + Color color(Vector const& arguments) const override; private: DeviceGrayColorSpace() = default; @@ -48,9 +52,9 @@ class DeviceRGBColorSpace final : public ColorSpace { public: static NonnullRefPtr the(); - virtual ~DeviceRGBColorSpace() override = default; + ~DeviceRGBColorSpace() override = default; - virtual Color color(Vector const& arguments) const override; + Color color(Vector const& arguments) const override; private: DeviceRGBColorSpace() = default; @@ -60,9 +64,9 @@ class DeviceCMYKColorSpace final : public ColorSpace { public: static NonnullRefPtr the(); - virtual ~DeviceCMYKColorSpace() override = default; + ~DeviceCMYKColorSpace() override = default; - virtual Color color(Vector const& arguments) const override; + Color color(Vector const& arguments) const override; private: DeviceCMYKColorSpace() = default; @@ -70,10 +74,11 @@ private: class CalRGBColorSpace final : public ColorSpace { public: - static PDFErrorOr> create(RefPtr, Vector&& parameters); - virtual ~CalRGBColorSpace() override = default; + static PDFErrorOr> create(Document*, Vector&& parameters); - virtual Color color(Vector const& arguments) const override; + ~CalRGBColorSpace() override = default; + + Color color(Vector const& arguments) const override; private: CalRGBColorSpace() = default; diff --git a/Userland/Libraries/LibPDF/Renderer.cpp b/Userland/Libraries/LibPDF/Renderer.cpp index f9f190f018..937048c801 100644 --- a/Userland/Libraries/LibPDF/Renderer.cpp +++ b/Userland/Libraries/LibPDF/Renderer.cpp @@ -462,14 +462,14 @@ RENDERER_TODO(type3_font_set_glyph_width_and_bbox) RENDERER_HANDLER(set_stroking_space) { - state().stroke_color_space = MUST(get_color_space(args[0])); + state().stroke_color_space = TRY(get_color_space(args[0])); VERIFY(state().stroke_color_space); return {}; } RENDERER_HANDLER(set_painting_space) { - state().paint_color_space = MUST(get_color_space(args[0])); + state().paint_color_space = TRY(get_color_space(args[0])); VERIFY(state().paint_color_space); return {}; } @@ -656,35 +656,7 @@ void Renderer::show_text(String const& string, float shift) PDFErrorOr> Renderer::get_color_space(Value const& value) { auto name = value.get>()->cast()->name(); - - // Simple color spaces with no parameters, which can be specified directly - if (name == CommonNames::DeviceGray) - return DeviceGrayColorSpace::the(); - if (name == CommonNames::DeviceRGB) - return DeviceRGBColorSpace::the(); - if (name == CommonNames::DeviceCMYK) - return DeviceCMYKColorSpace::the(); - if (name == CommonNames::Pattern) - TODO(); - - // The color space is a complex color space with parameters that resides in - // the resource dictionary - auto color_space_resource_dict = TRY(m_page.resources->get_dict(m_document, CommonNames::ColorSpace)); - if (!color_space_resource_dict->contains(name)) - TODO(); - - auto color_space_array = TRY(color_space_resource_dict->get_array(m_document, name)); - name = TRY(color_space_array->get_name_at(m_document, 0))->name(); - - Vector parameters; - parameters.ensure_capacity(color_space_array->size() - 1); - for (size_t i = 1; i < color_space_array->size(); i++) - parameters.unchecked_append(color_space_array->at(i)); - - if (name == CommonNames::CalRGB) - return TRY(CalRGBColorSpace::create(m_document, move(parameters))); - - TODO(); + return TRY(ColorSpace::create(m_document, name, m_page)); } Gfx::AffineTransform const& Renderer::calculate_text_rendering_matrix()