merge the formfield patch from ooo-build
[ooovba.git] / sd / source / ui / func / outlinfo.cxx
blob43322a1c0a64266ff20cf3361c91ba09b5601e9d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: outlinfo.cxx,v $
10 * $Revision: 1.16 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include <vcl/metric.hxx>
35 #include <svx/outliner.hxx>
36 #include <svx/svdorect.hxx>
37 #include <svx/svdoutl.hxx>
38 #include <svx/svxfont.hxx>
39 #include "drawdoc.hxx"
40 #include "outlinfo.hxx"
41 #include <algorithm>
43 // #101500#
44 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
46 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
47 #include <com/sun/star/i18n/ScriptType.hdl>
48 #endif
49 #include <com/sun/star/i18n/XBreakIterator.hpp>
50 #include <comphelper/processfactory.hxx>
52 #ifndef _COM_SUN_STAR_I18N_CHARACTERITERATORMODE_HDL_
53 #include <com/sun/star/i18n/CharacterIteratorMode.hdl>
54 #endif
55 #include <svx/unolingu.hxx>
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::lang;
59 using namespace ::com::sun::star::i18n;
61 // ----------------
62 // - OutlinerInfo -
63 // ----------------
65 OutlinerInfo::OutlinerInfo() :
66 pParagraphs ( NULL ),
67 nParaCount ( 0UL ),
68 nExtraData ( 0L )
72 // -----------------------------------------------------------------------------
74 OutlinerInfo::~OutlinerInfo()
76 Clear();
79 // -----------------------------------------------------------------------------
81 void OutlinerInfo::SetTextObj( SdDrawDocument* pDoc, SdrRectObj* pObj, OutputDevice* pOut )
83 Clear();
85 SdrOutliner& rOutliner = pDoc->GetDrawOutliner();
87 mpOut = pOut;
88 rOutliner.SetText( *pObj->GetOutlinerParaObject() );
90 aObjBound = pObj->GetCurrentBoundRect();
91 nParaCount = rOutliner.GetParagraphCount();
92 nExtraData = 0L;
94 if( nParaCount )
96 mbVertical = rOutliner.IsVertical();
97 pObj->TakeTextRect( rOutliner, aParaBound, TRUE );
99 if( IsVertical() )
100 aTextOffset = aParaBound.TopRight();
101 else
102 aTextOffset = aParaBound.TopLeft();
104 nCurPara = 0;
105 bInit = TRUE;
107 rOutliner.SetDrawPortionHdl( LINK( this, OutlinerInfo, DrawPortionHdl ) );
108 pParagraphs = new OutlinerParagraph[ nParaCount ];
109 rOutliner.StripPortions();
110 rOutliner.SetDrawPortionHdl( Link() );
112 if( 1 == nParaCount )
113 pParagraphs[ 0 ].aRect = aParaBound;
114 else if( IsVertical() )
116 pParagraphs[ 0 ].aRect.Right() = aParaBound.Right();
118 for( USHORT i = 0; i < nParaCount; i++ )
120 if( i > 0 )
121 pParagraphs[i].aRect.Right() = pParagraphs[ i - 1 ].aRect.Left();
123 pParagraphs[i].aRect.Left() = pParagraphs[i].aRect.Right() - rOutliner.GetTextHeight( i );
126 else
128 pParagraphs[ 0 ].aRect.Top() = aParaBound.Top();
130 for( USHORT i = 0; i < nParaCount; i++ )
132 if( i > 0 )
133 pParagraphs[ i ].aRect.Top() = pParagraphs[ i - 1 ].aRect.Bottom();
135 pParagraphs[ i ].aRect.Bottom() = pParagraphs[ i ].aRect.Top() + rOutliner.GetTextHeight( i );
139 else
141 pParagraphs = NULL;
142 aParaBound = Rectangle();
143 aTextOffset = Point();
146 nCurPara = 0;
147 bInit = FALSE;
150 // -----------------------------------------------------------------------------
152 void OutlinerInfo::Clear()
154 for( void* pChar = aCharacterList.First(); pChar; pChar = aCharacterList.Next() )
155 delete (OutlinerCharacter*) pChar;
156 aCharacterList.Clear();
158 delete[] pParagraphs;
159 pParagraphs = NULL;
161 nCurPara = nParaCount = 0UL;
162 aObjBound = aParaBound = Rectangle();
163 aTextOffset = Point();
166 // -----------------------------------------------------------------------------
168 const Rectangle& OutlinerInfo::GetParaRect( const ULONG nPara ) const
170 DBG_ASSERT( nPara < nParaCount, "Para out of range!" );
171 return pParagraphs[ nPara ].aRect;
174 // -----------------------------------------------------------------------------
176 BOOL OutlinerInfo::GetParaCharCount( const ULONG nPara ) const
178 DBG_ASSERT( nPara < nParaCount, "Para out of range!" );
179 return (0 != pParagraphs[ nPara ].nCharCount);
182 // -----------------------------------------------------------------------------
184 IMPL_LINK(OutlinerInfo, DrawPortionHdl, DrawPortionInfo*, pInfo)
186 // #101500#
187 Point aStart;
188 sal_Bool bIsVertical(IsVertical());
189 mpOut->SetFont((const Font&)pInfo->mrFont);
190 FontMetric aFontMetric(mpOut->GetFontMetric());
191 sal_Bool bUseBreakIterator(sal_False);
193 // initialize BreakIterator
194 Reference < com::sun::star::i18n::XBreakIterator > xBreak;
195 Reference < XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
196 Reference < XInterface > xInterface = xMSF->createInstance(::rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator"));
197 ::com::sun::star::lang::Locale aFontLocale = SvxCreateLocale(pInfo->mrFont.GetLanguage());
199 if(xInterface.is())
201 Any x = xInterface->queryInterface(::getCppuType((const Reference< XBreakIterator >*)0));
202 x >>= xBreak;
205 if(xBreak.is())
207 bUseBreakIterator = sal_True;
210 if(bIsVertical)
212 aStart.X() = pInfo->mrStartPos.X() + aTextOffset.X() - aFontMetric.GetDescent();
213 aStart.Y() = pInfo->mrStartPos.Y() + aTextOffset.Y();
215 const Point aTopLeft(aStart.X(), aParaBound.Top());
216 const Point aBottomRight(aStart.X() + aFontMetric.GetLineHeight(), aParaBound.Bottom());
217 const Rectangle aCurRect(aTopLeft, aBottomRight);
219 if(pInfo->mnPara != nCurPara)
221 nCurPara = pInfo->mnPara;
222 pParagraphs[nCurPara].aRect = aCurRect;
224 else
226 pParagraphs[nCurPara].aRect.Union(aCurRect);
229 else
231 aStart.X() = pInfo->mrStartPos.X() + aTextOffset.X();
232 aStart.Y() = pInfo->mrStartPos.Y() + aTextOffset.Y() - aFontMetric.GetAscent();
234 const Point aTopLeft(aParaBound.Left(), aStart.Y());
235 const Point aBottomRight(aParaBound.Right(), aStart.Y() + aFontMetric.GetLineHeight());
236 const Rectangle aCurRect(aTopLeft, aBottomRight);
238 if(pInfo->mnPara != nCurPara)
240 nCurPara = pInfo->mnPara;
241 pParagraphs[nCurPara].aRect = aCurRect;
243 else
245 pParagraphs[nCurPara].aRect.Union(aCurRect);
249 if(pInfo->mnTextLen && (0xFFFF != pInfo->mnIndex))
251 pParagraphs[nCurPara].nCharCount += pInfo->mnTextLen;
252 sal_uInt16 nInsertIndex(0xffff);
254 if(pInfo->IsRTL())
255 nInsertIndex = (sal_uInt16)aCharacterList.Count();
257 for(sal_uInt16 nCharIndex(0); nCharIndex < pInfo->mnTextLen; )
259 xub_StrLen nNextGlyphLen(1);
260 sal_Bool bIsSingleSpace(sal_False);
262 if(bUseBreakIterator)
264 sal_Int32 nDone(0L);
265 nNextGlyphLen = (xub_StrLen)xBreak->nextCharacters( pInfo->mrText, pInfo->mnTextStart, aFontLocale,
266 CharacterIteratorMode::SKIPCELL, 1, nDone) - (pInfo->mnTextStart);
269 if(!bIsSingleSpace)
271 Size aGlyphSize(pInfo->mrFont.GetPhysTxtSize(mpOut,
272 pInfo->mrText, nCharIndex + pInfo->mnTextStart, nNextGlyphLen));
274 if(bIsVertical)
276 ::std::swap(aGlyphSize.Width(), aGlyphSize.Height());
279 const Rectangle aRect(aStart, aGlyphSize);
281 aCharacterList.Insert(new OutlinerCharacter(
282 aRect,
283 pInfo->mnPara,
284 pInfo->mrFont.GetColor()),
285 nInsertIndex);
287 long dx = 0;
288 if( pInfo->mpDXArray )
289 dx = (pInfo->mpDXArray)[nCharIndex];
291 if(bIsVertical)
292 aStart.Y() = pInfo->mrStartPos.Y() + aTextOffset.Y() + dx;
293 else
294 aStart.X() = pInfo->mrStartPos.X() + aTextOffset.X() + dx;
297 nCharIndex = nCharIndex + nNextGlyphLen;
301 return 0L;
304 // eof