[Libreoffice-commits] .: Branch 'libreoffice-3-4' - 14 commits - sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Wed Apr 6 13:04:59 PDT 2011


 sc/source/ui/inc/output.hxx   |   21 
 sc/source/ui/view/output2.cxx | 1104 +++++++++++++++++++++++++++++++++++++-----
 2 files changed, 996 insertions(+), 129 deletions(-)

New commits:
commit 2b639587aa2520134baac7bff466f4a25efc3d75
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 16:00:05 2011 -0400

    Fixed horizontal alignment issues for vertical text with text wrap on.

diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index 43ebf79..84d1a9c 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -132,6 +132,16 @@ private:
          */
         bool isVerticallyOriented() const;
 
+        /**
+         * Calculate offset position for vertically oriented (either
+         * top-bottom or bottom-top orientation) text.
+         *
+         * @param rLogicStart initial position in pixels.  When the call is
+         *                    finished, this parameter will store the new
+         *                    position.
+         */
+        void calcStartPosForVertical(Point& rLogicStart, long nCellWidth, long nEngineWidth, long nTopM, OutputDevice* pRefDevice);
+
         void setAlignmentItems();
         bool adjustHorAlignment(ScFieldEditEngine* pEngine);
         void adjustForRTL();
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 2ee2d25..707c8d8 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -2323,6 +2323,36 @@ bool ScOutputData::DrawEditParam::isVerticallyOriented() const
     return (meOrient == SVX_ORIENTATION_TOPBOTTOM || meOrient == SVX_ORIENTATION_BOTTOMTOP);
 }
 
+void ScOutputData::DrawEditParam::calcStartPosForVertical(
+    Point& rLogicStart, long nCellWidth, long nEngineWidth, long nTopM, OutputDevice* pRefDevice)
+{
+    OSL_ENSURE(isVerticallyOriented(), "Use this only for vertically oriented cell!");
+
+    if (mbPixelToLogic)
+        rLogicStart = pRefDevice->PixelToLogic(rLogicStart);
+
+    if (mbBreak)
+    {
+        // vertical adjustment is within the EditEngine
+        if (mbPixelToLogic)
+            rLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+        else
+            rLogicStart.Y() += nTopM;
+
+        switch (meHorJust)
+        {
+            case SVX_HOR_JUSTIFY_CENTER:
+                rLogicStart.X() += (nCellWidth - nEngineWidth) / 2;
+            break;
+            case SVX_HOR_JUSTIFY_RIGHT:
+                rLogicStart.X() += nCellWidth - nEngineWidth;
+            break;
+            default:
+                ; // do nothing
+        }
+    }
+}
+
 void ScOutputData::DrawEditParam::setAlignmentItems()
 {
     if (isVerticallyOriented() || mbAsianVertical)
@@ -3130,7 +3160,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     //
 
     Size aPaperSize = Size( 1000000, 1000000 );
-    if (rParam.hasLineBreak())
+    if (rParam.mbBreak)
     {
         //	call GetOutputArea with nNeeded=0, to get only the cell width
 
@@ -3145,16 +3175,6 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     if (rParam.mbPixelToLogic)
     {
         Size aLogicSize = pRefDevice->PixelToLogic(aPaperSize);
-        if ( rParam.mbBreak && pRefDevice != pFmtDevice )
-        {
-            // #i85342# screen display and formatting for printer,
-            // use same GetEditArea call as in ScViewData::SetEditEngine
-
-            Fraction aFract(1,1);
-            Rectangle aUtilRect = ScEditUtil( pDoc, rParam.mnCellX, rParam.mnCellY, nTab, Point(0,0), pFmtDevice,
-                HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( rParam.mpPattern, false );
-            aLogicSize.Width() = aUtilRect.GetWidth();
-        }
         rParam.mpEngine->SetPaperSize(aLogicSize);
     }
     else
@@ -3399,20 +3419,8 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         }
     }
 
-    Point aLogicStart;
-    if (rParam.mbPixelToLogic)
-        aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
-    else
-        aLogicStart = Point(nStartX, nStartY);
-
-    if (rParam.mbBreak)
-    {
-        // vertical adjustment is within the EditEngine
-        if (rParam.mbPixelToLogic)
-            aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
-        else
-            aLogicStart.Y() += nTopM;
-    }
+    Point aLogicStart(nStartX, nStartY);
+    rParam.calcStartPosForVertical(aLogicStart, aCellSize.Width(), nEngineWidth, nTopM, pRefDevice);
 
     Point aURLStart = aLogicStart;      // copy before modifying for orientation
 
@@ -3548,16 +3556,6 @@ void ScOutputData::DrawEditTopBottom(DrawEditParam& rParam)
     if (rParam.mbPixelToLogic)
     {
         Size aLogicSize = pRefDevice->PixelToLogic(aPaperSize);
-        if ( rParam.mbBreak && pRefDevice != pFmtDevice )
-        {
-            // #i85342# screen display and formatting for printer,
-            // use same GetEditArea call as in ScViewData::SetEditEngine
-
-            Fraction aFract(1,1);
-            Rectangle aUtilRect = ScEditUtil( pDoc, rParam.mnCellX, rParam.mnCellY, nTab, Point(0,0), pFmtDevice,
-                HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( rParam.mpPattern, false );
-            aLogicSize.Width() = aUtilRect.GetWidth();
-        }
         rParam.mpEngine->SetPaperSize(aLogicSize);
     }
     else
@@ -3804,20 +3802,8 @@ void ScOutputData::DrawEditTopBottom(DrawEditParam& rParam)
         }
     }
 
-    Point aLogicStart;
-    if (rParam.mbPixelToLogic)
-        aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
-    else
-        aLogicStart = Point(nStartX, nStartY);
-
-    if (rParam.mbBreak)
-    {
-        // vertical adjustment is within the EditEngine
-        if (rParam.mbPixelToLogic)
-            aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
-        else
-            aLogicStart.Y() += nTopM;
-    }
+    Point aLogicStart(nStartX, nStartY);
+    rParam.calcStartPosForVertical(aLogicStart, aCellSize.Width(), nEngineWidth, nTopM, pRefDevice);
 
     Point aURLStart = aLogicStart;      // copy before modifying for orientation
 
commit cdaf170aca48b76acbd18bc5d33328d7305c788c
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 12:30:37 2011 -0400

    Branching in the main function to call appropriate sub-methods.

diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index aee8cfd..2ee2d25 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -4042,10 +4042,20 @@ void ScOutputData::DrawEdit(sal_Bool bPixelToLogic)
                         aParam.mpOldPattern = pOldPattern;
                         aParam.mpOldCondSet = pOldCondSet;
                         aParam.mpThisRowInfo = pThisRowInfo;
-                        if (aParam.meOrient == SVX_ORIENTATION_BOTTOMTOP)
-                            DrawEditBottomTop(aParam);
-                        else
-                            DrawEditStandard(aParam);
+                        switch (aParam.meOrient)
+                        {
+                            case SVX_ORIENTATION_BOTTOMTOP:
+                                DrawEditBottomTop(aParam);
+                            break;
+                            case SVX_ORIENTATION_TOPBOTTOM:
+                                DrawEditTopBottom(aParam);
+                            break;
+                            case SVX_ORIENTATION_STACKED:
+                                DrawEditStacked(aParam);
+                            break;
+                            default:
+                                DrawEditStandard(aParam);
+                        }
 
                         // Retrieve parameters for next iteration.
                         pOldPattern = aParam.mpOldPattern;
commit 9b59d1ea17149311d977b4340f78aca85af59967
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 12:25:41 2011 -0400

    Do the same for top-bottom text direction.

diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 003d0ca..aee8cfd 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -3488,7 +3488,400 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
 
 void ScOutputData::DrawEditTopBottom(DrawEditParam& rParam)
 {
-    DrawEditStandard(rParam);
+    Size aRefOne = pRefDevice->PixelToLogic(Size(1,1));
+
+    bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
+    bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
+
+    if ( rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT )
+    {
+        // ignore orientation/rotation if "repeat" is active
+        rParam.meOrient = SVX_ORIENTATION_STANDARD;
+        DrawEditStandard(rParam);
+        return;
+    }
+
+    SvxCellHorJustify eOutHorJust =
+        ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
+        ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
+
+    if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
+        eOutHorJust = SVX_HOR_JUSTIFY_LEFT;		// repeat is not yet implemented
+
+    //!	mirror margin values for RTL?
+    //!	move margin down to after final GetOutputArea call
+    long nTopM, nLeftM, nBottomM, nRightM;
+    rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, nPPTX, nPPTY);
+
+    SCCOL nXForPos = rParam.mnX;
+    if ( nXForPos < nX1 )
+    {
+        nXForPos = nX1;
+        rParam.mnPosX = rParam.mnInitPosX;
+    }
+    SCSIZE nArrYForPos = rParam.mnArrY;
+    if ( nArrYForPos < 1 )
+    {
+        nArrYForPos = 1;
+        rParam.mnPosY = nScrY;
+    }
+
+    OutputAreaParam aAreaParam;
+
+    //
+    //	Initial page size - large for normal text, cell size for automatic line breaks
+    //
+
+    Size aPaperSize = Size( 1000000, 1000000 );
+    if (rParam.hasLineBreak())
+    {
+        //	call GetOutputArea with nNeeded=0, to get only the cell width
+
+        //!	handle nArrY == 0
+        GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
+                       *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
+                       rParam.mbCellIsValue, true, false, aAreaParam );
+
+        //! special ScEditUtil handling if formatting for printer
+        rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, nPPTX, nPPTY);
+    }
+    if (rParam.mbPixelToLogic)
+    {
+        Size aLogicSize = pRefDevice->PixelToLogic(aPaperSize);
+        if ( rParam.mbBreak && pRefDevice != pFmtDevice )
+        {
+            // #i85342# screen display and formatting for printer,
+            // use same GetEditArea call as in ScViewData::SetEditEngine
+
+            Fraction aFract(1,1);
+            Rectangle aUtilRect = ScEditUtil( pDoc, rParam.mnCellX, rParam.mnCellY, nTab, Point(0,0), pFmtDevice,
+                HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( rParam.mpPattern, false );
+            aLogicSize.Width() = aUtilRect.GetWidth();
+        }
+        rParam.mpEngine->SetPaperSize(aLogicSize);
+    }
+    else
+        rParam.mpEngine->SetPaperSize(aPaperSize);
+
+    //
+    //	Fill the EditEngine (cell attributes and text)
+    //
+
+    rParam.updateEnginePattern(bUseStyleColor);
+    rParam.setAlignmentItems();
+
+    //	Read content from cell
+
+    bool bWrapFields = false;
+    if (!rParam.readCellContent(pDoc, bShowNullValues, bShowFormulas, bSyntaxMode, bUseStyleColor, bForceAutoColor, bWrapFields))
+        // Failed to read cell content.  Bail out.
+        return;
+
+    if ( bSyntaxMode )
+        SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
+    else if ( bUseStyleColor && bForceAutoColor )
+        lcl_SetEditColor( *rParam.mpEngine, COL_AUTO );		//! or have a flag at EditEngine
+    else
+    {
+        OSL_FAIL("pCell == NULL");
+    }
+
+    rParam.mpEngine->SetUpdateMode( true );		// after SetText, before CalcTextWidth/GetTextHeight
+
+    //
+    //	Get final output area using the calculated width
+    //
+
+    long nEngineWidth, nEngineHeight;
+    rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
+
+    long nNeededPixel = nEngineWidth;
+    if (rParam.mbPixelToLogic)
+        nNeededPixel = pRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
+    nNeededPixel += nLeftM + nRightM;
+
+    if (!rParam.mbBreak || bShrink)
+    {
+        // for break, the first GetOutputArea call is sufficient
+        GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
+                       *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
+                       rParam.mbCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
+
+        if ( bShrink )
+        {
+            ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
+                nLeftM, nTopM, nRightM, nBottomM, false,
+                sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
+                nEngineWidth, nEngineHeight, nNeededPixel,
+                aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
+        }
+        if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
+        {
+            // First check if twice the space for the formatted text is available
+            // (otherwise just keep it unchanged).
+
+            long nFormatted = nNeededPixel - nLeftM - nRightM;      // without margin
+            long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
+            if ( nAvailable >= 2 * nFormatted )
+            {
+                // "repeat" is handled with unformatted text (for performance reasons)
+                String aCellStr = rParam.mpEngine->GetText();
+                rParam.mpEngine->SetText( aCellStr );
+
+                long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
+                if (rParam.mbPixelToLogic)
+                    nRepeatSize = pRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
+                if ( pFmtDevice != pRefDevice )
+                    ++nRepeatSize;
+                if ( nRepeatSize > 0 )
+                {
+                    long nRepeatCount = nAvailable / nRepeatSize;
+                    if ( nRepeatCount > 1 )
+                    {
+                        String aRepeated = aCellStr;
+                        for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
+                            aRepeated.Append( aCellStr );
+                        rParam.mpEngine->SetText( aRepeated );
+
+                        nEngineHeight = rParam.mpEngine->GetTextHeight();
+                        nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
+                        if (rParam.mbPixelToLogic)
+                            nNeededPixel = pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
+                        else
+                            nNeededPixel = nEngineWidth;
+                        nNeededPixel += nLeftM + nRightM;
+                    }
+                }
+            }
+        }
+
+        if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
+        {
+            rParam.mpEngine->SetText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) );
+            nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
+            if (rParam.mbPixelToLogic)
+                nNeededPixel = pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
+            else
+                nNeededPixel = nEngineWidth;
+            nNeededPixel += nLeftM + nRightM;
+
+            //	No clip marks if "###" doesn't fit (same as in DrawStrings)
+        }
+    }
+
+    long nStartX = aAreaParam.maAlignRect.Left();
+    long nStartY = aAreaParam.maAlignRect.Top();
+    long nCellWidth = aAreaParam.maAlignRect.GetWidth();
+    long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
+    long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
+
+    if (rParam.mbBreak)
+    {
+        //	text with automatic breaks is aligned only within the
+        //	edit engine's paper size, the output of the whole area
+        //	is always left-aligned
+
+        nStartX += nLeftM;
+        if (rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK)
+            nStartX += aPaperSize.Height();
+    }
+    else
+    {
+        if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
+            nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
+        else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
+            nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
+        else
+            nStartX += nLeftM;
+    }
+
+    bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
+    if (bOutside)
+        return;
+
+    if ( aAreaParam.maClipRect.Left() < nScrX )
+    {
+        aAreaParam.maClipRect.Left() = nScrX;
+        aAreaParam.mbLeftClip = true;
+    }
+    if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
+    {
+        aAreaParam.maClipRect.Right() = nScrX + nScrW;			//! minus one?
+        aAreaParam.mbRightClip = true;
+    }
+
+    bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
+    bool bSimClip = false;
+
+    if ( bWrapFields )
+    {
+        //	Fields in a cell with automatic breaks: clip to cell width
+        bClip = true;
+    }
+
+    if ( aAreaParam.maClipRect.Top() < nScrY )
+    {
+        aAreaParam.maClipRect.Top() = nScrY;
+        bClip = true;
+    }
+    if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
+    {
+        aAreaParam.maClipRect.Bottom() = nScrY + nScrH;     //! minus one?
+        bClip = true;
+    }
+
+    Size aCellSize;			// output area, excluding margins, in logical units
+    if (rParam.mbPixelToLogic)
+        aCellSize = pRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
+    else
+        aCellSize = Size( nOutWidth, nOutHeight );
+
+    if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
+    {
+        const ScMergeAttr* pMerge =
+                (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
+        bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
+
+        //	Don't clip for text height when printing rows with optimal height,
+        //	except when font size is from conditional formatting.
+        //!	Allow clipping when vertically merged?
+        if ( eType != OUTTYPE_PRINTER ||
+            ( pDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
+            ( rParam.mpCondSet && SFX_ITEM_SET ==
+                rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
+            bClip = true;
+        else
+            bSimClip = true;
+
+        //	Show clip marks if height is at least 5pt too small and
+        //	there are several lines of text.
+        //	Not for asian vertical text, because that would interfere
+        //	with the default right position of the text.
+        //	Only with automatic line breaks, to avoid having to find
+        //	the cells with the horizontal end of the text again.
+        if ( nEngineHeight - aCellSize.Height() > 100 &&
+             rParam.mbBreak && bMarkClipped &&
+             ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
+        {
+            CellInfo* pClipMarkCell = NULL;
+            if ( bMerged )
+            {
+                //	anywhere in the merged area...
+                SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
+                pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
+            }
+            else
+                pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
+
+            pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT;		//! also allow left?
+            bAnyClipped = true;
+
+            long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
+            if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
+                aAreaParam.maClipRect.Right() -= nMarkPixel;
+        }
+    }
+
+    Rectangle aLogicClip;
+    if (bClip || bSimClip)
+    {
+        // Clip marks are already handled in GetOutputArea
+
+        if (rParam.mbPixelToLogic)
+            aLogicClip = pRefDevice->PixelToLogic( aAreaParam.maClipRect );
+        else
+            aLogicClip = aAreaParam.maClipRect;
+
+        if (bClip)	// bei bSimClip nur aClipRect initialisieren
+        {
+            if (bMetaFile)
+            {
+                pDev->Push();
+                pDev->IntersectClipRegion( aLogicClip );
+            }
+            else
+                pDev->SetClipRegion( Region( aLogicClip ) );
+        }
+    }
+
+    Point aLogicStart;
+    if (rParam.mbPixelToLogic)
+        aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
+    else
+        aLogicStart = Point(nStartX, nStartY);
+
+    if (rParam.mbBreak)
+    {
+        // vertical adjustment is within the EditEngine
+        if (rParam.mbPixelToLogic)
+            aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+        else
+            aLogicStart.Y() += nTopM;
+    }
+
+    Point aURLStart = aLogicStart;      // copy before modifying for orientation
+
+    if (rParam.meHorJust != SVX_HOR_JUSTIFY_BLOCK)
+    {
+        aLogicStart.X() += nEngineWidth;
+        if (!rParam.mbBreak)
+        {
+            // Set the paper width to text size.
+            Size aPSize = rParam.mpEngine->GetPaperSize();
+            aPSize.Width() = rParam.mpEngine->CalcTextWidth();
+            rParam.mpEngine->SetPaperSize(aPSize);
+
+            long nGap = 0;
+            long nTopOffset = 0; // offset by top margin
+            if (rParam.mbPixelToLogic)
+            {
+                nGap = pRefDevice->LogicToPixel(aPSize).Width() - pRefDevice->LogicToPixel(aCellSize).Height();
+                nGap = pRefDevice->PixelToLogic(Size(0, nGap)).Height();
+                nTopOffset = pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+            }
+            else
+            {
+                nGap = aPSize.Width() - aCellSize.Height();
+                nTopOffset = nTopM;
+            }
+            aLogicStart.Y() += nTopOffset;
+
+            switch (rParam.meVerJust)
+            {
+                case SVX_VER_JUSTIFY_STANDARD:
+                case SVX_VER_JUSTIFY_BOTTOM:
+                    // align to bottom
+                    aLogicStart.Y() -= nGap;
+                break;
+                case SVX_VER_JUSTIFY_CENTER:
+                    // center it.
+                    aLogicStart.Y() -= nGap / 2;
+                break;
+                case SVX_VER_JUSTIFY_BLOCK:
+                case SVX_VER_JUSTIFY_TOP:
+                    // align to top (do nothing)
+                default:
+                    ;
+            }
+        }
+    }
+
+    rParam.adjustForRTL();
+
+    // bMoveClipped handling has been replaced by complete alignment
+    // handling (also extending to the left).
+
+    rParam.mpEngine->Draw(pDev, aLogicStart, 2700);
+
+    if (bClip)
+    {
+        if (bMetaFile)
+            pDev->Pop();
+        else
+            pDev->SetClipRegion();
+    }
+
+    rParam.adjustForHyperlinkInPDF(aURLStart, pDev);
 }
 
 void ScOutputData::DrawEditStacked(DrawEditParam& rParam)
commit e24afa2a6ee9e4160cda36fdbbffc7b878e21664
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 11:51:54 2011 -0400

    Extracted a method that adjust hyperlinks in PDF output.

diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index cfa8ae9..43ebf79 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -135,6 +135,7 @@ private:
         void setAlignmentItems();
         bool adjustHorAlignment(ScFieldEditEngine* pEngine);
         void adjustForRTL();
+        void adjustForHyperlinkInPDF(Point aURLStart, OutputDevice* pDev);
     };
 
     OutputDevice* pDev;			// Device
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index b52d1fe..003d0ca 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -2465,6 +2465,33 @@ void ScOutputData::DrawEditParam::adjustForRTL()
     }
 }
 
+void ScOutputData::DrawEditParam::adjustForHyperlinkInPDF(Point aURLStart, OutputDevice* pDev)
+{
+    // PDF: whole-cell hyperlink from formula?
+    vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+    bool bHasURL = pPDFData && isHyperlinkCell();
+    if (!bHasURL)
+        return;
+
+    long nURLWidth = (long) mpEngine->CalcTextWidth();
+    long nURLHeight = mpEngine->GetTextHeight();
+    if (mbBreak)
+    {
+        Size aPaper = mpEngine->GetPaperSize();
+        if ( mbAsianVertical )
+            nURLHeight = aPaper.Height();
+        else
+            nURLWidth = aPaper.Width();
+    }
+    if (isVerticallyOriented())
+        std::swap( nURLWidth, nURLHeight );
+    else if (mbAsianVertical)
+        aURLStart.X() -= nURLWidth;
+
+    Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
+    lcl_DoHyperlinkResult( pDev, aURLRect, mpCell );
+}
+
 void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
 {
     Size aRefOne = pRefDevice->PixelToLogic(Size(1,1));
@@ -3053,29 +3080,7 @@ void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
             pDev->SetClipRegion();
     }
 
-    // PDF: whole-cell hyperlink from formula?
-    vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
-    bool bHasURL = pPDFData && rParam.isHyperlinkCell();
-    if ( bHasURL )
-    {
-        long nURLWidth = (long) rParam.mpEngine->CalcTextWidth();
-        long nURLHeight = rParam.mpEngine->GetTextHeight();
-        if ( rParam.mbBreak )
-        {
-            Size aPaper = rParam.mpEngine->GetPaperSize();
-            if ( rParam.mbAsianVertical )
-                nURLHeight = aPaper.Height();
-            else
-                nURLWidth = aPaper.Width();
-        }
-        if ( rParam.isVerticallyOriented() )
-            std::swap( nURLWidth, nURLHeight );
-        else if ( rParam.mbAsianVertical )
-            aURLStart.X() -= nURLWidth;
-
-        Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
-        lcl_DoHyperlinkResult( pDev, aURLRect, rParam.mpCell );
-    }
+    rParam.adjustForHyperlinkInPDF(aURLStart, pDev);
 }
 
 void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
