| OLD | NEW | 
|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "skia/ext/platform_device_win.h" | 5 #include "skia/ext/platform_device_win.h" | 
| 6 | 6 | 
| 7 #include "base/logging.h" |  | 
| 8 #include "skia/ext/skia_utils_win.h" | 7 #include "skia/ext/skia_utils_win.h" | 
| 9 #include "SkMatrix.h" | 8 #include "SkMatrix.h" | 
| 10 #include "SkPath.h" | 9 #include "SkPath.h" | 
| 11 #include "SkRegion.h" | 10 #include "SkRegion.h" | 
| 12 #include "SkUtils.h" | 11 #include "SkUtils.h" | 
| 13 | 12 | 
| 14 namespace skia { | 13 namespace skia { | 
| 15 | 14 | 
| 16 PlatformDeviceWin::PlatformDeviceWin(const SkBitmap& bitmap) | 15 PlatformDeviceWin::PlatformDeviceWin(const SkBitmap& bitmap) | 
| 17     : SkDevice(bitmap) { | 16     : SkDevice(bitmap) { | 
| 18 } | 17 } | 
| 19 | 18 | 
| 20 // static | 19 // static | 
| 21 void PlatformDeviceWin::InitializeDC(HDC context) { | 20 void PlatformDeviceWin::InitializeDC(HDC context) { | 
| 22   // Enables world transformation. | 21   // Enables world transformation. | 
| 23   // If the GM_ADVANCED graphics mode is set, GDI always draws arcs in the | 22   // If the GM_ADVANCED graphics mode is set, GDI always draws arcs in the | 
| 24   // counterclockwise direction in logical space. This is equivalent to the | 23   // counterclockwise direction in logical space. This is equivalent to the | 
| 25   // statement that, in the GM_ADVANCED graphics mode, both arc control points | 24   // statement that, in the GM_ADVANCED graphics mode, both arc control points | 
| 26   // and arcs themselves fully respect the device context's world-to-device | 25   // and arcs themselves fully respect the device context's world-to-device | 
| 27   // transformation. | 26   // transformation. | 
| 28   BOOL res = SetGraphicsMode(context, GM_ADVANCED); | 27   BOOL res = SetGraphicsMode(context, GM_ADVANCED); | 
| 29   DCHECK_NE(res, 0); | 28   SkASSERT(res != 0); | 
| 30 | 29 | 
| 31   // Enables dithering. | 30   // Enables dithering. | 
| 32   res = SetStretchBltMode(context, HALFTONE); | 31   res = SetStretchBltMode(context, HALFTONE); | 
| 33   DCHECK_NE(res, 0); | 32   SkASSERT(res != 0); | 
| 34   // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called | 33   // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called | 
| 35   // right after. | 34   // right after. | 
| 36   res = SetBrushOrgEx(context, 0, 0, NULL); | 35   res = SetBrushOrgEx(context, 0, 0, NULL); | 
| 37   DCHECK_NE(res, 0); | 36   SkASSERT(res != 0); | 
| 38 | 37 | 
| 39   // Sets up default orientation. | 38   // Sets up default orientation. | 
| 40   res = SetArcDirection(context, AD_CLOCKWISE); | 39   res = SetArcDirection(context, AD_CLOCKWISE); | 
| 41   DCHECK_NE(res, 0); | 40   SkASSERT(res != 0); | 
| 42 | 41 | 
| 43   // Sets up default colors. | 42   // Sets up default colors. | 
| 44   res = SetBkColor(context, RGB(255, 255, 255)); | 43   res = SetBkColor(context, RGB(255, 255, 255)); | 
| 45   DCHECK_NE(res, CLR_INVALID); | 44   SkASSERT(res != CLR_INVALID); | 
| 46   res = SetTextColor(context, RGB(0, 0, 0)); | 45   res = SetTextColor(context, RGB(0, 0, 0)); | 
| 47   DCHECK_NE(res, CLR_INVALID); | 46   SkASSERT(res != CLR_INVALID); | 
| 48   res = SetDCBrushColor(context, RGB(255, 255, 255)); | 47   res = SetDCBrushColor(context, RGB(255, 255, 255)); | 
| 49   DCHECK_NE(res, CLR_INVALID); | 48   SkASSERT(res != CLR_INVALID); | 
| 50   res = SetDCPenColor(context, RGB(0, 0, 0)); | 49   res = SetDCPenColor(context, RGB(0, 0, 0)); | 
| 51   DCHECK_NE(res, CLR_INVALID); | 50   SkASSERT(res != CLR_INVALID); | 
| 52 | 51 | 
| 53   // Sets up default transparency. | 52   // Sets up default transparency. | 
| 54   res = SetBkMode(context, OPAQUE); | 53   res = SetBkMode(context, OPAQUE); | 
| 55   DCHECK_NE(res, 0); | 54   SkASSERT(res != 0); | 
| 56   res = SetROP2(context, R2_COPYPEN); | 55   res = SetROP2(context, R2_COPYPEN); | 
| 57   DCHECK_NE(res, 0); | 56   SkASSERT(res != 0); | 
| 58 } | 57 } | 
| 59 | 58 | 
| 60 // static | 59 // static | 
| 61 void PlatformDeviceWin::LoadPathToDC(HDC context, const SkPath& path) { | 60 void PlatformDeviceWin::LoadPathToDC(HDC context, const SkPath& path) { | 
| 62   switch (path.getFillType()) { | 61   switch (path.getFillType()) { | 
| 63     case SkPath::kWinding_FillType: { | 62     case SkPath::kWinding_FillType: { | 
| 64       int res = SetPolyFillMode(context, WINDING); | 63       int res = SetPolyFillMode(context, WINDING); | 
| 65       DCHECK(res != 0); | 64       SkASSERT(res != 0); | 
| 66       break; | 65       break; | 
| 67     } | 66     } | 
| 68     case SkPath::kEvenOdd_FillType: { | 67     case SkPath::kEvenOdd_FillType: { | 
| 69       int res = SetPolyFillMode(context, ALTERNATE); | 68       int res = SetPolyFillMode(context, ALTERNATE); | 
| 70       DCHECK(res != 0); | 69       SkASSERT(res != 0); | 
| 71       break; | 70       break; | 
| 72     } | 71     } | 
| 73     default: { | 72     default: { | 
| 74       NOTREACHED(); | 73       SkASSERT(false); | 
| 75       break; | 74       break; | 
| 76     } | 75     } | 
| 77   } | 76   } | 
| 78   BOOL res = BeginPath(context); | 77   BOOL res = BeginPath(context); | 
| 79   DCHECK(res != 0); | 78   SkASSERT(res != 0); | 
| 80 | 79 | 
| 81   CubicPaths paths; | 80   CubicPaths paths; | 
| 82   if (!SkPathToCubicPaths(&paths, path)) | 81   if (!SkPathToCubicPaths(&paths, path)) | 
| 83     return; | 82     return; | 
| 84 | 83 | 
| 85   std::vector<POINT> points; | 84   std::vector<POINT> points; | 
| 86   for (CubicPaths::const_iterator path(paths.begin()); path != paths.end(); | 85   for (CubicPaths::const_iterator path(paths.begin()); path != paths.end(); | 
| 87        ++path) { | 86        ++path) { | 
| 88     if (!path->size()) | 87     if (!path->size()) | 
| 89       continue; | 88       continue; | 
| 90     // DCHECK_EQ(points.size() % 4, 0); |  | 
| 91     points.resize(0); | 89     points.resize(0); | 
| 92     points.reserve(path->size() * 3 / 4 + 1); | 90     points.reserve(path->size() * 3 / 4 + 1); | 
| 93     points.push_back(SkPointToPOINT(path->front().p[0])); | 91     points.push_back(SkPointToPOINT(path->front().p[0])); | 
| 94     for (CubicPath::const_iterator point(path->begin()); point != path->end(); | 92     for (CubicPath::const_iterator point(path->begin()); point != path->end(); | 
| 95        ++point) { | 93        ++point) { | 
| 96       // Never add point->p[0] | 94       // Never add point->p[0] | 
| 97       points.push_back(SkPointToPOINT(point->p[1])); | 95       points.push_back(SkPointToPOINT(point->p[1])); | 
| 98       points.push_back(SkPointToPOINT(point->p[2])); | 96       points.push_back(SkPointToPOINT(point->p[2])); | 
| 99       points.push_back(SkPointToPOINT(point->p[3])); | 97       points.push_back(SkPointToPOINT(point->p[3])); | 
| 100     } | 98     } | 
| 101     DCHECK_EQ((points.size() - 1) % 3, 0); | 99     SkASSERT((points.size() - 1) % 3 == 0); | 
| 102     // This is slightly inefficient since all straight line and quadratic lines | 100     // This is slightly inefficient since all straight line and quadratic lines | 
| 103     // are "upgraded" to a cubic line. | 101     // are "upgraded" to a cubic line. | 
| 104     // TODO(maruel):  http://b/1147346 We should use | 102     // TODO(maruel):  http://b/1147346 We should use | 
| 105     // PolyDraw/PolyBezier/Polyline whenever possible. | 103     // PolyDraw/PolyBezier/Polyline whenever possible. | 
| 106     res = PolyBezier(context, &points.front(), | 104     res = PolyBezier(context, &points.front(), | 
| 107                      static_cast<DWORD>(points.size())); | 105                      static_cast<DWORD>(points.size())); | 
| 108     DCHECK_NE(res, 0); | 106     SkASSERT(res != 0); | 
| 109     if (res == 0) | 107     if (res == 0) | 
| 110       break; | 108       break; | 
| 111   } | 109   } | 
| 112   if (res == 0) { | 110   if (res == 0) { | 
| 113     // Make sure the path is discarded. | 111     // Make sure the path is discarded. | 
| 114     AbortPath(context); | 112     AbortPath(context); | 
| 115   } else { | 113   } else { | 
| 116     res = EndPath(context); | 114     res = EndPath(context); | 
| 117     DCHECK(res != 0); | 115     SkASSERT(res != 0); | 
| 118   } | 116   } | 
| 119 } | 117 } | 
| 120 | 118 | 
| 121 // static | 119 // static | 
| 122 void PlatformDeviceWin::LoadTransformToDC(HDC dc, const SkMatrix& matrix) { | 120 void PlatformDeviceWin::LoadTransformToDC(HDC dc, const SkMatrix& matrix) { | 
| 123   XFORM xf; | 121   XFORM xf; | 
| 124   xf.eM11 = matrix[SkMatrix::kMScaleX]; | 122   xf.eM11 = matrix[SkMatrix::kMScaleX]; | 
| 125   xf.eM21 = matrix[SkMatrix::kMSkewX]; | 123   xf.eM21 = matrix[SkMatrix::kMSkewX]; | 
| 126   xf.eDx = matrix[SkMatrix::kMTransX]; | 124   xf.eDx = matrix[SkMatrix::kMTransX]; | 
| 127   xf.eM12 = matrix[SkMatrix::kMSkewY]; | 125   xf.eM12 = matrix[SkMatrix::kMSkewY]; | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 176         current_path = &paths->back(); | 174         current_path = &paths->back(); | 
| 177         continue; | 175         continue; | 
| 178       } | 176       } | 
| 179       case SkPath::kDone_Verb:  // iter.next returns 0 points | 177       case SkPath::kDone_Verb:  // iter.next returns 0 points | 
| 180       default: { | 178       default: { | 
| 181         current_path = NULL; | 179         current_path = NULL; | 
| 182         // Will return false. | 180         // Will return false. | 
| 183         break; | 181         break; | 
| 184       } | 182       } | 
| 185     } | 183     } | 
| 186     DCHECK(current_path); | 184     SkASSERT(current_path); | 
| 187     if (!current_path) { | 185     if (!current_path) { | 
| 188       paths->clear(); | 186       paths->clear(); | 
| 189       return false; | 187       return false; | 
| 190     } | 188     } | 
| 191     current_path->push_back(points_to_add); | 189     current_path->push_back(points_to_add); | 
| 192   } | 190   } | 
| 193   return true; | 191   return true; | 
| 194 } | 192 } | 
| 195 | 193 | 
| 196 // static | 194 // static | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 213     // It is complex. | 211     // It is complex. | 
| 214     SkPath path; | 212     SkPath path; | 
| 215     region.getBoundaryPath(&path); | 213     region.getBoundaryPath(&path); | 
| 216     // Clip. Note that windows clipping regions are not affected by the | 214     // Clip. Note that windows clipping regions are not affected by the | 
| 217     // transform so apply it manually. | 215     // transform so apply it manually. | 
| 218     path.transform(transformation); | 216     path.transform(transformation); | 
| 219     LoadPathToDC(context, path); | 217     LoadPathToDC(context, path); | 
| 220     hrgn = PathToRegion(context); | 218     hrgn = PathToRegion(context); | 
| 221   } | 219   } | 
| 222   int result = SelectClipRgn(context, hrgn); | 220   int result = SelectClipRgn(context, hrgn); | 
| 223   DCHECK_NE(result, ERROR); | 221   SkASSERT(result != ERROR); | 
| 224   result = DeleteObject(hrgn); | 222   result = DeleteObject(hrgn); | 
| 225   DCHECK_NE(result, 0); | 223   SkASSERT(result != 0); | 
| 226 } | 224 } | 
| 227 | 225 | 
| 228 }  // namespace skia | 226 }  // namespace skia | 
| 229 | 227 | 
| OLD | NEW | 
|---|