1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/gfx/skia_util.h"
7 #include "third_party/skia/include/core/SkBitmap.h"
8 #include "third_party/skia/include/core/SkColorFilter.h"
9 #include "third_party/skia/include/core/SkColorPriv.h"
10 #include "third_party/skia/include/core/SkUnPreMultiply.h"
11 #include "third_party/skia/include/effects/SkBlurMaskFilter.h"
12 #include "third_party/skia/include/effects/SkGradientShader.h"
13 #include "third_party/skia/include/effects/SkLayerDrawLooper.h"
14 #include "ui/gfx/image/image_skia_rep.h"
15 #include "ui/gfx/rect.h"
16 #include "ui/gfx/rect_f.h"
17 #include "ui/gfx/shadow_value.h"
21 SkRect
RectToSkRect(const Rect
& rect
) {
23 r
.iset(rect
.x(), rect
.y(), rect
.right(), rect
.bottom());
27 SkIRect
RectToSkIRect(const Rect
& rect
) {
28 return SkIRect::MakeXYWH(rect
.x(), rect
.y(), rect
.width(), rect
.height());
31 Rect
SkIRectToRect(const SkIRect
& rect
) {
32 return Rect(rect
.x(), rect
.y(), rect
.width(), rect
.height());
35 SkRect
RectFToSkRect(const RectF
& rect
) {
36 return SkRect::MakeXYWH(SkFloatToScalar(rect
.x()),
37 SkFloatToScalar(rect
.y()),
38 SkFloatToScalar(rect
.width()),
39 SkFloatToScalar(rect
.height()));
42 RectF
SkRectToRectF(const SkRect
& rect
) {
43 return RectF(SkScalarToFloat(rect
.x()),
44 SkScalarToFloat(rect
.y()),
45 SkScalarToFloat(rect
.width()),
46 SkScalarToFloat(rect
.height()));
50 skia::RefPtr
<SkShader
> CreateImageRepShader(const gfx::ImageSkiaRep
& image_rep
,
51 SkShader::TileMode tile_mode
,
52 const SkMatrix
& local_matrix
) {
53 skia::RefPtr
<SkShader
> shader
= skia::AdoptRef(SkShader::CreateBitmapShader(
54 image_rep
.sk_bitmap(), tile_mode
, tile_mode
));
55 SkScalar scale_x
= local_matrix
.getScaleX();
56 SkScalar scale_y
= local_matrix
.getScaleY();
57 SkScalar bitmap_scale
= SkFloatToScalar(image_rep
.GetScale());
59 // Unscale matrix by |bitmap_scale| such that the bitmap is drawn at the
61 // Convert skew and translation to pixel coordinates.
62 // Thus, for |bitmap_scale| = 2:
63 // x scale = 2, x translation = 1 DIP,
64 // should be converted to
65 // x scale = 1, x translation = 2 pixels.
66 SkMatrix shader_scale
= local_matrix
;
67 shader_scale
.preScale(bitmap_scale
, bitmap_scale
);
68 shader_scale
.setScaleX(SkScalarDiv(scale_x
, bitmap_scale
));
69 shader_scale
.setScaleY(SkScalarDiv(scale_y
, bitmap_scale
));
71 shader
->setLocalMatrix(shader_scale
);
75 skia::RefPtr
<SkShader
> CreateGradientShader(int start_point
,
79 SkColor grad_colors
[2] = { start_color
, end_color
};
80 SkPoint grad_points
[2];
81 grad_points
[0].iset(0, start_point
);
82 grad_points
[1].iset(0, end_point
);
84 return skia::AdoptRef(SkGradientShader::CreateLinear(
85 grad_points
, grad_colors
, NULL
, 2, SkShader::kRepeat_TileMode
));
88 skia::RefPtr
<SkDrawLooper
> CreateShadowDrawLooper(
89 const std::vector
<ShadowValue
>& shadows
) {
91 return skia::RefPtr
<SkDrawLooper
>();
93 skia::RefPtr
<SkLayerDrawLooper
> looper
=
94 skia::AdoptRef(new SkLayerDrawLooper
);
96 looper
->addLayer(); // top layer of the original.
98 SkLayerDrawLooper::LayerInfo layer_info
;
99 layer_info
.fPaintBits
|= SkLayerDrawLooper::kMaskFilter_Bit
;
100 layer_info
.fPaintBits
|= SkLayerDrawLooper::kColorFilter_Bit
;
101 layer_info
.fColorMode
= SkXfermode::kSrc_Mode
;
103 for (size_t i
= 0; i
< shadows
.size(); ++i
) {
104 const ShadowValue
& shadow
= shadows
[i
];
106 layer_info
.fOffset
.set(SkIntToScalar(shadow
.x()),
107 SkIntToScalar(shadow
.y()));
109 // SkBlurMaskFilter's blur radius defines the range to extend the blur from
110 // original mask, which is half of blur amount as defined in ShadowValue.
111 skia::RefPtr
<SkMaskFilter
> blur_mask
= skia::AdoptRef(
112 SkBlurMaskFilter::Create(SkDoubleToScalar(shadow
.blur() / 2),
113 SkBlurMaskFilter::kNormal_BlurStyle
,
114 SkBlurMaskFilter::kHighQuality_BlurFlag
));
115 skia::RefPtr
<SkColorFilter
> color_filter
= skia::AdoptRef(
116 SkColorFilter::CreateModeFilter(shadow
.color(),
117 SkXfermode::kSrcIn_Mode
));
119 SkPaint
* paint
= looper
->addLayer(layer_info
);
120 paint
->setMaskFilter(blur_mask
.get());
121 paint
->setColorFilter(color_filter
.get());
127 bool BitmapsAreEqual(const SkBitmap
& bitmap1
, const SkBitmap
& bitmap2
) {
133 bitmap1
.lockPixels();
134 addr1
= bitmap1
.getAddr32(0, 0);
135 size1
= bitmap1
.getSize();
136 bitmap1
.unlockPixels();
138 bitmap2
.lockPixels();
139 addr2
= bitmap2
.getAddr32(0, 0);
140 size2
= bitmap2
.getSize();
141 bitmap2
.unlockPixels();
143 return (size1
== size2
) && (0 == memcmp(addr1
, addr2
, bitmap1
.getSize()));
146 void ConvertSkiaToRGBA(const unsigned char* skia
,
148 unsigned char* rgba
) {
149 int total_length
= pixel_width
* 4;
150 for (int i
= 0; i
< total_length
; i
+= 4) {
151 const uint32_t pixel_in
= *reinterpret_cast<const uint32_t*>(&skia
[i
]);
153 // Pack the components here.
154 int alpha
= SkGetPackedA32(pixel_in
);
155 if (alpha
!= 0 && alpha
!= 255) {
156 SkColor unmultiplied
= SkUnPreMultiply::PMColorToColor(pixel_in
);
157 rgba
[i
+ 0] = SkColorGetR(unmultiplied
);
158 rgba
[i
+ 1] = SkColorGetG(unmultiplied
);
159 rgba
[i
+ 2] = SkColorGetB(unmultiplied
);
162 rgba
[i
+ 0] = SkGetPackedR32(pixel_in
);
163 rgba
[i
+ 1] = SkGetPackedG32(pixel_in
);
164 rgba
[i
+ 2] = SkGetPackedB32(pixel_in
);