OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <windows.h> | 5 #include <windows.h> |
6 #include <psapi.h> | 6 #include <psapi.h> |
7 | 7 |
8 #include "skia/ext/bitmap_platform_device_win.h" | 8 #include "skia/ext/bitmap_platform_device_win.h" |
9 | 9 |
10 #include "skia/ext/bitmap_platform_device_data.h" | 10 #include "skia/ext/bitmap_platform_device_data.h" |
11 #include "third_party/skia/include/core/SkMatrix.h" | 11 #include "third_party/skia/include/core/SkMatrix.h" |
12 #include "third_party/skia/include/core/SkRefCnt.h" | 12 #include "third_party/skia/include/core/SkRefCnt.h" |
13 #include "third_party/skia/include/core/SkRegion.h" | 13 #include "third_party/skia/include/core/SkRegion.h" |
14 #include "third_party/skia/include/core/SkUtils.h" | 14 #include "third_party/skia/include/core/SkUtils.h" |
15 | 15 |
16 namespace skia { | 16 namespace skia { |
17 | 17 |
18 namespace { | |
19 | |
20 // Constrains position and size to fit within available_size. If |size| is -1, | |
21 // all the available_size is used. Returns false if the position is out of | |
22 // available_size. | |
23 bool Constrain(int available_size, int* position, int *size) { | |
24 if (*size < -2) | |
25 return false; | |
26 | |
27 if (*position < 0) { | |
28 if (*size != -1) | |
29 *size += *position; | |
30 *position = 0; | |
31 } | |
32 if (*size == 0 || *position >= available_size) | |
33 return false; | |
34 | |
35 if (*size > 0) { | |
36 int overflow = (*position + *size) - available_size; | |
37 if (overflow > 0) { | |
38 *size -= overflow; | |
39 } | |
40 } else { | |
41 // Fill up available size. | |
42 *size = available_size - *position; | |
43 } | |
44 return true; | |
45 } | |
46 | |
47 } // namespace | |
48 | |
49 BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData( | 18 BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData( |
50 HBITMAP hbitmap) | 19 HBITMAP hbitmap) |
51 : bitmap_context_(hbitmap), | 20 : bitmap_context_(hbitmap), |
52 hdc_(NULL), | 21 hdc_(NULL), |
53 config_dirty_(true) { // Want to load the config next time. | 22 config_dirty_(true) { // Want to load the config next time. |
54 // Initialize the clip region to the entire bitmap. | 23 // Initialize the clip region to the entire bitmap. |
55 BITMAP bitmap_data; | 24 BITMAP bitmap_data; |
56 if (GetObject(bitmap_context_, sizeof(BITMAP), &bitmap_data)) { | 25 if (GetObject(bitmap_context_, sizeof(BITMAP), &bitmap_data)) { |
57 SkIRect rect; | 26 SkIRect rect; |
58 rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight); | 27 rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight); |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 copy_width, | 248 copy_width, |
280 copy_height, | 249 copy_height, |
281 blend_function); | 250 blend_function); |
282 } | 251 } |
283 LoadTransformToDC(source_dc, data_->transform()); | 252 LoadTransformToDC(source_dc, data_->transform()); |
284 | 253 |
285 if (created_dc) | 254 if (created_dc) |
286 data_->ReleaseBitmapDC(); | 255 data_->ReleaseBitmapDC(); |
287 } | 256 } |
288 | 257 |
289 void BitmapPlatformDevice::makeOpaque(int x, int y, int width, int height) { | |
290 const SkBitmap& bitmap = accessBitmap(true); | |
291 SkASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); | |
292 | |
293 // FIXME(brettw): This is kind of lame, we shouldn't be dealing with | |
294 // transforms at this level. Probably there should be a PlatformCanvas | |
295 // function that does the transform (using the actual transform not just the | |
296 // translation) and calls us with the transformed rect. | |
297 const SkMatrix& matrix = data_->transform(); | |
298 int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x; | |
299 int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y; | |
300 | |
301 if (Constrain(bitmap.width(), &bitmap_start_x, &width) && | |
302 Constrain(bitmap.height(), &bitmap_start_y, &height)) { | |
303 SkAutoLockPixels lock(bitmap); | |
304 SkASSERT(bitmap.rowBytes() % sizeof(uint32_t) == 0u); | |
305 size_t row_words = bitmap.rowBytes() / sizeof(uint32_t); | |
306 // Set data to the first pixel to be modified. | |
307 uint32_t* data = bitmap.getAddr32(0, 0) + (bitmap_start_y * row_words) + | |
308 bitmap_start_x; | |
309 for (int i = 0; i < height; i++) { | |
310 for (int j = 0; j < width; j++) | |
311 data[j] |= (0xFF << SK_A32_SHIFT); | |
312 data += row_words; | |
313 } | |
314 } | |
315 } | |
316 | |
317 // Returns the color value at the specified location. | 258 // Returns the color value at the specified location. |
318 SkColor BitmapPlatformDevice::getColorAt(int x, int y) { | 259 SkColor BitmapPlatformDevice::getColorAt(int x, int y) { |
319 const SkBitmap& bitmap = accessBitmap(false); | 260 const SkBitmap& bitmap = accessBitmap(false); |
320 SkAutoLockPixels lock(bitmap); | 261 SkAutoLockPixels lock(bitmap); |
321 uint32_t* data = bitmap.getAddr32(0, 0); | 262 uint32_t* data = bitmap.getAddr32(0, 0); |
322 return static_cast<SkColor>(data[x + y * width()]); | 263 return static_cast<SkColor>(data[x + y * width()]); |
323 } | 264 } |
324 | 265 |
325 void BitmapPlatformDevice::onAccessBitmap(SkBitmap* bitmap) { | 266 void BitmapPlatformDevice::onAccessBitmap(SkBitmap* bitmap) { |
326 // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI | 267 // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI |
327 // operation has occurred on our DC. | 268 // operation has occurred on our DC. |
328 if (data_->IsBitmapDCCreated()) | 269 if (data_->IsBitmapDCCreated()) |
329 GdiFlush(); | 270 GdiFlush(); |
330 } | 271 } |
331 | 272 |
332 } // namespace skia | 273 } // namespace skia |
333 | 274 |
OLD | NEW |