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 |