xref: /aoo41x/main/sc/source/ui/view/output2.cxx (revision b3f79822)
1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b3f79822SAndrew Rist  * distributed with this work for additional information
6*b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b3f79822SAndrew Rist  *
11*b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist  *
13*b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b3f79822SAndrew Rist  * specific language governing permissions and limitations
18*b3f79822SAndrew Rist  * under the License.
19*b3f79822SAndrew Rist  *
20*b3f79822SAndrew Rist  *************************************************************/
21*b3f79822SAndrew Rist 
22*b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir 
29cdf0e10cSrcweir 
30cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "scitems.hxx"
33cdf0e10cSrcweir #include <editeng/eeitem.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <editeng/adjitem.hxx>
37cdf0e10cSrcweir #include <svx/algitem.hxx>
38cdf0e10cSrcweir #include <editeng/brshitem.hxx>
39cdf0e10cSrcweir #include <svtools/colorcfg.hxx>
40cdf0e10cSrcweir #include <editeng/colritem.hxx>
41cdf0e10cSrcweir #include <editeng/editobj.hxx>
42cdf0e10cSrcweir #include <editeng/editstat.hxx>
43cdf0e10cSrcweir #include <editeng/fhgtitem.hxx>
44cdf0e10cSrcweir #include <editeng/forbiddencharacterstable.hxx>
45cdf0e10cSrcweir #include <editeng/frmdiritem.hxx>
46cdf0e10cSrcweir #include <editeng/langitem.hxx>
47cdf0e10cSrcweir #include <svx/rotmodit.hxx>
48cdf0e10cSrcweir #include <editeng/scripttypeitem.hxx>
49cdf0e10cSrcweir #include <editeng/udlnitem.hxx>
50cdf0e10cSrcweir #include <editeng/unolingu.hxx>
51cdf0e10cSrcweir #include <svl/zforlist.hxx>
52cdf0e10cSrcweir #include <svl/zformat.hxx>
53cdf0e10cSrcweir #include <vcl/svapp.hxx>
54cdf0e10cSrcweir #include <vcl/metric.hxx>
55cdf0e10cSrcweir #include <vcl/outdev.hxx>
56cdf0e10cSrcweir #include <vcl/pdfextoutdevdata.hxx>
57cdf0e10cSrcweir 
58cdf0e10cSrcweir #ifndef _SVSTDARR_USHORTS
59cdf0e10cSrcweir #define _SVSTDARR_USHORTS
60cdf0e10cSrcweir #include <svl/svstdarr.hxx>
61cdf0e10cSrcweir #endif
62cdf0e10cSrcweir 
63cdf0e10cSrcweir #include "output.hxx"
64cdf0e10cSrcweir #include "document.hxx"
65cdf0e10cSrcweir #include "cell.hxx"
66cdf0e10cSrcweir #include "attrib.hxx"
67cdf0e10cSrcweir #include "patattr.hxx"
68cdf0e10cSrcweir #include "cellform.hxx"
69cdf0e10cSrcweir #include "editutil.hxx"
70cdf0e10cSrcweir #include "progress.hxx"
71cdf0e10cSrcweir #include "scmod.hxx"
72cdf0e10cSrcweir #include "fillinfo.hxx"
73cdf0e10cSrcweir 
74cdf0e10cSrcweir #include <math.h>
75cdf0e10cSrcweir 
76cdf0e10cSrcweir //!	Autofilter-Breite mit column.cxx zusammenfassen
77cdf0e10cSrcweir #define DROPDOWN_BITMAP_SIZE        18
78cdf0e10cSrcweir 
79cdf0e10cSrcweir #define DRAWTEXT_MAX	32767
80cdf0e10cSrcweir 
81cdf0e10cSrcweir const sal_uInt16 SC_SHRINKAGAIN_MAX = 7;
82cdf0e10cSrcweir 
83cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
84cdf0e10cSrcweir 
85cdf0e10cSrcweir 
86cdf0e10cSrcweir // -----------------------------------------------------------------------
87cdf0e10cSrcweir 
88cdf0e10cSrcweir class ScDrawStringsVars
89cdf0e10cSrcweir {
90cdf0e10cSrcweir 	ScOutputData*		pOutput;				// Verbindung
91cdf0e10cSrcweir 
92cdf0e10cSrcweir 	const ScPatternAttr* pPattern;				// Attribute
93cdf0e10cSrcweir 	const SfxItemSet*	pCondSet;				// aus bedingter Formatierung
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 	Font				aFont;					// aus Attributen erzeugt
96cdf0e10cSrcweir 	FontMetric			aMetric;
97cdf0e10cSrcweir 	long				nAscentPixel;			// always pixels
98cdf0e10cSrcweir 	SvxCellOrientation	eAttrOrient;
99cdf0e10cSrcweir 	SvxCellHorJustify	eAttrHorJust;
100cdf0e10cSrcweir 	SvxCellVerJustify	eAttrVerJust;
101cdf0e10cSrcweir 	const SvxMarginItem* pMargin;
102cdf0e10cSrcweir 	sal_uInt16				nIndent;
103cdf0e10cSrcweir 	sal_Bool				bRotated;
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 	String				aString;				// Inhalte
106cdf0e10cSrcweir 	Size				aTextSize;
107cdf0e10cSrcweir 	long				nOriginalWidth;
108cdf0e10cSrcweir     long                nMaxDigitWidth;
109cdf0e10cSrcweir     long                nSignWidth;
110cdf0e10cSrcweir     long                nDotWidth;
111cdf0e10cSrcweir     long                nExpWidth;
112cdf0e10cSrcweir 
113cdf0e10cSrcweir 	ScBaseCell*			pLastCell;
114cdf0e10cSrcweir 	sal_uLong				nValueFormat;
115cdf0e10cSrcweir 	sal_Bool				bLineBreak;
116cdf0e10cSrcweir     sal_Bool                bRepeat;
117cdf0e10cSrcweir     sal_Bool                bShrink;
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 	sal_Bool				bPixelToLogic;
120cdf0e10cSrcweir 	sal_Bool				bCellContrast;
121cdf0e10cSrcweir 
122cdf0e10cSrcweir 	Color				aBackConfigColor;		// used for ScPatternAttr::GetFont calls
123cdf0e10cSrcweir 	Color				aTextConfigColor;
124cdf0e10cSrcweir 
125cdf0e10cSrcweir public:
126cdf0e10cSrcweir 				ScDrawStringsVars(ScOutputData* pData, sal_Bool bPTL);
127cdf0e10cSrcweir 				~ScDrawStringsVars();
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 				//	SetPattern = ex-SetVars
130cdf0e10cSrcweir 				//	SetPatternSimple: ohne Font
131cdf0e10cSrcweir 
132cdf0e10cSrcweir 	void		SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet, ScBaseCell* pCell, sal_uInt8 nScript );
133cdf0e10cSrcweir 	void		SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet );
134cdf0e10cSrcweir 
135cdf0e10cSrcweir 	sal_Bool		SetText( ScBaseCell* pCell );	// sal_True -> pOldPattern vergessen
136cdf0e10cSrcweir     void        SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth );
137cdf0e10cSrcweir 	void		SetAutoText( const String& rAutoText );
138cdf0e10cSrcweir 
GetPattern() const139cdf0e10cSrcweir 	const ScPatternAttr*	GetPattern() const		{ return pPattern; }
GetOrient() const140cdf0e10cSrcweir 	SvxCellOrientation		GetOrient() const		{ return eAttrOrient; }
GetHorJust() const141cdf0e10cSrcweir 	SvxCellHorJustify		GetHorJust() const		{ return eAttrHorJust; }
GetVerJust() const142cdf0e10cSrcweir 	SvxCellVerJustify		GetVerJust() const		{ return eAttrVerJust; }
GetMargin() const143cdf0e10cSrcweir 	const SvxMarginItem*	GetMargin() const		{ return pMargin; }
144cdf0e10cSrcweir 
GetLeftTotal() const145cdf0e10cSrcweir 	sal_uInt16	GetLeftTotal() const		{ return pMargin->GetLeftMargin() + nIndent; }
146cdf0e10cSrcweir 
GetString() const147cdf0e10cSrcweir 	const String&			GetString() const		{ return aString; }
GetTextSize() const148cdf0e10cSrcweir 	const Size&				GetTextSize() const		{ return aTextSize; }
GetOriginalWidth() const149cdf0e10cSrcweir 	long					GetOriginalWidth() const { return nOriginalWidth; }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir     sal_uLong   GetResultValueFormat( const ScBaseCell* pCell ) const;
152cdf0e10cSrcweir 
GetValueFormat() const153cdf0e10cSrcweir 	sal_uLong	GetValueFormat() const					{ return nValueFormat; }
GetLineBreak() const154cdf0e10cSrcweir 	sal_Bool	GetLineBreak() const					{ return bLineBreak; }
IsRepeat() const155cdf0e10cSrcweir 	sal_Bool    IsRepeat() const                        { return bRepeat; }
IsShrink() const156cdf0e10cSrcweir     sal_Bool    IsShrink() const                        { return bShrink; }
157cdf0e10cSrcweir 
GetAscent() const158cdf0e10cSrcweir 	long	GetAscent() const	{ return nAscentPixel; }
IsRotated() const159cdf0e10cSrcweir 	sal_Bool	IsRotated() const	{ return bRotated; }
160cdf0e10cSrcweir 
161cdf0e10cSrcweir     void    SetShrinkScale( long nScale, sal_uInt8 nScript );
162cdf0e10cSrcweir 
HasCondHeight() const163cdf0e10cSrcweir 	sal_Bool	HasCondHeight() const	{ return pCondSet && SFX_ITEM_SET ==
164cdf0e10cSrcweir 										pCondSet->GetItemState( ATTR_FONT_HEIGHT, sal_True ); }
165cdf0e10cSrcweir 
166cdf0e10cSrcweir     sal_Bool    HasEditCharacters() const;
167cdf0e10cSrcweir 
168cdf0e10cSrcweir private:
169cdf0e10cSrcweir     void        SetHashText();
170cdf0e10cSrcweir     long        GetMaxDigitWidth();     // in logic units
171cdf0e10cSrcweir     long        GetSignWidth();
172cdf0e10cSrcweir     long        GetDotWidth();
173cdf0e10cSrcweir     long        GetExpWidth();
174cdf0e10cSrcweir     void        TextChanged();
175cdf0e10cSrcweir };
176cdf0e10cSrcweir 
177cdf0e10cSrcweir //==================================================================
178cdf0e10cSrcweir 
ScDrawStringsVars(ScOutputData * pData,sal_Bool bPTL)179cdf0e10cSrcweir ScDrawStringsVars::ScDrawStringsVars(ScOutputData* pData, sal_Bool bPTL) :
180cdf0e10cSrcweir 	pOutput		( pData ),
181cdf0e10cSrcweir 	pPattern	( NULL ),
182cdf0e10cSrcweir 	pCondSet	( NULL ),
183cdf0e10cSrcweir 	eAttrOrient	( SVX_ORIENTATION_STANDARD ),
184cdf0e10cSrcweir 	eAttrHorJust( SVX_HOR_JUSTIFY_STANDARD ),
185cdf0e10cSrcweir 	eAttrVerJust( SVX_VER_JUSTIFY_BOTTOM ),
186cdf0e10cSrcweir 	pMargin		( NULL ),
187cdf0e10cSrcweir 	nIndent		( 0 ),
188cdf0e10cSrcweir 	bRotated	( sal_False ),
189cdf0e10cSrcweir 	nOriginalWidth( 0 ),
190cdf0e10cSrcweir     nMaxDigitWidth( 0 ),
191cdf0e10cSrcweir     nSignWidth( 0 ),
192cdf0e10cSrcweir     nDotWidth( 0 ),
193cdf0e10cSrcweir     nExpWidth( 0 ),
194cdf0e10cSrcweir 	pLastCell	( NULL ),
195cdf0e10cSrcweir 	nValueFormat( 0 ),
196cdf0e10cSrcweir 	bLineBreak	( sal_False ),
197cdf0e10cSrcweir     bRepeat     ( sal_False ),
198cdf0e10cSrcweir     bShrink     ( sal_False ),
199cdf0e10cSrcweir 	bPixelToLogic( bPTL )
200cdf0e10cSrcweir {
201cdf0e10cSrcweir 	ScModule* pScMod = SC_MOD();
202cdf0e10cSrcweir 	//	#105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
203cdf0e10cSrcweir 	bCellContrast = pOutput->bUseStyleColor &&
204cdf0e10cSrcweir 			Application::GetSettings().GetStyleSettings().GetHighContrastMode();
205cdf0e10cSrcweir 
206cdf0e10cSrcweir     const svtools::ColorConfig& rColorConfig = pScMod->GetColorConfig();
207cdf0e10cSrcweir     aBackConfigColor.SetColor( rColorConfig.GetColorValue(svtools::DOCCOLOR).nColor );
208cdf0e10cSrcweir     aTextConfigColor.SetColor( rColorConfig.GetColorValue(svtools::FONTCOLOR).nColor );
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
~ScDrawStringsVars()211cdf0e10cSrcweir ScDrawStringsVars::~ScDrawStringsVars()
212cdf0e10cSrcweir {
213cdf0e10cSrcweir }
214cdf0e10cSrcweir 
SetShrinkScale(long nScale,sal_uInt8 nScript)215cdf0e10cSrcweir void ScDrawStringsVars::SetShrinkScale( long nScale, sal_uInt8 nScript )
216cdf0e10cSrcweir {
217cdf0e10cSrcweir     // text remains valid, size is updated
218cdf0e10cSrcweir 
219cdf0e10cSrcweir     OutputDevice* pDev = pOutput->pDev;
220cdf0e10cSrcweir     OutputDevice* pRefDevice = pOutput->pRefDevice;
221cdf0e10cSrcweir     OutputDevice* pFmtDevice = pOutput->pFmtDevice;
222cdf0e10cSrcweir 
223cdf0e10cSrcweir     // call GetFont with a modified fraction, use only the height
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     Fraction aFraction( nScale, 100 );
226cdf0e10cSrcweir     if ( !bPixelToLogic )
227cdf0e10cSrcweir         aFraction *= pOutput->aZoomY;
228cdf0e10cSrcweir     Font aTmpFont;
229cdf0e10cSrcweir 	pPattern->GetFont( aTmpFont, SC_AUTOCOL_RAW, pFmtDevice, &aFraction, pCondSet, nScript );
230cdf0e10cSrcweir 	long nNewHeight = aTmpFont.GetHeight();
231cdf0e10cSrcweir 	if ( nNewHeight > 0 )
232cdf0e10cSrcweir         aFont.SetHeight( nNewHeight );
233cdf0e10cSrcweir 
234cdf0e10cSrcweir     // set font and dependent variables as in SetPattern
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 	pDev->SetFont( aFont );
237cdf0e10cSrcweir 	if ( pFmtDevice != pDev )
238cdf0e10cSrcweir 		pFmtDevice->SetFont( aFont );
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 	aMetric = pFmtDevice->GetFontMetric();
241cdf0e10cSrcweir 	if ( pFmtDevice->GetOutDevType() == OUTDEV_PRINTER && aMetric.GetIntLeading() == 0 )
242cdf0e10cSrcweir 	{
243cdf0e10cSrcweir 		OutputDevice* pDefaultDev = Application::GetDefaultDevice();
244cdf0e10cSrcweir 		MapMode aOld = pDefaultDev->GetMapMode();
245cdf0e10cSrcweir 		pDefaultDev->SetMapMode( pFmtDevice->GetMapMode() );
246cdf0e10cSrcweir 		aMetric = pDefaultDev->GetFontMetric( aFont );
247cdf0e10cSrcweir 		pDefaultDev->SetMapMode( aOld );
248cdf0e10cSrcweir 	}
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 	nAscentPixel = aMetric.GetAscent();
251cdf0e10cSrcweir 	if ( bPixelToLogic )
252cdf0e10cSrcweir 		nAscentPixel = pRefDevice->LogicToPixel( Size( 0, nAscentPixel ) ).Height();
253cdf0e10cSrcweir 
254cdf0e10cSrcweir     SetAutoText( aString );     // same text again, to get text size
255cdf0e10cSrcweir }
256cdf0e10cSrcweir 
SetPattern(const ScPatternAttr * pNew,const SfxItemSet * pSet,ScBaseCell * pCell,sal_uInt8 nScript)257cdf0e10cSrcweir void ScDrawStringsVars::SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet,
258cdf0e10cSrcweir 									ScBaseCell* pCell, sal_uInt8 nScript )
259cdf0e10cSrcweir {
260cdf0e10cSrcweir     nMaxDigitWidth = 0;
261cdf0e10cSrcweir     nSignWidth     = 0;
262cdf0e10cSrcweir     nDotWidth      = 0;
263cdf0e10cSrcweir     nExpWidth      = 0;
264cdf0e10cSrcweir 
265cdf0e10cSrcweir 	pPattern = pNew;
266cdf0e10cSrcweir 	pCondSet = pSet;
267cdf0e10cSrcweir 
268cdf0e10cSrcweir 	//	pPattern auswerten
269cdf0e10cSrcweir 
270cdf0e10cSrcweir 	OutputDevice* pDev = pOutput->pDev;
271cdf0e10cSrcweir 	OutputDevice* pRefDevice = pOutput->pRefDevice;
272cdf0e10cSrcweir 	OutputDevice* pFmtDevice = pOutput->pFmtDevice;
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 	//	Font
275cdf0e10cSrcweir 
276cdf0e10cSrcweir 	ScAutoFontColorMode eColorMode;
277cdf0e10cSrcweir 	if ( pOutput->bUseStyleColor )
278cdf0e10cSrcweir 	{
279cdf0e10cSrcweir 		if ( pOutput->bForceAutoColor )
280cdf0e10cSrcweir 			eColorMode = bCellContrast ? SC_AUTOCOL_IGNOREALL : SC_AUTOCOL_IGNOREFONT;
281cdf0e10cSrcweir 		else
282cdf0e10cSrcweir 			eColorMode = bCellContrast ? SC_AUTOCOL_IGNOREBACK : SC_AUTOCOL_DISPLAY;
283cdf0e10cSrcweir 	}
284cdf0e10cSrcweir 	else
285cdf0e10cSrcweir 		eColorMode = SC_AUTOCOL_PRINT;
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 	if ( bPixelToLogic )
288cdf0e10cSrcweir 		pPattern->GetFont( aFont, eColorMode, pFmtDevice, NULL, pCondSet, nScript,
289cdf0e10cSrcweir 							&aBackConfigColor, &aTextConfigColor );
290cdf0e10cSrcweir 	else
291cdf0e10cSrcweir 		pPattern->GetFont( aFont, eColorMode, pFmtDevice, &pOutput->aZoomY, pCondSet, nScript,
292cdf0e10cSrcweir 							&aBackConfigColor, &aTextConfigColor );
293cdf0e10cSrcweir 	aFont.SetAlign(ALIGN_BASELINE);
294cdf0e10cSrcweir 
295cdf0e10cSrcweir 	//	Orientierung
296cdf0e10cSrcweir 
297cdf0e10cSrcweir     eAttrOrient = pPattern->GetCellOrientation( pCondSet );
298cdf0e10cSrcweir 
299cdf0e10cSrcweir 	//	alignment
300cdf0e10cSrcweir 
301cdf0e10cSrcweir     eAttrHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
302cdf0e10cSrcweir 
303cdf0e10cSrcweir     eAttrVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)pPattern->GetItem( ATTR_VER_JUSTIFY, pCondSet )).GetValue();
304cdf0e10cSrcweir 	if ( eAttrVerJust == SVX_VER_JUSTIFY_STANDARD )
305cdf0e10cSrcweir 		eAttrVerJust = SVX_VER_JUSTIFY_BOTTOM;
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 	//	line break
308cdf0e10cSrcweir 
309cdf0e10cSrcweir     bLineBreak = ((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK, pCondSet )).GetValue();
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     //  handle "repeat" alignment
312cdf0e10cSrcweir 
313cdf0e10cSrcweir     bRepeat = ( eAttrHorJust == SVX_HOR_JUSTIFY_REPEAT );
314cdf0e10cSrcweir     if ( bRepeat )
315cdf0e10cSrcweir     {
316cdf0e10cSrcweir         // "repeat" disables rotation (before constructing the font)
317cdf0e10cSrcweir         eAttrOrient = SVX_ORIENTATION_STANDARD;
318cdf0e10cSrcweir 
319cdf0e10cSrcweir         // #i31843# "repeat" with "line breaks" is treated as default alignment (but rotation is still disabled)
320cdf0e10cSrcweir         if ( bLineBreak )
321cdf0e10cSrcweir             eAttrHorJust = SVX_HOR_JUSTIFY_STANDARD;
322cdf0e10cSrcweir     }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 	short nRot;
325cdf0e10cSrcweir 	switch (eAttrOrient)
326cdf0e10cSrcweir 	{
327cdf0e10cSrcweir 		case SVX_ORIENTATION_STANDARD:
328cdf0e10cSrcweir 			nRot = 0;
329cdf0e10cSrcweir             bRotated = (((const SfxInt32Item&)pPattern->GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue() != 0) &&
330cdf0e10cSrcweir                        !bRepeat;
331cdf0e10cSrcweir 			break;
332cdf0e10cSrcweir 		case SVX_ORIENTATION_STACKED:
333cdf0e10cSrcweir 			nRot = 0;
334cdf0e10cSrcweir 			bRotated = sal_False;
335cdf0e10cSrcweir 			break;
336cdf0e10cSrcweir 		case SVX_ORIENTATION_TOPBOTTOM:
337cdf0e10cSrcweir 			nRot = 2700;
338cdf0e10cSrcweir 			bRotated = sal_False;
339cdf0e10cSrcweir 			break;
340cdf0e10cSrcweir 		case SVX_ORIENTATION_BOTTOMTOP:
341cdf0e10cSrcweir 			nRot = 900;
342cdf0e10cSrcweir 			bRotated = sal_False;
343cdf0e10cSrcweir 			break;
344cdf0e10cSrcweir 		default:
345cdf0e10cSrcweir 			DBG_ERROR("Falscher SvxCellOrientation Wert");
346cdf0e10cSrcweir 			nRot = 0;
347cdf0e10cSrcweir 			bRotated = sal_False;
348cdf0e10cSrcweir 			break;
349cdf0e10cSrcweir 	}
350cdf0e10cSrcweir 	aFont.SetOrientation( nRot );
351cdf0e10cSrcweir 
352cdf0e10cSrcweir 	//	Syntax-Modus
353cdf0e10cSrcweir 
354cdf0e10cSrcweir 	if (pOutput->bSyntaxMode)
355cdf0e10cSrcweir 		pOutput->SetSyntaxColor( &aFont, pCell );
356cdf0e10cSrcweir 
357cdf0e10cSrcweir 	pDev->SetFont( aFont );
358cdf0e10cSrcweir 	if ( pFmtDevice != pDev )
359cdf0e10cSrcweir 		pFmtDevice->SetFont( aFont );
360cdf0e10cSrcweir 
361cdf0e10cSrcweir 	aMetric = pFmtDevice->GetFontMetric();
362cdf0e10cSrcweir 
363cdf0e10cSrcweir 	//
364cdf0e10cSrcweir 	//	Wenn auf dem Drucker das Leading 0 ist, gibt es Probleme
365cdf0e10cSrcweir 	//	-> Metric vom Bildschirm nehmen (wie EditEngine!)
366cdf0e10cSrcweir 	//
367cdf0e10cSrcweir 
368cdf0e10cSrcweir 	if ( pFmtDevice->GetOutDevType() == OUTDEV_PRINTER && aMetric.GetIntLeading() == 0 )
369cdf0e10cSrcweir 	{
370cdf0e10cSrcweir 		OutputDevice* pDefaultDev = Application::GetDefaultDevice();
371cdf0e10cSrcweir 		MapMode aOld = pDefaultDev->GetMapMode();
372cdf0e10cSrcweir 		pDefaultDev->SetMapMode( pFmtDevice->GetMapMode() );
373cdf0e10cSrcweir 		aMetric = pDefaultDev->GetFontMetric( aFont );
374cdf0e10cSrcweir 		pDefaultDev->SetMapMode( aOld );
375cdf0e10cSrcweir 	}
376cdf0e10cSrcweir 
377cdf0e10cSrcweir 	nAscentPixel = aMetric.GetAscent();
378cdf0e10cSrcweir 	if ( bPixelToLogic )
379cdf0e10cSrcweir 		nAscentPixel = pRefDevice->LogicToPixel( Size( 0, nAscentPixel ) ).Height();
380cdf0e10cSrcweir 
381cdf0e10cSrcweir     Color aULineColor( ((const SvxUnderlineItem&)pPattern->GetItem( ATTR_FONT_UNDERLINE, pCondSet )).GetColor() );
382cdf0e10cSrcweir 	pDev->SetTextLineColor( aULineColor );
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     Color aOLineColor( ((const SvxOverlineItem&)pPattern->GetItem( ATTR_FONT_OVERLINE, pCondSet )).GetColor() );
385cdf0e10cSrcweir 	pDev->SetOverlineColor( aOLineColor );
386cdf0e10cSrcweir 
387cdf0e10cSrcweir 	//	Zahlenformat
388cdf0e10cSrcweir 
389cdf0e10cSrcweir //    sal_uLong nOld = nValueFormat;
390cdf0e10cSrcweir 	nValueFormat = pPattern->GetNumberFormat( pOutput->pDoc->GetFormatTable(), pCondSet );
391cdf0e10cSrcweir 
392cdf0e10cSrcweir /*	s.u.
393cdf0e10cSrcweir 	if (nValueFormat != nOld)
394cdf0e10cSrcweir 		pLastCell = NULL;			// immer neu formatieren
395cdf0e10cSrcweir */
396cdf0e10cSrcweir 	//	Raender
397cdf0e10cSrcweir 
398cdf0e10cSrcweir     pMargin = (const SvxMarginItem*)&pPattern->GetItem( ATTR_MARGIN, pCondSet );
399cdf0e10cSrcweir 	if ( eAttrHorJust == SVX_HOR_JUSTIFY_LEFT )
400cdf0e10cSrcweir         nIndent = ((const SfxUInt16Item&)pPattern->GetItem( ATTR_INDENT, pCondSet )).GetValue();
401cdf0e10cSrcweir 	else
402cdf0e10cSrcweir 		nIndent = 0;
403cdf0e10cSrcweir 
404cdf0e10cSrcweir     //  "Shrink to fit"
405cdf0e10cSrcweir 
406cdf0e10cSrcweir     bShrink = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 	//	zumindest die Text-Groesse muss neu geholt werden
409cdf0e10cSrcweir 	//!	unterscheiden, und den Text nicht neu vom Numberformatter holen?
410cdf0e10cSrcweir 
411cdf0e10cSrcweir 	pLastCell = NULL;
412cdf0e10cSrcweir }
413cdf0e10cSrcweir 
SetPatternSimple(const ScPatternAttr * pNew,const SfxItemSet * pSet)414cdf0e10cSrcweir void ScDrawStringsVars::SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet )
415cdf0e10cSrcweir {
416cdf0e10cSrcweir     nMaxDigitWidth = 0;
417cdf0e10cSrcweir     nSignWidth     = 0;
418cdf0e10cSrcweir     nDotWidth      = 0;
419cdf0e10cSrcweir     nExpWidth      = 0;
420cdf0e10cSrcweir 	//	wird gerufen, wenn sich die Font-Variablen nicht aendern (!StringDiffer)
421cdf0e10cSrcweir 
422cdf0e10cSrcweir 	pPattern = pNew;
423cdf0e10cSrcweir 	pCondSet = pSet;		//! noetig ???
424cdf0e10cSrcweir 
425cdf0e10cSrcweir 	//	Zahlenformat
426cdf0e10cSrcweir 
427cdf0e10cSrcweir 	sal_uLong nOld = nValueFormat;
428cdf0e10cSrcweir //	nValueFormat = pPattern->GetNumberFormat( pFormatter );
429cdf0e10cSrcweir 	const SfxPoolItem* pFormItem;
430cdf0e10cSrcweir 	if ( !pCondSet || pCondSet->GetItemState(ATTR_VALUE_FORMAT,sal_True,&pFormItem) != SFX_ITEM_SET )
431cdf0e10cSrcweir 		pFormItem = &pPattern->GetItem(ATTR_VALUE_FORMAT);
432cdf0e10cSrcweir 	const SfxPoolItem* pLangItem;
433cdf0e10cSrcweir 	if ( !pCondSet || pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT,sal_True,&pLangItem) != SFX_ITEM_SET )
434cdf0e10cSrcweir 		pLangItem = &pPattern->GetItem(ATTR_LANGUAGE_FORMAT);
435cdf0e10cSrcweir 	nValueFormat = pOutput->pDoc->GetFormatTable()->GetFormatForLanguageIfBuiltIn(
436cdf0e10cSrcweir 					((SfxUInt32Item*)pFormItem)->GetValue(),
437cdf0e10cSrcweir 					((SvxLanguageItem*)pLangItem)->GetLanguage() );
438cdf0e10cSrcweir 
439cdf0e10cSrcweir 	if (nValueFormat != nOld)
440cdf0e10cSrcweir 		pLastCell = NULL;			// immer neu formatieren
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 	//	Raender
443cdf0e10cSrcweir 
444cdf0e10cSrcweir     pMargin = (const SvxMarginItem*)&pPattern->GetItem( ATTR_MARGIN, pCondSet );
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 	if ( eAttrHorJust == SVX_HOR_JUSTIFY_LEFT )
447cdf0e10cSrcweir         nIndent = ((const SfxUInt16Item&)pPattern->GetItem( ATTR_INDENT, pCondSet )).GetValue();
448cdf0e10cSrcweir 	else
449cdf0e10cSrcweir 		nIndent = 0;
450cdf0e10cSrcweir 
451cdf0e10cSrcweir     //  "Shrink to fit"
452cdf0e10cSrcweir 
453cdf0e10cSrcweir     bShrink = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
SameValue(ScBaseCell * pCell,ScBaseCell * pOldCell)456cdf0e10cSrcweir inline sal_Bool SameValue( ScBaseCell* pCell, ScBaseCell* pOldCell )	// pCell ist != 0
457cdf0e10cSrcweir {
458cdf0e10cSrcweir 	return pOldCell && pOldCell->GetCellType() == CELLTYPE_VALUE &&
459cdf0e10cSrcweir 			pCell->GetCellType() == CELLTYPE_VALUE &&
460cdf0e10cSrcweir 			((ScValueCell*)pCell)->GetValue() == ((ScValueCell*)pOldCell)->GetValue();
461cdf0e10cSrcweir }
462cdf0e10cSrcweir 
SetText(ScBaseCell * pCell)463cdf0e10cSrcweir sal_Bool ScDrawStringsVars::SetText( ScBaseCell* pCell )
464cdf0e10cSrcweir {
465cdf0e10cSrcweir 	sal_Bool bChanged = sal_False;
466cdf0e10cSrcweir 
467cdf0e10cSrcweir 	if (pCell)
468cdf0e10cSrcweir 	{
469cdf0e10cSrcweir 		if ( !SameValue( pCell, pLastCell ) )
470cdf0e10cSrcweir 		{
471cdf0e10cSrcweir 			pLastCell = pCell;			//	Zelle merken
472cdf0e10cSrcweir 
473cdf0e10cSrcweir 			Color* pColor;
474cdf0e10cSrcweir 			sal_uLong nFormat = GetValueFormat();
475cdf0e10cSrcweir 			ScCellFormat::GetString( pCell,
476cdf0e10cSrcweir 									 nFormat, aString, &pColor,
477cdf0e10cSrcweir 									 *pOutput->pDoc->GetFormatTable(),
478cdf0e10cSrcweir 									 pOutput->bShowNullValues,
479cdf0e10cSrcweir 									 pOutput->bShowFormulas,
480cdf0e10cSrcweir 									 ftCheck );
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 			if (aString.Len() > DRAWTEXT_MAX)
483cdf0e10cSrcweir 				aString.Erase(DRAWTEXT_MAX);
484cdf0e10cSrcweir 
485cdf0e10cSrcweir 			if ( pColor && !pOutput->bSyntaxMode && !( pOutput->bUseStyleColor && pOutput->bForceAutoColor ) )
486cdf0e10cSrcweir 			{
487cdf0e10cSrcweir 				OutputDevice* pDev = pOutput->pDev;
488cdf0e10cSrcweir 				aFont.SetColor(*pColor);
489cdf0e10cSrcweir 				pDev->SetFont( aFont );	// nur fuer Ausgabe
490cdf0e10cSrcweir 				bChanged = sal_True;
491cdf0e10cSrcweir 				pLastCell = NULL;		// naechstes Mal wieder hierherkommen
492cdf0e10cSrcweir 			}
493cdf0e10cSrcweir 
494cdf0e10cSrcweir             TextChanged();
495cdf0e10cSrcweir 		}
496cdf0e10cSrcweir 		//	sonst String/Groesse behalten
497cdf0e10cSrcweir 	}
498cdf0e10cSrcweir 	else
499cdf0e10cSrcweir 	{
500cdf0e10cSrcweir 		aString.Erase();
501cdf0e10cSrcweir 		pLastCell = NULL;
502cdf0e10cSrcweir 		aTextSize = Size(0,0);
503cdf0e10cSrcweir 		nOriginalWidth = 0;
504cdf0e10cSrcweir 	}
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 	return bChanged;
507cdf0e10cSrcweir }
508cdf0e10cSrcweir 
SetHashText()509cdf0e10cSrcweir void ScDrawStringsVars::SetHashText()
510cdf0e10cSrcweir {
511cdf0e10cSrcweir     SetAutoText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) );
512cdf0e10cSrcweir }
513cdf0e10cSrcweir 
SetTextToWidthOrHash(ScBaseCell * pCell,long nWidth)514cdf0e10cSrcweir void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth )
515cdf0e10cSrcweir {
516cdf0e10cSrcweir     // #i113045# do the single-character width calculations in logic units
517cdf0e10cSrcweir     if (bPixelToLogic)
518cdf0e10cSrcweir         nWidth = pOutput->pRefDevice->PixelToLogic(Size(nWidth,0)).Width();
519cdf0e10cSrcweir 
520cdf0e10cSrcweir     if (!pCell)
521cdf0e10cSrcweir         return;
522cdf0e10cSrcweir 
523cdf0e10cSrcweir     CellType eType = pCell->GetCellType();
524cdf0e10cSrcweir     if (eType != CELLTYPE_VALUE && eType != CELLTYPE_FORMULA)
525cdf0e10cSrcweir         // must be a value or formula cell.
526cdf0e10cSrcweir         return;
527cdf0e10cSrcweir 
528cdf0e10cSrcweir     if (eType == CELLTYPE_FORMULA)
529cdf0e10cSrcweir     {
530cdf0e10cSrcweir         ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
531cdf0e10cSrcweir         if (pFCell->GetErrCode() != 0 || pOutput->bShowFormulas)
532cdf0e10cSrcweir         {
533cdf0e10cSrcweir             SetHashText();      // If the error string doesn't fit, always use "###". Also for "display formulas" (#i116691#)
534cdf0e10cSrcweir             return;
535cdf0e10cSrcweir         }
536cdf0e10cSrcweir         // If it's formula, the result must be a value.
537cdf0e10cSrcweir         if (!pFCell->IsValue())
538cdf0e10cSrcweir             return;
539cdf0e10cSrcweir     }
540cdf0e10cSrcweir 
541cdf0e10cSrcweir     sal_uLong nFormat = GetResultValueFormat(pCell);
542cdf0e10cSrcweir     if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
543cdf0e10cSrcweir     {
544cdf0e10cSrcweir         // Not 'General' number format.  Set hash text and bail out.
545cdf0e10cSrcweir         SetHashText();
546cdf0e10cSrcweir         return;
547cdf0e10cSrcweir     }
548cdf0e10cSrcweir 
549cdf0e10cSrcweir     double fVal = (eType == CELLTYPE_VALUE) ?
550cdf0e10cSrcweir         static_cast<ScValueCell*>(pCell)->GetValue() : static_cast<ScFormulaCell*>(pCell)->GetValue();
551cdf0e10cSrcweir 
552cdf0e10cSrcweir     const SvNumberformat* pNumFormat = pOutput->pDoc->GetFormatTable()->GetEntry(nFormat);
553cdf0e10cSrcweir     if (!pNumFormat)
554cdf0e10cSrcweir         return;
555cdf0e10cSrcweir 
556cdf0e10cSrcweir     long nMaxDigit = GetMaxDigitWidth();
557cdf0e10cSrcweir     sal_uInt16 nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit);
558cdf0e10cSrcweir 
559cdf0e10cSrcweir     if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString))
560cdf0e10cSrcweir         // Failed to get output string.  Bail out.
561cdf0e10cSrcweir         return;
562cdf0e10cSrcweir 
563cdf0e10cSrcweir     sal_uInt8 nSignCount = 0, nDecimalCount = 0, nExpCount = 0;
564cdf0e10cSrcweir     xub_StrLen nLen = aString.Len();
565cdf0e10cSrcweir     sal_Unicode cDecSep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator.getStr()[0];
566cdf0e10cSrcweir     for (xub_StrLen i = 0; i < nLen; ++i)
567cdf0e10cSrcweir     {
568cdf0e10cSrcweir         sal_Unicode c = aString.GetChar(i);
569cdf0e10cSrcweir         if (c == sal_Unicode('-'))
570cdf0e10cSrcweir             ++nSignCount;
571cdf0e10cSrcweir         else if (c == cDecSep)
572cdf0e10cSrcweir             ++nDecimalCount;
573cdf0e10cSrcweir         else if (c == sal_Unicode('E'))
574cdf0e10cSrcweir             ++nExpCount;
575cdf0e10cSrcweir     }
576cdf0e10cSrcweir 
577cdf0e10cSrcweir     // #i112250# A small value might be formatted as "0" when only counting the digits,
578cdf0e10cSrcweir     // but fit into the column when considering the smaller width of the decimal separator.
579cdf0e10cSrcweir     if (aString.EqualsAscii("0") && fVal != 0.0)
580cdf0e10cSrcweir         nDecimalCount = 1;
581cdf0e10cSrcweir 
582cdf0e10cSrcweir     if (nDecimalCount)
583cdf0e10cSrcweir         nWidth += (nMaxDigit - GetDotWidth()) * nDecimalCount;
584cdf0e10cSrcweir     if (nSignCount)
585cdf0e10cSrcweir         nWidth += (nMaxDigit - GetSignWidth()) * nSignCount;
586cdf0e10cSrcweir     if (nExpCount)
587cdf0e10cSrcweir         nWidth += (nMaxDigit - GetExpWidth()) * nExpCount;
588cdf0e10cSrcweir 
589cdf0e10cSrcweir     if (nDecimalCount || nSignCount || nExpCount)
590cdf0e10cSrcweir     {
591cdf0e10cSrcweir         // Re-calculate.
592cdf0e10cSrcweir         nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit);
593cdf0e10cSrcweir         if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString))
594cdf0e10cSrcweir             // Failed to get output string.  Bail out.
595cdf0e10cSrcweir             return;
596cdf0e10cSrcweir     }
597cdf0e10cSrcweir 
598cdf0e10cSrcweir     long nActualTextWidth = pOutput->pFmtDevice->GetTextWidth(aString);
599cdf0e10cSrcweir     if (nActualTextWidth > nWidth)
600cdf0e10cSrcweir     {
601cdf0e10cSrcweir         // Even after the decimal adjustment the text doesn't fit.  Give up.
602cdf0e10cSrcweir         SetHashText();
603cdf0e10cSrcweir         return;
604cdf0e10cSrcweir     }
605cdf0e10cSrcweir 
606cdf0e10cSrcweir     TextChanged();
607cdf0e10cSrcweir     pLastCell = NULL;   // #i113022# equal cell and format in another column may give different string
608cdf0e10cSrcweir }
609cdf0e10cSrcweir 
SetAutoText(const String & rAutoText)610cdf0e10cSrcweir void ScDrawStringsVars::SetAutoText( const String& rAutoText )
611cdf0e10cSrcweir {
612cdf0e10cSrcweir 	aString = rAutoText;
613cdf0e10cSrcweir 
614cdf0e10cSrcweir 	OutputDevice* pRefDevice = pOutput->pRefDevice;
615cdf0e10cSrcweir 	OutputDevice* pFmtDevice = pOutput->pFmtDevice;
616cdf0e10cSrcweir 	aTextSize.Width() = pFmtDevice->GetTextWidth( aString );
617cdf0e10cSrcweir 	aTextSize.Height() = pFmtDevice->GetTextHeight();
618cdf0e10cSrcweir 
619cdf0e10cSrcweir 	if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
620cdf0e10cSrcweir 	{
621cdf0e10cSrcweir 		double fMul = pOutput->GetStretch();
622cdf0e10cSrcweir 		aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5);
623cdf0e10cSrcweir 	}
624cdf0e10cSrcweir 
625cdf0e10cSrcweir 	aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent();
626cdf0e10cSrcweir 	if ( GetOrient() != SVX_ORIENTATION_STANDARD )
627cdf0e10cSrcweir 	{
628cdf0e10cSrcweir 		long nTemp = aTextSize.Height();
629cdf0e10cSrcweir 		aTextSize.Height() = aTextSize.Width();
630cdf0e10cSrcweir 		aTextSize.Width() = nTemp;
631cdf0e10cSrcweir 	}
632cdf0e10cSrcweir 
633cdf0e10cSrcweir 	nOriginalWidth = aTextSize.Width();
634cdf0e10cSrcweir 	if ( bPixelToLogic )
635cdf0e10cSrcweir 		aTextSize = pRefDevice->LogicToPixel( aTextSize );
636cdf0e10cSrcweir 
637cdf0e10cSrcweir 	pLastCell = NULL;		// derselbe Text kann in der naechsten Zelle wieder passen
638cdf0e10cSrcweir }
639cdf0e10cSrcweir 
GetMaxDigitWidth()640cdf0e10cSrcweir long ScDrawStringsVars::GetMaxDigitWidth()
641cdf0e10cSrcweir {
642cdf0e10cSrcweir     if (nMaxDigitWidth > 0)
643cdf0e10cSrcweir         return nMaxDigitWidth;
644cdf0e10cSrcweir 
645cdf0e10cSrcweir     sal_Char cZero = '0';
646cdf0e10cSrcweir     for (sal_Char i = 0; i < 10; ++i)
647cdf0e10cSrcweir     {
648cdf0e10cSrcweir         sal_Char cDigit = cZero + i;
649cdf0e10cSrcweir         long n = pOutput->pFmtDevice->GetTextWidth(String(cDigit));
650cdf0e10cSrcweir         nMaxDigitWidth = ::std::max(nMaxDigitWidth, n);
651cdf0e10cSrcweir     }
652cdf0e10cSrcweir     return nMaxDigitWidth;
653cdf0e10cSrcweir }
654cdf0e10cSrcweir 
GetSignWidth()655cdf0e10cSrcweir long ScDrawStringsVars::GetSignWidth()
656cdf0e10cSrcweir {
657cdf0e10cSrcweir     if (nSignWidth > 0)
658cdf0e10cSrcweir         return nSignWidth;
659cdf0e10cSrcweir 
660cdf0e10cSrcweir     nSignWidth = pOutput->pFmtDevice->GetTextWidth(String('-'));
661cdf0e10cSrcweir     return nSignWidth;
662cdf0e10cSrcweir }
663cdf0e10cSrcweir 
GetDotWidth()664cdf0e10cSrcweir long ScDrawStringsVars::GetDotWidth()
665cdf0e10cSrcweir {
666cdf0e10cSrcweir     if (nDotWidth > 0)
667cdf0e10cSrcweir         return nDotWidth;
668cdf0e10cSrcweir 
669cdf0e10cSrcweir     const ::rtl::OUString& sep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator;
670cdf0e10cSrcweir     nDotWidth = pOutput->pFmtDevice->GetTextWidth(sep);
671cdf0e10cSrcweir     return nDotWidth;
672cdf0e10cSrcweir }
673cdf0e10cSrcweir 
GetExpWidth()674cdf0e10cSrcweir long ScDrawStringsVars::GetExpWidth()
675cdf0e10cSrcweir {
676cdf0e10cSrcweir     if (nExpWidth > 0)
677cdf0e10cSrcweir         return nExpWidth;
678cdf0e10cSrcweir 
679cdf0e10cSrcweir     nExpWidth = pOutput->pFmtDevice->GetTextWidth(String('E'));
680cdf0e10cSrcweir     return nExpWidth;
681cdf0e10cSrcweir }
682cdf0e10cSrcweir 
TextChanged()683cdf0e10cSrcweir void ScDrawStringsVars::TextChanged()
684cdf0e10cSrcweir {
685cdf0e10cSrcweir     OutputDevice* pRefDevice = pOutput->pRefDevice;
686cdf0e10cSrcweir     OutputDevice* pFmtDevice = pOutput->pFmtDevice;
687cdf0e10cSrcweir     aTextSize.Width() = pFmtDevice->GetTextWidth( aString );
688cdf0e10cSrcweir     aTextSize.Height() = pFmtDevice->GetTextHeight();
689cdf0e10cSrcweir 
690cdf0e10cSrcweir     if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
691cdf0e10cSrcweir     {
692cdf0e10cSrcweir         double fMul = pOutput->GetStretch();
693cdf0e10cSrcweir         aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5);
694cdf0e10cSrcweir     }
695cdf0e10cSrcweir 
696cdf0e10cSrcweir     aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent();
697cdf0e10cSrcweir     if ( GetOrient() != SVX_ORIENTATION_STANDARD )
698cdf0e10cSrcweir     {
699cdf0e10cSrcweir         long nTemp = aTextSize.Height();
700cdf0e10cSrcweir         aTextSize.Height() = aTextSize.Width();
701cdf0e10cSrcweir         aTextSize.Width() = nTemp;
702cdf0e10cSrcweir     }
703cdf0e10cSrcweir 
704cdf0e10cSrcweir     nOriginalWidth = aTextSize.Width();
705cdf0e10cSrcweir     if ( bPixelToLogic )
706cdf0e10cSrcweir         aTextSize = pRefDevice->LogicToPixel( aTextSize );
707cdf0e10cSrcweir }
708cdf0e10cSrcweir 
HasEditCharacters() const709cdf0e10cSrcweir sal_Bool ScDrawStringsVars::HasEditCharacters() const
710cdf0e10cSrcweir {
711cdf0e10cSrcweir     static const sal_Unicode pChars[] =
712cdf0e10cSrcweir     {
713cdf0e10cSrcweir         CHAR_NBSP, CHAR_SHY, CHAR_ZWSP, CHAR_LRM, CHAR_RLM, CHAR_NBHY, CHAR_ZWNBSP, 0
714cdf0e10cSrcweir     };
715cdf0e10cSrcweir     return aString.SearchChar( pChars ) != STRING_NOTFOUND;
716cdf0e10cSrcweir }
717cdf0e10cSrcweir 
GetResultValueFormat(const ScBaseCell * pCell) const718cdf0e10cSrcweir sal_uLong ScDrawStringsVars::GetResultValueFormat( const ScBaseCell* pCell ) const
719cdf0e10cSrcweir {
720cdf0e10cSrcweir     // Get the effective number format, including formula result types.
721cdf0e10cSrcweir     // This assumes that a formula cell has already been calculated.
722cdf0e10cSrcweir 
723cdf0e10cSrcweir     if ( (nValueFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 && pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
724cdf0e10cSrcweir         return static_cast<const ScFormulaCell*>(pCell)->GetStandardFormat(*pOutput->pDoc->GetFormatTable(), nValueFormat);
725cdf0e10cSrcweir     else
726cdf0e10cSrcweir         return nValueFormat;
727cdf0e10cSrcweir }
728cdf0e10cSrcweir 
729cdf0e10cSrcweir //==================================================================
730cdf0e10cSrcweir 
GetStretch()731cdf0e10cSrcweir double ScOutputData::GetStretch()
732cdf0e10cSrcweir {
733cdf0e10cSrcweir 	if ( pRefDevice->IsMapMode() )
734cdf0e10cSrcweir 	{
735cdf0e10cSrcweir 		//	#95920# If a non-trivial MapMode is set, its scale is now already
736cdf0e10cSrcweir 		//	taken into account in the OutputDevice's font handling
737cdf0e10cSrcweir 		//	(OutputDevice::ImplNewFont, see #95414#).
738cdf0e10cSrcweir 		//	The old handling below is only needed for pixel output.
739cdf0e10cSrcweir 		return 1.0;
740cdf0e10cSrcweir 	}
741cdf0e10cSrcweir 
742cdf0e10cSrcweir 	// calculation in double is faster than Fraction multiplication
743cdf0e10cSrcweir 	// and doesn't overflow
744cdf0e10cSrcweir 
745cdf0e10cSrcweir 	if ( pRefDevice == pFmtDevice )
746cdf0e10cSrcweir 	{
747cdf0e10cSrcweir 		MapMode aOld = pRefDevice->GetMapMode();
748cdf0e10cSrcweir 		return ((double)aOld.GetScaleY()) / ((double)aOld.GetScaleX()) * ((double)aZoomY) / ((double)aZoomX);
749cdf0e10cSrcweir 	}
750cdf0e10cSrcweir 	else
751cdf0e10cSrcweir 	{
752cdf0e10cSrcweir 		// when formatting for printer, device map mode has already been taken care of
753cdf0e10cSrcweir 		return ((double)aZoomY) / ((double)aZoomX);
754cdf0e10cSrcweir 	}
755cdf0e10cSrcweir }
756cdf0e10cSrcweir 
757cdf0e10cSrcweir //==================================================================
758cdf0e10cSrcweir 
759cdf0e10cSrcweir //
760cdf0e10cSrcweir //	output strings
761cdf0e10cSrcweir //
762cdf0e10cSrcweir 
lcl_DoHyperlinkResult(OutputDevice * pDev,const Rectangle & rRect,ScBaseCell * pCell)763cdf0e10cSrcweir void lcl_DoHyperlinkResult( OutputDevice* pDev, const Rectangle& rRect, ScBaseCell* pCell )
764cdf0e10cSrcweir {
765cdf0e10cSrcweir     vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
766cdf0e10cSrcweir 
767cdf0e10cSrcweir     String aCellText;
768cdf0e10cSrcweir     String aURL;
769cdf0e10cSrcweir     if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
770cdf0e10cSrcweir     {
771cdf0e10cSrcweir         ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
772cdf0e10cSrcweir         if ( pFCell->IsHyperLinkCell() )
773cdf0e10cSrcweir             pFCell->GetURLResult( aURL, aCellText );
774cdf0e10cSrcweir     }
775cdf0e10cSrcweir 
776cdf0e10cSrcweir     if ( aURL.Len() && pPDFData )
777cdf0e10cSrcweir     {
778cdf0e10cSrcweir         vcl::PDFExtOutDevBookmarkEntry aBookmark;
779cdf0e10cSrcweir         aBookmark.nLinkId = pPDFData->CreateLink( rRect );
780cdf0e10cSrcweir         aBookmark.aBookmark = aURL;
781cdf0e10cSrcweir         std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFData->GetBookmarks();
782cdf0e10cSrcweir         rBookmarks.push_back( aBookmark );
783cdf0e10cSrcweir     }
784cdf0e10cSrcweir }
785cdf0e10cSrcweir 
SetSyntaxColor(Font * pFont,ScBaseCell * pCell)786cdf0e10cSrcweir void ScOutputData::SetSyntaxColor( Font* pFont, ScBaseCell* pCell )
787cdf0e10cSrcweir {
788cdf0e10cSrcweir 	if (pCell)
789cdf0e10cSrcweir 	{
790cdf0e10cSrcweir 		switch (pCell->GetCellType())
791cdf0e10cSrcweir 		{
792cdf0e10cSrcweir 			case CELLTYPE_VALUE:
793cdf0e10cSrcweir 				pFont->SetColor( *pValueColor );
794cdf0e10cSrcweir 				break;
795cdf0e10cSrcweir 			case CELLTYPE_STRING:
796cdf0e10cSrcweir 				pFont->SetColor( *pTextColor );
797cdf0e10cSrcweir 				break;
798cdf0e10cSrcweir 			case CELLTYPE_FORMULA:
799cdf0e10cSrcweir 				pFont->SetColor( *pFormulaColor );
800cdf0e10cSrcweir 				break;
801cdf0e10cSrcweir             default:
802cdf0e10cSrcweir             {
803cdf0e10cSrcweir                 // added to avoid warnings
804cdf0e10cSrcweir             }
805cdf0e10cSrcweir 		}
806cdf0e10cSrcweir 	}
807cdf0e10cSrcweir }
808cdf0e10cSrcweir 
lcl_SetEditColor(EditEngine & rEngine,const Color & rColor)809cdf0e10cSrcweir void lcl_SetEditColor( EditEngine& rEngine, const Color& rColor )
810cdf0e10cSrcweir {
811cdf0e10cSrcweir 	ESelection aSel( 0, 0, rEngine.GetParagraphCount(), 0 );
812cdf0e10cSrcweir 	SfxItemSet aSet( rEngine.GetEmptyItemSet() );
813cdf0e10cSrcweir 	aSet.Put( SvxColorItem( rColor, EE_CHAR_COLOR ) );
814cdf0e10cSrcweir 	rEngine.QuickSetAttribs( aSet, aSel );
815cdf0e10cSrcweir 	// function is called with update mode set to FALSE
816cdf0e10cSrcweir }
817cdf0e10cSrcweir 
SetEditSyntaxColor(EditEngine & rEngine,ScBaseCell * pCell)818cdf0e10cSrcweir void ScOutputData::SetEditSyntaxColor( EditEngine& rEngine, ScBaseCell* pCell )
819cdf0e10cSrcweir {
820cdf0e10cSrcweir 	if (pCell)
821cdf0e10cSrcweir 	{
822cdf0e10cSrcweir 		Color aColor;
823cdf0e10cSrcweir 		switch (pCell->GetCellType())
824cdf0e10cSrcweir 		{
825cdf0e10cSrcweir 			case CELLTYPE_VALUE:
826cdf0e10cSrcweir 				aColor = *pValueColor;
827cdf0e10cSrcweir 				break;
828cdf0e10cSrcweir 			case CELLTYPE_STRING:
829cdf0e10cSrcweir 				aColor = *pTextColor;
830cdf0e10cSrcweir 				break;
831cdf0e10cSrcweir 			case CELLTYPE_FORMULA:
832cdf0e10cSrcweir 				aColor = *pFormulaColor;
833cdf0e10cSrcweir 				break;
834cdf0e10cSrcweir             default:
835cdf0e10cSrcweir             {
836cdf0e10cSrcweir                 // added to avoid warnings
837cdf0e10cSrcweir             }
838cdf0e10cSrcweir 		}
839cdf0e10cSrcweir 		lcl_SetEditColor( rEngine, aColor );
840cdf0e10cSrcweir 	}
841cdf0e10cSrcweir }
842cdf0e10cSrcweir 
GetMergeOrigin(SCCOL nX,SCROW nY,SCSIZE nArrY,SCCOL & rOverX,SCROW & rOverY,sal_Bool bVisRowChanged)843cdf0e10cSrcweir sal_Bool ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY,
844cdf0e10cSrcweir 									SCCOL& rOverX, SCROW& rOverY,
845cdf0e10cSrcweir 									sal_Bool bVisRowChanged )
846cdf0e10cSrcweir {
847cdf0e10cSrcweir 	sal_Bool bDoMerge = sal_False;
848cdf0e10cSrcweir 	sal_Bool bIsLeft = ( nX == nVisX1 );
849cdf0e10cSrcweir 	sal_Bool bIsTop  = ( nY == nVisY1 ) || bVisRowChanged;
850cdf0e10cSrcweir 
851cdf0e10cSrcweir 	CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
852cdf0e10cSrcweir 	if ( pInfo->bHOverlapped && pInfo->bVOverlapped )
853cdf0e10cSrcweir 		bDoMerge = bIsLeft && bIsTop;
854cdf0e10cSrcweir 	else if ( pInfo->bHOverlapped )
855cdf0e10cSrcweir 		bDoMerge = bIsLeft;
856cdf0e10cSrcweir 	else if ( pInfo->bVOverlapped )
857cdf0e10cSrcweir 		bDoMerge = bIsTop;
858cdf0e10cSrcweir 
859cdf0e10cSrcweir 									// weiter solange versteckt
860cdf0e10cSrcweir /*	if (!bDoMerge)
861cdf0e10cSrcweir 		return sal_False;
862cdf0e10cSrcweir */
863cdf0e10cSrcweir 
864cdf0e10cSrcweir 	rOverX = nX;
865cdf0e10cSrcweir 	rOverY = nY;
866cdf0e10cSrcweir 	sal_Bool bHOver = pInfo->bHOverlapped;
867cdf0e10cSrcweir 	sal_Bool bVOver = pInfo->bVOverlapped;
868cdf0e10cSrcweir 	sal_Bool bHidden;
869cdf0e10cSrcweir 
870cdf0e10cSrcweir 	while (bHOver)				// nY konstant
871cdf0e10cSrcweir 	{
872cdf0e10cSrcweir 		--rOverX;
873cdf0e10cSrcweir         bHidden = pDoc->ColHidden(rOverX, nTab);
874cdf0e10cSrcweir 		if ( !bDoMerge && !bHidden )
875cdf0e10cSrcweir 			return sal_False;
876cdf0e10cSrcweir 
877cdf0e10cSrcweir 		if (rOverX >= nX1 && !bHidden)
878cdf0e10cSrcweir 		{
879cdf0e10cSrcweir //			rVirtPosX -= pRowInfo[0].pCellInfo[rOverX+1].nWidth;
880cdf0e10cSrcweir 			bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
881cdf0e10cSrcweir 			bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
882cdf0e10cSrcweir 		}
883cdf0e10cSrcweir 		else
884cdf0e10cSrcweir 		{
885cdf0e10cSrcweir //			if (!bClipVirt)
886cdf0e10cSrcweir //				rVirtPosX -= (long) (pDoc->GetColWidth( rOverX, nTab ) * nPPTX);
887cdf0e10cSrcweir 			sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
888cdf0e10cSrcweir 								rOverX, rOverY, nTab, ATTR_MERGE_FLAG ))->GetValue();
889cdf0e10cSrcweir 			bHOver = ((nOverlap & SC_MF_HOR) != 0);
890cdf0e10cSrcweir 			bVOver = ((nOverlap & SC_MF_VER) != 0);
891cdf0e10cSrcweir 		}
892cdf0e10cSrcweir 	}
893cdf0e10cSrcweir 
894cdf0e10cSrcweir 	while (bVOver)
895cdf0e10cSrcweir 	{
896cdf0e10cSrcweir 		--rOverY;
897cdf0e10cSrcweir         bHidden = pDoc->RowHidden(rOverY, nTab);
898cdf0e10cSrcweir 		if ( !bDoMerge && !bHidden )
899cdf0e10cSrcweir 			return sal_False;
900cdf0e10cSrcweir 
901cdf0e10cSrcweir 		if (nArrY>0)
902cdf0e10cSrcweir 			--nArrY;						// lokale Kopie !
903cdf0e10cSrcweir 
904cdf0e10cSrcweir 		if (rOverX >= nX1 && rOverY >= nY1 &&
905cdf0e10cSrcweir             !pDoc->ColHidden(rOverX, nTab) &&
906cdf0e10cSrcweir             !pDoc->RowHidden(rOverY, nTab) &&
907cdf0e10cSrcweir 			pRowInfo[nArrY].nRowNo == rOverY)
908cdf0e10cSrcweir 		{
909cdf0e10cSrcweir //			rVirtPosY -= pRowInfo[nArrY].nHeight;
910cdf0e10cSrcweir 			bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
911cdf0e10cSrcweir 			bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
912cdf0e10cSrcweir 		}
913cdf0e10cSrcweir 		else
914cdf0e10cSrcweir 		{
915cdf0e10cSrcweir //			if (!bClipVirt)
916cdf0e10cSrcweir //				rVirtPosY -= (long) (pDoc->GetRowHeight( rOverY, nTab ) * nPPTY);
917cdf0e10cSrcweir 			sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
918cdf0e10cSrcweir 								rOverX, rOverY, nTab, ATTR_MERGE_FLAG ))->GetValue();
919cdf0e10cSrcweir 			bHOver = ((nOverlap & SC_MF_HOR) != 0);
920cdf0e10cSrcweir 			bVOver = ((nOverlap & SC_MF_VER) != 0);
921cdf0e10cSrcweir 		}
922cdf0e10cSrcweir 	}
923cdf0e10cSrcweir 
924cdf0e10cSrcweir 	return sal_True;
925cdf0e10cSrcweir }
926cdf0e10cSrcweir 
StringDiffer(const ScPatternAttr * & rpOldPattern,const ScPatternAttr * & rpNewPattern)927cdf0e10cSrcweir inline sal_Bool StringDiffer( const ScPatternAttr*& rpOldPattern, const ScPatternAttr*& rpNewPattern )
928cdf0e10cSrcweir {
929cdf0e10cSrcweir 	DBG_ASSERT( rpNewPattern, "pNewPattern" );
930cdf0e10cSrcweir 
931cdf0e10cSrcweir 	if ( rpNewPattern == rpOldPattern )
932cdf0e10cSrcweir 		return sal_False;
933cdf0e10cSrcweir 	else if ( !rpOldPattern )
934cdf0e10cSrcweir 		return sal_True;
935cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT ) != &rpOldPattern->GetItem( ATTR_FONT ) )
936cdf0e10cSrcweir 		return sal_True;
937cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT ) )
938cdf0e10cSrcweir 		return sal_True;
939cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT ) )
940cdf0e10cSrcweir 		return sal_True;
941cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_HEIGHT ) )
942cdf0e10cSrcweir 		return sal_True;
943cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) )
944cdf0e10cSrcweir 		return sal_True;
945cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) )
946cdf0e10cSrcweir 		return sal_True;
947cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_WEIGHT ) )
948cdf0e10cSrcweir 		return sal_True;
949cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) )
950cdf0e10cSrcweir 		return sal_True;
951cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) )
952cdf0e10cSrcweir 		return sal_True;
953cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_FONT_POSTURE ) )
954cdf0e10cSrcweir 		return sal_True;
955cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_POSTURE ) )
956cdf0e10cSrcweir 		return sal_True;
957cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_POSTURE ) )
958cdf0e10cSrcweir 		return sal_True;
959cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_UNDERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_UNDERLINE ) )
960cdf0e10cSrcweir 		return sal_True;
961cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_OVERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_OVERLINE ) )
962cdf0e10cSrcweir 		return sal_True;
963cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_WORDLINE ) != &rpOldPattern->GetItem( ATTR_FONT_WORDLINE ) )
964cdf0e10cSrcweir 		return sal_True;
965cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_CROSSEDOUT ) != &rpOldPattern->GetItem( ATTR_FONT_CROSSEDOUT ) )
966cdf0e10cSrcweir 		return sal_True;
967cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_CONTOUR ) != &rpOldPattern->GetItem( ATTR_FONT_CONTOUR ) )
968cdf0e10cSrcweir 		return sal_True;
969cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_SHADOWED ) != &rpOldPattern->GetItem( ATTR_FONT_SHADOWED ) )
970cdf0e10cSrcweir 		return sal_True;
971cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_COLOR ) != &rpOldPattern->GetItem( ATTR_FONT_COLOR ) )
972cdf0e10cSrcweir 		return sal_True;
973cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_HOR_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY ) )
974cdf0e10cSrcweir 		return sal_True;
975cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_VER_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_VER_JUSTIFY ) )
976cdf0e10cSrcweir 		return sal_True;
977cdf0e10cSrcweir     else if ( &rpNewPattern->GetItem( ATTR_STACKED ) != &rpOldPattern->GetItem( ATTR_STACKED ) )
978cdf0e10cSrcweir 		return sal_True;
979cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_LINEBREAK ) != &rpOldPattern->GetItem( ATTR_LINEBREAK ) )
980cdf0e10cSrcweir 		return sal_True;
981cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_MARGIN ) != &rpOldPattern->GetItem( ATTR_MARGIN ) )
982cdf0e10cSrcweir 		return sal_True;
983cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_ROTATE_VALUE ) != &rpOldPattern->GetItem( ATTR_ROTATE_VALUE ) )
984cdf0e10cSrcweir 		return sal_True;
985cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FORBIDDEN_RULES ) != &rpOldPattern->GetItem( ATTR_FORBIDDEN_RULES ) )
986cdf0e10cSrcweir 		return sal_True;
987cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_EMPHASISMARK ) != &rpOldPattern->GetItem( ATTR_FONT_EMPHASISMARK ) )
988cdf0e10cSrcweir 		return sal_True;
989cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_FONT_RELIEF ) != &rpOldPattern->GetItem( ATTR_FONT_RELIEF ) )
990cdf0e10cSrcweir 		return sal_True;
991cdf0e10cSrcweir 	else if ( &rpNewPattern->GetItem( ATTR_BACKGROUND ) != &rpOldPattern->GetItem( ATTR_BACKGROUND ) )
992cdf0e10cSrcweir 		return sal_True;	// needed with automatic text color
993cdf0e10cSrcweir 	else
994cdf0e10cSrcweir 	{
995cdf0e10cSrcweir 		rpOldPattern = rpNewPattern;
996cdf0e10cSrcweir 		return sal_False;
997cdf0e10cSrcweir 	}
998cdf0e10cSrcweir }
999cdf0e10cSrcweir 
lcl_CreateInterpretProgress(sal_Bool & bProgress,ScDocument * pDoc,ScFormulaCell * pFCell)1000cdf0e10cSrcweir inline void lcl_CreateInterpretProgress( sal_Bool& bProgress, ScDocument* pDoc,
1001cdf0e10cSrcweir 		ScFormulaCell* pFCell )
1002cdf0e10cSrcweir {
1003cdf0e10cSrcweir 	if ( !bProgress && pFCell->GetDirty() )
1004cdf0e10cSrcweir 	{
1005cdf0e10cSrcweir 		ScProgress::CreateInterpretProgress( pDoc, sal_True );
1006cdf0e10cSrcweir 		bProgress = sal_True;
1007cdf0e10cSrcweir 	}
1008cdf0e10cSrcweir }
1009cdf0e10cSrcweir 
GetScriptType(ScDocument * pDoc,ScBaseCell * pCell,const ScPatternAttr * pPattern,const SfxItemSet * pCondSet)1010cdf0e10cSrcweir inline sal_uInt8 GetScriptType( ScDocument* pDoc, ScBaseCell* pCell,
1011cdf0e10cSrcweir 							const ScPatternAttr* pPattern,
1012cdf0e10cSrcweir 							const SfxItemSet* pCondSet )
1013cdf0e10cSrcweir {
1014cdf0e10cSrcweir 	return pDoc->GetCellScriptType( pCell, pPattern->GetNumberFormat( pDoc->GetFormatTable(), pCondSet ) );
1015cdf0e10cSrcweir }
1016cdf0e10cSrcweir 
IsAmbiguousScript(sal_uInt8 nScript)1017cdf0e10cSrcweir inline sal_Bool IsAmbiguousScript( sal_uInt8 nScript )
1018cdf0e10cSrcweir {
1019cdf0e10cSrcweir 	return ( nScript != SCRIPTTYPE_LATIN &&
1020cdf0e10cSrcweir 			 nScript != SCRIPTTYPE_ASIAN &&
1021cdf0e10cSrcweir 			 nScript != SCRIPTTYPE_COMPLEX );
1022cdf0e10cSrcweir }
1023cdf0e10cSrcweir 
IsEmptyCellText(RowInfo * pThisRowInfo,SCCOL nX,SCROW nY)1024cdf0e10cSrcweir sal_Bool ScOutputData::IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY )
1025cdf0e10cSrcweir {
1026cdf0e10cSrcweir 	// pThisRowInfo may be NULL
1027cdf0e10cSrcweir 
1028cdf0e10cSrcweir 	sal_Bool bEmpty;
1029cdf0e10cSrcweir 	if ( pThisRowInfo && nX <= nX2 )
1030cdf0e10cSrcweir 		bEmpty = pThisRowInfo->pCellInfo[nX+1].bEmptyCellText;
1031cdf0e10cSrcweir 	else
1032cdf0e10cSrcweir 		bEmpty = ( pDoc->GetCell( ScAddress( nX, nY, nTab ) ) == NULL );
1033cdf0e10cSrcweir 
1034cdf0e10cSrcweir 	if ( !bEmpty && ( nX < nX1 || nX > nX2 || !pThisRowInfo ) )
1035cdf0e10cSrcweir 	{
1036cdf0e10cSrcweir 		//	for the range nX1..nX2 in RowInfo, cell protection attribute is already evaluated
1037cdf0e10cSrcweir 		//	into bEmptyCellText in ScDocument::FillInfo / lcl_HidePrint (printfun)
1038cdf0e10cSrcweir 
1039cdf0e10cSrcweir 		sal_Bool bIsPrint = ( eType == OUTTYPE_PRINTER );
1040cdf0e10cSrcweir 
1041cdf0e10cSrcweir 		if ( bIsPrint || bTabProtected )
1042cdf0e10cSrcweir 		{
1043cdf0e10cSrcweir 			const ScProtectionAttr* pAttr = (const ScProtectionAttr*)
1044cdf0e10cSrcweir 					pDoc->GetEffItem( nX, nY, nTab, ATTR_PROTECTION );
1045cdf0e10cSrcweir 			if ( bIsPrint && pAttr->GetHidePrint() )
1046cdf0e10cSrcweir 				bEmpty = sal_True;
1047cdf0e10cSrcweir 			else if ( bTabProtected )
1048cdf0e10cSrcweir 			{
1049cdf0e10cSrcweir 				if ( pAttr->GetHideCell() )
1050cdf0e10cSrcweir 					bEmpty = sal_True;
1051cdf0e10cSrcweir 				else if ( bShowFormulas && pAttr->GetHideFormula() )
1052cdf0e10cSrcweir 				{
1053cdf0e10cSrcweir 					ScBaseCell* pCell = pDoc->GetCell( ScAddress( nX, nY, nTab ) );
1054cdf0e10cSrcweir 					if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
1055cdf0e10cSrcweir 						bEmpty = sal_True;
1056cdf0e10cSrcweir 				}
1057cdf0e10cSrcweir 			}
1058cdf0e10cSrcweir 		}
1059cdf0e10cSrcweir 	}
1060cdf0e10cSrcweir 	return bEmpty;
1061cdf0e10cSrcweir }
1062cdf0e10cSrcweir 
GetVisibleCell(SCCOL nCol,SCROW nRow,SCTAB nTabP,ScBaseCell * & rpCell)1063cdf0e10cSrcweir void ScOutputData::GetVisibleCell( SCCOL nCol, SCROW nRow, SCTAB nTabP, ScBaseCell*& rpCell )
1064cdf0e10cSrcweir {
1065cdf0e10cSrcweir 	pDoc->GetCell( nCol, nRow, nTabP, rpCell );
1066cdf0e10cSrcweir 	if ( rpCell && IsEmptyCellText( NULL, nCol, nRow ) )
1067cdf0e10cSrcweir 		rpCell = NULL;
1068cdf0e10cSrcweir }
1069cdf0e10cSrcweir 
IsAvailable(SCCOL nX,SCROW nY)1070cdf0e10cSrcweir sal_Bool ScOutputData::IsAvailable( SCCOL nX, SCROW nY )
1071cdf0e10cSrcweir {
1072cdf0e10cSrcweir 	//	apply the same logic here as in DrawStrings/DrawEdit:
1073cdf0e10cSrcweir 	//	Stop at non-empty or merged or overlapped cell,
1074cdf0e10cSrcweir 	//	where a note is empty as well as a cell that's hidden by protection settings
1075cdf0e10cSrcweir 
1076cdf0e10cSrcweir 	const ScBaseCell* pCell = pDoc->GetCell( ScAddress( nX, nY, nTab ) );
1077cdf0e10cSrcweir 	if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE && !IsEmptyCellText( NULL, nX, nY ) )
1078cdf0e10cSrcweir 	{
1079cdf0e10cSrcweir 		return sal_False;
1080cdf0e10cSrcweir 	}
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir 	const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
1083cdf0e10cSrcweir 	if ( ((const ScMergeAttr&)pPattern->GetItem(ATTR_MERGE)).IsMerged() ||
1084cdf0e10cSrcweir 		 ((const ScMergeFlagAttr&)pPattern->GetItem(ATTR_MERGE_FLAG)).IsOverlapped() )
1085cdf0e10cSrcweir 	{
1086cdf0e10cSrcweir 		return sal_False;
1087cdf0e10cSrcweir 	}
1088cdf0e10cSrcweir 
1089cdf0e10cSrcweir 	return sal_True;
1090cdf0e10cSrcweir }
1091cdf0e10cSrcweir 
1092cdf0e10cSrcweir // nX, nArrY:		loop variables from DrawStrings / DrawEdit
1093cdf0e10cSrcweir // nPosX, nPosY:	corresponding positions for nX, nArrY
1094cdf0e10cSrcweir // nCellX, nCellY:	position of the cell that contains the text
1095cdf0e10cSrcweir // nNeeded:			Text width, including margin
1096cdf0e10cSrcweir // rPattern:		cell format at nCellX, nCellY
1097cdf0e10cSrcweir // nHorJustify:		horizontal alignment (visual) to determine which cells to use for long strings
1098cdf0e10cSrcweir // bCellIsValue:	if set, don't extend into empty cells
1099cdf0e10cSrcweir // bBreak:			if set, don't extend, and don't set clip marks (but rLeftClip/rRightClip is set)
1100cdf0e10cSrcweir // bOverwrite:		if set, also extend into non-empty cells (for rotated text)
1101cdf0e10cSrcweir // rParam           output: various area parameters.
1102cdf0e10cSrcweir 
GetOutputArea(SCCOL nX,SCSIZE nArrY,long nPosX,long nPosY,SCCOL nCellX,SCROW nCellY,long nNeeded,const ScPatternAttr & rPattern,sal_uInt16 nHorJustify,bool bCellIsValue,bool bBreak,bool bOverwrite,OutputAreaParam & rParam)1103cdf0e10cSrcweir void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY,
1104cdf0e10cSrcweir                                   SCCOL nCellX, SCROW nCellY, long nNeeded,
1105cdf0e10cSrcweir                                   const ScPatternAttr& rPattern,
1106cdf0e10cSrcweir                                   sal_uInt16 nHorJustify, bool bCellIsValue,
1107cdf0e10cSrcweir                                   bool bBreak, bool bOverwrite,
1108cdf0e10cSrcweir                                   OutputAreaParam& rParam )
1109cdf0e10cSrcweir {
1110cdf0e10cSrcweir     //  rThisRowInfo may be for a different row than nCellY, is still used for clip marks
1111cdf0e10cSrcweir 	RowInfo& rThisRowInfo = pRowInfo[nArrY];
1112cdf0e10cSrcweir 
1113cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
1114cdf0e10cSrcweir 
1115cdf0e10cSrcweir     long nCellPosX = nPosX;         // find nCellX position, starting at nX/nPosX
1116cdf0e10cSrcweir 	SCCOL nCompCol = nX;
1117cdf0e10cSrcweir 	while ( nCellX > nCompCol )
1118cdf0e10cSrcweir 	{
1119cdf0e10cSrcweir         //! extra member function for width?
1120cdf0e10cSrcweir 		long nColWidth = ( nCompCol <= nX2 ) ?
1121cdf0e10cSrcweir 				pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
1122cdf0e10cSrcweir 				(long) ( pDoc->GetColWidth( nCompCol, nTab ) * nPPTX );
1123cdf0e10cSrcweir 		nCellPosX += nColWidth * nLayoutSign;
1124cdf0e10cSrcweir 		++nCompCol;
1125cdf0e10cSrcweir 	}
1126cdf0e10cSrcweir 	while ( nCellX < nCompCol )
1127cdf0e10cSrcweir 	{
1128cdf0e10cSrcweir 		--nCompCol;
1129cdf0e10cSrcweir 		long nColWidth = ( nCompCol <= nX2 ) ?
1130cdf0e10cSrcweir 				pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
1131cdf0e10cSrcweir 				(long) ( pDoc->GetColWidth( nCompCol, nTab ) * nPPTX );
1132cdf0e10cSrcweir 		nCellPosX -= nColWidth * nLayoutSign;
1133cdf0e10cSrcweir 	}
1134cdf0e10cSrcweir 
1135cdf0e10cSrcweir     long nCellPosY = nPosY;         // find nCellY position, starting at nArrY/nPosY
1136cdf0e10cSrcweir 	SCSIZE nCompArr = nArrY;
1137cdf0e10cSrcweir 	SCROW nCompRow = pRowInfo[nCompArr].nRowNo;
1138cdf0e10cSrcweir 	while ( nCellY > nCompRow )
1139cdf0e10cSrcweir 	{
1140cdf0e10cSrcweir 		if ( nCompArr + 1 < nArrCount )
1141cdf0e10cSrcweir 		{
1142cdf0e10cSrcweir 			nCellPosY += pRowInfo[nCompArr].nHeight;
1143cdf0e10cSrcweir 			++nCompArr;
1144cdf0e10cSrcweir 			nCompRow = pRowInfo[nCompArr].nRowNo;
1145cdf0e10cSrcweir 		}
1146cdf0e10cSrcweir 		else
1147cdf0e10cSrcweir 		{
1148cdf0e10cSrcweir 			sal_uInt16 nDocHeight = pDoc->GetRowHeight( nCompRow, nTab );
1149cdf0e10cSrcweir 			if ( nDocHeight )
1150cdf0e10cSrcweir 				nCellPosY += (long) ( nDocHeight * nPPTY );
1151cdf0e10cSrcweir 			++nCompRow;
1152cdf0e10cSrcweir 		}
1153cdf0e10cSrcweir 	}
1154cdf0e10cSrcweir     nCellPosY -= (long) pDoc->GetScaledRowHeight( nCellY, nCompRow-1, nTab, nPPTY );
1155cdf0e10cSrcweir 
1156cdf0e10cSrcweir 	const ScMergeAttr* pMerge = (const ScMergeAttr*)&rPattern.GetItem( ATTR_MERGE );
1157cdf0e10cSrcweir 	sal_Bool bMerged = pMerge->IsMerged();
1158cdf0e10cSrcweir 	long nMergeCols = pMerge->GetColMerge();
1159cdf0e10cSrcweir 	if ( nMergeCols == 0 )
1160cdf0e10cSrcweir 		nMergeCols = 1;
1161cdf0e10cSrcweir 	long nMergeRows = pMerge->GetRowMerge();
1162cdf0e10cSrcweir 	if ( nMergeRows == 0 )
1163cdf0e10cSrcweir 		nMergeRows = 1;
1164cdf0e10cSrcweir 
1165cdf0e10cSrcweir 	long i;
1166cdf0e10cSrcweir 	long nMergeSizeX = 0;
1167cdf0e10cSrcweir 	for ( i=0; i<nMergeCols; i++ )
1168cdf0e10cSrcweir 	{
1169cdf0e10cSrcweir 		long nColWidth = ( nCellX+i <= nX2 ) ?
1170cdf0e10cSrcweir 				pRowInfo[0].pCellInfo[nCellX+i+1].nWidth :
1171cdf0e10cSrcweir                 (long) ( pDoc->GetColWidth( sal::static_int_cast<SCCOL>(nCellX+i), nTab ) * nPPTX );
1172cdf0e10cSrcweir 		nMergeSizeX += nColWidth;
1173cdf0e10cSrcweir 	}
1174cdf0e10cSrcweir 	long nMergeSizeY = 0;
1175cdf0e10cSrcweir 	short nDirect = 0;
1176cdf0e10cSrcweir 	if ( rThisRowInfo.nRowNo == nCellY )
1177cdf0e10cSrcweir 	{
1178cdf0e10cSrcweir 		// take first row's height from row info
1179cdf0e10cSrcweir 		nMergeSizeY += rThisRowInfo.nHeight;
1180cdf0e10cSrcweir         nDirect = 1;        // skip in loop
1181cdf0e10cSrcweir 	}
1182cdf0e10cSrcweir     // following rows always from document
1183cdf0e10cSrcweir     nMergeSizeY += (long) pDoc->GetScaledRowHeight( nCellY+nDirect, nCellY+nMergeRows-1, nTab, nPPTY);
1184cdf0e10cSrcweir 
1185cdf0e10cSrcweir     --nMergeSizeX;      // leave out the grid horizontally, also for alignment (align between grid lines)
1186cdf0e10cSrcweir 
1187cdf0e10cSrcweir     rParam.mnColWidth = nMergeSizeX; // store the actual column width.
1188cdf0e10cSrcweir 
1189cdf0e10cSrcweir 	//
1190cdf0e10cSrcweir 	// construct the rectangles using logical left/right values (justify is called at the end)
1191cdf0e10cSrcweir 	//
1192cdf0e10cSrcweir 
1193cdf0e10cSrcweir     //  rAlignRect is the single cell or merged area, used for alignment.
1194cdf0e10cSrcweir 
1195cdf0e10cSrcweir     rParam.maAlignRect.Left() = nCellPosX;
1196cdf0e10cSrcweir     rParam.maAlignRect.Right() = nCellPosX + ( nMergeSizeX - 1 ) * nLayoutSign;
1197cdf0e10cSrcweir     rParam.maAlignRect.Top() = nCellPosY;
1198cdf0e10cSrcweir     rParam.maAlignRect.Bottom() = nCellPosY + nMergeSizeY - 1;
1199cdf0e10cSrcweir 
1200cdf0e10cSrcweir     //  rClipRect is all cells that are used for output.
1201cdf0e10cSrcweir     //  For merged cells this is the same as rAlignRect, otherwise neighboring cells can also be used.
1202cdf0e10cSrcweir 
1203cdf0e10cSrcweir     rParam.maClipRect = rParam.maAlignRect;
1204cdf0e10cSrcweir 	if ( nNeeded > nMergeSizeX )
1205cdf0e10cSrcweir 	{
1206cdf0e10cSrcweir 		SvxCellHorJustify eHorJust = (SvxCellHorJustify)nHorJustify;
1207cdf0e10cSrcweir 
1208cdf0e10cSrcweir 		long nMissing = nNeeded - nMergeSizeX;
1209cdf0e10cSrcweir 		long nLeftMissing = 0;
1210cdf0e10cSrcweir 		long nRightMissing = 0;
1211cdf0e10cSrcweir 		switch ( eHorJust )
1212cdf0e10cSrcweir 		{
1213cdf0e10cSrcweir 			case SVX_HOR_JUSTIFY_LEFT:
1214cdf0e10cSrcweir 				nRightMissing = nMissing;
1215cdf0e10cSrcweir 				break;
1216cdf0e10cSrcweir 			case SVX_HOR_JUSTIFY_RIGHT:
1217cdf0e10cSrcweir 				nLeftMissing = nMissing;
1218cdf0e10cSrcweir 				break;
1219cdf0e10cSrcweir 			case SVX_HOR_JUSTIFY_CENTER:
1220cdf0e10cSrcweir 				nLeftMissing = nMissing / 2;
1221cdf0e10cSrcweir 				nRightMissing = nMissing - nLeftMissing;
1222cdf0e10cSrcweir 				break;
1223cdf0e10cSrcweir             default:
1224cdf0e10cSrcweir             {
1225cdf0e10cSrcweir                 // added to avoid warnings
1226cdf0e10cSrcweir             }
1227cdf0e10cSrcweir 		}
1228cdf0e10cSrcweir 
1229cdf0e10cSrcweir 		// nLeftMissing, nRightMissing are logical, eHorJust values are visual
1230cdf0e10cSrcweir 		if ( bLayoutRTL )
1231cdf0e10cSrcweir 			::std::swap( nLeftMissing, nRightMissing );
1232cdf0e10cSrcweir 
1233cdf0e10cSrcweir 		SCCOL nRightX = nCellX;
1234cdf0e10cSrcweir 		SCCOL nLeftX = nCellX;
1235cdf0e10cSrcweir 		if ( !bMerged && !bCellIsValue && !bBreak )
1236cdf0e10cSrcweir 		{
1237cdf0e10cSrcweir             //  look for empty cells into which the text can be extended
1238cdf0e10cSrcweir 
1239cdf0e10cSrcweir 			while ( nRightMissing > 0 && nRightX < MAXCOL && ( bOverwrite || IsAvailable( nRightX+1, nCellY ) ) )
1240cdf0e10cSrcweir 			{
1241cdf0e10cSrcweir 				++nRightX;
1242cdf0e10cSrcweir 				long nAdd = (long) ( pDoc->GetColWidth( nRightX, nTab ) * nPPTX );
1243cdf0e10cSrcweir 				nRightMissing -= nAdd;
1244cdf0e10cSrcweir                 rParam.maClipRect.Right() += nAdd * nLayoutSign;
1245cdf0e10cSrcweir 
1246cdf0e10cSrcweir 				if ( rThisRowInfo.nRowNo == nCellY && nRightX >= nX1 && nRightX <= nX2 )
1247cdf0e10cSrcweir 					rThisRowInfo.pCellInfo[nRightX].bHideGrid = sal_True;
1248cdf0e10cSrcweir 			}
1249cdf0e10cSrcweir 
1250cdf0e10cSrcweir 			while ( nLeftMissing > 0 && nLeftX > 0 && ( bOverwrite || IsAvailable( nLeftX-1, nCellY ) ) )
1251cdf0e10cSrcweir 			{
1252cdf0e10cSrcweir 				if ( rThisRowInfo.nRowNo == nCellY && nLeftX >= nX1 && nLeftX <= nX2 )
1253cdf0e10cSrcweir 					rThisRowInfo.pCellInfo[nLeftX].bHideGrid = sal_True;
1254cdf0e10cSrcweir 
1255cdf0e10cSrcweir 				--nLeftX;
1256cdf0e10cSrcweir 				long nAdd = (long) ( pDoc->GetColWidth( nLeftX, nTab ) * nPPTX );
1257cdf0e10cSrcweir 				nLeftMissing -= nAdd;
1258cdf0e10cSrcweir                 rParam.maClipRect.Left() -= nAdd * nLayoutSign;
1259cdf0e10cSrcweir 			}
1260cdf0e10cSrcweir 		}
1261cdf0e10cSrcweir 
1262cdf0e10cSrcweir         //  Set flag and reserve space for clipping mark triangle,
1263cdf0e10cSrcweir         //  even if rThisRowInfo isn't for nCellY (merged cells).
1264cdf0e10cSrcweir 		if ( nRightMissing > 0 && bMarkClipped && nRightX >= nX1 && nRightX <= nX2 && !bBreak && !bCellIsValue )
1265cdf0e10cSrcweir 		{
1266cdf0e10cSrcweir 			rThisRowInfo.pCellInfo[nRightX+1].nClipMark |= SC_CLIPMARK_RIGHT;
1267cdf0e10cSrcweir 			bAnyClipped = sal_True;
1268cdf0e10cSrcweir 			long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
1269cdf0e10cSrcweir             rParam.maClipRect.Right() -= nMarkPixel * nLayoutSign;
1270cdf0e10cSrcweir 		}
1271cdf0e10cSrcweir 		if ( nLeftMissing > 0 && bMarkClipped && nLeftX >= nX1 && nLeftX <= nX2 && !bBreak && !bCellIsValue )
1272cdf0e10cSrcweir 		{
1273cdf0e10cSrcweir 			rThisRowInfo.pCellInfo[nLeftX+1].nClipMark |= SC_CLIPMARK_LEFT;
1274cdf0e10cSrcweir 			bAnyClipped = sal_True;
1275cdf0e10cSrcweir 			long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
1276cdf0e10cSrcweir             rParam.maClipRect.Left() += nMarkPixel * nLayoutSign;
1277cdf0e10cSrcweir 		}
1278cdf0e10cSrcweir 
1279cdf0e10cSrcweir         rParam.mbLeftClip = ( nLeftMissing > 0 );
1280cdf0e10cSrcweir         rParam.mbRightClip = ( nRightMissing > 0 );
1281cdf0e10cSrcweir 	}
1282cdf0e10cSrcweir 	else
1283cdf0e10cSrcweir 	{
1284cdf0e10cSrcweir         rParam.mbLeftClip = rParam.mbRightClip = sal_False;
1285cdf0e10cSrcweir 
1286cdf0e10cSrcweir         // leave space for AutoFilter on screen
1287cdf0e10cSrcweir 		// (for automatic line break: only if not formatting for printer, as in ScColumn::GetNeededSize)
1288cdf0e10cSrcweir 
1289cdf0e10cSrcweir         if ( eType==OUTTYPE_WINDOW &&
1290cdf0e10cSrcweir              ( static_cast<const ScMergeFlagAttr&>(rPattern.GetItem(ATTR_MERGE_FLAG)).GetValue() & SC_MF_AUTO ) &&
1291cdf0e10cSrcweir              ( !bBreak || pRefDevice == pFmtDevice ) )
1292cdf0e10cSrcweir         {
1293cdf0e10cSrcweir             // filter drop-down width is now independent from row height
1294cdf0e10cSrcweir             const long nFilter = DROPDOWN_BITMAP_SIZE;
1295cdf0e10cSrcweir             sal_Bool bFit = ( nNeeded + nFilter <= nMergeSizeX );
1296cdf0e10cSrcweir             if ( bFit || bCellIsValue )
1297cdf0e10cSrcweir             {
1298cdf0e10cSrcweir                 // content fits even in the remaining area without the filter button
1299cdf0e10cSrcweir                 // -> align within that remaining area
1300cdf0e10cSrcweir 
1301cdf0e10cSrcweir                 rParam.maAlignRect.Right() -= nFilter * nLayoutSign;
1302cdf0e10cSrcweir                 rParam.maClipRect.Right() -= nFilter * nLayoutSign;
1303cdf0e10cSrcweir 
1304cdf0e10cSrcweir                 // if a number doesn't fit, don't hide part of the number behind the button
1305cdf0e10cSrcweir                 // -> set clip flags, so "###" replacement is used (but also within the smaller area)
1306cdf0e10cSrcweir 
1307cdf0e10cSrcweir                 if ( !bFit )
1308cdf0e10cSrcweir                     rParam.mbLeftClip = rParam.mbRightClip = sal_True;
1309cdf0e10cSrcweir             }
1310cdf0e10cSrcweir         }
1311cdf0e10cSrcweir 	}
1312cdf0e10cSrcweir 
1313cdf0e10cSrcweir     //  justify both rectangles for alignment calculation, use with DrawText etc.
1314cdf0e10cSrcweir 
1315cdf0e10cSrcweir     rParam.maAlignRect.Justify();
1316cdf0e10cSrcweir     rParam.maClipRect.Justify();
1317cdf0e10cSrcweir 
1318cdf0e10cSrcweir #if 0
1319cdf0e10cSrcweir 	//! Test !!!
1320cdf0e10cSrcweir 	pDev->Push();
1321cdf0e10cSrcweir 	pDev->SetLineColor();
1322cdf0e10cSrcweir 	pDev->SetFillColor( COL_LIGHTGREEN );
1323cdf0e10cSrcweir     pDev->DrawRect( pDev->PixelToLogic(rParam.maClipRect) );
1324cdf0e10cSrcweir     pDev->DrawRect( rParam.maClipRect );    // print preview
1325cdf0e10cSrcweir 	pDev->Pop();
1326cdf0e10cSrcweir 	//! Test !!!
1327cdf0e10cSrcweir #endif
1328cdf0e10cSrcweir }
1329cdf0e10cSrcweir 
DrawStrings(sal_Bool bPixelToLogic)1330cdf0e10cSrcweir void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
1331cdf0e10cSrcweir {
1332cdf0e10cSrcweir 	DBG_ASSERT( pDev == pRefDevice ||
1333cdf0e10cSrcweir 				pDev->GetMapMode().GetMapUnit() == pRefDevice->GetMapMode().GetMapUnit(),
1334cdf0e10cSrcweir 				"DrawStrings: unterschiedliche MapUnits ?!?!" );
1335cdf0e10cSrcweir 
1336cdf0e10cSrcweir     vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
1337cdf0e10cSrcweir 
1338cdf0e10cSrcweir 	sal_Bool bWasIdleDisabled = pDoc->IsIdleDisabled();
1339cdf0e10cSrcweir 	pDoc->DisableIdle( sal_True );
1340cdf0e10cSrcweir 	Size aMinSize = pRefDevice->PixelToLogic(Size(0,100));		// erst darueber wird ausgegeben
1341cdf0e10cSrcweir //    sal_uInt32 nMinHeight = aMinSize.Height() / 200;                // 1/2 Pixel
1342cdf0e10cSrcweir 
1343cdf0e10cSrcweir 	ScDrawStringsVars aVars( this, bPixelToLogic );
1344cdf0e10cSrcweir 
1345cdf0e10cSrcweir 	sal_Bool bProgress = sal_False;
1346cdf0e10cSrcweir 
1347cdf0e10cSrcweir 	long nInitPosX = nScrX;
1348cdf0e10cSrcweir 	if ( bLayoutRTL )
1349cdf0e10cSrcweir 		nInitPosX += nMirrorW - 1;				// pixels
1350cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir 	SCCOL nLastContentCol = MAXCOL;
1353cdf0e10cSrcweir 	if ( nX2 < MAXCOL )
1354cdf0e10cSrcweir         nLastContentCol = sal::static_int_cast<SCCOL>(
1355cdf0e10cSrcweir             nLastContentCol - pDoc->GetEmptyLinesInBlock( nX2+1, nY1, nTab, MAXCOL, nY2, nTab, DIR_RIGHT ) );
1356cdf0e10cSrcweir 	SCCOL nLoopStartX = nX1;
1357cdf0e10cSrcweir 	if ( nX1 > 0 )
1358cdf0e10cSrcweir 		--nLoopStartX;			// start before nX1 for rest of long text to the left
1359cdf0e10cSrcweir 
1360cdf0e10cSrcweir 	// variables for GetOutputArea
1361cdf0e10cSrcweir     OutputAreaParam aAreaParam;
1362cdf0e10cSrcweir 	sal_Bool bCellIsValue = sal_False;
1363cdf0e10cSrcweir 	long nNeededWidth = 0;
1364cdf0e10cSrcweir 	SvxCellHorJustify eOutHorJust = SVX_HOR_JUSTIFY_STANDARD;
1365cdf0e10cSrcweir 	const ScPatternAttr* pPattern = NULL;
1366cdf0e10cSrcweir 	const SfxItemSet* pCondSet = NULL;
1367cdf0e10cSrcweir     const ScPatternAttr* pOldPattern = NULL;
1368cdf0e10cSrcweir     const SfxItemSet* pOldCondSet = NULL;
1369cdf0e10cSrcweir     sal_uInt8 nOldScript = 0;
1370cdf0e10cSrcweir 
1371cdf0e10cSrcweir 	long nPosY = nScrY;
1372cdf0e10cSrcweir 	for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
1373cdf0e10cSrcweir 	{
1374cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1375cdf0e10cSrcweir 		if ( pThisRowInfo->bChanged )
1376cdf0e10cSrcweir 		{
1377cdf0e10cSrcweir 			SCROW nY = pThisRowInfo->nRowNo;
1378cdf0e10cSrcweir //            long nCellHeight = (long) pThisRowInfo->nHeight;
1379cdf0e10cSrcweir 			long nPosX = nInitPosX;
1380cdf0e10cSrcweir 			if ( nLoopStartX < nX1 )
1381cdf0e10cSrcweir 				nPosX -= pRowInfo[0].pCellInfo[nLoopStartX+1].nWidth * nLayoutSign;
1382cdf0e10cSrcweir 			for (SCCOL nX=nLoopStartX; nX<=nX2; nX++)
1383cdf0e10cSrcweir 			{
1384cdf0e10cSrcweir 				sal_Bool bMergeEmpty = sal_False;
1385cdf0e10cSrcweir 				CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
1386cdf0e10cSrcweir 				sal_Bool bEmpty = nX < nX1 || pInfo->bEmptyCellText;
1387cdf0e10cSrcweir 
1388cdf0e10cSrcweir 				SCCOL nCellX = nX;					// position where the cell really starts
1389cdf0e10cSrcweir 				SCROW nCellY = nY;
1390cdf0e10cSrcweir 				sal_Bool bDoCell = sal_False;
1391cdf0e10cSrcweir 				sal_Bool bNeedEdit = sal_False;
1392cdf0e10cSrcweir 
1393cdf0e10cSrcweir 				//
1394cdf0e10cSrcweir 				//	Part of a merged cell?
1395cdf0e10cSrcweir 				//
1396cdf0e10cSrcweir 
1397cdf0e10cSrcweir                 sal_Bool bOverlapped = ( pInfo->bHOverlapped || pInfo->bVOverlapped );
1398cdf0e10cSrcweir                 if ( bOverlapped )
1399cdf0e10cSrcweir 				{
1400cdf0e10cSrcweir 					bEmpty = sal_True;
1401cdf0e10cSrcweir 
1402cdf0e10cSrcweir 					SCCOL nOverX;					// start of the merged cells
1403cdf0e10cSrcweir 					SCROW nOverY;
1404cdf0e10cSrcweir 					sal_Bool bVisChanged = !pRowInfo[nArrY-1].bChanged;
1405cdf0e10cSrcweir 					if (GetMergeOrigin( nX,nY, nArrY, nOverX,nOverY, bVisChanged ))
1406cdf0e10cSrcweir 					{
1407cdf0e10cSrcweir 						nCellX = nOverX;
1408cdf0e10cSrcweir 						nCellY = nOverY;
1409cdf0e10cSrcweir 						bDoCell = sal_True;
1410cdf0e10cSrcweir 					}
1411cdf0e10cSrcweir 					else
1412cdf0e10cSrcweir 						bMergeEmpty = sal_True;
1413cdf0e10cSrcweir 				}
1414cdf0e10cSrcweir 
1415cdf0e10cSrcweir 				//
1416cdf0e10cSrcweir 				//	Rest of a long text further to the left?
1417cdf0e10cSrcweir 				//
1418cdf0e10cSrcweir 
1419cdf0e10cSrcweir 				if ( bEmpty && !bMergeEmpty && nX < nX1 && !bOverlapped )
1420cdf0e10cSrcweir 				{
1421cdf0e10cSrcweir 					SCCOL nTempX=nX1;
1422cdf0e10cSrcweir 					while (nTempX > 0 && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
1423cdf0e10cSrcweir 						--nTempX;
1424cdf0e10cSrcweir 
1425cdf0e10cSrcweir 					if ( nTempX < nX1 &&
1426cdf0e10cSrcweir 						 !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
1427cdf0e10cSrcweir 						 !pDoc->HasAttrib( nTempX,nY,nTab, nX1,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
1428cdf0e10cSrcweir 					{
1429cdf0e10cSrcweir 						nCellX = nTempX;
1430cdf0e10cSrcweir 						bDoCell = sal_True;
1431cdf0e10cSrcweir 					}
1432cdf0e10cSrcweir 				}
1433cdf0e10cSrcweir 
1434cdf0e10cSrcweir 				//
1435cdf0e10cSrcweir 				//	Rest of a long text further to the right?
1436cdf0e10cSrcweir 				//
1437cdf0e10cSrcweir 
1438cdf0e10cSrcweir 				if ( bEmpty && !bMergeEmpty && nX == nX2 && !bOverlapped )
1439cdf0e10cSrcweir 				{
1440cdf0e10cSrcweir 					//	don't have to look further than nLastContentCol
1441cdf0e10cSrcweir 
1442cdf0e10cSrcweir 					SCCOL nTempX=nX;
1443cdf0e10cSrcweir 					while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
1444cdf0e10cSrcweir 						++nTempX;
1445cdf0e10cSrcweir 
1446cdf0e10cSrcweir 					if ( nTempX > nX &&
1447cdf0e10cSrcweir 						 !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
1448cdf0e10cSrcweir 						 !pDoc->HasAttrib( nTempX,nY,nTab, nX,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
1449cdf0e10cSrcweir 					{
1450cdf0e10cSrcweir 						nCellX = nTempX;
1451cdf0e10cSrcweir 						bDoCell = sal_True;
1452cdf0e10cSrcweir 					}
1453cdf0e10cSrcweir 				}
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir 				//
1456cdf0e10cSrcweir 				//	normal visible cell
1457cdf0e10cSrcweir 				//
1458cdf0e10cSrcweir 
1459cdf0e10cSrcweir 				if (!bEmpty)
1460cdf0e10cSrcweir 					bDoCell = sal_True;
1461cdf0e10cSrcweir 
1462cdf0e10cSrcweir 				//
1463cdf0e10cSrcweir 				//	don't output the cell that's being edited
1464cdf0e10cSrcweir 				//
1465cdf0e10cSrcweir 
1466cdf0e10cSrcweir 				if ( bDoCell && bEditMode && nCellX == nEditCol && nCellY == nEditRow )
1467cdf0e10cSrcweir 					bDoCell = sal_False;
1468cdf0e10cSrcweir 
1469cdf0e10cSrcweir 				//
1470cdf0e10cSrcweir 				//	output the cell text
1471cdf0e10cSrcweir 				//
1472cdf0e10cSrcweir 
1473cdf0e10cSrcweir 				ScBaseCell* pCell = NULL;
1474cdf0e10cSrcweir 				if (bDoCell)
1475cdf0e10cSrcweir 				{
1476cdf0e10cSrcweir 					if ( nCellY == nY && nCellX == nX && nCellX >= nX1 && nCellX <= nX2 )
1477cdf0e10cSrcweir 						pCell = pThisRowInfo->pCellInfo[nCellX+1].pCell;
1478cdf0e10cSrcweir 					else
1479cdf0e10cSrcweir 						GetVisibleCell( nCellX, nCellY, nTab, pCell );		// get from document
1480cdf0e10cSrcweir 					if ( !pCell )
1481cdf0e10cSrcweir 						bDoCell = sal_False;
1482cdf0e10cSrcweir 					else if ( pCell->GetCellType() == CELLTYPE_EDIT )
1483cdf0e10cSrcweir 						bNeedEdit = sal_True;
1484cdf0e10cSrcweir 				}
1485cdf0e10cSrcweir 				if (bDoCell && !bNeedEdit)
1486cdf0e10cSrcweir 				{
1487cdf0e10cSrcweir 					if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 )
1488cdf0e10cSrcweir 					{
1489cdf0e10cSrcweir 						CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1];
1490cdf0e10cSrcweir 						pPattern = rCellInfo.pPatternAttr;
1491cdf0e10cSrcweir 						pCondSet = rCellInfo.pConditionSet;
1492cdf0e10cSrcweir 
1493cdf0e10cSrcweir                         if ( !pPattern )
1494cdf0e10cSrcweir                         {
1495cdf0e10cSrcweir                             // #i68085# pattern from cell info for hidden columns is null,
1496cdf0e10cSrcweir                             // test for null is quicker than using column flags
1497cdf0e10cSrcweir                             pPattern = pDoc->GetPattern( nCellX, nCellY, nTab );
1498cdf0e10cSrcweir                             pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab );
1499cdf0e10cSrcweir                         }
1500cdf0e10cSrcweir 					}
1501cdf0e10cSrcweir 					else		// get from document
1502cdf0e10cSrcweir 					{
1503cdf0e10cSrcweir 						pPattern = pDoc->GetPattern( nCellX, nCellY, nTab );
1504cdf0e10cSrcweir 						pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab );
1505cdf0e10cSrcweir 					}
1506cdf0e10cSrcweir 
1507cdf0e10cSrcweir 					sal_uInt8 nScript = GetScriptType( pDoc, pCell, pPattern, pCondSet );
1508cdf0e10cSrcweir 					if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
1509cdf0e10cSrcweir 					if ( pPattern != pOldPattern || pCondSet != pOldCondSet ||
1510cdf0e10cSrcweir 						 nScript != nOldScript || bSyntaxMode )
1511cdf0e10cSrcweir 					{
1512cdf0e10cSrcweir 						if ( StringDiffer(pOldPattern,pPattern) ||
1513cdf0e10cSrcweir 							 pCondSet != pOldCondSet || nScript != nOldScript || bSyntaxMode )
1514cdf0e10cSrcweir 							aVars.SetPattern( pPattern, pCondSet, pCell, nScript );
1515cdf0e10cSrcweir 						else
1516cdf0e10cSrcweir 							aVars.SetPatternSimple( pPattern, pCondSet );
1517cdf0e10cSrcweir 						pOldPattern = pPattern;
1518cdf0e10cSrcweir 						pOldCondSet = pCondSet;
1519cdf0e10cSrcweir 						nOldScript = nScript;
1520cdf0e10cSrcweir 					}
1521cdf0e10cSrcweir 
1522cdf0e10cSrcweir 					//	use edit engine for rotated, stacked or mixed-script text
1523cdf0e10cSrcweir 					if ( aVars.GetOrient() == SVX_ORIENTATION_STACKED ||
1524cdf0e10cSrcweir 						 aVars.IsRotated() || IsAmbiguousScript(nScript) )
1525cdf0e10cSrcweir 						bNeedEdit = sal_True;
1526cdf0e10cSrcweir 				}
1527cdf0e10cSrcweir 				if (bDoCell && !bNeedEdit)
1528cdf0e10cSrcweir 				{
1529cdf0e10cSrcweir 					sal_Bool bFormulaCell = (pCell->GetCellType() == CELLTYPE_FORMULA );
1530cdf0e10cSrcweir 					if ( bFormulaCell )
1531cdf0e10cSrcweir 						lcl_CreateInterpretProgress( bProgress, pDoc, (ScFormulaCell*)pCell );
1532cdf0e10cSrcweir 					if ( aVars.SetText(pCell) )
1533cdf0e10cSrcweir 						pOldPattern = NULL;
1534cdf0e10cSrcweir                     bNeedEdit = aVars.HasEditCharacters() ||
1535cdf0e10cSrcweir 					                (bFormulaCell && ((ScFormulaCell*)pCell)->IsMultilineResult());
1536cdf0e10cSrcweir                 }
1537cdf0e10cSrcweir                 long nTotalMargin = 0;
1538cdf0e10cSrcweir                 if (bDoCell && !bNeedEdit)
1539cdf0e10cSrcweir                 {
1540cdf0e10cSrcweir 					CellType eCellType = pCell->GetCellType();
1541cdf0e10cSrcweir 					bCellIsValue = ( eCellType == CELLTYPE_VALUE );
1542cdf0e10cSrcweir 					if ( eCellType == CELLTYPE_FORMULA )
1543cdf0e10cSrcweir 					{
1544cdf0e10cSrcweir 						ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
1545cdf0e10cSrcweir 						bCellIsValue = pFCell->IsRunning() || pFCell->IsValue();
1546cdf0e10cSrcweir 					}
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir 					eOutHorJust = ( aVars.GetHorJust() != SVX_HOR_JUSTIFY_STANDARD ) ?
1549cdf0e10cSrcweir 								  aVars.GetHorJust() :
1550cdf0e10cSrcweir 								  ( bCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
1551cdf0e10cSrcweir 
1552cdf0e10cSrcweir 					if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
1553cdf0e10cSrcweir 						eOutHorJust = SVX_HOR_JUSTIFY_LEFT;		// repeat is not yet implemented
1554cdf0e10cSrcweir 
1555cdf0e10cSrcweir 					sal_Bool bBreak = ( aVars.GetLineBreak() || aVars.GetHorJust() == SVX_HOR_JUSTIFY_BLOCK );
1556cdf0e10cSrcweir 
1557cdf0e10cSrcweir                     // #i111387# #o11817313# disable automatic line breaks only for "General" number format
1558cdf0e10cSrcweir                     if ( bBreak && bCellIsValue && ( aVars.GetResultValueFormat(pCell) % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 )
1559cdf0e10cSrcweir                         bBreak = sal_False;
1560cdf0e10cSrcweir 
1561cdf0e10cSrcweir 					sal_Bool bRepeat = aVars.IsRepeat() && !bBreak;
1562cdf0e10cSrcweir 					sal_Bool bShrink = aVars.IsShrink() && !bBreak && !bRepeat;
1563cdf0e10cSrcweir 
1564cdf0e10cSrcweir                     nTotalMargin =
1565cdf0e10cSrcweir                         static_cast<long>(aVars.GetLeftTotal() * nPPTX) +
1566cdf0e10cSrcweir                         static_cast<long>(aVars.GetMargin()->GetRightMargin() * nPPTX);
1567cdf0e10cSrcweir 
1568cdf0e10cSrcweir                     nNeededWidth = aVars.GetTextSize().Width() + nTotalMargin;
1569cdf0e10cSrcweir 
1570cdf0e10cSrcweir 					// GetOutputArea gives justfied rectangles
1571cdf0e10cSrcweir 					GetOutputArea( nX, nArrY, nPosX, nPosY, nCellX, nCellY, nNeededWidth,
1572cdf0e10cSrcweir                                    *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
1573cdf0e10cSrcweir                                    bCellIsValue || bRepeat || bShrink, bBreak, sal_False,
1574cdf0e10cSrcweir                                    aAreaParam );
1575cdf0e10cSrcweir 
1576cdf0e10cSrcweir                     if ( bShrink )
1577cdf0e10cSrcweir                     {
1578cdf0e10cSrcweir                         if ( aVars.GetOrient() != SVX_ORIENTATION_STANDARD )
1579cdf0e10cSrcweir                         {
1580cdf0e10cSrcweir                             // Only horizontal scaling is handled here.
1581cdf0e10cSrcweir                             // DrawEdit is used to vertically scale 90 deg rotated text.
1582cdf0e10cSrcweir                             bNeedEdit = sal_True;
1583cdf0e10cSrcweir                         }
1584cdf0e10cSrcweir                         else if ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip )     // horizontal
1585cdf0e10cSrcweir                         {
1586cdf0e10cSrcweir                             long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin;
1587cdf0e10cSrcweir                             long nScaleSize = aVars.GetTextSize().Width();         // without margin
1588cdf0e10cSrcweir 
1589cdf0e10cSrcweir                             if ( nScaleSize > 0 )       // 0 if the text is empty (formulas, number formats)
1590cdf0e10cSrcweir                             {
1591cdf0e10cSrcweir                                 long nScale = ( nAvailable * 100 ) / nScaleSize;
1592cdf0e10cSrcweir 
1593cdf0e10cSrcweir                                 aVars.SetShrinkScale( nScale, nOldScript );
1594cdf0e10cSrcweir                                 long nNewSize = aVars.GetTextSize().Width();
1595cdf0e10cSrcweir 
1596cdf0e10cSrcweir                                 sal_uInt16 nShrinkAgain = 0;
1597cdf0e10cSrcweir                                 while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
1598cdf0e10cSrcweir                                 {
1599cdf0e10cSrcweir                                     // If the text is still too large, reduce the scale again by 10%, until it fits,
1600cdf0e10cSrcweir                                     // at most 7 times (it's less than 50% of the calculated scale then).
1601cdf0e10cSrcweir 
1602cdf0e10cSrcweir                                     nScale = ( nScale * 9 ) / 10;
1603cdf0e10cSrcweir                                     aVars.SetShrinkScale( nScale, nOldScript );
1604cdf0e10cSrcweir                                     nNewSize = aVars.GetTextSize().Width();
1605cdf0e10cSrcweir                                     ++nShrinkAgain;
1606cdf0e10cSrcweir                                 }
1607cdf0e10cSrcweir                                 // If even at half the size the font still isn't rendered smaller,
1608cdf0e10cSrcweir                                 // fall back to normal clipping (showing ### for numbers).
1609cdf0e10cSrcweir                                 if ( nNewSize <= nAvailable )
1610cdf0e10cSrcweir                                     aAreaParam.mbLeftClip = aAreaParam.mbRightClip = sal_False;
1611cdf0e10cSrcweir 
1612cdf0e10cSrcweir                                 pOldPattern = NULL;
1613cdf0e10cSrcweir                             }
1614cdf0e10cSrcweir                         }
1615cdf0e10cSrcweir                     }
1616cdf0e10cSrcweir 
1617cdf0e10cSrcweir                     if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip )
1618cdf0e10cSrcweir                     {
1619cdf0e10cSrcweir                         long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin;
1620cdf0e10cSrcweir                         long nRepeatSize = aVars.GetTextSize().Width();         // without margin
1621cdf0e10cSrcweir                         // When formatting for the printer, the text sizes don't always add up.
1622cdf0e10cSrcweir                         // Round down (too few repetitions) rather than exceeding the cell size then:
1623cdf0e10cSrcweir                         if ( pFmtDevice != pRefDevice )
1624cdf0e10cSrcweir                             ++nRepeatSize;
1625cdf0e10cSrcweir                         if ( nRepeatSize > 0 )
1626cdf0e10cSrcweir                         {
1627cdf0e10cSrcweir                             long nRepeatCount = nAvailable / nRepeatSize;
1628cdf0e10cSrcweir                             if ( nRepeatCount > 1 )
1629cdf0e10cSrcweir                             {
1630cdf0e10cSrcweir                                 String aCellStr = aVars.GetString();
1631cdf0e10cSrcweir                                 String aRepeated = aCellStr;
1632cdf0e10cSrcweir                                 for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
1633cdf0e10cSrcweir                                     aRepeated.Append( aCellStr );
1634cdf0e10cSrcweir                                 aVars.SetAutoText( aRepeated );
1635cdf0e10cSrcweir                             }
1636cdf0e10cSrcweir                         }
1637cdf0e10cSrcweir                     }
1638cdf0e10cSrcweir 
1639cdf0e10cSrcweir 					//	use edit engine if automatic line breaks are needed
1640cdf0e10cSrcweir 					if ( bBreak )
1641cdf0e10cSrcweir 					{
1642cdf0e10cSrcweir 						if ( aVars.GetOrient() == SVX_ORIENTATION_STANDARD )
1643cdf0e10cSrcweir                             bNeedEdit = ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip );
1644cdf0e10cSrcweir 						else
1645cdf0e10cSrcweir 						{
1646cdf0e10cSrcweir 							long nHeight = aVars.GetTextSize().Height() +
1647cdf0e10cSrcweir 											(long)(aVars.GetMargin()->GetTopMargin()*nPPTY) +
1648cdf0e10cSrcweir 											(long)(aVars.GetMargin()->GetBottomMargin()*nPPTY);
1649cdf0e10cSrcweir                             bNeedEdit = ( nHeight > aAreaParam.maClipRect.GetHeight() );
1650cdf0e10cSrcweir 						}
1651cdf0e10cSrcweir 					}
1652cdf0e10cSrcweir 				}
1653cdf0e10cSrcweir 				if (bNeedEdit)
1654cdf0e10cSrcweir 				{
1655cdf0e10cSrcweir 					//	mark the cell in CellInfo to be drawn in DrawEdit:
1656cdf0e10cSrcweir 					//	Cells to the left are marked directly, cells to the
1657cdf0e10cSrcweir 					//	right are handled by the flag for nX2
1658cdf0e10cSrcweir 					SCCOL nMarkX = ( nCellX <= nX2 ) ? nCellX : nX2;
1659cdf0e10cSrcweir 					RowInfo* pMarkRowInfo = ( nCellY == nY ) ? pThisRowInfo : &pRowInfo[0];
1660cdf0e10cSrcweir 					pMarkRowInfo->pCellInfo[nMarkX+1].bEditEngine = sal_True;
1661cdf0e10cSrcweir 					bDoCell = sal_False;	// don't draw here
1662cdf0e10cSrcweir 				}
1663cdf0e10cSrcweir 				if ( bDoCell )
1664cdf0e10cSrcweir 				{
1665cdf0e10cSrcweir                     if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
1666cdf0e10cSrcweir 					{
1667cdf0e10cSrcweir                         // Adjust the decimals to fit the available column width.
1668cdf0e10cSrcweir                         aVars.SetTextToWidthOrHash(pCell, aAreaParam.mnColWidth - nTotalMargin);
1669cdf0e10cSrcweir 						nNeededWidth = aVars.GetTextSize().Width() +
1670cdf0e10cSrcweir 									(long) ( aVars.GetLeftTotal() * nPPTX ) +
1671cdf0e10cSrcweir 									(long) ( aVars.GetMargin()->GetRightMargin() * nPPTX );
1672cdf0e10cSrcweir                         if ( nNeededWidth <= aAreaParam.maClipRect.GetWidth() )
1673cdf0e10cSrcweir                             aAreaParam.mbLeftClip = aAreaParam.mbRightClip = sal_False;
1674cdf0e10cSrcweir 
1675cdf0e10cSrcweir 						//	If the "###" replacement doesn't fit into the cells, no clip marks
1676cdf0e10cSrcweir 						//	are shown, as the "###" already denotes too little space.
1677cdf0e10cSrcweir 						//	The rectangles from the first GetOutputArea call remain valid.
1678cdf0e10cSrcweir 					}
1679cdf0e10cSrcweir 
1680cdf0e10cSrcweir                     long nJustPosX = aAreaParam.maAlignRect.Left();		// "justified" - effect of alignment will be added
1681cdf0e10cSrcweir                     long nJustPosY = aAreaParam.maAlignRect.Top();
1682cdf0e10cSrcweir                     long nAvailWidth = aAreaParam.maAlignRect.GetWidth();
1683cdf0e10cSrcweir                     long nOutHeight = aAreaParam.maAlignRect.GetHeight();
1684cdf0e10cSrcweir 
1685cdf0e10cSrcweir                     sal_Bool bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW );
1686cdf0e10cSrcweir                     if ( aAreaParam.maClipRect.Left() < nScrX )
1687cdf0e10cSrcweir 					{
1688cdf0e10cSrcweir                         aAreaParam.maClipRect.Left() = nScrX;
1689cdf0e10cSrcweir                         aAreaParam.mbLeftClip = sal_True;
1690cdf0e10cSrcweir 					}
1691cdf0e10cSrcweir                     if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
1692cdf0e10cSrcweir 					{
1693cdf0e10cSrcweir                         aAreaParam.maClipRect.Right() = nScrX + nScrW;			//! minus one?
1694cdf0e10cSrcweir                         aAreaParam.mbRightClip = sal_True;
1695cdf0e10cSrcweir 					}
1696cdf0e10cSrcweir 
1697cdf0e10cSrcweir                     sal_Bool bHClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
1698cdf0e10cSrcweir 					sal_Bool bVClip = sal_False;
1699cdf0e10cSrcweir 
1700cdf0e10cSrcweir                     if ( aAreaParam.maClipRect.Top() < nScrY )
1701cdf0e10cSrcweir                     {
1702cdf0e10cSrcweir                         aAreaParam.maClipRect.Top() = nScrY;
1703cdf0e10cSrcweir                         bVClip = sal_True;
1704cdf0e10cSrcweir                     }
1705cdf0e10cSrcweir                     if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
1706cdf0e10cSrcweir                     {
1707cdf0e10cSrcweir                         aAreaParam.maClipRect.Bottom() = nScrY + nScrH;         //! minus one?
1708cdf0e10cSrcweir                         bVClip = sal_True;
1709cdf0e10cSrcweir                     }
1710cdf0e10cSrcweir 
1711cdf0e10cSrcweir 					//
1712cdf0e10cSrcweir 					//		horizontalen Platz testen
1713cdf0e10cSrcweir 					//
1714cdf0e10cSrcweir 
1715cdf0e10cSrcweir 					sal_Bool bRightAdjusted = sal_False;		// to correct text width calculation later
1716cdf0e10cSrcweir 					sal_Bool bNeedEditEngine = sal_False;
1717cdf0e10cSrcweir 					if ( !bNeedEditEngine && !bOutside )
1718cdf0e10cSrcweir 					{
1719cdf0e10cSrcweir 						switch (eOutHorJust)
1720cdf0e10cSrcweir 						{
1721cdf0e10cSrcweir 							case SVX_HOR_JUSTIFY_LEFT:
1722cdf0e10cSrcweir 								nJustPosX += (long) ( aVars.GetLeftTotal() * nPPTX );
1723cdf0e10cSrcweir 								break;
1724cdf0e10cSrcweir 							case SVX_HOR_JUSTIFY_RIGHT:
1725cdf0e10cSrcweir 								nJustPosX += nAvailWidth - aVars.GetTextSize().Width() -
1726cdf0e10cSrcweir 											(long) ( aVars.GetMargin()->GetRightMargin() * nPPTX );
1727cdf0e10cSrcweir 								bRightAdjusted = sal_True;
1728cdf0e10cSrcweir 								break;
1729cdf0e10cSrcweir 							case SVX_HOR_JUSTIFY_CENTER:
1730cdf0e10cSrcweir 								nJustPosX += ( nAvailWidth - aVars.GetTextSize().Width() +
1731cdf0e10cSrcweir 											(long) ( aVars.GetLeftTotal() * nPPTX ) -
1732cdf0e10cSrcweir 											(long) ( aVars.GetMargin()->GetRightMargin() * nPPTX ) ) / 2;
1733cdf0e10cSrcweir 								break;
1734cdf0e10cSrcweir                             default:
1735cdf0e10cSrcweir                             {
1736cdf0e10cSrcweir                                 // added to avoid warnings
1737cdf0e10cSrcweir                             }
1738cdf0e10cSrcweir 						}
1739cdf0e10cSrcweir 
1740cdf0e10cSrcweir 						long nTestClipHeight = aVars.GetTextSize().Height();
1741cdf0e10cSrcweir 						switch (aVars.GetVerJust())
1742cdf0e10cSrcweir 						{
1743cdf0e10cSrcweir 							case SVX_VER_JUSTIFY_TOP:
1744cdf0e10cSrcweir 								{
1745cdf0e10cSrcweir 									long nTop = (long)( aVars.GetMargin()->GetTopMargin() * nPPTY );
1746cdf0e10cSrcweir 									nJustPosY += nTop;
1747cdf0e10cSrcweir 									nTestClipHeight += nTop;
1748cdf0e10cSrcweir 								}
1749cdf0e10cSrcweir 								break;
1750cdf0e10cSrcweir 							case SVX_VER_JUSTIFY_BOTTOM:
1751cdf0e10cSrcweir 								{
1752cdf0e10cSrcweir 									long nBot = (long)( aVars.GetMargin()->GetBottomMargin() * nPPTY );
1753cdf0e10cSrcweir 									nJustPosY += nOutHeight - aVars.GetTextSize().Height() - nBot;
1754cdf0e10cSrcweir 									nTestClipHeight += nBot;
1755cdf0e10cSrcweir 								}
1756cdf0e10cSrcweir 								break;
1757cdf0e10cSrcweir 							case SVX_VER_JUSTIFY_CENTER:
1758cdf0e10cSrcweir 								{
1759cdf0e10cSrcweir 									long nTop = (long)( aVars.GetMargin()->GetTopMargin() * nPPTY );
1760cdf0e10cSrcweir 									long nBot = (long)( aVars.GetMargin()->GetBottomMargin() * nPPTY );
1761cdf0e10cSrcweir 									nJustPosY += ( nOutHeight + nTop -
1762cdf0e10cSrcweir 													aVars.GetTextSize().Height() - nBot ) / 2;
1763cdf0e10cSrcweir 									nTestClipHeight += Abs( nTop - nBot );
1764cdf0e10cSrcweir 								}
1765cdf0e10cSrcweir 								break;
1766cdf0e10cSrcweir                             default:
1767cdf0e10cSrcweir                             {
1768cdf0e10cSrcweir                                 // added to avoid warnings
1769cdf0e10cSrcweir                             }
1770cdf0e10cSrcweir 						}
1771cdf0e10cSrcweir 
1772cdf0e10cSrcweir 						if ( nTestClipHeight > nOutHeight )
1773cdf0e10cSrcweir 						{
1774cdf0e10cSrcweir 							//	kein vertikales Clipping beim Drucken von Zellen mit
1775cdf0e10cSrcweir 							//	optimaler Hoehe, ausser bei Groesse in bedingter Formatierung
1776cdf0e10cSrcweir 							if ( eType != OUTTYPE_PRINTER ||
1777cdf0e10cSrcweir 									( pDoc->GetRowFlags( nCellY, nTab ) & CR_MANUALSIZE ) ||
1778cdf0e10cSrcweir 									( aVars.HasCondHeight() ) )
1779cdf0e10cSrcweir 								bVClip = sal_True;
1780cdf0e10cSrcweir 						}
1781cdf0e10cSrcweir 
1782cdf0e10cSrcweir 						if ( bHClip || bVClip )
1783cdf0e10cSrcweir 						{
1784cdf0e10cSrcweir 							//	nur die betroffene Dimension clippen,
1785cdf0e10cSrcweir 							//	damit bei nicht-proportionalem Resize nicht alle
1786cdf0e10cSrcweir 							//	rechtsbuendigen Zahlen abgeschnitten werden:
1787cdf0e10cSrcweir 
1788cdf0e10cSrcweir 							if (!bHClip)
1789cdf0e10cSrcweir 							{
1790cdf0e10cSrcweir                                 aAreaParam.maClipRect.Left() = nScrX;
1791cdf0e10cSrcweir                                 aAreaParam.maClipRect.Right() = nScrX+nScrW;
1792cdf0e10cSrcweir 							}
1793cdf0e10cSrcweir 							if (!bVClip)
1794cdf0e10cSrcweir 							{
1795cdf0e10cSrcweir                                 aAreaParam.maClipRect.Top() = nScrY;
1796cdf0e10cSrcweir                                 aAreaParam.maClipRect.Bottom() = nScrY+nScrH;
1797cdf0e10cSrcweir 							}
1798cdf0e10cSrcweir 
1799cdf0e10cSrcweir 							//	aClipRect is not used after SetClipRegion/IntersectClipRegion,
1800cdf0e10cSrcweir 							//	so it can be modified here
1801cdf0e10cSrcweir 							if (bPixelToLogic)
1802cdf0e10cSrcweir                                 aAreaParam.maClipRect = pRefDevice->PixelToLogic( aAreaParam.maClipRect );
1803cdf0e10cSrcweir 
1804cdf0e10cSrcweir 							if (bMetaFile)
1805cdf0e10cSrcweir 							{
1806cdf0e10cSrcweir 								pDev->Push();
1807cdf0e10cSrcweir                                 pDev->IntersectClipRegion( aAreaParam.maClipRect );
1808cdf0e10cSrcweir 							}
1809cdf0e10cSrcweir 							else
1810cdf0e10cSrcweir                                 pDev->SetClipRegion( Region( aAreaParam.maClipRect ) );
1811cdf0e10cSrcweir 						}
1812cdf0e10cSrcweir 
1813cdf0e10cSrcweir                         Point aURLStart( nJustPosX, nJustPosY );    // copy before modifying for orientation
1814cdf0e10cSrcweir 
1815cdf0e10cSrcweir 						switch (aVars.GetOrient())
1816cdf0e10cSrcweir 						{
1817cdf0e10cSrcweir 							case SVX_ORIENTATION_STANDARD:
1818cdf0e10cSrcweir 								nJustPosY += aVars.GetAscent();
1819cdf0e10cSrcweir 								break;
1820cdf0e10cSrcweir 							case SVX_ORIENTATION_TOPBOTTOM:
1821cdf0e10cSrcweir 								nJustPosX += aVars.GetTextSize().Width() - aVars.GetAscent();
1822cdf0e10cSrcweir 								break;
1823cdf0e10cSrcweir 							case SVX_ORIENTATION_BOTTOMTOP:
1824cdf0e10cSrcweir 								nJustPosY += aVars.GetTextSize().Height();
1825cdf0e10cSrcweir 								nJustPosX += aVars.GetAscent();
1826cdf0e10cSrcweir 								break;
1827cdf0e10cSrcweir                             default:
1828cdf0e10cSrcweir                             {
1829cdf0e10cSrcweir                                 // added to avoid warnings
1830cdf0e10cSrcweir                             }
1831cdf0e10cSrcweir 						}
1832cdf0e10cSrcweir 
1833cdf0e10cSrcweir 						// When clipping, the visible part is now completely defined by the alignment,
1834cdf0e10cSrcweir 						// there's no more special handling to show the right part of RTL text.
1835cdf0e10cSrcweir 
1836cdf0e10cSrcweir 						Point aDrawTextPos( nJustPosX, nJustPosY );
1837cdf0e10cSrcweir 						if ( bPixelToLogic )
1838cdf0e10cSrcweir 						{
1839cdf0e10cSrcweir 							//	undo text width adjustment in pixels
1840cdf0e10cSrcweir 							if (bRightAdjusted)
1841cdf0e10cSrcweir 								aDrawTextPos.X() += aVars.GetTextSize().Width();
1842cdf0e10cSrcweir 
1843cdf0e10cSrcweir 							aDrawTextPos = pRefDevice->PixelToLogic( aDrawTextPos );
1844cdf0e10cSrcweir 
1845cdf0e10cSrcweir 							//	redo text width adjustment in logic units
1846cdf0e10cSrcweir 							if (bRightAdjusted)
1847cdf0e10cSrcweir 								aDrawTextPos.X() -= aVars.GetOriginalWidth();
1848cdf0e10cSrcweir 						}
1849cdf0e10cSrcweir 
1850cdf0e10cSrcweir 						//	in Metafiles immer DrawTextArray, damit die Positionen mit
1851cdf0e10cSrcweir 						//	aufgezeichnet werden (fuer nicht-proportionales Resize):
1852cdf0e10cSrcweir 
1853cdf0e10cSrcweir 						String aString = aVars.GetString();
1854cdf0e10cSrcweir 						if (bMetaFile || pFmtDevice != pDev || aZoomX != aZoomY)
1855cdf0e10cSrcweir 						{
1856cdf0e10cSrcweir 							sal_Int32* pDX = new sal_Int32[aString.Len()];
1857cdf0e10cSrcweir 							pFmtDevice->GetTextArray( aString, pDX );
1858cdf0e10cSrcweir 
1859cdf0e10cSrcweir 							if ( !pRefDevice->GetConnectMetaFile() ||
1860cdf0e10cSrcweir 									pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
1861cdf0e10cSrcweir 							{
1862cdf0e10cSrcweir 								double fMul = GetStretch();
1863cdf0e10cSrcweir 								xub_StrLen nLen = aString.Len();
1864cdf0e10cSrcweir 								for (xub_StrLen i=0; i<nLen; i++)
1865cdf0e10cSrcweir 									pDX[i] = (long)(pDX[i] / fMul + 0.5);
1866cdf0e10cSrcweir 							}
1867cdf0e10cSrcweir 
1868cdf0e10cSrcweir 							pDev->DrawTextArray( aDrawTextPos, aString, pDX );
1869cdf0e10cSrcweir 							delete[] pDX;
1870cdf0e10cSrcweir 						}
1871cdf0e10cSrcweir 						else
1872cdf0e10cSrcweir 							pDev->DrawText( aDrawTextPos, aString );
1873cdf0e10cSrcweir 
1874cdf0e10cSrcweir 						if ( bHClip || bVClip )
1875cdf0e10cSrcweir 						{
1876cdf0e10cSrcweir 							if (bMetaFile)
1877cdf0e10cSrcweir 								pDev->Pop();
1878cdf0e10cSrcweir 							else
1879cdf0e10cSrcweir 								pDev->SetClipRegion();
1880cdf0e10cSrcweir 						}
1881cdf0e10cSrcweir 
1882cdf0e10cSrcweir                         // PDF: whole-cell hyperlink from formula?
1883cdf0e10cSrcweir                         sal_Bool bHasURL = pPDFData && pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
1884cdf0e10cSrcweir                                         static_cast<ScFormulaCell*>(pCell)->IsHyperLinkCell();
1885cdf0e10cSrcweir                         if ( bHasURL )
1886cdf0e10cSrcweir                         {
1887cdf0e10cSrcweir                             Rectangle aURLRect( aURLStart, aVars.GetTextSize() );
1888cdf0e10cSrcweir                             lcl_DoHyperlinkResult( pDev, aURLRect, pCell );
1889cdf0e10cSrcweir                         }
1890cdf0e10cSrcweir 					}
1891cdf0e10cSrcweir 				}
1892cdf0e10cSrcweir 				nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
1893cdf0e10cSrcweir 			}
1894cdf0e10cSrcweir 		}
1895cdf0e10cSrcweir 		nPosY += pRowInfo[nArrY].nHeight;
1896cdf0e10cSrcweir 	}
1897cdf0e10cSrcweir 	if ( bProgress )
1898cdf0e10cSrcweir 		ScProgress::DeleteInterpretProgress();
1899cdf0e10cSrcweir 	pDoc->DisableIdle( bWasIdleDisabled );
1900cdf0e10cSrcweir }
1901cdf0e10cSrcweir 
1902cdf0e10cSrcweir //	-------------------------------------------------------------------------------
1903cdf0e10cSrcweir 
CreateOutputEditEngine()1904cdf0e10cSrcweir ScFieldEditEngine* ScOutputData::CreateOutputEditEngine()
1905cdf0e10cSrcweir {
1906cdf0e10cSrcweir     ScFieldEditEngine* pEngine = new ScFieldEditEngine( pDoc->GetEnginePool() );
1907cdf0e10cSrcweir     pEngine->SetUpdateMode( sal_False );
1908cdf0e10cSrcweir     // a RefDevice always has to be set, otherwise EditEngine would create a VirtualDevice
1909cdf0e10cSrcweir     pEngine->SetRefDevice( pFmtDevice );
1910cdf0e10cSrcweir     sal_uInt32 nCtrl = pEngine->GetControlWord();
1911cdf0e10cSrcweir     if ( bShowSpellErrors )
1912cdf0e10cSrcweir         nCtrl |= EE_CNTRL_ONLINESPELLING;
1913cdf0e10cSrcweir     if ( eType == OUTTYPE_PRINTER )
1914cdf0e10cSrcweir         nCtrl &= ~EE_CNTRL_MARKFIELDS;
1915cdf0e10cSrcweir     if ( eType == OUTTYPE_WINDOW && pRefDevice == pFmtDevice )
1916cdf0e10cSrcweir         nCtrl &= ~EE_CNTRL_FORMAT100;       // use the actual MapMode
1917cdf0e10cSrcweir     pEngine->SetControlWord( nCtrl );
1918cdf0e10cSrcweir     pDoc->ApplyAsianEditSettings( *pEngine );
1919cdf0e10cSrcweir     pEngine->EnableAutoColor( bUseStyleColor );
1920cdf0e10cSrcweir     pEngine->SetDefaultHorizontalTextDirection( (EEHorizontalTextDirection)pDoc->GetEditTextDirection( nTab ) );
1921cdf0e10cSrcweir     return pEngine;
1922cdf0e10cSrcweir }
1923cdf0e10cSrcweir 
lcl_ClearEdit(EditEngine & rEngine)1924cdf0e10cSrcweir void lcl_ClearEdit( EditEngine& rEngine )		// Text und Attribute
1925cdf0e10cSrcweir {
1926cdf0e10cSrcweir 	rEngine.SetUpdateMode( sal_False );
1927cdf0e10cSrcweir 
1928cdf0e10cSrcweir 	rEngine.SetText(EMPTY_STRING);
1929cdf0e10cSrcweir 	//	keine Para-Attribute uebrigbehalten...
1930cdf0e10cSrcweir 	const SfxItemSet& rPara = rEngine.GetParaAttribs(0);
1931cdf0e10cSrcweir 	if (rPara.Count())
1932cdf0e10cSrcweir 		rEngine.SetParaAttribs( 0,
1933cdf0e10cSrcweir 					SfxItemSet( *rPara.GetPool(), rPara.GetRanges() ) );
1934cdf0e10cSrcweir }
1935cdf0e10cSrcweir 
lcl_SafeIsValue(ScBaseCell * pCell)1936cdf0e10cSrcweir sal_Bool lcl_SafeIsValue( ScBaseCell* pCell )
1937cdf0e10cSrcweir {
1938cdf0e10cSrcweir 	if (!pCell)
1939cdf0e10cSrcweir 		return sal_False;
1940cdf0e10cSrcweir 
1941cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
1942cdf0e10cSrcweir 	switch ( pCell->GetCellType() )
1943cdf0e10cSrcweir 	{
1944cdf0e10cSrcweir 		case CELLTYPE_VALUE:
1945cdf0e10cSrcweir 			bRet = sal_True;
1946cdf0e10cSrcweir 			break;
1947cdf0e10cSrcweir 		case CELLTYPE_FORMULA:
1948cdf0e10cSrcweir 			{
1949cdf0e10cSrcweir 				ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
1950cdf0e10cSrcweir 				if ( pFCell->IsRunning() || pFCell->IsValue() )
1951cdf0e10cSrcweir 					bRet = sal_True;
1952cdf0e10cSrcweir 			}
1953cdf0e10cSrcweir 			break;
1954cdf0e10cSrcweir         default:
1955cdf0e10cSrcweir         {
1956cdf0e10cSrcweir             // added to avoid warnings
1957cdf0e10cSrcweir         }
1958cdf0e10cSrcweir 	}
1959cdf0e10cSrcweir 	return bRet;
1960cdf0e10cSrcweir }
1961cdf0e10cSrcweir 
lcl_ScaleFonts(EditEngine & rEngine,long nPercent)1962cdf0e10cSrcweir void lcl_ScaleFonts( EditEngine& rEngine, long nPercent )
1963cdf0e10cSrcweir {
1964cdf0e10cSrcweir     sal_Bool bUpdateMode = rEngine.GetUpdateMode();
1965cdf0e10cSrcweir     if ( bUpdateMode )
1966cdf0e10cSrcweir         rEngine.SetUpdateMode( sal_False );
1967cdf0e10cSrcweir 
1968cdf0e10cSrcweir     sal_uInt16 nParCount = rEngine.GetParagraphCount();
1969cdf0e10cSrcweir     for (sal_uInt16 nPar=0; nPar<nParCount; nPar++)
1970cdf0e10cSrcweir     {
1971cdf0e10cSrcweir         SvUShorts aPortions;
1972cdf0e10cSrcweir         rEngine.GetPortions( nPar, aPortions );
1973cdf0e10cSrcweir 
1974cdf0e10cSrcweir         sal_uInt16 nPCount = aPortions.Count();
1975cdf0e10cSrcweir         sal_uInt16 nStart = 0;
1976cdf0e10cSrcweir         for ( sal_uInt16 nPos=0; nPos<nPCount; nPos++ )
1977cdf0e10cSrcweir         {
1978cdf0e10cSrcweir             sal_uInt16 nEnd = aPortions.GetObject( nPos );
1979cdf0e10cSrcweir             ESelection aSel( nPar, nStart, nPar, nEnd );
1980cdf0e10cSrcweir             SfxItemSet aAttribs = rEngine.GetAttribs( aSel );
1981cdf0e10cSrcweir 
1982cdf0e10cSrcweir             long nWestern = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT)).GetHeight();
1983cdf0e10cSrcweir             long nCJK = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT_CJK)).GetHeight();
1984cdf0e10cSrcweir             long nCTL = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT_CTL)).GetHeight();
1985cdf0e10cSrcweir 
1986cdf0e10cSrcweir             nWestern = ( nWestern * nPercent ) / 100;
1987cdf0e10cSrcweir             nCJK     = ( nCJK     * nPercent ) / 100;
1988cdf0e10cSrcweir             nCTL     = ( nCTL     * nPercent ) / 100;
1989cdf0e10cSrcweir 
1990cdf0e10cSrcweir             aAttribs.Put( SvxFontHeightItem( nWestern, 100, EE_CHAR_FONTHEIGHT ) );
1991cdf0e10cSrcweir             aAttribs.Put( SvxFontHeightItem( nCJK, 100, EE_CHAR_FONTHEIGHT_CJK ) );
1992cdf0e10cSrcweir             aAttribs.Put( SvxFontHeightItem( nCTL, 100, EE_CHAR_FONTHEIGHT_CTL ) );
1993cdf0e10cSrcweir 
1994cdf0e10cSrcweir             rEngine.QuickSetAttribs( aAttribs, aSel );      //! remove paragraph attributes from aAttribs?
1995cdf0e10cSrcweir 
1996cdf0e10cSrcweir             nStart = nEnd;
1997cdf0e10cSrcweir         }
1998cdf0e10cSrcweir     }
1999cdf0e10cSrcweir 
2000cdf0e10cSrcweir     if ( bUpdateMode )
2001cdf0e10cSrcweir         rEngine.SetUpdateMode( sal_True );
2002cdf0e10cSrcweir }
2003cdf0e10cSrcweir 
lcl_GetEditSize(EditEngine & rEngine,sal_Bool bWidth,sal_Bool bSwap,long nAttrRotate)2004cdf0e10cSrcweir long lcl_GetEditSize( EditEngine& rEngine, sal_Bool bWidth, sal_Bool bSwap, long nAttrRotate )
2005cdf0e10cSrcweir {
2006cdf0e10cSrcweir     if ( bSwap )
2007cdf0e10cSrcweir         bWidth = !bWidth;
2008cdf0e10cSrcweir 
2009cdf0e10cSrcweir     if ( nAttrRotate )
2010cdf0e10cSrcweir     {
2011cdf0e10cSrcweir         long nRealWidth  = (long) rEngine.CalcTextWidth();
2012cdf0e10cSrcweir         long nRealHeight = rEngine.GetTextHeight();
2013cdf0e10cSrcweir 
2014cdf0e10cSrcweir         // assuming standard mode, otherwise width isn't used
2015cdf0e10cSrcweir 
2016cdf0e10cSrcweir         double nRealOrient = nAttrRotate * F_PI18000;	// 1/100th degrees
2017cdf0e10cSrcweir         double nAbsCos = fabs( cos( nRealOrient ) );
2018cdf0e10cSrcweir         double nAbsSin = fabs( sin( nRealOrient ) );
2019cdf0e10cSrcweir         if ( bWidth )
2020cdf0e10cSrcweir             return (long) ( nRealWidth * nAbsCos + nRealHeight * nAbsSin );
2021cdf0e10cSrcweir         else
2022cdf0e10cSrcweir             return (long) ( nRealHeight * nAbsCos + nRealWidth * nAbsSin );
2023cdf0e10cSrcweir     }
2024cdf0e10cSrcweir     else if ( bWidth )
2025cdf0e10cSrcweir         return (long) rEngine.CalcTextWidth();
2026cdf0e10cSrcweir     else
2027cdf0e10cSrcweir         return rEngine.GetTextHeight();
2028cdf0e10cSrcweir }
2029cdf0e10cSrcweir 
2030cdf0e10cSrcweir 
ShrinkEditEngine(EditEngine & rEngine,const Rectangle & rAlignRect,long nLeftM,long nTopM,long nRightM,long nBottomM,sal_Bool bWidth,sal_uInt16 nOrient,long nAttrRotate,sal_Bool bPixelToLogic,long & rEngineWidth,long & rEngineHeight,long & rNeededPixel,bool & rLeftClip,bool & rRightClip)2031cdf0e10cSrcweir void ScOutputData::ShrinkEditEngine( EditEngine& rEngine, const Rectangle& rAlignRect,
2032cdf0e10cSrcweir             long nLeftM, long nTopM, long nRightM, long nBottomM,
2033cdf0e10cSrcweir             sal_Bool bWidth, sal_uInt16 nOrient, long nAttrRotate, sal_Bool bPixelToLogic,
2034cdf0e10cSrcweir             long& rEngineWidth, long& rEngineHeight, long& rNeededPixel, bool& rLeftClip, bool& rRightClip )
2035cdf0e10cSrcweir {
2036cdf0e10cSrcweir     if ( !bWidth )
2037cdf0e10cSrcweir     {
2038cdf0e10cSrcweir         // vertical
2039cdf0e10cSrcweir 
2040cdf0e10cSrcweir         long nScaleSize = bPixelToLogic ?
2041cdf0e10cSrcweir             pRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
2042cdf0e10cSrcweir 
2043cdf0e10cSrcweir         // Don't scale if it fits already.
2044cdf0e10cSrcweir         // Allowing to extend into the margin, to avoid scaling at optimal height.
2045cdf0e10cSrcweir         if ( nScaleSize <= rAlignRect.GetHeight() )
2046cdf0e10cSrcweir             return;
2047cdf0e10cSrcweir 
2048cdf0e10cSrcweir         sal_Bool bSwap = ( nOrient == SVX_ORIENTATION_TOPBOTTOM || nOrient == SVX_ORIENTATION_BOTTOMTOP );
2049cdf0e10cSrcweir         long nAvailable = rAlignRect.GetHeight() - nTopM - nBottomM;
2050cdf0e10cSrcweir         long nScale = ( nAvailable * 100 ) / nScaleSize;
2051cdf0e10cSrcweir 
2052cdf0e10cSrcweir         lcl_ScaleFonts( rEngine, nScale );
2053cdf0e10cSrcweir         rEngineHeight = lcl_GetEditSize( rEngine, sal_False, bSwap, nAttrRotate );
2054cdf0e10cSrcweir         long nNewSize = bPixelToLogic ?
2055cdf0e10cSrcweir             pRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
2056cdf0e10cSrcweir 
2057cdf0e10cSrcweir         sal_uInt16 nShrinkAgain = 0;
2058cdf0e10cSrcweir         while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
2059cdf0e10cSrcweir         {
2060cdf0e10cSrcweir             // further reduce, like in DrawStrings
2061cdf0e10cSrcweir             lcl_ScaleFonts( rEngine, 90 );     // reduce by 10%
2062cdf0e10cSrcweir             rEngineHeight = lcl_GetEditSize( rEngine, sal_False, bSwap, nAttrRotate );
2063cdf0e10cSrcweir             nNewSize = bPixelToLogic ?
2064cdf0e10cSrcweir                 pRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
2065cdf0e10cSrcweir             ++nShrinkAgain;
2066cdf0e10cSrcweir         }
2067cdf0e10cSrcweir 
2068cdf0e10cSrcweir         // sizes for further processing (alignment etc):
2069cdf0e10cSrcweir         rEngineWidth = lcl_GetEditSize( rEngine, sal_True, bSwap, nAttrRotate );
2070cdf0e10cSrcweir         long nPixelWidth = bPixelToLogic ?
2071cdf0e10cSrcweir             pRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
2072cdf0e10cSrcweir         rNeededPixel = nPixelWidth + nLeftM + nRightM;
2073cdf0e10cSrcweir     }
2074cdf0e10cSrcweir     else if ( rLeftClip || rRightClip )
2075cdf0e10cSrcweir     {
2076cdf0e10cSrcweir         // horizontal
2077cdf0e10cSrcweir 
2078cdf0e10cSrcweir         long nAvailable = rAlignRect.GetWidth() - nLeftM - nRightM;
2079cdf0e10cSrcweir         long nScaleSize = rNeededPixel - nLeftM - nRightM;      // without margin
2080cdf0e10cSrcweir 
2081cdf0e10cSrcweir         if ( nScaleSize <= nAvailable )
2082cdf0e10cSrcweir             return;
2083cdf0e10cSrcweir 
2084cdf0e10cSrcweir         long nScale = ( nAvailable * 100 ) / nScaleSize;
2085cdf0e10cSrcweir 
2086cdf0e10cSrcweir         lcl_ScaleFonts( rEngine, nScale );
2087cdf0e10cSrcweir         rEngineWidth = lcl_GetEditSize( rEngine, sal_True, sal_False, nAttrRotate );
2088cdf0e10cSrcweir         long nNewSize = bPixelToLogic ?
2089cdf0e10cSrcweir             pRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
2090cdf0e10cSrcweir 
2091cdf0e10cSrcweir         sal_uInt16 nShrinkAgain = 0;
2092cdf0e10cSrcweir         while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
2093cdf0e10cSrcweir         {
2094cdf0e10cSrcweir             // further reduce, like in DrawStrings
2095cdf0e10cSrcweir             lcl_ScaleFonts( rEngine, 90 );     // reduce by 10%
2096cdf0e10cSrcweir             rEngineWidth = lcl_GetEditSize( rEngine, sal_True, sal_False, nAttrRotate );
2097cdf0e10cSrcweir             nNewSize = bPixelToLogic ?
2098cdf0e10cSrcweir                 pRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
2099cdf0e10cSrcweir             ++nShrinkAgain;
2100cdf0e10cSrcweir         }
2101cdf0e10cSrcweir         if ( nNewSize <= nAvailable )
2102cdf0e10cSrcweir             rLeftClip = rRightClip = sal_False;
2103cdf0e10cSrcweir 
2104cdf0e10cSrcweir         // sizes for further processing (alignment etc):
2105cdf0e10cSrcweir         rNeededPixel = nNewSize + nLeftM + nRightM;
2106cdf0e10cSrcweir         rEngineHeight = lcl_GetEditSize( rEngine, sal_False, sal_False, nAttrRotate );
2107cdf0e10cSrcweir     }
2108cdf0e10cSrcweir }
2109cdf0e10cSrcweir 
DrawEdit(sal_Bool bPixelToLogic)2110cdf0e10cSrcweir void ScOutputData::DrawEdit(sal_Bool bPixelToLogic)
2111cdf0e10cSrcweir {
2112cdf0e10cSrcweir     vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
2113cdf0e10cSrcweir 
2114cdf0e10cSrcweir 	Size aMinSize = pRefDevice->PixelToLogic(Size(0,100));		// erst darueber wird ausgegeben
2115cdf0e10cSrcweir //    sal_uInt32 nMinHeight = aMinSize.Height() / 200;                // 1/2 Pixel
2116cdf0e10cSrcweir 
2117cdf0e10cSrcweir 	ScModule* pScMod = SC_MOD();
2118cdf0e10cSrcweir     sal_Int32 nConfBackColor = pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
2119cdf0e10cSrcweir 	//	#105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
2120cdf0e10cSrcweir 	sal_Bool bCellContrast = bUseStyleColor &&
2121cdf0e10cSrcweir 			Application::GetSettings().GetStyleSettings().GetHighContrastMode();
2122cdf0e10cSrcweir 
2123cdf0e10cSrcweir 	ScFieldEditEngine* pEngine = NULL;
2124cdf0e10cSrcweir 	sal_Bool bHyphenatorSet = sal_False;
2125cdf0e10cSrcweir 	const ScPatternAttr* pOldPattern = NULL;
2126cdf0e10cSrcweir 	const SfxItemSet*	 pOldCondSet = NULL;
2127cdf0e10cSrcweir 	ScBaseCell* pCell = NULL;
2128cdf0e10cSrcweir 
2129cdf0e10cSrcweir 	Size aRefOne = pRefDevice->PixelToLogic(Size(1,1));
2130cdf0e10cSrcweir 
2131cdf0e10cSrcweir 	long nInitPosX = nScrX;
2132cdf0e10cSrcweir 	if ( bLayoutRTL )
2133cdf0e10cSrcweir 	{
2134cdf0e10cSrcweir #if 0
2135cdf0e10cSrcweir 		Size aOnePixel = pDev->PixelToLogic(Size(1,1));
2136cdf0e10cSrcweir 		long nOneX = aOnePixel.Width();
2137cdf0e10cSrcweir 		nInitPosX += nMirrorW - nOneX;
2138cdf0e10cSrcweir #endif
2139cdf0e10cSrcweir 		nInitPosX += nMirrorW - 1;
2140cdf0e10cSrcweir 	}
2141cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
2142cdf0e10cSrcweir 
2143cdf0e10cSrcweir 	//!	store nLastContentCol as member!
2144cdf0e10cSrcweir 	SCCOL nLastContentCol = MAXCOL;
2145cdf0e10cSrcweir 	if ( nX2 < MAXCOL )
2146cdf0e10cSrcweir         nLastContentCol = sal::static_int_cast<SCCOL>(
2147cdf0e10cSrcweir             nLastContentCol - pDoc->GetEmptyLinesInBlock( nX2+1, nY1, nTab, MAXCOL, nY2, nTab, DIR_RIGHT ) );
2148cdf0e10cSrcweir 
2149cdf0e10cSrcweir 	long nRowPosY = nScrY;
2150cdf0e10cSrcweir 	for (SCSIZE nArrY=0; nArrY+1<nArrCount; nArrY++)			// 0 fuer Reste von zusammengefassten
2151cdf0e10cSrcweir 	{
2152cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2153cdf0e10cSrcweir //        long nCellHeight = (long) pThisRowInfo->nHeight;
2154cdf0e10cSrcweir 		if (nArrY==1) nRowPosY = nScrY;							// vorher wird einzeln berechnet
2155cdf0e10cSrcweir 
2156cdf0e10cSrcweir 		if ( pThisRowInfo->bChanged || nArrY==0 )
2157cdf0e10cSrcweir 		{
2158cdf0e10cSrcweir 			long nPosX = 0;
2159cdf0e10cSrcweir 			for (SCCOL nX=0; nX<=nX2; nX++)					// wegen Ueberhaengen
2160cdf0e10cSrcweir 			{
2161cdf0e10cSrcweir 				if (nX==nX1) nPosX = nInitPosX;					// positions before nX1 are calculated individually
2162cdf0e10cSrcweir 
2163cdf0e10cSrcweir 				CellInfo*	pInfo = &pThisRowInfo->pCellInfo[nX+1];
2164cdf0e10cSrcweir 				if (pInfo->bEditEngine)
2165cdf0e10cSrcweir 				{
2166cdf0e10cSrcweir 					SCROW nY = pThisRowInfo->nRowNo;
2167cdf0e10cSrcweir 
2168cdf0e10cSrcweir 					SCCOL nCellX = nX;					// position where the cell really starts
2169cdf0e10cSrcweir 					SCROW nCellY = nY;
2170cdf0e10cSrcweir 					sal_Bool bDoCell = sal_False;
2171cdf0e10cSrcweir 
2172cdf0e10cSrcweir 					long nPosY = nRowPosY;
2173cdf0e10cSrcweir 					if ( nArrY == 0 )
2174cdf0e10cSrcweir 					{
2175cdf0e10cSrcweir 						nPosY = nScrY;
2176cdf0e10cSrcweir 						nY = pRowInfo[1].nRowNo;
2177cdf0e10cSrcweir 						SCCOL nOverX;					// start of the merged cells
2178cdf0e10cSrcweir 						SCROW nOverY;
2179cdf0e10cSrcweir 						if (GetMergeOrigin( nX,nY, 1, nOverX,nOverY, sal_True ))
2180cdf0e10cSrcweir 						{
2181cdf0e10cSrcweir 							nCellX = nOverX;
2182cdf0e10cSrcweir 							nCellY = nOverY;
2183cdf0e10cSrcweir 							bDoCell = sal_True;
2184cdf0e10cSrcweir 						}
2185cdf0e10cSrcweir 					}
2186cdf0e10cSrcweir 					else if ( nX == nX2 && !pThisRowInfo->pCellInfo[nX+1].pCell )
2187cdf0e10cSrcweir 					{
2188cdf0e10cSrcweir 						//	Rest of a long text further to the right?
2189cdf0e10cSrcweir 
2190cdf0e10cSrcweir 						SCCOL nTempX=nX;
2191cdf0e10cSrcweir 						while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
2192cdf0e10cSrcweir 							++nTempX;
2193cdf0e10cSrcweir 
2194cdf0e10cSrcweir 						if ( nTempX > nX &&
2195cdf0e10cSrcweir 							 !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
2196cdf0e10cSrcweir 							 !pDoc->HasAttrib( nTempX,nY,nTab, nX,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
2197cdf0e10cSrcweir 						{
2198cdf0e10cSrcweir 							nCellX = nTempX;
2199cdf0e10cSrcweir 							bDoCell = sal_True;
2200cdf0e10cSrcweir 						}
2201cdf0e10cSrcweir 					}
2202cdf0e10cSrcweir 					else
2203cdf0e10cSrcweir 					{
2204cdf0e10cSrcweir 						bDoCell = sal_True;
2205cdf0e10cSrcweir 					}
2206cdf0e10cSrcweir 
2207cdf0e10cSrcweir 					if ( bDoCell && bEditMode && nCellX == nEditCol && nCellY == nEditRow )
2208cdf0e10cSrcweir 						bDoCell = sal_False;
2209cdf0e10cSrcweir 
2210cdf0e10cSrcweir                     const ScPatternAttr* pPattern = NULL;
2211cdf0e10cSrcweir                     const SfxItemSet* pCondSet = NULL;
2212cdf0e10cSrcweir 					if (bDoCell)
2213cdf0e10cSrcweir 					{
2214cdf0e10cSrcweir                         if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 &&
2215cdf0e10cSrcweir                              !pDoc->ColHidden(nCellX, nTab) )
2216cdf0e10cSrcweir 						{
2217cdf0e10cSrcweir 							CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1];
2218cdf0e10cSrcweir 							pPattern = rCellInfo.pPatternAttr;
2219cdf0e10cSrcweir 							pCondSet = rCellInfo.pConditionSet;
2220cdf0e10cSrcweir 							pCell = rCellInfo.pCell;
2221cdf0e10cSrcweir 						}
2222cdf0e10cSrcweir 						else		// get from document
2223cdf0e10cSrcweir 						{
2224cdf0e10cSrcweir 							pPattern = pDoc->GetPattern( nCellX, nCellY, nTab );
2225cdf0e10cSrcweir 							pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab );
2226cdf0e10cSrcweir 							GetVisibleCell( nCellX, nCellY, nTab, pCell );
2227cdf0e10cSrcweir 						}
2228cdf0e10cSrcweir 						if ( !pCell )
2229cdf0e10cSrcweir 							bDoCell = sal_False;
2230cdf0e10cSrcweir 					}
2231cdf0e10cSrcweir 					if (bDoCell)
2232cdf0e10cSrcweir 					{
2233cdf0e10cSrcweir 						sal_Bool bHidden = sal_False;
2234cdf0e10cSrcweir 
2235cdf0e10cSrcweir 						//
2236cdf0e10cSrcweir 						//	Create EditEngine
2237cdf0e10cSrcweir 						//
2238cdf0e10cSrcweir 
2239cdf0e10cSrcweir 						if (!pEngine)
2240cdf0e10cSrcweir                             pEngine = CreateOutputEditEngine();
2241cdf0e10cSrcweir 						else
2242cdf0e10cSrcweir 							lcl_ClearEdit( *pEngine );		// also calls SetUpdateMode(sal_False)
2243cdf0e10cSrcweir 
2244cdf0e10cSrcweir 						sal_Bool bCellIsValue = lcl_SafeIsValue(pCell);
2245cdf0e10cSrcweir 
2246cdf0e10cSrcweir 						SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
2247cdf0e10cSrcweir 											pPattern->GetItem(ATTR_HOR_JUSTIFY, pCondSet)).GetValue();
2248cdf0e10cSrcweir 						sal_Bool bBreak = ( eHorJust == SVX_HOR_JUSTIFY_BLOCK ) ||
2249cdf0e10cSrcweir 										((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue();
2250cdf0e10cSrcweir                         sal_Bool bRepeat = ( eHorJust == SVX_HOR_JUSTIFY_REPEAT && !bBreak );
2251cdf0e10cSrcweir                         sal_Bool bShrink = !bBreak && !bRepeat && static_cast<const SfxBoolItem&>
2252cdf0e10cSrcweir                                         (pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
2253cdf0e10cSrcweir                         SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
2254cdf0e10cSrcweir 						long nAttrRotate = ((const SfxInt32Item&)pPattern->
2255cdf0e10cSrcweir 											GetItem(ATTR_ROTATE_VALUE, pCondSet)).GetValue();
2256cdf0e10cSrcweir                         if ( eHorJust == SVX_HOR_JUSTIFY_REPEAT )
2257cdf0e10cSrcweir                         {
2258cdf0e10cSrcweir                             // ignore orientation/rotation if "repeat" is active
2259cdf0e10cSrcweir                             eOrient = SVX_ORIENTATION_STANDARD;
2260cdf0e10cSrcweir                             nAttrRotate = 0;
2261cdf0e10cSrcweir 
2262cdf0e10cSrcweir                             // #i31843# "repeat" with "line breaks" is treated as default alignment
2263cdf0e10cSrcweir                             // (but rotation is still disabled)
2264cdf0e10cSrcweir                             if ( bBreak )
2265cdf0e10cSrcweir                                 eHorJust = SVX_HOR_JUSTIFY_STANDARD;
2266cdf0e10cSrcweir                         }
2267cdf0e10cSrcweir 						if ( eOrient==SVX_ORIENTATION_STANDARD && nAttrRotate )
2268cdf0e10cSrcweir 						{
2269cdf0e10cSrcweir 							//!	Flag setzen, um die Zelle in DrawRotated wiederzufinden ?
2270cdf0e10cSrcweir 							//!	(oder Flag schon bei DrawBackground, dann hier keine Abfrage)
2271cdf0e10cSrcweir 							bHidden = sal_True;		// gedreht wird getrennt ausgegeben
2272cdf0e10cSrcweir 						}
2273cdf0e10cSrcweir 
2274cdf0e10cSrcweir 						sal_Bool bAsianVertical = ( eOrient == SVX_ORIENTATION_STACKED &&
2275cdf0e10cSrcweir 								((const SfxBoolItem&)pPattern->GetItem( ATTR_VERTICAL_ASIAN, pCondSet )).GetValue() );
2276cdf0e10cSrcweir 						if ( bAsianVertical )
2277cdf0e10cSrcweir 						{
2278cdf0e10cSrcweir 							// in asian mode, use EditEngine::SetVertical instead of EE_CNTRL_ONECHARPERLINE
2279cdf0e10cSrcweir 							eOrient = SVX_ORIENTATION_STANDARD;
2280cdf0e10cSrcweir 							// default alignment for asian vertical mode is top-right
2281cdf0e10cSrcweir 							if ( eHorJust == SVX_HOR_JUSTIFY_STANDARD )
2282cdf0e10cSrcweir 								eHorJust = SVX_HOR_JUSTIFY_RIGHT;
2283cdf0e10cSrcweir 						}
2284cdf0e10cSrcweir 
2285cdf0e10cSrcweir 						SvxCellHorJustify eOutHorJust =
2286cdf0e10cSrcweir 							( eHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? eHorJust :
2287cdf0e10cSrcweir 							( bCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
2288cdf0e10cSrcweir 
2289cdf0e10cSrcweir 						if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
2290cdf0e10cSrcweir 							eOutHorJust = SVX_HOR_JUSTIFY_LEFT;		// repeat is not yet implemented
2291cdf0e10cSrcweir 
2292cdf0e10cSrcweir 
2293cdf0e10cSrcweir //!						if ( !bHidden && eType == OUTTYPE_PRINTER &&
2294cdf0e10cSrcweir //!							pDev->GetOutDevType() == OUTDEV_WINDOW &&
2295cdf0e10cSrcweir //!							((const SvxFontHeightItem&)pPattern->
2296cdf0e10cSrcweir //!							GetItem(ATTR_FONT_HEIGHT)).GetHeight() <= nMinHeight )
2297cdf0e10cSrcweir //!						{
2298cdf0e10cSrcweir //!							Point aPos( nStartX, nStartY );
2299cdf0e10cSrcweir //!							pDev->DrawPixel( aPos,
2300cdf0e10cSrcweir //!											((const SvxColorItem&)pPattern->
2301cdf0e10cSrcweir //!											GetItem( ATTR_FONT_COLOR )).GetValue() );
2302cdf0e10cSrcweir //!							bHidden = sal_True;
2303cdf0e10cSrcweir //!						}
2304cdf0e10cSrcweir 
2305cdf0e10cSrcweir 						if (!bHidden)
2306cdf0e10cSrcweir 						{
2307cdf0e10cSrcweir 							//!	mirror margin values for RTL?
2308cdf0e10cSrcweir 							//!	move margin down to after final GetOutputArea call
2309cdf0e10cSrcweir 
2310cdf0e10cSrcweir 							const SvxMarginItem* pMargin = (const SvxMarginItem*)
2311cdf0e10cSrcweir 													&pPattern->GetItem(ATTR_MARGIN, pCondSet);
2312cdf0e10cSrcweir 							sal_uInt16 nIndent = 0;
2313cdf0e10cSrcweir 							if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
2314cdf0e10cSrcweir 								nIndent = ((const SfxUInt16Item&)pPattern->
2315cdf0e10cSrcweir 													GetItem(ATTR_INDENT, pCondSet)).GetValue();
2316cdf0e10cSrcweir 
2317cdf0e10cSrcweir 							long nLeftM = (long) ( (pMargin->GetLeftMargin() + nIndent) * nPPTX );
2318cdf0e10cSrcweir 							long nTopM  = (long) ( pMargin->GetTopMargin() * nPPTY );
2319cdf0e10cSrcweir 							long nRightM = (long) ( pMargin->GetRightMargin() * nPPTX );
2320cdf0e10cSrcweir 							long nBottomM = (long) ( pMargin->GetBottomMargin() * nPPTY );
2321cdf0e10cSrcweir 
2322cdf0e10cSrcweir 							SCCOL nXForPos = nX;
2323cdf0e10cSrcweir 							if ( nXForPos < nX1 )
2324cdf0e10cSrcweir 							{
2325cdf0e10cSrcweir 								nXForPos = nX1;
2326cdf0e10cSrcweir 								nPosX = nInitPosX;
2327cdf0e10cSrcweir 							}
2328cdf0e10cSrcweir 							SCSIZE nArrYForPos = nArrY;
2329cdf0e10cSrcweir 							if ( nArrYForPos < 1 )
2330cdf0e10cSrcweir 							{
2331cdf0e10cSrcweir 								nArrYForPos = 1;
2332cdf0e10cSrcweir 								nPosY = nScrY;
2333cdf0e10cSrcweir 							}
2334cdf0e10cSrcweir 
2335cdf0e10cSrcweir                             OutputAreaParam aAreaParam;
2336cdf0e10cSrcweir 
2337cdf0e10cSrcweir 							//
2338cdf0e10cSrcweir 							//	Initial page size - large for normal text, cell size for automatic line breaks
2339cdf0e10cSrcweir 							//
2340cdf0e10cSrcweir 
2341cdf0e10cSrcweir 							Size aPaperSize = Size( 1000000, 1000000 );
2342cdf0e10cSrcweir 							if ( bBreak || eOrient == SVX_ORIENTATION_STACKED || bAsianVertical )
2343cdf0e10cSrcweir 							{
2344cdf0e10cSrcweir 								//!	also stacked, AsianVertical
2345cdf0e10cSrcweir 
2346cdf0e10cSrcweir 								//	call GetOutputArea with nNeeded=0, to get only the cell width
2347cdf0e10cSrcweir 
2348cdf0e10cSrcweir 								//!	handle nArrY == 0
2349cdf0e10cSrcweir 								GetOutputArea( nXForPos, nArrYForPos, nPosX, nPosY, nCellX, nCellY, 0,
2350cdf0e10cSrcweir                                                *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
2351cdf0e10cSrcweir                                                bCellIsValue, true, false, aAreaParam );
2352cdf0e10cSrcweir 
2353cdf0e10cSrcweir 								//! special ScEditUtil handling if formatting for printer
2354cdf0e10cSrcweir 
2355cdf0e10cSrcweir 								if ( eOrient == SVX_ORIENTATION_TOPBOTTOM || eOrient == SVX_ORIENTATION_BOTTOMTOP )
2356cdf0e10cSrcweir                                     aPaperSize.Width() = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
2357cdf0e10cSrcweir 								else
2358cdf0e10cSrcweir                                     aPaperSize.Width() = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
2359cdf0e10cSrcweir 
2360cdf0e10cSrcweir 								if (bAsianVertical && bBreak)
2361cdf0e10cSrcweir 								{
2362cdf0e10cSrcweir 									//	add some extra height (default margin value) for safety
2363cdf0e10cSrcweir 									//	as long as GetEditArea isn't used below
2364cdf0e10cSrcweir 									long nExtraHeight = (long)( 20 * nPPTY );
2365cdf0e10cSrcweir                                     aPaperSize.Height() = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM + nExtraHeight;
2366cdf0e10cSrcweir 								}
2367cdf0e10cSrcweir 							}
2368cdf0e10cSrcweir 							if (bPixelToLogic)
2369cdf0e10cSrcweir                             {
2370cdf0e10cSrcweir                                 Size aLogicSize = pRefDevice->PixelToLogic(aPaperSize);
2371cdf0e10cSrcweir                                 if ( bBreak && !bAsianVertical && pRefDevice != pFmtDevice )
2372cdf0e10cSrcweir                                 {
2373cdf0e10cSrcweir                                     // #i85342# screen display and formatting for printer,
2374cdf0e10cSrcweir                                     // use same GetEditArea call as in ScViewData::SetEditEngine
2375cdf0e10cSrcweir 
2376cdf0e10cSrcweir                                     Fraction aFract(1,1);
2377cdf0e10cSrcweir                                     Rectangle aUtilRect = ScEditUtil( pDoc, nCellX, nCellY, nTab, Point(0,0), pFmtDevice,
2378cdf0e10cSrcweir                                         HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( pPattern, sal_False );
2379cdf0e10cSrcweir                                     aLogicSize.Width() = aUtilRect.GetWidth();
2380cdf0e10cSrcweir                                 }
2381cdf0e10cSrcweir                                 pEngine->SetPaperSize(aLogicSize);
2382cdf0e10cSrcweir                             }
2383cdf0e10cSrcweir 							else
2384cdf0e10cSrcweir 								pEngine->SetPaperSize(aPaperSize);
2385cdf0e10cSrcweir 
2386cdf0e10cSrcweir 							//
2387cdf0e10cSrcweir 							//	Fill the EditEngine (cell attributes and text)
2388cdf0e10cSrcweir 							//
2389cdf0e10cSrcweir 
2390cdf0e10cSrcweir 							SvxCellVerJustify eVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)
2391cdf0e10cSrcweir 												pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet)).GetValue();
2392cdf0e10cSrcweir 
2393cdf0e10cSrcweir 							// default alignment for asian vertical mode is top-right
2394cdf0e10cSrcweir 							if ( bAsianVertical && eVerJust == SVX_VER_JUSTIFY_STANDARD )
2395cdf0e10cSrcweir 								eVerJust = SVX_VER_JUSTIFY_TOP;
2396cdf0e10cSrcweir 
2397cdf0e10cSrcweir 							// syntax highlighting mode is ignored here
2398cdf0e10cSrcweir 							// StringDiffer doesn't look at hyphenate, language items
2399cdf0e10cSrcweir 							if ( pPattern != pOldPattern || pCondSet != pOldCondSet )
2400cdf0e10cSrcweir 							{
2401cdf0e10cSrcweir 								SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
2402cdf0e10cSrcweir 								pPattern->FillEditItemSet( pSet, pCondSet );
2403cdf0e10cSrcweir 
2404cdf0e10cSrcweir 								pEngine->SetDefaults( pSet );
2405cdf0e10cSrcweir 								pOldPattern = pPattern;
2406cdf0e10cSrcweir 								pOldCondSet = pCondSet;
2407cdf0e10cSrcweir 
2408cdf0e10cSrcweir 								sal_uLong nControl = pEngine->GetControlWord();
2409cdf0e10cSrcweir 								if (eOrient==SVX_ORIENTATION_STACKED)
2410cdf0e10cSrcweir 									nControl |= EE_CNTRL_ONECHARPERLINE;
2411cdf0e10cSrcweir 								else
2412cdf0e10cSrcweir 									nControl &= ~EE_CNTRL_ONECHARPERLINE;
2413cdf0e10cSrcweir 								pEngine->SetControlWord( nControl );
2414cdf0e10cSrcweir 
2415cdf0e10cSrcweir 								if ( !bHyphenatorSet && ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() )
2416cdf0e10cSrcweir 								{
2417cdf0e10cSrcweir 									//	set hyphenator the first time it is needed
2418cdf0e10cSrcweir                                     com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
2419cdf0e10cSrcweir 									pEngine->SetHyphenator( xXHyphenator );
2420cdf0e10cSrcweir 									bHyphenatorSet = sal_True;
2421cdf0e10cSrcweir 								}
2422cdf0e10cSrcweir 
2423cdf0e10cSrcweir 								Color aBackCol = ((const SvxBrushItem&)
2424cdf0e10cSrcweir 									pPattern->GetItem( ATTR_BACKGROUND, pCondSet )).GetColor();
2425cdf0e10cSrcweir 								if ( bUseStyleColor && ( aBackCol.GetTransparency() > 0 || bCellContrast ) )
2426cdf0e10cSrcweir 									aBackCol.SetColor( nConfBackColor );
2427cdf0e10cSrcweir 								pEngine->SetBackgroundColor( aBackCol );
2428cdf0e10cSrcweir 							}
2429cdf0e10cSrcweir 
2430cdf0e10cSrcweir 							//	horizontal alignment now may depend on cell content
2431cdf0e10cSrcweir 							//	(for values with number formats with mixed script types)
2432cdf0e10cSrcweir 							//	-> always set adjustment
2433cdf0e10cSrcweir 
2434cdf0e10cSrcweir 							SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
2435cdf0e10cSrcweir 							if (eOrient==SVX_ORIENTATION_STACKED)
2436cdf0e10cSrcweir 								eSvxAdjust = SVX_ADJUST_CENTER;
2437cdf0e10cSrcweir 							else if (bBreak)
2438cdf0e10cSrcweir 							{
2439cdf0e10cSrcweir 								if (eOrient==SVX_ORIENTATION_STANDARD && !bAsianVertical)
2440cdf0e10cSrcweir 									switch (eHorJust)
2441cdf0e10cSrcweir 									{
2442cdf0e10cSrcweir 										case SVX_HOR_JUSTIFY_STANDARD:
2443cdf0e10cSrcweir 											eSvxAdjust = bCellIsValue ? SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
2444cdf0e10cSrcweir 											break;
2445cdf0e10cSrcweir 										case SVX_HOR_JUSTIFY_LEFT:
2446cdf0e10cSrcweir 										case SVX_HOR_JUSTIFY_REPEAT:			// nicht implementiert
2447cdf0e10cSrcweir 											eSvxAdjust = SVX_ADJUST_LEFT;
2448cdf0e10cSrcweir 											break;
2449cdf0e10cSrcweir 										case SVX_HOR_JUSTIFY_RIGHT:
2450cdf0e10cSrcweir 											eSvxAdjust = SVX_ADJUST_RIGHT;
2451cdf0e10cSrcweir 											break;
2452cdf0e10cSrcweir 										case SVX_HOR_JUSTIFY_CENTER:
2453cdf0e10cSrcweir 											eSvxAdjust = SVX_ADJUST_CENTER;
2454cdf0e10cSrcweir 											break;
2455cdf0e10cSrcweir 										case SVX_HOR_JUSTIFY_BLOCK:
2456cdf0e10cSrcweir 											eSvxAdjust = SVX_ADJUST_BLOCK;
2457cdf0e10cSrcweir 											break;
2458cdf0e10cSrcweir 									}
2459cdf0e10cSrcweir 								else
2460cdf0e10cSrcweir 									switch (eVerJust)
2461cdf0e10cSrcweir 									{
2462cdf0e10cSrcweir 										case SVX_VER_JUSTIFY_TOP:
2463cdf0e10cSrcweir 											eSvxAdjust = (eOrient==SVX_ORIENTATION_TOPBOTTOM || bAsianVertical) ?
2464cdf0e10cSrcweir 														SVX_ADJUST_LEFT : SVX_ADJUST_RIGHT;
2465cdf0e10cSrcweir 											break;
2466cdf0e10cSrcweir 										case SVX_VER_JUSTIFY_CENTER:
2467cdf0e10cSrcweir 											eSvxAdjust = SVX_ADJUST_CENTER;
2468cdf0e10cSrcweir 											break;
2469cdf0e10cSrcweir 										case SVX_VER_JUSTIFY_BOTTOM:
2470cdf0e10cSrcweir 										case SVX_HOR_JUSTIFY_STANDARD:
2471cdf0e10cSrcweir 											eSvxAdjust = (eOrient==SVX_ORIENTATION_TOPBOTTOM || bAsianVertical) ?
2472cdf0e10cSrcweir 														SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
2473cdf0e10cSrcweir 											break;
2474cdf0e10cSrcweir 									}
2475cdf0e10cSrcweir 							}
2476cdf0e10cSrcweir 							pEngine->SetDefaultItem( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
2477cdf0e10cSrcweir 
2478cdf0e10cSrcweir 							//	Read content from cell
2479cdf0e10cSrcweir 
2480cdf0e10cSrcweir 							sal_Bool bWrapFields = sal_False;
2481cdf0e10cSrcweir 							if (pCell)
2482cdf0e10cSrcweir 							{
2483cdf0e10cSrcweir 								if (pCell->GetCellType() == CELLTYPE_EDIT)
2484cdf0e10cSrcweir 								{
2485cdf0e10cSrcweir 									const EditTextObject* pData;
2486cdf0e10cSrcweir 									((ScEditCell*)pCell)->GetData(pData);
2487cdf0e10cSrcweir 
2488cdf0e10cSrcweir 									if (pData)
2489cdf0e10cSrcweir 									{
2490cdf0e10cSrcweir 										pEngine->SetText(*pData);
2491cdf0e10cSrcweir 
2492cdf0e10cSrcweir 										if ( bBreak && !bAsianVertical && pData->HasField() )
2493cdf0e10cSrcweir 										{
2494cdf0e10cSrcweir 											//	Fields aren't wrapped, so clipping is enabled to prevent
2495cdf0e10cSrcweir 											//	a field from being drawn beyond the cell size
2496cdf0e10cSrcweir 
2497cdf0e10cSrcweir 											bWrapFields = sal_True;
2498cdf0e10cSrcweir 										}
2499cdf0e10cSrcweir 									}
2500cdf0e10cSrcweir 									else
2501cdf0e10cSrcweir 									{
2502cdf0e10cSrcweir 										DBG_ERROR("pData == 0");
2503cdf0e10cSrcweir 									}
2504cdf0e10cSrcweir 								}
2505cdf0e10cSrcweir 								else
2506cdf0e10cSrcweir 								{
2507cdf0e10cSrcweir 									sal_uLong nFormat = pPattern->GetNumberFormat(
2508cdf0e10cSrcweir 																pDoc->GetFormatTable(), pCondSet );
2509cdf0e10cSrcweir 									String aString;
2510cdf0e10cSrcweir 									Color* pColor;
2511cdf0e10cSrcweir 									ScCellFormat::GetString( pCell,
2512cdf0e10cSrcweir 															 nFormat,aString, &pColor,
2513cdf0e10cSrcweir 															 *pDoc->GetFormatTable(),
2514cdf0e10cSrcweir 															 bShowNullValues,
2515cdf0e10cSrcweir 															 bShowFormulas,
2516cdf0e10cSrcweir 															 ftCheck );
2517cdf0e10cSrcweir 
2518cdf0e10cSrcweir 									pEngine->SetText(aString);
2519cdf0e10cSrcweir 									if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
2520cdf0e10cSrcweir 										lcl_SetEditColor( *pEngine, *pColor );
2521cdf0e10cSrcweir 								}
2522cdf0e10cSrcweir 
2523cdf0e10cSrcweir 								if ( bSyntaxMode )
2524cdf0e10cSrcweir 									SetEditSyntaxColor( *pEngine, pCell );
2525cdf0e10cSrcweir 								else if ( bUseStyleColor && bForceAutoColor )
2526cdf0e10cSrcweir 									lcl_SetEditColor( *pEngine, COL_AUTO );		//! or have a flag at EditEngine
2527cdf0e10cSrcweir 							}
2528cdf0e10cSrcweir 							else
2529cdf0e10cSrcweir 							{
2530cdf0e10cSrcweir 								DBG_ERROR("pCell == NULL");
2531cdf0e10cSrcweir 							}
2532cdf0e10cSrcweir 
2533cdf0e10cSrcweir 							pEngine->SetVertical( bAsianVertical );
2534cdf0e10cSrcweir 							pEngine->SetUpdateMode( sal_True );		// after SetText, before CalcTextWidth/GetTextHeight
2535cdf0e10cSrcweir 
2536cdf0e10cSrcweir 							//
2537cdf0e10cSrcweir 							//	Get final output area using the calculated width
2538cdf0e10cSrcweir 							//
2539cdf0e10cSrcweir 
2540cdf0e10cSrcweir 							long nEngineWidth;
2541cdf0e10cSrcweir 							if ( bBreak && eOrient != SVX_ORIENTATION_STACKED && !bAsianVertical )
2542cdf0e10cSrcweir 								nEngineWidth = 0;
2543cdf0e10cSrcweir 							else
2544cdf0e10cSrcweir 								nEngineWidth = (long) pEngine->CalcTextWidth();
2545cdf0e10cSrcweir 							long nEngineHeight = pEngine->GetTextHeight();
2546cdf0e10cSrcweir 
2547cdf0e10cSrcweir 							if (eOrient != SVX_ORIENTATION_STANDARD &&
2548cdf0e10cSrcweir 								eOrient != SVX_ORIENTATION_STACKED)
2549cdf0e10cSrcweir 							{
2550cdf0e10cSrcweir 								long nTemp = nEngineWidth;
2551cdf0e10cSrcweir 								nEngineWidth = nEngineHeight;
2552cdf0e10cSrcweir 								nEngineHeight = nTemp;
2553cdf0e10cSrcweir 							}
2554cdf0e10cSrcweir 
2555cdf0e10cSrcweir 							if (eOrient == SVX_ORIENTATION_STACKED)
2556cdf0e10cSrcweir 								nEngineWidth = nEngineWidth * 11 / 10;
2557cdf0e10cSrcweir 
2558cdf0e10cSrcweir 							long nNeededPixel = nEngineWidth;
2559cdf0e10cSrcweir 							if (bPixelToLogic)
2560cdf0e10cSrcweir 								nNeededPixel = pRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
2561cdf0e10cSrcweir 							nNeededPixel += nLeftM + nRightM;
2562cdf0e10cSrcweir 
2563cdf0e10cSrcweir 							if ( ( !bBreak && eOrient != SVX_ORIENTATION_STACKED ) || bAsianVertical || bShrink )
2564cdf0e10cSrcweir 							{
2565cdf0e10cSrcweir 								// for break, the first GetOutputArea call is sufficient
2566cdf0e10cSrcweir 								GetOutputArea( nXForPos, nArrYForPos, nPosX, nPosY, nCellX, nCellY, nNeededPixel,
2567cdf0e10cSrcweir                                                *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
2568cdf0e10cSrcweir                                                bCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
2569cdf0e10cSrcweir 
2570cdf0e10cSrcweir                                 if ( bShrink )
2571cdf0e10cSrcweir                                 {
2572cdf0e10cSrcweir                                     sal_Bool bWidth = ( eOrient == SVX_ORIENTATION_STANDARD && !bAsianVertical );
2573cdf0e10cSrcweir                                     ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect,
2574cdf0e10cSrcweir                                         nLeftM, nTopM, nRightM, nBottomM, bWidth,
2575cdf0e10cSrcweir                                         sal::static_int_cast<sal_uInt16>(eOrient), 0, bPixelToLogic,
2576cdf0e10cSrcweir                                         nEngineWidth, nEngineHeight, nNeededPixel,
2577cdf0e10cSrcweir                                         aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
2578cdf0e10cSrcweir                                 }
2579cdf0e10cSrcweir 
2580cdf0e10cSrcweir                                 if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && pEngine->GetParagraphCount() == 1 )
2581cdf0e10cSrcweir                                 {
2582cdf0e10cSrcweir                                     // First check if twice the space for the formatted text is available
2583cdf0e10cSrcweir                                     // (otherwise just keep it unchanged).
2584cdf0e10cSrcweir 
2585cdf0e10cSrcweir                                     long nFormatted = nNeededPixel - nLeftM - nRightM;      // without margin
2586cdf0e10cSrcweir                                     long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
2587cdf0e10cSrcweir                                     if ( nAvailable >= 2 * nFormatted )
2588cdf0e10cSrcweir                                     {
2589cdf0e10cSrcweir                                         // "repeat" is handled with unformatted text (for performance reasons)
2590cdf0e10cSrcweir                                         String aCellStr = pEngine->GetText();
2591cdf0e10cSrcweir                                         pEngine->SetText( aCellStr );
2592cdf0e10cSrcweir 
2593cdf0e10cSrcweir                                         long nRepeatSize = (long) pEngine->CalcTextWidth();
2594cdf0e10cSrcweir                                         if (bPixelToLogic)
2595cdf0e10cSrcweir                                             nRepeatSize = pRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
2596cdf0e10cSrcweir                                         if ( pFmtDevice != pRefDevice )
2597cdf0e10cSrcweir                                             ++nRepeatSize;
2598cdf0e10cSrcweir                                         if ( nRepeatSize > 0 )
2599cdf0e10cSrcweir                                         {
2600cdf0e10cSrcweir                                             long nRepeatCount = nAvailable / nRepeatSize;
2601cdf0e10cSrcweir                                             if ( nRepeatCount > 1 )
2602cdf0e10cSrcweir                                             {
2603cdf0e10cSrcweir                                                 String aRepeated = aCellStr;
2604cdf0e10cSrcweir                                                 for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
2605cdf0e10cSrcweir                                                     aRepeated.Append( aCellStr );
2606cdf0e10cSrcweir                                                 pEngine->SetText( aRepeated );
2607cdf0e10cSrcweir 
2608cdf0e10cSrcweir                                                 nEngineHeight = pEngine->GetTextHeight();
2609cdf0e10cSrcweir                                                 nEngineWidth = (long) pEngine->CalcTextWidth();
2610cdf0e10cSrcweir                                                 if (bPixelToLogic)
2611cdf0e10cSrcweir                                                 	nNeededPixel = pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
2612cdf0e10cSrcweir                                                 else
2613cdf0e10cSrcweir                                                     nNeededPixel = nEngineWidth;
2614cdf0e10cSrcweir                                                 nNeededPixel += nLeftM + nRightM;
2615cdf0e10cSrcweir                                             }
2616cdf0e10cSrcweir                                         }
2617cdf0e10cSrcweir                                     }
2618cdf0e10cSrcweir                                 }
2619cdf0e10cSrcweir 
2620cdf0e10cSrcweir                                 if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
2621cdf0e10cSrcweir 								{
2622cdf0e10cSrcweir 									pEngine->SetText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) );
2623cdf0e10cSrcweir 									nEngineWidth = (long) pEngine->CalcTextWidth();
2624cdf0e10cSrcweir 									if (bPixelToLogic)
2625cdf0e10cSrcweir 										nNeededPixel = pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
2626cdf0e10cSrcweir 									else
2627cdf0e10cSrcweir 										nNeededPixel = nEngineWidth;
2628cdf0e10cSrcweir 									nNeededPixel += nLeftM + nRightM;
2629cdf0e10cSrcweir 
2630cdf0e10cSrcweir 									//	No clip marks if "###" doesn't fit (same as in DrawStrings)
2631cdf0e10cSrcweir 								}
2632cdf0e10cSrcweir 
2633cdf0e10cSrcweir 								if ( eOutHorJust != SVX_HOR_JUSTIFY_LEFT && eOrient == SVX_ORIENTATION_STANDARD )
2634cdf0e10cSrcweir 								{
2635cdf0e10cSrcweir 									aPaperSize.Width() = nNeededPixel + 1;
2636cdf0e10cSrcweir 									if (bPixelToLogic)
2637cdf0e10cSrcweir 										pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
2638cdf0e10cSrcweir 									else
2639cdf0e10cSrcweir 										pEngine->SetPaperSize(aPaperSize);
2640cdf0e10cSrcweir 								}
2641cdf0e10cSrcweir 							}
2642cdf0e10cSrcweir 
2643cdf0e10cSrcweir                             long nStartX = aAreaParam.maAlignRect.Left();
2644cdf0e10cSrcweir                             long nStartY = aAreaParam.maAlignRect.Top();
2645cdf0e10cSrcweir                             long nCellWidth = aAreaParam.maAlignRect.GetWidth();
2646cdf0e10cSrcweir 							long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
2647cdf0e10cSrcweir                             long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
2648cdf0e10cSrcweir 
2649cdf0e10cSrcweir 							if ( bBreak || eOrient != SVX_ORIENTATION_STANDARD || bAsianVertical )
2650cdf0e10cSrcweir 							{
2651cdf0e10cSrcweir 								//	text with automatic breaks is aligned only within the
2652cdf0e10cSrcweir 								//	edit engine's paper size, the output of the whole area
2653cdf0e10cSrcweir 								//	is always left-aligned
2654cdf0e10cSrcweir 
2655cdf0e10cSrcweir 								nStartX += nLeftM;
2656cdf0e10cSrcweir 							}
2657cdf0e10cSrcweir 							else
2658cdf0e10cSrcweir 							{
2659cdf0e10cSrcweir 								if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
2660cdf0e10cSrcweir 									nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
2661cdf0e10cSrcweir 								else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
2662cdf0e10cSrcweir 									nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
2663cdf0e10cSrcweir 								else
2664cdf0e10cSrcweir 									nStartX += nLeftM;
2665cdf0e10cSrcweir 							}
2666cdf0e10cSrcweir 
2667cdf0e10cSrcweir                             sal_Bool bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW );
2668cdf0e10cSrcweir                             if ( aAreaParam.maClipRect.Left() < nScrX )
2669cdf0e10cSrcweir 							{
2670cdf0e10cSrcweir                                 aAreaParam.maClipRect.Left() = nScrX;
2671cdf0e10cSrcweir                                 aAreaParam.mbLeftClip = true;
2672cdf0e10cSrcweir 							}
2673cdf0e10cSrcweir                             if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
2674cdf0e10cSrcweir 							{
2675cdf0e10cSrcweir                                 aAreaParam.maClipRect.Right() = nScrX + nScrW;			//! minus one?
2676cdf0e10cSrcweir                                 aAreaParam.mbRightClip = true;
2677cdf0e10cSrcweir 							}
2678cdf0e10cSrcweir 
2679cdf0e10cSrcweir 							if ( !bHidden && !bOutside )
2680cdf0e10cSrcweir 							{
2681cdf0e10cSrcweir                                 bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
2682cdf0e10cSrcweir 								sal_Bool bSimClip = sal_False;
2683cdf0e10cSrcweir 
2684cdf0e10cSrcweir 								if ( bWrapFields )
2685cdf0e10cSrcweir 								{
2686cdf0e10cSrcweir 									//	Fields in a cell with automatic breaks: clip to cell width
2687cdf0e10cSrcweir 									bClip = sal_True;
2688cdf0e10cSrcweir 								}
2689cdf0e10cSrcweir 
2690cdf0e10cSrcweir                                 if ( aAreaParam.maClipRect.Top() < nScrY )
2691cdf0e10cSrcweir                                 {
2692cdf0e10cSrcweir                                     aAreaParam.maClipRect.Top() = nScrY;
2693cdf0e10cSrcweir                                     bClip = sal_True;
2694cdf0e10cSrcweir                                 }
2695cdf0e10cSrcweir                                 if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
2696cdf0e10cSrcweir                                 {
2697cdf0e10cSrcweir                                     aAreaParam.maClipRect.Bottom() = nScrY + nScrH;     //! minus one?
2698cdf0e10cSrcweir                                     bClip = sal_True;
2699cdf0e10cSrcweir                                 }
2700cdf0e10cSrcweir 
2701cdf0e10cSrcweir 								Size aCellSize;			// output area, excluding margins, in logical units
2702cdf0e10cSrcweir 								if (bPixelToLogic)
2703cdf0e10cSrcweir 									aCellSize = pRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
2704cdf0e10cSrcweir 								else
2705cdf0e10cSrcweir 									aCellSize = Size( nOutWidth, nOutHeight );
2706cdf0e10cSrcweir 
2707cdf0e10cSrcweir 								if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
2708cdf0e10cSrcweir 								{
2709cdf0e10cSrcweir 									const ScMergeAttr* pMerge =
2710cdf0e10cSrcweir 											(ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
2711cdf0e10cSrcweir 									sal_Bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
2712cdf0e10cSrcweir 
2713cdf0e10cSrcweir 									//	Don't clip for text height when printing rows with optimal height,
2714cdf0e10cSrcweir 									//	except when font size is from conditional formatting.
2715cdf0e10cSrcweir 									//!	Allow clipping when vertically merged?
2716cdf0e10cSrcweir 									if ( eType != OUTTYPE_PRINTER ||
2717cdf0e10cSrcweir 										( pDoc->GetRowFlags( nCellY, nTab ) & CR_MANUALSIZE ) ||
2718cdf0e10cSrcweir 										( pCondSet && SFX_ITEM_SET ==
2719cdf0e10cSrcweir 											pCondSet->GetItemState(ATTR_FONT_HEIGHT, sal_True) ) )
2720cdf0e10cSrcweir 										bClip = sal_True;
2721cdf0e10cSrcweir 									else
2722cdf0e10cSrcweir 										bSimClip = sal_True;
2723cdf0e10cSrcweir 
2724cdf0e10cSrcweir 									//	Show clip marks if height is at least 5pt too small and
2725cdf0e10cSrcweir 									//	there are several lines of text.
2726cdf0e10cSrcweir 									//	Not for asian vertical text, because that would interfere
2727cdf0e10cSrcweir 									//	with the default right position of the text.
2728cdf0e10cSrcweir 									//	Only with automatic line breaks, to avoid having to find
2729cdf0e10cSrcweir 									//	the cells with the horizontal end of the text again.
2730cdf0e10cSrcweir 									if ( nEngineHeight - aCellSize.Height() > 100 &&
2731cdf0e10cSrcweir 										 ( bBreak || eOrient == SVX_ORIENTATION_STACKED ) &&
2732cdf0e10cSrcweir 										 !bAsianVertical && bMarkClipped &&
2733cdf0e10cSrcweir 										 ( pEngine->GetParagraphCount() > 1 || pEngine->GetLineCount(0) > 1 ) )
2734cdf0e10cSrcweir 									{
2735cdf0e10cSrcweir 										CellInfo* pClipMarkCell = NULL;
2736cdf0e10cSrcweir 										if ( bMerged )
2737cdf0e10cSrcweir 										{
2738cdf0e10cSrcweir 											//	anywhere in the merged area...
2739cdf0e10cSrcweir 											SCCOL nClipX = ( nX < nX1 ) ? nX1 : nX;
2740cdf0e10cSrcweir 											pClipMarkCell = &pRowInfo[(nArrY != 0) ? nArrY : 1].pCellInfo[nClipX+1];
2741cdf0e10cSrcweir 										}
2742cdf0e10cSrcweir 										else
2743cdf0e10cSrcweir 											pClipMarkCell = &pThisRowInfo->pCellInfo[nX+1];
2744cdf0e10cSrcweir 
2745cdf0e10cSrcweir 										pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT;		//! also allow left?
2746cdf0e10cSrcweir 										bAnyClipped = sal_True;
2747cdf0e10cSrcweir 
2748cdf0e10cSrcweir 										long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
2749cdf0e10cSrcweir                                         if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
2750cdf0e10cSrcweir                                             aAreaParam.maClipRect.Right() -= nMarkPixel;
2751cdf0e10cSrcweir 									}
2752cdf0e10cSrcweir 								}
2753cdf0e10cSrcweir 
2754cdf0e10cSrcweir #if 0
2755cdf0e10cSrcweir 								long nClipStartY = nStartY;
2756cdf0e10cSrcweir 								if (nArrY==0 || bVisChanged)
2757cdf0e10cSrcweir 								{
2758cdf0e10cSrcweir 									if ( nClipStartY < nRowPosY )
2759cdf0e10cSrcweir 									{
2760cdf0e10cSrcweir 										long nDif = nRowPosY - nClipStartY;
2761cdf0e10cSrcweir 										bClip = sal_True;
2762cdf0e10cSrcweir 										nClipStartY = nRowPosY;
2763cdf0e10cSrcweir 										aClipSize.Height() -= nDif;
2764cdf0e10cSrcweir 									}
2765cdf0e10cSrcweir 								}
2766cdf0e10cSrcweir #endif
2767cdf0e10cSrcweir 
2768cdf0e10cSrcweir 								Rectangle aLogicClip;
2769cdf0e10cSrcweir 								if (bClip || bSimClip)
2770cdf0e10cSrcweir 								{
2771cdf0e10cSrcweir 									// Clip marks are already handled in GetOutputArea
2772cdf0e10cSrcweir 
2773cdf0e10cSrcweir 									if (bPixelToLogic)
2774cdf0e10cSrcweir                                         aLogicClip = pRefDevice->PixelToLogic( aAreaParam.maClipRect );
2775cdf0e10cSrcweir 									else
2776cdf0e10cSrcweir                                         aLogicClip = aAreaParam.maClipRect;
2777cdf0e10cSrcweir 
2778cdf0e10cSrcweir 									if (bClip)	// bei bSimClip nur aClipRect initialisieren
2779cdf0e10cSrcweir 									{
2780cdf0e10cSrcweir 										if (bMetaFile)
2781cdf0e10cSrcweir 										{
2782cdf0e10cSrcweir 											pDev->Push();
2783cdf0e10cSrcweir 											pDev->IntersectClipRegion( aLogicClip );
2784cdf0e10cSrcweir 										}
2785cdf0e10cSrcweir 										else
2786cdf0e10cSrcweir 											pDev->SetClipRegion( Region( aLogicClip ) );
2787cdf0e10cSrcweir 									}
2788cdf0e10cSrcweir 								}
2789cdf0e10cSrcweir 
2790cdf0e10cSrcweir 								Point aLogicStart;
2791cdf0e10cSrcweir 								if (bPixelToLogic)
2792cdf0e10cSrcweir 									aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
2793cdf0e10cSrcweir 								else
2794cdf0e10cSrcweir 									aLogicStart = Point(nStartX, nStartY);
2795cdf0e10cSrcweir 								if ( eOrient!=SVX_ORIENTATION_STANDARD || bAsianVertical || !bBreak )
2796cdf0e10cSrcweir 								{
2797cdf0e10cSrcweir 									long nAvailWidth = aCellSize.Width();
2798cdf0e10cSrcweir                                     // space for AutoFilter is already handled in GetOutputArea
2799cdf0e10cSrcweir 
2800cdf0e10cSrcweir 									//	horizontal alignment
2801cdf0e10cSrcweir 
2802cdf0e10cSrcweir 									if (eOrient==SVX_ORIENTATION_STANDARD && !bAsianVertical)
2803cdf0e10cSrcweir 									{
2804cdf0e10cSrcweir 										if (eHorJust==SVX_HOR_JUSTIFY_RIGHT ||
2805cdf0e10cSrcweir 											eHorJust==SVX_HOR_JUSTIFY_CENTER ||
2806cdf0e10cSrcweir 											(eHorJust==SVX_HOR_JUSTIFY_STANDARD && bCellIsValue) )
2807cdf0e10cSrcweir 										{
2808cdf0e10cSrcweir 											pEngine->SetUpdateMode( sal_False );
2809cdf0e10cSrcweir 
2810cdf0e10cSrcweir 											SvxAdjust eEditAdjust =
2811cdf0e10cSrcweir 												(eHorJust==SVX_HOR_JUSTIFY_CENTER) ?
2812cdf0e10cSrcweir 													SVX_ADJUST_CENTER : SVX_ADJUST_RIGHT;
2813cdf0e10cSrcweir 											pEngine->SetDefaultItem(
2814cdf0e10cSrcweir 												SvxAdjustItem( eEditAdjust, EE_PARA_JUST ) );
2815cdf0e10cSrcweir 
2816cdf0e10cSrcweir 											// #55142# reset adjustment for the next cell
2817cdf0e10cSrcweir 											pOldPattern = NULL;
2818cdf0e10cSrcweir 
2819cdf0e10cSrcweir 											pEngine->SetUpdateMode( sal_True );
2820cdf0e10cSrcweir 										}
2821cdf0e10cSrcweir 									}
2822cdf0e10cSrcweir 									else
2823cdf0e10cSrcweir 									{
2824cdf0e10cSrcweir 										if (eHorJust==SVX_HOR_JUSTIFY_RIGHT)
2825cdf0e10cSrcweir 											aLogicStart.X() += nAvailWidth - nEngineWidth;
2826cdf0e10cSrcweir 										else if (eHorJust==SVX_HOR_JUSTIFY_CENTER)
2827cdf0e10cSrcweir 											aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
2828cdf0e10cSrcweir 									}
2829cdf0e10cSrcweir 								}
2830cdf0e10cSrcweir 
2831cdf0e10cSrcweir 								if ( bAsianVertical )
2832cdf0e10cSrcweir 								{
2833cdf0e10cSrcweir 									// paper size is subtracted below
2834cdf0e10cSrcweir 									aLogicStart.X() += nEngineWidth;
2835cdf0e10cSrcweir 								}
2836cdf0e10cSrcweir 
2837cdf0e10cSrcweir 								if ( ( bAsianVertical || eOrient == SVX_ORIENTATION_TOPBOTTOM ||
2838cdf0e10cSrcweir 										eOrient == SVX_ORIENTATION_BOTTOMTOP ) && bBreak )
2839cdf0e10cSrcweir 								{
2840cdf0e10cSrcweir 									// vertical adjustment is within the EditEngine
2841cdf0e10cSrcweir 									if (bPixelToLogic)
2842cdf0e10cSrcweir 										aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
2843cdf0e10cSrcweir 									else
2844cdf0e10cSrcweir 										aLogicStart.Y() += nTopM;
2845cdf0e10cSrcweir 								}
2846cdf0e10cSrcweir 
2847cdf0e10cSrcweir 								if ( ( eOrient==SVX_ORIENTATION_STANDARD && !bAsianVertical ) ||
2848cdf0e10cSrcweir 									 eOrient==SVX_ORIENTATION_STACKED || !bBreak )
2849cdf0e10cSrcweir 								{
2850cdf0e10cSrcweir 									if (eVerJust==SVX_VER_JUSTIFY_BOTTOM ||
2851cdf0e10cSrcweir 										eVerJust==SVX_VER_JUSTIFY_STANDARD)
2852cdf0e10cSrcweir 									{
2853cdf0e10cSrcweir 										//!	if pRefDevice != pFmtDevice, keep heights in logic units,
2854cdf0e10cSrcweir 										//! only converting margin?
2855cdf0e10cSrcweir 
2856cdf0e10cSrcweir 										if (bPixelToLogic)
2857cdf0e10cSrcweir 											aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0, nTopM +
2858cdf0e10cSrcweir 															pRefDevice->LogicToPixel(aCellSize).Height() -
2859cdf0e10cSrcweir 															pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
2860cdf0e10cSrcweir 															)).Height();
2861cdf0e10cSrcweir 										else
2862cdf0e10cSrcweir 											aLogicStart.Y() += nTopM + aCellSize.Height() - nEngineHeight;
2863cdf0e10cSrcweir 									}
2864cdf0e10cSrcweir 									else if (eVerJust==SVX_VER_JUSTIFY_CENTER)
2865cdf0e10cSrcweir 									{
2866cdf0e10cSrcweir 										if (bPixelToLogic)
2867cdf0e10cSrcweir 											aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0, nTopM + (
2868cdf0e10cSrcweir 															pRefDevice->LogicToPixel(aCellSize).Height() -
2869cdf0e10cSrcweir 															pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height() )
2870cdf0e10cSrcweir 															/ 2)).Height();
2871cdf0e10cSrcweir 										else
2872cdf0e10cSrcweir 											aLogicStart.Y() += nTopM + (aCellSize.Height() - nEngineHeight) / 2;
2873cdf0e10cSrcweir 									}
2874cdf0e10cSrcweir 									else		// top
2875cdf0e10cSrcweir 									{
2876cdf0e10cSrcweir 										if (bPixelToLogic)
2877cdf0e10cSrcweir 											aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
2878cdf0e10cSrcweir 										else
2879cdf0e10cSrcweir 											aLogicStart.Y() += nTopM;
2880cdf0e10cSrcweir 									}
2881cdf0e10cSrcweir 								}
2882cdf0e10cSrcweir 
2883cdf0e10cSrcweir                                 Point aURLStart = aLogicStart;      // copy before modifying for orientation
2884cdf0e10cSrcweir 
2885cdf0e10cSrcweir 								short nOriVal = 0;
2886cdf0e10cSrcweir 								if (eOrient==SVX_ORIENTATION_TOPBOTTOM)
2887cdf0e10cSrcweir 								{
2888cdf0e10cSrcweir 									// nOriVal = -900;
2889cdf0e10cSrcweir 									nOriVal = 2700;
2890cdf0e10cSrcweir 									aLogicStart.X() += nEngineWidth;
2891cdf0e10cSrcweir 								}
2892cdf0e10cSrcweir 								else if (eOrient==SVX_ORIENTATION_BOTTOMTOP)
2893cdf0e10cSrcweir 								{
2894cdf0e10cSrcweir 									nOriVal = 900;
2895cdf0e10cSrcweir 									aLogicStart.Y() += bBreak ? pEngine->GetPaperSize().Width() :
2896cdf0e10cSrcweir 																nEngineHeight;
2897cdf0e10cSrcweir 								}
2898cdf0e10cSrcweir 								else if (eOrient==SVX_ORIENTATION_STACKED)
2899cdf0e10cSrcweir 								{
2900cdf0e10cSrcweir 									Size aPaperLogic = pEngine->GetPaperSize();
2901cdf0e10cSrcweir 									aPaperLogic.Width() = nEngineWidth;
2902cdf0e10cSrcweir 									pEngine->SetPaperSize(aPaperLogic);
2903cdf0e10cSrcweir 								}
2904cdf0e10cSrcweir 
2905cdf0e10cSrcweir 								if ( pEngine->IsRightToLeft( 0 ) )
2906cdf0e10cSrcweir 								{
2907cdf0e10cSrcweir 									//	For right-to-left, EditEngine always calculates its lines
2908cdf0e10cSrcweir 									//	beginning from the right edge, but EditLine::nStartPosX is
2909cdf0e10cSrcweir 									//	of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
2910cdf0e10cSrcweir 									Size aLogicPaper = pEngine->GetPaperSize();
2911cdf0e10cSrcweir 									if ( aLogicPaper.Width() > USHRT_MAX )
2912cdf0e10cSrcweir 									{
2913cdf0e10cSrcweir 										aLogicPaper.Width() = USHRT_MAX;
2914cdf0e10cSrcweir 										pEngine->SetPaperSize(aLogicPaper);
2915cdf0e10cSrcweir 									}
2916cdf0e10cSrcweir 								}
2917cdf0e10cSrcweir 
2918cdf0e10cSrcweir 								// bMoveClipped handling has been replaced by complete alignment
2919cdf0e10cSrcweir 								// handling (also extending to the left).
2920cdf0e10cSrcweir 
2921cdf0e10cSrcweir 								if ( bSimClip && !nOriVal && !bAsianVertical )
2922cdf0e10cSrcweir 								{
2923cdf0e10cSrcweir 									//	kein hartes Clipping, aber nur die betroffenen
2924cdf0e10cSrcweir 									//	Zeilen ausgeben
2925cdf0e10cSrcweir 
2926cdf0e10cSrcweir 									Point aDocStart = aLogicClip.TopLeft();
2927cdf0e10cSrcweir 									aDocStart -= aLogicStart;
2928cdf0e10cSrcweir 									pEngine->Draw( pDev, aLogicClip, aDocStart, sal_False );
2929cdf0e10cSrcweir 								}
2930cdf0e10cSrcweir 								else
2931cdf0e10cSrcweir 								{
2932cdf0e10cSrcweir 									if (bAsianVertical)
2933cdf0e10cSrcweir 									{
2934cdf0e10cSrcweir 										//	with SetVertical, the start position is top left of
2935cdf0e10cSrcweir 										//	the whole output area, not the text itself
2936cdf0e10cSrcweir 										aLogicStart.X() -= pEngine->GetPaperSize().Width();
2937cdf0e10cSrcweir 									}
2938cdf0e10cSrcweir 									pEngine->Draw( pDev, aLogicStart, nOriVal );
2939cdf0e10cSrcweir 								}
2940cdf0e10cSrcweir 
2941cdf0e10cSrcweir 								if (bClip)
2942cdf0e10cSrcweir 								{
2943cdf0e10cSrcweir 									if (bMetaFile)
2944cdf0e10cSrcweir 										pDev->Pop();
2945cdf0e10cSrcweir 									else
2946cdf0e10cSrcweir 										pDev->SetClipRegion();
2947cdf0e10cSrcweir 								}
2948cdf0e10cSrcweir 
2949cdf0e10cSrcweir                                 // PDF: whole-cell hyperlink from formula?
2950cdf0e10cSrcweir                                 sal_Bool bHasURL = pPDFData && pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
2951cdf0e10cSrcweir                                                 static_cast<ScFormulaCell*>(pCell)->IsHyperLinkCell();
2952cdf0e10cSrcweir                                 if ( bHasURL )
2953cdf0e10cSrcweir                                 {
2954cdf0e10cSrcweir                                     long nURLWidth = (long) pEngine->CalcTextWidth();
2955cdf0e10cSrcweir                                     long nURLHeight = pEngine->GetTextHeight();
2956cdf0e10cSrcweir                                     if ( bBreak )
2957cdf0e10cSrcweir                                     {
2958cdf0e10cSrcweir                                         Size aPaper = pEngine->GetPaperSize();
2959cdf0e10cSrcweir                                         if ( bAsianVertical )
2960cdf0e10cSrcweir                                             nURLHeight = aPaper.Height();
2961cdf0e10cSrcweir                                         else
2962cdf0e10cSrcweir                                             nURLWidth = aPaper.Width();
2963cdf0e10cSrcweir                                     }
2964cdf0e10cSrcweir                                     if ( eOrient == SVX_ORIENTATION_TOPBOTTOM || eOrient == SVX_ORIENTATION_BOTTOMTOP )
2965cdf0e10cSrcweir                                         std::swap( nURLWidth, nURLHeight );
2966cdf0e10cSrcweir                                     else if ( bAsianVertical )
2967cdf0e10cSrcweir                                         aURLStart.X() -= nURLWidth;
2968cdf0e10cSrcweir 
2969cdf0e10cSrcweir                                     Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
2970cdf0e10cSrcweir                                     lcl_DoHyperlinkResult( pDev, aURLRect, pCell );
2971cdf0e10cSrcweir                                 }
2972cdf0e10cSrcweir 							}
2973cdf0e10cSrcweir 						}
2974cdf0e10cSrcweir 					}
2975cdf0e10cSrcweir 				}
2976cdf0e10cSrcweir 				nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2977cdf0e10cSrcweir 			}
2978cdf0e10cSrcweir 		}
2979cdf0e10cSrcweir 		nRowPosY += pRowInfo[nArrY].nHeight;
2980cdf0e10cSrcweir 	}
2981cdf0e10cSrcweir 
2982cdf0e10cSrcweir 	delete pEngine;
2983cdf0e10cSrcweir 
2984cdf0e10cSrcweir 	if (bAnyRotated)
2985cdf0e10cSrcweir 		DrawRotated(bPixelToLogic);		//! von aussen rufen ?
2986cdf0e10cSrcweir }
2987cdf0e10cSrcweir 
2988cdf0e10cSrcweir //	-------------------------------------------------------------------------------
2989cdf0e10cSrcweir 
DrawRotated(sal_Bool bPixelToLogic)2990cdf0e10cSrcweir void ScOutputData::DrawRotated(sal_Bool bPixelToLogic)
2991cdf0e10cSrcweir {
2992cdf0e10cSrcweir 	//!	nRotMax speichern
2993cdf0e10cSrcweir 	SCCOL nRotMax = nX2;
2994cdf0e10cSrcweir 	for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
2995cdf0e10cSrcweir 		if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
2996cdf0e10cSrcweir 			nRotMax = pRowInfo[nRotY].nRotMaxCol;
2997cdf0e10cSrcweir 
2998cdf0e10cSrcweir 
2999cdf0e10cSrcweir 	ScModule* pScMod = SC_MOD();
3000cdf0e10cSrcweir     sal_Int32 nConfBackColor = pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
3001cdf0e10cSrcweir 	//	#105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
3002cdf0e10cSrcweir 	sal_Bool bCellContrast = bUseStyleColor &&
3003cdf0e10cSrcweir 			Application::GetSettings().GetStyleSettings().GetHighContrastMode();
3004cdf0e10cSrcweir 
3005cdf0e10cSrcweir 	ScFieldEditEngine* pEngine = NULL;
3006cdf0e10cSrcweir 	sal_Bool bHyphenatorSet = sal_False;
3007cdf0e10cSrcweir 	const ScPatternAttr* pPattern;
3008cdf0e10cSrcweir 	const SfxItemSet*	 pCondSet;
3009cdf0e10cSrcweir 	const ScPatternAttr* pOldPattern = NULL;
3010cdf0e10cSrcweir 	const SfxItemSet*	 pOldCondSet = NULL;
3011cdf0e10cSrcweir 	ScBaseCell* pCell = NULL;
3012cdf0e10cSrcweir 
3013cdf0e10cSrcweir 	long nInitPosX = nScrX;
3014cdf0e10cSrcweir 	if ( bLayoutRTL )
3015cdf0e10cSrcweir 	{
3016cdf0e10cSrcweir #if 0
3017cdf0e10cSrcweir 		Size aOnePixel = pDev->PixelToLogic(Size(1,1));
3018cdf0e10cSrcweir 		long nOneX = aOnePixel.Width();
3019cdf0e10cSrcweir 		nInitPosX += nMirrorW - nOneX;
3020cdf0e10cSrcweir #endif
3021cdf0e10cSrcweir 		nInitPosX += nMirrorW - 1;
3022cdf0e10cSrcweir 	}
3023cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
3024cdf0e10cSrcweir 
3025cdf0e10cSrcweir 	long nRowPosY = nScrY;
3026cdf0e10cSrcweir 	for (SCSIZE nArrY=0; nArrY+1<nArrCount; nArrY++)			// 0 fuer Reste von zusammengefassten
3027cdf0e10cSrcweir 	{
3028cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
3029cdf0e10cSrcweir 		long nCellHeight = (long) pThisRowInfo->nHeight;
3030cdf0e10cSrcweir 		if (nArrY==1) nRowPosY = nScrY;							// vorher wird einzeln berechnet
3031cdf0e10cSrcweir 
3032cdf0e10cSrcweir 		if ( ( pThisRowInfo->bChanged || nArrY==0 ) && pThisRowInfo->nRotMaxCol != SC_ROTMAX_NONE )
3033cdf0e10cSrcweir 		{
3034cdf0e10cSrcweir 			long nPosX = 0;
3035cdf0e10cSrcweir 			for (SCCOL nX=0; nX<=nRotMax; nX++)
3036cdf0e10cSrcweir 			{
3037cdf0e10cSrcweir 				if (nX==nX1) nPosX = nInitPosX;					// positions before nX1 are calculated individually
3038cdf0e10cSrcweir 
3039cdf0e10cSrcweir 				CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
3040cdf0e10cSrcweir 				if ( pInfo->nRotateDir != SC_ROTDIR_NONE )
3041cdf0e10cSrcweir 				{
3042cdf0e10cSrcweir 					SCROW nY = pThisRowInfo->nRowNo;
3043cdf0e10cSrcweir 
3044cdf0e10cSrcweir 					sal_Bool bHidden = sal_False;
3045cdf0e10cSrcweir 					if (bEditMode)
3046cdf0e10cSrcweir 						if ( nX == nEditCol && nY == nEditRow )
3047cdf0e10cSrcweir 							bHidden = sal_True;
3048cdf0e10cSrcweir 
3049cdf0e10cSrcweir 					if (!bHidden)
3050cdf0e10cSrcweir 					{
3051cdf0e10cSrcweir 						if (!pEngine)
3052cdf0e10cSrcweir                             pEngine = CreateOutputEditEngine();
3053cdf0e10cSrcweir 						else
3054cdf0e10cSrcweir 							lcl_ClearEdit( *pEngine );		// also calls SetUpdateMode(sal_False)
3055cdf0e10cSrcweir 
3056cdf0e10cSrcweir 						long nPosY = nRowPosY;
3057cdf0e10cSrcweir 						sal_Bool bVisChanged = sal_False;
3058cdf0e10cSrcweir 
3059cdf0e10cSrcweir 						//!	Rest von zusammengefasster Zelle weiter oben funktioniert nicht!
3060cdf0e10cSrcweir 
3061cdf0e10cSrcweir 						sal_Bool bFromDoc = sal_False;
3062cdf0e10cSrcweir 						pPattern = pInfo->pPatternAttr;
3063cdf0e10cSrcweir 						pCondSet = pInfo->pConditionSet;
3064cdf0e10cSrcweir 						if (!pPattern)
3065cdf0e10cSrcweir 						{
3066cdf0e10cSrcweir 							pPattern = pDoc->GetPattern( nX, nY, nTab );
3067cdf0e10cSrcweir 							bFromDoc = sal_True;
3068cdf0e10cSrcweir 						}
3069cdf0e10cSrcweir 						pCell = pInfo->pCell;
3070cdf0e10cSrcweir 						if (bFromDoc)
3071cdf0e10cSrcweir 							pCondSet = pDoc->GetCondResult( nX, nY, nTab );
3072cdf0e10cSrcweir 
3073cdf0e10cSrcweir 						if (!pCell && nX>nX2)
3074cdf0e10cSrcweir 							GetVisibleCell( nX, nY, nTab, pCell );
3075cdf0e10cSrcweir 
3076cdf0e10cSrcweir 						if ( !pCell || IsEmptyCellText( pThisRowInfo, nX, nY ) )
3077cdf0e10cSrcweir 							bHidden = sal_True;		// nRotateDir is also set without a cell
3078cdf0e10cSrcweir 
3079cdf0e10cSrcweir 						long nCellWidth = (long) pRowInfo[0].pCellInfo[nX+1].nWidth;
3080cdf0e10cSrcweir 
3081cdf0e10cSrcweir 						SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
3082cdf0e10cSrcweir 											pPattern->GetItem(ATTR_HOR_JUSTIFY, pCondSet)).GetValue();
3083cdf0e10cSrcweir 						sal_Bool bBreak = ( eHorJust == SVX_HOR_JUSTIFY_BLOCK ) ||
3084cdf0e10cSrcweir 									((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue();
3085cdf0e10cSrcweir                         sal_Bool bRepeat = ( eHorJust == SVX_HOR_JUSTIFY_REPEAT && !bBreak );
3086cdf0e10cSrcweir                         sal_Bool bShrink = !bBreak && !bRepeat && static_cast<const SfxBoolItem&>
3087cdf0e10cSrcweir                                         (pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
3088cdf0e10cSrcweir                         SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
3089cdf0e10cSrcweir 
3090cdf0e10cSrcweir 						const ScMergeAttr* pMerge =
3091cdf0e10cSrcweir 								(ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
3092cdf0e10cSrcweir 						sal_Bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
3093cdf0e10cSrcweir 
3094cdf0e10cSrcweir 						long nStartX = nPosX;
3095cdf0e10cSrcweir 						long nStartY = nPosY;
3096cdf0e10cSrcweir 						if (nX<nX1)
3097cdf0e10cSrcweir 						{
3098cdf0e10cSrcweir 							if ((bBreak || eOrient!=SVX_ORIENTATION_STANDARD) && !bMerged)
3099cdf0e10cSrcweir 								bHidden = sal_True;
3100cdf0e10cSrcweir 							else
3101cdf0e10cSrcweir 							{
3102cdf0e10cSrcweir 								nStartX = nInitPosX;
3103cdf0e10cSrcweir 								SCCOL nCol = nX1;
3104cdf0e10cSrcweir 								while (nCol > nX)
3105cdf0e10cSrcweir 								{
3106cdf0e10cSrcweir 									--nCol;
3107cdf0e10cSrcweir 									nStartX -= nLayoutSign * (long) pRowInfo[0].pCellInfo[nCol+1].nWidth;
3108cdf0e10cSrcweir 								}
3109cdf0e10cSrcweir 							}
3110cdf0e10cSrcweir 						}
3111cdf0e10cSrcweir 						long nCellStartX = nStartX;
3112cdf0e10cSrcweir 
3113cdf0e10cSrcweir 						//	Ersatzdarstellung fuer zu kleinen Text weggelassen
3114cdf0e10cSrcweir 
3115cdf0e10cSrcweir 						if (!bHidden)
3116cdf0e10cSrcweir 						{
3117cdf0e10cSrcweir 							long nOutWidth = nCellWidth - 1;
3118cdf0e10cSrcweir 							long nOutHeight;
3119cdf0e10cSrcweir 							if (pInfo)
3120cdf0e10cSrcweir 								nOutHeight = nCellHeight;
3121cdf0e10cSrcweir 							else
3122cdf0e10cSrcweir 								nOutHeight = (long) ( pDoc->GetRowHeight(nY,nTab) * nPPTY );
3123cdf0e10cSrcweir 
3124cdf0e10cSrcweir 							if ( bMerged )								// Zusammengefasst
3125cdf0e10cSrcweir 							{
3126cdf0e10cSrcweir 								SCCOL nCountX = pMerge->GetColMerge();
3127cdf0e10cSrcweir 								for (SCCOL i=1; i<nCountX; i++)
3128cdf0e10cSrcweir 									nOutWidth += (long) ( pDoc->GetColWidth(nX+i,nTab) * nPPTX );
3129cdf0e10cSrcweir 								SCROW nCountY = pMerge->GetRowMerge();
3130cdf0e10cSrcweir                                 nOutHeight += (long) pDoc->GetScaledRowHeight( nY+1, nY+nCountY-1, nTab, nPPTY);
3131cdf0e10cSrcweir 							}
3132cdf0e10cSrcweir 
3133cdf0e10cSrcweir 							SvxCellVerJustify eVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)
3134cdf0e10cSrcweir 												pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet)).GetValue();
3135cdf0e10cSrcweir 
3136cdf0e10cSrcweir 							// Syntax-Modus wird hier ignoriert...
3137cdf0e10cSrcweir 
3138cdf0e10cSrcweir 							// StringDiffer doesn't look at hyphenate, language items
3139cdf0e10cSrcweir 							if ( pPattern != pOldPattern || pCondSet != pOldCondSet )
3140cdf0e10cSrcweir 							{
3141cdf0e10cSrcweir 								SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
3142cdf0e10cSrcweir 								pPattern->FillEditItemSet( pSet, pCondSet );
3143cdf0e10cSrcweir 
3144cdf0e10cSrcweir 																	// Ausrichtung fuer EditEngine
3145cdf0e10cSrcweir 								SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
3146cdf0e10cSrcweir 								if (eOrient==SVX_ORIENTATION_STACKED)
3147cdf0e10cSrcweir 									eSvxAdjust = SVX_ADJUST_CENTER;
3148cdf0e10cSrcweir 								// Adjustment fuer bBreak ist hier weggelassen
3149cdf0e10cSrcweir 								pSet->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
3150cdf0e10cSrcweir 
3151cdf0e10cSrcweir 								pEngine->SetDefaults( pSet );
3152cdf0e10cSrcweir 								pOldPattern = pPattern;
3153cdf0e10cSrcweir 								pOldCondSet = pCondSet;
3154cdf0e10cSrcweir 
3155cdf0e10cSrcweir 								sal_uLong nControl = pEngine->GetControlWord();
3156cdf0e10cSrcweir 								if (eOrient==SVX_ORIENTATION_STACKED)
3157cdf0e10cSrcweir 									nControl |= EE_CNTRL_ONECHARPERLINE;
3158cdf0e10cSrcweir 								else
3159cdf0e10cSrcweir 									nControl &= ~EE_CNTRL_ONECHARPERLINE;
3160cdf0e10cSrcweir 								pEngine->SetControlWord( nControl );
3161cdf0e10cSrcweir 
3162cdf0e10cSrcweir 								if ( !bHyphenatorSet && ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() )
3163cdf0e10cSrcweir 								{
3164cdf0e10cSrcweir 									//	set hyphenator the first time it is needed
3165cdf0e10cSrcweir                                     com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
3166cdf0e10cSrcweir 									pEngine->SetHyphenator( xXHyphenator );
3167cdf0e10cSrcweir 									bHyphenatorSet = sal_True;
3168cdf0e10cSrcweir 								}
3169cdf0e10cSrcweir 
3170cdf0e10cSrcweir 								Color aBackCol = ((const SvxBrushItem&)
3171cdf0e10cSrcweir 									pPattern->GetItem( ATTR_BACKGROUND, pCondSet )).GetColor();
3172cdf0e10cSrcweir 								if ( bUseStyleColor && ( aBackCol.GetTransparency() > 0 || bCellContrast ) )
3173cdf0e10cSrcweir 									aBackCol.SetColor( nConfBackColor );
3174cdf0e10cSrcweir 								pEngine->SetBackgroundColor( aBackCol );
3175cdf0e10cSrcweir 							}
3176cdf0e10cSrcweir 
3177cdf0e10cSrcweir 							//	Raender
3178cdf0e10cSrcweir 
3179cdf0e10cSrcweir 							//!		Position und Papersize auf EditUtil umstellen !!!
3180cdf0e10cSrcweir 
3181cdf0e10cSrcweir 							const SvxMarginItem* pMargin = (const SvxMarginItem*)
3182cdf0e10cSrcweir 													&pPattern->GetItem(ATTR_MARGIN, pCondSet);
3183cdf0e10cSrcweir 							sal_uInt16 nIndent = 0;
3184cdf0e10cSrcweir 							if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
3185cdf0e10cSrcweir 								nIndent = ((const SfxUInt16Item&)pPattern->
3186cdf0e10cSrcweir 													GetItem(ATTR_INDENT, pCondSet)).GetValue();
3187cdf0e10cSrcweir 
3188cdf0e10cSrcweir 							long nTotalHeight = nOutHeight;	// ohne Rand abzuziehen
3189cdf0e10cSrcweir 							if ( bPixelToLogic )
3190cdf0e10cSrcweir 								nTotalHeight = pRefDevice->PixelToLogic(Size(0,nTotalHeight)).Height();
3191cdf0e10cSrcweir 
3192cdf0e10cSrcweir 							long nLeftM = (long) ( (pMargin->GetLeftMargin() + nIndent) * nPPTX );
3193cdf0e10cSrcweir 							long nTopM  = (long) ( pMargin->GetTopMargin() * nPPTY );
3194cdf0e10cSrcweir                             long nRightM  = (long) ( pMargin->GetRightMargin() * nPPTX );
3195cdf0e10cSrcweir                             long nBottomM = (long) ( pMargin->GetBottomMargin() * nPPTY );
3196cdf0e10cSrcweir 							nStartX += nLeftM;
3197cdf0e10cSrcweir 							nStartY += nTopM;
3198cdf0e10cSrcweir 							nOutWidth -= nLeftM + nRightM;
3199cdf0e10cSrcweir 							nOutHeight -= nTopM + nBottomM;
3200cdf0e10cSrcweir 
3201cdf0e10cSrcweir 							//	Rotation schon hier, um bei Umbruch auch PaperSize anzupassen
3202cdf0e10cSrcweir 							long nAttrRotate = 0;
3203cdf0e10cSrcweir 							double nSin = 0.0;
3204cdf0e10cSrcweir 							double nCos = 1.0;
3205cdf0e10cSrcweir 							SvxRotateMode eRotMode = SVX_ROTATE_MODE_STANDARD;
3206cdf0e10cSrcweir 							if ( eOrient == SVX_ORIENTATION_STANDARD )
3207cdf0e10cSrcweir 							{
3208cdf0e10cSrcweir 								nAttrRotate = ((const SfxInt32Item&)pPattern->
3209cdf0e10cSrcweir 													GetItem(ATTR_ROTATE_VALUE, pCondSet)).GetValue();
3210cdf0e10cSrcweir 								if ( nAttrRotate )
3211cdf0e10cSrcweir 								{
3212cdf0e10cSrcweir 									eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
3213cdf0e10cSrcweir 												pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
3214cdf0e10cSrcweir 
3215cdf0e10cSrcweir 									if ( nAttrRotate == 18000 )
3216cdf0e10cSrcweir 										eRotMode = SVX_ROTATE_MODE_STANDARD;	// keinen Ueberlauf
3217cdf0e10cSrcweir 
3218cdf0e10cSrcweir 									if ( bLayoutRTL )
3219cdf0e10cSrcweir 										nAttrRotate = -nAttrRotate;
3220cdf0e10cSrcweir 
3221cdf0e10cSrcweir 									double nRealOrient = nAttrRotate * F_PI18000;	// 1/100 Grad
3222cdf0e10cSrcweir 									nCos = cos( nRealOrient );
3223cdf0e10cSrcweir 									nSin = sin( nRealOrient );
3224cdf0e10cSrcweir 								}
3225cdf0e10cSrcweir 							}
3226cdf0e10cSrcweir 
3227cdf0e10cSrcweir 							Size aPaperSize = Size( 1000000, 1000000 );
3228cdf0e10cSrcweir 							if (eOrient==SVX_ORIENTATION_STACKED)
3229cdf0e10cSrcweir 								aPaperSize.Width() = nOutWidth;				// zum Zentrieren
3230cdf0e10cSrcweir 							else if (bBreak)
3231cdf0e10cSrcweir 							{
3232cdf0e10cSrcweir 								if (nAttrRotate)
3233cdf0e10cSrcweir 								{
3234cdf0e10cSrcweir 									//!	richtige PaperSize fuer Umbruch haengt von der Zeilenzahl
3235cdf0e10cSrcweir 									//!	ab, solange die Zeilen nicht einzeln versetzt ausgegeben
3236cdf0e10cSrcweir 									//!	werden koennen -> darum unbegrenzt, also kein Umbruch.
3237cdf0e10cSrcweir 									//!	Mit versetzten Zeilen waere das folgende richtig:
3238cdf0e10cSrcweir 									aPaperSize.Width() = (long)(nOutHeight / fabs(nSin));
3239cdf0e10cSrcweir 								}
3240cdf0e10cSrcweir 								else if (eOrient == SVX_ORIENTATION_STANDARD)
3241cdf0e10cSrcweir 									aPaperSize.Width() = nOutWidth;
3242cdf0e10cSrcweir 								else
3243cdf0e10cSrcweir 									aPaperSize.Width() = nOutHeight - 1;
3244cdf0e10cSrcweir 							}
3245cdf0e10cSrcweir 							if (bPixelToLogic)
3246cdf0e10cSrcweir 								pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
3247cdf0e10cSrcweir 							else
3248cdf0e10cSrcweir 								pEngine->SetPaperSize(aPaperSize);	// Scale ist immer 1
3249cdf0e10cSrcweir 
3250cdf0e10cSrcweir 							//	Daten aus Zelle lesen
3251cdf0e10cSrcweir 
3252cdf0e10cSrcweir 							if (pCell)
3253cdf0e10cSrcweir 							{
3254cdf0e10cSrcweir 								if (pCell->GetCellType() == CELLTYPE_EDIT)
3255cdf0e10cSrcweir 								{
3256cdf0e10cSrcweir 									const EditTextObject* pData;
3257cdf0e10cSrcweir 									((ScEditCell*)pCell)->GetData(pData);
3258cdf0e10cSrcweir 
3259cdf0e10cSrcweir 									if (pData)
3260cdf0e10cSrcweir 										pEngine->SetText(*pData);
3261cdf0e10cSrcweir 									else
3262cdf0e10cSrcweir 									{
3263cdf0e10cSrcweir 										DBG_ERROR("pData == 0");
3264cdf0e10cSrcweir 									}
3265cdf0e10cSrcweir 								}
3266cdf0e10cSrcweir 								else
3267cdf0e10cSrcweir 								{
3268cdf0e10cSrcweir 									sal_uLong nFormat = pPattern->GetNumberFormat(
3269cdf0e10cSrcweir 																pDoc->GetFormatTable(), pCondSet );
3270cdf0e10cSrcweir 									String aString;
3271cdf0e10cSrcweir 									Color* pColor;
3272cdf0e10cSrcweir 									ScCellFormat::GetString( pCell,
3273cdf0e10cSrcweir 															 nFormat,aString, &pColor,
3274cdf0e10cSrcweir 															 *pDoc->GetFormatTable(),
3275cdf0e10cSrcweir 															 bShowNullValues,
3276cdf0e10cSrcweir 															 bShowFormulas,
3277cdf0e10cSrcweir 															 ftCheck );
3278cdf0e10cSrcweir 
3279cdf0e10cSrcweir 									pEngine->SetText(aString);
3280cdf0e10cSrcweir 									if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
3281cdf0e10cSrcweir 										lcl_SetEditColor( *pEngine, *pColor );
3282cdf0e10cSrcweir 								}
3283cdf0e10cSrcweir 
3284cdf0e10cSrcweir 								if ( bSyntaxMode )
3285cdf0e10cSrcweir 									SetEditSyntaxColor( *pEngine, pCell );
3286cdf0e10cSrcweir 								else if ( bUseStyleColor && bForceAutoColor )
3287cdf0e10cSrcweir 									lcl_SetEditColor( *pEngine, COL_AUTO );		//! or have a flag at EditEngine
3288cdf0e10cSrcweir 							}
3289cdf0e10cSrcweir 							else
3290cdf0e10cSrcweir 							{
3291cdf0e10cSrcweir 								DBG_ERROR("pCell == NULL");
3292cdf0e10cSrcweir 							}
3293cdf0e10cSrcweir 
3294cdf0e10cSrcweir 							pEngine->SetUpdateMode( sal_True );		// after SetText, before CalcTextWidth/GetTextHeight
3295cdf0e10cSrcweir 
3296cdf0e10cSrcweir 							long nEngineWidth  = (long) pEngine->CalcTextWidth();
3297cdf0e10cSrcweir 							long nEngineHeight = pEngine->GetTextHeight();
3298cdf0e10cSrcweir 
3299cdf0e10cSrcweir 							if (nAttrRotate && bBreak)
3300cdf0e10cSrcweir 							{
3301cdf0e10cSrcweir 								double nAbsCos = fabs( nCos );
3302cdf0e10cSrcweir 								double nAbsSin = fabs( nSin );
3303cdf0e10cSrcweir 
3304cdf0e10cSrcweir 								// #47740# adjust witdh of papersize for height of text
3305cdf0e10cSrcweir 								int nSteps = 5;
3306cdf0e10cSrcweir 								while (nSteps > 0)
3307cdf0e10cSrcweir 								{
3308cdf0e10cSrcweir 									// everything is in pixels
3309cdf0e10cSrcweir 									long nEnginePixel = pRefDevice->LogicToPixel(
3310cdf0e10cSrcweir 															Size(0,nEngineHeight)).Height();
3311cdf0e10cSrcweir 									long nEffHeight = nOutHeight - (long)(nEnginePixel * nAbsCos) + 2;
3312cdf0e10cSrcweir 									long nNewWidth = (long)(nEffHeight / nAbsSin) + 2;
3313cdf0e10cSrcweir 									sal_Bool bFits = ( nNewWidth >= aPaperSize.Width() );
3314cdf0e10cSrcweir 									if ( bFits )
3315cdf0e10cSrcweir 										nSteps = 0;
3316cdf0e10cSrcweir 									else
3317cdf0e10cSrcweir 									{
3318cdf0e10cSrcweir 										if ( nNewWidth < 4 )
3319cdf0e10cSrcweir 										{
3320cdf0e10cSrcweir 											// can't fit -> fall back to using half height
3321cdf0e10cSrcweir 											nEffHeight = nOutHeight / 2;
3322cdf0e10cSrcweir 											nNewWidth = (long)(nEffHeight / nAbsSin) + 2;
3323cdf0e10cSrcweir 											nSteps = 0;
3324cdf0e10cSrcweir 										}
3325cdf0e10cSrcweir 										else
3326cdf0e10cSrcweir 											--nSteps;
3327cdf0e10cSrcweir 
3328cdf0e10cSrcweir 										// set paper width and get new text height
3329cdf0e10cSrcweir 										aPaperSize.Width() = nNewWidth;
3330cdf0e10cSrcweir 										if (bPixelToLogic)
3331cdf0e10cSrcweir 											pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
3332cdf0e10cSrcweir 										else
3333cdf0e10cSrcweir 											pEngine->SetPaperSize(aPaperSize);	// Scale ist immer 1
3334cdf0e10cSrcweir 										//pEngine->QuickFormatDoc( sal_True );
3335cdf0e10cSrcweir 										nEngineWidth  = (long) pEngine->CalcTextWidth();
3336cdf0e10cSrcweir 										nEngineHeight = pEngine->GetTextHeight();
3337cdf0e10cSrcweir 									}
3338cdf0e10cSrcweir 								}
3339cdf0e10cSrcweir 							}
3340cdf0e10cSrcweir 
3341cdf0e10cSrcweir 							long nRealWidth  = nEngineWidth;
3342cdf0e10cSrcweir 							long nRealHeight = nEngineHeight;
3343cdf0e10cSrcweir 
3344cdf0e10cSrcweir 							//	wenn gedreht, Groesse anpassen
3345cdf0e10cSrcweir 							if (nAttrRotate)
3346cdf0e10cSrcweir 							{
3347cdf0e10cSrcweir 								double nAbsCos = fabs( nCos );
3348cdf0e10cSrcweir 								double nAbsSin = fabs( nSin );
3349cdf0e10cSrcweir 
3350cdf0e10cSrcweir 								if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
3351cdf0e10cSrcweir 									nEngineWidth = (long) ( nRealWidth * nAbsCos +
3352cdf0e10cSrcweir 															nRealHeight * nAbsSin );
3353cdf0e10cSrcweir 								else
3354cdf0e10cSrcweir 									nEngineWidth = (long) ( nRealHeight / nAbsSin );
3355cdf0e10cSrcweir 								//!	begrenzen !!!
3356cdf0e10cSrcweir 
3357cdf0e10cSrcweir 								nEngineHeight = (long) ( nRealHeight * nAbsCos +
3358cdf0e10cSrcweir 														 nRealWidth * nAbsSin );
3359cdf0e10cSrcweir 							}
3360cdf0e10cSrcweir 
3361cdf0e10cSrcweir 							if (!nAttrRotate)			//	hier nur gedrehter Text
3362cdf0e10cSrcweir 								bHidden = sal_True;			//! vorher abfragen !!!
3363cdf0e10cSrcweir 
3364cdf0e10cSrcweir 							//!	weglassen, was nicht hereinragt
3365cdf0e10cSrcweir 
3366cdf0e10cSrcweir 							if (!bHidden)
3367cdf0e10cSrcweir 							{
3368cdf0e10cSrcweir 								sal_Bool bClip = sal_False;
3369cdf0e10cSrcweir 								Size aClipSize = Size( nScrX+nScrW-nStartX, nScrY+nScrH-nStartY );
3370cdf0e10cSrcweir 
3371cdf0e10cSrcweir 								//	weiterschreiben
3372cdf0e10cSrcweir 
3373cdf0e10cSrcweir 								Size aCellSize;
3374cdf0e10cSrcweir 								if (bPixelToLogic)
3375cdf0e10cSrcweir 									aCellSize = pRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
3376cdf0e10cSrcweir 								else
3377cdf0e10cSrcweir 									aCellSize = Size( nOutWidth, nOutHeight );	// Scale ist 1
3378cdf0e10cSrcweir 
3379cdf0e10cSrcweir 								long nGridWidth = nEngineWidth;
3380cdf0e10cSrcweir 								sal_Bool bNegative = sal_False;
3381cdf0e10cSrcweir 								if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
3382cdf0e10cSrcweir 								{
3383cdf0e10cSrcweir 									nGridWidth = aCellSize.Width() +
3384cdf0e10cSrcweir 											Abs((long) ( aCellSize.Height() * nCos / nSin ));
3385cdf0e10cSrcweir 									bNegative = ( pInfo->nRotateDir == SC_ROTDIR_LEFT );
3386cdf0e10cSrcweir 									if ( bLayoutRTL )
3387cdf0e10cSrcweir 										bNegative = !bNegative;
3388cdf0e10cSrcweir 								}
3389cdf0e10cSrcweir 
3390cdf0e10cSrcweir 								// use GetOutputArea to hide the grid
3391cdf0e10cSrcweir 								// (clip region is done manually below)
3392cdf0e10cSrcweir                                 OutputAreaParam aAreaParam;
3393cdf0e10cSrcweir 
3394cdf0e10cSrcweir 								SCCOL nCellX = nX;
3395cdf0e10cSrcweir 								SCROW nCellY = nY;
3396cdf0e10cSrcweir 								SvxCellHorJustify eOutHorJust = eHorJust;
3397cdf0e10cSrcweir 								if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
3398cdf0e10cSrcweir 									eOutHorJust = bNegative ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT;
3399cdf0e10cSrcweir 								long nNeededWidth = nGridWidth;		// in pixel for GetOutputArea
3400cdf0e10cSrcweir 								if ( bPixelToLogic )
3401cdf0e10cSrcweir 									nNeededWidth =  pRefDevice->LogicToPixel(Size(nNeededWidth,0)).Width();
3402cdf0e10cSrcweir 
3403cdf0e10cSrcweir 								GetOutputArea( nX, nArrY, nCellStartX, nPosY, nCellX, nCellY, nNeededWidth,
3404cdf0e10cSrcweir                                                 *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
3405cdf0e10cSrcweir                                                 sal_False, sal_False, sal_True, aAreaParam );
3406cdf0e10cSrcweir 
3407cdf0e10cSrcweir                                 if ( bShrink )
3408cdf0e10cSrcweir                                 {
3409cdf0e10cSrcweir                                     long nPixelWidth = bPixelToLogic ?
3410cdf0e10cSrcweir                                         pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width() : nEngineWidth;
3411cdf0e10cSrcweir                                     long nNeededPixel = nPixelWidth + nLeftM + nRightM;
3412cdf0e10cSrcweir 
3413cdf0e10cSrcweir                                     aAreaParam.mbLeftClip = aAreaParam.mbRightClip = sal_True;
3414cdf0e10cSrcweir 
3415cdf0e10cSrcweir                                     // always do height
3416cdf0e10cSrcweir                                     ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM,
3417cdf0e10cSrcweir                                         sal_False, sal::static_int_cast<sal_uInt16>(eOrient), nAttrRotate, bPixelToLogic,
3418cdf0e10cSrcweir                                         nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
3419cdf0e10cSrcweir 
3420cdf0e10cSrcweir                                     if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
3421cdf0e10cSrcweir                                     {
3422cdf0e10cSrcweir                                         // do width only if rotating within the cell (standard mode)
3423cdf0e10cSrcweir                                         ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM,
3424cdf0e10cSrcweir                                             sal_True, sal::static_int_cast<sal_uInt16>(eOrient), nAttrRotate, bPixelToLogic,
3425cdf0e10cSrcweir                                             nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
3426cdf0e10cSrcweir                                     }
3427cdf0e10cSrcweir 
3428cdf0e10cSrcweir                                     // nEngineWidth/nEngineHeight is updated in ShrinkEditEngine
3429cdf0e10cSrcweir                                     // (but width is only valid for standard mode)
3430cdf0e10cSrcweir                                     nRealWidth  = (long) pEngine->CalcTextWidth();
3431cdf0e10cSrcweir                                     nRealHeight = pEngine->GetTextHeight();
3432cdf0e10cSrcweir 
3433cdf0e10cSrcweir                                     if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
3434cdf0e10cSrcweir                                         nEngineWidth = (long) ( nRealHeight / fabs( nSin ) );
3435cdf0e10cSrcweir                                 }
3436cdf0e10cSrcweir 
3437cdf0e10cSrcweir 								// sal_Bool bVClip = ( nEngineHeight > aCellSize.Height() );
3438cdf0e10cSrcweir 
3439cdf0e10cSrcweir 								long nClipStartX = nStartX;
3440cdf0e10cSrcweir 								if (nX<nX1)
3441cdf0e10cSrcweir 								{
3442cdf0e10cSrcweir 									//! Clipping unnoetig, wenn links am Fenster
3443cdf0e10cSrcweir 
3444cdf0e10cSrcweir 									bClip = sal_True;					// nur Rest ausgeben!
3445cdf0e10cSrcweir 									if (nStartX<nScrX)
3446cdf0e10cSrcweir 									{
3447cdf0e10cSrcweir 										long nDif = nScrX - nStartX;
3448cdf0e10cSrcweir 										nClipStartX = nScrX;
3449cdf0e10cSrcweir 										aClipSize.Width() -= nDif;
3450cdf0e10cSrcweir 									}
3451cdf0e10cSrcweir 								}
3452cdf0e10cSrcweir 
3453cdf0e10cSrcweir 								long nClipStartY = nStartY;
3454cdf0e10cSrcweir 								if (nArrY==0 || bVisChanged)
3455cdf0e10cSrcweir 								{
3456cdf0e10cSrcweir 									if ( nClipStartY < nRowPosY )
3457cdf0e10cSrcweir 									{
3458cdf0e10cSrcweir 										long nDif = nRowPosY - nClipStartY;
3459cdf0e10cSrcweir 										bClip = sal_True;
3460cdf0e10cSrcweir 										nClipStartY = nRowPosY;
3461cdf0e10cSrcweir 										aClipSize.Height() -= nDif;
3462cdf0e10cSrcweir 									}
3463cdf0e10cSrcweir 								}
3464cdf0e10cSrcweir 
3465cdf0e10cSrcweir 								bClip = sal_True;		// always clip at the window/page border
3466cdf0e10cSrcweir 
3467cdf0e10cSrcweir 								//Rectangle aClipRect;
3468cdf0e10cSrcweir 								if (bClip)
3469cdf0e10cSrcweir 								{
3470cdf0e10cSrcweir 									if ( nAttrRotate /* && eRotMode != SVX_ROTATE_MODE_STANDARD */ )
3471cdf0e10cSrcweir 									{
3472cdf0e10cSrcweir 										//	gedrehten, ausgerichteten Text nur an den
3473cdf0e10cSrcweir 										//	Seitengrenzen clippen
3474cdf0e10cSrcweir 										nClipStartX = nScrX;
3475cdf0e10cSrcweir 										aClipSize.Width() = nScrW;
3476cdf0e10cSrcweir 									}
3477cdf0e10cSrcweir 
3478cdf0e10cSrcweir 									if (bPixelToLogic)
3479cdf0e10cSrcweir                                         aAreaParam.maClipRect = pRefDevice->PixelToLogic( Rectangle(
3480cdf0e10cSrcweir 														Point(nClipStartX,nClipStartY), aClipSize ) );
3481cdf0e10cSrcweir 									else
3482cdf0e10cSrcweir                                         aAreaParam.maClipRect = Rectangle(Point(nClipStartX, nClipStartY),
3483cdf0e10cSrcweir 																aClipSize );	// Scale = 1
3484cdf0e10cSrcweir 
3485cdf0e10cSrcweir 									if (bMetaFile)
3486cdf0e10cSrcweir 									{
3487cdf0e10cSrcweir 										pDev->Push();
3488cdf0e10cSrcweir                                         pDev->IntersectClipRegion( aAreaParam.maClipRect );
3489cdf0e10cSrcweir 									}
3490cdf0e10cSrcweir 									else
3491cdf0e10cSrcweir                                         pDev->SetClipRegion( Region( aAreaParam.maClipRect ) );
3492cdf0e10cSrcweir 								}
3493cdf0e10cSrcweir 
3494cdf0e10cSrcweir 								Point aLogicStart;
3495cdf0e10cSrcweir 								if (bPixelToLogic)
3496cdf0e10cSrcweir 									aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
3497cdf0e10cSrcweir 								else
3498cdf0e10cSrcweir 									aLogicStart = Point(nStartX, nStartY);
3499cdf0e10cSrcweir 								if ( eOrient!=SVX_ORIENTATION_STANDARD || !bBreak )
3500cdf0e10cSrcweir 								{
3501cdf0e10cSrcweir 									long nAvailWidth = aCellSize.Width();
3502cdf0e10cSrcweir 									if (eType==OUTTYPE_WINDOW &&
3503cdf0e10cSrcweir 											eOrient!=SVX_ORIENTATION_STACKED &&
3504cdf0e10cSrcweir 											pInfo && pInfo->bAutoFilter)
3505cdf0e10cSrcweir 									{
3506cdf0e10cSrcweir                                         // filter drop-down width is now independent from row height
3507cdf0e10cSrcweir                                         if (bPixelToLogic)
3508cdf0e10cSrcweir                                             nAvailWidth -= pRefDevice->PixelToLogic(Size(0,DROPDOWN_BITMAP_SIZE)).Height();
3509cdf0e10cSrcweir                                         else
3510cdf0e10cSrcweir                                             nAvailWidth -= DROPDOWN_BITMAP_SIZE;
3511cdf0e10cSrcweir 										long nComp = nEngineWidth;
3512cdf0e10cSrcweir 										if (nAvailWidth<nComp) nAvailWidth=nComp;
3513cdf0e10cSrcweir 									}
3514cdf0e10cSrcweir 
3515cdf0e10cSrcweir 									//	horizontale Ausrichtung
3516cdf0e10cSrcweir 
3517cdf0e10cSrcweir 									if (eOrient==SVX_ORIENTATION_STANDARD && !nAttrRotate)
3518cdf0e10cSrcweir 									{
3519cdf0e10cSrcweir 										if (eHorJust==SVX_HOR_JUSTIFY_RIGHT ||
3520cdf0e10cSrcweir 											eHorJust==SVX_HOR_JUSTIFY_CENTER)
3521cdf0e10cSrcweir 										{
3522cdf0e10cSrcweir 											pEngine->SetUpdateMode( sal_False );
3523cdf0e10cSrcweir 
3524cdf0e10cSrcweir 											SvxAdjust eSvxAdjust =
3525cdf0e10cSrcweir 												(eHorJust==SVX_HOR_JUSTIFY_RIGHT) ?
3526cdf0e10cSrcweir 													SVX_ADJUST_RIGHT : SVX_ADJUST_CENTER;
3527cdf0e10cSrcweir 											pEngine->SetDefaultItem(
3528cdf0e10cSrcweir 												SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
3529cdf0e10cSrcweir 
3530cdf0e10cSrcweir 											aPaperSize.Width() = nOutWidth;
3531cdf0e10cSrcweir 											if (bPixelToLogic)
3532cdf0e10cSrcweir 												pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
3533cdf0e10cSrcweir 											else
3534cdf0e10cSrcweir 												pEngine->SetPaperSize(aPaperSize);
3535cdf0e10cSrcweir 
3536cdf0e10cSrcweir 											pEngine->SetUpdateMode( sal_True );
3537cdf0e10cSrcweir 										}
3538cdf0e10cSrcweir 									}
3539cdf0e10cSrcweir 									else
3540cdf0e10cSrcweir 									{
3541cdf0e10cSrcweir 										//	bei gedrehtem Text ist Standard zentriert
3542cdf0e10cSrcweir 										if (eHorJust==SVX_HOR_JUSTIFY_RIGHT)
3543cdf0e10cSrcweir 											aLogicStart.X() += nAvailWidth - nEngineWidth;
3544cdf0e10cSrcweir 										else if (eHorJust==SVX_HOR_JUSTIFY_CENTER ||
3545cdf0e10cSrcweir 												 eHorJust==SVX_HOR_JUSTIFY_STANDARD)
3546cdf0e10cSrcweir 											aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
3547cdf0e10cSrcweir 									}
3548cdf0e10cSrcweir 								}
3549cdf0e10cSrcweir 
3550cdf0e10cSrcweir 								if ( bLayoutRTL )
3551cdf0e10cSrcweir 								{
3552cdf0e10cSrcweir 									if (bPixelToLogic)
3553cdf0e10cSrcweir 										aLogicStart.X() -= pRefDevice->PixelToLogic(
3554cdf0e10cSrcweir 														Size( nCellWidth, 0 ) ).Width();
3555cdf0e10cSrcweir 									else
3556cdf0e10cSrcweir 										aLogicStart.X() -= nCellWidth;
3557cdf0e10cSrcweir 								}
3558cdf0e10cSrcweir 
3559cdf0e10cSrcweir 								if ( eOrient==SVX_ORIENTATION_STANDARD ||
3560cdf0e10cSrcweir 									 eOrient==SVX_ORIENTATION_STACKED || !bBreak )
3561cdf0e10cSrcweir 								{
3562cdf0e10cSrcweir 									if (eVerJust==SVX_VER_JUSTIFY_BOTTOM ||
3563cdf0e10cSrcweir 										eVerJust==SVX_VER_JUSTIFY_STANDARD)
3564cdf0e10cSrcweir 									{
3565cdf0e10cSrcweir 										if (bPixelToLogic)
3566cdf0e10cSrcweir 											aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0,
3567cdf0e10cSrcweir 															pRefDevice->LogicToPixel(aCellSize).Height() -
3568cdf0e10cSrcweir 															pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
3569cdf0e10cSrcweir 															)).Height();
3570cdf0e10cSrcweir 										else
3571cdf0e10cSrcweir 											aLogicStart.Y() += aCellSize.Height() - nEngineHeight;
3572cdf0e10cSrcweir 									}
3573cdf0e10cSrcweir 
3574cdf0e10cSrcweir 									else if (eVerJust==SVX_VER_JUSTIFY_CENTER)
3575cdf0e10cSrcweir 									{
3576cdf0e10cSrcweir 										if (bPixelToLogic)
3577cdf0e10cSrcweir 											aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0,(
3578cdf0e10cSrcweir 															pRefDevice->LogicToPixel(aCellSize).Height() -
3579cdf0e10cSrcweir 															pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height())
3580cdf0e10cSrcweir 															/ 2)).Height();
3581cdf0e10cSrcweir 										else
3582cdf0e10cSrcweir 											aLogicStart.Y() += (aCellSize.Height() - nEngineHeight) / 2;
3583cdf0e10cSrcweir 									}
3584cdf0e10cSrcweir 								}
3585cdf0e10cSrcweir 
3586cdf0e10cSrcweir 								// TOPBOTTON and BOTTOMTOP are handled in DrawStrings/DrawEdit
3587cdf0e10cSrcweir 								DBG_ASSERT( eOrient == SVX_ORIENTATION_STANDARD && nAttrRotate,
3588cdf0e10cSrcweir 											"DrawRotated: no rotation" );
3589cdf0e10cSrcweir 
3590cdf0e10cSrcweir 								long nOriVal = 0;
3591cdf0e10cSrcweir 								if ( nAttrRotate )
3592cdf0e10cSrcweir 								{
3593cdf0e10cSrcweir 									// Attribut ist 1/100, Font 1/10 Grad
3594cdf0e10cSrcweir 									nOriVal = nAttrRotate / 10;
3595cdf0e10cSrcweir 
3596cdf0e10cSrcweir 									double nAddX = 0.0;
3597cdf0e10cSrcweir 									double nAddY = 0.0;
3598cdf0e10cSrcweir 									if ( nCos > 0.0 && eRotMode != SVX_ROTATE_MODE_STANDARD )
3599cdf0e10cSrcweir 									{
3600cdf0e10cSrcweir 										//!	begrenzen !!!
3601cdf0e10cSrcweir 										double nH = nRealHeight * nCos;
3602cdf0e10cSrcweir 										nAddX += nH * ( nCos / fabs(nSin) );
3603cdf0e10cSrcweir 									}
3604cdf0e10cSrcweir 									if ( nCos < 0.0 && eRotMode == SVX_ROTATE_MODE_STANDARD )
3605cdf0e10cSrcweir 										nAddX -= nRealWidth * nCos;
3606cdf0e10cSrcweir 									if ( nSin < 0.0 )
3607cdf0e10cSrcweir 										nAddX -= nRealHeight * nSin;
3608cdf0e10cSrcweir 									if ( nSin > 0.0 )
3609cdf0e10cSrcweir 										nAddY += nRealWidth * nSin;
3610cdf0e10cSrcweir 									if ( nCos < 0.0 )
3611cdf0e10cSrcweir 										nAddY -= nRealHeight * nCos;
3612cdf0e10cSrcweir 
3613cdf0e10cSrcweir 									if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
3614cdf0e10cSrcweir 									{
3615cdf0e10cSrcweir 										//!	begrenzen !!!
3616cdf0e10cSrcweir 										double nSkew = nTotalHeight * nCos / fabs(nSin);
3617cdf0e10cSrcweir 										if ( eRotMode == SVX_ROTATE_MODE_CENTER )
3618cdf0e10cSrcweir 											nAddX -= nSkew * 0.5;
3619cdf0e10cSrcweir 										if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nSin > 0.0 ) ||
3620cdf0e10cSrcweir 											 ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nSin < 0.0 ) )
3621cdf0e10cSrcweir 											nAddX -= nSkew;
3622cdf0e10cSrcweir 
3623cdf0e10cSrcweir 										long nUp = 0;
3624cdf0e10cSrcweir 										if ( eVerJust == SVX_VER_JUSTIFY_CENTER )
3625cdf0e10cSrcweir 											nUp = ( aCellSize.Height() - nEngineHeight ) / 2;
3626cdf0e10cSrcweir 										else if ( eVerJust == SVX_VER_JUSTIFY_TOP )
3627cdf0e10cSrcweir 										{
3628cdf0e10cSrcweir 											if ( nSin > 0.0 )
3629cdf0e10cSrcweir 												nUp = aCellSize.Height() - nEngineHeight;
3630cdf0e10cSrcweir 										}
3631cdf0e10cSrcweir 										else	// BOTTOM / STANDARD
3632cdf0e10cSrcweir 										{
3633cdf0e10cSrcweir 											if ( nSin < 0.0 )
3634cdf0e10cSrcweir 												nUp = aCellSize.Height() - nEngineHeight;
3635cdf0e10cSrcweir 										}
3636cdf0e10cSrcweir 										if ( nUp )
3637cdf0e10cSrcweir 											nAddX += ( nUp * nCos / fabs(nSin) );
3638cdf0e10cSrcweir 									}
3639cdf0e10cSrcweir 
3640cdf0e10cSrcweir 									aLogicStart.X() += (long) nAddX;
3641cdf0e10cSrcweir 									aLogicStart.Y() += (long) nAddY;
3642cdf0e10cSrcweir 								}
3643cdf0e10cSrcweir 
3644cdf0e10cSrcweir 								//	bSimClip is not used here (because nOriVal is set)
3645cdf0e10cSrcweir 
3646cdf0e10cSrcweir 								if ( pEngine->IsRightToLeft( 0 ) )
3647cdf0e10cSrcweir 								{
3648cdf0e10cSrcweir 									//	For right-to-left, EditEngine always calculates its lines
3649cdf0e10cSrcweir 									//	beginning from the right edge, but EditLine::nStartPosX is
3650cdf0e10cSrcweir 									//	of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
3651cdf0e10cSrcweir 									Size aLogicPaper = pEngine->GetPaperSize();
3652cdf0e10cSrcweir 									if ( aLogicPaper.Width() > USHRT_MAX )
3653cdf0e10cSrcweir 									{
3654cdf0e10cSrcweir 										aLogicPaper.Width() = USHRT_MAX;
3655cdf0e10cSrcweir 										pEngine->SetPaperSize(aLogicPaper);
3656cdf0e10cSrcweir 									}
3657cdf0e10cSrcweir 								}
3658cdf0e10cSrcweir 
3659cdf0e10cSrcweir 								pEngine->Draw( pDev, aLogicStart, (short)nOriVal );
3660cdf0e10cSrcweir 
3661cdf0e10cSrcweir 								if (bClip)
3662cdf0e10cSrcweir 								{
3663cdf0e10cSrcweir 									if (bMetaFile)
3664cdf0e10cSrcweir 										pDev->Pop();
3665cdf0e10cSrcweir 									else
3666cdf0e10cSrcweir 										pDev->SetClipRegion();
3667cdf0e10cSrcweir 								}
3668cdf0e10cSrcweir 							}
3669cdf0e10cSrcweir 						}
3670cdf0e10cSrcweir 					}
3671cdf0e10cSrcweir 				}
3672cdf0e10cSrcweir 				nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
3673cdf0e10cSrcweir 			}
3674cdf0e10cSrcweir 		}
3675cdf0e10cSrcweir 		nRowPosY += pRowInfo[nArrY].nHeight;
3676cdf0e10cSrcweir 	}
3677cdf0e10cSrcweir 
3678cdf0e10cSrcweir 	delete pEngine;
3679cdf0e10cSrcweir }
3680cdf0e10cSrcweir 
3681cdf0e10cSrcweir 
3682cdf0e10cSrcweir 
3683