Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "scitems.hxx"
30 : : #include <editeng/eeitem.hxx>
31 : :
32 : :
33 : : #include <editeng/adjitem.hxx>
34 : : #include <svx/algitem.hxx>
35 : : #include <editeng/brshitem.hxx>
36 : : #include <svtools/colorcfg.hxx>
37 : : #include <editeng/colritem.hxx>
38 : : #include <editeng/editobj.hxx>
39 : : #include <editeng/editstat.hxx>
40 : : #include <editeng/fhgtitem.hxx>
41 : : #include <editeng/forbiddencharacterstable.hxx>
42 : : #include <editeng/frmdiritem.hxx>
43 : : #include <editeng/langitem.hxx>
44 : : #include <editeng/justifyitem.hxx>
45 : : #include <svx/rotmodit.hxx>
46 : : #include <editeng/scripttypeitem.hxx>
47 : : #include <editeng/udlnitem.hxx>
48 : : #include <editeng/unolingu.hxx>
49 : : #include <svl/zforlist.hxx>
50 : : #include <svl/zformat.hxx>
51 : : #include <vcl/svapp.hxx>
52 : : #include <vcl/metric.hxx>
53 : : #include <vcl/outdev.hxx>
54 : : #include <vcl/pdfextoutdevdata.hxx>
55 : :
56 : : #include "output.hxx"
57 : : #include "document.hxx"
58 : : #include "cell.hxx"
59 : : #include "attrib.hxx"
60 : : #include "patattr.hxx"
61 : : #include "cellform.hxx"
62 : : #include "editutil.hxx"
63 : : #include "progress.hxx"
64 : : #include "scmod.hxx"
65 : : #include "fillinfo.hxx"
66 : :
67 : : #include <com/sun/star/i18n/DirectionProperty.hpp>
68 : :
69 : : #include <boost/ptr_container/ptr_vector.hpp>
70 : :
71 : : #include <math.h>
72 : :
73 : : using namespace com::sun::star;
74 : :
75 : : //! Autofilter-Breite mit column.cxx zusammenfassen
76 : : #define DROPDOWN_BITMAP_SIZE 18
77 : :
78 : : #define DRAWTEXT_MAX 32767
79 : :
80 : : const sal_uInt16 SC_SHRINKAGAIN_MAX = 7;
81 : :
82 : : // STATIC DATA -----------------------------------------------------------
83 : :
84 : :
85 : : // -----------------------------------------------------------------------
86 : :
87 : : class ScDrawStringsVars
88 : : {
89 : : ScOutputData* pOutput; // Verbindung
90 : :
91 : : const ScPatternAttr* pPattern; // Attribute
92 : : const SfxItemSet* pCondSet; // aus bedingter Formatierung
93 : :
94 : : Font aFont; // aus Attributen erzeugt
95 : : FontMetric aMetric;
96 : : long nAscentPixel; // always pixels
97 : : SvxCellOrientation eAttrOrient;
98 : : SvxCellHorJustify eAttrHorJust;
99 : : SvxCellVerJustify eAttrVerJust;
100 : : SvxCellJustifyMethod eAttrHorJustMethod;
101 : : SvxCellJustifyMethod eAttrVerJustMethod;
102 : : const SvxMarginItem* pMargin;
103 : : sal_uInt16 nIndent;
104 : : sal_Bool bRotated;
105 : :
106 : : String aString; // Inhalte
107 : : Size aTextSize;
108 : : long nOriginalWidth;
109 : : long nMaxDigitWidth;
110 : : long nSignWidth;
111 : : long nDotWidth;
112 : : long nExpWidth;
113 : :
114 : : ScBaseCell* pLastCell;
115 : : sal_uLong nValueFormat;
116 : : sal_Bool bLineBreak;
117 : : sal_Bool bRepeat;
118 : : sal_Bool bShrink;
119 : :
120 : : sal_Bool bPixelToLogic;
121 : : sal_Bool bCellContrast;
122 : :
123 : : Color aBackConfigColor; // used for ScPatternAttr::GetFont calls
124 : : Color aTextConfigColor;
125 : : sal_Int32 nPos;
126 : : sal_Unicode nChar;
127 : :
128 : : public:
129 : : ScDrawStringsVars(ScOutputData* pData, sal_Bool bPTL);
130 : : ~ScDrawStringsVars();
131 : :
132 : : // SetPattern = ex-SetVars
133 : : // SetPatternSimple: ohne Font
134 : :
135 : : void SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet, ScBaseCell* pCell, sal_uInt8 nScript );
136 : : void SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet );
137 : :
138 : : sal_Bool SetText( ScBaseCell* pCell ); // TRUE -> pOldPattern vergessen
139 : : void SetHashText();
140 : : void SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth );
141 : : void SetAutoText( const String& rAutoText );
142 : :
143 : : const ScPatternAttr* GetPattern() const { return pPattern; }
144 : 33418 : SvxCellOrientation GetOrient() const { return eAttrOrient; }
145 : 33543 : SvxCellHorJustify GetHorJust() const { return eAttrHorJust; }
146 : 10660 : SvxCellVerJustify GetVerJust() const { return eAttrVerJust; }
147 : 48 : SvxCellJustifyMethod GetHorJustMethod() const { return eAttrHorJustMethod; }
148 : : SvxCellJustifyMethod GetVerJustMethod() const { return eAttrVerJustMethod; }
149 : 27911 : const SvxMarginItem* GetMargin() const { return pMargin; }
150 : :
151 : 16245 : sal_uInt16 GetLeftTotal() const { return pMargin->GetLeftMargin() + nIndent; }
152 : :
153 : 20558 : const String& GetString() const { return aString; }
154 : 39454 : const Size& GetTextSize() const { return aTextSize; }
155 : 916 : long GetOriginalWidth() const { return nOriginalWidth; }
156 : :
157 : 11050 : sal_uLong GetValueFormat() const { return nValueFormat; }
158 : 10909 : sal_Bool GetLineBreak() const { return bLineBreak; }
159 : 10909 : sal_Bool IsRepeat() const { return bRepeat; }
160 : 10909 : sal_Bool IsShrink() const { return bShrink; }
161 : : void RepeatToFill( long colWidth );
162 : :
163 : 10660 : long GetAscent() const { return nAscentPixel; }
164 : 11486 : sal_Bool IsRotated() const { return bRotated; }
165 : :
166 : : void SetShrinkScale( long nScale, sal_uInt8 nScript );
167 : :
168 : 0 : sal_Bool HasCondHeight() const { return pCondSet && SFX_ITEM_SET ==
169 [ # # ][ # # ]: 0 : pCondSet->GetItemState( ATTR_FONT_HEIGHT, sal_True ); }
170 : :
171 : : sal_Bool HasEditCharacters() const;
172 : :
173 : : private:
174 : : long GetMaxDigitWidth(); // in logic units
175 : : long GetSignWidth();
176 : : long GetDotWidth();
177 : : long GetExpWidth();
178 : : void TextChanged();
179 : : };
180 : :
181 : : //==================================================================
182 : :
183 : 1345 : ScDrawStringsVars::ScDrawStringsVars(ScOutputData* pData, sal_Bool bPTL) :
184 : : pOutput ( pData ),
185 : : pPattern ( NULL ),
186 : : pCondSet ( NULL ),
187 : : nAscentPixel(0),
188 : : eAttrOrient ( SVX_ORIENTATION_STANDARD ),
189 : : eAttrHorJust( SVX_HOR_JUSTIFY_STANDARD ),
190 : : eAttrVerJust( SVX_VER_JUSTIFY_BOTTOM ),
191 : : eAttrHorJustMethod( SVX_JUSTIFY_METHOD_AUTO ),
192 : : eAttrVerJustMethod( SVX_JUSTIFY_METHOD_AUTO ),
193 : : pMargin ( NULL ),
194 : : nIndent ( 0 ),
195 : : bRotated ( false ),
196 : : nOriginalWidth( 0 ),
197 : : nMaxDigitWidth( 0 ),
198 : : nSignWidth( 0 ),
199 : : nDotWidth( 0 ),
200 : : nExpWidth( 0 ),
201 : : pLastCell ( NULL ),
202 : : nValueFormat( 0 ),
203 : : bLineBreak ( false ),
204 : : bRepeat ( false ),
205 : : bShrink ( false ),
206 : : bPixelToLogic( bPTL ),
207 : : nPos( STRING_NOTFOUND ),
208 [ + - ][ + - ]: 1345 : nChar( 0x0 )
209 : : {
210 [ + - ]: 1345 : ScModule* pScMod = SC_MOD();
211 : : bCellContrast = pOutput->mbUseStyleColor &&
212 [ + + ][ + - ]: 1345 : Application::GetSettings().GetStyleSettings().GetHighContrastMode();
[ - + ]
213 : :
214 [ + - ]: 1345 : const svtools::ColorConfig& rColorConfig = pScMod->GetColorConfig();
215 [ + - ]: 1345 : aBackConfigColor.SetColor( rColorConfig.GetColorValue(svtools::DOCCOLOR).nColor );
216 [ + - ]: 1345 : aTextConfigColor.SetColor( rColorConfig.GetColorValue(svtools::FONTCOLOR).nColor );
217 : 1345 : }
218 : :
219 [ + - ][ + - ]: 1345 : ScDrawStringsVars::~ScDrawStringsVars()
220 : : {
221 : 1345 : }
222 : :
223 : 0 : void ScDrawStringsVars::SetShrinkScale( long nScale, sal_uInt8 nScript )
224 : : {
225 : : // text remains valid, size is updated
226 : :
227 : 0 : OutputDevice* pDev = pOutput->mpDev;
228 : 0 : OutputDevice* pRefDevice = pOutput->mpRefDevice;
229 : 0 : OutputDevice* pFmtDevice = pOutput->pFmtDevice;
230 : :
231 : : // call GetFont with a modified fraction, use only the height
232 : :
233 [ # # ]: 0 : Fraction aFraction( nScale, 100 );
234 [ # # ]: 0 : if ( !bPixelToLogic )
235 [ # # ]: 0 : aFraction *= pOutput->aZoomY;
236 [ # # ]: 0 : Font aTmpFont;
237 [ # # ]: 0 : pPattern->GetFont( aTmpFont, SC_AUTOCOL_RAW, pFmtDevice, &aFraction, pCondSet, nScript );
238 [ # # ]: 0 : long nNewHeight = aTmpFont.GetHeight();
239 [ # # ]: 0 : if ( nNewHeight > 0 )
240 [ # # ]: 0 : aFont.SetHeight( nNewHeight );
241 : :
242 : : // set font and dependent variables as in SetPattern
243 : :
244 [ # # ]: 0 : pDev->SetFont( aFont );
245 [ # # ]: 0 : if ( pFmtDevice != pDev )
246 [ # # ]: 0 : pFmtDevice->SetFont( aFont );
247 : :
248 [ # # ][ # # ]: 0 : aMetric = pFmtDevice->GetFontMetric();
[ # # ]
249 [ # # ][ # # ]: 0 : if ( pFmtDevice->GetOutDevType() == OUTDEV_PRINTER && aMetric.GetIntLeading() == 0 )
[ # # ][ # # ]
250 : : {
251 [ # # ]: 0 : OutputDevice* pDefaultDev = Application::GetDefaultDevice();
252 [ # # ]: 0 : MapMode aOld = pDefaultDev->GetMapMode();
253 [ # # ]: 0 : pDefaultDev->SetMapMode( pFmtDevice->GetMapMode() );
254 [ # # ][ # # ]: 0 : aMetric = pDefaultDev->GetFontMetric( aFont );
[ # # ]
255 [ # # ][ # # ]: 0 : pDefaultDev->SetMapMode( aOld );
256 : : }
257 : :
258 [ # # ]: 0 : nAscentPixel = aMetric.GetAscent();
259 [ # # ]: 0 : if ( bPixelToLogic )
260 [ # # ]: 0 : nAscentPixel = pRefDevice->LogicToPixel( Size( 0, nAscentPixel ) ).Height();
261 : :
262 [ # # ][ # # ]: 0 : SetAutoText( aString ); // same text again, to get text size
263 : 0 : }
264 : :
265 : : namespace {
266 : :
267 : : template<typename _ItemType, typename _EnumType>
268 : 9115 : _EnumType lcl_GetValue(const ScPatternAttr& rPattern, sal_uInt16 nWhich, const SfxItemSet* pCondSet)
269 : : {
270 : 9115 : const _ItemType& rItem = static_cast<const _ItemType&>(rPattern.GetItem(nWhich, pCondSet));
271 : 9115 : return static_cast<_EnumType>(rItem.GetValue());
272 : : }
273 : :
274 : 964 : bool lcl_GetBoolValue(const ScPatternAttr& rPattern, sal_uInt16 nWhich, const SfxItemSet* pCondSet)
275 : : {
276 : 964 : return lcl_GetValue<SfxBoolItem, bool>(rPattern, nWhich, pCondSet);
277 : : }
278 : :
279 : : }
280 : :
281 : 1583 : void ScDrawStringsVars::SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet,
282 : : ScBaseCell* pCell, sal_uInt8 nScript )
283 : : {
284 : 1583 : nMaxDigitWidth = 0;
285 : 1583 : nSignWidth = 0;
286 : 1583 : nDotWidth = 0;
287 : 1583 : nExpWidth = 0;
288 : :
289 : 1583 : pPattern = pNew;
290 : 1583 : pCondSet = pSet;
291 : :
292 : : // pPattern auswerten
293 : :
294 : 1583 : OutputDevice* pDev = pOutput->mpDev;
295 : 1583 : OutputDevice* pRefDevice = pOutput->mpRefDevice;
296 : 1583 : OutputDevice* pFmtDevice = pOutput->pFmtDevice;
297 : :
298 : : // Font
299 : :
300 : : ScAutoFontColorMode eColorMode;
301 [ + - ]: 1583 : if ( pOutput->mbUseStyleColor )
302 : : {
303 [ - + ]: 1583 : if ( pOutput->mbForceAutoColor )
304 [ # # ]: 0 : eColorMode = bCellContrast ? SC_AUTOCOL_IGNOREALL : SC_AUTOCOL_IGNOREFONT;
305 : : else
306 [ - + ]: 1583 : eColorMode = bCellContrast ? SC_AUTOCOL_IGNOREBACK : SC_AUTOCOL_DISPLAY;
307 : : }
308 : : else
309 : 0 : eColorMode = SC_AUTOCOL_PRINT;
310 : :
311 [ + + ]: 1583 : if ( bPixelToLogic )
312 : : pPattern->GetFont( aFont, eColorMode, pFmtDevice, NULL, pCondSet, nScript,
313 [ + - ]: 29 : &aBackConfigColor, &aTextConfigColor );
314 : : else
315 : : pPattern->GetFont( aFont, eColorMode, pFmtDevice, &pOutput->aZoomY, pCondSet, nScript,
316 [ + - ]: 1554 : &aBackConfigColor, &aTextConfigColor );
317 [ + - ]: 1583 : aFont.SetAlign(ALIGN_BASELINE);
318 : :
319 : : // Orientierung
320 : :
321 [ + - ]: 1583 : eAttrOrient = pPattern->GetCellOrientation( pCondSet );
322 : :
323 : : // alignment
324 : :
325 [ + - ]: 1583 : eAttrHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
326 : :
327 [ + - ]: 1583 : eAttrVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)pPattern->GetItem( ATTR_VER_JUSTIFY, pCondSet )).GetValue();
328 [ + - ]: 1583 : if ( eAttrVerJust == SVX_VER_JUSTIFY_STANDARD )
329 : 1583 : eAttrVerJust = SVX_VER_JUSTIFY_BOTTOM;
330 : :
331 : : // justification method
332 : :
333 [ + - ]: 1583 : eAttrHorJustMethod = lcl_GetValue<SvxJustifyMethodItem, SvxCellJustifyMethod>(*pPattern, ATTR_HOR_JUSTIFY_METHOD, pCondSet);
334 [ + - ]: 1583 : eAttrVerJustMethod = lcl_GetValue<SvxJustifyMethodItem, SvxCellJustifyMethod>(*pPattern, ATTR_VER_JUSTIFY_METHOD, pCondSet);
335 : :
336 : : // line break
337 : :
338 [ + - ]: 1583 : bLineBreak = ((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK, pCondSet )).GetValue();
339 : :
340 : : // handle "repeat" alignment
341 : :
342 : 1583 : bRepeat = ( eAttrHorJust == SVX_HOR_JUSTIFY_REPEAT );
343 [ - + ]: 1583 : if ( bRepeat )
344 : : {
345 : : // "repeat" disables rotation (before constructing the font)
346 : 0 : eAttrOrient = SVX_ORIENTATION_STANDARD;
347 : :
348 : : // #i31843# "repeat" with "line breaks" is treated as default alignment (but rotation is still disabled)
349 [ # # ]: 0 : if ( bLineBreak )
350 : 0 : eAttrHorJust = SVX_HOR_JUSTIFY_STANDARD;
351 : : }
352 : :
353 : : short nRot;
354 [ + - + - : 1583 : switch (eAttrOrient)
- ]
355 : : {
356 : : case SVX_ORIENTATION_STANDARD:
357 : 1511 : nRot = 0;
358 [ + - ]: 1511 : bRotated = (((const SfxInt32Item&)pPattern->GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue() != 0) &&
359 [ + - ][ + + ]: 1511 : !bRepeat;
360 : 1511 : break;
361 : : case SVX_ORIENTATION_STACKED:
362 : 0 : nRot = 0;
363 : 0 : bRotated = false;
364 : 0 : break;
365 : : case SVX_ORIENTATION_TOPBOTTOM:
366 : 72 : nRot = 2700;
367 : 72 : bRotated = false;
368 : 72 : break;
369 : : case SVX_ORIENTATION_BOTTOMTOP:
370 : 0 : nRot = 900;
371 : 0 : bRotated = false;
372 : 0 : break;
373 : : default:
374 : : OSL_FAIL("Falscher SvxCellOrientation Wert");
375 : 0 : nRot = 0;
376 : 0 : bRotated = false;
377 : 0 : break;
378 : : }
379 [ + - ]: 1583 : aFont.SetOrientation( nRot );
380 : :
381 : : // Syntax-Modus
382 : :
383 [ - + ]: 1583 : if (pOutput->mbSyntaxMode)
384 [ # # ]: 0 : pOutput->SetSyntaxColor( &aFont, pCell );
385 : :
386 [ + - ]: 1583 : pDev->SetFont( aFont );
387 [ + + ]: 1583 : if ( pFmtDevice != pDev )
388 [ + - ]: 75 : pFmtDevice->SetFont( aFont );
389 : :
390 [ + - ][ + - ]: 1583 : aMetric = pFmtDevice->GetFontMetric();
[ + - ]
391 : :
392 : : //
393 : : // Wenn auf dem Drucker das Leading 0 ist, gibt es Probleme
394 : : // -> Metric vom Bildschirm nehmen (wie EditEngine!)
395 : : //
396 : :
397 [ + + ][ + - ]: 1583 : if ( pFmtDevice->GetOutDevType() == OUTDEV_PRINTER && aMetric.GetIntLeading() == 0 )
[ - + ][ - + ]
398 : : {
399 [ # # ]: 0 : OutputDevice* pDefaultDev = Application::GetDefaultDevice();
400 [ # # ]: 0 : MapMode aOld = pDefaultDev->GetMapMode();
401 [ # # ]: 0 : pDefaultDev->SetMapMode( pFmtDevice->GetMapMode() );
402 [ # # ][ # # ]: 0 : aMetric = pDefaultDev->GetFontMetric( aFont );
[ # # ]
403 [ # # ][ # # ]: 0 : pDefaultDev->SetMapMode( aOld );
404 : : }
405 : :
406 [ + - ]: 1583 : nAscentPixel = aMetric.GetAscent();
407 [ + + ]: 1583 : if ( bPixelToLogic )
408 [ + - ]: 29 : nAscentPixel = pRefDevice->LogicToPixel( Size( 0, nAscentPixel ) ).Height();
409 : :
410 [ + - ]: 1583 : Color aULineColor( ((const SvxUnderlineItem&)pPattern->GetItem( ATTR_FONT_UNDERLINE, pCondSet )).GetColor() );
411 [ + - ]: 1583 : pDev->SetTextLineColor( aULineColor );
412 : :
413 [ + - ]: 1583 : Color aOLineColor( ((const SvxOverlineItem&)pPattern->GetItem( ATTR_FONT_OVERLINE, pCondSet )).GetColor() );
414 [ + - ]: 1583 : pDev->SetOverlineColor( aOLineColor );
415 : :
416 : : // Zahlenformat
417 : :
418 [ + - ][ + - ]: 1583 : nValueFormat = pPattern->GetNumberFormat( pOutput->mpDoc->GetFormatTable(), pCondSet );
419 : :
420 : : // Raender
421 : :
422 [ + - ]: 1583 : pMargin = (const SvxMarginItem*)&pPattern->GetItem( ATTR_MARGIN, pCondSet );
423 [ + + ]: 1583 : if ( eAttrHorJust == SVX_HOR_JUSTIFY_LEFT )
424 [ + - ]: 215 : nIndent = ((const SfxUInt16Item&)pPattern->GetItem( ATTR_INDENT, pCondSet )).GetValue();
425 : : else
426 : 1368 : nIndent = 0;
427 : :
428 : : // "Shrink to fit"
429 : :
430 [ + - ]: 1583 : bShrink = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
431 : :
432 : : // zumindest die Text-Groesse muss neu geholt werden
433 : : //! unterscheiden, und den Text nicht neu vom Numberformatter holen?
434 : :
435 : 1583 : pLastCell = NULL;
436 : 1583 : }
437 : :
438 : 480 : void ScDrawStringsVars::SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet )
439 : : {
440 : 480 : nMaxDigitWidth = 0;
441 : 480 : nSignWidth = 0;
442 : 480 : nDotWidth = 0;
443 : 480 : nExpWidth = 0;
444 : : // wird gerufen, wenn sich die Font-Variablen nicht aendern (!StringDiffer)
445 : :
446 : 480 : pPattern = pNew;
447 : 480 : pCondSet = pSet; //! noetig ???
448 : :
449 : : // Zahlenformat
450 : :
451 : 480 : sal_uLong nOld = nValueFormat;
452 : : const SfxPoolItem* pFormItem;
453 [ - + ][ # # ]: 480 : if ( !pCondSet || pCondSet->GetItemState(ATTR_VALUE_FORMAT,sal_True,&pFormItem) != SFX_ITEM_SET )
[ # # ][ + - ]
454 [ + - ]: 480 : pFormItem = &pPattern->GetItem(ATTR_VALUE_FORMAT);
455 : : const SfxPoolItem* pLangItem;
456 [ - + ][ # # ]: 480 : if ( !pCondSet || pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT,sal_True,&pLangItem) != SFX_ITEM_SET )
[ # # ][ + - ]
457 [ + - ]: 480 : pLangItem = &pPattern->GetItem(ATTR_LANGUAGE_FORMAT);
458 : : nValueFormat = pOutput->mpDoc->GetFormatTable()->GetFormatForLanguageIfBuiltIn(
459 : : ((SfxUInt32Item*)pFormItem)->GetValue(),
460 [ + - ][ + - ]: 480 : ((SvxLanguageItem*)pLangItem)->GetLanguage() );
461 : :
462 [ - + ]: 480 : if (nValueFormat != nOld)
463 : 0 : pLastCell = NULL; // immer neu formatieren
464 : :
465 : : // Raender
466 : :
467 [ + - ]: 480 : pMargin = (const SvxMarginItem*)&pPattern->GetItem( ATTR_MARGIN, pCondSet );
468 : :
469 [ + + ]: 480 : if ( eAttrHorJust == SVX_HOR_JUSTIFY_LEFT )
470 [ + - ]: 104 : nIndent = ((const SfxUInt16Item&)pPattern->GetItem( ATTR_INDENT, pCondSet )).GetValue();
471 : : else
472 : 376 : nIndent = 0;
473 : :
474 : : // "Shrink to fit"
475 : :
476 [ + - ]: 480 : bShrink = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
477 : 480 : }
478 : :
479 : 10909 : inline sal_Bool SameValue( ScBaseCell* pCell, ScBaseCell* pOldCell ) // pCell ist != 0
480 : : {
481 : 9192 : return pOldCell && pOldCell->GetCellType() == CELLTYPE_VALUE &&
482 : 4904 : pCell->GetCellType() == CELLTYPE_VALUE &&
483 [ + + + + : 25005 : ((ScValueCell*)pCell)->GetValue() == ((ScValueCell*)pOldCell)->GetValue();
+ + ][ + + ]
484 : : }
485 : :
486 : 10909 : sal_Bool ScDrawStringsVars::SetText( ScBaseCell* pCell )
487 : : {
488 : 10909 : sal_Bool bChanged = false;
489 : :
490 [ + - ]: 10909 : if (pCell)
491 : : {
492 [ + + ]: 10909 : if ( !SameValue( pCell, pLastCell ) )
493 : : {
494 : 10727 : pLastCell = pCell; // Zelle merken
495 : :
496 : : Color* pColor;
497 : 10727 : sal_uLong nFormat = GetValueFormat();
498 [ + - ]: 10727 : rtl::OUString aOUString = aString;
499 : : ScCellFormat::GetString( pCell,
500 : : nFormat, aOUString, &pColor,
501 [ + - ]: 10727 : *pOutput->mpDoc->GetFormatTable(),
502 : : pOutput->mbShowNullValues,
503 : : pOutput->mbShowFormulas,
504 [ + - ]: 10727 : ftCheck, true );
505 [ + - ]: 10727 : aString = aOUString;
506 [ + + ]: 10727 : if ( nFormat )
507 : : {
508 [ + - ]: 308 : nPos = aString.Search( 0x1B );
509 [ - + ]: 308 : if ( nPos != STRING_NOTFOUND )
510 : : {
511 : 0 : nPos = nPos - 1;
512 : 0 : nChar = aString.GetChar( nPos );
513 : : // delete placeholder and char to repeat
514 [ # # ]: 0 : aString.Erase( nPos, 2 );
515 : : }
516 : : }
517 : : else
518 : : {
519 : 10419 : nPos = STRING_NOTFOUND;
520 : 10419 : nChar = 0x0;
521 : : }
522 [ - + ]: 10727 : if (aString.Len() > DRAWTEXT_MAX)
523 [ # # ]: 0 : aString.Erase(DRAWTEXT_MAX);
524 : :
525 [ - + ][ # # ]: 10727 : if ( pColor && !pOutput->mbSyntaxMode && !( pOutput->mbUseStyleColor && pOutput->mbForceAutoColor ) )
[ # # ][ # # ]
526 : : {
527 : 0 : OutputDevice* pDev = pOutput->mpDev;
528 [ # # ]: 0 : aFont.SetColor(*pColor);
529 [ # # ]: 0 : pDev->SetFont( aFont ); // nur fuer Ausgabe
530 : 0 : bChanged = sal_True;
531 : 0 : pLastCell = NULL; // naechstes Mal wieder hierherkommen
532 : : }
533 : :
534 [ + - ]: 10727 : TextChanged();
535 : : }
536 : : // sonst String/Groesse behalten
537 : : }
538 : : else
539 : : {
540 : 0 : aString.Erase();
541 : 0 : pLastCell = NULL;
542 : 0 : aTextSize = Size(0,0);
543 : 0 : nOriginalWidth = 0;
544 : : }
545 : :
546 : 10909 : return bChanged;
547 : : }
548 : :
549 : 48 : void ScDrawStringsVars::SetHashText()
550 : : {
551 [ + - ][ + - ]: 48 : SetAutoText(rtl::OUString("###"));
[ + - ]
552 : 48 : }
553 : :
554 : 10909 : void ScDrawStringsVars::RepeatToFill( long colWidth )
555 : : {
556 [ - + ][ # # ]: 10909 : if ( nPos == STRING_NOTFOUND || nPos >= aString.Len() )
[ - + ]
557 : : return;
558 : :
559 [ # # ][ # # ]: 0 : long charWidth = pOutput->pFmtDevice->GetTextWidth(rtl::OUString(nChar));
[ # # ]
560 [ # # ]: 0 : if (bPixelToLogic)
561 [ # # ]: 0 : colWidth = pOutput->mpRefDevice->PixelToLogic(Size(colWidth,0)).Width();
562 : : // Are there restrictions on the cell type we should filter out here ?
563 : 0 : long aSpaceToFill = ( colWidth - aTextSize.Width() );
564 : :
565 [ # # ]: 0 : if ( aSpaceToFill <= charWidth )
566 : : return;
567 : :
568 : 0 : long nCharsToInsert = aSpaceToFill / charWidth;
569 [ # # ]: 0 : String aFill;
570 [ # # ]: 0 : aFill.Expand( nCharsToInsert, nChar);
571 [ # # ]: 0 : aString.Insert( aFill, nPos);
572 [ # # ][ # # ]: 10909 : TextChanged();
573 : : }
574 : :
575 : 323 : void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth )
576 : : {
577 : : // #i113045# do the single-character width calculations in logic units
578 [ - + ]: 323 : if (bPixelToLogic)
579 [ # # ]: 0 : nWidth = pOutput->mpRefDevice->PixelToLogic(Size(nWidth,0)).Width();
580 : :
581 [ - + ]: 323 : if (!pCell)
582 : 0 : return;
583 : :
584 : 323 : CellType eType = pCell->GetCellType();
585 [ # # ][ - + ]: 323 : if (eType != CELLTYPE_VALUE && eType != CELLTYPE_FORMULA)
586 : : // must be a value or formula cell.
587 : 0 : return;
588 : :
589 [ - + ]: 323 : if (eType == CELLTYPE_FORMULA)
590 : : {
591 [ # # ]: 0 : ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
592 [ # # ][ # # ]: 0 : if (pFCell->GetErrCode() != 0 || pOutput->mbShowFormulas)
[ # # ]
593 : : {
594 : 0 : SetHashText(); // If the error string doesn't fit, always use "###". Also for "display formulas" (#i116691#)
595 : 0 : return;
596 : : }
597 : : // If it's formula, the result must be a value.
598 [ # # ]: 0 : if (!pFCell->IsValue())
599 : 0 : return;
600 : :
601 [ # # ]: 0 : if (pFCell->GetFormatType() != NUMBERFORMAT_NUMBER)
602 : : {
603 : : // Make sure the format type implicitly set by the interpreter is
604 : : // of pure numeric type. We don't want to adjust date and time
605 : : // values here.
606 : 0 : SetHashText();
607 : 0 : return;
608 : : }
609 : : }
610 : :
611 : 323 : sal_uLong nFormat = GetValueFormat();
612 [ + + ]: 323 : if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
613 : : {
614 : : // Not 'General' number format. Set hash text and bail out.
615 : 48 : SetHashText();
616 : 48 : return;
617 : : }
618 : :
619 : : double fVal = (eType == CELLTYPE_VALUE) ?
620 [ + - ][ # # ]: 275 : static_cast<ScValueCell*>(pCell)->GetValue() : static_cast<ScFormulaCell*>(pCell)->GetValue();
621 : :
622 : 275 : const SvNumberformat* pNumFormat = pOutput->mpDoc->GetFormatTable()->GetEntry(nFormat);
623 [ - + ]: 275 : if (!pNumFormat)
624 : 0 : return;
625 : :
626 : 275 : long nMaxDigit = GetMaxDigitWidth();
627 : 275 : sal_uInt16 nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit);
628 : :
629 [ - + ]: 275 : if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString))
630 : : // Failed to get output string. Bail out.
631 : 0 : return;
632 : :
633 : 275 : sal_uInt8 nSignCount = 0, nDecimalCount = 0, nExpCount = 0;
634 : 275 : xub_StrLen nLen = aString.Len();
635 : 275 : sal_Unicode cDecSep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator.getStr()[0];
636 [ + + ]: 3306 : for (xub_StrLen i = 0; i < nLen; ++i)
637 : : {
638 : 3031 : sal_Unicode c = aString.GetChar(i);
639 [ + + ]: 3031 : if (c == sal_Unicode('-'))
640 : 62 : ++nSignCount;
641 [ + + ]: 2969 : else if (c == cDecSep)
642 : 275 : ++nDecimalCount;
643 [ + + ]: 2694 : else if (c == sal_Unicode('E'))
644 : 2 : ++nExpCount;
645 : : }
646 : :
647 : : // #i112250# A small value might be formatted as "0" when only counting the digits,
648 : : // but fit into the column when considering the smaller width of the decimal separator.
649 [ - + ][ # # ]: 275 : if (aString.EqualsAscii("0") && fVal != 0.0)
[ - + ]
650 : 0 : nDecimalCount = 1;
651 : :
652 [ + - ]: 275 : if (nDecimalCount)
653 : 275 : nWidth += (nMaxDigit - GetDotWidth()) * nDecimalCount;
654 [ + + ]: 275 : if (nSignCount)
655 : 62 : nWidth += (nMaxDigit - GetSignWidth()) * nSignCount;
656 [ + + ]: 275 : if (nExpCount)
657 : 2 : nWidth += (nMaxDigit - GetExpWidth()) * nExpCount;
658 : :
659 [ - + ][ # # ]: 275 : if (nDecimalCount || nSignCount || nExpCount)
[ # # ]
660 : : {
661 : : // Re-calculate.
662 : 275 : nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit);
663 [ - + ]: 275 : if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString))
664 : : // Failed to get output string. Bail out.
665 : 0 : return;
666 : : }
667 : :
668 : 275 : long nActualTextWidth = pOutput->pFmtDevice->GetTextWidth(aString);
669 [ - + ]: 275 : if (nActualTextWidth > nWidth)
670 : : {
671 : : // Even after the decimal adjustment the text doesn't fit. Give up.
672 : 0 : SetHashText();
673 : 0 : return;
674 : : }
675 : :
676 : 275 : TextChanged();
677 : 323 : pLastCell = NULL; // #i113022# equal cell and format in another column may give different string
678 : : }
679 : :
680 : 48 : void ScDrawStringsVars::SetAutoText( const String& rAutoText )
681 : : {
682 : 48 : aString = rAutoText;
683 : :
684 : 48 : OutputDevice* pRefDevice = pOutput->mpRefDevice;
685 : 48 : OutputDevice* pFmtDevice = pOutput->pFmtDevice;
686 : 48 : aTextSize.Width() = pFmtDevice->GetTextWidth( aString );
687 : 48 : aTextSize.Height() = pFmtDevice->GetTextHeight();
688 : :
689 [ # # ][ + - ]: 48 : if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
[ - + ]
690 : : {
691 : 48 : double fMul = pOutput->GetStretch();
692 : 48 : aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5);
693 : : }
694 : :
695 : 48 : aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent();
696 [ + - ]: 48 : if ( GetOrient() != SVX_ORIENTATION_STANDARD )
697 : : {
698 : 48 : long nTemp = aTextSize.Height();
699 : 48 : aTextSize.Height() = aTextSize.Width();
700 : 48 : aTextSize.Width() = nTemp;
701 : : }
702 : :
703 : 48 : nOriginalWidth = aTextSize.Width();
704 [ - + ]: 48 : if ( bPixelToLogic )
705 : 0 : aTextSize = pRefDevice->LogicToPixel( aTextSize );
706 : :
707 : 48 : pLastCell = NULL; // derselbe Text kann in der naechsten Zelle wieder passen
708 : 48 : }
709 : :
710 : 275 : long ScDrawStringsVars::GetMaxDigitWidth()
711 : : {
712 [ + + ]: 275 : if (nMaxDigitWidth > 0)
713 : 223 : return nMaxDigitWidth;
714 : :
715 : 52 : sal_Char cZero = '0';
716 [ + + ]: 572 : for (sal_Char i = 0; i < 10; ++i)
717 : : {
718 : 520 : sal_Char cDigit = cZero + i;
719 [ + - ][ + - ]: 520 : long n = pOutput->pFmtDevice->GetTextWidth(rtl::OUString(cDigit));
[ + - ]
720 [ + - ]: 520 : nMaxDigitWidth = ::std::max(nMaxDigitWidth, n);
721 : : }
722 : 275 : return nMaxDigitWidth;
723 : : }
724 : :
725 : 62 : long ScDrawStringsVars::GetSignWidth()
726 : : {
727 [ + + ]: 62 : if (nSignWidth > 0)
728 : 20 : return nSignWidth;
729 : :
730 [ + - ][ + - ]: 42 : nSignWidth = pOutput->pFmtDevice->GetTextWidth(rtl::OUString('-'));
[ + - ]
731 : 62 : return nSignWidth;
732 : : }
733 : :
734 : 275 : long ScDrawStringsVars::GetDotWidth()
735 : : {
736 [ + + ]: 275 : if (nDotWidth > 0)
737 : 223 : return nDotWidth;
738 : :
739 : 52 : const ::rtl::OUString& sep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator;
740 [ + - ][ + - ]: 52 : nDotWidth = pOutput->pFmtDevice->GetTextWidth(sep);
[ + - ]
741 : 275 : return nDotWidth;
742 : : }
743 : :
744 : 2 : long ScDrawStringsVars::GetExpWidth()
745 : : {
746 [ - + ]: 2 : if (nExpWidth > 0)
747 : 0 : return nExpWidth;
748 : :
749 [ + - ][ + - ]: 2 : nExpWidth = pOutput->pFmtDevice->GetTextWidth(rtl::OUString('E'));
[ + - ]
750 : 2 : return nExpWidth;
751 : : }
752 : :
753 : 11002 : void ScDrawStringsVars::TextChanged()
754 : : {
755 : 11002 : OutputDevice* pRefDevice = pOutput->mpRefDevice;
756 : 11002 : OutputDevice* pFmtDevice = pOutput->pFmtDevice;
757 : 11002 : aTextSize.Width() = pFmtDevice->GetTextWidth( aString );
758 : 11002 : aTextSize.Height() = pFmtDevice->GetTextHeight();
759 : :
760 [ # # ][ + - ]: 11002 : if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
[ - + ]
761 : : {
762 : 11002 : double fMul = pOutput->GetStretch();
763 : 11002 : aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5);
764 : : }
765 : :
766 : 11002 : aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent();
767 [ + + ]: 11002 : if ( GetOrient() != SVX_ORIENTATION_STANDARD )
768 : : {
769 : 306 : long nTemp = aTextSize.Height();
770 : 306 : aTextSize.Height() = aTextSize.Width();
771 : 306 : aTextSize.Width() = nTemp;
772 : : }
773 : :
774 : 11002 : nOriginalWidth = aTextSize.Width();
775 [ + + ]: 11002 : if ( bPixelToLogic )
776 : 960 : aTextSize = pRefDevice->LogicToPixel( aTextSize );
777 : 11002 : }
778 : :
779 : 10909 : sal_Bool ScDrawStringsVars::HasEditCharacters() const
780 : : {
781 : : static const sal_Unicode pChars[] =
782 : : {
783 : : CHAR_NBSP, CHAR_SHY, CHAR_ZWSP, CHAR_LRM, CHAR_RLM, CHAR_NBHY, CHAR_ZWNBSP, 0
784 : : };
785 : 10909 : return aString.SearchChar( pChars ) != STRING_NOTFOUND;
786 : : }
787 : :
788 : : //==================================================================
789 : :
790 : 12052 : double ScOutputData::GetStretch()
791 : : {
792 [ + + ]: 12052 : if ( mpRefDevice->IsMapMode() )
793 : : {
794 : : // If a non-trivial MapMode is set, its scale is now already
795 : : // taken into account in the OutputDevice's font handling
796 : : // (OutputDevice::ImplNewFont, see #95414#).
797 : : // The old handling below is only needed for pixel output.
798 : 2008 : return 1.0;
799 : : }
800 : :
801 : : // calculation in double is faster than Fraction multiplication
802 : : // and doesn't overflow
803 : :
804 [ + - ]: 10044 : if ( mpRefDevice == pFmtDevice )
805 : : {
806 [ + - ]: 10044 : MapMode aOld = mpRefDevice->GetMapMode();
807 [ + - ][ + - ]: 10044 : return ((double)aOld.GetScaleY()) / ((double)aOld.GetScaleX()) * ((double)aZoomY) / ((double)aZoomX);
[ + - ][ + - ]
[ + - ]
808 : : }
809 : : else
810 : : {
811 : : // when formatting for printer, device map mode has already been taken care of
812 : 12052 : return ((double)aZoomY) / ((double)aZoomX);
813 : : }
814 : : }
815 : :
816 : : //==================================================================
817 : :
818 : : //
819 : : // output strings
820 : : //
821 : :
822 : 0 : void lcl_DoHyperlinkResult( OutputDevice* pDev, const Rectangle& rRect, ScBaseCell* pCell )
823 : : {
824 [ # # ][ # # ]: 0 : vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
[ # # ][ # # ]
825 : :
826 : 0 : rtl::OUString aCellText;
827 : 0 : rtl::OUString aURL;
828 [ # # ][ # # ]: 0 : if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
[ # # ]
829 : : {
830 [ # # ]: 0 : ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
831 [ # # ]: 0 : if ( pFCell->IsHyperLinkCell() )
832 [ # # ]: 0 : pFCell->GetURLResult( aURL, aCellText );
833 : : }
834 : :
835 [ # # ][ # # ]: 0 : if ( !aURL.isEmpty() && pPDFData )
[ # # ]
836 : : {
837 : 0 : vcl::PDFExtOutDevBookmarkEntry aBookmark;
838 [ # # ]: 0 : aBookmark.nLinkId = pPDFData->CreateLink( rRect );
839 : 0 : aBookmark.aBookmark = aURL;
840 [ # # ]: 0 : std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFData->GetBookmarks();
841 [ # # ]: 0 : rBookmarks.push_back( aBookmark );
842 : 0 : }
843 : 0 : }
844 : :
845 : 0 : void ScOutputData::SetSyntaxColor( Font* pFont, ScBaseCell* pCell )
846 : : {
847 [ # # ]: 0 : if (pCell)
848 : : {
849 [ # # # # ]: 0 : switch (pCell->GetCellType())
850 : : {
851 : : case CELLTYPE_VALUE:
852 : 0 : pFont->SetColor( *pValueColor );
853 : 0 : break;
854 : : case CELLTYPE_STRING:
855 : 0 : pFont->SetColor( *pTextColor );
856 : 0 : break;
857 : : case CELLTYPE_FORMULA:
858 : 0 : pFont->SetColor( *pFormulaColor );
859 : 0 : break;
860 : : default:
861 : : {
862 : : // added to avoid warnings
863 : : }
864 : : }
865 : : }
866 : 0 : }
867 : :
868 : 0 : void lcl_SetEditColor( EditEngine& rEngine, const Color& rColor )
869 : : {
870 [ # # ]: 0 : ESelection aSel( 0, 0, rEngine.GetParagraphCount(), 0 );
871 [ # # ][ # # ]: 0 : SfxItemSet aSet( rEngine.GetEmptyItemSet() );
872 [ # # ][ # # ]: 0 : aSet.Put( SvxColorItem( rColor, EE_CHAR_COLOR ) );
[ # # ]
873 [ # # ][ # # ]: 0 : rEngine.QuickSetAttribs( aSet, aSel );
874 : : // function is called with update mode set to FALSE
875 : 0 : }
876 : :
877 : 0 : void ScOutputData::SetEditSyntaxColor( EditEngine& rEngine, ScBaseCell* pCell )
878 : : {
879 [ # # ]: 0 : if (pCell)
880 : : {
881 : 0 : Color aColor;
882 [ # # # # ]: 0 : switch (pCell->GetCellType())
883 : : {
884 : : case CELLTYPE_VALUE:
885 : 0 : aColor = *pValueColor;
886 : 0 : break;
887 : : case CELLTYPE_STRING:
888 : 0 : aColor = *pTextColor;
889 : 0 : break;
890 : : case CELLTYPE_FORMULA:
891 : 0 : aColor = *pFormulaColor;
892 : 0 : break;
893 : : default:
894 : : {
895 : : // added to avoid warnings
896 : : }
897 : : }
898 [ # # ]: 0 : lcl_SetEditColor( rEngine, aColor );
899 : : }
900 : 0 : }
901 : :
902 : 34 : sal_Bool ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY,
903 : : SCCOL& rOverX, SCROW& rOverY,
904 : : sal_Bool bVisRowChanged )
905 : : {
906 : 34 : sal_Bool bDoMerge = false;
907 : 34 : sal_Bool bIsLeft = ( nX == nVisX1 );
908 [ + + ][ - + ]: 34 : sal_Bool bIsTop = ( nY == nVisY1 ) || bVisRowChanged;
909 : :
910 : 34 : CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
911 [ + + ][ + + ]: 34 : if ( pInfo->bHOverlapped && pInfo->bVOverlapped )
912 [ - + ][ # # ]: 21 : bDoMerge = bIsLeft && bIsTop;
913 [ + + ]: 13 : else if ( pInfo->bHOverlapped )
914 : 6 : bDoMerge = bIsLeft;
915 [ + - ]: 7 : else if ( pInfo->bVOverlapped )
916 : 7 : bDoMerge = bIsTop;
917 : :
918 : 34 : rOverX = nX;
919 : 34 : rOverY = nY;
920 : 34 : sal_Bool bHOver = pInfo->bHOverlapped;
921 : 34 : sal_Bool bVOver = pInfo->bVOverlapped;
922 : : sal_Bool bHidden;
923 : :
924 [ + + ]: 34 : while (bHOver) // nY konstant
925 : : {
926 : 27 : --rOverX;
927 : 27 : bHidden = mpDoc->ColHidden(rOverX, nTab);
928 [ + - ][ + - ]: 27 : if ( !bDoMerge && !bHidden )
929 : 27 : return false;
930 : :
931 [ # # ][ # # ]: 0 : if (rOverX >= nX1 && !bHidden)
932 : : {
933 : 0 : bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
934 : 0 : bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
935 : : }
936 : : else
937 : : {
938 : : sal_uInt16 nOverlap = ((ScMergeFlagAttr*)mpDoc->GetAttr(
939 : 0 : rOverX, rOverY, nTab, ATTR_MERGE_FLAG ))->GetValue();
940 : 0 : bHOver = ((nOverlap & SC_MF_HOR) != 0);
941 : 0 : bVOver = ((nOverlap & SC_MF_VER) != 0);
942 : : }
943 : : }
944 : :
945 [ + - ]: 7 : while (bVOver)
946 : : {
947 : 7 : --rOverY;
948 : 7 : bHidden = mpDoc->RowHidden(rOverY, nTab);
949 [ + - ][ + - ]: 7 : if ( !bDoMerge && !bHidden )
950 : 7 : return false;
951 : :
952 [ # # ]: 0 : if (nArrY>0)
953 : 0 : --nArrY; // lokale Kopie !
954 : :
955 [ # # ][ # # : 0 : if (rOverX >= nX1 && rOverY >= nY1 &&
# # # # ]
[ # # ][ # # ]
956 : 0 : !mpDoc->ColHidden(rOverX, nTab) &&
957 : 0 : !mpDoc->RowHidden(rOverY, nTab) &&
958 : 0 : pRowInfo[nArrY].nRowNo == rOverY)
959 : : {
960 : 0 : bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
961 : 0 : bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
962 : : }
963 : : else
964 : : {
965 : : sal_uInt16 nOverlap = ((ScMergeFlagAttr*)mpDoc->GetAttr(
966 : 0 : rOverX, rOverY, nTab, ATTR_MERGE_FLAG ))->GetValue();
967 : 0 : bHOver = ((nOverlap & SC_MF_HOR) != 0);
968 : 0 : bVOver = ((nOverlap & SC_MF_VER) != 0);
969 : : }
970 : : }
971 : :
972 : 34 : return sal_True;
973 : : }
974 : :
975 : 2063 : inline sal_Bool StringDiffer( const ScPatternAttr*& rpOldPattern, const ScPatternAttr*& rpNewPattern )
976 : : {
977 : : OSL_ENSURE( rpNewPattern, "pNewPattern" );
978 : :
979 [ + + ]: 2063 : if ( rpNewPattern == rpOldPattern )
980 : 4 : return false;
981 [ + + ]: 2059 : else if ( !rpOldPattern )
982 : 907 : return sal_True;
983 [ + + ]: 1152 : else if ( &rpNewPattern->GetItem( ATTR_FONT ) != &rpOldPattern->GetItem( ATTR_FONT ) )
984 : 146 : return sal_True;
985 [ + + ]: 1006 : else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT ) )
986 : 58 : return sal_True;
987 [ + + ]: 948 : else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT ) )
988 : 20 : return sal_True;
989 [ - + ]: 928 : else if ( &rpNewPattern->GetItem( ATTR_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_HEIGHT ) )
990 : 0 : return sal_True;
991 [ + + ]: 928 : else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) )
992 : 14 : return sal_True;
993 [ + + ]: 914 : else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) )
994 : 10 : return sal_True;
995 [ + + ]: 904 : else if ( &rpNewPattern->GetItem( ATTR_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_WEIGHT ) )
996 : 152 : return sal_True;
997 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) )
998 : 0 : return sal_True;
999 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) )
1000 : 0 : return sal_True;
1001 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_FONT_POSTURE ) )
1002 : 0 : return sal_True;
1003 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_POSTURE ) )
1004 : 0 : return sal_True;
1005 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_POSTURE ) )
1006 : 0 : return sal_True;
1007 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_FONT_UNDERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_UNDERLINE ) )
1008 : 0 : return sal_True;
1009 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_FONT_OVERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_OVERLINE ) )
1010 : 0 : return sal_True;
1011 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_FONT_WORDLINE ) != &rpOldPattern->GetItem( ATTR_FONT_WORDLINE ) )
1012 : 0 : return sal_True;
1013 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_FONT_CROSSEDOUT ) != &rpOldPattern->GetItem( ATTR_FONT_CROSSEDOUT ) )
1014 : 0 : return sal_True;
1015 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_FONT_CONTOUR ) != &rpOldPattern->GetItem( ATTR_FONT_CONTOUR ) )
1016 : 0 : return sal_True;
1017 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_FONT_SHADOWED ) != &rpOldPattern->GetItem( ATTR_FONT_SHADOWED ) )
1018 : 0 : return sal_True;
1019 [ - + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_FONT_COLOR ) != &rpOldPattern->GetItem( ATTR_FONT_COLOR ) )
1020 : 0 : return sal_True;
1021 [ + + ]: 752 : else if ( &rpNewPattern->GetItem( ATTR_HOR_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY ) )
1022 : 192 : return true;
1023 [ - + ]: 560 : else if ( &rpNewPattern->GetItem( ATTR_HOR_JUSTIFY_METHOD ) != &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY_METHOD ) )
1024 : 0 : return true;
1025 [ - + ]: 560 : else if ( &rpNewPattern->GetItem( ATTR_VER_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_VER_JUSTIFY ) )
1026 : 0 : return true;
1027 [ - + ]: 560 : else if ( &rpNewPattern->GetItem( ATTR_VER_JUSTIFY_METHOD ) != &rpOldPattern->GetItem( ATTR_VER_JUSTIFY_METHOD ) )
1028 : 0 : return true;
1029 [ - + ]: 560 : else if ( &rpNewPattern->GetItem( ATTR_STACKED ) != &rpOldPattern->GetItem( ATTR_STACKED ) )
1030 : 0 : return sal_True;
1031 [ + + ]: 560 : else if ( &rpNewPattern->GetItem( ATTR_LINEBREAK ) != &rpOldPattern->GetItem( ATTR_LINEBREAK ) )
1032 : 80 : return sal_True;
1033 [ - + ]: 480 : else if ( &rpNewPattern->GetItem( ATTR_MARGIN ) != &rpOldPattern->GetItem( ATTR_MARGIN ) )
1034 : 0 : return sal_True;
1035 [ - + ]: 480 : else if ( &rpNewPattern->GetItem( ATTR_ROTATE_VALUE ) != &rpOldPattern->GetItem( ATTR_ROTATE_VALUE ) )
1036 : 0 : return sal_True;
1037 [ - + ]: 480 : else if ( &rpNewPattern->GetItem( ATTR_FORBIDDEN_RULES ) != &rpOldPattern->GetItem( ATTR_FORBIDDEN_RULES ) )
1038 : 0 : return sal_True;
1039 [ - + ]: 480 : else if ( &rpNewPattern->GetItem( ATTR_FONT_EMPHASISMARK ) != &rpOldPattern->GetItem( ATTR_FONT_EMPHASISMARK ) )
1040 : 0 : return sal_True;
1041 [ - + ]: 480 : else if ( &rpNewPattern->GetItem( ATTR_FONT_RELIEF ) != &rpOldPattern->GetItem( ATTR_FONT_RELIEF ) )
1042 : 0 : return sal_True;
1043 [ - + ]: 480 : else if ( &rpNewPattern->GetItem( ATTR_BACKGROUND ) != &rpOldPattern->GetItem( ATTR_BACKGROUND ) )
1044 : 0 : return sal_True; // needed with automatic text color
1045 : : else
1046 : : {
1047 : 480 : rpOldPattern = rpNewPattern;
1048 : 2063 : return false;
1049 : : }
1050 : : }
1051 : :
1052 : 270 : inline void lcl_CreateInterpretProgress( sal_Bool& bProgress, ScDocument* pDoc,
1053 : : ScFormulaCell* pFCell )
1054 : : {
1055 [ + - ][ - + ]: 270 : if ( !bProgress && pFCell->GetDirty() )
[ - + ]
1056 : : {
1057 : 0 : ScProgress::CreateInterpretProgress( pDoc, sal_True );
1058 : 0 : bProgress = sal_True;
1059 : : }
1060 : 270 : }
1061 : :
1062 : 11486 : inline sal_uInt8 GetScriptType( ScDocument* pDoc, ScBaseCell* pCell,
1063 : : const ScPatternAttr* pPattern,
1064 : : const SfxItemSet* pCondSet )
1065 : : {
1066 : 11486 : return pDoc->GetCellScriptType( pCell, pPattern->GetNumberFormat( pDoc->GetFormatTable(), pCondSet ) );
1067 : : }
1068 : :
1069 : 0 : inline sal_Bool IsAmbiguousScript( sal_uInt8 nScript )
1070 : : {
1071 : : return ( nScript != SCRIPTTYPE_LATIN &&
1072 : : nScript != SCRIPTTYPE_ASIAN &&
1073 [ # # ][ # # ]: 0 : nScript != SCRIPTTYPE_COMPLEX );
[ # # ]
1074 : : }
1075 : :
1076 : 5017 : sal_Bool ScOutputData::IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY )
1077 : : {
1078 : : // pThisRowInfo may be NULL
1079 : :
1080 : : sal_Bool bEmpty;
1081 [ + + ][ + + ]: 5017 : if ( pThisRowInfo && nX <= nX2 )
1082 : 2647 : bEmpty = pThisRowInfo->pCellInfo[nX+1].bEmptyCellText;
1083 : : else
1084 [ + - ]: 2370 : bEmpty = ( mpDoc->GetCell( ScAddress( nX, nY, nTab ) ) == NULL );
1085 : :
1086 [ + + ][ + + ]: 5017 : if ( !bEmpty && ( nX < nX1 || nX > nX2 || !pThisRowInfo ) )
[ + + ][ + + ]
1087 : : {
1088 : : // for the range nX1..nX2 in RowInfo, cell protection attribute is already evaluated
1089 : : // into bEmptyCellText in ScDocument::FillInfo / lcl_HidePrint (printfun)
1090 : :
1091 : 318 : sal_Bool bIsPrint = ( eType == OUTTYPE_PRINTER );
1092 : :
1093 [ + - ][ - + ]: 318 : if ( bIsPrint || bTabProtected )
1094 : : {
1095 : : const ScProtectionAttr* pAttr = (const ScProtectionAttr*)
1096 : 0 : mpDoc->GetEffItem( nX, nY, nTab, ATTR_PROTECTION );
1097 [ # # ][ # # ]: 0 : if ( bIsPrint && pAttr->GetHidePrint() )
[ # # ]
1098 : 0 : bEmpty = sal_True;
1099 [ # # ]: 0 : else if ( bTabProtected )
1100 : : {
1101 [ # # ]: 0 : if ( pAttr->GetHideCell() )
1102 : 0 : bEmpty = sal_True;
1103 [ # # ][ # # ]: 0 : else if ( mbShowFormulas && pAttr->GetHideFormula() )
[ # # ]
1104 : : {
1105 [ # # ]: 0 : ScBaseCell* pCell = mpDoc->GetCell( ScAddress( nX, nY, nTab ) );
1106 [ # # ][ # # ]: 0 : if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
[ # # ]
1107 : 0 : bEmpty = sal_True;
1108 : : }
1109 : : }
1110 : : }
1111 : : }
1112 : 5017 : return bEmpty;
1113 : : }
1114 : :
1115 : 98 : void ScOutputData::GetVisibleCell( SCCOL nCol, SCROW nRow, SCTAB nTabP, ScBaseCell*& rpCell )
1116 : : {
1117 : 98 : mpDoc->GetCell( nCol, nRow, nTabP, rpCell );
1118 [ - + ][ - + ]: 98 : if ( rpCell && IsEmptyCellText( NULL, nCol, nRow ) )
[ + - ]
1119 : 0 : rpCell = NULL;
1120 : 98 : }
1121 : :
1122 : 343 : sal_Bool ScOutputData::IsAvailable( SCCOL nX, SCROW nY )
1123 : : {
1124 : : // apply the same logic here as in DrawStrings/DrawEdit:
1125 : : // Stop at non-empty or merged or overlapped cell,
1126 : : // where a note is empty as well as a cell that's hidden by protection settings
1127 : :
1128 [ + - ]: 343 : const ScBaseCell* pCell = mpDoc->GetCell( ScAddress( nX, nY, nTab ) );
1129 [ + + ][ + - ]: 343 : if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE && !IsEmptyCellText( NULL, nX, nY ) )
[ + - ][ + + ]
1130 : : {
1131 : 28 : return false;
1132 : : }
1133 : :
1134 : 315 : const ScPatternAttr* pPattern = mpDoc->GetPattern( nX, nY, nTab );
1135 [ - + ]: 630 : if ( ((const ScMergeAttr&)pPattern->GetItem(ATTR_MERGE)).IsMerged() ||
[ + - - + ]
1136 : 315 : ((const ScMergeFlagAttr&)pPattern->GetItem(ATTR_MERGE_FLAG)).IsOverlapped() )
1137 : : {
1138 : 0 : return false;
1139 : : }
1140 : :
1141 : 343 : return sal_True;
1142 : : }
1143 : :
1144 : : // nX, nArrY: loop variables from DrawStrings / DrawEdit
1145 : : // nPosX, nPosY: corresponding positions for nX, nArrY
1146 : : // nCellX, nCellY: position of the cell that contains the text
1147 : : // nNeeded: Text width, including margin
1148 : : // rPattern: cell format at nCellX, nCellY
1149 : : // nHorJustify: horizontal alignment (visual) to determine which cells to use for long strings
1150 : : // bCellIsValue: if set, don't extend into empty cells
1151 : : // bBreak: if set, don't extend, and don't set clip marks (but rLeftClip/rRightClip is set)
1152 : : // bOverwrite: if set, also extend into non-empty cells (for rotated text)
1153 : : // rParam output: various area parameters.
1154 : :
1155 : 11942 : void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY,
1156 : : SCCOL nCellX, SCROW nCellY, long nNeeded,
1157 : : const ScPatternAttr& rPattern,
1158 : : sal_uInt16 nHorJustify, bool bCellIsValue,
1159 : : bool bBreak, bool bOverwrite,
1160 : : OutputAreaParam& rParam )
1161 : : {
1162 : : // rThisRowInfo may be for a different row than nCellY, is still used for clip marks
1163 : 11942 : RowInfo& rThisRowInfo = pRowInfo[nArrY];
1164 : :
1165 [ - + ]: 11942 : long nLayoutSign = bLayoutRTL ? -1 : 1;
1166 : :
1167 : 11942 : long nCellPosX = nPosX; // find nCellX position, starting at nX/nPosX
1168 : 11942 : SCCOL nCompCol = nX;
1169 [ + + ]: 12522 : while ( nCellX > nCompCol )
1170 : : {
1171 : : //! extra member function for width?
1172 : : long nColWidth = ( nCompCol <= nX2 ) ?
1173 : 80 : pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
1174 [ + + ]: 580 : (long) ( mpDoc->GetColWidth( nCompCol, nTab ) * mnPPTX );
1175 : 580 : nCellPosX += nColWidth * nLayoutSign;
1176 : 580 : ++nCompCol;
1177 : : }
1178 [ + + ]: 11955 : while ( nCellX < nCompCol )
1179 : : {
1180 : 13 : --nCompCol;
1181 : : long nColWidth = ( nCompCol <= nX2 ) ?
1182 : 13 : pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
1183 [ + - ]: 13 : (long) ( mpDoc->GetColWidth( nCompCol, nTab ) * mnPPTX );
1184 : 13 : nCellPosX -= nColWidth * nLayoutSign;
1185 : : }
1186 : :
1187 : 11942 : long nCellPosY = nPosY; // find nCellY position, starting at nArrY/nPosY
1188 : 11942 : SCSIZE nCompArr = nArrY;
1189 : 11942 : SCROW nCompRow = pRowInfo[nCompArr].nRowNo;
1190 [ - + ]: 11942 : while ( nCellY > nCompRow )
1191 : : {
1192 [ # # ]: 0 : if ( nCompArr + 1 < nArrCount )
1193 : : {
1194 : 0 : nCellPosY += pRowInfo[nCompArr].nHeight;
1195 : 0 : ++nCompArr;
1196 : 0 : nCompRow = pRowInfo[nCompArr].nRowNo;
1197 : : }
1198 : : else
1199 : : {
1200 : 0 : sal_uInt16 nDocHeight = mpDoc->GetRowHeight( nCompRow, nTab );
1201 [ # # ]: 0 : if ( nDocHeight )
1202 : 0 : nCellPosY += (long) ( nDocHeight * mnPPTY );
1203 : 0 : ++nCompRow;
1204 : : }
1205 : : }
1206 : 11942 : nCellPosY -= (long) mpDoc->GetScaledRowHeight( nCellY, nCompRow-1, nTab, mnPPTY );
1207 : :
1208 : 11942 : const ScMergeAttr* pMerge = (const ScMergeAttr*)&rPattern.GetItem( ATTR_MERGE );
1209 : 11942 : sal_Bool bMerged = pMerge->IsMerged();
1210 : 11942 : long nMergeCols = pMerge->GetColMerge();
1211 [ + - ]: 11942 : if ( nMergeCols == 0 )
1212 : 11942 : nMergeCols = 1;
1213 : 11942 : long nMergeRows = pMerge->GetRowMerge();
1214 [ + - ]: 11942 : if ( nMergeRows == 0 )
1215 : 11942 : nMergeRows = 1;
1216 : :
1217 : : long i;
1218 : 11942 : long nMergeSizeX = 0;
1219 [ + + ]: 23884 : for ( i=0; i<nMergeCols; i++ )
1220 : : {
1221 : : long nColWidth = ( nCellX+i <= nX2 ) ?
1222 : 11862 : pRowInfo[0].pCellInfo[nCellX+i+1].nWidth :
1223 [ + + ]: 11942 : (long) ( mpDoc->GetColWidth( sal::static_int_cast<SCCOL>(nCellX+i), nTab ) * mnPPTX );
1224 : 11942 : nMergeSizeX += nColWidth;
1225 : : }
1226 : 11942 : long nMergeSizeY = 0;
1227 : 11942 : short nDirect = 0;
1228 [ + - ]: 11942 : if ( rThisRowInfo.nRowNo == nCellY )
1229 : : {
1230 : : // take first row's height from row info
1231 : 11942 : nMergeSizeY += rThisRowInfo.nHeight;
1232 : 11942 : nDirect = 1; // skip in loop
1233 : : }
1234 : : // following rows always from document
1235 : 11942 : nMergeSizeY += (long) mpDoc->GetScaledRowHeight( nCellY+nDirect, nCellY+nMergeRows-1, nTab, mnPPTY);
1236 : :
1237 : 11942 : --nMergeSizeX; // leave out the grid horizontally, also for alignment (align between grid lines)
1238 : :
1239 : 11942 : rParam.mnColWidth = nMergeSizeX; // store the actual column width.
1240 : :
1241 : : //
1242 : : // construct the rectangles using logical left/right values (justify is called at the end)
1243 : : //
1244 : :
1245 : : // rAlignRect is the single cell or merged area, used for alignment.
1246 : :
1247 : 11942 : rParam.maAlignRect.Left() = nCellPosX;
1248 : 11942 : rParam.maAlignRect.Right() = nCellPosX + ( nMergeSizeX - 1 ) * nLayoutSign;
1249 : 11942 : rParam.maAlignRect.Top() = nCellPosY;
1250 : 11942 : rParam.maAlignRect.Bottom() = nCellPosY + nMergeSizeY - 1;
1251 : :
1252 : : // rClipRect is all cells that are used for output.
1253 : : // For merged cells this is the same as rAlignRect, otherwise neighboring cells can also be used.
1254 : :
1255 : 11942 : rParam.maClipRect = rParam.maAlignRect;
1256 [ + + ]: 11942 : if ( nNeeded > nMergeSizeX )
1257 : : {
1258 : 1273 : SvxCellHorJustify eHorJust = (SvxCellHorJustify)nHorJustify;
1259 : :
1260 : 1273 : long nMissing = nNeeded - nMergeSizeX;
1261 : 1273 : long nLeftMissing = 0;
1262 : 1273 : long nRightMissing = 0;
1263 [ + + + + ]: 1273 : switch ( eHorJust )
1264 : : {
1265 : : case SVX_HOR_JUSTIFY_LEFT:
1266 : 359 : nRightMissing = nMissing;
1267 : 359 : break;
1268 : : case SVX_HOR_JUSTIFY_RIGHT:
1269 : 457 : nLeftMissing = nMissing;
1270 : 457 : break;
1271 : : case SVX_HOR_JUSTIFY_CENTER:
1272 : 244 : nLeftMissing = nMissing / 2;
1273 : 244 : nRightMissing = nMissing - nLeftMissing;
1274 : 244 : break;
1275 : : default:
1276 : : {
1277 : : // added to avoid warnings
1278 : : }
1279 : : }
1280 : :
1281 : : // nLeftMissing, nRightMissing are logical, eHorJust values are visual
1282 [ - + ]: 1273 : if ( bLayoutRTL )
1283 : 0 : ::std::swap( nLeftMissing, nRightMissing );
1284 : :
1285 : 1273 : SCCOL nRightX = nCellX;
1286 : 1273 : SCCOL nLeftX = nCellX;
1287 [ + - ][ + + ]: 1273 : if ( !bMerged && !bCellIsValue && !bBreak )
[ + + ]
1288 : : {
1289 : : // look for empty cells into which the text can be extended
1290 : :
1291 [ + + ][ + - ]: 1316 : while ( nRightMissing > 0 && nRightX < MAXCOL && ( bOverwrite || IsAvailable( nRightX+1, nCellY ) ) )
[ + + ][ + - ]
[ + + ][ + + ]
1292 : : {
1293 : 537 : ++nRightX;
1294 [ + - ]: 537 : long nAdd = (long) ( mpDoc->GetColWidth( nRightX, nTab ) * mnPPTX );
1295 : 537 : nRightMissing -= nAdd;
1296 : 537 : rParam.maClipRect.Right() += nAdd * nLayoutSign;
1297 : :
1298 [ + + ][ + + ]: 537 : if ( rThisRowInfo.nRowNo == nCellY && nRightX >= nX1 && nRightX <= nX2 )
[ + - ]
1299 : 524 : rThisRowInfo.pCellInfo[nRightX].bHideGrid = sal_True;
1300 : : }
1301 : :
1302 [ + + ][ + + ]: 1063 : while ( nLeftMissing > 0 && nLeftX > 0 && ( bOverwrite || IsAvailable( nLeftX-1, nCellY ) ) )
[ - + ][ # # ]
[ # # ][ + + ]
1303 : : {
1304 [ + - ][ + - ]: 284 : if ( rThisRowInfo.nRowNo == nCellY && nLeftX >= nX1 && nLeftX <= nX2 )
[ + - ]
1305 : 284 : rThisRowInfo.pCellInfo[nLeftX].bHideGrid = sal_True;
1306 : :
1307 : 284 : --nLeftX;
1308 [ + - ]: 284 : long nAdd = (long) ( mpDoc->GetColWidth( nLeftX, nTab ) * mnPPTX );
1309 : 284 : nLeftMissing -= nAdd;
1310 : 284 : rParam.maClipRect.Left() -= nAdd * nLayoutSign;
1311 : : }
1312 : : }
1313 : :
1314 : : // Set flag and reserve space for clipping mark triangle,
1315 : : // even if rThisRowInfo isn't for nCellY (merged cells).
1316 [ + + ][ + - ]: 1273 : if ( nRightMissing > 0 && bMarkClipped && nRightX >= nX1 && nRightX <= nX2 && !bBreak && !bCellIsValue )
[ + - ][ + - ]
[ + + ][ + + ]
1317 : : {
1318 : 28 : rThisRowInfo.pCellInfo[nRightX+1].nClipMark |= SC_CLIPMARK_RIGHT;
1319 : 28 : bAnyClipped = sal_True;
1320 : 28 : long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
1321 : 28 : rParam.maClipRect.Right() -= nMarkPixel * nLayoutSign;
1322 : : }
1323 [ + + ][ + - ]: 1273 : if ( nLeftMissing > 0 && bMarkClipped && nLeftX >= nX1 && nLeftX <= nX2 && !bBreak && !bCellIsValue )
[ + + ][ + - ]
[ + - ][ + + ]
1324 : : {
1325 : 134 : rThisRowInfo.pCellInfo[nLeftX+1].nClipMark |= SC_CLIPMARK_LEFT;
1326 : 134 : bAnyClipped = sal_True;
1327 : 134 : long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
1328 : 134 : rParam.maClipRect.Left() += nMarkPixel * nLayoutSign;
1329 : : }
1330 : :
1331 : 1273 : rParam.mbLeftClip = ( nLeftMissing > 0 );
1332 : 1273 : rParam.mbRightClip = ( nRightMissing > 0 );
1333 : : }
1334 : : else
1335 : : {
1336 : 10669 : rParam.mbLeftClip = rParam.mbRightClip = false;
1337 : :
1338 : : // leave space for AutoFilter on screen
1339 : : // (for automatic line break: only if not formatting for printer, as in ScColumn::GetNeededSize)
1340 : :
1341 [ + + + + ]: 21288 : if ( eType==OUTTYPE_WINDOW &&
[ - + ][ # # ]
[ + + ]
1342 : 10619 : ( static_cast<const ScMergeFlagAttr&>(rPattern.GetItem(ATTR_MERGE_FLAG)).GetValue() & SC_MF_AUTO ) &&
1343 : 2 : ( !bBreak || mpRefDevice == pFmtDevice ) )
1344 : : {
1345 : : // filter drop-down width is now independent from row height
1346 : 2 : const long nFilter = DROPDOWN_BITMAP_SIZE;
1347 : 2 : sal_Bool bFit = ( nNeeded + nFilter <= nMergeSizeX );
1348 [ - + ][ # # ]: 2 : if ( bFit || bCellIsValue )
1349 : : {
1350 : : // content fits even in the remaining area without the filter button
1351 : : // -> align within that remaining area
1352 : :
1353 : 2 : rParam.maAlignRect.Right() -= nFilter * nLayoutSign;
1354 : 2 : rParam.maClipRect.Right() -= nFilter * nLayoutSign;
1355 : :
1356 : : // if a number doesn't fit, don't hide part of the number behind the button
1357 : : // -> set clip flags, so "###" replacement is used (but also within the smaller area)
1358 : :
1359 [ - + ]: 2 : if ( !bFit )
1360 : 0 : rParam.mbLeftClip = rParam.mbRightClip = sal_True;
1361 : : }
1362 : : }
1363 : : }
1364 : :
1365 : : // justify both rectangles for alignment calculation, use with DrawText etc.
1366 : :
1367 : 11942 : rParam.maAlignRect.Justify();
1368 : 11942 : rParam.maClipRect.Justify();
1369 : 11942 : }
1370 : :
1371 : : namespace {
1372 : :
1373 : 10931 : bool beginsWithRTLCharacter(const rtl::OUString& rStr)
1374 : : {
1375 [ - + ]: 10931 : if (rStr.isEmpty())
1376 : 0 : return false;
1377 : :
1378 [ + - ][ - + ]: 10931 : switch (ScGlobal::pCharClass->getCharacterDirection(rStr, 0))
1379 : : {
1380 : : case i18n::DirectionProperty_RIGHT_TO_LEFT:
1381 : : case i18n::DirectionProperty_RIGHT_TO_LEFT_ARABIC:
1382 : : case i18n::DirectionProperty_RIGHT_TO_LEFT_EMBEDDING:
1383 : : case i18n::DirectionProperty_RIGHT_TO_LEFT_OVERRIDE:
1384 : 0 : return true;
1385 : : default:
1386 : : ;
1387 : : }
1388 : :
1389 : 10931 : return false;
1390 : : }
1391 : :
1392 : : }
1393 : :
1394 : 1345 : void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
1395 : : {
1396 : : OSL_ENSURE( mpDev == mpRefDevice ||
1397 : : mpDev->GetMapMode().GetMapUnit() == mpRefDevice->GetMapMode().GetMapUnit(),
1398 : : "DrawStrings: unterschiedliche MapUnits ?!?!" );
1399 : :
1400 [ - + ][ # # ]: 1345 : vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, mpDev->GetExtOutDevData() );
[ # # ][ # # ]
1401 : :
1402 : 1345 : sal_Bool bWasIdleDisabled = mpDoc->IsIdleDisabled();
1403 : 1345 : mpDoc->DisableIdle( true );
1404 : :
1405 [ + - ]: 1345 : ScDrawStringsVars aVars( this, bPixelToLogic );
1406 : :
1407 : 1345 : sal_Bool bProgress = false;
1408 : :
1409 : 1345 : long nInitPosX = nScrX;
1410 [ + + ]: 1345 : if ( bLayoutRTL )
1411 : 2 : nInitPosX += nMirrorW - 1; // pixels
1412 [ + + ]: 1345 : long nLayoutSign = bLayoutRTL ? -1 : 1;
1413 : :
1414 : 1345 : SCCOL nLastContentCol = MAXCOL;
1415 [ + - ]: 1345 : if ( nX2 < MAXCOL )
1416 : : nLastContentCol = sal::static_int_cast<SCCOL>(
1417 [ + - ]: 1345 : nLastContentCol - mpDoc->GetEmptyLinesInBlock( nX2+1, nY1, nTab, MAXCOL, nY2, nTab, DIR_RIGHT ) );
1418 : 1345 : SCCOL nLoopStartX = nX1;
1419 [ + + ]: 1345 : if ( nX1 > 0 )
1420 : 294 : --nLoopStartX; // start before nX1 for rest of long text to the left
1421 : :
1422 : : // variables for GetOutputArea
1423 [ + - ]: 1345 : OutputAreaParam aAreaParam;
1424 : 1345 : sal_Bool bCellIsValue = false;
1425 : 1345 : long nNeededWidth = 0;
1426 : 1345 : SvxCellHorJustify eOutHorJust = SVX_HOR_JUSTIFY_STANDARD;
1427 : 1345 : const ScPatternAttr* pPattern = NULL;
1428 : 1345 : const SfxItemSet* pCondSet = NULL;
1429 : 1345 : const ScPatternAttr* pOldPattern = NULL;
1430 : 1345 : const SfxItemSet* pOldCondSet = NULL;
1431 : 1345 : sal_uInt8 nOldScript = 0;
1432 : :
1433 : : // alternative pattern instances in case we need to modify the pattern
1434 : : // before processing the cell value.
1435 [ + - ]: 1345 : ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
1436 : :
1437 : 1345 : long nPosY = nScrY;
1438 [ + + ]: 17212 : for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
1439 : : {
1440 : 15867 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1441 [ + - ]: 15867 : if ( pThisRowInfo->bChanged )
1442 : : {
1443 : 15867 : SCROW nY = pThisRowInfo->nRowNo;
1444 : 15867 : long nPosX = nInitPosX;
1445 [ + + ]: 15867 : if ( nLoopStartX < nX1 )
1446 : 1340 : nPosX -= pRowInfo[0].pCellInfo[nLoopStartX+1].nWidth * nLayoutSign;
1447 [ + + ]: 168304 : for (SCCOL nX=nLoopStartX; nX<=nX2; nX++)
1448 : : {
1449 : 152437 : sal_Bool bMergeEmpty = false;
1450 : 152437 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
1451 [ + + ][ + + ]: 152437 : sal_Bool bEmpty = nX < nX1 || pInfo->bEmptyCellText;
1452 : :
1453 : 152437 : SCCOL nCellX = nX; // position where the cell really starts
1454 : 152437 : SCROW nCellY = nY;
1455 : 152437 : sal_Bool bDoCell = false;
1456 : 152437 : sal_Bool bNeedEdit = false;
1457 : :
1458 : : //
1459 : : // Part of a merged cell?
1460 : : //
1461 : :
1462 [ + + ][ + + ]: 152437 : sal_Bool bOverlapped = ( pInfo->bHOverlapped || pInfo->bVOverlapped );
1463 [ + + ]: 152437 : if ( bOverlapped )
1464 : : {
1465 : 34 : bEmpty = sal_True;
1466 : :
1467 : : SCCOL nOverX; // start of the merged cells
1468 : : SCROW nOverY;
1469 : 34 : sal_Bool bVisChanged = !pRowInfo[nArrY-1].bChanged;
1470 [ + - ][ - + ]: 34 : if (GetMergeOrigin( nX,nY, nArrY, nOverX,nOverY, bVisChanged ))
1471 : : {
1472 : 0 : nCellX = nOverX;
1473 : 0 : nCellY = nOverY;
1474 : 0 : bDoCell = sal_True;
1475 : : }
1476 : : else
1477 : 34 : bMergeEmpty = sal_True;
1478 : : }
1479 : :
1480 : : //
1481 : : // Rest of a long text further to the left?
1482 : : //
1483 : :
1484 [ + + ][ + + ]: 152437 : if ( bEmpty && !bMergeEmpty && nX < nX1 && !bOverlapped )
[ + + ][ + - ]
1485 : : {
1486 : 1340 : SCCOL nTempX=nX1;
1487 [ + + ][ + - ]: 1794 : while (nTempX > 0 && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
[ + + ][ + + ]
1488 : 454 : --nTempX;
1489 : :
1490 [ + + ][ + + ]: 1598 : if ( nTempX < nX1 &&
[ + - ][ + + ]
1491 [ + - ]: 241 : !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
1492 [ + - ]: 17 : !mpDoc->HasAttrib( nTempX,nY,nTab, nX1,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
1493 : : {
1494 : 17 : nCellX = nTempX;
1495 : 17 : bDoCell = sal_True;
1496 : : }
1497 : : }
1498 : :
1499 : : //
1500 : : // Rest of a long text further to the right?
1501 : : //
1502 : :
1503 [ + + ][ + + ]: 152437 : if ( bEmpty && !bMergeEmpty && nX == nX2 && !bOverlapped )
[ + + ][ + - ]
1504 : : {
1505 : : // don't have to look further than nLastContentCol
1506 : :
1507 : 15241 : SCCOL nTempX=nX;
1508 [ + + ][ + - ]: 17405 : while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
[ + + ][ + + ]
1509 : 2164 : ++nTempX;
1510 : :
1511 [ + + ][ + + ]: 15498 : if ( nTempX > nX &&
[ + - ][ + + ]
1512 [ + - ]: 177 : !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
1513 [ + - ]: 80 : !mpDoc->HasAttrib( nTempX,nY,nTab, nX,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
1514 : : {
1515 : 80 : nCellX = nTempX;
1516 : 80 : bDoCell = sal_True;
1517 : : }
1518 : : }
1519 : :
1520 : : //
1521 : : // normal visible cell
1522 : : //
1523 : :
1524 [ + + ]: 152437 : if (!bEmpty)
1525 : 11692 : bDoCell = sal_True;
1526 : :
1527 : : //
1528 : : // don't output the cell that's being edited
1529 : : //
1530 : :
1531 [ + + ][ - + ]: 152437 : if ( bDoCell && bEditMode && nCellX == nEditCol && nCellY == nEditRow )
[ # # ][ # # ]
1532 : 0 : bDoCell = false;
1533 : :
1534 : : // skip text in cell if data bar is set and only value selected
1535 [ + + ]: 152437 : if ( bDoCell )
1536 : : {
1537 [ - + ][ # # ]: 11789 : if(pInfo->pDataBar && !pInfo->pDataBar->mbShowValue)
1538 : 0 : bDoCell = false;
1539 : : }
1540 : :
1541 : : //
1542 : : // output the cell text
1543 : : //
1544 : :
1545 : 152437 : ScBaseCell* pCell = NULL;
1546 [ + + ]: 152437 : if (bDoCell)
1547 : : {
1548 [ + - ][ + + ]: 11789 : if ( nCellY == nY && nCellX == nX && nCellX >= nX1 && nCellX <= nX2 )
[ + + ][ + - ]
1549 : 11692 : pCell = pThisRowInfo->pCellInfo[nCellX+1].pCell;
1550 : : else
1551 [ + - ]: 97 : GetVisibleCell( nCellX, nCellY, nTab, pCell ); // get from document
1552 [ - + ]: 11789 : if ( !pCell )
1553 : 0 : bDoCell = false;
1554 [ + + ]: 11789 : else if ( pCell->GetCellType() == CELLTYPE_EDIT )
1555 : 303 : bNeedEdit = sal_True;
1556 : : }
1557 [ + + ][ + + ]: 152437 : if (bDoCell && !bNeedEdit)
1558 : : {
1559 [ + - ][ + + ]: 11486 : if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 )
[ + + ]
1560 : : {
1561 : 11390 : CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1];
1562 : 11390 : pPattern = rCellInfo.pPatternAttr;
1563 : 11390 : pCondSet = rCellInfo.pConditionSet;
1564 : :
1565 [ - + ]: 11390 : if ( !pPattern )
1566 : : {
1567 : : // #i68085# pattern from cell info for hidden columns is null,
1568 : : // test for null is quicker than using column flags
1569 [ # # ]: 0 : pPattern = mpDoc->GetPattern( nCellX, nCellY, nTab );
1570 [ # # ]: 0 : pCondSet = mpDoc->GetCondResult( nCellX, nCellY, nTab );
1571 : 11390 : }
1572 : : }
1573 : : else // get from document
1574 : : {
1575 [ + - ]: 96 : pPattern = mpDoc->GetPattern( nCellX, nCellY, nTab );
1576 [ + - ]: 96 : pCondSet = mpDoc->GetCondResult( nCellX, nCellY, nTab );
1577 : : }
1578 : :
1579 [ + - ]: 18068 : if (pCell->HasValueData() &&
[ + + + + ]
[ + + ]
1580 : : static_cast<const SfxBoolItem&>(
1581 [ + - ]: 6582 : pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue())
1582 : : {
1583 : : // Disable line break when the cell content is numeric.
1584 [ + - ][ + - ]: 320 : aAltPatterns.push_back(new ScPatternAttr(*pPattern));
[ + - ]
1585 [ + - ]: 320 : ScPatternAttr* pAltPattern = &aAltPatterns.back();
1586 [ + - ]: 320 : SfxBoolItem aLineBreak(ATTR_LINEBREAK, false);
1587 [ + - ]: 320 : pAltPattern->GetItemSet().Put(aLineBreak);
1588 [ + - ]: 320 : pPattern = pAltPattern;
1589 : : }
1590 : :
1591 [ + - ]: 11486 : sal_uInt8 nScript = GetScriptType( mpDoc, pCell, pPattern, pCondSet );
1592 [ + + ][ + - ]: 11486 : if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
1593 [ + + ][ + + ]: 11486 : if ( pPattern != pOldPattern || pCondSet != pOldCondSet ||
[ + - ][ - + ]
1594 : : nScript != nOldScript || mbSyntaxMode )
1595 : : {
1596 [ + - ][ + + ]: 2063 : if ( StringDiffer(pOldPattern,pPattern) ||
[ + + ][ + - ]
[ - + ][ + + ]
1597 : : pCondSet != pOldCondSet || nScript != nOldScript || mbSyntaxMode )
1598 [ + - ]: 1583 : aVars.SetPattern( pPattern, pCondSet, pCell, nScript );
1599 : : else
1600 [ + - ]: 480 : aVars.SetPatternSimple( pPattern, pCondSet );
1601 : 2063 : pOldPattern = pPattern;
1602 : 2063 : pOldCondSet = pCondSet;
1603 : 2063 : nOldScript = nScript;
1604 : : }
1605 : :
1606 : : // use edit engine for rotated, stacked or mixed-script text
1607 [ + - + + : 33881 : if ( aVars.GetOrient() == SVX_ORIENTATION_STACKED ||
- + ][ + + ]
1608 : 22395 : aVars.IsRotated() || IsAmbiguousScript(nScript) )
1609 : 577 : bNeedEdit = sal_True;
1610 : : }
1611 [ + + ][ + + ]: 152437 : if (bDoCell && !bNeedEdit)
1612 : : {
1613 : 10909 : sal_Bool bFormulaCell = (pCell->GetCellType() == CELLTYPE_FORMULA );
1614 [ + + ]: 10909 : if ( bFormulaCell )
1615 [ + - ][ + - ]: 270 : lcl_CreateInterpretProgress( bProgress, mpDoc, (ScFormulaCell*)pCell );
1616 [ + - ][ - + ]: 10909 : if ( aVars.SetText(pCell) )
1617 : 0 : pOldPattern = NULL;
1618 [ + - ]: 10909 : bNeedEdit = aVars.HasEditCharacters() ||
1619 [ + - ][ + + ]: 10909 : (bFormulaCell && ((ScFormulaCell*)pCell)->IsMultilineResult());
[ + - ][ + - ]
[ - + ]
1620 : : }
1621 : 152437 : long nTotalMargin = 0;
1622 [ + + ][ + + ]: 152437 : if (bDoCell && !bNeedEdit)
1623 : : {
1624 : 10909 : CellType eCellType = pCell->GetCellType();
1625 : 10909 : bCellIsValue = ( eCellType == CELLTYPE_VALUE );
1626 [ + + ]: 10909 : if ( eCellType == CELLTYPE_FORMULA )
1627 : : {
1628 [ + - ]: 270 : ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
1629 [ + - ][ + - ]: 270 : bCellIsValue = pFCell->IsRunning() || pFCell->IsValue();
[ + + ]
1630 : : }
1631 : :
1632 [ + + ]: 10909 : if (aVars.GetHorJust() == SVX_HOR_JUSTIFY_STANDARD)
1633 : : {
1634 : : // fdo#32530: Default alignment depends on value vs
1635 : : // string, and the direction of the 1st letter.
1636 [ + - ][ + - ]: 9898 : if (beginsWithRTLCharacter(aVars.GetString()))
[ - + ]
1637 [ # # ]: 0 : eOutHorJust = bCellIsValue ? SVX_HOR_JUSTIFY_LEFT : SVX_HOR_JUSTIFY_RIGHT;
1638 : : else
1639 [ + + ]: 9898 : eOutHorJust = bCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT;
1640 : : }
1641 : : else
1642 : 1011 : eOutHorJust = aVars.GetHorJust();
1643 : :
1644 [ + + ][ - + ]: 10909 : if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
1645 : 144 : eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
1646 : :
1647 [ + + ][ + + ]: 10909 : sal_Bool bBreak = ( aVars.GetLineBreak() || aVars.GetHorJust() == SVX_HOR_JUSTIFY_BLOCK );
1648 [ - + ][ # # ]: 10909 : sal_Bool bRepeat = aVars.IsRepeat() && !bBreak;
1649 [ + + ][ + + ]: 10909 : sal_Bool bShrink = aVars.IsShrink() && !bBreak && !bRepeat;
[ + - ]
1650 : :
1651 : : nTotalMargin =
1652 : 10909 : static_cast<long>(aVars.GetLeftTotal() * mnPPTX) +
1653 : 10909 : static_cast<long>(aVars.GetMargin()->GetRightMargin() * mnPPTX);
1654 : :
1655 : 10909 : nNeededWidth = aVars.GetTextSize().Width() + nTotalMargin;
1656 : :
1657 : : // GetOutputArea gives justfied rectangles
1658 : : GetOutputArea( nX, nArrY, nPosX, nPosY, nCellX, nCellY, nNeededWidth,
1659 : 10909 : *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
1660 : : bCellIsValue || bRepeat || bShrink, bBreak, false,
1661 [ + - ][ + + ]: 21818 : aAreaParam );
[ + - ][ + + ]
1662 : :
1663 [ + - ]: 10909 : aVars.RepeatToFill( aAreaParam.mnColWidth - nTotalMargin );
1664 [ + + ]: 10909 : if ( bShrink )
1665 : : {
1666 [ + - ]: 36 : if ( aVars.GetOrient() != SVX_ORIENTATION_STANDARD )
1667 : : {
1668 : : // Only horizontal scaling is handled here.
1669 : : // DrawEdit is used to vertically scale 90 deg rotated text.
1670 : 36 : bNeedEdit = sal_True;
1671 : : }
1672 [ # # ][ # # ]: 0 : else if ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) // horizontal
1673 : : {
1674 [ # # ]: 0 : long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin;
1675 : 0 : long nScaleSize = aVars.GetTextSize().Width(); // without margin
1676 : :
1677 [ # # ]: 0 : if ( nScaleSize > 0 ) // 0 if the text is empty (formulas, number formats)
1678 : : {
1679 : 0 : long nScale = ( nAvailable * 100 ) / nScaleSize;
1680 : :
1681 [ # # ]: 0 : aVars.SetShrinkScale( nScale, nOldScript );
1682 : 0 : long nNewSize = aVars.GetTextSize().Width();
1683 : :
1684 : 0 : sal_uInt16 nShrinkAgain = 0;
1685 [ # # ][ # # ]: 0 : while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
[ # # ]
1686 : : {
1687 : : // If the text is still too large, reduce the scale again by 10%, until it fits,
1688 : : // at most 7 times (it's less than 50% of the calculated scale then).
1689 : :
1690 : 0 : nScale = ( nScale * 9 ) / 10;
1691 [ # # ]: 0 : aVars.SetShrinkScale( nScale, nOldScript );
1692 : 0 : nNewSize = aVars.GetTextSize().Width();
1693 : 0 : ++nShrinkAgain;
1694 : : }
1695 : : // If even at half the size the font still isn't rendered smaller,
1696 : : // fall back to normal clipping (showing ### for numbers).
1697 [ # # ]: 0 : if ( nNewSize <= nAvailable )
1698 : 0 : aAreaParam.mbLeftClip = aAreaParam.mbRightClip = false;
1699 : :
1700 : 0 : pOldPattern = NULL;
1701 : : }
1702 : : }
1703 : : }
1704 : :
1705 [ - + ][ # # ]: 10909 : if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip )
[ # # ]
1706 : : {
1707 [ # # ]: 0 : long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin;
1708 : 0 : long nRepeatSize = aVars.GetTextSize().Width(); // without margin
1709 : : // When formatting for the printer, the text sizes don't always add up.
1710 : : // Round down (too few repetitions) rather than exceeding the cell size then:
1711 [ # # ]: 0 : if ( pFmtDevice != mpRefDevice )
1712 : 0 : ++nRepeatSize;
1713 [ # # ]: 0 : if ( nRepeatSize > 0 )
1714 : : {
1715 : 0 : long nRepeatCount = nAvailable / nRepeatSize;
1716 [ # # ]: 0 : if ( nRepeatCount > 1 )
1717 : : {
1718 [ # # ]: 0 : String aCellStr = aVars.GetString();
1719 [ # # ]: 0 : String aRepeated = aCellStr;
1720 [ # # ]: 0 : for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
1721 [ # # ]: 0 : aRepeated.Append( aCellStr );
1722 [ # # ][ # # ]: 0 : aVars.SetAutoText( aRepeated );
[ # # ]
1723 : : }
1724 : : }
1725 : : }
1726 : :
1727 : : // use edit engine if automatic line breaks are needed
1728 [ + + ]: 10909 : if ( bBreak )
1729 : : {
1730 [ - + ]: 186 : if ( aVars.GetOrient() == SVX_ORIENTATION_STANDARD )
1731 [ # # ][ # # ]: 0 : bNeedEdit = ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip );
1732 : : else
1733 : : {
1734 : 186 : long nHeight = aVars.GetTextSize().Height() +
1735 : 186 : (long)(aVars.GetMargin()->GetTopMargin()*mnPPTY) +
1736 : 186 : (long)(aVars.GetMargin()->GetBottomMargin()*mnPPTY);
1737 [ + - ]: 186 : bNeedEdit = ( nHeight > aAreaParam.maClipRect.GetHeight() );
1738 : : }
1739 : : }
1740 [ + + ]: 10909 : if (!bNeedEdit)
1741 : : {
1742 : : bNeedEdit =
1743 : 10756 : aVars.GetHorJust() == SVX_HOR_JUSTIFY_BLOCK &&
1744 [ - + ][ + + ]: 10756 : aVars.GetHorJustMethod() == SVX_JUSTIFY_METHOD_DISTRIBUTE;
1745 : : }
1746 : : }
1747 [ + + ]: 152437 : if (bNeedEdit)
1748 : : {
1749 : : // mark the cell in CellInfo to be drawn in DrawEdit:
1750 : : // Cells to the left are marked directly, cells to the
1751 : : // right are handled by the flag for nX2
1752 [ - + ]: 1033 : SCCOL nMarkX = ( nCellX <= nX2 ) ? nCellX : nX2;
1753 [ - + ]: 1033 : RowInfo* pMarkRowInfo = ( nCellY == nY ) ? pThisRowInfo : &pRowInfo[0];
1754 : 1033 : pMarkRowInfo->pCellInfo[nMarkX+1].bEditEngine = sal_True;
1755 : 1033 : bDoCell = false; // don't draw here
1756 : : }
1757 [ + + ]: 152437 : if ( bDoCell )
1758 : : {
1759 [ + + ][ + + ]: 10756 : if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
[ + + ]
1760 : : {
1761 [ - + ]: 323 : if (mbShowFormulas)
1762 [ # # ]: 0 : aVars.SetHashText();
1763 : : else
1764 : : // Adjust the decimals to fit the available column width.
1765 [ + - ]: 323 : aVars.SetTextToWidthOrHash(pCell, aAreaParam.mnColWidth - nTotalMargin);
1766 : :
1767 : 323 : nNeededWidth = aVars.GetTextSize().Width() +
1768 : 323 : (long) ( aVars.GetLeftTotal() * mnPPTX ) +
1769 : 323 : (long) ( aVars.GetMargin()->GetRightMargin() * mnPPTX );
1770 [ + + ][ + - ]: 323 : if ( nNeededWidth <= aAreaParam.maClipRect.GetWidth() )
1771 : 275 : aAreaParam.mbLeftClip = aAreaParam.mbRightClip = false;
1772 : :
1773 : : // If the "###" replacement doesn't fit into the cells, no clip marks
1774 : : // are shown, as the "###" already denotes too little space.
1775 : : // The rectangles from the first GetOutputArea call remain valid.
1776 : : }
1777 : :
1778 : 10756 : long nJustPosX = aAreaParam.maAlignRect.Left(); // "justified" - effect of alignment will be added
1779 : 10756 : long nJustPosY = aAreaParam.maAlignRect.Top();
1780 [ + - ]: 10756 : long nAvailWidth = aAreaParam.maAlignRect.GetWidth();
1781 [ + - ]: 10756 : long nOutHeight = aAreaParam.maAlignRect.GetHeight();
1782 : :
1783 [ + + ][ + + ]: 10756 : sal_Bool bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW );
1784 [ + + ]: 10756 : if ( aAreaParam.maClipRect.Left() < nScrX )
1785 : : {
1786 : 16 : aAreaParam.maClipRect.Left() = nScrX;
1787 : 16 : aAreaParam.mbLeftClip = sal_True;
1788 : : }
1789 [ + + ]: 10756 : if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
1790 : : {
1791 : 80 : aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one?
1792 : 80 : aAreaParam.mbRightClip = sal_True;
1793 : : }
1794 : :
1795 [ + + ][ + + ]: 10756 : sal_Bool bHClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
1796 : 10756 : sal_Bool bVClip = false;
1797 : :
1798 [ - + ]: 10756 : if ( aAreaParam.maClipRect.Top() < nScrY )
1799 : : {
1800 : 0 : aAreaParam.maClipRect.Top() = nScrY;
1801 : 0 : bVClip = sal_True;
1802 : : }
1803 [ - + ]: 10756 : if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
1804 : : {
1805 : 0 : aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one?
1806 : 0 : bVClip = sal_True;
1807 : : }
1808 : :
1809 : : //
1810 : : // horizontalen Platz testen
1811 : : //
1812 : :
1813 : 10756 : sal_Bool bRightAdjusted = false; // to correct text width calculation later
1814 : 10756 : sal_Bool bNeedEditEngine = false;
1815 [ + - ][ + + ]: 10756 : if ( !bNeedEditEngine && !bOutside )
1816 : : {
1817 [ + + - - ]: 10660 : switch (eOutHorJust)
1818 : : {
1819 : : case SVX_HOR_JUSTIFY_LEFT:
1820 : 5013 : nJustPosX += (long) ( aVars.GetLeftTotal() * mnPPTX );
1821 : 5013 : break;
1822 : : case SVX_HOR_JUSTIFY_RIGHT:
1823 : 5647 : nJustPosX += nAvailWidth - aVars.GetTextSize().Width() -
1824 : 5647 : (long) ( aVars.GetMargin()->GetRightMargin() * mnPPTX );
1825 : 5647 : bRightAdjusted = sal_True;
1826 : 5647 : break;
1827 : : case SVX_HOR_JUSTIFY_CENTER:
1828 : 0 : nJustPosX += ( nAvailWidth - aVars.GetTextSize().Width() +
1829 : 0 : (long) ( aVars.GetLeftTotal() * mnPPTX ) -
1830 : 0 : (long) ( aVars.GetMargin()->GetRightMargin() * mnPPTX ) ) / 2;
1831 : 0 : break;
1832 : : default:
1833 : : {
1834 : : // added to avoid warnings
1835 : : }
1836 : : }
1837 : :
1838 : 10660 : long nTestClipHeight = aVars.GetTextSize().Height();
1839 [ - + - - ]: 10660 : switch (aVars.GetVerJust())
1840 : : {
1841 : : case SVX_VER_JUSTIFY_TOP:
1842 : : case SVX_VER_JUSTIFY_BLOCK:
1843 : : {
1844 : 0 : long nTop = (long)( aVars.GetMargin()->GetTopMargin() * mnPPTY );
1845 : 0 : nJustPosY += nTop;
1846 : 0 : nTestClipHeight += nTop;
1847 : : }
1848 : 0 : break;
1849 : : case SVX_VER_JUSTIFY_BOTTOM:
1850 : : {
1851 : 10660 : long nBot = (long)( aVars.GetMargin()->GetBottomMargin() * mnPPTY );
1852 : 10660 : nJustPosY += nOutHeight - aVars.GetTextSize().Height() - nBot;
1853 : 10660 : nTestClipHeight += nBot;
1854 : : }
1855 : 10660 : break;
1856 : : case SVX_VER_JUSTIFY_CENTER:
1857 : : {
1858 : 0 : long nTop = (long)( aVars.GetMargin()->GetTopMargin() * mnPPTY );
1859 : 0 : long nBot = (long)( aVars.GetMargin()->GetBottomMargin() * mnPPTY );
1860 : : nJustPosY += ( nOutHeight + nTop -
1861 : 0 : aVars.GetTextSize().Height() - nBot ) / 2;
1862 : 0 : nTestClipHeight += Abs( nTop - nBot );
1863 : : }
1864 : 0 : break;
1865 : : default:
1866 : : {
1867 : : // added to avoid warnings
1868 : : }
1869 : : }
1870 : :
1871 [ + + ]: 10660 : if ( nTestClipHeight > nOutHeight )
1872 : : {
1873 : : // kein vertikales Clipping beim Drucken von Zellen mit
1874 : : // optimaler Hoehe, ausser bei Groesse in bedingter Formatierung
1875 [ - + ][ # # ]: 32 : if ( eType != OUTTYPE_PRINTER ||
[ # # ][ + - ]
1876 [ # # ]: 0 : ( mpDoc->GetRowFlags( nCellY, nTab ) & CR_MANUALSIZE ) ||
1877 [ # # ]: 0 : ( aVars.HasCondHeight() ) )
1878 : 32 : bVClip = sal_True;
1879 : : }
1880 : :
1881 [ + + ][ + + ]: 10660 : if ( bHClip || bVClip )
1882 : : {
1883 : : // nur die betroffene Dimension clippen,
1884 : : // damit bei nicht-proportionalem Resize nicht alle
1885 : : // rechtsbuendigen Zahlen abgeschnitten werden:
1886 : :
1887 [ + + ]: 75 : if (!bHClip)
1888 : : {
1889 : 2 : aAreaParam.maClipRect.Left() = nScrX;
1890 : 2 : aAreaParam.maClipRect.Right() = nScrX+nScrW;
1891 : : }
1892 [ + + ]: 75 : if (!bVClip)
1893 : : {
1894 : 43 : aAreaParam.maClipRect.Top() = nScrY;
1895 : 43 : aAreaParam.maClipRect.Bottom() = nScrY+nScrH;
1896 : : }
1897 : :
1898 : : // aClipRect is not used after SetClipRegion/IntersectClipRegion,
1899 : : // so it can be modified here
1900 [ - + ]: 75 : if (bPixelToLogic)
1901 [ # # ]: 0 : aAreaParam.maClipRect = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
1902 : :
1903 [ - + ]: 75 : if (bMetaFile)
1904 : : {
1905 [ # # ]: 0 : mpDev->Push();
1906 [ # # ]: 0 : mpDev->IntersectClipRegion( aAreaParam.maClipRect );
1907 : : }
1908 : : else
1909 [ + - ][ + - ]: 75 : mpDev->SetClipRegion( Region( aAreaParam.maClipRect ) );
[ + - ]
1910 : : }
1911 : :
1912 : 10660 : Point aURLStart( nJustPosX, nJustPosY ); // copy before modifying for orientation
1913 : :
1914 [ + + - - ]: 10660 : switch (aVars.GetOrient())
1915 : : {
1916 : : case SVX_ORIENTATION_STANDARD:
1917 : 10507 : nJustPosY += aVars.GetAscent();
1918 : 10507 : break;
1919 : : case SVX_ORIENTATION_TOPBOTTOM:
1920 : 153 : nJustPosX += aVars.GetTextSize().Width() - aVars.GetAscent();
1921 : 153 : break;
1922 : : case SVX_ORIENTATION_BOTTOMTOP:
1923 : 0 : nJustPosY += aVars.GetTextSize().Height();
1924 : 0 : nJustPosX += aVars.GetAscent();
1925 : 0 : break;
1926 : : default:
1927 : : {
1928 : : // added to avoid warnings
1929 : : }
1930 : : }
1931 : :
1932 : : // When clipping, the visible part is now completely defined by the alignment,
1933 : : // there's no more special handling to show the right part of RTL text.
1934 : :
1935 : 10660 : Point aDrawTextPos( nJustPosX, nJustPosY );
1936 [ + + ]: 10660 : if ( bPixelToLogic )
1937 : : {
1938 : : // undo text width adjustment in pixels
1939 [ + + ]: 956 : if (bRightAdjusted)
1940 : 916 : aDrawTextPos.X() += aVars.GetTextSize().Width();
1941 : :
1942 [ + - ]: 956 : aDrawTextPos = mpRefDevice->PixelToLogic( aDrawTextPos );
1943 : :
1944 : : // redo text width adjustment in logic units
1945 [ + + ]: 956 : if (bRightAdjusted)
1946 : 916 : aDrawTextPos.X() -= aVars.GetOriginalWidth();
1947 : : }
1948 : :
1949 : : // in Metafiles immer DrawTextArray, damit die Positionen mit
1950 : : // aufgezeichnet werden (fuer nicht-proportionales Resize):
1951 : :
1952 [ + - ]: 10660 : String aString = aVars.GetString();
1953 [ + - ][ + + ]: 10660 : if (bMetaFile || pFmtDevice != mpDev || aZoomX != aZoomY)
[ + - ][ - + ]
[ + + ]
1954 : : {
1955 [ + - ]: 1002 : sal_Int32* pDX = new sal_Int32[aString.Len()];
1956 [ + - ]: 1002 : pFmtDevice->GetTextArray( aString, pDX );
1957 : :
1958 [ - + # # ]: 1002 : if ( !mpRefDevice->GetConnectMetaFile() ||
[ + - ]
1959 : 0 : mpRefDevice->GetOutDevType() == OUTDEV_PRINTER )
1960 : : {
1961 [ + - ]: 1002 : double fMul = GetStretch();
1962 : 1002 : xub_StrLen nLen = aString.Len();
1963 [ + + ]: 3698 : for (xub_StrLen i=0; i<nLen; i++)
1964 : 2696 : pDX[i] = (long)(pDX[i] / fMul + 0.5);
1965 : : }
1966 : :
1967 [ + - ]: 1002 : mpDev->DrawTextArray( aDrawTextPos, aString, pDX );
1968 [ + - ]: 1002 : delete[] pDX;
1969 : : }
1970 : : else
1971 [ + - ]: 9658 : mpDev->DrawText( aDrawTextPos, aString );
1972 : :
1973 [ + + ][ + + ]: 10660 : if ( bHClip || bVClip )
1974 : : {
1975 [ - + ]: 75 : if (bMetaFile)
1976 [ # # ]: 0 : mpDev->Pop();
1977 : : else
1978 [ + - ]: 75 : mpDev->SetClipRegion();
1979 : : }
1980 : :
1981 : : // PDF: whole-cell hyperlink from formula?
1982 : 0 : sal_Bool bHasURL = pPDFData && pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
1983 [ - + ]: 10660 : static_cast<ScFormulaCell*>(pCell)->IsHyperLinkCell();
[ # # # # ]
[ # # ][ # # ]
1984 [ - + ]: 10660 : if ( bHasURL )
1985 : : {
1986 [ # # ]: 0 : Rectangle aURLRect( aURLStart, aVars.GetTextSize() );
1987 [ # # ]: 0 : lcl_DoHyperlinkResult( mpDev, aURLRect, pCell );
1988 [ + - ]: 10660 : }
1989 : : }
1990 : : }
1991 : 152437 : nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
1992 : : }
1993 : : }
1994 : 15867 : nPosY += pRowInfo[nArrY].nHeight;
1995 : : }
1996 [ - + ]: 1345 : if ( bProgress )
1997 [ # # ]: 0 : ScProgress::DeleteInterpretProgress();
1998 [ + - ][ + - ]: 1345 : mpDoc->DisableIdle( bWasIdleDisabled );
1999 : 1345 : }
2000 : :
2001 : : // -------------------------------------------------------------------------------
2002 : :
2003 : 405 : ScFieldEditEngine* ScOutputData::CreateOutputEditEngine()
2004 : : {
2005 [ + - ]: 405 : ScFieldEditEngine* pEngine = new ScFieldEditEngine(mpDoc, mpDoc->GetEnginePool());
2006 : 405 : pEngine->SetUpdateMode( false );
2007 : : // a RefDevice always has to be set, otherwise EditEngine would create a VirtualDevice
2008 : 405 : pEngine->SetRefDevice( pFmtDevice );
2009 : 405 : sal_uLong nCtrl = pEngine->GetControlWord();
2010 [ + + ]: 405 : if ( bShowSpellErrors )
2011 : 388 : nCtrl |= EE_CNTRL_ONLINESPELLING;
2012 [ + + ]: 405 : if ( eType == OUTTYPE_PRINTER )
2013 : 17 : nCtrl &= ~EE_CNTRL_MARKFIELDS;
2014 [ + + ][ + - ]: 405 : if ( eType == OUTTYPE_WINDOW && mpRefDevice == pFmtDevice )
2015 : 388 : nCtrl &= ~EE_CNTRL_FORMAT100; // use the actual MapMode
2016 : 405 : pEngine->SetControlWord( nCtrl );
2017 : 405 : mpDoc->ApplyAsianEditSettings( *pEngine );
2018 : 405 : pEngine->EnableAutoColor( mbUseStyleColor );
2019 : 405 : pEngine->SetDefaultHorizontalTextDirection( (EEHorizontalTextDirection)mpDoc->GetEditTextDirection( nTab ) );
2020 : 405 : return pEngine;
2021 : : }
2022 : :
2023 : 2083 : void lcl_ClearEdit( EditEngine& rEngine ) // Text und Attribute
2024 : : {
2025 : 2083 : rEngine.SetUpdateMode( false );
2026 : :
2027 : 2083 : rEngine.SetText(EMPTY_STRING);
2028 : : // keine Para-Attribute uebrigbehalten...
2029 : 2083 : const SfxItemSet& rPara = rEngine.GetParaAttribs(0);
2030 [ + + ]: 2083 : if (rPara.Count())
2031 : : rEngine.SetParaAttribs( 0,
2032 [ + - ]: 772 : SfxItemSet( *rPara.GetPool(), rPara.GetRanges() ) );
2033 : 2083 : }
2034 : :
2035 : 1033 : sal_Bool lcl_SafeIsValue( ScBaseCell* pCell )
2036 : : {
2037 [ - + ]: 1033 : if (!pCell)
2038 : 0 : return false;
2039 : :
2040 : 1033 : sal_Bool bRet = false;
2041 [ + - + ]: 1033 : switch ( pCell->GetCellType() )
2042 : : {
2043 : : case CELLTYPE_VALUE:
2044 : 456 : bRet = sal_True;
2045 : 456 : break;
2046 : : case CELLTYPE_FORMULA:
2047 : : {
2048 [ # # ]: 0 : ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
2049 [ # # ][ # # ]: 0 : if ( pFCell->IsRunning() || pFCell->IsValue() )
[ # # ]
2050 : 0 : bRet = sal_True;
2051 : : }
2052 : 0 : break;
2053 : : default:
2054 : : {
2055 : : // added to avoid warnings
2056 : : }
2057 : : }
2058 : 1033 : return bRet;
2059 : : }
2060 : :
2061 : 91 : void lcl_ScaleFonts( EditEngine& rEngine, long nPercent )
2062 : : {
2063 : 91 : sal_Bool bUpdateMode = rEngine.GetUpdateMode();
2064 [ + - ]: 91 : if ( bUpdateMode )
2065 : 91 : rEngine.SetUpdateMode( false );
2066 : :
2067 : 91 : sal_uInt16 nParCount = rEngine.GetParagraphCount();
2068 [ + + ]: 182 : for (sal_uInt16 nPar=0; nPar<nParCount; nPar++)
2069 : : {
2070 [ + - ]: 91 : std::vector<sal_uInt16> aPortions;
2071 [ + - ]: 91 : rEngine.GetPortions( nPar, aPortions );
2072 : :
2073 : 91 : sal_uInt16 nStart = 0;
2074 [ + - ][ + - ]: 182 : for ( std::vector<sal_uInt16>::const_iterator it(aPortions.begin()); it != aPortions.end(); ++it )
[ + - ][ + + ]
2075 : : {
2076 [ + - ]: 91 : sal_uInt16 nEnd = *it;
2077 : 91 : ESelection aSel( nPar, nStart, nPar, nEnd );
2078 [ + - ]: 91 : SfxItemSet aAttribs = rEngine.GetAttribs( aSel );
2079 : :
2080 [ + - ]: 91 : long nWestern = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT)).GetHeight();
2081 [ + - ]: 91 : long nCJK = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT_CJK)).GetHeight();
2082 [ + - ]: 91 : long nCTL = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT_CTL)).GetHeight();
2083 : :
2084 : 91 : nWestern = ( nWestern * nPercent ) / 100;
2085 : 91 : nCJK = ( nCJK * nPercent ) / 100;
2086 : 91 : nCTL = ( nCTL * nPercent ) / 100;
2087 : :
2088 [ + - ][ + - ]: 91 : aAttribs.Put( SvxFontHeightItem( nWestern, 100, EE_CHAR_FONTHEIGHT ) );
[ + - ]
2089 [ + - ][ + - ]: 91 : aAttribs.Put( SvxFontHeightItem( nCJK, 100, EE_CHAR_FONTHEIGHT_CJK ) );
[ + - ]
2090 [ + - ][ + - ]: 91 : aAttribs.Put( SvxFontHeightItem( nCTL, 100, EE_CHAR_FONTHEIGHT_CTL ) );
[ + - ]
2091 : :
2092 [ + - ]: 91 : rEngine.QuickSetAttribs( aAttribs, aSel ); //! remove paragraph attributes from aAttribs?
2093 : :
2094 : 91 : nStart = nEnd;
2095 [ + - ]: 91 : }
2096 : 91 : }
2097 : :
2098 [ + - ]: 91 : if ( bUpdateMode )
2099 : 91 : rEngine.SetUpdateMode( sal_True );
2100 : 91 : }
2101 : :
2102 : 182 : long lcl_GetEditSize( EditEngine& rEngine, sal_Bool bWidth, sal_Bool bSwap, long nAttrRotate )
2103 : : {
2104 [ - + ]: 182 : if ( bSwap )
2105 : 0 : bWidth = !bWidth;
2106 : :
2107 [ + - ]: 182 : if ( nAttrRotate )
2108 : : {
2109 : 182 : long nRealWidth = (long) rEngine.CalcTextWidth();
2110 : 182 : long nRealHeight = rEngine.GetTextHeight();
2111 : :
2112 : : // assuming standard mode, otherwise width isn't used
2113 : :
2114 : 182 : double nRealOrient = nAttrRotate * F_PI18000; // 1/100th degrees
2115 : 182 : double nAbsCos = fabs( cos( nRealOrient ) );
2116 : 182 : double nAbsSin = fabs( sin( nRealOrient ) );
2117 [ + + ]: 182 : if ( bWidth )
2118 : 91 : return (long) ( nRealWidth * nAbsCos + nRealHeight * nAbsSin );
2119 : : else
2120 : 91 : return (long) ( nRealHeight * nAbsCos + nRealWidth * nAbsSin );
2121 : : }
2122 [ # # ]: 0 : else if ( bWidth )
2123 : 0 : return (long) rEngine.CalcTextWidth();
2124 : : else
2125 : 182 : return rEngine.GetTextHeight();
2126 : : }
2127 : :
2128 : :
2129 : 221 : void ScOutputData::ShrinkEditEngine( EditEngine& rEngine, const Rectangle& rAlignRect,
2130 : : long nLeftM, long nTopM, long nRightM, long nBottomM,
2131 : : sal_Bool bWidth, sal_uInt16 nOrient, long nAttrRotate, sal_Bool bPixelToLogic,
2132 : : long& rEngineWidth, long& rEngineHeight, long& rNeededPixel, bool& rLeftClip, bool& rRightClip )
2133 : : {
2134 [ + + ]: 221 : if ( !bWidth )
2135 : : {
2136 : : // vertical
2137 : :
2138 : : long nScaleSize = bPixelToLogic ?
2139 [ + - ][ + - ]: 130 : mpRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
[ + - ][ + - ]
[ # # # # ]
2140 : :
2141 : : // Don't scale if it fits already.
2142 : : // Allowing to extend into the margin, to avoid scaling at optimal height.
2143 [ + - ]: 130 : if ( nScaleSize <= rAlignRect.GetHeight() )
2144 : 130 : return;
2145 : :
2146 [ # # ][ # # ]: 0 : sal_Bool bSwap = ( nOrient == SVX_ORIENTATION_TOPBOTTOM || nOrient == SVX_ORIENTATION_BOTTOMTOP );
2147 : 0 : long nAvailable = rAlignRect.GetHeight() - nTopM - nBottomM;
2148 : 0 : long nScale = ( nAvailable * 100 ) / nScaleSize;
2149 : :
2150 : 0 : lcl_ScaleFonts( rEngine, nScale );
2151 : 0 : rEngineHeight = lcl_GetEditSize( rEngine, false, bSwap, nAttrRotate );
2152 : : long nNewSize = bPixelToLogic ?
2153 [ # # ][ # # ]: 0 : mpRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
[ # # ]
[ # # # # ]
[ # # ]
2154 : :
2155 : 0 : sal_uInt16 nShrinkAgain = 0;
2156 [ # # ][ # # ]: 0 : while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
[ # # ]
2157 : : {
2158 : : // further reduce, like in DrawStrings
2159 : 0 : lcl_ScaleFonts( rEngine, 90 ); // reduce by 10%
2160 : 0 : rEngineHeight = lcl_GetEditSize( rEngine, false, bSwap, nAttrRotate );
2161 : : nNewSize = bPixelToLogic ?
2162 [ # # ][ # # ]: 0 : mpRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
[ # # ]
[ # # # # ]
[ # # ]
2163 : 0 : ++nShrinkAgain;
2164 : : }
2165 : :
2166 : : // sizes for further processing (alignment etc):
2167 : 0 : rEngineWidth = lcl_GetEditSize( rEngine, sal_True, bSwap, nAttrRotate );
2168 : : long nPixelWidth = bPixelToLogic ?
2169 [ # # ][ # # ]: 0 : mpRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
[ # # ]
[ # # # # ]
[ # # ]
2170 : 0 : rNeededPixel = nPixelWidth + nLeftM + nRightM;
2171 : : }
2172 [ - + ][ # # ]: 91 : else if ( rLeftClip || rRightClip )
2173 : : {
2174 : : // horizontal
2175 : :
2176 : 91 : long nAvailable = rAlignRect.GetWidth() - nLeftM - nRightM;
2177 : 91 : long nScaleSize = rNeededPixel - nLeftM - nRightM; // without margin
2178 : :
2179 [ - + ]: 91 : if ( nScaleSize <= nAvailable )
2180 : 0 : return;
2181 : :
2182 : 91 : long nScale = ( nAvailable * 100 ) / nScaleSize;
2183 : :
2184 : 91 : lcl_ScaleFonts( rEngine, nScale );
2185 : 91 : rEngineWidth = lcl_GetEditSize( rEngine, sal_True, false, nAttrRotate );
2186 : : long nNewSize = bPixelToLogic ?
2187 [ + - ][ + - ]: 91 : mpRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
[ + - ]
[ # # # # ]
[ + - ]
2188 : :
2189 : 91 : sal_uInt16 nShrinkAgain = 0;
2190 [ - + ][ # # ]: 91 : while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
[ - + ]
2191 : : {
2192 : : // further reduce, like in DrawStrings
2193 : 0 : lcl_ScaleFonts( rEngine, 90 ); // reduce by 10%
2194 : 0 : rEngineWidth = lcl_GetEditSize( rEngine, sal_True, false, nAttrRotate );
2195 : : nNewSize = bPixelToLogic ?
2196 [ # # ][ # # ]: 0 : mpRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
[ # # ]
[ # # # # ]
[ # # ]
2197 : 0 : ++nShrinkAgain;
2198 : : }
2199 [ + - ]: 91 : if ( nNewSize <= nAvailable )
2200 : 91 : rLeftClip = rRightClip = false;
2201 : :
2202 : : // sizes for further processing (alignment etc):
2203 : 91 : rNeededPixel = nNewSize + nLeftM + nRightM;
2204 : 221 : rEngineHeight = lcl_GetEditSize( rEngine, false, false, nAttrRotate );
2205 : : }
2206 : : }
2207 : :
2208 : 1033 : ScOutputData::DrawEditParam::DrawEditParam(const ScPatternAttr* pPattern, const SfxItemSet* pCondSet, bool bCellIsValue) :
2209 : 1033 : meHorJust( lcl_GetValue<SvxHorJustifyItem, SvxCellHorJustify>(*pPattern, ATTR_HOR_JUSTIFY, pCondSet) ),
2210 : 1033 : meVerJust( lcl_GetValue<SvxVerJustifyItem, SvxCellVerJustify>(*pPattern, ATTR_VER_JUSTIFY, pCondSet) ),
2211 : 1033 : meHorJustMethod( lcl_GetValue<SvxJustifyMethodItem, SvxCellJustifyMethod>(*pPattern, ATTR_HOR_JUSTIFY_METHOD, pCondSet) ),
2212 : 1033 : meVerJustMethod( lcl_GetValue<SvxJustifyMethodItem, SvxCellJustifyMethod>(*pPattern, ATTR_VER_JUSTIFY_METHOD, pCondSet) ),
2213 : 1033 : meOrient( pPattern->GetCellOrientation(pCondSet) ),
2214 : : mnArrY(0),
2215 : : mnX(0), mnY(0), mnCellX(0), mnCellY(0),
2216 : : mnPosX(0), mnPosY(0), mnInitPosX(0),
2217 : 655 : mbBreak( (meHorJust == SVX_HOR_JUSTIFY_BLOCK) || lcl_GetBoolValue(*pPattern, ATTR_LINEBREAK, pCondSet) ),
2218 : : mbCellIsValue(bCellIsValue),
2219 : : mbAsianVertical(false),
2220 : : mbPixelToLogic(false),
2221 : : mbHyphenatorSet(false),
2222 : : mbRTL(false),
2223 : : mpEngine(NULL),
2224 : : mpCell(NULL),
2225 : : mpPattern(pPattern),
2226 : : mpCondSet(pCondSet),
2227 : : mpOldPattern(NULL),
2228 : : mpOldCondSet(NULL),
2229 [ + + + + ]: 1688 : mpThisRowInfo(NULL)
2230 : 1033 : {}
2231 : :
2232 : 372 : bool ScOutputData::DrawEditParam::readCellContent(
2233 : : ScDocument* pDoc, bool bShowNullValues, bool bShowFormulas, bool bSyntaxMode, bool bUseStyleColor, bool bForceAutoColor, bool& rWrapFields)
2234 : : {
2235 [ - + ]: 372 : if (!mpCell)
2236 : : {
2237 : : OSL_FAIL("pCell == NULL");
2238 : 0 : return false;
2239 : : }
2240 : :
2241 [ + + ]: 372 : if (mpCell->GetCellType() == CELLTYPE_EDIT)
2242 : : {
2243 : : const EditTextObject* pData;
2244 [ + - ]: 219 : ((ScEditCell*)mpCell)->GetData(pData);
2245 : :
2246 [ + - ]: 219 : if (pData)
2247 : : {
2248 [ + - ]: 219 : mpEngine->SetText(*pData);
2249 : :
2250 [ + + ][ + - ]: 219 : if ( mbBreak && !mbAsianVertical && pData->HasField() )
[ + - ][ - + ]
[ - + ]
2251 : : {
2252 : : // Fields aren't wrapped, so clipping is enabled to prevent
2253 : : // a field from being drawn beyond the cell size
2254 : :
2255 : 0 : rWrapFields = true;
2256 : : }
2257 : : }
2258 : : else
2259 : : {
2260 : : OSL_FAIL("pData == 0");
2261 : 219 : return false;
2262 : : }
2263 : : }
2264 : : else
2265 : : {
2266 : : sal_uLong nFormat = mpPattern->GetNumberFormat(
2267 [ + - ][ + - ]: 153 : pDoc->GetFormatTable(), mpCondSet );
2268 : 153 : rtl::OUString aString;
2269 : : Color* pColor;
2270 : : ScCellFormat::GetString( mpCell,
2271 : : nFormat,aString, &pColor,
2272 [ + - ]: 153 : *pDoc->GetFormatTable(),
2273 : : bShowNullValues,
2274 : : bShowFormulas,
2275 [ + - ]: 153 : ftCheck );
2276 : :
2277 [ + - ][ + - ]: 153 : mpEngine->SetText(aString);
[ + - ]
2278 [ - + ][ # # ]: 153 : if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
[ # # ][ # # ]
2279 [ # # ]: 153 : lcl_SetEditColor( *mpEngine, *pColor );
2280 : : }
2281 : 372 : return true;
2282 : : }
2283 : :
2284 : 372 : void ScOutputData::DrawEditParam::setPatternToEngine(bool bUseStyleColor)
2285 : : {
2286 : : // syntax highlighting mode is ignored here
2287 : : // StringDiffer doesn't look at hyphenate, language items
2288 : :
2289 [ + + ][ - + ]: 372 : if (mpPattern == mpOldPattern && mpCondSet == mpOldCondSet)
2290 : 372 : return;
2291 : :
2292 [ + - ][ + - ]: 207 : sal_Int32 nConfBackColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
[ + - ]
2293 : : bool bCellContrast = bUseStyleColor &&
2294 [ + - ][ + - ]: 207 : Application::GetSettings().GetStyleSettings().GetHighContrastMode();
[ - + ]
2295 : :
2296 [ + - ][ + - ]: 207 : SfxItemSet* pSet = new SfxItemSet( mpEngine->GetEmptyItemSet() );
[ + - ]
2297 [ + - ]: 207 : mpPattern->FillEditItemSet( pSet, mpCondSet );
2298 : :
2299 [ + - ]: 207 : mpEngine->SetDefaults( pSet );
2300 : 207 : mpOldPattern = mpPattern;
2301 : 207 : mpOldCondSet = mpCondSet;
2302 : :
2303 [ + - ]: 207 : sal_uLong nControl = mpEngine->GetControlWord();
2304 [ - + ]: 207 : if (meOrient == SVX_ORIENTATION_STACKED)
2305 : 0 : nControl |= EE_CNTRL_ONECHARPERLINE;
2306 : : else
2307 : 207 : nControl &= ~EE_CNTRL_ONECHARPERLINE;
2308 [ + - ]: 207 : mpEngine->SetControlWord( nControl );
2309 : :
2310 [ + - ][ + - ]: 207 : if ( !mbHyphenatorSet && ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() )
[ + + ][ + + ]
2311 : : {
2312 : : // set hyphenator the first time it is needed
2313 [ + - ]: 30 : com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
2314 [ + - ]: 30 : mpEngine->SetHyphenator( xXHyphenator );
2315 : 30 : mbHyphenatorSet = true;
2316 : : }
2317 : :
2318 [ + - ]: 207 : Color aBackCol = ((const SvxBrushItem&)mpPattern->GetItem( ATTR_BACKGROUND, mpCondSet )).GetColor();
2319 [ + + ][ - + ]: 207 : if ( bUseStyleColor && ( aBackCol.GetTransparency() > 0 || bCellContrast ) )
[ + + ][ + - ]
2320 : 176 : aBackCol.SetColor( nConfBackColor );
2321 [ + - ]: 372 : mpEngine->SetBackgroundColor( aBackCol );
2322 : : }
2323 : :
2324 : 526 : void ScOutputData::DrawEditParam::calcMargins(long& rTopM, long& rLeftM, long& rBottomM, long& rRightM, double nPPTX, double nPPTY) const
2325 : : {
2326 : : const SvxMarginItem& rMargin =
2327 : 526 : static_cast<const SvxMarginItem&>(mpPattern->GetItem(ATTR_MARGIN, mpCondSet));
2328 : :
2329 : 526 : sal_uInt16 nIndent = 0;
2330 [ + + ]: 526 : if (meHorJust == SVX_HOR_JUSTIFY_LEFT)
2331 : 13 : nIndent = lcl_GetValue<SfxUInt16Item, sal_uInt16>(*mpPattern, ATTR_INDENT, mpCondSet);
2332 : :
2333 : 526 : rLeftM = static_cast<long>(((rMargin.GetLeftMargin() + nIndent) * nPPTX));
2334 : 526 : rTopM = static_cast<long>((rMargin.GetTopMargin() * nPPTY));
2335 : 526 : rRightM = static_cast<long>((rMargin.GetRightMargin() * nPPTX));
2336 : 526 : rBottomM = static_cast<long>((rMargin.GetBottomMargin() * nPPTY));
2337 : 526 : }
2338 : :
2339 : 154 : void ScOutputData::DrawEditParam::calcPaperSize(
2340 : : Size& rPaperSize, const Rectangle& rAlignRect, double nPPTX, double nPPTY) const
2341 : : {
2342 : : long nTopM, nLeftM, nBottomM, nRightM;
2343 [ + - ]: 154 : calcMargins(nTopM, nLeftM, nBottomM, nRightM, nPPTX, nPPTY);
2344 : :
2345 [ + - ]: 154 : if (isVerticallyOriented())
2346 : : {
2347 [ + - ]: 154 : rPaperSize.Width() = rAlignRect.GetHeight() - nTopM - nBottomM;
2348 [ + - ]: 154 : rPaperSize.Height() = rAlignRect.GetWidth() - nLeftM - nRightM;
2349 : : }
2350 : : else
2351 : : {
2352 [ # # ]: 0 : rPaperSize.Width() = rAlignRect.GetWidth() - nLeftM - nRightM;
2353 [ # # ]: 0 : rPaperSize.Height() = rAlignRect.GetHeight() - nTopM - nBottomM;
2354 : : }
2355 : :
2356 [ - + ]: 154 : if (mbAsianVertical)
2357 : : {
2358 [ # # ]: 0 : rPaperSize.Height() = rAlignRect.GetHeight() - nTopM - nBottomM;
2359 : : // Subtract some extra value from the height or else the text would go
2360 : : // outside the cell area. The value of 5 is arbitrary, and is based
2361 : : // entirely on heuristics.
2362 : 0 : rPaperSize.Height() -= 5;
2363 : : }
2364 : 154 : }
2365 : :
2366 : 372 : void ScOutputData::DrawEditParam::getEngineSize(ScFieldEditEngine* pEngine, long& rWidth, long& rHeight) const
2367 : : {
2368 : 372 : long nEngineWidth = 0;
2369 [ + + ][ + - ]: 372 : if (!mbBreak || meOrient == SVX_ORIENTATION_STACKED || mbAsianVertical)
[ - + ]
2370 : 218 : nEngineWidth = static_cast<long>(pEngine->CalcTextWidth());
2371 : :
2372 : 372 : long nEngineHeight = pEngine->GetTextHeight();
2373 : :
2374 [ + + ]: 372 : if (isVerticallyOriented())
2375 : : {
2376 : 193 : long nTemp = nEngineWidth;
2377 : 193 : nEngineWidth = nEngineHeight;
2378 : 193 : nEngineHeight = nTemp;
2379 : : }
2380 : :
2381 [ - + ]: 372 : if (meOrient == SVX_ORIENTATION_STACKED)
2382 : 0 : nEngineWidth = nEngineWidth * 11 / 10;
2383 : :
2384 : 372 : rWidth = nEngineWidth;
2385 : 372 : rHeight = nEngineHeight;
2386 : 372 : }
2387 : :
2388 : 193 : bool ScOutputData::DrawEditParam::hasLineBreak() const
2389 : : {
2390 [ + + ][ + - ]: 193 : return (mbBreak || (meOrient == SVX_ORIENTATION_STACKED) || mbAsianVertical);
[ - + ]
2391 : : }
2392 : :
2393 : 0 : bool ScOutputData::DrawEditParam::isHyperlinkCell() const
2394 : : {
2395 [ # # ]: 0 : if (!mpCell)
2396 : 0 : return false;
2397 : :
2398 [ # # ]: 0 : if (mpCell->GetCellType() != CELLTYPE_FORMULA)
2399 : 0 : return false;
2400 : :
2401 [ # # ]: 0 : return static_cast<ScFormulaCell*>(mpCell)->IsHyperLinkCell();
2402 : : }
2403 : :
2404 : 898 : bool ScOutputData::DrawEditParam::isVerticallyOriented() const
2405 : : {
2406 [ + + ][ - + ]: 898 : return (meOrient == SVX_ORIENTATION_TOPBOTTOM || meOrient == SVX_ORIENTATION_BOTTOMTOP);
2407 : : }
2408 : :
2409 : 193 : void ScOutputData::DrawEditParam::calcStartPosForVertical(
2410 : : Point& rLogicStart, long nCellWidth, long nEngineWidth, long nTopM, OutputDevice* pRefDevice)
2411 : : {
2412 : : OSL_ENSURE(isVerticallyOriented(), "Use this only for vertically oriented cell!");
2413 : :
2414 [ + - ]: 193 : if (mbPixelToLogic)
2415 : 193 : rLogicStart = pRefDevice->PixelToLogic(rLogicStart);
2416 : :
2417 [ + + ]: 193 : if (mbBreak)
2418 : : {
2419 : : // vertical adjustment is within the EditEngine
2420 [ + - ]: 154 : if (mbPixelToLogic)
2421 [ + - ]: 154 : rLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
2422 : : else
2423 : 0 : rLogicStart.Y() += nTopM;
2424 : :
2425 [ - + + ]: 154 : switch (meHorJust)
2426 : : {
2427 : : case SVX_HOR_JUSTIFY_CENTER:
2428 : 0 : rLogicStart.X() += (nCellWidth - nEngineWidth) / 2;
2429 : 0 : break;
2430 : : case SVX_HOR_JUSTIFY_RIGHT:
2431 : 28 : rLogicStart.X() += nCellWidth - nEngineWidth;
2432 : 154 : break;
2433 : : default:
2434 : : ; // do nothing
2435 : : }
2436 : : }
2437 : 193 : }
2438 : :
2439 : 372 : void ScOutputData::DrawEditParam::setAlignmentToEngine()
2440 : : {
2441 [ + + ][ - + ]: 372 : if (isVerticallyOriented() || mbAsianVertical)
[ + + ]
2442 : : {
2443 : 193 : SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
2444 [ - - + - : 193 : switch (meVerJust)
- ]
2445 : : {
2446 : : case SVX_VER_JUSTIFY_TOP:
2447 : : eSvxAdjust = (meOrient == SVX_ORIENTATION_TOPBOTTOM || mbAsianVertical) ?
2448 [ # # ][ # # ]: 0 : SVX_ADJUST_LEFT : SVX_ADJUST_RIGHT;
2449 : 0 : break;
2450 : : case SVX_VER_JUSTIFY_CENTER:
2451 : 0 : eSvxAdjust = SVX_ADJUST_CENTER;
2452 : 0 : break;
2453 : : case SVX_VER_JUSTIFY_BOTTOM:
2454 : : case SVX_VER_JUSTIFY_STANDARD:
2455 : : eSvxAdjust = (meOrient == SVX_ORIENTATION_TOPBOTTOM || mbAsianVertical) ?
2456 [ - + ][ # # ]: 193 : SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
2457 : 193 : break;
2458 : : case SVX_VER_JUSTIFY_BLOCK:
2459 : 0 : eSvxAdjust = SVX_ADJUST_BLOCK;
2460 : 0 : break;
2461 : : }
2462 : :
2463 [ + - ]: 193 : mpEngine->SetDefaultItem( SvxAdjustItem(eSvxAdjust, EE_PARA_JUST) );
2464 [ + - ]: 193 : mpEngine->SetDefaultItem( SvxJustifyMethodItem(meVerJustMethod, EE_PARA_JUST_METHOD) );
2465 : :
2466 [ + + ]: 193 : if (meHorJust == SVX_HOR_JUSTIFY_BLOCK)
2467 [ + - ]: 117 : mpEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
2468 : : }
2469 : : else
2470 : : {
2471 : : // horizontal alignment now may depend on cell content
2472 : : // (for values with number formats with mixed script types)
2473 : : // -> always set adjustment
2474 : :
2475 : 179 : SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
2476 [ - + ]: 179 : if (meOrient == SVX_ORIENTATION_STACKED)
2477 : 0 : eSvxAdjust = SVX_ADJUST_CENTER;
2478 [ - + ]: 179 : else if (mbBreak)
2479 : : {
2480 [ # # ]: 0 : if (meOrient == SVX_ORIENTATION_STANDARD)
2481 [ # # # # : 0 : switch (meHorJust)
# # ]
2482 : : {
2483 : : case SVX_HOR_JUSTIFY_STANDARD:
2484 [ # # ]: 0 : eSvxAdjust = mbCellIsValue ? SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
2485 : 0 : break;
2486 : : case SVX_HOR_JUSTIFY_LEFT:
2487 : : case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert
2488 : 0 : eSvxAdjust = SVX_ADJUST_LEFT;
2489 : 0 : break;
2490 : : case SVX_HOR_JUSTIFY_RIGHT:
2491 : 0 : eSvxAdjust = SVX_ADJUST_RIGHT;
2492 : 0 : break;
2493 : : case SVX_HOR_JUSTIFY_CENTER:
2494 : 0 : eSvxAdjust = SVX_ADJUST_CENTER;
2495 : 0 : break;
2496 : : case SVX_HOR_JUSTIFY_BLOCK:
2497 : 0 : eSvxAdjust = SVX_ADJUST_BLOCK;
2498 : 0 : break;
2499 : : }
2500 : : else
2501 [ # # # # : 0 : switch (meVerJust)
# ]
2502 : : {
2503 : : case SVX_VER_JUSTIFY_TOP:
2504 : 0 : eSvxAdjust = SVX_ADJUST_RIGHT;
2505 : 0 : break;
2506 : : case SVX_VER_JUSTIFY_CENTER:
2507 : 0 : eSvxAdjust = SVX_ADJUST_CENTER;
2508 : 0 : break;
2509 : : case SVX_VER_JUSTIFY_BOTTOM:
2510 : : case SVX_VER_JUSTIFY_STANDARD:
2511 : 0 : eSvxAdjust = SVX_ADJUST_LEFT;
2512 : 0 : break;
2513 : : case SVX_VER_JUSTIFY_BLOCK:
2514 : 0 : eSvxAdjust = SVX_ADJUST_BLOCK;
2515 : 0 : break;
2516 : : }
2517 : : }
2518 : :
2519 [ + - ]: 179 : mpEngine->SetDefaultItem( SvxAdjustItem(eSvxAdjust, EE_PARA_JUST) );
2520 : :
2521 [ - + ]: 179 : if (mbAsianVertical)
2522 : : {
2523 [ # # ]: 0 : mpEngine->SetDefaultItem( SvxJustifyMethodItem(meVerJustMethod, EE_PARA_JUST_METHOD) );
2524 [ # # ]: 0 : if (meHorJust == SVX_HOR_JUSTIFY_BLOCK)
2525 [ # # ]: 0 : mpEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
2526 : : }
2527 : : else
2528 : : {
2529 [ + - ]: 179 : mpEngine->SetDefaultItem( SvxJustifyMethodItem(meHorJustMethod, EE_PARA_JUST_METHOD) );
2530 [ - + ]: 179 : if (meVerJust == SVX_VER_JUSTIFY_BLOCK)
2531 [ # # ]: 0 : mpEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
2532 : : }
2533 : : }
2534 : :
2535 : 372 : mpEngine->SetVertical(mbAsianVertical);
2536 [ + + ][ + + ]: 372 : if (mpCell && mpCell->GetCellType() == CELLTYPE_EDIT)
[ + - ]
2537 : : {
2538 : : // We need to synchronize the vertical mode in the EditTextObject
2539 : : // instance too. No idea why we keep this state in two separate
2540 : : // instances.
2541 : 219 : ScEditCell* pEditCell = static_cast<ScEditCell*>(mpCell);
2542 : 219 : const EditTextObject* pData = pEditCell->GetData();
2543 [ + - ]: 219 : if (pData)
2544 : 219 : const_cast<EditTextObject*>(pData)->SetVertical(mbAsianVertical);
2545 : : }
2546 : 372 : }
2547 : :
2548 : 178 : bool ScOutputData::DrawEditParam::adjustHorAlignment(ScFieldEditEngine* pEngine)
2549 : : {
2550 [ + - ][ + - ]: 178 : if (meHorJust == SVX_HOR_JUSTIFY_RIGHT || meHorJust == SVX_HOR_JUSTIFY_CENTER ||
[ + + ][ - + ]
2551 : : (meHorJust == SVX_HOR_JUSTIFY_STANDARD && mbCellIsValue))
2552 : : {
2553 : : SvxAdjust eEditAdjust = (meHorJust == SVX_HOR_JUSTIFY_CENTER) ?
2554 [ # # ]: 0 : SVX_ADJUST_CENTER : SVX_ADJUST_RIGHT;
2555 : :
2556 : 0 : pEngine->SetUpdateMode(false);
2557 [ # # ]: 0 : pEngine->SetDefaultItem( SvxAdjustItem(eEditAdjust, EE_PARA_JUST) );
2558 : 0 : pEngine->SetUpdateMode(true);
2559 : 0 : return true;
2560 : : }
2561 : 178 : return false;
2562 : : }
2563 : :
2564 : 371 : void ScOutputData::DrawEditParam::adjustForRTL()
2565 : : {
2566 [ + - ][ - + ]: 371 : if (!mpEngine->IsRightToLeft(0))
2567 : : // No RTL mode.
2568 : 371 : return;
2569 : :
2570 : : // For right-to-left, EditEngine always calculates its lines
2571 : : // beginning from the right edge, but EditLine::nStartPosX is
2572 : : // of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
2573 [ # # ]: 0 : Size aLogicPaper = mpEngine->GetPaperSize();
2574 [ # # ]: 0 : if ( aLogicPaper.Width() > USHRT_MAX )
2575 : : {
2576 : 0 : aLogicPaper.Width() = USHRT_MAX;
2577 [ # # ]: 371 : mpEngine->SetPaperSize(aLogicPaper);
2578 : : }
2579 : : }
2580 : :
2581 : 371 : void ScOutputData::DrawEditParam::adjustForHyperlinkInPDF(Point aURLStart, OutputDevice* pDev)
2582 : : {
2583 : : // PDF: whole-cell hyperlink from formula?
2584 [ - + ][ # # ]: 371 : vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
[ # # ][ # # ]
2585 [ - + ][ # # ]: 371 : bool bHasURL = pPDFData && isHyperlinkCell();
2586 [ - + ]: 371 : if (!bHasURL)
2587 : 371 : return;
2588 : :
2589 [ # # ]: 0 : long nURLWidth = (long) mpEngine->CalcTextWidth();
2590 [ # # ]: 0 : long nURLHeight = mpEngine->GetTextHeight();
2591 [ # # ]: 0 : if (mbBreak)
2592 : : {
2593 [ # # ]: 0 : Size aPaper = mpEngine->GetPaperSize();
2594 [ # # ]: 0 : if ( mbAsianVertical )
2595 : 0 : nURLHeight = aPaper.Height();
2596 : : else
2597 : 0 : nURLWidth = aPaper.Width();
2598 : : }
2599 [ # # ]: 0 : if (isVerticallyOriented())
2600 : 0 : std::swap( nURLWidth, nURLHeight );
2601 [ # # ]: 0 : else if (mbAsianVertical)
2602 : 0 : aURLStart.X() -= nURLWidth;
2603 : :
2604 [ # # ]: 0 : Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
2605 [ # # ]: 371 : lcl_DoHyperlinkResult( pDev, aURLRect, mpCell );
2606 : : }
2607 : :
2608 : 840 : void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
2609 : : {
2610 : : OSL_ASSERT(rParam.meOrient == SVX_ORIENTATION_STANDARD);
2611 : : OSL_ASSERT(!rParam.mbAsianVertical);
2612 : :
2613 [ + - ]: 840 : Size aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
2614 : :
2615 : 840 : bool bHidden = false;
2616 [ - + ][ # # ]: 840 : bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
2617 [ + + ][ + - ]: 840 : bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
[ + - ][ + + ]
2618 [ + - ]: 840 : long nAttrRotate = lcl_GetValue<SfxInt32Item, long>(*rParam.mpPattern, ATTR_ROTATE_VALUE, rParam.mpCondSet);
2619 : :
2620 [ - + ]: 840 : if ( rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT )
2621 : : {
2622 : : // ignore orientation/rotation if "repeat" is active
2623 : 0 : rParam.meOrient = SVX_ORIENTATION_STANDARD;
2624 : 0 : nAttrRotate = 0;
2625 : :
2626 : : // #i31843# "repeat" with "line breaks" is treated as default alignment
2627 : : // (but rotation is still disabled)
2628 [ # # ]: 0 : if ( rParam.mbBreak )
2629 : 0 : rParam.meHorJust = SVX_HOR_JUSTIFY_STANDARD;
2630 : : }
2631 : :
2632 [ + + ]: 840 : if (nAttrRotate)
2633 : : {
2634 : : //! Flag setzen, um die Zelle in DrawRotated wiederzufinden ?
2635 : : //! (oder Flag schon bei DrawBackground, dann hier keine Abfrage)
2636 : 661 : bHidden = true; // gedreht wird getrennt ausgegeben
2637 : : }
2638 : :
2639 : 840 : SvxCellHorJustify eOutHorJust = rParam.meHorJust;
2640 [ + + ]: 840 : if (eOutHorJust == SVX_HOR_JUSTIFY_STANDARD)
2641 : : {
2642 : : // fdo#32530: Default alignment depends on value vs string, and the
2643 : : // direction of the 1st letter.
2644 [ - + ]: 166 : if (rParam.mbRTL)
2645 [ # # ]: 0 : eOutHorJust = rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_LEFT : SVX_HOR_JUSTIFY_RIGHT;
2646 : : else
2647 [ - + ]: 166 : eOutHorJust = rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT;
2648 : : }
2649 : :
2650 [ + + ][ - + ]: 840 : if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
2651 : 261 : eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
2652 : :
2653 [ + + ]: 840 : if (bHidden)
2654 : : return;
2655 : :
2656 : : //! mirror margin values for RTL?
2657 : : //! move margin down to after final GetOutputArea call
2658 : : long nTopM, nLeftM, nBottomM, nRightM;
2659 [ + - ]: 179 : rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, mnPPTX, mnPPTY);
2660 : :
2661 : 179 : SCCOL nXForPos = rParam.mnX;
2662 [ + + ]: 179 : if ( nXForPos < nX1 )
2663 : : {
2664 : 1 : nXForPos = nX1;
2665 : 1 : rParam.mnPosX = rParam.mnInitPosX;
2666 : : }
2667 : 179 : SCSIZE nArrYForPos = rParam.mnArrY;
2668 [ - + ]: 179 : if ( nArrYForPos < 1 )
2669 : : {
2670 : 0 : nArrYForPos = 1;
2671 : 0 : rParam.mnPosY = nScrY;
2672 : : }
2673 : :
2674 [ + - ]: 179 : OutputAreaParam aAreaParam;
2675 : :
2676 : : //
2677 : : // Initial page size - large for normal text, cell size for automatic line breaks
2678 : : //
2679 : :
2680 : 179 : Size aPaperSize = Size( 1000000, 1000000 );
2681 [ - + ]: 179 : if (rParam.mbBreak)
2682 : : {
2683 : : // call GetOutputArea with nNeeded=0, to get only the cell width
2684 : :
2685 : : //! handle nArrY == 0
2686 : : GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
2687 : 0 : *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
2688 [ # # ]: 0 : rParam.mbCellIsValue, true, false, aAreaParam );
2689 : :
2690 : : //! special ScEditUtil handling if formatting for printer
2691 [ # # ]: 0 : rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, mnPPTX, mnPPTY);
2692 : : }
2693 [ + + ]: 179 : if (rParam.mbPixelToLogic)
2694 : : {
2695 [ + - ]: 162 : Size aLogicSize = mpRefDevice->PixelToLogic(aPaperSize);
2696 [ - + ][ # # ]: 162 : if ( rParam.mbBreak && !rParam.mbAsianVertical && mpRefDevice != pFmtDevice )
[ # # ]
2697 : : {
2698 : : // #i85342# screen display and formatting for printer,
2699 : : // use same GetEditArea call as in ScViewData::SetEditEngine
2700 : :
2701 [ # # ]: 0 : Fraction aFract(1,1);
2702 : : Rectangle aUtilRect = ScEditUtil( mpDoc, rParam.mnCellX, rParam.mnCellY, nTab, Point(0,0), pFmtDevice,
2703 [ # # ][ # # ]: 0 : HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( rParam.mpPattern, false );
2704 [ # # ]: 0 : aLogicSize.Width() = aUtilRect.GetWidth();
2705 : : }
2706 [ + - ]: 162 : rParam.mpEngine->SetPaperSize(aLogicSize);
2707 : : }
2708 : : else
2709 [ + - ]: 17 : rParam.mpEngine->SetPaperSize(aPaperSize);
2710 : :
2711 : : //
2712 : : // Fill the EditEngine (cell attributes and text)
2713 : : //
2714 : :
2715 : : // default alignment for asian vertical mode is top-right
2716 [ - + ][ # # ]: 179 : if ( rParam.mbAsianVertical && rParam.meVerJust == SVX_VER_JUSTIFY_STANDARD )
2717 : 0 : rParam.meVerJust = SVX_VER_JUSTIFY_TOP;
2718 : :
2719 [ + - ]: 179 : rParam.setPatternToEngine(mbUseStyleColor);
2720 [ + - ]: 179 : rParam.setAlignmentToEngine();
2721 : :
2722 : : // Read content from cell
2723 : :
2724 : 179 : bool bWrapFields = false;
2725 [ + - ][ + - ]: 179 : if (!rParam.readCellContent(mpDoc, mbShowNullValues, mbShowFormulas, mbSyntaxMode, mbUseStyleColor, mbForceAutoColor, bWrapFields))
2726 : : // Failed to read cell content. Bail out.
2727 : : return;
2728 : :
2729 [ - + ]: 179 : if ( mbSyntaxMode )
2730 [ # # ]: 0 : SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
2731 [ + - ][ - + ]: 179 : else if ( mbUseStyleColor && mbForceAutoColor )
2732 [ # # ]: 0 : lcl_SetEditColor( *rParam.mpEngine, COL_AUTO ); //! or have a flag at EditEngine
2733 : :
2734 [ + - ]: 179 : rParam.mpEngine->SetUpdateMode( true ); // after SetText, before CalcTextWidth/GetTextHeight
2735 : :
2736 : : //
2737 : : // Get final output area using the calculated width
2738 : : //
2739 : :
2740 : : long nEngineWidth, nEngineHeight;
2741 [ + - ]: 179 : rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
2742 : :
2743 : 179 : long nNeededPixel = nEngineWidth;
2744 [ + + ]: 179 : if (rParam.mbPixelToLogic)
2745 [ + - ]: 162 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
2746 : 179 : nNeededPixel += nLeftM + nRightM;
2747 : :
2748 [ - + ][ # # ]: 179 : if (!rParam.mbBreak || bShrink)
2749 : : {
2750 : : // for break, the first GetOutputArea call is sufficient
2751 : : GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
2752 : 179 : *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
2753 [ + - ][ + - ]: 358 : rParam.mbCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
[ - + ][ + - ]
2754 : :
2755 [ - + ]: 179 : if ( bShrink )
2756 : : {
2757 : : ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
2758 : : nLeftM, nTopM, nRightM, nBottomM, true,
2759 : 0 : sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
2760 : : nEngineWidth, nEngineHeight, nNeededPixel,
2761 [ # # ]: 0 : aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
2762 : : }
2763 [ - + ][ # # ]: 179 : if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
[ # # ][ # # ]
[ # # ][ - + ]
2764 : : {
2765 : : // First check if twice the space for the formatted text is available
2766 : : // (otherwise just keep it unchanged).
2767 : :
2768 : 0 : long nFormatted = nNeededPixel - nLeftM - nRightM; // without margin
2769 [ # # ]: 0 : long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
2770 [ # # ]: 0 : if ( nAvailable >= 2 * nFormatted )
2771 : : {
2772 : : // "repeat" is handled with unformatted text (for performance reasons)
2773 [ # # ]: 0 : String aCellStr = rParam.mpEngine->GetText();
2774 [ # # ]: 0 : rParam.mpEngine->SetText( aCellStr );
2775 : :
2776 [ # # ]: 0 : long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
2777 [ # # ]: 0 : if (rParam.mbPixelToLogic)
2778 [ # # ]: 0 : nRepeatSize = mpRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
2779 [ # # ]: 0 : if ( pFmtDevice != mpRefDevice )
2780 : 0 : ++nRepeatSize;
2781 [ # # ]: 0 : if ( nRepeatSize > 0 )
2782 : : {
2783 : 0 : long nRepeatCount = nAvailable / nRepeatSize;
2784 [ # # ]: 0 : if ( nRepeatCount > 1 )
2785 : : {
2786 [ # # ]: 0 : String aRepeated = aCellStr;
2787 [ # # ]: 0 : for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
2788 [ # # ]: 0 : aRepeated.Append( aCellStr );
2789 [ # # ]: 0 : rParam.mpEngine->SetText( aRepeated );
2790 : :
2791 [ # # ]: 0 : nEngineHeight = rParam.mpEngine->GetTextHeight();
2792 [ # # ]: 0 : nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
2793 [ # # ]: 0 : if (rParam.mbPixelToLogic)
2794 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
2795 : : else
2796 : 0 : nNeededPixel = nEngineWidth;
2797 [ # # ]: 0 : nNeededPixel += nLeftM + nRightM;
2798 : : }
2799 [ # # ]: 0 : }
2800 : : }
2801 : : }
2802 : :
2803 [ - + ][ # # ]: 179 : if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
[ # # ]
2804 : : {
2805 [ # # ][ # # ]: 0 : rParam.mpEngine->SetText(rtl::OUString("###"));
[ # # ]
2806 [ # # ]: 0 : nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
2807 [ # # ]: 0 : if (rParam.mbPixelToLogic)
2808 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
2809 : : else
2810 : 0 : nNeededPixel = nEngineWidth;
2811 : 0 : nNeededPixel += nLeftM + nRightM;
2812 : :
2813 : : // No clip marks if "###" doesn't fit (same as in DrawStrings)
2814 : : }
2815 : :
2816 [ - + ]: 179 : if (eOutHorJust != SVX_HOR_JUSTIFY_LEFT)
2817 : : {
2818 : 0 : aPaperSize.Width() = nNeededPixel + 1;
2819 [ # # ]: 0 : if (rParam.mbPixelToLogic)
2820 [ # # ][ # # ]: 0 : rParam.mpEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
2821 : : else
2822 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aPaperSize);
2823 : : }
2824 : : }
2825 : :
2826 : 179 : long nStartX = aAreaParam.maAlignRect.Left();
2827 : 179 : long nStartY = aAreaParam.maAlignRect.Top();
2828 [ + - ]: 179 : long nCellWidth = aAreaParam.maAlignRect.GetWidth();
2829 : 179 : long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
2830 [ + - ]: 179 : long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
2831 : :
2832 [ - + ]: 179 : if (rParam.mbBreak)
2833 : : {
2834 : : // text with automatic breaks is aligned only within the
2835 : : // edit engine's paper size, the output of the whole area
2836 : : // is always left-aligned
2837 : :
2838 : 0 : nStartX += nLeftM;
2839 : : }
2840 : : else
2841 : : {
2842 [ - + ]: 179 : if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
2843 : 0 : nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
2844 [ - + ]: 179 : else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
2845 : 0 : nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
2846 : : else
2847 : 179 : nStartX += nLeftM;
2848 : : }
2849 : :
2850 [ + + ][ - + ]: 179 : bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
2851 [ + + ]: 179 : if (bOutside)
2852 : : return;
2853 : :
2854 [ - + ]: 178 : if ( aAreaParam.maClipRect.Left() < nScrX )
2855 : : {
2856 : 0 : aAreaParam.maClipRect.Left() = nScrX;
2857 : 0 : aAreaParam.mbLeftClip = true;
2858 : : }
2859 [ - + ]: 178 : if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
2860 : : {
2861 : 0 : aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one?
2862 : 0 : aAreaParam.mbRightClip = true;
2863 : : }
2864 : :
2865 [ + - ][ + + ]: 178 : bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
2866 : 178 : bool bSimClip = false;
2867 : :
2868 [ - + ]: 178 : if ( bWrapFields )
2869 : : {
2870 : : // Fields in a cell with automatic breaks: clip to cell width
2871 : 0 : bClip = true;
2872 : : }
2873 : :
2874 [ - + ]: 178 : if ( aAreaParam.maClipRect.Top() < nScrY )
2875 : : {
2876 : 0 : aAreaParam.maClipRect.Top() = nScrY;
2877 : 0 : bClip = true;
2878 : : }
2879 [ - + ]: 178 : if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
2880 : : {
2881 : 0 : aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one?
2882 : 0 : bClip = true;
2883 : : }
2884 : :
2885 : 178 : Size aCellSize; // output area, excluding margins, in logical units
2886 [ + + ]: 178 : if (rParam.mbPixelToLogic)
2887 [ + - ]: 161 : aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
2888 : : else
2889 : 17 : aCellSize = Size( nOutWidth, nOutHeight );
2890 : :
2891 [ + + ]: 178 : if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
2892 : : {
2893 : : const ScMergeAttr* pMerge =
2894 [ + - ]: 146 : (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
2895 [ + - ][ - + ]: 146 : bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
2896 : :
2897 : : // Don't clip for text height when printing rows with optimal height,
2898 : : // except when font size is from conditional formatting.
2899 : : //! Allow clipping when vertically merged?
2900 [ + + ][ + - ]: 163 : if ( eType != OUTTYPE_PRINTER ||
[ - + ][ # # ]
[ + + ]
2901 [ + - ]: 17 : ( mpDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
2902 : : ( rParam.mpCondSet && SFX_ITEM_SET ==
2903 [ # # ]: 0 : rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
2904 : 129 : bClip = true;
2905 : : else
2906 : 17 : bSimClip = true;
2907 : :
2908 : : // Show clip marks if height is at least 5pt too small and
2909 : : // there are several lines of text.
2910 : : // Not for asian vertical text, because that would interfere
2911 : : // with the default right position of the text.
2912 : : // Only with automatic line breaks, to avoid having to find
2913 : : // the cells with the horizontal end of the text again.
2914 [ - + ][ # # ]: 146 : if ( nEngineHeight - aCellSize.Height() > 100 &&
[ # # ][ # # ]
[ # # ][ - + ]
2915 : : rParam.mbBreak && bMarkClipped &&
2916 [ # # ][ # # ]: 0 : ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
2917 : : {
2918 : 0 : CellInfo* pClipMarkCell = NULL;
2919 [ # # ]: 0 : if ( bMerged )
2920 : : {
2921 : : // anywhere in the merged area...
2922 [ # # ]: 0 : SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
2923 [ # # ]: 0 : pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
2924 : : }
2925 : : else
2926 : 0 : pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
2927 : :
2928 : 0 : pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT; //! also allow left?
2929 : 0 : bAnyClipped = true;
2930 : :
2931 : 0 : long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
2932 [ # # ]: 0 : if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
2933 : 0 : aAreaParam.maClipRect.Right() -= nMarkPixel;
2934 : : }
2935 : : }
2936 : :
2937 [ + - ]: 178 : Rectangle aLogicClip;
2938 [ + + ][ + + ]: 178 : if (bClip || bSimClip)
2939 : : {
2940 : : // Clip marks are already handled in GetOutputArea
2941 : :
2942 [ + + ]: 146 : if (rParam.mbPixelToLogic)
2943 [ + - ]: 129 : aLogicClip = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
2944 : : else
2945 : 17 : aLogicClip = aAreaParam.maClipRect;
2946 : :
2947 [ + + ]: 146 : if (bClip) // bei bSimClip nur aClipRect initialisieren
2948 : : {
2949 [ - + ]: 129 : if (bMetaFile)
2950 : : {
2951 [ # # ]: 0 : mpDev->Push();
2952 [ # # ]: 0 : mpDev->IntersectClipRegion( aLogicClip );
2953 : : }
2954 : : else
2955 [ + - ][ + - ]: 129 : mpDev->SetClipRegion( Region( aLogicClip ) );
[ + - ]
2956 : : }
2957 : : }
2958 : :
2959 : 178 : Point aLogicStart;
2960 [ + + ]: 178 : if (rParam.mbPixelToLogic)
2961 [ + - ]: 161 : aLogicStart = mpRefDevice->PixelToLogic( Point(nStartX,nStartY) );
2962 : : else
2963 : 17 : aLogicStart = Point(nStartX, nStartY);
2964 : :
2965 [ + - ]: 178 : if (!rParam.mbBreak)
2966 : : {
2967 : : // horizontal alignment
2968 [ + - ][ - + ]: 178 : if (rParam.adjustHorAlignment(rParam.mpEngine))
2969 : : // reset adjustment for the next cell
2970 : 0 : rParam.mpOldPattern = NULL;
2971 : : }
2972 : :
2973 [ + - ][ + - ]: 178 : if (rParam.meVerJust==SVX_VER_JUSTIFY_BOTTOM ||
2974 : : rParam.meVerJust==SVX_VER_JUSTIFY_STANDARD)
2975 : : {
2976 : : //! if pRefDevice != pFmtDevice, keep heights in logic units,
2977 : : //! only converting margin?
2978 : :
2979 [ + + ]: 356 : if (rParam.mbPixelToLogic)
2980 : 161 : aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0, nTopM +
2981 [ + - ]: 322 : mpRefDevice->LogicToPixel(aCellSize).Height() -
2982 [ + - ]: 161 : mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
2983 [ + - ]: 161 : )).Height();
2984 : : else
2985 : 17 : aLogicStart.Y() += nTopM + aCellSize.Height() - nEngineHeight;
2986 : : }
2987 [ # # ]: 0 : else if (rParam.meVerJust==SVX_VER_JUSTIFY_CENTER)
2988 : : {
2989 [ # # ]: 0 : if (rParam.mbPixelToLogic)
2990 : 0 : aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0, nTopM + (
2991 [ # # ]: 0 : mpRefDevice->LogicToPixel(aCellSize).Height() -
2992 [ # # ]: 0 : mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height() )
2993 [ # # ]: 0 : / 2)).Height();
2994 : : else
2995 : 0 : aLogicStart.Y() += nTopM + (aCellSize.Height() - nEngineHeight) / 2;
2996 : : }
2997 : : else // top
2998 : : {
2999 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3000 [ # # ]: 0 : aLogicStart.Y() += mpRefDevice->PixelToLogic(Size(0,nTopM)).Height();
3001 : : else
3002 : 0 : aLogicStart.Y() += nTopM;
3003 : : }
3004 : :
3005 : 178 : Point aURLStart = aLogicStart; // copy before modifying for orientation
3006 : :
3007 [ + - ]: 178 : rParam.adjustForRTL();
3008 : :
3009 : : // bMoveClipped handling has been replaced by complete alignment
3010 : : // handling (also extending to the left).
3011 : :
3012 [ + + ]: 178 : if (bSimClip)
3013 : : {
3014 : : // kein hartes Clipping, aber nur die betroffenen
3015 : : // Zeilen ausgeben
3016 : :
3017 : 17 : Point aDocStart = aLogicClip.TopLeft();
3018 : 17 : aDocStart -= aLogicStart;
3019 [ + - ]: 17 : rParam.mpEngine->Draw( mpDev, aLogicClip, aDocStart, false );
3020 : : }
3021 : : else
3022 : : {
3023 [ + - ]: 161 : rParam.mpEngine->Draw(mpDev, aLogicStart, 0);
3024 : : }
3025 : :
3026 [ + + ]: 178 : if (bClip)
3027 : : {
3028 [ - + ]: 129 : if (bMetaFile)
3029 [ # # ]: 0 : mpDev->Pop();
3030 : : else
3031 [ + - ]: 129 : mpDev->SetClipRegion();
3032 : : }
3033 : :
3034 [ + - ]: 840 : rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
3035 : : }
3036 : :
3037 : 0 : void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
3038 : : {
3039 : : OSL_ASSERT(rParam.meHorJust != SVX_HOR_JUSTIFY_REPEAT);
3040 [ # # ]: 0 : Size aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
3041 : :
3042 [ # # ][ # # ]: 0 : bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
3043 [ # # ][ # # ]: 0 : bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
[ # # ][ # # ]
3044 : :
3045 : : SvxCellHorJustify eOutHorJust =
3046 : : ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
3047 [ # # ][ # # ]: 0 : ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
3048 : :
3049 [ # # ][ # # ]: 0 : if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
3050 : 0 : eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
3051 : :
3052 : : //! mirror margin values for RTL?
3053 : : //! move margin down to after final GetOutputArea call
3054 : : long nTopM, nLeftM, nBottomM, nRightM;
3055 [ # # ]: 0 : rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, mnPPTX, mnPPTY);
3056 : :
3057 : 0 : SCCOL nXForPos = rParam.mnX;
3058 [ # # ]: 0 : if ( nXForPos < nX1 )
3059 : : {
3060 : 0 : nXForPos = nX1;
3061 : 0 : rParam.mnPosX = rParam.mnInitPosX;
3062 : : }
3063 : 0 : SCSIZE nArrYForPos = rParam.mnArrY;
3064 [ # # ]: 0 : if ( nArrYForPos < 1 )
3065 : : {
3066 : 0 : nArrYForPos = 1;
3067 : 0 : rParam.mnPosY = nScrY;
3068 : : }
3069 : :
3070 [ # # ]: 0 : OutputAreaParam aAreaParam;
3071 : :
3072 : : //
3073 : : // Initial page size - large for normal text, cell size for automatic line breaks
3074 : : //
3075 : :
3076 : 0 : Size aPaperSize = Size( 1000000, 1000000 );
3077 [ # # ]: 0 : if (rParam.mbBreak)
3078 : : {
3079 : : // call GetOutputArea with nNeeded=0, to get only the cell width
3080 : :
3081 : : //! handle nArrY == 0
3082 : : GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
3083 : 0 : *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
3084 [ # # ]: 0 : rParam.mbCellIsValue, true, false, aAreaParam );
3085 : :
3086 : : //! special ScEditUtil handling if formatting for printer
3087 [ # # ]: 0 : rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, mnPPTX, mnPPTY);
3088 : : }
3089 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3090 : : {
3091 [ # # ]: 0 : Size aLogicSize = mpRefDevice->PixelToLogic(aPaperSize);
3092 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aLogicSize);
3093 : : }
3094 : : else
3095 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aPaperSize);
3096 : :
3097 : : //
3098 : : // Fill the EditEngine (cell attributes and text)
3099 : : //
3100 : :
3101 [ # # ]: 0 : rParam.setPatternToEngine(mbUseStyleColor);
3102 [ # # ]: 0 : rParam.setAlignmentToEngine();
3103 : :
3104 : : // Read content from cell
3105 : :
3106 : 0 : bool bWrapFields = false;
3107 [ # # ][ # # ]: 0 : if (!rParam.readCellContent(mpDoc, mbShowNullValues, mbShowFormulas, mbSyntaxMode, mbUseStyleColor, mbForceAutoColor, bWrapFields))
3108 : : // Failed to read cell content. Bail out.
3109 : : return;
3110 : :
3111 [ # # ]: 0 : if ( mbSyntaxMode )
3112 [ # # ]: 0 : SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
3113 [ # # ][ # # ]: 0 : else if ( mbUseStyleColor && mbForceAutoColor )
3114 [ # # ]: 0 : lcl_SetEditColor( *rParam.mpEngine, COL_AUTO ); //! or have a flag at EditEngine
3115 : :
3116 [ # # ]: 0 : rParam.mpEngine->SetUpdateMode( true ); // after SetText, before CalcTextWidth/GetTextHeight
3117 : :
3118 : : //
3119 : : // Get final output area using the calculated width
3120 : : //
3121 : :
3122 : : long nEngineWidth, nEngineHeight;
3123 [ # # ]: 0 : rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
3124 : :
3125 : 0 : long nNeededPixel = nEngineWidth;
3126 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3127 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
3128 : 0 : nNeededPixel += nLeftM + nRightM;
3129 : :
3130 [ # # ][ # # ]: 0 : if (!rParam.mbBreak || bShrink)
3131 : : {
3132 : : // for break, the first GetOutputArea call is sufficient
3133 : : GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
3134 : 0 : *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
3135 [ # # ][ # # ]: 0 : rParam.mbCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
[ # # ][ # # ]
3136 : :
3137 [ # # ]: 0 : if ( bShrink )
3138 : : {
3139 : : ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
3140 : : nLeftM, nTopM, nRightM, nBottomM, false,
3141 : 0 : sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
3142 : : nEngineWidth, nEngineHeight, nNeededPixel,
3143 [ # # ]: 0 : aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
3144 : : }
3145 [ # # ][ # # ]: 0 : if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
[ # # ][ # # ]
[ # # ][ # # ]
3146 : : {
3147 : : // First check if twice the space for the formatted text is available
3148 : : // (otherwise just keep it unchanged).
3149 : :
3150 : 0 : long nFormatted = nNeededPixel - nLeftM - nRightM; // without margin
3151 [ # # ]: 0 : long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
3152 [ # # ]: 0 : if ( nAvailable >= 2 * nFormatted )
3153 : : {
3154 : : // "repeat" is handled with unformatted text (for performance reasons)
3155 [ # # ]: 0 : String aCellStr = rParam.mpEngine->GetText();
3156 [ # # ]: 0 : rParam.mpEngine->SetText( aCellStr );
3157 : :
3158 [ # # ]: 0 : long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
3159 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3160 [ # # ]: 0 : nRepeatSize = mpRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
3161 [ # # ]: 0 : if ( pFmtDevice != mpRefDevice )
3162 : 0 : ++nRepeatSize;
3163 [ # # ]: 0 : if ( nRepeatSize > 0 )
3164 : : {
3165 : 0 : long nRepeatCount = nAvailable / nRepeatSize;
3166 [ # # ]: 0 : if ( nRepeatCount > 1 )
3167 : : {
3168 [ # # ]: 0 : String aRepeated = aCellStr;
3169 [ # # ]: 0 : for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
3170 [ # # ]: 0 : aRepeated.Append( aCellStr );
3171 [ # # ]: 0 : rParam.mpEngine->SetText( aRepeated );
3172 : :
3173 [ # # ]: 0 : nEngineHeight = rParam.mpEngine->GetTextHeight();
3174 [ # # ]: 0 : nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
3175 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3176 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
3177 : : else
3178 : 0 : nNeededPixel = nEngineWidth;
3179 [ # # ]: 0 : nNeededPixel += nLeftM + nRightM;
3180 : : }
3181 [ # # ]: 0 : }
3182 : : }
3183 : : }
3184 : :
3185 [ # # ][ # # ]: 0 : if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
[ # # ]
3186 : : {
3187 [ # # ][ # # ]: 0 : rParam.mpEngine->SetText(rtl::OUString("###"));
[ # # ]
3188 [ # # ]: 0 : nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
3189 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3190 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
3191 : : else
3192 : 0 : nNeededPixel = nEngineWidth;
3193 : 0 : nNeededPixel += nLeftM + nRightM;
3194 : :
3195 : : // No clip marks if "###" doesn't fit (same as in DrawStrings)
3196 : : }
3197 : : }
3198 : :
3199 : 0 : long nStartX = aAreaParam.maAlignRect.Left();
3200 : 0 : long nStartY = aAreaParam.maAlignRect.Top();
3201 [ # # ]: 0 : long nCellWidth = aAreaParam.maAlignRect.GetWidth();
3202 : 0 : long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
3203 [ # # ]: 0 : long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
3204 : :
3205 [ # # ]: 0 : if (rParam.mbBreak)
3206 : : {
3207 : : // text with automatic breaks is aligned only within the
3208 : : // edit engine's paper size, the output of the whole area
3209 : : // is always left-aligned
3210 : :
3211 : 0 : nStartX += nLeftM;
3212 : : }
3213 : : else
3214 : : {
3215 [ # # ]: 0 : if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
3216 : 0 : nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
3217 [ # # ]: 0 : else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
3218 : 0 : nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
3219 : : else
3220 : 0 : nStartX += nLeftM;
3221 : : }
3222 : :
3223 [ # # ][ # # ]: 0 : bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
3224 [ # # ]: 0 : if (bOutside)
3225 : : return;
3226 : :
3227 [ # # ]: 0 : if ( aAreaParam.maClipRect.Left() < nScrX )
3228 : : {
3229 : 0 : aAreaParam.maClipRect.Left() = nScrX;
3230 : 0 : aAreaParam.mbLeftClip = true;
3231 : : }
3232 [ # # ]: 0 : if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
3233 : : {
3234 : 0 : aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one?
3235 : 0 : aAreaParam.mbRightClip = true;
3236 : : }
3237 : :
3238 [ # # ][ # # ]: 0 : bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
3239 : 0 : bool bSimClip = false;
3240 : :
3241 [ # # ]: 0 : if ( bWrapFields )
3242 : : {
3243 : : // Fields in a cell with automatic breaks: clip to cell width
3244 : 0 : bClip = true;
3245 : : }
3246 : :
3247 [ # # ]: 0 : if ( aAreaParam.maClipRect.Top() < nScrY )
3248 : : {
3249 : 0 : aAreaParam.maClipRect.Top() = nScrY;
3250 : 0 : bClip = true;
3251 : : }
3252 [ # # ]: 0 : if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
3253 : : {
3254 : 0 : aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one?
3255 : 0 : bClip = true;
3256 : : }
3257 : :
3258 : 0 : Size aCellSize; // output area, excluding margins, in logical units
3259 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3260 [ # # ]: 0 : aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
3261 : : else
3262 : 0 : aCellSize = Size( nOutWidth, nOutHeight );
3263 : :
3264 [ # # ]: 0 : if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
3265 : : {
3266 : : const ScMergeAttr* pMerge =
3267 [ # # ]: 0 : (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
3268 [ # # ][ # # ]: 0 : bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
3269 : :
3270 : : // Don't clip for text height when printing rows with optimal height,
3271 : : // except when font size is from conditional formatting.
3272 : : //! Allow clipping when vertically merged?
3273 [ # # ][ # # ]: 0 : if ( eType != OUTTYPE_PRINTER ||
[ # # ][ # # ]
[ # # ]
3274 [ # # ]: 0 : ( mpDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
3275 : : ( rParam.mpCondSet && SFX_ITEM_SET ==
3276 [ # # ]: 0 : rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
3277 : 0 : bClip = true;
3278 : : else
3279 : 0 : bSimClip = true;
3280 : :
3281 : : // Show clip marks if height is at least 5pt too small and
3282 : : // there are several lines of text.
3283 : : // Not for asian vertical text, because that would interfere
3284 : : // with the default right position of the text.
3285 : : // Only with automatic line breaks, to avoid having to find
3286 : : // the cells with the horizontal end of the text again.
3287 [ # # ][ # # ]: 0 : if ( nEngineHeight - aCellSize.Height() > 100 &&
[ # # ][ # # ]
[ # # ][ # # ]
3288 : : rParam.mbBreak && bMarkClipped &&
3289 [ # # ][ # # ]: 0 : ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
3290 : : {
3291 : 0 : CellInfo* pClipMarkCell = NULL;
3292 [ # # ]: 0 : if ( bMerged )
3293 : : {
3294 : : // anywhere in the merged area...
3295 [ # # ]: 0 : SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
3296 [ # # ]: 0 : pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
3297 : : }
3298 : : else
3299 : 0 : pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
3300 : :
3301 : 0 : pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT; //! also allow left?
3302 : 0 : bAnyClipped = true;
3303 : :
3304 : 0 : long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
3305 [ # # ]: 0 : if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
3306 : 0 : aAreaParam.maClipRect.Right() -= nMarkPixel;
3307 : : }
3308 : : }
3309 : :
3310 [ # # ]: 0 : Rectangle aLogicClip;
3311 [ # # ][ # # ]: 0 : if (bClip || bSimClip)
3312 : : {
3313 : : // Clip marks are already handled in GetOutputArea
3314 : :
3315 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3316 [ # # ]: 0 : aLogicClip = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
3317 : : else
3318 : 0 : aLogicClip = aAreaParam.maClipRect;
3319 : :
3320 [ # # ]: 0 : if (bClip) // bei bSimClip nur aClipRect initialisieren
3321 : : {
3322 [ # # ]: 0 : if (bMetaFile)
3323 : : {
3324 [ # # ]: 0 : mpDev->Push();
3325 [ # # ]: 0 : mpDev->IntersectClipRegion( aLogicClip );
3326 : : }
3327 : : else
3328 [ # # ][ # # ]: 0 : mpDev->SetClipRegion( Region( aLogicClip ) );
[ # # ]
3329 : : }
3330 : : }
3331 : :
3332 : 0 : Point aLogicStart(nStartX, nStartY);
3333 [ # # ]: 0 : rParam.calcStartPosForVertical(aLogicStart, aCellSize.Width(), nEngineWidth, nTopM, mpRefDevice);
3334 : :
3335 : 0 : Point aURLStart = aLogicStart; // copy before modifying for orientation
3336 : :
3337 [ # # ][ # # ]: 0 : if (rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK || rParam.mbBreak)
3338 : : {
3339 [ # # ]: 0 : Size aPSize = rParam.mpEngine->GetPaperSize();
3340 : 0 : aPSize.Width() = aCellSize.Height();
3341 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aPSize);
3342 : 0 : aLogicStart.Y() +=
3343 [ # # ]: 0 : rParam.mbBreak ? aPSize.Width() : nEngineHeight;
3344 : : }
3345 : : else
3346 : : {
3347 : : // Note that the "paper" is rotated 90 degrees to the left, so
3348 : : // paper's width is in vertical direction. Also, the whole text
3349 : : // is on a single line, as text wrap is not in effect.
3350 : :
3351 : : // Set the paper width to be the width of the text.
3352 [ # # ]: 0 : Size aPSize = rParam.mpEngine->GetPaperSize();
3353 [ # # ]: 0 : aPSize.Width() = rParam.mpEngine->CalcTextWidth();
3354 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aPSize);
3355 : :
3356 : 0 : long nGap = 0;
3357 : 0 : long nTopOffset = 0;
3358 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3359 : : {
3360 [ # # ][ # # ]: 0 : nGap = mpRefDevice->LogicToPixel(aCellSize).Height() - mpRefDevice->LogicToPixel(aPSize).Width();
3361 [ # # ]: 0 : nGap = mpRefDevice->PixelToLogic(Size(0, nGap)).Height();
3362 [ # # ]: 0 : nTopOffset = mpRefDevice->PixelToLogic(Size(0,nTopM)).Height();
3363 : : }
3364 : : else
3365 : : {
3366 : 0 : nGap = aCellSize.Height() - aPSize.Width();
3367 : 0 : nTopOffset = nTopM;
3368 : : }
3369 : :
3370 : : // First, align text to bottom.
3371 : 0 : aLogicStart.Y() += aCellSize.Height();
3372 : 0 : aLogicStart.Y() += nTopOffset;
3373 : :
3374 [ # # # # ]: 0 : switch (rParam.meVerJust)
3375 : : {
3376 : : case SVX_VER_JUSTIFY_STANDARD:
3377 : : case SVX_VER_JUSTIFY_BOTTOM:
3378 : : // align to bottom (do nothing).
3379 : 0 : break;
3380 : : case SVX_VER_JUSTIFY_CENTER:
3381 : : // center it.
3382 : 0 : aLogicStart.Y() -= nGap / 2;
3383 : 0 : break;
3384 : : case SVX_VER_JUSTIFY_BLOCK:
3385 : : case SVX_VER_JUSTIFY_TOP:
3386 : : // align to top
3387 : 0 : aLogicStart.Y() -= nGap;
3388 : : default:
3389 : : ;
3390 : : }
3391 : : }
3392 : :
3393 [ # # ]: 0 : rParam.adjustForRTL();
3394 [ # # ]: 0 : rParam.mpEngine->Draw(mpDev, aLogicStart, 900);
3395 : :
3396 [ # # ]: 0 : if (bClip)
3397 : : {
3398 [ # # ]: 0 : if (bMetaFile)
3399 [ # # ]: 0 : mpDev->Pop();
3400 : : else
3401 [ # # ]: 0 : mpDev->SetClipRegion();
3402 : : }
3403 : :
3404 [ # # ]: 0 : rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
3405 : : }
3406 : :
3407 : 193 : void ScOutputData::DrawEditTopBottom(DrawEditParam& rParam)
3408 : : {
3409 : : OSL_ASSERT(rParam.meHorJust != SVX_HOR_JUSTIFY_REPEAT);
3410 [ + - ]: 193 : Size aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
3411 : :
3412 [ - + ][ # # ]: 193 : bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
3413 [ + + ][ + - ]: 193 : bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
[ + - ][ + - ]
3414 : :
3415 : : SvxCellHorJustify eOutHorJust =
3416 : : ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
3417 [ + + ][ - + ]: 193 : ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
3418 : :
3419 [ + + ][ - + ]: 193 : if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
3420 : 117 : eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
3421 : :
3422 : : //! mirror margin values for RTL?
3423 : : //! move margin down to after final GetOutputArea call
3424 : : long nTopM, nLeftM, nBottomM, nRightM;
3425 [ + - ]: 193 : rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, mnPPTX, mnPPTY);
3426 : :
3427 : 193 : SCCOL nXForPos = rParam.mnX;
3428 [ - + ]: 193 : if ( nXForPos < nX1 )
3429 : : {
3430 : 0 : nXForPos = nX1;
3431 : 0 : rParam.mnPosX = rParam.mnInitPosX;
3432 : : }
3433 : 193 : SCSIZE nArrYForPos = rParam.mnArrY;
3434 [ - + ]: 193 : if ( nArrYForPos < 1 )
3435 : : {
3436 : 0 : nArrYForPos = 1;
3437 : 0 : rParam.mnPosY = nScrY;
3438 : : }
3439 : :
3440 [ + - ]: 193 : OutputAreaParam aAreaParam;
3441 : :
3442 : : //
3443 : : // Initial page size - large for normal text, cell size for automatic line breaks
3444 : : //
3445 : :
3446 : 193 : Size aPaperSize = Size( 1000000, 1000000 );
3447 [ + + ]: 193 : if (rParam.hasLineBreak())
3448 : : {
3449 : : // call GetOutputArea with nNeeded=0, to get only the cell width
3450 : :
3451 : : //! handle nArrY == 0
3452 : : GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
3453 : 154 : *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
3454 [ + - ]: 154 : rParam.mbCellIsValue, true, false, aAreaParam );
3455 : :
3456 : : //! special ScEditUtil handling if formatting for printer
3457 [ + - ]: 154 : rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, mnPPTX, mnPPTY);
3458 : : }
3459 [ + - ]: 193 : if (rParam.mbPixelToLogic)
3460 : : {
3461 [ + - ]: 193 : Size aLogicSize = mpRefDevice->PixelToLogic(aPaperSize);
3462 [ + - ]: 193 : rParam.mpEngine->SetPaperSize(aLogicSize);
3463 : : }
3464 : : else
3465 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aPaperSize);
3466 : :
3467 : : //
3468 : : // Fill the EditEngine (cell attributes and text)
3469 : : //
3470 : :
3471 [ + - ]: 193 : rParam.setPatternToEngine(mbUseStyleColor);
3472 [ + - ]: 193 : rParam.setAlignmentToEngine();
3473 : :
3474 : : // Read content from cell
3475 : :
3476 : 193 : bool bWrapFields = false;
3477 [ + - ][ + - ]: 193 : if (!rParam.readCellContent(mpDoc, mbShowNullValues, mbShowFormulas, mbSyntaxMode, mbUseStyleColor, mbForceAutoColor, bWrapFields))
3478 : : // Failed to read cell content. Bail out.
3479 : : return;
3480 : :
3481 [ - + ]: 193 : if ( mbSyntaxMode )
3482 [ # # ]: 0 : SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
3483 [ + - ][ - + ]: 193 : else if ( mbUseStyleColor && mbForceAutoColor )
3484 [ # # ]: 0 : lcl_SetEditColor( *rParam.mpEngine, COL_AUTO ); //! or have a flag at EditEngine
3485 : :
3486 [ + - ]: 193 : rParam.mpEngine->SetUpdateMode( true ); // after SetText, before CalcTextWidth/GetTextHeight
3487 : :
3488 : : //
3489 : : // Get final output area using the calculated width
3490 : : //
3491 : :
3492 : : long nEngineWidth, nEngineHeight;
3493 [ + - ]: 193 : rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
3494 : :
3495 : 193 : long nNeededPixel = nEngineWidth;
3496 [ + - ]: 193 : if (rParam.mbPixelToLogic)
3497 [ + - ]: 193 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
3498 : 193 : nNeededPixel += nLeftM + nRightM;
3499 : :
3500 [ + + ][ - + ]: 193 : if (!rParam.mbBreak || bShrink)
3501 : : {
3502 : : // for break, the first GetOutputArea call is sufficient
3503 : : GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
3504 : 39 : *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
3505 [ + + ][ + - ]: 78 : rParam.mbCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
[ + - ][ + - ]
3506 : :
3507 [ + - ]: 39 : if ( bShrink )
3508 : : {
3509 : : ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
3510 : : nLeftM, nTopM, nRightM, nBottomM, false,
3511 : 39 : sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
3512 : : nEngineWidth, nEngineHeight, nNeededPixel,
3513 [ + - ]: 39 : aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
3514 : : }
3515 [ - + ][ # # ]: 39 : if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
[ # # ][ # # ]
[ # # ][ - + ]
3516 : : {
3517 : : // First check if twice the space for the formatted text is available
3518 : : // (otherwise just keep it unchanged).
3519 : :
3520 : 0 : long nFormatted = nNeededPixel - nLeftM - nRightM; // without margin
3521 [ # # ]: 0 : long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
3522 [ # # ]: 0 : if ( nAvailable >= 2 * nFormatted )
3523 : : {
3524 : : // "repeat" is handled with unformatted text (for performance reasons)
3525 [ # # ]: 0 : String aCellStr = rParam.mpEngine->GetText();
3526 [ # # ]: 0 : rParam.mpEngine->SetText( aCellStr );
3527 : :
3528 [ # # ]: 0 : long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
3529 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3530 [ # # ]: 0 : nRepeatSize = mpRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
3531 [ # # ]: 0 : if ( pFmtDevice != mpRefDevice )
3532 : 0 : ++nRepeatSize;
3533 [ # # ]: 0 : if ( nRepeatSize > 0 )
3534 : : {
3535 : 0 : long nRepeatCount = nAvailable / nRepeatSize;
3536 [ # # ]: 0 : if ( nRepeatCount > 1 )
3537 : : {
3538 [ # # ]: 0 : String aRepeated = aCellStr;
3539 [ # # ]: 0 : for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
3540 [ # # ]: 0 : aRepeated.Append( aCellStr );
3541 [ # # ]: 0 : rParam.mpEngine->SetText( aRepeated );
3542 : :
3543 [ # # ]: 0 : nEngineHeight = rParam.mpEngine->GetTextHeight();
3544 [ # # ]: 0 : nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
3545 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3546 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
3547 : : else
3548 : 0 : nNeededPixel = nEngineWidth;
3549 [ # # ]: 0 : nNeededPixel += nLeftM + nRightM;
3550 : : }
3551 [ # # ]: 0 : }
3552 : : }
3553 : : }
3554 : :
3555 [ + + ][ - + ]: 39 : if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
[ # # ]
3556 : : {
3557 [ + - ][ + - ]: 24 : rParam.mpEngine->SetText(rtl::OUString("###"));
[ + - ]
3558 [ + - ]: 24 : nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
3559 [ + - ]: 24 : if (rParam.mbPixelToLogic)
3560 [ + - ]: 24 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
3561 : : else
3562 : 0 : nNeededPixel = nEngineWidth;
3563 : 24 : nNeededPixel += nLeftM + nRightM;
3564 : :
3565 : : // No clip marks if "###" doesn't fit (same as in DrawStrings)
3566 : : }
3567 : : }
3568 : :
3569 : 193 : long nStartX = aAreaParam.maAlignRect.Left();
3570 : 193 : long nStartY = aAreaParam.maAlignRect.Top();
3571 [ + - ]: 193 : long nCellWidth = aAreaParam.maAlignRect.GetWidth();
3572 : 193 : long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
3573 [ + - ]: 193 : long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
3574 : :
3575 [ + + ]: 193 : if (rParam.mbBreak)
3576 : : {
3577 : : // text with automatic breaks is aligned only within the
3578 : : // edit engine's paper size, the output of the whole area
3579 : : // is always left-aligned
3580 : :
3581 : 154 : nStartX += nLeftM;
3582 [ + + ]: 154 : if (rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK)
3583 : 117 : nStartX += aPaperSize.Height();
3584 : : }
3585 : : else
3586 : : {
3587 [ - + ]: 39 : if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
3588 : 0 : nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
3589 [ + - ]: 39 : else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
3590 : 39 : nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
3591 : : else
3592 : 0 : nStartX += nLeftM;
3593 : : }
3594 : :
3595 [ + - ][ - + ]: 193 : bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
3596 [ + - ]: 193 : if (bOutside)
3597 : : return;
3598 : :
3599 [ - + ]: 193 : if ( aAreaParam.maClipRect.Left() < nScrX )
3600 : : {
3601 : 0 : aAreaParam.maClipRect.Left() = nScrX;
3602 : 0 : aAreaParam.mbLeftClip = true;
3603 : : }
3604 [ - + ]: 193 : if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
3605 : : {
3606 : 0 : aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one?
3607 : 0 : aAreaParam.mbRightClip = true;
3608 : : }
3609 : :
3610 [ + + ][ - + ]: 193 : bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
3611 : 193 : bool bSimClip = false;
3612 : :
3613 [ - + ]: 193 : if ( bWrapFields )
3614 : : {
3615 : : // Fields in a cell with automatic breaks: clip to cell width
3616 : 0 : bClip = true;
3617 : : }
3618 : :
3619 [ - + ]: 193 : if ( aAreaParam.maClipRect.Top() < nScrY )
3620 : : {
3621 : 0 : aAreaParam.maClipRect.Top() = nScrY;
3622 : 0 : bClip = true;
3623 : : }
3624 [ - + ]: 193 : if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
3625 : : {
3626 : 0 : aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one?
3627 : 0 : bClip = true;
3628 : : }
3629 : :
3630 : 193 : Size aCellSize; // output area, excluding margins, in logical units
3631 [ + - ]: 193 : if (rParam.mbPixelToLogic)
3632 [ + - ]: 193 : aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
3633 : : else
3634 : 0 : aCellSize = Size( nOutWidth, nOutHeight );
3635 : :
3636 [ + + ]: 193 : if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
3637 : : {
3638 : : const ScMergeAttr* pMerge =
3639 [ + - ]: 18 : (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
3640 [ + - ][ - + ]: 18 : bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
3641 : :
3642 : : // Don't clip for text height when printing rows with optimal height,
3643 : : // except when font size is from conditional formatting.
3644 : : //! Allow clipping when vertically merged?
3645 [ - + ][ # # ]: 18 : if ( eType != OUTTYPE_PRINTER ||
[ # # ][ # # ]
[ + - ]
3646 [ # # ]: 0 : ( mpDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
3647 : : ( rParam.mpCondSet && SFX_ITEM_SET ==
3648 [ # # ]: 0 : rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
3649 : 18 : bClip = true;
3650 : : else
3651 : 0 : bSimClip = true;
3652 : :
3653 : : // Show clip marks if height is at least 5pt too small and
3654 : : // there are several lines of text.
3655 : : // Not for asian vertical text, because that would interfere
3656 : : // with the default right position of the text.
3657 : : // Only with automatic line breaks, to avoid having to find
3658 : : // the cells with the horizontal end of the text again.
3659 [ - + ][ # # ]: 18 : if ( nEngineHeight - aCellSize.Height() > 100 &&
[ # # ][ # # ]
[ # # ][ - + ]
3660 : : rParam.mbBreak && bMarkClipped &&
3661 [ # # ][ # # ]: 0 : ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
3662 : : {
3663 : 0 : CellInfo* pClipMarkCell = NULL;
3664 [ # # ]: 0 : if ( bMerged )
3665 : : {
3666 : : // anywhere in the merged area...
3667 [ # # ]: 0 : SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
3668 [ # # ]: 0 : pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
3669 : : }
3670 : : else
3671 : 0 : pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
3672 : :
3673 : 0 : pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT; //! also allow left?
3674 : 0 : bAnyClipped = true;
3675 : :
3676 : 0 : long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
3677 [ # # ]: 0 : if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
3678 : 0 : aAreaParam.maClipRect.Right() -= nMarkPixel;
3679 : : }
3680 : : }
3681 : :
3682 [ + - ]: 193 : Rectangle aLogicClip;
3683 [ + + ][ - + ]: 193 : if (bClip || bSimClip)
3684 : : {
3685 : : // Clip marks are already handled in GetOutputArea
3686 : :
3687 [ + - ]: 39 : if (rParam.mbPixelToLogic)
3688 [ + - ]: 39 : aLogicClip = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
3689 : : else
3690 : 0 : aLogicClip = aAreaParam.maClipRect;
3691 : :
3692 [ + - ]: 39 : if (bClip) // bei bSimClip nur aClipRect initialisieren
3693 : : {
3694 [ - + ]: 39 : if (bMetaFile)
3695 : : {
3696 [ # # ]: 0 : mpDev->Push();
3697 [ # # ]: 0 : mpDev->IntersectClipRegion( aLogicClip );
3698 : : }
3699 : : else
3700 [ + - ][ + - ]: 39 : mpDev->SetClipRegion( Region( aLogicClip ) );
[ + - ]
3701 : : }
3702 : : }
3703 : :
3704 : 193 : Point aLogicStart(nStartX, nStartY);
3705 [ + - ]: 193 : rParam.calcStartPosForVertical(aLogicStart, aCellSize.Width(), nEngineWidth, nTopM, mpRefDevice);
3706 : :
3707 : 193 : Point aURLStart = aLogicStart; // copy before modifying for orientation
3708 : :
3709 [ + + ]: 193 : if (rParam.meHorJust != SVX_HOR_JUSTIFY_BLOCK)
3710 : : {
3711 : 76 : aLogicStart.X() += nEngineWidth;
3712 [ + + ]: 76 : if (!rParam.mbBreak)
3713 : : {
3714 : : // Set the paper width to text size.
3715 [ + - ]: 39 : Size aPSize = rParam.mpEngine->GetPaperSize();
3716 [ + - ]: 39 : aPSize.Width() = rParam.mpEngine->CalcTextWidth();
3717 [ + - ]: 39 : rParam.mpEngine->SetPaperSize(aPSize);
3718 : :
3719 : 39 : long nGap = 0;
3720 : 39 : long nTopOffset = 0; // offset by top margin
3721 [ + - ]: 39 : if (rParam.mbPixelToLogic)
3722 : : {
3723 [ + - ][ + - ]: 39 : nGap = mpRefDevice->LogicToPixel(aPSize).Width() - mpRefDevice->LogicToPixel(aCellSize).Height();
3724 [ + - ]: 39 : nGap = mpRefDevice->PixelToLogic(Size(0, nGap)).Height();
3725 [ + - ]: 39 : nTopOffset = mpRefDevice->PixelToLogic(Size(0,nTopM)).Height();
3726 : : }
3727 : : else
3728 : : {
3729 : 0 : nGap = aPSize.Width() - aCellSize.Height();
3730 : 0 : nTopOffset = nTopM;
3731 : : }
3732 : 39 : aLogicStart.Y() += nTopOffset;
3733 : :
3734 [ + - - ]: 39 : switch (rParam.meVerJust)
3735 : : {
3736 : : case SVX_VER_JUSTIFY_STANDARD:
3737 : : case SVX_VER_JUSTIFY_BOTTOM:
3738 : : // align to bottom
3739 : 39 : aLogicStart.Y() -= nGap;
3740 : 39 : break;
3741 : : case SVX_VER_JUSTIFY_CENTER:
3742 : : // center it.
3743 : 0 : aLogicStart.Y() -= nGap / 2;
3744 : 39 : break;
3745 : : case SVX_VER_JUSTIFY_BLOCK:
3746 : : case SVX_VER_JUSTIFY_TOP:
3747 : : // align to top (do nothing)
3748 : : default:
3749 : : ;
3750 : : }
3751 : : }
3752 : : }
3753 : :
3754 [ + - ]: 193 : rParam.adjustForRTL();
3755 : :
3756 : : // bMoveClipped handling has been replaced by complete alignment
3757 : : // handling (also extending to the left).
3758 : :
3759 [ + - ]: 193 : rParam.mpEngine->Draw(mpDev, aLogicStart, 2700);
3760 : :
3761 [ + + ]: 193 : if (bClip)
3762 : : {
3763 [ - + ]: 39 : if (bMetaFile)
3764 [ # # ]: 0 : mpDev->Pop();
3765 : : else
3766 [ + - ]: 39 : mpDev->SetClipRegion();
3767 : : }
3768 : :
3769 [ + - ]: 193 : rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
3770 : : }
3771 : :
3772 : 0 : void ScOutputData::DrawEditStacked(DrawEditParam& rParam)
3773 : : {
3774 : : OSL_ASSERT(rParam.meHorJust != SVX_HOR_JUSTIFY_REPEAT);
3775 [ # # ]: 0 : Size aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
3776 : :
3777 [ # # ][ # # ]: 0 : bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
3778 [ # # ][ # # ]: 0 : bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
[ # # ][ # # ]
3779 : :
3780 : : rParam.mbAsianVertical =
3781 [ # # ]: 0 : lcl_GetBoolValue(*rParam.mpPattern, ATTR_VERTICAL_ASIAN, rParam.mpCondSet);
3782 : :
3783 [ # # ]: 0 : if ( rParam.mbAsianVertical )
3784 : : {
3785 : : // in asian mode, use EditEngine::SetVertical instead of EE_CNTRL_ONECHARPERLINE
3786 : 0 : rParam.meOrient = SVX_ORIENTATION_STANDARD;
3787 [ # # ]: 0 : DrawEditAsianVertical(rParam);
3788 : : return;
3789 : : }
3790 : :
3791 : : SvxCellHorJustify eOutHorJust =
3792 : : ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
3793 [ # # ][ # # ]: 0 : ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
3794 : :
3795 [ # # ][ # # ]: 0 : if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
3796 : 0 : eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
3797 : :
3798 : : //! mirror margin values for RTL?
3799 : : //! move margin down to after final GetOutputArea call
3800 : : long nTopM, nLeftM, nBottomM, nRightM;
3801 [ # # ]: 0 : rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, mnPPTX, mnPPTY);
3802 : :
3803 : 0 : SCCOL nXForPos = rParam.mnX;
3804 [ # # ]: 0 : if ( nXForPos < nX1 )
3805 : : {
3806 : 0 : nXForPos = nX1;
3807 : 0 : rParam.mnPosX = rParam.mnInitPosX;
3808 : : }
3809 : 0 : SCSIZE nArrYForPos = rParam.mnArrY;
3810 [ # # ]: 0 : if ( nArrYForPos < 1 )
3811 : : {
3812 : 0 : nArrYForPos = 1;
3813 : 0 : rParam.mnPosY = nScrY;
3814 : : }
3815 : :
3816 [ # # ]: 0 : OutputAreaParam aAreaParam;
3817 : :
3818 : : //
3819 : : // Initial page size - large for normal text, cell size for automatic line breaks
3820 : : //
3821 : :
3822 : 0 : Size aPaperSize = Size( 1000000, 1000000 );
3823 : : // call GetOutputArea with nNeeded=0, to get only the cell width
3824 : :
3825 : : //! handle nArrY == 0
3826 : : GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
3827 : 0 : *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
3828 [ # # ]: 0 : rParam.mbCellIsValue, true, false, aAreaParam );
3829 : :
3830 : : //! special ScEditUtil handling if formatting for printer
3831 [ # # ]: 0 : rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, mnPPTX, mnPPTY);
3832 : :
3833 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3834 : : {
3835 [ # # ]: 0 : Size aLogicSize = mpRefDevice->PixelToLogic(aPaperSize);
3836 [ # # ][ # # ]: 0 : if ( rParam.mbBreak && mpRefDevice != pFmtDevice )
3837 : : {
3838 : : // #i85342# screen display and formatting for printer,
3839 : : // use same GetEditArea call as in ScViewData::SetEditEngine
3840 : :
3841 [ # # ]: 0 : Fraction aFract(1,1);
3842 : : Rectangle aUtilRect = ScEditUtil( mpDoc, rParam.mnCellX, rParam.mnCellY, nTab, Point(0,0), pFmtDevice,
3843 [ # # ][ # # ]: 0 : HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( rParam.mpPattern, false );
3844 [ # # ]: 0 : aLogicSize.Width() = aUtilRect.GetWidth();
3845 : : }
3846 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aLogicSize);
3847 : : }
3848 : : else
3849 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aPaperSize);
3850 : :
3851 : : //
3852 : : // Fill the EditEngine (cell attributes and text)
3853 : : //
3854 : :
3855 [ # # ]: 0 : rParam.setPatternToEngine(mbUseStyleColor);
3856 [ # # ]: 0 : rParam.setAlignmentToEngine();
3857 : :
3858 : : // Read content from cell
3859 : :
3860 : 0 : bool bWrapFields = false;
3861 [ # # ][ # # ]: 0 : if (!rParam.readCellContent(mpDoc, mbShowNullValues, mbShowFormulas, mbSyntaxMode, mbUseStyleColor, mbForceAutoColor, bWrapFields))
3862 : : // Failed to read cell content. Bail out.
3863 : : return;
3864 : :
3865 [ # # ]: 0 : if ( mbSyntaxMode )
3866 [ # # ]: 0 : SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
3867 [ # # ][ # # ]: 0 : else if ( mbUseStyleColor && mbForceAutoColor )
3868 [ # # ]: 0 : lcl_SetEditColor( *rParam.mpEngine, COL_AUTO ); //! or have a flag at EditEngine
3869 : :
3870 [ # # ]: 0 : rParam.mpEngine->SetUpdateMode( true ); // after SetText, before CalcTextWidth/GetTextHeight
3871 : :
3872 : : //
3873 : : // Get final output area using the calculated width
3874 : : //
3875 : :
3876 : : long nEngineWidth, nEngineHeight;
3877 [ # # ]: 0 : rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
3878 : :
3879 : 0 : long nNeededPixel = nEngineWidth;
3880 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3881 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
3882 : 0 : nNeededPixel += nLeftM + nRightM;
3883 : :
3884 [ # # ]: 0 : if (bShrink)
3885 : : {
3886 : : // for break, the first GetOutputArea call is sufficient
3887 : : GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
3888 : 0 : *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
3889 [ # # ]: 0 : true, false, false, aAreaParam );
3890 : :
3891 : : ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
3892 : : nLeftM, nTopM, nRightM, nBottomM, true,
3893 : 0 : sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
3894 : : nEngineWidth, nEngineHeight, nNeededPixel,
3895 [ # # ]: 0 : aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
3896 : :
3897 [ # # ][ # # ]: 0 : if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
[ # # ][ # # ]
[ # # ][ # # ]
3898 : : {
3899 : : // First check if twice the space for the formatted text is available
3900 : : // (otherwise just keep it unchanged).
3901 : :
3902 : 0 : long nFormatted = nNeededPixel - nLeftM - nRightM; // without margin
3903 [ # # ]: 0 : long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
3904 [ # # ]: 0 : if ( nAvailable >= 2 * nFormatted )
3905 : : {
3906 : : // "repeat" is handled with unformatted text (for performance reasons)
3907 [ # # ]: 0 : String aCellStr = rParam.mpEngine->GetText();
3908 [ # # ]: 0 : rParam.mpEngine->SetText( aCellStr );
3909 : :
3910 [ # # ]: 0 : long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
3911 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3912 [ # # ]: 0 : nRepeatSize = mpRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
3913 [ # # ]: 0 : if ( pFmtDevice != mpRefDevice )
3914 : 0 : ++nRepeatSize;
3915 [ # # ]: 0 : if ( nRepeatSize > 0 )
3916 : : {
3917 : 0 : long nRepeatCount = nAvailable / nRepeatSize;
3918 [ # # ]: 0 : if ( nRepeatCount > 1 )
3919 : : {
3920 [ # # ]: 0 : String aRepeated = aCellStr;
3921 [ # # ]: 0 : for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
3922 [ # # ]: 0 : aRepeated.Append( aCellStr );
3923 [ # # ]: 0 : rParam.mpEngine->SetText( aRepeated );
3924 : :
3925 [ # # ]: 0 : nEngineHeight = rParam.mpEngine->GetTextHeight();
3926 [ # # ]: 0 : nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
3927 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3928 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
3929 : : else
3930 : 0 : nNeededPixel = nEngineWidth;
3931 [ # # ]: 0 : nNeededPixel += nLeftM + nRightM;
3932 : : }
3933 [ # # ]: 0 : }
3934 : : }
3935 : : }
3936 : :
3937 [ # # ][ # # ]: 0 : if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
[ # # ]
3938 : : {
3939 [ # # ][ # # ]: 0 : rParam.mpEngine->SetText(rtl::OUString("###"));
[ # # ]
3940 [ # # ]: 0 : nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
3941 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3942 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
3943 : : else
3944 : 0 : nNeededPixel = nEngineWidth;
3945 : 0 : nNeededPixel += nLeftM + nRightM;
3946 : :
3947 : : // No clip marks if "###" doesn't fit (same as in DrawStrings)
3948 : : }
3949 : :
3950 [ # # ]: 0 : if ( eOutHorJust != SVX_HOR_JUSTIFY_LEFT )
3951 : : {
3952 : 0 : aPaperSize.Width() = nNeededPixel + 1;
3953 [ # # ]: 0 : if (rParam.mbPixelToLogic)
3954 [ # # ][ # # ]: 0 : rParam.mpEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
3955 : : else
3956 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aPaperSize);
3957 : : }
3958 : : }
3959 : :
3960 : 0 : long nStartX = aAreaParam.maAlignRect.Left();
3961 : 0 : long nStartY = aAreaParam.maAlignRect.Top();
3962 [ # # ]: 0 : long nCellWidth = aAreaParam.maAlignRect.GetWidth();
3963 : 0 : long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
3964 [ # # ]: 0 : long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
3965 : :
3966 [ # # ]: 0 : if (rParam.mbBreak)
3967 : : {
3968 : : // text with automatic breaks is aligned only within the
3969 : : // edit engine's paper size, the output of the whole area
3970 : : // is always left-aligned
3971 : :
3972 : 0 : nStartX += nLeftM;
3973 : : }
3974 : : else
3975 : : {
3976 [ # # ]: 0 : if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
3977 : 0 : nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
3978 [ # # ]: 0 : else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
3979 : 0 : nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
3980 : : else
3981 : 0 : nStartX += nLeftM;
3982 : : }
3983 : :
3984 [ # # ][ # # ]: 0 : bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
3985 [ # # ]: 0 : if (bOutside)
3986 : : return;
3987 : :
3988 [ # # ]: 0 : if ( aAreaParam.maClipRect.Left() < nScrX )
3989 : : {
3990 : 0 : aAreaParam.maClipRect.Left() = nScrX;
3991 : 0 : aAreaParam.mbLeftClip = true;
3992 : : }
3993 [ # # ]: 0 : if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
3994 : : {
3995 : 0 : aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one?
3996 : 0 : aAreaParam.mbRightClip = true;
3997 : : }
3998 : :
3999 [ # # ][ # # ]: 0 : bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
4000 : 0 : bool bSimClip = false;
4001 : :
4002 [ # # ]: 0 : if ( bWrapFields )
4003 : : {
4004 : : // Fields in a cell with automatic breaks: clip to cell width
4005 : 0 : bClip = true;
4006 : : }
4007 : :
4008 [ # # ]: 0 : if ( aAreaParam.maClipRect.Top() < nScrY )
4009 : : {
4010 : 0 : aAreaParam.maClipRect.Top() = nScrY;
4011 : 0 : bClip = true;
4012 : : }
4013 [ # # ]: 0 : if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
4014 : : {
4015 : 0 : aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one?
4016 : 0 : bClip = true;
4017 : : }
4018 : :
4019 : 0 : Size aCellSize; // output area, excluding margins, in logical units
4020 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4021 [ # # ]: 0 : aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
4022 : : else
4023 : 0 : aCellSize = Size( nOutWidth, nOutHeight );
4024 : :
4025 [ # # ]: 0 : if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
4026 : : {
4027 : : const ScMergeAttr* pMerge =
4028 [ # # ]: 0 : (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
4029 [ # # ][ # # ]: 0 : bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
4030 : :
4031 : : // Don't clip for text height when printing rows with optimal height,
4032 : : // except when font size is from conditional formatting.
4033 : : //! Allow clipping when vertically merged?
4034 [ # # ][ # # ]: 0 : if ( eType != OUTTYPE_PRINTER ||
[ # # ][ # # ]
[ # # ]
4035 [ # # ]: 0 : ( mpDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
4036 : : ( rParam.mpCondSet && SFX_ITEM_SET ==
4037 [ # # ]: 0 : rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
4038 : 0 : bClip = true;
4039 : : else
4040 : 0 : bSimClip = true;
4041 : :
4042 : : // Show clip marks if height is at least 5pt too small and
4043 : : // there are several lines of text.
4044 : : // Not for asian vertical text, because that would interfere
4045 : : // with the default right position of the text.
4046 : : // Only with automatic line breaks, to avoid having to find
4047 : : // the cells with the horizontal end of the text again.
4048 [ # # ][ # # ]: 0 : if ( nEngineHeight - aCellSize.Height() > 100 &&
[ # # ][ # # ]
[ # # ][ # # ]
4049 : : rParam.mbBreak && bMarkClipped &&
4050 [ # # ][ # # ]: 0 : ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
4051 : : {
4052 : 0 : CellInfo* pClipMarkCell = NULL;
4053 [ # # ]: 0 : if ( bMerged )
4054 : : {
4055 : : // anywhere in the merged area...
4056 [ # # ]: 0 : SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
4057 [ # # ]: 0 : pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
4058 : : }
4059 : : else
4060 : 0 : pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
4061 : :
4062 : 0 : pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT; //! also allow left?
4063 : 0 : bAnyClipped = true;
4064 : :
4065 : 0 : long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
4066 [ # # ]: 0 : if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
4067 : 0 : aAreaParam.maClipRect.Right() -= nMarkPixel;
4068 : : }
4069 : : }
4070 : :
4071 [ # # ]: 0 : Rectangle aLogicClip;
4072 [ # # ][ # # ]: 0 : if (bClip || bSimClip)
4073 : : {
4074 : : // Clip marks are already handled in GetOutputArea
4075 : :
4076 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4077 [ # # ]: 0 : aLogicClip = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
4078 : : else
4079 : 0 : aLogicClip = aAreaParam.maClipRect;
4080 : :
4081 [ # # ]: 0 : if (bClip) // bei bSimClip nur aClipRect initialisieren
4082 : : {
4083 [ # # ]: 0 : if (bMetaFile)
4084 : : {
4085 [ # # ]: 0 : mpDev->Push();
4086 [ # # ]: 0 : mpDev->IntersectClipRegion( aLogicClip );
4087 : : }
4088 : : else
4089 [ # # ][ # # ]: 0 : mpDev->SetClipRegion( Region( aLogicClip ) );
[ # # ]
4090 : : }
4091 : : }
4092 : :
4093 : 0 : Point aLogicStart;
4094 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4095 [ # # ]: 0 : aLogicStart = mpRefDevice->PixelToLogic( Point(nStartX,nStartY) );
4096 : : else
4097 : 0 : aLogicStart = Point(nStartX, nStartY);
4098 : :
4099 [ # # ][ # # ]: 0 : if (rParam.meVerJust==SVX_VER_JUSTIFY_BOTTOM ||
4100 : : rParam.meVerJust==SVX_VER_JUSTIFY_STANDARD)
4101 : : {
4102 : : //! if pRefDevice != pFmtDevice, keep heights in logic units,
4103 : : //! only converting margin?
4104 : :
4105 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4106 : 0 : aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0, nTopM +
4107 [ # # ]: 0 : mpRefDevice->LogicToPixel(aCellSize).Height() -
4108 [ # # ]: 0 : mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
4109 [ # # ]: 0 : )).Height();
4110 : : else
4111 : 0 : aLogicStart.Y() += nTopM + aCellSize.Height() - nEngineHeight;
4112 : : }
4113 [ # # ]: 0 : else if (rParam.meVerJust==SVX_VER_JUSTIFY_CENTER)
4114 : : {
4115 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4116 : 0 : aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0, nTopM + (
4117 [ # # ]: 0 : mpRefDevice->LogicToPixel(aCellSize).Height() -
4118 [ # # ]: 0 : mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height() )
4119 [ # # ]: 0 : / 2)).Height();
4120 : : else
4121 : 0 : aLogicStart.Y() += nTopM + (aCellSize.Height() - nEngineHeight) / 2;
4122 : : }
4123 : : else // top
4124 : : {
4125 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4126 [ # # ]: 0 : aLogicStart.Y() += mpRefDevice->PixelToLogic(Size(0,nTopM)).Height();
4127 : : else
4128 : 0 : aLogicStart.Y() += nTopM;
4129 : : }
4130 : :
4131 : 0 : Point aURLStart = aLogicStart; // copy before modifying for orientation
4132 : :
4133 [ # # ]: 0 : Size aPaperLogic = rParam.mpEngine->GetPaperSize();
4134 : 0 : aPaperLogic.Width() = nEngineWidth;
4135 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aPaperLogic);
4136 : :
4137 [ # # ]: 0 : rParam.adjustForRTL();
4138 : :
4139 : : // bMoveClipped handling has been replaced by complete alignment
4140 : : // handling (also extending to the left).
4141 : :
4142 [ # # ]: 0 : if (bSimClip)
4143 : : {
4144 : : // kein hartes Clipping, aber nur die betroffenen
4145 : : // Zeilen ausgeben
4146 : :
4147 : 0 : Point aDocStart = aLogicClip.TopLeft();
4148 : 0 : aDocStart -= aLogicStart;
4149 [ # # ]: 0 : rParam.mpEngine->Draw( mpDev, aLogicClip, aDocStart, false );
4150 : : }
4151 : : else
4152 : : {
4153 [ # # ]: 0 : rParam.mpEngine->Draw( mpDev, aLogicStart, 0 );
4154 : : }
4155 : :
4156 [ # # ]: 0 : if (bClip)
4157 : : {
4158 [ # # ]: 0 : if (bMetaFile)
4159 [ # # ]: 0 : mpDev->Pop();
4160 : : else
4161 [ # # ]: 0 : mpDev->SetClipRegion();
4162 : : }
4163 : :
4164 [ # # ]: 0 : rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
4165 : : }
4166 : :
4167 : 0 : void ScOutputData::DrawEditAsianVertical(DrawEditParam& rParam)
4168 : : {
4169 : : // When in asian vertical orientation, the orientation value is STANDARD,
4170 : : // and the asian vertical boolean is true.
4171 : : OSL_ASSERT(rParam.meOrient == SVX_ORIENTATION_STANDARD);
4172 : : OSL_ASSERT(rParam.mbAsianVertical);
4173 : : OSL_ASSERT(rParam.meHorJust != SVX_HOR_JUSTIFY_REPEAT);
4174 : :
4175 [ # # ]: 0 : Size aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
4176 : :
4177 : 0 : bool bHidden = false;
4178 : 0 : bool bRepeat = false;
4179 [ # # ][ # # ]: 0 : bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
[ # # ][ # # ]
4180 [ # # ]: 0 : long nAttrRotate = lcl_GetValue<SfxInt32Item, long>(*rParam.mpPattern, ATTR_ROTATE_VALUE, rParam.mpCondSet);
4181 : :
4182 [ # # ]: 0 : if (nAttrRotate)
4183 : : {
4184 : : //! Flag setzen, um die Zelle in DrawRotated wiederzufinden ?
4185 : : //! (oder Flag schon bei DrawBackground, dann hier keine Abfrage)
4186 : 0 : bHidden = true; // gedreht wird getrennt ausgegeben
4187 : : }
4188 : :
4189 : : // default alignment for asian vertical mode is top-right
4190 [ # # ]: 0 : if ( rParam.meHorJust == SVX_HOR_JUSTIFY_STANDARD )
4191 : 0 : rParam.meHorJust = SVX_HOR_JUSTIFY_RIGHT;
4192 : :
4193 : : SvxCellHorJustify eOutHorJust =
4194 : : ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
4195 [ # # ][ # # ]: 0 : ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
4196 : :
4197 [ # # ][ # # ]: 0 : if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
4198 : 0 : eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
4199 : :
4200 [ # # ]: 0 : if (bHidden)
4201 : : return;
4202 : :
4203 : : //! mirror margin values for RTL?
4204 : : //! move margin down to after final GetOutputArea call
4205 : : long nTopM, nLeftM, nBottomM, nRightM;
4206 [ # # ]: 0 : rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, mnPPTX, mnPPTY);
4207 : :
4208 : 0 : SCCOL nXForPos = rParam.mnX;
4209 [ # # ]: 0 : if ( nXForPos < nX1 )
4210 : : {
4211 : 0 : nXForPos = nX1;
4212 : 0 : rParam.mnPosX = rParam.mnInitPosX;
4213 : : }
4214 : 0 : SCSIZE nArrYForPos = rParam.mnArrY;
4215 [ # # ]: 0 : if ( nArrYForPos < 1 )
4216 : : {
4217 : 0 : nArrYForPos = 1;
4218 : 0 : rParam.mnPosY = nScrY;
4219 : : }
4220 : :
4221 [ # # ]: 0 : OutputAreaParam aAreaParam;
4222 : :
4223 : : //
4224 : : // Initial page size - large for normal text, cell size for automatic line breaks
4225 : : //
4226 : :
4227 : 0 : Size aPaperSize = Size( 1000000, 1000000 );
4228 : : // call GetOutputArea with nNeeded=0, to get only the cell width
4229 : :
4230 : : //! handle nArrY == 0
4231 : : GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
4232 : 0 : *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
4233 [ # # ]: 0 : rParam.mbCellIsValue, true, false, aAreaParam );
4234 : :
4235 : : //! special ScEditUtil handling if formatting for printer
4236 [ # # ]: 0 : rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, mnPPTX, mnPPTY);
4237 : :
4238 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4239 : : {
4240 [ # # ]: 0 : Size aLogicSize = mpRefDevice->PixelToLogic(aPaperSize);
4241 [ # # ][ # # ]: 0 : if ( rParam.mbBreak && !rParam.mbAsianVertical && mpRefDevice != pFmtDevice )
[ # # ]
4242 : : {
4243 : : // #i85342# screen display and formatting for printer,
4244 : : // use same GetEditArea call as in ScViewData::SetEditEngine
4245 : :
4246 [ # # ]: 0 : Fraction aFract(1,1);
4247 : : Rectangle aUtilRect = ScEditUtil( mpDoc, rParam.mnCellX, rParam.mnCellY, nTab, Point(0,0), pFmtDevice,
4248 [ # # ][ # # ]: 0 : HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( rParam.mpPattern, false );
4249 [ # # ]: 0 : aLogicSize.Width() = aUtilRect.GetWidth();
4250 : : }
4251 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aLogicSize);
4252 : : }
4253 : : else
4254 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aPaperSize);
4255 : :
4256 : : //
4257 : : // Fill the EditEngine (cell attributes and text)
4258 : : //
4259 : :
4260 : : // default alignment for asian vertical mode is top-right
4261 [ # # ]: 0 : if ( rParam.meVerJust == SVX_VER_JUSTIFY_STANDARD )
4262 : 0 : rParam.meVerJust = SVX_VER_JUSTIFY_TOP;
4263 : :
4264 [ # # ]: 0 : rParam.setPatternToEngine(mbUseStyleColor);
4265 [ # # ]: 0 : rParam.setAlignmentToEngine();
4266 : :
4267 : : // Read content from cell
4268 : :
4269 : 0 : bool bWrapFields = false;
4270 [ # # ][ # # ]: 0 : if (!rParam.readCellContent(mpDoc, mbShowNullValues, mbShowFormulas, mbSyntaxMode, mbUseStyleColor, mbForceAutoColor, bWrapFields))
4271 : : // Failed to read cell content. Bail out.
4272 : : return;
4273 : :
4274 [ # # ]: 0 : if ( mbSyntaxMode )
4275 [ # # ]: 0 : SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
4276 [ # # ][ # # ]: 0 : else if ( mbUseStyleColor && mbForceAutoColor )
4277 [ # # ]: 0 : lcl_SetEditColor( *rParam.mpEngine, COL_AUTO ); //! or have a flag at EditEngine
4278 : :
4279 [ # # ]: 0 : rParam.mpEngine->SetUpdateMode( true ); // after SetText, before CalcTextWidth/GetTextHeight
4280 : :
4281 : : //
4282 : : // Get final output area using the calculated width
4283 : : //
4284 : :
4285 : : long nEngineWidth, nEngineHeight;
4286 [ # # ]: 0 : rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
4287 : :
4288 : 0 : long nNeededPixel = nEngineWidth;
4289 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4290 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
4291 : 0 : nNeededPixel += nLeftM + nRightM;
4292 : :
4293 : : // for break, the first GetOutputArea call is sufficient
4294 : : GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
4295 : 0 : *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
4296 [ # # ][ # # ]: 0 : rParam.mbCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
[ # # ][ # # ]
4297 : :
4298 [ # # ]: 0 : if ( bShrink )
4299 : : {
4300 : : ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
4301 : : nLeftM, nTopM, nRightM, nBottomM, false,
4302 : 0 : sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
4303 : : nEngineWidth, nEngineHeight, nNeededPixel,
4304 [ # # ]: 0 : aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
4305 : : }
4306 [ # # ][ # # ]: 0 : if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
[ # # ][ # # ]
[ # # ][ # # ]
4307 : : {
4308 : : // First check if twice the space for the formatted text is available
4309 : : // (otherwise just keep it unchanged).
4310 : :
4311 : 0 : long nFormatted = nNeededPixel - nLeftM - nRightM; // without margin
4312 [ # # ]: 0 : long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
4313 [ # # ]: 0 : if ( nAvailable >= 2 * nFormatted )
4314 : : {
4315 : : // "repeat" is handled with unformatted text (for performance reasons)
4316 [ # # ]: 0 : String aCellStr = rParam.mpEngine->GetText();
4317 [ # # ]: 0 : rParam.mpEngine->SetText( aCellStr );
4318 : :
4319 [ # # ]: 0 : long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
4320 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4321 [ # # ]: 0 : nRepeatSize = mpRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
4322 [ # # ]: 0 : if ( pFmtDevice != mpRefDevice )
4323 : 0 : ++nRepeatSize;
4324 [ # # ]: 0 : if ( nRepeatSize > 0 )
4325 : : {
4326 : 0 : long nRepeatCount = nAvailable / nRepeatSize;
4327 [ # # ]: 0 : if ( nRepeatCount > 1 )
4328 : : {
4329 [ # # ]: 0 : String aRepeated = aCellStr;
4330 [ # # ]: 0 : for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
4331 [ # # ]: 0 : aRepeated.Append( aCellStr );
4332 [ # # ]: 0 : rParam.mpEngine->SetText( aRepeated );
4333 : :
4334 [ # # ]: 0 : nEngineHeight = rParam.mpEngine->GetTextHeight();
4335 [ # # ]: 0 : nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
4336 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4337 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
4338 : : else
4339 : 0 : nNeededPixel = nEngineWidth;
4340 [ # # ]: 0 : nNeededPixel += nLeftM + nRightM;
4341 : : }
4342 [ # # ]: 0 : }
4343 : : }
4344 : : }
4345 : :
4346 [ # # ][ # # ]: 0 : if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
[ # # ]
4347 : : {
4348 [ # # ][ # # ]: 0 : rParam.mpEngine->SetText(rtl::OUString("###"));
[ # # ]
4349 [ # # ]: 0 : nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
4350 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4351 [ # # ]: 0 : nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
4352 : : else
4353 : 0 : nNeededPixel = nEngineWidth;
4354 : 0 : nNeededPixel += nLeftM + nRightM;
4355 : :
4356 : : // No clip marks if "###" doesn't fit (same as in DrawStrings)
4357 : : }
4358 : :
4359 [ # # ]: 0 : if (eOutHorJust != SVX_HOR_JUSTIFY_LEFT)
4360 : : {
4361 : 0 : aPaperSize.Width() = nNeededPixel + 1;
4362 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4363 [ # # ][ # # ]: 0 : rParam.mpEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
4364 : : else
4365 [ # # ]: 0 : rParam.mpEngine->SetPaperSize(aPaperSize);
4366 : : }
4367 : :
4368 : 0 : long nStartX = aAreaParam.maAlignRect.Left();
4369 : 0 : long nStartY = aAreaParam.maAlignRect.Top();
4370 [ # # ]: 0 : long nCellWidth = aAreaParam.maAlignRect.GetWidth();
4371 : 0 : long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
4372 [ # # ]: 0 : long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
4373 : :
4374 : : // text with automatic breaks is aligned only within the
4375 : : // edit engine's paper size, the output of the whole area
4376 : : // is always left-aligned
4377 : :
4378 : 0 : nStartX += nLeftM;
4379 : :
4380 [ # # ][ # # ]: 0 : bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
4381 [ # # ]: 0 : if (bOutside)
4382 : : return;
4383 : :
4384 [ # # ]: 0 : if ( aAreaParam.maClipRect.Left() < nScrX )
4385 : : {
4386 : 0 : aAreaParam.maClipRect.Left() = nScrX;
4387 : 0 : aAreaParam.mbLeftClip = true;
4388 : : }
4389 [ # # ]: 0 : if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
4390 : : {
4391 : 0 : aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one?
4392 : 0 : aAreaParam.mbRightClip = true;
4393 : : }
4394 : :
4395 [ # # ][ # # ]: 0 : bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
4396 : 0 : bool bSimClip = false;
4397 : :
4398 [ # # ]: 0 : if ( bWrapFields )
4399 : : {
4400 : : // Fields in a cell with automatic breaks: clip to cell width
4401 : 0 : bClip = true;
4402 : : }
4403 : :
4404 [ # # ]: 0 : if ( aAreaParam.maClipRect.Top() < nScrY )
4405 : : {
4406 : 0 : aAreaParam.maClipRect.Top() = nScrY;
4407 : 0 : bClip = true;
4408 : : }
4409 [ # # ]: 0 : if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
4410 : : {
4411 : 0 : aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one?
4412 : 0 : bClip = true;
4413 : : }
4414 : :
4415 : 0 : Size aCellSize; // output area, excluding margins, in logical units
4416 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4417 [ # # ]: 0 : aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
4418 : : else
4419 : 0 : aCellSize = Size( nOutWidth, nOutHeight );
4420 : :
4421 [ # # ]: 0 : if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
4422 : : {
4423 : : const ScMergeAttr* pMerge =
4424 [ # # ]: 0 : (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
4425 [ # # ][ # # ]: 0 : bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
4426 : :
4427 : : // Don't clip for text height when printing rows with optimal height,
4428 : : // except when font size is from conditional formatting.
4429 : : //! Allow clipping when vertically merged?
4430 [ # # ][ # # ]: 0 : if ( eType != OUTTYPE_PRINTER ||
[ # # ][ # # ]
[ # # ]
4431 [ # # ]: 0 : ( mpDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
4432 : : ( rParam.mpCondSet && SFX_ITEM_SET ==
4433 [ # # ]: 0 : rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
4434 : 0 : bClip = true;
4435 : : else
4436 : 0 : bSimClip = true;
4437 : :
4438 : : // Show clip marks if height is at least 5pt too small and
4439 : : // there are several lines of text.
4440 : : // Not for asian vertical text, because that would interfere
4441 : : // with the default right position of the text.
4442 : : // Only with automatic line breaks, to avoid having to find
4443 : : // the cells with the horizontal end of the text again.
4444 [ # # ][ # # ]: 0 : if ( nEngineHeight - aCellSize.Height() > 100 &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
4445 : : ( rParam.mbBreak || rParam.meOrient == SVX_ORIENTATION_STACKED ) &&
4446 : 0 : !rParam.mbAsianVertical && bMarkClipped &&
4447 [ # # ][ # # ]: 0 : ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
4448 : : {
4449 : 0 : CellInfo* pClipMarkCell = NULL;
4450 [ # # ]: 0 : if ( bMerged )
4451 : : {
4452 : : // anywhere in the merged area...
4453 [ # # ]: 0 : SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
4454 [ # # ]: 0 : pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
4455 : : }
4456 : : else
4457 : 0 : pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
4458 : :
4459 : 0 : pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT; //! also allow left?
4460 : 0 : bAnyClipped = true;
4461 : :
4462 : 0 : long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
4463 [ # # ]: 0 : if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
4464 : 0 : aAreaParam.maClipRect.Right() -= nMarkPixel;
4465 : : }
4466 : : }
4467 : :
4468 [ # # ]: 0 : Rectangle aLogicClip;
4469 [ # # ][ # # ]: 0 : if (bClip || bSimClip)
4470 : : {
4471 : : // Clip marks are already handled in GetOutputArea
4472 : :
4473 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4474 [ # # ]: 0 : aLogicClip = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
4475 : : else
4476 : 0 : aLogicClip = aAreaParam.maClipRect;
4477 : :
4478 [ # # ]: 0 : if (bClip) // bei bSimClip nur aClipRect initialisieren
4479 : : {
4480 [ # # ]: 0 : if (bMetaFile)
4481 : : {
4482 [ # # ]: 0 : mpDev->Push();
4483 [ # # ]: 0 : mpDev->IntersectClipRegion( aLogicClip );
4484 : : }
4485 : : else
4486 [ # # ][ # # ]: 0 : mpDev->SetClipRegion( Region( aLogicClip ) );
[ # # ]
4487 : : }
4488 : : }
4489 : :
4490 : 0 : Point aLogicStart;
4491 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4492 [ # # ]: 0 : aLogicStart = mpRefDevice->PixelToLogic( Point(nStartX,nStartY) );
4493 : : else
4494 : 0 : aLogicStart = Point(nStartX, nStartY);
4495 : :
4496 : 0 : long nAvailWidth = aCellSize.Width();
4497 : : // space for AutoFilter is already handled in GetOutputArea
4498 : :
4499 : : // horizontal alignment
4500 : :
4501 [ # # ]: 0 : if (rParam.meHorJust==SVX_HOR_JUSTIFY_RIGHT)
4502 : 0 : aLogicStart.X() += nAvailWidth - nEngineWidth;
4503 [ # # ]: 0 : else if (rParam.meHorJust==SVX_HOR_JUSTIFY_CENTER)
4504 : 0 : aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
4505 : :
4506 : : // paper size is subtracted below
4507 : 0 : aLogicStart.X() += nEngineWidth;
4508 : :
4509 : : // vertical adjustment is within the EditEngine
4510 [ # # ]: 0 : if (rParam.mbPixelToLogic)
4511 [ # # ]: 0 : aLogicStart.Y() += mpRefDevice->PixelToLogic(Size(0,nTopM)).Height();
4512 : : else
4513 : 0 : aLogicStart.Y() += nTopM;
4514 : :
4515 : 0 : Point aURLStart = aLogicStart; // copy before modifying for orientation
4516 : :
4517 [ # # ]: 0 : rParam.adjustForRTL();
4518 : :
4519 : : // bMoveClipped handling has been replaced by complete alignment
4520 : : // handling (also extending to the left).
4521 : :
4522 : : // with SetVertical, the start position is top left of
4523 : : // the whole output area, not the text itself
4524 [ # # ]: 0 : aLogicStart.X() -= rParam.mpEngine->GetPaperSize().Width();
4525 : :
4526 [ # # ]: 0 : rParam.mpEngine->Draw(mpDev, aLogicStart, 0);
4527 : :
4528 [ # # ]: 0 : if (bClip)
4529 : : {
4530 [ # # ]: 0 : if (bMetaFile)
4531 [ # # ]: 0 : mpDev->Pop();
4532 : : else
4533 [ # # ]: 0 : mpDev->SetClipRegion();
4534 : : }
4535 : :
4536 [ # # ]: 0 : rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
4537 : : }
4538 : :
4539 : 1345 : void ScOutputData::DrawEdit(sal_Bool bPixelToLogic)
4540 : : {
4541 : 1345 : ScFieldEditEngine* pEngine = NULL;
4542 : 1345 : bool bHyphenatorSet = false;
4543 : 1345 : const ScPatternAttr* pOldPattern = NULL;
4544 : 1345 : const SfxItemSet* pOldCondSet = NULL;
4545 : 1345 : ScBaseCell* pCell = NULL;
4546 : :
4547 : 1345 : long nInitPosX = nScrX;
4548 [ + + ]: 1345 : if ( bLayoutRTL )
4549 : : {
4550 : 2 : nInitPosX += nMirrorW - 1;
4551 : : }
4552 [ + + ]: 1345 : long nLayoutSign = bLayoutRTL ? -1 : 1;
4553 : :
4554 : : //! store nLastContentCol as member!
4555 : 1345 : SCCOL nLastContentCol = MAXCOL;
4556 [ + - ]: 1345 : if ( nX2 < MAXCOL )
4557 : : nLastContentCol = sal::static_int_cast<SCCOL>(
4558 [ + - ]: 1345 : nLastContentCol - mpDoc->GetEmptyLinesInBlock( nX2+1, nY1, nTab, MAXCOL, nY2, nTab, DIR_RIGHT ) );
4559 : :
4560 : 1345 : long nRowPosY = nScrY;
4561 [ + + ]: 18557 : for (SCSIZE nArrY=0; nArrY+1<nArrCount; nArrY++) // 0 fuer Reste von zusammengefassten
4562 : : {
4563 : 17212 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
4564 : :
4565 [ + + ]: 17212 : if (nArrY==1) nRowPosY = nScrY; // vorher wird einzeln berechnet
4566 : :
4567 [ - + ][ # # ]: 17212 : if ( pThisRowInfo->bChanged || nArrY==0 )
4568 : : {
4569 : 17212 : long nPosX = 0;
4570 [ + + ]: 185084 : for (SCCOL nX=0; nX<=nX2; nX++) // wegen Ueberhaengen
4571 : : {
4572 [ + + ]: 167872 : if (nX==nX1) nPosX = nInitPosX; // positions before nX1 are calculated individually
4573 : :
4574 : 167872 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
4575 [ + + ]: 167872 : if (pInfo->bEditEngine)
4576 : : {
4577 : 1033 : SCROW nY = pThisRowInfo->nRowNo;
4578 : :
4579 : 1033 : SCCOL nCellX = nX; // position where the cell really starts
4580 : 1033 : SCROW nCellY = nY;
4581 : 1033 : sal_Bool bDoCell = false;
4582 : :
4583 : 1033 : long nPosY = nRowPosY;
4584 [ - + ]: 1033 : if ( nArrY == 0 )
4585 : : {
4586 : 0 : nPosY = nScrY;
4587 : 0 : nY = pRowInfo[1].nRowNo;
4588 : : SCCOL nOverX; // start of the merged cells
4589 : : SCROW nOverY;
4590 [ # # ][ # # ]: 0 : if (GetMergeOrigin( nX,nY, 1, nOverX,nOverY, sal_True ))
4591 : : {
4592 : 0 : nCellX = nOverX;
4593 : 0 : nCellY = nOverY;
4594 : 0 : bDoCell = sal_True;
4595 : : }
4596 : : }
4597 [ + + ][ - + ]: 1033 : else if ( nX == nX2 && !pThisRowInfo->pCellInfo[nX+1].pCell )
4598 : : {
4599 : : // Rest of a long text further to the right?
4600 : :
4601 : 0 : SCCOL nTempX=nX;
4602 [ # # ][ # # ]: 0 : while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
[ # # ][ # # ]
4603 : 0 : ++nTempX;
4604 : :
4605 [ # # ][ # # ]: 0 : if ( nTempX > nX &&
[ # # ][ # # ]
4606 [ # # ]: 0 : !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
4607 [ # # ]: 0 : !mpDoc->HasAttrib( nTempX,nY,nTab, nX,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
4608 : : {
4609 : 0 : nCellX = nTempX;
4610 : 0 : bDoCell = sal_True;
4611 : 0 : }
4612 : : }
4613 : : else
4614 : : {
4615 : 1033 : bDoCell = sal_True;
4616 : : }
4617 : :
4618 [ + - ][ - + ]: 1033 : if ( bDoCell && bEditMode && nCellX == nEditCol && nCellY == nEditRow )
[ # # ][ # # ]
4619 : 0 : bDoCell = false;
4620 : :
4621 : 1033 : const ScPatternAttr* pPattern = NULL;
4622 : 1033 : const SfxItemSet* pCondSet = NULL;
4623 [ + - ]: 1033 : if (bDoCell)
4624 : : {
4625 [ + - ][ + + ]: 2065 : if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 &&
[ + - ][ + - ]
[ + + ]
4626 [ + - ]: 1032 : !mpDoc->ColHidden(nCellX, nTab) )
4627 : : {
4628 : 1032 : CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1];
4629 : 1032 : pPattern = rCellInfo.pPatternAttr;
4630 : 1032 : pCondSet = rCellInfo.pConditionSet;
4631 : 1032 : pCell = rCellInfo.pCell;
4632 : : }
4633 : : else // get from document
4634 : : {
4635 [ + - ]: 1 : pPattern = mpDoc->GetPattern( nCellX, nCellY, nTab );
4636 [ + - ]: 1 : pCondSet = mpDoc->GetCondResult( nCellX, nCellY, nTab );
4637 [ + - ]: 1 : GetVisibleCell( nCellX, nCellY, nTab, pCell );
4638 : : }
4639 [ - + ]: 1033 : if ( !pCell )
4640 : 0 : bDoCell = false;
4641 : : }
4642 [ + - ]: 1033 : if (bDoCell)
4643 : : {
4644 [ + + ]: 1033 : if (!pEngine)
4645 [ + - ]: 306 : pEngine = CreateOutputEditEngine();
4646 : : else
4647 [ + - ]: 727 : lcl_ClearEdit( *pEngine ); // also calls SetUpdateMode(sal_False)
4648 : :
4649 : : // fdo#32530: Check if the first character is RTL.
4650 [ + - ]: 1033 : rtl::OUString aStr = mpDoc->GetString(nCellX, nCellY, nTab);
4651 : :
4652 [ + - ][ + - ]: 1033 : DrawEditParam aParam(pPattern, pCondSet, lcl_SafeIsValue(pCell));
4653 : 1033 : aParam.mbPixelToLogic = bPixelToLogic;
4654 : 1033 : aParam.mbHyphenatorSet = bHyphenatorSet;
4655 [ + - ]: 1033 : aParam.mbRTL = beginsWithRTLCharacter(aStr);
4656 : 1033 : aParam.mpEngine = pEngine;
4657 : 1033 : aParam.mpCell = pCell;
4658 : 1033 : aParam.mnArrY = nArrY;
4659 : 1033 : aParam.mnX = nX;
4660 : 1033 : aParam.mnY = nY;
4661 : 1033 : aParam.mnCellX = nCellX;
4662 : 1033 : aParam.mnCellY = nCellY;
4663 : 1033 : aParam.mnPosX = nPosX;
4664 : 1033 : aParam.mnPosY = nPosY;
4665 : 1033 : aParam.mnInitPosX = nInitPosX;
4666 : 1033 : aParam.mpOldPattern = pOldPattern;
4667 : 1033 : aParam.mpOldCondSet = pOldCondSet;
4668 : 1033 : aParam.mpThisRowInfo = pThisRowInfo;
4669 [ - + ]: 1033 : if (aParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT)
4670 : : {
4671 : : // ignore orientation/rotation if "repeat" is active
4672 : 0 : aParam.meOrient = SVX_ORIENTATION_STANDARD;
4673 : : }
4674 [ - + - + ]: 1033 : switch (aParam.meOrient)
4675 : : {
4676 : : case SVX_ORIENTATION_BOTTOMTOP:
4677 [ # # ]: 0 : DrawEditBottomTop(aParam);
4678 : 0 : break;
4679 : : case SVX_ORIENTATION_TOPBOTTOM:
4680 [ + - ]: 193 : DrawEditTopBottom(aParam);
4681 : 193 : break;
4682 : : case SVX_ORIENTATION_STACKED:
4683 : : // this can be vertically stacked or asian vertical.
4684 [ # # ]: 0 : DrawEditStacked(aParam);
4685 : 0 : break;
4686 : : default:
4687 [ + - ]: 840 : DrawEditStandard(aParam);
4688 : : }
4689 : :
4690 : : // Retrieve parameters for next iteration.
4691 : 1033 : pOldPattern = aParam.mpOldPattern;
4692 : 1033 : pOldCondSet = aParam.mpOldCondSet;
4693 : 1033 : bHyphenatorSet = aParam.mbHyphenatorSet;
4694 : : }
4695 : : }
4696 : 167872 : nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
4697 : : }
4698 : : }
4699 : 17212 : nRowPosY += pRowInfo[nArrY].nHeight;
4700 : : }
4701 : :
4702 [ + + ][ + - ]: 1345 : delete pEngine;
4703 : :
4704 [ + + ]: 1345 : if (bAnyRotated)
4705 [ + - ]: 99 : DrawRotated(bPixelToLogic); //! von aussen rufen ?
4706 : 1345 : }
4707 : :
4708 : : // -------------------------------------------------------------------------------
4709 : :
4710 : 99 : void ScOutputData::DrawRotated(sal_Bool bPixelToLogic)
4711 : : {
4712 : : //! nRotMax speichern
4713 : 99 : SCCOL nRotMax = nX2;
4714 [ + + ]: 736 : for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
4715 [ + + ][ - + ]: 637 : if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
4716 : 0 : nRotMax = pRowInfo[nRotY].nRotMaxCol;
4717 : :
4718 : :
4719 [ + - ]: 99 : ScModule* pScMod = SC_MOD();
4720 [ + - ][ + - ]: 99 : sal_Int32 nConfBackColor = pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
4721 : : sal_Bool bCellContrast = mbUseStyleColor &&
4722 [ + - ][ + - ]: 99 : Application::GetSettings().GetStyleSettings().GetHighContrastMode();
[ - + ]
4723 : :
4724 : 99 : ScFieldEditEngine* pEngine = NULL;
4725 : 99 : sal_Bool bHyphenatorSet = false;
4726 : : const ScPatternAttr* pPattern;
4727 : : const SfxItemSet* pCondSet;
4728 : 99 : const ScPatternAttr* pOldPattern = NULL;
4729 : 99 : const SfxItemSet* pOldCondSet = NULL;
4730 : 99 : ScBaseCell* pCell = NULL;
4731 : :
4732 : 99 : long nInitPosX = nScrX;
4733 [ - + ]: 99 : if ( bLayoutRTL )
4734 : : {
4735 : 0 : nInitPosX += nMirrorW - 1;
4736 : : }
4737 [ - + ]: 99 : long nLayoutSign = bLayoutRTL ? -1 : 1;
4738 : :
4739 : 99 : long nRowPosY = nScrY;
4740 [ + + ]: 637 : for (SCSIZE nArrY=0; nArrY+1<nArrCount; nArrY++) // 0 fuer Reste von zusammengefassten
4741 : : {
4742 : 538 : RowInfo* pThisRowInfo = &pRowInfo[nArrY];
4743 : 538 : long nCellHeight = (long) pThisRowInfo->nHeight;
4744 [ + + ]: 538 : if (nArrY==1) nRowPosY = nScrY; // vorher wird einzeln berechnet
4745 : :
4746 [ - + ][ # # ]: 538 : if ( ( pThisRowInfo->bChanged || nArrY==0 ) && pThisRowInfo->nRotMaxCol != SC_ROTMAX_NONE )
[ + + ]
4747 : : {
4748 : 366 : long nPosX = 0;
4749 [ + + ]: 4026 : for (SCCOL nX=0; nX<=nRotMax; nX++)
4750 : : {
4751 [ + + ]: 3660 : if (nX==nX1) nPosX = nInitPosX; // positions before nX1 are calculated individually
4752 : :
4753 : 3660 : CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
4754 [ + + ]: 3660 : if ( pInfo->nRotateDir != SC_ROTDIR_NONE )
4755 : : {
4756 : 1455 : SCROW nY = pThisRowInfo->nRowNo;
4757 : :
4758 : 1455 : sal_Bool bHidden = false;
4759 [ - + ]: 1455 : if (bEditMode)
4760 [ # # ][ # # ]: 0 : if ( nX == nEditCol && nY == nEditRow )
4761 : 0 : bHidden = sal_True;
4762 : :
4763 [ + - ]: 1455 : if (!bHidden)
4764 : : {
4765 [ + + ]: 1455 : if (!pEngine)
4766 [ + - ]: 99 : pEngine = CreateOutputEditEngine();
4767 : : else
4768 [ + - ]: 1356 : lcl_ClearEdit( *pEngine ); // also calls SetUpdateMode(sal_False)
4769 : :
4770 : 1455 : long nPosY = nRowPosY;
4771 : 1455 : sal_Bool bVisChanged = false;
4772 : :
4773 : : //! Rest von zusammengefasster Zelle weiter oben funktioniert nicht!
4774 : :
4775 : 1455 : sal_Bool bFromDoc = false;
4776 : 1455 : pPattern = pInfo->pPatternAttr;
4777 : 1455 : pCondSet = pInfo->pConditionSet;
4778 [ - + ]: 1455 : if (!pPattern)
4779 : : {
4780 [ # # ]: 0 : pPattern = mpDoc->GetPattern( nX, nY, nTab );
4781 : 0 : bFromDoc = sal_True;
4782 : : }
4783 : 1455 : pCell = pInfo->pCell;
4784 [ - + ]: 1455 : if (bFromDoc)
4785 [ # # ]: 0 : pCondSet = mpDoc->GetCondResult( nX, nY, nTab );
4786 : :
4787 [ + + ][ - + ]: 1455 : if (!pCell && nX>nX2)
4788 [ # # ]: 0 : GetVisibleCell( nX, nY, nTab, pCell );
4789 : :
4790 [ + + ][ + - ]: 1455 : if ( !pCell || IsEmptyCellText( pThisRowInfo, nX, nY ) )
[ - + ][ + + ]
4791 : 794 : bHidden = sal_True; // nRotateDir is also set without a cell
4792 : :
4793 : 1455 : long nCellWidth = (long) pRowInfo[0].pCellInfo[nX+1].nWidth;
4794 : :
4795 : : SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
4796 [ + - ]: 1455 : pPattern->GetItem(ATTR_HOR_JUSTIFY, pCondSet)).GetValue();
4797 : : sal_Bool bBreak = ( eHorJust == SVX_HOR_JUSTIFY_BLOCK ) ||
4798 [ + - ][ + + ]: 1455 : ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue();
[ + + ]
4799 [ - + ][ # # ]: 1455 : sal_Bool bRepeat = ( eHorJust == SVX_HOR_JUSTIFY_REPEAT && !bBreak );
4800 : : sal_Bool bShrink = !bBreak && !bRepeat && static_cast<const SfxBoolItem&>
4801 [ + + ][ + - ]: 1455 : (pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
[ + - ][ + - ]
4802 [ + - ]: 1455 : SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
4803 : :
4804 : : const ScMergeAttr* pMerge =
4805 [ + - ]: 1455 : (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
4806 [ + - ][ - + ]: 1455 : sal_Bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
4807 : :
4808 : 1455 : long nStartX = nPosX;
4809 : 1455 : long nStartY = nPosY;
4810 [ - + ]: 1455 : if (nX<nX1)
4811 : : {
4812 [ # # ][ # # ]: 0 : if ((bBreak || eOrient!=SVX_ORIENTATION_STANDARD) && !bMerged)
[ # # ]
4813 : 0 : bHidden = sal_True;
4814 : : else
4815 : : {
4816 : 0 : nStartX = nInitPosX;
4817 : 0 : SCCOL nCol = nX1;
4818 [ # # ]: 0 : while (nCol > nX)
4819 : : {
4820 : 0 : --nCol;
4821 : 0 : nStartX -= nLayoutSign * (long) pRowInfo[0].pCellInfo[nCol+1].nWidth;
4822 : : }
4823 : : }
4824 : : }
4825 : 1455 : long nCellStartX = nStartX;
4826 : :
4827 : : // Ersatzdarstellung fuer zu kleinen Text weggelassen
4828 : :
4829 [ + + ]: 1455 : if (!bHidden)
4830 : : {
4831 : 661 : long nOutWidth = nCellWidth - 1;
4832 : 661 : long nOutHeight = nCellHeight;
4833 : :
4834 [ - + ]: 661 : if ( bMerged ) // Zusammengefasst
4835 : : {
4836 : 0 : SCCOL nCountX = pMerge->GetColMerge();
4837 [ # # ]: 0 : for (SCCOL i=1; i<nCountX; i++)
4838 [ # # ]: 0 : nOutWidth += (long) ( mpDoc->GetColWidth(nX+i,nTab) * mnPPTX );
4839 : 0 : SCROW nCountY = pMerge->GetRowMerge();
4840 [ # # ]: 0 : nOutHeight += (long) mpDoc->GetScaledRowHeight( nY+1, nY+nCountY-1, nTab, mnPPTY);
4841 : : }
4842 : :
4843 : : SvxCellVerJustify eVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)
4844 [ + - ]: 661 : pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet)).GetValue();
4845 : :
4846 : : // Syntax-Modus wird hier ignoriert...
4847 : :
4848 : : // StringDiffer doesn't look at hyphenate, language items
4849 [ - + ][ + + ]: 661 : if ( pPattern != pOldPattern || pCondSet != pOldCondSet )
4850 : : {
4851 [ + - ][ + - ]: 99 : SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
[ + - ]
4852 [ + - ]: 99 : pPattern->FillEditItemSet( pSet, pCondSet );
4853 : :
4854 : : // Ausrichtung fuer EditEngine
4855 : 99 : SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
4856 [ - + ]: 99 : if (eOrient==SVX_ORIENTATION_STACKED)
4857 : 0 : eSvxAdjust = SVX_ADJUST_CENTER;
4858 : : // Adjustment fuer bBreak ist hier weggelassen
4859 [ + - ][ + - ]: 99 : pSet->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
[ + - ]
4860 : :
4861 [ + - ]: 99 : pEngine->SetDefaults( pSet );
4862 : 99 : pOldPattern = pPattern;
4863 : 99 : pOldCondSet = pCondSet;
4864 : :
4865 [ + - ]: 99 : sal_uLong nControl = pEngine->GetControlWord();
4866 [ - + ]: 99 : if (eOrient==SVX_ORIENTATION_STACKED)
4867 : 0 : nControl |= EE_CNTRL_ONECHARPERLINE;
4868 : : else
4869 : 99 : nControl &= ~EE_CNTRL_ONECHARPERLINE;
4870 [ + - ]: 99 : pEngine->SetControlWord( nControl );
4871 : :
4872 [ + - ][ + - ]: 99 : if ( !bHyphenatorSet && ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() )
[ + + ][ + + ]
4873 : : {
4874 : : // set hyphenator the first time it is needed
4875 [ + - ]: 65 : com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
4876 [ + - ]: 65 : pEngine->SetHyphenator( xXHyphenator );
4877 : 65 : bHyphenatorSet = sal_True;
4878 : : }
4879 : :
4880 : : Color aBackCol = ((const SvxBrushItem&)
4881 [ + - ]: 99 : pPattern->GetItem( ATTR_BACKGROUND, pCondSet )).GetColor();
4882 [ + + ][ - + ]: 99 : if ( mbUseStyleColor && ( aBackCol.GetTransparency() > 0 || bCellContrast ) )
[ + + ][ + - ]
4883 : 34 : aBackCol.SetColor( nConfBackColor );
4884 [ + - ]: 99 : pEngine->SetBackgroundColor( aBackCol );
4885 : : }
4886 : :
4887 : : // Raender
4888 : :
4889 : : //! Position und Papersize auf EditUtil umstellen !!!
4890 : :
4891 : : const SvxMarginItem* pMargin = (const SvxMarginItem*)
4892 [ + - ]: 661 : &pPattern->GetItem(ATTR_MARGIN, pCondSet);
4893 : 661 : sal_uInt16 nIndent = 0;
4894 [ - + ]: 661 : if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
4895 : : nIndent = ((const SfxUInt16Item&)pPattern->
4896 [ # # ]: 0 : GetItem(ATTR_INDENT, pCondSet)).GetValue();
4897 : :
4898 : 661 : long nTotalHeight = nOutHeight; // ohne Rand abzuziehen
4899 [ + - ]: 661 : if ( bPixelToLogic )
4900 [ + - ]: 661 : nTotalHeight = mpRefDevice->PixelToLogic(Size(0,nTotalHeight)).Height();
4901 : :
4902 : 661 : long nLeftM = (long) ( (pMargin->GetLeftMargin() + nIndent) * mnPPTX );
4903 : 661 : long nTopM = (long) ( pMargin->GetTopMargin() * mnPPTY );
4904 : 661 : long nRightM = (long) ( pMargin->GetRightMargin() * mnPPTX );
4905 : 661 : long nBottomM = (long) ( pMargin->GetBottomMargin() * mnPPTY );
4906 : 661 : nStartX += nLeftM;
4907 : 661 : nStartY += nTopM;
4908 : 661 : nOutWidth -= nLeftM + nRightM;
4909 : 661 : nOutHeight -= nTopM + nBottomM;
4910 : :
4911 : : // Rotation schon hier, um bei Umbruch auch PaperSize anzupassen
4912 : 661 : long nAttrRotate = 0;
4913 : 661 : double nSin = 0.0;
4914 : 661 : double nCos = 1.0;
4915 : 661 : SvxRotateMode eRotMode = SVX_ROTATE_MODE_STANDARD;
4916 [ + - ]: 661 : if ( eOrient == SVX_ORIENTATION_STANDARD )
4917 : : {
4918 : : nAttrRotate = ((const SfxInt32Item&)pPattern->
4919 [ + - ]: 661 : GetItem(ATTR_ROTATE_VALUE, pCondSet)).GetValue();
4920 [ + - ]: 661 : if ( nAttrRotate )
4921 : : {
4922 : : eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
4923 [ + - ]: 661 : pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
4924 : :
4925 [ - + ]: 661 : if ( nAttrRotate == 18000 )
4926 : 0 : eRotMode = SVX_ROTATE_MODE_STANDARD; // keinen Ueberlauf
4927 : :
4928 [ - + ]: 661 : if ( bLayoutRTL )
4929 : 0 : nAttrRotate = -nAttrRotate;
4930 : :
4931 : 661 : double nRealOrient = nAttrRotate * F_PI18000; // 1/100 Grad
4932 : 661 : nCos = cos( nRealOrient );
4933 : 661 : nSin = sin( nRealOrient );
4934 : : }
4935 : : }
4936 : :
4937 : 661 : Size aPaperSize = Size( 1000000, 1000000 );
4938 [ - + ]: 661 : if (eOrient==SVX_ORIENTATION_STACKED)
4939 : 0 : aPaperSize.Width() = nOutWidth; // zum Zentrieren
4940 [ + + ]: 661 : else if (bBreak)
4941 : : {
4942 [ + - ]: 570 : if (nAttrRotate)
4943 : : {
4944 : : //! richtige PaperSize fuer Umbruch haengt von der Zeilenzahl
4945 : : //! ab, solange die Zeilen nicht einzeln versetzt ausgegeben
4946 : : //! werden koennen -> darum unbegrenzt, also kein Umbruch.
4947 : : //! Mit versetzten Zeilen waere das folgende richtig:
4948 : 570 : aPaperSize.Width() = (long)(nOutHeight / fabs(nSin));
4949 : : }
4950 [ # # ]: 0 : else if (eOrient == SVX_ORIENTATION_STANDARD)
4951 : 0 : aPaperSize.Width() = nOutWidth;
4952 : : else
4953 : 0 : aPaperSize.Width() = nOutHeight - 1;
4954 : : }
4955 [ + - ]: 661 : if (bPixelToLogic)
4956 [ + - ][ + - ]: 661 : pEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
4957 : : else
4958 [ # # ]: 0 : pEngine->SetPaperSize(aPaperSize); // Scale ist immer 1
4959 : :
4960 : : // Daten aus Zelle lesen
4961 : :
4962 [ + - ]: 661 : if (pCell)
4963 : : {
4964 [ + + ]: 661 : if (pCell->GetCellType() == CELLTYPE_EDIT)
4965 : : {
4966 : : const EditTextObject* pData;
4967 [ + - ]: 84 : ((ScEditCell*)pCell)->GetData(pData);
4968 : :
4969 [ + - ]: 84 : if (pData)
4970 [ + - ]: 84 : pEngine->SetText(*pData);
4971 : : else
4972 : : {
4973 : : OSL_FAIL("pData == 0");
4974 : : }
4975 : : }
4976 : : else
4977 : : {
4978 : : sal_uLong nFormat = pPattern->GetNumberFormat(
4979 [ + - ][ + - ]: 577 : mpDoc->GetFormatTable(), pCondSet );
4980 : 577 : rtl::OUString aString;
4981 : : Color* pColor;
4982 : : ScCellFormat::GetString( pCell,
4983 : : nFormat,aString, &pColor,
4984 [ + - ]: 577 : *mpDoc->GetFormatTable(),
4985 : : mbShowNullValues,
4986 : : mbShowFormulas,
4987 [ + - ]: 577 : ftCheck );
4988 : :
4989 [ + - ][ + - ]: 577 : pEngine->SetText(aString);
[ + - ]
4990 [ - + ][ # # ]: 577 : if ( pColor && !mbSyntaxMode && !( mbUseStyleColor && mbForceAutoColor ) )
[ # # ][ # # ]
4991 [ # # ]: 577 : lcl_SetEditColor( *pEngine, *pColor );
4992 : : }
4993 : :
4994 [ - + ]: 661 : if ( mbSyntaxMode )
4995 [ # # ]: 0 : SetEditSyntaxColor( *pEngine, pCell );
4996 [ + - ][ - + ]: 661 : else if ( mbUseStyleColor && mbForceAutoColor )
4997 [ # # ]: 0 : lcl_SetEditColor( *pEngine, COL_AUTO ); //! or have a flag at EditEngine
4998 : : }
4999 : : else
5000 : : {
5001 : : OSL_FAIL("pCell == NULL");
5002 : : }
5003 : :
5004 [ + - ]: 661 : pEngine->SetUpdateMode( sal_True ); // after SetText, before CalcTextWidth/GetTextHeight
5005 : :
5006 [ + - ]: 661 : long nEngineWidth = (long) pEngine->CalcTextWidth();
5007 [ + - ]: 661 : long nEngineHeight = pEngine->GetTextHeight();
5008 : :
5009 [ + - ][ + + ]: 661 : if (nAttrRotate && bBreak)
5010 : : {
5011 : 570 : double nAbsCos = fabs( nCos );
5012 : 570 : double nAbsSin = fabs( nSin );
5013 : :
5014 : : // adjust witdh of papersize for height of text
5015 : 570 : int nSteps = 5;
5016 [ + + ]: 1335 : while (nSteps > 0)
5017 : : {
5018 : : // everything is in pixels
5019 : : long nEnginePixel = mpRefDevice->LogicToPixel(
5020 [ + - ]: 765 : Size(0,nEngineHeight)).Height();
5021 : 765 : long nEffHeight = nOutHeight - (long)(nEnginePixel * nAbsCos) + 2;
5022 : 765 : long nNewWidth = (long)(nEffHeight / nAbsSin) + 2;
5023 : 765 : sal_Bool bFits = ( nNewWidth >= aPaperSize.Width() );
5024 [ + + ]: 765 : if ( bFits )
5025 : 570 : nSteps = 0;
5026 : : else
5027 : : {
5028 [ - + ]: 195 : if ( nNewWidth < 4 )
5029 : : {
5030 : : // can't fit -> fall back to using half height
5031 : 0 : nEffHeight = nOutHeight / 2;
5032 : 0 : nNewWidth = (long)(nEffHeight / nAbsSin) + 2;
5033 : 0 : nSteps = 0;
5034 : : }
5035 : : else
5036 : 195 : --nSteps;
5037 : :
5038 : : // set paper width and get new text height
5039 : 195 : aPaperSize.Width() = nNewWidth;
5040 [ + - ]: 195 : if (bPixelToLogic)
5041 [ + - ][ + - ]: 195 : pEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
5042 : : else
5043 [ # # ]: 0 : pEngine->SetPaperSize(aPaperSize); // Scale ist immer 1
5044 : : //pEngine->QuickFormatDoc( sal_True );
5045 [ + - ]: 195 : nEngineWidth = (long) pEngine->CalcTextWidth();
5046 [ + - ]: 195 : nEngineHeight = pEngine->GetTextHeight();
5047 : : }
5048 : : }
5049 : : }
5050 : :
5051 : 661 : long nRealWidth = nEngineWidth;
5052 : 661 : long nRealHeight = nEngineHeight;
5053 : :
5054 : : // wenn gedreht, Groesse anpassen
5055 [ + - ]: 661 : if (nAttrRotate)
5056 : : {
5057 : 661 : double nAbsCos = fabs( nCos );
5058 : 661 : double nAbsSin = fabs( nSin );
5059 : :
5060 [ + - ]: 661 : if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
5061 : : nEngineWidth = (long) ( nRealWidth * nAbsCos +
5062 : 661 : nRealHeight * nAbsSin );
5063 : : else
5064 : 0 : nEngineWidth = (long) ( nRealHeight / nAbsSin );
5065 : : //! begrenzen !!!
5066 : :
5067 : : nEngineHeight = (long) ( nRealHeight * nAbsCos +
5068 : 661 : nRealWidth * nAbsSin );
5069 : : }
5070 : :
5071 [ - + ]: 661 : if (!nAttrRotate) // hier nur gedrehter Text
5072 : 0 : bHidden = sal_True; //! vorher abfragen !!!
5073 : :
5074 : : //! weglassen, was nicht hereinragt
5075 : :
5076 [ + - ]: 661 : if (!bHidden)
5077 : : {
5078 : 661 : sal_Bool bClip = false;
5079 : 661 : Size aClipSize = Size( nScrX+nScrW-nStartX, nScrY+nScrH-nStartY );
5080 : :
5081 : : // weiterschreiben
5082 : :
5083 : 661 : Size aCellSize;
5084 [ + - ]: 661 : if (bPixelToLogic)
5085 [ + - ]: 661 : aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
5086 : : else
5087 : 0 : aCellSize = Size( nOutWidth, nOutHeight ); // Scale ist 1
5088 : :
5089 : 661 : long nGridWidth = nEngineWidth;
5090 : 661 : sal_Bool bNegative = false;
5091 [ - + ]: 661 : if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
5092 : : {
5093 : 0 : nGridWidth = aCellSize.Width() +
5094 : 0 : Abs((long) ( aCellSize.Height() * nCos / nSin ));
5095 : 0 : bNegative = ( pInfo->nRotateDir == SC_ROTDIR_LEFT );
5096 [ # # ]: 0 : if ( bLayoutRTL )
5097 : 0 : bNegative = !bNegative;
5098 : : }
5099 : :
5100 : : // use GetOutputArea to hide the grid
5101 : : // (clip region is done manually below)
5102 [ + - ]: 661 : OutputAreaParam aAreaParam;
5103 : :
5104 : 661 : SCCOL nCellX = nX;
5105 : 661 : SCROW nCellY = nY;
5106 : 661 : SvxCellHorJustify eOutHorJust = eHorJust;
5107 [ - + ]: 661 : if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
5108 [ # # ]: 0 : eOutHorJust = bNegative ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT;
5109 : 661 : long nNeededWidth = nGridWidth; // in pixel for GetOutputArea
5110 [ + - ]: 661 : if ( bPixelToLogic )
5111 [ + - ]: 661 : nNeededWidth = mpRefDevice->LogicToPixel(Size(nNeededWidth,0)).Width();
5112 : :
5113 : : GetOutputArea( nX, nArrY, nCellStartX, nPosY, nCellX, nCellY, nNeededWidth,
5114 : 661 : *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
5115 [ + - ]: 661 : false, false, sal_True, aAreaParam );
5116 : :
5117 [ + + ]: 661 : if ( bShrink )
5118 : : {
5119 : : long nPixelWidth = bPixelToLogic ?
5120 [ + - ][ + - ]: 91 : mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width() : nEngineWidth;
[ + - ][ + - ]
[ # # # # ]
5121 : 91 : long nNeededPixel = nPixelWidth + nLeftM + nRightM;
5122 : :
5123 : 91 : aAreaParam.mbLeftClip = aAreaParam.mbRightClip = sal_True;
5124 : :
5125 : : // always do height
5126 : : ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM,
5127 : 91 : false, sal::static_int_cast<sal_uInt16>(eOrient), nAttrRotate, bPixelToLogic,
5128 [ + - ]: 91 : nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
5129 : :
5130 [ + - ]: 91 : if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
5131 : : {
5132 : : // do width only if rotating within the cell (standard mode)
5133 : : ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM,
5134 : 91 : sal_True, sal::static_int_cast<sal_uInt16>(eOrient), nAttrRotate, bPixelToLogic,
5135 [ + - ]: 91 : nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
5136 : : }
5137 : :
5138 : : // nEngineWidth/nEngineHeight is updated in ShrinkEditEngine
5139 : : // (but width is only valid for standard mode)
5140 [ + - ]: 91 : nRealWidth = (long) pEngine->CalcTextWidth();
5141 [ + - ]: 91 : nRealHeight = pEngine->GetTextHeight();
5142 : :
5143 [ - + ]: 91 : if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
5144 : 91 : nEngineWidth = (long) ( nRealHeight / fabs( nSin ) );
5145 : : }
5146 : :
5147 : 661 : long nClipStartX = nStartX;
5148 [ - + ]: 661 : if (nX<nX1)
5149 : : {
5150 : : //! Clipping unnoetig, wenn links am Fenster
5151 : :
5152 : 0 : bClip = sal_True; // nur Rest ausgeben!
5153 [ # # ]: 0 : if (nStartX<nScrX)
5154 : : {
5155 : 0 : long nDif = nScrX - nStartX;
5156 : 0 : nClipStartX = nScrX;
5157 : 0 : aClipSize.Width() -= nDif;
5158 : : }
5159 : : }
5160 : :
5161 : 661 : long nClipStartY = nStartY;
5162 [ + - ][ - + ]: 661 : if (nArrY==0 || bVisChanged)
5163 : : {
5164 [ # # ]: 0 : if ( nClipStartY < nRowPosY )
5165 : : {
5166 : 0 : long nDif = nRowPosY - nClipStartY;
5167 : 0 : bClip = sal_True;
5168 : 0 : nClipStartY = nRowPosY;
5169 : 0 : aClipSize.Height() -= nDif;
5170 : : }
5171 : : }
5172 : :
5173 : 661 : bClip = sal_True; // always clip at the window/page border
5174 : :
5175 : : //Rectangle aClipRect;
5176 [ + - ]: 661 : if (bClip)
5177 : : {
5178 [ + - ]: 661 : if ( nAttrRotate /* && eRotMode != SVX_ROTATE_MODE_STANDARD */ )
5179 : : {
5180 : : // gedrehten, ausgerichteten Text nur an den
5181 : : // Seitengrenzen clippen
5182 : 661 : nClipStartX = nScrX;
5183 : 661 : aClipSize.Width() = nScrW;
5184 : : }
5185 : :
5186 [ + - ]: 661 : if (bPixelToLogic)
5187 : : aAreaParam.maClipRect = mpRefDevice->PixelToLogic( Rectangle(
5188 [ + - ][ + - ]: 661 : Point(nClipStartX,nClipStartY), aClipSize ) );
5189 : : else
5190 : : aAreaParam.maClipRect = Rectangle(Point(nClipStartX, nClipStartY),
5191 [ # # ]: 0 : aClipSize ); // Scale = 1
5192 : :
5193 [ - + ]: 661 : if (bMetaFile)
5194 : : {
5195 [ # # ]: 0 : mpDev->Push();
5196 [ # # ]: 0 : mpDev->IntersectClipRegion( aAreaParam.maClipRect );
5197 : : }
5198 : : else
5199 [ + - ][ + - ]: 661 : mpDev->SetClipRegion( Region( aAreaParam.maClipRect ) );
[ + - ]
5200 : : }
5201 : :
5202 : 661 : Point aLogicStart;
5203 [ + - ]: 661 : if (bPixelToLogic)
5204 [ + - ]: 661 : aLogicStart = mpRefDevice->PixelToLogic( Point(nStartX,nStartY) );
5205 : : else
5206 : 0 : aLogicStart = Point(nStartX, nStartY);
5207 [ + - ][ + + ]: 661 : if ( eOrient!=SVX_ORIENTATION_STANDARD || !bBreak )
5208 : : {
5209 : 91 : long nAvailWidth = aCellSize.Width();
5210 [ + - ][ + - ]: 91 : if (eType==OUTTYPE_WINDOW &&
[ - + ][ + - ]
5211 : : eOrient!=SVX_ORIENTATION_STACKED &&
5212 : : pInfo && pInfo->bAutoFilter)
5213 : : {
5214 : : // filter drop-down width is now independent from row height
5215 [ # # ]: 0 : if (bPixelToLogic)
5216 [ # # ]: 0 : nAvailWidth -= mpRefDevice->PixelToLogic(Size(0,DROPDOWN_BITMAP_SIZE)).Height();
5217 : : else
5218 : 0 : nAvailWidth -= DROPDOWN_BITMAP_SIZE;
5219 : 0 : long nComp = nEngineWidth;
5220 [ # # ]: 0 : if (nAvailWidth<nComp) nAvailWidth=nComp;
5221 : : }
5222 : :
5223 : : // horizontale Ausrichtung
5224 : :
5225 [ + - ][ - + ]: 91 : if (eOrient==SVX_ORIENTATION_STANDARD && !nAttrRotate)
5226 : : {
5227 [ # # ][ # # ]: 0 : if (eHorJust==SVX_HOR_JUSTIFY_RIGHT ||
5228 : : eHorJust==SVX_HOR_JUSTIFY_CENTER)
5229 : : {
5230 [ # # ]: 0 : pEngine->SetUpdateMode( false );
5231 : :
5232 : : SvxAdjust eSvxAdjust =
5233 : : (eHorJust==SVX_HOR_JUSTIFY_RIGHT) ?
5234 [ # # ]: 0 : SVX_ADJUST_RIGHT : SVX_ADJUST_CENTER;
5235 : : pEngine->SetDefaultItem(
5236 [ # # ][ # # ]: 0 : SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
[ # # ]
5237 : :
5238 : 0 : aPaperSize.Width() = nOutWidth;
5239 [ # # ]: 0 : if (bPixelToLogic)
5240 [ # # ][ # # ]: 0 : pEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
5241 : : else
5242 [ # # ]: 0 : pEngine->SetPaperSize(aPaperSize);
5243 : :
5244 [ # # ]: 0 : pEngine->SetUpdateMode( sal_True );
5245 : 0 : }
5246 : : }
5247 : : else
5248 : : {
5249 : : // bei gedrehtem Text ist Standard zentriert
5250 [ - + ]: 91 : if (eHorJust==SVX_HOR_JUSTIFY_RIGHT)
5251 : 0 : aLogicStart.X() += nAvailWidth - nEngineWidth;
5252 [ - + ][ # # ]: 91 : else if (eHorJust==SVX_HOR_JUSTIFY_CENTER ||
5253 : : eHorJust==SVX_HOR_JUSTIFY_STANDARD)
5254 : 91 : aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
5255 : : }
5256 : : }
5257 : :
5258 [ - + ]: 661 : if ( bLayoutRTL )
5259 : : {
5260 [ # # ]: 0 : if (bPixelToLogic)
5261 : 0 : aLogicStart.X() -= mpRefDevice->PixelToLogic(
5262 [ # # ]: 0 : Size( nCellWidth, 0 ) ).Width();
5263 : : else
5264 : 0 : aLogicStart.X() -= nCellWidth;
5265 : : }
5266 : :
5267 [ - + ][ # # ]: 661 : if ( eOrient==SVX_ORIENTATION_STANDARD ||
[ # # ]
5268 : : eOrient==SVX_ORIENTATION_STACKED || !bBreak )
5269 : : {
5270 [ + - ][ + - ]: 661 : if (eVerJust==SVX_VER_JUSTIFY_BOTTOM ||
5271 : : eVerJust==SVX_VER_JUSTIFY_STANDARD)
5272 : : {
5273 [ + - ]: 1322 : if (bPixelToLogic)
5274 : 661 : aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0,
5275 [ + - ]: 1322 : mpRefDevice->LogicToPixel(aCellSize).Height() -
5276 [ + - ]: 661 : mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
5277 [ + - ]: 661 : )).Height();
5278 : : else
5279 : 0 : aLogicStart.Y() += aCellSize.Height() - nEngineHeight;
5280 : : }
5281 : :
5282 [ # # ]: 0 : else if (eVerJust==SVX_VER_JUSTIFY_CENTER)
5283 : : {
5284 [ # # ]: 0 : if (bPixelToLogic)
5285 : 0 : aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0,(
5286 [ # # ]: 0 : mpRefDevice->LogicToPixel(aCellSize).Height() -
5287 [ # # ]: 0 : mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height())
5288 [ # # ]: 0 : / 2)).Height();
5289 : : else
5290 : 0 : aLogicStart.Y() += (aCellSize.Height() - nEngineHeight) / 2;
5291 : : }
5292 : : }
5293 : :
5294 : : // TOPBOTTON and BOTTOMTOP are handled in DrawStrings/DrawEdit
5295 : : OSL_ENSURE( eOrient == SVX_ORIENTATION_STANDARD && nAttrRotate,
5296 : : "DrawRotated: no rotation" );
5297 : :
5298 : 661 : long nOriVal = 0;
5299 [ + - ]: 661 : if ( nAttrRotate )
5300 : : {
5301 : : // Attribut ist 1/100, Font 1/10 Grad
5302 : 661 : nOriVal = nAttrRotate / 10;
5303 : :
5304 : 661 : double nAddX = 0.0;
5305 : 661 : double nAddY = 0.0;
5306 [ + - ][ - + ]: 661 : if ( nCos > 0.0 && eRotMode != SVX_ROTATE_MODE_STANDARD )
5307 : : {
5308 : : //! begrenzen !!!
5309 : 0 : double nH = nRealHeight * nCos;
5310 : 0 : nAddX += nH * ( nCos / fabs(nSin) );
5311 : : }
5312 [ - + ][ # # ]: 661 : if ( nCos < 0.0 && eRotMode == SVX_ROTATE_MODE_STANDARD )
5313 : 0 : nAddX -= nRealWidth * nCos;
5314 [ + + ]: 661 : if ( nSin < 0.0 )
5315 : 466 : nAddX -= nRealHeight * nSin;
5316 [ + + ]: 661 : if ( nSin > 0.0 )
5317 : 195 : nAddY += nRealWidth * nSin;
5318 [ - + ]: 661 : if ( nCos < 0.0 )
5319 : 0 : nAddY -= nRealHeight * nCos;
5320 : :
5321 [ - + ]: 661 : if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
5322 : : {
5323 : : //! begrenzen !!!
5324 : 0 : double nSkew = nTotalHeight * nCos / fabs(nSin);
5325 [ # # ]: 0 : if ( eRotMode == SVX_ROTATE_MODE_CENTER )
5326 : 0 : nAddX -= nSkew * 0.5;
5327 [ # # ][ # # ]: 0 : if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nSin > 0.0 ) ||
[ # # ][ # # ]
5328 : : ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nSin < 0.0 ) )
5329 : 0 : nAddX -= nSkew;
5330 : :
5331 : 0 : long nUp = 0;
5332 [ # # ]: 0 : if ( eVerJust == SVX_VER_JUSTIFY_CENTER )
5333 : 0 : nUp = ( aCellSize.Height() - nEngineHeight ) / 2;
5334 [ # # ]: 0 : else if ( eVerJust == SVX_VER_JUSTIFY_TOP )
5335 : : {
5336 [ # # ]: 0 : if ( nSin > 0.0 )
5337 : 0 : nUp = aCellSize.Height() - nEngineHeight;
5338 : : }
5339 : : else // BOTTOM / STANDARD
5340 : : {
5341 [ # # ]: 0 : if ( nSin < 0.0 )
5342 : 0 : nUp = aCellSize.Height() - nEngineHeight;
5343 : : }
5344 [ # # ]: 0 : if ( nUp )
5345 : 0 : nAddX += ( nUp * nCos / fabs(nSin) );
5346 : : }
5347 : :
5348 : 661 : aLogicStart.X() += (long) nAddX;
5349 : 661 : aLogicStart.Y() += (long) nAddY;
5350 : : }
5351 : :
5352 : : // bSimClip is not used here (because nOriVal is set)
5353 : :
5354 [ + - ][ - + ]: 661 : if ( pEngine->IsRightToLeft( 0 ) )
5355 : : {
5356 : : // For right-to-left, EditEngine always calculates its lines
5357 : : // beginning from the right edge, but EditLine::nStartPosX is
5358 : : // of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
5359 [ # # ]: 0 : Size aLogicPaper = pEngine->GetPaperSize();
5360 [ # # ]: 0 : if ( aLogicPaper.Width() > USHRT_MAX )
5361 : : {
5362 : 0 : aLogicPaper.Width() = USHRT_MAX;
5363 [ # # ]: 0 : pEngine->SetPaperSize(aLogicPaper);
5364 : : }
5365 : : }
5366 : :
5367 [ + - ]: 661 : pEngine->Draw( mpDev, aLogicStart, (short)nOriVal );
5368 : :
5369 [ + - ]: 661 : if (bClip)
5370 : : {
5371 [ - + ]: 661 : if (bMetaFile)
5372 [ # # ]: 0 : mpDev->Pop();
5373 : : else
5374 [ + - ]: 661 : mpDev->SetClipRegion();
5375 : : }
5376 : : }
5377 : : }
5378 : : }
5379 : : }
5380 : 3660 : nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
5381 : : }
5382 : : }
5383 : 538 : nRowPosY += pRowInfo[nArrY].nHeight;
5384 : : }
5385 : :
5386 [ + - ][ + - ]: 99 : delete pEngine;
5387 : 99 : }
5388 : :
5389 : :
5390 : :
5391 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|