Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : */
12 :
13 : #include "frame.hxx"
14 : #include "frmfmt.hxx"
15 : #include "sectfrm.hxx"
16 : #include "tabfrm.hxx"
17 : #include "txtfrm.hxx"
18 : #include "hffrm.hxx"
19 : #include "porlin.hxx"
20 : #include "porlay.hxx"
21 : #include "portxt.hxx"
22 : #include "sortedobjs.hxx"
23 : #include <anchoredobject.hxx>
24 : #include <libxml/xmlwriter.h>
25 : #include <SwPortionHandler.hxx>
26 :
27 : class XmlPortionDumper:public SwPortionHandler
28 : {
29 : private:
30 : xmlTextWriterPtr writer;
31 : sal_uInt16 ofs;
32 :
33 436 : const char* getTypeName( sal_uInt16 nType )
34 : {
35 436 : switch ( nType )
36 : {
37 0 : case POR_LIN: return "POR_LIN";
38 1 : case POR_FLYCNT: return "POR_FLYCNT";
39 :
40 0 : case POR_HOLE: return "POR_HOLE";
41 0 : case POR_TMPEND: return "POR_TMPEND";
42 0 : case POR_BRK: return "POR_BRK";
43 0 : case POR_KERN: return "POR_KERN";
44 0 : case POR_ARROW: return "POR_ARROW";
45 0 : case POR_MULTI: return "POR_MULTI";
46 0 : case POR_HIDDEN_TXT: return "POR_HIDDEN_TXT";
47 0 : case POR_CONTROLCHAR: return "POR_CONTROLCHAR";
48 :
49 76 : case POR_TXT: return "POR_TXT";
50 26 : case POR_LAY: return "POR_LAY";
51 238 : case POR_PARA: return "POR_PARA";
52 0 : case POR_URL: return "POR_URL";
53 0 : case POR_HNG: return "POR_HNG";
54 :
55 0 : case POR_DROP: return "POR_DROP";
56 0 : case POR_TOX: return "POR_TOX";
57 0 : case POR_ISOTOX: return "POR_ISOTOX";
58 0 : case POR_REF: return "POR_REF";
59 0 : case POR_ISOREF: return "POR_ISOREF";
60 0 : case POR_META: return "POR_META";
61 :
62 0 : case POR_EXP: return "POR_EXP";
63 0 : case POR_BLANK: return "POR_BLANK";
64 0 : case POR_POSTITS: return "POR_POSTITS";
65 :
66 0 : case POR_HYPH: return "POR_HYPH";
67 0 : case POR_HYPHSTR: return "POR_HYPHSTR";
68 0 : case POR_SOFTHYPH: return "POR_SOFTHYPH";
69 0 : case POR_SOFTHYPHSTR: return "POR_SOFTHYPHSTR";
70 0 : case POR_SOFTHYPH_COMP: return "POR_SOFTHYPH_COMP";
71 :
72 0 : case POR_FLD: return "POR_FLD";
73 0 : case POR_HIDDEN: return "POR_HIDDEN";
74 0 : case POR_QUOVADIS: return "POR_QUOVADIS";
75 0 : case POR_ERGOSUM: return "POR_ERGOSUM";
76 0 : case POR_COMBINED: return "POR_COMBINED";
77 0 : case POR_FTN: return "POR_FTN";
78 :
79 0 : case POR_FTNNUM: return "POR_FTNNUM";
80 1 : case POR_NUMBER: return "POR_NUMBER";
81 24 : case POR_BULLET: return "POR_BULLET";
82 0 : case POR_GRFNUM: return "POR_GRFNUM";
83 :
84 0 : case POR_GLUE: return "POR_GLUE";
85 :
86 18 : case POR_MARGIN: return "POR_MARGIN";
87 :
88 0 : case POR_FIX: return "POR_FIX";
89 2 : case POR_FLY: return "POR_FLY";
90 :
91 0 : case POR_TAB: return "POR_TAB";
92 :
93 5 : case POR_TABRIGHT: return "POR_TABRIGHT";
94 0 : case POR_TABCENTER: return "POR_TABCENTER";
95 0 : case POR_TABDECIMAL: return "POR_TABDECIMAL";
96 :
97 45 : case POR_TABLEFT: return "POR_TABLEFT";
98 : default:
99 0 : return "Unknown";
100 : }
101 : }
102 :
103 : public:
104 :
105 590 : XmlPortionDumper( xmlTextWriterPtr some_writer ):writer( some_writer ), ofs( 0 )
106 : {
107 590 : }
108 :
109 590 : virtual ~ XmlPortionDumper( )
110 590 : {
111 590 : }
112 :
113 : /**
114 : @param nLength
115 : length of this portion in the model string
116 : @param rText
117 : text which is painted on-screen
118 : */
119 390 : virtual void Text( sal_uInt16 nLength,
120 : sal_uInt16 nType,
121 : sal_Int32 nHeight,
122 : sal_Int32 nWidth)
123 : {
124 390 : ofs += nLength;
125 390 : xmlTextWriterStartElement( writer, BAD_CAST( "Text" ) );
126 : xmlTextWriterWriteFormatAttribute( writer,
127 : BAD_CAST( "nLength" ),
128 390 : "%i", ( int ) nLength );
129 : xmlTextWriterWriteFormatAttribute( writer,
130 : BAD_CAST( "nType" ),
131 390 : "%s", getTypeName( nType ) );
132 390 : if (nHeight > 0)
133 390 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nHeight"), "%i", (int)nHeight);
134 390 : if (nWidth > 0)
135 362 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nWidth"), "%i", (int)nWidth);
136 :
137 390 : xmlTextWriterEndElement( writer );
138 390 : }
139 :
140 : /**
141 : @param nLength
142 : length of this portion in the model string
143 : @param rText
144 : text which is painted on-screen
145 : @param nType
146 : type of this portion
147 : @param nHeight
148 : font size of the painted text
149 : */
150 46 : virtual void Special( sal_uInt16 nLength,
151 : const String & rText,
152 : sal_uInt16 nType,
153 : sal_Int32 nHeight,
154 : sal_Int32 nWidth )
155 : {
156 46 : xmlTextWriterStartElement( writer, BAD_CAST( "Special" ) );
157 : xmlTextWriterWriteFormatAttribute( writer,
158 : BAD_CAST( "nLength" ),
159 46 : "%i", ( int ) nLength );
160 : xmlTextWriterWriteFormatAttribute( writer,
161 : BAD_CAST( "nType" ),
162 46 : "%s", getTypeName( nType ) );
163 46 : OUString sText( rText );
164 : OString sText8 =OUStringToOString( sText,
165 92 : RTL_TEXTENCODING_UTF8 );
166 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "rText" ),
167 46 : "%s", sText8.getStr( ) );
168 :
169 46 : if (nHeight > 0)
170 28 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nHeight"), "%i", (int)nHeight);
171 :
172 46 : if (nWidth > 0)
173 19 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nWidth"), "%i", (int)nWidth);
174 :
175 46 : xmlTextWriterEndElement( writer );
176 92 : ofs += nLength;
177 46 : }
178 :
179 314 : virtual void LineBreak( KSHORT nWidth )
180 : {
181 314 : xmlTextWriterStartElement( writer, BAD_CAST( "LineBreak" ) );
182 314 : if (nWidth > 0)
183 : xmlTextWriterWriteFormatAttribute( writer,
184 : BAD_CAST( "nWidth" ),
185 288 : "%i", ( int ) nWidth );
186 314 : xmlTextWriterEndElement( writer );
187 314 : }
188 :
189 : /**
190 : * @param nLength
191 : * number of 'model string' characters to be skipped
192 : */
193 0 : virtual void Skip( sal_uInt16 nLength )
194 : {
195 0 : xmlTextWriterStartElement( writer, BAD_CAST( "Skip" ) );
196 : xmlTextWriterWriteFormatAttribute( writer,
197 : BAD_CAST( "nLength" ),
198 0 : "%i", ( int ) nLength );
199 0 : xmlTextWriterEndElement( writer );
200 0 : ofs += nLength;
201 0 : }
202 :
203 590 : virtual void Finish( )
204 : {
205 590 : xmlTextWriterStartElement( writer, BAD_CAST( "Finish" ) );
206 590 : xmlTextWriterEndElement( writer );
207 590 : }
208 :
209 : };
210 :
211 : namespace
212 : {
213 0 : xmlTextWriterPtr lcl_createDefaultWriter()
214 : {
215 0 : xmlTextWriterPtr writer = xmlNewTextWriterFilename( "layout.xml", 0 );
216 0 : xmlTextWriterStartDocument( writer, NULL, NULL, NULL );
217 0 : return writer;
218 : }
219 :
220 0 : void lcl_freeWriter( xmlTextWriterPtr writer )
221 : {
222 0 : xmlTextWriterEndDocument( writer );
223 0 : xmlFreeTextWriter( writer );
224 0 : }
225 : }
226 :
227 1073 : void SwFrm::dumpAsXml( xmlTextWriterPtr writer )
228 : {
229 1073 : bool bCreateWriter = ( NULL == writer );
230 1073 : if ( bCreateWriter )
231 0 : writer = lcl_createDefaultWriter();
232 :
233 1073 : const char *name = NULL;
234 :
235 1073 : switch ( GetType( ) )
236 : {
237 : case FRM_ROOT:
238 12 : name = "root";
239 12 : break;
240 : case FRM_PAGE:
241 42 : name = "page";
242 42 : break;
243 : case FRM_COLUMN:
244 0 : name = "column";
245 0 : break;
246 : case FRM_HEADER:
247 36 : name = "header";
248 36 : break;
249 : case FRM_FOOTER:
250 36 : name = "footer";
251 36 : break;
252 : case FRM_FTNCONT:
253 0 : name = "ftncont";
254 0 : break;
255 : case FRM_FTN:
256 0 : name = "ftn";
257 0 : break;
258 : case FRM_BODY:
259 42 : name = "body";
260 42 : break;
261 : case FRM_FLY:
262 8 : name = "fly";
263 8 : break;
264 : case FRM_SECTION:
265 1 : name = "section";
266 1 : break;
267 : case FRM_UNUSED:
268 0 : name = "unused";
269 0 : break;
270 : case FRM_TAB:
271 10 : name = "tab";
272 10 : break;
273 : case FRM_ROW:
274 60 : name = "row";
275 60 : break;
276 : case FRM_CELL:
277 236 : name = "cell";
278 236 : break;
279 : case FRM_TXT:
280 590 : name = "txt";
281 590 : break;
282 : case FRM_NOTXT:
283 0 : name = "notxt";
284 0 : break;
285 : };
286 :
287 1073 : if ( name != NULL )
288 : {
289 1073 : xmlTextWriterStartElement( writer, ( const xmlChar * ) name );
290 :
291 1073 : dumpAsXmlAttributes( writer );
292 :
293 1073 : xmlTextWriterStartElement( writer, BAD_CAST( "infos" ) );
294 1073 : dumpInfosAsXml( writer );
295 1073 : xmlTextWriterEndElement( writer );
296 :
297 : // Dump Anchored objects if any
298 1073 : SwSortedObjs* pAnchored = GetDrawObjs();
299 1073 : if ( pAnchored && pAnchored->Count( ) > 0 )
300 : {
301 17 : xmlTextWriterStartElement( writer, BAD_CAST( "anchored" ) );
302 :
303 38 : for ( sal_uInt32 i = 0, len = pAnchored->Count(); i < len; i++ )
304 : {
305 21 : SwAnchoredObject* pObject = (*pAnchored)[i];
306 21 : pObject->dumpAsXml( writer );
307 : }
308 :
309 17 : xmlTextWriterEndElement( writer );
310 : }
311 :
312 : // Dump the children
313 1073 : if ( IsTxtFrm( ) )
314 : {
315 590 : SwTxtFrm *pTxtFrm = ( SwTxtFrm * ) this;
316 590 : OUString aTxt = pTxtFrm->GetTxt( );
317 19470 : for ( int i = 0; i < 32; i++ )
318 : {
319 18880 : aTxt = aTxt.replace( i, '*' );
320 : }
321 : OString aTxt8 =OUStringToOString( aTxt,
322 1180 : RTL_TEXTENCODING_UTF8 );
323 : xmlTextWriterWriteString( writer,
324 590 : ( const xmlChar * ) aTxt8.getStr( ) );
325 1180 : XmlPortionDumper pdumper( writer );
326 1180 : pTxtFrm->VisitPortions( pdumper );
327 :
328 : }
329 : else
330 : {
331 483 : dumpChildrenAsXml( writer );
332 : }
333 1073 : xmlTextWriterEndElement( writer );
334 : }
335 :
336 1073 : if ( bCreateWriter )
337 0 : lcl_freeWriter( writer );
338 1073 : }
339 :
340 1073 : void SwFrm::dumpInfosAsXml( xmlTextWriterPtr writer )
341 : {
342 : // output the Frm
343 1073 : xmlTextWriterStartElement( writer, BAD_CAST( "bounds" ) );
344 1073 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "left" ), "%ld", Frm().Left() );
345 1073 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "top" ), "%ld", Frm().Top() );
346 1073 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "width" ), "%ld", Frm().Width() );
347 1073 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "height" ), "%ld", Frm().Height() );
348 1073 : xmlTextWriterEndElement( writer );
349 1073 : }
350 :
351 : // Hack: somehow conversion from "..." to va_list does
352 : // bomb on two string litterals in the format.
353 : static const char* TMP_FORMAT = "%" SAL_PRIuUINTPTR;
354 :
355 1073 : void SwFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
356 : {
357 1073 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
358 1073 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "id" ), "%" SAL_PRIuUINT32, GetFrmId() );
359 1073 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "symbol" ), "%s", BAD_CAST( typeid( *this ).name( ) ) );
360 1073 : if ( GetNext( ) )
361 570 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "next" ), "%" SAL_PRIuUINT32, GetNext()->GetFrmId() );
362 1073 : if ( GetPrev( ) )
363 570 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "prev" ), "%" SAL_PRIuUINT32, GetPrev()->GetFrmId() );
364 1073 : if ( GetUpper( ) )
365 1053 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "upper" ), "%" SAL_PRIuUINT32, GetUpper()->GetFrmId() );
366 1073 : if ( GetLower( ) )
367 483 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "lower" ), "%" SAL_PRIuUINT32, GetLower()->GetFrmId() );
368 1073 : if ( IsTxtFrm( ) )
369 : {
370 590 : SwTxtFrm *pTxtFrm = ( SwTxtFrm * ) this;
371 590 : SwTxtNode *pTxtNode = pTxtFrm->GetTxtNode();
372 590 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "txtNodeIndex" ), TMP_FORMAT, pTxtNode->GetIndex() );
373 : }
374 1073 : if (IsHeaderFrm() || IsFooterFrm())
375 : {
376 72 : SwHeadFootFrm *pHeadFootFrm = (SwHeadFootFrm*)this;
377 72 : OUString aFmtName = pHeadFootFrm->GetFmt()->GetName();
378 72 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "fmtName" ), "%s", BAD_CAST(OUStringToOString(aFmtName, RTL_TEXTENCODING_UTF8).getStr()));
379 72 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "fmtPtr" ), "%p", pHeadFootFrm->GetFmt());
380 : }
381 1073 : }
382 :
383 483 : void SwFrm::dumpChildrenAsXml( xmlTextWriterPtr writer )
384 : {
385 483 : SwFrm *pFrm = GetLower( );
386 1536 : for ( ; pFrm != NULL; pFrm = pFrm->GetNext( ) )
387 : {
388 1053 : pFrm->dumpAsXml( writer );
389 : }
390 483 : }
391 :
392 13 : void SwAnchoredObject::dumpAsXml( xmlTextWriterPtr writer )
393 : {
394 13 : bool bCreateWriter = ( NULL == writer );
395 13 : if ( bCreateWriter )
396 0 : writer = lcl_createDefaultWriter();
397 :
398 13 : xmlTextWriterStartElement( writer, BAD_CAST( getElementName() ) );
399 13 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
400 13 : xmlTextWriterEndElement( writer );
401 :
402 13 : if ( bCreateWriter )
403 0 : lcl_freeWriter( writer );
404 13 : }
405 :
406 590 : void SwTxtFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
407 : {
408 590 : SwFrm::dumpAsXmlAttributes( writer );
409 590 : if ( HasFollow() )
410 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
411 :
412 590 : if (m_pPrecede != NULL)
413 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwTxtFrm*>(m_pPrecede)->GetFrmId() );
414 590 : }
415 :
416 1 : void SwSectionFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
417 : {
418 1 : SwFrm::dumpAsXmlAttributes( writer );
419 1 : if ( HasFollow() )
420 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
421 :
422 1 : if (m_pPrecede != NULL)
423 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwSectionFrm*>( m_pPrecede )->GetFrmId() );
424 1 : }
425 :
426 10 : void SwTabFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
427 : {
428 10 : SwFrm::dumpAsXmlAttributes( writer );
429 10 : if ( HasFollow() )
430 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
431 :
432 10 : if (m_pPrecede != NULL)
433 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwTabFrm*>( m_pPrecede )->GetFrmId() );
434 109 : }
435 :
436 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|