diff options
-rw-r--r-- | include/svx/annotation/Annotation.hxx | 4 | ||||
-rw-r--r-- | include/vcl/filter/PDFiumLibrary.hxx | 3 | ||||
-rw-r--r-- | include/vcl/pdf/PDFAnnotationMarker.hxx | 7 | ||||
-rw-r--r-- | sd/source/filter/pdf/sdpdffilter.cxx | 8 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotationmanager.cxx | 13 | ||||
-rw-r--r-- | vcl/source/filter/ipdf/pdfread.cxx | 21 | ||||
-rw-r--r-- | vcl/source/pdf/PDFiumLibrary.cxx | 64 |
7 files changed, 119 insertions, 1 deletions
diff --git a/include/svx/annotation/Annotation.hxx b/include/svx/annotation/Annotation.hxx index 6464d96c8ce2..8ffaad3f0997 100644 --- a/include/svx/annotation/Annotation.hxx +++ b/include/svx/annotation/Annotation.hxx @@ -22,6 +22,7 @@ #include <cppuhelper/basemutex.hxx> #include <svx/annotation/Annotation.hxx> #include <svx/annotation/TextAPI.hxx> +#include <vcl/bitmapex.hxx> class SdrUndoAction; class SfxViewShell; @@ -57,6 +58,7 @@ enum class AnnotationType Highlight, Line, FreeText, + Stamp }; /** Annotation data that is used at annotation creation */ @@ -74,6 +76,8 @@ struct CreationInfo bool mbColor = false; Color maColor = COL_TRANSPARENT; + + BitmapEx maBitmapEx; }; /** Data of an annotation */ diff --git a/include/vcl/filter/PDFiumLibrary.hxx b/include/vcl/filter/PDFiumLibrary.hxx index 3c087cf7b11c..d90da7286020 100644 --- a/include/vcl/filter/PDFiumLibrary.hxx +++ b/include/vcl/filter/PDFiumLibrary.hxx @@ -37,6 +37,7 @@ #include <vcl/pdf/PDFAnnotAActionType.hxx> class SvMemoryStream; +class BitmapEx; namespace vcl::pdf { @@ -80,6 +81,8 @@ public: virtual int getWidth() = 0; virtual int getHeight() = 0; virtual PDFBitmapType getFormat() = 0; + /// Convert the bitmap buffer to a BitmapEx + virtual BitmapEx createBitmapFromBuffer() = 0; }; class VCL_DLLPUBLIC PDFiumAnnotation diff --git a/include/vcl/pdf/PDFAnnotationMarker.hxx b/include/vcl/pdf/PDFAnnotationMarker.hxx index 3be2e6c8ca3d..d1217c65c3af 100644 --- a/include/vcl/pdf/PDFAnnotationMarker.hxx +++ b/include/vcl/pdf/PDFAnnotationMarker.hxx @@ -14,6 +14,7 @@ #include <tools/color.hxx> #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/point/b2dpoint.hxx> +#include <vcl/bitmapex.hxx> namespace vcl::pdf { @@ -27,6 +28,12 @@ struct VCL_DLLPUBLIC PDFAnnotationMarker Color maFillColor = COL_TRANSPARENT; }; +/** Stamp annotation marker - arbitrary bitmap as annotation */ +struct VCL_DLLPUBLIC PDFAnnotationMarkerStamp : public PDFAnnotationMarker +{ + BitmapEx maBitmapEx; +}; + /** Free text annotation marker - showing text of the annotation in the document */ struct VCL_DLLPUBLIC PDFAnnotationMarkerFreeText : public PDFAnnotationMarker { diff --git a/sd/source/filter/pdf/sdpdffilter.cxx b/sd/source/filter/pdf/sdpdffilter.cxx index 6b69530454c3..58e2dfead82f 100644 --- a/sd/source/filter/pdf/sdpdffilter.cxx +++ b/sd/source/filter/pdf/sdpdffilter.cxx @@ -210,6 +210,14 @@ bool SdPdfFilter::Import() { aInfo.meType = sdr::annotation::AnnotationType::FreeText; } + else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Stamp) + { + auto* pMarker = static_cast<vcl::pdf::PDFAnnotationMarkerStamp*>( + rPDFAnnotation.mpMarker.get()); + + aInfo.meType = sdr::annotation::AnnotationType::Stamp; + aInfo.maBitmapEx = pMarker->maBitmapEx; + } xAnnotation->setCreationInfo(aInfo); } diff --git a/sd/source/ui/annotations/annotationmanager.cxx b/sd/source/ui/annotations/annotationmanager.cxx index 98a79f902478..67f356884725 100644 --- a/sd/source/ui/annotations/annotationmanager.cxx +++ b/sd/source/ui/annotations/annotationmanager.cxx @@ -82,6 +82,7 @@ #include <svx/svdorect.hxx> #include <svx/svdopath.hxx> #include <svx/svdotext.hxx> +#include <svx/svdograf.hxx> #include <svx/xfillit0.hxx> #include <svx/xflclit.hxx> @@ -1070,6 +1071,18 @@ void AnnotationManagerImpl::SyncAnnotationObjects() applyAnnotationCommon(*pNewObject, xAnnotation); applyAnnotationProperties(*pNewObject, rInfo); } + else if (rInfo.meType == sdr::annotation::AnnotationType::Stamp) + { + pNewObject = new SdrCircObj(rModel, SdrCircKind::Full, aRectangle); + + rtl::Reference<SdrGrafObj> pGrafObject = new SdrGrafObj(rModel, Graphic(rInfo.maBitmapEx), aRectangle); + pNewObject = pGrafObject; + + applyAnnotationCommon(*pNewObject, xAnnotation); + + pGrafObject->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE)); + pGrafObject->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE)); + } else { SdrObjKind ekind = SdrObjKind::Polygon; diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index c19a6939b486..b2e97a519ed5 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -182,7 +182,8 @@ findAnnotations(const std::unique_ptr<vcl::pdf::PDFiumPage>& pPage, basegfx::B2D || eSubtype == vcl::pdf::PDFAnnotationSubType::Square || eSubtype == vcl::pdf::PDFAnnotationSubType::Ink || eSubtype == vcl::pdf::PDFAnnotationSubType::Highlight - || eSubtype == vcl::pdf::PDFAnnotationSubType::Line) + || eSubtype == vcl::pdf::PDFAnnotationSubType::Line + || eSubtype == vcl::pdf::PDFAnnotationSubType::Stamp) { OUString sAuthor = pAnnotation->getString(vcl::pdf::constDictionaryKeyTitle); OUString sText = pAnnotation->getString(vcl::pdf::constDictionaryKeyContents); @@ -330,6 +331,24 @@ findAnnotations(const std::unique_ptr<vcl::pdf::PDFiumPage>& pPage, basegfx::B2D auto pMarker = std::make_shared<vcl::pdf::PDFAnnotationMarkerFreeText>(); rPDFGraphicAnnotation.mpMarker = pMarker; } + else if (eSubtype == vcl::pdf::PDFAnnotationSubType::Stamp) + { + auto pMarker = std::make_shared<vcl::pdf::PDFAnnotationMarkerStamp>(); + rPDFGraphicAnnotation.mpMarker = pMarker; + + auto nObjects = pAnnotation->getObjectCount(); + + for (int nIndex = 0; nIndex < nObjects; nIndex++) + { + auto pPageObject = pAnnotation->getObject(nIndex); + if (pPageObject->getType() == vcl::pdf::PDFPageObjectType::Image) + { + std::unique_ptr<vcl::pdf::PDFiumBitmap> pBitmap + = pPageObject->getImageBitmap(); + pMarker->maBitmapEx = pBitmap->createBitmapFromBuffer(); + } + } + } } } } diff --git a/vcl/source/pdf/PDFiumLibrary.cxx b/vcl/source/pdf/PDFiumLibrary.cxx index 553be738c8f5..4c3872979d1d 100644 --- a/vcl/source/pdf/PDFiumLibrary.cxx +++ b/vcl/source/pdf/PDFiumLibrary.cxx @@ -28,6 +28,8 @@ #include <o3tl/string_view.hxx> #include <vcl/BitmapWriteAccess.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/dibtools.hxx> using namespace com::sun::star; @@ -214,6 +216,7 @@ public: int getWidth() override; int getHeight() override; PDFBitmapType getFormat() override; + BitmapEx createBitmapFromBuffer() override; }; class PDFiumPathSegmentImpl final : public PDFiumPathSegment @@ -1097,6 +1100,67 @@ PDFBitmapType PDFiumBitmapImpl::getFormat() return static_cast<PDFBitmapType>(FPDFBitmap_GetFormat(mpBitmap)); } +BitmapEx PDFiumBitmapImpl::createBitmapFromBuffer() +{ + BitmapEx aBitmapEx; + + const vcl::pdf::PDFBitmapType eFormat = getFormat(); + if (eFormat == vcl::pdf::PDFBitmapType::Unknown) + return aBitmapEx; + + const int nWidth = getWidth(); + const int nHeight = getHeight(); + const int nStride = getStride(); + + switch (eFormat) + { + case vcl::pdf::PDFBitmapType::BGR: + { + aBitmapEx = BitmapEx(Size(nWidth, nHeight), vcl::PixelFormat::N24_BPP); + ReadRawDIB(aBitmapEx, getBuffer(), ScanlineFormat::N24BitTcBgr, nHeight, nStride); + } + break; + + case vcl::pdf::PDFBitmapType::BGRx: + { + aBitmapEx = BitmapEx(Size(nWidth, nHeight), vcl::PixelFormat::N24_BPP); + ReadRawDIB(aBitmapEx, getBuffer(), ScanlineFormat::N32BitTcRgba, nHeight, nStride); + } + break; + + case vcl::pdf::PDFBitmapType::BGRA: + { + Bitmap aBitmap(Size(nWidth, nHeight), vcl::PixelFormat::N24_BPP); + AlphaMask aMask(Size(nWidth, nHeight)); + { + BitmapScopedWriteAccess pWriteAccess(aBitmap); + BitmapScopedWriteAccess pMaskAccess(aMask); + ConstScanline pBuffer = getBuffer(); + std::vector<sal_uInt8> aScanlineAlpha(nWidth); + for (int nRow = 0; nRow < nHeight; ++nRow) + { + ConstScanline pLine = pBuffer + (nStride * nRow); + pWriteAccess->CopyScanline(nRow, pLine, ScanlineFormat::N32BitTcBgra, nStride); + for (int nCol = 0; nCol < nWidth; ++nCol) + { + aScanlineAlpha[nCol] = pLine[3]; + pLine += 4; + } + pMaskAccess->CopyScanline(nRow, aScanlineAlpha.data(), ScanlineFormat::N8BitPal, + nWidth); + } + } + aBitmapEx = BitmapEx(aBitmap, aMask); + } + break; + + default: + break; + } + + return aBitmapEx; +} + PDFiumAnnotationImpl::PDFiumAnnotationImpl(FPDF_ANNOTATION pAnnotation) : mpAnnotation(pAnnotation) { |