1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: outlinfo.cxx,v $
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"
44 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
46 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
47 #include <com/sun/star/i18n/ScriptType.hdl>
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>
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
;
65 OutlinerInfo::OutlinerInfo() :
72 // -----------------------------------------------------------------------------
74 OutlinerInfo::~OutlinerInfo()
79 // -----------------------------------------------------------------------------
81 void OutlinerInfo::SetTextObj( SdDrawDocument
* pDoc
, SdrRectObj
* pObj
, OutputDevice
* pOut
)
85 SdrOutliner
& rOutliner
= pDoc
->GetDrawOutliner();
88 rOutliner
.SetText( *pObj
->GetOutlinerParaObject() );
90 aObjBound
= pObj
->GetCurrentBoundRect();
91 nParaCount
= rOutliner
.GetParagraphCount();
96 mbVertical
= rOutliner
.IsVertical();
97 pObj
->TakeTextRect( rOutliner
, aParaBound
, TRUE
);
100 aTextOffset
= aParaBound
.TopRight();
102 aTextOffset
= aParaBound
.TopLeft();
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
++ )
121 pParagraphs
[i
].aRect
.Right() = pParagraphs
[ i
- 1 ].aRect
.Left();
123 pParagraphs
[i
].aRect
.Left() = pParagraphs
[i
].aRect
.Right() - rOutliner
.GetTextHeight( i
);
128 pParagraphs
[ 0 ].aRect
.Top() = aParaBound
.Top();
130 for( USHORT i
= 0; i
< nParaCount
; i
++ )
133 pParagraphs
[ i
].aRect
.Top() = pParagraphs
[ i
- 1 ].aRect
.Bottom();
135 pParagraphs
[ i
].aRect
.Bottom() = pParagraphs
[ i
].aRect
.Top() + rOutliner
.GetTextHeight( i
);
142 aParaBound
= Rectangle();
143 aTextOffset
= Point();
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
;
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
)
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());
201 Any x
= xInterface
->queryInterface(::getCppuType((const Reference
< XBreakIterator
>*)0));
207 bUseBreakIterator
= sal_True
;
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
;
226 pParagraphs
[nCurPara
].aRect
.Union(aCurRect
);
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
;
245 pParagraphs
[nCurPara
].aRect
.Union(aCurRect
);
249 if(pInfo
->mnTextLen
&& (0xFFFF != pInfo
->mnIndex
))
251 pParagraphs
[nCurPara
].nCharCount
+= pInfo
->mnTextLen
;
252 sal_uInt16
nInsertIndex(0xffff);
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
)
265 nNextGlyphLen
= (xub_StrLen
)xBreak
->nextCharacters( pInfo
->mrText
, pInfo
->mnTextStart
, aFontLocale
,
266 CharacterIteratorMode::SKIPCELL
, 1, nDone
) - (pInfo
->mnTextStart
);
271 Size
aGlyphSize(pInfo
->mrFont
.GetPhysTxtSize(mpOut
,
272 pInfo
->mrText
, nCharIndex
+ pInfo
->mnTextStart
, nNextGlyphLen
));
276 ::std::swap(aGlyphSize
.Width(), aGlyphSize
.Height());
279 const Rectangle
aRect(aStart
, aGlyphSize
);
281 aCharacterList
.Insert(new OutlinerCharacter(
284 pInfo
->mrFont
.GetColor()),
288 if( pInfo
->mpDXArray
)
289 dx
= (pInfo
->mpDXArray
)[nCharIndex
];
292 aStart
.Y() = pInfo
->mrStartPos
.Y() + aTextOffset
.Y() + dx
;
294 aStart
.X() = pInfo
->mrStartPos
.X() + aTextOffset
.X() + dx
;
297 nCharIndex
= nCharIndex
+ nNextGlyphLen
;