diff --git a/Userland/Libraries/LibPDF/ColorSpace.cpp b/Userland/Libraries/LibPDF/ColorSpace.cpp index a8f0383180..b5a14ede35 100644 --- a/Userland/Libraries/LibPDF/ColorSpace.cpp +++ b/Userland/Libraries/LibPDF/ColorSpace.cpp @@ -45,7 +45,7 @@ PDFErrorOr> ColorSpace::create(Document* document, Non return Error { Error::Type::MalformedPDF, "Color space must be name or array" }; } -PDFErrorOr> ColorSpace::create(DeprecatedFlyString const& name, Renderer& renderer) +PDFErrorOr> ColorSpace::create(DeprecatedFlyString const& name, Renderer&) { // Simple color spaces with no parameters, which can be specified directly if (name == CommonNames::DeviceGray) @@ -55,7 +55,7 @@ PDFErrorOr> ColorSpace::create(DeprecatedFlyString con if (name == CommonNames::DeviceCMYK) return DeviceCMYKColorSpace::the(); if (name == CommonNames::Pattern) - return PatternColorSpace::create(renderer); + return Error::rendering_unsupported_error("Pattern color spaces not yet implemented"); VERIFY_NOT_REACHED(); } @@ -86,6 +86,9 @@ PDFErrorOr> ColorSpace::create(Document* document, Non if (color_space_name == CommonNames::Lab) return TRY(LabColorSpace::create(document, move(parameters))); + if (color_space_name == CommonNames::Pattern) + return Error::rendering_unsupported_error("Pattern color spaces not yet implemented"); + if (color_space_name == CommonNames::Separation) return TRY(SeparationColorSpace::create(document, move(parameters), renderer)); @@ -773,104 +776,4 @@ Vector SeparationColorSpace::default_decode() const { return { 0.0f, 1.0f }; } -NonnullRefPtr PatternColorSpace::create(Renderer& renderer) -{ - return adopt_ref(*new PatternColorSpace(renderer)); -} - -PDFErrorOr PatternColorSpace::style(ReadonlySpan arguments) const -{ - VERIFY(arguments.size() >= 1); - - auto resources = m_renderer.m_page.resources; - - auto pattern_resource = resources->get_value(CommonNames::Pattern); - auto doc_pattern_dict = pattern_resource.get>()->cast(); - - auto const& pattern_name = arguments.last().get>()->cast()->name(); - if (!doc_pattern_dict->contains(pattern_name)) - return Error::malformed_error("Pattern dictionary does not contain pattern {}", pattern_name); - - auto const pattern = TRY(m_renderer.m_document->resolve_to(doc_pattern_dict->get_value(pattern_name))); - - auto const type = pattern->dict()->get(CommonNames::Type)->get>()->cast(); - if (type->name() != CommonNames::Pattern) - return Error::rendering_unsupported_error("Unsupported pattern type {}", type->name()); - - auto const pattern_type = pattern->dict()->get(CommonNames::PatternType)->get_u16(); - if (pattern_type != 1) - return Error::rendering_unsupported_error("Unsupported pattern type {}", pattern_type); - - auto const pattern_paint_type = pattern->dict()->get("PaintType")->get_u16(); - if (pattern_paint_type != 1) - return Error::rendering_unsupported_error("Unsupported pattern paint type {}", pattern_paint_type); - - Vector pattern_matrix; - if (pattern->dict()->contains(CommonNames::Matrix)) { - pattern_matrix = pattern->dict()->get_array(m_renderer.m_document, CommonNames::Matrix).value()->elements(); - } else { - pattern_matrix = Vector { Value { 1 }, Value { 0 }, Value { 0 }, Value { 1 }, Value { 0 }, Value { 0 } }; - } - - auto pattern_bounding_box = pattern->dict()->get_array(m_renderer.m_document, "BBox").value()->elements(); - auto pattern_transform = Gfx::AffineTransform( - pattern_matrix[0].to_float(), - pattern_matrix[1].to_float(), - pattern_matrix[2].to_float(), - pattern_matrix[3].to_float(), - pattern_matrix[4].to_float(), - pattern_matrix[5].to_float()); - - // To get the device space size for the bitmap, apply the pattern transform to the pattern space bounding box, and then apply the initial ctm. - // NB: the pattern pattern_matrix maps pattern space to the default (initial) coordinate space of the page. (i.e cannot be updated via cm). - - auto initial_ctm = Gfx::AffineTransform(m_renderer.m_graphics_state_stack.first().ctm); - initial_ctm.set_translation(0, 0); - initial_ctm.set_scale(initial_ctm.x_scale(), initial_ctm.y_scale()); - - auto pattern_space_lower_left = Gfx::FloatPoint { pattern_bounding_box[0].to_int(), pattern_bounding_box[1].to_int() }; - auto pattern_space_upper_right = Gfx::FloatPoint { pattern_bounding_box[2].to_int(), pattern_bounding_box[3].to_int() }; - - auto device_space_lower_left = initial_ctm.map(pattern_transform.map(pattern_space_lower_left)); - auto device_space_upper_right = initial_ctm.map(pattern_transform.map(pattern_space_upper_right)); - - auto bitmap_width = (int)device_space_upper_right.x() - (int)device_space_lower_left.x(); - auto bitmap_height = (int)device_space_upper_right.y() - (int)device_space_lower_left.y(); - - auto pattern_cell = TRY(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { bitmap_width, bitmap_height })); - auto page = Page(m_renderer.m_page); - page.media_box = Rectangle { - pattern_space_lower_left.x(), pattern_space_lower_left.y(), - pattern_space_upper_right.x(), pattern_space_upper_right.y() - }; - page.crop_box = page.media_box; - - auto pattern_renderer = Renderer(m_renderer.m_document, page, pattern_cell, {}, m_renderer.m_rendering_preferences); - - auto operators = TRY(Parser::parse_operators(m_renderer.m_document, pattern->bytes())); - for (auto& op : operators) - TRY(pattern_renderer.handle_operator(op, resources)); - - auto x_steps = pattern->dict()->get("XStep").value_or(bitmap_width).to_int(); - auto y_steps = pattern->dict()->get("YStep").value_or(bitmap_height).to_int(); - - auto device_space_steps = initial_ctm.map(pattern_transform.map(Gfx::IntPoint { x_steps, y_steps })); - - NonnullRefPtr style = MUST(Gfx::RepeatingBitmapPaintStyle::create( - *pattern_cell, - device_space_steps, - {})); - - return style; -} -int PatternColorSpace::number_of_components() const -{ - // Not permitted - VERIFY_NOT_REACHED(); -} -Vector PatternColorSpace::default_decode() const -{ - // Not permitted - VERIFY_NOT_REACHED(); -} } diff --git a/Userland/Libraries/LibPDF/ColorSpace.h b/Userland/Libraries/LibPDF/ColorSpace.h index 61431e69c6..81296e40b3 100644 --- a/Userland/Libraries/LibPDF/ColorSpace.h +++ b/Userland/Libraries/LibPDF/ColorSpace.h @@ -252,24 +252,4 @@ private: NonnullRefPtr m_tint_transform; Vector mutable m_tint_output_values; }; - -class PatternColorSpace final : public ColorSpace { -public: - static NonnullRefPtr create(Renderer& renderer); - ~PatternColorSpace() override = default; - - PDFErrorOr style(ReadonlySpan arguments) const override; - int number_of_components() const override; - Vector default_decode() const override; - ColorSpaceFamily const& family() const override { return ColorSpaceFamily::Pattern; } - -private: - PatternColorSpace(Renderer& renderer) - : m_renderer(renderer) - { - } - - Renderer& m_renderer; -}; - } diff --git a/Userland/Libraries/LibPDF/CommonNames.h b/Userland/Libraries/LibPDF/CommonNames.h index 326a75c16b..65b2b6f2bb 100644 --- a/Userland/Libraries/LibPDF/CommonNames.h +++ b/Userland/Libraries/LibPDF/CommonNames.h @@ -138,10 +138,8 @@ X(Outlines) \ X(P) \ X(Pages) \ - X(PaintType) \ X(Parent) \ X(Pattern) \ - X(PatternType) \ X(Perms) \ X(Predictor) \ X(Prev) \ diff --git a/Userland/Libraries/LibPDF/Renderer.cpp b/Userland/Libraries/LibPDF/Renderer.cpp index 5dd7888641..cd31d03a4a 100644 --- a/Userland/Libraries/LibPDF/Renderer.cpp +++ b/Userland/Libraries/LibPDF/Renderer.cpp @@ -616,8 +616,14 @@ RENDERER_HANDLER(set_stroking_color) RENDERER_HANDLER(set_stroking_color_extended) { - // FIXME: Pattern color spaces might need extra resources - state().paint_style = TRY(state().paint_color_space->style(args)); + // FIXME: Handle Pattern color spaces + auto last_arg = args.last(); + if (last_arg.has>() && last_arg.get>()->is()) { + dbgln("pattern space {}", last_arg.get>()->cast()->name()); + return Error::rendering_unsupported_error("Pattern color spaces not yet implemented"); + } + + state().stroke_style = TRY(state().stroke_color_space->style(args)); return {}; } @@ -629,7 +635,13 @@ RENDERER_HANDLER(set_painting_color) RENDERER_HANDLER(set_painting_color_extended) { - // FIXME: Pattern color spaces might need extra resources + // FIXME: Handle Pattern color spaces + auto last_arg = args.last(); + if (last_arg.has>() && last_arg.get>()->is()) { + dbgln("pattern space {}", last_arg.get>()->cast()->name()); + return Error::rendering_unsupported_error("Pattern color spaces not yet implemented"); + } + state().paint_style = TRY(state().paint_color_space->style(args)); return {}; } diff --git a/Userland/Libraries/LibPDF/Renderer.h b/Userland/Libraries/LibPDF/Renderer.h index d199614978..b249a4e799 100644 --- a/Userland/Libraries/LibPDF/Renderer.h +++ b/Userland/Libraries/LibPDF/Renderer.h @@ -97,8 +97,6 @@ struct RenderingPreferences { }; class Renderer { - friend class PatternColorSpace; - public: static PDFErrorsOr render(Document&, Page const&, RefPtr, Color background_color, RenderingPreferences preferences);