gfx/skia/trunk/src/pdf/SkPDFDeviceFlattener.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/pdf/SkPDFDeviceFlattener.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,155 @@
     1.4 +/*
     1.5 + * Copyright 2013 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#include "SkPDFDeviceFlattener.h"
    1.12 +
    1.13 +#include "SkDraw.h"
    1.14 +
    1.15 +static SkISize SkSizeToISize(const SkSize& size) {
    1.16 +    return SkISize::Make(SkScalarRoundToInt(size.width()), SkScalarRoundToInt(size.height()));
    1.17 +}
    1.18 +
    1.19 +SkPDFDeviceFlattener::SkPDFDeviceFlattener(const SkSize& pageSize, const SkRect* trimBox)
    1.20 +            : SkPDFDevice(SkSizeToISize(pageSize),
    1.21 +                          SkSizeToISize(pageSize),
    1.22 +                          SkMatrix::I()) {
    1.23 +    // TODO(edisonn): store the trimbox on emit.
    1.24 +}
    1.25 +
    1.26 +SkPDFDeviceFlattener::~SkPDFDeviceFlattener() {
    1.27 +}
    1.28 +
    1.29 +static void flattenPaint(const SkDraw& d, SkPaint* paint) {
    1.30 +    if (paint->getShader()) {
    1.31 +        SkMatrix local = paint->getShader()->getLocalMatrix();
    1.32 +        local.preConcat(*d.fMatrix);
    1.33 +        paint->getShader()->setLocalMatrix(local);
    1.34 +    }
    1.35 +}
    1.36 +
    1.37 +void SkPDFDeviceFlattener::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
    1.38 +                                      size_t count, const SkPoint points[],
    1.39 +                                      const SkPaint& paint) {
    1.40 +    if (!mustFlatten(d)) {
    1.41 +        INHERITED::drawPoints(d, mode, count, points, paint);
    1.42 +        return;
    1.43 +    }
    1.44 +
    1.45 +    SkPaint paintFlatten(paint);
    1.46 +    flattenPaint(d, &paintFlatten);
    1.47 +
    1.48 +    SkPoint* flattenedPoints = SkNEW_ARRAY(SkPoint, count);
    1.49 +    d.fMatrix->mapPoints(flattenedPoints, points, SkToS32(count));
    1.50 +    SkDraw draw(d);
    1.51 +    SkMatrix identity = SkMatrix::I();
    1.52 +    draw.fMatrix = &identity;
    1.53 +    INHERITED::drawPoints(draw, mode, count, flattenedPoints, paintFlatten);
    1.54 +    SkDELETE_ARRAY(flattenedPoints);
    1.55 +}
    1.56 +
    1.57 +void SkPDFDeviceFlattener::drawRect(const SkDraw& d, const SkRect& r, const SkPaint& paint) {
    1.58 +    if (!mustFlatten(d)) {
    1.59 +        INHERITED::drawRect(d, r, paint);
    1.60 +        return;
    1.61 +    }
    1.62 +
    1.63 +    SkPath path;
    1.64 +    path.addRect(r);
    1.65 +    path.transform(*d.fMatrix);
    1.66 +    SkDraw draw(d);
    1.67 +    SkMatrix matrix = SkMatrix::I();
    1.68 +    draw.fMatrix = &matrix;
    1.69 +
    1.70 +    SkPaint paintFlatten(paint);
    1.71 +    flattenPaint(d, &paintFlatten);
    1.72 +
    1.73 +    INHERITED::drawPath(draw, path, paintFlatten, NULL, true);
    1.74 +}
    1.75 +
    1.76 +void SkPDFDeviceFlattener::drawPath(const SkDraw& d, const SkPath& origPath,
    1.77 +                                    const SkPaint& paint, const SkMatrix* prePathMatrix,
    1.78 +                                    bool pathIsMutable) {
    1.79 +    if (!mustFlatten(d) && !(prePathMatrix && prePathMatrix->hasPerspective())) {
    1.80 +        INHERITED::drawPath(d, origPath, paint, prePathMatrix, pathIsMutable);
    1.81 +        return;
    1.82 +    }
    1.83 +
    1.84 +    SkPath* pathPtr = (SkPath*)&origPath;
    1.85 +    SkPath tmpPath;
    1.86 +
    1.87 +    if (!pathIsMutable) {
    1.88 +        tmpPath = origPath;
    1.89 +        pathPtr = &tmpPath;
    1.90 +    }
    1.91 +
    1.92 +    if (prePathMatrix) {
    1.93 +        pathPtr->transform(*prePathMatrix);
    1.94 +    }
    1.95 +
    1.96 +    SkPaint paintFlatten(paint);
    1.97 +    flattenPaint(d, &paintFlatten);
    1.98 +
    1.99 +    bool fill = paintFlatten.getFillPath(*pathPtr, &tmpPath);
   1.100 +    SkDEBUGCODE(pathPtr = (SkPath*)0x12345678);  // Don't use pathPtr after this point.
   1.101 +
   1.102 +    paintFlatten.setPathEffect(NULL);
   1.103 +    if (fill) {
   1.104 +        paintFlatten.setStyle(SkPaint::kFill_Style);
   1.105 +    } else {
   1.106 +        paintFlatten.setStyle(SkPaint::kStroke_Style);
   1.107 +        paintFlatten.setStrokeWidth(0);
   1.108 +    }
   1.109 +
   1.110 +    tmpPath.transform(*d.fMatrix);
   1.111 +
   1.112 +    SkDraw draw(d);
   1.113 +    SkMatrix matrix = SkMatrix::I();
   1.114 +    draw.fMatrix = &matrix;
   1.115 +
   1.116 +    INHERITED::drawPath(draw, tmpPath, paintFlatten, NULL, true);
   1.117 +}
   1.118 +
   1.119 +void SkPDFDeviceFlattener::drawText(const SkDraw& d, const void* text, size_t len,
   1.120 +                                    SkScalar x, SkScalar y, const SkPaint& paint) {
   1.121 +    if (mustPathText(d, paint)) {
   1.122 +        d.drawText_asPaths((const char*)text, len, x, y, paint);
   1.123 +        return;
   1.124 +    }
   1.125 +
   1.126 +    INHERITED::drawText(d, text, len, x, y, paint);
   1.127 +}
   1.128 +
   1.129 +void SkPDFDeviceFlattener::drawPosText(const SkDraw& d, const void* text, size_t len,
   1.130 +                                       const SkScalar pos[], SkScalar constY,
   1.131 +                                       int scalarsPerPos, const SkPaint& paint) {
   1.132 +    if (mustPathText(d, paint)) {
   1.133 +        d.drawPosText_asPaths((const char*)text, len, pos, constY, scalarsPerPos, paint);
   1.134 +        return;
   1.135 +    }
   1.136 +    INHERITED::drawPosText(d, text, len, pos, constY,scalarsPerPos, paint);
   1.137 +}
   1.138 +
   1.139 +void SkPDFDeviceFlattener::drawTextOnPath(const SkDraw& d, const void* text, size_t len,
   1.140 +                                          const SkPath& path, const SkMatrix* matrix,
   1.141 +                                          const SkPaint& paint) {
   1.142 +    if (mustPathText(d, paint) || (matrix && matrix->hasPerspective())) {
   1.143 +        d.drawTextOnPath((const char*)text, len, path, matrix, paint);
   1.144 +        return;
   1.145 +    }
   1.146 +    INHERITED::drawTextOnPath(d, text, len, path, matrix, paint);
   1.147 +}
   1.148 +
   1.149 +bool SkPDFDeviceFlattener::mustFlatten(const SkDraw& d) const {
   1.150 +    // TODO(edisonn): testability, add flag to force return true.
   1.151 +    return d.fMatrix->hasPerspective();
   1.152 +}
   1.153 +
   1.154 +bool SkPDFDeviceFlattener::mustPathText(const SkDraw& d, const SkPaint&) {
   1.155 +    // TODO(edisonn): testability, add flag to force return true.
   1.156 +    // TODO(edisonn): TBD: How to flatten MaskFilter.
   1.157 +    return d.fMatrix->hasPerspective();
   1.158 +}

mercurial