Example #1
0
void Shadow::draw(QPainter* painter)
{
    // if nothing to show outside the item, just draw source
    if ((blurRadius() + distance()) <= 0) {
        drawSource(painter);
        return;
    }

    PixmapPadMode mode = QGraphicsEffect::PadToEffectiveBoundingRect;
    QPoint offset;
    const QPixmap px = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);

    // return if no source
    if (px.isNull())
        return;

    // save world transform
    QTransform restoreTransform = painter->worldTransform();
    painter->setWorldTransform(QTransform());

    // Calculate size for the background image
    QSize szi(px.size().width() + 2 * distance(), px.size().height() + 2 * distance());

    QImage tmp(szi, QImage::Format_ARGB32_Premultiplied);
    QPixmap scaled = px.scaled(szi);
    tmp.fill(0);
    QPainter tmpPainter(&tmp);
    tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
    tmpPainter.drawPixmap(QPointF(-distance(), -distance()), scaled);
    tmpPainter.end();

    // blur the alpha channel
    QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
    blurred.fill(0);
    QPainter blurPainter(&blurred);
    qt_blurImage(&blurPainter, tmp, blurRadius(), false, true);
    blurPainter.end();

    tmp = blurred;

    // blacken the image...
    tmpPainter.begin(&tmp);
    tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
    tmpPainter.fillRect(tmp.rect(), color());
    tmpPainter.end();

    // draw the blurred shadow...
    painter->drawImage(offset, tmp);

    // draw the actual pixmap...
    painter->drawPixmap(offset, px, QRectF());

    // restore world transform
    painter->setWorldTransform(restoreTransform);
}
Example #2
0
//  addDropShadow is inspired by QPixmapDropShadowFilter::draw in
//  qt/src/gui/effects/qpixmapfilter.cpp
QPixmap
addDropShadow( const QPixmap& source, const QSize& targetSize )
{
    const QPoint offset( 2, 4 );
    const int radius = 4;
    const QColor shadowColor( 100, 100, 100, 100 );

    // If there is no targetSize, then return a larger pixmap with the shadow added on
    // otherwise, return a bounded pixmap and shrink the source
    const QSize sizeToUse = targetSize.isEmpty() ? QSize( source.width() + offset.x() + radius, source.height() + offset.y() + radius ) : targetSize;
    const QSize shrunkToFit( sizeToUse.width() - offset.x() - radius, sizeToUse.height() - offset.y() - radius );
    const QPixmap shrunk = source.scaled( shrunkToFit, Qt::KeepAspectRatio, Qt::SmoothTransformation );

    QImage tmp( sizeToUse, QImage::Format_ARGB32_Premultiplied );
    tmp.fill( 0 );

    QPainter tmpPainter( &tmp );
    tmpPainter.setCompositionMode( QPainter::CompositionMode_Source );
    tmpPainter.drawPixmap( offset, shrunk );
    tmpPainter.end();

    // blur the alpha channel
    QImage blurred( sizeToUse, QImage::Format_ARGB32_Premultiplied );
    blurred.fill( 0 );
    QPainter blurPainter( &blurred );
    qt_blurImage( &blurPainter, tmp, radius, false, true );
    blurPainter.end();

    // blacken the image...
    QPainter blackenPainter( &blurred );
    blackenPainter.setCompositionMode( QPainter::CompositionMode_SourceIn );
    blackenPainter.fillRect( blurred.rect(), shadowColor );
    blackenPainter.end();

    const QRect resultRect( shrunk.rect().united( shrunk.rect().translated( offset ).adjusted( -radius, -radius, radius, radius ) ) );

    QPixmap result( resultRect.size() );
    result.fill( Qt::transparent );
    QPainter resultPainter( &result );

    // draw the blurred drop shadow...
    resultPainter.drawImage( 0, 0, blurred );

    // Draw the actual pixmap...
    resultPainter.drawPixmap( 0, 0, shrunk );

    return result;
}
Example #3
0
QT_END_NAMESPACE

void ShadowEffect::draw(QPainter* painter){
    if((blurRadius() + distance()) <= 0){
        drawSource(painter);
        return;
    }

    PixmapPadMode mode = QGraphicsEffect::PadToEffectiveBoundingRect;
    QPoint offset;
    const QPixmap px = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);

    if(px.isNull())
        return;

    QTransform restoreTransform = painter->worldTransform();
    painter->setWorldTransform(QTransform());

    QSize szi(px.size().width() + 2 * distance(), px.size().height() + 2 * distance());

    QImage tmp(szi, QImage::Format_ARGB32_Premultiplied);
    QPixmap scaled = px.scaled(szi);
    tmp.fill(0);
    QPainter tmpPainter(&tmp);
    tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
    tmpPainter.drawPixmap(QPointF(-distance(), -distance()), scaled);
    tmpPainter.end();

    QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
    blurred.fill(0);
    QPainter blurPainter(&blurred);
    qt_blurImage(&blurPainter, tmp, blurRadius(), false, true);
    blurPainter.end();

    tmp = blurred;

    tmpPainter.begin(&tmp);
    tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
    tmpPainter.fillRect(tmp.rect(), color());
    tmpPainter.end();

    painter->drawImage(offset, tmp);
    painter->drawPixmap(offset, px, QRectF());
    painter->setWorldTransform(restoreTransform);
}
void MirrorGraphicsEffect::draw(QPainter *painter)
{
	PixmapPadMode mode = PadToEffectiveBoundingRect;

	// Draw pixmap in device coordinates to avoid pixmap scaling.
	QPoint offset;
	const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
	if (pixmap.isNull())
		return;

	QTransform restoreTransform = painter->worldTransform();
	painter->setWorldTransform(QTransform());

	// We'll draw widget on this image
	QImage tmp(pixmap.size(), QImage::Format_ARGB32_Premultiplied);
	tmp.fill(Qt::transparent);
	// We're going to draw widget on tmp image using this painter object
	QPainter tmpPainter(&tmp);
	tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
	tmpPainter.drawPixmap(QPoint(0,0), pixmap);
	tmpPainter.end(); 

	// Now we need to mirror image and put alpha channel gradient on our image of control
	// First mirror it by Y axis
	QImage mirroredImage(tmp.mirrored(false, true));
	// Create gradient object
	QPoint p1, p2;
	p2.setY(mirroredImage.height());
	QLinearGradient gradient(p1, p2);
	gradient.setColorAt(0.3, QColor(0, 0, 0, 255));
	gradient.setColorAt(0.8, QColor(0, 0, 0, 0));

	// With this painter we'll draw gradient on mirror image
	QPainter mirroredImagePainter(&mirroredImage);
	mirroredImagePainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
	mirroredImagePainter.fillRect(0, 0, mirroredImage.width(), mirroredImage.height(), gradient);
	mirroredImagePainter.end();

	// Draw reflection first
	painter->drawImage(offset, mirroredImage);
	// Draw source widget
	painter->drawPixmap(offset, pixmap);
	painter->setWorldTransform(restoreTransform);
}
Example #5
0
// Draws a cached pixmap with shadow
void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
                                     QPainter *p, QIcon::Mode iconMode, int radius, const QColor &color, const QPoint &offset)
{
    QPixmap cache;
    QString pixmapName = QString("icon %0 %1 %2").arg(icon.cacheKey()).arg(iconMode).arg(rect.height());

    if (!QPixmapCache::find(pixmapName, cache)) {
        QPixmap px = icon.pixmap(rect.size());
        cache = QPixmap(px.size() + QSize(radius * 2, radius * 2));
        cache.fill(Qt::transparent);

        QPainter cachePainter(&cache);
        if (iconMode == QIcon::Disabled) {
            QImage im = px.toImage().convertToFormat(QImage::Format_ARGB32);
            for (int y=0; y<im.height(); ++y) {
                QRgb *scanLine = (QRgb*)im.scanLine(y);
                for (int x=0; x<im.width(); ++x) {
                    QRgb pixel = *scanLine;
                    char intensity = qGray(pixel);
                    *scanLine = qRgba(intensity, intensity, intensity, qAlpha(pixel));
                    ++scanLine;
                }
            }
            px = QPixmap::fromImage(im);
        }

        // Draw shadow
        QImage tmp(px.size() + QSize(radius * 2, radius * 2 + 1), QImage::Format_ARGB32_Premultiplied);
        tmp.fill(Qt::transparent);

        QPainter tmpPainter(&tmp);
        tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
        tmpPainter.drawPixmap(QPoint(radius, radius), px);
        tmpPainter.end();

        // blur the alpha channel
        QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
        blurred.fill(Qt::transparent);
        QPainter blurPainter(&blurred);
        qt_blurImage(&blurPainter, tmp, radius, false, true);
        blurPainter.end();

        tmp = blurred;

        // blacken the image...
        tmpPainter.begin(&tmp);
        tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
        tmpPainter.fillRect(tmp.rect(), color);
        tmpPainter.end();

        tmpPainter.begin(&tmp);
        tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
        tmpPainter.fillRect(tmp.rect(), color);
        tmpPainter.end();

        // draw the blurred drop shadow...
        cachePainter.drawImage(QRect(0, 0, cache.rect().width(), cache.rect().height()), tmp);

        // Draw the actual pixmap...
        cachePainter.drawPixmap(QPoint(radius, radius) + offset, px);
        QPixmapCache::insert(pixmapName, cache);
    }

    QRect targetRect = cache.rect();
    targetRect.moveCenter(rect.center());
    p->drawPixmap(targetRect.topLeft() - offset, cache);
}
Example #6
0
void CustomLabel::paintEvent(QPaintEvent *pe)
{
    if ((!text().isEmpty()) &&
            (textFormat() == Qt::PlainText ||
             (textFormat() == Qt::AutoText && !Qt::mightBeRichText(text()))))
    {
        QPainter painter(this);
#ifndef DEBUG_CUSTOMLABEL
        QRectF lr = contentsRect();
        lr.moveBottom(lr.bottom() - 1); // angry and dirty hack!
        QStyleOption opt;
        opt.initFrom(this);

        int align = QStyle::visualAlignment(text().isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight, alignment());
        int flags = align | (!text().isRightToLeft() ? Qt::TextForceLeftToRight : Qt::TextForceRightToLeft);
        if (wordWrap())
            flags |= Qt::TextWordWrap;
        switch (shadowType)
        {
        case NoShadow:
            flags |= TF_NOSHADOW;
            break;
        case DarkShadow:
            flags |= TF_DARKSHADOW;
            break;
        case LightShadow:
            flags |= TF_LIGHTSHADOW;
            break;
        default:
            break;
        }
        QString textToDraw = elidedText();
        style()->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), textToDraw, QPalette::WindowText);
