mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:17:44 +00:00
LibPDF: Split ColorSpace into a different class for each color space
While unnecessary at the moment, this will allow for more fine-grained control when complex color spaces get added.
This commit is contained in:
parent
ea3abb14fe
commit
7b4e36bf88
7 changed files with 174 additions and 106 deletions
|
@ -7,8 +7,6 @@
|
|||
#include <AK/Utf8View.h>
|
||||
#include <LibPDF/CommonNames.h>
|
||||
#include <LibPDF/Renderer.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
|
||||
#define RENDERER_HANDLER(name) \
|
||||
void Renderer::handle_##name([[maybe_unused]] const Vector<Value>& args)
|
||||
|
@ -22,58 +20,6 @@
|
|||
|
||||
namespace PDF {
|
||||
|
||||
Optional<ColorSpace::Type> ColorSpace::color_space_from_string(const FlyString& str)
|
||||
{
|
||||
#define ENUM(name) \
|
||||
if (str == #name) \
|
||||
return ColorSpace::Type::name;
|
||||
ENUMERATE_COLOR_SPACES(ENUM)
|
||||
#undef ENUM
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Color ColorSpace::default_color_for_color_space(ColorSpace::Type color_space)
|
||||
{
|
||||
switch (color_space) {
|
||||
case Type::DeviceGray:
|
||||
case Type::DeviceRGB:
|
||||
return Color::NamedColor::Black;
|
||||
case Type::DeviceCMYK:
|
||||
return Color::from_cmyk(1.0f, 1.0f, 1.0f, 0.0f);
|
||||
default:
|
||||
TODO();
|
||||
}
|
||||
}
|
||||
|
||||
Color ColorSpace::color_from_parameters(ColorSpace::Type color_space, const Vector<Value>& args)
|
||||
{
|
||||
switch (color_space) {
|
||||
case Type::DeviceGray: {
|
||||
VERIFY(args.size() == 1);
|
||||
auto gray = static_cast<u8>(args[0].to_float() * 255.0f);
|
||||
return Color(gray, gray, gray);
|
||||
}
|
||||
case Type::DeviceRGB: {
|
||||
VERIFY(args.size() == 3);
|
||||
auto r = static_cast<u8>(args[0].to_float() * 255.0f);
|
||||
auto g = static_cast<u8>(args[1].to_float() * 255.0f);
|
||||
auto b = static_cast<u8>(args[2].to_float() * 255.0f);
|
||||
return Color(r, g, b);
|
||||
}
|
||||
case Type::DeviceCMYK: {
|
||||
VERIFY(args.size() == 4);
|
||||
auto c = args[0].to_float();
|
||||
auto m = args[1].to_float();
|
||||
auto y = args[2].to_float();
|
||||
auto k = args[3].to_float();
|
||||
return Color::from_cmyk(c, m, y, k);
|
||||
}
|
||||
default:
|
||||
TODO();
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::render(Document& document, const Page& page, RefPtr<Gfx::Bitmap> bitmap)
|
||||
{
|
||||
Renderer(document, page, bitmap).render();
|
||||
|
@ -438,63 +384,63 @@ RENDERER_TODO(type3_font_set_glyph_width_and_bbox);
|
|||
RENDERER_HANDLER(set_stroking_space)
|
||||
{
|
||||
state().stroke_color_space = get_color_space(args[0]);
|
||||
state().stroke_color = ColorSpace::default_color_for_color_space(state().stroke_color_space);
|
||||
VERIFY(state().stroke_color_space);
|
||||
}
|
||||
|
||||
RENDERER_HANDLER(set_painting_space)
|
||||
{
|
||||
state().paint_color_space = get_color_space(args[0]);
|
||||
state().paint_color = ColorSpace::default_color_for_color_space(state().paint_color_space);
|
||||
VERIFY(state().paint_color_space);
|
||||
}
|
||||
|
||||
RENDERER_HANDLER(set_stroking_color)
|
||||
{
|
||||
state().stroke_color = ColorSpace::color_from_parameters(state().stroke_color_space, args);
|
||||
state().stroke_color = state().stroke_color_space->color(args);
|
||||
}
|
||||
|
||||
RENDERER_TODO(set_stroking_color_extended);
|
||||
|
||||
RENDERER_HANDLER(set_painting_color)
|
||||
{
|
||||
state().paint_color = ColorSpace::color_from_parameters(state().paint_color_space, args);
|
||||
state().paint_color = state().paint_color_space->color(args);
|
||||
}
|
||||
|
||||
RENDERER_TODO(set_painting_color_extended);
|
||||
|
||||
RENDERER_HANDLER(set_stroking_color_and_space_to_gray)
|
||||
{
|
||||
state().stroke_color_space = ColorSpace::Type::DeviceGray;
|
||||
state().stroke_color = ColorSpace::color_from_parameters(ColorSpace::Type::DeviceGray, args);
|
||||
state().stroke_color_space = DeviceGrayColorSpace::the();
|
||||
state().stroke_color = state().stroke_color_space->color(args);
|
||||
}
|
||||
|
||||
RENDERER_HANDLER(set_painting_color_and_space_to_gray)
|
||||
{
|
||||
state().paint_color_space = ColorSpace::Type::DeviceGray;
|
||||
state().paint_color = ColorSpace::color_from_parameters(ColorSpace::Type::DeviceGray, args);
|
||||
state().paint_color_space = DeviceGrayColorSpace::the();
|
||||
state().paint_color = state().paint_color_space->color(args);
|
||||
}
|
||||
|
||||
RENDERER_HANDLER(set_stroking_color_and_space_to_rgb)
|
||||
{
|
||||
state().stroke_color_space = ColorSpace::Type::DeviceRGB;
|
||||
state().stroke_color = ColorSpace::color_from_parameters(ColorSpace::Type::DeviceRGB, args);
|
||||
state().stroke_color_space = DeviceRGBColorSpace::the();
|
||||
state().stroke_color = state().stroke_color_space->color(args);
|
||||
}
|
||||
|
||||
RENDERER_HANDLER(set_painting_color_and_space_to_rgb)
|
||||
{
|
||||
state().paint_color_space = ColorSpace::Type::DeviceRGB;
|
||||
state().paint_color = ColorSpace::color_from_parameters(ColorSpace::Type::DeviceRGB, args);
|
||||
state().paint_color_space = DeviceRGBColorSpace::the();
|
||||
state().paint_color = state().paint_color_space->color(args);
|
||||
}
|
||||
|
||||
RENDERER_HANDLER(set_stroking_color_and_space_to_cmyk)
|
||||
{
|
||||
state().stroke_color_space = ColorSpace::Type::DeviceCMYK;
|
||||
state().stroke_color = ColorSpace::color_from_parameters(ColorSpace::Type::DeviceCMYK, args);
|
||||
state().stroke_color_space = DeviceCMYKColorSpace::the();
|
||||
state().stroke_color = state().stroke_color_space->color(args);
|
||||
}
|
||||
|
||||
RENDERER_HANDLER(set_painting_color_and_space_to_cmyk)
|
||||
{
|
||||
state().paint_color_space = ColorSpace::Type::DeviceCMYK;
|
||||
state().paint_color = ColorSpace::color_from_parameters(ColorSpace::Type::DeviceCMYK, args);
|
||||
state().paint_color_space = DeviceCMYKColorSpace::the();
|
||||
state().paint_color = state().paint_color_space->color(args);
|
||||
}
|
||||
|
||||
RENDERER_TODO(shade);
|
||||
|
@ -560,16 +506,19 @@ void Renderer::show_text(const String& string, int shift)
|
|||
}
|
||||
}
|
||||
|
||||
ColorSpace::Type Renderer::get_color_space(const Value& value)
|
||||
RefPtr<ColorSpace> Renderer::get_color_space(const Value& value)
|
||||
{
|
||||
auto name = object_cast<NameObject>(value.as_object())->name();
|
||||
auto color_space_opt = ColorSpace::color_space_from_string(name);
|
||||
if (!color_space_opt.has_value()) {
|
||||
// The name is probably a key into the resource dictionary
|
||||
TODO();
|
||||
}
|
||||
|
||||
return color_space_opt.value();
|
||||
// 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();
|
||||
|
||||
TODO();
|
||||
}
|
||||
|
||||
const Gfx::AffineTransform& Renderer::calculate_text_rendering_matrix()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue