/*! Fill a pixmap with the content of a widget In Qt >= 5.0 QPixmap::fill() is a nop, in Qt 4.x it is buggy for backgrounds with gradients. Thus fillPixmap() offers an alternative implementation. \param widget Widget \param pixmap Pixmap to be filled \param offset Offset \sa QPixmap::fill() */ void QwtPainter::fillPixmap( const QWidget *widget, QPixmap &pixmap, const QPoint &offset ) { const QRect rect( offset, pixmap.size() ); QPainter painter( &pixmap ); painter.translate( -offset ); const QBrush autoFillBrush = widget->palette().brush( widget->backgroundRole() ); if ( !( widget->autoFillBackground() && autoFillBrush.isOpaque() ) ) { const QBrush bg = widget->palette().brush( QPalette::Window ); qwtFillRect( widget, &painter, rect, bg); } if ( widget->autoFillBackground() ) qwtFillRect( widget, &painter, rect, autoFillBrush); if ( widget->testAttribute(Qt::WA_StyledBackground) ) { painter.setClipRegion( rect ); QStyleOption opt; opt.initFrom( widget ); widget->style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, widget ); } }
/* Should we require that q is a toplevel window ??? Used by QWSManager */ void QWidgetPrivate::blitToScreen(const QRegion &globalrgn) { Q_Q(QWidget); QWidget *win = q->window(); QBrush bgBrush = win->palette().brush(win->backgroundRole()); bool opaque = bgBrush.style() == Qt::NoBrush || bgBrush.isOpaque(); QWidget::qwsDisplay()->repaintRegion(win->data->winid, win->windowFlags(), opaque, globalrgn); }
void fillOpaqueRect(QPainter *painter, const QRect &rect, const QBrush &brush) { if (!brush.isOpaque()) { QPixmap chessboardPattern(16, 16); QPainter patternPainter(&chessboardPattern); patternPainter.fillRect(0, 0, 8, 8, Qt::black); patternPainter.fillRect(8, 8, 8, 8, Qt::black); patternPainter.fillRect(0, 8, 8, 8, Qt::white); patternPainter.fillRect(8, 0, 8, 8, Qt::white); patternPainter.end(); painter->fillRect(rect, QBrush(chessboardPattern)); } painter->fillRect(rect, brush); }
void KoOdfGraphicStyles::saveOdfFillStyle(KoGenStyle &styleFill, KoGenStyles& mainStyles, const QBrush & brush) { KoGenStyle::Type type = styleFill.type(); KoGenStyle::PropertyType propertyType = (type == KoGenStyle::GraphicStyle || type == KoGenStyle::GraphicAutoStyle || type == KoGenStyle::DrawingPageStyle || type == KoGenStyle::DrawingPageAutoStyle ) ? KoGenStyle::DefaultType : KoGenStyle::GraphicType; switch (brush.style()) { case Qt::Dense1Pattern: styleFill.addProperty("draw:opacity", "6%", propertyType); styleFill.addProperty("draw:fill", "solid", propertyType); styleFill.addProperty("draw:fill-color", brush.color().name(), propertyType); break; case Qt::Dense2Pattern: styleFill.addProperty("draw:opacity", "12%", propertyType); styleFill.addProperty("draw:fill", "solid", propertyType); styleFill.addProperty("draw:fill-color", brush.color().name(), propertyType); break; case Qt::Dense3Pattern: styleFill.addProperty("draw:opacity", "37%", propertyType); styleFill.addProperty("draw:fill", "solid", propertyType); styleFill.addProperty("draw:fill-color", brush.color().name(), propertyType); break; case Qt::Dense4Pattern: styleFill.addProperty("draw:opacity", "50%", propertyType); styleFill.addProperty("draw:fill", "solid", propertyType); styleFill.addProperty("draw:fill-color", brush.color().name(), propertyType); break; case Qt::Dense5Pattern: styleFill.addProperty("draw:opacity", "63%", propertyType); styleFill.addProperty("draw:fill", "solid", propertyType); styleFill.addProperty("draw:fill-color", brush.color().name(), propertyType); break; case Qt::Dense6Pattern: styleFill.addProperty("draw:opacity", "88%", propertyType); styleFill.addProperty("draw:fill", "solid", propertyType); styleFill.addProperty("draw:fill-color", brush.color().name(), propertyType); break; case Qt::Dense7Pattern: styleFill.addProperty("draw:opacity", "94%", propertyType); styleFill.addProperty("draw:fill", "solid", propertyType); styleFill.addProperty("draw:fill-color", brush.color().name(), propertyType); break; case Qt::LinearGradientPattern: case Qt::RadialGradientPattern: case Qt::ConicalGradientPattern: styleFill.addProperty("draw:fill", "gradient", propertyType); styleFill.addProperty("draw:fill-gradient-name", saveOdfGradientStyle(mainStyles, brush), propertyType); break; case Qt::HorPattern: case Qt::VerPattern: case Qt::CrossPattern: case Qt::BDiagPattern: case Qt::FDiagPattern: case Qt::DiagCrossPattern: styleFill.addProperty("draw:fill", "hatch", propertyType); styleFill.addProperty("draw:fill-hatch-name", saveOdfHatchStyle(mainStyles, brush), propertyType); break; case Qt::SolidPattern: styleFill.addProperty("draw:fill", "solid", propertyType); styleFill.addProperty("draw:fill-color", brush.color().name(), propertyType); if (! brush.isOpaque()) styleFill.addProperty("draw:opacity", QString("%1%").arg(brush.color().alphaF() * 100.0), propertyType); break; case Qt::NoBrush: default: styleFill.addProperty("draw:fill", "none", propertyType); break; } }
int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject) { const QGradient *gradient = b.gradient(); if (!gradient) return 0; QTransform inv = matrix.inverted(); QPointF page_rect[4] = { inv.map(QPointF(0, 0)), inv.map(QPointF(width_, 0)), inv.map(QPointF(0, height_)), inv.map(QPointF(width_, height_)) }; bool opaque = b.isOpaque(); QByteArray shader; QByteArray alphaShader; if (gradient->type() == QGradient::LinearGradient) { const QLinearGradient *lg = static_cast<const QLinearGradient *>(gradient); shader = QPdf::generateLinearGradientShader(lg, page_rect); if (!opaque) alphaShader = QPdf::generateLinearGradientShader(lg, page_rect, true); } else { // ############# return 0; } int shaderObject = addXrefEntry(-1); write(shader); QByteArray str; QPdf::ByteStream s(&str); s << "<<\n" "/Type /Pattern\n" "/PatternType 2\n" "/Shading " << shaderObject << "0 R\n" "/Matrix [" << matrix.m11() << matrix.m12() << matrix.m21() << matrix.m22() << matrix.dx() << matrix.dy() << "]\n"; s << ">>\n" "endobj\n"; int patternObj = addXrefEntry(-1); write(str); currentPage->patterns.append(patternObj); if (!opaque) { bool ca = true; QGradientStops stops = gradient->stops(); int a = stops.at(0).second.alpha(); for (int i = 1; i < stops.size(); ++i) { if (stops.at(i).second.alpha() != a) { ca = false; break; } } if (ca) { *gStateObject = addConstantAlphaObject(stops.at(0).second.alpha()); } else { int alphaShaderObject = addXrefEntry(-1); write(alphaShader); QByteArray content; QPdf::ByteStream c(&content); c << "/Shader" << alphaShaderObject << "sh\n"; QByteArray form; QPdf::ByteStream f(&form); f << "<<\n" "/Type /XObject\n" "/Subtype /Form\n" "/BBox [0 0 " << width_ << height_ << "]\n" "/Group <</S /Transparency >>\n" "/Resources <<\n" "/Shading << /Shader" << alphaShaderObject << alphaShaderObject << "0 R >>\n" ">>\n"; f << "/Length " << content.length() << "\n" ">>\n" "stream\n" << content << "endstream\n" "endobj\n"; int softMaskFormObject = addXrefEntry(-1); write(form); *gStateObject = addXrefEntry(-1); xprintf("<< /SMask << /S /Alpha /G %d 0 R >> >>\n" "endobj\n", softMaskFormObject); currentPage->graphicStates.append(*gStateObject); } } return patternObj; }
void KoOdfGraphicStyles::saveOdfFillStyle(KoGenStyle &styleFill, KoGenStyles& mainStyles, const QBrush & brush) { switch (brush.style()) { case Qt::Dense1Pattern: styleFill.addProperty("draw:transparency", "94%"); styleFill.addProperty("draw:fill", "solid"); styleFill.addProperty("draw:fill-color", brush.color().name()); break; case Qt::Dense2Pattern: styleFill.addProperty("draw:transparency", "88%"); styleFill.addProperty("draw:fill", "solid"); styleFill.addProperty("draw:fill-color", brush.color().name()); break; case Qt::Dense3Pattern: styleFill.addProperty("draw:transparency", "63%"); styleFill.addProperty("draw:fill", "solid"); styleFill.addProperty("draw:fill-color", brush.color().name()); break; case Qt::Dense4Pattern: styleFill.addProperty("draw:transparency", "50%"); styleFill.addProperty("draw:fill", "solid"); styleFill.addProperty("draw:fill-color", brush.color().name()); break; case Qt::Dense5Pattern: styleFill.addProperty("draw:transparency", "37%"); styleFill.addProperty("draw:fill", "solid"); styleFill.addProperty("draw:fill-color", brush.color().name()); break; case Qt::Dense6Pattern: styleFill.addProperty("draw:transparency", "12%"); styleFill.addProperty("draw:fill", "solid"); styleFill.addProperty("draw:fill-color", brush.color().name()); break; case Qt::Dense7Pattern: styleFill.addProperty("draw:transparency", "6%"); styleFill.addProperty("draw:fill", "solid"); styleFill.addProperty("draw:fill-color", brush.color().name()); break; case Qt::LinearGradientPattern: case Qt::RadialGradientPattern: case Qt::ConicalGradientPattern: styleFill.addProperty("draw:fill", "gradient"); styleFill.addProperty("draw:fill-gradient-name", saveOdfGradientStyle(mainStyles, brush)); break; case Qt::HorPattern: case Qt::VerPattern: case Qt::CrossPattern: case Qt::BDiagPattern: case Qt::FDiagPattern: case Qt::DiagCrossPattern: styleFill.addProperty("draw:fill", "hatch"); styleFill.addProperty("draw:fill-hatch-name", saveOdfHatchStyle(mainStyles, brush)); break; case Qt::SolidPattern: styleFill.addProperty("draw:fill", "solid"); styleFill.addProperty("draw:fill-color", brush.color().name()); if (! brush.isOpaque()) styleFill.addProperty("draw:opacity", QString("%1%").arg(brush.color().alphaF() * 100.0)); break; case Qt::NoBrush: default: styleFill.addProperty("draw:fill", "none"); break; } }
void BaseEditor::paintEvent(QPaintEvent *e) { //copy from QPlainTextEditor QPainter painter(viewport()); Q_ASSERT(qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout())); QPointF offset(contentOffset()); QRect er = e->rect(); QRect viewportRect = viewport()->rect(); bool editable = !isReadOnly(); QTextBlock block = firstVisibleBlock(); qreal maximumWidth = document()->documentLayout()->documentSize().width(); //margin qreal lineX = 0; if (conf->isDisplayRightColumnMargin()) { // Don't use QFontMetricsF::averageCharWidth here, due to it returning // a fractional size even when this is not supported by the platform. lineX = QFontMetricsF(document()->defaultFont()).width(QLatin1Char('X')) * conf->getRightMarginColumn() + offset.x() + 4; if (lineX < viewportRect.width()) { const QBrush background = QBrush(QColor(239, 239, 239)); painter.fillRect(QRectF(lineX, er.top(), viewportRect.width() - lineX, er.height()), background); const QColor col = (palette().base().color().value() > 128) ? Qt::black : Qt::white; const QPen pen = painter.pen(); painter.setPen(blendColors(background.isOpaque() ? background.color() : palette().base().color(), col, 32)); painter.drawLine(QPointF(lineX, er.top()), QPointF(lineX, er.bottom())); painter.setPen(pen); } } // Set a brush origin so that the WaveUnderline knows where the wave started painter.setBrushOrigin(offset); // keep right margin clean from full-width selection int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth) - document()->documentMargin(); er.setRight(qMin(er.right(), maxX)); painter.setClipRect(er); QAbstractTextDocumentLayout::PaintContext context = getPaintContext(); while (block.isValid()) { QRectF r = blockBoundingRect(block).translated(offset); QTextLayout *layout = block.layout(); if (!block.isVisible()) { offset.ry() += r.height(); block = block.next(); continue; } if (r.bottom() >= er.top() && r.top() <= er.bottom()) { QTextBlockFormat blockFormat = block.blockFormat(); QBrush bg = blockFormat.background(); if (bg != Qt::NoBrush) { QRectF contentsRect = r; contentsRect.setWidth(qMax(r.width(), maximumWidth)); fillBackground(&painter, contentsRect, bg); } QVector<QTextLayout::FormatRange> selections; int blpos = block.position(); int bllen = block.length(); for (int i = 0; i < context.selections.size(); ++i) { const QAbstractTextDocumentLayout::Selection &range = context.selections.at(i); const int selStart = range.cursor.selectionStart() - blpos; const int selEnd = range.cursor.selectionEnd() - blpos; if (selStart < bllen && selEnd > 0 && selEnd > selStart) { QTextLayout::FormatRange o; o.start = selStart; o.length = selEnd - selStart; o.format = range.format; selections.append(o); } else if (!range.cursor.hasSelection() && range.format.hasProperty(QTextFormat::FullWidthSelection) && block.contains(range.cursor.position())) { // for full width selections we don't require an actual selection, just // a position to specify the line. that's more convenience in usage. QTextLayout::FormatRange o; QTextLine l = layout->lineForTextPosition(range.cursor.position() - blpos); o.start = l.textStart(); o.length = l.textLength(); if (o.start + o.length == bllen - 1) ++o.length; // include newline o.format = range.format; selections.append(o); } } bool drawCursor = ((editable || (textInteractionFlags() & Qt::TextSelectableByKeyboard)) && context.cursorPosition >= blpos && context.cursorPosition < blpos + bllen); bool drawCursorAsBlock = drawCursor && overwriteMode() ; if (drawCursorAsBlock) { if (context.cursorPosition == blpos + bllen - 1) { drawCursorAsBlock = false; } else { QTextLayout::FormatRange o; o.start = context.cursorPosition - blpos; o.length = 1; o.format.setForeground(palette().base()); o.format.setBackground(palette().text()); selections.append(o); } } layout->draw(&painter, offset, selections, er); if ((drawCursor && !drawCursorAsBlock) || (editable && context.cursorPosition < -1 && !layout->preeditAreaText().isEmpty())) { int cpos = context.cursorPosition; if (cpos < -1) cpos = layout->preeditAreaPosition() - (cpos + 2); else cpos -= blpos; layout->drawCursor(&painter, offset, cpos, cursorWidth()); } } offset.ry() += r.height(); if (offset.y() > viewportRect.height()) break; block = block.next(); } if (backgroundVisible() && !block.isValid() && offset.y() <= er.bottom() && (centerOnScroll() || verticalScrollBar()->maximum() == verticalScrollBar()->minimum())) { painter.fillRect(QRect(QPoint((int)er.left(), (int)offset.y()), er.bottomRight()), palette().background()); } }