diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSolid.h new file mode 100644 index 0000000000..da5f0de2ef --- /dev/null +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSolid.h @@ -0,0 +1,155 @@ +/* + * Copyright 2005, Stephan Aßmus + * Copyright 2015, Julian Harnath + * All rights reserved. Distributed under the terms of the MIT License. + * + * DrawingMode implementing B_OP_ALPHA in "Pixel Composite" mode on B_RGBA32. + * + */ + +#ifndef DRAWING_MODE_ALPHA_PC_SOLID_H +#define DRAWING_MODE_ALPHA_PC_SOLID_H + +#include "DrawingMode.h" + + +#define BLEND_ALPHA_PC(d, r, g, b, a) \ +{ \ + BLEND_COMPOSITE16(d, r, g, b, a); \ +} + + +#define ASSIGN_ALPHA_PC(d, r, g, b) \ +{ \ + d[0] = (b); \ + d[1] = (g); \ + d[2] = (r); \ + d[3] = 255; \ +} + + +void +blend_pixel_alpha_pc_solid(int x, int y, const color_type& color, uint8 cover, + agg_buffer* buffer, const PatternHandler*) +{ + uint8* p = buffer->row_ptr(y) + (x << 2); + uint16 alpha = color.a * cover; + if (alpha == 255 * 255) { + ASSIGN_ALPHA_PC(p, color.r, color.g, color.b); + } else { + BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha); + } +} + + +void +blend_hline_alpha_pc_solid(int x, int y, unsigned len, + const color_type& color, uint8 cover, + agg_buffer* buffer, const PatternHandler*) +{ + uint8* p = buffer->row_ptr(y) + (x << 2); + uint16 alpha = color.a * cover; + if (alpha == 0) + return; + + if (alpha == 255 * 255) { + do { + ASSIGN_ALPHA_PC(p, color.r, color.g, color.b); + p += 4; + } while(--len); + return; + } + + do { + BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha); + p += 4; + } while(--len); +} + + +void +blend_solid_hspan_alpha_pc_solid(int x, int y, unsigned len, + const color_type& color, const uint8* covers, + agg_buffer* buffer, const PatternHandler*) +{ + uint8* p = buffer->row_ptr(y) + (x << 2); + do { + uint16 alpha = color.a * *covers; + if (alpha) { + if(alpha == 255 * 255) { + ASSIGN_ALPHA_PC(p, color.r, color.g, color.b); + } else { + BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha); + } + } + covers++; + p += 4; + } while(--len); +} + + +void +blend_solid_vspan_alpha_pc_solid(int x, int y, unsigned len, + const color_type& color, const uint8* covers, + agg_buffer* buffer, const PatternHandler*) +{ + uint8* p = buffer->row_ptr(y) + (x << 2); + do { + uint16 alpha = color.a * *covers; + if (alpha) { + if (alpha == 255 * 255) { + ASSIGN_ALPHA_PC(p, color.r, color.g, color.b); + } else { + BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha); + } + } + covers++; + p += buffer->stride(); + } while(--len); +} + + +void +blend_color_hspan_alpha_pc_solid(int x, int y, unsigned len, + const color_type* colors, + const uint8* covers, uint8 cover, + agg_buffer* buffer, const PatternHandler*) +{ + uint8* p = buffer->row_ptr(y) + (x << 2); + if (covers) { + // non-solid opacity + do { + uint16 alpha = colors->a * *covers; + if (alpha) { + if (alpha == 255 * 255) { + ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b); + } else { + BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha); + } + } + covers++; + p += 4; + ++colors; + } while(--len); + } else { + // solid full opcacity + uint16 alpha = colors->a * cover; + if (alpha == 255 * 255) { + do { + ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b); + p += 4; + ++colors; + } while(--len); + // solid partial opacity + } else if (alpha) { + do { + BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha); + p += 4; + ++colors; + } while(--len); + } + } +} + + +#endif // DRAWING_MODE_ALPHA_PC_SOLID_H diff --git a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp index 0e4508ffe3..40ca5d3505 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp +++ b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp @@ -20,6 +20,7 @@ #include "DrawingModeAlphaCO.h" #include "DrawingModeAlphaCOSolid.h" #include "DrawingModeAlphaPC.h" +#include "DrawingModeAlphaPCSolid.h" #include "DrawingModeAlphaPO.h" #include "DrawingModeAlphaPOSolid.h" #include "DrawingModeBlend.h" @@ -211,7 +212,7 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, case B_OP_COPY: if (text) { fBlendPixel = blend_pixel_copy_text; - fBlendHLine = blend_hline_copy_text; + fBlendHLine = blend_hline_copy_text; fBlendSolidHSpanSubpix = blend_solid_hspan_copy_text_subpix; fBlendSolidHSpan = blend_solid_hspan_copy_text; fBlendSolidVSpan = blend_solid_vspan_copy_text; @@ -327,12 +328,21 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, } fBlendColorHSpan = blend_color_hspan_alpha_po; } else if (alphaFncMode == B_ALPHA_COMPOSITE) { - fBlendPixel = blend_pixel_alpha_pc; - fBlendHLine = blend_hline_alpha_pc; - fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix; - fBlendSolidHSpan = blend_solid_hspan_alpha_pc; - fBlendSolidVSpan = blend_solid_vspan_alpha_pc; - fBlendColorHSpan = blend_color_hspan_alpha_pc; + if (fPatternHandler->IsSolid()) { + fBlendPixel = blend_pixel_alpha_pc_solid; + fBlendHLine = blend_hline_alpha_pc_solid; + fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix; + fBlendSolidHSpan = blend_solid_hspan_alpha_pc_solid; + fBlendSolidVSpan = blend_solid_vspan_alpha_pc_solid; + fBlendColorHSpan = blend_color_hspan_alpha_pc_solid; + } else { + fBlendPixel = blend_pixel_alpha_pc; + fBlendHLine = blend_hline_alpha_pc; + fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix; + fBlendSolidHSpan = blend_solid_hspan_alpha_pc; + fBlendSolidVSpan = blend_solid_vspan_alpha_pc; + fBlendColorHSpan = blend_color_hspan_alpha_pc; + } } } break;