Move gfx::Transformation to app::Transformation

In this way gfx library doesn't depend on fixmath.
master
David Capello 2016-07-11 14:16:01 -03:00
parent b0385d437f
commit 9c73841970
18 changed files with 173 additions and 174 deletions

View File

@ -18,6 +18,7 @@ because they don't depend on any other component.
* [css](css/): Pseudo-style sheet library.
* [fixmath](fixmath/): Fixed point operations (original code from Allegro code by Shawn Hargreaves).
* [flic](flic/): Library to load/save FLI/FLC files.
* [gfx](gfx/): Abstract graphics structures like point, size, rectangle, region, color, etc.
* [scripting](scripting/): JavaScript engine.
* [steam](steam/): Steam API wrapper to avoid static linking to the .lib file.
* [undo](undo/): Generic library to manage a history of undoable commands.
@ -27,7 +28,6 @@ because they don't depend on any other component.
* [cfg](cfg/) (base): Library to load/save .ini files.
* [gen](gen/) (base): Helper utility to generate C++ files from different XMLs.
* [gfx](gfx/) (fixmath): Abstract graphics structures like point, size, rectangle, region, color, etc.
* [net](net/) (base): Networking library to send HTTP requests.
* [webserver](webserver/) (base): HTTP web server

View File

@ -346,6 +346,7 @@ add_library(app-lib
tools/tool_box.cpp
tools/tool_loop_manager.cpp
transaction.cpp
transformation.cpp
ui/ani_controls.cpp
ui/app_menuitem.cpp
ui/brush_popup.cpp

View File

@ -251,12 +251,12 @@ void Document::setMaskVisible(bool visible)
//////////////////////////////////////////////////////////////////////
// Transformation
gfx::Transformation Document::getTransformation() const
Transformation Document::getTransformation() const
{
return m_transformation;
}
void Document::setTransformation(const gfx::Transformation& transform)
void Document::setTransformation(const Transformation& transform)
{
m_transformation = transform;
}
@ -264,9 +264,9 @@ void Document::setTransformation(const gfx::Transformation& transform)
void Document::resetTransformation()
{
if (m_mask)
m_transformation = gfx::Transformation(gfx::RectF(m_mask->bounds()));
m_transformation = Transformation(gfx::RectF(m_mask->bounds()));
else
m_transformation = gfx::Transformation();
m_transformation = Transformation();
}
//////////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -11,6 +11,7 @@
#include "app/extra_cel.h"
#include "app/file/format_options.h"
#include "app/transformation.h"
#include "base/disable_copying.h"
#include "base/mutex.h"
#include "base/observable.h"
@ -22,7 +23,6 @@
#include "doc/frame.h"
#include "doc/pixel_format.h"
#include "gfx/rect.h"
#include "gfx/transformation.h"
#include <string>
@ -149,8 +149,8 @@ namespace app {
//////////////////////////////////////////////////////////////////////
// Transformation
gfx::Transformation getTransformation() const;
void setTransformation(const gfx::Transformation& transform);
Transformation getTransformation() const;
void setTransformation(const Transformation& transform);
void resetTransformation();
//////////////////////////////////////////////////////////////////////
@ -209,7 +209,7 @@ namespace app {
bool m_maskVisible;
// Current transformation.
gfx::Transformation m_transformation;
Transformation m_transformation;
DISABLE_COPYING(Document);
};

View File

@ -8,14 +8,17 @@
#include "config.h"
#endif
#include "gfx/transformation.h"
#include "app/transformation.h"
#include "fixmath/fixmath.h"
#include "gfx/point.h"
#include "gfx/size.h"
#include "fixmath/fixmath.h"
#include <cmath>
namespace gfx {
namespace app {
using namespace gfx;
Transformation::Transformation()
{
@ -99,4 +102,4 @@ RectF Transformation::transformedBounds() const
return bounds;
}
}
} // namespace app

108
src/app/transformation.h Normal file
View File

@ -0,0 +1,108 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
#ifndef APP_TRANSFORMATION_H_INCLUDED
#define APP_TRANSFORMATION_H_INCLUDED
#pragma once
#include "gfx/point.h"
#include "gfx/rect.h"
#include <vector>
namespace app {
// Represents a transformation that can be done by the user in the
// document when he/she moves the mask using the selection handles.
class Transformation {
public:
class Corners {
public:
enum {
LEFT_TOP = 0,
RIGHT_TOP = 1,
RIGHT_BOTTOM = 2,
LEFT_BOTTOM = 3,
NUM_OF_CORNERS = 4
};
Corners() : m_corners(NUM_OF_CORNERS) { }
std::size_t size() const { return m_corners.size(); }
gfx::PointF& operator[](int index) { return m_corners[index]; }
const gfx::PointF& operator[](int index) const { return m_corners[index]; }
const gfx::PointF& leftTop() const { return m_corners[LEFT_TOP]; }
const gfx::PointF& rightTop() const { return m_corners[RIGHT_TOP]; }
const gfx::PointF& rightBottom() const { return m_corners[RIGHT_BOTTOM]; }
const gfx::PointF& leftBottom() const { return m_corners[LEFT_BOTTOM]; }
void leftTop(const gfx::PointF& pt) { m_corners[LEFT_TOP] = pt; }
void rightTop(const gfx::PointF& pt) { m_corners[RIGHT_TOP] = pt; }
void rightBottom(const gfx::PointF& pt) { m_corners[RIGHT_BOTTOM] = pt; }
void leftBottom(const gfx::PointF& pt) { m_corners[LEFT_BOTTOM] = pt; }
Corners& operator=(const gfx::RectF bounds) {
m_corners[LEFT_TOP].x = bounds.x;
m_corners[LEFT_TOP].y = bounds.y;
m_corners[RIGHT_TOP].x = bounds.x + bounds.w;
m_corners[RIGHT_TOP].y = bounds.y;
m_corners[RIGHT_BOTTOM].x = bounds.x + bounds.w;
m_corners[RIGHT_BOTTOM].y = bounds.y + bounds.h;
m_corners[LEFT_BOTTOM].x = bounds.x;
m_corners[LEFT_BOTTOM].y = bounds.y + bounds.h;
return *this;
}
gfx::RectF bounds() const {
gfx::RectF bounds;
for (int i=0; i<Corners::NUM_OF_CORNERS; ++i)
bounds |= gfx::RectF(m_corners[i].x, m_corners[i].y, 1, 1);
return bounds;
}
private:
std::vector<gfx::PointF> m_corners;
};
Transformation();
Transformation(const gfx::RectF& bounds);
// Simple getters and setters. The angle is in radians.
const gfx::RectF& bounds() const { return m_bounds; }
const gfx::PointF& pivot() const { return m_pivot; }
double angle() const { return m_angle; }
void bounds(const gfx::RectF& bounds) { m_bounds = bounds; }
void pivot(const gfx::PointF& pivot) { m_pivot = pivot; }
void angle(double angle) { m_angle = angle; }
// Applies the transformation (rotation with angle/pivot) to the
// current bounds (m_bounds).
void transformBox(Corners& corners) const;
// Changes the pivot to another location, adjusting the bounds to
// keep the current rotated-corners in the same location.
void displacePivotTo(const gfx::PointF& newPivot);
gfx::RectF transformedBounds() const;
// Static helper method to rotate points.
static gfx::PointF rotatePoint(const gfx::PointF& point,
const gfx::PointF& pivot,
double angle);
private:
gfx::RectF m_bounds;
gfx::PointF m_pivot;
double m_angle;
};
} // namespace app
#endif

View File

@ -432,7 +432,7 @@ bool MovingPixelsState::onUpdateStatusBar(Editor* editor)
ASSERT(m_pixelsMovement);
ASSERT(editor == m_editor);
const gfx::Transformation& transform(getTransformation(editor));
const Transformation& transform(getTransformation(editor));
gfx::Size imageSize = m_pixelsMovement->getInitialImageSize();
StatusBar::instance()->setStatusText
@ -621,7 +621,7 @@ void MovingPixelsState::dropPixels()
m_editor->backToPreviousState();
}
gfx::Transformation MovingPixelsState::getTransformation(Editor* editor)
Transformation MovingPixelsState::getTransformation(Editor* editor)
{
return m_pixelsMovement->getTransformation();
}

View File

@ -58,7 +58,7 @@ namespace app {
// ContextBarObserver
virtual void onDropPixels(ContextBarObserver::DropAction action) override;
virtual gfx::Transformation getTransformation(Editor* editor) override;
virtual Transformation getTransformation(Editor* editor) override;
private:
void onTransparentColorChange();

View File

@ -12,18 +12,18 @@
#include "app/ui/editor/pivot_helpers.h"
#include "app/pref/preferences.h"
#include "gfx/transformation.h"
#include "app/transformation.h"
namespace app {
void set_pivot_from_preferences(gfx::Transformation& t)
void set_pivot_from_preferences(Transformation& t)
{
gfx::Transformation::Corners corners;
Transformation::Corners corners;
t.transformBox(corners);
gfx::PointT<double> nw(corners[gfx::Transformation::Corners::LEFT_TOP]);
gfx::PointT<double> ne(corners[gfx::Transformation::Corners::RIGHT_TOP]);
gfx::PointT<double> sw(corners[gfx::Transformation::Corners::LEFT_BOTTOM]);
gfx::PointT<double> se(corners[gfx::Transformation::Corners::RIGHT_BOTTOM]);
gfx::PointT<double> nw(corners[Transformation::Corners::LEFT_TOP]);
gfx::PointT<double> ne(corners[Transformation::Corners::RIGHT_TOP]);
gfx::PointT<double> sw(corners[Transformation::Corners::LEFT_BOTTOM]);
gfx::PointT<double> se(corners[Transformation::Corners::RIGHT_BOTTOM]);
gfx::PointT<double> pivotPos((nw + se) / 2);
app::gen::PivotPosition pivot = Preferences::instance().selection.pivotPosition();

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -9,13 +9,10 @@
#define APP_UI_EDITOR_PIVOT_HELPERS_H_INCLUDED
#pragma once
namespace gfx {
class Transformation;
}
namespace app {
class Transformation;
void set_pivot_from_preferences(gfx::Transformation& t);
void set_pivot_from_preferences(Transformation& t);
} // namespace app

View File

@ -69,7 +69,7 @@ PixelsMovement::PixelsMovement(
, m_opaque(false)
, m_maskColor(m_sprite->transparentColor())
{
gfx::Transformation transform(mask->bounds());
Transformation transform(mask->bounds());
set_pivot_from_preferences(transform);
m_initialData = transform;
@ -232,7 +232,7 @@ void PixelsMovement::catchImageAgain(const gfx::Point& pos, HandleType handle)
void PixelsMovement::moveImage(const gfx::Point& pos, MoveModifier moveModifier)
{
gfx::Transformation::Corners oldCorners;
Transformation::Corners oldCorners;
m_currentData.transformBox(oldCorners);
ContextWriter writer(m_reader, 1000);
@ -427,13 +427,13 @@ void PixelsMovement::moveImage(const gfx::Point& pos, MoveModifier moveModifier)
m_document->setTransformation(m_currentData);
// Get the new transformed corners
gfx::Transformation::Corners newCorners;
Transformation::Corners newCorners;
m_currentData.transformBox(newCorners);
// Create a union of all corners, and that will be the bounds to
// redraw of the sprite.
gfx::Rect fullBounds;
for (int i=0; i<gfx::Transformation::Corners::NUM_OF_CORNERS; ++i) {
for (int i=0; i<Transformation::Corners::NUM_OF_CORNERS; ++i) {
fullBounds = fullBounds.createUnion(gfx::Rect((int)oldCorners[i].x, (int)oldCorners[i].y, 1, 1));
fullBounds = fullBounds.createUnion(gfx::Rect((int)newCorners[i].x, (int)newCorners[i].y, 1, 1));
}
@ -535,7 +535,7 @@ void PixelsMovement::dropImageTemporarily()
pivotPosFactor.y /= m_initialData.bounds().h;
// Get the current transformed bounds.
gfx::Transformation::Corners corners;
Transformation::Corners corners;
m_currentData.transformBox(corners);
// The new pivot will be located from the rotated left-top
@ -650,7 +650,7 @@ void PixelsMovement::drawImage(doc::Image* dst, const gfx::Point& pt, bool rende
{
ASSERT(dst);
gfx::Transformation::Corners corners;
Transformation::Corners corners;
m_currentData.transformBox(corners);
gfx::Rect bounds = corners.bounds();
@ -683,7 +683,7 @@ void PixelsMovement::drawImage(doc::Image* dst, const gfx::Point& pt, bool rende
void PixelsMovement::drawMask(doc::Mask* mask, bool shrink)
{
gfx::Transformation::Corners corners;
Transformation::Corners corners;
m_currentData.transformBox(corners);
gfx::Rect bounds = corners.bounds();
@ -701,7 +701,7 @@ void PixelsMovement::drawMask(doc::Mask* mask, bool shrink)
void PixelsMovement::drawParallelogram(
doc::Image* dst, const doc::Image* src, const doc::Mask* mask,
const gfx::Transformation::Corners& corners,
const Transformation::Corners& corners,
const gfx::Point& leftTop)
{
tools::RotationAlgorithm rotAlgo = Preferences::instance().selection.rotationAlgorithm();

View File

@ -94,7 +94,7 @@ namespace app {
// simulate RotateCommand when we're inside MovingPixelsState.
void rotate(double angle);
const gfx::Transformation& getTransformation() const { return m_currentData; }
const Transformation& getTransformation() const { return m_currentData; }
private:
void onPivotChange();
@ -104,7 +104,7 @@ namespace app {
void drawImage(doc::Image* dst, const gfx::Point& pos, bool renderOriginalLayer);
void drawMask(doc::Mask* dst, bool shrink);
void drawParallelogram(doc::Image* dst, const doc::Image* src, const doc::Mask* mask,
const gfx::Transformation::Corners& corners,
const Transformation::Corners& corners,
const gfx::Point& leftTop);
void updateDocumentMask();
@ -120,8 +120,8 @@ namespace app {
HandleType m_handle;
Image* m_originalImage;
gfx::Point m_catchPos;
gfx::Transformation m_initialData;
gfx::Transformation m_currentData;
Transformation m_initialData;
Transformation m_currentData;
Mask* m_initialMask;
Mask* m_currentMask;
bool m_opaque;

View File

@ -493,9 +493,9 @@ bool StandbyState::onUpdateStatusBar(Editor* editor)
return true;
}
gfx::Transformation StandbyState::getTransformation(Editor* editor)
Transformation StandbyState::getTransformation(Editor* editor)
{
gfx::Transformation t = editor->document()->getTransformation();
Transformation t = editor->document()->getTransformation();
set_pivot_from_preferences(t);
return t;
}
@ -615,7 +615,7 @@ bool StandbyState::Decorator::onSetCursor(tools::Ink* ink, Editor* editor, const
return false;
if (ink && ink->isSelection() && editor->document()->isMaskVisible()) {
const gfx::Transformation transformation(m_standbyState->getTransformation(editor));
const Transformation transformation(m_standbyState->getTransformation(editor));
TransformHandles* tr = getTransformHandles(editor);
HandleType handle = tr->getHandleAtPoint(
editor, mouseScreenPos, transformation);

View File

@ -9,11 +9,11 @@
#define APP_UI_EDITOR_STANDBY_STATE_H_INCLUDED
#pragma once
#include "app/transformation.h"
#include "app/ui/editor/editor_decorator.h"
#include "app/ui/editor/handle_type.h"
#include "app/ui/editor/state_with_wheel_behavior.h"
#include "base/connection.h"
#include "gfx/transformation.h"
namespace app {
namespace tools {
@ -41,7 +41,7 @@ namespace app {
// the brush-preview.
virtual bool requireBrushPreview() override { return true; }
virtual gfx::Transformation getTransformation(Editor* editor);
virtual Transformation getTransformation(Editor* editor);
void startSelectionTransformation(Editor* editor, const gfx::Point& move, double angle);

View File

@ -52,13 +52,13 @@ static struct HandlesInfo {
{ 2, 2, 224 << 16, { ScaleSEHandle, RotateSEHandle } },
};
HandleType TransformHandles::getHandleAtPoint(Editor* editor, const gfx::Point& pt, const gfx::Transformation& transform)
HandleType TransformHandles::getHandleAtPoint(Editor* editor, const gfx::Point& pt, const Transformation& transform)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
she::Surface* gfx = theme->parts.transformationHandle()->bitmap(0);
fixmath::fixed angle = fixmath::ftofix(128.0 * transform.angle() / PI);
gfx::Transformation::Corners corners;
Transformation::Corners corners;
transform.transformBox(corners);
std::vector<gfx::Point> screenPoints(corners.size());
@ -87,12 +87,12 @@ HandleType TransformHandles::getHandleAtPoint(Editor* editor, const gfx::Point&
return NoHandle;
}
void TransformHandles::drawHandles(Editor* editor, const gfx::Transformation& transform)
void TransformHandles::drawHandles(Editor* editor, const Transformation& transform)
{
ScreenGraphics g;
fixmath::fixed angle = fixmath::ftofix(128.0 * transform.angle() / PI);
gfx::Transformation::Corners corners;
Transformation::Corners corners;
transform.transformBox(corners);
std::vector<gfx::Point> screenPoints(corners.size());
@ -136,12 +136,12 @@ void TransformHandles::drawHandles(Editor* editor, const gfx::Transformation& tr
}
}
void TransformHandles::invalidateHandles(Editor* editor, const gfx::Transformation& transform)
void TransformHandles::invalidateHandles(Editor* editor, const Transformation& transform)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
fixmath::fixed angle = fixmath::ftofix(128.0 * transform.angle() / PI);
gfx::Transformation::Corners corners;
Transformation::Corners corners;
transform.transformBox(corners);
std::vector<gfx::Point> screenPoints(corners.size());
@ -172,8 +172,8 @@ void TransformHandles::invalidateHandles(Editor* editor, const gfx::Transformati
}
gfx::Rect TransformHandles::getPivotHandleBounds(Editor* editor,
const gfx::Transformation& transform,
const gfx::Transformation::Corners& corners)
const Transformation& transform,
const Transformation::Corners& corners)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
gfx::Size partSize = theme->parts.pivotHandle()->size();

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -9,10 +9,10 @@
#define APP_UI_EDITOR_TRANSFORM_HANDLES_H_INCLUDED
#pragma once
#include "app/transformation.h"
#include "app/ui/editor/handle_type.h"
#include "fixmath/fixmath.h"
#include "gfx/point.h"
#include "gfx/transformation.h"
namespace ui {
class Graphics;
@ -27,15 +27,15 @@ namespace app {
public:
// Returns the handle in the given mouse point (pt) when the user
// has applied the given transformation to the selection.
HandleType getHandleAtPoint(Editor* editor, const gfx::Point& pt, const gfx::Transformation& transform);
HandleType getHandleAtPoint(Editor* editor, const gfx::Point& pt, const Transformation& transform);
void drawHandles(Editor* editor, const gfx::Transformation& transform);
void invalidateHandles(Editor* editor, const gfx::Transformation& transform);
void drawHandles(Editor* editor, const Transformation& transform);
void invalidateHandles(Editor* editor, const Transformation& transform);
private:
gfx::Rect getPivotHandleBounds(Editor* editor,
const gfx::Transformation& transform,
const gfx::Transformation::Corners& corners);
const Transformation& transform,
const Transformation::Corners& corners);
bool inHandle(const gfx::Point& pt, int x, int y, int gfx_w, int gfx_h, fixmath::fixed angle);
void drawHandle(ui::Graphics* g, int x, int y, fixmath::fixed angle);

View File

@ -1,14 +1,12 @@
# Aseprite
# Copyright (C) 2001-2015 David Capello
# Copyright (C) 2001-2016 David Capello
add_library(gfx-lib
clip.cpp
hsv.cpp
packing_rects.cpp
region.cpp
rgb.cpp
transformation.cpp)
rgb.cpp)
target_link_libraries(gfx-lib
fixmath-lib
${PIXMAN_LIBRARY})

View File

@ -1,108 +0,0 @@
// Aseprite Gfx Library
// Copyright (C) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef TRANSFORMATION_H_INCLUDED
#define TRANSFORMATION_H_INCLUDED
#pragma once
#include "gfx/point.h"
#include "gfx/rect.h"
#include <vector>
namespace gfx {
// Represents a transformation that can be done by the user in the
// document when he/she moves the mask using the selection handles.
class Transformation
{
public:
class Corners {
public:
enum {
LEFT_TOP = 0,
RIGHT_TOP = 1,
RIGHT_BOTTOM = 2,
LEFT_BOTTOM = 3,
NUM_OF_CORNERS = 4
};
Corners() : m_corners(NUM_OF_CORNERS) { }
std::size_t size() const { return m_corners.size(); }
PointF& operator[](int index) { return m_corners[index]; }
const PointF& operator[](int index) const { return m_corners[index]; }
const PointF& leftTop() const { return m_corners[LEFT_TOP]; }
const PointF& rightTop() const { return m_corners[RIGHT_TOP]; }
const PointF& rightBottom() const { return m_corners[RIGHT_BOTTOM]; }
const PointF& leftBottom() const { return m_corners[LEFT_BOTTOM]; }
void leftTop(const PointF& pt) { m_corners[LEFT_TOP] = pt; }
void rightTop(const PointF& pt) { m_corners[RIGHT_TOP] = pt; }
void rightBottom(const PointF& pt) { m_corners[RIGHT_BOTTOM] = pt; }
void leftBottom(const PointF& pt) { m_corners[LEFT_BOTTOM] = pt; }
Corners& operator=(const RectF bounds) {
m_corners[LEFT_TOP].x = bounds.x;
m_corners[LEFT_TOP].y = bounds.y;
m_corners[RIGHT_TOP].x = bounds.x + bounds.w;
m_corners[RIGHT_TOP].y = bounds.y;
m_corners[RIGHT_BOTTOM].x = bounds.x + bounds.w;
m_corners[RIGHT_BOTTOM].y = bounds.y + bounds.h;
m_corners[LEFT_BOTTOM].x = bounds.x;
m_corners[LEFT_BOTTOM].y = bounds.y + bounds.h;
return *this;
}
RectF bounds() const {
RectF bounds;
for (int i=0; i<Corners::NUM_OF_CORNERS; ++i)
bounds |= RectF(m_corners[i].x, m_corners[i].y, 1, 1);
return bounds;
}
private:
std::vector<PointF> m_corners;
};
Transformation();
Transformation(const RectF& bounds);
// Simple getters and setters. The angle is in radians.
const RectF& bounds() const { return m_bounds; }
const PointF& pivot() const { return m_pivot; }
double angle() const { return m_angle; }
void bounds(const RectF& bounds) { m_bounds = bounds; }
void pivot(const PointF& pivot) { m_pivot = pivot; }
void angle(double angle) { m_angle = angle; }
// Applies the transformation (rotation with angle/pivot) to the
// current bounds (m_bounds).
void transformBox(Corners& corners) const;
// Changes the pivot to another location, adjusting the bounds to
// keep the current rotated-corners in the same location.
void displacePivotTo(const PointF& newPivot);
RectF transformedBounds() const;
// Static helper method to rotate points.
static PointF rotatePoint(const PointF& point,
const PointF& pivot,
double angle);
private:
RectF m_bounds;
PointF m_pivot;
double m_angle;
};
} // namespace gfx
#endif