diff --git a/src/apps/icon-o-matic/MainWindow.cpp b/src/apps/icon-o-matic/MainWindow.cpp index 5c0c6c2bb8..d1edfb6a63 100644 --- a/src/apps/icon-o-matic/MainWindow.cpp +++ b/src/apps/icon-o-matic/MainWindow.cpp @@ -17,6 +17,7 @@ #include "IconEditorApp.h" // TODO: just for testing +#include "Gradient.h" #include "Icon.h" #include "MultipleManipulatorState.h" #include "PathManipulator.h" @@ -92,6 +93,11 @@ MainWindow::_Init() Style* style = new Style(); style->SetColor((rgb_color){ 255, 0, 0, 255 }); + Gradient* gradient = new Gradient(true); + gradient->AddColor((rgb_color){ 255, 211, 6, 255 }, 0.0); + gradient->AddColor((rgb_color){ 255, 238, 160, 255 }, 0.5); + gradient->AddColor((rgb_color){ 208, 43, 92, 255 }, 1.0); + style->SetGradient(gradient); StyleManager::Default()->AddStyle(style); diff --git a/src/apps/icon-o-matic/document/IconRenderer.cpp b/src/apps/icon-o-matic/document/IconRenderer.cpp index 95277293ff..8e90962d26 100644 --- a/src/apps/icon-o-matic/document/IconRenderer.cpp +++ b/src/apps/icon-o-matic/document/IconRenderer.cpp @@ -14,7 +14,10 @@ #include #include "agg_conv_curve.h" +#include "agg_span_gradient.h" +#include "agg_span_interpolator_linear.h" +#include "Gradient.h" #include "Icon.h" #include "Shape.h" #include "ShapeContainer.h" @@ -43,37 +46,133 @@ class StyleHandler { return style->Gradient() == NULL; } - const agg::rgba8& color(unsigned styleIndex) - { - Style* style = fStyles->StyleAt(styleIndex); - if (!style) { - printf("no style at index: %d!\n", styleIndex); - return fTransparent; - } - - const rgb_color& c = style->Color(); - fColor = agg::rgba8(fGammaTable.dir(c.red), - fGammaTable.dir(c.green), - fGammaTable.dir(c.blue), - c.alpha); - fColor.premultiply(); - return fColor; - } + const agg::rgba8& color(unsigned styleIndex); void generate_span(agg::rgba8* span, int x, int y, - unsigned len, unsigned styleIndex) - { -printf("unimplemented: generate_span(%p, %d, %d, %d)\n", span, x, y, len); - // TODO: render gradient of Style at styleIndex into span - } + unsigned len, unsigned styleIndex); private: + template + void _GenerateGradient(agg::rgba8* span, int x, int y, unsigned len, + GradientFunction function, + const agg::rgba8* gradientColors, + agg::trans_affine& gradientTransform); + const StyleManager* fStyles; GammaTable& fGammaTable; agg::rgba8 fTransparent; agg::rgba8 fColor; }; +// color +const agg::rgba8& +StyleHandler::color(unsigned styleIndex) +{ + Style* style = fStyles->StyleAt(styleIndex); + if (!style) { + printf("no style at index: %d!\n", styleIndex); + return fTransparent; + } + + const rgb_color& c = style->Color(); + fColor = agg::rgba8(fGammaTable.dir(c.red), + fGammaTable.dir(c.green), + fGammaTable.dir(c.blue), + c.alpha); + fColor.premultiply(); + return fColor; +} + +// generate_span +void +StyleHandler::generate_span(agg::rgba8* span, int x, int y, + unsigned len, unsigned styleIndex) +{ + Style* style = fStyles->StyleAt(styleIndex); + if (!style || !style->Gradient()) { + printf("no style/gradient at index: %d!\n", styleIndex); + // TODO: memset() span? + return; + } + + Gradient* gradient = style->Gradient(); + + // TODO: move filling of color array elsewhere and cache result + // maybe in Style? + agg::rgba8 colors[256]; + gradient->MakeGradient((uint32*)colors, 256); + + agg::trans_affine transformation; + // TODO: construct the gradient transformation here + + switch (gradient->Type()) { + case GRADIENT_LINEAR: { + agg::gradient_x function; + _GenerateGradient(span, x, y, len, function, colors, + transformation); + break; + } + case GRADIENT_CIRCULAR: { + agg::gradient_radial function; + _GenerateGradient(span, x, y, len, function, colors, + transformation); + break; + } + case GRADIENT_DIAMONT: { + agg::gradient_diamond function; + _GenerateGradient(span, x, y, len, function, colors, + transformation); + break; + } + case GRADIENT_CONIC: { + agg::gradient_conic function; + _GenerateGradient(span, x, y, len, function, colors, + transformation); + break; + } + case GRADIENT_XY: { + agg::gradient_xy function; + _GenerateGradient(span, x, y, len, function, colors, + transformation); + break; + } + case GRADIENT_SQRT_XY: { + agg::gradient_sqrt_xy function; + _GenerateGradient(span, x, y, len, function, colors, + transformation); + break; + } + } +} + +// _GenerateGradient +template +void +StyleHandler::_GenerateGradient(agg::rgba8* span, int x, int y, unsigned len, + GradientFunction function, + const agg::rgba8* gradientColors, + agg::trans_affine& gradientTransform) + +{ + typedef agg::pod_auto_array ColorArray; + typedef agg::span_interpolator_linear<> Interpolator; + typedef agg::span_gradient GradientGenerator; + + Interpolator interpolator(gradientTransform); + + ColorArray array(gradientColors); + GradientGenerator gradientGenerator(interpolator, + function, + array, + 0, 100); + + gradientGenerator.generate(span, x, y, len); +} + +// #pragma mark - // constructor IconRenderer::IconRenderer(BBitmap* bitmap) @@ -81,7 +180,7 @@ IconRenderer::IconRenderer(BBitmap* bitmap) fIcon(NULL), fStyles(StyleManager::Default()), - fGammaTable(1.0), + fGammaTable(2.2), fRenderingBuffer(), fPixelFormat(fRenderingBuffer), diff --git a/src/apps/icon-o-matic/gradient/Gradient.cpp b/src/apps/icon-o-matic/gradient/Gradient.cpp index 5c76082c59..8539c7b474 100644 --- a/src/apps/icon-o-matic/gradient/Gradient.cpp +++ b/src/apps/icon-o-matic/gradient/Gradient.cpp @@ -392,9 +392,9 @@ Gradient::MakeGradient(uint32* colors, int32 count) const if (index > 0) { uint8* c = (uint8*)&colors[0]; for (int32 i = 0; i < index; i++) { - c[0] = from->color.blue; + c[0] = from->color.red; c[1] = from->color.green; - c[2] = from->color.red; + c[2] = from->color.blue; c[3] = from->color.alpha; c += 4; } @@ -457,9 +457,9 @@ Gradient::MakeGradient(uint32* colors, int32 count) const if (fInterpolation == INTERPOLATION_SMOOTH) f = gauss(1.0 - f); float t = 1.0 - f; - c[0] = (uint8)floor(from->color.blue * f + to->color.blue * t + 0.5); + c[0] = (uint8)floor(from->color.red * f + to->color.red * t + 0.5); c[1] = (uint8)floor(from->color.green * f + to->color.green * t + 0.5); - c[2] = (uint8)floor(from->color.red * f + to->color.red * t + 0.5); + c[2] = (uint8)floor(from->color.blue * f + to->color.blue * t + 0.5); c[3] = (uint8)floor(from->color.alpha * f + to->color.alpha * t + 0.5); c += 4; } @@ -473,9 +473,9 @@ Gradient::MakeGradient(uint32* colors, int32 count) const if (index < count) { uint8* c = (uint8*)&colors[index]; for (int32 i = index; i < count; i++) { - c[0] = from->color.blue; + c[0] = from->color.red; c[1] = from->color.green; - c[2] = from->color.red; + c[2] = from->color.blue; c[3] = from->color.alpha; c += 4; }