Rebased ref, commits from common ancestor:
commit ab69b886b4f54f7a6d42fe4faa03479d6ef0d9ee
Author: Armin Le Grand <[email protected]>
Date: Thu Jun 22 13:03:50 2017 +0200
emfplus: unified transformations, added test code
More unifications, changed all Map*() methods to use a single
B2DHomMatrix which is created based on former stuff, XForm now
completely replaced. To check, added debug-only code and switches
to the VclPixelProcessor so that visual checks get easy when
using these modes (overlay of both methods with modded colors).
Also resynched to master.
Change-Id: I7b749f90bfde2ec1c2e49ee90ca2ef368da0547e
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 4b5e45c7ef04..de9b7ad2f6b6 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -860,17 +860,52 @@ namespace drawinglayer
const primitive2d::MetafilePrimitive2D&
rMetafilePrimitive( static_cast< const primitive2d::MetafilePrimitive2D&
>(rCandidate) );
- static bool bTestMetaFilePrimitiveDecomposition( true );
- if( bTestMetaFilePrimitiveDecomposition &&
!rMetafilePrimitive.getMetaFile().GetUseCanvas() )
+ if( !rMetafilePrimitive.getMetaFile().GetUseCanvas() )
{
// use new Metafile decomposition
- // TODO EMF+ stuffed into METACOMMENT support required
process(rCandidate);
}
else
{
+#ifdef DBG_UTIL
+ // switch to test EMFPlus-enhanced
MetafileDecomposition
+ static bool bTestEMFPDecomposition(true);
+ // switch to show the new visualization color.-changed
behind
+ // the original output vor visual testing
+ static bool bUseChangedColorObject(true);
+
+ if (bTestEMFPDecomposition)
+ {
+ if (bUseChangedColorObject)
+ {
+ primitive2d::Primitive2DContainer
aDecomposition;
+
rMetafilePrimitive.get2DDecomposition(aDecomposition, getViewInformation2D());
+ const primitive2d::ModifiedColorPrimitive2D
aPrimitiveR(
+ aDecomposition,
+ basegfx::BColorModifierSharedPtr(
+ new
basegfx::BColorModifier_RGBLuminanceContrast(
+ 0.5, // red
+ -0.5, // green
+ -0.5, // blue
+ 0.0, // luminance
+ 0.0))); // contrast
+ processBasePrimitive2D(aPrimitiveR);
+ RenderMetafilePrimitive2D(rMetafilePrimitive);
+ }
+ else
+ {
+ process(rCandidate);
+ }
+ }
+ else
+ {
+ // direct draw of MetaFile
+ RenderMetafilePrimitive2D(rMetafilePrimitive);
+ }
+#else // DBG_UTIL
// direct draw of MetaFile
- RenderMetafilePrimitive2D( rMetafilePrimitive );
+ RenderMetafilePrimitive2D(rMetafilePrimitive);
+#endif // DBG_UTIL
}
if(bForceLineSnap)
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx
b/drawinglayer/source/tools/emfphelperdata.cxx
index 80d9a7f3fafa..c9ed51e8b5ca 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -131,14 +131,14 @@ namespace emfplushelper
case EmfPlusObjectTypeBrush:
{
EMFPBrush *brush;
- aObjects[index].reset(brush = new EMFPBrush());
+ maEMFPObjects[index].reset(brush = new EMFPBrush());
brush->Read(rObjectStream, *this);
break;
}
case EmfPlusObjectTypePen:
{
EMFPPen *pen;
- aObjects[index].reset(pen = new EMFPPen());
+ maEMFPObjects[index].reset(pen = new EMFPPen());
pen->Read(rObjectStream, *this);
break;
}
@@ -151,21 +151,21 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+\tpath");
SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex <<
header << " points: " << std::dec << points << " additional flags: 0x" <<
std::hex << pathFlags << std::dec);
EMFPPath *path;
- aObjects[index].reset(path = new EMFPPath(points));
+ maEMFPObjects[index].reset(path = new EMFPPath(points));
path->Read(rObjectStream, pathFlags, *this);
break;
}
case EmfPlusObjectTypeRegion:
{
EMFPRegion *region;
- aObjects[index].reset(region = new EMFPRegion());
+ maEMFPObjects[index].reset(region = new EMFPRegion());
region->Read(rObjectStream);
break;
}
case EmfPlusObjectTypeImage:
{
EMFPImage *image;
- aObjects[index].reset(image = new EMFPImage);
+ maEMFPObjects[index].reset(image = new EMFPImage);
image->type = 0;
image->width = 0;
image->height = 0;
@@ -177,7 +177,7 @@ namespace emfplushelper
case EmfPlusObjectTypeFont:
{
EMFPFont *font;
- aObjects[index].reset(font = new EMFPFont);
+ maEMFPObjects[index].reset(font = new EMFPFont);
font->emSize = 0;
font->sizeUnit = 0;
font->fontFlags = 0;
@@ -187,7 +187,7 @@ namespace emfplushelper
case EmfPlusObjectTypeStringFormat:
{
EMFPStringFormat *stringFormat;
- aObjects[index].reset(stringFormat = new EMFPStringFormat());
+ maEMFPObjects[index].reset(stringFormat = new
EMFPStringFormat());
stringFormat->Read(rObjectStream);
break;
}
@@ -287,49 +287,39 @@ namespace emfplushelper
return true;
}
- void EmfPlusHelperData::MapToDevice(double& x, double& y)
+ void EmfPlusHelperData::mappingChanged()
{
- // TODO: other units
- x = 100 * mnMmX*x / mnPixX;
- y = 100 * mnMmY*y / mnPixY;
+ // Call when
mnMmX/mnMmY/mnPixX/mnPixY/mnFrameLeft/mnFrameTop/maWorldTransform/ changes.
+ // Currently not used are mnHDPI/mnVDPI/mnFrameRight/mnFrameBottom.
*If* these should
+ // be used in the future, this method will need to be called.
+ //
+ // Re-calculate maMapTransform to contain the complete former
transformation so that
+ // it can be applied by a single matrix multiplication or be added to
an encapsulated
+ // primitive later
+ //
+ // To evtl. correct and see where this came from, please compare with
the implementations
+ // of EmfPlusHelperData::MapToDevice and EmfPlusHelperData::Map* in
prev versions
+ maMapTransform = maWorldTransform;
+ maMapTransform *= basegfx::tools::createScaleB2DHomMatrix(100.0 *
mnMmX / mnPixX, 100.0 * mnMmY / mnPixY);
+ maMapTransform *=
basegfx::tools::createTranslateB2DHomMatrix(double(-mnFrameLeft),
double(-mnFrameTop));
+ maMapTransform *=
basegfx::tools::createScaleB2DHomMatrix(maBaseTransform.get(0, 0),
maBaseTransform.get(1, 1));
}
::basegfx::B2DPoint EmfPlusHelperData::Map(double ix, double iy)
{
- double x, y;
-
- x = ix*aWorldTransform.get(0,0) + iy*aWorldTransform.get(0,1) +
aWorldTransform.get(0,2);
- y = ix*aWorldTransform.get(1,0) + iy*aWorldTransform.get(1,1) +
aWorldTransform.get(1,2);
-
- MapToDevice(x, y);
-
- x -= mnFrameLeft;
- y -= mnFrameTop;
-
- x *= aBaseTransform.get(0,0);
- y *= aBaseTransform.get(1,1);
-
- return ::basegfx::B2DPoint(x, y);
+ // map in one step using complete MapTransform (see mappingChanged)
+ return maMapTransform * ::basegfx::B2DPoint(ix, iy);
}
::basegfx::B2DSize EmfPlusHelperData::MapSize(double iwidth, double
iheight)
{
- double w, h;
-
- w = iwidth*aWorldTransform.get(0,0) + iheight*aWorldTransform.get(1,0);
- h = iwidth*aWorldTransform.get(1,0) + iheight*aWorldTransform.get(1,1);
-
- MapToDevice(w, h);
-
- w *= aBaseTransform.get(0,0);
- h *= aBaseTransform.get(1,1);
-
- return ::basegfx::B2DSize(w, h);
+ // map in one step using complete MapTransform (see mappingChanged)
+ return maMapTransform * ::basegfx::B2DSize(iwidth, iheight);
}
void EmfPlusHelperData::EMFPPlusDrawPolygon(const
::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex)
{
- const EMFPPen* pen = static_cast<EMFPPen*>(aObjects[penIndex &
0xff].get());
+ const EMFPPen* pen = static_cast<EMFPPen*>(maEMFPObjects[penIndex &
0xff].get());
SAL_WARN_IF(!pen, "cppcanvas.emf", "emf+ missing pen");
if (pen && polygon.count())
@@ -359,14 +349,15 @@ namespace emfplushelper
SvMemoryStream& rMS,
wmfemfhelper::TargetHolders& rTargetHolders,
wmfemfhelper::PropertyHolders& rPropertyHolders)
- : aBaseTransform(),
- aWorldTransform(),
- aObjects(),
- fPageScale(0.0),
- nOriginX(0),
- nOriginY(0),
- nHDPI(0),
- nVDPI(0),
+ : maBaseTransform(),
+ maWorldTransform(),
+ maMapTransform(),
+ maEMFPObjects(),
+ mfPageScale(0.0),
+ mnOriginX(0),
+ mnOriginY(0),
+ mnHDPI(0),
+ mnVDPI(0),
mnFrameLeft(0),
mnFrameTop(0),
mnFrameRight(0),
@@ -387,7 +378,8 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+ picture frame: " << mnFrameLeft << ","
<< mnFrameTop << " - " << mnFrameRight << "," << mnFrameBottom);
rMS.ReadInt32(mnPixX).ReadInt32(mnPixY).ReadInt32(mnMmX).ReadInt32(mnMmY);
SAL_INFO("cppcanvas.emf", "EMF+ ref device pixel size: " << mnPixX <<
"x" << mnPixY << " mm size: " << mnMmX << "x" << mnMmY);
- readXForm(rMS, aBaseTransform);
+ readXForm(rMS, maBaseTransform);
+ mappingChanged();
}
EmfPlusHelperData::~EmfPlusHelperData()
@@ -466,9 +458,9 @@ namespace emfplushelper
{
sal_uInt32 header, version;
-
rMS.ReadUInt32(header).ReadUInt32(version).ReadInt32(nHDPI).ReadInt32(nVDPI);
+
rMS.ReadUInt32(header).ReadUInt32(version).ReadInt32(mnHDPI).ReadInt32(mnVDPI);
SAL_INFO("cppcanvas.emf", "EMF+ Header");
- SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" <<
std::hex << header << " version: " << std::dec << version << " horizontal DPI:
" << nHDPI << " vertical DPI: " << nVDPI << " dual: " << (flags & 1));
+ SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" <<
std::hex << header << " version: " << std::dec << version << " horizontal DPI:
" << mnHDPI << " vertical DPI: " << mnVDPI << " dual: " << (flags & 1));
break;
}
case EmfPlusRecordTypeEndOfFile:
@@ -573,8 +565,8 @@ namespace emfplushelper
rMS.ReadUInt32(brushIndexOrColor);
SAL_INFO("cppcanvas.emf", "EMF+ FillPath slot: " <<
index);
-
EMFPPlusFillPolygon(static_cast<EMFPPath*>(aObjects[index].get())->GetPolygon(*this),
flags & 0x8000, brushIndexOrColor);
- //
EMFPPlusFillPolygon(static_cast<EMFPPath*>(aObjects[index])->GetPolygon(*this),
rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
+
EMFPPlusFillPolygon(static_cast<EMFPPath*>(maEMFPObjects[index].get())->GetPolygon(*this),
flags & 0x8000, brushIndexOrColor);
+ //
EMFPPlusFillPolygon(static_cast<EMFPPath*>(maEMFPObjects[index])->GetPolygon(*this),
rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
}
break;
case EmfPlusRecordTypeDrawEllipse:
@@ -705,7 +697,7 @@ namespace emfplushelper
rMS.ReadUInt32(penIndex);
SAL_INFO("cppcanvas.emf", "EMF+ DrawPath");
SAL_INFO("cppcanvas.emf", "EMF+\tpen: " << penIndex);
- EMFPPath* path = static_cast<EMFPPath*>(aObjects[flags
& 0xff].get());
+ EMFPPath* path =
static_cast<EMFPPath*>(maEMFPObjects[flags & 0xff].get());
SAL_WARN_IF(!path, "cppcanvas.emf",
"EmfPlusRecordTypeDrawPath missing path");
EMFPPlusDrawPolygon(path->GetPolygon(*this), penIndex);
@@ -768,10 +760,10 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+ " << (type ==
EmfPlusRecordTypeDrawImagePoints ? "DrawImagePoints" : "DrawImage") <<
"attributes index: " << attrIndex << "source unit: " << sourceUnit);
SAL_INFO("cppcanvas.emf", "EMF+\tTODO: use image
attributes");
- if (sourceUnit == 2 && aObjects[flags & 0xff].get())
+ if (sourceUnit == 2 && maEMFPObjects[flags &
0xff].get())
{
// we handle only GraphicsUnit.Pixel now
- EMFPImage& image = *static_cast<EMFPImage
*>(aObjects[flags & 0xff].get());
+ EMFPImage& image = *static_cast<EMFPImage
*>(maEMFPObjects[flags & 0xff].get());
float sx, sy, sw, sh;
sal_Int32 aCount;
ReadRectangle(rMS, sx, sy, sw, sh);
@@ -867,7 +859,7 @@ namespace emfplushelper
rMS.ReadFloat(lx).ReadFloat(ly).ReadFloat(lw).ReadFloat(lh);
SAL_INFO("cppcanvas.emf", "EMF+ DrawString
layoutRect: " << lx << "," << ly << " - " << lw << "x" << lh);
OUString text = read_uInt16s_ToOUString(rMS,
stringLength);
- EMFPStringFormat *stringFormat = static_cast<
EMFPStringFormat* >(aObjects[formatId & 0xff].get());
+ EMFPStringFormat *stringFormat = static_cast<
EMFPStringFormat* >(maEMFPObjects[formatId & 0xff].get());
// css::rendering::FontRequest aFontRequest;
//
// if (stringFormat)
@@ -922,9 +914,9 @@ namespace emfplushelper
}
case EmfPlusRecordTypeSetPageTransform:
{
- rMS.ReadFloat(fPageScale);
+ rMS.ReadFloat(mfPageScale);
SAL_INFO("cppcanvas.emf", "EMF+ SetPageTransform");
- SAL_INFO("cppcanvas.emf", "EMF+\tscale: " <<
fPageScale << " unit: " << flags);
+ SAL_INFO("cppcanvas.emf", "EMF+\tscale: " <<
mfPageScale << " unit: " << flags);
if (flags != UnitTypePixel)
{
@@ -932,16 +924,17 @@ namespace emfplushelper
}
else
{
- mnMmX *= fPageScale;
- mnMmY *= fPageScale;
+ mnMmX *= mfPageScale;
+ mnMmY *= mfPageScale;
+ mappingChanged();
}
break;
}
case EmfPlusRecordTypeSetRenderingOrigin:
{
- rMS.ReadInt32(nOriginX).ReadInt32(nOriginY);
+ rMS.ReadInt32(mnOriginX).ReadInt32(mnOriginY);
SAL_INFO("cppcanvas.emf", "EMF+ SetRenderingOrigin");
- SAL_INFO("cppcanvas.emf", "EMF+\torigin [x,y]: " <<
nOriginX << "," << nOriginY);
+ SAL_INFO("cppcanvas.emf", "EMF+\torigin [x,y]: " <<
mnOriginX << "," << mnOriginY);
break;
}
case EmfPlusRecordTypeSetTextRenderingHint:
@@ -1017,17 +1010,19 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+ SetWorldTransform");
basegfx::B2DHomMatrix transform;
readXForm(rMS, transform);
- aWorldTransform = transform;
+ maWorldTransform = transform;
+ mappingChanged();
SAL_INFO("cppcanvas.emf",
- "EMF+\tm11: " << aWorldTransform.get(0,0) <<
"\tm12: " << aWorldTransform.get(1,0) <<
- "\tm21: " << aWorldTransform.get(0,1) << "\tm22: "
<< aWorldTransform.get(1,1) <<
- "\tdx: " << aWorldTransform.get(0,2) << "\tdy: "
<< aWorldTransform.get(1,2));
+ "EMF+\tm11: " << maWorldTransform.get(0,0) <<
"\tm12: " << maWorldTransform.get(1,0) <<
+ "\tm21: " << maWorldTransform.get(0,1) << "\tm22:
" << maWorldTransform.get(1,1) <<
+ "\tdx: " << maWorldTransform.get(0,2) << "\tdy: "
<< maWorldTransform.get(1,2));
break;
}
case EmfPlusRecordTypeResetWorldTransform:
{
SAL_INFO("cppcanvas.emf", "EMF+ ResetWorldTransform");
- aWorldTransform.identity();
+ maWorldTransform.identity();
+ mappingChanged();
break;
}
case EmfPlusRecordTypeMultiplyWorldTransform:
@@ -1044,19 +1039,21 @@ namespace emfplushelper
if (flags & 0x2000)
{
// post multiply
- aWorldTransform *= transform;
+ maWorldTransform *= transform;
}
else
{
// pre multiply
- transform *= aWorldTransform;
- aWorldTransform = transform;
+ transform *= maWorldTransform;
+ maWorldTransform = transform;
}
+ mappingChanged();
+
SAL_INFO("cppcanvas.emf",
- "EMF+\tmatrix m11: " << aWorldTransform.get(0, 0)
<< "m12: " << aWorldTransform.get(0, 1) <<
- "EMF+\tm21: " << aWorldTransform.get(1, 0) <<
"m22: " << aWorldTransform.get(1, 1) <<
- "EMF+\tdx: " << aWorldTransform.get(2, 0) << "dy:
" << aWorldTransform.get(2, 1));
+ "EMF+\tmatrix m11: " << maWorldTransform.get(0, 0)
<< "m12: " << maWorldTransform.get(0, 1) <<
+ "EMF+\tm21: " << maWorldTransform.get(1, 0) <<
"m22: " << maWorldTransform.get(1, 1) <<
+ "EMF+\tdx: " << maWorldTransform.get(2, 0) << "dy:
" << maWorldTransform.get(2, 1));
break;
}
case EmfPlusRecordTypeTranslateWorldTransform:
@@ -1077,19 +1074,21 @@ namespace emfplushelper
if (flags & 0x2000)
{
// post multiply
- aWorldTransform *= transform;
+ maWorldTransform *= transform;
}
else
{
// pre multiply
- transform *= aWorldTransform;
- aWorldTransform = transform;
+ transform *= maWorldTransform;
+ maWorldTransform = transform;
}
+ mappingChanged();
+
SAL_INFO("cppcanvas.emf",
- "EMF+\tmatrix m11: " << aWorldTransform.get(0, 0)
<< "m12: " << aWorldTransform.get(0, 1) <<
- "EMF+\tm21: " << aWorldTransform.get(1, 0) <<
"m22: " << aWorldTransform.get(1, 1) <<
- "EMF+\tdx: " << aWorldTransform.get(2, 0) << "dy:
" << aWorldTransform.get(2, 1));
+ "EMF+\tmatrix m11: " << maWorldTransform.get(0, 0)
<< "m12: " << maWorldTransform.get(0, 1) <<
+ "EMF+\tm21: " << maWorldTransform.get(1, 0) <<
"m22: " << maWorldTransform.get(1, 1) <<
+ "EMF+\tdx: " << maWorldTransform.get(2, 0) << "dy:
" << maWorldTransform.get(2, 1));
break;
}
case EmfPlusRecordTypeScaleWorldTransform:
@@ -1102,26 +1101,28 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+ ScaleWorldTransform
Sx: " << transform.get(0,0) << " Sy: " << transform.get(1,1));
SAL_INFO("cppcanvas.emf",
- "EMF+\t m11: " << aWorldTransform.get(0,0) << ",
m12: " << aWorldTransform.get(0,1) <<
- "EMF+\t m21: " << aWorldTransform.get(1,0) << ",
m22: " << aWorldTransform.get(1,1) <<
- "EMF+\t dx: " << aWorldTransform.get(2,0) << ",
dy: " << aWorldTransform.get(2,1));
+ "EMF+\t m11: " << maWorldTransform.get(0,0) << ",
m12: " << maWorldTransform.get(0,1) <<
+ "EMF+\t m21: " << maWorldTransform.get(1,0) << ",
m22: " << maWorldTransform.get(1,1) <<
+ "EMF+\t dx: " << maWorldTransform.get(2,0) << ",
dy: " << maWorldTransform.get(2,1));
if (flags & 0x2000)
{
// post multiply
- aWorldTransform *= transform;
+ maWorldTransform *= transform;
}
else
{
// pre multiply
- transform *= aWorldTransform;
- aWorldTransform = transform;
+ transform *= maWorldTransform;
+ maWorldTransform = transform;
}
+ mappingChanged();
+
SAL_INFO("cppcanvas.emf",
- "EMF+\t m11: " << aWorldTransform.get(0, 0) << ",
m12: " << aWorldTransform.get(0, 1) <<
- "EMF+\t m21: " << aWorldTransform.get(1, 0) << ",
m22: " << aWorldTransform.get(1, 1) <<
- "EMF+\t dx: " << aWorldTransform.get(2, 0) << ",
dy: " << aWorldTransform.get(2, 1));
+ "EMF+\t m11: " << maWorldTransform.get(0, 0) << ",
m12: " << maWorldTransform.get(0, 1) <<
+ "EMF+\t m21: " << maWorldTransform.get(1, 0) << ",
m22: " << maWorldTransform.get(1, 1) <<
+ "EMF+\t dx: " << maWorldTransform.get(2, 0) << ",
dy: " << maWorldTransform.get(2, 1));
break;
}
case EmfPlusRecordTypeSetClipRect:
@@ -1161,7 +1162,7 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+ SetClipPath combine
mode: " << combineMode);
SAL_INFO("cppcanvas.emf", "EMF+\tpath in slot: " <<
(flags & 0xff));
- EMFPPath& path =
*static_cast<EMFPPath*>(aObjects[flags & 0xff].get());
+ EMFPPath& path =
*static_cast<EMFPPath*>(maEMFPObjects[flags & 0xff].get());
::basegfx::B2DPolyPolygon&
clipPoly(path.GetPolygon(*this));
// clipPoly.transform(rState.mapModeTransform);
@@ -1192,7 +1193,7 @@ namespace emfplushelper
int combineMode = (flags >> 8) & 0xf;
SAL_INFO("cppcanvas.emf", "EMF+ SetClipRegion");
SAL_INFO("cppcanvas.emf", "EMF+\tregion in slot: " <<
(flags & 0xff) << " combine mode: " << combineMode);
- EMFPRegion *region =
static_cast<EMFPRegion*>(aObjects[flags & 0xff].get());
+ EMFPRegion *region =
static_cast<EMFPRegion*>(maEMFPObjects[flags & 0xff].get());
// reset clip
if (region && region->parts == 0 &&
region->initialState == EmfPlusRegionInitialStateInfinite)
diff --git a/drawinglayer/source/tools/emfphelperdata.hxx
b/drawinglayer/source/tools/emfphelperdata.hxx
index c2d799cfd5f5..290fd4a0ad8a 100644
--- a/drawinglayer/source/tools/emfphelperdata.hxx
+++ b/drawinglayer/source/tools/emfphelperdata.hxx
@@ -171,7 +171,7 @@ namespace emfplushelper
// typedef struct
// {
-// basegfx::B2DHomMatrix aWorldTransform;
+// basegfx::B2DHomMatrix maWorldTransform;
// OutDevState aDevState;
// } EmfPlusGraphicState;
//
@@ -181,29 +181,31 @@ namespace emfplushelper
{
private:
/* EMF+ */
- basegfx::B2DHomMatrix aBaseTransform;
- basegfx::B2DHomMatrix aWorldTransform;
- std::unique_ptr<EMFPObject> aObjects[256];
- float fPageScale;
- sal_Int32 nOriginX;
- sal_Int32 nOriginY;
- sal_Int32 nHDPI;
- sal_Int32 nVDPI;
+ basegfx::B2DHomMatrix maBaseTransform;
+ basegfx::B2DHomMatrix maWorldTransform;
+ basegfx::B2DHomMatrix maMapTransform;
+
+ std::unique_ptr<EMFPObject> maEMFPObjects[256];
+ float mfPageScale;
+ sal_Int32 mnOriginX;
+ sal_Int32 mnOriginY;
+ sal_Int32 mnHDPI;
+ sal_Int32 mnVDPI;
/* EMF+ emf header info */
- sal_Int32 mnFrameLeft;
- sal_Int32 mnFrameTop;
- sal_Int32 mnFrameRight;
- sal_Int32 mnFrameBottom;
- sal_Int32 mnPixX;
- sal_Int32 mnPixY;
- sal_Int32 mnMmX;
- sal_Int32 mnMmY;
+ sal_Int32 mnFrameLeft;
+ sal_Int32 mnFrameTop;
+ sal_Int32 mnFrameRight;
+ sal_Int32 mnFrameBottom;
+ sal_Int32 mnPixX;
+ sal_Int32 mnPixY;
+ sal_Int32 mnMmX;
+ sal_Int32 mnMmY;
/* multipart object data */
- bool mbMultipart;
- sal_uInt16 mMFlags;
- SvMemoryStream mMStream;
+ bool mbMultipart;
+ sal_uInt16 mMFlags;
+ SvMemoryStream mMStream;
/* emf+ graphic state stack */
// GraphicStateMap mGSStack;
@@ -218,7 +220,7 @@ namespace emfplushelper
void ReadPoint(SvStream& s, float& x, float& y, sal_uInt32 flags);
// internal mapper
- void MapToDevice(double& x, double& y);
+ void mappingChanged();
// primitive creators
void EMFPPlusDrawPolygon(const ::basegfx::B2DPolyPolygon& polygon,
sal_uInt32 penIndex);
commit 58f831b4cee713855301e9d66b2b627993f8d5a7
Author: Armin Le Grand <[email protected]>
Date: Wed Jun 21 19:31:32 2017 +0200
emfplus: more corrections and rough geometry
Corrected/streamlined more, added 1st rough geometry
creation to have a proof of concept. Checked the
helper classes based on EMFPObject and their derivates.
First versions of EMFPPlusDrawPolygon and
EMFPPlusFillPolygon, but the complex info in the data
objects needs more complex primitive creation. Not sure
if primitive creators like createHairlineAndFillPrimitive
will be usable, these are based on PropertyHolder info.
Also added usage of HandleNewClipRegion, that should be
usable
Change-Id: I96119be290140bee252ee21a3e1187fad60e9c7d
diff --git a/drawinglayer/inc/wmfemfhelper.hxx
b/drawinglayer/inc/wmfemfhelper.hxx
index 699b065795df..a11b6578e572 100644
--- a/drawinglayer/inc/wmfemfhelper.hxx
+++ b/drawinglayer/inc/wmfemfhelper.hxx
@@ -208,6 +208,11 @@ namespace wmfemfhelper
drawinglayer::primitive2d::Primitive2DContainer interpretMetafile(
const GDIMetaFile& rMetaFile,
const drawinglayer::geometry::ViewInformation2D& rViewInformation);
+
+ void HandleNewClipRegion(
+ const basegfx::B2DPolyPolygon& rClipPolyPolygon,
+ TargetHolders& rTargetHolders,
+ PropertyHolders& rPropertyHolders);
}
#endif
diff --git a/drawinglayer/source/tools/emfpbrush.cxx
b/drawinglayer/source/tools/emfpbrush.cxx
index c093a5682572..d55a16ad30d7 100644
--- a/drawinglayer/source/tools/emfpbrush.cxx
+++ b/drawinglayer/source/tools/emfpbrush.cxx
@@ -64,23 +64,32 @@ namespace emfplushelper
EMFPBrush::~EMFPBrush()
{
- if (blendPositions != nullptr) {
+ if (blendPositions != nullptr)
+ {
delete[] blendPositions;
blendPositions = nullptr;
}
- if (colorblendPositions != nullptr) {
+
+ if (colorblendPositions != nullptr)
+ {
delete[] colorblendPositions;
colorblendPositions = nullptr;
}
- if (colorblendColors != nullptr) {
+
+ if (colorblendColors != nullptr)
+ {
delete[] colorblendColors;
colorblendColors = nullptr;
}
- if (surroundColors != nullptr) {
+
+ if (surroundColors != nullptr)
+ {
delete[] surroundColors;
surroundColors = nullptr;
}
- if (path) {
+
+ if (path)
+ {
delete path;
path = nullptr;
}
@@ -95,232 +104,267 @@ namespace emfplushelper
SAL_INFO("cppcanvas.emf", "EMF+\tbrush");
SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header <<
" type: " << type << std::dec);
- switch (type) {
- case BrushTypeSolidColor:
+ switch (type)
{
- sal_uInt32 color;
+ case BrushTypeSolidColor:
+ {
+ sal_uInt32 color;
+ s.ReadUInt32(color);
- s.ReadUInt32(color);
- solidColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff,
(color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tsolid color: 0x" << std::hex <<
color << std::dec);
- break;
- }
- case BrushTypeHatchFill:
- {
- sal_uInt32 style;
- sal_uInt32 foregroundColor;
- sal_uInt32 backgroundColor;
- s.ReadUInt32(style);
- s.ReadUInt32(foregroundColor);
- s.ReadUInt32(backgroundColor);
-
- hatchStyle = static_cast<EmfPlusHatchStyle>(style);
- solidColor = ::Color(0xff - (foregroundColor >> 24),
(foregroundColor >> 16) & 0xff, (foregroundColor >> 8) & 0xff, foregroundColor
& 0xff);
- secondColor = ::Color(0xff - (backgroundColor >> 24),
(backgroundColor >> 16) & 0xff, (backgroundColor >> 8) & 0xff, backgroundColor
& 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\thatch style " << style << "
foregroundcolor: 0x" << solidColor.AsRGBHexString() << " background 0x" <<
secondColor.AsRGBHexString());
- break;
- }
- case BrushTypeTextureFill:
- {
- SAL_WARN("cppcanvas.emf", "EMF+\tTODO: implement
BrushTypeTextureFill brush");
- break;
- }
- case BrushTypePathGradient:
- {
- s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
+ solidColor = ::Color(0xff - (color >> 24), (color >> 16) &
0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tsolid color: 0x" << std::hex
<< color << std::dec);
+ break;
+ }
+ case BrushTypeHatchFill:
+ {
+ sal_uInt32 style;
+ sal_uInt32 foregroundColor;
+ sal_uInt32 backgroundColor;
+ s.ReadUInt32(style);
+ s.ReadUInt32(foregroundColor);
+ s.ReadUInt32(backgroundColor);
+
+ hatchStyle = static_cast<EmfPlusHatchStyle>(style);
+ solidColor = ::Color(0xff - (foregroundColor >> 24),
(foregroundColor >> 16) & 0xff, (foregroundColor >> 8) & 0xff, foregroundColor
& 0xff);
+ secondColor = ::Color(0xff - (backgroundColor >> 24),
(backgroundColor >> 16) & 0xff, (backgroundColor >> 8) & 0xff, backgroundColor
& 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\thatch style " << style << "
foregroundcolor: 0x" << solidColor.AsRGBHexString() << " background 0x" <<
secondColor.AsRGBHexString());
+ break;
+ }
+ case BrushTypeTextureFill:
+ {
+ SAL_WARN("cppcanvas.emf", "EMF+\tTODO: implement
BrushTypeTextureFill brush");
+ break;
+ }
+ case BrushTypePathGradient:
+ {
+ s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
+ SAL_INFO("cppcanvas.emf", "EMF+\tpath gradient, additional
flags: 0x" << std::hex << additionalFlags << std::dec);
+ sal_uInt32 color;
+ s.ReadUInt32(color);
+ solidColor = ::Color(0xff - (color >> 24), (color >> 16) &
0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tcenter color: 0x" << std::hex
<< color << std::dec);
+ s.ReadFloat(areaX).ReadFloat(areaY);
+ SAL_INFO("cppcanvas.emf", "EMF+\tcenter point: " << areaX <<
"," << areaY);
+ s.ReadInt32(surroundColorsNumber);
+ SAL_INFO("cppcanvas.emf", "EMF+\t number of surround colors: "
<< surroundColorsNumber);
+
+ if (surroundColorsNumber<0 ||
sal_uInt32(surroundColorsNumber)>SAL_MAX_INT32 / sizeof(::Color))
+ {
+ surroundColorsNumber = SAL_MAX_INT32 / sizeof(::Color);
+ }
- SAL_INFO("cppcanvas.emf", "EMF+\tpath gradient, additional flags:
0x" << std::hex << additionalFlags << std::dec);
+ surroundColors = new ::Color[surroundColorsNumber];
- sal_uInt32 color;
+ for (int i = 0; i < surroundColorsNumber; i++)
+ {
+ s.ReadUInt32(color);
+ surroundColors[i] = ::Color(0xff - (color >> 24), (color
>> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ if (i == 0)
+ secondColor = surroundColors[0];
+ SAL_INFO("cppcanvas.emf", "EMF+\tsurround color[" << i <<
"]: 0x" << std::hex << color << std::dec);
+ }
- s.ReadUInt32(color);
- solidColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff,
(color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tcenter color: 0x" << std::hex <<
color << std::dec);
+ if (additionalFlags & 0x01)
+ {
+ sal_Int32 pathLength;
- s.ReadFloat(areaX).ReadFloat(areaY);
- SAL_INFO("cppcanvas.emf", "EMF+\tcenter point: " << areaX << ","
<< areaY);
+ s.ReadInt32(pathLength);
+ SAL_INFO("cppcanvas.emf", "EMF+\tpath length: " <<
pathLength);
- s.ReadInt32(surroundColorsNumber);
- SAL_INFO("cppcanvas.emf", "EMF+\t number of surround colors: " <<
surroundColorsNumber);
+ sal_uInt64 const pos = s.Tell();
- if (surroundColorsNumber<0 ||
sal_uInt32(surroundColorsNumber)>SAL_MAX_INT32 / sizeof(::Color))
- surroundColorsNumber = SAL_MAX_INT32 / sizeof(::Color);
+ sal_uInt32 pathHeader;
+ sal_Int32 pathPoints, pathFlags;
+
s.ReadUInt32(pathHeader).ReadInt32(pathPoints).ReadInt32(pathFlags);
- surroundColors = new ::Color[surroundColorsNumber];
- for (int i = 0; i < surroundColorsNumber; i++) {
- s.ReadUInt32(color);
- surroundColors[i] = ::Color(0xff - (color >> 24), (color >>
16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- if (i == 0)
- secondColor = surroundColors[0];
- SAL_INFO("cppcanvas.emf", "EMF+\tsurround color[" << i << "]:
0x" << std::hex << color << std::dec);
- }
+ SAL_INFO("cppcanvas.emf", "EMF+\tpath (brush path
gradient)");
+ SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex
<< pathHeader << " points: " << std::dec << pathPoints << " additional flags:
0x" << std::hex << pathFlags << std::dec);
- if (additionalFlags & 0x01) {
- sal_Int32 pathLength;
+ path = new EMFPPath(pathPoints);
+ path->Read(s, pathFlags, rR);
- s.ReadInt32(pathLength);
- SAL_INFO("cppcanvas.emf", "EMF+\tpath length: " << pathLength);
+ s.Seek(pos + pathLength);
- sal_uInt64 const pos = s.Tell();
+ const ::basegfx::B2DRectangle
aBounds(::basegfx::tools::getRange(path->GetPolygon(rR, false)));
+ areaWidth = aBounds.getWidth();
+ areaHeight = aBounds.getHeight();
+ SAL_INFO("cppcanvas.emf", "EMF+\t polygon bounding box: "
<< aBounds.getMinX() << "," << aBounds.getMinY() << " " << aBounds.getWidth()
<< "x" << aBounds.getHeight());
+ }
+ else
+ {
+ sal_Int32 boundaryPointCount;
+ s.ReadInt32(boundaryPointCount);
+
+ sal_uInt64 const pos = s.Tell();
+ SAL_INFO("cppcanvas.emf", "EMF+\t use boundary, points: "
<< boundaryPointCount);
+ path = new EMFPPath(boundaryPointCount);
+ path->Read(s, 0x0, rR);
+
+ s.Seek(pos + 8 * boundaryPointCount);
+
+ const ::basegfx::B2DRectangle
aBounds(::basegfx::tools::getRange(path->GetPolygon(rR, false)));
+ areaWidth = aBounds.getWidth();
+ areaHeight = aBounds.getHeight();
+ SAL_INFO("cppcanvas.emf", "EMF+\t polygon bounding box: "
<< aBounds.getMinX() << "," << aBounds.getMinY() << " " << aBounds.getWidth()
<< "x" << aBounds.getHeight());
+ }
- sal_uInt32 pathHeader;
- sal_Int32 pathPoints, pathFlags;
-
s.ReadUInt32(pathHeader).ReadInt32(pathPoints).ReadInt32(pathFlags);
+ if (additionalFlags & 0x02)
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation");
+ rR.readXForm(s, brush_transformation);
+ hasTransformation = true;
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\tm11: " << brush_transformation.get(0,0)
<< " m12: " << brush_transformation.get(1,0) <<
+ "\nEMF+\tm21: " <<
brush_transformation.get(0,1) << " m22: " << brush_transformation.get(1,1) <<
+ "\nEMF+\tdx: " <<
brush_transformation.get(0,2) << " dy: " << brush_transformation.get(1,2));
- SAL_INFO("cppcanvas.emf", "EMF+\tpath (brush path gradient)");
- SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex <<
pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x"
<< std::hex << pathFlags << std::dec);
+ }
- path = new EMFPPath(pathPoints);
- path->Read(s, pathFlags, rR);
+ if (additionalFlags & 0x08)
+ {
+ s.ReadInt32(blendPoints);
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse blend, points: " <<
blendPoints);
+ if (blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32
/ (2 * sizeof(float)))
+ blendPoints = SAL_MAX_INT32 / (2 * sizeof(float));
+ blendPositions = new float[2 * blendPoints];
+ blendFactors = blendPositions + blendPoints;
+
+ for (int i = 0; i < blendPoints; i++)
+ {
+ s.ReadFloat(blendPositions[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i <<
"]: " << blendPositions[i]);
+ }
+
+ for (int i = 0; i < blendPoints; i++)
+ {
+ s.ReadFloat(blendFactors[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tfactor[" << i << "]:
" << blendFactors[i]);
+ }
+ }
- s.Seek(pos + pathLength);
+ if (additionalFlags & 0x04)
+ {
+ s.ReadInt32(colorblendPoints);
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse color blend, points:
" << colorblendPoints);
+
+ if (colorblendPoints<0 ||
sal_uInt32(colorblendPoints)>SAL_MAX_INT32 / sizeof(float))
+ {
+ colorblendPoints = SAL_MAX_INT32 / sizeof(float);
+ }
+
+ if (sal_uInt32(colorblendPoints) > SAL_MAX_INT32 /
sizeof(::Color))
+ {
+ colorblendPoints = SAL_MAX_INT32 / sizeof(::Color);
+ }
+
+ colorblendPositions = new float[colorblendPoints];
+ colorblendColors = new ::Color[colorblendPoints];
+
+ for (int i = 0; i < colorblendPoints; i++)
+ {
+ s.ReadFloat(colorblendPositions[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i <<
"]: " << colorblendPositions[i]);
+ }
+
+ for (int i = 0; i < colorblendPoints; i++)
+ {
+ s.ReadUInt32(color);
+ colorblendColors[i] = ::Color(0xff - (color >> 24),
(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tcolor[" << i << "]:
0x" << std::hex << color << std::dec);
+ }
+ }
- const ::basegfx::B2DRectangle
aBounds(::basegfx::tools::getRange(path->GetPolygon(rR, false)));
- areaWidth = aBounds.getWidth();
- areaHeight = aBounds.getHeight();
- SAL_INFO("cppcanvas.emf", "EMF+\t polygon bounding box: " <<
aBounds.getMinX() << "," << aBounds.getMinY() << " " << aBounds.getWidth() <<
"x" << aBounds.getHeight());
+ break;
}
- else
+ case BrushTypeLinearGradient:
{
- sal_Int32 boundaryPointCount;
- s.ReadInt32(boundaryPointCount);
-
- sal_uInt64 const pos = s.Tell();
- SAL_INFO("cppcanvas.emf", "EMF+\t use boundary, points: " <<
boundaryPointCount);
- path = new EMFPPath(boundaryPointCount);
- path->Read(s, 0x0, rR);
-
- s.Seek(pos + 8 * boundaryPointCount);
-
- const ::basegfx::B2DRectangle
aBounds(::basegfx::tools::getRange(path->GetPolygon(rR, false)));
- areaWidth = aBounds.getWidth();
- areaHeight = aBounds.getHeight();
- SAL_INFO("cppcanvas.emf", "EMF+\t polygon bounding box: " <<
aBounds.getMinX() << "," << aBounds.getMinY() << " " << aBounds.getWidth() <<
"x" << aBounds.getHeight());
- }
+ s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
+ SAL_INFO("cppcanvas.emf", "EMF+\tlinear gradient, additional
flags: 0x" << std::hex << additionalFlags << std::dec);
+
s.ReadFloat(areaX).ReadFloat(areaY).ReadFloat(areaWidth).ReadFloat(areaHeight);
+ SAL_INFO("cppcanvas.emf", "EMF+\tarea: " << areaX << "," <<
areaY << " - " << areaWidth << "x" << areaHeight);
+ sal_uInt32 color;
+ s.ReadUInt32(color);
+ solidColor = ::Color(0xff - (color >> 24), (color >> 16) &
0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tfirst color: 0x" << std::hex
<< color << std::dec);
+ s.ReadUInt32(color);
+ secondColor = ::Color(0xff - (color >> 24), (color >> 16) &
0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tsecond color: 0x" << std::hex
<< color << std::dec);
- if (additionalFlags & 0x02) {
- SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation");
- rR.readXForm(s, brush_transformation);
- hasTransformation = true;
- SAL_INFO("cppcanvas.emf",
- "EMF+\tm11: " << brush_transformation.get(0,0) <<
" m12: " << brush_transformation.get(1,0) <<
- "\nEMF+\tm21: " << brush_transformation.get(0,1)
<< " m22: " << brush_transformation.get(1,1) <<
- "\nEMF+\tdx: " << brush_transformation.get(0,2) <<
" dy: " << brush_transformation.get(1,2));
+ // repeated colors, unknown meaning, see
http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/ObjectBrush.html
+ s.ReadUInt32(color);
+ s.ReadUInt32(color);
- }
- if (additionalFlags & 0x08) {
- s.ReadInt32(blendPoints);
- SAL_INFO("cppcanvas.emf", "EMF+\tuse blend, points: " <<
blendPoints);
- if (blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32 /
(2 * sizeof(float)))
- blendPoints = SAL_MAX_INT32 / (2 * sizeof(float));
- blendPositions = new float[2 * blendPoints];
- blendFactors = blendPositions + blendPoints;
- for (int i = 0; i < blendPoints; i++) {
- s.ReadFloat(blendPositions[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: "
<< blendPositions[i]);
+ if (additionalFlags & 0x02)
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation");
+ rR.readXForm(s, brush_transformation);
+ hasTransformation = true;
+ SAL_INFO("cppcanvas.emf",
+ "EMF+\tm11: " << brush_transformation.get(0,0) << "
m12: " << brush_transformation.get(1,0) <<
+ "\nEMF+\tm21: " << brush_transformation.get(0,1) << "
m22: " << brush_transformation.get(1,1) <<
+ "\nEMF+\tdx: " << brush_transformation.get(0,2) << "
dy: " << brush_transformation.get(1,2));
}
- for (int i = 0; i < blendPoints; i++) {
- s.ReadFloat(blendFactors[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tfactor[" << i << "]: " <<
blendFactors[i]);
- }
- }
- if (additionalFlags & 0x04) {
- s.ReadInt32(colorblendPoints);
- SAL_INFO("cppcanvas.emf", "EMF+\tuse color blend, points: " <<
colorblendPoints);
- if (colorblendPoints<0 ||
sal_uInt32(colorblendPoints)>SAL_MAX_INT32 / sizeof(float))
- colorblendPoints = SAL_MAX_INT32 / sizeof(float);
- if (sal_uInt32(colorblendPoints)>SAL_MAX_INT32 /
sizeof(::Color))
- colorblendPoints = SAL_MAX_INT32 / sizeof(::Color);
- colorblendPositions = new float[colorblendPoints];
- colorblendColors = new ::Color[colorblendPoints];
- for (int i = 0; i < colorblendPoints; i++) {
- s.ReadFloat(colorblendPositions[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: "
<< colorblendPositions[i]);
- }
- for (int i = 0; i < colorblendPoints; i++) {
- s.ReadUInt32(color);
- colorblendColors[i] = ::Color(0xff - (color >> 24), (color
>> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tcolor[" << i << "]: 0x"
<< std::hex << color << std::dec);
+ if (additionalFlags & 0x08)
+ {
+ s.ReadInt32(blendPoints);
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse blend, points: " <<
blendPoints);
+ if (blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32
/ (2 * sizeof(float)))
+ blendPoints = SAL_MAX_INT32 / (2 * sizeof(float));
+ blendPositions = new float[2 * blendPoints];
+ blendFactors = blendPositions + blendPoints;
+
+ for (int i = 0; i < blendPoints; i++)
+ {
+ s.ReadFloat(blendPositions[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i <<
"]: " << blendPositions[i]);
+ }
+
+ for (int i = 0; i < blendPoints; i++)
+ {
+ s.ReadFloat(blendFactors[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tfactor[" << i << "]:
" << blendFactors[i]);
+ }
}
- }
-
- break;
- }
- case BrushTypeLinearGradient:
- {
- s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
- SAL_INFO("cppcanvas.emf", "EMF+\tlinear gradient, additional
flags: 0x" << std::hex << additionalFlags << std::dec);
-
-
s.ReadFloat(areaX).ReadFloat(areaY).ReadFloat(areaWidth).ReadFloat(areaHeight);
-
- SAL_INFO("cppcanvas.emf", "EMF+\tarea: " << areaX << "," << areaY
<< " - " << areaWidth << "x" << areaHeight);
-
- sal_uInt32 color;
-
- s.ReadUInt32(color);
- solidColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff,
(color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tfirst color: 0x" << std::hex <<
color << std::dec);
-
- s.ReadUInt32(color);
- secondColor = ::Color(0xff - (color >> 24), (color >> 16) & 0xff,
(color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tsecond color: 0x" << std::hex <<
color << std::dec);
-
- // repeated colors, unknown meaning, see
http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/ObjectBrush.html
- s.ReadUInt32(color);
- s.ReadUInt32(color);
-
- if (additionalFlags & 0x02) {
- SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation");
- rR.readXForm(s, brush_transformation);
- hasTransformation = true;
- SAL_INFO("cppcanvas.emf",
- "EMF+\tm11: " << brush_transformation.get(0,0) << " m12: "
<< brush_transformation.get(1,0) <<
- "\nEMF+\tm21: " << brush_transformation.get(0,1) << " m22:
" << brush_transformation.get(1,1) <<
- "\nEMF+\tdx: " << brush_transformation.get(0,2) << " dy: "
<< brush_transformation.get(1,2));
- }
- if (additionalFlags & 0x08) {
- s.ReadInt32(blendPoints);
- SAL_INFO("cppcanvas.emf", "EMF+\tuse blend, points: " <<
blendPoints);
- if (blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32 /
(2 * sizeof(float)))
- blendPoints = SAL_MAX_INT32 / (2 * sizeof(float));
- blendPositions = new float[2 * blendPoints];
- blendFactors = blendPositions + blendPoints;
- for (int i = 0; i < blendPoints; i++) {
- s.ReadFloat(blendPositions[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: "
<< blendPositions[i]);
- }
- for (int i = 0; i < blendPoints; i++) {
- s.ReadFloat(blendFactors[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tfactor[" << i << "]: " <<
blendFactors[i]);
+ if (additionalFlags & 0x04)
+ {
+ s.ReadInt32(colorblendPoints);
+ SAL_INFO("cppcanvas.emf", "EMF+\tuse color blend, points:
" << colorblendPoints);
+
+ if (colorblendPoints<0 ||
sal_uInt32(colorblendPoints)>SAL_MAX_INT32 / sizeof(float))
+ {
+ colorblendPoints = SAL_MAX_INT32 / sizeof(float);
+ }
+
+ if (sal_uInt32(colorblendPoints) > SAL_MAX_INT32 /
sizeof(::Color))
+ {
+ colorblendPoints = sal_uInt32(SAL_MAX_INT32) /
sizeof(::Color);
+ }
+
+ colorblendPositions = new float[colorblendPoints];
+ colorblendColors = new ::Color[colorblendPoints];
+
+ for (int i = 0; i < colorblendPoints; i++)
+ {
+ s.ReadFloat(colorblendPositions[i]);
+ SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i <<
"]: " << colorblendPositions[i]);
+ }
+
+ for (int i = 0; i < colorblendPoints; i++)
+ {
+ s.ReadUInt32(color);
+ colorblendColors[i] = ::Color(0xff - (color >> 24),
(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ SAL_INFO("cppcanvas.emf", "EMF+\tcolor[" << i << "]:
0x" << std::hex << color << std::dec);
+ }
}
- }
- if (additionalFlags & 0x04) {
- s.ReadInt32(colorblendPoints);
- SAL_INFO("cppcanvas.emf", "EMF+\tuse color blend, points: " <<
colorblendPoints);
- if (colorblendPoints<0 ||
sal_uInt32(colorblendPoints)>SAL_MAX_INT32 / sizeof(float))
- colorblendPoints = SAL_MAX_INT32 / sizeof(float);
- if (sal_uInt32(colorblendPoints)>SAL_MAX_INT32 /
sizeof(::Color))
- colorblendPoints = sal_uInt32(SAL_MAX_INT32) /
sizeof(::Color);
- colorblendPositions = new float[colorblendPoints];
- colorblendColors = new ::Color[colorblendPoints];
- for (int i = 0; i < colorblendPoints; i++) {
- s.ReadFloat(colorblendPositions[i]);
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: "
<< colorblendPositions[i]);
- }
- for (int i = 0; i < colorblendPoints; i++) {
- s.ReadUInt32(color);
- colorblendColors[i] = ::Color(0xff - (color >> 24), (color
>> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tcolor[" << i << "]: 0x"
<< std::hex << color << std::dec);
- }
+ break;
+ }
+ default:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\tunhandled brush type: " <<
std::hex << type << std::dec);
}
-
- break;
- }
- default:
- SAL_INFO("cppcanvas.emf", "EMF+\tunhandled brush type: " <<
std::hex << type << std::dec);
}
}
}
diff --git a/drawinglayer/source/tools/emfpcustomlinecap.cxx
b/drawinglayer/source/tools/emfpcustomlinecap.cxx
index 9024a11a564e..d2d211d62d3e 100644
--- a/drawinglayer/source/tools/emfpcustomlinecap.cxx
+++ b/drawinglayer/source/tools/emfpcustomlinecap.cxx
@@ -46,7 +46,6 @@ namespace emfplushelper
{
const sal_uInt32 EmfPlusCustomLineCapDataTypeDefault = 0x00000000;
const sal_uInt32 EmfPlusCustomLineCapDataTypeAdjustableArrow = 0x00000001;
-
const sal_uInt32 EmfPlusCustomLineCapDataFillPath = 0x00000001;
const sal_uInt32 EmfPlusCustomLineCapDataLinePath = 0x00000002;
@@ -75,17 +74,14 @@ namespace emfplushelper
sal_Int32 pathLength;
s.ReadInt32(pathLength);
SAL_INFO("cppcanvas.emf", "EMF+\t\tpath length: " << pathLength);
-
sal_uInt32 pathHeader;
sal_Int32 pathPoints, pathFlags;
s.ReadUInt32(pathHeader).ReadInt32(pathPoints).ReadInt32(pathFlags);
-
SAL_INFO("cppcanvas.emf", "EMF+\t\tpath (custom cap line path)");
SAL_INFO("cppcanvas.emf", "EMF+\t\theader: 0x" << std::hex <<
pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x"
<< std::hex << pathFlags << std::dec);
EMFPPath path(pathPoints);
path.Read(s, pathFlags, rR);
-
polygon = path.GetPolygon(rR, false);
mbIsFilled = bFill;
@@ -93,16 +89,13 @@ namespace emfplushelper
// expects
B2DHomMatrix aMatrix;
aMatrix.scale(1.0, -1.0);
-
polygon.transform(aMatrix);
};
void EMFPCustomLineCap::Read(SvStream& s, EmfPlusHelperData& rR)
{
sal_uInt32 header;
-
s.ReadUInt32(header).ReadUInt32(type);
-
SAL_INFO("cppcanvas.emf", "EMF+\t\tcustom cap");
SAL_INFO("cppcanvas.emf", "EMF+\t\theader: 0x" << std::hex << header
<< " type: " << type << std::dec);
diff --git a/drawinglayer/source/tools/emfpfont.cxx
b/drawinglayer/source/tools/emfpfont.cxx
index b191a8f4c7e5..754e59e94319 100644
--- a/drawinglayer/source/tools/emfpfont.cxx
+++ b/drawinglayer/source/tools/emfpfont.cxx
@@ -44,11 +44,8 @@ namespace emfplushelper
sal_uInt32 header;
sal_uInt32 reserved;
sal_uInt32 length;
-
s.ReadUInt32(header).ReadFloat(emSize).ReadUInt32(sizeUnit).ReadInt32(fontFlags).ReadUInt32(reserved).ReadUInt32(length);
-
SAL_WARN_IF((header >> 12) != 0xdbc01, "cppcanvas.emf", "Invalid
header - not 0xdbc01");
-
SAL_INFO("cppcanvas.emf", "EMF+\tfont\nEMF+\theader: 0x" << std::hex
<< (header >> 12) << " version: 0x" << (header & 0x1fff) << " size: " <<
std::dec << emSize << " unit: 0x" << std::hex << sizeUnit << std::dec);
SAL_INFO("cppcanvas.emf", "EMF+\tflags: 0x" << std::hex << fontFlags
<< " reserved: 0x" << reserved << " length: 0x" << std::hex << length <<
std::dec);
@@ -58,7 +55,9 @@ namespace emfplushelper
sal_Unicode *chars = pStr->buffer;
for (sal_uInt32 i = 0; i < length; ++i)
+ {
s.ReadUtf16(chars[i]);
+ }
family = OUString(pStr, SAL_NO_ACQUIRE);
SAL_INFO("cppcanvas.emf", "EMF+\tfamily: " << family);
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx
b/drawinglayer/source/tools/emfphelperdata.cxx
index fcab2bbd7a44..80d9a7f3fafa 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -26,6 +26,8 @@
#include <emfpfont.hxx>
#include <emfpstringformat.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
+#include <wmfemfhelper.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
namespace emfplushelper
{
@@ -33,45 +35,45 @@ namespace emfplushelper
{
switch (type)
{
- case EmfPlusRecordTypeHeader: return "EmfPlusRecordTypeHeader";
- case EmfPlusRecordTypeEndOfFile: return "EmfPlusRecordTypeEndOfFile";
- case EmfPlusRecordTypeGetDC: return "EmfPlusRecordTypeGetDC";
- case EmfPlusRecordTypeObject: return "EmfPlusRecordTypeObject";
- case EmfPlusRecordTypeFillRects: return "EmfPlusRecordTypeFillRects";
- case EmfPlusRecordTypeDrawRects: return "EmfPlusRecordTypeDrawRects";
- case EmfPlusRecordTypeFillPolygon: return
"EmfPlusRecordTypeFillPolygon";
- case EmfPlusRecordTypeDrawLines: return "EmfPlusRecordTypeDrawLines";
- case EmfPlusRecordTypeFillEllipse: return
"EmfPlusRecordTypeFillEllipse";
- case EmfPlusRecordTypeDrawEllipse: return
"EmfPlusRecordTypeDrawEllipse";
- case EmfPlusRecordTypeFillPie: return "EmfPlusRecordTypeFillPie";
- case EmfPlusRecordTypeDrawPie: return "EmfPlusRecordTypeDrawPie";
- case EmfPlusRecordTypeDrawArc: return "EmfPlusRecordTypeDrawArc";
- case EmfPlusRecordTypeFillPath: return "EmfPlusRecordTypeFillPath";
- case EmfPlusRecordTypeDrawPath: return "EmfPlusRecordTypeDrawPath";
- case EmfPlusRecordTypeDrawBeziers: return
"EmfPlusRecordTypeDrawBeziers";
- case EmfPlusRecordTypeDrawImage: return "EmfPlusRecordTypeDrawImage";
- case EmfPlusRecordTypeDrawImagePoints: return
"EmfPlusRecordTypeDrawImagePoints";
- case EmfPlusRecordTypeDrawString: return "EmfPlusRecordTypeDrawString";
- case EmfPlusRecordTypeSetRenderingOrigin: return
"EmfPlusRecordTypeSetRenderingOrigin";
- case EmfPlusRecordTypeSetAntiAliasMode: return
"EmfPlusRecordTypeSetAntiAliasMode";
- case EmfPlusRecordTypeSetTextRenderingHint: return
"EmfPlusRecordTypeSetTextRenderingHint";
- case EmfPlusRecordTypeSetInterpolationMode: return
"EmfPlusRecordTypeSetInterpolationMode";
- case EmfPlusRecordTypeSetPixelOffsetMode: return
"EmfPlusRecordTypeSetPixelOffsetMode";
- case EmfPlusRecordTypeSetCompositingQuality: return
"EmfPlusRecordTypeSetCompositingQuality";
- case EmfPlusRecordTypeSave: return "EmfPlusRecordTypeSave";
- case EmfPlusRecordTypeRestore: return "EmfPlusRecordTypeRestore";
- case EmfPlusRecordTypeBeginContainerNoParams: return
"EmfPlusRecordTypeBeginContainerNoParams";
- case EmfPlusRecordTypeEndContainer: return
"EmfPlusRecordTypeEndContainer";
- case EmfPlusRecordTypeSetWorldTransform: return
"EmfPlusRecordTypeSetWorldTransform";
- case EmfPlusRecordTypeResetWorldTransform: return
"EmfPlusRecordTypeResetWorldTransform";
- case EmfPlusRecordTypeMultiplyWorldTransform: return
"EmfPlusRecordTypeMultiplyWorldTransform";
- case EmfPlusRecordTypeTranslateWorldTransform: return
"EmfPlusRecordTypeTranslateWorldTransform";
- case EmfPlusRecordTypeScaleWorldTransform: return
"EmfPlusRecordTypeScaleWorldTransform";
- case EmfPlusRecordTypeSetPageTransform: return
"EmfPlusRecordTypeSetPageTransform";
- case EmfPlusRecordTypeSetClipRect: return
"EmfPlusRecordTypeSetClipRect";
- case EmfPlusRecordTypeSetClipPath: return
"EmfPlusRecordTypeSetClipPath";
- case EmfPlusRecordTypeSetClipRegion: return
"EmfPlusRecordTypeSetClipRegion";
- case EmfPlusRecordTypeDrawDriverString: return
"EmfPlusRecordTypeDrawDriverString";
+ case EmfPlusRecordTypeHeader: return "EmfPlusRecordTypeHeader";
+ case EmfPlusRecordTypeEndOfFile: return
"EmfPlusRecordTypeEndOfFile";
+ case EmfPlusRecordTypeGetDC: return "EmfPlusRecordTypeGetDC";
+ case EmfPlusRecordTypeObject: return "EmfPlusRecordTypeObject";
+ case EmfPlusRecordTypeFillRects: return
"EmfPlusRecordTypeFillRects";
+ case EmfPlusRecordTypeDrawRects: return
"EmfPlusRecordTypeDrawRects";
+ case EmfPlusRecordTypeFillPolygon: return
"EmfPlusRecordTypeFillPolygon";
+ case EmfPlusRecordTypeDrawLines: return
"EmfPlusRecordTypeDrawLines";
+ case EmfPlusRecordTypeFillEllipse: return
"EmfPlusRecordTypeFillEllipse";
+ case EmfPlusRecordTypeDrawEllipse: return
"EmfPlusRecordTypeDrawEllipse";
+ case EmfPlusRecordTypeFillPie: return "EmfPlusRecordTypeFillPie";
+ case EmfPlusRecordTypeDrawPie: return "EmfPlusRecordTypeDrawPie";
+ case EmfPlusRecordTypeDrawArc: return "EmfPlusRecordTypeDrawArc";
+ case EmfPlusRecordTypeFillPath: return "EmfPlusRecordTypeFillPath";
+ case EmfPlusRecordTypeDrawPath: return "EmfPlusRecordTypeDrawPath";
+ case EmfPlusRecordTypeDrawBeziers: return
"EmfPlusRecordTypeDrawBeziers";
+ case EmfPlusRecordTypeDrawImage: return
"EmfPlusRecordTypeDrawImage";
+ case EmfPlusRecordTypeDrawImagePoints: return
"EmfPlusRecordTypeDrawImagePoints";
+ case EmfPlusRecordTypeDrawString: return
"EmfPlusRecordTypeDrawString";
+ case EmfPlusRecordTypeSetRenderingOrigin: return
"EmfPlusRecordTypeSetRenderingOrigin";
+ case EmfPlusRecordTypeSetAntiAliasMode: return
"EmfPlusRecordTypeSetAntiAliasMode";
+ case EmfPlusRecordTypeSetTextRenderingHint: return
"EmfPlusRecordTypeSetTextRenderingHint";
+ case EmfPlusRecordTypeSetInterpolationMode: return
"EmfPlusRecordTypeSetInterpolationMode";
+ case EmfPlusRecordTypeSetPixelOffsetMode: return
"EmfPlusRecordTypeSetPixelOffsetMode";
+ case EmfPlusRecordTypeSetCompositingQuality: return
"EmfPlusRecordTypeSetCompositingQuality";
+ case EmfPlusRecordTypeSave: return "EmfPlusRecordTypeSave";
+ case EmfPlusRecordTypeRestore: return "EmfPlusRecordTypeRestore";
+ case EmfPlusRecordTypeBeginContainerNoParams: return
"EmfPlusRecordTypeBeginContainerNoParams";
+ case EmfPlusRecordTypeEndContainer: return
"EmfPlusRecordTypeEndContainer";
+ case EmfPlusRecordTypeSetWorldTransform: return
"EmfPlusRecordTypeSetWorldTransform";
+ case EmfPlusRecordTypeResetWorldTransform: return
"EmfPlusRecordTypeResetWorldTransform";
+ case EmfPlusRecordTypeMultiplyWorldTransform: return
"EmfPlusRecordTypeMultiplyWorldTransform";
+ case EmfPlusRecordTypeTranslateWorldTransform: return
"EmfPlusRecordTypeTranslateWorldTransform";
+ case EmfPlusRecordTypeScaleWorldTransform: return
"EmfPlusRecordTypeScaleWorldTransform";
+ case EmfPlusRecordTypeSetPageTransform: return
"EmfPlusRecordTypeSetPageTransform";
+ case EmfPlusRecordTypeSetClipRect: return
"EmfPlusRecordTypeSetClipRect";
+ case EmfPlusRecordTypeSetClipPath: return
"EmfPlusRecordTypeSetClipPath";
+ case EmfPlusRecordTypeSetClipRegion: return
"EmfPlusRecordTypeSetClipRegion";
+ case EmfPlusRecordTypeDrawDriverString: return
"EmfPlusRecordTypeDrawDriverString";
}
return "";
}
@@ -126,82 +128,83 @@ namespace emfplushelper
switch (flags & 0x7f00)
{
- case EmfPlusObjectTypeBrush:
- {
- EMFPBrush *brush;
- aObjects[index].reset(brush = new EMFPBrush());
- brush->Read(rObjectStream, *this);
- break;
- }
- case EmfPlusObjectTypePen:
- {
- EMFPPen *pen;
- aObjects[index].reset(pen = new EMFPPen());
- pen->Read(rObjectStream, *this);
- break;
- }
- case EmfPlusObjectTypePath:
- {
- sal_uInt32 header, pathFlags;
- sal_Int32 points;
-
-
rObjectStream.ReadUInt32(header).ReadInt32(points).ReadUInt32(pathFlags);
- SAL_INFO("cppcanvas.emf", "EMF+\tpath");
- SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header
<< " points: " << std::dec << points << " additional flags: 0x" << std::hex <<
pathFlags << std::dec);
- EMFPPath *path;
- aObjects[index].reset(path = new EMFPPath(points));
- path->Read(rObjectStream, pathFlags, *this);
- break;
- }
- case EmfPlusObjectTypeRegion:
- {
- EMFPRegion *region;
- aObjects[index].reset(region = new EMFPRegion());
- region->Read(rObjectStream);
- break;
- }
- case EmfPlusObjectTypeImage:
- {
- EMFPImage *image;
- aObjects[index].reset(image = new EMFPImage);
- image->type = 0;
- image->width = 0;
- image->height = 0;
- image->stride = 0;
- image->pixelFormat = 0;
- image->Read(rObjectStream, dataSize, bUseWholeStream);
- break;
- }
- case EmfPlusObjectTypeFont:
- {
- EMFPFont *font;
- aObjects[index].reset(font = new EMFPFont);
- font->emSize = 0;
- font->sizeUnit = 0;
- font->fontFlags = 0;
- font->Read(rObjectStream);
- break;
- }
- case EmfPlusObjectTypeStringFormat:
- {
- EMFPStringFormat *stringFormat;
- aObjects[index].reset(stringFormat = new EMFPStringFormat());
- stringFormat->Read(rObjectStream);
- break;
- }
- case EmfPlusObjectTypeImageAttributes:
- {
- SAL_INFO("cppcanvas.emf", "EMF+\t Object type 'image attributes'
not yet implemented");
- break;
- }
- case EmfPlusObjectTypeCustomLineCap:
- {
- SAL_INFO("cppcanvas.emf", "EMF+\t Object type 'custom line cap'
not yet implemented");
- break;
- }
- default:
- SAL_INFO("cppcanvas.emf", "EMF+\tObject unhandled flags: 0x" <<
std::hex << (flags & 0xff00) << std::dec);
- break;
+ case EmfPlusObjectTypeBrush:
+ {
+ EMFPBrush *brush;
+ aObjects[index].reset(brush = new EMFPBrush());
+ brush->Read(rObjectStream, *this);
+ break;
+ }
+ case EmfPlusObjectTypePen:
+ {
+ EMFPPen *pen;
+ aObjects[index].reset(pen = new EMFPPen());
+ pen->Read(rObjectStream, *this);
+ break;
+ }
+ case EmfPlusObjectTypePath:
+ {
+ sal_uInt32 header, pathFlags;
+ sal_Int32 points;
+
+
rObjectStream.ReadUInt32(header).ReadInt32(points).ReadUInt32(pathFlags);
+ SAL_INFO("cppcanvas.emf", "EMF+\tpath");
+ SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex <<
header << " points: " << std::dec << points << " additional flags: 0x" <<
std::hex << pathFlags << std::dec);
+ EMFPPath *path;
+ aObjects[index].reset(path = new EMFPPath(points));
+ path->Read(rObjectStream, pathFlags, *this);
+ break;
+ }
+ case EmfPlusObjectTypeRegion:
+ {
+ EMFPRegion *region;
+ aObjects[index].reset(region = new EMFPRegion());
+ region->Read(rObjectStream);
+ break;
+ }
+ case EmfPlusObjectTypeImage:
+ {
+ EMFPImage *image;
+ aObjects[index].reset(image = new EMFPImage);
+ image->type = 0;
+ image->width = 0;
+ image->height = 0;
+ image->stride = 0;
+ image->pixelFormat = 0;
+ image->Read(rObjectStream, dataSize, bUseWholeStream);
+ break;
+ }
+ case EmfPlusObjectTypeFont:
+ {
+ EMFPFont *font;
+ aObjects[index].reset(font = new EMFPFont);
+ font->emSize = 0;
+ font->sizeUnit = 0;
+ font->fontFlags = 0;
+ font->Read(rObjectStream);
+ break;
+ }
+ case EmfPlusObjectTypeStringFormat:
+ {
+ EMFPStringFormat *stringFormat;
+ aObjects[index].reset(stringFormat = new EMFPStringFormat());
+ stringFormat->Read(rObjectStream);
+ break;
+ }
+ case EmfPlusObjectTypeImageAttributes:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\t Object type 'image
attributes' not yet implemented");
+ break;
+ }
+ case EmfPlusObjectTypeCustomLineCap:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\t Object type 'custom line
cap' not yet implemented");
+ break;
+ }
+ default:
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+\tObject unhandled flags: 0x"
<< std::hex << (flags & 0xff00) << std::dec);
+ }
}
}
@@ -324,6 +327,34 @@ namespace emfplushelper
return ::basegfx::B2DSize(w, h);
}
+ void EmfPlusHelperData::EMFPPlusDrawPolygon(const
::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex)
+ {
+ const EMFPPen* pen = static_cast<EMFPPen*>(aObjects[penIndex &
0xff].get());
+ SAL_WARN_IF(!pen, "cppcanvas.emf", "emf+ missing pen");
+
+ if (pen && polygon.count())
+ {
+ mrTargetHolders.Current().append(
+ new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D(
+ polygon,
+ pen->GetColor().getBColor()));
+ }
+ }
+
+ void EmfPlusHelperData::EMFPPlusFillPolygon(const
::basegfx::B2DPolyPolygon& polygon, bool isColor, sal_uInt32 brushIndexOrColor)
+ {
+ if (polygon.count())
+ {
+ if (isColor)
+ {
+ mrTargetHolders.Current().append(
+ new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ polygon,
+ ::Color(0xff - (brushIndexOrColor >> 24),
(brushIndexOrColor >> 16) & 0xff, (brushIndexOrColor >> 8) & 0xff,
brushIndexOrColor & 0xff).getBColor()));
+ }
+ }
+ }
+
EmfPlusHelperData::EmfPlusHelperData(
SvMemoryStream& rMS,
wmfemfhelper::TargetHolders& rTargetHolders,
@@ -431,804 +462,834 @@ namespace emfplushelper
{
switch (type)
{
- case EmfPlusRecordTypeHeader:
- {
- sal_uInt32 header, version;
-
-
rMS.ReadUInt32(header).ReadUInt32(version).ReadInt32(nHDPI).ReadInt32(nVDPI);
- SAL_INFO("cppcanvas.emf", "EMF+ Header");
- SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex
<< header << " version: " << std::dec << version << " horizontal DPI: " <<
nHDPI << " vertical DPI: " << nVDPI << " dual: " << (flags & 1));
- break;
- }
- case EmfPlusRecordTypeEndOfFile:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ EndOfFile");
- break;
- }
- case EmfPlusRecordTypeGetDC:
- {
- SAL_INFO("cppcanvas.emf", "EMF+ GetDC");
- SAL_INFO("cppcanvas.emf", "EMF+\talready used in svtools
wmf/emf filter parser");
- break;
- }
- case EmfPlusRecordTypeObject:
- {
- processObjectRecord(rMS, flags, dataSize);
- break;
- }
- case EmfPlusRecordTypeFillPie:
- case EmfPlusRecordTypeDrawPie:
- case EmfPlusRecordTypeDrawArc:
- {
- float startAngle, sweepAngle;
-
- // Silent MSVC warning C4701: potentially uninitialized
local variable 'brushIndexOrColor' used
- sal_uInt32 brushIndexOrColor = 999;
-
- if (type == EmfPlusRecordTypeFillPie)
+ case EmfPlusRecordTypeHeader:
{
- rMS.ReadUInt32(brushIndexOrColor);
- SAL_INFO("cppcanvas.emf", "EMF+ FillPie colorOrIndex:
" << brushIndexOrColor);
+ sal_uInt32 header, version;
+
+
rMS.ReadUInt32(header).ReadUInt32(version).ReadInt32(nHDPI).ReadInt32(nVDPI);
+ SAL_INFO("cppcanvas.emf", "EMF+ Header");
+ SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" <<
std::hex << header << " version: " << std::dec << version << " horizontal DPI:
" << nHDPI << " vertical DPI: " << nVDPI << " dual: " << (flags & 1));
+ break;
}
- else if (type == EmfPlusRecordTypeDrawPie)
+ case EmfPlusRecordTypeEndOfFile:
{
- SAL_INFO("cppcanvas.emf", "EMF+ DrawPie");
+ SAL_INFO("cppcanvas.emf", "EMF+ EndOfFile");
+ break;
}
- else
+ case EmfPlusRecordTypeGetDC:
{
- SAL_INFO("cppcanvas.emf", "EMF+ DrawArc");
+ SAL_INFO("cppcanvas.emf", "EMF+ GetDC");
+ SAL_INFO("cppcanvas.emf", "EMF+\talready used in
svtools wmf/emf filter parser");
+ break;
}
-
- rMS.ReadFloat(startAngle).ReadFloat(sweepAngle);
- float dx, dy, dw, dh;
- ReadRectangle(rMS, dx, dy, dw, dh, bool(flags & 0x4000));
- SAL_INFO("cppcanvas.emf", "EMF+\t RectData: " << dx << ","
<< dy << " " << dw << "x" << dh);
- startAngle = 2 * M_PI*startAngle / 360;
- sweepAngle = 2 * M_PI*sweepAngle / 360;
- ::basegfx::B2DPoint mappedCenter(Map(dx + dw / 2, dy + dh
/ 2));
- ::basegfx::B2DSize mappedSize(MapSize(dw / 2, dh / 2));
- float endAngle = startAngle + sweepAngle;
- startAngle = fmodf(startAngle, static_cast<float>(M_PI *
2));
-
- if (startAngle < 0.0)
+ case EmfPlusRecordTypeObject:
{
- startAngle += static_cast<float>(M_PI * 2.0);
+ processObjectRecord(rMS, flags, dataSize);
+ break;
}
-
- endAngle = fmodf(endAngle, static_cast<float>(M_PI * 2.0));
-
- if (endAngle < 0.0)
+ case EmfPlusRecordTypeFillPie:
+ case EmfPlusRecordTypeDrawPie:
+ case EmfPlusRecordTypeDrawArc:
{
- endAngle += static_cast<float>(M_PI * 2.0);
- }
+ float startAngle, sweepAngle;
- if (sweepAngle < 0)
- {
- std::swap(endAngle, startAngle);
- }
+ // Silent MSVC warning C4701: potentially
uninitialized local variable 'brushIndexOrColor' used
+ sal_uInt32 brushIndexOrColor = 999;
- SAL_INFO("cppcanvas.emf", "EMF+\t adjusted angles: start "
<<
- (360.0*startAngle / M_PI) << ", end: " <<
(360.0*endAngle / M_PI) <<
- " startAngle: " << startAngle << " sweepAngle: " <<
sweepAngle);
+ if (type == EmfPlusRecordTypeFillPie)
+ {
+ rMS.ReadUInt32(brushIndexOrColor);
+ SAL_INFO("cppcanvas.emf", "EMF+ FillPie
colorOrIndex: " << brushIndexOrColor);
+ }
+ else if (type == EmfPlusRecordTypeDrawPie)
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawPie");
+ }
+ else
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawArc");
+ }
- ::basegfx::B2DPolygon polygon =
basegfx::tools::createPolygonFromEllipseSegment(
- mappedCenter, mappedSize.getX(), mappedSize.getY(),
startAngle, endAngle);
+ rMS.ReadFloat(startAngle).ReadFloat(sweepAngle);
+ float dx, dy, dw, dh;
+ ReadRectangle(rMS, dx, dy, dw, dh, bool(flags &
0x4000));
+ SAL_INFO("cppcanvas.emf", "EMF+\t RectData: " << dx <<
"," << dy << " " << dw << "x" << dh);
+ startAngle = 2 * M_PI*startAngle / 360;
+ sweepAngle = 2 * M_PI*sweepAngle / 360;
+ ::basegfx::B2DPoint mappedCenter(Map(dx + dw / 2, dy +
dh / 2));
+ ::basegfx::B2DSize mappedSize(MapSize(dw / 2, dh / 2));
+ float endAngle = startAngle + sweepAngle;
+ startAngle = fmodf(startAngle, static_cast<float>(M_PI
* 2));
+
+ if (startAngle < 0.0)
+ {
+ startAngle += static_cast<float>(M_PI * 2.0);
+ }
- if (type != EmfPlusRecordTypeDrawArc)
- {
- polygon.append(mappedCenter);
- polygon.setClosed(true);
- }
+ endAngle = fmodf(endAngle, static_cast<float>(M_PI *
2.0));
- ::basegfx::B2DPolyPolygon polyPolygon(polygon);
-// if (type == EmfPlusRecordTypeFillPie)
-// EMFPPlusFillPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, flags & 0x8000,
brushIndexOrColor);
-// else
-// EMFPPlusDrawPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, flags & 0xff);
- }
- break;
- case EmfPlusRecordTypeFillPath:
- {
- sal_uInt32 index = flags & 0xff;
- sal_uInt32 brushIndexOrColor;
- rMS.ReadUInt32(brushIndexOrColor);
- SAL_INFO("cppcanvas.emf", "EMF+ FillPath slot: " << index);
+ if (endAngle < 0.0)
+ {
+ endAngle += static_cast<float>(M_PI * 2.0);
+ }
-//
EMFPPlusFillPolygon(static_cast<EMFPPath*>(aObjects[index])->GetPolygon(*this),
rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
- }
- break;
- case EmfPlusRecordTypeDrawEllipse:
- case EmfPlusRecordTypeFillEllipse:
- {
- // Intentionally very bogus initial value to avoid MSVC
complaining about potentially uninitialized local
- // variable. As long as the code stays as intended, this
variable will be assigned a (real) value in the case
- // when it is later used.
- sal_uInt32 brushIndexOrColor = 1234567;
+ if (sweepAngle < 0)
+ {
+ std::swap(endAngle, startAngle);
+ }
- if (type == EmfPlusRecordTypeFillEllipse)
- {
- rMS.ReadUInt32(brushIndexOrColor);
- }
+ SAL_INFO("cppcanvas.emf", "EMF+\t adjusted angles:
start " <<
+ (360.0*startAngle / M_PI) << ", end: " <<
(360.0*endAngle / M_PI) <<
+ " startAngle: " << startAngle << " sweepAngle: "
<< sweepAngle);
- SAL_INFO("cppcanvas.emf", "EMF+ " << (type ==
EmfPlusRecordTypeFillEllipse ? "Fill" : "Draw") << "Ellipse slot: " << (flags &
0xff));
- float dx, dy, dw, dh;
- ReadRectangle(rMS, dx, dy, dw, dh, bool(flags & 0x4000));
- SAL_INFO("cppcanvas.emf", "EMF+ RectData: " << dx << ","
<< dy << " " << dw << "x" << dh);
- ::basegfx::B2DPoint mappedCenter(Map(dx + dw / 2, dy + dh
/ 2));
- ::basegfx::B2DSize mappedSize(MapSize(dw / 2, dh / 2));
- ::basegfx::B2DPolyPolygon polyPolygon(
- ::basegfx::B2DPolygon(
-
::basegfx::tools::createPolygonFromEllipse(mappedCenter, mappedSize.getX(),
mappedSize.getY())));
-
-// if (type == EmfPlusRecordTypeFillEllipse)
-// EMFPPlusFillPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, flags & 0x8000,
brushIndexOrColor);
-// else
-// EMFPPlusDrawPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, flags & 0xff);
- }
- break;
- case EmfPlusRecordTypeFillRects:
- case EmfPlusRecordTypeDrawRects:
- {
- // Silent MSVC warning C4701: potentially uninitialized
local variable 'brushIndexOrColor' used
- sal_uInt32 brushIndexOrColor = 999;
- sal_Int32 rectangles;
- bool isColor = (flags & 0x8000);
- ::basegfx::B2DPolygon polygon;
+ ::basegfx::B2DPolygon polygon =
basegfx::tools::createPolygonFromEllipseSegment(
+ mappedCenter, mappedSize.getX(),
mappedSize.getY(), startAngle, endAngle);
+
+ if (type != EmfPlusRecordTypeDrawArc)
+ {
+ polygon.append(mappedCenter);
+ polygon.setClosed(true);
+ }
- if (EmfPlusRecordTypeFillRects == type)
+ ::basegfx::B2DPolyPolygon polyPolygon(polygon);
+ if (type == EmfPlusRecordTypeFillPie)
+ {
+ EMFPPlusFillPolygon(polyPolygon, flags & 0x8000,
brushIndexOrColor);
+ // EMFPPlusFillPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, flags &
0x8000, brushIndexOrColor);
+ }
+ else
+ {
+ EMFPPlusDrawPolygon(polyPolygon, flags & 0xff);
+ // EMFPPlusDrawPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, flags &
0xff);
+ }
+ }
+ break;
+ case EmfPlusRecordTypeFillPath:
{
- SAL_INFO("cppcanvas.emf", "EMF+ FillRects");
+ sal_uInt32 index = flags & 0xff;
+ sal_uInt32 brushIndexOrColor;
rMS.ReadUInt32(brushIndexOrColor);
- SAL_INFO("cppcanvas.emf", "EMF+\t" << (isColor ?
"color" : "brush index") << ": 0x" << std::hex << brushIndexOrColor <<
std::dec);
+ SAL_INFO("cppcanvas.emf", "EMF+ FillPath slot: " <<
index);
+
+
EMFPPlusFillPolygon(static_cast<EMFPPath*>(aObjects[index].get())->GetPolygon(*this),
flags & 0x8000, brushIndexOrColor);
+ //
EMFPPlusFillPolygon(static_cast<EMFPPath*>(aObjects[index])->GetPolygon(*this),
rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
}
- else
+ break;
+ case EmfPlusRecordTypeDrawEllipse:
+ case EmfPlusRecordTypeFillEllipse:
{
- SAL_INFO("cppcanvas.emf", "EMF+ DrawRects");
- }
+ // Intentionally very bogus initial value to avoid
MSVC complaining about potentially uninitialized local
+ // variable. As long as the code stays as intended,
this variable will be assigned a (real) value in the case
+ // when it is later used.
+ sal_uInt32 brushIndexOrColor = 1234567;
- rMS.ReadInt32(rectangles);
+ if (type == EmfPlusRecordTypeFillEllipse)
+ {
+ rMS.ReadUInt32(brushIndexOrColor);
+ }
- for (int i = 0; i < rectangles; i++)
+ SAL_INFO("cppcanvas.emf", "EMF+ " << (type ==
EmfPlusRecordTypeFillEllipse ? "Fill" : "Draw") << "Ellipse slot: " << (flags &
0xff));
+ float dx, dy, dw, dh;
+ ReadRectangle(rMS, dx, dy, dw, dh, bool(flags &
0x4000));
+ SAL_INFO("cppcanvas.emf", "EMF+ RectData: " << dx <<
"," << dy << " " << dw << "x" << dh);
+ ::basegfx::B2DPoint mappedCenter(Map(dx + dw / 2, dy +
dh / 2));
+ ::basegfx::B2DSize mappedSize(MapSize(dw / 2, dh / 2));
+ ::basegfx::B2DPolyPolygon polyPolygon(
+ ::basegfx::B2DPolygon(
+
::basegfx::tools::createPolygonFromEllipse(mappedCenter, mappedSize.getX(),
mappedSize.getY())));
+
+ if (type == EmfPlusRecordTypeFillEllipse)
+ {
+ EMFPPlusFillPolygon(polyPolygon, flags & 0x8000,
brushIndexOrColor);
+ // EMFPPlusFillPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, flags &
0x8000, brushIndexOrColor);
+ }
+ else
+ {
+ EMFPPlusDrawPolygon(polyPolygon, flags & 0xff);
+ // EMFPPlusDrawPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, flags &
0xff);
+ }
+ }
+ break;
+ case EmfPlusRecordTypeFillRects:
+ case EmfPlusRecordTypeDrawRects:
{
- float x, y, width, height;
- ReadRectangle(rMS, x, y, width, height, bool(flags &
0x4000));
+ // Silent MSVC warning C4701: potentially
uninitialized local variable 'brushIndexOrColor' used
+ sal_uInt32 brushIndexOrColor = 999;
+ sal_Int32 rectangles;
+ bool isColor = (flags & 0x8000);
+ ::basegfx::B2DPolygon polygon;
- polygon.append(Map(x, y));
- polygon.append(Map(x + width, y));
- polygon.append(Map(x + width, y + height));
- polygon.append(Map(x, y + height));
- polygon.append(Map(x, y));
-
- SAL_INFO("cppcanvas.emf", "EMF+\trectangle: " << x <<
", " << width << "x" << height);
+ if (EmfPlusRecordTypeFillRects == type)
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ FillRects");
+ rMS.ReadUInt32(brushIndexOrColor);
+ SAL_INFO("cppcanvas.emf", "EMF+\t" << (isColor ?
"color" : "brush index") << ": 0x" << std::hex << brushIndexOrColor <<
std::dec);
+ }
+ else
+ {
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawRects");
+ }
- ::basegfx::B2DPolyPolygon polyPolygon(polygon);
-// if (type == EmfPlusRecordTypeFillRects)
-// EMFPPlusFillPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, isColor,
brushIndexOrColor);
-// else
-// EMFPPlusDrawPolygon(polyPolygon,
-// rFactoryParms, rState, rCanvas, flags &
0xff);
- }
- break;
- }
- case EmfPlusRecordTypeFillPolygon:
- {
- sal_uInt8 index = flags & 0xff;
- sal_uInt32 brushIndexOrColor;
- sal_Int32 points;
+ rMS.ReadInt32(rectangles);
- rMS.ReadUInt32(brushIndexOrColor);
- rMS.ReadInt32(points);
- SAL_INFO("cppcanvas.emf", "EMF+ FillPolygon in slot: " <<
+index << " points: " << points);
- SAL_INFO("cppcanvas.emf", "EMF+\t: " << ((flags & 0x8000)
? "color" : "brush index") << " 0x" << std::hex << brushIndexOrColor <<
std::dec);
+ for (int i = 0; i < rectangles; i++)
+ {
+ float x, y, width, height;
+ ReadRectangle(rMS, x, y, width, height, bool(flags
& 0x4000));
- EMFPPath path(points, true);
- path.Read(rMS, flags, *this);
+ polygon.append(Map(x, y));
+ polygon.append(Map(x + width, y));
+ polygon.append(Map(x + width, y + height));
+ polygon.append(Map(x, y + height));
+ polygon.append(Map(x, y));
-// EMFPPlusFillPolygon(path.GetPolygon(*this),
rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
+ SAL_INFO("cppcanvas.emf", "EMF+\trectangle: " << x
<< ", " << width << "x" << height);
- break;
- }
- case EmfPlusRecordTypeDrawLines:
- {
- sal_uInt32 points;
- rMS.ReadUInt32(points);
- SAL_INFO("cppcanvas.emf", "EMF+ DrawLines in slot: " <<
(flags & 0xff) << " points: " << points);
- EMFPPath path(points, true);
- path.Read(rMS, flags, *this);
+ ::basegfx::B2DPolyPolygon polyPolygon(polygon);
+ if (type == EmfPlusRecordTypeFillRects)
+ {
+ EMFPPlusFillPolygon(polyPolygon, isColor,
brushIndexOrColor);
+ // EMFPPlusFillPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, isColor,
brushIndexOrColor);
+ }
+ else
+ {
+ EMFPPlusDrawPolygon(polyPolygon, flags & 0xff);
+ // EMFPPlusDrawPolygon(polyPolygon,
+ // rFactoryParms, rState, rCanvas, flags &
0xff);
+ }
+ }
+ break;
+ }
+ case EmfPlusRecordTypeFillPolygon:
+ {
+ sal_uInt8 index = flags & 0xff;
+ sal_uInt32 brushIndexOrColor;
+ sal_Int32 points;
- // 0x2000 bit indicates whether to draw an extra line
between the last point
- // and the first point, to close the shape.
-// EMFPPlusDrawPolygon(path.GetPolygon(*this, true, (flags
& 0x2000)), rFactoryParms, rState, rCanvas, flags);
+ rMS.ReadUInt32(brushIndexOrColor);
+ rMS.ReadInt32(points);
+ SAL_INFO("cppcanvas.emf", "EMF+ FillPolygon in slot: "
<< +index << " points: " << points);
+ SAL_INFO("cppcanvas.emf", "EMF+\t: " << ((flags &
0x8000) ? "color" : "brush index") << " 0x" << std::hex << brushIndexOrColor <<
std::dec);
- break;
- }
- case EmfPlusRecordTypeDrawPath:
- {
- sal_uInt32 penIndex;
- rMS.ReadUInt32(penIndex);
- SAL_INFO("cppcanvas.emf", "EMF+ DrawPath");
- SAL_INFO("cppcanvas.emf", "EMF+\tpen: " << penIndex);
- EMFPPath* path = static_cast<EMFPPath*>(aObjects[flags &
0xff].get());
- SAL_WARN_IF(!path, "cppcanvas.emf",
"EmfPlusRecordTypeDrawPath missing path");
+ EMFPPath path(points, true);
+ path.Read(rMS, flags, *this);
-// EMFPPlusDrawPolygon(path->GetPolygon(*this),
rFactoryParms, rState, rCanvas, penIndex);
+ EMFPPlusFillPolygon(path.GetPolygon(*this), flags &
0x8000, brushIndexOrColor);
+ // EMFPPlusFillPolygon(path.GetPolygon(*this),
rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
- break;
- }
- case EmfPlusRecordTypeDrawBeziers:
- {
- sal_uInt32 aCount;
- float x1, y1, x2, y2, x3, y3, x4, y4;
- ::basegfx::B2DPoint aStartPoint, aControlPointA,
aControlPointB, aEndPoint;
- ::basegfx::B2DPolygon aPolygon;
- rMS.ReadUInt32(aCount);
- SAL_INFO("cppcanvas.emf", "EMF+ DrawBeziers slot: " <<
(flags & 0xff) << "Number of points: " << aCount);
- SAL_WARN_IF((aCount - 1) % 3 != 0, "cppcanvas.emf",
"EMF+\t Bezier Draw not support number of points other than 4, 7, 10, 13,
16...");
-
- if (aCount < 4)
- {
- SAL_WARN("cppcanvas.emf", "EMF+\t Bezier Draw does not
support less than 4 points. Number of points: " << aCount);
break;
}
+ case EmfPlusRecordTypeDrawLines:
+ {
+ sal_uInt32 points;
+ rMS.ReadUInt32(points);
+ SAL_INFO("cppcanvas.emf", "EMF+ DrawLines in slot: "
<< (flags & 0xff) << " points: " << points);
+ EMFPPath path(points, true);
+ path.Read(rMS, flags, *this);
- ReadPoint(rMS, x1, y1, flags);
- // We need to add first starting point
- aStartPoint = Map(x1, y1);
- aPolygon.append(aStartPoint);
+ // 0x2000 bit indicates whether to draw an extra line
between the last point
+ // and the first point, to close the shape.
+ EMFPPlusDrawPolygon(path.GetPolygon(*this, true,
(flags & 0x2000)), flags);
... etc. - the rest is truncated
_______________________________________________
Libreoffice-commits mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits