| 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 |