diff options
-rw-r--r-- | vcl/source/filter/wmf/enhwmf.cxx | 14 | ||||
-rw-r--r-- | vcl/source/filter/wmf/winmtf.cxx | 123 | ||||
-rw-r--r-- | vcl/source/filter/wmf/winmtf.hxx | 19 |
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 ); |