pormulti.cxx (86e1cf34) pormulti.cxx (f6675432)
1/**************************************************************
1/**************************************************************
2 *
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
19 *
20 *************************************************************/
21
22
23
24// MARKER(update_precomp.py): autogen include statement, do not remove
25#include "precompiled_sw.hxx"
26
27
28#include <hintids.hxx>
29
30#include <com/sun/star/i18n/ScriptType.hdl>
31#include <editeng/twolinesitem.hxx>
32#include <editeng/charrotateitem.hxx>
33#include <vcl/outdev.hxx>
34#include <fmtfld.hxx>
20 *************************************************************/
21
22
23
24// MARKER(update_precomp.py): autogen include statement, do not remove
25#include "precompiled_sw.hxx"
26
27
28#include <hintids.hxx>
29
30#include <com/sun/star/i18n/ScriptType.hdl>
31#include <editeng/twolinesitem.hxx>
32#include <editeng/charrotateitem.hxx>
33#include <vcl/outdev.hxx>
34#include <fmtfld.hxx>
35#include <fldbas.hxx> // SwField
35#include <fldbas.hxx> // SwField
36#include <txatbase.hxx>
36#include <txatbase.hxx>
37#include <fmtruby.hxx> // SwFmtRuby
38#include <txtatr.hxx> // SwTxtRuby
37#include <fmtruby.hxx> // SwFmtRuby
38#include <txtatr.hxx> // SwTxtRuby
39#include <charfmt.hxx>
40#include <txtinet.hxx>
41#include <fchrfmt.hxx>
42#include <layfrm.hxx> // GetUpper()
43#include <SwPortionHandler.hxx>
44#include <pormulti.hxx> // SwMultiPortion
45#include <inftxt.hxx> // SwTxtSizeInfo
39#include <charfmt.hxx>
40#include <txtinet.hxx>
41#include <fchrfmt.hxx>
42#include <layfrm.hxx> // GetUpper()
43#include <SwPortionHandler.hxx>
44#include <pormulti.hxx> // SwMultiPortion
45#include <inftxt.hxx> // SwTxtSizeInfo
46#include <itrpaint.hxx> // SwTxtPainter
46#include <itrpaint.hxx> // SwTxtPainter
47#include <viewopt.hxx> // SwViewOptions
48#include <itrform2.hxx> // SwTxtFormatter
49#include <porfld.hxx> // SwFldPortion
50#include <porglue.hxx>
51#include <breakit.hxx>
52#include <pagefrm.hxx>
53#include <rowfrm.hxx>
47#include <viewopt.hxx> // SwViewOptions
48#include <itrform2.hxx> // SwTxtFormatter
49#include <porfld.hxx> // SwFldPortion
50#include <porglue.hxx>
51#include <breakit.hxx>
52#include <pagefrm.hxx>
53#include <rowfrm.hxx>
54#include <pagedesc.hxx> // SwPageDesc
54#include <pagedesc.hxx> // SwPageDesc
55#include <tgrditem.hxx>
56#include <swtable.hxx>
57#include <fmtfsize.hxx>
58
59using namespace ::com::sun::star;
60extern sal_Bool IsUnderlineBreak( const SwLinePortion& rPor, const SwFont& rFnt );
61
62/*-----------------10.10.00 15:23-------------------
55#include <tgrditem.hxx>
56#include <swtable.hxx>
57#include <fmtfsize.hxx>
58
59using namespace ::com::sun::star;
60extern sal_Bool IsUnderlineBreak( const SwLinePortion& rPor, const SwFont& rFnt );
61
62/*-----------------10.10.00 15:23-------------------
63 * class SwMultiPortion
63 * class SwMultiPortion
64 *
65 * A SwMultiPortion is not a simple portion,
66 * it's a container, which contains almost a SwLineLayoutPortion.
67 * This SwLineLayout could be followed by other textportions via pPortion
68 * and by another SwLineLayout via pNext to realize a doubleline portion.
69 * --------------------------------------------------*/
70
71SwMultiPortion::~SwMultiPortion()

--- 21 unchanged lines hidden (view full) ---

93 SwLineLayout *pLay = &GetRoot();
94 do
95 {
96 pLay->CalcLine( rLine, rInf );
97 if( rLine.IsFlyInCntBase() )
98 SetFlyInCntnt( sal_True );
99 if( IsRuby() && ( OnTop() == ( pLay == &GetRoot() ) ) )
100 {
64 *
65 * A SwMultiPortion is not a simple portion,
66 * it's a container, which contains almost a SwLineLayoutPortion.
67 * This SwLineLayout could be followed by other textportions via pPortion
68 * and by another SwLineLayout via pNext to realize a doubleline portion.
69 * --------------------------------------------------*/
70
71SwMultiPortion::~SwMultiPortion()

--- 21 unchanged lines hidden (view full) ---

93 SwLineLayout *pLay = &GetRoot();
94 do
95 {
96 pLay->CalcLine( rLine, rInf );
97 if( rLine.IsFlyInCntBase() )
98 SetFlyInCntnt( sal_True );
99 if( IsRuby() && ( OnTop() == ( pLay == &GetRoot() ) ) )
100 {
101 // An empty phonetic line don't need an ascent or a height.
101 // An empty phonetic line doesn't need an ascent or a height.
102 if( !pLay->Width() )
103 {
104 pLay->SetAscent( 0 );
105 pLay->Height( 0 );
106 }
107 if( OnTop() )
108 SetAscent( GetAscent() + pLay->Height() );
109 }

--- 5 unchanged lines hidden (view full) ---

115 pLay = pLay->GetNext();
116 } while ( pLay );
117 if( HasBrackets() )
118 {
119 KSHORT nTmp = ((SwDoubleLinePortion*)this)->GetBrackets()->nHeight;
120 if( nTmp > Height() )
121 {
122 KSHORT nAdd = ( nTmp - Height() ) / 2;
102 if( !pLay->Width() )
103 {
104 pLay->SetAscent( 0 );
105 pLay->Height( 0 );
106 }
107 if( OnTop() )
108 SetAscent( GetAscent() + pLay->Height() );
109 }

--- 5 unchanged lines hidden (view full) ---

115 pLay = pLay->GetNext();
116 } while ( pLay );
117 if( HasBrackets() )
118 {
119 KSHORT nTmp = ((SwDoubleLinePortion*)this)->GetBrackets()->nHeight;
120 if( nTmp > Height() )
121 {
122 KSHORT nAdd = ( nTmp - Height() ) / 2;
123 GetRoot().SetAscent( GetRoot().GetAscent() + nAdd );
124 GetRoot().Height( GetRoot().Height() + nAdd );
123 GetRoot().SetAscent( GetRoot().GetAscent() + nAdd );
124 GetRoot().Height( GetRoot().Height() + nAdd );
125 Height( nTmp );
126 }
127 nTmp = ((SwDoubleLinePortion*)this)->GetBrackets()->nAscent;
128 if( nTmp > GetAscent() )
129 SetAscent( nTmp );
130 }
131}
132
133long SwMultiPortion::CalcSpacing( long , const SwTxtSizeInfo & ) const
134{
135 return 0;
136}
137
138sal_Bool SwMultiPortion::ChgSpaceAdd( SwLineLayout*, long ) const
139{
125 Height( nTmp );
126 }
127 nTmp = ((SwDoubleLinePortion*)this)->GetBrackets()->nAscent;
128 if( nTmp > GetAscent() )
129 SetAscent( nTmp );
130 }
131}
132
133long SwMultiPortion::CalcSpacing( long , const SwTxtSizeInfo & ) const
134{
135 return 0;
136}
137
138sal_Bool SwMultiPortion::ChgSpaceAdd( SwLineLayout*, long ) const
139{
140 return sal_False;
140 return sal_False;
141}
142
143/*************************************************************************
141}
142
143/*************************************************************************
144 * virtual SwMultiPortion::HandlePortion()
144 * virtual SwMultiPortion::HandlePortion()
145 *************************************************************************/
146
147void SwMultiPortion::HandlePortion( SwPortionHandler& rPH ) const
148{
145 *************************************************************************/
146
147void SwMultiPortion::HandlePortion( SwPortionHandler& rPH ) const
148{
149 rPH.Text( GetLen(), GetWhichPor() );
149 rPH.Text( GetLen(), GetWhichPor() );
150}
151
152/*-----------------01.11.00 14:21-------------------
153 * SwMultiPortion::ActualizeTabulator()
154 * sets the tabulator-flag, if there's any tabulator-portion inside.
155 * --------------------------------------------------*/
156
157void SwMultiPortion::ActualizeTabulator()

--- 16 unchanged lines hidden (view full) ---

174 }
175}
176
177/*-----------------16.02.01 12:07-------------------
178 * SwRotatedPortion::SwRotatedPortion(..)
179 * --------------------------------------------------*/
180
181SwRotatedPortion::SwRotatedPortion( const SwMultiCreator& rCreate,
150}
151
152/*-----------------01.11.00 14:21-------------------
153 * SwMultiPortion::ActualizeTabulator()
154 * sets the tabulator-flag, if there's any tabulator-portion inside.
155 * --------------------------------------------------*/
156
157void SwMultiPortion::ActualizeTabulator()

--- 16 unchanged lines hidden (view full) ---

