void Na2DViewer::transformPainterToCurrentCamera(QPainter& painter) { // adjust painter coordinate system to place image correctly float scale = defaultScale * cameraModel.scale(); // origin at pixel center, not corner qreal w2 = (pixmap.width() - 1.0) / 2.0; qreal h2 = (pixmap.height() - 1.0) / 2.0; qreal tx = w2 + flip_X * (cameraModel.focus().x() - w2) + 0.5; qreal ty = h2 + flip_Y * (cameraModel.focus().y() - h2) + 0.5; painter.translate(width()/2.0 - tx * scale, height()/2.0 - ty * scale); painter.scale(scale, scale); // I want to convert screen coordinates to image coordinates; // The QPainter object knows this transformation. // This nomenclature for the transforms, e.g. X_view_img , comes from the // advanced dynamics community at Stanford, specifically the disciples of Thomas Kane. X_view_img = painter.transform(); X_img_view = painter.transform().inverted(); }
void PaintMethods::paintEllipse(const DebugDrawing::Ellipse& element, QPainter& painter) { setBrush(element.fillStyle, element.fillColor, painter); setPen(element, painter); if(element.rotation != 0.0f) { QTransform trans(painter.transform()); QTransform transBack(painter.transform()); trans.translate(qreal(element.x), qreal(element.y)); trans.rotateRadians(qreal(element.rotation)); painter.setTransform(trans); painter.drawEllipse(-element.radiusX, -element.radiusY, 2 * element.radiusX, 2 * element.radiusY); painter.setTransform(transBack); } else { painter.drawEllipse(element.x - element.radiusX, element.y - element.radiusY, 2 * element.radiusX, 2 * element.radiusY); } }
void PaintMethods::paintRectangle(const DebugDrawing::Rectangle& element, QPainter& painter) { setBrush(element.fillStyle, element.fillColor, painter); setPen(element, painter); const QRect dRect(element.topLX, element.topLY, element.w, element.h); if(element.rotation != 0.0f) { const QPoint center = dRect.center(); QTransform trans(painter.transform()); QTransform transBack(painter.transform()); trans.translate(center.x(), center.y()); trans.rotateRadians(qreal(element.rotation)); painter.setTransform(trans); painter.drawRect(element.topLX - center.x(), element.topLY - center.y(), dRect.width(), dRect.height()); painter.setTransform(transBack); } else { painter.drawRect(dRect); } }
void KoShapeShadow::paint(KoShape *shape, QPainter &painter, const KoViewConverter &converter) { if (! d->visible) return; // So the approach we are taking here is to draw into a buffer image the size of boundingRect // We offset by the shadow offset at the time we draw into the buffer // Then we filter the image and draw it at the position of the bounding rect on canvas //the boundingRect of the shape or the KoSelection boundingRect of the group QRectF shadowRect = shape->boundingRect(); QRectF zoomedClipRegion = converter.documentToView(shadowRect); // Init the buffer image QImage sourceGraphic(zoomedClipRegion.size().toSize(), QImage::Format_ARGB32_Premultiplied); sourceGraphic.fill(qRgba(0,0,0,0)); // Init the buffer painter QPainter imagePainter(&sourceGraphic); imagePainter.setPen(Qt::NoPen); imagePainter.setBrush(Qt::NoBrush); imagePainter.setRenderHint(QPainter::Antialiasing, painter.testRenderHint(QPainter::Antialiasing)); // Since our imagebuffer and the canvas don't align we need to offset our drawings imagePainter.translate(-1.0f*converter.documentToView(shadowRect.topLeft())); // Handle the shadow offset imagePainter.translate(converter.documentToView(offset())); KoShapeGroup *group = dynamic_cast<KoShapeGroup*>(shape); if (group) { d->paintGroupShadow(group, imagePainter, converter); } else { //apply shape's transformation imagePainter.setTransform(shape->absoluteTransformation(&converter), true); d->paintShadow(shape, imagePainter, converter); } imagePainter.end(); // Blur the shadow (well the entire buffer) d->blurShadow(sourceGraphic, converter.documentToViewX(d->blur), d->color); // Paint the result painter.save(); // The painter is initialized for us with canvas transform 'plus' shape transform // we are only interested in the canvas transform so 'subtract' the shape transform part painter.setTransform(shape->absoluteTransformation(&converter).inverted() * painter.transform()); painter.drawImage(zoomedClipRegion.topLeft(), sourceGraphic); painter.restore(); }
void PaintMethods::paintText(const DebugDrawing::Text& element, QPainter& painter) { QFont font("Arial", element.fontSize, QFont::Normal); pen.setColor(QColor(element.penColor.r, element.penColor.g, element.penColor.b, element.penColor.a)); painter.setPen(pen); painter.setFont(font); QTransform trans(painter.transform()); QTransform newTrans; newTrans.translate(trans.dx(), trans.dy()); newTrans.scale(std::abs(trans.m11()), std::abs(trans.m22())); painter.setTransform(newTrans); painter.drawText(QPoint(element.x * (int)sgn(trans.m11()), element.y * (int)sgn(trans.m22())), QObject::tr((const char*)(&element + 1))); painter.setTransform(trans); }
void KoCreatePathTool::paintPath(KoPathShape& pathShape, QPainter &painter, const KoViewConverter &converter) { Q_D(KoCreatePathTool); painter.setTransform(pathShape.absoluteTransformation(&converter) * painter.transform()); painter.save(); KoShapePaintingContext paintContext; //FIXME pathShape.paint(painter, converter, paintContext); painter.restore(); if (pathShape.stroke()) { painter.save(); pathShape.stroke()->paint(d->shape, painter, converter); painter.restore(); } }
void AdvancedImageWidget::drawResized(QPainter &painter) { //qDebug("AdvancedImageWidget::drawResized():called"); if (mImage.isNull()) { qDebug("AdvancedImageWidget::drawResized():image is null"); painter.drawText(0,0, this->width(), this->height(), Qt::AlignHCenter | Qt::AlignVCenter, QString("NO ACTIVE IMAGE")); return; } if (mUi->rotationComboBox->currentIndex() == 0) { painter.drawImage(mOutputRect, *mImage, mInputRect); return; } // qDebug() << "Input" << mInputRect; // qDebug() << "Output" << mOutputRect; Matrix33 matrix = currentTransformMatrix(); // cout << "Transfrom Matrix:\n" << matrix << std::endl << std::flush; QTransform transform = Core2Qt::QTransformFromMatrix(matrix); // qDebug() << "QTransfrom" << transform; QTransform old = painter.transform(); painter.setTransform(transform, false); painter.drawImage(mOutputRect.topLeft(), *mImage, mImage->rect()); #if 0 painter.setPen(Qt::red); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { painter.drawPoint(i * 64, j * 48); } } #endif painter.setTransform(old); }
void KoPathToolSelection::paint(QPainter &painter, const KoViewConverter &converter) { int handleRadius = m_tool->canvas()->shapeController()->resourceManager()->handleRadius(); PathShapePointMap::iterator it(m_shapePointMap.begin()); for (; it != m_shapePointMap.end(); ++it) { painter.save(); painter.setTransform(it.key()->absoluteTransformation(&converter) * painter.transform()); KoShape::applyConversion(painter, converter); foreach(KoPathPoint *p, it.value()) p->paint(painter, handleRadius, KoPathPoint::All); painter.restore(); } }
void RightToLeftPaintingStrategy::paint(KoShape *shape, QPainter &painter, const KoViewConverter &converter, bool forPrint) { painter.save(); const double width = d->canvas->canvasWidget()->width(); // const double offsetX = d->canvas->canvasController()->canvasOffsetX(); painter.translate(/*-2 * offsetX*/ + width, 0); // painter.scale(-1, 1); painter.setTransform(shape->absoluteTransformation(&converter) * painter.transform()); if (shapeManager()) { shapeManager()->paintShape(shape, painter, converter, forPrint); } painter.restore(); // for the matrix }
static void drawTextEx(QPainter &p, const QRectF &r, int fl, const QString &s, bool mirrorX = 0, bool mirrorY = 0) { QTransform t = p.transform(); qreal hw = 0.5*r.width(), hh = 0.5*r.height(); p.setTransform(QTransform(mirrorX ? -1:1, 0, 0, mirrorY ? -1:1, r.x() + hw, r.y() + hh), 1); if(mirrorX) { if(fl&Qt::AlignLeft) fl &= ~Qt::AlignLeft, fl |= Qt::AlignRight; else if(fl&Qt::AlignRight) fl &= ~Qt::AlignRight, fl |= Qt::AlignLeft; } if(mirrorY) { if(fl&Qt::AlignTop) fl &= ~Qt::AlignTop, fl |= Qt::AlignBottom; else if(fl&Qt::AlignBottom) fl &= ~Qt::AlignBottom, fl |= Qt::AlignTop; } p.drawText(QRect(-hw, -hh, r.width(), r.height()), fl, s); p.setTransform(t); }
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 } } }
void Shape2D::draw(QPainter& painter) const { painter.setPen(m_color); this->drawShape(painter); if (m_editing) { QColor c(255,255,255,100); painter.setPen(c); painter.setCompositionMode(QPainter::CompositionMode_Plus); painter.drawRect(m_boundingRect.toQRectF()); for(size_t i = 0; i < getNControlPoints(); ++i) { QPointF p = painter.transform().map(getControlPoint(i)); QRectF r(p - QPointF(sizeCP,sizeCP),p + QPointF(sizeCP,sizeCP)); painter.save(); painter.resetTransform(); painter.fillRect(r,c); painter.restore(); } } }
void GraphicsContext::beginTransparencyLayer(float opacity) { if (paintingDisabled()) return; int x, y, w, h; x = y = 0; QPainter *p = m_data->p(); const QPaintDevice *device = p->device(); w = device->width(); h = device->height(); QRectF clip = p->clipPath().boundingRect(); QRectF deviceClip = p->transform().mapRect(clip); x = int(qBound(qreal(0), deviceClip.x(), (qreal)w)); y = int(qBound(qreal(0), deviceClip.y(), (qreal)h)); w = int(qBound(qreal(0), deviceClip.width(), (qreal)w) + 2); h = int(qBound(qreal(0), deviceClip.height(), (qreal)h) + 2); TransparencyLayer * layer = new TransparencyLayer(m_data->p(), QRect(x, y, w, h)); layer->opacity = opacity; m_data->layers.push(layer); }
void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn) { int i, row = 0, col = 0, printed = 0, total = estimateTotalDives(); struct dive *dive; if (!total) return; // setup a painter QPainter painter; painter.begin(printer); painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.scale(scaleX, scaleY); // setup the profile widget ProfileGraphicsView *profile = MainWindow::instance()->graphics(); const int profileFrameStyle = profile->frameStyle(); profile->setFrameStyle(QFrame::NoFrame); profile->clear(); profile->setPrintMode(true, !printOptions->color_selected); QSize originalSize = profile->size(); // swap rows/col for landscape if (printer->orientation() == QPrinter::Landscape) { int swap = divesPerColumn; divesPerColumn = divesPerRow; divesPerRow = swap; } // padding in pixels between two dives. no padding if only one dive per page. const int padDef = 20; const int padW = (divesPerColumn < 2) ? 0 : padDef; const int padH = (divesPerRow < 2) ? 0 : padDef; // estimate dimensions for a single dive const int scaledW = ESTIMATE_DIVE_DIM(scaledPageW, divesPerColumn, padW); const int scaledH = ESTIMATE_DIVE_DIM(scaledPageH, divesPerRow, padH); // padding in pixels between profile and table const int padPT = 5; // create a model and table ProfilePrintModel model; QTableView *table = createProfileTable(&model, scaledW); // profilePrintTableMaxH updates after the table is created const int tableH = profilePrintTableMaxH; // resize the profile widget profile->resize(scaledW, scaledH - tableH - padPT); // offset table or profile on top int yOffsetProfile = 0, yOffsetTable = 0; if (printOptions->notes_up) yOffsetProfile = tableH + padPT; else yOffsetTable = scaledH - tableH; // plot the dives at specific rows and columns on the page for_each_dive(i, dive) { if (!dive->selected && printOptions->print_selected) continue; if (col == divesPerColumn) { col = 0; row++; if (row == divesPerRow) { row = 0; printer->newPage(); } } QTransform origTransform = painter.transform(); // draw a profile painter.translate((scaledW + padW) * col, (scaledH + padH) * row + yOffsetProfile); profile->plot(dive, true); profile->render(&painter, QRect(0, 0, scaledW, scaledH - tableH - padPT)); painter.setTransform(origTransform); // draw a table painter.translate((scaledW + padW) * col, (scaledH + padH) * row + yOffsetTable); model.setDive(dive); table->render(&painter); painter.setTransform(origTransform); col++; printed++; emit signalProgress((printed * 100) / total); } // cleanup painter.end(); delete table; profile->setFrameStyle(profileFrameStyle); profile->setPrintMode(false); profile->resize(originalSize); profile->clear(); profile->plot(current_dive, true); }
void TransferFunctionEditor::drawGrid(QPainter & painter, int w, int h) { QColor c(128, 128, 128, 128); QPen pen(c); pen.setWidth(1); QBrush brush(c); painter.setPen(pen); painter.setBrush(brush); // vykreslenie samotnej mriezky painter.setRenderHint(QPainter::Antialiasing, false); painter.setRenderHint(QPainter::HighQualityAntialiasing, false); const int vert_step = 20; const int horz_step = 10; // horizontalne ciary mriezky for (int i = INNER_PADDING_BOTTOM; i < h - INNER_PADDING_TOP; i += horz_step) { painter.drawLine(INNER_PADDING_LEFT, h - i, w - INNER_PADDING_RIGHT, h - i); } // vertikalne ciary mriezky for (int i = INNER_PADDING_LEFT; i < w - INNER_PADDING_RIGHT; i += vert_step) { painter.drawLine(i, INNER_PADDING_TOP, i, h - INNER_PADDING_BOTTOM); } painter.setRenderHint(QPainter::Antialiasing, true); painter.setRenderHint(QPainter::HighQualityAntialiasing, true); pen.setWidth(2); painter.setPen(pen); // vykreslenie horizontalnej osi const QPointF triangle_horz[3] = { QPointF(w - INNER_PADDING_RIGHT + EXTRA_INNNER_PADDING_RIGHT, h - INNER_PADDING_BOTTOM - 2.5f), QPointF(w - INNER_PADDING_RIGHT + EXTRA_INNNER_PADDING_RIGHT + AXIS_ARROW_SIZE, h - INNER_PADDING_BOTTOM + 0.0f), QPointF(w - INNER_PADDING_RIGHT + EXTRA_INNNER_PADDING_RIGHT, h - INNER_PADDING_BOTTOM + 2.5f) }; painter.drawLine(INNER_PADDING_LEFT, h - INNER_PADDING_BOTTOM, w - INNER_PADDING_RIGHT + EXTRA_INNNER_PADDING_RIGHT, h - INNER_PADDING_BOTTOM); painter.drawPolygon(triangle_horz, 3); // vykreslenie vertikalnej osi const QPointF triangle_vert[3] = { // x y QPointF(INNER_PADDING_LEFT - 2.5f, INNER_PADDING_TOP - EXTRA_INNNER_PADDING_TOP), // lavy bod QPointF(INNER_PADDING_LEFT + 2.5f, INNER_PADDING_TOP - EXTRA_INNNER_PADDING_TOP), // pravy bod QPointF(INNER_PADDING_LEFT + 0.0f, INNER_PADDING_TOP - EXTRA_INNNER_PADDING_TOP - AXIS_ARROW_SIZE) // stredny bod }; painter.drawLine(INNER_PADDING_LEFT, h - INNER_PADDING_BOTTOM, INNER_PADDING_LEFT, INNER_PADDING_TOP - EXTRA_INNNER_PADDING_TOP); painter.drawPolygon(triangle_vert, 3); // vykreslenie horizontalneho popisku painter.drawStaticText(w - INNER_PADDING_RIGHT - 40, h - INNER_PADDING_BOTTOM + 2, QStaticText("intensity")); // vykreslenie vertikalneho popisku { QTransform old_t = painter.transform(); QTransform t; t.translate(0, INNER_PADDING_TOP + 30); t.rotate(-90); painter.setTransform(t); painter.drawStaticText(0, 0, QStaticText("opacity")); painter.setTransform(old_t); } }
void PixmapCachingSheetView::paintCells(QPainter& painter, const QRectF& paintRect, const QPointF& topLeft, CanvasBase* canvas, const QRect& visibleRect) { if (!canvas) { SheetView::paintCells(painter, paintRect, topLeft, canvas, visibleRect); return; } // paintRect: the canvas area, that should be painted; in document coordinates; // no layout direction consideration; scrolling offset applied; // independent from painter transformations // topLeft: the document coordinate of the top left cell's top left corner; // no layout direction consideration; independent from painter // transformations QTransform t = painter.transform(); // figure out scaling from the transformation... not really perfect, but should work as long as rotation is in 90 degree steps I think const qreal cos_sx = t.m11(); const qreal sin_sx = t.m12(); const qreal msin_sy = t.m21(); const qreal cos_sy = t.m22(); const qreal sx = sqrt(cos_sx*cos_sx + sin_sx*sin_sx); const qreal sy = sqrt(cos_sy*cos_sy + msin_sy*msin_sy); //const qreal cost = (sx > 1e-10 ? cos_sx / sx : cos_sy / sy); //const qreal ang = acos(cost); QPointF scale = QPointF(sx, sy); if (scale != d->lastScale) { d->tileCache.clear(); } d->lastScale = scale; QRect tiles; const QRect visibleCells = paintCellRange(); const Sheet * s = sheet(); const QPointF bottomRight(s->columnPosition(visibleCells.right() + 1), s->rowPosition(visibleCells.bottom() + 1)); tiles.setLeft(topLeft.x() * sx / TILESIZE); tiles.setTop(topLeft.y() * sy / TILESIZE); tiles.setRight((bottomRight.x() * sx + TILESIZE-1) / TILESIZE); tiles.setBottom((bottomRight.y() * sy + TILESIZE-1) / TILESIZE); bool rtl = s->layoutDirection() == Qt::RightToLeft; if (rtl) { for (int x = qMax(0, tiles.left()); x < tiles.right(); x++) { for (int y = qMax(0, tiles.top()); y < tiles.bottom(); y++) { QPixmap *p = d->getTile(s, x, y, canvas); if (p) { QPointF pt(paintRect.width() - (x+1) * TILESIZE / scale.x(), y * TILESIZE / scale.y()); QRectF r(pt, QSizeF(TILESIZE / sx, TILESIZE / sy)); painter.drawPixmap(r, *p, p->rect()); } } } } else { for (int x = qMax(0, tiles.left()); x < tiles.right(); x++) { for (int y = qMax(0, tiles.top()); y < tiles.bottom(); y++) { QPixmap *p = d->getTile(s, x, y, canvas); if (p) { QPointF pt(x * TILESIZE / scale.x(), y * TILESIZE / scale.y()); QRectF r(pt, QSizeF(TILESIZE / sx, TILESIZE / sy)); painter.drawPixmap(r, *p, p->rect()); } } } } }
void KWCopyShape::paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &paintcontext) { Q_ASSERT(m_original); //paint all child shapes KoShapeContainer* container = dynamic_cast<KoShapeContainer*>(m_original); if (container) { QList<KoShape*> sortedObjects = container->shapes(); sortedObjects.append(m_original); qSort(sortedObjects.begin(), sortedObjects.end(), KoShape::compareShapeZIndex); // Do the following to revert the absolute transformation of the // container that is re-applied in shape->absoluteTransformation() // later on. The transformation matrix of the container has already // been applied once before this function is called. QTransform baseMatrix = container->absoluteTransformation(&converter).inverted() * painter.transform(); KWPage copypage = m_pageManager->page(this); Q_ASSERT(copypage.isValid()); foreach(KoShape *shape, sortedObjects) { painter.save(); if (shape != m_original) { painter.setTransform(shape->absoluteTransformation(&converter) * baseMatrix); } KoTextShapeData *data = qobject_cast<KoTextShapeData*>(shape->userData()); if (data == 0) { shape->paint(painter, converter, paintcontext); } else { // Since the rootArea is shared between the copyShape and the originalShape we need to // temporary switch the used KoTextPage to be sure the proper page-numbers are displayed. KWPage originalpage = m_pageManager->page(shape); Q_ASSERT(originalpage.isValid()); KoTextLayoutRootArea *area = data->rootArea(); bool wasBlockChanges = false; if (area) { // We need to block documentChanged() signals emitted cause for example page-variables // may change there content to result in us marking root-areas dirty for relayout else // we could end in an infinite relayout ping-pong. wasBlockChanges = area->documentLayout()->changesBlocked(); area->documentLayout()->setBlockChanges(true); area->setPage(new KWPage(copypage)); } shape->paint(painter, converter, paintcontext); if (area) { area->setPage(new KWPage(originalpage)); area->documentLayout()->setBlockChanges(wasBlockChanges); } } painter.restore(); if (shape->stroke()) { painter.save(); painter.setTransform(shape->absoluteTransformation(&converter) * baseMatrix); shape->stroke()->paint(shape, painter, converter); painter.restore(); } } } else {
void PaintMethods::paintDebugDrawing(QPainter& painter, const DebugDrawing& debugDrawing, const QTransform& baseTrans) { static QBrush brush(Qt::SolidPattern); static QBrush noBrush(Qt::NoBrush); static QPen pen; static QPen noPen(Qt::NoPen); for(const DebugDrawing::Element* e = debugDrawing.getFirst(); e; e = debugDrawing.getNext(e)) switch(e->type) { case DebugDrawing::Element::POLYGON: { const DebugDrawing::Polygon& element = *(const DebugDrawing::Polygon*) e; // select brush if(element.fillStyle == Drawings::bs_solid) { brush.setColor(QColor(element.fillColor.r, element.fillColor.g, element.fillColor.b, element.fillColor.a)); painter.setBrush(brush); } else painter.setBrush(noBrush); // select pen if(element.penStyle != Drawings::ps_null) { pen.setColor(QColor(element.penColor.r, element.penColor.g, element.penColor.b, element.penColor.a)); // A line width of zero indicates a cosmetic pen. This means that the pen width is always drawn one pixel wide, independent of the transformation set on the painter. pen.setWidth(element.width); switch(element.penStyle) { case Drawings::ps_dash: pen.setStyle(Qt::DashLine); break; case Drawings::ps_dot: pen.setStyle(Qt::DotLine); break; case Drawings::ps_solid: default: pen.setStyle(Qt::SolidLine); } painter.setPen(pen); } else painter.setPen(noPen); // copy vector2 to QPoints static QPoint points[16]; for(int n = element.nCount - 1; n >= 0 ; --n) points[n] = QPoint(element.points[n].x, element.points[n].y); painter.drawPolygon(points, element.nCount); break; } case DebugDrawing::Element::GRID_RGBA: { const DebugDrawing::GridRGBA& element = *(const DebugDrawing::GridRGBA*) e; const int totalWidth(element.cellsX * element.cellSize); const int totalHeight(element.cellsY * element.cellSize); for(int y = 0; y < element.cellsY; ++y) { for(int x = 0; x < element.cellsX; ++x) { int startX(x * element.cellSize - totalWidth / 2); int startY(y * element.cellSize - totalHeight / 2); int c(y * element.cellsX + x); brush.setColor(QColor(element.cells[c].r, element.cells[c].g, element.cells[c].b, element.cells[c].a)); pen.setColor(QColor(element.cells[c].r, element.cells[c].g, element.cells[c].b, element.cells[c].a)); pen.setWidth(1); painter.setBrush(brush); painter.setPen(pen); painter.drawRect(startX, startY, element.cellSize - 1, element.cellSize - 1); } } break; } case DebugDrawing::Element::GRID_MONO: { const DebugDrawing::GridMono& element = *(const DebugDrawing::GridMono*) e; const int totalWidth(element.cellsX * element.cellSize); const int totalHeight(element.cellsY * element.cellSize); for(int y = 0; y < element.cellsY; ++y) { for(int x = 0; x < element.cellsX; ++x) { int startX(x * element.cellSize - totalWidth / 2); int startY(y * element.cellSize - totalHeight / 2); int c(y * element.cellsX + x); ColorRGBA col(element.baseColor * (1.0f - (static_cast<float>(element.cells[c]) / 255.0))); brush.setColor(QColor(col.r, col.g, col.b, element.baseColor.a)); pen.setColor(QColor(col.r, col.g, col.b, element.baseColor.a)); pen.setWidth(1); painter.setBrush(brush); painter.setPen(pen); painter.drawRect(startX, startY, element.cellSize - 1, element.cellSize - 1); } } break; } case DebugDrawing::Element::ELLIPSE: { const DebugDrawing::Ellipse& element = *(const DebugDrawing::Ellipse*) e; // select brush if(element.fillStyle == Drawings::bs_solid) { brush.setColor(QColor(element.fillColor.r, element.fillColor.g, element.fillColor.b, element.fillColor.a)); painter.setBrush(brush); } else painter.setBrush(noBrush); // select pen if(element.penStyle != Drawings::ps_null) { pen.setColor(QColor(element.penColor.r, element.penColor.g, element.penColor.b, element.penColor.a)); // A line width of zero indicates a cosmetic pen. This means that the pen width is always drawn one pixel wide, independent of the transformation set on the painter. pen.setWidth(element.width); switch(element.penStyle) { case Drawings::ps_dash: pen.setStyle(Qt::DashLine); break; case Drawings::ps_dot: pen.setStyle(Qt::DotLine); break; case Drawings::ps_solid: default: pen.setStyle(Qt::SolidLine); } painter.setPen(pen); } else painter.setPen(noPen); if(element.rotation != 0.0f) { QTransform trans(painter.transform()); QTransform transBack(painter.transform()); trans.translate(qreal(element.x), qreal(element.y)); trans.rotateRadians(qreal(element.rotation)); painter.setTransform(trans); painter.drawEllipse(-element.radiusX, -element.radiusY, 2 * element.radiusX, 2 * element.radiusY); painter.setTransform(transBack); } else { painter.drawEllipse(element.x - element.radiusX, element.y - element.radiusY, 2 * element.radiusX, 2 * element.radiusY); } break; } case DebugDrawing::Element::LINE: { const DebugDrawing::Line& element = *(const DebugDrawing::Line*) e; if(element.penStyle != Drawings::ps_null) { pen.setColor(QColor(element.penColor.r, element.penColor.g, element.penColor.b, element.penColor.a)); // A line width of zero indicates a cosmetic pen. This means that the pen width is always drawn one pixel wide, independent of the transformation set on the painter. pen.setWidth(element.width); switch(element.penStyle) { case Drawings::ps_dash: pen.setStyle(Qt::DashLine); break; case Drawings::ps_dot: pen.setStyle(Qt::DotLine); break; case Drawings::ps_solid: default: pen.setStyle(Qt::SolidLine); } painter.setPen(pen); painter.drawLine(element.xStart, element.yStart, element.xEnd, element.yEnd); } break; } case DebugDrawing::Element::ORIGIN: { const DebugDrawing::Origin& element = *(const DebugDrawing::Origin*) e; QTransform trans(baseTrans); trans.translate(qreal(element.x), qreal(element.y)); trans.rotateRadians(qreal(element.angle)); painter.setTransform(trans); break; } case DebugDrawing::Element::TEXT: { const DebugDrawing::Text& element = *(const DebugDrawing::Text*) e; pen.setColor(QColor(element.penColor.r, element.penColor.g, element.penColor.b, element.penColor.a)); painter.setPen(pen); QTransform trans(painter.transform()); const QPoint& pos(trans.map(QPoint(element.x, element.y))); painter.resetTransform(); painter.drawText(pos, (const char*)(&element + 1)); painter.setTransform(trans); break; } default: break; } }
void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn) { int i, row = 0, col = 0, printed = 0, total = estimateTotalDives(); int animationOriginal = prefs.animation_speed; struct dive *dive; if (!total) return; // disable animations on the profile: prefs.animation_speed = 0; // setup a painter QPainter painter; painter.begin(printer); painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::SmoothPixmapTransform); // setup the profile widget QPointer<ProfileWidget2> profile = MainWindow::instance()->graphics(); const int profileFrameStyle = profile->frameStyle(); profile->setFrameStyle(QFrame::NoFrame); profile->setPrintMode(true, !printOptions->color_selected); profile->setFontPrintScale(divesPerRow * divesPerColumn > 3 ? 0.6 : 1.0); QSize originalSize = profile->size(); // swap rows/col for landscape if (printer->orientation() == QPrinter::Landscape) { int swap = divesPerColumn; divesPerColumn = divesPerRow; divesPerRow = swap; } // padding in pixels between two dives. no padding if only one dive per page. const int padDef = 20; const int padW = (divesPerColumn < 2) ? 0 : padDef; const int padH = (divesPerRow < 2) ? 0 : padDef; // estimate dimensions for a single dive const int scaledW = ESTIMATE_DIVE_DIM(pageW, divesPerColumn, padW); const int scaledH = ESTIMATE_DIVE_DIM(pageH, divesPerRow, padH); // padding in pixels between profile and table const int padPT = 5; // create a model and table ProfilePrintModel model; model.setFontsize(7); // if this is changed we also need to change 'const int sr' in the constructor // if there is only one dive per page row we pass fitNotesToHeight to be almost half the page height QPointer<QTableView> table(createProfileTable(&model, scaledW, (divesPerRow == 1) ? scaledH * 0.45 : 0.0)); // profilePrintTableMaxH updates after the table is created const int tableH = profilePrintTableMaxH; // resize the profile widget profile->resize(scaledW, scaledH - tableH - padPT); // offset table or profile on top int yOffsetProfile = 0, yOffsetTable = 0; if (printOptions->notes_up) yOffsetProfile = tableH + padPT; else yOffsetTable = scaledH - tableH; // plot the dives at specific rows and columns on the page for_each_dive (i, dive) { if (!dive->selected && printOptions->print_selected) continue; if (col == divesPerColumn) { col = 0; row++; if (row == divesPerRow) { row = 0; printer->newPage(); } } // draw a profile QTransform origTransform = painter.transform(); painter.translate((scaledW + padW) * col, (scaledH + padH) * row + yOffsetProfile); profile->plotDive(dive, true); // make sure the profile is actually redrawn #ifdef Q_OS_LINUX // on Linux there is a vector line bug (big lines in PDF), which forces us to render to QImage QImage image(scaledW, scaledH - tableH - padPT, QImage::Format_ARGB32); QPainter imgPainter(&image); imgPainter.setRenderHint(QPainter::Antialiasing); imgPainter.setRenderHint(QPainter::SmoothPixmapTransform); profile->render(&imgPainter, QRect(0, 0, scaledW, scaledH - tableH - padPT)); imgPainter.end(); painter.drawImage(image.rect(),image); #else // for other OS we can try rendering the profile as vector profile->render(&painter, QRect(0, 0, scaledW, scaledH - tableH - padPT)); #endif painter.setTransform(origTransform); // draw a table QPicture pic; QPainter picPainter; painter.translate((scaledW + padW) * col, (scaledH + padH) * row + yOffsetTable); model.setDive(dive); picPainter.begin(&pic); table->render(&picPainter); picPainter.end(); painter.drawPicture(QPoint(0,0), pic); painter.setTransform(origTransform); col++; printed++; emit signalProgress((printed * 100) / total); } // cleanup painter.end(); profile->setFrameStyle(profileFrameStyle); profile->setPrintMode(false); profile->resize(originalSize); // we need to force a redraw of the profile so it switches back from print mode profile->plotDive(0, true); // re-enable animations prefs.animation_speed = animationOriginal; }
void ConnectionTool::paint(QPainter &painter, const KoViewConverter &converter) { // get the correctly sized rect for painting handles QRectF handleRect = handlePaintRect(QPointF()); painter.setRenderHint(QPainter::Antialiasing, true); if (m_currentStrategy) { painter.save(); m_currentStrategy->paint(painter, converter); painter.restore(); } QList<KoShape*> shapes = canvas()->shapeManager()->shapes(); for (QList<KoShape*>::const_iterator end = shapes.constBegin(); end != shapes.constEnd(); ++end) { KoShape* shape = *end; if (!dynamic_cast<KoConnectionShape*>(shape)) { // only paint connection points of textShapes not inside a tos container and other shapes if (shape->shapeId() == TextShape_SHAPEID && dynamic_cast<KoTosContainer*>(shape->parent())) continue; painter.save(); painter.setPen(Qt::black); QTransform transform = shape->absoluteTransformation(0); KoShape::applyConversion(painter, converter); // Draw all the connection points of the shape KoConnectionPoints connectionPoints = shape->connectionPoints(); KoConnectionPoints::const_iterator cp = connectionPoints.constBegin(); KoConnectionPoints::const_iterator lastCp = connectionPoints.constEnd(); for(; cp != lastCp; ++cp) { if (shape == findNonConnectionShapeAtPosition(transform.map(cp.value().position)) ) { handleRect.moveCenter(transform.map(cp.value().position)); painter.setBrush(cp.key() == m_activeHandle && shape == m_currentShape ? Qt::red : Qt::white); painter.drawRect(handleRect); } } painter.restore(); } } // paint connection points or connection handles depending // on the shape the mouse is currently if (m_currentShape && m_editMode == EditConnection) { KoConnectionShape *connectionShape = dynamic_cast<KoConnectionShape*>(m_currentShape); if (connectionShape) { int radius = handleRadius()+1; int handleCount = connectionShape->handleCount(); for(int i = 0; i < handleCount; ++i) { painter.save(); painter.setPen(Qt::blue); painter.setBrush(i == m_activeHandle ? Qt::red : Qt::white); painter.setTransform(connectionShape->absoluteTransformation(&converter) * painter.transform()); connectionShape->paintHandle(painter, converter, i, radius); painter.restore(); } } } }
void PictureShape::paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &paintContext) { Q_UNUSED(paintContext); QRectF viewRect = converter.documentToView(QRectF(QPointF(0,0), size())); if (imageData() == 0) { painter.fillRect(viewRect, QColor(Qt::gray)); return; } painter.save(); applyConversion(painter, converter); paintBorder(painter, converter); painter.restore(); QSize pixmapSize = calcOptimalPixmapSize(viewRect.size(), imageData()->image().size()); // Normalize the clipping rect if it isn't already done. m_clippingRect.normalize(imageData()->imageSize()); // Handle style:mirror, i.e. mirroring horizontally and/or vertically. // // NOTE: At this time we don't handle HorizontalOnEven // and HorizontalOnOdd, which have to know which // page they are on. In those cases we treat it as // no horizontal mirroring at all. bool doFlip = false; QSizeF shapeSize = size(); QSizeF viewSize = converter.documentToView(shapeSize); qreal midpointX = 0.0; qreal midpointY = 0.0; qreal scaleX = 1.0; qreal scaleY = 1.0; if (m_mirrorMode & MirrorHorizontal) { midpointX = viewSize.width() / qreal(2.0); scaleX = -1.0; doFlip = true; } if (m_mirrorMode & MirrorVertical) { midpointY = viewSize.height() / qreal(2.0); scaleY = -1.0; doFlip = true; } if (doFlip) { QTransform outputTransform = painter.transform(); QTransform worldTransform = QTransform(); //kDebug(31000) << "Flipping" << midpointX << midpointY << scaleX << scaleY; worldTransform.translate(midpointX, midpointY); worldTransform.scale(scaleX, scaleY); worldTransform.translate(-midpointX, -midpointY); //kDebug(31000) << "After flipping for window" << worldTransform; QTransform newTransform = worldTransform * outputTransform; painter.setWorldTransform(newTransform); } // Paint the image as prepared in waitUntilReady() if (!m_printQualityImage.isNull() && pixmapSize != m_printQualityRequestedSize) { QSizeF imageSize = m_printQualityImage.size(); QRectF cropRect( imageSize.width() * m_clippingRect.left, imageSize.height() * m_clippingRect.top, imageSize.width() * m_clippingRect.width(), imageSize.height() * m_clippingRect.height() ); painter.drawImage(viewRect, m_printQualityImage, cropRect); m_printQualityImage = QImage(); // free memory } else { QPixmap pixmap; QString key(generate_key(imageData()->key(), pixmapSize)); // If the required pixmap is not in the cache // launch a task in a background thread that scales // the source image to the required size if (!QPixmapCache::find(key, &pixmap)) { QThreadPool::globalInstance()->start(new _Private::PixmapScaler(this, pixmapSize)); painter.fillRect(viewRect, QColor(Qt::gray)); // just paint a gray rect as long as we don't have the required pixmap } else { QRectF cropRect( pixmapSize.width() * m_clippingRect.left, pixmapSize.height() * m_clippingRect.top, pixmapSize.width() * m_clippingRect.width(), pixmapSize.height() * m_clippingRect.height() ); painter.drawPixmap(viewRect, pixmap, cropRect); } } }