/src/libwpd/src/lib/WPXPageSpan.cpp
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ |
2 | | /* libwpd |
3 | | * Version: MPL 2.0 / LGPLv2.1+ |
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 | | * Major Contributor(s): |
10 | | * Copyright (C) 2002 William Lachance (wrlach@gmail.com) |
11 | | * Copyright (C) 2002 Marc Maurer (uwog@uwog.net) |
12 | | * Copyright (C) 2006-2007 Fridrich Strba (fridrich.strba@bluewin.ch) |
13 | | * |
14 | | * For minor contributions see the git repository. |
15 | | * |
16 | | * Alternatively, the contents of this file may be used under the terms |
17 | | * of the GNU Lesser General Public License Version 2.1 or later |
18 | | * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are |
19 | | * applicable instead of those above. |
20 | | * |
21 | | * For further information visit http://libwpd.sourceforge.net |
22 | | */ |
23 | | |
24 | | /* "This product is not manufactured, approved, or supported by |
25 | | * Corel Corporation or Corel Corporation Limited." |
26 | | */ |
27 | | |
28 | | #include <algorithm> |
29 | | #include "WPXPageSpan.h" |
30 | | |
31 | | const double WPX_DEFAULT_PAGE_MARGIN_TOP = 1.0; |
32 | | const double WPX_DEFAULT_PAGE_MARGIN_BOTTOM = 1.0; |
33 | | |
34 | | const unsigned char DUMMY_INTERNAL_HEADER_FOOTER = 16; |
35 | | |
36 | | WPXPageSpan::WPXPageSpan() : |
37 | 0 | m_isPageNumberSuppressed(false), |
38 | 0 | m_formLength(11.0), |
39 | 0 | m_formWidth(8.5f), |
40 | 0 | m_formOrientation(PORTRAIT), |
41 | 0 | m_marginLeft(1.0), |
42 | 0 | m_marginRight(1.0), |
43 | 0 | m_marginTop(WPX_DEFAULT_PAGE_MARGIN_TOP), |
44 | 0 | m_marginBottom(WPX_DEFAULT_PAGE_MARGIN_BOTTOM), |
45 | 0 | m_pageNumberPosition(PAGENUMBER_POSITION_NONE), |
46 | 0 | m_isPageNumberOverridden(false), |
47 | 0 | m_pageNumberOverride(0), |
48 | 0 | m_pageNumberingType(ARABIC), |
49 | 0 | m_pageNumberingFontName(/*WP6_DEFAULT_FONT_NAME*/"Times New Roman"), // EN PAS DEFAULT FONT AAN VOOR WP5/6/etc |
50 | 0 | m_pageNumberingFontSize(12.0/*WP6_DEFAULT_FONT_SIZE*/), // FIXME ME!!!!!!!!!!!!!!!!!!! HELP WP6_DEFAULT_FONT_SIZE |
51 | 0 | m_headerFooterList(), |
52 | 0 | m_pageSpan(1) |
53 | 0 | { |
54 | 0 | for (bool &i : m_isHeaderFooterSuppressed) |
55 | 0 | i=false; |
56 | 0 | } |
57 | | |
58 | | // NB: this is not a literal "clone" function: it is contingent on the side margins that are passed, |
59 | | // and suppression and override variables are not copied |
60 | | WPXPageSpan::WPXPageSpan(const WPXPageSpan &page, double paragraphMarginLeft, double paragraphMarginRight) : |
61 | 0 | m_isPageNumberSuppressed(false), |
62 | 0 | m_formLength(page.getFormLength()), |
63 | 0 | m_formWidth(page.getFormWidth()), |
64 | 0 | m_formOrientation(page.getFormOrientation()), |
65 | 0 | m_marginLeft(page.getMarginLeft()+paragraphMarginLeft), |
66 | 0 | m_marginRight(page.getMarginRight()+paragraphMarginRight), |
67 | 0 | m_marginTop(page.getMarginTop()), |
68 | 0 | m_marginBottom(page.getMarginBottom()), |
69 | 0 | m_pageNumberPosition(page.getPageNumberPosition()), |
70 | 0 | m_isPageNumberOverridden(false), |
71 | 0 | m_pageNumberOverride(0), |
72 | 0 | m_pageNumberingType(page.getPageNumberingType()), |
73 | 0 | m_pageNumberingFontName(page.getPageNumberingFontName()), |
74 | 0 | m_pageNumberingFontSize(page.getPageNumberingFontSize()), |
75 | 0 | m_headerFooterList(page.getHeaderFooterList()), |
76 | 0 | m_pageSpan(page.getPageSpan()) |
77 | 0 | { |
78 | 0 | for (bool &i : m_isHeaderFooterSuppressed) |
79 | 0 | i = false; |
80 | 0 | } |
81 | | |
82 | | WPXPageSpan::~WPXPageSpan() |
83 | 0 | { |
84 | 0 | } |
85 | | |
86 | | |
87 | | void WPXPageSpan::setHeaderFooter(const WPXHeaderFooterType type, const unsigned char headerFooterType, const WPXHeaderFooterOccurrence occurrence, |
88 | | const std::shared_ptr<WPXSubDocument> &subDocument, WPXTableList tableList) |
89 | 0 | { |
90 | 0 | WPXHeaderFooter headerFooter(type, occurrence, headerFooterType, subDocument, tableList); |
91 | 0 | switch (occurrence) |
92 | 0 | { |
93 | 0 | case ALL: |
94 | 0 | case NEVER: |
95 | 0 | _removeHeaderFooter(type, ODD); |
96 | 0 | _removeHeaderFooter(type, EVEN); |
97 | 0 | _removeHeaderFooter(type, ALL); |
98 | 0 | break; |
99 | 0 | case ODD: |
100 | 0 | _removeHeaderFooter(type, ODD); |
101 | 0 | _removeHeaderFooter(type, ALL); |
102 | 0 | break; |
103 | 0 | case EVEN: |
104 | 0 | _removeHeaderFooter(type, EVEN); |
105 | 0 | _removeHeaderFooter(type, ALL); |
106 | 0 | break; |
107 | 0 | default: |
108 | 0 | break; |
109 | 0 | } |
110 | | |
111 | 0 | if ((occurrence != NEVER) && (subDocument)) |
112 | 0 | m_headerFooterList.push_back(headerFooter); |
113 | |
|
114 | 0 | bool containsHFLeft = _containsHeaderFooter(type, ODD); |
115 | 0 | bool containsHFRight = _containsHeaderFooter(type, EVEN); |
116 | |
|
117 | 0 | WPD_DEBUG_MSG(("Contains HFL: %i HFR: %i\n", containsHFLeft, containsHFRight)); |
118 | 0 | if (containsHFLeft && !containsHFRight) |
119 | 0 | { |
120 | 0 | WPD_DEBUG_MSG(("Inserting dummy header right\n")); |
121 | 0 | WPXHeaderFooter dummyHeader(type, EVEN, DUMMY_INTERNAL_HEADER_FOOTER, nullptr); |
122 | 0 | m_headerFooterList.push_back(dummyHeader); |
123 | 0 | } |
124 | 0 | else if (!containsHFLeft && containsHFRight) |
125 | 0 | { |
126 | 0 | WPD_DEBUG_MSG(("Inserting dummy header left\n")); |
127 | 0 | WPXHeaderFooter dummyHeader(type, ODD, DUMMY_INTERNAL_HEADER_FOOTER, nullptr); |
128 | 0 | m_headerFooterList.push_back(dummyHeader); |
129 | 0 | } |
130 | 0 | } |
131 | | |
132 | | void WPXPageSpan::_removeHeaderFooter(WPXHeaderFooterType type, WPXHeaderFooterOccurrence occurrence) |
133 | 0 | { |
134 | 0 | for (auto iter = m_headerFooterList.begin(); iter != m_headerFooterList.end(); ++iter) |
135 | 0 | { |
136 | 0 | if ((*iter).getType() == type && (*iter).getOccurrence() == occurrence) |
137 | 0 | { |
138 | 0 | WPD_DEBUG_MSG(("WordPerfect: Removing header/footer element of type: %i since it is identical to %i\n",(*iter).getType(), type)); |
139 | 0 | m_headerFooterList.erase(iter); |
140 | 0 | return; |
141 | 0 | } |
142 | 0 | } |
143 | 0 | } |
144 | | |
145 | | bool WPXPageSpan::_containsHeaderFooter(WPXHeaderFooterType type, WPXHeaderFooterOccurrence occurrence) |
146 | 0 | { |
147 | 0 | for (auto &iter : m_headerFooterList) |
148 | 0 | { |
149 | 0 | if (iter.getType()==type && iter.getOccurrence()==occurrence) |
150 | 0 | return true; |
151 | 0 | } |
152 | | |
153 | 0 | return false; |
154 | 0 | } |
155 | | |
156 | | inline bool operator==(const WPXHeaderFooter &headerFooter1, const WPXHeaderFooter &headerFooter2) |
157 | 0 | { |
158 | 0 | return ((headerFooter1.getType() == headerFooter2.getType()) && |
159 | 0 | (headerFooter1.getSubDocument() == headerFooter2.getSubDocument()) && |
160 | 0 | (headerFooter1.getOccurrence() == headerFooter2.getOccurrence()) && |
161 | 0 | (headerFooter1.getInternalType() == headerFooter2.getInternalType())); |
162 | 0 | } |
163 | | |
164 | | bool operator==(const WPXPageSpan &page1, const WPXPageSpan &page2) |
165 | 0 | { |
166 | 0 | if ((page1.getMarginLeft() != page2.getMarginLeft()) || (page1.getMarginRight() != page2.getMarginRight()) || |
167 | 0 | (page1.getMarginTop() != page2.getMarginTop())|| (page1.getMarginBottom() != page2.getMarginBottom())) |
168 | 0 | return false; |
169 | | |
170 | 0 | if (page1.getPageNumberPosition() != page2.getPageNumberPosition()) |
171 | 0 | return false; |
172 | | |
173 | 0 | if (page1.getPageNumberSuppression() != page2.getPageNumberSuppression()) |
174 | 0 | return false; |
175 | | |
176 | 0 | if (page1.getPageNumberOverriden() != page2.getPageNumberOverriden() || |
177 | 0 | page1.getPageNumberOverride() != page2.getPageNumberOverride()) |
178 | 0 | return false; |
179 | | |
180 | 0 | if (page1.getPageNumberingType() != page2.getPageNumberingType()) |
181 | 0 | return false; |
182 | | |
183 | 0 | if (page1.getPageNumberingFontName() != page2.getPageNumberingFontName() || |
184 | 0 | page1.getPageNumberingFontSize() != page2.getPageNumberingFontSize()) |
185 | 0 | return false; |
186 | | |
187 | 0 | for (unsigned char i=0; i<WPX_NUM_HEADER_FOOTER_TYPES; i++) |
188 | 0 | { |
189 | 0 | if (page1.getHeaderFooterSuppression(i) != page2.getHeaderFooterSuppression(i)) |
190 | 0 | return false; |
191 | 0 | } |
192 | | |
193 | | // NOTE: yes this is O(n^2): so what? n=4 at most |
194 | 0 | const std::vector<WPXHeaderFooter> headerFooterList1 = page1.getHeaderFooterList(); |
195 | 0 | const std::vector<WPXHeaderFooter> headerFooterList2 = page2.getHeaderFooterList(); |
196 | 0 | std::vector<WPXHeaderFooter>::const_iterator iter1; |
197 | 0 | std::vector<WPXHeaderFooter>::const_iterator iter2; |
198 | |
|
199 | 0 | for (iter1 = headerFooterList1.begin(); iter1 != headerFooterList1.end(); ++iter1) |
200 | 0 | { |
201 | 0 | if (std::find(headerFooterList2.begin(), headerFooterList2.end(), (*iter1)) == headerFooterList2.end()) |
202 | 0 | return false; |
203 | 0 | } |
204 | | |
205 | | // If we came here, we know that every header/footer that is found in the first page span is in the second too. |
206 | | // But this is not enought for us to know whether the page spans are equal. Now we have to check in addition |
207 | | // whether every header/footer that is in the second one is in the first too. If someone wants to optimize this, |
208 | | // (s)he is most welcome :-) |
209 | | |
210 | 0 | for (iter2 = headerFooterList2.begin(); iter2 != headerFooterList2.end(); ++iter2) |
211 | 0 | { |
212 | 0 | if (std::find(headerFooterList1.begin(), headerFooterList1.end(), (*iter2)) == headerFooterList1.end()) |
213 | 0 | return false; |
214 | 0 | } |
215 | | |
216 | | |
217 | 0 | WPD_DEBUG_MSG(("WordPerfect: WPXPageSpan == comparison finished, found no differences\n")); |
218 | |
|
219 | 0 | return true; |
220 | 0 | } |
221 | | /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ |