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;