Kaydet (Commit) 2c2919cb authored tarafından Szymon Kłos's avatar Szymon Kłos

PPTX export scale for TextFitToSize

MSO requires to save fontScale attribute to have
all the text shown properly (with FitToSize property)

Values are approximated, after any modification in MSO
scale is recalculated.

Change-Id: I73657fdd663b540b436747cfeeef3c76e8fe388c
Reviewed-on: https://gerrit.libreoffice.org/49742Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarSzymon Kłos <szymon.klos@collabora.com>
üst 168c5e49
......@@ -213,6 +213,7 @@ protected:
virtual SdrObject* getFullDragClone() const override;
public:
const Point& GetTextEditOffset() const { return maTextEditOffset; }
void SetTextEditOffset(const Point& rNew) { maTextEditOffset = rNew; }
......@@ -385,6 +386,7 @@ public:
// FitToSize and Fontwork are not taken into account in GetTextSize()!
virtual const Size& GetTextSize() const;
void FitFrameToTextSize();
double GetFontScaleY() const;
// Simultaneously sets the text into the Outliner (possibly
// the one of the EditOutliner) and sets the PaperSize.
......
......@@ -2553,8 +2553,25 @@ void DrawingML::WriteText( const Reference< XInterface >& rXIface, const OUStrin
TextFitToSizeType eFit = TextFitToSizeType_NONE;
if (GETA(TextFitToSize))
mAny >>= eFit;
if (eFit == TextFitToSizeType_AUTOFIT)
mpFS->singleElementNS(XML_a, XML_normAutofit, FSEND);
{
const sal_Int32 MAX_SCALE_VAL = 100000;
sal_Int32 nFontScale = MAX_SCALE_VAL;
SvxShapeText* pTextShape = dynamic_cast<SvxShapeText*>(rXIface.get());
if (pTextShape)
{
SdrTextObj* pTextObject = dynamic_cast<SdrTextObj*>(pTextShape->GetSdrObject());
if (pTextObject)
{
double fScaleY = pTextObject->GetFontScaleY();
nFontScale = static_cast<sal_uInt32>(fScaleY * 100) * 1000;
}
}
mpFS->singleElementNS(XML_a, XML_normAutofit, XML_fontScale,
( nFontScale < MAX_SCALE_VAL && nFontScale > 0 ) ? I32S(nFontScale) : nullptr, FSEND);
}
}
mpFS->endElementNS((nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr);
}
......
......@@ -128,6 +128,7 @@ public:
void testTdf90626();
void testTdf107608();
void testTdf111786();
void testFontScale();
void testTdf115394();
void testTdf115394Zero();
......@@ -183,6 +184,7 @@ public:
CPPUNIT_TEST(testTdf90626);
CPPUNIT_TEST(testTdf107608);
CPPUNIT_TEST(testTdf111786);
CPPUNIT_TEST(testFontScale);
CPPUNIT_TEST(testTdf115394);
CPPUNIT_TEST(testTdf115394Zero);
......@@ -1406,6 +1408,18 @@ void SdOOXMLExportTest2::testTdf111786()
xDocShRef->DoClose();
}
void SdOOXMLExportTest2::testFontScale()
{
sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/font-scale.pptx"), PPTX);
utl::TempFile tempFile;
xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
xmlDocPtr pXmlDocContent = parseExport(tempFile, "ppt/slides/slide1.xml");
assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:bodyPr/a:normAutofit", "fontScale", "73000");
xDocShRef->DoClose();
}
void SdOOXMLExportTest2::testTdf115394()
{
sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf115394.pptx"), PPTX);
......
......@@ -1259,6 +1259,69 @@ void SdrTextObj::ImpSetupDrawOutlinerForPaint( bool bContourFrame,
}
}
double SdrTextObj::GetFontScaleY() const
{
SdrText* pText = getActiveText();
if (pText == nullptr || !pText->GetOutlinerParaObject() || pModel == nullptr)
return 1.0;
SdrOutliner& rOutliner = ImpGetDrawOutliner();
const Size aShapeSize = GetSnapRect().GetSize();
const Size aSize = Size(aShapeSize.Width() - GetTextLeftDistance() - GetTextRightDistance(),
aShapeSize.Height() - GetTextUpperDistance() - GetTextLowerDistance());
rOutliner.SetPaperSize(aSize);
rOutliner.SetUpdateMode(true);
rOutliner.SetText(*pText->GetOutlinerParaObject());
bool bIsVerticalWriting = IsVerticalWriting();
// Algorithm from SdrTextObj::ImpAutoFitText
sal_uInt16 nMinStretchX = 0, nMinStretchY = 0;
sal_uInt16 nCurrStretchX = 100, nCurrStretchY = 100;
sal_uInt16 aOldStretchXVals[] = { 0,0,0 };
const size_t aStretchArySize = SAL_N_ELEMENTS(aOldStretchXVals);
for (unsigned int i = 0; i<aStretchArySize; ++i)
{
const Size aCurrTextSize = rOutliner.CalcTextSizeNTP();
double fFactor(1.0);
if (bIsVerticalWriting)
{
if (aCurrTextSize.Width() != 0)
{
fFactor = double(aSize.Width()) / aCurrTextSize.Width();
}
}
else if (aCurrTextSize.Height() != 0)
{
fFactor = double(aSize.Height()) / aCurrTextSize.Height();
}
fFactor = std::sqrt(fFactor);
rOutliner.GetGlobalCharStretching(nCurrStretchX, nCurrStretchY);
if (fFactor >= 1.0)
{
nMinStretchX = std::max(nMinStretchX, nCurrStretchX);
nMinStretchY = std::max(nMinStretchY, nCurrStretchY);
}
aOldStretchXVals[i] = nCurrStretchX;
if (std::find(aOldStretchXVals, aOldStretchXVals + i, nCurrStretchX) != aOldStretchXVals + i)
break; // same value already attained once; algo is looping, exit
if (fFactor < 1.0 || nCurrStretchX != 100)
{
nCurrStretchX = sal::static_int_cast<sal_uInt16>(nCurrStretchX*fFactor);
nCurrStretchY = sal::static_int_cast<sal_uInt16>(nCurrStretchY*fFactor);
rOutliner.SetGlobalCharStretching(std::min(sal_uInt16(100), nCurrStretchX),
std::min(sal_uInt16(100), nCurrStretchY));
}
}
return std::min(sal_uInt16(100), nCurrStretchY) / 100.0;
}
void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner ) const
{
const Size aShapeSize=GetSnapRect().GetSize();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment