Kaydet (Commit) ee21771d authored tarafından Vort's avatar Vort Kaydeden (comit) Caolán McNamara

fdo#88465 PDF Import: fix scale and rotate image transformations

Change-Id: I64bb088320099303b0da6d272c3cd6a9ba954f87
Reviewed-on: https://gerrit.libreoffice.org/13957Reviewed-by: 's avatarCaolán McNamara <caolanm@redhat.com>
Tested-by: 's avatarCaolán McNamara <caolanm@redhat.com>
üst 453b9c98
......@@ -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)))
{
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment