summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2023-03-23 11:24:30 +0900
committerTomaž Vajngerl <quikee@gmail.com>2023-04-28 15:40:41 +0200
commitd4a531ef8a52bf6bb75132546b7bbc43d4a48575 (patch)
tree0a56b31d954f16f55c8ddff83777028adb01d043 /oox
parentfa2fdc90d5fba9420cbb475f8c88423124c158ec (diff)
tdf#90407 Change the auto-fit alg. to match better with OOXML
The auto-fit algorithm has been tweaked to be more in-line with the expectations of OOXML. This means a couple of changes to what properties are scaled by the algorithm have been made: - most properties that influence the X axis position or size (for example indent) are not scaled down or changed by scaling. - properties that influence y axis position and size are scaled by a separate parameter (like in the OOXML). This is used in the auto-fit algorithm in a different way. - if line spacing is proportional, it is now scaled with the spacing parameter. Fixed line spacing doesn't get scaled. - the main scaling X,Y parameter only scales the fonts. - trying hard to scale the fonts to the nearest pt (point) value With this change the scaling is much more stable than it was before - for example it doesn't matter what the unscaled font size is, when it is scaled down to the text box size, it (should) always look the same (for example scaling from 32pt -> 10pt or 64pt -> 10pt or even 999pt -> 10pt). The algorithm is also rewritten to be better at finding a fit and is also better at find a good fit, but it can take more iterations by doing so (there are ways to improve it however). Previous algorithm used a linear search to converge to the best fit in less iterations, but the issue with that was that it could in some cases miss a solution (especially since change to floating point scaling parameter). The new algorithm now uses a binary search - always trying the middle of the search space. OOXML export and import was also changed to take advantage of the font scaling and spacing scaling parameters. The additional scaling at export that was needed to have consistent OOXML support was removed. Change-Id: I8f3bb8d43a01931f18bd7ffdf8e0ba40caa73d8b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149207 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> (cherry picked from commit 628275acb1b9652e65b8c5c013549dce5ad6f5bf) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150123 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/inc/drawingml/textparagraph.hxx3
-rw-r--r--oox/inc/drawingml/textparagraphproperties.hxx1
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx6
-rw-r--r--oox/source/drawingml/textbody.cxx4
-rw-r--r--oox/source/drawingml/textparagraph.cxx4
-rw-r--r--oox/source/drawingml/textparagraphproperties.cxx10
-rw-r--r--oox/source/export/drawingml.cxx45
7 files changed, 29 insertions, 44 deletions
diff --git a/oox/inc/drawingml/textparagraph.hxx b/oox/inc/drawingml/textparagraph.hxx
index 4920c99da7c5..1f43249372a5 100644
--- a/oox/inc/drawingml/textparagraph.hxx
+++ b/oox/inc/drawingml/textparagraph.hxx
@@ -77,8 +77,7 @@ public:
const TextListStyle& rMasterTextListStyle,
const TextListStyle& rTextListStyle,
bool bFirst,
- float nDefaultCharHeight,
- sal_Int32 nAutofitFontScale) const;
+ float nDefaultCharHeight) const;
bool HasMathXml() const
{
diff --git a/oox/inc/drawingml/textparagraphproperties.hxx b/oox/inc/drawingml/textparagraphproperties.hxx
index d3742e7377e0..e362119ed6f9 100644
--- a/oox/inc/drawingml/textparagraphproperties.hxx
+++ b/oox/inc/drawingml/textparagraphproperties.hxx
@@ -104,7 +104,6 @@ public:
const BulletList* pMasterBuList,
bool bApplyBulletList,
float fFontSize,
- sal_Int32 nAutofitFontScale = 100000,
bool bPushDefaultValues = false ) const;
/** Returns the largest character size of this paragraph. If possible the
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index efba958fa0e4..7927b7aa6945 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -186,13 +186,13 @@ void Diagram::syncDiagramFontHeights()
{
// Find out the minimum scale within this group.
const ShapePairs& rShapePairs = rNameAndPairs.second;
- sal_Int16 nMinScale = 100;
+ double nMinScale = 100.0;
for (const auto& rShapePair : rShapePairs)
{
uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY);
if (xPropertySet.is())
{
- sal_Int16 nTextFitToSizeScale = 0;
+ double nTextFitToSizeScale = 0.0;
xPropertySet->getPropertyValue("TextFitToSizeScale") >>= nTextFitToSizeScale;
if (nTextFitToSizeScale > 0 && nTextFitToSizeScale < nMinScale)
{
@@ -202,7 +202,7 @@ void Diagram::syncDiagramFontHeights()
}
// Set that minimum scale for all members of the group.
- if (nMinScale < 100)
+ if (nMinScale < 100.0)
{
for (const auto& rShapePair : rShapePairs)
{
diff --git a/oox/source/drawingml/textbody.cxx b/oox/source/drawingml/textbody.cxx
index 1be15c4f885d..266ff44b22f9 100644
--- a/oox/source/drawingml/textbody.cxx
+++ b/oox/source/drawingml/textbody.cxx
@@ -65,7 +65,7 @@ void TextBody::insertAt(
for (auto const& paragraph : maParagraphs)
{
paragraph->insertAt(rFilterBase, xText, xAt, rTextStyleProperties, aMasterTextStyle,
- maTextListStyle, (nIndex == 0), nCharHeight, getTextProperties().mnFontScale);
+ maTextListStyle, (nIndex == 0), nCharHeight);
++nIndex;
}
}
@@ -149,7 +149,7 @@ void TextBody::ApplyStyleEmpty(
TextParagraphProperties aParaProp;
aParaProp.apply(*pTextParagraphStyle);
aParaProp.pushToPropSet(&rFilterBase, xProps, aioBulletList, &pTextParagraphStyle->getBulletList(),
- true, nCharHeight, getTextProperties().mnFontScale, true);
+ true, nCharHeight, true);
}
}
diff --git a/oox/source/drawingml/textparagraph.cxx b/oox/source/drawingml/textparagraph.cxx
index f08efdbff3c3..e33cbb690ee9 100644
--- a/oox/source/drawingml/textparagraph.cxx
+++ b/oox/source/drawingml/textparagraph.cxx
@@ -88,7 +88,7 @@ void TextParagraph::insertAt(
const TextCharacterProperties& rTextStyleProperties,
const TextListStyle& rMasterTextListStyle,
const TextListStyle& rTextListStyle, bool bFirst,
- float nDefaultCharHeight, sal_Int32 nAutofitFontScale) const
+ float nDefaultCharHeight) const
{
try {
sal_Int32 nParagraphSize = 0;
@@ -176,7 +176,7 @@ void TextParagraph::insertAt(
}
float fCharacterSize = nCharHeight > 0 ? GetFontHeight ( nCharHeight ) : pTextParagraphStyle->getCharHeightPoints( 12 );
- aParaProp.pushToPropSet( &rFilterBase, xProps, aioBulletList, &pTextParagraphStyle->getBulletList(), true, fCharacterSize, nAutofitFontScale, true );
+ aParaProp.pushToPropSet( &rFilterBase, xProps, aioBulletList, &pTextParagraphStyle->getBulletList(), true, fCharacterSize, true );
}
// empty paragraphs do not have bullets in ppt
diff --git a/oox/source/drawingml/textparagraphproperties.cxx b/oox/source/drawingml/textparagraphproperties.cxx
index af65e0037d16..8122c4e53324 100644
--- a/oox/source/drawingml/textparagraphproperties.cxx
+++ b/oox/source/drawingml/textparagraphproperties.cxx
@@ -407,7 +407,7 @@ void TextParagraphProperties::apply( const TextParagraphProperties& rSourceProps
void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase* pFilterBase,
const Reference < XPropertySet >& xPropSet, PropertyMap& rioBulletMap, const BulletList* pMasterBuList, bool bApplyBulletMap, float fCharacterSize,
- sal_Int32 nAutofitFontScale, bool bPushDefaultValues ) const
+ bool bPushDefaultValues ) const
{
PropertySet aPropSet( xPropSet );
aPropSet.setProperties( maTextParagraphPropertyMap );
@@ -433,14 +433,6 @@ void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase* p
std::optional< sal_Int32 > noParaLeftMargin( moParaLeftMargin );
std::optional< sal_Int32 > noFirstLineIndentation( moFirstLineIndentation );
- // tdf#149961 Impress scales the indents when text is autofitted while Powerpoint doesn't
- // Try to counteract this by multiplying indents by the inverse of the autofit font scale.
- if ( nAutofitFontScale )
- {
- if ( noParaLeftMargin ) noParaLeftMargin = *noParaLeftMargin * MAX_PERCENT / nAutofitFontScale;
- if ( noFirstLineIndentation ) noFirstLineIndentation = *noFirstLineIndentation * MAX_PERCENT / nAutofitFontScale;
- }
-
if ( nNumberingType != NumberingType::NUMBER_NONE )
{
if ( noParaLeftMargin )
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 664d589d34fd..44877b10eaa2 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -3195,7 +3195,7 @@ void DrawingML::WriteLinespacing(const LineSpacing& rSpacing, float fFirstCharHe
}
}
-bool DrawingML::WriteParagraphProperties(const Reference<XTextContent>& rParagraph, const Reference<XPropertySet>& rXShapePropSet, float fFirstCharHeight, sal_Int32 nElement)
+bool DrawingML::WriteParagraphProperties(const Reference<XTextContent>& rParagraph, float fFirstCharHeight, sal_Int32 nElement)
{
Reference< XPropertySet > rXPropSet( rParagraph, UNO_QUERY );
Reference< XPropertyState > rXPropState( rParagraph, UNO_QUERY );
@@ -3289,24 +3289,6 @@ bool DrawingML::WriteParagraphProperties(const Reference<XTextContent>& rParagra
if (GetProperty(rXPropSet, "ParaTabStopDefaultDistance"))
mAny >>= nParaDefaultTabSize;
- // for autofitted textboxes, scale the indents
- if (GetProperty(rXShapePropSet, "TextFitToSize") && mAny.get<TextFitToSizeType>() == TextFitToSizeType_AUTOFIT)
- {
- SvxShapeText* pTextShape = dynamic_cast<SvxShapeText*>(rXShapePropSet.get());
- if (pTextShape)
- {
- SdrTextObj* pTextObject = DynCastSdrTextObj(pTextShape->GetSdrObject());
- if (pTextObject)
- {
- const auto nFontScaleY = pTextObject->GetFontScaleY();
- nLeftMargin = nLeftMargin * nFontScaleY / 100;
- nLineIndentation = nLineIndentation * nFontScaleY / 100;
- nParaLeftMargin = nParaLeftMargin * nFontScaleY / 100;
- nParaFirstLineIndent = nParaFirstLineIndent * nFontScaleY / 100;
- }
- }
- }
-
if (nParaLeftMargin) // For Paragraph
mpFS->startElementNS( XML_a, nElement,
XML_lvl, sax_fastparser::UseIf(OString::number(nLevel), nLevel > 0),
@@ -3396,7 +3378,7 @@ void DrawingML::WriteLstStyles(const css::uno::Reference<css::text::XTextContent
fFirstCharHeight = xFirstRunPropSet->getPropertyValue("CharHeight").get<float>();
mpFS->startElementNS(XML_a, XML_lstStyle);
- if( !WriteParagraphProperties(rParagraph, rXShapePropSet, fFirstCharHeight, XML_lvl1pPr) )
+ if( !WriteParagraphProperties(rParagraph, fFirstCharHeight, XML_lvl1pPr) )
mpFS->startElementNS(XML_a, XML_lvl1pPr);
WriteRunProperties(xFirstRunPropSet, false, XML_defRPr, true, rbOverridingCharHeight,
rnCharHeight, GetScriptType(rRun->getString()), rXShapePropSet);
@@ -3438,7 +3420,7 @@ void DrawingML::WriteParagraph( const Reference< XTextContent >& rParagraph,
rnCharHeight = 100 * fFirstCharHeight;
rbOverridingCharHeight = true;
}
- WriteParagraphProperties(rParagraph, rXShapePropSet, fFirstCharHeight, XML_pPr);
+ WriteParagraphProperties(rParagraph, fFirstCharHeight, XML_pPr);
bPropertiesWritten = true;
}
WriteRun( run, rbOverridingCharHeight, rnCharHeight, rXShapePropSet);
@@ -3984,16 +3966,29 @@ void DrawingML::WriteText(const Reference<XInterface>& rXIface, bool bBodyPr, bo
{
const sal_Int32 MAX_SCALE_VAL = 100000;
sal_Int32 nFontScale = MAX_SCALE_VAL;
+ sal_Int32 nSpacingReduction = 0;
SvxShapeText* pTextShape = dynamic_cast<SvxShapeText*>(rXIface.get());
if (pTextShape)
{
SdrTextObj* pTextObject = DynCastSdrTextObj(pTextShape->GetSdrObject());
if (pTextObject)
- nFontScale = pTextObject->GetFontScaleY() * 1000;
+ {
+ nFontScale = sal_Int32(pTextObject->GetFontScale() * 1000.0);
+ nSpacingReduction = sal_Int32((100.0 - pTextObject->GetSpacingScale()) * 1000.0);
+ }
}
- mpFS->singleElementNS(XML_a, XML_normAutofit, XML_fontScale,
- sax_fastparser::UseIf(OString::number(nFontScale), nFontScale < MAX_SCALE_VAL && nFontScale > 0));
+ bool bExportFontScale = false;
+ if (nFontScale < MAX_SCALE_VAL && nFontScale > 0)
+ bExportFontScale = true;
+
+ bool bExportSpaceReduction = false;
+ if (nSpacingReduction < MAX_SCALE_VAL && nSpacingReduction > 0)
+ bExportSpaceReduction = true;
+
+ mpFS->singleElementNS(XML_a, XML_normAutofit,
+ XML_fontScale, sax_fastparser::UseIf(OString::number(nFontScale), bExportFontScale),
+ XML_lnSpcReduction, sax_fastparser::UseIf(OString::number(nSpacingReduction), bExportSpaceReduction));
}
else
{
@@ -4057,7 +4052,7 @@ void DrawingML::WriteText(const Reference<XInterface>& rXIface, bool bBodyPr, bo
if( aAny >>= xParagraph )
{
mpFS->startElementNS(XML_a, XML_p);
- WriteParagraphProperties(xParagraph, rXPropSet, nCharHeight, XML_pPr);
+ WriteParagraphProperties(xParagraph, nCharHeight, XML_pPr);
sal_Int16 nDummy = -1;
WriteRunProperties(rXPropSet, false, XML_endParaRPr, false,
bOverridingCharHeight, nCharHeight, nDummy, rXPropSet);