*/
bool invert(SkMatrix* inverse) const;
+ /** Fills the passed array with the tranform values in the right order
+ for PDFs. If the matrix is a perspective transform, returns false
+ and fills the array with an identity transform.
+ @param transform The array to fill in.
+ */
+ bool pdfTransform(SkScalar transform[6]) const;
+
/** Apply this matrix to the array of points specified by src, and write
the transformed points into the array of points specified by dst.
dst[] = M * src[]
SkRefPtr<SkPDFArray> getMediaBox();
/** Returns a string with the page contents.
+ * @param flipOrigin Flip the origin between top and bottom.
*/
- SkString content();
+ SkString content(bool flipOrigin) const;
private:
int fWidth;
}
#endif
+bool SkMatrix::pdfTransform(SkScalar transform[6]) const {
+ SkMatrix identity;
+ const SkMatrix* use = this;
+ bool ret = true;
+ if (has_perspective(*this)) {
+ identity.reset();
+ use = &identity;
+ ret = false;
+ }
+ transform[0] = use->fMat[kMScaleX];
+ transform[1] = use->fMat[kMSkewY];
+ transform[2] = use->fMat[kMSkewX];
+ transform[3] = use->fMat[kMScaleY];
+ transform[4] = use->fMat[kMTransX];
+ transform[5] = use->fMat[kMTransY];
+ return true;
+}
+
bool SkMatrix::invert(SkMatrix* inv) const {
int isPersp = has_perspective(*this);
int shift;
fHeight(height),
fCurrentColor(0),
fCurrentTextScaleX(SK_Scalar1) {
- // Scale and translate to move the origin from the lower left to the upper
- // left.
- fCurTransform.setTranslate(0, height);
- fCurTransform.preScale(1, -1);
- fActiveTransform.reset();
- applyTransform(fCurTransform);
-
fContent.append("q\n");
fCurTransform.reset();
fActiveTransform.reset();
return mediaBox;
}
-SkString SkPDFDevice::content() {
- SkString result = fContent;
+SkString SkPDFDevice::content(bool flipOrigin) const {
+ SkString result;
+ // Scale and translate to move the origin from the lower left to the
+ // upper left.
+ if (flipOrigin)
+ result.printf("1 0 0 -1 0 %d cm\n", fHeight);
+ result.append(fContent);
result.append("Q");
return result;
}
void SkPDFDevice::applyTransform(const SkMatrix& m) {
if (m == fActiveTransform)
return;
- SkASSERT((m.getType() & SkMatrix::kPerspective_Mask) == 0);
-
- fContent.appendScalar(m[SkMatrix::kMScaleX]);
- fContent.append(" ");
- fContent.appendScalar(m[SkMatrix::kMSkewY]);
- fContent.append(" ");
- fContent.appendScalar(m[SkMatrix::kMSkewX]);
- fContent.append(" ");
- fContent.appendScalar(m[SkMatrix::kMScaleY]);
- fContent.append(" ");
- fContent.appendScalar(m[SkMatrix::kMTransX]);
- fContent.append(" ");
- fContent.appendScalar(m[SkMatrix::kMTransY]);
- fContent.append(" cm\n");
+ SkScalar transform[6];
+ SkAssertResult(m.pdfTransform(transform));
+ for (size_t i = 0; i < SK_ARRAY_COUNT(transform); i++) {
+ fContent.appendScalar(transform[i]);
+ fContent.append(" ");
+ }
+ fContent.append("cm\n");
fActiveTransform = m;
}
insert("Resources", fDevice->getResourceDict().get());
insert("MediaBox", fDevice->getMediaBox().get());
- fContent = fDevice->content();
+ fContent = fDevice->content(true);
SkRefPtr<SkMemoryStream> contentStream = new SkMemoryStream(
fContent.c_str(), fContent.size());
contentStream->unref(); // SkRefPtr and new both took a reference.