summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/source/filter/wmf/enhwmf.cxx14
-rw-r--r--vcl/source/filter/wmf/winmtf.cxx123
-rw-r--r--vcl/source/filter/wmf/winmtf.hxx19
3 files changed, 127 insertions, 29 deletions
diff --git a/vcl/source/filter/wmf/enhwmf.cxx b/vcl/source/filter/wmf/enhwmf.cxx
index f8b98845be4e..541d68dbe48c 100644
--- a/vcl/source/filter/wmf/enhwmf.cxx
+++ b/vcl/source/filter/wmf/enhwmf.cxx
@@ -485,8 +485,8 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
EMFP_DEBUG(printf ("\t\tunknown id: 0x%x\n",(unsigned int) id));
}
}
- } else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
-
+ }
+ else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
switch( nRecType )
{
case EMR_POLYBEZIERTO :
@@ -518,14 +518,14 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
case EMR_SETWINDOWEXTEX :
{ // #75383#
*pWMF >> nW >> nH;
- pOut->SetWinExt( Size( nW, nH ) );
+ pOut->SetWinExt( Size( nW, nH ), true);
}
break;
case EMR_SETWINDOWORGEX :
{
*pWMF >> nX32 >> nY32;
- pOut->SetWinOrg( Point( nX32, nY32 ) );
+ pOut->SetWinOrg( Point( nX32, nY32 ), true);
}
break;
@@ -917,7 +917,7 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
PolyPolygon aPolyPoly;
if ( cbRgnData )
ImplReadRegion( aPolyPoly, *pWMF, nRecSize );
- pOut->SetClipPath( aPolyPoly, iMode, sal_False );
+ pOut->SetClipPath( aPolyPoly, iMode, sal_True );
}
break;
@@ -1352,7 +1352,7 @@ sal_Bool EnhWMFReader::ReadHeader()
return sal_False;
// bound size
- Rectangle rclBounds; // rectangle in logical units 1/100th mm
+ Rectangle rclBounds; // rectangle in logical units
*pWMF >> nLeft >> nTop >> nRight >> nBottom;
rclBounds.Left() = nLeft;
rclBounds.Top() = nTop;
@@ -1360,7 +1360,7 @@ sal_Bool EnhWMFReader::ReadHeader()
rclBounds.Bottom() = nBottom;
// picture frame size
- Rectangle rclFrame; // rectangle in device units
+ Rectangle rclFrame; // rectangle in device units 1/100th mm
*pWMF >> nLeft >> nTop >> nRight >> nBottom;
rclFrame.Left() = nLeft;
rclFrame.Top() = nTop;
diff --git a/vcl/source/filter/wmf/winmtf.cxx b/vcl/source/filter/wmf/winmtf.cxx
index 0adca65d678b..fcfd07f4911b 100644
--- a/vcl/source/filter/wmf/winmtf.cxx
+++ b/vcl/source/filter/wmf/winmtf.cxx
@@ -350,6 +350,20 @@ Color WinMtf::ReadColor()
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
+Point WinMtfOutput::ImplScale( const Point& rPt)//Hack to set varying defaults for incompletely defined files.
+{
+ if (mbIsMapDevSet && mbIsMapWinSet)
+ {
+ return Point((rPt.X())*mnWinExtX/mnDevWidth-mrclFrame.Left(),(rPt.Y())*mnWinExtY/mnDevHeight-mrclFrame.Top());
+ }
+ else
+ {
+ return Point((rPt.X())*UNDOCUMENTED_WIN_RCL_RELATION-mrclFrame.Left(),(rPt.Y())*UNDOCUMENTED_WIN_RCL_RELATION-mrclFrame.Top());
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
Point WinMtfOutput::ImplMap( const Point& rPt )
{
if ( mnWinExtX && mnWinExtY )
@@ -368,8 +382,8 @@ Point WinMtfOutput::ImplMap( const Point& rPt )
fX2 -= mnWinOrgX;
fY2 -= mnWinOrgY;
if( mnDevWidth != 1 || mnDevHeight != 1 ) {
- fX2 *= 2540.0/mnUnitsPerInch;
- fY2 *= 2540.0/mnUnitsPerInch;
+ fX2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*1000/mnUnitsPerInch;
+ fY2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*1000/mnUnitsPerInch;
}
fX2 += mnDevOrgX;
fY2 += mnDevOrgY;
@@ -381,8 +395,8 @@ Point WinMtfOutput::ImplMap( const Point& rPt )
{
fX2 -= mnWinOrgX;
fY2 = mnWinOrgY-fY2;
- fX2 *= 25.40;
- fY2 *= 25.40;
+ fX2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*10;
+ fY2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*10;
fX2 += mnDevOrgX;
fY2 += mnDevOrgY;
}
@@ -391,8 +405,18 @@ Point WinMtfOutput::ImplMap( const Point& rPt )
{
fX2 -= mnWinOrgX;
fY2 = mnWinOrgY-fY2;
- fX2 *= 2.540;
- fY2 *= 2.540;
+ fX2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH;
+ fY2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH;
+ fX2 += mnDevOrgX;
+ fY2 += mnDevOrgY;
+ }
+ break;
+ case MM_TWIPS:
+ {
+ fX2 -= mnWinOrgX;
+ fY2 = mnWinOrgY-fY2;
+ fX2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH/MILLIINCH_PER_TWIPS;
+ fY2 *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH/MILLIINCH_PER_TWIPS;
fX2 += mnDevOrgX;
fY2 += mnDevOrgY;
}
@@ -407,7 +431,7 @@ Point WinMtfOutput::ImplMap( const Point& rPt )
fY2 += mnDevOrgY;
}
break;
- case MM_HIMETRIC :
+ case MM_HIMETRIC : //in hundredth of a millimeter
{
fX2 -= mnWinOrgX;
fY2 = mnWinOrgY-fY2;
@@ -454,8 +478,8 @@ Size WinMtfOutput::ImplMap( const Size& rSz )
{
case MM_TEXT:
if( mnDevWidth != 1 && mnDevHeight != 1 ) {
- fWidth *= 2540.0/mnUnitsPerInch;
- fHeight*= 2540.0/mnUnitsPerInch;
+ fWidth *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*1000/mnUnitsPerInch;
+ fHeight*= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*1000/mnUnitsPerInch;
} else {
fWidth *= (double)mnMillX * 100 / (double)mnPixX;
fHeight *= (double)mnMillY * 100 / (double)mnPixY;
@@ -463,14 +487,14 @@ Size WinMtfOutput::ImplMap( const Size& rSz )
break;
case MM_LOENGLISH :
{
- fWidth *= 25.40;
- fHeight*=-25.40;
+ fWidth *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH*10;
+ fHeight*=-HUNDREDTH_MILLIMETERS_PER_MILLIINCH*10;
}
break;
case MM_HIENGLISH :
{
- fWidth *= 2.540;
- fHeight*=-2.540;
+ fWidth *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH;
+ fHeight*=-HUNDREDTH_MILLIMETERS_PER_MILLIINCH;
}
break;
case MM_LOMETRIC :
@@ -479,11 +503,17 @@ Size WinMtfOutput::ImplMap( const Size& rSz )
fHeight*=-10;
}
break;
- case MM_HIMETRIC :
+ case MM_HIMETRIC : //in hundredth of millimeters
{
fHeight *= -1;
}
break;
+ case MM_TWIPS:
+ {
+ fWidth *= HUNDREDTH_MILLIMETERS_PER_MILLIINCH/MILLIINCH_PER_TWIPS;
+ fHeight*=-HUNDREDTH_MILLIMETERS_PER_MILLIINCH/MILLIINCH_PER_TWIPS;
+ }
+ break;
default :
{
fWidth /= mnWinExtX;
@@ -541,6 +571,27 @@ Polygon& WinMtfOutput::ImplMap( Polygon& rPolygon )
//-----------------------------------------------------------------------------------
+Polygon& WinMtfOutput::ImplScale( Polygon& rPolygon )
+{
+ sal_uInt16 nPoints = rPolygon.GetSize();
+ for ( sal_uInt16 i = 0; i < nPoints; i++ )
+ {
+ rPolygon[ i ] = ImplScale( rPolygon[ i ] );
+ }
+ return rPolygon;
+}
+
+//-----------------------------------------------------------------------------------
+
+PolyPolygon& WinMtfOutput::ImplScale( PolyPolygon& rPolyPolygon )
+{
+ sal_uInt16 nPolys = rPolyPolygon.Count();
+ for ( sal_uInt16 i = 0; i < nPolys; ImplScale( rPolyPolygon[ i++ ] ) ) ;
+ return rPolyPolygon;
+}
+
+//-----------------------------------------------------------------------------------
+
PolyPolygon& WinMtfOutput::ImplMap( PolyPolygon& rPolyPolygon )
{
sal_uInt16 nPolys = rPolyPolygon.Count();
@@ -836,6 +887,10 @@ void WinMtfOutput::DeleteObject( sal_Int32 nIndex )
void WinMtfOutput::IntersectClipRect( const Rectangle& rRect )
{
mbClipNeedsUpdate=true;
+ if ((rRect.Left()-rRect.Right()==0) && (rRect.Top()-rRect.Bottom()==0))
+ {
+ return; // empty rectangles cause trouble
+ }
aClipPath.intersectClipRect( ImplMap( rRect ) );
}
@@ -859,7 +914,10 @@ void WinMtfOutput::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClip
{
mbClipNeedsUpdate=true;
if ( bIsMapped )
- aClipPath.setClipPath( rPolyPolygon, nClippingMode );
+ {
+ PolyPolygon aPP( rPolyPolygon );
+ aClipPath.setClipPath( ImplScale( aPP ), nClippingMode );
+ }
else
{
PolyPolygon aPP( rPolyPolygon );
@@ -904,6 +962,8 @@ WinMtfOutput::WinMtfOutput( GDIMetaFile& rGDIMetaFile ) :
mnMillY ( 1 ),
mpGDIMetaFile ( &rGDIMetaFile )
{
+ mbIsMapWinSet = sal_False;
+ mbIsMapDevSet = sal_False;
mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) ); // The original clipregion has to be on top
// of the stack so it can always be restored
// this is necessary to be able to support
@@ -1114,7 +1174,6 @@ void WinMtfOutput::MoveTo( const Point& rPoint, sal_Bool bRecordPath )
void WinMtfOutput::LineTo( const Point& rPoint, sal_Bool bRecordPath )
{
UpdateClipRegion();
-
Point aDest( ImplMap( rPoint ) );
if ( bRecordPath )
aPathObj.AddPoint( aDest );
@@ -1894,7 +1953,7 @@ void WinMtfOutput::SetDevOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
//-----------------------------------------------------------------------------------
-void WinMtfOutput::SetDevExt( const Size& rSize )
+void WinMtfOutput::SetDevExt( const Size& rSize ,sal_Bool regular)
{
if ( rSize.Width() && rSize.Height() )
{
@@ -1907,6 +1966,10 @@ void WinMtfOutput::SetDevExt( const Size& rSize )
mnDevHeight = rSize.Height();
}
}
+ if (regular)
+ {
+ mbIsMapDevSet=sal_True;
+ }
}
}
@@ -1920,10 +1983,15 @@ void WinMtfOutput::ScaleDevExt( double fX, double fY )
//-----------------------------------------------------------------------------------
-void WinMtfOutput::SetWinOrg( const Point& rPoint )
+void WinMtfOutput::SetWinOrg( const Point& rPoint , sal_Bool bIsEMF)
{
mnWinOrgX = rPoint.X();
mnWinOrgY = rPoint.Y();
+ if (bIsEMF)
+ {
+ SetDevByWin();
+ }
+ mbIsMapWinSet=sal_True;
}
//-----------------------------------------------------------------------------------
@@ -1936,9 +2004,21 @@ void WinMtfOutput::SetWinOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
//-----------------------------------------------------------------------------------
-void WinMtfOutput::SetWinExt( const Size& rSize )
+void WinMtfOutput::SetDevByWin() //mnWinExt...-stuff has to be assigned before.
{
+ if (!mbIsMapDevSet)
+ {
+ if ((mnMapMode == MM_ISOTROPIC) ) //TODO: WHAT ABOUT ANISOTROPIC???
+ {
+ SetDevExt(Size((mnWinExtX+mnWinOrgX)>>MS_FIXPOINT_BITCOUNT_28_4,-((mnWinExtY-mnWinOrgY)>>MS_FIXPOINT_BITCOUNT_28_4)),sal_False);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+void WinMtfOutput::SetWinExt( const Size& rSize, sal_Bool bIsEMF )
+{
if( rSize.Width() && rSize.Height() )
{
switch( mnMapMode )
@@ -1948,6 +2028,11 @@ void WinMtfOutput::SetWinExt( const Size& rSize )
{
mnWinExtX = rSize.Width();
mnWinExtY = rSize.Height();
+ if (bIsEMF)
+ {
+ SetDevByWin();
+ }
+ mbIsMapWinSet=sal_True;
}
}
}
diff --git a/vcl/source/filter/wmf/winmtf.hxx b/vcl/source/filter/wmf/winmtf.hxx
index bc368e6e6baa..146493eda72c 100644
--- a/vcl/source/filter/wmf/winmtf.hxx
+++ b/vcl/source/filter/wmf/winmtf.hxx
@@ -278,6 +278,13 @@ struct WMF_EXTERNALHEADER;
#define PRIVATE_ESCAPE_UNICODE 2
+//Scalar constants
+
+#define UNDOCUMENTED_WIN_RCL_RELATION 32
+#define MS_FIXPOINT_BITCOUNT_28_4 4
+#define HUNDREDTH_MILLIMETERS_PER_MILLIINCH 2.54
+#define MILLIINCH_PER_TWIPS 1.44
+
//============================ WMFReader ==================================
#ifdef WIN_MTF_ASSERT
@@ -624,6 +631,8 @@ class WinMtfOutput
sal_Int32 mnDevWidth, mnDevHeight;
sal_Int32 mnWinOrgX, mnWinOrgY; // aktuelles Window-Origin
sal_Int32 mnWinExtX, mnWinExtY; // aktuelles Window-Extent
+ sal_Bool mbIsMapWinSet;
+ sal_Bool mbIsMapDevSet;
sal_Int32 mnPixX, mnPixY; // Reference Device in pixel
sal_Int32 mnMillX, mnMillY; // Reference Device in Mill
@@ -636,11 +645,14 @@ class WinMtfOutput
void UpdateFillStyle();
Point ImplMap( const Point& rPt );
+ Point ImplScale( const Point& rPt );
Size ImplMap( const Size& rSz );
Rectangle ImplMap( const Rectangle& rRectangle );
void ImplMap( Font& rFont );
Polygon& ImplMap( Polygon& rPolygon );
PolyPolygon& ImplMap( PolyPolygon& rPolyPolygon );
+ Polygon& ImplScale( Polygon& rPolygon );
+ PolyPolygon& ImplScale( PolyPolygon& rPolyPolygon );
void ImplResizeObjectArry( sal_uInt32 nNewEntry );
void ImplSetNonPersistentLineColorTransparenz();
void ImplDrawClippedPolyPolygon( const PolyPolygon& rPolyPoly );
@@ -648,14 +660,15 @@ class WinMtfOutput
public:
+ void SetDevByWin(); //Hack to set varying defaults for incompletely defined files.
void SetDevOrg( const Point& rPoint );
void SetDevOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd );
- void SetDevExt( const Size& rSize );
+ void SetDevExt( const Size& rSize ,sal_Bool regular = true);
void ScaleDevExt( double fX, double fY );
- void SetWinOrg( const Point& rPoint );
+ void SetWinOrg( const Point& rPoint , sal_Bool bIsEMF = false);
void SetWinOrgOffset( sal_Int32 nX, sal_Int32 nY );
- void SetWinExt( const Size& rSize );
+ void SetWinExt( const Size& rSize , sal_Bool bIsEMF = false);
void ScaleWinExt( double fX, double fY );
void SetrclBounds( const Rectangle& rRect );