Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |