Esempio n. 1
0
void SchemeSensors::paintEvent(QPaintEvent *)
{
    QPainter schemePainter(this);

    schemePainter.setRenderHint(QPainter::Antialiasing, true);
    schemePainter.setBrush(QBrush(Qt::gray, Qt::DiagCrossPattern));
    schemePainter.setPen(QPen(QColor(0, 153, 204), 2));

    /* Draw Rects */
    schemePainter.drawRect(QRect(30, 5, width() - 60, height() / 8));
    schemePainter.drawRect(QRect(100, 5 + height() / 8, width() - 200, (height() / 4) + (height() / 8)));

    /* Draw Polygon */
    QPolygonF polygon;
    polygon << QPointF(10, (5 + height() / 8) + (height() / 4) + (height() / 8));
    polygon << QPointF(width() - 20, (5 + height() / 8) + (height() / 4) + (height() / 8));
    polygon << QPointF(width() - 20, 105 + (height() / 2));
    polygon << QPointF(width() / 2, 205 + (height() / 2));
    polygon << QPointF(10, 105 + (height() / 2));
    polygon << QPointF(10, (5 + height() / 8) + (height() / 4) + (height() / 8));
    schemePainter.drawPolygon(polygon);

    /* Draw Text */
    QPainter textPainter(this);
    drawRotateText(&textPainter, 270, 25, (height() / 8) - 5, blockA);
    drawRotateText(&textPainter, 270, 95, ((height() / 4) + (height() / 8)) - 5, blockB);
    drawRotateText(&textPainter, 90, width() - 15, (30 + height() / 8) + (height() / 4) + (height() / 8), blockC);

    if (qDrawSensors)
    {
        drawSensors();
    }
}
Esempio n. 2
0
void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
{
    GraphicsContext* context = paintInfo.context;
    RenderStyle* style = renderer().style(isFirstLineStyle());
    const Font& font = style->font();
    FloatPoint boxOrigin = locationIncludingFlipping();
    boxOrigin.moveBy(FloatPoint(paintOffset));
    if (!isHorizontal())
        boxOrigin.move(0, -virtualLogicalHeight());
    FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight()));
    GraphicsContextStateSaver stateSaver(*context);
    if (!isHorizontal())
        context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clockwise));
    FloatPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent());

    bool isPrinting = renderer().document().printing();
    bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone;

    if (haveSelection)
        paintSelection(context, boxOrigin, style, font);
    else if (paintInfo.phase == PaintPhaseSelection)
        return;

    TextPainter::Style textStyle = TextPainter::textPaintingStyle(renderer(), style, paintInfo.forceBlackText(), isPrinting);
    if (haveSelection)
        textStyle = TextPainter::selectionPaintingStyle(renderer(), true, paintInfo.forceBlackText(), isPrinting, textStyle);

    TextRun textRun = constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion);
    TextPainter textPainter(context, font, textRun, textOrigin, boxRect, isHorizontal());
    textPainter.paint(0, m_str.length(), m_str.length(), textStyle);

    paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style);
}
void paintFlow(const RenderBlockFlow& flow, const Layout& layout, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    if (paintInfo.phase != PaintPhaseForeground)
        return;

    RenderStyle& style = flow.style();
    if (style.visibility() != VISIBLE)
        return;

    bool debugBordersEnabled = flow.frame().settings().simpleLineLayoutDebugBordersEnabled();

    TextPainter textPainter(paintInfo.context());
    textPainter.setFont(style.fontCascade());
    textPainter.setTextPaintStyle(computeTextPaintStyle(flow.frame(), style, paintInfo));

    Optional<TextDecorationPainter> textDecorationPainter;
    if (style.textDecorationsInEffect() != TextDecorationNone) {
        const RenderText* textRenderer = childrenOfType<RenderText>(flow).first();
        if (textRenderer) {
            textDecorationPainter = TextDecorationPainter(paintInfo.context(), style.textDecorationsInEffect(), *textRenderer, false);
            textDecorationPainter->setFont(style.fontCascade());
            textDecorationPainter->setBaseline(style.fontMetrics().ascent());
        }
    }

    LayoutRect paintRect = paintInfo.rect;
    paintRect.moveBy(-paintOffset);

    auto resolver = runResolver(flow, layout);
    float strokeOverflow = std::ceil(flow.style().textStrokeWidth());
    float deviceScaleFactor = flow.document().deviceScaleFactor();
    for (auto run : resolver.rangeForRect(paintRect)) {
        if (run.start() == run.end())
            continue;

        FloatRect rect = run.rect();
        FloatRect visualOverflowRect = rect;
        visualOverflowRect.inflate(strokeOverflow);
        if (paintRect.y() > visualOverflowRect.maxY() || paintRect.maxY() < visualOverflowRect.y())
            continue;

        TextRun textRun(run.text());
        textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize());
        // x position indicates the line offset from the rootbox. It's always 0 in case of simple line layout.
        textRun.setXPos(0);
        FloatPoint textOrigin = FloatPoint(rect.x() + paintOffset.x(), roundToDevicePixel(run.baselinePosition() + paintOffset.y(), deviceScaleFactor));
        textPainter.paintText(textRun, textRun.length(), rect, textOrigin);
        if (textDecorationPainter) {
            textDecorationPainter->setWidth(rect.width());
            textDecorationPainter->paintTextDecoration(textRun, textOrigin, rect.location() + paintOffset);
        }
        if (debugBordersEnabled)
            paintDebugBorders(paintInfo.context(), LayoutRect(run.rect()), paintOffset);
    }
}
void EllipsisBoxPainter::paintEllipsis(const PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom, const ComputedStyle& style)
{
    bool haveSelection = !paintInfo.isPrinting() && paintInfo.phase != PaintPhaseTextClip && m_ellipsisBox.getSelectionState() != SelectionNone;

    LayoutRect paintRect(m_ellipsisBox.logicalFrameRect());
    if (haveSelection)
        paintRect.unite(LayoutRect(m_ellipsisBox.selectionRect()));
    m_ellipsisBox.logicalRectToPhysicalRect(paintRect);
    paintRect.moveBy(paintOffset);

    GraphicsContext& context = paintInfo.context;
    DisplayItem::Type displayItemType = DisplayItem::paintPhaseToDrawingType(paintInfo.phase);
    if (DrawingRecorder::useCachedDrawingIfPossible(context, m_ellipsisBox, displayItemType))
        return;

    DrawingRecorder recorder(context, m_ellipsisBox, displayItemType, FloatRect(paintRect));

    LayoutPoint boxOrigin = m_ellipsisBox.locationIncludingFlipping();
    boxOrigin.moveBy(paintOffset);
    LayoutRect boxRect(boxOrigin, LayoutSize(m_ellipsisBox.logicalWidth(), m_ellipsisBox.virtualLogicalHeight()));

    GraphicsContextStateSaver stateSaver(context);
    if (!m_ellipsisBox.isHorizontal())
        context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Clockwise));

    const Font& font = style.font();

    if (haveSelection)
        paintSelection(context, boxOrigin, style, font);
    else if (paintInfo.phase == PaintPhaseSelection)
        return;

    TextPainter::Style textStyle = TextPainter::textPaintingStyle(m_ellipsisBox.getLineLayoutItem(), style, paintInfo);
    if (haveSelection)
        textStyle = TextPainter::selectionPaintingStyle(m_ellipsisBox.getLineLayoutItem(), true, paintInfo, textStyle);

    TextRun textRun = constructTextRun(font, m_ellipsisBox.ellipsisStr(), style, TextRun::AllowTrailingExpansion);
    LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.getFontMetrics().ascent());
    TextPainter textPainter(context, font, textRun, textOrigin, boxRect, m_ellipsisBox.isHorizontal());
    textPainter.paint(0, m_ellipsisBox.ellipsisStr().length(), m_ellipsisBox.ellipsisStr().length(), textStyle);
}
bool
ImageStackPainter::draw(
		const util::rect<double>&  roi,
		const util::point<double>& resolution) {

	LOG_ALL(imagestackpainterlog) << "redrawing section " << _section << std::endl;

	if (_showColored) {

		for (unsigned int i = 0; i < _stack->size(); i++) {

			_imagePainters[i]->draw(roi, resolution);
		}

	} else {

		for (unsigned int i = 0; i < _numImages; i++) {

			double d = static_cast<int>(i - _numImages/2)*(_imageHeight + _gap);

			glTranslated(0, -d, 0);
			_imagePainters[i]->draw(roi - util::point<double>(static_cast<double>(0), -d), resolution);
			glTranslated(0,  d, 0);
		}
	}

	if (_annotation != "") {

		gui::TextPainter textPainter(_annotation);

		glTranslatef( _annotationX,  _annotationY, 0.0f);
		textPainter.draw(roi - util::point<double>(_annotationX, _annotationY), resolution);
		glTranslatef(-_annotationX, -_annotationY, 0.0f);
	}

	return false;
}
Esempio n. 6
0
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;
	
}
Esempio n. 7
0
void TextBoxContent::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
{
	DEBUG_TSTART();
	// paint parent
	AbstractContent::paint(painter, option, widget);

	
	painter->save();
	
	//TODO should we clip to the rect or FORCE resize the rect? probably clip...
	//painter->setClipRect(contentsRect());
	//if(option)
	//	painter->setClipRect(option->exposedRect);
	painter->translate(contentsRect().topLeft()); // + QPoint(p.width(),p.width()));

	if(sceneContextHint() == MyGraphicsScene::StaticPreview || !modelItem()->shadowEnabled())
	{
		// If we're drawing in a Preview scene, then we render directly with the painter
		// (rather than caching the results in a pixmap) because this allows the painter 
		// to scale the text glyphs directly (vector scaling), rather than scaling bits 
		// in a pixmap (bitmap scaling), producing more legible results at lower scalings
		
// 		qDebug() << modelItem()->itemName()<<"TextBoxContent::paint: Rendering either preview or no shadow";
		
		QAbstractTextDocumentLayout::PaintContext pCtx;

		// What was this for - improving performance?
		// I've removed it because it seems to be causing the issue reported in Issue #51 on the google code issues tracker.
		// I'll keep an eye on performance to see if it suffers at all. For now, closing issue #51.
		//pCtx.clip = option->exposedRect;
		
		bool needRestore = false;
		
		if(m_zoomEnabled && sceneContextHint() == MyGraphicsScene::Live)
		{
			needRestore = true;
			painter->save();
			double xf = (1/m_zoomDestPoint.x());
			double yf = (1/m_zoomDestPoint.y());
			double sx = m_zoomCurSize.x() / m_zoomStartSize.x();
			double sy = m_zoomCurSize.y() / m_zoomStartSize.y();
			QRect cRect = contentsRect();
			painter->translate(cRect.width()/xf - m_zoomCurSize.x()/xf,cRect.height()/yf - m_zoomCurSize.y()/yf);
			painter->scale(sx,sy);
			
// 			qDebug() << modelItem()->itemName()<<"TextBoxContent::paint: Enabling tranlate & scale. Scale:"<<sx<<","<<sy<<". xf/yf:"<<xf<<","<<yf;
		}
			
			
	
		if(modelItem()->shadowEnabled())
		{
// 			qDebug() << modelItem()->itemName()<<"TextBoxContent::paint: Drawing m_shadowText";
							
			painter->save();
			
			painter->translate(modelItem()->shadowOffsetX(),modelItem()->shadowOffsetY());
			m_shadowText->documentLayout()->draw(painter, pCtx);
	
			painter->restore();
		}
		
		m_text->documentLayout()->draw(painter, pCtx);
		
		if(needRestore)
			painter->restore();
		
	}
	else
	{
		QPixmap cache;
// 		qDebug() << modelItem()->itemName()<<"TextBoxContent::paint: Rendering either live or with shadow";
		
		// The primary and only reason we cache the text rendering is inorder
		// to paint the text and shadow as a single unit (e.g. composite the
		// shadow+text BEFORE applying opacity rather than setting the opacity
		// before rendering the shaodw.) If we didnt cache the text as a pixmap
		// (e.g. render text directly) then when crossfading, the shadow
		// "apperas" to fade out last, after the text.
		
		// Update 20091015: Implemented very aggressive caching across TextBoxContent instances
		// that share the same modelItem() (see ::cacheKey()) inorder to avoid re-rendering 
		// potentially expensive drop shadows, below.
		
		
		
		QString key = cacheKey();
		if(m_text->toPlainText().trimmed().isEmpty())
		{
			// "<< m_text->toHtml()<<"
			//qDebug() << modelItem()->itemName()<<": Not rendering cache because:"<< QPixmapCache::find(key,cache)<< " or ...";//plain "<<m_text->toPlainText()<<" is empty";
			cache = QPixmap(contentsRect().size());
			cache.fill(Qt::transparent);
		}
		else
		{
			if(!QPixmapCache::find(key,cache))
			{
				if(QFile(key).exists())
				{
					cache.load(key);
					QPixmapCache::insert(key,cache);
					//qDebug()<<"TextBoxContent::paint(): modelItem:"<<modelItem()->itemName()<<": Cache load from"<<key;
				}
				else
				{
					qDebug()<<"TextBoxContent::paint(): modelItem:"<<modelItem()->itemName()<<": Cache redraw";

					QSizeF shadowSize = modelItem()->shadowEnabled() ? QSizeF(modelItem()->shadowOffsetX(),modelItem()->shadowOffsetY()) : QSizeF(0,0);
					cache = QPixmap((contentsRect().size()+shadowSize).toSize());

					cache.fill(Qt::transparent);
					QPainter textPainter(&cache);

					QAbstractTextDocumentLayout::PaintContext pCtx;

					#if QT46_SHADOW_ENAB == 0
					if(modelItem()->shadowEnabled())
						renderShadow(&textPainter,&pCtx);
					#endif

					// If we're zooming, we want to render the text straight to the painter
					// so it can transform the raw vectors instead of scaling the bitmap.
					// But if we're not zooming, we cache the text with the shadow since it
					// looks better that way when we're crossfading.
					if(!m_zoomEnabled)
						m_text->documentLayout()->draw(&textPainter, pCtx);

					cache.save(key,"PNG");
					QPixmapCache::insert(key, cache);
				}
			}
		}
	
		// Draw a rectangular outline in the editor inorder to visually locate empty text blocks
		if(sceneContextHint() == MyGraphicsScene::Editor &&
			m_text->toPlainText().trimmed() == "")
		{
			QPen p = modelItem() ? modelItem()->outlinePen() : QPen(Qt::black,1.5);
			painter->setPen(p);
			painter->setBrush(Qt::NoBrush);
	
			painter->drawRect(QRect(QPoint(0,0),contentsRect().size()));
		}
		else
		{
			if(m_zoomEnabled)
			{
				double xf = (1/m_zoomDestPoint.x());
				double yf = (1/m_zoomDestPoint.y());
				double sx = m_zoomCurSize.x() / m_zoomStartSize.x();
				double sy = m_zoomCurSize.y() / m_zoomStartSize.y();
				painter->save();
				QRect cRect = contentsRect();
				painter->translate(cRect.width()/xf - m_zoomCurSize.x()/xf,cRect.height()/yf - m_zoomCurSize.y()/yf);
				painter->scale(sx,sy);
				painter->drawPixmap(0,0,cache);
				QAbstractTextDocumentLayout::PaintContext pCtx;
				m_text->documentLayout()->draw(painter, pCtx);
				painter->restore();
				
			}
			else
			{
				painter->drawPixmap(0,0,cache);
				if(sceneContextHint() != MyGraphicsScene::Live && modelItem()->zoomEffectEnabled())
				{
					// cache may not contain the actual text, just shadow, since its not live,
					// so render the text
					QAbstractTextDocumentLayout::PaintContext pCtx;
					m_text->documentLayout()->draw(painter, pCtx);
				}
					
			}
		}
	}


	painter->restore();
	
	//qDebug() << "TextBoxContent::paint(): \t \t Elapsed:"<<(((double)total.elapsed())/1000.0)<<" sec";
}
Esempio n. 8
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);
}