Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: gfx/canvas_direct2d.cc

Issue 6246027: Move src/gfx/ to src/ui/gfx... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gfx/canvas_direct2d.h ('k') | gfx/canvas_direct2d_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gfx/canvas_direct2d.h"
6
7 #include "base/scoped_ptr.h"
8 #include "gfx/brush.h"
9 #include "gfx/rect.h"
10
11 namespace {
12
13 // Converts a SkColor to a ColorF.
14 D2D1_COLOR_F SkColorToColorF(SkColor color) {
15 return D2D1::ColorF(static_cast<float>(SkColorGetR(color)) / 0xFF,
16 static_cast<float>(SkColorGetG(color)) / 0xFF,
17 static_cast<float>(SkColorGetB(color)) / 0xFF,
18 static_cast<float>(SkColorGetA(color)) / 0xFF);
19 }
20
21 D2D1_RECT_F RectToRectF(int x, int y, int w, int h) {
22 return D2D1::RectF(static_cast<float>(x), static_cast<float>(y),
23 static_cast<float>(x + w), static_cast<float>(y + h));
24 }
25
26 D2D1_RECT_F RectToRectF(const gfx::Rect& rect) {
27 return RectToRectF(rect.x(), rect.y(), rect.width(), rect.height());
28 }
29
30 D2D1_POINT_2F PointToPoint2F(int x, int y) {
31 return D2D1::Point2F(static_cast<float>(x), static_cast<float>(y));
32 }
33
34 D2D1_BITMAP_INTERPOLATION_MODE FilterToInterpolationMode(bool filter) {
35 return filter ? D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
36 : D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
37 }
38
39 // Creates a Direct2D bitmap object from the contents of a SkBitmap. The caller
40 // is responsible for releasing this object.
41 ID2D1Bitmap* CreateD2D1BitmapFromSkBitmap(ID2D1RenderTarget* render_target,
42 const SkBitmap& bitmap) {
43 ID2D1Bitmap* d2d1_bitmap = NULL;
44 HRESULT hr = render_target->CreateBitmap(
45 D2D1::SizeU(bitmap.width(), bitmap.height()),
46 NULL,
47 NULL,
48 D2D1::BitmapProperties(
49 D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
50 D2D1_ALPHA_MODE_IGNORE)),
51 &d2d1_bitmap);
52 if (FAILED(hr))
53 return NULL;
54 bitmap.lockPixels();
55 d2d1_bitmap->CopyFromMemory(NULL, bitmap.getPixels(), bitmap.rowBytes());
56 bitmap.unlockPixels();
57 return d2d1_bitmap;
58 }
59
60 // Creates a Direct2D bitmap brush from the contents of a SkBitmap. The caller
61 // is responsible for releasing this object.
62 ID2D1Brush* CreateD2D1BrushFromSkBitmap(ID2D1RenderTarget* render_target,
63 const SkBitmap& bitmap,
64 D2D1_EXTEND_MODE extend_mode_x,
65 D2D1_EXTEND_MODE extend_mode_y) {
66 ScopedComPtr<ID2D1Bitmap> d2d1_bitmap(
67 CreateD2D1BitmapFromSkBitmap(render_target, bitmap));
68
69 ID2D1BitmapBrush* brush = NULL;
70 render_target->CreateBitmapBrush(
71 d2d1_bitmap,
72 D2D1::BitmapBrushProperties(extend_mode_x, extend_mode_y),
73 D2D1::BrushProperties(),
74 &brush);
75 return brush;
76 }
77
78 // A platform wrapper for a Direct2D brush that makes sure the underlying
79 // ID2D1Brush COM object is released when this object is destroyed.
80 class Direct2DBrush : public gfx::Brush {
81 public:
82 explicit Direct2DBrush(ID2D1Brush* brush) : brush_(brush) {
83 }
84
85 ID2D1Brush* brush() const { return brush_.get(); }
86
87 private:
88 ScopedComPtr<ID2D1Brush> brush_;
89
90 DISALLOW_COPY_AND_ASSIGN(Direct2DBrush);
91 };
92
93
94 } // namespace
95
96 namespace gfx {
97
98 // static
99 ID2D1Factory* CanvasDirect2D::d2d1_factory_ = NULL;
100
101 ////////////////////////////////////////////////////////////////////////////////
102 // CanvasDirect2D, public:
103
104 CanvasDirect2D::CanvasDirect2D(ID2D1RenderTarget* rt) : rt_(rt) {
105 // A RenderState entry is pushed onto the stack to track the clip count prior
106 // to any calls to Save*().
107 state_.push(RenderState());
108 rt_->BeginDraw();
109 }
110
111 CanvasDirect2D::~CanvasDirect2D() {
112 // Unwind any clips that were pushed outside of any Save*()/Restore() pairs.
113 int clip_count = state_.top().clip_count;
114 for (int i = 0; i < clip_count; ++i)
115 rt_->PopAxisAlignedClip();
116 rt_->EndDraw();
117 }
118
119 // static
120 ID2D1Factory* CanvasDirect2D::GetD2D1Factory() {
121 if (!d2d1_factory_)
122 D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &d2d1_factory_);
123 return d2d1_factory_;
124 }
125
126 ////////////////////////////////////////////////////////////////////////////////
127 // CanvasDirect2D, Canvas implementation:
128
129 void CanvasDirect2D::Save() {
130 SaveInternal(NULL);
131 }
132
133 void CanvasDirect2D::SaveLayerAlpha(uint8 alpha) {
134 SaveLayerAlpha(alpha, gfx::Rect());
135 }
136
137 void CanvasDirect2D::SaveLayerAlpha(uint8 alpha,
138 const gfx::Rect& layer_bounds) {
139 D2D1_RECT_F bounds = D2D1::InfiniteRect();
140 if (!layer_bounds.IsEmpty())
141 bounds = RectToRectF(layer_bounds);
142 ID2D1Layer* layer = NULL;
143 HRESULT hr = rt_->CreateLayer(NULL, &layer);
144 if (SUCCEEDED(hr)) {
145 rt_->PushLayer(D2D1::LayerParameters(bounds,
146 NULL,
147 D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
148 D2D1::IdentityMatrix(),
149 static_cast<float>(alpha) / 0xFF,
150 NULL,
151 D2D1_LAYER_OPTIONS_NONE),
152 layer);
153 }
154 SaveInternal(layer);
155 }
156
157 void CanvasDirect2D::Restore() {
158 ID2D1Layer* layer = state_.top().layer;
159 if (layer) {
160 rt_->PopLayer();
161 layer->Release();
162 }
163
164 int clip_count = state_.top().clip_count;
165 for (int i = 0; i < clip_count; ++i)
166 rt_->PopAxisAlignedClip();
167
168 state_.pop();
169 // The state_ stack should never be empty - we should always have at least one
170 // entry to hold a clip count when there is no active save/restore entry.
171 CHECK(!state_.empty()) << "Called Restore() once too often!";
172
173 rt_->RestoreDrawingState(drawing_state_block_);
174 }
175
176 bool CanvasDirect2D::ClipRectInt(int x, int y, int w, int h) {
177 rt_->PushAxisAlignedClip(RectToRectF(x, y, w, h),
178 D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
179 // Increment the clip count so the call to PushAxisAlignedClip() can be
180 // balanced with a call to PopAxisAlignedClip in the next Restore().
181 ++state_.top().clip_count;
182 return w > 0 && h > 0;
183 }
184
185 void CanvasDirect2D::TranslateInt(int x, int y) {
186 D2D1_MATRIX_3X2_F raw;
187 rt_->GetTransform(&raw);
188 D2D1::Matrix3x2F transform(raw._11, raw._12, raw._21, raw._22, raw._31,
189 raw._32);
190 transform = D2D1::Matrix3x2F::Translation(static_cast<float>(x),
191 static_cast<float>(y)) * transform;
192 rt_->SetTransform(transform);
193 }
194
195 void CanvasDirect2D::ScaleInt(int x, int y) {
196 D2D1_MATRIX_3X2_F raw;
197 rt_->GetTransform(&raw);
198 D2D1::Matrix3x2F transform(raw._11, raw._12, raw._21, raw._22, raw._31,
199 raw._32);
200 transform = D2D1::Matrix3x2F::Scale(static_cast<float>(x),
201 static_cast<float>(y)) * transform;
202 rt_->SetTransform(transform);
203 }
204
205 void CanvasDirect2D::FillRectInt(const SkColor& color,
206 int x, int y, int w, int h) {
207 ScopedComPtr<ID2D1SolidColorBrush> solid_brush;
208 rt_->CreateSolidColorBrush(SkColorToColorF(color), solid_brush.Receive());
209 rt_->FillRectangle(RectToRectF(x, y, w, h), solid_brush);
210 }
211
212 void CanvasDirect2D::FillRectInt(const SkColor& color,
213 int x, int y, int w, int h,
214 SkXfermode::Mode mode) {
215 NOTIMPLEMENTED();
216 }
217
218 void CanvasDirect2D::FillRectInt(const gfx::Brush* brush,
219 int x, int y, int w, int h) {
220 const Direct2DBrush* d2d_brush = static_cast<const Direct2DBrush*>(brush);
221 rt_->FillRectangle(RectToRectF(x, y, w, h), d2d_brush->brush());
222 }
223
224 void CanvasDirect2D::DrawRectInt(const SkColor& color,
225 int x, int y, int w, int h) {
226 ScopedComPtr<ID2D1SolidColorBrush> solid_brush;
227 rt_->CreateSolidColorBrush(SkColorToColorF(color), solid_brush.Receive());
228 rt_->DrawRectangle(RectToRectF(x, y, w, h), solid_brush);
229 }
230
231 void CanvasDirect2D::DrawRectInt(const SkColor& color,
232 int x, int y, int w, int h,
233 SkXfermode::Mode mode) {
234 NOTIMPLEMENTED();
235 }
236
237 void CanvasDirect2D::DrawRectInt(int x, int y, int w, int h,
238 const SkPaint& paint) {
239 NOTIMPLEMENTED();
240 }
241
242 void CanvasDirect2D::DrawLineInt(const SkColor& color,
243 int x1, int y1,
244 int x2, int y2) {
245 ScopedComPtr<ID2D1SolidColorBrush> solid_brush;
246 rt_->CreateSolidColorBrush(SkColorToColorF(color), solid_brush.Receive());
247 rt_->DrawLine(PointToPoint2F(x1, y1), PointToPoint2F(x2, y2), solid_brush);
248 }
249
250 void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap, int x, int y) {
251 ScopedComPtr<ID2D1Bitmap> d2d1_bitmap(
252 CreateD2D1BitmapFromSkBitmap(rt_, bitmap));
253 rt_->DrawBitmap(d2d1_bitmap,
254 RectToRectF(x, y, bitmap.width(), bitmap.height()),
255 1.0f,
256 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
257 RectToRectF(0, 0, bitmap.width(), bitmap.height()));
258 }
259
260 void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap,
261 int x, int y,
262 const SkPaint& paint) {
263 NOTIMPLEMENTED();
264 }
265
266 void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap,
267 int src_x, int src_y, int src_w, int src_h,
268 int dest_x, int dest_y,
269 int dest_w, int dest_h,
270 bool filter) {
271 ScopedComPtr<ID2D1Bitmap> d2d1_bitmap(
272 CreateD2D1BitmapFromSkBitmap(rt_, bitmap));
273 rt_->DrawBitmap(d2d1_bitmap,
274 RectToRectF(dest_x, dest_y, dest_w, dest_h),
275 1.0f,
276 FilterToInterpolationMode(filter),
277 RectToRectF(src_x, src_y, src_w, src_h));
278 }
279
280 void CanvasDirect2D::DrawBitmapInt(const SkBitmap& bitmap,
281 int src_x, int src_y, int src_w, int src_h,
282 int dest_x, int dest_y,
283 int dest_w, int dest_h,
284 bool filter,
285 const SkPaint& paint) {
286 NOTIMPLEMENTED();
287 }
288
289 void CanvasDirect2D::DrawStringInt(const string16& text,
290 const gfx::Font& font,
291 const SkColor& color,
292 int x, int y, int w, int h) {
293 NOTIMPLEMENTED();
294 }
295
296 void CanvasDirect2D::DrawStringInt(const string16& text,
297 const gfx::Font& font,
298 const SkColor& color,
299 const gfx::Rect& display_rect) {
300 NOTIMPLEMENTED();
301 }
302
303 void CanvasDirect2D::DrawStringInt(const string16& text,
304 const gfx::Font& font,
305 const SkColor& color,
306 int x, int y, int w, int h,
307 int flags) {
308 NOTIMPLEMENTED();
309 }
310
311 void CanvasDirect2D::DrawFocusRect(int x, int y, int width, int height) {
312 NOTIMPLEMENTED();
313 }
314
315 void CanvasDirect2D::TileImageInt(const SkBitmap& bitmap,
316 int x, int y, int w, int h) {
317 ScopedComPtr<ID2D1Brush> brush(
318 CreateD2D1BrushFromSkBitmap(rt_, bitmap, D2D1_EXTEND_MODE_WRAP,
319 D2D1_EXTEND_MODE_WRAP));
320 rt_->FillRectangle(RectToRectF(x, y, w, h), brush);
321 }
322
323 void CanvasDirect2D::TileImageInt(const SkBitmap& bitmap,
324 int src_x, int src_y,
325 int dest_x, int dest_y, int w, int h) {
326 NOTIMPLEMENTED();
327 }
328
329 gfx::NativeDrawingContext CanvasDirect2D::BeginPlatformPaint() {
330 DCHECK(!interop_rt_.get());
331 interop_rt_.QueryFrom(rt_);
332 HDC dc = NULL;
333 if (interop_rt_.get())
334 interop_rt_->GetDC(D2D1_DC_INITIALIZE_MODE_COPY, &dc);
335 return dc;
336 }
337
338 void CanvasDirect2D::EndPlatformPaint() {
339 DCHECK(interop_rt_.get());
340 interop_rt_->ReleaseDC(NULL);
341 interop_rt_.release();
342 }
343
344 CanvasSkia* CanvasDirect2D::AsCanvasSkia() {
345 return NULL;
346 }
347
348 const CanvasSkia* CanvasDirect2D::AsCanvasSkia() const {
349 return NULL;
350 }
351
352 ////////////////////////////////////////////////////////////////////////////////
353 // CanvasDirect2D, private:
354
355 void CanvasDirect2D::SaveInternal(ID2D1Layer* layer) {
356 if (!drawing_state_block_)
357 GetD2D1Factory()->CreateDrawingStateBlock(drawing_state_block_.Receive());
358 rt_->SaveDrawingState(drawing_state_block_.get());
359 state_.push(RenderState(layer));
360 }
361
362 } // namespace gfx
OLDNEW
« no previous file with comments | « gfx/canvas_direct2d.h ('k') | gfx/canvas_direct2d_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698