From cb2f3e524919444d84974fe3216edd8fafc28e10 Mon Sep 17 00:00:00 2001 From: Bartosz Kosiorek Date: Sat, 8 Apr 2017 02:35:34 +0200 Subject: tdf#106084 EMF+ Add support for EmfPlusTranslateWorldTransform record The EmfPlusTranslateWorldTransform record performs a translation on the current world space transform. Change-Id: I3e5744060c8a6d758bcc2804c6798e0208d2191f Reviewed-on: https://gerrit.libreoffice.org/36287 Tested-by: Jenkins Reviewed-by: Bartosz Kosiorek (cherry picked from commit fcb32f1cbc335a953cea62f66b9f50170263fb56) Reviewed-on: https://gerrit.libreoffice.org/37090 Reviewed-by: Thorsten Behrens --- cppcanvas/source/inc/implrenderer.hxx | 33 ++++++++++++++++++++++---------- cppcanvas/source/mtfrenderer/emfplus.cxx | 27 +++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/cppcanvas/source/inc/implrenderer.hxx b/cppcanvas/source/inc/implrenderer.hxx index b9babf1df753..b81e8908d5be 100644 --- a/cppcanvas/source/inc/implrenderer.hxx +++ b/cppcanvas/source/inc/implrenderer.hxx @@ -76,19 +76,26 @@ namespace cppcanvas }; // EMF+ - // TODO: replace? + // Transformation matrix (used for Affine Transformation) + // [ eM11, eM12, eDx ] + // [ eM21, eM22, eDy ] + // [ 0, 0, 1 ] + // that consists of a linear map (eM11, eM12, eM21, eM22) + // More info: https://en.wikipedia.org/wiki/Linear_map + // followed by a translation (eDx, eDy) + struct XForm { - float eM11; - float eM12; - float eM21; - float eM22; - float eDx; - float eDy; + float eM11; // M1,1 value in the matrix. Increases or decreases the size of the pixels horizontally. + float eM12; // M1,2 value in the matrix. This effectively angles the X axis up or down. + float eM21; // M2,1 value in the matrix. This effectively angles the Y axis left or right. + float eM22; // M2,2 value in the matrix. Increases or decreases the size of the pixels vertically. + float eDx; // Delta x (Dx) value in the matrix. Moves the whole coordinate system horizontally. + float eDy; // Delta y (Dy) value in the matrix. Moves the whole coordinate system vertically. XForm() { SetIdentity (); - }; + } void SetIdentity () { @@ -106,14 +113,20 @@ namespace cppcanvas eDy = f.eDy; } + // Multiple two square matrices + // [ eM11, eM12, eDx ] [ f.eM11, f.eM12, f.eDx ] + // [ eM21, eM22, eDy ] x [ f.eM21, f.eM22, f.eDy ] + // [ 0, 0, 1 ] [ 0, 0, 1 ] + // More information: https://en.wikipedia.org/wiki/Matrix_multiplication#Square_matrices + // FIXME We shouldn't modify source matrix during computation void Multiply (const XForm& f) { eM11 = eM11*f.eM11 + eM12*f.eM21; eM12 = eM11*f.eM12 + eM12*f.eM22; eM21 = eM21*f.eM11 + eM22*f.eM21; eM22 = eM21*f.eM12 + eM22*f.eM22; - eDx *= eDx*f.eM11 + eDy*f.eM21 + f.eDx; - eDy *= eDx*f.eM12 + eDy*f.eM22 + f.eDy; + eDx = eDx*f.eM11 + eDy*f.eM21 + f.eDx; + eDy = eDx*f.eM12 + eDy*f.eM22 + f.eDy; } #ifdef OSL_BIGENDIAN diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx index bf9e3b89099d..76cdd7ee8a54 100644 --- a/cppcanvas/source/mtfrenderer/emfplus.cxx +++ b/cppcanvas/source/mtfrenderer/emfplus.cxx @@ -93,7 +93,7 @@ namespace #define EmfPlusRecordTypeSetWorldTransform 0x402A #define EmfPlusRecordTypeResetWorldTransform 0x402B #define EmfPlusRecordTypeMultiplyWorldTransform 0x402C -//TODO EmfPlusRecordTypeTranslateWorldTransform 0x402D +#define EmfPlusRecordTypeTranslateWorldTransform 0x402D //TODO EmfPlusRecordTypeScaleWorldTransform 0x402E //TODO EmfPlusRecordTypeRotateWorldTransform 0x402F #define EmfPlusRecordTypeSetPageTransform 0x4030 @@ -243,6 +243,7 @@ const char* emfTypeToName(sal_uInt16 type) case EmfPlusRecordTypeSetWorldTransform: return "EmfPlusRecordTypeSetWorldTransform"; case EmfPlusRecordTypeResetWorldTransform: return "EmfPlusRecordTypeResetWorldTransform"; case EmfPlusRecordTypeMultiplyWorldTransform: return "EmfPlusRecordTypeMultiplyWorldTransform"; + case EmfPlusRecordTypeTranslateWorldTransform: return "EmfPlusRecordTypeTranslateWorldTransform"; case EmfPlusRecordTypeSetPageTransform: return "EmfPlusRecordTypeSetPageTransform"; case EmfPlusRecordTypeSetClipRect: return "EmfPlusRecordTypeSetClipRect"; case EmfPlusRecordTypeSetClipPath: return "EmfPlusRecordTypeSetClipPath"; @@ -2369,6 +2370,30 @@ namespace cppcanvas "EMF+\tdx: " << aWorldTransform.eDx << "dy: " << aWorldTransform.eDy); break; } + case EmfPlusRecordTypeTranslateWorldTransform: + { + SAL_INFO("cppcanvas.emf", "EMF+ TranslateWorldTransform"); + + XForm transform = XForm(); + rMF.ReadFloat( transform.eDx ).ReadFloat( transform.eDy ); + + SAL_INFO("cppcanvas.emf", + "EMF+\t m11: " << transform.eM11 << ", m12: " << transform.eM12 << + "EMF+\t m21: " << transform.eM21 << ", m22: " << transform.eM22 << + "EMF+\t dx: " << transform.eDx << ", dy: " << transform.eDy); + + if (flags & 0x2000) // post multiply + aWorldTransform.Multiply (transform); + else { // pre multiply + transform.Multiply (aWorldTransform); + aWorldTransform.Set (transform); + } + SAL_INFO("cppcanvas.emf", + "EMF+\t m11: " << aWorldTransform.eM11 << ", m12: " << aWorldTransform.eM12 << + "EMF+\t m21: " << aWorldTransform.eM21 << ", m22: " << aWorldTransform.eM22 << + "EMF+\t dx: " << aWorldTransform.eDx << ", dy: " << aWorldTransform.eDy); + break; + } case EmfPlusRecordTypeSetClipRect: { int combineMode = (flags >> 8) & 0xf; -- cgit v1.2.3