diff options
author | sail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-02 23:03:07 +0000 |
---|---|---|
committer | sail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-02 23:03:07 +0000 |
commit | 267c03d478d9c83ef8c37999f3abb1cd822881ff (patch) | |
tree | 6286c650d0ec58cdee9c7482fda929252bd985b5 /gfx | |
parent | 7c085463177741a3844215675577bba3de1be836 (diff) | |
download | chromium_src-267c03d478d9c83ef8c37999f3abb1cd822881ff.zip chromium_src-267c03d478d9c83ef8c37999f3abb1cd822881ff.tar.gz chromium_src-267c03d478d9c83ef8c37999f3abb1cd822881ff.tar.bz2 |
Move src/gfx/ to src/ui/gfx
To reduce the size of this change I've left stub header files in src/gfx/. Once all includes have been updated I'll delete the stub files.
BUG=71063
TEST=Still doing test builds.
Review URL: http://codereview.chromium.org/6246027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73530 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gfx')
91 files changed, 73 insertions, 14525 deletions
@@ -2,4 +2,5 @@ include_rules = [ "+base", "+grit/gfx_resources.h", "+skia", + "+ui/gfx", ] diff --git a/gfx/blit.cc b/gfx/blit.cc deleted file mode 100644 index 8853339..0000000 --- a/gfx/blit.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/blit.h" - -#include "base/logging.h" -#include "build/build_config.h" -#include "gfx/point.h" -#include "gfx/rect.h" -#include "skia/ext/platform_canvas.h" -#include "skia/ext/platform_device.h" - -#if defined(OS_POSIX) && !defined(OS_MACOSX) -#include <cairo/cairo.h> -#endif - -#if defined(OS_MACOSX) -#include "base/mac/scoped_cftyperef.h" -#endif - -namespace gfx { - -namespace { - -// Returns true if the given canvas has any part of itself clipped out or -// any non-identity tranform. -bool HasClipOrTransform(const skia::PlatformCanvas& canvas) { - if (!canvas.getTotalMatrix().isIdentity()) - return true; - - const SkRegion& clip_region = canvas.getTotalClip(); - if (clip_region.isEmpty() || clip_region.isComplex()) - return true; - - // Now we know the clip is a regular rectangle, make sure it covers the - // entire canvas. - const SkBitmap& bitmap = canvas.getTopPlatformDevice().accessBitmap(false); - const SkIRect& clip_bounds = clip_region.getBounds(); - if (clip_bounds.fLeft != 0 || clip_bounds.fTop != 0 || - clip_bounds.fRight != bitmap.width() || - clip_bounds.fBottom != bitmap.height()) - return true; - - return false; -} - -} // namespace - -void BlitContextToContext(NativeDrawingContext dst_context, - const Rect& dst_rect, - NativeDrawingContext src_context, - const Point& src_origin) { -#if defined(OS_WIN) - BitBlt(dst_context, dst_rect.x(), dst_rect.y(), - dst_rect.width(), dst_rect.height(), - src_context, src_origin.x(), src_origin.y(), SRCCOPY); -#elif defined(OS_MACOSX) - // Only translations and/or vertical flips in the source context are - // supported; more complex source context transforms will be ignored. - - // If there is a translation on the source context, we need to account for - // it ourselves since CGBitmapContextCreateImage will bypass it. - Rect src_rect(src_origin, dst_rect.size()); - CGAffineTransform transform = CGContextGetCTM(src_context); - bool flipped = fabs(transform.d + 1) < 0.0001; - CGFloat delta_y = flipped ? CGBitmapContextGetHeight(src_context) - - transform.ty - : transform.ty; - src_rect.Offset(transform.tx, delta_y); - - base::mac::ScopedCFTypeRef<CGImageRef> - src_image(CGBitmapContextCreateImage(src_context)); - base::mac::ScopedCFTypeRef<CGImageRef> src_sub_image( - CGImageCreateWithImageInRect(src_image, src_rect.ToCGRect())); - CGContextDrawImage(dst_context, dst_rect.ToCGRect(), src_sub_image); -#else // Linux, BSD, others - // Only translations in the source context are supported; more complex - // source context transforms will be ignored. - cairo_save(dst_context); - double surface_x = src_origin.x(); - double surface_y = src_origin.y(); - cairo_user_to_device(src_context, &surface_x, &surface_y); - cairo_set_source_surface(dst_context, cairo_get_target(src_context), - dst_rect.x()-surface_x, dst_rect.y()-surface_y); - cairo_rectangle(dst_context, dst_rect.x(), dst_rect.y(), - dst_rect.width(), dst_rect.height()); - cairo_clip(dst_context); - cairo_paint(dst_context); - cairo_restore(dst_context); -#endif -} - -static NativeDrawingContext GetContextFromCanvas( - skia::PlatformCanvas *canvas) { - skia::PlatformDevice& device = canvas->getTopPlatformDevice(); -#if defined(OS_WIN) - return device.getBitmapDC(); -#elif defined(OS_MACOSX) - return device.GetBitmapContext(); -#else // Linux, BSD, others - return device.beginPlatformPaint(); -#endif -} - -void BlitContextToCanvas(skia::PlatformCanvas *dst_canvas, - const Rect& dst_rect, - NativeDrawingContext src_context, - const Point& src_origin) { - BlitContextToContext(GetContextFromCanvas(dst_canvas), dst_rect, - src_context, src_origin); -} - -void BlitCanvasToContext(NativeDrawingContext dst_context, - const Rect& dst_rect, - skia::PlatformCanvas *src_canvas, - const Point& src_origin) { - BlitContextToContext(dst_context, dst_rect, - GetContextFromCanvas(src_canvas), src_origin); -} - -void BlitCanvasToCanvas(skia::PlatformCanvas *dst_canvas, - const Rect& dst_rect, - skia::PlatformCanvas *src_canvas, - const Point& src_origin) { - BlitContextToContext(GetContextFromCanvas(dst_canvas), dst_rect, - GetContextFromCanvas(src_canvas), src_origin); -} - -#if defined(OS_WIN) - -void ScrollCanvas(skia::PlatformCanvas* canvas, - const gfx::Rect& clip, - const gfx::Point& amount) { - DCHECK(!HasClipOrTransform(*canvas)); // Don't support special stuff. - HDC hdc = canvas->beginPlatformPaint(); - - RECT damaged_rect; - RECT r = clip.ToRECT(); - ScrollDC(hdc, amount.x(), amount.y(), NULL, &r, NULL, &damaged_rect); - - canvas->endPlatformPaint(); -} - -#elif defined(OS_POSIX) -// Cairo has no nice scroll function so we do our own. On Mac it's possible to -// use platform scroll code, but it's complex so we just use the same path -// here. Either way it will be software-only, so it shouldn't matter much. - -void ScrollCanvas(skia::PlatformCanvas* canvas, - const gfx::Rect& in_clip, - const gfx::Point& amount) { - DCHECK(!HasClipOrTransform(*canvas)); // Don't support special stuff. - SkBitmap& bitmap = const_cast<SkBitmap&>( - canvas->getTopPlatformDevice().accessBitmap(true)); - SkAutoLockPixels lock(bitmap); - - // We expect all coords to be inside the canvas, so clip here. - gfx::Rect clip = in_clip.Intersect( - gfx::Rect(0, 0, bitmap.width(), bitmap.height())); - - // Compute the set of pixels we'll actually end up painting. - gfx::Rect dest_rect = clip; - dest_rect.Offset(amount); - dest_rect = dest_rect.Intersect(clip); - if (dest_rect.size() == gfx::Size()) - return; // Nothing to do. - - // Compute the source pixels that will map to the dest_rect - gfx::Rect src_rect = dest_rect; - src_rect.Offset(-amount.x(), -amount.y()); - - size_t row_bytes = dest_rect.width() * 4; - if (amount.y() > 0) { - // Data is moving down, copy from the bottom up. - for (int y = dest_rect.height() - 1; y >= 0; y--) { - memcpy(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y), - bitmap.getAddr32(src_rect.x(), src_rect.y() + y), - row_bytes); - } - } else if (amount.y() < 0) { - // Data is moving up, copy from the top down. - for (int y = 0; y < dest_rect.height(); y++) { - memcpy(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y), - bitmap.getAddr32(src_rect.x(), src_rect.y() + y), - row_bytes); - } - } else if (amount.x() != 0) { - // Horizontal-only scroll. We can do it in either top-to-bottom or bottom- - // to-top, but have to be careful about the order for copying each row. - // Fortunately, memmove already handles this for us. - for (int y = 0; y < dest_rect.height(); y++) { - memmove(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y), - bitmap.getAddr32(src_rect.x(), src_rect.y() + y), - row_bytes); - } - } -} - -#endif - -} // namespace gfx @@ -6,48 +6,7 @@ #define GFX_BLIT_H_ #pragma once -#include "gfx/native_widget_types.h" - -namespace skia { -class PlatformCanvas; -} // namespace skia - -namespace gfx { - -class Point; -class Rect; - -// Blits a rectangle from the source context into the destination context. -void BlitContextToContext(NativeDrawingContext dst_context, - const Rect& dst_rect, - NativeDrawingContext src_context, - const Point& src_origin); - -// Blits a rectangle from the source context into the destination canvas. -void BlitContextToCanvas(skia::PlatformCanvas *dst_canvas, - const Rect& dst_rect, - NativeDrawingContext src_context, - const Point& src_origin); - -// Blits a rectangle from the source canvas into the destination context. -void BlitCanvasToContext(NativeDrawingContext dst_context, - const Rect& dst_rect, - skia::PlatformCanvas *src_canvas, - const Point& src_origin); - -// Blits a rectangle from the source canvas into the destination canvas. -void BlitCanvasToCanvas(skia::PlatformCanvas *dst_canvas, - const Rect& dst_rect, - skia::PlatformCanvas *src_canvas, - const Point& src_origin); - -// Scrolls the given subset of the given canvas by the given amount. -// The canvas should not have a clip or a transform applied, since platforms -// may implement those operations differently. -void ScrollCanvas(skia::PlatformCanvas* canvas, - const Rect& clip, - const Point& amount); - -} // namespace gfx +#include "ui/gfx/blit.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_BLIT_H_ diff --git a/gfx/blit_unittest.cc b/gfx/blit_unittest.cc deleted file mode 100644 index cea3296..0000000 --- a/gfx/blit_unittest.cc +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/basictypes.h" -#include "gfx/blit.h" -#include "gfx/point.h" -#include "gfx/rect.h" -#include "skia/ext/platform_canvas.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -// Fills the given canvas with the values by duplicating the values into each -// color channel for the corresponding pixel. -// -// Example values = {{0x0, 0x01}, {0x12, 0xFF}} would give a canvas with: -// 0x00000000 0x01010101 -// 0x12121212 0xFFFFFFFF -template<int w, int h> -void SetToCanvas(skia::PlatformCanvas* canvas, uint8 values[h][w]) { - SkBitmap& bitmap = const_cast<SkBitmap&>( - canvas->getTopPlatformDevice().accessBitmap(true)); - SkAutoLockPixels lock(bitmap); - ASSERT_EQ(w, bitmap.width()); - ASSERT_EQ(h, bitmap.height()); - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - uint8 value = values[y][x]; - *bitmap.getAddr32(x, y) = - (value << 24) | (value << 16) | (value << 8) | value; - } - } -} - -// Checks each pixel in the given canvas and see if it is made up of the given -// values, where each value has been duplicated into each channel of the given -// bitmap (see SetToCanvas above). -template<int w, int h> -void VerifyCanvasValues(skia::PlatformCanvas* canvas, uint8 values[h][w]) { - SkBitmap& bitmap = const_cast<SkBitmap&>( - canvas->getTopPlatformDevice().accessBitmap(true)); - SkAutoLockPixels lock(bitmap); - ASSERT_EQ(w, bitmap.width()); - ASSERT_EQ(h, bitmap.height()); - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - uint8 value = values[y][x]; - uint32 expected = - (value << 24) | (value << 16) | (value << 8) | value; - ASSERT_EQ(expected, *bitmap.getAddr32(x, y)); - } - } -} - -} // namespace - -TEST(Blit, ScrollCanvas) { - static const int kCanvasWidth = 5; - static const int kCanvasHeight = 5; - skia::PlatformCanvas canvas(kCanvasWidth, kCanvasHeight, true); - uint8 initial_values[kCanvasHeight][kCanvasWidth] = { - { 0x00, 0x01, 0x02, 0x03, 0x04 }, - { 0x10, 0x11, 0x12, 0x13, 0x14 }, - { 0x20, 0x21, 0x22, 0x23, 0x24 }, - { 0x30, 0x31, 0x32, 0x33, 0x34 }, - { 0x40, 0x41, 0x42, 0x43, 0x44 }}; - SetToCanvas<5, 5>(&canvas, initial_values); - - // Sanity check on input. - VerifyCanvasValues<5, 5>(&canvas, initial_values); - - // Scroll none and make sure it's a NOP. - gfx::ScrollCanvas(&canvas, - gfx::Rect(0, 0, kCanvasWidth, kCanvasHeight), - gfx::Point(0, 0)); - VerifyCanvasValues<5, 5>(&canvas, initial_values); - - // Scroll the center 3 pixels up one. - gfx::Rect center_three(1, 1, 3, 3); - gfx::ScrollCanvas(&canvas, center_three, gfx::Point(0, -1)); - uint8 scroll_up_expected[kCanvasHeight][kCanvasWidth] = { - { 0x00, 0x01, 0x02, 0x03, 0x04 }, - { 0x10, 0x21, 0x22, 0x23, 0x14 }, - { 0x20, 0x31, 0x32, 0x33, 0x24 }, - { 0x30, 0x31, 0x32, 0x33, 0x34 }, - { 0x40, 0x41, 0x42, 0x43, 0x44 }}; - VerifyCanvasValues<5, 5>(&canvas, scroll_up_expected); - - // Reset and scroll the center 3 pixels down one. - SetToCanvas<5, 5>(&canvas, initial_values); - gfx::ScrollCanvas(&canvas, center_three, gfx::Point(0, 1)); - uint8 scroll_down_expected[kCanvasHeight][kCanvasWidth] = { - { 0x00, 0x01, 0x02, 0x03, 0x04 }, - { 0x10, 0x11, 0x12, 0x13, 0x14 }, - { 0x20, 0x11, 0x12, 0x13, 0x24 }, - { 0x30, 0x21, 0x22, 0x23, 0x34 }, - { 0x40, 0x41, 0x42, 0x43, 0x44 }}; - VerifyCanvasValues<5, 5>(&canvas, scroll_down_expected); - - // Reset and scroll the center 3 pixels right one. - SetToCanvas<5, 5>(&canvas, initial_values); - gfx::ScrollCanvas(&canvas, center_three, gfx::Point(1, 0)); - uint8 scroll_right_expected[kCanvasHeight][kCanvasWidth] = { - { 0x00, 0x01, 0x02, 0x03, 0x04 }, - { 0x10, 0x11, 0x11, 0x12, 0x14 }, - { 0x20, 0x21, 0x21, 0x22, 0x24 }, - { 0x30, 0x31, 0x31, 0x32, 0x34 }, - { 0x40, 0x41, 0x42, 0x43, 0x44 }}; - VerifyCanvasValues<5, 5>(&canvas, scroll_right_expected); - - // Reset and scroll the center 3 pixels left one. - SetToCanvas<5, 5>(&canvas, initial_values); - gfx::ScrollCanvas(&canvas, center_three, gfx::Point(-1, 0)); - uint8 scroll_left_expected[kCanvasHeight][kCanvasWidth] = { - { 0x00, 0x01, 0x02, 0x03, 0x04 }, - { 0x10, 0x12, 0x13, 0x13, 0x14 }, - { 0x20, 0x22, 0x23, 0x23, 0x24 }, - { 0x30, 0x32, 0x33, 0x33, 0x34 }, - { 0x40, 0x41, 0x42, 0x43, 0x44 }}; - VerifyCanvasValues<5, 5>(&canvas, scroll_left_expected); - - // Diagonal scroll. - SetToCanvas<5, 5>(&canvas, initial_values); - gfx::ScrollCanvas(&canvas, center_three, gfx::Point(2, 2)); - uint8 scroll_diagonal_expected[kCanvasHeight][kCanvasWidth] = { - { 0x00, 0x01, 0x02, 0x03, 0x04 }, - { 0x10, 0x11, 0x12, 0x13, 0x14 }, - { 0x20, 0x21, 0x22, 0x23, 0x24 }, - { 0x30, 0x31, 0x32, 0x11, 0x34 }, - { 0x40, 0x41, 0x42, 0x43, 0x44 }}; - VerifyCanvasValues<5, 5>(&canvas, scroll_diagonal_expected); -} diff --git a/gfx/brush.h b/gfx/brush.h index 125ee3c..de48204 100644 --- a/gfx/brush.h +++ b/gfx/brush.h @@ -6,19 +6,7 @@ #define GFX_BRUSH_H_ #pragma once -namespace gfx { - -// An object that encapsulates a platform native brush. -// Subclasses handle memory management of the underlying native brush. -class Brush { - public: - Brush() {} - virtual ~Brush() {} - - private: - DISALLOW_COPY_AND_ASSIGN(Brush); -}; - -} // namespace gfx +#include "ui/gfx/brush.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_BRUSH_H_ diff --git a/gfx/canvas.cc b/gfx/canvas.cc deleted file mode 100644 index 28e6a8a..0000000 --- a/gfx/canvas.cc +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/canvas.h" - -namespace gfx { - -CanvasSkia* Canvas::AsCanvasSkia() { - return NULL; -} - -const CanvasSkia* Canvas::AsCanvasSkia() const { - return NULL; -} - -} // namespace gfx; diff --git a/gfx/canvas.h b/gfx/canvas.h index 17a9586..62cc77e 100644 --- a/gfx/canvas.h +++ b/gfx/canvas.h @@ -6,233 +6,7 @@ #define GFX_CANVAS_H_ #pragma once -#include <string> - -#include "base/string16.h" -#include "gfx/native_widget_types.h" -// TODO(beng): remove this include when we no longer depend on SkTypes. -#include "skia/ext/platform_canvas.h" - -namespace gfx { - -class Brush; -class CanvasSkia; -class Font; -class Point; -class Rect; - -// TODO(beng): documentation. -class Canvas { - public: - // Specifies the alignment for text rendered with the DrawStringInt method. - enum { - TEXT_ALIGN_LEFT = 1, - TEXT_ALIGN_CENTER = 2, - TEXT_ALIGN_RIGHT = 4, - TEXT_VALIGN_TOP = 8, - TEXT_VALIGN_MIDDLE = 16, - TEXT_VALIGN_BOTTOM = 32, - - // Specifies the text consists of multiple lines. - MULTI_LINE = 64, - - // By default DrawStringInt does not process the prefix ('&') character - // specially. That is, the string "&foo" is rendered as "&foo". When - // rendering text from a resource that uses the prefix character for - // mnemonics, the prefix should be processed and can be rendered as an - // underline (SHOW_PREFIX), or not rendered at all (HIDE_PREFIX). - SHOW_PREFIX = 128, - HIDE_PREFIX = 256, - - // Prevent ellipsizing - NO_ELLIPSIS = 512, - - // Specifies if words can be split by new lines. - // This only works with MULTI_LINE. - CHARACTER_BREAK = 1024, - - // Instructs DrawStringInt() to render the text using RTL directionality. - // In most cases, passing this flag is not necessary because information - // about the text directionality is going to be embedded within the string - // in the form of special Unicode characters. However, we don't insert - // directionality characters into strings if the locale is LTR because some - // platforms (for example, an English Windows XP with no RTL fonts - // installed) don't support these characters. Thus, this flag should be - // used to render text using RTL directionality when the locale is LTR. - FORCE_RTL_DIRECTIONALITY = 2048, - }; - - virtual ~Canvas() {} - - // Creates an empty canvas. Must be initialized before it can be used. - static Canvas* CreateCanvas(); - - // Creates a canvas with the specified size. - static Canvas* CreateCanvas(int width, int height, bool is_opaque); - - // Saves a copy of the drawing state onto a stack, operating on this copy - // until a balanced call to Restore() is made. - virtual void Save() = 0; - - // As with Save(), except draws to a layer that is blended with the canvas - // at the specified alpha once Restore() is called. - // |layer_bounds| are the bounds of the layer relative to the current - // transform. - virtual void SaveLayerAlpha(uint8 alpha) = 0; - virtual void SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds) = 0; - - // Restores the drawing state after a call to Save*(). It is an error to - // call Restore() more times than Save*(). - virtual void Restore() = 0; - - // Wrapper function that takes integer arguments. - // Returns true if the clip is non-empty. - // See clipRect for specifics. - virtual bool ClipRectInt(int x, int y, int w, int h) = 0; - - // Wrapper function that takes integer arguments. - // See translate() for specifics. - virtual void TranslateInt(int x, int y) = 0; - - // Wrapper function that takes integer arguments. - // See scale() for specifics. - virtual void ScaleInt(int x, int y) = 0; - - // Fills the specified region with the specified color using a transfer - // mode of SkXfermode::kSrcOver_Mode. - virtual void FillRectInt(const SkColor& color, - int x, int y, int w, int h) = 0; - - // Fills the specified region with the specified color and mode - virtual void FillRectInt(const SkColor& color, - int x, int y, int w, int h, - SkXfermode::Mode mode) = 0; - - // Fills the specified region with the specified brush. - virtual void FillRectInt(const gfx::Brush* brush, - int x, int y, int w, int h) = 0; - - // Draws a single pixel rect in the specified region with the specified - // color, using a transfer mode of SkXfermode::kSrcOver_Mode. - // - // NOTE: if you need a single pixel line, use DrawLineInt. - virtual void DrawRectInt(const SkColor& color, - int x, int y, int w, int h) = 0; - - // Draws a single pixel rect in the specified region with the specified - // color and transfer mode. - // - // NOTE: if you need a single pixel line, use DrawLineInt. - virtual void DrawRectInt(const SkColor& color, - int x, int y, int w, int h, - SkXfermode::Mode mode) = 0; - - // Draws the given rectangle with the given paint's parameters. - virtual void DrawRectInt(int x, int y, int w, int h, - const SkPaint& paint) = 0; - - // Draws a single pixel line with the specified color. - virtual void DrawLineInt(const SkColor& color, - int x1, int y1, - int x2, int y2) = 0; - - // Draws a bitmap with the origin at the specified location. The upper left - // corner of the bitmap is rendered at the specified location. - virtual void DrawBitmapInt(const SkBitmap& bitmap, int x, int y) = 0; - - // Draws a bitmap with the origin at the specified location, using the - // specified paint. The upper left corner of the bitmap is rendered at the - // specified location. - virtual void DrawBitmapInt(const SkBitmap& bitmap, - int x, int y, - const SkPaint& paint) = 0; - - // Draws a portion of a bitmap in the specified location. The src parameters - // correspond to the region of the bitmap to draw in the region defined - // by the dest coordinates. - // - // If the width or height of the source differs from that of the destination, - // the bitmap will be scaled. When scaling down, it is highly recommended - // that you call buildMipMap(false) on your bitmap to ensure that it has - // a mipmap, which will result in much higher-quality output. Set |filter| - // to use filtering for bitmaps, otherwise the nearest-neighbor algorithm - // is used for resampling. - // - // An optional custom SkPaint can be provided. - virtual void DrawBitmapInt(const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, - bool filter) = 0; - virtual void DrawBitmapInt(const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, - bool filter, - const SkPaint& paint) = 0; - - // Draws text with the specified color, font and location. The text is - // aligned to the left, vertically centered, clipped to the region. If the - // text is too big, it is truncated and '...' is added to the end. - virtual void DrawStringInt(const string16& text, const - gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h) = 0; - virtual void DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - const gfx::Rect& display_rect) = 0; - - // Draws text with the specified color, font and location. The last argument - // specifies flags for how the text should be rendered. It can be one of - // TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT. - virtual void DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h, - int flags) = 0; - - // Draws a dotted gray rectangle used for focus purposes. - virtual void DrawFocusRect(int x, int y, int width, int height) = 0; - - // Tiles the image in the specified region. - virtual void TileImageInt(const SkBitmap& bitmap, - int x, int y, int w, int h) = 0; - virtual void TileImageInt(const SkBitmap& bitmap, - int src_x, int src_y, - int dest_x, int dest_y, int w, int h) = 0; - - // Returns a native drawing context for platform specific drawing routines to - // use. Must be balanced by a call to EndPlatformPaint(). - virtual gfx::NativeDrawingContext BeginPlatformPaint() = 0; - - // Signifies the end of platform drawing using the native drawing context - // returned by BeginPlatformPaint(). - virtual void EndPlatformPaint() = 0; - - // TODO(beng): remove this once we don't need to use any skia-specific methods - // through this interface. - // A quick and dirty way to obtain the underlying SkCanvas. - virtual CanvasSkia* AsCanvasSkia(); - virtual const CanvasSkia* AsCanvasSkia() const; -}; - -class CanvasPaint { - public: - virtual ~CanvasPaint() {} - - // Creates a canvas that paints to |view| when it is destroyed. The canvas is - // sized to the client area of |view|. - static CanvasPaint* CreateCanvasPaint(gfx::NativeView view); - - // Returns true if the canvas has an invalid rect that needs to be repainted. - virtual bool IsValid() const = 0; - - // Returns the rectangle that is invalid. - virtual gfx::Rect GetInvalidRect() const = 0; - - // Returns the underlying Canvas. - virtual Canvas* AsCanvas() = 0; -}; - -} // namespace gfx; +#include "ui/gfx/canvas.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_CANVAS_H_ diff --git a/gfx/canvas_direct2d.cc b/gfx/canvas_direct2d.cc deleted file mode 100644 index cba7b64..0000000 --- a/gfx/canvas_direct2d.cc +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/canvas_direct2d.h" - -#include "base/scoped_ptr.h" -#include "gfx/brush.h" -#include "gfx/rect.h" - -namespace { - -// Converts a SkColor to a ColorF. -D2D1_COLOR_F SkColorToColorF(SkColor color) { - return D2D1::ColorF(static_cast<float>(SkColorGetR(color)) / 0xFF, - static_cast<float>(SkColorGetG(color)) / 0xFF, - static_cast<float>(SkColorGetB(color)) / 0xFF, - static_cast<float>(SkColorGetA(color)) / 0xFF); -} - -D2D1_RECT_F RectToRectF(int x, int y, int w, int h) { - return D2D1::RectF(static_cast<float>(x), static_cast<float>(y), - static_cast<float>(x + w), static_cast<float>(y + h)); -} - -D2D1_RECT_F RectToRectF(const gfx::Rect& rect) { - return RectToRectF(rect.x(), rect.y(), rect.width(), rect.height()); -} - -D2D1_POINT_2F PointToPoint2F(int x, int y) { - return D2D1::Point2F(static_cast<float>(x), static_cast<float>(y)); -} - -D2D1_BITMAP_INTERPOLATION_MODE FilterToInterpolationMode(bool filter) { - return filter ? D2D1_BITMAP_INTERPOLATION_MODE_LINEAR - : D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR; -} - -// Creates a Direct2D bitmap object from the contents of a SkBitmap. The caller -// is responsible for releasing this object. -ID2D1Bitmap* CreateD2D1BitmapFromSkBitmap(ID2D1RenderTarget* render_target, - const SkBitmap& bitmap) { - ID2D1Bitmap* d2d1_bitmap = NULL; - HRESULT hr = render_target->CreateBitmap( - D2D1::SizeU(bitmap.width(), bitmap.height()), - NULL, - NULL, - D2D1::BitmapProperties( - D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, - D2D1_ALPHA_MODE_IGNORE)), - &d2d1_bitmap); - if (FAILED(hr)) - return NULL; - bitmap.lockPixels(); - d2d1_bitmap->CopyFromMemory(NULL, bitmap.getPixels(), bitmap.rowBytes()); - bitmap.unlockPixels(); - return d2d1_bitmap; -} - -// Creates a Direct2D bitmap brush from the contents of a SkBitmap. The caller -// is responsible for releasing this object. -ID2D1Brush* CreateD2D1BrushFromSkBitmap(ID2D1RenderTarget* render_target, - const SkBitmap& bitmap, - D2D1_EXTEND_MODE extend_mode_x, - D2D1_EXTEND_MODE extend_mode_y) { - ScopedComPtr<ID2D1Bitmap> d2d1_bitmap( - CreateD2D1BitmapFromSkBitmap(render_target, bitmap)); - - ID2D1BitmapBrush* brush = NULL; - render_target->CreateBitmapBrush( - d2d1_bitmap, - D2D1::BitmapBrushProperties(extend_mode_x, extend_mode_y), - D2D1::BrushProperties(), - &brush); - return brush; -} - -// A platform wrapper for a Direct2D brush that makes sure the underlying -// ID2D1Brush COM object is released when this object is destroyed. -class Direct2DBrush : public gfx::Brush { - public: - explicit Direct2DBrush(ID2D1Brush* brush) : brush_(brush) { - } - - ID2D1Brush* brush() const { return brush_.get(); } - - private: - ScopedComPtr<ID2D1Brush> brush_; - - DISALLOW_COPY_AND_ASSIGN(Direct2DBrush); -}; - - -} // namespace - -namespace gfx { - -// static -ID2D1Factory* CanvasDirect2D::d2d1_factory_ = NULL; - -//////////////////////////////////////////////////////////////////////////////// -// CanvasDirect2D, public: - -CanvasDirect2D::CanvasDirect2D(ID2D1RenderTarget* rt) : rt_(rt) { - // A RenderState entry is pushed onto the stack to track the clip count prior - // to any calls to Save*(). - state_.push(RenderState()); - rt_->BeginDraw(); -} - -CanvasDirect2D::~CanvasDirect2D() { - // Unwind any clips that were pushed outside of any Save*()/Restore() pairs. - int clip_count = state_.top().clip_count; - for (int i = 0; i < clip_count; ++i) - rt_->PopAxisAlignedClip(); - rt_->EndDraw(); -} - -// static -ID2D1Factory* CanvasDirect2D::GetD2D1Factory() { - if (!d2d1_factory_) - D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &d2d1_factory_); - return d2d1_factory_; -} - -//////////////////////////////////////////////////////////////////////////////// -// CanvasDirect2D, Canvas implementation: - -void CanvasDirect2D::Save() { - SaveInternal(NULL); -} - -void CanvasDirect2D::SaveLayerAlpha(uint8 alpha) { - SaveLayerAlpha(alpha, gfx::Rect()); -} - -void CanvasDirect2D::SaveLayerAlpha(uint8 alpha, - const gfx::Rect& layer_bounds) { - D2D1_RECT_F bounds = D2D1::InfiniteRect(); - if (!layer_bounds.IsEmpty()) - bounds = RectToRectF(layer_bounds); - ID2D1Layer* layer = NULL; - HRESULT hr = rt_->CreateLayer(NULL, &layer); - if (SUCCEEDED(hr)) { - rt_->PushLayer(D2D1::LayerParameters(bounds, - NULL, - D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, - D2D1::IdentityMatrix(), - static_cast<float>(alpha) / 0xFF, - NULL, - D2D1_LAYER_OPTIONS_NONE), - layer); - } - SaveInternal(layer); -} - -void CanvasDirect2D::Restore() { - ID2D1Layer* layer = state_.top().layer; - if (layer) { - rt_->PopLayer(); - layer->Release(); - } - - int clip_count = state_.top().clip_count; - for (int i = 0; i < clip_count; ++i) - rt_->PopAxisAlignedClip(); - - state_.pop(); - // The state_ stack should never be empty - we should always have at least one - // entry to hold a clip count when there is no active save/restore entry. - CHECK(!state_.empty()) << "Called Restore() once too often!"; - - rt_->RestoreDrawingState(drawing_state_block_); -} - -bool CanvasDirect2D::ClipRectInt(int x, int y, int w, int h) { - rt_->PushAxisAlignedClip(RectToRectF(x, y, w, h), - D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); - // Increment the clip count so the call to PushAxisAlignedClip() can be - // balanced with a call to PopAxisAlignedClip in the next Restore(). - ++state_.top().clip_count; - return w > 0 && h > 0; -} - -void CanvasDirect2D::TranslateInt(int x, int y) { - D2D1_MATRIX_3X2_F raw; - rt_->GetTransform(&raw); - D2D1::Matrix3x2F transform(raw._11, raw._12, raw._21, raw._22, raw._31, - raw._32); - transform = D2D1::Matrix3x2F::Translation(static_cast<float>(x), - static_cast<float>(y)) * transform; - rt_->SetTransform(transform); -} - -void CanvasDirect2D::ScaleInt(int x, int y) { - D2D1_MATRIX_3X2_F raw; - rt_->GetTransform(&raw); - D2D1::Matrix3x2F transform(raw._11, raw._12, raw._21, raw._22, raw._31, - raw._32); - transform = D2D1::Matrix3x2F::Scale(static_cast<float>(x), - static_cast<float>(y)) * transform; - rt_->SetTransform(transform); -} - -void CanvasDirect2D::FillRectInt(const SkColor& color, - int x, int y, int w, int h) { - ScopedComPtr<ID2D1SolidColorBrush> solid_brush; - rt_->CreateSolidColorBrush(SkColorToColorF(color), solid_brush.Receive()); - rt_->FillRectangle(RectToRectF(x, y, w, h), solid_brush); -} - -void CanvasDirect2D::FillRectInt(const SkColor& color, - int x, int y, int w, int h, - SkXfermode::Mode mode) { - NOTIMPLEMENTED(); -} - -void CanvasDirect2D::FillRectInt(const gfx::Brush* brush, - int x, int y, int w, int h) { - const Direct2DBrush* d2d_brush = static_cast<const Direct2DBrush*>(brush); - rt_->FillRectangle(RectToRectF(x, y, w, h), d2d_brush->brush()); -} - -void CanvasDirect2D::DrawRectInt(const SkColor& color, - int x, int y, int w, int h) { - ScopedComPtr<ID2D1SolidColorBrush> solid_brush; - rt_->CreateSolidColorBrush(SkColorToColorF(color), solid_brush.Receive()); - rt_->DrawRectangle(RectToRectF(x, y, w, h), solid_brush); -} - -void CanvasDirect2D::DrawRectInt(const SkColor& color, - int x, int y, int w, int h, - SkXfermode::Mode mode) { - NOTIMPLEMENTED(); -} - -void CanvasDirect2D::DrawRectInt(int x, int y, int w, int h, - const SkPaint& paint) { - NOTIMPLEMENTED(); -} - -void CanvasDirect2D::DrawLineInt(const SkColor& color, - int x1, int y1, - int x2, int y2) { - ScopedComPtr<ID2D1SolidColorBrush> solid_brush; - rt_->CreateSolidColorBrush(SkColorToColorF(color), solid_brush.Receive()); - rt_->DrawLine(PointToPoint2F(x1, y1), PointToPoint2F(x2, y2), solid_brush); -} - -void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap, int x, int y) { - ScopedComPtr<ID2D1Bitmap> d2d1_bitmap( - CreateD2D1BitmapFromSkBitmap(rt_, bitmap)); - rt_->DrawBitmap(d2d1_bitmap, - RectToRectF(x, y, bitmap.width(), bitmap.height()), - 1.0f, - D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, - RectToRectF(0, 0, bitmap.width(), bitmap.height())); -} - -void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap, - int x, int y, - const SkPaint& paint) { - NOTIMPLEMENTED(); -} - -void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, - int dest_w, int dest_h, - bool filter) { - ScopedComPtr<ID2D1Bitmap> d2d1_bitmap( - CreateD2D1BitmapFromSkBitmap(rt_, bitmap)); - rt_->DrawBitmap(d2d1_bitmap, - RectToRectF(dest_x, dest_y, dest_w, dest_h), - 1.0f, - FilterToInterpolationMode(filter), - RectToRectF(src_x, src_y, src_w, src_h)); -} - -void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, - int dest_w, int dest_h, - bool filter, - const SkPaint& paint) { - NOTIMPLEMENTED(); -} - -void CanvasDirect2D::DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h) { - NOTIMPLEMENTED(); -} - -void CanvasDirect2D::DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - const gfx::Rect& display_rect) { - NOTIMPLEMENTED(); -} - -void CanvasDirect2D::DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h, - int flags) { - NOTIMPLEMENTED(); -} - -void CanvasDirect2D::DrawFocusRect(int x, int y, int width, int height) { - NOTIMPLEMENTED(); -} - -void CanvasDirect2D::TileImageInt(const SkBitmap& bitmap, - int x, int y, int w, int h) { - ScopedComPtr<ID2D1Brush> brush( - CreateD2D1BrushFromSkBitmap(rt_, bitmap, D2D1_EXTEND_MODE_WRAP, - D2D1_EXTEND_MODE_WRAP)); - rt_->FillRectangle(RectToRectF(x, y, w, h), brush); -} - -void CanvasDirect2D::TileImageInt(const SkBitmap& bitmap, - int src_x, int src_y, - int dest_x, int dest_y, int w, int h) { - NOTIMPLEMENTED(); -} - -gfx::NativeDrawingContext CanvasDirect2D::BeginPlatformPaint() { - DCHECK(!interop_rt_.get()); - interop_rt_.QueryFrom(rt_); - HDC dc = NULL; - if (interop_rt_.get()) - interop_rt_->GetDC(D2D1_DC_INITIALIZE_MODE_COPY, &dc); - return dc; -} - -void CanvasDirect2D::EndPlatformPaint() { - DCHECK(interop_rt_.get()); - interop_rt_->ReleaseDC(NULL); - interop_rt_.release(); -} - -CanvasSkia* CanvasDirect2D::AsCanvasSkia() { - return NULL; -} - -const CanvasSkia* CanvasDirect2D::AsCanvasSkia() const { - return NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -// CanvasDirect2D, private: - -void CanvasDirect2D::SaveInternal(ID2D1Layer* layer) { - if (!drawing_state_block_) - GetD2D1Factory()->CreateDrawingStateBlock(drawing_state_block_.Receive()); - rt_->SaveDrawingState(drawing_state_block_.get()); - state_.push(RenderState(layer)); -} - -} // namespace gfx diff --git a/gfx/canvas_direct2d.h b/gfx/canvas_direct2d.h index 740a24d..4a46a396 100644 --- a/gfx/canvas_direct2d.h +++ b/gfx/canvas_direct2d.h @@ -6,107 +6,7 @@ #define GFX_CANVAS_DIRECT2D_H_ #pragma once -#include <d2d1.h> - -#include <stack> - -#include "base/scoped_comptr_win.h" -#include "gfx/canvas.h" - -namespace gfx { - -class CanvasDirect2D : public Canvas { - public: - // Creates an empty Canvas. - explicit CanvasDirect2D(ID2D1RenderTarget* rt); - virtual ~CanvasDirect2D(); - - // Retrieves the application's D2D1 Factory. - static ID2D1Factory* GetD2D1Factory(); - - // Overridden from Canvas: - virtual void Save(); - virtual void SaveLayerAlpha(uint8 alpha); - virtual void SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds); - virtual void Restore(); - virtual bool ClipRectInt(int x, int y, int w, int h); - virtual void TranslateInt(int x, int y); - virtual void ScaleInt(int x, int y); - virtual void FillRectInt(const SkColor& color, int x, int y, int w, int h); - virtual void FillRectInt(const SkColor& color, int x, int y, int w, int h, - SkXfermode::Mode mode); - virtual void FillRectInt(const gfx::Brush* brush, int x, int y, int w, int h); - virtual void DrawRectInt(const SkColor& color, int x, int y, int w, int h); - virtual void DrawRectInt(const SkColor& color, - int x, int y, int w, int h, - SkXfermode::Mode mode); - virtual void DrawRectInt(int x, int y, int w, int h, const SkPaint& paint); - virtual void DrawLineInt(const SkColor& color, - int x1, int y1, - int x2, int y2); - virtual void DrawBitmapInt(const SkBitmap& bitmap, int x, int y); - virtual void DrawBitmapInt(const SkBitmap& bitmap, - int x, int y, - const SkPaint& paint); - virtual void DrawBitmapInt(const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, - bool filter); - virtual void DrawBitmapInt(const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, - bool filter, - const SkPaint& paint); - virtual void DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h); - virtual void DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - const gfx::Rect& display_rect); - virtual void DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h, - int flags); - virtual void DrawFocusRect(int x, int y, int width, int height); - virtual void TileImageInt(const SkBitmap& bitmap, int x, int y, int w, int h); - virtual void TileImageInt(const SkBitmap& bitmap, - int src_x, int src_y, - int dest_x, int dest_y, int w, int h); - virtual gfx::NativeDrawingContext BeginPlatformPaint(); - virtual void EndPlatformPaint(); - virtual CanvasSkia* AsCanvasSkia(); - virtual const CanvasSkia* AsCanvasSkia() const; - - private: - void SaveInternal(ID2D1Layer* layer); - - ID2D1RenderTarget* rt_; - ScopedComPtr<ID2D1GdiInteropRenderTarget> interop_rt_; - ScopedComPtr<ID2D1DrawingStateBlock> drawing_state_block_; - static ID2D1Factory* d2d1_factory_; - - // Every time Save* is called, a RenderState object is pushed onto the - // RenderState stack. - struct RenderState { - explicit RenderState(ID2D1Layer* layer) : layer(layer), clip_count(0) {} - RenderState() : layer(NULL), clip_count(0) {} - - // A D2D layer associated with this state, or NULL if there is no layer. - // The layer is created and owned by the Canvas. - ID2D1Layer* layer; - // The number of clip operations performed. This is used to balance calls to - // PushAxisAlignedClip with calls to PopAxisAlignedClip when Restore() is - // called. - int clip_count; - }; - std::stack<RenderState> state_; - - DISALLOW_COPY_AND_ASSIGN(CanvasDirect2D); -}; - -} // namespace gfx; +#include "ui/gfx/canvas_direct2d.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_CANVAS_DIRECT2D_H_ diff --git a/gfx/canvas_direct2d_unittest.cc b/gfx/canvas_direct2d_unittest.cc deleted file mode 100644 index 8884f32..0000000 --- a/gfx/canvas_direct2d_unittest.cc +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <windows.h> -#include <uxtheme.h> -#include <vsstyle.h> -#include <vssym32.h> - -#include "base/command_line.h" -#include "base/ref_counted_memory.h" -#include "base/resource_util.h" -#include "base/scoped_ptr.h" -#include "gfx/brush.h" -#include "gfx/canvas_direct2d.h" -#include "gfx/canvas_skia.h" -#include "gfx/codec/png_codec.h" -#include "gfx/native_theme_win.h" -#include "gfx/rect.h" -#include "gfx/win_util.h" -#include "grit/gfx_resources.h" -#include "testing/gtest/include/gtest/gtest.h" - - -namespace { - -const char kVisibleModeFlag[] = "d2d-canvas-visible"; -const wchar_t kWindowClassName[] = L"GFXD2DTestWindowClass"; - -class TestWindow { - public: - static const int kWindowSize = 500; - static const int kWindowPosition = 10; - - TestWindow() : hwnd_(NULL) { - if (CommandLine::ForCurrentProcess()->HasSwitch(kVisibleModeFlag)) - Sleep(1000); - - RegisterMyClass(); - - hwnd_ = CreateWindowEx(0, kWindowClassName, NULL, - WS_OVERLAPPEDWINDOW, - kWindowPosition, kWindowPosition, - kWindowSize, kWindowSize, - NULL, NULL, NULL, this); - DCHECK(hwnd_); - - // Initialize the RenderTarget for the window. - rt_ = MakeHWNDRenderTarget(); - - if (CommandLine::ForCurrentProcess()->HasSwitch(kVisibleModeFlag)) - ShowWindow(hwnd(), SW_SHOW); - } - virtual ~TestWindow() { - if (CommandLine::ForCurrentProcess()->HasSwitch(kVisibleModeFlag)) - Sleep(1000); - DestroyWindow(hwnd()); - UnregisterMyClass(); - } - - HWND hwnd() const { return hwnd_; } - - ID2D1RenderTarget* rt() const { return rt_.get(); } - - private: - ID2D1RenderTarget* MakeHWNDRenderTarget() { - D2D1_RENDER_TARGET_PROPERTIES rt_properties = - D2D1::RenderTargetProperties(); - rt_properties.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; - - ID2D1HwndRenderTarget* rt = NULL; - gfx::CanvasDirect2D::GetD2D1Factory()->CreateHwndRenderTarget( - rt_properties, - D2D1::HwndRenderTargetProperties(hwnd(), D2D1::SizeU(500, 500)), - &rt); - return rt; - } - - void RegisterMyClass() { - WNDCLASSEX class_ex; - class_ex.cbSize = sizeof(WNDCLASSEX); - class_ex.style = CS_DBLCLKS; - class_ex.lpfnWndProc = &DefWindowProc; - class_ex.cbClsExtra = 0; - class_ex.cbWndExtra = 0; - class_ex.hInstance = NULL; - class_ex.hIcon = NULL; - class_ex.hCursor = LoadCursor(NULL, IDC_ARROW); - class_ex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND); - class_ex.lpszMenuName = NULL; - class_ex.lpszClassName = kWindowClassName; - class_ex.hIconSm = class_ex.hIcon; - ATOM atom = RegisterClassEx(&class_ex); - DCHECK(atom); - } - - void UnregisterMyClass() { - ::UnregisterClass(kWindowClassName, NULL); - } - - HWND hwnd_; - - ScopedComPtr<ID2D1RenderTarget> rt_; - - DISALLOW_COPY_AND_ASSIGN(TestWindow); -}; - -// Loads a png data blob from the data resources associated with this -// executable, decodes it and returns a SkBitmap. -SkBitmap LoadBitmapFromResources(int resource_id) { - SkBitmap bitmap; - - HINSTANCE resource_instance = GetModuleHandle(NULL); - void* data_ptr; - size_t data_size; - if (base::GetDataResourceFromModule(resource_instance, resource_id, &data_ptr, - &data_size)) { - scoped_refptr<RefCountedMemory> memory(new RefCountedStaticMemory( - reinterpret_cast<const unsigned char*>(data_ptr), data_size)); - if (!memory) - return bitmap; - - if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), &bitmap)) - NOTREACHED() << "Unable to decode theme image resource " << resource_id; - } - return bitmap; -} - -bool CheckForD2DCompatibility() { - if (!gfx::Direct2dIsAvailable()) { - LOG(WARNING) << "Test is disabled as it requires either Windows 7 or " << - "Vista with Platform Update KB971644"; - return false; - } - return true; -} - -} // namespace - -TEST(CanvasDirect2D, CreateCanvas) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); -} - -TEST(CanvasDirect2D, SaveRestoreNesting) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - // Simple. - canvas.Save(); - canvas.Restore(); - - // Nested. - canvas.Save(); - canvas.Save(); - canvas.Restore(); - canvas.Restore(); - - // Simple alpha. - canvas.SaveLayerAlpha(127); - canvas.Restore(); - - // Alpha with sub-rect. - canvas.SaveLayerAlpha(127, gfx::Rect(20, 20, 100, 100)); - canvas.Restore(); - - // Nested alpha. - canvas.Save(); - canvas.SaveLayerAlpha(127); - canvas.Save(); - canvas.Restore(); - canvas.Restore(); - canvas.Restore(); -} - -TEST(CanvasDirect2D, SaveLayerAlpha) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - canvas.Save(); - canvas.FillRectInt(SK_ColorBLUE, 20, 20, 100, 100); - canvas.SaveLayerAlpha(127); - canvas.FillRectInt(SK_ColorRED, 60, 60, 100, 100); - canvas.Restore(); - canvas.Restore(); -} - -TEST(CanvasDirect2D, SaveLayerAlphaWithBounds) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - canvas.Save(); - canvas.FillRectInt(SK_ColorBLUE, 20, 20, 100, 100); - canvas.SaveLayerAlpha(127, gfx::Rect(60, 60, 50, 50)); - canvas.FillRectInt(SK_ColorRED, 60, 60, 100, 100); - canvas.Restore(); - canvas.Restore(); -} - -TEST(CanvasDirect2D, FillRect) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - canvas.FillRectInt(SK_ColorRED, 20, 20, 100, 100); -} - -TEST(CanvasDirect2D, PlatformPainting) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - gfx::NativeDrawingContext dc = canvas.BeginPlatformPaint(); - - // Use the system theme engine to draw a native button. This only works on a - // GDI device context. - RECT r = { 20, 20, 220, 80 }; - gfx::NativeTheme::instance()->PaintButton( - dc, BP_PUSHBUTTON, PBS_NORMAL, DFCS_BUTTONPUSH, &r); - - canvas.EndPlatformPaint(); -} - -TEST(CanvasDirect2D, ClipRect) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - canvas.FillRectInt(SK_ColorGREEN, 0, 0, 500, 500); - canvas.ClipRectInt(20, 20, 120, 120); - canvas.FillRectInt(SK_ColorBLUE, 0, 0, 500, 500); -} - -TEST(CanvasDirect2D, ClipRectWithTranslate) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - // Repeat the same rendering as in ClipRect... - canvas.Save(); - canvas.FillRectInt(SK_ColorGREEN, 0, 0, 500, 500); - canvas.ClipRectInt(20, 20, 120, 120); - canvas.FillRectInt(SK_ColorBLUE, 0, 0, 500, 500); - canvas.Restore(); - - // ... then translate, clip and fill again relative to the new origin. - canvas.Save(); - canvas.TranslateInt(150, 150); - canvas.ClipRectInt(10, 10, 110, 110); - canvas.FillRectInt(SK_ColorRED, 0, 0, 500, 500); - canvas.Restore(); -} - -TEST(CanvasDirect2D, ClipRectWithScale) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - // Repeat the same rendering as in ClipRect... - canvas.Save(); - canvas.FillRectInt(SK_ColorGREEN, 0, 0, 500, 500); - canvas.ClipRectInt(20, 20, 120, 120); - canvas.FillRectInt(SK_ColorBLUE, 0, 0, 500, 500); - canvas.Restore(); - - // ... then translate and scale, clip and fill again relative to the new - // origin. - canvas.Save(); - canvas.TranslateInt(150, 150); - canvas.ScaleInt(2, 2); - canvas.ClipRectInt(10, 10, 110, 110); - canvas.FillRectInt(SK_ColorRED, 0, 0, 500, 500); - canvas.Restore(); -} - -TEST(CanvasDirect2D, DrawRectInt) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - canvas.Save(); - canvas.DrawRectInt(SK_ColorRED, 10, 10, 200, 200); - canvas.Restore(); -} - -TEST(CanvasDirect2D, DrawLineInt) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - canvas.Save(); - canvas.DrawLineInt(SK_ColorRED, 10, 10, 210, 210); - canvas.Restore(); -} - -TEST(CanvasDirect2D, DrawBitmapInt) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - SkBitmap bitmap = LoadBitmapFromResources(IDR_BITMAP_BRUSH_IMAGE); - - canvas.Save(); - canvas.DrawBitmapInt(bitmap, 100, 100); - canvas.Restore(); -} - -TEST(CanvasDirect2D, DrawBitmapInt2) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - SkBitmap bitmap = LoadBitmapFromResources(IDR_BITMAP_BRUSH_IMAGE); - - canvas.Save(); - canvas.DrawBitmapInt(bitmap, 5, 5, 30, 30, 10, 10, 30, 30, false); - canvas.DrawBitmapInt(bitmap, 5, 5, 30, 30, 110, 110, 100, 100, true); - canvas.DrawBitmapInt(bitmap, 5, 5, 30, 30, 220, 220, 100, 100, false); - canvas.Restore(); -} - -TEST(CanvasDirect2D, TileImageInt) { - if (!CheckForD2DCompatibility()) - return; - TestWindow window; - gfx::CanvasDirect2D canvas(window.rt()); - - SkBitmap bitmap = LoadBitmapFromResources(IDR_BITMAP_BRUSH_IMAGE); - - canvas.Save(); - canvas.TileImageInt(bitmap, 10, 10, 300, 300); - canvas.Restore(); -} diff --git a/gfx/canvas_skia.cc b/gfx/canvas_skia.cc deleted file mode 100644 index aa0cb9d..0000000 --- a/gfx/canvas_skia.cc +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/canvas_skia.h" - -#include <limits> - -#include "base/i18n/rtl.h" -#include "base/logging.h" -#include "gfx/brush.h" -#include "gfx/font.h" -#include "gfx/rect.h" -#include "third_party/skia/include/effects/SkGradientShader.h" - -#if defined(OS_WIN) -#include "gfx/canvas_skia_paint.h" -#endif - -namespace { - -// A platform wrapper for a Skia shader that makes sure the underlying -// SkShader object is unref'ed when this object is destroyed. -class SkiaShader : public gfx::Brush { - public: - explicit SkiaShader(SkShader* shader) : shader_(shader) { - } - virtual ~SkiaShader() { - shader_->unref(); - } - - // Accessor for shader, so it can be associated with a SkPaint. - SkShader* shader() const { return shader_; } - - private: - SkShader* shader_; - - DISALLOW_COPY_AND_ASSIGN(SkiaShader); -}; - - -} // namespace - -namespace gfx { - -//////////////////////////////////////////////////////////////////////////////// -// CanvasSkia, public: - -// static -int CanvasSkia::DefaultCanvasTextAlignment() { - if (!base::i18n::IsRTL()) - return gfx::Canvas::TEXT_ALIGN_LEFT; - return gfx::Canvas::TEXT_ALIGN_RIGHT; -} - -SkBitmap CanvasSkia::ExtractBitmap() const { - const SkBitmap& device_bitmap = getDevice()->accessBitmap(false); - - // Make a bitmap to return, and a canvas to draw into it. We don't just want - // to call extractSubset or the copy constructor, since we want an actual copy - // of the bitmap. - SkBitmap result; - device_bitmap.copyTo(&result, SkBitmap::kARGB_8888_Config); - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// CanvasSkia, Canvas implementation: - -void CanvasSkia::Save() { - save(); -} - -void CanvasSkia::SaveLayerAlpha(uint8 alpha) { - saveLayerAlpha(NULL, alpha); -} - - -void CanvasSkia::SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds) { - SkRect bounds; - bounds.set(SkIntToScalar(layer_bounds.x()), - SkIntToScalar(layer_bounds.y()), - SkIntToScalar(layer_bounds.right()), - SkIntToScalar(layer_bounds.bottom())); - saveLayerAlpha(&bounds, alpha); -} - -void CanvasSkia::Restore() { - restore(); -} - -bool CanvasSkia::ClipRectInt(int x, int y, int w, int h) { - SkRect new_clip; - new_clip.set(SkIntToScalar(x), SkIntToScalar(y), - SkIntToScalar(x + w), SkIntToScalar(y + h)); - return clipRect(new_clip); -} - -void CanvasSkia::TranslateInt(int x, int y) { - translate(SkIntToScalar(x), SkIntToScalar(y)); -} - -void CanvasSkia::ScaleInt(int x, int y) { - scale(SkIntToScalar(x), SkIntToScalar(y)); -} - -void CanvasSkia::FillRectInt(const SkColor& color, int x, int y, int w, int h) { - FillRectInt(color, x, y, w, h, SkXfermode::kSrcOver_Mode); -} - -void CanvasSkia::FillRectInt(const SkColor& color, - int x, int y, int w, int h, - SkXfermode::Mode mode) { - SkPaint paint; - paint.setColor(color); - paint.setStyle(SkPaint::kFill_Style); - paint.setXfermodeMode(mode); - DrawRectInt(x, y, w, h, paint); -} - -void CanvasSkia::FillRectInt(const gfx::Brush* brush, - int x, int y, int w, int h) { - const SkiaShader* shader = static_cast<const SkiaShader*>(brush); - SkPaint paint; - paint.setShader(shader->shader()); - // TODO(beng): set shader transform to match canvas transform. - DrawRectInt(x, y, w, h, paint); -} - -void CanvasSkia::DrawRectInt(const SkColor& color, int x, int y, int w, int h) { - DrawRectInt(color, x, y, w, h, SkXfermode::kSrcOver_Mode); -} - -void CanvasSkia::DrawRectInt(const SkColor& color, - int x, int y, int w, int h, - SkXfermode::Mode mode) { - SkPaint paint; - paint.setColor(color); - paint.setStyle(SkPaint::kStroke_Style); - // Set a stroke width of 0, which will put us down the stroke rect path. If - // we set a stroke width of 1, for example, this will internally create a - // path and fill it, which causes problems near the edge of the canvas. - paint.setStrokeWidth(SkIntToScalar(0)); - paint.setXfermodeMode(mode); - - DrawRectInt(x, y, w, h, paint); -} - -void CanvasSkia::DrawRectInt(int x, int y, int w, int h, const SkPaint& paint) { - SkIRect rc = { x, y, x + w, y + h }; - drawIRect(rc, paint); -} - -void CanvasSkia::DrawLineInt(const SkColor& color, - int x1, int y1, - int x2, int y2) { - SkPaint paint; - paint.setColor(color); - paint.setStrokeWidth(SkIntToScalar(1)); - drawLine(SkIntToScalar(x1), SkIntToScalar(y1), SkIntToScalar(x2), - SkIntToScalar(y2), paint); -} - -void CanvasSkia::DrawFocusRect(int x, int y, int width, int height) { - // Create a 2D bitmap containing alternating on/off pixels - we do this - // so that you never get two pixels of the same color around the edges - // of the focus rect (this may mean that opposing edges of the rect may - // have a dot pattern out of phase to each other). - static SkBitmap* dots = NULL; - if (!dots) { - int col_pixels = 32; - int row_pixels = 32; - - dots = new SkBitmap; - dots->setConfig(SkBitmap::kARGB_8888_Config, col_pixels, row_pixels); - dots->allocPixels(); - dots->eraseARGB(0, 0, 0, 0); - - uint32_t* dot = dots->getAddr32(0, 0); - for (int i = 0; i < row_pixels; i++) { - for (int u = 0; u < col_pixels; u++) { - if ((u % 2 + i % 2) % 2 != 0) { - dot[i * row_pixels + u] = SK_ColorGRAY; - } - } - } - } - - // First the horizontal lines. - - // Make a shader for the bitmap with an origin of the box we'll draw. This - // shader is refcounted and will have an initial refcount of 1. - SkShader* shader = SkShader::CreateBitmapShader( - *dots, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); - // Assign the shader to the paint & release our reference. The paint will - // now own the shader and the shader will be destroyed when the paint goes - // out of scope. - SkPaint paint; - paint.setShader(shader); - shader->unref(); - - DrawRectInt(x, y, width, 1, paint); - DrawRectInt(x, y + height - 1, width, 1, paint); - DrawRectInt(x, y, 1, height, paint); - DrawRectInt(x + width - 1, y, 1, height, paint); -} - -void CanvasSkia::DrawBitmapInt(const SkBitmap& bitmap, int x, int y) { - drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y)); -} - -void CanvasSkia::DrawBitmapInt(const SkBitmap& bitmap, - int x, int y, - const SkPaint& paint) { - drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y), &paint); -} - -void CanvasSkia::DrawBitmapInt(const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, - bool filter) { - SkPaint p; - DrawBitmapInt(bitmap, src_x, src_y, src_w, src_h, dest_x, dest_y, - dest_w, dest_h, filter, p); -} - -void CanvasSkia::DrawBitmapInt(const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, - bool filter, - const SkPaint& paint) { - DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && - src_y + src_h < std::numeric_limits<int16_t>::max()); - if (src_w <= 0 || src_h <= 0 || dest_w <= 0 || dest_h <= 0) { - NOTREACHED() << "Attempting to draw bitmap to/from an empty rect!"; - return; - } - - if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h)) - return; - - SkRect dest_rect = { SkIntToScalar(dest_x), - SkIntToScalar(dest_y), - SkIntToScalar(dest_x + dest_w), - SkIntToScalar(dest_y + dest_h) }; - - if (src_w == dest_w && src_h == dest_h) { - // Workaround for apparent bug in Skia that causes image to occasionally - // shift. - SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h }; - drawBitmapRect(bitmap, &src_rect, dest_rect, &paint); - return; - } - - // Make a bitmap shader that contains the bitmap we want to draw. This is - // basically what SkCanvas.drawBitmap does internally, but it gives us - // more control over quality and will use the mipmap in the source image if - // it has one, whereas drawBitmap won't. - SkShader* shader = SkShader::CreateBitmapShader(bitmap, - SkShader::kRepeat_TileMode, - SkShader::kRepeat_TileMode); - SkMatrix shader_scale; - shader_scale.setScale(SkFloatToScalar(static_cast<float>(dest_w) / src_w), - SkFloatToScalar(static_cast<float>(dest_h) / src_h)); - shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); - shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); - shader->setLocalMatrix(shader_scale); - - // Set up our paint to use the shader & release our reference (now just owned - // by the paint). - SkPaint p(paint); - p.setFilterBitmap(filter); - p.setShader(shader); - shader->unref(); - - // The rect will be filled by the bitmap. - drawRect(dest_rect, p); -} - -void CanvasSkia::DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h) { - DrawStringInt(text, font, color, x, y, w, h, - gfx::CanvasSkia::DefaultCanvasTextAlignment()); -} - -void CanvasSkia::DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - const gfx::Rect& display_rect) { - DrawStringInt(text, font, color, display_rect.x(), display_rect.y(), - display_rect.width(), display_rect.height()); -} - -void CanvasSkia::TileImageInt(const SkBitmap& bitmap, - int x, int y, int w, int h) { - TileImageInt(bitmap, 0, 0, x, y, w, h); -} - -void CanvasSkia::TileImageInt(const SkBitmap& bitmap, - int src_x, int src_y, - int dest_x, int dest_y, int w, int h) { - if (!IntersectsClipRectInt(dest_x, dest_y, w, h)) - return; - - SkPaint paint; - - SkShader* shader = SkShader::CreateBitmapShader(bitmap, - SkShader::kRepeat_TileMode, - SkShader::kRepeat_TileMode); - paint.setShader(shader); - paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); - - // CreateBitmapShader returns a Shader with a reference count of one, we - // need to unref after paint takes ownership of the shader. - shader->unref(); - save(); - translate(SkIntToScalar(dest_x - src_x), SkIntToScalar(dest_y - src_y)); - ClipRectInt(src_x, src_y, w, h); - drawPaint(paint); - restore(); -} - -gfx::NativeDrawingContext CanvasSkia::BeginPlatformPaint() { - return beginPlatformPaint(); -} - -void CanvasSkia::EndPlatformPaint() { - endPlatformPaint(); -} - -CanvasSkia* CanvasSkia::AsCanvasSkia() { - return this; -} - -const CanvasSkia* CanvasSkia::AsCanvasSkia() const { - return this; -} - -//////////////////////////////////////////////////////////////////////////////// -// CanvasSkia, private: - -bool CanvasSkia::IntersectsClipRectInt(int x, int y, int w, int h) { - SkRect clip; - return getClipBounds(&clip) && - clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), - SkIntToScalar(y + h)); -} - -//////////////////////////////////////////////////////////////////////////////// -// Canvas, public: - -Canvas* Canvas::CreateCanvas() { - return new CanvasSkia; -} - -Canvas* Canvas::CreateCanvas(int width, int height, bool is_opaque) { - return new CanvasSkia(width, height, is_opaque); -} - -#if defined(OS_WIN) -// TODO(beng): move to canvas_win.cc, etc. -class CanvasPaintWin : public CanvasSkiaPaint, public CanvasPaint { - public: - CanvasPaintWin(gfx::NativeView view) : CanvasSkiaPaint(view) {} - - // Overridden from CanvasPaint2: - virtual bool IsValid() const { - return isEmpty(); - } - - virtual gfx::Rect GetInvalidRect() const { - return gfx::Rect(paintStruct().rcPaint); - } - - virtual Canvas* AsCanvas() { - return this; - } -}; -#endif - -CanvasPaint* CanvasPaint::CreateCanvasPaint(gfx::NativeView view) { -#if defined(OS_WIN) - return new CanvasPaintWin(view); -#else - return NULL; -#endif -} - -} // namespace gfx diff --git a/gfx/canvas_skia.h b/gfx/canvas_skia.h index b8b0aa9..d967eab 100644 --- a/gfx/canvas_skia.h +++ b/gfx/canvas_skia.h @@ -6,160 +6,7 @@ #define GFX_CANVAS_SKIA_H_ #pragma once -#include "base/basictypes.h" -#include "base/string16.h" -#include "gfx/canvas.h" -#include "skia/ext/platform_canvas.h" - -#if defined(OS_POSIX) && !defined(OS_MACOSX) -typedef struct _GdkPixbuf GdkPixbuf; -#endif - -namespace gfx { - -class Canvas; - -// CanvasSkia is a SkCanvas subclass that provides a number of methods for -// common operations used throughout an application built using base/gfx and -// app/gfx. -// -// All methods that take integer arguments (as is used throughout views) -// end with Int. If you need to use methods provided by the superclass -// you'll need to do a conversion. In particular you'll need to use -// macro SkIntToScalar(xxx), or if converting from a scalar to an integer -// SkScalarRound. -// -// A handful of methods in this class are overloaded providing an additional -// argument of type SkXfermode::Mode. SkXfermode::Mode specifies how the -// source and destination colors are combined. Unless otherwise specified, -// the variant that does not take a SkXfermode::Mode uses a transfer mode -// of kSrcOver_Mode. -class CanvasSkia : public skia::PlatformCanvas, - public Canvas { - public: - // Creates an empty Canvas. Callers must use initialize before using the - // canvas. - CanvasSkia(); - - CanvasSkia(int width, int height, bool is_opaque); - - virtual ~CanvasSkia(); - - // Compute the size required to draw some text with the provided font. - // Attempts to fit the text with the provided width and height. Increases - // height and then width as needed to make the text fit. This method - // supports multiple lines. - static void SizeStringInt(const string16& text, - const gfx::Font& font, - int* width, int* height, - int flags); - - // Returns the default text alignment to be used when drawing text on a - // gfx::CanvasSkia based on the directionality of the system locale language. - // This function is used by gfx::Canvas::DrawStringInt when the text alignment - // is not specified. - // - // This function returns either gfx::Canvas::TEXT_ALIGN_LEFT or - // gfx::Canvas::TEXT_ALIGN_RIGHT. - static int DefaultCanvasTextAlignment(); - -#if defined(OS_POSIX) && !defined(OS_MACOSX) - // Draw the pixbuf in its natural size at (x, y). - void DrawGdkPixbuf(GdkPixbuf* pixbuf, int x, int y); -#endif - -#if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX)) - // Draws text with a 1-pixel halo around it of the given color. - // On Windows, 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. - // On Linux, text with halo is created by stroking it with 2px |halo_color| - // then filling it with |text_color|. - void DrawStringWithHalo(const string16& text, - const gfx::Font& font, - const SkColor& text_color, - const SkColor& halo_color, - int x, int y, int w, int h, - int flags); -#endif - - // Extracts a bitmap from the contents of this canvas. - SkBitmap ExtractBitmap() const; - - // Overridden from Canvas: - virtual void Save(); - virtual void SaveLayerAlpha(uint8 alpha); - virtual void SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds); - virtual void Restore(); - virtual bool ClipRectInt(int x, int y, int w, int h); - virtual void TranslateInt(int x, int y); - virtual void ScaleInt(int x, int y); - virtual void FillRectInt(const SkColor& color, int x, int y, int w, int h); - virtual void FillRectInt(const SkColor& color, int x, int y, int w, int h, - SkXfermode::Mode mode); - virtual void FillRectInt(const gfx::Brush* brush, int x, int y, int w, int h); - virtual void DrawRectInt(const SkColor& color, int x, int y, int w, int h); - virtual void DrawRectInt(const SkColor& color, - int x, int y, int w, int h, - SkXfermode::Mode mode); - virtual void DrawRectInt(int x, int y, int w, int h, const SkPaint& paint); - virtual void DrawLineInt(const SkColor& color, - int x1, int y1, - int x2, int y2); - virtual void DrawBitmapInt(const SkBitmap& bitmap, int x, int y); - virtual void DrawBitmapInt(const SkBitmap& bitmap, - int x, int y, - const SkPaint& paint); - virtual void DrawBitmapInt(const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, - bool filter); - virtual void DrawBitmapInt(const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h, - bool filter, - const SkPaint& paint); - virtual void DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h); - virtual void DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - const gfx::Rect& display_rect); - virtual void DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h, - int flags); - virtual void DrawFocusRect(int x, int y, int width, int height); - virtual void TileImageInt(const SkBitmap& bitmap, int x, int y, int w, int h); - virtual void TileImageInt(const SkBitmap& bitmap, - int src_x, int src_y, - int dest_x, int dest_y, int w, int h); - virtual gfx::NativeDrawingContext BeginPlatformPaint(); - virtual void EndPlatformPaint(); - virtual CanvasSkia* AsCanvasSkia(); - virtual const CanvasSkia* AsCanvasSkia() const; - - private: - // Test whether the provided rectangle intersects the current clip rect. - bool IntersectsClipRectInt(int x, int y, int w, int h); - -#if defined(OS_WIN) - // Draws text with the specified color, font and location. The text is - // aligned to the left, vertically centered, clipped to the region. If the - // text is too big, it is truncated and '...' is added to the end. - void DrawStringInt(const string16& text, - HFONT font, - const SkColor& color, - int x, int y, int w, int h, - int flags); -#endif - - DISALLOW_COPY_AND_ASSIGN(CanvasSkia); -}; - -} // namespace gfx; +#include "ui/gfx/canvas_skia.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_CANVAS_SKIA_H_ diff --git a/gfx/canvas_skia_linux.cc b/gfx/canvas_skia_linux.cc deleted file mode 100644 index ce2ae01..0000000 --- a/gfx/canvas_skia_linux.cc +++ /dev/null @@ -1,387 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/canvas_skia.h" - -#include <cairo/cairo.h> -#include <gtk/gtk.h> -#include <pango/pango.h> -#include <pango/pangocairo.h> - -#include "base/logging.h" -#include "base/utf_string_conversions.h" -#include "gfx/font.h" -#include "gfx/gtk_util.h" -#include "gfx/platform_font_gtk.h" -#include "gfx/rect.h" - -namespace { - -const gunichar kAcceleratorChar = '&'; - -// Font settings that we initialize once and then use when drawing text in -// DrawStringInt(). -static cairo_font_options_t* cairo_font_options = NULL; - -// Update |cairo_font_options| based on GtkSettings, allocating it if needed. -static void UpdateCairoFontOptions() { - if (!cairo_font_options) - cairo_font_options = cairo_font_options_create(); - - GtkSettings* gtk_settings = gtk_settings_get_default(); - gint antialias = 0; - gint hinting = 0; - gchar* hint_style = NULL; - gchar* rgba_style = NULL; - g_object_get(gtk_settings, - "gtk-xft-antialias", &antialias, - "gtk-xft-hinting", &hinting, - "gtk-xft-hintstyle", &hint_style, - "gtk-xft-rgba", &rgba_style, - NULL); - - // g_object_get() doesn't tell us whether the properties were present or not, - // but if they aren't (because gnome-settings-daemon isn't running), we'll get - // NULL values for the strings. - if (hint_style && rgba_style) { - if (!antialias) { - cairo_font_options_set_antialias(cairo_font_options, - CAIRO_ANTIALIAS_NONE); - } else if (strcmp(rgba_style, "none") == 0) { - cairo_font_options_set_antialias(cairo_font_options, - CAIRO_ANTIALIAS_GRAY); - } else { - cairo_font_options_set_antialias(cairo_font_options, - CAIRO_ANTIALIAS_SUBPIXEL); - cairo_subpixel_order_t cairo_subpixel_order = - CAIRO_SUBPIXEL_ORDER_DEFAULT; - if (strcmp(rgba_style, "rgb") == 0) { - cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; - } else if (strcmp(rgba_style, "bgr") == 0) { - cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; - } else if (strcmp(rgba_style, "vrgb") == 0) { - cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; - } else if (strcmp(rgba_style, "vbgr") == 0) { - cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; - } - cairo_font_options_set_subpixel_order(cairo_font_options, - cairo_subpixel_order); - } - - cairo_hint_style_t cairo_hint_style = CAIRO_HINT_STYLE_DEFAULT; - if (hinting == 0 || strcmp(hint_style, "hintnone") == 0) { - cairo_hint_style = CAIRO_HINT_STYLE_NONE; - } else if (strcmp(hint_style, "hintslight") == 0) { - cairo_hint_style = CAIRO_HINT_STYLE_SLIGHT; - } else if (strcmp(hint_style, "hintmedium") == 0) { - cairo_hint_style = CAIRO_HINT_STYLE_MEDIUM; - } else if (strcmp(hint_style, "hintfull") == 0) { - cairo_hint_style = CAIRO_HINT_STYLE_FULL; - } - cairo_font_options_set_hint_style(cairo_font_options, cairo_hint_style); - } - - if (hint_style) - g_free(hint_style); - if (rgba_style) - g_free(rgba_style); -} - -// Pass a width > 0 to force wrapping and elliding. -static void SetupPangoLayout(PangoLayout* layout, - const string16& text, - const gfx::Font& font, - int width, - int flags) { - if (!cairo_font_options) - UpdateCairoFontOptions(); - // This needs to be done early on; it has no effect when called just before - // pango_cairo_show_layout(). - pango_cairo_context_set_font_options( - pango_layout_get_context(layout), cairo_font_options); - - // Callers of DrawStringInt handle RTL layout themselves, so tell pango to not - // scope out RTL characters. - pango_layout_set_auto_dir(layout, FALSE); - - if (width > 0) - pango_layout_set_width(layout, width * PANGO_SCALE); - - if (flags & gfx::Canvas::NO_ELLIPSIS) { - pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); - } else { - pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); - } - - if (flags & gfx::Canvas::TEXT_ALIGN_CENTER) { - pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); - } else if (flags & gfx::Canvas::TEXT_ALIGN_RIGHT) { - pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); - } - - if (flags & gfx::Canvas::MULTI_LINE) { - pango_layout_set_wrap(layout, - (flags & gfx::Canvas::CHARACTER_BREAK) ? - PANGO_WRAP_WORD_CHAR : PANGO_WRAP_WORD); - } - - // Set the resolution to match that used by Gtk. If we don't set the - // resolution and the resolution differs from the default, Gtk and Chrome end - // up drawing at different sizes. - double resolution = gfx::GetPangoResolution(); - if (resolution > 0) { - pango_cairo_context_set_resolution(pango_layout_get_context(layout), - resolution); - } - - PangoFontDescription* desc = font.GetNativeFont(); - pango_layout_set_font_description(layout, desc); - pango_font_description_free(desc); - - // Set text and accelerator character if needed. - std::string utf8 = UTF16ToUTF8(text); - if (flags & gfx::Canvas::SHOW_PREFIX) { - // Escape the text string to be used as markup. - gchar* escaped_text = g_markup_escape_text(utf8.c_str(), utf8.size()); - pango_layout_set_markup_with_accel(layout, - escaped_text, - strlen(escaped_text), - kAcceleratorChar, NULL); - g_free(escaped_text); - } else if (flags & gfx::Canvas::HIDE_PREFIX) { - // Remove the ampersand character. - utf8 = gfx::RemoveWindowsStyleAccelerators(utf8); - pango_layout_set_text(layout, utf8.data(), utf8.size()); - } else { - pango_layout_set_text(layout, utf8.data(), utf8.size()); - } -} - -// A class to encapsulate string drawing params and operations. -class DrawStringContext { - public: - DrawStringContext(gfx::CanvasSkia* canvas, - const string16& text, - const gfx::Font& font, - const gfx::Rect& bounds, - const gfx::Rect& clip, - int flags); - ~DrawStringContext(); - - void Draw(const SkColor& text_color); - void DrawWithHalo(const SkColor& text_color, - const SkColor& halo_color); - - private: - const gfx::Rect& bounds_; - int flags_; - const gfx::Font& font_; - - gfx::CanvasSkia* canvas_; - cairo_t* cr_; - PangoLayout* layout_; - - int text_x_; - int text_y_; - int text_width_; - int text_height_; - - DISALLOW_COPY_AND_ASSIGN(DrawStringContext); -}; - -DrawStringContext::DrawStringContext(gfx::CanvasSkia* canvas, - const string16& text, - const gfx::Font& font, - const gfx::Rect& bounds, - const gfx::Rect& clip, - int flags) - : bounds_(bounds), - flags_(flags), - font_(font), - canvas_(canvas), - cr_(NULL), - layout_(NULL), - text_x_(bounds.x()), - text_y_(bounds.y()), - text_width_(0), - text_height_(0) { - DCHECK(!bounds_.IsEmpty()); - - cr_ = canvas_->beginPlatformPaint(); - layout_ = pango_cairo_create_layout(cr_); - - SetupPangoLayout(layout_, text, font, bounds_.width(), flags_); - - pango_layout_set_height(layout_, bounds_.height() * PANGO_SCALE); - - cairo_save(cr_); - - cairo_rectangle(cr_, clip.x(), clip.y(), clip.width(), clip.height()); - cairo_clip(cr_); - - pango_layout_get_pixel_size(layout_, &text_width_, &text_height_); - - if (flags_ & gfx::Canvas::TEXT_VALIGN_TOP) { - // Cairo should draw from the top left corner already. - } else if (flags_ & gfx::Canvas::TEXT_VALIGN_BOTTOM) { - text_y_ += (bounds.height() - text_height_); - } else { - // Vertically centered. - text_y_ += ((bounds.height() - text_height_) / 2); - } -} - -DrawStringContext::~DrawStringContext() { - if (font_.GetStyle() & gfx::Font::UNDERLINED) { - gfx::PlatformFontGtk* platform_font = - static_cast<gfx::PlatformFontGtk*>(font_.platform_font()); - double underline_y = - static_cast<double>(text_y_) + text_height_ + - platform_font->underline_position(); - cairo_set_line_width(cr_, platform_font->underline_thickness()); - cairo_move_to(cr_, text_x_, underline_y); - cairo_line_to(cr_, text_x_ + text_width_, underline_y); - cairo_stroke(cr_); - } - cairo_restore(cr_); - - g_object_unref(layout_); - // NOTE: beginPlatformPaint returned its surface, we shouldn't destroy it. -} - -void DrawStringContext::Draw(const SkColor& text_color) { - cairo_set_source_rgba(cr_, - SkColorGetR(text_color) / 255.0, - SkColorGetG(text_color) / 255.0, - SkColorGetB(text_color) / 255.0, - SkColorGetA(text_color) / 255.0); - cairo_move_to(cr_, text_x_, text_y_); - pango_cairo_show_layout(cr_, layout_); -} - -void DrawStringContext::DrawWithHalo(const SkColor& text_color, - const SkColor& halo_color) { - gfx::CanvasSkia text_canvas(bounds_.width() + 2, bounds_.height() + 2, false); - text_canvas.FillRectInt(static_cast<SkColor>(0), - 0, 0, bounds_.width() + 2, bounds_.height() + 2); - - cairo_t* text_cr = text_canvas.beginPlatformPaint(); - - cairo_move_to(text_cr, 1, 1); - pango_cairo_layout_path(text_cr, layout_); - - cairo_set_source_rgba(text_cr, - SkColorGetR(halo_color) / 255.0, - SkColorGetG(halo_color) / 255.0, - SkColorGetB(halo_color) / 255.0, - SkColorGetA(halo_color) / 255.0); - cairo_set_line_width(text_cr, 2.0); - cairo_set_line_join(text_cr, CAIRO_LINE_JOIN_ROUND); - cairo_stroke_preserve(text_cr); - - cairo_set_operator(text_cr, CAIRO_OPERATOR_SOURCE); - cairo_set_source_rgba(text_cr, - SkColorGetR(text_color) / 255.0, - SkColorGetG(text_color) / 255.0, - SkColorGetB(text_color) / 255.0, - SkColorGetA(text_color) / 255.0); - cairo_fill(text_cr); - - text_canvas.endPlatformPaint(); - - const SkBitmap& text_bitmap = const_cast<SkBitmap&>( - text_canvas.getTopPlatformDevice().accessBitmap(false)); - canvas_->DrawBitmapInt(text_bitmap, text_x_ - 1, text_y_ - 1); -} - -} // namespace - -namespace gfx { - -CanvasSkia::CanvasSkia(int width, int height, bool is_opaque) - : skia::PlatformCanvas(width, height, is_opaque) { -} - -CanvasSkia::CanvasSkia() : skia::PlatformCanvas() { -} - -CanvasSkia::~CanvasSkia() { -} - -// static -void CanvasSkia::SizeStringInt(const string16& text, - const gfx::Font& font, - int* width, int* height, - int flags) { - int org_width = *width; - cairo_surface_t* surface = - cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0); - cairo_t* cr = cairo_create(surface); - PangoLayout* layout = pango_cairo_create_layout(cr); - - SetupPangoLayout(layout, text, font, *width, flags); - - pango_layout_get_pixel_size(layout, width, height); - - if (org_width > 0 && flags & Canvas::MULTI_LINE && - pango_layout_is_wrapped(layout)) { - // The text wrapped. There seems to be a bug in Pango when this happens - // such that the width returned from pango_layout_get_pixel_size is too - // small. Using the width from pango_layout_get_pixel_size in this case - // results in wrapping across more lines, which requires a bigger height. - // As a workaround we use the original width, which is not necessarily - // exactly correct, but isn't wrong by much. - // - // It looks like Pango uses the size of whitespace in calculating wrapping - // but doesn't include the size of the whitespace when the extents are - // asked for. See the loop in pango-layout.c process_item that determines - // where to wrap. - *width = org_width; - } - - g_object_unref(layout); - cairo_destroy(cr); - cairo_surface_destroy(surface); -} - -void CanvasSkia::DrawStringWithHalo(const string16& text, - const gfx::Font& font, - const SkColor& text_color, - const SkColor& halo_color, - int x, int y, int w, int h, - int flags) { - if (w <= 0 || h <= 0) - return; - - gfx::Rect bounds(x, y, w, h); - gfx::Rect clip(x - 1, y - 1, w + 2, h + 2); // Bigger clip for halo - DrawStringContext context(this, text, font, bounds, clip,flags); - context.DrawWithHalo(text_color, halo_color); -} - -void CanvasSkia::DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h, - int flags) { - if (w <= 0 || h <= 0) - return; - - gfx::Rect bounds(x, y, w, h); - DrawStringContext context(this, text, font, bounds, bounds, flags); - context.Draw(color); -} - -void CanvasSkia::DrawGdkPixbuf(GdkPixbuf* pixbuf, int x, int y) { - if (!pixbuf) { - NOTREACHED(); - return; - } - - cairo_t* cr = beginPlatformPaint(); - gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); - cairo_paint(cr); -} - -} // namespace gfx diff --git a/gfx/canvas_skia_mac.mm b/gfx/canvas_skia_mac.mm deleted file mode 100644 index fb30055..0000000 --- a/gfx/canvas_skia_mac.mm +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import <Cocoa/Cocoa.h> - -#include "gfx/canvas_skia.h" - -#include "base/mac/scoped_cftyperef.h" -#include "base/sys_string_conversions.h" -#include "gfx/font.h" -#include "gfx/rect.h" -#include "third_party/skia/include/core/SkShader.h" - -namespace gfx { - -CanvasSkia::CanvasSkia(int width, int height, bool is_opaque) - : skia::PlatformCanvas(width, height, is_opaque) { -} - -CanvasSkia::CanvasSkia() : skia::PlatformCanvas() { -} - -CanvasSkia::~CanvasSkia() { -} - -// static -void CanvasSkia::SizeStringInt(const string16& text, - const gfx::Font& font, - int* width, int* height, - int flags) { - NSFont* native_font = font.GetNativeFont(); - NSString* ns_string = base::SysUTF16ToNSString(text); - NSDictionary* attributes = - [NSDictionary dictionaryWithObject:native_font - forKey:NSFontAttributeName]; - NSSize string_size = [ns_string sizeWithAttributes:attributes]; - *width = string_size.width; - *height = font.GetHeight(); -} - -void CanvasSkia::DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h, - int flags) { - if (!IntersectsClipRectInt(x, y, w, h)) - return; - - CGContextRef context = beginPlatformPaint(); - CGContextSaveGState(context); - - NSColor* ns_color = [NSColor colorWithDeviceRed:SkColorGetR(color) / 255.0 - green:SkColorGetG(color) / 255.0 - blue:SkColorGetB(color) / 255.0 - alpha:SkColorGetA(color) / 255.0]; - NSMutableParagraphStyle *ns_style = - [[[NSParagraphStyle alloc] init] autorelease]; - if (flags & TEXT_ALIGN_CENTER) - [ns_style setAlignment:NSCenterTextAlignment]; - // TODO(awalker): Implement the rest of the Canvas text flags - - NSDictionary* attributes = - [NSDictionary dictionaryWithObjectsAndKeys: - font.GetNativeFont(), NSFontAttributeName, - ns_color, NSForegroundColorAttributeName, - ns_style, NSParagraphStyleAttributeName, - nil]; - - NSAttributedString* ns_string = - [[[NSAttributedString alloc] initWithString:base::SysUTF16ToNSString(text) - attributes:attributes] autorelease]; - base::mac::ScopedCFTypeRef<CTFramesetterRef> framesetter( - CTFramesetterCreateWithAttributedString( - reinterpret_cast<CFAttributedStringRef>(ns_string))); - - CGRect text_bounds = CGRectMake(x, y, w, h); - CGMutablePathRef path = CGPathCreateMutable(); - CGPathAddRect(path, NULL, text_bounds); - - base::mac::ScopedCFTypeRef<CTFrameRef> frame( - CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL)); - CTFrameDraw(frame, context); - CGContextRestoreGState(context); - endPlatformPaint(); -} - -} // namespace gfx diff --git a/gfx/canvas_skia_paint.h b/gfx/canvas_skia_paint.h index 56c6d83..5d57184 100644 --- a/gfx/canvas_skia_paint.h +++ b/gfx/canvas_skia_paint.h @@ -6,16 +6,7 @@ #define GFX_CANVAS_SKIA_PAINT_H_ #pragma once -#include "gfx/canvas_skia.h" -#include "skia/ext/canvas_paint.h" - -// Define a gfx::CanvasSkiaPaint type that wraps our gfx::Canvas like the -// skia::PlatformCanvasPaint wraps PlatformCanvas. - -namespace gfx { - -typedef skia::CanvasPaintT<CanvasSkia> CanvasSkiaPaint; - -} // namespace gfx +#include "ui/gfx/canvas_skia_paint.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_CANVAS_SKIA_PAINT_H_ diff --git a/gfx/canvas_skia_win.cc b/gfx/canvas_skia_win.cc deleted file mode 100644 index 03186fa..0000000 --- a/gfx/canvas_skia_win.cc +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/canvas_skia.h" - -#include <limits> - -#include "base/i18n/rtl.h" -#include "gfx/font.h" -#include "gfx/rect.h" -#include "third_party/skia/include/core/SkShader.h" - -namespace { - -// We make sure that LTR text we draw in an RTL context is modified -// appropriately to make sure it maintains it LTR orientation. -void DoDrawText(HDC hdc, - const string16& text, - RECT* text_bounds, - int flags) { - // Only adjust string directionality if both of the following are true: - // 1. The current locale is RTL. - // 2. The string itself has RTL directionality. - const wchar_t* string_ptr = text.c_str(); - int string_size = static_cast<int>(text.length()); - - string16 localized_text; - if (flags & DT_RTLREADING) { - localized_text = text; - base::i18n::AdjustStringForLocaleDirection(&localized_text); - string_ptr = localized_text.c_str(); - string_size = static_cast<int>(localized_text.length()); - } - - DrawText(hdc, string_ptr, string_size, text_bounds, flags); -} - -// Compute the windows flags necessary to implement the provided text Canvas -// flags. -int ComputeFormatFlags(int flags, const string16& text) { - // Setting the text alignment explicitly in case it hasn't already been set. - // This will make sure that we don't align text to the left on RTL locales - // just because no alignment flag was passed to DrawStringInt(). - if (!(flags & (gfx::Canvas::TEXT_ALIGN_CENTER | - gfx::Canvas::TEXT_ALIGN_RIGHT | - gfx::Canvas::TEXT_ALIGN_LEFT))) { - flags |= gfx::CanvasSkia::DefaultCanvasTextAlignment(); - } - - // horizontal alignment - int f = 0; - if (flags & gfx::Canvas::TEXT_ALIGN_CENTER) - f |= DT_CENTER; - else if (flags & gfx::Canvas::TEXT_ALIGN_RIGHT) - f |= DT_RIGHT; - else - f |= DT_LEFT; - - // vertical alignment - if (flags & gfx::Canvas::TEXT_VALIGN_TOP) - f |= DT_TOP; - else if (flags & gfx::Canvas::TEXT_VALIGN_BOTTOM) - f |= DT_BOTTOM; - else - f |= DT_VCENTER; - - if (flags & gfx::Canvas::MULTI_LINE) { - f |= DT_WORDBREAK; - if (flags & gfx::Canvas::CHARACTER_BREAK) - f |= DT_EDITCONTROL; // Turns on character breaking (not documented) - else if (!(flags & gfx::Canvas::NO_ELLIPSIS)) - f |= DT_WORD_ELLIPSIS; - } else { - f |= DT_SINGLELINE; - } - - if (flags & gfx::Canvas::HIDE_PREFIX) - f |= DT_HIDEPREFIX; - else if ((flags & gfx::Canvas::SHOW_PREFIX) == 0) - f |= DT_NOPREFIX; - - if (!(flags & gfx::Canvas::NO_ELLIPSIS)) - f |= DT_END_ELLIPSIS; - - // In order to make sure RTL/BiDi strings are rendered correctly, we must - // pass the flag DT_RTLREADING to DrawText (when the locale's language is - // a right-to-left language) so that Windows does the right thing. - // - // In addition to correctly displaying text containing both RTL and LTR - // elements (for example, a string containing a telephone number within a - // sentence in Hebrew, or a sentence in Hebrew that contains a word in - // English) this flag also makes sure that if there is not enough space to - // display the entire string, the ellipsis is displayed on the left hand side - // of the truncated string and not on the right hand side. - // - // We make a distinction between Chrome UI strings and text coming from a web - // page. - // - // For text coming from a web page we determine the alignment based on the - // first character with strong directionality. If the directionality of the - // first character with strong directionality in the text is LTR, the - // alignment is set to DT_LEFT, and the directionality should not be set as - // DT_RTLREADING. - // - // This heuristic doesn't work for Chrome UI strings since even in RTL - // locales, some of those might start with English text but we know they're - // localized so we always want them to be right aligned, and their - // directionality should be set as DT_RTLREADING. - // - // Caveat: If the string is purely LTR, don't set DTL_RTLREADING since when - // the flag is set, LRE-PDF don't have the desired effect of rendering - // multiline English-only text as LTR. - // - // Note that if the caller is explicitly requesting displaying the text - // using RTL directionality then we respect that and pass DT_RTLREADING to - // ::DrawText even if the locale is LTR. - if ((flags & gfx::Canvas::FORCE_RTL_DIRECTIONALITY) || - (base::i18n::IsRTL() && - (f & DT_RIGHT) && base::i18n::StringContainsStrongRTLChars(text))) { - f |= DT_RTLREADING; - } - - return f; -} - -} // anonymous namespace - -namespace gfx { - -CanvasSkia::CanvasSkia(int width, int height, bool is_opaque) - : skia::PlatformCanvas(width, height, is_opaque) { -} - -CanvasSkia::CanvasSkia() : skia::PlatformCanvas() { -} - -CanvasSkia::~CanvasSkia() { -} - -// static -void CanvasSkia::SizeStringInt(const string16& text, - const gfx::Font& font, - int* width, int* height, - int flags) { - // Clamp the max amount of text we'll measure to 2K. When the string is - // actually drawn, it will be clipped to whatever size box is provided, and - // the time to do that doesn't depend on the length being clipped off. - const int kMaxStringLength = 2048 - 1; // So the trailing \0 fits in 2K. - string16 clamped_string(text.substr(0, kMaxStringLength)); - - if (*width == 0) { - // If multi-line + character break are on, the computed width will be one - // character wide (useless). Furthermore, if in this case the provided text - // contains very long "words" (substrings without a word-breaking point), - // DrawText() can run extremely slowly (e.g. several seconds). So in this - // case, we turn character breaking off to get a more accurate "desired" - // width and avoid the slowdown. - if (flags & (gfx::Canvas::MULTI_LINE | gfx::Canvas::CHARACTER_BREAK)) - flags &= ~gfx::Canvas::CHARACTER_BREAK; - - // Weird undocumented behavior: if the width is 0, DoDrawText() won't - // calculate a size at all. So set it to 1, which it will then change. - if (!text.empty()) - *width = 1; - } - RECT r = { 0, 0, *width, *height }; - - HDC dc = GetDC(NULL); - HFONT old_font = static_cast<HFONT>(SelectObject(dc, font.GetNativeFont())); - DoDrawText(dc, clamped_string, &r, - ComputeFormatFlags(flags, clamped_string) | DT_CALCRECT); - SelectObject(dc, old_font); - ReleaseDC(NULL, dc); - - *width = r.right; - *height = r.bottom; -} - -void CanvasSkia::DrawStringInt(const string16& text, - HFONT font, - const SkColor& color, - int x, int y, int w, int h, - int flags) { - if (!IntersectsClipRectInt(x, y, w, h)) - return; - - // Clamp the max amount of text we'll draw to 32K. There seem to be bugs in - // DrawText() if you e.g. ask it to character-break a no-whitespace string of - // length > 43680 (for which it draws nothing), and since we clamped to 2K in - // SizeStringInt() we're unlikely to be able to display this much anyway. - const int kMaxStringLength = 32768 - 1; // So the trailing \0 fits in 32K. - string16 clamped_string(text.substr(0, kMaxStringLength)); - - RECT text_bounds = { x, y, x + w, y + h }; - HDC dc = beginPlatformPaint(); - SetBkMode(dc, TRANSPARENT); - HFONT old_font = (HFONT)SelectObject(dc, font); - COLORREF brush_color = RGB(SkColorGetR(color), SkColorGetG(color), - SkColorGetB(color)); - SetTextColor(dc, brush_color); - - int f = ComputeFormatFlags(flags, clamped_string); - DoDrawText(dc, clamped_string, &text_bounds, f); - endPlatformPaint(); - - // Restore the old font. This way we don't have to worry if the caller - // deletes the font and the DC lives longer. - SelectObject(dc, old_font); - - // Windows will have cleared the alpha channel of the text we drew. Assume - // we're drawing to an opaque surface, or at least the text rect area is - // opaque. - getTopPlatformDevice().makeOpaque(x, y, w, h); -} - -void CanvasSkia::DrawStringInt(const string16& text, - const gfx::Font& font, - const SkColor& color, - int x, int y, int w, int h, - int flags) { - DrawStringInt(text, font.GetNativeFont(), 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 CanvasSkia::DrawStringWithHalo(const string16& text, - const gfx::Font& 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. - CanvasSkia text_canvas(w + 2, h + 2, true); - SkPaint bkgnd_paint; - bkgnd_paint.setColor(halo_color); - text_canvas.DrawRectInt(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. - DrawBitmapInt(text_bitmap, x - 1, y - 1); -} - -} // namespace gfx diff --git a/gfx/codec/DEPS b/gfx/codec/DEPS deleted file mode 100644 index e4907a6c..0000000 --- a/gfx/codec/DEPS +++ /dev/null @@ -1,5 +0,0 @@ -include_rules = [ - "+skia", - "+third_party/libjpeg", - "+third_party/libpng", -] diff --git a/gfx/codec/jpeg_codec.cc b/gfx/codec/jpeg_codec.cc deleted file mode 100644 index ad499e5..0000000 --- a/gfx/codec/jpeg_codec.cc +++ /dev/null @@ -1,535 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/codec/jpeg_codec.h" - -#include <setjmp.h> - -#include "base/logging.h" -#include "base/scoped_ptr.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkColorPriv.h" - -extern "C" { -#if defined(USE_SYSTEM_LIBJPEG) -#include <jpeglib.h> -#else -#include "jpeglib.h" -#endif -} - -namespace gfx { - -// Encoder/decoder shared stuff ------------------------------------------------ - -namespace { - -// used to pass error info through the JPEG library -struct CoderErrorMgr { - jpeg_error_mgr pub; - jmp_buf setjmp_buffer; -}; - -void ErrorExit(jpeg_common_struct* cinfo) { - CoderErrorMgr *err = reinterpret_cast<CoderErrorMgr*>(cinfo->err); - - // Return control to the setjmp point. - longjmp(err->setjmp_buffer, false); -} - -} // namespace - -// Encoder --------------------------------------------------------------------- -// -// This code is based on nsJPEGEncoder from Mozilla. -// Copyright 2005 Google Inc. (Brett Wilson, contributor) - -namespace { - -// Initial size for the output buffer in the JpegEncoderState below. -static const int initial_output_buffer_size = 8192; - -struct JpegEncoderState { - explicit JpegEncoderState(std::vector<unsigned char>* o) - : out(o), - image_buffer_used(0) { - } - - // Output buffer, of which 'image_buffer_used' bytes are actually used (this - // will often be less than the actual size of the vector because we size it - // so that libjpeg can write directly into it. - std::vector<unsigned char>* out; - - // Number of bytes in the 'out' buffer that are actually used (see above). - size_t image_buffer_used; -}; - -// Initializes the JpegEncoderState for encoding, and tells libjpeg about where -// the output buffer is. -// -// From the JPEG library: -// "Initialize destination. This is called by jpeg_start_compress() before -// any data is actually written. It must initialize next_output_byte and -// free_in_buffer. free_in_buffer must be initialized to a positive value." -void InitDestination(jpeg_compress_struct* cinfo) { - JpegEncoderState* state = static_cast<JpegEncoderState*>(cinfo->client_data); - DCHECK(state->image_buffer_used == 0) << "initializing after use"; - - state->out->resize(initial_output_buffer_size); - state->image_buffer_used = 0; - - cinfo->dest->next_output_byte = &(*state->out)[0]; - cinfo->dest->free_in_buffer = initial_output_buffer_size; -} - -// Resize the buffer that we give to libjpeg and update our and its state. -// -// From the JPEG library: -// "Callback used by libjpeg whenever the buffer has filled (free_in_buffer -// reaches zero). In typical applications, it should write out the *entire* -// buffer (use the saved start address and buffer length; ignore the current -// state of next_output_byte and free_in_buffer). Then reset the pointer & -// count to the start of the buffer, and return TRUE indicating that the -// buffer has been dumped. free_in_buffer must be set to a positive value -// when TRUE is returned. A FALSE return should only be used when I/O -// suspension is desired (this operating mode is discussed in the next -// section)." -boolean EmptyOutputBuffer(jpeg_compress_struct* cinfo) { - JpegEncoderState* state = static_cast<JpegEncoderState*>(cinfo->client_data); - - // note the new size, the buffer is full - state->image_buffer_used = state->out->size(); - - // expand buffer, just double size each time - state->out->resize(state->out->size() * 2); - - // tell libjpeg where to write the next data - cinfo->dest->next_output_byte = &(*state->out)[state->image_buffer_used]; - cinfo->dest->free_in_buffer = state->out->size() - state->image_buffer_used; - return 1; -} - -// Cleans up the JpegEncoderState to prepare for returning in the final form. -// -// From the JPEG library: -// "Terminate destination --- called by jpeg_finish_compress() after all data -// has been written. In most applications, this must flush any data -// remaining in the buffer. Use either next_output_byte or free_in_buffer to -// determine how much data is in the buffer." -void TermDestination(jpeg_compress_struct* cinfo) { - JpegEncoderState* state = static_cast<JpegEncoderState*>(cinfo->client_data); - DCHECK(state->out->size() >= state->image_buffer_used); - - // update the used byte based on the next byte libjpeg would write to - state->image_buffer_used = cinfo->dest->next_output_byte - &(*state->out)[0]; - DCHECK(state->image_buffer_used < state->out->size()) << - "JPEG library busted, got a bad image buffer size"; - - // update our buffer so that it exactly encompases the desired data - state->out->resize(state->image_buffer_used); -} - -// Converts RGBA to RGB (removing the alpha values) to prepare to send data to -// libjpeg. This converts one row of data in rgba with the given width in -// pixels the the given rgb destination buffer (which should have enough space -// reserved for the final data). -void StripAlpha(const unsigned char* rgba, int pixel_width, unsigned char* rgb) -{ - for (int x = 0; x < pixel_width; x++) { - const unsigned char* pixel_in = &rgba[x * 4]; - unsigned char* pixel_out = &rgb[x * 3]; - pixel_out[0] = pixel_in[0]; - pixel_out[1] = pixel_in[1]; - pixel_out[2] = pixel_in[2]; - } -} - -// Converts BGRA to RGB by reordering the color components and dropping the -// alpha. This converts one row of data in rgba with the given width in -// pixels the the given rgb destination buffer (which should have enough space -// reserved for the final data). -void BGRAtoRGB(const unsigned char* bgra, int pixel_width, unsigned char* rgb) -{ - for (int x = 0; x < pixel_width; x++) { - const unsigned char* pixel_in = &bgra[x * 4]; - unsigned char* pixel_out = &rgb[x * 3]; - pixel_out[0] = pixel_in[2]; - pixel_out[1] = pixel_in[1]; - pixel_out[2] = pixel_in[0]; - } -} - -// This class destroys the given jpeg_compress object when it goes out of -// scope. It simplifies the error handling in Encode (and even applies to the -// success case). -class CompressDestroyer { - public: - CompressDestroyer() : cinfo_(NULL) { - } - ~CompressDestroyer() { - DestroyManagedObject(); - } - void SetManagedObject(jpeg_compress_struct* ci) { - DestroyManagedObject(); - cinfo_ = ci; - } - void DestroyManagedObject() { - if (cinfo_) { - jpeg_destroy_compress(cinfo_); - cinfo_ = NULL; - } - } - private: - jpeg_compress_struct* cinfo_; -}; - -} // namespace - -bool JPEGCodec::Encode(const unsigned char* input, ColorFormat format, - int w, int h, int row_byte_width, - int quality, std::vector<unsigned char>* output) { - jpeg_compress_struct cinfo; - CompressDestroyer destroyer; - destroyer.SetManagedObject(&cinfo); - output->clear(); - - // We set up the normal JPEG error routines, then override error_exit. - // This must be done before the call to create_compress. - CoderErrorMgr errmgr; - cinfo.err = jpeg_std_error(&errmgr.pub); - errmgr.pub.error_exit = ErrorExit; - // Establish the setjmp return context for ErrorExit to use. - if (setjmp(errmgr.setjmp_buffer)) { - // If we get here, the JPEG code has signaled an error. - // MSDN notes: "if you intend your code to be portable, do not rely on - // correct destruction of frame-based objects when executing a nonlocal - // goto using a call to longjmp." So we delete the CompressDestroyer's - // object manually instead. - destroyer.DestroyManagedObject(); - return false; - } - - // The destroyer will destroy() cinfo on exit. - jpeg_create_compress(&cinfo); - - cinfo.image_width = w; - cinfo.image_height = h; - cinfo.input_components = 3; - cinfo.in_color_space = JCS_RGB; - cinfo.data_precision = 8; - - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, quality, 1); // quality here is 0-100 - - // set up the destination manager - jpeg_destination_mgr destmgr; - destmgr.init_destination = InitDestination; - destmgr.empty_output_buffer = EmptyOutputBuffer; - destmgr.term_destination = TermDestination; - cinfo.dest = &destmgr; - - JpegEncoderState state(output); - cinfo.client_data = &state; - - jpeg_start_compress(&cinfo, 1); - - // feed it the rows, doing necessary conversions for the color format - if (format == FORMAT_RGB) { - // no conversion necessary - while (cinfo.next_scanline < cinfo.image_height) { - const unsigned char* row = &input[cinfo.next_scanline * row_byte_width]; - jpeg_write_scanlines(&cinfo, const_cast<unsigned char**>(&row), 1); - } - } else { - // get the correct format converter - void (*converter)(const unsigned char* in, int w, unsigned char* rgb); - if (format == FORMAT_RGBA || - (format == FORMAT_SkBitmap && SK_R32_SHIFT == 0)) { - converter = StripAlpha; - } else if (format == FORMAT_BGRA || - (format == FORMAT_SkBitmap && SK_B32_SHIFT == 0)) { - converter = BGRAtoRGB; - } else { - NOTREACHED() << "Invalid pixel format"; - return false; - } - - // output row after converting - unsigned char* row = new unsigned char[w * 3]; - - while (cinfo.next_scanline < cinfo.image_height) { - converter(&input[cinfo.next_scanline * row_byte_width], w, row); - jpeg_write_scanlines(&cinfo, &row, 1); - } - delete[] row; - } - - jpeg_finish_compress(&cinfo); - return true; -} - -// Decoder -------------------------------------------------------------------- - -namespace { - -struct JpegDecoderState { - JpegDecoderState(const unsigned char* in, size_t len) - : input_buffer(in), input_buffer_length(len) { - } - - const unsigned char* input_buffer; - size_t input_buffer_length; -}; - -// Callback to initialize the source. -// -// From the JPEG library: -// "Initialize source. This is called by jpeg_read_header() before any data is -// actually read. May leave bytes_in_buffer set to 0 (in which case a -// fill_input_buffer() call will occur immediately)." -void InitSource(j_decompress_ptr cinfo) { - JpegDecoderState* state = static_cast<JpegDecoderState*>(cinfo->client_data); - cinfo->src->next_input_byte = state->input_buffer; - cinfo->src->bytes_in_buffer = state->input_buffer_length; -} - -// Callback to fill the buffer. Since our buffer already contains all the data, -// we should never need to provide more data. If libjpeg thinks it needs more -// data, our input is probably corrupt. -// -// From the JPEG library: -// "This is called whenever bytes_in_buffer has reached zero and more data is -// wanted. In typical applications, it should read fresh data into the buffer -// (ignoring the current state of next_input_byte and bytes_in_buffer), reset -// the pointer & count to the start of the buffer, and return TRUE indicating -// that the buffer has been reloaded. It is not necessary to fill the buffer -// entirely, only to obtain at least one more byte. bytes_in_buffer MUST be -// set to a positive value if TRUE is returned. A FALSE return should only -// be used when I/O suspension is desired." -boolean FillInputBuffer(j_decompress_ptr cinfo) { - return false; -} - -// Skip data in the buffer. Since we have all the data at once, this operation -// is easy. It is not clear if this ever gets called because the JPEG library -// should be able to do the skip itself (it has all the data). -// -// From the JPEG library: -// "Skip num_bytes worth of data. The buffer pointer and count should be -// advanced over num_bytes input bytes, refilling the buffer as needed. This -// is used to skip over a potentially large amount of uninteresting data -// (such as an APPn marker). In some applications it may be possible to -// optimize away the reading of the skipped data, but it's not clear that -// being smart is worth much trouble; large skips are uncommon. -// bytes_in_buffer may be zero on return. A zero or negative skip count -// should be treated as a no-op." -void SkipInputData(j_decompress_ptr cinfo, long num_bytes) { - if (num_bytes > static_cast<long>(cinfo->src->bytes_in_buffer)) { - // Since all our data should be in the buffer, trying to skip beyond it - // means that there is some kind of error or corrupt input data. A 0 for - // bytes left means it will call FillInputBuffer which will then fail. - cinfo->src->next_input_byte += cinfo->src->bytes_in_buffer; - cinfo->src->bytes_in_buffer = 0; - } else if (num_bytes > 0) { - cinfo->src->bytes_in_buffer -= static_cast<size_t>(num_bytes); - cinfo->src->next_input_byte += num_bytes; - } -} - -// Our source doesn't need any cleanup, so this is a NOP. -// -// From the JPEG library: -// "Terminate source --- called by jpeg_finish_decompress() after all data has -// been read to clean up JPEG source manager. NOT called by jpeg_abort() or -// jpeg_destroy()." -void TermSource(j_decompress_ptr cinfo) { -} - -// Converts one row of rgb data to rgba data by adding a fully-opaque alpha -// value. -void AddAlpha(const unsigned char* rgb, int pixel_width, unsigned char* rgba) { - for (int x = 0; x < pixel_width; x++) { - const unsigned char* pixel_in = &rgb[x * 3]; - unsigned char* pixel_out = &rgba[x * 4]; - pixel_out[0] = pixel_in[0]; - pixel_out[1] = pixel_in[1]; - pixel_out[2] = pixel_in[2]; - pixel_out[3] = 0xff; - } -} - -// Converts one row of RGB data to BGRA by reordering the color components and -// adding alpha values of 0xff. -void RGBtoBGRA(const unsigned char* bgra, int pixel_width, unsigned char* rgb) -{ - for (int x = 0; x < pixel_width; x++) { - const unsigned char* pixel_in = &bgra[x * 3]; - unsigned char* pixel_out = &rgb[x * 4]; - pixel_out[0] = pixel_in[2]; - pixel_out[1] = pixel_in[1]; - pixel_out[2] = pixel_in[0]; - pixel_out[3] = 0xff; - } -} - -// This class destroys the given jpeg_decompress object when it goes out of -// scope. It simplifies the error handling in Decode (and even applies to the -// success case). -class DecompressDestroyer { - public: - DecompressDestroyer() : cinfo_(NULL) { - } - ~DecompressDestroyer() { - DestroyManagedObject(); - } - void SetManagedObject(jpeg_decompress_struct* ci) { - DestroyManagedObject(); - cinfo_ = ci; - } - void DestroyManagedObject() { - if (cinfo_) { - jpeg_destroy_decompress(cinfo_); - cinfo_ = NULL; - } - } - private: - jpeg_decompress_struct* cinfo_; -}; - -} // namespace - -bool JPEGCodec::Decode(const unsigned char* input, size_t input_size, - ColorFormat format, std::vector<unsigned char>* output, - int* w, int* h) { - jpeg_decompress_struct cinfo; - DecompressDestroyer destroyer; - destroyer.SetManagedObject(&cinfo); - output->clear(); - - // We set up the normal JPEG error routines, then override error_exit. - // This must be done before the call to create_decompress. - CoderErrorMgr errmgr; - cinfo.err = jpeg_std_error(&errmgr.pub); - errmgr.pub.error_exit = ErrorExit; - // Establish the setjmp return context for ErrorExit to use. - if (setjmp(errmgr.setjmp_buffer)) { - // If we get here, the JPEG code has signaled an error. - // See note in JPEGCodec::Encode() for why we need to destroy the cinfo - // manually here. - destroyer.DestroyManagedObject(); - return false; - } - - // The destroyer will destroy() cinfo on exit. We don't want to set the - // destroyer's object until cinfo is initialized. - jpeg_create_decompress(&cinfo); - - // set up the source manager - jpeg_source_mgr srcmgr; - srcmgr.init_source = InitSource; - srcmgr.fill_input_buffer = FillInputBuffer; - srcmgr.skip_input_data = SkipInputData; - srcmgr.resync_to_restart = jpeg_resync_to_restart; // use default routine - srcmgr.term_source = TermSource; - cinfo.src = &srcmgr; - - JpegDecoderState state(input, input_size); - cinfo.client_data = &state; - - // fill the file metadata into our buffer - if (jpeg_read_header(&cinfo, true) != JPEG_HEADER_OK) - return false; - - // we want to always get RGB data out - switch (cinfo.jpeg_color_space) { - case JCS_GRAYSCALE: - case JCS_RGB: - case JCS_YCbCr: - cinfo.out_color_space = JCS_RGB; - break; - case JCS_CMYK: - case JCS_YCCK: - default: - // Mozilla errors out on these color spaces, so I presume that the jpeg - // library can't do automatic color space conversion for them. We don't - // care about these anyway. - return false; - } - cinfo.output_components = 3; - - jpeg_calc_output_dimensions(&cinfo); - *w = cinfo.output_width; - *h = cinfo.output_height; - - jpeg_start_decompress(&cinfo); - - // FIXME(brettw) we may want to allow the capability for callers to request - // how to align row lengths as we do for the compressor. - int row_read_stride = cinfo.output_width * cinfo.output_components; - - if (format == FORMAT_RGB) { - // easy case, row needs no conversion - int row_write_stride = row_read_stride; - output->resize(row_write_stride * cinfo.output_height); - - for (int row = 0; row < static_cast<int>(cinfo.output_height); row++) { - unsigned char* rowptr = &(*output)[row * row_write_stride]; - if (!jpeg_read_scanlines(&cinfo, &rowptr, 1)) - return false; - } - } else { - // Rows need conversion to output format: read into a temporary buffer and - // expand to the final one. Performance: we could avoid the extra - // allocation by doing the expansion in-place. - int row_write_stride; - void (*converter)(const unsigned char* rgb, int w, unsigned char* out); - if (format == FORMAT_RGBA || - (format == FORMAT_SkBitmap && SK_R32_SHIFT == 0)) { - row_write_stride = cinfo.output_width * 4; - converter = AddAlpha; - } else if (format == FORMAT_BGRA || - (format == FORMAT_SkBitmap && SK_B32_SHIFT == 0)) { - row_write_stride = cinfo.output_width * 4; - converter = RGBtoBGRA; - } else { - NOTREACHED() << "Invalid pixel format"; - jpeg_destroy_decompress(&cinfo); - return false; - } - - output->resize(row_write_stride * cinfo.output_height); - - scoped_array<unsigned char> row_data(new unsigned char[row_read_stride]); - unsigned char* rowptr = row_data.get(); - for (int row = 0; row < static_cast<int>(cinfo.output_height); row++) { - if (!jpeg_read_scanlines(&cinfo, &rowptr, 1)) - return false; - converter(rowptr, *w, &(*output)[row * row_write_stride]); - } - } - - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - return true; -} - -// static -SkBitmap* JPEGCodec::Decode(const unsigned char* input, size_t input_size) { - int w, h; - std::vector<unsigned char> data_vector; - if (!Decode(input, input_size, FORMAT_SkBitmap, &data_vector, &w, &h)) - return NULL; - - // Skia only handles 32 bit images. - int data_length = w * h * 4; - - SkBitmap* bitmap = new SkBitmap(); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, w, h); - bitmap->allocPixels(); - memcpy(bitmap->getAddr32(0, 0), &data_vector[0], data_length); - - return bitmap; -} - -} // namespace gfx diff --git a/gfx/codec/jpeg_codec_unittest.cc b/gfx/codec/jpeg_codec_unittest.cc deleted file mode 100644 index 16fc848..0000000 --- a/gfx/codec/jpeg_codec_unittest.cc +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <math.h> - -#include "gfx/codec/jpeg_codec.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace gfx { - -// out of 100, this indicates how compressed it will be, this should be changed -// with jpeg equality threshold -// static int jpeg_quality = 75; // FIXME(brettw) -static int jpeg_quality = 100; - -// The threshold of average color differences where we consider two images -// equal. This number was picked to be a little above the observed difference -// using the above quality. -static double jpeg_equality_threshold = 1.0; - -// Computes the average difference between each value in a and b. A and b -// should be the same size. Used to see if two images are approximately equal -// in the presence of compression. -static double AveragePixelDelta(const std::vector<unsigned char>& a, - const std::vector<unsigned char>& b) { - // if the sizes are different, say the average difference is the maximum - if (a.size() != b.size()) - return 255.0; - if (a.size() == 0) - return 0; // prevent divide by 0 below - - double acc = 0.0; - for (size_t i = 0; i < a.size(); i++) - acc += fabs(static_cast<double>(a[i]) - static_cast<double>(b[i])); - - return acc / static_cast<double>(a.size()); -} - -static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) { - dat->resize(w * h * 3); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - unsigned char* org_px = &(*dat)[(y * w + x) * 3]; - org_px[0] = x * 3; // r - org_px[1] = x * 3 + 1; // g - org_px[2] = x * 3 + 2; // b - } - } -} - -TEST(JPEGCodec, EncodeDecodeRGB) { - int w = 20, h = 20; - - // create an image with known values - std::vector<unsigned char> original; - MakeRGBImage(w, h, &original); - - // encode, making sure it was compressed some - std::vector<unsigned char> encoded; - EXPECT_TRUE(JPEGCodec::Encode(&original[0], JPEGCodec::FORMAT_RGB, w, h, - w * 3, jpeg_quality, &encoded)); - EXPECT_GT(original.size(), encoded.size()); - - // decode, it should have the same size as the original - std::vector<unsigned char> decoded; - int outw, outh; - EXPECT_TRUE(JPEGCodec::Decode(&encoded[0], encoded.size(), - JPEGCodec::FORMAT_RGB, &decoded, - &outw, &outh)); - ASSERT_EQ(w, outw); - ASSERT_EQ(h, outh); - ASSERT_EQ(original.size(), decoded.size()); - - // Images must be approximately equal (compression will have introduced some - // minor artifacts). - ASSERT_GE(jpeg_equality_threshold, AveragePixelDelta(original, decoded)); -} - -TEST(JPEGCodec, EncodeDecodeRGBA) { - int w = 20, h = 20; - - // create an image with known values, a must be opaque because it will be - // lost during compression - std::vector<unsigned char> original; - original.resize(w * h * 4); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - unsigned char* org_px = &original[(y * w + x) * 4]; - org_px[0] = x * 3; // r - org_px[1] = x * 3 + 1; // g - org_px[2] = x * 3 + 2; // b - org_px[3] = 0xFF; // a (opaque) - } - } - - // encode, making sure it was compressed some - std::vector<unsigned char> encoded; - EXPECT_TRUE(JPEGCodec::Encode(&original[0], JPEGCodec::FORMAT_RGBA, w, h, - w * 4, jpeg_quality, &encoded)); - EXPECT_GT(original.size(), encoded.size()); - - // decode, it should have the same size as the original - std::vector<unsigned char> decoded; - int outw, outh; - EXPECT_TRUE(JPEGCodec::Decode(&encoded[0], encoded.size(), - JPEGCodec::FORMAT_RGBA, &decoded, - &outw, &outh)); - ASSERT_EQ(w, outw); - ASSERT_EQ(h, outh); - ASSERT_EQ(original.size(), decoded.size()); - - // Images must be approximately equal (compression will have introduced some - // minor artifacts). - ASSERT_GE(jpeg_equality_threshold, AveragePixelDelta(original, decoded)); -} - -// Test that corrupted data decompression causes failures. -TEST(JPEGCodec, DecodeCorrupted) { - int w = 20, h = 20; - - // some random data (an uncompressed image) - std::vector<unsigned char> original; - MakeRGBImage(w, h, &original); - - // it should fail when given non-JPEG compressed data - std::vector<unsigned char> output; - int outw, outh; - ASSERT_FALSE(JPEGCodec::Decode(&original[0], original.size(), - JPEGCodec::FORMAT_RGB, &output, - &outw, &outh)); - - // make some compressed data - std::vector<unsigned char> compressed; - ASSERT_TRUE(JPEGCodec::Encode(&original[0], JPEGCodec::FORMAT_RGB, w, h, - w * 3, jpeg_quality, &compressed)); - - // try decompressing a truncated version - ASSERT_FALSE(JPEGCodec::Decode(&compressed[0], compressed.size() / 2, - JPEGCodec::FORMAT_RGB, &output, - &outw, &outh)); - - // corrupt it and try decompressing that - for (int i = 10; i < 30; i++) - compressed[i] = i; - ASSERT_FALSE(JPEGCodec::Decode(&compressed[0], compressed.size(), - JPEGCodec::FORMAT_RGB, &output, - &outw, &outh)); -} - -} // namespace gfx diff --git a/gfx/codec/png_codec.cc b/gfx/codec/png_codec.cc deleted file mode 100644 index 5fd6d7a..0000000 --- a/gfx/codec/png_codec.cc +++ /dev/null @@ -1,699 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/codec/png_codec.h" - -#include "base/logging.h" -#include "base/scoped_ptr.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkUnPreMultiply.h" -#include "third_party/skia/include/core/SkColorPriv.h" - -extern "C" { -#if defined(USE_SYSTEM_LIBPNG) -#include <png.h> -#else -#include "third_party/libpng/png.h" -#endif -} - -namespace gfx { - -namespace { - -// Converts BGRA->RGBA and RGBA->BGRA. -void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width, - unsigned char* output, bool* is_opaque) { - for (int x = 0; x < pixel_width; x++) { - const unsigned char* pixel_in = &input[x * 4]; - unsigned char* pixel_out = &output[x * 4]; - pixel_out[0] = pixel_in[2]; - pixel_out[1] = pixel_in[1]; - pixel_out[2] = pixel_in[0]; - pixel_out[3] = pixel_in[3]; - } -} - -void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width, - unsigned char* rgb, bool* is_opaque) { - for (int x = 0; x < pixel_width; x++) { - const unsigned char* pixel_in = &rgba[x * 4]; - unsigned char* pixel_out = &rgb[x * 3]; - pixel_out[0] = pixel_in[0]; - pixel_out[1] = pixel_in[1]; - pixel_out[2] = pixel_in[2]; - } -} - -void ConvertRGBtoSkia(const unsigned char* rgb, int pixel_width, - unsigned char* rgba, bool* is_opaque) { - for (int x = 0; x < pixel_width; x++) { - const unsigned char* pixel_in = &rgb[x * 3]; - uint32_t* pixel_out = reinterpret_cast<uint32_t*>(&rgba[x * 4]); - *pixel_out = SkPackARGB32(0xFF, pixel_in[0], pixel_in[1], pixel_in[2]); - } -} - -void ConvertRGBAtoSkia(const unsigned char* rgb, int pixel_width, - unsigned char* rgba, bool* is_opaque) { - int total_length = pixel_width * 4; - for (int x = 0; x < total_length; x += 4) { - const unsigned char* pixel_in = &rgb[x]; - uint32_t* pixel_out = reinterpret_cast<uint32_t*>(&rgba[x]); - - unsigned char alpha = pixel_in[3]; - if (alpha != 255) { - *is_opaque = false; - *pixel_out = SkPreMultiplyARGB(alpha, - pixel_in[0], pixel_in[1], pixel_in[2]); - } else { - *pixel_out = SkPackARGB32(alpha, - pixel_in[0], pixel_in[1], pixel_in[2]); - } - } -} - -void ConvertSkiatoRGB(const unsigned char* skia, int pixel_width, - unsigned char* rgb, bool* is_opaque) { - for (int x = 0; x < pixel_width; x++) { - const uint32_t pixel_in = *reinterpret_cast<const uint32_t*>(&skia[x * 4]); - unsigned char* pixel_out = &rgb[x * 3]; - - int alpha = SkGetPackedA32(pixel_in); - if (alpha != 0 && alpha != 255) { - SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel_in); - pixel_out[0] = SkColorGetR(unmultiplied); - pixel_out[1] = SkColorGetG(unmultiplied); - pixel_out[2] = SkColorGetB(unmultiplied); - } else { - pixel_out[0] = SkGetPackedR32(pixel_in); - pixel_out[1] = SkGetPackedG32(pixel_in); - pixel_out[2] = SkGetPackedB32(pixel_in); - } - } -} - -void ConvertSkiatoRGBA(const unsigned char* skia, int pixel_width, - unsigned char* rgba, bool* is_opaque) { - int total_length = pixel_width * 4; - for (int i = 0; i < total_length; i += 4) { - const uint32_t pixel_in = *reinterpret_cast<const uint32_t*>(&skia[i]); - - // Pack the components here. - int alpha = SkGetPackedA32(pixel_in); - if (alpha != 0 && alpha != 255) { - SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel_in); - rgba[i + 0] = SkColorGetR(unmultiplied); - rgba[i + 1] = SkColorGetG(unmultiplied); - rgba[i + 2] = SkColorGetB(unmultiplied); - rgba[i + 3] = alpha; - } else { - rgba[i + 0] = SkGetPackedR32(pixel_in); - rgba[i + 1] = SkGetPackedG32(pixel_in); - rgba[i + 2] = SkGetPackedB32(pixel_in); - rgba[i + 3] = alpha; - } - } -} - -} // namespace - -// Decoder -------------------------------------------------------------------- -// -// This code is based on WebKit libpng interface (PNGImageDecoder), which is -// in turn based on the Mozilla png decoder. - -namespace { - -// Gamma constants: We assume we're on Windows which uses a gamma of 2.2. -const double kMaxGamma = 21474.83; // Maximum gamma accepted by png library. -const double kDefaultGamma = 2.2; -const double kInverseGamma = 1.0 / kDefaultGamma; - -class PngDecoderState { - public: - // Output is a vector<unsigned char>. - PngDecoderState(PNGCodec::ColorFormat ofmt, std::vector<unsigned char>* o) - : output_format(ofmt), - output_channels(0), - bitmap(NULL), - is_opaque(true), - output(o), - row_converter(NULL), - width(0), - height(0), - done(false) { - } - - // Output is an SkBitmap. - explicit PngDecoderState(SkBitmap* skbitmap) - : output_format(PNGCodec::FORMAT_SkBitmap), - output_channels(0), - bitmap(skbitmap), - is_opaque(true), - output(NULL), - row_converter(NULL), - width(0), - height(0), - done(false) { - } - - PNGCodec::ColorFormat output_format; - int output_channels; - - // An incoming SkBitmap to write to. If NULL, we write to output instead. - SkBitmap* bitmap; - - // Used during the reading of an SkBitmap. Defaults to true until we see a - // pixel with anything other than an alpha of 255. - bool is_opaque; - - // The other way to decode output, where we write into an intermediary buffer - // instead of directly to an SkBitmap. - std::vector<unsigned char>* output; - - // Called to convert a row from the library to the correct output format. - // When NULL, no conversion is necessary. - void (*row_converter)(const unsigned char* in, int w, unsigned char* out, - bool* is_opaque); - - // Size of the image, set in the info callback. - int width; - int height; - - // Set to true when we've found the end of the data. - bool done; - - private: - DISALLOW_COPY_AND_ASSIGN(PngDecoderState); -}; - -void ConvertRGBtoRGBA(const unsigned char* rgb, int pixel_width, - unsigned char* rgba, bool* is_opaque) { - for (int x = 0; x < pixel_width; x++) { - const unsigned char* pixel_in = &rgb[x * 3]; - unsigned char* pixel_out = &rgba[x * 4]; - pixel_out[0] = pixel_in[0]; - pixel_out[1] = pixel_in[1]; - pixel_out[2] = pixel_in[2]; - pixel_out[3] = 0xff; - } -} - -void ConvertRGBtoBGRA(const unsigned char* rgb, int pixel_width, - unsigned char* bgra, bool* is_opaque) { - for (int x = 0; x < pixel_width; x++) { - const unsigned char* pixel_in = &rgb[x * 3]; - unsigned char* pixel_out = &bgra[x * 4]; - pixel_out[0] = pixel_in[2]; - pixel_out[1] = pixel_in[1]; - pixel_out[2] = pixel_in[0]; - pixel_out[3] = 0xff; - } -} - -// Called when the png header has been read. This code is based on the WebKit -// PNGImageDecoder -void DecodeInfoCallback(png_struct* png_ptr, png_info* info_ptr) { - PngDecoderState* state = static_cast<PngDecoderState*>( - png_get_progressive_ptr(png_ptr)); - - int bit_depth, color_type, interlace_type, compression_type; - int filter_type, channels; - png_uint_32 w, h; - png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, - &interlace_type, &compression_type, &filter_type); - - // Bounds check. When the image is unreasonably big, we'll error out and - // end up back at the setjmp call when we set up decoding. "Unreasonably big" - // means "big enough that w * h * 32bpp might overflow an int"; we choose this - // threshold to match WebKit and because a number of places in code assume - // that an image's size (in bytes) fits in a (signed) int. - unsigned long long total_size = - static_cast<unsigned long long>(w) * static_cast<unsigned long long>(h); - if (total_size > ((1 << 29) - 1)) - longjmp(png_jmpbuf(png_ptr), 1); - state->width = static_cast<int>(w); - state->height = static_cast<int>(h); - - // Expand to ensure we use 24-bit for RGB and 32-bit for RGBA. - if (color_type == PNG_COLOR_TYPE_PALETTE || - (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)) - png_set_expand(png_ptr); - - // Transparency for paletted images. - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) - png_set_expand(png_ptr); - - // Convert 16-bit to 8-bit. - if (bit_depth == 16) - png_set_strip_16(png_ptr); - - // Expand grayscale to RGB. - if (color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(png_ptr); - - // Deal with gamma and keep it under our control. - double gamma; - if (png_get_gAMA(png_ptr, info_ptr, &gamma)) { - if (gamma <= 0.0 || gamma > kMaxGamma) { - gamma = kInverseGamma; - png_set_gAMA(png_ptr, info_ptr, gamma); - } - png_set_gamma(png_ptr, kDefaultGamma, gamma); - } else { - png_set_gamma(png_ptr, kDefaultGamma, kInverseGamma); - } - - // Tell libpng to send us rows for interlaced pngs. - if (interlace_type == PNG_INTERLACE_ADAM7) - png_set_interlace_handling(png_ptr); - - // Update our info now - png_read_update_info(png_ptr, info_ptr); - channels = png_get_channels(png_ptr, info_ptr); - - // Pick our row format converter necessary for this data. - if (channels == 3) { - switch (state->output_format) { - case PNGCodec::FORMAT_RGB: - state->row_converter = NULL; // no conversion necessary - state->output_channels = 3; - break; - case PNGCodec::FORMAT_RGBA: - state->row_converter = &ConvertRGBtoRGBA; - state->output_channels = 4; - break; - case PNGCodec::FORMAT_BGRA: - state->row_converter = &ConvertRGBtoBGRA; - state->output_channels = 4; - break; - case PNGCodec::FORMAT_SkBitmap: - state->row_converter = &ConvertRGBtoSkia; - state->output_channels = 4; - break; - default: - NOTREACHED() << "Unknown output format"; - break; - } - } else if (channels == 4) { - switch (state->output_format) { - case PNGCodec::FORMAT_RGB: - state->row_converter = &ConvertRGBAtoRGB; - state->output_channels = 3; - break; - case PNGCodec::FORMAT_RGBA: - state->row_converter = NULL; // no conversion necessary - state->output_channels = 4; - break; - case PNGCodec::FORMAT_BGRA: - state->row_converter = &ConvertBetweenBGRAandRGBA; - state->output_channels = 4; - break; - case PNGCodec::FORMAT_SkBitmap: - state->row_converter = &ConvertRGBAtoSkia; - state->output_channels = 4; - break; - default: - NOTREACHED() << "Unknown output format"; - break; - } - } else { - NOTREACHED() << "Unknown input channels"; - longjmp(png_jmpbuf(png_ptr), 1); - } - - if (state->bitmap) { - state->bitmap->setConfig(SkBitmap::kARGB_8888_Config, - state->width, state->height); - state->bitmap->allocPixels(); - } else if (state->output) { - state->output->resize( - state->width * state->output_channels * state->height); - } -} - -void DecodeRowCallback(png_struct* png_ptr, png_byte* new_row, - png_uint_32 row_num, int pass) { - PngDecoderState* state = static_cast<PngDecoderState*>( - png_get_progressive_ptr(png_ptr)); - - DCHECK(pass == 0) << "We didn't turn on interlace handling, but libpng is " - "giving us interlaced data."; - if (static_cast<int>(row_num) > state->height) { - NOTREACHED() << "Invalid row"; - return; - } - - unsigned char* base = NULL; - if (state->bitmap) - base = reinterpret_cast<unsigned char*>(state->bitmap->getAddr32(0, 0)); - else if (state->output) - base = &state->output->front(); - - unsigned char* dest = &base[state->width * state->output_channels * row_num]; - if (state->row_converter) - state->row_converter(new_row, state->width, dest, &state->is_opaque); - else - memcpy(dest, new_row, state->width * state->output_channels); -} - -void DecodeEndCallback(png_struct* png_ptr, png_info* info) { - PngDecoderState* state = static_cast<PngDecoderState*>( - png_get_progressive_ptr(png_ptr)); - - // Mark the image as complete, this will tell the Decode function that we - // have successfully found the end of the data. - state->done = true; -} - -// Automatically destroys the given read structs on destruction to make -// cleanup and error handling code cleaner. -class PngReadStructDestroyer { - public: - PngReadStructDestroyer(png_struct** ps, png_info** pi) : ps_(ps), pi_(pi) { - } - ~PngReadStructDestroyer() { - png_destroy_read_struct(ps_, pi_, NULL); - } - private: - png_struct** ps_; - png_info** pi_; -}; - -bool BuildPNGStruct(const unsigned char* input, size_t input_size, - png_struct** png_ptr, png_info** info_ptr) { - if (input_size < 8) - return false; // Input data too small to be a png - - // Have libpng check the signature, it likes the first 8 bytes. - if (png_sig_cmp(const_cast<unsigned char*>(input), 0, 8) != 0) - return false; - - *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!*png_ptr) - return false; - - *info_ptr = png_create_info_struct(*png_ptr); - if (!*info_ptr) { - png_destroy_read_struct(png_ptr, NULL, NULL); - return false; - } - - return true; -} - -} // namespace - -// static -bool PNGCodec::Decode(const unsigned char* input, size_t input_size, - ColorFormat format, std::vector<unsigned char>* output, - int* w, int* h) { - png_struct* png_ptr = NULL; - png_info* info_ptr = NULL; - if (!BuildPNGStruct(input, input_size, &png_ptr, &info_ptr)) - return false; - - PngReadStructDestroyer destroyer(&png_ptr, &info_ptr); - if (setjmp(png_jmpbuf(png_ptr))) { - // The destroyer will ensure that the structures are cleaned up in this - // case, even though we may get here as a jump from random parts of the - // PNG library called below. - return false; - } - - PngDecoderState state(format, output); - - png_set_progressive_read_fn(png_ptr, &state, &DecodeInfoCallback, - &DecodeRowCallback, &DecodeEndCallback); - png_process_data(png_ptr, - info_ptr, - const_cast<unsigned char*>(input), - input_size); - - if (!state.done) { - // Fed it all the data but the library didn't think we got all the data, so - // this file must be truncated. - output->clear(); - return false; - } - - *w = state.width; - *h = state.height; - return true; -} - -// static -bool PNGCodec::Decode(const unsigned char* input, size_t input_size, - SkBitmap* bitmap) { - DCHECK(bitmap); - png_struct* png_ptr = NULL; - png_info* info_ptr = NULL; - if (!BuildPNGStruct(input, input_size, &png_ptr, &info_ptr)) - return false; - - PngReadStructDestroyer destroyer(&png_ptr, &info_ptr); - if (setjmp(png_jmpbuf(png_ptr))) { - // The destroyer will ensure that the structures are cleaned up in this - // case, even though we may get here as a jump from random parts of the - // PNG library called below. - return false; - } - - PngDecoderState state(bitmap); - - png_set_progressive_read_fn(png_ptr, &state, &DecodeInfoCallback, - &DecodeRowCallback, &DecodeEndCallback); - png_process_data(png_ptr, - info_ptr, - const_cast<unsigned char*>(input), - input_size); - - if (!state.done) { - return false; - } - - // Set the bitmap's opaqueness based on what we saw. - bitmap->setIsOpaque(state.is_opaque); - - return true; -} - -// static -SkBitmap* PNGCodec::CreateSkBitmapFromBGRAFormat( - std::vector<unsigned char>& bgra, int width, int height) { - SkBitmap* bitmap = new SkBitmap(); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); - bitmap->allocPixels(); - - bool opaque = false; - unsigned char* bitmap_data = - reinterpret_cast<unsigned char*>(bitmap->getAddr32(0, 0)); - for (int i = width * height * 4 - 4; i >= 0; i -= 4) { - unsigned char alpha = bgra[i + 3]; - if (!opaque && alpha != 255) { - opaque = false; - } - bitmap_data[i + 3] = alpha; - bitmap_data[i] = (bgra[i] * alpha) >> 8; - bitmap_data[i + 1] = (bgra[i + 1] * alpha) >> 8; - bitmap_data[i + 2] = (bgra[i + 2] * alpha) >> 8; - } - - bitmap->setIsOpaque(opaque); - return bitmap; -} - -// Encoder -------------------------------------------------------------------- -// -// This section of the code is based on nsPNGEncoder.cpp in Mozilla -// (Copyright 2005 Google Inc.) - -namespace { - -// Passed around as the io_ptr in the png structs so our callbacks know where -// to write data. -struct PngEncoderState { - explicit PngEncoderState(std::vector<unsigned char>* o) : out(o) {} - std::vector<unsigned char>* out; -}; - -// Called by libpng to flush its internal buffer to ours. -void EncoderWriteCallback(png_structp png, png_bytep data, png_size_t size) { - PngEncoderState* state = static_cast<PngEncoderState*>(png_get_io_ptr(png)); - DCHECK(state->out); - - size_t old_size = state->out->size(); - state->out->resize(old_size + size); - memcpy(&(*state->out)[old_size], data, size); -} - -void FakeFlushCallback(png_structp png) { - // We don't need to perform any flushing since we aren't doing real IO, but - // we're required to provide this function by libpng. -} - -void ConvertBGRAtoRGB(const unsigned char* bgra, int pixel_width, - unsigned char* rgb, bool* is_opaque) { - for (int x = 0; x < pixel_width; x++) { - const unsigned char* pixel_in = &bgra[x * 4]; - unsigned char* pixel_out = &rgb[x * 3]; - pixel_out[0] = pixel_in[2]; - pixel_out[1] = pixel_in[1]; - pixel_out[2] = pixel_in[0]; - } -} - -// The type of functions usable for converting between pixel formats. -typedef void (*FormatConverter)(const unsigned char* in, int w, - unsigned char* out, bool* is_opaque); - -// libpng uses a wacky setjmp-based API, which makes the compiler nervous. -// We constrain all of the calls we make to libpng where the setjmp() is in -// place to this function. -// Returns true on success. -bool DoLibpngWrite(png_struct* png_ptr, png_info* info_ptr, - PngEncoderState* state, - int width, int height, int row_byte_width, - const unsigned char* input, - int png_output_color_type, int output_color_components, - FormatConverter converter) { - // Make sure to not declare any locals here -- locals in the presence - // of setjmp() in C++ code makes gcc complain. - - if (setjmp(png_jmpbuf(png_ptr))) - return false; - - // Set our callback for libpng to give us the data. - png_set_write_fn(png_ptr, state, EncoderWriteCallback, FakeFlushCallback); - - png_set_IHDR(png_ptr, info_ptr, width, height, 8, png_output_color_type, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png_ptr, info_ptr); - - if (!converter) { - // No conversion needed, give the data directly to libpng. - for (int y = 0; y < height; y ++) { - png_write_row(png_ptr, - const_cast<unsigned char*>(&input[y * row_byte_width])); - } - } else { - // Needs conversion using a separate buffer. - unsigned char* row = new unsigned char[width * output_color_components]; - for (int y = 0; y < height; y ++) { - converter(&input[y * row_byte_width], width, row, NULL); - png_write_row(png_ptr, row); - } - delete[] row; - } - - png_write_end(png_ptr, info_ptr); - return true; -} - -} // namespace - -// static -bool PNGCodec::Encode(const unsigned char* input, ColorFormat format, - int w, int h, int row_byte_width, - bool discard_transparency, - std::vector<unsigned char>* output) { - // Run to convert an input row into the output row format, NULL means no - // conversion is necessary. - FormatConverter converter = NULL; - - int input_color_components, output_color_components; - int png_output_color_type; - switch (format) { - case FORMAT_RGB: - input_color_components = 3; - output_color_components = 3; - png_output_color_type = PNG_COLOR_TYPE_RGB; - discard_transparency = false; - break; - - case FORMAT_RGBA: - input_color_components = 4; - if (discard_transparency) { - output_color_components = 3; - png_output_color_type = PNG_COLOR_TYPE_RGB; - converter = ConvertRGBAtoRGB; - } else { - output_color_components = 4; - png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; - converter = NULL; - } - break; - - case FORMAT_BGRA: - input_color_components = 4; - if (discard_transparency) { - output_color_components = 3; - png_output_color_type = PNG_COLOR_TYPE_RGB; - converter = ConvertBGRAtoRGB; - } else { - output_color_components = 4; - png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; - converter = ConvertBetweenBGRAandRGBA; - } - break; - - case FORMAT_SkBitmap: - input_color_components = 4; - if (discard_transparency) { - output_color_components = 3; - png_output_color_type = PNG_COLOR_TYPE_RGB; - converter = ConvertSkiatoRGB; - } else { - output_color_components = 4; - png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; - converter = ConvertSkiatoRGBA; - } - break; - - default: - NOTREACHED() << "Unknown pixel format"; - return false; - } - - // Row stride should be at least as long as the length of the data. - DCHECK(input_color_components * w <= row_byte_width); - - png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL); - if (!png_ptr) - return false; - png_info* info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, NULL); - return false; - } - - PngEncoderState state(output); - bool success = DoLibpngWrite(png_ptr, info_ptr, &state, - w, h, row_byte_width, input, - png_output_color_type, output_color_components, - converter); - png_destroy_write_struct(&png_ptr, &info_ptr); - - return success; -} - -// static -bool PNGCodec::EncodeBGRASkBitmap(const SkBitmap& input, - bool discard_transparency, - std::vector<unsigned char>* output) { - static const int bbp = 4; - - SkAutoLockPixels lock_input(input); - DCHECK(input.empty() || input.bytesPerPixel() == bbp); - - return Encode(reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)), - FORMAT_SkBitmap, input.width(), input.height(), - input.width() * bbp, discard_transparency, output); -} - -} // namespace gfx diff --git a/gfx/codec/png_codec_unittest.cc b/gfx/codec/png_codec_unittest.cc deleted file mode 100644 index 19d1f19..0000000 --- a/gfx/codec/png_codec_unittest.cc +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <math.h> - -#include "gfx/codec/png_codec.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkUnPreMultiply.h" - -namespace gfx { - -static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) { - dat->resize(w * h * 3); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - unsigned char* org_px = &(*dat)[(y * w + x) * 3]; - org_px[0] = x * 3; // r - org_px[1] = x * 3 + 1; // g - org_px[2] = x * 3 + 2; // b - } - } -} - -// Set use_transparency to write data into the alpha channel, otherwise it will -// be filled with 0xff. With the alpha channel stripped, this should yield the -// same image as MakeRGBImage above, so the code below can make reference -// images for conversion testing. -static void MakeRGBAImage(int w, int h, bool use_transparency, - std::vector<unsigned char>* dat) { - dat->resize(w * h * 4); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - unsigned char* org_px = &(*dat)[(y * w + x) * 4]; - org_px[0] = x * 3; // r - org_px[1] = x * 3 + 1; // g - org_px[2] = x * 3 + 2; // b - if (use_transparency) - org_px[3] = x*3 + 3; // a - else - org_px[3] = 0xFF; // a (opaque) - } - } -} - -// Returns true if each channel of the given two colors are "close." This is -// used for comparing colors where rounding errors may cause off-by-one. -bool ColorsClose(uint32_t a, uint32_t b) { - return abs(static_cast<int>(SkColorGetB(a) - SkColorGetB(b))) < 2 && - abs(static_cast<int>(SkColorGetG(a) - SkColorGetG(b))) < 2 && - abs(static_cast<int>(SkColorGetR(a) - SkColorGetR(b))) < 2 && - abs(static_cast<int>(SkColorGetA(a) - SkColorGetA(b))) < 2; -} - -// Returns true if the RGB components are "close." -bool NonAlphaColorsClose(uint32_t a, uint32_t b) { - return abs(static_cast<int>(SkColorGetB(a) - SkColorGetB(b))) < 2 && - abs(static_cast<int>(SkColorGetG(a) - SkColorGetG(b))) < 2 && - abs(static_cast<int>(SkColorGetR(a) - SkColorGetR(b))) < 2; -} - -void MakeTestSkBitmap(int w, int h, SkBitmap* bmp) { - bmp->setConfig(SkBitmap::kARGB_8888_Config, w, h); - bmp->allocPixels(); - - uint32_t* src_data = bmp->getAddr32(0, 0); - for (int i = 0; i < w * h; i++) { - src_data[i] = SkPreMultiplyARGB(i % 255, i % 250, i % 245, i % 240); - } -} - -TEST(PNGCodec, EncodeDecodeRGB) { - const int w = 20, h = 20; - - // create an image with known values - std::vector<unsigned char> original; - MakeRGBImage(w, h, &original); - - // encode - std::vector<unsigned char> encoded; - EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, w, h, - w * 3, false, &encoded)); - - // decode, it should have the same size as the original - std::vector<unsigned char> decoded; - int outw, outh; - EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), - PNGCodec::FORMAT_RGB, &decoded, - &outw, &outh)); - ASSERT_EQ(w, outw); - ASSERT_EQ(h, outh); - ASSERT_EQ(original.size(), decoded.size()); - - // Images must be equal - ASSERT_TRUE(original == decoded); -} - -TEST(PNGCodec, EncodeDecodeRGBA) { - const int w = 20, h = 20; - - // create an image with known values, a must be opaque because it will be - // lost during encoding - std::vector<unsigned char> original; - MakeRGBAImage(w, h, true, &original); - - // encode - std::vector<unsigned char> encoded; - EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGBA, w, h, - w * 4, false, &encoded)); - - // decode, it should have the same size as the original - std::vector<unsigned char> decoded; - int outw, outh; - EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), - PNGCodec::FORMAT_RGBA, &decoded, - &outw, &outh)); - ASSERT_EQ(w, outw); - ASSERT_EQ(h, outh); - ASSERT_EQ(original.size(), decoded.size()); - - // Images must be exactly equal - ASSERT_TRUE(original == decoded); -} - -// Test that corrupted data decompression causes failures. -TEST(PNGCodec, DecodeCorrupted) { - int w = 20, h = 20; - - // Make some random data (an uncompressed image). - std::vector<unsigned char> original; - MakeRGBImage(w, h, &original); - - // It should fail when given non-JPEG compressed data. - std::vector<unsigned char> output; - int outw, outh; - EXPECT_FALSE(PNGCodec::Decode(&original[0], original.size(), - PNGCodec::FORMAT_RGB, &output, - &outw, &outh)); - - // Make some compressed data. - std::vector<unsigned char> compressed; - EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, w, h, - w * 3, false, &compressed)); - - // Try decompressing a truncated version. - EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size() / 2, - PNGCodec::FORMAT_RGB, &output, - &outw, &outh)); - - // Corrupt it and try decompressing that. - for (int i = 10; i < 30; i++) - compressed[i] = i; - EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size(), - PNGCodec::FORMAT_RGB, &output, - &outw, &outh)); -} - -TEST(PNGCodec, EncodeDecodeBGRA) { - const int w = 20, h = 20; - - // Create an image with known values, alpha must be opaque because it will be - // lost during encoding. - std::vector<unsigned char> original; - MakeRGBAImage(w, h, true, &original); - - // Encode. - std::vector<unsigned char> encoded; - EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_BGRA, w, h, - w * 4, false, &encoded)); - - // Decode, it should have the same size as the original. - std::vector<unsigned char> decoded; - int outw, outh; - EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), - PNGCodec::FORMAT_BGRA, &decoded, - &outw, &outh)); - ASSERT_EQ(w, outw); - ASSERT_EQ(h, outh); - ASSERT_EQ(original.size(), decoded.size()); - - // Images must be exactly equal. - ASSERT_TRUE(original == decoded); -} - -TEST(PNGCodec, StripAddAlpha) { - const int w = 20, h = 20; - - // These should be the same except one has a 0xff alpha channel. - std::vector<unsigned char> original_rgb; - MakeRGBImage(w, h, &original_rgb); - std::vector<unsigned char> original_rgba; - MakeRGBAImage(w, h, false, &original_rgba); - - // Encode RGBA data as RGB. - std::vector<unsigned char> encoded; - EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], - PNGCodec::FORMAT_RGBA, - w, h, - w * 4, true, &encoded)); - - // Decode the RGB to RGBA. - std::vector<unsigned char> decoded; - int outw, outh; - EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), - PNGCodec::FORMAT_RGBA, &decoded, - &outw, &outh)); - - // Decoded and reference should be the same (opaque alpha). - ASSERT_EQ(w, outw); - ASSERT_EQ(h, outh); - ASSERT_EQ(original_rgba.size(), decoded.size()); - ASSERT_TRUE(original_rgba == decoded); - - // Encode RGBA to RGBA. - EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], - PNGCodec::FORMAT_RGBA, - w, h, - w * 4, false, &encoded)); - - // Decode the RGBA to RGB. - EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), - PNGCodec::FORMAT_RGB, &decoded, - &outw, &outh)); - - // It should be the same as our non-alpha-channel reference. - ASSERT_EQ(w, outw); - ASSERT_EQ(h, outh); - ASSERT_EQ(original_rgb.size(), decoded.size()); - ASSERT_TRUE(original_rgb == decoded); -} - -TEST(PNGCodec, EncodeBGRASkBitmap) { - const int w = 20, h = 20; - - SkBitmap original_bitmap; - MakeTestSkBitmap(w, h, &original_bitmap); - - // Encode the bitmap. - std::vector<unsigned char> encoded; - PNGCodec::EncodeBGRASkBitmap(original_bitmap, false, &encoded); - - // Decode the encoded string. - SkBitmap decoded_bitmap; - EXPECT_TRUE(PNGCodec::Decode(&encoded.front(), encoded.size(), - &decoded_bitmap)); - - // Compare the original bitmap and the output bitmap. We use ColorsClose - // as SkBitmaps are considered to be pre-multiplied, the unpremultiplication - // (in Encode) and repremultiplication (in Decode) can be lossy. - for (int x = 0; x < w; x++) { - for (int y = 0; y < h; y++) { - uint32_t original_pixel = original_bitmap.getAddr32(0, y)[x]; - uint32_t decoded_pixel = decoded_bitmap.getAddr32(0, y)[x]; - EXPECT_TRUE(ColorsClose(original_pixel, decoded_pixel)); - } - } -} - -TEST(PNGCodec, EncodeBGRASkBitmapDiscardTransparency) { - const int w = 20, h = 20; - - SkBitmap original_bitmap; - MakeTestSkBitmap(w, h, &original_bitmap); - - // Encode the bitmap. - std::vector<unsigned char> encoded; - PNGCodec::EncodeBGRASkBitmap(original_bitmap, true, &encoded); - - // Decode the encoded string. - SkBitmap decoded_bitmap; - EXPECT_TRUE(PNGCodec::Decode(&encoded.front(), encoded.size(), - &decoded_bitmap)); - - // Compare the original bitmap and the output bitmap. We need to - // unpremultiply original_pixel, as the decoded bitmap doesn't have an alpha - // channel. - for (int x = 0; x < w; x++) { - for (int y = 0; y < h; y++) { - uint32_t original_pixel = original_bitmap.getAddr32(0, y)[x]; - uint32_t unpremultiplied = - SkUnPreMultiply::PMColorToColor(original_pixel); - uint32_t decoded_pixel = decoded_bitmap.getAddr32(0, y)[x]; - EXPECT_TRUE(NonAlphaColorsClose(unpremultiplied, decoded_pixel)) - << "Original_pixel: (" - << SkColorGetR(unpremultiplied) << ", " - << SkColorGetG(unpremultiplied) << ", " - << SkColorGetB(unpremultiplied) << "), " - << "Decoded pixel: (" - << SkColorGetR(decoded_pixel) << ", " - << SkColorGetG(decoded_pixel) << ", " - << SkColorGetB(decoded_pixel) << ")"; - } - } -} - -} // namespace gfx diff --git a/gfx/color_utils.cc b/gfx/color_utils.cc deleted file mode 100644 index 73c585b..0000000 --- a/gfx/color_utils.cc +++ /dev/null @@ -1,300 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/color_utils.h" - -#include <math.h> -#if defined(OS_WIN) -#include <windows.h> -#endif - -#include <algorithm> - -#include "base/basictypes.h" -#include "base/logging.h" -#include "build/build_config.h" -#if defined(OS_WIN) -#include "skia/ext/skia_utils_win.h" -#endif -#include "third_party/skia/include/core/SkBitmap.h" - -namespace color_utils { - -// Helper functions ----------------------------------------------------------- - -namespace { - -double calcHue(double temp1, double temp2, double hue) { - if (hue < 0.0) - ++hue; - else if (hue > 1.0) - --hue; - - if (hue * 6.0 < 1.0) - return temp1 + (temp2 - temp1) * hue * 6.0; - if (hue * 2.0 < 1.0) - return temp2; - if (hue * 3.0 < 2.0) - return temp1 + (temp2 - temp1) * (2.0 / 3.0 - hue) * 6.0; - - return temp1; -} - -int GetLumaForColor(SkColor* color) { - int luma = static_cast<int>((0.3 * SkColorGetR(*color)) + - (0.59 * SkColorGetG(*color)) + - (0.11 * SkColorGetB(*color))); - return std::max(std::min(luma, 255), 0); -} - -// Next two functions' formulas from: -// http://www.w3.org/TR/WCAG20/#relativeluminancedef -// http://www.w3.org/TR/WCAG20/#contrast-ratiodef - -double ConvertSRGB(double eight_bit_component) { - const double component = eight_bit_component / 255.0; - return (component <= 0.03928) ? - (component / 12.92) : pow((component + 0.055) / 1.055, 2.4); -} - -SkColor LumaInvertColor(const SkColor& color) { - HSL hsl; - SkColorToHSL(color, &hsl); - hsl.l = 1.0 - hsl.l; - return HSLToSkColor(hsl, 255); -} - -double ContrastRatio(double foreground_luminance, double background_luminance) { - // NOTE: Only pass in numbers obtained from RelativeLuminance(), since those - // are guaranteed to be > 0 and thus not cause a divide-by-zero error here. - return (foreground_luminance > background_luminance) ? - (foreground_luminance / background_luminance) : - (background_luminance / foreground_luminance); -} - -} // namespace - -// ---------------------------------------------------------------------------- - -double RelativeLuminance(SkColor color) { - return (0.2126 * ConvertSRGB(SkColorGetR(color))) + - (0.7152 * ConvertSRGB(SkColorGetG(color))) + - (0.0722 * ConvertSRGB(SkColorGetB(color))) + 0.05; -} - -void SkColorToHSL(SkColor c, HSL* hsl) { - double r = static_cast<double>(SkColorGetR(c)) / 255.0; - double g = static_cast<double>(SkColorGetG(c)) / 255.0; - double b = static_cast<double>(SkColorGetB(c)) / 255.0; - double vmax = std::max(std::max(r, g), b); - double vmin = std::min(std::min(r, g), b); - double delta = vmax - vmin; - hsl->l = (vmax + vmin) / 2; - if (delta) { - double dr = (((vmax - r) / 6.0) + (delta / 2.0)) / delta; - double dg = (((vmax - g) / 6.0) + (delta / 2.0)) / delta; - double db = (((vmax - b) / 6.0) + (delta / 2.0)) / delta; - // We need to compare for the max value because comparing vmax to r, - // g or b can sometimes result in values overflowing registers. - if (r >= g && r >= b) - hsl->h = db - dg; - else if (g >= r && g >= b) - hsl->h = (1.0 / 3.0) + dr - db; - else // (b >= r && b >= g) - hsl->h = (2.0 / 3.0) + dg - dr; - - if (hsl->h < 0.0) - ++hsl->h; - else if (hsl->h > 1.0) - --hsl->h; - - hsl->s = delta / ((hsl->l < 0.5) ? (vmax + vmin) : (2 - vmax - vmin)); - } else { - hsl->h = hsl->s = 0; - } -} - -SkColor HSLToSkColor(const HSL& hsl, SkAlpha alpha) { - double hue = hsl.h; - double saturation = hsl.s; - double lightness = hsl.l; - - // If there's no color, we don't care about hue and can do everything based - // on brightness. - if (!saturation) { - uint8 light; - - if (lightness < 0) - light = 0; - else if (lightness >= 1.0) - light = 255; - else - light = SkDoubleToFixed(lightness) >> 8; - - return SkColorSetARGB(alpha, light, light, light); - } - - double temp2 = (lightness < 0.5) ? - (lightness * (1.0 + saturation)) : - (lightness + saturation - (lightness * saturation)); - double temp1 = 2.0 * lightness - temp2; - return SkColorSetARGB(alpha, - static_cast<int>(calcHue(temp1, temp2, hue + 1.0 / 3.0) * 255), - static_cast<int>(calcHue(temp1, temp2, hue) * 255), - static_cast<int>(calcHue(temp1, temp2, hue - 1.0 / 3.0) * 255)); -} - -SkColor HSLShift(SkColor color, const HSL& shift) { - HSL hsl; - int alpha = SkColorGetA(color); - SkColorToHSL(color, &hsl); - - // Replace the hue with the tint's hue. - if (shift.h >= 0) - hsl.h = shift.h; - - // Change the saturation. - if (shift.s >= 0) { - if (shift.s <= 0.5) - hsl.s *= shift.s * 2.0; - else - hsl.s += (1.0 - hsl.s) * ((shift.s - 0.5) * 2.0); - } - - SkColor result = HSLToSkColor(hsl, alpha); - - if (shift.l < 0) - return result; - - // Lightness shifts in the style of popular image editors aren't - // actually represented in HSL - the L value does have some effect - // on saturation. - double r = static_cast<double>(SkColorGetR(result)); - double g = static_cast<double>(SkColorGetG(result)); - double b = static_cast<double>(SkColorGetB(result)); - if (shift.l <= 0.5) { - r *= (shift.l * 2.0); - g *= (shift.l * 2.0); - b *= (shift.l * 2.0); - } else { - r += (255.0 - r) * ((shift.l - 0.5) * 2.0); - g += (255.0 - g) * ((shift.l - 0.5) * 2.0); - b += (255.0 - b) * ((shift.l - 0.5) * 2.0); - } - return SkColorSetARGB(alpha, - static_cast<int>(r), - static_cast<int>(g), - static_cast<int>(b)); -} - -bool IsColorCloseToTransparent(SkAlpha alpha) { - const int kCloseToBoundary = 64; - return alpha < kCloseToBoundary; -} - -bool IsColorCloseToGrey(int r, int g, int b) { - const int kAverageBoundary = 15; - int average = (r + g + b) / 3; - return (abs(r - average) < kAverageBoundary) && - (abs(g - average) < kAverageBoundary) && - (abs(b - average) < kAverageBoundary); -} - -SkColor GetAverageColorOfFavicon(SkBitmap* favicon, SkAlpha alpha) { - int r = 0, g = 0, b = 0; - - SkAutoLockPixels favicon_lock(*favicon); - SkColor* pixels = static_cast<SkColor*>(favicon->getPixels()); - // Assume ARGB_8888 format. - DCHECK(favicon->getConfig() == SkBitmap::kARGB_8888_Config); - SkColor* current_color = pixels; - - DCHECK(favicon->width() <= 16 && favicon->height() <= 16); - - int pixel_count = favicon->width() * favicon->height(); - int color_count = 0; - for (int i = 0; i < pixel_count; ++i, ++current_color) { - // Disregard this color if it is close to black, close to white, or close - // to transparent since any of those pixels do not contribute much to the - // color makeup of this icon. - int cr = SkColorGetR(*current_color); - int cg = SkColorGetG(*current_color); - int cb = SkColorGetB(*current_color); - - if (IsColorCloseToTransparent(SkColorGetA(*current_color)) || - IsColorCloseToGrey(cr, cg, cb)) - continue; - - r += cr; - g += cg; - b += cb; - ++color_count; - } - - return color_count ? - SkColorSetARGB(alpha, r / color_count, g / color_count, b / color_count) : - SkColorSetARGB(alpha, 0, 0, 0); -} - -void BuildLumaHistogram(SkBitmap* bitmap, int histogram[256]) { - SkAutoLockPixels bitmap_lock(*bitmap); - // Assume ARGB_8888 format. - DCHECK(bitmap->getConfig() == SkBitmap::kARGB_8888_Config); - - int pixel_width = bitmap->width(); - int pixel_height = bitmap->height(); - for (int y = 0; y < pixel_height; ++y) { - SkColor* current_color = static_cast<uint32_t*>(bitmap->getAddr32(0, y)); - for (int x = 0; x < pixel_width; ++x, ++current_color) - histogram[GetLumaForColor(current_color)]++; - } -} - -SkColor AlphaBlend(SkColor foreground, SkColor background, SkAlpha alpha) { - if (alpha == 0) - return background; - if (alpha == 255) - return foreground; - - int f_alpha = SkColorGetA(foreground); - int b_alpha = SkColorGetA(background); - - double normalizer = (f_alpha * alpha + b_alpha * (255 - alpha)) / 255.0; - if (normalizer == 0.0) - return SkColorSetARGB(0, 0, 0, 0); - - double f_weight = f_alpha * alpha / normalizer; - double b_weight = b_alpha * (255 - alpha) / normalizer; - - double r = (SkColorGetR(foreground) * f_weight + - SkColorGetR(background) * b_weight) / 255.0; - double g = (SkColorGetG(foreground) * f_weight + - SkColorGetG(background) * b_weight) / 255.0; - double b = (SkColorGetB(foreground) * f_weight + - SkColorGetB(background) * b_weight) / 255.0; - - return SkColorSetARGB(static_cast<int>(normalizer), - static_cast<int>(r), - static_cast<int>(g), - static_cast<int>(b)); -} - -SkColor GetReadableColor(SkColor foreground, SkColor background) { - const SkColor foreground2 = LumaInvertColor(foreground); - const double background_luminance = RelativeLuminance(background); - return (ContrastRatio(RelativeLuminance(foreground), background_luminance) >= - ContrastRatio(RelativeLuminance(foreground2), background_luminance)) ? - foreground : foreground2; -} - -SkColor GetSysSkColor(int which) { -#if defined(OS_WIN) - return skia::COLORREFToSkColor(GetSysColor(which)); -#else - NOTIMPLEMENTED(); - return SK_ColorLTGRAY; -#endif -} - -} // namespace color_utils diff --git a/gfx/color_utils.h b/gfx/color_utils.h index b6eb2da..166a793 100644 --- a/gfx/color_utils.h +++ b/gfx/color_utils.h @@ -6,75 +6,7 @@ #define APP_GFX_COLOR_UTILS_H_ #pragma once -#include "third_party/skia/include/core/SkColor.h" - -class SkBitmap; - -namespace color_utils { - -// Represents an HSL color. -struct HSL { - double h; - double s; - double l; -}; - -// Calculated according to http://www.w3.org/TR/WCAG20/#relativeluminancedef -double RelativeLuminance(SkColor color); - -// Note: these transformations assume sRGB as the source color space -void SkColorToHSL(SkColor c, HSL* hsl); -SkColor HSLToSkColor(const HSL& hsl, SkAlpha alpha); - -// HSL-Shift an SkColor. The shift values are in the range of 0-1, with the -// option to specify -1 for 'no change'. The shift values are defined as: -// hsl_shift[0] (hue): The absolute hue value - 0 and 1 map -// to 0 and 360 on the hue color wheel (red). -// hsl_shift[1] (saturation): A saturation shift, with the -// following key values: -// 0 = remove all color. -// 0.5 = leave unchanged. -// 1 = fully saturate the image. -// hsl_shift[2] (lightness): A lightness shift, with the -// following key values: -// 0 = remove all lightness (make all pixels black). -// 0.5 = leave unchanged. -// 1 = full lightness (make all pixels white). -SkColor HSLShift(SkColor color, const HSL& shift); - -// Determine if a given alpha value is nearly completely transparent. -bool IsColorCloseToTransparent(SkAlpha alpha); - -// Determine if a color is near grey. -bool IsColorCloseToGrey(int r, int g, int b); - -// Gets a color representing a bitmap. The definition of "representing" is the -// average color in the bitmap. The color returned is modified to have the -// specified alpha. -SkColor GetAverageColorOfFavicon(SkBitmap* bitmap, SkAlpha alpha); - -// Builds a histogram based on the Y' of the Y'UV representation of -// this image. -void BuildLumaHistogram(SkBitmap* bitmap, int histogram[256]); - -// Returns a blend of the supplied colors, ranging from |background| (for -// |alpha| == 0) to |foreground| (for |alpha| == 255). The alpha channels of -// the supplied colors are also taken into account, so the returned color may -// be partially transparent. -SkColor AlphaBlend(SkColor foreground, SkColor background, SkAlpha alpha); - -// Given a foreground and background color, try to return a foreground color -// that is "readable" over the background color by luma-inverting the foreground -// color and then picking whichever foreground color has higher contrast against -// the background color. -// -// NOTE: This won't do anything but waste time if the supplied foreground color -// has a luma value close to the midpoint (0.5 in the HSL representation). -SkColor GetReadableColor(SkColor foreground, SkColor background); - -// Gets a Windows system color as a SkColor -SkColor GetSysSkColor(int which); - -} // namespace color_utils +#include "ui/gfx/color_utils.h" +// TODO(sail): remove this file once all includes have been updated. #endif // APP_GFX_COLOR_UTILS_H_ diff --git a/gfx/color_utils_unittest.cc b/gfx/color_utils_unittest.cc deleted file mode 100644 index 30cf514..0000000 --- a/gfx/color_utils_unittest.cc +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stdlib.h> - -#include "gfx/color_utils.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkColorPriv.h" - -TEST(ColorUtils, SkColorToHSLRed) { - color_utils::HSL hsl = { 0, 0, 0 }; - color_utils::SkColorToHSL(SK_ColorRED, &hsl); - EXPECT_EQ(hsl.h, 0); - EXPECT_EQ(hsl.s, 1); - EXPECT_EQ(hsl.l, 0.5); -} - -TEST(ColorUtils, SkColorToHSLGrey) { - color_utils::HSL hsl = { 0, 0, 0 }; - color_utils::SkColorToHSL(SkColorSetARGB(255, 128, 128, 128), &hsl); - EXPECT_EQ(hsl.h, 0); - EXPECT_EQ(hsl.s, 0); - EXPECT_EQ(static_cast<int>(hsl.l * 100), - static_cast<int>(0.5 * 100)); // Accurate to two decimal places. -} - -TEST(ColorUtils, HSLToSkColorWithAlpha) { - SkColor red = SkColorSetARGB(128, 255, 0, 0); - color_utils::HSL hsl = { 0, 1, 0.5 }; - SkColor result = color_utils::HSLToSkColor(hsl, 128); - EXPECT_EQ(SkColorGetA(red), SkColorGetA(result)); - EXPECT_EQ(SkColorGetR(red), SkColorGetR(result)); - EXPECT_EQ(SkColorGetG(red), SkColorGetG(result)); - EXPECT_EQ(SkColorGetB(red), SkColorGetB(result)); -} - -TEST(ColorUtils, ColorToHSLRegisterSpill) { - // In a opt build on Linux, this was causing a register spill on my laptop - // (Pentium M) when converting from SkColor to HSL. - SkColor input = SkColorSetARGB(255, 206, 154, 89); - color_utils::HSL hsl = { -1, -1, -1 }; - SkColor result = color_utils::HSLShift(input, hsl); - EXPECT_EQ(255U, SkColorGetA(result)); - EXPECT_EQ(206U, SkColorGetR(result)); - EXPECT_EQ(153U, SkColorGetG(result)); - EXPECT_EQ(88U, SkColorGetB(result)); -} - -TEST(ColorUtils, AlphaBlend) { - SkColor fore = SkColorSetARGB(255, 200, 200, 200); - SkColor back = SkColorSetARGB(255, 100, 100, 100); - - EXPECT_TRUE(color_utils::AlphaBlend(fore, back, 255) == - fore); - EXPECT_TRUE(color_utils::AlphaBlend(fore, back, 0) == - back); - - // One is fully transparent, result is partially transparent. - back = SkColorSetA(back, 0); - EXPECT_EQ(136U, SkColorGetA(color_utils::AlphaBlend(fore, back, 136))); - - // Both are fully transparent, result is fully transparent. - fore = SkColorSetA(fore, 0); - EXPECT_EQ(0U, SkColorGetA(color_utils::AlphaBlend(fore, back, 255))); -} diff --git a/gfx/empty.cc b/gfx/empty.cc deleted file mode 100644 index 63672f6..0000000 --- a/gfx/empty.cc +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -void MacSux() { -} diff --git a/gfx/favicon_size.h b/gfx/favicon_size.h index 018d348..9d36608 100644 --- a/gfx/favicon_size.h +++ b/gfx/favicon_size.h @@ -6,29 +6,7 @@ #define APP_GFX_FAVICON_SIZE_H_ #pragma once -#include "base/compiler_specific.h" - -// Size (along each axis) of the favicon. -const int kFavIconSize = 16; - -// If the width or height is bigger than the favicon size, a new width/height -// is calculated and returned in width/height that maintains the aspect -// ratio of the supplied values. -static void calc_favicon_target_size(int* width, int* height) ALLOW_UNUSED; - -// static -void calc_favicon_target_size(int* width, int* height) { - if (*width > kFavIconSize || *height > kFavIconSize) { - // Too big, resize it maintaining the aspect ratio. - float aspect_ratio = static_cast<float>(*width) / - static_cast<float>(*height); - *height = kFavIconSize; - *width = static_cast<int>(aspect_ratio * *height); - if (*width > kFavIconSize) { - *width = kFavIconSize; - *height = static_cast<int>(*width / aspect_ratio); - } - } -} +#include "ui/gfx/favicon_size.h" +// TODO(sail): remove this file once all includes have been updated. #endif // APP_GFX_FAVICON_SIZE_H_ diff --git a/gfx/font.cc b/gfx/font.cc deleted file mode 100644 index 78b1a34..0000000 --- a/gfx/font.cc +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/font.h" - -#include "base/utf_string_conversions.h" -#include "gfx/platform_font.h" - -namespace gfx { - -//////////////////////////////////////////////////////////////////////////////// -// Font, public: - -Font::Font() : platform_font_(PlatformFont::CreateDefault()) { -} - -Font::Font(const Font& other) : platform_font_(other.platform_font_) { -} - -gfx::Font& Font::operator=(const Font& other) { - platform_font_ = other.platform_font_; - return *this; -} - -Font::Font(NativeFont native_font) - : platform_font_(PlatformFont::CreateFromNativeFont(native_font)) { -} - -Font::Font(PlatformFont* platform_font) : platform_font_(platform_font) { -} - -Font::Font(const string16& font_name, int font_size) - : platform_font_(PlatformFont::CreateFromNameAndSize(font_name, - font_size)) { -} - -Font::~Font() { -} - -Font Font::DeriveFont(int size_delta) const { - return DeriveFont(size_delta, GetStyle()); -} - -Font Font::DeriveFont(int size_delta, int style) const { - return platform_font_->DeriveFont(size_delta, style); -} - -int Font::GetHeight() const { - return platform_font_->GetHeight(); -} - -int Font::GetBaseline() const { - return platform_font_->GetBaseline(); -} - -int Font::GetAverageCharacterWidth() const { - return platform_font_->GetAverageCharacterWidth(); -} - -int Font::GetStringWidth(const string16& text) const { - return platform_font_->GetStringWidth(text); -} - -int Font::GetExpectedTextWidth(int length) const { - return platform_font_->GetExpectedTextWidth(length); -} - -int Font::GetStyle() const { - return platform_font_->GetStyle(); -} - -string16 Font::GetFontName() const { - return platform_font_->GetFontName(); -} - -int Font::GetFontSize() const { - return platform_font_->GetFontSize(); -} - -NativeFont Font::GetNativeFont() const { - return platform_font_->GetNativeFont(); -} - -} // namespace gfx @@ -6,108 +6,7 @@ #define GFX_FONT_H_ #pragma once -#include <string> - -#include "base/ref_counted.h" -#include "base/string16.h" -#include "gfx/native_widget_types.h" - -namespace gfx { - -class PlatformFont; - -// Font provides a wrapper around an underlying font. Copy and assignment -// operators are explicitly allowed, and cheap. -class Font { - public: - // The following constants indicate the font style. - enum FontStyle { - NORMAL = 0, - BOLD = 1, - ITALIC = 2, - UNDERLINED = 4, - }; - - // Creates a font with the default name and style. - Font(); - - // Creates a font that is a clone of another font object. - Font(const Font& other); - gfx::Font& operator=(const Font& other); - - // Creates a font from the specified native font. - explicit Font(NativeFont native_font); - - // Construct a Font object with the specified PlatformFont object. The Font - // object takes ownership of the PlatformFont object. - explicit Font(PlatformFont* platform_font); - - // Creates a font with the specified name and size. - Font(const string16& font_name, int font_size); - - ~Font(); - - // Returns a new Font derived from the existing font. - // size_deta is the size to add to the current font. For example, a value - // of 5 results in a font 5 units bigger than this font. - Font DeriveFont(int size_delta) const; - - // Returns a new Font derived from the existing font. - // size_delta is the size to add to the current font. See the single - // argument version of this method for an example. - // The style parameter specifies the new style for the font, and is a - // bitmask of the values: BOLD, ITALIC and UNDERLINED. - Font DeriveFont(int size_delta, int style) const; - - // Returns the number of vertical pixels needed to display characters from - // the specified font. This may include some leading, i.e. height may be - // greater than just ascent + descent. Specifically, the Windows and Mac - // implementations include leading and the Linux one does not. This may - // need to be revisited in the future. - int GetHeight() const; - - // Returns the baseline, or ascent, of the font. - int GetBaseline() const; - - // Returns the average character width for the font. - int GetAverageCharacterWidth() const; - - // Returns the number of horizontal pixels needed to display the specified - // string. - int GetStringWidth(const string16& text) const; - - // Returns the expected number of horizontal pixels needed to display the - // specified length of characters. Call GetStringWidth() to retrieve the - // actual number. - int GetExpectedTextWidth(int length) const; - - // Returns the style of the font. - int GetStyle() const; - - // Returns the font name. - string16 GetFontName() const; - - // Returns the font size in pixels. - int GetFontSize() const; - - // Returns the native font handle. - // Lifetime lore: - // Windows: This handle is owned by the Font object, and should not be - // destroyed by the caller. - // Mac: Caller must release this object. - // Gtk: This handle is created on demand, and must be freed by calling - // pango_font_description_free() when the caller is done using it. - NativeFont GetNativeFont() const; - - // Raw access to the underlying platform font implementation. Can be - // static_cast to a known implementation type if needed. - PlatformFont* platform_font() const { return platform_font_.get(); } - - private: - // Wrapped platform font implementation. - scoped_refptr<PlatformFont> platform_font_; -}; - -} // namespace gfx +#include "ui/gfx/font.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_FONT_H_ diff --git a/gfx/font_unittest.cc b/gfx/font_unittest.cc deleted file mode 100644 index 43eaa7c..0000000 --- a/gfx/font_unittest.cc +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/font.h" - -#include "base/utf_string_conversions.h" -#if defined(OS_WIN) -#include "gfx/platform_font_win.h" -#endif // defined(OS_WIN) -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -using gfx::Font; - -class FontTest : public testing::Test { -}; - -#if defined(OS_WIN) -class ScopedMinimumFontSizeCallback { - public: - explicit ScopedMinimumFontSizeCallback(int minimum_size) { - minimum_size_ = minimum_size; - old_callback_ = gfx::PlatformFontWin::get_minimum_font_size_callback; - gfx::PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize; - } - - ~ScopedMinimumFontSizeCallback() { - gfx::PlatformFontWin::get_minimum_font_size_callback = old_callback_; - } - - private: - static int GetMinimumFontSize() { - return minimum_size_; - } - - gfx::PlatformFontWin::GetMinimumFontSizeCallback old_callback_; - static int minimum_size_; - - DISALLOW_COPY_AND_ASSIGN(ScopedMinimumFontSizeCallback); -}; - -int ScopedMinimumFontSizeCallback::minimum_size_ = 0; -#endif // defined(OS_WIN) - - -TEST_F(FontTest, LoadArial) { - Font cf(ASCIIToUTF16("Arial"), 16); - ASSERT_TRUE(cf.GetNativeFont()); - ASSERT_EQ(cf.GetStyle(), Font::NORMAL); - ASSERT_EQ(cf.GetFontSize(), 16); - ASSERT_EQ(cf.GetFontName(), ASCIIToUTF16("Arial")); -} - -TEST_F(FontTest, LoadArialBold) { - Font cf(ASCIIToUTF16("Arial"), 16); - Font bold(cf.DeriveFont(0, Font::BOLD)); - ASSERT_TRUE(bold.GetNativeFont()); - ASSERT_EQ(bold.GetStyle(), Font::BOLD); -} - -TEST_F(FontTest, Ascent) { - Font cf(ASCIIToUTF16("Arial"), 16); - ASSERT_GT(cf.GetBaseline(), 2); - ASSERT_LE(cf.GetBaseline(), 22); -} - -TEST_F(FontTest, Height) { - Font cf(ASCIIToUTF16("Arial"), 16); - ASSERT_GE(cf.GetHeight(), 16); - // TODO(akalin): Figure out why height is so large on Linux. - ASSERT_LE(cf.GetHeight(), 26); -} - -TEST_F(FontTest, AvgWidths) { - Font cf(ASCIIToUTF16("Arial"), 16); - ASSERT_EQ(cf.GetExpectedTextWidth(0), 0); - ASSERT_GT(cf.GetExpectedTextWidth(1), cf.GetExpectedTextWidth(0)); - ASSERT_GT(cf.GetExpectedTextWidth(2), cf.GetExpectedTextWidth(1)); - ASSERT_GT(cf.GetExpectedTextWidth(3), cf.GetExpectedTextWidth(2)); -} - -TEST_F(FontTest, Widths) { - Font cf(ASCIIToUTF16("Arial"), 16); - ASSERT_EQ(cf.GetStringWidth(ASCIIToUTF16("")), 0); - ASSERT_GT(cf.GetStringWidth(ASCIIToUTF16("a")), - cf.GetStringWidth(ASCIIToUTF16(""))); - ASSERT_GT(cf.GetStringWidth(ASCIIToUTF16("ab")), - cf.GetStringWidth(ASCIIToUTF16("a"))); - ASSERT_GT(cf.GetStringWidth(ASCIIToUTF16("abc")), - cf.GetStringWidth(ASCIIToUTF16("ab"))); -} - -#if defined(OS_WIN) -TEST_F(FontTest, DeriveFontResizesIfSizeTooSmall) { - // This creates font of height -8. - Font cf(L"Arial", 6); - // The minimum font size is set to 5 in browser_main.cc. - ScopedMinimumFontSizeCallback minimum_size(5); - - Font derived_font = cf.DeriveFont(-4); - LOGFONT font_info; - GetObject(derived_font.GetNativeFont(), sizeof(LOGFONT), &font_info); - EXPECT_EQ(-5, font_info.lfHeight); -} - -TEST_F(FontTest, DeriveFontKeepsOriginalSizeIfHeightOk) { - // This creates font of height -8. - Font cf(L"Arial", 6); - // The minimum font size is set to 5 in browser_main.cc. - ScopedMinimumFontSizeCallback minimum_size(5); - - Font derived_font = cf.DeriveFont(-2); - LOGFONT font_info; - GetObject(derived_font.GetNativeFont(), sizeof(LOGFONT), &font_info); - EXPECT_EQ(-6, font_info.lfHeight); -} -#endif -} // namespace diff --git a/gfx/gdi_util.cc b/gfx/gdi_util.cc deleted file mode 100644 index 5dbb5b5..0000000 --- a/gfx/gdi_util.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/gdi_util.h" - -namespace gfx { - -void CreateBitmapHeader(int width, int height, BITMAPINFOHEADER* hdr) { - CreateBitmapHeaderWithColorDepth(width, height, 32, hdr); -} - -void CreateBitmapHeaderWithColorDepth(int width, int height, int color_depth, - BITMAPINFOHEADER* hdr) { - // These values are shared with gfx::PlatformDevice - hdr->biSize = sizeof(BITMAPINFOHEADER); - hdr->biWidth = width; - hdr->biHeight = -height; // minus means top-down bitmap - hdr->biPlanes = 1; - hdr->biBitCount = color_depth; - hdr->biCompression = BI_RGB; // no compression - hdr->biSizeImage = 0; - hdr->biXPelsPerMeter = 1; - hdr->biYPelsPerMeter = 1; - hdr->biClrUsed = 0; - hdr->biClrImportant = 0; -} - - -void CreateBitmapV4Header(int width, int height, BITMAPV4HEADER* hdr) { - // Because bmp v4 header is just an extension, we just create a v3 header and - // copy the bits over to the v4 header. - BITMAPINFOHEADER header_v3; - CreateBitmapHeader(width, height, &header_v3); - memset(hdr, 0, sizeof(BITMAPV4HEADER)); - memcpy(hdr, &header_v3, sizeof(BITMAPINFOHEADER)); - - // Correct the size of the header and fill in the mask values. - hdr->bV4Size = sizeof(BITMAPV4HEADER); - hdr->bV4RedMask = 0x00ff0000; - hdr->bV4GreenMask = 0x0000ff00; - hdr->bV4BlueMask = 0x000000ff; - hdr->bV4AlphaMask = 0xff000000; -} - -// Creates a monochrome bitmap header. -void CreateMonochromeBitmapHeader(int width, - int height, - BITMAPINFOHEADER* hdr) { - hdr->biSize = sizeof(BITMAPINFOHEADER); - hdr->biWidth = width; - hdr->biHeight = -height; - hdr->biPlanes = 1; - hdr->biBitCount = 1; - hdr->biCompression = BI_RGB; - hdr->biSizeImage = 0; - hdr->biXPelsPerMeter = 1; - hdr->biYPelsPerMeter = 1; - hdr->biClrUsed = 0; - hdr->biClrImportant = 0; -} - -void SubtractRectanglesFromRegion(HRGN hrgn, - const std::vector<gfx::Rect>& cutouts) { - if (cutouts.size()) { - HRGN cutout = ::CreateRectRgn(0, 0, 0, 0); - for (size_t i = 0; i < cutouts.size(); i++) { - ::SetRectRgn(cutout, - cutouts[i].x(), - cutouts[i].y(), - cutouts[i].right(), - cutouts[i].bottom()); - ::CombineRgn(hrgn, hrgn, cutout, RGN_DIFF); - } - ::DeleteObject(cutout); - } -} - -} // namespace gfx diff --git a/gfx/gdi_util.h b/gfx/gdi_util.h index 3f37ed8..324dafc 100644 --- a/gfx/gdi_util.h +++ b/gfx/gdi_util.h @@ -6,33 +6,7 @@ #define APP_GFX_GDI_UTIL_H_ #pragma once -#include <vector> -#include <windows.h> - -#include "gfx/rect.h" - -namespace gfx { - -// Creates a BITMAPINFOHEADER structure given the bitmap's size. -void CreateBitmapHeader(int width, int height, BITMAPINFOHEADER* hdr); - -// Creates a BITMAPINFOHEADER structure given the bitmap's size and -// color depth in bits per pixel. -void CreateBitmapHeaderWithColorDepth(int width, int height, int color_depth, - BITMAPINFOHEADER* hdr); - -// Creates a BITMAPV4HEADER structure given the bitmap's size. You probably -// only need to use BMP V4 if you need transparency (alpha channel). This -// function sets the AlphaMask to 0xff000000. -void CreateBitmapV4Header(int width, int height, BITMAPV4HEADER* hdr); - -// Creates a monochrome bitmap header. -void CreateMonochromeBitmapHeader(int width, int height, BITMAPINFOHEADER* hdr); - -// Modify the given hrgn by subtracting the given rectangles. -void SubtractRectanglesFromRegion(HRGN hrgn, - const std::vector<gfx::Rect>& cutouts); - -} // namespace gfx +#include "ui/gfx/gdi_util.h" +// TODO(sail): remove this file once all includes have been updated. #endif // APP_GFX_GDI_UTIL_H_ diff --git a/gfx/gfx.gyp b/gfx/gfx.gyp deleted file mode 100644 index ac512f3..0000000 --- a/gfx/gfx.gyp +++ /dev/null @@ -1,231 +0,0 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -{ - 'variables': { - 'chromium_code': 1, - 'grit_info_cmd': ['python', '../tools/grit/grit_info.py', - '<@(grit_defines)'], - 'grit_cmd': ['python', '../tools/grit/grit.py'], - 'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/gfx', - }, - 'targets': [ - { - 'target_name': 'gfx_unittests', - 'type': 'executable', - 'msvs_guid': 'C8BD2821-EAE5-4AC6-A0E4-F82CAC2956CC', - 'dependencies': [ - 'gfx', - 'gfx_resources', - '../base/base.gyp:test_support_base', - '../skia/skia.gyp:skia', - '../testing/gtest.gyp:gtest', - ], - 'sources': [ - 'blit_unittest.cc', - 'codec/jpeg_codec_unittest.cc', - 'codec/png_codec_unittest.cc', - 'color_utils_unittest.cc', - 'font_unittest.cc', - 'insets_unittest.cc', - 'rect_unittest.cc', - 'run_all_unittests.cc', - 'scoped_image_unittest.cc', - 'skbitmap_operations_unittest.cc', - 'test_suite.cc', - 'test_suite.h', - '<(SHARED_INTERMEDIATE_DIR)/gfx/gfx_resources.rc', - ], - 'include_dirs': [ - '..', - ], - 'conditions': [ - ['OS=="win"', { - 'sources': [ - # TODO(brettw) re-enable this when the dependencies on WindowImpl are fixed! - 'canvas_direct2d_unittest.cc', - 'icon_util_unittest.cc', - 'native_theme_win_unittest.cc', - ], - 'include_dirs': [ - '..', - '<(DEPTH)/third_party/wtl/include', - ], - 'msvs_settings': { - 'VCLinkerTool': { - 'DelayLoadDLLs': [ - 'd2d1.dll', - 'd3d10_1.dll', - ], - 'AdditionalDependencies': [ - 'd2d1.lib', - 'd3d10_1.lib', - ], - }, - } - }], - ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', { - 'dependencies': [ - '../build/linux/system.gyp:gtk', - ], - }], - ], - }, - { - 'target_name': 'gfx', - 'type': '<(library)', - 'msvs_guid': '13A8D36C-0467-4B4E-BAA3-FD69C45F076A', - 'dependencies': [ - '../base/base.gyp:base', - '../base/base.gyp:base_i18n', - '../skia/skia.gyp:skia', - '../third_party/icu/icu.gyp:icui18n', - '../third_party/icu/icu.gyp:icuuc', - '../third_party/libpng/libpng.gyp:libpng', - '../third_party/zlib/zlib.gyp:zlib', - 'gfx_resources', - '<(libjpeg_gyp_path):libjpeg', - ], - 'sources': [ - 'blit.cc', - 'blit.h', - 'brush.h', - 'canvas.cc', - 'canvas.h', - 'canvas_skia.h', - 'canvas_skia.cc', - 'canvas_skia_linux.cc', - 'canvas_skia_mac.mm', - 'canvas_skia_paint.h', - 'canvas_skia_win.cc', - 'codec/jpeg_codec.cc', - 'codec/jpeg_codec.h', - 'codec/png_codec.cc', - 'codec/png_codec.h', - 'color_utils.cc', - 'color_utils.h', - 'favicon_size.h', - 'font.h', - 'font.cc', - 'gfx_paths.cc', - 'gfx_paths.h', - 'gfx_module.cc', - 'gfx_module.h', - 'insets.cc', - 'insets.h', - 'native_widget_types.h', - 'path.cc', - 'path.h', - 'path_gtk.cc', - 'path_win.cc', - 'platform_font.h', - 'platform_font_gtk.h', - 'platform_font_gtk.cc', - 'platform_font_mac.h', - 'platform_font_mac.mm', - 'platform_font_win.h', - 'platform_font_win.cc', - 'point.cc', - 'point.h', - 'rect.cc', - 'rect.h', - 'scoped_cg_context_state_mac.h', - 'scoped_image.h', - 'scrollbar_size.cc', - 'scrollbar_size.h', - 'size.cc', - 'size.h', - 'skbitmap_operations.cc', - 'skbitmap_operations.h', - 'skia_util.cc', - 'skia_util.h', - 'skia_utils_gtk.cc', - 'skia_utils_gtk.h', - ], - 'conditions': [ - ['OS=="win"', { - 'sources': [ - 'canvas_direct2d.cc', - 'canvas_direct2d.h', - 'gdi_util.cc', - 'gdi_util.h', - 'icon_util.cc', - 'icon_util.h', - 'native_theme_win.cc', - 'native_theme_win.h', - 'win_util.cc', - 'win_util.h', - ], - 'include_dirs': [ - '..', - '<(DEPTH)/third_party/wtl/include', - ], - }], - ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', { - 'dependencies': [ - # font_gtk.cc uses fontconfig. - # TODO(evanm): I think this is wrong; it should just use GTK. - '../build/linux/system.gyp:fontconfig', - '../build/linux/system.gyp:gtk', - ], - 'sources': [ - 'gtk_native_view_id_manager.cc', - 'gtk_native_view_id_manager.h', - 'gtk_preserve_window.cc', - 'gtk_preserve_window.h', - 'gtk_util.cc', - 'gtk_util.h', - 'native_theme_linux.cc', - 'native_theme_linux.h', - 'native_widget_types_gtk.cc', - ], - }], - ], - }, - { - # theme_resources also generates a .cc file, so it can't use the rules above. - 'target_name': 'gfx_resources', - 'type': 'none', - 'msvs_guid' : '5738AE53-E919-4987-A2EF-15FDBD8F90F6', - 'actions': [ - { - 'action_name': 'gfx_resources', - 'variables': { - 'input_path': 'gfx_resources.grd', - }, - 'inputs': [ - '<!@(<(grit_info_cmd) --inputs <(input_path))', - ], - 'outputs': [ - '<!@(<(grit_info_cmd) --outputs \'<(grit_out_dir)\' <(input_path))', - ], - 'action': [ - '<@(grit_cmd)', - '-i', '<(input_path)', 'build', - '-o', '<(grit_out_dir)', - '<@(grit_defines)', - ], - 'message': 'Generating resources from <(input_path)', - }, - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(grit_out_dir)', - ], - }, - 'conditions': [ - ['OS=="win"', { - 'dependencies': ['../build/win/system.gyp:cygwin'], - }], - ], - }, - - ], -} - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/gfx/gfx_module.cc b/gfx/gfx_module.cc deleted file mode 100644 index 882efad..0000000 --- a/gfx/gfx_module.cc +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/gfx_module.h" - -namespace gfx { - -static GfxModule::ResourceProvider resource_provider = NULL; - -// static -void GfxModule::SetResourceProvider(ResourceProvider func) { - resource_provider = func; -} - -// static -base::StringPiece GfxModule::GetResource(int key) { - return resource_provider ? resource_provider(key) : base::StringPiece(); -} - -} // namespace gfx diff --git a/gfx/gfx_module.h b/gfx/gfx_module.h index 91f8963..aa9510c 100644 --- a/gfx/gfx_module.h +++ b/gfx/gfx_module.h @@ -6,29 +6,7 @@ #define GFX_MODULE_H_ #pragma once -#include "base/basictypes.h" -#include "base/string_piece.h" - -namespace gfx { - -// Defines global initializers and associated methods for the gfx module. -// See net/base/net_module.h for more details. -class GfxModule { - public: - typedef base::StringPiece (*ResourceProvider)(int key); - - // Set the function to call when the gfx module needs resources - static void SetResourceProvider(ResourceProvider func); - - // Call the resource provider (if one exists) to get the specified resource. - // Returns an empty string if the resource does not exist or if there is no - // resource provider. - static base::StringPiece GetResource(int key); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(GfxModule); -}; - -} // namespace gfx +#include "ui/gfx/gfx_module.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_MODULE_H_ diff --git a/gfx/gfx_paths.cc b/gfx/gfx_paths.cc deleted file mode 100644 index bcb82ab..0000000 --- a/gfx/gfx_paths.cc +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/gfx_paths.h" - -#include "base/command_line.h" -#include "base/file_path.h" -#include "base/file_util.h" -#include "base/path_service.h" - -namespace gfx { - -bool PathProvider(int key, FilePath* result) { - // Assume that we will not need to create the directory if it does not exist. - // This flag can be set to true for the cases where we want to create it. - bool create_dir = false; - - FilePath cur; - switch (key) { - // The following are only valid in the development environment, and - // will fail if executed from an installed executable (because the - // generated path won't exist). - case DIR_TEST_DATA: - if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur)) - return false; - cur = cur.Append(FILE_PATH_LITERAL("gfx")); - cur = cur.Append(FILE_PATH_LITERAL("test")); - cur = cur.Append(FILE_PATH_LITERAL("data")); - if (!file_util::PathExists(cur)) // we don't want to create this - return false; - break; - default: - return false; - } - - if (create_dir && !file_util::PathExists(cur) && - !file_util::CreateDirectory(cur)) - return false; - - *result = cur; - return true; -} - -// This cannot be done as a static initializer sadly since Visual Studio will -// eliminate this object file if there is no direct entry point into it. -void RegisterPathProvider() { - PathService::RegisterProvider(PathProvider, PATH_START, PATH_END); -} - -} // namespace gfx diff --git a/gfx/gfx_paths.h b/gfx/gfx_paths.h index 596fba3..8ee96bf 100644 --- a/gfx/gfx_paths.h +++ b/gfx/gfx_paths.h @@ -6,23 +6,7 @@ #define GFX_GFX_PATHS_H_ #pragma once -// This file declares path keys for the app module. These can be used with -// the PathService to access various special directories and files. - -namespace gfx { - -enum { - PATH_START = 2000, - - // Valid only in development environment; TODO(darin): move these - DIR_TEST_DATA, // Directory where unit test data resides. - - PATH_END -}; - -// Call once to register the provider for the path keys defined above. -void RegisterPathProvider(); - -} // namespace gfx +#include "ui/gfx/gfx_paths.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_GFX_PATHS_H_ diff --git a/gfx/gfx_resources.grd b/gfx/gfx_resources.grd deleted file mode 100644 index 357679d..0000000 --- a/gfx/gfx_resources.grd +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<grit latest_public_release="0" current_release="1"> - <outputs> - <output filename="grit/gfx_resources.h" type="rc_header"> - <emit emit_type='prepend'></emit> - </output> - <output filename="grit/gfx_resources_map.cc" type="resource_map_source" /> - <output filename="grit/gfx_resources_map.h" type="resource_map_header" /> - <output filename="gfx_resources.pak" type="data_package" /> - <output filename="gfx_resources.rc" type="rc_all" /> - </outputs> - <release seq="1"> - <includes> - <if expr="os.find('win') != -1"> - <!-- IDR_BITMAP_BRUSH_IMAGE is for canvas_direct2d_unittest on win --> - <include name="IDR_BITMAP_BRUSH_IMAGE" file="resources\bitmap_brush_image.png" type="BINDATA" /> - </if> - - <if expr="os == 'linux2' or os.find('bsd') != -1 or os == 'sunos5'"> - <include name="IDR_LINUX_CHECKBOX_DISABLED_INDETERMINATE" file="resources\linux-checkbox-disabled-indeterminate.png" type="BINDATA" /> - <include name="IDR_LINUX_CHECKBOX_DISABLED_OFF" file="resources\linux-checkbox-disabled-off.png" type="BINDATA" /> - <include name="IDR_LINUX_CHECKBOX_DISABLED_ON" file="resources\linux-checkbox-disabled-on.png" type="BINDATA" /> - <include name="IDR_LINUX_CHECKBOX_INDETERMINATE" file="resources\linux-checkbox-indeterminate.png" type="BINDATA" /> - <include name="IDR_LINUX_CHECKBOX_OFF" file="resources\linux-checkbox-off.png" type="BINDATA" /> - <include name="IDR_LINUX_CHECKBOX_ON" file="resources\linux-checkbox-on.png" type="BINDATA" /> - <include name="IDR_LINUX_RADIO_DISABLED_OFF" file="resources\linux-radio-disabled-off.png" type="BINDATA" /> - <include name="IDR_LINUX_RADIO_DISABLED_ON" file="resources\linux-radio-disabled-on.png" type="BINDATA" /> - <include name="IDR_LINUX_RADIO_OFF" file="resources\linux-radio-off.png" type="BINDATA" /> - <include name="IDR_LINUX_RADIO_ON" file="resources\linux-radio-on.png" type="BINDATA" /> - <include name="IDR_PROGRESS_BAR" file="resources\linux-progress-bar.png" type="BINDATA" /> - <include name="IDR_PROGRESS_BORDER_LEFT" file="resources\linux-progress-border-left.png" type="BINDATA" /> - <include name="IDR_PROGRESS_BORDER_RIGHT" file="resources\linux-progress-border-right.png" type="BINDATA" /> - <include name="IDR_PROGRESS_VALUE" file="resources\linux-progress-value.png" type="BINDATA" /> - </if> - </includes> - </release> -</grit> - diff --git a/gfx/gtk_native_view_id_manager.cc b/gfx/gtk_native_view_id_manager.cc deleted file mode 100644 index e9e72f2..0000000 --- a/gfx/gtk_native_view_id_manager.cc +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/gtk_native_view_id_manager.h" - -#include <gtk/gtk.h> -#include <gdk/gdkx.h> - -#include "base/logging.h" -#include "base/rand_util.h" -#include "gfx/gtk_preserve_window.h" - -// ----------------------------------------------------------------------------- -// Bounce functions for GTK to callback into a C++ object... - -void OnRealize(gfx::NativeView widget, void* arg) { - GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg); - manager->OnRealize(widget); -} - -void OnUnrealize(gfx::NativeView widget, void *arg) { - GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg); - manager->OnUnrealize(widget); -} - -static void OnDestroy(GtkObject* obj, void* arg) { - GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg); - manager->OnDestroy(reinterpret_cast<GtkWidget*>(obj)); -} - -// ----------------------------------------------------------------------------- - - -// ----------------------------------------------------------------------------- -// Public functions... - -GtkNativeViewManager::GtkNativeViewManager() { -} - -GtkNativeViewManager::~GtkNativeViewManager() { -} - -// static -GtkNativeViewManager* GtkNativeViewManager::GetInstance() { - return Singleton<GtkNativeViewManager>::get(); -} - -gfx::NativeViewId GtkNativeViewManager::GetIdForWidget(gfx::NativeView widget) { - // This is just for unit tests: - if (!widget) - return 0; - - base::AutoLock locked(lock_); - - std::map<gfx::NativeView, gfx::NativeViewId>::const_iterator i = - native_view_to_id_.find(widget); - - if (i != native_view_to_id_.end()) - return i->second; - - gfx::NativeViewId new_id = - static_cast<gfx::NativeViewId>(base::RandUint64()); - while (id_to_info_.find(new_id) != id_to_info_.end()) - new_id = static_cast<gfx::NativeViewId>(base::RandUint64()); - - NativeViewInfo info; - info.widget = widget; - if (GTK_WIDGET_REALIZED(widget)) { - GdkWindow *gdk_window = widget->window; - DCHECK(gdk_window); - info.x_window_id = GDK_WINDOW_XID(gdk_window); - } - - native_view_to_id_[widget] = new_id; - id_to_info_[new_id] = info; - - g_signal_connect(widget, "realize", G_CALLBACK(::OnRealize), this); - g_signal_connect(widget, "unrealize", G_CALLBACK(::OnUnrealize), this); - g_signal_connect(widget, "destroy", G_CALLBACK(::OnDestroy), this); - - return new_id; -} - -bool GtkNativeViewManager::GetXIDForId(XID* output, gfx::NativeViewId id) { - base::AutoLock locked(lock_); - - std::map<gfx::NativeViewId, NativeViewInfo>::const_iterator i = - id_to_info_.find(id); - - if (i == id_to_info_.end()) - return false; - - *output = i->second.x_window_id; - return true; -} - -bool GtkNativeViewManager::GetPermanentXIDForId(XID* output, - gfx::NativeViewId id) { - base::AutoLock locked(lock_); - - std::map<gfx::NativeViewId, NativeViewInfo>::iterator i = - id_to_info_.find(id); - - if (i == id_to_info_.end()) - return false; - - // We only return permanent XIDs for widgets that allow us to guarantee that - // the XID will not change. - DCHECK(GTK_IS_PRESERVE_WINDOW(i->second.widget)); - GtkPreserveWindow* widget = - reinterpret_cast<GtkPreserveWindow*>(i->second.widget); - gtk_preserve_window_set_preserve(widget, TRUE); - - *output = GDK_WINDOW_XID(i->second.widget->window); - - // Update the reference count on the permanent XID. - PermanentXIDInfo info; - info.widget = widget; - info.ref_count = 1; - std::pair<std::map<XID, PermanentXIDInfo>::iterator, bool> ret = - perm_xid_to_info_.insert(std::make_pair(*output, info)); - - if (!ret.second) { - DCHECK(ret.first->second.widget == widget); - ret.first->second.ref_count++; - } - - return true; -} - -void GtkNativeViewManager::ReleasePermanentXID(XID xid) { - base::AutoLock locked(lock_); - - std::map<XID, PermanentXIDInfo>::iterator i = - perm_xid_to_info_.find(xid); - - if (i == perm_xid_to_info_.end()) - return; - - if (i->second.ref_count > 1) { - i->second.ref_count--; - } else { - if (i->second.widget) { - gtk_preserve_window_set_preserve(i->second.widget, FALSE); - } else { - GdkWindow* window = reinterpret_cast<GdkWindow*>( - gdk_xid_table_lookup(xid)); - DCHECK(window); - gdk_window_destroy(window); - } - perm_xid_to_info_.erase(i); - } -} - -// ----------------------------------------------------------------------------- - - -// ----------------------------------------------------------------------------- -// Private functions... - -gfx::NativeViewId GtkNativeViewManager::GetWidgetId(gfx::NativeView widget) { - lock_.AssertAcquired(); - - std::map<gfx::NativeView, gfx::NativeViewId>::const_iterator i = - native_view_to_id_.find(widget); - - CHECK(i != native_view_to_id_.end()); - return i->second; -} - -void GtkNativeViewManager::OnRealize(gfx::NativeView widget) { - base::AutoLock locked(lock_); - - const gfx::NativeViewId id = GetWidgetId(widget); - std::map<gfx::NativeViewId, NativeViewInfo>::iterator i = - id_to_info_.find(id); - - CHECK(i != id_to_info_.end()); - CHECK(widget->window); - - i->second.x_window_id = GDK_WINDOW_XID(widget->window); -} - -void GtkNativeViewManager::OnUnrealize(gfx::NativeView widget) { - base::AutoLock unrealize_locked(unrealize_lock_); - base::AutoLock locked(lock_); - - const gfx::NativeViewId id = GetWidgetId(widget); - std::map<gfx::NativeViewId, NativeViewInfo>::iterator i = - id_to_info_.find(id); - - CHECK(i != id_to_info_.end()); -} - -void GtkNativeViewManager::OnDestroy(gfx::NativeView widget) { - base::AutoLock locked(lock_); - - std::map<gfx::NativeView, gfx::NativeViewId>::iterator i = - native_view_to_id_.find(widget); - CHECK(i != native_view_to_id_.end()); - - std::map<gfx::NativeViewId, NativeViewInfo>::iterator j = - id_to_info_.find(i->second); - CHECK(j != id_to_info_.end()); - - // If the XID is supposed to outlive the widget, mark it - // in the lookup table. - if (GTK_IS_PRESERVE_WINDOW(widget) && - gtk_preserve_window_get_preserve( - reinterpret_cast<GtkPreserveWindow*>(widget))) { - std::map<XID, PermanentXIDInfo>::iterator k = - perm_xid_to_info_.find(GDK_WINDOW_XID(widget->window)); - - if (k != perm_xid_to_info_.end()) - k->second.widget = NULL; - } - - native_view_to_id_.erase(i); - id_to_info_.erase(j); -} - -// ----------------------------------------------------------------------------- diff --git a/gfx/gtk_native_view_id_manager.h b/gfx/gtk_native_view_id_manager.h index 8772bc8..8fd601b 100644 --- a/gfx/gtk_native_view_id_manager.h +++ b/gfx/gtk_native_view_id_manager.h @@ -6,136 +6,7 @@ #define GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_ #pragma once -#include <map> - -#include "base/singleton.h" -#include "base/synchronization/lock.h" -#include "gfx/native_widget_types.h" - -typedef unsigned long XID; -struct _GtkPreserveWindow; - -// NativeViewIds are the opaque values which the renderer holds as a reference -// to a window. These ids are often used in sync calls from the renderer and -// one cannot terminate sync calls on the UI thread as that can lead to -// deadlocks. -// -// Because of this, we have the BACKGROUND_X11 thread for these calls and this -// thread has a separate X connection in order to answer them. But one cannot -// use GTK on multiple threads, so the BACKGROUND_X11 thread deals only in Xlib -// calls and, thus, XIDs. -// -// So we could make NativeViewIds be the X id of the window. However, at the -// time when we need to tell the renderer about its NativeViewId, an XID isn't -// availible and it goes very much against the grain of the code to make it so. -// Also, we worry that GTK might choose to change the underlying X window id -// when, say, the widget is hidden or repacked. Finally, if we used XIDs then a -// compromised renderer could start asking questions about any X windows on the -// system. -// -// Thus, we have this object. It produces random NativeViewIds from GtkWidget -// pointers and observes the various signals from the widget for when an X -// window is created, destroyed etc. Thus it provides a thread safe mapping -// from NativeViewIds to the current XID for that widget. -class GtkNativeViewManager { - public: - // Returns the singleton instance. - static GtkNativeViewManager* GetInstance(); - - // Must be called from the UI thread: - // - // Return a NativeViewId for the given widget and attach to the various - // signals emitted by that widget. The NativeViewId is pseudo-randomly - // allocated so that a compromised renderer trying to guess values will fail - // with high probability. The NativeViewId will not be reused for the - // lifetime of the GtkWidget. - gfx::NativeViewId GetIdForWidget(gfx::NativeView widget); - - // May be called from any thread: - // - // xid: (output) the resulting X window ID, or 0 - // id: a value previously returned from GetIdForWidget - // returns: true if |id| is a valid id, false otherwise. - // - // If the widget referenced by |id| does not current have an X window id, - // |*xid| is set to 0. - bool GetXIDForId(XID* xid, gfx::NativeViewId id); - - // Must be called from the UI thread because we may need the associated - // widget to create a window. - // - // Keeping the XID permanent requires a bit of overhead, so it must - // be explicitly requested. - // - // xid: (output) the resulting X window - // id: a value previously returned from GetIdForWidget - // returns: true if |id| is a valid id, false otherwise. - bool GetPermanentXIDForId(XID* xid, gfx::NativeViewId id); - - // Must be called from the UI thread because we may need to access a - // GtkWidget or destroy a GdkWindow. - // - // If the widget associated with the XID is still alive, allow the widget - // to destroy the associated XID when it wants. Otherwise, destroy the - // GdkWindow associated with the XID. - void ReleasePermanentXID(XID xid); - - // These are actually private functions, but need to be called from statics. - void OnRealize(gfx::NativeView widget); - void OnUnrealize(gfx::NativeView widget); - void OnDestroy(gfx::NativeView widget); - - base::Lock& unrealize_lock() { return unrealize_lock_; } - - private: - // This object is a singleton: - GtkNativeViewManager(); - ~GtkNativeViewManager(); - friend struct DefaultSingletonTraits<GtkNativeViewManager>; - - struct NativeViewInfo { - NativeViewInfo() : widget(NULL), x_window_id(0) { - } - gfx::NativeView widget; - XID x_window_id; - }; - - gfx::NativeViewId GetWidgetId(gfx::NativeView id); - - // This lock can be used to block GTK from unrealizing windows. This is needed - // when the BACKGROUND_X11 thread is using a window obtained via GetXIDForId, - // and can't allow the X11 resource to be deleted. - base::Lock unrealize_lock_; - - // protects native_view_to_id_ and id_to_info_ - base::Lock lock_; - - // If asked for an id for the same widget twice, we want to return the same - // id. So this records the current mapping. - std::map<gfx::NativeView, gfx::NativeViewId> native_view_to_id_; - std::map<gfx::NativeViewId, NativeViewInfo> id_to_info_; - - struct PermanentXIDInfo { - PermanentXIDInfo() : widget(NULL), ref_count(0) { - } - _GtkPreserveWindow* widget; - int ref_count; - }; - - // Used to maintain the reference count for permanent XIDs - // (referenced by GetPermanentXIDForId and dereferenced by - // ReleasePermanentXID). Only those XIDs with a positive reference count - // will be in the table. - // - // In general, several GTK widgets may share the same X window. We assume - // that is not true of the widgets stored in this registry. - // - // An XID will map to NULL, if there is an outstanding reference but the - // widget was destroyed. In this case, the destruction of the X window - // is deferred to the dropping of all references. - std::map<XID, PermanentXIDInfo> perm_xid_to_info_; - - DISALLOW_COPY_AND_ASSIGN(GtkNativeViewManager); -}; +#include "ui/gfx/gtk_native_view_id_manager.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_ diff --git a/gfx/gtk_preserve_window.cc b/gfx/gtk_preserve_window.cc deleted file mode 100644 index 20215d1..0000000 --- a/gfx/gtk_preserve_window.cc +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/gtk_preserve_window.h" - -#include <gdk/gdkwindow.h> -#include <gtk/gtk.h> -#include <gtk/gtkwidget.h> -#include <gtk/gtkfixed.h> - -G_BEGIN_DECLS - -#define GTK_PRESERVE_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - GTK_TYPE_PRESERVE_WINDOW, \ - GtkPreserveWindowPrivate)) - -typedef struct _GtkPreserveWindowPrivate GtkPreserveWindowPrivate; - -struct _GtkPreserveWindowPrivate { - // If true, don't create/destroy windows on realize/unrealize. - gboolean preserve_window; - - // Whether or not we delegate the resize of the GdkWindow - // to someone else. - gboolean delegate_resize; -}; - -G_DEFINE_TYPE(GtkPreserveWindow, gtk_preserve_window, GTK_TYPE_FIXED) - -static void gtk_preserve_window_destroy(GtkObject* object); -static void gtk_preserve_window_realize(GtkWidget* widget); -static void gtk_preserve_window_unrealize(GtkWidget* widget); -static void gtk_preserve_window_size_allocate(GtkWidget* widget, - GtkAllocation* allocation); - -static void gtk_preserve_window_class_init(GtkPreserveWindowClass *klass) { - GtkWidgetClass* widget_class = reinterpret_cast<GtkWidgetClass*>(klass); - widget_class->realize = gtk_preserve_window_realize; - widget_class->unrealize = gtk_preserve_window_unrealize; - widget_class->size_allocate = gtk_preserve_window_size_allocate; - - GtkObjectClass* object_class = reinterpret_cast<GtkObjectClass*>(klass); - object_class->destroy = gtk_preserve_window_destroy; - - GObjectClass* gobject_class = G_OBJECT_CLASS(klass); - g_type_class_add_private(gobject_class, sizeof(GtkPreserveWindowPrivate)); -} - -static void gtk_preserve_window_init(GtkPreserveWindow* widget) { - GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget); - priv->preserve_window = FALSE; - - // These widgets always have their own window. - gtk_fixed_set_has_window(GTK_FIXED(widget), TRUE); -} - -GtkWidget* gtk_preserve_window_new() { - return GTK_WIDGET(g_object_new(GTK_TYPE_PRESERVE_WINDOW, NULL)); -} - -static void gtk_preserve_window_destroy(GtkObject* object) { - GtkWidget* widget = reinterpret_cast<GtkWidget*>(object); - GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget); - - if (widget->window) { - gdk_window_set_user_data(widget->window, NULL); - // If the window is preserved, someone else must destroy it. - if (!priv->preserve_window) - gdk_window_destroy(widget->window); - widget->window = NULL; - } - - GTK_OBJECT_CLASS(gtk_preserve_window_parent_class)->destroy(object); -} - -static void gtk_preserve_window_realize(GtkWidget* widget) { - g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget)); - - if (widget->window) { - gdk_window_reparent(widget->window, - gtk_widget_get_parent_window(widget), - widget->allocation.x, - widget->allocation.y); - widget->style = gtk_style_attach(widget->style, widget->window); - gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL); - - gint event_mask = gtk_widget_get_events(widget); - event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK; - gdk_window_set_events(widget->window, (GdkEventMask) event_mask); - gdk_window_set_user_data(widget->window, widget); - - // Deprecated as of GTK 2.22. Used for compatibility. - // It should be: gtk_widget_set_realized(widget, TRUE) - GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); - } else { - GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->realize(widget); - } -} - -static void gtk_preserve_window_unrealize(GtkWidget* widget) { - g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget)); - - GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget); - if (priv->preserve_window) { - GtkWidgetClass* widget_class = - GTK_WIDGET_CLASS(gtk_preserve_window_parent_class); - GtkContainerClass* container_class = - GTK_CONTAINER_CLASS(gtk_preserve_window_parent_class); - - // Deprecated as of GTK 2.22. Used for compatibility. - // It should be: gtk_widget_get_mapped() - if (GTK_WIDGET_MAPPED(widget)) { - widget_class->unmap(widget); - - // Deprecated as of GTK 2.22. Used for compatibility. - // It should be: gtk_widget_set_mapped(widget, FALSE) - GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED); - } - - // This is the behavior from GtkWidget, inherited by GtkFixed. - // It is unclear why we should not call the potentially overridden - // unrealize method (via the callback), but doing so causes errors. - container_class->forall( - GTK_CONTAINER(widget), FALSE, - reinterpret_cast<GtkCallback>(gtk_widget_unrealize), NULL); - - gtk_style_detach(widget->style); - gdk_window_reparent(widget->window, gdk_get_default_root_window(), 0, 0); - gtk_selection_remove_all(widget); - gdk_window_set_user_data(widget->window, NULL); - - // Deprecated as of GTK 2.22. Used for compatibility. - // It should be: gtk_widget_set_realized(widget, FALSE) - GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED); - } else { - GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->unrealize(widget); - } -} - -gboolean gtk_preserve_window_get_preserve(GtkPreserveWindow* window) { - g_return_val_if_fail(GTK_IS_PRESERVE_WINDOW(window), FALSE); - GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(window); - - return priv->preserve_window; -} - -void gtk_preserve_window_set_preserve(GtkPreserveWindow* window, - gboolean value) { - g_return_if_fail(GTK_IS_PRESERVE_WINDOW(window)); - GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(window); - priv->preserve_window = value; - - GtkWidget* widget = GTK_WIDGET(window); - if (value && !widget->window) { - GdkWindowAttr attributes; - gint attributes_mask; - - // We may not know the width and height, so we rely on the fact - // that a size-allocation will resize it later. - attributes.width = 1; - attributes.height = 1; - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - - attributes.visual = gtk_widget_get_visual(widget); - attributes.colormap = gtk_widget_get_colormap(widget); - - attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP; - widget->window = gdk_window_new( - gdk_get_default_root_window(), &attributes, attributes_mask); - } else if (!value && widget->window && !GTK_WIDGET_REALIZED(widget)) { - gdk_window_destroy(widget->window); - widget->window = NULL; - } -} - -void gtk_preserve_window_size_allocate(GtkWidget* widget, - GtkAllocation* allocation) { - g_return_if_fail(GTK_IS_PRESERVE_WINDOW(widget)); - GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget); - - if (priv->delegate_resize) { - // Just update the state. Someone else will gdk_window_resize the - // associated GdkWindow. - widget->allocation = *allocation; - } else { - GTK_WIDGET_CLASS(gtk_preserve_window_parent_class)->size_allocate( - widget, allocation); - } -} - -void gtk_preserve_window_delegate_resize(GtkPreserveWindow* widget, - gboolean delegate) { - GtkPreserveWindowPrivate* priv = GTK_PRESERVE_WINDOW_GET_PRIVATE(widget); - priv->delegate_resize = delegate; -} - -G_END_DECLS diff --git a/gfx/gtk_preserve_window.h b/gfx/gtk_preserve_window.h index 2bbd277..bf62d00 100644 --- a/gfx/gtk_preserve_window.h +++ b/gfx/gtk_preserve_window.h @@ -6,59 +6,7 @@ #define GFX_GTK_PRESERVE_WINDOW_H_ #pragma once -#include <gdk/gdk.h> -#include <gtk/gtk.h> - -// GtkFixed creates an X window when realized and destroys an X window -// when unrealized. GtkPreserveWindow allows overrides this -// behaviour. When preserve is set (via gtk_preserve_window_set_preserve), -// the X window is only destroyed when the widget is destroyed. - -G_BEGIN_DECLS - -#define GTK_TYPE_PRESERVE_WINDOW \ - (gtk_preserve_window_get_type()) -#define GTK_PRESERVE_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_PERSERVE_WINDOW, \ - GtkPreserveWindow)) -#define GTK_PRESERVE_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_PRESERVE_WINDOW, \ - GtkPreserveWindowClass)) -#define GTK_IS_PRESERVE_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_PRESERVE_WINDOW)) -#define GTK_IS_PRESERVE_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_PRESERVE_WINDOW)) -#define GTK_PRESERVE_WINDOW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_PRESERVE_WINDOW, \ - GtkPreserveWindowClass)) - -typedef struct _GtkPreserveWindow GtkPreserveWindow; -typedef struct _GtkPreserveWindowClass GtkPreserveWindowClass; - -struct _GtkPreserveWindow { - // Parent class. - GtkFixed fixed; -}; - -struct _GtkPreserveWindowClass { - GtkFixedClass parent_class; -}; - -GType gtk_preserve_window_get_type() G_GNUC_CONST; -GtkWidget* gtk_preserve_window_new(); - -// Whether or not we should preserve associated windows as the widget -// is realized or unrealized. -gboolean gtk_preserve_window_get_preserve(GtkPreserveWindow* widget); -void gtk_preserve_window_set_preserve(GtkPreserveWindow* widget, - gboolean value); - -// Whether or not someone else will gdk_window_resize the GdkWindow associated -// with this widget (needed by the GPU process to synchronize resizing -// with swapped between front and back buffer). -void gtk_preserve_window_delegate_resize(GtkPreserveWindow* widget, - gboolean delegate); - -G_END_DECLS +#include "ui/gfx/gtk_preserve_window.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_GTK_PRESERVE_WINDOW_H_ diff --git a/gfx/gtk_util.cc b/gfx/gtk_util.cc deleted file mode 100644 index fc240e0..0000000 --- a/gfx/gtk_util.cc +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/gtk_util.h" - -#include <gdk/gdk.h> -#include <gtk/gtk.h> -#include <stdlib.h> - -#include "base/basictypes.h" -#include "base/command_line.h" -#include "base/linux_util.h" -#include "gfx/rect.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkUnPreMultiply.h" - -namespace { - -// A process wide singleton that manages our usage of gdk -// cursors. gdk_cursor_new() hits the disk in several places and GdkCursor -// instances can be reused throughout the process. -class GdkCursorCache { - public: - GdkCursorCache() {} - ~GdkCursorCache() { - for (std::map<GdkCursorType, GdkCursor*>::iterator it = - cursor_cache_.begin(); it != cursor_cache_.end(); ++it) { - gdk_cursor_unref(it->second); - } - cursor_cache_.clear(); - } - - GdkCursor* GetCursorImpl(GdkCursorType type) { - std::map<GdkCursorType, GdkCursor*>::iterator it = cursor_cache_.find(type); - GdkCursor* cursor = NULL; - if (it == cursor_cache_.end()) { - cursor = gdk_cursor_new(type); - cursor_cache_.insert(std::make_pair(type, cursor)); - } else { - cursor = it->second; - } - - // It is not necessary to add a reference here. The callers can ref the - // cursor if they need it for something. - return cursor; - } - - std::map<GdkCursorType, GdkCursor*> cursor_cache_; - - DISALLOW_COPY_AND_ASSIGN(GdkCursorCache); -}; - -void FreePixels(guchar* pixels, gpointer data) { - free(data); -} - -// Common implementation of ConvertAcceleratorsFromWindowsStyle() and -// RemoveWindowsStyleAccelerators(). -// Replaces all ampersands (as used in our grd files to indicate mnemonics) -// to |target|. Similarly any underscores get replaced with two underscores as -// is needed by pango. -std::string ConvertAmperstandsTo(const std::string& label, - const std::string& target) { - std::string ret; - ret.reserve(label.length() * 2); - for (size_t i = 0; i < label.length(); ++i) { - if ('_' == label[i]) { - ret.push_back('_'); - ret.push_back('_'); - } else if ('&' == label[i]) { - if (i + 1 < label.length() && '&' == label[i + 1]) { - ret.push_back('&'); - ++i; - } else { - ret.append(target); - } - } else { - ret.push_back(label[i]); - } - } - - return ret; -} - -} // namespace - -namespace gfx { - -void GtkInitFromCommandLine(const CommandLine& command_line) { - const std::vector<std::string>& args = command_line.argv(); - int argc = args.size(); - scoped_array<char *> argv(new char *[argc + 1]); - for (size_t i = 0; i < args.size(); ++i) { - // TODO(piman@google.com): can gtk_init modify argv? Just being safe - // here. - argv[i] = strdup(args[i].c_str()); - } - argv[argc] = NULL; - char **argv_pointer = argv.get(); - - gtk_init(&argc, &argv_pointer); - for (size_t i = 0; i < args.size(); ++i) { - free(argv[i]); - } -} - -GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap* bitmap) { - if (bitmap->isNull()) - return NULL; - - bitmap->lockPixels(); - - int width = bitmap->width(); - int height = bitmap->height(); - int stride = bitmap->rowBytes(); - - // SkBitmaps are premultiplied, we need to unpremultiply them. - const int kBytesPerPixel = 4; - uint8* divided = static_cast<uint8*>(malloc(height * stride)); - - for (int y = 0, i = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - uint32 pixel = bitmap->getAddr32(0, y)[x]; - - int alpha = SkColorGetA(pixel); - if (alpha != 0 && alpha != 255) { - SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel); - divided[i + 0] = SkColorGetR(unmultiplied); - divided[i + 1] = SkColorGetG(unmultiplied); - divided[i + 2] = SkColorGetB(unmultiplied); - divided[i + 3] = alpha; - } else { - divided[i + 0] = SkColorGetR(pixel); - divided[i + 1] = SkColorGetG(pixel); - divided[i + 2] = SkColorGetB(pixel); - divided[i + 3] = alpha; - } - i += kBytesPerPixel; - } - } - - // This pixbuf takes ownership of our malloc()ed data and will - // free it for us when it is destroyed. - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( - divided, - GDK_COLORSPACE_RGB, // The only colorspace gtk supports. - true, // There is an alpha channel. - 8, - width, height, stride, &FreePixels, divided); - - bitmap->unlockPixels(); - return pixbuf; -} - -void SubtractRectanglesFromRegion(GdkRegion* region, - const std::vector<Rect>& cutouts) { - for (size_t i = 0; i < cutouts.size(); ++i) { - GdkRectangle rect = cutouts[i].ToGdkRectangle(); - GdkRegion* rect_region = gdk_region_rectangle(&rect); - gdk_region_subtract(region, rect_region); - // TODO(deanm): It would be nice to be able to reuse the GdkRegion here. - gdk_region_destroy(rect_region); - } -} - -double GetPangoResolution() { - static double resolution; - static bool determined_resolution = false; - if (!determined_resolution) { - determined_resolution = true; - PangoContext* default_context = gdk_pango_context_get(); - resolution = pango_cairo_context_get_resolution(default_context); - g_object_unref(default_context); - } - return resolution; -} - -GdkCursor* GetCursor(int type) { - static GdkCursorCache impl; - return impl.GetCursorImpl(static_cast<GdkCursorType>(type)); -} - -std::string ConvertAcceleratorsFromWindowsStyle(const std::string& label) { - return ConvertAmperstandsTo(label, "_"); -} - -std::string RemoveWindowsStyleAccelerators(const std::string& label) { - return ConvertAmperstandsTo(label, ""); -} - -uint8_t* BGRAToRGBA(const uint8_t* pixels, int width, int height, int stride) { - if (stride == 0) - stride = width * 4; - - uint8_t* new_pixels = static_cast<uint8_t*>(malloc(height * stride)); - - // We have to copy the pixels and swap from BGRA to RGBA. - for (int i = 0; i < height; ++i) { - for (int j = 0; j < width; ++j) { - int idx = i * stride + j * 4; - new_pixels[idx] = pixels[idx + 2]; - new_pixels[idx + 1] = pixels[idx + 1]; - new_pixels[idx + 2] = pixels[idx]; - new_pixels[idx + 3] = pixels[idx + 3]; - } - } - - return new_pixels; -} - -} // namespace gfx diff --git a/gfx/gtk_util.h b/gfx/gtk_util.h index 683b80c..d8d0b49 100644 --- a/gfx/gtk_util.h +++ b/gfx/gtk_util.h @@ -6,79 +6,7 @@ #define GFX_GTK_UTIL_H_ #pragma once -#include <glib-object.h> -#include <stdint.h> - -#include <string> -#include <vector> - -#include "base/scoped_ptr.h" - -typedef struct _GdkPixbuf GdkPixbuf; -typedef struct _GdkRegion GdkRegion; -typedef struct _GdkCursor GdkCursor; - -class CommandLine; -class SkBitmap; - -namespace gfx { - -class Rect; - -// Call gtk_init() using the argc and argv from command_line. -// gtk_init() wants an argc and argv that it can mutate; we provide those, -// but leave the original CommandLine unaltered. -void GtkInitFromCommandLine(const CommandLine& command_line); - -// Convert and copy a SkBitmap to a GdkPixbuf. NOTE: this uses BGRAToRGBA, so -// it is an expensive operation. The returned GdkPixbuf will have a refcount of -// 1, and the caller is responsible for unrefing it when done. -GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap* bitmap); - -// Modify the given region by subtracting the given rectangles. -void SubtractRectanglesFromRegion(GdkRegion* region, - const std::vector<Rect>& cutouts); - -// Returns the resolution (DPI) used by pango. A negative values means the -// resolution hasn't been set. -double GetPangoResolution(); - -// Returns a static instance of a GdkCursor* object, sharable across the -// process. Caller must gdk_cursor_ref() it if they want to assume ownership. -GdkCursor* GetCursor(int type); - -// Change windows accelerator style to GTK style. (GTK uses _ for -// accelerators. Windows uses & with && as an escape for &.) -std::string ConvertAcceleratorsFromWindowsStyle(const std::string& label); - -// Removes the "&" accelerators from a Windows label. -std::string RemoveWindowsStyleAccelerators(const std::string& label); - -// Makes a copy of |pixels| with the ordering changed from BGRA to RGBA. -// The caller is responsible for free()ing the data. If |stride| is 0, it's -// assumed to be 4 * |width|. -uint8_t* BGRAToRGBA(const uint8_t* pixels, int width, int height, int stride); - -} // namespace gfx - -namespace { -// A helper class that will g_object_unref |p| when it goes out of scope. -// This never adds a ref, it only unrefs. -template <typename Type> -struct GObjectUnrefer { - void operator()(Type* ptr) const { - if (ptr) - g_object_unref(ptr); - } -}; -} // namespace - -// It's not legal C++ to have a templatized typedefs, so we wrap it in a -// struct. When using this, you need to include ::Type. E.g., -// ScopedGObject<GdkPixbufLoader>::Type loader(gdk_pixbuf_loader_new()); -template<class T> -struct ScopedGObject { - typedef scoped_ptr_malloc<T, GObjectUnrefer<T> > Type; -}; +#include "ui/gfx/gtk_util.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_GTK_UTIL_H_ diff --git a/gfx/icon_util.cc b/gfx/icon_util.cc deleted file mode 100644 index cabc505..0000000 --- a/gfx/icon_util.cc +++ /dev/null @@ -1,457 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/icon_util.h" - -#include "base/file_util.h" -#include "base/logging.h" -#include "base/scoped_ptr.h" -#include "base/win/scoped_handle.h" -#include "gfx/size.h" -#include "skia/ext/image_operations.h" -#include "third_party/skia/include/core/SkBitmap.h" - -// Defining the dimensions for the icon images. We store only one value because -// we always resize to a square image; that is, the value 48 means that we are -// going to resize the given bitmap to a 48 by 48 pixels bitmap. -// -// The icon images appear in the icon file in same order in which their -// corresponding dimensions appear in the |icon_dimensions_| array, so it is -// important to keep this array sorted. Also note that the maximum icon image -// size we can handle is 255 by 255. -const int IconUtil::icon_dimensions_[] = { - 8, // Recommended by the MSDN as a nice to have icon size. - 10, // Used by the Shell (e.g. for shortcuts). - 14, // Recommended by the MSDN as a nice to have icon size. - 16, // Toolbar, Application and Shell icon sizes. - 22, // Recommended by the MSDN as a nice to have icon size. - 24, // Used by the Shell (e.g. for shortcuts). - 32, // Toolbar, Dialog and Wizard icon size. - 40, // Quick Launch. - 48, // Alt+Tab icon size. - 64, // Recommended by the MSDN as a nice to have icon size. - 96, // Recommended by the MSDN as a nice to have icon size. - 128 // Used by the Shell (e.g. for shortcuts). -}; - -HICON IconUtil::CreateHICONFromSkBitmap(const SkBitmap& bitmap) { - // Only 32 bit ARGB bitmaps are supported. We also try to perform as many - // validations as we can on the bitmap. - SkAutoLockPixels bitmap_lock(bitmap); - if ((bitmap.getConfig() != SkBitmap::kARGB_8888_Config) || - (bitmap.width() <= 0) || (bitmap.height() <= 0) || - (bitmap.getPixels() == NULL)) - return NULL; - - // We start by creating a DIB which we'll use later on in order to create - // the HICON. We use BITMAPV5HEADER since the bitmap we are about to convert - // may contain an alpha channel and the V5 header allows us to specify the - // alpha mask for the DIB. - BITMAPV5HEADER bitmap_header; - InitializeBitmapHeader(&bitmap_header, bitmap.width(), bitmap.height()); - void* bits; - HDC hdc = ::GetDC(NULL); - HBITMAP dib; - dib = ::CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO*>(&bitmap_header), - DIB_RGB_COLORS, &bits, NULL, 0); - DCHECK(dib); - ::ReleaseDC(NULL, hdc); - memcpy(bits, bitmap.getPixels(), bitmap.width() * bitmap.height() * 4); - - // Icons are generally created using an AND and XOR masks where the AND - // specifies boolean transparency (the pixel is either opaque or - // transparent) and the XOR mask contains the actual image pixels. If the XOR - // mask bitmap has an alpha channel, the AND monochrome bitmap won't - // actually be used for computing the pixel transparency. Even though all our - // bitmap has an alpha channel, Windows might not agree when all alpha values - // are zero. So the monochrome bitmap is created with all pixels transparent - // for this case. Otherwise, it is created with all pixels opaque. - bool bitmap_has_alpha_channel = PixelsHaveAlpha( - static_cast<const uint32*>(bitmap.getPixels()), - bitmap.width() * bitmap.height()); - - scoped_array<uint8> mask_bits; - if (!bitmap_has_alpha_channel) { - // Bytes per line with paddings to make it word alignment. - size_t bytes_per_line = (bitmap.width() + 0xF) / 16 * 2; - size_t mask_bits_size = bytes_per_line * bitmap.height(); - - mask_bits.reset(new uint8[mask_bits_size]); - DCHECK(mask_bits.get()); - - // Make all pixels transparent. - memset(mask_bits.get(), 0xFF, mask_bits_size); - } - - HBITMAP mono_bitmap = ::CreateBitmap(bitmap.width(), bitmap.height(), 1, 1, - reinterpret_cast<LPVOID>(mask_bits.get())); - DCHECK(mono_bitmap); - - ICONINFO icon_info; - icon_info.fIcon = TRUE; - icon_info.xHotspot = 0; - icon_info.yHotspot = 0; - icon_info.hbmMask = mono_bitmap; - icon_info.hbmColor = dib; - HICON icon = ::CreateIconIndirect(&icon_info); - ::DeleteObject(dib); - ::DeleteObject(mono_bitmap); - return icon; -} - -SkBitmap* IconUtil::CreateSkBitmapFromHICON(HICON icon, const gfx::Size& s) { - // We start with validating parameters. - ICONINFO icon_info; - if (!icon || !(::GetIconInfo(icon, &icon_info)) || - !icon_info.fIcon || s.IsEmpty()) - return NULL; - - // Allocating memory for the SkBitmap object. We are going to create an ARGB - // bitmap so we should set the configuration appropriately. - SkBitmap* bitmap = new SkBitmap; - DCHECK(bitmap); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, s.width(), s.height()); - bitmap->allocPixels(); - bitmap->eraseARGB(0, 0, 0, 0); - SkAutoLockPixels bitmap_lock(*bitmap); - - // Now we should create a DIB so that we can use ::DrawIconEx in order to - // obtain the icon's image. - BITMAPV5HEADER h; - InitializeBitmapHeader(&h, s.width(), s.height()); - HDC dc = ::GetDC(NULL); - uint32* bits; - HBITMAP dib = ::CreateDIBSection(dc, reinterpret_cast<BITMAPINFO*>(&h), - DIB_RGB_COLORS, reinterpret_cast<void**>(&bits), NULL, 0); - DCHECK(dib); - HDC dib_dc = CreateCompatibleDC(dc); - DCHECK(dib_dc); - ::SelectObject(dib_dc, dib); - - // Windows icons are defined using two different masks. The XOR mask, which - // represents the icon image and an AND mask which is a monochrome bitmap - // which indicates the transparency of each pixel. - // - // To make things more complex, the icon image itself can be an ARGB bitmap - // and therefore contain an alpha channel which specifies the transparency - // for each pixel. Unfortunately, there is no easy way to determine whether - // or not a bitmap has an alpha channel and therefore constructing the bitmap - // for the icon is nothing but straightforward. - // - // The idea is to read the AND mask but use it only if we know for sure that - // the icon image does not have an alpha channel. The only way to tell if the - // bitmap has an alpha channel is by looking through the pixels and checking - // whether there are non-zero alpha bytes. - // - // We start by drawing the AND mask into our DIB. - size_t num_pixels = s.GetArea(); - memset(bits, 0, num_pixels * 4); - ::DrawIconEx(dib_dc, 0, 0, icon, s.width(), s.height(), 0, NULL, DI_MASK); - - // Capture boolean opacity. We may not use it if we find out the bitmap has - // an alpha channel. - bool* opaque = new bool[num_pixels]; - DCHECK(opaque); - for (size_t i = 0; i < num_pixels; ++i) - opaque[i] = !bits[i]; - - // Then draw the image itself which is really the XOR mask. - memset(bits, 0, num_pixels * 4); - ::DrawIconEx(dib_dc, 0, 0, icon, s.width(), s.height(), 0, NULL, DI_NORMAL); - memcpy(bitmap->getPixels(), static_cast<void*>(bits), num_pixels * 4); - - // Finding out whether the bitmap has an alpha channel. - bool bitmap_has_alpha_channel = PixelsHaveAlpha( - static_cast<const uint32*>(bitmap->getPixels()), num_pixels); - - // If the bitmap does not have an alpha channel, we need to build it using - // the previously captured AND mask. Otherwise, we are done. - if (!bitmap_has_alpha_channel) { - uint32* p = static_cast<uint32*>(bitmap->getPixels()); - for (size_t i = 0; i < num_pixels; ++p, ++i) { - DCHECK_EQ((*p & 0xff000000), 0u); - if (opaque[i]) - *p |= 0xff000000; - else - *p &= 0x00ffffff; - } - } - - delete [] opaque; - ::DeleteDC(dib_dc); - ::DeleteObject(dib); - ::ReleaseDC(NULL, dc); - - return bitmap; -} - -bool IconUtil::CreateIconFileFromSkBitmap(const SkBitmap& bitmap, - const FilePath& icon_path) { - // Only 32 bit ARGB bitmaps are supported. We also make sure the bitmap has - // been properly initialized. - SkAutoLockPixels bitmap_lock(bitmap); - if ((bitmap.getConfig() != SkBitmap::kARGB_8888_Config) || - (bitmap.height() <= 0) || (bitmap.width() <= 0) || - (bitmap.getPixels() == NULL)) - return false; - - // We start by creating the file. - base::win::ScopedHandle icon_file(::CreateFile(icon_path.value().c_str(), - GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); - - if (icon_file.Get() == INVALID_HANDLE_VALUE) - return false; - - // Creating a set of bitmaps corresponding to the icon images we'll end up - // storing in the icon file. Each bitmap is created by resizing the given - // bitmap to the desired size. - std::vector<SkBitmap> bitmaps; - CreateResizedBitmapSet(bitmap, &bitmaps); - DCHECK(!bitmaps.empty()); - size_t bitmap_count = bitmaps.size(); - - // Computing the total size of the buffer we need in order to store the - // images in the desired icon format. - size_t buffer_size = ComputeIconFileBufferSize(bitmaps); - unsigned char* buffer = new unsigned char[buffer_size]; - DCHECK(buffer != NULL); - memset(buffer, 0, buffer_size); - - // Setting the information in the structures residing within the buffer. - // First, we set the information which doesn't require iterating through the - // bitmap set and then we set the bitmap specific structures. In the latter - // step we also copy the actual bits. - ICONDIR* icon_dir = reinterpret_cast<ICONDIR*>(buffer); - icon_dir->idType = kResourceTypeIcon; - icon_dir->idCount = bitmap_count; - size_t icon_dir_count = bitmap_count - 1; // Note DCHECK(!bitmaps.empty())! - size_t offset = sizeof(ICONDIR) + (sizeof(ICONDIRENTRY) * icon_dir_count); - for (size_t i = 0; i < bitmap_count; i++) { - ICONIMAGE* image = reinterpret_cast<ICONIMAGE*>(buffer + offset); - DCHECK_LT(offset, buffer_size); - size_t icon_image_size = 0; - SetSingleIconImageInformation(bitmaps[i], i, icon_dir, image, offset, - &icon_image_size); - DCHECK_GT(icon_image_size, 0U); - offset += icon_image_size; - } - DCHECK_EQ(offset, buffer_size); - - // Finally, writing the data info the file. - DWORD bytes_written; - bool delete_file = false; - if (!WriteFile(icon_file.Get(), buffer, buffer_size, &bytes_written, NULL) || - bytes_written != buffer_size) - delete_file = true; - - ::CloseHandle(icon_file.Take()); - delete [] buffer; - if (delete_file) { - bool success = file_util::Delete(icon_path, false); - DCHECK(success); - } - - return !delete_file; -} - -bool IconUtil::PixelsHaveAlpha(const uint32* pixels, size_t num_pixels) { - for (const uint32* end = pixels + num_pixels; pixels != end; ++pixels) { - if ((*pixels & 0xff000000) != 0) - return true; - } - - return false; -} - -void IconUtil::InitializeBitmapHeader(BITMAPV5HEADER* header, int width, - int height) { - DCHECK(header); - memset(header, 0, sizeof(BITMAPV5HEADER)); - header->bV5Size = sizeof(BITMAPV5HEADER); - - // Note that icons are created using top-down DIBs so we must negate the - // value used for the icon's height. - header->bV5Width = width; - header->bV5Height = -height; - header->bV5Planes = 1; - header->bV5Compression = BI_RGB; - - // Initializing the bitmap format to 32 bit ARGB. - header->bV5BitCount = 32; - header->bV5RedMask = 0x00FF0000; - header->bV5GreenMask = 0x0000FF00; - header->bV5BlueMask = 0x000000FF; - header->bV5AlphaMask = 0xFF000000; - - // Use the system color space. The default value is LCS_CALIBRATED_RGB, which - // causes us to crash if we don't specify the approprite gammas, etc. See - // <http://msdn.microsoft.com/en-us/library/ms536531(VS.85).aspx> and - // <http://b/1283121>. - header->bV5CSType = LCS_WINDOWS_COLOR_SPACE; - - // Use a valid value for bV5Intent as 0 is not a valid one. - // <http://msdn.microsoft.com/en-us/library/dd183381(VS.85).aspx> - header->bV5Intent = LCS_GM_IMAGES; -} - -void IconUtil::SetSingleIconImageInformation(const SkBitmap& bitmap, - size_t index, - ICONDIR* icon_dir, - ICONIMAGE* icon_image, - size_t image_offset, - size_t* image_byte_count) { - DCHECK(icon_dir != NULL); - DCHECK(icon_image != NULL); - DCHECK_GT(image_offset, 0U); - DCHECK(image_byte_count != NULL); - - // We start by computing certain image values we'll use later on. - size_t xor_mask_size, bytes_in_resource; - ComputeBitmapSizeComponents(bitmap, - &xor_mask_size, - &bytes_in_resource); - - icon_dir->idEntries[index].bWidth = static_cast<BYTE>(bitmap.width()); - icon_dir->idEntries[index].bHeight = static_cast<BYTE>(bitmap.height()); - icon_dir->idEntries[index].wPlanes = 1; - icon_dir->idEntries[index].wBitCount = 32; - icon_dir->idEntries[index].dwBytesInRes = bytes_in_resource; - icon_dir->idEntries[index].dwImageOffset = image_offset; - icon_image->icHeader.biSize = sizeof(BITMAPINFOHEADER); - - // The width field in the BITMAPINFOHEADER structure accounts for the height - // of both the AND mask and the XOR mask so we need to multiply the bitmap's - // height by 2. The same does NOT apply to the width field. - icon_image->icHeader.biHeight = bitmap.height() * 2; - icon_image->icHeader.biWidth = bitmap.width(); - icon_image->icHeader.biPlanes = 1; - icon_image->icHeader.biBitCount = 32; - - // We use a helper function for copying to actual bits from the SkBitmap - // object into the appropriate space in the buffer. We use a helper function - // (rather than just copying the bits) because there is no way to specify the - // orientation (bottom-up vs. top-down) of a bitmap residing in a .ico file. - // Thus, if we just copy the bits, we'll end up with a bottom up bitmap in - // the .ico file which will result in the icon being displayed upside down. - // The helper function copies the image into the buffer one scanline at a - // time. - // - // Note that we don't need to initialize the AND mask since the memory - // allocated for the icon data buffer was initialized to zero. The icon we - // create will therefore use an AND mask containing only zeros, which is OK - // because the underlying image has an alpha channel. An AND mask containing - // only zeros essentially means we'll initially treat all the pixels as - // opaque. - unsigned char* image_addr = reinterpret_cast<unsigned char*>(icon_image); - unsigned char* xor_mask_addr = image_addr + sizeof(BITMAPINFOHEADER); - CopySkBitmapBitsIntoIconBuffer(bitmap, xor_mask_addr, xor_mask_size); - *image_byte_count = bytes_in_resource; -} - -void IconUtil::CopySkBitmapBitsIntoIconBuffer(const SkBitmap& bitmap, - unsigned char* buffer, - size_t buffer_size) { - SkAutoLockPixels bitmap_lock(bitmap); - unsigned char* bitmap_ptr = static_cast<unsigned char*>(bitmap.getPixels()); - size_t bitmap_size = bitmap.height() * bitmap.width() * 4; - DCHECK_EQ(buffer_size, bitmap_size); - for (size_t i = 0; i < bitmap_size; i += bitmap.width() * 4) { - memcpy(buffer + bitmap_size - bitmap.width() * 4 - i, - bitmap_ptr + i, - bitmap.width() * 4); - } -} - -void IconUtil::CreateResizedBitmapSet(const SkBitmap& bitmap_to_resize, - std::vector<SkBitmap>* bitmaps) { - DCHECK(bitmaps != NULL); - DCHECK(bitmaps->empty()); - - bool inserted_original_bitmap = false; - for (size_t i = 0; i < arraysize(icon_dimensions_); i++) { - // If the dimensions of the bitmap we are resizing are the same as the - // current dimensions, then we should insert the bitmap and not a resized - // bitmap. If the bitmap's dimensions are smaller, we insert our bitmap - // first so that the bitmaps we return in the vector are sorted based on - // their dimensions. - if (!inserted_original_bitmap) { - if ((bitmap_to_resize.width() == icon_dimensions_[i]) && - (bitmap_to_resize.height() == icon_dimensions_[i])) { - bitmaps->push_back(bitmap_to_resize); - inserted_original_bitmap = true; - continue; - } - - if ((bitmap_to_resize.width() < icon_dimensions_[i]) && - (bitmap_to_resize.height() < icon_dimensions_[i])) { - bitmaps->push_back(bitmap_to_resize); - inserted_original_bitmap = true; - } - } - bitmaps->push_back(skia::ImageOperations::Resize( - bitmap_to_resize, skia::ImageOperations::RESIZE_LANCZOS3, - icon_dimensions_[i], icon_dimensions_[i])); - } - - if (!inserted_original_bitmap) - bitmaps->push_back(bitmap_to_resize); -} - -size_t IconUtil::ComputeIconFileBufferSize(const std::vector<SkBitmap>& set) { - DCHECK(!set.empty()); - - // We start by counting the bytes for the structures that don't depend on the - // number of icon images. Note that sizeof(ICONDIR) already accounts for a - // single ICONDIRENTRY structure, which is why we subtract one from the - // number of bitmaps. - size_t total_buffer_size = sizeof(ICONDIR); - size_t bitmap_count = set.size(); - total_buffer_size += sizeof(ICONDIRENTRY) * (bitmap_count - 1); - DCHECK_GE(bitmap_count, arraysize(icon_dimensions_)); - - // Add the bitmap specific structure sizes. - for (size_t i = 0; i < bitmap_count; i++) { - size_t xor_mask_size, bytes_in_resource; - ComputeBitmapSizeComponents(set[i], - &xor_mask_size, - &bytes_in_resource); - total_buffer_size += bytes_in_resource; - } - return total_buffer_size; -} - -void IconUtil::ComputeBitmapSizeComponents(const SkBitmap& bitmap, - size_t* xor_mask_size, - size_t* bytes_in_resource) { - // The XOR mask size is easy to calculate since we only deal with 32bpp - // images. - *xor_mask_size = bitmap.width() * bitmap.height() * 4; - - // Computing the AND mask is a little trickier since it is a monochrome - // bitmap (regardless of the number of bits per pixels used in the XOR mask). - // There are two things we must make sure we do when computing the AND mask - // size: - // - // 1. Make sure the right number of bytes is allocated for each AND mask - // scan line in case the number of pixels in the image is not divisible by - // 8. For example, in a 15X15 image, 15 / 8 is one byte short of - // containing the number of bits we need in order to describe a single - // image scan line so we need to add a byte. Thus, we need 2 bytes instead - // of 1 for each scan line. - // - // 2. Make sure each scan line in the AND mask is 4 byte aligned (so that the - // total icon image has a 4 byte alignment). In the 15X15 image example - // above, we can not use 2 bytes so we increase it to the next multiple of - // 4 which is 4. - // - // Once we compute the size for a singe AND mask scan line, we multiply that - // number by the image height in order to get the total number of bytes for - // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes - // for the monochrome bitmap representing the AND mask. - size_t and_line_length = (bitmap.width() + 7) >> 3; - and_line_length = (and_line_length + 3) & ~3; - size_t and_mask_size = and_line_length * bitmap.height(); - size_t masks_size = *xor_mask_size + and_mask_size; - *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); -} diff --git a/gfx/icon_util.h b/gfx/icon_util.h index 9f07b8d..6b96190 100644 --- a/gfx/icon_util.h +++ b/gfx/icon_util.h @@ -6,189 +6,7 @@ #define GFX_ICON_UTIL_H_ #pragma once -#include <windows.h> -#include <string> -#include <vector> -#include "base/basictypes.h" - -namespace gfx { -class Size; -} -class FilePath; -class SkBitmap; - -/////////////////////////////////////////////////////////////////////////////// -// -// The IconUtil class contains helper functions for manipulating Windows icons. -// The class interface contains methods for converting an HICON handle into an -// SkBitmap object and vice versa. The class can also create a .ico file given -// a PNG image contained in an SkBitmap object. The following code snippet -// shows an example usage of IconUtil::CreateHICONFromSkBitmap(): -// -// SkBitmap bitmap; -// -// // Fill |bitmap| with valid data -// bitmap.setConfig(...); -// bitmap.allocPixels(); -// -// ... -// -// // Convert the bitmap into a Windows HICON -// HICON icon = IconUtil::CreateHICONFromSkBitmap(bitmap); -// if (icon == NULL) { -// // Handle error -// ... -// } -// -// // Use the icon with a WM_SETICON message -// ::SendMessage(hwnd, WM_SETICON, static_cast<WPARAM>(ICON_BIG), -// reinterpret_cast<LPARAM>(icon)); -// -// // Destroy the icon when we are done -// ::DestroyIcon(icon); -// -/////////////////////////////////////////////////////////////////////////////// -class IconUtil { - public: - // Given an SkBitmap object, the function converts the bitmap to a Windows - // icon and returns the corresponding HICON handle. If the function cannot - // convert the bitmap, NULL is returned. - // - // The client is responsible for destroying the icon when it is no longer - // needed by calling ::DestroyIcon(). - static HICON CreateHICONFromSkBitmap(const SkBitmap& bitmap); - - // Given a valid HICON handle representing an icon, this function converts - // the icon into an SkBitmap object containing an ARGB bitmap using the - // dimensions specified in |s|. |s| must specify valid dimensions (both - // width() an height() must be greater than zero). If the function cannot - // convert the icon to a bitmap (most probably due to an invalid parameter), - // the return value is NULL. - // - // The client owns the returned bitmap object and is responsible for deleting - // it when it is no longer needed. - static SkBitmap* CreateSkBitmapFromHICON(HICON icon, const gfx::Size& s); - - // Given an initialized SkBitmap object and a file name, this function - // creates a .ico file with the given name using the provided bitmap. The - // icon file is created with multiple icon images of varying predefined - // dimensions because Windows uses different image sizes when loading icons, - // depending on where the icon is drawn (ALT+TAB window, desktop shortcut, - // Quick Launch, etc.). |icon_file_name| needs to specify the full path for - // the desired .ico file. - // - // The function returns true on success and false otherwise. - static bool CreateIconFileFromSkBitmap(const SkBitmap& bitmap, - const FilePath& icon_path); - - private: - // The icon format is published in the MSDN but there is no definition of - // the icon file structures in any of the Windows header files so we need to - // define these structure within the class. We must make sure we use 2 byte - // packing so that the structures are layed out properly within the file. -#pragma pack(push) -#pragma pack(2) - - // ICONDIRENTRY contains meta data for an individual icon image within a - // .ico file. - struct ICONDIRENTRY { - BYTE bWidth; - BYTE bHeight; - BYTE bColorCount; - BYTE bReserved; - WORD wPlanes; - WORD wBitCount; - DWORD dwBytesInRes; - DWORD dwImageOffset; - }; - - // ICONDIR Contains information about all the icon images contained within a - // single .ico file. - struct ICONDIR { - WORD idReserved; - WORD idType; - WORD idCount; - ICONDIRENTRY idEntries[1]; - }; - - // Contains the actual icon image. - struct ICONIMAGE { - BITMAPINFOHEADER icHeader; - RGBQUAD icColors[1]; - BYTE icXOR[1]; - BYTE icAND[1]; - }; -#pragma pack(pop) - - // Used for indicating that the .ico contains an icon (rather than a cursor) - // image. This value is set in the |idType| field of the ICONDIR structure. - static const int kResourceTypeIcon = 1; - - // The dimensions of the icon images we insert into the .ico file. - static const int icon_dimensions_[]; - - // Returns true if any pixel in the given pixels buffer has an non-zero alpha. - static bool PixelsHaveAlpha(const uint32* pixels, size_t num_pixels); - - // A helper function that initializes a BITMAPV5HEADER structure with a set - // of values. - static void InitializeBitmapHeader(BITMAPV5HEADER* header, int width, - int height); - - // Given a single SkBitmap object and pointers to the corresponding icon - // structures within the icon data buffer, this function sets the image - // information (dimensions, color depth, etc.) in the icon structures and - // also copies the underlying icon image into the appropriate location. - // - // The function will set the data pointed to by |image_byte_count| with the - // number of image bytes written to the buffer. Note that the number of bytes - // includes only the image data written into the memory pointed to by - // |icon_image|. - static void SetSingleIconImageInformation(const SkBitmap& bitmap, - size_t index, - ICONDIR* icon_dir, - ICONIMAGE* icon_image, - size_t image_offset, - size_t* image_byte_count); - - // Copies the bits of an SkBitmap object into a buffer holding the bits of - // the corresponding image for an icon within the .ico file. - static void CopySkBitmapBitsIntoIconBuffer(const SkBitmap& bitmap, - unsigned char* buffer, - size_t buffer_size); - - // Given a single bitmap, this function creates a set of bitmaps with - // specific dimensions by resizing the given bitmap to the appropriate sizes. - static void CreateResizedBitmapSet(const SkBitmap& bitmap_to_resize, - std::vector<SkBitmap>* bitmaps); - - // Given a set of bitmaps with varying dimensions, this function computes - // the amount of memory needed in order to store the bitmaps as image icons - // in a .ico file. - static size_t ComputeIconFileBufferSize(const std::vector<SkBitmap>& set); - - // A helper function for computing various size components of a given bitmap. - // The different sizes can be used within the various .ico file structures. - // - // |xor_mask_size| - the size, in bytes, of the XOR mask in the ICONIMAGE - // structure. - // |and_mask_size| - the size, in bytes, of the AND mask in the ICONIMAGE - // structure. - // |bytes_in_resource| - the total number of bytes set in the ICONIMAGE - // structure. This value is equal to the sum of the - // bytes in the AND mask and the XOR mask plus the size - // of the BITMAPINFOHEADER structure. Note that since - // only 32bpp are handled by the IconUtil class, the - // icColors field in the ICONIMAGE structure is ignored - // and is not accounted for when computing the - // different size components. - static void ComputeBitmapSizeComponents(const SkBitmap& bitmap, - size_t* xor_mask_size, - size_t* bytes_in_resource); - - // Prevent clients from instantiating objects of that class by declaring the - // ctor/dtor as private. - DISALLOW_IMPLICIT_CONSTRUCTORS(IconUtil); -}; +#include "ui/gfx/icon_util.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_ICON_UTIL_H_ diff --git a/gfx/icon_util_unittest.cc b/gfx/icon_util_unittest.cc deleted file mode 100644 index 43eca49..0000000 --- a/gfx/icon_util_unittest.cc +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/file_util.h" -#include "base/path_service.h" -#include "base/scoped_ptr.h" -#include "gfx/gfx_paths.h" -#include "gfx/icon_util.h" -#include "gfx/size.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkBitmap.h" - -namespace { - -static const char kSmallIconName[] = "icon_util/16_X_16_icon.ico"; -static const char kLargeIconName[] = "icon_util/128_X_128_icon.ico"; -static const char kTempIconFilename[] = "temp_test_icon.ico"; - -class IconUtilTest : public testing::Test { - public: - IconUtilTest() { - PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_); - } - ~IconUtilTest() {} - - static const int kSmallIconWidth = 16; - static const int kSmallIconHeight = 16; - static const int kLargeIconWidth = 128; - static const int kLargeIconHeight = 128; - - // Given a file name for an .ico file and an image dimentions, this - // function loads the icon and returns an HICON handle. - HICON LoadIconFromFile(const FilePath& filename, int width, int height) { - HICON icon = static_cast<HICON>(LoadImage(NULL, - filename.value().c_str(), - IMAGE_ICON, - width, - height, - LR_LOADTRANSPARENT | LR_LOADFROMFILE)); - return icon; - } - - protected: - // The root directory for test files. - FilePath test_data_directory_; - - private: - DISALLOW_COPY_AND_ASSIGN(IconUtilTest); -}; - -} // namespace - -// The following test case makes sure IconUtil::SkBitmapFromHICON fails -// gracefully when called with invalid input parameters. -TEST_F(IconUtilTest, TestIconToBitmapInvalidParameters) { - FilePath icon_filename = test_data_directory_.AppendASCII(kSmallIconName); - gfx::Size icon_size(kSmallIconWidth, kSmallIconHeight); - HICON icon = LoadIconFromFile(icon_filename, - icon_size.width(), - icon_size.height()); - ASSERT_TRUE(icon != NULL); - - // Invalid size parameter. - gfx::Size invalid_icon_size(kSmallIconHeight, 0); - EXPECT_EQ(IconUtil::CreateSkBitmapFromHICON(icon, invalid_icon_size), - static_cast<SkBitmap*>(NULL)); - - // Invalid icon. - EXPECT_EQ(IconUtil::CreateSkBitmapFromHICON(NULL, icon_size), - static_cast<SkBitmap*>(NULL)); - - // The following code should succeed. - scoped_ptr<SkBitmap> bitmap; - bitmap.reset(IconUtil::CreateSkBitmapFromHICON(icon, icon_size)); - EXPECT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - ::DestroyIcon(icon); -} - -// The following test case makes sure IconUtil::CreateHICONFromSkBitmap fails -// gracefully when called with invalid input parameters. -TEST_F(IconUtilTest, TestBitmapToIconInvalidParameters) { - HICON icon = NULL; - scoped_ptr<SkBitmap> bitmap; - - // Wrong bitmap format. - bitmap.reset(new SkBitmap); - ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - bitmap->setConfig(SkBitmap::kA8_Config, kSmallIconWidth, kSmallIconHeight); - icon = IconUtil::CreateHICONFromSkBitmap(*bitmap); - EXPECT_EQ(icon, static_cast<HICON>(NULL)); - - // Invalid bitmap size. - bitmap.reset(new SkBitmap); - ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, 0, 0); - icon = IconUtil::CreateHICONFromSkBitmap(*bitmap); - EXPECT_EQ(icon, static_cast<HICON>(NULL)); - - // Valid bitmap configuration but no pixels allocated. - bitmap.reset(new SkBitmap); - ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, - kSmallIconWidth, - kSmallIconHeight); - icon = IconUtil::CreateHICONFromSkBitmap(*bitmap); - EXPECT_TRUE(icon == NULL); -} - -// The following test case makes sure IconUtil::CreateIconFileFromSkBitmap -// fails gracefully when called with invalid input parameters. -TEST_F(IconUtilTest, TestCreateIconFileInvalidParameters) { - scoped_ptr<SkBitmap> bitmap; - FilePath valid_icon_filename = test_data_directory_.AppendASCII( - kSmallIconName); - FilePath invalid_icon_filename(FILE_PATH_LITERAL("C:\\<>?.ico")); - - // Wrong bitmap format. - bitmap.reset(new SkBitmap); - ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - bitmap->setConfig(SkBitmap::kA8_Config, kSmallIconWidth, kSmallIconHeight); - EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap, - valid_icon_filename)); - - // Invalid bitmap size. - bitmap.reset(new SkBitmap); - ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, 0, 0); - EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap, - valid_icon_filename)); - - // Bitmap with no allocated pixels. - bitmap.reset(new SkBitmap); - ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, - kSmallIconWidth, - kSmallIconHeight); - EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap, - valid_icon_filename)); - - // Invalid file name. - bitmap->allocPixels(); - // Setting the pixels to black. - memset(bitmap->getPixels(), 0, bitmap->width() * bitmap->height() * 4); - EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap, - invalid_icon_filename)); -} - -// This test case makes sure that when we load an icon from disk and convert -// the HICON into a bitmap, the bitmap has the expected format and dimentions. -TEST_F(IconUtilTest, TestCreateSkBitmapFromHICON) { - scoped_ptr<SkBitmap> bitmap; - FilePath small_icon_filename = test_data_directory_.AppendASCII( - kSmallIconName); - gfx::Size small_icon_size(kSmallIconWidth, kSmallIconHeight); - HICON small_icon = LoadIconFromFile(small_icon_filename, - small_icon_size.width(), - small_icon_size.height()); - ASSERT_NE(small_icon, static_cast<HICON>(NULL)); - bitmap.reset(IconUtil::CreateSkBitmapFromHICON(small_icon, small_icon_size)); - ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - EXPECT_EQ(bitmap->width(), small_icon_size.width()); - EXPECT_EQ(bitmap->height(), small_icon_size.height()); - EXPECT_EQ(bitmap->config(), SkBitmap::kARGB_8888_Config); - ::DestroyIcon(small_icon); - - FilePath large_icon_filename = test_data_directory_.AppendASCII( - kLargeIconName); - gfx::Size large_icon_size(kLargeIconWidth, kLargeIconHeight); - HICON large_icon = LoadIconFromFile(large_icon_filename, - large_icon_size.width(), - large_icon_size.height()); - ASSERT_NE(large_icon, static_cast<HICON>(NULL)); - bitmap.reset(IconUtil::CreateSkBitmapFromHICON(large_icon, large_icon_size)); - ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - EXPECT_EQ(bitmap->width(), large_icon_size.width()); - EXPECT_EQ(bitmap->height(), large_icon_size.height()); - EXPECT_EQ(bitmap->config(), SkBitmap::kARGB_8888_Config); - ::DestroyIcon(large_icon); -} - -// This test case makes sure that when an HICON is created from an SkBitmap, -// the returned handle is valid and refers to an icon with the expected -// dimentions color depth etc. -TEST_F(IconUtilTest, TestBasicCreateHICONFromSkBitmap) { - scoped_ptr<SkBitmap> bitmap; - bitmap.reset(new SkBitmap); - ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, - kSmallIconWidth, - kSmallIconHeight); - bitmap->allocPixels(); - HICON icon = IconUtil::CreateHICONFromSkBitmap(*bitmap); - EXPECT_NE(icon, static_cast<HICON>(NULL)); - ICONINFO icon_info; - ASSERT_TRUE(::GetIconInfo(icon, &icon_info)); - EXPECT_TRUE(icon_info.fIcon); - - // Now that have the icon information, we should obtain the specification of - // the icon's bitmap and make sure it matches the specification of the - // SkBitmap we started with. - // - // The bitmap handle contained in the icon information is a handle to a - // compatible bitmap so we need to call ::GetDIBits() in order to retrieve - // the bitmap's header information. - BITMAPINFO bitmap_info; - ::ZeroMemory(&bitmap_info, sizeof(BITMAPINFO)); - bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFO); - HDC hdc = ::GetDC(NULL); - int result = ::GetDIBits(hdc, - icon_info.hbmColor, - 0, - kSmallIconWidth, - NULL, - &bitmap_info, - DIB_RGB_COLORS); - ASSERT_GT(result, 0); - EXPECT_EQ(bitmap_info.bmiHeader.biWidth, kSmallIconWidth); - EXPECT_EQ(bitmap_info.bmiHeader.biHeight, kSmallIconHeight); - EXPECT_EQ(bitmap_info.bmiHeader.biPlanes, 1); - EXPECT_EQ(bitmap_info.bmiHeader.biBitCount, 32); - ::ReleaseDC(NULL, hdc); - ::DestroyIcon(icon); -} - -// The following test case makes sure IconUtil::CreateIconFileFromSkBitmap -// creates a valid .ico file given an SkBitmap. -TEST_F(IconUtilTest, TestCreateIconFile) { - scoped_ptr<SkBitmap> bitmap; - FilePath icon_filename = test_data_directory_.AppendASCII(kTempIconFilename); - - // Allocating the bitmap. - bitmap.reset(new SkBitmap); - ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL)); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, - kSmallIconWidth, - kSmallIconHeight); - bitmap->allocPixels(); - - // Setting the pixels to black. - memset(bitmap->getPixels(), 0, bitmap->width() * bitmap->height() * 4); - - EXPECT_TRUE(IconUtil::CreateIconFileFromSkBitmap(*bitmap, - icon_filename)); - - // We are currently only testing that it is possible to load an icon from - // the .ico file we just created. We don't really check the additional icon - // images created by IconUtil::CreateIconFileFromSkBitmap. - HICON icon = LoadIconFromFile(icon_filename, - kSmallIconWidth, - kSmallIconHeight); - EXPECT_NE(icon, static_cast<HICON>(NULL)); - if (icon != NULL) { - ::DestroyIcon(icon); - } -} diff --git a/gfx/insets.cc b/gfx/insets.cc deleted file mode 100644 index 06cc6aa..0000000 --- a/gfx/insets.cc +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/insets.h" - -#include "base/string_util.h" - -namespace gfx { - -std::string Insets::ToString() const { - // Print members in the same order of the constructor parameters. - return StringPrintf("%d,%d,%d,%d", top_, left_, bottom_, right_); -} - -} // namespace gfx diff --git a/gfx/insets.h b/gfx/insets.h index ba6cb58..aa1191b 100644 --- a/gfx/insets.h +++ b/gfx/insets.h @@ -6,89 +6,7 @@ #define GFX_INSETS_H_ #pragma once -#include "build/build_config.h" - -#if defined(OS_POSIX) && !defined(OS_MACOSX) -#include <gtk/gtkstyle.h> -#endif - -#include <string> - -namespace gfx { - -// -// An insets represents the borders of a container (the space the container must -// leave at each of its edges). -// - -class Insets { - public: - Insets() : top_(0), left_(0), bottom_(0), right_(0) {} - Insets(int top, int left, int bottom, int right) - : top_(top), - left_(left), - bottom_(bottom), - right_(right) {} -#if defined(OS_POSIX) && !defined(OS_MACOSX) - explicit Insets(const GtkBorder& border) - : top_(border.top), - left_(border.left), - bottom_(border.bottom), - right_(border.right) {} -#endif - - ~Insets() {} - - int top() const { return top_; } - int left() const { return left_; } - int bottom() const { return bottom_; } - int right() const { return right_; } - - // Returns the total width taken up by the insets, which is the sum of the - // left and right insets. - int width() const { return left_ + right_; } - - // Returns the total height taken up by the insets, which is the sum of the - // top and bottom insets. - int height() const { return top_ + bottom_; } - - // Returns true if the insets are empty. - bool empty() const { return width() == 0 && height() == 0; } - - void Set(int top, int left, int bottom, int right) { - top_ = top; - left_ = left; - bottom_ = bottom; - right_ = right; - } - - bool operator==(const Insets& insets) const { - return top_ == insets.top_ && left_ == insets.left_ && - bottom_ == insets.bottom_ && right_ == insets.right_; - } - - bool operator!=(const Insets& insets) const { - return !(*this == insets); - } - - Insets& operator+=(const Insets& insets) { - top_ += insets.top_; - left_ += insets.left_; - bottom_ += insets.bottom_; - right_ += insets.right_; - return *this; - } - - // Returns a string representation of the insets. - std::string ToString() const; - - private: - int top_; - int left_; - int bottom_; - int right_; -}; - -} // namespace gfx +#include "ui/gfx/insets.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_INSETS_H_ diff --git a/gfx/insets_unittest.cc b/gfx/insets_unittest.cc deleted file mode 100644 index 30d6d7f..0000000 --- a/gfx/insets_unittest.cc +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/insets.h" - -#include "testing/gtest/include/gtest/gtest.h" - -TEST(InsetsTest, InsetsDefault) { - gfx::Insets insets; - EXPECT_EQ(0, insets.top()); - EXPECT_EQ(0, insets.left()); - EXPECT_EQ(0, insets.bottom()); - EXPECT_EQ(0, insets.right()); - EXPECT_EQ(0, insets.width()); - EXPECT_EQ(0, insets.height()); - EXPECT_TRUE(insets.empty()); -} - -TEST(InsetsTest, Insets) { - gfx::Insets insets(1, 2, 3, 4); - EXPECT_EQ(1, insets.top()); - EXPECT_EQ(2, insets.left()); - EXPECT_EQ(3, insets.bottom()); - EXPECT_EQ(4, insets.right()); - EXPECT_EQ(6, insets.width()); // Left + right. - EXPECT_EQ(4, insets.height()); // Top + bottom. - EXPECT_FALSE(insets.empty()); -} - -TEST(InsetsTest, Set) { - gfx::Insets insets; - insets.Set(1, 2, 3, 4); - EXPECT_EQ(1, insets.top()); - EXPECT_EQ(2, insets.left()); - EXPECT_EQ(3, insets.bottom()); - EXPECT_EQ(4, insets.right()); -} - -TEST(InsetsTest, Add) { - gfx::Insets insets; - insets.Set(1, 2, 3, 4); - insets += gfx::Insets(5, 6, 7, 8); - EXPECT_EQ(6, insets.top()); - EXPECT_EQ(8, insets.left()); - EXPECT_EQ(10, insets.bottom()); - EXPECT_EQ(12, insets.right()); -} - -TEST(InsetsTest, Equality) { - gfx::Insets insets1; - insets1.Set(1, 2, 3, 4); - gfx::Insets insets2; - // Test operator== and operator!=. - EXPECT_FALSE(insets1 == insets2); - EXPECT_TRUE(insets1 != insets2); - - insets2.Set(1, 2, 3, 4); - EXPECT_TRUE(insets1 == insets2); - EXPECT_FALSE(insets1 != insets2); -} - -TEST(InsetsTest, ToString) { - gfx::Insets insets(1, 2, 3, 4); - EXPECT_EQ("1,2,3,4", insets.ToString()); -} diff --git a/gfx/native_theme_linux.cc b/gfx/native_theme_linux.cc deleted file mode 100644 index b2087fe..0000000 --- a/gfx/native_theme_linux.cc +++ /dev/null @@ -1,941 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/native_theme_linux.h" - -#include <limits> - -#include "base/logging.h" -#include "gfx/codec/png_codec.h" -#include "gfx/color_utils.h" -#include "gfx/gfx_module.h" -#include "gfx/size.h" -#include "gfx/rect.h" -#include "grit/gfx_resources.h" -#include "third_party/skia/include/effects/SkGradientShader.h" - -namespace gfx { - -unsigned int NativeThemeLinux::button_length_ = 14; -unsigned int NativeThemeLinux::scrollbar_width_ = 15; -unsigned int NativeThemeLinux::thumb_inactive_color_ = 0xeaeaea; -unsigned int NativeThemeLinux::thumb_active_color_ = 0xf4f4f4; -unsigned int NativeThemeLinux::track_color_ = 0xd3d3d3; - -// These are the default dimensions of radio buttons and checkboxes. -static const int kCheckboxAndRadioWidth = 13; -static const int kCheckboxAndRadioHeight = 13; - -// These sizes match the sizes in Chromium Win. -static const int kSliderThumbWidth = 11; -static const int kSliderThumbHeight = 21; - -static const SkColor kSliderTrackBackgroundColor = - SkColorSetRGB(0xe3, 0xdd, 0xd8); -static const SkColor kSliderThumbLightGrey = SkColorSetRGB(0xf4, 0xf2, 0xef); -static const SkColor kSliderThumbDarkGrey = SkColorSetRGB(0xea, 0xe5, 0xe0); -static const SkColor kSliderThumbBorderDarkGrey = - SkColorSetRGB(0x9d, 0x96, 0x8e); - -#if !defined(OS_CHROMEOS) -// Chromeos has a different look. -// static -NativeThemeLinux* NativeThemeLinux::instance() { - // The global NativeThemeLinux instance. - static NativeThemeLinux s_native_theme; - return &s_native_theme; -} -#endif - -// Get lightness adjusted color. -static SkColor BrightenColor(const color_utils::HSL& hsl, SkAlpha alpha, - double lightness_amount) { - color_utils::HSL adjusted = hsl; - adjusted.l += lightness_amount; - if (adjusted.l > 1.0) - adjusted.l = 1.0; - if (adjusted.l < 0.0) - adjusted.l = 0.0; - - return color_utils::HSLToSkColor(adjusted, alpha); -} - -static SkBitmap* GfxGetBitmapNamed(int key) { - base::StringPiece data = GfxModule::GetResource(key); - if (!data.size()) { - NOTREACHED() << "Unable to load image resource " << key; - return NULL; - } - - SkBitmap bitmap; - if (!gfx::PNGCodec::Decode( - reinterpret_cast<const unsigned char*>(data.data()), - data.size(), &bitmap)) { - NOTREACHED() << "Unable to decode image resource " << key; - return NULL; - } - - return new SkBitmap(bitmap); -} - -NativeThemeLinux::NativeThemeLinux() { -} - -NativeThemeLinux::~NativeThemeLinux() { -} - -gfx::Size NativeThemeLinux::GetPartSize(Part part) const { - switch (part) { - case kScrollbarDownArrow: - case kScrollbarUpArrow: - return gfx::Size(scrollbar_width_, button_length_); - case kScrollbarLeftArrow: - case kScrollbarRightArrow: - return gfx::Size(button_length_, scrollbar_width_); - case kScrollbarHorizontalThumb: - // This matches Firefox on Linux. - return gfx::Size(2 * scrollbar_width_, scrollbar_width_); - case kScrollbarVerticalThumb: - // This matches Firefox on Linux. - return gfx::Size(scrollbar_width_, 2 * scrollbar_width_); - break; - case kScrollbarHorizontalTrack: - return gfx::Size(0, scrollbar_width_); - case kScrollbarVerticalTrack: - return gfx::Size(scrollbar_width_, 0); - case kCheckbox: - case kRadio: - return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight); - case kSliderThumb: - // These sizes match the sizes in Chromium Win. - return gfx::Size(kSliderThumbWidth, kSliderThumbHeight); - case kInnerSpinButton: - return gfx::Size(scrollbar_width_, 0); - case kPushButton: - case kTextField: - case kMenuList: - case kSliderTrack: - case kProgressBar: - return gfx::Size(); // No default size. - } - return gfx::Size(); -} - -void NativeThemeLinux::PaintArrowButton( - skia::PlatformCanvas* canvas, - const gfx::Rect& rect, Part direction, State state) { - int widthMiddle, lengthMiddle; - SkPaint paint; - if (direction == kScrollbarUpArrow || direction == kScrollbarDownArrow) { - widthMiddle = rect.width() / 2 + 1; - lengthMiddle = rect.height() / 2 + 1; - } else { - lengthMiddle = rect.width() / 2 + 1; - widthMiddle = rect.height() / 2 + 1; - } - - // Calculate button color. - SkScalar trackHSV[3]; - SkColorToHSV(track_color_, trackHSV); - SkColor buttonColor = SaturateAndBrighten(trackHSV, 0, 0.2); - SkColor backgroundColor = buttonColor; - if (state == kPressed) { - SkScalar buttonHSV[3]; - SkColorToHSV(buttonColor, buttonHSV); - buttonColor = SaturateAndBrighten(buttonHSV, 0, -0.1); - } else if (state == kHovered) { - SkScalar buttonHSV[3]; - SkColorToHSV(buttonColor, buttonHSV); - buttonColor = SaturateAndBrighten(buttonHSV, 0, 0.05); - } - - SkIRect skrect; - skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() - + rect.height()); - // Paint the background (the area visible behind the rounded corners). - paint.setColor(backgroundColor); - canvas->drawIRect(skrect, paint); - - // Paint the button's outline and fill the middle - SkPath outline; - switch (direction) { - case kScrollbarUpArrow: - outline.moveTo(rect.x() + 0.5, rect.y() + rect.height() + 0.5); - outline.rLineTo(0, -(rect.height() - 2)); - outline.rLineTo(2, -2); - outline.rLineTo(rect.width() - 5, 0); - outline.rLineTo(2, 2); - outline.rLineTo(0, rect.height() - 2); - break; - case kScrollbarDownArrow: - outline.moveTo(rect.x() + 0.5, rect.y() - 0.5); - outline.rLineTo(0, rect.height() - 2); - outline.rLineTo(2, 2); - outline.rLineTo(rect.width() - 5, 0); - outline.rLineTo(2, -2); - outline.rLineTo(0, -(rect.height() - 2)); - break; - case kScrollbarRightArrow: - outline.moveTo(rect.x() - 0.5, rect.y() + 0.5); - outline.rLineTo(rect.width() - 2, 0); - outline.rLineTo(2, 2); - outline.rLineTo(0, rect.height() - 5); - outline.rLineTo(-2, 2); - outline.rLineTo(-(rect.width() - 2), 0); - break; - case kScrollbarLeftArrow: - outline.moveTo(rect.x() + rect.width() + 0.5, rect.y() + 0.5); - outline.rLineTo(-(rect.width() - 2), 0); - outline.rLineTo(-2, 2); - outline.rLineTo(0, rect.height() - 5); - outline.rLineTo(2, 2); - outline.rLineTo(rect.width() - 2, 0); - break; - default: - break; - } - outline.close(); - - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(buttonColor); - canvas->drawPath(outline, paint); - - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kStroke_Style); - SkScalar thumbHSV[3]; - SkColorToHSV(thumb_inactive_color_, thumbHSV); - paint.setColor(OutlineColor(trackHSV, thumbHSV)); - canvas->drawPath(outline, paint); - - // If the button is disabled or read-only, the arrow is drawn with the - // outline color. - if (state != kDisabled) - paint.setColor(SK_ColorBLACK); - - paint.setAntiAlias(false); - paint.setStyle(SkPaint::kFill_Style); - - SkPath path; - // The constants in this block of code are hand-tailored to produce good - // looking arrows without anti-aliasing. - switch (direction) { - case kScrollbarUpArrow: - path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle + 2); - path.rLineTo(7, 0); - path.rLineTo(-4, -4); - break; - case kScrollbarDownArrow: - path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle - 3); - path.rLineTo(7, 0); - path.rLineTo(-4, 4); - break; - case kScrollbarRightArrow: - path.moveTo(rect.x() + lengthMiddle - 3, rect.y() + widthMiddle - 4); - path.rLineTo(0, 7); - path.rLineTo(4, -4); - break; - case kScrollbarLeftArrow: - path.moveTo(rect.x() + lengthMiddle + 1, rect.y() + widthMiddle - 5); - path.rLineTo(0, 9); - path.rLineTo(-4, -4); - break; - default: - break; - } - path.close(); - - canvas->drawPath(path, paint); -} - -void NativeThemeLinux::Paint(skia::PlatformCanvas* canvas, - Part part, - State state, - const gfx::Rect& rect, - const ExtraParams& extra) { - switch (part) { - case kScrollbarDownArrow: - case kScrollbarUpArrow: - case kScrollbarLeftArrow: - case kScrollbarRightArrow: - PaintArrowButton(canvas, rect, part, state); - break; - case kScrollbarHorizontalThumb: - case kScrollbarVerticalThumb: - PaintScrollbarThumb(canvas, part, state, rect); - break; - case kScrollbarHorizontalTrack: - case kScrollbarVerticalTrack: - PaintScrollbarTrack(canvas, part, state, extra.scrollbar_track, rect); - break; - case kCheckbox: - PaintCheckbox(canvas, state, rect, extra.button); - break; - case kRadio: - PaintRadio(canvas, state, rect, extra.button); - break; - case kPushButton: - PaintButton(canvas, state, rect, extra.button); - break; - case kTextField: - PaintTextField(canvas, state, rect, extra.text_field); - break; - case kMenuList: - PaintMenuList(canvas, state, rect, extra.menu_list); - break; - case kSliderTrack: - PaintSliderTrack(canvas, state, rect, extra.slider); - break; - case kSliderThumb: - PaintSliderThumb(canvas, state, rect, extra.slider); - break; - case kInnerSpinButton: - PaintInnerSpinButton(canvas, state, rect, extra.inner_spin); - break; - case kProgressBar: - PaintProgressBar(canvas, state, rect, extra.progress_bar); - break; - } -} - -void NativeThemeLinux::PaintScrollbarTrack(skia::PlatformCanvas* canvas, - Part part, - State state, - const ScrollbarTrackExtraParams& extra_params, - const gfx::Rect& rect) { - SkPaint paint; - SkIRect skrect; - - skrect.set(rect.x(), rect.y(), rect.right(), rect.bottom()); - SkScalar track_hsv[3]; - SkColorToHSV(track_color_, track_hsv); - paint.setColor(SaturateAndBrighten(track_hsv, 0, 0)); - canvas->drawIRect(skrect, paint); - - SkScalar thumb_hsv[3]; - SkColorToHSV(thumb_inactive_color_, thumb_hsv); - - paint.setColor(OutlineColor(track_hsv, thumb_hsv)); - DrawBox(canvas, rect, paint); -} - -void NativeThemeLinux::PaintScrollbarThumb(skia::PlatformCanvas* canvas, - Part part, - State state, - const gfx::Rect& rect) { - const bool hovered = state == kHovered; - const int midx = rect.x() + rect.width() / 2; - const int midy = rect.y() + rect.height() / 2; - const bool vertical = part == kScrollbarVerticalThumb; - - SkScalar thumb[3]; - SkColorToHSV(hovered ? thumb_active_color_ : thumb_inactive_color_, thumb); - - SkPaint paint; - paint.setColor(SaturateAndBrighten(thumb, 0, 0.02)); - - SkIRect skrect; - if (vertical) - skrect.set(rect.x(), rect.y(), midx + 1, rect.y() + rect.height()); - else - skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), midy + 1); - - canvas->drawIRect(skrect, paint); - - paint.setColor(SaturateAndBrighten(thumb, 0, -0.02)); - - if (vertical) { - skrect.set( - midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); - } else { - skrect.set( - rect.x(), midy + 1, rect.x() + rect.width(), rect.y() + rect.height()); - } - - canvas->drawIRect(skrect, paint); - - SkScalar track[3]; - SkColorToHSV(track_color_, track); - paint.setColor(OutlineColor(track, thumb)); - DrawBox(canvas, rect, paint); - - if (rect.height() > 10 && rect.width() > 10) { - const int grippy_half_width = 2; - const int inter_grippy_offset = 3; - if (vertical) { - DrawHorizLine(canvas, - midx - grippy_half_width, - midx + grippy_half_width, - midy - inter_grippy_offset, - paint); - DrawHorizLine(canvas, - midx - grippy_half_width, - midx + grippy_half_width, - midy, - paint); - DrawHorizLine(canvas, - midx - grippy_half_width, - midx + grippy_half_width, - midy + inter_grippy_offset, - paint); - } else { - DrawVertLine(canvas, - midx - inter_grippy_offset, - midy - grippy_half_width, - midy + grippy_half_width, - paint); - DrawVertLine(canvas, - midx, - midy - grippy_half_width, - midy + grippy_half_width, - paint); - DrawVertLine(canvas, - midx + inter_grippy_offset, - midy - grippy_half_width, - midy + grippy_half_width, - paint); - } - } -} - -void NativeThemeLinux::PaintCheckbox(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const ButtonExtraParams& button) { - static SkBitmap* image_disabled_indeterminate = GfxGetBitmapNamed( - IDR_LINUX_CHECKBOX_DISABLED_INDETERMINATE); - static SkBitmap* image_indeterminate = GfxGetBitmapNamed( - IDR_LINUX_CHECKBOX_INDETERMINATE); - static SkBitmap* image_disabled_on = GfxGetBitmapNamed( - IDR_LINUX_CHECKBOX_DISABLED_ON); - static SkBitmap* image_on = GfxGetBitmapNamed(IDR_LINUX_CHECKBOX_ON); - static SkBitmap* image_disabled_off = GfxGetBitmapNamed( - IDR_LINUX_CHECKBOX_DISABLED_OFF); - static SkBitmap* image_off = GfxGetBitmapNamed(IDR_LINUX_CHECKBOX_OFF); - - SkBitmap* image = NULL; - if (button.indeterminate) { - image = state == kDisabled ? image_disabled_indeterminate - : image_indeterminate; - } else if (button.checked) { - image = state == kDisabled ? image_disabled_on : image_on; - } else { - image = state == kDisabled ? image_disabled_off : image_off; - } - - gfx::Rect bounds = rect.Center(gfx::Size(image->width(), image->height())); - DrawBitmapInt(canvas, *image, 0, 0, image->width(), image->height(), - bounds.x(), bounds.y(), bounds.width(), bounds.height()); -} - -void NativeThemeLinux::PaintRadio(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const ButtonExtraParams& button) { - static SkBitmap* image_disabled_on = GfxGetBitmapNamed( - IDR_LINUX_RADIO_DISABLED_ON); - static SkBitmap* image_on = GfxGetBitmapNamed(IDR_LINUX_RADIO_ON); - static SkBitmap* image_disabled_off = GfxGetBitmapNamed( - IDR_LINUX_RADIO_DISABLED_OFF); - static SkBitmap* image_off = GfxGetBitmapNamed(IDR_LINUX_RADIO_OFF); - - SkBitmap* image = NULL; - if (state == kDisabled) - image = button.checked ? image_disabled_on : image_disabled_off; - else - image = button.checked ? image_on : image_off; - - gfx::Rect bounds = rect.Center(gfx::Size(image->width(), image->height())); - DrawBitmapInt(canvas, *image, 0, 0, image->width(), image->height(), - bounds.x(), bounds.y(), bounds.width(), bounds.height()); -} - -void NativeThemeLinux::PaintButton(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const ButtonExtraParams& button) { - SkPaint paint; - SkRect skrect; - const int kRight = rect.right(); - const int kBottom = rect.bottom(); - SkColor base_color = button.background_color; - - color_utils::HSL base_hsl; - color_utils::SkColorToHSL(base_color, &base_hsl); - - // Our standard gradient is from 0xdd to 0xf8. This is the amount of - // increased luminance between those values. - SkColor light_color(BrightenColor(base_hsl, SkColorGetA(base_color), 0.105)); - - // If the button is too small, fallback to drawing a single, solid color - if (rect.width() < 5 || rect.height() < 5) { - paint.setColor(base_color); - skrect.set(rect.x(), rect.y(), kRight, kBottom); - canvas->drawRect(skrect, paint); - return; - } - - const int kBorderAlpha = state == kHovered ? 0x80 : 0x55; - paint.setARGB(kBorderAlpha, 0, 0, 0); - canvas->drawLine(rect.x() + 1, rect.y(), kRight - 1, rect.y(), paint); - canvas->drawLine(kRight - 1, rect.y() + 1, kRight - 1, kBottom - 1, paint); - canvas->drawLine(rect.x() + 1, kBottom - 1, kRight - 1, kBottom - 1, paint); - canvas->drawLine(rect.x(), rect.y() + 1, rect.x(), kBottom - 1, paint); - - paint.setColor(SK_ColorBLACK); - const int kLightEnd = state == kPressed ? 1 : 0; - const int kDarkEnd = !kLightEnd; - SkPoint gradient_bounds[2]; - gradient_bounds[kLightEnd].set(SkIntToScalar(rect.x()), - SkIntToScalar(rect.y())); - gradient_bounds[kDarkEnd].set(SkIntToScalar(rect.x()), - SkIntToScalar(kBottom - 1)); - SkColor colors[2]; - colors[0] = light_color; - colors[1] = base_color; - - SkShader* shader = SkGradientShader::CreateLinear( - gradient_bounds, colors, NULL, 2, SkShader::kClamp_TileMode, NULL); - paint.setStyle(SkPaint::kFill_Style); - paint.setShader(shader); - shader->unref(); - - skrect.set(rect.x() + 1, rect.y() + 1, kRight - 1, kBottom - 1); - canvas->drawRect(skrect, paint); - - paint.setShader(NULL); - paint.setColor(BrightenColor(base_hsl, SkColorGetA(base_color), -0.0588)); - canvas->drawPoint(rect.x() + 1, rect.y() + 1, paint); - canvas->drawPoint(kRight - 2, rect.y() + 1, paint); - canvas->drawPoint(rect.x() + 1, kBottom - 2, paint); - canvas->drawPoint(kRight - 2, kBottom - 2, paint); -} - -void NativeThemeLinux::PaintTextField(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const TextFieldExtraParams& text) { - // The following drawing code simulates the user-agent css border for - // text area and text input so that we do not break layout tests. Once we - // have decided the desired looks, we should update the code here and - // the layout test expectations. - SkRect bounds; - bounds.set(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1); - - SkPaint fill_paint; - fill_paint.setStyle(SkPaint::kFill_Style); - fill_paint.setColor(text.background_color); - canvas->drawRect(bounds, fill_paint); - - if (text.is_text_area) { - // Draw text area border: 1px solid black - SkPaint stroke_paint; - fill_paint.setStyle(SkPaint::kStroke_Style); - fill_paint.setColor(SK_ColorBLACK); - canvas->drawRect(bounds, fill_paint); - } else { - // Draw text input and listbox inset border - // Text Input: 2px inset #eee - // Listbox: 1px inset #808080 - const SkColor kLightColor = text.is_listbox ? - SkColorSetRGB(0x80, 0x80, 0x80) : SkColorSetRGB(0xee, 0xee, 0xee); - const SkColor kDarkColor = text.is_listbox ? - SkColorSetRGB(0x2c, 0x2c, 0x2c) : SkColorSetRGB(0x9a, 0x9a, 0x9a); - const int kBorderWidth = text.is_listbox ? 1 : 2; - - SkPaint dark_paint; - dark_paint.setAntiAlias(true); - dark_paint.setStyle(SkPaint::kFill_Style); - dark_paint.setColor(kDarkColor); - - SkPaint light_paint; - light_paint.setAntiAlias(true); - light_paint.setStyle(SkPaint::kFill_Style); - light_paint.setColor(kLightColor); - - int left = rect.x(); - int top = rect.y(); - int right = rect.right(); - int bottom = rect.bottom(); - - SkPath path; - path.incReserve(4); - - // Top - path.moveTo(SkIntToScalar(left), SkIntToScalar(top)); - path.lineTo(SkIntToScalar(left + kBorderWidth), - SkIntToScalar(top + kBorderWidth)); - path.lineTo(SkIntToScalar(right - kBorderWidth), - SkIntToScalar(top + kBorderWidth)); - path.lineTo(SkIntToScalar(right), SkIntToScalar(top)); - canvas->drawPath(path, dark_paint); - - // Bottom - path.reset(); - path.moveTo(SkIntToScalar(left + kBorderWidth), - SkIntToScalar(bottom - kBorderWidth)); - path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom)); - path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom)); - path.lineTo(SkIntToScalar(right - kBorderWidth), - SkIntToScalar(bottom - kBorderWidth)); - canvas->drawPath(path, light_paint); - - // Left - path.reset(); - path.moveTo(SkIntToScalar(left), SkIntToScalar(top)); - path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom)); - path.lineTo(SkIntToScalar(left + kBorderWidth), - SkIntToScalar(bottom - kBorderWidth)); - path.lineTo(SkIntToScalar(left + kBorderWidth), - SkIntToScalar(top + kBorderWidth)); - canvas->drawPath(path, dark_paint); - - // Right - path.reset(); - path.moveTo(SkIntToScalar(right - kBorderWidth), - SkIntToScalar(top + kBorderWidth)); - path.lineTo(SkIntToScalar(right - kBorderWidth), SkIntToScalar(bottom)); - path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom)); - path.lineTo(SkIntToScalar(right), SkIntToScalar(top)); - canvas->drawPath(path, light_paint); - } -} - -void NativeThemeLinux::PaintMenuList(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const MenuListExtraParams& menu_list) { - ButtonExtraParams button = { 0 }; - button.background_color = menu_list.background_color; - PaintButton(canvas, state, rect, button); - - SkPaint paint; - paint.setColor(SK_ColorBLACK); - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kFill_Style); - - SkPath path; - path.moveTo(menu_list.arrow_x, menu_list.arrow_y - 3); - path.rLineTo(6, 0); - path.rLineTo(-3, 6); - path.close(); - canvas->drawPath(path, paint); -} - -void NativeThemeLinux::PaintSliderTrack(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const SliderExtraParams& slider) { - const int kMidX = rect.x() + rect.width() / 2; - const int kMidY = rect.y() + rect.height() / 2; - - SkPaint paint; - paint.setColor(kSliderTrackBackgroundColor); - - SkRect skrect; - if (slider.vertical) { - skrect.set(std::max(rect.x(), kMidX - 2), - rect.y(), - std::min(rect.right(), kMidX + 2), - rect.bottom()); - } else { - skrect.set(rect.x(), - std::max(rect.y(), kMidY - 2), - rect.right(), - std::min(rect.bottom(), kMidY + 2)); - } - canvas->drawRect(skrect, paint); -} - -void NativeThemeLinux::PaintSliderThumb(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const SliderExtraParams& slider) { - const bool hovered = (state == kHovered) || slider.in_drag; - const int kMidX = rect.x() + rect.width() / 2; - const int kMidY = rect.y() + rect.height() / 2; - - SkPaint paint; - paint.setColor(hovered ? SK_ColorWHITE : kSliderThumbLightGrey); - - SkIRect skrect; - if (slider.vertical) - skrect.set(rect.x(), rect.y(), kMidX + 1, rect.bottom()); - else - skrect.set(rect.x(), rect.y(), rect.right(), kMidY + 1); - - canvas->drawIRect(skrect, paint); - - paint.setColor(hovered ? kSliderThumbLightGrey : kSliderThumbDarkGrey); - - if (slider.vertical) - skrect.set(kMidX + 1, rect.y(), rect.right(), rect.bottom()); - else - skrect.set(rect.x(), kMidY + 1, rect.right(), rect.bottom()); - - canvas->drawIRect(skrect, paint); - - paint.setColor(kSliderThumbBorderDarkGrey); - DrawBox(canvas, rect, paint); - - if (rect.height() > 10 && rect.width() > 10) { - DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY, paint); - DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY - 3, paint); - DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY + 3, paint); - } -} - -void NativeThemeLinux::PaintInnerSpinButton(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const InnerSpinButtonExtraParams& spin_button) { - if (spin_button.read_only) - state = kDisabled; - - State north_state = state; - State south_state = state; - if (spin_button.spin_up) - south_state = south_state != kDisabled ? kNormal : kDisabled; - else - north_state = north_state != kDisabled ? kNormal : kDisabled; - - gfx::Rect half = rect; - half.set_height(rect.height() / 2); - PaintArrowButton(canvas, half, kScrollbarUpArrow, north_state); - - half.set_y(rect.y() + rect.height() / 2); - PaintArrowButton(canvas, half, kScrollbarDownArrow, south_state); -} - -void NativeThemeLinux::PaintProgressBar(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const ProgressBarExtraParams& progress_bar) { - static SkBitmap* bar_image = GfxGetBitmapNamed(IDR_PROGRESS_BAR); - static SkBitmap* value_image = GfxGetBitmapNamed(IDR_PROGRESS_VALUE); - static SkBitmap* left_border_image = GfxGetBitmapNamed( - IDR_PROGRESS_BORDER_LEFT); - static SkBitmap* right_border_image = GfxGetBitmapNamed( - IDR_PROGRESS_BORDER_RIGHT); - - double tile_scale = static_cast<double>(rect.height()) / - bar_image->height(); - - int new_tile_width = static_cast<int>(bar_image->width() * tile_scale); - double tile_scale_x = static_cast<double>(new_tile_width) / - bar_image->width(); - - DrawTiledImage(canvas, *bar_image, 0, 0, tile_scale_x, tile_scale, - rect.x(), rect.y(), rect.width(), rect.height()); - - if (progress_bar.value_rect_width) { - - new_tile_width = static_cast<int>(value_image->width() * tile_scale); - tile_scale_x = static_cast<double>(new_tile_width) / - value_image->width(); - - DrawTiledImage(canvas, *value_image, 0, 0, tile_scale_x, tile_scale, - progress_bar.value_rect_x, - progress_bar.value_rect_y, - progress_bar.value_rect_width, - progress_bar.value_rect_height); - } - - int dest_left_border_width = static_cast<int>(left_border_image->width() * - tile_scale); - SkRect dest_rect = { - SkIntToScalar(rect.x()), - SkIntToScalar(rect.y()), - SkIntToScalar(rect.x() + dest_left_border_width), - SkIntToScalar(rect.bottom()) - }; - canvas->drawBitmapRect(*left_border_image, NULL, dest_rect); - - int dest_right_border_width = static_cast<int>(right_border_image->width() * - tile_scale); - dest_rect.set(SkIntToScalar(rect.right() - dest_right_border_width), - SkIntToScalar(rect.y()), - SkIntToScalar(rect.right()), - SkIntToScalar(rect.bottom())); - canvas->drawBitmapRect(*right_border_image, NULL, dest_rect); -} - -bool NativeThemeLinux::IntersectsClipRectInt( - skia::PlatformCanvas* canvas, int x, int y, int w, int h) { - SkRect clip; - return canvas->getClipBounds(&clip) && - clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), - SkIntToScalar(y + h)); -} - -void NativeThemeLinux::DrawVertLine(SkCanvas* canvas, - int x, - int y1, - int y2, - const SkPaint& paint) const { - SkIRect skrect; - skrect.set(x, y1, x + 1, y2 + 1); - canvas->drawIRect(skrect, paint); -} - -void NativeThemeLinux::DrawHorizLine(SkCanvas* canvas, - int x1, - int x2, - int y, - const SkPaint& paint) const { - SkIRect skrect; - skrect.set(x1, y, x2 + 1, y + 1); - canvas->drawIRect(skrect, paint); -} - -void NativeThemeLinux::DrawBox(SkCanvas* canvas, - const gfx::Rect& rect, - const SkPaint& paint) const { - const int right = rect.x() + rect.width() - 1; - const int bottom = rect.y() + rect.height() - 1; - DrawHorizLine(canvas, rect.x(), right, rect.y(), paint); - DrawVertLine(canvas, right, rect.y(), bottom, paint); - DrawHorizLine(canvas, rect.x(), right, bottom, paint); - DrawVertLine(canvas, rect.x(), rect.y(), bottom, paint); -} - -void NativeThemeLinux::DrawBitmapInt( - skia::PlatformCanvas* canvas, const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h) { - DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && - src_y + src_h < std::numeric_limits<int16_t>::max()); - if (src_w <= 0 || src_h <= 0 || dest_w <= 0 || dest_h <= 0) { - NOTREACHED() << "Attempting to draw bitmap to/from an empty rect!"; - return; - } - - if (!IntersectsClipRectInt(canvas, dest_x, dest_y, dest_w, dest_h)) - return; - - SkRect dest_rect = { SkIntToScalar(dest_x), - SkIntToScalar(dest_y), - SkIntToScalar(dest_x + dest_w), - SkIntToScalar(dest_y + dest_h) }; - - if (src_w == dest_w && src_h == dest_h) { - // Workaround for apparent bug in Skia that causes image to occasionally - // shift. - SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h }; - canvas->drawBitmapRect(bitmap, &src_rect, dest_rect); - return; - } - - // Make a bitmap shader that contains the bitmap we want to draw. This is - // basically what SkCanvas.drawBitmap does internally, but it gives us - // more control over quality and will use the mipmap in the source image if - // it has one, whereas drawBitmap won't. - SkShader* shader = SkShader::CreateBitmapShader(bitmap, - SkShader::kRepeat_TileMode, - SkShader::kRepeat_TileMode); - SkMatrix shader_scale; - shader_scale.setScale(SkFloatToScalar(static_cast<float>(dest_w) / src_w), - SkFloatToScalar(static_cast<float>(dest_h) / src_h)); - shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); - shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); - shader->setLocalMatrix(shader_scale); - - // The rect will be filled by the bitmap. - SkPaint p; - p.setFilterBitmap(true); - p.setShader(shader); - shader->unref(); - canvas->drawRect(dest_rect, p); -} - -void NativeThemeLinux::DrawTiledImage(SkCanvas* canvas, - const SkBitmap& bitmap, - int src_x, int src_y, double tile_scale_x, double tile_scale_y, - int dest_x, int dest_y, int w, int h) const { - SkShader* shader = SkShader::CreateBitmapShader(bitmap, - SkShader::kRepeat_TileMode, - SkShader::kRepeat_TileMode); - if (tile_scale_x != 1.0 || tile_scale_y != 1.0) { - SkMatrix shader_scale; - shader_scale.setScale(SkDoubleToScalar(tile_scale_x), - SkDoubleToScalar(tile_scale_y)); - shader->setLocalMatrix(shader_scale); - } - - SkPaint paint; - paint.setShader(shader); - paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); - - // CreateBitmapShader returns a Shader with a reference count of one, we - // need to unref after paint takes ownership of the shader. - shader->unref(); - canvas->save(); - canvas->translate(SkIntToScalar(dest_x - src_x), - SkIntToScalar(dest_y - src_y)); - canvas->clipRect(SkRect::MakeXYWH(src_x, src_y, w, h)); - canvas->drawPaint(paint); - canvas->restore(); -} - -SkScalar NativeThemeLinux::Clamp(SkScalar value, - SkScalar min, - SkScalar max) const { - return std::min(std::max(value, min), max); -} - -SkColor NativeThemeLinux::SaturateAndBrighten(SkScalar* hsv, - SkScalar saturate_amount, - SkScalar brighten_amount) const { - SkScalar color[3]; - color[0] = hsv[0]; - color[1] = Clamp(hsv[1] + saturate_amount, 0.0, 1.0); - color[2] = Clamp(hsv[2] + brighten_amount, 0.0, 1.0); - return SkHSVToColor(color); -} - -SkColor NativeThemeLinux::OutlineColor(SkScalar* hsv1, SkScalar* hsv2) const { - // GTK Theme engines have way too much control over the layout of - // the scrollbar. We might be able to more closely approximate its - // look-and-feel, if we sent whole images instead of just colors - // from the browser to the renderer. But even then, some themes - // would just break. - // - // So, instead, we don't even try to 100% replicate the look of - // the native scrollbar. We render our own version, but we make - // sure to pick colors that blend in nicely with the system GTK - // theme. In most cases, we can just sample a couple of pixels - // from the system scrollbar and use those colors to draw our - // scrollbar. - // - // This works fine for the track color and the overall thumb - // color. But it fails spectacularly for the outline color used - // around the thumb piece. Not all themes have a clearly defined - // outline. For some of them it is partially transparent, and for - // others the thickness is very unpredictable. - // - // So, instead of trying to approximate the system theme, we - // instead try to compute a reasonable looking choice based on the - // known color of the track and the thumb piece. This is difficult - // when trying to deal both with high- and low-contrast themes, - // and both with positive and inverted themes. - // - // The following code has been tested to look OK with all of the - // default GTK themes. - SkScalar min_diff = Clamp((hsv1[1] + hsv2[1]) * 1.2, 0.28, 0.5); - SkScalar diff = Clamp(fabs(hsv1[2] - hsv2[2]) / 2, min_diff, 0.5); - - if (hsv1[2] + hsv2[2] > 1.0) - diff = -diff; - - return SaturateAndBrighten(hsv2, -0.2, diff); -} - -void NativeThemeLinux::SetScrollbarColors(unsigned inactive_color, - unsigned active_color, - unsigned track_color) const { - thumb_inactive_color_ = inactive_color; - thumb_active_color_ = active_color; - track_color_ = track_color; -} - -} // namespace gfx diff --git a/gfx/native_theme_linux.h b/gfx/native_theme_linux.h index 0837d2a..679c6b8 100644 --- a/gfx/native_theme_linux.h +++ b/gfx/native_theme_linux.h @@ -5,234 +5,7 @@ #ifndef GFX_NATIVE_THEME_LINUX_H_ #define GFX_NATIVE_THEME_LINUX_H_ -#include "base/basictypes.h" -#include "skia/ext/platform_canvas.h" - -namespace skia { -class PlatformCanvas; -} - -namespace gfx { -class Rect; -class Size; - -// Linux theming API. -class NativeThemeLinux { - public: - // The part to be painted / sized. - enum Part { - kScrollbarDownArrow, - kScrollbarLeftArrow, - kScrollbarRightArrow, - kScrollbarUpArrow, - kScrollbarHorizontalThumb, - kScrollbarVerticalThumb, - kScrollbarHorizontalTrack, - kScrollbarVerticalTrack, - kCheckbox, - kRadio, - kPushButton, - kTextField, - kMenuList, - kSliderTrack, - kSliderThumb, - kInnerSpinButton, - kProgressBar, - }; - - // The state of the part. - enum State { - kDisabled, - kHovered, - kNormal, - kPressed, - }; - - // Extra data needed to draw scrollbar track correctly. - struct ScrollbarTrackExtraParams { - int track_x; - int track_y; - int track_width; - int track_height; - }; - - struct ButtonExtraParams { - bool checked; - bool indeterminate; // Whether the button state is indeterminate. - bool is_default; // Whether the button is default button. - SkColor background_color; - }; - - struct TextFieldExtraParams { - bool is_text_area; - bool is_listbox; - SkColor background_color; - }; - - struct MenuListExtraParams { - int arrow_x; - int arrow_y; - SkColor background_color; - }; - - struct SliderExtraParams { - bool vertical; - bool in_drag; - }; - - struct InnerSpinButtonExtraParams { - bool spin_up; - bool read_only; - }; - - struct ProgressBarExtraParams { - bool determinate; - int value_rect_x; - int value_rect_y; - int value_rect_width; - int value_rect_height; - }; - - union ExtraParams { - ScrollbarTrackExtraParams scrollbar_track; - ButtonExtraParams button; - MenuListExtraParams menu_list; - SliderExtraParams slider; - TextFieldExtraParams text_field; - InnerSpinButtonExtraParams inner_spin; - ProgressBarExtraParams progress_bar; - }; - - // Gets our singleton instance. - static NativeThemeLinux* instance(); - - // Return the size of the part. - virtual gfx::Size GetPartSize(Part part) const; - // Paint the part to the canvas. - virtual void Paint(skia::PlatformCanvas* canvas, - Part part, - State state, - const gfx::Rect& rect, - const ExtraParams& extra); - // Supports theme specific colors. - void SetScrollbarColors(unsigned inactive_color, - unsigned active_color, - unsigned track_color) const; - - protected: - NativeThemeLinux(); - virtual ~NativeThemeLinux(); - - // Draw the arrow. Used by scrollbar and inner spin button. - virtual void PaintArrowButton( - skia::PlatformCanvas* gc, - const gfx::Rect& rect, - Part direction, - State state); - // Paint the scrollbar track. Done before the thumb so that it can contain - // alpha. - virtual void PaintScrollbarTrack(skia::PlatformCanvas* canvas, - Part part, - State state, - const ScrollbarTrackExtraParams& extra_params, - const gfx::Rect& rect); - // Draw the scrollbar thumb over the track. - virtual void PaintScrollbarThumb(skia::PlatformCanvas* canvas, - Part part, - State state, - const gfx::Rect& rect); - // Draw the checkbox. - virtual void PaintCheckbox(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const ButtonExtraParams& button); - // Draw the radio. - virtual void PaintRadio(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const ButtonExtraParams& button); - // Draw the push button. - virtual void PaintButton(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const ButtonExtraParams& button); - // Draw the text field. - virtual void PaintTextField(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const TextFieldExtraParams& text); - // Draw the menu list. - virtual void PaintMenuList(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const MenuListExtraParams& menu_list); - // Draw the slider track. - virtual void PaintSliderTrack(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const SliderExtraParams& slider); - // Draw the slider thumb. - virtual void PaintSliderThumb(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const SliderExtraParams& slider); - // Draw the inner spin button. - virtual void PaintInnerSpinButton(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const InnerSpinButtonExtraParams& spin_button); - // Draw the progress bar. - virtual void PaintProgressBar(skia::PlatformCanvas* canvas, - State state, - const gfx::Rect& rect, - const ProgressBarExtraParams& progress_bar); - - protected: - bool IntersectsClipRectInt(skia::PlatformCanvas* canvas, - int x, int y, int w, int h); - - void DrawBitmapInt(skia::PlatformCanvas* canvas, const SkBitmap& bitmap, - int src_x, int src_y, int src_w, int src_h, - int dest_x, int dest_y, int dest_w, int dest_h); - - void DrawTiledImage(SkCanvas* canvas, - const SkBitmap& bitmap, - int src_x, int src_y, - double tile_scale_x, double tile_scale_y, - int dest_x, int dest_y, int w, int h) const; - - SkColor SaturateAndBrighten(SkScalar* hsv, - SkScalar saturate_amount, - SkScalar brighten_amount) const; - - private: - void DrawVertLine(SkCanvas* canvas, - int x, - int y1, - int y2, - const SkPaint& paint) const; - void DrawHorizLine(SkCanvas* canvas, - int x1, - int x2, - int y, - const SkPaint& paint) const; - void DrawBox(SkCanvas* canvas, - const gfx::Rect& rect, - const SkPaint& paint) const; - SkScalar Clamp(SkScalar value, - SkScalar min, - SkScalar max) const; - SkColor OutlineColor(SkScalar* hsv1, SkScalar* hsv2) const; - - static unsigned int scrollbar_width_; - static unsigned int button_length_; - static unsigned int thumb_inactive_color_; - static unsigned int thumb_active_color_; - static unsigned int track_color_; - - DISALLOW_COPY_AND_ASSIGN(NativeThemeLinux); -}; - -} // namespace gfx +#include "ui/gfx/native_theme_linux.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_NATIVE_THEME_LINUX_H_ diff --git a/gfx/native_theme_win.cc b/gfx/native_theme_win.cc deleted file mode 100644 index b563b4f..0000000 --- a/gfx/native_theme_win.cc +++ /dev/null @@ -1,874 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/native_theme_win.h" - -#include <windows.h> -#include <uxtheme.h> -#include <vsstyle.h> -#include <vssym32.h> - -#include "base/logging.h" -#include "base/scoped_handle.h" -#include "base/win/scoped_gdi_object.h" -#include "base/win/scoped_hdc.h" -#include "base/win/windows_version.h" -#include "gfx/gdi_util.h" -#include "gfx/rect.h" -#include "skia/ext/platform_canvas.h" -#include "skia/ext/skia_utils_win.h" -#include "third_party/skia/include/core/SkShader.h" - -namespace { - -void SetCheckerboardShader(SkPaint* paint, const RECT& align_rect) { - // Create a 2x2 checkerboard pattern using the 3D face and highlight colors. - SkColor face = skia::COLORREFToSkColor(GetSysColor(COLOR_3DFACE)); - SkColor highlight = skia::COLORREFToSkColor(GetSysColor(COLOR_3DHILIGHT)); - SkColor buffer[] = { face, highlight, highlight, face }; - // Confusing bit: we first create a temporary bitmap with our desired pattern, - // then copy it to another bitmap. The temporary bitmap doesn't take - // ownership of the pixel data, and so will point to garbage when this - // function returns. The copy will copy the pixel data into a place owned by - // the bitmap, which is in turn owned by the shader, etc., so it will live - // until we're done using it. - SkBitmap temp_bitmap; - temp_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); - temp_bitmap.setPixels(buffer); - SkBitmap bitmap; - temp_bitmap.copyTo(&bitmap, temp_bitmap.config()); - SkShader* shader = SkShader::CreateBitmapShader(bitmap, - SkShader::kRepeat_TileMode, - SkShader::kRepeat_TileMode); - - // Align the pattern with the upper corner of |align_rect|. - SkMatrix matrix; - matrix.setTranslate(SkIntToScalar(align_rect.left), - SkIntToScalar(align_rect.top)); - shader->setLocalMatrix(matrix); - SkSafeUnref(paint->setShader(shader)); -} - -} // namespace - -namespace gfx { - -/* static */ -const NativeTheme* NativeTheme::instance() { - // The global NativeTheme instance. - static const NativeTheme s_native_theme; - return &s_native_theme; -} - -NativeTheme::NativeTheme() - : theme_dll_(LoadLibrary(L"uxtheme.dll")), - draw_theme_(NULL), - draw_theme_ex_(NULL), - get_theme_color_(NULL), - get_theme_content_rect_(NULL), - get_theme_part_size_(NULL), - open_theme_(NULL), - close_theme_(NULL), - set_theme_properties_(NULL), - is_theme_active_(NULL), - get_theme_int_(NULL) { - if (theme_dll_) { - draw_theme_ = reinterpret_cast<DrawThemeBackgroundPtr>( - GetProcAddress(theme_dll_, "DrawThemeBackground")); - draw_theme_ex_ = reinterpret_cast<DrawThemeBackgroundExPtr>( - GetProcAddress(theme_dll_, "DrawThemeBackgroundEx")); - get_theme_color_ = reinterpret_cast<GetThemeColorPtr>( - GetProcAddress(theme_dll_, "GetThemeColor")); - get_theme_content_rect_ = reinterpret_cast<GetThemeContentRectPtr>( - GetProcAddress(theme_dll_, "GetThemeBackgroundContentRect")); - get_theme_part_size_ = reinterpret_cast<GetThemePartSizePtr>( - GetProcAddress(theme_dll_, "GetThemePartSize")); - open_theme_ = reinterpret_cast<OpenThemeDataPtr>( - GetProcAddress(theme_dll_, "OpenThemeData")); - close_theme_ = reinterpret_cast<CloseThemeDataPtr>( - GetProcAddress(theme_dll_, "CloseThemeData")); - set_theme_properties_ = reinterpret_cast<SetThemeAppPropertiesPtr>( - GetProcAddress(theme_dll_, "SetThemeAppProperties")); - is_theme_active_ = reinterpret_cast<IsThemeActivePtr>( - GetProcAddress(theme_dll_, "IsThemeActive")); - get_theme_int_ = reinterpret_cast<GetThemeIntPtr>( - GetProcAddress(theme_dll_, "GetThemeInt")); - } - memset(theme_handles_, 0, sizeof(theme_handles_)); -} - -NativeTheme::~NativeTheme() { - if (theme_dll_) { - // todo (cpu): fix this soon. - // CloseHandles(); - FreeLibrary(theme_dll_); - } -} - -HRESULT NativeTheme::PaintButton(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect) const { - HANDLE handle = GetThemeHandle(BUTTON); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - - // Draw it manually. - // All pressed states have both low bits set, and no other states do. - const bool focused = ((state_id & ETS_FOCUSED) == ETS_FOCUSED); - const bool pressed = ((state_id & PBS_PRESSED) == PBS_PRESSED); - if ((BP_PUSHBUTTON == part_id) && (pressed || focused)) { - // BP_PUSHBUTTON has a focus rect drawn around the outer edge, and the - // button itself is shrunk by 1 pixel. - HBRUSH brush = GetSysColorBrush(COLOR_3DDKSHADOW); - if (brush) { - FrameRect(hdc, rect, brush); - InflateRect(rect, -1, -1); - } - } - DrawFrameControl(hdc, rect, DFC_BUTTON, classic_state); - - // Draw the focus rectangle (the dotted line box) only on buttons. For radio - // and checkboxes, we let webkit draw the focus rectangle (orange glow). - if ((BP_PUSHBUTTON == part_id) && focused) { - // The focus rect is inside the button. The exact number of pixels depends - // on whether we're in classic mode or using uxtheme. - if (handle && get_theme_content_rect_) { - get_theme_content_rect_(handle, hdc, part_id, state_id, rect, rect); - } else { - InflateRect(rect, -GetSystemMetrics(SM_CXEDGE), - -GetSystemMetrics(SM_CYEDGE)); - } - DrawFocusRect(hdc, rect); - } - - return S_OK; -} - -HRESULT NativeTheme::PaintDialogBackground(HDC hdc, bool active, - RECT* rect) const { - HANDLE handle = GetThemeHandle(WINDOW); - if (handle && draw_theme_) { - return draw_theme_(handle, hdc, WP_DIALOG, - active ? FS_ACTIVE : FS_INACTIVE, rect, NULL); - } - - // Classic just renders a flat color background. - FillRect(hdc, rect, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1)); - return S_OK; -} - -HRESULT NativeTheme::PaintListBackground(HDC hdc, - bool enabled, - RECT* rect) const { - HANDLE handle = GetThemeHandle(LIST); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, 1, TS_NORMAL, rect, NULL); - - // Draw it manually. - HBRUSH bg_brush = GetSysColorBrush(COLOR_WINDOW); - FillRect(hdc, rect, bg_brush); - DrawEdge(hdc, rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); - return S_OK; -} - -HRESULT NativeTheme::PaintMenuArrow(ThemeName theme, - HDC hdc, - int part_id, - int state_id, - RECT* rect, - MenuArrowDirection arrow_direction, - ControlState control_state) const { - HANDLE handle = GetThemeHandle(MENU); - if (handle && draw_theme_) { - if (arrow_direction == RIGHT_POINTING_ARROW) { - return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - } else { - // There is no way to tell the uxtheme API to draw a left pointing arrow; - // it doesn't have a flag equivalent to DFCS_MENUARROWRIGHT. But they - // are needed for RTL locales on Vista. So use a memory DC and mirror - // the region with GDI's StretchBlt. - Rect r(*rect); - base::win::ScopedHDC mem_dc(CreateCompatibleDC(hdc)); - base::win::ScopedBitmap mem_bitmap(CreateCompatibleBitmap(hdc, r.width(), - r.height())); - HGDIOBJ old_bitmap = SelectObject(mem_dc, mem_bitmap); - // Copy and horizontally mirror the background from hdc into mem_dc. Use - // a negative-width source rect, starting at the rightmost pixel. - StretchBlt(mem_dc, 0, 0, r.width(), r.height(), - hdc, r.right()-1, r.y(), -r.width(), r.height(), SRCCOPY); - // Draw the arrow. - RECT theme_rect = {0, 0, r.width(), r.height()}; - HRESULT result = draw_theme_(handle, mem_dc, part_id, - state_id, &theme_rect, NULL); - // Copy and mirror the result back into mem_dc. - StretchBlt(hdc, r.x(), r.y(), r.width(), r.height(), - mem_dc, r.width()-1, 0, -r.width(), r.height(), SRCCOPY); - SelectObject(mem_dc, old_bitmap); - return result; - } - } - - // For some reason, Windows uses the name DFCS_MENUARROWRIGHT to indicate a - // left pointing arrow. This makes the following 'if' statement slightly - // counterintuitive. - UINT state; - if (arrow_direction == RIGHT_POINTING_ARROW) - state = DFCS_MENUARROW; - else - state = DFCS_MENUARROWRIGHT; - return PaintFrameControl(hdc, rect, DFC_MENU, state, control_state); -} - -HRESULT NativeTheme::PaintMenuBackground(ThemeName theme, - HDC hdc, - int part_id, - int state_id, - RECT* rect) const { - HANDLE handle = GetThemeHandle(MENU); - if (handle && draw_theme_) { - HRESULT result = draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - FrameRect(hdc, rect, GetSysColorBrush(COLOR_3DSHADOW)); - return result; - } - - FillRect(hdc, rect, GetSysColorBrush(COLOR_MENU)); - DrawEdge(hdc, rect, EDGE_RAISED, BF_RECT); - return S_OK; -} - -HRESULT NativeTheme::PaintMenuCheckBackground(ThemeName theme, - HDC hdc, - int part_id, - int state_id, - RECT* rect) const { - HANDLE handle = GetThemeHandle(MENU); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - // Nothing to do for background. - return S_OK; -} - -HRESULT NativeTheme::PaintMenuCheck(ThemeName theme, - HDC hdc, - int part_id, - int state_id, - RECT* rect, - ControlState control_state) const { - HANDLE handle = GetThemeHandle(MENU); - if (handle && draw_theme_) { - return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - } - return PaintFrameControl(hdc, rect, DFC_MENU, DFCS_MENUCHECK, control_state); -} - -HRESULT NativeTheme::PaintMenuGutter(HDC hdc, - int part_id, - int state_id, - RECT* rect) const { - HANDLE handle = GetThemeHandle(MENU); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - return E_NOTIMPL; -} - -HRESULT NativeTheme::PaintMenuItemBackground(ThemeName theme, - HDC hdc, - int part_id, - int state_id, - bool selected, - RECT* rect) const { - HANDLE handle = GetThemeHandle(MENU); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - if (selected) - FillRect(hdc, rect, GetSysColorBrush(COLOR_HIGHLIGHT)); - return S_OK; -} - -HRESULT NativeTheme::PaintMenuList(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect) const { - HANDLE handle = GetThemeHandle(MENULIST); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - - // Draw it manually. - DrawFrameControl(hdc, rect, DFC_SCROLL, DFCS_SCROLLCOMBOBOX | classic_state); - return S_OK; -} - -HRESULT NativeTheme::PaintMenuSeparator(HDC hdc, - int part_id, - int state_id, - RECT* rect) const { - HANDLE handle = GetThemeHandle(MENU); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - DrawEdge(hdc, rect, EDGE_ETCHED, BF_TOP); - return S_OK; -} - -HRESULT NativeTheme::PaintScrollbarArrow(HDC hdc, - int state_id, - int classic_state, - RECT* rect) const { - HANDLE handle = GetThemeHandle(SCROLLBAR); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, SBP_ARROWBTN, state_id, rect, NULL); - - // Draw it manually. - DrawFrameControl(hdc, rect, DFC_SCROLL, classic_state); - return S_OK; -} - -HRESULT NativeTheme::PaintScrollbarTrack( - HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* target_rect, - RECT* align_rect, - skia::PlatformCanvas* canvas) const { - HANDLE handle = GetThemeHandle(SCROLLBAR); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, part_id, state_id, target_rect, NULL); - - // Draw it manually. - const DWORD colorScrollbar = GetSysColor(COLOR_SCROLLBAR); - const DWORD color3DFace = GetSysColor(COLOR_3DFACE); - if ((colorScrollbar != color3DFace) && - (colorScrollbar != GetSysColor(COLOR_WINDOW))) { - FillRect(hdc, target_rect, reinterpret_cast<HBRUSH>(COLOR_SCROLLBAR + 1)); - } else { - SkPaint paint; - SetCheckerboardShader(&paint, *align_rect); - canvas->drawIRect(skia::RECTToSkIRect(*target_rect), paint); - } - if (classic_state & DFCS_PUSHED) - InvertRect(hdc, target_rect); - return S_OK; -} - -HRESULT NativeTheme::PaintScrollbarThumb(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect) const { - HANDLE handle = GetThemeHandle(SCROLLBAR); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - - // Draw it manually. - if ((part_id == SBP_THUMBBTNHORZ) || (part_id == SBP_THUMBBTNVERT)) - DrawEdge(hdc, rect, EDGE_RAISED, BF_RECT | BF_MIDDLE); - // Classic mode doesn't have a gripper. - return S_OK; -} - -HRESULT NativeTheme::PaintSpinButton(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect) const { - HANDLE handle = GetThemeHandle(SPIN); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - DrawFrameControl(hdc, rect, DFC_SCROLL, classic_state); - return S_OK; -} - -HRESULT NativeTheme::PaintStatusGripper(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect) const { - HANDLE handle = GetThemeHandle(STATUS); - if (handle && draw_theme_) { - // Paint the status bar gripper. There doesn't seem to be a - // standard gripper in Windows for the space between - // scrollbars. This is pretty close, but it's supposed to be - // painted over a status bar. - return draw_theme_(handle, hdc, SP_GRIPPER, 0, rect, NULL); - } - - // Draw a windows classic scrollbar gripper. - DrawFrameControl(hdc, rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP); - return S_OK; -} - -HRESULT NativeTheme::PaintTabPanelBackground(HDC hdc, RECT* rect) const { - HANDLE handle = GetThemeHandle(TAB); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, TABP_BODY, 0, rect, NULL); - - // Classic just renders a flat color background. - FillRect(hdc, rect, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1)); - return S_OK; -} - -HRESULT NativeTheme::PaintTrackbar(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect, - skia::PlatformCanvas* canvas) const { - // Make the channel be 4 px thick in the center of the supplied rect. (4 px - // matches what XP does in various menus; GetThemePartSize() doesn't seem to - // return good values here.) - RECT channel_rect = *rect; - const int channel_thickness = 4; - if (part_id == TKP_TRACK) { - channel_rect.top += - ((channel_rect.bottom - channel_rect.top - channel_thickness) / 2); - channel_rect.bottom = channel_rect.top + channel_thickness; - } else if (part_id == TKP_TRACKVERT) { - channel_rect.left += - ((channel_rect.right - channel_rect.left - channel_thickness) / 2); - channel_rect.right = channel_rect.left + channel_thickness; - } // else this isn't actually a channel, so |channel_rect| == |rect|. - - HANDLE handle = GetThemeHandle(TRACKBAR); - if (handle && draw_theme_) - return draw_theme_(handle, hdc, part_id, state_id, &channel_rect, NULL); - - // Classic mode, draw it manually. - if ((part_id == TKP_TRACK) || (part_id == TKP_TRACKVERT)) { - DrawEdge(hdc, &channel_rect, EDGE_SUNKEN, BF_RECT); - } else if (part_id == TKP_THUMBVERT) { - DrawEdge(hdc, rect, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE); - } else { - // Split rect into top and bottom pieces. - RECT top_section = *rect; - RECT bottom_section = *rect; - top_section.bottom -= ((bottom_section.right - bottom_section.left) / 2); - bottom_section.top = top_section.bottom; - DrawEdge(hdc, &top_section, EDGE_RAISED, - BF_LEFT | BF_TOP | BF_RIGHT | BF_SOFT | BF_MIDDLE | BF_ADJUST); - - // Split triangular piece into two diagonals. - RECT& left_half = bottom_section; - RECT right_half = bottom_section; - right_half.left += ((bottom_section.right - bottom_section.left) / 2); - left_half.right = right_half.left; - DrawEdge(hdc, &left_half, EDGE_RAISED, - BF_DIAGONAL_ENDTOPLEFT | BF_SOFT | BF_MIDDLE | BF_ADJUST); - DrawEdge(hdc, &right_half, EDGE_RAISED, - BF_DIAGONAL_ENDBOTTOMLEFT | BF_SOFT | BF_MIDDLE | BF_ADJUST); - - // If the button is pressed, draw hatching. - if (classic_state & DFCS_PUSHED) { - SkPaint paint; - SetCheckerboardShader(&paint, *rect); - - // Fill all three pieces with the pattern. - canvas->drawIRect(skia::RECTToSkIRect(top_section), paint); - - SkScalar left_triangle_top = SkIntToScalar(left_half.top); - SkScalar left_triangle_right = SkIntToScalar(left_half.right); - SkPath left_triangle; - left_triangle.moveTo(SkIntToScalar(left_half.left), left_triangle_top); - left_triangle.lineTo(left_triangle_right, left_triangle_top); - left_triangle.lineTo(left_triangle_right, - SkIntToScalar(left_half.bottom)); - left_triangle.close(); - canvas->drawPath(left_triangle, paint); - - SkScalar right_triangle_left = SkIntToScalar(right_half.left); - SkScalar right_triangle_top = SkIntToScalar(right_half.top); - SkPath right_triangle; - right_triangle.moveTo(right_triangle_left, right_triangle_top); - right_triangle.lineTo(SkIntToScalar(right_half.right), - right_triangle_top); - right_triangle.lineTo(right_triangle_left, - SkIntToScalar(right_half.bottom)); - right_triangle.close(); - canvas->drawPath(right_triangle, paint); - } - } - return S_OK; -} - -// <-a-> -// [ ***** ] -// ____ | | -// <-a-> <------b-----> -// a: object_width -// b: frame_width -// *: animating object -// -// - the animation goes from "[" to "]" repeatedly. -// - the animation offset is at first "|" -// -static int ComputeAnimationProgress(int frame_width, - int object_width, - int pixels_per_second, - double animated_seconds) { - int animation_width = frame_width + object_width; - double interval = static_cast<double>(animation_width) / pixels_per_second; - double ratio = fmod(animated_seconds, interval) / interval; - return static_cast<int>(animation_width * ratio) - object_width; -} - -static RECT InsetRect(const RECT* rect, int size) { - gfx::Rect result(*rect); - result.Inset(size, size); - return result.ToRECT(); -} - -HRESULT NativeTheme::PaintProgressBar(HDC hdc, - RECT* bar_rect, - RECT* value_rect, - bool determinate, - double animated_seconds, - skia::PlatformCanvas* canvas) const { - // There is no documentation about the animation speed, frame-rate, nor - // size of moving overlay of the indeterminate progress bar. - // So we just observed real-world programs and guessed following parameters. - const int kDeteminateOverlayPixelsPerSecond = 300; - const int kDeteminateOverlayWidth = 120; - const int kIndeterminateOverlayPixelsPerSecond = 175; - const int kVistaIndeterminateOverlayWidth = 120; - const int kXPIndeterminateOverlayWidth = 55; - // The thickness of the bar frame inside |value_rect| - const int kXPBarPadding = 3; - - bool pre_vista = base::win::GetVersion() < base::win::VERSION_VISTA; - HANDLE handle = GetThemeHandle(PROGRESS); - if (handle && draw_theme_ && draw_theme_ex_) { - draw_theme_(handle, hdc, PP_BAR, 0, bar_rect, NULL); - - int bar_width = bar_rect->right - bar_rect->left; - if (determinate) { - // TODO(morrita): this RTL guess can be wrong. - // We should pass the direction from WebKit side. - bool is_rtl = (bar_rect->right == value_rect->right && - bar_rect->left != value_rect->left); - // We should care the direction here because PP_CNUNK painting - // is asymmetric. - DTBGOPTS value_draw_options; - value_draw_options.dwSize = sizeof(DTBGOPTS); - value_draw_options.dwFlags = is_rtl ? DTBG_MIRRORDC : 0; - value_draw_options.rcClip = *bar_rect; - - if (pre_vista) { - // On XP, progress bar is chunk-style and has no glossy effect. - // We need to shrink destination rect to fit the part inside the bar - // with an appropriate margin. - RECT shrunk_value_rect = InsetRect(value_rect, kXPBarPadding); - draw_theme_ex_(handle, hdc, PP_CHUNK, 0, - &shrunk_value_rect, &value_draw_options); - } else { - // On Vista or later, the progress bar part has a - // single-block value part. It also has glossy effect. - // And the value part has exactly same height as the bar part - // so we don't need to shrink the rect. - draw_theme_ex_(handle, hdc, PP_FILL, 0, - value_rect, &value_draw_options); - - int dx = ComputeAnimationProgress(bar_width, - kDeteminateOverlayWidth, - kDeteminateOverlayPixelsPerSecond, - animated_seconds); - RECT overlay_rect = *value_rect; - overlay_rect.left += dx; - overlay_rect.right = overlay_rect.left + kDeteminateOverlayWidth; - draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, value_rect); - } - } else { - // A glossy overlay for indeterminate progress bar has small pause - // after each animation. We emulate this by adding an invisible margin - // the animation has to traverse. - int width_with_margin = bar_width + kIndeterminateOverlayPixelsPerSecond; - int overlay_width = pre_vista ? - kXPIndeterminateOverlayWidth : kVistaIndeterminateOverlayWidth; - int dx = ComputeAnimationProgress(width_with_margin, - overlay_width, - kIndeterminateOverlayPixelsPerSecond, - animated_seconds); - RECT overlay_rect = *bar_rect; - overlay_rect.left += dx; - overlay_rect.right = overlay_rect.left + overlay_width; - if (pre_vista) { - RECT shrunk_rect = InsetRect(&overlay_rect, kXPBarPadding); - RECT shrunk_bar_rect = InsetRect(bar_rect, kXPBarPadding); - draw_theme_(handle, hdc, PP_CHUNK, 0, &shrunk_rect, &shrunk_bar_rect); - } else { - draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, bar_rect); - } - } - - return S_OK; - } - - HBRUSH bg_brush = GetSysColorBrush(COLOR_BTNFACE); - HBRUSH fg_brush = GetSysColorBrush(COLOR_BTNSHADOW); - FillRect(hdc, bar_rect, bg_brush); - FillRect(hdc, value_rect, fg_brush); - DrawEdge(hdc, bar_rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); - return S_OK; -} - -HRESULT NativeTheme::PaintTextField(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect, - COLORREF color, - bool fill_content_area, - bool draw_edges) const { - // TODO(ojan): http://b/1210017 Figure out how to give the ability to - // exclude individual edges from being drawn. - - HANDLE handle = GetThemeHandle(TEXTFIELD); - // TODO(mpcomplete): can we detect if the color is specified by the user, - // and if not, just use the system color? - // CreateSolidBrush() accepts a RGB value but alpha must be 0. - HBRUSH bg_brush = CreateSolidBrush(color); - HRESULT hr; - // DrawThemeBackgroundEx was introduced in XP SP2, so that it's possible - // draw_theme_ex_ is NULL and draw_theme_ is non-null. - if (handle && (draw_theme_ex_ || (draw_theme_ && draw_edges))) { - if (draw_theme_ex_) { - static DTBGOPTS omit_border_options = { - sizeof(DTBGOPTS), - DTBG_OMITBORDER, - {0,0,0,0} - }; - DTBGOPTS* draw_opts = draw_edges ? NULL : &omit_border_options; - hr = draw_theme_ex_(handle, hdc, part_id, state_id, rect, draw_opts); - } else { - hr = draw_theme_(handle, hdc, part_id, state_id, rect, NULL); - } - - // TODO(maruel): Need to be fixed if get_theme_content_rect_ is NULL. - if (fill_content_area && get_theme_content_rect_) { - RECT content_rect; - hr = get_theme_content_rect_(handle, hdc, part_id, state_id, rect, - &content_rect); - FillRect(hdc, &content_rect, bg_brush); - } - } else { - // Draw it manually. - if (draw_edges) - DrawEdge(hdc, rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); - - if (fill_content_area) { - FillRect(hdc, rect, (classic_state & DFCS_INACTIVE) ? - reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1) : bg_brush); - } - hr = S_OK; - } - DeleteObject(bg_brush); - return hr; -} - -bool NativeTheme::IsThemingActive() const { - if (is_theme_active_) - return !!is_theme_active_(); - return false; -} - -HRESULT NativeTheme::GetThemePartSize(ThemeName theme_name, - HDC hdc, - int part_id, - int state_id, - RECT* rect, - int ts, - SIZE* size) const { - HANDLE handle = GetThemeHandle(theme_name); - if (handle && get_theme_part_size_) - return get_theme_part_size_(handle, hdc, part_id, state_id, rect, ts, size); - - return E_NOTIMPL; -} - -HRESULT NativeTheme::GetThemeColor(ThemeName theme, - int part_id, - int state_id, - int prop_id, - SkColor* color) const { - HANDLE handle = GetThemeHandle(theme); - if (handle && get_theme_color_) { - COLORREF color_ref; - if (get_theme_color_(handle, part_id, state_id, prop_id, &color_ref) == - S_OK) { - *color = skia::COLORREFToSkColor(color_ref); - return S_OK; - } - } - return E_NOTIMPL; -} - -SkColor NativeTheme::GetThemeColorWithDefault(ThemeName theme, - int part_id, - int state_id, - int prop_id, - int default_sys_color) const { - SkColor color; - if (GetThemeColor(theme, part_id, state_id, prop_id, &color) != S_OK) - color = skia::COLORREFToSkColor(GetSysColor(default_sys_color)); - return color; -} - -HRESULT NativeTheme::GetThemeInt(ThemeName theme, - int part_id, - int state_id, - int prop_id, - int *value) const { - HANDLE handle = GetThemeHandle(theme); - if (handle && get_theme_int_) - return get_theme_int_(handle, part_id, state_id, prop_id, value); - return E_NOTIMPL; -} - -Size NativeTheme::GetThemeBorderSize(ThemeName theme) const { - // For simplicity use the wildcard state==0, part==0, since it works - // for the cases we currently depend on. - int border; - if (GetThemeInt(theme, 0, 0, TMT_BORDERSIZE, &border) == S_OK) - return Size(border, border); - else - return Size(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)); -} - - -void NativeTheme::DisableTheming() const { - if (!set_theme_properties_) - return; - set_theme_properties_(0); -} - -HRESULT NativeTheme::PaintFrameControl(HDC hdc, - RECT* rect, - UINT type, - UINT state, - ControlState control_state) const { - const int width = rect->right - rect->left; - const int height = rect->bottom - rect->top; - - // DrawFrameControl for menu arrow/check wants a monochrome bitmap. - base::win::ScopedBitmap mask_bitmap(CreateBitmap(width, height, 1, 1, NULL)); - - if (mask_bitmap == NULL) - return E_OUTOFMEMORY; - - base::win::ScopedHDC bitmap_dc(CreateCompatibleDC(NULL)); - HGDIOBJ org_bitmap = SelectObject(bitmap_dc, mask_bitmap); - RECT local_rect = { 0, 0, width, height }; - DrawFrameControl(bitmap_dc, &local_rect, type, state); - - // We're going to use BitBlt with a b&w mask. This results in using the dest - // dc's text color for the black bits in the mask, and the dest dc's - // background color for the white bits in the mask. DrawFrameControl draws the - // check in black, and the background in white. - int bg_color_key; - int text_color_key; - switch (control_state) { - case CONTROL_HIGHLIGHTED: - bg_color_key = COLOR_HIGHLIGHT; - text_color_key = COLOR_HIGHLIGHTTEXT; - break; - case CONTROL_NORMAL: - bg_color_key = COLOR_MENU; - text_color_key = COLOR_MENUTEXT; - break; - case CONTROL_DISABLED: - bg_color_key = COLOR_MENU; - text_color_key = COLOR_GRAYTEXT; - break; - default: - NOTREACHED(); - bg_color_key = COLOR_MENU; - text_color_key = COLOR_MENUTEXT; - break; - } - COLORREF old_bg_color = SetBkColor(hdc, GetSysColor(bg_color_key)); - COLORREF old_text_color = SetTextColor(hdc, GetSysColor(text_color_key)); - BitBlt(hdc, rect->left, rect->top, width, height, bitmap_dc, 0, 0, SRCCOPY); - SetBkColor(hdc, old_bg_color); - SetTextColor(hdc, old_text_color); - - SelectObject(bitmap_dc, org_bitmap); - - return S_OK; -} - -void NativeTheme::CloseHandles() const -{ - if (!close_theme_) - return; - - for (int i = 0; i < LAST; ++i) { - if (theme_handles_[i]) - close_theme_(theme_handles_[i]); - theme_handles_[i] = NULL; - } -} - -bool NativeTheme::IsClassicTheme(ThemeName name) const { - if (!theme_dll_) - return true; - - return !GetThemeHandle(name); -} - -HANDLE NativeTheme::GetThemeHandle(ThemeName theme_name) const -{ - if (!open_theme_ || theme_name < 0 || theme_name >= LAST) - return 0; - - if (theme_handles_[theme_name]) - return theme_handles_[theme_name]; - - // Not found, try to load it. - HANDLE handle = 0; - switch (theme_name) { - case BUTTON: - handle = open_theme_(NULL, L"Button"); - break; - case LIST: - handle = open_theme_(NULL, L"Listview"); - break; - case MENU: - handle = open_theme_(NULL, L"Menu"); - break; - case MENULIST: - handle = open_theme_(NULL, L"Combobox"); - break; - case SCROLLBAR: - handle = open_theme_(NULL, L"Scrollbar"); - break; - case STATUS: - handle = open_theme_(NULL, L"Status"); - break; - case TAB: - handle = open_theme_(NULL, L"Tab"); - break; - case TEXTFIELD: - handle = open_theme_(NULL, L"Edit"); - break; - case TRACKBAR: - handle = open_theme_(NULL, L"Trackbar"); - break; - case WINDOW: - handle = open_theme_(NULL, L"Window"); - break; - case PROGRESS: - handle = open_theme_(NULL, L"Progress"); - break; - case SPIN: - handle = open_theme_(NULL, L"Spin"); - break; - default: - NOTREACHED(); - } - theme_handles_[theme_name] = handle; - return handle; -} - -} // namespace gfx diff --git a/gfx/native_theme_win.h b/gfx/native_theme_win.h index 72a5432..c45b5fc 100644 --- a/gfx/native_theme_win.h +++ b/gfx/native_theme_win.h @@ -12,310 +12,7 @@ #define APP_GFX_NATIVE_THEME_WIN_H_ #pragma once -#include <windows.h> -#include <uxtheme.h> -#include "base/basictypes.h" -#include "gfx/size.h" -#include "third_party/skia/include/core/SkColor.h" - -namespace skia { -class PlatformCanvas; -} // namespace skia - -namespace gfx { - -// TODO: Define class member enums to replace part_id and state_id parameters -// that are currently defined in <vssym32.h>. Afterward, classic_state should -// be removed and class users wouldn't need to include <vssym32.h> anymore. -// This would enable HOT state on non-themed UI (like when RDP'ing) and would -// simplify usage. -// TODO: This class should probably be changed to be platform independent at -// the same time. -class NativeTheme { - public: - enum ThemeName { - BUTTON, - LIST, - MENU, - MENULIST, - SCROLLBAR, - STATUS, - TAB, - TEXTFIELD, - TRACKBAR, - WINDOW, - PROGRESS, - SPIN, - LAST - }; - - // This enumeration is used within PaintMenuArrow in order to indicate the - // direction the menu arrow should point to. - enum MenuArrowDirection { - LEFT_POINTING_ARROW, - RIGHT_POINTING_ARROW - }; - - enum ControlState { - CONTROL_NORMAL, - CONTROL_HIGHLIGHTED, - CONTROL_DISABLED - }; - - typedef HRESULT (WINAPI* DrawThemeBackgroundPtr)(HANDLE theme, - HDC hdc, - int part_id, - int state_id, - const RECT* rect, - const RECT* clip_rect); - typedef HRESULT (WINAPI* DrawThemeBackgroundExPtr)(HANDLE theme, - HDC hdc, - int part_id, - int state_id, - const RECT* rect, - const DTBGOPTS* opts); - typedef HRESULT (WINAPI* GetThemeColorPtr)(HANDLE hTheme, - int part_id, - int state_id, - int prop_id, - COLORREF* color); - typedef HRESULT (WINAPI* GetThemeContentRectPtr)(HANDLE hTheme, - HDC hdc, - int part_id, - int state_id, - const RECT* rect, - RECT* content_rect); - typedef HRESULT (WINAPI* GetThemePartSizePtr)(HANDLE hTheme, - HDC hdc, - int part_id, - int state_id, - RECT* rect, - int ts, - SIZE* size); - typedef HANDLE (WINAPI* OpenThemeDataPtr)(HWND window, - LPCWSTR class_list); - typedef HRESULT (WINAPI* CloseThemeDataPtr)(HANDLE theme); - - typedef void (WINAPI* SetThemeAppPropertiesPtr) (DWORD flags); - typedef BOOL (WINAPI* IsThemeActivePtr)(); - typedef HRESULT (WINAPI* GetThemeIntPtr)(HANDLE hTheme, - int part_id, - int state_id, - int prop_id, - int *value); - - HRESULT PaintButton(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect) const; - - HRESULT PaintDialogBackground(HDC dc, bool active, RECT* rect) const; - - HRESULT PaintListBackground(HDC dc, bool enabled, RECT* rect) const; - - // |arrow_direction| determines whether the arrow is pointing to the left or - // to the right. In RTL locales, sub-menus open from right to left and - // therefore the menu arrow should point to the left and not to the right. - HRESULT PaintMenuArrow(ThemeName theme, - HDC hdc, - int part_id, - int state_id, - RECT* rect, - MenuArrowDirection arrow_direction, - ControlState state) const; - - HRESULT PaintMenuBackground(ThemeName theme, - HDC hdc, - int part_id, - int state_id, - RECT* rect) const; - - HRESULT PaintMenuCheck(ThemeName theme, - HDC hdc, - int part_id, - int state_id, - RECT* rect, - ControlState state) const; - - HRESULT PaintMenuCheckBackground(ThemeName theme, - HDC hdc, - int part_id, - int state_id, - RECT* rect) const; - - HRESULT PaintMenuGutter(HDC hdc, - int part_id, - int state_id, - RECT* rect) const; - - HRESULT PaintMenuItemBackground(ThemeName theme, - HDC hdc, - int part_id, - int state_id, - bool selected, - RECT* rect) const; - - HRESULT PaintMenuList(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect) const; - - HRESULT PaintMenuSeparator(HDC hdc, - int part_id, - int state_id, - RECT* rect) const; - - // Paints a scrollbar arrow. |classic_state| should have the appropriate - // classic part number ORed in already. - HRESULT PaintScrollbarArrow(HDC hdc, - int state_id, - int classic_state, - RECT* rect) const; - - // Paints a scrollbar track section. |align_rect| is only used in classic - // mode, and makes sure the checkerboard pattern in |target_rect| is aligned - // with one presumed to be in |align_rect|. - HRESULT PaintScrollbarTrack(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* target_rect, - RECT* align_rect, - skia::PlatformCanvas* canvas) const; - - // Paints a scrollbar thumb or gripper. - HRESULT PaintScrollbarThumb(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect) const; - - HRESULT PaintSpinButton(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect) const; - - HRESULT PaintStatusGripper(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect) const; - - HRESULT PaintTabPanelBackground(HDC dc, RECT* rect) const; - - HRESULT PaintTextField(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect, - COLORREF color, - bool fill_content_area, - bool draw_edges) const; - - HRESULT PaintTrackbar(HDC hdc, - int part_id, - int state_id, - int classic_state, - RECT* rect, - skia::PlatformCanvas* canvas) const; - - HRESULT PaintProgressBar(HDC hdc, - RECT* bar_rect, - RECT* value_rect, - bool determinate, - double animated_seconds, - skia::PlatformCanvas* canvas) const; - - bool IsThemingActive() const; - - HRESULT GetThemePartSize(ThemeName themeName, - HDC hdc, - int part_id, - int state_id, - RECT* rect, - int ts, - SIZE* size) const; - - HRESULT GetThemeColor(ThemeName theme, - int part_id, - int state_id, - int prop_id, - SkColor* color) const; - - // Get the theme color if theming is enabled. If theming is unsupported - // for this part, use Win32's GetSysColor to find the color specified - // by default_sys_color. - SkColor GetThemeColorWithDefault(ThemeName theme, - int part_id, - int state_id, - int prop_id, - int default_sys_color) const; - - HRESULT GetThemeInt(ThemeName theme, - int part_id, - int state_id, - int prop_id, - int *result) const; - - // Get the thickness of the border associated with the specified theme, - // defaulting to GetSystemMetrics edge size if themes are disabled. - // In Classic Windows, borders are typically 2px; on XP+, they are 1px. - Size GetThemeBorderSize(ThemeName theme) const; - - // Disables all theming for top-level windows in the entire process, from - // when this method is called until the process exits. All the other - // methods in this class will continue to work, but their output will ignore - // the user's theme. This is meant for use when running tests that require - // consistent visual results. - void DisableTheming() const; - - // Closes cached theme handles so we can unload the DLL or update our UI - // for a theme change. - void CloseHandles() const; - - // Returns true if classic theme is in use. - bool IsClassicTheme(ThemeName name) const; - - // Gets our singleton instance. - static const NativeTheme* instance(); - - private: - NativeTheme(); - ~NativeTheme(); - - HRESULT PaintFrameControl(HDC hdc, - RECT* rect, - UINT type, - UINT state, - ControlState control_state) const; - - // Returns a handle to the theme data. - HANDLE GetThemeHandle(ThemeName theme_name) const; - - // Function pointers into uxtheme.dll. - DrawThemeBackgroundPtr draw_theme_; - DrawThemeBackgroundExPtr draw_theme_ex_; - GetThemeColorPtr get_theme_color_; - GetThemeContentRectPtr get_theme_content_rect_; - GetThemePartSizePtr get_theme_part_size_; - OpenThemeDataPtr open_theme_; - CloseThemeDataPtr close_theme_; - SetThemeAppPropertiesPtr set_theme_properties_; - IsThemeActivePtr is_theme_active_; - GetThemeIntPtr get_theme_int_; - - // Handle to uxtheme.dll. - HMODULE theme_dll_; - - // A cache of open theme handles. - mutable HANDLE theme_handles_[LAST]; - - DISALLOW_COPY_AND_ASSIGN(NativeTheme); -}; - -} // namespace gfx +#include "ui/gfx/native_theme_win.h" +// TODO(sail): remove this file once all includes have been updated. #endif // APP_GFX_NATIVE_THEME_WIN_H_ diff --git a/gfx/native_theme_win_unittest.cc b/gfx/native_theme_win_unittest.cc deleted file mode 100644 index b087da6..0000000 --- a/gfx/native_theme_win_unittest.cc +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/native_theme_win.h" - -#include "testing/gtest/include/gtest/gtest.h" - -TEST(NativeThemeTest, Init) { - ASSERT_TRUE(gfx::NativeTheme::instance() != NULL); -} diff --git a/gfx/native_widget_types.h b/gfx/native_widget_types.h index 89b091b..f8ff236 100644 --- a/gfx/native_widget_types.h +++ b/gfx/native_widget_types.h @@ -6,171 +6,7 @@ #define GFX_NATIVE_WIDGET_TYPES_H_ #pragma once -#include "base/basictypes.h" -#include "build/build_config.h" - -// This file provides cross platform typedefs for native widget types. -// NativeWindow: this is a handle to a native, top-level window -// NativeView: this is a handle to a native UI element. It may be the -// same type as a NativeWindow on some platforms. -// NativeViewId: Often, in our cross process model, we need to pass around a -// reference to a "window". This reference will, say, be echoed back from a -// renderer to the browser when it wishes to query its size. On Windows we -// use an HWND for this. -// -// As a rule of thumb - if you're in the renderer, you should be dealing -// with NativeViewIds. This should remind you that you shouldn't be doing -// direct operations on platform widgets from the renderer process. -// -// If you're in the browser, you're probably dealing with NativeViews, -// unless you're in the IPC layer, which will be translating between -// NativeViewIds from the renderer and NativeViews. -// -// NativeEditView: a handle to a native edit-box. The Mac folks wanted this -// specific typedef. -// -// NativeImage: The platform-specific image type used for drawing UI elements -// in the browser. -// -// The name 'View' here meshes with OS X where the UI elements are called -// 'views' and with our Chrome UI code where the elements are also called -// 'views'. - -#if defined(OS_WIN) -#include <windows.h> // NOLINT -typedef struct HFONT__* HFONT; -#elif defined(OS_MACOSX) -struct CGContext; -#ifdef __OBJC__ -@class NSFont; -@class NSImage; -@class NSView; -@class NSWindow; -@class NSTextField; -#else -class NSFont; -class NSImage; -class NSView; -class NSWindow; -class NSTextField; -#endif // __OBJC__ -#elif defined(TOOLKIT_USES_GTK) -typedef struct _PangoFontDescription PangoFontDescription; -typedef struct _GdkCursor GdkCursor; -typedef struct _GdkPixbuf GdkPixbuf; -typedef struct _GdkRegion GdkRegion; -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; -typedef struct _cairo cairo_t; -#endif -class SkBitmap; - -namespace gfx { - -#if defined(OS_WIN) -typedef HFONT NativeFont; -typedef HWND NativeView; -typedef HWND NativeWindow; -typedef HWND NativeEditView; -typedef HDC NativeDrawingContext; -typedef HCURSOR NativeCursor; -typedef HMENU NativeMenu; -typedef HRGN NativeRegion; -#elif defined(OS_MACOSX) -typedef NSFont* NativeFont; -typedef NSView* NativeView; -typedef NSWindow* NativeWindow; -typedef NSTextField* NativeEditView; -typedef CGContext* NativeDrawingContext; -typedef void* NativeCursor; -typedef void* NativeMenu; -#elif defined(USE_X11) -typedef PangoFontDescription* NativeFont; -typedef GtkWidget* NativeView; -typedef GtkWindow* NativeWindow; -typedef GtkWidget* NativeEditView; -typedef cairo_t* NativeDrawingContext; -typedef GdkCursor* NativeCursor; -typedef GtkWidget* NativeMenu; -typedef GdkRegion* NativeRegion; -#endif - -#if defined(OS_MACOSX) -typedef NSImage NativeImageType; -#elif defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) -typedef GdkPixbuf NativeImageType; -#else -typedef SkBitmap NativeImageType; -#endif -typedef NativeImageType* NativeImage; - -// Note: for test_shell we're packing a pointer into the NativeViewId. So, if -// you make it a type which is smaller than a pointer, you have to fix -// test_shell. -// -// See comment at the top of the file for usage. -typedef intptr_t NativeViewId; - -#if defined(OS_WIN) -// Convert a NativeViewId to a NativeView. -// -// On Windows, we pass an HWND into the renderer. As stated above, the renderer -// should not be performing operations on the view. -static inline NativeView NativeViewFromId(NativeViewId id) { - return reinterpret_cast<NativeView>(id); -} -#define NativeViewFromIdInBrowser(x) NativeViewFromId(x) -#elif defined(OS_POSIX) -// On Mac and Linux, a NativeView is a pointer to an object, and is useless -// outside the process in which it was created. NativeViewFromId should only be -// used inside the appropriate platform ifdef outside of the browser. -// (NativeViewFromIdInBrowser can be used everywhere in the browser.) If your -// cross-platform design involves a call to NativeViewFromId from outside the -// browser it will never work on Mac or Linux and is fundamentally broken. - -// Please do not call this from outside the browser. It won't work; the name -// should give you a subtle hint. -static inline NativeView NativeViewFromIdInBrowser(NativeViewId id) { - return reinterpret_cast<NativeView>(id); -} -#endif // defined(OS_POSIX) - -// Convert a NativeView to a NativeViewId. See the comments at the top of -// this file. -#if defined(OS_WIN) || defined(OS_MACOSX) -static inline NativeViewId IdFromNativeView(NativeView view) { - return reinterpret_cast<NativeViewId>(view); -} -#elif defined(USE_X11) -// Not inlined because it involves pulling too many headers. -NativeViewId IdFromNativeView(NativeView view); -#endif // defined(USE_X11) - - -// PluginWindowHandle is an abstraction wrapping "the types of windows -// used by NPAPI plugins". On Windows it's an HWND, on X it's an X -// window id. -#if defined(OS_WIN) - typedef HWND PluginWindowHandle; - const PluginWindowHandle kNullPluginWindow = NULL; -#elif defined(USE_X11) - typedef unsigned long PluginWindowHandle; - const PluginWindowHandle kNullPluginWindow = 0; -#else - // On OS X we don't have windowed plugins. - // We use a NULL/0 PluginWindowHandle in shared code to indicate there - // is no window present, so mirror that behavior here. - // - // The GPU plugin is currently an exception to this rule. As of this - // writing it uses some NPAPI infrastructure, and minimally we need - // to identify the plugin instance via this window handle. When the - // GPU plugin becomes a full-on GPU process, this typedef can be - // returned to a bool. For now we use a type large enough to hold a - // pointer on 64-bit architectures in case we need this capability. - typedef uint64 PluginWindowHandle; - const PluginWindowHandle kNullPluginWindow = 0; -#endif - -} // namespace gfx +#include "ui/gfx/native_widget_types.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_NATIVE_WIDGET_TYPES_H_ diff --git a/gfx/native_widget_types_gtk.cc b/gfx/native_widget_types_gtk.cc deleted file mode 100644 index ccf428c..0000000 --- a/gfx/native_widget_types_gtk.cc +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/native_widget_types.h" - -#include "gfx/gtk_native_view_id_manager.h" - -namespace gfx { - -NativeViewId IdFromNativeView(NativeView view) { - return GtkNativeViewManager::GetInstance()->GetIdForWidget(view); -} - -} // namespace gfx diff --git a/gfx/path.cc b/gfx/path.cc deleted file mode 100644 index e456679..0000000 --- a/gfx/path.cc +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/path.h" - -#include "base/logging.h" - -namespace gfx { - -Path::Path() - : SkPath() { - moveTo(0, 0); -} - -Path::Path(const Point* points, size_t count) { - DCHECK(count > 1); - moveTo(SkIntToScalar(points[0].x), SkIntToScalar(points[0].y)); - for (size_t i = 1; i < count; ++i) - lineTo(SkIntToScalar(points[i].x), SkIntToScalar(points[i].y)); -} - -Path::~Path() { -} - -} // namespace gfx @@ -6,52 +6,7 @@ #define GFX_PATH_H_ #pragma once -#include "base/basictypes.h" -#include "gfx/native_widget_types.h" - -#include "third_party/skia/include/core/SkPath.h" - -namespace gfx { - -class Path : public SkPath { - public: - // Used by Path(Point,size_t) constructor. - struct Point { - int x; - int y; - }; - - Path(); - - // Creates a path populated with the specified points. - Path(const Point* points, size_t count); - - ~Path(); - -#if defined(OS_WIN) || defined(USE_X11) - // Creates a NativeRegion from the path. The caller is responsible for freeing - // resources used by this region. This only supports polygon paths. - NativeRegion CreateNativeRegion() const; - - // Returns the intersection of the two regions. The caller owns the returned - // object. - static gfx::NativeRegion IntersectRegions(gfx::NativeRegion r1, - gfx::NativeRegion r2); - - // Returns the union of the two regions. The caller owns the returned object. - static gfx::NativeRegion CombineRegions(gfx::NativeRegion r1, - gfx::NativeRegion r2); - - // Returns the difference of the two regions. The caller owns the returned - // object. - static gfx::NativeRegion SubtractRegion(gfx::NativeRegion r1, - gfx::NativeRegion r2); -#endif - - private: - DISALLOW_COPY_AND_ASSIGN(Path); -}; - -} +#include "ui/gfx/path.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_PATH_H_ diff --git a/gfx/path_gtk.cc b/gfx/path_gtk.cc deleted file mode 100644 index 2149aad..0000000 --- a/gfx/path_gtk.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/path.h" - -#include <gdk/gdk.h> - -#include "base/scoped_ptr.h" -#include "base/command_line.h" - -namespace gfx { - -GdkRegion* Path::CreateNativeRegion() const { - int point_count = getPoints(NULL, 0); - if (point_count <= 1) { - // NOTE: ideally this would return gdk_empty_region, but that returns a - // region with nothing in it. - return NULL; - } - - scoped_array<SkPoint> points(new SkPoint[point_count]); - getPoints(points.get(), point_count); - - scoped_array<GdkPoint> gdk_points(new GdkPoint[point_count]); - for (int i = 0; i < point_count; ++i) { - gdk_points[i].x = SkScalarRound(points[i].fX); - gdk_points[i].y = SkScalarRound(points[i].fY); - } - - return gdk_region_polygon(gdk_points.get(), point_count, GDK_EVEN_ODD_RULE); -} - -// static -NativeRegion Path::IntersectRegions(NativeRegion r1, NativeRegion r2) { - GdkRegion* copy = gdk_region_copy(r1); - gdk_region_intersect(copy, r2); - return copy; -} - -// static -NativeRegion Path::CombineRegions(NativeRegion r1, NativeRegion r2) { - GdkRegion* copy = gdk_region_copy(r1); - gdk_region_union(copy, r2); - return copy; -} - -// static -NativeRegion Path::SubtractRegion(NativeRegion r1, NativeRegion r2) { - GdkRegion* copy = gdk_region_copy(r1); - gdk_region_subtract(copy, r2); - return copy; -} - -} // namespace gfx diff --git a/gfx/path_win.cc b/gfx/path_win.cc deleted file mode 100644 index b5f206c..0000000 --- a/gfx/path_win.cc +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/path.h" - -#include "base/scoped_ptr.h" - -namespace gfx { - -HRGN Path::CreateNativeRegion() const { - int point_count = getPoints(NULL, 0); - scoped_array<SkPoint> points(new SkPoint[point_count]); - getPoints(points.get(), point_count); - scoped_array<POINT> windows_points(new POINT[point_count]); - for (int i = 0; i < point_count; ++i) { - windows_points[i].x = SkScalarRound(points[i].fX); - windows_points[i].y = SkScalarRound(points[i].fY); - } - - return ::CreatePolygonRgn(windows_points.get(), point_count, ALTERNATE); -} - -// static -NativeRegion Path::IntersectRegions(NativeRegion r1, NativeRegion r2) { - HRGN dest = CreateRectRgn(0, 0, 1, 1); - CombineRgn(dest, r1, r2, RGN_AND); - return dest; -} - -// static -NativeRegion Path::CombineRegions(NativeRegion r1, NativeRegion r2) { - HRGN dest = CreateRectRgn(0, 0, 1, 1); - CombineRgn(dest, r1, r2, RGN_OR); - return dest; -} - -// static -NativeRegion Path::SubtractRegion(NativeRegion r1, NativeRegion r2) { - HRGN dest = CreateRectRgn(0, 0, 1, 1); - CombineRgn(dest, r1, r2, RGN_DIFF); - return dest; -} - -} // namespace gfx diff --git a/gfx/platform_font.h b/gfx/platform_font.h index 412e260..2a88fff 100644 --- a/gfx/platform_font.h +++ b/gfx/platform_font.h @@ -6,74 +6,8 @@ #define GFX_PLATFORM_FONT_ #pragma once -#include <string> - -#include "base/ref_counted.h" -#include "base/string16.h" -#include "gfx/native_widget_types.h" - -namespace gfx { - -class Font; - -class PlatformFont : public base::RefCounted<PlatformFont> { - public: - // Create an appropriate PlatformFont implementation. - static PlatformFont* CreateDefault(); - static PlatformFont* CreateFromFont(const Font& other); - static PlatformFont* CreateFromNativeFont(NativeFont native_font); - static PlatformFont* CreateFromNameAndSize(const string16& font_name, - int font_size); - - // Returns a new Font derived from the existing font. - // size_delta is the size to add to the current font. See the single - // argument version of this method for an example. - // The style parameter specifies the new style for the font, and is a - // bitmask of the values: BOLD, ITALIC and UNDERLINED. - virtual Font DeriveFont(int size_delta, int style) const = 0; - - // Returns the number of vertical pixels needed to display characters from - // the specified font. This may include some leading, i.e. height may be - // greater than just ascent + descent. Specifically, the Windows and Mac - // implementations include leading and the Linux one does not. This may - // need to be revisited in the future. - virtual int GetHeight() const = 0; - - // Returns the baseline, or ascent, of the font. - virtual int GetBaseline() const = 0; - - // Returns the average character width for the font. - virtual int GetAverageCharacterWidth() const = 0; - - // Returns the number of horizontal pixels needed to display the specified - // string. - virtual int GetStringWidth(const string16& text) const = 0; - - // Returns the expected number of horizontal pixels needed to display the - // specified length of characters. Call GetStringWidth() to retrieve the - // actual number. - virtual int GetExpectedTextWidth(int length) const = 0; - - // Returns the style of the font. - virtual int GetStyle() const = 0; - - // Returns the font name. - virtual string16 GetFontName() const = 0; - - // Returns the font size in pixels. - virtual int GetFontSize() const = 0; - - // Returns the native font handle. - virtual NativeFont GetNativeFont() const = 0; - - protected: - virtual ~PlatformFont() {} - - private: - friend class base::RefCounted<PlatformFont>; -}; - -} // namespace gfx +#include "ui/gfx/platform_font.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_PLATFORM_FONT_ diff --git a/gfx/platform_font_gtk.cc b/gfx/platform_font_gtk.cc deleted file mode 100644 index 82b2e06..0000000 --- a/gfx/platform_font_gtk.cc +++ /dev/null @@ -1,450 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/platform_font_gtk.h" - -#include <algorithm> -#include <fontconfig/fontconfig.h> -#include <gdk/gdk.h> -#include <gtk/gtk.h> -#include <map> -#include <pango/pango.h> - -#include "base/logging.h" -#include "base/string_piece.h" -#include "base/utf_string_conversions.h" -#include "gfx/canvas_skia.h" -#include "gfx/font.h" -#include "gfx/gtk_util.h" -#include "third_party/skia/include/core/SkTypeface.h" -#include "third_party/skia/include/core/SkPaint.h" - -namespace { - -// The font family name which is used when a user's application font for -// GNOME/KDE is a non-scalable one. The name should be listed in the -// IsFallbackFontAllowed function in skia/ext/SkFontHost_fontconfig_direct.cpp. -const char* kFallbackFontFamilyName = "sans"; - -// Returns the number of pixels in a point. -// - multiply a point size by this to get pixels ("device units") -// - divide a pixel size by this to get points -float GetPixelsInPoint() { - static float pixels_in_point = 1.0; - static bool determined_value = false; - - if (!determined_value) { - // http://goo.gl/UIh5m: "This is a scale factor between points specified in - // a PangoFontDescription and Cairo units. The default value is 96, meaning - // that a 10 point font will be 13 units high. (10 * 96. / 72. = 13.3)." - double pango_dpi = gfx::GetPangoResolution(); - if (pango_dpi <= 0) - pango_dpi = 96.0; - pixels_in_point = pango_dpi / 72.0; // 72 points in an inch - determined_value = true; - } - - return pixels_in_point; -} - -// Retrieves the pango metrics for a pango font description. Caches the metrics -// and never frees them. The metrics objects are relatively small and -// very expensive to look up. -PangoFontMetrics* GetPangoFontMetrics(PangoFontDescription* desc) { - static std::map<int, PangoFontMetrics*>* desc_to_metrics = NULL; - static PangoContext* context = NULL; - - if (!context) { - context = gdk_pango_context_get_for_screen(gdk_screen_get_default()); - pango_context_set_language(context, pango_language_get_default()); - } - - if (!desc_to_metrics) { - desc_to_metrics = new std::map<int, PangoFontMetrics*>(); - } - - int desc_hash = pango_font_description_hash(desc); - std::map<int, PangoFontMetrics*>::iterator i = - desc_to_metrics->find(desc_hash); - - if (i == desc_to_metrics->end()) { - PangoFontMetrics* metrics = pango_context_get_metrics(context, desc, NULL); - (*desc_to_metrics)[desc_hash] = metrics; - return metrics; - } else { - return i->second; - } -} - -// Find the best match font for |family_name| in the same way as Skia -// to make sure CreateFont() successfully creates a default font. In -// Skia, it only checks the best match font. If it failed to find -// one, SkTypeface will be NULL for that font family. It eventually -// causes a segfault. For example, family_name = "Sans" and system -// may have various fonts. The first font family in FcPattern will be -// "DejaVu Sans" but a font family returned by FcFontMatch will be "VL -// PGothic". In this case, SkTypeface for "Sans" returns NULL even if -// the system has a font for "Sans" font family. See FontMatch() in -// skia/ports/SkFontHost_fontconfig.cpp for more detail. -string16 FindBestMatchFontFamilyName(const char* family_name) { - FcPattern* pattern = FcPatternCreate(); - FcValue fcvalue; - fcvalue.type = FcTypeString; - char* family_name_copy = strdup(family_name); - fcvalue.u.s = reinterpret_cast<FcChar8*>(family_name_copy); - FcPatternAdd(pattern, FC_FAMILY, fcvalue, 0); - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - FcResult result; - FcPattern* match = FcFontMatch(0, pattern, &result); - DCHECK(match) << "Could not find font: " << family_name; - FcChar8* match_family; - FcPatternGetString(match, FC_FAMILY, 0, &match_family); - - string16 font_family = UTF8ToUTF16(reinterpret_cast<char*>(match_family)); - FcPatternDestroy(match); - FcPatternDestroy(pattern); - free(family_name_copy); - return font_family; -} - -} // namespace - -namespace gfx { - -Font* PlatformFontGtk::default_font_ = NULL; - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFontGtk, public: - -PlatformFontGtk::PlatformFontGtk() { - if (default_font_ == NULL) { - GtkSettings* settings = gtk_settings_get_default(); - - gchar* font_name = NULL; - g_object_get(settings, "gtk-font-name", &font_name, NULL); - - // Temporary CHECK for helping track down - // http://code.google.com/p/chromium/issues/detail?id=12530 - CHECK(font_name) << " Unable to get gtk-font-name for default font."; - - PangoFontDescription* desc = - pango_font_description_from_string(font_name); - default_font_ = new Font(desc); - pango_font_description_free(desc); - g_free(font_name); - - DCHECK(default_font_); - } - - InitFromPlatformFont( - static_cast<PlatformFontGtk*>(default_font_->platform_font())); -} - -PlatformFontGtk::PlatformFontGtk(const Font& other) { - InitFromPlatformFont( - static_cast<PlatformFontGtk*>(other.platform_font())); -} - -PlatformFontGtk::PlatformFontGtk(NativeFont native_font) { - const char* family_name = pango_font_description_get_family(native_font); - - gint size_in_pixels = 0; - if (pango_font_description_get_size_is_absolute(native_font)) { - // If the size is absolute, then it's in Pango units rather than points. - // There are PANGO_SCALE Pango units in a device unit (pixel). - size_in_pixels = pango_font_description_get_size(native_font) / PANGO_SCALE; - } else { - // Otherwise, we need to convert from points. - size_in_pixels = - pango_font_description_get_size(native_font) * GetPixelsInPoint() / - PANGO_SCALE; - } - - // Find best match font for |family_name| to make sure we can get - // a SkTypeface for the default font. - // TODO(agl): remove this. - string16 font_family = FindBestMatchFontFamilyName(family_name); - - InitWithNameAndSize(font_family, size_in_pixels); - int style = 0; - if (pango_font_description_get_weight(native_font) == PANGO_WEIGHT_BOLD) { - // TODO(davemoore) What should we do about other weights? We currently - // only support BOLD. - style |= gfx::Font::BOLD; - } - if (pango_font_description_get_style(native_font) == PANGO_STYLE_ITALIC) { - // TODO(davemoore) What about PANGO_STYLE_OBLIQUE? - style |= gfx::Font::ITALIC; - } - if (style != 0) - style_ = style; -} - -PlatformFontGtk::PlatformFontGtk(const string16& font_name, - int font_size) { - InitWithNameAndSize(font_name, font_size); -} - -double PlatformFontGtk::underline_position() const { - const_cast<PlatformFontGtk*>(this)->InitPangoMetrics(); - return underline_position_pixels_; -} - -double PlatformFontGtk::underline_thickness() const { - const_cast<PlatformFontGtk*>(this)->InitPangoMetrics(); - return underline_thickness_pixels_; -} - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFontGtk, PlatformFont implementation: - -Font PlatformFontGtk::DeriveFont(int size_delta, int style) const { - // If the delta is negative, if must not push the size below 1 - if (size_delta < 0) - DCHECK_LT(-size_delta, font_size_pixels_); - - if (style == style_) { - // Fast path, we just use the same typeface at a different size - return Font(new PlatformFontGtk(typeface_, - font_family_, - font_size_pixels_ + size_delta, - style_)); - } - - // If the style has changed we may need to load a new face - int skstyle = SkTypeface::kNormal; - if (gfx::Font::BOLD & style) - skstyle |= SkTypeface::kBold; - if (gfx::Font::ITALIC & style) - skstyle |= SkTypeface::kItalic; - - SkTypeface* typeface = SkTypeface::CreateFromName( - UTF16ToUTF8(font_family_).c_str(), - static_cast<SkTypeface::Style>(skstyle)); - SkAutoUnref tf_helper(typeface); - - return Font(new PlatformFontGtk(typeface, - font_family_, - font_size_pixels_ + size_delta, - style)); -} - -int PlatformFontGtk::GetHeight() const { - return height_pixels_; -} - -int PlatformFontGtk::GetBaseline() const { - return ascent_pixels_; -} - -int PlatformFontGtk::GetAverageCharacterWidth() const { - return SkScalarRound(average_width_pixels_); -} - -int PlatformFontGtk::GetStringWidth(const string16& text) const { - int width = 0, height = 0; - CanvasSkia::SizeStringInt(text, Font(const_cast<PlatformFontGtk*>(this)), - &width, &height, gfx::Canvas::NO_ELLIPSIS); - return width; -} - -int PlatformFontGtk::GetExpectedTextWidth(int length) const { - double char_width = const_cast<PlatformFontGtk*>(this)->GetAverageWidth(); - return round(static_cast<float>(length) * char_width); -} - -int PlatformFontGtk::GetStyle() const { - return style_; -} - -string16 PlatformFontGtk::GetFontName() const { - return font_family_; -} - -int PlatformFontGtk::GetFontSize() const { - return font_size_pixels_; -} - -NativeFont PlatformFontGtk::GetNativeFont() const { - PangoFontDescription* pfd = pango_font_description_new(); - pango_font_description_set_family(pfd, UTF16ToUTF8(GetFontName()).c_str()); - // Set the absolute size to avoid overflowing UI elements. - // pango_font_description_set_absolute_size() takes a size in Pango units. - // There are PANGO_SCALE Pango units in one device unit. Screen output - // devices use pixels as their device units. - pango_font_description_set_absolute_size( - pfd, font_size_pixels_ * PANGO_SCALE); - - switch (GetStyle()) { - case gfx::Font::NORMAL: - // Nothing to do, should already be PANGO_STYLE_NORMAL. - break; - case gfx::Font::BOLD: - pango_font_description_set_weight(pfd, PANGO_WEIGHT_BOLD); - break; - case gfx::Font::ITALIC: - pango_font_description_set_style(pfd, PANGO_STYLE_ITALIC); - break; - case gfx::Font::UNDERLINED: - // TODO(deanm): How to do underlined? Where do we use it? Probably have - // to paint it ourselves, see pango_font_metrics_get_underline_position. - break; - } - - return pfd; -} - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFontGtk, private: - -PlatformFontGtk::PlatformFontGtk(SkTypeface* typeface, - const string16& name, - int size, - int style) { - InitWithTypefaceNameSizeAndStyle(typeface, name, size, style); -} - -PlatformFontGtk::~PlatformFontGtk() {} - -void PlatformFontGtk::InitWithNameAndSize(const string16& font_name, - int font_size) { - DCHECK_GT(font_size, 0); - string16 fallback; - - SkTypeface* typeface = SkTypeface::CreateFromName( - UTF16ToUTF8(font_name).c_str(), SkTypeface::kNormal); - if (!typeface) { - // A non-scalable font such as .pcf is specified. Falls back to a default - // scalable font. - typeface = SkTypeface::CreateFromName( - kFallbackFontFamilyName, SkTypeface::kNormal); - CHECK(typeface) << "Could not find any font: " - << UTF16ToUTF8(font_name) - << ", " << kFallbackFontFamilyName; - fallback = UTF8ToUTF16(kFallbackFontFamilyName); - } - SkAutoUnref typeface_helper(typeface); - - InitWithTypefaceNameSizeAndStyle(typeface, - fallback.empty() ? font_name : fallback, - font_size, - gfx::Font::NORMAL); -} - -void PlatformFontGtk::InitWithTypefaceNameSizeAndStyle( - SkTypeface* typeface, - const string16& font_family, - int font_size, - int style) { - typeface_helper_.reset(new SkAutoUnref(typeface)); - typeface_ = typeface; - typeface_->ref(); - font_family_ = font_family; - font_size_pixels_ = font_size; - style_ = style; - pango_metrics_inited_ = false; - average_width_pixels_ = 0.0f; - underline_position_pixels_ = 0.0f; - underline_thickness_pixels_ = 0.0f; - - SkPaint paint; - SkPaint::FontMetrics metrics; - PaintSetup(&paint); - paint.getFontMetrics(&metrics); - - ascent_pixels_ = SkScalarCeil(-metrics.fAscent); - height_pixels_ = ascent_pixels_ + SkScalarCeil(metrics.fDescent); -} - -void PlatformFontGtk::InitFromPlatformFont(const PlatformFontGtk* other) { - typeface_helper_.reset(new SkAutoUnref(other->typeface_)); - typeface_ = other->typeface_; - typeface_->ref(); - font_family_ = other->font_family_; - font_size_pixels_ = other->font_size_pixels_; - style_ = other->style_; - height_pixels_ = other->height_pixels_; - ascent_pixels_ = other->ascent_pixels_; - pango_metrics_inited_ = other->pango_metrics_inited_; - average_width_pixels_ = other->average_width_pixels_; - underline_position_pixels_ = other->underline_position_pixels_; - underline_thickness_pixels_ = other->underline_thickness_pixels_; -} - -void PlatformFontGtk::PaintSetup(SkPaint* paint) const { - paint->setAntiAlias(false); - paint->setSubpixelText(false); - paint->setTextSize(font_size_pixels_); - paint->setTypeface(typeface_); - paint->setFakeBoldText((gfx::Font::BOLD & style_) && !typeface_->isBold()); - paint->setTextSkewX((gfx::Font::ITALIC & style_) && !typeface_->isItalic() ? - -SK_Scalar1/4 : 0); -} - -void PlatformFontGtk::InitPangoMetrics() { - if (!pango_metrics_inited_) { - pango_metrics_inited_ = true; - PangoFontDescription* pango_desc = GetNativeFont(); - PangoFontMetrics* pango_metrics = GetPangoFontMetrics(pango_desc); - - underline_position_pixels_ = - pango_font_metrics_get_underline_position(pango_metrics) / - PANGO_SCALE; - - // TODO(davemoore): Come up with a better solution. - // This is a hack, but without doing this the underlines - // we get end up fuzzy. So we align to the midpoint of a pixel. - underline_position_pixels_ /= 2; - - underline_thickness_pixels_ = - pango_font_metrics_get_underline_thickness(pango_metrics) / - PANGO_SCALE; - - // First get the Pango-based width (converting from Pango units to pixels). - double pango_width_pixels = - pango_font_metrics_get_approximate_char_width(pango_metrics) / - PANGO_SCALE; - - // Yes, this is how Microsoft recommends calculating the dialog unit - // conversions. - int text_width_pixels = GetStringWidth( - ASCIIToUTF16("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); - double dialog_units_pixels = (text_width_pixels / 26 + 1) / 2; - average_width_pixels_ = std::min(pango_width_pixels, dialog_units_pixels); - pango_font_description_free(pango_desc); - } -} - - -double PlatformFontGtk::GetAverageWidth() const { - const_cast<PlatformFontGtk*>(this)->InitPangoMetrics(); - return average_width_pixels_; -} - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFont, public: - -// static -PlatformFont* PlatformFont::CreateDefault() { - return new PlatformFontGtk; -} - -// static -PlatformFont* PlatformFont::CreateFromFont(const Font& other) { - return new PlatformFontGtk(other); -} - -// static -PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) { - return new PlatformFontGtk(native_font); -} - -// static -PlatformFont* PlatformFont::CreateFromNameAndSize(const string16& font_name, - int font_size) { - return new PlatformFontGtk(font_name, font_size); -} - -} // namespace gfx diff --git a/gfx/platform_font_gtk.h b/gfx/platform_font_gtk.h index e69c24a..b87df6c 100644 --- a/gfx/platform_font_gtk.h +++ b/gfx/platform_font_gtk.h @@ -6,102 +6,7 @@ #define GFX_PLATFORM_FONT_GTK_ #pragma once -#include "base/scoped_ptr.h" -#include "gfx/platform_font.h" -#include "third_party/skia/include/core/SkRefCnt.h" - -class SkTypeface; -class SkPaint; - -namespace gfx { - -class PlatformFontGtk : public PlatformFont { - public: - PlatformFontGtk(); - explicit PlatformFontGtk(const Font& other); - explicit PlatformFontGtk(NativeFont native_font); - PlatformFontGtk(const string16& font_name, - int font_size); - - // Converts |gfx_font| to a new pango font. Free the returned font with - // pango_font_description_free(). - static PangoFontDescription* PangoFontFromGfxFont(const gfx::Font& gfx_font); - - // Position as an offset from the height of the drawn text, used to draw - // an underline. This is a negative number, so the underline would be - // drawn at y + height + underline_position; - double underline_position() const; - // The thickness to draw the underline. - double underline_thickness() const; - - // Overridden from PlatformFont: - virtual Font DeriveFont(int size_delta, int style) const; - virtual int GetHeight() const; - virtual int GetBaseline() const; - virtual int GetAverageCharacterWidth() const; - virtual int GetStringWidth(const string16& text) const; - virtual int GetExpectedTextWidth(int length) const; - virtual int GetStyle() const; - virtual string16 GetFontName() const; - virtual int GetFontSize() const; - virtual NativeFont GetNativeFont() const; - - private: - // Create a new instance of this object with the specified properties. Called - // from DeriveFont. - PlatformFontGtk(SkTypeface* typeface, - const string16& name, - int size, - int style); - virtual ~PlatformFontGtk(); - - // Initialize this object. - void InitWithNameAndSize(const string16& font_name, int font_size); - void InitWithTypefaceNameSizeAndStyle(SkTypeface* typeface, - const string16& name, - int size, - int style); - void InitFromPlatformFont(const PlatformFontGtk* other); - - // Potentially slow call to get pango metrics (average width, underline info). - void InitPangoMetrics(); - - // Setup a Skia context to use the current typeface - void PaintSetup(SkPaint* paint) const; - - // Make |this| a copy of |other|. - void CopyFont(const Font& other); - - // The average width of a character, initialized and cached if needed. - double GetAverageWidth() const; - - // These two both point to the same SkTypeface. We use the SkAutoUnref to - // handle the reference counting, but without @typeface_ we would have to - // cast the SkRefCnt from @typeface_helper_ every time. - scoped_ptr<SkAutoUnref> typeface_helper_; - SkTypeface *typeface_; - - // Additional information about the face - // Skia actually expects a family name and not a font name. - string16 font_family_; - int font_size_pixels_; - int style_; - - // Cached metrics, generated at construction - int height_pixels_; - int ascent_pixels_; - - // The pango metrics are much more expensive so we wait until we need them - // to compute them. - bool pango_metrics_inited_; - double average_width_pixels_; - double underline_position_pixels_; - double underline_thickness_pixels_; - - // The default font, used for the default constructor. - static Font* default_font_; -}; - -} // namespace gfx +#include "ui/gfx/platform_font_gtk.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_PLATFORM_FONT_GTK_ diff --git a/gfx/platform_font_mac.h b/gfx/platform_font_mac.h index 62f44b6..8f676d7 100644 --- a/gfx/platform_font_mac.h +++ b/gfx/platform_font_mac.h @@ -6,52 +6,7 @@ #define GFX_PLATFORM_FONT_MAC_ #pragma once -#include "gfx/platform_font.h" - -namespace gfx { - -class PlatformFontMac : public PlatformFont { - public: - PlatformFontMac(); - explicit PlatformFontMac(const Font& other); - explicit PlatformFontMac(NativeFont native_font); - PlatformFontMac(const string16& font_name, - int font_size); - - // Overridden from PlatformFont: - virtual Font DeriveFont(int size_delta, int style) const; - virtual int GetHeight() const; - virtual int GetBaseline() const; - virtual int GetAverageCharacterWidth() const; - virtual int GetStringWidth(const string16& text) const; - virtual int GetExpectedTextWidth(int length) const; - virtual int GetStyle() const; - virtual string16 GetFontName() const; - virtual int GetFontSize() const; - virtual NativeFont GetNativeFont() const; - - private: - PlatformFontMac(const string16& font_name, int font_size, int style); - virtual ~PlatformFontMac() {} - - // Initialize the object with the specified parameters. - void InitWithNameSizeAndStyle(const string16& font_name, - int font_size, - int style); - - // Calculate and cache the font metrics. - void CalculateMetrics(); - - string16 font_name_; - int font_size_; - int style_; - - // Cached metrics, generated at construction - int height_; - int ascent_; - int average_width_; -}; - -} // namespace gfx +#include "ui/gfx/platform_font_mac.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_PLATFORM_FONT_MAC_ diff --git a/gfx/platform_font_mac.mm b/gfx/platform_font_mac.mm deleted file mode 100644 index 4aa9b88..0000000 --- a/gfx/platform_font_mac.mm +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/platform_font_mac.h" - -#include <Cocoa/Cocoa.h> - -#include "base/basictypes.h" -#include "base/scoped_nsobject.h" -#include "base/sys_string_conversions.h" -#include "base/utf_string_conversions.h" -#include "gfx/canvas_skia.h" -#include "gfx/font.h" - -namespace gfx { - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFontMac, public: - -PlatformFontMac::PlatformFontMac() { - font_size_ = [NSFont systemFontSize]; - style_ = gfx::Font::NORMAL; - NSFont* system_font = [NSFont systemFontOfSize:font_size_]; - font_name_ = base::SysNSStringToUTF16([system_font fontName]); - CalculateMetrics(); -} - -PlatformFontMac::PlatformFontMac(const Font& other) { -} - -PlatformFontMac::PlatformFontMac(NativeFont native_font) { -} - -PlatformFontMac::PlatformFontMac(const string16& font_name, - int font_size) { - InitWithNameSizeAndStyle(font_name, font_size, gfx::Font::NORMAL); -} - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFontMac, PlatformFont implementation: - -Font PlatformFontMac::DeriveFont(int size_delta, int style) const { - return Font(new PlatformFontMac(font_name_, font_size_ + size_delta, style)); -} - -int PlatformFontMac::GetHeight() const { - return height_; -} - -int PlatformFontMac::GetBaseline() const { - return ascent_; -} - -int PlatformFontMac::GetAverageCharacterWidth() const { - return average_width_; -} - -int PlatformFontMac::GetStringWidth(const string16& text) const { - int width = 0, height = 0; - CanvasSkia::SizeStringInt(text, Font(const_cast<PlatformFontMac*>(this)), - &width, &height, gfx::Canvas::NO_ELLIPSIS); - return width; -} - -int PlatformFontMac::GetExpectedTextWidth(int length) const { - return length * average_width_; -} - -int PlatformFontMac::GetStyle() const { - return style_; -} - -string16 PlatformFontMac::GetFontName() const { - return font_name_; -} - -int PlatformFontMac::GetFontSize() const { - return font_size_; -} - -NativeFont PlatformFontMac::GetNativeFont() const { - // TODO(pinkerton): apply |style_| to font. http://crbug.com/34667 - // We could cache this, but then we'd have to conditionally change the - // dtor just for MacOS. Not sure if we want to/need to do that. - return [NSFont fontWithName:base::SysUTF16ToNSString(font_name_) - size:font_size_]; -} - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFontMac, private: - -PlatformFontMac::PlatformFontMac(const string16& font_name, - int font_size, - int style) { - InitWithNameSizeAndStyle(font_name, font_size, style); -} - -void PlatformFontMac::InitWithNameSizeAndStyle(const string16& font_name, - int font_size, - int style) { - font_name_ = font_name; - font_size_ = font_size; - style_ = style; - CalculateMetrics(); -} - -void PlatformFontMac::CalculateMetrics() { - NSFont* font = GetNativeFont(); - scoped_nsobject<NSLayoutManager> layout_manager( - [[NSLayoutManager alloc] init]); - height_ = [layout_manager defaultLineHeightForFont:font]; - ascent_ = [font ascender]; - average_width_ = - [font boundingRectForGlyph:[font glyphWithName:@"x"]].size.width; -} - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFont, public: - -// static -PlatformFont* PlatformFont::CreateDefault() { - return new PlatformFontMac; -} - -// static -PlatformFont* PlatformFont::CreateFromFont(const Font& other) { - return new PlatformFontMac(other); -} - -// static -PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) { - return new PlatformFontMac(native_font); -} - -// static -PlatformFont* PlatformFont::CreateFromNameAndSize(const string16& font_name, - int font_size) { - return new PlatformFontMac(font_name, font_size); -} - -} // namespace gfx - diff --git a/gfx/platform_font_win.cc b/gfx/platform_font_win.cc deleted file mode 100644 index 8071640..0000000 --- a/gfx/platform_font_win.cc +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/platform_font_win.h" - -#include <windows.h> -#include <math.h> - -#include <algorithm> - -#include "base/logging.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "base/win/win_util.h" -#include "gfx/canvas_skia.h" -#include "gfx/font.h" - -namespace { - -// If the tmWeight field of a TEXTMETRIC structure has a value >= this, the -// font is bold. -const int kTextMetricWeightBold = 700; - -// Returns either minimum font allowed for a current locale or -// lf_height + size_delta value. -int AdjustFontSize(int lf_height, int size_delta) { - if (lf_height < 0) { - lf_height -= size_delta; - } else { - lf_height += size_delta; - } - int min_font_size = 0; - if (gfx::PlatformFontWin::get_minimum_font_size_callback) - min_font_size = gfx::PlatformFontWin::get_minimum_font_size_callback(); - // Make sure lf_height is not smaller than allowed min font size for current - // locale. - if (abs(lf_height) < min_font_size) { - return lf_height < 0 ? -min_font_size : min_font_size; - } else { - return lf_height; - } -} - -} // namespace - -namespace gfx { - -// static -PlatformFontWin::HFontRef* PlatformFontWin::base_font_ref_; - -// static -PlatformFontWin::AdjustFontCallback - PlatformFontWin::adjust_font_callback = NULL; -PlatformFontWin::GetMinimumFontSizeCallback - PlatformFontWin::get_minimum_font_size_callback = NULL; - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFontWin, public - -PlatformFontWin::PlatformFontWin() : font_ref_(GetBaseFontRef()) { -} - -PlatformFontWin::PlatformFontWin(const Font& other) { - InitWithCopyOfHFONT(other.GetNativeFont()); -} - -PlatformFontWin::PlatformFontWin(NativeFont native_font) { - InitWithCopyOfHFONT(native_font); -} - -PlatformFontWin::PlatformFontWin(const string16& font_name, - int font_size) { - InitWithFontNameAndSize(font_name, font_size); -} - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFontWin, PlatformFont implementation: - -Font PlatformFontWin::DeriveFont(int size_delta, int style) const { - LOGFONT font_info; - GetObject(GetNativeFont(), sizeof(LOGFONT), &font_info); - font_info.lfHeight = AdjustFontSize(font_info.lfHeight, size_delta); - font_info.lfUnderline = - ((style & gfx::Font::UNDERLINED) == gfx::Font::UNDERLINED); - font_info.lfItalic = ((style & gfx::Font::ITALIC) == gfx::Font::ITALIC); - font_info.lfWeight = (style & gfx::Font::BOLD) ? FW_BOLD : FW_NORMAL; - - HFONT hfont = CreateFontIndirect(&font_info); - return Font(new PlatformFontWin(CreateHFontRef(hfont))); -} - -int PlatformFontWin::GetHeight() const { - return font_ref_->height(); -} - -int PlatformFontWin::GetBaseline() const { - return font_ref_->baseline(); -} - -int PlatformFontWin::GetAverageCharacterWidth() const { - return font_ref_->ave_char_width(); -} - -int PlatformFontWin::GetStringWidth(const string16& text) const { - int width = 0, height = 0; - CanvasSkia::SizeStringInt(text, Font(const_cast<PlatformFontWin*>(this)), - &width, &height, gfx::Canvas::NO_ELLIPSIS); - return width; -} - -int PlatformFontWin::GetExpectedTextWidth(int length) const { - return length * std::min(font_ref_->dlu_base_x(), GetAverageCharacterWidth()); -} - -int PlatformFontWin::GetStyle() const { - return font_ref_->style(); -} - -string16 PlatformFontWin::GetFontName() const { - return font_ref_->font_name(); -} - -int PlatformFontWin::GetFontSize() const { - LOGFONT font_info; - GetObject(font_ref_->hfont(), sizeof(LOGFONT), &font_info); - long lf_height = font_info.lfHeight; - HDC hdc = GetDC(NULL); - int device_caps = GetDeviceCaps(hdc, LOGPIXELSY); - int font_size = 0; - if (device_caps != 0) { - float font_size_float = -static_cast<float>(lf_height)*72/device_caps; - font_size = static_cast<int>(::ceil(font_size_float - 0.5)); - } - ReleaseDC(NULL, hdc); - return font_size; -} - -NativeFont PlatformFontWin::GetNativeFont() const { - return font_ref_->hfont(); -} - -//////////////////////////////////////////////////////////////////////////////// -// Font, private: - -void PlatformFontWin::InitWithCopyOfHFONT(HFONT hfont) { - DCHECK(hfont); - LOGFONT font_info; - GetObject(hfont, sizeof(LOGFONT), &font_info); - font_ref_ = CreateHFontRef(CreateFontIndirect(&font_info)); -} - -void PlatformFontWin::InitWithFontNameAndSize(const string16& font_name, - int font_size) { - HDC hdc = GetDC(NULL); - long lf_height = -MulDiv(font_size, GetDeviceCaps(hdc, LOGPIXELSY), 72); - ReleaseDC(NULL, hdc); - HFONT hf = ::CreateFont(lf_height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - font_name.c_str()); - font_ref_ = CreateHFontRef(hf); -} - -// static -PlatformFontWin::HFontRef* PlatformFontWin::GetBaseFontRef() { - if (base_font_ref_ == NULL) { - NONCLIENTMETRICS metrics; - base::win::GetNonClientMetrics(&metrics); - - if (adjust_font_callback) - adjust_font_callback(&metrics.lfMessageFont); - metrics.lfMessageFont.lfHeight = - AdjustFontSize(metrics.lfMessageFont.lfHeight, 0); - HFONT font = CreateFontIndirect(&metrics.lfMessageFont); - DLOG_ASSERT(font); - base_font_ref_ = PlatformFontWin::CreateHFontRef(font); - // base_font_ref_ is global, up the ref count so it's never deleted. - base_font_ref_->AddRef(); - } - return base_font_ref_; -} - -PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) { - TEXTMETRIC font_metrics; - HDC screen_dc = GetDC(NULL); - HFONT previous_font = static_cast<HFONT>(SelectObject(screen_dc, font)); - int last_map_mode = SetMapMode(screen_dc, MM_TEXT); - GetTextMetrics(screen_dc, &font_metrics); - // Yes, this is how Microsoft recommends calculating the dialog unit - // conversions. - SIZE ave_text_size; - GetTextExtentPoint32(screen_dc, - L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - 52, &ave_text_size); - const int dlu_base_x = (ave_text_size.cx / 26 + 1) / 2; - // To avoid the DC referencing font_handle_, select the previous font. - SelectObject(screen_dc, previous_font); - SetMapMode(screen_dc, last_map_mode); - ReleaseDC(NULL, screen_dc); - - const int height = std::max(1, static_cast<int>(font_metrics.tmHeight)); - const int baseline = std::max(1, static_cast<int>(font_metrics.tmAscent)); - const int ave_char_width = - std::max(1, static_cast<int>(font_metrics.tmAveCharWidth)); - int style = 0; - if (font_metrics.tmItalic) - style |= Font::ITALIC; - if (font_metrics.tmUnderlined) - style |= Font::UNDERLINED; - if (font_metrics.tmWeight >= kTextMetricWeightBold) - style |= Font::BOLD; - - return new HFontRef(font, height, baseline, ave_char_width, style, - dlu_base_x); -} - -PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) { -} - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFontWin::HFontRef: - -PlatformFontWin::HFontRef::HFontRef(HFONT hfont, - int height, - int baseline, - int ave_char_width, - int style, - int dlu_base_x) - : hfont_(hfont), - height_(height), - baseline_(baseline), - ave_char_width_(ave_char_width), - style_(style), - dlu_base_x_(dlu_base_x) { - DLOG_ASSERT(hfont); - - LOGFONT font_info; - GetObject(hfont_, sizeof(LOGFONT), &font_info); - font_name_ = string16(font_info.lfFaceName); -} - -PlatformFontWin::HFontRef::~HFontRef() { - DeleteObject(hfont_); -} - -//////////////////////////////////////////////////////////////////////////////// -// PlatformFont, public: - -// static -PlatformFont* PlatformFont::CreateDefault() { - return new PlatformFontWin; -} - -// static -PlatformFont* PlatformFont::CreateFromFont(const Font& other) { - return new PlatformFontWin(other); -} - -// static -PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) { - return new PlatformFontWin(native_font); -} - -// static -PlatformFont* PlatformFont::CreateFromNameAndSize(const string16& font_name, - int font_size) { - return new PlatformFontWin(font_name, font_size); -} - -} // namespace gfx diff --git a/gfx/platform_font_win.h b/gfx/platform_font_win.h index 4adaa38..b491e80 100644 --- a/gfx/platform_font_win.h +++ b/gfx/platform_font_win.h @@ -6,126 +6,7 @@ #define GFX_PLATFORM_FONT_WIN_ #pragma once -#include "base/ref_counted.h" -#include "gfx/platform_font.h" - -namespace gfx { - -class PlatformFontWin : public PlatformFont { - public: - PlatformFontWin(); - explicit PlatformFontWin(const Font& other); - explicit PlatformFontWin(NativeFont native_font); - PlatformFontWin(const string16& font_name, - int font_size); - - // Dialog units to pixels conversion. - // See http://support.microsoft.com/kb/145994 for details. - int horizontal_dlus_to_pixels(int dlus) const { - return dlus * font_ref_->dlu_base_x() / 4; - } - int vertical_dlus_to_pixels(int dlus) const { - return dlus * font_ref_->height() / 8; - } - - // Callback that returns the minimum height that should be used for - // gfx::Fonts. Optional. If not specified, the minimum font size is 0. - typedef int (*GetMinimumFontSizeCallback)(); - static GetMinimumFontSizeCallback get_minimum_font_size_callback; - - // Callback that adjusts a LOGFONT to meet suitability requirements of the - // embedding application. Optional. If not specified, no adjustments are - // performed other than clamping to a minimum font height if - // |get_minimum_font_size_callback| is specified. - typedef void (*AdjustFontCallback)(LOGFONT* lf); - static AdjustFontCallback adjust_font_callback; - - // Overridden from PlatformFont: - virtual Font DeriveFont(int size_delta, int style) const; - virtual int GetHeight() const; - virtual int GetBaseline() const; - virtual int GetAverageCharacterWidth() const; - virtual int GetStringWidth(const string16& text) const; - virtual int GetExpectedTextWidth(int length) const; - virtual int GetStyle() const; - virtual string16 GetFontName() const; - virtual int GetFontSize() const; - virtual NativeFont GetNativeFont() const; - - private: - virtual ~PlatformFontWin() {} - - // Chrome text drawing bottoms out in the Windows GDI functions that take an - // HFONT (an opaque handle into Windows). To avoid lots of GDI object - // allocation and destruction, Font indirectly refers to the HFONT by way of - // an HFontRef. That is, every Font has an HFontRef, which has an HFONT. - // - // HFontRef is reference counted. Upon deletion, it deletes the HFONT. - // By making HFontRef maintain the reference to the HFONT, multiple - // HFontRefs can share the same HFONT, and Font can provide value semantics. - class HFontRef : public base::RefCounted<HFontRef> { - public: - // This constructor takes control of the HFONT, and will delete it when - // the HFontRef is deleted. - HFontRef(HFONT hfont, - int height, - int baseline, - int ave_char_width, - int style, - int dlu_base_x); - - // Accessors - HFONT hfont() const { return hfont_; } - int height() const { return height_; } - int baseline() const { return baseline_; } - int ave_char_width() const { return ave_char_width_; } - int style() const { return style_; } - int dlu_base_x() const { return dlu_base_x_; } - const string16& font_name() const { return font_name_; } - - private: - friend class base::RefCounted<HFontRef>; - - ~HFontRef(); - - const HFONT hfont_; - const int height_; - const int baseline_; - const int ave_char_width_; - const int style_; - // Constants used in converting dialog units to pixels. - const int dlu_base_x_; - string16 font_name_; - - DISALLOW_COPY_AND_ASSIGN(HFontRef); - }; - - // Initializes this object with a copy of the specified HFONT. - void InitWithCopyOfHFONT(HFONT hfont); - - // Initializes this object with the specified font name and size. - void InitWithFontNameAndSize(const string16& font_name, - int font_size); - - // Returns the base font ref. This should ONLY be invoked on the - // UI thread. - static HFontRef* GetBaseFontRef(); - - // Creates and returns a new HFONTRef from the specified HFONT. - static HFontRef* CreateHFontRef(HFONT font); - - // Creates a new PlatformFontWin with the specified HFontRef. Used when - // constructing a Font from a HFONT we don't want to copy. - explicit PlatformFontWin(HFontRef* hfont_ref); - - // Reference to the base font all fonts are derived from. - static HFontRef* base_font_ref_; - - // Indirect reference to the HFontRef, which references the underlying HFONT. - scoped_refptr<HFontRef> font_ref_; -}; - -} // namespace gfx +#include "ui/gfx/platform_font_win.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_PLATFORM_FONT_WIN_ - diff --git a/gfx/point.cc b/gfx/point.cc deleted file mode 100644 index d601580..0000000 --- a/gfx/point.cc +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/point.h" - -#if defined(OS_WIN) -#include <windows.h> -#endif - -#include <ostream> - -namespace gfx { - -Point::Point() : x_(0), y_(0) { -} - -Point::Point(int x, int y) : x_(x), y_(y) { -} - -#if defined(OS_WIN) -Point::Point(DWORD point) { - POINTS points = MAKEPOINTS(point); - x_ = points.x; - y_ = points.y; -} - -Point::Point(const POINT& point) : x_(point.x), y_(point.y) { -} - -Point& Point::operator=(const POINT& point) { - x_ = point.x; - y_ = point.y; - return *this; -} - -POINT Point::ToPOINT() const { - POINT p; - p.x = x_; - p.y = y_; - return p; -} -#elif defined(OS_MACOSX) -Point::Point(const CGPoint& point) : x_(point.x), y_(point.y) { -} - -CGPoint Point::ToCGPoint() const { - return CGPointMake(x_, y_); -} -#endif - -std::ostream& operator<<(std::ostream& out, const gfx::Point& p) { - return out << p.x() << "," << p.y(); -} - -} // namespace gfx diff --git a/gfx/point.h b/gfx/point.h index a2c10ad..ff313c7 100644 --- a/gfx/point.h +++ b/gfx/point.h @@ -6,96 +6,7 @@ #define GFX_POINT_H_ #pragma once -#include "build/build_config.h" - -#include <iosfwd> - -#if defined(OS_WIN) -typedef unsigned long DWORD; -typedef struct tagPOINT POINT; -#elif defined(OS_MACOSX) -#include <ApplicationServices/ApplicationServices.h> -#endif - -namespace gfx { - -// A point has an x and y coordinate. -class Point { - public: - Point(); - Point(int x, int y); -#if defined(OS_WIN) - // |point| is a DWORD value that contains a coordinate. The x-coordinate is - // the low-order short and the y-coordinate is the high-order short. This - // value is commonly acquired from GetMessagePos/GetCursorPos. - explicit Point(DWORD point); - explicit Point(const POINT& point); - Point& operator=(const POINT& point); -#elif defined(OS_MACOSX) - explicit Point(const CGPoint& point); -#endif - - ~Point() {} - - int x() const { return x_; } - int y() const { return y_; } - - void SetPoint(int x, int y) { - x_ = x; - y_ = y; - } - - void set_x(int x) { x_ = x; } - void set_y(int y) { y_ = y; } - - void Offset(int delta_x, int delta_y) { - x_ += delta_x; - y_ += delta_y; - } - - Point Add(const Point& other) const{ - Point copy = *this; - copy.Offset(other.x_, other.y_); - return copy; - } - - Point Subtract(const Point& other) const { - Point copy = *this; - copy.Offset(-other.x_, -other.y_); - return copy; - } - - bool operator==(const Point& rhs) const { - return x_ == rhs.x_ && y_ == rhs.y_; - } - - bool operator!=(const Point& rhs) const { - return !(*this == rhs); - } - - // A point is less than another point if its y-value is closer - // to the origin. If the y-values are the same, then point with - // the x-value closer to the origin is considered less than the - // other. - // This comparison is required to use Points in sets, or sorted - // vectors. - bool operator<(const Point& rhs) const { - return (y_ == rhs.y_) ? (x_ < rhs.x_) : (y_ < rhs.y_); - } - -#if defined(OS_WIN) - POINT ToPOINT() const; -#elif defined(OS_MACOSX) - CGPoint ToCGPoint() const; -#endif - - private: - int x_; - int y_; -}; - -std::ostream& operator<<(std::ostream& out, const gfx::Point& p); - -} // namespace gfx +#include "ui/gfx/point.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_POINT_H_ diff --git a/gfx/rect.cc b/gfx/rect.cc deleted file mode 100644 index a1a72cb..0000000 --- a/gfx/rect.cc +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/rect.h" - -#if defined(OS_WIN) -#include <windows.h> -#elif defined(OS_MACOSX) -#include <CoreGraphics/CGGeometry.h> -#elif defined(OS_POSIX) -#include <gdk/gdk.h> -#endif - -#include <ostream> - -#include "gfx/insets.h" - -namespace { - -void AdjustAlongAxis(int dst_origin, int dst_size, int* origin, int* size) { - if (*origin < dst_origin) { - *origin = dst_origin; - *size = std::min(dst_size, *size); - } else { - *size = std::min(dst_size, *size); - *origin = std::min(dst_origin + dst_size, *origin + *size) - *size; - } -} - -} // namespace - -namespace gfx { - -Rect::Rect() { -} - -Rect::Rect(int width, int height) - : size_(width, height) { -} - -Rect::Rect(int x, int y, int width, int height) - : origin_(x, y), size_(width, height) { -} - -Rect::Rect(const gfx::Size& size) - : size_(size) { -} - -Rect::Rect(const gfx::Point& origin, const gfx::Size& size) - : origin_(origin), size_(size) { -} - -#if defined(OS_WIN) -Rect::Rect(const RECT& r) - : origin_(r.left, r.top) { - set_width(r.right - r.left); - set_height(r.bottom - r.top); -} - -Rect& Rect::operator=(const RECT& r) { - origin_.SetPoint(r.left, r.top); - set_width(r.right - r.left); - set_height(r.bottom - r.top); - return *this; -} -#elif defined(OS_MACOSX) -Rect::Rect(const CGRect& r) - : origin_(r.origin.x, r.origin.y) { - set_width(r.size.width); - set_height(r.size.height); -} - -Rect& Rect::operator=(const CGRect& r) { - origin_.SetPoint(r.origin.x, r.origin.y); - set_width(r.size.width); - set_height(r.size.height); - return *this; -} -#elif defined(OS_POSIX) -Rect::Rect(const GdkRectangle& r) - : origin_(r.x, r.y) { - set_width(r.width); - set_height(r.height); -} - -Rect& Rect::operator=(const GdkRectangle& r) { - origin_.SetPoint(r.x, r.y); - set_width(r.width); - set_height(r.height); - return *this; -} -#endif - -void Rect::SetRect(int x, int y, int width, int height) { - origin_.SetPoint(x, y); - set_width(width); - set_height(height); -} - -void Rect::Inset(const gfx::Insets& insets) { - Inset(insets.left(), insets.top(), insets.right(), insets.bottom()); -} - -void Rect::Inset(int left, int top, int right, int bottom) { - Offset(left, top); - set_width(std::max(width() - left - right, 0)); - set_height(std::max(height() - top - bottom, 0)); -} - -void Rect::Offset(int horizontal, int vertical) { - origin_.Offset(horizontal, vertical); -} - -bool Rect::operator==(const Rect& other) const { - return origin_ == other.origin_ && size_ == other.size_; -} - -bool Rect::operator<(const Rect& other) const { - if (origin_ == other.origin_) { - if (width() == other.width()) { - return height() < other.height(); - } else { - return width() < other.width(); - } - } else { - return origin_ < other.origin_; - } -} - -#if defined(OS_WIN) -RECT Rect::ToRECT() const { - RECT r; - r.left = x(); - r.right = right(); - r.top = y(); - r.bottom = bottom(); - return r; -} -#elif defined(OS_MACOSX) -CGRect Rect::ToCGRect() const { - return CGRectMake(x(), y(), width(), height()); -} -#elif defined(OS_POSIX) -GdkRectangle Rect::ToGdkRectangle() const { - GdkRectangle r = {x(), y(), width(), height()}; - return r; -} -#endif - -bool Rect::Contains(int point_x, int point_y) const { - return (point_x >= x()) && (point_x < right()) && - (point_y >= y()) && (point_y < bottom()); -} - -bool Rect::Contains(const Rect& rect) const { - return (rect.x() >= x() && rect.right() <= right() && - rect.y() >= y() && rect.bottom() <= bottom()); -} - -bool Rect::Intersects(const Rect& rect) const { - return !(rect.x() >= right() || rect.right() <= x() || - rect.y() >= bottom() || rect.bottom() <= y()); -} - -Rect Rect::Intersect(const Rect& rect) const { - int rx = std::max(x(), rect.x()); - int ry = std::max(y(), rect.y()); - int rr = std::min(right(), rect.right()); - int rb = std::min(bottom(), rect.bottom()); - - if (rx >= rr || ry >= rb) - rx = ry = rr = rb = 0; // non-intersecting - - return Rect(rx, ry, rr - rx, rb - ry); -} - -Rect Rect::Union(const Rect& rect) const { - // special case empty rects... - if (IsEmpty()) - return rect; - if (rect.IsEmpty()) - return *this; - - int rx = std::min(x(), rect.x()); - int ry = std::min(y(), rect.y()); - int rr = std::max(right(), rect.right()); - int rb = std::max(bottom(), rect.bottom()); - - return Rect(rx, ry, rr - rx, rb - ry); -} - -Rect Rect::Subtract(const Rect& rect) const { - // boundary cases: - if (!Intersects(rect)) - return *this; - if (rect.Contains(*this)) - return Rect(); - - int rx = x(); - int ry = y(); - int rr = right(); - int rb = bottom(); - - if (rect.y() <= y() && rect.bottom() >= bottom()) { - // complete intersection in the y-direction - if (rect.x() <= x()) { - rx = rect.right(); - } else { - rr = rect.x(); - } - } else if (rect.x() <= x() && rect.right() >= right()) { - // complete intersection in the x-direction - if (rect.y() <= y()) { - ry = rect.bottom(); - } else { - rb = rect.y(); - } - } - return Rect(rx, ry, rr - rx, rb - ry); -} - -Rect Rect::AdjustToFit(const Rect& rect) const { - int new_x = x(); - int new_y = y(); - int new_width = width(); - int new_height = height(); - AdjustAlongAxis(rect.x(), rect.width(), &new_x, &new_width); - AdjustAlongAxis(rect.y(), rect.height(), &new_y, &new_height); - return Rect(new_x, new_y, new_width, new_height); -} - -Point Rect::CenterPoint() const { - return Point(x() + (width() + 1) / 2, y() + (height() + 1) / 2); -} - -Rect Rect::Center(const gfx::Size& size) const { - int new_width = std::min(width(), size.width()); - int new_height = std::min(height(), size.height()); - int new_x = x() + (width() - new_width) / 2; - int new_y = y() + (height() - new_height) / 2; - return Rect(new_x, new_y, new_width, new_height); -} - -bool Rect::SharesEdgeWith(const gfx::Rect& rect) const { - return (y() == rect.y() && height() == rect.height() && - (x() == rect.right() || right() == rect.x())) || - (x() == rect.x() && width() == rect.width() && - (y() == rect.bottom() || bottom() == rect.y())); -} - -std::ostream& operator<<(std::ostream& out, const gfx::Rect& r) { - return out << r.origin() << " " << r.size(); -} - -} // namespace gfx @@ -13,172 +13,7 @@ #define GFX_RECT_H_ #pragma once -#include <iosfwd> - -#include "gfx/point.h" -#include "gfx/size.h" - -#if defined(OS_WIN) -typedef struct tagRECT RECT; -#elif defined(USE_X11) -typedef struct _GdkRectangle GdkRectangle; -#endif - -namespace gfx { - -class Insets; - -class Rect { - public: - Rect(); - Rect(int width, int height); - Rect(int x, int y, int width, int height); -#if defined(OS_WIN) - explicit Rect(const RECT& r); -#elif defined(OS_MACOSX) - explicit Rect(const CGRect& r); -#elif defined(USE_X11) - explicit Rect(const GdkRectangle& r); -#endif - explicit Rect(const gfx::Size& size); - Rect(const gfx::Point& origin, const gfx::Size& size); - - ~Rect() {} - -#if defined(OS_WIN) - Rect& operator=(const RECT& r); -#elif defined(OS_MACOSX) - Rect& operator=(const CGRect& r); -#elif defined(USE_X11) - Rect& operator=(const GdkRectangle& r); -#endif - - int x() const { return origin_.x(); } - void set_x(int x) { origin_.set_x(x); } - - int y() const { return origin_.y(); } - void set_y(int y) { origin_.set_y(y); } - - int width() const { return size_.width(); } - void set_width(int width) { size_.set_width(width); } - - int height() const { return size_.height(); } - void set_height(int height) { size_.set_height(height); } - - const gfx::Point& origin() const { return origin_; } - void set_origin(const gfx::Point& origin) { origin_ = origin; } - - const gfx::Size& size() const { return size_; } - void set_size(const gfx::Size& size) { size_ = size; } - - int right() const { return x() + width(); } - int bottom() const { return y() + height(); } - - void SetRect(int x, int y, int width, int height); - - // Shrink the rectangle by a horizontal and vertical distance on all sides. - void Inset(int horizontal, int vertical) { - Inset(horizontal, vertical, horizontal, vertical); - } - - // Shrink the rectangle by the given insets. - void Inset(const gfx::Insets& insets); - - // Shrink the rectangle by the specified amount on each side. - void Inset(int left, int top, int right, int bottom); - - // Move the rectangle by a horizontal and vertical distance. - void Offset(int horizontal, int vertical); - void Offset(const gfx::Point& point) { - Offset(point.x(), point.y()); - } - - // Returns true if the area of the rectangle is zero. - bool IsEmpty() const { return size_.IsEmpty(); } - - bool operator==(const Rect& other) const; - - bool operator!=(const Rect& other) const { - return !(*this == other); - } - - // A rect is less than another rect if its origin is less than - // the other rect's origin. If the origins are equal, then the - // shortest rect is less than the other. If the origin and the - // height are equal, then the narrowest rect is less than. - // This comparison is required to use Rects in sets, or sorted - // vectors. - bool operator<(const Rect& other) const; - -#if defined(OS_WIN) - // Construct an equivalent Win32 RECT object. - RECT ToRECT() const; -#elif defined(USE_X11) - GdkRectangle ToGdkRectangle() const; -#elif defined(OS_MACOSX) - // Construct an equivalent CoreGraphics object. - CGRect ToCGRect() const; -#endif - - // Returns true if the point identified by point_x and point_y falls inside - // this rectangle. The point (x, y) is inside the rectangle, but the - // point (x + width, y + height) is not. - bool Contains(int point_x, int point_y) const; - - // Returns true if the specified point is contained by this rectangle. - bool Contains(const gfx::Point& point) const { - return Contains(point.x(), point.y()); - } - - // Returns true if this rectangle contains the specified rectangle. - bool Contains(const Rect& rect) const; - - // Returns true if this rectangle intersects the specified rectangle. - bool Intersects(const Rect& rect) const; - - // Computes the intersection of this rectangle with the given rectangle. - Rect Intersect(const Rect& rect) const; - - // Computes the union of this rectangle with the given rectangle. The union - // is the smallest rectangle containing both rectangles. - Rect Union(const Rect& rect) const; - - // Computes the rectangle resulting from subtracting |rect| from |this|. If - // |rect| does not intersect completely in either the x- or y-direction, then - // |*this| is returned. If |rect| contains |this|, then an empty Rect is - // returned. - Rect Subtract(const Rect& rect) const; - - // Returns true if this rectangle equals that of the supplied rectangle. - bool Equals(const Rect& rect) const { - return *this == rect; - } - - // Fits as much of the receiving rectangle into the supplied rectangle as - // possible, returning the result. For example, if the receiver had - // a x-location of 2 and a width of 4, and the supplied rectangle had - // an x-location of 0 with a width of 5, the returned rectangle would have - // an x-location of 1 with a width of 4. - Rect AdjustToFit(const Rect& rect) const; - - // Returns the center of this rectangle. - Point CenterPoint() const; - - // Return a rectangle that has the same center point but with a size capped - // at given |size|. - Rect Center(const gfx::Size& size) const; - - // Returns true if this rectangle shares an entire edge (i.e., same width or - // same height) with the given rectangle, and the rectangles do not overlap. - bool SharesEdgeWith(const gfx::Rect& rect) const; - - private: - gfx::Point origin_; - gfx::Size size_; -}; - -std::ostream& operator<<(std::ostream& out, const gfx::Rect& r); - -} // namespace gfx +#include "ui/gfx/rect.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_RECT_H_ diff --git a/gfx/rect_unittest.cc b/gfx/rect_unittest.cc deleted file mode 100644 index f5b4d9b..0000000 --- a/gfx/rect_unittest.cc +++ /dev/null @@ -1,314 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/basictypes.h" -#include "gfx/rect.h" -#include "testing/gtest/include/gtest/gtest.h" - -typedef testing::Test RectTest; - -TEST(RectTest, Contains) { - static const struct ContainsCase { - int rect_x; - int rect_y; - int rect_width; - int rect_height; - int point_x; - int point_y; - bool contained; - } contains_cases[] = { - {0, 0, 10, 10, 0, 0, true}, - {0, 0, 10, 10, 5, 5, true}, - {0, 0, 10, 10, 9, 9, true}, - {0, 0, 10, 10, 5, 10, false}, - {0, 0, 10, 10, 10, 5, false}, - {0, 0, 10, 10, -1, -1, false}, - {0, 0, 10, 10, 50, 50, false}, - #ifdef NDEBUG - {0, 0, -10, -10, 0, 0, false}, - #endif // NDEBUG - }; - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(contains_cases); ++i) { - const ContainsCase& value = contains_cases[i]; - gfx::Rect rect(value.rect_x, value.rect_y, - value.rect_width, value.rect_height); - EXPECT_EQ(value.contained, rect.Contains(value.point_x, value.point_y)); - } -} - -TEST(RectTest, Intersects) { - static const struct { - int x1; // rect 1 - int y1; - int w1; - int h1; - int x2; // rect 2 - int y2; - int w2; - int h2; - bool intersects; - } tests[] = { - { 0, 0, 0, 0, 0, 0, 0, 0, false }, - { 0, 0, 10, 10, 0, 0, 10, 10, true }, - { 0, 0, 10, 10, 10, 10, 10, 10, false }, - { 10, 10, 10, 10, 0, 0, 10, 10, false }, - { 10, 10, 10, 10, 5, 5, 10, 10, true }, - { 10, 10, 10, 10, 15, 15, 10, 10, true }, - { 10, 10, 10, 10, 20, 15, 10, 10, false }, - { 10, 10, 10, 10, 21, 15, 10, 10, false } - }; - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { - gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1); - gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2); - EXPECT_EQ(tests[i].intersects, r1.Intersects(r2)); - } -} - -TEST(RectTest, Intersect) { - static const struct { - int x1; // rect 1 - int y1; - int w1; - int h1; - int x2; // rect 2 - int y2; - int w2; - int h2; - int x3; // rect 3: the union of rects 1 and 2 - int y3; - int w3; - int h3; - } tests[] = { - { 0, 0, 0, 0, // zeros - 0, 0, 0, 0, - 0, 0, 0, 0 }, - { 0, 0, 4, 4, // equal - 0, 0, 4, 4, - 0, 0, 4, 4 }, - { 0, 0, 4, 4, // neighboring - 4, 4, 4, 4, - 0, 0, 0, 0 }, - { 0, 0, 4, 4, // overlapping corners - 2, 2, 4, 4, - 2, 2, 2, 2 }, - { 0, 0, 4, 4, // T junction - 3, 1, 4, 2, - 3, 1, 1, 2 }, - { 3, 0, 2, 2, // gap - 0, 0, 2, 2, - 0, 0, 0, 0 } - }; - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { - gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1); - gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2); - gfx::Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3); - gfx::Rect ir = r1.Intersect(r2); - EXPECT_EQ(r3.x(), ir.x()); - EXPECT_EQ(r3.y(), ir.y()); - EXPECT_EQ(r3.width(), ir.width()); - EXPECT_EQ(r3.height(), ir.height()); - } -} - -TEST(RectTest, Union) { - static const struct Test { - int x1; // rect 1 - int y1; - int w1; - int h1; - int x2; // rect 2 - int y2; - int w2; - int h2; - int x3; // rect 3: the union of rects 1 and 2 - int y3; - int w3; - int h3; - } tests[] = { - { 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 }, - { 0, 0, 4, 4, - 0, 0, 4, 4, - 0, 0, 4, 4 }, - { 0, 0, 4, 4, - 4, 4, 4, 4, - 0, 0, 8, 8 }, - { 0, 0, 4, 4, - 0, 5, 4, 4, - 0, 0, 4, 9 }, - { 0, 0, 2, 2, - 3, 3, 2, 2, - 0, 0, 5, 5 }, - { 3, 3, 2, 2, // reverse r1 and r2 from previous test - 0, 0, 2, 2, - 0, 0, 5, 5 }, - { 0, 0, 0, 0, // union with empty rect - 2, 2, 2, 2, - 2, 2, 2, 2 } - }; - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { - gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1); - gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2); - gfx::Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3); - gfx::Rect u = r1.Union(r2); - EXPECT_EQ(r3.x(), u.x()); - EXPECT_EQ(r3.y(), u.y()); - EXPECT_EQ(r3.width(), u.width()); - EXPECT_EQ(r3.height(), u.height()); - } -} - -TEST(RectTest, Equals) { - ASSERT_TRUE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 0, 0, 0))); - ASSERT_TRUE(gfx::Rect(1, 2, 3, 4).Equals(gfx::Rect(1, 2, 3, 4))); - ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 0, 0, 1))); - ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 0, 1, 0))); - ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 1, 0, 0))); - ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(1, 0, 0, 0))); -} - -TEST(RectTest, AdjustToFit) { - static const struct Test { - int x1; // source - int y1; - int w1; - int h1; - int x2; // target - int y2; - int w2; - int h2; - int x3; // rect 3: results of invoking AdjustToFit - int y3; - int w3; - int h3; - } tests[] = { - { 0, 0, 2, 2, - 0, 0, 2, 2, - 0, 0, 2, 2 }, - { 2, 2, 3, 3, - 0, 0, 4, 4, - 1, 1, 3, 3 }, - { -1, -1, 5, 5, - 0, 0, 4, 4, - 0, 0, 4, 4 }, - { 2, 2, 4, 4, - 0, 0, 3, 3, - 0, 0, 3, 3 }, - { 2, 2, 1, 1, - 0, 0, 3, 3, - 2, 2, 1, 1 } - }; - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { - gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1); - gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2); - gfx::Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3); - gfx::Rect u(r1.AdjustToFit(r2)); - EXPECT_EQ(r3.x(), u.x()); - EXPECT_EQ(r3.y(), u.y()); - EXPECT_EQ(r3.width(), u.width()); - EXPECT_EQ(r3.height(), u.height()); - } -} - -TEST(RectTest, Subtract) { - // Matching - EXPECT_TRUE( - gfx::Rect(10, 10, 20, 20).Subtract( - gfx::Rect(10, 10, 20, 20)).Equals( - gfx::Rect(0, 0, 0, 0))); - - // Contains - EXPECT_TRUE( - gfx::Rect(10, 10, 20, 20).Subtract( - gfx::Rect(5, 5, 30, 30)).Equals( - gfx::Rect(0, 0, 0, 0))); - - // No intersection - EXPECT_TRUE( - gfx::Rect(10, 10, 20, 20).Subtract( - gfx::Rect(30, 30, 20, 20)).Equals( - gfx::Rect(10, 10, 20, 20))); - - // Not a complete intersection in either direction - EXPECT_TRUE( - gfx::Rect(10, 10, 20, 20).Subtract( - gfx::Rect(15, 15, 20, 20)).Equals( - gfx::Rect(10, 10, 20, 20))); - - // Complete intersection in the x-direction - EXPECT_TRUE( - gfx::Rect(10, 10, 20, 20).Subtract( - gfx::Rect(10, 15, 20, 20)).Equals( - gfx::Rect(10, 10, 20, 5))); - - // Complete intersection in the x-direction - EXPECT_TRUE( - gfx::Rect(10, 10, 20, 20).Subtract( - gfx::Rect(5, 15, 30, 20)).Equals( - gfx::Rect(10, 10, 20, 5))); - - // Complete intersection in the x-direction - EXPECT_TRUE( - gfx::Rect(10, 10, 20, 20).Subtract( - gfx::Rect(5, 5, 30, 20)).Equals( - gfx::Rect(10, 25, 20, 5))); - - // Complete intersection in the y-direction - EXPECT_TRUE( - gfx::Rect(10, 10, 20, 20).Subtract( - gfx::Rect(10, 10, 10, 30)).Equals( - gfx::Rect(20, 10, 10, 20))); - - // Complete intersection in the y-direction - EXPECT_TRUE( - gfx::Rect(10, 10, 20, 20).Subtract( - gfx::Rect(5, 5, 20, 30)).Equals( - gfx::Rect(25, 10, 5, 20))); -} - -TEST(RectTest, IsEmpty) { - EXPECT_TRUE(gfx::Rect(0, 0, 0, 0).IsEmpty()); - EXPECT_TRUE(gfx::Rect(0, 0, 0, 0).size().IsEmpty()); - EXPECT_TRUE(gfx::Rect(0, 0, 10, 0).IsEmpty()); - EXPECT_TRUE(gfx::Rect(0, 0, 10, 0).size().IsEmpty()); - EXPECT_TRUE(gfx::Rect(0, 0, 0, 10).IsEmpty()); - EXPECT_TRUE(gfx::Rect(0, 0, 0, 10).size().IsEmpty()); - EXPECT_FALSE(gfx::Rect(0, 0, 10, 10).IsEmpty()); - EXPECT_FALSE(gfx::Rect(0, 0, 10, 10).size().IsEmpty()); -} - -TEST(RectTest, SharesEdgeWith) { - gfx::Rect r(2, 3, 4, 5); - - // Must be non-overlapping - EXPECT_FALSE(r.SharesEdgeWith(r)); - - gfx::Rect just_above(2, 1, 4, 2); - gfx::Rect just_below(2, 8, 4, 2); - gfx::Rect just_left(0, 3, 2, 5); - gfx::Rect just_right(6, 3, 2, 5); - - EXPECT_TRUE(r.SharesEdgeWith(just_above)); - EXPECT_TRUE(r.SharesEdgeWith(just_below)); - EXPECT_TRUE(r.SharesEdgeWith(just_left)); - EXPECT_TRUE(r.SharesEdgeWith(just_right)); - - // Wrong placement - gfx::Rect same_height_no_edge(0, 0, 1, 5); - gfx::Rect same_width_no_edge(0, 0, 4, 1); - - EXPECT_FALSE(r.SharesEdgeWith(same_height_no_edge)); - EXPECT_FALSE(r.SharesEdgeWith(same_width_no_edge)); - - gfx::Rect just_above_no_edge(2, 1, 5, 2); // too wide - gfx::Rect just_below_no_edge(2, 8, 3, 2); // too narrow - gfx::Rect just_left_no_edge(0, 3, 2, 6); // too tall - gfx::Rect just_right_no_edge(6, 3, 2, 4); // too short - - EXPECT_FALSE(r.SharesEdgeWith(just_above_no_edge)); - EXPECT_FALSE(r.SharesEdgeWith(just_below_no_edge)); - EXPECT_FALSE(r.SharesEdgeWith(just_left_no_edge)); - EXPECT_FALSE(r.SharesEdgeWith(just_right_no_edge)); -} diff --git a/gfx/run_all_unittests.cc b/gfx/run_all_unittests.cc deleted file mode 100644 index 834d7c8..0000000 --- a/gfx/run_all_unittests.cc +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/test_suite.h" - -int main(int argc, char** argv) { - return GfxTestSuite(argc, argv).Run(); -} diff --git a/gfx/scoped_cg_context_state_mac.h b/gfx/scoped_cg_context_state_mac.h index 4ba7fac..f661efe 100644 --- a/gfx/scoped_cg_context_state_mac.h +++ b/gfx/scoped_cg_context_state_mac.h @@ -5,26 +5,7 @@ #ifndef GFX_SCOPED_CG_CONTEXT_STATE_MAC_H_ #define GFX_SCOPED_CG_CONTEXT_STATE_MAC_H_ -#import <QuartzCore/QuartzCore.h> - -namespace gfx { - -class ScopedCGContextSaveGState { - public: - explicit ScopedCGContextSaveGState(CGContextRef context) : context_(context) { - CGContextSaveGState(context_); - } - - ~ScopedCGContextSaveGState() { - CGContextRestoreGState(context_); - } - - private: - CGContextRef context_; - - DISALLOW_COPY_AND_ASSIGN(ScopedCGContextSaveGState); -}; - -} // namespace gfx +#include "ui/gfx/scoped_cg_context_state_mac.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_SCOPED_CG_CONTEXT_STATE_MAC_H_ diff --git a/gfx/scoped_image.h b/gfx/scoped_image.h index 56e99b7..686f249 100644 --- a/gfx/scoped_image.h +++ b/gfx/scoped_image.h @@ -6,142 +6,7 @@ #define GFX_SCOPED_IMAGE_H_ #pragma once -#include "base/basictypes.h" -#include "build/build_config.h" -#include "gfx/native_widget_types.h" -#include "third_party/skia/include/core/SkBitmap.h" - -#if defined(OS_LINUX) -#include <glib-object.h> -#elif defined(OS_MACOSX) -#include "base/mac/mac_util.h" -#endif - -namespace gfx { - -namespace internal { - -// ScopedImage is class that encapsulates one of the three platform-specific -// images used: SkBitmap, NSImage, and GdkPixbuf. This is the abstract interface -// that all ScopedImages respond to. This wrapper expects to own the image it -// holds, unless it is Release()ed or Free()ed. -// -// This class is abstract and callers should use the specialized versions below, -// which are not in the internal namespace. -template <class ImageType> -class ScopedImage { - public: - virtual ~ScopedImage() {} - - // Frees the actual image that this boxes. - virtual void Free() = 0; - - // Returns the image that this boxes. - ImageType* Get() { - return image_; - } - - // Frees the current image and sets a new one. - void Set(ImageType* new_image) { - Free(); - image_ = new_image; - } - - // Returns the image this boxes and relinquishes ownership. - ImageType* Release() { - ImageType* tmp = image_; - image_ = NULL; - return tmp; - } - - protected: - explicit ScopedImage(ImageType* image) : image_(image) {} - ImageType* image_; - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedImage); -}; - -} // namespace internal - -// Generic template. -template <class ImageType = gfx::NativeImageType> -class ScopedImage : public gfx::internal::ScopedImage<ImageType> { - public: - explicit ScopedImage(gfx::NativeImage image) - : gfx::internal::ScopedImage<ImageType>(image) {} - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedImage<ImageType>); -}; - -// Specialization for SkBitmap on all platforms. -template <> -class ScopedImage<SkBitmap> : public gfx::internal::ScopedImage<SkBitmap> { - public: - explicit ScopedImage(SkBitmap* image) - : gfx::internal::ScopedImage<SkBitmap>(image) {} - virtual ~ScopedImage() { - Free(); - } - - virtual void Free() { - delete image_; - image_ = NULL; - } - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedImage); -}; - -// Specialization for the NSImage type on Mac OS X. -#if defined(OS_MACOSX) -template <> -class ScopedImage<NSImage> : public gfx::internal::ScopedImage<NSImage> { - public: - explicit ScopedImage(NSImage* image) - : gfx::internal::ScopedImage<NSImage>(image) {} - virtual ~ScopedImage() { - Free(); - } - - virtual void Free() { - base::mac::NSObjectRelease(image_); - image_ = NULL; - } - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedImage); -}; -#endif // defined(OS_MACOSX) - -// Specialization for the GdkPixbuf type on Linux. -#if defined(OS_LINUX) -template <> -class ScopedImage<GdkPixbuf> : public gfx::internal::ScopedImage<GdkPixbuf> { - public: - explicit ScopedImage(GdkPixbuf* image) - : gfx::internal::ScopedImage<GdkPixbuf>(image) {} - virtual ~ScopedImage() { - Free(); - } - - virtual void Free() { - if (image_) { - g_object_unref(image_); - image_ = NULL; - } - } - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedImage); -}; -#endif // defined(OS_LINUX) - -// Typedef ScopedNativeImage to the default template argument. This allows for -// easy exchange between gfx::NativeImage and a gfx::ScopedNativeImage. -typedef ScopedImage<> ScopedNativeImage; - -} // namespace gfx +#include "ui/gfx/scoped_image.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_SCOPED_IMAGE_H_ diff --git a/gfx/scoped_image_unittest.cc b/gfx/scoped_image_unittest.cc deleted file mode 100644 index 8e8b312..0000000 --- a/gfx/scoped_image_unittest.cc +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/scoped_ptr.h" -#include "gfx/scoped_image.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkBitmap.h" - -#if defined(OS_LINUX) -#include "gfx/gtk_util.h" -#elif defined(OS_MACOSX) -#include "base/mac/mac_util.h" -#include "skia/ext/skia_utils_mac.h" -#endif - -namespace { - -class ScopedImageTest : public testing::Test { - public: - SkBitmap* CreateBitmap() { - SkBitmap* bitmap = new SkBitmap(); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, 25, 25); - bitmap->allocPixels(); - bitmap->eraseRGB(255, 0, 0); - return bitmap; - } - - gfx::NativeImage CreateNativeImage() { - scoped_ptr<SkBitmap> bitmap(CreateBitmap()); -#if defined(OS_MACOSX) - NSImage* image = gfx::SkBitmapToNSImage(*(bitmap.get())); - base::mac::NSObjectRetain(image); - return image; -#elif defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) - return gfx::GdkPixbufFromSkBitmap(bitmap.get()); -#else - return bitmap.release(); -#endif - } -}; - -TEST_F(ScopedImageTest, Initialize) { - gfx::ScopedImage<SkBitmap> image(CreateBitmap()); - EXPECT_TRUE(image.Get()); -} - -TEST_F(ScopedImageTest, Free) { - gfx::ScopedImage<SkBitmap> image(CreateBitmap()); - EXPECT_TRUE(image.Get()); - image.Free(); - EXPECT_FALSE(image.Get()); -} - -TEST_F(ScopedImageTest, Release) { - gfx::ScopedImage<SkBitmap> image(CreateBitmap()); - EXPECT_TRUE(image.Get()); - scoped_ptr<SkBitmap> bitmap(image.Release()); - EXPECT_FALSE(image.Get()); -} - -TEST_F(ScopedImageTest, Set) { - gfx::ScopedImage<SkBitmap> image(CreateBitmap()); - EXPECT_TRUE(image.Get()); - SkBitmap* image2 = CreateBitmap(); - image.Set(image2); - EXPECT_EQ(image2, image.Get()); -} - -TEST_F(ScopedImageTest, NativeInitialize) { - gfx::ScopedNativeImage image(CreateNativeImage()); - EXPECT_TRUE(image.Get()); -} - -TEST_F(ScopedImageTest, NativeFree) { - gfx::ScopedNativeImage image(CreateNativeImage()); - EXPECT_TRUE(image.Get()); - image.Free(); - EXPECT_FALSE(image.Get()); -} - -TEST_F(ScopedImageTest, NativeRelease) { - gfx::ScopedNativeImage image(CreateNativeImage()); - EXPECT_TRUE(image.Get()); - gfx::ScopedNativeImage image2(image.Release()); - EXPECT_FALSE(image.Get()); - EXPECT_TRUE(image2.Get()); -} - -TEST_F(ScopedImageTest, NativeSet) { - gfx::ScopedNativeImage image(CreateNativeImage()); - EXPECT_TRUE(image.Get()); - gfx::NativeImage image2 = CreateNativeImage(); - image.Set(image2); - EXPECT_EQ(image2, image.Get()); -} - -} // namespace diff --git a/gfx/scrollbar_size.cc b/gfx/scrollbar_size.cc deleted file mode 100644 index 426b0ac..0000000 --- a/gfx/scrollbar_size.cc +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/scrollbar_size.h" - -#include "base/compiler_specific.h" - -#if defined(OS_WIN) -#include <windows.h> -#endif - -namespace gfx { - -int scrollbar_size() { -#if defined(OS_WIN) - return GetSystemMetrics(SM_CXVSCROLL); -#else - return 15; -#endif -} - -} // namespace gfx diff --git a/gfx/scrollbar_size.h b/gfx/scrollbar_size.h index 9b4a9c4..2bf70b9 100644 --- a/gfx/scrollbar_size.h +++ b/gfx/scrollbar_size.h @@ -6,13 +6,7 @@ #define GFX_SCROLLBAR_SIZE_H_ #pragma once -namespace gfx { - -// This should return the thickness, in pixels, of a scrollbar in web content. -// This needs to match the values in WebCore's -// ScrollbarThemeChromiumXXX.cpp::scrollbarThickness(). -int scrollbar_size(); - -} // namespace gfx +#include "ui/gfx/scrollbar_size.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_SCROLLBAR_SIZE_H_ diff --git a/gfx/size.cc b/gfx/size.cc deleted file mode 100644 index 6e5528e..0000000 --- a/gfx/size.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/size.h" - -#if defined(OS_WIN) -#include <windows.h> -#elif defined(OS_MACOSX) -#include <CoreGraphics/CGGeometry.h> -#endif - -#include <ostream> - -#include "base/logging.h" - -namespace gfx { - -Size::Size(int width, int height) { - set_width(width); - set_height(height); -} - -#if defined(OS_MACOSX) -Size::Size(const CGSize& s) { - set_width(s.width); - set_height(s.height); -} - -Size& Size::operator=(const CGSize& s) { - set_width(s.width); - set_height(s.height); - return *this; -} -#endif - -#if defined(OS_WIN) -SIZE Size::ToSIZE() const { - SIZE s; - s.cx = width_; - s.cy = height_; - return s; -} -#elif defined(OS_MACOSX) -CGSize Size::ToCGSize() const { - return CGSizeMake(width_, height_); -} -#endif - -void Size::set_width(int width) { - if (width < 0) { - NOTREACHED() << "negative width:" << width; - width = 0; - } - width_ = width; -} - -void Size::set_height(int height) { - if (height < 0) { - NOTREACHED() << "negative height:" << height; - height = 0; - } - height_ = height; -} - -std::ostream& operator<<(std::ostream& out, const gfx::Size& s) { - return out << s.width() << "x" << s.height(); -} - -} // namespace gfx @@ -6,77 +6,7 @@ #define GFX_SIZE_H_ #pragma once -#include "build/build_config.h" - -#include <iosfwd> - -#if defined(OS_WIN) -typedef struct tagSIZE SIZE; -#elif defined(OS_MACOSX) -#include <ApplicationServices/ApplicationServices.h> -#endif - -namespace gfx { - -// A size has width and height values. -class Size { - public: - Size() : width_(0), height_(0) {} - Size(int width, int height); -#if defined(OS_MACOSX) - explicit Size(const CGSize& s); -#endif - - ~Size() {} - -#if defined(OS_MACOSX) - Size& operator=(const CGSize& s); -#endif - - int width() const { return width_; } - int height() const { return height_; } - - int GetArea() const { return width_ * height_; } - - void SetSize(int width, int height) { - set_width(width); - set_height(height); - } - - void Enlarge(int width, int height) { - set_width(width_ + width); - set_height(height_ + height); - } - - void set_width(int width); - void set_height(int height); - - bool operator==(const Size& s) const { - return width_ == s.width_ && height_ == s.height_; - } - - bool operator!=(const Size& s) const { - return !(*this == s); - } - - bool IsEmpty() const { - // Size doesn't allow negative dimensions, so testing for 0 is enough. - return (width_ == 0) || (height_ == 0); - } - -#if defined(OS_WIN) - SIZE ToSIZE() const; -#elif defined(OS_MACOSX) - CGSize ToCGSize() const; -#endif - - private: - int width_; - int height_; -}; - -std::ostream& operator<<(std::ostream& out, const gfx::Size& s); - -} // namespace gfx +#include "ui/gfx/size.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_SIZE_H_ diff --git a/gfx/skbitmap_operations.cc b/gfx/skbitmap_operations.cc deleted file mode 100644 index 6899553..0000000 --- a/gfx/skbitmap_operations.cc +++ /dev/null @@ -1,721 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/skbitmap_operations.h" - -#include <algorithm> -#include <string.h> - -#include "base/logging.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkColorPriv.h" -#include "third_party/skia/include/core/SkUnPreMultiply.h" - -// static -SkBitmap SkBitmapOperations::CreateInvertedBitmap(const SkBitmap& image) { - DCHECK(image.config() == SkBitmap::kARGB_8888_Config); - - SkAutoLockPixels lock_image(image); - - SkBitmap inverted; - inverted.setConfig(SkBitmap::kARGB_8888_Config, image.width(), image.height(), - 0); - inverted.allocPixels(); - inverted.eraseARGB(0, 0, 0, 0); - - for (int y = 0; y < image.height(); ++y) { - uint32* image_row = image.getAddr32(0, y); - uint32* dst_row = inverted.getAddr32(0, y); - - for (int x = 0; x < image.width(); ++x) { - uint32 image_pixel = image_row[x]; - dst_row[x] = (image_pixel & 0xFF000000) | - (0x00FFFFFF - (image_pixel & 0x00FFFFFF)); - } - } - - return inverted; -} - -// static -SkBitmap SkBitmapOperations::CreateSuperimposedBitmap(const SkBitmap& first, - const SkBitmap& second) { - DCHECK(first.width() == second.width()); - DCHECK(first.height() == second.height()); - DCHECK(first.bytesPerPixel() == second.bytesPerPixel()); - DCHECK(first.config() == SkBitmap::kARGB_8888_Config); - - SkAutoLockPixels lock_first(first); - SkAutoLockPixels lock_second(second); - - SkBitmap superimposed; - superimposed.setConfig(SkBitmap::kARGB_8888_Config, - first.width(), first.height()); - superimposed.allocPixels(); - superimposed.eraseARGB(0, 0, 0, 0); - - SkCanvas canvas(superimposed); - - SkRect rect; - rect.fLeft = 0; - rect.fTop = 0; - rect.fRight = SkIntToScalar(first.width()); - rect.fBottom = SkIntToScalar(first.height()); - - canvas.drawBitmapRect(first, NULL, rect); - canvas.drawBitmapRect(second, NULL, rect); - - return superimposed; -} - -// static -SkBitmap SkBitmapOperations::CreateBlendedBitmap(const SkBitmap& first, - const SkBitmap& second, - double alpha) { - DCHECK((alpha >= 0) && (alpha <= 1)); - DCHECK(first.width() == second.width()); - DCHECK(first.height() == second.height()); - DCHECK(first.bytesPerPixel() == second.bytesPerPixel()); - DCHECK(first.config() == SkBitmap::kARGB_8888_Config); - - // Optimize for case where we won't need to blend anything. - static const double alpha_min = 1.0 / 255; - static const double alpha_max = 254.0 / 255; - if (alpha < alpha_min) - return first; - else if (alpha > alpha_max) - return second; - - SkAutoLockPixels lock_first(first); - SkAutoLockPixels lock_second(second); - - SkBitmap blended; - blended.setConfig(SkBitmap::kARGB_8888_Config, first.width(), first.height(), - 0); - blended.allocPixels(); - blended.eraseARGB(0, 0, 0, 0); - - double first_alpha = 1 - alpha; - - for (int y = 0; y < first.height(); ++y) { - uint32* first_row = first.getAddr32(0, y); - uint32* second_row = second.getAddr32(0, y); - uint32* dst_row = blended.getAddr32(0, y); - - for (int x = 0; x < first.width(); ++x) { - uint32 first_pixel = first_row[x]; - uint32 second_pixel = second_row[x]; - - int a = static_cast<int>((SkColorGetA(first_pixel) * first_alpha) + - (SkColorGetA(second_pixel) * alpha)); - int r = static_cast<int>((SkColorGetR(first_pixel) * first_alpha) + - (SkColorGetR(second_pixel) * alpha)); - int g = static_cast<int>((SkColorGetG(first_pixel) * first_alpha) + - (SkColorGetG(second_pixel) * alpha)); - int b = static_cast<int>((SkColorGetB(first_pixel) * first_alpha) + - (SkColorGetB(second_pixel) * alpha)); - - dst_row[x] = SkColorSetARGB(a, r, g, b); - } - } - - return blended; -} - -// static -SkBitmap SkBitmapOperations::CreateMaskedBitmap(const SkBitmap& rgb, - const SkBitmap& alpha) { - DCHECK(rgb.width() == alpha.width()); - DCHECK(rgb.height() == alpha.height()); - DCHECK(rgb.bytesPerPixel() == alpha.bytesPerPixel()); - DCHECK(rgb.config() == SkBitmap::kARGB_8888_Config); - DCHECK(alpha.config() == SkBitmap::kARGB_8888_Config); - - SkBitmap masked; - masked.setConfig(SkBitmap::kARGB_8888_Config, rgb.width(), rgb.height(), 0); - masked.allocPixels(); - masked.eraseARGB(0, 0, 0, 0); - - SkAutoLockPixels lock_rgb(rgb); - SkAutoLockPixels lock_alpha(alpha); - SkAutoLockPixels lock_masked(masked); - - for (int y = 0; y < masked.height(); ++y) { - uint32* rgb_row = rgb.getAddr32(0, y); - uint32* alpha_row = alpha.getAddr32(0, y); - uint32* dst_row = masked.getAddr32(0, y); - - for (int x = 0; x < masked.width(); ++x) { - SkColor rgb_pixel = SkUnPreMultiply::PMColorToColor(rgb_row[x]); - int alpha = SkAlphaMul(SkColorGetA(rgb_pixel), SkColorGetA(alpha_row[x])); - dst_row[x] = SkColorSetARGB(alpha, - SkAlphaMul(SkColorGetR(rgb_pixel), alpha), - SkAlphaMul(SkColorGetG(rgb_pixel), alpha), - SkAlphaMul(SkColorGetB(rgb_pixel), alpha)); - } - } - - return masked; -} - -// static -SkBitmap SkBitmapOperations::CreateButtonBackground(SkColor color, - const SkBitmap& image, - const SkBitmap& mask) { - DCHECK(image.config() == SkBitmap::kARGB_8888_Config); - DCHECK(mask.config() == SkBitmap::kARGB_8888_Config); - - SkBitmap background; - background.setConfig( - SkBitmap::kARGB_8888_Config, mask.width(), mask.height(), 0); - background.allocPixels(); - - double bg_a = SkColorGetA(color); - double bg_r = SkColorGetR(color); - double bg_g = SkColorGetG(color); - double bg_b = SkColorGetB(color); - - SkAutoLockPixels lock_mask(mask); - SkAutoLockPixels lock_image(image); - SkAutoLockPixels lock_background(background); - - for (int y = 0; y < mask.height(); ++y) { - uint32* dst_row = background.getAddr32(0, y); - uint32* image_row = image.getAddr32(0, y % image.height()); - uint32* mask_row = mask.getAddr32(0, y); - - for (int x = 0; x < mask.width(); ++x) { - uint32 image_pixel = image_row[x % image.width()]; - - double img_a = SkColorGetA(image_pixel); - double img_r = SkColorGetR(image_pixel); - double img_g = SkColorGetG(image_pixel); - double img_b = SkColorGetB(image_pixel); - - double img_alpha = static_cast<double>(img_a) / 255.0; - double img_inv = 1 - img_alpha; - - double mask_a = static_cast<double>(SkColorGetA(mask_row[x])) / 255.0; - - dst_row[x] = SkColorSetARGB( - static_cast<int>(std::min(255.0, bg_a + img_a) * mask_a), - static_cast<int>(((bg_r * img_inv) + (img_r * img_alpha)) * mask_a), - static_cast<int>(((bg_g * img_inv) + (img_g * img_alpha)) * mask_a), - static_cast<int>(((bg_b * img_inv) + (img_b * img_alpha)) * mask_a)); - } - } - - return background; -} - -namespace { -namespace HSLShift { - -// TODO(viettrungluu): Some things have yet to be optimized at all. - -// Notes on and conventions used in the following code -// -// Conventions: -// - R, G, B, A = obvious; as variables: |r|, |g|, |b|, |a| (see also below) -// - H, S, L = obvious; as variables: |h|, |s|, |l| (see also below) -// - variables derived from S, L shift parameters: |sdec| and |sinc| for S -// increase and decrease factors, |ldec| and |linc| for L (see also below) -// -// To try to optimize HSL shifts, we do several things: -// - Avoid unpremultiplying (then processing) then premultiplying. This means -// that R, G, B values (and also L, but not H and S) should be treated as -// having a range of 0..A (where A is alpha). -// - Do things in integer/fixed-point. This avoids costly conversions between -// floating-point and integer, though I should study the tradeoff more -// carefully (presumably, at some point of processing complexity, converting -// and processing using simpler floating-point code will begin to win in -// performance). Also to be studied is the speed/type of floating point -// conversions; see, e.g., <http://www.stereopsis.com/sree/fpu2006.html>. -// -// Conventions for fixed-point arithmetic -// - Each function has a constant denominator (called |den|, which should be a -// power of 2), appropriate for the computations done in that function. -// - A value |x| is then typically represented by a numerator, named |x_num|, -// so that its actual value is |x_num / den| (casting to floating-point -// before division). -// - To obtain |x_num| from |x|, simply multiply by |den|, i.e., |x_num = x * -// den| (casting appropriately). -// - When necessary, a value |x| may also be represented as a numerator over -// the denominator squared (set |den2 = den * den|). In such a case, the -// corresponding variable is called |x_num2| (so that its actual value is -// |x_num^2 / den2|. -// - The representation of the product of |x| and |y| is be called |x_y_num| if -// |x * y == x_y_num / den|, and |xy_num2| if |x * y == x_y_num2 / den2|. In -// the latter case, notice that one can calculate |x_y_num2 = x_num * y_num|. - -// Routine used to process a line; typically specialized for specific kinds of -// HSL shifts (to optimize). -typedef void (*LineProcessor)(color_utils::HSL, - const SkPMColor*, - SkPMColor*, - int width); - -enum OperationOnH { kOpHNone = 0, kOpHShift, kNumHOps }; -enum OperationOnS { kOpSNone = 0, kOpSDec, kOpSInc, kNumSOps }; -enum OperationOnL { kOpLNone = 0, kOpLDec, kOpLInc, kNumLOps }; - -// Epsilon used to judge when shift values are close enough to various critical -// values (typically 0.5, which yields a no-op for S and L shifts. 1/256 should -// be small enough, but let's play it safe> -const double epsilon = 0.0005; - -// Line processor: default/universal (i.e., old-school). -void LineProcDefault(color_utils::HSL hsl_shift, const SkPMColor* in, - SkPMColor* out, int width) { - for (int x = 0; x < width; x++) { - out[x] = SkPreMultiplyColor(color_utils::HSLShift( - SkUnPreMultiply::PMColorToColor(in[x]), hsl_shift)); - } -} - -// Line processor: no-op (i.e., copy). -void LineProcCopy(color_utils::HSL hsl_shift, const SkPMColor* in, - SkPMColor* out, int width) { - DCHECK(hsl_shift.h < 0); - DCHECK(hsl_shift.s < 0 || fabs(hsl_shift.s - 0.5) < HSLShift::epsilon); - DCHECK(hsl_shift.l < 0 || fabs(hsl_shift.l - 0.5) < HSLShift::epsilon); - memcpy(out, in, static_cast<size_t>(width) * sizeof(out[0])); -} - -// Line processor: H no-op, S no-op, L decrease. -void LineProcHnopSnopLdec(color_utils::HSL hsl_shift, const SkPMColor* in, - SkPMColor* out, int width) { - const uint32_t den = 65536; - - DCHECK(hsl_shift.h < 0); - DCHECK(hsl_shift.s < 0 || fabs(hsl_shift.s - 0.5) < HSLShift::epsilon); - DCHECK(hsl_shift.l <= 0.5 - HSLShift::epsilon && hsl_shift.l >= 0); - - uint32_t ldec_num = static_cast<uint32_t>(hsl_shift.l * 2 * den); - for (int x = 0; x < width; x++) { - uint32_t a = SkGetPackedA32(in[x]); - uint32_t r = SkGetPackedR32(in[x]); - uint32_t g = SkGetPackedG32(in[x]); - uint32_t b = SkGetPackedB32(in[x]); - r = r * ldec_num / den; - g = g * ldec_num / den; - b = b * ldec_num / den; - out[x] = SkPackARGB32(a, r, g, b); - } -} - -// Line processor: H no-op, S no-op, L increase. -void LineProcHnopSnopLinc(color_utils::HSL hsl_shift, const SkPMColor* in, - SkPMColor* out, int width) { - const uint32_t den = 65536; - - DCHECK(hsl_shift.h < 0); - DCHECK(hsl_shift.s < 0 || fabs(hsl_shift.s - 0.5) < HSLShift::epsilon); - DCHECK(hsl_shift.l >= 0.5 + HSLShift::epsilon && hsl_shift.l <= 1); - - uint32_t linc_num = static_cast<uint32_t>((hsl_shift.l - 0.5) * 2 * den); - for (int x = 0; x < width; x++) { - uint32_t a = SkGetPackedA32(in[x]); - uint32_t r = SkGetPackedR32(in[x]); - uint32_t g = SkGetPackedG32(in[x]); - uint32_t b = SkGetPackedB32(in[x]); - r += (a - r) * linc_num / den; - g += (a - g) * linc_num / den; - b += (a - b) * linc_num / den; - out[x] = SkPackARGB32(a, r, g, b); - } -} - -// Saturation changes modifications in RGB -// -// (Note that as a further complication, the values we deal in are -// premultiplied, so R/G/B values must be in the range 0..A. For mathematical -// purposes, one may as well use r=R/A, g=G/A, b=B/A. Without loss of -// generality, assume that R/G/B values are in the range 0..1.) -// -// Let Max = max(R,G,B), Min = min(R,G,B), and Med be the median value. Then L = -// (Max+Min)/2. If L is to remain constant, Max+Min must also remain constant. -// -// For H to remain constant, first, the (numerical) order of R/G/B (from -// smallest to largest) must remain the same. Second, all the ratios -// (R-G)/(Max-Min), (R-B)/(Max-Min), (G-B)/(Max-Min) must remain constant (of -// course, if Max = Min, then S = 0 and no saturation change is well-defined, -// since H is not well-defined). -// -// Let C_max be a colour with value Max, C_min be one with value Min, and C_med -// the remaining colour. Increasing saturation (to the maximum) is accomplished -// by increasing the value of C_max while simultaneously decreasing C_min and -// changing C_med so that the ratios are maintained; for the latter, it suffices -// to keep (C_med-C_min)/(C_max-C_min) constant (and equal to -// (Med-Min)/(Max-Min)). - -// Line processor: H no-op, S decrease, L no-op. -void LineProcHnopSdecLnop(color_utils::HSL hsl_shift, const SkPMColor* in, - SkPMColor* out, int width) { - DCHECK(hsl_shift.h < 0); - DCHECK(hsl_shift.s >= 0 && hsl_shift.s <= 0.5 - HSLShift::epsilon); - DCHECK(hsl_shift.l < 0 || fabs(hsl_shift.l - 0.5) < HSLShift::epsilon); - - const int32_t denom = 65536; - int32_t s_numer = static_cast<int32_t>(hsl_shift.s * 2 * denom); - for (int x = 0; x < width; x++) { - int32_t a = static_cast<int32_t>(SkGetPackedA32(in[x])); - int32_t r = static_cast<int32_t>(SkGetPackedR32(in[x])); - int32_t g = static_cast<int32_t>(SkGetPackedG32(in[x])); - int32_t b = static_cast<int32_t>(SkGetPackedB32(in[x])); - - int32_t vmax, vmin; - if (r > g) { // This uses 3 compares rather than 4. - vmax = std::max(r, b); - vmin = std::min(g, b); - } else { - vmax = std::max(g, b); - vmin = std::min(r, b); - } - - // Use denom * L to avoid rounding. - int32_t denom_l = (vmax + vmin) * (denom / 2); - int32_t s_numer_l = (vmax + vmin) * s_numer / 2; - - r = (denom_l + r * s_numer - s_numer_l) / denom; - g = (denom_l + g * s_numer - s_numer_l) / denom; - b = (denom_l + b * s_numer - s_numer_l) / denom; - out[x] = SkPackARGB32(a, r, g, b); - } -} - -// Line processor: H no-op, S decrease, L decrease. -void LineProcHnopSdecLdec(color_utils::HSL hsl_shift, const SkPMColor* in, - SkPMColor* out, int width) { - DCHECK(hsl_shift.h < 0); - DCHECK(hsl_shift.s >= 0 && hsl_shift.s <= 0.5 - HSLShift::epsilon); - DCHECK(hsl_shift.l >= 0 && hsl_shift.l <= 0.5 - HSLShift::epsilon); - - // Can't be too big since we need room for denom*denom and a bit for sign. - const int32_t denom = 1024; - int32_t l_numer = static_cast<int32_t>(hsl_shift.l * 2 * denom); - int32_t s_numer = static_cast<int32_t>(hsl_shift.s * 2 * denom); - for (int x = 0; x < width; x++) { - int32_t a = static_cast<int32_t>(SkGetPackedA32(in[x])); - int32_t r = static_cast<int32_t>(SkGetPackedR32(in[x])); - int32_t g = static_cast<int32_t>(SkGetPackedG32(in[x])); - int32_t b = static_cast<int32_t>(SkGetPackedB32(in[x])); - - int32_t vmax, vmin; - if (r > g) { // This uses 3 compares rather than 4. - vmax = std::max(r, b); - vmin = std::min(g, b); - } else { - vmax = std::max(g, b); - vmin = std::min(r, b); - } - - // Use denom * L to avoid rounding. - int32_t denom_l = (vmax + vmin) * (denom / 2); - int32_t s_numer_l = (vmax + vmin) * s_numer / 2; - - r = (denom_l + r * s_numer - s_numer_l) * l_numer / (denom * denom); - g = (denom_l + g * s_numer - s_numer_l) * l_numer / (denom * denom); - b = (denom_l + b * s_numer - s_numer_l) * l_numer / (denom * denom); - out[x] = SkPackARGB32(a, r, g, b); - } -} - -// Line processor: H no-op, S decrease, L increase. -void LineProcHnopSdecLinc(color_utils::HSL hsl_shift, const SkPMColor* in, - SkPMColor* out, int width) { - DCHECK(hsl_shift.h < 0); - DCHECK(hsl_shift.s >= 0 && hsl_shift.s <= 0.5 - HSLShift::epsilon); - DCHECK(hsl_shift.l >= 0.5 + HSLShift::epsilon && hsl_shift.l <= 1); - - // Can't be too big since we need room for denom*denom and a bit for sign. - const int32_t denom = 1024; - int32_t l_numer = static_cast<int32_t>((hsl_shift.l - 0.5) * 2 * denom); - int32_t s_numer = static_cast<int32_t>(hsl_shift.s * 2 * denom); - for (int x = 0; x < width; x++) { - int32_t a = static_cast<int32_t>(SkGetPackedA32(in[x])); - int32_t r = static_cast<int32_t>(SkGetPackedR32(in[x])); - int32_t g = static_cast<int32_t>(SkGetPackedG32(in[x])); - int32_t b = static_cast<int32_t>(SkGetPackedB32(in[x])); - - int32_t vmax, vmin; - if (r > g) { // This uses 3 compares rather than 4. - vmax = std::max(r, b); - vmin = std::min(g, b); - } else { - vmax = std::max(g, b); - vmin = std::min(r, b); - } - - // Use denom * L to avoid rounding. - int32_t denom_l = (vmax + vmin) * (denom / 2); - int32_t s_numer_l = (vmax + vmin) * s_numer / 2; - - r = denom_l + r * s_numer - s_numer_l; - g = denom_l + g * s_numer - s_numer_l; - b = denom_l + b * s_numer - s_numer_l; - - r = (r * denom + (a * denom - r) * l_numer) / (denom * denom); - g = (g * denom + (a * denom - g) * l_numer) / (denom * denom); - b = (b * denom + (a * denom - b) * l_numer) / (denom * denom); - out[x] = SkPackARGB32(a, r, g, b); - } -} - -const LineProcessor kLineProcessors[kNumHOps][kNumSOps][kNumLOps] = { - { // H: kOpHNone - { // S: kOpSNone - LineProcCopy, // L: kOpLNone - LineProcHnopSnopLdec, // L: kOpLDec - LineProcHnopSnopLinc // L: kOpLInc - }, - { // S: kOpSDec - LineProcHnopSdecLnop, // L: kOpLNone - LineProcHnopSdecLdec, // L: kOpLDec - LineProcHnopSdecLinc // L: kOpLInc - }, - { // S: kOpSInc - LineProcDefault, // L: kOpLNone - LineProcDefault, // L: kOpLDec - LineProcDefault // L: kOpLInc - } - }, - { // H: kOpHShift - { // S: kOpSNone - LineProcDefault, // L: kOpLNone - LineProcDefault, // L: kOpLDec - LineProcDefault // L: kOpLInc - }, - { // S: kOpSDec - LineProcDefault, // L: kOpLNone - LineProcDefault, // L: kOpLDec - LineProcDefault // L: kOpLInc - }, - { // S: kOpSInc - LineProcDefault, // L: kOpLNone - LineProcDefault, // L: kOpLDec - LineProcDefault // L: kOpLInc - } - } -}; - -} // namespace HSLShift -} // namespace - -// static -SkBitmap SkBitmapOperations::CreateHSLShiftedBitmap( - const SkBitmap& bitmap, - color_utils::HSL hsl_shift) { - // Default to NOPs. - HSLShift::OperationOnH H_op = HSLShift::kOpHNone; - HSLShift::OperationOnS S_op = HSLShift::kOpSNone; - HSLShift::OperationOnL L_op = HSLShift::kOpLNone; - - if (hsl_shift.h >= 0 && hsl_shift.h <= 1) - H_op = HSLShift::kOpHShift; - - // Saturation shift: 0 -> fully desaturate, 0.5 -> NOP, 1 -> fully saturate. - if (hsl_shift.s >= 0 && hsl_shift.s <= (0.5 - HSLShift::epsilon)) - S_op = HSLShift::kOpSDec; - else if (hsl_shift.s >= (0.5 + HSLShift::epsilon)) - S_op = HSLShift::kOpSInc; - - // Lightness shift: 0 -> black, 0.5 -> NOP, 1 -> white. - if (hsl_shift.l >= 0 && hsl_shift.l <= (0.5 - HSLShift::epsilon)) - L_op = HSLShift::kOpLDec; - else if (hsl_shift.l >= (0.5 + HSLShift::epsilon)) - L_op = HSLShift::kOpLInc; - - HSLShift::LineProcessor line_proc = - HSLShift::kLineProcessors[H_op][S_op][L_op]; - - DCHECK(bitmap.empty() == false); - DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config); - - SkBitmap shifted; - shifted.setConfig(SkBitmap::kARGB_8888_Config, bitmap.width(), - bitmap.height(), 0); - shifted.allocPixels(); - shifted.eraseARGB(0, 0, 0, 0); - shifted.setIsOpaque(false); - - SkAutoLockPixels lock_bitmap(bitmap); - SkAutoLockPixels lock_shifted(shifted); - - // Loop through the pixels of the original bitmap. - for (int y = 0; y < bitmap.height(); ++y) { - SkPMColor* pixels = bitmap.getAddr32(0, y); - SkPMColor* tinted_pixels = shifted.getAddr32(0, y); - - (*line_proc)(hsl_shift, pixels, tinted_pixels, bitmap.width()); - } - - return shifted; -} - -// static -SkBitmap SkBitmapOperations::CreateTiledBitmap(const SkBitmap& source, - int src_x, int src_y, - int dst_w, int dst_h) { - DCHECK(source.getConfig() == SkBitmap::kARGB_8888_Config); - - SkBitmap cropped; - cropped.setConfig(SkBitmap::kARGB_8888_Config, dst_w, dst_h, 0); - cropped.allocPixels(); - cropped.eraseARGB(0, 0, 0, 0); - - SkAutoLockPixels lock_source(source); - SkAutoLockPixels lock_cropped(cropped); - - // Loop through the pixels of the original bitmap. - for (int y = 0; y < dst_h; ++y) { - int y_pix = (src_y + y) % source.height(); - while (y_pix < 0) - y_pix += source.height(); - - uint32* source_row = source.getAddr32(0, y_pix); - uint32* dst_row = cropped.getAddr32(0, y); - - for (int x = 0; x < dst_w; ++x) { - int x_pix = (src_x + x) % source.width(); - while (x_pix < 0) - x_pix += source.width(); - - dst_row[x] = source_row[x_pix]; - } - } - - return cropped; -} - -// static -SkBitmap SkBitmapOperations::DownsampleByTwoUntilSize(const SkBitmap& bitmap, - int min_w, int min_h) { - if ((bitmap.width() <= min_w) || (bitmap.height() <= min_h) || - (min_w < 0) || (min_h < 0)) - return bitmap; - - // Since bitmaps are refcounted, this copy will be fast. - SkBitmap current = bitmap; - while ((current.width() >= min_w * 2) && (current.height() >= min_h * 2) && - (current.width() > 1) && (current.height() > 1)) - current = DownsampleByTwo(current); - return current; -} - -// static -SkBitmap SkBitmapOperations::DownsampleByTwo(const SkBitmap& bitmap) { - // Handle the nop case. - if ((bitmap.width() <= 1) || (bitmap.height() <= 1)) - return bitmap; - - SkBitmap result; - result.setConfig(SkBitmap::kARGB_8888_Config, - (bitmap.width() + 1) / 2, (bitmap.height() + 1) / 2); - result.allocPixels(); - - SkAutoLockPixels lock(bitmap); - for (int dest_y = 0; dest_y < result.height(); ++dest_y) { - for (int dest_x = 0; dest_x < result.width(); ++dest_x) { - // This code is based on downsampleby2_proc32 in SkBitmap.cpp. It is very - // clever in that it does two channels at once: alpha and green ("ag") - // and red and blue ("rb"). Each channel gets averaged across 4 pixels - // to get the result. - int src_x = dest_x << 1; - int src_y = dest_y << 1; - const SkPMColor* cur_src = bitmap.getAddr32(src_x, src_y); - SkPMColor tmp, ag, rb; - - // Top left pixel of the 2x2 block. - tmp = *cur_src; - ag = (tmp >> 8) & 0xFF00FF; - rb = tmp & 0xFF00FF; - if (src_x < (bitmap.width() - 1)) - ++cur_src; - - // Top right pixel of the 2x2 block. - tmp = *cur_src; - ag += (tmp >> 8) & 0xFF00FF; - rb += tmp & 0xFF00FF; - if (src_y < (bitmap.height() - 1)) - cur_src = bitmap.getAddr32(src_x, src_y + 1); - else - cur_src = bitmap.getAddr32(src_x, src_y); // Move back to the first. - - // Bottom left pixel of the 2x2 block. - tmp = *cur_src; - ag += (tmp >> 8) & 0xFF00FF; - rb += tmp & 0xFF00FF; - if (src_x < (bitmap.width() - 1)) - ++cur_src; - - // Bottom right pixel of the 2x2 block. - tmp = *cur_src; - ag += (tmp >> 8) & 0xFF00FF; - rb += tmp & 0xFF00FF; - - // Put the channels back together, dividing each by 4 to get the average. - // |ag| has the alpha and green channels shifted right by 8 bits from - // there they should end up, so shifting left by 6 gives them in the - // correct position divided by 4. - *result.getAddr32(dest_x, dest_y) = - ((rb >> 2) & 0xFF00FF) | ((ag << 6) & 0xFF00FF00); - } - } - - return result; -} - -// static -SkBitmap SkBitmapOperations::UnPreMultiply(const SkBitmap& bitmap) { - if (bitmap.isNull()) - return bitmap; - if (bitmap.isOpaque()) - return bitmap; - - SkBitmap opaque_bitmap; - opaque_bitmap.setConfig(bitmap.config(), bitmap.width(), bitmap.height()); - opaque_bitmap.allocPixels(); - - { - SkAutoLockPixels bitmap_lock(bitmap); - SkAutoLockPixels opaque_bitmap_lock(opaque_bitmap); - for (int y = 0; y < opaque_bitmap.height(); y++) { - for (int x = 0; x < opaque_bitmap.width(); x++) { - uint32 src_pixel = *bitmap.getAddr32(x, y); - uint32* dst_pixel = opaque_bitmap.getAddr32(x, y); - SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(src_pixel); - *dst_pixel = unmultiplied; - } - } - } - - opaque_bitmap.setIsOpaque(true); - return opaque_bitmap; -} - -// static -SkBitmap SkBitmapOperations::CreateTransposedBtmap(const SkBitmap& image) { - DCHECK(image.config() == SkBitmap::kARGB_8888_Config); - - SkAutoLockPixels lock_image(image); - - SkBitmap transposed; - transposed.setConfig( - SkBitmap::kARGB_8888_Config, image.height(), image.width(), 0); - transposed.allocPixels(); - transposed.eraseARGB(0, 0, 0, 0); - - for (int y = 0; y < image.height(); ++y) { - uint32* image_row = image.getAddr32(0, y); - for (int x = 0; x < image.width(); ++x) { - uint32* dst = transposed.getAddr32(y, x); - *dst = image_row[x]; - } - } - - return transposed; -} - diff --git a/gfx/skbitmap_operations.h b/gfx/skbitmap_operations.h index e64c1aa..42aa7b3 100644 --- a/gfx/skbitmap_operations.h +++ b/gfx/skbitmap_operations.h @@ -6,97 +6,7 @@ #define GFX_SKBITMAP_OPERATIONS_H_ #pragma once -#include "base/gtest_prod_util.h" -#include "gfx/color_utils.h" - -class SkBitmap; - -class SkBitmapOperations { - public: - // Create a bitmap that is an inverted image of the passed in image. - // Each color becomes its inverse in the color wheel. So (255, 15, 0) becomes - // (0, 240, 255). The alpha value is not inverted. - static SkBitmap CreateInvertedBitmap(const SkBitmap& image); - - // Create a bitmap that is a superimposition of the second bitmap on top of - // the first. The provided bitmaps must use have the kARGB_8888_Config config - // and be of equal dimensions. - static SkBitmap CreateSuperimposedBitmap(const SkBitmap& first, - const SkBitmap& second); - - // Create a bitmap that is a blend of two others. The alpha argument - // specifies the opacity of the second bitmap. The provided bitmaps must - // use have the kARGB_8888_Config config and be of equal dimensions. - static SkBitmap CreateBlendedBitmap(const SkBitmap& first, - const SkBitmap& second, - double alpha); - - // Create a bitmap that is the original bitmap masked out by the mask defined - // in the alpha bitmap. The images must use the kARGB_8888_Config config and - // be of equal dimensions. - static SkBitmap CreateMaskedBitmap(const SkBitmap& first, - const SkBitmap& alpha); - - // We create a button background image by compositing the color and image - // together, then applying the mask. This is a highly specialized composite - // operation that is the equivalent of drawing a background in |color|, - // tiling |image| over the top, and then masking the result out with |mask|. - // The images must use kARGB_8888_Config config. - static SkBitmap CreateButtonBackground(SkColor color, - const SkBitmap& image, - const SkBitmap& mask); - - // Shift a bitmap's HSL values. The shift values are in the range of 0-1, - // with the option to specify -1 for 'no change'. The shift values are - // defined as: - // hsl_shift[0] (hue): The absolute hue value for the image - 0 and 1 map - // to 0 and 360 on the hue color wheel (red). - // hsl_shift[1] (saturation): A saturation shift for the image, with the - // following key values: - // 0 = remove all color. - // 0.5 = leave unchanged. - // 1 = fully saturate the image. - // hsl_shift[2] (lightness): A lightness shift for the image, with the - // following key values: - // 0 = remove all lightness (make all pixels black). - // 0.5 = leave unchanged. - // 1 = full lightness (make all pixels white). - static SkBitmap CreateHSLShiftedBitmap(const SkBitmap& bitmap, - color_utils::HSL hsl_shift); - - // Create a bitmap that is cropped from another bitmap. This is special - // because it tiles the original bitmap, so your coordinates can extend - // outside the bounds of the original image. - static SkBitmap CreateTiledBitmap(const SkBitmap& bitmap, - int src_x, int src_y, - int dst_w, int dst_h); - - // Iteratively downsamples by 2 until the bitmap is no smaller than the - // input size. The normal use of this is to downsample the bitmap "close" to - // the final size, and then use traditional resampling on the result. - // Because the bitmap will be closer to the final size, it will be faster, - // and linear interpolation will generally work well as a second step. - static SkBitmap DownsampleByTwoUntilSize(const SkBitmap& bitmap, - int min_w, int min_h); - - // Makes a bitmap half has large in each direction by averaging groups of - // 4 pixels. This is one step in generating a mipmap. - static SkBitmap DownsampleByTwo(const SkBitmap& bitmap); - - // Unpremultiplies all pixels in |bitmap|. You almost never want to call - // this, as |SkBitmap|s are always premultiplied by conversion. Call this - // only if you will pass the bitmap's data into a system function that - // doesn't expect premultiplied colors. - static SkBitmap UnPreMultiply(const SkBitmap& bitmap); - - // Transpose the pixels in |bitmap| by swapping x and y. - static SkBitmap CreateTransposedBtmap(const SkBitmap& bitmap); - - private: - SkBitmapOperations(); // Class for scoping only. - - FRIEND_TEST_ALL_PREFIXES(SkBitmapOperationsTest, DownsampleByTwo); - FRIEND_TEST_ALL_PREFIXES(SkBitmapOperationsTest, DownsampleByTwoSmall); -}; +#include "ui/gfx/skbitmap_operations.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_SKBITMAP_OPERATIONS_H_ diff --git a/gfx/skbitmap_operations_unittest.cc b/gfx/skbitmap_operations_unittest.cc deleted file mode 100644 index bcad287..0000000 --- a/gfx/skbitmap_operations_unittest.cc +++ /dev/null @@ -1,517 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/skbitmap_operations.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkColorPriv.h" -#include "third_party/skia/include/core/SkUnPreMultiply.h" - -namespace { - -// Returns true if each channel of the given two colors are "close." This is -// used for comparing colors where rounding errors may cause off-by-one. -inline bool ColorsClose(uint32_t a, uint32_t b) { - return abs(static_cast<int>(SkColorGetB(a) - SkColorGetB(b))) <= 2 && - abs(static_cast<int>(SkColorGetG(a) - SkColorGetG(b))) <= 2 && - abs(static_cast<int>(SkColorGetR(a) - SkColorGetR(b))) <= 2 && - abs(static_cast<int>(SkColorGetA(a) - SkColorGetA(b))) <= 2; -} - -inline bool MultipliedColorsClose(uint32_t a, uint32_t b) { - return ColorsClose(SkUnPreMultiply::PMColorToColor(a), - SkUnPreMultiply::PMColorToColor(b)); -} - -bool BitmapsClose(const SkBitmap& a, const SkBitmap& b) { - SkAutoLockPixels a_lock(a); - SkAutoLockPixels b_lock(b); - - for (int y = 0; y < a.height(); y++) { - for (int x = 0; x < a.width(); x++) { - SkColor a_pixel = *a.getAddr32(x, y); - SkColor b_pixel = *b.getAddr32(x, y); - if (!ColorsClose(a_pixel, b_pixel)) - return false; - } - } - return true; -} - -void FillDataToBitmap(int w, int h, SkBitmap* bmp) { - bmp->setConfig(SkBitmap::kARGB_8888_Config, w, h); - bmp->allocPixels(); - - unsigned char* src_data = - reinterpret_cast<unsigned char*>(bmp->getAddr32(0, 0)); - for (int i = 0; i < w * h; i++) { - src_data[i * 4 + 0] = static_cast<unsigned char>(i % 255); - src_data[i * 4 + 1] = static_cast<unsigned char>(i % 255); - src_data[i * 4 + 2] = static_cast<unsigned char>(i % 255); - src_data[i * 4 + 3] = static_cast<unsigned char>(i % 255); - } -} - -// The reference (i.e., old) implementation of |CreateHSLShiftedBitmap()|. -SkBitmap ReferenceCreateHSLShiftedBitmap( - const SkBitmap& bitmap, - color_utils::HSL hsl_shift) { - SkBitmap shifted; - shifted.setConfig(SkBitmap::kARGB_8888_Config, bitmap.width(), - bitmap.height(), 0); - shifted.allocPixels(); - shifted.eraseARGB(0, 0, 0, 0); - shifted.setIsOpaque(false); - - SkAutoLockPixels lock_bitmap(bitmap); - SkAutoLockPixels lock_shifted(shifted); - - // Loop through the pixels of the original bitmap. - for (int y = 0; y < bitmap.height(); ++y) { - SkPMColor* pixels = bitmap.getAddr32(0, y); - SkPMColor* tinted_pixels = shifted.getAddr32(0, y); - - for (int x = 0; x < bitmap.width(); ++x) { - tinted_pixels[x] = SkPreMultiplyColor(color_utils::HSLShift( - SkUnPreMultiply::PMColorToColor(pixels[x]), hsl_shift)); - } - } - - return shifted; -} - -} // namespace - -// Invert bitmap and verify the each pixel is inverted and the alpha value is -// not changed. -TEST(SkBitmapOperationsTest, CreateInvertedBitmap) { - int src_w = 16, src_h = 16; - SkBitmap src; - src.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); - src.allocPixels(); - - for (int y = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - int i = y * src_w + x; - *src.getAddr32(x, y) = - SkColorSetARGB((255 - i) % 255, i % 255, i * 4 % 255, 0); - } - } - - SkBitmap inverted = SkBitmapOperations::CreateInvertedBitmap(src); - SkAutoLockPixels src_lock(src); - SkAutoLockPixels inverted_lock(inverted); - - for (int y = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - int i = y * src_w + x; - EXPECT_EQ(static_cast<unsigned int>((255 - i) % 255), - SkColorGetA(*inverted.getAddr32(x, y))); - EXPECT_EQ(static_cast<unsigned int>(255 - (i % 255)), - SkColorGetR(*inverted.getAddr32(x, y))); - EXPECT_EQ(static_cast<unsigned int>(255 - (i * 4 % 255)), - SkColorGetG(*inverted.getAddr32(x, y))); - EXPECT_EQ(static_cast<unsigned int>(255), - SkColorGetB(*inverted.getAddr32(x, y))); - } - } -} - -// Blend two bitmaps together at 50% alpha and verify that the result -// is the middle-blend of the two. -TEST(SkBitmapOperationsTest, CreateBlendedBitmap) { - int src_w = 16, src_h = 16; - SkBitmap src_a; - src_a.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); - src_a.allocPixels(); - - SkBitmap src_b; - src_b.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); - src_b.allocPixels(); - - for (int y = 0, i = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - *src_a.getAddr32(x, y) = SkColorSetARGB(255, 0, i * 2 % 255, i % 255); - *src_b.getAddr32(x, y) = - SkColorSetARGB((255 - i) % 255, i % 255, i * 4 % 255, 0); - i++; - } - } - - // Shift to red. - SkBitmap blended = SkBitmapOperations::CreateBlendedBitmap( - src_a, src_b, 0.5); - SkAutoLockPixels srca_lock(src_a); - SkAutoLockPixels srcb_lock(src_b); - SkAutoLockPixels blended_lock(blended); - - for (int y = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - int i = y * src_w + x; - EXPECT_EQ(static_cast<unsigned int>((255 + ((255 - i) % 255)) / 2), - SkColorGetA(*blended.getAddr32(x, y))); - EXPECT_EQ(static_cast<unsigned int>(i % 255 / 2), - SkColorGetR(*blended.getAddr32(x, y))); - EXPECT_EQ((static_cast<unsigned int>((i * 2) % 255 + (i * 4) % 255) / 2), - SkColorGetG(*blended.getAddr32(x, y))); - EXPECT_EQ(static_cast<unsigned int>(i % 255 / 2), - SkColorGetB(*blended.getAddr32(x, y))); - } - } -} - -// Test our masking functions. -TEST(SkBitmapOperationsTest, CreateMaskedBitmap) { - int src_w = 16, src_h = 16; - - SkBitmap src; - FillDataToBitmap(src_w, src_h, &src); - - // Generate alpha mask - SkBitmap alpha; - alpha.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); - alpha.allocPixels(); - for (int y = 0, i = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - *alpha.getAddr32(x, y) = SkColorSetARGB((i + 128) % 255, - (i + 128) % 255, - (i + 64) % 255, - (i + 0) % 255); - i++; - } - } - - SkBitmap masked = SkBitmapOperations::CreateMaskedBitmap(src, alpha); - - SkAutoLockPixels src_lock(src); - SkAutoLockPixels alpha_lock(alpha); - SkAutoLockPixels masked_lock(masked); - for (int y = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - // Test that the alpha is equal. - SkColor src_pixel = SkUnPreMultiply::PMColorToColor(*src.getAddr32(x, y)); - SkColor alpha_pixel = - SkUnPreMultiply::PMColorToColor(*alpha.getAddr32(x, y)); - SkColor masked_pixel = *masked.getAddr32(x, y); - - int alpha_value = SkAlphaMul(SkColorGetA(src_pixel), - SkColorGetA(alpha_pixel)); - SkColor expected_pixel = SkColorSetARGB( - alpha_value, - SkAlphaMul(SkColorGetR(src_pixel), alpha_value), - SkAlphaMul(SkColorGetG(src_pixel), alpha_value), - SkAlphaMul(SkColorGetB(src_pixel), alpha_value)); - - EXPECT_TRUE(ColorsClose(expected_pixel, masked_pixel)); - } - } -} - -// Make sure that when shifting a bitmap without any shift parameters, -// the end result is close enough to the original (rounding errors -// notwithstanding). -TEST(SkBitmapOperationsTest, CreateHSLShiftedBitmapToSame) { - int src_w = 16, src_h = 16; - SkBitmap src; - src.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); - src.allocPixels(); - - for (int y = 0, i = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - *src.getAddr32(x, y) = SkPreMultiplyColor(SkColorSetARGB((i + 128) % 255, - (i + 128) % 255, (i + 64) % 255, (i + 0) % 255)); - i++; - } - } - - color_utils::HSL hsl = { -1, -1, -1 }; - SkBitmap shifted = ReferenceCreateHSLShiftedBitmap(src, hsl); - - SkAutoLockPixels src_lock(src); - SkAutoLockPixels shifted_lock(shifted); - - for (int y = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - SkColor src_pixel = *src.getAddr32(x, y); - SkColor shifted_pixel = *shifted.getAddr32(x, y); - EXPECT_TRUE(MultipliedColorsClose(src_pixel, shifted_pixel)) << - "source: (a,r,g,b) = (" << SkColorGetA(src_pixel) << "," << - SkColorGetR(src_pixel) << "," << - SkColorGetG(src_pixel) << "," << - SkColorGetB(src_pixel) << "); " << - "shifted: (a,r,g,b) = (" << SkColorGetA(shifted_pixel) << "," << - SkColorGetR(shifted_pixel) << "," << - SkColorGetG(shifted_pixel) << "," << - SkColorGetB(shifted_pixel) << ")"; - } - } -} - -// Shift a blue bitmap to red. -TEST(SkBitmapOperationsTest, CreateHSLShiftedBitmapHueOnly) { - int src_w = 16, src_h = 16; - SkBitmap src; - src.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); - src.allocPixels(); - - for (int y = 0, i = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - *src.getAddr32(x, y) = SkColorSetARGB(255, 0, 0, i % 255); - i++; - } - } - - // Shift to red. - color_utils::HSL hsl = { 0, -1, -1 }; - - SkBitmap shifted = SkBitmapOperations::CreateHSLShiftedBitmap(src, hsl); - - SkAutoLockPixels src_lock(src); - SkAutoLockPixels shifted_lock(shifted); - - for (int y = 0, i = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - EXPECT_TRUE(ColorsClose(*shifted.getAddr32(x, y), - SkColorSetARGB(255, i % 255, 0, 0))); - i++; - } - } -} - -// Validate HSL shift. -TEST(SkBitmapOperationsTest, ValidateHSLShift) { - // Note: 255/51 = 5 (exactly) => 6 including 0! - const int inc = 51; - const int dim = 255 / inc + 1; - SkBitmap src; - src.setConfig(SkBitmap::kARGB_8888_Config, dim*dim, dim*dim); - src.allocPixels(); - - for (int a = 0, y = 0; a <= 255; a += inc) { - for (int r = 0; r <= 255; r += inc, y++) { - for (int g = 0, x = 0; g <= 255; g += inc) { - for (int b = 0; b <= 255; b+= inc, x++) { - *src.getAddr32(x, y) = - SkPreMultiplyColor(SkColorSetARGB(a, r, g, b)); - } - } - } - } - - // Shhhh. The spec says I should set things to -1 for "no change", but - // actually -0.1 will do. Don't tell anyone I did this. - for (double h = -0.1; h <= 1.0001; h += 0.1) { - for (double s = -0.1; s <= 1.0001; s += 0.1) { - for (double l = -0.1; l <= 1.0001; l += 0.1) { - color_utils::HSL hsl = { h, s, l }; - SkBitmap ref_shifted = ReferenceCreateHSLShiftedBitmap(src, hsl); - SkBitmap shifted = SkBitmapOperations::CreateHSLShiftedBitmap(src, hsl); - EXPECT_TRUE(BitmapsClose(ref_shifted, shifted)) - << "h = " << h << ", s = " << s << ", l = " << l; - } - } - } -} - -// Test our cropping. -TEST(SkBitmapOperationsTest, CreateCroppedBitmap) { - int src_w = 16, src_h = 16; - SkBitmap src; - FillDataToBitmap(src_w, src_h, &src); - - SkBitmap cropped = SkBitmapOperations::CreateTiledBitmap(src, 4, 4, - 8, 8); - ASSERT_EQ(8, cropped.width()); - ASSERT_EQ(8, cropped.height()); - - SkAutoLockPixels src_lock(src); - SkAutoLockPixels cropped_lock(cropped); - for (int y = 4; y < 12; y++) { - for (int x = 4; x < 12; x++) { - EXPECT_EQ(*src.getAddr32(x, y), - *cropped.getAddr32(x - 4, y - 4)); - } - } -} - -// Test whether our cropping correctly wraps across image boundaries. -TEST(SkBitmapOperationsTest, CreateCroppedBitmapWrapping) { - int src_w = 16, src_h = 16; - SkBitmap src; - FillDataToBitmap(src_w, src_h, &src); - - SkBitmap cropped = SkBitmapOperations::CreateTiledBitmap( - src, src_w / 2, src_h / 2, src_w, src_h); - ASSERT_EQ(src_w, cropped.width()); - ASSERT_EQ(src_h, cropped.height()); - - SkAutoLockPixels src_lock(src); - SkAutoLockPixels cropped_lock(cropped); - for (int y = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - EXPECT_EQ(*src.getAddr32(x, y), - *cropped.getAddr32((x + src_w / 2) % src_w, - (y + src_h / 2) % src_h)); - } - } -} - -TEST(SkBitmapOperationsTest, DownsampleByTwo) { - // Use an odd-sized bitmap to make sure the edge cases where there isn't a - // 2x2 block of pixels is handled correctly. - // Here's the ARGB example - // - // 50% transparent green opaque 50% blue white - // 80008000 FF000080 FFFFFFFF - // - // 50% transparent red opaque 50% gray black - // 80800000 80808080 FF000000 - // - // black white 50% gray - // FF000000 FFFFFFFF FF808080 - // - // The result of this computation should be: - // A0404040 FF808080 - // FF808080 FF808080 - SkBitmap input; - input.setConfig(SkBitmap::kARGB_8888_Config, 3, 3); - input.allocPixels(); - - // The color order may be different, but we don't care (the channels are - // trated the same). - *input.getAddr32(0, 0) = 0x80008000; - *input.getAddr32(1, 0) = 0xFF000080; - *input.getAddr32(2, 0) = 0xFFFFFFFF; - *input.getAddr32(0, 1) = 0x80800000; - *input.getAddr32(1, 1) = 0x80808080; - *input.getAddr32(2, 1) = 0xFF000000; - *input.getAddr32(0, 2) = 0xFF000000; - *input.getAddr32(1, 2) = 0xFFFFFFFF; - *input.getAddr32(2, 2) = 0xFF808080; - - SkBitmap result = SkBitmapOperations::DownsampleByTwo(input); - EXPECT_EQ(2, result.width()); - EXPECT_EQ(2, result.height()); - - // Some of the values are off-by-one due to rounding. - SkAutoLockPixels lock(result); - EXPECT_EQ(0x9f404040, *result.getAddr32(0, 0)); - EXPECT_EQ(0xFF7f7f7f, *result.getAddr32(1, 0)); - EXPECT_EQ(0xFF7f7f7f, *result.getAddr32(0, 1)); - EXPECT_EQ(0xFF808080, *result.getAddr32(1, 1)); -} - -// Test edge cases for DownsampleByTwo. -TEST(SkBitmapOperationsTest, DownsampleByTwoSmall) { - SkPMColor reference = 0xFF4080FF; - - // Test a 1x1 bitmap. - SkBitmap one_by_one; - one_by_one.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); - one_by_one.allocPixels(); - *one_by_one.getAddr32(0, 0) = reference; - SkBitmap result = SkBitmapOperations::DownsampleByTwo(one_by_one); - SkAutoLockPixels lock1(result); - EXPECT_EQ(1, result.width()); - EXPECT_EQ(1, result.height()); - EXPECT_EQ(reference, *result.getAddr32(0, 0)); - - // Test an n by 1 bitmap. - SkBitmap one_by_n; - one_by_n.setConfig(SkBitmap::kARGB_8888_Config, 300, 1); - one_by_n.allocPixels(); - result = SkBitmapOperations::DownsampleByTwo(one_by_n); - SkAutoLockPixels lock2(result); - EXPECT_EQ(300, result.width()); - EXPECT_EQ(1, result.height()); - - // Test a 1 by n bitmap. - SkBitmap n_by_one; - n_by_one.setConfig(SkBitmap::kARGB_8888_Config, 1, 300); - n_by_one.allocPixels(); - result = SkBitmapOperations::DownsampleByTwo(n_by_one); - SkAutoLockPixels lock3(result); - EXPECT_EQ(1, result.width()); - EXPECT_EQ(300, result.height()); - - // Test an empty bitmap - SkBitmap empty; - result = SkBitmapOperations::DownsampleByTwo(empty); - EXPECT_TRUE(result.isNull()); - EXPECT_EQ(0, result.width()); - EXPECT_EQ(0, result.height()); -} - -// Here we assume DownsampleByTwo works correctly (it's tested above) and -// just make sure that the wrapper function does the right thing. -TEST(SkBitmapOperationsTest, DownsampleByTwoUntilSize) { - // First make sure a "too small" bitmap doesn't get modified at all. - SkBitmap too_small; - too_small.setConfig(SkBitmap::kARGB_8888_Config, 10, 10); - too_small.allocPixels(); - SkBitmap result = SkBitmapOperations::DownsampleByTwoUntilSize( - too_small, 16, 16); - EXPECT_EQ(10, result.width()); - EXPECT_EQ(10, result.height()); - - // Now make sure giving it a 0x0 target returns something reasonable. - result = SkBitmapOperations::DownsampleByTwoUntilSize(too_small, 0, 0); - EXPECT_EQ(1, result.width()); - EXPECT_EQ(1, result.height()); - - // Test multiple steps of downsampling. - SkBitmap large; - large.setConfig(SkBitmap::kARGB_8888_Config, 100, 43); - large.allocPixels(); - result = SkBitmapOperations::DownsampleByTwoUntilSize(large, 6, 6); - - // The result should be divided in half 100x43 -> 50x22 -> 25x11 - EXPECT_EQ(25, result.width()); - EXPECT_EQ(11, result.height()); -} - -TEST(SkBitmapOperationsTest, UnPreMultiply) { - SkBitmap input; - input.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); - input.allocPixels(); - - *input.getAddr32(0, 0) = 0x80000000; - *input.getAddr32(1, 0) = 0x80808080; - *input.getAddr32(0, 1) = 0xFF00CC88; - *input.getAddr32(1, 1) = 0x0000CC88; - - SkBitmap result = SkBitmapOperations::UnPreMultiply(input); - EXPECT_EQ(2, result.width()); - EXPECT_EQ(2, result.height()); - - SkAutoLockPixels lock(result); - EXPECT_EQ(0x80000000, *result.getAddr32(0, 0)); - EXPECT_EQ(0x80FFFFFF, *result.getAddr32(1, 0)); - EXPECT_EQ(0xFF00CC88, *result.getAddr32(0, 1)); - EXPECT_EQ(0x00000000u, *result.getAddr32(1, 1)); // "Division by zero". -} - -TEST(SkBitmapOperationsTest, CreateTransposedBtmap) { - SkBitmap input; - input.setConfig(SkBitmap::kARGB_8888_Config, 2, 3); - input.allocPixels(); - - for (int x = 0; x < input.width(); ++x) { - for (int y = 0; y < input.height(); ++y) { - *input.getAddr32(x, y) = x * input.width() + y; - } - } - - SkBitmap result = SkBitmapOperations::CreateTransposedBtmap(input); - EXPECT_EQ(3, result.width()); - EXPECT_EQ(2, result.height()); - - SkAutoLockPixels lock(result); - for (int x = 0; x < input.width(); ++x) { - for (int y = 0; y < input.height(); ++y) { - EXPECT_EQ(*input.getAddr32(x, y), *result.getAddr32(y, x)); - } - } -} diff --git a/gfx/skia_util.cc b/gfx/skia_util.cc deleted file mode 100644 index 865f8fda..0000000 --- a/gfx/skia_util.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/skia_util.h" - -#include "gfx/rect.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkColorPriv.h" -#include "third_party/skia/include/core/SkShader.h" -#include "third_party/skia/include/effects/SkGradientShader.h" - -namespace gfx { - -SkRect RectToSkRect(const gfx::Rect& rect) { - SkRect r; - r.set(SkIntToScalar(rect.x()), SkIntToScalar(rect.y()), - SkIntToScalar(rect.right()), SkIntToScalar(rect.bottom())); - return r; -} - -gfx::Rect SkRectToRect(const SkRect& rect) { - return gfx::Rect(SkScalarToFixed(rect.fLeft), - SkScalarToFixed(rect.fTop), - SkScalarToFixed(rect.width()), - SkScalarToFixed(rect.height())); -} - -SkShader* CreateGradientShader(int start_point, - int end_point, - SkColor start_color, - SkColor end_color) { - SkColor grad_colors[2] = { start_color, end_color}; - SkPoint grad_points[2]; - grad_points[0].set(SkIntToScalar(0), SkIntToScalar(start_point)); - grad_points[1].set(SkIntToScalar(0), SkIntToScalar(end_point)); - - return SkGradientShader::CreateLinear( - grad_points, grad_colors, NULL, 2, SkShader::kRepeat_TileMode); -} - -bool BitmapsAreEqual(const SkBitmap& bitmap1, const SkBitmap& bitmap2) { - void* addr1 = NULL; - void* addr2 = NULL; - size_t size1 = 0; - size_t size2 = 0; - - bitmap1.lockPixels(); - addr1 = bitmap1.getAddr32(0, 0); - size1 = bitmap1.getSize(); - bitmap1.unlockPixels(); - - bitmap2.lockPixels(); - addr2 = bitmap2.getAddr32(0, 0); - size2 = bitmap2.getSize(); - bitmap2.unlockPixels(); - - return (size1 == size2) && (0 == memcmp(addr1, addr2, bitmap1.getSize())); -} - -} // namespace gfx diff --git a/gfx/skia_util.h b/gfx/skia_util.h index 00a1d1c..1af4255 100644 --- a/gfx/skia_util.h +++ b/gfx/skia_util.h @@ -6,34 +6,7 @@ #define GFX_SKIA_UTIL_H_ #pragma once -#include "third_party/skia/include/core/SkColor.h" -#include "third_party/skia/include/core/SkRect.h" - -class SkBitmap; -class SkShader; - -namespace gfx { - -class Rect; - -// Convert between Skia and gfx rect types. -SkRect RectToSkRect(const gfx::Rect& rect); -gfx::Rect SkRectToRect(const SkRect& rect); - -// Creates a vertical gradient shader. The caller owns the shader. -// Example usage to avoid leaks: -// SkSafeUnref(paint.setShader(gfx::CreateGradientShader(0, 10, red, blue))); -// -// (The old shader in the paint, if any, needs to be freed, and SkSafeUnref will -// handle the NULL case.) -SkShader* CreateGradientShader(int start_point, - int end_point, - SkColor start_color, - SkColor end_color); - -// Returns true if the two bitmaps contain the same pixels. -bool BitmapsAreEqual(const SkBitmap& bitmap1, const SkBitmap& bitmap2); - -} // namespace gfx; +#include "ui/gfx/skia_util.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_SKIA_UTIL_H_ diff --git a/gfx/skia_utils_gtk.cc b/gfx/skia_utils_gtk.cc deleted file mode 100644 index 8ed4bec..0000000 --- a/gfx/skia_utils_gtk.cc +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/skia_utils_gtk.h" - -#include <gdk/gdkcolor.h> - -namespace gfx { - -const int kSkiaToGDKMultiplier = 257; - -// GDK_COLOR_RGB multiplies by 257 (= 0x10001) to distribute the bits evenly -// See: http://www.mindcontrol.org/~hplus/graphics/expand-bits.html -// To get back, we can just right shift by eight -// (or, formulated differently, i == (i*257)/256 for all i < 256). - -SkColor GdkColorToSkColor(GdkColor color) { - return SkColorSetRGB(color.red >> 8, color.green >> 8, color.blue >> 8); -} - -GdkColor SkColorToGdkColor(SkColor color) { - GdkColor gdk_color = { - 0, - SkColorGetR(color) * kSkiaToGDKMultiplier, - SkColorGetG(color) * kSkiaToGDKMultiplier, - SkColorGetB(color) * kSkiaToGDKMultiplier - }; - return gdk_color; -} - -} // namespace gfx diff --git a/gfx/skia_utils_gtk.h b/gfx/skia_utils_gtk.h index 1114908..f958340 100644 --- a/gfx/skia_utils_gtk.h +++ b/gfx/skia_utils_gtk.h @@ -6,18 +6,7 @@ #define APP_GFX_SKIA_UTILS_GTK_H_ #pragma once -#include "third_party/skia/include/core/SkColor.h" - -typedef struct _GdkColor GdkColor; - -namespace gfx { - -// Converts GdkColors to the ARGB layout Skia expects. -SkColor GdkColorToSkColor(GdkColor color); - -// Converts ARGB to GdkColor. -GdkColor SkColorToGdkColor(SkColor color); - -} // namespace gfx +#include "ui/gfx/skia_utils_gtk.h" +// TODO(sail): remove this file once all includes have been updated. #endif // APP_GFX_SKIA_UTILS_GTK_H_ diff --git a/gfx/test_suite.cc b/gfx/test_suite.cc deleted file mode 100644 index 02e1f7f..0000000 --- a/gfx/test_suite.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/test_suite.h" - -#include "gfx/gfx_paths.h" -#include "base/file_path.h" -#include "base/path_service.h" -#include "base/mac/scoped_nsautorelease_pool.h" - -#if defined(OS_MACOSX) -#include "base/mac/mac_util.h" -#endif - -GfxTestSuite::GfxTestSuite(int argc, char** argv) : TestSuite(argc, argv) {} - -void GfxTestSuite::Initialize() { - base::mac::ScopedNSAutoreleasePool autorelease_pool; - - TestSuite::Initialize(); - - gfx::RegisterPathProvider(); - -#if defined(OS_MACOSX) - // Look in the framework bundle for resources. - // TODO(port): make a resource bundle for non-app exes. What's done here - // isn't really right because this code needs to depend on chrome_dll - // being built. This is inappropriate in app. - FilePath path; - PathService::Get(base::DIR_EXE, &path); -#if defined(GOOGLE_CHROME_BUILD) - path = path.AppendASCII("Google Chrome Framework.framework"); -#elif defined(CHROMIUM_BUILD) - path = path.AppendASCII("Chromium Framework.framework"); -#else -#error Unknown branding -#endif - base::mac::SetOverrideAppBundlePath(path); -#endif // OS_MACOSX -} - -void GfxTestSuite::Shutdown() { -#if defined(OS_MACOSX) - base::mac::SetOverrideAppBundle(NULL); -#endif - TestSuite::Shutdown(); -} diff --git a/gfx/test_suite.h b/gfx/test_suite.h index 7c6ffbd..97c6a8f 100644 --- a/gfx/test_suite.h +++ b/gfx/test_suite.h @@ -6,19 +6,7 @@ #define GFX_TEST_SUITE_H_ #pragma once -#include <string> - -#include "base/test/test_suite.h" -#include "build/build_config.h" - -class GfxTestSuite : public base::TestSuite { - public: - GfxTestSuite(int argc, char** argv); - - protected: - // Overridden from base::TestSuite: - virtual void Initialize(); - virtual void Shutdown(); -}; +#include "ui/gfx/test_suite.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_TEST_SUITE_H_ diff --git a/gfx/win_util.cc b/gfx/win_util.cc deleted file mode 100644 index 9941a65..0000000 --- a/gfx/win_util.cc +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gfx/win_util.h" - -#include <windows.h> - -#include "base/win/windows_version.h" - -namespace { - -bool DynamicLibraryPresent(const wchar_t* lib_name) { - HINSTANCE lib = LoadLibrary(lib_name); - if (lib) { - FreeLibrary(lib); - return true; - } - return false; -} - -} // namespace - -namespace gfx { - -// Returns true if Direct2d is available, false otherwise. -bool Direct2dIsAvailable() { - static bool checked = false; - static bool available = false; - - if (!checked) { - base::win::Version version = base::win::GetVersion(); - if (version < base::win::VERSION_VISTA) - available = false; - else if (version >= base::win::VERSION_WIN7) - available = true; - else - available = DynamicLibraryPresent(L"d2d1.dll"); - checked = true; - } - return available; -} - -// Returns true if DirectWrite is available, false otherwise. -bool DirectWriteIsAvailable() { - static bool checked = false; - static bool available = false; - - if (!checked) { - base::win::Version version = base::win::GetVersion(); - if (version < base::win::VERSION_VISTA) - available = false; - else if (version >= base::win::VERSION_WIN7) - available = true; - else - available = DynamicLibraryPresent(L"dwrite.dll"); - checked = true; - } - return available; -} - -} // namespace gfx - diff --git a/gfx/win_util.h b/gfx/win_util.h index 3daa00f..fc5cc0f 100644 --- a/gfx/win_util.h +++ b/gfx/win_util.h @@ -6,15 +6,8 @@ #define GFX_WIN_UTIL_H_ #pragma once -namespace gfx { - -// Returns true if Direct2d is available, false otherwise. -bool Direct2dIsAvailable(); - -// Returns true if DirectWrite is available, false otherwise. -bool DirectWriteIsAvailable(); - -} // namespace gfx; +#include "ui/gfx/win_util.h" +// TODO(sail): remove this file once all includes have been updated. #endif // GFX_WIN_UTIL_H_ |