Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1315)

Unified Diff: ui/gfx/image/image_skia_operations.cc

Issue 12730010: Fix rounding rules for skia operations to work with non-integer scaling factors. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Update sizes. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/canvas.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/image/image_skia_operations.cc
diff --git a/ui/gfx/image/image_skia_operations.cc b/ui/gfx/image/image_skia_operations.cc
index 4b5612ea063bc1376556b58dee5e03e80b9ffe23..67ea1bf79a00479ec3866ac7e7971957c24194a8 100644
--- a/ui/gfx/image/image_skia_operations.cc
+++ b/ui/gfx/image/image_skia_operations.cc
@@ -14,6 +14,8 @@
#include "ui/gfx/image/image_skia_rep.h"
#include "ui/gfx/image/image_skia_source.h"
#include "ui/gfx/insets.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/point_conversions.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/size.h"
@@ -24,6 +26,22 @@
namespace gfx {
namespace {
+gfx::Rect DIPToPixelBounds(gfx::Rect dip_bounds, float scale) {
+ return ToEnclosingRect(ScaleRect(dip_bounds, scale));
+}
+
+gfx::Size DIPToPixelSize(gfx::Size dip_size, float scale) {
+ return ToCeiledSize(ScaleSize(dip_size, scale));
+}
+
+ImageSkiaRep CropBitmap(ImageSkiaRep& source, gfx::Rect& bounds) {
pkotwicz 2013/03/13 04:03:48 Nit: Rename to CropImageSkiaRep Rename |bound
kevers 2013/03/13 14:36:59 Done.
+ SkBitmap result;
+ bool success = source.sk_bitmap().extractSubset(&result,
+ RectToSkIRect(bounds));
+ DCHECK(success);
+ return ImageSkiaRep(result, source.scale_factor());
+}
+
// Returns an image rep for the ImageSkiaSource to return to visually indicate
// an error.
ImageSkiaRep GetErrorImageRep(ui::ScaleFactor scale_factor,
@@ -54,7 +72,12 @@ class BinaryImageSource : public gfx::ImageSkiaSource {
virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE {
ImageSkiaRep first_rep = first_.GetRepresentation(scale_factor);
ImageSkiaRep second_rep = second_.GetRepresentation(scale_factor);
- if (first_rep.pixel_size() != second_rep.pixel_size()) {
+ gfx::Size first_size = first_rep.pixel_size();
+ gfx::Size second_size = second_rep.pixel_size();
+ // Allow for maximum of 1 pixel mismatch due to rounding errors.
pkotwicz 2013/03/13 04:03:48 Nit: "due to rounding errors because of a fraction
kevers 2013/03/13 14:36:59 Done.
+ int dw = first_size.width() - second_size.width();
+ int dh = first_size.height() - second_size.height();
+ if (abs(dw) > 1 || abs(dh) > 1) {
DCHECK_NE(first_rep.scale_factor(), second_rep.scale_factor());
if (first_rep.scale_factor() == second_rep.scale_factor()) {
LOG(ERROR) << "ImageSkiaRep size mismatch in " << source_name_;
@@ -63,9 +86,13 @@ class BinaryImageSource : public gfx::ImageSkiaSource {
}
first_rep = first_.GetRepresentation(ui::SCALE_FACTOR_100P);
second_rep = second_.GetRepresentation(ui::SCALE_FACTOR_100P);
- DCHECK_EQ(first_rep.pixel_width(), second_rep.pixel_width());
- DCHECK_EQ(first_rep.pixel_height(), second_rep.pixel_height());
- if (first_rep.pixel_size() != second_rep.pixel_size()) {
+ first_size = first_rep.pixel_size();
+ second_size = second_rep.pixel_size();
+ dw = first_size.width() - second_size.width();
+ dh = first_size.height() - second_size.height();
pkotwicz 2013/03/13 04:03:48 Use ImageSkiaRep::pixel_width() and ImageSkiaRep::
kevers 2013/03/13 14:36:59 Done.
+ DCHECK_LE(abs(dw), 1);
+ DCHECK_LE(abs(dh), 1);
+ if (abs(dw) > 1 || abs(dh) > 1) {
LOG(ERROR) << "ImageSkiaRep size mismatch in " << source_name_;
return GetErrorImageRep(first_rep.scale_factor(),
first_rep.pixel_size());
@@ -73,6 +100,11 @@ class BinaryImageSource : public gfx::ImageSkiaSource {
} else {
DCHECK_EQ(first_rep.scale_factor(), second_rep.scale_factor());
}
+ if (dw || dh) {
+ gfx::Rect bounds = IntersectRects(Rect(first_size), Rect(second_size));
+ first_rep = CropBitmap(first_rep, bounds);
+ second_rep = CropBitmap(second_rep, bounds);
+ }
return CreateImageSkiaRep(first_rep, second_rep);
}
@@ -216,10 +248,12 @@ class TiledImageSource : public gfx::ImageSkiaSource {
virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE {
ImageSkiaRep source_rep = source_.GetRepresentation(scale_factor);
float scale = ui::GetScaleFactorScale(source_rep.scale_factor());
+ gfx::Rect bounds = DIPToPixelBounds(gfx::Rect(src_x_, src_y_, dst_w_,
+ dst_h_), scale);
pkotwicz 2013/03/13 04:03:48 ToEnclosingRect() does something different than us
kevers 2013/03/13 14:36:59 The size resulting from using ToEnclosingRect is a
return ImageSkiaRep(
SkBitmapOperations::CreateTiledBitmap(
source_rep.sk_bitmap(),
- src_x_ * scale, src_y_ * scale, dst_w_ * scale, dst_h_ * scale),
+ bounds.x(), bounds.y(), bounds.width(), bounds.height()),
source_rep.scale_factor());
}
@@ -260,37 +294,30 @@ class HSLImageSource : public gfx::ImageSkiaSource {
// ImageSkiaSource which uses SkBitmapOperations::CreateButtonBackground
// to generate image reps for the target image.
-class ButtonImageSource: public gfx::ImageSkiaSource {
+class ButtonImageSource: public BinaryImageSource {
public:
ButtonImageSource(SkColor color,
const ImageSkia& image,
const ImageSkia& mask)
- : color_(color),
- image_(image),
- mask_(mask) {
+ : BinaryImageSource(image, mask, "ButtonImageSource"),
+ color_(color) {
}
virtual ~ButtonImageSource() {
}
- // gfx::ImageSkiaSource overrides:
- virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE {
- ImageSkiaRep image_rep = image_.GetRepresentation(scale_factor);
- ImageSkiaRep mask_rep = mask_.GetRepresentation(scale_factor);
- if (image_rep.scale_factor() != mask_rep.scale_factor()) {
- image_rep = image_.GetRepresentation(ui::SCALE_FACTOR_100P);
- mask_rep = mask_.GetRepresentation(ui::SCALE_FACTOR_100P);
- }
+ // BinaryImageSource overrides:
+ virtual ImageSkiaRep CreateImageSkiaRep(
+ const ImageSkiaRep& first_rep,
+ const ImageSkiaRep& second_rep) const OVERRIDE {
return gfx::ImageSkiaRep(
SkBitmapOperations::CreateButtonBackground(color_,
- image_rep.sk_bitmap(), mask_rep.sk_bitmap()),
- image_rep.scale_factor());
+ first_rep.sk_bitmap(), second_rep.sk_bitmap()),
+ first_rep.scale_factor());
}
private:
const SkColor color_;
- const ImageSkia image_;
- const ImageSkia mask_;
DISALLOW_COPY_AND_ASSIGN(ButtonImageSource);
};
@@ -312,13 +339,9 @@ class ExtractSubsetImageSource: public gfx::ImageSkiaSource {
virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE {
ImageSkiaRep image_rep = image_.GetRepresentation(scale_factor);
float scale_to_pixel = ui::GetScaleFactorScale(image_rep.scale_factor());
- SkIRect subset_bounds_in_pixel = RectToSkIRect(ToFlooredRectDeprecated(
- gfx::ScaleRect(subset_bounds_, scale_to_pixel)));
- SkBitmap dst;
- bool success = image_rep.sk_bitmap().extractSubset(&dst,
- subset_bounds_in_pixel);
- DCHECK(success);
- return gfx::ImageSkiaRep(dst, image_rep.scale_factor());
+ Rect subset_bounds_in_pixel = DIPToPixelBounds(subset_bounds_,
+ scale_to_pixel);
+ return CropBitmap(image_rep, subset_bounds_in_pixel);
}
private:
@@ -349,8 +372,7 @@ class ResizeSource : public ImageSkiaSource {
return image_rep;
const float scale = ui::GetScaleFactorScale(scale_factor);
- const Size target_pixel_size = gfx::ToFlooredSize(
- gfx::ScaleSize(target_dip_size_, scale));
+ const Size target_pixel_size = DIPToPixelSize(target_dip_size_, scale);
const SkBitmap resized = skia::ImageOperations::Resize(
image_rep.sk_bitmap(),
resize_method_,
« no previous file with comments | « ui/gfx/canvas.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698