summaryrefslogtreecommitdiffstats
path: root/chrome/common
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-02 21:49:12 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-02 21:49:12 +0000
commitf00fa4d766ac76419a051345a496caecfbeddc78 (patch)
treeb742fc1bdaa6dfd815e3b8ad719789572bb23398 /chrome/common
parent50d7d7283db42b531a9df9c6f5a34b8526d4d5b0 (diff)
downloadchromium_src-f00fa4d766ac76419a051345a496caecfbeddc78.zip
chromium_src-f00fa4d766ac76419a051345a496caecfbeddc78.tar.gz
chromium_src-f00fa4d766ac76419a051345a496caecfbeddc78.tar.bz2
Fix bookmark and menu drag images by making a halo around them. This makes
the ClearType composited on the correct color to fix the semitransparent pixels into 1-bit transparency pixels. Remove some unnecessary header file dependencies on ChromeCanvas I noticed when compiling this patch. BUG=8258 Review URL: http://codereview.chromium.org/27321 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10732 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
-rw-r--r--chrome/common/gfx/chrome_canvas.h10
-rw-r--r--chrome/common/gfx/chrome_canvas_win.cc75
2 files changed, 85 insertions, 0 deletions
diff --git a/chrome/common/gfx/chrome_canvas.h b/chrome/common/gfx/chrome_canvas.h
index a78d85c..d6cf77f 100644
--- a/chrome/common/gfx/chrome_canvas.h
+++ b/chrome/common/gfx/chrome_canvas.h
@@ -147,6 +147,16 @@ class ChromeCanvas : public skia::PlatformCanvas {
const SkColor& color, int x, int y, int w, int h,
int flags);
+#ifdef OS_WIN // Only implemented on Windows for now.
+ // Draws text with a 1-pixel halo around it of the given color. It allows
+ // ClearType to be drawn to an otherwise transparenct bitmap for drag images.
+ // Drag images have only 1-bit of transparency, so we don't do any fancy
+ // blurring.
+ void DrawStringWithHalo(const std::wstring& text, const ChromeFont& font,
+ const SkColor& text_color, const SkColor& halo_color,
+ int x, int y, int w, int h, int flags);
+#endif
+
// Draws a dotted gray rectangle used for focus purposes.
void DrawFocusRect(int x, int y, int width, int height);
diff --git a/chrome/common/gfx/chrome_canvas_win.cc b/chrome/common/gfx/chrome_canvas_win.cc
index 5e40ceb..376db65 100644
--- a/chrome/common/gfx/chrome_canvas_win.cc
+++ b/chrome/common/gfx/chrome_canvas_win.cc
@@ -195,3 +195,78 @@ void ChromeCanvas::DrawStringInt(const std::wstring& text,
int x, int y, int w, int h, int flags) {
DrawStringInt(text, font.hfont(), color, x, y, w, h, flags);
}
+
+// Checks each pixel immediately adjacent to the given pixel in the bitmap. If
+// any of them are not the halo color, returns true. This defines the halo of
+// pixels that will appear around the text. Note that we have to check each
+// pixel against both the halo color and transparent since DrawStringWithHalo
+// will modify the bitmap as it goes, and clears pixels shouldn't count as
+// changed.
+static bool pixelShouldGetHalo(const SkBitmap& bitmap, int x, int y,
+ SkColor halo_color) {
+ if (x > 0 &&
+ *bitmap.getAddr32(x - 1, y) != halo_color &&
+ *bitmap.getAddr32(x - 1, y) != 0)
+ return true; // Touched pixel to the left.
+ if (x < bitmap.width() - 1 &&
+ *bitmap.getAddr32(x + 1, y) != halo_color &&
+ *bitmap.getAddr32(x + 1, y) != 0)
+ return true; // Touched pixel to the right.
+ if (y > 0 &&
+ *bitmap.getAddr32(x, y - 1) != halo_color &&
+ *bitmap.getAddr32(x, y - 1) != 0)
+ return true; // Touched pixel above.
+ if (y < bitmap.height() - 1 &&
+ *bitmap.getAddr32(x, y + 1) != halo_color &&
+ *bitmap.getAddr32(x, y + 1) != 0)
+ return true; // Touched pixel below.
+ return false;
+}
+
+void ChromeCanvas::DrawStringWithHalo(const std::wstring& text,
+ const ChromeFont& font,
+ const SkColor& text_color,
+ const SkColor& halo_color_in,
+ int x, int y, int w, int h,
+ int flags) {
+ // Some callers will have semitransparent halo colors, which we don't handle
+ // (since the resulting image can have 1-bit transparency only).
+ SkColor halo_color = halo_color_in | 0xFF000000;
+
+ // Create a temporary buffer filled with the halo color. It must leave room
+ // for the 1-pixel border around the text.
+ ChromeCanvas text_canvas(w + 2, h + 2, true);
+ SkPaint bkgnd_paint;
+ bkgnd_paint.setColor(halo_color);
+ text_canvas.FillRectInt(0, 0, w + 2, h + 2, bkgnd_paint);
+
+ // Draw the text into the temporary buffer. This will have correct
+ // ClearType since the background color is the same as the halo color.
+ text_canvas.DrawStringInt(text, font, text_color, 1, 1, w, h, flags);
+
+ // Windows will have cleared the alpha channel for the pixels it drew. Make it
+ // opaque. We have to do this first since pixelShouldGetHalo will check for
+ // 0 to see if a pixel has been modified to transparent, and black text that
+ // Windows draw will look transparent to it!
+ text_canvas.getTopPlatformDevice().makeOpaque(0, 0, w + 2, h + 2);
+
+ uint32_t halo_premul = SkPreMultiplyColor(halo_color);
+ SkBitmap& text_bitmap = const_cast<SkBitmap&>(
+ text_canvas.getTopPlatformDevice().accessBitmap(true));
+ for (int cur_y = 0; cur_y < h + 2; cur_y++) {
+ uint32_t* text_row = text_bitmap.getAddr32(0, cur_y);
+ for (int cur_x = 0; cur_x < w + 2; cur_x++) {
+ if (text_row[cur_x] == halo_premul) {
+ // This pixel was not touched by the text routines. See if it borders
+ // a touched pixel in any of the 4 directions (not diagonally).
+ if (!pixelShouldGetHalo(text_bitmap, cur_x, cur_y, halo_premul))
+ text_row[cur_x] = 0; // Make transparent.
+ } else {
+ text_row[cur_x] |= 0xff << SK_A32_SHIFT; // Make opaque.
+ }
+ }
+ }
+
+ // Draw the halo bitmap with blur.
+ drawBitmap(text_bitmap, SkIntToScalar(x - 1), SkIntToScalar(y - 1));
+}