summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Rentz [dr] <daniel.rentz@oracle.com>2011-01-08 12:55:26 +0100
committerDaniel Rentz [dr] <daniel.rentz@oracle.com>2011-01-08 12:55:26 +0100
commitf9a2b2913692fa1d65200f53c90e77b0bd134445 (patch)
tree43eb5a578375e2617d4111f33b4b2441f26af6b9
parentbb282d6533202ce6056d6aed37774c59a2deab2a (diff)
dr78: oox - BIFF3-BIFF5 arcs and polygons, line and fill formatting
-rwxr-xr-xoox/inc/oox/xls/drawingmanager.hxx77
-rw-r--r--oox/source/drawingml/lineproperties.cxx26
-rw-r--r--oox/source/token/properties.txt4
-rwxr-xr-xoox/source/xls/drawingmanager.cxx472
-rw-r--r--oox/source/xls/worksheethelper.cxx2
5 files changed, 535 insertions, 46 deletions
diff --git a/oox/inc/oox/xls/drawingmanager.hxx b/oox/inc/oox/xls/drawingmanager.hxx
index 75ccb05da117..0e5610d05d24 100755
--- a/oox/inc/oox/xls/drawingmanager.hxx
+++ b/oox/inc/oox/xls/drawingmanager.hxx
@@ -53,12 +53,10 @@ struct BiffObjLineModel
sal_uInt8 mnColorIdx; /// Index into color palette.
sal_uInt8 mnStyle; /// Line dash style.
sal_uInt8 mnWidth; /// Line width.
- sal_uInt8 mnAuto; /// Automatic line flag.
+ bool mbAuto; /// True = automatic line format.
explicit BiffObjLineModel();
- /** Returns true, if the line formatting is set to automatic. */
- bool isAuto() const;
/** Returns true, if the line formatting is visible (automatic or explicit). */
bool isVisible() const;
};
@@ -71,12 +69,10 @@ struct BiffObjFillModel
sal_uInt8 mnBackColorIdx; /// Index to color palette for background color.
sal_uInt8 mnPattColorIdx; /// Index to color palette for pattern foreground color.
sal_uInt8 mnPattern; /// Fill pattern.
- sal_uInt8 mnAuto; /// Automatic fill flag.
+ bool mbAuto; /// True = automatic fill format.
explicit BiffObjFillModel();
- /** Returns true, if the fill formatting is set to automatic. */
- bool isAuto() const;
/** Returns true, if the fill formatting is visible (automatic or explicit). */
bool isFilled() const;
};
@@ -204,6 +200,13 @@ protected:
/** Reads the contents of the ftMacro sub structure in an OBJ record. */
void readMacroBiff8( BiffInputStream& rStrm );
+ /** Converts the passed line formatting to the passed property map. */
+ void convertLineProperties( PropertyMap& rPropMap, const BiffObjLineModel& rLineModel, sal_uInt16 nArrows = 0 ) const;
+ /** Converts the passed fill formatting to the passed property map. */
+ void convertFillProperties( PropertyMap& rPropMap, const BiffObjFillModel& rFillModel ) const;
+ /** Converts the passed frame flags to the passed property map. */
+ void convertFrameProperties( PropertyMap& rPropMap, sal_uInt16 nFrameFlags ) const;
+
/** Derived classes read the contents of the a BIFF3 OBJ record from the passed stream. */
virtual void implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize );
/** Derived classes read the contents of the a BIFF4 OBJ record from the passed stream. */
@@ -336,6 +339,9 @@ protected:
/** Reads the fill model, the line model, and frame flags. */
void readFrameData( BiffInputStream& rStrm );
+ /** Converts fill formatting, line formatting, and frame style. */
+ void convertRectProperties( PropertyMap& rPropMap ) const;
+
/** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
virtual void implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize );
/** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
@@ -372,6 +378,65 @@ protected:
};
// ============================================================================
+
+/** A simple arc object. */
+class BiffArcObject : public BiffDrawingObjectBase
+{
+public:
+ explicit BiffArcObject( const WorksheetHelper& rHelper );
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+
+ /** Creates the corresponding XShape and insert it into the passed container. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ implConvertAndInsert( BiffDrawingBase& rDrawing,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+
+protected:
+ BiffObjFillModel maFillModel; /// Fill formatting.
+ BiffObjLineModel maLineModel; /// Line formatting.
+ sal_uInt8 mnQuadrant; /// Visible quadrant of the circle.
+};
+
+// ============================================================================
+
+/** A simple polygon object. */
+class BiffPolygonObject : public BiffRectObject
+{
+public:
+ explicit BiffPolygonObject( const WorksheetHelper& rHelper );
+
+protected:
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+
+ /** Creates the corresponding XShape and insert it into the passed container. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ implConvertAndInsert( BiffDrawingBase& rDrawing,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+
+private:
+ /** Reads the COORDLIST record following the OBJ record. */
+ void importCoordList( BiffInputStream& rStrm );
+
+protected:
+ typedef ::std::vector< ::com::sun::star::awt::Point > PointVector;
+ PointVector maCoords; /// Coordinates relative to bounding rectangle.
+ sal_uInt16 mnPolyFlags; /// Additional flags.
+ sal_uInt16 mnPointCount; /// Polygon point count.
+};
+
+// ============================================================================
// BIFF drawing page
// ============================================================================
diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx
index 9f23cf466d30..a0836612fafb 100644
--- a/oox/source/drawingml/lineproperties.cxx
+++ b/oox/source/drawingml/lineproperties.cxx
@@ -251,9 +251,9 @@ void lclPushMarkerProperties( PropertyMap& rPropMap, const LineArrowProperties&
case OOX_ARROWSIZE_MEDIUM: fArrowWidth = (bIsArrow ? 4.5 : 3.0); break;
case OOX_ARROWSIZE_LARGE: fArrowWidth = (bIsArrow ? 6.0 : 5.0); break;
}
- // set arrow width relative to line width (convert line width from EMUs to 1/100 mm)
- sal_Int32 nApiLineWidth = ::std::max< sal_Int32 >( GetCoordinate( nLineWidth ), 70 );
- nMarkerWidth = static_cast< sal_Int32 >( fArrowWidth * nApiLineWidth );
+ // set arrow width relative to line width
+ sal_Int32 nBaseLineWidth = ::std::max< sal_Int32 >( nLineWidth, 70 );
+ nMarkerWidth = static_cast< sal_Int32 >( fArrowWidth * nBaseLineWidth );
// test if the arrow already exists, do not create it again in this case
if( !rPropIds.mbNamedLineMarker || !rModelObjHelper.hasLineMarker( aMarkerName ) )
@@ -403,6 +403,9 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM
// line style (our core only supports none and solid)
LineStyle eLineStyle = (maLineFill.moFillType.get() == XML_noFill) ? LineStyle_NONE : LineStyle_SOLID;
+ // convert line width from EMUs to 1/100mm
+ sal_Int32 nLineWidth = convertEmuToHmm( moLineWidth.get( 0 ) );
+
// create line dash from preset dash token (not for invisible line)
if( (eLineStyle != LineStyle_NONE) && (moPresetDash.differsFrom( XML_solid ) || (!moPresetDash && !maCustomDash.empty())) )
{
@@ -416,10 +419,10 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM
lclConvertCustomDash( aLineDash, maCustomDash );
// convert relative dash/dot length to absolute length
- sal_Int32 nLineWidth = GetCoordinate( moLineWidth.get( 103500 ) );
- aLineDash.DotLen *= nLineWidth;
- aLineDash.DashLen *= nLineWidth;
- aLineDash.Distance *= nLineWidth;
+ sal_Int32 nBaseLineWidth = ::std::max< sal_Int32 >( nLineWidth, 35 );
+ aLineDash.DotLen *= nBaseLineWidth;
+ aLineDash.DashLen *= nBaseLineWidth;
+ aLineDash.Distance *= nBaseLineWidth;
if( rPropIds.mbNamedLineDash )
{
@@ -444,9 +447,8 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM
if( moLineJoint.has() )
rPropMap.setProperty( rPropIds[ LineJointId ], lclGetLineJoint( moLineJoint.get() ) );
- // convert line width from EMUs to 1/100 mm
- if( moLineWidth.has() )
- rPropMap.setProperty( rPropIds[ LineWidthId ], GetCoordinate( moLineWidth.get() ) );
+ // line width in 1/100mm
+ rPropMap.setProperty( rPropIds[ LineWidthId ], nLineWidth );
// line color and transparence
Color aLineColor = maLineFill.getBestSolidColor();
@@ -458,8 +460,8 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM
}
// line markers
- lclPushMarkerProperties( rPropMap, maStartArrow, rModelObjHelper, rPropIds, moLineWidth.get( 0 ), false );
- lclPushMarkerProperties( rPropMap, maEndArrow, rModelObjHelper, rPropIds, moLineWidth.get( 0 ), true );
+ lclPushMarkerProperties( rPropMap, maStartArrow, rModelObjHelper, rPropIds, nLineWidth, false );
+ lclPushMarkerProperties( rPropMap, maEndArrow, rModelObjHelper, rPropIds, nLineWidth, true );
}
}
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index ba51c3577a8e..2850d422e234 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -76,6 +76,9 @@ CharUnderlineHasColor
CharWeight
CharWeightAsian
CharWeightComplex
+CircleEndAngle
+CircleKind
+CircleStartAngle
CodeName
Color
ColumnGrand
@@ -301,6 +304,7 @@ PercentageNumberFormat
PersistName
Perspective
PolyPolygon
+PolygonKind
Position
PositionBottom
PositionLeft
diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx
index d9a58eafb9d8..e1607e99e6c6 100755
--- a/oox/source/xls/drawingmanager.cxx
+++ b/oox/source/xls/drawingmanager.cxx
@@ -28,9 +28,18 @@
#include "oox/xls/drawingmanager.hxx"
#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/drawing/CircleKind.hpp>
+#include <com/sun/star/drawing/PointSequenceSequence.hpp>
+#include <com/sun/star/drawing/PolygonKind.hpp>
#include <com/sun/star/drawing/XShapes.hpp>
+#include "oox/core/filterbase.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
#include "oox/xls/biffinputstream.hxx"
#include "oox/xls/unitconverter.hxx"
+#include "properties.hxx"
+#include "tokens.hxx"
namespace oox {
namespace xls {
@@ -115,6 +124,13 @@ const sal_uInt8 BIFF_OBJ_LINE_TR = 1;
const sal_uInt8 BIFF_OBJ_LINE_BR = 2;
const sal_uInt8 BIFF_OBJ_LINE_BL = 3;
+const sal_uInt8 BIFF_OBJ_ARC_TR = 0;
+const sal_uInt8 BIFF_OBJ_ARC_TL = 1;
+const sal_uInt8 BIFF_OBJ_ARC_BL = 2;
+const sal_uInt8 BIFF_OBJ_ARC_BR = 3;
+
+const sal_uInt16 BIFF_OBJ_POLY_CLOSED = 0x0100;
+
// fill formatting ------------------------------------------------------------
const sal_uInt8 BIFF_OBJ_FILL_AUTOCOLOR = 65;
@@ -170,23 +186,21 @@ BiffObjLineModel::BiffObjLineModel() :
mnColorIdx( BIFF_OBJ_LINE_AUTOCOLOR ),
mnStyle( BIFF_OBJ_LINE_SOLID ),
mnWidth( BIFF_OBJ_LINE_HAIR ),
- mnAuto( BIFF_OBJ_LINE_AUTO )
-{
-}
-
-bool BiffObjLineModel::isAuto() const
+ mbAuto( true )
{
- return getFlag( mnAuto, BIFF_OBJ_LINE_AUTO );
}
bool BiffObjLineModel::isVisible() const
{
- return isAuto() || (mnStyle != BIFF_OBJ_LINE_NONE);
+ return mbAuto || (mnStyle != BIFF_OBJ_LINE_NONE);
}
BiffInputStream& operator>>( BiffInputStream& rStrm, BiffObjLineModel& rModel )
{
- return rStrm >> rModel.mnColorIdx >> rModel.mnStyle >> rModel.mnWidth >> rModel.mnAuto;
+ sal_uInt8 nFlags;
+ rStrm >> rModel.mnColorIdx >> rModel.mnStyle >> rModel.mnWidth >> nFlags;
+ rModel.mbAuto = getFlag( nFlags, BIFF_OBJ_LINE_AUTO );
+ return rStrm;
}
// ============================================================================
@@ -195,23 +209,21 @@ BiffObjFillModel::BiffObjFillModel() :
mnBackColorIdx( BIFF_OBJ_LINE_AUTOCOLOR ),
mnPattColorIdx( BIFF_OBJ_FILL_AUTOCOLOR ),
mnPattern( BIFF_OBJ_PATT_SOLID ),
- mnAuto( BIFF_OBJ_FILL_AUTO )
+ mbAuto( true )
{
}
-bool BiffObjFillModel::isAuto() const
-{
- return getFlag( mnAuto, BIFF_OBJ_FILL_AUTO );
-}
-
bool BiffObjFillModel::isFilled() const
{
- return isAuto() || (mnPattern != BIFF_OBJ_PATT_NONE);
+ return mbAuto || (mnPattern != BIFF_OBJ_PATT_NONE);
}
BiffInputStream& operator>>( BiffInputStream& rStrm, BiffObjFillModel& rModel )
{
- return rStrm >> rModel.mnBackColorIdx >> rModel.mnPattColorIdx >> rModel.mnPattern >> rModel.mnAuto;
+ sal_uInt8 nFlags;
+ rStrm >> rModel.mnBackColorIdx >> rModel.mnPattColorIdx >> rModel.mnPattern >> nFlags;
+ rModel.mbAuto = getFlag( nFlags, BIFF_OBJ_FILL_AUTO );
+ return rStrm;
}
// ============================================================================
@@ -335,15 +347,17 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase()
case BIFF_OBJTYPE_LINE: xDrawingObj.reset( new BiffLineObject( rHelper ) ); break;
case BIFF_OBJTYPE_RECTANGLE: xDrawingObj.reset( new BiffRectObject( rHelper ) ); break;
case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break;
+ case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new BiffArcObject( rHelper ) ); break;
#if 0
- case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new XclImpArcObj( rHelper ) ); break;
case BIFF_OBJTYPE_CHART: xDrawingObj.reset( new XclImpChartObj( rHelper ) ); break;
case BIFF_OBJTYPE_TEXT: xDrawingObj.reset( new XclImpTextObj( rHelper ) ); break;
case BIFF_OBJTYPE_BUTTON: xDrawingObj.reset( new XclImpButtonObj( rHelper ) ); break;
case BIFF_OBJTYPE_PICTURE: xDrawingObj.reset( new XclImpPictureObj( rHelper ) ); break;
#endif
default:
+#if 0
OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff3 - unknown object type" );
+#endif
xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) );
}
}
@@ -367,16 +381,18 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase()
case BIFF_OBJTYPE_LINE: xDrawingObj.reset( new BiffLineObject( rHelper ) ); break;
case BIFF_OBJTYPE_RECTANGLE: xDrawingObj.reset( new BiffRectObject( rHelper ) ); break;
case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break;
+ case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new BiffArcObject( rHelper ) ); break;
+ case BIFF_OBJTYPE_POLYGON: xDrawingObj.reset( new BiffPolygonObject( rHelper ) ); break;
#if 0
- case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new XclImpArcObj( rHelper ) ); break;
case BIFF_OBJTYPE_CHART: xDrawingObj.reset( new XclImpChartObj( rHelper ) ); break;
case BIFF_OBJTYPE_TEXT: xDrawingObj.reset( new XclImpTextObj( rHelper ) ); break;
case BIFF_OBJTYPE_BUTTON: xDrawingObj.reset( new XclImpButtonObj( rHelper ) ); break;
case BIFF_OBJTYPE_PICTURE: xDrawingObj.reset( new XclImpPictureObj( rHelper ) ); break;
- case BIFF_OBJTYPE_POLYGON: xDrawingObj.reset( new XclImpPolygonObj( rHelper ) ); break;
#endif
default:
+#if 0
OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff4 - unknown object type" );
+#endif
xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) );
}
}
@@ -399,14 +415,14 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase()
case BIFF_OBJTYPE_GROUP: xDrawingObj.reset( new BiffGroupObject( rHelper ) ); break;
case BIFF_OBJTYPE_LINE: xDrawingObj.reset( new BiffLineObject( rHelper ) ); break;
case BIFF_OBJTYPE_RECTANGLE: xDrawingObj.reset( new BiffRectObject( rHelper ) ); break;
- case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break;
+ case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break;
+ case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new BiffArcObject( rHelper ) ); break;
+ case BIFF_OBJTYPE_POLYGON: xDrawingObj.reset( new BiffPolygonObject( rHelper ) ); break;
#if 0
- case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new XclImpArcObj( rHelper ) ); break;
case BIFF_OBJTYPE_CHART: xDrawingObj.reset( new XclImpChartObj( rHelper ) ); break;
case BIFF_OBJTYPE_TEXT: xDrawingObj.reset( new XclImpTextObj( rHelper ) ); break;
case BIFF_OBJTYPE_BUTTON: xDrawingObj.reset( new XclImpButtonObj( rHelper ) ); break;
case BIFF_OBJTYPE_PICTURE: xDrawingObj.reset( new XclImpPictureObj( rHelper ) ); break;
- case BIFF_OBJTYPE_POLYGON: xDrawingObj.reset( new XclImpPolygonObj( rHelper ) ); break;
case BIFF_OBJTYPE_CHECKBOX: xDrawingObj.reset( new XclImpCheckBoxObj( rHelper ) ); break;
case BIFF_OBJTYPE_OPTIONBUTTON: xDrawingObj.reset( new XclImpOptionButtonObj( rHelper ) ); break;
case BIFF_OBJTYPE_EDIT: xDrawingObj.reset( new XclImpEditObj( rHelper ) ); break;
@@ -419,7 +435,9 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase()
case BIFF_OBJTYPE_DROPDOWN: xDrawingObj.reset( new XclImpDropDownObj( rHelper ) ); break;
#endif
default:
+#if 0
OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff5 - unknown object type" );
+#endif
xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) );
}
}
@@ -447,7 +465,7 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase()
case BIFF_OBJTYPE_ARC:
xDrawingObj.reset( new XclImpTextObj( rHelper ) );
// lines and arcs may be 2-dimensional
- xDrawingObj->SetAreaObj( false );
+ xDrawingObj->setAreaObj( false );
break;
// in BIFF8, all simple objects support text
@@ -479,7 +497,9 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase()
#endif
default:
+#if 0
OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff8 - unknown object type" );
+#endif
xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) );
}
}
@@ -574,6 +594,210 @@ void BiffDrawingObjectBase::readMacroBiff8( BiffInputStream& rStrm )
}
}
+void BiffDrawingObjectBase::convertLineProperties( PropertyMap& rPropMap, const BiffObjLineModel& rLineModel, sal_uInt16 nArrows ) const
+{
+ if( rLineModel.mbAuto )
+ {
+ BiffObjLineModel aAutoModel;
+ aAutoModel.mbAuto = false;
+ convertLineProperties( rPropMap, aAutoModel, nArrows );
+ return;
+ }
+
+ /* Convert line formatting to DrawingML line formatting and let the
+ DrawingML code do the hard work. */
+ LineProperties aLineProps;
+
+ if( rLineModel.mnStyle == BIFF_OBJ_LINE_NONE )
+ {
+ aLineProps.maLineFill.moFillType = XML_noFill;
+ }
+ else
+ {
+ aLineProps.maLineFill.moFillType = XML_solidFill;
+ aLineProps.maLineFill.maFillColor.setPaletteClr( rLineModel.mnColorIdx );
+ aLineProps.moLineCompound = XML_sng;
+ aLineProps.moLineCap = XML_flat;
+ aLineProps.moLineJoint = XML_round;
+
+ // line width: use 0.35 mm per BIFF line width step
+ sal_Int32 nLineWidth = 0;
+ switch( rLineModel.mnWidth )
+ {
+ default:
+ case BIFF_OBJ_LINE_HAIR: nLineWidth = 0; break;
+ case BIFF_OBJ_LINE_THIN: nLineWidth = 20; break;
+ case BIFF_OBJ_LINE_MEDIUM: nLineWidth = 40; break;
+ case BIFF_OBJ_LINE_THICK: nLineWidth = 60; break;
+ }
+ aLineProps.moLineWidth = getLimitedValue< sal_Int32, sal_Int64 >( convertHmmToEmu( nLineWidth ), 0, SAL_MAX_INT32 );
+
+ // dash style and transparency
+ switch( rLineModel.mnStyle )
+ {
+ default:
+ case BIFF_OBJ_LINE_SOLID:
+ aLineProps.moPresetDash = XML_solid;
+ break;
+ case BIFF_OBJ_LINE_DASH:
+ aLineProps.moPresetDash = XML_lgDash;
+ break;
+ case BIFF_OBJ_LINE_DOT:
+ aLineProps.moPresetDash = XML_dot;
+ break;
+ case BIFF_OBJ_LINE_DASHDOT:
+ aLineProps.moPresetDash = XML_lgDashDot;
+ break;
+ case BIFF_OBJ_LINE_DASHDOTDOT:
+ aLineProps.moPresetDash = XML_lgDashDotDot;
+ break;
+ case BIFF_OBJ_LINE_MEDTRANS:
+ aLineProps.moPresetDash = XML_solid;
+ aLineProps.maLineFill.maFillColor.addTransformation( XML_alpha, 50 * PER_PERCENT );
+ break;
+ case BIFF_OBJ_LINE_DARKTRANS:
+ aLineProps.moPresetDash = XML_solid;
+ aLineProps.maLineFill.maFillColor.addTransformation( XML_alpha, 75 * PER_PERCENT );
+ break;
+ case BIFF_OBJ_LINE_LIGHTTRANS:
+ aLineProps.moPresetDash = XML_solid;
+ aLineProps.maLineFill.maFillColor.addTransformation( XML_alpha, 25 * PER_PERCENT );
+ break;
+ }
+
+ // line ends
+ bool bLineStart = false;
+ bool bLineEnd = false;
+ bool bFilled = false;
+ switch( extractValue< sal_uInt8 >( nArrows, 0, 4 ) )
+ {
+ case BIFF_OBJ_ARROW_OPEN: bLineStart = false; bLineEnd = true; bFilled = false; break;
+ case BIFF_OBJ_ARROW_OPENBOTH: bLineStart = true; bLineEnd = true; bFilled = false; break;
+ case BIFF_OBJ_ARROW_FILLED: bLineStart = false; bLineEnd = true; bFilled = true; break;
+ case BIFF_OBJ_ARROW_FILLEDBOTH: bLineStart = true; bLineEnd = true; bFilled = true; break;
+ }
+ if( bLineStart || bLineEnd )
+ {
+ // arrow type (open or closed)
+ sal_Int32 nArrowType = bFilled ? XML_triangle : XML_arrow;
+ aLineProps.maStartArrow.moArrowType = bLineStart ? nArrowType : XML_none;
+ aLineProps.maEndArrow.moArrowType = bLineEnd ? nArrowType : XML_none;
+
+ // arrow width
+ sal_Int32 nArrowWidth = XML_med;
+ switch( extractValue< sal_uInt8 >( nArrows, 4, 4 ) )
+ {
+ case BIFF_OBJ_ARROW_NARROW: nArrowWidth = XML_sm; break;
+ case BIFF_OBJ_ARROW_MEDIUM: nArrowWidth = XML_med; break;
+ case BIFF_OBJ_ARROW_WIDE: nArrowWidth = XML_lg; break;
+ }
+ aLineProps.maStartArrow.moArrowWidth = aLineProps.maEndArrow.moArrowWidth = nArrowWidth;
+
+ // arrow length
+ sal_Int32 nArrowLength = XML_med;
+ switch( extractValue< sal_uInt8 >( nArrows, 8, 4 ) )
+ {
+ case BIFF_OBJ_ARROW_NARROW: nArrowLength = XML_sm; break;
+ case BIFF_OBJ_ARROW_MEDIUM: nArrowLength = XML_med; break;
+ case BIFF_OBJ_ARROW_WIDE: nArrowLength = XML_lg; break;
+ }
+ aLineProps.maStartArrow.moArrowLength = aLineProps.maEndArrow.moArrowLength = nArrowLength;
+ }
+ }
+
+ aLineProps.pushToPropMap( rPropMap, getBaseFilter().getModelObjectHelper(), getBaseFilter().getGraphicHelper() );
+}
+
+void BiffDrawingObjectBase::convertFillProperties( PropertyMap& rPropMap, const BiffObjFillModel& rFillModel ) const
+{
+ if( rFillModel.mbAuto )
+ {
+ BiffObjFillModel aAutoModel;
+ aAutoModel.mbAuto = false;
+ convertFillProperties( rPropMap, aAutoModel );
+ return;
+ }
+
+ /* Convert fill formatting to DrawingML fill formatting and let the
+ DrawingML code do the hard work. */
+ FillProperties aFillProps;
+
+ if( rFillModel.mnPattern == BIFF_OBJ_PATT_NONE )
+ {
+ aFillProps.moFillType = XML_noFill;
+ }
+ else
+ {
+ const sal_Int32 spnPatternPresets[] = {
+ XML_TOKEN_INVALID, XML_TOKEN_INVALID, XML_pct50, XML_pct50, XML_pct25,
+ XML_dkHorz, XML_dkVert, XML_dkDnDiag, XML_dkUpDiag, XML_smCheck, XML_trellis,
+ XML_ltHorz, XML_ltVert, XML_ltDnDiag, XML_ltUpDiag, XML_smGrid, XML_diagCross,
+ XML_pct20, XML_pct10 };
+ sal_Int32 nPatternPreset = STATIC_ARRAY_SELECT( spnPatternPresets, rFillModel.mnPattern, XML_TOKEN_INVALID );
+ if( nPatternPreset == XML_TOKEN_INVALID )
+ {
+ aFillProps.moFillType = XML_solidFill;
+ aFillProps.maFillColor.setPaletteClr( rFillModel.mnPattColorIdx );
+ }
+ else
+ {
+ aFillProps.moFillType = XML_pattFill;
+ aFillProps.maPatternProps.maPattFgColor.setPaletteClr( rFillModel.mnPattColorIdx );
+ aFillProps.maPatternProps.maPattBgColor.setPaletteClr( rFillModel.mnBackColorIdx );
+ aFillProps.maPatternProps.moPattPreset = nPatternPreset;
+ }
+#if 0
+ static const sal_uInt8 sppnPatterns[][ 8 ] =
+ {
+ { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
+ { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },
+ { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },
+ { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 },
+ { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC },
+ { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 },
+ { 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99 },
+ { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 },
+ { 0xCC, 0xFF, 0x33, 0xFF, 0xCC, 0xFF, 0x33, 0xFF },
+ { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
+ { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
+ { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
+ { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 },
+ { 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x11, 0x11, 0x11 },
+ { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 },
+ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
+ { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 }
+ };
+ const sal_uInt8* const pnPattern = sppnPatterns[ ::std::min< size_t >( rFillData.mnPattern - 2, STATIC_ARRAY_SIZE( sppnPatterns ) ) ];
+ // create 2-colored 8x8 DIB
+ SvMemoryStream aMemStrm;
+// { 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00 }
+ aMemStrm << sal_uInt32( 12 ) << sal_Int16( 8 ) << sal_Int16( 8 ) << sal_uInt16( 1 ) << sal_uInt16( 1 );
+ aMemStrm << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF );
+ aMemStrm << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 );
+ for( size_t nIdx = 0; nIdx < 8; ++nIdx )
+ aMemStrm << sal_uInt32( pnPattern[ nIdx ] ); // 32-bit little-endian
+ aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ Bitmap aBitmap;
+ aBitmap.Read( aMemStrm, FALSE );
+ XOBitmap aXOBitmap( aBitmap );
+ aXOBitmap.Bitmap2Array();
+ aXOBitmap.SetBitmapType( XBITMAP_8X8 );
+ if( aXOBitmap.GetBackgroundColor().GetColor() == COL_BLACK )
+ ::std::swap( aPattColor, aBackColor );
+ aXOBitmap.SetPixelColor( aPattColor );
+ aXOBitmap.SetBackgroundColor( aBackColor );
+ rSdrObj.SetMergedItem( XFillStyleItem( XFILL_BITMAP ) );
+ rSdrObj.SetMergedItem( XFillBitmapItem( EMPTY_STRING, aXOBitmap ) );
+#endif
+ }
+
+ aFillProps.pushToPropMap( rPropMap, getBaseFilter().getModelObjectHelper(), getBaseFilter().getGraphicHelper() );
+}
+
+void BiffDrawingObjectBase::convertFrameProperties( PropertyMap& /*rPropMap*/, sal_uInt16 /*nFrameFlags*/ ) const
+{
+}
+
void BiffDrawingObjectBase::implReadObjBiff3( BiffInputStream& /*rStrm*/, sal_uInt16 /*nMacroSize*/ )
{
}
@@ -820,7 +1044,33 @@ void BiffLineObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameL
Reference< XShape > BiffLineObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
{
- return rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.LineShape" ), rxShapes, rShapeRect );
+ PropertyMap aPropMap;
+ convertLineProperties( aPropMap, maLineModel, mnArrows );
+
+ // create the line polygon
+ PointSequenceSequence aPoints( 1 );
+ aPoints[ 0 ].realloc( 2 );
+ Point& rBeg = aPoints[ 0 ][ 0 ];
+ Point& rEnd = aPoints[ 0 ][ 1 ];
+ sal_Int32 nL = rShapeRect.X;
+ sal_Int32 nT = rShapeRect.Y;
+ sal_Int32 nR = rShapeRect.X + ::std::max< sal_Int32 >( rShapeRect.Width - 1, 0 );
+ sal_Int32 nB = rShapeRect.Y + ::std::max< sal_Int32 >( rShapeRect.Height - 1, 0 );
+ switch( mnStartPoint )
+ {
+ default:
+ case BIFF_OBJ_LINE_TL: rBeg.X = nL; rBeg.Y = nT; rEnd.X = nR; rEnd.Y = nB; break;
+ case BIFF_OBJ_LINE_TR: rBeg.X = nR; rBeg.Y = nT; rEnd.X = nL; rEnd.Y = nB; break;
+ case BIFF_OBJ_LINE_BR: rBeg.X = nR; rBeg.Y = nB; rEnd.X = nL; rEnd.Y = nT; break;
+ case BIFF_OBJ_LINE_BL: rBeg.X = nL; rBeg.Y = nB; rEnd.X = nR; rEnd.Y = nT; break;
+ }
+ aPropMap.setProperty( PROP_PolyPolygon, aPoints );
+ aPropMap.setProperty( PROP_PolygonKind, PolygonKind_LINE );
+
+ // create the shape
+ Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.LineShape" ), rxShapes, rShapeRect );
+ PropertySet( xShape ).setProperties( aPropMap );
+ return xShape;
}
// ============================================================================
@@ -837,6 +1087,13 @@ void BiffRectObject::readFrameData( BiffInputStream& rStrm )
rStrm >> maFillModel >> maLineModel >> mnFrameFlags;
}
+void BiffRectObject::convertRectProperties( PropertyMap& rPropMap ) const
+{
+ convertLineProperties( rPropMap, maLineModel );
+ convertFillProperties( rPropMap, maFillModel );
+ convertFrameProperties( rPropMap, mnFrameFlags );
+}
+
void BiffRectObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
{
readFrameData( rStrm );
@@ -859,7 +1116,12 @@ void BiffRectObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameL
Reference< XShape > BiffRectObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
{
- return rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ), rxShapes, rShapeRect );
+ PropertyMap aPropMap;
+ convertRectProperties( aPropMap );
+
+ Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ), rxShapes, rShapeRect );
+ PropertySet( xShape ).setProperties( aPropMap );
+ return xShape;
}
// ============================================================================
@@ -872,7 +1134,165 @@ BiffOvalObject::BiffOvalObject( const WorksheetHelper& rHelper ) :
Reference< XShape > BiffOvalObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
{
- return rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ), rxShapes, rShapeRect );
+ PropertyMap aPropMap;
+ convertRectProperties( aPropMap );
+
+ Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ), rxShapes, rShapeRect );
+ PropertySet( xShape ).setProperties( aPropMap );
+ return xShape;
+}
+
+// ============================================================================
+
+BiffArcObject::BiffArcObject( const WorksheetHelper& rHelper ) :
+ BiffDrawingObjectBase( rHelper ),
+ mnQuadrant( BIFF_OBJ_ARC_TR )
+{
+ setAreaObj( false ); // arc may be 2-dimensional
+}
+
+void BiffArcObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm >> maFillModel >> maLineModel >> mnQuadrant;
+ rStrm.skip( 1 );
+ readMacroBiff3( rStrm, nMacroSize );
+}
+
+void BiffArcObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm >> maFillModel >> maLineModel >> mnQuadrant;
+ rStrm.skip( 1 );
+ readMacroBiff4( rStrm, nMacroSize );
+}
+
+void BiffArcObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ rStrm >> maFillModel >> maLineModel >> mnQuadrant;
+ rStrm.skip( 1 );
+ readNameBiff5( rStrm, nNameLen );
+ readMacroBiff5( rStrm, nMacroSize );
+}
+
+Reference< XShape > BiffArcObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
+ const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ PropertyMap aPropMap;
+ convertLineProperties( aPropMap, maLineModel );
+ convertFillProperties( aPropMap, maFillModel );
+
+ /* Simulate arc objects with ellipse sections. While the original arc
+ object uses the entire object rectangle, only one quarter of the
+ ellipse shape will be visible. Thus, the size of the ellipse shape
+ needs to be extended and its position adjusted according to the visible
+ quadrant. */
+ Rectangle aNewRect( rShapeRect.X, rShapeRect.Y, rShapeRect.Width * 2, rShapeRect.Height * 2 );
+ long nStartAngle = 0;
+ switch( mnQuadrant )
+ {
+ default:
+ case BIFF_OBJ_ARC_TR: nStartAngle = 0; aNewRect.X -= rShapeRect.Width; break;
+ case BIFF_OBJ_ARC_TL: nStartAngle = 9000; break;
+ case BIFF_OBJ_ARC_BL: nStartAngle = 18000; aNewRect.Y -= rShapeRect.Height; break;
+ case BIFF_OBJ_ARC_BR: nStartAngle = 27000; aNewRect.X -= rShapeRect.Width; aNewRect.Y -= rShapeRect.Height; break;
+ }
+ long nEndAngle = (nStartAngle + 9000) % 36000;
+ aPropMap.setProperty( PROP_CircleKind, maFillModel.isFilled() ? CircleKind_SECTION : CircleKind_ARC );
+ aPropMap.setProperty( PROP_CircleStartAngle, nStartAngle );
+ aPropMap.setProperty( PROP_CircleEndAngle, nEndAngle );
+
+ // create the shape
+ Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ), rxShapes, aNewRect );
+ PropertySet( xShape ).setProperties( aPropMap );
+ return xShape;
+}
+
+// ============================================================================
+
+BiffPolygonObject::BiffPolygonObject( const WorksheetHelper& rHelper ) :
+ BiffRectObject( rHelper ),
+ mnPolyFlags( 0 ),
+ mnPointCount( 0 )
+{
+ setAreaObj( false ); // polygon may be 2-dimensional
+}
+
+void BiffPolygonObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
+{
+ readFrameData( rStrm );
+ rStrm >> mnPolyFlags;
+ rStrm.skip( 10 );
+ rStrm >> mnPointCount;
+ rStrm.skip( 8 );
+ readMacroBiff4( rStrm, nMacroSize );
+ importCoordList( rStrm );
+}
+
+void BiffPolygonObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ readFrameData( rStrm );
+ rStrm >> mnPolyFlags;
+ rStrm.skip( 10 );
+ rStrm >> mnPointCount;
+ rStrm.skip( 8 );
+ readNameBiff5( rStrm, nNameLen );
+ readMacroBiff5( rStrm, nMacroSize );
+ importCoordList( rStrm );
+}
+
+namespace {
+
+Point lclGetPolyPoint( const Rectangle& rAnchorRect, const Point& rPoint )
+{
+ // polygon coordinates are given in 1/16384 of shape size
+ return Point(
+ rAnchorRect.X + static_cast< sal_Int32 >( rAnchorRect.Width * getLimitedValue< double >( static_cast< double >( rPoint.X ) / 16384.0, 0.0, 1.0 ) + 0.5 ),
+ rAnchorRect.Y + static_cast< sal_Int32 >( rAnchorRect.Height * getLimitedValue< double >( static_cast< double >( rPoint.Y ) / 16384.0, 0.0, 1.0 ) + 0.5 ) );
+}
+
+} // namespace
+
+Reference< XShape > BiffPolygonObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
+ const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ Reference< XShape > xShape;
+ if( maCoords.size() >= 2 )
+ {
+ PropertyMap aPropMap;
+ convertRectProperties( aPropMap );
+
+ // create the polygon
+ PointVector aPolygon;
+ for( PointVector::const_iterator aIt = maCoords.begin(), aEnd = maCoords.end(); aIt != aEnd; ++aIt )
+ aPolygon.push_back( lclGetPolyPoint( rShapeRect, *aIt ) );
+ // close polygon if specified
+ if( getFlag( mnPolyFlags, BIFF_OBJ_POLY_CLOSED ) && ((maCoords.front().X != maCoords.back().X) || (maCoords.front().Y != maCoords.back().Y)) )
+ aPolygon.push_back( aPolygon.front() );
+ PointSequenceSequence aPoints( 1 );
+ aPoints[ 0 ] = ContainerHelper::vectorToSequence( aPolygon );
+ aPropMap.setProperty( PROP_PolyPolygon, aPoints );
+
+ // create the shape
+ OUString aService = maFillModel.isFilled() ?
+ CREATE_OUSTRING( "com.sun.star.drawing.PolyPolygonShape" ) :
+ CREATE_OUSTRING( "com.sun.star.drawing.PolyLineShape" );
+ xShape = rDrawing.createAndInsertXShape( aService, rxShapes, rShapeRect );
+ PropertySet( xShape ).setProperties( aPropMap );
+ }
+ return xShape;
+}
+
+void BiffPolygonObject::importCoordList( BiffInputStream& rStrm )
+{
+ if( (rStrm.getNextRecId() == BIFF_ID_COORDLIST) && rStrm.startNextRecord() )
+ {
+ OSL_ENSURE( rStrm.getRemaining() / 4 == mnPointCount, "BiffPolygonObject::importCoordList - wrong polygon point count" );
+ while( rStrm.getRemaining() >= 4 )
+ {
+ sal_uInt16 nX, nY;
+ rStrm >> nX >> nY;
+ maCoords.push_back( Point( nX, nY ) );
+ }
+ }
}
// ============================================================================
diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx
index 626d3b962ceb..cbdb564ac7c5 100644
--- a/oox/source/xls/worksheethelper.cxx
+++ b/oox/source/xls/worksheethelper.cxx
@@ -162,8 +162,6 @@ struct ValueRangeComp
inline bool operator()( const ValueRange& rRange, sal_Int32 nValue ) const { return rRange.mnLast < nValue; }
};
-typedef ::std::vector< ValueRange > ValueRangeVector;
-
// ----------------------------------------------------------------------------
class ValueRangeSet