@@ -3478,24 +3483,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
             pDev->SetClipRegion();
     }
 
-    // PDF: whole-cell hyperlink from formula?
-    vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
-    bool bHasURL = pPDFData && rParam.isHyperlinkCell();
-    if ( bHasURL )
-    {
-        long nURLWidth = (long) rParam.mpEngine->CalcTextWidth();
-        long nURLHeight = rParam.mpEngine->GetTextHeight();
-        if ( rParam.mbBreak )
-        {
-            Size aPaper = rParam.mpEngine->GetPaperSize();
-            nURLWidth = aPaper.Width();
-        }
-
-        std::swap( nURLWidth, nURLHeight ); // vertical orientation
-
-        Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
-        lcl_DoHyperlinkResult( pDev, aURLRect, rParam.mpCell );
-    }
+    rParam.adjustForHyperlinkInPDF(aURLStart, pDev);
 }
 
 void ScOutputData::DrawEditTopBottom(DrawEditParam& rParam)
commit ab144ee269bfa2047421ded14d02d06f6ab2ccc3
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 11:25:15 2011 -0400

    More sharing of common code blocks.

diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index dee44ba..cfa8ae9 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -123,6 +123,7 @@ private:
         void getEngineSize(ScFieldEditEngine* pEngine, long& rWidth, long& rHeight) const;
         long getEngineWidth(ScFieldEditEngine* pEngine) const;
         bool hasLineBreak() const;
+        bool isHyperlinkCell() const;
 
         /**
          * When the text is vertically oriented, the text is either rotated 90
@@ -133,6 +134,7 @@ private:
 
         void setAlignmentItems();
         bool adjustHorAlignment(ScFieldEditEngine* pEngine);
+        void adjustForRTL();
     };
 
     OutputDevice* pDev;			// Device
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 3e3bd76..b52d1fe 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -2307,6 +2307,17 @@ bool ScOutputData::DrawEditParam::hasLineBreak() const
     return (mbBreak || (meOrient == SVX_ORIENTATION_STACKED) || mbAsianVertical);
 }
 
+bool ScOutputData::DrawEditParam::isHyperlinkCell() const
+{
+    if (!mpCell)
+        return false;
+
+    if (mpCell->GetCellType() != CELLTYPE_FORMULA)
+        return false;
+
+    return static_cast<ScFormulaCell*>(mpCell)->IsHyperLinkCell();
+}
+
 bool ScOutputData::DrawEditParam::isVerticallyOriented() const
 {
     return (meOrient == SVX_ORIENTATION_TOPBOTTOM || meOrient == SVX_ORIENTATION_BOTTOMTOP);
@@ -2437,11 +2448,27 @@ bool ScOutputData::DrawEditParam::adjustHorAlignment(ScFieldEditEngine* pEngine)
     return false;
 }
 
+void ScOutputData::DrawEditParam::adjustForRTL()
+{
+    if (!mpEngine->IsRightToLeft(0))
+        // No RTL mode.
+        return;
+
+    //	For right-to-left, EditEngine always calculates its lines
+    //	beginning from the right edge, but EditLine::nStartPosX is
+    //	of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
+    Size aLogicPaper = mpEngine->GetPaperSize();
+    if ( aLogicPaper.Width() > USHRT_MAX )
+    {
+        aLogicPaper.Width() = USHRT_MAX;
+        mpEngine->SetPaperSize(aLogicPaper);
+    }
+}
+
 void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
 {
     Size aRefOne = pRefDevice->PixelToLogic(Size(1,1));
 
-    vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
     bool bHidden = false;
     bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
     bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
@@ -2993,18 +3020,7 @@ void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
         rParam.mpEngine->SetPaperSize(aPaperLogic);
     }
 
-    if ( rParam.mpEngine->IsRightToLeft( 0 ) )
-    {
-        //	For right-to-left, EditEngine always calculates its lines
-        //	beginning from the right edge, but EditLine::nStartPosX is
-        //	of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
-        Size aLogicPaper = rParam.mpEngine->GetPaperSize();
-        if ( aLogicPaper.Width() > USHRT_MAX )
-        {
-            aLogicPaper.Width() = USHRT_MAX;
-            rParam.mpEngine->SetPaperSize(aLogicPaper);
-        }
-    }
+    rParam.adjustForRTL();
 
     // bMoveClipped handling has been replaced by complete alignment
     // handling (also extending to the left).
@@ -3038,8 +3054,8 @@ void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
     }
 
     // PDF: whole-cell hyperlink from formula?
-    bool bHasURL = pPDFData && rParam.mpCell && rParam.mpCell->GetCellType() == CELLTYPE_FORMULA &&
-                    static_cast<ScFormulaCell*>(rParam.mpCell)->IsHyperLinkCell();
+    vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+    bool bHasURL = pPDFData && rParam.isHyperlinkCell();
     if ( bHasURL )
     {
         long nURLWidth = (long) rParam.mpEngine->CalcTextWidth();
@@ -3066,7 +3082,6 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
 {
     Size aRefOne = pRefDevice->PixelToLogic(Size(1,1));
 
-    vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
     bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
     bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
 
@@ -3452,19 +3467,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         }
     }
 
-    if ( rParam.mpEngine->IsRightToLeft( 0 ) )
-    {
-        //	For right-to-left, EditEngine always calculates its lines
-        //	beginning from the right edge, but EditLine::nStartPosX is
-        //	of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
-        Size aLogicPaper = rParam.mpEngine->GetPaperSize();
-        if ( aLogicPaper.Width() > USHRT_MAX )
-        {
-            aLogicPaper.Width() = USHRT_MAX;
-            rParam.mpEngine->SetPaperSize(aLogicPaper);
-        }
-    }
-
+    rParam.adjustForRTL();
     rParam.mpEngine->Draw(pDev, aLogicStart, 900);
 
     if (bClip)
@@ -3476,8 +3479,8 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     }
 
     // PDF: whole-cell hyperlink from formula?
-    bool bHasURL = pPDFData && rParam.mpCell && rParam.mpCell->GetCellType() == CELLTYPE_FORMULA &&
-                    static_cast<ScFormulaCell*>(rParam.mpCell)->IsHyperLinkCell();
+    vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+    bool bHasURL = pPDFData && rParam.isHyperlinkCell();
     if ( bHasURL )
     {
         long nURLWidth = (long) rParam.mpEngine->CalcTextWidth();
commit 9c78b98380b1ab244107030042d2ce9cad0cc9c2
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 11:12:11 2011 -0400

    Extracted a method to read cell content.  That code is common in both methods.

diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index e20de15..dee44ba 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -116,6 +116,7 @@ private:
 
         explicit DrawEditParam(const ScPatternAttr* pPattern, const SfxItemSet* pCondSet, bool bCellIsValue);
 
+        bool readCellContent(ScDocument* pDoc, bool bShowNullValues, bool bShowFormulas, bool bSyntaxMode, bool bUseStyleColor, bool bForceAutoColor, bool& rWrapFields);
         void updateEnginePattern(bool bUseStyleColor);
         void calcMargins(long& rTop, long& rLeft, long& rBottom, long& rRight, double nPPTX, double nPPTY) const;
         void calcPaperSize(Size& rPaperSize, const Rectangle& rAlignRect, double nPPTX, double nPPTY) const;
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index e797bca..3e3bd76 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -2137,6 +2137,58 @@ ScOutputData::DrawEditParam::DrawEditParam(const ScPatternAttr* pPattern, const
     mpThisRowInfo(NULL)
 {}
 
+bool ScOutputData::DrawEditParam::readCellContent(
+    ScDocument* pDoc, bool bShowNullValues, bool bShowFormulas, bool bSyntaxMode, bool bUseStyleColor, bool bForceAutoColor, bool& rWrapFields)
+{
+    if (!mpCell)
+    {
+        OSL_FAIL("pCell == NULL");
+        return false;
+    }
+
+    if (mpCell->GetCellType() == CELLTYPE_EDIT)
+    {
+        const EditTextObject* pData;
+        ((ScEditCell*)mpCell)->GetData(pData);
+
+        if (pData)
+        {
+            mpEngine->SetText(*pData);
+
+            if ( mbBreak && !mbAsianVertical && pData->HasField() )
+            {
+                //	Fields aren't wrapped, so clipping is enabled to prevent
+                //	a field from being drawn beyond the cell size
+
+                rWrapFields = true;
+            }
+        }
+        else
+        {
+            OSL_FAIL("pData == 0");
+            return false;
+        }
+    }
+    else
+    {
+        sal_uLong nFormat = mpPattern->GetNumberFormat(
+                                    pDoc->GetFormatTable(), mpCondSet );
+        String aString;
+        Color* pColor;
+        ScCellFormat::GetString( mpCell,
+                                 nFormat,aString, &pColor,
+                                 *pDoc->GetFormatTable(),
+                                 bShowNullValues,
+                                 bShowFormulas,
+                                 ftCheck );
+
+        mpEngine->SetText(aString);
+        if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
+            lcl_SetEditColor( *mpEngine, *pColor );
+    }
+    return true;
+}
+
 void ScOutputData::DrawEditParam::updateEnginePattern(bool bUseStyleColor)
 {
     // syntax highlighting mode is ignored here
@@ -2504,51 +2556,9 @@ void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
     //	Read content from cell
 
     bool bWrapFields = false;
-    if (!rParam.mpCell)
-    {
-        OSL_FAIL("pCell == NULL");
+    if (!rParam.readCellContent(pDoc, bShowNullValues, bShowFormulas, bSyntaxMode, bUseStyleColor, bForceAutoColor, bWrapFields))
+        // Failed to read cell content.  Bail out.
         return;
-    }
-
-    if (rParam.mpCell->GetCellType() == CELLTYPE_EDIT)
-    {
-        const EditTextObject* pData;
-        ((ScEditCell*)rParam.mpCell)->GetData(pData);
-
-        if (pData)
-        {
-            rParam.mpEngine->SetText(*pData);
-
-            if ( rParam.mbBreak && !rParam.mbAsianVertical && pData->HasField() )
-            {
-                //	Fields aren't wrapped, so clipping is enabled to prevent
-                //	a field from being drawn beyond the cell size
-
-                bWrapFields = true;
-            }
-        }
-        else
-        {
-            OSL_FAIL("pData == 0");
-        }
-    }
-    else
-    {
-        sal_uLong nFormat = rParam.mpPattern->GetNumberFormat(
-                                    pDoc->GetFormatTable(), rParam.mpCondSet );
-        String aString;
-        Color* pColor;
-        ScCellFormat::GetString( rParam.mpCell,
-                                 nFormat,aString, &pColor,
-                                 *pDoc->GetFormatTable(),
-                                 bShowNullValues,
-                                 bShowFormulas,
-                                 ftCheck );
-
-        rParam.mpEngine->SetText(aString);
-        if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
-            lcl_SetEditColor( *rParam.mpEngine, *pColor );
-    }
 
     if ( bSyntaxMode )
         SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
@@ -3140,51 +3150,9 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     //	Read content from cell
 
     bool bWrapFields = false;
-    if (!rParam.mpCell)
-    {
-        OSL_FAIL("pCell == NULL");
+    if (!rParam.readCellContent(pDoc, bShowNullValues, bShowFormulas, bSyntaxMode, bUseStyleColor, bForceAutoColor, bWrapFields))
+        // Failed to read cell content.  Bail out.
         return;
-    }
-
-    if (rParam.mpCell->GetCellType() == CELLTYPE_EDIT)
-    {
-        const EditTextObject* pData;
-        ((ScEditCell*)rParam.mpCell)->GetData(pData);
-
-        if (pData)
-        {
-            rParam.mpEngine->SetText(*pData);
-
-            if ( rParam.mbBreak && pData->HasField() )
-            {
-                //	Fields aren't wrapped, so clipping is enabled to prevent
-                //	a field from being drawn beyond the cell size
-
-                bWrapFields = true;
-            }
-        }
-        else
-        {
-            OSL_FAIL("pData == 0");
-        }
-    }
-    else
-    {
-        sal_uLong nFormat = rParam.mpPattern->GetNumberFormat(
-                                    pDoc->GetFormatTable(), rParam.mpCondSet );
-        String aString;
-        Color* pColor;
-        ScCellFormat::GetString( rParam.mpCell,
-                                 nFormat,aString, &pColor,
-                                 *pDoc->GetFormatTable(),
-                                 bShowNullValues,
-                                 bShowFormulas,
-                                 ftCheck );
-
-        rParam.mpEngine->SetText(aString);
-        if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
-            lcl_SetEditColor( *rParam.mpEngine, *pColor );
-    }
 
     if ( bSyntaxMode )
         SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
commit 838c39286631e00e1a5bb7882056b1a8bcca6b10
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 10:03:01 2011 -0400

    More cleanups.

diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index de5cb46..e797bca 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -3057,10 +3057,8 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     Size aRefOne = pRefDevice->PixelToLogic(Size(1,1));
 
     vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
-    bool bHidden = false;
     bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
     bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
-    long nAttrRotate = lcl_GetValue<SfxInt32Item, long>(*rParam.mpPattern, ATTR_ROTATE_VALUE, rParam.mpCondSet);
 
     if ( rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT )
     {
@@ -3077,9 +3075,6 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
         eOutHorJust = SVX_HOR_JUSTIFY_LEFT;		// repeat is not yet implemented
 
-    if (bHidden)
-        return;
-
     //!	mirror margin values for RTL?
     //!	move margin down to after final GetOutputArea call
     long nTopM, nLeftM, nBottomM, nRightM;
@@ -3421,15 +3416,6 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
     else
         aLogicStart = Point(nStartX, nStartY);
-    if (!rParam.mbBreak)
-    {
-        long nAvailWidth = aCellSize.Width();
-        // space for AutoFilter is already handled in GetOutputArea
-
-        //	horizontal alignment
-
-        // (do nothing)
-    }
 
     if (rParam.mbBreak)
     {
@@ -3442,7 +3428,6 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
 
     Point aURLStart = aLogicStart;      // copy before modifying for orientation
 
-    short nOriVal = 900; // Angle of orientation
     if (rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK || rParam.mbBreak)
     {
         Size aPSize = rParam.mpEngine->GetPaperSize();
@@ -3512,22 +3497,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         }
     }
 
-    // bMoveClipped handling has been replaced by complete alignment
-    // handling (also extending to the left).
-
-    if ( bSimClip && !nOriVal)
-    {
-        //	kein hartes Clipping, aber nur die betroffenen
-        //	Zeilen ausgeben
-
-        Point aDocStart = aLogicClip.TopLeft();
-        aDocStart -= aLogicStart;
-        rParam.mpEngine->Draw( pDev, aLogicClip, aDocStart, false );
-    }
-    else
-    {
-        rParam.mpEngine->Draw( pDev, aLogicStart, nOriVal );
-    }
+    rParam.mpEngine->Draw(pDev, aLogicStart, 900);
 
     if (bClip)
     {
commit 0ba1a4b3a343e990f4dc2af17666d64227542a7f
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 09:58:44 2011 -0400

    isVerticallyOriented() is always true in this method.

diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 40a5ede..de5cb46 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -3431,7 +3431,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         // (do nothing)
     }
 
-    if (rParam.isVerticallyOriented() && rParam.mbBreak)
+    if (rParam.mbBreak)
     {
         // vertical adjustment is within the EditEngine
         if (rParam.mbPixelToLogic)
@@ -3440,41 +3440,6 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
             aLogicStart.Y() += nTopM;
     }
 
-    if (!rParam.isVerticallyOriented() && !rParam.mbBreak)
-    {
-        if (rParam.meVerJust==SVX_VER_JUSTIFY_BOTTOM ||
-            rParam.meVerJust==SVX_VER_JUSTIFY_STANDARD)
-        {
-            //!	if pRefDevice != pFmtDevice, keep heights in logic units,
-            //! only converting margin?
-
-            if (rParam.mbPixelToLogic)
-                aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0, nTopM +
-                                pRefDevice->LogicToPixel(aCellSize).Height() -
-                                pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
-                                )).Height();
-            else
-                aLogicStart.Y() += nTopM + aCellSize.Height() - nEngineHeight;
-        }
-        else if (rParam.meVerJust==SVX_VER_JUSTIFY_CENTER)
-        {
-            if (rParam.mbPixelToLogic)
-                aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0, nTopM + (
-                                pRefDevice->LogicToPixel(aCellSize).Height() -
-                                pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height() )
-                                / 2)).Height();
-            else
-                aLogicStart.Y() += nTopM + (aCellSize.Height() - nEngineHeight) / 2;
-        }
-        else		// top
-        {
-            if (rParam.mbPixelToLogic)
-                aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
-            else
-                aLogicStart.Y() += nTopM;
-        }
-    }
-
     Point aURLStart = aLogicStart;      // copy before modifying for orientation
 
     short nOriVal = 900; // Angle of orientation
@@ -3584,8 +3549,8 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
             Size aPaper = rParam.mpEngine->GetPaperSize();
             nURLWidth = aPaper.Width();
         }
-        if ( rParam.isVerticallyOriented() )
-            std::swap( nURLWidth, nURLHeight );
+
+        std::swap( nURLWidth, nURLHeight ); // vertical orientation
 
         Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
         lcl_DoHyperlinkResult( pDev, aURLRect, rParam.mpCell );
commit 7a472ef52ca806bc5203426c577a8fc6b44a5709
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 09:54:42 2011 -0400

    Asianl vertical is always false in bottom-top orientation.

diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 01c4f84..40a5ede 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -3070,18 +3070,6 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         return;
     }
 
-    rParam.mbAsianVertical = (rParam.meOrient == SVX_ORIENTATION_STACKED) &&
-        lcl_GetBoolValue(*rParam.mpPattern, ATTR_VERTICAL_ASIAN, rParam.mpCondSet);
-
-    if ( rParam.mbAsianVertical )
-    {
-        // in asian mode, use EditEngine::SetVertical instead of EE_CNTRL_ONECHARPERLINE
-        rParam.meOrient = SVX_ORIENTATION_STANDARD;
-        // default alignment for asian vertical mode is top-right
-        if ( rParam.meHorJust == SVX_HOR_JUSTIFY_STANDARD )
-            rParam.meHorJust = SVX_HOR_JUSTIFY_RIGHT;
-    }
-
     SvxCellHorJustify eOutHorJust =
         ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
         ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
@@ -3132,7 +3120,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     if (rParam.mbPixelToLogic)
     {
         Size aLogicSize = pRefDevice->PixelToLogic(aPaperSize);
-        if ( rParam.mbBreak && !rParam.mbAsianVertical && pRefDevice != pFmtDevice )
+        if ( rParam.mbBreak && pRefDevice != pFmtDevice )
         {
             // #i85342# screen display and formatting for printer,
             // use same GetEditArea call as in ScViewData::SetEditEngine
@@ -3151,10 +3139,6 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     //	Fill the EditEngine (cell attributes and text)
     //
 
-    // default alignment for asian vertical mode is top-right
-    if ( rParam.mbAsianVertical && rParam.meVerJust == SVX_VER_JUSTIFY_STANDARD )
-        rParam.meVerJust = SVX_VER_JUSTIFY_TOP;
-
     rParam.updateEnginePattern(bUseStyleColor);
     rParam.setAlignmentItems();
 
@@ -3176,7 +3160,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         {
             rParam.mpEngine->SetText(*pData);
 
-            if ( rParam.mbBreak && !rParam.mbAsianVertical && pData->HasField() )
+            if ( rParam.mbBreak && pData->HasField() )
             {
                 //	Fields aren't wrapped, so clipping is enabled to prevent
                 //	a field from being drawn beyond the cell size
@@ -3230,7 +3214,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         nNeededPixel = pRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
     nNeededPixel += nLeftM + nRightM;
 
-    if (!rParam.mbBreak || rParam.mbAsianVertical || bShrink)
+    if (!rParam.mbBreak || bShrink)
     {
         // for break, the first GetOutputArea call is sufficient
         GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
@@ -3305,7 +3289,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
     long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
 
-    if ( rParam.mbBreak || rParam.mbAsianVertical )
+    if (rParam.mbBreak)
     {
         //	text with automatic breaks is aligned only within the
         //	edit engine's paper size, the output of the whole area
@@ -3388,8 +3372,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         //	Only with automatic line breaks, to avoid having to find
         //	the cells with the horizontal end of the text again.
         if ( nEngineHeight - aCellSize.Height() > 100 &&
-             rParam.mbBreak &&
-             !rParam.mbAsianVertical && bMarkClipped &&
+             rParam.mbBreak && bMarkClipped &&
              ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
         {
             CellInfo* pClipMarkCell = NULL;
@@ -3438,7 +3421,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
     else
         aLogicStart = Point(nStartX, nStartY);
-    if (rParam.mbAsianVertical || !rParam.mbBreak)
+    if (!rParam.mbBreak)
     {
         long nAvailWidth = aCellSize.Width();
         // space for AutoFilter is already handled in GetOutputArea
@@ -3448,13 +3431,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         // (do nothing)
     }
 
-    if ( rParam.mbAsianVertical )
-    {
-        // paper size is subtracted below
-        aLogicStart.X() += nEngineWidth;
-    }
-
-    if ( (rParam.mbAsianVertical || rParam.isVerticallyOriented()) && rParam.mbBreak )
+    if (rParam.isVerticallyOriented() && rParam.mbBreak)
     {
         // vertical adjustment is within the EditEngine
         if (rParam.mbPixelToLogic)
@@ -3463,7 +3440,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
             aLogicStart.Y() += nTopM;
     }
 
-    if (!rParam.mbAsianVertical && !rParam.isVerticallyOriented() && !rParam.mbBreak)
+    if (!rParam.isVerticallyOriented() && !rParam.mbBreak)
     {
         if (rParam.meVerJust==SVX_VER_JUSTIFY_BOTTOM ||
             rParam.meVerJust==SVX_VER_JUSTIFY_STANDARD)
@@ -3573,7 +3550,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     // bMoveClipped handling has been replaced by complete alignment
     // handling (also extending to the left).
 
-    if ( bSimClip && !nOriVal && !rParam.mbAsianVertical )
+    if ( bSimClip && !nOriVal)
     {
         //	kein hartes Clipping, aber nur die betroffenen
         //	Zeilen ausgeben
@@ -3584,12 +3561,6 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     }
     else
     {
-        if (rParam.mbAsianVertical)
-        {
-            //	with SetVertical, the start position is top left of
-            //	the whole output area, not the text itself
-            aLogicStart.X() -= rParam.mpEngine->GetPaperSize().Width();
-        }
         rParam.mpEngine->Draw( pDev, aLogicStart, nOriVal );
     }
 
@@ -3611,15 +3582,10 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         if ( rParam.mbBreak )
         {
             Size aPaper = rParam.mpEngine->GetPaperSize();
-            if ( rParam.mbAsianVertical )
-                nURLHeight = aPaper.Height();
-            else
-                nURLWidth = aPaper.Width();
+            nURLWidth = aPaper.Width();
         }
         if ( rParam.isVerticallyOriented() )
             std::swap( nURLWidth, nURLHeight );
-        else if ( rParam.mbAsianVertical )
-            aURLStart.X() -= nURLWidth;
 
         Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
         lcl_DoHyperlinkResult( pDev, aURLRect, rParam.mpCell );
commit c30dcda2d961a790ea01d11c5dbbe79f828dc876
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 09:48:40 2011 -0400

    Remove the code that's not relevant to the bottom-top orientation.

diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 1075812..01c4f84 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -3066,18 +3066,8 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     {
         // ignore orientation/rotation if "repeat" is active
         rParam.meOrient = SVX_ORIENTATION_STANDARD;
-        nAttrRotate = 0;
-
-        // #i31843# "repeat" with "line breaks" is treated as default alignment
-        // (but rotation is still disabled)
-        if ( rParam.mbBreak )
-            rParam.meHorJust = SVX_HOR_JUSTIFY_STANDARD;
-    }
-    if ( rParam.meOrient==SVX_ORIENTATION_STANDARD && nAttrRotate )
-    {
-        //!	Flag setzen, um die Zelle in DrawRotated wiederzufinden ?
-        //!	(oder Flag schon bei DrawBackground, dann hier keine Abfrage)
-        bHidden = true;		// gedreht wird getrennt ausgegeben
+        DrawEditStandard(rParam);
+        return;
     }
 
     rParam.mbAsianVertical = (rParam.meOrient == SVX_ORIENTATION_STACKED) &&
@@ -3240,7 +3230,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         nNeededPixel = pRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
     nNeededPixel += nLeftM + nRightM;
 
-    if ( ( !rParam.mbBreak && rParam.meOrient != SVX_ORIENTATION_STACKED ) || rParam.mbAsianVertical || bShrink )
+    if (!rParam.mbBreak || rParam.mbAsianVertical || bShrink)
     {
         // for break, the first GetOutputArea call is sufficient
         GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
@@ -3249,9 +3239,8 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
 
         if ( bShrink )
         {
-            bool bWidth = ( rParam.meOrient == SVX_ORIENTATION_STANDARD && !rParam.mbAsianVertical );
             ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
-                nLeftM, nTopM, nRightM, nBottomM, bWidth,
+                nLeftM, nTopM, nRightM, nBottomM, false,
                 sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
                 nEngineWidth, nEngineHeight, nNeededPixel,
                 aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
@@ -3308,15 +3297,6 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
 
             //	No clip marks if "###" doesn't fit (same as in DrawStrings)
         }
-
-        if ( eOutHorJust != SVX_HOR_JUSTIFY_LEFT && rParam.meOrient == SVX_ORIENTATION_STANDARD )
-        {
-            aPaperSize.Width() = nNeededPixel + 1;
-            if (rParam.mbPixelToLogic)
-                rParam.mpEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
-            else
-                rParam.mpEngine->SetPaperSize(aPaperSize);
-        }
     }
 
     long nStartX = aAreaParam.maAlignRect.Left();
@@ -3325,15 +3305,13 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
     long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
     long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
 
-    if ( rParam.mbBreak || rParam.meOrient != SVX_ORIENTATION_STANDARD || rParam.mbAsianVertical )
+    if ( rParam.mbBreak || rParam.mbAsianVertical )
     {
         //	text with automatic breaks is aligned only within the
         //	edit engine's paper size, the output of the whole area
         //	is always left-aligned
 
         nStartX += nLeftM;
-        if (rParam.meOrient == SVX_ORIENTATION_TOPBOTTOM && rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK)
-            nStartX += aPaperSize.Height();
     }
     else
     {
@@ -3410,7 +3388,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         //	Only with automatic line breaks, to avoid having to find
         //	the cells with the horizontal end of the text again.
         if ( nEngineHeight - aCellSize.Height() > 100 &&
-             ( rParam.mbBreak || rParam.meOrient == SVX_ORIENTATION_STACKED ) &&
+             rParam.mbBreak &&
              !rParam.mbAsianVertical && bMarkClipped &&
              ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
         {
@@ -3460,26 +3438,14 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
         aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
     else
         aLogicStart = Point(nStartX, nStartY);
-    if ( rParam.meOrient!=SVX_ORIENTATION_STANDARD || rParam.mbAsianVertical || !rParam.mbBreak )
+    if (rParam.mbAsianVertical || !rParam.mbBreak)
     {
         long nAvailWidth = aCellSize.Width();
         // space for AutoFilter is already handled in GetOutputArea
 
         //	horizontal alignment
 
-        if (rParam.meOrient==SVX_ORIENTATION_STANDARD && !rParam.mbAsianVertical)
-        {
-            if (rParam.adjustHorAlignment(rParam.mpEngine))
-                // reset adjustment for the next cell
-                rParam.mpOldPattern = NULL;
-        }
-        else if (!rParam.isVerticallyOriented())
-        {
-            if (rParam.meHorJust==SVX_HOR_JUSTIFY_RIGHT)
-                aLogicStart.X() += nAvailWidth - nEngineWidth;
-            else if (rParam.meHorJust==SVX_HOR_JUSTIFY_CENTER)
-                aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
-        }
+        // (do nothing)
     }
 
     if ( rParam.mbAsianVertical )
@@ -3497,8 +3463,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
             aLogicStart.Y() += nTopM;
     }
 
-    if (!rParam.mbAsianVertical && !rParam.isVerticallyOriented() &&
-        (rParam.meOrient == SVX_ORIENTATION_STANDARD || rParam.meOrient == SVX_ORIENTATION_STACKED || !rParam.mbBreak))
+    if (!rParam.mbAsianVertical && !rParam.isVerticallyOriented() && !rParam.mbBreak)
     {
         if (rParam.meVerJust==SVX_VER_JUSTIFY_BOTTOM ||
             rParam.meVerJust==SVX_VER_JUSTIFY_STANDARD)
@@ -3535,120 +3500,62 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
 
     Point aURLStart = aLogicStart;      // copy before modifying for orientation
 
-    short nOriVal = 0; // Angle of orientation
-    if (rParam.meOrient == SVX_ORIENTATION_TOPBOTTOM)
+    short nOriVal = 900; // Angle of orientation
+    if (rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK || rParam.mbBreak)
     {
-        nOriVal = 2700;
-        if (rParam.meHorJust != SVX_HOR_JUSTIFY_BLOCK)
-        {
-            aLogicStart.X() += nEngineWidth;
-            if (!rParam.mbBreak)
-            {
-                // Set the paper width to text size.
-                Size aPSize = rParam.mpEngine->GetPaperSize();
-                aPSize.Width() = rParam.mpEngine->CalcTextWidth();
-                rParam.mpEngine->SetPaperSize(aPSize);
-
-                long nGap = 0;
-                long nTopOffset = 0; // offset by top margin
-                if (rParam.mbPixelToLogic)
-                {
-                    nGap = pRefDevice->LogicToPixel(aPSize).Width() - pRefDevice->LogicToPixel(aCellSize).Height();
-                    nGap = pRefDevice->PixelToLogic(Size(0, nGap)).Height();
-                    nTopOffset = pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
-                }
-                else
-                {
-                    nGap = aPSize.Width() - aCellSize.Height();
-                    nTopOffset = nTopM;
-                }
-                aLogicStart.Y() += nTopOffset;
-
-                switch (rParam.meVerJust)
-                {
-                    case SVX_VER_JUSTIFY_STANDARD:
-                    case SVX_VER_JUSTIFY_BOTTOM:
-                        // align to bottom
-                        aLogicStart.Y() -= nGap;
-                    break;
-                    case SVX_VER_JUSTIFY_CENTER:
-                        // center it.
-                        aLogicStart.Y() -= nGap / 2;
-                    break;
-                    case SVX_VER_JUSTIFY_BLOCK:
-                    case SVX_VER_JUSTIFY_TOP:
-                        // align to top (do nothing)
-                    default:
-                        ;
-                }
-            }
-        }
+        Size aPSize = rParam.mpEngine->GetPaperSize();
+        aPSize.Width() = aCellSize.Height();
+        rParam.mpEngine->SetPaperSize(aPSize);
+        aLogicStart.Y() +=
+            rParam.mbBreak ? aPSize.Width() : nEngineHeight;
     }
-    else if (rParam.meOrient == SVX_ORIENTATION_BOTTOMTOP)
+    else
     {
-        nOriVal = 900;
-        if (rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK || rParam.mbBreak)
+        // Note that the "paper" is rotated 90 degrees to the left, so
+        // paper's width is in vertical direction.  Also, the whole text
+        // is on a single line, as text wrap is not in effect.
+
+        // Set the paper width to be the width of the text.
+        Size aPSize = rParam.mpEngine->GetPaperSize();
+        aPSize.Width() = rParam.mpEngine->CalcTextWidth();
+        rParam.mpEngine->SetPaperSize(aPSize);
+
+        long nGap = 0;
+        long nTopOffset = 0;
+        if (rParam.mbPixelToLogic)
         {
-            Size aPSize = rParam.mpEngine->GetPaperSize();
-            aPSize.Width() = aCellSize.Height();
-            rParam.mpEngine->SetPaperSize(aPSize);
-            aLogicStart.Y() +=
-                rParam.mbBreak ? aPSize.Width() : nEngineHeight;
+            nGap = pRefDevice->LogicToPixel(aCellSize).Height() - pRefDevice->LogicToPixel(aPSize).Width();
+            nGap = pRefDevice->PixelToLogic(Size(0, nGap)).Height();
+            nTopOffset = pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
         }
         else
         {
-            // Note that the "paper" is rotated 90 degrees to the left, so
-            // paper's width is in vertical direction.  Also, the whole text
-            // is on a single line, as text wrap is not in effect.
-
-            // Set the paper width to be the width of the text.
-            Size aPSize = rParam.mpEngine->GetPaperSize();
-            aPSize.Width() = rParam.mpEngine->CalcTextWidth();
-            rParam.mpEngine->SetPaperSize(aPSize);
-
-            long nGap = 0;
-            long nTopOffset = 0;
-            if (rParam.mbPixelToLogic)
-            {
-                nGap = pRefDevice->LogicToPixel(aCellSize).Height() - pRefDevice->LogicToPixel(aPSize).Width();
-                nGap = pRefDevice->PixelToLogic(Size(0, nGap)).Height();
-                nTopOffset = pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
-            }
-            else
-            {
-                nGap = aCellSize.Height() - aPSize.Width();
-                nTopOffset = nTopM;
-            }
+            nGap = aCellSize.Height() - aPSize.Width();
+            nTopOffset = nTopM;
+        }
 
-            // First, align text to bottom.
-            aLogicStart.Y() += aCellSize.Height();
-            aLogicStart.Y() += nTopOffset;
+        // First, align text to bottom.
+        aLogicStart.Y() += aCellSize.Height();
+        aLogicStart.Y() += nTopOffset;
 
-            switch (rParam.meVerJust)
-            {
-                case SVX_VER_JUSTIFY_STANDARD:
-                case SVX_VER_JUSTIFY_BOTTOM:
-                    // align to bottom (do nothing).
-                break;
-                case SVX_VER_JUSTIFY_CENTER:
-                    // center it.
-                    aLogicStart.Y() -= nGap / 2;
-                break;
-                case SVX_VER_JUSTIFY_BLOCK:
-                case SVX_VER_JUSTIFY_TOP:
-                    // align to top
-                    aLogicStart.Y() -= nGap;
-                default:
-                    ;
-            }
+        switch (rParam.meVerJust)
+        {
+            case SVX_VER_JUSTIFY_STANDARD:
+            case SVX_VER_JUSTIFY_BOTTOM:
+                // align to bottom (do nothing).
+            break;
+            case SVX_VER_JUSTIFY_CENTER:
+                // center it.
+                aLogicStart.Y() -= nGap / 2;
+            break;
+            case SVX_VER_JUSTIFY_BLOCK:
+            case SVX_VER_JUSTIFY_TOP:
+                // align to top
+                aLogicStart.Y() -= nGap;
+            default:
+                ;
         }
     }
-    else if (rParam.meOrient == SVX_ORIENTATION_STACKED)
-    {
-        Size aPaperLogic = rParam.mpEngine->GetPaperSize();
-        aPaperLogic.Width() = nEngineWidth;
-        rParam.mpEngine->SetPaperSize(aPaperLogic);
-    }
 
     if ( rParam.mpEngine->IsRightToLeft( 0 ) )
     {
commit 29cbec27176c8c85c017167fde7f2442fa6c4ced
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 09:41:54 2011 -0400

    First, shameless duplication of the guts of DrawEditStandard().

diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index a20bf22..1075812 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -3054,18 +3054,684 @@ void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
 
 void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
 {
+    Size aRefOne = pRefDevice->PixelToLogic(Size(1,1));
+
+    vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+    bool bHidden = false;
+    bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
+    bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
+    long nAttrRotate = lcl_GetValue<SfxInt32Item, long>(*rParam.mpPattern, ATTR_ROTATE_VALUE, rParam.mpCondSet);
+
+    if ( rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT )
+    {
+        // ignore orientation/rotation if "repeat" is active
+        rParam.meOrient = SVX_ORIENTATION_STANDARD;
+        nAttrRotate = 0;
+
+        // #i31843# "repeat" with "line breaks" is treated as default alignment
+        // (but rotation is still disabled)
+        if ( rParam.mbBreak )
+            rParam.meHorJust = SVX_HOR_JUSTIFY_STANDARD;
+    }
+    if ( rParam.meOrient==SVX_ORIENTATION_STANDARD && nAttrRotate )
+    {
+        //!	Flag setzen, um die Zelle in DrawRotated wiederzufinden ?
+        //!	(oder Flag schon bei DrawBackground, dann hier keine Abfrage)
+        bHidden = true;		// gedreht wird getrennt ausgegeben
+    }
+
+    rParam.mbAsianVertical = (rParam.meOrient == SVX_ORIENTATION_STACKED) &&
+        lcl_GetBoolValue(*rParam.mpPattern, ATTR_VERTICAL_ASIAN, rParam.mpCondSet);
+
+    if ( rParam.mbAsianVertical )
+    {
+        // in asian mode, use EditEngine::SetVertical instead of EE_CNTRL_ONECHARPERLINE
+        rParam.meOrient = SVX_ORIENTATION_STANDARD;
+        // default alignment for asian vertical mode is top-right
+        if ( rParam.meHorJust == SVX_HOR_JUSTIFY_STANDARD )
+            rParam.meHorJust = SVX_HOR_JUSTIFY_RIGHT;
+    }
+
+    SvxCellHorJustify eOutHorJust =
+        ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
+        ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
+
+    if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
+        eOutHorJust = SVX_HOR_JUSTIFY_LEFT;		// repeat is not yet implemented
+
+    if (bHidden)
+        return;
+
+    //!	mirror margin values for RTL?
+    //!	move margin down to after final GetOutputArea call
+    long nTopM, nLeftM, nBottomM, nRightM;
+    rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, nPPTX, nPPTY);
+
+    SCCOL nXForPos = rParam.mnX;
+    if ( nXForPos < nX1 )
+    {
+        nXForPos = nX1;
+        rParam.mnPosX = rParam.mnInitPosX;
+    }
+    SCSIZE nArrYForPos = rParam.mnArrY;
+    if ( nArrYForPos < 1 )
+    {
+        nArrYForPos = 1;
+        rParam.mnPosY = nScrY;
+    }
+
+    OutputAreaParam aAreaParam;
+
+    //
+    //	Initial page size - large for normal text, cell size for automatic line breaks
+    //
+
+    Size aPaperSize = Size( 1000000, 1000000 );
+    if (rParam.hasLineBreak())
+    {
+        //	call GetOutputArea with nNeeded=0, to get only the cell width
+
+        //!	handle nArrY == 0
+        GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
+                       *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
+                       rParam.mbCellIsValue, true, false, aAreaParam );
+
+        //! special ScEditUtil handling if formatting for printer
+        rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, nPPTX, nPPTY);
+    }
+    if (rParam.mbPixelToLogic)
+    {
+        Size aLogicSize = pRefDevice->PixelToLogic(aPaperSize);
+        if ( rParam.mbBreak && !rParam.mbAsianVertical && pRefDevice != pFmtDevice )
+        {
+            // #i85342# screen display and formatting for printer,
+            // use same GetEditArea call as in ScViewData::SetEditEngine
+
+            Fraction aFract(1,1);
+            Rectangle aUtilRect = ScEditUtil( pDoc, rParam.mnCellX, rParam.mnCellY, nTab, Point(0,0), pFmtDevice,
+                HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( rParam.mpPattern, false );
+            aLogicSize.Width() = aUtilRect.GetWidth();
+        }
+        rParam.mpEngine->SetPaperSize(aLogicSize);
+    }
+    else
+        rParam.mpEngine->SetPaperSize(aPaperSize);
+
+    //
+    //	Fill the EditEngine (cell attributes and text)
+    //
+
+    // default alignment for asian vertical mode is top-right
+    if ( rParam.mbAsianVertical && rParam.meVerJust == SVX_VER_JUSTIFY_STANDARD )
+        rParam.meVerJust = SVX_VER_JUSTIFY_TOP;
+
+    rParam.updateEnginePattern(bUseStyleColor);
+    rParam.setAlignmentItems();
+
+    //	Read content from cell
+
+    bool bWrapFields = false;
+    if (!rParam.mpCell)
+    {
+        OSL_FAIL("pCell == NULL");
+        return;
+    }
+
+    if (rParam.mpCell->GetCellType() == CELLTYPE_EDIT)
+    {
+        const EditTextObject* pData;
+        ((ScEditCell*)rParam.mpCell)->GetData(pData);
+
+        if (pData)
+        {
+            rParam.mpEngine->SetText(*pData);
+
+            if ( rParam.mbBreak && !rParam.mbAsianVertical && pData->HasField() )
+            {
+                //	Fields aren't wrapped, so clipping is enabled to prevent
+                //	a field from being drawn beyond the cell size
+
+                bWrapFields = true;
+            }
+        }
+        else
+        {
+            OSL_FAIL("pData == 0");
+        }
+    }
+    else
+    {
+        sal_uLong nFormat = rParam.mpPattern->GetNumberFormat(
+                                    pDoc->GetFormatTable(), rParam.mpCondSet );
+        String aString;
+        Color* pColor;
+        ScCellFormat::GetString( rParam.mpCell,
+                                 nFormat,aString, &pColor,
+                                 *pDoc->GetFormatTable(),
+                                 bShowNullValues,
+                                 bShowFormulas,
+                                 ftCheck );
+
+        rParam.mpEngine->SetText(aString);
+        if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
+            lcl_SetEditColor( *rParam.mpEngine, *pColor );
+    }
+
+    if ( bSyntaxMode )
+        SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
+    else if ( bUseStyleColor && bForceAutoColor )
+        lcl_SetEditColor( *rParam.mpEngine, COL_AUTO );		//! or have a flag at EditEngine
+    else
+    {
+        OSL_FAIL("pCell == NULL");
+    }
+
+    rParam.mpEngine->SetUpdateMode( true );		// after SetText, before CalcTextWidth/GetTextHeight
+
+    //
+    //	Get final output area using the calculated width
+    //
+
+    long nEngineWidth, nEngineHeight;
+    rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
+
+    long nNeededPixel = nEngineWidth;
+    if (rParam.mbPixelToLogic)
+        nNeededPixel = pRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
+    nNeededPixel += nLeftM + nRightM;
+
+    if ( ( !rParam.mbBreak && rParam.meOrient != SVX_ORIENTATION_STACKED ) || rParam.mbAsianVertical || bShrink )
+    {
+        // for break, the first GetOutputArea call is sufficient
+        GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
+                       *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
+                       rParam.mbCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
+
+        if ( bShrink )
+        {
+            bool bWidth = ( rParam.meOrient == SVX_ORIENTATION_STANDARD && !rParam.mbAsianVertical );
+            ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
+                nLeftM, nTopM, nRightM, nBottomM, bWidth,
+                sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
+                nEngineWidth, nEngineHeight, nNeededPixel,
+                aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
+        }
+        if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
+        {
+            // First check if twice the space for the formatted text is available
+            // (otherwise just keep it unchanged).
+
+            long nFormatted = nNeededPixel - nLeftM - nRightM;      // without margin
+            long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
+            if ( nAvailable >= 2 * nFormatted )
+            {
+                // "repeat" is handled with unformatted text (for performance reasons)
+                String aCellStr = rParam.mpEngine->GetText();
+                rParam.mpEngine->SetText( aCellStr );
+
+                long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
+                if (rParam.mbPixelToLogic)
+                    nRepeatSize = pRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
+                if ( pFmtDevice != pRefDevice )
+                    ++nRepeatSize;
+                if ( nRepeatSize > 0 )
+                {
+                    long nRepeatCount = nAvailable / nRepeatSize;
+                    if ( nRepeatCount > 1 )
+                    {
+                        String aRepeated = aCellStr;
+                        for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
+                            aRepeated.Append( aCellStr );
+                        rParam.mpEngine->SetText( aRepeated );
+
+                        nEngineHeight = rParam.mpEngine->GetTextHeight();
+                        nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
+                        if (rParam.mbPixelToLogic)
+                            nNeededPixel = pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
+                        else
+                            nNeededPixel = nEngineWidth;
+                        nNeededPixel += nLeftM + nRightM;
+                    }
+                }
+            }
+        }
+
+        if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
+        {
+            rParam.mpEngine->SetText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) );
+            nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
+            if (rParam.mbPixelToLogic)
+                nNeededPixel = pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
+            else
+                nNeededPixel = nEngineWidth;
+            nNeededPixel += nLeftM + nRightM;
+
+            //	No clip marks if "###" doesn't fit (same as in DrawStrings)
+        }
+
+        if ( eOutHorJust != SVX_HOR_JUSTIFY_LEFT && rParam.meOrient == SVX_ORIENTATION_STANDARD )
+        {
+            aPaperSize.Width() = nNeededPixel + 1;
+            if (rParam.mbPixelToLogic)
+                rParam.mpEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
+            else
+                rParam.mpEngine->SetPaperSize(aPaperSize);
+        }
+    }
+
+    long nStartX = aAreaParam.maAlignRect.Left();
+    long nStartY = aAreaParam.maAlignRect.Top();
+    long nCellWidth = aAreaParam.maAlignRect.GetWidth();
+    long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
+    long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
+
+    if ( rParam.mbBreak || rParam.meOrient != SVX_ORIENTATION_STANDARD || rParam.mbAsianVertical )
+    {
+        //	text with automatic breaks is aligned only within the
+        //	edit engine's paper size, the output of the whole area
+        //	is always left-aligned
+
+        nStartX += nLeftM;
+        if (rParam.meOrient == SVX_ORIENTATION_TOPBOTTOM && rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK)
+            nStartX += aPaperSize.Height();
+    }
+    else
+    {
+        if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
+            nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
+        else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
+            nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
+        else
+            nStartX += nLeftM;
+    }
+
+    bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
+    if (bOutside)
+        return;
+
+    if ( aAreaParam.maClipRect.Left() < nScrX )
+    {
+        aAreaParam.maClipRect.Left() = nScrX;
+        aAreaParam.mbLeftClip = true;
+    }
+    if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
+    {
+        aAreaParam.maClipRect.Right() = nScrX + nScrW;			//! minus one?
+        aAreaParam.mbRightClip = true;
+    }
+
+    bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
+    bool bSimClip = false;
+
+    if ( bWrapFields )
+    {
+        //	Fields in a cell with automatic breaks: clip to cell width
+        bClip = true;
+    }
+
+    if ( aAreaParam.maClipRect.Top() < nScrY )
+    {
+        aAreaParam.maClipRect.Top() = nScrY;
+        bClip = true;
+    }
+    if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
+    {
+        aAreaParam.maClipRect.Bottom() = nScrY + nScrH;     //! minus one?
+        bClip = true;
+    }
+
+    Size aCellSize;			// output area, excluding margins, in logical units
+    if (rParam.mbPixelToLogic)
+        aCellSize = pRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
+    else
+        aCellSize = Size( nOutWidth, nOutHeight );
+
+    if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
+    {
+        const ScMergeAttr* pMerge =
+                (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
+        bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
+
+        //	Don't clip for text height when printing rows with optimal height,
+        //	except when font size is from conditional formatting.
+        //!	Allow clipping when vertically merged?
+        if ( eType != OUTTYPE_PRINTER ||
+            ( pDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
+            ( rParam.mpCondSet && SFX_ITEM_SET ==
+                rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
+            bClip = true;
+        else
+            bSimClip = true;
+
+        //	Show clip marks if height is at least 5pt too small and
+        //	there are several lines of text.
+        //	Not for asian vertical text, because that would interfere
+        //	with the default right position of the text.
+        //	Only with automatic line breaks, to avoid having to find
+        //	the cells with the horizontal end of the text again.
+        if ( nEngineHeight - aCellSize.Height() > 100 &&
+             ( rParam.mbBreak || rParam.meOrient == SVX_ORIENTATION_STACKED ) &&
+             !rParam.mbAsianVertical && bMarkClipped &&
+             ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
+        {
+            CellInfo* pClipMarkCell = NULL;
+            if ( bMerged )
+            {
+                //	anywhere in the merged area...
+                SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
+                pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
+            }
+            else
+                pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
+
+            pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT;		//! also allow left?
+            bAnyClipped = true;
+
+            long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
+            if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
+                aAreaParam.maClipRect.Right() -= nMarkPixel;
+        }
+    }
+
+    Rectangle aLogicClip;
+    if (bClip || bSimClip)
+    {
+        // Clip marks are already handled in GetOutputArea
+
+        if (rParam.mbPixelToLogic)
+            aLogicClip = pRefDevice->PixelToLogic( aAreaParam.maClipRect );
+        else
+            aLogicClip = aAreaParam.maClipRect;
+
+        if (bClip)	// bei bSimClip nur aClipRect initialisieren
+        {
+            if (bMetaFile)
+            {
+                pDev->Push();
+                pDev->IntersectClipRegion( aLogicClip );
+            }
+            else
+                pDev->SetClipRegion( Region( aLogicClip ) );
+        }
+    }
+
+    Point aLogicStart;
+    if (rParam.mbPixelToLogic)
+        aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
+    else
+        aLogicStart = Point(nStartX, nStartY);
+    if ( rParam.meOrient!=SVX_ORIENTATION_STANDARD || rParam.mbAsianVertical || !rParam.mbBreak )
+    {
+        long nAvailWidth = aCellSize.Width();
+        // space for AutoFilter is already handled in GetOutputArea
+
+        //	horizontal alignment
+
+        if (rParam.meOrient==SVX_ORIENTATION_STANDARD && !rParam.mbAsianVertical)
+        {
+            if (rParam.adjustHorAlignment(rParam.mpEngine))
+                // reset adjustment for the next cell
+                rParam.mpOldPattern = NULL;
+        }
+        else if (!rParam.isVerticallyOriented())
+        {
+            if (rParam.meHorJust==SVX_HOR_JUSTIFY_RIGHT)
+                aLogicStart.X() += nAvailWidth - nEngineWidth;
+            else if (rParam.meHorJust==SVX_HOR_JUSTIFY_CENTER)
+                aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
+        }
+    }
+
+    if ( rParam.mbAsianVertical )
+    {
+        // paper size is subtracted below
+        aLogicStart.X() += nEngineWidth;
+    }
+
+    if ( (rParam.mbAsianVertical || rParam.isVerticallyOriented()) && rParam.mbBreak )
+    {
+        // vertical adjustment is within the EditEngine
+        if (rParam.mbPixelToLogic)
+            aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+        else
+            aLogicStart.Y() += nTopM;
+    }
+
+    if (!rParam.mbAsianVertical && !rParam.isVerticallyOriented() &&
+        (rParam.meOrient == SVX_ORIENTATION_STANDARD || rParam.meOrient == SVX_ORIENTATION_STACKED || !rParam.mbBreak))
+    {
+        if (rParam.meVerJust==SVX_VER_JUSTIFY_BOTTOM ||
+            rParam.meVerJust==SVX_VER_JUSTIFY_STANDARD)
+        {
+            //!	if pRefDevice != pFmtDevice, keep heights in logic units,
+            //! only converting margin?
+
+            if (rParam.mbPixelToLogic)
+                aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0, nTopM +
+                                pRefDevice->LogicToPixel(aCellSize).Height() -
+                                pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
+                                )).Height();
+            else
+                aLogicStart.Y() += nTopM + aCellSize.Height() - nEngineHeight;
+        }
+        else if (rParam.meVerJust==SVX_VER_JUSTIFY_CENTER)
+        {
+            if (rParam.mbPixelToLogic)
+                aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0, nTopM + (
+                                pRefDevice->LogicToPixel(aCellSize).Height() -
+                                pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height() )
+                                / 2)).Height();
+            else
+                aLogicStart.Y() += nTopM + (aCellSize.Height() - nEngineHeight) / 2;
+        }
+        else		// top
+        {
+            if (rParam.mbPixelToLogic)
+                aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+            else
+                aLogicStart.Y() += nTopM;
+        }
+    }
+
+    Point aURLStart = aLogicStart;      // copy before modifying for orientation
+
+    short nOriVal = 0; // Angle of orientation
+    if (rParam.meOrient == SVX_ORIENTATION_TOPBOTTOM)
+    {
+        nOriVal = 2700;
+        if (rParam.meHorJust != SVX_HOR_JUSTIFY_BLOCK)
+        {
+            aLogicStart.X() += nEngineWidth;
+            if (!rParam.mbBreak)
+            {
+                // Set the paper width to text size.
+                Size aPSize = rParam.mpEngine->GetPaperSize();
+                aPSize.Width() = rParam.mpEngine->CalcTextWidth();
+                rParam.mpEngine->SetPaperSize(aPSize);
+
+                long nGap = 0;
+                long nTopOffset = 0; // offset by top margin
+                if (rParam.mbPixelToLogic)
+                {
+                    nGap = pRefDevice->LogicToPixel(aPSize).Width() - pRefDevice->LogicToPixel(aCellSize).Height();
+                    nGap = pRefDevice->PixelToLogic(Size(0, nGap)).Height();
+                    nTopOffset = pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+                }
+                else
+                {
+                    nGap = aPSize.Width() - aCellSize.Height();
+                    nTopOffset = nTopM;
+                }
+                aLogicStart.Y() += nTopOffset;
+
+                switch (rParam.meVerJust)
+                {
+                    case SVX_VER_JUSTIFY_STANDARD:
+                    case SVX_VER_JUSTIFY_BOTTOM:
+                        // align to bottom
+                        aLogicStart.Y() -= nGap;
+                    break;
+                    case SVX_VER_JUSTIFY_CENTER:
+                        // center it.
+                        aLogicStart.Y() -= nGap / 2;
+                    break;
+                    case SVX_VER_JUSTIFY_BLOCK:
+                    case SVX_VER_JUSTIFY_TOP:
+                        // align to top (do nothing)
+                    default:
+                        ;
+                }
+            }
+        }
+    }
+    else if (rParam.meOrient == SVX_ORIENTATION_BOTTOMTOP)
+    {
+        nOriVal = 900;
+        if (rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK || rParam.mbBreak)
+        {
+            Size aPSize = rParam.mpEngine->GetPaperSize();
+            aPSize.Width() = aCellSize.Height();
+            rParam.mpEngine->SetPaperSize(aPSize);
+            aLogicStart.Y() +=
+                rParam.mbBreak ? aPSize.Width() : nEngineHeight;
+        }
+        else
+        {
+            // Note that the "paper" is rotated 90 degrees to the left, so
+            // paper's width is in vertical direction.  Also, the whole text
+            // is on a single line, as text wrap is not in effect.
+
+            // Set the paper width to be the width of the text.
+            Size aPSize = rParam.mpEngine->GetPaperSize();
+            aPSize.Width() = rParam.mpEngine->CalcTextWidth();
+            rParam.mpEngine->SetPaperSize(aPSize);
+
+            long nGap = 0;
+            long nTopOffset = 0;
+            if (rParam.mbPixelToLogic)
+            {
+                nGap = pRefDevice->LogicToPixel(aCellSize).Height() - pRefDevice->LogicToPixel(aPSize).Width();
+                nGap = pRefDevice->PixelToLogic(Size(0, nGap)).Height();
+                nTopOffset = pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+            }
+            else
+            {
+                nGap = aCellSize.Height() - aPSize.Width();
+                nTopOffset = nTopM;
+            }
+
+            // First, align text to bottom.
+            aLogicStart.Y() += aCellSize.Height();
+            aLogicStart.Y() += nTopOffset;
+
+            switch (rParam.meVerJust)
+            {
+                case SVX_VER_JUSTIFY_STANDARD:
+                case SVX_VER_JUSTIFY_BOTTOM:
+                    // align to bottom (do nothing).
+                break;
+                case SVX_VER_JUSTIFY_CENTER:
+                    // center it.
+                    aLogicStart.Y() -= nGap / 2;
+                break;
+                case SVX_VER_JUSTIFY_BLOCK:
+                case SVX_VER_JUSTIFY_TOP:
+                    // align to top
+                    aLogicStart.Y() -= nGap;
+                default:
+                    ;
+            }
+        }
+    }
+    else if (rParam.meOrient == SVX_ORIENTATION_STACKED)
+    {
+        Size aPaperLogic = rParam.mpEngine->GetPaperSize();
+        aPaperLogic.Width() = nEngineWidth;
+        rParam.mpEngine->SetPaperSize(aPaperLogic);
+    }
+
+    if ( rParam.mpEngine->IsRightToLeft( 0 ) )
+    {
+        //	For right-to-left, EditEngine always calculates its lines
+        //	beginning from the right edge, but EditLine::nStartPosX is
+        //	of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
+        Size aLogicPaper = rParam.mpEngine->GetPaperSize();
+        if ( aLogicPaper.Width() > USHRT_MAX )
+        {
+            aLogicPaper.Width() = USHRT_MAX;
+            rParam.mpEngine->SetPaperSize(aLogicPaper);
+        }
+    }
+
+    // bMoveClipped handling has been replaced by complete alignment
+    // handling (also extending to the left).
+
+    if ( bSimClip && !nOriVal && !rParam.mbAsianVertical )
+    {
+        //	kein hartes Clipping, aber nur die betroffenen
+        //	Zeilen ausgeben
+
+        Point aDocStart = aLogicClip.TopLeft();
+        aDocStart -= aLogicStart;
+        rParam.mpEngine->Draw( pDev, aLogicClip, aDocStart, false );
+    }
+    else
+    {
+        if (rParam.mbAsianVertical)
+        {
+            //	with SetVertical, the start position is top left of
+            //	the whole output area, not the text itself
+            aLogicStart.X() -= rParam.mpEngine->GetPaperSize().Width();
+        }
+        rParam.mpEngine->Draw( pDev, aLogicStart, nOriVal );
+    }
+
+    if (bClip)
+    {
+        if (bMetaFile)
+            pDev->Pop();
+        else
+            pDev->SetClipRegion();
+    }
+
+    // PDF: whole-cell hyperlink from formula?
+    bool bHasURL = pPDFData && rParam.mpCell && rParam.mpCell->GetCellType() == CELLTYPE_FORMULA &&
+                    static_cast<ScFormulaCell*>(rParam.mpCell)->IsHyperLinkCell();
+    if ( bHasURL )
+    {
+        long nURLWidth = (long) rParam.mpEngine->CalcTextWidth();
+        long nURLHeight = rParam.mpEngine->GetTextHeight();
+        if ( rParam.mbBreak )
+        {
+            Size aPaper = rParam.mpEngine->GetPaperSize();
+            if ( rParam.mbAsianVertical )
+                nURLHeight = aPaper.Height();
+            else
+                nURLWidth = aPaper.Width();
+        }
+        if ( rParam.isVerticallyOriented() )
+            std::swap( nURLWidth, nURLHeight );
+        else if ( rParam.mbAsianVertical )
+            aURLStart.X() -= nURLWidth;
+
+        Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
+        lcl_DoHyperlinkResult( pDev, aURLRect, rParam.mpCell );
+    }
 }
 
 void ScOutputData::DrawEditTopBottom(DrawEditParam& rParam)
 {
+    DrawEditStandard(rParam);
 }
 
 void ScOutputData::DrawEditStacked(DrawEditParam& rParam)
 {
+    DrawEditStandard(rParam);
 }
 
 void ScOutputData::DrawEditAsianVertical(DrawEditParam& rParam)
 {
+    DrawEditStandard(rParam);
 }
 
 void ScOutputData::DrawEdit(sal_Bool bPixelToLogic)
@@ -3216,7 +3882,10 @@ void ScOutputData::DrawEdit(sal_Bool bPixelToLogic)
                         aParam.mpOldPattern = pOldPattern;
                         aParam.mpOldCondSet = pOldCondSet;
                         aParam.mpThisRowInfo = pThisRowInfo;
-                        DrawEditStandard(aParam);
+                        if (aParam.meOrient == SVX_ORIENTATION_BOTTOMTOP)
+                            DrawEditBottomTop(aParam);
+                        else
+                            DrawEditStandard(aParam);
 
                         // Retrieve parameters for next iteration.
                         pOldPattern = aParam.mpOldPattern;
commit 82b322d4ba92d7241da1a74da6707b600954fc9f
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 09:34:08 2011 -0400

    Added empty methods for each orientation.
    
    We can't maintain this monster method that processes all orientations
    in a single function.  We need to split it up.

diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index dc75ef5..e20de15 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -237,6 +237,10 @@ private:
     drawinglayer::processor2d::BaseProcessor2D*  CreateProcessor2D( );
 
     void DrawEditStandard(DrawEditParam& rParam);
+    void DrawEditBottomTop(DrawEditParam& rParam);
+    void DrawEditTopBottom(DrawEditParam& rParam);
+    void DrawEditStacked(DrawEditParam& rParam);
+    void DrawEditAsianVertical(DrawEditParam& rParam);
 
 public:
                     ScOutputData( OutputDevice* pNewDev, ScOutputType eNewType,
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 81ea4b0..a20bf22 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -2806,7 +2806,7 @@ void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
                 // reset adjustment for the next cell
                 rParam.mpOldPattern = NULL;
         }
-        else
+        else if (!rParam.isVerticallyOriented())
         {
             if (rParam.meHorJust==SVX_HOR_JUSTIFY_RIGHT)
                 aLogicStart.X() += nAvailWidth - nEngineWidth;
@@ -3052,6 +3052,22 @@ void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
     }
 }
 
+void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
+{
+}
+
+void ScOutputData::DrawEditTopBottom(DrawEditParam& rParam)
+{
+}
+
+void ScOutputData::DrawEditStacked(DrawEditParam& rParam)
+{
+}
+
+void ScOutputData::DrawEditAsianVertical(DrawEditParam& rParam)
+{
+}
+
 void ScOutputData::DrawEdit(sal_Bool bPixelToLogic)
 {
     ScFieldEditEngine* pEngine = NULL;
commit 2b188ebff2346e8f960a870a1c87f0dc4f90c17a
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 00:32:26 2011 -0400

    Remove silliness of passing own data members as params to its own method.

diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index 09de726..dc75ef5 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -130,7 +130,7 @@ private:
          */
         bool isVerticallyOriented() const;
 
-        void setAlignmentItems(ScFieldEditEngine* pEngine, ScBaseCell* pCell);
+        void setAlignmentItems();
         bool adjustHorAlignment(ScFieldEditEngine* pEngine);
     };
 
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 204fc8a..81ea4b0 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -2260,7 +2260,7 @@ bool ScOutputData::DrawEditParam::isVerticallyOriented() const
     return (meOrient == SVX_ORIENTATION_TOPBOTTOM || meOrient == SVX_ORIENTATION_BOTTOMTOP);
 }
 
-void ScOutputData::DrawEditParam::setAlignmentItems(ScFieldEditEngine* pEngine, ScBaseCell* pCell)
+void ScOutputData::DrawEditParam::setAlignmentItems()
 {
     if (isVerticallyOriented() || mbAsianVertical)
     {
@@ -2284,11 +2284,11 @@ void ScOutputData::DrawEditParam::setAlignmentItems(ScFieldEditEngine* pEngine,
                 break;
         }
 
-        pEngine->SetDefaultItem( SvxAdjustItem(eSvxAdjust, EE_PARA_JUST) );
-        pEngine->SetDefaultItem( SvxJustifyMethodItem(meVerJustMethod, EE_PARA_JUST_METHOD) );
+        mpEngine->SetDefaultItem( SvxAdjustItem(eSvxAdjust, EE_PARA_JUST) );
+        mpEngine->SetDefaultItem( SvxJustifyMethodItem(meVerJustMethod, EE_PARA_JUST_METHOD) );
 
         if (meHorJust == SVX_HOR_JUSTIFY_BLOCK)
-            pEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
+            mpEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
     }
     else
     {
@@ -2340,29 +2340,29 @@ void ScOutputData::DrawEditParam::setAlignmentItems(ScFieldEditEngine* pEngine,
                 }
         }
 
-        pEngine->SetDefaultItem( SvxAdjustItem(eSvxAdjust, EE_PARA_JUST) );
+        mpEngine->SetDefaultItem( SvxAdjustItem(eSvxAdjust, EE_PARA_JUST) );
 
         if (mbAsianVertical)
         {
-            pEngine->SetDefaultItem( SvxJustifyMethodItem(meVerJustMethod, EE_PARA_JUST_METHOD) );
+            mpEngine->SetDefaultItem( SvxJustifyMethodItem(meVerJustMethod, EE_PARA_JUST_METHOD) );
             if (meHorJust == SVX_HOR_JUSTIFY_BLOCK)
-                pEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
+                mpEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
         }
         else
         {
-            pEngine->SetDefaultItem( SvxJustifyMethodItem(meHorJustMethod, EE_PARA_JUST_METHOD) );
+            mpEngine->SetDefaultItem( SvxJustifyMethodItem(meHorJustMethod, EE_PARA_JUST_METHOD) );
             if (meVerJust == SVX_VER_JUSTIFY_BLOCK)
-                pEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
+                mpEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
         }
     }
 
