PlatformContextCairo.cpp [plain text]
#include "config.h"
#include "PlatformContextCairo.h"
#include "GraphicsContext.h"
#include <cairo.h>
namespace WebCore {
PlatformContextCairo::PlatformContextCairo(cairo_t* cr)
: m_cr(cr)
{
}
void PlatformContextCairo::restore()
{
const ImageMaskInformation& maskInformation = m_maskImageStack.last();
if (maskInformation.isValid()) {
const FloatRect& maskRect = maskInformation.maskRect();
cairo_pop_group_to_source(m_cr.get());
cairo_mask_surface(m_cr.get(), maskInformation.maskSurface(), maskRect.x(), maskRect.y());
}
m_maskImageStack.removeLast();
cairo_restore(m_cr.get());
}
void PlatformContextCairo::save()
{
m_maskImageStack.append(ImageMaskInformation());
cairo_save(m_cr.get());
}
void PlatformContextCairo::pushImageMask(cairo_surface_t* surface, const FloatRect& rect)
{
ASSERT(!m_maskImageStack.isEmpty());
m_maskImageStack.last().update(surface, rect);
cairo_surface_t* currentTarget = cairo_get_target(m_cr.get());
cairo_surface_flush(currentTarget);
cairo_push_group(m_cr.get());
cairo_set_operator(m_cr.get(), CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface(m_cr.get(), currentTarget, 0, 0);
cairo_rectangle(m_cr.get(), rect.x(), rect.y(), rect.width(), rect.height());
cairo_fill(m_cr.get());
}
static void drawPatternToCairoContext(cairo_t* cr, cairo_pattern_t* pattern, const FloatRect& destRect, float alpha)
{
cairo_translate(cr, destRect.x(), destRect.y());
cairo_set_source(cr, pattern);
cairo_rectangle(cr, 0, 0, destRect.width(), destRect.height());
cairo_clip(cr);
cairo_paint_with_alpha(cr, alpha);
}
void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& srcRect, GraphicsContext* context)
{
RefPtr<cairo_pattern_t> pattern = adoptRef(cairo_pattern_create_for_surface(surface));
cairo_pattern_set_extend(pattern.get(), CAIRO_EXTEND_PAD);
float scaleX = srcRect.width() / destRect.width();
float scaleY = srcRect.height() / destRect.height();
cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() };
cairo_pattern_set_matrix(pattern.get(), &matrix);
ContextShadow* shadow = context->contextShadow();
if (shadow && shadow->m_type != ContextShadow::NoShadow) {
if (cairo_t* shadowContext = shadow->beginShadowLayer(context, destRect)) {
drawPatternToCairoContext(shadowContext, pattern.get(), destRect, 1);
shadow->endShadowLayer(context);
}
}
cairo_save(m_cr.get());
drawPatternToCairoContext(m_cr.get(), pattern.get(), destRect, context->getAlpha());
cairo_restore(m_cr.get());
}
}