Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "swrect.hxx"
30 : : #include "paratr.hxx" // pTabStop, ADJ*
31 : : #include "viewopt.hxx" // SwViewOptions
32 : : #include <SwPortionHandler.hxx>
33 : :
34 : : #include "porglue.hxx"
35 : : #include "inftxt.hxx"
36 : : #include "porlay.hxx" // SwParaPortion, SetFull
37 : : #include "porfly.hxx" // SwParaPortion, SetFull
38 : :
39 : : /*************************************************************************
40 : : * class SwGluePortion
41 : : *************************************************************************/
42 : :
43 : 2854 : SwGluePortion::SwGluePortion( const KSHORT nInitFixWidth )
44 : 2854 : : nFixWidth( nInitFixWidth )
45 : : {
46 : 2854 : PrtWidth( nFixWidth );
47 : 2854 : SetWhichPor( POR_GLUE );
48 : 2854 : }
49 : :
50 : : /*************************************************************************
51 : : * virtual SwGluePortion::GetCrsrOfst()
52 : : *************************************************************************/
53 : :
54 : 0 : xub_StrLen SwGluePortion::GetCrsrOfst( const KSHORT nOfst ) const
55 : : {
56 [ # # ][ # # ]: 0 : if( !GetLen() || nOfst > GetLen() || !Width() )
[ # # ][ # # ]
57 : 0 : return SwLinePortion::GetCrsrOfst( nOfst );
58 : : else
59 : 0 : return nOfst / (Width() / GetLen());
60 : : }
61 : :
62 : : /*************************************************************************
63 : : * virtual SwGluePortion::GetTxtSize()
64 : : *************************************************************************/
65 : :
66 : 0 : SwPosSize SwGluePortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
67 : : {
68 [ # # ][ # # ]: 0 : if( 1 >= GetLen() || rInf.GetLen() > GetLen() || !Width() || !GetLen() )
[ # # ][ # # ]
[ # # ]
69 : 0 : return SwPosSize(*this);
70 : : else
71 : 0 : return SwPosSize( (Width() / GetLen()) * rInf.GetLen(), Height() );
72 : : }
73 : :
74 : : /*************************************************************************
75 : : * virtual SwGluePortion::GetExpTxt()
76 : : *************************************************************************/
77 : :
78 : 0 : sal_Bool SwGluePortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
79 : : {
80 [ # # ][ # # : 0 : if( GetLen() && rInf.OnWin() &&
# # # # ]
[ # # ]
81 : 0 : rInf.GetOpt().IsBlank() && rInf.IsNoSymbol() )
82 : : {
83 : 0 : rTxt.Fill( GetLen(), CH_BULLET );
84 : 0 : return sal_True;
85 : : }
86 : 0 : return sal_False;
87 : : }
88 : :
89 : : /*************************************************************************
90 : : * virtual SwGluePortion::Paint()
91 : : *************************************************************************/
92 : :
93 : 2205 : void SwGluePortion::Paint( const SwTxtPaintInfo &rInf ) const
94 : : {
95 [ + - ]: 2205 : if( !GetLen() )
96 : 2205 : return;
97 : :
98 [ # # ]: 0 : if( rInf.GetFont()->IsPaintBlank() )
99 : : {
100 [ # # ]: 0 : XubString aTxt;
101 [ # # ]: 0 : aTxt.Fill( GetFixWidth() / GetLen(), ' ' );
102 [ # # ]: 0 : SwTxtPaintInfo aInf( rInf, aTxt );
103 [ # # ][ # # ]: 0 : aInf.DrawText( *this, aTxt.Len(), sal_True );
[ # # ]
104 : : }
105 : :
106 [ # # ][ # # ]: 0 : if( rInf.OnWin() && rInf.GetOpt().IsBlank() && rInf.IsNoSymbol() )
[ # # ][ # # ]
107 : : {
108 : : #if OSL_DEBUG_LEVEL > 0
109 : : const xub_Unicode cChar = rInf.GetChar( rInf.GetIdx() );
110 : : OSL_ENSURE( CH_BLANK == cChar || CH_BULLET == cChar,
111 : : "SwGluePortion::Paint: blank expected" );
112 : : #endif
113 [ # # ]: 0 : if( 1 == GetLen() )
114 : : {
115 : 0 : rtl::OUString aBullet( CH_BULLET );
116 [ # # ][ # # ]: 0 : SwPosSize aBulletSize( rInf.GetTxtSize( aBullet ) );
[ # # ]
117 : 0 : Point aPos( rInf.GetPos() );
118 : 0 : aPos.X() += (Width()/2) - (aBulletSize.Width()/2);
119 [ # # ][ # # ]: 0 : SwTxtPaintInfo aInf( rInf, aBullet );
[ # # ]
120 : 0 : aInf.SetPos( aPos );
121 [ # # ]: 0 : SwTxtPortion aBulletPor;
122 : 0 : aBulletPor.Width( aBulletSize.Width() );
123 : 0 : aBulletPor.Height( aBulletSize.Height() );
124 : 0 : aBulletPor.SetAscent( GetAscent() );
125 [ # # ][ # # ]: 0 : aInf.DrawText( aBulletPor, aBullet.getLength(), sal_True );
[ # # ]
126 : : }
127 : : else
128 : : {
129 [ # # ]: 0 : SwTxtSlot aSlot( &rInf, this, true, false );
130 [ # # ][ # # ]: 0 : rInf.DrawText( *this, rInf.GetLen(), sal_True );
131 : : }
132 : : }
133 : : }
134 : :
135 : : /*************************************************************************
136 : : * SwGluePortion::MoveGlue()
137 : : *************************************************************************/
138 : :
139 : 885 : void SwGluePortion::MoveGlue( SwGluePortion *pTarget, const short nPrtGlue )
140 : : {
141 : 885 : short nPrt = Min( nPrtGlue, GetPrtGlue() );
142 [ + - ]: 885 : if( 0 < nPrt )
143 : : {
144 : 885 : pTarget->AddPrtWidth( nPrt );
145 : 885 : SubPrtWidth( nPrt );
146 : : }
147 : 885 : }
148 : :
149 : : /*************************************************************************
150 : : * void SwGluePortion::Join()
151 : : *************************************************************************/
152 : :
153 : 3 : void SwGluePortion::Join( SwGluePortion *pVictim )
154 : : {
155 : : // Die GluePortion wird ausgesogen und weggespuelt ...
156 : 3 : AddPrtWidth( pVictim->PrtWidth() );
157 : 3 : SetLen( pVictim->GetLen() + GetLen() );
158 [ + - ]: 3 : if( Height() < pVictim->Height() )
159 : 3 : Height( pVictim->Height() );
160 : :
161 : 3 : AdjFixWidth();
162 : 3 : Cut( pVictim );
163 [ + - ]: 3 : delete pVictim;
164 : 3 : }
165 : :
166 : : /*************************************************************************
167 : : * class SwFixPortion
168 : : *************************************************************************/
169 : :
170 : : // Wir erwarten ein framelokales SwRect !
171 : 729 : SwFixPortion::SwFixPortion( const SwRect &rRect )
172 : 729 : :SwGluePortion( KSHORT(rRect.Width()) ), nFix( KSHORT(rRect.Left()) )
173 : : {
174 : 729 : Height( KSHORT(rRect.Height()) );
175 : 729 : SetWhichPor( POR_FIX );
176 : 729 : }
177 : :
178 : 207 : SwFixPortion::SwFixPortion(const KSHORT nFixedWidth, const KSHORT nFixedPos)
179 : 207 : : SwGluePortion(nFixedWidth), nFix(nFixedPos)
180 : : {
181 : 207 : SetWhichPor( POR_FIX );
182 : 207 : }
183 : :
184 : : /*************************************************************************
185 : : * class SwMarginPortion
186 : : *************************************************************************/
187 : :
188 : 1918 : SwMarginPortion::SwMarginPortion( const KSHORT nFixedWidth )
189 : 1918 : :SwGluePortion( nFixedWidth )
190 : : {
191 : 1918 : SetWhichPor( POR_MARGIN );
192 : 1918 : }
193 : :
194 : : /*************************************************************************
195 : : * SwMarginPortion::AdjustRight()
196 : : *
197 : : * In der umschliessenden Schleife werden alle Portions durchsucht,
198 : : * dabei werden erst die am Ende liegenden GluePortions verarbeitet.
199 : : * Das Ende wird nach jeder Schleife nach vorne verlegt, bis keine
200 : : * GluePortions mehr vorhanden sind.
201 : : * Es werden immer GluePortion-Paare betrachtet (pLeft und pRight),
202 : : * wobei Textportions zwischen pLeft und pRight hinter pRight verschoben
203 : : * werden, wenn pRight genuegend Glue besitzt. Bei jeder Verschiebung
204 : : * wandert ein Teil des Glues von pRight nach pLeft.
205 : : * Im naechsten Schleifendurchlauf ist pLeft das pRight und das Spiel
206 : : * beginnt von vorne.
207 : : *************************************************************************/
208 : :
209 : 0 : void SwMarginPortion::AdjustRight( const SwLineLayout *pCurr )
210 : : {
211 : 0 : SwGluePortion *pRight = 0;
212 : 0 : sal_Bool bNoMove = 0 != pCurr->GetpKanaComp();
213 [ # # ]: 0 : while( pRight != this )
214 : : {
215 : :
216 : : // 1) Wir suchen den linken Glue
217 : 0 : SwLinePortion *pPos = (SwLinePortion*)this;
218 : 0 : SwGluePortion *pLeft = 0;
219 [ # # ]: 0 : while( pPos )
220 : : {
221 [ # # ]: 0 : if( pPos->InFixMargGrp() )
222 : 0 : pLeft = (SwGluePortion*)pPos;
223 : 0 : pPos = pPos->GetPortion();
224 [ # # ]: 0 : if( pPos == pRight)
225 : 0 : pPos = 0;
226 : : }
227 : :
228 : : // Zwei nebeneinander liegende FlyPortions verschmelzen
229 [ # # ][ # # ]: 0 : if( pRight && pLeft->GetPortion() == pRight )
[ # # ]
230 : : {
231 : 0 : pRight->MoveAllGlue( pLeft );
232 : 0 : pRight = 0;
233 : : }
234 : 0 : KSHORT nRightGlue = pRight && 0 < pRight->GetPrtGlue()
235 [ # # # # ]: 0 : ? KSHORT(pRight->GetPrtGlue()) : 0;
236 : : // 2) linken und rechten Glue ausgleichen
237 : : // Bei Tabs haengen wir nix um ...
238 [ # # ][ # # ]: 0 : if( pLeft && nRightGlue && !pRight->InTabGrp() )
[ # # ][ # # ]
239 : : {
240 : : // pPrev ist die Portion, die unmittelbar vor pRight liegt.
241 : 0 : SwLinePortion *pPrev = pRight->FindPrevPortion( pLeft );
242 : :
243 [ # # ][ # # ]: 0 : if ( pRight->IsFlyPortion() && pRight->GetLen() )
[ # # ]
244 : : {
245 : 0 : SwFlyPortion *pFly = (SwFlyPortion *)pRight;
246 [ # # ]: 0 : if ( pFly->GetBlankWidth() < nRightGlue )
247 : : {
248 : : // Hier entsteht eine neue TxtPortion, die dass zuvor
249 : : // vom Fly verschluckte Blank reaktiviert.
250 : 0 : nRightGlue = nRightGlue - pFly->GetBlankWidth();
251 : 0 : pFly->SubPrtWidth( pFly->GetBlankWidth() );
252 : 0 : pFly->SetLen( 0 );
253 [ # # ]: 0 : SwTxtPortion *pNewPor = new SwTxtPortion;
254 : 0 : pNewPor->SetLen( 1 );
255 : 0 : pNewPor->Height( pFly->Height() );
256 : 0 : pNewPor->Width( pFly->GetBlankWidth() );
257 : 0 : pFly->Insert( pNewPor );
258 : : }
259 : : else
260 : 0 : pPrev = pLeft;
261 : : }
262 [ # # ]: 0 : while( pPrev != pLeft )
263 : : {
264 [ # # ][ # # : 0 : if( bNoMove || pPrev->PrtWidth() >= nRightGlue ||
# # # # ]
[ # # ]
265 : 0 : pPrev->InHyphGrp() || pPrev->IsKernPortion() )
266 : : {
267 : : // Die Portion, die vor pRight liegt kann nicht
268 : : // verschoben werden, weil kein Glue mehr vorhanden ist.
269 : : // Wir fuehren die Abbruchbedingung herbei:
270 : 0 : pPrev = pLeft;
271 : : }
272 : : else
273 : : {
274 : 0 : nRightGlue = nRightGlue - pPrev->PrtWidth();
275 : : // pPrev wird hinter pRight verschoben.
276 : : // Dazu wird der Gluewert zwischen pRight und pLeft
277 : : // ausgeglichen.
278 : 0 : pRight->MoveGlue( pLeft, short( pPrev->PrtWidth() ) );
279 : : // Jetzt wird die Verkettung gerichtet.
280 : 0 : SwLinePortion *pPrevPrev = pPrev->FindPrevPortion( pLeft );
281 : 0 : pPrevPrev->SetPortion( pRight );
282 : 0 : pPrev->SetPortion( pRight->GetPortion() );
283 : 0 : pRight->SetPortion( pPrev );
284 [ # # # # ]: 0 : if ( pPrev->GetPortion() && pPrev->InTxtGrp()
[ # # ][ # # ]
285 : 0 : && pPrev->GetPortion()->IsHolePortion() )
286 : : {
287 : : SwHolePortion *pHolePor =
288 : 0 : (SwHolePortion*)pPrev->GetPortion();
289 [ # # ]: 0 : if ( !pHolePor->GetPortion() ||
[ # # # # ]
290 : 0 : !pHolePor->GetPortion()->InFixMargGrp() )
291 : : {
292 : 0 : pPrev->AddPrtWidth( pHolePor->GetBlankWidth() );
293 : 0 : pPrev->SetLen( pPrev->GetLen() + 1 );
294 : 0 : pPrev->SetPortion( pHolePor->GetPortion() );
295 [ # # ]: 0 : delete pHolePor;
296 : : }
297 : : }
298 : 0 : pPrev = pPrevPrev;
299 : : }
300 : : }
301 : : }
302 : : // Wenn es keinen linken Glue mehr gibt, wird die Abbruchbedingung
303 : : // herbeigefuehrt.
304 [ # # ]: 0 : pRight = pLeft ? pLeft : (SwGluePortion*)this;
305 : : }
306 : 0 : }
307 : :
308 : :
309 : :
310 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|