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