Chromium Code Reviews| Index: src/pdf/SkPDFDevice.cpp |
| diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp |
| index 6680ea472e9e534c20fa8a920685f55921a643f4..5f0937c3aff4bf1e4d1668f86c44929c31102cc9 100644 |
| --- a/src/pdf/SkPDFDevice.cpp |
| +++ b/src/pdf/SkPDFDevice.cpp |
| @@ -41,6 +41,26 @@ |
| // Utility functions |
| +static bool excessive_translation(const SkMatrix& m) { |
| + const SkScalar kExcessiveTranslation = 8192.0f; |
| + return SkScalarAbs(m.getTranslateX()) > kExcessiveTranslation |
| + || SkScalarAbs(m.getTranslateY()) > kExcessiveTranslation; |
| +} |
| + |
| +static SkDraw untranslate(const SkDraw& d, SkVector* shiftVector) { |
| + SkScalar translateX = d.fMatrix->getTranslateX() / d.fMatrix->getScaleX(); |
| + SkScalar translateY = d.fMatrix->getTranslateY() / d.fMatrix->getScaleY(); |
| + SkMatrix translate = *d.fMatrix; |
| + translate.preTranslate(-translateX, -translateY); |
| + SkASSERT(translate.getTranslateX() <= 1.0); |
|
tomhudson
2015/11/16 16:35:30
Do we want an fabs() here for paranoia?
hal.canary
2015/11/16 16:50:17
done
|
| + SkDraw drawCopy(d); |
| + drawCopy.fMatrix = &translate; |
|
tomhudson
2015/11/16 16:35:30
Uh-oh; returning reference to a local static - thi
hal.canary
2015/11/16 16:50:18
Argh!
This is what I get from copy-and-pasting in
|
| + if (shiftVector) { |
| + shiftVector->set(translateX, translateY); |
| + } |
| + return drawCopy; |
| +} |
| + |
| // If the paint will definitely draw opaquely, replace kSrc_Mode with |
| // kSrcOver_Mode. http://crbug.com/473572 |
| static void replace_srcmode_on_opaque_paint(SkPaint* paint) { |
| @@ -801,6 +821,16 @@ void SkPDFDevice::drawPoints(const SkDraw& d, |
| return; |
| } |
| } |
| + if (excessive_translation(*d.fMatrix)) { |
| + // https://bug.skia.org/257 If the translation is too large, |
| + // PDF can't exactly represent the float values as numbers. |
|
tomhudson
2015/11/16 16:35:30
Nit: this comment is cut-and-pasted four times. Do
hal.canary
2015/11/16 16:50:18
done
|
| + SkVector translate; |
| + SkDraw drawCopy = untranslate(d, &translate); |
| + SkTArray<SkPoint> pointsCopy(points, count); |
| + SkPoint::Offset(&pointsCopy[0], count, translate.x(), translate.y()); |
| + this->drawPoints(drawCopy, mode, count, &pointsCopy[0], srcPaint); |
| + return; // NOTE: shader behavior will be off. |
| + } |
| // SkDraw::drawPoints converts to multiple calls to fDevice->drawPath. |
| // We only use this when there's a path effect because of the overhead |
| @@ -929,6 +959,17 @@ void SkPDFDevice::drawRect(const SkDraw& d, |
| SkRect r = rect; |
| r.sort(); |
| + if (excessive_translation(*d.fMatrix)) { |
| + // https://bug.skia.org/257 If the translation is too large, |
| + // PDF can't exactly represent the float values as numbers. |
| + SkVector translate; |
| + SkDraw drawCopy = untranslate(d, &translate); |
| + SkRect rectCopy = rect; |
| + rectCopy.offset(translate.x(), translate.y()); |
| + this->drawRect(drawCopy, rectCopy, srcPaint); |
| + return; // NOTE: shader behavior will be off. |
| + } |
| + |
| if (paint.getPathEffect()) { |
| if (d.fClip->isEmpty()) { |
| return; |
| @@ -981,6 +1022,17 @@ void SkPDFDevice::drawPath(const SkDraw& d, |
| const SkPaint& srcPaint, |
| const SkMatrix* prePathMatrix, |
| bool pathIsMutable) { |
| + if (excessive_translation(*d.fMatrix)) { |
| + // https://bug.skia.org/257 If the translation is too large, |
| + // PDF can't exactly represent the float values as numbers. |
| + SkVector translate; |
| + SkDraw drawCopy = untranslate(d, &translate); |
| + SkPath pathCopy(origPath); |
| + pathCopy.offset(translate.x(), translate.y()); |
| + this->drawPath(drawCopy, pathCopy, srcPaint, prePathMatrix, true); |
| + return; // NOTE: shader behavior will be off. |
| + } |
| + |
| SkPaint paint = srcPaint; |
| replace_srcmode_on_opaque_paint(&paint); |
| SkPath modifiedPath; |
| @@ -1273,6 +1325,16 @@ static void draw_transparent_text(SkPDFDevice* device, |
| void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, |
| SkScalar x, SkScalar y, const SkPaint& srcPaint) { |
| + if (excessive_translation(*d.fMatrix)) { |
| + // https://bug.skia.org/257 If the translation is too large, |
| + // PDF can't exactly represent the float values as numbers. |
| + SkVector translate; |
| + SkDraw drawCopy = untranslate(d, &translate); |
| + this->drawText(drawCopy, text, len, x + translate.x(), |
| + y + translate.y(), srcPaint); |
| + return; // NOTE: shader behavior will be off. |
| + } |
| + |
| if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { |
| // https://bug.skia.org/3866 |
| SkPath path; |
| @@ -1334,6 +1396,18 @@ void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, |
| void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, |
| const SkScalar pos[], int scalarsPerPos, |
| const SkPoint& offset, const SkPaint& srcPaint) { |
| + if (excessive_translation(*d.fMatrix)) { |
| + // https://bug.skia.org/257 If the translation is too large, |
| + // PDF can't exactly represent the float values as numbers. |
| + SkVector translate; |
| + SkDraw drawCopy = untranslate(d, &translate); |
| + SkPoint offsetCopy = offset; |
| + SkPoint::Offset(&offsetCopy, 1, translate.x(), translate.y()); |
| + this->drawPosText(drawCopy, text, len, pos, scalarsPerPos, offsetCopy, |
| + srcPaint); |
| + return; // NOTE: shader behavior will be off. |
|
tomhudson
2015/11/16 16:35:30
Can we quantify and document how much of a shader
hal.canary
2015/11/16 16:50:17
It's already off (comparing PDF to 8888 in that GM
|
| + } |
| + |
| if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { |
| const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos); |
| SkAutoTMalloc<SkPoint> positionsBuffer; |