[Libreoffice-commits] core.git: Branch 'feature/perfwork4' - 6 commits - chart2/source
Kohei Yoshida
kohei.yoshida at collabora.com
Thu Oct 23 10:40:05 PDT 2014
chart2/source/view/axes/VAxisBase.cxx | 4
chart2/source/view/axes/VAxisBase.hxx | 2
chart2/source/view/axes/VAxisProperties.cxx | 9
chart2/source/view/axes/VAxisProperties.hxx | 4
chart2/source/view/axes/VCartesianAxis.cxx | 300 +++++++++++++++++++++-------
chart2/source/view/axes/VCartesianAxis.hxx | 36 ++-
6 files changed, 277 insertions(+), 78 deletions(-)
New commits:
commit 6a71d5bd7722b30b5cb268487da706c7a6e0c05b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Thu Oct 23 13:35:54 2014 -0400
Modify the tick iterator strategy to use fewer ticks.
To pre-determine the size of the largest text label object, auto-staggering
strategy etc. In theory (if I read the code correctly) we could achieve
the same thing by using only 3 ticks rather than 5.
Change-Id: Iee51588061e482c724ee4fb666c51c2a6b636e8c
diff --git a/chart2/source/view/axes/VCartesianAxis.cxx b/chart2/source/view/axes/VCartesianAxis.cxx
index 7ff0f99..1209664 100644
--- a/chart2/source/view/axes/VCartesianAxis.cxx
+++ b/chart2/source/view/axes/VCartesianAxis.cxx
@@ -407,9 +407,10 @@ void getAxisLabelProperties(
}
/**
- * Iterate through only the first 2 and last 2 tick info items, and the tick
- * that has the longest text (in terms of character length) in case it's not
- * in the first or last 2 items.
+ * Iterate through only 3 ticks including the one that has the longest text
+ * length. When the first tick has the longest text, it iterates through
+ * the first 3 ticks. Otherwise it iterates through 3 ticks such that the
+ * 2nd tick is the one with the longest text.
*/
class MaxLabelTickIter : public TickIter
{
@@ -431,21 +432,27 @@ MaxLabelTickIter::MaxLabelTickIter(
m_rTickInfoVector(rTickInfoVector), m_nCurrentIndex(0)
{
assert(!rTickInfoVector.empty()); // should be checked by the caller.
+ assert(nLongestLabelIndex < rTickInfoVector.size());
size_t nMaxIndex = m_rTickInfoVector.size()-1;
if (nLongestLabelIndex >= nMaxIndex-1)
nLongestLabelIndex = 0;
- m_aValidIndices.push_back(0);
- if( nMaxIndex>=1 )
- m_aValidIndices.push_back(1);
- if( nLongestLabelIndex>1 )
+ if (nLongestLabelIndex > 0)
+ m_aValidIndices.push_back(nLongestLabelIndex-1);
+
+ m_aValidIndices.push_back(nLongestLabelIndex);
+
+ while (m_aValidIndices.size() < 3)
+ {
+ ++nLongestLabelIndex;
+ if (nLongestLabelIndex > nMaxIndex)
+ break;
+
m_aValidIndices.push_back(nLongestLabelIndex);
- if( nMaxIndex > 2 )
- m_aValidIndices.push_back(nMaxIndex-1);
- if( nMaxIndex > 1 )
- m_aValidIndices.push_back(nMaxIndex);
+ }
}
+
MaxLabelTickIter::~MaxLabelTickIter()
{
}
@@ -624,6 +631,9 @@ TickIter* VCartesianAxis::createMaximumLabelTickIterator( sal_Int32 nTextLevel )
if( !m_aAllTickInfos.empty() )
{
size_t nLongestLabelIndex = m_bUseTextLabels ? getIndexOfLongestLabel(m_aTextLabels) : 0;
+ if (nLongestLabelIndex >= m_aAllTickInfos[0].size())
+ return NULL;
+
return new MaxLabelTickIter( m_aAllTickInfos[0], nLongestLabelIndex );
}
}
commit af7aedbceb694a1193e34eafcb94db632ff089d7
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Thu Oct 23 12:43:30 2014 -0400
Let's use size_t for the index.
This removes unnecessary static_cast's and check for negative values
which, from what I've read from the code, never happens.
Change-Id: I9d9e1de5b091df335dd3b7eeb34e4e8f98de0fbd
diff --git a/chart2/source/view/axes/VAxisBase.cxx b/chart2/source/view/axes/VAxisBase.cxx
index c391382..f97655f 100644
--- a/chart2/source/view/axes/VAxisBase.cxx
+++ b/chart2/source/view/axes/VAxisBase.cxx
@@ -187,7 +187,7 @@ bool VAxisBase::prepareShapeCreation()
return true;
}
-sal_Int32 VAxisBase::getIndexOfLongestLabel( const uno::Sequence< OUString >& rLabels )
+size_t VAxisBase::getIndexOfLongestLabel( const uno::Sequence<OUString>& rLabels )
{
sal_Int32 nRet = 0;
sal_Int32 nLength = 0;
@@ -201,6 +201,8 @@ sal_Int32 VAxisBase::getIndexOfLongestLabel( const uno::Sequence< OUString >& rL
nRet = nN;
}
}
+
+ assert(nRet >= 0);
return nRet;
}
diff --git a/chart2/source/view/axes/VAxisBase.hxx b/chart2/source/view/axes/VAxisBase.hxx
index d43ef58..ab0e4093 100644
--- a/chart2/source/view/axes/VAxisBase.hxx
+++ b/chart2/source/view/axes/VAxisBase.hxx
@@ -65,7 +65,7 @@ public:
void setExrtaLinePositionAtOtherAxis( double fCrossingAt );
protected: //methods
- sal_Int32 getIndexOfLongestLabel( const ::com::sun::star::uno::Sequence< OUString >& rLabels );
+ size_t getIndexOfLongestLabel( const css::uno::Sequence<OUString>& rLabels );
void removeTextShapesFromTicks();
void updateUnscaledValuesAtTicks( TickIter& rIter );
diff --git a/chart2/source/view/axes/VCartesianAxis.cxx b/chart2/source/view/axes/VCartesianAxis.cxx
index fbc5335..7ff0f99 100644
--- a/chart2/source/view/axes/VCartesianAxis.cxx
+++ b/chart2/source/view/axes/VCartesianAxis.cxx
@@ -414,8 +414,7 @@ void getAxisLabelProperties(
class MaxLabelTickIter : public TickIter
{
public:
- MaxLabelTickIter( TickInfoArrayType& rTickInfoVector
- , sal_Int32 nLongestLabelIndex );
+ MaxLabelTickIter( TickInfoArrayType& rTickInfoVector, size_t nLongestLabelIndex );
virtual ~MaxLabelTickIter();
virtual TickInfo* firstInfo() SAL_OVERRIDE;
@@ -423,21 +422,21 @@ public:
private:
TickInfoArrayType& m_rTickInfoVector;
- ::std::vector< sal_Int32 > m_aValidIndices;
- sal_Int32 m_nCurrentIndex;
+ std::vector<size_t> m_aValidIndices;
+ size_t m_nCurrentIndex;
};
-MaxLabelTickIter::MaxLabelTickIter( TickInfoArrayType& rTickInfoVector
- , sal_Int32 nLongestLabelIndex )
- : m_rTickInfoVector(rTickInfoVector)
- , m_nCurrentIndex(0)
+MaxLabelTickIter::MaxLabelTickIter(
+ TickInfoArrayType& rTickInfoVector, size_t nLongestLabelIndex ) :
+ m_rTickInfoVector(rTickInfoVector), m_nCurrentIndex(0)
{
- sal_Int32 nMaxIndex = m_rTickInfoVector.size()-1;
- if( nLongestLabelIndex<0 || nLongestLabelIndex>=nMaxIndex-1 )
+ assert(!rTickInfoVector.empty()); // should be checked by the caller.
+
+ size_t nMaxIndex = m_rTickInfoVector.size()-1;
+ if (nLongestLabelIndex >= nMaxIndex-1)
nLongestLabelIndex = 0;
- if( nMaxIndex>=0 )
- m_aValidIndices.push_back(0);
+ m_aValidIndices.push_back(0);
if( nMaxIndex>=1 )
m_aValidIndices.push_back(1);
if( nLongestLabelIndex>1 )
@@ -454,7 +453,7 @@ MaxLabelTickIter::~MaxLabelTickIter()
TickInfo* MaxLabelTickIter::firstInfo()
{
m_nCurrentIndex = 0;
- if( m_nCurrentIndex < static_cast<sal_Int32>(m_aValidIndices.size()) )
+ if (m_nCurrentIndex < m_aValidIndices.size())
return &m_rTickInfoVector[m_aValidIndices[m_nCurrentIndex]];
return 0;
}
@@ -462,7 +461,7 @@ TickInfo* MaxLabelTickIter::firstInfo()
TickInfo* MaxLabelTickIter::nextInfo()
{
m_nCurrentIndex++;
- if( m_nCurrentIndex>=0 && m_nCurrentIndex<static_cast<sal_Int32>(m_aValidIndices.size()) )
+ if (m_nCurrentIndex < m_aValidIndices.size())
return &m_rTickInfoVector[m_aValidIndices[m_nCurrentIndex]];
return 0;
}
@@ -624,7 +623,7 @@ TickIter* VCartesianAxis::createMaximumLabelTickIterator( sal_Int32 nTextLevel )
{
if( !m_aAllTickInfos.empty() )
{
- sal_Int32 nLongestLabelIndex = m_bUseTextLabels ? this->getIndexOfLongestLabel( m_aTextLabels ) : 0;
+ size_t nLongestLabelIndex = m_bUseTextLabels ? getIndexOfLongestLabel(m_aTextLabels) : 0;
return new MaxLabelTickIter( m_aAllTickInfos[0], nLongestLabelIndex );
}
}
commit 19e33a3ad865e5fbe12dbaca90199f4d6441cc97
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Oct 22 11:50:41 2014 -0400
Some code sharing.
Change-Id: If80c4b0ceec5e0afd55d12ebe7511fb4f40b4797
diff --git a/chart2/source/view/axes/VAxisProperties.cxx b/chart2/source/view/axes/VAxisProperties.cxx
index 3b5502f..3db365d 100644
--- a/chart2/source/view/axes/VAxisProperties.cxx
+++ b/chart2/source/view/axes/VAxisProperties.cxx
@@ -412,6 +412,13 @@ bool AxisLabelProperties::isStaggered() const
return ( STAGGER_ODD == eStaggering || STAGGER_EVEN == eStaggering );
}
+void AxisLabelProperties::autoRotate45()
+{
+ fRotationAngleDegree = 45;
+ bLineBreakAllowed = false;
+ eStaggering = SIDE_BY_SIDE;
+}
+
} //namespace chart
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/view/axes/VAxisProperties.hxx b/chart2/source/view/axes/VAxisProperties.hxx
index b658925..1eadf70 100644
--- a/chart2/source/view/axes/VAxisProperties.hxx
+++ b/chart2/source/view/axes/VAxisProperties.hxx
@@ -82,6 +82,8 @@ struct AxisLabelProperties SAL_FINAL
::com::sun::star::chart2::XAxis >& xAxisModel );
bool isStaggered() const;
+
+ void autoRotate45();
};
struct AxisLabelAlignment
diff --git a/chart2/source/view/axes/VCartesianAxis.cxx b/chart2/source/view/axes/VCartesianAxis.cxx
index d43e32f..fbc5335 100644
--- a/chart2/source/view/axes/VCartesianAxis.cxx
+++ b/chart2/source/view/axes/VCartesianAxis.cxx
@@ -365,6 +365,47 @@ bool lcl_hasWordBreak( const Reference<drawing::XShape>& xShape )
return false;
}
+OUString getTextLabelString(
+ const FixedNumberFormatter& rFixedNumberFormatter, const uno::Sequence<OUString>* pCategories,
+ const TickInfo* pTickInfo, bool bComplexCat, sal_Int32& rExtraColor, bool& rHasExtraColor )
+{
+ 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() )
+ return (*pCategories)[nIndex];
+
+ return OUString();
+ }
+ else if (bComplexCat)
+ {
+ // This is a complex category axis. The label is stored in the tick.
+ return pTickInfo->aText;
+ }
+
+ // This is a numeric axis. Format the original tick value per number format.
+ return rFixedNumberFormatter.getFormattedString(pTickInfo->getUnscaledTickValue(), rExtraColor, rHasExtraColor);
+}
+
+void getAxisLabelProperties(
+ tNameSequence& rPropNames, tAnySequence& rPropValues, const AxisProperties& rAxisProp,
+ const AxisLabelProperties& rAxisLabelProp,
+ sal_Int32 nLimitedSpaceForText, bool bLimitedHeight )
+{
+ Reference<beans::XPropertySet> xProps(rAxisProp.m_xAxisModel, uno::UNO_QUERY);
+
+ PropertyMapper::getTextLabelMultiPropertyLists(
+ xProps, rPropNames, rPropValues, false, nLimitedSpaceForText, bLimitedHeight);
+
+ LabelPositionHelper::doDynamicFontResize(
+ rPropValues, rPropNames, xProps, rAxisLabelProp.m_aFontReferenceSize);
+
+ LabelPositionHelper::changeTextAdjustment(
+ rPropValues, rPropNames, rAxisProp.maLabelAlignment.meAlignment);
+}
+
/**
* Iterate through only the first 2 and last 2 tick info items, and the tick
* that has the longest text (in terms of character length) in case it's not
@@ -644,17 +685,12 @@ bool VCartesianAxis::createTextShapes(
const TickInfo* pPREPreviousVisibleTickInfo = NULL;
const TickInfo* pLastVisibleNeighbourTickInfo = NULL;
+ bool bLimitedHeight = fabs(aTextToTickDistance.getX()) > fabs(aTextToTickDistance.getY());
+
//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
- , nLimitedSpaceForText, bLimitedHeight );
- LabelPositionHelper::doDynamicFontResize( aPropValues, aPropNames, xProps
- , m_aAxisLabelProperties.m_aFontReferenceSize );
- LabelPositionHelper::changeTextAdjustment( aPropValues, aPropNames, m_aAxisProperties.maLabelAlignment.meAlignment );
+ getAxisLabelProperties(aPropNames, aPropValues, m_aAxisProperties, rAxisLabelProperties, nLimitedSpaceForText, bLimitedHeight);
uno::Any* pColorAny = PropertyMapper::getValuePointer(aPropValues,aPropNames,"CharColor");
sal_Int32 nColor = Color( COL_AUTO ).GetColor();
@@ -725,25 +761,9 @@ bool VCartesianAxis::createTextShapes(
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 );
- }
+ OUString aLabel = getTextLabelString(
+ aFixedNumberFormatter, pCategories, pTickInfo, isComplexCategoryAxis(),
+ nExtraColor, bHasExtraColor);
if(pColorAny)
*pColorAny = uno::makeAny(bHasExtraColor?nExtraColor:nColor);
@@ -810,10 +830,7 @@ bool VCartesianAxis::createTextShapes(
// 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;
+ rAxisLabelProperties.autoRotate45();
m_aAxisLabelProperties.fRotationAngleDegree = rAxisLabelProperties.fRotationAngleDegree; // Store it for future runs.
removeTextShapesFromTicks();
return false;
@@ -862,17 +879,12 @@ bool VCartesianAxis::createTextShapesSimple(
const TickInfo* pPreviousVisibleTickInfo = NULL;
const TickInfo* pLastVisibleNeighbourTickInfo = NULL;
+ bool bLimitedHeight = fabs(aTextToTickDistance.getX()) > fabs(aTextToTickDistance.getY());
+
//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 );
+ getAxisLabelProperties(aPropNames, aPropValues, m_aAxisProperties, rAxisLabelProperties, -1, bLimitedHeight);
uno::Any* pColorAny = PropertyMapper::getValuePointer(aPropValues,aPropNames,"CharColor");
sal_Int32 nColor = Color( COL_AUTO ).GetColor();
@@ -921,25 +933,9 @@ bool VCartesianAxis::createTextShapesSimple(
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 );
- }
+ OUString aLabel = getTextLabelString(
+ aFixedNumberFormatter, pCategories, pTickInfo, isComplexCategoryAxis(),
+ nExtraColor, bHasExtraColor);
if(pColorAny)
*pColorAny = uno::makeAny(bHasExtraColor?nExtraColor:nColor);
@@ -975,10 +971,7 @@ bool VCartesianAxis::createTextShapesSimple(
// 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;
+ rAxisLabelProperties.autoRotate45();
m_aAxisLabelProperties.fRotationAngleDegree = rAxisLabelProperties.fRotationAngleDegree; // Store it for future runs.
removeTextShapesFromTicks();
return false;
commit b6601a01b4202ff21bc621fd1fd1da11ede0f06a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Oct 22 10:51:44 2014 -0400
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
diff --git a/chart2/source/view/axes/VAxisProperties.cxx b/chart2/source/view/axes/VAxisProperties.cxx
index 9b449d5..3b5502f 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 7495c21..b658925 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 d095af5..d43e32f 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 3b9886d..839d5e8 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 );
commit 0bf0c8af7e22ee2745ca32d8c0291ebc687893bd
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Oct 22 10:25:42 2014 -0400
These methods can be private rather than protected.
Change-Id: I56f1296f5a2df67ae9386ae9f30761aee0fde7f3
diff --git a/chart2/source/view/axes/VCartesianAxis.hxx b/chart2/source/view/axes/VCartesianAxis.hxx
index 8abe4eb..3b9886d 100644
--- a/chart2/source/view/axes/VCartesianAxis.hxx
+++ b/chart2/source/view/axes/VCartesianAxis.hxx
@@ -100,7 +100,7 @@ public:
::basegfx::B2DVector aScreenPos;
};
-protected: //methods
+private: //methods
/**
* Go through all tick label positions and decide which labels to display
* based on the text shape geometry, overlap setting, tick interval,
commit 15a501b6e05fb2490b69a98a4c0782f09dd326d2
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Oct 22 09:56:01 2014 -0400
More method descriptions.
I'm starting to "get" this axis label layout code.
Change-Id: I797a92698cb81a1b9325f81b5275cb033cb7c342
diff --git a/chart2/source/view/axes/VCartesianAxis.hxx b/chart2/source/view/axes/VCartesianAxis.hxx
index 2492bb0..8abe4eb 100644
--- a/chart2/source/view/axes/VCartesianAxis.hxx
+++ b/chart2/source/view/axes/VCartesianAxis.hxx
@@ -131,14 +131,24 @@ protected: //methods
/**
* Shift the screen positions of the tick labels according to the stagger
- * settings. Stagger setting is finalized during the createTextShapes
+ * settings. Final stagger setting is decided during the createTextShapes
* call, but this method does the physical shifting of the label
- * positions.
+ * positions based on the final stagger setting.
*/
void doStaggeringOfLabels( const AxisLabelProperties& rAxisLabelProperties
, TickFactory2D* pTickFactory2D );
+
+ /**
+ * @return true if we can try to stagger labels in order to avoid
+ * overlaps, otherwise false.
+ */
bool isAutoStaggeringOfLabelsAllowed(
const AxisLabelProperties& rAxisLabelProperties, bool bIsHorizontalAxis, bool bIsVerticalAxis ) const;
+
+ /**
+ * @return true if we can break a single line label text into multiple
+ * lines for better fitting, otherwise false.
+ */
bool isBreakOfLabelsAllowed( const AxisLabelProperties& rAxisLabelProperties, bool bIsHorizontalAxis ) const;
::basegfx::B2DVector getScreenPosition( double fLogicX, double fLogicY, double fLogicZ ) const;
More information about the Libreoffice-commits
mailing list