LibreOffice Module sd (master) 1
sdpdffilter.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <sfx2/docfile.hxx>
23#include <svx/svdograf.hxx>
24#include <o3tl/safeint.hxx>
25
26#include <sdpage.hxx>
27#include <drawdoc.hxx>
28#include <sdpdffilter.hxx>
29
30#include <vcl/graph.hxx>
31#include <vcl/pdfread.hxx>
32
33#include <Annotation.hxx>
34
35#include <com/sun/star/office/XAnnotation.hpp>
36#include <com/sun/star/text/XText.hpp>
37
39
40using namespace css;
41
43 : SdFilter(rMedium, rDocShell)
44{
45}
46
48
50{
51 const OUString aFileName(
53
54 std::vector<vcl::PDFGraphicResult> aGraphics;
55 if (vcl::ImportPDFUnloaded(aFileName, aGraphics) == 0)
56 return false;
57
58 bool bWasLocked = mrDocument.isLocked();
59 mrDocument.setLock(true);
60 const bool bSavedUndoEnabled = mrDocument.IsUndoEnabled();
62
63 // Add as many pages as we need up-front.
65 for (size_t i = 0; i < aGraphics.size() - 1; ++i)
66 {
68 }
69
70 for (vcl::PDFGraphicResult const& rPDFGraphicResult : aGraphics)
71 {
72 const Graphic& rGraphic = rPDFGraphicResult.GetGraphic();
73 const Size& aSizeHMM = rPDFGraphicResult.GetSize();
74
75 const sal_Int32 nPageNumber = rGraphic.getPageNumber();
76 assert(nPageNumber >= 0 && o3tl::make_unsigned(nPageNumber) < aGraphics.size());
77
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?
81 return false;
82
83 // Make the page size match the rendered image.
84 pPage->SetSize(aSizeHMM);
85
86 rtl::Reference<SdrGrafObj> pSdrGrafObj = new SdrGrafObj(
87 pPage->getSdrModelFromSdrPage(), rGraphic, tools::Rectangle(Point(), aSizeHMM));
88
89 pSdrGrafObj->SetResizeProtect(true);
90 pSdrGrafObj->SetMoveProtect(true);
91
92 pPage->InsertObject(pSdrGrafObj.get());
93
94 for (auto const& rPDFAnnotation : rPDFGraphicResult.GetAnnotations())
95 {
96 uno::Reference<office::XAnnotation> xAnnotation;
97 pPage->createAnnotation(xAnnotation);
98
99 xAnnotation->setAuthor(rPDFAnnotation.maAuthor);
100
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);
111
112 if (rPDFAnnotation.mpMarker)
113 {
114 auto* pAnnotation = static_cast<sd::Annotation*>(xAnnotation.get());
115 pAnnotation->createCustomAnnotationMarker();
116 sd::CustomAnnotationMarker& rCustomAnnotationMarker
117 = pAnnotation->getCustomAnnotationMarker();
118
119 rCustomAnnotationMarker.maLineColor = rPDFAnnotation.maColor;
120
121 if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Polygon)
122 {
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);
128 }
129 else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Square)
130 {
131 auto* pMarker = static_cast<vcl::pdf::PDFAnnotationMarkerSquare*>(
132 rPDFAnnotation.mpMarker.get());
134 = basegfx::utils::createPolygonFromRect(rPDFAnnotation.maRectangle);
135 rCustomAnnotationMarker.mnLineWidth = pMarker->mnWidth;
136 rCustomAnnotationMarker.maFillColor = pMarker->maFillColor;
137 rCustomAnnotationMarker.maPolygons.push_back(aPoly);
138 }
139 else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Circle)
140 {
141 auto* pMarker = static_cast<vcl::pdf::PDFAnnotationMarkerCircle*>(
142 rPDFAnnotation.mpMarker.get());
143
144 basegfx::B2DPoint rCenter = rPDFAnnotation.maRectangle.getCenter();
145 double fRadiusX = rPDFAnnotation.maRectangle.getWidth() / 2;
146 double fRadiusY = rPDFAnnotation.maRectangle.getHeight() / 2;
147
149 = basegfx::utils::createPolygonFromEllipse(rCenter, fRadiusX, fRadiusY);
150 rCustomAnnotationMarker.mnLineWidth = pMarker->mnWidth;
151 rCustomAnnotationMarker.maFillColor = pMarker->maFillColor;
152 rCustomAnnotationMarker.maPolygons.push_back(aPoly);
153 }
154 else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Ink)
155 {
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;
163 }
164 else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Highlight)
165 {
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);
177 }
178 else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Line)
179 {
180 auto* pMarker = static_cast<vcl::pdf::PDFAnnotationMarkerLine*>(
181 rPDFAnnotation.mpMarker.get());
182
184 aPoly.append(pMarker->maLineStart);
185 aPoly.append(pMarker->maLineEnd);
186 rCustomAnnotationMarker.maPolygons.push_back(aPoly);
187
188 rCustomAnnotationMarker.mnLineWidth = pMarker->mnWidth;
189 rCustomAnnotationMarker.maFillColor = COL_TRANSPARENT;
190 }
191 }
192 else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::FreeText)
193 {
194 auto* pAnnotation = static_cast<sd::Annotation*>(xAnnotation.get());
195 pAnnotation->setIsFreeText(true);
196 }
197 }
198 }
199 mrDocument.setLock(bWasLocked);
200 mrDocument.EnableUndo(bSavedUndoEnabled);
201 return true;
202}
203
204bool SdPdfFilter::Export() { return false; }
205
206/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsTransparent() const
void SetAlpha(sal_uInt8 nAlpha)
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE) override
sal_Int32 getPageNumber() const
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void CreateFirstPages(SdDrawDocument const *pRefDocument=nullptr)
if the document does not contain at least one handout, one slide and one notes page with at least one...
Definition: drawdoc2.cxx:493
SAL_DLLPRIVATE sal_uInt16 DuplicatePage(sal_uInt16 nPageNum)
This method acts as a simplified front end for the more complex <member>DuplicatePage()</member> meth...
Definition: drawdoc2.cxx:1215
SdPage * GetSdPage(sal_uInt16 nPgNum, PageKind ePgKind) const
Definition: drawdoc2.cxx:207
SfxMedium & mrMedium
Definition: sdfilter.hxx:52
SdDrawDocument & mrDocument
Definition: sdfilter.hxx:54
void createAnnotation(css::uno::Reference< css::office::XAnnotation > &xAnnotation)
Definition: sdpage2.cxx:560
virtual void SetSize(const Size &aSize) override
Definition: sdpage.cxx:1746
bool Import()
Definition: sdpdffilter.cxx:49
bool Export() override
SdPdfFilter(SfxMedium &rMedium, ::sd::DrawDocShell &rDocShell)
Definition: sdpdffilter.cxx:42
virtual ~SdPdfFilter() override
Definition: sdpdffilter.cxx:47
bool isLocked() const
void setLock(bool bLock)
void EnableUndo(bool bEnable)
bool IsUndoEnabled() const
SdrModel & getSdrModelFromSdrPage() const
const INetURLObject & GetURLObject() const
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
void createCustomAnnotationMarker()
Definition: Annotation.hxx:121
void setIsFreeText(bool value)
Definition: Annotation.hxx:136
constexpr ::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
B2DPolygon createPolygonFromEllipse(const B2DPoint &rCenter, double fRadiusX, double fRadiusY, sal_uInt32 nStartQuadrant=0)
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
size_t ImportPDFUnloaded(const OUString &rURL, std::vector< PDFGraphicResult > &rGraphics)
std::vector< basegfx::B2DPolygon > maPolygons
Definition: Annotation.hxx:73