Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <hintids.hxx>
31 : : #include <vcl/font.hxx>
32 : : #include <editeng/fontitem.hxx>
33 : : #include <editeng/lrspitem.hxx>
34 : : #include <doc.hxx>
35 : : #include <docary.hxx>
36 : : #include <numrule.hxx>
37 : : #include <paratr.hxx>
38 : : #include <charfmt.hxx>
39 : : #include <ndtxt.hxx>
40 : : #include <com/sun/star/i18n/ScriptType.hpp>
41 : :
42 : : #include <writerfilter/doctok/sprmids.hxx>
43 : :
44 : : #include "ww8attributeoutput.hxx"
45 : : #include "writerhelper.hxx"
46 : : #include "writerwordglue.hxx"
47 : : #include "wrtww8.hxx"
48 : : #include "ww8par.hxx"
49 : :
50 : : using namespace ::com::sun::star;
51 : : using namespace sw::types;
52 : : using namespace sw::util;
53 : :
54 : 0 : sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8 nLevel, sal_uInt16 nVal )
55 : : {
56 : 0 : sal_uInt16 nNumId = USHRT_MAX;
57 [ # # ]: 0 : String sPrefix(rtl::OUString("WW8TempExport"));
58 [ # # ][ # # ]: 0 : sPrefix += String::CreateFromInt32( nUniqueList++ );
[ # # ]
59 : : SwNumRule* pMyNumRule =
60 : : new SwNumRule( pDoc->GetUniqueNumRuleName( &sPrefix ),
61 [ # # ][ # # ]: 0 : SvxNumberFormat::LABEL_WIDTH_AND_POSITION );
[ # # ][ # # ]
62 [ # # ]: 0 : pUsedNumTbl->push_back( pMyNumRule );
63 : :
64 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < MAXLEVEL; i++ )
65 : : {
66 [ # # ]: 0 : const SwNumFmt& rSubRule = pRule->Get(i);
67 [ # # ]: 0 : pMyNumRule->Set( i, rSubRule );
68 : : }
69 : :
70 [ # # ][ # # ]: 0 : SwNumFmt aNumFmt( pMyNumRule->Get( nLevel ) );
71 : 0 : aNumFmt.SetStart( nVal );
72 [ # # ]: 0 : pMyNumRule->Set( nLevel, aNumFmt );
73 : :
74 [ # # ]: 0 : nNumId = GetId( *pMyNumRule );
75 : :
76 : : //Map the old list to our new list
77 [ # # ][ # # ]: 0 : aRuleDuplicates[GetId( *pRule )] = nNumId;
78 : :
79 [ # # ][ # # ]: 0 : return nNumId;
80 : : }
81 : :
82 : 18 : sal_uInt16 MSWordExportBase::GetId( const SwNumRule& rNumRule )
83 : : {
84 [ + + ]: 18 : if ( !pUsedNumTbl )
85 : : {
86 [ + - ][ + - ]: 3 : pUsedNumTbl = new SwNumRuleTbl;
87 [ + - ]: 3 : pUsedNumTbl->insert( pUsedNumTbl->begin(), pDoc->GetNumRuleTbl().begin(), pDoc->GetNumRuleTbl().end() );
88 : : // Check, if the outline rule is already inserted into <pUsedNumTbl>.
89 : : // If yes, do not insert it again.
90 : 3 : bool bOutlineRuleAdded( false );
91 [ + + ]: 12 : for ( sal_uInt16 n = pUsedNumTbl->size(); n; )
92 : : {
93 : 9 : const SwNumRule& rRule = *(*pUsedNumTbl)[ --n ];
94 [ + + ][ + - ]: 9 : if ( !pDoc->IsUsed( rRule ) )
95 : : {
96 [ + - ][ + - ]: 6 : pUsedNumTbl->erase( pUsedNumTbl->begin() + n );
97 : : }
98 [ + - ]: 3 : else if ( &rRule == pDoc->GetOutlineNumRule() )
99 : : {
100 : 3 : bOutlineRuleAdded = true;
101 : : }
102 : : }
103 : :
104 [ - + ]: 3 : if ( !bOutlineRuleAdded )
105 : : {
106 : : // jetzt noch die OutlineRule einfuegen
107 : 0 : SwNumRule* pR = (SwNumRule*)pDoc->GetOutlineNumRule();
108 [ # # ]: 0 : pUsedNumTbl->push_back( pR );
109 : : }
110 : : }
111 : 18 : SwNumRule* p = (SwNumRule*)&rNumRule;
112 [ + - ]: 18 : sal_uInt16 nRet = pUsedNumTbl->GetPos(p);
113 : :
114 : : //Is this list now duplicated into a new list which we should use
115 : : // #i77812# - perform 'deep' search in duplication map
116 [ + - ]: 18 : ::std::map<sal_uInt16,sal_uInt16>::const_iterator aResult = aRuleDuplicates.end();
117 [ + - ][ - + ]: 18 : do {
118 [ + - ][ + - ]: 18 : aResult = aRuleDuplicates.find(nRet);
119 [ + - ][ + - ]: 18 : if ( aResult != aRuleDuplicates.end() )
[ - + ]
120 : : {
121 [ # # ]: 0 : nRet = (*aResult).second;
122 : : }
123 [ + - ]: 18 : } while ( aResult != aRuleDuplicates.end() );
124 : :
125 : 18 : return nRet;
126 : : }
127 : :
128 : : //GetFirstLineOffset should problem never appear unadorned apart from
129 : : //here in the ww export filter
130 : 0 : sal_Int16 GetWordFirstLineOffset(const SwNumFmt &rFmt)
131 : : {
132 : : OSL_ENSURE( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION,
133 : : "<GetWordFirstLineOffset> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION" );
134 : :
135 : : short nFirstLineOffset;
136 [ # # ]: 0 : if (rFmt.GetNumAdjust() == SVX_ADJUST_RIGHT)
137 : 0 : nFirstLineOffset = -rFmt.GetCharTextDistance();
138 : : else
139 : 0 : nFirstLineOffset = rFmt.GetFirstLineOffset();
140 : 0 : return nFirstLineOffset;
141 : : }
142 : :
143 : 9 : void WW8Export::WriteNumbering()
144 : : {
145 [ + + ]: 9 : if ( !pUsedNumTbl )
146 : 9 : return; // no numbering is used
147 : :
148 : : // list formats - LSTF
149 : 3 : pFib->fcPlcfLst = pTableStrm->Tell();
150 : 3 : SwWW8Writer::WriteShort( *pTableStrm, pUsedNumTbl->size() );
151 : 3 : NumberingDefinitions();
152 : : // set len to FIB
153 : 3 : pFib->lcbPlcfLst = pTableStrm->Tell() - pFib->fcPlcfLst;
154 : :
155 : : // list formats - LVLF
156 : 3 : AbstractNumberingDefinitions();
157 : :
158 : : // list formats - LFO
159 : 3 : OutOverrideListTab();
160 : :
161 : : // list formats - ListNames
162 : 3 : OutListNamesTab();
163 : : }
164 : :
165 : 3 : void WW8AttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule )
166 : : {
167 : 3 : SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nId );
168 : 3 : SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nId );
169 : :
170 : : // mit keinen Styles verbunden
171 [ + + ]: 30 : for ( int i = 0; i < WW8ListManager::nMaxLevel; ++i )
172 : 27 : SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0xFFF );
173 : :
174 : 3 : sal_uInt8 nFlags = 0, nDummy = 0;
175 [ - + ]: 3 : if ( rRule.IsContinusNum() )
176 : 0 : nFlags |= 0x1;
177 : :
178 : 3 : *m_rWW8Export.pTableStrm << nFlags << nDummy;
179 : 3 : }
180 : :
181 : 3 : void MSWordExportBase::NumberingDefinitions()
182 : : {
183 [ - + ]: 3 : if ( !pUsedNumTbl )
184 : 3 : return; // no numbering is used
185 : :
186 : 3 : sal_uInt16 nCount = pUsedNumTbl->size();
187 : :
188 : : // Write static data of SwNumRule - LSTF
189 [ + + ]: 6 : for ( sal_uInt16 n = 0; n < nCount; ++n )
190 : : {
191 : 3 : const SwNumRule& rRule = *(*pUsedNumTbl)[ n ];
192 : :
193 : 3 : AttrOutput().NumberingDefinition( n + 1, rRule );
194 : : }
195 : : }
196 : :
197 : 27 : void WW8AttributeOutput::NumberingLevel( sal_uInt8 /*nLevel*/,
198 : : sal_uInt16 nStart,
199 : : sal_uInt16 nNumberingType,
200 : : SvxAdjust eAdjust,
201 : : const sal_uInt8 *pNumLvlPos,
202 : : sal_uInt8 nFollow,
203 : : const wwFont *pFont,
204 : : const SfxItemSet *pOutSet,
205 : : sal_Int16 nIndentAt,
206 : : sal_Int16 nFirstLineIndex,
207 : : sal_Int16 nListTabPos,
208 : : const String &rNumberingString
209 : : )
210 : : {
211 : : // Start value
212 [ + - ]: 27 : SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nStart );
213 : :
214 : : // Type
215 [ + - ][ + - ]: 27 : *m_rWW8Export.pTableStrm << WW8Export::GetNumId( nNumberingType );
216 : :
217 : : // Justification
218 : : sal_uInt8 nAlign;
219 [ - - + ]: 27 : switch ( eAdjust )
220 : : {
221 : : case SVX_ADJUST_CENTER:
222 : 0 : nAlign = 1;
223 : 0 : break;
224 : : case SVX_ADJUST_RIGHT:
225 : 0 : nAlign = 2;
226 : 0 : break;
227 : : default:
228 : 27 : nAlign = 0;
229 : 27 : break;
230 : : }
231 [ + - ]: 27 : *m_rWW8Export.pTableStrm << nAlign;
232 : :
233 : : // Write the rgbxchNums[9], positions of placeholders for paragraph
234 : : // numbers in the text
235 [ + - ]: 27 : m_rWW8Export.pTableStrm->Write( pNumLvlPos, WW8ListManager::nMaxLevel );
236 : :
237 : : // Type of the character between the bullet and the text
238 [ + - ]: 27 : *m_rWW8Export.pTableStrm << nFollow;
239 : :
240 : : // dxaSoace/dxaIndent (Word 6 compatibility)
241 [ + - ]: 27 : SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 );
242 [ + - ]: 27 : SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 );
243 : :
244 : : // cbGrpprlChpx
245 [ + - ]: 27 : ww::bytes aCharAtrs;
246 [ - + ]: 27 : if ( pOutSet )
247 : : {
248 : 0 : ww::bytes* pOldpO = m_rWW8Export.pO;
249 : 0 : m_rWW8Export.pO = &aCharAtrs;
250 [ # # ]: 0 : if ( pFont )
251 : : {
252 [ # # ]: 0 : sal_uInt16 nFontID = m_rWW8Export.maFontHelper.GetId( *pFont );
253 : :
254 [ # # ]: 0 : if ( m_rWW8Export.bWrtWW8 )
255 : : {
256 [ # # ]: 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc0 );
257 [ # # ]: 0 : m_rWW8Export.InsUInt16( nFontID );
258 [ # # ]: 0 : m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc2 );
259 : : }
260 : : else
261 [ # # ]: 0 : m_rWW8Export.pO->push_back( 93 );
262 [ # # ]: 0 : m_rWW8Export.InsUInt16( nFontID );
263 : : }
264 : :
265 [ # # ]: 0 : m_rWW8Export.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN, m_rWW8Export.mbExportModeRTF );
266 : :
267 : 0 : m_rWW8Export.pO = pOldpO;
268 : : }
269 [ + - ]: 27 : *m_rWW8Export.pTableStrm << sal_uInt8( aCharAtrs.size() );
270 : :
271 : : // cbGrpprlPapx
272 : : sal_uInt8 aPapSprms [] = {
273 : : 0x5e, 0x84, 0, 0, // sprmPDxaLeft
274 : : 0x60, 0x84, 0, 0, // sprmPDxaLeft1
275 : : 0x15, 0xc6, 0x05, 0x00, 0x01, 0, 0, 0x06
276 : 27 : };
277 [ + - ]: 27 : *m_rWW8Export.pTableStrm << sal_uInt8( sizeof( aPapSprms ) );
278 : :
279 : : // reserved
280 [ + - ]: 27 : SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0 );
281 : :
282 : : // pap sprms
283 : 27 : sal_uInt8* pData = aPapSprms + 2;
284 : 27 : Set_UInt16( pData, nIndentAt );
285 : 27 : pData += 2;
286 : 27 : Set_UInt16( pData, nFirstLineIndex );
287 : 27 : pData += 5;
288 : 27 : Set_UInt16( pData, nListTabPos );
289 : :
290 [ + - ]: 27 : m_rWW8Export.pTableStrm->Write( aPapSprms, sizeof( aPapSprms ));
291 : :
292 : : // write Chpx
293 [ - + ]: 27 : if( !aCharAtrs.empty() )
294 [ # # ][ # # ]: 0 : m_rWW8Export.pTableStrm->Write( aCharAtrs.data(), aCharAtrs.size() );
295 : :
296 : : // write the num string
297 [ + - ]: 27 : SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, rNumberingString.Len() );
298 [ + - ]: 27 : SwWW8Writer::WriteString16( *m_rWW8Export.pTableStrm, rNumberingString, false );
299 : 27 : }
300 : :
301 : 3 : void MSWordExportBase::AbstractNumberingDefinitions()
302 : : {
303 : 3 : sal_uInt16 nCount = pUsedNumTbl->size();
304 : : sal_uInt16 n;
305 : :
306 : : // prepare the NodeNum to generate the NumString
307 [ + - ]: 3 : SwNumberTree::tNumberVector aNumVector;
308 [ + + ]: 30 : for ( n = 0; n < WW8ListManager::nMaxLevel; ++n )
309 [ + - ]: 27 : aNumVector.push_back( n );
310 : :
311 : 3 : StarSymbolToMSMultiFont *pConvert = 0;
312 [ + + ]: 6 : for( n = 0; n < nCount; ++n )
313 : : {
314 [ + - ][ + - ]: 3 : AttrOutput().StartAbstractNumbering( n + 1 );
315 : :
316 : 3 : const SwNumRule& rRule = *(*pUsedNumTbl)[ n ];
317 : : sal_uInt8 nLvl;
318 : 3 : sal_uInt8 nLevels = static_cast< sal_uInt8 >(rRule.IsContinusNum() ?
319 [ - + ]: 3 : WW8ListManager::nMinLevel : WW8ListManager::nMaxLevel);
320 [ + + ]: 30 : for( nLvl = 0; nLvl < nLevels; ++nLvl )
321 : : {
322 : : // write the static data of the SwNumFmt of this level
323 : 27 : sal_uInt8 aNumLvlPos[WW8ListManager::nMaxLevel] = { 0,0,0,0,0,0,0,0,0 };
324 : :
325 [ + - ]: 27 : const SwNumFmt& rFmt = rRule.Get( nLvl );
326 : :
327 : 27 : sal_uInt8 nFollow = 0;
328 : : // #i86652#
329 [ + - ][ - + ]: 27 : if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
330 : : {
331 : 0 : nFollow = 2; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
332 : : }
333 [ + - ][ + - ]: 27 : else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
334 : : {
335 [ + - ]: 27 : switch ( rFmt.GetLabelFollowedBy() )
[ - - + - ]
336 : : {
337 : : case SvxNumberFormat::LISTTAB:
338 : : {
339 : : // 0 (tab) unless there would be no content before the tab, in which case 2 (nothing)
340 [ # # ]: 0 : nFollow = (SVX_NUM_NUMBER_NONE != rFmt.GetNumberingType()) ? 0 : 2;
341 : : }
342 : 0 : break;
343 : : case SvxNumberFormat::SPACE:
344 : : {
345 : : // 1 (space) unless there would be no content before the space in which case 2 (nothing)
346 [ # # ]: 0 : nFollow = (SVX_NUM_NUMBER_NONE != rFmt.GetNumberingType()) ? 1 : 2;
347 : : }
348 : 0 : break;
349 : : case SvxNumberFormat::NOTHING:
350 : : {
351 : 27 : nFollow = 2;
352 : : }
353 : 27 : break;
354 : : default:
355 : : {
356 : 27 : nFollow = 0;
357 : : OSL_FAIL( "unknown GetLabelFollowedBy() return value" );
358 : : }
359 : : }
360 : : }
361 : :
362 : : // Build the NumString for this Level
363 [ + - ]: 27 : String sNumStr;
364 [ + - ]: 27 : String sFontName;
365 : 27 : bool bWriteBullet = false;
366 : 27 : const Font* pBulletFont=0;
367 : 27 : rtl_TextEncoding eChrSet=0;
368 : 27 : FontFamily eFamily=FAMILY_DECORATIVE;
369 [ + - - + ]: 54 : if( SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType() ||
[ - + ]
370 : 27 : SVX_NUM_BITMAP == rFmt.GetNumberingType() )
371 : : {
372 [ # # ]: 0 : sNumStr = rFmt.GetBulletChar();
373 : 0 : bWriteBullet = true;
374 : :
375 : 0 : pBulletFont = rFmt.GetBulletFont();
376 [ # # ]: 0 : if (!pBulletFont)
377 : : {
378 [ # # ]: 0 : pBulletFont = &numfunc::GetDefBulletFont();
379 : : }
380 : :
381 [ # # ]: 0 : eChrSet = pBulletFont->GetCharSet();
382 [ # # ][ # # ]: 0 : sFontName = pBulletFont->GetName();
383 [ # # ]: 0 : eFamily = pBulletFont->GetFamily();
384 : :
385 [ # # ][ # # ]: 0 : if ( sw::util::IsStarSymbol( sFontName ) )
[ # # ]
386 [ # # ]: 0 : SubstituteBullet( sNumStr, eChrSet, sFontName );
387 : :
388 : : // #i86652#
389 [ # # ][ # # ]: 0 : if ( rFmt.GetPositionAndSpaceMode() ==
390 : : SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
391 : : {
392 : : // <nFollow = 2>, if minimum label width equals 0 and
393 : : // minimum distance between label and text equals 0
394 [ # # ]: 0 : nFollow = ( rFmt.GetFirstLineOffset() == 0 &&
395 [ # # ]: 0 : rFmt.GetCharTextDistance() == 0 )
396 [ # # ][ # # ]: 0 : ? 2 : 0; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
397 : : }
398 : : }
399 : : else
400 : : {
401 [ - + ]: 27 : if (SVX_NUM_NUMBER_NONE != rFmt.GetNumberingType())
402 : : {
403 : 0 : sal_uInt8* pLvlPos = aNumLvlPos;
404 : : // the numbering string has to be restrict
405 : : // to the level currently working on.
406 [ # # ][ # # ]: 0 : sNumStr = rRule.MakeNumString(aNumVector, false, true, nLvl);
[ # # ]
407 : :
408 : : // now search the nums in the string
409 [ # # ]: 0 : for( sal_uInt8 i = 0; i <= nLvl; ++i )
410 : : {
411 [ # # ]: 0 : String sSrch( String::CreateFromInt32( i ));
412 [ # # ]: 0 : xub_StrLen nFnd = sNumStr.Search( sSrch );
413 [ # # ]: 0 : if( STRING_NOTFOUND != nFnd )
414 : : {
415 : 0 : *pLvlPos = (sal_uInt8)(nFnd + rFmt.GetPrefix().getLength() + 1 );
416 : 0 : ++pLvlPos;
417 [ # # ]: 0 : sNumStr.SetChar( nFnd, (char)i );
418 : : }
419 [ # # ]: 0 : }
420 : : // #i86652#
421 [ # # ][ # # ]: 0 : if ( rFmt.GetPositionAndSpaceMode() ==
422 : : SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
423 : : {
424 : : // <nFollow = 2>, if minimum label width equals 0 and
425 : : // minimum distance between label and text equals 0
426 [ # # ]: 0 : nFollow = ( rFmt.GetFirstLineOffset() == 0 &&
427 [ # # ]: 0 : rFmt.GetCharTextDistance() == 0 )
428 [ # # ][ # # ]: 0 : ? 2 : 0; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
429 : : }
430 : : }
431 : :
432 [ - + ]: 27 : if( !rFmt.GetPrefix().isEmpty() )
433 [ # # ][ # # ]: 0 : sNumStr.Insert( rFmt.GetPrefix(), 0 );
[ # # ]
434 [ + - ]: 27 : sNumStr += rFmt.GetSuffix();
435 : : }
436 : :
437 : : // Attributes of the numbering
438 : 27 : wwFont *pPseudoFont = NULL;
439 : 27 : const SfxItemSet* pOutSet = NULL;
440 : :
441 : : // cbGrpprlChpx
442 : 27 : SfxItemSet aSet( pDoc->GetAttrPool(), RES_CHRATR_BEGIN,
443 [ + - ]: 27 : RES_CHRATR_END );
444 [ + - ][ - + ]: 27 : if ( rFmt.GetCharFmt() || bWriteBullet )
[ - + ]
445 : : {
446 [ # # ]: 0 : if ( bWriteBullet )
447 : : {
448 : 0 : pOutSet = &aSet;
449 : :
450 [ # # ]: 0 : if ( rFmt.GetCharFmt() )
451 [ # # ]: 0 : aSet.Put( rFmt.GetCharFmt()->GetAttrSet() );
452 [ # # ]: 0 : aSet.ClearItem( RES_CHRATR_CJK_FONT );
453 [ # # ]: 0 : aSet.ClearItem( RES_CHRATR_FONT );
454 : :
455 [ # # ]: 0 : if ( !sFontName.Len() )
456 [ # # ][ # # ]: 0 : sFontName = pBulletFont->GetName();
457 : :
458 : : pPseudoFont = new wwFont( sFontName, pBulletFont->GetPitch(),
459 [ # # ][ # # ]: 0 : eFamily, eChrSet, SupportsUnicode() );
[ # # ][ # # ]
460 : : }
461 : : else
462 : 0 : pOutSet = &rFmt.GetCharFmt()->GetAttrSet();
463 : : }
464 : :
465 : 27 : sal_Int16 nIndentAt = 0;
466 : 27 : sal_Int16 nFirstLineIndex = 0;
467 : 27 : sal_Int16 nListTabPos = 0;
468 : :
469 : : // #i86652#
470 [ + - ][ - + ]: 27 : if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
471 : : {
472 [ # # ]: 0 : nIndentAt = nListTabPos = rFmt.GetAbsLSpace();
473 [ # # ]: 0 : nFirstLineIndex = GetWordFirstLineOffset(rFmt);
474 : : }
475 [ + - ][ + - ]: 27 : else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
476 : : {
477 [ + - ]: 27 : nIndentAt = static_cast<sal_Int16>(rFmt.GetIndentAt());
478 [ + - ]: 27 : nFirstLineIndex = static_cast<sal_Int16>(rFmt.GetFirstLineIndent());
479 [ + - ]: 27 : nListTabPos = rFmt.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB?
480 [ - + ][ # # ]: 27 : static_cast<sal_Int16>( rFmt.GetListtabPos() ) : 0;
481 : : }
482 : :
483 [ + - ]: 27 : AttrOutput().NumberingLevel( nLvl,
484 : 27 : rFmt.GetStart(),
485 : 27 : rFmt.GetNumberingType(),
486 : : rFmt.GetNumAdjust(),
487 : : aNumLvlPos,
488 : : nFollow,
489 : : pPseudoFont, pOutSet,
490 : : nIndentAt, nFirstLineIndex, nListTabPos,
491 [ + - ]: 54 : sNumStr );
492 : :
493 [ - + ][ # # ]: 27 : delete pPseudoFont;
494 [ + - ][ + - ]: 27 : }
[ + - ]
495 [ + - ][ + - ]: 3 : AttrOutput().EndAbstractNumbering();
496 : : }
497 [ - + ][ # # ]: 3 : delete pConvert;
498 : 3 : }
499 : :
500 : 3 : void WW8Export::OutOverrideListTab()
501 : : {
502 [ - + ]: 3 : if( !pUsedNumTbl )
503 : 3 : return ; // no numbering is used
504 : :
505 : : // write the "list format override" - LFO
506 : 3 : sal_uInt16 nCount = pUsedNumTbl->size();
507 : : sal_uInt16 n;
508 : :
509 : 3 : pFib->fcPlfLfo = pTableStrm->Tell();
510 : 3 : SwWW8Writer::WriteLong( *pTableStrm, nCount );
511 : :
512 [ + + ]: 6 : for( n = 0; n < nCount; ++n )
513 : : {
514 : 3 : SwWW8Writer::WriteLong( *pTableStrm, n + 1 );
515 : 3 : SwWW8Writer::FillCount( *pTableStrm, 12 );
516 : : }
517 [ + + ]: 6 : for( n = 0; n < nCount; ++n )
518 : 3 : SwWW8Writer::WriteLong( *pTableStrm, -1 ); // no overwrite
519 : :
520 : : // set len to FIB
521 : 3 : pFib->lcbPlfLfo = pTableStrm->Tell() - pFib->fcPlfLfo;
522 : : }
523 : :
524 : 3 : void WW8Export::OutListNamesTab()
525 : : {
526 [ - + ]: 3 : if( !pUsedNumTbl )
527 : 3 : return ; // no numbering is used
528 : :
529 : : // write the "list format override" - LFO
530 : 3 : sal_uInt16 nNms = 0, nCount = pUsedNumTbl->size();
531 : :
532 : 3 : pFib->fcSttbListNames = pTableStrm->Tell();
533 : 3 : SwWW8Writer::WriteShort( *pTableStrm, -1 );
534 : 3 : SwWW8Writer::WriteLong( *pTableStrm, nCount );
535 : :
536 [ + + ]: 6 : for( ; nNms < nCount; ++nNms )
537 : : {
538 : 3 : const SwNumRule& rRule = *(*pUsedNumTbl)[ nNms ];
539 [ + - ]: 3 : String sNm;
540 [ - + ]: 3 : if( !rRule.IsAutoRule() )
541 [ # # ]: 0 : sNm = rRule.GetName();
542 : :
543 [ + - ]: 3 : SwWW8Writer::WriteShort( *pTableStrm, sNm.Len() );
544 [ - + ]: 3 : if (sNm.Len())
545 [ # # ]: 0 : SwWW8Writer::WriteString16(*pTableStrm, sNm, false);
546 [ + - ]: 3 : }
547 : :
548 : 3 : SwWW8Writer::WriteLong( *pTableStrm, pFib->fcSttbListNames + 2, nNms );
549 : : // set len to FIB
550 : 3 : pFib->lcbSttbListNames = pTableStrm->Tell() - pFib->fcSttbListNames;
551 : : }
552 : :
553 : :
554 : : // old WW95-Code
555 : :
556 : 0 : void WW8Export::OutputOlst( const SwNumRule& rRule )
557 : : {
558 [ # # ]: 0 : if ( bWrtWW8 )
559 : 0 : return;
560 : :
561 : : static sal_uInt8 aAnlvBase[] = { // Defaults
562 : : 1,0,0, // Upper Roman
563 : : 0x0C, // Hanging Indent, fPrev
564 : : 0,0,1,0x80,0,0,1,0,0x1b,1,0,0 };
565 : :
566 : : static sal_uInt8 aSprmOlstHdr[] = { 133, 212 };
567 : :
568 [ # # ]: 0 : pO->insert( pO->end(), aSprmOlstHdr, aSprmOlstHdr+sizeof( aSprmOlstHdr ) );
569 : : WW8_OLST aOlst;
570 : 0 : memset( &aOlst, 0, sizeof(aOlst) );
571 : 0 : sal_uInt8* pC = aOlst.rgch;
572 : 0 : sal_uInt8* pChars = (sal_uInt8*)pC;
573 : 0 : sal_uInt16 nCharLen = 64;
574 : :
575 [ # # ]: 0 : for (sal_uInt16 j = 0; j < WW8ListManager::nMaxLevel; j++ ) // 9 variable ANLVs
576 : : {
577 : 0 : memcpy( &aOlst.rganlv[j], aAnlvBase, sizeof( WW8_ANLV ) ); // Defaults
578 : :
579 [ # # ]: 0 : const SwNumFmt* pFmt = rRule.GetNumFmt( j );
580 [ # # ]: 0 : if( pFmt )
581 : 0 : BuildAnlvBase( aOlst.rganlv[j], pChars, nCharLen, rRule,
582 [ # # ]: 0 : *pFmt, (sal_uInt8)j );
583 : : }
584 : :
585 [ # # ]: 0 : pO->insert( pO->end(), (sal_uInt8*)&aOlst, (sal_uInt8*)&aOlst+sizeof( aOlst ) );
586 : : }
587 : :
588 : :
589 : 0 : void WW8Export::Out_WwNumLvl( sal_uInt8 nWwLevel )
590 : : {
591 [ # # ]: 0 : pO->push_back( 13 );
592 : 0 : pO->push_back( nWwLevel );
593 : 0 : }
594 : :
595 : 0 : void WW8Export::Out_SwNumLvl( sal_uInt8 nSwLevel )
596 : : {
597 : : OSL_ENSURE( nSwLevel < MAXLEVEL, "numbered?");
598 : 0 : Out_WwNumLvl( nSwLevel + 1 );
599 : 0 : }
600 : :
601 : 0 : void WW8Export::BuildAnlvBulletBase(WW8_ANLV& rAnlv, sal_uInt8*& rpCh,
602 : : sal_uInt16& rCharLen, const SwNumFmt& rFmt)
603 : : {
604 : 0 : ByteToSVBT8(11, rAnlv.nfc);
605 : :
606 : 0 : sal_uInt8 nb = 0; // Zahlentyp
607 [ # # # # : 0 : switch (rFmt.GetNumAdjust())
# ]
608 : : {
609 : : case SVX_ADJUST_RIGHT:
610 : 0 : nb = 2;
611 : 0 : break;
612 : : case SVX_ADJUST_CENTER:
613 : 0 : nb = 1;
614 : 0 : break;
615 : : case SVX_ADJUST_BLOCK:
616 : : case SVX_ADJUST_BLOCKLINE:
617 : 0 : nb = 3;
618 : 0 : break;
619 : : case SVX_ADJUST_LEFT:
620 : : case SVX_ADJUST_END:
621 : 0 : break;
622 : : }
623 : :
624 : : // #i86652#
625 [ # # ]: 0 : if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
626 : : {
627 [ # # ]: 0 : if (GetWordFirstLineOffset(rFmt) < 0)
628 : 0 : nb |= 0x8; // number will be displayed using a hanging indent
629 : : }
630 : 0 : ByteToSVBT8(nb, rAnlv.aBits1);
631 : :
632 [ # # ]: 0 : if (1 < rCharLen)
633 : : {
634 : 0 : const Font& rFont = rFmt.GetBulletFont()
635 : 0 : ? *rFmt.GetBulletFont()
636 [ # # ][ # # ]: 0 : : numfunc::GetDefBulletFont();
637 [ # # ]: 0 : String sNumStr = rtl::OUString(rFmt.GetBulletChar());
638 [ # # ]: 0 : rtl_TextEncoding eChrSet = rFont.GetCharSet();
639 [ # # ][ # # ]: 0 : String sFontName = rFont.GetName();
640 : :
641 : : sal_uInt16 nFontId;
642 [ # # ][ # # ]: 0 : if (sw::util::IsStarSymbol(sFontName))
[ # # ]
643 : : {
644 : : /*
645 : : If we are starsymbol then in ww7- mode we will always convert to a
646 : : windows 8bit symbol font and an index into it, to conversion to
647 : : 8 bit is complete at this stage.
648 : : */
649 [ # # ]: 0 : SubstituteBullet(sNumStr, eChrSet, sFontName);
650 : : wwFont aPseudoFont(sFontName, rFont.GetPitch(), rFont.GetFamily(),
651 [ # # ][ # # ]: 0 : eChrSet, bWrtWW8);
[ # # ]
652 [ # # ]: 0 : nFontId = maFontHelper.GetId(aPseudoFont);
653 [ # # ]: 0 : *rpCh = static_cast<sal_uInt8>(sNumStr.GetChar(0));
654 : : }
655 : : else
656 : : {
657 : : /*
658 : : Otherwise we are a unicode char and need to be converted back to
659 : : an 8 bit format. We happen to know that if the font is already an
660 : : 8 bit windows font currently, staroffice promotes the char into
661 : : the F000->F0FF range, so we can undo this, and we'll be back to
662 : : the equivalent 8bit location, otherwise we have to convert from
663 : : true unicode to an 8bit charset
664 : : */
665 [ # # ]: 0 : nFontId = maFontHelper.GetId(rFont);
666 : 0 : sal_Unicode cChar = sNumStr.GetChar(0);
667 [ # # ][ # # ]: 0 : if ( (eChrSet == RTL_TEXTENCODING_SYMBOL) && (cChar >= 0xF000) && (
[ # # ]
668 : : cChar <= 0xF0FF) )
669 : : {
670 : 0 : *rpCh = static_cast< sal_uInt8 >(cChar - 0xF000);
671 : : }
672 : : else
673 [ # # ]: 0 : *rpCh = rtl::OUStringToOString(rtl::OUString(cChar), eChrSet).toChar();
674 : : }
675 : 0 : rpCh++;
676 : 0 : rCharLen--;
677 : 0 : ShortToSVBT16(nFontId, rAnlv.ftc);
678 [ # # ][ # # ]: 0 : ByteToSVBT8( 1, rAnlv.cbTextBefore );
679 : : }
680 : : // #i86652#
681 [ # # ]: 0 : if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
682 : : {
683 : 0 : ShortToSVBT16( -GetWordFirstLineOffset(rFmt), rAnlv.dxaIndent );
684 : 0 : ShortToSVBT16( rFmt.GetCharTextDistance(), rAnlv.dxaSpace );
685 : : }
686 : : else
687 : : {
688 : 0 : ShortToSVBT16( 0, rAnlv.dxaIndent );
689 : 0 : ShortToSVBT16( 0, rAnlv.dxaSpace );
690 : : }
691 : 0 : }
692 : :
693 : 0 : void MSWordExportBase::SubstituteBullet( String& rNumStr,
694 : : rtl_TextEncoding& rChrSet, String& rFontName ) const
695 : : {
696 [ # # ]: 0 : if (!bSubstituteBullets)
697 : 0 : return;
698 [ # # ]: 0 : rtl::OUString sFontName = rFontName;
699 : 0 : rNumStr.SetChar(0, msfilter::util::bestFitOpenSymbolToMSFont(rNumStr.GetChar(0),
700 [ # # # # ]: 0 : rChrSet, sFontName, !SupportsUnicode()));
[ # # ]
701 [ # # ]: 0 : rFontName = sFontName;
702 : : }
703 : :
704 : 0 : static void SwWw8_InsertAnlText( const String& rStr, sal_uInt8*& rpCh,
705 : : sal_uInt16& rCharLen, SVBT8& r8Len )
706 : : {
707 : 0 : sal_uInt8 nb = 0;
708 [ # # ]: 0 : ww::bytes aO;
709 [ # # ]: 0 : SwWW8Writer::InsAsString8( aO, rStr, RTL_TEXTENCODING_MS_1252 );
710 : :
711 : 0 : sal_uInt16 nCnt = aO.size();
712 [ # # ][ # # ]: 0 : if( nCnt && nCnt < rCharLen )
713 : : {
714 : 0 : nb = (sal_uInt8)nCnt;
715 [ # # ]: 0 : std::copy( aO.begin(), aO.end(), rpCh );
716 : 0 : rpCh += nCnt;
717 : 0 : rCharLen = rCharLen - nCnt;
718 : : }
719 : 0 : ByteToSVBT8( nb, r8Len );
720 : 0 : }
721 : :
722 : 0 : void WW8Export::BuildAnlvBase(WW8_ANLV& rAnlv, sal_uInt8*& rpCh,
723 : : sal_uInt16& rCharLen, const SwNumRule& rRul, const SwNumFmt& rFmt,
724 : : sal_uInt8 nSwLevel)
725 : : {
726 : 0 : ByteToSVBT8(WW8Export::GetNumId(rFmt.GetNumberingType()), rAnlv.nfc);
727 : :
728 : 0 : sal_uInt8 nb = 0;
729 [ # # # # : 0 : switch (rFmt.GetNumAdjust())
# ]
730 : : {
731 : : case SVX_ADJUST_RIGHT:
732 : 0 : nb = 2;
733 : 0 : break;
734 : : case SVX_ADJUST_CENTER:
735 : 0 : nb = 1;
736 : 0 : break;
737 : : case SVX_ADJUST_BLOCK:
738 : : case SVX_ADJUST_BLOCKLINE:
739 : 0 : nb = 3;
740 : 0 : break;
741 : : case SVX_ADJUST_LEFT:
742 : : case SVX_ADJUST_END:
743 : 0 : break;
744 : : }
745 : :
746 : 0 : bool bInclUpper = rFmt.GetIncludeUpperLevels() > 0;
747 [ # # ]: 0 : if( bInclUpper )
748 : 0 : nb |= 0x4; // include previous levels
749 : :
750 [ # # ]: 0 : if (GetWordFirstLineOffset(rFmt) < 0)
751 : 0 : nb |= 0x8; // number will be displayed using a hanging indent
752 : 0 : ByteToSVBT8( nb, rAnlv.aBits1 );
753 : :
754 [ # # ][ # # ]: 0 : if( bInclUpper && !rRul.IsContinusNum() )
[ # # ]
755 : : {
756 [ # # ]: 0 : if( (nSwLevel >= WW8ListManager::nMinLevel )
[ # # # # ]
[ # # ]
757 : : && (nSwLevel<= WW8ListManager::nMaxLevel )
758 : 0 : && (rFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE ) ) // UEberhaupt Nummerierung ?
759 : : { // -> suche, ob noch Zahlen davor
760 : 0 : sal_uInt8 nUpper = rFmt.GetIncludeUpperLevels();
761 [ # # ]: 0 : if( (nUpper <= WW8ListManager::nMaxLevel) &&
[ # # # # ]
762 : 0 : (rRul.Get(nUpper).GetNumberingType() != SVX_NUM_NUMBER_NONE ) ) // Nummerierung drueber ?
763 : : {
764 : : // dann Punkt einfuegen
765 : : SwWw8_InsertAnlText( aDotStr, rpCh, rCharLen,
766 [ # # ]: 0 : rAnlv.cbTextBefore );
767 : : }
768 : :
769 : : }
770 : : }
771 : : else
772 : : {
773 : 0 : SwWw8_InsertAnlText( rFmt.GetPrefix(), rpCh, rCharLen,
774 [ # # ]: 0 : rAnlv.cbTextBefore );
775 : 0 : SwWw8_InsertAnlText( rFmt.GetSuffix(), rpCh, rCharLen,
776 [ # # ]: 0 : rAnlv.cbTextAfter );
777 : : }
778 : :
779 : 0 : ShortToSVBT16( rFmt.GetStart(), rAnlv.iStartAt );
780 : : // #i86652#
781 [ # # ]: 0 : if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
782 : : {
783 : 0 : ShortToSVBT16( -GetWordFirstLineOffset(rFmt), rAnlv.dxaIndent );
784 : 0 : ShortToSVBT16( rFmt.GetCharTextDistance(), rAnlv.dxaSpace );
785 : : }
786 : : else
787 : : {
788 : 0 : ShortToSVBT16( 0, rAnlv.dxaIndent );
789 : 0 : ShortToSVBT16( 0, rAnlv.dxaSpace );
790 : : }
791 : 0 : }
792 : :
793 : 0 : void WW8Export::Out_NumRuleAnld( const SwNumRule& rRul, const SwNumFmt& rFmt,
794 : : sal_uInt8 nSwLevel )
795 : : {
796 : : static sal_uInt8 aSprmAnldDefault[54] = {
797 : : 12, 52,
798 : : 1,0,0,0x0c,0,0,1,0x80,0,0,1,0,0x1b,1,0,0,0x2e,
799 : : 0,0,0,
800 : : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
801 : : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
802 : : sal_uInt8 aSprmAnld[54];
803 : :
804 : 0 : memcpy( aSprmAnld, aSprmAnldDefault, sizeof( aSprmAnld ) );
805 : 0 : WW8_ANLD* pA = (WW8_ANLD*)(aSprmAnld + 2); // handlicher Pointer
806 : :
807 : 0 : sal_uInt8* pChars = (sal_uInt8*)(pA->rgchAnld);
808 : 0 : sal_uInt16 nCharLen = 31;
809 : :
810 [ # # ]: 0 : if( nSwLevel == 11 )
811 [ # # ]: 0 : BuildAnlvBulletBase( pA->eAnlv, pChars, nCharLen, rFmt );
812 : : else
813 [ # # ]: 0 : BuildAnlvBase( pA->eAnlv, pChars, nCharLen, rRul, rFmt, nSwLevel );
814 : :
815 : : // ... und raus damit
816 [ # # ]: 0 : OutSprmBytes( (sal_uInt8*)&aSprmAnld, sizeof( aSprmAnld ) );
817 : 0 : }
818 : :
819 : :
820 : : // Return: ist es eine Gliederung ?
821 : 0 : bool WW8Export::Out_SwNum(const SwTxtNode* pNd)
822 : : {
823 [ # # ]: 0 : int nLevel = pNd->GetActualListLevel();
824 : :
825 [ # # ][ # # ]: 0 : if (nLevel < 0 || nLevel >= MAXLEVEL)
826 : : {
827 : : OSL_FAIL("Invalid level");
828 : :
829 : 0 : return false;
830 : : }
831 : :
832 : 0 : sal_uInt8 nSwLevel = static_cast< sal_uInt8 >(nLevel);
833 : :
834 [ # # ]: 0 : const SwNumRule* pRul = pNd->GetNumRule();
835 [ # # ][ # # ]: 0 : if( !pRul || nSwLevel == WW8ListManager::nMaxLevel)
836 : 0 : return false;
837 : :
838 : 0 : bool bRet = true;
839 : :
840 [ # # ][ # # ]: 0 : SwNumFmt aFmt(pRul->Get(nSwLevel));
841 : : // #i86652#
842 [ # # ][ # # ]: 0 : if ( aFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
843 : : {
844 [ # # ]: 0 : const SvxLRSpaceItem& rLR = ItemGet<SvxLRSpaceItem>(*pNd, RES_LR_SPACE);
845 [ # # ][ # # ]: 0 : aFmt.SetAbsLSpace(writer_cast<short>(aFmt.GetAbsLSpace() + rLR.GetLeft()));
846 : : }
847 : :
848 [ # # ][ # # : 0 : if (
# # # # ]
849 : 0 : aFmt.GetNumberingType() == SVX_NUM_NUMBER_NONE ||
850 : 0 : aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL ||
851 : 0 : aFmt.GetNumberingType() == SVX_NUM_BITMAP
852 : : )
853 : : {
854 [ # # ]: 0 : Out_WwNumLvl(11);
855 [ # # ]: 0 : Out_NumRuleAnld(*pRul, aFmt, 11);
856 : 0 : bRet = false;
857 : : }
858 [ # # ]: 0 : else if (
[ # # # # ]
859 : 0 : pRul->IsContinusNum() ||
860 [ # # ]: 0 : (pRul->Get(1).GetIncludeUpperLevels() <= 1)
861 : : )
862 : : {
863 [ # # ]: 0 : Out_WwNumLvl(10);
864 [ # # ]: 0 : Out_NumRuleAnld(*pRul, aFmt, 10);
865 : 0 : bRet = false;
866 : : }
867 : : else
868 : : {
869 [ # # ]: 0 : Out_SwNumLvl(nSwLevel);
870 [ # # ]: 0 : Out_NumRuleAnld(*pRul, aFmt, nSwLevel);
871 : : }
872 [ # # ]: 0 : return bRet;
873 [ + - ][ + - ]: 54 : }
874 : :
875 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|