if (cairo_surface_status(sourceImageSurface.get()) != CAIRO_STATUS_SUCCESS)
return;
image = sourceImageSurface.get();
- }
- else if (cairo_surface_get_type(cairo_get_target(cr)) == CAIRO_SURFACE_TYPE_GL && cairo_surface_get_type(image) == CAIRO_SURFACE_TYPE_IMAGE) {
+ } else if (cairo_surface_get_type(cairo_get_target(cr)) == CAIRO_SURFACE_TYPE_GL && cairo_surface_get_type(image) == CAIRO_SURFACE_TYPE_IMAGE) {
RefPtr<cairo_surface_t> snapshot = adoptRef((cairo_surface_t *) cairo_surface_get_user_data(image, (const cairo_user_data_key_t *)image));
if (snapshot && cairo_surface_get_type(snapshot.get()) != CAIRO_SURFACE_TYPE_GL) {
cairo_surface_set_user_data(image, (const cairo_user_data_key_t *)image, 0, 0);
RefPtr<cairo_t> snapshotContext = adoptRef(cairo_create(snapshot.get()));
cairo_set_source_surface(snapshotContext.get(), image, 0, 0);
cairo_paint(snapshotContext.get());
- cairo_surface_set_user_data(image, (const cairo_user_data_key_t *)image,
- (void *)snapshot.get(), destroyCachedCairoSurface);
- } else {
+ cairo_surface_set_user_data(image, (const cairo_user_data_key_t *)image, (void *)snapshot.get(), destroyCachedCairoSurface);
+ } else
snapshot = 0;
- // re-consider : this can be image-surface for oversized buffer.
- }
}
if(snapshot)
image = clippedImageSurface.get();
}
+#if ENABLE(TIZEN_DRAW_SCALED_PATTERN)
+ // Images bigger than this in all directions will be scaled because width or height could be 0 by the ctm.
+ const int kImageSizeThreshold = 1;
+ // The value of repetitionX * repetitionY smaller than this is considered inefficient source and will not be replaced by scaled pattern.
+ // FIXME: Need to figure out the optimum value.
+ const float kRepetitionThreshold = 2;
+
+#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
+ int imageWidth, imageHeight;
+ if (cairo_surface_get_type(image) == CAIRO_SURFACE_TYPE_GL) {
+ imageWidth = cairo_gl_surface_get_width(image);
+ imageHeight = cairo_gl_surface_get_height(image);
+ } else {
+ imageWidth = cairo_image_surface_get_width(image);
+ imageHeight = cairo_image_surface_get_height(image);
+ }
+#else
+ int imageWidth = cairo_image_surface_get_width(image);
+ int imageHeight = cairo_image_surface_get_height(image);
+#endif
+ if (!imageWidth || !imageHeight)
+ return;
+
+ cairo_matrix_t ctm;
+ cairo_get_matrix(cr, &ctm);
+ cairo_matrix_t matrix = cairo_matrix_t(patternTransform);
+ cairo_matrix_t totalMatrix;
+ cairo_matrix_multiply(&totalMatrix, &ctm, &matrix);
+
+ double scaleX = ctm.xx ? ctm.xx : 1;
+ double scaleY = ctm.yy ? ctm.yy : 1;
+ int destBitmapWidth = imageWidth * totalMatrix.xx;
+ int destBitmapHeight = imageHeight * totalMatrix.yy;
+ float repetitionX = destRect.width() / destBitmapWidth;
+ float repetitionY = destRect.height() / destBitmapHeight;
+
+ bool shouldScalePattern = false;
+ if (scaleX != 1 && scaleY != 1 && totalMatrix.xx != 1 && totalMatrix.yy != 1 && destBitmapWidth && destBitmapHeight
+ && imageWidth > kImageSizeThreshold && imageHeight > kImageSizeThreshold && repetitionX * repetitionY > kRepetitionThreshold)
+ shouldScalePattern = true;
+
+ RefPtr<cairo_surface_t> scaledImageSurface = 0;
+ if (shouldScalePattern) {
+#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
+ if (cairo_surface_get_type(image) == CAIRO_SURFACE_TYPE_GL)
+ scaledImageSurface = adoptRef(cairo_surface_create_similar(image, CAIRO_CONTENT_COLOR_ALPHA, destBitmapWidth, destBitmapHeight));
+ else
+ scaledImageSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, destBitmapWidth, destBitmapHeight));
+#else
+ scaledImageSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, destBitmapWidth, destBitmapHeight));
+#endif
+ RefPtr<cairo_t> scaledImageContext = adoptRef(cairo_create(scaledImageSurface.get()));
+ cairo_set_operator(scaledImageContext.get(), CAIRO_OPERATOR_SOURCE);
+ cairo_scale(scaledImageContext.get(), totalMatrix.xx, totalMatrix.yy);
+ cairo_set_source_surface(scaledImageContext.get(), image, 0, 0);
+ cairo_paint(scaledImageContext.get());
+ image = scaledImageSurface.get();
+ }
+#endif
+
cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image);
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
+#if ENABLE(TIZEN_DRAW_SCALED_PATTERN)
+ cairo_matrix_t combined;
+ if (shouldScalePattern)
+ cairo_matrix_init(&combined, 1 / scaleX, 0, 0, 1 / scaleY, phase.x() + tileRect.x() * patternTransform.a(), phase.y() + tileRect.y() * patternTransform.d());
+ else {
+ cairo_matrix_t patternMatrix = cairo_matrix_t(patternTransform);
+ cairo_matrix_t phaseMatrix = {1, 0, 0, 1, phase.x() + tileRect.x() * patternTransform.a(), phase.y() + tileRect.y() * patternTransform.d()};
+ cairo_matrix_multiply(&combined, &patternMatrix, &phaseMatrix);
+ }
+#else
cairo_matrix_t patternMatrix = cairo_matrix_t(patternTransform);
cairo_matrix_t phaseMatrix = {1, 0, 0, 1, phase.x() + tileRect.x() * patternTransform.a(), phase.y() + tileRect.y() * patternTransform.d()};
cairo_matrix_t combined;
cairo_matrix_multiply(&combined, &patternMatrix, &phaseMatrix);
+#endif
cairo_matrix_invert(&combined);
#if ENABLE(TIZEN_ADJUST_PATTERN_MATRIX)
- adjustPatternMatrixForPixelAlign(cr, pattern, &combined, destRect.x(), destRect.y(), destRect.width(), destRect.height());
+#if ENABLE(TIZEN_DRAW_SCALED_PATTERN)
+ if (!shouldScalePattern)
+#endif
+ adjustPatternMatrixForPixelAlign(cr, pattern, &combined, destRect.x(), destRect.y(), destRect.width(), destRect.height());
#endif
cairo_pattern_set_matrix(pattern, &combined);
cairo_fill(cr);
#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
- if(clippedImageSurface && sourceImageSurface)
+ if (sourceImageSurface)
cairo_surface_unmap_image(original_image, sourceImageSurface.get());
#endif