Repository: SerenityOS/serenity
File: Userland/Libraries/LibPDF/Renderer.cpp (C++)

Code before:
    OwnPtr<ClipRAII> clip_raii;
    if (m_rendering_preferences.clip_text)
        clip_raii = make<ClipRAII>(*this);

    auto start_position = Gfx::FloatPoint { 0.0f, 0.0f };
    auto end_position = TRY(text_state().font->draw_string(m_painter, start_position, string, *this));

    // Update text matrix.
    auto delta = end_position - start_position;
    m_text_rendering_matrix_is_dirty = true;
    m_text_matrix.translate(delta);
    return {};
}

PDFErrorOr<TransparencyGroupAttributes> Renderer::read_transparency_group_attributes(NonnullRefPtr<DictObject> group_dict)
{
    // TABLE 7.13 Additional entries specific to a transparency group attributes dictionary
    TransparencyGroupAttributes attributes;

    auto name = TRY(group_dict->get_name(m_document, CommonNames::S))->name();
    if (name != CommonNames::Transparency)
        return Error::malformed_error("Invalid transparency group /S: {}", name);

    if (group_dict->contains(CommonNames::CS)) {
        auto color_space_object = TRY(group_dict->get_object(m_document, CommonNames::CS));
        auto color_space = TRY(get_color_space_from_document(color_space_object));

        // "These restrictions exclude Lab and lightness-chromaticity ICCBased color spac-
        //  es, as well as the special color spaces Pattern, Indexed, Separation, and DeviceN."
        if (color_space->family() == ColorSpaceFamily::Lab
            || color_space->family() == ColorSpaceFamily::Pattern
            || color_space->family() == ColorSpaceFamily::Indexed
            || color_space->family() == ColorSpaceFamily::Separation
            || color_space->family() == ColorSpaceFamily::DeviceN) {
            // FIXME: Reject Lab and lightness-chromaticity ICCBased color spaces.
            return Error::malformed_error("Invalid transparency group /CS");
        }
    }

    if (group_dict->contains(CommonNames::I))
        attributes.is_isolated = group_dict->get_value(CommonNames::I).get<bool>();

    if (group_dict->contains(CommonNames::K))
        attributes.is_knockout = group_dict->get_value(CommonNames::K).get<bool>();

    return attributes;
}

PDFErrorOr<void> Renderer::paint_form_xobject(NonnullRefPtr<StreamObject> form)
{
    Optional<NonnullRefPtr<DictObject>> xobject_resources {};

Review comment (suggestion):
The retrieved color_space is not assigned to `attributes.color_space`, so the `TransparencyGroupAttributes::color_space` remains unset. Add `attributes.color_space = color_space;` after this line.
```suggestion
        auto color_space = TRY(get_color_space_from_document(color_space_object));
        attributes.color_space = color_space;
```

Code after:
    OwnPtr<ClipRAII> clip_raii;
    if (m_rendering_preferences.clip_text)
        clip_raii = make<ClipRAII>(*this);

    auto start_position = Gfx::FloatPoint { 0.0f, 0.0f };
    auto end_position = TRY(text_state().font->draw_string(m_painter, start_position, string, *this));

    // Update text matrix.
    auto delta = end_position - start_position;
    m_text_rendering_matrix_is_dirty = true;
    m_text_matrix.translate(delta);
    return {};
}

PDFErrorOr<TransparencyGroupAttributes> Renderer::read_transparency_group_attributes(NonnullRefPtr<DictObject> group_dict)
{
    // TABLE 7.13 Additional entries specific to a transparency group attributes dictionary
    TransparencyGroupAttributes attributes;

    auto name = TRY(group_dict->get_name(m_document, CommonNames::S))->name();
    if (name != CommonNames::Transparency)
        return Error::malformed_error("Invalid transparency group /S: {}", name);

    if (group_dict->contains(CommonNames::CS)) {
        auto color_space_object = TRY(group_dict->get_object(m_document, CommonNames::CS));
        auto color_space = TRY(get_color_space_from_document(color_space_object));

        // "These restrictions exclude Lab and lightness-chromaticity ICCBased color spac-
        //  es, as well as the special color spaces Pattern, Indexed, Separation, and DeviceN."
        if (color_space->family() == ColorSpaceFamily::Lab
            || color_space->family() == ColorSpaceFamily::Pattern
            || color_space->family() == ColorSpaceFamily::Indexed
            || color_space->family() == ColorSpaceFamily::Separation
            || color_space->family() == ColorSpaceFamily::DeviceN) {
            // FIXME: Reject Lab and lightness-chromaticity ICCBased color spaces.
            return Error::malformed_error("Invalid transparency group /CS");
        }

        attributes.color_space = color_space;
    }

    if (group_dict->contains(CommonNames::I))
        attributes.is_isolated = TRY(m_document->resolve_to<bool>(group_dict->get_value(CommonNames::I)));

    if (group_dict->contains(CommonNames::K))
        attributes.is_knockout = TRY(m_document->resolve_to<bool>(group_dict->get_value(CommonNames::K)));

    return attributes;
}

PDFErrorOr<void> Renderer::paint_form_xobject(NonnullRefPtr<StreamObject> form)