complete rework of the drawing_modes implementation... I achieved a speedup of 8 to 9 times, tested with text rendering. Believe it or not, but the Haiku text rendering is now faster than R5 for B_OP_COPY at least. And there is quite some room for improvement yet. (faster text bounding box calculation, avoiding the double UTF8 conversion, etc)

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15596 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-12-19 21:22:03 +00:00
parent 270b7f58b6
commit 8d7b8e8ce7
26 changed files with 2145 additions and 3724 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ StaticLibrary libpainter.a :
Transformable.cpp Transformable.cpp
# drawing_modes # drawing_modes
DrawingModeFactory.cpp PixelFormat.cpp
# font_support # font_support
# is contained within libagg.a, # is contained within libagg.a,
+19 -45
View File
@@ -30,7 +30,6 @@
#include "AGGTextRenderer.h" #include "AGGTextRenderer.h"
#include "DrawingMode.h" #include "DrawingMode.h"
#include "DrawingModeFactory.h"
#include "PatternHandler.h" #include "PatternHandler.h"
#include "RenderingBuffer.h" #include "RenderingBuffer.h"
#include "ServerBitmap.h" #include "ServerBitmap.h"
@@ -84,7 +83,6 @@ Painter::Painter()
fLineJoinMode(B_MITER_JOIN), fLineJoinMode(B_MITER_JOIN),
fMiterLimit(B_DEFAULT_MITER_LIMIT), fMiterLimit(B_DEFAULT_MITER_LIMIT),
fDrawingModeFactory(new DrawingModeFactory()),
fPatternHandler(new PatternHandler()), fPatternHandler(new PatternHandler()),
fTextRenderer(new AGGTextRenderer()) fTextRenderer(new AGGTextRenderer())
{ {
@@ -103,7 +101,6 @@ Painter::~Painter()
_MakeEmpty(); _MakeEmpty();
delete fClippingRegion; delete fClippingRegion;
delete fDrawingModeFactory;
delete fPatternHandler; delete fPatternHandler;
delete fTextRenderer; delete fTextRenderer;
} }
@@ -127,10 +124,7 @@ Painter::AttachToBuffer(RenderingBuffer* buffer)
buffer->BytesPerRow()); buffer->BytesPerRow());
fPixelFormat = new pixfmt(*fBuffer, fPatternHandler); fPixelFormat = new pixfmt(*fBuffer, fPatternHandler);
fPixelFormat->set_drawing_mode(fDrawingModeFactory->DrawingModeFor(fDrawingMode, fPixelFormat->SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode);
fAlphaSrcMode,
fAlphaFncMode,
false));
fBaseRenderer = new renderer_base(*fPixelFormat); fBaseRenderer = new renderer_base(*fPixelFormat);
// attach our clipping region to the renderer, it keeps a pointer // attach our clipping region to the renderer, it keeps a pointer
@@ -1176,29 +1170,14 @@ Painter::_UpdateDrawingMode()
// has to be called so that all internal colors in the renderes // has to be called so that all internal colors in the renderes
// are up to date for use by the solid drawing mode version. // are up to date for use by the solid drawing mode version.
if (fPixelFormat) { if (fPixelFormat) {
DrawingMode* mode = NULL; if (fPatternHandler->IsSolidHigh()) {
pattern p = *fPatternHandler->GetR5Pattern();
if (p == B_SOLID_HIGH) {
// TODO: fix me! is already set in SetHighColor() // TODO: fix me! is already set in SetHighColor()
_SetRendererColor(fPatternHandler->HighColor().GetColor32()); _SetRendererColor(fPatternHandler->HighColor().GetColor32());
mode = fDrawingModeFactory->DrawingModeFor(fDrawingMode, } else if (fPatternHandler->IsSolidLow()) {
fAlphaSrcMode,
fAlphaFncMode,
true);
} else if (p == B_SOLID_LOW) {
// TODO: fix me! is already set in SetLowColor() // TODO: fix me! is already set in SetLowColor()
_SetRendererColor(fPatternHandler->LowColor().GetColor32()); _SetRendererColor(fPatternHandler->LowColor().GetColor32());
mode = fDrawingModeFactory->DrawingModeFor(fDrawingMode,
fAlphaSrcMode,
fAlphaFncMode,
true);
} else {
mode = fDrawingModeFactory->DrawingModeFor(fDrawingMode,
fAlphaSrcMode,
fAlphaFncMode,
false);
} }
fPixelFormat->set_drawing_mode(mode); fPixelFormat->SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode);
} }
} }
@@ -1381,11 +1360,7 @@ Painter::_DrawBitmap32(const agg::rendering_buffer& srcBuffer,
{ {
typedef agg::span_allocator<agg::rgba8> span_alloc_type; typedef agg::span_allocator<agg::rgba8> span_alloc_type;
// pipeline for non-scaled bitmaps // AGG pipeline
//typedef agg::span_generator<agg::rgba8, span_alloc_type> span_gen_type;
//typedef agg::renderer_scanline_aa<renderer_base, span_gen_type> image_renderer_type;
// pipeline for scaled bitmaps
typedef agg::span_interpolator_linear<> interpolator_type; typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_image_filter_rgba32_nn<agg::order_bgra32, typedef agg::span_image_filter_rgba32_nn<agg::order_bgra32,
interpolator_type> scaled_span_gen_type; interpolator_type> scaled_span_gen_type;
@@ -1398,7 +1373,8 @@ typedef agg::renderer_scanline_aa<renderer_base, scaled_span_gen_type> scaled_im
// compensate for the lefttop offset the actualBitmapRect might have // compensate for the lefttop offset the actualBitmapRect might have
// NOTE: I have no clue why enabling the next call gives a wrong result! // NOTE: I have no clue why enabling the next call gives a wrong result!
// According to the BeBook, bitmapRect is supposed to be in native // According to the BeBook, bitmapRect is supposed to be in native
// bitmap space! // bitmap space! Disabling this call makes it look like the bitmap bounds are
// assumed to have a left/top coord of 0,0 at all times. This is simply not true.
// bitmapRect.OffsetBy(-actualBitmapRect.left, -actualBitmapRect.top); // bitmapRect.OffsetBy(-actualBitmapRect.left, -actualBitmapRect.top);
actualBitmapRect.OffsetBy(-actualBitmapRect.left, -actualBitmapRect.top); actualBitmapRect.OffsetBy(-actualBitmapRect.left, -actualBitmapRect.top);
@@ -1406,6 +1382,9 @@ typedef agg::renderer_scanline_aa<renderer_base, scaled_span_gen_type> scaled_im
double xScale = (viewRect.Width() + 1) / (bitmapRect.Width() + 1); double xScale = (viewRect.Width() + 1) / (bitmapRect.Width() + 1);
double yScale = (viewRect.Height() + 1) / (bitmapRect.Height() + 1); double yScale = (viewRect.Height() + 1) / (bitmapRect.Height() + 1);
if (xScale == 0.0 || yScale == 0.0)
return;
// constrain rect to passed bitmap bounds // constrain rect to passed bitmap bounds
// and transfer the changes to the viewRect // and transfer the changes to the viewRect
if (bitmapRect.left < actualBitmapRect.left) { if (bitmapRect.left < actualBitmapRect.left) {
@@ -1446,33 +1425,28 @@ typedef agg::renderer_scanline_aa<renderer_base, scaled_span_gen_type> scaled_im
agg::rasterizer_scanline_aa<> pf; agg::rasterizer_scanline_aa<> pf;
agg::scanline_u8 sl; agg::scanline_u8 sl;
// clip to the current clipping region's frame
viewRect = viewRect & fClippingRegion->Frame();
// convert to pixel coords (versus pixel indices)
viewRect.right++;
viewRect.bottom++;
// path encloses image // path encloses image
agg::path_storage path; agg::path_storage path;
path.move_to(viewRect.left, viewRect.top); path.move_to(viewRect.left, viewRect.top);
path.line_to(viewRect.right + 1, viewRect.top); path.line_to(viewRect.right, viewRect.top);
path.line_to(viewRect.right + 1, viewRect.bottom + 1); path.line_to(viewRect.right, viewRect.bottom);
path.line_to(viewRect.left, viewRect.bottom + 1); path.line_to(viewRect.left, viewRect.bottom);
path.close_polygon(); path.close_polygon();
agg::conv_transform<agg::path_storage> tr(path, srcMatrix); agg::conv_transform<agg::path_storage> tr(path, srcMatrix);
pf.add_path(tr); pf.add_path(tr);
// if (xScale != 1.0 || yScale != 1.0) {
//printf("scaled\n");
scaled_span_gen_type sg(sa, srcBuffer, agg::rgba(0, 0, 0, 0), interpolator); scaled_span_gen_type sg(sa, srcBuffer, agg::rgba(0, 0, 0, 0), interpolator);
scaled_image_renderer_type ri(*fBaseRenderer, sg); scaled_image_renderer_type ri(*fBaseRenderer, sg);
agg::render_scanlines(pf, sl, ri); agg::render_scanlines(pf, sl, ri);
/* } else {
// TODO: Does not even compile, find out how to construct a pipeline without
// scaling
printf("non scaled scaled\n");
span_gen_type sg(sa);
image_renderer_type ri(*fBaseRenderer, sg);
agg::render_scanlines(pf, sl, ri);
}*/
} }
} }
@@ -16,7 +16,6 @@
#include <ServerFont.h> #include <ServerFont.h>
#include "defines.h" #include "defines.h"
#include "forwarding_pixfmt.h"
#include "RGBColor.h" #include "RGBColor.h"
@@ -24,7 +23,6 @@ class AGGTextRenderer;
class BBitmap; class BBitmap;
class BRegion; class BRegion;
class DrawState; class DrawState;
class DrawingModeFactory;
class PatternHandler; class PatternHandler;
class RenderingBuffer; class RenderingBuffer;
class ServerBitmap; class ServerBitmap;
@@ -301,7 +299,6 @@ class Painter {
join_mode fLineJoinMode; join_mode fLineJoinMode;
float fMiterLimit; float fMiterLimit;
DrawingModeFactory* fDrawingModeFactory;
PatternHandler* fPatternHandler; PatternHandler* fPatternHandler;
ServerFont fFont; ServerFont fFont;
+2 -4
View File
@@ -24,13 +24,11 @@
#include "agg_renderer_region.h" #include "agg_renderer_region.h"
//#include "_for_reference_.h" #include "PixelFormat.h"
#include "forwarding_pixfmt.h"
#define ALIASED_DRAWING 0 #define ALIASED_DRAWING 0
// typedef agg::pixfmt_bgra32 pixfmt; typedef PixelFormat pixfmt;
typedef forwarding_pixel_format<agg::order_bgra32> pixfmt;
typedef agg::renderer_region<pixfmt> renderer_base; typedef agg::renderer_region<pixfmt> renderer_base;
#if ALIASED_DRAWING #if ALIASED_DRAWING
@@ -9,14 +9,14 @@
#ifndef DRAWING_MODE_H #ifndef DRAWING_MODE_H
#define DRAWING_MODE_H #define DRAWING_MODE_H
#include <stdio.h> #include "PatternHandler.h"
#include <string.h> #include "PixelFormat.h"
#include <agg_basics.h>
#include <agg_color_rgba8.h>
#include <agg_rendering_buffer.h>
class PatternHandler; class PatternHandler;
typedef PixelFormat::color_type color_type;
typedef PixelFormat::agg_buffer agg_buffer;
union pixel32 { union pixel32 {
uint32 data32; uint32 data32;
uint8 data8[4]; uint8 data8[4];
@@ -27,12 +27,13 @@ union pixel32 {
// This macro assumes source alpha in range 0..255 and // This macro assumes source alpha in range 0..255 and
// ignores dest alpha (is assumed to equal 255). // ignores dest alpha (is assumed to equal 255).
// TODO: We need the assignment of alpha only when drawing into bitmaps! // TODO: We need the assignment of alpha only when drawing into bitmaps!
#define BLEND(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND(d, r, g, b, a) \
{ \ { \
(d1) = (((((s1) - (d1)) * (a)) + ((d1) << 8)) >> 8); \ pixel32 _p; \
(d2) = (((((s2) - (d2)) * (a)) + ((d2) << 8)) >> 8); \ _p.data32 = *(uint32*)d; \
(d3) = (((((s3) - (d3)) * (a)) + ((d3) << 8)) >> 8); \ d[0] = (((((b) - _p.data8[0]) * (a)) + (_p.data8[0] << 8)) >> 8); \
(da) = max_c((da), (a)); \ d[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 8)) >> 8); \
d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 8)) >> 8); \
} }
// BLEND_FROM // BLEND_FROM
@@ -42,12 +43,11 @@ union pixel32 {
// It uses two colors for the blending (f and s) and writes // It uses two colors for the blending (f and s) and writes
// the result into a third color (d). // the result into a third color (d).
// TODO: We need the assignment of alpha only when drawing into bitmaps! // TODO: We need the assignment of alpha only when drawing into bitmaps!
#define BLEND_FROM(d1, d2, d3, da, f1, f2, f3, s1, s2, s3, a) \ #define BLEND_FROM(d, r1, g1, b1, r2, g2, b2, a) \
{ \ { \
(d1) = (((((s1) - (f1)) * (a)) + ((f1) << 8)) >> 8); \ d[0] = (((((b2) - (b1)) * (a)) + ((b1) << 8)) >> 8); \
(d2) = (((((s2) - (f2)) * (a)) + ((f2) << 8)) >> 8); \ d[1] = (((((g2) - (g1)) * (a)) + ((g1) << 8)) >> 8); \
(d3) = (((((s3) - (f3)) * (a)) + ((f3) << 8)) >> 8); \ d[2] = (((((r2) - (r1)) * (a)) + ((r1) << 8)) >> 8); \
(da) = max_c((da), (a)); \
} }
// BLEND16 // BLEND16
@@ -55,31 +55,37 @@ union pixel32 {
// This macro assumes source alpha in range 0..65025 and // This macro assumes source alpha in range 0..65025 and
// ignores dest alpha (is assumed to equal 255). // ignores dest alpha (is assumed to equal 255).
// TODO: We need the assignment of alpha only when drawing into bitmaps! // TODO: We need the assignment of alpha only when drawing into bitmaps!
#define BLEND16(d1, d2, d3, da, s1, s2, s3, a) \ // BLEND16
#define BLEND16(d, r, g, b, a) \
{ \ { \
(d1) = (((((s1) - (d1)) * (a)) + ((d1) << 16)) >> 16); \ pixel32 _p; \
(d2) = (((((s2) - (d2)) * (a)) + ((d2) << 16)) >> 16); \ _p.data32 = *(uint32*)d; \
(d3) = (((((s3) - (d3)) * (a)) + ((d3) << 16)) >> 16); \ d[0] = (((((b) - _p.data8[0]) * (a)) + (_p.data8[0] << 16)) >> 16); \
(da) = max_c((da), (a) >> 8); \ d[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 16)) >> 16); \
d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 16)) >> 16); \
} }
// BLEND_COMPOSITE // BLEND_COMPOSITE
// //
// This macro assumes source alpha in range 0..255 and // This macro assumes source alpha in range 0..255 and
// composes the source color over a possibly semi-transparent background. // composes the source color over a possibly semi-transparent background.
#define BLEND_COMPOSITE(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_COMPOSITE(d, r, g, b, a) \
{ \ { \
if ((da) == 255) { \ pixel32 _p; \
BLEND(d1, d2, d3, da, s1, s2, s3, a); \ _p.data32 = *(uint32*)d; \
if (_p.data8[3] == 255) { \
BLEND(d, r, g, b, a); \
} else { \ } else { \
uint8 alphaRest = 255 - (a); \ uint8 alphaRest = 255 - (a); \
uint32 alphaTemp = (65025 - alphaRest * (255 - (da))); \ uint32 alphaTemp = (65025 - alphaRest * (255 - _p.data8[3])); \
uint32 alphaDest = (da) * alphaRest; \ uint32 alphaDest = _p.data8[3] * alphaRest; \
uint32 alphaSrc = 255 * (a); \ uint32 alphaSrc = 255 * (a); \
(d1) = ((d1) * alphaDest + (s2) * alphaSrc) / alphaTemp; \ d[0] = (_p.data8[0] * alphaDest + (b) * alphaSrc) / alphaTemp; \
(d2) = ((d2) * alphaDest + (s2) * alphaSrc) / alphaTemp; \ d[1] = (_p.data8[1] * alphaDest + (g) * alphaSrc) / alphaTemp; \
(d3) = ((d3) * alphaDest + (s3) * alphaSrc) / alphaTemp; \ d[2] = (_p.data8[2] * alphaDest + (r) * alphaSrc) / alphaTemp; \
(da) = alphaTemp >> 8; \ d[3] = alphaTemp >> 8; \
} \ } \
} }
@@ -88,68 +94,11 @@ union pixel32 {
// This macro assumes source alpha in range 0..65025 and // This macro assumes source alpha in range 0..65025 and
// composes the source color over a possibly semi-transparent background. // composes the source color over a possibly semi-transparent background.
// TODO: implement a faster version // TODO: implement a faster version
#define BLEND_COMPOSITE16(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_COMPOSITE16(d, r, g, b, a) \
{ \ { \
BLEND_COMPOSITE(d1, d2, d3, da, s1, s2, s3, (a) >> 8); \ BLEND_COMPOSITE(d, r, g, b, (a) >> 8); \
} }
class DrawingMode {
public:
typedef agg::rgba8 color_type;
// constructor
DrawingMode()
: fBuffer(NULL)
{
}
// destructor
virtual ~DrawingMode()
{
}
// set_rendering_buffer
void set_rendering_buffer(agg::rendering_buffer* buffer)
{
fBuffer = buffer;
}
// set_pattern_handler
void set_pattern_handler(const PatternHandler* handler)
{
fPatternHandler = handler;
}
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover) = 0;
virtual void blend_hline(int x, int y, unsigned len,
const color_type& c, uint8 cover) = 0;
virtual void blend_vline(int x, int y, unsigned len,
const color_type& c, uint8 cover) = 0;
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers) = 0;
virtual void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers) = 0;
virtual void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover) = 0;
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover) = 0;
protected:
agg::rendering_buffer* fBuffer;
const PatternHandler* fPatternHandler;
};
#endif // DRAWING_MODE_H #endif // DRAWING_MODE_H
@@ -9,153 +9,136 @@
#ifndef DRAWING_MODE_ADD_H #ifndef DRAWING_MODE_ADD_H
#define DRAWING_MODE_ADD_H #define DRAWING_MODE_ADD_H
#include <SupportDefs.h>
#include "DrawingMode.h" #include "DrawingMode.h"
#include "PatternHandler.h"
// BLEND_ADD // BLEND_ADD
#define BLEND_ADD(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_ADD(d, r, g, b, a) \
{ \ { \
uint8 t1 = min_c(255, (d1) + (s1)); \ pixel32 _p; \
uint8 t2 = min_c(255, (d2) + (s2)); \ _p.data32 = *(uint32*)d; \
uint8 t3 = min_c(255, (d3) + (s3)); \ uint8 rt = min_c(255, _p.data8[2] + (r)); \
BLEND(d1, d2, d3, da, t1, t2, t3, a); \ uint8 gt = min_c(255, _p.data8[1] + (g)); \
uint8 bt = min_c(255, _p.data8[0] + (b)); \
BLEND(d, rt, gt, bt, a); \
} }
//ASSIGN_ADD //ASSIGN_ADD
#define ASSIGN_ADD(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_ADD(d, r, g, b) \
{ \ { \
(d1) = min_c(255, (d1) + (s1)); \ pixel32 _p; \
(d2) = min_c(255, (d2) + (s2)); \ _p.data32 = *(uint32*)d; \
(d3) = min_c(255, (d3) + (s3)); \ d[0] = min_c(255, _p.data8[0] + (b)); \
(da) = 255; \ d[1] = min_c(255, _p.data8[1] + (g)); \
d[2] = min_c(255, _p.data8[2] + (r)); \
} }
template<class Order> // blend_pixel_add
class DrawingModeAdd : public DrawingMode { void
public: blend_pixel_add(int x, int y, const color_type& c, uint8 cover,
// constructor agg_buffer* buffer, const PatternHandler* pattern)
DrawingModeAdd() {
: DrawingMode() uint8* p = buffer->row(y) + (x << 2);
{ rgb_color color = pattern->R5ColorAt(x, y);
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->R5ColorAt(x, y);
if (cover == 255) { if (cover == 255) {
ASSIGN_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ADD(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ADD(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
}
} }
}
// blend_hline // blend_hline_add
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_add(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
if (cover == 255) { if (cover == 255) {
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
ASSIGN_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ADD(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} else { } else {
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
BLEND_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ADD(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_add
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_add(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeAdd::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ADD(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ADD(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
covers++; covers++;
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_add
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_add(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ADD(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ADD(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_add
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_add(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ADD(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ADD(p, colors->r, colors->g, colors->b, *covers);
colors->r, colors->g, colors->b, *covers);
} }
} }
covers++; covers++;
@@ -166,39 +149,20 @@ printf("DrawingModeAdd::blend_vline()\n");
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ADD(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (cover) { } else if (cover) {
do { do {
BLEND_ADD(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ADD(p, colors->r, colors->g, colors->b, cover);
colors->r, colors->g, colors->b, cover);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeAdd::blend_color_vspan()\n");
}
};
typedef DrawingModeAdd<agg::order_rgba32> DrawingModeRGBA32Add;
typedef DrawingModeAdd<agg::order_argb32> DrawingModeARGB32Add;
typedef DrawingModeAdd<agg::order_abgr32> DrawingModeABGR32Add;
typedef DrawingModeAdd<agg::order_bgra32> DrawingModeBGRA32Add;
#endif // DRAWING_MODE_ADD_H #endif // DRAWING_MODE_ADD_H
@@ -12,72 +12,63 @@
#include "DrawingMode.h" #include "DrawingMode.h"
// BLEND_ALPHA_CC // BLEND_ALPHA_CC
#define BLEND_ALPHA_CC(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_ALPHA_CC(d, r, g, b, a) \
{ \ { \
BLEND_COMPOSITE16(d1, d2, d3, da, s1, s2, s3, a); \ BLEND_COMPOSITE16(d, r, g, b, a); \
} }
// ASSIGN_ALPHA_CC // ASSIGN_ALPHA_CC
#define ASSIGN_ALPHA_CC(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_ALPHA_CC(d, r, g, b) \
{ \ { \
(d1) = (s1); \ d[0] = (r); \
(d2) = (s2); \ d[1] = (g); \
(d3) = (s3); \ d[2] = (b); \
(da) = 255; \
} }
// blend_pixel_alpha_cc
template<class Order> void
class DrawingModeAlphaCC : public DrawingMode { blend_pixel_alpha_cc(int x, int y, const color_type& c, uint8 cover,
public: agg_buffer* buffer, const PatternHandler* pattern)
// constructor {
DrawingModeAlphaCC() uint8* p = buffer->row(y) + (x << 2);
: DrawingMode() rgb_color color = pattern->R5ColorAt(x, y);
{ uint16 alpha = pattern->HighColor().GetColor32().alpha * cover;
} if (alpha == 255 * 255) {
ASSIGN_ALPHA_CC(p, color.red, color.green, color.blue);
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->R5ColorAt(x, y);
uint16 alpha = fPatternHandler->HighColor().GetColor32().alpha * cover;
if (alpha == 255*255) {
ASSIGN_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CC(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
}
} }
}
// blend_hline // blend_hline_alpha_cc
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_alpha_cc(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
rgb_color color = fPatternHandler->HighColor().GetColor32(); agg_buffer* buffer, const PatternHandler* pattern)
{
rgb_color color = pattern->HighColor().GetColor32();
uint16 alpha = color.alpha * cover; uint16 alpha = color.alpha * cover;
if (alpha == 255*255) { if (alpha == 255 * 255) {
// cache the low and high color as 32bit values // cache the low and high color as 32bit values
// high color // high color
uint32 vh; uint32 vh;
uint8* p8 = (uint8*)&vh; uint8* p8 = (uint8*)&vh;
p8[Order::R] = color.red; p8[0] = color.blue;
p8[Order::G] = color.green; p8[1] = color.green;
p8[Order::B] = color.blue; p8[2] = color.red;
p8[Order::A] = 255; p8[3] = 255;
// low color // low color
color = fPatternHandler->LowColor().GetColor32(); color = pattern->LowColor().GetColor32();
uint32 vl; uint32 vl;
p8 = (uint8*)&vl; p8 = (uint8*)&vl;
p8[Order::R] = color.red; p8[0] = color.blue;
p8[Order::G] = color.green; p8[1] = color.green;
p8[Order::B] = color.blue; p8[2] = color.red;
p8[Order::A] = 255; p8[3] = 255;
// row offset as 32 bit pointer // row offset as 32 bit pointer
uint32* p32 = (uint32*)(fBuffer->row(y)) + x; uint32* p32 = (uint32*)(buffer->row(y)) + x;
do { do {
if (fPatternHandler->IsHighColor(x, y)) if (pattern->IsHighColor(x, y))
*p32 = vh; *p32 = vh;
else else
*p32 = vl; *p32 = vl;
@@ -85,94 +76,83 @@ class DrawingModeAlphaCC : public DrawingMode {
x++; x++;
} while(--len); } while(--len);
} else { } else {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
BLEND_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CC(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_alpha_cc
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_alpha_cc(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeAlphaCC::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan uint8 hAlpha = pattern->HighColor().GetColor32().alpha;
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
uint8 hAlpha = fPatternHandler->HighColor().GetColor32().alpha;
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
uint16 alpha = hAlpha * *covers; uint16 alpha = hAlpha * *covers;
if (alpha) { if (alpha) {
if (alpha == 255*255) { if (alpha == 255 * 255) {
ASSIGN_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_CC(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CC(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
} }
} }
covers++; covers++;
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan_alpha_cc
void
// blend_solid_vspan blend_solid_vspan_alpha_cc(int x, int y, unsigned len,
virtual void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const uint8* covers,
const color_type& c, const uint8* covers) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
uint8 hAlpha = fPatternHandler->HighColor().GetColor32().alpha; uint8 hAlpha = pattern->HighColor().GetColor32().alpha;
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
uint16 alpha = hAlpha * *covers; uint16 alpha = hAlpha * *covers;
if (alpha) { if (alpha) {
if (alpha == 255*255) { if (alpha == 255 * 255) {
ASSIGN_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_CC(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CC(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_alpha_cc
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_alpha_cc(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
uint8 hAlpha = fPatternHandler->HighColor().GetColor32().alpha; uint8 hAlpha = pattern->HighColor().GetColor32().alpha;
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
uint16 alpha = hAlpha * *covers; uint16 alpha = hAlpha * *covers;
if (alpha) { if (alpha) {
if (alpha == 255*255) { if (alpha == 255 * 255) {
ASSIGN_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_CC(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CC(p, colors->r, colors->g, colors->b, alpha);
colors->r, colors->g, colors->b, alpha);
} }
} }
covers++; covers++;
@@ -182,41 +162,22 @@ printf("DrawingModeAlphaCC::blend_vline()\n");
} else { } else {
// solid full opcacity // solid full opcacity
uint16 alpha = hAlpha * cover; uint16 alpha = hAlpha * cover;
if (alpha == 255*255) { if (alpha == 255 * 255) {
do { do {
ASSIGN_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_CC(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (alpha) { } else if (alpha) {
do { do {
BLEND_ALPHA_CC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CC(p, colors->r, colors->g, colors->b, alpha);
colors->r, colors->g, colors->b, alpha);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeAlphaCC::blend_color_vspan()\n");
}
};
typedef DrawingModeAlphaCC<agg::order_rgba32> DrawingModeRGBA32AlphaCC;
typedef DrawingModeAlphaCC<agg::order_argb32> DrawingModeARGB32AlphaCC;
typedef DrawingModeAlphaCC<agg::order_abgr32> DrawingModeABGR32AlphaCC;
typedef DrawingModeAlphaCC<agg::order_bgra32> DrawingModeBGRA32AlphaCC;
#endif // DRAWING_MODE_ALPHA_CC_H #endif // DRAWING_MODE_ALPHA_CC_H
@@ -12,72 +12,63 @@
#include "DrawingMode.h" #include "DrawingMode.h"
// BLEND_ALPHA_CO // BLEND_ALPHA_CO
#define BLEND_ALPHA_CO(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_ALPHA_CO(d, r, g, b, a) \
{ \ { \
BLEND16(d1, d2, d3, da, s1, s2, s3, a); \ BLEND16(d, r, g, b, a); \
} }
// ASSIGN_ALPHA_CO // ASSIGN_ALPHA_CO
#define ASSIGN_ALPHA_CO(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_ALPHA_CO(d, r, g, b) \
{ \ { \
(d1) = (s1); \ d[0] = (b); \
(d2) = (s2); \ d[1] = (g); \
(d3) = (s3); \ d[2] = (r); \
(da) = 255; \
} }
// blend_pixel_alpha_co
template<class Order> void
class DrawingModeAlphaCO : public DrawingMode { blend_pixel_alpha_co(int x, int y, const color_type& c, uint8 cover,
public: agg_buffer* buffer, const PatternHandler* pattern)
// constructor {
DrawingModeAlphaCO() uint8* p = buffer->row(y) + (x << 2);
: DrawingMode() rgb_color color = pattern->R5ColorAt(x, y);
{ uint16 alpha = pattern->HighColor().GetColor32().alpha * cover;
} if (alpha == 255 * 255) {
ASSIGN_ALPHA_CO(p, color.red, color.green, color.blue);
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->R5ColorAt(x, y);
uint16 alpha = fPatternHandler->HighColor().GetColor32().alpha * cover;
if (alpha == 255*255) {
ASSIGN_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
}
} }
}
// blend_hline // blend_hline_alpha_co
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_alpha_co(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
rgb_color color = fPatternHandler->HighColor().GetColor32(); agg_buffer* buffer, const PatternHandler* pattern)
{
rgb_color color = pattern->HighColor().GetColor32();
uint16 alpha = color.alpha * cover; uint16 alpha = color.alpha * cover;
if (alpha == 255*255) { if (alpha == 255*255) {
// cache the low and high color as 32bit values // cache the low and high color as 32bit values
// high color // high color
uint32 vh; uint32 vh;
uint8* p8 = (uint8*)&vh; uint8* p8 = (uint8*)&vh;
p8[Order::R] = color.red; p8[0] = color.blue;
p8[Order::G] = color.green; p8[1] = color.green;
p8[Order::B] = color.blue; p8[2] = color.red;
p8[Order::A] = 255; p8[3] = 255;
// low color // low color
color = fPatternHandler->LowColor().GetColor32(); color = pattern->LowColor().GetColor32();
uint32 vl; uint32 vl;
p8 = (uint8*)&vl; p8 = (uint8*)&vl;
p8[Order::R] = color.red; p8[0] = color.blue;
p8[Order::G] = color.green; p8[1] = color.green;
p8[Order::B] = color.blue; p8[2] = color.red;
p8[Order::A] = 255; p8[3] = 255;
// row offset as 32bit pointer // row offset as 32bit pointer
uint32* p32 = (uint32*)(fBuffer->row(y)) + x; uint32* p32 = (uint32*)(buffer->row(y)) + x;
do { do {
if (fPatternHandler->IsHighColor(x, y)) if (pattern->IsHighColor(x, y))
*p32 = vh; *p32 = vh;
else else
*p32 = vl; *p32 = vl;
@@ -85,94 +76,85 @@ class DrawingModeAlphaCO : public DrawingMode {
x++; x++;
} while(--len); } while(--len);
} else { } else {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
BLEND_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_alpha_co
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_alpha_co(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeAlphaCO::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan uint8 hAlpha = pattern->HighColor().GetColor32().alpha;
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
uint8 hAlpha = fPatternHandler->HighColor().GetColor32().alpha;
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
uint16 alpha = hAlpha * *covers; uint16 alpha = hAlpha * *covers;
if (alpha) { if (alpha) {
if (alpha == 255*255) { if (alpha == 255 * 255) {
ASSIGN_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_CO(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
} }
} }
covers++; covers++;
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_alpha_co
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_alpha_co(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
uint8 hAlpha = fPatternHandler->HighColor().GetColor32().alpha; {
uint8* p = buffer->row(y) + (x << 2);
uint8 hAlpha = pattern->HighColor().GetColor32().alpha;
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
uint16 alpha = hAlpha * *covers; uint16 alpha = hAlpha * *covers;
if (alpha) { if (alpha) {
if (alpha == 255*255) { if (alpha == 255 * 255) {
ASSIGN_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_CO(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_alpha_co
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_alpha_co(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
uint8 hAlpha = fPatternHandler->HighColor().GetColor32().alpha; uint8 hAlpha = pattern->HighColor().GetColor32().alpha;
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
uint16 alpha = hAlpha * *covers; uint16 alpha = hAlpha * *covers;
if (alpha) { if (alpha) {
if (alpha == 255*255) { if (alpha == 255*255) {
ASSIGN_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_CO(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CO(p, colors->r, colors->g, colors->b, alpha);
colors->r, colors->g, colors->b, alpha);
} }
} }
covers++; covers++;
@@ -182,41 +164,22 @@ printf("DrawingModeAlphaCO::blend_vline()\n");
} else { } else {
// solid full opcacity // solid full opcacity
uint16 alpha = hAlpha * cover; uint16 alpha = hAlpha * cover;
if (alpha == 255*255) { if (alpha == 255 * 255) {
do { do {
ASSIGN_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_CO(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (alpha) { } else if (alpha) {
do { do {
BLEND_ALPHA_CO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_CO(p, colors->r, colors->g, colors->b, alpha);
colors->r, colors->g, colors->b, alpha);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeAlphaCO::blend_color_vspan()\n");
}
};
typedef DrawingModeAlphaCO<agg::order_rgba32> DrawingModeRGBA32AlphaCO;
typedef DrawingModeAlphaCO<agg::order_argb32> DrawingModeARGB32AlphaCO;
typedef DrawingModeAlphaCO<agg::order_abgr32> DrawingModeABGR32AlphaCO;
typedef DrawingModeAlphaCO<agg::order_bgra32> DrawingModeBGRA32AlphaCO;
#endif // DRAWING_MODE_ALPHA_CO_H #endif // DRAWING_MODE_ALPHA_CO_H
@@ -12,141 +12,120 @@
#include "DrawingMode.h" #include "DrawingMode.h"
// BLEND_ALPHA_PC // BLEND_ALPHA_PC
#define BLEND_ALPHA_PC(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_ALPHA_PC(d, r, g, b, a) \
{ \ { \
BLEND_COMPOSITE16(d1, d2, d3, da, s1, s2, s3, a); \ BLEND_COMPOSITE16(d, r, g, b, a); \
} }
// ASSIGN_ALPHA_PC // ASSIGN_ALPHA_PC
#define ASSIGN_ALPHA_PC(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_ALPHA_PC(d, r, g, b) \
{ \ { \
(d1) = (s1); \ d[0] = (b); \
(d2) = (s2); \ d[1] = (g); \
(d3) = (s3); \ d[2] = (r); \
(da) = 255; \
} }
// blend_pixel_alpha_pc
template<class Order> void
class DrawingModeAlphaPC : public DrawingMode { blend_pixel_alpha_pc(int x, int y, const color_type& c, uint8 cover,
public: agg_buffer* buffer, const PatternHandler* pattern)
// constructor {
DrawingModeAlphaPC() uint8* p = buffer->row(y) + (x << 2);
: DrawingMode() rgb_color color = pattern->R5ColorAt(x, y);
{
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->R5ColorAt(x, y);
uint16 alpha = color.alpha * cover; uint16 alpha = color.alpha * cover;
if (alpha == 255*255) { if (alpha == 255*255) {
ASSIGN_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PC(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PC(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
}
} }
}
// blend_hline // blend_hline_alpha_pc
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_alpha_pc(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
uint16 alpha = color.alpha * cover; uint16 alpha = color.alpha * cover;
if (alpha) { if (alpha) {
if (alpha == 255) { if (alpha == 255) {
ASSIGN_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PC(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PC(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
} }
} }
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
// blend_vline // blend_solid_hspan_alpha_pc
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_alpha_pc(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeAlphaPC::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
uint16 alpha = color.alpha * *covers; uint16 alpha = color.alpha * *covers;
if (alpha) { if (alpha) {
if(alpha == 255*255) { if(alpha == 255 * 255) {
ASSIGN_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PC(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PC(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
} }
} }
covers++; covers++;
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan_alpha_pc
void
// blend_solid_vspan blend_solid_vspan_alpha_pc(int x, int y, unsigned len,
virtual void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const uint8* covers,
const color_type& c, const uint8* covers) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
uint16 alpha = color.alpha * *covers; uint16 alpha = color.alpha * *covers;
if (alpha) { if (alpha) {
if (alpha == 255*255) { if (alpha == 255 * 255) {
ASSIGN_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PC(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PC(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_alpha_pc
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_alpha_pc(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
uint16 alpha = colors->a * *covers; uint16 alpha = colors->a * *covers;
if (alpha) { if (alpha) {
if (alpha == 255*255) { if (alpha == 255 * 255) {
ASSIGN_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha);
colors->r, colors->g, colors->b, alpha);
} }
} }
covers++; covers++;
@@ -156,41 +135,22 @@ printf("DrawingModeAlphaPC::blend_vline()\n");
} else { } else {
// solid full opcacity // solid full opcacity
uint16 alpha = colors->a * cover; uint16 alpha = colors->a * cover;
if (alpha == 255*255) { if (alpha == 255 * 255) {
do { do {
ASSIGN_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (alpha) { } else if (alpha) {
do { do {
BLEND_ALPHA_PC(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha);
colors->r, colors->g, colors->b, alpha);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeAlphaPC::blend_color_vspan()\n");
}
};
typedef DrawingModeAlphaPC<agg::order_rgba32> DrawingModeRGBA32AlphaPC;
typedef DrawingModeAlphaPC<agg::order_argb32> DrawingModeARGB32AlphaPC;
typedef DrawingModeAlphaPC<agg::order_abgr32> DrawingModeABGR32AlphaPC;
typedef DrawingModeAlphaPC<agg::order_bgra32> DrawingModeBGRA32AlphaPC;
#endif // DRAWING_MODE_ALPHA_PC_H #endif // DRAWING_MODE_ALPHA_PC_H
@@ -12,141 +12,122 @@
#include "DrawingMode.h" #include "DrawingMode.h"
// BLEND_ALPHA_PO // BLEND_ALPHA_PO
#define BLEND_ALPHA_PO(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_ALPHA_PO(d, r, g, b, a) \
{ \ { \
BLEND16(d1, d2, d3, da, s1, s2, s3, a); \ BLEND16(d, r, g, b, a); \
} }
// ASSIGN_ALPHA_PO // ASSIGN_ALPHA_PO
#define ASSIGN_ALPHA_PO(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_ALPHA_PO(d, r, g, b) \
{ \ { \
(d1) = (s1); \ d[0] = (b); \
(d2) = (s2); \ d[1] = (g); \
(d3) = (s3); \ d[2] = (r); \
(da) = 255; \
} }
// blend_pixel_alpha_po
template<class Order> void
class DrawingModeAlphaPO : public DrawingMode { blend_pixel_alpha_po(int x, int y, const color_type& c, uint8 cover,
public: agg_buffer* buffer, const PatternHandler* pattern)
// constructor {
DrawingModeAlphaPO() uint8* p = buffer->row(y) + (x << 2);
: DrawingMode() rgb_color color = pattern->R5ColorAt(x, y);
{
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->R5ColorAt(x, y);
uint16 alpha = color.alpha * cover; uint16 alpha = color.alpha * cover;
if (alpha == 255*255) { if (alpha == 255 * 255) {
ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PO(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PO(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
}
} }
}
// blend_hline // blend_hline_alpha_po
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_alpha_po(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
uint16 alpha = color.alpha * cover; uint16 alpha = color.alpha * cover;
if (alpha) { if (alpha) {
if (alpha == 255) { if (alpha == 255) {
ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PO(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PO(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
} }
} }
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
// blend_vline // blend_solid_hspan_alpha_po
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_alpha_po(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeAlphaPO::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
uint16 alpha = color.alpha * *covers; uint16 alpha = color.alpha * *covers;
if (alpha) { if (alpha) {
if(alpha == 255*255) { if(alpha == 255 * 255) {
ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PO(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PO(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
} }
} }
covers++; covers++;
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_alpha_po
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_alpha_po(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
uint16 alpha = color.alpha * *covers; uint16 alpha = color.alpha * *covers;
if (alpha) { if (alpha) {
if (alpha == 255*255) { if (alpha == 255 * 255) {
ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PO(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PO(p, color.red, color.green, color.blue, alpha);
color.red, color.green, color.blue, alpha);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_alpha_po
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_alpha_po(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
uint16 alpha = colors->a * *covers; uint16 alpha = colors->a * *covers;
if (alpha) { if (alpha) {
if (alpha == 255*255) { if (alpha == 255 * 255) {
ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PO(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PO(p, colors->r, colors->g, colors->b, alpha);
colors->r, colors->g, colors->b, alpha);
} }
} }
covers++; covers++;
@@ -156,41 +137,22 @@ printf("DrawingModeAlphaPO::blend_vline()\n");
} else { } else {
// solid full opcacity // solid full opcacity
uint16 alpha = colors->a * cover; uint16 alpha = colors->a * cover;
if (alpha == 255*255) { if (alpha == 255 * 255) {
do { do {
ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ALPHA_PO(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (alpha) { } else if (alpha) {
do { do {
BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ALPHA_PO(p, colors->r, colors->g, colors->b, alpha);
colors->r, colors->g, colors->b, alpha);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeAlphaPO::blend_color_vspan()\n");
}
};
typedef DrawingModeAlphaPO<agg::order_rgba32> DrawingModeRGBA32AlphaPO;
typedef DrawingModeAlphaPO<agg::order_argb32> DrawingModeARGB32AlphaPO;
typedef DrawingModeAlphaPO<agg::order_abgr32> DrawingModeABGR32AlphaPO;
typedef DrawingModeAlphaPO<agg::order_bgra32> DrawingModeBGRA32AlphaPO;
#endif // DRAWING_MODE_ALPHA_PO_H #endif // DRAWING_MODE_ALPHA_PO_H
@@ -9,154 +9,134 @@
#ifndef DRAWING_MODE_BLEND_H #ifndef DRAWING_MODE_BLEND_H
#define DRAWING_MODE_BLEND_H #define DRAWING_MODE_BLEND_H
#include <SupportDefs.h>
#include "DrawingMode.h" #include "DrawingMode.h"
#include "PatternHandler.h"
// BLEND_BLEND // BLEND_BLEND
#define BLEND_BLEND(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_BLEND(d, r, g, b, a) \
{ \ { \
uint8 t1 = ((d1) + (s1)) >> 1; \ pixel32 _p; \
uint8 t2 = ((d2) + (s2)) >> 1; \ _p.data32 = *(uint32*)d; \
uint8 t3 = ((d3) + (s3)) >> 1; \ uint8 bt = (_p.data8[0] + (b)) >> 1; \
BLEND(d1, d2, d3, da, t1, t2, t3, a); \ uint8 gt = (_p.data8[1] + (g)) >> 1; \
uint8 rt = (_p.data8[2] + (r)) >> 1; \
BLEND(d, rt, gt, bt, a); \
} }
// ASSIGN_BLEND // ASSIGN_BLEND
#define ASSIGN_BLEND(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_BLEND(d, r, g, b) \
{ \ { \
(d1) = ((d1) + (s1)) >> 1; \ pixel32 _p; \
(d2) = ((d2) + (s2)) >> 1; \ _p.data32 = *(uint32*)d; \
(d3) = ((d3) + (s3)) >> 1; \ d[0] = (_p.data8[0] + (b)) >> 1; \
(da) = 255; \ d[1] = (_p.data8[1] + (g)) >> 1; \
d[2] = (_p.data8[2] + (r)) >> 1; \
}
// blend_pixel_blend
void
blend_pixel_blend(int x, int y, const color_type& c, uint8 cover,
agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
rgb_color color = pattern->R5ColorAt(x, y);
if (cover == 255) {
ASSIGN_BLEND(p, color.red, color.green, color.blue);
} else {
BLEND_BLEND(p, color.red, color.green, color.blue, cover);
}
}
// blend_hline_blend
void
blend_hline_blend(int x, int y, unsigned len,
const color_type& c, uint8 cover,
agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
if (cover == 255) {
do {
rgb_color color = pattern->R5ColorAt(x, y);
ASSIGN_BLEND(p, color.red, color.green, color.blue);
p += 4;
x++;
} while(--len);
} else {
do {
rgb_color color = pattern->R5ColorAt(x, y);
BLEND_BLEND(p, color.red, color.green, color.blue, cover);
x++;
p += 4;
} while(--len);
}
}
// blend_solid_hspan_blend
void
blend_solid_hspan_blend(int x, int y, unsigned len,
const color_type& c, const uint8* covers,
agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
do {
rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) {
if (*covers == 255) {
ASSIGN_BLEND(p, color.red, color.green, color.blue);
} else {
BLEND_BLEND(p, color.red, color.green, color.blue, *covers);
}
}
covers++;
p += 4;
x++;
} while(--len);
} }
template<class Order>
class DrawingModeBlend : public DrawingMode // blend_solid_vspan_blend
void
blend_solid_vspan_blend(int x, int y, unsigned len,
const color_type& c, const uint8* covers,
agg_buffer* buffer, const PatternHandler* pattern)
{ {
public: uint8* p = buffer->row(y) + (x << 2);
// constructor
DrawingModeBlend()
: DrawingMode()
{
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->R5ColorAt(x, y);
if (cover == 255) {
ASSIGN_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue);
} else {
BLEND_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, cover);
}
}
// blend_hline
virtual void blend_hline(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
if (cover == 255) {
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
ASSIGN_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue);
p += 4;
x++;
} while(--len);
} else {
do {
rgb_color color = fPatternHandler->R5ColorAt(x, y);
BLEND_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, cover);
x++;
p += 4;
} while(--len);
}
}
// blend_vline
virtual void blend_vline(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
printf("DrawingModeBlend::blend_vline()\n");
}
// blend_solid_hspan
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
do {
rgb_color color = fPatternHandler->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_BLEND(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_BLEND(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
covers++; covers++;
p += 4; p += buffer->stride();
x++;
} while(--len);
}
// blend_solid_vspan
virtual void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
do {
rgb_color color = fPatternHandler->R5ColorAt(x, y);
if (*covers) {
if (*covers == 255) {
ASSIGN_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue);
} else {
BLEND_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, *covers);
}
}
covers++;
p += fBuffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_blend
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_blend(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_BLEND(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_BLEND(p, colors->r, colors->g, colors->b, *covers);
colors->r, colors->g, colors->b, *covers);
} }
} }
covers++; covers++;
@@ -167,39 +147,20 @@ printf("DrawingModeBlend::blend_vline()\n");
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_BLEND(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (cover) { } else if (cover) {
do { do {
BLEND_BLEND(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_BLEND(p, colors->r, colors->g, colors->b, cover);
colors->r, colors->g, colors->b, cover);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
//--------------------------------------------------------------------
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeBlend::blend_color_vspan()\n");
}
};
typedef DrawingModeBlend<agg::order_rgba32> DrawingModeRGBA32Blend;
typedef DrawingModeBlend<agg::order_argb32> DrawingModeARGB32Blend;
typedef DrawingModeBlend<agg::order_abgr32> DrawingModeABGR32Blend;
typedef DrawingModeBlend<agg::order_bgra32> DrawingModeBGRA32Blend;
#endif // DRAWING_MODE_BLEND_H #endif // DRAWING_MODE_BLEND_H
@@ -12,74 +12,64 @@
#include "DrawingMode.h" #include "DrawingMode.h"
// BLEND_COPY // BLEND_COPY
#define BLEND_COPY(d1, d2, d3, da, s1, s2, s3, a, l1, l2, l3) \ #define BLEND_COPY(d, r2, g2, b2, a, r1, g1, b1) \
{ \ { \
BLEND_FROM(d1, d2, d3, da, l1, l2, l3, s1, s2, s3, a); \ BLEND_FROM(d, r1, g1, b1, r2, g2, b2, a); \
} }
// ASSIGN_COPY // ASSIGN_COPY
#define ASSIGN_COPY(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_COPY(d, r, g, b) \
{ \ { \
(d1) = (s1); \ d[0] = (b); \
(d2) = (s2); \ d[1] = (g); \
(d3) = (s3); \ d[2] = (r); \
(da) = 255; \
} }
template<class Order> // blend_pixel_copy
class DrawingModeCopy : public DrawingMode { void
public: blend_pixel_copy(int x, int y, const color_type& c, uint8 cover,
typedef Order order_type; agg_buffer* buffer, const PatternHandler* pattern)
{
// constructor uint8* p = buffer->row(y) + (x << 2);
DrawingModeCopy() rgb_color color = pattern->R5ColorAt(x, y);
: DrawingMode()
{
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->R5ColorAt(x, y);
if (cover == 255) { if (cover == 255) {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
rgb_color l = fPatternHandler->LowColor().GetColor32(); rgb_color l = pattern->LowColor().GetColor32();
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, color.red, color.green, color.blue, cover,
color.red, color.green, color.blue, cover,
l.red, l.green, l.blue); l.red, l.green, l.blue);
} }
} }
// blend_hline // blend_hline_copy
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_copy(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
agg_buffer* buffer, const PatternHandler* pattern)
{
if (cover == 255) { if (cover == 255) {
// cache the low and high color as 32bit values // cache the low and high color as 32bit values
// high color // high color
rgb_color color = fPatternHandler->HighColor().GetColor32(); rgb_color color = pattern->HighColor().GetColor32();
uint32 vh; uint32 vh;
uint8* p8 = (uint8*)&vh; uint8* p8 = (uint8*)&vh;
p8[Order::R] = (uint8)color.red; p8[0] = (uint8)color.blue;
p8[Order::G] = (uint8)color.green; p8[1] = (uint8)color.green;
p8[Order::B] = (uint8)color.blue; p8[2] = (uint8)color.red;
p8[Order::A] = 255; p8[3] = 255;
// low color // low color
color = fPatternHandler->LowColor().GetColor32(); color = pattern->LowColor().GetColor32();
uint32 vl; uint32 vl;
p8 = (uint8*)&vl; p8 = (uint8*)&vl;
p8[Order::R] = (uint8)color.red; p8[0] = (uint8)color.blue;
p8[Order::G] = (uint8)color.green; p8[1] = (uint8)color.green;
p8[Order::B] = (uint8)color.blue; p8[2] = (uint8)color.red;
p8[Order::A] = 255; p8[3] = 255;
// row offset as 32bit pointer // row offset as 32bit pointer
uint32* p32 = (uint32*)(fBuffer->row(y)) + x; uint32* p32 = (uint32*)(buffer->row(y)) + x;
do { do {
if (fPatternHandler->IsHighColor(x, y)) if (pattern->IsHighColor(x, y))
*p32 = vh; *p32 = vh;
else else
*p32 = vl; *p32 = vl;
@@ -87,95 +77,85 @@ class DrawingModeCopy : public DrawingMode {
x++; x++;
} while(--len); } while(--len);
} else { } else {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
rgb_color l = fPatternHandler->LowColor().GetColor32(); rgb_color l = pattern->LowColor().GetColor32();
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, color.red, color.green, color.blue, cover,
color.red, color.green, color.blue, cover,
l.red, l.green, l.blue); l.red, l.green, l.blue);
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_copy
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_copy(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeCopy::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan rgb_color l = pattern->LowColor().GetColor32();
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color l = fPatternHandler->LowColor().GetColor32();
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) {
if(*covers == 255) {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue);
} else {
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, *covers,
l.red, l.green, l.blue);
}
}
covers++;
p += 4;
x++;
} while(--len);
}
// blend_solid_vspan
virtual void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color l = fPatternHandler->LowColor().GetColor32();
do {
rgb_color color = fPatternHandler->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, color.red, color.green, color.blue, *covers,
color.red, color.green, color.blue, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += 4;
x++;
} while(--len);
}
// blend_solid_vspan_copy
void
blend_solid_vspan_copy(int x, int y, unsigned len,
const color_type& c, const uint8* covers,
agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
rgb_color l = pattern->LowColor().GetColor32();
do {
rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) {
if (*covers == 255) {
ASSIGN_COPY(p, color.red, color.green, color.blue);
} else {
BLEND_COPY(p, color.red, color.green, color.blue, *covers,
l.red, l.green, l.blue);
}
}
covers++;
p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_copy
virtual void blend_color_hspan(int x, int y, unsigned len, void
const color_type* colors, blend_color_hspan_copy(int x, int y, unsigned len, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
rgb_color l = fPatternHandler->LowColor().GetColor32(); rgb_color l = pattern->LowColor().GetColor32();
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
if(*covers) { if(*covers) {
if(*covers == 255) { if(*covers == 255) {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, colors->r, colors->g, colors->b, *covers,
colors->r, colors->g, colors->b, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
} }
} }
@@ -187,40 +167,21 @@ printf("DrawingModeCopy::blend_vline()\n");
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (cover) { } else if (cover) {
do { do {
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, colors->r, colors->g, colors->b, cover,
colors->r, colors->g, colors->b, cover,
l.red, l.green, l.blue); l.red, l.green, l.blue);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeCopy::blend_color_vspan()\n");
}
};
typedef DrawingModeCopy<agg::order_rgba32> DrawingModeRGBA32Copy;
typedef DrawingModeCopy<agg::order_argb32> DrawingModeARGB32Copy;
typedef DrawingModeCopy<agg::order_abgr32> DrawingModeABGR32Copy;
typedef DrawingModeCopy<agg::order_bgra32> DrawingModeBGRA32Copy;
#endif // DRAWING_MODE_COPY_H #endif // DRAWING_MODE_COPY_H
@@ -11,132 +11,119 @@
#include "DrawingModeCopy.h" #include "DrawingModeCopy.h"
template<class Order> // blend_pixel_copy_solid
class DrawingModeCopySolid : public DrawingMode { void
public: blend_pixel_copy_solid(int x, int y, const color_type& c, uint8 cover,
// constructor agg_buffer* buffer, const PatternHandler* pattern)
DrawingModeCopySolid() {
: DrawingMode() uint8* p = buffer->row(y) + (x << 2);
{
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
if (cover == 255) { if (cover == 255) {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p, c.r, c.g, c.b);
c.r, c.g, c.b);
} else { } else {
rgb_color l = fPatternHandler->LowColor().GetColor32(); rgb_color l = pattern->LowColor().GetColor32();
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, c.r, c.g, c.b, cover,
c.r, c.g, c.b, cover,
l.red, l.green, l.blue); l.red, l.green, l.blue);
} }
} }
// blend_hline // blend_hline_copy_solid
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_copy_solid(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
agg_buffer* buffer, const PatternHandler* pattern)
{
if(cover == 255) { if(cover == 255) {
// cache the color as 32bit value // cache the color as 32bit value
uint32 v; uint32 v;
uint8* p8 = (uint8*)&v; uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)c.r; p8[0] = (uint8)c.b;
p8[Order::G] = (uint8)c.g; p8[1] = (uint8)c.g;
p8[Order::B] = (uint8)c.b; p8[2] = (uint8)c.r;
p8[Order::A] = 255; p8[3] = 255;
// row offset as 32bit pointer // row offset as 32bit pointer
uint32* p32 = (uint32*)(fBuffer->row(y)) + x; uint32* p32 = (uint32*)(buffer->row(y)) + x;
do { do {
*p32 = v; *p32 = v;
p32++; p32++;
} while(--len); } while(--len);
} else { } else {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
rgb_color l = fPatternHandler->LowColor().GetColor32(); rgb_color l = pattern->LowColor().GetColor32();
do { do {
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, c.r, c.g, c.b, cover,
c.r, c.g, c.b, cover,
l.red, l.green, l.blue); l.red, l.green, l.blue);
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_copy_solid
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_copy_solid(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeCopySolid::blend_vline()\n"); agg_buffer* buffer,
} const PatternHandler* pattern)
{
// blend_solid_hspan uint8* p = buffer->row(y) + (x << 2);
virtual void blend_solid_hspan(int x, int y, unsigned len, rgb_color l = pattern->LowColor().GetColor32();
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color l = fPatternHandler->LowColor().GetColor32();
do { do {
if (*covers) { if (*covers) {
if(*covers == 255) { if(*covers == 255) {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p, c.r, c.g, c.b);
c.r, c.g, c.b);
} else { } else {
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, c.r, c.g, c.b, *covers,
c.r, c.g, c.b, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
} }
} }
covers++; covers++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_copy_solid
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_copy_solid(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer,
rgb_color l = fPatternHandler->LowColor().GetColor32(); const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
rgb_color l = pattern->LowColor().GetColor32();
do { do {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p, c.r, c.g, c.b);
c.r, c.g, c.b);
} else { } else {
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, c.r, c.g, c.b, *covers,
c.r, c.g, c.b, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_copy_solid
virtual void blend_color_hspan(int x, int y, unsigned len, void
const color_type* colors, blend_color_hspan_copy_solid(int x, int y, unsigned len,
const uint8* covers, const color_type* colors, const uint8* covers,
uint8 cover) uint8 cover,
{ agg_buffer* buffer,
uint8* p = fBuffer->row(y) + (x << 2); const PatternHandler* pattern)
rgb_color l = fPatternHandler->LowColor().GetColor32(); {
uint8* p = buffer->row(y) + (x << 2);
rgb_color l = pattern->LowColor().GetColor32();
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
if(*covers) { if(*covers) {
if(*covers == 255) { if(*covers == 255) {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, colors->r, colors->g, colors->b, *covers,
colors->r, colors->g, colors->b, *covers,
l.red, l.green, l.blue); l.red, l.green, l.blue);
} }
} }
@@ -148,40 +135,21 @@ printf("DrawingModeCopySolid::blend_vline()\n");
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (cover) { } else if (cover) {
do { do {
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p, colors->r, colors->g, colors->b, cover,
colors->r, colors->g, colors->b, cover,
l.red, l.green, l.blue); l.red, l.green, l.blue);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeCopySolid::blend_color_vspan()\n");
}
};
typedef DrawingModeCopySolid<agg::order_rgba32> DrawingModeRGBA32CopySolid;
typedef DrawingModeCopySolid<agg::order_argb32> DrawingModeARGB32CopySolid;
typedef DrawingModeCopySolid<agg::order_abgr32> DrawingModeABGR32CopySolid;
typedef DrawingModeCopySolid<agg::order_bgra32> DrawingModeBGRA32CopySolid;
#endif // DRAWING_MODE_COPY_SOLID_H #endif // DRAWING_MODE_COPY_SOLID_H
@@ -12,101 +12,84 @@
#include "DrawingMode.h" #include "DrawingMode.h"
// BLEND_ERASE // BLEND_ERASE
#define BLEND_ERASE(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_ERASE(d, r, g, b, a) \
{ \ { \
BLEND(d1, d2, d3, da, s1, s2, s3, a); \ BLEND(d, r, g, b, a); \
} }
// ASSIGN_ERASE // ASSIGN_ERASE
#define ASSIGN_ERASE(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_ERASE(d, r, g, b) \
{ \ { \
(d1) = (s1); \ d[0] = (b); \
(d2) = (s2); \ d[1] = (g); \
(d3) = (s3); \ d[2] = (r); \
(da) = 255; \
} }
// blend_pixel_erase
template<class Order> void
class DrawingModeErase : public DrawingMode { blend_pixel_erase(int x, int y, const color_type& c, uint8 cover,
public: agg_buffer* buffer, const PatternHandler* pattern)
// constructor {
DrawingModeErase() if (pattern->IsHighColor(x, y)) {
: DrawingMode() uint8* p = buffer->row(y) + (x << 2);
{ rgb_color color = pattern->LowColor().GetColor32();
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
if (fPatternHandler->IsHighColor(x, y)) {
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->LowColor().GetColor32();
if (cover == 255) { if (cover == 255) {
ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ERASE(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ERASE(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
}
} }
} }
}
// blend_hline // blend_hline_erase
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_erase(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
agg_buffer* buffer, const PatternHandler* pattern)
{
if (cover == 255) { if (cover == 255) {
rgb_color color = fPatternHandler->LowColor().GetColor32(); rgb_color color = pattern->LowColor().GetColor32();
uint32 v; uint32 v;
uint8* p8 = (uint8*)&v; uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)color.red; p8[0] = (uint8)color.blue;
p8[Order::G] = (uint8)color.green; p8[1] = (uint8)color.green;
p8[Order::B] = (uint8)color.blue; p8[2] = (uint8)color.red;
p8[Order::A] = 255; p8[3] = 255;
uint32* p32 = (uint32*)(fBuffer->row(y)) + x; uint32* p32 = (uint32*)(buffer->row(y)) + x;
do { do {
if (fPatternHandler->IsHighColor(x, y)) if (pattern->IsHighColor(x, y))
*p32 = v; *p32 = v;
p32++; p32++;
x++; x++;
} while(--len); } while(--len);
} else { } else {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->LowColor().GetColor32(); rgb_color color = pattern->LowColor().GetColor32();
do { do {
if (fPatternHandler->IsHighColor(x, y)) { if (pattern->IsHighColor(x, y)) {
BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ERASE(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
} }
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_erase
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_erase(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeErase::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan rgb_color color = pattern->LowColor().GetColor32();
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->LowColor().GetColor32();
do { do {
if (fPatternHandler->IsHighColor(x, y)) { if (pattern->IsHighColor(x, y)) {
if (*covers) { if (*covers) {
if(*covers == 255) { if(*covers == 255) {
ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ERASE(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ERASE(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
} }
@@ -114,53 +97,52 @@ printf("DrawingModeErase::blend_vline()\n");
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_erase
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_erase(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
rgb_color color = fPatternHandler->LowColor().GetColor32(); {
uint8* p = buffer->row(y) + (x << 2);
rgb_color color = pattern->LowColor().GetColor32();
do { do {
if (fPatternHandler->IsHighColor(x, y)) { if (pattern->IsHighColor(x, y)) {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ERASE(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ERASE(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_erase
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_erase(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
// TODO: compare this with BView // TODO: compare this with BView
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
if(*covers) { if(*covers) {
if(*covers == 255) { if(*covers == 255) {
ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ERASE(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ERASE(p, colors->r, colors->g, colors->b, *covers);
colors->r, colors->g, colors->b, *covers);
} }
} }
covers++; covers++;
@@ -171,39 +153,20 @@ printf("DrawingModeErase::blend_vline()\n");
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_ERASE(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (cover) { } else if (cover) {
do { do {
BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_ERASE(p, colors->r, colors->g, colors->b, cover);
colors->r, colors->g, colors->b, cover);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeErase::blend_color_vspan()\n");
}
};
typedef DrawingModeErase<agg::order_rgba32> DrawingModeRGBA32Erase;
typedef DrawingModeErase<agg::order_argb32> DrawingModeARGB32Erase;
typedef DrawingModeErase<agg::order_abgr32> DrawingModeABGR32Erase;
typedef DrawingModeErase<agg::order_bgra32> DrawingModeBGRA32Erase;
#endif // DRAWING_MODE_ERASE_H #endif // DRAWING_MODE_ERASE_H
@@ -1,153 +0,0 @@
/*
* Copyright 2005, Stephan Aßmus <[email protected]>. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Manages retrieving/instantiating of the correct DrawingMode class for
* a given drawing_mode constant.
*
*/
#include <stdio.h>
#include "DrawingModeAdd.h"
#include "DrawingModeAlphaCC.h"
#include "DrawingModeAlphaCO.h"
#include "DrawingModeAlphaPC.h"
#include "DrawingModeAlphaPO.h"
#include "DrawingModeBlend.h"
#include "DrawingModeCopy.h"
#include "DrawingModeCopySolid.h"
#include "DrawingModeErase.h"
#include "DrawingModeInvert.h"
#include "DrawingModeMax.h"
#include "DrawingModeMin.h"
#include "DrawingModeOver.h"
#include "DrawingModeOverSolid.h"
#include "DrawingModeSelect.h"
#include "DrawingModeSubtract.h"
#include "DrawingModeFactory.h"
// constructor
DrawingModeFactory::DrawingModeFactory()
: fDrawingModeBGRA32Over(new DrawingModeBGRA32Over()),
fDrawingModeBGRA32OverSolid(new DrawingModeBGRA32OverSolid()),
fDrawingModeBGRA32Erase(new DrawingModeBGRA32Erase()),
fDrawingModeBGRA32Invert(new DrawingModeBGRA32Invert()),
fDrawingModeBGRA32Select(new DrawingModeBGRA32Select()),
fDrawingModeBGRA32CopySolid(new DrawingModeBGRA32CopySolid()),
fDrawingModeBGRA32Copy(new DrawingModeBGRA32Copy()),
fDrawingModeBGRA32Add(new DrawingModeBGRA32Add()),
fDrawingModeBGRA32Subtract(new DrawingModeBGRA32Subtract()),
fDrawingModeBGRA32Blend(new DrawingModeBGRA32Blend()),
fDrawingModeBGRA32Min(new DrawingModeBGRA32Min()),
fDrawingModeBGRA32Max(new DrawingModeBGRA32Max()),
fDrawingModeBGRA32AlphaCO(new DrawingModeBGRA32AlphaCO()),
fDrawingModeBGRA32AlphaCC(new DrawingModeBGRA32AlphaCC()),
fDrawingModeBGRA32AlphaPO(new DrawingModeBGRA32AlphaPO()),
fDrawingModeBGRA32AlphaPC(new DrawingModeBGRA32AlphaPC())
{
}
// destructor
DrawingModeFactory::~DrawingModeFactory()
{
delete fDrawingModeBGRA32Over;
delete fDrawingModeBGRA32OverSolid;
delete fDrawingModeBGRA32Erase;
delete fDrawingModeBGRA32Invert;
delete fDrawingModeBGRA32Select;
delete fDrawingModeBGRA32CopySolid;
delete fDrawingModeBGRA32Copy;
delete fDrawingModeBGRA32Add;
delete fDrawingModeBGRA32Subtract;
delete fDrawingModeBGRA32Blend;
delete fDrawingModeBGRA32Min;
delete fDrawingModeBGRA32Max;
delete fDrawingModeBGRA32AlphaCO;
delete fDrawingModeBGRA32AlphaCC;
delete fDrawingModeBGRA32AlphaPO;
delete fDrawingModeBGRA32AlphaPC;
}
// DrawingModeFor
DrawingMode*
DrawingModeFactory::DrawingModeFor(drawing_mode mode,
source_alpha alphaSrcMode,
alpha_function alphaFncMode,
bool solid)
{
switch (mode) {
// these drawing modes discard source pixels
// which have the current low color
case B_OP_OVER:
if (solid)
return fDrawingModeBGRA32OverSolid;
else
return fDrawingModeBGRA32Over;
break;
case B_OP_ERASE:
return fDrawingModeBGRA32Erase;
break;
case B_OP_INVERT:
return fDrawingModeBGRA32Invert;
break;
case B_OP_SELECT:
return fDrawingModeBGRA32Select;
break;
// in these drawing modes, the current high
// and low color are treated equally
case B_OP_COPY:
if (solid)
return fDrawingModeBGRA32CopySolid;
else
return fDrawingModeBGRA32Copy;
break;
case B_OP_ADD:
return fDrawingModeBGRA32Add;
break;
case B_OP_SUBTRACT:
return fDrawingModeBGRA32Subtract;
break;
case B_OP_BLEND:
return fDrawingModeBGRA32Blend;
break;
case B_OP_MIN:
return fDrawingModeBGRA32Min;
break;
case B_OP_MAX:
return fDrawingModeBGRA32Max;
break;
// this drawing mode is the only one considering
// alpha at all. In B_CONSTANT_ALPHA, the alpha
// value from the current high color is used for
// all computations. In B_PIXEL_ALPHA, the alpha
// is considered at every source pixel.
// To simplify the implementation, four separate
// DrawingMode classes are used to cover the
// four possible combinations of alpha enabled drawing.
case B_OP_ALPHA:
if (alphaSrcMode == B_CONSTANT_ALPHA) {
if (alphaFncMode == B_ALPHA_OVERLAY) {
return fDrawingModeBGRA32AlphaCO;
} else if (alphaFncMode == B_ALPHA_COMPOSITE) {
return fDrawingModeBGRA32AlphaCC;
}
} else if (alphaSrcMode == B_PIXEL_ALPHA){
if (alphaFncMode == B_ALPHA_OVERLAY) {
return fDrawingModeBGRA32AlphaPO;
} else if (alphaFncMode == B_ALPHA_COMPOSITE) {
return fDrawingModeBGRA32AlphaPC;
}
}
break;
default:
fprintf(stderr, "DrawingModeFactory::DrawingModeFor() - drawing_mode not implemented\n");
return fDrawingModeBGRA32Copy;
}
return NULL;
}
@@ -1,46 +0,0 @@
/*
* Copyright 2005, Stephan Aßmus <[email protected]>. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Manages retrieving/instantiating of the correct DrawingMode class for
* a given drawing_mode constant.
*
*/
#ifndef DRAWING_MODE_FACTORY_H
#define DRAWING_MODE_FACTORY_H
#include <GraphicsDefs.h>
#include "DrawingMode.h"
class DrawingModeFactory {
public:
DrawingModeFactory();
virtual ~DrawingModeFactory();
DrawingMode* DrawingModeFor(drawing_mode mode,
source_alpha alphaSrcMode,
alpha_function alphaFncMode,
bool solid = false);
private:
DrawingMode* fDrawingModeBGRA32Over;
DrawingMode* fDrawingModeBGRA32OverSolid;
DrawingMode* fDrawingModeBGRA32Erase;
DrawingMode* fDrawingModeBGRA32Invert;
DrawingMode* fDrawingModeBGRA32Select;
DrawingMode* fDrawingModeBGRA32CopySolid;
DrawingMode* fDrawingModeBGRA32Copy;
DrawingMode* fDrawingModeBGRA32Add;
DrawingMode* fDrawingModeBGRA32Subtract;
DrawingMode* fDrawingModeBGRA32Blend;
DrawingMode* fDrawingModeBGRA32Min;
DrawingMode* fDrawingModeBGRA32Max;
DrawingMode* fDrawingModeBGRA32AlphaCO;
DrawingMode* fDrawingModeBGRA32AlphaCC;
DrawingMode* fDrawingModeBGRA32AlphaPO;
DrawingMode* fDrawingModeBGRA32AlphaPC;
};
#endif // DRAWING_MODE_FACTORY_H
@@ -12,136 +12,131 @@
#include "DrawingMode.h" #include "DrawingMode.h"
// BLEND_INVERT // BLEND_INVERT
#define BLEND_INVERT(d1, d2, d3, da, a) \ #define BLEND_INVERT(d, a) \
{ \ { \
BLEND(d1, d2, d3, da, 255 - d1, 255 - d2, 255 - d3, a); \ pixel32 _p; \
_p.data32 = *(uint32*)d; \
BLEND(d, 255 - _p.data8[2], 255 - _p.data8[1], 255 - _p.data8[0], a); \
} }
// ASSIGN_INVERT // ASSIGN_INVERT
#define ASSIGN_INVERT(d1, d2, d3, da) \ #define ASSIGN_INVERT(d) \
{ \ { \
(d1) = 255 - (d1); \ pixel32 _p; \
(d2) = 255 - (d2); \ _p.data32 = *(uint32*)d; \
(d3) = 255 - (d3); \ d[0] = 255 - _p.data8[0]; \
(da) = 255; \ d[1] = 255 - _p.data8[1]; \
d[2] = 255 - _p.data8[2]; \
}
// blend_pixel_invert
void
blend_pixel_invert(int x, int y, const color_type& c, uint8 cover,
agg_buffer* buffer, const PatternHandler* pattern)
{
if (pattern->IsHighColor(x, y)) {
uint8* p = buffer->row(y) + (x << 2);
if (cover == 255) {
ASSIGN_INVERT(p);
} else {
BLEND_INVERT(p, cover);
}
}
}
// blend_hline_invert
void
blend_hline_invert(int x, int y, unsigned len,
const color_type& c, uint8 cover,
agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
if(cover == 255) {
do {
if (pattern->IsHighColor(x, y)) {
ASSIGN_INVERT(p);
}
x++;
p += 4;
} while(--len);
} else {
do {
if (pattern->IsHighColor(x, y)) {
BLEND_INVERT(p, cover);
}
x++;
p += 4;
} while(--len);
}
}
// blend_solid_hspan_invert
void
blend_solid_hspan_invert(int x, int y, unsigned len,
const color_type& c, const uint8* covers,
agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
do {
if (pattern->IsHighColor(x, y)) {
if (*covers) {
if (*covers == 255) {
ASSIGN_INVERT(p);
} else {
BLEND_INVERT(p, *covers);
}
}
}
covers++;
p += 4;
x++;
} while(--len);
} }
template<class Order>
class DrawingModeInvert : public DrawingMode {
public:
// constructor
DrawingModeInvert()
: DrawingMode()
{
}
// blend_pixel // blend_solid_vspan_invert
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover) void
{ blend_solid_vspan_invert(int x, int y, unsigned len,
if (fPatternHandler->IsHighColor(x, y)) { const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
if (cover == 255) { {
ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]); uint8* p = buffer->row(y) + (x << 2);
} else {
BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], cover);
}
}
}
// blend_hline
virtual void blend_hline(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
if(cover == 255) {
do { do {
if (fPatternHandler->IsHighColor(x, y)) { if (pattern->IsHighColor(x, y)) {
ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
}
x++;
p += 4;
} while(--len);
} else {
do {
if (fPatternHandler->IsHighColor(x, y)) {
BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], cover);
}
x++;
p += 4;
} while(--len);
}
}
// blend_vline
virtual void blend_vline(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
printf("DrawingModeInvert::blend_vline()\n");
}
// blend_solid_hspan
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
do {
if (fPatternHandler->IsHighColor(x, y)) {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]); ASSIGN_INVERT(p);
} else { } else {
BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], *covers); BLEND_INVERT(p, *covers);
} }
} }
} }
covers++; covers++;
p += 4; p += buffer->stride();
x++;
} while(--len);
}
// blend_solid_vspan
virtual void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
do {
if (fPatternHandler->IsHighColor(x, y)) {
if (*covers) {
if (*covers == 255) {
ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
} else {
BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], *covers);
}
}
}
covers++;
p += fBuffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_invert
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_invert(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
// TODO: does the R5 app_server check for the // TODO: does the R5 app_server check for the
// appearance of the high color in the source bitmap? // appearance of the high color in the source bitmap?
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]); ASSIGN_INVERT(p);
} else { } else {
BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], *covers); BLEND_INVERT(p, *covers);
} }
} }
covers++; covers++;
@@ -152,37 +147,20 @@ printf("DrawingModeInvert::blend_vline()\n");
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]); ASSIGN_INVERT(p);
p += 4; p += 4;
// ++colors; // ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (cover) { } else if (cover) {
do { do {
BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], cover); BLEND_INVERT(p, cover);
p += 4; p += 4;
// ++colors; // ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeInvert::blend_color_vspan()\n");
}
};
typedef DrawingModeInvert<agg::order_rgba32> DrawingModeRGBA32Invert;
typedef DrawingModeInvert<agg::order_argb32> DrawingModeARGB32Invert;
typedef DrawingModeInvert<agg::order_abgr32> DrawingModeABGR32Invert;
typedef DrawingModeInvert<agg::order_bgra32> DrawingModeBGRA32Invert;
#endif // DRAWING_MODE_INVERT_H #endif // DRAWING_MODE_INVERT_H
@@ -9,152 +9,136 @@
#ifndef DRAWING_MODE_MAX_H #ifndef DRAWING_MODE_MAX_H
#define DRAWING_MODE_MAX_H #define DRAWING_MODE_MAX_H
#include <SupportDefs.h>
#include "DrawingMode.h" #include "DrawingMode.h"
#include "PatternHandler.h"
// BLEND_MAX // BLEND_MAX
#define BLEND_MAX(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_MAX(d, r, g, b, a) \
{ \ { \
uint8 t1 = max_c((d1), (s1)); \ pixel32 _p; \
uint8 t2 = max_c((d2), (s2)); \ _p.data32 = *(uint32*)d; \
uint8 t3 = max_c((d3), (s3)); \ uint8 rt = max_c(_p.data8[2], (r)); \
BLEND(d1, d2, d3, da, t1, t2, t3, a); \ uint8 gt = max_c(_p.data8[1], (g)); \
uint8 bt = max_c(_p.data8[0], (b)); \
BLEND(d, rt, gt, bt, a); \
} }
// ASSIGN_MAX // ASSIGN_MAX
#define ASSIGN_MAX(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_MAX(d, r, g, b) \
{ \ { \
(d1) = max_c((d1), (s1)); \ pixel32 _p; \
(d2) = max_c((d2), (s2)); \ _p.data32 = *(uint32*)d; \
(d3) = max_c((d3), (s3)); \ d[0] = max_c(_p.data8[0], (b)); \
(da) = 255; \ d[1] = max_c(_p.data8[1], (g)); \
d[2] = max_c(_p.data8[2], (r)); \
} }
template<class Order> // blend_pixel_max
class DrawingModeMax : public DrawingMode { void
public: blend_pixel_max(int x, int y, const color_type& c, uint8 cover,
// constructor agg_buffer* buffer, const PatternHandler* pattern)
DrawingModeMax() {
: DrawingMode() uint8* p = buffer->row(y) + (x << 2);
{ rgb_color color = pattern->R5ColorAt(x, y);
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->R5ColorAt(x, y);
if (cover == 255) { if (cover == 255) {
ASSIGN_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MAX(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MAX(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
}
} }
}
// blend_hline // blend_hline_max
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_max(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
if (cover == 255) { if (cover == 255) {
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
ASSIGN_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MAX(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} else { } else {
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
BLEND_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MAX(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_max
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_max(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeMax::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
//--------------------------------------------------------------------
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MAX(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MAX(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
covers++; covers++;
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_max
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_max(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MAX(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MAX(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_max
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_max(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MAX(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MAX(p, colors->r, colors->g, colors->b, *covers);
colors->r, colors->g, colors->b, *covers);
} }
} }
covers++; covers++;
@@ -165,39 +149,20 @@ printf("DrawingModeMax::blend_vline()\n");
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MAX(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (cover) { } else if (cover) {
do { do {
BLEND_MAX(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MAX(p, colors->r, colors->g, colors->b, cover);
colors->r, colors->g, colors->b, cover);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
//--------------------------------------------------------------------
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeMax::blend_color_vspan()\n");
}
};
typedef DrawingModeMax<agg::order_rgba32> DrawingModeRGBA32Max;
typedef DrawingModeMax<agg::order_argb32> DrawingModeARGB32Max;
typedef DrawingModeMax<agg::order_abgr32> DrawingModeABGR32Max;
typedef DrawingModeMax<agg::order_bgra32> DrawingModeBGRA32Max;
#endif // DRAWING_MODE_MAX_H #endif // DRAWING_MODE_MAX_H
@@ -3,153 +3,136 @@
#ifndef DRAWING_MODE_MIN_H #ifndef DRAWING_MODE_MIN_H
#define DRAWING_MODE_MIN_H #define DRAWING_MODE_MIN_H
#include <SupportDefs.h>
#include "DrawingMode.h" #include "DrawingMode.h"
#include "PatternHandler.h"
// BLEND_MIN // BLEND_MIN
#define BLEND_MIN(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_MIN(d, r, g, b, a) \
{ \ { \
uint8 t1 = min_c((d1), (s1)); \ pixel32 _p; \
uint8 t2 = min_c((d2), (s2)); \ _p.data32 = *(uint32*)d; \
uint8 t3 = min_c((d3), (s3)); \ uint8 rt = min_c(_p.data8[2], (r)); \
BLEND(d1, d2, d3, da, t1, t2, t3, a); \ uint8 gt = min_c(_p.data8[1], (g)); \
uint8 bt = min_c(_p.data8[0], (b)); \
BLEND(d, rt, gt, bt, a); \
} }
// ASSIGN_MIN // ASSIGN_MIN
#define ASSIGN_MIN(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_MIN(d, r, g, b) \
{ \ { \
(d1) = min_c((d1), (s1)); \ pixel32 _p; \
(d2) = min_c((d2), (s2)); \ _p.data32 = *(uint32*)d; \
(d3) = min_c((d3), (s3)); \ d[0] = min_c(_p.data8[0], (b)); \
(da) = 255; \ d[1] = min_c(_p.data8[1], (g)); \
d[2] = min_c(_p.data8[2], (r)); \
} }
template<class Order> // blend_pixel_min
class DrawingModeMin : public DrawingMode { void
public: blend_pixel_min(int x, int y, const color_type& c, uint8 cover,
// constructor agg_buffer* buffer, const PatternHandler* pattern)
DrawingModeMin() {
: DrawingMode() uint8* p = buffer->row(y) + (x << 2);
{ rgb_color color = pattern->R5ColorAt(x, y);
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->R5ColorAt(x, y);
if (cover == 255) { if (cover == 255) {
ASSIGN_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MIN(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MIN(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
}
} }
}
// blend_hline // blend_hline_min
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_min(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
if (cover == 255) { if (cover == 255) {
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
ASSIGN_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MIN(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} else { } else {
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
BLEND_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MIN(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_min
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_min(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeMin::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MIN(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MIN(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
covers++; covers++;
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_min
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_min(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MIN(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MIN(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_min
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_min(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MIN(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MIN(p, colors->r, colors->g, colors->b, *covers);
colors->r, colors->g, colors->b, *covers);
} }
} }
covers++; covers++;
@@ -160,39 +143,20 @@ printf("DrawingModeMin::blend_vline()\n");
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_MIN(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (cover) { } else if (cover) {
do { do {
BLEND_MIN(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_MIN(p, colors->r, colors->g, colors->b, cover);
colors->r, colors->g, colors->b, cover);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
//--------------------------------------------------------------------
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeMin::blend_color_vspan()\n");
}
};
typedef DrawingModeMin<agg::order_rgba32> DrawingModeRGBA32Min;
typedef DrawingModeMin<agg::order_argb32> DrawingModeARGB32Min;
typedef DrawingModeMin<agg::order_abgr32> DrawingModeABGR32Min;
typedef DrawingModeMin<agg::order_bgra32> DrawingModeBGRA32Min;
#endif // DRAWING_MODE_MIN_H #endif // DRAWING_MODE_MIN_H
@@ -12,101 +12,82 @@
#include "DrawingMode.h" #include "DrawingMode.h"
// BLEND_OVER // BLEND_OVER
#define BLEND_OVER(d, s1, s2, s3, a) \ #define BLEND_OVER(d, r, g, b, a) \
{ \ { \
pixel32 _p; \ BLEND(d, r, g, b, a) \
_p.data32 = *(uint32*)d; \
d[0] = (((((s3) - _p.data8[0]) * (a)) + (_p.data8[0] << 8)) >> 8); \
d[1] = (((((s2) - _p.data8[1]) * (a)) + (_p.data8[1] << 8)) >> 8); \
d[2] = (((((s1) - _p.data8[2]) * (a)) + (_p.data8[2] << 8)) >> 8); \
d[3] = 255; \
} }
// ASSIGN_OVER // ASSIGN_OVER
#define ASSIGN_OVER(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_OVER(d, r, g, b) \
{ \ { \
(d1) = (s1); \ d[0] = (b); \
(d2) = (s2); \ d[1] = (g); \
(d3) = (s3); \ d[2] = (r); \
(da) = 255; \
} }
// blend_pixel_over
template<class Order> void
class DrawingModeOver : public DrawingMode { blend_pixel_over(int x, int y, const color_type& c, uint8 cover,
public: agg_buffer* buffer, const PatternHandler* pattern)
// constructor {
DrawingModeOver() if (pattern->IsHighColor(x, y)) {
: DrawingMode() uint8* p = buffer->row(y) + (x << 2);
{ rgb_color color = pattern->HighColor().GetColor32();
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
if (fPatternHandler->IsHighColor(x, y)) {
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->HighColor().GetColor32();
if (cover == 255) { if (cover == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_OVER(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_OVER(p, color.red, color.green, color.blue, cover); BLEND_OVER(p, color.red, color.green, color.blue, cover);
} }
} }
} }
// blend_hline // blend_hline_over
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_over(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
if(cover == 255) { agg_buffer* buffer, const PatternHandler* pattern)
rgb_color color = fPatternHandler->HighColor().GetColor32(); {
if (cover == 255) {
rgb_color color = pattern->HighColor().GetColor32();
uint32 v; uint32 v;
uint8* p8 = (uint8*)&v; uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)color.red; p8[0] = (uint8)color.blue;
p8[Order::G] = (uint8)color.green; p8[1] = (uint8)color.green;
p8[Order::B] = (uint8)color.blue; p8[2] = (uint8)color.red;
p8[Order::A] = 255; p8[3] = 255;
uint32* p32 = (uint32*)(fBuffer->row(y)) + x; uint32* p32 = (uint32*)(buffer->row(y)) + x;
do { do {
if (fPatternHandler->IsHighColor(x, y)) if (pattern->IsHighColor(x, y))
*p32 = v; *p32 = v;
p32++; p32++;
x++; x++;
} while(--len); } while(--len);
} else { } else {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->HighColor().GetColor32(); rgb_color color = pattern->HighColor().GetColor32();
do { do {
if (fPatternHandler->IsHighColor(x, y)) { if (pattern->IsHighColor(x, y)) {
BLEND_OVER(p, color.red, color.green, color.blue, cover); BLEND_OVER(p, color.red, color.green, color.blue, cover);
} }
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_over
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_over(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeOver::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan rgb_color color = pattern->HighColor().GetColor32();
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->HighColor().GetColor32();
do { do {
if (fPatternHandler->IsHighColor(x, y)) { if (pattern->IsHighColor(x, y)) {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_OVER(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_OVER(p, color.red, color.green, color.blue, *covers); BLEND_OVER(p, color.red, color.green, color.blue, *covers);
} }
@@ -116,49 +97,50 @@ printf("DrawingModeOver::blend_vline()\n");
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_over
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_over(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
rgb_color color = fPatternHandler->HighColor().GetColor32(); {
uint8* p = buffer->row(y) + (x << 2);
rgb_color color = pattern->HighColor().GetColor32();
do { do {
if (fPatternHandler->IsHighColor(x, y)) { if (pattern->IsHighColor(x, y)) {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_OVER(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_OVER(p, color.red, color.green, color.blue, *covers); BLEND_OVER(p, color.red, color.green, color.blue, *covers);
} }
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_over
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_over(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
// if (*covers) { // if (*covers) {
if (*covers && (colors->a & 0xff)) { if (*covers && (colors->a & 0xff)) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_OVER(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_OVER(p, colors->r, colors->g, colors->b, *covers); BLEND_OVER(p, colors->r, colors->g, colors->b, *covers);
} }
@@ -172,8 +154,7 @@ if (*covers && (colors->a & 0xff)) {
if (cover == 255) { if (cover == 255) {
do { do {
if (colors->a & 0xff) { if (colors->a & 0xff) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_OVER(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} }
p += 4; p += 4;
++colors; ++colors;
@@ -187,24 +168,7 @@ if (colors->a & 0xff) {
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeOver::blend_color_vspan()\n");
}
};
typedef DrawingModeOver<agg::order_rgba32> DrawingModeRGBA32Over;
typedef DrawingModeOver<agg::order_argb32> DrawingModeARGB32Over;
typedef DrawingModeOver<agg::order_abgr32> DrawingModeABGR32Over;
typedef DrawingModeOver<agg::order_bgra32> DrawingModeBGRA32Over;
#endif // DRAWING_MODE_OVER_H #endif // DRAWING_MODE_OVER_H
@@ -11,80 +11,68 @@
#include "DrawingModeOver.h" #include "DrawingModeOver.h"
template<class Order> // blend_pixel_over_solid
class DrawingModeOverSolid : public DrawingMode { void
public: blend_pixel_over_solid(int x, int y, const color_type& c, uint8 cover,
// constructor agg_buffer* buffer, const PatternHandler* pattern)
DrawingModeOverSolid() {
: DrawingMode() if (pattern->IsSolidLow())
{
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
if (fPatternHandler->IsSolidLow())
return; return;
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (cover == 255) { if (cover == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_OVER(p, c.r, c.g, c.b);
c.r, c.g, c.b);
} else { } else {
BLEND_OVER(p, c.r, c.g, c.b, cover); BLEND_OVER(p, c.r, c.g, c.b, cover);
} }
} }
// blend_hline // blend_hline_over_solid
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_over_solid(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
if (fPatternHandler->IsSolidLow()) agg_buffer* buffer, const PatternHandler* pattern)
{
if (pattern->IsSolidLow())
return; return;
if(cover == 255) { if(cover == 255) {
uint32 v; uint32 v;
uint8* p8 = (uint8*)&v; uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)c.r; p8[0] = (uint8)c.b;
p8[Order::G] = (uint8)c.g; p8[1] = (uint8)c.g;
p8[Order::B] = (uint8)c.b; p8[2] = (uint8)c.r;
p8[Order::A] = 255; p8[3] = 255;
uint32* p32 = (uint32*)(fBuffer->row(y)) + x; uint32* p32 = (uint32*)(buffer->row(y)) + x;
do { do {
*p32 = v; *p32 = v;
p32++; p32++;
x++; x++;
} while(--len); } while(--len);
} else { } else {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
do { do {
BLEND_OVER(p, c.r, c.g, c.b, cover); BLEND_OVER(p, c.r, c.g, c.b, cover);
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_over_solid
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_over_solid(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeOver::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
if (pattern->IsSolidLow())
// blend_solid_hspan
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
if (fPatternHandler->IsSolidLow())
return; return;
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
do { do {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_OVER(p, c.r, c.g, c.b);
c.r, c.g, c.b);
} else { } else {
BLEND_OVER(p, c.r, c.g, c.b, *covers); BLEND_OVER(p, c.r, c.g, c.b, *covers);
} }
@@ -93,49 +81,50 @@ printf("DrawingModeOver::blend_vline()\n");
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_over_solid
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_over_solid(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
if (fPatternHandler->IsSolidLow()) agg_buffer* buffer, const PatternHandler* pattern)
{
if (pattern->IsSolidLow())
return; return;
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
do { do {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_OVER(p, c.r, c.g, c.b);
c.r, c.g, c.b);
} else { } else {
BLEND_OVER(p, c.r, c.g, c.b, *covers); BLEND_OVER(p, c.r, c.g, c.b, *covers);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_over_solid
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_over_solid(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
// if (*covers) { // if (*covers) {
if (*covers && (colors->a & 0xff)) { if (*covers && (colors->a & 0xff)) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_OVER(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_OVER(p, colors->r, colors->g, colors->b, *covers); BLEND_OVER(p, colors->r, colors->g, colors->b, *covers);
} }
@@ -149,8 +138,7 @@ if (*covers && (colors->a & 0xff)) {
if (cover == 255) { if (cover == 255) {
do { do {
if (colors->a & 0xff) { if (colors->a & 0xff) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_OVER(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} }
p += 4; p += 4;
++colors; ++colors;
@@ -164,24 +152,7 @@ if (colors->a & 0xff) {
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeOver::blend_color_vspan()\n");
}
};
typedef DrawingModeOverSolid<agg::order_rgba32> DrawingModeRGBA32OverSolid;
typedef DrawingModeOverSolid<agg::order_argb32> DrawingModeARGB32OverSolid;
typedef DrawingModeOverSolid<agg::order_abgr32> DrawingModeABGR32OverSolid;
typedef DrawingModeOverSolid<agg::order_bgra32> DrawingModeBGRA32OverSolid;
#endif // DRAWING_MODE_OVER_H #endif // DRAWING_MODE_OVER_H
@@ -12,128 +12,110 @@
#include "DrawingMode.h" #include "DrawingMode.h"
// BLEND_SELECT // BLEND_SELECT
#define BLEND_SELECT(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_SELECT(d, r, g, b, a) \
{ \ { \
BLEND(d1, d2, d3, da, s1, s2, s3, a); \ BLEND(d, r, g, b, a); \
} }
// ASSIGN_SELECT // ASSIGN_SELECT
#define ASSIGN_SELECT(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_SELECT(d, r, g, b) \
{ \ { \
(d1) = (s1); \ d[0] = (b); \
(d2) = (s2); \ d[1] = (g); \
(d3) = (s3); \ d[2] = (r); \
(da) = 255; \
} }
// compare
template<class Order> inline bool
class DrawingModeSelect : public DrawingMode { compare(uint8* p, const rgb_color& high, const rgb_color& low, rgb_color* result)
public: {
// constructor pixel32 _p;
DrawingModeSelect() _p.data32 = *(uint32*)p;
: DrawingMode() if (_p.data8[2] == high.red &&
{ _p.data8[1] == high.green &&
} _p.data8[0] == high.blue) {
// compare
inline bool compare(uint8* p,
const rgb_color& high,
const rgb_color& low, rgb_color* result)
{
if (p[Order::R] == high.red &&
p[Order::G] == high.green &&
p[Order::B] == high.blue) {
result->red = low.red; result->red = low.red;
result->green = low.green; result->green = low.green;
result->blue = low.blue; result->blue = low.blue;
return true; return true;
} else if (p[Order::R] == low.red && } else if (_p.data8[2] == low.red &&
p[Order::G] == low.green && _p.data8[1] == low.green &&
p[Order::B] == low.blue) { _p.data8[0] == low.blue) {
result->red = high.red; result->red = high.red;
result->green = high.green; result->green = high.green;
result->blue = high.blue; result->blue = high.blue;
return true; return true;
} }
return false; return false;
} }
// blend_pixel_select
// blend_pixel void
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover) blend_pixel_select(int x, int y, const color_type& c, uint8 cover,
{ agg_buffer* buffer, const PatternHandler* pattern)
if (fPatternHandler->IsHighColor(x, y)) { {
uint8* p = fBuffer->row(y) + (x << 2); if (pattern->IsHighColor(x, y)) {
rgb_color high = fPatternHandler->HighColor().GetColor32(); uint8* p = buffer->row(y) + (x << 2);
rgb_color low = fPatternHandler->LowColor().GetColor32(); rgb_color high = pattern->HighColor().GetColor32();
rgb_color low = pattern->LowColor().GetColor32();
rgb_color color; rgb_color color;
if (compare(p, high, low, &color)) { if (compare(p, high, low, &color)) {
if (cover == 255) { if (cover == 255) {
ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SELECT(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SELECT(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
}
} }
} }
} }
}
// blend_hline // blend_hline_select
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_select(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
rgb_color high = fPatternHandler->HighColor().GetColor32(); {
rgb_color low = fPatternHandler->LowColor().GetColor32(); uint8* p = buffer->row(y) + (x << 2);
rgb_color high = pattern->HighColor().GetColor32();
rgb_color low = pattern->LowColor().GetColor32();
rgb_color color; rgb_color color;
if (cover == 255) { if (cover == 255) {
do { do {
if (fPatternHandler->IsHighColor(x, y) if (pattern->IsHighColor(x, y)
&& compare(p, high, low, &color)) && compare(p, high, low, &color))
ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SELECT(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} else { } else {
do { do {
if (fPatternHandler->IsHighColor(x, y) if (pattern->IsHighColor(x, y)
&& compare(p, high, low, &color)) { && compare(p, high, low, &color)) {
BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SELECT(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
} }
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
} }
} }
// blend_vline // blend_solid_hspan_select
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_select(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeSelect::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan rgb_color high = pattern->HighColor().GetColor32();
virtual void blend_solid_hspan(int x, int y, unsigned len, rgb_color low = pattern->LowColor().GetColor32();
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color high = fPatternHandler->HighColor().GetColor32();
rgb_color low = fPatternHandler->LowColor().GetColor32();
rgb_color color; rgb_color color;
do { do {
if (fPatternHandler->IsHighColor(x, y)) { if (pattern->IsHighColor(x, y)) {
if (*covers && compare(p, high, low, &color)) { if (*covers && compare(p, high, low, &color)) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SELECT(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SELECT(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
} }
@@ -141,57 +123,56 @@ printf("DrawingModeSelect::blend_vline()\n");
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_select
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_select(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
rgb_color high = fPatternHandler->HighColor().GetColor32(); {
rgb_color low = fPatternHandler->LowColor().GetColor32(); uint8* p = buffer->row(y) + (x << 2);
rgb_color high = pattern->HighColor().GetColor32();
rgb_color low = pattern->LowColor().GetColor32();
rgb_color color; rgb_color color;
do { do {
if (fPatternHandler->IsHighColor(x, y)) { if (pattern->IsHighColor(x, y)) {
if (*covers && compare(p, high, low, &color)) { if (*covers && compare(p, high, low, &color)) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SELECT(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SELECT(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_select
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_select(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
rgb_color high = fPatternHandler->HighColor().GetColor32(); rgb_color high = pattern->HighColor().GetColor32();
rgb_color low = fPatternHandler->LowColor().GetColor32(); rgb_color low = pattern->LowColor().GetColor32();
rgb_color color; rgb_color color;
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
if (*covers && compare(p, high, low, &color)) { if (*covers && compare(p, high, low, &color)) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SELECT(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SELECT(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
covers++; covers++;
@@ -203,8 +184,7 @@ printf("DrawingModeSelect::blend_vline()\n");
if (cover == 255) { if (cover == 255) {
do { do {
if (compare(p, high, low, &color)) { if (compare(p, high, low, &color)) {
ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SELECT(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} }
p += 4; p += 4;
++colors; ++colors;
@@ -213,32 +193,14 @@ printf("DrawingModeSelect::blend_vline()\n");
} else if (cover) { } else if (cover) {
do { do {
if (compare(p, high, low, &color)) { if (compare(p, high, low, &color)) {
BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SELECT(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeSelect::blend_color_vspan()\n");
}
};
typedef DrawingModeSelect<agg::order_rgba32> DrawingModeRGBA32Select;
typedef DrawingModeSelect<agg::order_argb32> DrawingModeARGB32Select;
typedef DrawingModeSelect<agg::order_abgr32> DrawingModeABGR32Select;
typedef DrawingModeSelect<agg::order_bgra32> DrawingModeBGRA32Select;
#endif // DRAWING_MODE_SELECT_H #endif // DRAWING_MODE_SELECT_H
@@ -15,147 +15,132 @@
#include "PatternHandler.h" #include "PatternHandler.h"
// BLEND_SUBTRACT // BLEND_SUBTRACT
#define BLEND_SUBTRACT(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_SUBTRACT(d, r, g, b, a) \
{ \ { \
uint8 t1 = max_c(0, (d1) - (s1)); \ pixel32 _p; \
uint8 t2 = max_c(0, (d2) - (s2)); \ _p.data32 = *(uint32*)d; \
uint8 t3 = max_c(0, (d3) - (s3)); \ uint8 rt = max_c(0, _p.data8[2] - (r)); \
BLEND(d1, d2, d3, da, t1, t2, t3, a); \ uint8 gt = max_c(0, _p.data8[1] - (g)); \
uint8 bt = max_c(0, _p.data8[0] - (b)); \
BLEND(d, rt, gt, bt, a); \
} }
// ASSIGN_SUBTRACT // ASSIGN_SUBTRACT
#define ASSIGN_SUBTRACT(d1, d2, d3, da, s1, s2, s3) \ #define ASSIGN_SUBTRACT(d, r, g, b) \
{ \ { \
(d1) = max_c(0, (d1) - (s1)); \ pixel32 _p; \
(d2) = max_c(0, (d2) - (s2)); \ _p.data32 = *(uint32*)d; \
(d3) = max_c(0, (d3) - (s3)); \ d[0] = max_c(0, _p.data8[0] - (b)); \
(da) = 255; \ d[1] = max_c(0, _p.data8[1] - (g)); \
d[2] = max_c(0, _p.data8[2] - (r)); \
} }
template<class Order> // blend_pixel_subtract
class DrawingModeSubtract : public DrawingMode { void
public: blend_pixel_subtract(int x, int y, const color_type& c, uint8 cover,
// constructor agg_buffer* buffer, const PatternHandler* pattern)
DrawingModeSubtract() {
: DrawingMode() uint8* p = buffer->row(y) + (x << 2);
{ rgb_color color = pattern->R5ColorAt(x, y);
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
rgb_color color = fPatternHandler->R5ColorAt(x, y);
if (cover == 255) { if (cover == 255) {
ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SUBTRACT(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SUBTRACT(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
}
} }
}
// blend_hline // blend_hline_subtract
virtual void blend_hline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_hline_subtract(int x, int y, unsigned len,
{ const color_type& c, uint8 cover,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
if (cover == 255) { if (cover == 255) {
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SUBTRACT(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} else { } else {
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SUBTRACT(p, color.red, color.green, color.blue, cover);
color.red, color.green, color.blue, cover);
x++; x++;
p += 4; p += 4;
} while(--len);
} }
while(--len); }
}
}
// blend_vline // blend_solid_hspan_subtract
virtual void blend_vline(int x, int y, unsigned len, void
const color_type& c, uint8 cover) blend_solid_hspan_subtract(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
printf("DrawingModeSubtract::blend_vline()\n"); agg_buffer* buffer, const PatternHandler* pattern)
} {
uint8* p = buffer->row(y) + (x << 2);
// blend_solid_hspan
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
uint8* p = fBuffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SUBTRACT(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SUBTRACT(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
covers++; covers++;
p += 4; p += 4;
x++; x++;
} while(--len); } while(--len);
} }
// blend_solid_vspan // blend_solid_vspan_subtract
virtual void blend_solid_vspan(int x, int y, unsigned len, void
const color_type& c, const uint8* covers) blend_solid_vspan_subtract(int x, int y, unsigned len,
{ const color_type& c, const uint8* covers,
uint8* p = fBuffer->row(y) + (x << 2); agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
do { do {
rgb_color color = fPatternHandler->R5ColorAt(x, y); rgb_color color = pattern->R5ColorAt(x, y);
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SUBTRACT(p, color.red, color.green, color.blue);
color.red, color.green, color.blue);
} else { } else {
BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SUBTRACT(p, color.red, color.green, color.blue, *covers);
color.red, color.green, color.blue, *covers);
} }
} }
covers++; covers++;
p += fBuffer->stride(); p += buffer->stride();
y++; y++;
} while(--len); } while(--len);
} }
// blend_color_hspan // blend_color_hspan_subtract
virtual void blend_color_hspan(int x, int y, unsigned len, void
blend_color_hspan_subtract(int x, int y, unsigned len,
const color_type* colors, const color_type* colors,
const uint8* covers, const uint8* covers, uint8 cover,
uint8 cover) agg_buffer* buffer, const PatternHandler* pattern)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = buffer->row(y) + (x << 2);
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
if (*covers) { if (*covers) {
if (*covers == 255) { if (*covers == 255) {
ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SUBTRACT(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
} else { } else {
BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SUBTRACT(p, colors->r, colors->g, colors->b, *covers);
colors->r, colors->g, colors->b, *covers);
} }
} }
covers++; covers++;
@@ -166,39 +151,20 @@ printf("DrawingModeSubtract::blend_vline()\n");
// solid full opcacity // solid full opcacity
if (cover == 255) { if (cover == 255) {
do { do {
ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_SUBTRACT(p, colors->r, colors->g, colors->b);
colors->r, colors->g, colors->b);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
// solid partial opacity // solid partial opacity
} else if (cover) { } else if (cover) {
do { do {
BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_SUBTRACT(p, colors->r, colors->g, colors->b, cover);
colors->r, colors->g, colors->b, cover);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
} }
} }
} }
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeSubtract::blend_color_vspan()\n");
}
};
typedef DrawingModeSubtract<agg::order_rgba32> DrawingModeRGBA32Subtract;
typedef DrawingModeSubtract<agg::order_argb32> DrawingModeARGB32Subtract;
typedef DrawingModeSubtract<agg::order_abgr32> DrawingModeABGR32Subtract;
typedef DrawingModeSubtract<agg::order_bgra32> DrawingModeBGRA32Subtract;
#endif // DRAWING_MODE_SUBTRACT_H #endif // DRAWING_MODE_SUBTRACT_H
@@ -1,475 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef PIXFMT_RGBA32_OVER_H
#define PIXFMT_RGBA32_OVER_H
#include <string.h>
#include <agg_basics.h>
#include <agg_color_rgba8.h>
#include <agg_rendering_buffer.h>
class PatternHandler;
class DrawingMode;
template<class Order> class pixel_formats_rgba32 {
public:
typedef agg::rgba8 color_type;
typedef Order order_type;
typedef agg::rendering_buffer::row_data row_data;
// constructor
pixel_formats_rgba32(agg::rendering_buffer& rb, const PatternHandler* handler)
: m_rbuf(&rb)
{
}
// set_drawing_mode
void set_drawing_mode(DrawingMode* mode)
{
// DUMMY
}
// set_pattern
void set_pattern(const PatternHandler* handler)
{
// DUMMY
}
// width
unsigned width() const { return m_rbuf->width(); }
// height
unsigned height() const { return m_rbuf->height(); }
// pixel
color_type pixel(int x, int y) const
{
printf("pixel()\n");
uint8* p = m_rbuf->row(y) + (x << 2);
return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
}
// span
row_data span(int x, int y) const
{
printf("span()\n");
return row_data(x, width() - 1, m_rbuf->row(y) + (x << 2));
}
// copy_pixel
void copy_pixel(int x, int y, const color_type& c)
{
printf("copy_pixel()\n");
uint8* p = m_rbuf->row(y) + (x << 2);
p[Order::R] = (uint8)c.r;
p[Order::G] = (uint8)c.g;
p[Order::B] = (uint8)c.b;
p[Order::A] = (uint8)c.a;
}
// blend_pixel
void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
//printf("blend_pixel()\n");
uint8* p = m_rbuf->row(y) + (x << 2);
p[Order::R] = (uint8)c.r;
p[Order::G] = (uint8)c.g;
p[Order::B] = (uint8)c.b;
/* int alpha = int(cover) * int(c.a);
if(alpha == 255*255)
{
p[Order::R] = (uint8)c.r;
p[Order::G] = (uint8)c.g;
p[Order::B] = (uint8)c.b;
p[Order::A] = (uint8)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (uint8)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (uint8)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (uint8)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (uint8)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}*/
}
// copy_hline
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
printf("copy_hline()\n");
uint32 v;
uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)c.r;
p8[Order::G] = (uint8)c.g;
p8[Order::B] = (uint8)c.b;
p8[Order::A] = (uint8)c.a;
uint32* p32 = (uint32*)(m_rbuf->row(y)) + x;
do
{
*p32++ = v;
}
while(--len);
}
// copy_vline
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
printf("copy_vline()\n");
uint32 v;
uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)c.r;
p8[Order::G] = (uint8)c.g;
p8[Order::B] = (uint8)c.b;
p8[Order::A] = (uint8)c.a;
uint8* p = m_rbuf->row(y) + (x << 2);
do
{
*(uint32*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
// blend_hline
void blend_hline(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
printf("blend_hline()\n");
int alpha = int(cover) * int(c.a);
if(alpha == 255*255)
{
uint32 v;
uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)c.r;
p8[Order::G] = (uint8)c.g;
p8[Order::B] = (uint8)c.b;
p8[Order::A] = (uint8)c.a;
uint32* p32 = (uint32*)(m_rbuf->row(y)) + x;
do
{
*p32++ = v;
}
while(--len);
}
else
{
uint8* p = m_rbuf->row(y) + (x << 2);
do
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (uint8)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (uint8)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (uint8)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (uint8)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
p += 4;
}
while(--len);
}
}
// blend_vline
void blend_vline(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
printf("blend_vline()\n");
uint8* p = m_rbuf->row(y) + (x << 2);
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
uint32 v;
uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)c.r;
p8[Order::G] = (uint8)c.g;
p8[Order::B] = (uint8)c.b;
p8[Order::A] = (uint8)c.a;
do
{
*(uint32*)p = v;
p += m_rbuf->stride();
}
while(--len);
}
else
{
do
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (uint8)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (uint8)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (uint8)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (uint8)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
p += m_rbuf->stride();
}
while(--len);
}
}
// copy_from
void copy_from(const agg::rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
printf("copy_from()\n");
memmove(m_rbuf->row(ydst) + xdst * 4,
(const void*)(from.row(ysrc) + xsrc * 4), len * 4);
}
// blend_from
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
const uint8* psrc,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
printf("blend_from()\n");
typedef typename SrcPixelFormatRenderer::order_type src_order;
uint8* pdst = m_rbuf->row(ydst) + (xdst << 2);
int incp = 4;
if(xdst > xsrc)
{
psrc += (len-1) << 2;
pdst += (len-1) << 2;
incp = -4;
}
do
{
int alpha = psrc[src_order::A];
if(alpha)
{
if(alpha == 255)
{
pdst[Order::R] = psrc[src_order::R];
pdst[Order::G] = psrc[src_order::G];
pdst[Order::B] = psrc[src_order::B];
pdst[Order::A] = psrc[src_order::A];
}
else
{
int r = pdst[Order::R];
int g = pdst[Order::G];
int b = pdst[Order::B];
int a = pdst[Order::A];
pdst[Order::R] = (uint8)((((psrc[src_order::R] - r) * alpha) + (r << 8)) >> 8);
pdst[Order::G] = (uint8)((((psrc[src_order::G] - g) * alpha) + (g << 8)) >> 8);
pdst[Order::B] = (uint8)((((psrc[src_order::B] - b) * alpha) + (b << 8)) >> 8);
pdst[Order::A] = (uint8)((alpha + a) - ((alpha * a) >> 8));
}
}
psrc += incp;
pdst += incp;
}
while(--len);
}
// blend_solid_hspan
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
//printf("blend_solid_hspan()\n");
uint8* p = m_rbuf->row(y) + (x << 2);
do
{
int alpha = int(*covers++) * c.a;
//int alpha = int(*covers++);
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (uint8)c.r;
p[Order::G] = (uint8)c.g;
p[Order::B] = (uint8)c.b;
p[Order::A] = (uint8)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (uint8)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (uint8)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (uint8)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (uint8)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
/*if(alpha > 127)
{
p[Order::R] = (uint8)c.r;
p[Order::G] = (uint8)c.g;
p[Order::B] = (uint8)c.b;
p[Order::A] = (uint8)c.a;
}*/
}
p += 4;
}
while(--len);
}
// blend_solid_vspan
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
//printf("blend_solid_vspan()\n");
uint8* p = m_rbuf->row(y) + (x << 2);
do
{
int alpha = int(*covers++) * c.a;
//int alpha = int(*covers++);
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (uint8)c.r;
p[Order::G] = (uint8)c.g;
p[Order::B] = (uint8)c.b;
p[Order::A] = (uint8)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (uint8)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (uint8)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (uint8)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (uint8)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
/*if(alpha > 127)
{
p[Order::R] = (uint8)c.r;
p[Order::G] = (uint8)c.g;
p[Order::B] = (uint8)c.b;
p[Order::A] = (uint8)c.a;
}*/
}
p += m_rbuf->stride();
}
while(--len);
}
// blend_color_hspan
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("blend_color_hspan()\n");
uint8* p = m_rbuf->row(y) + (x << 2);
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (uint8)colors->r;
p[Order::G] = (uint8)colors->g;
p[Order::B] = (uint8)colors->b;
p[Order::A] = (uint8)colors->a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (uint8)((((colors->r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (uint8)((((colors->g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (uint8)((((colors->b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (uint8)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
p += 4;
++colors;
}
while(--len);
}
// blend_color_vspan
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("blend_color_vspan()\n");
uint8* p = m_rbuf->row(y) + (x << 2);
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (uint8)colors->r;
p[Order::G] = (uint8)colors->g;
p[Order::B] = (uint8)colors->b;
p[Order::A] = (uint8)colors->a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (uint8)((((colors->r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (uint8)((((colors->g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (uint8)((((colors->b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (uint8)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
p += m_rbuf->stride();
++colors;
}
while(--len);
}
private:
agg::rendering_buffer* m_rbuf;
};
typedef pixel_formats_rgba32<order_rgba32> pixfmt_rgba32;
typedef pixel_formats_rgba32<order_argb32> pixfmt_argb32;
typedef pixel_formats_rgba32<order_abgr32> pixfmt_abgr32;
typedef pixel_formats_rgba32<order_bgra32> pixfmt_bgra32;
#endif // PIXFMT_RGBA32_OVER_H
@@ -1,256 +0,0 @@
/*
* Copyright 2005, Stephan Aßmus <[email protected]>. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
*
* A class implementing the AGG "pixel format" interface which maintains
* a PatternHandler and DrawingMode instance, to which it forwards any requests.
*
*/
#ifndef FORWARDING_PIXFMT_H
#define FORWARDING_PIXFMT_H
#include <stdio.h>
#include <string.h>
#include <agg_basics.h>
#include <agg_color_rgba8.h>
#include <agg_rendering_buffer.h>
#include "DrawingMode.h"
#include "PatternHandler.h"
template<class Order>
class forwarding_pixel_format {
public:
typedef agg::rgba8 color_type;
typedef Order order_type;
typedef agg::rendering_buffer::row_data row_data;
// constructor
forwarding_pixel_format(agg::rendering_buffer& rb, const PatternHandler* handler)
: fBuffer(&rb),
fDrawingMode(NULL),
fPatternHandler(handler)
{
}
~forwarding_pixel_format()
{
}
// set_drawing_mode
void set_drawing_mode(DrawingMode* mode)
{
if (fDrawingMode != mode) {
// attach new DrawingMode
fDrawingMode = mode;
if (fDrawingMode) {
fDrawingMode->set_rendering_buffer(fBuffer);
fDrawingMode->set_pattern_handler(fPatternHandler);
}
}
}
// set_pattern
void set_pattern(const PatternHandler* handler)
{
fPatternHandler = handler;
}
// width
unsigned width() const { return fBuffer->width(); }
// height
unsigned height() const { return fBuffer->height(); }
// pixel
color_type pixel(int x, int y) const
{
printf("forwarding_pixel_format::pixel()\n");
uint8* p = fBuffer->row(y) + (x << 2);
return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
}
// span
row_data span(int x, int y) const
{
printf("forwarding_pixel_format::span()\n");
return row_data(x, width() - 1, fBuffer->row(y) + (x << 2));
}
// copy_pixel
void copy_pixel(int x, int y, const color_type& c)
{
printf("forwarding_pixel_format::copy_pixel()\n");
uint8* p = fBuffer->row(y) + (x << 2);
p[Order::R] = (uint8)c.r;
p[Order::G] = (uint8)c.g;
p[Order::B] = (uint8)c.b;
p[Order::A] = (uint8)c.a;
}
// blend_pixel
void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
fDrawingMode->blend_pixel(x, y, c, cover);
}
// copy_hline
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
printf("forwarding_pixel_format::copy_hline()\n");
uint32 v;
uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)c.r;
p8[Order::G] = (uint8)c.g;
p8[Order::B] = (uint8)c.b;
p8[Order::A] = (uint8)c.a;
uint32* p32 = (uint32*)(fBuffer->row(y)) + x;
do {
*p32++ = v;
}
while(--len);
}
// copy_vline
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
printf("forwarding_pixel_format::copy_vline()\n");
uint32 v;
uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)c.r;
p8[Order::G] = (uint8)c.g;
p8[Order::B] = (uint8)c.b;
p8[Order::A] = (uint8)c.a;
uint8* p = fBuffer->row(y) + (x << 2);
do {
*(uint32*)p = v;
p += fBuffer->stride();
}
while(--len);
}
// blend_hline
void blend_hline(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
fDrawingMode->blend_hline(x, y, len, c, cover);
}
// blend_vline
void blend_vline(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
printf("forwarding_pixel_format::blend_vline()\n");
fDrawingMode->blend_vline(x, y, len, c, cover);
}
// copy_from
void copy_from(const agg::rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
printf("forwarding_pixel_format::copy_from()\n");
memmove(fBuffer->row(ydst) + xdst * 4,
(const void*)(from.row(ysrc) + xsrc * 4), len * 4);
}
// blend_from
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
const uint8* psrc,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
printf("forwarding_pixel_format::blend_from()\n");
typedef typename SrcPixelFormatRenderer::order_type src_order;
uint8* pdst = fBuffer->row(ydst) + (xdst << 2);
int incp = 4;
if (xdst > xsrc) {
psrc += (len-1) << 2;
pdst += (len-1) << 2;
incp = -4;
}
do {
int alpha = psrc[src_order::A];
if (alpha) {
if (alpha == 255) {
pdst[Order::R] = psrc[src_order::R];
pdst[Order::G] = psrc[src_order::G];
pdst[Order::B] = psrc[src_order::B];
pdst[Order::A] = psrc[src_order::A];
} else {
int r = pdst[Order::R];
int g = pdst[Order::G];
int b = pdst[Order::B];
int a = pdst[Order::A];
pdst[Order::R] = (uint8)((((psrc[src_order::R] - r) * alpha) + (r << 8)) >> 8);
pdst[Order::G] = (uint8)((((psrc[src_order::G] - g) * alpha) + (g << 8)) >> 8);
pdst[Order::B] = (uint8)((((psrc[src_order::B] - b) * alpha) + (b << 8)) >> 8);
pdst[Order::A] = (uint8)((alpha + a) - ((alpha * a) >> 8));
}
}
psrc += incp;
pdst += incp;
} while(--len);
}
// blend_solid_hspan
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
fDrawingMode->blend_solid_hspan(x, y, len, c, covers);
}
// blend_solid_vspan
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
fDrawingMode->blend_solid_vspan(x, y, len, c, covers);
}
// blend_color_hspan
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
fDrawingMode->blend_color_hspan(x, y, len, colors, covers, cover);
}
// blend_color_vspan
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("forwarding_pixel_format::blend_color_vspan()\n");
fDrawingMode->blend_color_vspan(x, y, len, colors, covers, cover);
}
private:
agg::rendering_buffer* fBuffer;
DrawingMode* fDrawingMode;
const PatternHandler* fPatternHandler;
};
#endif // FORWARDING_PIXFMT_H
@@ -565,7 +565,7 @@ namespace agg
} }
update_transform(); update_transform();
// update_char_size(); update_char_size();
} }
return ret; return ret;
} }