Bump for 3.6-28
[LibreOffice.git] / hwpfilter / source / hwpreader.cxx
blobc726fb6fd16d9fd265ac56f42ca0ee05ce720386
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <deque>
32 #include <boost/shared_ptr.hpp>
34 #include "hwpreader.hxx"
35 #include <math.h>
37 #include <comphelper/newarray.hxx>
39 #include "formula.h"
40 #include "cspline.h"
42 extern int getRepFamilyName(const char* , char *, double &ratio);
44 #include <iostream>
45 #include <locale.h>
46 #include <sal/types.h>
47 // #i42367# prevent MS compiler from using system locale for parsing
48 #ifdef _MSC_VER
49 #pragma setlocale("C")
50 #endif
52 // To be shorten source code by realking
53 #define hconv(x) OUString(hstr2ucsstr(x).c_str())
54 #define ascii(x) OUString::createFromAscii(x)
55 #define rstartEl(x,y) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->startElement(x,y); } while(0)
56 #define rendEl(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->endElement(x); } while(0)
57 #define rchars(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->characters(x); } while(0)
58 #define padd(x,y,z) pList->addAttribute(x,y,z)
59 #define Double2Str(x) OUString::valueOf((double)(x))
60 #define WTI(x) ((double)(x) / 1800.) // unit => inch
61 #define WTMM(x) ((double)(x) / 1800. * 25.4) // unit => mm
62 #define WTSM(x) ((int)((x) / 1800. * 2540)) // unit ==> 1/100 mm
64 #define PI 3.14159265358979323846
66 // xmloff/xmlkyd.hxx
67 #define sXML_CDATA ascii("CDATA")
69 #define STARTP padd( ascii("text:style-name"), ascii("CDATA"), ascii(getPStyleName(((ParaShape *)para->GetParaShape())->index,buf))); \
70 rstartEl( ascii("text:p"),rList ); \
71 pList->clear(); \
72 pstart = true
73 #define STARTT \
74 curr = para->GetCharShape(n > 0 ? n-1 : 0)->index; \
75 padd( ascii("text:style-name"), ascii("CDATA") , ascii( getTStyleName(curr, buf) ) ); \
76 rstartEl( ascii("text:span"),rList ); \
77 pList->clear(); \
78 tstart = true
79 #define ENDP \
80 rendEl(ascii("text:p")); \
81 pstart = false
82 #define ENDT \
83 rendEl(ascii("text:span")); \
84 tstart = false
86 static hchar *field = 0L;
87 static char buf[1024];
89 namespace
92 template<typename T>
93 struct Free
95 void operator()(T* const ptr)
97 free(ptr);
103 struct HwpReaderPrivate
105 HwpReaderPrivate()
107 bFirstPara = sal_True;
108 bInBody = sal_False;
109 bInHeader = sal_False;
110 nPnPos = 0;
111 pPn = 0L;
114 sal_Bool bFirstPara;
115 sal_Bool bInBody;
116 sal_Bool bInHeader;
117 ShowPageNum *pPn;
118 int nPnPos;
121 HwpReader::HwpReader()
123 pList = new AttributeListImpl;
124 rList = (XAttributeList *) pList;
125 d = new HwpReaderPrivate;
129 HwpReader::~HwpReader()
131 rList = 0;
132 delete d;
136 sal_Bool HwpReader::filter(const Sequence< PropertyValue >& rDescriptor) throw(RuntimeException)
138 comphelper::MediaDescriptor aDescriptor(rDescriptor);
139 aDescriptor.addInputStream();
141 Reference< XInputStream > xInputStream(
142 aDescriptor[comphelper::MediaDescriptor::PROP_INPUTSTREAM()], UNO_QUERY_THROW);
144 HStream stream;
145 Sequence < sal_Int8 > aBuffer;
146 sal_Int32 nRead, nBlock = 32768, nTotal = 0;
147 while( 1 )
149 nRead = xInputStream->readBytes(aBuffer, nBlock);
150 if( nRead == 0 )
151 break;
152 stream.addData( (const byte *)aBuffer.getConstArray(), nRead );
153 nTotal += nRead;
156 if( nTotal == 0 ) return sal_False;
158 if (hwpfile.ReadHwpFile(stream))
159 return sal_False;
161 if (m_rxDocumentHandler.is())
162 m_rxDocumentHandler->startDocument();
164 padd(ascii("office:class"), sXML_CDATA, ascii("text"));
165 padd(ascii("office:version"), sXML_CDATA, ascii("0.9"));
167 padd(ascii("xmlns:office"), ascii("CDATA"), ascii("http://openoffice.org/2000/office"));
168 padd(ascii("xmlns:style"), ascii("CDATA"), ascii("http://openoffice.org/2000/style"));
169 padd(ascii("xmlns:text"), ascii("CDATA"), ascii("http://openoffice.org/2000/text"));
170 padd(ascii("xmlns:table"), ascii("CDATA"), ascii("http://openoffice.org/2000/table"));
171 padd(ascii("xmlns:draw"), ascii("CDATA"), ascii("http://openoffice.org/2000/drawing"));
172 padd(ascii("xmlns:fo"), ascii("CDATA"), ascii("http://www.w3.org/1999/XSL/Format"));
173 padd(ascii("xmlns:xlink"), ascii("CDATA"), ascii("http://www.w3.org/1999/xlink"));
174 padd(ascii("xmlns:dc"), ascii("CDATA"), ascii("http://purl.org/dc/elements/1.1/"));
175 padd(ascii("xmlns:meta"), ascii("CDATA"), ascii("http://openoffice.org/2000/meta"));
176 padd(ascii("xmlns:number"), ascii("CDATA"), ascii("http://openoffice.org/2000/datastyle"));
177 padd(ascii("xmlns:svg"), ascii("CDATA"), ascii("http://www.w3.org/2000/svg"));
178 padd(ascii("xmlns:chart"), ascii("CDATA"), ascii("http://openoffice.org/2000/chart"));
179 padd(ascii("xmlns:dr3d"), ascii("CDATA"), ascii("http://openoffice.org/2000/dr3d"));
180 padd(ascii("xmlns:math"), ascii("CDATA"), ascii("http://www.w3.org/1998/Math/MathML"));
181 padd(ascii("xmlns:form"), ascii("CDATA"), ascii("http://openoffice.org/2000/form"));
182 padd(ascii("xmlns:script"), ascii("CDATA"), ascii("http://openoffice.org/2000/script"));
184 rstartEl(ascii("office:document"), rList);
185 pList->clear();
187 makeMeta();
188 makeStyles();
189 makeAutoStyles();
190 makeMasterStyles();
191 makeBody();
193 rendEl(ascii("office:document"));
195 if (m_rxDocumentHandler.is())
196 m_rxDocumentHandler->endDocument();
197 return sal_True;
202 * make office:body
204 void HwpReader::makeBody()
206 rstartEl(ascii("office:body"), rList);
207 makeTextDecls();
208 HWPPara *hwppara = hwpfile.GetFirstPara();
209 d->bInBody = sal_True;
210 parsePara(hwppara);
211 rendEl(ascii("office:body"));
212 d->bInBody = sal_False;
217 * make text decls
219 void HwpReader::makeTextDecls()
221 rstartEl(ascii("text:sequence-decls"), rList);
222 padd(ascii("text:display-outline-level"), sXML_CDATA, ascii("0"));
223 padd(ascii("text:name"), sXML_CDATA, ascii("Illustration"));
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("Table"));
229 rstartEl(ascii("text:sequence-decl"), rList);
230 pList->clear();
231 rendEl(ascii("text:sequence-decl"));
232 padd(ascii("text:display-outline-level"), sXML_CDATA, ascii("0"));
233 padd(ascii("text:name"), sXML_CDATA, ascii("Text"));
234 rstartEl(ascii("text:sequence-decl"), rList);
235 pList->clear();
236 rendEl(ascii("text:sequence-decl"));
237 padd(ascii("text:display-outline-level"), sXML_CDATA, ascii("0"));
238 padd(ascii("text:name"), sXML_CDATA, ascii("Drawing"));
239 rstartEl(ascii("text:sequence-decl"), rList);
240 pList->clear();
241 rendEl(ascii("text:sequence-decl"));
242 rendEl(ascii("text:sequence-decls"));
246 #define ISNUMBER(x) ( (x) <= 0x39 && (x) >= 0x30 )
248 * make office:meta
249 * Completed
251 void HwpReader::makeMeta()
253 HWPInfo *hwpinfo = hwpfile.GetHWPInfo();
255 rstartEl(ascii("office:meta"), rList);
257 if (hwpinfo->summary.title[0])
259 rstartEl(ascii("dc:title"), rList);
260 rchars((hconv(hwpinfo->summary.title)));
261 rendEl(ascii("dc:title"));
264 if (hwpinfo->summary.subject[0])
266 rstartEl(ascii("dc:subject"), rList);
267 rchars((hconv(hwpinfo->summary.subject)));
268 rendEl(ascii("dc:subject"));
271 if (hwpinfo->summary.author[0])
273 rstartEl(ascii("meta:initial-creator"), rList);
274 rchars((hconv(hwpinfo->summary.author)));
275 rendEl(ascii("meta:initial-creator"));
278 if (hwpinfo->summary.date[0])
280 unsigned short *pDate = hwpinfo->summary.date;
281 int year,month,day,hour,minute;
282 int gab = 0;
283 if( ISNUMBER( pDate[0] ) && ISNUMBER( pDate[1] ) &&
284 ISNUMBER( pDate[2] ) && ISNUMBER( pDate[3] ))
286 year = (pDate[0]-0x30) * 1000 + (pDate[1]-0x30) * 100 +
287 (pDate[2]-0x30) * 10 + (pDate[3]-0x30);
289 else {
290 year = 0;
292 if( ISNUMBER( pDate[6] ))
294 if( ISNUMBER( pDate[7] ) )
295 month = (pDate[6] - 0x30) * 10 + (pDate[6+ ++gab]-0x30);
296 else
297 month = (pDate[6] - 0x30);
299 else {
300 month = 0;
302 if( ISNUMBER( pDate[9 + gab] ) )
304 if( ISNUMBER( pDate[10 + gab])) {
305 day = ( pDate[9 + gab] - 0x30 ) * 10 + (pDate[9+ gab + 1]-0x30);
306 ++gab;
307 } else
308 day = (pDate[9+gab]-0x30);
310 else {
311 day = 0;
313 if( ISNUMBER( pDate[17 + gab] ) )
315 if( ISNUMBER( pDate[18 + gab])) {
316 hour = ( pDate[17 + gab] - 0x30 ) * 10 + (pDate[17+ gab + 1]-0x30);
317 ++gab;
318 } else
319 hour = (pDate[17+gab]-0x30);
321 else {
322 hour = 0;
324 if( ISNUMBER( pDate[20 + gab] ) )
326 if( ISNUMBER( pDate[21 + gab])) {
327 minute = ( pDate[20 + gab] - 0x30 ) * 10 + (pDate[20+ gab + 1]-0x30);
328 ++gab;
329 } else
330 minute = (pDate[20+gab]-0x30);
332 else {
333 minute = 0;
335 sprintf(buf,"%d-%02d-%02dT%02d:%02d:00",year,month,day,hour,minute);
337 rstartEl( ascii("meta:creation-date"), rList );
338 rchars( ascii(buf));
339 rendEl( ascii("meta:creation-date") );
342 if (hwpinfo->summary.keyword[0][0] || hwpinfo->summary.etc[0][0])
344 rstartEl(ascii("meta:keywords"), rList);
345 if (hwpinfo->summary.keyword[0][0])
347 rstartEl(ascii("meta:keyword"), rList);
348 rchars((hconv(hwpinfo->summary.keyword[0])));
349 rendEl(ascii("meta:keyword"));
351 if (hwpinfo->summary.keyword[1][0])
353 rstartEl(ascii("meta:keyword"), rList);
354 rchars((hconv(hwpinfo->summary.keyword[1])));
355 rendEl(ascii("meta:keyword"));
357 if (hwpinfo->summary.etc[0][0])
359 rstartEl(ascii("meta:keyword"), rList);
360 rchars((hconv(hwpinfo->summary.etc[0])));
361 rendEl(ascii("meta:keyword"));
363 if (hwpinfo->summary.etc[1][0])
365 rstartEl(ascii("meta:keyword"), rList);
366 rchars((hconv(hwpinfo->summary.etc[1])));
367 rendEl(ascii("meta:keyword"));
369 if (hwpinfo->summary.etc[2][0])
371 rstartEl(ascii("meta:keyword"), rList);
372 rchars((hconv(hwpinfo->summary.etc[2])));
373 rendEl(ascii("meta:keyword"));
375 rendEl(ascii("meta:keywords"));
377 rendEl(ascii("office:meta"));
381 static struct
383 const char *name;
384 sal_Bool bMade;
388 ArrowShape[] =
390 { "", sal_False },
392 "Arrow", sal_False
394 { "Line Arrow", sal_False },
396 "Square", sal_False
400 static struct
402 double dots1;
403 double dots2;
404 double distance;
408 LineStyle[] =
410 { 0.0, 0.0, 0.0 },
412 0.34, 0., 0.272
414 { 0.17, 0., 0.136},
416 0.612, 0.17, 0.136
418 { 0.85, 0.17, 0.136}
421 void HwpReader::makeDrawMiscStyle( HWPDrawingObject *hdo )
423 while( hdo )
425 if( hdo->child )
426 makeDrawMiscStyle( hdo->child );
428 HWPDOProperty *prop = &hdo->property;
429 if( hdo->type == HWPDO_CONTAINER )
431 hdo = hdo->next;
432 continue;
435 if( prop->line_pstyle > 0 && prop->line_pstyle < 5 && prop->line_color <= 0xffffff)
437 padd( ascii("draw:name"), sXML_CDATA, ascii(Int2Str(hdo->index, "LineType%d", buf)));
438 padd( ascii("draw:style"), sXML_CDATA, ascii("round"));
439 padd( ascii("draw:dots1"), sXML_CDATA, ascii("1"));
440 padd( ascii("draw:dots1-length"), sXML_CDATA, Double2Str( LineStyle[prop->line_pstyle].dots1 * WTMM(prop->line_width) ) + ascii("cm"));
441 if( prop->line_pstyle == 3 )
443 padd( ascii("draw:dots2"), sXML_CDATA, ascii("1"));
444 padd( ascii("draw:dots2-length"), sXML_CDATA, Double2Str( LineStyle[prop->line_pstyle].dots2 * WTMM(prop->line_width) ) + ascii("cm"));
446 else if( prop->line_pstyle == 4 )
448 padd( ascii("draw:dots2"), sXML_CDATA, ascii("2"));
449 padd( ascii("draw:dots2-length"), sXML_CDATA, Double2Str( LineStyle[prop->line_pstyle].dots2 * WTMM(prop->line_width)) + ascii("cm"));
451 padd( ascii("draw:distance"), sXML_CDATA, Double2Str( LineStyle[prop->line_pstyle].distance * WTMM(prop->line_width)) + ascii("cm"));
452 rstartEl( ascii("draw:stroke-dash"), rList);
453 pList->clear();
454 rendEl( ascii("draw:stroke-dash") );
457 if( hdo->type == HWPDO_LINE || hdo->type == HWPDO_ARC || hdo->type == HWPDO_FREEFORM ||
458 hdo->type == HWPDO_ADVANCED_ARC )
460 if( prop->line_tstyle && !ArrowShape[prop->line_tstyle].bMade )
462 ArrowShape[prop->line_tstyle].bMade = sal_True;
463 padd(ascii("draw:name"), sXML_CDATA,
464 ascii(ArrowShape[prop->line_tstyle].name));
465 if( prop->line_tstyle == 1 )
467 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 20 30"));
468 padd(ascii("svg:d"), sXML_CDATA, ascii("m10 0-10 30h20z"));
470 else if( prop->line_tstyle == 2 )
472 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 1122 2243"));
473 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"));
475 else if( prop->line_tstyle == 3 )
477 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 30 30"));
478 padd(ascii("svg:d"), sXML_CDATA, ascii("m0 0h30v30h-30z"));
480 rstartEl(ascii("draw:marker"), rList);
481 pList->clear();
482 rendEl(ascii("draw:marker"));
484 if( prop->line_hstyle && !ArrowShape[prop->line_hstyle].bMade)
486 ArrowShape[prop->line_hstyle].bMade = sal_True;
487 padd(ascii("draw:name"), sXML_CDATA,
488 ascii(ArrowShape[prop->line_hstyle].name));
489 if( prop->line_hstyle == 1 )
491 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 20 30"));
492 padd(ascii("svg:d"), sXML_CDATA, ascii("m10 0-10 30h20z"));
494 else if( prop->line_hstyle == 2 )
496 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 1122 2243"));
497 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"));
499 else if( prop->line_hstyle == 3 )
501 padd(ascii("svg:viewBox"), sXML_CDATA, ascii("0 0 20 20"));
502 padd(ascii("svg:d"), sXML_CDATA, ascii("m0 0h20v20h-20z"));
504 rstartEl(ascii("draw:marker"), rList);
505 pList->clear();
506 rendEl(ascii("draw:marker"));
510 if( hdo->type != HWPDO_LINE )
512 if( prop->flag >> 18 & 0x01 )
514 padd( ascii("draw:name"), sXML_CDATA, ascii(Int2Str(hdo->index, "fillimage%d", buf)));
515 if( !prop->pictype )
517 padd( ascii("xlink:href"), sXML_CDATA,
518 hconv(kstr2hstr( (uchar *)urltounix(prop->szPatternFile).c_str()).c_str()));
520 else
522 EmPicture *emp = 0L;
523 if ( strlen( prop->szPatternFile ) > 3)
524 emp = hwpfile.GetEmPictureByName(prop->szPatternFile);
525 if( emp )
527 char filename[128+17+9];
528 char dirname[128];
529 int fd;
530 #ifdef _WIN32
531 GetTempPath(sizeof(dirname), dirname);
532 sprintf(filename, "%s%s",dirname, emp->name);
533 if( (fd = open( filename , _O_CREAT | _O_WRONLY | _O_BINARY , 0666)) >= 0 )
534 #else
535 strcpy(dirname, "/tmp/");
536 sprintf(filename, "%s%s", dirname, emp->name);
537 if( (fd = open( filename , O_CREAT | O_WRONLY , 0666)) >= 0 )
538 #endif
540 size_t nWritten = write(fd, emp->data, emp->size);
541 OSL_VERIFY(nWritten == emp->size);
542 close(fd);
544 #ifdef _WIN32
545 int j;
546 for(j = 0 ; j < (int)strlen( dirname ) ; j++)
548 if( dirname[j] == '\\' ) buf[j] = '/';
549 else buf[j] = dirname[j];
551 buf[j] = '\0';
552 sprintf(filename, "file:///%s%s",buf, emp->name );
553 #else
554 sprintf(filename, "file://%s%s",dirname, emp->name );
555 #endif
556 padd( ascii("xlink:href"), sXML_CDATA, ascii(filename));
558 else
560 padd( ascii("xlink:href"), sXML_CDATA,
561 hconv(kstr2hstr( (uchar *)urltounix(prop->szPatternFile).c_str()).c_str()));
565 padd( ascii("xlink:type"), sXML_CDATA, ascii("simple"));
566 padd( ascii("xlink:show"), sXML_CDATA, ascii("embed"));
567 padd( ascii("xlink:actuate"), sXML_CDATA, ascii("onLoad"));
569 rstartEl( ascii("draw:fill-image"), rList);
570 pList->clear();
571 rendEl( ascii("draw:fill-image"));
573 /* 그라데이션이 존재해도, 비트맵파일이 존재하면, 이것이 우선이다. */
574 else if( prop->flag >> 16 & 0x01 ) /* 그라데이션 존재여부 */
576 padd( ascii("draw:name"), sXML_CDATA, ascii(Int2Str(hdo->index, "Grad%d", buf)));
577 switch( prop->gstyle )
579 case 1 :
580 if( prop->center_y == 50 )
581 padd( ascii("draw:style"), sXML_CDATA, ascii("axial"));
582 else
583 padd( ascii("draw:style"), sXML_CDATA, ascii("linear"));
584 break;
585 case 2:
586 case 3:
587 padd( ascii("draw:style"), sXML_CDATA, ascii("radial"));
588 break;
589 case 4:
590 padd( ascii("draw:style"), sXML_CDATA, ascii("square"));
591 break;
592 default:
593 padd( ascii("draw:style"), sXML_CDATA, ascii("linear"));
594 break;
596 padd( ascii("draw:cx"), sXML_CDATA,ascii(Int2Str(prop->center_x, "%d%%", buf)));
597 padd( ascii("draw:cy"), sXML_CDATA,ascii(Int2Str(prop->center_y, "%d%%", buf)));
599 HWPInfo *hwpinfo = hwpfile.GetHWPInfo();
600 int default_color = 0xffffff;
601 if( hwpinfo->back_info.isset )
603 if( hwpinfo->back_info.color[0] > 0 || hwpinfo->back_info.color[1] > 0
604 || hwpinfo->back_info.color[2] > 0 )
605 default_color = hwpinfo->back_info.color[0] << 16 |
606 hwpinfo->back_info.color[1] << 8 | hwpinfo->back_info.color[2];
609 if( prop->fromcolor > 0xffffff )
610 prop->fromcolor = default_color;
611 if( prop->tocolor > 0xffffff )
612 prop->tocolor = default_color;
614 if( prop->gstyle == 1)
616 if( prop->center_y == 100 )
618 sprintf( buf, "#%02x%02x%02x", prop->tocolor & 0xff,
619 (prop->tocolor >> 8) & 0xff, (prop->tocolor >>16) & 0xff );
620 padd( ascii("draw:start-color"), sXML_CDATA, ascii( buf ));
621 sprintf( buf, "#%02x%02x%02x", prop->fromcolor & 0xff,
622 (prop->fromcolor >> 8) & 0xff, (prop->fromcolor >>16) & 0xff );
623 padd( ascii("draw:end-color"), sXML_CDATA, ascii( buf ));
625 else
627 sprintf( buf, "#%02x%02x%02x", prop->fromcolor & 0xff,
628 (prop->fromcolor >> 8) & 0xff, (prop->fromcolor >>16) & 0xff );
629 padd( ascii("draw:start-color"), sXML_CDATA, ascii( buf ));
630 sprintf( buf, "#%02x%02x%02x", prop->tocolor & 0xff,
631 (prop->tocolor >> 8) & 0xff, (prop->tocolor >>16) & 0xff );
632 padd( ascii("draw:end-color"), sXML_CDATA, ascii( buf ));
635 else
637 sprintf( buf, "#%02x%02x%02x", prop->tocolor & 0xff,
638 (prop->tocolor >> 8) & 0xff, (prop->tocolor >>16) & 0xff );
639 padd( ascii("draw:start-color"), sXML_CDATA,ascii( buf ));
641 sprintf( buf, "#%02x%02x%02x", prop->fromcolor & 0xff,
642 (prop->fromcolor >> 8) & 0xff, (prop->fromcolor >>16) & 0xff );
643 padd( ascii("draw:end-color"), sXML_CDATA,ascii( buf ));
645 if( prop->angle > 0 && ( prop->gstyle == 1 || prop->gstyle == 4))
647 int angle = prop->angle >= 180 ? prop->angle - 180 : prop->angle;
648 angle = 1800 - prop->angle * 10;
649 padd( ascii("draw:angle"), sXML_CDATA,
650 ascii(Int2Str( angle, "%d", buf)));
652 rstartEl( ascii("draw:gradient"), rList );
653 pList->clear();
654 rendEl( ascii("draw:gradient"));
656 /* 해칭 */
657 else if( prop->pattern_type >> 24 & 0x01 )
659 int type = prop->pattern_type & 0xffffff;
660 padd( ascii("draw:name"), sXML_CDATA,
661 ascii(Int2Str(hdo->index, "Hatch%d", buf)));
662 if( type < 4 )
663 padd( ascii("draw:style"), sXML_CDATA, ascii("single") );
664 else
665 padd( ascii("draw:style"), sXML_CDATA, ascii("double") );
666 sprintf( buf, "#%02x%02x%02x",
667 sal_uInt16(prop->pattern_color & 0xff),
668 sal_uInt16((prop->pattern_color >> 8) & 0xff),
669 sal_uInt16((prop->pattern_color >>16) & 0xff) );
670 padd( ascii("draw:color"), sXML_CDATA, ascii( buf ));
671 padd( ascii("draw:distance"), sXML_CDATA, ascii("0.12cm"));
672 switch( type )
674 case 0 :
675 case 4 :
676 padd( ascii("draw:rotation"), sXML_CDATA, ascii("0"));
677 break;
678 case 1 :
679 padd( ascii("draw:rotation"), sXML_CDATA, ascii("900"));
680 break;
681 case 2 :
682 padd( ascii("draw:rotation"), sXML_CDATA, ascii("1350"));
683 break;
684 case 3 :
685 case 5 :
686 padd( ascii("draw:rotation"), sXML_CDATA, ascii("450"));
687 break;
689 rstartEl( ascii("draw:hatch"), rList);
690 pList->clear();
691 rendEl( ascii("draw:hatch"));
694 hdo = hdo->next;
699 void HwpReader::makeStyles()
701 HWPStyle *hwpstyle = hwpfile.GetHWPStyle();
703 rstartEl(ascii("office:styles"), rList);
705 int i;
706 for (i = 0; i < hwpfile.getFBoxStyleCount(); i++)
708 if( hwpfile.getFBoxStyle(i)->boxtype == 'D' )
710 makeDrawMiscStyle((HWPDrawingObject *)hwpfile.getFBoxStyle(i)->cell );
714 padd(ascii("style:name"), sXML_CDATA, ascii("Standard"));
715 padd(ascii("style:family"), sXML_CDATA, ascii("paragraph"));
716 padd(ascii("style:class"), sXML_CDATA, ascii("text"));
717 rstartEl(ascii("style:style"), rList);
718 pList->clear();
720 padd(ascii("fo:line-height"), sXML_CDATA, ascii("160%"));
721 padd(ascii("fo:text-align"), sXML_CDATA, ascii("justify"));
722 rstartEl(ascii("style:properties"), rList);
723 pList->clear();
724 rstartEl(ascii("style:tab-stops"), rList);
726 for( i = 1 ; i < 40 ; i++)
728 padd(ascii("style:position"), sXML_CDATA,
729 Double2Str( WTI(1000 * i)) + ascii("inch"));
730 rstartEl(ascii("style:tab-stop"), rList);
731 pList->clear();
732 rendEl(ascii("style:tab-stop"));
734 rendEl(ascii("style:tab-stops"));
735 rendEl(ascii("style:properties"));
737 rendEl(ascii("style:style"));
739 for (int ii = 0; ii < hwpstyle->Num(); ii++)
741 unsigned char *stylename = (unsigned char *) hwpstyle->GetName(ii);
742 padd(ascii("style:name"), sXML_CDATA, (hconv(kstr2hstr(stylename).c_str())));
743 padd(ascii("style:family"), sXML_CDATA, ascii("paragraph"));
744 padd(ascii("style:parent-style-name"), sXML_CDATA, ascii("Standard"));
746 rstartEl(ascii("style:style"), rList);
748 pList->clear();
750 parseCharShape(hwpstyle->GetCharShape(ii));
751 parseParaShape(hwpstyle->GetParaShape(ii));
753 rstartEl(ascii("style:properties"), rList);
754 pList->clear();
755 rendEl(ascii("style:properties"));
757 rendEl(ascii("style:style"));
761 padd( ascii("style:name"), sXML_CDATA, ascii("Header"));
762 padd( ascii("style:family"), sXML_CDATA, ascii("paragraph"));
763 padd( ascii("style:parent-style-name"), sXML_CDATA, ascii("Standard"));
764 padd( ascii("style:class"), sXML_CDATA, ascii("extra"));
765 rstartEl(ascii("style:style"), rList);
766 pList->clear();
767 rendEl(ascii("style:style"));
771 padd( ascii("style:name"), sXML_CDATA, ascii("Footer"));
772 padd( ascii("style:family"), sXML_CDATA, ascii("paragraph"));
773 padd( ascii("style:parent-style-name"), sXML_CDATA, ascii("Standard"));
774 padd( ascii("style:class"), sXML_CDATA, ascii("extra"));
775 rstartEl(ascii("style:style"), rList);
776 pList->clear();
778 rendEl(ascii("style:style"));
781 if( hwpfile.linenumber > 0)
783 padd( ascii("style:name"), sXML_CDATA, ascii("Horizontal Line"));
784 padd( ascii("style:family"), sXML_CDATA, ascii("paragraph"));
785 padd( ascii("style:parent-style-name"), sXML_CDATA, ascii("Standard"));
786 padd( ascii("style:class"), sXML_CDATA, ascii("html"));
787 rstartEl( ascii("style:style"), rList);
788 pList->clear();
789 padd( ascii("fo:font-size"), sXML_CDATA, ascii("6pt"));
790 padd( ascii("fo:margin-top"), sXML_CDATA, ascii("0cm"));
791 padd( ascii("fo:margin-bottom"), sXML_CDATA, ascii("0cm"));
792 padd( ascii("style:border-line-width-bottom"), sXML_CDATA, ascii("0.02cm 0.035cm 0.002cm"));
793 padd( ascii("fo:padding"), sXML_CDATA, ascii("0cm"));
794 padd( ascii("fo:border-bottom"), sXML_CDATA, ascii("0.039cm double #808080"));
795 padd( ascii("text:number-lines"), sXML_CDATA, ascii("false"));
796 padd( ascii("text:line-number"), sXML_CDATA, ascii("0"));
797 padd(ascii("fo:line-height"), sXML_CDATA, ascii("100%"));
798 rstartEl( ascii("style:properties"), rList);
799 pList->clear();
800 rendEl( ascii("style:properties"));
801 rendEl( ascii("style:style"));
804 HWPInfo *hwpinfo = hwpfile.GetHWPInfo();
806 padd(ascii("text:num-suffix"), sXML_CDATA, ascii(")"));
807 padd(ascii("text:num-format"), sXML_CDATA, ascii("1"));
808 if( hwpinfo->beginfnnum != 1)
809 padd(ascii("text:offset"), sXML_CDATA, ascii(Int2Str(hwpinfo->beginfnnum -1, "%d", buf)));
810 rstartEl(ascii("text:footnotes-configuration"), rList);
811 pList->clear();
812 rendEl(ascii("text:footnotes-configuration"));
814 rendEl(ascii("office:styles"));
819 * parse automatic styles from hwpfile
820 * 자동적으로 반영이 되는 스타일을 정의한다. 예를들어 각각의 문단이나, 테이블, 헤더 등등의 스타일을 이곳에서 정의하고, Body에서는 이곳에 정의된 스타일을 이용한다.
821 * 1. paragraph, text, fbox, page스타일에 대해 지원한다.
823 void HwpReader::makeAutoStyles()
825 int i;
827 rstartEl(ascii("office:automatic-styles"), rList);
829 for (i = 0; i < hwpfile.getParaShapeCount(); i++)
830 makePStyle(hwpfile.getParaShape(i));
832 for (i = 0; i < hwpfile.getCharShapeCount(); i++)
833 makeTStyle(hwpfile.getCharShape(i));
835 for( i = 0 ; i < hwpfile.getTableCount(); i++)
836 makeTableStyle(hwpfile.getTable(i));
838 for (i = 0; i < hwpfile.getFBoxStyleCount(); i++)
840 if( hwpfile.getFBoxStyle(i)->boxtype == 'D' )
841 makeDrawStyle((HWPDrawingObject *)hwpfile.getFBoxStyle(i)->cell, hwpfile.getFBoxStyle(i));
842 else
843 makeFStyle(hwpfile.getFBoxStyle(i));
846 sal_Bool bIsLeft = sal_False, bIsMiddle = sal_False, bIsRight = sal_False;
847 for( i = 0 ; i < hwpfile.getPageNumberCount() ; i++ )
849 ShowPageNum *pn = hwpfile.getPageNumber(i);
850 if( pn->where == 7 || pn->where == 8 )
852 bIsLeft = sal_True;
853 bIsRight = sal_True;
855 else if( pn->where == 1 || pn->where == 4 )
857 bIsLeft = sal_True;
859 else if( pn->where == 2 || pn->where == 5 )
861 bIsMiddle = sal_True;
863 else if( pn->where == 3 || pn->where == 6 )
865 bIsRight = sal_True;
869 for( i = 1; i <= 3 ; i++ )
871 if( i == 1 && bIsLeft == sal_False )
872 continue;
873 if( i == 2 && bIsMiddle == sal_False )
874 continue;
875 if( i == 3 && bIsRight == sal_False )
876 continue;
877 padd(ascii("style:name"), sXML_CDATA,
878 ascii(Int2Str(i,"PNPara%d", buf)));
879 padd(ascii("style:family"), sXML_CDATA, ascii("paragraph"));
880 padd(ascii("style:parent-style-name"), sXML_CDATA, ascii("Standard"));
881 rstartEl(ascii("style:style"), rList);
882 pList->clear();
883 if( i == 1 )
884 padd(ascii("fo:text-align"), sXML_CDATA, ascii("start"));
885 else if ( i == 2 )
886 padd(ascii("fo:text-align"), sXML_CDATA, ascii("center"));
887 else if ( i == 3 )
888 padd(ascii("fo:text-align"), sXML_CDATA, ascii("end"));
889 rstartEl(ascii("style:properties"), rList);
890 pList->clear();
891 rendEl( ascii("style:properties"));
892 rendEl( ascii("style:style"));
894 padd(ascii("style:name"), sXML_CDATA, ascii(Int2Str(i,"PNBox%d",buf)));
895 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
896 rstartEl(ascii("style:style"), rList);
897 pList->clear();
899 padd(ascii("fo:margin-top"), sXML_CDATA, ascii("0cm"));
900 padd(ascii("fo:margin-bottom"), sXML_CDATA, ascii("0cm"));
901 padd(ascii("style:wrap"), sXML_CDATA, ascii("run-through"));
902 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("from-top"));
903 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("paragraph"));
905 if( i == 1 )
906 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("left"));
907 else if ( i == 2 )
908 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("center"));
909 else if ( i == 3 )
910 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("right"));
911 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
912 padd(ascii("fo:padding"), sXML_CDATA, ascii("0cm"));
913 padd(ascii("stylefamily"), sXML_CDATA, ascii("graphics"));
914 rstartEl(ascii("style:properties"), rList);
915 pList->clear();
916 rendEl(ascii("style:properties"));
917 rendEl(ascii("style:style"));
920 for (i = 0; i < hwpfile.getDateFormatCount(); i++)
921 makeDateFormat(hwpfile.getDateCode(i));
923 makePageStyle();
925 rendEl(ascii("office:automatic-styles"));
929 struct PageSetting
931 PageSetting()
933 header = 0L;
934 header_odd = 0L;
935 header_even = 0L;
936 footer = 0L;
937 footer_odd = 0L;
938 footer_even = 0L;
939 pagenumber=0L;
940 bIsSet = sal_False;
942 HeaderFooter *header ;
943 HeaderFooter *header_odd ;
944 HeaderFooter *header_even ;
945 HeaderFooter *footer ;
946 HeaderFooter *footer_odd ;
947 HeaderFooter *footer_even ;
948 ShowPageNum *pagenumber;
949 sal_Bool bIsSet;
952 void HwpReader::makeMasterStyles()
954 rstartEl(ascii("office:master-styles"), rList);
956 int i;
957 int nMax = hwpfile.getMaxSettedPage();
958 std::deque<PageSetting> pSet(nMax + 1);
960 for( i = 0 ; i < hwpfile.getPageNumberCount() ; i++ )
962 ShowPageNum *pn = hwpfile.getPageNumber(i);
963 pSet[pn->m_nPageNumber].pagenumber = pn;
964 pSet[pn->m_nPageNumber].bIsSet = sal_True;
966 for( i = 0 ; i < hwpfile.getHeaderFooterCount() ; i++ )
968 HeaderFooter* hf = hwpfile.getHeaderFooter(i);
969 pSet[hf->m_nPageNumber].bIsSet = sal_True;
970 if( hf->type == 0 ) // header
972 switch( hf->where )
974 case 0 :
975 pSet[hf->m_nPageNumber].header = hf;
976 pSet[hf->m_nPageNumber].header_even = 0L;
977 pSet[hf->m_nPageNumber].header_odd = 0L;
978 break;
979 case 1:
980 pSet[hf->m_nPageNumber].header_even = hf;
981 if( pSet[hf->m_nPageNumber].header )
983 pSet[hf->m_nPageNumber].header_odd =
984 pSet[hf->m_nPageNumber].header;
985 pSet[hf->m_nPageNumber].header = 0L;
987 break;
988 case 2:
989 pSet[hf->m_nPageNumber].header_odd = hf;
990 if( pSet[hf->m_nPageNumber].header )
992 pSet[hf->m_nPageNumber].header_even =
993 pSet[hf->m_nPageNumber].header;
994 pSet[hf->m_nPageNumber].header = 0L;
996 break;
999 else // footer
1001 switch( hf->where )
1003 case 0 :
1004 pSet[hf->m_nPageNumber].footer = hf;
1005 pSet[hf->m_nPageNumber].footer_even = 0L;
1006 pSet[hf->m_nPageNumber].footer_odd = 0L;
1007 break;
1008 case 1:
1009 pSet[hf->m_nPageNumber].footer_even = hf;
1010 if( pSet[hf->m_nPageNumber].footer )
1012 pSet[hf->m_nPageNumber].footer_odd =
1013 pSet[hf->m_nPageNumber].footer;
1014 pSet[hf->m_nPageNumber].footer = 0L;
1016 break;
1017 case 2:
1018 pSet[hf->m_nPageNumber].footer_odd = hf;
1019 if( pSet[hf->m_nPageNumber].footer )
1021 pSet[hf->m_nPageNumber].footer_even =
1022 pSet[hf->m_nPageNumber].footer;
1023 pSet[hf->m_nPageNumber].footer = 0L;
1025 break;
1030 PageSetting *pPrevSet = 0L;
1031 PageSetting *pPage = 0L;
1033 for( i = 1; i <= nMax ; i++ )
1035 if( i == 1 )
1036 padd(ascii("style:name"), sXML_CDATA, ascii("Standard"));
1037 else
1038 padd(ascii("style:name"), sXML_CDATA,
1039 ascii(Int2Str(i, "p%d", buf)));
1040 padd(ascii("style:page-master-name"), sXML_CDATA,
1041 ascii(Int2Str(hwpfile.GetPageMasterNum(i), "pm%d", buf)));
1042 if( i < nMax )
1043 padd(ascii("style:next-style-name"), sXML_CDATA,
1044 ascii(Int2Str(i+1, "p%d", buf)));
1045 padd(ascii("draw:style-name"), sXML_CDATA,
1046 ascii(Int2Str(i, "master%d", buf)));
1047 rstartEl(ascii("style:master-page"), rList);
1048 pList->clear();
1050 if( pSet[i].bIsSet ) /* 현재 설정이 바뀌었으면 */
1052 if( !pSet[i].pagenumber ){
1053 if( pPrevSet && pPrevSet->pagenumber )
1054 pSet[i].pagenumber = pPrevSet->pagenumber;
1056 if( pSet[i].pagenumber )
1058 if( pSet[i].pagenumber->where == 7 && pSet[i].header )
1060 pSet[i].header_even = pSet[i].header;
1061 pSet[i].header_odd = pSet[i].header;
1062 pSet[i].header = 0L;
1064 if( pSet[i].pagenumber->where == 8 && pSet[i].footer )
1066 pSet[i].footer_even = pSet[i].footer;
1067 pSet[i].footer_odd = pSet[i].footer;
1068 pSet[i].footer = 0L;
1072 if( !pSet[i].header_even && pPrevSet && pPrevSet->header_even )
1074 pSet[i].header_even = pPrevSet->header_even;
1076 if( !pSet[i].header_odd && pPrevSet && pPrevSet->header_odd )
1078 pSet[i].header_odd = pPrevSet->header_odd;
1080 if( !pSet[i].footer_even && pPrevSet && pPrevSet->footer_even )
1082 pSet[i].footer_even = pPrevSet->footer_even;
1084 if( !pSet[i].footer_odd && pPrevSet && pPrevSet->footer_odd )
1086 pSet[i].footer_odd = pPrevSet->footer_odd;
1089 pPage = &pSet[i];
1090 pPrevSet = &pSet[i];
1092 else if( pPrevSet ) /* 이전의 설정된 것이 있으면. */
1094 pPage = pPrevSet;
1096 else /* 아직 설정이 없다면 기본설정으로 */
1098 rstartEl(ascii("style:header"), rList);
1099 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1100 rstartEl(ascii("text:p"), rList);
1101 pList->clear();
1102 rendEl(ascii("text:p"));
1103 rendEl(ascii("style:header"));
1105 rstartEl(ascii("style:footer"), rList);
1106 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1107 rstartEl(ascii("text:p"), rList);
1108 pList->clear();
1109 rendEl(ascii("text:p"));
1110 rendEl(ascii("style:footer"));
1112 rendEl(ascii("style:master-page"));
1114 continue;
1116 // ------------- header ------------- //
1117 if( pPage->header )
1119 rstartEl(ascii("style:header"), rList);
1120 if( pPage->pagenumber && pPage->pagenumber->where < 4 )
1122 d->bInHeader = sal_True;
1123 d->pPn = pPage->pagenumber;
1125 parsePara(pPage->header->plist.front());
1126 d->bInHeader = sal_False;
1127 d->pPn = 0L;
1128 rendEl(ascii("style:header"));
1130 if( pPage->header_even )
1132 rstartEl(ascii("style:header"), rList);
1133 if( pPage->pagenumber && ( pPage->pagenumber->where < 4
1134 || pPage->pagenumber->where == 7 ) )
1136 d->bInHeader = sal_True;
1137 d->pPn = pPage->pagenumber;
1138 d->nPnPos = 3;
1140 parsePara(pPage->header_even->plist.front());
1141 d->bInHeader = sal_False;
1142 d->pPn = 0L;
1143 d->nPnPos = 0;
1144 rendEl(ascii("style:header"));
1146 /* 기본으로 한다. */
1147 else if( pPage->header_odd && !pPage->header_even )
1149 rstartEl(ascii("style:header"), rList);
1150 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1151 rstartEl(ascii("text:p"), rList);
1152 pList->clear();
1153 if( pPage->pagenumber && ( pPage->pagenumber->where < 4 ||
1154 pPage->pagenumber->where == 7 ) )
1156 d->pPn = pPage->pagenumber;
1157 d->nPnPos = 3;
1158 makeShowPageNum();
1159 d->pPn = 0L;
1160 d->nPnPos = 0;
1162 rendEl(ascii("text:p"));
1163 rendEl(ascii("style:header"));
1165 if( pPage->header_odd )
1167 rstartEl(ascii("style:header-left"), rList);
1168 if( pPage->pagenumber && ( pPage->pagenumber->where < 4
1169 || pPage->pagenumber->where == 7 ) )
1171 d->bInHeader = sal_True;
1172 d->nPnPos = 1;
1173 d->pPn = pPage->pagenumber;
1175 parsePara(pPage->header_odd->plist.front());
1176 d->bInHeader = sal_False;
1177 d->pPn = 0L;
1178 d->nPnPos = 0;
1179 rendEl(ascii("style:header-left"));
1181 /* 기본으로 한다. */
1182 else if( pPage->header_even && !pPage->header_odd )
1184 rstartEl(ascii("style:header-left"), rList);
1185 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1186 rstartEl(ascii("text:p"), rList);
1187 pList->clear();
1188 if( pPage->pagenumber && ( pPage->pagenumber->where < 4 ||
1189 pPage->pagenumber->where == 7 ) )
1191 d->pPn = pPage->pagenumber;
1192 d->nPnPos = 1;
1193 makeShowPageNum();
1194 d->pPn = 0L;
1195 d->nPnPos = 0;
1197 rendEl(ascii("text:p"));
1198 rendEl(ascii("style:header-left"));
1200 if( !pPage->header && !pPage->header_even && !pPage->header_odd )
1202 rstartEl(ascii("style:header"), rList);
1203 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1204 rstartEl(ascii("text:p"), rList);
1205 pList->clear();
1206 if( pPage->pagenumber && pPage->pagenumber->where < 4
1207 && pPage->pagenumber->where == 7 )
1209 d->pPn = pPage->pagenumber;
1210 makeShowPageNum();
1211 d->pPn = 0L;
1213 rendEl(ascii("text:p"));
1214 rendEl(ascii("style:header"));
1216 // ------------- footer ------------- //
1217 if( pPage->footer )
1219 rstartEl(ascii("style:footer"), rList);
1220 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1221 && pPage->pagenumber->where != 7 )
1223 d->bInHeader = sal_True;
1224 d->pPn = pPage->pagenumber;
1226 parsePara(pPage->footer->plist.front());
1227 d->bInHeader = sal_False;
1228 d->pPn = 0L;
1229 rendEl(ascii("style:footer"));
1231 if( pPage->footer_even )
1233 rstartEl(ascii("style:footer"), rList);
1234 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1235 && pPage->pagenumber->where != 7 )
1237 d->bInHeader = sal_True;
1238 d->pPn = pPage->pagenumber;
1239 d->nPnPos = 3;
1241 parsePara(pPage->footer_even->plist.front());
1242 d->bInHeader = sal_False;
1243 d->pPn = 0L;
1244 d->nPnPos = 0;
1245 rendEl(ascii("style:footer"));
1247 /* 기본으로 한다. */
1248 else if( pPage->footer_odd && !pPage->footer_even )
1250 rstartEl(ascii("style:footer"), rList);
1251 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1252 rstartEl(ascii("text:p"), rList);
1253 pList->clear();
1254 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1255 && pPage->pagenumber->where != 7 )
1257 d->pPn = pPage->pagenumber;
1258 d->nPnPos = 3;
1259 makeShowPageNum();
1260 d->pPn = 0L;
1261 d->nPnPos = 0;
1263 rendEl(ascii("text:p"));
1264 rendEl(ascii("style:footer"));
1266 if( pPage->footer_odd )
1268 rstartEl(ascii("style:footer-left"), rList);
1269 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1270 && pPage->pagenumber->where != 7 )
1272 d->bInHeader = sal_True;
1273 d->pPn = pPage->pagenumber;
1274 d->nPnPos = 1;
1276 parsePara(pPage->footer_odd->plist.front());
1277 d->bInHeader = sal_False;
1278 d->pPn = 0L;
1279 d->nPnPos = 0;
1280 rendEl(ascii("style:footer-left"));
1282 /* 기본으로 한다. */
1283 else if( pPage->footer_even && !pPage->footer_odd )
1285 rstartEl(ascii("style:footer-left"), rList);
1286 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1287 rstartEl(ascii("text:p"), rList);
1288 pList->clear();
1289 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1290 && pPage->pagenumber->where != 7 )
1292 d->pPn = pPage->pagenumber;
1293 d->nPnPos = 1;
1294 makeShowPageNum();
1295 d->pPn = 0L;
1296 d->nPnPos = 0;
1298 rendEl(ascii("text:p"));
1299 rendEl(ascii("style:footer-left"));
1301 if( !pPage->footer && !pPage->footer_even && !pPage->footer_odd )
1303 rstartEl(ascii("style:footer"), rList);
1304 padd(ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
1305 rstartEl(ascii("text:p"), rList);
1306 pList->clear();
1307 if( pPage->pagenumber && pPage->pagenumber->where >= 4
1308 && pPage->pagenumber->where != 7 )
1310 d->pPn = pPage->pagenumber;
1311 makeShowPageNum();
1312 d->pPn = 0L;
1314 rendEl(ascii("text:p"));
1315 rendEl(ascii("style:footer"));
1318 rendEl(ascii("style:master-page"));
1320 rendEl(ascii("office:master-styles"));
1325 * 텍스트 스타일을 위한 프로퍼티들을 만든다.
1326 * 1. fo:font-size, fo:font-family, fo:letter-spacing, fo:color,
1327 * style:text-background-color, fo:font-style, fo:font-weight,
1328 * style:text-underline,style:text-outline,fo:text-shadow,style:text-position
1329 * 을 지원한다.
1331 void HwpReader::parseCharShape(CharShape * cshape)
1333 HWPFont *hwpfont = hwpfile.GetHWPFont();
1335 padd(ascii("fo:font-size"), sXML_CDATA,
1336 ascii(Int2Str(cshape->size / 25, "%dpt", buf)));
1337 padd(ascii("style:font-size-asian"), sXML_CDATA,
1338 ascii(Int2Str(cshape->size / 25, "%dpt", buf)));
1340 ::std::string const tmp = hstr2ksstr(kstr2hstr(
1341 (unsigned char *) hwpfont->GetFontName(0, cshape->font[0])).c_str());
1342 double fRatio = 1.0;
1343 int size = getRepFamilyName(tmp.c_str(), buf, fRatio);
1345 padd(ascii("fo:font-family"), sXML_CDATA,
1346 OUString(buf, size, RTL_TEXTENCODING_EUC_KR));
1347 padd(ascii("style:font-family-asian"), sXML_CDATA,
1348 OUString(buf, size, RTL_TEXTENCODING_EUC_KR));
1350 padd(ascii("style:text-scale"), sXML_CDATA,
1351 ascii(Int2Str((int)(cshape->ratio[0] * fRatio), "%d%%", buf)));
1353 double sspace = (cshape->size / 25) * cshape->space[0] / 100.;
1355 if (sspace != 0.)
1357 padd(ascii("fo:letter-spacing"), sXML_CDATA,
1358 Double2Str(sspace) + ascii("pt"));
1360 if (cshape->color[1] != 0)
1361 padd(ascii("fo:color"), sXML_CDATA,
1362 ascii(hcolor2str(cshape->color[1], 100, buf, true)));
1363 if (cshape->shade != 0)
1364 padd(ascii("style:text-background-color"), sXML_CDATA,
1365 ascii(hcolor2str(cshape->color[0], cshape->shade, buf)));
1366 if (cshape->attr & 0x01)
1368 padd(ascii("fo:font-style"), sXML_CDATA, ascii("italic"));
1369 padd(ascii("style:font-style-asian"), sXML_CDATA, ascii("italic"));
1371 else{
1372 padd(ascii("fo:font-style"), sXML_CDATA, ascii("normal"));
1373 padd(ascii("style:font-style-asian"), sXML_CDATA, ascii("normal"));
1375 if (cshape->attr >> 1 & 0x01)
1377 padd(ascii("fo:font-weight"), sXML_CDATA, ascii("bold"));
1378 padd(ascii("style:font-weight-asian"), sXML_CDATA, ascii("bold"));
1380 else{
1381 padd(ascii("fo:font-weight"), sXML_CDATA, ascii("normal"));
1382 padd(ascii("style:font-weight-asian"), sXML_CDATA, ascii("normal"));
1384 if (cshape->attr >> 2 & 0x01)
1385 padd(ascii("style:text-underline"), sXML_CDATA, ascii("single"));
1386 if (cshape->attr >> 3 & 0x01)
1387 padd(ascii("style:text-outline"), sXML_CDATA, ascii("true"));
1388 if (cshape->attr >> 4 & 0x01)
1389 padd(ascii("fo:text-shadow"), sXML_CDATA, ascii("1pt 1pt"));
1390 if (cshape->attr >> 5 & 0x01)
1391 padd(ascii("style:text-position"), sXML_CDATA, ascii("super 58%"));
1392 if (cshape->attr >> 6 & 0x01)
1393 padd(ascii("style:text-position"), sXML_CDATA, ascii("sub 58%"));
1399 * 실제 Paragraph에 해당하는 properties들을 만든다.
1400 * 1. fo:margin-left,fo:margin-right,fo:margin-top, fo:margin-bottom,
1401 * fo:text-indent, fo:line-height, fo:text-align, fo:border
1402 * 가 구현됨.
1403 * TODO : 탭설정 => 기본값이 아닌것들만 선택적으로 설정해야 한다.
1405 void HwpReader::parseParaShape(ParaShape * pshape)
1408 if (pshape->left_margin != 0)
1409 padd(ascii("fo:margin-left"), sXML_CDATA, Double2Str
1410 (WTI(pshape->left_margin )) + ascii("inch"));
1411 if (pshape->right_margin != 0)
1412 padd(ascii("fo:margin-right"), sXML_CDATA, Double2Str
1413 (WTI(pshape->right_margin)) + ascii("inch"));
1414 if (pshape->pspacing_prev != 0)
1415 padd(ascii("fo:margin-top"), sXML_CDATA, Double2Str
1416 (WTI(pshape->pspacing_prev)) + ascii("inch"));
1417 if (pshape->pspacing_next != 0)
1418 padd(ascii("fo:margin-bottom"), sXML_CDATA, Double2Str
1419 (WTI(pshape->pspacing_next)) + ascii("inch"));
1420 if (pshape->indent != 0)
1421 padd(ascii("fo:text-indent"), sXML_CDATA, Double2Str
1422 (WTI(pshape->indent)) + ascii("inch"));
1423 if (pshape->lspacing != 0)
1424 padd(ascii("fo:line-height"), sXML_CDATA,
1425 ascii(Int2Str (pshape->lspacing, "%d%%", buf)));
1427 unsigned char set_align = 0;
1429 switch ((int) pshape->arrange_type)
1431 case 1:
1432 strcpy(buf, "start");
1433 set_align = 1;
1434 break;
1435 case 2:
1436 strcpy(buf, "end");
1437 set_align = 1;
1438 break;
1439 case 3:
1440 strcpy(buf, "center");
1441 set_align = 1;
1442 break;
1443 case 4:
1444 case 5:
1445 case 6:
1446 strcpy(buf, "justify");
1447 set_align = 1;
1448 break;
1451 if (set_align)
1452 padd(ascii("fo:text-align"), sXML_CDATA, ascii(buf));
1454 if (pshape->outline)
1455 padd(ascii("fo:border"), sXML_CDATA, ascii("0.002cm solid #000000"));
1456 if( pshape->shade > 0 )
1458 padd(ascii("fo:background-color"), sXML_CDATA,
1459 ascii(hcolor2str(0, pshape->shade, buf)));
1462 if( pshape->pagebreak & 0x02 || pshape->pagebreak & 0x04)
1463 padd(ascii("fo:break-before"), sXML_CDATA, ascii("page"));
1464 else if( pshape->pagebreak & 0x01 )
1465 padd(ascii("fo:break-before"), sXML_CDATA, ascii("column"));
1471 * Paragraph에 대한 스타일을 만든다.
1473 void HwpReader::makePStyle(ParaShape * pshape)
1475 int nscount = pshape->tabs[MAXTABS -1].type;
1476 padd(ascii("style:name"), sXML_CDATA,
1477 ascii(Int2Str(pshape->index, "P%d", buf)));
1478 padd(ascii("style:family"), sXML_CDATA, ascii("paragraph"));
1479 rstartEl(ascii("style:style"), rList);
1480 pList->clear();
1481 parseParaShape(pshape);
1482 parseCharShape(pshape->cshape);
1483 rstartEl(ascii("style:properties"), rList);
1484 pList->clear();
1486 if( nscount )
1488 unsigned char tf = 0;
1489 rstartEl(ascii("style:tab-stops"),rList);
1491 int tab_margin = pshape->left_margin + pshape->indent;
1492 if( tab_margin < 0 )
1493 tab_margin = 0;
1494 for( int i = 0 ; i < MAXTABS -1 ; i++)
1496 if( i > 0 && pshape->tabs[i].position == 0. )
1497 break;
1498 if( pshape->tabs[i].position <= tab_margin )
1499 continue;
1500 padd(ascii("style:position"), sXML_CDATA,
1501 Double2Str(WTMM(pshape->tabs[i].position - tab_margin )) + ascii("mm"));
1502 if( pshape->tabs[i].type )
1504 tf = 1;
1505 switch(pshape->tabs[i].type)
1507 case 1 :
1508 padd(ascii("style:type"), sXML_CDATA, ascii("right"));
1509 break;
1510 case 2:
1511 padd(ascii("style:type"), sXML_CDATA, ascii("center"));
1512 break;
1513 case 3:
1514 padd(ascii("style:type"), sXML_CDATA, ascii("char"));
1515 padd(ascii("style:char"), sXML_CDATA, ascii("."));
1516 break;
1519 if( pshape->tabs[i].dot_continue )
1521 tf = 1;
1522 padd(ascii("style:leader-char"), sXML_CDATA, ascii("."));
1524 rstartEl( ascii("style:tab-stop"), rList);
1525 pList->clear();
1526 rendEl( ascii("style:tab-stop") );
1528 if( (pshape->tabs[i].position != 1000 * i ) || tf )
1530 if( !--nscount ) break;
1533 rendEl( ascii("style:tab-stops"));
1535 rendEl(ascii("style:properties"));
1536 rendEl(ascii("style:style"));
1541 * 페이지의 스타일을 만든다. 여기에는 header/footer, footnote등이 포함된다.
1542 * TODO : , fo:background-color(정보가 없다)
1544 void HwpReader::makePageStyle()
1546 HWPInfo *hwpinfo = hwpfile.GetHWPInfo();
1547 int pmCount = hwpfile.getColumnCount();
1549 for( int i = 0 ; i < pmCount ; i++ ){
1550 padd(ascii("style:name"), sXML_CDATA, ascii(Int2Str(i + 1, "pm%d", buf)));
1551 rstartEl(ascii("style:page-master"),rList);
1552 pList->clear();
1555 switch( hwpinfo->paper.paper_kind )
1557 case 3: // A4
1558 if( hwpinfo->paper.paper_direction )
1560 padd(ascii("fo:page-height"),sXML_CDATA, ascii("210mm"));
1561 padd(ascii("fo:page-width"),sXML_CDATA, ascii("297mm"));
1563 else
1565 padd(ascii("fo:page-width"),sXML_CDATA, ascii("210mm"));
1566 padd(ascii("fo:page-height"),sXML_CDATA, ascii("297mm"));
1568 break;
1569 case 4: // 80 column
1570 if( hwpinfo->paper.paper_direction )
1572 padd(ascii("fo:page-height"),sXML_CDATA, ascii("8.5inch"));
1573 padd(ascii("fo:page-width"),sXML_CDATA, ascii("11inch"));
1575 else
1577 padd(ascii("fo:page-width"),sXML_CDATA, ascii("8.5inch"));
1578 padd(ascii("fo:page-height"),sXML_CDATA, ascii("11inch"));
1580 break;
1581 case 5: // B5
1582 if( hwpinfo->paper.paper_direction )
1584 padd(ascii("fo:page-height"),sXML_CDATA, ascii("176mm"));
1585 padd(ascii("fo:page-width"),sXML_CDATA, ascii("250mm"));
1587 else
1589 padd(ascii("fo:page-width"),sXML_CDATA, ascii("176mm"));
1590 padd(ascii("fo:page-height"),sXML_CDATA, ascii("250mm"));
1592 break;
1593 case 6: // B4
1594 if( hwpinfo->paper.paper_direction )
1596 padd(ascii("fo:page-height"),sXML_CDATA, ascii("250mm"));
1597 padd(ascii("fo:page-width"),sXML_CDATA, ascii("353mm"));
1599 else
1601 padd(ascii("fo:page-width"),sXML_CDATA, ascii("250mm"));
1602 padd(ascii("fo:page-height"),sXML_CDATA, ascii("353mm"));
1604 break;
1605 case 7:
1606 if( hwpinfo->paper.paper_direction )
1608 padd(ascii("fo:page-height"),sXML_CDATA, ascii("8.5inch"));
1609 padd(ascii("fo:page-width"),sXML_CDATA, ascii("14inch"));
1611 else
1613 padd(ascii("fo:page-width"),sXML_CDATA, ascii("8.5inch"));
1614 padd(ascii("fo:page-height"),sXML_CDATA, ascii("14inch"));
1616 break;
1617 case 8:
1618 if( hwpinfo->paper.paper_direction )
1620 padd(ascii("fo:page-height"),sXML_CDATA, ascii("297mm"));
1621 padd(ascii("fo:page-width"),sXML_CDATA, ascii("420mm"));
1623 else
1625 padd(ascii("fo:page-width"),sXML_CDATA, ascii("297mm"));
1626 padd(ascii("fo:page-height"),sXML_CDATA, ascii("420mm"));
1628 break;
1629 case 0:
1630 case 1:
1631 case 2:
1632 default:
1633 if( hwpinfo->paper.paper_direction )
1635 padd(ascii("fo:page-width"),sXML_CDATA,
1636 Double2Str(WTI(hwpinfo->paper.paper_height)) + ascii("inch"));
1637 padd(ascii("fo:page-height"),sXML_CDATA,
1638 Double2Str(WTI(hwpinfo->paper.paper_width)) + ascii("inch"));
1640 else
1642 padd(ascii("fo:page-width"),sXML_CDATA,
1643 Double2Str(WTI(hwpinfo->paper.paper_width)) + ascii("inch"));
1644 padd(ascii("fo:page-height"),sXML_CDATA,
1645 Double2Str(WTI(hwpinfo->paper.paper_height)) + ascii("inch"));
1647 break;
1651 padd(ascii("style:print-orientation"),sXML_CDATA,
1652 ascii(hwpinfo->paper.paper_direction ? "landscape" : "portrait"));
1653 if( hwpinfo->beginpagenum != 1)
1654 padd(ascii("style:first-page-number"),sXML_CDATA,
1655 ascii(Int2Str(hwpinfo->beginpagenum, "%d", buf)));
1657 if( hwpinfo->borderline ){
1658 padd(ascii("fo:margin-left"),sXML_CDATA,
1659 Double2Str(WTI(hwpinfo->paper.left_margin - hwpinfo->bordermargin[0] + hwpinfo->paper.gutter_length)) + ascii("inch"));
1660 padd(ascii("fo:margin-right"),sXML_CDATA,
1661 Double2Str(WTI(hwpinfo->paper.right_margin - hwpinfo->bordermargin[1])) + ascii("inch"));
1662 padd(ascii("fo:margin-top"),sXML_CDATA,
1663 Double2Str(WTI(hwpinfo->paper.top_margin - hwpinfo->bordermargin[2])) + ascii("inch"));
1664 padd(ascii("fo:margin-bottom"),sXML_CDATA,
1665 Double2Str(WTI(hwpinfo->paper.bottom_margin - hwpinfo->bordermargin[3])) + ascii("inch"));
1667 else{
1668 padd(ascii("fo:margin-left"),sXML_CDATA,
1669 Double2Str(WTI(hwpinfo->paper.left_margin + hwpinfo->paper.gutter_length)) + ascii("inch"));
1670 padd(ascii("fo:margin-right"),sXML_CDATA,
1671 Double2Str(WTI(hwpinfo->paper.right_margin)) + ascii("inch"));
1672 padd(ascii("fo:margin-top"),sXML_CDATA,
1673 Double2Str(WTI(hwpinfo->paper.top_margin)) + ascii("inch"));
1674 padd(ascii("fo:margin-bottom"),sXML_CDATA,
1675 Double2Str(WTI(hwpinfo->paper.bottom_margin)) + ascii("inch"));
1678 switch( hwpinfo->borderline )
1680 case 1:
1681 padd(ascii("fo:border"), sXML_CDATA,ascii("0.002cm solid #000000"));
1682 break;
1683 case 3:
1684 padd(ascii("fo:border"), sXML_CDATA,ascii("0.002cm dotted #000000"));
1685 break;
1686 case 2:
1687 padd(ascii("fo:border"), sXML_CDATA,ascii("0.035cm solid #000000"));
1688 break;
1689 case 4:
1690 padd(ascii("style:border-line-width"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1691 padd(ascii("fo:border"), sXML_CDATA,ascii("0.039cm double #000000"));
1692 break;
1695 padd(ascii("fo:padding-left"), sXML_CDATA,
1696 Double2Str(WTI(hwpinfo->bordermargin[0])) + ascii("inch"));
1697 padd(ascii("fo:padding-right"), sXML_CDATA,
1698 Double2Str(WTI(hwpinfo->bordermargin[1])) + ascii("inch"));
1699 padd(ascii("fo:padding-top"), sXML_CDATA,
1700 Double2Str(WTI(hwpinfo->bordermargin[2])) + ascii("inch"));
1701 padd(ascii("fo:padding-bottom"), sXML_CDATA,
1702 Double2Str(WTI(hwpinfo->bordermargin[3])) + ascii("inch"));
1704 /* background color */
1705 if( hwpinfo->back_info.isset )
1707 if( hwpinfo->back_info.color[0] > 0 || hwpinfo->back_info.color[1] > 0
1708 || hwpinfo->back_info.color[2] > 0 ){
1709 sprintf(buf,"#%02x%02x%02x",hwpinfo->back_info.color[0],
1710 hwpinfo->back_info.color[1],hwpinfo->back_info.color[2] );
1711 padd(ascii("fo:background-color"), sXML_CDATA, ascii(buf));
1715 rstartEl(ascii("style:properties"),rList);
1716 pList->clear();
1718 /* background image */
1719 if( hwpinfo->back_info.isset && hwpinfo->back_info.type > 0 )
1721 if( hwpinfo->back_info.type == 1 ){
1722 #ifdef _WIN32
1723 padd(ascii("xlink:href"), sXML_CDATA,
1724 hconv(kstr2hstr((uchar*) urltowin(hwpinfo->back_info.filename).c_str()).c_str()));
1725 #else
1726 padd(ascii("xlink:href"), sXML_CDATA,
1727 hconv(kstr2hstr( (uchar *)urltounix(hwpinfo->back_info.filename).c_str()).c_str()));
1728 #endif
1729 padd(ascii("xlink:type"), sXML_CDATA, ascii("simple"));
1730 padd(ascii("xlink:actuate"), sXML_CDATA, ascii("onLoad"));
1732 if( hwpinfo->back_info.flag >= 2)
1733 padd(ascii("style:repeat"), sXML_CDATA, ascii("stretch"));
1734 else if( hwpinfo->back_info.flag == 1 ){
1735 padd(ascii("style:repeat"), sXML_CDATA, ascii("no-repeat"));
1736 padd(ascii("style:position"), sXML_CDATA, ascii("center"));
1738 rstartEl(ascii("style:background-image"),rList);
1740 if( hwpinfo->back_info.type == 2 ){
1741 rstartEl(ascii("office:binary-data"), rList);
1742 pList->clear();
1743 boost::shared_ptr<char> pStr(base64_encode_string((unsigned char *) hwpinfo->back_info.data, hwpinfo->back_info.size ), Free<char>());
1744 rchars(ascii(pStr.get()));
1745 rendEl(ascii("office:binary-data"));
1747 rendEl(ascii("style:background-image"));
1750 makeColumns( hwpfile.GetColumnDef(i) );
1752 rendEl(ascii("style:properties"));
1754 /* header style */
1755 rstartEl(ascii("style:header-style"), rList);
1756 padd(ascii("svg:height"), sXML_CDATA,
1757 Double2Str(WTI(hwpinfo->paper.header_length)) + ascii("inch"));
1758 padd(ascii("fo:margin-bottom"), sXML_CDATA, ascii("0mm"));
1760 rstartEl(ascii("style:properties"),rList);
1761 pList->clear();
1762 rendEl(ascii("style:properties"));
1763 rendEl(ascii("style:header-style"));
1765 /* footer style */
1766 rstartEl(ascii("style:footer-style"), rList);
1767 padd(ascii("svg:height"), sXML_CDATA,
1768 Double2Str(WTI(hwpinfo->paper.footer_length)) + ascii("inch"));
1769 padd(ascii("fo:margin-top"), sXML_CDATA, ascii("0mm"));
1770 rstartEl(ascii("style:properties"),rList);
1771 pList->clear();
1772 rendEl(ascii("style:properties"));
1773 rendEl(ascii("style:footer-style"));
1775 /* footnote style 이건 dtd에서는 빠졌으나, 스펙에는 정의되어 있다. REALKING */
1776 rstartEl(ascii("style:footnote-layout"), rList);
1778 padd(ascii("style:distance-before-sep"), sXML_CDATA,
1779 Double2Str(WTI(hwpinfo->splinetext)) + ascii("inch"));
1780 padd(ascii("style:distance-after-sep"), sXML_CDATA,
1781 Double2Str(WTI(hwpinfo->splinefn)) + ascii("inch"));
1782 rstartEl(ascii("style:properties"),rList);
1783 pList->clear();
1784 rendEl(ascii("style:properties"));
1785 if ( hwpinfo->fnlinetype == 2 )
1786 padd(ascii("style:width"), sXML_CDATA, ascii("15cm"));
1787 else if ( hwpinfo->fnlinetype == 1)
1788 padd(ascii("style:width"), sXML_CDATA, ascii("2cm"));
1789 else if ( hwpinfo->fnlinetype == 3)
1790 padd(ascii("style:width"), sXML_CDATA, ascii("0cm"));
1791 else
1792 padd(ascii("style:width"), sXML_CDATA, ascii("5cm"));
1794 rstartEl(ascii("style:footnote-sep"),rList);
1795 pList->clear();
1796 rendEl(ascii("style:footnote-sep"));
1798 rendEl(ascii("style:footnote-layout"));
1800 rendEl(ascii("style:page-master"));
1804 void HwpReader::makeColumns(ColumnDef *coldef)
1806 if( !coldef ) return;
1807 padd(ascii("fo:column-count"), sXML_CDATA, ascii(Int2Str(coldef->ncols, "%d", buf)));
1808 rstartEl(ascii("style:columns"),rList);
1809 pList->clear();
1810 if( coldef->separator != 0 )
1812 switch( coldef->separator )
1814 case 1: /* 얇은선 */
1815 padd(ascii("style:width"), sXML_CDATA, ascii("0.02mm"));
1816 case 3: /* 점선 */
1817 padd(ascii("style:style"), sXML_CDATA, ascii("dotted"));
1818 padd(ascii("style:width"), sXML_CDATA, ascii("0.02mm"));
1819 break;
1820 case 2: /* 두꺼운선 */
1821 case 4: /* 2중선 */
1822 padd(ascii("style:width"), sXML_CDATA, ascii("0.35mm"));
1823 break;
1824 case 0: /* 없음 */
1825 default:
1826 padd(ascii("style:style"), sXML_CDATA, ascii("none"));
1827 break;
1829 rstartEl(ascii("style:column-sep"),rList);
1830 pList->clear();
1831 rendEl(ascii("style:column-sep"));
1833 double spacing = WTI(coldef->spacing)/ 2. ;
1834 for(int ii = 0 ; ii < coldef->ncols ; ii++)
1836 if( ii == 0 )
1837 padd(ascii("fo:margin-left"), sXML_CDATA, ascii("0mm"));
1838 else
1839 padd(ascii("fo:margin-left"), sXML_CDATA,
1840 Double2Str( spacing) + ascii("inch"));
1841 if( ii == ( coldef->ncols -1) )
1842 padd(ascii("fo:margin-right"), sXML_CDATA,ascii("0mm"));
1843 else
1844 padd(ascii("fo:margin-right"), sXML_CDATA,
1845 Double2Str( spacing) + ascii("inch"));
1846 rstartEl(ascii("style:column"),rList);
1847 pList->clear();
1848 rendEl(ascii("style:column"));
1850 rendEl(ascii("style:columns"));
1853 void HwpReader::makeTStyle(CharShape * cshape)
1855 padd(ascii("style:name"), sXML_CDATA,
1856 ascii(Int2Str(cshape->index, "T%d", buf)));
1857 padd(ascii("style:family"), sXML_CDATA, ascii("text"));
1858 rstartEl(ascii("style:style"), rList);
1859 pList->clear();
1860 parseCharShape(cshape);
1861 rstartEl(ascii("style:properties"), rList);
1862 pList->clear();
1863 rendEl(ascii("style:properties"));
1864 rendEl(ascii("style:style"));
1868 void HwpReader::makeTableStyle(Table *tbl)
1870 // --------------- table ---------------- //
1871 TxtBox *hbox = tbl->box;
1873 padd(ascii("style:name"), sXML_CDATA,
1874 ascii(Int2Str(hbox->style.boxnum, "Table%d", buf)));
1875 padd(ascii("style:family"), sXML_CDATA,ascii("table"));
1876 rstartEl(ascii("style:style"), rList);
1877 pList->clear();
1878 padd(ascii("style:width"), sXML_CDATA,
1879 Double2Str(WTMM(hbox->box_xs)) + ascii("mm"));
1880 padd(ascii("table:align"), sXML_CDATA,ascii("left"));
1881 padd(ascii("fo:keep-with-next"), sXML_CDATA,ascii("false"));
1882 rstartEl(ascii("style:properties"), rList);
1883 pList->clear();
1884 rendEl(ascii("style:properties"));
1885 rendEl(ascii("style:style"));
1887 // --------------- column ---------------- //
1888 for (size_t i = 0 ; i < tbl->columns.nCount -1 ; i++)
1890 sprintf(buf,"Table%d.%c",hbox->style.boxnum, static_cast<char>('A'+i));
1891 padd(ascii("style:name"), sXML_CDATA, ascii( buf ));
1892 padd(ascii("style:family"), sXML_CDATA,ascii("table-column"));
1893 rstartEl(ascii("style:style"), rList);
1894 pList->clear();
1895 padd(ascii("style:column-width"), sXML_CDATA,
1896 Double2Str(WTMM(tbl->columns.data[i+1] - tbl->columns.data[i])) + ascii("mm"));
1897 rstartEl(ascii("style:properties"), rList);
1898 pList->clear();
1899 rendEl(ascii("style:properties"));
1900 rendEl(ascii("style:style"));
1903 // --------------- row ---------------- //
1904 for (size_t i = 0 ; i < tbl->rows.nCount -1 ; i++)
1906 sprintf(buf,"Table%d.row%" SAL_PRI_SIZET "u",hbox->style.boxnum, i + 1);
1907 padd(ascii("style:name"), sXML_CDATA, ascii( buf ));
1908 padd(ascii("style:family"), sXML_CDATA,ascii("table-row"));
1909 rstartEl(ascii("style:style"), rList);
1910 pList->clear();
1911 padd(ascii("style:row-height"), sXML_CDATA,
1912 Double2Str(WTMM(tbl->rows.data[i+1] - tbl->rows.data[i])) + ascii("mm"));
1913 rstartEl(ascii("style:properties"), rList);
1914 pList->clear();
1915 rendEl(ascii("style:properties"));
1916 rendEl(ascii("style:style"));
1919 // --------------- cell --------------------- //
1920 for (int i = 0 ; i < static_cast<int>(tbl->cells.size()); i++)
1922 std::list<TCell*>::iterator it = tbl->cells.begin();
1924 for( int ii = 0; it != tbl->cells.end(); ++it, ii++ ){
1925 if( ii == i )
1926 break;
1929 TCell *tcell = *it;
1930 sprintf(buf,"Table%d.%c%d",hbox->style.boxnum, 'A'+ tcell->nColumnIndex, tcell->nRowIndex +1);
1931 padd(ascii("style:name"), sXML_CDATA, ascii( buf ));
1932 padd(ascii("style:family"), sXML_CDATA,ascii("table-cell"));
1933 rstartEl(ascii("style:style"), rList);
1934 pList->clear();
1935 Cell *cl = tcell->pCell;
1936 if( cl->ver_align == 1 )
1937 padd(ascii("fo:vertical-align"), sXML_CDATA,ascii("middle"));
1939 if(cl->linetype[2] == cl->linetype[3] && cl->linetype[2] == cl->linetype[0]
1940 && cl->linetype[2] == cl->linetype[1])
1942 switch( cl->linetype[2] )
1944 case 1: /* 가는실선 */
1945 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
1946 padd(ascii("fo:border"), sXML_CDATA,ascii("0.002cm solid #000000"));
1947 break;
1948 case 2: /* 굵은실선 */
1949 padd(ascii("fo:border"), sXML_CDATA,ascii("0.035cm solid #000000"));
1950 break;
1951 case 4: /* 2중선 */
1952 padd(ascii("style:border-line-width"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1953 padd(ascii("fo:border"), sXML_CDATA,ascii("0.039cm double #000000"));
1954 break;
1957 else
1959 switch( cl->linetype[0] )
1961 case 1: /* 가는실선 */
1962 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
1963 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.002cm solid #000000"));
1964 break;
1965 case 2: /* 굵은실선 */
1966 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.035cm solid #000000"));
1967 break;
1968 case 4: /* 2중선 */
1969 padd(ascii("style:border-line-width-left"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1970 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.039cm double #000000"));
1971 break;
1973 switch( cl->linetype[1] )
1975 case 1: /* 가는실선 */
1976 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
1977 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.002cm solid #000000"));
1978 break;
1979 case 2: /* 굵은실선 */
1980 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.035cm solid #000000"));
1981 break;
1982 case 4: /* 2중선 */
1983 padd(ascii("style:border-line-width-right"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1984 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.039cm double #000000"));
1985 break;
1987 switch( cl->linetype[2] )
1989 case 1: /* 가는실선 */
1990 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
1991 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.002cm solid #000000"));
1992 break;
1993 case 2: /* 굵은실선 */
1994 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.035cm solid #000000"));
1995 break;
1996 case 4: /* 2중선 */
1997 padd(ascii("style:border-line-width-top"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
1998 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.039cm double #000000"));
1999 break;
2001 switch( cl->linetype[3] )
2003 case 1: /* 가는실선 */
2004 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2005 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.002cm solid #000000"));
2006 break;
2007 case 2: /* 굵은실선 */
2008 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.035cm solid #000000"));
2009 break;
2010 case 4: /* 2중선 */
2011 padd(ascii("style:border-line-width-bottom"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2012 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.039cm double #000000"));
2013 break;
2016 if(cl->shade != 0)
2017 padd(ascii("fo:background-color"), sXML_CDATA,
2018 ascii(hcolor2str(sal::static_int_cast<uchar>(cl->color),
2019 sal::static_int_cast<uchar>(cl->shade), buf)));
2021 rstartEl(ascii("style:properties"), rList);
2022 pList->clear();
2023 rendEl(ascii("style:properties"));
2025 rendEl(ascii("style:style"));
2030 void HwpReader::makeDrawStyle( HWPDrawingObject * hdo, FBoxStyle * fstyle)
2032 while( hdo )
2034 padd(ascii("style:name"), sXML_CDATA,
2035 ascii(Int2Str(hdo->index, "Draw%d", buf)));
2036 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
2038 rstartEl(ascii("style:style"), rList);
2039 pList->clear();
2041 switch (fstyle->txtflow)
2043 case 0:
2044 break;
2045 case 1:
2046 padd(ascii("style:wrap"), sXML_CDATA, ascii("run-through"));
2047 break;
2048 case 2:
2049 padd(ascii("style:wrap"), sXML_CDATA, ascii("dynamic"));
2050 break;
2052 long color;
2053 // invisible line
2054 if( hdo->property.line_color > 0xffffff )
2056 padd(ascii("draw:stroke"), sXML_CDATA, ascii("none") );
2058 else
2061 if( hdo->property.line_pstyle == 0 )
2062 padd(ascii("draw:stroke"), sXML_CDATA, ascii("solid") );
2063 else if( hdo->property.line_pstyle < 5 )
2065 padd(ascii("draw:stroke"), sXML_CDATA, ascii("dash") );
2066 padd(ascii("draw:stroke-dash"), sXML_CDATA,
2067 ascii(Int2Str(hdo->index, "LineType%d", buf)));
2069 padd(ascii("svg:stroke-width"), sXML_CDATA,
2070 Double2Str( WTMM(hdo->property.line_width)) + ascii("mm" ));
2071 color = hdo->property.line_color;
2072 sprintf( buf, "#%02x%02x%02x",
2073 sal_uInt16(color & 0xff),
2074 sal_uInt16((color >> 8) & 0xff),
2075 sal_uInt16((color >>16) & 0xff) );
2076 padd(ascii("svg:stroke-color"), sXML_CDATA, ascii( buf) );
2079 if( hdo->type == HWPDO_LINE || hdo->type == HWPDO_ARC ||
2080 hdo->type == HWPDO_FREEFORM || hdo->type == HWPDO_ADVANCED_ARC )
2083 if( hdo->property.line_tstyle > 0 )
2085 padd(ascii("draw:marker-start"), sXML_CDATA,
2086 ascii(ArrowShape[hdo->property.line_tstyle].name) );
2087 if( hdo->property.line_width > 100 )
2088 padd(ascii("draw:marker-start-width"), sXML_CDATA,
2089 Double2Str( WTMM(hdo->property.line_width * 3)) + ascii("mm" ));
2090 else if( hdo->property.line_width > 80 )
2091 padd(ascii("draw:marker-start-width"), sXML_CDATA,
2092 Double2Str( WTMM(hdo->property.line_width * 4)) + ascii("mm" ));
2093 else if( hdo->property.line_width > 60 )
2094 padd(ascii("draw:marker-start-width"), sXML_CDATA,
2095 Double2Str( WTMM(hdo->property.line_width * 5)) + ascii("mm" ));
2096 else if( hdo->property.line_width > 40 )
2097 padd(ascii("draw:marker-start-width"), sXML_CDATA,
2098 Double2Str( WTMM(hdo->property.line_width * 6)) + ascii("mm" ));
2099 else
2100 padd(ascii("draw:marker-start-width"), sXML_CDATA,
2101 Double2Str( WTMM(hdo->property.line_width * 7)) + ascii("mm" ));
2104 if( hdo->property.line_hstyle > 0 )
2106 padd(ascii("draw:marker-end"), sXML_CDATA,
2107 ascii(ArrowShape[hdo->property.line_hstyle].name) );
2108 if( hdo->property.line_width > 100 )
2109 padd(ascii("draw:marker-end-width"), sXML_CDATA,
2110 Double2Str( WTMM(hdo->property.line_width * 3)) + ascii("mm" ));
2111 else if( hdo->property.line_width > 80 )
2112 padd(ascii("draw:marker-end-width"), sXML_CDATA,
2113 Double2Str( WTMM(hdo->property.line_width * 4)) + ascii("mm" ));
2114 else if( hdo->property.line_width > 60 )
2115 padd(ascii("draw:marker-end-width"), sXML_CDATA,
2116 Double2Str( WTMM(hdo->property.line_width * 5)) + ascii("mm" ));
2117 else if( hdo->property.line_width > 40 )
2118 padd(ascii("draw:marker-end-width"), sXML_CDATA,
2119 Double2Str( WTMM(hdo->property.line_width * 6)) + ascii("mm" ));
2120 else
2121 padd(ascii("draw:marker-end-width"), sXML_CDATA,
2122 Double2Str( WTMM(hdo->property.line_width * 7)) + ascii("mm" ));
2126 if(hdo->type != HWPDO_LINE )
2128 if( hdo->property.flag >> 19 & 0x01 )
2130 padd( ascii("draw:textarea-horizontal-align"), sXML_CDATA, ascii("center"));
2133 color = hdo->property.fill_color;
2135 if( hdo->property.flag >> 18 & 0x01 ) // bitmap pattern
2137 padd(ascii("draw:fill"), sXML_CDATA, ascii("bitmap"));
2138 padd(ascii("draw:fill-image-name"), sXML_CDATA,
2139 ascii(Int2Str(hdo->index, "fillimage%d", buf)));
2140 // bitmap resizing
2141 if( hdo->property.flag >> 3 & 0x01 )
2143 padd(ascii("style:repeat"), sXML_CDATA, ascii("stretch"));
2145 else
2147 padd(ascii("style:repeat"), sXML_CDATA, ascii("repeat"));
2148 padd(ascii("draw:fill-image-ref-point"), sXML_CDATA, ascii("top-left"));
2150 if( hdo->property.flag >> 20 & 0x01 )
2152 if( hdo->property.luminance > 0 )
2154 padd(ascii("draw:transparency"), sXML_CDATA,
2155 ascii(Int2Str(hdo->property.luminance, "%d%%", buf)));
2160 // Gradation
2161 else if( hdo->property.flag >> 16 & 0x01 )
2163 padd(ascii("draw:fill"), sXML_CDATA, ascii("gradient"));
2164 padd(ascii("draw:fill-gradient-name"), sXML_CDATA,
2165 ascii(Int2Str(hdo->index, "Grad%d", buf)));
2166 padd(ascii("draw:gradient-step-count"), sXML_CDATA,
2167 ascii(Int2Str(hdo->property.nstep, "%d", buf)));
2170 // Hatching
2171 else if( hdo->property.pattern_type >> 24 & 0x01 )
2173 padd(ascii("draw:fill"), sXML_CDATA, ascii("hatch"));
2174 padd(ascii("draw:fill-hatch-name"), sXML_CDATA,
2175 ascii(Int2Str(hdo->index, "Hatch%d", buf)));
2176 if( color < 0xffffff )
2178 sprintf( buf, "#%02x%02x%02x",
2179 sal_uInt16(color & 0xff),
2180 sal_uInt16((color >> 8) & 0xff),
2181 sal_uInt16((color >>16) & 0xff) );
2182 padd(ascii("draw:fill-color"), sXML_CDATA, ascii( buf) );
2183 padd(ascii("draw:fill-hatch-solid"), sXML_CDATA, ascii("true"));
2186 else if( color <= 0xffffff )
2188 padd(ascii("draw:fill"), sXML_CDATA, ascii("solid"));
2189 sprintf( buf, "#%02x%02x%02x",
2190 sal_uInt16(color & 0xff),
2191 sal_uInt16((color >> 8) & 0xff),
2192 sal_uInt16((color >>16) & 0xff) );
2193 padd(ascii("draw:fill-color"), sXML_CDATA, ascii( buf) );
2195 else
2196 padd(ascii("draw:fill"), sXML_CDATA, ascii("none"));
2199 if( fstyle->anchor_type == CHAR_ANCHOR )
2201 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("top"));
2202 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("baseline"));
2205 rstartEl(ascii("style:properties"), rList);
2206 pList->clear();
2207 rendEl(ascii("style:properties"));
2208 rendEl(ascii("style:style"));
2210 if( hdo->type == 0 )
2212 makeDrawStyle( hdo->child, fstyle );
2214 hdo = hdo->next;
2219 void HwpReader::makeCaptionStyle(FBoxStyle * fstyle)
2221 padd(ascii("style:name"), sXML_CDATA,
2222 ascii(Int2Str(fstyle->boxnum, "CapBox%d", buf)));
2223 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
2224 rstartEl(ascii("style:style"), rList);
2225 pList->clear();
2226 padd(ascii("fo:margin-left"), sXML_CDATA, ascii("0cm"));
2227 padd(ascii("fo:margin-right"), sXML_CDATA, ascii("0cm"));
2228 padd(ascii("fo:margin-top"), sXML_CDATA, ascii("0cm"));
2229 padd(ascii("fo:margin-bottom"), sXML_CDATA, ascii("0cm"));
2230 padd(ascii("fo:padding"), sXML_CDATA, ascii("0cm"));
2231 switch (fstyle->txtflow)
2233 case 0:
2234 padd(ascii("style:wrap"), sXML_CDATA, ascii("none"));
2235 break;
2236 case 1:
2237 if( fstyle->boxtype == 'G' )
2238 padd(ascii("style:run-through"), sXML_CDATA, ascii("background"));
2239 padd(ascii("style:wrap"), sXML_CDATA, ascii("run-through"));
2240 break;
2241 case 2:
2242 padd(ascii("style:wrap"), sXML_CDATA, ascii("dynamic"));
2243 break;
2245 if (fstyle->anchor_type == CHAR_ANCHOR)
2247 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("top"));
2248 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("baseline"));
2249 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("center"));
2250 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
2252 else
2255 switch (-(fstyle->xpos))
2257 case 2:
2258 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("right"));
2259 break;
2260 case 3:
2261 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("center"));
2262 break;
2263 case 1:
2264 default:
2265 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("from-left"));
2266 break;
2268 switch (-(fstyle->ypos))
2270 case 2:
2271 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("bottom"));
2272 break;
2273 case 3:
2274 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("middle"));
2275 break;
2276 case 1:
2277 default:
2278 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("from-top"));
2279 break;
2281 if ( fstyle->anchor_type == PARA_ANCHOR )
2283 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("paragraph"));
2284 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
2286 else
2288 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("page-content"));
2289 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("page-content"));
2292 rstartEl(ascii("style:properties"), rList);
2293 pList->clear();
2294 rendEl(ascii("style:properties"));
2295 rendEl(ascii("style:style"));
2296 if( fstyle->boxtype == 'G' )
2298 padd(ascii("style:name"), sXML_CDATA,
2299 ascii(Int2Str(fstyle->boxnum, "G%d", buf)));
2301 else
2303 padd(ascii("style:name"), sXML_CDATA,
2304 ascii(Int2Str(fstyle->boxnum, "Txtbox%d", buf)));
2307 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
2308 rstartEl(ascii("style:style"), rList);
2309 pList->clear();
2311 padd(ascii("fo:margin-left"), sXML_CDATA, ascii("0cm"));
2312 padd(ascii("fo:margin-right"), sXML_CDATA, ascii("0cm"));
2313 padd(ascii("fo:margin-top"), sXML_CDATA, ascii("0cm"));
2314 padd(ascii("fo:margin-bottom"), sXML_CDATA, ascii("0cm"));
2315 padd(ascii("fo:padding"), sXML_CDATA, ascii("0cm"));
2316 padd(ascii("style:wrap"), sXML_CDATA, ascii("none"));
2317 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("from-top"));
2318 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("paragraph"));
2319 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("from-left"));
2320 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
2321 if( fstyle->boxtype == 'G' )
2323 char *cell = (char *)fstyle->cell;
2324 padd(ascii("draw:luminance"), sXML_CDATA,
2325 ascii(Int2Str(cell[0], "%d%%", buf)));
2326 padd(ascii("draw:contrast"), sXML_CDATA,
2327 ascii(Int2Str(cell[1], "%d%%", buf)));
2328 if( cell[2] == 0 )
2329 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("standard"));
2330 else if( cell[2] == 1 )
2331 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("greyscale"));
2332 else if( cell[2] == 2 )
2333 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("mono"));
2335 else
2337 Cell *cell = (Cell *)fstyle->cell;
2338 if(cell->linetype[0] == cell->linetype[1] &&
2339 cell->linetype[0] == cell->linetype[2] &&
2340 cell->linetype[0] == cell->linetype[3])
2342 switch( cell->linetype[0] )
2344 case 0:
2345 padd(ascii("fo:padding"), sXML_CDATA,ascii("0mm"));
2346 break;
2347 case 1: /* 가는실선 */
2348 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2349 padd(ascii("fo:border"), sXML_CDATA,ascii("0.002cm solid #000000"));
2350 break;
2351 case 2: /* 굵은실선 */
2352 padd(ascii("fo:border"), sXML_CDATA,ascii("0.035cm solid #000000"));
2353 break;
2354 case 4: /* 2중선 */
2355 padd(ascii("style:border-line-width"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2356 padd(ascii("fo:border"), sXML_CDATA,ascii("0.039cm double #000000"));
2357 break;
2360 else
2362 switch( cell->linetype[0] )
2364 case 1: /* 가는실선 */
2365 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2366 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.002cm solid #000000"));
2367 break;
2368 case 2: /* 굵은실선 */
2369 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.035cm solid #000000"));
2370 break;
2371 case 4: /* 2중선 */
2372 padd(ascii("style:border-line-width-left"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2373 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.039cm double #000000"));
2374 break;
2376 switch( cell->linetype[1] )
2378 case 1: /* 가는실선 */
2379 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2380 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.002cm solid #000000"));
2381 break;
2382 case 2: /* 굵은실선 */
2383 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.035cm solid #000000"));
2384 break;
2385 case 4: /* 2중선 */
2386 padd(ascii("style:border-line-width-right"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2387 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.039cm double #000000"));
2388 break;
2390 switch( cell->linetype[2] )
2392 case 1: /* 가는실선 */
2393 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2394 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.002cm solid #000000"));
2395 break;
2396 case 2: /* 굵은실선 */
2397 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.035cm solid #000000"));
2398 break;
2399 case 4: /* 2중선 */
2400 padd(ascii("style:border-line-width-top"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2401 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.039cm double #000000"));
2402 break;
2404 switch( cell->linetype[3] )
2406 case 1: /* 가는실선 */
2407 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2408 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.002cm solid #000000"));
2409 break;
2410 case 2: /* 굵은실선 */
2411 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.035cm solid #000000"));
2412 break;
2413 case 4: /* 2중선 */
2414 padd(ascii("style:border-line-width-bottom"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2415 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.039cm double #000000"));
2416 break;
2419 if(cell->shade != 0)
2420 padd(ascii("fo:background-color"), sXML_CDATA, ascii(hcolor2str(
2421 sal::static_int_cast<uchar>(cell->color),
2422 sal::static_int_cast<uchar>(cell->shade), buf)));
2424 rstartEl(ascii("style:properties"), rList);
2425 pList->clear();
2426 rendEl(ascii("style:properties"));
2427 rendEl(ascii("style:style"));
2432 * Floating 객체에 대한 스타일을 만든다.
2434 void HwpReader::makeFStyle(FBoxStyle * fstyle)
2436 /* 캡션 exist */
2437 if( ( fstyle->boxtype == 'G' || fstyle->boxtype == 'X' ) && fstyle->cap_len > 0 )
2439 makeCaptionStyle(fstyle);
2440 return;
2442 switch( fstyle->boxtype )
2444 case 'X' : // txtbox
2445 case 'E' : // equation
2446 case 'B' : // button
2447 case 'O' : // other
2448 case 'T' : // table
2449 padd(ascii("style:name"), sXML_CDATA,
2450 ascii(Int2Str(fstyle->boxnum, "Txtbox%d", buf)));
2451 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
2452 break;
2453 case 'G' : // graphics
2454 padd(ascii("style:name"), sXML_CDATA,
2455 ascii(Int2Str(fstyle->boxnum, "G%d", buf)));
2456 padd(ascii("style:family"), sXML_CDATA, ascii("graphics"));
2457 break;
2458 case 'L' : // line TODO : all
2459 padd(ascii("style:name"), sXML_CDATA,
2460 ascii(Int2Str(fstyle->boxnum, "L%d", buf)));
2461 padd( ascii("style:family") , sXML_CDATA , ascii("paragraph") );
2462 break;
2465 rstartEl(ascii("style:style"), rList);
2466 pList->clear();
2468 if ( fstyle->boxtype == 'T')
2470 padd(ascii("fo:padding"), sXML_CDATA, ascii("0cm"));
2473 if( !(fstyle->boxtype == 'G' && fstyle->cap_len > 0 ))
2475 padd(ascii("fo:margin-left"), sXML_CDATA,
2476 Double2Str(WTMM(fstyle->margin[0][0]) ) + ascii("mm"));
2477 padd(ascii("fo:margin-right"), sXML_CDATA,
2478 Double2Str(WTMM(fstyle->margin[0][1])) + ascii("mm"));
2479 padd(ascii("fo:margin-top"), sXML_CDATA,
2480 Double2Str(WTMM(fstyle->margin[0][2])) + ascii("mm"));
2481 padd(ascii("fo:margin-bottom"), sXML_CDATA,
2482 Double2Str(WTMM(fstyle->margin[0][3])) + ascii("mm"));
2485 switch (fstyle->txtflow)
2487 case 0:
2488 padd(ascii("style:wrap"), sXML_CDATA, ascii("none"));
2489 break;
2490 case 1:
2491 if( fstyle->boxtype == 'G' || fstyle->boxtype == 'B' || fstyle->boxtype == 'O')
2492 padd(ascii("style:run-through"), sXML_CDATA, ascii("background"));
2493 padd(ascii("style:wrap"), sXML_CDATA, ascii("run-through"));
2494 break;
2495 case 2:
2496 padd(ascii("style:wrap"), sXML_CDATA, ascii("dynamic"));
2497 break;
2499 if (fstyle->anchor_type == CHAR_ANCHOR)
2501 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("top"));
2502 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("baseline"));
2503 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("center"));
2504 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
2506 else
2509 switch (-(fstyle->xpos))
2511 case 2:
2512 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("right"));
2513 break;
2514 case 3:
2515 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("center"));
2516 break;
2517 case 1:
2518 default:
2519 padd(ascii("style:horizontal-pos"), sXML_CDATA, ascii("from-left"));
2520 break;
2522 switch (-(fstyle->ypos))
2524 case 2:
2525 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("bottom"));
2526 break;
2527 case 3:
2528 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("middle"));
2529 break;
2530 case 1:
2531 default:
2532 padd(ascii("style:vertical-pos"), sXML_CDATA, ascii("from-top"));
2533 break;
2535 if ( fstyle->anchor_type == PARA_ANCHOR )
2537 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("paragraph"));
2538 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("paragraph"));
2540 else
2542 padd(ascii("style:vertical-rel"), sXML_CDATA, ascii("page-content"));
2543 padd(ascii("style:horizontal-rel"), sXML_CDATA, ascii("page-content"));
2546 if( fstyle->boxtype == 'X' || fstyle->boxtype == 'B' )
2548 Cell *cell = (Cell *)fstyle->cell;
2549 if(cell->linetype[0] == cell->linetype[1] &&
2550 cell->linetype[0] == cell->linetype[2] &&
2551 cell->linetype[0] == cell->linetype[3])
2553 switch( cell->linetype[0] )
2555 case 0:
2556 padd(ascii("fo:border"), sXML_CDATA, ascii("none"));
2557 break;
2558 case 1: /* 가는실선 */
2559 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2560 padd(ascii("fo:border"), sXML_CDATA,ascii("0.002cm solid #000000"));
2561 break;
2562 case 2: /* 굵은실선 */
2563 padd(ascii("fo:border"), sXML_CDATA,ascii("0.035cm solid #000000"));
2564 break;
2565 case 4: /* 2중선 */
2566 padd(ascii("style:border-line-width"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2567 padd(ascii("fo:border"), sXML_CDATA,ascii("0.039cm double #000000"));
2568 break;
2571 else
2573 switch( cell->linetype[0] )
2575 case 1: /* 가는실선 */
2576 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2577 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.002cm solid #000000"));
2578 break;
2579 case 2: /* 굵은실선 */
2580 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.035cm solid #000000"));
2581 break;
2582 case 4: /* 2중선 */
2583 padd(ascii("style:border-line-width-left"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2584 padd(ascii("fo:border-left"), sXML_CDATA,ascii("0.039cm double #000000"));
2585 break;
2587 switch( cell->linetype[1] )
2589 case 1: /* 가는실선 */
2590 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2591 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.002cm solid #000000"));
2592 break;
2593 case 2: /* 굵은실선 */
2594 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.035cm solid #000000"));
2595 break;
2596 case 4: /* 2중선 */
2597 padd(ascii("style:border-line-width-right"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2598 padd(ascii("fo:border-right"), sXML_CDATA,ascii("0.039cm double #000000"));
2599 break;
2601 switch( cell->linetype[2] )
2603 case 1: /* 가는실선 */
2604 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2605 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.002cm solid #000000"));
2606 break;
2607 case 2: /* 굵은실선 */
2608 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.035cm solid #000000"));
2609 break;
2610 case 4: /* 2중선 */
2611 padd(ascii("style:border-line-width-top"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2612 padd(ascii("fo:border-top"), sXML_CDATA,ascii("0.039cm double #000000"));
2613 break;
2615 switch( cell->linetype[3] )
2617 case 1: /* 가는실선 */
2618 case 3: /* 점선 -> 스타오피스에는 점선이 없다. */
2619 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.002cm solid #000000"));
2620 break;
2621 case 2: /* 굵은실선 */
2622 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.035cm solid #000000"));
2623 break;
2624 case 4: /* 2중선 */
2625 padd(ascii("style:border-line-width-bottom"), sXML_CDATA,ascii("0.002cm 0.035cm 0.002cm"));
2626 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.039cm double #000000"));
2627 break;
2631 if( cell->linetype[0] == 0 && cell->linetype[1] == 0 &&
2632 cell->linetype[2] == 0 && cell->linetype[3] == 0 ){
2633 padd(ascii("fo:padding"), sXML_CDATA,ascii("0mm"));
2635 else{
2636 padd(ascii("fo:padding-left"), sXML_CDATA,
2637 Double2Str(WTMM(fstyle->margin[1][0])) + ascii("mm"));
2638 padd(ascii("fo:padding-right"), sXML_CDATA,
2639 Double2Str(WTMM(fstyle->margin[1][1])) + ascii("mm"));
2640 padd(ascii("fo:padding-top"), sXML_CDATA,
2641 Double2Str(WTMM(fstyle->margin[1][2])) + ascii("mm"));
2642 padd(ascii("fo:padding-bottom"), sXML_CDATA,
2643 Double2Str(WTMM(fstyle->margin[1][3])) + ascii("mm"));
2645 if(cell->shade != 0)
2646 padd(ascii("fo:background-color"), sXML_CDATA,
2647 ascii(hcolor2str(
2648 sal::static_int_cast<uchar>(cell->color),
2649 sal::static_int_cast<uchar>(cell->shade),
2650 buf)));
2652 else if( fstyle->boxtype == 'E' )
2654 padd(ascii("fo:padding"), sXML_CDATA,ascii("0mm"));
2656 else if( fstyle->boxtype == 'L' )
2658 padd( ascii("style:border-line-width-bottom"), sXML_CDATA, ascii("0.02mm 0.35mm 0.02mm"));
2659 padd(ascii("fo:border-bottom"), sXML_CDATA,ascii("0.039cm double #808080"));
2661 else if( fstyle->boxtype == 'G' )
2663 if( fstyle->margin[1][0] || fstyle->margin[1][1] || fstyle->margin[1][2] || fstyle->margin[1][3] ){
2664 OUString clip = ascii("rect(");
2665 clip += Double2Str(WTMM(-fstyle->margin[1][0]) ) + ascii("mm ");
2666 clip += Double2Str(WTMM(-fstyle->margin[1][1]) ) + ascii("mm ");
2667 clip += Double2Str(WTMM(-fstyle->margin[1][2]) ) + ascii("mm ");
2668 clip += Double2Str(WTMM(-fstyle->margin[1][3]) ) + ascii("mm)");
2669 padd(ascii("style:mirror"), sXML_CDATA, ascii("none"));
2670 padd(ascii("fo:clip"), sXML_CDATA, clip);
2672 char *cell = (char *)fstyle->cell;
2673 padd(ascii("draw:luminance"), sXML_CDATA,
2674 ascii(Int2Str(cell[0], "%d%%", buf)));
2675 padd(ascii("draw:contrast"), sXML_CDATA,
2676 ascii(Int2Str(cell[1], "%d%%", buf)));
2677 if( cell[2] == 0 )
2678 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("standard"));
2679 else if( cell[2] == 1 )
2680 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("greyscale"));
2681 else if( cell[2] == 2 )
2682 padd(ascii("draw:color-mode"), sXML_CDATA, ascii("mono"));
2685 rstartEl(ascii("style:properties"), rList);
2686 pList->clear();
2687 rendEl(ascii("style:properties"));
2688 rendEl(ascii("style:style"));
2692 char *HwpReader::getTStyleName(int index, char *_buf)
2694 return Int2Str(index, "T%d", _buf);
2698 char *HwpReader::getPStyleName(int index, char *_buf)
2700 return Int2Str(index, "P%d", _buf);
2704 void HwpReader::makeChars(hchar_string & rStr)
2706 rchars(OUString(rStr.c_str()));
2707 rStr.clear();
2712 * 문단내에 특수문자가 없고 모든 문자가 동일한 CharShape를 사용하는 경우
2714 void HwpReader::make_text_p0(HWPPara * para, sal_Bool bParaStart)
2716 hchar_string str;
2717 int n;
2718 int res;
2719 hchar dest[3];
2720 unsigned char firstspace = 0;
2721 if( !bParaStart)
2723 padd(ascii("text:style-name"), sXML_CDATA,
2724 ascii(getPStyleName(para->GetParaShape()->index, buf)));
2725 rstartEl(ascii("text:p"), rList);
2726 pList->clear();
2728 if( d->bFirstPara && d->bInBody )
2730 strcpy(buf,"[문서의 처음]"); /* "Begin of Document" */
2731 padd(ascii("text:name"), sXML_CDATA, OUString(buf, strlen(buf), RTL_TEXTENCODING_UTF8));
2732 rstartEl(ascii("text:bookmark"), rList);
2733 pList->clear();
2734 rendEl(ascii("text:bookmark"));
2735 d->bFirstPara = sal_False;
2737 if( d->bInHeader )
2739 makeShowPageNum();
2740 d->bInHeader = sal_False;
2742 padd(ascii("text:style-name"), sXML_CDATA,
2743 ascii(getTStyleName(para->cshape.index, buf)));
2744 rstartEl(ascii("text:span"), rList);
2745 pList->clear();
2747 for (n = 0; n < para->nch && para->hhstr[n]->hh;
2748 n += para->hhstr[n]->WSize())
2750 if (para->hhstr[n]->hh == CH_SPACE && !firstspace)
2752 makeChars(str);
2753 rstartEl(ascii("text:s"), rList);
2754 rendEl(ascii("text:s"));
2756 else if (para->hhstr[n]->hh == CH_END_PARA)
2758 makeChars(str);
2759 rendEl(ascii("text:span"));
2760 rendEl(ascii("text:p"));
2761 break;
2763 else
2765 if (para->hhstr[n]->hh == CH_SPACE)
2766 firstspace = 0;
2767 else
2768 firstspace = 1;
2769 res = hcharconv(para->hhstr[n]->hh, dest, UNICODE);
2770 for( int j = 0 ; j < res; j++ )
2772 str.push_back(dest[j]);
2780 * 문단내에 특수문자가 없으나 문자들이 다른 CharShape를 사용하는 경우
2782 void HwpReader::make_text_p1(HWPPara * para,sal_Bool bParaStart)
2784 hchar_string str;
2785 int n;
2786 int res;
2787 hchar dest[3];
2788 int curr = para->cshape.index;
2789 unsigned char firstspace = 0;
2791 if( !bParaStart )
2793 padd(ascii("text:style-name"), sXML_CDATA,
2794 ascii(getPStyleName(para->GetParaShape()->index, buf)));
2795 rstartEl(ascii("text:p"), rList);
2796 pList->clear();
2798 if( d->bFirstPara && d->bInBody )
2800 /* for HWP's Bookmark */
2801 strcpy(buf,"[문서의 처음]"); /* "Begin of Document" */
2802 padd(ascii("text:name"), sXML_CDATA, OUString(buf, strlen(buf), RTL_TEXTENCODING_UTF8));
2803 rstartEl(ascii("text:bookmark"), rList);
2804 pList->clear();
2805 rendEl(ascii("text:bookmark"));
2806 d->bFirstPara = sal_False;
2808 if( d->bInHeader )
2810 makeShowPageNum();
2811 d->bInHeader = sal_False;
2813 padd(ascii("text:style-name"), sXML_CDATA,
2814 ascii(getTStyleName(curr, buf)));
2815 rstartEl(ascii("text:span"), rList);
2816 pList->clear();
2818 for (n = 0; n < para->nch && para->hhstr[n]->hh;
2819 n += para->hhstr[n]->WSize())
2821 if (para->GetCharShape(n)->index != curr)
2823 makeChars(str);
2824 rendEl(ascii("text:span"));
2825 curr = para->GetCharShape(n)->index;
2826 padd(ascii("text:style-name"), sXML_CDATA,
2827 ascii(getTStyleName(curr, buf)));
2828 rstartEl(ascii("text:span"), rList);
2829 pList->clear();
2831 if (para->hhstr[n]->hh == CH_SPACE && !firstspace)
2833 makeChars(str);
2834 rstartEl(ascii("text:s"), rList);
2835 rendEl(ascii("text:s"));
2837 else if (para->hhstr[n]->hh == CH_END_PARA)
2839 makeChars(str);
2840 rendEl(ascii("text:span"));
2841 rendEl(ascii("text:p"));
2842 break;
2844 else
2846 if( para->hhstr[n]->hh < CH_SPACE )
2847 continue;
2848 if (para->hhstr[n]->hh == CH_SPACE)
2849 firstspace = 0;
2850 else
2851 firstspace = 1;
2852 res = hcharconv(para->hhstr[n]->hh, dest, UNICODE);
2853 for( int j = 0 ; j < res; j++ )
2855 str.push_back(dest[j]);
2863 * 문단 내의 특수문자가 있으며 문자들이 다른 CharShape를 갖는 경우에 대해 처리
2865 void HwpReader::make_text_p3(HWPPara * para,sal_Bool bParaStart)
2867 hchar_string str;
2868 int n, res;
2869 hchar dest[3];
2870 unsigned char firstspace = 0;
2871 bool pstart = bParaStart;
2872 bool tstart = false;
2873 bool infield = false;
2874 int curr = para->cshape.index;
2875 if( d->bFirstPara && d->bInBody )
2877 if( !pstart )
2878 STARTP;
2879 strcpy(buf,"[문서의 처음]"); /* "Begin of Document" */
2880 padd(ascii("text:name"), sXML_CDATA, OUString(buf, strlen(buf), RTL_TEXTENCODING_UTF8));
2881 rstartEl(ascii("text:bookmark"), rList);
2882 pList->clear();
2883 rendEl(ascii("text:bookmark"));
2884 d->bFirstPara = sal_False;
2886 if( d->bInHeader )
2888 if( !pstart )
2889 STARTP;
2890 makeShowPageNum();
2891 d->bInHeader = sal_False;
2894 for (n = 0; n < para->nch && para->hhstr[n]->hh;
2895 n += para->hhstr[n]->WSize())
2897 if( para->hhstr[n]->hh == CH_END_PARA )
2899 if (str.size() > 0)
2901 if( !pstart ){ STARTP;}
2902 if( !tstart ){ STARTT;}
2903 makeChars(str);
2905 if( tstart ){ ENDT;}
2906 if( !pstart ){ STARTP;}
2907 if( pstart ){ ENDP;}
2908 break;
2910 else if( para->hhstr[n]->hh == CH_SPACE && !firstspace)
2912 if( !pstart ) {STARTP;}
2913 if( !tstart ) {STARTT;}
2914 makeChars(str);
2915 rstartEl(ascii("text:s"), rList);
2916 pList->clear();
2917 rendEl(ascii("text:s"));
2919 else if ( para->hhstr[n]->hh >= CH_SPACE )
2921 if( n > 0 )
2922 if( para->GetCharShape(n)->index != para->GetCharShape(n-1)->index && !infield )
2924 if( !pstart ) {STARTP;}
2925 if( !tstart ) {STARTT;}
2926 makeChars(str);
2927 ENDT;
2929 if( para->hhstr[n]->hh == CH_SPACE )
2930 firstspace = 0;
2931 else
2932 firstspace = 1;
2933 res = hcharconv(para->hhstr[n]->hh, dest, UNICODE);
2934 for( int j = 0 ; j < res; j++ )
2936 str.push_back(dest[j]);
2939 else if (para->hhstr[n]->hh == CH_FIELD)
2941 FieldCode *hbox = (FieldCode *) para->hhstr[n];
2942 if( hbox->location_info == 1)
2944 if( !pstart ) {STARTP;}
2945 if( !tstart ) {STARTT;}
2946 makeChars(str);
2947 firstspace = 1;
2948 if( hbox->type[0] == 4 && hbox->type[1] == 0 )
2950 field = hbox->str3;
2952 else{
2953 makeFieldCode(str, hbox);
2955 infield = true;
2957 else
2959 firstspace = 1;
2960 if( hbox->type[0] == 4 && hbox->type[1] == 0 )
2962 makeFieldCode(str, hbox);
2963 field = 0L;
2965 infield = false;
2966 str.clear();
2969 else
2971 switch (para->hhstr[n]->hh)
2973 case CH_BOOKMARK:
2974 if( !pstart ) {STARTP;}
2975 if( !tstart ) {STARTT;}
2976 makeChars(str);
2977 makeBookmark((Bookmark *) para->hhstr[n]);
2978 break;
2979 case CH_DATE_FORM: // 7
2980 break;
2981 case CH_DATE_CODE: // 8
2982 if( !pstart ) {STARTP;}
2983 if( !tstart ) {STARTT;}
2984 makeChars(str);
2985 makeDateCode((DateCode *) para->hhstr[n]);
2986 break;
2987 case CH_TAB: // 9
2988 if( !pstart ) {STARTP;}
2989 if (str.size() > 0)
2991 if( !tstart ) {STARTT;}
2992 makeChars(str);
2994 makeTab((Tab *) para->hhstr[n]);
2995 break;
2996 case CH_TEXT_BOX: /* 10 - 표/텍스트박스/수식/버튼/하이퍼텍스트 순 */
2998 /* 일단은 표만 처리하고, 수식은 text:p안에 들어가는 것으로 처리. */
2999 TxtBox *hbox = (TxtBox *) para->hhstr[n];
3001 if( hbox->style.anchor_type == 0 )
3003 if( !pstart ) {STARTP;}
3004 if( !tstart ) {STARTT;}
3005 makeChars(str);
3007 else
3009 if( !pstart ) {STARTP;}
3010 if (str.size() > 0)
3012 if( !tstart ) {STARTT;}
3013 makeChars(str);
3015 if( tstart ) {ENDT;}
3017 switch (hbox->type)
3019 case TBL_TYPE: // table
3020 case TXT_TYPE: // text box
3021 case EQU_TYPE: // formula
3022 makeTextBox(hbox);
3023 break;
3024 case BUTTON_TYPE: // text button
3025 case HYPERTEXT_TYPE: // hypertext
3026 makeHyperText(hbox);
3027 break;
3029 break;
3031 case CH_PICTURE: // 11
3033 Picture *hbox = (Picture *) para->hhstr[n];
3034 if( hbox->style.anchor_type == 0 )
3036 if( !pstart ) {STARTP;}
3037 if( !tstart ) {STARTT;}
3038 makeChars(str);
3040 else
3042 if( !pstart ) {STARTP;}
3043 if (str.size() > 0)
3045 if( !tstart ) {STARTT;}
3046 makeChars(str);
3048 if( tstart ) {ENDT;}
3050 makePicture(hbox);
3051 break;
3053 case CH_LINE: // 14
3055 Line *hbox = (Line *) para->hhstr[n];
3056 if (str.size() > 0)
3058 if( !pstart ) {STARTP;}
3059 if( !tstart ) {STARTT;}
3060 makeChars(str);
3062 if( tstart ) {ENDT;}
3063 if( pstart ) {ENDP;}
3064 makeLine(hbox);
3065 pstart = true;
3066 break;
3068 case CH_HIDDEN: // 15
3069 if( !pstart ) {STARTP;}
3070 if( !tstart ) {STARTT;}
3071 makeChars(str);
3072 makeHidden((Hidden *) para->hhstr[n]);
3073 break;
3074 case CH_FOOTNOTE: // 17
3075 if( !pstart ) {STARTP;}
3076 if( !tstart ) {STARTT;}
3077 makeChars(str);
3078 makeFootnote((Footnote *) para->hhstr[n]);
3079 break;
3080 case CH_AUTO_NUM: // 18
3081 if( !pstart ) {STARTP;}
3082 if( !tstart ) {STARTT;}
3083 makeChars(str);
3084 makeAutoNum((AutoNum *) para->hhstr[n]);
3085 break;
3086 case CH_NEW_NUM: // 19 -skip
3087 break;
3088 case CH_PAGE_NUM_CTRL: // 21
3089 break;
3090 case CH_MAIL_MERGE: // 22
3091 if( !pstart ) {STARTP;}
3092 if( !tstart ) {STARTT;}
3093 makeChars(str);
3094 makeMailMerge((MailMerge *) para->hhstr[n]);
3095 break;
3096 case CH_COMPOSE: /* 23 - 글자겹침 */
3097 break;
3098 case CH_HYPHEN: // 24
3099 break;
3100 case CH_TOC_MARK: /* 25 아래의 3개는 작업해야 한다. */
3101 if( !pstart ) {STARTP;}
3102 if( !tstart ) {STARTT;}
3103 makeChars(str);
3104 makeTocMark((TocMark *) para->hhstr[n]);
3105 break;
3106 case CH_INDEX_MARK: // 26
3107 if( !pstart ) {STARTP;}
3108 if( !tstart ) {STARTT;}
3109 makeChars(str);
3110 makeIndexMark((IndexMark *) para->hhstr[n]);
3111 break;
3112 case CH_OUTLINE: // 28
3113 if( !pstart ) {STARTP;}
3114 if( !tstart ) {STARTT;}
3115 makeChars(str);
3116 makeOutline((Outline *) para->hhstr[n]);
3117 break;
3118 case CH_FIXED_SPACE:
3119 case CH_KEEP_SPACE:
3120 str.push_back(0x0020);
3121 break;
3128 void HwpReader::makeFieldCode(hchar_string & rStr, FieldCode *hbox)
3130 /* 누름틀 */
3131 if( hbox->type[0] == 4 && hbox->type[1] == 0 )
3133 padd(ascii("text:placeholder-type"), sXML_CDATA, ascii("text"));
3134 if( field )
3135 padd(ascii("text:description"), sXML_CDATA, hconv(field));
3136 rstartEl( ascii("text:placeholder"), rList);
3137 pList->clear();
3138 rchars( OUString(rStr.c_str()));
3139 rendEl( ascii("text:placeholder") );
3141 /* 문서요약 */
3142 else if( hbox->type[0] == 3 && hbox->type[1] == 0 )
3144 if (hconv(hbox->str3) == "title")
3146 rstartEl( ascii("text:title"), rList );
3147 rchars( hconv(hbox->str2) );
3148 rendEl( ascii("text:title") );
3150 else if (hconv(hbox->str3) == "subject")
3152 rstartEl( ascii("text:subject"), rList );
3153 rchars( hconv(hbox->str2) );
3154 rendEl( ascii("text:subject") );
3156 else if (hconv(hbox->str3) == "author")
3158 rstartEl( ascii("text:author-name"), rList );
3159 rchars( hconv(hbox->str2) );
3160 rendEl( ascii("text:author-name") );
3162 else if (hconv(hbox->str3) == "keywords")
3164 rstartEl( ascii("text:keywords"), rList );
3165 rchars( hconv(hbox->str2) );
3166 rendEl( ascii("text:keywords") );
3169 /* 개인정보 */
3170 else if( hbox->type[0] == 3 && hbox->type[1] == 1 )
3172 if (hconv(hbox->str3) == "User")
3174 rstartEl( ascii("text:sender-lastname"), rList );
3175 rchars( hconv(hbox->str2) );
3176 rendEl( ascii("text:sender-lastname") );
3178 else if (hconv(hbox->str3) == "Company")
3180 rstartEl( ascii("text:sender-company"), rList );
3181 rchars( hconv(hbox->str2) );
3182 rendEl( ascii("text:sender-company") );
3184 else if (hconv(hbox->str3) == "Position")
3186 rstartEl( ascii("text:sender-title"), rList );
3187 rchars( hconv(hbox->str2) );
3188 rendEl( ascii("text:sender-title") );
3190 else if (hconv(hbox->str3) == "Division")
3192 rstartEl( ascii("text:sender-position"), rList );
3193 rchars( hconv(hbox->str2) );
3194 rendEl( ascii("text:sender-position") );
3196 else if (hconv(hbox->str3) == "Fax")
3198 rstartEl( ascii("text:sender-fax"), rList );
3199 rchars( hconv(hbox->str2) );
3200 rendEl( ascii("text:sender-fax") );
3202 else if (hconv(hbox->str3) == "Pager")
3204 rstartEl( ascii("text:phone-private"), rList );
3205 rchars( hconv(hbox->str2) );
3206 rendEl( ascii("text:phone-private") );
3208 else if (hconv(hbox->str3) == "E-mail")
3210 rstartEl( ascii("text:sender-email"), rList );
3211 rchars( hconv(hbox->str2) );
3212 rendEl( ascii("text:sender-email") );
3214 else if (hconv(hbox->str3) == "Zipcode(office)")
3216 rstartEl( ascii("text:sender-postal-code"), rList );
3217 rchars( hconv(hbox->str2) );
3218 rendEl( ascii("text:sender-postal-code") );
3220 else if (hconv(hbox->str3) == "Phone(office)")
3222 rstartEl( ascii("text:sender-phone-work"), rList );
3223 rchars( hconv(hbox->str2) );
3224 rendEl( ascii("text:sender-phone-work") );
3226 else if (hconv(hbox->str3) == "Address(office)")
3228 rstartEl( ascii("text:sender-street"), rList );
3229 rchars( hconv(hbox->str2) );
3230 rendEl( ascii("text:sender-street") );
3234 else if( hbox->type[0] == 3 && hbox->type[1] == 2 ) /* 만든날짜 */
3236 if( hbox->m_pDate )
3237 padd(ascii("style:data-style-name"), sXML_CDATA,
3238 ascii(Int2Str(hbox->m_pDate->key, "N%d", buf)));
3239 rstartEl( ascii("text:creation-date"), rList );
3240 pList->clear();
3241 rchars( hconv(hbox->str2) );
3242 rendEl( ascii("text:creation-date") );
3248 * Completed
3249 * 스타오피스에서는 북마크를 Reference로 참조하나 hwp에는 그 기능이 없다.
3251 void HwpReader::makeBookmark(Bookmark * hbox)
3253 if (hbox->type == 0)
3255 padd(ascii("text:name"), sXML_CDATA, (hconv(hbox->id)));
3256 rstartEl(ascii("text:bookmark"), rList);
3257 pList->clear();
3258 rendEl(ascii("text:bookmark"));
3260 else if (hbox->type == 1) /* 블록 북마크일 경우 시작과 끝이 있다 */
3262 padd(ascii("text:name"), sXML_CDATA, (hconv(hbox->id)));
3263 rstartEl(ascii("text:bookmark-start"), rList);
3264 pList->clear();
3265 rendEl(ascii("text:bookmark-start"));
3267 else if (hbox->type == 2)
3269 padd(ascii("text:name"), sXML_CDATA, (hconv(hbox->id)));
3270 rstartEl(ascii("text:bookmark-end"), rList);
3271 pList->clear();
3272 rendEl(ascii("text:bookmark-end"));
3277 #include "datecode.h"
3279 void HwpReader::makeDateFormat(DateCode * hbox)
3281 padd(ascii("style:name"), sXML_CDATA,
3282 ascii(Int2Str(hbox->key, "N%d", buf)));
3283 padd(ascii("style:family"), sXML_CDATA,ascii("data-style"));
3284 padd(ascii("number:language"), sXML_CDATA,ascii("ko"));
3285 padd(ascii("number:country"), sXML_CDATA,ascii("KR"));
3287 rstartEl(ascii("number:date-style"), rList);
3288 pList->clear();
3290 bool add_zero = false;
3291 int zero_check = 0;
3292 hbox->format[DATE_SIZE -1] = 0;
3294 const hchar *fmt = hbox->format[0] ? hbox->format : defaultform;
3296 for( ; *fmt ; fmt++ )
3298 if( zero_check == 1 )
3300 zero_check = 0;
3302 else
3303 add_zero = false;
3305 switch( *fmt )
3307 case '0':
3308 zero_check = 1;
3309 add_zero = true;
3310 break;
3311 case '1':
3312 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3313 rstartEl(ascii("number:year"), rList);
3314 pList->clear();
3315 rendEl(ascii("number:year"));
3316 break;
3317 case '!':
3318 rstartEl(ascii("number:year"), rList);
3319 pList->clear();
3320 rendEl(ascii("number:year"));
3321 break;
3322 case '2':
3323 if( add_zero )
3324 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3325 rstartEl(ascii("number:month"), rList);
3326 pList->clear();
3327 rendEl(ascii("number:month"));
3328 break;
3329 case '@':
3330 padd(ascii("number:textual"), sXML_CDATA, ascii("true"));
3331 rstartEl(ascii("number:month"), rList);
3332 pList->clear();
3333 rendEl(ascii("number:month"));
3334 break;
3335 case '*':
3336 padd(ascii("number:textual"), sXML_CDATA, ascii("true"));
3337 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3338 rstartEl(ascii("number:month"), rList);
3339 pList->clear();
3340 rendEl(ascii("number:month"));
3341 break;
3342 case '3':
3343 if( add_zero )
3344 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3345 rstartEl(ascii("number:day"), rList);
3346 pList->clear();
3347 rendEl(ascii("number:day"));
3348 break;
3349 case '#':
3350 if( add_zero )
3351 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3352 rstartEl(ascii("number:day"), rList);
3353 pList->clear();
3354 rendEl(ascii("number:day"));
3355 switch( hbox->date[DateCode::DAY] % 10)
3357 case 1:
3358 rstartEl(ascii("number:text"), rList);
3359 rchars(ascii("st"));
3360 rendEl(ascii("number:text"));
3361 break;
3362 case 2:
3363 rstartEl(ascii("number:text"), rList);
3364 rchars(ascii("nd"));
3365 rendEl(ascii("number:text"));
3366 break;
3367 case 3:
3368 rstartEl(ascii("number:text"), rList);
3369 rchars(ascii("rd"));
3370 rendEl(ascii("number:text"));
3371 break;
3372 default:
3373 rstartEl(ascii("number:text"), rList);
3374 rchars(ascii("th"));
3375 rendEl(ascii("number:text"));
3376 break;
3378 break;
3379 case '4':
3380 case '$':
3381 if( add_zero )
3382 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3383 rstartEl(ascii("number:hours"), rList);
3384 pList->clear();
3385 rendEl(ascii("number:hours"));
3386 break;
3387 case '5':
3388 case '%':
3389 if( add_zero )
3390 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3391 rstartEl(ascii("number:minutes"), rList);
3392 pList->clear();
3393 rendEl(ascii("number:minutes"));
3394 break;
3395 case '_':
3396 padd(ascii("number:style"), sXML_CDATA, ascii("long"));
3397 case '6':
3398 case '^':
3399 rstartEl(ascii("number:day-of-week"), rList);
3400 pList->clear();
3401 rendEl(ascii("number:day-of-week"));
3402 break;
3403 case '7':
3404 case '&':
3405 case '+':
3406 rstartEl(ascii("number:am-pm"), rList);
3407 pList->clear();
3408 rendEl(ascii("number:am-pm"));
3409 break;
3410 case '~': // Chinese Locale
3411 break;
3412 default:
3413 hchar sbuf[2];
3414 sbuf[0] = *fmt;
3415 sbuf[1] = 0;
3416 rstartEl(ascii("number:text"), rList);
3417 rchars((hconv(sbuf)));
3418 rendEl(ascii("number:text"));
3419 break;
3422 pList->clear();
3423 rendEl(ascii("number:date-style"));
3427 void HwpReader::makeDateCode(DateCode * hbox)
3429 padd(ascii("style:data-style-name"), sXML_CDATA,
3430 ascii(Int2Str(hbox->key, "N%d", buf)));
3431 rstartEl( ascii("text:date"), rList );
3432 pList->clear();
3433 hchar_string const boxstr = hbox->GetString();
3434 rchars((hconv(boxstr.c_str())));
3435 rendEl( ascii("text:date") );
3439 void HwpReader::makeTab(Tab * ) /*hbox */
3441 rstartEl(ascii("text:tab-stop"), rList);
3442 rendEl(ascii("text:tab-stop"));
3446 void HwpReader::makeTable(TxtBox * hbox)
3448 padd(ascii("table:name"), sXML_CDATA,
3449 ascii(Int2Str(hbox->style.boxnum, "Table%d", buf)));
3450 padd(ascii("table:style-name"), sXML_CDATA,
3451 ascii(Int2Str(hbox->style.boxnum, "Table%d", buf)));
3452 rstartEl(ascii("table:table"), rList);
3453 pList->clear();
3455 Table *tbl = hbox->m_pTable;
3456 // ----------- column ---------------- //
3457 for (size_t i = 0 ; i < tbl->columns.nCount -1 ; i++)
3459 sprintf(buf,"Table%d.%c",hbox->style.boxnum, static_cast<char>('A'+i));
3460 padd(ascii("table:style-name"), sXML_CDATA, ascii( buf ));
3461 rstartEl(ascii("table:table-column"), rList);
3462 pList->clear();
3463 rendEl(ascii("table:table-column"));
3466 // ----------- cell ---------------- //
3467 int j = -1, k = -1;
3468 for (int i = 0 ; i < static_cast<int>(tbl->cells.size()); i++)
3470 std::list<TCell*>::iterator it = tbl->cells.begin();
3472 for( int ii = 0; it != tbl->cells.end(); ++it, ii++ ){
3473 if( ii == i )
3474 break;
3477 TCell *tcell = *it;
3478 if( tcell->nRowIndex > j )
3480 if( j > k )
3482 rendEl(ascii("table:table-row"));
3483 k = j;
3485 // --------------- row ---------------- //
3486 sprintf(buf,"Table%d.row%d",hbox->style.boxnum, tcell->nRowIndex + 1);
3487 padd(ascii("table:style-name"), sXML_CDATA, ascii( buf ));
3488 rstartEl(ascii("table:table-row"), rList);
3489 pList->clear();
3490 j = tcell->nRowIndex;
3493 sprintf(buf,"Table%d.%c%d",hbox->style.boxnum, 'A'+ tcell->nColumnIndex, tcell->nRowIndex +1);
3494 padd(ascii("table:style-name"), sXML_CDATA, ascii( buf ));
3495 if( tcell->nColumnSpan > 1 )
3496 padd(ascii("table:number-columns-spanned"), sXML_CDATA,
3497 ascii(Int2Str(tcell->nColumnSpan, "%d", buf)));
3498 if( tcell->nRowSpan > 1 )
3499 padd(ascii("table:number-rows-spanned"), sXML_CDATA,
3500 ascii(Int2Str(tcell->nRowSpan, "%d", buf)));
3501 padd(ascii("table:value-type"), sXML_CDATA,ascii("string"));
3502 if( tcell->pCell->protect )
3503 padd(ascii("table:protected"), sXML_CDATA,ascii("true"));
3504 rstartEl(ascii("table:table-cell"), rList);
3505 pList->clear();
3506 parsePara(hbox->plists[tcell->pCell->key].front());
3507 rendEl(ascii("table:table-cell"));
3509 rendEl(ascii("table:table-row"));
3510 rendEl(ascii("table:table"));
3515 * 텍스트박스와 테이블을 파싱한다.
3516 * 1. draw:style-name, draw:name, text:anchor-type, svg:width,
3517 * fo:min-height, svg:x, svg:y
3518 * TODO : fo:background-color로 셀의 칼라 설정=>스타일에 들어가는 지 아직 모르겠다.
3520 void HwpReader::makeTextBox(TxtBox * hbox)
3522 if( hbox->style.cap_len > 0 && hbox->type == TXT_TYPE)
3524 padd(ascii("draw:style-name"), sXML_CDATA,
3525 ascii(Int2Str(hbox->style.boxnum, "CapBox%d", buf)));
3526 padd(ascii("draw:name"), sXML_CDATA,
3527 ascii(Int2Str(hbox->style.boxnum, "CaptionBox%d", buf)));
3528 padd(ascii("draw:z-index"), sXML_CDATA,
3529 ascii(Int2Str(hbox->zorder, "%d", buf)));
3530 switch (hbox->style.anchor_type)
3532 case CHAR_ANCHOR:
3533 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3534 break;
3535 case PARA_ANCHOR:
3536 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
3537 break;
3538 case PAGE_ANCHOR:
3539 case PAPER_ANCHOR:
3541 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("page"));
3542 padd(ascii("text:anchor-page-number"), sXML_CDATA,
3543 ascii(Int2Str(hbox->pgno +1, "%d", buf)));
3544 break;
3547 if (hbox->style.anchor_type != CHAR_ANCHOR)
3549 padd(ascii("svg:x"), sXML_CDATA,
3550 Double2Str(WTMM( ( hbox->pgx + hbox->style.margin[0][0] ) )) + ascii("mm"));
3551 padd(ascii("svg:y"), sXML_CDATA,
3552 Double2Str(WTMM( ( hbox->pgy + hbox->style.margin[0][2] ) )) + ascii("mm"));
3554 padd(ascii("svg:width"), sXML_CDATA,
3555 Double2Str(WTMM(( hbox->box_xs + hbox->cap_xs) )) + ascii("mm"));
3556 padd(ascii("fo:min-height"), sXML_CDATA,
3557 Double2Str(WTMM(( hbox->box_ys + hbox->cap_ys) )) + ascii("mm"));
3558 rstartEl(ascii("draw:text-box"), rList);
3559 pList->clear();
3560 if( hbox->cap_pos % 2 ) /* 캡션이 위쪽에 위치한다 */
3562 parsePara(hbox->caption.front());
3564 padd( ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
3565 rstartEl(ascii("text:p"), rList);
3566 pList->clear();
3568 else{
3569 padd(ascii("draw:z-index"), sXML_CDATA,
3570 ascii(Int2Str(hbox->zorder, "%d", buf)));
3573 padd(ascii("draw:style-name"), sXML_CDATA,
3574 ascii(Int2Str(hbox->style.boxnum, "Txtbox%d", buf)));
3575 padd(ascii("draw:name"), sXML_CDATA,
3576 ascii(Int2Str(hbox->style.boxnum, "Frame%d", buf)));
3578 if( hbox->style.cap_len <= 0 || hbox->type != TXT_TYPE )
3580 int x = 0;
3581 int y = 0;
3582 switch (hbox->style.anchor_type)
3584 case CHAR_ANCHOR:
3585 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3586 break;
3587 case PARA_ANCHOR:
3588 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
3589 break;
3590 case PAGE_ANCHOR:
3591 case PAPER_ANCHOR:
3593 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("page"));
3594 padd(ascii("text:anchor-page-number"), sXML_CDATA,
3595 ascii(Int2Str(hbox->pgno +1, "%d", buf)));
3596 break;
3599 if( hbox->style.anchor_type != CHAR_ANCHOR )
3601 x += hbox->style.margin[0][0];
3602 y += hbox->style.margin[0][2];
3604 padd(ascii("svg:x"), sXML_CDATA,
3605 Double2Str(WTMM( hbox->pgx + x )) + ascii("mm"));
3606 padd(ascii("svg:y"), sXML_CDATA,
3607 Double2Str(WTMM( hbox->pgy + y )) + ascii("mm"));
3609 else
3611 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3612 padd(ascii("svg:y"), sXML_CDATA, ascii("0cm"));
3614 padd(ascii("svg:width"), sXML_CDATA,
3615 Double2Str(WTMM( hbox->box_xs )) + ascii("mm"));
3616 if( hbox->style.cap_len > 0 && hbox->type != TXT_TYPE)
3617 padd(ascii("fo:min-height"), sXML_CDATA,
3618 Double2Str(WTMM( hbox->box_ys + hbox->cap_ys)) + ascii("mm"));
3619 else
3620 padd(ascii("svg:height"), sXML_CDATA,
3621 Double2Str(WTMM(hbox->box_ys )) + ascii("mm"));
3623 if( hbox->type != EQU_TYPE )
3625 rstartEl(ascii("draw:text-box"), rList);
3626 pList->clear();
3627 /* 캡션이 존재하고, 위쪽에 있으면 */
3628 if( hbox->style.cap_len > 0 && (hbox->cap_pos % 2) && hbox->type == TBL_TYPE )
3630 parsePara(hbox->caption.front());
3632 if( hbox->type == TBL_TYPE) // Is Table
3634 makeTable(hbox);
3636 else // Is TextBox
3638 parsePara(hbox->plists[0].front());
3640 /* 캡션이 존재하고, 아래쪽에 있으면 */
3641 if( hbox->style.cap_len > 0 && !(hbox->cap_pos % 2) && hbox->type == TBL_TYPE)
3643 parsePara(hbox->caption.front());
3645 rendEl(ascii("draw:text-box"));
3646 // Caption exist and it is text-box
3647 if( hbox->style.cap_len > 0 && hbox->type == TXT_TYPE)
3649 rendEl( ascii("text:p"));
3650 if( !(hbox->cap_pos % 2))
3652 parsePara(hbox->caption.front());
3654 rendEl( ascii("draw:text-box"));
3657 else // is Formula
3659 rstartEl(ascii("draw:object"), rList);
3660 pList->clear();
3661 makeFormula(hbox);
3662 rendEl(ascii("draw:object"));
3668 * MathML로 변환해야 한다.
3671 void HwpReader::makeFormula(TxtBox * hbox)
3673 char mybuf[3000];
3674 HWPPara* pPar;
3675 CharShape *cshape = 0;
3677 int n, c, res;
3678 hchar dest[3];
3679 size_t l = 0;
3681 pPar = hbox->plists[0].front();
3682 while( pPar )
3684 for( n = 0; n < pPar->nch && pPar->hhstr[n]->hh;
3685 n += pPar->hhstr[n]->WSize() )
3687 if (!cshape)
3688 cshape = pPar->GetCharShape(n);
3689 if (l >= sizeof(mybuf)-7)
3690 break;
3691 res = hcharconv(pPar->hhstr[n]->hh, dest, UNICODE);
3692 for( int j = 0 ; j < res; j++ ){
3693 c = dest[j];
3694 if( c < 32 )
3695 c = ' ';
3696 if( c < 256 )
3697 mybuf[l++] = sal::static_int_cast<char>(c);
3698 else
3700 mybuf[l++] = sal::static_int_cast<char>((c >> 8) & 0xff);
3701 mybuf[l++] = sal::static_int_cast<char>(c & 0xff);
3705 if (l >= sizeof(mybuf)-7)
3706 break;
3707 mybuf[l++] = '\n';
3708 pPar = pPar->Next();
3710 mybuf[l] = '\0';
3712 Formula *form = new Formula(mybuf);
3713 form->setDocumentHandler(m_rxDocumentHandler);
3714 form->setAttributeListImpl(pList);
3715 form->parse();
3717 delete form;
3722 * platform정보를 읽어들여서 href가 C:\나 D:\로 시작할 경우 리눅스나 솔라리스이면
3723 * C:\ => 홈으로, D:\ => 루트(/)로 바꾸어주는 작업이 필요하다. 이것은
3724 * 한컴이 도스에뮬레이터를 쓰기 때문이다.
3726 void HwpReader::makeHyperText(TxtBox * hbox)
3728 HyperText *hypert = hwpfile.GetHyperText();
3729 if( !hypert ) return;
3731 if( strlen((char *)hypert->filename) > 0 ){
3732 ::std::string const tmp = hstr2ksstr(hypert->bookmark);
3733 ::std::string const tmp2 = hstr2ksstr(kstr2hstr(
3734 #ifdef _WIN32
3735 (uchar *) urltowin((char *)hypert->filename).c_str()).c_str());
3736 #else
3737 (uchar *) urltounix((char *)hypert->filename).c_str()).c_str());
3738 #endif
3739 padd(ascii("xlink:type"), sXML_CDATA, ascii("simple"));
3740 if (tmp.size() > 0 && strcmp(tmp.c_str(), "[HTML]")) {
3741 ::std::string tmp3(tmp2);
3742 tmp3.push_back('#');
3743 tmp3.append(tmp);
3744 padd(ascii("xlink:href"), sXML_CDATA,
3745 OUString(tmp3.c_str(), tmp3.size()+1, RTL_TEXTENCODING_EUC_KR));
3747 else{
3748 padd(ascii("xlink:href"), sXML_CDATA,
3749 OUString(tmp2.c_str(), tmp2.size()+1, RTL_TEXTENCODING_EUC_KR));
3753 else
3755 padd(ascii("xlink:type"), sXML_CDATA, ascii("simple"));
3756 ::std::string tmp;
3757 tmp.push_back('#');
3758 tmp.append(hstr2ksstr(hypert->bookmark));
3759 padd(ascii("xlink:href"), sXML_CDATA,
3760 OUString(tmp.c_str(), tmp.size()+1, RTL_TEXTENCODING_EUC_KR));
3762 rstartEl(ascii("draw:a"), rList);
3763 pList->clear();
3764 makeTextBox(hbox);
3765 rendEl(ascii("draw:a"));
3770 * platform정보를 읽어들여서 href가 C:\나 D:\로 시작할 경우 리눅스나 솔라리스이면
3771 * C:\ => 홈으로, D:\ => 루트(/)로 바꾸었다. 이것은
3772 * 한컴이 도스에뮬레이터를 쓰기 때문이다.
3774 void HwpReader::makePicture(Picture * hbox)
3776 switch (hbox->pictype)
3778 case PICTYPE_OLE:
3779 case PICTYPE_EMBED:
3780 case PICTYPE_FILE:
3782 if( hbox->style.cap_len > 0 )
3784 padd(ascii("draw:style-name"), sXML_CDATA,
3785 ascii(Int2Str(hbox->style.boxnum, "CapBox%d", buf)));
3786 padd(ascii("draw:name"), sXML_CDATA,
3787 ascii(Int2Str(hbox->style.boxnum, "CaptionBox%d", buf)));
3788 padd(ascii("draw:z-index"), sXML_CDATA,
3789 ascii(Int2Str(hbox->zorder, "%d", buf)));
3790 switch (hbox->style.anchor_type)
3792 case CHAR_ANCHOR:
3793 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3794 break;
3795 case PARA_ANCHOR:
3796 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
3797 break;
3798 case PAGE_ANCHOR:
3799 case PAPER_ANCHOR:
3801 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("page"));
3802 padd(ascii("text:anchor-page-number"), sXML_CDATA,
3803 ascii(Int2Str(hbox->pgno +1, "%d", buf)));
3804 break;
3807 if (hbox->style.anchor_type != CHAR_ANCHOR)
3809 padd(ascii("svg:x"), sXML_CDATA,
3810 Double2Str(WTMM( hbox->pgx + hbox->style.margin[0][0] )) + ascii("mm"));
3811 padd(ascii("svg:y"), sXML_CDATA,
3812 Double2Str(WTMM( hbox->pgy + hbox->style.margin[0][2] )) + ascii("mm"));
3814 padd(ascii("svg:width"), sXML_CDATA,
3815 Double2Str(WTMM( hbox->box_xs + hbox->style.margin[1][0] + hbox->style.margin[1][1] )) + ascii("mm"));
3816 padd(ascii("fo:min-height"), sXML_CDATA,
3817 Double2Str(WTMM( hbox->box_ys + hbox->style.margin[1][2] + hbox->style.margin[1][3] + hbox->cap_ys )) + ascii("mm"));
3818 rstartEl(ascii("draw:text-box"), rList);
3819 pList->clear();
3820 if( hbox->cap_pos % 2 ) /* 캡션이 위쪽에 위치한다 */
3822 parsePara(hbox->caption.front());
3824 padd( ascii("text:style-name"), sXML_CDATA, ascii("Standard"));
3825 rstartEl(ascii("text:p"), rList);
3826 pList->clear();
3828 if( hbox->ishyper )
3830 padd(ascii("xlink:type"), sXML_CDATA, ascii("simple"));
3831 #ifdef _WIN32
3832 if( hbox->follow[4] != 0 )
3833 padd(ascii("xlink:href"), sXML_CDATA, (hconv(kstr2hstr(hbox->follow + 4).c_str())));
3834 else
3835 padd(ascii("xlink:href"), sXML_CDATA, (hconv(kstr2hstr(hbox->follow + 5).c_str())));
3836 #else
3837 if( hbox->follow[4] != 0 )
3838 padd(ascii("xlink:href"), sXML_CDATA,
3839 (hconv(kstr2hstr((uchar *)urltounix((char *)(hbox->follow + 4)).c_str()).c_str())));
3840 else
3841 padd(ascii("xlink:href"), sXML_CDATA,
3842 (hconv(kstr2hstr((uchar *)urltounix((char *)(hbox->follow + 5)).c_str()).c_str())));
3843 #endif
3844 rstartEl(ascii("draw:a"), rList);
3845 pList->clear();
3847 padd(ascii("draw:style-name"), sXML_CDATA,
3848 ascii(Int2Str(hbox->style.boxnum, "G%d", buf)));
3849 padd(ascii("draw:name"), sXML_CDATA,
3850 ascii(Int2Str(hbox->style.boxnum, "Image%d", buf)));
3852 if( hbox->style.cap_len <= 0 )
3854 padd(ascii("draw:z-index"), sXML_CDATA,
3855 ascii(Int2Str(hbox->zorder, "%d", buf)));
3856 switch (hbox->style.anchor_type)
3858 case CHAR_ANCHOR:
3859 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3860 break;
3861 case PARA_ANCHOR:
3862 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
3863 break;
3864 case PAGE_ANCHOR:
3865 case PAPER_ANCHOR:
3867 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("page"));
3868 padd(ascii("text:anchor-page-number"), sXML_CDATA,
3869 ascii(Int2Str(hbox->pgno +1, "%d", buf)));
3870 break;
3873 if (hbox->style.anchor_type != CHAR_ANCHOR)
3875 padd(ascii("svg:x"), sXML_CDATA,
3876 Double2Str(WTMM( hbox->pgx + hbox->style.margin[0][0] )) + ascii("mm"));
3877 padd(ascii("svg:y"), sXML_CDATA,
3878 Double2Str(WTMM( hbox->pgy + hbox->style.margin[0][2] )) + ascii("mm"));
3881 else
3883 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
3884 padd(ascii("svg:y"), sXML_CDATA, ascii("0cm"));
3886 padd(ascii("svg:width"), sXML_CDATA,
3887 Double2Str(WTMM( hbox->box_xs + hbox->style.margin[1][0] + hbox->style.margin[1][1])) + ascii("mm"));
3888 padd(ascii("svg:height"), sXML_CDATA,
3889 Double2Str(WTMM( hbox->box_ys + hbox->style.margin[1][2] + hbox->style.margin[1][3])) + ascii("mm"));
3891 if ( hbox->pictype == PICTYPE_FILE ){
3892 #ifdef _WIN32
3893 sprintf(buf, "file:///%s", hbox->picinfo.picun.path );
3894 padd(ascii("xlink:href"), sXML_CDATA, (hconv(kstr2hstr((uchar *) buf).c_str())));
3895 #else
3896 padd(ascii("xlink:href"), sXML_CDATA,
3897 (hconv(kstr2hstr((uchar *) urltounix(hbox->picinfo.picun.path).c_str()).c_str())));
3898 #endif
3899 padd(ascii("xlink:type"), sXML_CDATA, ascii("simple"));
3900 padd(ascii("xlink:show"), sXML_CDATA, ascii("embed"));
3901 padd(ascii("xlink:actuate"), sXML_CDATA, ascii("onLoad"));
3904 if( hbox->pictype == PICTYPE_OLE )
3905 rstartEl(ascii("draw:object-ole"), rList);
3906 else
3907 rstartEl(ascii("draw:image"), rList);
3908 pList->clear();
3909 if (hbox->pictype == PICTYPE_EMBED || hbox->pictype == PICTYPE_OLE)
3911 rstartEl(ascii("office:binary-data"), rList);
3912 pList->clear();
3913 if( hbox->pictype == PICTYPE_EMBED ){
3914 EmPicture *emp = hwpfile.GetEmPicture(hbox);
3915 if( emp )
3917 boost::shared_ptr<char> pStr(base64_encode_string( emp->data, emp->size ), Free<char>());
3918 rchars(ascii(pStr.get()));
3921 else{
3922 if( hwpfile.oledata ){
3923 #ifdef WIN32
3924 LPSTORAGE srcsto;
3925 LPUNKNOWN pObj;
3926 wchar_t pathname[200];
3928 MultiByteToWideChar(CP_ACP, 0, hbox->picinfo.picole.embname, -1, pathname, 200);
3929 int rc = hwpfile.oledata->pis->OpenStorage(pathname, 0,
3930 STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, NULL, 0, &srcsto);
3931 if (rc != S_OK) {
3932 rchars(ascii(""));
3934 else{
3935 rc = OleLoad(srcsto, IID_IUnknown, NULL, (LPVOID*)&pObj);
3936 if( rc != S_OK ){
3937 srcsto->Release();
3938 rchars(ascii(""));
3940 else{
3941 boost::shared_ptr<char> pStr(base64_encode_string( (uchar *)pObj, strlen((char *)pObj)), Free<char>());
3942 rchars(ascii(pStr.get()));
3943 pObj->Release();
3944 srcsto->Release();
3947 #else
3948 rchars(ascii(""));
3949 #endif
3952 rendEl(ascii("office:binary-data"));
3954 if( hbox->pictype == PICTYPE_OLE )
3955 rendEl(ascii("draw:object-ole"));
3956 else
3957 rendEl(ascii("draw:image"));
3958 if( hbox->ishyper )
3960 rendEl(ascii("draw:a"));
3962 if( hbox->style.cap_len > 0 )
3964 rendEl( ascii("text:p"));
3965 if( !(hbox->cap_pos % 2)) /* 캡션이 아래쪽에 위치하면, */
3967 parsePara(hbox->caption.front());
3969 rendEl( ascii("draw:text-box"));
3971 break;
3973 case PICTYPE_DRAW:
3974 if( hbox->picinfo.picdraw.zorder > 0 )
3975 padd(ascii("draw:z-index"), sXML_CDATA,
3976 ascii(Int2Str( hbox->picinfo.picdraw.zorder + 10000, "%d", buf)));
3977 makePictureDRAW( (HWPDrawingObject *) hbox->picinfo.picdraw.hdo, hbox);
3978 break;
3979 case PICTYPE_UNKNOWN:
3980 break;
3985 #define DBL(x) ((x) * (x))
3986 void HwpReader::makePictureDRAW(HWPDrawingObject *drawobj, Picture * hbox)
3988 int x = hbox->pgx;
3989 int y = hbox->pgy;
3990 int a, b;
3991 sal_Bool bIsRotate = sal_False;
3993 while (drawobj)
3995 padd(ascii("draw:style-name"), sXML_CDATA,
3996 ascii(Int2Str(drawobj->index, "Draw%d", buf)));
3997 a = 0; b = 0;
3999 switch (hbox->style.anchor_type)
4001 case CHAR_ANCHOR:
4002 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("as-char"));
4003 break;
4004 case PARA_ANCHOR:
4005 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
4006 break;
4007 case PAGE_ANCHOR:
4008 case PAPER_ANCHOR:
4010 HWPInfo *hwpinfo = hwpfile.GetHWPInfo();
4011 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("page"));
4012 padd(ascii("text:anchor-page-number"), sXML_CDATA,
4013 ascii(Int2Str(hbox->pgno +1, "%d", buf)));
4014 a = hwpinfo->paper.left_margin;
4015 b = hwpinfo->paper.top_margin + hwpinfo->paper.header_length;
4016 break;
4020 if (drawobj->type == HWPDO_CONTAINER)
4022 rstartEl(ascii("draw:g"), rList);
4023 pList->clear();
4024 makePictureDRAW(drawobj->child, hbox);
4025 rendEl(ascii("draw:g"));
4027 else
4029 bIsRotate = sal_False;
4030 if( (drawobj->property.flag & HWPDO_FLAG_ROTATION) &&
4031 (drawobj->property.parall.pt[0].y != drawobj->property.parall.pt[1].y) &&
4032 //(drawobj->type == HWPDO_RECT || drawobj->type == HWPDO_ADVANCED_ELLIPSE || drawobj->type == HWPDO_ADVANCED_ARC )
4033 (drawobj->type == HWPDO_RECT || drawobj->type == HWPDO_ADVANCED_ELLIPSE )
4037 int i;
4038 ZZParall *pal = &drawobj->property.parall;
4040 ZZPoint pt[3], r_pt[3];
4041 for(i = 0 ; i < 3 ; i++ ){
4042 pt[i].x = pal->pt[i].x - drawobj->property.rot_originx;
4043 /* 물리좌표계로 변환 */
4044 pt[i].y = -(pal->pt[i].y - drawobj->property.rot_originy);
4047 double rotate, skewX ;
4049 /* 2 - 회전각 계산 */
4050 if( pt[1].x == pt[0].x ){
4051 if( pt[1].y > pt[0].y )
4052 rotate = PI/2;
4053 else
4054 rotate = -(PI/2);
4056 else
4057 rotate = atan((double)( pt[1].y - pt[0].y )/(pt[1].x - pt[0].x ));
4058 if( pt[1].x < pt[0].x )
4059 rotate += PI;
4061 for( i = 0 ; i < 3 ; i++){
4062 r_pt[i].x = (int)(pt[i].x * cos(-(rotate)) - pt[i].y * sin(-(rotate)));
4063 r_pt[i].y = (int)(pt[i].y * cos(-(rotate)) + pt[i].x * sin(-(rotate)));
4066 /* 4 - 휜각 계산 */
4067 if( r_pt[2].y == r_pt[1].y )
4068 skewX = 0;
4069 else
4070 skewX = atan((double)(r_pt[2].x - r_pt[1].x )/( r_pt[2].y - r_pt[1].y ));
4071 if( skewX >= PI/2 )
4072 skewX -= PI;
4073 if( skewX <= -PI/2 )
4074 skewX += PI;
4076 OUString trans;
4077 if( skewX != 0.0 && rotate != 0.0 ){
4078 trans = ascii("skewX (") + Double2Str(skewX)
4079 + ascii(") rotate (") + Double2Str(rotate)
4080 + ascii(") translate (") + Double2Str(WTMM(x + a + drawobj->offset2.x + pal->pt[0].x)) + ascii("mm ")
4081 + Double2Str(WTMM(y + b + drawobj->offset2.y + pal->pt[0].y)) + ascii("mm)");
4082 bIsRotate = sal_True;
4084 else if( skewX != 0.0 ){
4085 trans = ascii("skewX (") + Double2Str(skewX)
4086 + ascii(") translate (") + Double2Str(WTMM(x + a + drawobj->offset2.x + pal->pt[0].x)) + ascii("mm ")
4087 + Double2Str(WTMM(y + b + drawobj->offset2.y + pal->pt[0].y)) + ascii("mm)");
4088 bIsRotate = sal_True;
4090 else if( rotate != 0.0 ){
4091 trans = ascii("rotate (") + Double2Str(rotate)
4092 + ascii(") translate (") + Double2Str(WTMM(x + a + drawobj->offset2.x + pal->pt[0].x)) + ascii("mm ")
4093 + Double2Str(WTMM(y + b + drawobj->offset2.y + pal->pt[0].y)) + ascii("mm)");
4094 bIsRotate = sal_True;
4096 if( bIsRotate == sal_True ){
4097 drawobj->extent.w = (int)sqrt(double(DBL(pt[1].x-pt[0].x)+DBL(pt[1].y-pt[0].y)));
4098 drawobj->extent.h = (int)sqrt(double(DBL(pt[2].x-pt[1].x)+DBL(pt[2].y-pt[1].y)));
4099 padd(ascii("draw:transform"), sXML_CDATA, trans);
4102 switch (drawobj->type)
4104 case HWPDO_LINE: /* 선 - 시작좌표, 끝좌표. */
4105 if( drawobj->u.line_arc.flip & 0x01 )
4107 padd(ascii("svg:x1"), sXML_CDATA,
4108 Double2Str (WTMM(x + a + drawobj->offset2.x + drawobj->extent.w)) + ascii("mm"));
4109 padd(ascii("svg:x2"), sXML_CDATA,
4110 Double2Str (WTMM( x + a + drawobj->offset2.x )) + ascii("mm"));
4112 else
4114 padd(ascii("svg:x1"), sXML_CDATA,
4115 Double2Str (WTMM( x + a + drawobj->offset2.x )) + ascii("mm"));
4116 padd(ascii("svg:x2"), sXML_CDATA,
4117 Double2Str (WTMM(x + a + drawobj->offset2.x + drawobj->extent.w)) + ascii("mm"));
4119 if( drawobj->u.line_arc.flip & 0x02 )
4121 padd(ascii("svg:y1"), sXML_CDATA,
4122 Double2Str (WTMM( y + b + drawobj->offset2.y + drawobj->extent.h ) ) + ascii("mm"));
4123 padd(ascii("svg:y2"), sXML_CDATA,
4124 Double2Str (WTMM( y + b + drawobj->offset2.y )) + ascii("mm"));
4126 else
4128 padd(ascii("svg:y1"), sXML_CDATA,
4129 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4130 padd(ascii("svg:y2"), sXML_CDATA,
4131 Double2Str (WTMM(y + b + drawobj->offset2.y + drawobj->extent.h)) + ascii("mm"));
4134 rstartEl(ascii("draw:line"), rList);
4135 pList->clear();
4136 rendEl(ascii("draw:line"));
4137 break;
4138 case HWPDO_RECT: /* 사각형 - 시작위치, 가로/세로 */
4139 if( !bIsRotate )
4141 padd(ascii("svg:x"), sXML_CDATA,
4142 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4143 padd(ascii("svg:y"), sXML_CDATA,
4144 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4146 padd(ascii("svg:width"), sXML_CDATA,
4147 Double2Str (WTMM( drawobj->extent.w )) + ascii("mm"));
4148 padd(ascii("svg:height"), sXML_CDATA,
4149 Double2Str (WTMM( drawobj->extent.h )) + ascii("mm"));
4150 if( drawobj->property.flag & 0x01 )
4152 int value = drawobj->extent.w < drawobj->extent.h ?
4153 drawobj->extent.w : drawobj->extent.h ;
4154 padd(ascii("draw:corner-radius"), sXML_CDATA,
4155 Double2Str (WTMM( value/10 )) + ascii("mm"));
4157 else if( drawobj->property.flag & 0x04 )
4159 int value = drawobj->extent.w < drawobj->extent.h ?
4160 drawobj->extent.w : drawobj->extent.h ;
4161 padd(ascii("draw:corner-radius"), sXML_CDATA,
4162 Double2Str (WTMM( value / 2)) + ascii("mm"));
4165 rstartEl(ascii("draw:rect"), rList);
4166 pList->clear();
4167 if( (drawobj->property.flag & HWPDO_FLAG_AS_TEXTBOX) &&
4168 drawobj->property.pPara ) // As Textbox
4170 HWPPara *pPara = drawobj->property.pPara;
4171 //parsePara(pPara);
4172 while(pPara)
4174 make_text_p1( pPara );
4175 pPara = pPara->Next();
4178 rendEl(ascii("draw:rect"));
4179 break;
4180 case HWPDO_ELLIPSE: /* 타원 - 시작위치, 가로/세로 */
4181 case HWPDO_ADVANCED_ELLIPSE: /* 변형된 타원 */
4183 if( !bIsRotate )
4185 padd(ascii("svg:x"), sXML_CDATA,
4186 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4187 padd(ascii("svg:y"), sXML_CDATA,
4188 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4191 padd(ascii("svg:width"), sXML_CDATA,
4192 Double2Str (WTMM( drawobj->extent.w )) + ascii("mm"));
4193 padd(ascii("svg:height"), sXML_CDATA,
4194 Double2Str (WTMM( drawobj->extent.h )) + ascii("mm"));
4195 if( drawobj->type == HWPDO_ADVANCED_ELLIPSE ){
4196 if( drawobj->u.arc.radial[0].x != drawobj->u.arc.radial[1].x
4197 || drawobj->u.arc.radial[0].y != drawobj->u.arc.radial[1].y ){
4198 int Cx,Cy;
4199 Cx = ( drawobj->offset2.x + drawobj->extent.w ) / 2;
4200 Cy = ( drawobj->offset2.y + drawobj->extent.h ) / 2;
4202 double start_angle, end_angle;
4203 start_angle = calcAngle( Cx, Cy, drawobj->u.arc.radial[0].x, drawobj->u.arc.radial[0].y );
4204 end_angle = calcAngle( Cx, Cy, drawobj->u.arc.radial[1].x, drawobj->u.arc.radial[1].y );
4205 if( drawobj->property.fill_color < 0xffffff )
4206 padd(ascii("draw:kind"), sXML_CDATA, ascii("section"));
4207 else
4208 padd(ascii("draw:kind"), sXML_CDATA, ascii("arc"));
4209 padd(ascii("draw:start-angle"), sXML_CDATA, Double2Str(start_angle ));
4210 padd(ascii("draw:end-angle"), sXML_CDATA, Double2Str(end_angle));
4213 rstartEl(ascii("draw:ellipse"), rList);
4214 pList->clear();
4215 if( drawobj->property.flag >> 19 & 0x01 &&
4216 drawobj->property.pPara ) // As Textbox
4218 HWPPara *pPara = drawobj->property.pPara;
4219 //parsePara(pPara);
4220 while(pPara)
4222 make_text_p1( pPara );
4223 pPara = pPara->Next();
4226 rendEl(ascii("draw:ellipse"));
4227 break;
4230 case HWPDO_ARC: /* 호 */
4231 case HWPDO_ADVANCED_ARC:
4233 /* 호일경우에, 스타오피스는 전체 타원의 크기를 사이즈로 한다. */
4234 uint flip = drawobj->u.line_arc.flip;
4235 if( !bIsRotate )
4237 if( ( flip == 0 || flip == 2 ) && drawobj->type == HWPDO_ARC)
4238 padd(ascii("svg:x"), sXML_CDATA,
4239 Double2Str (WTMM( x + a + drawobj->offset2.x - drawobj->extent.w)) + ascii("mm"));
4240 else
4241 padd(ascii("svg:x"), sXML_CDATA,
4242 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4243 if( ( flip == 0 || flip == 1 ) && drawobj->type == HWPDO_ARC)
4244 padd(ascii("svg:y"), sXML_CDATA,
4245 Double2Str (WTMM( y + b + drawobj->offset2.y - drawobj->extent.h)) + ascii("mm"));
4246 else
4247 padd(ascii("svg:y"), sXML_CDATA,
4248 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4251 padd(ascii("svg:width"), sXML_CDATA,
4252 Double2Str (WTMM( drawobj->extent.w * 2)) + ascii("mm"));
4253 padd(ascii("svg:height"), sXML_CDATA,
4254 Double2Str (WTMM( drawobj->extent.h * 2)) + ascii("mm"));
4255 if( drawobj->property.flag & HWPDO_FLAG_DRAW_PIE ||
4256 drawobj->property.fill_color < 0xffffff )
4257 padd(ascii("draw:kind"), sXML_CDATA, ascii("section"));
4258 else
4259 padd(ascii("draw:kind"), sXML_CDATA, ascii("arc"));
4261 if( drawobj->type == HWPDO_ADVANCED_ARC ){
4262 double start_angle, end_angle;
4263 ZZParall *pal = &drawobj->property.parall;
4265 if( pal->pt[1].x == pal->pt[0].x ){
4266 if( pal->pt[0].y < pal->pt[1].y )
4267 start_angle = 1.5 * PI;
4268 else
4269 start_angle = 0.5 * PI;
4271 else{
4272 start_angle = atan((double)( pal->pt[0].y - pal->pt[1].y )/( pal->pt[1].x - pal->pt[0].x ));
4273 if( pal->pt[1].x < pal->pt[0].x )
4274 start_angle += PI;
4276 if( pal->pt[1].x == pal->pt[2].x ){
4277 if( pal->pt[2].y < pal->pt[1].y )
4278 end_angle = 1.5 * PI;
4279 else
4280 end_angle = 0.5 * PI;
4282 else{
4283 end_angle = atan((double)( pal->pt[2].y - pal->pt[1].y )/( pal->pt[1].x - pal->pt[2].x ));
4284 if( pal->pt[1].x < pal->pt[2].x )
4285 end_angle += PI;
4288 if( start_angle >= 2 * PI )
4289 start_angle -= 2 * PI;
4290 if( end_angle >= 2 * PI )
4291 end_angle -= 2 * PI;
4292 if( ( start_angle > end_angle ) && (start_angle - end_angle < PI )){
4293 double tmp_angle = start_angle;
4294 start_angle = end_angle;
4295 end_angle = tmp_angle;
4297 padd(ascii("draw:start-angle"), sXML_CDATA, Double2Str(start_angle * 180. / PI));
4298 padd(ascii("draw:end-angle"), sXML_CDATA, Double2Str(end_angle * 180. / PI));
4301 else{
4302 if( drawobj->u.line_arc.flip == 0 )
4304 padd(ascii("draw:start-angle"), sXML_CDATA, ascii("270"));
4305 padd(ascii("draw:end-angle"), sXML_CDATA, ascii("0"));
4307 else if( drawobj->u.line_arc.flip == 1 )
4309 padd(ascii("draw:start-angle"), sXML_CDATA, ascii("180"));
4310 padd(ascii("draw:end-angle"), sXML_CDATA, ascii("270"));
4312 else if( drawobj->u.line_arc.flip == 2 )
4314 padd(ascii("draw:start-angle"), sXML_CDATA, ascii("0"));
4315 padd(ascii("draw:end-angle"), sXML_CDATA, ascii("90"));
4317 else
4319 padd(ascii("draw:start-angle"), sXML_CDATA, ascii("90"));
4320 padd(ascii("draw:end-angle"), sXML_CDATA, ascii("180"));
4323 rstartEl(ascii("draw:ellipse"), rList);
4324 pList->clear();
4325 if( drawobj->property.flag >> 19 & 0x01 &&
4326 drawobj->property.pPara ) // As Textbox
4328 HWPPara *pPara = drawobj->property.pPara;
4329 //parsePara(pPara);
4330 while(pPara)
4332 make_text_p1( pPara );
4333 pPara = pPara->Next();
4336 rendEl(ascii("draw:ellipse"));
4337 break;
4340 case HWPDO_CURVE: /* 곡선 : 다각형으로 변환. */
4342 sal_Bool bIsNatural = sal_True;
4343 if( drawobj->property.flag >> 5 & 0x01){
4344 bIsNatural = sal_False;
4346 if( !bIsRotate )
4348 padd(ascii("svg:x"), sXML_CDATA,
4349 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4350 padd(ascii("svg:y"), sXML_CDATA,
4351 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4353 padd(ascii("svg:width"), sXML_CDATA,
4354 Double2Str (WTMM( drawobj->extent.w )) + ascii("mm"));
4355 padd(ascii("svg:height"), sXML_CDATA,
4356 Double2Str (WTMM( drawobj->extent.h )) + ascii("mm"));
4357 sprintf(buf, "0 0 %d %d", WTSM(drawobj->extent.w) , WTSM(drawobj->extent.h) );
4358 padd(ascii("svg:viewBox"), sXML_CDATA, ascii(buf) );
4360 OUString oustr;
4362 if ((drawobj->u.freeform.npt > 2) &&
4363 (static_cast<size_t>(drawobj->u.freeform.npt) <
4364 (::std::numeric_limits<int>::max() / sizeof(double))))
4366 int n, i;
4367 n = drawobj->u.freeform.npt;
4369 double *xarr = new double[n+1];
4370 double *yarr = new double[n+1];
4371 double *tarr = new double[n+1];
4373 double *xb = 0L;
4374 double *yb = 0L;
4376 double *carr = 0L;
4377 double *darr = 0L;
4380 for( i = 0 ; i < n ; i++ ){
4381 xarr[i] = drawobj->u.freeform.pt[i].x;
4382 yarr[i] = drawobj->u.freeform.pt[i].y;
4383 tarr[i] = i;
4385 xarr[n] = xarr[0];
4386 yarr[n] = yarr[0];
4387 tarr[n] = n;
4389 if( bIsNatural == sal_False ){
4390 PeriodicSpline(n, tarr, xarr, xb, carr, darr);
4391 // prevent memory leak
4392 delete[] carr;
4393 carr = 0;
4394 delete[] darr;
4395 darr = 0;
4396 PeriodicSpline(n, tarr, yarr, yb, carr, darr);
4398 else{
4399 NaturalSpline(n, tarr, xarr, xb, carr, darr);
4400 // prevent memory leak
4401 delete[] carr;
4402 carr = 0;
4403 delete[] darr;
4404 darr = 0;
4405 NaturalSpline(n, tarr, yarr, yb, carr, darr);
4408 sprintf(buf, "M%d %dC%d %d", WTSM((int)xarr[0]), WTSM((int)yarr[0]),
4409 WTSM((int)(xarr[0] + xb[0]/3)), WTSM((int)(yarr[0] + yb[0]/3)) );
4410 oustr += ascii(buf);
4412 for( i = 1 ; i < n ; i++ ){
4413 if( i == n -1 ){
4414 sprintf(buf, " %d %d %d %dz",
4415 WTSM((int)(xarr[i] - xb[i]/3)), WTSM((int)(yarr[i] - yb[i]/3)),
4416 WTSM((int)xarr[i]), WTSM((int)yarr[i]) );
4418 else{
4419 sprintf(buf, " %d %d %d %d %d %d",
4420 WTSM((int)(xarr[i] - xb[i]/3)), WTSM((int)(yarr[i] - yb[i]/3)),
4421 WTSM((int)xarr[i]), WTSM((int)yarr[i]),
4422 WTSM((int)xarr[i] + xb[i]/3), WTSM((int)(yarr[i] + yb[i]/3)) );
4425 oustr += ascii(buf);
4427 delete[] tarr;
4428 delete[] xarr;
4429 delete[] yarr;
4431 delete[] xb;
4432 delete[] yb;
4434 delete[] carr;
4435 delete[] darr;
4438 padd(ascii("svg:d"), sXML_CDATA, oustr);
4440 rstartEl(ascii("draw:path"), rList);
4441 pList->clear();
4442 // As Textbox
4443 if( drawobj->property.flag >> 19 & 0x01 && drawobj->property.pPara )
4445 HWPPara *pPara = drawobj->property.pPara;
4446 while(pPara)
4448 make_text_p1( pPara );
4449 pPara = pPara->Next();
4452 rendEl(ascii("draw:path"));
4453 break;
4455 case HWPDO_CLOSED_FREEFORM:
4456 case HWPDO_FREEFORM: /* 다각형 */
4458 bool bIsPolygon = false;
4460 padd(ascii("svg:x"), sXML_CDATA,
4461 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4462 padd(ascii("svg:y"), sXML_CDATA,
4463 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4465 padd(ascii("svg:width"), sXML_CDATA,
4466 Double2Str (WTMM( drawobj->extent.w )) + ascii("mm"));
4467 padd(ascii("svg:height"), sXML_CDATA,
4468 Double2Str (WTMM( drawobj->extent.h )) + ascii("mm"));
4470 sprintf(buf, "0 0 %d %d", WTSM(drawobj->extent.w), WTSM(drawobj->extent.h));
4471 padd(ascii("svg:viewBox"), sXML_CDATA, ascii(buf) );
4473 OUString oustr;
4475 if (drawobj->u.freeform.npt > 0)
4477 sprintf(buf, "%d,%d", WTSM(drawobj->u.freeform.pt[0].x), WTSM(drawobj->u.freeform.pt[0].y));
4478 oustr += ascii(buf);
4479 int i;
4480 for (i = 1; i < drawobj->u.freeform.npt ; i++)
4482 sprintf(buf, " %d,%d",
4483 WTSM(drawobj->u.freeform.pt[i].x),
4484 WTSM(drawobj->u.freeform.pt[i].y));
4485 oustr += ascii(buf);
4487 if( drawobj->u.freeform.pt[0].x == drawobj->u.freeform.pt[i-1].x &&
4488 drawobj->u.freeform.pt[0].y == drawobj->u.freeform.pt[i-1].y )
4490 bIsPolygon = true;
4493 padd(ascii("draw:points"), sXML_CDATA, oustr);
4495 if( drawobj->property.fill_color <= 0xffffff ||
4496 drawobj->property.pattern_type != 0)
4498 bIsPolygon = true;
4501 if(bIsPolygon)
4503 rstartEl(ascii("draw:polygon"), rList);
4504 pList->clear();
4505 if( drawobj->property.flag >> 19 & 0x01 &&
4506 // As Textbox
4507 drawobj->property.pPara )
4509 HWPPara *pPara = drawobj->property.pPara;
4510 // parsePara(pPara);
4511 while(pPara)
4513 make_text_p1( pPara );
4514 pPara = pPara->Next();
4517 rendEl(ascii("draw:polygon"));
4519 else
4521 rstartEl(ascii("draw:polyline"), rList);
4522 pList->clear();
4523 if( drawobj->property.flag >> 19 & 0x01 &&
4524 // As Textbox
4525 drawobj->property.pPara )
4527 HWPPara *pPara = drawobj->property.pPara;
4528 //parsePara(pPara);
4529 while(pPara)
4531 make_text_p1( pPara );
4532 pPara = pPara->Next();
4535 rendEl(ascii("draw:polyline"));
4537 break;
4539 case HWPDO_TEXTBOX:
4540 if( !bIsRotate )
4542 padd(ascii("svg:x"), sXML_CDATA,
4543 Double2Str (WTMM( x + a + drawobj->offset2.x)) + ascii("mm"));
4544 padd(ascii("svg:y"), sXML_CDATA,
4545 Double2Str (WTMM( y + b + drawobj->offset2.y)) + ascii("mm"));
4547 padd(ascii("svg:width"), sXML_CDATA,
4548 Double2Str (WTMM( drawobj->extent.w )) + ascii("mm"));
4549 padd(ascii("svg:height"), sXML_CDATA,
4550 Double2Str (WTMM( drawobj->extent.h )) + ascii("mm"));
4551 if( drawobj->property.flag & 0x01 )
4553 int value = drawobj->extent.w < drawobj->extent.h ?
4554 drawobj->extent.w : drawobj->extent.h ;
4555 padd(ascii("draw:corner-radius"), sXML_CDATA,
4556 Double2Str (WTMM( value/10 )) + ascii("mm"));
4558 else if( drawobj->property.flag & 0x04 )
4560 int value = drawobj->extent.w < drawobj->extent.h ?
4561 drawobj->extent.w : drawobj->extent.h ;
4562 padd(ascii("draw:corner-radius"), sXML_CDATA,
4563 Double2Str (WTMM( value / 2)) + ascii("mm"));
4566 rstartEl(ascii("draw:text-box"), rList);
4567 pList->clear();
4569 HWPPara *pPara = drawobj->u.textbox.h;
4570 //parsePara(pPara);
4571 while(pPara)
4573 make_text_p1( pPara );
4574 pPara = pPara->Next();
4577 rendEl(ascii("draw:text-box"));
4578 break;
4581 pList->clear();
4582 drawobj = drawobj->next;
4590 void HwpReader::makeLine(Line * )
4592 padd(ascii("text:style-name"), sXML_CDATA, ascii("Horizontal Line"));
4593 rstartEl( ascii("text:p"), rList);
4594 pList->clear();
4599 * 입력-주석-숨은설명 : 사용자에게 숨은 설명을 보여준다.
4600 * 문단이 포함될 수 있으나, 단지 문자열만 뽑아내어 파싱한다.
4602 void HwpReader::makeHidden(Hidden * hbox)
4604 hchar_string str;
4605 int res;
4606 hchar dest[3];
4608 padd(ascii("text:condition"), sXML_CDATA, ascii(""));
4609 padd(ascii("text:string-value"), sXML_CDATA, ascii(""));
4610 rstartEl(ascii("text:hidden-text"), rList);
4611 pList->clear();
4612 HWPPara *para = hbox->plist.front();
4614 while (para)
4616 for (int n = 0; n < para->nch && para->hhstr[n]->hh;
4617 n += para->hhstr[n]->WSize())
4619 res = hcharconv(para->hhstr[n]->hh, dest, UNICODE);
4620 for( int j = 0 ; j < res ; j++ )
4622 str.push_back(dest[j]);
4625 para = para->Next();
4627 makeChars(str);
4628 rendEl(ascii("text:hidden-text"));
4633 * 각주는 text:footnote, 미주는 text:endnote로 변환
4635 void HwpReader::makeFootnote(Footnote * hbox)
4637 if (hbox->type)
4639 padd(ascii("text:id"), sXML_CDATA,
4640 ascii(Int2Str(hbox->number, "edn%d", buf)));
4641 rstartEl(ascii("text:endnote"), rList);
4642 pList->clear();
4643 padd(ascii("text:label"), sXML_CDATA,
4644 ascii(Int2Str(hbox->number, "%d", buf)));
4645 rstartEl(ascii("text:endnote-citation"), rList);
4646 pList->clear();
4647 rchars(ascii(Int2Str(hbox->number, "%d", buf)));
4648 rendEl(ascii("text:endnote-citation"));
4649 rstartEl(ascii("text:endnote-body"), rList);
4650 parsePara(hbox->plist.front());
4651 rendEl(ascii("text:endnote-body"));
4652 rendEl(ascii("text:endnote"));
4654 else
4656 padd(ascii("text:id"), sXML_CDATA,
4657 ascii(Int2Str(hbox->number, "ftn%d", buf)));
4658 rstartEl(ascii("text:footnote"), rList);
4659 pList->clear();
4660 padd(ascii("text:label"), sXML_CDATA,
4661 ascii(Int2Str(hbox->number, "%d", buf)));
4662 rstartEl(ascii("text:footnote-citation"), rList);
4663 pList->clear();
4664 rchars(ascii(Int2Str(hbox->number, "%d", buf)));
4665 rendEl(ascii("text:footnote-citation"));
4666 rstartEl(ascii("text:footnote-body"), rList);
4667 parsePara(hbox->plist.front());
4668 rendEl(ascii("text:footnote-body"));
4669 rendEl(ascii("text:footnote"));
4675 * page/footnote/endnote/picture/table/formula number
4677 void HwpReader::makeAutoNum(AutoNum * hbox)
4679 switch (hbox->type)
4681 case PGNUM_AUTO:
4682 rstartEl(ascii("text:page-number"), rList);
4683 rchars(ascii(Int2Str(hbox->number, "%d", buf)));
4684 rendEl(ascii("text:page-number"));
4685 break;
4686 case FNNUM_AUTO:
4687 break;
4688 case ENNUM_AUTO:
4689 break;
4690 case EQUNUM_AUTO:
4691 case PICNUM_AUTO:
4692 padd(ascii("text:ref-name"),sXML_CDATA,
4693 ascii(Int2Str(hbox->number, "refIllustration%d", buf)));
4694 padd(ascii("text:name"),sXML_CDATA, ascii("Illustration"));
4695 padd(ascii("style:num-format"),sXML_CDATA, ascii("1"));
4696 rstartEl(ascii("text:sequence"), rList);
4697 rchars(ascii(Int2Str(hbox->number, "%d", buf)));
4698 rendEl(ascii("text:sequence"));
4699 break;
4700 case TBLNUM_AUTO:
4701 padd(ascii("text:ref-name"),sXML_CDATA,
4702 ascii(Int2Str(hbox->number, "refTable%d", buf)));
4703 padd(ascii("text:name"),sXML_CDATA, ascii("Table"));
4704 padd(ascii("style:num-format"),sXML_CDATA, ascii("1"));
4705 rstartEl(ascii("text:sequence"), rList);
4706 rchars(ascii(Int2Str(hbox->number, "%d", buf)));
4707 rendEl(ascii("text:sequence"));
4708 break;
4713 void HwpReader::makeShowPageNum()
4715 ShowPageNum *hbox = d->pPn;
4716 int nPos = 0;
4717 if( hbox->where == 1 || hbox->where == 4 )
4718 nPos = 1;
4719 else if( hbox->where == 2 || hbox->where == 5 )
4720 nPos = 2;
4721 else if( hbox->where == 3 || hbox->where == 6 )
4722 nPos = 3;
4723 else /* 이 경우가 존재하면 안된다. */
4725 if( d->nPnPos == 1 )
4726 nPos = 1;
4727 else if( d->nPnPos == 3 )
4728 nPos = 3;
4731 padd(ascii("draw:style-name"), sXML_CDATA,
4732 ascii(Int2Str(nPos, "PNBox%d", buf)));
4733 padd(ascii("draw:name"), sXML_CDATA,
4734 ascii(Int2Str(nPos, "PageNumber%d", buf)));
4735 padd(ascii("text:anchor-type"), sXML_CDATA, ascii("paragraph"));
4736 padd(ascii("svg:y"), sXML_CDATA, ascii("0cm"));
4737 padd(ascii("svg:width"), sXML_CDATA, ascii("2.0cm"));
4738 padd(ascii("fo:min-height"), sXML_CDATA, ascii("0.5cm"));
4739 rstartEl(ascii("draw:text-box"), rList);
4740 pList->clear();
4742 padd(ascii("text:style-name"), sXML_CDATA,
4743 ascii(Int2Str(nPos, "PNPara%d", buf)));
4744 rstartEl(ascii("text:p"), rList);
4745 pList->clear();
4746 if( hbox->shape > 2 )
4747 rchars(ascii("- "));
4748 if( hbox->shape % 3 == 0 )
4749 padd(ascii("style:num-format"), sXML_CDATA, ascii("1"));
4750 else if( hbox->shape % 3 == 1 )
4751 padd(ascii("style:num-format"), sXML_CDATA, ascii("I"));
4752 else
4753 padd(ascii("style:num-format"), sXML_CDATA, ascii("i"));
4754 padd(ascii("text:select-page"), sXML_CDATA, ascii("current"));
4755 rstartEl(ascii("text:page-number"), rList);
4756 pList->clear();
4757 rchars(ascii("2"));
4758 rendEl(ascii("text:page-number"));
4759 if( hbox->shape > 2 )
4760 rchars(ascii(" -"));
4761 rendEl(ascii("text:p"));
4762 rendEl(ascii("draw:text-box"));
4767 * mail merge operation using hwp addressbook and hwp data form.
4768 * not support operation in OO writer.
4770 void HwpReader::makeMailMerge(MailMerge * hbox)
4772 hchar_string const boxstr = hbox->GetString();
4773 rchars((hconv(boxstr.c_str())));
4778 * Make heading contents file using toc marks
4779 * not support operation.
4781 void HwpReader::makeTocMark(TocMark * ) /*hbox */
4787 * Make search character table in automatic
4788 * not support operation
4790 void HwpReader::makeIndexMark(IndexMark * ) /*hbox */
4795 void HwpReader::makeOutline(Outline * hbox)
4797 if( hbox->kind == 1 )
4798 rchars(OUString(hbox->GetUnicode().c_str()));
4802 void HwpReader::parsePara(HWPPara * para, sal_Bool bParaStart)
4805 while (para)
4807 if( para->nch == 1)
4809 if( !bParaStart )
4811 padd(ascii("text:style-name"), sXML_CDATA,
4812 ascii(getPStyleName(para->GetParaShape()->index, buf)));
4813 rstartEl( ascii("text:p"),rList);
4814 pList->clear();
4816 if( d->bFirstPara && d->bInBody )
4818 /* for HWP's Bookmark */
4819 strcpy(buf,"[문서의 처음]"); /* "Begin of Document" */
4820 padd(ascii("text:name"), sXML_CDATA, OUString(buf, strlen(buf), RTL_TEXTENCODING_UTF8));
4821 rstartEl(ascii("text:bookmark"), rList);
4822 pList->clear();
4823 rendEl(ascii("text:bookmark"));
4824 d->bFirstPara = sal_False;
4826 if( d->bInHeader )
4828 makeShowPageNum();
4829 d->bInHeader = sal_False;
4832 rendEl( ascii("text:p") );
4834 else
4836 if (!para->ctrlflag)
4838 if (para->contain_cshape)
4839 make_text_p1(para, bParaStart);
4840 else
4841 make_text_p0(para, bParaStart);
4843 else
4844 make_text_p3(para, bParaStart);
4846 bParaStart = false;
4847 para = para->Next();
4851 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */