tdf#128213 Fix text camera z rotation import and export.

Text3DProperties is added to distinguish shape and text 3D effects.
Before there was implementation error about text camera z rotation
support. We were using shape effects for text. We already have not
support shape 3D rotation but we have text camera z rotation. This
patch includes import and export filter changes about text camera z
rotation.

Change-Id: I623392b82edf4585888d2f15ad91ffb2109d8f96
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106033
Tested-by: Jenkins
Reviewed-by: Gülşah Köse <gulsah.kose@collabora.com>
This commit is contained in:
Gülşah Köse
2020-11-17 12:43:12 +03:00
parent 6fa1161d31
commit 72998fc859
9 changed files with 126 additions and 24 deletions

View File

@@ -41,14 +41,23 @@ private:
class Scene3DPropertiesContext final : public ::oox::core::ContextHandler2
{
public:
Scene3DPropertiesContext( ::oox::core::ContextHandler2Helper const & rParent, Shape3DProperties& r3DProperties ) throw();
Scene3DPropertiesContext( ::oox::core::ContextHandler2Helper const & rParent, Shape3DProperties& rShape3DProperties ) throw();
::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 Element, const ::oox::AttributeList& rAttribs ) override;
private:
Shape3DProperties& mr3DProperties;
};
class SceneText3DPropertiesContext final : public ::oox::core::ContextHandler2
{
public:
SceneText3DPropertiesContext( ::oox::core::ContextHandler2Helper const & rParent, Text3DProperties& rText3DProperties ) throw();
::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 Element, const ::oox::AttributeList& rAttribs ) override;
private:
Text3DProperties& mr3DProperties;
};
class Shape3DPropertiesContext final : public ::oox::core::ContextHandler2
{
public:

View File

@@ -44,7 +44,7 @@ struct BevelProperties
OptValue< sal_Int32 > mnHeight;
};
struct Shape3DProperties
struct Generic3DProperties
{
OptValue< sal_Int32 > mnPreset;
OptValue< float > mfFieldOfVision;
@@ -79,6 +79,11 @@ struct Shape3DProperties
const Color& rColor, const GraphicHelper& rGraphicHelper, ::Color rPhClr );
};
struct Shape3DProperties : Generic3DProperties
{};
struct Text3DProperties : Generic3DProperties
{};
} // namespace oox::drawingml

View File

@@ -23,6 +23,7 @@
#include <oox/drawingml/drawingmltypes.hxx>
#include <drawingml/textbodyproperties.hxx>
#include <drawingml/textliststyle.hxx>
#include <drawingml/shape3dproperties.hxx>
namespace com::sun::star::text {
class XText;
@@ -53,6 +54,9 @@ public:
const TextBodyProperties& getTextProperties() const { return maTextProperties; }
TextBodyProperties& getTextProperties() { return maTextProperties; }
Text3DProperties& get3DProperties() { return ma3DProperties; }
const Text3DProperties& get3DProperties() const { return ma3DProperties; }
/** insert the text body at the text cursor */
void insertAt(
const ::oox::core::XmlFilterBase& rFilterBase,
@@ -72,6 +76,7 @@ protected:
TextParagraphVector maParagraphs;
TextBodyProperties maTextProperties;
TextListStyle maTextListStyle;
Text3DProperties ma3DProperties;
};
}

View File

