Skip to content

Commit 4fc28d5

Browse files
committed
Add zoom out (related to issue #33)
Before the zoom was handle as a bits shift (scaled = value << zoom), now the zoom is a fraction (scaled = value * zoom.num / zoom.den). Changes: * Add Zoom class to apply/remove zoom factor * Split merge_zoomed_image template function into merge_zoomed_image_scale_down and merge_zoomed_image_scale_up to handle the special case where zoom.num/zoom.den < 1.0
1 parent 17b0bee commit 4fc28d5

23 files changed

Lines changed: 367 additions & 148 deletions

src/app/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,5 @@ add_library(app-lib
259259
webserver.cpp
260260
widget_loader.cpp
261261
xml_document.cpp
262-
xml_exception.cpp)
262+
xml_exception.cpp
263+
zoom.cpp)

src/app/commands/cmd_move_mask.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,13 @@ void MoveMaskCommand::onExecute(Context* context)
9999
pixels = gridBounds.h;
100100
break;
101101
case ZoomedPixel:
102-
pixels = 1 << current_editor->zoom();
102+
pixels = current_editor->zoom().apply(1);
103103
break;
104104
case ZoomedTileWidth:
105-
pixels = gridBounds.w << current_editor->zoom();
105+
pixels = current_editor->zoom().apply(gridBounds.w);
106106
break;
107107
case ZoomedTileHeight:
108-
pixels = gridBounds.h << current_editor->zoom();
108+
pixels = current_editor->zoom().apply(gridBounds.h);
109109
break;
110110
case ViewportWidth:
111111
pixels = vp.h;

