1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <string_view>
24 #include "hwpreader.hxx"
27 #include <o3tl/safeint.hxx>
28 #include <o3tl/sprintf.hxx>
29 #include <osl/diagnose.h>
30 #include <tools/stream.hxx>
31 #include <basegfx/numeric/ftools.hxx>
32 #include <basegfx/point/b2dpoint.hxx>
33 #include <unotools/configmgr.hxx>
35 #include "fontmap.hxx"
42 #include <sal/types.h>
43 #include <rtl/character.hxx>
44 #include <rtl/ustrbuf.hxx>
45 #include <sal/log.hxx>
48 constexpr OUString sXML_CDATA
= u
"CDATA"_ustr
;
52 double WTI(double x
) { return x
/ 1800.; } // unit => inch
53 double WTMM(double x
) { return x
/ 1800. * 25.4; } // unit => mm
54 int WTSM(double x
) { return x
/ 1800. * 2540; } // unit ==> 1/100 mm
56 constexpr OUString
sBeginOfDoc(u
"[\uBB38\uC11C\uC758 \uCC98\uC74C]"_ustr
);
57 // U+BB38 HANGUL SYLLABLE MUN, U+C11C HANGUL SYLLABLE SEO,
58 // U+C758 HANGUL SYLLABLE YI, U+CC98 HANGUL SYLLABLE CEO,
59 // U+C74C HANGUL SYLLABLE EUM: "Begin of Document"
62 struct HwpReaderPrivate
82 HwpReader::HwpReader() : mxList(new AttributeListImpl
), d(new HwpReaderPrivate
)
87 HwpReader::~HwpReader()
91 extern "C" SAL_DLLPUBLIC_EXPORT
bool TestImportHWP(SvStream
&rStream
)
95 std::unique_ptr
<HStream
> stream(new HStream
);
100 std::size_t nRead
= rStream
.ReadBytes(aData
, 32768);
103 stream
->addData(aData
, static_cast<int>(nRead
));
106 rtl::Reference
<HwpReader
> hwpreader(new HwpReader
);
107 return hwpreader
->importHStream(std::move(stream
));
115 bool HwpReader::importHStream(std::unique_ptr
<HStream
> stream
)
117 if (hwpfile
.ReadHwpFile(std::move(stream
)))
120 if (m_rxDocumentHandler
.is())
121 m_rxDocumentHandler
->startDocument();
123 mxList
->addAttribute("office:class", sXML_CDATA
, "text");
124 mxList
->addAttribute("office:version", sXML_CDATA
, "0.9");
126 mxList
->addAttribute("xmlns:office", "CDATA", "http://openoffice.org/2000/office");
127 mxList
->addAttribute("xmlns:style", "CDATA", "http://openoffice.org/2000/style");
128 mxList
->addAttribute("xmlns:text", "CDATA", "http://openoffice.org/2000/text");
129 mxList
->addAttribute("xmlns:table", "CDATA", "http://openoffice.org/2000/table");
130 mxList
->addAttribute("xmlns:draw", "CDATA", "http://openoffice.org/2000/drawing");
131 mxList
->addAttribute("xmlns:fo", "CDATA", "http://www.w3.org/1999/XSL/Format");
132 mxList
->addAttribute("xmlns:xlink", "CDATA", "http://www.w3.org/1999/xlink");
133 mxList
->addAttribute("xmlns:dc", "CDATA", "http://purl.org/dc/elements/1.1/");
134 mxList
->addAttribute("xmlns:meta", "CDATA", "http://openoffice.org/2000/meta");
135 mxList
->addAttribute("xmlns:number", "CDATA", "http://openoffice.org/2000/datastyle");
136 mxList
->addAttribute("xmlns:svg", "CDATA", "http://www.w3.org/2000/svg");
137 mxList
->addAttribute("xmlns:chart", "CDATA", "http://openoffice.org/2000/chart");
138 mxList
->addAttribute("xmlns:dr3d", "CDATA", "http://openoffice.org/2000/dr3d");
139 mxList
->addAttribute("xmlns:math", "CDATA", "http://www.w3.org/1998/Math/MathML");
140 mxList
->addAttribute("xmlns:form", "CDATA", "http://openoffice.org/2000/form");
141 mxList
->addAttribute("xmlns:script", "CDATA", "http://openoffice.org/2000/script");
143 startEl("office:document");
152 endEl("office:document");
154 if (m_rxDocumentHandler
.is())
155 m_rxDocumentHandler
->endDocument();
159 sal_Bool
HwpReader::filter(const Sequence
< PropertyValue
>& rDescriptor
)
161 utl::MediaDescriptor
aDescriptor(rDescriptor
);
162 aDescriptor
.addInputStream();
164 Reference
< XInputStream
> xInputStream(
165 aDescriptor
[utl::MediaDescriptor::PROP_INPUTSTREAM
], UNO_QUERY_THROW
);
167 std::unique_ptr
<HStream
> stream(new HStream
);
168 Sequence
< sal_Int8
> aBuffer
;
169 sal_Int32 nRead
, nTotal
= 0;
172 nRead
= xInputStream
->readBytes(aBuffer
, 32768);
175 stream
->addData( reinterpret_cast<const byte
*>(aBuffer
.getConstArray()), nRead
);
179 if( nTotal
== 0 ) return false;
181 return importHStream(std::move(stream
));
187 void HwpReader::makeBody()
189 startEl("office:body");
191 HWPPara
*hwppara
= hwpfile
.GetFirstPara();
194 endEl("office:body");
202 void HwpReader::makeTextDecls()
204 startEl("text:sequence-decls");
205 mxList
->addAttribute("text:display-outline-level", sXML_CDATA
, "0");
206 mxList
->addAttribute("text:name", sXML_CDATA
, "Illustration");
207 startEl("text:sequence-decl");
209 endEl("text:sequence-decl");
210 mxList
->addAttribute("text:display-outline-level", sXML_CDATA
, "0");
211 mxList
->addAttribute("text:name", sXML_CDATA
, "Table");
212 startEl("text:sequence-decl");
214 endEl("text:sequence-decl");
215 mxList
->addAttribute("text:display-outline-level", sXML_CDATA
, "0");
216 mxList
->addAttribute("text:name", sXML_CDATA
, "Text");
217 startEl("text:sequence-decl");
219 endEl("text:sequence-decl");
220 mxList
->addAttribute("text:display-outline-level", sXML_CDATA
, "0");
221 mxList
->addAttribute("text:name", sXML_CDATA
, "Drawing");
222 startEl("text:sequence-decl");
224 endEl("text:sequence-decl");
225 endEl("text:sequence-decls");
233 void HwpReader::makeMeta()
235 HWPInfo
& hwpinfo
= hwpfile
.GetHWPInfo();
237 startEl("office:meta");
239 if (hwpinfo
.summary
.title
[0])
242 chars(hstr2OUString(reinterpret_cast<hchar
*>(hwpinfo
.summary
.title
)));
246 if (hwpinfo
.summary
.subject
[0])
248 startEl("dc:subject");
249 chars(hstr2OUString(reinterpret_cast<hchar
*>(hwpinfo
.summary
.subject
)));
253 if (hwpinfo
.summary
.author
[0])
255 startEl("meta:initial-creator");
256 chars(hstr2OUString(reinterpret_cast<hchar
*>(hwpinfo
.summary
.author
)));
257 endEl("meta:initial-creator");
260 if (hwpinfo
.summary
.date
[0])
262 unsigned short *pDate
= hwpinfo
.summary
.date
;
263 int year
,month
,day
,hour
,minute
;
265 if( rtl::isAsciiDigit( pDate
[0] ) && rtl::isAsciiDigit( pDate
[1] ) &&
266 rtl::isAsciiDigit( pDate
[2] ) && rtl::isAsciiDigit( pDate
[3] ))
268 year
= (pDate
[0]-0x30) * 1000 + (pDate
[1]-0x30) * 100 +
269 (pDate
[2]-0x30) * 10 + (pDate
[3]-0x30);
274 if( rtl::isAsciiDigit( pDate
[6] ))
276 if( rtl::isAsciiDigit( pDate
[7] ) )
277 month
= (pDate
[6] - 0x30) * 10 + (pDate
[6+ ++gab
]-0x30);
279 month
= (pDate
[6] - 0x30);
284 if( rtl::isAsciiDigit( pDate
[9 + gab
] ) )
286 if( rtl::isAsciiDigit( pDate
[10 + gab
])) {
287 day
= ( pDate
[9 + gab
] - 0x30 ) * 10 + (pDate
[9+ gab
+ 1]-0x30);
290 day
= (pDate
[9+gab
]-0x30);
295 if( rtl::isAsciiDigit( pDate
[17 + gab
] ) )
297 if( rtl::isAsciiDigit( pDate
[18 + gab
])) {
298 hour
= ( pDate
[17 + gab
] - 0x30 ) * 10 + (pDate
[17+ gab
+ 1]-0x30);
301 hour
= (pDate
[17+gab
]-0x30);
306 if( rtl::isAsciiDigit( pDate
[20 + gab
] ) )
308 if( rtl::isAsciiDigit( pDate
[21 + gab
])) {
309 minute
= ( pDate
[20 + gab
] - 0x30 ) * 10 + (pDate
[20+ gab
+ 1]-0x30);
312 minute
= (pDate
[20+gab
]-0x30);
317 o3tl::sprintf(d
->buf
,"%d-%02d-%02dT%02d:%02d:00",year
,month
,day
,hour
,minute
);
319 startEl("meta:creation-date");
320 chars( OUString::createFromAscii(d
->buf
));
321 endEl("meta:creation-date");
324 if (hwpinfo
.summary
.keyword
[0][0] || hwpinfo
.summary
.etc
[0][0])
326 startEl("meta:keywords");
327 if (hwpinfo
.summary
.keyword
[0][0])
329 startEl("meta:keyword");
330 chars(hstr2OUString(reinterpret_cast<hchar
*>(hwpinfo
.summary
.keyword
[0])));
331 endEl("meta:keyword");
333 if (hwpinfo
.summary
.keyword
[1][0])
335 startEl("meta:keyword");
336 chars(hstr2OUString(reinterpret_cast<hchar
*>(hwpinfo
.summary
.keyword
[1])));
337 endEl("meta:keyword");
339 if (hwpinfo
.summary
.etc
[0][0])
341 startEl("meta:keyword");
342 chars(hstr2OUString(reinterpret_cast<hchar
*>(hwpinfo
.summary
.etc
[0])));
343 endEl("meta:keyword");
345 if (hwpinfo
.summary
.etc
[1][0])
347 startEl("meta:keyword");
348 chars(hstr2OUString(reinterpret_cast<hchar
*>(hwpinfo
.summary
.etc
[1])));
349 endEl("meta:keyword");
351 if (hwpinfo
.summary
.etc
[2][0])
353 startEl("meta:keyword");
354 chars(hstr2OUString(reinterpret_cast<hchar
*>(hwpinfo
.summary
.etc
[2])));
355 endEl("meta:keyword");
357 endEl("meta:keywords");
359 endEl("office:meta");
372 { "Line Arrow", false },
397 void HwpReader::makeDrawMiscStyle( HWPDrawingObject
*hdo
)
402 makeDrawMiscStyle( hdo
->child
.get() );
404 HWPDOProperty
*prop
= &hdo
->property
;
405 if( hdo
->type
== HWPDO_CONTAINER
)
407 hdo
= hdo
->next
.get();
411 if( prop
->line_pstyle
> 0 && prop
->line_pstyle
< 5 && prop
->line_color
<= 0xffffff)
413 mxList
->addAttribute( "draw:name", sXML_CDATA
, "LineType" + OUString::number(hdo
->index
));
414 mxList
->addAttribute( "draw:style", sXML_CDATA
, "round");
415 mxList
->addAttribute( "draw:dots1", sXML_CDATA
, "1");
416 mxList
->addAttribute( "draw:dots1-length", sXML_CDATA
, OUString::number( LineStyle
[prop
->line_pstyle
].dots1
* WTMM(prop
->line_width
) ) + "cm");
417 if( prop
->line_pstyle
== 3 )
419 mxList
->addAttribute( "draw:dots2", sXML_CDATA
, "1");
420 mxList
->addAttribute( "draw:dots2-length", sXML_CDATA
, OUString::number( LineStyle
[prop
->line_pstyle
].dots2
* WTMM(prop
->line_width
) ) + "cm");
422 else if( prop
->line_pstyle
== 4 )
424 mxList
->addAttribute( "draw:dots2", sXML_CDATA
, "2");
425 mxList
->addAttribute( "draw:dots2-length", sXML_CDATA
, OUString::number( LineStyle
[prop
->line_pstyle
].dots2
* WTMM(prop
->line_width
)) + "cm");
427 mxList
->addAttribute( "draw:distance", sXML_CDATA
, OUString::number( LineStyle
[prop
->line_pstyle
].distance
* WTMM(prop
->line_width
)) + "cm");
428 startEl("draw:stroke-dash");
430 endEl("draw:stroke-dash");
433 if( hdo
->type
== HWPDO_LINE
|| hdo
->type
== HWPDO_ARC
|| hdo
->type
== HWPDO_FREEFORM
||
434 hdo
->type
== HWPDO_ADVANCED_ARC
)
436 if( prop
->line_tstyle
> 0 &&
437 o3tl::make_unsigned(prop
->line_tstyle
) < std::size(ArrowShape
) &&
438 !ArrowShape
[prop
->line_tstyle
].bMade
)
440 ArrowShape
[prop
->line_tstyle
].bMade
= true;
441 mxList
->addAttribute("draw:name", sXML_CDATA
,
442 OUString::createFromAscii(ArrowShape
[prop
->line_tstyle
].name
));
443 if( prop
->line_tstyle
== 1 )
445 mxList
->addAttribute("svg:viewBox", sXML_CDATA
, "0 0 20 30");
446 mxList
->addAttribute("svg:d", sXML_CDATA
, "m10 0-10 30h20z");
448 else if( prop
->line_tstyle
== 2 )
450 mxList
->addAttribute("svg:viewBox", sXML_CDATA
, "0 0 1122 2243");
451 mxList
->addAttribute("svg:d", sXML_CDATA
, "m0 2108v17 17l12 42 30 34 38 21 43 4 29-8 30-21 25-26 13-34 343-1532 339 1520 13 42 29 34 39 21 42 4 42-12 34-30 21-42v-39-12l-4 4-440-1998-9-42-25-39-38-25-43-8-42 8-38 25-26 39-8 42z");
453 else if( prop
->line_tstyle
== 3 )
455 mxList
->addAttribute("svg:viewBox", sXML_CDATA
, "0 0 30 30");
456 mxList
->addAttribute("svg:d", sXML_CDATA
, "m0 0h30v30h-30z");
458 startEl("draw:marker");
460 endEl("draw:marker");
462 if (prop
->line_hstyle
> 0 &&
463 o3tl::make_unsigned(prop
->line_hstyle
) < std::size(ArrowShape
) &&
464 !ArrowShape
[prop
->line_hstyle
].bMade
)
466 ArrowShape
[prop
->line_hstyle
].bMade
= true;
467 mxList
->addAttribute("draw:name", sXML_CDATA
,
468 OUString::createFromAscii(ArrowShape
[prop
->line_hstyle
].name
));
469 if( prop
->line_hstyle
== 1 )
471 mxList
->addAttribute("svg:viewBox", sXML_CDATA
, "0 0 20 30");
472 mxList
->addAttribute("svg:d", sXML_CDATA
, "m10 0-10 30h20z");
474 else if( prop
->line_hstyle
== 2 )
476 mxList
->addAttribute("svg:viewBox", sXML_CDATA
, "0 0 1122 2243");
477 mxList
->addAttribute("svg:d", sXML_CDATA
, "m0 2108v17 17l12 42 30 34 38 21 43 4 29-8 30-21 25-26 13-34 343-1532 339 1520 13 42 29 34 39 21 42 4 42-12 34-30 21-42v-39-12l-4 4-440-1998-9-42-25-39-38-25-43-8-42 8-38 25-26 39-8 42z");
479 else if( prop
->line_hstyle
== 3 )
481 mxList
->addAttribute("svg:viewBox", sXML_CDATA
, "0 0 20 20");
482 mxList
->addAttribute("svg:d", sXML_CDATA
, "m0 0h20v20h-20z");
484 startEl("draw:marker");
486 endEl("draw:marker");
490 if( hdo
->type
!= HWPDO_LINE
)
492 if( prop
->flag
>> 18 & 0x01 )
494 mxList
->addAttribute( "draw:name", sXML_CDATA
, "fillimage" + OUString::number(hdo
->index
));
496 EmPicture
*emp
= nullptr;
497 if (prop
->pictype
&& strlen(prop
->szPatternFile
) > 3)
498 emp
= hwpfile
.GetEmPictureByName(prop
->szPatternFile
);
501 mxList
->addAttribute( "xlink:href", sXML_CDATA
,
502 hstr2OUString(kstr2hstr( reinterpret_cast<uchar
const *>(urltounix(prop
->szPatternFile
).c_str())).c_str()));
503 mxList
->addAttribute( "xlink:type", sXML_CDATA
, "simple");
504 mxList
->addAttribute( "xlink:show", sXML_CDATA
, "embed");
505 mxList
->addAttribute( "xlink:actuate", sXML_CDATA
, "onLoad");
508 startEl("draw:fill-image");
512 startEl("office:binary-data");
513 chars(base64_encode_string(emp
->data
.data(), emp
->size
));
514 endEl("office:binary-data");
516 endEl("draw:fill-image");
518 /* If there is a gradient, when a bitmap file is present, this is the first. */
519 else if( prop
->flag
>> 16 & 0x01 ) /* existence gradient */
521 mxList
->addAttribute( "draw:name", sXML_CDATA
, "Grad" + OUString::number(hdo
->index
));
522 switch( prop
->gstyle
)
525 if( prop
->center_y
== 50 )
526 mxList
->addAttribute( "draw:style", sXML_CDATA
, "axial");
528 mxList
->addAttribute( "draw:style", sXML_CDATA
, "linear");
532 mxList
->addAttribute( "draw:style", sXML_CDATA
, "radial");
535 mxList
->addAttribute( "draw:style", sXML_CDATA
, "square");
538 mxList
->addAttribute( "draw:style", sXML_CDATA
, "linear");
541 mxList
->addAttribute( "draw:cx", sXML_CDATA
, OUString::number(prop
->center_x
) + "%");
542 mxList
->addAttribute( "draw:cy", sXML_CDATA
, OUString::number(prop
->center_y
) + "%");
544 HWPInfo
& hwpinfo
= hwpfile
.GetHWPInfo();
545 int default_color
= 0xffffff;
546 if( hwpinfo
.back_info
.isset
)
548 if( hwpinfo
.back_info
.color
[0] > 0 || hwpinfo
.back_info
.color
[1] > 0
549 || hwpinfo
.back_info
.color
[2] > 0 )
550 default_color
= hwpinfo
.back_info
.color
[0] << 16 |
551 hwpinfo
.back_info
.color
[1] << 8 | hwpinfo
.back_info
.color
[2];
554 if( prop
->fromcolor
> 0xffffff )
555 prop
->fromcolor
= default_color
;
556 if( prop
->tocolor
> 0xffffff )
557 prop
->tocolor
= default_color
;
559 if( prop
->gstyle
== 1)
561 if( prop
->center_y
== 100 )
563 mxList
->addAttribute( "draw:start-color", sXML_CDATA
, rgb2str( prop
->tocolor
));
564 mxList
->addAttribute( "draw:end-color", sXML_CDATA
, rgb2str( prop
->fromcolor
));
568 mxList
->addAttribute( "draw:start-color", sXML_CDATA
, rgb2str( prop
->fromcolor
));
569 mxList
->addAttribute( "draw:end-color", sXML_CDATA
, rgb2str( prop
->tocolor
));
574 mxList
->addAttribute( "draw:start-color", sXML_CDATA
,rgb2str( prop
->tocolor
));
575 mxList
->addAttribute( "draw:end-color", sXML_CDATA
,rgb2str( prop
->fromcolor
));
577 if( prop
->angle
> 0 && ( prop
->gstyle
== 1 || prop
->gstyle
== 4))
579 auto normangle
= prop
->angle
% 360;
580 int angle
= 1800 - normangle
* 10;
581 mxList
->addAttribute( "draw:angle", sXML_CDATA
, OUString::number(angle
));
583 startEl("draw:gradient");
585 endEl("draw:gradient");
588 else if( prop
->pattern_type
>> 24 & 0x01 )
590 int type
= prop
->pattern_type
& 0xffffff;
591 mxList
->addAttribute( "draw:name", sXML_CDATA
, "Hatch" + OUString::number(hdo
->index
));
593 mxList
->addAttribute( "draw:style", sXML_CDATA
, "single" );
595 mxList
->addAttribute( "draw:style", sXML_CDATA
, "double" );
596 mxList
->addAttribute( "draw:color", sXML_CDATA
, rgb2str( static_cast<int32_t>(prop
->pattern_color
) ));
597 mxList
->addAttribute( "draw:distance", sXML_CDATA
, "0.12cm");
602 mxList
->addAttribute( "draw:rotation", sXML_CDATA
, "0");
605 mxList
->addAttribute( "draw:rotation", sXML_CDATA
, "900");
608 mxList
->addAttribute( "draw:rotation", sXML_CDATA
, "1350");
612 mxList
->addAttribute( "draw:rotation", sXML_CDATA
, "450");
615 startEl("draw:hatch");
620 hdo
= hdo
->next
.get();
625 void HwpReader::makeStyles()
627 HWPStyle
& hwpstyle
= hwpfile
.GetHWPStyle();
629 startEl("office:styles");
632 for (i
= 0; i
< hwpfile
.getFBoxStyleCount(); i
++)
634 if( hwpfile
.getFBoxStyle(i
)->boxtype
== 'D' )
636 makeDrawMiscStyle(static_cast<HWPDrawingObject
*>(hwpfile
.getFBoxStyle(i
)->cell
) );
640 mxList
->addAttribute("style:name", sXML_CDATA
, "Standard");
641 mxList
->addAttribute("style:family", sXML_CDATA
, "paragraph");
642 mxList
->addAttribute("style:class", sXML_CDATA
, "text");
643 startEl("style:style");
646 mxList
->addAttribute("fo:line-height", sXML_CDATA
, "160%");
647 mxList
->addAttribute("fo:text-align", sXML_CDATA
, "justify");
648 startEl("style:properties");
650 startEl("style:tab-stops");
652 for( i
= 1 ; i
< 40 ; i
++)
654 mxList
->addAttribute("style:position", sXML_CDATA
,
655 OUString::number( WTI(1000 * i
)) + "inch");
656 startEl("style:tab-stop");
658 endEl("style:tab-stop");
660 endEl("style:tab-stops");
661 endEl("style:properties");
663 endEl("style:style");
665 for (int ii
= 0; ii
< hwpstyle
.Num(); ii
++)
667 unsigned char *stylename
= reinterpret_cast<unsigned char *>(hwpstyle
.GetName(ii
));
668 mxList
->addAttribute("style:name", sXML_CDATA
, hstr2OUString(kstr2hstr(stylename
).c_str()));
669 mxList
->addAttribute("style:family", sXML_CDATA
, "paragraph");
670 mxList
->addAttribute("style:parent-style-name", sXML_CDATA
, "Standard");
672 startEl("style:style");
676 parseCharShape(hwpstyle
.GetCharShape(ii
));
677 parseParaShape(hwpstyle
.GetParaShape(ii
));
679 startEl("style:properties");
681 endEl("style:properties");
683 endEl("style:style");
687 mxList
->addAttribute( "style:name", sXML_CDATA
, "Header");
688 mxList
->addAttribute( "style:family", sXML_CDATA
, "paragraph");
689 mxList
->addAttribute( "style:parent-style-name", sXML_CDATA
, "Standard");
690 mxList
->addAttribute( "style:class", sXML_CDATA
, "extra");
691 startEl("style:style");
693 endEl("style:style");
697 mxList
->addAttribute( "style:name", sXML_CDATA
, "Footer");
698 mxList
->addAttribute( "style:family", sXML_CDATA
, "paragraph");
699 mxList
->addAttribute( "style:parent-style-name", sXML_CDATA
, "Standard");
700 mxList
->addAttribute( "style:class", sXML_CDATA
, "extra");
701 startEl("style:style");
704 endEl("style:style");
707 if( hwpfile
.linenumber
> 0)
709 mxList
->addAttribute( "style:name", sXML_CDATA
, "Horizontal Line");
710 mxList
->addAttribute( "style:family", sXML_CDATA
, "paragraph");
711 mxList
->addAttribute( "style:parent-style-name", sXML_CDATA
, "Standard");
712 mxList
->addAttribute( "style:class", sXML_CDATA
, "html");
713 startEl("style:style");
715 mxList
->addAttribute( "fo:font-size", sXML_CDATA
, "6pt");
716 mxList
->addAttribute( "fo:margin-top", sXML_CDATA
, "0cm");
717 mxList
->addAttribute( "fo:margin-bottom", sXML_CDATA
, "0cm");
718 mxList
->addAttribute( "style:border-line-width-bottom", sXML_CDATA
, "0.02cm 0.035cm 0.002cm");
719 mxList
->addAttribute( "fo:padding", sXML_CDATA
, "0cm");
720 mxList
->addAttribute( "fo:border-bottom", sXML_CDATA
, "0.039cm double #808080");
721 mxList
->addAttribute( "text:number-lines", sXML_CDATA
, "false");
722 mxList
->addAttribute( "text:line-number", sXML_CDATA
, "0");
723 mxList
->addAttribute("fo:line-height", sXML_CDATA
, "100%");
724 startEl("style:properties");
726 endEl("style:properties");
727 endEl("style:style");
730 HWPInfo
& hwpinfo
= hwpfile
.GetHWPInfo();
732 mxList
->addAttribute("text:num-suffix", sXML_CDATA
, ")");
733 mxList
->addAttribute("text:num-format", sXML_CDATA
, "1");
734 if( hwpinfo
.beginfnnum
!= 1)
735 mxList
->addAttribute("text:offset", sXML_CDATA
, OUString::number(hwpinfo
.beginfnnum
- 1));
736 startEl("text:footnotes-configuration");
738 endEl("text:footnotes-configuration");
740 endEl("office:styles");
745 * parse automatic styles from hwpfile
746 * Define a style that is automatically reflected. For example, defining styles of each paragraph, tables, header, and etc,. at here. In Body, use the defined style.
747 * 1. supports for the styles of paragraph, text, fbox, and page.
749 void HwpReader::makeAutoStyles()
753 startEl("office:automatic-styles");
755 for (i
= 0; i
< hwpfile
.getParaShapeCount(); i
++)
756 makePStyle(hwpfile
.getParaShape(i
));
758 for (i
= 0; i
< hwpfile
.getCharShapeCount(); i
++)
759 makeTStyle(hwpfile
.getCharShape(i
));
761 for( i
= 0 ; i
< hwpfile
.getTableCount(); i
++)
762 makeTableStyle(hwpfile
.getTable(i
));
764 for (i
= 0; i
< hwpfile
.getFBoxStyleCount(); i
++)
766 if( hwpfile
.getFBoxStyle(i
)->boxtype
== 'D' )
767 makeDrawStyle(static_cast<HWPDrawingObject
*>(hwpfile
.getFBoxStyle(i
)->cell
), hwpfile
.getFBoxStyle(i
));
769 makeFStyle(hwpfile
.getFBoxStyle(i
));
772 bool bIsLeft
= false, bIsMiddle
= false, bIsRight
= false;
773 for( i
= 0 ; i
< hwpfile
.getPageNumberCount() ; i
++ )
775 ShowPageNum
*pn
= hwpfile
.getPageNumber(i
);
776 if( pn
->where
== 7 || pn
->where
== 8 )
781 else if( pn
->where
== 1 || pn
->where
== 4 )
785 else if( pn
->where
== 2 || pn
->where
== 5 )
789 else if( pn
->where
== 3 || pn
->where
== 6 )
795 for( i
= 1; i
<= 3 ; i
++ )
797 if( i
== 1 && !bIsLeft
)
799 if( i
== 2 && !bIsMiddle
)
801 if( i
== 3 && !bIsRight
)
803 mxList
->addAttribute("style:name", sXML_CDATA
, "PNPara" + OUString::number(i
));
804 mxList
->addAttribute("style:family", sXML_CDATA
, "paragraph");
805 mxList
->addAttribute("style:parent-style-name", sXML_CDATA
, "Standard");
806 startEl("style:style");
809 mxList
->addAttribute("fo:text-align", sXML_CDATA
, "start");
811 mxList
->addAttribute("fo:text-align", sXML_CDATA
, "center");
813 mxList
->addAttribute("fo:text-align", sXML_CDATA
, "end");
814 startEl("style:properties");
816 endEl("style:properties");
817 endEl("style:style");
819 mxList
->addAttribute("style:name", sXML_CDATA
, "PNBox" + OUString::number(i
));
820 mxList
->addAttribute("style:family", sXML_CDATA
, "graphics");
821 startEl("style:style");
824 mxList
->addAttribute("fo:margin-top", sXML_CDATA
, "0cm");
825 mxList
->addAttribute("fo:margin-bottom", sXML_CDATA
, "0cm");
826 mxList
->addAttribute("style:wrap", sXML_CDATA
, "run-through");
827 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "from-top");
828 mxList
->addAttribute("style:vertical-rel", sXML_CDATA
, "paragraph");
831 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "left");
833 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "center");
835 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "right");
836 mxList
->addAttribute("style:horizontal-rel", sXML_CDATA
, "paragraph");
837 mxList
->addAttribute("fo:padding", sXML_CDATA
, "0cm");
838 mxList
->addAttribute("stylefamily", sXML_CDATA
, "graphics");
839 startEl("style:properties");
841 endEl("style:properties");
842 endEl("style:style");
845 for (i
= 0; i
< hwpfile
.getDateFormatCount(); i
++)
846 makeDateFormat(hwpfile
.getDateCode(i
));
850 endEl("office:automatic-styles");
860 header_odd
= nullptr;
861 header_even
= nullptr;
863 footer_odd
= nullptr;
864 footer_even
= nullptr;
868 HeaderFooter
*header
;
869 HeaderFooter
*header_odd
;
870 HeaderFooter
*header_even
;
871 HeaderFooter
*footer
;
872 HeaderFooter
*footer_odd
;
873 HeaderFooter
*footer_even
;
874 ShowPageNum
*pagenumber
;
880 void HwpReader::makeMasterStyles()
882 startEl("office:master-styles");
885 int nMax
= hwpfile
.getMaxSettedPage();
886 std::vector
<PageSetting
> aSet(nMax
+ 1);
888 for( i
= 0 ; i
< hwpfile
.getPageNumberCount() ; i
++ )
890 ShowPageNum
*pn
= hwpfile
.getPageNumber(i
);
891 aSet
[pn
->m_nPageNumber
].pagenumber
= pn
;
892 aSet
[pn
->m_nPageNumber
].bIsSet
= true;
894 for( i
= 0 ; i
< hwpfile
.getHeaderFooterCount() ; i
++ )
896 HeaderFooter
* hf
= hwpfile
.getHeaderFooter(i
);
897 aSet
[hf
->m_nPageNumber
].bIsSet
= true;
898 if( hf
->type
== 0 ) // header
903 aSet
[hf
->m_nPageNumber
].header
= hf
;
904 aSet
[hf
->m_nPageNumber
].header_even
= nullptr;
905 aSet
[hf
->m_nPageNumber
].header_odd
= nullptr;
908 aSet
[hf
->m_nPageNumber
].header_even
= hf
;
909 if( aSet
[hf
->m_nPageNumber
].header
)
911 aSet
[hf
->m_nPageNumber
].header_odd
=
912 aSet
[hf
->m_nPageNumber
].header
;
913 aSet
[hf
->m_nPageNumber
].header
= nullptr;
917 aSet
[hf
->m_nPageNumber
].header_odd
= hf
;
918 if( aSet
[hf
->m_nPageNumber
].header
)
920 aSet
[hf
->m_nPageNumber
].header_even
=
921 aSet
[hf
->m_nPageNumber
].header
;
922 aSet
[hf
->m_nPageNumber
].header
= nullptr;
932 aSet
[hf
->m_nPageNumber
].footer
= hf
;
933 aSet
[hf
->m_nPageNumber
].footer_even
= nullptr;
934 aSet
[hf
->m_nPageNumber
].footer_odd
= nullptr;
937 aSet
[hf
->m_nPageNumber
].footer_even
= hf
;
938 if( aSet
[hf
->m_nPageNumber
].footer
)
940 aSet
[hf
->m_nPageNumber
].footer_odd
=
941 aSet
[hf
->m_nPageNumber
].footer
;
942 aSet
[hf
->m_nPageNumber
].footer
= nullptr;
946 aSet
[hf
->m_nPageNumber
].footer_odd
= hf
;
947 if( aSet
[hf
->m_nPageNumber
].footer
)
949 aSet
[hf
->m_nPageNumber
].footer_even
=
950 aSet
[hf
->m_nPageNumber
].footer
;
951 aSet
[hf
->m_nPageNumber
].footer
= nullptr;
958 PageSetting
*pPrevSet
= nullptr;
959 PageSetting
*pPage
= nullptr;
961 if (nMax
> 512 && utl::ConfigManager::IsFuzzing())
963 SAL_WARN("filter.hwp", "too many pages: " << nMax
<< " clip to " << 512);
967 for( i
= 1; i
<= nMax
; i
++ )
970 mxList
->addAttribute("style:name", sXML_CDATA
, "Standard");
972 mxList
->addAttribute("style:name", sXML_CDATA
, "p" + OUString::number(i
));
973 mxList
->addAttribute("style:page-master-name", sXML_CDATA
,
974 "pm" + OUString::number(hwpfile
.GetPageMasterNum(i
)));
976 mxList
->addAttribute("style:next-style-name", sXML_CDATA
, "p" + OUString::number(i
+ 1));
977 mxList
->addAttribute("draw:style-name", sXML_CDATA
, "master" + OUString::number(i
));
978 startEl("style:master-page");
981 if( aSet
[i
].bIsSet
) /* If you've changed the current setting */
983 if( !aSet
[i
].pagenumber
){
984 if( pPrevSet
&& pPrevSet
->pagenumber
)
985 aSet
[i
].pagenumber
= pPrevSet
->pagenumber
;
987 if( aSet
[i
].pagenumber
)
989 if( aSet
[i
].pagenumber
->where
== 7 && aSet
[i
].header
)
991 aSet
[i
].header_even
= aSet
[i
].header
;
992 aSet
[i
].header_odd
= aSet
[i
].header
;
993 aSet
[i
].header
= nullptr;
995 if( aSet
[i
].pagenumber
->where
== 8 && aSet
[i
].footer
)
997 aSet
[i
].footer_even
= aSet
[i
].footer
;
998 aSet
[i
].footer_odd
= aSet
[i
].footer
;
999 aSet
[i
].footer
= nullptr;
1003 if( !aSet
[i
].header_even
&& pPrevSet
&& pPrevSet
->header_even
)
1005 aSet
[i
].header_even
= pPrevSet
->header_even
;
1007 if( !aSet
[i
].header_odd
&& pPrevSet
&& pPrevSet
->header_odd
)
1009 aSet
[i
].header_odd
= pPrevSet
->header_odd
;
1011 if( !aSet
[i
].footer_even
&& pPrevSet
&& pPrevSet
->footer_even
)
1013 aSet
[i
].footer_even
= pPrevSet
->footer_even
;
1015 if( !aSet
[i
].footer_odd
&& pPrevSet
&& pPrevSet
->footer_odd
)
1017 aSet
[i
].footer_odd
= pPrevSet
->footer_odd
;
1021 pPrevSet
= &aSet
[i
];
1023 else if( pPrevSet
) /* If the previous setting exists */
1027 else /* If the previous settings doesn't exist, set to the default settings */
1029 startEl("style:header");
1030 mxList
->addAttribute("text:style-name", sXML_CDATA
, "Standard");
1034 endEl("style:header");
1036 startEl("style:footer");
1037 mxList
->addAttribute("text:style-name", sXML_CDATA
, "Standard");
1041 endEl("style:footer");
1043 endEl("style:master-page");
1050 startEl("style:header");
1051 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
< 4 )
1053 d
->bInHeader
= true;
1054 d
->pPn
= pPage
->pagenumber
;
1056 if (!pPage
->header
->plist
.empty())
1057 parsePara(pPage
->header
->plist
.front().get());
1058 d
->bInHeader
= false;
1060 endEl("style:header");
1062 if( pPage
->header_even
)
1064 startEl("style:header");
1065 if( pPage
->pagenumber
&& ( pPage
->pagenumber
->where
< 4
1066 || pPage
->pagenumber
->where
== 7 ) )
1068 d
->bInHeader
= true;
1069 d
->pPn
= pPage
->pagenumber
;
1072 if (!pPage
->header_even
->plist
.empty())
1073 parsePara(pPage
->header_even
->plist
.front().get());
1074 d
->bInHeader
= false;
1077 endEl("style:header");
1079 /* Will be the default. */
1080 else if (pPage
->header_odd
)
1082 startEl("style:header");
1083 mxList
->addAttribute("text:style-name", sXML_CDATA
, "Standard");
1086 if( pPage
->pagenumber
&& ( pPage
->pagenumber
->where
< 4 ||
1087 pPage
->pagenumber
->where
== 7 ) )
1089 d
->pPn
= pPage
->pagenumber
;
1096 endEl("style:header");
1098 if( pPage
->header_odd
)
1100 startEl("style:header-left");
1101 if( pPage
->pagenumber
&& ( pPage
->pagenumber
->where
< 4
1102 || pPage
->pagenumber
->where
== 7 ) )
1104 d
->bInHeader
= true;
1106 d
->pPn
= pPage
->pagenumber
;
1108 if (!pPage
->header_odd
->plist
.empty())
1109 parsePara(pPage
->header_odd
->plist
.front().get());
1110 d
->bInHeader
= false;
1113 endEl("style:header-left");
1115 /* Will be the default. */
1116 else if (pPage
->header_even
)
1118 startEl("style:header-left");
1119 mxList
->addAttribute("text:style-name", sXML_CDATA
, "Standard");
1122 if( pPage
->pagenumber
&& ( pPage
->pagenumber
->where
< 4 ||
1123 pPage
->pagenumber
->where
== 7 ) )
1125 d
->pPn
= pPage
->pagenumber
;
1132 endEl("style:header-left");
1134 if( !pPage
->header
&& !pPage
->header_even
&& !pPage
->header_odd
)
1136 startEl("style:header");
1137 mxList
->addAttribute("text:style-name", sXML_CDATA
, "Standard");
1140 if( pPage
->pagenumber
&& (pPage
->pagenumber
->where
< 4 ||
1141 pPage
->pagenumber
->where
== 7 ) )
1143 d
->pPn
= pPage
->pagenumber
;
1148 endEl("style:header");
1153 startEl("style:footer");
1154 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1155 && pPage
->pagenumber
->where
!= 7 )
1157 d
->bInHeader
= true;
1158 d
->pPn
= pPage
->pagenumber
;
1160 if (!pPage
->footer
->plist
.empty())
1161 parsePara(pPage
->footer
->plist
.front().get());
1162 d
->bInHeader
= false;
1164 endEl("style:footer");
1166 if( pPage
->footer_even
)
1168 startEl("style:footer");
1169 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1170 && pPage
->pagenumber
->where
!= 7 )
1172 d
->bInHeader
= true;
1173 d
->pPn
= pPage
->pagenumber
;
1176 if (!pPage
->footer_even
->plist
.empty())
1177 parsePara(pPage
->footer_even
->plist
.front().get());
1178 d
->bInHeader
= false;
1181 endEl("style:footer");
1183 /* Will be the default. */
1184 else if (pPage
->footer_odd
)
1186 startEl("style:footer");
1187 mxList
->addAttribute("text:style-name", sXML_CDATA
, "Standard");
1190 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1191 && pPage
->pagenumber
->where
!= 7 )
1193 d
->pPn
= pPage
->pagenumber
;
1200 endEl("style:footer");
1202 if( pPage
->footer_odd
)
1204 startEl("style:footer-left");
1205 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1206 && pPage
->pagenumber
->where
!= 7 )
1208 d
->bInHeader
= true;
1209 d
->pPn
= pPage
->pagenumber
;
1212 if (!pPage
->footer_odd
->plist
.empty())
1213 parsePara(pPage
->footer_odd
->plist
.front().get());
1214 d
->bInHeader
= false;
1217 endEl("style:footer-left");
1219 /* Will be the default. */
1220 else if (pPage
->footer_even
)
1222 startEl("style:footer-left");
1223 mxList
->addAttribute("text:style-name", sXML_CDATA
, "Standard");
1226 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1227 && pPage
->pagenumber
->where
!= 7 )
1229 d
->pPn
= pPage
->pagenumber
;
1236 endEl("style:footer-left");
1238 if( !pPage
->footer
&& !pPage
->footer_even
&& !pPage
->footer_odd
)
1240 startEl("style:footer");
1241 mxList
->addAttribute("text:style-name", sXML_CDATA
, "Standard");
1244 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1245 && pPage
->pagenumber
->where
!= 7 )
1247 d
->pPn
= pPage
->pagenumber
;
1252 endEl("style:footer");
1255 endEl("style:master-page");
1257 endEl("office:master-styles");
1262 * Create the properties for text styles.
1263 * 1. fo:font-size, fo:font-family, fo:letter-spacing, fo:color,
1264 * style:text-background-color, fo:font-style, fo:font-weight,
1265 * style:text-underline,style:text-outline,fo:text-shadow,style:text-position
1268 void HwpReader::parseCharShape(CharShape
const * cshape
)
1270 HWPFont
& hwpfont
= hwpfile
.GetHWPFont();
1272 mxList
->addAttribute("fo:font-size", sXML_CDATA
, OUString::number(cshape
->size
/ 25) + "pt");
1273 mxList
->addAttribute("style:font-size-asian", sXML_CDATA
, OUString::number(cshape
->size
/ 25) + "pt");
1275 ::std::string
const tmp
= hstr2ksstr(kstr2hstr(
1276 reinterpret_cast<unsigned char const *>(hwpfont
.GetFontName(0, cshape
->font
))).c_str());
1277 double fRatio
= 1.0;
1278 int size
= getRepFamilyName(tmp
.c_str(), d
->buf
, fRatio
);
1280 mxList
->addAttribute("fo:font-family", sXML_CDATA
,
1281 OUString(d
->buf
, size
, RTL_TEXTENCODING_EUC_KR
));
1282 mxList
->addAttribute("style:font-family-asian", sXML_CDATA
,
1283 OUString(d
->buf
, size
, RTL_TEXTENCODING_EUC_KR
));
1285 mxList
->addAttribute("style:text-scale", sXML_CDATA
,
1286 OUString::number(static_cast<int>(cshape
->ratio
* fRatio
)) + "%");
1288 double sspace
= (cshape
->size
/ 25) * cshape
->space
/ 100.;
1292 mxList
->addAttribute("fo:letter-spacing", sXML_CDATA
,
1293 OUString::number(sspace
) + "pt");
1295 if (cshape
->color
[1] != 0)
1296 mxList
->addAttribute("fo:color", sXML_CDATA
,
1297 hcolor2str(cshape
->color
[1], 100, true));
1298 if (cshape
->shade
!= 0)
1299 mxList
->addAttribute("style:text-background-color", sXML_CDATA
,
1300 hcolor2str(cshape
->color
[0], cshape
->shade
));
1301 if (cshape
->attr
& 0x01)
1303 mxList
->addAttribute("fo:font-style", sXML_CDATA
, "italic");
1304 mxList
->addAttribute("style:font-style-asian", sXML_CDATA
, "italic");
1307 mxList
->addAttribute("fo:font-style", sXML_CDATA
, "normal");
1308 mxList
->addAttribute("style:font-style-asian", sXML_CDATA
, "normal");
1310 if (cshape
->attr
>> 1 & 0x01)
1312 mxList
->addAttribute("fo:font-weight", sXML_CDATA
, "bold");
1313 mxList
->addAttribute("style:font-weight-asian", sXML_CDATA
, "bold");
1316 mxList
->addAttribute("fo:font-weight", sXML_CDATA
, "normal");
1317 mxList
->addAttribute("style:font-weight-asian", sXML_CDATA
, "normal");
1319 if (cshape
->attr
>> 2 & 0x01)
1320 mxList
->addAttribute("style:text-underline", sXML_CDATA
, "single");
1321 if (cshape
->attr
>> 3 & 0x01)
1322 mxList
->addAttribute("style:text-outline", sXML_CDATA
, "true");
1323 if (cshape
->attr
>> 4 & 0x01)
1324 mxList
->addAttribute("fo:text-shadow", sXML_CDATA
, "1pt 1pt");
1325 if (cshape
->attr
>> 5 & 0x01)
1326 mxList
->addAttribute("style:text-position", sXML_CDATA
, "super 58%");
1327 if (cshape
->attr
>> 6 & 0x01)
1328 mxList
->addAttribute("style:text-position", sXML_CDATA
, "sub 58%");
1334 * Create the properties that correspond to the real Paragraph.
1335 * 1. fo:margin-left,fo:margin-right,fo:margin-top, fo:margin-bottom,
1336 * fo:text-indent, fo:line-height, fo:text-align, fo:border
1338 * TODO: Tab Settings => set values of properties only which doesn't have the default value
1340 void HwpReader::parseParaShape(ParaShape
const * pshape
)
1343 if (pshape
->left_margin
!= 0)
1344 mxList
->addAttribute("fo:margin-left", sXML_CDATA
, OUString::number
1345 (WTI(pshape
->left_margin
)) + "inch");
1346 if (pshape
->right_margin
!= 0)
1347 mxList
->addAttribute("fo:margin-right", sXML_CDATA
, OUString::number
1348 (WTI(pshape
->right_margin
)) + "inch");
1349 if (pshape
->pspacing_prev
!= 0)
1350 mxList
->addAttribute("fo:margin-top", sXML_CDATA
, OUString::number
1351 (WTI(pshape
->pspacing_prev
)) + "inch");
1352 if (pshape
->pspacing_next
!= 0)
1353 mxList
->addAttribute("fo:margin-bottom", sXML_CDATA
, OUString::number
1354 (WTI(pshape
->pspacing_next
)) + "inch");
1355 if (pshape
->indent
!= 0)
1356 mxList
->addAttribute("fo:text-indent", sXML_CDATA
, OUString::number
1357 (WTI(pshape
->indent
)) + "inch");
1358 if (pshape
->lspacing
!= 0)
1359 mxList
->addAttribute("fo:line-height", sXML_CDATA
, OUString::number(pshape
->lspacing
) + "%");
1361 const char* align
= nullptr;
1363 switch (static_cast<int>(pshape
->arrange_type
))
1382 mxList
->addAttribute("fo:text-align", sXML_CDATA
, OUString::createFromAscii(align
));
1384 if (pshape
->outline
)
1385 mxList
->addAttribute("fo:border", sXML_CDATA
, "0.002cm solid #000000");
1386 if( pshape
->shade
> 0 )
1388 mxList
->addAttribute("fo:background-color", sXML_CDATA
,
1389 hcolor2str(0, pshape
->shade
));
1392 if( pshape
->pagebreak
& 0x02 || pshape
->pagebreak
& 0x04)
1393 mxList
->addAttribute("fo:break-before", sXML_CDATA
, "page");
1394 else if( pshape
->pagebreak
& 0x01 )
1395 mxList
->addAttribute("fo:break-before", sXML_CDATA
, "column");
1401 * Make the style of the Paragraph.
1403 void HwpReader::makePStyle(ParaShape
const * pshape
)
1405 int nscount
= pshape
->tabs
[MAXTABS
-1].type
;
1406 mxList
->addAttribute("style:name", sXML_CDATA
, "P" + OUString::number(pshape
->index
));
1407 mxList
->addAttribute("style:family", sXML_CDATA
, "paragraph");
1408 startEl("style:style");
1410 parseParaShape(pshape
);
1412 parseCharShape(pshape
->cshape
.get());
1413 startEl("style:properties");
1418 unsigned char tf
= 0;
1419 startEl("style:tab-stops");
1421 int tab_margin
= pshape
->left_margin
+ pshape
->indent
;
1422 if( tab_margin
< 0 )
1424 for( int i
= 0 ; i
< MAXTABS
-1 ; i
++)
1426 if( i
> 0 && pshape
->tabs
[i
].position
== 0. )
1428 if( pshape
->tabs
[i
].position
<= tab_margin
)
1430 mxList
->addAttribute("style:position", sXML_CDATA
,
1431 OUString::number(WTMM(pshape
->tabs
[i
].position
- tab_margin
)) + "mm");
1432 if( pshape
->tabs
[i
].type
)
1435 switch(pshape
->tabs
[i
].type
)
1438 mxList
->addAttribute("style:type", sXML_CDATA
, "right");
1441 mxList
->addAttribute("style:type", sXML_CDATA
, "center");
1444 mxList
->addAttribute("style:type", sXML_CDATA
, "char");
1445 mxList
->addAttribute("style:char", sXML_CDATA
, ".");
1449 if( pshape
->tabs
[i
].dot_continue
)
1452 mxList
->addAttribute("style:leader-char", sXML_CDATA
, ".");
1454 startEl("style:tab-stop");
1456 endEl("style:tab-stop");
1458 if( (pshape
->tabs
[i
].position
!= 1000 * i
) || tf
)
1460 if( !--nscount
) break;
1463 endEl("style:tab-stops");
1465 endEl("style:properties");
1466 endEl("style:style");
1471 * Create a style for the page. This includes the header/footer, footnote and more.
1472 * TODO: fo: background-color (no information)
1474 void HwpReader::makePageStyle()
1476 HWPInfo
& hwpinfo
= hwpfile
.GetHWPInfo();
1477 int pmCount
= hwpfile
.getColumnCount();
1479 if (pmCount
> 512 && utl::ConfigManager::IsFuzzing())
1481 SAL_WARN("filter.hwp", "too many pages: " << pmCount
<< " clip to " << 512);
1485 for( int i
= 0 ; i
< pmCount
; i
++ ){
1486 mxList
->addAttribute("style:name", sXML_CDATA
, "pm" + OUString::number(i
+ 1));
1487 startEl("style:page-master");
1491 switch( hwpinfo
.paper
.paper_kind
)
1494 if( hwpinfo
.paper
.paper_direction
)
1496 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "210mm");
1497 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "297mm");
1501 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "210mm");
1502 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "297mm");
1505 case 4: // 80 column
1506 if( hwpinfo
.paper
.paper_direction
)
1508 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "8.5inch");
1509 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "11inch");
1513 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "8.5inch");
1514 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "11inch");
1518 if( hwpinfo
.paper
.paper_direction
)
1520 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "176mm");
1521 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "250mm");
1525 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "176mm");
1526 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "250mm");
1530 if( hwpinfo
.paper
.paper_direction
)
1532 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "250mm");
1533 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "353mm");
1537 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "250mm");
1538 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "353mm");
1542 if( hwpinfo
.paper
.paper_direction
)
1544 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "8.5inch");
1545 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "14inch");
1549 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "8.5inch");
1550 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "14inch");
1554 if( hwpinfo
.paper
.paper_direction
)
1556 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "297mm");
1557 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "420mm");
1561 mxList
->addAttribute("fo:page-width",sXML_CDATA
, "297mm");
1562 mxList
->addAttribute("fo:page-height",sXML_CDATA
, "420mm");
1569 if( hwpinfo
.paper
.paper_direction
)
1571 mxList
->addAttribute("fo:page-width",sXML_CDATA
,
1572 OUString::number(WTI(hwpinfo
.paper
.paper_height
)) + "inch");
1573 mxList
->addAttribute("fo:page-height",sXML_CDATA
,
1574 OUString::number(WTI(hwpinfo
.paper
.paper_width
)) + "inch");
1578 mxList
->addAttribute("fo:page-width",sXML_CDATA
,
1579 OUString::number(WTI(hwpinfo
.paper
.paper_width
)) + "inch");
1580 mxList
->addAttribute("fo:page-height",sXML_CDATA
,
1581 OUString::number(WTI(hwpinfo
.paper
.paper_height
)) + "inch");
1587 mxList
->addAttribute("style:print-orientation",sXML_CDATA
,
1588 OUString::createFromAscii(hwpinfo
.paper
.paper_direction
? "landscape" : "portrait"));
1589 if( hwpinfo
.beginpagenum
!= 1)
1590 mxList
->addAttribute("style:first-page-number",sXML_CDATA
, OUString::number(hwpinfo
.beginpagenum
));
1592 if( hwpinfo
.borderline
){
1593 mxList
->addAttribute("fo:margin-left",sXML_CDATA
,
1594 OUString::number(WTI(hwpinfo
.paper
.left_margin
- hwpinfo
.bordermargin
[0] + hwpinfo
.paper
.gutter_length
)) + "inch");
1595 mxList
->addAttribute("fo:margin-right",sXML_CDATA
,
1596 OUString::number(WTI(hwpinfo
.paper
.right_margin
- hwpinfo
.bordermargin
[1])) + "inch");
1597 mxList
->addAttribute("fo:margin-top",sXML_CDATA
,
1598 OUString::number(WTI(hwpinfo
.paper
.top_margin
- hwpinfo
.bordermargin
[2])) + "inch");
1599 mxList
->addAttribute("fo:margin-bottom",sXML_CDATA
,
1600 OUString::number(WTI(hwpinfo
.paper
.bottom_margin
- hwpinfo
.bordermargin
[3])) + "inch");
1603 mxList
->addAttribute("fo:margin-left",sXML_CDATA
,
1604 OUString::number(WTI(hwpinfo
.paper
.left_margin
+ hwpinfo
.paper
.gutter_length
)) + "inch");
1605 mxList
->addAttribute("fo:margin-right",sXML_CDATA
,
1606 OUString::number(WTI(hwpinfo
.paper
.right_margin
)) + "inch");
1607 mxList
->addAttribute("fo:margin-top",sXML_CDATA
,
1608 OUString::number(WTI(hwpinfo
.paper
.top_margin
)) + "inch");
1609 mxList
->addAttribute("fo:margin-bottom",sXML_CDATA
,
1610 OUString::number(WTI(hwpinfo
.paper
.bottom_margin
)) + "inch");
1613 switch( hwpinfo
.borderline
)
1616 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.002cm solid #000000");
1619 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.002cm dotted #000000");
1622 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.035cm solid #000000");
1625 mxList
->addAttribute("style:border-line-width", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1626 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.039cm double #000000");
1630 mxList
->addAttribute("fo:padding-left", sXML_CDATA
,
1631 OUString::number(WTI(hwpinfo
.bordermargin
[0])) + "inch");
1632 mxList
->addAttribute("fo:padding-right", sXML_CDATA
,
1633 OUString::number(WTI(hwpinfo
.bordermargin
[1])) + "inch");
1634 mxList
->addAttribute("fo:padding-top", sXML_CDATA
,
1635 OUString::number(WTI(hwpinfo
.bordermargin
[2])) + "inch");
1636 mxList
->addAttribute("fo:padding-bottom", sXML_CDATA
,
1637 OUString::number(WTI(hwpinfo
.bordermargin
[3])) + "inch");
1639 /* background color */
1640 if( hwpinfo
.back_info
.isset
)
1642 if( hwpinfo
.back_info
.color
[0] > 0 || hwpinfo
.back_info
.color
[1] > 0
1643 || hwpinfo
.back_info
.color
[2] > 0 ){
1644 mxList
->addAttribute("fo:background-color", sXML_CDATA
,
1645 rgb2str(hwpinfo
.back_info
.color
[0],
1646 hwpinfo
.back_info
.color
[1],
1647 hwpinfo
.back_info
.color
[2]));
1651 startEl("style:properties");
1654 /* background image */
1655 if( hwpinfo
.back_info
.isset
&& hwpinfo
.back_info
.type
> 0 )
1657 if( hwpinfo
.back_info
.type
== 1 ){
1659 mxList
->addAttribute("xlink:href", sXML_CDATA
,
1660 hstr2OUString(kstr2hstr(reinterpret_cast<uchar
const *>(urltowin(hwpinfo
.back_info
.filename
).c_str())).c_str()));
1662 mxList
->addAttribute("xlink:href", sXML_CDATA
,
1663 hstr2OUString(kstr2hstr( reinterpret_cast<uchar
const *>(urltounix(hwpinfo
.back_info
.filename
).c_str())).c_str()));
1665 mxList
->addAttribute("xlink:type", sXML_CDATA
, "simple");
1666 mxList
->addAttribute("xlink:actuate", sXML_CDATA
, "onLoad");
1668 if( hwpinfo
.back_info
.flag
>= 2)
1669 mxList
->addAttribute("style:repeat", sXML_CDATA
, "stretch");
1670 else if( hwpinfo
.back_info
.flag
== 1 ){
1671 mxList
->addAttribute("style:repeat", sXML_CDATA
, "no-repeat");
1672 mxList
->addAttribute("style:position", sXML_CDATA
, "center");
1674 startEl("style:background-image");
1676 if( hwpinfo
.back_info
.type
== 2 ){
1677 startEl("office:binary-data");
1679 chars(base64_encode_string(reinterpret_cast<unsigned char*>(hwpinfo
.back_info
.data
.data()), hwpinfo
.back_info
.size
));
1680 endEl("office:binary-data");
1682 endEl("style:background-image");
1685 makeColumns( hwpfile
.GetColumnDef(i
) );
1687 endEl("style:properties");
1690 startEl("style:header-style");
1691 mxList
->addAttribute("svg:height", sXML_CDATA
,
1692 OUString::number(WTI(hwpinfo
.paper
.header_length
)) + "inch");
1693 mxList
->addAttribute("fo:margin-bottom", sXML_CDATA
, "0mm");
1695 startEl("style:properties");
1697 endEl("style:properties");
1698 endEl("style:header-style");
1701 startEl("style:footer-style");
1702 mxList
->addAttribute("svg:height", sXML_CDATA
,
1703 OUString::number(WTI(hwpinfo
.paper
.footer_length
)) + "inch");
1704 mxList
->addAttribute("fo:margin-top", sXML_CDATA
, "0mm");
1705 startEl("style:properties");
1707 endEl("style:properties");
1708 endEl("style:footer-style");
1710 /* Footnote style */
1711 startEl("style:page-layout-properties");
1713 mxList
->addAttribute("style:distance-before-sep", sXML_CDATA
,
1714 OUString::number(WTI(hwpinfo
.splinetext
)) + "inch");
1715 mxList
->addAttribute("style:distance-after-sep", sXML_CDATA
,
1716 OUString::number(WTI(hwpinfo
.splinefn
)) + "inch");
1717 startEl("style:properties");
1719 endEl("style:properties");
1720 if ( hwpinfo
.fnlinetype
== 2 )
1721 mxList
->addAttribute("style:width", sXML_CDATA
, "15cm");
1722 else if ( hwpinfo
.fnlinetype
== 1)
1723 mxList
->addAttribute("style:width", sXML_CDATA
, "2cm");
1724 else if ( hwpinfo
.fnlinetype
== 3)
1725 mxList
->addAttribute("style:width", sXML_CDATA
, "0cm");
1727 mxList
->addAttribute("style:width", sXML_CDATA
, "5cm");
1729 startEl("style:footnote-sep");
1731 endEl("style:footnote-sep");
1733 endEl("style:page-layout-properties");
1735 endEl("style:page-master");
1739 void HwpReader::makeColumns(ColumnDef
const *coldef
)
1741 if( !coldef
) return;
1742 mxList
->addAttribute("fo:column-count", sXML_CDATA
, OUString::number(coldef
->ncols
));
1743 startEl("style:columns");
1745 if( coldef
->separator
!= 0 )
1747 switch( coldef
->separator
)
1749 case 1: /* thin line */
1750 mxList
->addAttribute("style:width", sXML_CDATA
, "0.02mm");
1752 case 3: /* dotted line */
1753 mxList
->addAttribute("style:style", sXML_CDATA
, "dotted");
1754 mxList
->addAttribute("style:width", sXML_CDATA
, "0.02mm");
1756 case 2: /* thick line */
1757 case 4: /* double line */
1758 mxList
->addAttribute("style:width", sXML_CDATA
, "0.35mm");
1762 mxList
->addAttribute("style:style", sXML_CDATA
, "none");
1765 startEl("style:column-sep");
1767 endEl("style:column-sep");
1769 double spacing
= WTI(coldef
->spacing
)/ 2. ;
1770 for(int ii
= 0 ; ii
< coldef
->ncols
; ii
++)
1773 mxList
->addAttribute("fo:margin-left", sXML_CDATA
, "0mm");
1775 mxList
->addAttribute("fo:margin-left", sXML_CDATA
,
1776 OUString::number( spacing
) + "inch");
1777 if( ii
== ( coldef
->ncols
-1) )
1778 mxList
->addAttribute("fo:margin-right", sXML_CDATA
,"0mm");
1780 mxList
->addAttribute("fo:margin-right", sXML_CDATA
,
1781 OUString::number( spacing
) + "inch");
1782 startEl("style:column");
1784 endEl("style:column");
1786 endEl("style:columns");
1789 void HwpReader::makeTStyle(CharShape
const * cshape
)
1791 mxList
->addAttribute("style:name", sXML_CDATA
, "T" + OUString::number(cshape
->index
));
1792 mxList
->addAttribute("style:family", sXML_CDATA
, "text");
1793 startEl("style:style");
1795 parseCharShape(cshape
);
1796 startEl("style:properties");
1798 endEl("style:properties");
1799 endEl("style:style");
1803 void HwpReader::makeTableStyle(Table
*tbl
)
1806 TxtBox
*hbox
= tbl
->box
;
1808 mxList
->addAttribute("style:name", sXML_CDATA
, "Table" + OUString::number(hbox
->style
.boxnum
));
1809 mxList
->addAttribute("style:family", sXML_CDATA
,"table");
1810 startEl("style:style");
1812 mxList
->addAttribute("style:width", sXML_CDATA
,
1813 OUString::number(WTMM(hbox
->box_xs
)) + "mm");
1814 mxList
->addAttribute("table:align", sXML_CDATA
,"left");
1815 mxList
->addAttribute("fo:keep-with-next", sXML_CDATA
,"false");
1816 startEl("style:properties");
1818 endEl("style:properties");
1819 endEl("style:style");
1822 for (size_t i
= 0 ; i
< tbl
->columns
.nCount
-1 ; i
++)
1824 mxList
->addAttribute(
1825 "style:name", sXML_CDATA
,
1826 "Table" + OUString::number(hbox
->style
.boxnum
) + "."
1827 + OUStringChar(static_cast<char>('A'+i
)));
1828 mxList
->addAttribute("style:family", sXML_CDATA
,"table-column");
1829 startEl("style:style");
1831 mxList
->addAttribute("style:column-width", sXML_CDATA
,
1832 OUString::number(WTMM(tbl
->columns
.data
[i
+1] - tbl
->columns
.data
[i
])) + "mm");
1833 startEl("style:properties");
1835 endEl("style:properties");
1836 endEl("style:style");
1840 for (size_t i
= 0 ; i
< tbl
->rows
.nCount
-1 ; i
++)
1842 mxList
->addAttribute(
1843 "style:name", sXML_CDATA
,
1844 "Table" + OUString::number(hbox
->style
.boxnum
) + ".row" + OUString::number(i
+ 1));
1845 mxList
->addAttribute("style:family", sXML_CDATA
,"table-row");
1846 startEl("style:style");
1848 mxList
->addAttribute("style:row-height", sXML_CDATA
,
1849 OUString::number(WTMM(tbl
->rows
.data
[i
+1] - tbl
->rows
.data
[i
])) + "mm");
1850 startEl("style:properties");
1852 endEl("style:properties");
1853 endEl("style:style");
1857 for (auto const& tcell
: tbl
->cells
)
1859 mxList
->addAttribute(
1860 "style:name", sXML_CDATA
,
1861 "Table" + OUString::number(hbox
->style
.boxnum
) + "."
1862 + OUStringChar(char('A'+ tcell
->nColumnIndex
))
1863 + OUString::number(tcell
->nRowIndex
+1));
1864 mxList
->addAttribute("style:family", sXML_CDATA
,"table-cell");
1865 startEl("style:style");
1867 Cell
*cl
= tcell
->pCell
;
1868 if( cl
->ver_align
== 1 )
1869 mxList
->addAttribute("fo:vertical-align", sXML_CDATA
,"middle");
1871 if(cl
->linetype
[2] == cl
->linetype
[3] && cl
->linetype
[2] == cl
->linetype
[0]
1872 && cl
->linetype
[2] == cl
->linetype
[1])
1874 switch( cl
->linetype
[2] )
1876 case 1: /* A thin solid line */
1877 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
1878 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.002cm solid #000000");
1880 case 2: /* Bold lines */
1881 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.035cm solid #000000");
1883 case 4: /* Double line */
1884 mxList
->addAttribute("style:border-line-width", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1885 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.039cm double #000000");
1891 switch( cl
->linetype
[0] )
1893 case 1: /* A thin solid line */
1894 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
1895 mxList
->addAttribute("fo:border-left", sXML_CDATA
,"0.002cm solid #000000");
1897 case 2: /* Bold lines */
1898 mxList
->addAttribute("fo:border-left", sXML_CDATA
,"0.035cm solid #000000");
1900 case 4: /* Double line */
1901 mxList
->addAttribute("style:border-line-width-left", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1902 mxList
->addAttribute("fo:border-left", sXML_CDATA
,"0.039cm double #000000");
1905 switch( cl
->linetype
[1] )
1907 case 1: /* A thin solid line */
1908 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
1909 mxList
->addAttribute("fo:border-right", sXML_CDATA
,"0.002cm solid #000000");
1911 case 2: /* Bold lines */
1912 mxList
->addAttribute("fo:border-right", sXML_CDATA
,"0.035cm solid #000000");
1914 case 4: /* Double line */
1915 mxList
->addAttribute("style:border-line-width-right", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1916 mxList
->addAttribute("fo:border-right", sXML_CDATA
,"0.039cm double #000000");
1919 switch( cl
->linetype
[2] )
1921 case 1: /* A thin solid line */
1922 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
1923 mxList
->addAttribute("fo:border-top", sXML_CDATA
,"0.002cm solid #000000");
1925 case 2: /* Bold lines */
1926 mxList
->addAttribute("fo:border-top", sXML_CDATA
,"0.035cm solid #000000");
1928 case 4: /* Double line */
1929 mxList
->addAttribute("style:border-line-width-top", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1930 mxList
->addAttribute("fo:border-top", sXML_CDATA
,"0.039cm double #000000");
1933 switch( cl
->linetype
[3] )
1935 case 1: /* A thin solid line */
1936 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
1937 mxList
->addAttribute("fo:border-bottom", sXML_CDATA
,"0.002cm solid #000000");
1939 case 2: /* Bold lines */
1940 mxList
->addAttribute("fo:border-bottom", sXML_CDATA
,"0.035cm solid #000000");
1942 case 4: /* Double line */
1943 mxList
->addAttribute("style:border-line-width-bottom", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1944 mxList
->addAttribute("fo:border-bottom", sXML_CDATA
,"0.039cm double #000000");
1949 mxList
->addAttribute("fo:background-color", sXML_CDATA
,
1950 hcolor2str(sal::static_int_cast
<uchar
>(cl
->color
),
1951 sal::static_int_cast
<uchar
>(cl
->shade
)));
1953 startEl("style:properties");
1955 endEl("style:properties");
1957 endEl("style:style");
1962 void HwpReader::makeDrawStyle( HWPDrawingObject
* hdo
, FBoxStyle
* fstyle
)
1966 mxList
->addAttribute("style:name", sXML_CDATA
, "Draw" + OUString::number(hdo
->index
));
1967 mxList
->addAttribute("style:family", sXML_CDATA
, "graphics");
1969 startEl("style:style");
1972 switch (fstyle
->txtflow
)
1977 mxList
->addAttribute("style:wrap", sXML_CDATA
, "run-through");
1980 mxList
->addAttribute("style:wrap", sXML_CDATA
, "dynamic");
1985 if( hdo
->property
.line_color
> 0xffffff )
1987 mxList
->addAttribute("draw:stroke", sXML_CDATA
, "none" );
1992 if( hdo
->property
.line_pstyle
== 0 )
1993 mxList
->addAttribute("draw:stroke", sXML_CDATA
, "solid" );
1994 else if( hdo
->property
.line_pstyle
< 5 )
1996 mxList
->addAttribute("draw:stroke", sXML_CDATA
, "dash" );
1997 mxList
->addAttribute("draw:stroke-dash", sXML_CDATA
, "LineType" + OUString::number(hdo
->index
));
1999 mxList
->addAttribute("svg:stroke-width", sXML_CDATA
,
2000 OUString::number( WTMM(hdo
->property
.line_width
)) + "mm");
2001 mxList
->addAttribute("svg:stroke-color", sXML_CDATA
,
2002 rgb2str(static_cast<int32_t>(hdo
->property
.line_color
)));
2005 if( hdo
->type
== HWPDO_LINE
|| hdo
->type
== HWPDO_ARC
||
2006 hdo
->type
== HWPDO_FREEFORM
|| hdo
->type
== HWPDO_ADVANCED_ARC
)
2009 if( hdo
->property
.line_tstyle
> 0 &&
2010 o3tl::make_unsigned(hdo
->property
.line_tstyle
) < std::size(ArrowShape
) )
2012 mxList
->addAttribute("draw:marker-start", sXML_CDATA
,
2013 OUString::createFromAscii(ArrowShape
[hdo
->property
.line_tstyle
].name
) );
2014 if( hdo
->property
.line_width
> 100 )
2015 mxList
->addAttribute("draw:marker-start-width", sXML_CDATA
,
2016 OUString::number( WTMM(hdo
->property
.line_width
* 3)) + "mm");
2017 else if( hdo
->property
.line_width
> 80 )
2018 mxList
->addAttribute("draw:marker-start-width", sXML_CDATA
,
2019 OUString::number( WTMM(hdo
->property
.line_width
* 4)) + "mm");
2020 else if( hdo
->property
.line_width
> 60 )
2021 mxList
->addAttribute("draw:marker-start-width", sXML_CDATA
,
2022 OUString::number( WTMM(hdo
->property
.line_width
* 5)) + "mm");
2023 else if( hdo
->property
.line_width
> 40 )
2024 mxList
->addAttribute("draw:marker-start-width", sXML_CDATA
,
2025 OUString::number( WTMM(hdo
->property
.line_width
* 6)) + "mm");
2027 mxList
->addAttribute("draw:marker-start-width", sXML_CDATA
,
2028 OUString::number( WTMM(hdo
->property
.line_width
* 7)) + "mm");
2031 if( hdo
->property
.line_hstyle
> 0 &&
2032 o3tl::make_unsigned(hdo
->property
.line_hstyle
) < std::size(ArrowShape
) )
2034 mxList
->addAttribute("draw:marker-end", sXML_CDATA
,
2035 OUString::createFromAscii(ArrowShape
[hdo
->property
.line_hstyle
].name
) );
2036 if( hdo
->property
.line_width
> 100 )
2037 mxList
->addAttribute("draw:marker-end-width", sXML_CDATA
,
2038 OUString::number( WTMM(hdo
->property
.line_width
* 3)) + "mm");
2039 else if( hdo
->property
.line_width
> 80 )
2040 mxList
->addAttribute("draw:marker-end-width", sXML_CDATA
,
2041 OUString::number( WTMM(hdo
->property
.line_width
* 4)) + "mm");
2042 else if( hdo
->property
.line_width
> 60 )
2043 mxList
->addAttribute("draw:marker-end-width", sXML_CDATA
,
2044 OUString::number( WTMM(hdo
->property
.line_width
* 5)) + "mm");
2045 else if( hdo
->property
.line_width
> 40 )
2046 mxList
->addAttribute("draw:marker-end-width", sXML_CDATA
,
2047 OUString::number( WTMM(hdo
->property
.line_width
* 6)) + "mm");
2049 mxList
->addAttribute("draw:marker-end-width", sXML_CDATA
,
2050 OUString::number( WTMM(hdo
->property
.line_width
* 7)) + "mm");
2054 if(hdo
->type
!= HWPDO_LINE
)
2056 if( hdo
->property
.flag
>> 19 & 0x01 )
2058 mxList
->addAttribute( "draw:textarea-horizontal-align", sXML_CDATA
, "center");
2061 color
= hdo
->property
.fill_color
;
2063 if( hdo
->property
.flag
>> 18 & 0x01 ) // bitmap pattern
2065 mxList
->addAttribute("draw:fill", sXML_CDATA
, "bitmap");
2066 mxList
->addAttribute("draw:fill-image-name", sXML_CDATA
,
2067 "fillimage" + OUString::number(hdo
->index
));
2069 if( hdo
->property
.flag
>> 3 & 0x01 )
2071 mxList
->addAttribute("style:repeat", sXML_CDATA
, "stretch");
2075 mxList
->addAttribute("style:repeat", sXML_CDATA
, "repeat");
2076 mxList
->addAttribute("draw:fill-image-ref-point", sXML_CDATA
, "top-left");
2078 if( hdo
->property
.flag
>> 20 & 0x01 )
2080 if( hdo
->property
.luminance
> 0 )
2082 mxList
->addAttribute("draw:transparency", sXML_CDATA
,
2083 OUString::number(hdo
->property
.luminance
) + "%");
2089 else if( hdo
->property
.flag
>> 16 & 0x01 )
2091 mxList
->addAttribute("draw:fill", sXML_CDATA
, "gradient");
2092 mxList
->addAttribute("draw:fill-gradient-name", sXML_CDATA
, "Grad" + OUString::number(hdo
->index
));
2093 mxList
->addAttribute("draw:gradient-step-count", sXML_CDATA
, OUString::number(hdo
->property
.nstep
));
2097 else if( hdo
->property
.pattern_type
>> 24 & 0x01 )
2099 mxList
->addAttribute("draw:fill", sXML_CDATA
, "hatch");
2100 mxList
->addAttribute("draw:fill-hatch-name", sXML_CDATA
, "Hatch" + OUString::number(hdo
->index
));
2101 if( color
< 0xffffff )
2103 mxList
->addAttribute("draw:fill-color", sXML_CDATA
,
2104 rgb2str(static_cast<int32_t>(color
)));
2105 mxList
->addAttribute("draw:fill-hatch-solid", sXML_CDATA
, "true");
2108 else if( color
<= 0xffffff )
2110 mxList
->addAttribute("draw:fill", sXML_CDATA
, "solid");
2111 mxList
->addAttribute("draw:fill-color", sXML_CDATA
,
2112 rgb2str(static_cast<int32_t>(color
)));
2115 mxList
->addAttribute("draw:fill", sXML_CDATA
, "none");
2118 if( fstyle
->anchor_type
== CHAR_ANCHOR
)
2120 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "top");
2121 mxList
->addAttribute("style:vertical-rel", sXML_CDATA
, "baseline");
2124 startEl("style:properties");
2126 endEl("style:properties");
2127 endEl("style:style");
2129 if( hdo
->type
== 0 )
2131 makeDrawStyle( hdo
->child
.get(), fstyle
);
2133 hdo
= hdo
->next
.get();
2138 void HwpReader::makeCaptionStyle(FBoxStyle
* fstyle
)
2140 mxList
->addAttribute("style:name", sXML_CDATA
, "CapBox" + OUString::number(fstyle
->boxnum
));
2141 mxList
->addAttribute("style:family", sXML_CDATA
, "graphics");
2142 startEl("style:style");
2144 mxList
->addAttribute("fo:margin-left", sXML_CDATA
, "0cm");
2145 mxList
->addAttribute("fo:margin-right", sXML_CDATA
, "0cm");
2146 mxList
->addAttribute("fo:margin-top", sXML_CDATA
, "0cm");
2147 mxList
->addAttribute("fo:margin-bottom", sXML_CDATA
, "0cm");
2148 mxList
->addAttribute("fo:padding", sXML_CDATA
, "0cm");
2149 switch (fstyle
->txtflow
)
2152 mxList
->addAttribute("style:wrap", sXML_CDATA
, "none");
2155 if( fstyle
->boxtype
== 'G' )
2156 mxList
->addAttribute("style:run-through", sXML_CDATA
, "background");
2157 mxList
->addAttribute("style:wrap", sXML_CDATA
, "run-through");
2160 mxList
->addAttribute("style:wrap", sXML_CDATA
, "dynamic");
2163 if (fstyle
->anchor_type
== CHAR_ANCHOR
)
2165 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "top");
2166 mxList
->addAttribute("style:vertical-rel", sXML_CDATA
, "baseline");
2167 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "center");
2168 mxList
->addAttribute("style:horizontal-rel", sXML_CDATA
, "paragraph");
2173 switch (-(fstyle
->xpos
))
2176 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "right");
2179 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "center");
2183 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "from-left");
2186 switch (-(fstyle
->ypos
))
2189 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "bottom");
2192 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "middle");
2196 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "from-top");
2199 if ( fstyle
->anchor_type
== PARA_ANCHOR
)
2201 mxList
->addAttribute("style:vertical-rel", sXML_CDATA
, "paragraph");
2202 mxList
->addAttribute("style:horizontal-rel", sXML_CDATA
, "paragraph");
2206 mxList
->addAttribute("style:vertical-rel", sXML_CDATA
, "page-content");
2207 mxList
->addAttribute("style:horizontal-rel", sXML_CDATA
, "page-content");
2210 startEl("style:properties");
2212 endEl("style:properties");
2213 endEl("style:style");
2214 if( fstyle
->boxtype
== 'G' )
2216 mxList
->addAttribute("style:name", sXML_CDATA
, "G" + OUString::number(fstyle
->boxnum
));
2220 mxList
->addAttribute("style:name", sXML_CDATA
, "Txtbox" + OUString::number(fstyle
->boxnum
));
2223 mxList
->addAttribute("style:family", sXML_CDATA
, "graphics");
2224 startEl("style:style");
2227 mxList
->addAttribute("fo:margin-left", sXML_CDATA
, "0cm");
2228 mxList
->addAttribute("fo:margin-right", sXML_CDATA
, "0cm");
2229 mxList
->addAttribute("fo:margin-top", sXML_CDATA
, "0cm");
2230 mxList
->addAttribute("fo:margin-bottom", sXML_CDATA
, "0cm");
2231 mxList
->addAttribute("fo:padding", sXML_CDATA
, "0cm");
2232 mxList
->addAttribute("style:wrap", sXML_CDATA
, "none");
2233 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "from-top");
2234 mxList
->addAttribute("style:vertical-rel", sXML_CDATA
, "paragraph");
2235 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "from-left");
2236 mxList
->addAttribute("style:horizontal-rel", sXML_CDATA
, "paragraph");
2237 if (fstyle
->boxtype
== 'G' && fstyle
->cell
)
2239 char *cell
= static_cast<char *>(fstyle
->cell
);
2240 mxList
->addAttribute("draw:luminance", sXML_CDATA
, OUString::number(cell
[0]) + "%");
2241 mxList
->addAttribute("draw:contrast", sXML_CDATA
, OUString::number(cell
[1]) + "%");
2243 mxList
->addAttribute("draw:color-mode", sXML_CDATA
, "standard");
2244 else if( cell
[2] == 1 )
2245 mxList
->addAttribute("draw:color-mode", sXML_CDATA
, "greyscale");
2246 else if( cell
[2] == 2 )
2247 mxList
->addAttribute("draw:color-mode", sXML_CDATA
, "mono");
2249 else if (fstyle
->cell
)
2251 Cell
*cell
= static_cast<Cell
*>(fstyle
->cell
);
2252 if(cell
->linetype
[0] == cell
->linetype
[1] &&
2253 cell
->linetype
[0] == cell
->linetype
[2] &&
2254 cell
->linetype
[0] == cell
->linetype
[3])
2256 switch( cell
->linetype
[0] )
2259 mxList
->addAttribute("fo:padding", sXML_CDATA
,"0mm");
2261 case 1: /* A thin solid line */
2262 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2263 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.002cm solid #000000");
2265 case 2: /* Bold lines */
2266 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.035cm solid #000000");
2268 case 4: /* Double line */
2269 mxList
->addAttribute("style:border-line-width", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2270 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.039cm double #000000");
2276 switch( cell
->linetype
[0] )
2278 case 1: /* A thin solid line */
2279 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2280 mxList
->addAttribute("fo:border-left", sXML_CDATA
,"0.002cm solid #000000");
2282 case 2: /* Bold lines */
2283 mxList
->addAttribute("fo:border-left", sXML_CDATA
,"0.035cm solid #000000");
2285 case 4: /* Double line */
2286 mxList
->addAttribute("style:border-line-width-left", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2287 mxList
->addAttribute("fo:border-left", sXML_CDATA
,"0.039cm double #000000");
2290 switch( cell
->linetype
[1] )
2292 case 1: /* A thin solid line */
2293 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2294 mxList
->addAttribute("fo:border-right", sXML_CDATA
,"0.002cm solid #000000");
2296 case 2: /* Bold lines */
2297 mxList
->addAttribute("fo:border-right", sXML_CDATA
,"0.035cm solid #000000");
2299 case 4: /* Double line */
2300 mxList
->addAttribute("style:border-line-width-right", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2301 mxList
->addAttribute("fo:border-right", sXML_CDATA
,"0.039cm double #000000");
2304 switch( cell
->linetype
[2] )
2306 case 1: /* A thin solid line */
2307 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2308 mxList
->addAttribute("fo:border-top", sXML_CDATA
,"0.002cm solid #000000");
2310 case 2: /* Bold lines */
2311 mxList
->addAttribute("fo:border-top", sXML_CDATA
,"0.035cm solid #000000");
2313 case 4: /* Double line */
2314 mxList
->addAttribute("style:border-line-width-top", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2315 mxList
->addAttribute("fo:border-top", sXML_CDATA
,"0.039cm double #000000");
2318 switch( cell
->linetype
[3] )
2320 case 1: /* A thin solid line */
2321 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2322 mxList
->addAttribute("fo:border-bottom", sXML_CDATA
,"0.002cm solid #000000");
2324 case 2: /* Bold lines */
2325 mxList
->addAttribute("fo:border-bottom", sXML_CDATA
,"0.035cm solid #000000");
2327 case 4: /* Double line */
2328 mxList
->addAttribute("style:border-line-width-bottom", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2329 mxList
->addAttribute("fo:border-bottom", sXML_CDATA
,"0.039cm double #000000");
2333 if(cell
->shade
!= 0)
2334 mxList
->addAttribute("fo:background-color", sXML_CDATA
, hcolor2str(
2335 sal::static_int_cast
<uchar
>(cell
->color
),
2336 sal::static_int_cast
<uchar
>(cell
->shade
)));
2338 startEl("style:properties");
2340 endEl("style:properties");
2341 endEl("style:style");
2346 * Create a style for the Floating objects.
2348 void HwpReader::makeFStyle(FBoxStyle
* fstyle
)
2351 if( ( fstyle
->boxtype
== 'G' || fstyle
->boxtype
== 'X' ) && fstyle
->cap_len
> 0 )
2353 makeCaptionStyle(fstyle
);
2356 switch( fstyle
->boxtype
)
2358 case 'X' : // txtbox
2359 case 'E' : // equation
2360 case 'B' : // button
2363 mxList
->addAttribute("style:name", sXML_CDATA
, "Txtbox" + OUString::number(fstyle
->boxnum
));
2364 mxList
->addAttribute("style:family", sXML_CDATA
, "graphics");
2366 case 'G' : // graphics
2367 mxList
->addAttribute("style:name", sXML_CDATA
, "G" + OUString::number(fstyle
->boxnum
));
2368 mxList
->addAttribute("style:family", sXML_CDATA
, "graphics");
2370 case 'L' : // line TODO : all
2371 mxList
->addAttribute("style:name", sXML_CDATA
, "L" + OUString::number(fstyle
->boxnum
));
2372 mxList
->addAttribute( "style:family" , sXML_CDATA
, "paragraph" );
2376 startEl("style:style");
2379 if ( fstyle
->boxtype
== 'T')
2381 mxList
->addAttribute("fo:padding", sXML_CDATA
, "0cm");
2384 if( fstyle
->boxtype
!= 'G' || fstyle
->cap_len
<= 0 )
2386 mxList
->addAttribute("fo:margin-left", sXML_CDATA
,
2387 OUString::number(WTMM(fstyle
->margin
[0][0]) ) + "mm");
2388 mxList
->addAttribute("fo:margin-right", sXML_CDATA
,
2389 OUString::number(WTMM(fstyle
->margin
[0][1])) + "mm");
2390 mxList
->addAttribute("fo:margin-top", sXML_CDATA
,
2391 OUString::number(WTMM(fstyle
->margin
[0][2])) + "mm");
2392 mxList
->addAttribute("fo:margin-bottom", sXML_CDATA
,
2393 OUString::number(WTMM(fstyle
->margin
[0][3])) + "mm");
2396 switch (fstyle
->txtflow
)
2399 mxList
->addAttribute("style:wrap", sXML_CDATA
, "none");
2402 if( fstyle
->boxtype
== 'G' || fstyle
->boxtype
== 'B' || fstyle
->boxtype
== 'O')
2403 mxList
->addAttribute("style:run-through", sXML_CDATA
, "background");
2404 mxList
->addAttribute("style:wrap", sXML_CDATA
, "run-through");
2407 mxList
->addAttribute("style:wrap", sXML_CDATA
, "dynamic");
2410 if (fstyle
->anchor_type
== CHAR_ANCHOR
)
2412 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "top");
2413 mxList
->addAttribute("style:vertical-rel", sXML_CDATA
, "baseline");
2414 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "center");
2415 mxList
->addAttribute("style:horizontal-rel", sXML_CDATA
, "paragraph");
2420 switch (-(fstyle
->xpos
))
2423 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "right");
2426 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "center");
2430 mxList
->addAttribute("style:horizontal-pos", sXML_CDATA
, "from-left");
2433 switch (-(fstyle
->ypos
))
2436 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "bottom");
2439 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "middle");
2443 mxList
->addAttribute("style:vertical-pos", sXML_CDATA
, "from-top");
2446 if ( fstyle
->anchor_type
== PARA_ANCHOR
)
2448 mxList
->addAttribute("style:vertical-rel", sXML_CDATA
, "paragraph");
2449 mxList
->addAttribute("style:horizontal-rel", sXML_CDATA
, "paragraph");
2453 mxList
->addAttribute("style:vertical-rel", sXML_CDATA
, "page-content");
2454 mxList
->addAttribute("style:horizontal-rel", sXML_CDATA
, "page-content");
2457 if (fstyle
->cell
&& (fstyle
->boxtype
== 'X' || fstyle
->boxtype
== 'B'))
2459 Cell
*cell
= static_cast<Cell
*>(fstyle
->cell
);
2460 if(cell
->linetype
[0] == cell
->linetype
[1] &&
2461 cell
->linetype
[0] == cell
->linetype
[2] &&
2462 cell
->linetype
[0] == cell
->linetype
[3])
2464 switch( cell
->linetype
[0] )
2467 mxList
->addAttribute("fo:border", sXML_CDATA
, "none");
2469 case 1: /* A thin solid line */
2470 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2471 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.002cm solid #000000");
2473 case 2: /* Bold lines */
2474 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.035cm solid #000000");
2476 case 4: /* Double line */
2477 mxList
->addAttribute("style:border-line-width", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2478 mxList
->addAttribute("fo:border", sXML_CDATA
,"0.039cm double #000000");
2484 switch( cell
->linetype
[0] )
2486 case 1: /* A thin solid line */
2487 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2488 mxList
->addAttribute("fo:border-left", sXML_CDATA
,"0.002cm solid #000000");
2490 case 2: /* Bold lines */
2491 mxList
->addAttribute("fo:border-left", sXML_CDATA
,"0.035cm solid #000000");
2493 case 4: /* Double line */
2494 mxList
->addAttribute("style:border-line-width-left", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2495 mxList
->addAttribute("fo:border-left", sXML_CDATA
,"0.039cm double #000000");
2498 switch( cell
->linetype
[1] )
2500 case 1: /* A thin solid line */
2501 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2502 mxList
->addAttribute("fo:border-right", sXML_CDATA
,"0.002cm solid #000000");
2504 case 2: /* Bold lines */
2505 mxList
->addAttribute("fo:border-right", sXML_CDATA
,"0.035cm solid #000000");
2507 case 4: /* Double line */
2508 mxList
->addAttribute("style:border-line-width-right", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2509 mxList
->addAttribute("fo:border-right", sXML_CDATA
,"0.039cm double #000000");
2512 switch( cell
->linetype
[2] )
2514 case 1: /* A thin solid line */
2515 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2516 mxList
->addAttribute("fo:border-top", sXML_CDATA
,"0.002cm solid #000000");
2518 case 2: /* Bold lines */
2519 mxList
->addAttribute("fo:border-top", sXML_CDATA
,"0.035cm solid #000000");
2521 case 4: /* Double line */
2522 mxList
->addAttribute("style:border-line-width-top", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2523 mxList
->addAttribute("fo:border-top", sXML_CDATA
,"0.039cm double #000000");
2526 switch( cell
->linetype
[3] )
2528 case 1: /* A thin solid line */
2529 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2530 mxList
->addAttribute("fo:border-bottom", sXML_CDATA
,"0.002cm solid #000000");
2532 case 2: /* Bold lines */
2533 mxList
->addAttribute("fo:border-bottom", sXML_CDATA
,"0.035cm solid #000000");
2535 case 4: /* Double line */
2536 mxList
->addAttribute("style:border-line-width-bottom", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2537 mxList
->addAttribute("fo:border-bottom", sXML_CDATA
,"0.039cm double #000000");
2542 if( cell
->linetype
[0] == 0 && cell
->linetype
[1] == 0 &&
2543 cell
->linetype
[2] == 0 && cell
->linetype
[3] == 0 ){
2544 mxList
->addAttribute("fo:padding", sXML_CDATA
,"0mm");
2547 mxList
->addAttribute("fo:padding-left", sXML_CDATA
,
2548 OUString::number(WTMM(fstyle
->margin
[1][0])) + "mm");
2549 mxList
->addAttribute("fo:padding-right", sXML_CDATA
,
2550 OUString::number(WTMM(fstyle
->margin
[1][1])) + "mm");
2551 mxList
->addAttribute("fo:padding-top", sXML_CDATA
,
2552 OUString::number(WTMM(fstyle
->margin
[1][2])) + "mm");
2553 mxList
->addAttribute("fo:padding-bottom", sXML_CDATA
,
2554 OUString::number(WTMM(fstyle
->margin
[1][3])) + "mm");
2556 if(cell
->shade
!= 0)
2557 mxList
->addAttribute("fo:background-color", sXML_CDATA
,
2559 sal::static_int_cast
<uchar
>(cell
->color
),
2560 sal::static_int_cast
<uchar
>(cell
->shade
)));
2562 else if( fstyle
->boxtype
== 'E' )
2564 mxList
->addAttribute("fo:padding", sXML_CDATA
,"0mm");
2566 else if( fstyle
->boxtype
== 'L' )
2568 mxList
->addAttribute( "style:border-line-width-bottom", sXML_CDATA
, "0.02mm 0.35mm 0.02mm");
2569 mxList
->addAttribute("fo:border-bottom", sXML_CDATA
,"0.039cm double #808080");
2571 else if( fstyle
->boxtype
== 'G' && fstyle
->cell
)
2573 if( fstyle
->margin
[1][0] || fstyle
->margin
[1][1] || fstyle
->margin
[1][2] || fstyle
->margin
[1][3] ){
2574 OUString clip
= "rect(" +
2575 OUString::number(WTMM(-fstyle
->margin
[1][0]) ) + "mm " +
2576 OUString::number(WTMM(-fstyle
->margin
[1][1]) ) + "mm " +
2577 OUString::number(WTMM(-fstyle
->margin
[1][2]) ) + "mm " +
2578 OUString::number(WTMM(-fstyle
->margin
[1][3]) ) + "mm)";
2579 mxList
->addAttribute("style:mirror", sXML_CDATA
, "none");
2580 mxList
->addAttribute("fo:clip", sXML_CDATA
, clip
);
2582 char *cell
= static_cast<char *>(fstyle
->cell
);
2583 mxList
->addAttribute("draw:luminance", sXML_CDATA
, OUString::number(cell
[0]) + "%");
2584 mxList
->addAttribute("draw:contrast", sXML_CDATA
, OUString::number(cell
[1]) + "%");
2586 mxList
->addAttribute("draw:color-mode", sXML_CDATA
, "standard");
2587 else if( cell
[2] == 1 )
2588 mxList
->addAttribute("draw:color-mode", sXML_CDATA
, "greyscale");
2589 else if( cell
[2] == 2 )
2590 mxList
->addAttribute("draw:color-mode", sXML_CDATA
, "mono");
2593 startEl("style:properties");
2595 endEl("style:properties");
2596 endEl("style:style");
2600 OUString
HwpReader::getTStyleName(int index
)
2602 return "T" + OUString::number(index
);
2606 OUString
HwpReader::getPStyleName(int index
)
2608 return "P" + OUString::number(index
);
2612 void HwpReader::makeChars(hchar_string
& rStr
)
2614 chars(fromHcharStringToOUString(rStr
));
2620 * If no special characters in the paragraph and all characters use the same CharShape
2622 void HwpReader::make_text_p0(HWPPara
* para
, bool bParaStart
)
2627 unsigned char firstspace
= 0;
2630 mxList
->addAttribute("text:style-name", sXML_CDATA
,
2631 getPStyleName(para
->GetParaShape().index
));
2635 if( d
->bFirstPara
&& d
->bInBody
)
2637 mxList
->addAttribute("text:name", sXML_CDATA
, sBeginOfDoc
);
2638 startEl("text:bookmark");
2640 endEl("text:bookmark");
2641 d
->bFirstPara
= false;
2646 d
->bInHeader
= false;
2648 mxList
->addAttribute("text:style-name", sXML_CDATA
,
2649 getTStyleName(para
->cshape
->index
));
2650 startEl("text:span");
2653 for (const auto& box
: para
->hhstr
)
2658 if (box
->hh
== CH_SPACE
&& !firstspace
)
2664 else if (box
->hh
== CH_END_PARA
)
2673 if (box
->hh
== CH_SPACE
)
2677 res
= hcharconv(box
->hh
, dest
, UNICODE
);
2678 for( int j
= 0 ; j
< res
; j
++ )
2680 str
.push_back(dest
[j
]);
2688 * There is no special characters in the paragraph, but characters use different CharShapes
2690 void HwpReader::make_text_p1(HWPPara
* para
,bool bParaStart
)
2695 int curr
= para
->cshape
->index
;
2696 unsigned char firstspace
= 0;
2700 mxList
->addAttribute("text:style-name", sXML_CDATA
,
2701 getPStyleName(para
->GetParaShape().index
));
2705 if( d
->bFirstPara
&& d
->bInBody
)
2707 /* for HWP's Bookmark */
2708 mxList
->addAttribute("text:name", sXML_CDATA
, sBeginOfDoc
);
2709 startEl("text:bookmark");
2711 endEl("text:bookmark");
2712 d
->bFirstPara
= false;
2717 d
->bInHeader
= false;
2719 mxList
->addAttribute("text:style-name", sXML_CDATA
,
2720 getTStyleName(curr
));
2721 startEl("text:span");
2725 for (const auto& box
: para
->hhstr
)
2730 if (para
->GetCharShape(n
)->index
!= curr
)
2734 curr
= para
->GetCharShape(n
)->index
;
2735 mxList
->addAttribute("text:style-name", sXML_CDATA
,
2736 getTStyleName(curr
));
2737 startEl("text:span");
2740 if (box
->hh
== CH_SPACE
&& !firstspace
)
2746 else if (box
->hh
== CH_END_PARA
)
2755 if( box
->hh
< CH_SPACE
)
2757 if (box
->hh
== CH_SPACE
)
2761 res
= hcharconv(box
->hh
, dest
, UNICODE
);
2762 for( int j
= 0 ; j
< res
; j
++ )
2764 str
.push_back(dest
[j
]);
2773 * Special characters are in the paragraph and characters use different CharShapes
2775 void HwpReader::make_text_p3(HWPPara
* para
,bool bParaStart
)
2780 unsigned char firstspace
= 0;
2781 bool pstart
= bParaStart
;
2782 bool tstart
= false;
2783 bool infield
= false;
2785 const auto STARTP
= [this, para
, &pstart
]()
2787 mxList
->addAttribute("text:style-name", "CDATA",
2788 getPStyleName(para
->GetParaShape().index
));
2793 const auto STARTT
= [this, para
, &tstart
](int pos
)
2795 auto curr
= para
->GetCharShape(pos
> 0 ? pos
- 1 : 0)->index
;
2796 mxList
->addAttribute("text:style-name", "CDATA", getTStyleName(curr
));
2797 startEl("text:span");
2801 const auto ENDP
= [this, &pstart
]()
2806 const auto ENDT
= [this, &tstart
]()
2812 if( d
->bFirstPara
&& d
->bInBody
)
2817 mxList
->addAttribute("text:name", sXML_CDATA
, sBeginOfDoc
);
2818 startEl("text:bookmark");
2820 endEl("text:bookmark");
2821 d
->bFirstPara
= false;
2829 d
->bInHeader
= false;
2833 for (const auto& box
: para
->hhstr
)
2838 if (box
->hh
== CH_END_PARA
)
2842 if( !pstart
){ STARTP(); }
2843 if( !tstart
){ STARTT(n
);}
2846 if( tstart
){ ENDT();}
2847 if( !pstart
){ STARTP(); }
2848 if( pstart
){ ENDP(); }
2851 else if (box
->hh
== CH_SPACE
&& !firstspace
)
2853 if( !pstart
) {STARTP(); }
2854 if( !tstart
) {STARTT(n
);}
2860 else if (box
->hh
>= CH_SPACE
)
2863 if( para
->GetCharShape(n
)->index
!= para
->GetCharShape(n
-1)->index
&& !infield
)
2865 if( !pstart
) {STARTP(); }
2866 if( !tstart
) {STARTT(n
);}
2870 if (box
->hh
== CH_SPACE
)
2874 res
= hcharconv(box
->hh
, dest
, UNICODE
);
2875 for( int j
= 0 ; j
< res
; j
++ )
2877 str
.push_back(dest
[j
]);
2880 else if (box
->hh
== CH_FIELD
)
2882 FieldCode
*hbox
= static_cast<FieldCode
*>(box
.get());
2883 if( hbox
->location_info
== 1)
2885 if( !pstart
) {STARTP(); }
2886 if( !tstart
) {STARTT(n
);}
2889 if( hbox
->type
[0] == 4 && hbox
->type
[1] == 0 )
2891 d
->pField
= hbox
->str3
.get();
2894 makeFieldCode(str
, hbox
);
2901 if( hbox
->type
[0] == 4 && hbox
->type
[1] == 0 )
2903 makeFieldCode(str
, hbox
);
2904 d
->pField
= nullptr;
2915 if( !pstart
) {STARTP(); }
2916 if( !tstart
) {STARTT(n
);}
2918 makeBookmark(static_cast<Bookmark
*>(box
.get()));
2920 case CH_DATE_FORM
: // 7
2922 case CH_DATE_CODE
: // 8
2923 if( !pstart
) {STARTP(); }
2924 if( !tstart
) {STARTT(n
);}
2926 makeDateCode(static_cast<DateCode
*>(box
.get()));
2929 if( !pstart
) {STARTP(); }
2932 if( !tstart
) {STARTT(n
);}
2937 case CH_TEXT_BOX
: /* 10 - ordered by Table/text box/formula/button/hypertext */
2939 /* produce tables first, and treat formula as being in text:p. */
2940 TxtBox
*hbox
= static_cast<TxtBox
*>(box
.get());
2942 if( hbox
->style
.anchor_type
== 0 )
2944 if( !pstart
) {STARTP(); }
2945 if( !tstart
) {STARTT(n
);}
2950 if( !pstart
) {STARTP(); }
2953 if( !tstart
) {STARTT(n
);}
2956 if( tstart
) {ENDT();}
2960 case TBL_TYPE
: // table
2961 case TXT_TYPE
: // text box
2962 case EQU_TYPE
: // formula
2965 case BUTTON_TYPE
: // text button
2966 case HYPERTEXT_TYPE
: // hypertext
2967 makeHyperText(hbox
);
2972 case CH_PICTURE
: // 11
2974 Picture
*hbox
= static_cast<Picture
*>(box
.get());
2975 if( hbox
->style
.anchor_type
== 0 )
2977 if( !pstart
) {STARTP(); }
2978 if( !tstart
) {STARTT(n
);}
2983 if( !pstart
) {STARTP(); }
2986 if( !tstart
) {STARTT(n
);}
2989 if( tstart
) {ENDT();}
2998 if( !pstart
) {STARTP();}
2999 if( !tstart
) {STARTT(n
);}
3002 if( tstart
) {ENDT();}
3003 if( pstart
) {ENDP();}
3008 case CH_HIDDEN
: // 15
3009 if( !pstart
) {STARTP();}
3010 if( !tstart
) {STARTT(n
);}
3012 makeHidden(static_cast<Hidden
*>(box
.get()));
3014 case CH_FOOTNOTE
: // 17
3015 if( !pstart
) {STARTP();}
3016 if( !tstart
) {STARTT(n
);}
3018 makeFootnote(static_cast<Footnote
*>(box
.get()));
3020 case CH_AUTO_NUM
: // 18
3021 if( !pstart
) {STARTP();}
3022 if( !tstart
) {STARTT(n
);}
3024 makeAutoNum(static_cast<AutoNum
*>(box
.get()));
3026 case CH_NEW_NUM
: // 19 -skip
3028 case CH_PAGE_NUM_CTRL
: // 21
3030 case CH_MAIL_MERGE
: // 22
3031 if( !pstart
) {STARTP();}
3032 if( !tstart
) {STARTT(n
);}
3034 makeMailMerge(static_cast<MailMerge
*>(box
.get()));
3036 case CH_COMPOSE
: /* 23 - overlapping letters */
3038 case CH_HYPHEN
: // 24
3040 case CH_TOC_MARK
: /* 25 Need to fix below 3 */
3041 if( !pstart
) {STARTP();}
3042 if( !tstart
) {STARTT(n
);}
3045 case CH_INDEX_MARK
: // 26
3046 if( !pstart
) {STARTP();}
3047 if( !tstart
) {STARTT(n
);}
3050 case CH_OUTLINE
: // 28
3051 if( !pstart
) {STARTP();}
3052 if( !tstart
) {STARTT(n
);}
3054 makeOutline(static_cast<Outline
*>(box
.get()));
3056 case CH_FIXED_SPACE
:
3058 str
.push_back(0x0020);
3067 void HwpReader::makeFieldCode(hchar_string
const & rStr
, FieldCode
const *hbox
)
3070 if( hbox
->type
[0] == 4 && hbox
->type
[1] == 0 )
3072 mxList
->addAttribute("text:placeholder-type", sXML_CDATA
, "text");
3074 mxList
->addAttribute("text:description", sXML_CDATA
, hstr2OUString(d
->pField
));
3075 startEl("text:placeholder");
3077 chars( fromHcharStringToOUString(rStr
) );
3078 endEl("text:placeholder");
3080 /* Document Summary */
3081 else if( hbox
->type
[0] == 3 && hbox
->type
[1] == 0 )
3083 const OUString uStr3
= hstr2OUString(hbox
->str3
.get());
3084 if (uStr3
== "title")
3086 startEl("text:title");
3087 chars( hstr2OUString(hbox
->str2
.get()) );
3088 endEl("text:title");
3090 else if (uStr3
== "subject")
3092 startEl("text:subject");
3093 chars( hstr2OUString(hbox
->str2
.get()) );
3094 endEl("text:subject");
3096 else if (uStr3
== "author")
3098 startEl("text:author-name");
3099 chars( hstr2OUString(hbox
->str2
.get()) );
3100 endEl("text:author-name");
3102 else if (uStr3
== "keywords")
3104 startEl("text:keywords");
3105 chars( hstr2OUString(hbox
->str2
.get()) );
3106 endEl("text:keywords");
3109 /* Personal Information */
3110 else if( hbox
->type
[0] == 3 && hbox
->type
[1] == 1 )
3112 const OUString uStr3
= hstr2OUString(hbox
->str3
.get());
3113 if (uStr3
== "User")
3115 startEl("text:sender-lastname");
3116 chars( hstr2OUString(hbox
->str2
.get()) );
3117 endEl("text:sender-lastname");
3119 else if (uStr3
== "Company")
3121 startEl("text:sender-company");
3122 chars( hstr2OUString(hbox
->str2
.get()) );
3123 endEl("text:sender-company");
3125 else if (uStr3
== "Position")
3127 startEl("text:sender-title");
3128 chars( hstr2OUString(hbox
->str2
.get()) );
3129 endEl("text:sender-title");
3131 else if (uStr3
== "Division")
3133 startEl("text:sender-position");
3134 chars( hstr2OUString(hbox
->str2
.get()) );
3135 endEl("text:sender-position");
3137 else if (uStr3
== "Fax")
3139 startEl("text:sender-fax");
3140 chars( hstr2OUString(hbox
->str2
.get()) );
3141 endEl("text:sender-fax");
3143 else if (uStr3
== "Pager")
3145 startEl("text:phone-private");
3146 chars( hstr2OUString(hbox
->str2
.get()) );
3147 endEl("text:phone-private");
3149 else if (uStr3
== "E-mail")
3151 startEl("text:sender-email");
3152 chars( hstr2OUString(hbox
->str2
.get()) );
3153 endEl("text:sender-email");
3155 else if (uStr3
== "Zipcode(office)")
3157 startEl("text:sender-postal-code");
3158 chars( hstr2OUString(hbox
->str2
.get()) );
3159 endEl("text:sender-postal-code");
3161 else if (uStr3
== "Phone(office)")
3163 startEl("text:sender-phone-work");
3164 chars( hstr2OUString(hbox
->str2
.get()) );
3165 endEl("text:sender-phone-work");
3167 else if (uStr3
== "Address(office)")
3169 startEl("text:sender-street");
3170 chars( hstr2OUString(hbox
->str2
.get()) );
3171 endEl("text:sender-street");
3175 else if( hbox
->type
[0] == 3 && hbox
->type
[1] == 2 ) /* creation date */
3178 mxList
->addAttribute("style:data-style-name", sXML_CDATA
, "N" + OUString::number(hbox
->m_pDate
->key
));
3179 startEl("text:creation-date");
3181 chars( hstr2OUString(hbox
->str2
.get()) );
3182 endEl("text:creation-date");
3189 * In LibreOffice, refer bookmarks as reference, but hwp doesn't have the sort of feature.
3191 void HwpReader::makeBookmark(Bookmark
const * hbox
)
3193 if (hbox
->type
== 0)
3195 mxList
->addAttribute("text:name", sXML_CDATA
, hstr2OUString(hbox
->id
));
3196 startEl("text:bookmark");
3198 endEl("text:bookmark");
3200 else if (hbox
->type
== 1) /* Block bookmarks days begin and end there if */
3202 mxList
->addAttribute("text:name", sXML_CDATA
, hstr2OUString(hbox
->id
));
3203 startEl("text:bookmark-start");
3205 endEl("text:bookmark-start");
3207 else if (hbox
->type
== 2)
3209 mxList
->addAttribute("text:name", sXML_CDATA
, hstr2OUString(hbox
->id
));
3210 startEl("text:bookmark-end");
3212 endEl("text:bookmark-end");
3217 void HwpReader::makeDateFormat(DateCode
* hbox
)
3219 mxList
->addAttribute("style:name", sXML_CDATA
, "N" + OUString::number(hbox
->key
));
3220 mxList
->addAttribute("style:family", sXML_CDATA
,"data-style");
3221 mxList
->addAttribute("number:language", sXML_CDATA
,"ko");
3222 mxList
->addAttribute("number:country", sXML_CDATA
,"KR");
3224 startEl("number:date-style");
3227 bool add_zero
= false;
3229 hbox
->format
[DATE_SIZE
-1] = 0;
3231 const hchar
*fmt
= hbox
->format
[0] ? hbox
->format
: defaultform
;
3233 for( ; *fmt
; fmt
++ )
3235 if( zero_check
== 1 )
3249 mxList
->addAttribute("number:style", sXML_CDATA
, "long");
3250 startEl("number:year");
3252 endEl("number:year");
3255 startEl("number:year");
3257 endEl("number:year");
3261 mxList
->addAttribute("number:style", sXML_CDATA
, "long");
3262 startEl("number:month");
3264 endEl("number:month");
3267 mxList
->addAttribute("number:textual", sXML_CDATA
, "true");
3268 startEl("number:month");
3270 endEl("number:month");
3273 mxList
->addAttribute("number:textual", sXML_CDATA
, "true");
3274 mxList
->addAttribute("number:style", sXML_CDATA
, "long");
3275 startEl("number:month");
3277 endEl("number:month");
3281 mxList
->addAttribute("number:style", sXML_CDATA
, "long");
3282 startEl("number:day");
3284 endEl("number:day");
3288 mxList
->addAttribute("number:style", sXML_CDATA
, "long");
3289 startEl("number:day");
3291 endEl("number:day");
3292 switch( hbox
->date
[DateCode::DAY
] % 10)
3295 startEl("number:text");
3297 endEl("number:text");
3300 startEl("number:text");
3302 endEl("number:text");
3305 startEl("number:text");
3307 endEl("number:text");
3310 startEl("number:text");
3312 endEl("number:text");
3319 mxList
->addAttribute("number:style", sXML_CDATA
, "long");
3320 startEl("number:hours");
3322 endEl("number:hours");
3327 mxList
->addAttribute("number:style", sXML_CDATA
, "long");
3328 startEl("number:minutes");
3330 endEl("number:minutes");
3333 mxList
->addAttribute("number:style", sXML_CDATA
, "long");
3337 startEl("number:day-of-week");
3339 endEl("number:day-of-week");
3344 startEl("number:am-pm");
3346 endEl("number:am-pm");
3348 case '~': // Chinese Locale
3354 startEl("number:text");
3355 chars(hstr2OUString(sbuf
));
3356 endEl("number:text");
3361 endEl("number:date-style");
3365 void HwpReader::makeDateCode(DateCode
* hbox
)
3367 mxList
->addAttribute("style:data-style-name", sXML_CDATA
, "N" + OUString::number(hbox
->key
));
3368 startEl("text:date");
3370 hchar_string
const boxstr
= hbox
->GetString();
3371 chars(hstr2OUString(boxstr
.c_str()));
3376 void HwpReader::makeTab()
3378 startEl("text:tab-stop");
3379 endEl("text:tab-stop");
3383 void HwpReader::makeTable(TxtBox
* hbox
)
3385 mxList
->addAttribute("table:name", sXML_CDATA
, "Table" + OUString::number(hbox
->style
.boxnum
));
3386 mxList
->addAttribute("table:style-name", sXML_CDATA
, "Table" + OUString::number(hbox
->style
.boxnum
));
3387 startEl("table:table");
3390 Table
*tbl
= hbox
->m_pTable
;
3392 for (size_t i
= 0 ; i
< tbl
->columns
.nCount
-1 ; i
++)
3394 mxList
->addAttribute(
3395 "table:style-name", sXML_CDATA
,
3396 "Table" + OUString::number(hbox
->style
.boxnum
) + "."
3397 + OUStringChar(static_cast<char>('A'+i
)));
3398 startEl("table:table-column");
3400 endEl("table:table-column");
3405 for (auto const& tcell
: tbl
->cells
)
3407 if( tcell
->nRowIndex
> j
)
3411 endEl("table:table-row");
3415 mxList
->addAttribute(
3416 "table:style-name", sXML_CDATA
,
3417 "Table" + OUString::number(hbox
->style
.boxnum
) + ".row"
3418 + OUString::number(tcell
->nRowIndex
+ 1));
3419 startEl("table:table-row");
3421 j
= tcell
->nRowIndex
;
3424 mxList
->addAttribute(
3425 "table:style-name", sXML_CDATA
,
3426 "Table" + OUString::number(hbox
->style
.boxnum
) + "."
3427 + OUStringChar(char('A'+ tcell
->nColumnIndex
))
3428 + OUString::number(tcell
->nRowIndex
+1));
3429 if( tcell
->nColumnSpan
> 1 )
3430 mxList
->addAttribute("table:number-columns-spanned", sXML_CDATA
, OUString::number(tcell
->nColumnSpan
));
3431 if( tcell
->nRowSpan
> 1 )
3432 mxList
->addAttribute("table:number-rows-spanned", sXML_CDATA
, OUString::number(tcell
->nRowSpan
));
3433 mxList
->addAttribute("table:value-type", sXML_CDATA
,"string");
3434 if( tcell
->pCell
->protect
)
3435 mxList
->addAttribute("table:protected", sXML_CDATA
,"true");
3436 startEl("table:table-cell");
3438 TxtBox::plist_t
& rVec
= hbox
->plists
[tcell
->pCell
->key
];
3440 parsePara(rVec
.front().get());
3441 endEl("table:table-cell");
3443 endEl("table:table-row");
3444 endEl("table:table");
3449 * Parses the text boxes and tables.
3450 * 1. draw: style-name, draw: name, text: anchor-type, svg: width,
3451 * Fo: min-height, svg: x, svg: y
3452 * TODO: fo:background-color <= no idea whether the value of color setting->style is in it or not
3454 void HwpReader::makeTextBox(TxtBox
* hbox
)
3456 if( hbox
->style
.cap_len
> 0 && hbox
->type
== TXT_TYPE
)
3458 mxList
->addAttribute("draw:style-name", sXML_CDATA
, "CapBox" + OUString::number(hbox
->style
.boxnum
));
3459 mxList
->addAttribute("draw:name", sXML_CDATA
, "CaptionBox" + OUString::number(hbox
->style
.boxnum
));
3460 mxList
->addAttribute("draw:z-index", sXML_CDATA
, OUString::number(hbox
->zorder
));
3461 switch (hbox
->style
.anchor_type
)
3464 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "as-char");
3467 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "paragraph");
3472 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "page");
3473 mxList
->addAttribute("text:anchor-page-number", sXML_CDATA
, OUString::number(hbox
->pgno
+ 1));
3477 if (hbox
->style
.anchor_type
!= CHAR_ANCHOR
)
3479 mxList
->addAttribute("svg:x", sXML_CDATA
,
3480 OUString::number(WTMM( hbox
->pgx
+ hbox
->style
.margin
[0][0] )) + "mm");
3481 mxList
->addAttribute("svg:y", sXML_CDATA
,
3482 OUString::number(WTMM( hbox
->pgy
+ hbox
->style
.margin
[0][2] )) + "mm");
3484 mxList
->addAttribute("svg:width", sXML_CDATA
,
3485 OUString::number(WTMM( hbox
->box_xs
+ hbox
->cap_xs
)) + "mm");
3486 mxList
->addAttribute("fo:min-height", sXML_CDATA
,
3487 OUString::number(WTMM( hbox
->box_ys
+ hbox
->cap_ys
)) + "mm");
3488 startEl("draw:text-box");
3490 if (!hbox
->caption
.empty() && hbox
->cap_pos
% 2) /* The caption is on the top */
3492 parsePara(hbox
->caption
.front().get());
3494 mxList
->addAttribute( "text:style-name", sXML_CDATA
, "Standard");
3499 mxList
->addAttribute("draw:z-index", sXML_CDATA
, OUString::number(hbox
->zorder
));
3502 mxList
->addAttribute("draw:style-name", sXML_CDATA
, "Txtbox" + OUString::number(hbox
->style
.boxnum
));
3503 mxList
->addAttribute("draw:name", sXML_CDATA
, "Frame" + OUString::number(hbox
->style
.boxnum
));
3505 if( hbox
->style
.cap_len
<= 0 || hbox
->type
!= TXT_TYPE
)
3509 switch (hbox
->style
.anchor_type
)
3512 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "as-char");
3515 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "paragraph");
3520 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "page");
3521 mxList
->addAttribute("text:anchor-page-number", sXML_CDATA
, OUString::number(hbox
->pgno
+ 1));
3525 if( hbox
->style
.anchor_type
!= CHAR_ANCHOR
)
3527 x
+= hbox
->style
.margin
[0][0];
3528 y
+= hbox
->style
.margin
[0][2];
3530 mxList
->addAttribute("svg:x", sXML_CDATA
,
3531 OUString::number(WTMM( hbox
->pgx
+ x
)) + "mm");
3532 mxList
->addAttribute("svg:y", sXML_CDATA
,
3533 OUString::number(WTMM( hbox
->pgy
+ y
)) + "mm");
3537 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "as-char");
3538 mxList
->addAttribute("svg:y", sXML_CDATA
, "0cm");
3540 mxList
->addAttribute("svg:width", sXML_CDATA
,
3541 OUString::number(WTMM( hbox
->box_xs
)) + "mm");
3542 if( hbox
->style
.cap_len
> 0 && hbox
->type
!= TXT_TYPE
)
3543 mxList
->addAttribute("fo:min-height", sXML_CDATA
,
3544 OUString::number(WTMM( hbox
->box_ys
+ hbox
->cap_ys
)) + "mm");
3546 mxList
->addAttribute("svg:height", sXML_CDATA
,
3547 OUString::number(WTMM(hbox
->box_ys
)) + "mm");
3549 if( hbox
->type
!= EQU_TYPE
)
3551 startEl("draw:text-box");
3553 /* If captions are present and it is on the top */
3554 if (hbox
->style
.cap_len
> 0 && (hbox
->cap_pos
% 2) && hbox
->type
== TBL_TYPE
&& !hbox
->caption
.empty())
3556 parsePara(hbox
->caption
.front().get());
3558 if( hbox
->type
== TBL_TYPE
) // Is Table
3562 else if (!hbox
->plists
[0].empty()) // Is TextBox
3564 parsePara(hbox
->plists
[0].front().get());
3566 /* If captions are present and it is on the bottom */
3567 if (hbox
->style
.cap_len
> 0 && !(hbox
->cap_pos
% 2) && hbox
->type
== TBL_TYPE
&& !hbox
->caption
.empty())
3569 parsePara(hbox
->caption
.front().get());
3571 endEl("draw:text-box");
3572 // Caption exist and it is text-box
3573 if( hbox
->style
.cap_len
> 0 && hbox
->type
== TXT_TYPE
)
3576 if (!(hbox
->cap_pos
% 2) && !hbox
->caption
.empty())
3578 parsePara(hbox
->caption
.front().get());
3580 endEl("draw:text-box");
3585 startEl("draw:object");
3588 endEl("draw:object");
3594 * It must be converted into MathML.
3597 void HwpReader::makeFormula(TxtBox
* hbox
)
3605 pPar
= hbox
->plists
[0].empty() ? nullptr : hbox
->plists
[0].front().get();
3608 for (const auto& box
: pPar
->hhstr
)
3613 if (l
>= sizeof(mybuf
)-7)
3615 int res
= hcharconv(box
->hh
, dest
, UNICODE
);
3616 for( int j
= 0 ; j
< res
; j
++ ){
3621 mybuf
[l
++] = sal::static_int_cast
<char>(c
);
3624 mybuf
[l
++] = sal::static_int_cast
<char>((c
>> 8) & 0xff);
3625 mybuf
[l
++] = sal::static_int_cast
<char>(c
& 0xff);
3629 if (l
>= sizeof(mybuf
)-7)
3632 pPar
= pPar
->Next();
3636 Formula
form( mybuf
);
3637 form
.setDocumentHandler(m_rxDocumentHandler
);
3638 form
.setAttributeListImpl(mxList
.get());
3643 * Read the platform information. if the platform is Linux or Solaris, it needs to change
3644 * C: \ => Home, D: \ => changed to root (/). Because HWP uses DOS emulator.
3647 void HwpReader::makeHyperText(TxtBox
* hbox
)
3649 HyperText
*hypert
= hwpfile
.GetHyperText();
3650 if( !hypert
) return;
3652 if (hypert
->filename
[0] != '\0') {
3653 ::std::string
const tmp
= hstr2ksstr(hypert
->bookmark
);
3654 ::std::string
const tmp2
= hstr2ksstr(kstr2hstr(
3656 reinterpret_cast<uchar
const *>(urltowin(reinterpret_cast<char *>(hypert
->filename
)).c_str())).c_str());
3658 reinterpret_cast<uchar
const *>(urltounix(reinterpret_cast<char *>(hypert
->filename
)).c_str())).c_str());
3660 mxList
->addAttribute("xlink:type", sXML_CDATA
, "simple");
3661 if (!tmp
.empty() && strcmp(tmp
.c_str(), "[HTML]")) {
3662 ::std::string
tmp3(tmp2
);
3663 tmp3
.push_back('#');
3665 mxList
->addAttribute("xlink:href", sXML_CDATA
,
3666 OUString(tmp3
.c_str(), tmp3
.size()+1, RTL_TEXTENCODING_EUC_KR
));
3669 mxList
->addAttribute("xlink:href", sXML_CDATA
,
3670 OUString(tmp2
.c_str(), tmp2
.size()+1, RTL_TEXTENCODING_EUC_KR
));
3676 mxList
->addAttribute("xlink:type", sXML_CDATA
, "simple");
3679 tmp
.append(hstr2ksstr(hypert
->bookmark
));
3680 mxList
->addAttribute("xlink:href", sXML_CDATA
,
3681 OUString(tmp
.c_str(), tmp
.size()+1, RTL_TEXTENCODING_EUC_KR
));
3691 * Read the platform information. if the platform is Linux or Solaris, it needs to change
3692 * C: \ => Home, D: \ => changed to root (/). Because HWP uses DOS emulator.
3695 void HwpReader::makePicture(Picture
* hbox
)
3697 switch (hbox
->pictype
)
3703 if( hbox
->style
.cap_len
> 0 )
3705 mxList
->addAttribute("draw:style-name", sXML_CDATA
,
3706 "CapBox" + OUString::number(hbox
->style
.boxnum
));
3707 mxList
->addAttribute("draw:name", sXML_CDATA
, "CaptionBox" + OUString::number(hbox
->style
.boxnum
));
3708 mxList
->addAttribute("draw:z-index", sXML_CDATA
, OUString::number(hbox
->zorder
));
3709 switch (hbox
->style
.anchor_type
)
3712 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "as-char");
3715 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "paragraph");
3720 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "page");
3721 mxList
->addAttribute("text:anchor-page-number", sXML_CDATA
,
3722 OUString::number(hbox
->pgno
+ 1));
3726 if (hbox
->style
.anchor_type
!= CHAR_ANCHOR
)
3728 mxList
->addAttribute("svg:x", sXML_CDATA
,
3729 OUString::number(WTMM( hbox
->pgx
+ hbox
->style
.margin
[0][0] )) + "mm");
3730 mxList
->addAttribute("svg:y", sXML_CDATA
,
3731 OUString::number(WTMM( hbox
->pgy
+ hbox
->style
.margin
[0][2] )) + "mm");
3733 mxList
->addAttribute("svg:width", sXML_CDATA
,
3734 OUString::number(WTMM( hbox
->box_xs
+ hbox
->style
.margin
[1][0] + hbox
->style
.margin
[1][1] )) + "mm");
3735 mxList
->addAttribute("fo:min-height", sXML_CDATA
,
3736 OUString::number(WTMM( hbox
->box_ys
+ hbox
->style
.margin
[1][2] + hbox
->style
.margin
[1][3] + hbox
->cap_ys
)) + "mm");
3737 startEl("draw:text-box");
3739 if (!hbox
->caption
.empty() && hbox
->cap_pos
% 2) /* Caption is on the top */
3741 parsePara(hbox
->caption
.front().get());
3743 mxList
->addAttribute( "text:style-name", sXML_CDATA
, "Standard");
3749 mxList
->addAttribute("xlink:type", sXML_CDATA
, "simple");
3751 if( hbox
->follow
[4] != 0 )
3752 mxList
->addAttribute("xlink:href", sXML_CDATA
, hstr2OUString(kstr2hstr(hbox
->follow
.data() + 4).c_str()));
3754 mxList
->addAttribute("xlink:href", sXML_CDATA
, hstr2OUString(kstr2hstr(hbox
->follow
.data() + 5).c_str()));
3756 if( hbox
->follow
[4] != 0 )
3757 mxList
->addAttribute("xlink:href", sXML_CDATA
,
3758 hstr2OUString(kstr2hstr(reinterpret_cast<uchar
const *>(urltounix(reinterpret_cast<char *>(hbox
->follow
.data() + 4)).c_str())).c_str()));
3760 mxList
->addAttribute("xlink:href", sXML_CDATA
,
3761 hstr2OUString(kstr2hstr(reinterpret_cast<uchar
const *>(urltounix(reinterpret_cast<char *>(hbox
->follow
.data() + 5)).c_str())).c_str()));
3766 mxList
->addAttribute("draw:style-name", sXML_CDATA
, "G" + OUString::number(hbox
->style
.boxnum
));
3767 mxList
->addAttribute("draw:name", sXML_CDATA
, "Image" + OUString::number(hbox
->style
.boxnum
));
3769 if( hbox
->style
.cap_len
<= 0 )
3771 mxList
->addAttribute("draw:z-index", sXML_CDATA
, OUString::number(hbox
->zorder
));
3772 switch (hbox
->style
.anchor_type
)
3775 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "as-char");
3778 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "paragraph");
3783 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "page");
3784 mxList
->addAttribute("text:anchor-page-number", sXML_CDATA
,
3785 OUString::number(hbox
->pgno
+ 1));
3789 if (hbox
->style
.anchor_type
!= CHAR_ANCHOR
)
3791 mxList
->addAttribute("svg:x", sXML_CDATA
,
3792 OUString::number(WTMM( hbox
->pgx
+ hbox
->style
.margin
[0][0] )) + "mm");
3793 mxList
->addAttribute("svg:y", sXML_CDATA
,
3794 OUString::number(WTMM( hbox
->pgy
+ hbox
->style
.margin
[0][2] )) + "mm");
3799 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "as-char");
3800 mxList
->addAttribute("svg:y", sXML_CDATA
, "0cm");
3802 mxList
->addAttribute("svg:width", sXML_CDATA
,
3803 OUString::number(WTMM( hbox
->box_xs
+ hbox
->style
.margin
[1][0] + hbox
->style
.margin
[1][1])) + "mm");
3804 mxList
->addAttribute("svg:height", sXML_CDATA
,
3805 OUString::number(WTMM( hbox
->box_ys
+ hbox
->style
.margin
[1][2] + hbox
->style
.margin
[1][3])) + "mm");
3807 if ( hbox
->pictype
== PICTYPE_FILE
){
3809 sprintf(d
->buf
, "file:///%s", hbox
->picinfo
.picun
.path
);
3810 mxList
->addAttribute("xlink:href", sXML_CDATA
, hstr2OUString(kstr2hstr(reinterpret_cast<uchar
*>(d
->buf
)).c_str()));
3812 mxList
->addAttribute("xlink:href", sXML_CDATA
,
3813 hstr2OUString(kstr2hstr(reinterpret_cast<uchar
const *>(urltounix(hbox
->picinfo
.picun
.path
).c_str())).c_str()));
3815 mxList
->addAttribute("xlink:type", sXML_CDATA
, "simple");
3816 mxList
->addAttribute("xlink:show", sXML_CDATA
, "embed");
3817 mxList
->addAttribute("xlink:actuate", sXML_CDATA
, "onLoad");
3820 if( hbox
->pictype
== PICTYPE_OLE
)
3821 startEl("draw:object-ole");
3823 startEl("draw:image");
3825 if (hbox
->pictype
== PICTYPE_EMBED
|| hbox
->pictype
== PICTYPE_OLE
)
3827 startEl("office:binary-data");
3829 if( hbox
->pictype
== PICTYPE_EMBED
){
3830 EmPicture
*emp
= hwpfile
.GetEmPicture(hbox
);
3833 chars(base64_encode_string(emp
->data
.data(), emp
->size
));
3837 if( hwpfile
.oledata
){
3841 wchar_t pathname
[200];
3843 MultiByteToWideChar(CP_ACP
, 0, hbox
->picinfo
.picole
.embname
, -1, pathname
, 200);
3844 int rc
= hwpfile
.oledata
->pis
->OpenStorage(pathname
, nullptr,
3845 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_TRANSACTED
, nullptr, 0, &srcsto
);
3850 rc
= OleLoad(srcsto
, IID_IUnknown
, nullptr, reinterpret_cast<LPVOID
*>(&pObj
));
3856 chars(base64_encode_string(reinterpret_cast<uchar
*>(pObj
), strlen(reinterpret_cast<char*>(pObj
))));
3866 endEl("office:binary-data");
3868 if( hbox
->pictype
== PICTYPE_OLE
)
3869 endEl("draw:object-ole");
3871 endEl("draw:image");
3876 if( hbox
->style
.cap_len
> 0 )
3879 if (!hbox
->caption
.empty() && !(hbox
->cap_pos
% 2)) /* Caption is at the bottom, */
3881 parsePara(hbox
->caption
.front().get());
3883 endEl("draw:text-box");
3888 if( hbox
->picinfo
.picdraw
.zorder
> 0 )
3889 mxList
->addAttribute("draw:z-index", sXML_CDATA
,
3890 OUString::number(hbox
->picinfo
.picdraw
.zorder
+ 10000));
3891 makePictureDRAW(hbox
->picinfo
.picdraw
.hdo
, hbox
);
3893 case PICTYPE_UNKNOWN
:
3898 void HwpReader::makePictureDRAW(HWPDrawingObject
*drawobj
, const Picture
* hbox
)
3900 bool bIsRotate
= false;
3904 mxList
->addAttribute("draw:style-name", sXML_CDATA
, "Draw" + OUString::number(drawobj
->index
));
3908 switch (hbox
->style
.anchor_type
)
3911 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "as-char");
3914 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "paragraph");
3919 HWPInfo
& hwpinfo
= hwpfile
.GetHWPInfo();
3920 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "page");
3921 mxList
->addAttribute("text:anchor-page-number", sXML_CDATA
, OUString::number(hbox
->pgno
+ 1));
3922 a
= hwpinfo
.paper
.left_margin
;
3923 b
= hwpinfo
.paper
.top_margin
+ hwpinfo
.paper
.header_length
;
3928 if (drawobj
->type
== HWPDO_CONTAINER
)
3932 makePictureDRAW(drawobj
->child
.get(), hbox
);
3937 double x
= hbox
->pgx
;
3938 double y
= hbox
->pgy
;
3941 if( (drawobj
->property
.flag
& HWPDO_FLAG_ROTATION
) &&
3942 (drawobj
->property
.parall
.pt
[0].y
!= drawobj
->property
.parall
.pt
[1].y
) &&
3943 //(drawobj->type == HWPDO_RECT || drawobj->type == HWPDO_ADVANCED_ELLIPSE || drawobj->type == HWPDO_ADVANCED_ARC )
3944 (drawobj
->type
== HWPDO_RECT
|| drawobj
->type
== HWPDO_ADVANCED_ELLIPSE
)
3949 ZZParall
& pal
= drawobj
->property
.parall
;
3951 basegfx::B2DPoint pt
[3], r_pt
[3];
3952 for(i
= 0 ; i
< 3 ; i
++ ){
3953 basegfx::B2DPoint
rot_origin(drawobj
->property
.rot_originx
, drawobj
->property
.rot_originy
);
3954 pt
[i
].setX(pal
.pt
[i
].x
- rot_origin
.getX());
3955 /* Convert to a physical coordinate */
3956 pt
[i
].setY(-(pal
.pt
[i
].y
- rot_origin
.getY()));
3961 /* 2 - rotation angle calculation */
3962 double rotate
= atan2(pt
[1].getY() - pt
[0].getY(), pt
[1].getX() - pt
[0].getX());
3964 for( i
= 0 ; i
< 3 ; i
++){
3965 r_pt
[i
].setX(pt
[i
].getX() * cos(-rotate
) - pt
[i
].getY() * sin(-rotate
));
3966 r_pt
[i
].setY(pt
[i
].getY() * cos(-rotate
) + pt
[i
].getX() * sin(-rotate
));
3969 /* 4 - Calculation of reflex angle */
3970 if (r_pt
[2].getY() == r_pt
[1].getY())
3973 skewX
= atan((r_pt
[2].getX() - r_pt
[1].getX()) / (r_pt
[2].getY() - r_pt
[1].getY()));
3974 if( skewX
>= M_PI_2
)
3976 if( skewX
<= -M_PI_2
)
3980 if( skewX
!= 0.0 && rotate
!= 0.0 ){
3981 trans
= "skewX (" + OUString::number(skewX
)
3982 + ") rotate (" + OUString::number(rotate
)
3983 + ") translate (" + OUString::number(WTMM(x
+ a
+ drawobj
->offset2
.x
+ pal
.pt
[0].x
)) + "mm "
3984 + OUString::number(WTMM(y
+ b
+ drawobj
->offset2
.y
+ pal
.pt
[0].y
)) + "mm)";
3987 else if( skewX
!= 0.0 ){
3988 trans
= "skewX (" + OUString::number(skewX
)
3989 + ") translate (" + OUString::number(WTMM(x
+ a
+ drawobj
->offset2
.x
+ pal
.pt
[0].x
)) + "mm "
3990 + OUString::number(WTMM(y
+ b
+ drawobj
->offset2
.y
+ pal
.pt
[0].y
)) + "mm)";
3993 else if( rotate
!= 0.0 ){
3994 trans
= "rotate (" + OUString::number(rotate
)
3995 + ") translate (" + OUString::number(WTMM(x
+ a
+ drawobj
->offset2
.x
+ pal
.pt
[0].x
)) + "mm "
3996 + OUString::number(WTMM(y
+ b
+ drawobj
->offset2
.y
+ pal
.pt
[0].y
)) + "mm)";
4000 drawobj
->extent
.w
= static_cast<int>(std::hypot(pt
[1].getX() - pt
[0].getX(), pt
[1].getY() - pt
[0].getY()));
4001 drawobj
->extent
.h
= static_cast<int>(std::hypot(pt
[2].getX() - pt
[1].getX(), pt
[2].getY() - pt
[1].getY()));
4002 mxList
->addAttribute("draw:transform", sXML_CDATA
, trans
);
4005 switch (drawobj
->type
)
4007 case HWPDO_LINE
: /* Line-starting coordinates, ending coordinates. */
4008 if( drawobj
->u
.line_arc
.flip
& 0x01 )
4010 mxList
->addAttribute("svg:x1", sXML_CDATA
,
4011 OUString::number (WTMM(x
+ a
+ drawobj
->offset2
.x
+ drawobj
->extent
.w
)) + "mm");
4012 mxList
->addAttribute("svg:x2", sXML_CDATA
,
4013 OUString::number (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4017 mxList
->addAttribute("svg:x1", sXML_CDATA
,
4018 OUString::number (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4019 mxList
->addAttribute("svg:x2", sXML_CDATA
,
4020 OUString::number (WTMM(x
+ a
+ drawobj
->offset2
.x
+ drawobj
->extent
.w
)) + "mm");
4022 if( drawobj
->u
.line_arc
.flip
& 0x02 )
4024 mxList
->addAttribute("svg:y1", sXML_CDATA
,
4025 OUString::number (WTMM( y
+ b
+ drawobj
->offset2
.y
+ drawobj
->extent
.h
) ) + "mm");
4026 mxList
->addAttribute("svg:y2", sXML_CDATA
,
4027 OUString::number (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4031 mxList
->addAttribute("svg:y1", sXML_CDATA
,
4032 OUString::number (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4033 mxList
->addAttribute("svg:y2", sXML_CDATA
,
4034 OUString::number (WTMM(y
+ b
+ drawobj
->offset2
.y
+ drawobj
->extent
.h
)) + "mm");
4037 startEl("draw:line");
4041 case HWPDO_RECT
: /* rectangle - the starting position, vertical/horizontal */
4044 mxList
->addAttribute("svg:x", sXML_CDATA
,
4045 OUString::number (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4046 mxList
->addAttribute("svg:y", sXML_CDATA
,
4047 OUString::number (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4049 mxList
->addAttribute("svg:width", sXML_CDATA
,
4050 OUString::number (WTMM( drawobj
->extent
.w
)) + "mm");
4051 mxList
->addAttribute("svg:height", sXML_CDATA
,
4052 OUString::number (WTMM( drawobj
->extent
.h
)) + "mm");
4053 if( drawobj
->property
.flag
& 0x01 )
4055 int value
= drawobj
->extent
.w
< drawobj
->extent
.h
?
4056 drawobj
->extent
.w
: drawobj
->extent
.h
;
4057 mxList
->addAttribute("draw:corner-radius", sXML_CDATA
,
4058 OUString::number (WTMM( value
/10 )) + "mm");
4060 else if( drawobj
->property
.flag
& 0x04 )
4062 int value
= drawobj
->extent
.w
< drawobj
->extent
.h
?
4063 drawobj
->extent
.w
: drawobj
->extent
.h
;
4064 mxList
->addAttribute("draw:corner-radius", sXML_CDATA
,
4065 OUString::number (WTMM( value
/ 2)) + "mm");
4068 startEl("draw:rect");
4070 if( (drawobj
->property
.flag
& HWPDO_FLAG_AS_TEXTBOX
) &&
4071 drawobj
->property
.pPara
) // As Textbox
4073 HWPPara
*pPara
= drawobj
->property
.pPara
;
4077 make_text_p1( pPara
, false );
4078 pPara
= pPara
->Next();
4083 case HWPDO_ELLIPSE
: /* Ellipse - the starting position, vertical/horizontal */
4084 case HWPDO_ADVANCED_ELLIPSE
: /* modified ellipse */
4088 mxList
->addAttribute("svg:x", sXML_CDATA
,
4089 OUString::number (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4090 mxList
->addAttribute("svg:y", sXML_CDATA
,
4091 OUString::number (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4094 mxList
->addAttribute("svg:width", sXML_CDATA
,
4095 OUString::number (WTMM( drawobj
->extent
.w
)) + "mm");
4096 mxList
->addAttribute("svg:height", sXML_CDATA
,
4097 OUString::number (WTMM( drawobj
->extent
.h
)) + "mm");
4098 if( drawobj
->type
== HWPDO_ADVANCED_ELLIPSE
){
4099 if (drawobj
->u
.arc
.radial
[0].x
!= drawobj
->u
.arc
.radial
[1].x
||
4100 drawobj
->u
.arc
.radial
[0].y
!= drawobj
->u
.arc
.radial
[1].y
) {
4103 if (!o3tl::checked_add(drawobj
->offset2
.x
, drawobj
->extent
.w
, Cx
) &&
4104 !o3tl::checked_add(drawobj
->offset2
.y
, drawobj
->extent
.h
, Cy
))
4109 double start_angle
= calcAngle( Cx
, Cy
, drawobj
->u
.arc
.radial
[0].x
, drawobj
->u
.arc
.radial
[0].y
);
4110 double end_angle
= calcAngle( Cx
, Cy
, drawobj
->u
.arc
.radial
[1].x
, drawobj
->u
.arc
.radial
[1].y
);
4111 if( drawobj
->property
.fill_color
< 0xffffff )
4112 mxList
->addAttribute("draw:kind", sXML_CDATA
, "section");
4114 mxList
->addAttribute("draw:kind", sXML_CDATA
, "arc");
4115 mxList
->addAttribute("draw:start-angle", sXML_CDATA
, OUString::number(start_angle
));
4116 mxList
->addAttribute("draw:end-angle", sXML_CDATA
, OUString::number(end_angle
));
4120 startEl("draw:ellipse");
4122 if( drawobj
->property
.flag
>> 19 & 0x01 &&
4123 drawobj
->property
.pPara
) // As Textbox
4125 HWPPara
*pPara
= drawobj
->property
.pPara
;
4129 make_text_p1( pPara
, false );
4130 pPara
= pPara
->Next();
4133 endEl("draw:ellipse");
4137 case HWPDO_ARC
: /* Arc */
4138 case HWPDO_ADVANCED_ARC
:
4140 /* If it is the arc, LibreOffice assumes the size as the entire ellipse size */
4141 uint flip
= drawobj
->u
.line_arc
.flip
;
4144 if( ( flip
== 0 || flip
== 2 ) && drawobj
->type
== HWPDO_ARC
)
4145 mxList
->addAttribute("svg:x", sXML_CDATA
,
4146 OUString::number (WTMM( x
+ a
+ drawobj
->offset2
.x
- drawobj
->extent
.w
)) + "mm");
4148 mxList
->addAttribute("svg:x", sXML_CDATA
,
4149 OUString::number (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4150 if( ( flip
== 0 || flip
== 1 ) && drawobj
->type
== HWPDO_ARC
)
4151 mxList
->addAttribute("svg:y", sXML_CDATA
,
4152 OUString::number (WTMM( y
+ b
+ drawobj
->offset2
.y
- drawobj
->extent
.h
)) + "mm");
4154 mxList
->addAttribute("svg:y", sXML_CDATA
,
4155 OUString::number (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4158 mxList
->addAttribute("svg:width", sXML_CDATA
,
4159 OUString::number (WTMM( drawobj
->extent
.w
* 2)) + "mm");
4160 mxList
->addAttribute("svg:height", sXML_CDATA
,
4161 OUString::number (WTMM( drawobj
->extent
.h
* 2)) + "mm");
4162 if( drawobj
->property
.flag
& HWPDO_FLAG_DRAW_PIE
||
4163 drawobj
->property
.fill_color
< 0xffffff )
4164 mxList
->addAttribute("draw:kind", sXML_CDATA
, "section");
4166 mxList
->addAttribute("draw:kind", sXML_CDATA
, "arc");
4168 if( drawobj
->type
== HWPDO_ADVANCED_ARC
){
4169 double start_angle
, end_angle
;
4170 ZZParall
& pal
= drawobj
->property
.parall
;
4172 start_angle
= atan2(pal
.pt
[0].y
- pal
.pt
[1].y
,pal
.pt
[1].x
- pal
.pt
[0].x
);
4173 end_angle
= atan2(pal
.pt
[2].y
- pal
.pt
[1].y
, pal
.pt
[1].x
- pal
.pt
[2].x
);
4175 if( ( start_angle
> end_angle
) && (start_angle
- end_angle
< M_PI
))
4176 std::swap( start_angle
, end_angle
);
4177 mxList
->addAttribute("draw:start-angle", sXML_CDATA
, OUString::number(basegfx::rad2deg(start_angle
)));
4178 mxList
->addAttribute("draw:end-angle", sXML_CDATA
, OUString::number(basegfx::rad2deg(end_angle
)));
4183 if( drawobj
->u
.line_arc
.flip
== 0 )
4185 mxList
->addAttribute("draw:start-angle", sXML_CDATA
, "270");
4186 mxList
->addAttribute("draw:end-angle", sXML_CDATA
, "0");
4188 else if( drawobj
->u
.line_arc
.flip
== 1 )
4190 mxList
->addAttribute("draw:start-angle", sXML_CDATA
, "180");
4191 mxList
->addAttribute("draw:end-angle", sXML_CDATA
, "270");
4193 else if( drawobj
->u
.line_arc
.flip
== 2 )
4195 mxList
->addAttribute("draw:start-angle", sXML_CDATA
, "0");
4196 mxList
->addAttribute("draw:end-angle", sXML_CDATA
, "90");
4200 mxList
->addAttribute("draw:start-angle", sXML_CDATA
, "90");
4201 mxList
->addAttribute("draw:end-angle", sXML_CDATA
, "180");
4204 startEl("draw:ellipse");
4206 if( drawobj
->property
.flag
>> 19 & 0x01 &&
4207 drawobj
->property
.pPara
) // As Textbox
4209 HWPPara
*pPara
= drawobj
->property
.pPara
;
4213 make_text_p1( pPara
, false );
4214 pPara
= pPara
->Next();
4217 endEl("draw:ellipse");
4221 case HWPDO_CURVE
: /* Curve: converts to polygons. */
4223 bool bIsNatural
= true;
4224 if( drawobj
->property
.flag
>> 5 & 0x01){
4229 mxList
->addAttribute("svg:x", sXML_CDATA
,
4230 OUString::number (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4231 mxList
->addAttribute("svg:y", sXML_CDATA
,
4232 OUString::number (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4234 mxList
->addAttribute("svg:width", sXML_CDATA
,
4235 OUString::number (WTMM( drawobj
->extent
.w
)) + "mm");
4236 mxList
->addAttribute("svg:height", sXML_CDATA
,
4237 OUString::number (WTMM( drawobj
->extent
.h
)) + "mm");
4238 mxList
->addAttribute(
4239 "svg:viewBox", sXML_CDATA
,
4240 "0 0 " + OUString::number(WTSM(drawobj
->extent
.w
)) + " "
4241 + OUString::number(WTSM(drawobj
->extent
.h
)));
4243 OUStringBuffer oustr
;
4245 if ((drawobj
->u
.freeform
.npt
> 2) &&
4246 (o3tl::make_unsigned(drawobj
->u
.freeform
.npt
) <
4247 (::std::numeric_limits
<int>::max() / sizeof(double))))
4250 n
= drawobj
->u
.freeform
.npt
;
4252 std::unique_ptr
<double[]> xarr( new double[n
+1] );
4253 std::unique_ptr
<double[]> yarr( new double[n
+1] );
4254 std::unique_ptr
<double[]> tarr( new double[n
+1] );
4256 std::unique_ptr
<double[]> xb
;
4257 std::unique_ptr
<double[]> yb
;
4259 std::unique_ptr
<double[]> carr
;
4260 std::unique_ptr
<double[]> darr
;
4263 for( i
= 0 ; i
< n
; i
++ ){
4264 xarr
[i
] = drawobj
->u
.freeform
.pt
[i
].x
;
4265 yarr
[i
] = drawobj
->u
.freeform
.pt
[i
].y
;
4273 PeriodicSpline(n
, tarr
.get(), xarr
.get(), xb
, carr
, darr
);
4274 // prevent memory leak
4277 PeriodicSpline(n
, tarr
.get(), yarr
.get(), yb
, carr
, darr
);
4280 NaturalSpline(n
, tarr
.get(), xarr
.get(), xb
, carr
, darr
);
4281 // prevent memory leak
4284 NaturalSpline(n
, tarr
.get(), yarr
.get(), yb
, carr
, darr
);
4288 "M" + OUString::number(WTSM(xarr
[0])) + " "
4289 + OUString::number(WTSM(yarr
[0])) + "C"
4290 + OUString::number(WTSM(xarr
[0] + xb
[0]/3)) + " "
4291 + OUString::number(WTSM(yarr
[0] + yb
[0]/3)));
4293 for( i
= 1 ; i
< n
; i
++ ){
4296 " " + OUString::number(WTSM(xarr
[i
] - xb
[i
]/3)) + " "
4297 + OUString::number(WTSM(yarr
[i
] - yb
[i
]/3)) + " "
4298 + OUString::number(WTSM(xarr
[i
])) + " "
4299 + OUString::number(WTSM(yarr
[i
])) + "z");
4303 " " + OUString::number(WTSM(xarr
[i
] - xb
[i
]/3)) + " "
4304 + OUString::number(WTSM(yarr
[i
] - yb
[i
]/3)) + " "
4305 + OUString::number(WTSM(xarr
[i
])) + " "
4306 + OUString::number(WTSM(yarr
[i
])) + " "
4307 + OUString::number(WTSM(xarr
[i
] + xb
[i
]/3)) + " "
4308 + OUString::number(WTSM(yarr
[i
] + yb
[i
]/3)));
4313 mxList
->addAttribute("svg:d", sXML_CDATA
, oustr
.makeStringAndClear());
4315 startEl("draw:path");
4318 if( drawobj
->property
.flag
>> 19 & 0x01 && drawobj
->property
.pPara
)
4320 HWPPara
*pPara
= drawobj
->property
.pPara
;
4323 make_text_p1( pPara
, false );
4324 pPara
= pPara
->Next();
4330 case HWPDO_CLOSED_FREEFORM
:
4331 case HWPDO_FREEFORM
: /* polygon */
4333 bool bIsPolygon
= false;
4335 mxList
->addAttribute("svg:x", sXML_CDATA
,
4336 OUString::number (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4337 mxList
->addAttribute("svg:y", sXML_CDATA
,
4338 OUString::number (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4340 mxList
->addAttribute("svg:width", sXML_CDATA
,
4341 OUString::number (WTMM( drawobj
->extent
.w
)) + "mm");
4342 mxList
->addAttribute("svg:height", sXML_CDATA
,
4343 OUString::number (WTMM( drawobj
->extent
.h
)) + "mm");
4345 mxList
->addAttribute("svg:viewBox", sXML_CDATA
, "0 0 " + OUString::number(WTSM(drawobj
->extent
.w
)) + " " + OUString::number(WTSM(drawobj
->extent
.h
)));
4347 OUStringBuffer oustr
;
4349 if (drawobj
->u
.freeform
.npt
> 0)
4352 OUString::number(WTSM(drawobj
->u
.freeform
.pt
[0].x
)) + ","
4353 + OUString::number(WTSM(drawobj
->u
.freeform
.pt
[0].y
)));
4355 for (i
= 1; i
< drawobj
->u
.freeform
.npt
; i
++)
4358 " " + OUString::number(WTSM(drawobj
->u
.freeform
.pt
[i
].x
)) + ","
4359 + OUString::number(WTSM(drawobj
->u
.freeform
.pt
[i
].y
)));
4361 if( drawobj
->u
.freeform
.pt
[0].x
== drawobj
->u
.freeform
.pt
[i
-1].x
&&
4362 drawobj
->u
.freeform
.pt
[0].y
== drawobj
->u
.freeform
.pt
[i
-1].y
)
4367 mxList
->addAttribute("draw:points", sXML_CDATA
, oustr
.makeStringAndClear());
4369 if( drawobj
->property
.fill_color
<= 0xffffff ||
4370 drawobj
->property
.pattern_type
!= 0)
4377 startEl("draw:polygon");
4379 if( drawobj
->property
.flag
>> 19 & 0x01 &&
4381 drawobj
->property
.pPara
)
4383 HWPPara
*pPara
= drawobj
->property
.pPara
;
4384 // parsePara(pPara);
4387 make_text_p1( pPara
, false );
4388 pPara
= pPara
->Next();
4391 endEl("draw:polygon");
4395 startEl("draw:polyline");
4397 if( drawobj
->property
.flag
>> 19 & 0x01 &&
4399 drawobj
->property
.pPara
)
4401 HWPPara
*pPara
= drawobj
->property
.pPara
;
4405 make_text_p1( pPara
, false );
4406 pPara
= pPara
->Next();
4409 endEl("draw:polyline");
4416 mxList
->addAttribute("svg:x", sXML_CDATA
,
4417 OUString::number (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4418 mxList
->addAttribute("svg:y", sXML_CDATA
,
4419 OUString::number (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4421 mxList
->addAttribute("svg:width", sXML_CDATA
,
4422 OUString::number (WTMM( drawobj
->extent
.w
)) + "mm");
4423 mxList
->addAttribute("svg:height", sXML_CDATA
,
4424 OUString::number (WTMM( drawobj
->extent
.h
)) + "mm");
4425 if( drawobj
->property
.flag
& 0x01 )
4427 int value
= drawobj
->extent
.w
< drawobj
->extent
.h
?
4428 drawobj
->extent
.w
: drawobj
->extent
.h
;
4429 mxList
->addAttribute("draw:corner-radius", sXML_CDATA
,
4430 OUString::number (WTMM( value
/10 )) + "mm");
4432 else if( drawobj
->property
.flag
& 0x04 )
4434 int value
= drawobj
->extent
.w
< drawobj
->extent
.h
?
4435 drawobj
->extent
.w
: drawobj
->extent
.h
;
4436 mxList
->addAttribute("draw:corner-radius", sXML_CDATA
,
4437 OUString::number (WTMM( value
/ 2)) + "mm");
4440 startEl("draw:text-box");
4443 HWPPara
*pPara
= drawobj
->u
.textbox
.h
;
4447 make_text_p1( pPara
, false );
4448 pPara
= pPara
->Next();
4451 endEl("draw:text-box");
4456 drawobj
= drawobj
->next
.get();
4460 void HwpReader::makeLine()
4462 mxList
->addAttribute("text:style-name", sXML_CDATA
, "Horizontal Line");
4468 * Input-comment-hidden description: shows a hidden explanation to the users.
4469 * Parse out only strings, but it may contain paragraphs.
4471 void HwpReader::makeHidden(Hidden
* hbox
)
4477 mxList
->addAttribute("text:condition", sXML_CDATA
, "");
4478 mxList
->addAttribute("text:string-value", sXML_CDATA
, "");
4479 startEl("text:hidden-text");
4481 HWPPara
*para
= !hbox
->plist
.empty() ? hbox
->plist
.front().get() : nullptr;
4485 for (const auto& box
: para
->hhstr
)
4490 res
= hcharconv(box
->hh
, dest
, UNICODE
);
4491 for( int j
= 0 ; j
< res
; j
++ )
4493 str
.push_back(dest
[j
]);
4496 para
= para
->Next();
4499 endEl("text:hidden-text");
4504 * Converts footnote to text:footnote, endnote to text:endnote
4506 void HwpReader::makeFootnote(Footnote
* hbox
)
4510 mxList
->addAttribute("text:id", sXML_CDATA
, "edn" + OUString::number(hbox
->number
));
4511 startEl("text:endnote");
4513 mxList
->addAttribute("text:label", sXML_CDATA
, OUString::number(hbox
->number
));
4514 startEl("text:endnote-citation");
4516 chars(OUString::number(hbox
->number
));
4517 endEl("text:endnote-citation");
4518 startEl("text:endnote-body");
4519 if (!hbox
->plist
.empty())
4520 parsePara(hbox
->plist
.front().get());
4521 endEl("text:endnote-body");
4522 endEl("text:endnote");
4526 mxList
->addAttribute("text:id", sXML_CDATA
, "ftn" + OUString::number(hbox
->number
));
4527 startEl("text:footnote");
4529 mxList
->addAttribute("text:label", sXML_CDATA
, OUString::number(hbox
->number
));
4530 startEl("text:footnote-citation");
4532 chars(OUString::number(hbox
->number
));
4533 endEl("text:footnote-citation");
4534 startEl("text:footnote-body");
4535 if (!hbox
->plist
.empty())
4536 parsePara(hbox
->plist
.front().get());
4537 endEl("text:footnote-body");
4538 endEl("text:footnote");
4544 * page/footnote/endnote/picture/table/formula number
4546 void HwpReader::makeAutoNum(AutoNum
const * hbox
)
4551 startEl("text:page-number");
4552 chars(OUString::number(hbox
->number
));
4553 endEl("text:page-number");
4561 mxList
->addAttribute("text:ref-name",sXML_CDATA
, "refIllustration" + OUString::number(hbox
->number
));
4562 mxList
->addAttribute("text:name",sXML_CDATA
, "Illustration");
4563 mxList
->addAttribute("style:num-format",sXML_CDATA
, "1");
4564 startEl("text:sequence");
4565 chars(OUString::number(hbox
->number
));
4566 endEl("text:sequence");
4569 mxList
->addAttribute("text:ref-name",sXML_CDATA
, "refTable" + OUString::number(hbox
->number
));
4570 mxList
->addAttribute("text:name",sXML_CDATA
, "Table");
4571 mxList
->addAttribute("style:num-format",sXML_CDATA
, "1");
4572 startEl("text:sequence");
4573 chars(OUString::number(hbox
->number
));
4574 endEl("text:sequence");
4580 void HwpReader::makeShowPageNum()
4582 ShowPageNum
*hbox
= d
->pPn
;
4584 if( hbox
->where
== 1 || hbox
->where
== 4 )
4586 else if( hbox
->where
== 2 || hbox
->where
== 5 )
4588 else if( hbox
->where
== 3 || hbox
->where
== 6 )
4590 else /* should not exist in this case. */
4592 if( d
->nPnPos
== 1 )
4594 else if( d
->nPnPos
== 3 )
4598 mxList
->addAttribute("draw:style-name", sXML_CDATA
, "PNBox" + OUString::number(nPos
));
4599 mxList
->addAttribute("draw:name", sXML_CDATA
, "PageNumber" + OUString::number(nPos
));
4600 mxList
->addAttribute("text:anchor-type", sXML_CDATA
, "paragraph");
4601 mxList
->addAttribute("svg:y", sXML_CDATA
, "0cm");
4602 mxList
->addAttribute("svg:width", sXML_CDATA
, "2.0cm");
4603 mxList
->addAttribute("fo:min-height", sXML_CDATA
, "0.5cm");
4604 startEl("draw:text-box");
4607 mxList
->addAttribute("text:style-name", sXML_CDATA
, "PNPara" + OUString::number(nPos
));
4610 if( hbox
->shape
> 2 )
4612 if( hbox
->shape
% 3 == 0 )
4613 mxList
->addAttribute("style:num-format", sXML_CDATA
, "1");
4614 else if( hbox
->shape
% 3 == 1 )
4615 mxList
->addAttribute("style:num-format", sXML_CDATA
, "I");
4617 mxList
->addAttribute("style:num-format", sXML_CDATA
, "i");
4618 mxList
->addAttribute("text:select-page", sXML_CDATA
, "current");
4619 startEl("text:page-number");
4622 endEl("text:page-number");
4623 if( hbox
->shape
> 2 )
4626 endEl("draw:text-box");
4631 * mail merge operation using hwp addressbook and hwp data form.
4632 * not support operation in OO writer.
4634 void HwpReader::makeMailMerge(MailMerge
*)
4636 hchar_string
const boxstr
= MailMerge::GetString();
4637 chars(hstr2OUString(boxstr
.c_str()));
4641 void HwpReader::makeOutline(Outline
const * hbox
)
4643 if( hbox
->kind
== 1 )
4644 chars( hbox
->GetUnicode() );
4648 void HwpReader::parsePara(HWPPara
* para
)
4650 bool bParaStart
= false;
4657 mxList
->addAttribute("text:style-name", sXML_CDATA
,
4658 getPStyleName(para
->GetParaShape().index
));
4662 if( d
->bFirstPara
&& d
->bInBody
)
4664 /* for HWP's Bookmark */
4665 mxList
->addAttribute("text:name", sXML_CDATA
, sBeginOfDoc
);
4666 startEl("text:bookmark");
4668 endEl("text:bookmark");
4669 d
->bFirstPara
= false;
4674 d
->bInHeader
= false;
4681 if (!para
->ctrlflag
)
4683 if (para
->contain_cshape
)
4684 make_text_p1(para
, bParaStart
);
4686 make_text_p0(para
, bParaStart
);
4689 make_text_p3(para
, bParaStart
);
4692 para
= para
->Next();
4697 void HwpReader::startEl(const OUString
& el
)
4699 if (m_rxDocumentHandler
)
4700 m_rxDocumentHandler
->startElement(el
, mxList
);
4704 void HwpReader::endEl(const OUString
& el
)
4706 if (m_rxDocumentHandler
)
4707 m_rxDocumentHandler
->endElement(el
);
4711 void HwpReader::chars(const OUString
& s
)
4713 if (m_rxDocumentHandler
)
4714 m_rxDocumentHandler
->characters(s
);
4721 constexpr OUStringLiteral IMPLEMENTATION_NAME
= u
"com.sun.comp.hwpimport.HwpImportFilter";
4722 constexpr OUString SERVICE_NAME1
= u
"com.sun.star.document.ImportFilter"_ustr
;
4723 constexpr OUString SERVICE_NAME2
= u
"com.sun.star.document.ExtendedTypeDetection"_ustr
;
4725 class HwpImportFilter
: public WeakImplHelper
< XFilter
, XImporter
, XServiceInfo
, XExtendedFilterDetection
>
4728 explicit HwpImportFilter(const Reference
< XComponentContext
>& );
4732 virtual sal_Bool SAL_CALL
filter( const Sequence
< PropertyValue
>& aDescriptor
) override
;
4733 virtual void SAL_CALL
cancel() override
;
4736 virtual void SAL_CALL
setTargetDocument( const Reference
< XComponent
>& xDoc
) override
;
4739 OUString SAL_CALL
getImplementationName() override
;
4740 Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
4741 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) override
;
4743 //XExtendedFilterDetection
4744 virtual OUString SAL_CALL
detect( css::uno::Sequence
< css::beans::PropertyValue
>& rDescriptor
) override
;
4747 Reference
< XFilter
> rFilter
;
4748 Reference
< XImporter
> rImporter
;
4752 HwpImportFilter::HwpImportFilter(const Reference
< XComponentContext
>& rxContext
)
4755 Reference
< XDocumentHandler
> xHandler( rxContext
->getServiceManager()->createInstanceWithContext( WRITER_IMPORTER_NAME
, rxContext
), UNO_QUERY
);
4757 rtl::Reference
<HwpReader
> p
= new HwpReader
;
4758 p
->setDocumentHandler( xHandler
);
4760 Reference
< XImporter
> xImporter( xHandler
, UNO_QUERY
);
4761 rImporter
= xImporter
;
4764 catch( Exception
& )
4766 printf(" fail to instantiate %s\n", WRITER_IMPORTER_NAME
.toUtf8().getStr() );
4771 sal_Bool
HwpImportFilter::filter( const Sequence
< PropertyValue
>& aDescriptor
)
4773 // delegate to IchitaroImporter
4774 return rFilter
->filter( aDescriptor
);
4777 void HwpImportFilter::cancel()
4782 void HwpImportFilter::setTargetDocument( const Reference
< XComponent
>& xDoc
)
4785 rImporter
->setTargetDocument( xDoc
);
4788 OUString
HwpImportFilter::getImplementationName()
4790 return IMPLEMENTATION_NAME
;
4793 sal_Bool
HwpImportFilter::supportsService( const OUString
& ServiceName
)
4795 return cppu::supportsService(this, ServiceName
);
4798 //XExtendedFilterDetection
4799 OUString
HwpImportFilter::detect( css::uno::Sequence
< css::beans::PropertyValue
>& rDescriptor
)
4803 utl::MediaDescriptor
aDescriptor(rDescriptor
);
4804 aDescriptor
.addInputStream();
4806 Reference
< XInputStream
> xInputStream(
4807 aDescriptor
[utl::MediaDescriptor::PROP_INPUTSTREAM
], UNO_QUERY
);
4809 if (xInputStream
.is())
4811 Sequence
< sal_Int8
> aData
;
4812 sal_Int32 nLen
= HWPIDLen
;
4814 nLen
== xInputStream
->readBytes(aData
, nLen
) &&
4815 detect_hwp_version(reinterpret_cast<const char*>(aData
.getConstArray()))
4818 sTypeName
= "writer_MIZI_Hwp_97";
4825 Sequence
< OUString
> HwpImportFilter::getSupportedServiceNames()
4827 return { SERVICE_NAME1
, SERVICE_NAME2
};
4832 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
4833 hwpfilter_HwpImportFilter_get_implementation(
4834 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
4836 return cppu::acquire(new HwpImportFilter(context
));
4840 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */