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