2021-05-28 00:01:37 +03:00
|
|
|
/*
|
2022-03-06 03:52:00 +03:00
|
|
|
* Copyright (c) 2021-2022, Matthew Olsson <mattco@serenityos.org>
|
2021-05-28 00:01:37 +03:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2023-01-09 03:23:00 +03:00
|
|
|
#include <AK/DeprecatedFlyString.h>
|
2023-01-02 17:15:14 +03:00
|
|
|
#include <AK/Forward.h>
|
2021-05-28 00:01:37 +03:00
|
|
|
#include <LibGfx/Color.h>
|
2023-07-19 04:35:49 +03:00
|
|
|
#include <LibGfx/ICC/Profile.h>
|
2023-12-05 15:51:42 +03:00
|
|
|
#include <LibGfx/PaintStyle.h>
|
2023-11-04 23:02:28 +03:00
|
|
|
#include <LibPDF/Function.h>
|
2021-05-28 00:01:37 +03:00
|
|
|
#include <LibPDF/Value.h>
|
|
|
|
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
#define ENUMERATE_COLOR_SPACE_FAMILIES(V) \
|
|
|
|
V(DeviceGray, true) \
|
|
|
|
V(DeviceRGB, true) \
|
|
|
|
V(DeviceCMYK, true) \
|
|
|
|
V(CalGray, false) \
|
|
|
|
V(CalRGB, false) \
|
|
|
|
V(Lab, false) \
|
|
|
|
V(ICCBased, false) \
|
|
|
|
V(Indexed, false) \
|
2023-10-20 18:12:38 +03:00
|
|
|
V(Pattern, true) \
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
V(Separation, false) \
|
|
|
|
V(DeviceN, false)
|
2021-05-28 00:01:37 +03:00
|
|
|
|
|
|
|
namespace PDF {
|
|
|
|
|
2023-12-05 15:51:42 +03:00
|
|
|
typedef Variant<Gfx::Color, NonnullRefPtr<Gfx::PaintStyle>> ColorOrStyle;
|
|
|
|
class Renderer;
|
|
|
|
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
class ColorSpaceFamily {
|
|
|
|
public:
|
2023-10-20 18:11:03 +03:00
|
|
|
ColorSpaceFamily(DeprecatedFlyString name, bool may_be_specified_directly)
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
: m_name(move(name))
|
2023-10-20 18:11:03 +03:00
|
|
|
, m_may_be_specified_directly(may_be_specified_directly)
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-07-08 05:48:11 +03:00
|
|
|
DeprecatedFlyString name() const { return m_name; }
|
2023-10-20 18:11:03 +03:00
|
|
|
bool may_be_specified_directly() const { return m_may_be_specified_directly; }
|
2023-01-09 03:23:00 +03:00
|
|
|
static PDFErrorOr<ColorSpaceFamily> get(DeprecatedFlyString const&);
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
|
2023-10-20 18:11:03 +03:00
|
|
|
#define ENUMERATE(name, may_be_specified_directly) static ColorSpaceFamily name;
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
ENUMERATE_COLOR_SPACE_FAMILIES(ENUMERATE)
|
|
|
|
#undef ENUMERATE
|
|
|
|
|
2023-11-06 15:23:48 +03:00
|
|
|
bool operator==(ColorSpaceFamily const& other) const
|
|
|
|
{
|
|
|
|
return m_name == other.m_name;
|
|
|
|
}
|
|
|
|
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
private:
|
2023-01-09 03:23:00 +03:00
|
|
|
DeprecatedFlyString m_name;
|
2023-10-20 18:11:03 +03:00
|
|
|
bool m_may_be_specified_directly;
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
};
|
2022-03-24 20:08:08 +03:00
|
|
|
|
2021-05-28 00:01:37 +03:00
|
|
|
class ColorSpace : public RefCounted<ColorSpace> {
|
|
|
|
public:
|
2023-12-07 16:45:44 +03:00
|
|
|
static PDFErrorOr<NonnullRefPtr<ColorSpace>> create(Document*, NonnullRefPtr<Object>, Renderer&);
|
|
|
|
static PDFErrorOr<NonnullRefPtr<ColorSpace>> create(DeprecatedFlyString const&, Renderer&);
|
|
|
|
static PDFErrorOr<NonnullRefPtr<ColorSpace>> create(Document*, NonnullRefPtr<ArrayObject>, Renderer&);
|
2022-03-24 20:08:08 +03:00
|
|
|
|
2021-05-28 00:01:37 +03:00
|
|
|
virtual ~ColorSpace() = default;
|
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
virtual PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const = 0;
|
|
|
|
virtual PDFErrorOr<ColorOrStyle> style(ReadonlySpan<Value> arguments) const
|
|
|
|
{
|
|
|
|
Vector<float, 4> float_arguments;
|
|
|
|
for (auto& argument : arguments)
|
|
|
|
float_arguments.append(argument.to_float());
|
|
|
|
return style(float_arguments);
|
|
|
|
}
|
|
|
|
|
2022-11-24 20:43:31 +03:00
|
|
|
virtual int number_of_components() const = 0;
|
2023-11-03 08:44:41 +03:00
|
|
|
virtual Vector<float> default_decode() const = 0; // "TABLE 4.40 Default Decode arrays"
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
virtual ColorSpaceFamily const& family() const = 0;
|
2021-05-28 00:01:37 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
class DeviceGrayColorSpace final : public ColorSpace {
|
|
|
|
public:
|
2022-03-06 03:52:00 +03:00
|
|
|
static NonnullRefPtr<DeviceGrayColorSpace> the();
|
2021-05-28 00:01:37 +03:00
|
|
|
|
2022-03-24 20:08:08 +03:00
|
|
|
~DeviceGrayColorSpace() override = default;
|
2021-05-28 00:01:37 +03:00
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const override;
|
2022-11-24 20:43:31 +03:00
|
|
|
int number_of_components() const override { return 1; }
|
|
|
|
Vector<float> default_decode() const override;
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
ColorSpaceFamily const& family() const override { return ColorSpaceFamily::DeviceGray; }
|
2021-05-28 00:01:37 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
DeviceGrayColorSpace() = default;
|
|
|
|
};
|
|
|
|
|
|
|
|
class DeviceRGBColorSpace final : public ColorSpace {
|
|
|
|
public:
|
2022-03-06 03:52:00 +03:00
|
|
|
static NonnullRefPtr<DeviceRGBColorSpace> the();
|
2021-05-28 00:01:37 +03:00
|
|
|
|
2022-03-24 20:08:08 +03:00
|
|
|
~DeviceRGBColorSpace() override = default;
|
2021-05-28 00:01:37 +03:00
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const override;
|
2022-11-24 20:43:31 +03:00
|
|
|
int number_of_components() const override { return 3; }
|
|
|
|
Vector<float> default_decode() const override;
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
ColorSpaceFamily const& family() const override { return ColorSpaceFamily::DeviceRGB; }
|
2021-05-28 00:01:37 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
DeviceRGBColorSpace() = default;
|
|
|
|
};
|
|
|
|
|
|
|
|
class DeviceCMYKColorSpace final : public ColorSpace {
|
|
|
|
public:
|
2022-03-06 03:52:00 +03:00
|
|
|
static NonnullRefPtr<DeviceCMYKColorSpace> the();
|
2021-05-28 00:01:37 +03:00
|
|
|
|
2022-03-24 20:08:08 +03:00
|
|
|
~DeviceCMYKColorSpace() override = default;
|
2021-05-28 00:01:37 +03:00
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const override;
|
2022-11-24 20:43:31 +03:00
|
|
|
int number_of_components() const override { return 4; }
|
|
|
|
Vector<float> default_decode() const override;
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
ColorSpaceFamily const& family() const override { return ColorSpaceFamily::DeviceCMYK; }
|
2021-05-28 00:01:37 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
DeviceCMYKColorSpace() = default;
|
|
|
|
};
|
|
|
|
|
2023-10-24 20:26:20 +03:00
|
|
|
class DeviceNColorSpace final : public ColorSpace {
|
|
|
|
public:
|
2023-12-07 16:45:44 +03:00
|
|
|
static PDFErrorOr<NonnullRefPtr<DeviceNColorSpace>> create(Document*, Vector<Value>&& parameters, Renderer&);
|
2023-10-24 20:26:20 +03:00
|
|
|
|
|
|
|
~DeviceNColorSpace() override = default;
|
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const override;
|
2023-10-24 20:26:20 +03:00
|
|
|
int number_of_components() const override;
|
|
|
|
Vector<float> default_decode() const override;
|
|
|
|
ColorSpaceFamily const& family() const override { return ColorSpaceFamily::DeviceN; }
|
|
|
|
|
|
|
|
private:
|
2023-11-06 15:54:59 +03:00
|
|
|
DeviceNColorSpace(NonnullRefPtr<ColorSpace>, NonnullRefPtr<Function>);
|
2023-10-24 20:26:20 +03:00
|
|
|
|
2023-12-16 17:19:34 +03:00
|
|
|
Vector<ByteString> m_names;
|
2023-11-06 15:54:59 +03:00
|
|
|
NonnullRefPtr<ColorSpace> m_alternate_space;
|
|
|
|
NonnullRefPtr<Function> m_tint_transform;
|
|
|
|
Vector<Value> mutable m_tint_output_values;
|
2023-10-24 20:26:20 +03:00
|
|
|
};
|
|
|
|
|
2023-11-02 15:49:34 +03:00
|
|
|
class CalGrayColorSpace final : public ColorSpace {
|
|
|
|
public:
|
|
|
|
static PDFErrorOr<NonnullRefPtr<CalGrayColorSpace>> create(Document*, Vector<Value>&& parameters);
|
|
|
|
|
|
|
|
~CalGrayColorSpace() override = default;
|
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const override;
|
2023-11-02 15:49:34 +03:00
|
|
|
int number_of_components() const override { return 1; }
|
|
|
|
Vector<float> default_decode() const override;
|
|
|
|
ColorSpaceFamily const& family() const override { return ColorSpaceFamily::CalGray; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
CalGrayColorSpace() = default;
|
|
|
|
|
|
|
|
Array<float, 3> m_whitepoint { 0, 0, 0 };
|
|
|
|
Array<float, 3> m_blackpoint { 0, 0, 0 };
|
|
|
|
float m_gamma { 1 };
|
|
|
|
};
|
|
|
|
|
2021-05-28 00:03:29 +03:00
|
|
|
class CalRGBColorSpace final : public ColorSpace {
|
|
|
|
public:
|
2022-03-24 20:08:08 +03:00
|
|
|
static PDFErrorOr<NonnullRefPtr<CalRGBColorSpace>> create(Document*, Vector<Value>&& parameters);
|
|
|
|
|
|
|
|
~CalRGBColorSpace() override = default;
|
2021-05-28 00:03:29 +03:00
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const override;
|
2022-11-24 20:43:31 +03:00
|
|
|
int number_of_components() const override { return 3; }
|
|
|
|
Vector<float> default_decode() const override;
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
ColorSpaceFamily const& family() const override { return ColorSpaceFamily::CalRGB; }
|
2021-05-28 00:03:29 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
CalRGBColorSpace() = default;
|
|
|
|
|
|
|
|
Array<float, 3> m_whitepoint { 0, 0, 0 };
|
|
|
|
Array<float, 3> m_blackpoint { 0, 0, 0 };
|
|
|
|
Array<float, 3> m_gamma { 1, 1, 1 };
|
|
|
|
Array<float, 9> m_matrix { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
|
|
|
|
};
|
|
|
|
|
2022-03-24 20:08:43 +03:00
|
|
|
class ICCBasedColorSpace final : public ColorSpace {
|
|
|
|
public:
|
2023-12-07 16:45:44 +03:00
|
|
|
static PDFErrorOr<NonnullRefPtr<ColorSpace>> create(Document*, Vector<Value>&& parameters, Renderer&);
|
2022-03-24 20:08:43 +03:00
|
|
|
|
|
|
|
~ICCBasedColorSpace() override = default;
|
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const override;
|
2023-10-20 04:54:34 +03:00
|
|
|
int number_of_components() const override;
|
2022-11-24 20:43:31 +03:00
|
|
|
Vector<float> default_decode() const override;
|
LibPDF: Refactor parsing of ColorSpaces
ColorSpaces can be specified in two ways: with a stream as operands of
the color space operations (CS/cs), or as a separate PDF object, which
is then referred to by other means (e.g., from Image XObjects and other
entities). These two modes of addressing a ColorSpace are slightly
different and need to be addressed separately. However, the current
implementation embedded the full logic of the first case in the routine
that created ColorSpace objects.
This commit refactors the creation of ColorSpace to support both cases.
First, a new ColorSpaceFamily class encapsulates the static aspects of a
family, like its name or whether color space construction never requires
parameters. Then we define the supported ColorSpaceFamily objects.
On top of this also sit a breakage on how ColorSpaces are created. Two
methods are now offered: one only providing construction of no-argument
color spaces (and thus taking a simple name), and another taking an
ArrayObject, hence used to create ColorSpaces requiring arguments.
Finally, on top of *that* two ways to get a color space in the Renderer
are made available: the first creates a ColorSpace with a name and a
Resources dictionary, and another takes an Object. These model the two
addressing modes described above.
2022-11-24 07:40:24 +03:00
|
|
|
ColorSpaceFamily const& family() const override { return ColorSpaceFamily::ICCBased; }
|
2022-03-24 20:08:43 +03:00
|
|
|
|
2023-10-20 15:17:14 +03:00
|
|
|
static NonnullRefPtr<Gfx::ICC::Profile> sRGB();
|
|
|
|
|
2022-03-24 20:08:43 +03:00
|
|
|
private:
|
2023-07-19 04:35:49 +03:00
|
|
|
ICCBasedColorSpace(NonnullRefPtr<Gfx::ICC::Profile>);
|
|
|
|
|
|
|
|
static RefPtr<Gfx::ICC::Profile> s_srgb_profile;
|
|
|
|
NonnullRefPtr<Gfx::ICC::Profile> m_profile;
|
2024-01-09 04:22:22 +03:00
|
|
|
mutable Vector<float, 4> m_components;
|
|
|
|
mutable Vector<u8, 4> m_bytes;
|
2024-01-09 03:52:14 +03:00
|
|
|
Optional<Gfx::ICC::MatrixMatrixConversion> m_map;
|
2022-03-24 20:08:43 +03:00
|
|
|
};
|
|
|
|
|
2023-10-24 21:13:04 +03:00
|
|
|
class LabColorSpace final : public ColorSpace {
|
|
|
|
public:
|
|
|
|
static PDFErrorOr<NonnullRefPtr<LabColorSpace>> create(Document*, Vector<Value>&& parameters);
|
|
|
|
|
|
|
|
~LabColorSpace() override = default;
|
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const override;
|
2023-10-24 21:13:04 +03:00
|
|
|
int number_of_components() const override { return 3; }
|
|
|
|
Vector<float> default_decode() const override;
|
|
|
|
ColorSpaceFamily const& family() const override { return ColorSpaceFamily::Lab; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
LabColorSpace() = default;
|
2023-11-02 16:52:43 +03:00
|
|
|
|
|
|
|
Array<float, 3> m_whitepoint { 0, 0, 0 };
|
|
|
|
Array<float, 3> m_blackpoint { 0, 0, 0 };
|
|
|
|
Array<float, 4> m_range { -100, 100, -100, 100 };
|
2023-10-24 21:13:04 +03:00
|
|
|
};
|
|
|
|
|
2023-11-03 08:49:04 +03:00
|
|
|
class IndexedColorSpace final : public ColorSpace {
|
|
|
|
public:
|
2023-12-07 16:45:44 +03:00
|
|
|
static PDFErrorOr<NonnullRefPtr<ColorSpace>> create(Document*, Vector<Value>&& parameters, Renderer&);
|
2023-11-03 08:49:04 +03:00
|
|
|
|
|
|
|
~IndexedColorSpace() override = default;
|
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const override;
|
2023-11-03 08:49:04 +03:00
|
|
|
int number_of_components() const override { return 1; }
|
|
|
|
Vector<float> default_decode() const override;
|
|
|
|
ColorSpaceFamily const& family() const override { return ColorSpaceFamily::Indexed; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
IndexedColorSpace(NonnullRefPtr<ColorSpace>);
|
|
|
|
|
|
|
|
NonnullRefPtr<ColorSpace> m_base;
|
|
|
|
int m_hival { 0 };
|
|
|
|
Vector<u8> m_lookup;
|
|
|
|
};
|
|
|
|
|
2023-07-23 23:55:10 +03:00
|
|
|
class SeparationColorSpace final : public ColorSpace {
|
|
|
|
public:
|
2023-12-07 16:45:44 +03:00
|
|
|
static PDFErrorOr<NonnullRefPtr<SeparationColorSpace>> create(Document*, Vector<Value>&& parameters, Renderer&);
|
2023-07-23 23:55:10 +03:00
|
|
|
|
|
|
|
~SeparationColorSpace() override = default;
|
|
|
|
|
2024-01-09 05:36:21 +03:00
|
|
|
PDFErrorOr<ColorOrStyle> style(ReadonlySpan<float> arguments) const override;
|
2023-10-24 20:39:58 +03:00
|
|
|
int number_of_components() const override { return 1; }
|
2023-07-23 23:55:10 +03:00
|
|
|
Vector<float> default_decode() const override;
|
|
|
|
ColorSpaceFamily const& family() const override { return ColorSpaceFamily::Separation; }
|
|
|
|
|
|
|
|
private:
|
2023-11-04 23:02:28 +03:00
|
|
|
SeparationColorSpace(NonnullRefPtr<ColorSpace>, NonnullRefPtr<Function>);
|
|
|
|
|
2023-12-16 17:19:34 +03:00
|
|
|
ByteString m_name;
|
2023-11-04 23:02:28 +03:00
|
|
|
NonnullRefPtr<ColorSpace> m_alternate_space;
|
|
|
|
NonnullRefPtr<Function> m_tint_transform;
|
|
|
|
Vector<Value> mutable m_tint_output_values;
|
2023-07-23 23:55:10 +03:00
|
|
|
};
|
2021-05-28 00:01:37 +03:00
|
|
|
}
|