mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-02 11:59:58 +00:00
Move gradient rendering code to render library
This commit is contained in:
parent
0bab4e7ae7
commit
317b493fb7
@ -6,7 +6,6 @@
|
||||
|
||||
#include "app/modules/palettes.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "base/vector2d.h"
|
||||
#include "doc/blend_funcs.h"
|
||||
#include "doc/image_impl.h"
|
||||
#include "doc/layer.h"
|
||||
@ -18,6 +17,7 @@
|
||||
#include "gfx/hsv.h"
|
||||
#include "gfx/rgb.h"
|
||||
#include "render/dithering.h"
|
||||
#include "render/gradient.h"
|
||||
|
||||
namespace app {
|
||||
namespace tools {
|
||||
@ -897,83 +897,12 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is no vector defining the gradient (just one point),
|
||||
// the "gradient" will be just "c0"
|
||||
if (strokes[0].firstPoint().x == strokes[0].lastPoint().x &&
|
||||
strokes[0].firstPoint().y == strokes[0].lastPoint().y) {
|
||||
m_tmpImage->clear(c0);
|
||||
return;
|
||||
}
|
||||
|
||||
const render::DitheringMatrix& m_matrix =
|
||||
loop->getDitheringMatrix();
|
||||
|
||||
base::Vector2d<double>
|
||||
u(strokes[0].firstPoint().x,
|
||||
strokes[0].firstPoint().y),
|
||||
v(strokes[0].lastPoint().x,
|
||||
strokes[0].lastPoint().y), w;
|
||||
w = v - u;
|
||||
|
||||
// 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 & rgba_rgb_mask);
|
||||
}
|
||||
else if (doc::rgba_geta(c0) != 0 &&
|
||||
doc::rgba_geta(c1) == 0) {
|
||||
c1 = (c0 & 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(m_tmpImage.get());
|
||||
auto it = bits.begin();
|
||||
const int width = m_tmpImage->width();
|
||||
const int height = m_tmpImage->height();
|
||||
|
||||
if (m_matrix.rows() == 1 && m_matrix.cols() == 1) {
|
||||
for (int y=0; y<height; ++y) {
|
||||
for (int x=0; x<width; ++x, ++it) {
|
||||
base::Vector2d<double> q(x, y);
|
||||
q -= u;
|
||||
double f = (q * w.normalize()) / (w.magnitude());
|
||||
|
||||
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(x, y);
|
||||
q -= u;
|
||||
double f = (q * w.normalize()) / (w.magnitude());
|
||||
*it = (f*m_matrix.maxValue() < m_matrix(y, x) ? c0: c1);
|
||||
}
|
||||
}
|
||||
}
|
||||
render::render_rgba_linear_gradient(
|
||||
m_tmpImage.get(),
|
||||
strokes[0].firstPoint(),
|
||||
strokes[0].lastPoint(),
|
||||
c0, c1,
|
||||
loop->getDitheringMatrix());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
add_library(render-lib
|
||||
get_sprite_pixel.cpp
|
||||
gradient.cpp
|
||||
ordered_dither.cpp
|
||||
quantization.cpp
|
||||
render.cpp
|
||||
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2001-2014 David Capello
|
||||
Copyright (c) 2001-2017 David Capello
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Aseprite Render Library
|
||||
*Copyright (C) 2001-2014 David Capello*
|
||||
*Copyright (C) 2001-2017 David Capello*
|
||||
|
||||
> Distributed under [MIT license](LICENSE.txt)
|
||||
|
106
src/render/gradient.cpp
Normal file
106
src/render/gradient.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
// Aseprite Render Library
|
||||
// Copyright (c) 2017 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "render/gradient.h"
|
||||
|
||||
#include "base/vector2d.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/image_impl.h"
|
||||
#include "render/dithering_matrix.h"
|
||||
|
||||
namespace render {
|
||||
|
||||
void render_rgba_linear_gradient(
|
||||
doc::Image* img,
|
||||
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;
|
||||
|
||||
// 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(x, y);
|
||||
q -= u;
|
||||
double f = (q * w.normalize()) / (w.magnitude());
|
||||
|
||||
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(x, y);
|
||||
q -= u;
|
||||
double f = (q * w.normalize()) / (w.magnitude());
|
||||
*it = (f*matrix.maxValue() < matrix(y, x) ? c0: c1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace render
|
32
src/render/gradient.h
Normal file
32
src/render/gradient.h
Normal file
@ -0,0 +1,32 @@
|
||||
// Aseprite Render Library
|
||||
// Copyright (c) 2017 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef RENDER_GRADIENT_H_INCLUDED
|
||||
#define RENDER_GRADIENT_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "doc/color.h"
|
||||
#include "gfx/point.h"
|
||||
|
||||
namespace doc {
|
||||
class Image;
|
||||
}
|
||||
|
||||
namespace render {
|
||||
|
||||
class DitheringMatrix;
|
||||
|
||||
void render_rgba_linear_gradient(
|
||||
doc::Image* img,
|
||||
const gfx::Point p0,
|
||||
const gfx::Point p1,
|
||||
doc::color_t c0,
|
||||
doc::color_t c1,
|
||||
const render::DitheringMatrix& matrix);
|
||||
|
||||
} // namespace render
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user