Kaydet (Commit) ff17478e authored tarafından Miklos Vajna's avatar Miklos Vajna

sw btlr writing mode: implement DOCX shape import for tbrl

Now that the btlr writing mode works reasonably well in table cells, the
next context is shape text. But turns out that DOCX shape text lacked
support in the easier tbrl case, so add that first.

Also remove the char-level text rotation code in oox, that is
effectively dead code since we import drawingML shapes as shape +
Writer TextBox.

Change-Id: I30c7793221cc3aceedfcfd9e4e1725634ebb3309
Reviewed-on: https://gerrit.libreoffice.org/71329
Tested-by: Jenkins
Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.com>
üst 647660cf
......@@ -59,61 +59,39 @@ oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken
{
uno::Reference<lang::XServiceInfo> xServiceInfo(mxShape, uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
OptValue<OUString> oVert = rAttribs.getString(XML_vert);
if (oVert.has() && oVert.get() == "vert270")
sal_Int32 nVert = rAttribs.getToken(XML_vert, XML_horz);
if (nVert != XML_horz)
{
if (xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
{
// No support for this in core, work around by char rotation, as we do so for table cells already.
uno::Reference<text::XText> xText(mxShape, uno::UNO_QUERY);
uno::Reference<text::XTextCursor> xTextCursor = xText->createTextCursor();
xTextCursor->gotoStart(false);
xTextCursor->gotoEnd(true);
uno::Reference<beans::XPropertyState> xPropertyState(xTextCursor,
uno::UNO_QUERY);
beans::PropertyState aState
= xPropertyState->getPropertyState("CharRotation");
if (aState == beans::PropertyState_DEFAULT_VALUE)
{
uno::Reference<beans::XPropertySet> xTextCursorPropertySet(
xTextCursor, uno::UNO_QUERY);
xTextCursorPropertySet->setPropertyValue("CharRotation",
uno::makeAny(sal_Int16(900)));
}
}
else
{
// Get the existing rotation of the shape.
drawing::HomogenMatrix3 aMatrix;
xPropertySet->getPropertyValue("Transformation") >>= aMatrix;
basegfx::B2DHomMatrix aTransformation;
aTransformation.set(0, 0, aMatrix.Line1.Column1);
aTransformation.set(0, 1, aMatrix.Line1.Column2);
aTransformation.set(0, 2, aMatrix.Line1.Column3);
aTransformation.set(1, 0, aMatrix.Line1.Column1);
aTransformation.set(1, 1, aMatrix.Line2.Column2);
aTransformation.set(1, 2, aMatrix.Line3.Column3);
aTransformation.set(2, 0, aMatrix.Line1.Column1);
aTransformation.set(2, 1, aMatrix.Line2.Column2);
aTransformation.set(2, 2, aMatrix.Line3.Column3);
basegfx::B2DTuple aScale;
basegfx::B2DTuple aTranslate;
double fRotate = 0;
double fShearX = 0;
aTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
// Get the existing rotation of the shape.
drawing::HomogenMatrix3 aMatrix;
xPropertySet->getPropertyValue("Transformation") >>= aMatrix;
basegfx::B2DHomMatrix aTransformation;
aTransformation.set(0, 0, aMatrix.Line1.Column1);
aTransformation.set(0, 1, aMatrix.Line1.Column2);
aTransformation.set(0, 2, aMatrix.Line1.Column3);
aTransformation.set(1, 0, aMatrix.Line1.Column1);
aTransformation.set(1, 1, aMatrix.Line2.Column2);
aTransformation.set(1, 2, aMatrix.Line3.Column3);
aTransformation.set(2, 0, aMatrix.Line1.Column1);
aTransformation.set(2, 1, aMatrix.Line2.Column2);
aTransformation.set(2, 2, aMatrix.Line3.Column3);
basegfx::B2DTuple aScale;
basegfx::B2DTuple aTranslate;
double fRotate = 0;
double fShearX = 0;
aTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
// If the text is not rotated the way the shape wants it already, set the angle.
const sal_Int32 nRotation = -270;
if (static_cast<long>(basegfx::rad2deg(fRotate))
!= NormAngle36000(static_cast<long>(nRotation) * 100) / 100)
{
comphelper::SequenceAsHashMap aCustomShapeGeometry(
xPropertySet->getPropertyValue("CustomShapeGeometry"));
aCustomShapeGeometry["TextPreRotateAngle"] <<= nRotation;
xPropertySet->setPropertyValue(
"CustomShapeGeometry",
uno::makeAny(aCustomShapeGeometry.getAsConstPropertyValueList()));
}
// If the text is not rotated the way the shape wants it already, set the angle.
const sal_Int32 nRotation = nVert == XML_vert270 ? -270 : -90;
if (static_cast<long>(basegfx::rad2deg(fRotate))
!= NormAngle36000(static_cast<long>(nRotation) * 100) / 100)
{
comphelper::SequenceAsHashMap aCustomShapeGeometry(
xPropertySet->getPropertyValue("CustomShapeGeometry"));
aCustomShapeGeometry["TextPreRotateAngle"] <<= nRotation;
xPropertySet->setPropertyValue(
"CustomShapeGeometry",
uno::makeAny(aCustomShapeGeometry.getAsConstPropertyValueList()));
}
}
......
......@@ -65,6 +65,16 @@ DECLARE_OOXMLEXPORT_TEST(testendingSectionProps, "endingSectionProps.docx")
//CPPUNIT_ASSERT_EQUAL_MESSAGE("Section Left Margin", sal_Int32(2540), getProperty<sal_Int32>(xSect, "SectionLeftMargin"));
}
DECLARE_OOXMLEXPORT_TEST(testTbrlTextbox, "tbrl-textbox.docx")
{
uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY);
comphelper::SequenceAsHashMap aGeometry(xPropertySet->getPropertyValue("CustomShapeGeometry"));
// Without the accompanying fix in place, this test would have failed with 'Expected: -90;
// Actual: 0', i.e. tbRl writing direction was imported as lrTb.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-90),
aGeometry["TextPreRotateAngle"].get<sal_Int32>());
}
DECLARE_OOXMLEXPORT_TEST(testTdf124637_sectionMargin, "tdf124637_sectionMargin.docx")
{
uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
......
......@@ -44,6 +44,7 @@
#include <com/sun/star/text/WrapTextMode.hpp>
#include <com/sun/star/text/XTextDocument.hpp>
#include <com/sun/star/table/BorderLine2.hpp>
#include <com/sun/star/text/WritingMode2.hpp>
using namespace com::sun::star;
......@@ -349,29 +350,49 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, const OUString& rPrope
uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Top()))));
}
if (SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
if (!pFormat)
return;
comphelper::SequenceAsHashMap aCustomShapeGeometry(rValue);
auto it = aCustomShapeGeometry.find("TextPreRotateAngle");
if (it != aCustomShapeGeometry.end())
{
comphelper::SequenceAsHashMap aCustomShapeGeometry(rValue);
// That would be the btLr text direction which we don't support at a frame level, so do it at a character level.
if (aCustomShapeGeometry.find("TextPreRotateAngle") != aCustomShapeGeometry.end()
&& aCustomShapeGeometry["TextPreRotateAngle"].get<sal_Int32>() == -270)
auto nTextPreRotateAngle = it->second.get<sal_Int32>();
if (nTextPreRotateAngle == -270)
{
if (const SwNodeIndex* pNodeIndex = pFormat->GetContent().GetContentIdx())
// That would be the btLr text direction which we don't support at a frame level, so
// do it at a character level.
const SwNodeIndex* pNodeIndex = pFormat->GetContent().GetContentIdx();
if (!pNodeIndex)
return;
SwPaM aPaM(*pFormat->GetDoc()->GetNodes()[pNodeIndex->GetIndex() + 1], 0);
aPaM.SetMark();
if (SwTextNode* pMark
= pFormat->GetDoc()
->GetNodes()[pNodeIndex->GetNode().EndOfSectionIndex() - 1]
->GetTextNode())
{
SwPaM aPaM(*pFormat->GetDoc()->GetNodes()[pNodeIndex->GetIndex() + 1], 0);
aPaM.SetMark();
if (SwTextNode* pMark
= pFormat->GetDoc()
->GetNodes()[pNodeIndex->GetNode().EndOfSectionIndex() - 1]
->GetTextNode())
{
aPaM.GetMark()->nNode = *pMark;
aPaM.GetMark()->nContent.Assign(pMark, pMark->GetText().getLength());
SvxCharRotateItem aItem(900, false, RES_CHRATR_ROTATE);
pFormat->GetDoc()->getIDocumentContentOperations().InsertPoolItem(aPaM,
aItem);
}
aPaM.GetMark()->nNode = *pMark;
aPaM.GetMark()->nContent.Assign(pMark, pMark->GetText().getLength());
SvxCharRotateItem aItem(900, false, RES_CHRATR_ROTATE);
pFormat->GetDoc()->getIDocumentContentOperations().InsertPoolItem(aPaM, aItem);
}
return;
}
sal_Int16 nDirection = 0;
switch (nTextPreRotateAngle)
{
case -90:
nDirection = text::WritingMode2::TB_RL;
break;
}
if (nDirection)
{
syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(nDirection));
}
}
}
......@@ -548,6 +569,9 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_u
case RES_OPAQUE:
aPropertyName = UNO_NAME_OPAQUE;
break;
case RES_FRAMEDIR:
aPropertyName = UNO_NAME_WRITING_MODE;
break;
}
if (!aPropertyName.isEmpty())
......
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