/src/libreoffice/sw/inc/EnhancedPDFExportHelper.hxx
Line | Count | Source |
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 | | #pragma once |
21 | | |
22 | | #include <i18nlangtag/lang.h> |
23 | | #include <vcl/pdfwriter.hxx> |
24 | | #include "swrect.hxx" |
25 | | #include "swtypes.hxx" |
26 | | |
27 | | #include <memory> |
28 | | #include <vector> |
29 | | |
30 | | namespace vcl |
31 | | { |
32 | | class PDFExtOutDevData; |
33 | | } |
34 | | class OutputDevice; |
35 | | class SwFrame; |
36 | | class SwLinePortion; |
37 | | class SwPageFrame; |
38 | | class SwPrintData; |
39 | | class SwTextPainter; |
40 | | class SwEditShell; |
41 | | class StringRangeEnumerator; |
42 | | class SwTextAttr; |
43 | | class SwTextNode; |
44 | | class SwTextPaintInfo; |
45 | | class SwTextFrame; |
46 | | |
47 | | /* |
48 | | * Mapping of OOo elements to tagged pdf elements: |
49 | | * |
50 | | * OOo element tagged pdf element |
51 | | * ----------- ------------------ |
52 | | * |
53 | | * Grouping elements: |
54 | | * |
55 | | * SwRootFrame Document |
56 | | * Part |
57 | | * Art |
58 | | * SwSection Sect |
59 | | * SwFootnoteContFrame and SwFlyFrame Div |
60 | | * SwFormat "Quotations" BlockQuote |
61 | | * SwFormat "Caption" Caption |
62 | | * SwSection (TOC) TOC |
63 | | * SwTextNode in TOC TOCI |
64 | | * SwSection (Index) Index |
65 | | * |
66 | | * Block-Level Structure Elements: |
67 | | * |
68 | | * SwTextNode P |
69 | | * SwFormat "Heading" H |
70 | | * SwTextNode with Outline H1 - H6 |
71 | | * SwTextNode with NumRule L, LI, LBody |
72 | | * SwTable Table |
73 | | * SwRowFrame TR |
74 | | * SwCellFrame in Headline row or |
75 | | * SwFtm "Table Heading" TH |
76 | | * SwCellFrame TD |
77 | | * |
78 | | * Inline-Level Structure Elements: |
79 | | * |
80 | | * SwTextPortion Span |
81 | | * SwFormat "Quotation" Quote |
82 | | * SwFootnoteFrame Note |
83 | | * Form |
84 | | * Reference |
85 | | * SwFieldPortion (AuthorityField) BibEntry |
86 | | * SwFormat "Source Text" Code |
87 | | * SwFootnotePortion, SwFieldPortion (RefField) Link |
88 | | * |
89 | | * Illustration elements: |
90 | | * |
91 | | * SwFlyFrame with SwNoTextFrame Figure |
92 | | * SwFlyFrame with Math OLE Object Formula |
93 | | * |
94 | | */ |
95 | | |
96 | | struct Num_Info |
97 | | { |
98 | | const SwTextFrame& mrFrame; |
99 | 79.4k | Num_Info( const SwTextFrame& rFrame ) : mrFrame( rFrame ) {}; |
100 | | }; |
101 | | |
102 | | struct Frame_Info |
103 | | { |
104 | | const SwFrame& mrFrame; |
105 | | bool const m_isLink; |
106 | | |
107 | | Frame_Info(const SwFrame& rFrame, bool const isLink) |
108 | 243k | : mrFrame(rFrame), m_isLink(isLink) {} |
109 | | }; |
110 | | |
111 | | struct Por_Info |
112 | | { |
113 | | const SwLinePortion& mrPor; |
114 | | const SwTextPainter& mrTextPainter; |
115 | | /** this can be used to generate multiple different SE for the same portion: |
116 | | FootnoteNum: 0-> Link 1-> Lbl |
117 | | Double: 0-> Warichu 1-> WP 2-> WT |
118 | | Ruby: 0-> Ruby 1-> RT 2-> RB |
119 | | */ |
120 | | int const m_Mode; |
121 | | |
122 | | Por_Info(const SwLinePortion& rPor, const SwTextPainter& rTextPainer, int const nMode) |
123 | 1.08M | : mrPor(rPor), mrTextPainter(rTextPainer), m_Mode(nMode) {}; |
124 | | }; |
125 | | |
126 | | struct lt_TableColumn |
127 | | { |
128 | | bool operator()( tools::Long nVal1, tools::Long nVal2 ) const |
129 | 0 | { |
130 | 0 | return nVal1 + ( MINLAY - 1 ) < nVal2; |
131 | 0 | } |
132 | | }; |
133 | | |
134 | | // Analyses a given frame during painting and generates the appropriate |
135 | | // structure elements. |
136 | | class SwTaggedPDFHelper |
137 | | { |
138 | | private: |
139 | | |
140 | | // This will be incremented for each BeginTag() call. |
141 | | // It denotes the number of tags to close during EndStructureElements(); |
142 | | sal_uInt8 m_nEndStructureElement; |
143 | | |
144 | | // If an already existing tag is reopened for follows of flow frames, |
145 | | // this value stores the tag id which has to be restored. |
146 | | sal_Int32 m_nRestoreCurrentTag; |
147 | | |
148 | | vcl::PDFExtOutDevData* mpPDFExtOutDevData; |
149 | | |
150 | | const Num_Info* mpNumInfo; |
151 | | const Frame_Info* mpFrameInfo; |
152 | | const Por_Info* mpPorInfo; |
153 | | |
154 | | void OpenTagImpl(void const* pKey); |
155 | | sal_Int32 BeginTagImpl(void const* pKey,vcl::pdf::StructElement aTagRole, const OUString& rTagName); |
156 | | void BeginTag(vcl::pdf::StructElement aTagRole, const OUString& rTagName); |
157 | | void EndTag(); |
158 | | |
159 | | void SetAttributes(vcl::pdf::StructElement eType); |
160 | | |
161 | | // These functions are called by the c'tor, d'tor |
162 | | void BeginNumberedListStructureElements(); |
163 | | void BeginBlockStructureElements(); |
164 | | void BeginInlineStructureElements(); |
165 | | void EndStructureElements(); |
166 | | |
167 | | void EndCurrentAll(); |
168 | | void EndCurrentSpan(); |
169 | | void CreateCurrentSpan(SwTextPaintInfo const& rInf, OUString const& rStyleName); |
170 | | bool CheckContinueSpan(SwTextPaintInfo const& rInf, std::u16string_view rStyleName, SwTextAttr const* pInetFormatAttr); |
171 | | |
172 | | bool CheckReopenTag(); |
173 | | void CheckRestoreTag() const; |
174 | | |
175 | | public: |
176 | | |
177 | | // pFrameInfo != 0 => BeginBlockStructureElement |
178 | | // pPorInfo != 0 => BeginInlineStructureElement |
179 | | // pFrameInfo, pPorInfo = 0 => BeginNonStructureElement |
180 | | SwTaggedPDFHelper( const Num_Info* pNumInfo, const Frame_Info* pFrameInfo, const Por_Info* pPorInfo, |
181 | | OutputDevice const & rOut ); |
182 | | ~SwTaggedPDFHelper(); |
183 | | |
184 | | static bool IsExportTaggedPDF( const OutputDevice& rOut ); |
185 | | static void EndCurrentLink(OutputDevice const&); |
186 | | }; |
187 | | |
188 | | /* |
189 | | * Analyses the document structure and export Notes, Hyperlinks, References, |
190 | | * and Outline. Link ids created during pdf export are stored in |
191 | | * SwEnhancedPDFState, in order to use them during |
192 | | * tagged pdf output. Therefore the SwEnhancedPDFExportHelper is used |
193 | | * before painting. Unfortunately links from the EditEngine into the |
194 | | * Writer document require to be exported after they have been painted. |
195 | | * Therefore SwEnhancedPDFExportHelper also has to be used after the |
196 | | * painting process, the parameter bEditEngineOnly indicated that only |
197 | | * the bookmarks from the EditEngine have to be processed. |
198 | | */ |
199 | | class SwEnhancedPDFExportHelper |
200 | | { |
201 | | private: |
202 | | |
203 | | SwEditShell& mrSh; |
204 | | OutputDevice& mrOut; |
205 | | |
206 | | std::unique_ptr<StringRangeEnumerator> mpRangeEnum; |
207 | | /** The problem is that numbers in StringRangeEnumerator aren't accordant |
208 | | * to real page numbers if mbSkipEmptyPages is true, because in this case |
209 | | * empty pages are excluded from a page range and numbers in |
210 | | * StringRangeEnumerator are shifted. |
211 | | * |
212 | | * maPageNumberMap[real_page_number] is either a corresponding page number |
213 | | * in a page range without empty pages, or -1 if this page is empty. */ |
214 | | std::vector< sal_Int32 > maPageNumberMap; |
215 | | |
216 | | bool mbSkipEmptyPages; |
217 | | bool mbEditEngineOnly; |
218 | | |
219 | | const SwPrintData& mrPrintData; |
220 | | |
221 | | void EnhancedPDFExport(LanguageType const eLanguageDefault); |
222 | | |
223 | | /// Exports bibliography entry links. |
224 | | void ExportAuthorityEntryLinks(); |
225 | | |
226 | | sal_Int32 CalcOutputPageNum( const SwRect& rRect ) const; |
227 | | std::vector< sal_Int32 > CalcOutputPageNums( const SwRect& rRect ) const; |
228 | | |
229 | | void MakeHeaderFooterLinks( vcl::PDFExtOutDevData& rPDFExtOutDevData, |
230 | | const SwTextNode& rTNd, const SwRect& rLinkRect, |
231 | | sal_Int32 nDestId, const OUString& rURL, |
232 | | bool bIntern, OUString const& rContent) const; |
233 | | |
234 | | public: |
235 | | |
236 | | SwEnhancedPDFExportHelper( SwEditShell& rSh, |
237 | | OutputDevice& rOut, |
238 | | const OUString& rPageRange, |
239 | | bool bSkipEmptyPages, |
240 | | bool bEditEngineOnly, |
241 | | const SwPrintData& rPrintData ); |
242 | | |
243 | | ~SwEnhancedPDFExportHelper(); |
244 | | |
245 | | //scale and position rRectangle if we're scaling due to notes in margins. |
246 | | tools::Rectangle SwRectToPDFRect(const SwPageFrame* pCurrPage, |
247 | | const tools::Rectangle& rRectangle) const; |
248 | | |
249 | | static tools::Rectangle MapSwRectToPDFRect(const SwPageFrame* pCurrPage, |
250 | | const tools::Rectangle& rRectangle); |
251 | | static double GetSwRectToPDFRectScale(); |
252 | | }; |
253 | | |
254 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |