15e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org/* 25e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org * Copyright 2013 Google Inc. 35e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org * 45e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 55e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org * found in the LICENSE file. 65e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org */ 75e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 85e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org#include "SkPDFDeviceFlattener.h" 95e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org#include "SkDraw.h" 105e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 115e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgstatic SkISize SkSizeToISize(const SkSize& size) { 125e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org return SkISize::Make(SkScalarRoundToInt(size.width()), SkScalarRoundToInt(size.height())); 135e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 145e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 155e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgSkPDFDeviceFlattener::SkPDFDeviceFlattener(const SkSize& pageSize, const SkRect* trimBox) 165e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org : SkPDFDevice(SkSizeToISize(pageSize), 175e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkSizeToISize(pageSize), 185e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkMatrix::I()) { 195e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org // TODO(edisonn): store the trimbox on emit. 205e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 215e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 225e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgSkPDFDeviceFlattener::~SkPDFDeviceFlattener() { 235e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 245e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 255e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgstatic void flattenPaint(const SkDraw& d, SkPaint* paint) { 265e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org if (paint->getShader()) { 275970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org SkAutoTUnref<SkShader> lms(SkShader::CreateLocalMatrixShader(paint->getShader(), 285970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org *d.fMatrix)); 295970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org paint->setShader(lms); 305e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } 315e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 325e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 335e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgvoid SkPDFDeviceFlattener::drawPoints(const SkDraw& d, SkCanvas::PointMode mode, 345e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org size_t count, const SkPoint points[], 355e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org const SkPaint& paint) { 365e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org if (!mustFlatten(d)) { 375e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org INHERITED::drawPoints(d, mode, count, points, paint); 385e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org return; 395e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } 405e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 415e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkPaint paintFlatten(paint); 425e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org flattenPaint(d, &paintFlatten); 435e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 445e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkPoint* flattenedPoints = SkNEW_ARRAY(SkPoint, count); 45a4662865e37a2ca95b5e3379072f6a274acc8ac8robertphillips@google.com d.fMatrix->mapPoints(flattenedPoints, points, SkToS32(count)); 465e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkDraw draw(d); 475e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkMatrix identity = SkMatrix::I(); 485e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org draw.fMatrix = &identity; 495e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org INHERITED::drawPoints(draw, mode, count, flattenedPoints, paintFlatten); 505e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkDELETE_ARRAY(flattenedPoints); 515e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 525e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 535e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgvoid SkPDFDeviceFlattener::drawRect(const SkDraw& d, const SkRect& r, const SkPaint& paint) { 545e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org if (!mustFlatten(d)) { 555e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org INHERITED::drawRect(d, r, paint); 565e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org return; 575e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } 585e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 595e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkPath path; 605e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org path.addRect(r); 615e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org path.transform(*d.fMatrix); 625e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkDraw draw(d); 635e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkMatrix matrix = SkMatrix::I(); 645e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org draw.fMatrix = &matrix; 655e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 665e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkPaint paintFlatten(paint); 675e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org flattenPaint(d, &paintFlatten); 685e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 695e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org INHERITED::drawPath(draw, path, paintFlatten, NULL, true); 705e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 715e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 725e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgvoid SkPDFDeviceFlattener::drawPath(const SkDraw& d, const SkPath& origPath, 735e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org const SkPaint& paint, const SkMatrix* prePathMatrix, 745e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org bool pathIsMutable) { 755e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org if (!mustFlatten(d) && !(prePathMatrix && prePathMatrix->hasPerspective())) { 765e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org INHERITED::drawPath(d, origPath, paint, prePathMatrix, pathIsMutable); 775e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org return; 785e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } 795e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 805e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkPath* pathPtr = (SkPath*)&origPath; 815e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkPath tmpPath; 825e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 835e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org if (!pathIsMutable) { 845e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org tmpPath = origPath; 855e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org pathPtr = &tmpPath; 865e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } 875e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 885e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org if (prePathMatrix) { 895e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org pathPtr->transform(*prePathMatrix); 905e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } 915e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 925e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkPaint paintFlatten(paint); 935e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org flattenPaint(d, &paintFlatten); 945e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 955e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org bool fill = paintFlatten.getFillPath(*pathPtr, &tmpPath); 965e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkDEBUGCODE(pathPtr = (SkPath*)0x12345678); // Don't use pathPtr after this point. 975e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 985e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org paintFlatten.setPathEffect(NULL); 995e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org if (fill) { 1005e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org paintFlatten.setStyle(SkPaint::kFill_Style); 1015e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } else { 1025e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org paintFlatten.setStyle(SkPaint::kStroke_Style); 1035e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org paintFlatten.setStrokeWidth(0); 1045e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } 1055e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 1065e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org tmpPath.transform(*d.fMatrix); 1075e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 1085e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkDraw draw(d); 1095e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkMatrix matrix = SkMatrix::I(); 1105e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org draw.fMatrix = &matrix; 1115e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 1125e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org INHERITED::drawPath(draw, tmpPath, paintFlatten, NULL, true); 1135e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 1145e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 1155e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgvoid SkPDFDeviceFlattener::drawText(const SkDraw& d, const void* text, size_t len, 1165e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org SkScalar x, SkScalar y, const SkPaint& paint) { 1175e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org if (mustPathText(d, paint)) { 1185e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org d.drawText_asPaths((const char*)text, len, x, y, paint); 1195e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org return; 1205e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } 1215e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 1225e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org INHERITED::drawText(d, text, len, x, y, paint); 1235e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 1245e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 1255e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgvoid SkPDFDeviceFlattener::drawPosText(const SkDraw& d, const void* text, size_t len, 1265e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org const SkScalar pos[], SkScalar constY, 1275e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org int scalarsPerPos, const SkPaint& paint) { 1285e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org if (mustPathText(d, paint)) { 1295e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org d.drawPosText_asPaths((const char*)text, len, pos, constY, scalarsPerPos, paint); 1305e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org return; 1315e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } 1325e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org INHERITED::drawPosText(d, text, len, pos, constY,scalarsPerPos, paint); 1335e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 1345e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 1355e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgvoid SkPDFDeviceFlattener::drawTextOnPath(const SkDraw& d, const void* text, size_t len, 1365e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org const SkPath& path, const SkMatrix* matrix, 1375e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org const SkPaint& paint) { 1385e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org if (mustPathText(d, paint) || (matrix && matrix->hasPerspective())) { 1395e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org d.drawTextOnPath((const char*)text, len, path, matrix, paint); 1405e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org return; 1415e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org } 1425e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org INHERITED::drawTextOnPath(d, text, len, path, matrix, paint); 1435e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 1445e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 1455e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgbool SkPDFDeviceFlattener::mustFlatten(const SkDraw& d) const { 1465e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org // TODO(edisonn): testability, add flag to force return true. 1475e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org return d.fMatrix->hasPerspective(); 1485e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 1495e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org 1505e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgbool SkPDFDeviceFlattener::mustPathText(const SkDraw& d, const SkPaint&) { 1515e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org // TODO(edisonn): testability, add flag to force return true. 1525e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org // TODO(edisonn): TBD: How to flatten MaskFilter. 1535e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org return d.fMatrix->hasPerspective(); 1545e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org} 155