OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkPDFDevice.h" | 8 #include "SkPDFDevice.h" |
9 #include "SkAnnotationKeys.h" | 9 #include "SkAnnotationKeys.h" |
10 #include "SkBitmapDevice.h" | 10 #include "SkBitmapDevice.h" |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 &fDstFormXObject); | 555 &fDstFormXObject); |
556 } | 556 } |
557 }; | 557 }; |
558 | 558 |
559 //////////////////////////////////////////////////////////////////////////////// | 559 //////////////////////////////////////////////////////////////////////////////// |
560 | 560 |
561 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* do
c, bool flip) | 561 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* do
c, bool flip) |
562 : INHERITED(SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height()), | 562 : INHERITED(SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height()), |
563 SkSurfaceProps(0, kUnknown_SkPixelGeometry)) | 563 SkSurfaceProps(0, kUnknown_SkPixelGeometry)) |
564 , fPageSize(pageSize) | 564 , fPageSize(pageSize) |
565 , fContentSize(pageSize) | |
566 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) | 565 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) |
567 , fRasterDpi(rasterDpi) | 566 , fRasterDpi(rasterDpi) |
568 , fDocument(doc) { | 567 , fDocument(doc) { |
569 SkASSERT(pageSize.width() > 0); | 568 SkASSERT(pageSize.width() > 0); |
570 SkASSERT(pageSize.height() > 0); | 569 SkASSERT(pageSize.height() > 0); |
571 | 570 |
572 if (flip) { | 571 if (flip) { |
573 // Skia generally uses the top left as the origin but PDF | 572 // Skia generally uses the top left as the origin but PDF |
574 // natively has the origin at the bottom left. This matrix | 573 // natively has the origin at the bottom left. This matrix |
575 // corrects for that. But that only needs to be done once, we | 574 // corrects for that. But that only needs to be done once, we |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1318 mediaBox->reserve(4); | 1317 mediaBox->reserve(4); |
1319 mediaBox->appendInt(0); | 1318 mediaBox->appendInt(0); |
1320 mediaBox->appendInt(0); | 1319 mediaBox->appendInt(0); |
1321 mediaBox->appendInt(fPageSize.width()); | 1320 mediaBox->appendInt(fPageSize.width()); |
1322 mediaBox->appendInt(fPageSize.height()); | 1321 mediaBox->appendInt(fPageSize.height()); |
1323 return mediaBox; | 1322 return mediaBox; |
1324 } | 1323 } |
1325 | 1324 |
1326 std::unique_ptr<SkStreamAsset> SkPDFDevice::content() const { | 1325 std::unique_ptr<SkStreamAsset> SkPDFDevice::content() const { |
1327 SkDynamicMemoryWStream buffer; | 1326 SkDynamicMemoryWStream buffer; |
1328 this->writeContent(&buffer); | |
1329 return std::unique_ptr<SkStreamAsset>( | |
1330 buffer.bytesWritten() > 0 | |
1331 ? buffer.detachAsStream() | |
1332 : new SkMemoryStream); | |
1333 } | |
1334 | |
1335 void SkPDFDevice::writeContent(SkWStream* out) const { | |
1336 if (fInitialTransform.getType() != SkMatrix::kIdentity_Mask) { | 1327 if (fInitialTransform.getType() != SkMatrix::kIdentity_Mask) { |
1337 SkPDFUtils::AppendTransform(fInitialTransform, out); | 1328 SkPDFUtils::AppendTransform(fInitialTransform, &buffer); |
1338 } | 1329 } |
1339 | 1330 |
1340 // If the content area is the entire page, then we don't need to clip | 1331 GraphicStackState gsState(fExistingClipStack, fExistingClipRegion, &buffer); |
1341 // the content area (PDF area clips to the page size). Otherwise, | |
1342 // we have to clip to the content area; we've already applied the | |
1343 // initial transform, so just clip to the device size. | |
1344 if (fPageSize != fContentSize) { | |
1345 SkRect r = SkRect::MakeWH(SkIntToScalar(this->width()), | |
1346 SkIntToScalar(this->height())); | |
1347 emit_clip(nullptr, &r, out); | |
1348 } | |
1349 | |
1350 GraphicStackState gsState(fExistingClipStack, fExistingClipRegion, out); | |
1351 for (const auto& entry : fContentEntries) { | 1332 for (const auto& entry : fContentEntries) { |
1352 SkPoint translation; | 1333 SkPoint translation; |
1353 translation.iset(this->getOrigin()); | 1334 translation.iset(this->getOrigin()); |
1354 translation.negate(); | 1335 translation.negate(); |
1355 gsState.updateClip(entry.fState.fClipStack, entry.fState.fClipRegion, | 1336 gsState.updateClip(entry.fState.fClipStack, entry.fState.fClipRegion, |
1356 translation); | 1337 translation); |
1357 gsState.updateMatrix(entry.fState.fMatrix); | 1338 gsState.updateMatrix(entry.fState.fMatrix); |
1358 gsState.updateDrawingState(entry.fState); | 1339 gsState.updateDrawingState(entry.fState); |
1359 | 1340 |
1360 entry.fContent.writeToStream(out); | 1341 entry.fContent.writeToStream(&buffer); |
1361 } | 1342 } |
1362 gsState.drainStack(); | 1343 gsState.drainStack(); |
| 1344 |
| 1345 return std::unique_ptr<SkStreamAsset>( |
| 1346 buffer.bytesWritten() > 0 |
| 1347 ? buffer.detachAsStream() |
| 1348 : new SkMemoryStream); |
1363 } | 1349 } |
1364 | 1350 |
1365 /* Draws an inverse filled path by using Path Ops to compute the positive | 1351 /* Draws an inverse filled path by using Path Ops to compute the positive |
1366 * inverse using the current clip as the inverse bounds. | 1352 * inverse using the current clip as the inverse bounds. |
1367 * Return true if this was an inverse path and was properly handled, | 1353 * Return true if this was an inverse path and was properly handled, |
1368 * otherwise returns false and the normal drawing routine should continue, | 1354 * otherwise returns false and the normal drawing routine should continue, |
1369 * either as a (incorrect) fallback or because the path was not inverse | 1355 * either as a (incorrect) fallback or because the path was not inverse |
1370 * in the first place. | 1356 * in the first place. |
1371 */ | 1357 */ |
1372 bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath, | 1358 bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath, |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 pdfDest->appendScalar(p.x()); | 1478 pdfDest->appendScalar(p.x()); |
1493 pdfDest->appendScalar(p.y()); | 1479 pdfDest->appendScalar(p.y()); |
1494 pdfDest->appendInt(0); // Leave zoom unchanged | 1480 pdfDest->appendInt(0); // Leave zoom unchanged |
1495 SkString name(static_cast<const char*>(dest.nameData->data())); | 1481 SkString name(static_cast<const char*>(dest.nameData->data())); |
1496 dict->insertObject(name, std::move(pdfDest)); | 1482 dict->insertObject(name, std::move(pdfDest)); |
1497 } | 1483 } |
1498 } | 1484 } |
1499 | 1485 |
1500 sk_sp<SkPDFObject> SkPDFDevice::makeFormXObjectFromDevice() { | 1486 sk_sp<SkPDFObject> SkPDFDevice::makeFormXObjectFromDevice() { |
1501 SkMatrix inverseTransform = SkMatrix::I(); | 1487 SkMatrix inverseTransform = SkMatrix::I(); |
1502 if (!this->initialTransform().isIdentity()) { | 1488 if (!fInitialTransform.isIdentity()) { |
1503 if (!this->initialTransform().invert(&inverseTransform)) { | 1489 if (!fInitialTransform.invert(&inverseTransform)) { |
1504 SkDEBUGFAIL("Layer initial transform should be invertible."); | 1490 SkDEBUGFAIL("Layer initial transform should be invertible."); |
1505 inverseTransform.reset(); | 1491 inverseTransform.reset(); |
1506 } | 1492 } |
1507 } | 1493 } |
1508 sk_sp<SkPDFObject> xobject = | 1494 sk_sp<SkPDFObject> xobject = |
1509 SkPDFMakeFormXObject(this->content(), this->copyMediaBox(), | 1495 SkPDFMakeFormXObject(this->content(), this->copyMediaBox(), |
1510 this->makeResourceDict(), inverseTransform, nullptr
); | 1496 this->makeResourceDict(), inverseTransform, nullptr
); |
1511 // We always draw the form xobjects that we create back into the device, so | 1497 // We always draw the form xobjects that we create back into the device, so |
1512 // we simply preserve the font usage instead of pulling it out and merging | 1498 // we simply preserve the font usage instead of pulling it out and merging |
1513 // it back in later. | 1499 // it back in later. |
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2151 } | 2137 } |
2152 | 2138 |
2153 sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) { | 2139 sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) { |
2154 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image->
height()), | 2140 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image->
height()), |
2155 image->makeNonTextureImage()); | 2141 image->makeNonTextureImage()); |
2156 } | 2142 } |
2157 | 2143 |
2158 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() { | 2144 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() { |
2159 return nullptr; | 2145 return nullptr; |
2160 } | 2146 } |
OLD | NEW |