Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */