diff options
author | Daniel Rentz [dr] <daniel.rentz@oracle.com> | 2011-01-08 12:55:26 +0100 |
---|---|---|
committer | Daniel Rentz [dr] <daniel.rentz@oracle.com> | 2011-01-08 12:55:26 +0100 |
commit | f9a2b2913692fa1d65200f53c90e77b0bd134445 (patch) | |
tree | 43eb5a578375e2617d4111f33b4b2441f26af6b9 | |
parent | bb282d6533202ce6056d6aed37774c59a2deab2a (diff) |
dr78: oox - BIFF3-BIFF5 arcs and polygons, line and fill formatting
-rwxr-xr-x | oox/inc/oox/xls/drawingmanager.hxx | 77 | ||||
-rw-r--r-- | oox/source/drawingml/lineproperties.cxx | 26 | ||||
-rw-r--r-- | oox/source/token/properties.txt | 4 | ||||
-rwxr-xr-x | oox/source/xls/drawingmanager.cxx | 472 | ||||
-rw-r--r-- | oox/source/xls/worksheethelper.cxx | 2 |
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 |