-    pEngine->SetVertical(mbAsianVertical);
-    if (pCell && pCell->GetCellType() == CELLTYPE_EDIT)
+    mpEngine->SetVertical(mbAsianVertical);
+    if (mpCell && mpCell->GetCellType() == CELLTYPE_EDIT)
     {
         // We need to synchronize the vertical mode in the EditTextObject
         // instance too.  No idea why we keep this state in two separate
         // instances.
-        ScEditCell* pEditCell = static_cast<ScEditCell*>(pCell);
+        ScEditCell* pEditCell = static_cast<ScEditCell*>(mpCell);
         const EditTextObject* pData = pEditCell->GetData();
         if (pData)
             const_cast<EditTextObject*>(pData)->SetVertical(mbAsianVertical);
@@ -2499,8 +2499,7 @@ void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
         rParam.meVerJust = SVX_VER_JUSTIFY_TOP;
 
     rParam.updateEnginePattern(bUseStyleColor);
-
-    rParam.setAlignmentItems(rParam.mpEngine, rParam.mpCell);
+    rParam.setAlignmentItems();
 
     //	Read content from cell
 
commit 5aeabb0db83b223294b77391822c0c8a16c2e996
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Apr 6 00:29:34 2011 -0400

    Fixed vertical alignment when the auto wrap is on.
    
    Also extracted a method.

diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index 0db97d0..09de726 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -116,6 +116,7 @@ private:
 

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list