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

Side by Side Diff: ui/gfx/skbitmap_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: 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/skbitmap_operations.h" 5 #include "ui/gfx/skbitmap_operations.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string.h> 8 #include <string.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 canvas.drawBitmapRect(second, NULL, rect); 74 canvas.drawBitmapRect(second, NULL, rect);
75 75
76 return superimposed; 76 return superimposed;
77 } 77 }
78 78
79 // static 79 // static
80 SkBitmap SkBitmapOperations::CreateBlendedBitmap(const SkBitmap& first, 80 SkBitmap SkBitmapOperations::CreateBlendedBitmap(const SkBitmap& first,
81 const SkBitmap& second, 81 const SkBitmap& second,
82 double alpha) { 82 double alpha) {
83 DCHECK((alpha >= 0) && (alpha <= 1)); 83 DCHECK((alpha >= 0) && (alpha <= 1));
84 DCHECK(first.width() == second.width()); 84 // Allow for a 1 pixel mismatch in height or width, which may result from
pkotwicz 2013/03/12 15:54:37 I would rather that you did the clipping before ca
kevers 2013/03/12 22:02:25 Done.
85 DCHECK(first.height() == second.height()); 85 // rounding errors when working with fractional scale factors.
86 DCHECK(abs(first.width() - second.width()) <= 1);
87 DCHECK(abs(first.height() - second.height()) <= 1);
86 DCHECK(first.bytesPerPixel() == second.bytesPerPixel()); 88 DCHECK(first.bytesPerPixel() == second.bytesPerPixel());
87 DCHECK(first.config() == SkBitmap::kARGB_8888_Config); 89 DCHECK(first.config() == SkBitmap::kARGB_8888_Config);
88 90
89 // Optimize for case where we won't need to blend anything. 91 // Optimize for case where we won't need to blend anything.
90 static const double alpha_min = 1.0 / 255; 92 static const double alpha_min = 1.0 / 255;
91 static const double alpha_max = 254.0 / 255; 93 static const double alpha_max = 254.0 / 255;
92 if (alpha < alpha_min) 94 if (alpha < alpha_min)
93 return first; 95 return first;
94 else if (alpha > alpha_max) 96 else if (alpha > alpha_max)
95 return second; 97 return second;
96 98
97 SkAutoLockPixels lock_first(first); 99 SkAutoLockPixels lock_first(first);
98 SkAutoLockPixels lock_second(second); 100 SkAutoLockPixels lock_second(second);
99 101
102 int width = std::min(first.width(), second.width());
103 int height = std::min(first.height(), second.height());
104
100 SkBitmap blended; 105 SkBitmap blended;
101 blended.setConfig(SkBitmap::kARGB_8888_Config, first.width(), first.height(), 106 blended.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0);
102 0);
103 blended.allocPixels(); 107 blended.allocPixels();
104 blended.eraseARGB(0, 0, 0, 0); 108 blended.eraseARGB(0, 0, 0, 0);
105 109
106 double first_alpha = 1 - alpha; 110 double first_alpha = 1 - alpha;
107 111
108 for (int y = 0; y < first.height(); ++y) { 112 for (int y = 0; y < height; ++y) {
109 uint32* first_row = first.getAddr32(0, y); 113 uint32* first_row = first.getAddr32(0, y);
110 uint32* second_row = second.getAddr32(0, y); 114 uint32* second_row = second.getAddr32(0, y);
111 uint32* dst_row = blended.getAddr32(0, y); 115 uint32* dst_row = blended.getAddr32(0, y);
112 116
113 for (int x = 0; x < first.width(); ++x) { 117 for (int x = 0; x < width; ++x) {
114 uint32 first_pixel = first_row[x]; 118 uint32 first_pixel = first_row[x];
115 uint32 second_pixel = second_row[x]; 119 uint32 second_pixel = second_row[x];
116 120
117 int a = static_cast<int>((SkColorGetA(first_pixel) * first_alpha) + 121 int a = static_cast<int>((SkColorGetA(first_pixel) * first_alpha) +
118 (SkColorGetA(second_pixel) * alpha)); 122 (SkColorGetA(second_pixel) * alpha));
119 int r = static_cast<int>((SkColorGetR(first_pixel) * first_alpha) + 123 int r = static_cast<int>((SkColorGetR(first_pixel) * first_alpha) +
120 (SkColorGetR(second_pixel) * alpha)); 124 (SkColorGetR(second_pixel) * alpha));
121 int g = static_cast<int>((SkColorGetG(first_pixel) * first_alpha) + 125 int g = static_cast<int>((SkColorGetG(first_pixel) * first_alpha) +
122 (SkColorGetG(second_pixel) * alpha)); 126 (SkColorGetG(second_pixel) * alpha));
123 int b = static_cast<int>((SkColorGetB(first_pixel) * first_alpha) + 127 int b = static_cast<int>((SkColorGetB(first_pixel) * first_alpha) +
124 (SkColorGetB(second_pixel) * alpha)); 128 (SkColorGetB(second_pixel) * alpha));
125 129
126 dst_row[x] = SkColorSetARGB(a, r, g, b); 130 dst_row[x] = SkColorSetARGB(a, r, g, b);
127 } 131 }
128 } 132 }
129 133
130 return blended; 134 return blended;
131 } 135 }
132 136
133 // static 137 // static
134 SkBitmap SkBitmapOperations::CreateMaskedBitmap(const SkBitmap& rgb, 138 SkBitmap SkBitmapOperations::CreateMaskedBitmap(const SkBitmap& rgb,
135 const SkBitmap& alpha) { 139 const SkBitmap& alpha) {
136 DCHECK(rgb.width() == alpha.width()); 140 // Allow for a 1 pixel mismatch in height or width, which may result from
137 DCHECK(rgb.height() == alpha.height()); 141 // rounding errors when working with fractional scale factors.
142 DCHECK(abs(rgb.width() - alpha.width()) <= 1);
143 DCHECK(abs(rgb.height() - alpha.height()) <= 1);
138 DCHECK(rgb.bytesPerPixel() == alpha.bytesPerPixel()); 144 DCHECK(rgb.bytesPerPixel() == alpha.bytesPerPixel());
139 DCHECK(rgb.config() == SkBitmap::kARGB_8888_Config); 145 DCHECK(rgb.config() == SkBitmap::kARGB_8888_Config);
140 DCHECK(alpha.config() == SkBitmap::kARGB_8888_Config); 146 DCHECK(alpha.config() == SkBitmap::kARGB_8888_Config);
141 147
142 SkBitmap masked; 148 SkBitmap masked;
143 masked.setConfig(SkBitmap::kARGB_8888_Config, rgb.width(), rgb.height(), 0); 149 masked.setConfig(SkBitmap::kARGB_8888_Config, rgb.width(), rgb.height(), 0);
144 masked.allocPixels(); 150 masked.allocPixels();
145 masked.eraseARGB(0, 0, 0, 0); 151 masked.eraseARGB(0, 0, 0, 0);
146 152
147 SkAutoLockPixels lock_rgb(rgb); 153 SkAutoLockPixels lock_rgb(rgb);
148 SkAutoLockPixels lock_alpha(alpha); 154 SkAutoLockPixels lock_alpha(alpha);
149 SkAutoLockPixels lock_masked(masked); 155 SkAutoLockPixels lock_masked(masked);
150 156
151 for (int y = 0; y < masked.height(); ++y) { 157 int height = std::min(rgb.height(), masked.height());
158 int width = std::min(rgb.width(), masked.width());
159
160 for (int y = 0; y < height; ++y) {
152 uint32* rgb_row = rgb.getAddr32(0, y); 161 uint32* rgb_row = rgb.getAddr32(0, y);
153 uint32* alpha_row = alpha.getAddr32(0, y); 162 uint32* alpha_row = alpha.getAddr32(0, y);
154 uint32* dst_row = masked.getAddr32(0, y); 163 uint32* dst_row = masked.getAddr32(0, y);
155 164
156 for (int x = 0; x < masked.width(); ++x) { 165 for (int x = 0; x < width; ++x) {
157 SkColor rgb_pixel = SkUnPreMultiply::PMColorToColor(rgb_row[x]); 166 SkColor rgb_pixel = SkUnPreMultiply::PMColorToColor(rgb_row[x]);
158 SkColor alpha_pixel = SkUnPreMultiply::PMColorToColor(alpha_row[x]); 167 SkColor alpha_pixel = SkUnPreMultiply::PMColorToColor(alpha_row[x]);
159 int alpha = SkAlphaMul(SkColorGetA(rgb_pixel), 168 int alpha = SkAlphaMul(SkColorGetA(rgb_pixel),
160 SkAlpha255To256(SkColorGetA(alpha_pixel))); 169 SkAlpha255To256(SkColorGetA(alpha_pixel)));
161 int alpha_256 = SkAlpha255To256(alpha); 170 int alpha_256 = SkAlpha255To256(alpha);
162 dst_row[x] = SkColorSetARGB(alpha, 171 dst_row[x] = SkColorSetARGB(alpha,
163 SkAlphaMul(SkColorGetR(rgb_pixel), alpha_256), 172 SkAlphaMul(SkColorGetR(rgb_pixel), alpha_256),
164 SkAlphaMul(SkColorGetG(rgb_pixel), alpha_256), 173 SkAlphaMul(SkColorGetG(rgb_pixel), alpha_256),
165 SkAlphaMul(SkColorGetB(rgb_pixel), 174 SkAlphaMul(SkColorGetB(rgb_pixel),
166 alpha_256)); 175 alpha_256));
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 canvas.translate(SkFloatToScalar(result.width() * 0.5f), 851 canvas.translate(SkFloatToScalar(result.width() * 0.5f),
843 SkFloatToScalar(result.height() * 0.5f)); 852 SkFloatToScalar(result.height() * 0.5f));
844 canvas.rotate(angle); 853 canvas.rotate(angle);
845 canvas.translate(-SkFloatToScalar(source.width() * 0.5f), 854 canvas.translate(-SkFloatToScalar(source.width() * 0.5f),
846 -SkFloatToScalar(source.height() * 0.5f)); 855 -SkFloatToScalar(source.height() * 0.5f));
847 canvas.drawBitmap(source, 0, 0); 856 canvas.drawBitmap(source, 0, 0);
848 canvas.flush(); 857 canvas.flush();
849 858
850 return result; 859 return result;
851 } 860 }
OLDNEW
« ui/gfx/image/image_skia_operations.cc ('K') | « ui/gfx/image/image_skia_operations.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698