* removed the special font renderer which was actually

the same as the normal one (one less renderer to update
  the color of)
* added a special B_OP_COPY implementation for text, which
  is in fact what the implementation was until now, so
  just like on R5, you have to specify the correct low color
  or you will see artifacts for the anti-aliased pixels
* implemented B_OP_COPY just like B_OP_OVER (only it draws
  the low color too like it should). So all apps that
  used B_OP_COPY to draw anything can continue to do so
  without having to worry about the low color, it will
  be anti-aliased against the actual background instead of
  the low color (which made especially no sense when drawing
  with the low color). Although this change makes it a bit
  slower to use B_OP_COPY, Haiku is now much more compatible.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17117 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2006-04-12 21:02:59 +00:00
parent 82081c70ea
commit b6a33e1d41
10 changed files with 228 additions and 86 deletions

View File

@ -70,8 +70,7 @@ Painter::Painter()
fPackedScanline(NULL),
fRasterizer(NULL),
fRenderer(NULL),
fFontRendererSolid(NULL),
fFontRendererBin(NULL),
fRendererBin(NULL),
fLineProfile(),
fSubpixelPrecise(false),
@ -79,6 +78,7 @@ Painter::Painter()
fClippingRegion(new BRegion()),
fValidClipping(false),
fDrawingMode(B_OP_COPY),
fDrawingText(false),
fAlphaSrcMode(B_PIXEL_ALPHA),
fAlphaFncMode(B_ALPHA_OVERLAY),
fPenLocation(0.0, 0.0),
@ -129,7 +129,7 @@ Painter::AttachToBuffer(RenderingBuffer* buffer)
buffer->BytesPerRow());
fPixelFormat = new pixfmt(*fBuffer, fPatternHandler);
fPixelFormat->SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode);
fPixelFormat->SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode, false);
fBaseRenderer = new renderer_base(*fPixelFormat);
// attach our clipping region to the renderer, it keeps a pointer
@ -159,9 +159,9 @@ Painter::AttachToBuffer(RenderingBuffer* buffer)
fRasterizer->gamma(agg::gamma_threshold(0.5));
#endif
// These are renderers needed for drawing text
fFontRendererSolid = new font_renderer_solid_type(*fBaseRenderer);
fFontRendererBin = new font_renderer_bin_type(*fBaseRenderer);
// possibly needed for drawing text (if the font is
// a one bit bitmap font, which is currently not supported yet)
fRendererBin = new renderer_bin_type(*fBaseRenderer);
_SetRendererColor(fPatternHandler->HighColor().GetColor32());
}
@ -261,11 +261,12 @@ Painter::SetPenSize(float size)
// SetPattern
void
Painter::SetPattern(const pattern& p)
Painter::SetPattern(const pattern& p, bool drawingText)
{
if (!(p == *fPatternHandler->GetR5Pattern())) {
if (!(p == *fPatternHandler->GetR5Pattern()) || drawingText != fDrawingText) {
fPatternHandler->SetPattern(p);
_UpdateDrawingMode();
fDrawingText = drawingText;
_UpdateDrawingMode(fDrawingText);
// update renderer color if necessary
if (fPatternHandler->IsSolidHigh()) {
@ -925,13 +926,13 @@ Painter::DrawString(const char* utf8String, uint32 length,
BRect bounds(0.0, 0.0, -1.0, -1.0);
SetPattern(B_SOLID_HIGH);
SetPattern(B_SOLID_HIGH, true);
if (fBuffer) {
bounds = fTextRenderer->RenderString(utf8String,
length,
fFontRendererSolid,
fFontRendererBin,
fRenderer,
fRendererBin,
baseLine,
fClippingRegion->Frame(),
false,
@ -955,8 +956,8 @@ Painter::BoundingBox(const char* utf8String, uint32 length,
static BRect dummy;
return fTextRenderer->RenderString(utf8String,
length,
fFontRendererSolid,
fFontRendererBin,
fRenderer,
fRendererBin,
baseLine, dummy, true, penLocation,
delta);
}
@ -1064,11 +1065,8 @@ Painter::_MakeEmpty()
delete fRenderer;
fRenderer = NULL;
delete fFontRendererSolid;
fFontRendererSolid = NULL;
delete fFontRendererBin;
fFontRendererBin = NULL;
delete fRendererBin;
fRendererBin = NULL;
}
// _Transform
@ -1125,7 +1123,7 @@ Painter::_UpdateLineWidth()
// _UpdateDrawingMode
void
Painter::_UpdateDrawingMode()
Painter::_UpdateDrawingMode(bool drawingText)
{
// The AGG renderers have their own color setting, however
// almost all drawing mode classes ignore the color given
@ -1139,7 +1137,8 @@ Painter::_UpdateDrawingMode()
// has to be called so that all internal colors in the renderes
// are up to date for use by the solid drawing mode version.
if (fPixelFormat) {
fPixelFormat->SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode);
fPixelFormat->SetDrawingMode(fDrawingMode, fAlphaSrcMode,
fAlphaFncMode, drawingText);
}
}
@ -1167,16 +1166,12 @@ Painter::_SetRendererColor(const rgb_color& color) const
color.green / 255.0,
color.blue / 255.0,
color.alpha / 255.0));
if (fFontRendererSolid)
fFontRendererSolid->color(agg::rgba(color.red / 255.0,
color.green / 255.0,
color.blue / 255.0,
color.alpha / 255.0));
if (fFontRendererBin)
fFontRendererBin->color(agg::rgba(color.red / 255.0,
color.green / 255.0,
color.blue / 255.0,
color.alpha / 255.0));
// TODO: bitmap fonts not yet correctly setup in AGGTextRenderer
// if (RendererBin)
// RendererBin->color(agg::rgba(color.red / 255.0,
// color.green / 255.0,
// color.blue / 255.0,
// color.alpha / 255.0));
}

View File

@ -75,7 +75,8 @@ class Painter {
{ SetLowColor(color.GetColor32()); }
void SetPenSize(float size);
void SetPattern(const pattern& p);
void SetPattern(const pattern& p,
bool drawingText = false);
void SetPenLocation(const BPoint& location);
BPoint PenLocation() const
@ -212,7 +213,7 @@ class Painter {
void _UpdateFont();
void _UpdateLineWidth();
void _UpdateDrawingMode();
void _UpdateDrawingMode(bool drawingText = false);
void _SetRendererColor(const rgb_color& color) const;
// drawing functions stroke/fill
@ -273,9 +274,7 @@ class Painter {
scanline_packed_type* fPackedScanline;
rasterizer_type* fRasterizer;
renderer_type* fRenderer;
font_renderer_solid_type* fFontRendererSolid;
font_renderer_bin_type* fFontRendererBin;
renderer_bin_type* fRendererBin;
agg::line_profile_aa fLineProfile;
@ -286,6 +285,7 @@ class Painter {
BRegion* fClippingRegion;
bool fValidClipping;
drawing_mode fDrawingMode;
bool fDrawingText;
source_alpha fAlphaSrcMode;
alpha_function fAlphaFncMode;
BPoint fPenLocation;

View File

@ -36,7 +36,6 @@
typedef agg::scanline_bin scanline_unpacked_type;
typedef agg::scanline_bin scanline_packed_type;
typedef agg::rasterizer_scanline_aa<> rasterizer_type;
typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_type;
#else
typedef agg::renderer_outline_aa<renderer_base> outline_renderer_type;
@ -44,12 +43,12 @@
typedef agg::scanline_u8 scanline_unpacked_type;
typedef agg::scanline_p8 scanline_packed_type;
typedef agg::rasterizer_scanline_aa<> rasterizer_type;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
#endif
typedef agg::renderer_scanline_aa_solid<renderer_base> font_renderer_solid_type;
typedef agg::renderer_scanline_bin_solid<renderer_base> font_renderer_bin_type;
typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_bin_type;
typedef agg::rasterizer_scanline_aa<> rasterizer_type;
#endif // DEFINES_H

View File

@ -9,7 +9,7 @@
#ifndef DRAWING_MODE_COPY_SOLID_H
#define DRAWING_MODE_COPY_SOLID_H
#include "DrawingModeCopy.h"
#include "DrawingModeOver.h"
// blend_pixel_copy_solid
void
@ -18,11 +18,9 @@ blend_pixel_copy_solid(int x, int y, const color_type& c, uint8 cover,
{
uint8* p = buffer->row(y) + (x << 2);
if (cover == 255) {
ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
ASSIGN_OVER(p, c.r, c.g, c.b);
} else {
rgb_color l = pattern->LowColor().GetColor32();
BLEND_COPY(p, c.r, c.g, c.b, cover,
l.red, l.green, l.blue);
BLEND_OVER(p, c.r, c.g, c.b, cover);
}
}
@ -33,25 +31,23 @@ blend_hline_copy_solid(int x, int y, unsigned len,
agg_buffer* buffer, const PatternHandler* pattern)
{
if (cover == 255) {
// cache the color as 32bit value
uint32 v;
uint8* p8 = (uint8*)&v;
p8[0] = (uint8)c.b;
p8[1] = (uint8)c.g;
p8[2] = (uint8)c.r;
p8[3] = 255;
// row offset as 32bit pointer
uint32* p32 = (uint32*)(buffer->row(y)) + x;
do {
*p32 = v;
p32++;
x++;
} while(--len);
} else {
uint8* p = buffer->row(y) + (x << 2);
rgb_color l = pattern->LowColor().GetColor32();
do {
BLEND_COPY(p, c.r, c.g, c.b, cover,
l.red, l.green, l.blue);
BLEND_OVER(p, c.r, c.g, c.b, cover);
x++;
p += 4;
} while(--len);
}
@ -65,18 +61,17 @@ blend_solid_hspan_copy_solid(int x, int y, unsigned len,
const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
rgb_color l = pattern->LowColor().GetColor32();
do {
if (*covers) {
if(*covers == 255) {
ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
if (*covers == 255) {
ASSIGN_OVER(p, c.r, c.g, c.b);
} else {
BLEND_COPY(p, c.r, c.g, c.b, *covers,
l.red, l.green, l.blue);
BLEND_OVER(p, c.r, c.g, c.b, *covers);
}
}
covers++;
p += 4;
x++;
} while(--len);
}
@ -90,18 +85,17 @@ blend_solid_vspan_copy_solid(int x, int y, unsigned len,
const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
rgb_color l = pattern->LowColor().GetColor32();
do {
if (*covers) {
if (*covers == 255) {
ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
ASSIGN_OVER(p, c.r, c.g, c.b);
} else {
BLEND_COPY(p, c.r, c.g, c.b, *covers,
l.red, l.green, l.blue);
BLEND_OVER(p, c.r, c.g, c.b, *covers);
}
}
covers++;
p += buffer->stride();
y++;
} while(--len);
}
@ -115,16 +109,14 @@ blend_color_hspan_copy_solid(int x, int y, unsigned len,
const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
rgb_color l = pattern->LowColor().GetColor32();
if (covers) {
// non-solid opacity
do {
if(*covers) {
if(*covers == 255) {
ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
if (*covers) {
if (*covers == 255) {
ASSIGN_OVER(p, colors->r, colors->g, colors->b);
} else {
BLEND_COPY(p, colors->r, colors->g, colors->b, *covers,
l.red, l.green, l.blue);
BLEND_OVER(p, colors->r, colors->g, colors->b, *covers);
}
}
covers++;
@ -135,15 +127,14 @@ blend_color_hspan_copy_solid(int x, int y, unsigned len,
// solid full opcacity
if (cover == 255) {
do {
ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
ASSIGN_OVER(p, colors->r, colors->g, colors->b);
p += 4;
++colors;
} while(--len);
// solid partial opacity
} else if (cover) {
do {
BLEND_COPY(p, colors->r, colors->g, colors->b, cover,
l.red, l.green, l.blue);
BLEND_OVER(p, colors->r, colors->g, colors->b, cover);
p += 4;
++colors;
} while(--len);

View File

@ -0,0 +1,155 @@
/*
* Copyright 2006, Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
* Distributed under the terms of the MIT License.
*
* DrawingMode implementing B_OP_COPY for text on B_RGBA32.
*
*/
#ifndef DRAWING_MODE_COPY_TEXT_H
#define DRAWING_MODE_COPY_TEXT_H
#include "DrawingModeCopy.h"
// blend_pixel_copy_text
void
blend_pixel_copy_text(int x, int y, const color_type& c, uint8 cover,
agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
if (cover == 255) {
ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
} else {
rgb_color l = pattern->LowColor().GetColor32();
BLEND_COPY(p, c.r, c.g, c.b, cover,
l.red, l.green, l.blue);
}
}
// blend_hline_copy_text
void
blend_hline_copy_text(int x, int y, unsigned len,
const color_type& c, uint8 cover,
agg_buffer* buffer, const PatternHandler* pattern)
{
if (cover == 255) {
// cache the color as 32bit value
uint32 v;
uint8* p8 = (uint8*)&v;
p8[0] = (uint8)c.b;
p8[1] = (uint8)c.g;
p8[2] = (uint8)c.r;
p8[3] = 255;
// row offset as 32bit pointer
uint32* p32 = (uint32*)(buffer->row(y)) + x;
do {
*p32 = v;
p32++;
} while(--len);
} else {
uint8* p = buffer->row(y) + (x << 2);
rgb_color l = pattern->LowColor().GetColor32();
do {
BLEND_COPY(p, c.r, c.g, c.b, cover,
l.red, l.green, l.blue);
p += 4;
} while(--len);
}
}
// blend_solid_hspan_copy_text
void
blend_solid_hspan_copy_text(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 {
if (*covers) {
if(*covers == 255) {
ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
} else {
BLEND_COPY(p, c.r, c.g, c.b, *covers,
l.red, l.green, l.blue);
}
}
covers++;
p += 4;
} while(--len);
}
// blend_solid_vspan_copy_text
void
blend_solid_vspan_copy_text(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 {
if (*covers) {
if (*covers == 255) {
ASSIGN_COPY(p, c.r, c.g, c.b, c.a);
} else {
BLEND_COPY(p, c.r, c.g, c.b, *covers,
l.red, l.green, l.blue);
}
}
covers++;
p += buffer->stride();
} while(--len);
}
// blend_color_hspan_copy_text
void
blend_color_hspan_copy_text(int x, int y, unsigned len,
const color_type* colors, const uint8* covers,
uint8 cover,
agg_buffer* buffer,
const PatternHandler* pattern)
{
uint8* p = buffer->row(y) + (x << 2);
rgb_color l = pattern->LowColor().GetColor32();
if (covers) {
// non-solid opacity
do {
if(*covers) {
if(*covers == 255) {
ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
} else {
BLEND_COPY(p, colors->r, colors->g, colors->b, *covers,
l.red, l.green, l.blue);
}
}
covers++;
p += 4;
++colors;
} while(--len);
} else {
// solid full opcacity
if (cover == 255) {
do {
ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
p += 4;
++colors;
} while(--len);
// solid partial opacity
} else if (cover) {
do {
BLEND_COPY(p, colors->r, colors->g, colors->b, cover,
l.red, l.green, l.blue);
p += 4;
++colors;
} while(--len);
}
}
}
#endif // DRAWING_MODE_COPY_TEXT_H

View File

@ -36,7 +36,7 @@ blend_hline_over_solid(int x, int y, unsigned len,
if (pattern->IsSolidLow())
return;
if(cover == 255) {
if (cover == 255) {
uint32 v;
uint8* p8 = (uint8*)&v;
p8[0] = (uint8)c.b;

View File

@ -24,6 +24,7 @@
#include "DrawingModeBlend.h"
#include "DrawingModeCopy.h"
#include "DrawingModeCopySolid.h"
#include "DrawingModeCopyText.h"
#include "DrawingModeErase.h"
#include "DrawingModeInvert.h"
#include "DrawingModeMin.h"
@ -126,7 +127,7 @@ PixelFormat::~PixelFormat()
// SetDrawingMode
void
PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
alpha_function alphaFncMode)
alpha_function alphaFncMode, bool text)
{
switch (mode) {
// these drawing modes discard source pixels
@ -171,7 +172,13 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
// in these drawing modes, the current high
// and low color are treated equally
case B_OP_COPY:
if (fPatternHandler->IsSolid()) {
if (text) {
fBlendPixel = blend_pixel_copy_text;
fBlendHLine = blend_hline_copy_text;
fBlendSolidHSpan = blend_solid_hspan_copy_text;
fBlendSolidVSpan = blend_solid_vspan_copy_text;
fBlendColorHSpan = blend_color_hspan_copy_text;
} else if (fPatternHandler->IsSolid()) {
fBlendPixel = blend_pixel_copy_solid;
fBlendHLine = blend_hline_copy_solid;
fBlendSolidHSpan = blend_solid_hspan_copy_solid;

View File

@ -19,9 +19,6 @@
#include <GraphicsDefs.h>
// TODO: remove (just DrawingMode)
class DrawingMode;
class PatternHandler;
class PixelFormat {
@ -59,14 +56,10 @@ class PixelFormat {
~PixelFormat();
// TODO: remove set_drawing_mode
void set_drawing_mode(DrawingMode* mode)
{
}
void SetDrawingMode(drawing_mode mode,
source_alpha alphaSrcMode,
alpha_function alphaFncMode);
alpha_function alphaFncMode,
bool text);
// AGG "pixel format" interface
unsigned width() const { return fBuffer->width(); }

View File

@ -175,8 +175,8 @@ AGGTextRenderer::Unset()
BRect
AGGTextRenderer::RenderString(const char* string,
uint32 length,
font_renderer_solid_type* solidRenderer,
font_renderer_bin_type* binRenderer,
renderer_type* solidRenderer,
renderer_bin_type* binRenderer,
const BPoint& baseLine,
const BRect& clippingFrame,
bool dryRun,

View File

@ -38,8 +38,8 @@ class AGGTextRenderer {
BRect RenderString(const char* utf8String,
uint32 length,
font_renderer_solid_type* solidRenderer,
font_renderer_bin_type* binRenderer,
renderer_type* solidRenderer,
renderer_bin_type* binRenderer,
const BPoint& baseLine,
const BRect& clippingFrame,
bool dryRun = false,
@ -67,8 +67,10 @@ class AGGTextRenderer {
conv_font_curve_type fCurves;
conv_font_contour_type fContour;
agg::scanline_u8 fScanline;
agg::rasterizer_scanline_aa<> fRasterizer;
scanline_unpacked_type fScanline;
rasterizer_type fRasterizer;
// TODO: both of these are actually in Painter already
// and could be reused by this object
char* fUnicodeBuffer;
int32 fUnicodeBufferSize;