From b6a33e1d41f7e77f5d1fdec054adf03fd2b97464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 12 Apr 2006 21:02:59 +0000 Subject: [PATCH] * 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 --- src/servers/app/drawing/Painter/Painter.cpp | 57 +++---- src/servers/app/drawing/Painter/Painter.h | 10 +- src/servers/app/drawing/Painter/defines.h | 7 +- .../drawing_modes/DrawingModeCopySolid.h | 47 +++--- .../drawing_modes/DrawingModeCopyText.h | 155 ++++++++++++++++++ .../drawing_modes/DrawingModeOverSolid.h | 2 +- .../Painter/drawing_modes/PixelFormat.cpp | 11 +- .../Painter/drawing_modes/PixelFormat.h | 11 +- .../Painter/font_support/AGGTextRenderer.cpp | 4 +- .../Painter/font_support/AGGTextRenderer.h | 10 +- 10 files changed, 228 insertions(+), 86 deletions(-) create mode 100644 src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyText.h diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index e94a967f27..888a3e0990 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -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)); } diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index 3b8a740856..4cda4e1105 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -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; diff --git a/src/servers/app/drawing/Painter/defines.h b/src/servers/app/drawing/Painter/defines.h index 496195692b..bdac7c8e2a 100644 --- a/src/servers/app/drawing/Painter/defines.h +++ b/src/servers/app/drawing/Painter/defines.h @@ -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_type; #else typedef agg::renderer_outline_aa 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_type; #endif - typedef agg::renderer_scanline_aa_solid font_renderer_solid_type; - typedef agg::renderer_scanline_bin_solid font_renderer_bin_type; + typedef agg::renderer_scanline_bin_solid renderer_bin_type; + + typedef agg::rasterizer_scanline_aa<> rasterizer_type; #endif // DEFINES_H diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h index 8e1789d829..db69afd3e8 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolid.h @@ -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); diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyText.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyText.h new file mode 100644 index 0000000000..11dcfc5cf1 --- /dev/null +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyText.h @@ -0,0 +1,155 @@ +/* + * Copyright 2006, Stephan Aßmus . 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 + diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h index 848e8b2794..4f4eb8ad34 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h @@ -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; diff --git a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp index cd16c77cc0..cd7d3e7716 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp +++ b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp @@ -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; diff --git a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h index a90ebe51be..18aedc6eac 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h +++ b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h @@ -19,9 +19,6 @@ #include -// 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(); } diff --git a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp index 4178070a10..e3091fb815 100644 --- a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp @@ -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, diff --git a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h index 9e5a581994..3c8c5e452c 100644 --- a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h +++ b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h @@ -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;