[Libreoffice-commits] core.git: sdext/source

Vort vvort at yandex.ru
Mon Jan 19 04:54:30 PST 2015


 sdext/source/pdfimport/tree/drawtreevisiting.cxx |   85 ++++++++--------------
 sdext/source/pdfimport/tree/pdfiprocessor.cxx    |   88 ++++++-----------------
 2 files changed, 56 insertions(+), 117 deletions(-)

New commits:
commit ee21771db0292315ff3e1b87ff58294335106bd3
Author: Vort <vvort at yandex.ru>
Date:   Fri Jan 16 18:29:40 2015 +0200

    fdo#88465 PDF Import: fix scale and rotate image transformations
    
    Change-Id: I64bb088320099303b0da6d272c3cd6a9ba954f87
    Reviewed-on: https://gerrit.libreoffice.org/13957
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.cxx b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
index 2194ad7..67f4912 100644
--- a/sdext/source/pdfimport/tree/drawtreevisiting.cxx
+++ b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
@@ -190,74 +190,55 @@ void DrawXmlEmitter::fillFrameProps( DrawElement&       rElem,
                                      bool               bWasTransformed
                                      )
 {
-    double rel_x = rElem.x, rel_y = rElem.y;
-
     rProps[ "draw:z-index" ] = OUString::number( rElem.ZOrder );
     rProps[ "draw:style-name"] = rEmitContext.rStyles.getStyleName( rElem.StyleId );
-    rProps[ "svg:width" ]   = convertPixelToUnitString( rElem.w );
-    rProps[ "svg:height" ]  = convertPixelToUnitString( rElem.h );
 
     if (rElem.IsForText)
         rProps["draw:text-style-name"] = rEmitContext.rStyles.getStyleName(rElem.TextStyleId);
 
     const GraphicsContext& rGC =
         rEmitContext.rProcessor.getGraphicsContext( rElem.GCId );
-    if( rGC.Transformation.isIdentity() || bWasTransformed )
+
+    if (bWasTransformed)
     {
-        rProps[ "svg:x" ]       = convertPixelToUnitString( rel_x );
-        rProps[ "svg:y" ]       = convertPixelToUnitString( rel_y );
+        rProps[ "svg:x" ]       = convertPixelToUnitString(rElem.x);
+        rProps[ "svg:y" ]       = convertPixelToUnitString(rElem.y);
+        rProps[ "svg:width" ]   = convertPixelToUnitString(rElem.w);
+        rProps[ "svg:height" ]  = convertPixelToUnitString(rElem.h);
     }
     else
     {
-        basegfx::B2DTuple aScale, aTranslation;
-        double fRotate, fShearX;
-
-        rGC.Transformation.decompose( aScale, aTranslation, fRotate, fShearX );
-
-        OUStringBuffer aBuf( 256 );
-
-        // TODO(F2): general transformation case missing; if implemented, note
-        // that ODF rotation is oriented the other way
+        OUStringBuffer aBuf(256);
 
-        // vertical mirroring is done by horizontally mirroring and rotaing 180 degree
-        // quaint !
-        if( rElem.MirrorVertical )
-            fRotate += M_PI;
+        basegfx::B2DHomMatrix mat(rGC.Transformation);
 
-        // First check here is to skip image frame case
-        if (rElem.IsForText &&
-            (aScale.getX() < 0) &&
-            (aScale.getY() > 0) &&
-            (basegfx::fTools::equalZero(aScale.getX() + aScale.getY(), 0.0001)))
+        if (rElem.MirrorVertical)
         {
-            fRotate += M_PI;
+            basegfx::B2DHomMatrix mat2;
+            mat2.translate(-0.5, -0.5);
+            mat2.scale(-1, -1);
+            mat2.translate(0.5, 0.5);
+            mat = mat * mat2;
         }
 
-        // build transformation string
-        if( fShearX != 0.0 )
-        {
-            aBuf.appendAscii( "skewX( " );
-            aBuf.append( fShearX );
-            aBuf.appendAscii( " )" );
-        }
-        if( fRotate != 0.0 )
-        {
-            if( !aBuf.isEmpty() )
-                aBuf.append( ' ' );
-            aBuf.appendAscii( "rotate( " );
-            aBuf.append( -fRotate );
-            aBuf.appendAscii( " )" );
-
-        }
-        if( !aBuf.isEmpty() )
-            aBuf.append( ' ' );
-        aBuf.appendAscii( "translate( " );
-        aBuf.append( convertPixelToUnitString( rel_x ) );
-        aBuf.append( ' ' );
-        aBuf.append( convertPixelToUnitString( rel_y ) );
-        aBuf.appendAscii( " )" );
-
-        rProps[ "draw:transform" ] = aBuf.makeStringAndClear();
+        double scale = convPx2mm(100);
+        mat.scale(scale, scale);
+
+        aBuf.appendAscii("matrix(");
+        aBuf.append(mat.get(0, 0));
+        aBuf.append(' ');
+        aBuf.append(mat.get(1, 0));
+        aBuf.append(' ');
+        aBuf.append(mat.get(0, 1));
+        aBuf.append(' ');
+        aBuf.append(mat.get(1, 1));
+        aBuf.append(' ');
+        aBuf.append(mat.get(0, 2));
+        aBuf.append(' ');
+        aBuf.append(mat.get(1, 2));
+        aBuf.appendAscii(")");
+
+        rProps["draw:transform"] = aBuf.makeStringAndClear();
     }
 }
 
