David Capello 2019-03-19 20:54:25 -03:00
parent 250d40c0f3
commit 3ec3f75d91
10 changed files with 195 additions and 5 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -402,6 +402,8 @@
<part id="aseprite_face_mouse" x="28" y="272" w="28" h="30" /> <part id="aseprite_face_mouse" x="28" y="272" w="28" h="30" />
<part id="aseprite_face_pushed" x="56" y="272" w="28" h="30" /> <part id="aseprite_face_pushed" x="56" y="272" w="28" h="30" />
<part id="icon_aspect_ratio" x="256" y="264" w="10" h="8" /> <part id="icon_aspect_ratio" x="256" y="264" w="10" h="8" />
<part id="linear_gradient" x="176" y="208" w="8" h="8" />
<part id="radial_gradient" x="184" y="208" w="8" h="8" />
</parts> </parts>
<styles> <styles>
<style id="box" /> <style id="box" />

View File

@ -908,9 +908,10 @@ public:
imgPos.y *= h; imgPos.y *= h;
} }
render::render_rgba_linear_gradient( render::render_rgba_gradient(
m_tmpImage.get(), imgPos, u, v, c0, c1, m_tmpImage.get(), imgPos, u, v, c0, c1,
loop->getDitheringMatrix()); loop->getDitheringMatrix(),
loop->getGradientType());
} }
protected: protected:

View File

@ -16,6 +16,7 @@
#include "filters/tiled_mode.h" #include "filters/tiled_mode.h"
#include "gfx/point.h" #include "gfx/point.h"
#include "gfx/rect.h" #include "gfx/rect.h"
#include "render/gradient.h"
namespace gfx { namespace gfx {
class Region; class Region;
@ -233,6 +234,7 @@ namespace app {
// For gradients // For gradients
virtual render::DitheringMatrix getDitheringMatrix() = 0; virtual render::DitheringMatrix getDitheringMatrix() = 0;
virtual render::DitheringAlgorithmBase* getDitheringAlgorithm() = 0; virtual render::DitheringAlgorithmBase* getDitheringAlgorithm() = 0;
virtual render::GradientType getGradientType() = 0;
}; };
} // namespace tools } // namespace tools

View File

