Skip to content

Commit

Permalink
Remove pre_scale. Use affine transforms instead to properly address d…
Browse files Browse the repository at this point in the history
…evice_to_user and user_to_device conversions.
  • Loading branch information
djowel committed Mar 10, 2024
1 parent 9f57012 commit 4986836
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 45 deletions.
17 changes: 2 additions & 15 deletions lib/impl/macos/quartz2d/canvas.mm
Original file line number Diff line number Diff line change
Expand Up @@ -233,20 +233,6 @@ void make_gradient(std::vector<canvas::color_stop> const& space, CGGradientRef&
{
}

void canvas::pre_scale(float sc)
{
// Quartz-2D does not need to be pre-scaled because it already does this
// when setting up its context. But see how we take the actual pre-scale
// in the constructor.
}

float canvas::pre_scale() const
{
// Quartz-2D does not need to be pre-scaled because it already does this
// when setting up its context.
return 1.0; // Pre-scale is always 1.0
}

void canvas::translate(point p)
{
CGContextTranslateCTM(CGContextRef(_context), p.x, p.y);
Expand Down Expand Up @@ -621,8 +607,9 @@ void round_rect(canvas& c, rect bounds, float radius)

void canvas::shadow_style(point offset, float blur, color c)
{
auto [scx, scy] = device_to_user({1.0, 1.0});
CGContextSetShadowWithColor(
CGContextRef(_context), CGSizeMake(offset.x, -offset.y), blur,
CGContextRef(_context), CGSizeMake(offset.x/scx, -offset.y/scx), blur,
[
[NSColor
colorWithRed : c.red
Expand Down
61 changes: 34 additions & 27 deletions lib/impl/skia/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ namespace cycfi::artist

void save();
void restore();

float _pre_scale = 1.0;
affine_transform get_inv_affine() const;
void set_inv_affine(affine_transform xf);

static SkPaint& get_fill_paint(canvas const& cnv);

Expand Down Expand Up @@ -79,6 +79,7 @@ namespace cycfi::artist

state_info_stack _stack;
SkPaint _clear_paint;
affine_transform _inv_affine;
};

canvas::canvas_state::canvas_state()
Expand Down Expand Up @@ -135,25 +136,25 @@ namespace cycfi::artist
return cnv._state->fill_paint();
}

canvas::canvas(canvas_impl* context_)
: _context{context_}
, _state{std::make_unique<canvas_state>()}
affine_transform canvas::canvas_state::get_inv_affine() const
{
return _inv_affine;
}

canvas::~canvas()
void canvas::canvas_state::set_inv_affine(affine_transform xf)
{
_inv_affine = xf;
}

void canvas::pre_scale(float sc)
canvas::canvas(canvas_impl* context_)
: _context{context_}
, _state{std::make_unique<canvas_state>()}
{
scale(sc, sc);
_state->_pre_scale = sc;
_state->set_inv_affine(transform().invert());
}

float canvas::pre_scale() const
canvas::~canvas()
{
return _state->_pre_scale;
}

void canvas::translate(point p)
Expand All @@ -178,21 +179,30 @@ namespace cycfi::artist

point canvas::device_to_user(point p)
{
auto scale = _state->_pre_scale;
auto mat = _context->getTotalMatrix();
(void) mat.invert(&mat);
SkPoint skp;
mat.mapXY(p.x * scale, p.y * scale, &skp);
return {skp.x(), skp.y()};
// Get the current transform
auto af = transform();

// Undo the initial transform
auto xaf = af * _state->get_inv_affine();

// Map the point to the inverted `xaf` transform
auto up = xaf.invert().apply(p);

return {float(up.x), float(up.y)};
}

point canvas::user_to_device(point p)
{
auto scale = _state->_pre_scale;
auto mat = _context->getTotalMatrix();
SkPoint skp;
mat.mapXY(p.x, p.y, &skp);
return {skp.x() / scale, skp.y() / scale};
// Get the current transform
auto af = transform();

// Undo the initial transform
auto xaf = af * _state->get_inv_affine();

// Map the point to the `xaf` transform
auto up = xaf.apply(p);

return {float(up.x), float(up.y)};
}

affine_transform canvas::transform() const
Expand Down Expand Up @@ -392,11 +402,8 @@ namespace cycfi::artist

void canvas::shadow_style(point offset, float blur, color c)
{
constexpr auto blur_factor = 0.4f;

auto matrix = _context->getTotalMatrix();
auto scx = matrix.getScaleX() / _state->_pre_scale;
auto scy = matrix.getScaleY() / _state->_pre_scale;
constexpr auto blur_factor = 1.0f;
auto [scx, scy] = device_to_user({1.0, 1.0});

auto shadow = SkImageFilters::DropShadow(
offset.x / scx
Expand Down
3 changes: 0 additions & 3 deletions lib/include/artist/canvas.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ namespace cycfi::artist
explicit operator bool() const;
bool operator!() const;

void pre_scale(float sc);
float pre_scale() const;

///////////////////////////////////////////////////////////////////////////////////
// Transforms
void translate(point p);
Expand Down

0 comments on commit 4986836

Please sign in to comment.