@@ -63,6 +63,39 @@ ContextHandlerRef Scene3DPropertiesContext::onCreateContext( sal_Int32 aElementT
return nullptr;
}
SceneText3DPropertiesContext::SceneText3DPropertiesContext( ContextHandler2Helper const & rParent, Text3DProperties& r3DProperties ) throw()
: ContextHandler2( rParent )
, mr3DProperties( r3DProperties )
{
}
ContextHandlerRef SceneText3DPropertiesContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
{
switch( aElementToken )
{
case A_TOKEN( camera ):
if( rAttribs.hasAttribute( XML_fov ) )
mr3DProperties.mfFieldOfVision = rAttribs.getInteger( XML_fov, 0 ) / 60000.0; // 60000ths of degree
if( rAttribs.hasAttribute( XML_zoom ) )
mr3DProperties.mfZoom = rAttribs.getInteger( XML_zoom, 100000 ) / 100000.0;
if( rAttribs.hasAttribute( XML_prst ) )
mr3DProperties.mnPreset = rAttribs.getToken( XML_prst, XML_none );
return new Scene3DRotationPropertiesContext( *this, mr3DProperties.maCameraRotation );
case A_TOKEN( lightRig ):
mr3DProperties.mnLightRigDirection = rAttribs.getToken( XML_dir, XML_none );
mr3DProperties.mnLightRigType = rAttribs.getToken( XML_rig, XML_none );
return new Scene3DRotationPropertiesContext( *this, mr3DProperties.maLightRigRotation );
case A_TOKEN( backdrop ):
case A_TOKEN( extLst ):
return nullptr; // TODO: later (backdrop is not supported by core anyway)
}
return nullptr;
}
Shape3DPropertiesContext::Shape3DPropertiesContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, Shape3DProperties& r3DProperties ) throw()
: ContextHandler2( rParent )
, mr3DProperties( r3DProperties )

View File