src/app/commands/cmd_preview.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class PreviewWindow : public Window {
6363
, m_pal(m_sprite->getPalette(editor->frame()))
6464
, m_index_bg_color(-1)
6565
, m_doublebuf(Image::create(IMAGE_RGB, ui::display_w(), ui::display_h()))
66-
, m_doublesur(she::instance()->createRgbaSurface(ui::display_w(), ui::display_h())) {
66+
, m_doublesur(she::instance()->createRgbaSurface(ui::display_w(), ui::display_h()))
67+
, m_zoom(editor->zoom()) {
6768
// Do not use DocumentWriter (do not lock the document) because we
6869
// will call other sub-commands (e.g. previous frame, next frame,
6970
// etc.).
@@ -83,7 +84,6 @@ class PreviewWindow : public Window {
8384
m_oldMousePos = ui::get_mouse_position();
8485
m_pos.x = -scroll.x + vp.x + editor->offsetX();
8586
m_pos.y = -scroll.y + vp.y + editor->offsetY();
86-
m_zoom = editor->zoom();
8787

8888
setFocusStop(true);
8989
captureMouse();
@@ -193,14 +193,14 @@ class PreviewWindow : public Window {
193193
m_render.reset(
194194
renderEngine.renderSprite(
195195
0, 0, m_sprite->width(), m_sprite->height(),
196-
m_editor->frame(), 0, false, false));
196+
m_editor->frame(), Zoom(1, 1), false, false));
197197
}
198198

199199
int x, y, w, h, u, v;
200-
x = m_pos.x + ((m_delta.x >> m_zoom) << m_zoom);
201-
y = m_pos.y + ((m_delta.y >> m_zoom) << m_zoom);
202-
w = (m_sprite->width()<<m_zoom);
203-
h = (m_sprite->height()<<m_zoom);
200+
x = m_pos.x + m_zoom.apply(m_zoom.remove(m_delta.x));
201+
y = m_pos.y + m_zoom.apply(m_zoom.remove(m_delta.y));
202+
w = m_zoom.apply(m_sprite->width());
203+
h = m_zoom.apply(m_sprite->height());
204204

205205
if (m_tiled & TILED_X_AXIS) x = SGN(x) * (ABS(x)%w);
206206
if (m_tiled & TILED_Y_AXIS) y = SGN(y) * (ABS(y)%h);
@@ -243,7 +243,7 @@ class PreviewWindow : public Window {
243243
gfx::Point m_pos;
244244
gfx::Point m_oldMousePos;
245245
gfx::Point m_delta;
246-
int m_zoom;
246+
Zoom m_zoom;
247247
int m_index_bg_color;
248248
base::UniquePtr<Image> m_render;
249249
base::UniquePtr<Image> m_doublebuf;

src/app/commands/cmd_scroll.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,13 @@ void ScrollCommand::onExecute(Context* context)
117117
pixels = gridBounds.h;
118118
break;
119119
case ZoomedPixel:
120-
pixels = 1 << current_editor->zoom();
120+
pixels = current_editor->zoom().apply(1);
121121
break;
122122
case ZoomedTileWidth:
123-
pixels = gridBounds.w << current_editor->zoom();
123+
pixels = current_editor->zoom().apply(gridBounds.w);
124124
break;
125125
case ZoomedTileHeight:
126-
pixels = gridBounds.h << current_editor->zoom();
126+
pixels = current_editor->zoom().apply(gridBounds.h);
127127
break;
128128
case ViewportWidth:
129129
pixels = vp.h;

src/app/commands/cmd_zoom.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,23 @@ bool ZoomCommand::onEnabled(Context* context)
7474

7575
void ZoomCommand::onExecute(Context* context)
7676
{
77-
int zoom = current_editor->zoom();
77+
Zoom zoom = current_editor->zoom();
7878

7979
switch (m_action) {
8080
case In:
81-
if (zoom < 5)
82-
++zoom;
81+
zoom.in();
8382
break;
8483
case Out:
85-
if (zoom > 0)
86-
--zoom;
84+
zoom.out();
8785
break;
8886
case Set:
8987
switch (m_percentage) {
90-
case 3200: zoom = 5; break;
91-
case 1600: zoom = 4; break;
92-
case 800: zoom = 3; break;
93-
case 400: zoom = 2; break;
94-
case 200: zoom = 1; break;
95-
default: zoom = 0; break;
88+
case 3200: zoom = Zoom(32, 1); break;
89+
case 1600: zoom = Zoom(16, 1); break;
90+
case 800: zoom = Zoom(8, 1); break;
91+
case 400: zoom = Zoom(4, 1); break;
92+
case 200: zoom = Zoom(2, 1); break;
93+
default: zoom = Zoom(1, 1); break;
9694
}
9795
break;
9896
}

src/app/commands/filters/filter_manager_impl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,8 @@ void FilterManagerImpl::flush()
257257
m_x+m_offset_x,
258258
m_y+m_offset_y+m_row-1)),
259259
gfx::Size(
260-
(m_w << editor->zoom()),
261-
(1 << editor->zoom())));
260+
editor->zoom().apply(m_w),
261+
editor->zoom().apply(1)));
262262

263263
gfx::Region reg1(rect);
264264
gfx::Region reg2;

src/app/thumbnail_generator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class ThumbnailGenerator::Worker {
8585

8686
base::UniquePtr<Image> image(renderEngine.renderSprite(
8787
0, 0, sprite->width(), sprite->height(),
88-
FrameNumber(0), 0, true, false));
88+
FrameNumber(0), Zoom(1, 1), true, false));
8989

9090
// Calculate the thumbnail size
9191
int thumb_w = MAX_THUMBNAIL_SIZE * image->width() / MAX(image->width(), image->height());

