cairo_fill(cr);
}
-void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& srcRect, GraphicsContext* context)
+void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& originalSrcRect, GraphicsContext* context)
{
#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
cairo_surface_type_t surfaceType = cairo_surface_get_type(cairo_get_target (cr()));
}
#endif
- // 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
+ FloatRect srcRect = originalSrcRect;
+
+ // We need to account for negative source dimensions by flipping the rectangle.
+ if (originalSrcRect.width() < 0) {
+ srcRect.setX(originalSrcRect.x() + originalSrcRect.width());
+ srcRect.setWidth(std::fabs(originalSrcRect.width()));
+ }
+ if (originalSrcRect.height() < 0) {
+ srcRect.setY(originalSrcRect.y() + originalSrcRect.height());
+ srcRect.setHeight(std::fabs(originalSrcRect.height()));
+ }
+
+ // Cairo subsurfaces don't support floating point boundaries well, so we expand the rectangle.
+ IntRect expandedSrcRect(enclosingIntRect(srcRect));
+
#if ENABLE(TIZEN_ATLAS_IMAGE_BUG_FIX)
#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
RefPtr<cairo_pattern_t> pattern;
&& (srcRect.x() >= 0 && srcRect.x() < imageWidth && srcRect.y() >= 0 && srcRect.y() < imageHeight)
&& floor(srcRect.x() + srcRect.width()) - ceil(srcRect.x()) >= 1
&& floor(srcRect.y() + srcRect.height()) - ceil(srcRect.y()) >= 1) {
- subSurface = cairo_surface_create_for_rectangle(surface, srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height());
+ subSurface = cairo_surface_create_for_rectangle(surface, expandedSrcRect.x(), expandedSrcRect.y(), expandedSrcRect.width(), expandedSrcRect.height());
pattern = adoptRef(cairo_pattern_create_for_surface(subSurface));
cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, 0, 0 };
cairo_pattern_set_matrix(pattern.get(), &matrix);
&& (srcRect.x() >= 0 && srcRect.x() < imageWidth && srcRect.y() >= 0 && srcRect.y() < imageHeight)
&& floor(srcRect.x() + srcRect.width()) - ceil(srcRect.x()) >= 1
&& floor(srcRect.y() + srcRect.height()) - ceil(srcRect.y()) >= 1) {
- subSurface = cairo_surface_create_for_rectangle(surface, srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height());
+ subSurface = cairo_surface_create_for_rectangle(surface, expandedSrcRect.x(), expandedSrcRect.y(), expandedSrcRect.width(), expandedSrcRect.height());
pattern = adoptRef(cairo_pattern_create_for_surface(subSurface));
cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, 0, 0 };
cairo_pattern_set_matrix(pattern.get(), &matrix);
}
cairo_pattern_set_extend(pattern.get(), CAIRO_EXTEND_PAD);
+ float leftPadding = static_cast<float>(expandedSrcRect.x()) - floorf(srcRect.x());
+ float topPadding = static_cast<float>(expandedSrcRect.y()) - floorf(srcRect.y());
#if !ENABLE(TIZEN_ATLAS_IMAGE_BUG_FIX)
- float scaleX = srcRect.width() / destRect.width();
- float scaleY = srcRect.height() / destRect.height();
+ float scaleX = std::fabs(srcRect.width() / destRect.width());
+ float scaleY = std::fabs(srcRect.height() / destRect.height());
#if ENABLE(TIZEN_CAIROGLES_IMAGE_AUTOSCALE)
float scaleWidth = (float)original_width/current_width;
float scaleHeight = (float)original_height/current_height;
- cairo_matrix_t matrix = { scaleX/scaleWidth, 0, 0, scaleY/scaleHeight, srcRect.x()/scaleWidth, srcRect.y()/scaleHeight };
+ cairo_matrix_t matrix = { scaleX/scaleWidth, 0, 0, scaleY/scaleHeight, leftPadding/scaleWidth, topPadding/scaleHeight };
#else
- cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() };
+ cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, leftPadding, topPadding };
#endif
cairo_pattern_set_matrix(pattern.get(), &matrix);
#else
#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) ||ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
if (surfaceType == CAIRO_SURFACE_TYPE_GL) {
- float scaleX = srcRect.width() / destRect.width();
- float scaleY = srcRect.height() / destRect.height();
+ float scaleX = std::fabs(srcRect.width() / destRect.width());
+ float scaleY = std::fabs(srcRect.height() / destRect.height());
#if ENABLE(TIZEN_CAIROGLES_IMAGE_AUTOSCALE)
float scaleWidth = (float)original_width/current_width;
float scaleHeight = (float)original_height/current_height;
- cairo_matrix_t matrix = { scaleX/scaleWidth, 0, 0, scaleY/scaleHeight, srcRect.x()/scaleWidth, srcRect.y()/scaleHeight };
+ cairo_matrix_t matrix = { scaleX/scaleWidth, 0, 0, scaleY/scaleHeight,leftPadding/scaleWidth, topPadding/scaleHeight };
#else
- cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() };
+ cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, leftPadding, topPadding };
#endif
cairo_pattern_set_matrix(pattern.get(), &matrix);
}