@ -933,6 +933,27 @@ protected:
} }
}; };
class ContextBar::GradientTypeField : public ButtonSet {
public:
GradientTypeField() : ButtonSet(2) {
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
addItem(theme->parts.linearGradient());
addItem(theme->parts.radialGradient());
setSelectedItem(0);
}
void setupTooltips(TooltipManager* tooltipManager) {
tooltipManager->addTooltipFor(at(0), "Linear Gradient", BOTTOM);
tooltipManager->addTooltipFor(at(1), "Radial Gradient", BOTTOM);
}
render::GradientType gradientType() const {
return (render::GradientType)selectedItem();
}
};
class ContextBar::DropPixelsField : public ButtonSet { class ContextBar::DropPixelsField : public ButtonSet {
public: public:
DropPixelsField() : ButtonSet(2) { DropPixelsField() : ButtonSet(2) {
@ -1100,6 +1121,7 @@ ContextBar::ContextBar(TooltipManager* tooltipManager)
addChild(m_tolerance = new ToleranceField()); addChild(m_tolerance = new ToleranceField());
addChild(m_contiguous = new ContiguousField()); addChild(m_contiguous = new ContiguousField());
addChild(m_paintBucketSettings = new PaintBucketSettingsField()); addChild(m_paintBucketSettings = new PaintBucketSettingsField());
addChild(m_gradientType = new GradientTypeField());
addChild(m_ditheringSelector = new DitheringSelector(DitheringSelector::SelectMatrix)); addChild(m_ditheringSelector = new DitheringSelector(DitheringSelector::SelectMatrix));
m_ditheringSelector->setUseCustomWidget(false); // Disable custom widget because the context bar is too small m_ditheringSelector->setUseCustomWidget(false); // Disable custom widget because the context bar is too small
@ -1428,6 +1450,7 @@ void ContextBar::updateForTool(tools::Tool* tool)
m_paintBucketSettings->setVisible(hasTolerance); m_paintBucketSettings->setVisible(hasTolerance);
m_sprayBox->setVisible(hasSprayOptions); m_sprayBox->setVisible(hasSprayOptions);
m_selectionOptionsBox->setVisible(hasSelectOptions); m_selectionOptionsBox->setVisible(hasSelectOptions);
m_gradientType->setVisible(withDithering);
m_ditheringSelector->setVisible(withDithering); m_ditheringSelector->setVisible(withDithering);
m_selectionMode->setVisible(true); m_selectionMode->setVisible(true);
m_pivot->setVisible(true); m_pivot->setVisible(true);
@ -1718,6 +1741,11 @@ render::DitheringAlgorithmBase* ContextBar::ditheringAlgorithm()
return s_dither.get(); return s_dither.get();
} }
render::GradientType ContextBar::gradientType()
{
return m_gradientType->gradientType();
}
void ContextBar::setupTooltips(TooltipManager* tooltipManager) void ContextBar::setupTooltips(TooltipManager* tooltipManager)
{ {
tooltipManager->addTooltipFor(m_brushBack->at(0), "Discard Brush (Esc)", BOTTOM); tooltipManager->addTooltipFor(m_brushBack->at(0), "Discard Brush (Esc)", BOTTOM);
@ -1741,6 +1769,7 @@ void ContextBar::setupTooltips(TooltipManager* tooltipManager)
"Extra paint bucket options", BOTTOM); "Extra paint bucket options", BOTTOM);
m_selectionMode->setupTooltips(tooltipManager); m_selectionMode->setupTooltips(tooltipManager);
m_gradientType->setupTooltips(tooltipManager);
m_dropPixels->setupTooltips(tooltipManager); m_dropPixels->setupTooltips(tooltipManager);
m_symmetry->setupTooltips(tooltipManager); m_symmetry->setupTooltips(tooltipManager);
} }

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2018-2019 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello // Copyright (C) 2001-2017 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -19,6 +19,7 @@
#include "obs/connection.h" #include "obs/connection.h"
#include "obs/observable.h" #include "obs/observable.h"
#include "obs/signal.h" #include "obs/signal.h"
#include "render/gradient.h"
#include "ui/box.h" #include "ui/box.h"
#include <vector> #include <vector>
@ -48,6 +49,7 @@ namespace app {
class BrushSlot; class BrushSlot;
class DitheringSelector; class DitheringSelector;
class GradientTypeSelector;
class ContextBar : public ui::Box class ContextBar : public ui::Box
, public obs::observable<ContextBarObserver> , public obs::observable<ContextBarObserver>
@ -83,6 +85,7 @@ namespace app {
// For gradients // For gradients
render::DitheringMatrix ditheringMatrix(); render::DitheringMatrix ditheringMatrix();
render::DitheringAlgorithmBase* ditheringAlgorithm(); render::DitheringAlgorithmBase* ditheringAlgorithm();
render::GradientType gradientType();
// Signals // Signals
obs::signal<void()> BrushChange; obs::signal<void()> BrushChange;
@ -122,6 +125,7 @@ namespace app {
class SprayWidthField; class SprayWidthField;
class SpraySpeedField; class SpraySpeedField;
class SelectionModeField; class SelectionModeField;
class GradientTypeField;
class TransparentColorField; class TransparentColorField;
class PivotField; class PivotField;
class RotAlgorithmField; class RotAlgorithmField;
@ -157,6 +161,7 @@ namespace app {
ui::Box* m_selectionOptionsBox; ui::Box* m_selectionOptionsBox;
DitheringSelector* m_ditheringSelector; DitheringSelector* m_ditheringSelector;
SelectionModeField* m_selectionMode; SelectionModeField* m_selectionMode;
GradientTypeField* m_gradientType;
TransparentColorField* m_transparentColor; TransparentColorField* m_transparentColor;
PivotField* m_pivot; PivotField* m_pivot;
RotAlgorithmField* m_rotAlgo; RotAlgorithmField* m_rotAlgo;

View File

@ -330,6 +330,15 @@ public:
#endif #endif
} }
render::GradientType getGradientType() override {
#ifdef ENABLE_UI // TODO add support when UI is not enabled
return App::instance()->contextBar()->gradientType();
#else
return render::GradientType::Linear;
#endif
}
}; };
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////

View File

@ -1,4 +1,5 @@
Copyright (c) 2001-2017 David Capello Copyright (c) 2019 Igara Studio S.A.
Copyright (c) 2001-2018 David Capello
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the

View File