#else // DEBUG_CUSTOMLABEL
        QTextDocument *doc = textDocument();
        QAbstractTextDocumentLayout::PaintContext ctx = textDocumentPaintContext(doc);
        QString shadowKey;
        switch (shadowType)
        {
        case DarkShadow:
            shadowKey = GFX_TEXTSHADOWS;
            break;
        case LightShadow:
            shadowKey = GFX_NOTICEWIDGET;
            break;
        case NoShadow:
        default:
            break;
        }

        // magic numbers
        int dx = -2;
        int dy = -2;
        // adding margins
        dx += contentsMargins().left();
        dy += contentsMargins().top();

# if 1 // for debug set 0
        QGraphicsDropShadowEffect *shadow = qobject_cast<QGraphicsDropShadowEffect *>(GraphicsEffectsStorage::staticStorage(RSR_STORAGE_GRAPHICSEFFECTS)->getFirstEffect(shadowKey));
# else // debug shadow
        QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect;
        shadow->setColor(Qt::red);
        shadow->setOffset(1, 1);
# endif
        if (shadow)
        {
# if 0 // for "image method" set 1
            QImage shadowedText(size(), QImage::Format_ARGB32_Premultiplied);
#  if defined(Q_WS_MAC) && !defined(__MAC_OS_X_NATIVE_FULLSCREEN)
            // TODO: fix that
            shadowedText.fill(Qt::red); // DUNNO WHY!!!
#  else
            shadowedText.fill(Qt::transparent);
#  endif
            QPainter tmpPainter(&shadowedText);
            tmpPainter.setRenderHint(QPainter::Antialiasing);
            tmpPainter.setRenderHint(QPainter::HighQualityAntialiasing);
            tmpPainter.setRenderHint(QPainter::TextAntialiasing);
            tmpPainter.setRenderHint(QPainter::SmoothPixmapTransform);
            tmpPainter.translate(dx, dy);
            doc->documentLayout()->draw(&tmpPainter, ctx);
            painter.drawImage(0, 0, shadowedText);
# else // text method
            QPalette origPal = ctx.palette;
            ctx.palette.setColor(QPalette::Text, shadow->color());

            // draw shadow
            painter.save();
            painter.translate(dx + shadow->xOffset(), dy + shadow->yOffset());
            doc->documentLayout()->draw(&painter, ctx);
            painter.restore();

            ctx.palette = origPal;

            // draw text
            painter.save();
            painter.translate(dx, dy);
            doc->documentLayout()->draw(&painter, ctx);
            painter.restore();
# endif // shadow method
        }
        else
        {
            painter.save();
            painter.translate(dx, dy);
            doc->documentLayout()->draw(&painter, ctx);
            painter.restore();
        }
        doc->deleteLater();
