Skip to content

Commit

Permalink
Add zoom out (related to issue #33)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dacap committed Nov 24, 2014
1 parent 17b0bee commit 4fc28d5
Show file tree
Hide file tree
Showing 23 changed files with 367 additions and 148 deletions.
3 changes: 2 additions & 1 deletion src/app/CMakeLists.txt
Expand Up @@ -259,4 +259,5 @@ add_library(app-lib
webserver.cpp
widget_loader.cpp
xml_document.cpp
xml_exception.cpp)
xml_exception.cpp
zoom.cpp)
6 changes: 3 additions & 3 deletions src/app/commands/cmd_move_mask.cpp
Expand Up @@ -99,13 +99,13 @@ void MoveMaskCommand::onExecute(Context* context)
pixels = gridBounds.h;
break;
case ZoomedPixel:
pixels = 1 << current_editor->zoom();
pixels = current_editor->zoom().apply(1);
break;
case ZoomedTileWidth:
pixels = gridBounds.w << current_editor->zoom();
pixels = current_editor->zoom().apply(gridBounds.w);
break;
case ZoomedTileHeight:
pixels = gridBounds.h << current_editor->zoom();
pixels = current_editor->zoom().apply(gridBounds.h);
break;
case ViewportWidth:
pixels = vp.h;
Expand Down
16 changes: 8 additions & 8 deletions src/app/commands/cmd_preview.cpp
Expand Up @@ -63,7 +63,8 @@ class PreviewWindow : public Window {
, m_pal(m_sprite->getPalette(editor->frame()))
, m_index_bg_color(-1)
, m_doublebuf(Image::create(IMAGE_RGB, ui::display_w(), ui::display_h()))
, m_doublesur(she::instance()->createRgbaSurface(ui::display_w(), ui::display_h())) {
, m_doublesur(she::instance()->createRgbaSurface(ui::display_w(), ui::display_h()))
, m_zoom(editor->zoom()) {
// Do not use DocumentWriter (do not lock the document) because we
// will call other sub-commands (e.g. previous frame, next frame,
// etc.).
Expand All @@ -83,7 +84,6 @@ class PreviewWindow : public Window {
m_oldMousePos = ui::get_mouse_position();
m_pos.x = -scroll.x + vp.x + editor->offsetX();
m_pos.y = -scroll.y + vp.y + editor->offsetY();
m_zoom = editor->zoom();

setFocusStop(true);
captureMouse();
Expand Down Expand Up @@ -193,14 +193,14 @@ class PreviewWindow : public Window {
m_render.reset(
renderEngine.renderSprite(
0, 0, m_sprite->width(), m_sprite->height(),
m_editor->frame(), 0, false, false));
m_editor->frame(), Zoom(1, 1), false, false));
}

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

if (m_tiled & TILED_X_AXIS) x = SGN(x) * (ABS(x)%w);
if (m_tiled & TILED_Y_AXIS) y = SGN(y) * (ABS(y)%h);
Expand Down Expand Up @@ -243,7 +243,7 @@ class PreviewWindow : public Window {
gfx::Point m_pos;
gfx::Point m_oldMousePos;
gfx::Point m_delta;
int m_zoom;
Zoom m_zoom;
int m_index_bg_color;
base::UniquePtr<Image> m_render;
base::UniquePtr<Image> m_doublebuf;
Expand Down
6 changes: 3 additions & 3 deletions src/app/commands/cmd_scroll.cpp
Expand Up @@ -117,13 +117,13 @@ void ScrollCommand::onExecute(Context* context)
pixels = gridBounds.h;
break;
case ZoomedPixel:
pixels = 1 << current_editor->zoom();
pixels = current_editor->zoom().apply(1);
break;
case ZoomedTileWidth:
pixels = gridBounds.w << current_editor->zoom();
pixels = current_editor->zoom().apply(gridBounds.w);
break;
case ZoomedTileHeight:
pixels = gridBounds.h << current_editor->zoom();
pixels = current_editor->zoom().apply(gridBounds.h);
break;
case ViewportWidth:
pixels = vp.h;
Expand Down
20 changes: 9 additions & 11 deletions src/app/commands/cmd_zoom.cpp
Expand Up @@ -74,25 +74,23 @@ bool ZoomCommand::onEnabled(Context* context)

void ZoomCommand::onExecute(Context* context)
{
int zoom = current_editor->zoom();
Zoom zoom = current_editor->zoom();

switch (m_action) {
case In:
if (zoom < 5)
++zoom;
zoom.in();
break;
case Out:
if (zoom > 0)
--zoom;
zoom.out();
break;
case Set:
switch (m_percentage) {
case 3200: zoom = 5; break;
case 1600: zoom = 4; break;
case 800: zoom = 3; break;
case 400: zoom = 2; break;
case 200: zoom = 1; break;
default: zoom = 0; break;
case 3200: zoom = Zoom(32, 1); break;
case 1600: zoom = Zoom(16, 1); break;
case 800: zoom = Zoom(8, 1); break;
case 400: zoom = Zoom(4, 1); break;
case 200: zoom = Zoom(2, 1); break;
default: zoom = Zoom(1, 1); break;
}
break;
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/commands/filters/filter_manager_impl.cpp
Expand Up @@ -257,8 +257,8 @@ void FilterManagerImpl::flush()
m_x+m_offset_x,
m_y+m_offset_y+m_row-1)),
gfx::Size(
(m_w << editor->zoom()),
(1 << editor->zoom())));
editor->zoom().apply(m_w),
editor->zoom().apply(1)));