@@ -1377,6 +1377,24 @@ Reference< XShape > const & Shape::createAndInsert(
putPropertyToGrabBag( "3DEffectProperties", Any( a3DEffectsGrabBag ) );
}
if( bIsCustomShape && getTextBody())
{
Sequence< PropertyValue > aTextCamera3DEffects = getTextBody()->get3DProperties().getCameraAttributes();
Sequence< PropertyValue > aTextLightRig3DEffects = getTextBody()->get3DProperties().getLightRigAttributes();
Sequence< PropertyValue > aTextShape3DEffects = getTextBody()->get3DProperties().getShape3DAttributes( rGraphicHelper, nFillPhClr );
if( aTextCamera3DEffects.hasElements() || aTextLightRig3DEffects.hasElements() || aTextShape3DEffects.hasElements() )
{
uno::Sequence<beans::PropertyValue> aText3DEffectsGrabBag = comphelper::InitPropertySequence(
{
{"Camera", uno::makeAny(aTextCamera3DEffects)},
{"LightRig", uno::makeAny(aTextLightRig3DEffects)},
{"Shape3D", uno::makeAny(aTextShape3DEffects)}
});
putPropertyToGrabBag( "Text3DEffectProperties", Any( aText3DEffectsGrabBag ) );
}
}
// store bitmap artistic effects in the grab bag
if( !mpGraphicPropertiesPtr->maBlipProps.maEffect.isEmpty() )
putPropertyToGrabBag( "ArtisticEffectProperties",
@@ -1403,7 +1421,7 @@ Reference< XShape > const & Shape::createAndInsert(
mpCustomShapePropertiesPtr->setMirroredY( true );
if( getTextBody() )
{
sal_Int32 nTextCameraZRotation = static_cast< sal_Int32 >( get3DProperties().maCameraRotation.mnRevolution.get() );
sal_Int32 nTextCameraZRotation = static_cast< sal_Int32 >( getTextBody()->get3DProperties().maCameraRotation.mnRevolution.get() );
mpCustomShapePropertiesPtr->setTextCameraZRotateAngle( nTextCameraZRotation / 60000 );
sal_Int32 nTextRotateAngle = static_cast< sal_Int32 >( getTextBody()->getTextProperties().moRotation.get( 0 ) );

View File

@@ -30,7 +30,7 @@ using namespace ::com::sun::star::graphic;
namespace oox::drawingml {
OUString Shape3DProperties::getCameraPrstName( sal_Int32 nElement )
OUString Generic3DProperties::getCameraPrstName( sal_Int32 nElement )
{
switch( nElement )
{
@@ -97,11 +97,11 @@ OUString Shape3DProperties::getCameraPrstName( sal_Int32 nElement )
case XML_perspectiveRelaxed: return "perspectiveRelaxed";
case XML_perspectiveRelaxedModerately: return "perspectiveRelaxedModerately";
}
SAL_WARN( "oox.drawingml", "Shape3DProperties::getCameraPrstName - unexpected prst type" );
SAL_WARN( "oox.drawingml", "Generic3DProperties::getCameraPrstName - unexpected prst type" );
return OUString();
}
OUString Shape3DProperties::getLightRigName( sal_Int32 nElement )
OUString Generic3DProperties::getLightRigName( sal_Int32 nElement )
{
switch( nElement )
{
@@ -133,11 +133,11 @@ OUString Shape3DProperties::getLightRigName( sal_Int32 nElement )
case XML_glow: return "glow";
case XML_brightRoom: return "brightRoom";
}
SAL_WARN( "oox.drawingml", "Shape3DProperties::getLightRigName - unexpected token" );
SAL_WARN( "oox.drawingml", "Generic3DProperties::getLightRigName - unexpected token" );
return OUString();
}
OUString Shape3DProperties::getLightRigDirName( sal_Int32 nElement )
OUString Generic3DProperties::getLightRigDirName( sal_Int32 nElement )
{
switch( nElement )
{
@@ -150,11 +150,11 @@ OUString Shape3DProperties::getLightRigDirName( sal_Int32 nElement )
case XML_b: return "b";
case XML_br: return "br";
}
SAL_WARN( "oox.drawingml", "Shape3DProperties::getLightRigDirName - unexpected token" );
SAL_WARN( "oox.drawingml", "Generic3DProperties::getLightRigDirName - unexpected token" );
return OUString();
}
OUString Shape3DProperties::getBevelPresetTypeString( sal_Int32 nType )
OUString Generic3DProperties::getBevelPresetTypeString( sal_Int32 nType )
{
switch (nType)
{
@@ -171,11 +171,11 @@ OUString Shape3DProperties::getBevelPresetTypeString( sal_Int32 nType )
case XML_hardEdge: return "hardEdge";
case XML_artDeco: return "artDeco";
}
SAL_WARN( "oox.drawingml", "Shape3DProperties::getBevelPresetTypeString - unexpected token" );
SAL_WARN( "oox.drawingml", "Generic3DProperties::getBevelPresetTypeString - unexpected token" );
return OUString();
}
OUString Shape3DProperties::getPresetMaterialTypeString( sal_Int32 nType )
OUString Generic3DProperties::getPresetMaterialTypeString( sal_Int32 nType )
{
switch (nType)
{
@@ -196,11 +196,11 @@ OUString Shape3DProperties::getPresetMaterialTypeString( sal_Int32 nType )
case XML_softmetal: return "softmetal";
case XML_none: return "none";
}
SAL_WARN( "oox.drawingml", "Shape3DProperties::getPresetMaterialTypeString - unexpected token" );
SAL_WARN( "oox.drawingml", "Generic3DProperties::getPresetMaterialTypeString - unexpected token" );
return OUString();
}
css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getCameraAttributes()
css::uno::Sequence< css::beans::PropertyValue > Generic3DProperties::getCameraAttributes()
{
css::uno::Sequence<css::beans::PropertyValue> aSeq(6);
sal_Int32 nSize = 0;
@@ -244,7 +244,7 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getCameraAttr
return aSeq;
}
css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getLightRigAttributes()
css::uno::Sequence< css::beans::PropertyValue > Generic3DProperties::getLightRigAttributes()
{
css::uno::Sequence<css::beans::PropertyValue> aSeq(5);
sal_Int32 nSize = 0;
@@ -282,7 +282,7 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getLightRigAt
return aSeq;
}
css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getBevelAttributes( BevelProperties rProps )
css::uno::Sequence< css::beans::PropertyValue > Generic3DProperties::getBevelAttributes( BevelProperties rProps )
{
css::uno::Sequence<css::beans::PropertyValue> aSeq(3);
sal_Int32 nSize = 0;
@@ -308,7 +308,7 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getBevelAttri
return aSeq;
}
css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getColorAttributes(
css::uno::Sequence< css::beans::PropertyValue > Generic3DProperties::getColorAttributes(
const Color& rColor, const GraphicHelper& rGraphicHelper, ::Color rPhClr )
{
css::uno::Sequence<css::beans::PropertyValue> aSeq(2);
@@ -332,7 +332,7 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getColorAttri
return aSeq;
}
css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getShape3DAttributes(
css::uno::Sequence< css::beans::PropertyValue > Generic3DProperties::getShape3DAttributes(
const GraphicHelper& rGraphicHelper, ::Color rPhClr )
{
css::uno::Sequence<css::beans::PropertyValue> aSeq(8);

View File

@@ -170,7 +170,7 @@ ContextHandlerRef TextBodyPropertiesContext::onCreateContext( sal_Int32 aElement
case A_TOKEN( scene3d ): // CT_Scene3D
{
if(mpShapePtr && mpShapePtr->getServiceName() == "com.sun.star.drawing.CustomShape")
return new Scene3DPropertiesContext( *this, mpShapePtr->get3DProperties() );
return new SceneText3DPropertiesContext( *this, mpShapePtr->getTextBody()->get3DProperties() );
break;
}

View File

@@ -3178,6 +3178,9 @@ void DrawingML::WriteText(const Reference<XInterface>& rXIface, bool bBodyPr, bo
mpFS->singleElementNS(XML_a, (bTextAutoGrowHeight ? XML_spAutoFit : XML_noAutofit));
}
}
WriteShape3DEffects( rXPropSet );
mpFS->endElementNS((nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr);
}
@@ -4245,12 +4248,12 @@ void DrawingML::WriteShape3DEffects( const Reference< XPropertySet >& xPropSet )
// extract the relevant properties from the grab bag
Sequence< PropertyValue > aGrabBag, aEffectProps, aLightRigProps, aShape3DProps;
mAny >>= aGrabBag;
auto pProp = std::find_if(std::cbegin(aGrabBag), std::cend(aGrabBag),
auto pShapeProp = std::find_if(std::cbegin(aGrabBag), std::cend(aGrabBag),
[](const PropertyValue& rProp) { return rProp.Name == "3DEffectProperties"; });
if (pProp != std::cend(aGrabBag))
if (pShapeProp != std::cend(aGrabBag))
{
Sequence< PropertyValue > a3DEffectProps;
pProp->Value >>= a3DEffectProps;
pShapeProp->Value >>= a3DEffectProps;
for( const auto& r3DEffectProp : std::as_const(a3DEffectProps) )
{
if( r3DEffectProp.Name == "Camera" )
@@ -4261,6 +4264,25 @@ void DrawingML::WriteShape3DEffects( const Reference< XPropertySet >& xPropSet )
r3DEffectProp.Value >>= aShape3DProps;
}
}
auto pTextProp = std::find_if(std::cbegin(aGrabBag), std::cend(aGrabBag),
[](const PropertyValue& rProp) { return rProp.Name == "Text3DEffectProperties"; });
if (pTextProp != std::cend(aGrabBag))
{
Sequence< PropertyValue > a3DEffectProps;
pTextProp->Value >>= a3DEffectProps;
for( const auto& r3DEffectProp : std::as_const(a3DEffectProps) )
{
if( r3DEffectProp.Name == "Camera" )
r3DEffectProp.Value >>= aEffectProps;
else if( r3DEffectProp.Name == "LightRig" )
r3DEffectProp.Value >>= aLightRigProps;
else if( r3DEffectProp.Name == "Shape3D" )
r3DEffectProp.Value >>= aShape3DProps;
}
}
if( !aEffectProps.hasElements() && !aLightRigProps.hasElements() && !aShape3DProps.hasElements() )
return;

View File

@@ -993,7 +993,17 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
WriteFill( rXPropSet );
WriteOutline( rXPropSet );
WriteShapeEffects( rXPropSet );
WriteShape3DEffects( rXPropSet );
bool bHas3DEffectinShape = false;
uno::Sequence<beans::PropertyValue> grabBag;
rXPropSet->getPropertyValue("InteropGrabBag") >>= grabBag;
for (auto const& it : std::as_const(grabBag))
if (it.Name == "3DEffectProperties")
bHas3DEffectinShape = true;
if( bHas3DEffectinShape)
WriteShape3DEffects( rXPropSet );
}
pFS->endElementNS( mnXmlNamespace, XML_spPr );