OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "gfx/canvas.h" | 5 #include "gfx/canvas.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/i18n/rtl.h" | 9 #include "base/i18n/rtl.h" |
10 #include "gfx/font.h" | 10 #include "gfx/font.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 | 35 |
36 // Compute the windows flags necessary to implement the provided text Canvas | 36 // Compute the windows flags necessary to implement the provided text Canvas |
37 // flags. | 37 // flags. |
38 int ComputeFormatFlags(int flags, const std::wstring& text) { | 38 int ComputeFormatFlags(int flags, const std::wstring& text) { |
39 // Setting the text alignment explicitly in case it hasn't already been set. | 39 // Setting the text alignment explicitly in case it hasn't already been set. |
40 // This will make sure that we don't align text to the left on RTL locales | 40 // This will make sure that we don't align text to the left on RTL locales |
41 // just because no alignment flag was passed to DrawStringInt(). | 41 // just because no alignment flag was passed to DrawStringInt(). |
42 if (!(flags & (gfx::Canvas::TEXT_ALIGN_CENTER | | 42 if (!(flags & (gfx::Canvas::TEXT_ALIGN_CENTER | |
43 gfx::Canvas::TEXT_ALIGN_RIGHT | | 43 gfx::Canvas::TEXT_ALIGN_RIGHT | |
44 gfx::Canvas::TEXT_ALIGN_LEFT))) { | 44 gfx::Canvas::TEXT_ALIGN_LEFT))) { |
45 flags |= gfx::Canvas::DefaultCanvasTextAlignment(); | 45 flags |= gfx::CanvasSkia::DefaultCanvasTextAlignment(); |
46 } | 46 } |
47 | 47 |
48 // horizontal alignment | 48 // horizontal alignment |
49 int f = 0; | 49 int f = 0; |
50 if (flags & gfx::Canvas::TEXT_ALIGN_CENTER) | 50 if (flags & gfx::Canvas::TEXT_ALIGN_CENTER) |
51 f |= DT_CENTER; | 51 f |= DT_CENTER; |
52 else if (flags & gfx::Canvas::TEXT_ALIGN_RIGHT) | 52 else if (flags & gfx::Canvas::TEXT_ALIGN_RIGHT) |
53 f |= DT_RIGHT; | 53 f |= DT_RIGHT; |
54 else | 54 else |
55 f |= DT_LEFT; | 55 f |= DT_LEFT; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 f |= DT_RTLREADING; | 118 f |= DT_RTLREADING; |
119 } | 119 } |
120 | 120 |
121 return f; | 121 return f; |
122 } | 122 } |
123 | 123 |
124 } // anonymous namespace | 124 } // anonymous namespace |
125 | 125 |
126 namespace gfx { | 126 namespace gfx { |
127 | 127 |
128 Canvas::Canvas(int width, int height, bool is_opaque) | 128 CanvasSkia::CanvasSkia(int width, int height, bool is_opaque) |
129 : skia::PlatformCanvas(width, height, is_opaque) { | 129 : skia::PlatformCanvas(width, height, is_opaque) { |
130 } | 130 } |
131 | 131 |
132 Canvas::Canvas() : skia::PlatformCanvas() { | 132 CanvasSkia::CanvasSkia() : skia::PlatformCanvas() { |
133 } | 133 } |
134 | 134 |
135 Canvas::~Canvas() { | 135 CanvasSkia::~CanvasSkia() { |
136 } | 136 } |
137 | 137 |
138 // static | 138 // static |
139 void Canvas::SizeStringInt(const std::wstring& text, | 139 void CanvasSkia::SizeStringInt(const std::wstring& text, |
140 const gfx::Font& font, | 140 const gfx::Font& font, |
141 int* width, int* height, int flags) { | 141 int* width, int* height, int flags) { |
142 // Clamp the max amount of text we'll measure to 2K. When the string is | 142 // Clamp the max amount of text we'll measure to 2K. When the string is |
143 // actually drawn, it will be clipped to whatever size box is provided, and | 143 // actually drawn, it will be clipped to whatever size box is provided, and |
144 // the time to do that doesn't depend on the length being clipped off. | 144 // the time to do that doesn't depend on the length being clipped off. |
145 const int kMaxStringLength = 2048 - 1; // So the trailing \0 fits in 2K. | 145 const int kMaxStringLength = 2048 - 1; // So the trailing \0 fits in 2K. |
146 std::wstring clamped_string(text.substr(0, kMaxStringLength)); | 146 std::wstring clamped_string(text.substr(0, kMaxStringLength)); |
147 | 147 |
148 if (*width == 0) { | 148 if (*width == 0) { |
149 // If multi-line + character break are on, the computed width will be one | 149 // If multi-line + character break are on, the computed width will be one |
150 // character wide (useless). Furthermore, if in this case the provided text | 150 // character wide (useless). Furthermore, if in this case the provided text |
151 // contains very long "words" (substrings without a word-breaking point), | 151 // contains very long "words" (substrings without a word-breaking point), |
(...skipping 14 matching lines...) Expand all Loading... |
166 HFONT old_font = static_cast<HFONT>(SelectObject(dc, font.hfont())); | 166 HFONT old_font = static_cast<HFONT>(SelectObject(dc, font.hfont())); |
167 DoDrawText(dc, clamped_string, &r, | 167 DoDrawText(dc, clamped_string, &r, |
168 ComputeFormatFlags(flags, clamped_string) | DT_CALCRECT); | 168 ComputeFormatFlags(flags, clamped_string) | DT_CALCRECT); |
169 SelectObject(dc, old_font); | 169 SelectObject(dc, old_font); |
170 ReleaseDC(NULL, dc); | 170 ReleaseDC(NULL, dc); |
171 | 171 |
172 *width = r.right; | 172 *width = r.right; |
173 *height = r.bottom; | 173 *height = r.bottom; |
174 } | 174 } |
175 | 175 |
176 void Canvas::DrawStringInt(const std::wstring& text, HFONT font, | 176 void CanvasSkia::DrawStringInt(const std::wstring& text, HFONT font, |
177 const SkColor& color, int x, int y, int w, int h, | 177 const SkColor& color, int x, int y, int w, int h, |
178 int flags) { | 178 int flags) { |
179 if (!IntersectsClipRectInt(x, y, w, h)) | 179 if (!IntersectsClipRectInt(x, y, w, h)) |
180 return; | 180 return; |
181 | 181 |
182 // Clamp the max amount of text we'll draw to 32K. There seem to be bugs in | 182 // Clamp the max amount of text we'll draw to 32K. There seem to be bugs in |
183 // DrawText() if you e.g. ask it to character-break a no-whitespace string of | 183 // DrawText() if you e.g. ask it to character-break a no-whitespace string of |
184 // length > 43680 (for which it draws nothing), and since we clamped to 2K in | 184 // length > 43680 (for which it draws nothing), and since we clamped to 2K in |
185 // SizeStringInt() we're unlikely to be able to display this much anyway. | 185 // SizeStringInt() we're unlikely to be able to display this much anyway. |
186 const int kMaxStringLength = 32768 - 1; // So the trailing \0 fits in 32K. | 186 const int kMaxStringLength = 32768 - 1; // So the trailing \0 fits in 32K. |
187 std::wstring clamped_string(text.substr(0, kMaxStringLength)); | 187 std::wstring clamped_string(text.substr(0, kMaxStringLength)); |
188 | 188 |
(...skipping 12 matching lines...) Expand all Loading... |
201 // Restore the old font. This way we don't have to worry if the caller | 201 // Restore the old font. This way we don't have to worry if the caller |
202 // deletes the font and the DC lives longer. | 202 // deletes the font and the DC lives longer. |
203 SelectObject(dc, old_font); | 203 SelectObject(dc, old_font); |
204 | 204 |
205 // Windows will have cleared the alpha channel of the text we drew. Assume | 205 // Windows will have cleared the alpha channel of the text we drew. Assume |
206 // we're drawing to an opaque surface, or at least the text rect area is | 206 // we're drawing to an opaque surface, or at least the text rect area is |
207 // opaque. | 207 // opaque. |
208 getTopPlatformDevice().makeOpaque(x, y, w, h); | 208 getTopPlatformDevice().makeOpaque(x, y, w, h); |
209 } | 209 } |
210 | 210 |
211 void Canvas::DrawStringInt(const std::wstring& text, | 211 void CanvasSkia::DrawStringInt(const std::wstring& text, |
212 const gfx::Font& font, | 212 const gfx::Font& font, |
213 const SkColor& color, | 213 const SkColor& color, |
214 int x, int y, int w, int h, int flags) { | 214 int x, int y, int w, int h, int flags) { |
215 DrawStringInt(text, font.hfont(), color, x, y, w, h, flags); | 215 DrawStringInt(text, font.hfont(), color, x, y, w, h, flags); |
216 } | 216 } |
217 | 217 |
218 // Checks each pixel immediately adjacent to the given pixel in the bitmap. If | 218 // Checks each pixel immediately adjacent to the given pixel in the bitmap. If |
219 // any of them are not the halo color, returns true. This defines the halo of | 219 // any of them are not the halo color, returns true. This defines the halo of |
220 // pixels that will appear around the text. Note that we have to check each | 220 // pixels that will appear around the text. Note that we have to check each |
221 // pixel against both the halo color and transparent since DrawStringWithHalo | 221 // pixel against both the halo color and transparent since DrawStringWithHalo |
222 // will modify the bitmap as it goes, and clears pixels shouldn't count as | 222 // will modify the bitmap as it goes, and clears pixels shouldn't count as |
223 // changed. | 223 // changed. |
224 static bool pixelShouldGetHalo(const SkBitmap& bitmap, int x, int y, | 224 static bool pixelShouldGetHalo(const SkBitmap& bitmap, int x, int y, |
(...skipping 10 matching lines...) Expand all Loading... |
235 *bitmap.getAddr32(x, y - 1) != halo_color && | 235 *bitmap.getAddr32(x, y - 1) != halo_color && |
236 *bitmap.getAddr32(x, y - 1) != 0) | 236 *bitmap.getAddr32(x, y - 1) != 0) |
237 return true; // Touched pixel above. | 237 return true; // Touched pixel above. |
238 if (y < bitmap.height() - 1 && | 238 if (y < bitmap.height() - 1 && |
239 *bitmap.getAddr32(x, y + 1) != halo_color && | 239 *bitmap.getAddr32(x, y + 1) != halo_color && |
240 *bitmap.getAddr32(x, y + 1) != 0) | 240 *bitmap.getAddr32(x, y + 1) != 0) |
241 return true; // Touched pixel below. | 241 return true; // Touched pixel below. |
242 return false; | 242 return false; |
243 } | 243 } |
244 | 244 |
245 void Canvas::DrawStringWithHalo(const std::wstring& text, | 245 void CanvasSkia::DrawStringWithHalo(const std::wstring& text, |
246 const gfx::Font& font, | 246 const gfx::Font& font, |
247 const SkColor& text_color, | 247 const SkColor& text_color, |
248 const SkColor& halo_color_in, | 248 const SkColor& halo_color_in, |
249 int x, int y, int w, int h, | 249 int x, int y, int w, int h, |
250 int flags) { | 250 int flags) { |
251 // Some callers will have semitransparent halo colors, which we don't handle | 251 // Some callers will have semitransparent halo colors, which we don't handle |
252 // (since the resulting image can have 1-bit transparency only). | 252 // (since the resulting image can have 1-bit transparency only). |
253 SkColor halo_color = halo_color_in | 0xFF000000; | 253 SkColor halo_color = halo_color_in | 0xFF000000; |
254 | 254 |
255 // Create a temporary buffer filled with the halo color. It must leave room | 255 // Create a temporary buffer filled with the halo color. It must leave room |
256 // for the 1-pixel border around the text. | 256 // for the 1-pixel border around the text. |
257 Canvas text_canvas(w + 2, h + 2, true); | 257 CanvasSkia text_canvas(w + 2, h + 2, true); |
258 SkPaint bkgnd_paint; | 258 SkPaint bkgnd_paint; |
259 bkgnd_paint.setColor(halo_color); | 259 bkgnd_paint.setColor(halo_color); |
260 text_canvas.FillRectInt(0, 0, w + 2, h + 2, bkgnd_paint); | 260 text_canvas.FillRectInt(0, 0, w + 2, h + 2, bkgnd_paint); |
261 | 261 |
262 // Draw the text into the temporary buffer. This will have correct | 262 // Draw the text into the temporary buffer. This will have correct |
263 // ClearType since the background color is the same as the halo color. | 263 // ClearType since the background color is the same as the halo color. |
264 text_canvas.DrawStringInt(text, font, text_color, 1, 1, w, h, flags); | 264 text_canvas.DrawStringInt(text, font, text_color, 1, 1, w, h, flags); |
265 | 265 |
266 // Windows will have cleared the alpha channel for the pixels it drew. Make it | 266 // Windows will have cleared the alpha channel for the pixels it drew. Make it |
267 // opaque. We have to do this first since pixelShouldGetHalo will check for | 267 // opaque. We have to do this first since pixelShouldGetHalo will check for |
(...skipping 16 matching lines...) Expand all Loading... |
284 text_row[cur_x] |= 0xff << SK_A32_SHIFT; // Make opaque. | 284 text_row[cur_x] |= 0xff << SK_A32_SHIFT; // Make opaque. |
285 } | 285 } |
286 } | 286 } |
287 } | 287 } |
288 | 288 |
289 // Draw the halo bitmap with blur. | 289 // Draw the halo bitmap with blur. |
290 drawBitmap(text_bitmap, SkIntToScalar(x - 1), SkIntToScalar(y - 1)); | 290 drawBitmap(text_bitmap, SkIntToScalar(x - 1), SkIntToScalar(y - 1)); |
291 } | 291 } |
292 | 292 |
293 } // namespace gfx | 293 } // namespace gfx |
OLD | NEW |