void TransformTest::testTransformCombined() { QFETCH(int, type); QFETCH(double, rotation); qint32 dx = -3000; qint32 dy = 16000; qreal scale_x = 4.5; qreal scale_y = 2.5; QTransform qt; // Template::applyTemplateTransform order: translate, rotate, scale qt.translate(dx / 1000.0, dy / 1000.0); qt.rotate(qreal(rotation)); qt.scale(scale_x, scale_y); QVERIFY(qt.isScaling()); QCOMPARE(int(qt.type()), type); auto t = TemplateTransform::fromQTransform(qt); QCOMPARE(t.template_x, dx); QCOMPARE(t.template_y, dy); QCOMPARE(t.template_scale_x, scale_x); QCOMPARE(t.template_scale_y, scale_y); if (rotation <= 180.0) QCOMPARE(t.template_rotation, -qDegreesToRadians(qreal(rotation))); else QCOMPARE(t.template_rotation, -qDegreesToRadians(qreal(rotation - 360.0))); }
static inline void qwtDrawPixmapSymbols( QPainter *painter, const QPointF *points, int numPoints, const QwtSymbol &symbol ) { QSize size = symbol.size(); if ( size.isEmpty() ) size = symbol.pixmap().size(); const QTransform transform = painter->transform(); if ( transform.isScaling() ) { const QRect r( 0, 0, size.width(), size.height() ); size = transform.mapRect( r ).size(); } QPixmap pm = symbol.pixmap(); if ( pm.size() != size ) pm = pm.scaled( size ); QPointF pinPoint( 0.5 * size.width(), 0.5 * size.height() ); if ( symbol.isPinPointEnabled() ) pinPoint = symbol.pinPoint(); painter->resetTransform(); for ( int i = 0; i < numPoints; i++ ) { const QPointF pos = transform.map( points[i] ) - pinPoint; QwtPainter::drawPixmap( painter, QRect( pos.toPoint(), pm.size() ), pm ); } }
void TransformTest::testEstimateNonIsometric() { // Scaling and translation PassPointList passpoints; passpoints.resize(3); passpoints[0].src_coords = MapCoordF { 128.0, 0.0 }; passpoints[0].dest_coords = MapCoordF { 64.0, 64.0 }; passpoints[1].src_coords = MapCoordF { 256.0, 0.0 }; passpoints[1].dest_coords = MapCoordF { 96.0, 64.0 }; passpoints[2].src_coords = MapCoordF { 128.0, 128.0 }; passpoints[2].dest_coords = MapCoordF { 64.0, 96.0 }; QTransform qt; QVERIFY(passpoints.estimateNonIsometricSimilarityTransform(&qt)); QVERIFY(qt.isTranslating()); QVERIFY(qt.isScaling()); QCOMPARE(int(qt.type()), int(QTransform::TxScale)); QCOMPARE(qt.map(passpoints[0].src_coords), QPointF{passpoints[0].dest_coords}); QCOMPARE(qt.map(passpoints[1].src_coords), QPointF{passpoints[1].dest_coords}); QCOMPARE(qt.map(passpoints[2].src_coords), QPointF{passpoints[2].dest_coords}); auto t = TemplateTransform::fromQTransform(qt); QCOMPARE(t.template_x, MapCoord(32,64).nativeX()); QCOMPARE(t.template_y, MapCoord(32,64).nativeY()); QCOMPARE(t.template_scale_x, 0.25); QCOMPARE(t.template_scale_y, 0.25); QVERIFY(qAbs(t.template_rotation) < 0.000001); // Rotation passpoints[0].src_coords = MapCoordF { 0.0, 0.0 }; passpoints[0].dest_coords = MapCoordF { 0.0, 0.0 }; passpoints[1].src_coords = MapCoordF { 5.0, 0.0 }; passpoints[1].dest_coords = MapCoordF { 4.0, -3.0 }; passpoints[2].src_coords = MapCoordF { 0.0, 5.0 }; passpoints[2].dest_coords = MapCoordF { 3.0, 4.0 }; QVERIFY(passpoints.estimateNonIsometricSimilarityTransform(&qt)); QVERIFY(qt.isRotating()); QCOMPARE(int(qt.type()), int(QTransform::TxRotate)); QCOMPARE(qt.map(passpoints[0].src_coords), QPointF{passpoints[0].dest_coords}); QCOMPARE(qt.map(passpoints[1].src_coords), QPointF{passpoints[1].dest_coords}); QCOMPARE(qt.map(passpoints[2].src_coords), QPointF{passpoints[2].dest_coords}); t = TemplateTransform::fromQTransform(qt); QCOMPARE(t.template_x, 0); QCOMPARE(t.template_y, 0); QCOMPARE(t.template_scale_x, 1.0); QCOMPARE(t.template_scale_y, 1.0); QCOMPARE(t.template_rotation, qAcos(passpoints[1].dest_coords.x() / passpoints[1].src_coords.x())); }
void TransformTest::testTransformProject() { qreal scale_x = 4.5; qreal scale_y = 2.5; QTransform qt; qt.scale(scale_x, scale_y); QVERIFY(qt.isScaling()); QCOMPARE(int(qt.type()), int(QTransform::TxScale)); auto t = TemplateTransform::fromQTransform(qt); QCOMPARE(t.template_x, 0); QCOMPARE(t.template_y, 0); QCOMPARE(t.template_scale_x, scale_x); QCOMPARE(t.template_scale_y, scale_y); QCOMPARE(t.template_rotation, 0.0); }
void KPrShapeManagerAnimationStrategy::paint( KoShape * shape, QPainter &painter, const KoViewConverter &converter, bool forPrint ) { if ( ! dynamic_cast<KPrPlaceholderShape *>( shape ) && m_strategy->page()->displayShape( shape ) ) { if ( m_animationCache->value(shape, "visibility", true).toBool() ) { painter.save(); QTransform animationTransform = m_animationCache->value(shape, "transform", QTransform()).value<QTransform>();; QTransform transform(painter.transform() * shape->absoluteTransformation(&converter)); if (animationTransform.isScaling()) { transform = animationTransform * transform; } else { transform = transform * animationTransform; } painter.setTransform(transform); // paint shape shapeManager()->paintShape( shape, painter, converter, forPrint ); painter.restore(); // for the transform } } }
/*! Check if the painter is using a paint engine, that aligns coordinates to integers. Today these are all paint engines beside QPaintEngine::Pdf and QPaintEngine::SVG. If we have an integer based paint engine it is also checked if the painter has a transformation matrix, that rotates or scales. \param painter Painter \return true, when the painter is aligning \sa setRoundingAlignment() */ bool QwtPainter::isAligning( QPainter *painter ) { if ( painter && painter->isActive() ) { switch ( painter->paintEngine()->type() ) { case QPaintEngine::Pdf: case QPaintEngine::SVG: return false; default:; } const QTransform tr = painter->transform(); if ( tr.isRotating() || tr.isScaling() ) { // we might have to check translations too return false; } } return true; }
void TransformTest::testTransformIdentity() { // Default QTransform: identity QTransform qt; QVERIFY(qt.isIdentity()); QCOMPARE(int(qt.type()), int(QTransform::TxNone)); // Default TemplateTransform: identity TemplateTransform t; // TemplateTransform list initialization, and assignment t = { 12, -3, 0.1, 2.0, 3.0 }; QCOMPARE(t.template_x, 12); QCOMPARE(t.template_y, -3); QCOMPARE(t.template_scale_x, 2.0); QCOMPARE(t.template_scale_y, 3.0); QCOMPARE(t.template_rotation, 0.1); // Now transfer the identity QTransform to the TemplateTransform t = TemplateTransform::fromQTransform(qt); QCOMPARE(t.template_x, 0); QCOMPARE(t.template_y, 0); QCOMPARE(t.template_scale_x, 1.0); QCOMPARE(t.template_scale_y, 1.0); QCOMPARE(t.template_rotation, 0.0); // Put something different in the QTransform qt.translate(4, 8); qt.rotate(1); qt.scale(2.0, 1.5); QVERIFY(qt.isAffine()); QVERIFY(!qt.isIdentity()); QVERIFY(qt.isTranslating()); QVERIFY(qt.isRotating()); QVERIFY(qt.isScaling()); }
void RenderImage::paint(PaintInfo& paintInfo, int _tx, int _ty) { if (paintInfo.phase == PaintActionOutline && style()->outlineWidth() && style()->visibility() == VISIBLE) paintOutline(paintInfo.p, _tx + m_x, _ty + m_y, width(), height(), style()); if (paintInfo.phase != PaintActionForeground && paintInfo.phase != PaintActionSelection) return; // not visible or not even once layouted? if (style()->visibility() != VISIBLE || m_y <= -500000) return; _tx += m_x; _ty += m_y; if((_ty > paintInfo.r.bottom()) || (_ty + m_height <= paintInfo.r.top())) return; if(shouldPaintBackgroundOrBorder()) paintBoxDecorations(paintInfo, _tx, _ty); if (!canvas()->printImages()) return; int cWidth = contentWidth(); int cHeight = contentHeight(); int leftBorder = borderLeft(); int topBorder = borderTop(); int leftPad = paddingLeft(); int topPad = paddingTop(); // paint frame around image and loading icon as long as it is not completely loaded from web. if (bUnfinishedImageFrame && paintInfo.phase == PaintActionForeground && cWidth > 2 && cHeight > 2 && !complete()) { static QPixmap *loadingIcon; QColor bg = khtml::retrieveBackgroundColor(this); QColor fg = khtml::hasSufficientContrast(Qt::gray, bg) ? Qt::gray : (hasSufficientContrast(Qt::white, bg) ? Qt::white : Qt::black); paintInfo.p->setPen(QPen(fg, 1)); paintInfo.p->setBrush( Qt::NoBrush ); const int offsetX = _tx + leftBorder + leftPad; const int offsetY = _ty + topBorder + topPad; paintInfo.p->drawRect(offsetX, offsetY, cWidth - 1, cHeight - 1); if (!(m_width <= 5 || m_height <= 5)) { if (!loadingIcon) { loadingIcon = new QPixmap(); loadingIcon->loadFromData(loading_icon_data, loading_icon_len); } paintInfo.p->drawPixmap(offsetX + 4, offsetY + 4, *loadingIcon, 0, 0, cWidth - 5, cHeight - 5); } } CachedImage* i = m_cachedImage; //kDebug( 6040 ) << " contents (" << contentWidth << "/" << contentHeight << ") border=" << borderLeft() << " padding=" << paddingLeft(); if ( !i || berrorPic) { if(cWidth > 2 && cHeight > 2) { if ( !berrorPic ) { //qDebug("qDrawShadePanel %d/%d/%d/%d", _tx + leftBorder, _ty + topBorder, cWidth, cHeight); qDrawShadePanel( paintInfo.p, _tx + leftBorder + leftPad, _ty + topBorder + topPad, cWidth, cHeight, QApplication::palette(), true, 1 ); } QPixmap pix = *Cache::brokenPixmap; if(berrorPic && (cWidth >= pix.width()+4) && (cHeight >= pix.height()+4) ) { QRect r(pix.rect()); r = r.intersect(QRect(0, 0, cWidth-4, cHeight-4)); paintInfo.p->drawPixmap( QPoint( _tx + leftBorder + leftPad+2, _ty + topBorder + topPad+2), pix, r ); } if(!alt.isEmpty()) { QString text = alt.string(); paintInfo.p->setFont(style()->font()); paintInfo.p->setPen( style()->color() ); int ax = _tx + leftBorder + leftPad + 2; int ay = _ty + topBorder + topPad + 2; const QFontMetrics &fm = style()->fontMetrics(); //BEGIN HACK #ifdef __GNUC__ #warning "KDE4: hack for testregression, remove when main branch" #endif ax += qMax(-fm.minLeftBearing(), 0); cWidth -= qMax(-fm.minLeftBearing(), 0); //END HACK if (cWidth>5 && cHeight>=fm.height()) paintInfo.p->drawText(ax, ay+1, cWidth - 4, cHeight - 4, Qt::TextWordWrap, text ); } } } else if (i && !i->isTransparent() && i->image()->size().width() && i->image()->size().height()) { paintInfo.p->setPen( Qt::black ); // used for bitmaps //const QPixmap& pix = i->pixmap(); if (!m_imagePainter) m_imagePainter = new ImagePainter(i->image()); // If we have a scaled painter we want to handle the resizing ourselves, so figure out the scaled size, QTransform painterTransform = paintInfo.p->transform(); bool scaled = painterTransform.isScaling() && !painterTransform.isRotating(); QRect scaledRect; // bounding box of the whole thing, transformed, so we also know where the origin goes. if (scaled) { scaledRect = painterTransform.mapRect(QRect(0, 0, contentWidth(), contentHeight())); m_imagePainter->setSize(QSize(scaledRect.width(), scaledRect.height())); } else { m_imagePainter->setSize(QSize(contentWidth(), contentHeight())); } // Now, figure out the rectangle to paint (in painter coordinates), by interesting us with the painting clip rectangle. int x = _tx + leftBorder + leftPad; int y = _ty + topBorder + topPad; QRect imageGeom = QRect(0, 0, contentWidth(), contentHeight()); QRect clipPortion = paintInfo.r.translated(-x, -y); imageGeom &= clipPortion; QPoint destPos = QPoint(x + imageGeom.x(), y + imageGeom.y()); // If we're scaling, reset the painters transform, and apply it ourselves; though // being careful not apply the translation to the source rect. if (scaled) { paintInfo.p->resetTransform(); destPos = painterTransform.map(destPos); imageGeom = painterTransform.mapRect(imageGeom).translated(-scaledRect.topLeft()); } m_imagePainter->paint(destPos.x(), destPos.y(), paintInfo.p, imageGeom.x(), imageGeom.y(), imageGeom.width(), imageGeom.height()); if (scaled) paintInfo.p->setTransform(painterTransform); } if (m_selectionState != SelectionNone) { // kDebug(6040) << "_tx " << _tx << " _ty " << _ty << " _x " << _x << " _y " << _y; // Draw in any case if inside selection. For selection borders, the // offset will decide whether to draw selection or not bool draw = true; if (m_selectionState != SelectionInside) { int startPos, endPos; selectionStartEnd(startPos, endPos); if(selectionState() == SelectionStart) endPos = 1; else if(selectionState() == SelectionEnd) startPos = 0; draw = endPos - startPos > 0; } if (draw) { // setting the brush origin is important for compatibility, // don't touch it unless you know what you're doing paintInfo.p->setBrushOrigin(_tx, _ty - paintInfo.r.y()); paintInfo.p->fillRect(_tx, _ty, width(), height(), QBrush(style()->palette().color( QPalette::Active, QPalette::Highlight ), Qt::Dense4Pattern)); } } }