#endif // DEBUG_CUSTOMLABEL
    }
    else
        QLabel::paintEvent(pe);
}
Example #7
0
// Draws a cached pixmap with shadow
void FancyTabBar::drawIconWithShadow(const QIcon &icon, const QRect &rect, QPainter *p, QIcon::Mode iconMode, int dipRadius, const QColor &color, const QPoint &dipOffset)
{
    QPixmap cache;
    QString pixmapName = QString::fromLatin1("icon %0 %1 %2").arg(icon.cacheKey()).arg(iconMode).arg(rect.height());

    if (!QPixmapCache::find(pixmapName, cache)) {
        // High-dpi support: The in parameters (rect, radius, offset) are in
        // device-independent pixels. The call to QIcon::pixmap() below might
        // return a high-dpi pixmap, which will in that case have a devicePixelRatio
        // different than 1. The shadow drawing caluculations are done in device
        // pixels.
        QPixmap px = icon.pixmap(rect.size());
        //jassuncao int devicePixelRatio = qCeil(px.devicePixelRatio());
        int devicePixelRatio = 1;
        int radius = dipRadius * devicePixelRatio;
        QPoint offset = dipOffset * devicePixelRatio;
        cache = QPixmap(px.size() + QSize(radius * 2, radius * 2));
        cache.fill(Qt::transparent);

        QPainter cachePainter(&cache);
        if (iconMode == QIcon::Disabled) {
            QImage im = px.toImage().convertToFormat(QImage::Format_ARGB32);
            for (int y=0; y<im.height(); ++y) {
                QRgb *scanLine = (QRgb*)im.scanLine(y);
                for (int x=0; x<im.width(); ++x) {
                    QRgb pixel = *scanLine;
                    char intensity = qGray(pixel);
                    *scanLine = qRgba(intensity, intensity, intensity, qAlpha(pixel));
                    ++scanLine;
                }
            }
            px = QPixmap::fromImage(im);
        }

        // Draw shadow
        QImage tmp(px.size() + QSize(radius * 2, radius * 2 + 1), QImage::Format_ARGB32_Premultiplied);
        tmp.fill(Qt::transparent);

        QPainter tmpPainter(&tmp);
        tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
        tmpPainter.drawPixmap(QRect(radius, radius, px.width(), px.height()), px);
        tmpPainter.end();

        // blur the alpha channel
        QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
        blurred.fill(Qt::transparent);
        QPainter blurPainter(&blurred);
        qt_blurImage(&blurPainter, tmp, radius, false, true);
        blurPainter.end();

        tmp = blurred;

        // blacken the image...
        tmpPainter.begin(&tmp);
        tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
        tmpPainter.fillRect(tmp.rect(), color);
        tmpPainter.end();

        tmpPainter.begin(&tmp);
        tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
        tmpPainter.fillRect(tmp.rect(), color);
        tmpPainter.end();

        // draw the blurred drop shadow...
        cachePainter.drawImage(QRect(0, 0, cache.rect().width(), cache.rect().height()), tmp);

        // Draw the actual pixmap...
        cachePainter.drawPixmap(QRect(QPoint(radius, radius) + offset, QSize(px.width(), px.height())), px);
        //jassuncao: cache.setDevicePixelRatio(devicePixelRatio);
        QPixmapCache::insert(pixmapName, cache);
    }

    QRect targetRect = cache.rect();
    //jassuncao targetRect.setSize(targetRect.size() / cache.devicePixelRatio());
    targetRect.moveCenter(rect.center() - dipOffset);
    p->drawPixmap(targetRect, cache);
}
void MapGraphicsView::setStatusMessage(QString msg)
{
    if(msg.isEmpty())
    {
        m_statusLabel->setPixmap(QPixmap());
        m_statusLabel->hide();
        return;
    }

    m_statusLabel->show();

    if(Qt::mightBeRichText(msg))
    {
        QTextDocument doc;
        doc.setHtml(msg);
        msg = doc.toPlainText();
    }

    QImage tmp(1,1,QImage::Format_ARGB32_Premultiplied);
    QPainter tmpPainter(&tmp);

    QFont font("");//"",  20);
    tmpPainter.setFont(font);

    QRectF maxRect(0, 0, (qreal)width(), (qreal)height() * .25);
    QRectF boundingRect = tmpPainter.boundingRect(maxRect, Qt::TextWordWrap | Qt::AlignHCenter, msg);
    boundingRect.adjust(0, 0, tmpPainter.font().pointSizeF() * 3, tmpPainter.font().pointSizeF() * 1.25);

    QImage labelImage(boundingRect.size().toSize(), QImage::Format_ARGB32_Premultiplied);
    memset(labelImage.bits(), 0, labelImage.byteCount());

    QPainter p(&labelImage);

    QColor bgColor(0, 127, 254, 180);

#ifdef Q_OS_ANDROID
    bgColor = bgColor.lighter(300);
#endif

    p.setPen(QPen(Qt::white, 2.5));
    p.setBrush(bgColor);
    p.drawRoundedRect(labelImage.rect().adjusted(0,0,-1,-1), 3., 3.);

    QImage txtImage(boundingRect.size().toSize(), QImage::Format_ARGB32_Premultiplied);
    memset(txtImage.bits(), 0, txtImage.byteCount());
    QPainter tp(&txtImage);

    tp.setPen(Qt::white);
    tp.setFont(font);
    tp.drawText(QRectF(QPointF(0,0), boundingRect.size()), Qt::TextWordWrap | Qt::AlignHCenter | Qt::AlignVCenter, msg);
    tp.end();

    double ss = 8.;
    p.drawImage((int)-ss,(int)-ss, ImageUtils::addDropShadow(txtImage, ss));

    p.end();

#ifdef Q_OS_ANDROID
    m_statusLabel->setPixmap(QPixmap::fromImage(labelImage));
#else
    m_statusLabel->setPixmap(QPixmap::fromImage(ImageUtils::addDropShadow(labelImage, ss)));
#endif
}
QImage RichTextRenderer::renderText()
{
// 	qDebug()<<itemName()<<"TextBoxWarmingThread::run(): htmlCode:"<<htmlCode;
	//qDebug() << "RichTextRenderer::renderText(): HTML:"<<html();
	//qDebug() << "RichTextRenderer::update(): Update Start...";
 	//qDebug() << "RichTextRenderer::renderText(): \t in thread:"<<QThread::currentThreadId();
	if(m_updateTimer.isActive())
		m_updateTimer.stop();
		
	QTime renderTime;
	renderTime.start();
	
	QTextDocument doc;
	QTextDocument shadowDoc;
	
	if (Qt::mightBeRichText(html()))
	{
		doc.setHtml(html());
		shadowDoc.setHtml(html());
	}
	else
	{
		doc.setPlainText(html());
		shadowDoc.setPlainText(html());
	}
	
	int textWidth = m_textWidth;

	doc.setTextWidth(textWidth);
	shadowDoc.setTextWidth(textWidth);
	
	// Apply outline pen to the html
	QTextCursor cursor(&doc);
	cursor.select(QTextCursor::Document);

	QTextCharFormat format;

	QPen p(Qt::NoPen);
	if(outlineEnabled())
	{
		p = outlinePen();
		p.setJoinStyle(Qt::MiterJoin);
	}

	format.setTextOutline(p);
	//format.setForeground(fillEnabled() ? fillBrush() : Qt::NoBrush); //Qt::white);

	cursor.mergeCharFormat(format);
	
	// Setup the shadow text formatting if enabled
	if(shadowEnabled())
	{
		if(shadowBlurRadius() <= 0.05)
		{
			QTextCursor cursor(&shadowDoc);
			cursor.select(QTextCursor::Document);
	
			QTextCharFormat format;
			format.setTextOutline(Qt::NoPen);
			format.setForeground(shadowBrush());
	
			cursor.mergeCharFormat(format);
		}
	}
	
			
	QSizeF shadowSize = shadowEnabled() ? QSizeF(shadowOffsetX(),shadowOffsetY()) : QSizeF(0,0);
	QSizeF docSize = doc.size();
	QSizeF padSize(12.,12.);
	QSizeF sumSize = (docSize + shadowSize + padSize);//.toSize();
	
	QSizeF scaledSize = QSizeF(sumSize.width() * m_scaling.x(), sumSize.height() * m_scaling.y());
	if(m_scaling.x() != 1. || m_scaling.y() != 1.)
	{
		//qDebug() << "RichTextRenderer::renderText(): Orig size:"<<sumSize<<", scaled size:"<<scaledSize<<", scaling:"<<m_scaling;
		m_rawSize = sumSize;
	}
	//qDebug() << "RichTextRenderer::update(): textWidth: "<<textWidth<<", shadowSize:"<<shadowSize<<", docSize:"<<docSize<<", sumSize:"<<sumSize;
	QImage cache(scaledSize.toSize(),QImage::Format_ARGB32); //_Premultiplied);
	memset(cache.scanLine(0),0,cache.byteCount());
	
	double padSizeHalfX = padSize.width() / 2;
	double padSizeHalfY = padSize.height() / 2;
			
	
	QPainter textPainter(&cache);
	textPainter.scale(m_scaling.x(), m_scaling.y());
	//textPainter.fillRect(cache.rect(),Qt::transparent);
	
	QAbstractTextDocumentLayout::PaintContext pCtx;

	//qDebug() << "RichTextRenderer::renderText(): shadowEnabled():"<<shadowEnabled()<<", shadowBlurRadius():"<<shadowBlurRadius(); 
	if(shadowEnabled())
	{
		if(shadowBlurRadius() <= 0.05)
		{
			// render a "cheap" version of the shadow using the shadow text document
			textPainter.save();

			textPainter.translate(shadowOffsetX(),shadowOffsetY());
			shadowDoc.documentLayout()->draw(&textPainter, pCtx);

			textPainter.restore();
		}
		else
		{
			double radius = shadowBlurRadius();
			
			// create temporary pixmap to hold a copy of the text
			QSizeF blurSize = ImageFilters::blurredSizeFor(doc.size(), (int)radius);
			
			QSizeF scaledBlurSize = QSize(blurSize.width() * m_scaling.x(), blurSize.height() * m_scaling.y());
			//QSize docSize = doc.size();
			//qDebug() << "RichTextRenderer::renderText(): [shadow] radius:"<<radius<<" blurSize:"<<blurSize<<", scaling:"<<m_scaling<<", scaledBlurSize:"<<scaledBlurSize;
			
			
			//qDebug() << "Blur size:"<<blurSize<<", doc:"<<doc.size()<<", radius:"<<radius;
			QImage tmpImage(scaledBlurSize.toSize(),QImage::Format_ARGB32_Premultiplied);
			memset(tmpImage.scanLine(0),0,tmpImage.byteCount());
			
			// render the text
			QPainter tmpPainter(&tmpImage);
			tmpPainter.scale(m_scaling.x(), m_scaling.y());
			
			tmpPainter.save();
			tmpPainter.translate(radius + padSizeHalfX, radius + padSizeHalfY);
			doc.documentLayout()->draw(&tmpPainter, pCtx);
			tmpPainter.restore();
			
			// blacken the text by applying a color to the copy using a QPainter::CompositionMode_DestinationIn operation. 
			// This produces a homogeneously-colored pixmap.
			QRect rect = tmpImage.rect();
			tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
			tmpPainter.fillRect(rect, shadowBrush().color());
			tmpPainter.end();

			// blur the colored text
			ImageFilters::blurImage(tmpImage, (int)radius);
			
			// render the blurred text at an offset into the cache
			textPainter.save();
			textPainter.translate(shadowOffsetX() - radius,
					      shadowOffsetY() - radius);
			textPainter.drawImage(0, 0, tmpImage);
			textPainter.restore();
		}
	}
	
	textPainter.translate(padSizeHalfX, padSizeHalfY);
	doc.documentLayout()->draw(&textPainter, pCtx);
	
	textPainter.end();
	
	m_image = cache.convertToFormat(QImage::Format_ARGB32);
	emit textRendered(m_image);
	
	//qDebug() << "RichTextRenderer::renderText(): Render finished, elapsed:"<<renderTime.elapsed()<<"ms";
	//m_image.save("debug-text.png");
	return m_image;
	
}
Example #10
0
void GLImageDrawable::updateShadow()
{
	if(!m_shadowDrawable)
		return;
		
	QImage sourceImg = m_imageWithBorder.isNull() ? m_image : m_imageWithBorder;
	
	QSizeF originalSizeWithBorder = sourceImg.size();
	
	QPointF scale = m_glw ? QPointF(m_glw->transform().m11(), m_glw->transform().m22()) : QPointF(1.,1.);
	
	if(scale.x() < 1.25 && scale.y() < 1.25)
		scale = QPointF(1,1);
	
	double radius = m_shadowBlurRadius;
	
	// create temporary pixmap to hold a copy of the text
	double radiusSpacing = radius;// / 1.75;// * 1.5;
	double radius2 = radius * 2;
// 	double offx = 0; //fabs(m_shadowOffset.x());
// 	double offy = 0; //fabs(m_shadowOffset.y());
	double newWidth  = originalSizeWithBorder.width() 
			 + radius2 * scale.x();// blur on both sides
			 //+ offx * scale.x();
	
	double newHeight = originalSizeWithBorder.height() 
			 + radius2 * scale.y();// blur on both sides
			 //+ offy * scale.y();
			
	QSizeF blurSize(newWidth,newHeight);
// 	blurSize.rwidth()  *= scale.x();
// 	blurSize.rheight() *= scale.y();
	
	//qDebug() << "GLImageDrawable::applyBorderAndShadow(): Blur size:"<<blurSize<<", originalSizeWithBorder:"<<originalSizeWithBorder<<", radius:"<<radius<<", radius2:"<<radius2<<", m_shadowOffset:"<<m_shadowOffset<<", offx:"<<offx<<", offy:"<<offy<<", scale:"<<scale;
	QImage tmpImage(blurSize.toSize(),QImage::Format_ARGB32_Premultiplied);
	memset(tmpImage.scanLine(0),0,tmpImage.byteCount());
	
	// render the source image into a temporary buffer for bluring
	QPainter tmpPainter(&tmpImage);
	//tmpPainter.scale(scale.x(),scale.y());
	
	tmpPainter.save();
	QPointF translate1(radiusSpacing, 
			   radiusSpacing);
	translate1.rx() *= scale.x();
	translate1.ry() *= scale.y();
	//qDebug() << "stage1: radiusSpacing:"<<radiusSpacing<<", m_shadowOffset:"<<m_shadowOffset<<", translate1:"<<translate1;
	//qDebug() << "GLImageDrawable::updateShadow(): translate1:"<<translate1<<", scale:"<<scale; 
	
	tmpPainter.translate(translate1);
	tmpPainter.drawImage(0,0,sourceImg);
	
	tmpPainter.restore();
	
	// color the orignal image by applying a color to the copy using a QPainter::CompositionMode_DestinationIn operation. 
	// This produces a homogeneously-colored pixmap.
	QRect imgRect = tmpImage.rect();
	tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
	
	QColor color = m_shadowColor;
	// clamp m_shadowOpacity to 1.0 because we handle values >1.0 by repainting the blurred image over itself (m_shadowOpacity-1) times.
	color.setAlpha((int)(255.0 * (m_shadowOpacity > 1.0 ? 1.0 : m_shadowOpacity)));
	tmpPainter.fillRect(imgRect, color);
	
	tmpPainter.end();

	// blur the colored text
	ImageFilters::blurImage(tmpImage, (int)(radius * scale.x()));
	
	if(m_shadowOpacity > 1.0)
	{
		QPainter painter2(&tmpImage);
	
		int times = (int)(m_shadowOpacity - 1.0);
		// Cap at 10 - an arbitrary cap just to prevent the user from taxing the CPU too much.
		if(times > 10)
			times = 10;
			
		double finalOpacity = m_shadowOpacity - ((int)m_shadowOpacity);
		if(finalOpacity < 0.001)
			finalOpacity = 1.0;
		
		QImage copy = tmpImage.copy();
		for(int i=0; i<times-1; i++)
			painter2.drawImage(0,0,copy);
		
		//qDebug() << "Overpaint feature: times:"<<times<<", finalOpacity:"<<finalOpacity;
		painter2.setOpacity(finalOpacity);
		painter2.drawImage(0,0,copy);
		painter2.setOpacity(1.0);
	}
	
// 	{
// 		QPainter painter2(&tmpImage);
// 		painter2.setPen(Qt::yellow);
// 		
// 		QPointF translate1(radiusSpacing, 
// 				radiusSpacing);
// 		translate1.rx() *= scale.x();
// 		translate1.ry() *= scale.y();
// 		//qDebug() << "stage1: radiusSpacing:"<<radiusSpacing<<", m_shadowOffset:"<<m_shadowOffset<<", translate1:"<<translate1;
// 		//qDebug() << "GLImageDrawable::updateShadow(): translate1:"<<translate1<<", scale:"<<scale; 
// 		
// 		painter2.translate(translate1);
// 		painter2.drawImage(0,0,sourceImg);
// 		painter2.drawRect(sourceImg.rect());
// 	
// 	}
	
	
	// Notice: Older versions of this shadow code drew the sourceImg back on top of the shadow -
	// Since we are drawaing the drop shadow as a separate texture below the real image in the 
	// m_shadowDrawable, we are not going to draw the sourceImg on top now.
	
	//qDebug() << "GLImageDrawable::updateShadow(): shadow location:"<<point<<", size:"<<tmpImage.size()<<", rect().topLeft():"<<rect().topLeft()<<", m_shadowOffset:"<<m_shadowOffset<<", radiusSpacing:"<<radiusSpacing;
	bool scaleFlag = dynamic_cast<GLTextDrawable*>(this) == NULL;
// 	double scale_w = scaleFlag ? fabs((double)(rect().width()  - sourceImg.width()))  / sourceImg.width()  : 1.0;
// 	double scale_h = scaleFlag ? fabs((double)(rect().height() - sourceImg.height())) / sourceImg.height() : 1.0;
	double scale_w = scaleFlag ? m_targetRect.width()  / m_sourceRect.width()  : 1.0;
	double scale_h = scaleFlag ? m_targetRect.height() / m_sourceRect.height() : 1.0;
	
// 	scale_w *= 2;
// 	scale_h *= 2;
	
	QSizeF size(((double)tmpImage.width()) * scale_w, ((double)tmpImage.height()) * scale_h);
	QPointF point = rect().topLeft() + QPointF(m_shadowOffset.x() * scale_w, m_shadowOffset.y() * scale_h) - QPointF(m_shadowBlurRadius * scale_w,m_shadowBlurRadius * scale_h);
	
	//qDebug() << "GLImageDrawable::updateShadow: "<<(QObject*)this<<" m_targetRect:"<<m_targetRect.size()<<", m_sourceRect:"<<m_sourceRect.size()<<", scale:"<<scale_w<<"x"<<scale_h<<", tmpImage:"<<tmpImage.size()<<", new size:"<<size<<", point:"<<point;
	
	m_shadowDrawable->setRect(QRectF(point, size));
	
	m_shadowDrawable->setImage(tmpImage);
	//updateGL();
}
Example #11
0
void TextBoxContent::renderShadow(QPainter *painter, QAbstractTextDocumentLayout::PaintContext *pCtx)
{
	AbstractVisualItem *model = modelItem();
	if(qFuzzyIsNull(model->shadowBlurRadius()))
	{
		// render a "cheap" version of the shadow using the shadow text document
		painter->save();

		painter->translate(model->shadowOffsetX(),model->shadowOffsetY());
		m_shadowText->documentLayout()->draw(painter, *pCtx);

		painter->restore();
	}
	else
	{
// 		double radius = model->shadowBlurRadius();
// 		double radiusSquared = radius*radius;
// 		
// 		// create temporary pixmap to hold a copy of the text
// 		double blurSize = (int)(radiusSquared*2);
// 		QSize shadowSize(blurSize,blurSize);
// 		QPixmap tmpPx(contentsRect().size()+shadowSize);
// 		tmpPx.fill(Qt::transparent);
// 		
// 		// render the text
// 		QPainter tmpPainter(&tmpPx);
// 		tmpPainter.save();
// 		tmpPainter.translate(radiusSquared, radiusSquared);
// 		m_text->documentLayout()->draw(&tmpPainter, *pCtx);
// 		tmpPainter.restore();
// 		
// 		// blacken the text by applying a color to the copy using a QPainter::CompositionMode_DestinationIn operation. 
// 		// This produces a homogeneously-colored pixmap.
// 		QRect rect = QRect(0, 0, tmpPx.width(), tmpPx.height());
// 		tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
// 		tmpPainter.fillRect(rect, model->shadowBrush().color());
// 		tmpPainter.end();
// 
// 		// blur the colored text
// 		QImage  orignalImage   = tmpPx.toImage();
// 		QImage  blurredImage   = ImageFilters::blurred(orignalImage, rect, (int)radius);
// 		QPixmap blurredPixmap  = QPixmap::fromImage(blurredImage);
// 		
// 		// render the blurred text at an offset into the cache
// 		painter->save();
// 		painter->translate(model->shadowOffsetX() - radiusSquared,
// 				model->shadowOffsetY() - radiusSquared);
// 		painter->drawPixmap(0, 0, blurredPixmap);
// 		painter->restore();
		
		// New method of rendering shadows
		double radius = model->shadowBlurRadius();
		
		// create temporary pixmap to hold a copy of the text
		QSizeF blurSize = ImageFilters::blurredSizeFor(model->contentsRect().size(), (int)radius);
		//qDebug() << "Blur size:"<<blurSize<<", doc:"<<doc.size()<<", radius:"<<radius;
		QImage tmpImage(blurSize.toSize(),QImage::Format_ARGB32_Premultiplied);
		memset(tmpImage.scanLine(0),0,tmpImage.byteCount());
		
		// render the text
		QPainter tmpPainter(&tmpImage);
		
		tmpPainter.save();
		tmpPainter.translate(radius, radius);
		m_text->documentLayout()->draw(&tmpPainter, *pCtx);
		tmpPainter.restore();
		
		// blacken the text by applying a color to the copy using a QPainter::CompositionMode_DestinationIn operation. 
		// This produces a homogeneously-colored pixmap.
		QRect rect = tmpImage.rect();
		tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
		tmpPainter.fillRect(rect, model->shadowBrush().color());
		tmpPainter.end();

		// blur the colored text
		ImageFilters::blurImage(tmpImage, (int)radius);
		
		// render the blurred text at an offset into the cache
		painter->save();
		painter->translate(model->shadowOffsetX() - radius,
				      model->shadowOffsetY() - radius);
		painter->drawImage(0, 0, tmpImage);
		painter->restore();
	}
}
Example #12
0
void TextBoxWarmingThread::run()
{
	if(!m_model)
	{
		qDebug()<<"TextBoxWarmingThread::run(): m_model is null";
		return;
	}
	//qDebug()<<"TextBoxWarmingThread::run(): model ptr:"<<m_model<<", attempting to dynamic cast";
	
	TextBoxItem * model = dynamic_cast<TextBoxItem*>((AbstractVisualItem*)m_model);
	
	//int sleepTime = (int)(((float)qrand()) / ((float)RAND_MAX) * 10000.0 + 2000.0);
	
	//qDebug()<<"TextBoxWarmingThread::run(): modelItem:"<<model->itemName();//<<": Cache redraw, sleep: "<<sleepTime;
	
	// Sleep doesnt work - if I sleep, then it seems the cache is never updated!
	//sleep((unsigned long)sleepTime);
	//sleep(1000);
	
			
	QString htmlCode = model->text();
// 	qDebug()<<model->itemName()<<"TextBoxWarmingThread::run(): htmlCode:"<<htmlCode;
	
	QTextDocument doc;
	QTextDocument shadowDoc;
	
	doc.setHtml(htmlCode);
	shadowDoc.setHtml(htmlCode);
	
	int textWidth = model->contentsRect().toRect().width();

	doc.setTextWidth(textWidth);
	shadowDoc.setTextWidth(textWidth);

	
	
	// Apply outline pen to the html
	QTextCursor cursor(&doc);
	cursor.select(QTextCursor::Document);

	QTextCharFormat format;

	QPen p(Qt::NoPen);
	if(model && model->outlineEnabled())
	{
		p = model->outlinePen();
		p.setJoinStyle(Qt::MiterJoin);
	}

	format.setTextOutline(p);
	format.setForeground(model && model->fillType() == AbstractVisualItem::Solid ? model->fillBrush() : Qt::NoBrush); //Qt::white);

	
	cursor.mergeCharFormat(format);
	
	#if QT46_SHADOW_ENAB == 0
	// Setup the shadow text formatting if enabled
	if(model && model->shadowEnabled())
	{
		if(qFuzzyIsNull(model->shadowBlurRadius()))
		{
			QTextCursor cursor(&shadowDoc);
			cursor.select(QTextCursor::Document);
	
			QTextCharFormat format;
			format.setTextOutline(Qt::NoPen);
			format.setForeground(model ? model->shadowBrush() : Qt::black);
	
			cursor.mergeCharFormat(format);
		}
	}
	#endif
	
			
	QSizeF shadowSize = model->shadowEnabled() ? QSizeF(model->shadowOffsetX(),model->shadowOffsetY()) : QSizeF(0,0);
	QImage *cache = new QImage((model->contentsRect().size()+shadowSize).toSize(),QImage::Format_ARGB32_Premultiplied);
	memset(cache->scanLine(0),0,cache->byteCount());

	QPainter textPainter(cache);
	textPainter.fillRect(cache->rect(),Qt::transparent);
	
	QAbstractTextDocumentLayout::PaintContext pCtx;

	#if QT46_SHADOW_ENAB == 0
	if(model->shadowEnabled())
	{
		if(qFuzzyIsNull(model->shadowBlurRadius()))
		{
			// render a "cheap" version of the shadow using the shadow text document
			textPainter.save();

			textPainter.translate(model->shadowOffsetX(),model->shadowOffsetY());
			shadowDoc.documentLayout()->draw(&textPainter, pCtx);

			textPainter.restore();
		}
		else
		{
// 			double radius = model->shadowBlurRadius();
// 			double radiusSquared = radius*radius;
// 			
// 			// create temporary pixmap to hold a copy of the text
// 			double blurSize = (int)(radiusSquared*2);
// 			QSize shadowSize(blurSize,blurSize);
// 			QImage tmpImage((model->contentsRect().size()+shadowSize).toSize(),QImage::Format_ARGB32);
// 			memset(tmpImage.scanLine(0),0,tmpImage.byteCount());
// 			
// 			// render the text
// 			QPainter tmpPainter(&tmpImage);
// 			tmpPainter.fillRect(tmpImage.rect(),Qt::transparent);
// 			
// 			tmpPainter.save();
// 			tmpPainter.translate(radiusSquared, radiusSquared);
// 			doc.documentLayout()->draw(&tmpPainter, pCtx);
// 			tmpPainter.restore();
// 			
// 			// blacken the text by applying a color to the copy using a QPainter::CompositionMode_DestinationIn operation. 
// 			// This produces a homogeneously-colored pixmap.
// 			QRect rect = tmpImage.rect();
// 			tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
// 			tmpPainter.fillRect(rect, model->shadowBrush().color());
// 			tmpPainter.end();
// 
// 			// blur the colored text
// 			QImage  blurredImage   = ImageFilters::blurred(tmpImage, rect, (int)radius);
// 			
// 			// render the blurred text at an offset into the cache
// 			textPainter.save();
// 			textPainter.translate(model->shadowOffsetX() - radiusSquared,
// 					model->shadowOffsetY() - radiusSquared);
// 			textPainter.drawImage(0, 0, blurredImage.copy(blurredImage.rect()));
// 			textPainter.restore();
			
			
			// New method of rendering shadows
			double radius = model->shadowBlurRadius();
			
			// create temporary pixmap to hold a copy of the text
			QSizeF blurSize = ImageFilters::blurredSizeFor(model->contentsRect().size(), (int)radius);
			//qDebug() << "Blur size:"<<blurSize<<", doc:"<<doc.size()<<", radius:"<<radius;
			QImage tmpImage(blurSize.toSize(),QImage::Format_ARGB32_Premultiplied);
			memset(tmpImage.scanLine(0),0,tmpImage.byteCount());
			
			// render the text
			QPainter tmpPainter(&tmpImage);
			
			tmpPainter.save();
			tmpPainter.translate(radius, radius);
			doc.documentLayout()->draw(&tmpPainter, pCtx);
			tmpPainter.restore();
			
			// blacken the text by applying a color to the copy using a QPainter::CompositionMode_DestinationIn operation. 
			// This produces a homogeneously-colored pixmap.
			QRect rect = tmpImage.rect();
			tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
			tmpPainter.fillRect(rect, model->shadowBrush().color());
			tmpPainter.end();

			// blur the colored text
			ImageFilters::blurImage(tmpImage, (int)radius);
			
			// render the blurred text at an offset into the cache
			textPainter.save();
			textPainter.translate(model->shadowOffsetX() - radius,
					      model->shadowOffsetY() - radius);
			textPainter.drawImage(0, 0, tmpImage);
			textPainter.restore();
		}
	}
	#endif
	
	doc.documentLayout()->draw(&textPainter, pCtx);
	
	textPainter.end();
	
	emit renderDone(cache);
}