Kaydet (Commit) e67dbbf9 authored tarafından Patrick Jaap's avatar Patrick Jaap Kaydeden (comit) Thorsten Behrens

new EMF+ Parser: Basic implementation for Graphic Stacks

Some basic code for push/pop events of the graphic stacks.
Each draw/fill action is also transferred to the currend state.
The implementation follows the one from the old parser.

Change-Id: Ib6411046801023dfa72b16038a9e8ede4c628942
Reviewed-on: https://gerrit.libreoffice.org/40867Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarThorsten Behrens <Thorsten.Behrens@CIB.de>
üst 708eb747
...@@ -23,11 +23,11 @@ ...@@ -23,11 +23,11 @@
#include <sal/types.h> #include <sal/types.h>
#include <sal/config.h> #include <sal/config.h>
#include <memory> #include <memory>
#include <wmfemfhelper.hxx>
/// predefines /// predefines
namespace emfplushelper { struct EmfPlusHelperData; } namespace emfplushelper { struct EmfPlusHelperData; }
namespace wmfemfhelper { class TargetHolders; } namespace wmfemfhelper { class TargetHolders; }
namespace wmfemfhelper { class PropertyHolders; }
namespace drawinglayer { namespace geometry { class ViewInformation2D; }} namespace drawinglayer { namespace geometry { class ViewInformation2D; }}
class SvMemoryStream; class SvMemoryStream;
......
...@@ -349,6 +349,40 @@ namespace emfplushelper ...@@ -349,6 +349,40 @@ namespace emfplushelper
return color; return color;
} }
void EmfPlusHelperData::GraphicStatePush(GraphicStateMap& map, sal_Int32 index)
{
GraphicStateMap::iterator iter = map.find( index );
if ( iter != map.end() )
{
wmfemfhelper::PropertyHolder state = iter->second;
map.erase( iter );
SAL_INFO("cppcanvas.emf", "stack index: " << index << " found and erased");
}
wmfemfhelper::PropertyHolder state;
state = mrPropertyHolders.Current();
map[ index ] = state;
}
void EmfPlusHelperData::GraphicStatePop(GraphicStateMap& map, sal_Int32 index, wmfemfhelper::PropertyHolder& rState)
{
GraphicStateMap::iterator iter = map.find( index );
if ( iter != map.end() )
{
SAL_INFO("cppcanvas.emf", "stack index: " << index << " found");
wmfemfhelper::PropertyHolder state = iter->second;
maWorldTransform = state.getTransformation();
rState.setClipPolyPolygon( state.getClipPolyPolygon() );
}
}
void EmfPlusHelperData::EMFPPlusDrawPolygon(const ::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex) void EmfPlusHelperData::EMFPPlusDrawPolygon(const ::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex)
{ {
const EMFPPen* pen = static_cast<EMFPPen*>(maEMFPObjects[penIndex & 0xff].get()); const EMFPPen* pen = static_cast<EMFPPen*>(maEMFPObjects[penIndex & 0xff].get());
...@@ -356,38 +390,42 @@ namespace emfplushelper ...@@ -356,38 +390,42 @@ namespace emfplushelper
if (pen && polygon.count()) if (pen && polygon.count())
{ {
// we need a line join attribute // we need a line join attribute
basegfx::B2DLineJoin lineJoin = basegfx::B2DLineJoin::Round; basegfx::B2DLineJoin lineJoin = basegfx::B2DLineJoin::Round;
if (pen->penDataFlags & 0x00000008) // additional line join information if (pen->penDataFlags & 0x00000008) // additional line join information
{ {
lineJoin = static_cast<basegfx::B2DLineJoin>(EMFPPen::lcl_convertLineJoinType(pen->lineJoin)); lineJoin = static_cast<basegfx::B2DLineJoin>(EMFPPen::lcl_convertLineJoinType(pen->lineJoin));
} }
// we need a line cap attribute // we need a line cap attribute
css::drawing::LineCap lineCap = css::drawing::LineCap_BUTT; css::drawing::LineCap lineCap = css::drawing::LineCap_BUTT;
if (pen->penDataFlags & 0x00000002) // additional line cap information if (pen->penDataFlags & 0x00000002) // additional line cap information
{ {
lineCap = static_cast<css::drawing::LineCap>(EMFPPen::lcl_convertStrokeCap(pen->startCap)); lineCap = static_cast<css::drawing::LineCap>(EMFPPen::lcl_convertStrokeCap(pen->startCap));
SAL_WARN_IF(pen->startCap != pen->endCap, "cppcanvas.emf", "emf+ pen uses different start and end cap"); SAL_WARN_IF(pen->startCap != pen->endCap, "cppcanvas.emf", "emf+ pen uses different start and end cap");
} }
// transform the pen width // transform the pen width
double adjustedPenWidth = pen->penWidth; double adjustedPenWidth = pen->penWidth;
if (!pen->penWidth) // no width specified, then use default value if (!pen->penWidth) // no width specified, then use default value
{ {
adjustedPenWidth = pen->penUnit == 0 ? 0.18f // 0.18f is determined by comparison with MSO (case of Unit == World) adjustedPenWidth = pen->penUnit == 0 ? 0.18f // 0.18f is determined by comparison with MSO (case of Unit == World)
: 0.05f; // 0.05f is taken from old EMF+ implementation (case of Unit == Pixel etc.) : 0.05f; // 0.05f is taken from old EMF+ implementation (case of Unit == Pixel etc.)
} }
// transform and compare to 5 (the value 5 is determined by comparison to MSO) // transform and compare to 5 (the value 5 is determined by comparison to MSO)
const double transformedPenWidth = std::max( MapSize(adjustedPenWidth,0).getX() , 5.); const double transformedPenWidth = std::max( MapSize(adjustedPenWidth,0).getX() , 5.);
drawinglayer::attribute::LineAttribute lineAttribute(pen->GetColor().getBColor(), drawinglayer::attribute::LineAttribute lineAttribute(pen->GetColor().getBColor(),
transformedPenWidth, transformedPenWidth,
lineJoin, lineJoin,
lineCap); lineCap);
mrTargetHolders.Current().append( mrTargetHolders.Current().append(
new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D( new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
polygon, polygon,
lineAttribute)); lineAttribute));
mrPropertyHolders.Current().setLineColor(pen->GetColor().getBColor());
mrPropertyHolders.Current().setLineColorActive(true);
mrPropertyHolders.Current().setFillColorActive(false);
} }
} }
...@@ -403,6 +441,11 @@ namespace emfplushelper ...@@ -403,6 +441,11 @@ namespace emfplushelper
new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
polygon, polygon,
::Color(0xff - (brushIndexOrColor >> 24), (brushIndexOrColor >> 16) & 0xff, (brushIndexOrColor >> 8) & 0xff, brushIndexOrColor & 0xff).getBColor())); ::Color(0xff - (brushIndexOrColor >> 24), (brushIndexOrColor >> 16) & 0xff, (brushIndexOrColor >> 8) & 0xff, brushIndexOrColor & 0xff).getBColor()));
mrPropertyHolders.Current().setFillColor(::Color(0xff - (brushIndexOrColor >> 24), (brushIndexOrColor >> 16) & 0xff, (brushIndexOrColor >> 8) & 0xff, brushIndexOrColor & 0xff).getBColor());
mrPropertyHolders.Current().setFillColorActive(true);
mrPropertyHolders.Current().setLineColorActive(false);
} }
else // use Brush else // use Brush
{ {
...@@ -412,6 +455,10 @@ namespace emfplushelper ...@@ -412,6 +455,10 @@ namespace emfplushelper
// give up in case something wrong happened // give up in case something wrong happened
if( !brush ) if( !brush )
return; return;
mrPropertyHolders.Current().setFillColorActive(false);
mrPropertyHolders.Current().setLineColorActive(false);
if (brush->type == BrushTypeHatchFill) if (brush->type == BrushTypeHatchFill)
{ {
// EMF+ like hatching is currently not supported. These are just color blends which serve as an approximation for some of them // EMF+ like hatching is currently not supported. These are just color blends which serve as an approximation for some of them
...@@ -448,7 +495,12 @@ namespace emfplushelper ...@@ -448,7 +495,12 @@ namespace emfplushelper
{ {
fillColor = brush->secondColor; fillColor = brush->secondColor;
} }
EMFPPlusFillPolygon(polygon,true,fillColor.GetRGBColor()); // temporal solution: create a solid colored polygon
// TODO create a 'real' hatching primitive
mrTargetHolders.Current().append(
new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
polygon,
fillColor.getBColor()));
} }
else if (brush->type == BrushTypeTextureFill) else if (brush->type == BrushTypeTextureFill)
{ {
...@@ -1104,9 +1156,12 @@ namespace emfplushelper ...@@ -1104,9 +1156,12 @@ namespace emfplushelper
{ {
break; break;
} }
mrPropertyHolders.Current().setFont(vcl::Font(font->family , Size(font->emSize,font->emSize)));
// done reading // done reading
// transform to TextSimplePortionPrimitive2D // transform to TextSimplePortionPrimitive2D
// TODO add more decorations: underline, strikeout, etc
// and create a TextDecoratedPortionPrimitive2D
const OUString emptyString; const OUString emptyString;
drawinglayer::attribute::FontAttribute fontAttribute( drawinglayer::attribute::FontAttribute fontAttribute(
...@@ -1139,6 +1194,8 @@ namespace emfplushelper ...@@ -1139,6 +1194,8 @@ namespace emfplushelper
color = pen->GetColor().getBColor(); color = pen->GetColor().getBColor();
} }
} }
mrPropertyHolders.Current().setTextColor(color);
mrPropertyHolders.Current().setTextColorActive(true);
std::vector<double> emptyVector; std::vector<double> emptyVector;
mrTargetHolders.Current().append( mrTargetHolders.Current().append(
...@@ -1219,7 +1276,7 @@ namespace emfplushelper ...@@ -1219,7 +1276,7 @@ namespace emfplushelper
rMS.ReadUInt32(stackIndex); rMS.ReadUInt32(stackIndex);
SAL_INFO("cppcanvas.emf", "EMF+ Save stack index: " << stackIndex); SAL_INFO("cppcanvas.emf", "EMF+ Save stack index: " << stackIndex);
// GraphicStatePush(mGSStack, stackIndex, rState); GraphicStatePush(mGSStack, stackIndex);
break; break;
} }
...@@ -1229,8 +1286,7 @@ namespace emfplushelper ...@@ -1229,8 +1286,7 @@ namespace emfplushelper
rMS.ReadUInt32(stackIndex); rMS.ReadUInt32(stackIndex);
SAL_INFO("cppcanvas.emf", "EMF+ Restore stack index: " << stackIndex); SAL_INFO("cppcanvas.emf", "EMF+ Restore stack index: " << stackIndex);
// GraphicStatePop(mGSStack, stackIndex, rState); GraphicStatePop(mGSStack, stackIndex, mrPropertyHolders.Current());
break; break;
} }
case EmfPlusRecordTypeBeginContainerNoParams: case EmfPlusRecordTypeBeginContainerNoParams:
...@@ -1239,7 +1295,7 @@ namespace emfplushelper ...@@ -1239,7 +1295,7 @@ namespace emfplushelper
rMS.ReadUInt32(stackIndex); rMS.ReadUInt32(stackIndex);
SAL_INFO("cppcanvas.emf", "EMF+ Begin Container No Params stack index: " << stackIndex); SAL_INFO("cppcanvas.emf", "EMF+ Begin Container No Params stack index: " << stackIndex);
// GraphicStatePush(mGSContainerStack, stackIndex, rState); GraphicStatePush(mGSContainerStack, stackIndex);
break; break;
} }
case EmfPlusRecordTypeEndContainer: case EmfPlusRecordTypeEndContainer:
...@@ -1248,7 +1304,7 @@ namespace emfplushelper ...@@ -1248,7 +1304,7 @@ namespace emfplushelper
rMS.ReadUInt32(stackIndex); rMS.ReadUInt32(stackIndex);
SAL_INFO("cppcanvas.emf", "EMF+ End Container stack index: " << stackIndex); SAL_INFO("cppcanvas.emf", "EMF+ End Container stack index: " << stackIndex);
// GraphicStatePop(mGSContainerStack, stackIndex, rState); GraphicStatePop(mGSContainerStack, stackIndex, mrPropertyHolders.Current());
break; break;
} }
case EmfPlusRecordTypeSetWorldTransform: case EmfPlusRecordTypeSetWorldTransform:
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <basegfx/point/b2dpoint.hxx> #include <basegfx/point/b2dpoint.hxx>
#include <basegfx/vector/b2dsize.hxx> #include <basegfx/vector/b2dsize.hxx>
#include <basegfx/color/bcolor.hxx> #include <basegfx/color/bcolor.hxx>
#include <map>
// predefines // predefines
class SvStream; class SvStream;
...@@ -184,6 +185,8 @@ namespace emfplushelper ...@@ -184,6 +185,8 @@ namespace emfplushelper
// //
// typedef std::map<int, EmfPlusGraphicState> GraphicStateMap; // typedef std::map<int, EmfPlusGraphicState> GraphicStateMap;
typedef std::map<int, wmfemfhelper::PropertyHolder> GraphicStateMap;
struct EmfPlusHelperData struct EmfPlusHelperData
{ {
private: private:
...@@ -215,8 +218,8 @@ namespace emfplushelper ...@@ -215,8 +218,8 @@ namespace emfplushelper
SvMemoryStream mMStream; SvMemoryStream mMStream;
/* emf+ graphic state stack */ /* emf+ graphic state stack */
// GraphicStateMap mGSStack; GraphicStateMap mGSStack;
// GraphicStateMap mGSContainerStack; GraphicStateMap mGSContainerStack;
/// data holders /// data holders
wmfemfhelper::TargetHolders& mrTargetHolders; wmfemfhelper::TargetHolders& mrTargetHolders;
...@@ -229,6 +232,10 @@ namespace emfplushelper ...@@ -229,6 +232,10 @@ namespace emfplushelper
// internal mapper // internal mapper
void mappingChanged(); void mappingChanged();
// stack actions
void GraphicStatePush(GraphicStateMap& map, sal_Int32 index);
void GraphicStatePop (GraphicStateMap& map, sal_Int32 index, wmfemfhelper::PropertyHolder& rState);
// primitive creators // primitive creators
void EMFPPlusDrawPolygon(const ::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex); void EMFPPlusDrawPolygon(const ::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex);
void EMFPPlusFillPolygon(const ::basegfx::B2DPolyPolygon& polygon, bool isColor, sal_uInt32 brushIndexOrColor); void EMFPPlusFillPolygon(const ::basegfx::B2DPolyPolygon& polygon, bool isColor, sal_uInt32 brushIndexOrColor);
......
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