void CanvasStyle::applyStrokeColor(GraphicsContext* context) { if (!context) return; switch (m_type) { case ColorString: { Color c = Color(m_color); if (c.isValid()) { context->setStrokeColor(c.rgb(), DeviceColorSpace); break; } RGBA32 color = 0; // default is transparent black if (CSSParser::parseColor(color, m_color)) context->setStrokeColor(color, DeviceColorSpace); break; } case ColorStringWithAlpha: { Color c = Color(m_color); if (c.isValid()) { context->setStrokeColor(colorWithOverrideAlpha(c.rgb(), m_alpha), DeviceColorSpace); break; } RGBA32 color = 0; // default is transparent black if (CSSParser::parseColor(color, m_color)) context->setStrokeColor(colorWithOverrideAlpha(color, m_alpha), DeviceColorSpace); break; } case GrayLevel: // We're only supporting 255 levels of gray here. Since this isn't // even part of HTML5, I don't expect anyone will care. If they do // we'll make a fancier Color abstraction. context->setStrokeColor(Color(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha), DeviceColorSpace); break; case RGBA: context->setStrokeColor(Color(m_red, m_green, m_blue, m_alpha), DeviceColorSpace); break; case CMYKA: { // FIXME: Do this through platform-independent GraphicsContext API. // We'll need a fancier Color abstraction to support CYMKA correctly #if PLATFORM(CG) CGContextSetCMYKStrokeColor(context->platformContext(), m_cyan, m_magenta, m_yellow, m_black, m_alpha); #elif PLATFORM(QT) QPen currentPen = context->platformContext()->pen(); QColor clr; clr.setCmykF(m_cyan, m_magenta, m_yellow, m_black, m_alpha); currentPen.setColor(clr); context->platformContext()->setPen(currentPen); #else context->setStrokeColor(Color(m_cyan, m_magenta, m_yellow, m_black, m_alpha), DeviceColorSpace); #endif break; } case Gradient: context->setStrokeGradient(canvasGradient()->gradient()); break; case ImagePattern: context->setStrokePattern(canvasPattern()->pattern()); break; } }
static Color blendWithOpacity(const Color& color, float opacity) { RGBA32 rgba = color.rgb(); // See Color::getRGBA() to know how to extract alpha from color. float alpha = alphaChannel(rgba) / 255.; float effectiveAlpha = alpha * opacity; return Color(colorWithOverrideAlpha(rgba, effectiveAlpha)); }
Color SVGStopElement::stopColorIncludingOpacity() const { ASSERT(renderer()); ASSERT(renderer()->style()); const SVGRenderStyle* svgStyle = renderer()->style()->svgStyle(); return colorWithOverrideAlpha(svgStyle->stopColor().rgb(), svgStyle->stopOpacity()); }
void FEFlood::apply(Filter* filter) { GraphicsContext* filterContext = effectContext(filter); if (!filterContext) return; Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity()); filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color, DeviceColorSpace); }
void FEFlood::platformApplySoftware() { ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity()); resultImage->context()->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color, ColorSpaceDeviceRGB); }
Color SVGStopElement::stopColorIncludingOpacity() const { RenderStyle* style = renderer() ? &renderer()->style() : nullptr; // FIXME: This check for null style exists to address Bug WK 90814, a rare crash condition in // which the renderer or style is null. This entire class is scheduled for removal (Bug WK 86941) // and we will tolerate this null check until then. if (!style) return Color(Color::transparent, true); // Transparent black. const SVGRenderStyle& svgStyle = style->svgStyle(); return colorWithOverrideAlpha(svgStyle.stopColor().rgb(), svgStyle.stopOpacity()); }
static void prepareCairoContextSource(cairo_t* cr, Pattern* pattern, Gradient* gradient, const Color& color, float globalAlpha) { if (pattern) { RefPtr<cairo_pattern_t> cairoPattern(adoptRef(pattern->createPlatformPattern(AffineTransform()))); cairo_set_source(cr, cairoPattern.get()); reduceSourceByAlpha(cr, globalAlpha); } else if (gradient) cairo_set_source(cr, gradient->platformGradient(globalAlpha)); else { // Solid color source. if (globalAlpha < 1) setSourceRGBAFromColor(cr, colorWithOverrideAlpha(color.rgb(), color.alpha() / 255.f * globalAlpha)); else setSourceRGBAFromColor(cr, color); } }
PassRefPtrWillBeRawPtr<CanvasStyle> CanvasStyle::createFromStringWithOverrideAlpha(const String& color, float alpha) { RGBA32 rgba; ColorParseResult parseResult = parseColor(rgba, color); switch (parseResult) { case ParsedRGBA: return adoptRefWillBeNoop(new CanvasStyle(colorWithOverrideAlpha(rgba, alpha))); case ParsedCurrentColor: return adoptRefWillBeNoop(new CanvasStyle(CurrentColorWithOverrideAlpha, alpha)); case ParseFailed: return nullptr; default: ASSERT_NOT_REACHED(); return nullptr; } }
CanvasStyle CanvasStyle::createFromStringWithOverrideAlpha(const String& color, float alpha) { RGBA32 rgba; ColorParseResult parseResult = parseColor(rgba, color); switch (parseResult) { case ParsedRGBA: return CanvasStyle(colorWithOverrideAlpha(rgba, alpha)); case ParsedCurrentColor: return CanvasStyle(CurrentColorWithOverrideAlpha, alpha); case ParseFailed: return CanvasStyle(); default: ASSERT_NOT_REACHED(); return CanvasStyle(); } }
static void prepareCairoContextSource(cairo_t* cr, Pattern* pattern, Gradient* gradient, const Color& color, float globalAlpha) { if (pattern) { RefPtr<cairo_pattern_t> cairoPattern(adoptRef(pattern->createPlatformPattern(AffineTransform()))); cairo_set_source(cr, cairoPattern.get()); reduceSourceByAlpha(cr, globalAlpha); } else if (gradient) { cairo_set_source(cr, gradient->platformGradient()); // FIXME: It would be faster to simply recreate the Cairo gradient and multiply the // color stops by the global alpha. reduceSourceByAlpha(cr, globalAlpha); } else { // Solid color source. if (globalAlpha < 1) setSourceRGBAFromColor(cr, colorWithOverrideAlpha(color.rgb(), color.alpha() / 255.f * globalAlpha)); else setSourceRGBAFromColor(cr, color); } }
Color Color::combineWithAlpha(float otherAlpha) const { return colorWithOverrideAlpha(rgb(), (alpha() / 255.f) * otherAlpha); }
void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op) { FloatRect srcRect(src); FloatRect dstRect(dst); if (dstRect.width() == 0.0f || dstRect.height() == 0.0f || srcRect.width() == 0.0f || srcRect.height() == 0.0f) return; startAnimation(); cairo_surface_t* image = frameAtIndex(m_currentFrame); if (!image) // If it's too early we won't have an image yet. return; if (mayFillWithSolidColor()) { fillWithSolidColor(context, dstRect, solidColor(), styleColorSpace, op); return; } IntSize selfSize = size(); cairo_t* cr = context->platformContext(); context->save(); // Set the compositing operation. if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame)) context->setCompositeOperation(CompositeCopy); else context->setCompositeOperation(op); // If we're drawing a sub portion of the image or scaling then create // a pattern transformation on the image and draw the transformed pattern. // Test using example site at http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD); float scaleX = srcRect.width() / dstRect.width(); float scaleY = srcRect.height() / dstRect.height(); cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() }; cairo_pattern_set_matrix(pattern, &matrix); // Draw the shadow #if ENABLE(FILTERS) FloatSize shadowOffset; float shadowBlur; Color shadowColor; if (context->getShadow(shadowOffset, shadowBlur, shadowColor)) { IntSize shadowBufferSize; FloatRect shadowRect; float radius = 0; context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, dstRect, shadowOffset, shadowBlur); shadowColor = colorWithOverrideAlpha(shadowColor.rgb(), (shadowColor.alpha() * context->getAlpha()) / 255.f); //draw shadow into a new ImageBuffer OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); cairo_t* shadowContext = shadowBuffer->context()->platformContext(); cairo_set_source(shadowContext, pattern); cairo_translate(shadowContext, -dstRect.x(), -dstRect.y()); cairo_rectangle(shadowContext, 0, 0, dstRect.width(), dstRect.height()); cairo_fill(shadowContext); context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); } #endif // Draw the image. cairo_translate(cr, dstRect.x(), dstRect.y()); cairo_set_source(cr, pattern); cairo_pattern_destroy(pattern); cairo_rectangle(cr, 0, 0, dstRect.width(), dstRect.height()); cairo_clip(cr); cairo_paint_with_alpha(cr, context->getAlpha()); context->restore(); if (imageObserver()) imageObserver()->didDraw(this); }