summaryrefslogtreecommitdiff
path: root/chart2
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-10-22 10:51:44 -0400
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-11-04 12:30:36 -0500
commit519634b357a63bc1ff5c559244d9c7313f1b4c04 (patch)
treee2bb87f8640d020602621852c5f56189b591ad1e /chart2
parentc95a355b0571329747095b23747405252c232c8b (diff)
Create a variant of createTextShapes for simpler use cases.
So that we can do more aggressive optimization without breaking the other cases. Change-Id: I5d4ceb2a3b7f041f752a570827815236e9de58db
Diffstat (limited to 'chart2')
-rw-r--r--chart2/source/view/axes/VAxisProperties.cxx2
-rw-r--r--chart2/source/view/axes/VAxisProperties.hxx2
-rw-r--r--chart2/source/view/axes/VCartesianAxis.cxx186
-rw-r--r--chart2/source/view/axes/VCartesianAxis.hxx20
4 files changed, 193 insertions, 17 deletions
diff --git a/chart2/source/view/axes/VAxisProperties.cxx b/chart2/source/view/axes/VAxisProperties.cxx
index 9b449d5a96d4..3b5502f464e8 100644
--- a/chart2/source/view/axes/VAxisProperties.cxx
+++ b/chart2/source/view/axes/VAxisProperties.cxx
@@ -407,7 +407,7 @@ void AxisLabelProperties::init( const uno::Reference< XAxis >& xAxisModel )
}
}
-bool AxisLabelProperties::getIsStaggered() const
+bool AxisLabelProperties::isStaggered() const
{
return ( STAGGER_ODD == eStaggering || STAGGER_EVEN == eStaggering );
}
diff --git a/chart2/source/view/axes/VAxisProperties.hxx b/chart2/source/view/axes/VAxisProperties.hxx
index 7495c21a03b4..b65892507a02 100644
--- a/chart2/source/view/axes/VAxisProperties.hxx
+++ b/chart2/source/view/axes/VAxisProperties.hxx
@@ -81,7 +81,7 @@ struct AxisLabelProperties SAL_FINAL
void init( const ::com::sun::star::uno::Reference<
::com::sun::star::chart2::XAxis >& xAxisModel );
- bool getIsStaggered() const;
+ bool isStaggered() const;
};
struct AxisLabelAlignment
diff --git a/chart2/source/view/axes/VCartesianAxis.cxx b/chart2/source/view/axes/VCartesianAxis.cxx
index d095af5df24e..d43e32f69fee 100644
--- a/chart2/source/view/axes/VCartesianAxis.cxx
+++ b/chart2/source/view/axes/VCartesianAxis.cxx
@@ -600,20 +600,25 @@ sal_Int32 VCartesianAxis::getTextLevelCount() const
}
bool VCartesianAxis::createTextShapes(
- const Reference< drawing::XShapes >& xTarget
- , TickIter& rTickIter
- , AxisLabelProperties& rAxisLabelProperties
- , TickFactory2D* pTickFactory
- , sal_Int32 nScreenDistanceBetweenTicks )
+ const Reference<drawing::XShapes>& xTarget, TickIter& rTickIter,
+ AxisLabelProperties& rAxisLabelProperties, TickFactory2D* pTickFactory,
+ sal_Int32 nScreenDistanceBetweenTicks )
{
+ const bool bIsHorizontalAxis = pTickFactory->isHorizontalAxis();
+ const bool bIsVerticalAxis = pTickFactory->isVerticalAxis();
+
+ if (!isBreakOfLabelsAllowed(rAxisLabelProperties, bIsHorizontalAxis) &&
+ !isAutoStaggeringOfLabelsAllowed(rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis) &&
+ !rAxisLabelProperties.isStaggered())
+ return createTextShapesSimple(xTarget, rTickIter, rAxisLabelProperties, pTickFactory);
+
FixedNumberFormatter aFixedNumberFormatter(
m_xNumberFormatsSupplier, rAxisLabelProperties.nNumberFormatKey );
- const bool bIsHorizontalAxis = pTickFactory->isHorizontalAxis();
- const bool bIsVerticalAxis = pTickFactory->isVerticalAxis();
- bool bIsStaggered = rAxisLabelProperties.getIsStaggered();
+ bool bIsStaggered = rAxisLabelProperties.isStaggered();
B2DVector aTextToTickDistance = pTickFactory->getDistanceAxisTickToText(m_aAxisProperties, true);
sal_Int32 nLimitedSpaceForText = -1;
+
if( isBreakOfLabelsAllowed( rAxisLabelProperties, bIsHorizontalAxis ) )
{
nLimitedSpaceForText = nScreenDistanceBetweenTicks;
@@ -837,6 +842,169 @@ bool VCartesianAxis::createTextShapes(
return true;
}
+bool VCartesianAxis::createTextShapesSimple(
+ const Reference<drawing::XShapes>& xTarget, TickIter& rTickIter,
+ AxisLabelProperties& rAxisLabelProperties, TickFactory2D* pTickFactory )
+{
+ FixedNumberFormatter aFixedNumberFormatter(
+ m_xNumberFormatsSupplier, rAxisLabelProperties.nNumberFormatKey );
+
+ const bool bIsHorizontalAxis = pTickFactory->isHorizontalAxis();
+ const bool bIsVerticalAxis = pTickFactory->isVerticalAxis();
+ B2DVector aTextToTickDistance = pTickFactory->getDistanceAxisTickToText(m_aAxisProperties, true);
+
+ // Stores an array of text label strings in case of a normal
+ // (non-complex) category axis.
+ const uno::Sequence<OUString>* pCategories = NULL;
+ if( m_bUseTextLabels && !m_aAxisProperties.m_bComplexCategories )
+ pCategories = &m_aTextLabels;
+
+ const TickInfo* pPreviousVisibleTickInfo = NULL;
+ const TickInfo* pLastVisibleNeighbourTickInfo = NULL;
+
+ //prepare properties for multipropertyset-interface of shape
+ tNameSequence aPropNames;
+ tAnySequence aPropValues;
+
+ bool bLimitedHeight = fabs(aTextToTickDistance.getX()) > fabs(aTextToTickDistance.getY());
+ Reference< beans::XPropertySet > xProps( m_aAxisProperties.m_xAxisModel, uno::UNO_QUERY );
+ PropertyMapper::getTextLabelMultiPropertyLists( xProps, aPropNames, aPropValues, false
+ , -1, bLimitedHeight );
+ LabelPositionHelper::doDynamicFontResize( aPropValues, aPropNames, xProps
+ , m_aAxisLabelProperties.m_aFontReferenceSize );
+ LabelPositionHelper::changeTextAdjustment( aPropValues, aPropNames, m_aAxisProperties.maLabelAlignment.meAlignment );
+
+ uno::Any* pColorAny = PropertyMapper::getValuePointer(aPropValues,aPropNames,"CharColor");
+ sal_Int32 nColor = Color( COL_AUTO ).GetColor();
+ if(pColorAny)
+ *pColorAny >>= nColor;
+
+ uno::Any* pLimitedSpaceAny = PropertyMapper::getValuePointerForLimitedSpace(aPropValues,aPropNames,bLimitedHeight);
+
+ sal_Int32 nTick = 0;
+ for( TickInfo* pTickInfo = rTickIter.firstInfo()
+ ; pTickInfo
+ ; pTickInfo = rTickIter.nextInfo(), nTick++ )
+ {
+ pLastVisibleNeighbourTickInfo = pPreviousVisibleTickInfo;
+
+ //don't create labels which does not fit into the rhythm
+ if( nTick%rAxisLabelProperties.nRhythm != 0 )
+ continue;
+
+ //don't create labels for invisible ticks
+ if( !pTickInfo->bPaintIt )
+ continue;
+
+ if( pLastVisibleNeighbourTickInfo && !rAxisLabelProperties.bOverlapAllowed )
+ {
+ // Overlapping is not allowed. If the label overlaps with its
+ // neighbering label, try increasing the tick interval (or rhythm
+ // as it's called) and start over.
+
+ if( lcl_doesShapeOverlapWithTickmark( pLastVisibleNeighbourTickInfo->xTextShape
+ , rAxisLabelProperties.fRotationAngleDegree
+ , pTickInfo->aTickScreenPosition
+ , bIsHorizontalAxis, bIsVerticalAxis ) )
+ {
+ // This tick overlaps with its neighbor. Increment the visible
+ // tick intervals (if that's allowed) and start over.
+
+ if( rAxisLabelProperties.bRhythmIsFix )
+ continue;
+ rAxisLabelProperties.nRhythm++;
+ removeShapesAtWrongRhythm( rTickIter, rAxisLabelProperties.nRhythm, nTick, xTarget );
+ return false;
+ }
+ }
+
+ bool bHasExtraColor=false;
+ sal_Int32 nExtraColor=0;
+
+ OUString aLabel;
+ if(pCategories)
+ {
+ // This is a normal category axis. Get the label string from the
+ // label string array.
+ sal_Int32 nIndex = static_cast<sal_Int32>(pTickInfo->getUnscaledTickValue()) - 1; //first category (index 0) matches with real number 1.0
+ if( nIndex>=0 && nIndex<pCategories->getLength() )
+ aLabel = (*pCategories)[nIndex];
+ }
+ else if( m_aAxisProperties.m_bComplexCategories )
+ {
+ // This is a complex category axis. The label is stored in the tick.
+ aLabel = pTickInfo->aText;
+ }
+ else
+ {
+ // This is a numeric axis. Format the original tick value per number format.
+ aLabel = aFixedNumberFormatter.getFormattedString( pTickInfo->getUnscaledTickValue(), nExtraColor, bHasExtraColor );
+ }
+
+ if(pColorAny)
+ *pColorAny = uno::makeAny(bHasExtraColor?nExtraColor:nColor);
+ if(pLimitedSpaceAny)
+ *pLimitedSpaceAny = uno::makeAny(sal_Int32(-1*pTickInfo->nFactorForLimitedTextWidth));
+
+ B2DVector aTickScreenPos2D = pTickInfo->aTickScreenPosition;
+ aTickScreenPos2D += aTextToTickDistance;
+ awt::Point aAnchorScreenPosition2D(
+ static_cast<sal_Int32>(aTickScreenPos2D.getX())
+ ,static_cast<sal_Int32>(aTickScreenPos2D.getY()));
+
+ //create single label
+ if(!pTickInfo->xTextShape.is())
+ pTickInfo->xTextShape = createSingleLabel( m_xShapeFactory, xTarget
+ , aAnchorScreenPosition2D, aLabel
+ , rAxisLabelProperties, m_aAxisProperties
+ , aPropNames, aPropValues );
+ if(!pTickInfo->xTextShape.is())
+ continue;
+
+ recordMaximumTextSize( pTickInfo->xTextShape, rAxisLabelProperties.fRotationAngleDegree );
+
+ //if NO OVERLAP -> remove overlapping shapes
+ if( pLastVisibleNeighbourTickInfo && !rAxisLabelProperties.bOverlapAllowed )
+ {
+ // Check if the label still overlaps with its neighber.
+ if( doesOverlap( pLastVisibleNeighbourTickInfo->xTextShape, pTickInfo->xTextShape, rAxisLabelProperties.fRotationAngleDegree ) )
+ {
+ // It overlaps.
+ if( !rAxisLabelProperties.bOverlapAllowed && ::rtl::math::approxEqual( rAxisLabelProperties.fRotationAngleDegree, 0.0 ) )
+ {
+ // Try auto-rotating the labels at 45 degrees and
+ // start over. This rotation angle will be stored for
+ // all future text shape creation runs.
+
+ rAxisLabelProperties.fRotationAngleDegree = 45;
+ rAxisLabelProperties.bLineBreakAllowed = false;
+ rAxisLabelProperties.eStaggering = SIDE_BY_SIDE;
+ m_aAxisLabelProperties.fRotationAngleDegree = rAxisLabelProperties.fRotationAngleDegree; // Store it for future runs.
+ removeTextShapesFromTicks();
+ return false;
+ }
+
+ if( rAxisLabelProperties.bRhythmIsFix )
+ {
+ // Tick interval is fixed. We have no choice but to
+ // remove this label.
+ xTarget->remove(pTickInfo->xTextShape);
+ pTickInfo->xTextShape = NULL;
+ continue;
+ }
+
+ // Try incrementing the tick interval and start over.
+ rAxisLabelProperties.nRhythm++;
+ removeShapesAtWrongRhythm( rTickIter, rAxisLabelProperties.nRhythm, nTick, xTarget );
+ return false;
+ }
+ }
+
+ pPreviousVisibleTickInfo = pTickInfo;
+ }
+ return true;
+}
+
drawing::PointSequenceSequence lcl_makePointSequence( B2DVector& rStart, B2DVector& rEnd )
{
drawing::PointSequenceSequence aPoints(1);
@@ -1377,7 +1545,7 @@ void VCartesianAxis::doStaggeringOfLabels( const AxisLabelProperties& rAxisLabel
}
}
}
- else if( rAxisLabelProperties.getIsStaggered() )
+ else if (rAxisLabelProperties.isStaggered())
{
if( !m_aAllTickInfos.empty() )
{
diff --git a/chart2/source/view/axes/VCartesianAxis.hxx b/chart2/source/view/axes/VCartesianAxis.hxx
index 3b9886daab65..839d5e817d5e 100644
--- a/chart2/source/view/axes/VCartesianAxis.hxx
+++ b/chart2/source/view/axes/VCartesianAxis.hxx
@@ -117,12 +117,20 @@ private: //methods
* have changed during the call, and the caller needs to call this
* method once again to get the text shapes created.
*/
- bool createTextShapes( const ::com::sun::star::uno::Reference<
- ::com::sun::star::drawing::XShapes >& xTarget
- , TickIter& rTickIter
- , AxisLabelProperties& rAxisLabelProperties
- , TickFactory2D* pTickFactory
- , sal_Int32 nScreenDistanceBetweenTicks );
+ bool createTextShapes(
+ const css::uno::Reference<css::drawing::XShapes >& xTarget,
+ TickIter& rTickIter, AxisLabelProperties& rAxisLabelProperties,
+ TickFactory2D* pTickFactory, sal_Int32 nScreenDistanceBetweenTicks );
+
+ /**
+ * Variant of createTextShapes where none of auto-staggering and
+ * link-breaking are allowed in case of overlaps. Overlaps of text shapes
+ * are to be resolved only by adjusting the label tick interval.
+ */
+ bool createTextShapesSimple(
+ const css::uno::Reference<css::drawing::XShapes >& xTarget,
+ TickIter& rTickIter, AxisLabelProperties& rAxisLabelProperties,
+ TickFactory2D* pTickFactory );
void createTickMarkLineShapes( TickInfoArrayType& rTickInfos, const TickmarkProperties& rTickmarkProperties, TickFactory2D& rTickFactory2D, bool bOnlyAtLabels );