diff options
Diffstat (limited to 'sd/source/ui/slidesorter/view/SlsLayouter.cxx')
-rwxr-xr-x | sd/source/ui/slidesorter/view/SlsLayouter.cxx | 758 |
1 files changed, 758 insertions, 0 deletions
diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx new file mode 100755 index 000000000000..3767a655c48b --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -0,0 +1,758 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "view/SlsLayouter.hxx" + +#include <vcl/outdev.hxx> +#include <rtl/math.hxx> + +namespace sd { namespace slidesorter { namespace view { + +Layouter::Layouter (void) + : mnRequestedLeftBorder(10), + mnRequestedRightBorder(10), + mnRequestedTopBorder(10), + mnRequestedBottomBorder(10), + mnLeftBorder(10), + mnRightBorder(10), + mnTopBorder(10), + mnBottomBorder(10), + mnLeftPageBorder(0), + mnRightPageBorder(0), + mnTopPageBorder(0), + mnBottomPageBorder(0), + mnVerticalGap (20), + mnHorizontalGap (20), + mnInsertionMarkerThickness (4), + mnTotalVerticalGap(0), + mnTotalHorizontalGap(0), + mnMinimalWidth (100), + mnPreferredWidth (200), + mnMaximalWidth (300), + mnMinimalColumnCount (1), + mnMaximalColumnCount (5), + mnColumnCount (1), + maPageObjectModelSize (1,1), + maPageObjectPixelSize (1,1) +{ +} + + + + +Layouter::~Layouter (void) +{ +} + + +void Layouter::SetBorders ( + sal_Int32 nLeftBorder, + sal_Int32 nRightBorder, + sal_Int32 nTopBorder, + sal_Int32 nBottomBorder) +{ + if (nLeftBorder >= 0) + mnRequestedLeftBorder.mnScreen = nLeftBorder; + if (nRightBorder >= 0) + mnRequestedRightBorder.mnScreen = nRightBorder; + if (nTopBorder >= 0) + mnRequestedTopBorder.mnScreen = nTopBorder; + if (nBottomBorder >= 0) + mnRequestedBottomBorder.mnScreen = nBottomBorder; +} + + + + +void Layouter::SetPageBorders ( + sal_Int32 nLeftBorder, + sal_Int32 nRightBorder, + sal_Int32 nTopBorder, + sal_Int32 nBottomBorder) +{ + if (nLeftBorder >= 0) + mnLeftPageBorder.mnScreen = nLeftBorder; + if (nRightBorder >= 0) + mnRightPageBorder.mnScreen = nRightBorder; + if (nTopBorder >= 0) + mnTopPageBorder.mnScreen = nTopBorder; + if (nBottomBorder >= 0) + mnBottomPageBorder.mnScreen = nBottomBorder; +} + + + + +void Layouter::SetColumnCount ( + sal_Int32 nMinimalColumnCount, + sal_Int32 nMaximalColumnCount) +{ + if (nMinimalColumnCount <= nMaximalColumnCount) + { + mnMinimalColumnCount = nMinimalColumnCount; + mnMaximalColumnCount = nMaximalColumnCount; + } +} + + + + +bool Layouter::RearrangeHorizontal ( + const Size& rWindowSize, + const Size& rPageObjectSize, + OutputDevice* pDevice, + const sal_uInt32 nPageCount) +{ + if (rWindowSize.Width() > 0 + && rWindowSize.Height() > 0 + && rPageObjectSize.Width() > 0 + && rPageObjectSize.Height() > 0) + { + mnTotalHorizontalGap.mnScreen = mnHorizontalGap.mnScreen + + mnRightPageBorder.mnScreen + mnLeftPageBorder.mnScreen; + mnTotalVerticalGap.mnScreen = mnVerticalGap.mnScreen + + mnTopPageBorder.mnScreen + mnBottomPageBorder.mnScreen; + + // Calculate the column count. + mnColumnCount = nPageCount; + + // Update the border values. The insertion marker has to have space. + mnLeftBorder.mnScreen = mnRequestedLeftBorder.mnScreen; + mnTopBorder.mnScreen = mnRequestedTopBorder.mnScreen; + mnRightBorder.mnScreen = mnRequestedRightBorder.mnScreen; + mnBottomBorder.mnScreen = mnRequestedBottomBorder.mnScreen; + if (mnColumnCount > 1) + { + int nMinimumBorderWidth = mnInsertionMarkerThickness.mnScreen + + mnHorizontalGap.mnScreen/2; + if (mnLeftBorder.mnScreen < nMinimumBorderWidth) + mnLeftBorder.mnScreen = nMinimumBorderWidth; + if (mnRightBorder.mnScreen < nMinimumBorderWidth) + mnRightBorder.mnScreen = nMinimumBorderWidth; + } + else + { + int nMinimumBorderHeight = mnInsertionMarkerThickness.mnScreen + + mnVerticalGap.mnScreen/2; + if (mnTopBorder.mnScreen < nMinimumBorderHeight) + mnTopBorder.mnScreen = nMinimumBorderHeight; + if (mnBottomBorder.mnScreen < nMinimumBorderHeight) + mnBottomBorder.mnScreen = nMinimumBorderHeight; + } + + // Calculate the width of each page object. + sal_uInt32 nTargetHeight = 0; + sal_uInt32 nRowCount = 1; + if (mnColumnCount > 0) + nTargetHeight = (rWindowSize.Height() + - mnTopBorder.mnScreen + - mnBottomBorder.mnScreen + - nRowCount * (mnTopPageBorder.mnScreen + + mnBottomPageBorder.mnScreen) + - (nRowCount-1) * mnTotalVerticalGap.mnScreen + ) + / nRowCount; + sal_uInt32 nMinimalHeight ( + mnMinimalWidth * rPageObjectSize.Height() / rPageObjectSize.Width()); + sal_uInt32 nMaximalHeight ( + mnMaximalWidth * rPageObjectSize.Height() / rPageObjectSize.Width()); + if (nTargetHeight < nMinimalHeight) + nTargetHeight = nMinimalHeight; + if (nTargetHeight > nMaximalHeight) + nTargetHeight = nMaximalHeight; + + // Initialize the device with some arbitrary zoom factor just in + // case that the current zoom factor is numerically instable when + // used in a multiplication. + MapMode aMapMode (pDevice->GetMapMode()); + aMapMode.SetScaleX (Fraction(1,1)); + aMapMode.SetScaleY (Fraction(1,1)); + pDevice->SetMapMode (aMapMode); + + // Calculate the resulting scale factor and the page object size in + // pixels. + maPageObjectModelSize = rPageObjectSize; + int nPagePixelHeight (pDevice->LogicToPixel(maPageObjectModelSize).Height()); + + // Adapt the layout of the given output device to the new layout of + // page objects. The zoom factor is set so that the page objects in + // one column fill the screen. + Fraction aScaleFactor (nTargetHeight, nPagePixelHeight); + SetZoom (aMapMode.GetScaleX() * aScaleFactor, pDevice); + + return true; + } + else + return false; +} + + + + +bool Layouter::RearrangeVertical ( + const Size& rWindowSize, + const Size& rPageObjectSize, + OutputDevice* pDevice) +{ + if (rWindowSize.Width() > 0 + && rWindowSize.Height() > 0 + && rPageObjectSize.Width() > 0 + && rPageObjectSize.Height() > 0) + { + mnTotalHorizontalGap.mnScreen = mnHorizontalGap.mnScreen + + mnRightPageBorder.mnScreen + mnLeftPageBorder.mnScreen; + mnTotalVerticalGap.mnScreen = mnVerticalGap.mnScreen + + mnTopPageBorder.mnScreen + mnBottomPageBorder.mnScreen; + + // Calculate the column count. + mnColumnCount = (rWindowSize.Width() + - mnRequestedLeftBorder.mnScreen - mnRequestedRightBorder.mnScreen) + / (mnPreferredWidth + mnTotalHorizontalGap.mnScreen); + if (mnColumnCount < mnMinimalColumnCount) + mnColumnCount = mnMinimalColumnCount; + if (mnColumnCount > mnMaximalColumnCount) + mnColumnCount = mnMaximalColumnCount; + + // Update the border values. The insertion marker has to have space. + mnLeftBorder.mnScreen = mnRequestedLeftBorder.mnScreen; + mnTopBorder.mnScreen = mnRequestedTopBorder.mnScreen; + mnRightBorder.mnScreen = mnRequestedRightBorder.mnScreen; + mnBottomBorder.mnScreen = mnRequestedBottomBorder.mnScreen; + if (mnColumnCount > 1) + { + int nMinimumBorderWidth = mnInsertionMarkerThickness.mnScreen + + mnHorizontalGap.mnScreen/2; + if (mnLeftBorder.mnScreen < nMinimumBorderWidth) + mnLeftBorder.mnScreen = nMinimumBorderWidth; + if (mnRightBorder.mnScreen < nMinimumBorderWidth) + mnRightBorder.mnScreen = nMinimumBorderWidth; + } + else + { + int nMinimumBorderHeight = mnInsertionMarkerThickness.mnScreen + + mnVerticalGap.mnScreen/2; + if (mnTopBorder.mnScreen < nMinimumBorderHeight) + mnTopBorder.mnScreen = nMinimumBorderHeight; + if (mnBottomBorder.mnScreen < nMinimumBorderHeight) + mnBottomBorder.mnScreen = nMinimumBorderHeight; + } + + // Calculate the width of each page object. + sal_Int32 nTargetWidth = 0; + if (mnColumnCount > 0) + nTargetWidth = (rWindowSize.Width() + - mnLeftBorder.mnScreen + - mnRightBorder.mnScreen + - mnColumnCount * (mnRightPageBorder.mnScreen + + mnLeftPageBorder.mnScreen) + - (mnColumnCount-1) * mnTotalHorizontalGap.mnScreen + ) + / mnColumnCount; + if (nTargetWidth < mnMinimalWidth) + nTargetWidth = mnMinimalWidth; + if (nTargetWidth > mnMaximalWidth) + nTargetWidth = mnMaximalWidth; + + // Initialize the device with some arbitrary zoom factor just in + // case that the current zoom factor is numerically instable when + // used in a multiplication. + MapMode aMapMode (pDevice->GetMapMode()); + aMapMode.SetScaleX (Fraction(1,1)); + aMapMode.SetScaleY (Fraction(1,1)); + pDevice->SetMapMode (aMapMode); + + // Calculate the resulting scale factor and the page object size in + // pixels. + maPageObjectModelSize = rPageObjectSize; + int nPagePixelWidth (pDevice->LogicToPixel (maPageObjectModelSize).Width()); + + // Adapt the layout of the given output device to the new layout of + // page objects. The zoom factor is set so that the page objects in + // one row fill the screen. + Fraction aScaleFactor (nTargetWidth, nPagePixelWidth); + SetZoom (aMapMode.GetScaleX() * aScaleFactor, pDevice); + + return true; + } + else + return false; +} + + + + +void Layouter::SetZoom (Fraction nZoomFactor, OutputDevice* pDevice) +{ + MapMode aMapMode (pDevice->GetMapMode()); + aMapMode.SetScaleX (nZoomFactor); + aMapMode.SetScaleY (nZoomFactor); + maPageObjectPixelSize = pDevice->LogicToPixel (maPageObjectModelSize); + pDevice->SetMapMode (aMapMode); + + // Transform frequently used values from pixel to model coordinates. + + Size aTotalGap (pDevice->PixelToLogic (Size ( + mnTotalHorizontalGap.mnScreen, + mnTotalVerticalGap.mnScreen))); + mnTotalHorizontalGap.mnModel = aTotalGap.Width(); + mnTotalVerticalGap.mnModel = aTotalGap.Height(); + + Size aGap (pDevice->PixelToLogic (Size ( + mnHorizontalGap.mnScreen, + mnVerticalGap.mnScreen))); + mnHorizontalGap.mnModel = aGap.Width(); + mnVerticalGap.mnModel = aGap.Height(); + + Size aTopLeftBorder (pDevice->PixelToLogic (Size ( + mnLeftBorder.mnScreen, + mnTopBorder.mnScreen))); + mnLeftBorder.mnModel = aTopLeftBorder.Width(); + mnTopBorder.mnModel = aTopLeftBorder.Height(); + + Size aBottomRightBorder (pDevice->PixelToLogic (Size ( + mnLeftBorder.mnScreen, + mnTopBorder.mnScreen))); + mnRightBorder.mnModel = aBottomRightBorder.Width(); + mnBottomBorder.mnModel = aBottomRightBorder.Height(); + + Size aTopLeftPageBorder (pDevice->PixelToLogic (Size ( + mnLeftPageBorder.mnScreen, + mnTopPageBorder.mnScreen))); + mnLeftPageBorder.mnModel = aTopLeftPageBorder.Width(); + mnTopPageBorder.mnModel = aTopLeftPageBorder.Height(); + + Size aBottomRightPageBorder (pDevice->PixelToLogic (Size ( + mnRightPageBorder.mnScreen, + mnBottomPageBorder.mnScreen))); + mnRightPageBorder.mnModel = aBottomRightPageBorder.Width(); + mnBottomPageBorder.mnModel = aBottomRightPageBorder.Height(); + + mnInsertionMarkerThickness.mnModel = pDevice->PixelToLogic ( + Size(mnInsertionMarkerThickness.mnScreen,0)).Width(); +} + + + + +sal_Int32 Layouter::GetColumnCount (void) const +{ + return mnColumnCount; +} + + + + +Size Layouter::GetPageObjectSize (void) const +{ + return maPageObjectModelSize; +} + + + + +Rectangle Layouter::GetPageObjectBox (sal_Int32 nIndex) const +{ + int nColumn = nIndex % mnColumnCount; + int nRow = nIndex / mnColumnCount; + return Rectangle ( + Point (mnLeftBorder.mnModel + + nColumn * maPageObjectModelSize.Width() + + mnLeftPageBorder.mnModel + + (nColumn>0 ? nColumn : 0) * mnTotalHorizontalGap.mnModel, + mnTopBorder.mnModel + + nRow * maPageObjectModelSize.Height() + + mnTopPageBorder.mnModel + + (nRow>0 ? nRow : 0) * mnTotalVerticalGap.mnModel), + maPageObjectModelSize); +} + + + + +Rectangle Layouter::GetPageBox (sal_Int32 nObjectCount) const +{ + sal_Int32 nHorizontalSize = 0; + sal_Int32 nVerticalSize = 0; + if (mnColumnCount > 0) + { + sal_Int32 nRowCount = (nObjectCount+mnColumnCount-1) / mnColumnCount; + nHorizontalSize = + mnLeftBorder.mnModel + + mnRightBorder.mnModel + + mnColumnCount * maPageObjectModelSize.Width() + + mnLeftPageBorder.mnModel + mnRightPageBorder.mnModel; + if (mnColumnCount > 1) + nHorizontalSize + += (mnColumnCount-1) * mnTotalHorizontalGap.mnModel; + nVerticalSize = + mnTopBorder.mnModel + + mnBottomBorder.mnModel + + nRowCount * maPageObjectModelSize.Height() + + mnTopPageBorder.mnModel + mnBottomPageBorder.mnModel; + if (nRowCount > 1) + nVerticalSize += (nRowCount-1) * mnTotalVerticalGap.mnModel; + } + + return Rectangle ( + Point(0,0), + Size (nHorizontalSize, nVerticalSize) + ); +} + + + + +Rectangle Layouter::GetInsertionMarkerBox ( + sal_Int32 nIndex, + bool bVertical, + bool bLeftOrTop) const +{ + Rectangle aBox (GetPageObjectBox (nIndex)); + + if (bVertical) + { + sal_Int32 nHorizontalInsertionMarkerOffset + = (mnHorizontalGap.mnModel-mnInsertionMarkerThickness.mnModel) / 2; + if (bLeftOrTop) + { + // Left. + aBox.Left() -= mnLeftPageBorder.mnModel + + mnHorizontalGap.mnModel + - nHorizontalInsertionMarkerOffset; + } + else + { + // Right. + aBox.Left() = aBox.Right() + + mnRightPageBorder.mnModel + + nHorizontalInsertionMarkerOffset; + } + aBox.Right() = aBox.Left() + mnInsertionMarkerThickness.mnModel; + } + else + { + sal_Int32 nVerticalInsertionMarkerOffset + = (mnVerticalGap.mnModel - mnInsertionMarkerThickness.mnModel) / 2; + if (bLeftOrTop) + { + // Above. + aBox.Top() -= mnTopPageBorder.mnModel + + mnVerticalGap.mnModel + - nVerticalInsertionMarkerOffset; + } + else + { + // Below. + aBox.Top() = aBox.Bottom() + + mnBottomPageBorder.mnModel + + nVerticalInsertionMarkerOffset; + } + aBox.Bottom() = aBox.Top() + mnInsertionMarkerThickness.mnModel; + } + + return aBox; +} + + + + +sal_Int32 Layouter::GetIndexOfFirstVisiblePageObject ( + const Rectangle& aVisibleArea) const +{ + sal_Int32 nRow = GetRowAtPosition (aVisibleArea.Top(), true, GM_BOTH); + return nRow * mnColumnCount; +} + + + + +sal_Int32 Layouter::GetIndexOfLastVisiblePageObject ( + const Rectangle& aVisibleArea) const +{ + sal_Int32 nRow = GetRowAtPosition (aVisibleArea.Bottom(), + true, GM_BOTH); + return (nRow+1) * mnColumnCount - 1; +} + + + + +sal_Int32 Layouter::GetIndexAtPoint ( + const Point& rPosition, + bool bIncludePageBorders) const +{ + sal_Int32 nRow = GetRowAtPosition (rPosition.Y(), + bIncludePageBorders, + bIncludePageBorders ? GM_PAGE_BORDER : GM_NONE); + sal_Int32 nColumn = GetColumnAtPosition (rPosition.X(), + bIncludePageBorders, + bIncludePageBorders ? GM_PAGE_BORDER : GM_NONE); + + if (nRow >= 0 && nColumn >= 0) + return nRow * mnColumnCount + nColumn; + else + return -1; +} + + + + +/** Calculation of the insertion index: + 1. Determine the row. rPoint has to be in the row between upper and + lower border. If it is in a horizontal gap or border an invalid + insertion index (-1, which is a valid return value) will be returned. + 2. Determine the column. Here both vertical borders and vertical gaps + will yield valid return values. The horizontal positions between the + center of page objects in column i and the center of page objects in + column i+1 will return column i+1 as insertion index. + + When there is only one column and bAllowVerticalPosition is true than + take the vertical areas between rows into account as well. +*/ +sal_Int32 Layouter::GetInsertionIndex ( + const Point& rPosition, + bool bAllowVerticalPosition) const +{ + sal_Int32 nIndex = -1; + + sal_Int32 nRow = GetRowAtPosition (rPosition.Y(), true, + (mnColumnCount==1 && bAllowVerticalPosition) ? GM_BOTH : GM_BOTH); + sal_Int32 nColumn = GetColumnAtPosition (rPosition.X(), true, GM_BOTH); + + if (nRow >= 0 && nColumn >= 0) + nIndex = nRow * mnColumnCount + nColumn; + + return nIndex; +} + + + + +Layouter::DoublePoint + Layouter::ConvertModelToLayouterCoordinates ( + const Point& rModelPoint) const +{ + sal_Int32 nColumn = GetColumnAtPosition (rModelPoint.X(), true, GM_BOTH); + sal_Int32 nColumnWidth + = maPageObjectModelSize.Width() + mnTotalHorizontalGap.mnModel; + sal_Int32 nDistanceIntoColumn = + rModelPoint.X() - mnLeftBorder.mnModel - mnLeftPageBorder.mnModel + - nColumn * nColumnWidth; + + sal_Int32 nRow = GetRowAtPosition (rModelPoint.Y(), true, GM_BOTH); + sal_Int32 nRowHeight + = maPageObjectModelSize.Height() + mnTotalVerticalGap.mnModel; + sal_Int32 nDistanceIntoRow = + rModelPoint.Y() - mnTopBorder.mnModel - mnTopPageBorder.mnModel + - nRow * nRowHeight; + + return DoublePoint ( + nColumn + double(nDistanceIntoColumn) / double(nColumnWidth), + nRow + double(nDistanceIntoRow) / double(nRowHeight)); +} + + + + +Point Layouter::ConvertLayouterToModelCoordinates ( + const DoublePoint & rLayouterPoint) const +{ + sal_Int32 nColumn = (sal_Int32) ::rtl::math::round(rLayouterPoint.first, + 0,rtl_math_RoundingMode_Floor); + sal_Int32 nColumnWidth + = maPageObjectModelSize.Width() + mnTotalHorizontalGap.mnModel; + sal_Int32 nDistanceIntoColumn + = (sal_Int32)((rLayouterPoint.first - nColumn) * nColumnWidth); + + sal_Int32 nRow = (sal_Int32) ::rtl::math::round(rLayouterPoint.second, + 0,rtl_math_RoundingMode_Floor); + sal_Int32 nRowHeight + = maPageObjectModelSize.Height() + mnTotalVerticalGap.mnModel; + sal_Int32 nDistanceIntoRow + = (sal_Int32)((rLayouterPoint.second - nRow) * nRowHeight); + + return Point ( + mnLeftBorder.mnModel + mnLeftPageBorder.mnModel + + nColumn * nColumnWidth + nDistanceIntoColumn, + mnTopBorder.mnModel + mnTopPageBorder.mnModel + + nRow * nRowHeight + nDistanceIntoRow); +} + + + + +sal_Int32 Layouter::GetRowAtPosition ( + sal_Int32 nYPosition, + bool bIncludeBordersAndGaps, + GapMembership eGapMembership) const +{ + sal_Int32 nRow = -1; + + const sal_Int32 nY = nYPosition + - mnTopBorder.mnModel - mnTopPageBorder.mnModel; + if (nY >= 0) + { + // Vertical distance from one row to the next. + const sal_Int32 nRowOffset ( + maPageObjectModelSize.Height() + mnTotalVerticalGap.mnModel); + + // Calculate row consisting of page objects and gap below. + nRow = nY / nRowOffset; + + const sal_Int32 nDistanceIntoGap ( + (nY - nRow*nRowOffset) - maPageObjectModelSize.Height()); + // When inside the gap below then nYPosition is not over a page + // object. + if (nDistanceIntoGap > 0) + nRow = ResolvePositionInGap ( + nDistanceIntoGap, + eGapMembership, + nRow, + mnBottomPageBorder.mnModel, + mnVerticalGap.mnModel); + } + else if (bIncludeBordersAndGaps) + { + // We are in the top border area. Set nRow to the first row when + // the top border shall be considered to belong to the first row. + nRow = 0; + } + + return nRow; +} + + + + +sal_Int32 Layouter::GetColumnAtPosition ( + sal_Int32 nXPosition, + bool bIncludeBordersAndGaps, + GapMembership eGapMembership) const +{ + sal_Int32 nColumn = -1; + + sal_Int32 nX = nXPosition + - mnLeftBorder.mnModel - mnLeftPageBorder.mnModel; + if (nX >= 0) + { + // Horizontal distance from one column to the next. + const sal_Int32 nColumnOffset ( + maPageObjectModelSize.Width() + mnTotalHorizontalGap.mnModel); + + // Calculate row consisting of page objects and gap below. + nColumn = nX / nColumnOffset; + if (nColumn < 0) + nColumn = 0; + else if (nColumn >= mnColumnCount) + nColumn = mnColumnCount-1; + + const sal_Int32 nDistanceIntoGap ( + (nX - nColumn*nColumnOffset) - maPageObjectModelSize.Width()); + // When inside the gap at the right then nXPosition is not over a + // page object. + if (nDistanceIntoGap > 0) + nColumn = ResolvePositionInGap ( + nDistanceIntoGap, + eGapMembership, + nColumn, + mnRightPageBorder.mnModel, + mnHorizontalGap.mnModel); + } + else if (bIncludeBordersAndGaps) + { + // We are in the left border area. Set nColumn to the first column + // when the left border shall be considered to belong to the first + // column. + nColumn = 0; + } + return nColumn; +} + + + + +sal_Int32 Layouter::ResolvePositionInGap ( + sal_Int32 nDistanceIntoGap, + GapMembership eGapMembership, + sal_Int32 nIndex, + sal_Int32 nLeftOrTopPageBorder, + sal_Int32 nGap) const +{ + switch (eGapMembership) + { + case GM_NONE: + // The gap is no man's land. + nIndex = -1; + break; + + case GM_BOTH: + { + // The lower half of the gap belongs to the next row or column. + sal_Int32 nFirstHalfGapWidth = nLeftOrTopPageBorder + nGap / 2; + if (nDistanceIntoGap > nFirstHalfGapWidth) + nIndex ++; + break; + } + + case GM_PREVIOUS: + // Row or column already at correct value. + break; + + case GM_NEXT: + // The complete gap belongs to the next row or column. + nIndex ++; + break; + + case GM_PAGE_BORDER: + if (nDistanceIntoGap > nLeftOrTopPageBorder) + { + if (nDistanceIntoGap > nLeftOrTopPageBorder + nGap) + { + // Inside the border of the next row or column. + nIndex ++; + } + else + { + // Inside the gap between the page borders. + nIndex = -1; + } + } + break; + + default: + nIndex = -1; + } + + return nIndex; +} + + + + +} } } // end of namespace ::sd::slidesorter::namespace |