This source file includes following definitions.
- InitializeDC
- BeginPlatformPaint
- EndPlatformPaint
- DrawToNativeContext
- LoadPathToDC
- LoadTransformToDC
- SkPathToCubicPaths
- LoadClippingRegionToDC
#include "skia/ext/platform_device.h"
#include "skia/ext/skia_utils_win.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "third_party/skia/include/core/SkUtils.h"
namespace skia {
void InitializeDC(HDC context) {
BOOL res = SetGraphicsMode(context, GM_ADVANCED);
SkASSERT(res != 0);
res = SetStretchBltMode(context, HALFTONE);
SkASSERT(res != 0);
res = SetBrushOrgEx(context, 0, 0, NULL);
SkASSERT(res != 0);
res = SetArcDirection(context, AD_CLOCKWISE);
SkASSERT(res != 0);
res = SetBkColor(context, RGB(255, 255, 255));
SkASSERT(res != CLR_INVALID);
res = SetTextColor(context, RGB(0, 0, 0));
SkASSERT(res != CLR_INVALID);
res = SetDCBrushColor(context, RGB(255, 255, 255));
SkASSERT(res != CLR_INVALID);
res = SetDCPenColor(context, RGB(0, 0, 0));
SkASSERT(res != CLR_INVALID);
res = SetBkMode(context, OPAQUE);
SkASSERT(res != 0);
res = SetROP2(context, R2_COPYPEN);
SkASSERT(res != 0);
}
PlatformSurface PlatformDevice::BeginPlatformPaint() {
return 0;
}
void PlatformDevice::EndPlatformPaint() {
}
void PlatformDevice::DrawToNativeContext(PlatformSurface surface, int x, int y,
const PlatformRect* src_rect) {
}
bool PlatformDevice::LoadPathToDC(HDC context, const SkPath& path) {
switch (path.getFillType()) {
case SkPath::kWinding_FillType: {
int res = SetPolyFillMode(context, WINDING);
SkASSERT(res != 0);
break;
}
case SkPath::kEvenOdd_FillType: {
int res = SetPolyFillMode(context, ALTERNATE);
SkASSERT(res != 0);
break;
}
default: {
SkASSERT(false);
break;
}
}
BOOL res = BeginPath(context);
if (!res) {
return false;
}
CubicPaths paths;
if (!SkPathToCubicPaths(&paths, path))
return false;
std::vector<POINT> points;
for (CubicPaths::const_iterator path(paths.begin()); path != paths.end();
++path) {
if (!path->size())
continue;
points.resize(0);
points.reserve(path->size() * 3 / 4 + 1);
points.push_back(SkPointToPOINT(path->front().p[0]));
for (CubicPath::const_iterator point(path->begin()); point != path->end();
++point) {
points.push_back(SkPointToPOINT(point->p[1]));
points.push_back(SkPointToPOINT(point->p[2]));
points.push_back(SkPointToPOINT(point->p[3]));
}
SkASSERT((points.size() - 1) % 3 == 0);
res = PolyBezier(context, &points.front(),
static_cast<DWORD>(points.size()));
SkASSERT(res != 0);
if (res == 0)
break;
}
if (res == 0) {
AbortPath(context);
} else {
res = EndPath(context);
SkASSERT(res != 0);
}
return true;
}
void PlatformDevice::LoadTransformToDC(HDC dc, const SkMatrix& matrix) {
XFORM xf;
xf.eM11 = matrix[SkMatrix::kMScaleX];
xf.eM21 = matrix[SkMatrix::kMSkewX];
xf.eDx = matrix[SkMatrix::kMTransX];
xf.eM12 = matrix[SkMatrix::kMSkewY];
xf.eM22 = matrix[SkMatrix::kMScaleY];
xf.eDy = matrix[SkMatrix::kMTransY];
SetWorldTransform(dc, &xf);
}
bool PlatformDevice::SkPathToCubicPaths(CubicPaths* paths,
const SkPath& skpath) {
paths->clear();
CubicPath* current_path = NULL;
SkPoint current_points[4];
CubicPoints points_to_add;
SkPath::Iter iter(skpath, false);
for (SkPath::Verb verb = iter.next(current_points);
verb != SkPath::kDone_Verb;
verb = iter.next(current_points)) {
switch (verb) {
case SkPath::kMove_Verb: {
paths->push_back(CubicPath());
current_path = &paths->back();
continue;
}
case SkPath::kLine_Verb: {
points_to_add.p[0] = current_points[0];
points_to_add.p[1] = current_points[0];
points_to_add.p[2] = current_points[1];
points_to_add.p[3] = current_points[1];
break;
}
case SkPath::kQuad_Verb: {
points_to_add.p[0] = current_points[0];
points_to_add.p[1] = current_points[1];
points_to_add.p[2] = current_points[2];
points_to_add.p[3] = current_points[2];
break;
}
case SkPath::kCubic_Verb: {
points_to_add.p[0] = current_points[0];
points_to_add.p[1] = current_points[1];
points_to_add.p[2] = current_points[2];
points_to_add.p[3] = current_points[3];
break;
}
case SkPath::kClose_Verb: {
paths->push_back(CubicPath());
current_path = &paths->back();
continue;
}
default: {
current_path = NULL;
break;
}
}
SkASSERT(current_path);
if (!current_path) {
paths->clear();
return false;
}
current_path->push_back(points_to_add);
}
return true;
}
void PlatformDevice::LoadClippingRegionToDC(HDC context,
const SkRegion& region,
const SkMatrix& transformation) {
HRGN hrgn;
if (region.isEmpty()) {
hrgn = CreateRectRgn(0, 0, 0, 0);
} else if (region.isRect()) {
hrgn = CreateRectRgnIndirect(&SkIRectToRECT(region.getBounds()));
} else {
SkPath path;
region.getBoundaryPath(&path);
SkMatrix t(transformation);
t.setTranslateX(-t.getTranslateX());
t.setTranslateY(-t.getTranslateY());
path.transform(t);
LoadPathToDC(context, path);
hrgn = PathToRegion(context);
}
int result = SelectClipRgn(context, hrgn);
SkASSERT(result != ERROR);
result = DeleteObject(hrgn);
SkASSERT(result != 0);
}
}