@@ -905,7 +886,7 @@ void DrawXmlFinalizer::visit( TextElement& elem, const std::list< Element* >::co
     double fRotate, fShearX;
     basegfx::B2DTuple aScale, aTranslation;
     rGC.Transformation.decompose(aScale, aTranslation, fRotate, fShearX);
-    double textScale = -100 * aScale.getX() / aScale.getY();
+    double textScale = 100 * aScale.getX() / aScale.getY();
     if (((textScale >= 1) && (textScale <= 99)) ||
         ((textScale >= 101) && (textScale <= 999)))
     {
diff --git a/sdext/source/pdfimport/tree/pdfiprocessor.cxx b/sdext/source/pdfimport/tree/pdfiprocessor.cxx
index 37f4126..87eda4e 100644
--- a/sdext/source/pdfimport/tree/pdfiprocessor.cxx
+++ b/sdext/source/pdfimport/tree/pdfiprocessor.cxx
@@ -282,15 +282,22 @@ void PDFIProcessor::drawGlyphs( const OUString&             rGlyphs,
 {
     double ascent = getFont(getCurrentContext().FontId).ascent;
 
-    double ascentdx = rFontMatrix.m01 * ascent * fontSize;
-    double ascentdy = rFontMatrix.m11 * ascent * fontSize;
-
-    basegfx::B2DHomMatrix totalTextMatrix1(
-        rFontMatrix.m00, rFontMatrix.m01, rRect.X1 + ascentdx,
-        rFontMatrix.m10, rFontMatrix.m11, rRect.Y1 + ascentdy);
-    basegfx::B2DHomMatrix totalTextMatrix2(
-        rFontMatrix.m00, rFontMatrix.m01, rRect.X2 + ascentdx,
-        rFontMatrix.m10, rFontMatrix.m11, rRect.Y2 + ascentdy);
+    basegfx::B2DHomMatrix fontMatrix(
+        rFontMatrix.m00, rFontMatrix.m01, 0.0,
+        rFontMatrix.m10, rFontMatrix.m11, 0.0);
+    fontMatrix.scale(fontSize, fontSize);
+
+    basegfx::B2DHomMatrix totalTextMatrix1(fontMatrix);
+    basegfx::B2DHomMatrix totalTextMatrix2(fontMatrix);
+    totalTextMatrix1.translate(rRect.X1, rRect.Y1);
+    totalTextMatrix2.translate(rRect.X2, rRect.Y2);
+
+    basegfx::B2DHomMatrix corrMatrix;
+    corrMatrix.scale(1.0, -1.0);
+    corrMatrix.translate(0.0, ascent);
+    totalTextMatrix1 = totalTextMatrix1 * corrMatrix;
+    totalTextMatrix2 = totalTextMatrix2 * corrMatrix;
+
     totalTextMatrix1 *= getCurrentContext().Transformation;
     totalTextMatrix2 *= getCurrentContext().Transformation;
 
@@ -334,72 +341,23 @@ void PDFIProcessor::endText()
 
 void PDFIProcessor::setupImage(ImageId nImage)
 {
-    const GraphicsContext& rGC( getCurrentContext() );
-
-    basegfx::B2DHomMatrix aTrans( rGC.Transformation );
+    const GraphicsContext& rGC(getCurrentContext());
 
-    // check for rotation, which is the other way around in ODF
     basegfx::B2DTuple aScale, aTranslation;
     double fRotate, fShearX;
-    rGC.Transformation.decompose( aScale, aTranslation, fRotate, fShearX );
-    // TODDO(F4): correcting rotation when fShearX != 0 ?
-    if( fRotate != 0.0 )
-    {
-
-        // try to create a Transformation that corrects for the wrong rotation
-        aTrans.identity();
-        aTrans.scale( aScale.getX(), aScale.getY() );
-        aTrans.rotate( -fRotate );
-
-        basegfx::B2DRange aRect( 0, 0, 1, 1 );
-        aRect.transform( aTrans );
-
-        // TODO(F3) treat translation correctly
-        // the corrections below work for multiples of 90 degree
-        // which is a common case (landscape/portrait/seascape)
-        // we need a general solution here; however this needs to
-        // work in sync with DrawXmlEmitter::fillFrameProps and WriterXmlEmitter::fillFrameProps
-        // admittedly this is a lame workaround and fails for arbitrary rotation
-        double fQuadrant = fmod( fRotate, 2.0*M_PI ) / M_PI_2;
-        int nQuadrant = (int)fQuadrant;
-        if( nQuadrant < 0 )
-            nQuadrant += 4;
-        if( nQuadrant == 1 )
-        {
-            aTranslation.setX( aTranslation.getX() + aRect.getHeight() + aRect.getWidth());
-            aTranslation.setY( aTranslation.getY() + aRect.getHeight() );
-        }
-        if( nQuadrant == 3 )
-            aTranslation.setX( aTranslation.getX() - aRect.getHeight() );
+    rGC.Transformation.decompose(aScale, aTranslation, fRotate, fShearX);
 
-        aTrans.translate( aTranslation.getX(),
-                          aTranslation.getY() );
-    }
-
-    bool bMirrorVertical = aScale.getY() > 0;
-
-    // transform unit rect to determine view box
-    basegfx::B2DRange aRect( 0, 0, 1, 1 );
-    aRect.transform( aTrans );
-
-    // TODO(F3): Handle clip
     const sal_Int32 nGCId = getGCId(rGC);
     FrameElement* pFrame = m_pElFactory->createFrameElement( m_pCurElement, nGCId );
     ImageElement* pImageElement = m_pElFactory->createImageElement( pFrame, nGCId, nImage );
-    pFrame->x = pImageElement->x = aRect.getMinX();
-    pFrame->y = pImageElement->y = aRect.getMinY();
-    pFrame->w = pImageElement->w = aRect.getWidth();
-    pFrame->h = pImageElement->h = aRect.getHeight();
+    pFrame->x = pImageElement->x = aTranslation.getX();
+    pFrame->y = pImageElement->y = aTranslation.getY();
+    pFrame->w = pImageElement->w = aScale.getX();
+    pFrame->h = pImageElement->h = aScale.getY();
     pFrame->ZOrder = m_nNextZOrder++;
 
-    if( bMirrorVertical )
-    {
+    if (aScale.getY() > 0)
         pFrame->MirrorVertical = pImageElement->MirrorVertical = true;
-        pFrame->x        += aRect.getWidth();
-        pImageElement->x += aRect.getWidth();
-        pFrame->y        += aRect.getHeight();
-        pImageElement->y += aRect.getHeight();
-    }
 }
 
 void PDFIProcessor::drawMask(const uno::Sequence<beans::PropertyValue>& xBitmap,


More information about the Libreoffice-commits mailing list