gfx::Region reg1(rect);
gfx::Region reg2;
Expand Down
2 changes: 1 addition & 1 deletion src/app/thumbnail_generator.cpp
Expand Up @@ -85,7 +85,7 @@ class ThumbnailGenerator::Worker {

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

// Calculate the thumbnail size
int thumb_w = MAX_THUMBNAIL_SIZE * image->width() / MAX(image->width(), image->height());
Expand Down
4 changes: 4 additions & 0 deletions src/app/tools/tool_loop.h
Expand Up @@ -22,6 +22,7 @@

#include "app/settings/selection_mode.h"
#include "app/tools/trace_policy.h"
#include "app/zoom.h"
#include "doc/frame_number.h"
#include "filters/tiled_mode.h"
#include "gfx/point.h"
Expand Down Expand Up @@ -104,6 +105,9 @@ namespace app {
// Gets mask X,Y origin coordinates
virtual gfx::Point getMaskOrigin() = 0;

// Returns the zoom
virtual const Zoom& zoom() = 0;

// Return the mouse button which start the tool-loop. It can be used
// by some tools that instead of using the primary/secondary color
// uses the pressed button for different behavior (like selection
Expand Down
21 changes: 13 additions & 8 deletions src/app/tools/tool_loop_manager.cpp
Expand Up @@ -213,7 +213,7 @@ void ToolLoopManager::doLoopStep(bool last_step)

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

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

void ToolLoopManager::calculateDirtyArea(ToolLoop* loop, const Points& points, Region& dirty_area)
void ToolLoopManager::calculateDirtyArea(const Points& points, Region& dirty_area)
{
dirty_area.clear();

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

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

dirty_area.createUnion(dirty_area, Region(r1.createUnion(r2)));
}

// Apply offset mode
Point offset(loop->getOffset());
Point offset(m_toolLoop->getOffset());
dirty_area.offset(-offset);

// Apply tiled mode
TiledMode tiledMode = loop->getDocumentSettings()->getTiledMode();
TiledMode tiledMode = m_toolLoop->getDocumentSettings()->getTiledMode();
if (tiledMode != TILED_NONE) {
int w = loop->sprite()->width();
int h = loop->sprite()->height();
int w = m_toolLoop->sprite()->width();
int h = m_toolLoop->sprite()->height();
Region sprite_area(Rect(0, 0, w, h));
Region outside;
outside.createSubtraction(dirty_area, sprite_area);
Expand Down Expand Up @@ -312,6 +312,11 @@ void ToolLoopManager::calculateMinMax(const Points& points, Point& minpt, Point&
maxpt.x = MAX(maxpt.x, points[c].x);
maxpt.y = MAX(maxpt.y, points[c].y);
}

if (m_toolLoop->zoom().scale() < 1.0) {
maxpt.x += m_toolLoop->zoom().remove(1);
maxpt.y += m_toolLoop->zoom().remove(1);
}
}

} // namespace tools
Expand Down
12 changes: 6 additions & 6 deletions src/app/tools/tool_loop_manager.h
Expand Up @@ -103,13 +103,13 @@ namespace app {
void doLoopStep(bool last_step);
void snapToGrid(gfx::Point& point);

static void calculateDirtyArea(ToolLoop* loop,
const Points& points,
gfx::Region& dirty_area);
void calculateDirtyArea(
const Points& points,
gfx::Region& dirty_area);

static void calculateMinMax(const Points& points,
gfx::Point& minpt,
gfx::Point& maxpt);
void calculateMinMax(const Points& points,
gfx::Point& minpt,
gfx::Point& maxpt);

ToolLoop* m_toolLoop;
Points m_points;
Expand Down
25 changes: 11 additions & 14 deletions src/app/ui/editor/cursor.cpp
Expand Up @@ -55,7 +55,7 @@ namespace app {
using namespace ui;

// Returns true if the cursor of the editor needs subpixel movement.
#define IS_SUBPIXEL(editor) ((editor)->m_zoom >= 2)
#define IS_SUBPIXEL(editor) ((editor)->m_zoom.scale() >= 4.0)

// Maximum quantity of colors to save pixels overlapped by the cursor.
#define MAX_SAVED 4096
Expand Down Expand Up @@ -514,25 +514,22 @@ static void trace_thickcross_pixels(ui::Graphics* g, Editor* editor,
0, 0, 1, 1, 0, 0,
0, 0, 1, 1, 0, 0,
};
gfx::Point out;
gfx::Point out, outpt = editor->editorToScreen(pt);
int u, v;
int zoom = editor->zoom();
int size = editor->zoom().apply(thickness/2);
int size2 = editor->zoom().apply(thickness);
if (size2 == 0) size2 = 1;

for (v=0; v<6; v++) {
for (u=0; u<6; u++) {
if (cursor_cross[v*6+u]) {
out = editor->editorToScreen(pt);

out.x += ((u<3) ?
u-((thickness>>1)<<zoom)-3:
u-((thickness>>1)<<zoom)-3+(thickness<<zoom));
if (!cursor_cross[v*6+u])
continue;

out.y += ((v<3)?
v-((thickness>>1)<<zoom)-3:
v-((thickness>>1)<<zoom)-3+(thickness<<zoom));
out = outpt;
out.x += ((u<3) ? u-size-3: u-size-3+size2);
out.y += ((v<3) ? v-size-3: v-size-3+size2);

pixelDelegate(g, out, color);
}
pixelDelegate(g, out, color);
}
}
}
Expand Down

0 comments on commit 4fc28d5

Please sign in to comment.