Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(410)

Unified Diff: src/pdf/SkPDFDevice.cpp

Issue 1438503002: SkPDF: fix large-number bug (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2015-11-16 (Monday) 13:37:23 EST Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gm/skbug_257.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pdf/SkPDFDevice.cpp
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 6680ea472e9e534c20fa8a920685f55921a643f4..1c5b4da07065c7a7afc0963fd713f7bd3a47091a 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include <tuple>
#include "SkPDFDevice.h"
#include "SkAnnotation.h"
@@ -41,6 +42,23 @@
// Utility functions
+static bool excessive_translation(const SkMatrix& m) {
+ const SkScalar kExcessiveTranslation = 8192.0f;
+ return SkScalarAbs(m.getTranslateX()) > kExcessiveTranslation
+ || SkScalarAbs(m.getTranslateY()) > kExcessiveTranslation;
+}
+
+static std::tuple<SkMatrix, SkVector> untranslate(const SkDraw& d) {
+ // https://bug.skia.org/257 If the translation is too large,
+ // PDF can't exactly represent the float values as numbers.
+ SkScalar translateX = d.fMatrix->getTranslateX() / d.fMatrix->getScaleX();
+ SkScalar translateY = d.fMatrix->getTranslateY() / d.fMatrix->getScaleY();
+ SkMatrix mat = *d.fMatrix;
+ mat.preTranslate(-translateX, -translateY);
+ SkASSERT(SkScalarAbs(mat.getTranslateX()) <= 1.0);
+ return std::make_tuple(mat, SkVector::Make(translateX, translateY));
+}
+
// 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 +819,16 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
return;
}
}
+ if (excessive_translation(*d.fMatrix)) {
+ SkVector translate; SkMatrix translateMatrix;
+ std::tie(translateMatrix, translate) = untranslate(d);
+ SkDraw drawCopy(d);
+ drawCopy.fMatrix = &translateMatrix;
+ SkTArray<SkPoint> pointsCopy(points, SkToInt(count));
+ SkPoint::Offset(&pointsCopy[0], SkToInt(count), translate);
+ 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 +957,17 @@ void SkPDFDevice::drawRect(const SkDraw& d,
SkRect r = rect;
r.sort();
+ if (excessive_translation(*d.fMatrix)) {
+ SkVector translate; SkMatrix translateMatrix;
+ std::tie(translateMatrix, translate) = untranslate(d);
+ SkDraw drawCopy(d);
+ drawCopy.fMatrix = &translateMatrix;
+ 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 +1020,17 @@ void SkPDFDevice::drawPath(const SkDraw& d,
const SkPaint& srcPaint,
const SkMatrix* prePathMatrix,
bool pathIsMutable) {
+ if (excessive_translation(*d.fMatrix)) {
+ SkVector translate; SkMatrix translateMatrix;
+ std::tie(translateMatrix, translate) = untranslate(d);
+ SkDraw drawCopy(d);
+ drawCopy.fMatrix = &translateMatrix;
+ 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 +1323,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)) {
+ SkVector translate; SkMatrix translateMatrix;
+ std::tie(translateMatrix, translate) = untranslate(d);
+ SkDraw drawCopy(d);
+ drawCopy.fMatrix = &translateMatrix;
+ 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 +1394,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)) {
+ SkVector translate; SkMatrix translateMatrix;
+ std::tie(translateMatrix, translate) = untranslate(d);
+ SkDraw drawCopy(d);
+ drawCopy.fMatrix = &translateMatrix;
+ 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.
+ }
+
if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) {
const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos);
SkAutoTMalloc<SkPoint> positionsBuffer;
« no previous file with comments | « gm/skbug_257.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698