Commit 831d9ba7 authored by oshima@chromium.org's avatar oshima@chromium.org

Make tab/tabstrip high density compatible

added ImageSkiaOperations and replaced Bitmap with ImageSkiaRep/ImagSkia.

BUG=122992
TEST=manual

Review URL: https://chromiumcodereview.appspot.com/10704113

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145976 0039d316-1c4b-4281-b951-d872f2087c98
parent c192ea0e
......@@ -23,8 +23,8 @@
#include "ui/gfx/canvas.h"
#include "ui/gfx/favicon_size.h"
#include "ui/gfx/font.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/path.h"
#include "ui/gfx/skbitmap_operations.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/widget/tooltip_manager.h"
#include "ui/views/widget/widget.h"
......@@ -563,13 +563,13 @@ void Tab::PaintTabBackground(gfx::Canvas* canvas) {
void Tab::PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas) {
// Render the inactive tab background. We'll use this for clipping.
gfx::Canvas background_canvas(size(), false);
gfx::Canvas background_canvas(size(), canvas->scale_factor(), false);
PaintInactiveTabBackground(&background_canvas);
gfx::ImageSkia background_image = background_canvas.ExtractBitmap();
gfx::ImageSkia background_image(background_canvas.ExtractImageSkiaRep());
// Draw a radial gradient to hover_canvas.
gfx::Canvas hover_canvas(size(), false);
gfx::Canvas hover_canvas(size(), canvas->scale_factor(), false);
int radius = kMiniTitleChangeGradientRadius;
int x0 = width() + radius - kMiniTitleChangeInitialXOffset;
int x1 = radius;
......@@ -595,8 +595,8 @@ void Tab::PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas) {
paint);
// Draw the radial gradient clipped to the background into hover_image.
gfx::ImageSkia hover_image = SkBitmapOperations::CreateMaskedBitmap(
hover_canvas.ExtractBitmap(), background_image);
gfx::ImageSkia hover_image = gfx::ImageSkiaOperations::CreateMaskedImage(
gfx::ImageSkia(hover_canvas.ExtractImageSkiaRep()), background_image);
// Draw the tab background to the canvas.
canvas->DrawImageInt(background_image, 0, 0);
......@@ -642,25 +642,25 @@ void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) {
// We need a gfx::Canvas object to be able to extract the image from.
// We draw everything to this canvas and then output it to the canvas
// parameter in addition to using it to mask the hover glow if needed.
gfx::Canvas background_canvas(size(), false);
gfx::Canvas background_canvas(size(), canvas->scale_factor(), false);
// Draw left edge. Don't draw over the toolbar, as we're not the foreground
// tab.
gfx::ImageSkia tab_l = SkBitmapOperations::CreateTiledBitmap(
gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage(
*tab_bg, offset, bg_offset_y, tab_image->l_width, height());
gfx::ImageSkia theme_l =
SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l);
gfx::ImageSkiaOperations::CreateMaskedImage(tab_l, *alpha->image_l);
background_canvas.DrawImageInt(theme_l,
0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap,
0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap,
false);
// Draw right edge. Again, don't draw over the toolbar.
gfx::ImageSkia tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg,
gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage(*tab_bg,
offset + width() - tab_image->r_width, bg_offset_y,
tab_image->r_width, height());
gfx::ImageSkia theme_r =
SkBitmapOperations::CreateMaskedBitmap(tab_r, *alpha->image_r);
gfx::ImageSkiaOperations::CreateMaskedImage(tab_r, *alpha->image_r);
background_canvas.DrawImageInt(theme_r,
0, 0, theme_r.width(), theme_r.height() - kToolbarOverlap,
width() - theme_r.width(), 0, theme_r.width(),
......@@ -677,11 +677,12 @@ void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) {
width() - tab_image->l_width - tab_image->r_width,
height() - drop_shadow_height() - kToolbarOverlap - tab_image->y_offset);
canvas->DrawImageInt(background_canvas.ExtractBitmap(), 0, 0);
canvas->DrawImageInt(
gfx::ImageSkia(background_canvas.ExtractImageSkiaRep()), 0, 0);
if (!GetThemeProvider()->HasCustomImage(tab_id) &&
hover_controller().ShouldDraw()) {
hover_controller().Draw(canvas, background_canvas.ExtractBitmap());
hover_controller().Draw(canvas, background_canvas.ExtractImageSkiaRep());
}
// Now draw the highlights/shadows around the tab edge.
......@@ -707,17 +708,18 @@ void Tab::PaintActiveTabBackground(gfx::Canvas* canvas,
TabImage* alpha = &tab_alpha_;
// Draw left edge.
gfx::ImageSkia tab_l = SkBitmapOperations::CreateTiledBitmap(
gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage(
*tab_background, offset, 0, tab_image->l_width, height());
gfx::ImageSkia theme_l =
SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l);
gfx::ImageSkiaOperations::CreateMaskedImage(tab_l, *alpha->image_l);
canvas->DrawImageInt(theme_l, 0, 0);
// Draw right edge.
gfx::ImageSkia tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_background,
gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage(
*tab_background,
offset + width() - tab_image->r_width, 0, tab_image->r_width, height());
gfx::ImageSkia theme_r =
SkBitmapOperations::CreateMaskedBitmap(tab_r, *alpha->image_r);
gfx::ImageSkiaOperations::CreateMaskedImage(tab_r, *alpha->image_r);
canvas->DrawImageInt(theme_r, width() - tab_image->r_width, 0);
// Draw center. Instead of masking out the top portion we simply skip over it
......
......@@ -39,10 +39,11 @@
#include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/path.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/size.h"
#include "ui/gfx/skbitmap_operations.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/mouse_watcher_view_host.h"
#include "ui/views/view_model_utils.h"
......@@ -302,9 +303,11 @@ class NewTabButton : public views::ImageButton {
private:
bool ShouldUseNativeFrame() const;
SkBitmap GetBackgroundBitmap(views::CustomButton::ButtonState state) const;
SkBitmap GetBitmapForState(views::CustomButton::ButtonState state) const;
SkBitmap GetBitmap() const;
gfx::ImageSkia GetBackgroundImage(views::CustomButton::ButtonState state,
ui::ScaleFactor scale_factor) const;
gfx::ImageSkia GetImageForState(views::CustomButton::ButtonState state,
ui::ScaleFactor scale_factor) const;
gfx::ImageSkia GetImage(ui::ScaleFactor scale_factor) const;
// Tab strip that contains this button.
TabStrip* tab_strip_;
......@@ -372,7 +375,7 @@ ui::GestureStatus NewTabButton::OnGestureEvent(
}
void NewTabButton::OnPaint(gfx::Canvas* canvas) {
SkBitmap image = GetBitmap();
gfx::ImageSkia image = GetImage(canvas->scale_factor());
canvas->DrawImageInt(image, 0, height() - image.height());
}
......@@ -381,8 +384,9 @@ bool NewTabButton::ShouldUseNativeFrame() const {
GetWidget()->GetTopLevelWidget()->ShouldUseNativeFrame();
}
SkBitmap NewTabButton::GetBackgroundBitmap(
views::CustomButton::ButtonState state) const {
gfx::ImageSkia NewTabButton::GetBackgroundImage(
views::CustomButton::ButtonState state,
ui::ScaleFactor scale_factor) const {
int background_id = 0;
if (ShouldUseNativeFrame()) {
background_id = IDR_THEME_TAB_BACKGROUND_V;
......@@ -409,7 +413,7 @@ SkBitmap NewTabButton::GetBackgroundBitmap(
GetThemeProvider()->GetImageSkiaNamed(IDR_NEWTAB_BUTTON_MASK);
int height = mask->height();
int width = mask->width();
gfx::Canvas canvas(gfx::Size(width, height), false);
gfx::Canvas canvas(gfx::Size(width, height), scale_factor, false);
// For custom images the background starts at the top of the tab strip.
// Otherwise the background starts at the top of the frame.
......@@ -432,11 +436,13 @@ SkBitmap NewTabButton::GetBackgroundBitmap(
if (state == views::CustomButton::BS_HOT)
canvas.FillRect(gfx::Rect(size()), SkColorSetARGB(64, 255, 255, 255));
return SkBitmapOperations::CreateMaskedBitmap(canvas.ExtractBitmap(), *mask);
return gfx::ImageSkiaOperations::CreateMaskedImage(
gfx::ImageSkia(canvas.ExtractImageSkiaRep()), *mask);
}
SkBitmap NewTabButton::GetBitmapForState(
views::CustomButton::ButtonState state) const {
gfx::ImageSkia NewTabButton::GetImageForState(
views::CustomButton::ButtonState state,
ui::ScaleFactor scale_factor) const {
int overlay_id = 0;
// The new tab button field trial will get created in variations_service.cc
// through the variations server.
......@@ -450,8 +456,9 @@ SkBitmap NewTabButton::GetBitmapForState(
}
gfx::ImageSkia* overlay = GetThemeProvider()->GetImageSkiaNamed(overlay_id);
gfx::Canvas canvas(gfx::Size(overlay->width(), overlay->height()), false);
canvas.DrawImageInt(GetBackgroundBitmap(state), 0, 0);
gfx::Canvas canvas(
gfx::Size(overlay->width(), overlay->height()), scale_factor, false);
canvas.DrawImageInt(GetBackgroundImage(state, scale_factor), 0, 0);
// Draw the button border with a slight alpha.
const int kNativeFrameOverlayAlpha = 178;
......@@ -461,15 +468,15 @@ SkBitmap NewTabButton::GetBitmapForState(
canvas.DrawImageInt(*overlay, 0, 0);
canvas.Restore();
return canvas.ExtractBitmap();
return gfx::ImageSkia(canvas.ExtractImageSkiaRep());
}
SkBitmap NewTabButton::GetBitmap() const {
gfx::ImageSkia NewTabButton::GetImage(ui::ScaleFactor scale_factor) const {
if (!hover_animation_->is_animating())
return GetBitmapForState(state());
return SkBitmapOperations::CreateBlendedBitmap(
GetBitmapForState(views::CustomButton::BS_NORMAL),
GetBitmapForState(views::CustomButton::BS_HOT),
return GetImageForState(state(), scale_factor);
return gfx::ImageSkiaOperations::CreateBlendedImage(
GetImageForState(views::CustomButton::BS_NORMAL, scale_factor),
GetImageForState(views::CustomButton::BS_HOT, scale_factor),
hover_animation_->GetCurrentValue());
}
......
......@@ -6,6 +6,11 @@
namespace switches {
// Whether or not ImageSkiaOperations methods can scale one of images
// if they don't have the same scale factor.
const char kDisableScalingInImageSkiaOperations[] =
"disable-scaling-in-image-skia-operations";
// Let text glyphs have X-positions that aren't snapped to the pixel grid.
const char kEnableTextSubpixelPositioning[] =
"enable-text-subpixel-positioning";
......
......@@ -13,6 +13,7 @@
namespace switches {
UI_EXPORT extern const char kDisableScalingInImageSkiaOperations[];
UI_EXPORT extern const char kEnableTextSubpixelPositioning[];
UI_EXPORT extern const char kEnableTouchCalibration[];
UI_EXPORT extern const char kEnableTouchEvents[];
......
// Copyright (c) 2012 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 "ui/gfx/image/image_skia_operations.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "skia/ext/platform_canvas.h"
#include "ui/base/layout.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "ui/gfx/image/image_skia_source.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#include "ui/gfx/skbitmap_operations.h"
#include "ui/gfx/skia_util.h"
namespace gfx {
namespace {
bool ScalingEnabled() {
static bool scale_images = !CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableScalingInImageSkiaOperations);
return scale_images;
}
// Creates 2x scaled image of the give |source|.
ImageSkiaRep Create2XImageSkiaRep(const ImageSkiaRep& source) {
gfx::Size size(source.GetWidth() * 2.0f, source.GetHeight() * 2.0f);
skia::PlatformCanvas canvas(size.width(), size.height(), false);
SkRect resized_bounds = RectToSkRect(gfx::Rect(size));
canvas.drawBitmapRect(source.sk_bitmap(), NULL, resized_bounds);
SkBitmap resized_bitmap = canvas.getDevice()->accessBitmap(false);
return ImageSkiaRep(resized_bitmap, ui::SCALE_FACTOR_200P);
}
// A utility function to synchronize the scale factor of the two images.
// When the command line option "--disable-scaling-in-image-skia-operation"
// is provided, this function will fail if the scale factors of the two images
// are different. This assumes that the platform only supports
// 1x and 2x scale factors.
// TODO(oshima): Remove and replace this with plain CHECK once
// 2x images for all resources are provided.
void MatchScale(ImageSkiaRep* first, ImageSkiaRep* second) {
if (first->scale_factor() != second->scale_factor()) {
CHECK(ScalingEnabled());
ImageSkiaRep* target = NULL;
if (first->scale_factor() == ui::SCALE_FACTOR_100P) {
target = first;
} else {
target = second;
}
*target = Create2XImageSkiaRep(*target);
}
}
class BlendingImageSource : public gfx::ImageSkiaSource {
public:
BlendingImageSource(const ImageSkia& first,
const ImageSkia& second,
double alpha)
: first_(first),
second_(second),
alpha_(alpha) {
}
// gfx::ImageSkiaSource overrides:
virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE {
ImageSkiaRep first_rep = first_.GetRepresentation(scale_factor);
ImageSkiaRep second_rep = second_.GetRepresentation(scale_factor);
MatchScale(&first_rep, &second_rep);
SkBitmap blended = SkBitmapOperations::CreateBlendedBitmap(
first_rep.sk_bitmap(), second_rep.sk_bitmap(), alpha_);
return ImageSkiaRep(blended, first_rep.scale_factor());
}
private:
const ImageSkia first_;
const ImageSkia second_;
double alpha_;
DISALLOW_COPY_AND_ASSIGN(BlendingImageSource);
};
class MaskedImageSource : public gfx::ImageSkiaSource {
public:
MaskedImageSource(const ImageSkia& rgb, const ImageSkia& alpha)
: rgb_(rgb),
alpha_(alpha) {
}
// gfx::ImageSkiaSource overrides:
virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE {
ImageSkiaRep rgb_rep = rgb_.GetRepresentation(scale_factor);
ImageSkiaRep alpha_rep = alpha_.GetRepresentation(scale_factor);
MatchScale(&rgb_rep, &alpha_rep);
return ImageSkiaRep(SkBitmapOperations::CreateMaskedBitmap(
rgb_rep.sk_bitmap(), alpha_rep.sk_bitmap()),
rgb_rep.scale_factor());
}
private:
const ImageSkia rgb_;
const ImageSkia alpha_;
DISALLOW_COPY_AND_ASSIGN(MaskedImageSource);
};
class TiledImageSource : public gfx::ImageSkiaSource {
public:
TiledImageSource(const ImageSkia& source,
int src_x, int src_y,
int dst_w, int dst_h)
: source_(source),
src_x_(src_x),
src_y_(src_y),
dst_w_(dst_w),
dst_h_(dst_h) {
}
// gfx::ImageSkiaSource overrides:
virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE {
ImageSkiaRep source_rep = source_.GetRepresentation(scale_factor);
float scale = ui::GetScaleFactorScale(source_rep.scale_factor());
return ImageSkiaRep(
SkBitmapOperations::CreateTiledBitmap(
source_rep.sk_bitmap(),
src_x_ * scale, src_y_ * scale, dst_w_ * scale, dst_h_ * scale),
source_rep.scale_factor());
}
private:
const ImageSkia& source_;
const int src_x_;
const int src_y_;
const int dst_w_;
const int dst_h_;
DISALLOW_COPY_AND_ASSIGN(TiledImageSource);
};
} // namespace;
// static
ImageSkia ImageSkiaOperations::CreateBlendedImage(const ImageSkia& first,
const ImageSkia& second,
double alpha) {
return ImageSkia(new BlendingImageSource(first, second, alpha), first.size());
}
// static
ImageSkia ImageSkiaOperations::CreateMaskedImage(const ImageSkia& rgb,
const ImageSkia& alpha) {
return ImageSkia(new MaskedImageSource(rgb, alpha), rgb.size());
}
// static
ImageSkia ImageSkiaOperations::CreateTiledImage(const ImageSkia& source,
int src_x, int src_y,
int dst_w, int dst_h) {
return ImageSkia(new TiledImageSource(source, src_x, src_y, dst_w, dst_h),
gfx::Size(dst_w, dst_h));
}
} // namespace gfx
// Copyright (c) 2012 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.
#ifndef UI_GFX_IMAGESKIA_OPERATIONS_H_
#define UI_GFX_IMAGESKIA_OPERATIONS_H_
#pragma once
#include "base/gtest_prod_util.h"
#include "ui/base/ui_export.h"
namespace gfx {
class ImageSkia;
class UI_EXPORT ImageSkiaOperations {
public:
// Create an image that is a blend of two others. The alpha argument
// specifies the opacity of the second imag. The provided image must
// use the kARGB_8888_Config config and be of equal dimensions.
static ImageSkia CreateBlendedImage(const ImageSkia& first,
const ImageSkia& second,
double alpha);
// Create an image that is the original image masked out by the mask defined
// in the alpha image. The images must use the kARGB_8888_Config config and
// be of equal dimensions.
static ImageSkia CreateMaskedImage(const ImageSkia& first,
const ImageSkia& alpha);
// Create an image that is cropped from another image. This is special
// because it tiles the original image, so your coordinates can extend
// outside the bounds of the original image.
static ImageSkia CreateTiledImage(const ImageSkia& image,
int src_x, int src_y,
int dst_w, int dst_h);
private:
ImageSkiaOperations(); // Class for scoping only.
};
}
#endif // UI_GFX_IMAGESKIA_OPERATIONS_H_
......@@ -350,6 +350,8 @@
'gfx/image/image.h',
'gfx/image/image_skia.cc',
'gfx/image/image_skia.h',
'gfx/image/image_skia_operations.cc',
'gfx/image/image_skia_operations.h',
'gfx/image/image_skia_rep.cc',
'gfx/image/image_skia_rep.h',
'gfx/image/image_skia_source.h',
......
......@@ -7,7 +7,7 @@
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/skbitmap_operations.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/views/view.h"
namespace views {
......@@ -70,6 +70,7 @@ void GlowHoverController::Draw(gfx::Canvas* canvas,
// Draw a radial gradient to hover_canvas.
gfx::Canvas hover_canvas(gfx::Size(mask_image.width(), mask_image.height()),
canvas->scale_factor(),
false);
// Draw a radial gradient to hover_canvas.
......@@ -96,8 +97,8 @@ void GlowHoverController::Draw(gfx::Canvas* canvas,
location_.y() - radius,
radius * 2, radius * 2), paint);
}
gfx::ImageSkia result = SkBitmapOperations::CreateMaskedBitmap(
hover_canvas.ExtractBitmap(), mask_image);
gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage(
gfx::ImageSkia(hover_canvas.ExtractImageSkiaRep()), mask_image);
canvas->DrawImageInt(result, (view_->width() - mask_image.width()) / 2,
(view_->height() - mask_image.height()) / 2);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment