summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVort <vvort@yandex.ru>2015-01-16 18:29:40 +0200
committerAndras Timar <andras.timar@collabora.com>2015-07-07 16:03:59 +0000
commit470eaff4ddbadb26b7c3d524d351508e984ce878 (patch)
treeef79ed411b54dbba2d0e55360950c04f71be4e62
parent7c7836141b6f2e71b4c41227718b4b916f464f5a (diff)
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@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit ee21771db0292315ff3e1b87ff58294335106bd3) Reviewed-on: https://gerrit.libreoffice.org/16824 Reviewed-by: Andras Timar <andras.timar@collabora.com> Tested-by: Andras Timar <andras.timar@collabora.com>
-rw-r--r--sdext/source/pdfimport/tree/drawtreevisiting.cxx85
-rw-r--r--sdext/source/pdfimport/tree/pdfiprocessor.cxx88
2 files changed, 56 insertions, 117 deletions
diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.cxx b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
index 2194ad726972..67f491283ff7 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 37f412631013..87eda4e36929 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,