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 .
23 #include "hwpreader.hxx"
26 #include <osl/diagnose.h>
27 #include <tools/stream.hxx>
29 #include "fontmap.hxx"
36 #include <sal/types.h>
37 #include <rtl/ustrbuf.hxx>
39 // To be shorten source code by realking
40 #define hconv(x) hstr2ucsstr(x).c_str()
41 #define ascii(x) OUString::createFromAscii(x)
42 #define rstartEl(x,y) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->startElement(x,y); } while(false)
43 #define rendEl(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->endElement(x); } while(false)
44 #define rchars(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->characters(x); } while(false)
45 #define padd(x,y,z) mxList->addAttribute(x,y,z)
46 #define Double2Str(x) OUString::number(x)
47 #define WTI(x) (static_cast<double>(x) / 1800.) // unit => inch
48 #define WTMM(x) (static_cast<double>(x) / 1800. * 25.4) // unit => mm
49 #define WTSM(x) (static_cast<int>((x) / 1800. * 2540)) // unit ==> 1/100 mm
51 #define PI 3.14159265358979323846
54 #define sXML_CDATA "CDATA"
56 #define STARTP padd( "text:style-name", "CDATA", ascii(getPStyleName((para->GetParaShape()).index,buf))); \
57 rstartEl( "text:p",mxList.get() ); \
61 curr = para->GetCharShape(n > 0 ? n-1 : 0)->index; \
62 padd( "text:style-name", "CDATA" , ascii( getTStyleName(curr, buf) ) ); \
63 rstartEl( "text:span",mxList.get() ); \
70 rendEl("text:span"); \
73 static hchar
*field
= nullptr;
74 static char buf
[1024];
82 void operator()(T
* const ptr
)
90 struct HwpReaderPrivate
108 HwpReader::HwpReader()
110 mxList
= new AttributeListImpl
;
111 d
.reset( new HwpReaderPrivate
);
115 HwpReader::~HwpReader()
119 extern "C" SAL_DLLPUBLIC_EXPORT
bool TestImportHWP(SvStream
&rStream
)
123 std::unique_ptr
<HStream
> stream(new HStream
);
128 std::size_t nRead
= rStream
.ReadBytes(aData
, 32768);
131 stream
->addData(aData
, static_cast<int>(nRead
));
135 if (hwpfile
.ReadHwpFile(std::move(stream
)))
145 sal_Bool
HwpReader::filter(const Sequence
< PropertyValue
>& rDescriptor
)
147 utl::MediaDescriptor
aDescriptor(rDescriptor
);
148 aDescriptor
.addInputStream();
150 Reference
< XInputStream
> xInputStream(
151 aDescriptor
[utl::MediaDescriptor::PROP_INPUTSTREAM()], UNO_QUERY_THROW
);
153 std::unique_ptr
<HStream
> stream(new HStream
);
154 Sequence
< sal_Int8
> aBuffer
;
155 sal_Int32 nRead
, nTotal
= 0;
158 nRead
= xInputStream
->readBytes(aBuffer
, 32768);
161 stream
->addData( reinterpret_cast<const byte
*>(aBuffer
.getConstArray()), nRead
);
165 if( nTotal
== 0 ) return false;
167 if (hwpfile
.ReadHwpFile(std::move(stream
)))
170 if (m_rxDocumentHandler
.is())
171 m_rxDocumentHandler
->startDocument();
173 padd("office:class", sXML_CDATA
, "text");
174 padd("office:version", sXML_CDATA
, "0.9");
176 padd("xmlns:office", "CDATA", "http://openoffice.org/2000/office");
177 padd("xmlns:style", "CDATA", "http://openoffice.org/2000/style");
178 padd("xmlns:text", "CDATA", "http://openoffice.org/2000/text");
179 padd("xmlns:table", "CDATA", "http://openoffice.org/2000/table");
180 padd("xmlns:draw", "CDATA", "http://openoffice.org/2000/drawing");
181 padd("xmlns:fo", "CDATA", "http://www.w3.org/1999/XSL/Format");
182 padd("xmlns:xlink", "CDATA", "http://www.w3.org/1999/xlink");
183 padd("xmlns:dc", "CDATA", "http://purl.org/dc/elements/1.1/");
184 padd("xmlns:meta", "CDATA", "http://openoffice.org/2000/meta");
185 padd("xmlns:number", "CDATA", "http://openoffice.org/2000/datastyle");
186 padd("xmlns:svg", "CDATA", "http://www.w3.org/2000/svg");
187 padd("xmlns:chart", "CDATA", "http://openoffice.org/2000/chart");
188 padd("xmlns:dr3d", "CDATA", "http://openoffice.org/2000/dr3d");
189 padd("xmlns:math", "CDATA", "http://www.w3.org/1998/Math/MathML");
190 padd("xmlns:form", "CDATA", "http://openoffice.org/2000/form");
191 padd("xmlns:script", "CDATA", "http://openoffice.org/2000/script");
193 rstartEl("office:document", mxList
.get());
202 rendEl("office:document");
204 if (m_rxDocumentHandler
.is())
205 m_rxDocumentHandler
->endDocument();
213 void HwpReader::makeBody()
215 rstartEl("office:body", mxList
.get());
217 HWPPara
*hwppara
= hwpfile
.GetFirstPara();
220 rendEl("office:body");
228 void HwpReader::makeTextDecls()
230 rstartEl("text:sequence-decls", mxList
.get());
231 padd("text:display-outline-level", sXML_CDATA
, "0");
232 padd("text:name", sXML_CDATA
, "Illustration");
233 rstartEl("text:sequence-decl", mxList
.get());
235 rendEl("text:sequence-decl");
236 padd("text:display-outline-level", sXML_CDATA
, "0");
237 padd("text:name", sXML_CDATA
, "Table");
238 rstartEl("text:sequence-decl", mxList
.get());
240 rendEl("text:sequence-decl");
241 padd("text:display-outline-level", sXML_CDATA
, "0");
242 padd("text:name", sXML_CDATA
, "Text");
243 rstartEl("text:sequence-decl", mxList
.get());
245 rendEl("text:sequence-decl");
246 padd("text:display-outline-level", sXML_CDATA
, "0");
247 padd("text:name", sXML_CDATA
, "Drawing");
248 rstartEl("text:sequence-decl", mxList
.get());
250 rendEl("text:sequence-decl");
251 rendEl("text:sequence-decls");
255 #define ISNUMBER(x) ( (x) <= 0x39 && (x) >= 0x30 )
260 void HwpReader::makeMeta()
262 HWPInfo
& hwpinfo
= hwpfile
.GetHWPInfo();
264 rstartEl("office:meta", mxList
.get());
266 if (hwpinfo
.summary
.title
[0])
268 rstartEl("dc:title", mxList
.get());
269 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(hwpinfo
.summary
.title
)));
273 if (hwpinfo
.summary
.subject
[0])
275 rstartEl("dc:subject", mxList
.get());
276 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(hwpinfo
.summary
.subject
)));
277 rendEl("dc:subject");
280 if (hwpinfo
.summary
.author
[0])
282 rstartEl("meta:initial-creator", mxList
.get());
283 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(hwpinfo
.summary
.author
)));
284 rendEl("meta:initial-creator");
287 if (hwpinfo
.summary
.date
[0])
289 unsigned short *pDate
= hwpinfo
.summary
.date
;
290 int year
,month
,day
,hour
,minute
;
292 if( ISNUMBER( pDate
[0] ) && ISNUMBER( pDate
[1] ) &&
293 ISNUMBER( pDate
[2] ) && ISNUMBER( pDate
[3] ))
295 year
= (pDate
[0]-0x30) * 1000 + (pDate
[1]-0x30) * 100 +
296 (pDate
[2]-0x30) * 10 + (pDate
[3]-0x30);
301 if( ISNUMBER( pDate
[6] ))
303 if( ISNUMBER( pDate
[7] ) )
304 month
= (pDate
[6] - 0x30) * 10 + (pDate
[6+ ++gab
]-0x30);
306 month
= (pDate
[6] - 0x30);
311 if( ISNUMBER( pDate
[9 + gab
] ) )
313 if( ISNUMBER( pDate
[10 + gab
])) {
314 day
= ( pDate
[9 + gab
] - 0x30 ) * 10 + (pDate
[9+ gab
+ 1]-0x30);
317 day
= (pDate
[9+gab
]-0x30);
322 if( ISNUMBER( pDate
[17 + gab
] ) )
324 if( ISNUMBER( pDate
[18 + gab
])) {
325 hour
= ( pDate
[17 + gab
] - 0x30 ) * 10 + (pDate
[17+ gab
+ 1]-0x30);
328 hour
= (pDate
[17+gab
]-0x30);
333 if( ISNUMBER( pDate
[20 + gab
] ) )
335 if( ISNUMBER( pDate
[21 + gab
])) {
336 minute
= ( pDate
[20 + gab
] - 0x30 ) * 10 + (pDate
[20+ gab
+ 1]-0x30);
339 minute
= (pDate
[20+gab
]-0x30);
344 sprintf(buf
,"%d-%02d-%02dT%02d:%02d:00",year
,month
,day
,hour
,minute
);
346 rstartEl( "meta:creation-date", mxList
.get() );
348 rendEl( "meta:creation-date" );
351 if (hwpinfo
.summary
.keyword
[0][0] || hwpinfo
.summary
.etc
[0][0])
353 rstartEl("meta:keywords", mxList
.get());
354 if (hwpinfo
.summary
.keyword
[0][0])
356 rstartEl("meta:keyword", mxList
.get());
357 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(hwpinfo
.summary
.keyword
[0])));
358 rendEl("meta:keyword");
360 if (hwpinfo
.summary
.keyword
[1][0])
362 rstartEl("meta:keyword", mxList
.get());
363 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(hwpinfo
.summary
.keyword
[1])));
364 rendEl("meta:keyword");
366 if (hwpinfo
.summary
.etc
[0][0])
368 rstartEl("meta:keyword", mxList
.get());
369 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(hwpinfo
.summary
.etc
[0])));
370 rendEl("meta:keyword");
372 if (hwpinfo
.summary
.etc
[1][0])
374 rstartEl("meta:keyword", mxList
.get());
375 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(hwpinfo
.summary
.etc
[1])));
376 rendEl("meta:keyword");
378 if (hwpinfo
.summary
.etc
[2][0])
380 rstartEl("meta:keyword", mxList
.get());
381 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(hwpinfo
.summary
.etc
[2])));
382 rendEl("meta:keyword");
384 rendEl("meta:keywords");
386 rendEl("office:meta");
399 { "Line Arrow", false },
424 void HwpReader::makeDrawMiscStyle( HWPDrawingObject
*hdo
)
429 makeDrawMiscStyle( hdo
->child
.get() );
431 HWPDOProperty
*prop
= &hdo
->property
;
432 if( hdo
->type
== HWPDO_CONTAINER
)
434 hdo
= hdo
->next
.get();
438 if( prop
->line_pstyle
> 0 && prop
->line_pstyle
< 5 && prop
->line_color
<= 0xffffff)
440 padd( "draw:name", sXML_CDATA
, ascii(Int2Str(hdo
->index
, "LineType%d", buf
)));
441 padd( "draw:style", sXML_CDATA
, "round");
442 padd( "draw:dots1", sXML_CDATA
, "1");
443 padd( "draw:dots1-length", sXML_CDATA
, Double2Str( LineStyle
[prop
->line_pstyle
].dots1
* WTMM(prop
->line_width
) ) + "cm");
444 if( prop
->line_pstyle
== 3 )
446 padd( "draw:dots2", sXML_CDATA
, "1");
447 padd( "draw:dots2-length", sXML_CDATA
, Double2Str( LineStyle
[prop
->line_pstyle
].dots2
* WTMM(prop
->line_width
) ) + "cm");
449 else if( prop
->line_pstyle
== 4 )
451 padd( "draw:dots2", sXML_CDATA
, "2");
452 padd( "draw:dots2-length", sXML_CDATA
, Double2Str( LineStyle
[prop
->line_pstyle
].dots2
* WTMM(prop
->line_width
)) + "cm");
454 padd( "draw:distance", sXML_CDATA
, Double2Str( LineStyle
[prop
->line_pstyle
].distance
* WTMM(prop
->line_width
)) + "cm");
455 rstartEl( "draw:stroke-dash", mxList
.get());
457 rendEl( "draw:stroke-dash" );
460 if( hdo
->type
== HWPDO_LINE
|| hdo
->type
== HWPDO_ARC
|| hdo
->type
== HWPDO_FREEFORM
||
461 hdo
->type
== HWPDO_ADVANCED_ARC
)
463 if( prop
->line_tstyle
&& !ArrowShape
[prop
->line_tstyle
].bMade
)
465 ArrowShape
[prop
->line_tstyle
].bMade
= true;
466 padd("draw:name", sXML_CDATA
,
467 ascii(ArrowShape
[prop
->line_tstyle
].name
));
468 if( prop
->line_tstyle
== 1 )
470 padd("svg:viewBox", sXML_CDATA
, "0 0 20 30");
471 padd("svg:d", sXML_CDATA
, "m10 0-10 30h20z");
473 else if( prop
->line_tstyle
== 2 )
475 padd("svg:viewBox", sXML_CDATA
, "0 0 1122 2243");
476 padd("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");
478 else if( prop
->line_tstyle
== 3 )
480 padd("svg:viewBox", sXML_CDATA
, "0 0 30 30");
481 padd("svg:d", sXML_CDATA
, "m0 0h30v30h-30z");
483 rstartEl("draw:marker", mxList
.get());
485 rendEl("draw:marker");
487 if( prop
->line_hstyle
&& !ArrowShape
[prop
->line_hstyle
].bMade
)
489 ArrowShape
[prop
->line_hstyle
].bMade
= true;
490 padd("draw:name", sXML_CDATA
,
491 ascii(ArrowShape
[prop
->line_hstyle
].name
));
492 if( prop
->line_hstyle
== 1 )
494 padd("svg:viewBox", sXML_CDATA
, "0 0 20 30");
495 padd("svg:d", sXML_CDATA
, "m10 0-10 30h20z");
497 else if( prop
->line_hstyle
== 2 )
499 padd("svg:viewBox", sXML_CDATA
, "0 0 1122 2243");
500 padd("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");
502 else if( prop
->line_hstyle
== 3 )
504 padd("svg:viewBox", sXML_CDATA
, "0 0 20 20");
505 padd("svg:d", sXML_CDATA
, "m0 0h20v20h-20z");
507 rstartEl("draw:marker", mxList
.get());
509 rendEl("draw:marker");
513 if( hdo
->type
!= HWPDO_LINE
)
515 if( prop
->flag
>> 18 & 0x01 )
517 padd( "draw:name", sXML_CDATA
, ascii(Int2Str(hdo
->index
, "fillimage%d", buf
)));
520 padd( "xlink:href", sXML_CDATA
,
521 reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr( reinterpret_cast<uchar
const *>(urltounix(prop
->szPatternFile
).c_str())).c_str())));
525 EmPicture
*emp
= nullptr;
526 if ( strlen( prop
->szPatternFile
) > 3)
527 emp
= hwpfile
.GetEmPictureByName(prop
->szPatternFile
);
530 char filename
[128+17+9];
534 GetTempPathA(sizeof(dirname
), dirname
);
535 sprintf(filename
, "%s%s",dirname
, emp
->name
);
536 if( (fd
= open( filename
, _O_CREAT
| _O_WRONLY
| _O_BINARY
, 0666)) >= 0 )
538 strcpy(dirname
, "/tmp/");
539 sprintf(filename
, "%s%s", dirname
, emp
->name
);
540 if( (fd
= open( filename
, O_CREAT
| O_WRONLY
, 0666)) >= 0 )
543 size_t nWritten
= write(fd
, emp
->data
.get(), emp
->size
);
544 OSL_VERIFY(nWritten
== emp
->size
);
549 for(j
= 0 ; j
< static_cast<int>(strlen( dirname
)) ; j
++)
551 if( dirname
[j
] == '\\' ) buf
[j
] = '/';
552 else buf
[j
] = dirname
[j
];
555 sprintf(filename
, "file:///%s%s",buf
, emp
->name
);
557 sprintf(filename
, "file://%s%s",dirname
, emp
->name
);
559 padd( "xlink:href", sXML_CDATA
, ascii(filename
));
563 padd( "xlink:href", sXML_CDATA
,
564 reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr( reinterpret_cast<uchar
const *>(urltounix(prop
->szPatternFile
).c_str())).c_str())));
568 padd( "xlink:type", sXML_CDATA
, "simple");
569 padd( "xlink:show", sXML_CDATA
, "embed");
570 padd( "xlink:actuate", sXML_CDATA
, "onLoad");
572 rstartEl( "draw:fill-image", mxList
.get());
574 rendEl( "draw:fill-image");
576 /* If there is a gradient, when a bitmap file is present, this is the first. */
577 else if( prop
->flag
>> 16 & 0x01 ) /* existence gradient */
579 padd( "draw:name", sXML_CDATA
, ascii(Int2Str(hdo
->index
, "Grad%d", buf
)));
580 switch( prop
->gstyle
)
583 if( prop
->center_y
== 50 )
584 padd( "draw:style", sXML_CDATA
, "axial");
586 padd( "draw:style", sXML_CDATA
, "linear");
590 padd( "draw:style", sXML_CDATA
, "radial");
593 padd( "draw:style", sXML_CDATA
, "square");
596 padd( "draw:style", sXML_CDATA
, "linear");
599 padd( "draw:cx", sXML_CDATA
,ascii(Int2Str(prop
->center_x
, "%d%%", buf
)));
600 padd( "draw:cy", sXML_CDATA
,ascii(Int2Str(prop
->center_y
, "%d%%", buf
)));
602 HWPInfo
& hwpinfo
= hwpfile
.GetHWPInfo();
603 int default_color
= 0xffffff;
604 if( hwpinfo
.back_info
.isset
)
606 if( hwpinfo
.back_info
.color
[0] > 0 || hwpinfo
.back_info
.color
[1] > 0
607 || hwpinfo
.back_info
.color
[2] > 0 )
608 default_color
= hwpinfo
.back_info
.color
[0] << 16 |
609 hwpinfo
.back_info
.color
[1] << 8 | hwpinfo
.back_info
.color
[2];
612 if( prop
->fromcolor
> 0xffffff )
613 prop
->fromcolor
= default_color
;
614 if( prop
->tocolor
> 0xffffff )
615 prop
->tocolor
= default_color
;
617 if( prop
->gstyle
== 1)
619 if( prop
->center_y
== 100 )
621 sprintf( buf
, "#%02x%02x%02x", prop
->tocolor
& 0xff,
622 (prop
->tocolor
>> 8) & 0xff, (prop
->tocolor
>>16) & 0xff );
623 padd( "draw:start-color", sXML_CDATA
, ascii( buf
));
624 sprintf( buf
, "#%02x%02x%02x", prop
->fromcolor
& 0xff,
625 (prop
->fromcolor
>> 8) & 0xff, (prop
->fromcolor
>>16) & 0xff );
626 padd( "draw:end-color", sXML_CDATA
, ascii( buf
));
630 sprintf( buf
, "#%02x%02x%02x", prop
->fromcolor
& 0xff,
631 (prop
->fromcolor
>> 8) & 0xff, (prop
->fromcolor
>>16) & 0xff );
632 padd( "draw:start-color", sXML_CDATA
, ascii( buf
));
633 sprintf( buf
, "#%02x%02x%02x", prop
->tocolor
& 0xff,
634 (prop
->tocolor
>> 8) & 0xff, (prop
->tocolor
>>16) & 0xff );
635 padd( "draw:end-color", sXML_CDATA
, ascii( buf
));
640 sprintf( buf
, "#%02x%02x%02x", prop
->tocolor
& 0xff,
641 (prop
->tocolor
>> 8) & 0xff, (prop
->tocolor
>>16) & 0xff );
642 padd( "draw:start-color", sXML_CDATA
,ascii( buf
));
644 sprintf( buf
, "#%02x%02x%02x", prop
->fromcolor
& 0xff,
645 (prop
->fromcolor
>> 8) & 0xff, (prop
->fromcolor
>>16) & 0xff );
646 padd( "draw:end-color", sXML_CDATA
,ascii( buf
));
648 if( prop
->angle
> 0 && ( prop
->gstyle
== 1 || prop
->gstyle
== 4))
650 int angle
= 1800 - prop
->angle
* 10;
651 padd( "draw:angle", sXML_CDATA
,
652 ascii(Int2Str( angle
, "%d", buf
)));
654 rstartEl( "draw:gradient", mxList
.get() );
656 rendEl( "draw:gradient");
659 else if( prop
->pattern_type
>> 24 & 0x01 )
661 int type
= prop
->pattern_type
& 0xffffff;
662 padd( "draw:name", sXML_CDATA
,
663 ascii(Int2Str(hdo
->index
, "Hatch%d", buf
)));
665 padd( "draw:style", sXML_CDATA
, "single" );
667 padd( "draw:style", sXML_CDATA
, "double" );
668 sprintf( buf
, "#%02x%02x%02x",
669 sal_uInt16(prop
->pattern_color
& 0xff),
670 sal_uInt16((prop
->pattern_color
>> 8) & 0xff),
671 sal_uInt16((prop
->pattern_color
>>16) & 0xff) );
672 padd( "draw:color", sXML_CDATA
, ascii( buf
));
673 padd( "draw:distance", sXML_CDATA
, "0.12cm");
678 padd( "draw:rotation", sXML_CDATA
, "0");
681 padd( "draw:rotation", sXML_CDATA
, "900");
684 padd( "draw:rotation", sXML_CDATA
, "1350");
688 padd( "draw:rotation", sXML_CDATA
, "450");
691 rstartEl( "draw:hatch", mxList
.get());
693 rendEl( "draw:hatch");
696 hdo
= hdo
->next
.get();
701 void HwpReader::makeStyles()
703 HWPStyle
& hwpstyle
= hwpfile
.GetHWPStyle();
705 rstartEl("office:styles", mxList
.get());
708 for (i
= 0; i
< hwpfile
.getFBoxStyleCount(); i
++)
710 if( hwpfile
.getFBoxStyle(i
)->boxtype
== 'D' )
712 makeDrawMiscStyle(static_cast<HWPDrawingObject
*>(hwpfile
.getFBoxStyle(i
)->cell
) );
716 padd("style:name", sXML_CDATA
, "Standard");
717 padd("style:family", sXML_CDATA
, "paragraph");
718 padd("style:class", sXML_CDATA
, "text");
719 rstartEl("style:style", mxList
.get());
722 padd("fo:line-height", sXML_CDATA
, "160%");
723 padd("fo:text-align", sXML_CDATA
, "justify");
724 rstartEl("style:properties", mxList
.get());
726 rstartEl("style:tab-stops", mxList
.get());
728 for( i
= 1 ; i
< 40 ; i
++)
730 padd("style:position", sXML_CDATA
,
731 Double2Str( WTI(1000 * i
)) + "inch");
732 rstartEl("style:tab-stop", mxList
.get());
734 rendEl("style:tab-stop");
736 rendEl("style:tab-stops");
737 rendEl("style:properties");
739 rendEl("style:style");
741 for (int ii
= 0; ii
< hwpstyle
.Num(); ii
++)
743 unsigned char *stylename
= reinterpret_cast<unsigned char *>(hwpstyle
.GetName(ii
));
744 padd("style:name", sXML_CDATA
, reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr(stylename
).c_str())));
745 padd("style:family", sXML_CDATA
, "paragraph");
746 padd("style:parent-style-name", sXML_CDATA
, "Standard");
748 rstartEl("style:style", mxList
.get());
752 parseCharShape(hwpstyle
.GetCharShape(ii
));
753 parseParaShape(hwpstyle
.GetParaShape(ii
));
755 rstartEl("style:properties", mxList
.get());
757 rendEl("style:properties");
759 rendEl("style:style");
763 padd( "style:name", sXML_CDATA
, "Header");
764 padd( "style:family", sXML_CDATA
, "paragraph");
765 padd( "style:parent-style-name", sXML_CDATA
, "Standard");
766 padd( "style:class", sXML_CDATA
, "extra");
767 rstartEl("style:style", mxList
.get());
769 rendEl("style:style");
773 padd( "style:name", sXML_CDATA
, "Footer");
774 padd( "style:family", sXML_CDATA
, "paragraph");
775 padd( "style:parent-style-name", sXML_CDATA
, "Standard");
776 padd( "style:class", sXML_CDATA
, "extra");
777 rstartEl("style:style", mxList
.get());
780 rendEl("style:style");
783 if( hwpfile
.linenumber
> 0)
785 padd( "style:name", sXML_CDATA
, "Horizontal Line");
786 padd( "style:family", sXML_CDATA
, "paragraph");
787 padd( "style:parent-style-name", sXML_CDATA
, "Standard");
788 padd( "style:class", sXML_CDATA
, "html");
789 rstartEl( "style:style", mxList
.get());
791 padd( "fo:font-size", sXML_CDATA
, "6pt");
792 padd( "fo:margin-top", sXML_CDATA
, "0cm");
793 padd( "fo:margin-bottom", sXML_CDATA
, "0cm");
794 padd( "style:border-line-width-bottom", sXML_CDATA
, "0.02cm 0.035cm 0.002cm");
795 padd( "fo:padding", sXML_CDATA
, "0cm");
796 padd( "fo:border-bottom", sXML_CDATA
, "0.039cm double #808080");
797 padd( "text:number-lines", sXML_CDATA
, "false");
798 padd( "text:line-number", sXML_CDATA
, "0");
799 padd("fo:line-height", sXML_CDATA
, "100%");
800 rstartEl( "style:properties", mxList
.get());
802 rendEl( "style:properties");
803 rendEl( "style:style");
806 HWPInfo
& hwpinfo
= hwpfile
.GetHWPInfo();
808 padd("text:num-suffix", sXML_CDATA
, ")");
809 padd("text:num-format", sXML_CDATA
, "1");
810 if( hwpinfo
.beginfnnum
!= 1)
811 padd("text:offset", sXML_CDATA
, ascii(Int2Str(hwpinfo
.beginfnnum
-1, "%d", buf
)));
812 rstartEl("text:footnotes-configuration", mxList
.get());
814 rendEl("text:footnotes-configuration");
816 rendEl("office:styles");
821 * parse automatic styles from hwpfile
822 * 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.
823 * 1. supports for the styles of paragraph, text, fbox, and page.
825 void HwpReader::makeAutoStyles()
829 rstartEl("office:automatic-styles", mxList
.get());
831 for (i
= 0; i
< hwpfile
.getParaShapeCount(); i
++)
832 makePStyle(hwpfile
.getParaShape(i
));
834 for (i
= 0; i
< hwpfile
.getCharShapeCount(); i
++)
835 makeTStyle(hwpfile
.getCharShape(i
));
837 for( i
= 0 ; i
< hwpfile
.getTableCount(); i
++)
838 makeTableStyle(hwpfile
.getTable(i
));
840 for (i
= 0; i
< hwpfile
.getFBoxStyleCount(); i
++)
842 if( hwpfile
.getFBoxStyle(i
)->boxtype
== 'D' )
843 makeDrawStyle(static_cast<HWPDrawingObject
*>(hwpfile
.getFBoxStyle(i
)->cell
), hwpfile
.getFBoxStyle(i
));
845 makeFStyle(hwpfile
.getFBoxStyle(i
));
848 bool bIsLeft
= false, bIsMiddle
= false, bIsRight
= false;
849 for( i
= 0 ; i
< hwpfile
.getPageNumberCount() ; i
++ )
851 ShowPageNum
*pn
= hwpfile
.getPageNumber(i
);
852 if( pn
->where
== 7 || pn
->where
== 8 )
857 else if( pn
->where
== 1 || pn
->where
== 4 )
861 else if( pn
->where
== 2 || pn
->where
== 5 )
865 else if( pn
->where
== 3 || pn
->where
== 6 )
871 for( i
= 1; i
<= 3 ; i
++ )
873 if( i
== 1 && !bIsLeft
)
875 if( i
== 2 && !bIsMiddle
)
877 if( i
== 3 && !bIsRight
)
879 padd("style:name", sXML_CDATA
,
880 ascii(Int2Str(i
,"PNPara%d", buf
)));
881 padd("style:family", sXML_CDATA
, "paragraph");
882 padd("style:parent-style-name", sXML_CDATA
, "Standard");
883 rstartEl("style:style", mxList
.get());
886 padd("fo:text-align", sXML_CDATA
, "start");
888 padd("fo:text-align", sXML_CDATA
, "center");
890 padd("fo:text-align", sXML_CDATA
, "end");
891 rstartEl("style:properties", mxList
.get());
893 rendEl( "style:properties");
894 rendEl( "style:style");
896 padd("style:name", sXML_CDATA
, ascii(Int2Str(i
,"PNBox%d",buf
)));
897 padd("style:family", sXML_CDATA
, "graphics");
898 rstartEl("style:style", mxList
.get());
901 padd("fo:margin-top", sXML_CDATA
, "0cm");
902 padd("fo:margin-bottom", sXML_CDATA
, "0cm");
903 padd("style:wrap", sXML_CDATA
, "run-through");
904 padd("style:vertical-pos", sXML_CDATA
, "from-top");
905 padd("style:vertical-rel", sXML_CDATA
, "paragraph");
908 padd("style:horizontal-pos", sXML_CDATA
, "left");
910 padd("style:horizontal-pos", sXML_CDATA
, "center");
912 padd("style:horizontal-pos", sXML_CDATA
, "right");
913 padd("style:horizontal-rel", sXML_CDATA
, "paragraph");
914 padd("fo:padding", sXML_CDATA
, "0cm");
915 padd("stylefamily", sXML_CDATA
, "graphics");
916 rstartEl("style:properties", mxList
.get());
918 rendEl("style:properties");
919 rendEl("style:style");
922 for (i
= 0; i
< hwpfile
.getDateFormatCount(); i
++)
923 makeDateFormat(hwpfile
.getDateCode(i
));
927 rendEl("office:automatic-styles");
936 header_odd
= nullptr;
937 header_even
= nullptr;
939 footer_odd
= nullptr;
940 footer_even
= nullptr;
944 HeaderFooter
*header
;
945 HeaderFooter
*header_odd
;
946 HeaderFooter
*header_even
;
947 HeaderFooter
*footer
;
948 HeaderFooter
*footer_odd
;
949 HeaderFooter
*footer_even
;
950 ShowPageNum
*pagenumber
;
954 void HwpReader::makeMasterStyles()
956 rstartEl("office:master-styles", mxList
.get());
959 int nMax
= hwpfile
.getMaxSettedPage();
960 std::deque
<PageSetting
> aSet(nMax
+ 1);
962 for( i
= 0 ; i
< hwpfile
.getPageNumberCount() ; i
++ )
964 ShowPageNum
*pn
= hwpfile
.getPageNumber(i
);
965 aSet
[pn
->m_nPageNumber
].pagenumber
= pn
;
966 aSet
[pn
->m_nPageNumber
].bIsSet
= true;
968 for( i
= 0 ; i
< hwpfile
.getHeaderFooterCount() ; i
++ )
970 HeaderFooter
* hf
= hwpfile
.getHeaderFooter(i
);
971 aSet
[hf
->m_nPageNumber
].bIsSet
= true;
972 if( hf
->type
== 0 ) // header
977 aSet
[hf
->m_nPageNumber
].header
= hf
;
978 aSet
[hf
->m_nPageNumber
].header_even
= nullptr;
979 aSet
[hf
->m_nPageNumber
].header_odd
= nullptr;
982 aSet
[hf
->m_nPageNumber
].header_even
= hf
;
983 if( aSet
[hf
->m_nPageNumber
].header
)
985 aSet
[hf
->m_nPageNumber
].header_odd
=
986 aSet
[hf
->m_nPageNumber
].header
;
987 aSet
[hf
->m_nPageNumber
].header
= nullptr;
991 aSet
[hf
->m_nPageNumber
].header_odd
= hf
;
992 if( aSet
[hf
->m_nPageNumber
].header
)
994 aSet
[hf
->m_nPageNumber
].header_even
=
995 aSet
[hf
->m_nPageNumber
].header
;
996 aSet
[hf
->m_nPageNumber
].header
= nullptr;
1006 aSet
[hf
->m_nPageNumber
].footer
= hf
;
1007 aSet
[hf
->m_nPageNumber
].footer_even
= nullptr;
1008 aSet
[hf
->m_nPageNumber
].footer_odd
= nullptr;
1011 aSet
[hf
->m_nPageNumber
].footer_even
= hf
;
1012 if( aSet
[hf
->m_nPageNumber
].footer
)
1014 aSet
[hf
->m_nPageNumber
].footer_odd
=
1015 aSet
[hf
->m_nPageNumber
].footer
;
1016 aSet
[hf
->m_nPageNumber
].footer
= nullptr;
1020 aSet
[hf
->m_nPageNumber
].footer_odd
= hf
;
1021 if( aSet
[hf
->m_nPageNumber
].footer
)
1023 aSet
[hf
->m_nPageNumber
].footer_even
=
1024 aSet
[hf
->m_nPageNumber
].footer
;
1025 aSet
[hf
->m_nPageNumber
].footer
= nullptr;
1032 PageSetting
*pPrevSet
= nullptr;
1033 PageSetting
*pPage
= nullptr;
1035 for( i
= 1; i
<= nMax
; i
++ )
1038 padd("style:name", sXML_CDATA
, "Standard");
1040 padd("style:name", sXML_CDATA
,
1041 ascii(Int2Str(i
, "p%d", buf
)));
1042 padd("style:page-master-name", sXML_CDATA
,
1043 ascii(Int2Str(hwpfile
.GetPageMasterNum(i
), "pm%d", buf
)));
1045 padd("style:next-style-name", sXML_CDATA
,
1046 ascii(Int2Str(i
+1, "p%d", buf
)));
1047 padd("draw:style-name", sXML_CDATA
,
1048 ascii(Int2Str(i
, "master%d", buf
)));
1049 rstartEl("style:master-page", mxList
.get());
1052 if( aSet
[i
].bIsSet
) /* If you've changed the current setting */
1054 if( !aSet
[i
].pagenumber
){
1055 if( pPrevSet
&& pPrevSet
->pagenumber
)
1056 aSet
[i
].pagenumber
= pPrevSet
->pagenumber
;
1058 if( aSet
[i
].pagenumber
)
1060 if( aSet
[i
].pagenumber
->where
== 7 && aSet
[i
].header
)
1062 aSet
[i
].header_even
= aSet
[i
].header
;
1063 aSet
[i
].header_odd
= aSet
[i
].header
;
1064 aSet
[i
].header
= nullptr;
1066 if( aSet
[i
].pagenumber
->where
== 8 && aSet
[i
].footer
)
1068 aSet
[i
].footer_even
= aSet
[i
].footer
;
1069 aSet
[i
].footer_odd
= aSet
[i
].footer
;
1070 aSet
[i
].footer
= nullptr;
1074 if( !aSet
[i
].header_even
&& pPrevSet
&& pPrevSet
->header_even
)
1076 aSet
[i
].header_even
= pPrevSet
->header_even
;
1078 if( !aSet
[i
].header_odd
&& pPrevSet
&& pPrevSet
->header_odd
)
1080 aSet
[i
].header_odd
= pPrevSet
->header_odd
;
1082 if( !aSet
[i
].footer_even
&& pPrevSet
&& pPrevSet
->footer_even
)
1084 aSet
[i
].footer_even
= pPrevSet
->footer_even
;
1086 if( !aSet
[i
].footer_odd
&& pPrevSet
&& pPrevSet
->footer_odd
)
1088 aSet
[i
].footer_odd
= pPrevSet
->footer_odd
;
1092 pPrevSet
= &aSet
[i
];
1094 else if( pPrevSet
) /* If the previous setting exists */
1098 else /* If the previous settings doesn't exist, set to the default settings */
1100 rstartEl("style:header", mxList
.get());
1101 padd("text:style-name", sXML_CDATA
, "Standard");
1102 rstartEl("text:p", mxList
.get());
1105 rendEl("style:header");
1107 rstartEl("style:footer", mxList
.get());
1108 padd("text:style-name", sXML_CDATA
, "Standard");
1109 rstartEl("text:p", mxList
.get());
1112 rendEl("style:footer");
1114 rendEl("style:master-page");
1121 rstartEl("style:header", mxList
.get());
1122 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
< 4 )
1124 d
->bInHeader
= true;
1125 d
->pPn
= pPage
->pagenumber
;
1127 parsePara(pPage
->header
->plist
.front().get());
1128 d
->bInHeader
= false;
1130 rendEl("style:header");
1132 if( pPage
->header_even
)
1134 rstartEl("style:header", mxList
.get());
1135 if( pPage
->pagenumber
&& ( pPage
->pagenumber
->where
< 4
1136 || pPage
->pagenumber
->where
== 7 ) )
1138 d
->bInHeader
= true;
1139 d
->pPn
= pPage
->pagenumber
;
1142 parsePara(pPage
->header_even
->plist
.front().get());
1143 d
->bInHeader
= false;
1146 rendEl("style:header");
1148 /* Will be the default. */
1149 else if (pPage
->header_odd
)
1151 rstartEl("style:header", mxList
.get());
1152 padd("text:style-name", sXML_CDATA
, "Standard");
1153 rstartEl("text:p", mxList
.get());
1155 if( pPage
->pagenumber
&& ( pPage
->pagenumber
->where
< 4 ||
1156 pPage
->pagenumber
->where
== 7 ) )
1158 d
->pPn
= pPage
->pagenumber
;
1165 rendEl("style:header");
1167 if( pPage
->header_odd
)
1169 rstartEl("style:header-left", mxList
.get());
1170 if( pPage
->pagenumber
&& ( pPage
->pagenumber
->where
< 4
1171 || pPage
->pagenumber
->where
== 7 ) )
1173 d
->bInHeader
= true;
1175 d
->pPn
= pPage
->pagenumber
;
1177 parsePara(pPage
->header_odd
->plist
.front().get());
1178 d
->bInHeader
= false;
1181 rendEl("style:header-left");
1183 /* Will be the default. */
1184 else if (pPage
->header_even
)
1186 rstartEl("style:header-left", mxList
.get());
1187 padd("text:style-name", sXML_CDATA
, "Standard");
1188 rstartEl("text:p", mxList
.get());
1190 if( pPage
->pagenumber
&& ( pPage
->pagenumber
->where
< 4 ||
1191 pPage
->pagenumber
->where
== 7 ) )
1193 d
->pPn
= pPage
->pagenumber
;
1200 rendEl("style:header-left");
1202 if( !pPage
->header
&& !pPage
->header_even
&& !pPage
->header_odd
)
1204 rstartEl("style:header", mxList
.get());
1205 padd("text:style-name", sXML_CDATA
, "Standard");
1206 rstartEl("text:p", mxList
.get());
1208 if( pPage
->pagenumber
&& (pPage
->pagenumber
->where
< 4 ||
1209 pPage
->pagenumber
->where
== 7 ) )
1211 d
->pPn
= pPage
->pagenumber
;
1216 rendEl("style:header");
1221 rstartEl("style:footer", mxList
.get());
1222 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1223 && pPage
->pagenumber
->where
!= 7 )
1225 d
->bInHeader
= true;
1226 d
->pPn
= pPage
->pagenumber
;
1228 parsePara(pPage
->footer
->plist
.front().get());
1229 d
->bInHeader
= false;
1231 rendEl("style:footer");
1233 if( pPage
->footer_even
)
1235 rstartEl("style:footer", mxList
.get());
1236 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1237 && pPage
->pagenumber
->where
!= 7 )
1239 d
->bInHeader
= true;
1240 d
->pPn
= pPage
->pagenumber
;
1243 parsePara(pPage
->footer_even
->plist
.front().get());
1244 d
->bInHeader
= false;
1247 rendEl("style:footer");
1249 /* Will be the default. */
1250 else if (pPage
->footer_odd
)
1252 rstartEl("style:footer", mxList
.get());
1253 padd("text:style-name", sXML_CDATA
, "Standard");
1254 rstartEl("text:p", mxList
.get());
1256 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1257 && pPage
->pagenumber
->where
!= 7 )
1259 d
->pPn
= pPage
->pagenumber
;
1266 rendEl("style:footer");
1268 if( pPage
->footer_odd
)
1270 rstartEl("style:footer-left", mxList
.get());
1271 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1272 && pPage
->pagenumber
->where
!= 7 )
1274 d
->bInHeader
= true;
1275 d
->pPn
= pPage
->pagenumber
;
1278 parsePara(pPage
->footer_odd
->plist
.front().get());
1279 d
->bInHeader
= false;
1282 rendEl("style:footer-left");
1284 /* Will be the default. */
1285 else if (pPage
->footer_even
)
1287 rstartEl("style:footer-left", mxList
.get());
1288 padd("text:style-name", sXML_CDATA
, "Standard");
1289 rstartEl("text:p", mxList
.get());
1291 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1292 && pPage
->pagenumber
->where
!= 7 )
1294 d
->pPn
= pPage
->pagenumber
;
1301 rendEl("style:footer-left");
1303 if( !pPage
->footer
&& !pPage
->footer_even
&& !pPage
->footer_odd
)
1305 rstartEl("style:footer", mxList
.get());
1306 padd("text:style-name", sXML_CDATA
, "Standard");
1307 rstartEl("text:p", mxList
.get());
1309 if( pPage
->pagenumber
&& pPage
->pagenumber
->where
>= 4
1310 && pPage
->pagenumber
->where
!= 7 )
1312 d
->pPn
= pPage
->pagenumber
;
1317 rendEl("style:footer");
1320 rendEl("style:master-page");
1322 rendEl("office:master-styles");
1327 * Create the properties for text styles.
1328 * 1. fo:font-size, fo:font-family, fo:letter-spacing, fo:color,
1329 * style:text-background-color, fo:font-style, fo:font-weight,
1330 * style:text-underline,style:text-outline,fo:text-shadow,style:text-position
1333 void HwpReader::parseCharShape(CharShape
const * cshape
)
1335 HWPFont
& hwpfont
= hwpfile
.GetHWPFont();
1337 padd("fo:font-size", sXML_CDATA
,
1338 ascii(Int2Str(cshape
->size
/ 25, "%dpt", buf
)));
1339 padd("style:font-size-asian", sXML_CDATA
,
1340 ascii(Int2Str(cshape
->size
/ 25, "%dpt", buf
)));
1342 ::std::string
const tmp
= hstr2ksstr(kstr2hstr(
1343 reinterpret_cast<unsigned char const *>(hwpfont
.GetFontName(0, cshape
->font
[0]))).c_str());
1344 double fRatio
= 1.0;
1345 int size
= getRepFamilyName(tmp
.c_str(), buf
, fRatio
);
1347 padd("fo:font-family", sXML_CDATA
,
1348 OUString(buf
, size
, RTL_TEXTENCODING_EUC_KR
));
1349 padd("style:font-family-asian", sXML_CDATA
,
1350 OUString(buf
, size
, RTL_TEXTENCODING_EUC_KR
));
1352 padd("style:text-scale", sXML_CDATA
,
1353 ascii(Int2Str(static_cast<int>(cshape
->ratio
[0] * fRatio
), "%d%%", buf
)));
1355 double sspace
= (cshape
->size
/ 25) * cshape
->space
[0] / 100.;
1359 padd("fo:letter-spacing", sXML_CDATA
,
1360 Double2Str(sspace
) + "pt");
1362 if (cshape
->color
[1] != 0)
1363 padd("fo:color", sXML_CDATA
,
1364 ascii(hcolor2str(cshape
->color
[1], 100, buf
, true)));
1365 if (cshape
->shade
!= 0)
1366 padd("style:text-background-color", sXML_CDATA
,
1367 ascii(hcolor2str(cshape
->color
[0], cshape
->shade
, buf
)));
1368 if (cshape
->attr
& 0x01)
1370 padd("fo:font-style", sXML_CDATA
, "italic");
1371 padd("style:font-style-asian", sXML_CDATA
, "italic");
1374 padd("fo:font-style", sXML_CDATA
, "normal");
1375 padd("style:font-style-asian", sXML_CDATA
, "normal");
1377 if (cshape
->attr
>> 1 & 0x01)
1379 padd("fo:font-weight", sXML_CDATA
, "bold");
1380 padd("style:font-weight-asian", sXML_CDATA
, "bold");
1383 padd("fo:font-weight", sXML_CDATA
, "normal");
1384 padd("style:font-weight-asian", sXML_CDATA
, "normal");
1386 if (cshape
->attr
>> 2 & 0x01)
1387 padd("style:text-underline", sXML_CDATA
, "single");
1388 if (cshape
->attr
>> 3 & 0x01)
1389 padd("style:text-outline", sXML_CDATA
, "true");
1390 if (cshape
->attr
>> 4 & 0x01)
1391 padd("fo:text-shadow", sXML_CDATA
, "1pt 1pt");
1392 if (cshape
->attr
>> 5 & 0x01)
1393 padd("style:text-position", sXML_CDATA
, "super 58%");
1394 if (cshape
->attr
>> 6 & 0x01)
1395 padd("style:text-position", sXML_CDATA
, "sub 58%");
1401 * Create the properties that correspond to the real Paragraph.
1402 * 1. fo:margin-left,fo:margin-right,fo:margin-top, fo:margin-bottom,
1403 * fo:text-indent, fo:line-height, fo:text-align, fo:border
1405 * TODO: Tab Settings => set values of properties only which doesn't have the default value
1407 void HwpReader::parseParaShape(ParaShape
const * pshape
)
1410 if (pshape
->left_margin
!= 0)
1411 padd("fo:margin-left", sXML_CDATA
, Double2Str
1412 (WTI(pshape
->left_margin
)) + "inch");
1413 if (pshape
->right_margin
!= 0)
1414 padd("fo:margin-right", sXML_CDATA
, Double2Str
1415 (WTI(pshape
->right_margin
)) + "inch");
1416 if (pshape
->pspacing_prev
!= 0)
1417 padd("fo:margin-top", sXML_CDATA
, Double2Str
1418 (WTI(pshape
->pspacing_prev
)) + "inch");
1419 if (pshape
->pspacing_next
!= 0)
1420 padd("fo:margin-bottom", sXML_CDATA
, Double2Str
1421 (WTI(pshape
->pspacing_next
)) + "inch");
1422 if (pshape
->indent
!= 0)
1423 padd("fo:text-indent", sXML_CDATA
, Double2Str
1424 (WTI(pshape
->indent
)) + "inch");
1425 if (pshape
->lspacing
!= 0)
1426 padd("fo:line-height", sXML_CDATA
,
1427 ascii(Int2Str (pshape
->lspacing
, "%d%%", buf
)));
1429 unsigned char set_align
= 0;
1431 switch (static_cast<int>(pshape
->arrange_type
))
1434 strcpy(buf
, "start");
1442 strcpy(buf
, "center");
1448 strcpy(buf
, "justify");
1454 padd("fo:text-align", sXML_CDATA
, ascii(buf
));
1456 if (pshape
->outline
)
1457 padd("fo:border", sXML_CDATA
, "0.002cm solid #000000");
1458 if( pshape
->shade
> 0 )
1460 padd("fo:background-color", sXML_CDATA
,
1461 ascii(hcolor2str(0, pshape
->shade
, buf
)));
1464 if( pshape
->pagebreak
& 0x02 || pshape
->pagebreak
& 0x04)
1465 padd("fo:break-before", sXML_CDATA
, "page");
1466 else if( pshape
->pagebreak
& 0x01 )
1467 padd("fo:break-before", sXML_CDATA
, "column");
1473 * Make the style of the Paragraph.
1475 void HwpReader::makePStyle(ParaShape
const * pshape
)
1477 int nscount
= pshape
->tabs
[MAXTABS
-1].type
;
1478 padd("style:name", sXML_CDATA
,
1479 ascii(Int2Str(pshape
->index
, "P%d", buf
)));
1480 padd("style:family", sXML_CDATA
, "paragraph");
1481 rstartEl("style:style", mxList
.get());
1483 parseParaShape(pshape
);
1484 parseCharShape(pshape
->cshape
.get());
1485 rstartEl("style:properties", mxList
.get());
1490 unsigned char tf
= 0;
1491 rstartEl("style:tab-stops",mxList
.get());
1493 int tab_margin
= pshape
->left_margin
+ pshape
->indent
;
1494 if( tab_margin
< 0 )
1496 for( int i
= 0 ; i
< MAXTABS
-1 ; i
++)
1498 if( i
> 0 && pshape
->tabs
[i
].position
== 0. )
1500 if( pshape
->tabs
[i
].position
<= tab_margin
)
1502 padd("style:position", sXML_CDATA
,
1503 Double2Str(WTMM(pshape
->tabs
[i
].position
- tab_margin
)) + "mm");
1504 if( pshape
->tabs
[i
].type
)
1507 switch(pshape
->tabs
[i
].type
)
1510 padd("style:type", sXML_CDATA
, "right");
1513 padd("style:type", sXML_CDATA
, "center");
1516 padd("style:type", sXML_CDATA
, "char");
1517 padd("style:char", sXML_CDATA
, ".");
1521 if( pshape
->tabs
[i
].dot_continue
)
1524 padd("style:leader-char", sXML_CDATA
, ".");
1526 rstartEl( "style:tab-stop", mxList
.get());
1528 rendEl( "style:tab-stop" );
1530 if( (pshape
->tabs
[i
].position
!= 1000 * i
) || tf
)
1532 if( !--nscount
) break;
1535 rendEl( "style:tab-stops");
1537 rendEl("style:properties");
1538 rendEl("style:style");
1543 * Create a style for the page. This includes the header/footer, footnote and more.
1544 * TODO: fo: background-color (no information)
1546 void HwpReader::makePageStyle()
1548 HWPInfo
& hwpinfo
= hwpfile
.GetHWPInfo();
1549 int pmCount
= hwpfile
.getColumnCount();
1551 for( int i
= 0 ; i
< pmCount
; i
++ ){
1552 padd("style:name", sXML_CDATA
, ascii(Int2Str(i
+ 1, "pm%d", buf
)));
1553 rstartEl("style:page-master",mxList
.get());
1557 switch( hwpinfo
.paper
.paper_kind
)
1560 if( hwpinfo
.paper
.paper_direction
)
1562 padd("fo:page-height",sXML_CDATA
, "210mm");
1563 padd("fo:page-width",sXML_CDATA
, "297mm");
1567 padd("fo:page-width",sXML_CDATA
, "210mm");
1568 padd("fo:page-height",sXML_CDATA
, "297mm");
1571 case 4: // 80 column
1572 if( hwpinfo
.paper
.paper_direction
)
1574 padd("fo:page-height",sXML_CDATA
, "8.5inch");
1575 padd("fo:page-width",sXML_CDATA
, "11inch");
1579 padd("fo:page-width",sXML_CDATA
, "8.5inch");
1580 padd("fo:page-height",sXML_CDATA
, "11inch");
1584 if( hwpinfo
.paper
.paper_direction
)
1586 padd("fo:page-height",sXML_CDATA
, "176mm");
1587 padd("fo:page-width",sXML_CDATA
, "250mm");
1591 padd("fo:page-width",sXML_CDATA
, "176mm");
1592 padd("fo:page-height",sXML_CDATA
, "250mm");
1596 if( hwpinfo
.paper
.paper_direction
)
1598 padd("fo:page-height",sXML_CDATA
, "250mm");
1599 padd("fo:page-width",sXML_CDATA
, "353mm");
1603 padd("fo:page-width",sXML_CDATA
, "250mm");
1604 padd("fo:page-height",sXML_CDATA
, "353mm");
1608 if( hwpinfo
.paper
.paper_direction
)
1610 padd("fo:page-height",sXML_CDATA
, "8.5inch");
1611 padd("fo:page-width",sXML_CDATA
, "14inch");
1615 padd("fo:page-width",sXML_CDATA
, "8.5inch");
1616 padd("fo:page-height",sXML_CDATA
, "14inch");
1620 if( hwpinfo
.paper
.paper_direction
)
1622 padd("fo:page-height",sXML_CDATA
, "297mm");
1623 padd("fo:page-width",sXML_CDATA
, "420mm");
1627 padd("fo:page-width",sXML_CDATA
, "297mm");
1628 padd("fo:page-height",sXML_CDATA
, "420mm");
1635 if( hwpinfo
.paper
.paper_direction
)
1637 padd("fo:page-width",sXML_CDATA
,
1638 Double2Str(WTI(hwpinfo
.paper
.paper_height
)) + "inch");
1639 padd("fo:page-height",sXML_CDATA
,
1640 Double2Str(WTI(hwpinfo
.paper
.paper_width
)) + "inch");
1644 padd("fo:page-width",sXML_CDATA
,
1645 Double2Str(WTI(hwpinfo
.paper
.paper_width
)) + "inch");
1646 padd("fo:page-height",sXML_CDATA
,
1647 Double2Str(WTI(hwpinfo
.paper
.paper_height
)) + "inch");
1653 padd("style:print-orientation",sXML_CDATA
,
1654 ascii(hwpinfo
.paper
.paper_direction
? "landscape" : "portrait"));
1655 if( hwpinfo
.beginpagenum
!= 1)
1656 padd("style:first-page-number",sXML_CDATA
,
1657 ascii(Int2Str(hwpinfo
.beginpagenum
, "%d", buf
)));
1659 if( hwpinfo
.borderline
){
1660 padd("fo:margin-left",sXML_CDATA
,
1661 Double2Str(WTI(hwpinfo
.paper
.left_margin
- hwpinfo
.bordermargin
[0] + hwpinfo
.paper
.gutter_length
)) + "inch");
1662 padd("fo:margin-right",sXML_CDATA
,
1663 Double2Str(WTI(hwpinfo
.paper
.right_margin
- hwpinfo
.bordermargin
[1])) + "inch");
1664 padd("fo:margin-top",sXML_CDATA
,
1665 Double2Str(WTI(hwpinfo
.paper
.top_margin
- hwpinfo
.bordermargin
[2])) + "inch");
1666 padd("fo:margin-bottom",sXML_CDATA
,
1667 Double2Str(WTI(hwpinfo
.paper
.bottom_margin
- hwpinfo
.bordermargin
[3])) + "inch");
1670 padd("fo:margin-left",sXML_CDATA
,
1671 Double2Str(WTI(hwpinfo
.paper
.left_margin
+ hwpinfo
.paper
.gutter_length
)) + "inch");
1672 padd("fo:margin-right",sXML_CDATA
,
1673 Double2Str(WTI(hwpinfo
.paper
.right_margin
)) + "inch");
1674 padd("fo:margin-top",sXML_CDATA
,
1675 Double2Str(WTI(hwpinfo
.paper
.top_margin
)) + "inch");
1676 padd("fo:margin-bottom",sXML_CDATA
,
1677 Double2Str(WTI(hwpinfo
.paper
.bottom_margin
)) + "inch");
1680 switch( hwpinfo
.borderline
)
1683 padd("fo:border", sXML_CDATA
,"0.002cm solid #000000");
1686 padd("fo:border", sXML_CDATA
,"0.002cm dotted #000000");
1689 padd("fo:border", sXML_CDATA
,"0.035cm solid #000000");
1692 padd("style:border-line-width", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1693 padd("fo:border", sXML_CDATA
,"0.039cm double #000000");
1697 padd("fo:padding-left", sXML_CDATA
,
1698 Double2Str(WTI(hwpinfo
.bordermargin
[0])) + "inch");
1699 padd("fo:padding-right", sXML_CDATA
,
1700 Double2Str(WTI(hwpinfo
.bordermargin
[1])) + "inch");
1701 padd("fo:padding-top", sXML_CDATA
,
1702 Double2Str(WTI(hwpinfo
.bordermargin
[2])) + "inch");
1703 padd("fo:padding-bottom", sXML_CDATA
,
1704 Double2Str(WTI(hwpinfo
.bordermargin
[3])) + "inch");
1706 /* background color */
1707 if( hwpinfo
.back_info
.isset
)
1709 if( hwpinfo
.back_info
.color
[0] > 0 || hwpinfo
.back_info
.color
[1] > 0
1710 || hwpinfo
.back_info
.color
[2] > 0 ){
1711 sprintf(buf
,"#%02x%02x%02x",hwpinfo
.back_info
.color
[0],
1712 hwpinfo
.back_info
.color
[1],hwpinfo
.back_info
.color
[2] );
1713 padd("fo:background-color", sXML_CDATA
, ascii(buf
));
1717 rstartEl("style:properties",mxList
.get());
1720 /* background image */
1721 if( hwpinfo
.back_info
.isset
&& hwpinfo
.back_info
.type
> 0 )
1723 if( hwpinfo
.back_info
.type
== 1 ){
1725 padd("xlink:href", sXML_CDATA
,
1726 reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr(reinterpret_cast<uchar
const *>(urltowin(hwpinfo
.back_info
.filename
).c_str())).c_str())));
1728 padd("xlink:href", sXML_CDATA
,
1729 reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr( reinterpret_cast<uchar
const *>(urltounix(hwpinfo
.back_info
.filename
).c_str())).c_str())));
1731 padd("xlink:type", sXML_CDATA
, "simple");
1732 padd("xlink:actuate", sXML_CDATA
, "onLoad");
1734 if( hwpinfo
.back_info
.flag
>= 2)
1735 padd("style:repeat", sXML_CDATA
, "stretch");
1736 else if( hwpinfo
.back_info
.flag
== 1 ){
1737 padd("style:repeat", sXML_CDATA
, "no-repeat");
1738 padd("style:position", sXML_CDATA
, "center");
1740 rstartEl("style:background-image",mxList
.get());
1742 if( hwpinfo
.back_info
.type
== 2 ){
1743 rstartEl("office:binary-data", mxList
.get());
1745 std::shared_ptr
<char> pStr(base64_encode_string(reinterpret_cast<unsigned char *>(hwpinfo
.back_info
.data
.data()), hwpinfo
.back_info
.size
), Free
<char>());
1746 rchars(ascii(pStr
.get()));
1747 rendEl("office:binary-data");
1749 rendEl("style:background-image");
1752 makeColumns( hwpfile
.GetColumnDef(i
) );
1754 rendEl("style:properties");
1757 rstartEl("style:header-style", mxList
.get());
1758 padd("svg:height", sXML_CDATA
,
1759 Double2Str(WTI(hwpinfo
.paper
.header_length
)) + "inch");
1760 padd("fo:margin-bottom", sXML_CDATA
, "0mm");
1762 rstartEl("style:properties",mxList
.get());
1764 rendEl("style:properties");
1765 rendEl("style:header-style");
1768 rstartEl("style:footer-style", mxList
.get());
1769 padd("svg:height", sXML_CDATA
,
1770 Double2Str(WTI(hwpinfo
.paper
.footer_length
)) + "inch");
1771 padd("fo:margin-top", sXML_CDATA
, "0mm");
1772 rstartEl("style:properties",mxList
.get());
1774 rendEl("style:properties");
1775 rendEl("style:footer-style");
1777 /* Footnote style, but it fell in the dtd, the specification has been defined. REALKING */
1778 rstartEl("style:footnote-layout", mxList
.get());
1780 padd("style:distance-before-sep", sXML_CDATA
,
1781 Double2Str(WTI(hwpinfo
.splinetext
)) + "inch");
1782 padd("style:distance-after-sep", sXML_CDATA
,
1783 Double2Str(WTI(hwpinfo
.splinefn
)) + "inch");
1784 rstartEl("style:properties",mxList
.get());
1786 rendEl("style:properties");
1787 if ( hwpinfo
.fnlinetype
== 2 )
1788 padd("style:width", sXML_CDATA
, "15cm");
1789 else if ( hwpinfo
.fnlinetype
== 1)
1790 padd("style:width", sXML_CDATA
, "2cm");
1791 else if ( hwpinfo
.fnlinetype
== 3)
1792 padd("style:width", sXML_CDATA
, "0cm");
1794 padd("style:width", sXML_CDATA
, "5cm");
1796 rstartEl("style:footnote-sep",mxList
.get());
1798 rendEl("style:footnote-sep");
1800 rendEl("style:footnote-layout");
1802 rendEl("style:page-master");
1806 void HwpReader::makeColumns(ColumnDef
const *coldef
)
1808 if( !coldef
) return;
1809 padd("fo:column-count", sXML_CDATA
, ascii(Int2Str(coldef
->ncols
, "%d", buf
)));
1810 rstartEl("style:columns",mxList
.get());
1812 if( coldef
->separator
!= 0 )
1814 switch( coldef
->separator
)
1816 case 1: /* thin line */
1817 padd("style:width", sXML_CDATA
, "0.02mm");
1819 case 3: /* dotted line */
1820 padd("style:style", sXML_CDATA
, "dotted");
1821 padd("style:width", sXML_CDATA
, "0.02mm");
1823 case 2: /* thick line */
1824 case 4: /* double line */
1825 padd("style:width", sXML_CDATA
, "0.35mm");
1829 padd("style:style", sXML_CDATA
, "none");
1832 rstartEl("style:column-sep",mxList
.get());
1834 rendEl("style:column-sep");
1836 double spacing
= WTI(coldef
->spacing
)/ 2. ;
1837 for(int ii
= 0 ; ii
< coldef
->ncols
; ii
++)
1840 padd("fo:margin-left", sXML_CDATA
, "0mm");
1842 padd("fo:margin-left", sXML_CDATA
,
1843 Double2Str( spacing
) + "inch");
1844 if( ii
== ( coldef
->ncols
-1) )
1845 padd("fo:margin-right", sXML_CDATA
,"0mm");
1847 padd("fo:margin-right", sXML_CDATA
,
1848 Double2Str( spacing
) + "inch");
1849 rstartEl("style:column",mxList
.get());
1851 rendEl("style:column");
1853 rendEl("style:columns");
1856 void HwpReader::makeTStyle(CharShape
const * cshape
)
1858 padd("style:name", sXML_CDATA
,
1859 ascii(Int2Str(cshape
->index
, "T%d", buf
)));
1860 padd("style:family", sXML_CDATA
, "text");
1861 rstartEl("style:style", mxList
.get());
1863 parseCharShape(cshape
);
1864 rstartEl("style:properties", mxList
.get());
1866 rendEl("style:properties");
1867 rendEl("style:style");
1871 void HwpReader::makeTableStyle(Table
*tbl
)
1874 TxtBox
*hbox
= tbl
->box
;
1876 padd("style:name", sXML_CDATA
,
1877 ascii(Int2Str(hbox
->style
.boxnum
, "Table%d", buf
)));
1878 padd("style:family", sXML_CDATA
,"table");
1879 rstartEl("style:style", mxList
.get());
1881 padd("style:width", sXML_CDATA
,
1882 Double2Str(WTMM(hbox
->box_xs
)) + "mm");
1883 padd("table:align", sXML_CDATA
,"left");
1884 padd("fo:keep-with-next", sXML_CDATA
,"false");
1885 rstartEl("style:properties", mxList
.get());
1887 rendEl("style:properties");
1888 rendEl("style:style");
1891 for (size_t i
= 0 ; i
< tbl
->columns
.nCount
-1 ; i
++)
1893 sprintf(buf
,"Table%d.%c",hbox
->style
.boxnum
, static_cast<char>('A'+i
));
1894 padd("style:name", sXML_CDATA
, ascii( buf
));
1895 padd("style:family", sXML_CDATA
,"table-column");
1896 rstartEl("style:style", mxList
.get());
1898 padd("style:column-width", sXML_CDATA
,
1899 Double2Str(WTMM(tbl
->columns
.data
[i
+1] - tbl
->columns
.data
[i
])) + "mm");
1900 rstartEl("style:properties", mxList
.get());
1902 rendEl("style:properties");
1903 rendEl("style:style");
1907 for (size_t i
= 0 ; i
< tbl
->rows
.nCount
-1 ; i
++)
1909 sprintf(buf
,"Table%d.row%" SAL_PRI_SIZET
"u",hbox
->style
.boxnum
, i
+ 1);
1910 padd("style:name", sXML_CDATA
, ascii( buf
));
1911 padd("style:family", sXML_CDATA
,"table-row");
1912 rstartEl("style:style", mxList
.get());
1914 padd("style:row-height", sXML_CDATA
,
1915 Double2Str(WTMM(tbl
->rows
.data
[i
+1] - tbl
->rows
.data
[i
])) + "mm");
1916 rstartEl("style:properties", mxList
.get());
1918 rendEl("style:properties");
1919 rendEl("style:style");
1923 for (auto const& tcell
: tbl
->cells
)
1925 sprintf(buf
,"Table%d.%c%d",hbox
->style
.boxnum
, 'A'+ tcell
->nColumnIndex
, tcell
->nRowIndex
+1);
1926 padd("style:name", sXML_CDATA
, ascii( buf
));
1927 padd("style:family", sXML_CDATA
,"table-cell");
1928 rstartEl("style:style", mxList
.get());
1930 Cell
*cl
= tcell
->pCell
;
1931 if( cl
->ver_align
== 1 )
1932 padd("fo:vertical-align", sXML_CDATA
,"middle");
1934 if(cl
->linetype
[2] == cl
->linetype
[3] && cl
->linetype
[2] == cl
->linetype
[0]
1935 && cl
->linetype
[2] == cl
->linetype
[1])
1937 switch( cl
->linetype
[2] )
1939 case 1: /* A thin solid line */
1940 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
1941 padd("fo:border", sXML_CDATA
,"0.002cm solid #000000");
1943 case 2: /* Bold lines */
1944 padd("fo:border", sXML_CDATA
,"0.035cm solid #000000");
1946 case 4: /* Double line */
1947 padd("style:border-line-width", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1948 padd("fo:border", sXML_CDATA
,"0.039cm double #000000");
1954 switch( cl
->linetype
[0] )
1956 case 1: /* A thin solid line */
1957 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
1958 padd("fo:border-left", sXML_CDATA
,"0.002cm solid #000000");
1960 case 2: /* Bold lines */
1961 padd("fo:border-left", sXML_CDATA
,"0.035cm solid #000000");
1963 case 4: /* Double line */
1964 padd("style:border-line-width-left", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1965 padd("fo:border-left", sXML_CDATA
,"0.039cm double #000000");
1968 switch( cl
->linetype
[1] )
1970 case 1: /* A thin solid line */
1971 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
1972 padd("fo:border-right", sXML_CDATA
,"0.002cm solid #000000");
1974 case 2: /* Bold lines */
1975 padd("fo:border-right", sXML_CDATA
,"0.035cm solid #000000");
1977 case 4: /* Double line */
1978 padd("style:border-line-width-right", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1979 padd("fo:border-right", sXML_CDATA
,"0.039cm double #000000");
1982 switch( cl
->linetype
[2] )
1984 case 1: /* A thin solid line */
1985 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
1986 padd("fo:border-top", sXML_CDATA
,"0.002cm solid #000000");
1988 case 2: /* Bold lines */
1989 padd("fo:border-top", sXML_CDATA
,"0.035cm solid #000000");
1991 case 4: /* Double line */
1992 padd("style:border-line-width-top", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
1993 padd("fo:border-top", sXML_CDATA
,"0.039cm double #000000");
1996 switch( cl
->linetype
[3] )
1998 case 1: /* A thin solid line */
1999 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2000 padd("fo:border-bottom", sXML_CDATA
,"0.002cm solid #000000");
2002 case 2: /* Bold lines */
2003 padd("fo:border-bottom", sXML_CDATA
,"0.035cm solid #000000");
2005 case 4: /* Double line */
2006 padd("style:border-line-width-bottom", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2007 padd("fo:border-bottom", sXML_CDATA
,"0.039cm double #000000");
2012 padd("fo:background-color", sXML_CDATA
,
2013 ascii(hcolor2str(sal::static_int_cast
<uchar
>(cl
->color
),
2014 sal::static_int_cast
<uchar
>(cl
->shade
), buf
)));
2016 rstartEl("style:properties", mxList
.get());
2018 rendEl("style:properties");
2020 rendEl("style:style");
2025 void HwpReader::makeDrawStyle( HWPDrawingObject
* hdo
, FBoxStyle
* fstyle
)
2029 padd("style:name", sXML_CDATA
,
2030 ascii(Int2Str(hdo
->index
, "Draw%d", buf
)));
2031 padd("style:family", sXML_CDATA
, "graphics");
2033 rstartEl("style:style", mxList
.get());
2036 switch (fstyle
->txtflow
)
2041 padd("style:wrap", sXML_CDATA
, "run-through");
2044 padd("style:wrap", sXML_CDATA
, "dynamic");
2049 if( hdo
->property
.line_color
> 0xffffff )
2051 padd("draw:stroke", sXML_CDATA
, "none" );
2056 if( hdo
->property
.line_pstyle
== 0 )
2057 padd("draw:stroke", sXML_CDATA
, "solid" );
2058 else if( hdo
->property
.line_pstyle
< 5 )
2060 padd("draw:stroke", sXML_CDATA
, "dash" );
2061 padd("draw:stroke-dash", sXML_CDATA
,
2062 ascii(Int2Str(hdo
->index
, "LineType%d", buf
)));
2064 padd("svg:stroke-width", sXML_CDATA
,
2065 Double2Str( WTMM(hdo
->property
.line_width
)) + "mm");
2066 color
= hdo
->property
.line_color
;
2067 sprintf( buf
, "#%02x%02x%02x",
2068 sal_uInt16(color
& 0xff),
2069 sal_uInt16((color
>> 8) & 0xff),
2070 sal_uInt16((color
>>16) & 0xff) );
2071 padd("svg:stroke-color", sXML_CDATA
, ascii( buf
) );
2074 if( hdo
->type
== HWPDO_LINE
|| hdo
->type
== HWPDO_ARC
||
2075 hdo
->type
== HWPDO_FREEFORM
|| hdo
->type
== HWPDO_ADVANCED_ARC
)
2078 if( hdo
->property
.line_tstyle
> 0 )
2080 padd("draw:marker-start", sXML_CDATA
,
2081 ascii(ArrowShape
[hdo
->property
.line_tstyle
].name
) );
2082 if( hdo
->property
.line_width
> 100 )
2083 padd("draw:marker-start-width", sXML_CDATA
,
2084 Double2Str( WTMM(hdo
->property
.line_width
* 3)) + "mm");
2085 else if( hdo
->property
.line_width
> 80 )
2086 padd("draw:marker-start-width", sXML_CDATA
,
2087 Double2Str( WTMM(hdo
->property
.line_width
* 4)) + "mm");
2088 else if( hdo
->property
.line_width
> 60 )
2089 padd("draw:marker-start-width", sXML_CDATA
,
2090 Double2Str( WTMM(hdo
->property
.line_width
* 5)) + "mm");
2091 else if( hdo
->property
.line_width
> 40 )
2092 padd("draw:marker-start-width", sXML_CDATA
,
2093 Double2Str( WTMM(hdo
->property
.line_width
* 6)) + "mm");
2095 padd("draw:marker-start-width", sXML_CDATA
,
2096 Double2Str( WTMM(hdo
->property
.line_width
* 7)) + "mm");
2099 if( hdo
->property
.line_hstyle
> 0 )
2101 padd("draw:marker-end", sXML_CDATA
,
2102 ascii(ArrowShape
[hdo
->property
.line_hstyle
].name
) );
2103 if( hdo
->property
.line_width
> 100 )
2104 padd("draw:marker-end-width", sXML_CDATA
,
2105 Double2Str( WTMM(hdo
->property
.line_width
* 3)) + "mm");
2106 else if( hdo
->property
.line_width
> 80 )
2107 padd("draw:marker-end-width", sXML_CDATA
,
2108 Double2Str( WTMM(hdo
->property
.line_width
* 4)) + "mm");
2109 else if( hdo
->property
.line_width
> 60 )
2110 padd("draw:marker-end-width", sXML_CDATA
,
2111 Double2Str( WTMM(hdo
->property
.line_width
* 5)) + "mm");
2112 else if( hdo
->property
.line_width
> 40 )
2113 padd("draw:marker-end-width", sXML_CDATA
,
2114 Double2Str( WTMM(hdo
->property
.line_width
* 6)) + "mm");
2116 padd("draw:marker-end-width", sXML_CDATA
,
2117 Double2Str( WTMM(hdo
->property
.line_width
* 7)) + "mm");
2121 if(hdo
->type
!= HWPDO_LINE
)
2123 if( hdo
->property
.flag
>> 19 & 0x01 )
2125 padd( "draw:textarea-horizontal-align", sXML_CDATA
, "center");
2128 color
= hdo
->property
.fill_color
;
2130 if( hdo
->property
.flag
>> 18 & 0x01 ) // bitmap pattern
2132 padd("draw:fill", sXML_CDATA
, "bitmap");
2133 padd("draw:fill-image-name", sXML_CDATA
,
2134 ascii(Int2Str(hdo
->index
, "fillimage%d", buf
)));
2136 if( hdo
->property
.flag
>> 3 & 0x01 )
2138 padd("style:repeat", sXML_CDATA
, "stretch");
2142 padd("style:repeat", sXML_CDATA
, "repeat");
2143 padd("draw:fill-image-ref-point", sXML_CDATA
, "top-left");
2145 if( hdo
->property
.flag
>> 20 & 0x01 )
2147 if( hdo
->property
.luminance
> 0 )
2149 padd("draw:transparency", sXML_CDATA
,
2150 ascii(Int2Str(hdo
->property
.luminance
, "%d%%", buf
)));
2156 else if( hdo
->property
.flag
>> 16 & 0x01 )
2158 padd("draw:fill", sXML_CDATA
, "gradient");
2159 padd("draw:fill-gradient-name", sXML_CDATA
,
2160 ascii(Int2Str(hdo
->index
, "Grad%d", buf
)));
2161 padd("draw:gradient-step-count", sXML_CDATA
,
2162 ascii(Int2Str(hdo
->property
.nstep
, "%d", buf
)));
2166 else if( hdo
->property
.pattern_type
>> 24 & 0x01 )
2168 padd("draw:fill", sXML_CDATA
, "hatch");
2169 padd("draw:fill-hatch-name", sXML_CDATA
,
2170 ascii(Int2Str(hdo
->index
, "Hatch%d", buf
)));
2171 if( color
< 0xffffff )
2173 sprintf( buf
, "#%02x%02x%02x",
2174 sal_uInt16(color
& 0xff),
2175 sal_uInt16((color
>> 8) & 0xff),
2176 sal_uInt16((color
>>16) & 0xff) );
2177 padd("draw:fill-color", sXML_CDATA
, ascii( buf
) );
2178 padd("draw:fill-hatch-solid", sXML_CDATA
, "true");
2181 else if( color
<= 0xffffff )
2183 padd("draw:fill", sXML_CDATA
, "solid");
2184 sprintf( buf
, "#%02x%02x%02x",
2185 sal_uInt16(color
& 0xff),
2186 sal_uInt16((color
>> 8) & 0xff),
2187 sal_uInt16((color
>>16) & 0xff) );
2188 padd("draw:fill-color", sXML_CDATA
, ascii( buf
) );
2191 padd("draw:fill", sXML_CDATA
, "none");
2194 if( fstyle
->anchor_type
== CHAR_ANCHOR
)
2196 padd("style:vertical-pos", sXML_CDATA
, "top");
2197 padd("style:vertical-rel", sXML_CDATA
, "baseline");
2200 rstartEl("style:properties", mxList
.get());
2202 rendEl("style:properties");
2203 rendEl("style:style");
2205 if( hdo
->type
== 0 )
2207 makeDrawStyle( hdo
->child
.get(), fstyle
);
2209 hdo
= hdo
->next
.get();
2214 void HwpReader::makeCaptionStyle(FBoxStyle
* fstyle
)
2216 padd("style:name", sXML_CDATA
,
2217 ascii(Int2Str(fstyle
->boxnum
, "CapBox%d", buf
)));
2218 padd("style:family", sXML_CDATA
, "graphics");
2219 rstartEl("style:style", mxList
.get());
2221 padd("fo:margin-left", sXML_CDATA
, "0cm");
2222 padd("fo:margin-right", sXML_CDATA
, "0cm");
2223 padd("fo:margin-top", sXML_CDATA
, "0cm");
2224 padd("fo:margin-bottom", sXML_CDATA
, "0cm");
2225 padd("fo:padding", sXML_CDATA
, "0cm");
2226 switch (fstyle
->txtflow
)
2229 padd("style:wrap", sXML_CDATA
, "none");
2232 if( fstyle
->boxtype
== 'G' )
2233 padd("style:run-through", sXML_CDATA
, "background");
2234 padd("style:wrap", sXML_CDATA
, "run-through");
2237 padd("style:wrap", sXML_CDATA
, "dynamic");
2240 if (fstyle
->anchor_type
== CHAR_ANCHOR
)
2242 padd("style:vertical-pos", sXML_CDATA
, "top");
2243 padd("style:vertical-rel", sXML_CDATA
, "baseline");
2244 padd("style:horizontal-pos", sXML_CDATA
, "center");
2245 padd("style:horizontal-rel", sXML_CDATA
, "paragraph");
2250 switch (-(fstyle
->xpos
))
2253 padd("style:horizontal-pos", sXML_CDATA
, "right");
2256 padd("style:horizontal-pos", sXML_CDATA
, "center");
2260 padd("style:horizontal-pos", sXML_CDATA
, "from-left");
2263 switch (-(fstyle
->ypos
))
2266 padd("style:vertical-pos", sXML_CDATA
, "bottom");
2269 padd("style:vertical-pos", sXML_CDATA
, "middle");
2273 padd("style:vertical-pos", sXML_CDATA
, "from-top");
2276 if ( fstyle
->anchor_type
== PARA_ANCHOR
)
2278 padd("style:vertical-rel", sXML_CDATA
, "paragraph");
2279 padd("style:horizontal-rel", sXML_CDATA
, "paragraph");
2283 padd("style:vertical-rel", sXML_CDATA
, "page-content");
2284 padd("style:horizontal-rel", sXML_CDATA
, "page-content");
2287 rstartEl("style:properties", mxList
.get());
2289 rendEl("style:properties");
2290 rendEl("style:style");
2291 if( fstyle
->boxtype
== 'G' )
2293 padd("style:name", sXML_CDATA
,
2294 ascii(Int2Str(fstyle
->boxnum
, "G%d", buf
)));
2298 padd("style:name", sXML_CDATA
,
2299 ascii(Int2Str(fstyle
->boxnum
, "Txtbox%d", buf
)));
2302 padd("style:family", sXML_CDATA
, "graphics");
2303 rstartEl("style:style", mxList
.get());
2306 padd("fo:margin-left", sXML_CDATA
, "0cm");
2307 padd("fo:margin-right", sXML_CDATA
, "0cm");
2308 padd("fo:margin-top", sXML_CDATA
, "0cm");
2309 padd("fo:margin-bottom", sXML_CDATA
, "0cm");
2310 padd("fo:padding", sXML_CDATA
, "0cm");
2311 padd("style:wrap", sXML_CDATA
, "none");
2312 padd("style:vertical-pos", sXML_CDATA
, "from-top");
2313 padd("style:vertical-rel", sXML_CDATA
, "paragraph");
2314 padd("style:horizontal-pos", sXML_CDATA
, "from-left");
2315 padd("style:horizontal-rel", sXML_CDATA
, "paragraph");
2316 if( fstyle
->boxtype
== 'G' )
2318 char *cell
= static_cast<char *>(fstyle
->cell
);
2319 padd("draw:luminance", sXML_CDATA
,
2320 ascii(Int2Str(cell
[0], "%d%%", buf
)));
2321 padd("draw:contrast", sXML_CDATA
,
2322 ascii(Int2Str(cell
[1], "%d%%", buf
)));
2324 padd("draw:color-mode", sXML_CDATA
, "standard");
2325 else if( cell
[2] == 1 )
2326 padd("draw:color-mode", sXML_CDATA
, "greyscale");
2327 else if( cell
[2] == 2 )
2328 padd("draw:color-mode", sXML_CDATA
, "mono");
2332 Cell
*cell
= static_cast<Cell
*>(fstyle
->cell
);
2333 if(cell
->linetype
[0] == cell
->linetype
[1] &&
2334 cell
->linetype
[0] == cell
->linetype
[2] &&
2335 cell
->linetype
[0] == cell
->linetype
[3])
2337 switch( cell
->linetype
[0] )
2340 padd("fo:padding", sXML_CDATA
,"0mm");
2342 case 1: /* A thin solid line */
2343 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2344 padd("fo:border", sXML_CDATA
,"0.002cm solid #000000");
2346 case 2: /* Bold lines */
2347 padd("fo:border", sXML_CDATA
,"0.035cm solid #000000");
2349 case 4: /* Double line */
2350 padd("style:border-line-width", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2351 padd("fo:border", sXML_CDATA
,"0.039cm double #000000");
2357 switch( cell
->linetype
[0] )
2359 case 1: /* A thin solid line */
2360 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2361 padd("fo:border-left", sXML_CDATA
,"0.002cm solid #000000");
2363 case 2: /* Bold lines */
2364 padd("fo:border-left", sXML_CDATA
,"0.035cm solid #000000");
2366 case 4: /* Double line */
2367 padd("style:border-line-width-left", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2368 padd("fo:border-left", sXML_CDATA
,"0.039cm double #000000");
2371 switch( cell
->linetype
[1] )
2373 case 1: /* A thin solid line */
2374 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2375 padd("fo:border-right", sXML_CDATA
,"0.002cm solid #000000");
2377 case 2: /* Bold lines */
2378 padd("fo:border-right", sXML_CDATA
,"0.035cm solid #000000");
2380 case 4: /* Double line */
2381 padd("style:border-line-width-right", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2382 padd("fo:border-right", sXML_CDATA
,"0.039cm double #000000");
2385 switch( cell
->linetype
[2] )
2387 case 1: /* A thin solid line */
2388 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2389 padd("fo:border-top", sXML_CDATA
,"0.002cm solid #000000");
2391 case 2: /* Bold lines */
2392 padd("fo:border-top", sXML_CDATA
,"0.035cm solid #000000");
2394 case 4: /* Double line */
2395 padd("style:border-line-width-top", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2396 padd("fo:border-top", sXML_CDATA
,"0.039cm double #000000");
2399 switch( cell
->linetype
[3] )
2401 case 1: /* A thin solid line */
2402 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2403 padd("fo:border-bottom", sXML_CDATA
,"0.002cm solid #000000");
2405 case 2: /* Bold lines */
2406 padd("fo:border-bottom", sXML_CDATA
,"0.035cm solid #000000");
2408 case 4: /* Double line */
2409 padd("style:border-line-width-bottom", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2410 padd("fo:border-bottom", sXML_CDATA
,"0.039cm double #000000");
2414 if(cell
->shade
!= 0)
2415 padd("fo:background-color", sXML_CDATA
, ascii(hcolor2str(
2416 sal::static_int_cast
<uchar
>(cell
->color
),
2417 sal::static_int_cast
<uchar
>(cell
->shade
), buf
)));
2419 rstartEl("style:properties", mxList
.get());
2421 rendEl("style:properties");
2422 rendEl("style:style");
2427 * Create a style for the Floating objects.
2429 void HwpReader::makeFStyle(FBoxStyle
* fstyle
)
2432 if( ( fstyle
->boxtype
== 'G' || fstyle
->boxtype
== 'X' ) && fstyle
->cap_len
> 0 )
2434 makeCaptionStyle(fstyle
);
2437 switch( fstyle
->boxtype
)
2439 case 'X' : // txtbox
2440 case 'E' : // equation
2441 case 'B' : // button
2444 padd("style:name", sXML_CDATA
,
2445 ascii(Int2Str(fstyle
->boxnum
, "Txtbox%d", buf
)));
2446 padd("style:family", sXML_CDATA
, "graphics");
2448 case 'G' : // graphics
2449 padd("style:name", sXML_CDATA
,
2450 ascii(Int2Str(fstyle
->boxnum
, "G%d", buf
)));
2451 padd("style:family", sXML_CDATA
, "graphics");
2453 case 'L' : // line TODO : all
2454 padd("style:name", sXML_CDATA
,
2455 ascii(Int2Str(fstyle
->boxnum
, "L%d", buf
)));
2456 padd( "style:family" , sXML_CDATA
, "paragraph" );
2460 rstartEl("style:style", mxList
.get());
2463 if ( fstyle
->boxtype
== 'T')
2465 padd("fo:padding", sXML_CDATA
, "0cm");
2468 if( !(fstyle
->boxtype
== 'G' && fstyle
->cap_len
> 0 ))
2470 padd("fo:margin-left", sXML_CDATA
,
2471 Double2Str(WTMM(fstyle
->margin
[0][0]) ) + "mm");
2472 padd("fo:margin-right", sXML_CDATA
,
2473 Double2Str(WTMM(fstyle
->margin
[0][1])) + "mm");
2474 padd("fo:margin-top", sXML_CDATA
,
2475 Double2Str(WTMM(fstyle
->margin
[0][2])) + "mm");
2476 padd("fo:margin-bottom", sXML_CDATA
,
2477 Double2Str(WTMM(fstyle
->margin
[0][3])) + "mm");
2480 switch (fstyle
->txtflow
)
2483 padd("style:wrap", sXML_CDATA
, "none");
2486 if( fstyle
->boxtype
== 'G' || fstyle
->boxtype
== 'B' || fstyle
->boxtype
== 'O')
2487 padd("style:run-through", sXML_CDATA
, "background");
2488 padd("style:wrap", sXML_CDATA
, "run-through");
2491 padd("style:wrap", sXML_CDATA
, "dynamic");
2494 if (fstyle
->anchor_type
== CHAR_ANCHOR
)
2496 padd("style:vertical-pos", sXML_CDATA
, "top");
2497 padd("style:vertical-rel", sXML_CDATA
, "baseline");
2498 padd("style:horizontal-pos", sXML_CDATA
, "center");
2499 padd("style:horizontal-rel", sXML_CDATA
, "paragraph");
2504 switch (-(fstyle
->xpos
))
2507 padd("style:horizontal-pos", sXML_CDATA
, "right");
2510 padd("style:horizontal-pos", sXML_CDATA
, "center");
2514 padd("style:horizontal-pos", sXML_CDATA
, "from-left");
2517 switch (-(fstyle
->ypos
))
2520 padd("style:vertical-pos", sXML_CDATA
, "bottom");
2523 padd("style:vertical-pos", sXML_CDATA
, "middle");
2527 padd("style:vertical-pos", sXML_CDATA
, "from-top");
2530 if ( fstyle
->anchor_type
== PARA_ANCHOR
)
2532 padd("style:vertical-rel", sXML_CDATA
, "paragraph");
2533 padd("style:horizontal-rel", sXML_CDATA
, "paragraph");
2537 padd("style:vertical-rel", sXML_CDATA
, "page-content");
2538 padd("style:horizontal-rel", sXML_CDATA
, "page-content");
2541 if( fstyle
->boxtype
== 'X' || fstyle
->boxtype
== 'B' )
2543 Cell
*cell
= static_cast<Cell
*>(fstyle
->cell
);
2544 if(cell
->linetype
[0] == cell
->linetype
[1] &&
2545 cell
->linetype
[0] == cell
->linetype
[2] &&
2546 cell
->linetype
[0] == cell
->linetype
[3])
2548 switch( cell
->linetype
[0] )
2551 padd("fo:border", sXML_CDATA
, "none");
2553 case 1: /* A thin solid line */
2554 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2555 padd("fo:border", sXML_CDATA
,"0.002cm solid #000000");
2557 case 2: /* Bold lines */
2558 padd("fo:border", sXML_CDATA
,"0.035cm solid #000000");
2560 case 4: /* Double line */
2561 padd("style:border-line-width", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2562 padd("fo:border", sXML_CDATA
,"0.039cm double #000000");
2568 switch( cell
->linetype
[0] )
2570 case 1: /* A thin solid line */
2571 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2572 padd("fo:border-left", sXML_CDATA
,"0.002cm solid #000000");
2574 case 2: /* Bold lines */
2575 padd("fo:border-left", sXML_CDATA
,"0.035cm solid #000000");
2577 case 4: /* Double line */
2578 padd("style:border-line-width-left", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2579 padd("fo:border-left", sXML_CDATA
,"0.039cm double #000000");
2582 switch( cell
->linetype
[1] )
2584 case 1: /* A thin solid line */
2585 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2586 padd("fo:border-right", sXML_CDATA
,"0.002cm solid #000000");
2588 case 2: /* Bold lines */
2589 padd("fo:border-right", sXML_CDATA
,"0.035cm solid #000000");
2591 case 4: /* Double line */
2592 padd("style:border-line-width-right", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2593 padd("fo:border-right", sXML_CDATA
,"0.039cm double #000000");
2596 switch( cell
->linetype
[2] )
2598 case 1: /* A thin solid line */
2599 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2600 padd("fo:border-top", sXML_CDATA
,"0.002cm solid #000000");
2602 case 2: /* Bold lines */
2603 padd("fo:border-top", sXML_CDATA
,"0.035cm solid #000000");
2605 case 4: /* Double line */
2606 padd("style:border-line-width-top", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2607 padd("fo:border-top", sXML_CDATA
,"0.039cm double #000000");
2610 switch( cell
->linetype
[3] )
2612 case 1: /* A thin solid line */
2613 case 3: /* Dotted line -> LibreOffice, there is no dotted line */
2614 padd("fo:border-bottom", sXML_CDATA
,"0.002cm solid #000000");
2616 case 2: /* Bold lines */
2617 padd("fo:border-bottom", sXML_CDATA
,"0.035cm solid #000000");
2619 case 4: /* Double line */
2620 padd("style:border-line-width-bottom", sXML_CDATA
,"0.002cm 0.035cm 0.002cm");
2621 padd("fo:border-bottom", sXML_CDATA
,"0.039cm double #000000");
2626 if( cell
->linetype
[0] == 0 && cell
->linetype
[1] == 0 &&
2627 cell
->linetype
[2] == 0 && cell
->linetype
[3] == 0 ){
2628 padd("fo:padding", sXML_CDATA
,"0mm");
2631 padd("fo:padding-left", sXML_CDATA
,
2632 Double2Str(WTMM(fstyle
->margin
[1][0])) + "mm");
2633 padd("fo:padding-right", sXML_CDATA
,
2634 Double2Str(WTMM(fstyle
->margin
[1][1])) + "mm");
2635 padd("fo:padding-top", sXML_CDATA
,
2636 Double2Str(WTMM(fstyle
->margin
[1][2])) + "mm");
2637 padd("fo:padding-bottom", sXML_CDATA
,
2638 Double2Str(WTMM(fstyle
->margin
[1][3])) + "mm");
2640 if(cell
->shade
!= 0)
2641 padd("fo:background-color", sXML_CDATA
,
2643 sal::static_int_cast
<uchar
>(cell
->color
),
2644 sal::static_int_cast
<uchar
>(cell
->shade
),
2647 else if( fstyle
->boxtype
== 'E' )
2649 padd("fo:padding", sXML_CDATA
,"0mm");
2651 else if( fstyle
->boxtype
== 'L' )
2653 padd( "style:border-line-width-bottom", sXML_CDATA
, "0.02mm 0.35mm 0.02mm");
2654 padd("fo:border-bottom", sXML_CDATA
,"0.039cm double #808080");
2656 else if( fstyle
->boxtype
== 'G' )
2658 if( fstyle
->margin
[1][0] || fstyle
->margin
[1][1] || fstyle
->margin
[1][2] || fstyle
->margin
[1][3] ){
2659 OUString clip
= "rect(" +
2660 Double2Str(WTMM(-fstyle
->margin
[1][0]) ) + "mm " +
2661 Double2Str(WTMM(-fstyle
->margin
[1][1]) ) + "mm " +
2662 Double2Str(WTMM(-fstyle
->margin
[1][2]) ) + "mm " +
2663 Double2Str(WTMM(-fstyle
->margin
[1][3]) ) + "mm)";
2664 padd("style:mirror", sXML_CDATA
, "none");
2665 padd("fo:clip", sXML_CDATA
, clip
);
2667 char *cell
= static_cast<char *>(fstyle
->cell
);
2668 padd("draw:luminance", sXML_CDATA
,
2669 ascii(Int2Str(cell
[0], "%d%%", buf
)));
2670 padd("draw:contrast", sXML_CDATA
,
2671 ascii(Int2Str(cell
[1], "%d%%", buf
)));
2673 padd("draw:color-mode", sXML_CDATA
, "standard");
2674 else if( cell
[2] == 1 )
2675 padd("draw:color-mode", sXML_CDATA
, "greyscale");
2676 else if( cell
[2] == 2 )
2677 padd("draw:color-mode", sXML_CDATA
, "mono");
2680 rstartEl("style:properties", mxList
.get());
2682 rendEl("style:properties");
2683 rendEl("style:style");
2687 char *HwpReader::getTStyleName(int index
, char *_buf
)
2689 return Int2Str(index
, "T%d", _buf
);
2693 char *HwpReader::getPStyleName(int index
, char *_buf
)
2695 return Int2Str(index
, "P%d", _buf
);
2699 void HwpReader::makeChars(hchar_string
& rStr
)
2701 rchars(reinterpret_cast<sal_Unicode
const *>(rStr
.c_str()));
2707 * If no special characters in the paragraph and all characters use the same CharShape
2709 void HwpReader::make_text_p0(HWPPara
* para
, bool bParaStart
)
2715 unsigned char firstspace
= 0;
2718 padd("text:style-name", sXML_CDATA
,
2719 ascii(getPStyleName(para
->GetParaShape().index
, buf
)));
2720 rstartEl("text:p", mxList
.get());
2723 if( d
->bFirstPara
&& d
->bInBody
)
2727 "[\xEB\xAC\xB8\xEC\x84\x9C\xEC\x9D\x98 \xEC\xB2\x98\xEC\x9D\x8C]");
2728 // U+BB38 HANGUL SYLLABLE MUN, U+C11C HANGUL SYLLABLE SEO,
2729 // U+C758 HANGUL SYLLABLE YI, U+CC98 HANGUL SYLLABLE CEO,
2730 // U+C74C HANGUL SYLLABLE EUM: "Begin of Document"
2731 padd("text:name", sXML_CDATA
, OUString(buf
, strlen(buf
), RTL_TEXTENCODING_UTF8
));
2732 rstartEl("text:bookmark", mxList
.get());
2734 rendEl("text:bookmark");
2735 d
->bFirstPara
= false;
2740 d
->bInHeader
= false;
2742 padd("text:style-name", sXML_CDATA
,
2743 ascii(getTStyleName(para
->cshape
->index
, buf
)));
2744 rstartEl("text:span", mxList
.get());
2747 for (n
= 0; n
< para
->nch
&& para
->hhstr
[n
]->hh
;
2748 n
+= para
->hhstr
[n
]->WSize())
2750 if (para
->hhstr
[n
]->hh
== CH_SPACE
&& !firstspace
)
2753 rstartEl("text:s", mxList
.get());
2756 else if (para
->hhstr
[n
]->hh
== CH_END_PARA
)
2759 rendEl("text:span");
2765 if (para
->hhstr
[n
]->hh
== CH_SPACE
)
2769 res
= hcharconv(para
->hhstr
[n
]->hh
, dest
, UNICODE
);
2770 for( int j
= 0 ; j
< res
; j
++ )
2772 str
.push_back(dest
[j
]);
2780 * There is no special characters in the paragraph, but characters use different CharShapes
2782 void HwpReader::make_text_p1(HWPPara
* para
,bool bParaStart
)
2788 int curr
= para
->cshape
->index
;
2789 unsigned char firstspace
= 0;
2793 padd("text:style-name", sXML_CDATA
,
2794 ascii(getPStyleName(para
->GetParaShape().index
, buf
)));
2795 rstartEl("text:p", mxList
.get());
2798 if( d
->bFirstPara
&& d
->bInBody
)
2800 /* for HWP's Bookmark */
2803 "[\xEB\xAC\xB8\xEC\x84\x9C\xEC\x9D\x98 \xEC\xB2\x98\xEC\x9D\x8C]");
2804 // U+BB38 HANGUL SYLLABLE MUN, U+C11C HANGUL SYLLABLE SEO,
2805 // U+C758 HANGUL SYLLABLE YI, U+CC98 HANGUL SYLLABLE CEO,
2806 // U+C74C HANGUL SYLLABLE EUM: "Begin of Document"
2807 padd("text:name", sXML_CDATA
, OUString(buf
, strlen(buf
), RTL_TEXTENCODING_UTF8
));
2808 rstartEl("text:bookmark", mxList
.get());
2810 rendEl("text:bookmark");
2811 d
->bFirstPara
= false;
2816 d
->bInHeader
= false;
2818 padd("text:style-name", sXML_CDATA
,
2819 ascii(getTStyleName(curr
, buf
)));
2820 rstartEl("text:span", mxList
.get());
2823 for (n
= 0; n
< para
->nch
&& para
->hhstr
[n
]->hh
;
2824 n
+= para
->hhstr
[n
]->WSize())
2826 if (para
->GetCharShape(n
)->index
!= curr
)
2829 rendEl("text:span");
2830 curr
= para
->GetCharShape(n
)->index
;
2831 padd("text:style-name", sXML_CDATA
,
2832 ascii(getTStyleName(curr
, buf
)));
2833 rstartEl("text:span", mxList
.get());
2836 if (para
->hhstr
[n
]->hh
== CH_SPACE
&& !firstspace
)
2839 rstartEl("text:s", mxList
.get());
2842 else if (para
->hhstr
[n
]->hh
== CH_END_PARA
)
2845 rendEl("text:span");
2851 if( para
->hhstr
[n
]->hh
< CH_SPACE
)
2853 if (para
->hhstr
[n
]->hh
== CH_SPACE
)
2857 res
= hcharconv(para
->hhstr
[n
]->hh
, dest
, UNICODE
);
2858 for( int j
= 0 ; j
< res
; j
++ )
2860 str
.push_back(dest
[j
]);
2868 * Special characters are in the paragraph and characters use different CharShapes
2870 void HwpReader::make_text_p3(HWPPara
* para
,bool bParaStart
)
2875 unsigned char firstspace
= 0;
2876 bool pstart
= bParaStart
;
2877 bool tstart
= false;
2878 bool infield
= false;
2880 if( d
->bFirstPara
&& d
->bInBody
)
2887 "[\xEB\xAC\xB8\xEC\x84\x9C\xEC\x9D\x98 \xEC\xB2\x98\xEC\x9D\x8C]");
2888 // U+BB38 HANGUL SYLLABLE MUN, U+C11C HANGUL SYLLABLE SEO,
2889 // U+C758 HANGUL SYLLABLE YI, U+CC98 HANGUL SYLLABLE CEO,
2890 // U+C74C HANGUL SYLLABLE EUM: "Begin of Document"
2891 padd("text:name", sXML_CDATA
, OUString(buf
, strlen(buf
), RTL_TEXTENCODING_UTF8
));
2892 rstartEl("text:bookmark", mxList
.get());
2894 rendEl("text:bookmark");
2895 d
->bFirstPara
= false;
2903 d
->bInHeader
= false;
2906 for (n
= 0; n
< para
->nch
&& para
->hhstr
[n
]->hh
;
2907 n
+= para
->hhstr
[n
]->WSize())
2909 if( para
->hhstr
[n
]->hh
== CH_END_PARA
)
2913 if( !pstart
){ STARTP
;}
2914 if( !tstart
){ STARTT
;}
2917 if( tstart
){ ENDT
;}
2918 if( !pstart
){ STARTP
;}
2919 if( pstart
){ ENDP
;}
2922 else if( para
->hhstr
[n
]->hh
== CH_SPACE
&& !firstspace
)
2924 if( !pstart
) {STARTP
;}
2925 if( !tstart
) {STARTT
;}
2927 rstartEl("text:s", mxList
.get());
2931 else if ( para
->hhstr
[n
]->hh
>= CH_SPACE
)
2934 if( para
->GetCharShape(n
)->index
!= para
->GetCharShape(n
-1)->index
&& !infield
)
2936 if( !pstart
) {STARTP
;}
2937 if( !tstart
) {STARTT
;}
2941 if( para
->hhstr
[n
]->hh
== CH_SPACE
)
2945 res
= hcharconv(para
->hhstr
[n
]->hh
, dest
, UNICODE
);
2946 for( int j
= 0 ; j
< res
; j
++ )
2948 str
.push_back(dest
[j
]);
2951 else if (para
->hhstr
[n
]->hh
== CH_FIELD
)
2953 FieldCode
*hbox
= static_cast<FieldCode
*>(para
->hhstr
[n
].get());
2954 if( hbox
->location_info
== 1)
2956 if( !pstart
) {STARTP
;}
2957 if( !tstart
) {STARTT
;}
2960 if( hbox
->type
[0] == 4 && hbox
->type
[1] == 0 )
2962 field
= hbox
->str3
.get();
2965 makeFieldCode(str
, hbox
);
2972 if( hbox
->type
[0] == 4 && hbox
->type
[1] == 0 )
2974 makeFieldCode(str
, hbox
);
2983 switch (para
->hhstr
[n
]->hh
)
2986 if( !pstart
) {STARTP
;}
2987 if( !tstart
) {STARTT
;}
2989 makeBookmark(static_cast<Bookmark
*>(para
->hhstr
[n
].get()));
2991 case CH_DATE_FORM
: // 7
2993 case CH_DATE_CODE
: // 8
2994 if( !pstart
) {STARTP
;}
2995 if( !tstart
) {STARTT
;}
2997 makeDateCode(static_cast<DateCode
*>(para
->hhstr
[n
].get()));
3000 if( !pstart
) {STARTP
;}
3003 if( !tstart
) {STARTT
;}
3008 case CH_TEXT_BOX
: /* 10 - ordered by Table/text box/formula/button/hypertext */
3010 /* produce tables first, and treat formula as being in text:p. */
3011 TxtBox
*hbox
= static_cast<TxtBox
*>(para
->hhstr
[n
].get());
3013 if( hbox
->style
.anchor_type
== 0 )
3015 if( !pstart
) {STARTP
;}
3016 if( !tstart
) {STARTT
;}
3021 if( !pstart
) {STARTP
;}
3024 if( !tstart
) {STARTT
;}
3027 if( tstart
) {ENDT
;}
3031 case TBL_TYPE
: // table
3032 case TXT_TYPE
: // text box
3033 case EQU_TYPE
: // formula
3036 case BUTTON_TYPE
: // text button
3037 case HYPERTEXT_TYPE
: // hypertext
3038 makeHyperText(hbox
);
3043 case CH_PICTURE
: // 11
3045 Picture
*hbox
= static_cast<Picture
*>(para
->hhstr
[n
].get());
3046 if( hbox
->style
.anchor_type
== 0 )
3048 if( !pstart
) {STARTP
;}
3049 if( !tstart
) {STARTT
;}
3054 if( !pstart
) {STARTP
;}
3057 if( !tstart
) {STARTT
;}
3060 if( tstart
) {ENDT
;}
3069 if( !pstart
) {STARTP
;}
3070 if( !tstart
) {STARTT
;}
3073 if( tstart
) {ENDT
;}
3074 if( pstart
) {ENDP
;}
3079 case CH_HIDDEN
: // 15
3080 if( !pstart
) {STARTP
;}
3081 if( !tstart
) {STARTT
;}
3083 makeHidden(static_cast<Hidden
*>(para
->hhstr
[n
].get()));
3085 case CH_FOOTNOTE
: // 17
3086 if( !pstart
) {STARTP
;}
3087 if( !tstart
) {STARTT
;}
3089 makeFootnote(static_cast<Footnote
*>(para
->hhstr
[n
].get()));
3091 case CH_AUTO_NUM
: // 18
3092 if( !pstart
) {STARTP
;}
3093 if( !tstart
) {STARTT
;}
3095 makeAutoNum(static_cast<AutoNum
*>(para
->hhstr
[n
].get()));
3097 case CH_NEW_NUM
: // 19 -skip
3099 case CH_PAGE_NUM_CTRL
: // 21
3101 case CH_MAIL_MERGE
: // 22
3102 if( !pstart
) {STARTP
;}
3103 if( !tstart
) {STARTT
;}
3105 makeMailMerge(static_cast<MailMerge
*>(para
->hhstr
[n
].get()));
3107 case CH_COMPOSE
: /* 23 - overlapping letters */
3109 case CH_HYPHEN
: // 24
3111 case CH_TOC_MARK
: /* 25 Need to fix below 3 */
3112 if( !pstart
) {STARTP
;}
3113 if( !tstart
) {STARTT
;}
3116 case CH_INDEX_MARK
: // 26
3117 if( !pstart
) {STARTP
;}
3118 if( !tstart
) {STARTT
;}
3121 case CH_OUTLINE
: // 28
3122 if( !pstart
) {STARTP
;}
3123 if( !tstart
) {STARTT
;}
3125 makeOutline(static_cast<Outline
*>(para
->hhstr
[n
].get()));
3127 case CH_FIXED_SPACE
:
3129 str
.push_back(0x0020);
3137 void HwpReader::makeFieldCode(hchar_string
const & rStr
, FieldCode
const *hbox
)
3140 if( hbox
->type
[0] == 4 && hbox
->type
[1] == 0 )
3142 padd("text:placeholder-type", sXML_CDATA
, "text");
3144 padd("text:description", sXML_CDATA
, reinterpret_cast<sal_Unicode
const *>(hconv(field
)));
3145 rstartEl( "text:placeholder", mxList
.get());
3147 rchars( reinterpret_cast<sal_Unicode
const *>(rStr
.c_str()) );
3148 rendEl( "text:placeholder" );
3150 /* Document Summary */
3151 else if( hbox
->type
[0] == 3 && hbox
->type
[1] == 0 )
3153 if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "title")
3155 rstartEl( "text:title", mxList
.get() );
3156 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3157 rendEl( "text:title" );
3159 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "subject")
3161 rstartEl( "text:subject", mxList
.get() );
3162 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3163 rendEl( "text:subject" );
3165 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "author")
3167 rstartEl( "text:author-name", mxList
.get() );
3168 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3169 rendEl( "text:author-name" );
3171 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "keywords")
3173 rstartEl( "text:keywords", mxList
.get() );
3174 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3175 rendEl( "text:keywords" );
3178 /* Personal Information */
3179 else if( hbox
->type
[0] == 3 && hbox
->type
[1] == 1 )
3181 if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "User")
3183 rstartEl( "text:sender-lastname", mxList
.get() );
3184 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3185 rendEl( "text:sender-lastname" );
3187 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "Company")
3189 rstartEl( "text:sender-company", mxList
.get() );
3190 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3191 rendEl( "text:sender-company" );
3193 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "Position")
3195 rstartEl( "text:sender-title", mxList
.get() );
3196 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3197 rendEl( "text:sender-title" );
3199 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "Division")
3201 rstartEl( "text:sender-position", mxList
.get() );
3202 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3203 rendEl( "text:sender-position" );
3205 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "Fax")
3207 rstartEl( "text:sender-fax", mxList
.get() );
3208 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3209 rendEl( "text:sender-fax" );
3211 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "Pager")
3213 rstartEl( "text:phone-private", mxList
.get() );
3214 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3215 rendEl( "text:phone-private" );
3217 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "E-mail")
3219 rstartEl( "text:sender-email", mxList
.get() );
3220 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3221 rendEl( "text:sender-email" );
3223 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "Zipcode(office)")
3225 rstartEl( "text:sender-postal-code", mxList
.get() );
3226 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3227 rendEl( "text:sender-postal-code" );
3229 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "Phone(office)")
3231 rstartEl( "text:sender-phone-work", mxList
.get() );
3232 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3233 rendEl( "text:sender-phone-work" );
3235 else if (OUString(reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str3
.get()))) == "Address(office)")
3237 rstartEl( "text:sender-street", mxList
.get() );
3238 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3239 rendEl( "text:sender-street" );
3243 else if( hbox
->type
[0] == 3 && hbox
->type
[1] == 2 ) /* creation date */
3246 padd("style:data-style-name", sXML_CDATA
,
3247 ascii(Int2Str(hbox
->m_pDate
->key
, "N%d", buf
)));
3248 rstartEl( "text:creation-date", mxList
.get() );
3250 rchars( reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->str2
.get())) );
3251 rendEl( "text:creation-date" );
3258 * In LibreOffice, refer bookmarks as reference, but hwp doesn't have the sort of feature.
3260 void HwpReader::makeBookmark(Bookmark
const * hbox
)
3262 if (hbox
->type
== 0)
3264 padd("text:name", sXML_CDATA
, reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->id
)));
3265 rstartEl("text:bookmark", mxList
.get());
3267 rendEl("text:bookmark");
3269 else if (hbox
->type
== 1) /* Block bookmarks days begin and end there if */
3271 padd("text:name", sXML_CDATA
, reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->id
)));
3272 rstartEl("text:bookmark-start", mxList
.get());
3274 rendEl("text:bookmark-start");
3276 else if (hbox
->type
== 2)
3278 padd("text:name", sXML_CDATA
, reinterpret_cast<sal_Unicode
const *>(hconv(hbox
->id
)));
3279 rstartEl("text:bookmark-end", mxList
.get());
3281 rendEl("text:bookmark-end");
3286 void HwpReader::makeDateFormat(DateCode
* hbox
)
3288 padd("style:name", sXML_CDATA
,
3289 ascii(Int2Str(hbox
->key
, "N%d", buf
)));
3290 padd("style:family", sXML_CDATA
,"data-style");
3291 padd("number:language", sXML_CDATA
,"ko");
3292 padd("number:country", sXML_CDATA
,"KR");
3294 rstartEl("number:date-style", mxList
.get());
3297 bool add_zero
= false;
3299 hbox
->format
[DATE_SIZE
-1] = 0;
3301 const hchar
*fmt
= hbox
->format
[0] ? hbox
->format
: defaultform
;
3303 for( ; *fmt
; fmt
++ )
3305 if( zero_check
== 1 )
3319 padd("number:style", sXML_CDATA
, "long");
3320 rstartEl("number:year", mxList
.get());
3322 rendEl("number:year");
3325 rstartEl("number:year", mxList
.get());
3327 rendEl("number:year");
3331 padd("number:style", sXML_CDATA
, "long");
3332 rstartEl("number:month", mxList
.get());
3334 rendEl("number:month");
3337 padd("number:textual", sXML_CDATA
, "true");
3338 rstartEl("number:month", mxList
.get());
3340 rendEl("number:month");
3343 padd("number:textual", sXML_CDATA
, "true");
3344 padd("number:style", sXML_CDATA
, "long");
3345 rstartEl("number:month", mxList
.get());
3347 rendEl("number:month");
3351 padd("number:style", sXML_CDATA
, "long");
3352 rstartEl("number:day", mxList
.get());
3354 rendEl("number:day");
3358 padd("number:style", sXML_CDATA
, "long");
3359 rstartEl("number:day", mxList
.get());
3361 rendEl("number:day");
3362 switch( hbox
->date
[DateCode::DAY
] % 10)
3365 rstartEl("number:text", mxList
.get());
3367 rendEl("number:text");
3370 rstartEl("number:text", mxList
.get());
3372 rendEl("number:text");
3375 rstartEl("number:text", mxList
.get());
3377 rendEl("number:text");
3380 rstartEl("number:text", mxList
.get());
3382 rendEl("number:text");
3389 padd("number:style", sXML_CDATA
, "long");
3390 rstartEl("number:hours", mxList
.get());
3392 rendEl("number:hours");
3397 padd("number:style", sXML_CDATA
, "long");
3398 rstartEl("number:minutes", mxList
.get());
3400 rendEl("number:minutes");
3403 padd("number:style", sXML_CDATA
, "long");
3407 rstartEl("number:day-of-week", mxList
.get());
3409 rendEl("number:day-of-week");
3414 rstartEl("number:am-pm", mxList
.get());
3416 rendEl("number:am-pm");
3418 case '~': // Chinese Locale
3424 rstartEl("number:text", mxList
.get());
3425 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(sbuf
)));
3426 rendEl("number:text");
3431 rendEl("number:date-style");
3435 void HwpReader::makeDateCode(DateCode
* hbox
)
3437 padd("style:data-style-name", sXML_CDATA
,
3438 ascii(Int2Str(hbox
->key
, "N%d", buf
)));
3439 rstartEl( "text:date", mxList
.get() );
3441 hchar_string
const boxstr
= hbox
->GetString();
3442 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(boxstr
.c_str())));
3443 rendEl( "text:date" );
3447 void HwpReader::makeTab()
3449 rstartEl("text:tab-stop", mxList
.get());
3450 rendEl("text:tab-stop");
3454 void HwpReader::makeTable(TxtBox
* hbox
)
3456 padd("table:name", sXML_CDATA
,
3457 ascii(Int2Str(hbox
->style
.boxnum
, "Table%d", buf
)));
3458 padd("table:style-name", sXML_CDATA
,
3459 ascii(Int2Str(hbox
->style
.boxnum
, "Table%d", buf
)));
3460 rstartEl("table:table", mxList
.get());
3463 Table
*tbl
= hbox
->m_pTable
;
3465 for (size_t i
= 0 ; i
< tbl
->columns
.nCount
-1 ; i
++)
3467 sprintf(buf
,"Table%d.%c",hbox
->style
.boxnum
, static_cast<char>('A'+i
));
3468 padd("table:style-name", sXML_CDATA
, ascii( buf
));
3469 rstartEl("table:table-column", mxList
.get());
3471 rendEl("table:table-column");
3476 for (auto const& tcell
: tbl
->cells
)
3478 if( tcell
->nRowIndex
> j
)
3482 rendEl("table:table-row");
3486 sprintf(buf
,"Table%d.row%d",hbox
->style
.boxnum
, tcell
->nRowIndex
+ 1);
3487 padd("table:style-name", sXML_CDATA
, ascii( buf
));
3488 rstartEl("table:table-row", mxList
.get());
3490 j
= tcell
->nRowIndex
;
3493 sprintf(buf
,"Table%d.%c%d",hbox
->style
.boxnum
, 'A'+ tcell
->nColumnIndex
, tcell
->nRowIndex
+1);
3494 padd("table:style-name", sXML_CDATA
, ascii( buf
));
3495 if( tcell
->nColumnSpan
> 1 )
3496 padd("table:number-columns-spanned", sXML_CDATA
,
3497 ascii(Int2Str(tcell
->nColumnSpan
, "%d", buf
)));
3498 if( tcell
->nRowSpan
> 1 )
3499 padd("table:number-rows-spanned", sXML_CDATA
,
3500 ascii(Int2Str(tcell
->nRowSpan
, "%d", buf
)));
3501 padd("table:value-type", sXML_CDATA
,"string");
3502 if( tcell
->pCell
->protect
)
3503 padd("table:protected", sXML_CDATA
,"true");
3504 rstartEl("table:table-cell", mxList
.get());
3506 parsePara(hbox
->plists
[tcell
->pCell
->key
].front().get());
3507 rendEl("table:table-cell");
3509 rendEl("table:table-row");
3510 rendEl("table:table");
3515 * Parses the text boxes and tables.
3516 * 1. draw: style-name, draw: name, text: anchor-type, svg: width,
3517 * Fo: min-height, svg: x, svg: y
3518 * TODO: fo:background-color <= no idea whether the value of color setting->style is in it or not
3520 void HwpReader::makeTextBox(TxtBox
* hbox
)
3522 if( hbox
->style
.cap_len
> 0 && hbox
->type
== TXT_TYPE
)
3524 padd("draw:style-name", sXML_CDATA
,
3525 ascii(Int2Str(hbox
->style
.boxnum
, "CapBox%d", buf
)));
3526 padd("draw:name", sXML_CDATA
,
3527 ascii(Int2Str(hbox
->style
.boxnum
, "CaptionBox%d", buf
)));
3528 padd("draw:z-index", sXML_CDATA
,
3529 ascii(Int2Str(hbox
->zorder
, "%d", buf
)));
3530 switch (hbox
->style
.anchor_type
)
3533 padd("text:anchor-type", sXML_CDATA
, "as-char");
3536 padd("text:anchor-type", sXML_CDATA
, "paragraph");
3541 padd("text:anchor-type", sXML_CDATA
, "page");
3542 padd("text:anchor-page-number", sXML_CDATA
,
3543 ascii(Int2Str(hbox
->pgno
+1, "%d", buf
)));
3547 if (hbox
->style
.anchor_type
!= CHAR_ANCHOR
)
3549 padd("svg:x", sXML_CDATA
,
3550 Double2Str(WTMM( ( hbox
->pgx
+ hbox
->style
.margin
[0][0] ) )) + "mm");
3551 padd("svg:y", sXML_CDATA
,
3552 Double2Str(WTMM( ( hbox
->pgy
+ hbox
->style
.margin
[0][2] ) )) + "mm");
3554 padd("svg:width", sXML_CDATA
,
3555 Double2Str(WTMM(( hbox
->box_xs
+ hbox
->cap_xs
) )) + "mm");
3556 padd("fo:min-height", sXML_CDATA
,
3557 Double2Str(WTMM(( hbox
->box_ys
+ hbox
->cap_ys
) )) + "mm");
3558 rstartEl("draw:text-box", mxList
.get());
3560 if( hbox
->cap_pos
% 2 ) /* The caption is on the top */
3562 parsePara(hbox
->caption
.front().get());
3564 padd( "text:style-name", sXML_CDATA
, "Standard");
3565 rstartEl("text:p", mxList
.get());
3569 padd("draw:z-index", sXML_CDATA
,
3570 ascii(Int2Str(hbox
->zorder
, "%d", buf
)));
3573 padd("draw:style-name", sXML_CDATA
,
3574 ascii(Int2Str(hbox
->style
.boxnum
, "Txtbox%d", buf
)));
3575 padd("draw:name", sXML_CDATA
,
3576 ascii(Int2Str(hbox
->style
.boxnum
, "Frame%d", buf
)));
3578 if( hbox
->style
.cap_len
<= 0 || hbox
->type
!= TXT_TYPE
)
3582 switch (hbox
->style
.anchor_type
)
3585 padd("text:anchor-type", sXML_CDATA
, "as-char");
3588 padd("text:anchor-type", sXML_CDATA
, "paragraph");
3593 padd("text:anchor-type", sXML_CDATA
, "page");
3594 padd("text:anchor-page-number", sXML_CDATA
,
3595 ascii(Int2Str(hbox
->pgno
+1, "%d", buf
)));
3599 if( hbox
->style
.anchor_type
!= CHAR_ANCHOR
)
3601 x
+= hbox
->style
.margin
[0][0];
3602 y
+= hbox
->style
.margin
[0][2];
3604 padd("svg:x", sXML_CDATA
,
3605 Double2Str(WTMM( hbox
->pgx
+ x
)) + "mm");
3606 padd("svg:y", sXML_CDATA
,
3607 Double2Str(WTMM( hbox
->pgy
+ y
)) + "mm");
3611 padd("text:anchor-type", sXML_CDATA
, "as-char");
3612 padd("svg:y", sXML_CDATA
, "0cm");
3614 padd("svg:width", sXML_CDATA
,
3615 Double2Str(WTMM( hbox
->box_xs
)) + "mm");
3616 if( hbox
->style
.cap_len
> 0 && hbox
->type
!= TXT_TYPE
)
3617 padd("fo:min-height", sXML_CDATA
,
3618 Double2Str(WTMM( hbox
->box_ys
+ hbox
->cap_ys
)) + "mm");
3620 padd("svg:height", sXML_CDATA
,
3621 Double2Str(WTMM(hbox
->box_ys
)) + "mm");
3623 if( hbox
->type
!= EQU_TYPE
)
3625 rstartEl("draw:text-box", mxList
.get());
3627 /* If captions are present and it is on the top */
3628 if( hbox
->style
.cap_len
> 0 && (hbox
->cap_pos
% 2) && hbox
->type
== TBL_TYPE
)
3630 parsePara(hbox
->caption
.front().get());
3632 if( hbox
->type
== TBL_TYPE
) // Is Table
3638 parsePara(hbox
->plists
[0].front().get());
3640 /* If captions are present and it is on the bottom */
3641 if( hbox
->style
.cap_len
> 0 && !(hbox
->cap_pos
% 2) && hbox
->type
== TBL_TYPE
)
3643 parsePara(hbox
->caption
.front().get());
3645 rendEl("draw:text-box");
3646 // Caption exist and it is text-box
3647 if( hbox
->style
.cap_len
> 0 && hbox
->type
== TXT_TYPE
)
3650 if( !(hbox
->cap_pos
% 2))
3652 parsePara(hbox
->caption
.front().get());
3654 rendEl( "draw:text-box");
3659 rstartEl("draw:object", mxList
.get());
3662 rendEl("draw:object");
3668 * It must be converted into MathML.
3671 void HwpReader::makeFormula(TxtBox
* hbox
)
3680 pPar
= hbox
->plists
[0].front().get();
3683 for( n
= 0; n
< pPar
->nch
&& pPar
->hhstr
[n
]->hh
;
3684 n
+= pPar
->hhstr
[n
]->WSize() )
3686 if (l
>= sizeof(mybuf
)-7)
3688 res
= hcharconv(pPar
->hhstr
[n
]->hh
, dest
, UNICODE
);
3689 for( int j
= 0 ; j
< res
; j
++ ){
3694 mybuf
[l
++] = sal::static_int_cast
<char>(c
);
3697 mybuf
[l
++] = sal::static_int_cast
<char>((c
>> 8) & 0xff);
3698 mybuf
[l
++] = sal::static_int_cast
<char>(c
& 0xff);
3702 if (l
>= sizeof(mybuf
)-7)
3705 pPar
= pPar
->Next();
3709 std::unique_ptr
<Formula
> form( new Formula(mybuf
) );
3710 form
->setDocumentHandler(m_rxDocumentHandler
);
3711 form
->setAttributeListImpl(mxList
.get());
3716 * Read the platform information. if the platform is Linux or Solaris, it needs to change
3717 * C: \ => Home, D: \ => changed to root (/). Because HWP uses DOS emulator.
3720 void HwpReader::makeHyperText(TxtBox
* hbox
)
3722 HyperText
*hypert
= hwpfile
.GetHyperText();
3723 if( !hypert
) return;
3725 if (hypert
->filename
[0] != '\0') {
3726 ::std::string
const tmp
= hstr2ksstr(hypert
->bookmark
);
3727 ::std::string
const tmp2
= hstr2ksstr(kstr2hstr(
3729 reinterpret_cast<uchar
const *>(urltowin(reinterpret_cast<char *>(hypert
->filename
)).c_str())).c_str());
3731 reinterpret_cast<uchar
const *>(urltounix(reinterpret_cast<char *>(hypert
->filename
)).c_str())).c_str());
3733 padd("xlink:type", sXML_CDATA
, "simple");
3734 if (!tmp
.empty() && strcmp(tmp
.c_str(), "[HTML]")) {
3735 ::std::string
tmp3(tmp2
);
3736 tmp3
.push_back('#');
3738 padd("xlink:href", sXML_CDATA
,
3739 OUString(tmp3
.c_str(), tmp3
.size()+1, RTL_TEXTENCODING_EUC_KR
));
3742 padd("xlink:href", sXML_CDATA
,
3743 OUString(tmp2
.c_str(), tmp2
.size()+1, RTL_TEXTENCODING_EUC_KR
));
3749 padd("xlink:type", sXML_CDATA
, "simple");
3752 tmp
.append(hstr2ksstr(hypert
->bookmark
));
3753 padd("xlink:href", sXML_CDATA
,
3754 OUString(tmp
.c_str(), tmp
.size()+1, RTL_TEXTENCODING_EUC_KR
));
3756 rstartEl("draw:a", mxList
.get());
3764 * Read the platform information. if the platform is Linux or Solaris, it needs to change
3765 * C: \ => Home, D: \ => changed to root (/). Because HWP uses DOS emulator.
3768 void HwpReader::makePicture(Picture
* hbox
)
3770 switch (hbox
->pictype
)
3776 if( hbox
->style
.cap_len
> 0 )
3778 padd("draw:style-name", sXML_CDATA
,
3779 ascii(Int2Str(hbox
->style
.boxnum
, "CapBox%d", buf
)));
3780 padd("draw:name", sXML_CDATA
,
3781 ascii(Int2Str(hbox
->style
.boxnum
, "CaptionBox%d", buf
)));
3782 padd("draw:z-index", sXML_CDATA
,
3783 ascii(Int2Str(hbox
->zorder
, "%d", buf
)));
3784 switch (hbox
->style
.anchor_type
)
3787 padd("text:anchor-type", sXML_CDATA
, "as-char");
3790 padd("text:anchor-type", sXML_CDATA
, "paragraph");
3795 padd("text:anchor-type", sXML_CDATA
, "page");
3796 padd("text:anchor-page-number", sXML_CDATA
,
3797 ascii(Int2Str(hbox
->pgno
+1, "%d", buf
)));
3801 if (hbox
->style
.anchor_type
!= CHAR_ANCHOR
)
3803 padd("svg:x", sXML_CDATA
,
3804 Double2Str(WTMM( hbox
->pgx
+ hbox
->style
.margin
[0][0] )) + "mm");
3805 padd("svg:y", sXML_CDATA
,
3806 Double2Str(WTMM( hbox
->pgy
+ hbox
->style
.margin
[0][2] )) + "mm");
3808 padd("svg:width", sXML_CDATA
,
3809 Double2Str(WTMM( hbox
->box_xs
+ hbox
->style
.margin
[1][0] + hbox
->style
.margin
[1][1] )) + "mm");
3810 padd("fo:min-height", sXML_CDATA
,
3811 Double2Str(WTMM( hbox
->box_ys
+ hbox
->style
.margin
[1][2] + hbox
->style
.margin
[1][3] + hbox
->cap_ys
)) + "mm");
3812 rstartEl("draw:text-box", mxList
.get());
3814 if( hbox
->cap_pos
% 2 ) /* Caption is on the top */
3816 parsePara(hbox
->caption
.front().get());
3818 padd( "text:style-name", sXML_CDATA
, "Standard");
3819 rstartEl("text:p", mxList
.get());
3824 padd("xlink:type", sXML_CDATA
, "simple");
3826 if( hbox
->follow
[4] != 0 )
3827 padd("xlink:href", sXML_CDATA
, reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr(hbox
->follow
.data() + 4).c_str())));
3829 padd("xlink:href", sXML_CDATA
, reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr(hbox
->follow
.data() + 5).c_str())));
3831 if( hbox
->follow
[4] != 0 )
3832 padd("xlink:href", sXML_CDATA
,
3833 reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr(reinterpret_cast<uchar
const *>(urltounix(reinterpret_cast<char *>(hbox
->follow
.data() + 4)).c_str())).c_str())));
3835 padd("xlink:href", sXML_CDATA
,
3836 reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr(reinterpret_cast<uchar
const *>(urltounix(reinterpret_cast<char *>(hbox
->follow
.data() + 5)).c_str())).c_str())));
3838 rstartEl("draw:a", mxList
.get());
3841 padd("draw:style-name", sXML_CDATA
,
3842 ascii(Int2Str(hbox
->style
.boxnum
, "G%d", buf
)));
3843 padd("draw:name", sXML_CDATA
,
3844 ascii(Int2Str(hbox
->style
.boxnum
, "Image%d", buf
)));
3846 if( hbox
->style
.cap_len
<= 0 )
3848 padd("draw:z-index", sXML_CDATA
,
3849 ascii(Int2Str(hbox
->zorder
, "%d", buf
)));
3850 switch (hbox
->style
.anchor_type
)
3853 padd("text:anchor-type", sXML_CDATA
, "as-char");
3856 padd("text:anchor-type", sXML_CDATA
, "paragraph");
3861 padd("text:anchor-type", sXML_CDATA
, "page");
3862 padd("text:anchor-page-number", sXML_CDATA
,
3863 ascii(Int2Str(hbox
->pgno
+1, "%d", buf
)));
3867 if (hbox
->style
.anchor_type
!= CHAR_ANCHOR
)
3869 padd("svg:x", sXML_CDATA
,
3870 Double2Str(WTMM( hbox
->pgx
+ hbox
->style
.margin
[0][0] )) + "mm");
3871 padd("svg:y", sXML_CDATA
,
3872 Double2Str(WTMM( hbox
->pgy
+ hbox
->style
.margin
[0][2] )) + "mm");
3877 padd("text:anchor-type", sXML_CDATA
, "as-char");
3878 padd("svg:y", sXML_CDATA
, "0cm");
3880 padd("svg:width", sXML_CDATA
,
3881 Double2Str(WTMM( hbox
->box_xs
+ hbox
->style
.margin
[1][0] + hbox
->style
.margin
[1][1])) + "mm");
3882 padd("svg:height", sXML_CDATA
,
3883 Double2Str(WTMM( hbox
->box_ys
+ hbox
->style
.margin
[1][2] + hbox
->style
.margin
[1][3])) + "mm");
3885 if ( hbox
->pictype
== PICTYPE_FILE
){
3887 sprintf(buf
, "file:///%s", hbox
->picinfo
.picun
.path
);
3888 padd("xlink:href", sXML_CDATA
, reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr(reinterpret_cast<uchar
*>(buf
)).c_str())));
3890 padd("xlink:href", sXML_CDATA
,
3891 reinterpret_cast<sal_Unicode
const *>(hconv(kstr2hstr(reinterpret_cast<uchar
const *>(urltounix(hbox
->picinfo
.picun
.path
).c_str())).c_str())));
3893 padd("xlink:type", sXML_CDATA
, "simple");
3894 padd("xlink:show", sXML_CDATA
, "embed");
3895 padd("xlink:actuate", sXML_CDATA
, "onLoad");
3898 if( hbox
->pictype
== PICTYPE_OLE
)
3899 rstartEl("draw:object-ole", mxList
.get());
3901 rstartEl("draw:image", mxList
.get());
3903 if (hbox
->pictype
== PICTYPE_EMBED
|| hbox
->pictype
== PICTYPE_OLE
)
3905 rstartEl("office:binary-data", mxList
.get());
3907 if( hbox
->pictype
== PICTYPE_EMBED
){
3908 EmPicture
*emp
= hwpfile
.GetEmPicture(hbox
);
3911 std::shared_ptr
<char> pStr(base64_encode_string( emp
->data
.get(), emp
->size
), Free
<char>());
3912 rchars(ascii(pStr
.get()));
3916 if( hwpfile
.oledata
){
3920 wchar_t pathname
[200];
3922 MultiByteToWideChar(CP_ACP
, 0, hbox
->picinfo
.picole
.embname
, -1, pathname
, 200);
3923 int rc
= hwpfile
.oledata
->pis
->OpenStorage(pathname
, nullptr,
3924 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_TRANSACTED
, nullptr, 0, &srcsto
);
3929 rc
= OleLoad(srcsto
, IID_IUnknown
, nullptr, reinterpret_cast<LPVOID
*>(&pObj
));
3935 std::shared_ptr
<char> pStr(base64_encode_string( reinterpret_cast<uchar
*>(pObj
), strlen(reinterpret_cast<char *>(pObj
))), Free
<char>());
3936 rchars(ascii(pStr
.get()));
3946 rendEl("office:binary-data");
3948 if( hbox
->pictype
== PICTYPE_OLE
)
3949 rendEl("draw:object-ole");
3951 rendEl("draw:image");
3956 if( hbox
->style
.cap_len
> 0 )
3959 if( !(hbox
->cap_pos
% 2)) /* Caption is at the bottom, */
3961 parsePara(hbox
->caption
.front().get());
3963 rendEl( "draw:text-box");
3968 if( hbox
->picinfo
.picdraw
.zorder
> 0 )
3969 padd("draw:z-index", sXML_CDATA
,
3970 ascii(Int2Str( hbox
->picinfo
.picdraw
.zorder
+ 10000, "%d", buf
)));
3971 makePictureDRAW(hbox
->picinfo
.picdraw
.hdo
, hbox
);
3973 case PICTYPE_UNKNOWN
:
3979 #define DBL(x) ((x) * (x))
3980 void HwpReader::makePictureDRAW(HWPDrawingObject
*drawobj
, Picture
* hbox
)
3984 bool bIsRotate
= false;
3988 padd("draw:style-name", sXML_CDATA
,
3989 ascii(Int2Str(drawobj
->index
, "Draw%d", buf
)));
3993 switch (hbox
->style
.anchor_type
)
3996 padd("text:anchor-type", sXML_CDATA
, "as-char");
3999 padd("text:anchor-type", sXML_CDATA
, "paragraph");
4004 HWPInfo
& hwpinfo
= hwpfile
.GetHWPInfo();
4005 padd("text:anchor-type", sXML_CDATA
, "page");
4006 padd("text:anchor-page-number", sXML_CDATA
,
4007 ascii(Int2Str(hbox
->pgno
+1, "%d", buf
)));
4008 a
= hwpinfo
.paper
.left_margin
;
4009 b
= hwpinfo
.paper
.top_margin
+ hwpinfo
.paper
.header_length
;
4014 if (drawobj
->type
== HWPDO_CONTAINER
)
4016 rstartEl("draw:g", mxList
.get());
4018 makePictureDRAW(drawobj
->child
.get(), hbox
);
4024 if( (drawobj
->property
.flag
& HWPDO_FLAG_ROTATION
) &&
4025 (drawobj
->property
.parall
.pt
[0].y
!= drawobj
->property
.parall
.pt
[1].y
) &&
4026 //(drawobj->type == HWPDO_RECT || drawobj->type == HWPDO_ADVANCED_ELLIPSE || drawobj->type == HWPDO_ADVANCED_ARC )
4027 (drawobj
->type
== HWPDO_RECT
|| drawobj
->type
== HWPDO_ADVANCED_ELLIPSE
)
4032 ZZParall
*pal
= &drawobj
->property
.parall
;
4034 ZZPoint pt
[3], r_pt
[3];
4035 for(i
= 0 ; i
< 3 ; i
++ ){
4036 pt
[i
].x
= pal
->pt
[i
].x
- drawobj
->property
.rot_originx
;
4037 /* Convert to a physical coordinate */
4038 pt
[i
].y
= -(pal
->pt
[i
].y
- drawobj
->property
.rot_originy
);
4041 double rotate
, skewX
;
4043 /* 2 - rotation angle calculation */
4044 if( pt
[1].x
== pt
[0].x
){
4045 if( pt
[1].y
> pt
[0].y
)
4051 rotate
= atan(static_cast<double>( pt
[1].y
- pt
[0].y
)/(pt
[1].x
- pt
[0].x
));
4052 if( pt
[1].x
< pt
[0].x
)
4055 for( i
= 0 ; i
< 3 ; i
++){
4056 r_pt
[i
].x
= static_cast<int>(pt
[i
].x
* cos(-rotate
) - pt
[i
].y
* sin(-rotate
));
4057 r_pt
[i
].y
= static_cast<int>(pt
[i
].y
* cos(-rotate
) + pt
[i
].x
* sin(-rotate
));
4060 /* 4 - Calculation of reflex angle */
4061 if( r_pt
[2].y
== r_pt
[1].y
)
4064 skewX
= atan(static_cast<double>(r_pt
[2].x
- r_pt
[1].x
)/( r_pt
[2].y
- r_pt
[1].y
));
4067 if( skewX
<= -PI
/2 )
4071 if( skewX
!= 0.0 && rotate
!= 0.0 ){
4072 trans
= "skewX (" + Double2Str(skewX
)
4073 + ") rotate (" + Double2Str(rotate
)
4074 + ") translate (" + Double2Str(WTMM(x
+ a
+ drawobj
->offset2
.x
+ pal
->pt
[0].x
)) + "mm "
4075 + Double2Str(WTMM(y
+ b
+ drawobj
->offset2
.y
+ pal
->pt
[0].y
)) + "mm)";
4078 else if( skewX
!= 0.0 ){
4079 trans
= "skewX (" + Double2Str(skewX
)
4080 + ") translate (" + Double2Str(WTMM(x
+ a
+ drawobj
->offset2
.x
+ pal
->pt
[0].x
)) + "mm "
4081 + Double2Str(WTMM(y
+ b
+ drawobj
->offset2
.y
+ pal
->pt
[0].y
)) + "mm)";
4084 else if( rotate
!= 0.0 ){
4085 trans
= "rotate (" + Double2Str(rotate
)
4086 + ") translate (" + Double2Str(WTMM(x
+ a
+ drawobj
->offset2
.x
+ pal
->pt
[0].x
)) + "mm "
4087 + Double2Str(WTMM(y
+ b
+ drawobj
->offset2
.y
+ pal
->pt
[0].y
)) + "mm)";
4091 drawobj
->extent
.w
= static_cast<int>(sqrt(double(DBL(pt
[1].x
-pt
[0].x
)+DBL(pt
[1].y
-pt
[0].y
))));
4092 drawobj
->extent
.h
= static_cast<int>(sqrt(double(DBL(pt
[2].x
-pt
[1].x
)+DBL(pt
[2].y
-pt
[1].y
))));
4093 padd("draw:transform", sXML_CDATA
, trans
);
4096 switch (drawobj
->type
)
4098 case HWPDO_LINE
: /* Line-starting coordinates, ending coordinates. */
4099 if( drawobj
->u
.line_arc
.flip
& 0x01 )
4101 padd("svg:x1", sXML_CDATA
,
4102 Double2Str (WTMM(x
+ a
+ drawobj
->offset2
.x
+ drawobj
->extent
.w
)) + "mm");
4103 padd("svg:x2", sXML_CDATA
,
4104 Double2Str (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4108 padd("svg:x1", sXML_CDATA
,
4109 Double2Str (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4110 padd("svg:x2", sXML_CDATA
,
4111 Double2Str (WTMM(x
+ a
+ drawobj
->offset2
.x
+ drawobj
->extent
.w
)) + "mm");
4113 if( drawobj
->u
.line_arc
.flip
& 0x02 )
4115 padd("svg:y1", sXML_CDATA
,
4116 Double2Str (WTMM( y
+ b
+ drawobj
->offset2
.y
+ drawobj
->extent
.h
) ) + "mm");
4117 padd("svg:y2", sXML_CDATA
,
4118 Double2Str (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4122 padd("svg:y1", sXML_CDATA
,
4123 Double2Str (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4124 padd("svg:y2", sXML_CDATA
,
4125 Double2Str (WTMM(y
+ b
+ drawobj
->offset2
.y
+ drawobj
->extent
.h
)) + "mm");
4128 rstartEl("draw:line", mxList
.get());
4130 rendEl("draw:line");
4132 case HWPDO_RECT
: /* rectangle - the starting position, vertical/horizontal */
4135 padd("svg:x", sXML_CDATA
,
4136 Double2Str (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4137 padd("svg:y", sXML_CDATA
,
4138 Double2Str (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4140 padd("svg:width", sXML_CDATA
,
4141 Double2Str (WTMM( drawobj
->extent
.w
)) + "mm");
4142 padd("svg:height", sXML_CDATA
,
4143 Double2Str (WTMM( drawobj
->extent
.h
)) + "mm");
4144 if( drawobj
->property
.flag
& 0x01 )
4146 int value
= drawobj
->extent
.w
< drawobj
->extent
.h
?
4147 drawobj
->extent
.w
: drawobj
->extent
.h
;
4148 padd("draw:corner-radius", sXML_CDATA
,
4149 Double2Str (WTMM( value
/10 )) + "mm");
4151 else if( drawobj
->property
.flag
& 0x04 )
4153 int value
= drawobj
->extent
.w
< drawobj
->extent
.h
?
4154 drawobj
->extent
.w
: drawobj
->extent
.h
;
4155 padd("draw:corner-radius", sXML_CDATA
,
4156 Double2Str (WTMM( value
/ 2)) + "mm");
4159 rstartEl("draw:rect", mxList
.get());
4161 if( (drawobj
->property
.flag
& HWPDO_FLAG_AS_TEXTBOX
) &&
4162 drawobj
->property
.pPara
) // As Textbox
4164 HWPPara
*pPara
= drawobj
->property
.pPara
;
4168 make_text_p1( pPara
, false );
4169 pPara
= pPara
->Next();
4172 rendEl("draw:rect");
4174 case HWPDO_ELLIPSE
: /* Ellipse - the starting position, vertical/horizontal */
4175 case HWPDO_ADVANCED_ELLIPSE
: /* modified ellipse */
4179 padd("svg:x", sXML_CDATA
,
4180 Double2Str (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4181 padd("svg:y", sXML_CDATA
,
4182 Double2Str (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4185 padd("svg:width", sXML_CDATA
,
4186 Double2Str (WTMM( drawobj
->extent
.w
)) + "mm");
4187 padd("svg:height", sXML_CDATA
,
4188 Double2Str (WTMM( drawobj
->extent
.h
)) + "mm");
4189 if( drawobj
->type
== HWPDO_ADVANCED_ELLIPSE
){
4190 if( drawobj
->u
.arc
.radial
[0].x
!= drawobj
->u
.arc
.radial
[1].x
4191 || drawobj
->u
.arc
.radial
[0].y
!= drawobj
->u
.arc
.radial
[1].y
){
4193 Cx
= ( drawobj
->offset2
.x
+ drawobj
->extent
.w
) / 2;
4194 Cy
= ( drawobj
->offset2
.y
+ drawobj
->extent
.h
) / 2;
4196 double start_angle
, end_angle
;
4197 start_angle
= calcAngle( Cx
, Cy
, drawobj
->u
.arc
.radial
[0].x
, drawobj
->u
.arc
.radial
[0].y
);
4198 end_angle
= calcAngle( Cx
, Cy
, drawobj
->u
.arc
.radial
[1].x
, drawobj
->u
.arc
.radial
[1].y
);
4199 if( drawobj
->property
.fill_color
< 0xffffff )
4200 padd("draw:kind", sXML_CDATA
, "section");
4202 padd("draw:kind", sXML_CDATA
, "arc");
4203 padd("draw:start-angle", sXML_CDATA
, Double2Str(start_angle
));
4204 padd("draw:end-angle", sXML_CDATA
, Double2Str(end_angle
));
4207 rstartEl("draw:ellipse", mxList
.get());
4209 if( drawobj
->property
.flag
>> 19 & 0x01 &&
4210 drawobj
->property
.pPara
) // As Textbox
4212 HWPPara
*pPara
= drawobj
->property
.pPara
;
4216 make_text_p1( pPara
, false );
4217 pPara
= pPara
->Next();
4220 rendEl("draw:ellipse");
4224 case HWPDO_ARC
: /* Arc */
4225 case HWPDO_ADVANCED_ARC
:
4227 /* If it is the arc, LibreOffice assumes the size as the entire ellipse size */
4228 uint flip
= drawobj
->u
.line_arc
.flip
;
4231 if( ( flip
== 0 || flip
== 2 ) && drawobj
->type
== HWPDO_ARC
)
4232 padd("svg:x", sXML_CDATA
,
4233 Double2Str (WTMM( x
+ a
+ drawobj
->offset2
.x
- drawobj
->extent
.w
)) + "mm");
4235 padd("svg:x", sXML_CDATA
,
4236 Double2Str (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4237 if( ( flip
== 0 || flip
== 1 ) && drawobj
->type
== HWPDO_ARC
)
4238 padd("svg:y", sXML_CDATA
,
4239 Double2Str (WTMM( y
+ b
+ drawobj
->offset2
.y
- drawobj
->extent
.h
)) + "mm");
4241 padd("svg:y", sXML_CDATA
,
4242 Double2Str (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4245 padd("svg:width", sXML_CDATA
,
4246 Double2Str (WTMM( drawobj
->extent
.w
* 2)) + "mm");
4247 padd("svg:height", sXML_CDATA
,
4248 Double2Str (WTMM( drawobj
->extent
.h
* 2)) + "mm");
4249 if( drawobj
->property
.flag
& HWPDO_FLAG_DRAW_PIE
||
4250 drawobj
->property
.fill_color
< 0xffffff )
4251 padd("draw:kind", sXML_CDATA
, "section");
4253 padd("draw:kind", sXML_CDATA
, "arc");
4255 if( drawobj
->type
== HWPDO_ADVANCED_ARC
){
4256 double start_angle
, end_angle
;
4257 ZZParall
*pal
= &drawobj
->property
.parall
;
4259 if( pal
->pt
[1].x
== pal
->pt
[0].x
){
4260 if( pal
->pt
[0].y
< pal
->pt
[1].y
)
4261 start_angle
= 1.5 * PI
;
4263 start_angle
= 0.5 * PI
;
4266 start_angle
= atan(static_cast<double>( pal
->pt
[0].y
- pal
->pt
[1].y
)/( pal
->pt
[1].x
- pal
->pt
[0].x
));
4267 if( pal
->pt
[1].x
< pal
->pt
[0].x
)
4270 if( pal
->pt
[1].x
== pal
->pt
[2].x
){
4271 if( pal
->pt
[2].y
< pal
->pt
[1].y
)
4272 end_angle
= 1.5 * PI
;
4274 end_angle
= 0.5 * PI
;
4277 end_angle
= atan(static_cast<double>( pal
->pt
[2].y
- pal
->pt
[1].y
)/( pal
->pt
[1].x
- pal
->pt
[2].x
));
4278 if( pal
->pt
[1].x
< pal
->pt
[2].x
)
4282 if( start_angle
>= 2 * PI
)
4283 start_angle
-= 2 * PI
;
4284 if( end_angle
>= 2 * PI
)
4285 end_angle
-= 2 * PI
;
4286 if( ( start_angle
> end_angle
) && (start_angle
- end_angle
< PI
)){
4287 double tmp_angle
= start_angle
;
4288 start_angle
= end_angle
;
4289 end_angle
= tmp_angle
;
4291 padd("draw:start-angle", sXML_CDATA
, Double2Str(start_angle
* 180. / PI
));
4292 padd("draw:end-angle", sXML_CDATA
, Double2Str(end_angle
* 180. / PI
));
4296 if( drawobj
->u
.line_arc
.flip
== 0 )
4298 padd("draw:start-angle", sXML_CDATA
, "270");
4299 padd("draw:end-angle", sXML_CDATA
, "0");
4301 else if( drawobj
->u
.line_arc
.flip
== 1 )
4303 padd("draw:start-angle", sXML_CDATA
, "180");
4304 padd("draw:end-angle", sXML_CDATA
, "270");
4306 else if( drawobj
->u
.line_arc
.flip
== 2 )
4308 padd("draw:start-angle", sXML_CDATA
, "0");
4309 padd("draw:end-angle", sXML_CDATA
, "90");
4313 padd("draw:start-angle", sXML_CDATA
, "90");
4314 padd("draw:end-angle", sXML_CDATA
, "180");
4317 rstartEl("draw:ellipse", mxList
.get());
4319 if( drawobj
->property
.flag
>> 19 & 0x01 &&
4320 drawobj
->property
.pPara
) // As Textbox
4322 HWPPara
*pPara
= drawobj
->property
.pPara
;
4326 make_text_p1( pPara
, false );
4327 pPara
= pPara
->Next();
4330 rendEl("draw:ellipse");
4334 case HWPDO_CURVE
: /* Curve: converts to polygons. */
4336 bool bIsNatural
= true;
4337 if( drawobj
->property
.flag
>> 5 & 0x01){
4342 padd("svg:x", sXML_CDATA
,
4343 Double2Str (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4344 padd("svg:y", sXML_CDATA
,
4345 Double2Str (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4347 padd("svg:width", sXML_CDATA
,
4348 Double2Str (WTMM( drawobj
->extent
.w
)) + "mm");
4349 padd("svg:height", sXML_CDATA
,
4350 Double2Str (WTMM( drawobj
->extent
.h
)) + "mm");
4351 sprintf(buf
, "0 0 %d %d", WTSM(drawobj
->extent
.w
) , WTSM(drawobj
->extent
.h
) );
4352 padd("svg:viewBox", sXML_CDATA
, ascii(buf
) );
4354 OUStringBuffer oustr
;
4356 if ((drawobj
->u
.freeform
.npt
> 2) &&
4357 (static_cast<size_t>(drawobj
->u
.freeform
.npt
) <
4358 (::std::numeric_limits
<int>::max() / sizeof(double))))
4361 n
= drawobj
->u
.freeform
.npt
;
4363 std::unique_ptr
<double[]> xarr( new double[n
+1] );
4364 std::unique_ptr
<double[]> yarr( new double[n
+1] );
4365 std::unique_ptr
<double[]> tarr( new double[n
+1] );
4367 std::unique_ptr
<double[]> xb
;
4368 std::unique_ptr
<double[]> yb
;
4370 std::unique_ptr
<double[]> carr
;
4371 std::unique_ptr
<double[]> darr
;
4374 for( i
= 0 ; i
< n
; i
++ ){
4375 xarr
[i
] = drawobj
->u
.freeform
.pt
[i
].x
;
4376 yarr
[i
] = drawobj
->u
.freeform
.pt
[i
].y
;
4384 PeriodicSpline(n
, tarr
.get(), xarr
.get(), xb
, carr
, darr
);
4385 // prevent memory leak
4388 PeriodicSpline(n
, tarr
.get(), yarr
.get(), yb
, carr
, darr
);
4391 NaturalSpline(n
, tarr
.get(), xarr
.get(), xb
, carr
, darr
);
4392 // prevent memory leak
4395 NaturalSpline(n
, tarr
.get(), yarr
.get(), yb
, carr
, darr
);
4398 sprintf(buf
, "M%d %dC%d %d", WTSM(xarr
[0]), WTSM(yarr
[0]),
4399 WTSM(xarr
[0] + xb
[0]/3), WTSM(yarr
[0] + yb
[0]/3) );
4400 oustr
.append(ascii(buf
));
4402 for( i
= 1 ; i
< n
; i
++ ){
4404 sprintf(buf
, " %d %d %d %dz",
4405 WTSM(xarr
[i
] - xb
[i
]/3), WTSM(yarr
[i
] - yb
[i
]/3),
4406 WTSM(xarr
[i
]), WTSM(yarr
[i
]) );
4409 sprintf(buf
, " %d %d %d %d %d %d",
4410 WTSM(xarr
[i
] - xb
[i
]/3), WTSM(yarr
[i
] - yb
[i
]/3),
4411 WTSM(xarr
[i
]), WTSM(yarr
[i
]),
4412 WTSM(xarr
[i
] + xb
[i
]/3), WTSM(yarr
[i
] + yb
[i
]/3) );
4415 oustr
.append(ascii(buf
));
4419 padd("svg:d", sXML_CDATA
, oustr
.makeStringAndClear());
4421 rstartEl("draw:path", mxList
.get());
4424 if( drawobj
->property
.flag
>> 19 & 0x01 && drawobj
->property
.pPara
)
4426 HWPPara
*pPara
= drawobj
->property
.pPara
;
4429 make_text_p1( pPara
, false );
4430 pPara
= pPara
->Next();
4433 rendEl("draw:path");
4436 case HWPDO_CLOSED_FREEFORM
:
4437 case HWPDO_FREEFORM
: /* polygon */
4439 bool bIsPolygon
= false;
4441 padd("svg:x", sXML_CDATA
,
4442 Double2Str (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4443 padd("svg:y", sXML_CDATA
,
4444 Double2Str (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4446 padd("svg:width", sXML_CDATA
,
4447 Double2Str (WTMM( drawobj
->extent
.w
)) + "mm");
4448 padd("svg:height", sXML_CDATA
,
4449 Double2Str (WTMM( drawobj
->extent
.h
)) + "mm");
4451 sprintf(buf
, "0 0 %d %d", WTSM(drawobj
->extent
.w
), WTSM(drawobj
->extent
.h
));
4452 padd("svg:viewBox", sXML_CDATA
, ascii(buf
) );
4454 OUStringBuffer oustr
;
4456 if (drawobj
->u
.freeform
.npt
> 0)
4458 sprintf(buf
, "%d,%d", WTSM(drawobj
->u
.freeform
.pt
[0].x
), WTSM(drawobj
->u
.freeform
.pt
[0].y
));
4459 oustr
.append(ascii(buf
));
4461 for (i
= 1; i
< drawobj
->u
.freeform
.npt
; i
++)
4463 sprintf(buf
, " %d,%d",
4464 WTSM(drawobj
->u
.freeform
.pt
[i
].x
),
4465 WTSM(drawobj
->u
.freeform
.pt
[i
].y
));
4466 oustr
.append(ascii(buf
));
4468 if( drawobj
->u
.freeform
.pt
[0].x
== drawobj
->u
.freeform
.pt
[i
-1].x
&&
4469 drawobj
->u
.freeform
.pt
[0].y
== drawobj
->u
.freeform
.pt
[i
-1].y
)
4474 padd("draw:points", sXML_CDATA
, oustr
.makeStringAndClear());
4476 if( drawobj
->property
.fill_color
<= 0xffffff ||
4477 drawobj
->property
.pattern_type
!= 0)
4484 rstartEl("draw:polygon", mxList
.get());
4486 if( drawobj
->property
.flag
>> 19 & 0x01 &&
4488 drawobj
->property
.pPara
)
4490 HWPPara
*pPara
= drawobj
->property
.pPara
;
4491 // parsePara(pPara);
4494 make_text_p1( pPara
, false );
4495 pPara
= pPara
->Next();
4498 rendEl("draw:polygon");
4502 rstartEl("draw:polyline", mxList
.get());
4504 if( drawobj
->property
.flag
>> 19 & 0x01 &&
4506 drawobj
->property
.pPara
)
4508 HWPPara
*pPara
= drawobj
->property
.pPara
;
4512 make_text_p1( pPara
, false );
4513 pPara
= pPara
->Next();
4516 rendEl("draw:polyline");
4523 padd("svg:x", sXML_CDATA
,
4524 Double2Str (WTMM( x
+ a
+ drawobj
->offset2
.x
)) + "mm");
4525 padd("svg:y", sXML_CDATA
,
4526 Double2Str (WTMM( y
+ b
+ drawobj
->offset2
.y
)) + "mm");
4528 padd("svg:width", sXML_CDATA
,
4529 Double2Str (WTMM( drawobj
->extent
.w
)) + "mm");
4530 padd("svg:height", sXML_CDATA
,
4531 Double2Str (WTMM( drawobj
->extent
.h
)) + "mm");
4532 if( drawobj
->property
.flag
& 0x01 )
4534 int value
= drawobj
->extent
.w
< drawobj
->extent
.h
?
4535 drawobj
->extent
.w
: drawobj
->extent
.h
;
4536 padd("draw:corner-radius", sXML_CDATA
,
4537 Double2Str (WTMM( value
/10 )) + "mm");
4539 else if( drawobj
->property
.flag
& 0x04 )
4541 int value
= drawobj
->extent
.w
< drawobj
->extent
.h
?
4542 drawobj
->extent
.w
: drawobj
->extent
.h
;
4543 padd("draw:corner-radius", sXML_CDATA
,
4544 Double2Str (WTMM( value
/ 2)) + "mm");
4547 rstartEl("draw:text-box", mxList
.get());
4550 HWPPara
*pPara
= drawobj
->u
.textbox
.h
;
4554 make_text_p1( pPara
, false );
4555 pPara
= pPara
->Next();
4558 rendEl("draw:text-box");
4563 drawobj
= drawobj
->next
.get();
4568 void HwpReader::makeLine()
4570 padd("text:style-name", sXML_CDATA
, "Horizontal Line");
4571 rstartEl( "text:p", mxList
.get());
4577 * Input-comment-hidden description: shows a hidden explanation to the users.
4578 * Parse out only strings, but it may contain paragraphs.
4580 void HwpReader::makeHidden(Hidden
* hbox
)
4586 padd("text:condition", sXML_CDATA
, "");
4587 padd("text:string-value", sXML_CDATA
, "");
4588 rstartEl("text:hidden-text", mxList
.get());
4590 HWPPara
*para
= hbox
->plist
.front().get();
4594 for (int n
= 0; n
< para
->nch
&& para
->hhstr
[n
]->hh
;
4595 n
+= para
->hhstr
[n
]->WSize())
4597 res
= hcharconv(para
->hhstr
[n
]->hh
, dest
, UNICODE
);
4598 for( int j
= 0 ; j
< res
; j
++ )
4600 str
.push_back(dest
[j
]);
4603 para
= para
->Next();
4606 rendEl("text:hidden-text");
4611 * Converts footnote to text:footnote, endnote to text:endnote
4613 void HwpReader::makeFootnote(Footnote
* hbox
)
4617 padd("text:id", sXML_CDATA
,
4618 ascii(Int2Str(hbox
->number
, "edn%d", buf
)));
4619 rstartEl("text:endnote", mxList
.get());
4621 padd("text:label", sXML_CDATA
,
4622 ascii(Int2Str(hbox
->number
, "%d", buf
)));
4623 rstartEl("text:endnote-citation", mxList
.get());
4625 rchars(ascii(Int2Str(hbox
->number
, "%d", buf
)));
4626 rendEl("text:endnote-citation");
4627 rstartEl("text:endnote-body", mxList
.get());
4628 parsePara(hbox
->plist
.front().get());
4629 rendEl("text:endnote-body");
4630 rendEl("text:endnote");
4634 padd("text:id", sXML_CDATA
,
4635 ascii(Int2Str(hbox
->number
, "ftn%d", buf
)));
4636 rstartEl("text:footnote", mxList
.get());
4638 padd("text:label", sXML_CDATA
,
4639 ascii(Int2Str(hbox
->number
, "%d", buf
)));
4640 rstartEl("text:footnote-citation", mxList
.get());
4642 rchars(ascii(Int2Str(hbox
->number
, "%d", buf
)));
4643 rendEl("text:footnote-citation");
4644 rstartEl("text:footnote-body", mxList
.get());
4645 parsePara(hbox
->plist
.front().get());
4646 rendEl("text:footnote-body");
4647 rendEl("text:footnote");
4653 * page/footnote/endnote/picture/table/formula number
4655 void HwpReader::makeAutoNum(AutoNum
const * hbox
)
4660 rstartEl("text:page-number", mxList
.get());
4661 rchars(ascii(Int2Str(hbox
->number
, "%d", buf
)));
4662 rendEl("text:page-number");
4670 padd("text:ref-name",sXML_CDATA
,
4671 ascii(Int2Str(hbox
->number
, "refIllustration%d", buf
)));
4672 padd("text:name",sXML_CDATA
, "Illustration");
4673 padd("style:num-format",sXML_CDATA
, "1");
4674 rstartEl("text:sequence", mxList
.get());
4675 rchars(ascii(Int2Str(hbox
->number
, "%d", buf
)));
4676 rendEl("text:sequence");
4679 padd("text:ref-name",sXML_CDATA
,
4680 ascii(Int2Str(hbox
->number
, "refTable%d", buf
)));
4681 padd("text:name",sXML_CDATA
, "Table");
4682 padd("style:num-format",sXML_CDATA
, "1");
4683 rstartEl("text:sequence", mxList
.get());
4684 rchars(ascii(Int2Str(hbox
->number
, "%d", buf
)));
4685 rendEl("text:sequence");
4691 void HwpReader::makeShowPageNum()
4693 ShowPageNum
*hbox
= d
->pPn
;
4695 if( hbox
->where
== 1 || hbox
->where
== 4 )
4697 else if( hbox
->where
== 2 || hbox
->where
== 5 )
4699 else if( hbox
->where
== 3 || hbox
->where
== 6 )
4701 else /* should not exist in this case. */
4703 if( d
->nPnPos
== 1 )
4705 else if( d
->nPnPos
== 3 )
4709 padd("draw:style-name", sXML_CDATA
,
4710 ascii(Int2Str(nPos
, "PNBox%d", buf
)));
4711 padd("draw:name", sXML_CDATA
,
4712 ascii(Int2Str(nPos
, "PageNumber%d", buf
)));
4713 padd("text:anchor-type", sXML_CDATA
, "paragraph");
4714 padd("svg:y", sXML_CDATA
, "0cm");
4715 padd("svg:width", sXML_CDATA
, "2.0cm");
4716 padd("fo:min-height", sXML_CDATA
, "0.5cm");
4717 rstartEl("draw:text-box", mxList
.get());
4720 padd("text:style-name", sXML_CDATA
,
4721 ascii(Int2Str(nPos
, "PNPara%d", buf
)));
4722 rstartEl("text:p", mxList
.get());
4724 if( hbox
->shape
> 2 )
4726 if( hbox
->shape
% 3 == 0 )
4727 padd("style:num-format", sXML_CDATA
, "1");
4728 else if( hbox
->shape
% 3 == 1 )
4729 padd("style:num-format", sXML_CDATA
, "I");
4731 padd("style:num-format", sXML_CDATA
, "i");
4732 padd("text:select-page", sXML_CDATA
, "current");
4733 rstartEl("text:page-number", mxList
.get());
4736 rendEl("text:page-number");
4737 if( hbox
->shape
> 2 )
4740 rendEl("draw:text-box");
4745 * mail merge operation using hwp addressbook and hwp data form.
4746 * not support operation in OO writer.
4748 void HwpReader::makeMailMerge(MailMerge
*)
4750 hchar_string
const boxstr
= MailMerge::GetString();
4751 rchars(reinterpret_cast<sal_Unicode
const *>(hconv(boxstr
.c_str())));
4755 void HwpReader::makeOutline(Outline
const * hbox
)
4757 if( hbox
->kind
== 1 )
4758 rchars( reinterpret_cast<sal_Unicode
const *>(hbox
->GetUnicode().c_str()) );
4762 void HwpReader::parsePara(HWPPara
* para
)
4764 bool bParaStart
= false;
4771 padd("text:style-name", sXML_CDATA
,
4772 ascii(getPStyleName(para
->GetParaShape().index
, buf
)));
4773 rstartEl( "text:p",mxList
.get());
4776 if( d
->bFirstPara
&& d
->bInBody
)
4778 /* for HWP's Bookmark */
4781 "[\xEB\xAC\xB8\xEC\x84\x9C\xEC\x9D\x98"
4782 " \xEC\xB2\x98\xEC\x9D\x8C]");
4783 // U+BB38 HANGUL SYLLABLE MUN, U+C11C HANGUL SYLLABLE SEO,
4784 // U+C758 HANGUL SYLLABLE YI, U+CC98 HANGUL SYLLABLE CEO,
4785 // U+C74C HANGUL SYLLABLE EUM: "Begin of Document"
4786 padd("text:name", sXML_CDATA
, OUString(buf
, strlen(buf
), RTL_TEXTENCODING_UTF8
));
4787 rstartEl("text:bookmark", mxList
.get());
4789 rendEl("text:bookmark");
4790 d
->bFirstPara
= false;
4795 d
->bInHeader
= false;
4802 if (!para
->ctrlflag
)
4804 if (para
->contain_cshape
)
4805 make_text_p1(para
, bParaStart
);
4807 make_text_p0(para
, bParaStart
);
4810 make_text_p3(para
, bParaStart
);
4813 para
= para
->Next();
4817 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */