1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <sfx2/docfile.hxx>
23 #include <svx/svdograf.hxx>
24 #include <o3tl/safeint.hxx>
27 #include <drawdoc.hxx>
28 #include <sdpdffilter.hxx>
30 #include <vcl/graph.hxx>
31 #include <vcl/pdfread.hxx>
33 #include <Annotation.hxx>
35 #include <com/sun/star/office/XAnnotation.hpp>
36 #include <com/sun/star/text/XText.hpp>
38 #include <basegfx/polygon/b2dpolygontools.hxx>
42 SdPdfFilter::SdPdfFilter(SfxMedium
& rMedium
, sd::DrawDocShell
& rDocShell
)
43 : SdFilter(rMedium
, rDocShell
)
47 SdPdfFilter::~SdPdfFilter() {}
49 bool SdPdfFilter::Import()
51 const OUString
aFileName(
52 mrMedium
.GetURLObject().GetMainURL(INetURLObject::DecodeMechanism::NONE
));
54 std::vector
<vcl::PDFGraphicResult
> aGraphics
;
55 if (vcl::ImportPDFUnloaded(aFileName
, aGraphics
) == 0)
58 bool bWasLocked
= mrDocument
.isLocked();
59 mrDocument
.setLock(true);
60 const bool bSavedUndoEnabled
= mrDocument
.IsUndoEnabled();
61 mrDocument
.EnableUndo(false);
63 // Add as many pages as we need up-front.
64 mrDocument
.CreateFirstPages();
65 for (size_t i
= 0; i
< aGraphics
.size() - 1; ++i
)
67 mrDocument
.DuplicatePage(0);
70 for (vcl::PDFGraphicResult
const& rPDFGraphicResult
: aGraphics
)
72 const Graphic
& rGraphic
= rPDFGraphicResult
.GetGraphic();
73 const Size
& aSizeHMM
= rPDFGraphicResult
.GetSize();
75 const sal_Int32 nPageNumber
= rGraphic
.getPageNumber();
76 assert(nPageNumber
>= 0 && o3tl::make_unsigned(nPageNumber
) < aGraphics
.size());
78 // Create the page and insert the Graphic.
79 SdPage
* pPage
= mrDocument
.GetSdPage(nPageNumber
, PageKind::Standard
);
80 if (!pPage
) // failed to duplicate page, out of memory?
83 // Make the page size match the rendered image.
84 pPage
->SetSize(aSizeHMM
);
86 SdrGrafObj
* pSdrGrafObj
= new SdrGrafObj(pPage
->getSdrModelFromSdrPage(), rGraphic
,
87 tools::Rectangle(Point(), aSizeHMM
));
89 pSdrGrafObj
->SetResizeProtect(true);
90 pSdrGrafObj
->SetMoveProtect(true);
92 pPage
->InsertObject(pSdrGrafObj
);
94 for (auto const& rPDFAnnotation
: rPDFGraphicResult
.GetAnnotations())
96 uno::Reference
<office::XAnnotation
> xAnnotation
;
97 pPage
->createAnnotation(xAnnotation
);
99 xAnnotation
->setAuthor(rPDFAnnotation
.maAuthor
);
101 uno::Reference
<text::XText
> xText(xAnnotation
->getTextRange());
102 xText
->setString(rPDFAnnotation
.maText
);
103 // position is in mm not 100thmm
104 geometry::RealPoint2D
aUnoPosition(rPDFAnnotation
.maRectangle
.getMinX() / 100.0,
105 rPDFAnnotation
.maRectangle
.getMinY() / 100.00);
106 geometry::RealSize2D
aUnoSize(rPDFAnnotation
.maRectangle
.getWidth() / 100.0,
107 rPDFAnnotation
.maRectangle
.getHeight() / 100.00);
108 xAnnotation
->setPosition(aUnoPosition
);
109 xAnnotation
->setSize(aUnoSize
);
110 xAnnotation
->setDateTime(rPDFAnnotation
.maDateTime
);
112 if (rPDFAnnotation
.mpMarker
)
114 auto* pAnnotation
= static_cast<sd::Annotation
*>(xAnnotation
.get());
115 pAnnotation
->createCustomAnnotationMarker();
116 sd::CustomAnnotationMarker
& rCustomAnnotationMarker
117 = pAnnotation
->getCustomAnnotationMarker();
119 rCustomAnnotationMarker
.maLineColor
= rPDFAnnotation
.maColor
;
121 if (rPDFAnnotation
.meSubType
== vcl::pdf::PDFAnnotationSubType::Polygon
)
123 auto* pMarker
= static_cast<vcl::pdf::PDFAnnotationMarkerPolygon
*>(
124 rPDFAnnotation
.mpMarker
.get());
125 rCustomAnnotationMarker
.mnLineWidth
= pMarker
->mnWidth
;
126 rCustomAnnotationMarker
.maFillColor
= pMarker
->maFillColor
;
127 rCustomAnnotationMarker
.maPolygons
.push_back(pMarker
->maPolygon
);
129 else if (rPDFAnnotation
.meSubType
== vcl::pdf::PDFAnnotationSubType::Square
)
131 auto* pMarker
= static_cast<vcl::pdf::PDFAnnotationMarkerSquare
*>(
132 rPDFAnnotation
.mpMarker
.get());
133 basegfx::B2DPolygon aPoly
134 = basegfx::utils::createPolygonFromRect(rPDFAnnotation
.maRectangle
);
135 rCustomAnnotationMarker
.mnLineWidth
= pMarker
->mnWidth
;
136 rCustomAnnotationMarker
.maFillColor
= pMarker
->maFillColor
;
137 rCustomAnnotationMarker
.maPolygons
.push_back(aPoly
);
139 else if (rPDFAnnotation
.meSubType
== vcl::pdf::PDFAnnotationSubType::Circle
)
141 auto* pMarker
= static_cast<vcl::pdf::PDFAnnotationMarkerCircle
*>(
142 rPDFAnnotation
.mpMarker
.get());
144 basegfx::B2DPoint rCenter
= rPDFAnnotation
.maRectangle
.getCenter();
145 double fRadiusX
= rPDFAnnotation
.maRectangle
.getWidth() / 2;
146 double fRadiusY
= rPDFAnnotation
.maRectangle
.getHeight() / 2;
148 basegfx::B2DPolygon aPoly
149 = basegfx::utils::createPolygonFromEllipse(rCenter
, fRadiusX
, fRadiusY
);
150 rCustomAnnotationMarker
.mnLineWidth
= pMarker
->mnWidth
;
151 rCustomAnnotationMarker
.maFillColor
= pMarker
->maFillColor
;
152 rCustomAnnotationMarker
.maPolygons
.push_back(aPoly
);
154 else if (rPDFAnnotation
.meSubType
== vcl::pdf::PDFAnnotationSubType::Ink
)
156 auto* pMarker
= static_cast<vcl::pdf::PDFAnnotationMarkerInk
*>(
157 rPDFAnnotation
.mpMarker
.get());
158 rCustomAnnotationMarker
.maPolygons
.insert(
159 rCustomAnnotationMarker
.maPolygons
.end(), pMarker
->maStrokes
.begin(),
160 pMarker
->maStrokes
.end());
161 rCustomAnnotationMarker
.mnLineWidth
= pMarker
->mnWidth
;
162 rCustomAnnotationMarker
.maFillColor
= pMarker
->maFillColor
;
164 else if (rPDFAnnotation
.meSubType
== vcl::pdf::PDFAnnotationSubType::Highlight
)
166 if (!rCustomAnnotationMarker
.maLineColor
.IsTransparent())
167 rCustomAnnotationMarker
.maLineColor
.SetAlpha(255 - 0x90);
168 auto* pMarker
= static_cast<vcl::pdf::PDFAnnotationMarkerHighlight
*>(
169 rPDFAnnotation
.mpMarker
.get());
170 rCustomAnnotationMarker
.maPolygons
.insert(
171 rCustomAnnotationMarker
.maPolygons
.end(), pMarker
->maQuads
.begin(),
172 pMarker
->maQuads
.end());
173 rCustomAnnotationMarker
.mnLineWidth
= 1;
174 rCustomAnnotationMarker
.maFillColor
= rPDFAnnotation
.maColor
;
175 if (!rCustomAnnotationMarker
.maFillColor
.IsTransparent())
176 rCustomAnnotationMarker
.maFillColor
.SetAlpha(255 - 0x90);
178 else if (rPDFAnnotation
.meSubType
== vcl::pdf::PDFAnnotationSubType::Line
)
180 auto* pMarker
= static_cast<vcl::pdf::PDFAnnotationMarkerLine
*>(
181 rPDFAnnotation
.mpMarker
.get());
183 basegfx::B2DPolygon aPoly
;
184 aPoly
.append(pMarker
->maLineStart
);
185 aPoly
.append(pMarker
->maLineEnd
);
186 rCustomAnnotationMarker
.maPolygons
.push_back(aPoly
);
188 rCustomAnnotationMarker
.mnLineWidth
= pMarker
->mnWidth
;
189 rCustomAnnotationMarker
.maFillColor
= COL_TRANSPARENT
;
194 mrDocument
.setLock(bWasLocked
);
195 mrDocument
.EnableUndo(bSavedUndoEnabled
);
199 bool SdPdfFilter::Export() { return false; }
201 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */