more correct implementation of B_OP_COPY, in that it blends against the current low color (as seen in text rendering on BeOS), of course this extends to anti-aliased lines on Haiku

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12559 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-05-03 21:45:16 +00:00
parent 24bc7597eb
commit b060f5e1eb
4 changed files with 64 additions and 25 deletions
@@ -13,8 +13,9 @@ class PatternHandler;
// BLEND // BLEND
// //
// 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!
#define BLEND(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND(d1, d2, d3, da, s1, s2, s3, a) \
{ \ { \
(d1) = (((((s1) - (d1)) * (a)) + ((d1) << 8)) >> 8); \ (d1) = (((((s1) - (d1)) * (a)) + ((d1) << 8)) >> 8); \
@@ -23,10 +24,26 @@ class PatternHandler;
(da) = max_c((da), (a)); \ (da) = max_c((da), (a)); \
} }
// BLEND_FROM
//
// This macro assumes source alpha in range 0..255 and
// ignores dest alpha (is assumed to equal 255).
// It uses two colors for the blending (f and s) and writes
// the result into a third color (d).
// 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) \
{ \
(d1) = (((((s1) - (f1)) * (a)) + ((f1) << 8)) >> 8); \
(d2) = (((((s2) - (f2)) * (a)) + ((f2) << 8)) >> 8); \
(d3) = (((((s3) - (f3)) * (a)) + ((f3) << 8)) >> 8); \
(da) = max_c((da), (a)); \
}
// BLEND16 // BLEND16
// //
// 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!
#define BLEND16(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND16(d1, d2, d3, da, s1, s2, s3, a) \
{ \ { \
(d1) = (((((s1) - (d1)) * (a)) + ((d1) << 16)) >> 16); \ (d1) = (((((s1) - (d1)) * (a)) + ((d1) << 16)) >> 16); \
@@ -37,8 +54,8 @@ class PatternHandler;
// 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(d1, d2, d3, da, s1, s2, s3, a) \
{ \ { \
if ((da) == 255) { \ if ((da) == 255) { \
@@ -57,8 +74,8 @@ class PatternHandler;
// BLEND_COMPOSITE16 // BLEND_COMPOSITE16
// //
// 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(d1, d2, d3, da, s1, s2, s3, a) \
{ \ { \
@@ -6,9 +6,9 @@
#include "DrawingMode.h" #include "DrawingMode.h"
// BLEND_COPY // BLEND_COPY
#define BLEND_COPY(d1, d2, d3, da, s1, s2, s3, a) \ #define BLEND_COPY(d1, d2, d3, da, s1, s2, s3, a, l1, l2, l3) \
{ \ { \
BLEND(d1, d2, d3, da, s1, s2, s3, a); \ BLEND_FROM(d1, d2, d3, da, l1, l2, l3, s1, s2, s3, a); \
} }
// ASSIGN_COPY // ASSIGN_COPY
@@ -41,8 +41,10 @@ class DrawingModeCopy : public DrawingMode {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue); color.red, color.green, color.blue);
} else { } else {
rgb_color l = fPatternHandler->LowColor().GetColor32();
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, cover); color.red, color.green, color.blue, cover,
l.red, l.green, l.blue);
} }
} }
@@ -50,7 +52,7 @@ class DrawingModeCopy : public DrawingMode {
virtual void blend_hline(int x, int y, unsigned len, virtual void blend_hline(int x, int y, unsigned len,
const color_type& c, uint8 cover) const color_type& c, uint8 cover)
{ {
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 = fPatternHandler->HighColor().GetColor32();
@@ -80,10 +82,12 @@ class DrawingModeCopy : public DrawingMode {
} while(--len); } while(--len);
} else { } else {
uint8* p = fBuffer->row(y) + (x << 2); 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 = fPatternHandler->R5ColorAt(x, y);
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, cover); color.red, color.green, color.blue, cover,
l.red, l.green, l.blue);
x++; x++;
p += 4; p += 4;
} while(--len); } while(--len);
@@ -102,6 +106,7 @@ printf("DrawingModeCopy::blend_vline()\n");
const color_type& c, const uint8* covers) const color_type& c, const uint8* covers)
{ {
uint8* p = fBuffer->row(y) + (x << 2); 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 = fPatternHandler->R5ColorAt(x, y);
if (*covers) { if (*covers) {
@@ -110,7 +115,8 @@ printf("DrawingModeCopy::blend_vline()\n");
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[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, *covers); color.red, color.green, color.blue, *covers,
l.red, l.green, l.blue);
} }
} }
covers++; covers++;
@@ -126,6 +132,7 @@ printf("DrawingModeCopy::blend_vline()\n");
const color_type& c, const uint8* covers) const color_type& c, const uint8* covers)
{ {
uint8* p = fBuffer->row(y) + (x << 2); 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 = fPatternHandler->R5ColorAt(x, y);
if (*covers) { if (*covers) {
@@ -134,7 +141,8 @@ printf("DrawingModeCopy::blend_vline()\n");
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[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, *covers); color.red, color.green, color.blue, *covers,
l.red, l.green, l.blue);
} }
} }
covers++; covers++;
@@ -151,6 +159,7 @@ printf("DrawingModeCopy::blend_vline()\n");
uint8 cover) uint8 cover)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = fBuffer->row(y) + (x << 2);
rgb_color l = fPatternHandler->LowColor().GetColor32();
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
@@ -160,7 +169,8 @@ printf("DrawingModeCopy::blend_vline()\n");
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[Order::R], p[Order::G], p[Order::B], p[Order::A],
colors->r, colors->g, colors->b, *covers); colors->r, colors->g, colors->b, *covers,
l.red, l.green, l.blue);
} }
} }
covers++; covers++;
@@ -180,7 +190,8 @@ printf("DrawingModeCopy::blend_vline()\n");
} 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[Order::R], p[Order::G], p[Order::B], p[Order::A],
colors->r, colors->g, colors->b, cover); colors->r, colors->g, colors->b, cover,
l.red, l.green, l.blue);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
@@ -22,8 +22,10 @@ class DrawingModeCopySolid : public DrawingMode {
ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], ASSIGN_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
c.r, c.g, c.b); c.r, c.g, c.b);
} else { } else {
rgb_color l = fPatternHandler->LowColor().GetColor32();
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
c.r, c.g, c.b, cover); c.r, c.g, c.b, cover,
l.red, l.green, l.blue);
} }
} }
@@ -47,9 +49,11 @@ class DrawingModeCopySolid : public DrawingMode {
} while(--len); } while(--len);
} else { } else {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = fBuffer->row(y) + (x << 2);
rgb_color l = fPatternHandler->LowColor().GetColor32();
do { do {
BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A], BLEND_COPY(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
c.r, c.g, c.b, cover); c.r, c.g, c.b, cover,
l.red, l.green, l.blue);
p += 4; p += 4;
} while(--len); } while(--len);
} }
@@ -67,6 +71,7 @@ printf("DrawingModeCopySolid::blend_vline()\n");
const color_type& c, const uint8* covers) const color_type& c, const uint8* covers)
{ {
uint8* p = fBuffer->row(y) + (x << 2); 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) {
@@ -74,7 +79,8 @@ printf("DrawingModeCopySolid::blend_vline()\n");
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[Order::R], p[Order::G], p[Order::B], p[Order::A],
c.r, c.g, c.b, *covers); c.r, c.g, c.b, *covers,
l.red, l.green, l.blue);
} }
} }
covers++; covers++;
@@ -89,6 +95,7 @@ printf("DrawingModeCopySolid::blend_vline()\n");
const color_type& c, const uint8* covers) const color_type& c, const uint8* covers)
{ {
uint8* p = fBuffer->row(y) + (x << 2); 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) {
@@ -96,7 +103,8 @@ printf("DrawingModeCopySolid::blend_vline()\n");
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[Order::R], p[Order::G], p[Order::B], p[Order::A],
c.r, c.g, c.b, *covers); c.r, c.g, c.b, *covers,
l.red, l.green, l.blue);
} }
} }
covers++; covers++;
@@ -112,6 +120,7 @@ printf("DrawingModeCopySolid::blend_vline()\n");
uint8 cover) uint8 cover)
{ {
uint8* p = fBuffer->row(y) + (x << 2); uint8* p = fBuffer->row(y) + (x << 2);
rgb_color l = fPatternHandler->LowColor().GetColor32();
if (covers) { if (covers) {
// non-solid opacity // non-solid opacity
do { do {
@@ -121,7 +130,8 @@ printf("DrawingModeCopySolid::blend_vline()\n");
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[Order::R], p[Order::G], p[Order::B], p[Order::A],
colors->r, colors->g, colors->b, *covers); colors->r, colors->g, colors->b, *covers,
l.red, l.green, l.blue);
} }
} }
covers++; covers++;
@@ -141,7 +151,8 @@ printf("DrawingModeCopySolid::blend_vline()\n");
} 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[Order::R], p[Order::G], p[Order::B], p[Order::A],
colors->r, colors->g, colors->b, cover); colors->r, colors->g, colors->b, cover,
l.red, l.green, l.blue);
p += 4; p += 4;
++colors; ++colors;
} while(--len); } while(--len);
@@ -86,9 +86,9 @@ DrawingModeFactory::DrawingModeFor(drawing_mode mode,
// in these drawing modes, the current high // in these drawing modes, the current high
// and low color are treated equally // and low color are treated equally
case B_OP_COPY: case B_OP_COPY:
if (solid) { if (solid)
return fDrawingModeBGRA32CopySolid; return fDrawingModeBGRA32CopySolid;
} else else
return fDrawingModeBGRA32Copy; return fDrawingModeBGRA32Copy;
break; break;
case B_OP_ADD: case B_OP_ADD: