update credits
[LibreOffice.git] / hwpfilter / source / hwpreader.cxx
blobfe997965214a0aa2e8830f5b330f0e6bd314ba06
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <deque>
22 #include <boost/shared_ptr.hpp>
24 #include "hwpreader.hxx"
25 #include <math.h>
27 #include <comphelper/newarray.hxx>
29 #include "formula.h"
30 #include "cspline.h"
32 extern int getRepFamilyName(const char* , char *, double &ratio);
34 #include <iostream>
35 #include <locale.h>
36 #include <sal/types.h>
37 // #i42367# prevent MS compiler from using system locale for parsing
38 #ifdef _MSC_VER
39 #pragma setlocale("C")
40 #endif
42 // To be shorten source code by realking
43 #define hconv(x) OUString(hstr2ucsstr(x).c_str())
44 #define ascii(x) OUString::createFromAscii(x)
45 #define rstartEl(x,y) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->startElement(x,y); } while(0)
46 #define rendEl(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->endElement(x); } while(0)
47 #define rchars(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->characters(x); } while(0)
48 #define padd(x,y,z) pList->addAttribute(x,y,z)
49 #define Double2Str(x) OUString::valueOf((double)(x))
50 #define WTI(x) ((double)(x) / 1800.) // unit => inch
51 #define WTMM(x) ((double)(x) / 1800. * 25.4) // unit => mm
52 #define WTSM(x) ((int)((x) / 1800. * 2540)) // unit ==> 1/100 mm
54 #define PI 3.14159265358979323846
56 // xmloff/xmlkyd.hxx
57 #define sXML_CDATA ascii("CDATA")
59 #define STARTP padd( ascii("text:style-name"), ascii("CDATA"), ascii(getPStyleName(((ParaShape *)para->GetParaShape())->index,buf))); \
60 rstartEl( ascii("text:p"),rList ); \
61 pList->clear(); \
62 pstart = true
63 #define STARTT \
64 curr = para->GetCharShape(n > 0 ? n-1 : 0)->index; \
65 padd( ascii("text:style-name"), ascii("CDATA") , ascii( getTStyleName(curr, buf) ) ); \
66 rstartEl( ascii("text:span"),rList ); \
67 pList->clear(); \
68 tstart = true
69 #define ENDP \
70 rendEl(ascii("text:p")); \
71 pstart = false
72 #define ENDT \
73 rendEl(ascii("text:span")); \
74 tstart = false
76 static hchar *field = 0L;
77 static char buf[1024];
79 namespace
82 template<typename T>
83 struct Free
85 void operator()(T* const ptr)
87 free(ptr);
93 struct HwpReaderPrivate
95 HwpReaderPrivate()
97 bFirstPara = true;
98 bInBody = false;
99 bInHeader = false;
100 nPnPos = 0;
101 pPn = 0L;
104 bool bFirstPara;
105 bool bInBody;
106 bool bInHeader;
107 ShowPageNum *pPn;
108 int nPnPos;
111 HwpReader::HwpReader()
113 pList = new AttributeListImpl;
114 rList = (XAttributeList *) pList;
115 d = new HwpReaderPrivate;
119 HwpReader::~HwpReader()
121 rList = 0;
122 delete d;
126 sal_Bool HwpReader::filter(const Sequence< PropertyValue >& rDescriptor) throw(RuntimeException)
128 comphelper::MediaDescriptor aDescriptor(rDescriptor);
129 aDescriptor.addInputStream();
131 Reference< XInputStream > xInputStream(
132 aDescriptor[comphelper::MediaDescriptor::PROP_INPUTSTREAM()], UNO_QUERY_THROW);
134 HStream stream;
135 Sequence < sal_Int8 > aBuffer;
136 sal_Int32 nRead, nBlock = 32768, nTotal = 0;
137 while( 1 )
139 nRead = xInputStream->readBytes(aBuffer, nBlock);
140 if( nRead == 0 )
141 break;
142 stream.addData( (const byte *)aBuffer.getConstArray(), nRead );
143 nTotal += nRead;
146 if( nTotal == 0 ) return sal_False;
148 if (hwpfile.ReadHwpFile(stream))
149 return sal_False;
151 if (m_rxDocumentHandler.is())
152 m_rxDocumentHandler->startDocument();
154 padd(ascii("office:class"), sXML_CDATA, ascii("text"));
155 padd(ascii("office:version"), sXML_CDATA, ascii("0.9"));
157 padd(ascii("xmlns:office"), ascii("CDATA"), ascii("http://openoffice.org/2000/office"));
158 padd(ascii("xmlns:style"), ascii("CDATA"), ascii("http://openoffice.org/2000/style"));
159 padd(ascii("xmlns:text"), ascii("CDATA"), ascii("http://openoffice.org/2000/text"));
160 padd(ascii("xmlns:table"), ascii("CDATA"), ascii("http://openoffice.org/2000/table"));
161 padd(ascii("xmlns:draw"), ascii("CDATA"), ascii("http://openoffice.org/2000/drawing"));
162 padd(ascii("xmlns:fo"), ascii("CDATA"), ascii("http://www.w3.org/1999/XSL/Format"));
163 padd(ascii("xmlns:xlink"), ascii("CDATA"), ascii("http://www.w3.org/1999/xlink"));
164 padd(ascii("xmlns:dc"), ascii("CDATA"), ascii("http://purl.org/dc/elements/1.1/"));
165 padd(ascii("xmlns:meta"), ascii("CDATA"), ascii("http://openoffice.org/2000/meta"));
166 padd(ascii("xmlns:number"), ascii("CDATA"), ascii("http://openoffice.org/2000/datastyle"));
167 padd(ascii("xmlns:svg"), ascii("CDATA"), ascii("http://www.w3.org/2000/svg"));
168 padd(ascii("xmlns:chart"), ascii("CDATA"), ascii("http://openoffice.org/2000/chart"));
169 padd(ascii("xmlns:dr3d"), ascii("CDATA"), ascii("http://openoffice.org/2000/dr3d"));
170 padd(ascii("xmlns:math"), ascii("CDATA"), ascii("http://www.w3.org/1998/Math/MathML"));
171 padd(ascii("xmlns:form"), ascii("CDATA"), ascii("http://openoffice.org/2000/form"));
172 padd(ascii("xmlns:script"), ascii("CDATA"), ascii("http://openoffice.org/2000/script"));
174 rstartEl(ascii("office:document"), rList);
175 pList->clear();
177 makeMeta();
178 makeStyles();
179 makeAutoStyles();
180 makeMasterStyles();
181 makeBody();
183 rendEl(ascii("office:document"));
185 if (m_rxDocumentHandler.is())
186 m_rxDocumentHandler->endDocument();
187 return sal_True;
192 * make office:body
194 void HwpReader::makeBody()
196 rstartEl(ascii("office:body"), rList);
197 makeTextDecls();
198 HWPPara *hwppara = hwpfile.GetFirstPara();
199 d->bInBody = true;
200 parsePara(hwppara);
201 rendEl(ascii("office:body"));
202 d->bInBody = false;
207 * make text decls
209 void HwpReader::makeTextDecls()
211 rstartEl(ascii("text:sequence-decls"), rList);
212 padd(ascii("text:display-outline-level"), sXML_CDATA, ascii("0"));
213 padd(ascii("text:name"), sXML_CDATA, ascii("Illustration"));
214 rstartEl(ascii("text:sequence-decl"), rList);
215 pList->clear();
216 rendEl(ascii("text:sequence-decl"));
217 padd(ascii("text:display-outline-level"), sXML_CDATA, ascii("0"));
218 padd(ascii("text:name"), sXML_CDATA, ascii("Table"));
219 rstartEl(ascii("text:sequence-decl"), rList);
220 pList->clear();
221 rendEl(ascii("text:sequence-decl"));
222 padd(ascii("text:display-outline-level"), sXML_CDATA, ascii("0"));
223 padd(ascii("text:name"), sXML_CDATA, ascii("Text"));
224 rstartEl(ascii("text:sequence-decl"), rList);
225 pList->clear();
226 rendEl(ascii("text:sequence-decl"));
227 padd(ascii("text:display-outline-level"), sXML_CDATA, ascii("0"));
228 padd(ascii("text:name"), sXML_CDATA, ascii("Drawing"));
229 rstartEl(ascii("text:sequence-decl"), rList);
230 pList->clear();
231 rendEl(ascii("text:sequence-decl"));
232 rendEl(ascii("text:sequence-decls"));
236 #define ISNUMBER(x) ( (x) <= 0x39 && (x) >= 0x30 )
238 * make office:meta
239 * Completed
241 void HwpReader::makeMeta()
243 HWPInfo *hwpinfo = hwpfile.GetHWPInfo();
245 rstartEl(ascii("office:meta"), rList);
247 if (hwpinfo->summary.title[0])
249 rstartEl(ascii("dc:title"), rList);
250 rchars((hconv(hwpinfo->summary.title)));
251 rendEl(ascii("dc:title"));
254 if (hwpinfo->summary.subject[0])
256 rstartEl(ascii("dc:subject"), rList);
257 rchars((hconv(hwpinfo->summary.subject)));
258 rendEl(ascii("dc:subject"));
261 if (hwpinfo->summary.author[0])
263 rstartEl(ascii("meta:initial-creator"), rList);
264 rchars((hconv(hwpinfo->summary.author)));
265 rendEl(ascii("meta:initial-creator"));
268 if (hwpinfo->summary.date[0])
270 unsigned short *pDate = hwpinfo->summary.date;
271 int year,month,day,hour,minute;
272 int gab = 0;
273 if( ISNUMBER( pDate[0] ) && ISNUMBER( pDate[1] ) &&
274 ISNUMBER( pDate[2] ) && ISNUMBER( pDate[3] ))
276 year = (pDate[0]-0x30) * 1000 + (pDate[1]-0x30) * 100 +
277 (pDate[2]-0x30) * 10 + (pDate[3]-0x30);
279 else {
280 year = 0;
282 if( ISNUMBER( pDate[6] ))
284 if( ISNUMBER( pDate[7] ) )
285 month = (pDate[6] - 0x30) * 10 + (pDate[6+ ++gab]-0x30);
286 else
287 month = (pDate[6] - 0x30);
289 else {
290 month = 0;
292 if( ISNUMBER( pDate[9 + gab] ) )
294 if( ISNUMBER( pDate[10 + gab])) {
295 day = ( pDate[9 + gab] - 0x30 ) * 10 + (pDate[9+ gab + 1]-0x30);
296 ++gab;
297 } else
298 day = (pDate[9+gab]-0x30);
300 else {
301 day = 0;
303 if( ISNUMBER( pDate[17 + gab] ) )
305 if( ISNUMBER( pDate[18 + gab])) {
306 hour = ( pDate[17 + gab] - 0x30 ) * 10 + (pDate[17+ gab + 1]-0x30);
307 ++gab;
308 } else
309 hour = (pDate[17+gab]-0x30);
311 else {
312 hour = 0;
314 if( ISNUMBER( pDate[20 + gab] ) )
316 if( ISNUMBER( pDate[21 + gab])) {
317 minute = ( pDate[20 + gab] - 0x30 ) * 10 + (pDate[20+ gab + 1]-0x30);
318 ++gab;
319 } else
320 minute = (pDate[20+gab]-0x30);
322 else {
323 minute = 0;
325 sprintf(buf,"%d-%02d-%02dT%02d:%02d:00",year,month,day,hour,minute);
327 rstartEl( ascii("meta:creation-date"), rList );
328 rchars( ascii(buf));
329 rendEl( ascii("meta:creation-date") );
332 if (hwpinfo->summary.keyword[0][0] || hwpinfo->summary.etc[0][0])
334 rstartEl(ascii("meta:keywords"), rList);
335 if (hwpinfo->summary.keyword[0][0])
337 rstartEl(ascii("meta:keyword"), rList);
338 rchars((hconv(hwpinfo->summary.keyword[0])));
339 rendEl(ascii("meta:keyword"));
341 if (hwpinfo->summary.keyword[1][0])
343 rstartEl(ascii("meta:keyword"), rList);
344 rchars((hconv(hwpinfo->summary.keyword[1])));
345 rendEl(ascii("meta:keyword"));
347 if (hwpinfo->summary.etc[0][0])
349 rstartEl(ascii("meta:keyword"), rList);
350 rchars((hconv(hwpinfo->summary.etc[0])));
351 rendEl(ascii("meta:keyword"));
353 if (hwpinfo->summary.etc[1][0])
355 rstartEl(ascii("meta:keyword"), rList);
356 rchars((hconv(hwpinfo->summary.etc[1])));
357 rendEl(ascii("meta:keyword"));
359 if (hwpinfo->summary.etc[2][0])
361 rstartEl(ascii("meta:keyword"), rList);
362 rchars((hconv(hwpinfo->summary.etc[2])));
363 rendEl(ascii("meta:keyword"));
365 rendEl(ascii("meta:keywords"));
367 rendEl(ascii("office:meta"));
371 static struct
373 const char *name;
374 bool bMade;
376 ArrowShape[] =
378 { "", false },
379 { "Arrow", false },
380 { "Line Arrow", false },
381 { "Square", false }
384 static struct
386 double dots1;
387 double dots2;
388 double distance;
392 LineStyle[] =
394 { 0.0, 0.0, 0.0 },
396 0.34, 0., 0.272
398 { 0.17, 0., 0.136},
400 0.612, 0.17, 0.136
402 { 0.85, 0.17, 0.136}
405 void HwpReader::makeDrawMiscStyle( HWPDrawingObject *hdo )
407 while( hdo )
409 if( hdo->child )
410 makeDrawMiscStyle( hdo->child );
412 HWPDOProperty *prop = &hdo->property;
413 if( hdo->type == HWPDO_CONTAINER )
415 hdo = hdo->next;
416 continue;
419 if( prop->line_pstyle > 0 && prop->line_pstyle < 5 && prop->line_color <= 0xffffff)
421 padd( ascii("draw:name"), sXML_CDATA, ascii(Int2Str(hdo->index, "LineType%d", buf)));
422 padd( ascii("draw:style"), sXML_CDATA, ascii("round"));
423 padd( ascii("draw:dots1"), sXML_CDATA, ascii("1"));
424 padd( ascii("draw:dots1-length"), sXML_CDATA, Double2Str( LineStyle[prop->line_pstyle].dots1 * WTMM(prop->line_width) ) + ascii("cm"));
425 if( prop->line_pstyle == 3 )
427 padd( ascii("draw:dots2"), sXML_CDATA, ascii("1"));
428 padd( ascii("draw:dots2-length"), sXML_CDATA, Double2Str( LineStyle[prop->line_pstyle].dots2 * WTMM(prop->line_width) ) + ascii("cm"));
430 else if( prop->line_pstyle == 4 )
432 padd( ascii("draw:dots2"), sXML_CDATA, ascii("2"));
433 padd( ascii("draw:dots2-length"), sXML_CDATA, Double2Str( LineStyle[prop->line_pstyle].dots2 * WTMM(prop->line_width)) + ascii("cm"));
435 padd( ascii("draw:distance"), sXML_CDATA, Double2Str( LineStyle[prop->line_pstyle].distance * WTMM(prop->line_width)) + ascii("cm"));
436 rstartEl( ascii("draw:stroke-dash"), rList);
437 pList->clear();
438 rendEl( ascii("draw:stroke-dash") );
441 if( hdo->type == HWPDO_LINE || hdo->type == HWPDO_ARC || hdo->type == HWPDO_FREEFORM ||
442 hdo->type == HWPDO_ADVANCED_ARC )
444 if( prop->line_tstyle && !ArrowShape[prop->line_tstyle].bMade )
446 ArrowShape[prop->line_tstyle].bMade = true;
447 padd(ascii("draw:name"), sXML_CDATA,
448 ascii(ArrowShape[prop->line_tstyle].name));
449 if( prop->line_tstyle == 1 )
451 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 20 30"));
452 padd(ascii("svg:d"), sXML_CDATA, ascii("m10 0-10 30h20z"));
454 else if( prop->line_tstyle == 2 )
456 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 1122 2243"));
457 padd(ascii("svg:d"), sXML_CDATA, ascii("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"));
459 else if( prop->line_tstyle == 3 )
461 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 30 30"));
462 padd(ascii("svg:d"), sXML_CDATA, ascii("m0 0h30v30h-30z"));
464 rstartEl(ascii("draw:marker"), rList);
465 pList->clear();
466 rendEl(ascii("draw:marker"));
468 if( prop->line_hstyle && !ArrowShape[prop->line_hstyle].bMade)
470 ArrowShape[prop->line_hstyle].bMade = true;
471 padd(ascii("draw:name"), sXML_CDATA,
472 ascii(ArrowShape[prop->line_hstyle].name));
473 if( prop->line_hstyle == 1 )
475 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 20 30"));
476 padd(ascii("svg:d"), sXML_CDATA, ascii("m10 0-10 30h20z"));
478 else if( prop->line_hstyle == 2 )
480 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 1122 2243"));
481 padd(ascii("svg:d"), sXML_CDATA, ascii("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"));
483 else if( prop->line_hstyle == 3 )
485 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 20 20"));
486 padd(ascii("svg:d"), sXML_CDATA, ascii("m0 0h20v20h-20z"));
488 rstartEl(ascii("draw:marker"), rList);
489 pList->clear();
490 rendEl(ascii("draw:marker"));
494 if( hdo->type != HWPDO_LINE )
496 if( prop->flag >> 18 & 0x01 )
498 padd( ascii("draw:name"), sXML_CDATA, ascii(Int2Str(hdo->index, "fillimage%d", buf)));
499 if( !prop->pictype )
501 padd( ascii("xlink:href"), sXML_CDATA,
502 hconv(kstr2hstr( (uchar *)urltounix(prop->szPatternFile).c_str()).c_str()));
504 else
506 EmPicture *emp = 0L;
507 if ( strlen( prop->szPatternFile ) > 3)
508 emp = hwpfile.GetEmPictureByName(prop->szPatternFile);
509 if( emp )
511 char filename[128+17+9];
512 char dirname[128];
513 int fd;
514 #ifdef _WIN32
515 GetTempPath(sizeof(dirname), dirname);
516 sprintf(filename, "%s%s",dirname, emp->name);
517 if( (fd = open( filename , _O_CREAT | _O_WRONLY | _O_BINARY , 0666)) >= 0 )
518 #else
519 strcpy(dirname, "/tmp/");
520 sprintf(filename, "%s%s", dirname, emp->name);
521 if( (fd = open( filename , O_CREAT | O_WRONLY , 0666)) >= 0 )
522 #endif
524 size_t nWritten = write(fd, emp->data, emp->size);
525 OSL_VERIFY(nWritten == emp->size);
526 close(fd);
528 #ifdef _WIN32
529 int j;
530 for(j = 0 ; j < (int)strlen( dirname ) ; j++)
532 if( dirname[j] == '\\' ) buf[j] = '/';
533 else buf[j] = dirname[j];
535 buf[j] = '\0';
536 sprintf(filename, "file:///%s%s",buf, emp->name );
537 #else
538 sprintf(filename, "file://%s%s",dirname, emp->name );
539 #endif
540 padd( ascii("xlink:href"), sXML_CDATA, ascii(filename));
542 else
544 padd( ascii("xlink:href"), sXML_CDATA,
545 hconv(kstr2hstr( (uchar *)urltounix(prop->szPatternFile).c_str()).c_str()));
549 padd( ascii("xlink:type"), sXML_CDATA, ascii("simple"));
550 padd( ascii("xlink:show"), sXML_CDATA, ascii("embed"));
551 padd( ascii("xlink:actuate"), sXML_CDATA, ascii("onLoad"));
553 rstartEl( ascii("draw:fill-image"), rList);
554 pList->clear();
555 rendEl( ascii("draw:fill-image"));
557 /* 그라데이션이 존재해도, 비트맵파일이 존재하면, 이것이 우선이다. */
558 else if( prop->flag >> 16 & 0x01 ) /* 그라데이션 존재여부 */
560 padd( ascii("draw:name"), sXML_CDATA, ascii(Int2Str(hdo->index, "Grad%d", buf)));
561 switch( prop->gstyle )
563 case 1 :
564 if( prop->center_y == 50 )
565 padd( ascii("draw:style"), sXML_CDATA, ascii("axial"));
566 else
567 padd( ascii("draw:style"), sXML_CDATA, ascii("linear"));
568 break;
569 case 2:
570 case 3:
571 padd( ascii("draw:style"), sXML_CDATA, ascii("radial"));
572 break;
573 case 4:
574 padd( ascii("draw:style"), sXML_CDATA, ascii("square"));
575 break;
576 default:
577 padd( ascii("draw:style"), sXML_CDATA, ascii("linear"));
578 break;
580 padd( ascii("draw:cx"), sXML_CDATA,ascii(Int2Str(prop->center_x, "%d%%", buf)));
581 padd( ascii("draw:cy"), sXML_CDATA,ascii(Int2Str(prop->center_y, "%d%%", buf)));
583 HWPInfo *hwpinfo = hwpfile.GetHWPInfo();
584 int default_color = 0xffffff;
585 if( hwpinfo->back_info.isset )
587 if( hwpinfo->back_info.color[0] > 0 || hwpinfo->back_info.color[1] > 0
588 || hwpinfo->back_info.color[2] > 0 )
589 default_color = hwpinfo->back_info.color[0] << 16 |
590 hwpinfo->back_info.color[1] << 8 | hwpinfo->back_info.color[2];
593 if( prop->fromcolor > 0xffffff )
594 prop->fromcolor = default_color;
595 if( prop->tocolor > 0xffffff )
596 prop->tocolor = default_color;
598 if( prop->gstyle == 1)
600 if( prop->center_y == 100 )
602 sprintf( buf, "#%02x%02x%02x", prop->tocolor & 0xff,
603 (prop->tocolor >> 8) & 0xff, (prop->tocolor >>16) & 0xff );
604 padd( ascii("draw:start-color"), sXML_CDATA, ascii( buf ));
605 sprintf( buf, "#%02x%02x%02x", prop->fromcolor & 0xff,
606 (prop->fromcolor >> 8) & 0xff, (prop->fromcolor >>16) & 0xff );
607 padd( ascii("draw:end-color"), sXML_CDATA, ascii( buf ));
609 else
611 sprintf( buf, "#%02x%02x%02x", prop->fromcolor & 0xff,
612 (prop->fromcolor >> 8) & 0xff, (prop->fromcolor >>16) & 0xff );
613 padd( ascii("draw:start-color"), sXML_CDATA, ascii( buf ));
614 sprintf( buf, "#%02x%02x%02x", prop->tocolor & 0xff,
615 (prop->tocolor >> 8) & 0xff, (prop->tocolor >>16) & 0xff );
616 padd( ascii("draw:end-color"), sXML_CDATA, ascii( buf ));
619 else
621 sprintf( buf, "#%02x%02x%02x", prop->tocolor & 0xff,
622 (prop->tocolor >> 8) & 0xff, (prop->tocolor >>16) & 0xff );
623 padd( ascii("draw:start-color"), sXML_CDATA,ascii( buf ));
625 sprintf( buf, "#%02x%02x%02x", prop->fromcolor & 0xff,
626 (prop->fromcolor >> 8) & 0xff, (prop->fromcolor >>16) & 0xff );
627 padd( ascii("draw:end-color"), sXML_CDATA,ascii( buf ));
629 if( prop->angle > 0 && ( prop->gstyle == 1 || prop->gstyle == 4))
631 int angle = prop->angle >= 180 ? prop->angle - 180 : prop->angle;
632 angle = 1800 - prop->angle * 10;
633 padd( ascii("draw:angle"), sXML_CDATA,
634 ascii(Int2Str( angle, "%d", buf)));
636 rstartEl( ascii("draw:gradient"), rList );
637 pList->clear();
638 rendEl( ascii("draw:gradient"));
640 /* 해칭 */
641 else if( prop->pattern_type >> 24 & 0x01 )
643 int type = prop->pattern_type & 0xffffff;
644 padd( ascii("draw:name"), sXML_CDATA,
645 ascii(Int2Str(hdo->index, "Hatch%d", buf)));
646 if( type < 4 )
647 padd( ascii("draw:style"), sXML_CDATA, ascii("single") );
648 else
649 padd( ascii("draw:style"), sXML_CDATA, ascii("double") );
650 sprintf( buf, "#%02x%02x%02x",
651 sal_uInt16(prop->pattern_color & 0xff),
652 sal_uInt16((prop->pattern_color >> 8) & 0xff),
653 sal_uInt16((prop->pattern_color >>16) & 0xff) );
654 padd( ascii("draw:color"), sXML_CDATA, ascii( buf ));
655 padd( ascii("draw:distance"), sXML_CDATA, ascii("0.12cm"));
656 switch( type )
658 case 0 :
659 case 4 :
660 padd( ascii("draw:rotation"), sXML_CDATA, ascii("0"));
661 break;
662 case 1 :
663 padd( ascii("draw:rotation"), sXML_CDATA, ascii("900"));
664 break;
665 case 2 :
666 padd( ascii("draw:rotation"), sXML_CDATA, ascii("1350"));
667 break;
668 case 3 :
669 case 5 :
670 padd( ascii("draw:rotation"), sXML_CDATA, ascii("450"));
671 break;
673 rstartEl( ascii("draw:hatch"), rList);
674 pList->clear();
675 rendEl( ascii("draw:hatch"));
678 hdo = hdo->next;
683 void HwpReader::makeStyles()
685 HWPStyle *hwpstyle = hwpfile.GetHWPStyle();
687 rstartEl(ascii("office:styles"), rList);
689 int i;
690 for (i = 0; i < hwpfile.getFBoxStyleCount(); i++)
692 if( hwpfile.getFBoxStyle(i)->boxtype == 'D' )
694 makeDrawMiscStyle((HWPDrawingObject *)hwpfile.getFBoxStyle(i)->cell );
698 padd(ascii("style:name"), sXML_CDATA, ascii("Standard"));
699 padd(ascii("style:family"), sXML_CDATA, ascii("paragraph"));
700 padd(ascii("style:class"), sXML_CDATA, ascii("text"));
701 rstartEl(ascii("style:style"), rList);
702 pList->clear();
704 padd(ascii("fo:line-height"), sXML_CDATA, ascii("160%"));
705 padd(ascii("fo:text-align"), sXML_CDATA, ascii("justify"));
706 rstartEl(ascii("style:properties"), rList);
707 pList->clear();
708 rstartEl(ascii("style:tab-stops"), rList);
710 for( i = 1 ; i < 40 ; i++)
712 padd(ascii("style:position"), sXML_CDATA,
713 Double2Str( WTI(1000 * i)) + ascii("inch"));
714 rstartEl(ascii("style:tab-stop"), rList);
715 pList->clear();
716 rendEl(ascii("style:tab-stop"));
718 rendEl(ascii("style:tab-stops"));
719 rendEl(ascii("style:properties"));
721 rendEl(ascii("style:style"));
723 for (int ii = 0; ii < hwpstyle->Num(); ii++)
725 unsigned char *stylename = (unsigned char *) hwpstyle->GetName(ii);
726 padd(ascii("style:name"), sXML_CDATA, (hconv(kstr2hstr(stylename).c_str())));
727 padd(ascii("style:family"), sXML_CDATA, ascii("paragraph"));
728 padd(ascii("style:parent-style-name"), sXML_CDATA, ascii("Standard"));
730 rstartEl(ascii("style:style"), rList);
732 pList->clear();
734 parseCharShape(hwpstyle->GetCharShape(ii));
735 parseParaShape(hwpstyle->GetParaShape(ii));
737 rstartEl(ascii("style:properties"), rList);
738 pList->clear();
739 rendEl(ascii("style:properties"));
741 rendEl(ascii("style:style"));
745 padd( ascii("style:name"), sXML_CDATA, ascii("Header"));
746 padd( ascii("style:family"), sXML_CDATA, ascii("paragraph"));
747 padd( ascii("style:parent-style-name"), sXML_CDATA, ascii("Standard"));
748 padd( ascii("style:class"), sXML_CDATA, ascii("extra"));
749 rstartEl(ascii("style:style"), rList);
750 pList->clear();
751 rendEl(ascii("style:style"));
755 padd( ascii("style:name"), sXML_CDATA, ascii("Footer"));
756 padd( ascii("style:family"), sXML_CDATA, ascii("paragraph"));
757 padd( ascii("style:parent-style-name"), sXML_CDATA, ascii("Standard"));
758 padd( ascii("style:class"), sXML_CDATA, ascii("extra"));
759 rstartEl(ascii("style:style"), rList);
760 pList->clear();
762 rendEl(ascii("style:style"));
765 if( hwpfile.linenumber > 0)
767 padd( ascii("style:name"), sXML_CDATA, ascii("Horizontal Line"));
768 padd( ascii("style:family"), sXML_CDATA, ascii("paragraph"));
769 padd( ascii("style:parent-style-name"), sXML_CDATA, ascii("Standard"));
770 padd( ascii("style:class"), sXML_CDATA, ascii("html"));
771 rstartEl( ascii("style:style"), rList);
772 pList->clear();
773 padd( ascii("fo:font-size"), sXML_CDATA, ascii("6pt"));
774 padd( ascii("fo:margin-top"), sXML_CDATA, ascii("0cm"));
775 padd( ascii("fo:margin-bottom"), sXML_CDATA, ascii("0cm"));
776 padd( ascii("style:border-line-width-bottom"), sXML_CDATA, ascii("0.02cm 0.035cm 0.002cm"));
777 padd( ascii("fo:padding"), sXML_CDATA, ascii("0cm"));
778 padd( ascii("fo:border-bottom"), sXML_CDATA, ascii("0.039cm double #808080"));
779 padd( ascii("text:number-lines"), sXML_CDATA, ascii("false"));
780 padd( ascii("text:line-number"), sXML_CDATA, ascii("0"));
781 padd(ascii("fo:line-height"), sXML_CDATA, ascii("100%"));
782 rstartEl( ascii("style:properties"), rList);
783 pList->clear();
784 rendEl( ascii("style:properties"));
785 rendEl( ascii("style:style"));
788 HWPInfo *hwpinfo = hwpfile.GetHWPInfo();
790 padd(ascii("text:num-suffix"), sXML_CDATA, ascii(")"));
791 padd(ascii("text:num-format"), sXML_CDATA, ascii("1"));
792 if( hwpinfo->beginfnnum != 1)
793 padd(ascii("text:offset"), sXML_CDATA, ascii(Int2Str(hwpinfo->beginfnnum -1, "%d", buf)));
794 rstartEl(ascii("text:footnotes-configuration"), rList);
795 pList->clear();
796 rendEl(ascii("text:footnotes-configuration"));
798 rendEl(ascii("office:styles"));
803 * parse automatic styles from hwpfile
804 * 자동적으로 반영이 되는 스타일을 정의한다. 예를들어 각각의 문단이나, 테이블, 헤더 등등의 스타일을 이곳에서 정의하고, Body에서는 이곳에 정의된 스타일을 이용한다.
805 * 1. paragraph, text, fbox, page스타일에 대해 지원한다.
807 void HwpReader::makeAutoStyles()
809 int i;
811 rstartEl(ascii("office:automatic-styles"), rList);
813 for (i = 0; i < hwpfile.getParaShapeCount(); i++)
814 makePStyle(hwpfile.getParaShape(i));
816 for (i = 0; i < hwpfile.getCharShapeCount(); i++)
817 makeTStyle(hwpfile.getCharShape(i));
819 for( i = 0 ; i < hwpfile.getTableCount(); i++)
820 makeTableStyle(hwpfile.getTable(i));
822 for (i = 0; i < hwpfile.getFBoxStyleCount(); i++)
824 if( hwpfile.getFBoxStyle(i)->boxtype == 'D' )
825 makeDrawStyle((HWPDrawingObject *)hwpfile.getFBoxStyle(i)->cell, hwpfile.getFBoxStyle(i));
826 else
827 makeFStyle(hwpfile.getFBoxStyle(i));
830 sal_Bool bIsLeft = sal_False, bIsMiddle = sal_False, bIsRight = sal_False;
831 for( i = 0 ; i < hwpfile.getPageNumberCount() ; i++ )
833 ShowPageNum *pn = hwpfile.getPageNumber(i);
834 if( pn->where == 7 || pn->where == 8 )
836 bIsLeft = sal_True;
837 bIsRight = sal_True;
839 else if( pn->where == 1 || pn->where == 4 )
841 bIsLeft = sal_True;
843 else if( pn->where == 2 || pn->where == 5 )
845 bIsMiddle = sal_True;
847 else if( pn->where == 3 || pn->where == 6 )
849 bIsRight = sal_True;
853 for( i = 1; i <= 3 ; i++ )
855 if( i == 1 && bIsLeft == sal_False )
856 continue;
857 if( i == 2 && bIsMiddle == sal_False )
858 continue;
859 if( i == 3 && bIsRight == sal_False )
860 continue;
861 padd(ascii("style:name"), sXML_CDATA,
862 ascii(Int2Str(i,"PNPara%d", buf)));
863 padd(ascii("style:family"), sXML_CDATA, ascii("paragraph"));
864 padd(ascii("style:parent-style-name"), sXML_CDATA, ascii("Standard"));
865 rstartEl(ascii("style:style"), rList);
866 pList->clear();
867 if( i == 1 )
868 padd(ascii("fo:text-align"), sXML_CDATA, ascii("start"));
869 else if ( i == 2 )
870 padd(ascii("fo:text-align"), sXML_CDATA, ascii("center"));
871 else if ( i == 3 )
872 padd(ascii("fo:text-align"), sXML_CDATA, ascii("end"));
873 rstartEl(ascii("style:properties"), rList);
874 pList->clear();
875 rendEl( ascii("style:properties"));
876 rendEl( ascii("style:style"));
878 padd(ascii("style:name"), sXML_CDATA, ascii(Int2Str(i,"PNBox%d",buf)));
879 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
880 rstartEl(ascii("style:style"), rList);
881 pList->clear();
883 padd(ascii("fo:margin-top"), sXML_CDATA, ascii("0cm"));
884 padd(ascii("fo:margin-bottom"), sXML_CDATA, ascii("0cm"));
885 padd(ascii("style:wrap"), sXML_CDATA, ascii("run-through"));
886 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("from-top"));
887 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("paragraph"));
889 if( i == 1 )
890 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("left"));
891 else if ( i == 2 )
892 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("center"));
893 else if ( i == 3 )
894 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("right"));
895 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
896 padd(ascii("fo:padding"), sXML_CDATA, ascii("0cm"));
897 padd(ascii("stylefamily"), sXML_CDATA, ascii("graphics"));
898 rstartEl(ascii("style:properties"), rList);
899 pList->clear();
900 rendEl(ascii("style:properties"));
901 rendEl(ascii("style:style"));
904 for (i = 0; i < hwpfile.getDateFormatCount(); i++)
905 makeDateFormat(hwpfile.getDateCode(i));
907 makePageStyle();
909 rendEl(ascii("office:automatic-styles"));
913 struct PageSetting
915 PageSetting()
917 header = 0L;
918 header_odd = 0L;
919 header_even = 0L;
920 footer = 0L;
921 footer_odd = 0L;
922 footer_even = 0L;
923 pagenumber=0L;
924 bIsSet = false;
926 HeaderFooter *header ;
927 HeaderFooter *header_odd ;
928 HeaderFooter *header_even ;
929 HeaderFooter *footer ;
930 HeaderFooter *footer_odd ;
931 HeaderFooter *footer_even ;
932 ShowPageNum *pagenumber;
933 bool bIsSet;
936 void HwpReader::makeMasterStyles()
938 rstartEl(ascii("office:master-styles"), rList);
940 int i;
941 int nMax = hwpfile.getMaxSettedPage();
942 std::deque<PageSetting> pSet(nMax + 1);
944 for( i = 0 ; i < hwpfile.getPageNumberCount() ; i++ )
946 ShowPageNum *pn = hwpfile.getPageNumber(i);
947 pSet[pn->m_nPageNumber].pagenumber = pn;
948 pSet[pn->m_nPageNumber].bIsSet = true;
950 for( i = 0 ; i < hwpfile.getHeaderFooterCount() ; i++ )
952 HeaderFooter* hf = hwpfile.getHeaderFooter(i);
953 pSet[hf->m_nPageNumber].bIsSet = true;
954 if( hf->type == 0 ) // header
956 switch( hf->where )
958 case 0 :
959 pSet[hf->m_nPageNumber].header = hf;
960 pSet[hf->m_nPageNumber].header_even = 0L;
961 pSet[hf->m_nPageNumber].header_odd = 0L;
962 break;
963 case 1:
964 pSet[hf->m_nPageNumber].header_even = hf;
965 if( pSet[hf->m_nPageNumber].header )
967 pSet[hf->m_nPageNumber].header_odd =
968 pSet[hf->m_nPageNumber].header;
969 pSet[hf->m_nPageNumber].header = 0L;
971 break;
972 case 2:
973 pSet[hf->m_nPageNumber].header_odd = hf;
974 if( pSet[hf->m_nPageNumber].header )
976 pSet[hf->m_nPageNumber].header_even =
977 pSet[hf->m_nPageNumber].header;
978 pSet[hf->m_nPageNumber].header = 0L;
980 break;
983 else // footer
985 switch( hf->where )
987 case 0 :
988 pSet[hf->m_nPageNumber].footer = hf;
989 pSet[hf->m_nPageNumber].footer_even = 0L;
990 pSet[hf->m_nPageNumber].footer_odd = 0L;
991 break;
992 case 1:
993 pSet[hf->m_nPageNumber].footer_even = hf;
994 if( pSet[hf->m_nPageNumber].footer )
996 pSet[hf->m_nPageNumber].footer_odd =
997 pSet[hf->m_nPageNumber].footer;
998 pSet[hf->m_nPageNumber].footer = 0L;
1000 break;
1001 case 2:
1002 pSet[hf->m_nPageNumber].footer_odd = hf;
1003 if( pSet[hf->m_nPageNumber].footer )
1005 pSet[hf->m_nPageNumber].footer_even =
1006 pSet[hf->m_nPageNumber].footer;
1007 pSet[hf->m_nPageNumber].footer = 0L;
1009 break;
1014 PageSetting *pPrevSet = 0L;
1015 PageSetting *pPage = 0L;
1017 for( i = 1; i <= nMax ; i++ )
1019 if( i == 1 )
1020 padd(ascii("style:name"), sXML_CDATA, ascii("Standard"));
1021 else
1022 padd(ascii("style:name"), sXML_CDATA,
1023 ascii(Int2Str(i, "p%d", buf)));
1024 padd(ascii("style:page-master-name"), sXML_CDATA,
1025 ascii(Int2Str(hwpfile.GetPageMasterNum(i), "pm%d", buf)));
1026 if( i < nMax )
1027 padd(ascii("style:next-style-name"), sXML_CDATA,
1028 ascii(Int2Str(i+1, "p%d", buf)));
1029 padd(ascii("draw:style-name"), sXML_CDATA,
1030 ascii(Int2Str(i, "master%d", buf)));
1031 rstartEl(ascii("style:master-page"), rList);
1032 pList->clear();
1034 if( pSet[i].bIsSet ) /* 현재 설정이 바뀌었으면 */
1036 if( !pSet[i].pagenumber ){
1037 if( pPrevSet && pPrevSet->pagenumber )
1038 pSet[i].pagenumber = pPrevSet->pagenumber;
1040 if( pSet[i].pagenumber )
1042 if( pSet[i].pagenumber->where == 7 && pSet[i].header )
1044 pSet[i].header_even = pSet[i].header;
1045 pSet[i].header_odd = pSet[i].header;
1046 pSet[i].header = 0L;
1048 if( pSet[i].pagenumber->where == 8 && pSet[i].footer )
1050 pSet[i].footer_even = pSet[i].footer;
1051 pSet[i].footer_odd = pSet[i].footer;
1052 pSet[i].footer = 0L;
1056 if( !pSet[i].header_even && pPrevSet && pPrevSet->header_even )
1058 pSet[i].header_even = pPrevSet->header_even;
1060 if( !pSet[i].header_odd && pPrevSet && pPrevSet->header_odd )
1062 pSet[i].header_odd = pPrevSet->header_odd;
1064 if( !pSet[i].footer_even && pPrevSet && pPrevSet->footer_even )
1066 pSet[i].footer_even = pPrevSet->footer_even;
1068 if( !pSet[i].footer_odd && pPrevSet && pPrevSet->footer_odd )
1070 pSet[i].footer_odd = pPrevSet->footer_odd;
1073 pPage = &pSet[i];
1074 pPrevSet = &pSet[i];
1076 else if( pPrevSet ) /* 이전의 설정된 것이 있으면. */
1078 pPage = pPrevSet;
1080 else /* 아직 설정이 없다면 기본설정으로 */
1082 rstartEl(ascii("style:header"), rList);
1083 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1084 rstartEl(ascii("text:p"), rList);
1085 pList->clear();
1086 rendEl(ascii("text:p"));
1087 rendEl(ascii("style:header"));
1089 rstartEl(ascii("style:footer"), rList);
1090 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1091 rstartEl(ascii("text:p"), rList);
1092 pList->clear();
1093 rendEl(ascii("text:p"));
1094 rendEl(ascii("style:footer"));
1096 rendEl(ascii("style:master-page"));
1098 continue;
1100 // ------------- header ------------- //
1101 if( pPage->header )
1103 rstartEl(ascii("style:header"), rList);
1104 if( pPage->pagenumber && pPage->pagenumber->where < 4 )
1106 d->bInHeader = true;
1107 d->pPn = pPage->pagenumber;
1109 parsePara(pPage->header->plist.front());
1110 d->bInHeader = false;
1111 d->pPn = 0L;
1112 rendEl(ascii("style:header"));
1114 if( pPage->header_even )
1116 rstartEl(ascii("style:header"), rList);
1117 if( pPage->pagenumber && ( pPage->pagenumber->where < 4
1118 || pPage->pagenumber->where == 7 ) )
1120 d->bInHeader = true;
1121 d->pPn = pPage->pagenumber;
1122 d->nPnPos = 3;
1124 parsePara(pPage->header_even->plist.front());
1125 d->bInHeader = false;
1126 d->pPn = 0L;
1127 d->nPnPos = 0;
1128 rendEl(ascii("style:header"));
1130 /* 기본으로 한다. */
1131 else if( pPage->header_odd && !pPage->header_even )
1133 rstartEl(ascii("style:header"), rList);
1134 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1135 rstartEl(ascii("text:p"), rList);
1136 pList->clear();
1137 if( pPage->pagenumber && ( pPage->pagenumber->where < 4 ||
1138 pPage->pagenumber->where == 7 ) )
1140 d->pPn = pPage->pagenumber;
1141 d->nPnPos = 3;
1142 makeShowPageNum();
1143 d->pPn = 0L;
1144 d->nPnPos = 0;
1146 rendEl(ascii("text:p"));
1147 rendEl(ascii("style:header"));
1149 if( pPage->header_odd )
1151 rstartEl(ascii("style:header-left"), rList);
1152 if( pPage->pagenumber && ( pPage->pagenumber->where < 4
1153 || pPage->pagenumber->where == 7 ) )
1155 d->bInHeader = true;
1156 d->nPnPos = 1;
1157 d->pPn = pPage->pagenumber;
1159 parsePara(pPage->header_odd->plist.front());
1160 d->bInHeader = false;
1161 d->pPn = 0L;
1162 d->nPnPos = 0;
1163 rendEl(ascii("style:header-left"));
1165 /* 기본으로 한다. */
1166 else if( pPage->header_even && !pPage->header_odd )
1168 rstartEl(ascii("style:header-left"), rList);
1169 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1170 rstartEl(ascii("text:p"), rList);
1171 pList->clear();
1172 if( pPage->pagenumber && ( pPage->pagenumber->where < 4 ||
1173 pPage->pagenumber->where == 7 ) )
1175 d->pPn = pPage->pagenumber;
1176 d->nPnPos = 1;
1177 makeShowPageNum();
1178 d->pPn = 0L;
1179 d->nPnPos = 0;
1181 rendEl(ascii("text:p"));
1182 rendEl(ascii("style:header-left"));
1184 if( !pPage->header && !pPage->header_even && !pPage->header_odd )
1186 rstartEl(ascii("style:header"), rList);
1187 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1188 rstartEl(ascii("text:p"), rList);
1189 pList->clear();
1190 if( pPage->pagenumber && pPage->pagenumber->where < 4
1191 && pPage->pagenumber->where == 7 )
1193 d->pPn = pPage->pagenumber;
1194 makeShowPageNum();
1195 d->pPn = 0L;
1197 rendEl(ascii("text:p"));
1198 rendEl(ascii("style:header"));
1200 // ------------- footer ------------- //
1201 if( pPage->footer )
1203 rstartEl(ascii("style:footer"), rList);
1204 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1205 && pPage->pagenumber->where != 7 )
1207 d->bInHeader = true;
1208 d->pPn = pPage->pagenumber;
1210 parsePara(pPage->footer->plist.front());
1211 d->bInHeader = false;
1212 d->pPn = 0L;
1213 rendEl(ascii("style:footer"));
1215 if( pPage->footer_even )
1217 rstartEl(ascii("style:footer"), rList);
1218 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1219 && pPage->pagenumber->where != 7 )
1221 d->bInHeader = true;
1222 d->pPn = pPage->pagenumber;
1223 d->nPnPos = 3;
1225 parsePara(pPage->footer_even->plist.front());
1226 d->bInHeader = false;
1227 d->pPn = 0L;
1228 d->nPnPos = 0;
1229 rendEl(ascii("style:footer"));
1231 /* 기본으로 한다. */
1232 else if( pPage->footer_odd && !pPage->footer_even )
1234 rstartEl(ascii("style:footer"), rList);
1235 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1236 rstartEl(ascii("text:p"), rList);
1237 pList->clear();
1238 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1239 && pPage->pagenumber->where != 7 )
1241 d->pPn = pPage->pagenumber;
1242 d->nPnPos = 3;
1243 makeShowPageNum();
1244 d->pPn = 0L;
1245 d->nPnPos = 0;
1247 rendEl(ascii("text:p"));
1248 rendEl(ascii("style:footer"));
1250 if( pPage->footer_odd )
1252 rstartEl(ascii("style:footer-left"), rList);
1253 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1254 && pPage->pagenumber->where != 7 )
1256 d->bInHeader = true;
1257 d->pPn = pPage->pagenumber;
1258 d->nPnPos = 1;
1260 parsePara(pPage->footer_odd->plist.front());
1261 d->bInHeader = false;
1262 d->pPn = 0L;
1263 d->nPnPos = 0;
1264 rendEl(ascii("style:footer-left"));
1266 /* 기본으로 한다. */
1267 else if( pPage->footer_even && !pPage->footer_odd )
1269 rstartEl(ascii("style:footer-left"), rList);
1270 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1271 rstartEl(ascii("text:p"), rList);
1272 pList->clear();
1273 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1274 && pPage->pagenumber->where != 7 )
1276 d->pPn = pPage->pagenumber;
1277 d->nPnPos = 1;
1278 makeShowPageNum();
1279 d->pPn = 0L;
1280 d->nPnPos = 0;
1282 rendEl(ascii("text:p"));
1283 rendEl(ascii("style:footer-left"));
1285 if( !pPage->footer && !pPage->footer_even && !pPage->footer_odd )
1287 rstartEl(ascii("style:footer"), rList);
1288 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1289 rstartEl(ascii("text:p"), rList);
1290 pList->clear();
1291 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1292 && pPage->pagenumber->where != 7 )
1294 d->pPn = pPage->pagenumber;
1295 makeShowPageNum();
1296 d->pPn = 0L;
1298 rendEl(ascii("text:p"));
1299 rendEl(ascii("style:footer"));
1302 rendEl(ascii("style:master-page"));
1304 rendEl(ascii("office:master-styles"));
1309 * 텍스트 스타일을 위한 프로퍼티들을 만든다.
1310 * 1. fo:font-size, fo:font-family, fo:letter-spacing, fo:color,
1311 * style:text-background-color, fo:font-style, fo:font-weight,
1312 * style:text-underline,style:text-outline,fo:text-shadow,style:text-position
1313 * 을 지원한다.
1315 void HwpReader::parseCharShape(CharShape * cshape)
1317 HWPFont *hwpfont = hwpfile.GetHWPFont();
1319 padd(ascii("fo:font-size"), sXML_CDATA,
1320 ascii(Int2Str(cshape->size / 25, "%dpt", buf)));
1321 padd(ascii("style:font-size-asian"), sXML_CDATA,
1322 ascii(Int2Str(cshape->size / 25, "%dpt", buf)));
1324 ::std::string const tmp = hstr2ksstr(kstr2hstr(
1325 (unsigned char *) hwpfont->GetFontName(0, cshape->font[0])).c_str());
1326 double fRatio = 1.0;
1327 int size = getRepFamilyName(tmp.c_str(), buf, fRatio);
1329 padd(ascii("fo:font-family"), sXML_CDATA,
1330 OUString(buf, size, RTL_TEXTENCODING_EUC_KR));
1331 padd(ascii("style:font-family-asian"), sXML_CDATA,
1332 OUString(buf, size, RTL_TEXTENCODING_EUC_KR));
1334 padd(ascii("style:text-scale"), sXML_CDATA,
1335 ascii(Int2Str((int)(cshape->ratio[0] * fRatio), "%d%%", buf)));
1337 double sspace = (cshape->size / 25) * cshape->space[0] / 100.;
1339 if (sspace != 0.)
1341 padd(ascii("fo:letter-spacing"), sXML_CDATA,
1342 Double2Str(sspace) + ascii("pt"));
1344 if (cshape->color[1] != 0)
1345 padd(ascii("fo:color"), sXML_CDATA,
1346 ascii(hcolor2str(cshape->color[1], 100, buf, true)));
1347 if (cshape->shade != 0)
1348 padd(ascii("style:text-background-color"), sXML_CDATA,
1349 ascii(hcolor2str(cshape->color[0], cshape->shade, buf)));
1350 if (cshape->attr & 0x01)
1352 padd(ascii("fo:font-style"), sXML_CDATA, ascii("italic"));
1353 padd(ascii("style:font-style-asian"), sXML_CDATA, ascii("italic"));
1355 else{
1356 padd(ascii("fo:font-style"), sXML_CDATA, ascii("normal"));
1357 padd(ascii("style:font-style-asian"), sXML_CDATA, ascii("normal"));
1359 if (cshape->attr >> 1 & 0x01)
1361 padd(ascii("fo:font-weight"), sXML_CDATA, ascii("bold"));
1362 padd(ascii("style:font-weight-asian"), sXML_CDATA, ascii("bold"));
1364 else{
1365 padd(ascii("fo:font-weight"), sXML_CDATA, ascii("normal"));
1366 padd(ascii("style:font-weight-asian"), sXML_CDATA, ascii("normal"));
1368 if (cshape->attr >> 2 & 0x01)
1369 padd(ascii("style:text-underline"), sXML_CDATA, ascii("single"));
1370 if (cshape->attr >> 3 & 0x01)
1371 padd(ascii("style:text-outline"), sXML_CDATA, ascii("true"));
1372 if (cshape->attr >> 4 & 0x01)
1373 padd(ascii("fo:text-shadow"), sXML_CDATA, ascii("1pt 1pt"));
1374 if (cshape->attr >> 5 & 0x01)
1375 padd(ascii("style:text-position"), sXML_CDATA, ascii("super 58%"));
1376 if (cshape->attr >> 6 & 0x01)
1377 padd(ascii("style:text-position"), sXML_CDATA, ascii("sub 58%"));
1383 * 실제 Paragraph에 해당하는 properties들을 만든다.
1384 * 1. fo:margin-left,fo:margin-right,fo:margin-top, fo:margin-bottom,
1385 * fo:text-indent, fo:line-height, fo:text-align, fo:border
1386 * 가 구현됨.
1387 * TODO : 탭설정 => 기본값이 아닌것들만 선택적으로 설정해야 한다.
1389 void HwpReader::parseParaShape(ParaShape * pshape)
1392 if (pshape->left_margin != 0)
1393 padd(ascii("fo:margin-left"), sXML_CDATA, Double2Str
1394 (WTI(pshape->left_margin )) + ascii("inch"));
1395 if (pshape->right_margin != 0)
1396 padd(ascii("fo:margin-right"), sXML_CDATA, Double2Str
1397 (WTI(pshape->right_margin)) + ascii("inch"));
1398 if (pshape->pspacing_prev != 0)
1399 padd(ascii("fo:margin-top"), sXML_CDATA, Double2Str
1400 (WTI(pshape->pspacing_prev)) + ascii("inch"));
1401 if (pshape->pspacing_next != 0)
1402 padd(ascii("fo:margin-bottom"), sXML_CDATA, Double2Str
1403 (WTI(pshape->pspacing_next)) + ascii("inch"));
1404 if (pshape->indent != 0)
1405 padd(ascii("fo:text-indent"), sXML_CDATA, Double2Str
1406 (WTI(pshape->indent)) + ascii("inch"));
1407 if (pshape->lspacing != 0)
1408 padd(ascii("fo:line-height"), sXML_CDATA,
1409 ascii(Int2Str (pshape->lspacing, "%d%%", buf)));
1411 unsigned char set_align = 0;
1413 switch ((int) pshape->arrange_type)
1415 case 1:
1416 strcpy(buf, "start");
1417 set_align = 1;
1418 break;
1419 case 2:
1420 strcpy(buf, "end");
1421 set_align = 1;
1422 break;
1423 case 3:
1424 strcpy(buf, "center");
1425 set_align = 1;
1426 break;
1427 case 4:
1428 case 5:
1429 case 6:
1430 strcpy(buf, "justify");
1431 set_align = 1;
1432 break;
1435 if (set_align)
1436 padd(ascii("fo:text-align"), sXML_CDATA, ascii(buf));
1438 if (pshape->outline)
1439 padd(ascii("fo:border"), sXML_CDATA, ascii("0.002cm solid #000000"));
1440 if( pshape->shade > 0 )
1442 padd(ascii("fo:background-color"), sXML_CDATA,
1443 ascii(hcolor2str(0, pshape->shade, buf)));
1446 if( pshape->pagebreak & 0x02 || pshape->pagebreak & 0x04)
1447 padd(ascii("fo:break-before"), sXML_CDATA, ascii("page"));
1448 else if( pshape->pagebreak & 0x01 )
1449 padd(ascii("fo:break-before"), sXML_CDATA, ascii("column"));
1455 * Paragraph에 대한 스타일을 만든다.
1457 void HwpReader::makePStyle(ParaShape * pshape)
1459 int nscount = pshape->tabs[MAXTABS -1].type;
1460 padd(ascii("style:name"), sXML_CDATA,
1461 ascii(Int2Str(pshape->index, "P%d", buf)));
1462 padd(ascii("style:family"), sXML_CDATA, ascii("paragraph"));
1463 rstartEl(ascii("style:style"), rList);
1464 pList->clear();
1465 parseParaShape(pshape);
1466 parseCharShape(pshape->cshape);
1467 rstartEl(ascii("style:properties"), rList);
1468 pList->clear();
1470 if( nscount )
1472 unsigned char tf = 0;
1473 rstartEl(ascii("style:tab-stops"),rList);
1475 int tab_margin = pshape->left_margin + pshape->indent;
1476 if( tab_margin < 0 )
1477 tab_margin = 0;
1478 for( int i = 0 ; i < MAXTABS -1 ; i++)
1480 if( i > 0 && pshape->tabs[i].position == 0. )
1481 break;
1482 if( pshape->tabs[i].position <= tab_margin )
1483 continue;
1484 padd(ascii("style:position"), sXML_CDATA,
1485 Double2Str(WTMM(pshape->tabs[i].position - tab_margin )) + ascii("mm"));
1486 if( pshape->tabs[i].type )
1488 tf = 1;
1489 switch(pshape->tabs[i].type)
1491 case 1 :
1492 padd(ascii("style:type"), sXML_CDATA, ascii("right"));
1493 break;
1494 case 2:
1495 padd(ascii("style:type"), sXML_CDATA, ascii("center"));
1496 break;
1497 case 3:
1498 padd(ascii("style:type"), sXML_CDATA, ascii("char"));
1499 padd(ascii("style:char"), sXML_CDATA, ascii("."));
1500 break;
1503 if( pshape->tabs[i].dot_continue )
1505 tf = 1;
1506 padd(ascii("style:leader-char"), sXML_CDATA, ascii("."));
1508 rstartEl( ascii("style:tab-stop"), rList);
1509 pList->clear();
1510 rendEl( ascii("style:tab-stop") );
1512 if( (pshape->tabs[i].position != 1000 * i ) || tf )
1514 if( !--nscount ) break;
1517 rendEl( ascii("style:tab-stops"));
1519 rendEl(ascii("style:properties"));
1520 rendEl(ascii("style:style"));
1525 * 페이지의 스타일을 만든다. 여기에는 header/footer, footnote등이 포함된다.
1526 * TODO : , fo:background-color(정보가 없다)
1528 void HwpReader::makePageStyle()
1530 HWPInfo *hwpinfo = hwpfile.GetHWPInfo();
1531 int pmCount = hwpfile.getColumnCount();
1533 for( int i = 0 ; i < pmCount ; i++ ){
1534 padd(ascii("style:name"), sXML_CDATA, ascii(Int2Str(i + 1, "pm%d", buf)));
1535 rstartEl(ascii("style:page-master"),rList);
1536 pList->clear();
1539 switch( hwpinfo->paper.paper_kind )
1541 case 3: // A4
1542 if( hwpinfo->paper.paper_direction )
1544 padd(ascii("fo:page-height"),sXML_CDATA, ascii("210mm"));
1545 padd(ascii("fo:page-width"),sXML_CDATA, ascii("297mm"));
1547 else
1549 padd(ascii("fo:page-width"),sXML_CDATA, ascii("210mm"));
1550 padd(ascii("fo:page-height"),sXML_CDATA, ascii("297mm"));
1552 break;
1553 case 4: // 80 column
1554 if( hwpinfo->paper.paper_direction )
1556 padd(ascii("fo:page-height"),sXML_CDATA, ascii("8.5inch"));
1557 padd(ascii("fo:page-width"),sXML_CDATA, ascii("11inch"));
1559 else
1561 padd(ascii("fo:page-width"),sXML_CDATA, ascii("8.5inch"));
1562 padd(ascii("fo:page-height"),sXML_CDATA, ascii("11inch"));
1564 break;
1565 case 5: // B5
1566 if( hwpinfo->paper.paper_direction )
1568 padd(ascii("fo:page-height"),sXML_CDATA, ascii("176mm"));
1569 padd(ascii("fo:page-width"),sXML_CDATA, ascii("250mm"));
1571 else
1573 padd(ascii("fo:page-width"),sXML_CDATA, ascii("176mm"));
1574 padd(ascii("fo:page-height"),sXML_CDATA, ascii("250mm"));
1576 break;
1577 case 6: // B4
1578 if( hwpinfo->paper.paper_direction )
1580 padd(ascii("fo:page-height"),sXML_CDATA, ascii("250mm"));
1581 padd(ascii("fo:page-width"),sXML_CDATA, ascii("353mm"));
1583 else
1585 padd(ascii("fo:page-width"),sXML_CDATA, ascii("250mm"));
1586 padd(ascii("fo:page-height"),sXML_CDATA, ascii("353mm"));
1588 break;
1589 case 7:
1590 if( hwpinfo->paper.paper_direction )
1592 padd(ascii("fo:page-height"),sXML_CDATA, ascii("8.5inch"));
1593 padd(ascii("fo:page-width"),sXML_CDATA, ascii("14inch"));
1595 else
1597 padd(ascii("fo:page-width"),sXML_CDATA, ascii("8.5inch"));
1598 padd(ascii("fo:page-height"),sXML_CDATA, ascii("14inch"));
1600 break;
1601 case 8:
1602 if( hwpinfo->paper.paper_direction )
1604 padd(ascii("fo:page-height"),sXML_CDATA, ascii("297mm"));
1605 padd(ascii("fo:page-width"),sXML_CDATA, ascii("420mm"));
1607 else
1609 padd(ascii("fo:page-width"),sXML_CDATA, ascii("297mm"));
1610 padd(ascii("fo:page-height"),sXML_CDATA, ascii("420mm"));
1612 break;
1613 case 0:
1614 case 1:
1615 case 2:
1616 default:
1617 if( hwpinfo->paper.paper_direction )
1619 padd(ascii("fo:page-width"),sXML_CDATA,
1620 Double2Str(WTI(hwpinfo->paper.paper_height)) + ascii("inch"));
1621 padd(ascii("fo:page-height"),sXML_CDATA,
1622 Double2Str(WTI(hwpinfo->paper.paper_width)) + ascii("inch"));
1624 else
1626 padd(ascii("fo:page-width"),sXML_CDATA,
1627 Double2Str(WTI(hwpinfo->paper.paper_width)) + ascii("inch"));
1628 padd(ascii("fo:page-height"),sXML_CDATA,
1629 Double2Str(WTI(hwpinfo->paper.paper_height)) + ascii("inch"));
1631 break;
1635 padd(ascii("style:print-orientation"),sXML_CDATA,
1636 ascii(hwpinfo->paper.paper_direction ? "landscape" : "portrait"));
1637 if( hwpinfo->beginpagenum != 1)
1638 padd(ascii("style:first-page-number"),sXML_CDATA,
1639 ascii(Int2Str(hwpinfo->beginpagenum, "%d", buf)));
1641 if( hwpinfo->borderline ){
1642 padd(ascii("fo:margin-left"),sXML_CDATA,
1643 Double2Str(WTI(hwpinfo->paper.left_margin - hwpinfo->bordermargin[0] + hwpinfo->paper.gutter_length)) + ascii("inch"));
1644 padd(ascii("fo:margin-right"),sXML_CDATA,
1645 Double2Str(WTI(hwpinfo->paper.right_margin - hwpinfo->bordermargin[1])) + ascii("inch"));
1646 padd(ascii("fo:margin-top"),sXML_CDATA,
1647 Double2Str(WTI(hwpinfo->paper.top_margin - hwpinfo->bordermargin[2])) + ascii("inch"));
1648 padd(ascii("fo:margin-bottom"),sXML_CDATA,
1649 Double2Str(WTI(hwpinfo->paper.bottom_margin - hwpinfo->bordermargin[3])) + ascii("inch"));
1651 else{
1652 padd(ascii("fo:margin-left"),sXML_CDATA,
1653 Double2Str(WTI(hwpinfo->paper.left_margin + hwpinfo->paper.gutter_length)) + ascii("inch"));
1654 padd(ascii("fo:margin-right"),sXML_CDATA,
1655 Double2Str(WTI(hwpinfo->paper.right_margin)) + ascii("inch"));
1656 padd(ascii("fo:margin-top"),sXML_CDATA,
1657 Double2Str(WTI(hwpinfo->paper.top_margin)) + ascii("inch"));
1658 padd(ascii("fo:margin-bottom"),sXML_CDATA,
1659 Double2Str(WTI(hwpinfo->paper.bottom_margin)) + ascii("inch"));
1662 switch( hwpinfo->borderline )
1664 case 1:
1665 padd(ascii("fo:border"), sXML_CDATA,ascii("0.002cm solid #000000"));
1666 break;
1667 case 3:
1668 padd(ascii("fo:border"), sXML_CDATA,ascii("0.002cm dotted #000000"));
1669 break;
1670 case 2:
1671 padd(ascii("fo:border"), sXML_CDATA,ascii("0.035cm solid #000000"));
1672 break;
1673 case 4:
1674 padd(ascii("style:border-line-width"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1675 padd(ascii("fo:border"), sXML_CDATA,ascii("0.039cm double #000000"));
1676 break;
1679 padd(ascii("fo:padding-left"), sXML_CDATA,
1680 Double2Str(WTI(hwpinfo->bordermargin[0])) + ascii("inch"));
1681 padd(ascii("fo:padding-right"), sXML_CDATA,
1682 Double2Str(WTI(hwpinfo->bordermargin[1])) + ascii("inch"));
1683 padd(ascii("fo:padding-top"), sXML_CDATA,
1684 Double2Str(WTI(hwpinfo->bordermargin[2])) + ascii("inch"));
1685 padd(ascii("fo:padding-bottom"), sXML_CDATA,
1686 Double2Str(WTI(hwpinfo->bordermargin[3])) + ascii("inch"));
1688 /* background color */
1689 if( hwpinfo->back_info.isset )
1691 if( hwpinfo->back_info.color[0] > 0 || hwpinfo->back_info.color[1] > 0
1692 || hwpinfo->back_info.color[2] > 0 ){
1693 sprintf(buf,"#%02x%02x%02x",hwpinfo->back_info.color[0],
1694 hwpinfo->back_info.color[1],hwpinfo->back_info.color[2] );
1695 padd(ascii("fo:background-color"), sXML_CDATA, ascii(buf));
1699 rstartEl(ascii("style:properties"),rList);
1700 pList->clear();
1702 /* background image */
1703 if( hwpinfo->back_info.isset && hwpinfo->back_info.type > 0 )
1705 if( hwpinfo->back_info.type == 1 ){
1706 #ifdef _WIN32
1707 padd(ascii("xlink:href"), sXML_CDATA,
1708 hconv(kstr2hstr((uchar*) urltowin(hwpinfo->back_info.filename).c_str()).c_str()));
1709 #else
1710 padd(ascii("xlink:href"), sXML_CDATA,
1711 hconv(kstr2hstr( (uchar *)urltounix(hwpinfo->back_info.filename).c_str()).c_str()));
1712 #endif
1713 padd(ascii("xlink:type"), sXML_CDATA, ascii("simple"));
1714 padd(ascii("xlink:actuate"), sXML_CDATA, ascii("onLoad"));
1716 if( hwpinfo->back_info.flag >= 2)
1717 padd(ascii("style:repeat"), sXML_CDATA, ascii("stretch"));
1718 else if( hwpinfo->back_info.flag == 1 ){
1719 padd(ascii("style:repeat"), sXML_CDATA, ascii("no-repeat"));
1720 padd(ascii("style:position"), sXML_CDATA, ascii("center"));
1722 rstartEl(ascii("style:background-image"),rList);
1724 if( hwpinfo->back_info.type == 2 ){
1725 rstartEl(ascii("office:binary-data"), rList);
1726 pList->clear();
1727 boost::shared_ptr<char> pStr(base64_encode_string((unsigned char *) hwpinfo->back_info.data, hwpinfo->back_info.size ), Free<char>());
1728 rchars(ascii(pStr.get()));
1729 rendEl(ascii("office:binary-data"));
1731 rendEl(ascii("style:background-image"));
1734 makeColumns( hwpfile.GetColumnDef(i) );
1736 rendEl(ascii("style:properties"));
1738 /* header style */
1739 rstartEl(ascii("style:header-style"), rList);
1740 padd(ascii("svg:height"), sXML_CDATA,
1741 Double2Str(WTI(hwpinfo->paper.header_length)) + ascii("inch"));
1742 padd(ascii("fo:margin-bottom"), sXML_CDATA, ascii("0mm"));
1744 rstartEl(ascii("style:properties"),rList);
1745 pList->clear();
1746 rendEl(ascii("style:properties"));
1747 rendEl(ascii("style:header-style"));
1749 /* footer style */
1750 rstartEl(ascii("style:footer-style"), rList);
1751 padd(ascii("svg:height"), sXML_CDATA,
1752 Double2Str(WTI(hwpinfo->paper.footer_length)) + ascii("inch"));
1753 padd(ascii("fo:margin-top"), sXML_CDATA, ascii("0mm"));
1754 rstartEl(ascii("style:properties"),rList);
1755 pList->clear();
1756 rendEl(ascii("style:properties"));
1757 rendEl(ascii("style:footer-style"));
1759 /* footnote style 이건 dtd에서는 빠졌으나, 스펙에는 정의되어 있다. REALKING */
1760 rstartEl(ascii("style:footnote-layout"), rList);
1762 padd(ascii("style:distance-before-sep"), sXML_CDATA,
1763 Double2Str(WTI(hwpinfo->splinetext)) + ascii("inch"));
1764 padd(ascii("style:distance-after-sep"), sXML_CDATA,
1765 Double2Str(WTI(hwpinfo->splinefn)) + ascii("inch"));
1766 rstartEl(ascii("style:properties"),rList);
1767 pList->clear();
1768 rendEl(ascii("style:properties"));
1769 if ( hwpinfo->fnlinetype == 2 )
1770 padd(ascii("style:width"), sXML_CDATA, ascii("15cm"));
1771 else if ( hwpinfo->fnlinetype == 1)
1772 padd(ascii("style:width"), sXML_CDATA, ascii("2cm"));
1773 else if ( hwpinfo->fnlinetype == 3)
1774 padd(ascii("style:width"), sXML_CDATA, ascii("0cm"));
1775 else
1776 padd(ascii("style:width"), sXML_CDATA, ascii("5cm"));
1778 rstartEl(ascii("style:footnote-sep"),rList);
1779 pList->clear();
1780 rendEl(ascii("style:footnote-sep"));
1782 rendEl(ascii("style:footnote-layout"));
1784 rendEl(ascii("style:page-master"));
1788 void HwpReader::makeColumns(ColumnDef *coldef)
1790 if( !coldef ) return;
1791 padd(ascii("fo:column-count"), sXML_CDATA, ascii(Int2Str(coldef->ncols, "%d", buf)));
1792 rstartEl(ascii("style:columns"),rList);
1793 pList->clear();
1794 if( coldef->separator != 0 )
1796 switch( coldef->separator )
1798 case 1: /* 얇은선 */
1799 padd(ascii("style:width"), sXML_CDATA, ascii("0.02mm"));
1800 case 3: /* 점선 */
1801 padd(ascii("style:style"), sXML_CDATA, ascii("dotted"));
1802 padd(ascii("style:width"), sXML_CDATA, ascii("0.02mm"));
1803 break;
1804 case 2: /* 두꺼운선 */
1805 case 4: /* 2중선 */
1806 padd(ascii("style:width"), sXML_CDATA, ascii("0.35mm"));
1807 break;
1808 case 0: /* 없음 */
1809 default:
1810 padd(ascii("style:style"), sXML_CDATA, ascii("none"));
1811 break;
1813 rstartEl(ascii("style:column-sep"),rList);
1814 pList->clear();
1815 rendEl(ascii("style:column-sep"));
1817 double spacing = WTI(coldef->spacing)/ 2. ;
1818 for(int ii = 0 ; ii < coldef->ncols ; ii++)
1820 if( ii == 0 )
1821 padd(ascii("fo:margin-left"), sXML_CDATA, ascii("0mm"));
1822 else
1823 padd(ascii("fo:margin-left"), sXML_CDATA,
1824 Double2Str( spacing) + ascii("inch"));
1825 if( ii == ( coldef->ncols -1) )
1826 padd(ascii("fo:margin-right"), sXML_CDATA,ascii("0mm"));
1827 else
1828 padd(ascii("fo:margin-right"), sXML_CDATA,
1829 Double2Str( spacing) + ascii("inch"));
1830 rstartEl(ascii("style:column"),rList);
1831 pList->clear();
1832 rendEl(ascii("style:column"));
1834 rendEl(ascii("style:columns"));
1837 void HwpReader::makeTStyle(CharShape * cshape)
1839 padd(ascii("style:name"), sXML_CDATA,
1840 ascii(Int2Str(cshape->index, "T%d", buf)));
1841 padd(ascii("style:family"), sXML_CDATA, ascii("text"));
1842 rstartEl(ascii("style:style"), rList);
1843 pList->clear();
1844 parseCharShape(cshape);
1845 rstartEl(ascii("style:properties"), rList);
1846 pList->clear();
1847 rendEl(ascii("style:properties"));
1848 rendEl(ascii("style:style"));
1852 void HwpReader::makeTableStyle(Table *tbl)
1854 // --------------- table ---------------- //
1855 TxtBox *hbox = tbl->box;
1857 padd(ascii("style:name"), sXML_CDATA,
1858 ascii(Int2Str(hbox->style.boxnum, "Table%d", buf)));
1859 padd(ascii("style:family"), sXML_CDATA,ascii("table"));
1860 rstartEl(ascii("style:style"), rList);
1861 pList->clear();
1862 padd(ascii("style:width"), sXML_CDATA,
1863 Double2Str(WTMM(hbox->box_xs)) + ascii("mm"));
1864 padd(ascii("table:align"), sXML_CDATA,ascii("left"));
1865 padd(ascii("fo:keep-with-next"), sXML_CDATA,ascii("false"));
1866 rstartEl(ascii("style:properties"), rList);
1867 pList->clear();
1868 rendEl(ascii("style:properties"));
1869 rendEl(ascii("style:style"));
1871 // --------------- column ---------------- //
1872 for (size_t i = 0 ; i < tbl->columns.nCount -1 ; i++)
1874 sprintf(buf,"Table%d.%c",hbox->style.boxnum, static_cast<char>('A'+i));
1875 padd(ascii("style:name"), sXML_CDATA, ascii( buf ));
1876 padd(ascii("style:family"), sXML_CDATA,ascii("table-column"));
1877 rstartEl(ascii("style:style"), rList);
1878 pList->clear();
1879 padd(ascii("style:column-width"), sXML_CDATA,
1880 Double2Str(WTMM(tbl->columns.data[i+1] - tbl->columns.data[i])) + ascii("mm"));
1881 rstartEl(ascii("style:properties"), rList);
1882 pList->clear();
1883 rendEl(ascii("style:properties"));
1884 rendEl(ascii("style:style"));
1887 // --------------- row ---------------- //
1888 for (size_t i = 0 ; i < tbl->rows.nCount -1 ; i++)
1890 sprintf(buf,"Table%d.row%" SAL_PRI_SIZET "u",hbox->style.boxnum, i + 1);
1891 padd(ascii("style:name"), sXML_CDATA, ascii( buf ));
1892 padd(ascii("style:family"), sXML_CDATA,ascii("table-row"));
1893 rstartEl(ascii("style:style"), rList);
1894 pList->clear();
1895 padd(ascii("style:row-height"), sXML_CDATA,
1896 Double2Str(WTMM(tbl->rows.data[i+1] - tbl->rows.data[i])) + ascii("mm"));
1897 rstartEl(ascii("style:properties"), rList);
1898 pList->clear();
1899 rendEl(ascii("style:properties"));
1900 rendEl(ascii("style:style"));
1903 // --------------- cell --------------------- //
1904 for (int i = 0 ; i < static_cast<int>(tbl->cells.size()); i++)
1906 std::list<TCell*>::iterator it = tbl->cells.begin();
1908 for( int ii = 0; it != tbl->cells.end(); ++it, ii++ ){
1909 if( ii == i )
1910 break;
1913 TCell *tcell = *it;
1914 sprintf(buf,"Table%d.%c%d",hbox->style.boxnum, 'A'+ tcell->nColumnIndex, tcell->nRowIndex +1);
1915 padd(ascii("style:name"), sXML_CDATA, ascii( buf ));
1916 padd(ascii("style:family"), sXML_CDATA,ascii("table-cell"));
1917 rstartEl(ascii("style:style"), rList);
1918 pList->clear();
1919 Cell *cl = tcell->pCell;
1920 if( cl->ver_align == 1 )
1921 padd(ascii("fo:vertical-align"), sXML_CDATA,ascii("middle"));
1923 if(cl->linetype[2] == cl->linetype[3] && cl->linetype[2] == cl->linetype[0]
1924 && cl->linetype[2] == cl->linetype[1])
1926 switch( cl->linetype[2] )
1928 case 1: /* 가는실선 */
1929 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
1930 padd(ascii("fo:border"), sXML_CDATA,ascii("0.002cm solid #000000"));
1931 break;
1932 case 2: /* 굵은실선 */
1933 padd(ascii("fo:border"), sXML_CDATA,ascii("0.035cm solid #000000"));
1934 break;
1935 case 4: /* 2중선 */
1936 padd(ascii("style:border-line-width"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1937 padd(ascii("fo:border"), sXML_CDATA,ascii("0.039cm double #000000"));
1938 break;
1941 else
1943 switch( cl->linetype[0] )
1945 case 1: /* 가는실선 */
1946 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
1947 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.002cm solid #000000"));
1948 break;
1949 case 2: /* 굵은실선 */
1950 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.035cm solid #000000"));
1951 break;
1952 case 4: /* 2중선 */
1953 padd(ascii("style:border-line-width-left"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1954 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.039cm double #000000"));
1955 break;
1957 switch( cl->linetype[1] )
1959 case 1: /* 가는실선 */
1960 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
1961 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.002cm solid #000000"));
1962 break;
1963 case 2: /* 굵은실선 */
1964 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.035cm solid #000000"));
1965 break;
1966 case 4: /* 2중선 */
1967 padd(ascii("style:border-line-width-right"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1968 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.039cm double #000000"));
1969 break;
1971 switch( cl->linetype[2] )
1973 case 1: /* 가는실선 */
1974 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
1975 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.002cm solid #000000"));
1976 break;
1977 case 2: /* 굵은실선 */
1978 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.035cm solid #000000"));
1979 break;
1980 case 4: /* 2중선 */
1981 padd(ascii("style:border-line-width-top"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1982 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.039cm double #000000"));
1983 break;
1985 switch( cl->linetype[3] )
1987 case 1: /* 가는실선 */
1988 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
1989 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.002cm solid #000000"));
1990 break;
1991 case 2: /* 굵은실선 */
1992 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.035cm solid #000000"));
1993 break;
1994 case 4: /* 2중선 */
1995 padd(ascii("style:border-line-width-bottom"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1996 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.039cm double #000000"));
1997 break;
2000 if(cl->shade != 0)
2001 padd(ascii("fo:background-color"), sXML_CDATA,
2002 ascii(hcolor2str(sal::static_int_cast<uchar>(cl->color),
2003 sal::static_int_cast<uchar>(cl->shade), buf)));
2005 rstartEl(ascii("style:properties"), rList);
2006 pList->clear();
2007 rendEl(ascii("style:properties"));
2009 rendEl(ascii("style:style"));
2014 void HwpReader::makeDrawStyle( HWPDrawingObject * hdo, FBoxStyle * fstyle)
2016 while( hdo )
2018 padd(ascii("style:name"), sXML_CDATA,
2019 ascii(Int2Str(hdo->index, "Draw%d", buf)));
2020 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
2022 rstartEl(ascii("style:style"), rList);
2023 pList->clear();
2025 switch (fstyle->txtflow)
2027 case 0:
2028 break;
2029 case 1:
2030 padd(ascii("style:wrap"), sXML_CDATA, ascii("run-through"));
2031 break;
2032 case 2:
2033 padd(ascii("style:wrap"), sXML_CDATA, ascii("dynamic"));
2034 break;
2036 long color;
2037 // invisible line
2038 if( hdo->property.line_color > 0xffffff )
2040 padd(ascii("draw:stroke"), sXML_CDATA, ascii("none") );
2042 else
2045 if( hdo->property.line_pstyle == 0 )
2046 padd(ascii("draw:stroke"), sXML_CDATA, ascii("solid") );
2047 else if( hdo->property.line_pstyle < 5 )
2049 padd(ascii("draw:stroke"), sXML_CDATA, ascii("dash") );
2050 padd(ascii("draw:stroke-dash"), sXML_CDATA,
2051 ascii(Int2Str(hdo->index, "LineType%d", buf)));
2053 padd(ascii("svg:stroke-width"), sXML_CDATA,
2054 Double2Str( WTMM(hdo->property.line_width)) + ascii("mm" ));
2055 color = hdo->property.line_color;
2056 sprintf( buf, "#%02x%02x%02x",
2057 sal_uInt16(color & 0xff),
2058 sal_uInt16((color >> 8) & 0xff),
2059 sal_uInt16((color >>16) & 0xff) );
2060 padd(ascii("svg:stroke-color"), sXML_CDATA, ascii( buf) );
2063 if( hdo->type == HWPDO_LINE || hdo->type == HWPDO_ARC ||
2064 hdo->type == HWPDO_FREEFORM || hdo->type == HWPDO_ADVANCED_ARC )
2067 if( hdo->property.line_tstyle > 0 )
2069 padd(ascii("draw:marker-start"), sXML_CDATA,
2070 ascii(ArrowShape[hdo->property.line_tstyle].name) );
2071 if( hdo->property.line_width > 100 )
2072 padd(ascii("draw:marker-start-width"), sXML_CDATA,
2073 Double2Str( WTMM(hdo->property.line_width * 3)) + ascii("mm" ));
2074 else if( hdo->property.line_width > 80 )
2075 padd(ascii("draw:marker-start-width"), sXML_CDATA,
2076 Double2Str( WTMM(hdo->property.line_width * 4)) + ascii("mm" ));
2077 else if( hdo->property.line_width > 60 )
2078 padd(ascii("draw:marker-start-width"), sXML_CDATA,
2079 Double2Str( WTMM(hdo->property.line_width * 5)) + ascii("mm" ));
2080 else if( hdo->property.line_width > 40 )
2081 padd(ascii("draw:marker-start-width"), sXML_CDATA,
2082 Double2Str( WTMM(hdo->property.line_width * 6)) + ascii("mm" ));
2083 else
2084 padd(ascii("draw:marker-start-width"), sXML_CDATA,
2085 Double2Str( WTMM(hdo->property.line_width * 7)) + ascii("mm" ));
2088 if( hdo->property.line_hstyle > 0 )
2090 padd(ascii("draw:marker-end"), sXML_CDATA,
2091 ascii(ArrowShape[hdo->property.line_hstyle].name) );
2092 if( hdo->property.line_width > 100 )
2093 padd(ascii("draw:marker-end-width"), sXML_CDATA,
2094 Double2Str( WTMM(hdo->property.line_width * 3)) + ascii("mm" ));
2095 else if( hdo->property.line_width > 80 )
2096 padd(ascii("draw:marker-end-width"), sXML_CDATA,
2097 Double2Str( WTMM(hdo->property.line_width * 4)) + ascii("mm" ));
2098 else if( hdo->property.line_width > 60 )
2099 padd(ascii("draw:marker-end-width"), sXML_CDATA,
2100 Double2Str( WTMM(hdo->property.line_width * 5)) + ascii("mm" ));
2101 else if( hdo->property.line_width > 40 )
2102 padd(ascii("draw:marker-end-width"), sXML_CDATA,
2103 Double2Str( WTMM(hdo->property.line_width * 6)) + ascii("mm" ));
2104 else
2105 padd(ascii("draw:marker-end-width"), sXML_CDATA,
2106 Double2Str( WTMM(hdo->property.line_width * 7)) + ascii("mm" ));
2110 if(hdo->type != HWPDO_LINE )
2112 if( hdo->property.flag >> 19 & 0x01 )
2114 padd( ascii("draw:textarea-horizontal-align"), sXML_CDATA, ascii("center"));
2117 color = hdo->property.fill_color;
2119 if( hdo->property.flag >> 18 & 0x01 ) // bitmap pattern
2121 padd(ascii("draw:fill"), sXML_CDATA, ascii("bitmap"));
2122 padd(ascii("draw:fill-image-name"), sXML_CDATA,
2123 ascii(Int2Str(hdo->index, "fillimage%d", buf)));
2124 // bitmap resizing
2125 if( hdo->property.flag >> 3 & 0x01 )
2127 padd(ascii("style:repeat"), sXML_CDATA, ascii("stretch"));
2129 else
2131 padd(ascii("style:repeat"), sXML_CDATA, ascii("repeat"));
2132 padd(ascii("draw:fill-image-ref-point"), sXML_CDATA, ascii("top-left"));
2134 if( hdo->property.flag >> 20 & 0x01 )
2136 if( hdo->property.luminance > 0 )
2138 padd(ascii("draw:transparency"), sXML_CDATA,
2139 ascii(Int2Str(hdo->property.luminance, "%d%%", buf)));
2144 // Gradation
2145 else if( hdo->property.flag >> 16 & 0x01 )
2147 padd(ascii("draw:fill"), sXML_CDATA, ascii("gradient"));
2148 padd(ascii("draw:fill-gradient-name"), sXML_CDATA,
2149 ascii(Int2Str(hdo->index, "Grad%d", buf)));
2150 padd(ascii("draw:gradient-step-count"), sXML_CDATA,
2151 ascii(Int2Str(hdo->property.nstep, "%d", buf)));
2154 // Hatching
2155 else if( hdo->property.pattern_type >> 24 & 0x01 )
2157 padd(ascii("draw:fill"), sXML_CDATA, ascii("hatch"));
2158 padd(ascii("draw:fill-hatch-name"), sXML_CDATA,
2159 ascii(Int2Str(hdo->index, "Hatch%d", buf)));
2160 if( color < 0xffffff )
2162 sprintf( buf, "#%02x%02x%02x",
2163 sal_uInt16(color & 0xff),
2164 sal_uInt16((color >> 8) & 0xff),
2165 sal_uInt16((color >>16) & 0xff) );
2166 padd(ascii("draw:fill-color"), sXML_CDATA, ascii( buf) );
2167 padd(ascii("draw:fill-hatch-solid"), sXML_CDATA, ascii("true"));
2170 else if( color <= 0xffffff )
2172 padd(ascii("draw:fill"), sXML_CDATA, ascii("solid"));
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(ascii("draw:fill-color"), sXML_CDATA, ascii( buf) );
2179 else
2180 padd(ascii("draw:fill"), sXML_CDATA, ascii("none"));
2183 if( fstyle->anchor_type == CHAR_ANCHOR )
2185 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("top"));
2186 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("baseline"));
2189 rstartEl(ascii("style:properties"), rList);
2190 pList->clear();
2191 rendEl(ascii("style:properties"));
2192 rendEl(ascii("style:style"));
2194 if( hdo->type == 0 )
2196 makeDrawStyle( hdo->child, fstyle );
2198 hdo = hdo->next;
2203 void HwpReader::makeCaptionStyle(FBoxStyle * fstyle)
2205 padd(ascii("style:name"), sXML_CDATA,
2206 ascii(Int2Str(fstyle->boxnum, "CapBox%d", buf)));
2207 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
2208 rstartEl(ascii("style:style"), rList);
2209 pList->clear();
2210 padd(ascii("fo:margin-left"), sXML_CDATA, ascii("0cm"));
2211 padd(ascii("fo:margin-right"), sXML_CDATA, ascii("0cm"));
2212 padd(ascii("fo:margin-top"), sXML_CDATA, ascii("0cm"));
2213 padd(ascii("fo:margin-bottom"), sXML_CDATA, ascii("0cm"));
2214 padd(ascii("fo:padding"), sXML_CDATA, ascii("0cm"));
2215 switch (fstyle->txtflow)
2217 case 0:
2218 padd(ascii("style:wrap"), sXML_CDATA, ascii("none"));
2219 break;
2220 case 1:
2221 if( fstyle->boxtype == 'G' )
2222 padd(ascii("style:run-through"), sXML_CDATA, ascii("background"));
2223 padd(ascii("style:wrap"), sXML_CDATA, ascii("run-through"));
2224 break;
2225 case 2:
2226 padd(ascii("style:wrap"), sXML_CDATA, ascii("dynamic"));
2227 break;
2229 if (fstyle->anchor_type == CHAR_ANCHOR)
2231 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("top"));
2232 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("baseline"));
2233 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("center"));
2234 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
2236 else
2239 switch (-(fstyle->xpos))
2241 case 2:
2242 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("right"));
2243 break;
2244 case 3:
2245 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("center"));
2246 break;
2247 case 1:
2248 default:
2249 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("from-left"));
2250 break;
2252 switch (-(fstyle->ypos))
2254 case 2:
2255 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("bottom"));
2256 break;
2257 case 3:
2258 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("middle"));
2259 break;
2260 case 1:
2261 default:
2262 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("from-top"));
2263 break;
2265 if ( fstyle->anchor_type == PARA_ANCHOR )
2267 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("paragraph"));
2268 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
2270 else
2272 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("page-content"));
2273 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("page-content"));
2276 rstartEl(ascii("style:properties"), rList);
2277 pList->clear();
2278 rendEl(ascii("style:properties"));
2279 rendEl(ascii("style:style"));
2280 if( fstyle->boxtype == 'G' )
2282 padd(ascii("style:name"), sXML_CDATA,
2283 ascii(Int2Str(fstyle->boxnum, "G%d", buf)));
2285 else
2287 padd(ascii("style:name"), sXML_CDATA,
2288 ascii(Int2Str(fstyle->boxnum, "Txtbox%d", buf)));
2291 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
2292 rstartEl(ascii("style:style"), rList);
2293 pList->clear();
2295 padd(ascii("fo:margin-left"), sXML_CDATA, ascii("0cm"));
2296 padd(ascii("fo:margin-right"), sXML_CDATA, ascii("0cm"));
2297 padd(ascii("fo:margin-top"), sXML_CDATA, ascii("0cm"));
2298 padd(ascii("fo:margin-bottom"), sXML_CDATA, ascii("0cm"));
2299 padd(ascii("fo:padding"), sXML_CDATA, ascii("0cm"));
2300 padd(ascii("style:wrap"), sXML_CDATA, ascii("none"));
2301 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("from-top"));
2302 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("paragraph"));
2303 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("from-left"));
2304 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
2305 if( fstyle->boxtype == 'G' )
2307 char *cell = (char *)fstyle->cell;
2308 padd(ascii("draw:luminance"), sXML_CDATA,
2309 ascii(Int2Str(cell[0], "%d%%", buf)));
2310 padd(ascii("draw:contrast"), sXML_CDATA,
2311 ascii(Int2Str(cell[1], "%d%%", buf)));
2312 if( cell[2] == 0 )
2313 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("standard"));
2314 else if( cell[2] == 1 )
2315 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("greyscale"));
2316 else if( cell[2] == 2 )
2317 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("mono"));
2319 else
2321 Cell *cell = (Cell *)fstyle->cell;
2322 if(cell->linetype[0] == cell->linetype[1] &&
2323 cell->linetype[0] == cell->linetype[2] &&
2324 cell->linetype[0] == cell->linetype[3])
2326 switch( cell->linetype[0] )
2328 case 0:
2329 padd(ascii("fo:padding"), sXML_CDATA,ascii("0mm"));
2330 break;
2331 case 1: /* 가는실선 */
2332 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2333 padd(ascii("fo:border"), sXML_CDATA,ascii("0.002cm solid #000000"));
2334 break;
2335 case 2: /* 굵은실선 */
2336 padd(ascii("fo:border"), sXML_CDATA,ascii("0.035cm solid #000000"));
2337 break;
2338 case 4: /* 2중선 */
2339 padd(ascii("style:border-line-width"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2340 padd(ascii("fo:border"), sXML_CDATA,ascii("0.039cm double #000000"));
2341 break;
2344 else
2346 switch( cell->linetype[0] )
2348 case 1: /* 가는실선 */
2349 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2350 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.002cm solid #000000"));
2351 break;
2352 case 2: /* 굵은실선 */
2353 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.035cm solid #000000"));
2354 break;
2355 case 4: /* 2중선 */
2356 padd(ascii("style:border-line-width-left"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2357 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.039cm double #000000"));
2358 break;
2360 switch( cell->linetype[1] )
2362 case 1: /* 가는실선 */
2363 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2364 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.002cm solid #000000"));
2365 break;
2366 case 2: /* 굵은실선 */
2367 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.035cm solid #000000"));
2368 break;
2369 case 4: /* 2중선 */
2370 padd(ascii("style:border-line-width-right"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2371 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.039cm double #000000"));
2372 break;
2374 switch( cell->linetype[2] )
2376 case 1: /* 가는실선 */
2377 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2378 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.002cm solid #000000"));
2379 break;
2380 case 2: /* 굵은실선 */
2381 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.035cm solid #000000"));
2382 break;
2383 case 4: /* 2중선 */
2384 padd(ascii("style:border-line-width-top"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2385 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.039cm double #000000"));
2386 break;
2388 switch( cell->linetype[3] )
2390 case 1: /* 가는실선 */
2391 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2392 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.002cm solid #000000"));
2393 break;
2394 case 2: /* 굵은실선 */
2395 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.035cm solid #000000"));
2396 break;
2397 case 4: /* 2중선 */
2398 padd(ascii("style:border-line-width-bottom"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2399 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.039cm double #000000"));
2400 break;
2403 if(cell->shade != 0)
2404 padd(ascii("fo:background-color"), sXML_CDATA, ascii(hcolor2str(
2405 sal::static_int_cast<uchar>(cell->color),
2406 sal::static_int_cast<uchar>(cell->shade), buf)));
2408 rstartEl(ascii("style:properties"), rList);
2409 pList->clear();
2410 rendEl(ascii("style:properties"));
2411 rendEl(ascii("style:style"));
2416 * Floating 객체에 대한 스타일을 만든다.
2418 void HwpReader::makeFStyle(FBoxStyle * fstyle)
2420 /* 캡션 exist */
2421 if( ( fstyle->boxtype == 'G' || fstyle->boxtype == 'X' ) && fstyle->cap_len > 0 )
2423 makeCaptionStyle(fstyle);
2424 return;
2426 switch( fstyle->boxtype )
2428 case 'X' : // txtbox
2429 case 'E' : // equation
2430 case 'B' : // button
2431 case 'O' : // other
2432 case 'T' : // table
2433 padd(ascii("style:name"), sXML_CDATA,
2434 ascii(Int2Str(fstyle->boxnum, "Txtbox%d", buf)));
2435 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
2436 break;
2437 case 'G' : // graphics
2438 padd(ascii("style:name"), sXML_CDATA,
2439 ascii(Int2Str(fstyle->boxnum, "G%d", buf)));
2440 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
2441 break;
2442 case 'L' : // line TODO : all
2443 padd(ascii("style:name"), sXML_CDATA,
2444 ascii(Int2Str(fstyle->boxnum, "L%d", buf)));
2445 padd( ascii("style:family") , sXML_CDATA , ascii("paragraph") );
2446 break;
2449 rstartEl(ascii("style:style"), rList);
2450 pList->clear();
2452 if ( fstyle->boxtype == 'T')
2454 padd(ascii("fo:padding"), sXML_CDATA, ascii("0cm"));
2457 if( !(fstyle->boxtype == 'G' && fstyle->cap_len > 0 ))
2459 padd(ascii("fo:margin-left"), sXML_CDATA,
2460 Double2Str(WTMM(fstyle->margin[0][0]) ) + ascii("mm"));
2461 padd(ascii("fo:margin-right"), sXML_CDATA,
2462 Double2Str(WTMM(fstyle->margin[0][1])) + ascii("mm"));
2463 padd(ascii("fo:margin-top"), sXML_CDATA,
2464 Double2Str(WTMM(fstyle->margin[0][2])) + ascii("mm"));
2465 padd(ascii("fo:margin-bottom"), sXML_CDATA,
2466 Double2Str(WTMM(fstyle->margin[0][3])) + ascii("mm"));
2469 switch (fstyle->txtflow)
2471 case 0:
2472 padd(ascii("style:wrap"), sXML_CDATA, ascii("none"));
2473 break;
2474 case 1:
2475 if( fstyle->boxtype == 'G' || fstyle->boxtype == 'B' || fstyle->boxtype == 'O')
2476 padd(ascii("style:run-through"), sXML_CDATA, ascii("background"));
2477 padd(ascii("style:wrap"), sXML_CDATA, ascii("run-through"));
2478 break;
2479 case 2:
2480 padd(ascii("style:wrap"), sXML_CDATA, ascii("dynamic"));
2481 break;
2483 if (fstyle->anchor_type == CHAR_ANCHOR)
2485 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("top"));
2486 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("baseline"));
2487 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("center"));
2488 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
2490 else
2493 switch (-(fstyle->xpos))
2495 case 2:
2496 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("right"));
2497 break;
2498 case 3:
2499 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("center"));
2500 break;
2501 case 1:
2502 default:
2503 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("from-left"));
2504 break;
2506 switch (-(fstyle->ypos))
2508 case 2:
2509 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("bottom"));
2510 break;
2511 case 3:
2512 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("middle"));
2513 break;
2514 case 1:
2515 default:
2516 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("from-top"));
2517 break;
2519 if ( fstyle->anchor_type == PARA_ANCHOR )
2521 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("paragraph"));
2522 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
2524 else
2526 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("page-content"));
2527 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("page-content"));
2530 if( fstyle->boxtype == 'X' || fstyle->boxtype == 'B' )
2532 Cell *cell = (Cell *)fstyle->cell;
2533 if(cell->linetype[0] == cell->linetype[1] &&
2534 cell->linetype[0] == cell->linetype[2] &&
2535 cell->linetype[0] == cell->linetype[3])
2537 switch( cell->linetype[0] )
2539 case 0:
2540 padd(ascii("fo:border"), sXML_CDATA, ascii("none"));
2541 break;
2542 case 1: /* 가는실선 */
2543 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2544 padd(ascii("fo:border"), sXML_CDATA,ascii("0.002cm solid #000000"));
2545 break;
2546 case 2: /* 굵은실선 */
2547 padd(ascii("fo:border"), sXML_CDATA,ascii("0.035cm solid #000000"));
2548 break;
2549 case 4: /* 2중선 */
2550 padd(ascii("style:border-line-width"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2551 padd(ascii("fo:border"), sXML_CDATA,ascii("0.039cm double #000000"));
2552 break;
2555 else
2557 switch( cell->linetype[0] )
2559 case 1: /* 가는실선 */
2560 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2561 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.002cm solid #000000"));
2562 break;
2563 case 2: /* 굵은실선 */
2564 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.035cm solid #000000"));
2565 break;
2566 case 4: /* 2중선 */
2567 padd(ascii("style:border-line-width-left"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2568 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.039cm double #000000"));
2569 break;
2571 switch( cell->linetype[1] )
2573 case 1: /* 가는실선 */
2574 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2575 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.002cm solid #000000"));
2576 break;
2577 case 2: /* 굵은실선 */
2578 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.035cm solid #000000"));
2579 break;
2580 case 4: /* 2중선 */
2581 padd(ascii("style:border-line-width-right"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2582 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.039cm double #000000"));
2583 break;
2585 switch( cell->linetype[2] )
2587 case 1: /* 가는실선 */
2588 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2589 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.002cm solid #000000"));
2590 break;
2591 case 2: /* 굵은실선 */
2592 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.035cm solid #000000"));
2593 break;
2594 case 4: /* 2중선 */
2595 padd(ascii("style:border-line-width-top"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2596 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.039cm double #000000"));
2597 break;
2599 switch( cell->linetype[3] )
2601 case 1: /* 가는실선 */
2602 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2603 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.002cm solid #000000"));
2604 break;
2605 case 2: /* 굵은실선 */
2606 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.035cm solid #000000"));
2607 break;
2608 case 4: /* 2중선 */
2609 padd(ascii("style:border-line-width-bottom"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2610 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.039cm double #000000"));
2611 break;
2615 if( cell->linetype[0] == 0 && cell->linetype[1] == 0 &&
2616 cell->linetype[2] == 0 && cell->linetype[3] == 0 ){
2617 padd(ascii("fo:padding"), sXML_CDATA,ascii("0mm"));
2619 else{
2620 padd(ascii("fo:padding-left"), sXML_CDATA,
2621 Double2Str(WTMM(fstyle->margin[1][0])) + ascii("mm"));
2622 padd(ascii("fo:padding-right"), sXML_CDATA,
2623 Double2Str(WTMM(fstyle->margin[1][1])) + ascii("mm"));
2624 padd(ascii("fo:padding-top"), sXML_CDATA,
2625 Double2Str(WTMM(fstyle->margin[1][2])) + ascii("mm"));
2626 padd(ascii("fo:padding-bottom"), sXML_CDATA,
2627 Double2Str(WTMM(fstyle->margin[1][3])) + ascii("mm"));
2629 if(cell->shade != 0)
2630 padd(ascii("fo:background-color"), sXML_CDATA,
2631 ascii(hcolor2str(
2632 sal::static_int_cast<uchar>(cell->color),
2633 sal::static_int_cast<uchar>(cell->shade),
2634 buf)));
2636 else if( fstyle->boxtype == 'E' )
2638 padd(ascii("fo:padding"), sXML_CDATA,ascii("0mm"));
2640 else if( fstyle->boxtype == 'L' )
2642 padd( ascii("style:border-line-width-bottom"), sXML_CDATA, ascii("0.02mm 0.35mm 0.02mm"));
2643 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.039cm double #808080"));
2645 else if( fstyle->boxtype == 'G' )
2647 if( fstyle->margin[1][0] || fstyle->margin[1][1] || fstyle->margin[1][2] || fstyle->margin[1][3] ){
2648 OUString clip = ascii("rect(");
2649 clip += Double2Str(WTMM(-fstyle->margin[1][0]) ) + ascii("mm ");
2650 clip += Double2Str(WTMM(-fstyle->margin[1][1]) ) + ascii("mm ");
2651 clip += Double2Str(WTMM(-fstyle->margin[1][2]) ) + ascii("mm ");
2652 clip += Double2Str(WTMM(-fstyle->margin[1][3]) ) + ascii("mm)");
2653 padd(ascii("style:mirror"), sXML_CDATA, ascii("none"));
2654 padd(ascii("fo:clip"), sXML_CDATA, clip);
2656 char *cell = (char *)fstyle->cell;
2657 padd(ascii("draw:luminance"), sXML_CDATA,
2658 ascii(Int2Str(cell[0], "%d%%", buf)));
2659 padd(ascii("draw:contrast"), sXML_CDATA,
2660 ascii(Int2Str(cell[1], "%d%%", buf)));
2661 if( cell[2] == 0 )
2662 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("standard"));
2663 else if( cell[2] == 1 )
2664 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("greyscale"));
2665 else if( cell[2] == 2 )
2666 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("mono"));
2669 rstartEl(ascii("style:properties"), rList);
2670 pList->clear();
2671 rendEl(ascii("style:properties"));
2672 rendEl(ascii("style:style"));
2676 char *HwpReader::getTStyleName(int index, char *_buf)
2678 return Int2Str(index, "T%d", _buf);
2682 char *HwpReader::getPStyleName(int index, char *_buf)
2684 return Int2Str(index, "P%d", _buf);
2688 void HwpReader::makeChars(hchar_string & rStr)
2690 rchars(OUString(rStr.c_str()));
2691 rStr.clear();
2696 * 문단내에 특수문자가 없고 모든 문자가 동일한 CharShape를 사용하는 경우
2698 void HwpReader::make_text_p0(HWPPara * para, sal_Bool bParaStart)
2700 hchar_string str;
2701 int n;
2702 int res;
2703 hchar dest[3];
2704 unsigned char firstspace = 0;
2705 if( !bParaStart)
2707 padd(ascii("text:style-name"), sXML_CDATA,
2708 ascii(getPStyleName(para->GetParaShape()->index, buf)));
2709 rstartEl(ascii("text:p"), rList);
2710 pList->clear();
2712 if( d->bFirstPara && d->bInBody )
2714 strcpy(buf,"[문서의 처음]"); /* "Begin of Document" */
2715 padd(ascii("text:name"), sXML_CDATA, OUString(buf, strlen(buf), RTL_TEXTENCODING_UTF8));
2716 rstartEl(ascii("text:bookmark"), rList);
2717 pList->clear();
2718 rendEl(ascii("text:bookmark"));
2719 d->bFirstPara = false;
2721 if( d->bInHeader )
2723 makeShowPageNum();
2724 d->bInHeader = false;
2726 padd(ascii("text:style-name"), sXML_CDATA,
2727 ascii(getTStyleName(para->cshape.index, buf)));
2728 rstartEl(ascii("text:span"), rList);
2729 pList->clear();
2731 for (n = 0; n < para->nch && para->hhstr[n]->hh;
2732 n += para->hhstr[n]->WSize())
2734 if (para->hhstr[n]->hh == CH_SPACE && !firstspace)
2736 makeChars(str);
2737 rstartEl(ascii("text:s"), rList);
2738 rendEl(ascii("text:s"));
2740 else if (para->hhstr[n]->hh == CH_END_PARA)
2742 makeChars(str);
2743 rendEl(ascii("text:span"));
2744 rendEl(ascii("text:p"));
2745 break;
2747 else
2749 if (para->hhstr[n]->hh == CH_SPACE)
2750 firstspace = 0;
2751 else
2752 firstspace = 1;
2753 res = hcharconv(para->hhstr[n]->hh, dest, UNICODE);
2754 for( int j = 0 ; j < res; j++ )
2756 str.push_back(dest[j]);
2764 * 문단내에 특수문자가 없으나 문자들이 다른 CharShape를 사용하는 경우
2766 void HwpReader::make_text_p1(HWPPara * para,sal_Bool bParaStart)
2768 hchar_string str;
2769 int n;
2770 int res;
2771 hchar dest[3];
2772 int curr = para->cshape.index;
2773 unsigned char firstspace = 0;
2775 if( !bParaStart )
2777 padd(ascii("text:style-name"), sXML_CDATA,
2778 ascii(getPStyleName(para->GetParaShape()->index, buf)));
2779 rstartEl(ascii("text:p"), rList);
2780 pList->clear();
2782 if( d->bFirstPara && d->bInBody )
2784 /* for HWP's Bookmark */
2785 strcpy(buf,"[문서의 처음]"); /* "Begin of Document" */
2786 padd(ascii("text:name"), sXML_CDATA, OUString(buf, strlen(buf), RTL_TEXTENCODING_UTF8));
2787 rstartEl(ascii("text:bookmark"), rList);
2788 pList->clear();
2789 rendEl(ascii("text:bookmark"));
2790 d->bFirstPara = false;
2792 if( d->bInHeader )
2794 makeShowPageNum();
2795 d->bInHeader = false;
2797 padd(ascii("text:style-name"), sXML_CDATA,
2798 ascii(getTStyleName(curr, buf)));
2799 rstartEl(ascii("text:span"), rList);
2800 pList->clear();
2802 for (n = 0; n < para->nch && para->hhstr[n]->hh;
2803 n += para->hhstr[n]->WSize())
2805 if (para->GetCharShape(n)->index != curr)
2807 makeChars(str);
2808 rendEl(ascii("text:span"));
2809 curr = para->GetCharShape(n)->index;
2810 padd(ascii("text:style-name"), sXML_CDATA,
2811 ascii(getTStyleName(curr, buf)));
2812 rstartEl(ascii("text:span"), rList);
2813 pList->clear();
2815 if (para->hhstr[n]->hh == CH_SPACE && !firstspace)
2817 makeChars(str);
2818 rstartEl(ascii("text:s"), rList);
2819 rendEl(ascii("text:s"));
2821 else if (para->hhstr[n]->hh == CH_END_PARA)
2823 makeChars(str);
2824 rendEl(ascii("text:span"));
2825 rendEl(ascii("text:p"));
2826 break;
2828 else
2830 if( para->hhstr[n]->hh < CH_SPACE )
2831 continue;
2832 if (para->hhstr[n]->hh == CH_SPACE)
2833 firstspace = 0;
2834 else
2835 firstspace = 1;
2836 res = hcharconv(para->hhstr[n]->hh, dest, UNICODE);
2837 for( int j = 0 ; j < res; j++ )
2839 str.push_back(dest[j]);
2847 * 문단 내의 특수문자가 있으며 문자들이 다른 CharShape를 갖는 경우에 대해 처리
2849 void HwpReader::make_text_p3(HWPPara * para,sal_Bool bParaStart)
2851 hchar_string str;
2852 int n, res;
2853 hchar dest[3];
2854 unsigned char firstspace = 0;
2855 bool pstart = bParaStart;
2856 bool tstart = false;
2857 bool infield = false;
2858 int curr = para->cshape.index;
2859 if( d->bFirstPara && d->bInBody )
2861 if ( !pstart ) {
2862 STARTP;
2864 strcpy(buf,"[문서의 처음]"); /* "Begin of Document" */
2865 padd(ascii("text:name"), sXML_CDATA, OUString(buf, strlen(buf), RTL_TEXTENCODING_UTF8));
2866 rstartEl(ascii("text:bookmark"), rList);
2867 pList->clear();
2868 rendEl(ascii("text:bookmark"));
2869 d->bFirstPara = false;
2871 if( d->bInHeader )
2873 if ( !pstart ) {
2874 STARTP;
2876 makeShowPageNum();
2877 d->bInHeader = false;
2880 for (n = 0; n < para->nch && para->hhstr[n]->hh;
2881 n += para->hhstr[n]->WSize())
2883 if( para->hhstr[n]->hh == CH_END_PARA )
2885 if (str.size() > 0)
2887 if( !pstart ){ STARTP;}
2888 if( !tstart ){ STARTT;}
2889 makeChars(str);
2891 if( tstart ){ ENDT;}
2892 if( !pstart ){ STARTP;}
2893 if( pstart ){ ENDP;}
2894 break;
2896 else if( para->hhstr[n]->hh == CH_SPACE && !firstspace)
2898 if( !pstart ) {STARTP;}
2899 if( !tstart ) {STARTT;}
2900 makeChars(str);
2901 rstartEl(ascii("text:s"), rList);
2902 pList->clear();
2903 rendEl(ascii("text:s"));
2905 else if ( para->hhstr[n]->hh >= CH_SPACE )
2907 if( n > 0 )
2908 if( para->GetCharShape(n)->index != para->GetCharShape(n-1)->index && !infield )
2910 if( !pstart ) {STARTP;}
2911 if( !tstart ) {STARTT;}
2912 makeChars(str);
2913 ENDT;
2915 if( para->hhstr[n]->hh == CH_SPACE )
2916 firstspace = 0;
2917 else
2918 firstspace = 1;
2919 res = hcharconv(para->hhstr[n]->hh, dest, UNICODE);
2920 for( int j = 0 ; j < res; j++ )
2922 str.push_back(dest[j]);
2925 else if (para->hhstr[n]->hh == CH_FIELD)
2927 FieldCode *hbox = (FieldCode *) para->hhstr[n];
2928 if( hbox->location_info == 1)
2930 if( !pstart ) {STARTP;}
2931 if( !tstart ) {STARTT;}
2932 makeChars(str);
2933 firstspace = 1;
2934 if( hbox->type[0] == 4 && hbox->type[1] == 0 )
2936 field = hbox->str3;
2938 else{
2939 makeFieldCode(str, hbox);
2941 infield = true;
2943 else
2945 firstspace = 1;
2946 if( hbox->type[0] == 4 && hbox->type[1] == 0 )
2948 makeFieldCode(str, hbox);
2949 field = 0L;
2951 infield = false;
2952 str.clear();
2955 else
2957 switch (para->hhstr[n]->hh)
2959 case CH_BOOKMARK:
2960 if( !pstart ) {STARTP;}
2961 if( !tstart ) {STARTT;}
2962 makeChars(str);
2963 makeBookmark((Bookmark *) para->hhstr[n]);
2964 break;
2965 case CH_DATE_FORM: // 7
2966 break;
2967 case CH_DATE_CODE: // 8
2968 if( !pstart ) {STARTP;}
2969 if( !tstart ) {STARTT;}
2970 makeChars(str);
2971 makeDateCode((DateCode *) para->hhstr[n]);
2972 break;
2973 case CH_TAB: // 9
2974 if( !pstart ) {STARTP;}
2975 if (str.size() > 0)
2977 if( !tstart ) {STARTT;}
2978 makeChars(str);
2980 makeTab((Tab *) para->hhstr[n]);
2981 break;
2982 case CH_TEXT_BOX: /* 10 - 표/텍스트박스/수식/버튼/하이퍼텍스트 순 */
2984 /* 일단은 표만 처리하고, 수식은 text:p안에 들어가는 것으로 처리. */
2985 TxtBox *hbox = (TxtBox *) para->hhstr[n];
2987 if( hbox->style.anchor_type == 0 )
2989 if( !pstart ) {STARTP;}
2990 if( !tstart ) {STARTT;}
2991 makeChars(str);
2993 else
2995 if( !pstart ) {STARTP;}
2996 if (str.size() > 0)
2998 if( !tstart ) {STARTT;}
2999 makeChars(str);
3001 if( tstart ) {ENDT;}
3003 switch (hbox->type)
3005 case TBL_TYPE: // table
3006 case TXT_TYPE: // text box
3007 case EQU_TYPE: // formula
3008 makeTextBox(hbox);
3009 break;
3010 case BUTTON_TYPE: // text button
3011 case HYPERTEXT_TYPE: // hypertext
3012 makeHyperText(hbox);
3013 break;
3015 break;
3017 case CH_PICTURE: // 11
3019 Picture *hbox = (Picture *) para->hhstr[n];
3020 if( hbox->style.anchor_type == 0 )
3022 if( !pstart ) {STARTP;}
3023 if( !tstart ) {STARTT;}
3024 makeChars(str);
3026 else
3028 if( !pstart ) {STARTP;}
3029 if (str.size() > 0)
3031 if( !tstart ) {STARTT;}
3032 makeChars(str);
3034 if( tstart ) {ENDT;}
3036 makePicture(hbox);
3037 break;
3039 case CH_LINE: // 14
3041 Line *hbox = (Line *) para->hhstr[n];
3042 if (str.size() > 0)
3044 if( !pstart ) {STARTP;}
3045 if( !tstart ) {STARTT;}
3046 makeChars(str);
3048 if( tstart ) {ENDT;}
3049 if( pstart ) {ENDP;}
3050 makeLine(hbox);
3051 pstart = true;
3052 break;
3054 case CH_HIDDEN: // 15
3055 if( !pstart ) {STARTP;}
3056 if( !tstart ) {STARTT;}
3057 makeChars(str);
3058 makeHidden((Hidden *) para->hhstr[n]);
3059 break;
3060 case CH_FOOTNOTE: // 17
3061 if( !pstart ) {STARTP;}
3062 if( !tstart ) {STARTT;}
3063 makeChars(str);
3064 makeFootnote((Footnote *) para->hhstr[n]);
3065 break;
3066 case CH_AUTO_NUM: // 18
3067 if( !pstart ) {STARTP;}
3068 if( !tstart ) {STARTT;}
3069 makeChars(str);
3070 makeAutoNum((AutoNum *) para->hhstr[n]);
3071 break;
3072 case CH_NEW_NUM: // 19 -skip
3073 break;
3074 case CH_PAGE_NUM_CTRL: // 21
3075 break;
3076 case CH_MAIL_MERGE: // 22
3077 if( !pstart ) {STARTP;}
3078 if( !tstart ) {STARTT;}
3079 makeChars(str);
3080 makeMailMerge((MailMerge *) para->hhstr[n]);
3081 break;
3082 case CH_COMPOSE: /* 23 - 글자겹침 */
3083 break;
3084 case CH_HYPHEN: // 24
3085 break;
3086 case CH_TOC_MARK: /* 25 아래의 3개는 작업해야 한다. */
3087 if( !pstart ) {STARTP;}
3088 if( !tstart ) {STARTT;}
3089 makeChars(str);
3090 makeTocMark((TocMark *) para->hhstr[n]);
3091 break;
3092 case CH_INDEX_MARK: // 26
3093 if( !pstart ) {STARTP;}
3094 if( !tstart ) {STARTT;}
3095 makeChars(str);
3096 makeIndexMark((IndexMark *) para->hhstr[n]);
3097 break;
3098 case CH_OUTLINE: // 28
3099 if( !pstart ) {STARTP;}
3100 if( !tstart ) {STARTT;}
3101 makeChars(str);
3102 makeOutline((Outline *) para->hhstr[n]);
3103 break;
3104 case CH_FIXED_SPACE:
3105 case CH_KEEP_SPACE:
3106 str.push_back(0x0020);
3107 break;
3114 void HwpReader::makeFieldCode(hchar_string & rStr, FieldCode *hbox)
3116 /* 누름틀 */
3117 if( hbox->type[0] == 4 && hbox->type[1] == 0 )
3119 padd(ascii("text:placeholder-type"), sXML_CDATA, ascii("text"));
3120 if( field )
3121 padd(ascii("text:description"), sXML_CDATA, hconv(field));
3122 rstartEl( ascii("text:placeholder"), rList);
3123 pList->clear();
3124 rchars( OUString(rStr.c_str()));
3125 rendEl( ascii("text:placeholder") );
3127 /* 문서요약 */
3128 else if( hbox->type[0] == 3 && hbox->type[1] == 0 )
3130 if (hconv(hbox->str3) == "title")
3132 rstartEl( ascii("text:title"), rList );
3133 rchars( hconv(hbox->str2) );
3134 rendEl( ascii("text:title") );
3136 else if (hconv(hbox->str3) == "subject")
3138 rstartEl( ascii("text:subject"), rList );
3139 rchars( hconv(hbox->str2) );
3140 rendEl( ascii("text:subject") );
3142 else if (hconv(hbox->str3) == "author")
3144 rstartEl( ascii("text:author-name"), rList );
3145 rchars( hconv(hbox->str2) );
3146 rendEl( ascii("text:author-name") );
3148 else if (hconv(hbox->str3) == "keywords")
3150 rstartEl( ascii("text:keywords"), rList );
3151 rchars( hconv(hbox->str2) );
3152 rendEl( ascii("text:keywords") );
3155 /* 개인정보 */
3156 else if( hbox->type[0] == 3 && hbox->type[1] == 1 )
3158 if (hconv(hbox->str3) == "User")
3160 rstartEl( ascii("text:sender-lastname"), rList );
3161 rchars( hconv(hbox->str2) );
3162 rendEl( ascii("text:sender-lastname") );
3164 else if (hconv(hbox->str3) == "Company")
3166 rstartEl( ascii("text:sender-company"), rList );
3167 rchars( hconv(hbox->str2) );
3168 rendEl( ascii("text:sender-company") );
3170 else if (hconv(hbox->str3) == "Position")
3172 rstartEl( ascii("text:sender-title"), rList );
3173 rchars( hconv(hbox->str2) );
3174 rendEl( ascii("text:sender-title") );
3176 else if (hconv(hbox->str3) == "Division")
3178 rstartEl( ascii("text:sender-position"), rList );
3179 rchars( hconv(hbox->str2) );
3180 rendEl( ascii("text:sender-position") );
3182 else if (hconv(hbox->str3) == "Fax")
3184 rstartEl( ascii("text:sender-fax"), rList );
3185 rchars( hconv(hbox->str2) );
3186 rendEl( ascii("text:sender-fax") );
3188 else if (hconv(hbox->str3) == "Pager")
3190 rstartEl( ascii("text:phone-private"), rList );
3191 rchars( hconv(hbox->str2) );
3192 rendEl( ascii("text:phone-private") );
3194 else if (hconv(hbox->str3) == "E-mail")
3196 rstartEl( ascii("text:sender-email"), rList );
3197 rchars( hconv(hbox->str2) );
3198 rendEl( ascii("text:sender-email") );
3200 else if (hconv(hbox->str3) == "Zipcode(office)")
3202 rstartEl( ascii("text:sender-postal-code"), rList );
3203 rchars( hconv(hbox->str2) );
3204 rendEl( ascii("text:sender-postal-code") );
3206 else if (hconv(hbox->str3) == "Phone(office)")
3208 rstartEl( ascii("text:sender-phone-work"), rList );
3209 rchars( hconv(hbox->str2) );
3210 rendEl( ascii("text:sender-phone-work") );
3212 else if (hconv(hbox->str3) == "Address(office)")
3214 rstartEl( ascii("text:sender-street"), rList );
3215 rchars( hconv(hbox->str2) );
3216 rendEl( ascii("text:sender-street") );
3220 else if( hbox->type[0] == 3 && hbox->type[1] == 2 ) /* 만든날짜 */
3222 if( hbox->m_pDate )
3223 padd(ascii("style:data-style-name"), sXML_CDATA,
3224 ascii(Int2Str(hbox->m_pDate->key, "N%d", buf)));
3225 rstartEl( ascii("text:creation-date"), rList );
3226 pList->clear();
3227 rchars( hconv(hbox->str2) );
3228 rendEl( ascii("text:creation-date") );
3234 * Completed
3235 * 스타오피스에서는 북마크를 Reference로 참조하나 hwp에는 그 기능이 없다.
3237 void HwpReader::makeBookmark(Bookmark * hbox)
3239 if (hbox->type == 0)
3241 padd(ascii("text:name"), sXML_CDATA, (hconv(hbox->id)));
3242 rstartEl(ascii("text:bookmark"), rList);
3243 pList->clear();
3244 rendEl(ascii("text:bookmark"));
3246 else if (hbox->type == 1) /* 블록 북마크일 경우 시작과 끝이 있다 */
3248 padd(ascii("text:name"), sXML_CDATA, (hconv(hbox->id)));
3249 rstartEl(ascii("text:bookmark-start"), rList);
3250 pList->clear();
3251 rendEl(ascii("text:bookmark-start"));
3253 else if (hbox->type == 2)
3255 padd(ascii("text:name"), sXML_CDATA, (hconv(hbox->id)));
3256 rstartEl(ascii("text:bookmark-end"), rList);
3257 pList->clear();
3258 rendEl(ascii("text:bookmark-end"));
3263 #include "datecode.h"
3265 void HwpReader::makeDateFormat(DateCode * hbox)
3267 padd(ascii("style:name"), sXML_CDATA,
3268 ascii(Int2Str(hbox->key, "N%d", buf)));
3269 padd(ascii("style:family"), sXML_CDATA,ascii("data-style"));
3270 padd(ascii("number:language"), sXML_CDATA,ascii("ko"));
3271 padd(ascii("number:country"), sXML_CDATA,ascii("KR"));
3273 rstartEl(ascii("number:date-style"), rList);
3274 pList->clear();
3276 bool add_zero = false;
3277 int zero_check = 0;
3278 hbox->format[DATE_SIZE -1] = 0;
3280 const hchar *fmt = hbox->format[0] ? hbox->format : defaultform;
3282 for( ; *fmt ; fmt++ )
3284 if( zero_check == 1 )
3286 zero_check = 0;
3288 else
3289 add_zero = false;
3291 switch( *fmt )
3293 case '0':
3294 zero_check = 1;
3295 add_zero = true;
3296 break;
3297 case '1':
3298 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3299 rstartEl(ascii("number:year"), rList);
3300 pList->clear();
3301 rendEl(ascii("number:year"));
3302 break;
3303 case '!':
3304 rstartEl(ascii("number:year"), rList);
3305 pList->clear();
3306 rendEl(ascii("number:year"));
3307 break;
3308 case '2':
3309 if( add_zero )
3310 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3311 rstartEl(ascii("number:month"), rList);
3312 pList->clear();
3313 rendEl(ascii("number:month"));
3314 break;
3315 case '@':
3316 padd(ascii("number:textual"), sXML_CDATA, ascii("true"));
3317 rstartEl(ascii("number:month"), rList);
3318 pList->clear();
3319 rendEl(ascii("number:month"));
3320 break;
3321 case '*':
3322 padd(ascii("number:textual"), sXML_CDATA, ascii("true"));
3323 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3324 rstartEl(ascii("number:month"), rList);
3325 pList->clear();
3326 rendEl(ascii("number:month"));
3327 break;
3328 case '3':
3329 if( add_zero )
3330 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3331 rstartEl(ascii("number:day"), rList);
3332 pList->clear();
3333 rendEl(ascii("number:day"));
3334 break;
3335 case '#':
3336 if( add_zero )
3337 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3338 rstartEl(ascii("number:day"), rList);
3339 pList->clear();
3340 rendEl(ascii("number:day"));
3341 switch( hbox->date[DateCode::DAY] % 10)
3343 case 1:
3344 rstartEl(ascii("number:text"), rList);
3345 rchars(ascii("st"));
3346 rendEl(ascii("number:text"));
3347 break;
3348 case 2:
3349 rstartEl(ascii("number:text"), rList);
3350 rchars(ascii("nd"));
3351 rendEl(ascii("number:text"));
3352 break;
3353 case 3:
3354 rstartEl(ascii("number:text"), rList);
3355 rchars(ascii("rd"));
3356 rendEl(ascii("number:text"));
3357 break;
3358 default:
3359 rstartEl(ascii("number:text"), rList);
3360 rchars(ascii("th"));
3361 rendEl(ascii("number:text"));
3362 break;
3364 break;
3365 case '4':
3366 case '$':
3367 if( add_zero )
3368 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3369 rstartEl(ascii("number:hours"), rList);
3370 pList->clear();
3371 rendEl(ascii("number:hours"));
3372 break;
3373 case '5':
3374 case '%':
3375 if( add_zero )
3376 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3377 rstartEl(ascii("number:minutes"), rList);
3378 pList->clear();
3379 rendEl(ascii("number:minutes"));
3380 break;
3381 case '_':
3382 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3383 case '6':
3384 case '^':
3385 rstartEl(ascii("number:day-of-week"), rList);
3386 pList->clear();
3387 rendEl(ascii("number:day-of-week"));
3388 break;
3389 case '7':
3390 case '&':
3391 case '+':
3392 rstartEl(ascii("number:am-pm"), rList);
3393 pList->clear();
3394 rendEl(ascii("number:am-pm"));
3395 break;
3396 case '~': // Chinese Locale
3397 break;
3398 default:
3399 hchar sbuf[2];
3400 sbuf[0] = *fmt;
3401 sbuf[1] = 0;
3402 rstartEl(ascii("number:text"), rList);
3403 rchars((hconv(sbuf)));
3404 rendEl(ascii("number:text"));
3405 break;
3408 pList->clear();
3409 rendEl(ascii("number:date-style"));
3413 void HwpReader::makeDateCode(DateCode * hbox)
3415 padd(ascii("style:data-style-name"), sXML_CDATA,
3416 ascii(Int2Str(hbox->key, "N%d", buf)));
3417 rstartEl( ascii("text:date"), rList );
3418 pList->clear();
3419 hchar_string const boxstr = hbox->GetString();
3420 rchars((hconv(boxstr.c_str())));
3421 rendEl( ascii("text:date") );
3425 void HwpReader::makeTab(Tab * ) /*hbox */
3427 rstartEl(ascii("text:tab-stop"), rList);
3428 rendEl(ascii("text:tab-stop"));
3432 void HwpReader::makeTable(TxtBox * hbox)
3434 padd(ascii("table:name"), sXML_CDATA,
3435 ascii(Int2Str(hbox->style.boxnum, "Table%d", buf)));
3436 padd(ascii("table:style-name"), sXML_CDATA,
3437 ascii(Int2Str(hbox->style.boxnum, "Table%d", buf)));
3438 rstartEl(ascii("table:table"), rList);
3439 pList->clear();
3441 Table *tbl = hbox->m_pTable;
3442 // ----------- column ---------------- //
3443 for (size_t i = 0 ; i < tbl->columns.nCount -1 ; i++)
3445 sprintf(buf,"Table%d.%c",hbox->style.boxnum, static_cast<char>('A'+i));
3446 padd(ascii("table:style-name"), sXML_CDATA, ascii( buf ));
3447 rstartEl(ascii("table:table-column"), rList);
3448 pList->clear();
3449 rendEl(ascii("table:table-column"));
3452 // ----------- cell ---------------- //
3453 int j = -1, k = -1;
3454 for (int i = 0 ; i < static_cast<int>(tbl->cells.size()); i++)
3456 std::list<TCell*>::iterator it = tbl->cells.begin();
3458 for( int ii = 0; it != tbl->cells.end(); ++it, ii++ ){
3459 if( ii == i )
3460 break;
3463 TCell *tcell = *it;
3464 if( tcell->nRowIndex > j )
3466 if( j > k )
3468 rendEl(ascii("table:table-row"));
3469 k = j;
3471 // --------------- row ---------------- //
3472 sprintf(buf,"Table%d.row%d",hbox->style.boxnum, tcell->nRowIndex + 1);
3473 padd(ascii("table:style-name"), sXML_CDATA, ascii( buf ));
3474 rstartEl(ascii("table:table-row"), rList);
3475 pList->clear();
3476 j = tcell->nRowIndex;
3479 sprintf(buf,"Table%d.%c%d",hbox->style.boxnum, 'A'+ tcell->nColumnIndex, tcell->nRowIndex +1);
3480 padd(ascii("table:style-name"), sXML_CDATA, ascii( buf ));
3481 if( tcell->nColumnSpan > 1 )
3482 padd(ascii("table:number-columns-spanned"), sXML_CDATA,
3483 ascii(Int2Str(tcell->nColumnSpan, "%d", buf)));
3484 if( tcell->nRowSpan > 1 )
3485 padd(ascii("table:number-rows-spanned"), sXML_CDATA,
3486 ascii(Int2Str(tcell->nRowSpan, "%d", buf)));
3487 padd(ascii("table:value-type"), sXML_CDATA,ascii("string"));
3488 if( tcell->pCell->protect )
3489 padd(ascii("table:protected"), sXML_CDATA,ascii("true"));
3490 rstartEl(ascii("table:table-cell"), rList);
3491 pList->clear();
3492 parsePara(hbox->plists[tcell->pCell->key].front());
3493 rendEl(ascii("table:table-cell"));
3495 rendEl(ascii("table:table-row"));
3496 rendEl(ascii("table:table"));
3501 * 텍스트박스와 테이블을 파싱한다.
3502 * 1. draw:style-name, draw:name, text:anchor-type, svg:width,
3503 * fo:min-height, svg:x, svg:y
3504 * TODO : fo:background-color로 셀의 칼라 설정=>스타일에 들어가는 지 아직 모르겠다.
3506 void HwpReader::makeTextBox(TxtBox * hbox)
3508 if( hbox->style.cap_len > 0 && hbox->type == TXT_TYPE)
3510 padd(ascii("draw:style-name"), sXML_CDATA,
3511 ascii(Int2Str(hbox->style.boxnum, "CapBox%d", buf)));
3512 padd(ascii("draw:name"), sXML_CDATA,
3513 ascii(Int2Str(hbox->style.boxnum, "CaptionBox%d", buf)));
3514 padd(ascii("draw:z-index"), sXML_CDATA,
3515 ascii(Int2Str(hbox->zorder, "%d", buf)));
3516 switch (hbox->style.anchor_type)
3518 case CHAR_ANCHOR:
3519 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3520 break;
3521 case PARA_ANCHOR:
3522 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
3523 break;
3524 case PAGE_ANCHOR:
3525 case PAPER_ANCHOR:
3527 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("page"));
3528 padd(ascii("text:anchor-page-number"), sXML_CDATA,
3529 ascii(Int2Str(hbox->pgno +1, "%d", buf)));
3530 break;
3533 if (hbox->style.anchor_type != CHAR_ANCHOR)
3535 padd(ascii("svg:x"), sXML_CDATA,
3536 Double2Str(WTMM( ( hbox->pgx + hbox->style.margin[0][0] ) )) + ascii("mm"));
3537 padd(ascii("svg:y"), sXML_CDATA,
3538 Double2Str(WTMM( ( hbox->pgy + hbox->style.margin[0][2] ) )) + ascii("mm"));
3540 padd(ascii("svg:width"), sXML_CDATA,
3541 Double2Str(WTMM(( hbox->box_xs + hbox->cap_xs) )) + ascii("mm"));
3542 padd(ascii("fo:min-height"), sXML_CDATA,
3543 Double2Str(WTMM(( hbox->box_ys + hbox->cap_ys) )) + ascii("mm"));
3544 rstartEl(ascii("draw:text-box"), rList);
3545 pList->clear();
3546 if( hbox->cap_pos % 2 ) /* 캡션이 위쪽에 위치한다 */
3548 parsePara(hbox->caption.front());
3550 padd( ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
3551 rstartEl(ascii("text:p"), rList);
3552 pList->clear();
3554 else{
3555 padd(ascii("draw:z-index"), sXML_CDATA,
3556 ascii(Int2Str(hbox->zorder, "%d", buf)));
3559 padd(ascii("draw:style-name"), sXML_CDATA,
3560 ascii(Int2Str(hbox->style.boxnum, "Txtbox%d", buf)));
3561 padd(ascii("draw:name"), sXML_CDATA,
3562 ascii(Int2Str(hbox->style.boxnum, "Frame%d", buf)));
3564 if( hbox->style.cap_len <= 0 || hbox->type != TXT_TYPE )
3566 int x = 0;
3567 int y = 0;
3568 switch (hbox->style.anchor_type)
3570 case CHAR_ANCHOR:
3571 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3572 break;
3573 case PARA_ANCHOR:
3574 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
3575 break;
3576 case PAGE_ANCHOR:
3577 case PAPER_ANCHOR:
3579 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("page"));
3580 padd(ascii("text:anchor-page-number"), sXML_CDATA,
3581 ascii(Int2Str(hbox->pgno +1, "%d", buf)));
3582 break;
3585 if( hbox->style.anchor_type != CHAR_ANCHOR )
3587 x += hbox->style.margin[0][0];
3588 y += hbox->style.margin[0][2];
3590 padd(ascii("svg:x"), sXML_CDATA,
3591 Double2Str(WTMM( hbox->pgx + x )) + ascii("mm"));
3592 padd(ascii("svg:y"), sXML_CDATA,
3593 Double2Str(WTMM( hbox->pgy + y )) + ascii("mm"));
3595 else
3597 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3598 padd(ascii("svg:y"), sXML_CDATA, ascii("0cm"));
3600 padd(ascii("svg:width"), sXML_CDATA,
3601 Double2Str(WTMM( hbox->box_xs )) + ascii("mm"));
3602 if( hbox->style.cap_len > 0 && hbox->type != TXT_TYPE)
3603 padd(ascii("fo:min-height"), sXML_CDATA,
3604 Double2Str(WTMM( hbox->box_ys + hbox->cap_ys)) + ascii("mm"));
3605 else
3606 padd(ascii("svg:height"), sXML_CDATA,
3607 Double2Str(WTMM(hbox->box_ys )) + ascii("mm"));
3609 if( hbox->type != EQU_TYPE )
3611 rstartEl(ascii("draw:text-box"), rList);
3612 pList->clear();
3613 /* 캡션이 존재하고, 위쪽에 있으면 */
3614 if( hbox->style.cap_len > 0 && (hbox->cap_pos % 2) && hbox->type == TBL_TYPE )
3616 parsePara(hbox->caption.front());
3618 if( hbox->type == TBL_TYPE) // Is Table
3620 makeTable(hbox);
3622 else // Is TextBox
3624 parsePara(hbox->plists[0].front());
3626 /* 캡션이 존재하고, 아래쪽에 있으면 */
3627 if( hbox->style.cap_len > 0 && !(hbox->cap_pos % 2) && hbox->type == TBL_TYPE)
3629 parsePara(hbox->caption.front());
3631 rendEl(ascii("draw:text-box"));
3632 // Caption exist and it is text-box
3633 if( hbox->style.cap_len > 0 && hbox->type == TXT_TYPE)
3635 rendEl( ascii("text:p"));
3636 if( !(hbox->cap_pos % 2))
3638 parsePara(hbox->caption.front());
3640 rendEl( ascii("draw:text-box"));
3643 else // is Formula
3645 rstartEl(ascii("draw:object"), rList);
3646 pList->clear();
3647 makeFormula(hbox);
3648 rendEl(ascii("draw:object"));
3654 * MathML로 변환해야 한다.
3657 void HwpReader::makeFormula(TxtBox * hbox)
3659 char mybuf[3000];
3660 HWPPara* pPar;
3661 CharShape *cshape = 0;
3663 int n, c, res;
3664 hchar dest[3];
3665 size_t l = 0;
3667 pPar = hbox->plists[0].front();
3668 while( pPar )
3670 for( n = 0; n < pPar->nch && pPar->hhstr[n]->hh;
3671 n += pPar->hhstr[n]->WSize() )
3673 if (!cshape)
3674 cshape = pPar->GetCharShape(n);
3675 if (l >= sizeof(mybuf)-7)
3676 break;
3677 res = hcharconv(pPar->hhstr[n]->hh, dest, UNICODE);
3678 for( int j = 0 ; j < res; j++ ){
3679 c = dest[j];
3680 if( c < 32 )
3681 c = ' ';
3682 if( c < 256 )
3683 mybuf[l++] = sal::static_int_cast<char>(c);
3684 else
3686 mybuf[l++] = sal::static_int_cast<char>((c >> 8) & 0xff);
3687 mybuf[l++] = sal::static_int_cast<char>(c & 0xff);
3691 if (l >= sizeof(mybuf)-7)
3692 break;
3693 mybuf[l++] = '\n';
3694 pPar = pPar->Next();
3696 mybuf[l] = '\0';
3698 Formula *form = new Formula(mybuf);
3699 form->setDocumentHandler(m_rxDocumentHandler);
3700 form->setAttributeListImpl(pList);
3701 form->parse();
3703 delete form;
3708 * platform정보를 읽어들여서 href가 C:\나 D:\로 시작할 경우 리눅스나 솔라리스이면
3709 * C:\ => 홈으로, D:\ => 루트(/)로 바꾸어주는 작업이 필요하다. 이것은
3710 * 한컴이 도스에뮬레이터를 쓰기 때문이다.
3712 void HwpReader::makeHyperText(TxtBox * hbox)
3714 HyperText *hypert = hwpfile.GetHyperText();
3715 if( !hypert ) return;
3717 if( strlen((char *)hypert->filename) > 0 ){
3718 ::std::string const tmp = hstr2ksstr(hypert->bookmark);
3719 ::std::string const tmp2 = hstr2ksstr(kstr2hstr(
3720 #ifdef _WIN32
3721 (uchar *) urltowin((char *)hypert->filename).c_str()).c_str());
3722 #else
3723 (uchar *) urltounix((char *)hypert->filename).c_str()).c_str());
3724 #endif
3725 padd(ascii("xlink:type"), sXML_CDATA, ascii("simple"));
3726 if (tmp.size() > 0 && strcmp(tmp.c_str(), "[HTML]")) {
3727 ::std::string tmp3(tmp2);
3728 tmp3.push_back('#');
3729 tmp3.append(tmp);
3730 padd(ascii("xlink:href"), sXML_CDATA,
3731 OUString(tmp3.c_str(), tmp3.size()+1, RTL_TEXTENCODING_EUC_KR));
3733 else{
3734 padd(ascii("xlink:href"), sXML_CDATA,
3735 OUString(tmp2.c_str(), tmp2.size()+1, RTL_TEXTENCODING_EUC_KR));
3739 else
3741 padd(ascii("xlink:type"), sXML_CDATA, ascii("simple"));
3742 ::std::string tmp;
3743 tmp.push_back('#');
3744 tmp.append(hstr2ksstr(hypert->bookmark));
3745 padd(ascii("xlink:href"), sXML_CDATA,
3746 OUString(tmp.c_str(), tmp.size()+1, RTL_TEXTENCODING_EUC_KR));
3748 rstartEl(ascii("draw:a"), rList);
3749 pList->clear();
3750 makeTextBox(hbox);
3751 rendEl(ascii("draw:a"));
3756 * platform정보를 읽어들여서 href가 C:\나 D:\로 시작할 경우 리눅스나 솔라리스이면
3757 * C:\ => 홈으로, D:\ => 루트(/)로 바꾸었다. 이것은
3758 * 한컴이 도스에뮬레이터를 쓰기 때문이다.
3760 void HwpReader::makePicture(Picture * hbox)
3762 switch (hbox->pictype)
3764 case PICTYPE_OLE:
3765 case PICTYPE_EMBED:
3766 case PICTYPE_FILE:
3768 if( hbox->style.cap_len > 0 )
3770 padd(ascii("draw:style-name"), sXML_CDATA,
3771 ascii(Int2Str(hbox->style.boxnum, "CapBox%d", buf)));
3772 padd(ascii("draw:name"), sXML_CDATA,
3773 ascii(Int2Str(hbox->style.boxnum, "CaptionBox%d", buf)));
3774 padd(ascii("draw:z-index"), sXML_CDATA,
3775 ascii(Int2Str(hbox->zorder, "%d", buf)));
3776 switch (hbox->style.anchor_type)
3778 case CHAR_ANCHOR:
3779 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3780 break;
3781 case PARA_ANCHOR:
3782 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
3783 break;
3784 case PAGE_ANCHOR:
3785 case PAPER_ANCHOR:
3787 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("page"));
3788 padd(ascii("text:anchor-page-number"), sXML_CDATA,
3789 ascii(Int2Str(hbox->pgno +1, "%d", buf)));
3790 break;
3793 if (hbox->style.anchor_type != CHAR_ANCHOR)
3795 padd(ascii("svg:x"), sXML_CDATA,
3796 Double2Str(WTMM( hbox->pgx + hbox->style.margin[0][0] )) + ascii("mm"));
3797 padd(ascii("svg:y"), sXML_CDATA,
3798 Double2Str(WTMM( hbox->pgy + hbox->style.margin[0][2] )) + ascii("mm"));
3800 padd(ascii("svg:width"), sXML_CDATA,
3801 Double2Str(WTMM( hbox->box_xs + hbox->style.margin[1][0] + hbox->style.margin[1][1] )) + ascii("mm"));
3802 padd(ascii("fo:min-height"), sXML_CDATA,
3803 Double2Str(WTMM( hbox->box_ys + hbox->style.margin[1][2] + hbox->style.margin[1][3] + hbox->cap_ys )) + ascii("mm"));
3804 rstartEl(ascii("draw:text-box"), rList);
3805 pList->clear();
3806 if( hbox->cap_pos % 2 ) /* 캡션이 위쪽에 위치한다 */
3808 parsePara(hbox->caption.front());
3810 padd( ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
3811 rstartEl(ascii("text:p"), rList);
3812 pList->clear();
3814 if( hbox->ishyper )
3816 padd(ascii("xlink:type"), sXML_CDATA, ascii("simple"));
3817 #ifdef _WIN32
3818 if( hbox->follow[4] != 0 )
3819 padd(ascii("xlink:href"), sXML_CDATA, (hconv(kstr2hstr(hbox->follow + 4).c_str())));
3820 else
3821 padd(ascii("xlink:href"), sXML_CDATA, (hconv(kstr2hstr(hbox->follow + 5).c_str())));
3822 #else
3823 if( hbox->follow[4] != 0 )
3824 padd(ascii("xlink:href"), sXML_CDATA,
3825 (hconv(kstr2hstr((uchar *)urltounix((char *)(hbox->follow + 4)).c_str()).c_str())));
3826 else
3827 padd(ascii("xlink:href"), sXML_CDATA,
3828 (hconv(kstr2hstr((uchar *)urltounix((char *)(hbox->follow + 5)).c_str()).c_str())));
3829 #endif
3830 rstartEl(ascii("draw:a"), rList);
3831 pList->clear();
3833 padd(ascii("draw:style-name"), sXML_CDATA,
3834 ascii(Int2Str(hbox->style.boxnum, "G%d", buf)));
3835 padd(ascii("draw:name"), sXML_CDATA,
3836 ascii(Int2Str(hbox->style.boxnum, "Image%d", buf)));
3838 if( hbox->style.cap_len <= 0 )
3840 padd(ascii("draw:z-index"), sXML_CDATA,
3841 ascii(Int2Str(hbox->zorder, "%d", buf)));
3842 switch (hbox->style.anchor_type)
3844 case CHAR_ANCHOR:
3845 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3846 break;
3847 case PARA_ANCHOR:
3848 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
3849 break;
3850 case PAGE_ANCHOR:
3851 case PAPER_ANCHOR:
3853 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("page"));
3854 padd(ascii("text:anchor-page-number"), sXML_CDATA,
3855 ascii(Int2Str(hbox->pgno +1, "%d", buf)));
3856 break;
3859 if (hbox->style.anchor_type != CHAR_ANCHOR)
3861 padd(ascii("svg:x"), sXML_CDATA,
3862 Double2Str(WTMM( hbox->pgx + hbox->style.margin[0][0] )) + ascii("mm"));
3863 padd(ascii("svg:y"), sXML_CDATA,
3864 Double2Str(WTMM( hbox->pgy + hbox->style.margin[0][2] )) + ascii("mm"));
3867 else
3869 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3870 padd(ascii("svg:y"), sXML_CDATA, ascii("0cm"));
3872 padd(ascii("svg:width"), sXML_CDATA,
3873 Double2Str(WTMM( hbox->box_xs + hbox->style.margin[1][0] + hbox->style.margin[1][1])) + ascii("mm"));
3874 padd(ascii("svg:height"), sXML_CDATA,
3875 Double2Str(WTMM( hbox->box_ys + hbox->style.margin[1][2] + hbox->style.margin[1][3])) + ascii("mm"));
3877 if ( hbox->pictype == PICTYPE_FILE ){
3878 #ifdef _WIN32
3879 sprintf(buf, "file:///%s", hbox->picinfo.picun.path );
3880 padd(ascii("xlink:href"), sXML_CDATA, (hconv(kstr2hstr((uchar *) buf).c_str())));
3881 #else
3882 padd(ascii("xlink:href"), sXML_CDATA,
3883 (hconv(kstr2hstr((uchar *) urltounix(hbox->picinfo.picun.path).c_str()).c_str())));
3884 #endif
3885 padd(ascii("xlink:type"), sXML_CDATA, ascii("simple"));
3886 padd(ascii("xlink:show"), sXML_CDATA, ascii("embed"));
3887 padd(ascii("xlink:actuate"), sXML_CDATA, ascii("onLoad"));
3890 if( hbox->pictype == PICTYPE_OLE )
3891 rstartEl(ascii("draw:object-ole"), rList);
3892 else
3893 rstartEl(ascii("draw:image"), rList);
3894 pList->clear();
3895 if (hbox->pictype == PICTYPE_EMBED || hbox->pictype == PICTYPE_OLE)
3897 rstartEl(ascii("office:binary-data"), rList);
3898 pList->clear();
3899 if( hbox->pictype == PICTYPE_EMBED ){
3900 EmPicture *emp = hwpfile.GetEmPicture(hbox);
3901 if( emp )
3903 boost::shared_ptr<char> pStr(base64_encode_string( emp->data, emp->size ), Free<char>());
3904 rchars(ascii(pStr.get()));
3907 else{
3908 if( hwpfile.oledata ){
3909 #ifdef WIN32
3910 LPSTORAGE srcsto;
3911 LPUNKNOWN pObj;
3912 wchar_t pathname[200];
3914 MultiByteToWideChar(CP_ACP, 0, hbox->picinfo.picole.embname, -1, pathname, 200);
3915 int rc = hwpfile.oledata->pis->OpenStorage(pathname, 0,
3916 STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, NULL, 0, &srcsto);
3917 if (rc != S_OK) {
3918 rchars(ascii(""));
3920 else{
3921 rc = OleLoad(srcsto, IID_IUnknown, NULL, (LPVOID*)&pObj);
3922 if( rc != S_OK ){
3923 srcsto->Release();
3924 rchars(ascii(""));
3926 else{
3927 boost::shared_ptr<char> pStr(base64_encode_string( (uchar *)pObj, strlen((char *)pObj)), Free<char>());
3928 rchars(ascii(pStr.get()));
3929 pObj->Release();
3930 srcsto->Release();
3933 #else
3934 rchars(ascii(""));
3935 #endif
3938 rendEl(ascii("office:binary-data"));
3940 if( hbox->pictype == PICTYPE_OLE )
3941 rendEl(ascii("draw:object-ole"));
3942 else
3943 rendEl(ascii("draw:image"));
3944 if( hbox->ishyper )
3946 rendEl(ascii("draw:a"));
3948 if( hbox->style.cap_len > 0 )
3950 rendEl( ascii("text:p"));
3951 if( !(hbox->cap_pos % 2)) /* 캡션이 아래쪽에 위치하면, */
3953 parsePara(hbox->caption.front());
3955 rendEl( ascii("draw:text-box"));
3957 break;
3959 case PICTYPE_DRAW:
3960 if( hbox->picinfo.picdraw.zorder > 0 )
3961 padd(ascii("draw:z-index"), sXML_CDATA,
3962 ascii(Int2Str( hbox->picinfo.picdraw.zorder + 10000, "%d", buf)));
3963 makePictureDRAW( (HWPDrawingObject *) hbox->picinfo.picdraw.hdo, hbox);
3964 break;
3965 case PICTYPE_UNKNOWN:
3966 break;
3971 #define DBL(x) ((x) * (x))
3972 void HwpReader::makePictureDRAW(HWPDrawingObject *drawobj, Picture * hbox)
3974 int x = hbox->pgx;
3975 int y = hbox->pgy;
3976 int a, b;
3977 sal_Bool bIsRotate = sal_False;
3979 while (drawobj)
3981 padd(ascii("draw:style-name"), sXML_CDATA,
3982 ascii(Int2Str(drawobj->index, "Draw%d", buf)));
3983 a = 0; b = 0;
3985 switch (hbox->style.anchor_type)
3987 case CHAR_ANCHOR:
3988 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3989 break;
3990 case PARA_ANCHOR:
3991 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
3992 break;
3993 case PAGE_ANCHOR:
3994 case PAPER_ANCHOR:
3996 HWPInfo *hwpinfo = hwpfile.GetHWPInfo();
3997 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("page"));
3998 padd(ascii("text:anchor-page-number"), sXML_CDATA,
3999 ascii(Int2Str(hbox->pgno +1, "%d", buf)));
4000 a = hwpinfo->paper.left_margin;
4001 b = hwpinfo->paper.top_margin + hwpinfo->paper.header_length;
4002 break;
4006 if (drawobj->type == HWPDO_CONTAINER)
4008 rstartEl(ascii("draw:g"), rList);
4009 pList->clear();
4010 makePictureDRAW(drawobj->child, hbox);
4011 rendEl(ascii("draw:g"));
4013 else
4015 bIsRotate = sal_False;
4016 if( (drawobj->property.flag & HWPDO_FLAG_ROTATION) &&
4017 (drawobj->property.parall.pt[0].y != drawobj->property.parall.pt[1].y) &&
4018 //(drawobj->type == HWPDO_RECT || drawobj->type == HWPDO_ADVANCED_ELLIPSE || drawobj->type == HWPDO_ADVANCED_ARC )
4019 (drawobj->type == HWPDO_RECT || drawobj->type == HWPDO_ADVANCED_ELLIPSE )
4023 int i;
4024 ZZParall *pal = &drawobj->property.parall;
4026 ZZPoint pt[3], r_pt[3];
4027 for(i = 0 ; i < 3 ; i++ ){
4028 pt[i].x = pal->pt[i].x - drawobj->property.rot_originx;
4029 /* 물리좌표계로 변환 */
4030 pt[i].y = -(pal->pt[i].y - drawobj->property.rot_originy);
4033 double rotate, skewX ;
4035 /* 2 - 회전각 계산 */
4036 if( pt[1].x == pt[0].x ){
4037 if( pt[1].y > pt[0].y )
4038 rotate = PI/2;
4039 else
4040 rotate = -(PI/2);
4042 else
4043 rotate = atan((double)( pt[1].y - pt[0].y )/(pt[1].x - pt[0].x ));
4044 if( pt[1].x < pt[0].x )
4045 rotate += PI;
4047 for( i = 0 ; i < 3 ; i++){
4048 r_pt[i].x = (int)(pt[i].x * cos(-(rotate)) - pt[i].y * sin(-(rotate)));
4049 r_pt[i].y = (int)(pt[i].y * cos(-(rotate)) + pt[i].x * sin(-(rotate)));
4052 /* 4 - 휜각 계산 */
4053 if( r_pt[2].y == r_pt[1].y )
4054 skewX = 0;
4055 else
4056 skewX = atan((double)(r_pt[2].x - r_pt[1].x )/( r_pt[2].y - r_pt[1].y ));
4057 if( skewX >= PI/2 )
4058 skewX -= PI;
4059 if( skewX <= -PI/2 )
4060 skewX += PI;
4062 OUString trans;
4063 if( skewX != 0.0 && rotate != 0.0 ){
4064 trans = ascii("skewX (") + Double2Str(skewX)
4065 + ascii(") rotate (") + Double2Str(rotate)
4066 + ascii(") translate (") + Double2Str(WTMM(x + a + drawobj->offset2.x + pal->pt[0].x)) + ascii("mm ")
4067 + Double2Str(WTMM(y + b + drawobj->offset2.y + pal->pt[0].y)) + ascii("mm)");
4068 bIsRotate = sal_True;
4070 else if( skewX != 0.0 ){
4071 trans = ascii("skewX (") + Double2Str(skewX)
4072 + ascii(") translate (") + Double2Str(WTMM(x + a + drawobj->offset2.x + pal->pt[0].x)) + ascii("mm ")
4073 + Double2Str(WTMM(y + b + drawobj->offset2.y + pal->pt[0].y)) + ascii("mm)");
4074 bIsRotate = sal_True;
4076 else if( rotate != 0.0 ){
4077 trans = ascii("rotate (") + Double2Str(rotate)
4078 + ascii(") translate (") + Double2Str(WTMM(x + a + drawobj->offset2.x + pal->pt[0].x)) + ascii("mm ")
4079 + Double2Str(WTMM(y + b + drawobj->offset2.y + pal->pt[0].y)) + ascii("mm)");
4080 bIsRotate = sal_True;
4082 if( bIsRotate == sal_True ){
4083 drawobj->extent.w = (int)sqrt(double(DBL(pt[1].x-pt[0].x)+DBL(pt[1].y-pt[0].y)));
4084 drawobj->extent.h = (int)sqrt(double(DBL(pt[2].x-pt[1].x)+DBL(pt[2].y-pt[1].y)));
4085 padd(ascii("draw:transform"), sXML_CDATA, trans);
4088 switch (drawobj->type)
4090 case HWPDO_LINE: /* 선 - 시작좌표, 끝좌표. */
4091 if( drawobj->u.line_arc.flip & 0x01 )
4093 padd(ascii("svg:x1"), sXML_CDATA,
4094 Double2Str (WTMM(x + a + drawobj->offset2.x + drawobj->extent.w)) + ascii("mm"));
4095 padd(ascii("svg:x2"), sXML_CDATA,
4096 Double2Str (WTMM( x + a + drawobj->offset2.x )) + ascii("mm"));
4098 else
4100 padd(ascii("svg:x1"), sXML_CDATA,
4101 Double2Str (WTMM( x + a + drawobj->offset2.x )) + ascii("mm"));
4102 padd(ascii("svg:x2"), sXML_CDATA,
4103 Double2Str (WTMM(x + a + drawobj->offset2.x + drawobj->extent.w)) + ascii("mm"));
4105 if( drawobj->u.line_arc.flip & 0x02 )
4107 padd(ascii("svg:y1"), sXML_CDATA,
4108 Double2Str (WTMM( y + b + drawobj->offset2.y + drawobj->extent.h ) ) + ascii("mm"));
4109 padd(ascii("svg:y2"), sXML_CDATA,
4110 Double2Str (WTMM( y + b + drawobj->offset2.y )) + ascii("mm"));
4112 else
4114 padd(ascii("svg:y1"), sXML_CDATA,
4115 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4116 padd(ascii("svg:y2"), sXML_CDATA,
4117 Double2Str (WTMM(y + b + drawobj->offset2.y + drawobj->extent.h)) + ascii("mm"));
4120 rstartEl(ascii("draw:line"), rList);
4121 pList->clear();
4122 rendEl(ascii("draw:line"));
4123 break;
4124 case HWPDO_RECT: /* 사각형 - 시작위치, 가로/세로 */
4125 if( !bIsRotate )
4127 padd(ascii("svg:x"), sXML_CDATA,
4128 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4129 padd(ascii("svg:y"), sXML_CDATA,
4130 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4132 padd(ascii("svg:width"), sXML_CDATA,
4133 Double2Str (WTMM( drawobj->extent.w )) + ascii("mm"));
4134 padd(ascii("svg:height"), sXML_CDATA,
4135 Double2Str (WTMM( drawobj->extent.h )) + ascii("mm"));
4136 if( drawobj->property.flag & 0x01 )
4138 int value = drawobj->extent.w < drawobj->extent.h ?
4139 drawobj->extent.w : drawobj->extent.h ;
4140 padd(ascii("draw:corner-radius"), sXML_CDATA,
4141 Double2Str (WTMM( value/10 )) + ascii("mm"));
4143 else if( drawobj->property.flag & 0x04 )
4145 int value = drawobj->extent.w < drawobj->extent.h ?
4146 drawobj->extent.w : drawobj->extent.h ;
4147 padd(ascii("draw:corner-radius"), sXML_CDATA,
4148 Double2Str (WTMM( value / 2)) + ascii("mm"));
4151 rstartEl(ascii("draw:rect"), rList);
4152 pList->clear();
4153 if( (drawobj->property.flag & HWPDO_FLAG_AS_TEXTBOX) &&
4154 drawobj->property.pPara ) // As Textbox
4156 HWPPara *pPara = drawobj->property.pPara;
4157 //parsePara(pPara);
4158 while(pPara)
4160 make_text_p1( pPara );
4161 pPara = pPara->Next();
4164 rendEl(ascii("draw:rect"));
4165 break;
4166 case HWPDO_ELLIPSE: /* 타원 - 시작위치, 가로/세로 */
4167 case HWPDO_ADVANCED_ELLIPSE: /* 변형된 타원 */
4169 if( !bIsRotate )
4171 padd(ascii("svg:x"), sXML_CDATA,
4172 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4173 padd(ascii("svg:y"), sXML_CDATA,
4174 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4177 padd(ascii("svg:width"), sXML_CDATA,
4178 Double2Str (WTMM( drawobj->extent.w )) + ascii("mm"));
4179 padd(ascii("svg:height"), sXML_CDATA,
4180 Double2Str (WTMM( drawobj->extent.h )) + ascii("mm"));
4181 if( drawobj->type == HWPDO_ADVANCED_ELLIPSE ){
4182 if( drawobj->u.arc.radial[0].x != drawobj->u.arc.radial[1].x
4183 || drawobj->u.arc.radial[0].y != drawobj->u.arc.radial[1].y ){
4184 int Cx,Cy;
4185 Cx = ( drawobj->offset2.x + drawobj->extent.w ) / 2;
4186 Cy = ( drawobj->offset2.y + drawobj->extent.h ) / 2;
4188 double start_angle, end_angle;
4189 start_angle = calcAngle( Cx, Cy, drawobj->u.arc.radial[0].x, drawobj->u.arc.radial[0].y );
4190 end_angle = calcAngle( Cx, Cy, drawobj->u.arc.radial[1].x, drawobj->u.arc.radial[1].y );
4191 if( drawobj->property.fill_color < 0xffffff )
4192 padd(ascii("draw:kind"), sXML_CDATA, ascii("section"));
4193 else
4194 padd(ascii("draw:kind"), sXML_CDATA, ascii("arc"));
4195 padd(ascii("draw:start-angle"), sXML_CDATA, Double2Str(start_angle ));
4196 padd(ascii("draw:end-angle"), sXML_CDATA, Double2Str(end_angle));
4199 rstartEl(ascii("draw:ellipse"), rList);
4200 pList->clear();
4201 if( drawobj->property.flag >> 19 & 0x01 &&
4202 drawobj->property.pPara ) // As Textbox
4204 HWPPara *pPara = drawobj->property.pPara;
4205 //parsePara(pPara);
4206 while(pPara)
4208 make_text_p1( pPara );
4209 pPara = pPara->Next();
4212 rendEl(ascii("draw:ellipse"));
4213 break;
4216 case HWPDO_ARC: /* 호 */
4217 case HWPDO_ADVANCED_ARC:
4219 /* 호일경우에, 스타오피스는 전체 타원의 크기를 사이즈로 한다. */
4220 uint flip = drawobj->u.line_arc.flip;
4221 if( !bIsRotate )
4223 if( ( flip == 0 || flip == 2 ) && drawobj->type == HWPDO_ARC)
4224 padd(ascii("svg:x"), sXML_CDATA,
4225 Double2Str (WTMM( x + a + drawobj->offset2.x - drawobj->extent.w)) + ascii("mm"));
4226 else
4227 padd(ascii("svg:x"), sXML_CDATA,
4228 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4229 if( ( flip == 0 || flip == 1 ) && drawobj->type == HWPDO_ARC)
4230 padd(ascii("svg:y"), sXML_CDATA,
4231 Double2Str (WTMM( y + b + drawobj->offset2.y - drawobj->extent.h)) + ascii("mm"));
4232 else
4233 padd(ascii("svg:y"), sXML_CDATA,
4234 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4237 padd(ascii("svg:width"), sXML_CDATA,
4238 Double2Str (WTMM( drawobj->extent.w * 2)) + ascii("mm"));
4239 padd(ascii("svg:height"), sXML_CDATA,
4240 Double2Str (WTMM( drawobj->extent.h * 2)) + ascii("mm"));
4241 if( drawobj->property.flag & HWPDO_FLAG_DRAW_PIE ||
4242 drawobj->property.fill_color < 0xffffff )
4243 padd(ascii("draw:kind"), sXML_CDATA, ascii("section"));
4244 else
4245 padd(ascii("draw:kind"), sXML_CDATA, ascii("arc"));
4247 if( drawobj->type == HWPDO_ADVANCED_ARC ){
4248 double start_angle, end_angle;
4249 ZZParall *pal = &drawobj->property.parall;
4251 if( pal->pt[1].x == pal->pt[0].x ){
4252 if( pal->pt[0].y < pal->pt[1].y )
4253 start_angle = 1.5 * PI;
4254 else
4255 start_angle = 0.5 * PI;
4257 else{
4258 start_angle = atan((double)( pal->pt[0].y - pal->pt[1].y )/( pal->pt[1].x - pal->pt[0].x ));
4259 if( pal->pt[1].x < pal->pt[0].x )
4260 start_angle += PI;
4262 if( pal->pt[1].x == pal->pt[2].x ){
4263 if( pal->pt[2].y < pal->pt[1].y )
4264 end_angle = 1.5 * PI;
4265 else
4266 end_angle = 0.5 * PI;
4268 else{
4269 end_angle = atan((double)( pal->pt[2].y - pal->pt[1].y )/( pal->pt[1].x - pal->pt[2].x ));
4270 if( pal->pt[1].x < pal->pt[2].x )
4271 end_angle += PI;
4274 if( start_angle >= 2 * PI )
4275 start_angle -= 2 * PI;
4276 if( end_angle >= 2 * PI )
4277 end_angle -= 2 * PI;
4278 if( ( start_angle > end_angle ) && (start_angle - end_angle < PI )){
4279 double tmp_angle = start_angle;
4280 start_angle = end_angle;
4281 end_angle = tmp_angle;
4283 padd(ascii("draw:start-angle"), sXML_CDATA, Double2Str(start_angle * 180. / PI));
4284 padd(ascii("draw:end-angle"), sXML_CDATA, Double2Str(end_angle * 180. / PI));
4287 else{
4288 if( drawobj->u.line_arc.flip == 0 )
4290 padd(ascii("draw:start-angle"), sXML_CDATA, ascii("270"));
4291 padd(ascii("draw:end-angle"), sXML_CDATA, ascii("0"));
4293 else if( drawobj->u.line_arc.flip == 1 )
4295 padd(ascii("draw:start-angle"), sXML_CDATA, ascii("180"));
4296 padd(ascii("draw:end-angle"), sXML_CDATA, ascii("270"));
4298 else if( drawobj->u.line_arc.flip == 2 )
4300 padd(ascii("draw:start-angle"), sXML_CDATA, ascii("0"));
4301 padd(ascii("draw:end-angle"), sXML_CDATA, ascii("90"));
4303 else
4305 padd(ascii("draw:start-angle"), sXML_CDATA, ascii("90"));
4306 padd(ascii("draw:end-angle"), sXML_CDATA, ascii("180"));
4309 rstartEl(ascii("draw:ellipse"), rList);
4310 pList->clear();
4311 if( drawobj->property.flag >> 19 & 0x01 &&
4312 drawobj->property.pPara ) // As Textbox
4314 HWPPara *pPara = drawobj->property.pPara;
4315 //parsePara(pPara);
4316 while(pPara)
4318 make_text_p1( pPara );
4319 pPara = pPara->Next();
4322 rendEl(ascii("draw:ellipse"));
4323 break;
4326 case HWPDO_CURVE: /* 곡선 : 다각형으로 변환. */
4328 sal_Bool bIsNatural = sal_True;
4329 if( drawobj->property.flag >> 5 & 0x01){
4330 bIsNatural = sal_False;
4332 if( !bIsRotate )
4334 padd(ascii("svg:x"), sXML_CDATA,
4335 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4336 padd(ascii("svg:y"), sXML_CDATA,
4337 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4339 padd(ascii("svg:width"), sXML_CDATA,
4340 Double2Str (WTMM( drawobj->extent.w )) + ascii("mm"));
4341 padd(ascii("svg:height"), sXML_CDATA,
4342 Double2Str (WTMM( drawobj->extent.h )) + ascii("mm"));
4343 sprintf(buf, "0 0 %d %d", WTSM(drawobj->extent.w) , WTSM(drawobj->extent.h) );
4344 padd(ascii("svg:viewBox"), sXML_CDATA, ascii(buf) );
4346 OUString oustr;
4348 if ((drawobj->u.freeform.npt > 2) &&
4349 (static_cast<size_t>(drawobj->u.freeform.npt) <
4350 ((::std::numeric_limits<int>::max)() / sizeof(double))))
4352 int n, i;
4353 n = drawobj->u.freeform.npt;
4355 double *xarr = new double[n+1];
4356 double *yarr = new double[n+1];
4357 double *tarr = new double[n+1];
4359 double *xb = 0L;
4360 double *yb = 0L;
4362 double *carr = 0L;
4363 double *darr = 0L;
4366 for( i = 0 ; i < n ; i++ ){
4367 xarr[i] = drawobj->u.freeform.pt[i].x;
4368 yarr[i] = drawobj->u.freeform.pt[i].y;
4369 tarr[i] = i;
4371 xarr[n] = xarr[0];
4372 yarr[n] = yarr[0];
4373 tarr[n] = n;
4375 if( bIsNatural == sal_False ){
4376 PeriodicSpline(n, tarr, xarr, xb, carr, darr);
4377 // prevent memory leak
4378 delete[] carr;
4379 carr = 0;
4380 delete[] darr;
4381 darr = 0;
4382 PeriodicSpline(n, tarr, yarr, yb, carr, darr);
4384 else{
4385 NaturalSpline(n, tarr, xarr, xb, carr, darr);
4386 // prevent memory leak
4387 delete[] carr;
4388 carr = 0;
4389 delete[] darr;
4390 darr = 0;
4391 NaturalSpline(n, tarr, yarr, yb, carr, darr);
4394 sprintf(buf, "M%d %dC%d %d", WTSM((int)xarr[0]), WTSM((int)yarr[0]),
4395 WTSM((int)(xarr[0] + xb[0]/3)), WTSM((int)(yarr[0] + yb[0]/3)) );
4396 oustr += ascii(buf);
4398 for( i = 1 ; i < n ; i++ ){
4399 if( i == n -1 ){
4400 sprintf(buf, " %d %d %d %dz",
4401 WTSM((int)(xarr[i] - xb[i]/3)), WTSM((int)(yarr[i] - yb[i]/3)),
4402 WTSM((int)xarr[i]), WTSM((int)yarr[i]) );
4404 else{
4405 sprintf(buf, " %d %d %d %d %d %d",
4406 WTSM((int)(xarr[i] - xb[i]/3)), WTSM((int)(yarr[i] - yb[i]/3)),
4407 WTSM((int)xarr[i]), WTSM((int)yarr[i]),
4408 WTSM((int)xarr[i] + xb[i]/3), WTSM((int)(yarr[i] + yb[i]/3)) );
4411 oustr += ascii(buf);
4413 delete[] tarr;
4414 delete[] xarr;
4415 delete[] yarr;
4417 delete[] xb;
4418 delete[] yb;
4420 delete[] carr;
4421 delete[] darr;
4424 padd(ascii("svg:d"), sXML_CDATA, oustr);
4426 rstartEl(ascii("draw:path"), rList);
4427 pList->clear();
4428 // As Textbox
4429 if( drawobj->property.flag >> 19 & 0x01 && drawobj->property.pPara )
4431 HWPPara *pPara = drawobj->property.pPara;
4432 while(pPara)
4434 make_text_p1( pPara );
4435 pPara = pPara->Next();
4438 rendEl(ascii("draw:path"));
4439 break;
4441 case HWPDO_CLOSED_FREEFORM:
4442 case HWPDO_FREEFORM: /* 다각형 */
4444 bool bIsPolygon = false;
4446 padd(ascii("svg:x"), sXML_CDATA,
4447 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4448 padd(ascii("svg:y"), sXML_CDATA,
4449 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4451 padd(ascii("svg:width"), sXML_CDATA,
4452 Double2Str (WTMM( drawobj->extent.w )) + ascii("mm"));
4453 padd(ascii("svg:height"), sXML_CDATA,
4454 Double2Str (WTMM( drawobj->extent.h )) + ascii("mm"));
4456 sprintf(buf, "0 0 %d %d", WTSM(drawobj->extent.w), WTSM(drawobj->extent.h));
4457 padd(ascii("svg:viewBox"), sXML_CDATA, ascii(buf) );
4459 OUString oustr;
4461 if (drawobj->u.freeform.npt > 0)
4463 sprintf(buf, "%d,%d", WTSM(drawobj->u.freeform.pt[0].x), WTSM(drawobj->u.freeform.pt[0].y));
4464 oustr += ascii(buf);
4465 int i;
4466 for (i = 1; i < drawobj->u.freeform.npt ; i++)
4468 sprintf(buf, " %d,%d",
4469 WTSM(drawobj->u.freeform.pt[i].x),
4470 WTSM(drawobj->u.freeform.pt[i].y));
4471 oustr += ascii(buf);
4473 if( drawobj->u.freeform.pt[0].x == drawobj->u.freeform.pt[i-1].x &&
4474 drawobj->u.freeform.pt[0].y == drawobj->u.freeform.pt[i-1].y )
4476 bIsPolygon = true;
4479 padd(ascii("draw:points"), sXML_CDATA, oustr);
4481 if( drawobj->property.fill_color <= 0xffffff ||
4482 drawobj->property.pattern_type != 0)
4484 bIsPolygon = true;
4487 if(bIsPolygon)
4489 rstartEl(ascii("draw:polygon"), rList);
4490 pList->clear();
4491 if( drawobj->property.flag >> 19 & 0x01 &&
4492 // As Textbox
4493 drawobj->property.pPara )
4495 HWPPara *pPara = drawobj->property.pPara;
4496 // parsePara(pPara);
4497 while(pPara)
4499 make_text_p1( pPara );
4500 pPara = pPara->Next();
4503 rendEl(ascii("draw:polygon"));
4505 else
4507 rstartEl(ascii("draw:polyline"), rList);
4508 pList->clear();
4509 if( drawobj->property.flag >> 19 & 0x01 &&
4510 // As Textbox
4511 drawobj->property.pPara )
4513 HWPPara *pPara = drawobj->property.pPara;
4514 //parsePara(pPara);
4515 while(pPara)
4517 make_text_p1( pPara );
4518 pPara = pPara->Next();
4521 rendEl(ascii("draw:polyline"));
4523 break;
4525 case HWPDO_TEXTBOX:
4526 if( !bIsRotate )
4528 padd(ascii("svg:x"), sXML_CDATA,
4529 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4530 padd(ascii("svg:y"), sXML_CDATA,
4531 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4533 padd(ascii("svg:width"), sXML_CDATA,
4534 Double2Str (WTMM( drawobj->extent.w )) + ascii("mm"));
4535 padd(ascii("svg:height"), sXML_CDATA,
4536 Double2Str (WTMM( drawobj->extent.h )) + ascii("mm"));
4537 if( drawobj->property.flag & 0x01 )
4539 int value = drawobj->extent.w < drawobj->extent.h ?
4540 drawobj->extent.w : drawobj->extent.h ;
4541 padd(ascii("draw:corner-radius"), sXML_CDATA,
4542 Double2Str (WTMM( value/10 )) + ascii("mm"));
4544 else if( drawobj->property.flag & 0x04 )
4546 int value = drawobj->extent.w < drawobj->extent.h ?
4547 drawobj->extent.w : drawobj->extent.h ;
4548 padd(ascii("draw:corner-radius"), sXML_CDATA,
4549 Double2Str (WTMM( value / 2)) + ascii("mm"));
4552 rstartEl(ascii("draw:text-box"), rList);
4553 pList->clear();
4555 HWPPara *pPara = drawobj->u.textbox.h;
4556 //parsePara(pPara);
4557 while(pPara)
4559 make_text_p1( pPara );
4560 pPara = pPara->Next();
4563 rendEl(ascii("draw:text-box"));
4564 break;
4567 pList->clear();
4568 drawobj = drawobj->next;
4576 void HwpReader::makeLine(Line * )
4578 padd(ascii("text:style-name"), sXML_CDATA, ascii("Horizontal Line"));
4579 rstartEl( ascii("text:p"), rList);
4580 pList->clear();
4585 * 입력-주석-숨은설명 : 사용자에게 숨은 설명을 보여준다.
4586 * 문단이 포함될 수 있으나, 단지 문자열만 뽑아내어 파싱한다.
4588 void HwpReader::makeHidden(Hidden * hbox)
4590 hchar_string str;
4591 int res;
4592 hchar dest[3];
4594 padd(ascii("text:condition"), sXML_CDATA, ascii(""));
4595 padd(ascii("text:string-value"), sXML_CDATA, ascii(""));
4596 rstartEl(ascii("text:hidden-text"), rList);
4597 pList->clear();
4598 HWPPara *para = hbox->plist.front();
4600 while (para)
4602 for (int n = 0; n < para->nch && para->hhstr[n]->hh;
4603 n += para->hhstr[n]->WSize())
4605 res = hcharconv(para->hhstr[n]->hh, dest, UNICODE);
4606 for( int j = 0 ; j < res ; j++ )
4608 str.push_back(dest[j]);
4611 para = para->Next();
4613 makeChars(str);
4614 rendEl(ascii("text:hidden-text"));
4619 * 각주는 text:footnote, 미주는 text:endnote로 변환
4621 void HwpReader::makeFootnote(Footnote * hbox)
4623 if (hbox->type)
4625 padd(ascii("text:id"), sXML_CDATA,
4626 ascii(Int2Str(hbox->number, "edn%d", buf)));
4627 rstartEl(ascii("text:endnote"), rList);
4628 pList->clear();
4629 padd(ascii("text:label"), sXML_CDATA,
4630 ascii(Int2Str(hbox->number, "%d", buf)));
4631 rstartEl(ascii("text:endnote-citation"), rList);
4632 pList->clear();
4633 rchars(ascii(Int2Str(hbox->number, "%d", buf)));
4634 rendEl(ascii("text:endnote-citation"));
4635 rstartEl(ascii("text:endnote-body"), rList);
4636 parsePara(hbox->plist.front());
4637 rendEl(ascii("text:endnote-body"));
4638 rendEl(ascii("text:endnote"));
4640 else
4642 padd(ascii("text:id"), sXML_CDATA,
4643 ascii(Int2Str(hbox->number, "ftn%d", buf)));
4644 rstartEl(ascii("text:footnote"), rList);
4645 pList->clear();
4646 padd(ascii("text:label"), sXML_CDATA,
4647 ascii(Int2Str(hbox->number, "%d", buf)));
4648 rstartEl(ascii("text:footnote-citation"), rList);
4649 pList->clear();
4650 rchars(ascii(Int2Str(hbox->number, "%d", buf)));
4651 rendEl(ascii("text:footnote-citation"));
4652 rstartEl(ascii("text:footnote-body"), rList);
4653 parsePara(hbox->plist.front());
4654 rendEl(ascii("text:footnote-body"));
4655 rendEl(ascii("text:footnote"));
4661 * page/footnote/endnote/picture/table/formula number
4663 void HwpReader::makeAutoNum(AutoNum * hbox)
4665 switch (hbox->type)
4667 case PGNUM_AUTO:
4668 rstartEl(ascii("text:page-number"), rList);
4669 rchars(ascii(Int2Str(hbox->number, "%d", buf)));
4670 rendEl(ascii("text:page-number"));
4671 break;
4672 case FNNUM_AUTO:
4673 break;
4674 case ENNUM_AUTO:
4675 break;
4676 case EQUNUM_AUTO:
4677 case PICNUM_AUTO:
4678 padd(ascii("text:ref-name"),sXML_CDATA,
4679 ascii(Int2Str(hbox->number, "refIllustration%d", buf)));
4680 padd(ascii("text:name"),sXML_CDATA, ascii("Illustration"));
4681 padd(ascii("style:num-format"),sXML_CDATA, ascii("1"));
4682 rstartEl(ascii("text:sequence"), rList);
4683 rchars(ascii(Int2Str(hbox->number, "%d", buf)));
4684 rendEl(ascii("text:sequence"));
4685 break;
4686 case TBLNUM_AUTO:
4687 padd(ascii("text:ref-name"),sXML_CDATA,
4688 ascii(Int2Str(hbox->number, "refTable%d", buf)));
4689 padd(ascii("text:name"),sXML_CDATA, ascii("Table"));
4690 padd(ascii("style:num-format"),sXML_CDATA, ascii("1"));
4691 rstartEl(ascii("text:sequence"), rList);
4692 rchars(ascii(Int2Str(hbox->number, "%d", buf)));
4693 rendEl(ascii("text:sequence"));
4694 break;
4699 void HwpReader::makeShowPageNum()
4701 ShowPageNum *hbox = d->pPn;
4702 int nPos = 0;
4703 if( hbox->where == 1 || hbox->where == 4 )
4704 nPos = 1;
4705 else if( hbox->where == 2 || hbox->where == 5 )
4706 nPos = 2;
4707 else if( hbox->where == 3 || hbox->where == 6 )
4708 nPos = 3;
4709 else /* 이 경우가 존재하면 안된다. */
4711 if( d->nPnPos == 1 )
4712 nPos = 1;
4713 else if( d->nPnPos == 3 )
4714 nPos = 3;
4717 padd(ascii("draw:style-name"), sXML_CDATA,
4718 ascii(Int2Str(nPos, "PNBox%d", buf)));
4719 padd(ascii("draw:name"), sXML_CDATA,
4720 ascii(Int2Str(nPos, "PageNumber%d", buf)));
4721 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
4722 padd(ascii("svg:y"), sXML_CDATA, ascii("0cm"));
4723 padd(ascii("svg:width"), sXML_CDATA, ascii("2.0cm"));
4724 padd(ascii("fo:min-height"), sXML_CDATA, ascii("0.5cm"));
4725 rstartEl(ascii("draw:text-box"), rList);
4726 pList->clear();
4728 padd(ascii("text:style-name"), sXML_CDATA,
4729 ascii(Int2Str(nPos, "PNPara%d", buf)));
4730 rstartEl(ascii("text:p"), rList);
4731 pList->clear();
4732 if( hbox->shape > 2 )
4733 rchars(ascii("- "));
4734 if( hbox->shape % 3 == 0 )
4735 padd(ascii("style:num-format"), sXML_CDATA, ascii("1"));
4736 else if( hbox->shape % 3 == 1 )
4737 padd(ascii("style:num-format"), sXML_CDATA, ascii("I"));
4738 else
4739 padd(ascii("style:num-format"), sXML_CDATA, ascii("i"));
4740 padd(ascii("text:select-page"), sXML_CDATA, ascii("current"));
4741 rstartEl(ascii("text:page-number"), rList);
4742 pList->clear();
4743 rchars(ascii("2"));
4744 rendEl(ascii("text:page-number"));
4745 if( hbox->shape > 2 )
4746 rchars(ascii(" -"));
4747 rendEl(ascii("text:p"));
4748 rendEl(ascii("draw:text-box"));
4753 * mail merge operation using hwp addressbook and hwp data form.
4754 * not support operation in OO writer.
4756 void HwpReader::makeMailMerge(MailMerge * hbox)
4758 hchar_string const boxstr = hbox->GetString();
4759 rchars((hconv(boxstr.c_str())));
4764 * Make heading contents file using toc marks
4765 * not support operation.
4767 void HwpReader::makeTocMark(TocMark * ) /*hbox */
4773 * Make search character table in automatic
4774 * not support operation
4776 void HwpReader::makeIndexMark(IndexMark * ) /*hbox */
4781 void HwpReader::makeOutline(Outline * hbox)
4783 if( hbox->kind == 1 )
4784 rchars(OUString(hbox->GetUnicode().c_str()));
4788 void HwpReader::parsePara(HWPPara * para, sal_Bool bParaStart)
4791 while (para)
4793 if( para->nch == 1)
4795 if( !bParaStart )
4797 padd(ascii("text:style-name"), sXML_CDATA,
4798 ascii(getPStyleName(para->GetParaShape()->index, buf)));
4799 rstartEl( ascii("text:p"),rList);
4800 pList->clear();
4802 if( d->bFirstPara && d->bInBody )
4804 /* for HWP's Bookmark */
4805 strcpy(buf,"[문서의 처음]"); /* "Begin of Document" */
4806 padd(ascii("text:name"), sXML_CDATA, OUString(buf, strlen(buf), RTL_TEXTENCODING_UTF8));
4807 rstartEl(ascii("text:bookmark"), rList);
4808 pList->clear();
4809 rendEl(ascii("text:bookmark"));
4810 d->bFirstPara = false;
4812 if( d->bInHeader )
4814 makeShowPageNum();
4815 d->bInHeader = false;
4818 rendEl( ascii("text:p") );
4820 else
4822 if (!para->ctrlflag)
4824 if (para->contain_cshape)
4825 make_text_p1(para, bParaStart);
4826 else
4827 make_text_p0(para, bParaStart);
4829 else
4830 make_text_p3(para, bParaStart);
4832 bParaStart = false;
4833 para = para->Next();
4837 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */