/src/libstaroffice/src/lib/StarObjectNumericRuler.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */ |
2 | | |
3 | | /* libstaroffice |
4 | | * Version: MPL 2.0 / LGPLv2+ |
5 | | * |
6 | | * The contents of this file are subject to the Mozilla Public License Version |
7 | | * 2.0 (the "License"); you may not use this file except in compliance with |
8 | | * the License or as specified alternatively below. You may obtain a copy of |
9 | | * the License at http://www.mozilla.org/MPL/ |
10 | | * |
11 | | * Software distributed under the License is distributed on an "AS IS" basis, |
12 | | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
13 | | * for the specific language governing rights and limitations under the |
14 | | * License. |
15 | | * |
16 | | * Major Contributor(s): |
17 | | * Copyright (C) 2002 William Lachance (wrlach@gmail.com) |
18 | | * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net) |
19 | | * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch) |
20 | | * Copyright (C) 2006, 2007 Andrew Ziem |
21 | | * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr) |
22 | | * |
23 | | * |
24 | | * All Rights Reserved. |
25 | | * |
26 | | * For minor contributions see the git repository. |
27 | | * |
28 | | * Alternatively, the contents of this file may be used under the terms of |
29 | | * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"), |
30 | | * in which case the provisions of the LGPLv2+ are applicable |
31 | | * instead of those above. |
32 | | */ |
33 | | |
34 | | #include <cstring> |
35 | | #include <iomanip> |
36 | | #include <iostream> |
37 | | #include <limits> |
38 | | #include <map> |
39 | | #include <sstream> |
40 | | |
41 | | #include <librevenge/librevenge.h> |
42 | | |
43 | | #include "StarObjectNumericRuler.hxx" |
44 | | |
45 | | #include "STOFFListener.hxx" |
46 | | #include "STOFFPageSpan.hxx" |
47 | | |
48 | | #include "StarAttribute.hxx" |
49 | | #include "StarBitmap.hxx" |
50 | | #include "StarFormatManager.hxx" |
51 | | #include "StarItemPool.hxx" |
52 | | #include "StarObject.hxx" |
53 | | #include "StarState.hxx" |
54 | | #include "StarWriterStruct.hxx" |
55 | | #include "StarZone.hxx" |
56 | | #include "SWFieldManager.hxx" |
57 | | |
58 | | /** Internal: the structures of a StarObjectNumericRuler */ |
59 | | namespace StarObjectNumericRulerInternal |
60 | | { |
61 | | //////////////////////////////////////// |
62 | | //! Internal: the state of a StarObjectNumericRuler |
63 | | struct State { |
64 | | //! constructor |
65 | | State() |
66 | 254 | : m_nameToListMap() |
67 | 254 | , m_simplifyNameToListMap() |
68 | 254 | { |
69 | 254 | } |
70 | | //! a map list name to list |
71 | | std::map<librevenge::RVNGString, std::shared_ptr<STOFFList> > m_nameToListMap; |
72 | | //! a map list simpl name to list |
73 | | std::map<librevenge::RVNGString, std::shared_ptr<STOFFList> > m_simplifyNameToListMap; |
74 | | }; |
75 | | |
76 | | } |
77 | | |
78 | | //////////////////////////////////////////////////////////// |
79 | | // constructor/destructor, ... |
80 | | //////////////////////////////////////////////////////////// |
81 | | StarObjectNumericRuler::StarObjectNumericRuler(StarObject const &orig, bool duplicateState) |
82 | 254 | : StarObject(orig, duplicateState) |
83 | 254 | , m_numericRulerState(new StarObjectNumericRulerInternal::State) |
84 | 254 | { |
85 | 254 | } |
86 | | |
87 | | StarObjectNumericRuler::~StarObjectNumericRuler() |
88 | 254 | { |
89 | 254 | } |
90 | | |
91 | | //////////////////////////////////////////////////////////// |
92 | | // send data |
93 | | //////////////////////////////////////////////////////////// |
94 | | std::shared_ptr<STOFFList> StarObjectNumericRuler::getList(librevenge::RVNGString const &name) const |
95 | 179 | { |
96 | 179 | if (name.empty()) |
97 | 0 | return std::shared_ptr<STOFFList>(); |
98 | 179 | if (m_numericRulerState->m_nameToListMap.find(name)!=m_numericRulerState->m_nameToListMap.end()) |
99 | 109 | return m_numericRulerState->m_nameToListMap.find(name)->second; |
100 | 70 | auto simpName=libstoff::simplifyString(name); |
101 | 70 | if (m_numericRulerState->m_simplifyNameToListMap.find(simpName)!=m_numericRulerState->m_simplifyNameToListMap.end()) |
102 | 0 | return m_numericRulerState->m_simplifyNameToListMap.find(simpName)->second; |
103 | 70 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::getList: can not find list with name %s\n", name.cstr())); |
104 | 70 | return std::shared_ptr<STOFFList>(); |
105 | 70 | } |
106 | | |
107 | | //////////////////////////////////////////////////////////// |
108 | | // the parser |
109 | | //////////////////////////////////////////////////////////// |
110 | | bool StarObjectNumericRuler::read(StarZone &zone) |
111 | 254 | try |
112 | 254 | { |
113 | 254 | STOFFInputStreamPtr input=zone.input(); |
114 | 254 | libstoff::DebugFile &ascFile=zone.ascii(); |
115 | 254 | if (!zone.readSWHeader()) { |
116 | 5 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::read: can not read the header\n")); |
117 | 5 | return false; |
118 | 5 | } |
119 | 249 | zone.readStringsPool(); |
120 | | // sw_sw3num.cxx::Sw3IoImp::InNumRules |
121 | 510 | while (!input->isEnd()) { |
122 | 510 | long pos=input->tell(); |
123 | 510 | bool done=false; |
124 | 510 | switch (input->peek()) { |
125 | 239 | case '0': |
126 | 253 | case 'R': { |
127 | 253 | std::shared_ptr<STOFFList> list; |
128 | 253 | done=StarObjectNumericRuler::readList(zone,list); |
129 | 253 | if (!done || !list) break; |
130 | 252 | if (list->m_name.empty()) { |
131 | 0 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::read: can not find the list name\n")); |
132 | 0 | break; |
133 | 0 | } |
134 | 252 | if (m_numericRulerState->m_nameToListMap.find(list->m_name)!=m_numericRulerState->m_nameToListMap.end()) { |
135 | 0 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::read: oops a list with name %s already exists\n", list->m_name.cstr())); |
136 | 0 | } |
137 | 252 | else { |
138 | 252 | m_numericRulerState->m_nameToListMap[list->m_name]=list; |
139 | 252 | auto simpName=libstoff::simplifyString(list->m_name); |
140 | 252 | if (m_numericRulerState->m_simplifyNameToListMap.find(simpName)==m_numericRulerState->m_simplifyNameToListMap.end()) |
141 | 252 | m_numericRulerState->m_simplifyNameToListMap[simpName]=list; |
142 | 252 | } |
143 | 252 | break; |
144 | 252 | } |
145 | 257 | default: |
146 | 257 | break; |
147 | 510 | } |
148 | 510 | if (done && input->tell()>pos) |
149 | 252 | continue; |
150 | 258 | unsigned char type; |
151 | 258 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
152 | 258 | if (!zone.openSWRecord(type)) { |
153 | 6 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
154 | 6 | break; |
155 | 6 | } |
156 | 252 | libstoff::DebugStream f; |
157 | 252 | f << "StarNumericList[list-" << type << "]:"; |
158 | 252 | done=false; |
159 | 252 | switch (type) { |
160 | 0 | case '+': { // extra outline |
161 | 0 | zone.openFlagZone(); |
162 | 0 | auto N=int(input->readULong(1)); |
163 | 0 | f << "N=" << N << ","; |
164 | 0 | zone.closeFlagZone(); |
165 | 0 | if (input->tell()+3*N>zone.getRecordLastPosition()) { |
166 | 0 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::read: nExtraOutline seems bad\n")); |
167 | 0 | f << "###,"; |
168 | 0 | break; |
169 | 0 | } |
170 | 0 | f << "levSpace=["; |
171 | 0 | for (int i=0; i<N; ++i) |
172 | 0 | f << input->readULong(1) << ":" << input->readULong(2) << ","; |
173 | 0 | f << "],"; |
174 | 0 | break; |
175 | 0 | } |
176 | 0 | case '?': |
177 | 0 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::read: reading inHugeRecord(TEST_HUGE_DOCS) is not implemented\n")); |
178 | 0 | break; |
179 | 243 | case 'Z': |
180 | 243 | done=true; |
181 | 243 | break; |
182 | 9 | default: |
183 | 9 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::read: find unimplemented type\n")); |
184 | 9 | f << "###type,"; |
185 | 9 | break; |
186 | 252 | } |
187 | 252 | if (!zone.closeSWRecord(type, "StarNumericList")) { |
188 | 0 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
189 | 0 | break; |
190 | 0 | } |
191 | 252 | ascFile.addPos(pos); |
192 | 252 | ascFile.addNote(f.str().c_str()); |
193 | | |
194 | 252 | if (done) |
195 | 243 | break; |
196 | 252 | } |
197 | 249 | if (!input->isEnd()) { |
198 | 6 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::read: find extra data\n")); |
199 | 6 | ascFile.addPos(input->tell()); |
200 | 6 | ascFile.addNote("StarNumericList:###extra"); |
201 | 6 | } |
202 | 249 | return true; |
203 | 249 | } |
204 | 254 | catch (...) |
205 | 254 | { |
206 | 0 | return false; |
207 | 0 | } |
208 | | |
209 | | bool StarObjectNumericRuler::readLevel(StarZone &zone, STOFFListLevel &level) |
210 | 164 | { |
211 | 164 | STOFFInputStreamPtr input=zone.input(); |
212 | 164 | libstoff::DebugFile &ascFile=zone.ascii(); |
213 | 164 | unsigned char type; |
214 | 164 | long pos=input->tell(); |
215 | 164 | if (input->peek()!='n' || !zone.openSWRecord(type)) { |
216 | 58 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
217 | 58 | return false; |
218 | 58 | } |
219 | 106 | libstoff::DebugStream f; |
220 | 106 | f << "Entries(StarNumericList)[level-" << zone.getRecordLevel() << "]:"; |
221 | | // sw_sw3num.cxx Sw3IoImp::InNumFmt |
222 | 106 | level=STOFFListLevel(); |
223 | 106 | std::vector<uint32_t> string; |
224 | 106 | librevenge::RVNGString fontName; |
225 | 528 | for (int i=0; i<4; ++i) { |
226 | 424 | if (!zone.readString(string)) { |
227 | 2 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readLevel: can not read a string\n")); |
228 | 2 | f << "###string"; |
229 | 2 | ascFile.addPos(pos); |
230 | 2 | ascFile.addNote(f.str().c_str()); |
231 | | |
232 | 2 | zone.closeSWRecord('n', "StarNumericList"); |
233 | 2 | return true; |
234 | 2 | } |
235 | 422 | if (string.empty()) continue; |
236 | 176 | static char const* const wh[]= {"prefix", "postfix", "fontname", "fontstyle"}; |
237 | 176 | f << wh[i] << "=" << libstoff::getString(string).cstr() << ","; |
238 | 176 | if (i==0) level.m_propertyList.insert("style:num-prefix",libstoff::getString(string)); |
239 | 176 | else if (i==1) level.m_propertyList.insert("style:num-suffix",libstoff::getString(string)); |
240 | 88 | else if (i==2) fontName=libstoff::getString(string); |
241 | 176 | } |
242 | 104 | auto format=int(input->readULong(2)); |
243 | 104 | auto eType=int(input->readULong(1)); |
244 | 104 | auto cBullet=uint8_t(input->readULong(1)); |
245 | 104 | int maxLevel=0; |
246 | 104 | if (zone.isCompatibleWith(0x201)) |
247 | 104 | maxLevel=int(input->readULong(1)); |
248 | 0 | else { |
249 | 0 | bool hasLevel; |
250 | 0 | *input >> hasLevel; |
251 | 0 | if (hasLevel) maxLevel=10; |
252 | 0 | } |
253 | 104 | level.m_startValue=int(input->readULong(2)); |
254 | 104 | auto adjust=int(input->readULong(1)); |
255 | 104 | unsigned long leftSpace=input->readULong(4); |
256 | 104 | long firstLineOffset=input->readLong(4); |
257 | 104 | auto fontFamily=int(input->readULong(1)); |
258 | 104 | auto fontPitch=int(input->readULong(1)); |
259 | 104 | auto charSet=int(input->readULong(1)); |
260 | 104 | bool isSymbolFont=false; |
261 | 104 | if (!fontName.empty()) { |
262 | | // todo find where other font characteristic are stored |
263 | 86 | level.m_font.reset(new STOFFFont); |
264 | 86 | STOFFFont &font=*level.m_font; |
265 | 86 | font.m_propertyList.insert("style:font-name", fontName); |
266 | 86 | if (fontName=="StarBats" || fontName=="StarMath") { |
267 | 0 | isSymbolFont=true; |
268 | 0 | font.m_propertyList.insert("style:font-charset","x-symbol"); |
269 | 0 | } |
270 | 86 | } |
271 | 104 | if (format!=0xFFFF) f << "nFmt=" << format << ","; |
272 | 104 | if (eType<=4 || eType==9 || eType==10) { |
273 | 0 | char const *wh[]= {"A", "a", "I", "i", "1", "", "", "", "", "A"/*UPPER_LETTER_N*/, "a"/*LOWER_LETTER_N*/}; |
274 | 0 | level.m_propertyList.insert("style:num-format", wh[eType]); |
275 | 0 | level.m_type=STOFFListLevel::NUMBER; |
276 | 0 | f << "type=" << wh[eType] << ","; |
277 | 0 | } |
278 | 104 | else if (eType==5) { |
279 | 18 | level.m_propertyList.insert("text:bullet-char", " "); |
280 | 18 | level.m_type=STOFFListLevel::NONE; |
281 | 18 | f << "none,"; |
282 | 18 | } |
283 | 86 | else if (eType==6) { |
284 | 86 | level.m_type=STOFFListLevel::BULLET; |
285 | 86 | std::vector<uint8_t> buffer(1, cBullet); |
286 | 86 | std::vector<uint32_t> res; |
287 | 86 | std::vector<size_t> positions; |
288 | | // checkme if fontname is StarBats or StarMath, this does not works very well... |
289 | 86 | auto encoding=(charSet==0 && isSymbolFont) ? StarEncoding::E_SYMBOL : StarEncoding::getEncodingForId(charSet); |
290 | 86 | StarEncoding::convert(buffer, encoding, res, positions); |
291 | 86 | level.m_propertyList.insert("text:bullet-char", libstoff::getString(res)); |
292 | 86 | f << "bullet=" << libstoff::getString(res).cstr() << ","; |
293 | 86 | } |
294 | 0 | else { |
295 | 0 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readLevel: unimplemented format\n")); |
296 | | // PAGEDESC, BITMAP |
297 | 0 | level.m_type=STOFFListLevel::BULLET; |
298 | 0 | librevenge::RVNGString bullet; |
299 | 0 | libstoff::appendUnicode(0x2022, bullet); // checkme |
300 | 0 | level.m_propertyList.insert("text:bullet-char", bullet); |
301 | 0 | f << "#eType=" << eType << "," << "cBullet=" << cBullet << ","; |
302 | 0 | } |
303 | 104 | if (maxLevel) f << "nUpperLevel=" << maxLevel << ","; |
304 | 104 | if (level.m_startValue) f << "start=" << level.m_startValue << ","; |
305 | 104 | if (adjust>=0 && adjust<=5) { |
306 | 104 | char const *wh[]= {"left", "right", "justify", "center", "justify"/*block line*/, "end"}; |
307 | 104 | level.m_propertyList.insert("fo:text-align", wh[adjust]); |
308 | 104 | f << wh[adjust] << ","; |
309 | 104 | } |
310 | 0 | else { |
311 | 0 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readLevel: unknown adjust\n")); |
312 | 0 | f << "#adjust=" << adjust << ","; |
313 | 0 | } |
314 | | |
315 | 104 | if (leftSpace || firstLineOffset) { // checkme |
316 | 86 | f << "left[offset]=" << leftSpace << ","; |
317 | 86 | level.m_propertyList.insert("fo:margin-left", 0.05*double(long(leftSpace)+(firstLineOffset<0 ? -firstLineOffset: 0)), librevenge::RVNG_POINT); |
318 | 86 | } |
319 | 104 | if (firstLineOffset) { |
320 | 86 | level.m_propertyList.insert("fo:text-indent", 0.05*double(firstLineOffset), librevenge::RVNG_POINT); |
321 | 86 | f << "firstLine[offset]=" << firstLineOffset << ","; |
322 | 86 | } |
323 | 104 | if (fontFamily) f << "family[font]=" << fontFamily << ","; |
324 | 104 | if (fontPitch) f << "pitch[font]=" << fontPitch << ","; |
325 | 104 | if (charSet) f << "char[set]=" << charSet << ","; |
326 | | |
327 | 104 | int cFlags=zone.openFlagZone(); |
328 | 104 | zone.closeFlagZone(); |
329 | 104 | if (cFlags&0xF0) f << "cFlags=" << (cFlags>>4) << ","; |
330 | 104 | if (zone.isCompatibleWith(0x17, 0x22)) // the character format |
331 | 0 | f << "nFmt=" << input->readULong(2) << ","; |
332 | 104 | if (zone.isCompatibleWith(0x17,0x22, 0x101,0x201)) { // ignored by old LibreOffice |
333 | 0 | f << "bRelSpace=" << input->readULong(1) << ","; |
334 | 0 | f << "nRelLSpace=" << input->readLong(4) << ","; |
335 | 0 | } |
336 | 104 | if (zone.isCompatibleWith(0x17,0x22, 0x101)) { |
337 | 104 | auto charTextDistance=int(input->readULong(2)); |
338 | 104 | if (charTextDistance) { |
339 | 0 | level.m_propertyList.insert("text:min-label-distance", 0.05*double(charTextDistance), librevenge::RVNG_POINT); |
340 | 0 | f << "nTextOffset=" << charTextDistance << ","; |
341 | 0 | } |
342 | 104 | if (input->tell()<zone.getRecordLastPosition() && eType==8) { |
343 | 0 | f << "width=" << input->readLong(4) << ","; |
344 | 0 | f << "height=" << input->readLong(4) << ","; |
345 | 0 | auto cF=int(input->readULong(1)); |
346 | 0 | if (cF&1) f << "nVer[brush]=" << input->readULong(2) << ","; |
347 | 0 | if (cF&2) f << "nVer[vertOrient]=" << input->readULong(2) << ","; |
348 | 0 | } |
349 | 104 | } |
350 | 104 | ascFile.addPos(pos); |
351 | 104 | ascFile.addNote(f.str().c_str()); |
352 | 104 | zone.closeSWRecord('n', "StarNumericList"); |
353 | 104 | return true; |
354 | 106 | } |
355 | | |
356 | | bool StarObjectNumericRuler::readList(StarZone &zone, std::shared_ptr<STOFFList> &list) |
357 | 413 | { |
358 | 413 | STOFFInputStreamPtr input=zone.input(); |
359 | 413 | libstoff::DebugFile &ascFile=zone.ascii(); |
360 | 413 | unsigned char type; |
361 | 413 | long pos=input->tell(); |
362 | 413 | if ((input->peek()!='0' && input->peek()!='R') || !zone.openSWRecord(type)) { |
363 | 28 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
364 | 28 | return false; |
365 | 28 | } |
366 | | // sw_sw3num.cxx::Sw3IoImp::InNumRule |
367 | 385 | libstoff::DebugStream f; |
368 | 385 | f << "Entries(StarNumericList)[" << zone.getRecordLevel() << "]:"; |
369 | 385 | int val; |
370 | 385 | librevenge::RVNGString name; |
371 | 385 | if (zone.isCompatibleWith(0x201)) { |
372 | 297 | auto cFlags=int(zone.openFlagZone()); |
373 | 297 | auto nStringId=int(input->readULong(2)); |
374 | 297 | if (nStringId==0xFFFF) |
375 | 0 | ; |
376 | 297 | else if (!zone.getPoolName(nStringId, name)) |
377 | 2 | f << "###name=" << nStringId << ","; |
378 | 295 | else if (!name.empty()) |
379 | 294 | f << name.cstr() << ","; |
380 | 297 | if (cFlags&0x10) { |
381 | 14 | val=int(input->readULong(2)); // 3<<11+1<<10+(num1,num2,...,num5,bul1,...,bul5) |
382 | 14 | if (val!=0xFFFF) f << "frmtId=" << val << ","; |
383 | 14 | val=int(input->readULong(2)); |
384 | 14 | if (val) f << "poolHelpId=" << val << ","; |
385 | 14 | val=int(input->readULong(1)); |
386 | 14 | if (val) f << "poolHelpFileId=" << val << ","; |
387 | 14 | } |
388 | 297 | if (cFlags&0x20) f << "invalid,"; |
389 | 297 | if (cFlags&0x40) f << "continuous,"; |
390 | 297 | if ((cFlags&0x80) && zone.isCompatibleWith(0x211)) f << "absolute[spaces],"; |
391 | 297 | } |
392 | 385 | val=int(input->readULong(1)); |
393 | | // initialise list to default |
394 | 385 | list.reset(new STOFFList(val==0)); |
395 | 385 | if (val==0) f << "outline,"; // OUTLINE_RULE, NUM_RULE |
396 | 118 | else if (val!=1) { |
397 | 104 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readList: unknown type\n")); |
398 | 104 | f << "##eType=" << val << ","; |
399 | 104 | } |
400 | 385 | list->m_name=name; |
401 | 385 | STOFFListLevel defLevel; |
402 | 385 | defLevel.m_type=STOFFListLevel::NUMBER; |
403 | 385 | defLevel.m_propertyList.insert("style:num-format", "1"); |
404 | 4.23k | for (int i=0; i<10; ++i) list->set(i+1, defLevel); |
405 | 385 | if (zone.isCompatibleWith(0x201)) |
406 | 297 | zone.closeFlagZone(); |
407 | 385 | auto nFormat=int(input->readULong(1)); |
408 | 385 | long lastPos=zone.getRecordLastPosition(); |
409 | 385 | f << "nFormat=" << nFormat << ","; |
410 | 385 | if (input->tell()+nFormat>lastPos) { |
411 | 12 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readList: nFormat seems bad\n")); |
412 | 12 | f << "###,"; |
413 | 12 | ascFile.addPos(pos); |
414 | 12 | ascFile.addNote(f.str().c_str()); |
415 | 12 | zone.closeSWRecord(type, "StarNumericList"); |
416 | 12 | return true; |
417 | 12 | } |
418 | 373 | std::vector<int> levels; |
419 | 373 | f << "lvl=["; |
420 | 1.17k | for (int i=0; i<nFormat; ++i) { |
421 | 801 | levels.push_back(int(input->readULong(1))); |
422 | 801 | f << levels.back() << ","; |
423 | 801 | } |
424 | 373 | f << "],"; |
425 | 373 | ascFile.addPos(pos); |
426 | 373 | ascFile.addNote(f.str().c_str()); |
427 | | |
428 | 373 | int nKnownFormat=nFormat>10 ? 10 : nFormat; |
429 | 479 | for (int i=0; i<nKnownFormat; ++i) { |
430 | 164 | pos=input->tell(); |
431 | 164 | STOFFListLevel level; |
432 | 164 | if (StarObjectNumericRuler::readLevel(zone, level)) { |
433 | 106 | list->set(levels[size_t(i)]+1, level); |
434 | 106 | continue; |
435 | 106 | } |
436 | 58 | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readList: can not read a format\n")); |
437 | 58 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
438 | 58 | break; |
439 | 164 | } |
440 | | |
441 | 373 | zone.closeSWRecord(type, "StarNumericList"); |
442 | 373 | return true; |
443 | 385 | } |
444 | | |
445 | | bool StarObjectNumericRuler::readAttributeLevel(StarZone &zone, int vers, long lastPos, STOFFListLevel &level) |
446 | 75.0k | { |
447 | 75.0k | STOFFInputStreamPtr input=zone.input(); |
448 | 75.0k | long pos=input->tell(); |
449 | 75.0k | libstoff::DebugFile &ascFile=zone.ascii(); |
450 | 75.0k | libstoff::DebugStream f; |
451 | 75.0k | f << "Entries(StarAttribute)[" << zone.getRecordLevel() << "]:paraBullet,"; |
452 | | |
453 | 75.0k | level=STOFFListLevel(); |
454 | | // svx_bulitem.cxx SvxBulletItem::SvxBulletItem |
455 | 75.0k | uint16_t style; |
456 | 75.0k | *input >> style; |
457 | 75.0k | uint16_t charSet=0; |
458 | 75.0k | bool isSymbolFont=false; |
459 | 75.0k | int alignement=-1; |
460 | 75.0k | if (style==128) { |
461 | 252 | f << "bitmap,"; |
462 | 252 | StarBitmap bitmap; |
463 | 252 | librevenge::RVNGBinaryData data; |
464 | 252 | std::string dType; |
465 | 252 | if (!bitmap.readBitmap(zone, true, lastPos, data, dType)) { |
466 | 252 | f << "###BM,"; |
467 | 252 | ascFile.addPos(pos); |
468 | 252 | ascFile.addNote(f.str().c_str()); |
469 | 252 | return false; |
470 | 252 | } |
471 | 252 | } |
472 | 74.8k | else { |
473 | 74.8k | f << "type=" << style << ","; |
474 | | // SvxBulletItem::CreateFont |
475 | 74.8k | f << "font=["; |
476 | 74.8k | level.m_font.reset(new STOFFFont); |
477 | 74.8k | auto &font=*level.m_font; |
478 | | |
479 | 74.8k | STOFFColor col; |
480 | 74.8k | if (!input->readColor(col)) { |
481 | 3.32k | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readAttributeLevel: can not read a color\n")); |
482 | 3.32k | f << "###color,"; |
483 | 3.32k | ascFile.addPos(pos); |
484 | 3.32k | ascFile.addNote(f.str().c_str()); |
485 | 3.32k | return false; |
486 | 3.32k | } |
487 | 71.5k | else { |
488 | 71.5k | font.m_propertyList.insert("fo:color", col.str().c_str()); |
489 | 71.5k | if (!col.isBlack()) |
490 | 17.0k | f << "color=" << col << ","; |
491 | 71.5k | } |
492 | 71.5k | uint16_t family, pitch, align, weight, underline, strikeOut, italic; |
493 | 71.5k | *input >> family >> charSet >> pitch >> align >> weight >> underline >> strikeOut >> italic; |
494 | 71.5k | alignement=int(align); |
495 | 71.5k | if (family) f << "family=" << family << ","; |
496 | 71.5k | if (charSet) f << "charSet=" << charSet << ","; |
497 | 71.5k | if (pitch) f << "pitch=" << pitch << ","; |
498 | 71.5k | if (weight) f << "weight=" << weight << ","; |
499 | 71.5k | if (underline) f << "underline=" << underline << ","; |
500 | 71.5k | if (strikeOut) f << "strikeOut=" << strikeOut << ","; |
501 | 71.5k | if (italic) f << "italic=" << italic << ","; |
502 | 71.5k | std::vector<uint32_t> text; |
503 | 71.5k | if (!zone.readString(text)) { |
504 | 6.60k | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readAttributeLevel: can not read a name\n")); |
505 | 6.60k | f << "###fontName,"; |
506 | 6.60k | ascFile.addPos(pos); |
507 | 6.60k | ascFile.addNote(f.str().c_str()); |
508 | 6.60k | return false; |
509 | 6.60k | } |
510 | 64.9k | if (!text.empty()) { |
511 | 51.4k | auto name=libstoff::getString(text); |
512 | 51.4k | font.m_propertyList.insert("style:font-name", name); |
513 | 51.4k | f << name.cstr() << ","; |
514 | 51.4k | if (name=="StarBats" || name=="StarMath") { |
515 | 7.64k | font.m_propertyList.insert("style:font-charset","x-symbol"); |
516 | 7.64k | isSymbolFont=true; |
517 | 7.64k | } |
518 | 51.4k | } |
519 | 64.9k | if (vers==1) f << "size=" << input->readLong(4) << "x" << input->readLong(4) << ","; |
520 | 64.9k | bool outline, shadow, transparent; |
521 | 64.9k | *input >> outline >> shadow >> transparent; |
522 | 64.9k | if (outline) f << "outline,"; |
523 | 64.9k | if (shadow) f << "shadow,"; |
524 | 64.9k | if (transparent) f << "transparent,"; |
525 | 64.9k | f << "],"; |
526 | | // |
527 | | // time to update the font |
528 | | // |
529 | 64.9k | font.m_propertyList.insert("style:font-pitch", pitch==1 ? "fixed" : "variable"); |
530 | 64.9k | if (weight==5) |
531 | 8.49k | font.m_propertyList.insert("fo:font-weight", "normal"); |
532 | 56.4k | else if (weight==8) |
533 | 2.65k | font.m_propertyList.insert("fo:font-weight", "bold"); |
534 | 53.7k | else if (weight>=1 && weight<=9) |
535 | 1.77k | font.m_propertyList.insert("fo:font-weight", weight*100, librevenge::RVNG_GENERIC); |
536 | 52.0k | else // 10: WEIGHT_BLACK |
537 | 52.0k | font.m_propertyList.insert("fo:font-weight", "normal"); |
538 | 64.9k | switch (underline) { |
539 | 21.0k | case 0: // none |
540 | 21.3k | case 4: // unknown |
541 | 21.3k | font.m_propertyList.insert("style:text-underline-type", "none"); |
542 | 21.3k | break; |
543 | 6.30k | case 1: // single |
544 | 7.39k | case 2: // double |
545 | 7.39k | font.m_propertyList.insert("style:text-underline-type", underline==1 ? "single" : "double"); |
546 | 7.39k | font.m_propertyList.insert("style:text-underline-style", "solid"); |
547 | 7.39k | break; |
548 | 497 | case 3: // dot |
549 | 1.22k | case 5: // dash |
550 | 1.58k | case 6: // long-dash |
551 | 1.80k | case 7: // dash-dot |
552 | 2.30k | case 8: // dash-dot-dot |
553 | 2.30k | font.m_propertyList.insert("style:text-underline-type", "single"); |
554 | 2.30k | font.m_propertyList.insert("style:text-underline-style", underline==3 ? "dotted" : underline==5 ? "dash" : |
555 | 1.80k | underline==6 ? "long-dash" : underline==7 ? "dot-dash" : "dot-dot-dash"); |
556 | 2.30k | break; |
557 | 248 | case 9: // small wave |
558 | 767 | case 10: // wave |
559 | 1.11k | case 11: // double wave |
560 | 1.11k | font.m_propertyList.insert("style:text-underline-type", underline==11 ? "single" : "double"); |
561 | 1.11k | font.m_propertyList.insert("style:text-underline-style", "wave"); |
562 | 1.11k | if (underline==9) |
563 | 248 | font.m_propertyList.insert("style:text-underline-width", "thin"); |
564 | 1.11k | break; |
565 | 597 | case 12: // bold |
566 | 1.99k | case 13: // bold dot |
567 | 2.61k | case 14: // bold dash |
568 | 6.03k | case 15: // bold long-dash |
569 | 6.36k | case 16: // bold dash-dot |
570 | 6.63k | case 17: // bold dash-dot-dot |
571 | 7.03k | case 18: { // bold wave |
572 | 7.03k | char const *wh[]= {"solid", "dotted", "dash", "long-dash", "dot-dash", "dot-dot-dash", "wave"}; |
573 | 7.03k | font.m_propertyList.insert("style:text-underline-type", "single"); |
574 | 7.03k | font.m_propertyList.insert("style:text-underline-style", wh[underline-12]); |
575 | 7.03k | font.m_propertyList.insert("style:text-underline-width", "thick"); |
576 | 7.03k | break; |
577 | 6.63k | } |
578 | 25.7k | default: |
579 | 25.7k | font.m_propertyList.insert("style:text-underline-type", "none"); |
580 | 25.7k | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readAttributeLevel: find unknown underline enum=%d\n", underline)); |
581 | 25.7k | break; |
582 | 64.9k | } |
583 | 64.9k | switch (strikeOut) { |
584 | 25.2k | case 0: // none |
585 | 25.2k | font.m_propertyList.insert("style:text-line-through-type", "none"); |
586 | 25.2k | break; |
587 | 439 | case 1: // single |
588 | 1.73k | case 2: // double |
589 | 1.73k | font.m_propertyList.insert("style:text-line-through-type", strikeOut==1 ? "single" : "double"); |
590 | 1.73k | font.m_propertyList.insert("style:text-line-through-style", "solid"); |
591 | 1.73k | break; |
592 | 445 | case 3: // dontknow |
593 | 445 | break; |
594 | 3.03k | case 4: // bold |
595 | 3.03k | font.m_propertyList.insert("style:text-line-through-type", "single"); |
596 | 3.03k | font.m_propertyList.insert("style:text-line-through-style", "solid"); |
597 | 3.03k | font.m_propertyList.insert("style:text-line-through-width", "thick"); |
598 | 3.03k | break; |
599 | 2.28k | case 5: // slash |
600 | 2.82k | case 6: // X |
601 | 2.82k | font.m_propertyList.insert("style:text-line-through-type", "single"); |
602 | 2.82k | font.m_propertyList.insert("style:text-line-through-style", "solid"); |
603 | 2.82k | font.m_propertyList.insert("style:text-line-through-text", strikeOut==5 ? "/" : "X"); |
604 | 2.82k | break; |
605 | 31.5k | default: |
606 | 31.5k | font.m_propertyList.insert("style:text-line-through-type", "none"); |
607 | 31.5k | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readAttributeLevel: find unknown crossedout enum=%d\n", strikeOut)); |
608 | 31.5k | break; |
609 | 64.9k | } |
610 | 64.9k | if (italic==1) |
611 | 602 | font.m_propertyList.insert("fo:font-style", "oblique"); |
612 | 64.3k | else if (italic==2) |
613 | 548 | font.m_propertyList.insert("fo:font-style", "italic"); |
614 | 63.7k | else if (italic) { |
615 | 23.0k | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readAttributeLevel: find unknown posture enum=%d\n", italic)); |
616 | 23.0k | } |
617 | 64.9k | font.m_propertyList.insert("style:text-outline", outline); |
618 | 64.9k | font.m_propertyList.insert("fo:text-shadow", shadow ? "1pt 1pt" : "none"); |
619 | 64.9k | } |
620 | 64.9k | auto width=int(input->readLong(4)); |
621 | 64.9k | auto start=int(input->readULong(2)); |
622 | 64.9k | auto justify=int(input->readULong(1)); |
623 | 64.9k | auto symbol=int(input->readULong(1)); |
624 | 64.9k | auto scale=int(input->readULong(2)); |
625 | 64.9k | if (width) f << "width=" << width << ","; |
626 | 64.9k | if (start) f << "start=" << start << ","; |
627 | 64.9k | if (justify) f << "justify=" << justify << ","; |
628 | 64.9k | if (symbol) f << "symbol=" << symbol << ","; |
629 | 64.9k | if (scale) f << "scale=" << scale << ","; |
630 | | |
631 | 64.9k | if (style<=4) { |
632 | 5.86k | char const *wh[]= {"A", "a", "I", "i", "1"}; |
633 | 5.86k | level.m_propertyList.insert("style:num-format", wh[style]); |
634 | 5.86k | level.m_type=STOFFListLevel::NUMBER; |
635 | 5.86k | } |
636 | 59.0k | else if (style==5 || (style==6 && symbol==0)) { |
637 | 8.45k | level.m_propertyList.insert("text:bullet-char", " "); |
638 | 8.45k | level.m_type=STOFFListLevel::NONE; |
639 | 8.45k | } |
640 | 50.5k | else if (style==6) { |
641 | 14.5k | level.m_type=STOFFListLevel::BULLET; |
642 | 14.5k | std::vector<uint8_t> buffer(1, uint8_t(symbol)); |
643 | 14.5k | std::vector<uint32_t> res; |
644 | 14.5k | std::vector<size_t> positions; |
645 | 14.5k | auto encoding=(charSet==0 && isSymbolFont) ? StarEncoding::E_SYMBOL : StarEncoding::getEncodingForId(charSet); |
646 | 14.5k | StarEncoding::convert(buffer, encoding, res, positions); |
647 | 14.5k | level.m_propertyList.insert("text:bullet-char", libstoff::getString(res)); |
648 | 14.5k | } |
649 | 36.0k | else { |
650 | 36.0k | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readAttributeLevel: unimplemented style %d\n", style)); |
651 | | // BITMAP |
652 | 36.0k | level.m_type=STOFFListLevel::BULLET; |
653 | 36.0k | librevenge::RVNGString bullet; |
654 | 36.0k | libstoff::appendUnicode(0x2022, bullet); // checkme |
655 | 36.0k | level.m_propertyList.insert("text:bullet-char", bullet); |
656 | 36.0k | } |
657 | 64.9k | if (alignement>=0 && alignement<6) { |
658 | 40.9k | char const *wh[]= {"left", "right", "justify", "center", "justify"/*block line*/, "end"}; |
659 | 40.9k | level.m_propertyList.insert("fo:text-align", wh[alignement]); |
660 | 40.9k | } |
661 | 24.0k | else if (alignement>=0) { |
662 | 24.0k | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readAttributeLevel: unknown align %d\n", alignement)); |
663 | 24.0k | } |
664 | | |
665 | 159k | for (int i=0; i<2; ++i) { |
666 | 117k | std::vector<uint32_t> text; |
667 | 117k | if (!zone.readString(text)) { |
668 | 22.4k | STOFF_DEBUG_MSG(("StarObjectNumericRuler::readAttributeLevel: can not read a name\n")); |
669 | 22.4k | f << "###text,"; |
670 | 22.4k | break; |
671 | 22.4k | } |
672 | 94.8k | else if (text.empty()) |
673 | 64.5k | continue; |
674 | 30.3k | f << (i==0 ? "prefix" : "suffix") << "=" << libstoff::getString(text).cstr() << ","; |
675 | 30.3k | if (i==0) level.m_propertyList.insert("style:num-prefix",libstoff::getString(text)); |
676 | 9.59k | else if (i==1) level.m_propertyList.insert("style:num-suffix",libstoff::getString(text)); |
677 | 30.3k | } |
678 | | |
679 | 64.9k | ascFile.addPos(pos); |
680 | 64.9k | ascFile.addNote(f.str().c_str()); |
681 | 64.9k | return input->tell()<=lastPos; |
682 | 75.0k | } |
683 | | |
684 | | // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: |