174 }
175}
176
177/*-----------------16.02.01 12:07-------------------
178 * SwRotatedPortion::SwRotatedPortion(..)
179 * --------------------------------------------------*/
180
181SwRotatedPortion::SwRotatedPortion( const SwMultiCreator& rCreate,
182 xub_StrLen nEnd, sal_Bool bRTL ) : SwMultiPortion( nEnd )
182 xub_StrLen nEnd, sal_Bool bRTL ) : SwMultiPortion( nEnd )
183{
184 const SvxCharRotateItem* pRot = (SvxCharRotateItem*)rCreate.pItem;
185 if( !pRot )
186 {
183{
184 const SvxCharRotateItem* pRot = (SvxCharRotateItem*)rCreate.pItem;
185 if( !pRot )
186 {
187 const SwTxtAttr& rAttr = *rCreate.pAttr;
188 const SfxPoolItem *const pItem =
189 CharFmt::GetItem(rAttr, RES_CHRATR_ROTATE);
190 if ( pItem )
191 {
192 pRot = static_cast<const SvxCharRotateItem*>(pItem);
193 }
187 const SwTxtAttr& rAttr = *rCreate.pAttr;
188 const SfxPoolItem *const pItem =
189 CharFmt::GetItem(rAttr, RES_CHRATR_ROTATE);
190 if ( pItem )
191 {
192 pRot = static_cast<const SvxCharRotateItem*>(pItem);
193 }
194 }
195 if( pRot )
194 }
195 if( pRot )
196 {
197 sal_uInt8 nDir;
198 if ( bRTL )
199 nDir = pRot->IsBottomToTop() ? 3 : 1;
200 else
201 nDir = pRot->IsBottomToTop() ? 1 : 3;
196 {
197 sal_uInt8 nDir;
198 if ( bRTL )
199 nDir = pRot->IsBottomToTop() ? 3 : 1;
200 else
201 nDir = pRot->IsBottomToTop() ? 1 : 3;
202
202
203 SetDirection( nDir );
204 }
203 SetDirection( nDir );
204 }
205}
206
207/*---------------------------------------------------
208 * SwBidiPortion::SwBidiPortion(..)
209 * --------------------------------------------------*/
210
211SwBidiPortion::SwBidiPortion( xub_StrLen nEnd, sal_uInt8 nLv )
205}
206
207/*---------------------------------------------------
208 * SwBidiPortion::SwBidiPortion(..)
209 * --------------------------------------------------*/
210
211SwBidiPortion::SwBidiPortion( xub_StrLen nEnd, sal_uInt8 nLv )
212 : SwMultiPortion( nEnd ), nLevel( nLv )
212 : SwMultiPortion( nEnd ), nLevel( nLv )
213{
213{
214 SetBidi();
214 SetBidi();
215
215
216 if ( nLevel % 2 )
217 SetDirection( DIR_RIGHT2LEFT );
218 else
219 SetDirection( DIR_LEFT2RIGHT );
216 if ( nLevel % 2 )
217 SetDirection( DIR_RIGHT2LEFT );
218 else
219 SetDirection( DIR_LEFT2RIGHT );
220}
221
222
223long SwBidiPortion::CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo& rInf ) const
224{
220}
221
222
223long SwBidiPortion::CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo& rInf ) const
224{
225 return HasTabulator() ? 0 : GetSpaceCnt(rInf) * nSpaceAdd / SPACING_PRECISION_FACTOR;
225 return HasTabulator() ? 0 : GetSpaceCnt(rInf) * nSpaceAdd / SPACING_PRECISION_FACTOR;
226}
227
228sal_Bool SwBidiPortion::ChgSpaceAdd( SwLineLayout* pCurr, long nSpaceAdd ) const
229{
230 sal_Bool bRet = sal_False;
226}
227
228sal_Bool SwBidiPortion::ChgSpaceAdd( SwLineLayout* pCurr, long nSpaceAdd ) const
229{
230 sal_Bool bRet = sal_False;
231 if( !HasTabulator() && nSpaceAdd > 0 && !pCurr->IsSpaceAdd() )
232 {
233 pCurr->CreateSpaceAdd();
234 pCurr->SetLLSpaceAdd( nSpaceAdd, 0 );
235 bRet = sal_True;
236 }
231 if( !HasTabulator() && nSpaceAdd > 0 && !pCurr->IsSpaceAdd() )
232 {
233 pCurr->CreateSpaceAdd();
234 pCurr->SetLLSpaceAdd( nSpaceAdd, 0 );
235 bRet = sal_True;
236 }
237
237
238 return bRet;
238 return bRet;
239}
240
241xub_StrLen SwBidiPortion::GetSpaceCnt( const SwTxtSizeInfo &rInf ) const
242{
239}
240
241xub_StrLen SwBidiPortion::GetSpaceCnt( const SwTxtSizeInfo &rInf ) const
242{
243 // Calculate number of blanks for justified alignment
244 SwLinePortion* pPor = GetRoot().GetFirstPortion();
245 xub_StrLen nTmpStart = rInf.GetIdx();
246 xub_StrLen nNull = 0;
247 xub_StrLen nBlanks;
243 // Calculate number of blanks for justified alignment
244 SwLinePortion* pPor = GetRoot().GetFirstPortion();
245 xub_StrLen nTmpStart = rInf.GetIdx();
246 xub_StrLen nNull = 0;
247 xub_StrLen nBlanks;
248
248
249 for( nBlanks = 0; pPor; pPor = pPor->GetPortion() )
250 {
251 if( pPor->InTxtGrp() )
252 nBlanks = nBlanks + ((SwTxtPortion*)pPor)->GetSpaceCnt( rInf, nNull );
253 else if ( pPor->IsMultiPortion() &&
254 ((SwMultiPortion*)pPor)->IsBidi() )
255 nBlanks = nBlanks + ((SwBidiPortion*)pPor)->GetSpaceCnt( rInf );
249 for( nBlanks = 0; pPor; pPor = pPor->GetPortion() )
250 {
251 if( pPor->InTxtGrp() )
252 nBlanks = nBlanks + ((SwTxtPortion*)pPor)->GetSpaceCnt( rInf, nNull );
253 else if ( pPor->IsMultiPortion() &&
254 ((SwMultiPortion*)pPor)->IsBidi() )
255 nBlanks = nBlanks + ((SwBidiPortion*)pPor)->GetSpaceCnt( rInf );
256
256
257 ((SwTxtSizeInfo &)rInf).SetIdx( rInf.GetIdx() + pPor->GetLen() );
258 }
259 ((SwTxtSizeInfo &)rInf).SetIdx( nTmpStart );
260 return nBlanks;
257 ((SwTxtSizeInfo &)rInf).SetIdx( rInf.GetIdx() + pPor->GetLen() );
258 }
259 ((SwTxtSizeInfo &)rInf).SetIdx( nTmpStart );
260 return nBlanks;
261}
262
263/*-----------------01.11.00 14:22-------------------
264 * SwDoubleLinePortion::SwDoubleLinePortion(..)
265 * This constructor is for the continuation of a doubleline portion
266 * in the next line.
267 * It takes the same brackets and if the original has no content except
268 * brackets, these will be deleted.
269 * --------------------------------------------------*/
270
271SwDoubleLinePortion::SwDoubleLinePortion( SwDoubleLinePortion& rDouble,
261}
262
263/*-----------------01.11.00 14:22-------------------
264 * SwDoubleLinePortion::SwDoubleLinePortion(..)
265 * This constructor is for the continuation of a doubleline portion
266 * in the next line.
267 * It takes the same brackets and if the original has no content except
268 * brackets, these will be deleted.
269 * --------------------------------------------------*/
270
271SwDoubleLinePortion::SwDoubleLinePortion( SwDoubleLinePortion& rDouble,
272 xub_StrLen nEnd ) :
273 SwMultiPortion( nEnd ),
274 pBracket( 0 )
272 xub_StrLen nEnd ) :
273 SwMultiPortion( nEnd ),
274 pBracket( 0 )
275{
275{
276 SetDirection( rDouble.GetDirection() );
277 SetDouble();
276 SetDirection( rDouble.GetDirection() );
277 SetDouble();
278 if( rDouble.GetBrackets() )
279 {
280 SetBrackets( rDouble );
281 // An empty multiportion needs no brackets.
282 // Notice: GetLen() might be zero, if the multiportion contains
283 // the second part of a field and the width might be zero, if
284 // it contains a note only. In this cases the brackets are okay.
285 // But if the length and the width are both zero, the portion

--- 17 unchanged lines hidden (view full) ---

303 const SvxTwoLinesItem* pTwo = (SvxTwoLinesItem*)rCreate.pItem;
304 if( pTwo )
305 pBracket->nStart = 0;
306 else
307 {
308 const SwTxtAttr& rAttr = *rCreate.pAttr;
309 pBracket->nStart = *rAttr.GetStart();
310
278 if( rDouble.GetBrackets() )
279 {
280 SetBrackets( rDouble );
281 // An empty multiportion needs no brackets.
282 // Notice: GetLen() might be zero, if the multiportion contains
283 // the second part of a field and the width might be zero, if
284 // it contains a note only. In this cases the brackets are okay.
285 // But if the length and the width are both zero, the portion

--- 17 unchanged lines hidden (view full) ---

303 const SvxTwoLinesItem* pTwo = (SvxTwoLinesItem*)rCreate.pItem;
304 if( pTwo )
305 pBracket->nStart = 0;
306 else
307 {
308 const SwTxtAttr& rAttr = *rCreate.pAttr;
309 pBracket->nStart = *rAttr.GetStart();
310
311 const SfxPoolItem * const pItem =
312 CharFmt::GetItem( rAttr, RES_CHRATR_TWO_LINES );
313 if ( pItem )
314 {
315 pTwo = static_cast<const SvxTwoLinesItem*>(pItem);
316 }
311 const SfxPoolItem * const pItem =
312 CharFmt::GetItem( rAttr, RES_CHRATR_TWO_LINES );
313 if ( pItem )
314 {
315 pTwo = static_cast<const SvxTwoLinesItem*>(pItem);
316 }
317 }
318 if( pTwo )
319 {
320 pBracket->cPre = pTwo->GetStartBracket();
321 pBracket->cPost = pTwo->GetEndBracket();
322 }
323 else
324 {
325 pBracket->cPre = 0;
326 pBracket->cPost = 0;
327 }
328 sal_uInt8 nTmp = SW_SCRIPTS;
329 if( pBracket->cPre > 255 )
330 {
331 String aTxt( pBracket->cPre );
317 }
318 if( pTwo )
319 {
320 pBracket->cPre = pTwo->GetStartBracket();
321 pBracket->cPost = pTwo->GetEndBracket();
322 }
323 else
324 {
325 pBracket->cPre = 0;
326 pBracket->cPost = 0;
327 }
328 sal_uInt8 nTmp = SW_SCRIPTS;
329 if( pBracket->cPre > 255 )
330 {
331 String aTxt( pBracket->cPre );
332 nTmp = SwScriptInfo::WhichFont( 0, &aTxt, 0 );
332 nTmp = SwScriptInfo::WhichFont( 0, &aTxt, 0 );
333 }
334 pBracket->nPreScript = nTmp;
335 nTmp = SW_SCRIPTS;
336 if( pBracket->cPost > 255 )
337 {
338 String aTxt( pBracket->cPost );
333 }
334 pBracket->nPreScript = nTmp;
335 nTmp = SW_SCRIPTS;
336 if( pBracket->cPost > 255 )
337 {
338 String aTxt( pBracket->cPost );
339 nTmp = SwScriptInfo::WhichFont( 0, &aTxt, 0 );
340 }
339 nTmp = SwScriptInfo::WhichFont( 0, &aTxt, 0 );
340 }
341 pBracket->nPostScript = nTmp;
342
343 if( !pBracket->cPre && !pBracket->cPost )
344 {
345 delete pBracket;
346 pBracket = 0;
347 }
348
341 pBracket->nPostScript = nTmp;
342
343 if( !pBracket->cPre && !pBracket->cPost )
344 {
345 delete pBracket;
346 pBracket = 0;
347 }
348
349 // double line portions have the same direction as the frame directions
350 if ( rCreate.nLevel % 2 )
351 SetDirection( DIR_RIGHT2LEFT );
352 else
353 SetDirection( DIR_LEFT2RIGHT );
349 // double line portions have the same direction as the frame directions
350 if ( rCreate.nLevel % 2 )
351 SetDirection( DIR_RIGHT2LEFT );
352 else
353 SetDirection( DIR_LEFT2RIGHT );
354}
355
356
357/*-----------------25.10.00 09:51-------------------
358 * SwMultiPortion::PaintBracket paints the wished bracket,
359 * if the multiportion has surrounding brackets.
360 * The X-position of the SwTxtPaintInfo will be modified:
361 * the open bracket sets position behind itself,
362 * the close bracket in front of itself.
363 * --------------------------------------------------*/
364
365void SwDoubleLinePortion::PaintBracket( SwTxtPaintInfo &rInf,
354}
355
356
357/*-----------------25.10.00 09:51-------------------
358 * SwMultiPortion::PaintBracket paints the wished bracket,
359 * if the multiportion has surrounding brackets.
360 * The X-position of the SwTxtPaintInfo will be modified:
361 * the open bracket sets position behind itself,
362 * the close bracket in front of itself.
363 * --------------------------------------------------*/
364
365void SwDoubleLinePortion::PaintBracket( SwTxtPaintInfo &rInf,
366 long nSpaceAdd,
367 sal_Bool bOpen ) const
366 long nSpaceAdd,
367 sal_Bool bOpen ) const
368{
369 sal_Unicode cCh = bOpen ? pBracket->cPre : pBracket->cPost;
370 if( !cCh )
371 return;
372 KSHORT nChWidth = bOpen ? PreWidth() : PostWidth();
373 if( !nChWidth )
374 return;
375 if( !bOpen )

--- 14 unchanged lines hidden (view full) ---

390 aBlank.Paint( rInf );
391 delete pTmpFnt;
392 }
393 if( bOpen )
394 rInf.X( rInf.X() + PreWidth() );
395}
396
397/*-----------------25.10.00 16:26-------------------
368{
369 sal_Unicode cCh = bOpen ? pBracket->cPre : pBracket->cPost;
370 if( !cCh )
371 return;
372 KSHORT nChWidth = bOpen ? PreWidth() : PostWidth();
373 if( !nChWidth )
374 return;
375 if( !bOpen )

--- 14 unchanged lines hidden (view full) ---

390 aBlank.Paint( rInf );
391 delete pTmpFnt;
392 }
393 if( bOpen )
394 rInf.X( rInf.X() + PreWidth() );
395}
396
397/*-----------------25.10.00 16:26-------------------
398 * SwDoubleLinePortion::SetBrackets creates the bracket-structur
398 * SwDoubleLinePortion::SetBrackets creates the bracket-structure
399 * and fills it, if not both characters are 0x00.
400 * --------------------------------------------------*/
401
402void SwDoubleLinePortion::SetBrackets( const SwDoubleLinePortion& rDouble )
403{
404 if( rDouble.pBracket )
405 {
406 pBracket = new SwBracket;

--- 111 unchanged lines hidden (view full) ---

518 if( pPor->InTabGrp() )
519 SetTab2( sal_True );
520 }
521 rInf.SetIdx( nStart );
522}
523
524long SwDoubleLinePortion::CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo & ) const
525{
399 * and fills it, if not both characters are 0x00.
400 * --------------------------------------------------*/
401
402void SwDoubleLinePortion::SetBrackets( const SwDoubleLinePortion& rDouble )
403{
404 if( rDouble.pBracket )
405 {
406 pBracket = new SwBracket;

--- 111 unchanged lines hidden (view full) ---

518 if( pPor->InTabGrp() )
519 SetTab2( sal_True );
520 }
521 rInf.SetIdx( nStart );
522}
523
524long SwDoubleLinePortion::CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo & ) const
525{
526 return HasTabulator() ? 0 : GetSpaceCnt() * nSpaceAdd / SPACING_PRECISION_FACTOR;
526 return HasTabulator() ? 0 : GetSpaceCnt() * nSpaceAdd / SPACING_PRECISION_FACTOR;
527}
528
529/*-----------------01.11.00 14:29-------------------
530 * SwDoubleLinePortion::ChangeSpaceAdd(..)
531 * merges the spaces for text adjustment from the inner and outer part.
532 * Inside the doubleline portion the wider line has no spaceadd-array, the
533 * smaller line has such an array to reach width of the wider line.
534 * If the surrounding line has text adjustment and the doubleline portion
535 * contains no tabulator, it is necessary to create/manipulate the inner
536 * space arrays.
537 * --------------------------------------------------*/
538
539sal_Bool SwDoubleLinePortion::ChgSpaceAdd( SwLineLayout* pCurr,
527}
528
529/*-----------------01.11.00 14:29-------------------
530 * SwDoubleLinePortion::ChangeSpaceAdd(..)
531 * merges the spaces for text adjustment from the inner and outer part.
532 * Inside the doubleline portion the wider line has no spaceadd-array, the
533 * smaller line has such an array to reach width of the wider line.
534 * If the surrounding line has text adjustment and the doubleline portion
535 * contains no tabulator, it is necessary to create/manipulate the inner
536 * space arrays.
537 * --------------------------------------------------*/
538
539sal_Bool SwDoubleLinePortion::ChgSpaceAdd( SwLineLayout* pCurr,
540 long nSpaceAdd ) const
540 long nSpaceAdd ) const
541{
542 sal_Bool bRet = sal_False;
543 if( !HasTabulator() && nSpaceAdd > 0 )
544 {
541{
542 sal_Bool bRet = sal_False;
543 if( !HasTabulator() && nSpaceAdd > 0 )
544 {
545 if( !pCurr->IsSpaceAdd() )
546 {
547 // The wider line gets the spaceadd from the surrounding line direct
545 if( !pCurr->IsSpaceAdd() )
546 {
547 // The wider line gets the spaceadd from the surrounding line direct
548 pCurr->CreateSpaceAdd();
548 pCurr->CreateSpaceAdd();
549 pCurr->SetLLSpaceAdd( nSpaceAdd, 0 );
549 pCurr->SetLLSpaceAdd( nSpaceAdd, 0 );
550 bRet = sal_True;
551 }
552 else
553 {
554 xub_StrLen nMyBlank = GetSmallerSpaceCnt();
555 xub_StrLen nOther = GetSpaceCnt();
550 bRet = sal_True;
551 }
552 else
553 {
554 xub_StrLen nMyBlank = GetSmallerSpaceCnt();
555 xub_StrLen nOther = GetSpaceCnt();
556 SwTwips nMultiSpace = pCurr->GetLLSpaceAdd( 0 ) * nMyBlank + nOther * nSpaceAdd;
556 SwTwips nMultiSpace = pCurr->GetLLSpaceAdd( 0 ) * nMyBlank + nOther * nSpaceAdd;
557
557
558 if( nMyBlank )
558 if( nMyBlank )
559 nMultiSpace /= nMyBlank;
560
559 nMultiSpace /= nMyBlank;
560
561 if( nMultiSpace < KSHRT_MAX * SPACING_PRECISION_FACTOR )
561 if( nMultiSpace < KSHRT_MAX * SPACING_PRECISION_FACTOR )
562 {
562 {
563// pCurr->SetLLSpaceAdd( nMultiSpace, 0 );
564 // --> FME 2006-07-11 #i65711# SetLLSpaceAdd replaces the first value,
565 // instead we want to insert a new first value:
566 std::vector<long>* pVec = pCurr->GetpLLSpaceAdd();
567 pVec->insert( pVec->begin(), nMultiSpace );
568 // <--
563// pCurr->SetLLSpaceAdd( nMultiSpace, 0 );
564 // --> FME 2006-07-11 #i65711# SetLLSpaceAdd replaces the first value,
565 // instead we want to insert a new first value:
566 std::vector<long>* pVec = pCurr->GetpLLSpaceAdd();
567 pVec->insert( pVec->begin(), nMultiSpace );
568 // <--
569 bRet = sal_True;
570 }
571 }
572 }
573 return bRet;
574}
575/*-----------------01.11.00 14:29-------------------
576 * SwDoubleLinePortion::ResetSpaceAdd(..)
577 * cancels the manipulation from SwDoubleLinePortion::ChangeSpaceAdd(..)
578 * --------------------------------------------------*/
579
580void SwDoubleLinePortion::ResetSpaceAdd( SwLineLayout* pCurr )
581{
569 bRet = sal_True;
570 }
571 }
572 }
573 return bRet;
574}
575/*-----------------01.11.00 14:29-------------------
576 * SwDoubleLinePortion::ResetSpaceAdd(..)
577 * cancels the manipulation from SwDoubleLinePortion::ChangeSpaceAdd(..)
578 * --------------------------------------------------*/
579
580void SwDoubleLinePortion::ResetSpaceAdd( SwLineLayout* pCurr )
581{
582 pCurr->RemoveFirstLLSpaceAdd();;
583 if( !pCurr->GetLLSpaceAddCount() )
582 pCurr->RemoveFirstLLSpaceAdd();;
583 if( !pCurr->GetLLSpaceAddCount() )
584 pCurr->FinishSpaceAdd();
585}
586
587SwDoubleLinePortion::~SwDoubleLinePortion()
588{
589 delete pBracket;
590}
591
592/*-----------------13.11.00 14:50-------------------
593 * SwRubyPortion::SwRubyPortion(..)
594 * constructs a ruby portion, i.e. an additional text is displayed
595 * beside the main text, e.g. phonetic characters.
596 * --------------------------------------------------*/
597
598
599SwRubyPortion::SwRubyPortion( const SwRubyPortion& rRuby, xub_StrLen nEnd ) :
584 pCurr->FinishSpaceAdd();
585}
586
587SwDoubleLinePortion::~SwDoubleLinePortion()
588{
589 delete pBracket;
590}
591
592/*-----------------13.11.00 14:50-------------------
593 * SwRubyPortion::SwRubyPortion(..)
594 * constructs a ruby portion, i.e. an additional text is displayed
595 * beside the main text, e.g. phonetic characters.
596 * --------------------------------------------------*/
597
598
599SwRubyPortion::SwRubyPortion( const SwRubyPortion& rRuby, xub_StrLen nEnd ) :
600 SwMultiPortion( nEnd ),
601 nRubyOffset( rRuby.GetRubyOffset() ),
602 nAdjustment( rRuby.GetAdjustment() )
600 SwMultiPortion( nEnd ),
601 nRubyOffset( rRuby.GetRubyOffset() ),
602 nAdjustment( rRuby.GetAdjustment() )
603{
603{
604 SetDirection( rRuby.GetDirection() ),
605 SetTop( rRuby.OnTop() );
606 SetRuby();
604 SetDirection( rRuby.GetDirection() ),
605 SetTop( rRuby.OnTop() );
606 SetRuby();
607}
608
609/*-----------------13.11.00 14:50-------------------
610 * SwRubyPortion::SwRubyPortion(..)
611 * constructs a ruby portion, i.e. an additional text is displayed
612 * beside the main text, e.g. phonetic characters.
613 * --------------------------------------------------*/
614
615SwRubyPortion::SwRubyPortion( const SwMultiCreator& rCreate, const SwFont& rFnt,
607}
608
609/*-----------------13.11.00 14:50-------------------
610 * SwRubyPortion::SwRubyPortion(..)
611 * constructs a ruby portion, i.e. an additional text is displayed
612 * beside the main text, e.g. phonetic characters.
613 * --------------------------------------------------*/
614
615SwRubyPortion::SwRubyPortion( const SwMultiCreator& rCreate, const SwFont& rFnt,
616 const IDocumentSettingAccess& rIDocumentSettingAccess,
617 xub_StrLen nEnd, xub_StrLen nOffs,
618 const sal_Bool* pForceRubyPos )
619 : SwMultiPortion( nEnd )
616 const IDocumentSettingAccess& rIDocumentSettingAccess,
617 xub_StrLen nEnd, xub_StrLen nOffs,
618 const sal_Bool* pForceRubyPos )
619 : SwMultiPortion( nEnd )
620{
621 SetRuby();
620{
621 SetRuby();
622 ASSERT( SW_MC_RUBY == rCreate.nId, "Ruby expected" );
622 ASSERT( SW_MC_RUBY == rCreate.nId, "Ruby expected" );
623 ASSERT( RES_TXTATR_CJK_RUBY == rCreate.pAttr->Which(), "Wrong attribute" );
624 const SwFmtRuby& rRuby = rCreate.pAttr->GetRuby();
625 nAdjustment = rRuby.GetAdjustment();
626 nRubyOffset = nOffs;
627
623 ASSERT( RES_TXTATR_CJK_RUBY == rCreate.pAttr->Which(), "Wrong attribute" );
624 const SwFmtRuby& rRuby = rCreate.pAttr->GetRuby();
625 nAdjustment = rRuby.GetAdjustment();
626 nRubyOffset = nOffs;
627
628 // in grid mode we force the ruby text to the upper or lower line
629 if ( pForceRubyPos )
630 SetTop( *pForceRubyPos );
631 else
632 SetTop( ! rRuby.GetPosition() );
628 // in grid mode we force the ruby text to the upper or lower line
629 if ( pForceRubyPos )
630 SetTop( *pForceRubyPos );
631 else
632 SetTop( ! rRuby.GetPosition() );
633
633
634 const SwCharFmt* pFmt = ((SwTxtRuby*)rCreate.pAttr)->GetCharFmt();
634 const SwCharFmt* pFmt = ((SwTxtRuby*)rCreate.pAttr)->GetCharFmt();
635 SwFont *pRubyFont;
636 if( pFmt )
637 {
638 const SwAttrSet& rSet = pFmt->GetAttrSet();
639 pRubyFont = new SwFont( rFnt );
635 SwFont *pRubyFont;
636 if( pFmt )
637 {
638 const SwAttrSet& rSet = pFmt->GetAttrSet();
639 pRubyFont = new SwFont( rFnt );
640 pRubyFont->SetDiffFnt( &rSet, &rIDocumentSettingAccess );
640 pRubyFont->SetDiffFnt( &rSet, &rIDocumentSettingAccess );
641
641
642 // we do not allow a vertical font for the ruby text
643 pRubyFont->SetVertical( rFnt.GetOrientation() );
642 // we do not allow a vertical font for the ruby text
643 pRubyFont->SetVertical( rFnt.GetOrientation() );
644 }
645 else
646 pRubyFont = NULL;
647
648 String aStr( rRuby.GetText(), nOffs, STRING_LEN );
649 SwFldPortion *pFld = new SwFldPortion( aStr, pRubyFont );
644 }
645 else
646 pRubyFont = NULL;
647
648 String aStr( rRuby.GetText(), nOffs, STRING_LEN );
649 SwFldPortion *pFld = new SwFldPortion( aStr, pRubyFont );
650 pFld->SetNextOffset( nOffs );
650 pFld->SetNextOffset( nOffs );
651 pFld->SetFollow( sal_True );
652
651 pFld->SetFollow( sal_True );
652
653 if( OnTop() )
653 if( OnTop() )
654 GetRoot().SetPortion( pFld );
655 else
656 {
657 GetRoot().SetNext( new SwLineLayout() );
658 GetRoot().GetNext()->SetPortion( pFld );
659 }
660
654 GetRoot().SetPortion( pFld );
655 else
656 {
657 GetRoot().SetNext( new SwLineLayout() );
658 GetRoot().GetNext()->SetPortion( pFld );
659 }
660
661 // ruby portions have the same direction as the frame directions
662 if ( rCreate.nLevel % 2 )
663 {
664 // switch right and left ruby adjustment in rtl environment
665 if ( 0 == nAdjustment )
666 nAdjustment = 2;
667 else if ( 2 == nAdjustment )
668 nAdjustment = 0;
661 // ruby portions have the same direction as the frame directions
662 if ( rCreate.nLevel % 2 )
663 {
664 // switch right and left ruby adjustment in rtl environment
665 if ( 0 == nAdjustment )
666 nAdjustment = 2;
667 else if ( 2 == nAdjustment )
668 nAdjustment = 0;
669
669
670 SetDirection( DIR_RIGHT2LEFT );
671 }
672 else
673 SetDirection( DIR_LEFT2RIGHT );
670 SetDirection( DIR_RIGHT2LEFT );
671 }
672 else
673 SetDirection( DIR_LEFT2RIGHT );
674}
675
676/*-----------------13.11.00 14:56-------------------
677 * SwRubyPortion::_Adjust(..)
678 * In ruby portion there are different alignments for
679 * the ruby text and the main text.
680 * Left, right, centered and two possibilities of block adjustment
674}
675
676/*-----------------13.11.00 14:56-------------------
677 * SwRubyPortion::_Adjust(..)
678 * In ruby portion there are different alignments for
679 * the ruby text and the main text.
680 * Left, right, centered and two possibilities of block adjustment
681 * The block adjustment is realized by spacing between the characteres,
681 * The block adjustment is realized by spacing between the characters,
682 * either with a half space or no space in front of the first letter and
683 * a half space at the end of the last letter.
684 * Notice: the smaller line will be manipulated, normally it's the ruby line,
685 * but it could be the main text, too.
686 * If there is a tabulator in smaller line, no adjustment is possible.
687 * --------------------------------------------------*/
688
689void SwRubyPortion::_Adjust( SwTxtFormatInfo &rInf )
690{
691 SwTwips nLineDiff = GetRoot().Width() - GetRoot().GetNext()->Width();
692 xub_StrLen nOldIdx = rInf.GetIdx();
693 if( !nLineDiff )
694 return;
695 SwLineLayout *pCurr;
696 if( nLineDiff < 0 )
682 * either with a half space or no space in front of the first letter and
683 * a half space at the end of the last letter.
684 * Notice: the smaller line will be manipulated, normally it's the ruby line,
685 * but it could be the main text, too.
686 * If there is a tabulator in smaller line, no adjustment is possible.
687 * --------------------------------------------------*/
688
689void SwRubyPortion::_Adjust( SwTxtFormatInfo &rInf )
690{
691 SwTwips nLineDiff = GetRoot().Width() - GetRoot().GetNext()->Width();
692 xub_StrLen nOldIdx = rInf.GetIdx();
693 if( !nLineDiff )
694 return;
695 SwLineLayout *pCurr;
696 if( nLineDiff < 0 )
697 { // The first line has to be adjusted.
697 { // The first line has to be adjusted.
698 if( GetTab1() )
699 return;
700 pCurr = &GetRoot();
701 nLineDiff = -nLineDiff;
702 }
703 else
698 if( GetTab1() )
699 return;
700 pCurr = &GetRoot();
701 nLineDiff = -nLineDiff;
702 }
703 else
704 { // The second line has to be adjusted.
704 { // The second line has to be adjusted.
705 if( GetTab2() )
706 return;
707 pCurr = GetRoot().GetNext();
708 rInf.SetIdx( nOldIdx + GetRoot().GetLen() );
709 }
710 KSHORT nLeft = 0; // the space in front of the first letter
711 KSHORT nRight = 0; // the space at the end of the last letter
712 sal_uInt16 nSub = 0;
713 switch ( nAdjustment )
714 {
705 if( GetTab2() )
706 return;
707 pCurr = GetRoot().GetNext();
708 rInf.SetIdx( nOldIdx + GetRoot().GetLen() );
709 }
710 KSHORT nLeft = 0; // the space in front of the first letter
711 KSHORT nRight = 0; // the space at the end of the last letter
712 sal_uInt16 nSub = 0;
713 switch ( nAdjustment )
714 {
715 case 1: nRight = static_cast<sal_uInt16>(nLineDiff / 2); // no break
716 case 2: nLeft = static_cast<sal_uInt16>(nLineDiff - nRight); break;
717 case 3: nSub = 1; // no break
715 case 1: nRight = static_cast<sal_uInt16>(nLineDiff / 2); // no break
716 case 2: nLeft = static_cast<sal_uInt16>(nLineDiff - nRight); break;
717 case 3: nSub = 1; // no break
718 case 4:
719 {
720 xub_StrLen nCharCnt = 0;
721 SwLinePortion *pPor;
722 for( pPor = pCurr->GetFirstPortion(); pPor; pPor = pPor->GetPortion() )
723 {
724 if( pPor->InTxtGrp() )
725 ((SwTxtPortion*)pPor)->GetSpaceCnt( rInf, nCharCnt );
726 rInf.SetIdx( rInf.GetIdx() + pPor->GetLen() );
727 }
728 if( nCharCnt > nSub )
729 {
730 SwTwips nCalc = nLineDiff / ( nCharCnt - nSub );
718 case 4:
719 {
720 xub_StrLen nCharCnt = 0;
721 SwLinePortion *pPor;
722 for( pPor = pCurr->GetFirstPortion(); pPor; pPor = pPor->GetPortion() )
723 {
724 if( pPor->InTxtGrp() )
725 ((SwTxtPortion*)pPor)->GetSpaceCnt( rInf, nCharCnt );
726 rInf.SetIdx( rInf.GetIdx() + pPor->GetLen() );
727 }
728 if( nCharCnt > nSub )
729 {
730 SwTwips nCalc = nLineDiff / ( nCharCnt - nSub );
731 short nTmp;
731 short nTmp;
732 if( nCalc < SHRT_MAX )
733 nTmp = -short(nCalc);
734 else
735 nTmp = SHRT_MIN;
736
732 if( nCalc < SHRT_MAX )
733 nTmp = -short(nCalc);
734 else
735 nTmp = SHRT_MIN;
736
737 pCurr->CreateSpaceAdd( SPACING_PRECISION_FACTOR * nTmp );
737 pCurr->CreateSpaceAdd( SPACING_PRECISION_FACTOR * nTmp );
738 nLineDiff -= nCalc * ( nCharCnt - 1 );
739 }
740 if( nLineDiff > 1 )
741 {
738 nLineDiff -= nCalc * ( nCharCnt - 1 );
739 }
740 if( nLineDiff > 1 )
741 {
742 nRight = static_cast<sal_uInt16>(nLineDiff / 2);
743 nLeft = static_cast<sal_uInt16>(nLineDiff - nRight);
742 nRight = static_cast<sal_uInt16>(nLineDiff / 2);
743 nLeft = static_cast<sal_uInt16>(nLineDiff - nRight);
744 }
745 break;
746 }
747 default: ASSERT( sal_False, "New ruby adjustment" );
748 }
749 if( nLeft || nRight )
750 {
751 if( !pCurr->GetPortion() )

--- 8 unchanged lines hidden (view full) ---

760 if( nRight )
761 {
762 pMarg = new SwMarginPortion( 0 );
763 pMarg->AddPrtWidth( nRight );
764 pCurr->FindLastPortion()->Append( pMarg );
765 }
766 }
767
744 }
745 break;
746 }
747 default: ASSERT( sal_False, "New ruby adjustment" );
748 }
749 if( nLeft || nRight )
750 {
751 if( !pCurr->GetPortion() )

--- 8 unchanged lines hidden (view full) ---

760 if( nRight )
761 {
762 pMarg = new SwMarginPortion( 0 );
763 pMarg->AddPrtWidth( nRight );
764 pCurr->FindLastPortion()->Append( pMarg );
765 }
766 }
767
768 pCurr->Width( Width() );
768 pCurr->Width( Width() );
769 rInf.SetIdx( nOldIdx );
770}
771
772/*-----------------08.11.00 14:14-------------------
773 * CalcRubyOffset()
774 * has to change the nRubyOffset, if there's a fieldportion
775 * in the phonetic line.
776 * The nRubyOffset is the position in the rubystring, where the

--- 47 unchanged lines hidden (view full) ---

824 * no 2-line-format reference is passed. If there is a 2-line-format reference,
825 * then the rValue is set only, if the 2-line-attribute's value is set _and_
826 * the 2-line-formats has the same brackets.
827 * --------------------------------------------------*/
828
829sal_Bool lcl_Has2Lines( const SwTxtAttr& rAttr, const SvxTwoLinesItem* &rpRef,
830 sal_Bool &rValue )
831{
769 rInf.SetIdx( nOldIdx );
770}
771
772/*-----------------08.11.00 14:14-------------------
773 * CalcRubyOffset()
774 * has to change the nRubyOffset, if there's a fieldportion
775 * in the phonetic line.
776 * The nRubyOffset is the position in the rubystring, where the

--- 47 unchanged lines hidden (view full) ---

824 * no 2-line-format reference is passed. If there is a 2-line-format reference,
825 * then the rValue is set only, if the 2-line-attribute's value is set _and_
826 * the 2-line-formats has the same brackets.
827 * --------------------------------------------------*/
828
829sal_Bool lcl_Has2Lines( const SwTxtAttr& rAttr, const SvxTwoLinesItem* &rpRef,
830 sal_Bool &rValue )
831{
832 const SfxPoolItem* pItem = CharFmt::GetItem( rAttr, RES_CHRATR_TWO_LINES );
833 if( pItem )
834 {
835 rValue = ((SvxTwoLinesItem*)pItem)->GetValue();
836 if( !rpRef )
837 rpRef = (SvxTwoLinesItem*)pItem;
838 else if( ((SvxTwoLinesItem*)pItem)->GetEndBracket() !=
839 rpRef->GetEndBracket() ||
840 ((SvxTwoLinesItem*)pItem)->GetStartBracket() !=
841 rpRef->GetStartBracket() )
842 rValue = sal_False;
843 return sal_True;
844 }
832 const SfxPoolItem* pItem = CharFmt::GetItem( rAttr, RES_CHRATR_TWO_LINES );
833 if( pItem )
834 {
835 rValue = ((SvxTwoLinesItem*)pItem)->GetValue();
836 if( !rpRef )
837 rpRef = (SvxTwoLinesItem*)pItem;
838 else if( ((SvxTwoLinesItem*)pItem)->GetEndBracket() !=
839 rpRef->GetEndBracket() ||
840 ((SvxTwoLinesItem*)pItem)->GetStartBracket() !=
841 rpRef->GetStartBracket() )
842 rValue = sal_False;
843 return sal_True;
844 }
845 return sal_False;
846}
847
848/*-----------------16.02.01 16:39-------------------
849 * lcl_HasRotation(..)
850 * is a little help function for GetMultiCreator(..)
851 * It extracts the charrotation from a charrotate-attribute or a character style.
852 * The rValue is set to sal_True, if the charrotate-attribute's value is set and
853 * no charrotate-format reference is passed.
854 * If there is a charrotate-format reference, then the rValue is set only,
855 * if the charrotate-attribute's value is set _and_ identical
856 * to the charrotate-format's value.
857 * --------------------------------------------------*/
858
859sal_Bool lcl_HasRotation( const SwTxtAttr& rAttr,
860 const SvxCharRotateItem* &rpRef, sal_Bool &rValue )
861{
845 return sal_False;
846}
847
848/*-----------------16.02.01 16:39-------------------
849 * lcl_HasRotation(..)
850 * is a little help function for GetMultiCreator(..)
851 * It extracts the charrotation from a charrotate-attribute or a character style.
852 * The rValue is set to sal_True, if the charrotate-attribute's value is set and
853 * no charrotate-format reference is passed.
854 * If there is a charrotate-format reference, then the rValue is set only,
855 * if the charrotate-attribute's value is set _and_ identical
856 * to the charrotate-format's value.
857 * --------------------------------------------------*/
858
859sal_Bool lcl_HasRotation( const SwTxtAttr& rAttr,
860 const SvxCharRotateItem* &rpRef, sal_Bool &rValue )
861{
862 const SfxPoolItem* pItem = CharFmt::GetItem( rAttr, RES_CHRATR_ROTATE );
863 if ( pItem )
862 const SfxPoolItem* pItem = CharFmt::GetItem( rAttr, RES_CHRATR_ROTATE );
863 if ( pItem )
864 {
864 {
865 rValue = 0 != ((SvxCharRotateItem*)pItem)->GetValue();
866 if( !rpRef )
867 rpRef = (SvxCharRotateItem*)pItem;
868 else if( ((SvxCharRotateItem*)pItem)->GetValue() !=
869 rpRef->GetValue() )
870 rValue = sal_False;
871 return sal_True;
872 }
865 rValue = 0 != ((SvxCharRotateItem*)pItem)->GetValue();
866 if( !rpRef )
867 rpRef = (SvxCharRotateItem*)pItem;
868 else if( ((SvxCharRotateItem*)pItem)->GetValue() !=
869 rpRef->GetValue() )
870 rValue = sal_False;
871 return sal_True;
872 }
873
874 return sal_False;
875}
876
877SwMultiCreator* SwTxtSizeInfo::GetMultiCreator( xub_StrLen &rPos,
873
874 return sal_False;
875}
876
877SwMultiCreator* SwTxtSizeInfo::GetMultiCreator( xub_StrLen &rPos,
878 SwMultiPortion* pMulti ) const
878 SwMultiPortion* pMulti ) const
879{
879{
880 SwScriptInfo& rSI = ((SwParaPortion*)GetParaPortion())->GetScriptInfo();
880 SwScriptInfo& rSI = ((SwParaPortion*)GetParaPortion())->GetScriptInfo();
881
881
882 // get the last embedding level
883 sal_uInt8 nCurrLevel;
884 if ( pMulti )
885 {
886 ASSERT( pMulti->IsBidi(), "Nested MultiPortion is not BidiPortion" )
887 // level associated with bidi-portion;
888 nCurrLevel = ((SwBidiPortion*)pMulti)->GetLevel();
889 }
890 else
891 // no nested bidi portion required
892 nCurrLevel = GetTxtFrm()->IsRightToLeft() ? 1 : 0;
882 // get the last embedding level
883 sal_uInt8 nCurrLevel;
884 if ( pMulti )
885 {
886 ASSERT( pMulti->IsBidi(), "Nested MultiPortion is not BidiPortion" )
887 // level associated with bidi-portion;
888 nCurrLevel = ((SwBidiPortion*)pMulti)->GetLevel();
889 }
890 else
891 // no nested bidi portion required
892 nCurrLevel = GetTxtFrm()->IsRightToLeft() ? 1 : 0;
893
893
894 // check if there is a field at rPos:
895 sal_uInt8 nNextLevel = nCurrLevel;
896 sal_Bool bFldBidi = sal_False;
894 // check if there is a field at rPos:
895 sal_uInt8 nNextLevel = nCurrLevel;
896 sal_Bool bFldBidi = sal_False;
897
897
898 if ( CH_TXTATR_BREAKWORD == GetChar( rPos ) )
899 {
898 if ( CH_TXTATR_BREAKWORD == GetChar( rPos ) )
899 {
900 bFldBidi = sal_True;
901/*
900 bFldBidi = sal_True;
901/*
902 // examining the script of the field text should be sufficient
903 // for 99% of all cases
904 XubString aTxt = GetTxtFrm()->GetTxtNode()->GetExpandTxt( rPos, 1 );
902 // examining the script of the field text should be sufficient
903 // for 99% of all cases
904 XubString aTxt = GetTxtFrm()->GetTxtNode()->GetExpandTxt( rPos, 1 );
905
905
906 if ( pBreakIt->GetBreakIter().is() && aTxt.Len() )
907 {
908 sal_Bool bFldDir = ( i18n::ScriptType::COMPLEX ==
909 pBreakIt->GetRealScriptOfText( aTxt, 0 ) );
910 sal_Bool bCurrDir = ( 0 != ( nCurrLevel % 2 ) );
911 if ( bFldDir != bCurrDir )
912 {
913 nNextLevel = nCurrLevel + 1;
914 bFldBidi = sal_True;
915 }
916 }*/
917 }
918 else
919 nNextLevel = rSI.DirType( rPos );
906 if ( pBreakIt->GetBreakIter().is() && aTxt.Len() )
907 {
908 sal_Bool bFldDir = ( i18n::ScriptType::COMPLEX ==
909 pBreakIt->GetRealScriptOfText( aTxt, 0 ) );
910 sal_Bool bCurrDir = ( 0 != ( nCurrLevel % 2 ) );
911 if ( bFldDir != bCurrDir )
912 {
913 nNextLevel = nCurrLevel + 1;
914 bFldBidi = sal_True;
915 }
916 }*/
917 }
918 else
919 nNextLevel = rSI.DirType( rPos );
920
920
921 if ( GetTxt().Len() != rPos && nNextLevel > nCurrLevel )
922 {
923 rPos = bFldBidi ? rPos + 1 : rSI.NextDirChg( rPos, &nCurrLevel );
924 if ( STRING_LEN == rPos )
925 return NULL;
926 SwMultiCreator *pRet = new SwMultiCreator;
921 if ( GetTxt().Len() != rPos && nNextLevel > nCurrLevel )
922 {
923 rPos = bFldBidi ? rPos + 1 : rSI.NextDirChg( rPos, &nCurrLevel );
924 if ( STRING_LEN == rPos )
925 return NULL;
926 SwMultiCreator *pRet = new SwMultiCreator;
927 pRet->pItem = NULL;
927 pRet->pItem = NULL;
928 pRet->pAttr = NULL;
929 pRet->nId = SW_MC_BIDI;
930 pRet->nLevel = nCurrLevel + 1;
928 pRet->pAttr = NULL;
929 pRet->nId = SW_MC_BIDI;
930 pRet->nLevel = nCurrLevel + 1;
931 return pRet;
931 return pRet;
932 }
932 }
933
933
934 // a bidi portion can only contain other bidi portions
935 if ( pMulti )
936 return NULL;
934 // a bidi portion can only contain other bidi portions
935 if ( pMulti )
936 return NULL;
937
938 const SvxCharRotateItem* pRotate = NULL;
939 const SfxPoolItem* pRotItem;
940 if( SFX_ITEM_SET == pFrm->GetTxtNode()->GetSwAttrSet().
941 GetItemState( RES_CHRATR_ROTATE, sal_True, &pRotItem ) &&
942 ((SvxCharRotateItem*)pRotItem)->GetValue() )
943 pRotate = (SvxCharRotateItem*)pRotItem;
944 else

--- 47 unchanged lines hidden (view full) ---

992 if( pRuby )
993 { // The winner is ... a ruby attribute and so
994 // the end of the multiportion is the end of the ruby attribute.
995 rPos = *pRuby->End();
996 SwMultiCreator *pRet = new SwMultiCreator;
997 pRet->pItem = NULL;
998 pRet->pAttr = pRuby;
999 pRet->nId = SW_MC_RUBY;
937
938 const SvxCharRotateItem* pRotate = NULL;
939 const SfxPoolItem* pRotItem;
940 if( SFX_ITEM_SET == pFrm->GetTxtNode()->GetSwAttrSet().
941 GetItemState( RES_CHRATR_ROTATE, sal_True, &pRotItem ) &&
942 ((SvxCharRotateItem*)pRotItem)->GetValue() )
943 pRotate = (SvxCharRotateItem*)pRotItem;
944 else

--- 47 unchanged lines hidden (view full) ---

992 if( pRuby )
993 { // The winner is ... a ruby attribute and so
994 // the end of the multiportion is the end of the ruby attribute.
995 rPos = *pRuby->End();
996 SwMultiCreator *pRet = new SwMultiCreator;
997 pRet->pItem = NULL;
998 pRet->pAttr = pRuby;
999 pRet->nId = SW_MC_RUBY;
1000 pRet->nLevel = GetTxtFrm()->IsRightToLeft() ? 1 : 0;
1001 return pRet;
1000 pRet->nLevel = GetTxtFrm()->IsRightToLeft() ? 1 : 0;
1001 return pRet;
1002 }
1003 if( n2Lines < nCount || ( pItem && pItem == p2Lines &&
1004 rPos < GetTxt().Len() ) )
1005 { // The winner is a 2-line-attribute,
1006 // the end of the multiportion depends on the following attributes...
1007 SwMultiCreator *pRet = new SwMultiCreator;
1008
1009 // We note the endpositions of the 2-line attributes in aEnd as stack

--- 20 unchanged lines hidden (view full) ---

1030 }
1031 else
1032 {
1033 pRet->pItem = pItem;
1034 pRet->pAttr = NULL;
1035 aEnd.push_front( GetTxt().Len() );
1036 }
1037 pRet->nId = SW_MC_DOUBLE;
1002 }
1003 if( n2Lines < nCount || ( pItem && pItem == p2Lines &&
1004 rPos < GetTxt().Len() ) )
1005 { // The winner is a 2-line-attribute,
1006 // the end of the multiportion depends on the following attributes...
1007 SwMultiCreator *pRet = new SwMultiCreator;
1008
1009 // We note the endpositions of the 2-line attributes in aEnd as stack

--- 20 unchanged lines hidden (view full) ---

1030 }
1031 else
1032 {
1033 pRet->pItem = pItem;
1034 pRet->pAttr = NULL;
1035 aEnd.push_front( GetTxt().Len() );
1036 }
1037 pRet->nId = SW_MC_DOUBLE;
1038 pRet->nLevel = GetTxtFrm()->IsRightToLeft() ? 1 : 0;
1038 pRet->nLevel = GetTxtFrm()->IsRightToLeft() ? 1 : 0;
1039
1040 // n2Lines is the index of the last 2-line-attribute, which contains
1041 // the actual position.
1042 i = 0;
1043 // At this moment we know that at position rPos the "winner"-attribute
1044 // causes a 2-line-portion. The end of the attribute is the end of the
1045 // portion, if there's no interrupting attribute.
1046 // There are two kinds of interruptors:
1047 // - ruby attributes stops the 2-line-attribute, the end of the
1048 // multiline is the start of the ruby attribute
1049 // - 2-line-attributes with value "Off" or with different brackets,
1039
1040 // n2Lines is the index of the last 2-line-attribute, which contains
1041 // the actual position.
1042 i = 0;
1043 // At this moment we know that at position rPos the "winner"-attribute
1044 // causes a 2-line-portion. The end of the attribute is the end of the
1045 // portion, if there's no interrupting attribute.
1046 // There are two kinds of interruptors:
1047 // - ruby attributes stops the 2-line-attribute, the end of the
1048 // multiline is the start of the ruby attribute
1049 // - 2-line-attributes with value "Off" or with different brackets,
1050 // these attributes may interrupt the winner, but they could be
1050 // these attributes may interrupt the winner, but they could be
1051 // neutralized by another 2-line-attribute starting at the same
1052 // position with the same brackets as the winner-attribute.
1053
1054 // In the following loop rPos is the critical position and it will be
1055 // evaluated, if at rPos starts a interrupting or a maintaining
1056 // continuity attribute.
1057 while( i < nCount )
1058 {

--- 26 unchanged lines hidden (view full) ---

1085 aEnd.push_front( rPos );
1086 bOn = sal_True;
1087 }
1088 }
1089 // A ruby attribute stops the 2-line immediately
1090 if( RES_TXTATR_CJK_RUBY == pTmp->Which() )
1091 return pRet;
1092 if( lcl_Has2Lines( *pTmp, p2Lines, bTwo ) )
1051 // neutralized by another 2-line-attribute starting at the same
1052 // position with the same brackets as the winner-attribute.
1053
1054 // In the following loop rPos is the critical position and it will be
1055 // evaluated, if at rPos starts a interrupting or a maintaining
1056 // continuity attribute.
1057 while( i < nCount )
1058 {

--- 26 unchanged lines hidden (view full) ---

1085 aEnd.push_front( rPos );
1086 bOn = sal_True;
1087 }
1088 }
1089 // A ruby attribute stops the 2-line immediately
1090 if( RES_TXTATR_CJK_RUBY == pTmp->Which() )
1091 return pRet;
1092 if( lcl_Has2Lines( *pTmp, p2Lines, bTwo ) )
1093 { // We have an interesting attribute..
1093 { // We have an interesting attribute..
1094 if( bTwo == bOn )
1094 if( bTwo == bOn )
1095 { // .. with the same state, so the last attribute could
1095 { // ...with the same state, so the last attribute could
1096 // be continued.
1097 if( aEnd.back() < *pTmp->End() )
1098 aEnd.back() = *pTmp->End();
1099 }
1100 else
1096 // be continued.
1097 if( aEnd.back() < *pTmp->End() )
1098 aEnd.back() = *pTmp->End();
1099 }
1100 else
1101 { // .. with a different state.
1101 { // ...with a different state.
1102 bOn = bTwo;
1103 // If this is smaller than the last on the stack, we put
1104 // it on the stack. If it has the same endposition, the last
1105 // could be removed.
1106 if( aEnd.back() > *pTmp->End() )
1107 aEnd.push_back( *pTmp->End() );
1108 else if( aEnd.size() > 1 )
1109 aEnd.pop_back();

--- 160 unchanged lines hidden (view full) ---

1270 * the second line.
1271 * The destructor restores the values of the last manipulation.
1272 * --------------------------------------------------*/
1273
1274class SwSpaceManipulator
1275{
1276 SwTxtPaintInfo& rInfo;
1277 SwMultiPortion& rMulti;
1102 bOn = bTwo;
1103 // If this is smaller than the last on the stack, we put
1104 // it on the stack. If it has the same endposition, the last
1105 // could be removed.
1106 if( aEnd.back() > *pTmp->End() )
1107 aEnd.push_back( *pTmp->End() );
1108 else if( aEnd.size() > 1 )
1109 aEnd.pop_back();

--- 160 unchanged lines hidden (view full) ---

1270 * the second line.
1271 * The destructor restores the values of the last manipulation.
1272 * --------------------------------------------------*/
1273
1274class SwSpaceManipulator
1275{
1276 SwTxtPaintInfo& rInfo;
1277 SwMultiPortion& rMulti;
1278 std::vector<long>* pOldSpaceAdd;
1278 std::vector<long>* pOldSpaceAdd;
1279 MSHORT nOldSpIdx;
1279 MSHORT nOldSpIdx;
1280 long nSpaceAdd;
1280 long nSpaceAdd;
1281 sal_Bool bSpaceChg : 1;
1282 sal_uInt8 nOldDir : 2;
1283public:
1284 SwSpaceManipulator( SwTxtPaintInfo& rInf, SwMultiPortion& rMult );
1285 ~SwSpaceManipulator();
1286 void SecondLine();
1281 sal_Bool bSpaceChg : 1;
1282 sal_uInt8 nOldDir : 2;
1283public:
1284 SwSpaceManipulator( SwTxtPaintInfo& rInf, SwMultiPortion& rMult );
1285 ~SwSpaceManipulator();
1286 void SecondLine();
1287 inline long GetSpaceAdd() const { return nSpaceAdd; }
1287 inline long GetSpaceAdd() const { return nSpaceAdd; }
1288};
1289
1290SwSpaceManipulator::SwSpaceManipulator( SwTxtPaintInfo& rInf,
1288};
1289
1290SwSpaceManipulator::SwSpaceManipulator( SwTxtPaintInfo& rInf,
1291 SwMultiPortion& rMult ) :
1292 rInfo( rInf ), rMulti( rMult )
1291 SwMultiPortion& rMult ) :
1292 rInfo( rInf ), rMulti( rMult )
1293{
1294 pOldSpaceAdd = rInfo.GetpSpaceAdd();
1295 nOldSpIdx = rInfo.GetSpaceIdx();
1296 nOldDir = rInfo.GetDirection();
1297 rInfo.SetDirection( rMulti.GetDirection() );
1298 bSpaceChg = sal_False;
1299
1293{
1294 pOldSpaceAdd = rInfo.GetpSpaceAdd();
1295 nOldSpIdx = rInfo.GetSpaceIdx();
1296 nOldDir = rInfo.GetDirection();
1297 rInfo.SetDirection( rMulti.GetDirection() );
1298 bSpaceChg = sal_False;
1299
1300 if( rMulti.IsDouble() )
1300 if( rMulti.IsDouble() )
1301 {
1302 nSpaceAdd = ( pOldSpaceAdd && !rMulti.HasTabulator() ) ?
1303 rInfo.GetSpaceAdd() : 0;
1301 {
1302 nSpaceAdd = ( pOldSpaceAdd && !rMulti.HasTabulator() ) ?
1303 rInfo.GetSpaceAdd() : 0;
1304 if( rMulti.GetRoot().IsSpaceAdd() )
1304 if( rMulti.GetRoot().IsSpaceAdd() )
1305 {
1305 {
1306 rInfo.SetpSpaceAdd( rMulti.GetRoot().GetpLLSpaceAdd() );
1306 rInfo.SetpSpaceAdd( rMulti.GetRoot().GetpLLSpaceAdd() );
1307 rInfo.ResetSpaceIdx();
1308 bSpaceChg = rMulti.ChgSpaceAdd( &rMulti.GetRoot(), nSpaceAdd );
1309 }
1310 else if( rMulti.HasTabulator() )
1307 rInfo.ResetSpaceIdx();
1308 bSpaceChg = rMulti.ChgSpaceAdd( &rMulti.GetRoot(), nSpaceAdd );
1309 }
1310 else if( rMulti.HasTabulator() )
1311 rInfo.SetpSpaceAdd( NULL );
1311 rInfo.SetpSpaceAdd( NULL );
1312 }
1312 }
1313 else if ( ! rMulti.IsBidi() )
1314 {
1315 rInfo.SetpSpaceAdd( rMulti.GetRoot().GetpLLSpaceAdd() );
1313 else if ( ! rMulti.IsBidi() )
1314 {
1315 rInfo.SetpSpaceAdd( rMulti.GetRoot().GetpLLSpaceAdd() );
1316 rInfo.ResetSpaceIdx();
1317 }
1318}
1319
1320void SwSpaceManipulator::SecondLine()
1321{
1322 if( bSpaceChg )
1323 {
1316 rInfo.ResetSpaceIdx();
1317 }
1318}
1319
1320void SwSpaceManipulator::SecondLine()
1321{
1322 if( bSpaceChg )
1323 {
1324 rInfo.RemoveFirstSpaceAdd();
1324 rInfo.RemoveFirstSpaceAdd();
1325 bSpaceChg = sal_False;
1326 }
1327 SwLineLayout *pLay = rMulti.GetRoot().GetNext();
1325 bSpaceChg = sal_False;
1326 }
1327 SwLineLayout *pLay = rMulti.GetRoot().GetNext();
1328 if( pLay->IsSpaceAdd() )
1328 if( pLay->IsSpaceAdd() )
1329 {
1329 {
1330 rInfo.SetpSpaceAdd( pLay->GetpLLSpaceAdd() );
1330 rInfo.SetpSpaceAdd( pLay->GetpLLSpaceAdd() );
1331 rInfo.ResetSpaceIdx();
1332 bSpaceChg = rMulti.ChgSpaceAdd( pLay, nSpaceAdd );
1333 }
1334 else
1335 {
1331 rInfo.ResetSpaceIdx();
1332 bSpaceChg = rMulti.ChgSpaceAdd( pLay, nSpaceAdd );
1333 }
1334 else
1335 {
1336 rInfo.SetpSpaceAdd( (!rMulti.IsDouble() || rMulti.HasTabulator() ) ?
1336 rInfo.SetpSpaceAdd( (!rMulti.IsDouble() || rMulti.HasTabulator() ) ?
1337 0 : pOldSpaceAdd );
1338 rInfo.SetSpaceIdx( nOldSpIdx);
1339 }
1340}
1341
1342SwSpaceManipulator::~SwSpaceManipulator()
1343{
1344 if( bSpaceChg )
1345 {
1337 0 : pOldSpaceAdd );
1338 rInfo.SetSpaceIdx( nOldSpIdx);
1339 }
1340}
1341
1342SwSpaceManipulator::~SwSpaceManipulator()
1343{
1344 if( bSpaceChg )
1345 {
1346 rInfo.RemoveFirstSpaceAdd();
1346 rInfo.RemoveFirstSpaceAdd();
1347 bSpaceChg = sal_False;
1348 }
1347 bSpaceChg = sal_False;
1348 }
1349 rInfo.SetpSpaceAdd( pOldSpaceAdd );
1349 rInfo.SetpSpaceAdd( pOldSpaceAdd );
1350 rInfo.SetSpaceIdx( nOldSpIdx);
1351 rInfo.SetDirection( nOldDir );
1352}
1353
1354/*-----------------13.10.00 16:24-------------------
1355 * SwTxtPainter::PaintMultiPortion manages the paint for a SwMultiPortion.
1356 * External, for the calling function, it seems to be a normal Paint-function,
1357 * internal it is like a SwTxtFrm::Paint with multiple DrawTextLines
1358 * --------------------------------------------------*/
1359
1360void SwTxtPainter::PaintMultiPortion( const SwRect &rPaint,
1350 rInfo.SetSpaceIdx( nOldSpIdx);
1351 rInfo.SetDirection( nOldDir );
1352}
1353
1354/*-----------------13.10.00 16:24-------------------
1355 * SwTxtPainter::PaintMultiPortion manages the paint for a SwMultiPortion.
1356 * External, for the calling function, it seems to be a normal Paint-function,
1357 * internal it is like a SwTxtFrm::Paint with multiple DrawTextLines
1358 * --------------------------------------------------*/
1359
1360void SwTxtPainter::PaintMultiPortion( const SwRect &rPaint,
1361 SwMultiPortion& rMulti, const SwMultiPortion* pEnvPor )
1361 SwMultiPortion& rMulti, const SwMultiPortion* pEnvPor )
1362{
1362{
1363 GETGRID( pFrm->FindPageFrm() )
1364 const sal_Bool bHasGrid = pGrid && GetInfo().SnapToGrid();
1365 sal_uInt16 nGridWidth = 0;
1366 sal_uInt16 nRubyHeight = 0;
1367 sal_Bool bRubyTop = sal_False;
1363 GETGRID( pFrm->FindPageFrm() )
1364 const sal_Bool bHasGrid = pGrid && GetInfo().SnapToGrid();
1365 sal_uInt16 nGridWidth = 0;
1366 sal_uInt16 nRubyHeight = 0;
1367 sal_Bool bRubyTop = sal_False;
1368
1368
1369 if ( bHasGrid )
1370 {
1371 nGridWidth = pGrid->GetBaseHeight();
1372 nRubyHeight = pGrid->GetRubyHeight();
1373 bRubyTop = ! pGrid->GetRubyTextBelow();
1374 }
1369 if ( bHasGrid )
1370 {
1371 nGridWidth = pGrid->GetBaseHeight();
1372 nRubyHeight = pGrid->GetRubyHeight();
1373 bRubyTop = ! pGrid->GetRubyTextBelow();
1374 }
1375
1375
1376 // do not allow grid mode for first line in ruby portion
1377 const sal_Bool bRubyInGrid = bHasGrid && rMulti.IsRuby();
1376 // do not allow grid mode for first line in ruby portion
1377 const sal_Bool bRubyInGrid = bHasGrid && rMulti.IsRuby();
1378
1378
1379 const sal_uInt16 nOldHeight = rMulti.Height();
1380 const sal_Bool bOldGridModeAllowed = GetInfo().SnapToGrid();
1379 const sal_uInt16 nOldHeight = rMulti.Height();
1380 const sal_Bool bOldGridModeAllowed = GetInfo().SnapToGrid();
1381
1381
1382 if ( bRubyInGrid )
1383 {
1384 GetInfo().SetSnapToGrid( ! bRubyTop );
1385 rMulti.Height( pCurr->Height() );
1386 }
1382 if ( bRubyInGrid )
1383 {
1384 GetInfo().SetSnapToGrid( ! bRubyTop );
1385 rMulti.Height( pCurr->Height() );
1386 }
1387
1387
1388 SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
1389 sal_uInt8 nEnvDir = 0;
1390 sal_uInt8 nThisDir = 0;
1391 sal_uInt8 nFrmDir = 0;
1392 if ( rMulti.IsBidi() )
1393 {
1394 // these values are needed for the calculation of the x coordinate
1395 // and the layout mode
1396 ASSERT( ! pEnvPor || pEnvPor->IsBidi(),
1397 "Oh no, I expected a BidiPortion" )
1398 nFrmDir = GetInfo().GetTxtFrm()->IsRightToLeft() ? 1 : 0;
1399 nEnvDir = pEnvPor ? ((SwBidiPortion*)pEnvPor)->GetLevel() % 2 : nFrmDir;
1400 nThisDir = ((SwBidiPortion&)rMulti).GetLevel() % 2;
1401 }
1388 SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
1389 sal_uInt8 nEnvDir = 0;
1390 sal_uInt8 nThisDir = 0;
1391 sal_uInt8 nFrmDir = 0;
1392 if ( rMulti.IsBidi() )
1393 {
1394 // these values are needed for the calculation of the x coordinate
1395 // and the layout mode
1396 ASSERT( ! pEnvPor || pEnvPor->IsBidi(), "I expected a BidiPortion" )
1397 nFrmDir = GetInfo().GetTxtFrm()->IsRightToLeft() ? 1 : 0;
1398 nEnvDir = pEnvPor ? ((SwBidiPortion*)pEnvPor)->GetLevel() % 2 : nFrmDir;
1399 nThisDir = ((SwBidiPortion&)rMulti).GetLevel() % 2;
1400 }
1402
1403#if OSL_DEBUG_LEVEL > 1
1401
1402#if OSL_DEBUG_LEVEL > 1
1404 // only paint first level bidi portions
1405 if( rMulti.Width() > 1 && ! pEnvPor )
1406 GetInfo().DrawViewOpt( rMulti, POR_FLD );
1403 // only paint first level bidi portions
1404 if( rMulti.Width() > 1 && ! pEnvPor )
1405 GetInfo().DrawViewOpt( rMulti, POR_FLD );
1407#endif
1408
1406#endif
1407
1409 if ( bRubyInGrid )
1410 rMulti.Height( nOldHeight );
1408 if ( bRubyInGrid )
1409 rMulti.Height( nOldHeight );
1411
1410
1412 // do we have to repaint a post it portion?
1413 if( GetInfo().OnWin() && rMulti.GetPortion() &&
1414 ! rMulti.GetPortion()->Width() )
1415 rMulti.GetPortion()->PrePaint( GetInfo(), &rMulti );
1411 // do we have to repaint a post it portion?
1412 if( GetInfo().OnWin() && rMulti.GetPortion() &&
1413 ! rMulti.GetPortion()->Width() )
1414 rMulti.GetPortion()->PrePaint( GetInfo(), &rMulti );
1416
1417 // old values must be saved and restored at the end
1418 xub_StrLen nOldLen = GetInfo().GetLen();
1419 KSHORT nOldX = KSHORT(GetInfo().X());
1415
1416 // old values must be saved and restored at the end
1417 xub_StrLen nOldLen = GetInfo().GetLen();
1418 KSHORT nOldX = KSHORT(GetInfo().X());
1420 long nOldY = GetInfo().Y();
1419 long nOldY = GetInfo().Y();
1421 xub_StrLen nOldIdx = GetInfo().GetIdx();
1422
1423 SwSpaceManipulator aManip( GetInfo(), rMulti );
1424
1425 SwFontSave *pFontSave;
1426 SwFont* pTmpFnt;
1427
1428 if( rMulti.IsDouble() )

--- 9 unchanged lines hidden (view full) ---

1438 else
1439 {
1440 pFontSave = NULL;
1441 pTmpFnt = NULL;
1442 }
1443
1444 if( rMulti.HasBrackets() )
1445 {
1420 xub_StrLen nOldIdx = GetInfo().GetIdx();
1421
1422 SwSpaceManipulator aManip( GetInfo(), rMulti );
1423
1424 SwFontSave *pFontSave;
1425 SwFont* pTmpFnt;
1426
1427 if( rMulti.IsDouble() )

--- 9 unchanged lines hidden (view full) ---

1437 else
1438 {
1439 pFontSave = NULL;
1440 pTmpFnt = NULL;
1441 }
1442
1443 if( rMulti.HasBrackets() )
1444 {
1446 xub_StrLen nTmpOldIdx = GetInfo().GetIdx();
1445 xub_StrLen nTmpOldIdx = GetInfo().GetIdx();
1447 GetInfo().SetIdx(((SwDoubleLinePortion&)rMulti).GetBrackets()->nStart);
1448 SeekAndChg( GetInfo() );
1449 ((SwDoubleLinePortion&)rMulti).PaintBracket( GetInfo(), 0, sal_True );
1446 GetInfo().SetIdx(((SwDoubleLinePortion&)rMulti).GetBrackets()->nStart);
1447 SeekAndChg( GetInfo() );
1448 ((SwDoubleLinePortion&)rMulti).PaintBracket( GetInfo(), 0, sal_True );
1450 GetInfo().SetIdx( nTmpOldIdx );
1449 GetInfo().SetIdx( nTmpOldIdx );
1451 }
1452
1453 KSHORT nTmpX = KSHORT(GetInfo().X());
1454
1455 SwLineLayout* pLay = &rMulti.GetRoot();// the first line of the multiportion
1456 SwLinePortion* pPor = pLay->GetFirstPortion();//first portion of these line
1450 }
1451
1452 KSHORT nTmpX = KSHORT(GetInfo().X());
1453
1454 SwLineLayout* pLay = &rMulti.GetRoot();// the first line of the multiportion
1455 SwLinePortion* pPor = pLay->GetFirstPortion();//first portion of these line
1457 SwTwips nOfst = 0;
1456 SwTwips nOfst = 0;
1458
1457
1459 // GetInfo().Y() is the baseline from the surrounding line. We must switch
1458 // GetInfo().Y() is the baseline from the surrounding line. We must switch
1460 // this temporary to the baseline of the inner lines of the multiportion.
1459 // this temporary to the baseline of the inner lines of the multiportion.
1461 if( rMulti.HasRotation() )
1462 {
1463 if( rMulti.IsRevers() )
1464 {
1465 GetInfo().Y( nOldY - rMulti.GetAscent() );
1466 nOfst = nTmpX + rMulti.Width();
1467 }
1468 else
1469 {
1470 GetInfo().Y( nOldY - rMulti.GetAscent() + rMulti.Height() );
1471 nOfst = nTmpX;
1472 }
1473 }
1474 else if ( rMulti.IsBidi() )
1475 {
1476 // does the current bidi portion has the same direction
1477 // as its environment?
1478 if ( nEnvDir != nThisDir )
1479 {
1480 // different directions, we have to adjust the x coordinate
1481 SwTwips nMultiWidth = rMulti.Width() +
1482 rMulti.CalcSpacing( GetInfo().GetSpaceAdd(), GetInfo() );
1460 if( rMulti.HasRotation() )
1461 {
1462 if( rMulti.IsRevers() )
1463 {
1464 GetInfo().Y( nOldY - rMulti.GetAscent() );
1465 nOfst = nTmpX + rMulti.Width();
1466 }
1467 else
1468 {
1469 GetInfo().Y( nOldY - rMulti.GetAscent() + rMulti.Height() );
1470 nOfst = nTmpX;
1471 }
1472 }
1473 else if ( rMulti.IsBidi() )
1474 {
1475 // does the current bidi portion has the same direction
1476 // as its environment?
1477 if ( nEnvDir != nThisDir )
1478 {
1479 // different directions, we have to adjust the x coordinate
1480 SwTwips nMultiWidth = rMulti.Width() +
1481 rMulti.CalcSpacing( GetInfo().GetSpaceAdd(), GetInfo() );
1483
1482
1484 if ( nFrmDir == nThisDir )
1485 GetInfo().X( GetInfo().X() - nMultiWidth );
1486 else
1487 GetInfo().X( GetInfo().X() + nMultiWidth );
1488 }
1483 if ( nFrmDir == nThisDir )
1484 GetInfo().X( GetInfo().X() - nMultiWidth );
1485 else
1486 GetInfo().X( GetInfo().X() + nMultiWidth );
1487 }
1489
1488
1490 nOfst = nOldY - rMulti.GetAscent();
1489 nOfst = nOldY - rMulti.GetAscent();
1491
1490
1492 // set layout mode
1493 aLayoutModeModifier.Modify( nThisDir );
1494 }
1495 else
1496 nOfst = nOldY - rMulti.GetAscent();
1491 // set layout mode
1492 aLayoutModeModifier.Modify( nThisDir );
1493 }
1494 else
1495 nOfst = nOldY - rMulti.GetAscent();
1497
1496
1498 sal_Bool bRest = pLay->IsRest();
1497 sal_Bool bRest = pLay->IsRest();
1499 sal_Bool bFirst = sal_True;
1500
1498 sal_Bool bFirst = sal_True;
1499
1501 ASSERT( 0 == GetInfo().GetUnderFnt() || rMulti.IsBidi(),
1502 " Only BiDi portions are allowed to use the common underlining font" )
1500 ASSERT( 0 == GetInfo().GetUnderFnt() || rMulti.IsBidi(),
1501 " Only BiDi portions are allowed to use the common underlining font" )
1503
1502
1504 do
1503 do
1505 {
1504 {
1506 if ( bHasGrid )
1507 {
1508 if( rMulti.HasRotation() )
1509 {
1510 const sal_uInt16 nAdjustment = ( pLay->Height() - pPor->Height() ) / 2 +
1511 pPor->GetAscent();
1512 if( rMulti.IsRevers() )
1513 GetInfo().X( nOfst - nAdjustment );
1514 else
1515 GetInfo().X( nOfst + nAdjustment );
1516 }
1517 else
1518 {
1519 // special treatment for ruby portions in grid mode
1520 SwTwips nAdjustment = 0;
1521 if ( rMulti.IsRuby() )
1522 {
1523 if ( bRubyTop != ( pLay == &rMulti.GetRoot() ) )
1524 // adjust base text
1525 nAdjustment = ( pCurr->Height() - nRubyHeight - pPor->Height() ) / 2;
1526 else if ( bRubyTop )
1527 // adjust upper ruby text
1528 nAdjustment = nRubyHeight - pPor->Height();
1529 // else adjust lower ruby text
1530 }
1505 if ( bHasGrid )
1506 {
1507 if( rMulti.HasRotation() )
1508 {
1509 const sal_uInt16 nAdjustment = ( pLay->Height() - pPor->Height() ) / 2 +
1510 pPor->GetAscent();
1511 if( rMulti.IsRevers() )
1512 GetInfo().X( nOfst - nAdjustment );
1513 else
1514 GetInfo().X( nOfst + nAdjustment );
1515 }
1516 else
1517 {
1518 // special treatment for ruby portions in grid mode
1519 SwTwips nAdjustment = 0;
1520 if ( rMulti.IsRuby() )
1521 {
1522 if ( bRubyTop != ( pLay == &rMulti.GetRoot() ) )
1523 // adjust base text
1524 nAdjustment = ( pCurr->Height() - nRubyHeight - pPor->Height() ) / 2;
1525 else if ( bRubyTop )
1526 // adjust upper ruby text
1527 nAdjustment = nRubyHeight - pPor->Height();
1528 // else adjust lower ruby text
1529 }
1531
1530
1532 GetInfo().Y( nOfst + nAdjustment + pPor->GetAscent() );
1533 }
1534 }
1535 else if( rMulti.HasRotation() )
1536 {
1537 if( rMulti.IsRevers() )
1538 GetInfo().X( nOfst - AdjustBaseLine( *pLay, pPor, 0, 0, sal_True ) );
1539 else
1540 GetInfo().X( nOfst + AdjustBaseLine( *pLay, pPor ) );
1541 }
1542 else
1543 GetInfo().Y( nOfst + AdjustBaseLine( *pLay, pPor ) );
1531 GetInfo().Y( nOfst + nAdjustment + pPor->GetAscent() );
1532 }
1533 }
1534 else if( rMulti.HasRotation() )
1535 {
1536 if( rMulti.IsRevers() )
1537 GetInfo().X( nOfst - AdjustBaseLine( *pLay, pPor, 0, 0, sal_True ) );
1538 else
1539 GetInfo().X( nOfst + AdjustBaseLine( *pLay, pPor ) );
1540 }
1541 else
1542 GetInfo().Y( nOfst + AdjustBaseLine( *pLay, pPor ) );
1544
1543
1545 sal_Bool bSeeked = sal_True;
1544 sal_Bool bSeeked = sal_True;
1546 GetInfo().SetLen( pPor->GetLen() );
1547
1545 GetInfo().SetLen( pPor->GetLen() );
1546
1548 if( bRest && pPor->InFldGrp() && !pPor->GetLen() )
1547 if( bRest && pPor->InFldGrp() && !pPor->GetLen() )
1549 {
1550 if( ((SwFldPortion*)pPor)->HasFont() )
1551 bSeeked = sal_False;
1552 else
1553 SeekAndChgBefore( GetInfo() );
1554 }
1555 else if( pPor->InTxtGrp() || pPor->InFldGrp() || pPor->InTabGrp() )
1556 SeekAndChg( GetInfo() );
1557 else if ( !bFirst && pPor->IsBreakPortion() && GetInfo().GetOpt().IsParagraph() )
1558 {
1559 if( GetRedln() )
1560 SeekAndChg( GetInfo() );
1561 else
1562 SeekAndChgBefore( GetInfo() );
1563 }
1564 else
1548 {
1549 if( ((SwFldPortion*)pPor)->HasFont() )
1550 bSeeked = sal_False;
1551 else
1552 SeekAndChgBefore( GetInfo() );
1553 }
1554 else if( pPor->InTxtGrp() || pPor->InFldGrp() || pPor->InTabGrp() )
1555 SeekAndChg( GetInfo() );
1556 else if ( !bFirst && pPor->IsBreakPortion() && GetInfo().GetOpt().IsParagraph() )
1557 {
1558 if( GetRedln() )
1559 SeekAndChg( GetInfo() );
1560 else
1561 SeekAndChgBefore( GetInfo() );
1562 }
1563 else
1565 bSeeked = sal_False;
1564 bSeeked = sal_False;
1566
1567 SwLinePortion *pNext = pPor->GetPortion();
1568 if(GetInfo().OnWin() && pNext && !pNext->Width() )
1569 {
1570 if ( !bSeeked )
1571 SeekAndChg( GetInfo() );
1565
1566 SwLinePortion *pNext = pPor->GetPortion();
1567 if(GetInfo().OnWin() && pNext && !pNext->Width() )
1568 {
1569 if ( !bSeeked )
1570 SeekAndChg( GetInfo() );
1572 pNext->PrePaint( GetInfo(), pPor );
1571 pNext->PrePaint( GetInfo(), pPor );
1573 }
1574
1572 }
1573
1575 CheckSpecialUnderline( pPor );
1576 SwUnderlineFont* pUnderLineFnt = GetInfo().GetUnderFnt();
1577 if ( pUnderLineFnt )
1578 {
1579 if ( rMulti.IsDouble() )
1580 pUnderLineFnt->GetFont().SetProportion( 50 );
1581 pUnderLineFnt->SetPos( GetInfo().GetPos() );
1582 }
1574 CheckSpecialUnderline( pPor );
1575 SwUnderlineFont* pUnderLineFnt = GetInfo().GetUnderFnt();
1576 if ( pUnderLineFnt )
1577 {
1578 if ( rMulti.IsDouble() )
1579 pUnderLineFnt->GetFont().SetProportion( 50 );
1580 pUnderLineFnt->SetPos( GetInfo().GetPos() );
1581 }
1583
1582
1584 if ( rMulti.IsBidi() )
1585 {
1586 // we do not allow any rotation inside a bidi portion
1587 SwFont* pTmpFont = GetInfo().GetFont();
1588 pTmpFont->SetVertical( 0, GetInfo().GetTxtFrm()->IsVertical() );
1589 }
1583 if ( rMulti.IsBidi() )
1584 {
1585 // we do not allow any rotation inside a bidi portion
1586 SwFont* pTmpFont = GetInfo().GetFont();
1587 pTmpFont->SetVertical( 0, GetInfo().GetTxtFrm()->IsVertical() );
1588 }
1590
1589
1591 if( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsBidi() )
1592 {
1593 // but we do allow nested bidi portions
1594 ASSERT( rMulti.IsBidi(), "Only nesting of bidi portions is allowed" )
1595 PaintMultiPortion( rPaint, (SwMultiPortion&)*pPor, &rMulti );
1596 }
1597 else
1598 pPor->Paint( GetInfo() );
1590 if( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsBidi() )
1591 {
1592 // but we do allow nested bidi portions
1593 ASSERT( rMulti.IsBidi(), "Only nesting of bidi portions is allowed" )
1594 PaintMultiPortion( rPaint, (SwMultiPortion&)*pPor, &rMulti );
1595 }
1596 else
1597 pPor->Paint( GetInfo() );
1599
1598
1600 if( GetFnt()->IsURL() && pPor->InTxtGrp() )
1599 if( GetFnt()->IsURL() && pPor->InTxtGrp() )
1601 GetInfo().NotifyURL( *pPor );
1602
1603 bFirst &= !pPor->GetLen();
1604 if( pNext || !pPor->IsMarginPortion() )
1605 pPor->Move( GetInfo() );
1606
1600 GetInfo().NotifyURL( *pPor );
1601
1602 bFirst &= !pPor->GetLen();
1603 if( pNext || !pPor->IsMarginPortion() )
1604 pPor->Move( GetInfo() );
1605
1607 pPor = pNext;
1606 pPor = pNext;
1608
1609 // If there's no portion left, we go to the next line
1610 if( !pPor && pLay->GetNext() )
1611 {
1607
1608 // If there's no portion left, we go to the next line
1609 if( !pPor && pLay->GetNext() )
1610 {
1612 pLay = pLay->GetNext();
1613 pPor = pLay->GetFirstPortion();
1614 bRest = pLay->IsRest();
1615 aManip.SecondLine();
1611 pLay = pLay->GetNext();
1612 pPor = pLay->GetFirstPortion();
1613 bRest = pLay->IsRest();
1614 aManip.SecondLine();
1616
1615
1617 // delete underline font
1618 delete GetInfo().GetUnderFnt();
1619 GetInfo().SetUnderFnt( 0 );
1616 // delete underline font
1617 delete GetInfo().GetUnderFnt();
1618 GetInfo().SetUnderFnt( 0 );
1620
1619
1621 if( rMulti.HasRotation() )
1622 {
1623 if( rMulti.IsRevers() )
1624 {
1625 nOfst += pLay->Height();
1626 GetInfo().Y( nOldY - rMulti.GetAscent() );
1627 }
1628 else
1629 {
1630 nOfst -= pLay->Height();
1631 GetInfo().Y( nOldY - rMulti.GetAscent() + rMulti.Height() );
1632 }
1633 }
1634 else if ( bHasGrid && rMulti.IsRuby() )
1635 {
1636 GetInfo().X( nTmpX );
1637 if ( bRubyTop )
1638 {
1639 nOfst += nRubyHeight;
1640 GetInfo().SetSnapToGrid( sal_True );
1641 }
1642 else
1643 {
1644 nOfst += pCurr->Height() - nRubyHeight;
1645 GetInfo().SetSnapToGrid( sal_False );
1646 }
1647 } else
1648 {
1649 GetInfo().X( nTmpX );
1650 // We switch to the baseline of the next inner line
1651 nOfst += rMulti.GetRoot().Height();
1652 }
1620 if( rMulti.HasRotation() )
1621 {
1622 if( rMulti.IsRevers() )
1623 {
1624 nOfst += pLay->Height();
1625 GetInfo().Y( nOldY - rMulti.GetAscent() );
1626 }
1627 else
1628 {
1629 nOfst -= pLay->Height();
1630 GetInfo().Y( nOldY - rMulti.GetAscent() + rMulti.Height() );
1631 }
1632 }
1633 else if ( bHasGrid && rMulti.IsRuby() )
1634 {
1635 GetInfo().X( nTmpX );
1636 if ( bRubyTop )
1637 {
1638 nOfst += nRubyHeight;
1639 GetInfo().SetSnapToGrid( sal_True );
1640 }
1641 else
1642 {
1643 nOfst += pCurr->Height() - nRubyHeight;
1644 GetInfo().SetSnapToGrid( sal_False );
1645 }
1646 } else
1647 {
1648 GetInfo().X( nTmpX );
1649 // We switch to the baseline of the next inner line
1650 nOfst += rMulti.GetRoot().Height();
1651 }
1653 }
1654 } while( pPor );
1655
1652 }
1653 } while( pPor );
1654
1656 if ( bRubyInGrid )
1657 GetInfo().SetSnapToGrid( bOldGridModeAllowed );
1655 if ( bRubyInGrid )
1656 GetInfo().SetSnapToGrid( bOldGridModeAllowed );
1658
1657
1659 // delete underline font
1660 if ( ! rMulti.IsBidi() )
1661 {
1662 delete GetInfo().GetUnderFnt();
1663 GetInfo().SetUnderFnt( 0 );
1664 }
1658 // delete underline font
1659 if ( ! rMulti.IsBidi() )
1660 {
1661 delete GetInfo().GetUnderFnt();
1662 GetInfo().SetUnderFnt( 0 );
1663 }
1665
1664
1666 GetInfo().SetIdx( nOldIdx );
1665 GetInfo().SetIdx( nOldIdx );
1667 GetInfo().Y( nOldY );
1668
1669 if( rMulti.HasBrackets() )
1670 {
1666 GetInfo().Y( nOldY );
1667
1668 if( rMulti.HasBrackets() )
1669 {
1671 xub_StrLen nTmpOldIdx = GetInfo().GetIdx();
1670 xub_StrLen nTmpOldIdx = GetInfo().GetIdx();
1672 GetInfo().SetIdx(((SwDoubleLinePortion&)rMulti).GetBrackets()->nStart);
1673 SeekAndChg( GetInfo() );
1674 GetInfo().X( nOldX );
1675 ((SwDoubleLinePortion&)rMulti).PaintBracket( GetInfo(),
1676 aManip.GetSpaceAdd(), sal_False );
1671 GetInfo().SetIdx(((SwDoubleLinePortion&)rMulti).GetBrackets()->nStart);
1672 SeekAndChg( GetInfo() );
1673 GetInfo().X( nOldX );
1674 ((SwDoubleLinePortion&)rMulti).PaintBracket( GetInfo(),
1675 aManip.GetSpaceAdd(), sal_False );
1677 GetInfo().SetIdx( nTmpOldIdx );
1676 GetInfo().SetIdx( nTmpOldIdx );
1678 }
1679 // Restore the saved values
1680 GetInfo().X( nOldX );
1681 GetInfo().SetLen( nOldLen );
1682 delete pFontSave;
1683 delete pTmpFnt;
1684 SetPropFont( 0 );
1685}

--- 18 unchanged lines hidden (view full) ---

1704 else
1705 rpFld = NULL;
1706 }
1707 pLine->Truncate();
1708 return bRet;
1709}
1710
1711/*----------------------------------------------------
1677 }
1678 // Restore the saved values
1679 GetInfo().X( nOldX );
1680 GetInfo().SetLen( nOldLen );
1681 delete pFontSave;
1682 delete pTmpFnt;
1683 SetPropFont( 0 );
1684}

--- 18 unchanged lines hidden (view full) ---

1703 else
1704 rpFld = NULL;
1705 }
1706 pLine->Truncate();
1707 return bRet;
1708}
1709
1710/*----------------------------------------------------
1712 * lcl_TruncateMultiPortion
1711 * lcl_TruncateMultiPortion
1713 * If a multi portion completely has to go to the
1712 * If a multi portion completely has to go to the
1714 * next line, this function is called to trunctate
1713 * next line, this function is called to truncate
1715 * the rest of the remaining multi portion
1716 * --------------------------------------------------*/
1717
1718void lcl_TruncateMultiPortion( SwMultiPortion& rMulti, SwTxtFormatInfo& rInf,
1714 * the rest of the remaining multi portion
1715 * --------------------------------------------------*/
1716
1717void lcl_TruncateMultiPortion( SwMultiPortion& rMulti, SwTxtFormatInfo& rInf,
1719 xub_StrLen nStartIdx )
1718 xub_StrLen nStartIdx )
1720{
1719{
1721 rMulti.GetRoot().Truncate();
1722 rMulti.GetRoot().SetLen(0);
1723 rMulti.GetRoot().Width(0);
1724// rMulti.CalcSize( *this, aInf );
1725 if ( rMulti.GetRoot().GetNext() )
1726 {
1727 rMulti.GetRoot().GetNext()->Truncate();
1728 rMulti.GetRoot().GetNext()->SetLen( 0 );
1729 rMulti.GetRoot().GetNext()->Width( 0 );
1730 }
1731 rMulti.Width( 0 );
1732 rMulti.SetLen(0);
1733 rInf.SetIdx( nStartIdx );
1720 rMulti.GetRoot().Truncate();
1721 rMulti.GetRoot().SetLen(0);
1722 rMulti.GetRoot().Width(0);
1723// rMulti.CalcSize( *this, aInf );
1724 if ( rMulti.GetRoot().GetNext() )
1725 {
1726 rMulti.GetRoot().GetNext()->Truncate();
1727 rMulti.GetRoot().GetNext()->SetLen( 0 );
1728 rMulti.GetRoot().GetNext()->Width( 0 );
1729 }
1730 rMulti.Width( 0 );
1731 rMulti.SetLen(0);
1732 rInf.SetIdx( nStartIdx );
1734}
1735
1736/*-----------------------------------------------------------------------------
1733}
1734
1735/*-----------------------------------------------------------------------------
1737 * SwTxtFormatter::BuildMultiPortion
1736 * SwTxtFormatter::BuildMultiPortion
1738 * manages the formatting of a SwMultiPortion. External, for the calling
1739 * function, it seems to be a normal Format-function, internal it is like a
1740 * SwTxtFrm::_Format with multiple BuildPortions
1741 *---------------------------------------------------------------------------*/
1742
1743sal_Bool SwTxtFormatter::BuildMultiPortion( SwTxtFormatInfo &rInf,
1744 SwMultiPortion& rMulti )
1745{
1746 SwTwips nMaxWidth = rInf.Width();
1737 * manages the formatting of a SwMultiPortion. External, for the calling
1738 * function, it seems to be a normal Format-function, internal it is like a
1739 * SwTxtFrm::_Format with multiple BuildPortions
1740 *---------------------------------------------------------------------------*/
1741
1742sal_Bool SwTxtFormatter::BuildMultiPortion( SwTxtFormatInfo &rInf,
1743 SwMultiPortion& rMulti )
1744{
1745 SwTwips nMaxWidth = rInf.Width();
1747 KSHORT nOldX = 0;
1746 KSHORT nOldX = 0;
1748
1749 if( rMulti.HasBrackets() )
1750 {
1751 xub_StrLen nOldIdx = rInf.GetIdx();
1752 rInf.SetIdx( ((SwDoubleLinePortion&)rMulti).GetBrackets()->nStart );
1753 SeekAndChg( rInf );
1747
1748 if( rMulti.HasBrackets() )
1749 {
1750 xub_StrLen nOldIdx = rInf.GetIdx();
1751 rInf.SetIdx( ((SwDoubleLinePortion&)rMulti).GetBrackets()->nStart );
1752 SeekAndChg( rInf );
1754 nOldX = KSHORT(GetInfo().X());
1753 nOldX = KSHORT(GetInfo().X());
1755 ((SwDoubleLinePortion&)rMulti).FormatBrackets( rInf, nMaxWidth );
1756 rInf.SetIdx( nOldIdx );
1757 }
1758
1759 SeekAndChg( rInf );
1760 SwFontSave *pFontSave;
1761 if( rMulti.IsDouble() )
1762 {
1763 SwFont* pTmpFnt = new SwFont( *rInf.GetFont() );
1764 if( rMulti.IsDouble() )
1765 {
1766 SetPropFont( 50 );
1767 pTmpFnt->SetProportion( GetPropFont() );
1768 }
1769 pFontSave = new SwFontSave( rInf, pTmpFnt, this );
1770 }
1771 else
1772 pFontSave = NULL;
1773
1754 ((SwDoubleLinePortion&)rMulti).FormatBrackets( rInf, nMaxWidth );
1755 rInf.SetIdx( nOldIdx );
1756 }
1757
1758 SeekAndChg( rInf );
1759 SwFontSave *pFontSave;
1760 if( rMulti.IsDouble() )
1761 {
1762 SwFont* pTmpFnt = new SwFont( *rInf.GetFont() );
1763 if( rMulti.IsDouble() )
1764 {
1765 SetPropFont( 50 );
1766 pTmpFnt->SetProportion( GetPropFont() );
1767 }
1768 pFontSave = new SwFontSave( rInf, pTmpFnt, this );
1769 }
1770 else
1771 pFontSave = NULL;
1772
1774 SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
1775 if ( rMulti.IsBidi() )
1776 {
1777 // set layout mode
1778 aLayoutModeModifier.Modify( ! rInf.GetTxtFrm()->IsRightToLeft() );
1779 }
1773 SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
1774 if ( rMulti.IsBidi() )
1775 {
1776 // set layout mode
1777 aLayoutModeModifier.Modify( ! rInf.GetTxtFrm()->IsRightToLeft() );
1778 }
1780
1779
1781 SwTwips nTmpX = 0;
1780 SwTwips nTmpX = 0;
1782
1781
1783 if( rMulti.HasRotation() )
1784 {
1785 // For nMaxWidth we take the height of the body frame.
1786 // #i25067#: If the current frame is inside a table, we restrict
1787 // nMaxWidth to the current frame height, unless the frame size
1788 // attribute is set to variable size:
1782 if( rMulti.HasRotation() )
1783 {
1784 // For nMaxWidth we take the height of the body frame.
1785 // #i25067#: If the current frame is inside a table, we restrict
1786 // nMaxWidth to the current frame height, unless the frame size
1787 // attribute is set to variable size:
1789
1788
1790 // We set nTmpX (which is used for portion calculating) to the
1791 // current Y value
1792 const SwPageFrm* pPage = pFrm->FindPageFrm();
1793 ASSERT( pPage, "No page in frame!");
1794 const SwLayoutFrm* pUpperFrm = pPage;
1789 // We set nTmpX (which is used for portion calculating) to the
1790 // current Y value
1791 const SwPageFrm* pPage = pFrm->FindPageFrm();
1792 ASSERT( pPage, "No page in frame!");
1793 const SwLayoutFrm* pUpperFrm = pPage;
1795
1794
1796 if ( pFrm->IsInTab() )
1797 {
1798 pUpperFrm = pFrm->GetUpper();
1799 while ( pUpperFrm && !pUpperFrm->IsCellFrm() )
1800 pUpperFrm = pUpperFrm->GetUpper();
1801 ASSERT( pUpperFrm, "pFrm is in table but does not have an upper cell frame" )
1802 const SwTableLine* pLine = ((SwRowFrm*)pUpperFrm->GetUpper())->GetTabLine();
1803 const SwFmtFrmSize& rFrmFmtSize = pLine->GetFrmFmt()->GetFrmSize();
1804 if ( ATT_VAR_SIZE == rFrmFmtSize.GetHeightSizeType() )
1805 pUpperFrm = pPage;
1806 }
1807 if ( pUpperFrm == pPage && !pFrm->IsInFtn() )
1808 pUpperFrm = pPage->FindBodyCont();
1795 if ( pFrm->IsInTab() )
1796 {
1797 pUpperFrm = pFrm->GetUpper();
1798 while ( pUpperFrm && !pUpperFrm->IsCellFrm() )
1799 pUpperFrm = pUpperFrm->GetUpper();
1800 ASSERT( pUpperFrm, "pFrm is in table but does not have an upper cell frame" )
1801 const SwTableLine* pLine = ((SwRowFrm*)pUpperFrm->GetUpper())->GetTabLine();
1802 const SwFmtFrmSize& rFrmFmtSize = pLine->GetFrmFmt()->GetFrmSize();
1803 if ( ATT_VAR_SIZE == rFrmFmtSize.GetHeightSizeType() )
1804 pUpperFrm = pPage;
1805 }
1806 if ( pUpperFrm == pPage && !pFrm->IsInFtn() )
1807 pUpperFrm = pPage->FindBodyCont();
1809
1808
1810 nMaxWidth = pUpperFrm ?
1811 ( rInf.GetTxtFrm()->IsVertical() ?
1812 pUpperFrm->Prt().Width() :
1813 pUpperFrm->Prt().Height() ) :
1814 USHRT_MAX;
1815 }
1816 else
1817 nTmpX = rInf.X();
1809 nMaxWidth = pUpperFrm ?
1810 ( rInf.GetTxtFrm()->IsVertical() ?
1811 pUpperFrm->Prt().Width() :
1812 pUpperFrm->Prt().Height() ) :
1813 USHRT_MAX;
1814 }
1815 else
1816 nTmpX = rInf.X();
1818
1817
1819 SwMultiPortion* pOldMulti = pMulti;
1818 SwMultiPortion* pOldMulti = pMulti;
1820
1819
1821 pMulti = &rMulti;
1820 pMulti = &rMulti;
1822 SwLineLayout *pOldCurr = pCurr;
1823 xub_StrLen nOldStart = GetStart();
1824 SwTwips nMinWidth = nTmpX + 1;
1821 SwLineLayout *pOldCurr = pCurr;
1822 xub_StrLen nOldStart = GetStart();
1823 SwTwips nMinWidth = nTmpX + 1;
1825 SwTwips nActWidth = nMaxWidth;
1826 const xub_StrLen nStartIdx = rInf.GetIdx();
1824 SwTwips nActWidth = nMaxWidth;
1825 const xub_StrLen nStartIdx = rInf.GetIdx();
1827 xub_StrLen nMultiLen = rMulti.GetLen();
1828
1829 SwLinePortion *pFirstRest;
1830 SwLinePortion *pSecondRest;
1831 if( rMulti.IsFormatted() )
1832 {
1833 if( !lcl_ExtractFieldFollow( &rMulti.GetRoot(), pFirstRest )
1834 && rMulti.IsDouble() && rMulti.GetRoot().GetNext() )

--- 11 unchanged lines hidden (view full) ---

1846 if( pFirstRest )
1847 rMulti.GetRoot().SetPortion( NULL );
1848 if( pSecondRest )
1849 rMulti.GetRoot().GetNext()->SetPortion( NULL );
1850 rMulti.SetFormatted();
1851 nMultiLen = nMultiLen - rInf.GetIdx();
1852 }
1853
1826 xub_StrLen nMultiLen = rMulti.GetLen();
1827
1828 SwLinePortion *pFirstRest;
1829 SwLinePortion *pSecondRest;
1830 if( rMulti.IsFormatted() )
1831 {
1832 if( !lcl_ExtractFieldFollow( &rMulti.GetRoot(), pFirstRest )
1833 && rMulti.IsDouble() && rMulti.GetRoot().GetNext() )

--- 11 unchanged lines hidden (view full) ---

1845 if( pFirstRest )
1846 rMulti.GetRoot().SetPortion( NULL );
1847 if( pSecondRest )
1848 rMulti.GetRoot().GetNext()->SetPortion( NULL );
1849 rMulti.SetFormatted();
1850 nMultiLen = nMultiLen - rInf.GetIdx();
1851 }
1852
1854 // save some values
1853 // save some values
1855 const XubString* pOldTxt = &(rInf.GetTxt());
1854 const XubString* pOldTxt = &(rInf.GetTxt());
1856 const SwTwips nOldPaintOfst = rInf.GetPaintOfst();
1855 const SwTwips nOldPaintOfst = rInf.GetPaintOfst();
1857
1858 XubString aMultiStr( rInf.GetTxt(), 0, nMultiLen + rInf.GetIdx() );
1859 rInf.SetTxt( aMultiStr );
1860 SwTxtFormatInfo aInf( rInf, rMulti.GetRoot(), nActWidth );
1856
1857 XubString aMultiStr( rInf.GetTxt(), 0, nMultiLen + rInf.GetIdx() );
1858 rInf.SetTxt( aMultiStr );
1859 SwTxtFormatInfo aInf( rInf, rMulti.GetRoot(), nActWidth );
1861 // Do we allow break cuts? The FirstMulti-Flag is evaluated during
1862 // line break determination.
1863 sal_Bool bFirstMulti = rInf.GetIdx() != rInf.GetLineStart();
1860 // Do we allow break cuts? The FirstMulti-Flag is evaluated during
1861 // line break determination.
1862 sal_Bool bFirstMulti = rInf.GetIdx() != rInf.GetLineStart();
1864
1865 SwLinePortion *pNextFirst = NULL;
1866 SwLinePortion *pNextSecond = NULL;
1867 sal_Bool bRet = sal_False;
1868
1863
1864 SwLinePortion *pNextFirst = NULL;
1865 SwLinePortion *pNextSecond = NULL;
1866 sal_Bool bRet = sal_False;
1867
1869 GETGRID( pFrm->FindPageFrm() )
1870 const sal_Bool bHasGrid = pGrid && GRID_LINES_CHARS == pGrid->GetGridType();
1868 GETGRID( pFrm->FindPageFrm() )
1869 const sal_Bool bHasGrid = pGrid && GRID_LINES_CHARS == pGrid->GetGridType();
1871
1870
1872 sal_uInt16 nGridWidth = 0;
1873 sal_uInt16 nRubyHeight = 0;
1874 sal_Bool bRubyTop = sal_False;
1871 sal_uInt16 nGridWidth = 0;
1872 sal_uInt16 nRubyHeight = 0;
1873 sal_Bool bRubyTop = sal_False;
1875
1874
1876 if ( bHasGrid )
1877 {
1878 nGridWidth = pGrid->GetBaseHeight();
1879 nRubyHeight = pGrid->GetRubyHeight();
1880 bRubyTop = ! pGrid->GetRubyTextBelow();
1881 }
1875 if ( bHasGrid )
1876 {
1877 nGridWidth = pGrid->GetBaseHeight();
1878 nRubyHeight = pGrid->GetRubyHeight();
1879 bRubyTop = ! pGrid->GetRubyTextBelow();
1880 }
1882
1883 do
1884 {
1885 pCurr = &rMulti.GetRoot();
1886 nStart = nStartIdx;
1887 bRet = sal_False;
1888 FormatReset( aInf );
1889 aInf.X( nTmpX );
1890 aInf.Width( KSHORT(nActWidth) );
1891 aInf.RealWidth( KSHORT(nActWidth) );
1881
1882 do
1883 {
1884 pCurr = &rMulti.GetRoot();
1885 nStart = nStartIdx;
1886 bRet = sal_False;
1887 FormatReset( aInf );
1888 aInf.X( nTmpX );
1889 aInf.Width( KSHORT(nActWidth) );
1890 aInf.RealWidth( KSHORT(nActWidth) );
1892 aInf.SetFirstMulti( bFirstMulti );
1893 aInf.SetNumDone( rInf.IsNumDone() );
1894 aInf.SetFtnDone( rInf.IsFtnDone() );
1891 aInf.SetFirstMulti( bFirstMulti );
1892 aInf.SetNumDone( rInf.IsNumDone() );
1893 aInf.SetFtnDone( rInf.IsFtnDone() );
1895
1894
1896 if( pFirstRest )
1895 if( pFirstRest )
1897 {
1896 {
1898 ASSERT( pFirstRest->InFldGrp(), "BuildMulti: Fieldrest expected");
1897 ASSERT( pFirstRest->InFldGrp(), "BuildMulti: Fieldrest expected");
1899 SwFldPortion *pFld =
1900 ((SwFldPortion*)pFirstRest)->Clone(
1901 ((SwFldPortion*)pFirstRest)->GetExp() );
1902 pFld->SetFollow( sal_True );
1903 aInf.SetRest( pFld );
1904 }
1905 aInf.SetRuby( rMulti.IsRuby() && rMulti.OnTop() );
1906
1898 SwFldPortion *pFld =
1899 ((SwFldPortion*)pFirstRest)->Clone(
1900 ((SwFldPortion*)pFirstRest)->GetExp() );
1901 pFld->SetFollow( sal_True );
1902 aInf.SetRest( pFld );
1903 }
1904 aInf.SetRuby( rMulti.IsRuby() && rMulti.OnTop() );
1905
1907 // in grid mode we temporarily have to disable the grid for the ruby line
1908 const sal_Bool bOldGridModeAllowed = GetInfo().SnapToGrid();
1909 if ( bHasGrid && aInf.IsRuby() && bRubyTop )
1910 aInf.SetSnapToGrid( sal_False );
1906 // in grid mode we temporarily have to disable the grid for the ruby line
1907 const sal_Bool bOldGridModeAllowed = GetInfo().SnapToGrid();
1908 if ( bHasGrid && aInf.IsRuby() && bRubyTop )
1909 aInf.SetSnapToGrid( sal_False );
1911
1910
1912 // If there's no more rubytext, then buildportion is forbidden
1911 // If there's no more rubytext, then buildportion is forbidden
1913 if( pFirstRest || !aInf.IsRuby() )
1914 BuildPortions( aInf );
1915
1912 if( pFirstRest || !aInf.IsRuby() )
1913 BuildPortions( aInf );
1914
1916 aInf.SetSnapToGrid( bOldGridModeAllowed );
1915 aInf.SetSnapToGrid( bOldGridModeAllowed );
1917
1918 rMulti.CalcSize( *this, aInf );
1916
1917 rMulti.CalcSize( *this, aInf );
1919 pCurr->SetRealHeight( pCurr->Height() );
1918 pCurr->SetRealHeight( pCurr->Height() );
1920
1919
1921 if( rMulti.IsBidi() )
1922 {
1923 pNextFirst = aInf.GetRest();
1924 break;
1925 }
1920 if( rMulti.IsBidi() )
1921 {
1922 pNextFirst = aInf.GetRest();
1923 break;
1924 }
1926
1927 if( rMulti.HasRotation() && !rMulti.IsDouble() )
1928 break;
1925
1926 if( rMulti.HasRotation() && !rMulti.IsDouble() )
1927 break;
1929 // second line has to be formatted
1930 else if( pCurr->GetLen()<nMultiLen || rMulti.IsRuby() || aInf.GetRest())
1928 // second line has to be formatted
1929 else if( pCurr->GetLen()<nMultiLen || rMulti.IsRuby() || aInf.GetRest())
1931 {
1932 xub_StrLen nFirstLen = pCurr->GetLen();
1933 delete pCurr->GetNext();
1934 pCurr->SetNext( new SwLineLayout() );
1930 {
1931 xub_StrLen nFirstLen = pCurr->GetLen();
1932 delete pCurr->GetNext();
1933 pCurr->SetNext( new SwLineLayout() );
1935 pCurr = pCurr->GetNext();
1934 pCurr = pCurr->GetNext();
1936 nStart = aInf.GetIdx();
1937 aInf.X( nTmpX );
1938 SwTxtFormatInfo aTmp( aInf, *pCurr, nActWidth );
1939 if( rMulti.IsRuby() )
1940 {
1941 aTmp.SetRuby( !rMulti.OnTop() );
1942 pNextFirst = aInf.GetRest();
1943 if( pSecondRest )
1944 {
1935 nStart = aInf.GetIdx();
1936 aInf.X( nTmpX );
1937 SwTxtFormatInfo aTmp( aInf, *pCurr, nActWidth );
1938 if( rMulti.IsRuby() )
1939 {
1940 aTmp.SetRuby( !rMulti.OnTop() );
1941 pNextFirst = aInf.GetRest();
1942 if( pSecondRest )
1943 {
1945 ASSERT( pSecondRest->InFldGrp(), "Fieldrest expected");
1944 ASSERT( pSecondRest->InFldGrp(), "Fieldrest expected");
1946 SwFldPortion *pFld = ((SwFldPortion*)pSecondRest)->Clone(
1947 ((SwFldPortion*)pSecondRest)->GetExp() );
1948 pFld->SetFollow( sal_True );
1949 aTmp.SetRest( pFld );
1950 }
1951 if( !rMulti.OnTop() && nFirstLen < nMultiLen )
1952 bRet = sal_True;
1953 }
1954 else
1955 aTmp.SetRest( aInf.GetRest() );
1956 aInf.SetRest( NULL );
1957
1945 SwFldPortion *pFld = ((SwFldPortion*)pSecondRest)->Clone(
1946 ((SwFldPortion*)pSecondRest)->GetExp() );
1947 pFld->SetFollow( sal_True );
1948 aTmp.SetRest( pFld );
1949 }
1950 if( !rMulti.OnTop() && nFirstLen < nMultiLen )
1951 bRet = sal_True;
1952 }
1953 else
1954 aTmp.SetRest( aInf.GetRest() );
1955 aInf.SetRest( NULL );
1956
1958 // in grid mode we temporarily have to disable the grid for the ruby line
1959 if ( bHasGrid && aTmp.IsRuby() && ! bRubyTop )
1960 aTmp.SetSnapToGrid( sal_False );
1957 // in grid mode we temporarily have to disable the grid for the ruby line
1958 if ( bHasGrid && aTmp.IsRuby() && ! bRubyTop )
1959 aTmp.SetSnapToGrid( sal_False );
1961
1960
1962 BuildPortions( aTmp );
1961 BuildPortions( aTmp );
1963
1962
1964 aTmp.SetSnapToGrid( bOldGridModeAllowed );
1963 aTmp.SetSnapToGrid( bOldGridModeAllowed );
1965
1964
1966 rMulti.CalcSize( *this, aInf );
1967 rMulti.GetRoot().SetRealHeight( rMulti.GetRoot().Height() );
1965 rMulti.CalcSize( *this, aInf );
1966 rMulti.GetRoot().SetRealHeight( rMulti.GetRoot().Height() );
1968 pCurr->SetRealHeight( pCurr->Height() );
1969 if( rMulti.IsRuby() )
1970 {
1971 pNextSecond = aTmp.GetRest();
1972 if( pNextFirst )
1973 bRet = sal_True;
1974 }
1975 else
1976 pNextFirst = aTmp.GetRest();
1977 if( ( !aTmp.IsRuby() && nFirstLen + pCurr->GetLen() < nMultiLen )
1978 || aTmp.GetRest() )
1967 pCurr->SetRealHeight( pCurr->Height() );
1968 if( rMulti.IsRuby() )
1969 {
1970 pNextSecond = aTmp.GetRest();
1971 if( pNextFirst )
1972 bRet = sal_True;
1973 }
1974 else
1975 pNextFirst = aTmp.GetRest();
1976 if( ( !aTmp.IsRuby() && nFirstLen + pCurr->GetLen() < nMultiLen )
1977 || aTmp.GetRest() )
1979 // our guess for width of multiportion was too small,
1980 // text did not fit into multiportion
1978 // our guess for width of multiportion was too small,
1979 // text did not fit into multiportion
1981 bRet = sal_True;
1982 }
1980 bRet = sal_True;
1981 }
1983 if( rMulti.IsRuby() )
1984 break;
1982 if( rMulti.IsRuby() )
1983 break;
1985 if( bRet )
1986 {
1984 if( bRet )
1985 {
1987 // our guess for multiportion width was too small,
1988 // we set min to act
1986 // our guess for multiportion width was too small,
1987 // we set min to act
1989 nMinWidth = nActWidth;
1990 nActWidth = ( 3 * nMaxWidth + nMinWidth + 3 ) / 4;
1988 nMinWidth = nActWidth;
1989 nActWidth = ( 3 * nMaxWidth + nMinWidth + 3 ) / 4;
1991 if ( nActWidth == nMaxWidth && rInf.GetLineStart() == rInf.GetIdx() )
1992 // we have too less space, we must allow break cuts
1993 // ( the first multi flag is considered during TxtPortion::_Format() )
1994 bFirstMulti = sal_False;
1995 if( nActWidth <= nMinWidth )
1990 if ( nActWidth == nMaxWidth && rInf.GetLineStart() == rInf.GetIdx() )
1991 // we have too less space, we must allow break cuts
1992 // ( the first multi flag is considered during TxtPortion::_Format() )
1993 bFirstMulti = sal_False;
1994 if( nActWidth <= nMinWidth )
1996 break;
1997 }
1998 else
1995 break;
1996 }
1997 else
1999 {
2000 // For Solaris, this optimisation can causes trouble:
2001 // Setting this to the portion width ( = rMulti.Width() )
2002 // can make GetTextBreak inside SwTxtGuess::Guess return to small
2003 // values. Therefore we add some extra twips.
2004 if( nActWidth > nTmpX + rMulti.Width() + 6 )
2005 nActWidth = nTmpX + rMulti.Width() + 6;
2006 nMaxWidth = nActWidth;
1998 {
1999 // For Solaris, this optimization can causes trouble:
2000 // Setting this to the portion width ( = rMulti.Width() )
2001 // can make GetTextBreak inside SwTxtGuess::Guess return to small
2002 // values. Therefore we add some extra twips.
2003 if( nActWidth > nTmpX + rMulti.Width() + 6 )
2004 nActWidth = nTmpX + rMulti.Width() + 6;
2005 nMaxWidth = nActWidth;
2007 nActWidth = ( 3 * nMaxWidth + nMinWidth + 3 ) / 4;
2008 if( nActWidth >= nMaxWidth )
2009 break;
2006 nActWidth = ( 3 * nMaxWidth + nMinWidth + 3 ) / 4;
2007 if( nActWidth >= nMaxWidth )
2008 break;
2010 // we do not allow break cuts during formatting
2011 bFirstMulti = sal_True;
2009 // we do not allow break cuts during formatting
2010 bFirstMulti = sal_True;
2012 }
2013 delete pNextFirst;
2014 pNextFirst = NULL;
2015 } while ( sal_True );
2016
2011 }
2012 delete pNextFirst;
2013 pNextFirst = NULL;
2014 } while ( sal_True );
2015
2017 pMulti = pOldMulti;
2016 pMulti = pOldMulti;
2018
2019 pCurr = pOldCurr;
2020 nStart = nOldStart;
2017
2018 pCurr = pOldCurr;
2019 nStart = nOldStart;
2021 SetPropFont( 0 );
2020 SetPropFont( 0 );
2022
2023 rMulti.SetLen( rMulti.GetRoot().GetLen() + ( rMulti.GetRoot().GetNext() ?
2024 rMulti.GetRoot().GetNext()->GetLen() : 0 ) );
2025
2026 if( rMulti.IsDouble() )
2027 {
2028 ((SwDoubleLinePortion&)rMulti).CalcBlanks( rInf );
2029 if( ((SwDoubleLinePortion&)rMulti).GetLineDiff() )

--- 8 unchanged lines hidden (view full) ---

2038 {
2039 GetInfo().SetMulti( sal_True );
2040 CalcNewBlock( pLine, NULL, rMulti.Width() );
2041 GetInfo().SetMulti( sal_False );
2042 }
2043 rInf.SetIdx( nStartIdx );
2044 }
2045 if( ((SwDoubleLinePortion&)rMulti).GetBrackets() )
2021
2022 rMulti.SetLen( rMulti.GetRoot().GetLen() + ( rMulti.GetRoot().GetNext() ?
2023 rMulti.GetRoot().GetNext()->GetLen() : 0 ) );
2024
2025 if( rMulti.IsDouble() )
2026 {
2027 ((SwDoubleLinePortion&)rMulti).CalcBlanks( rInf );
2028 if( ((SwDoubleLinePortion&)rMulti).GetLineDiff() )

--- 8 unchanged lines hidden (view full) ---

2037 {
2038 GetInfo().SetMulti( sal_True );
2039 CalcNewBlock( pLine, NULL, rMulti.Width() );
2040 GetInfo().SetMulti( sal_False );
2041 }
2042 rInf.SetIdx( nStartIdx );
2043 }
2044 if( ((SwDoubleLinePortion&)rMulti).GetBrackets() )
2046 {
2047 rMulti.Width( rMulti.Width() +
2048 ((SwDoubleLinePortion&)rMulti).BracketWidth() );
2049 GetInfo().X( nOldX );
2050 }
2045 {
2046 rMulti.Width( rMulti.Width() +
2047 ((SwDoubleLinePortion&)rMulti).BracketWidth() );
2048 GetInfo().X( nOldX );
2049 }
2051 }
2052 else
2053 {
2054 rMulti.ActualizeTabulator();
2055 if( rMulti.IsRuby() )
2056 {
2057 ((SwRubyPortion&)rMulti).Adjust( rInf );
2058 ((SwRubyPortion&)rMulti).CalcRubyOffset();

--- 5 unchanged lines hidden (view full) ---

2064 SwTwips nAsc = rMulti.GetAscent() + ( nH - rMulti.Height() )/2;
2065 if( nAsc > nH )
2066 nAsc = nH;
2067 else if( nAsc < 0 )
2068 nAsc = 0;
2069 rMulti.Width( rMulti.Height() );
2070 rMulti.Height( KSHORT(nH) );
2071 rMulti.SetAscent( KSHORT(nAsc) );
2050 }
2051 else
2052 {
2053 rMulti.ActualizeTabulator();
2054 if( rMulti.IsRuby() )
2055 {
2056 ((SwRubyPortion&)rMulti).Adjust( rInf );
2057 ((SwRubyPortion&)rMulti).CalcRubyOffset();

--- 5 unchanged lines hidden (view full) ---

2063 SwTwips nAsc = rMulti.GetAscent() + ( nH - rMulti.Height() )/2;
2064 if( nAsc > nH )
2065 nAsc = nH;
2066 else if( nAsc < 0 )
2067 nAsc = 0;
2068 rMulti.Width( rMulti.Height() );
2069 rMulti.Height( KSHORT(nH) );
2070 rMulti.SetAscent( KSHORT(nAsc) );
2072 bRet = ( rInf.GetPos().X() + rMulti.Width() > rInf.Width() ) &&
2073 nStartIdx != rInf.GetLineStart();
2071 bRet = ( rInf.GetPos().X() + rMulti.Width() > rInf.Width() ) &&
2072 nStartIdx != rInf.GetLineStart();
2074 }
2073 }
2075 else if ( rMulti.IsBidi() )
2076 {
2077 bRet = rMulti.GetLen() < nMultiLen || pNextFirst;
2078 }
2074 else if ( rMulti.IsBidi() )
2075 {
2076 bRet = rMulti.GetLen() < nMultiLen || pNextFirst;
2077 }
2079
2080 // line break has to be performed!
2078
2079 // line break has to be performed!
2081 if( bRet )
2082 {
2083 ASSERT( !pNextFirst || pNextFirst->InFldGrp(),
2084 "BuildMultiPortion: Surprising restportion, field expected" );
2085 SwMultiPortion *pTmp;
2086 if( rMulti.IsDouble() )
2087 pTmp = new SwDoubleLinePortion( ((SwDoubleLinePortion&)rMulti),
2088 nMultiLen + rInf.GetIdx() );
2089 else if( rMulti.IsRuby() )
2090 {
2091 ASSERT( !pNextSecond || pNextSecond->InFldGrp(),
2092 "BuildMultiPortion: Surprising restportion, field expected" );
2080 if( bRet )
2081 {
2082 ASSERT( !pNextFirst || pNextFirst->InFldGrp(),
2083 "BuildMultiPortion: Surprising restportion, field expected" );
2084 SwMultiPortion *pTmp;
2085 if( rMulti.IsDouble() )
2086 pTmp = new SwDoubleLinePortion( ((SwDoubleLinePortion&)rMulti),
2087 nMultiLen + rInf.GetIdx() );
2088 else if( rMulti.IsRuby() )
2089 {
2090 ASSERT( !pNextSecond || pNextSecond->InFldGrp(),
2091 "BuildMultiPortion: Surprising restportion, field expected" );
2093
2092
2094 if ( rInf.GetIdx() == rInf.GetLineStart() )
2095 {
2096 // the ruby portion has to be split in two portions
2097 pTmp = new SwRubyPortion( ((SwRubyPortion&)rMulti),
2098 nMultiLen + rInf.GetIdx() );
2093 if ( rInf.GetIdx() == rInf.GetLineStart() )
2094 {
2095 // the ruby portion has to be split in two portions
2096 pTmp = new SwRubyPortion( ((SwRubyPortion&)rMulti),
2097 nMultiLen + rInf.GetIdx() );
2099
2098
2100 if( pNextSecond )
2101 {
2102 pTmp->GetRoot().SetNext( new SwLineLayout() );
2103 pTmp->GetRoot().GetNext()->SetPortion( pNextSecond );
2104 }
2105 pTmp->SetFollowFld();
2106 }
2107 else
2108 {
2109 // we try to keep our ruby portion together
2110 lcl_TruncateMultiPortion( rMulti, rInf, nStartIdx );
2111 pTmp = 0;
2112 }
2113 }
2114 else if( rMulti.HasRotation() )
2115 {
2116 // we try to keep our rotated portion together
2117 lcl_TruncateMultiPortion( rMulti, rInf, nStartIdx );
2118 pTmp = new SwRotatedPortion( nMultiLen + rInf.GetIdx(),
2119 rMulti.GetDirection() );
2120 }
2121 // during a recursion of BuildMultiPortions we may not build
2122 // a new SwBidiPortion, this would cause a memory leak
2123 else if( rMulti.IsBidi() && ! pMulti )
2099 if( pNextSecond )
2100 {
2101 pTmp->GetRoot().SetNext( new SwLineLayout() );
2102 pTmp->GetRoot().GetNext()->SetPortion( pNextSecond );
2103 }
2104 pTmp->SetFollowFld();
2105 }
2106 else
2107 {
2108 // we try to keep our ruby portion together
2109 lcl_TruncateMultiPortion( rMulti, rInf, nStartIdx );
2110 pTmp = 0;
2111 }
2112 }
2113 else if( rMulti.HasRotation() )
2124 {
2114 {
2125 if ( ! rMulti.GetLen() )
2126 lcl_TruncateMultiPortion( rMulti, rInf, nStartIdx );
2115 // we try to keep our rotated portion together
2116 lcl_TruncateMultiPortion( rMulti, rInf, nStartIdx );
2117 pTmp = new SwRotatedPortion( nMultiLen + rInf.GetIdx(),
2118 rMulti.GetDirection() );
2119 }
2120 // during a recursion of BuildMultiPortions we may not build
2121 // a new SwBidiPortion, this would cause a memory leak
2122 else if( rMulti.IsBidi() && ! pMulti )
2123 {
2124 if ( ! rMulti.GetLen() )
2125 lcl_TruncateMultiPortion( rMulti, rInf, nStartIdx );
2127
2126
2128 // If there is a HolePortion at the end of the bidi portion,
2129 // it has to be moved behind the bidi portion. Otherwise
2130 // the visual cursor travelling gets into trouble.
2131 SwLineLayout& aRoot = rMulti.GetRoot();
2132 SwLinePortion* pPor = aRoot.GetFirstPortion();
2133 while ( pPor )
2134 {
2135 if ( pPor->GetPortion() && pPor->GetPortion()->IsHolePortion() )
2136 {
2137 SwLinePortion* pHolePor = pPor->GetPortion();
2138 pPor->SetPortion( NULL );
2139 aRoot.SetLen( aRoot.GetLen() - pHolePor->GetLen() );
2140 rMulti.SetLen( rMulti.GetLen() - pHolePor->GetLen() );
2141 rMulti.SetPortion( pHolePor );
2142 break;
2143 }
2144 pPor = pPor->GetPortion();
2145 }
2127 // If there is a HolePortion at the end of the bidi portion,
2128 // it has to be moved behind the bidi portion. Otherwise
2129 // the visual cursor traveling gets into trouble.
2130 SwLineLayout& aRoot = rMulti.GetRoot();
2131 SwLinePortion* pPor = aRoot.GetFirstPortion();
2132 while ( pPor )
2133 {
2134 if ( pPor->GetPortion() && pPor->GetPortion()->IsHolePortion() )
2135 {
2136 SwLinePortion* pHolePor = pPor->GetPortion();
2137 pPor->SetPortion( NULL );
2138 aRoot.SetLen( aRoot.GetLen() - pHolePor->GetLen() );
2139 rMulti.SetLen( rMulti.GetLen() - pHolePor->GetLen() );
2140 rMulti.SetPortion( pHolePor );
2141 break;
2142 }
2143 pPor = pPor->GetPortion();
2144 }
2146
2145
2147 pTmp = new SwBidiPortion( nMultiLen + rInf.GetIdx(),
2148 ((SwBidiPortion&)rMulti).GetLevel() );
2146 pTmp = new SwBidiPortion( nMultiLen + rInf.GetIdx(),
2147 ((SwBidiPortion&)rMulti).GetLevel() );
2149 }
2148 }
2150 else
2151 pTmp = NULL;
2149 else
2150 pTmp = NULL;
2152
2151
2153 if ( ! rMulti.GetLen() && rInf.GetLast() )
2154 {
2155 SeekAndChgBefore( rInf );
2156 rInf.GetLast()->FormatEOL( rInf );
2157 }
2152 if ( ! rMulti.GetLen() && rInf.GetLast() )
2153 {
2154 SeekAndChgBefore( rInf );
2155 rInf.GetLast()->FormatEOL( rInf );
2156 }
2158
2157
2159 if( pNextFirst && pTmp )
2160 {
2161 pTmp->SetFollowFld();
2162 pTmp->GetRoot().SetPortion( pNextFirst );
2163 }
2164 else
2165 // A follow field portion is still waiting. If nobody wants it,
2166 // we delete it.
2167 delete pNextFirst;
2158 if( pNextFirst && pTmp )
2159 {
2160 pTmp->SetFollowFld();
2161 pTmp->GetRoot().SetPortion( pNextFirst );
2162 }
2163 else
2164 // A follow field portion is still waiting. If nobody wants it,
2165 // we delete it.
2166 delete pNextFirst;
2168
2167
2169 rInf.SetRest( pTmp );
2170 }
2168 rInf.SetRest( pTmp );
2169 }
2171
2172 rInf.SetTxt( *pOldTxt );
2170
2171 rInf.SetTxt( *pOldTxt );
2173 rInf.SetPaintOfst( nOldPaintOfst );
2174 rInf.SetStop( aInf.IsStop() );
2175 rInf.SetNumDone( sal_True );
2176 rInf.SetFtnDone( sal_True );
2172 rInf.SetPaintOfst( nOldPaintOfst );
2173 rInf.SetStop( aInf.IsStop() );
2174 rInf.SetNumDone( sal_True );
2175 rInf.SetFtnDone( sal_True );
2177 SeekAndChg( rInf );
2178 delete pFirstRest;
2179 delete pSecondRest;
2180 delete pFontSave;
2181 return bRet;
2182}
2183
2184/*-----------------08.11.00 09:29-------------------
2185 * SwTxtFormatter::MakeRestPortion(..)
2186 * When a fieldportion at the end of line breaks and needs a following
2187 * fieldportion in the next line, then the "restportion" of the formatinfo
2188 * has to be set. Normally this happens during the formatting of the first
2189 * part of the fieldportion.
2190 * But sometimes the formatting starts at the line with the following part,
2176 SeekAndChg( rInf );
2177 delete pFirstRest;
2178 delete pSecondRest;
2179 delete pFontSave;
2180 return bRet;
2181}
2182
2183/*-----------------08.11.00 09:29-------------------
2184 * SwTxtFormatter::MakeRestPortion(..)
2185 * When a fieldportion at the end of line breaks and needs a following
2186 * fieldportion in the next line, then the "restportion" of the formatinfo
2187 * has to be set. Normally this happens during the formatting of the first
2188 * part of the fieldportion.
2189 * But sometimes the formatting starts at the line with the following part,
2191 * exspecally when the following part is on the next page.
2190 * especially when the following part is on the next page.
2192 * In this case the MakeRestPortion-function has to create the following part.
2193 * The first parameter is the line that contains possibly a first part
2194 * of a field. When the function finds such field part, it creates the right
2195 * restportion. This may be a multiportion, e.g. if the field is surrounded by
2196 * a doubleline- or ruby-portion.
2197 * The second parameter is the start index of the line.
2198 * --------------------------------------------------*/
2199
2200SwLinePortion* SwTxtFormatter::MakeRestPortion( const SwLineLayout* pLine,
2191 * In this case the MakeRestPortion-function has to create the following part.
2192 * The first parameter is the line that contains possibly a first part
2193 * of a field. When the function finds such field part, it creates the right
2194 * restportion. This may be a multiportion, e.g. if the field is surrounded by
2195 * a doubleline- or ruby-portion.
2196 * The second parameter is the start index of the line.
2197 * --------------------------------------------------*/
2198
2199SwLinePortion* SwTxtFormatter::MakeRestPortion( const SwLineLayout* pLine,
2201 xub_StrLen nPosition )
2200 xub_StrLen nPosition )
2202{
2201{
2203 if( !nPosition )
2202 if( !nPosition )
2204 return NULL;
2203 return NULL;
2205 xub_StrLen nMultiPos = nPosition - pLine->GetLen();
2204 xub_StrLen nMultiPos = nPosition - pLine->GetLen();
2206 const SwMultiPortion *pTmpMulti = NULL;
2205 const SwMultiPortion *pTmpMulti = NULL;
2207 const SwMultiPortion *pHelpMulti = NULL;
2206 const SwMultiPortion *pHelpMulti = NULL;
2208 const SwLinePortion* pPor = pLine->GetFirstPortion();
2209 SwFldPortion *pFld = NULL;
2210 while( pPor )
2211 {
2212 if( pPor->GetLen() )
2213 {
2207 const SwLinePortion* pPor = pLine->GetFirstPortion();
2208 SwFldPortion *pFld = NULL;
2209 while( pPor )
2210 {
2211 if( pPor->GetLen() )
2212 {
2214 if( !pHelpMulti )
2213 if( !pHelpMulti )
2215 {
2216 nMultiPos = nMultiPos + pPor->GetLen();
2217 pTmpMulti = NULL;
2218 }
2219 }
2220 if( pPor->InFldGrp() )
2221 {
2214 {
2215 nMultiPos = nMultiPos + pPor->GetLen();
2216 pTmpMulti = NULL;
2217 }
2218 }
2219 if( pPor->InFldGrp() )
2220 {
2222 if( !pHelpMulti )
2221 if( !pHelpMulti )
2223 pTmpMulti = NULL;
2224 pFld = (SwFldPortion*)pPor;
2225 }
2226 else if( pPor->IsMultiPortion() )
2227 {
2222 pTmpMulti = NULL;
2223 pFld = (SwFldPortion*)pPor;
2224 }
2225 else if( pPor->IsMultiPortion() )
2226 {
2228 ASSERT( !pHelpMulti || pHelpMulti->IsBidi(),
2229 "Nested multiportions are forbidden." );
2227 ASSERT( !pHelpMulti || pHelpMulti->IsBidi(),
2228 "Nested multiportions are forbidden." );
2230
2231 pFld = NULL;
2232 pTmpMulti = (SwMultiPortion*)pPor;
2233 }
2234 pPor = pPor->GetPortion();
2235 // If the last portion is a multi-portion, we enter it
2236 // and look for a field portion inside.
2237 // If we are already in a multiportion, we could change to the
2238 // next line
2239 if( !pPor && pTmpMulti )
2240 {
2229
2230 pFld = NULL;
2231 pTmpMulti = (SwMultiPortion*)pPor;
2232 }
2233 pPor = pPor->GetPortion();
2234 // If the last portion is a multi-portion, we enter it
2235 // and look for a field portion inside.
2236 // If we are already in a multiportion, we could change to the
2237 // next line
2238 if( !pPor && pTmpMulti )
2239 {
2241 if( pHelpMulti )
2240 if( pHelpMulti )
2242 { // We're already inside the multiportion, let's take the second
2243 // line, if we are in a double line portion
2241 { // We're already inside the multiportion, let's take the second
2242 // line, if we are in a double line portion
2244 if( !pHelpMulti->IsRuby() )
2245 pPor = pHelpMulti->GetRoot().GetNext();
2243 if( !pHelpMulti->IsRuby() )
2244 pPor = pHelpMulti->GetRoot().GetNext();
2246 pTmpMulti = NULL;
2247 }
2248 else
2249 { // Now we enter a multiportion, in a ruby portion we take the
2250 // main line, not the phonetic line, in a doublelineportion we
2251 // starts with the first line.
2245 pTmpMulti = NULL;
2246 }
2247 else
2248 { // Now we enter a multiportion, in a ruby portion we take the
2249 // main line, not the phonetic line, in a doublelineportion we
2250 // starts with the first line.
2252 pHelpMulti = pTmpMulti;
2253 nMultiPos = nMultiPos - pHelpMulti->GetLen();
2254 if( pHelpMulti->IsRuby() && pHelpMulti->OnTop() )
2255 pPor = pHelpMulti->GetRoot().GetNext();
2251 pHelpMulti = pTmpMulti;
2252 nMultiPos = nMultiPos - pHelpMulti->GetLen();
2253 if( pHelpMulti->IsRuby() && pHelpMulti->OnTop() )
2254 pPor = pHelpMulti->GetRoot().GetNext();
2256 else
2255 else
2257 pPor = pHelpMulti->GetRoot().GetFirstPortion();
2256 pPor = pHelpMulti->GetRoot().GetFirstPortion();
2258 }
2259 }
2260 }
2261 if( pFld && !pFld->HasFollow() )
2262 pFld = NULL;
2263
2257 }
2258 }
2259 }
2260 if( pFld && !pFld->HasFollow() )
2261 pFld = NULL;
2262
2264 SwLinePortion *pRest = NULL;
2265 if( pFld )
2266 {
2267 const SwTxtAttr *pHint = GetAttr( nPosition - 1 );
2268 if ( pHint
2269 && ( pHint->Which() == RES_TXTATR_FIELD
2270 || pHint->Which() == RES_TXTATR_ANNOTATION ) )
2271 {
2272 pRest = NewFldPortion( GetInfo(), pHint );
2273 if( pRest->InFldGrp() )
2274 ((SwFldPortion*)pRest)->TakeNextOffset( pFld );
2275 else
2276 {
2277 delete pRest;
2278 pRest = NULL;
2279 }
2280 }
2281 }
2282 if( !pHelpMulti )
2283 return pRest;
2263 SwLinePortion *pRest = NULL;
2264 if( pFld )
2265 {
2266 const SwTxtAttr *pHint = GetAttr( nPosition - 1 );
2267 if ( pHint
2268 && ( pHint->Which() == RES_TXTATR_FIELD
2269 || pHint->Which() == RES_TXTATR_ANNOTATION ) )
2270 {
2271 pRest = NewFldPortion( GetInfo(), pHint );
2272 if( pRest->InFldGrp() )
2273 ((SwFldPortion*)pRest)->TakeNextOffset( pFld );
2274 else
2275 {
2276 delete pRest;
2277 pRest = NULL;
2278 }
2279 }
2280 }
2281 if( !pHelpMulti )
2282 return pRest;
2284
2283
2285 nPosition = nMultiPos + pHelpMulti->GetLen();
2286 SwMultiCreator* pCreate = GetInfo().GetMultiCreator( nMultiPos, 0 );
2284 nPosition = nMultiPos + pHelpMulti->GetLen();
2285 SwMultiCreator* pCreate = GetInfo().GetMultiCreator( nMultiPos, 0 );
2287
2286
2288 if ( !pCreate )
2289 {
2290 ASSERT( !pHelpMulti->GetLen(), "Multiportion without attribut?" );
2291 if ( nMultiPos )
2292 --nMultiPos;
2293 pCreate = GetInfo().GetMultiCreator( --nMultiPos, 0 );
2294 }
2287 if ( !pCreate )
2288 {
2289 ASSERT( !pHelpMulti->GetLen(), "Multiportion without attribut?" );
2290 if ( nMultiPos )
2291 --nMultiPos;
2292 pCreate = GetInfo().GetMultiCreator( --nMultiPos, 0 );
2293 }
2295
2294
2296 if( pRest || nMultiPos > nPosition || ( pHelpMulti->IsRuby() &&
2297 ((SwRubyPortion*)pHelpMulti)->GetRubyOffset() < STRING_LEN ) )
2295 if( pRest || nMultiPos > nPosition || ( pHelpMulti->IsRuby() &&
2296 ((SwRubyPortion*)pHelpMulti)->GetRubyOffset() < STRING_LEN ) )
2298 {
2299 SwMultiPortion* pTmp;
2297 {
2298 SwMultiPortion* pTmp;
2300 if( pHelpMulti->IsDouble() )
2299 if( pHelpMulti->IsDouble() )
2301 pTmp = new SwDoubleLinePortion( *pCreate, nMultiPos );
2300 pTmp = new SwDoubleLinePortion( *pCreate, nMultiPos );
2302 else if( pHelpMulti->IsBidi() )
2303 pTmp = new SwBidiPortion( nMultiPos, pCreate->nLevel );
2304 else if( pHelpMulti->IsRuby() )
2305 {
2306 sal_Bool bRubyTop;
2307 sal_Bool* pRubyPos = 0;
2301 else if( pHelpMulti->IsBidi() )
2302 pTmp = new SwBidiPortion( nMultiPos, pCreate->nLevel );
2303 else if( pHelpMulti->IsRuby() )
2304 {
2305 sal_Bool bRubyTop;
2306 sal_Bool* pRubyPos = 0;
2308
2307
2309 if ( GetInfo().SnapToGrid() )
2310 {
2311 GETGRID( pFrm->FindPageFrm() )
2312 if ( pGrid )
2313 {
2314 bRubyTop = ! pGrid->GetRubyTextBelow();
2315 pRubyPos = &bRubyTop;
2316 }
2317 }
2308 if ( GetInfo().SnapToGrid() )
2309 {
2310 GETGRID( pFrm->FindPageFrm() )
2311 if ( pGrid )
2312 {
2313 bRubyTop = ! pGrid->GetRubyTextBelow();
2314 pRubyPos = &bRubyTop;
2315 }
2316 }
2318
2317
2319 pTmp = new SwRubyPortion( *pCreate, *GetInfo().GetFont(),
2320 *pFrm->GetTxtNode()->getIDocumentSettingAccess(),
2321 nMultiPos, ((SwRubyPortion*)pHelpMulti)->GetRubyOffset(),
2322 pRubyPos );
2323 }
2324 else if( pHelpMulti->HasRotation() )
2325 pTmp = new SwRotatedPortion( nMultiPos, pHelpMulti->GetDirection() );
2318 pTmp = new SwRubyPortion( *pCreate, *GetInfo().GetFont(),
2319 *pFrm->GetTxtNode()->getIDocumentSettingAccess(),
2320 nMultiPos, ((SwRubyPortion*)pHelpMulti)->GetRubyOffset(),
2321 pRubyPos );
2322 }
2323 else if( pHelpMulti->HasRotation() )
2324 pTmp = new SwRotatedPortion( nMultiPos, pHelpMulti->GetDirection() );
2326 else
2327 {
2328 delete pCreate;
2329 return pRest;
2330 }
2331 delete pCreate;
2332 pTmp->SetFollowFld();
2333 if( pRest )

--- 15 unchanged lines hidden (view full) ---

2349
2350/*-----------------23.10.00 10:47-------------------
2351 * SwTxtCursorSave notes the start and current line of a SwTxtCursor,
2352 * sets them to the values for GetCrsrOfst inside a multiportion
2353 * and restores them in the destructor.
2354 * --------------------------------------------------*/
2355
2356SwTxtCursorSave::SwTxtCursorSave( SwTxtCursor* pTxtCursor,
2325 else
2326 {
2327 delete pCreate;
2328 return pRest;
2329 }
2330 delete pCreate;
2331 pTmp->SetFollowFld();
2332 if( pRest )

--- 15 unchanged lines hidden (view full) ---

2348
2349/*-----------------23.10.00 10:47-------------------
2350 * SwTxtCursorSave notes the start and current line of a SwTxtCursor,
2351 * sets them to the values for GetCrsrOfst inside a multiportion
2352 * and restores them in the destructor.
2353 * --------------------------------------------------*/
2354
2355SwTxtCursorSave::SwTxtCursorSave( SwTxtCursor* pTxtCursor,
2357 SwMultiPortion* pMulti,
2358 SwTwips nY,
2359 sal_uInt16& nX,
2360 xub_StrLen nCurrStart,
2361 long nSpaceAdd )
2356 SwMultiPortion* pMulti,
2357 SwTwips nY,
2358 sal_uInt16& nX,
2359 xub_StrLen nCurrStart,
2360 long nSpaceAdd )
2362{
2363 pTxtCrsr = pTxtCursor;
2364 nStart = pTxtCursor->nStart;
2365 pTxtCursor->nStart = nCurrStart;
2366 pCurr = pTxtCursor->pCurr;
2367 pTxtCursor->pCurr = &pMulti->GetRoot();
2361{
2362 pTxtCrsr = pTxtCursor;
2363 nStart = pTxtCursor->nStart;
2364 pTxtCursor->nStart = nCurrStart;
2365 pCurr = pTxtCursor->pCurr;
2366 pTxtCursor->pCurr = &pMulti->GetRoot();
2368 while( pTxtCursor->Y() + pTxtCursor->GetLineHeight() < nY &&
2367 while( pTxtCursor->Y() + pTxtCursor->GetLineHeight() < nY &&
2369 pTxtCursor->Next() )
2370 ; // nothing
2371 nWidth = pTxtCursor->pCurr->Width();
2372 nOldProp = pTxtCursor->GetPropFont();
2373
2368 pTxtCursor->Next() )
2369 ; // nothing
2370 nWidth = pTxtCursor->pCurr->Width();
2371 nOldProp = pTxtCursor->GetPropFont();
2372
2374 if ( pMulti->IsDouble() || pMulti->IsBidi() )
2375 {
2373 if ( pMulti->IsDouble() || pMulti->IsBidi() )
2374 {
2376 bSpaceChg = pMulti->ChgSpaceAdd( pTxtCursor->pCurr, nSpaceAdd );
2377
2375 bSpaceChg = pMulti->ChgSpaceAdd( pTxtCursor->pCurr, nSpaceAdd );
2376
2378 sal_uInt16 nSpaceCnt;
2379 if ( pMulti->IsDouble() )
2380 {
2381 pTxtCursor->SetPropFont( 50 );
2382 nSpaceCnt = ((SwDoubleLinePortion*)pMulti)->GetSpaceCnt();
2383 }
2384 else
2385 {
2386 const xub_StrLen nOldIdx = pTxtCursor->GetInfo().GetIdx();
2387 pTxtCursor->GetInfo().SetIdx ( nCurrStart );
2388 nSpaceCnt = ((SwBidiPortion*)pMulti)->GetSpaceCnt(pTxtCursor->GetInfo());
2389 pTxtCursor->GetInfo().SetIdx ( nOldIdx );
2390 }
2377 sal_uInt16 nSpaceCnt;
2378 if ( pMulti->IsDouble() )
2379 {
2380 pTxtCursor->SetPropFont( 50 );
2381 nSpaceCnt = ((SwDoubleLinePortion*)pMulti)->GetSpaceCnt();
2382 }
2383 else
2384 {
2385 const xub_StrLen nOldIdx = pTxtCursor->GetInfo().GetIdx();
2386 pTxtCursor->GetInfo().SetIdx ( nCurrStart );
2387 nSpaceCnt = ((SwBidiPortion*)pMulti)->GetSpaceCnt(pTxtCursor->GetInfo());
2388 pTxtCursor->GetInfo().SetIdx ( nOldIdx );
2389 }
2391
2392 if( nSpaceAdd > 0 && !pMulti->HasTabulator() )
2390
2391 if( nSpaceAdd > 0 && !pMulti->HasTabulator() )
2393 pTxtCursor->pCurr->Width( static_cast<sal_uInt16>(nWidth + nSpaceAdd * nSpaceCnt / SPACING_PRECISION_FACTOR ) );
2392 pTxtCursor->pCurr->Width( static_cast<sal_uInt16>(nWidth + nSpaceAdd * nSpaceCnt / SPACING_PRECISION_FACTOR ) );
2394
2393
2395 // For a BidiPortion we have to calculate the offset from the
2396 // end of the portion
2397 if ( nX && pMulti->IsBidi() )
2398 nX = pTxtCursor->pCurr->Width() - nX;
2399 }
2400 else
2394 // For a BidiPortion we have to calculate the offset from the
2395 // end of the portion
2396 if ( nX && pMulti->IsBidi() )
2397 nX = pTxtCursor->pCurr->Width() - nX;
2398 }
2399 else
2401 bSpaceChg = sal_False;
2402}
2403
2404SwTxtCursorSave::~SwTxtCursorSave()
2405{
2406 if( bSpaceChg )
2407 SwDoubleLinePortion::ResetSpaceAdd( pTxtCrsr->pCurr );
2408 pTxtCrsr->pCurr->Width( KSHORT(nWidth) );
2409 pTxtCrsr->pCurr = pCurr;
2410 pTxtCrsr->nStart = nStart;
2411 pTxtCrsr->SetPropFont( nOldProp );
2412}
2413
2400 bSpaceChg = sal_False;
2401}
2402
2403SwTxtCursorSave::~SwTxtCursorSave()
2404{
2405 if( bSpaceChg )
2406 SwDoubleLinePortion::ResetSpaceAdd( pTxtCrsr->pCurr );
2407 pTxtCrsr->pCurr->Width( KSHORT(nWidth) );
2408 pTxtCrsr->pCurr = pCurr;
2409 pTxtCrsr->nStart = nStart;
2410 pTxtCrsr->SetPropFont( nOldProp );
2411}
2412
2413/* vim: set noet sw=4 ts=4: */