src/app/tools/tool_loop.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "app/settings/selection_mode.h"
2424
#include "app/tools/trace_policy.h"
25+
#include "app/zoom.h"
2526
#include "doc/frame_number.h"
2627
#include "filters/tiled_mode.h"
2728
#include "gfx/point.h"
@@ -104,6 +105,9 @@ namespace app {
104105
// Gets mask X,Y origin coordinates
105106
virtual gfx::Point getMaskOrigin() = 0;
106107

108+
// Returns the zoom
109+
virtual const Zoom& zoom() = 0;
110+
107111
// Return the mouse button which start the tool-loop. It can be used
108112
// by some tools that instead of using the primary/secondary color
109113
// uses the pressed button for different behavior (like selection

src/app/tools/tool_loop_manager.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ void ToolLoopManager::doLoopStep(bool last_step)
213213

214214
// Calculate the area to be updated in all document observers.
215215
Region& dirty_area = m_toolLoop->getDirtyArea();
216-
calculateDirtyArea(m_toolLoop, points_to_interwine, dirty_area);
216+
calculateDirtyArea(points_to_interwine, dirty_area);
217217

218218
if (m_toolLoop->getTracePolicy() == TracePolicyLast) {
219219
Region prev_dirty_area = dirty_area;
@@ -235,7 +235,7 @@ void ToolLoopManager::snapToGrid(Point& point)
235235
m_toolLoop->getDocumentSettings()->snapToGrid(point);
236236
}
237237

238-
void ToolLoopManager::calculateDirtyArea(ToolLoop* loop, const Points& points, Region& dirty_area)
238+
void ToolLoopManager::calculateDirtyArea(const Points& points, Region& dirty_area)
239239
{
240240
dirty_area.clear();
241241

@@ -245,21 +245,21 @@ void ToolLoopManager::calculateDirtyArea(ToolLoop* loop, const Points& points, R
245245

246246
// Expand the dirty-area with the pen width
247247
Rect r1, r2;
248-
loop->getPointShape()->getModifiedArea(loop, minpt.x, minpt.y, r1);
249-
loop->getPointShape()->getModifiedArea(loop, maxpt.x, maxpt.y, r2);
248+
m_toolLoop->getPointShape()->getModifiedArea(m_toolLoop, minpt.x, minpt.y, r1);
249+
m_toolLoop->getPointShape()->getModifiedArea(m_toolLoop, maxpt.x, maxpt.y, r2);
250250

251251
dirty_area.createUnion(dirty_area, Region(r1.createUnion(r2)));
252252
}
253253

254254
// Apply offset mode
255-
Point offset(loop->getOffset());
255+
Point offset(m_toolLoop->getOffset());
256256
dirty_area.offset(-offset);
257257

258258
// Apply tiled mode
259-
TiledMode tiledMode = loop->getDocumentSettings()->getTiledMode();
259+
TiledMode tiledMode = m_toolLoop->getDocumentSettings()->getTiledMode();
260260
if (tiledMode != TILED_NONE) {
261-
int w = loop->sprite()->width();
262-
int h = loop->sprite()->height();
261+
int w = m_toolLoop->sprite()->width();
262+
int h = m_toolLoop->sprite()->height();
263263
Region sprite_area(Rect(0, 0, w, h));
264264
Region outside;
265265
outside.createSubtraction(dirty_area, sprite_area);
@@ -312,6 +312,11 @@ void ToolLoopManager::calculateMinMax(const Points& points, Point& minpt, Point&
312312
maxpt.x = MAX(maxpt.x, points[c].x);
313313
maxpt.y = MAX(maxpt.y, points[c].y);
314314
}
315+
316+
if (m_toolLoop->zoom().scale() < 1.0) {
317+
maxpt.x += m_toolLoop->zoom().remove(1);
318+
maxpt.y += m_toolLoop->zoom().remove(1);
319+
}
315320
}
316321

317322
} // namespace tools

src/app/tools/tool_loop_manager.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,13 @@ namespace app {
103103
void doLoopStep(bool last_step);
104104
void snapToGrid(gfx::Point& point);
105105

106-
static void calculateDirtyArea(ToolLoop* loop,
107-
const Points& points,
108-
gfx::Region& dirty_area);
106+
void calculateDirtyArea(
107+
const Points& points,
108+
gfx::Region& dirty_area);
109109

110-
static void calculateMinMax(const Points& points,
111-
gfx::Point& minpt,
112-
gfx::Point& maxpt);
110+
void calculateMinMax(const Points& points,
111+
gfx::Point& minpt,
112+
gfx::Point& maxpt);
113113

114114
ToolLoop* m_toolLoop;
115115
Points m_points;

0 commit comments

Comments
 (0)