| 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 | 9 |
| 10 #include "SkAnnotation.h" | 10 #include "SkAnnotation.h" |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 | 568 |
| 569 SkBaseDevice* SkPDFDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) { | 569 SkBaseDevice* SkPDFDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) { |
| 570 // PDF does not support image filters, so render them on CPU. | 570 // PDF does not support image filters, so render them on CPU. |
| 571 // Note that this rendering is done at "screen" resolution (100dpi), not | 571 // Note that this rendering is done at "screen" resolution (100dpi), not |
| 572 // printer resolution. | 572 // printer resolution. |
| 573 // FIXME: It may be possible to express some filters natively using PDF | 573 // FIXME: It may be possible to express some filters natively using PDF |
| 574 // to improve quality and file size (http://skbug.com/3043) | 574 // to improve quality and file size (http://skbug.com/3043) |
| 575 if (kImageFilter_Usage == cinfo.fUsage) { | 575 if (kImageFilter_Usage == cinfo.fUsage) { |
| 576 return SkBitmapDevice::Create(cinfo.fInfo); | 576 return SkBitmapDevice::Create(cinfo.fInfo); |
| 577 } | 577 } |
| 578 | |
| 579 SkMatrix initialTransform; | |
| 580 initialTransform.reset(); | |
| 581 SkISize size = SkISize::Make(cinfo.fInfo.width(), cinfo.fInfo.height()); | 578 SkISize size = SkISize::Make(cinfo.fInfo.width(), cinfo.fInfo.height()); |
| 582 return SkNEW_ARGS(SkPDFDevice, (size, size, initialTransform)); | 579 return SkPDFDevice::Create(size, fRasterDpi, fCanon); |
| 583 } | 580 } |
| 584 | 581 |
| 585 | 582 |
| 586 struct ContentEntry { | 583 struct ContentEntry { |
| 587 GraphicStateEntry fState; | 584 GraphicStateEntry fState; |
| 588 SkDynamicMemoryWStream fContent; | 585 SkDynamicMemoryWStream fContent; |
| 589 SkAutoTDelete<ContentEntry> fNext; | 586 SkAutoTDelete<ContentEntry> fNext; |
| 590 | 587 |
| 591 // If the stack is too deep we could get Stack Overflow. | 588 // If the stack is too deep we could get Stack Overflow. |
| 592 // So we manually destruct the object. | 589 // So we manually destruct the object. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 paint.getXfermode()->asMode(&fXfermode); | 685 paint.getXfermode()->asMode(&fXfermode); |
| 689 } | 686 } |
| 690 fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion, | 687 fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion, |
| 691 matrix, paint, hasText, | 688 matrix, paint, hasText, |
| 692 &fDstFormXObject); | 689 &fDstFormXObject); |
| 693 } | 690 } |
| 694 }; | 691 }; |
| 695 | 692 |
| 696 //////////////////////////////////////////////////////////////////////////////// | 693 //////////////////////////////////////////////////////////////////////////////// |
| 697 | 694 |
| 698 static inline SkImageInfo make_content_info(const SkISize& contentSize, | 695 SkPDFDevice::SkPDFDevice(SkISize pageSize, |
| 699 const SkMatrix* initialTransform) { | 696 SkScalar rasterDpi, |
| 700 SkImageInfo info; | 697 SkPDFCanon* canon, |
| 701 if (initialTransform) { | 698 bool flip) |
| 702 // Compute the size of the drawing area. | |
| 703 SkVector drawingSize; | |
| 704 SkMatrix inverse; | |
| 705 drawingSize.set(SkIntToScalar(contentSize.fWidth), | |
| 706 SkIntToScalar(contentSize.fHeight)); | |
| 707 if (!initialTransform->invert(&inverse)) { | |
| 708 // This shouldn't happen, initial transform should be invertible. | |
| 709 SkASSERT(false); | |
| 710 inverse.reset(); | |
| 711 } | |
| 712 inverse.mapVectors(&drawingSize, 1); | |
| 713 SkISize size = SkSize::Make(drawingSize.fX, drawingSize.fY).toRound(); | |
| 714 info = SkImageInfo::MakeUnknown(abs(size.fWidth), abs(size.fHeight)); | |
| 715 } else { | |
| 716 info = SkImageInfo::MakeUnknown(abs(contentSize.fWidth), | |
| 717 abs(contentSize.fHeight)); | |
| 718 } | |
| 719 return info; | |
| 720 } | |
| 721 | |
| 722 // TODO(vandebo) change pageSize to SkSize. | |
| 723 SkPDFDevice::SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize, | |
| 724 const SkMatrix& initialTransform) | |
| 725 : fPageSize(pageSize) | 699 : fPageSize(pageSize) |
| 726 , fContentSize(contentSize) | 700 , fContentSize(pageSize) |
| 701 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) |
| 702 , fAnnotations(NULL) |
| 703 , fResourceDict(NULL) |
| 727 , fLastContentEntry(NULL) | 704 , fLastContentEntry(NULL) |
| 728 , fLastMarginContentEntry(NULL) | 705 , fLastMarginContentEntry(NULL) |
| 706 , fDrawingArea(kContent_DrawingArea) |
| 729 , fClipStack(NULL) | 707 , fClipStack(NULL) |
| 730 , fRasterDpi(72.0f) | 708 , fFontGlyphUsage(SkNEW(SkPDFGlyphSetMap)) |
| 731 { | 709 , fRasterDpi(rasterDpi) |
| 732 const SkImageInfo info = make_content_info(contentSize, &initialTransform); | 710 , fCanon(canon) { |
| 733 | 711 SkASSERT(pageSize.width() > 0); |
| 734 // Just report that PDF does not supports perspective in the | 712 SkASSERT(pageSize.height() > 0); |
| 735 // initial transform. | 713 fLegacyBitmap.setInfo( |
| 736 NOT_IMPLEMENTED(initialTransform.hasPerspective(), true); | 714 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); |
| 737 | 715 if (flip) { |
| 738 // Skia generally uses the top left as the origin but PDF natively has the | 716 // Skia generally uses the top left as the origin but PDF |
| 739 // origin at the bottom left. This matrix corrects for that. But that only | 717 // natively has the origin at the bottom left. This matrix |
| 740 // needs to be done once, we don't do it when layering. | 718 // corrects for that. But that only needs to be done once, we |
| 741 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); | 719 // don't do it when layering. |
| 742 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1); | 720 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); |
| 743 fInitialTransform.preConcat(initialTransform); | 721 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1); |
| 744 fLegacyBitmap.setInfo(info); | 722 } else { |
| 745 | 723 fInitialTransform.setIdentity(); |
| 746 SkIRect existingClip = info.bounds(); | 724 } |
| 747 fExistingClipRegion.setRect(existingClip); | |
| 748 this->init(); | |
| 749 } | |
| 750 | |
| 751 // TODO(vandebo) change layerSize to SkSize. | |
| 752 SkPDFDevice::SkPDFDevice(const SkISize& layerSize, | |
| 753 const SkClipStack& existingClipStack, | |
| 754 const SkRegion& existingClipRegion) | |
| 755 : fPageSize(layerSize) | |
| 756 , fContentSize(layerSize) | |
| 757 , fExistingClipStack(existingClipStack) | |
| 758 , fExistingClipRegion(existingClipRegion) | |
| 759 , fLastContentEntry(NULL) | |
| 760 , fLastMarginContentEntry(NULL) | |
| 761 , fClipStack(NULL) | |
| 762 , fRasterDpi(72.0f) | |
| 763 { | |
| 764 fInitialTransform.reset(); | |
| 765 fLegacyBitmap.setInfo(make_content_info(layerSize, NULL)); | |
| 766 | |
| 767 this->init(); | |
| 768 } | 725 } |
| 769 | 726 |
| 770 SkPDFDevice::~SkPDFDevice() { | 727 SkPDFDevice::~SkPDFDevice() { |
| 771 this->cleanUp(true); | 728 this->cleanUp(true); |
| 772 } | 729 } |
| 773 | 730 |
| 774 void SkPDFDevice::init() { | 731 void SkPDFDevice::init() { |
| 775 fAnnotations = NULL; | 732 fAnnotations = NULL; |
| 776 fResourceDict = NULL; | 733 fResourceDict = NULL; |
| 777 fContentEntries.free(); | 734 fContentEntries.free(); |
| (...skipping 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2178 SkAutoTUnref<SkPDFObject> image( | 2135 SkAutoTUnref<SkPDFObject> image( |
| 2179 SkPDFCreateImageObject(*bitmap, subset)); | 2136 SkPDFCreateImageObject(*bitmap, subset)); |
| 2180 if (!image) { | 2137 if (!image) { |
| 2181 return; | 2138 return; |
| 2182 } | 2139 } |
| 2183 | 2140 |
| 2184 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()), | 2141 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()), |
| 2185 &content.entry()->fContent); | 2142 &content.entry()->fContent); |
| 2186 } | 2143 } |
| 2187 | 2144 |
| OLD | NEW |