@ -1,4 +1,5 @@
// Aseprite Render Library // Aseprite Render Library
// Copyright (c) 2019 Igara Studio S.A.
// Copyright (c) 2017 David Capello // Copyright (c) 2017 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
@ -17,6 +18,26 @@
namespace render { namespace render {
void render_rgba_gradient(
doc::Image* img,
const gfx::Point imgPos,
const gfx::Point p0,
const gfx::Point p1,
doc::color_t c0,
doc::color_t c1,
const render::DitheringMatrix& matrix,
const GradientType type)
{
switch (type) {
case GradientType::Linear:
render_rgba_linear_gradient(img, imgPos, p0, p1, c0, c1, matrix);
break;
case GradientType::Radial:
render_rgba_radial_gradient(img, imgPos, p0, p1, c0, c1, matrix);
break;
}
}
void render_rgba_linear_gradient( void render_rgba_linear_gradient(
doc::Image* img, doc::Image* img,
const gfx::Point imgPos, const gfx::Point imgPos,
@ -98,7 +119,8 @@ void render_rgba_linear_gradient(
else { else {
for (int y=0; y<height; ++y) { for (int y=0; y<height; ++y) {
for (int x=0; x<width; ++x, ++it) { for (int x=0; x<width; ++x, ++it) {
base::Vector2d<double> q(x, y); base::Vector2d<double> q(imgPos.x+x,
imgPos.y+y);
q -= u; q -= u;
double f = (q * w) / wmag; double f = (q * w) / wmag;
@ -108,4 +130,98 @@ void render_rgba_linear_gradient(
} }
} }
void render_rgba_radial_gradient(
doc::Image* img,
const gfx::Point imgPos,
const gfx::Point p0,
const gfx::Point p1,
doc::color_t c0,
doc::color_t c1,
const render::DitheringMatrix& matrix)
{
ASSERT(img->pixelFormat() == doc::IMAGE_RGB);
if (img->pixelFormat() != doc::IMAGE_RGB) {
return;
}
// If there is no vector defining the gradient (just one point),
// the "gradient" will be just "c0"
if (p0 == p1) {
img->clear(c0);
return;
}
base::Vector2d<double>
u(p0.x, p0.y),
v(p1.x, p1.y), w;
w = (v - u) / 2;
// As we use non-premultiplied RGB values, we need correct RGB
// values on each stop. So in case that one color has alpha=0
// (complete transparent), use the RGB values of the
// non-transparent color in the other stop point.
if (doc::rgba_geta(c0) == 0 &&
doc::rgba_geta(c1) != 0) {
c0 = (c1 & doc::rgba_rgb_mask);
}
else if (doc::rgba_geta(c0) != 0 &&
doc::rgba_geta(c1) == 0) {
c1 = (c0 & doc::rgba_rgb_mask);
}
const double r0 = double(doc::rgba_getr(c0)) / 255.0;
const double g0 = double(doc::rgba_getg(c0)) / 255.0;
const double b0 = double(doc::rgba_getb(c0)) / 255.0;
const double a0 = double(doc::rgba_geta(c0)) / 255.0;
const double r1 = double(doc::rgba_getr(c1)) / 255.0;
const double g1 = double(doc::rgba_getg(c1)) / 255.0;
const double b1 = double(doc::rgba_getb(c1)) / 255.0;
const double a1 = double(doc::rgba_geta(c1)) / 255.0;
doc::LockImageBits<doc::RgbTraits> bits(img);
auto it = bits.begin();
const int width = img->width();
const int height = img->height();
if (matrix.rows() == 1 && matrix.cols() == 1) {
for (int y=0; y<height; ++y) {
for (int x=0; x<width; ++x, ++it) {
base::Vector2d<double> q(imgPos.x+x,
imgPos.y+y);
q -= (u+v)/2;
q.x /= std::fabs(w.x);
q.y /= std::fabs(w.y);
double f = std::sqrt(q.x*q.x + q.y*q.y);
doc::color_t c;
if (f < 0.0) c = c0;
else if (f > 1.0) c = c1;
else {
c = doc::rgba(int(255.0 * (r0 + f*(r1-r0))),
int(255.0 * (g0 + f*(g1-g0))),
int(255.0 * (b0 + f*(b1-b0))),
int(255.0 * (a0 + f*(a1-a0))));
}
*it = c;
}
}
}
else {
for (int y=0; y<height; ++y) {
for (int x=0; x<width; ++x, ++it) {
base::Vector2d<double> q(imgPos.x+x,
imgPos.y+y);
q -= (u+v)/2;
q.x /= std::fabs(w.x);
q.y /= std::fabs(w.y);
double f = std::sqrt(q.x*q.x + q.y*q.y);
*it = (f*(matrix.maxValue()+2) < matrix(y, x)+1 ? c0: c1);
}
}
}
}
} // namespace render } // namespace render

View File

@ -1,4 +1,5 @@
// Aseprite Render Library // Aseprite Render Library
// Copyright (c) 2019 Igara Studio S.A.
// Copyright (c) 2017 David Capello // Copyright (c) 2017 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
@ -19,6 +20,21 @@ namespace render {
class DitheringMatrix; class DitheringMatrix;
enum class GradientType {
Linear,
Radial,
};
void render_rgba_gradient(
doc::Image* img,
const gfx::Point imgPos,
const gfx::Point p0,
const gfx::Point p1,
doc::color_t c0,
doc::color_t c1,
const render::DitheringMatrix& matrix,
const GradientType type);
void render_rgba_linear_gradient( void render_rgba_linear_gradient(
doc::Image* img, doc::Image* img,
const gfx::Point imgPos, const gfx::Point imgPos,
@ -28,6 +44,15 @@ void render_rgba_linear_gradient(
doc::color_t c1, doc::color_t c1,
const render::DitheringMatrix& matrix); const render::DitheringMatrix& matrix);
void render_rgba_radial_gradient(
doc::Image* img,
const gfx::Point imgPos,
const gfx::Point p0,
const gfx::Point p1,
doc::color_t c0,
doc::color_t c1,
const render::DitheringMatrix& matrix);
} // namespace render } // namespace render
#endif #endif