//-----------------------------------------------------------------------------
void GdiplusDrawContext::drawGraphicsPath (CGraphicsPath* _path, PathDrawMode mode, CGraphicsTransform* t)
{
	GdiplusGraphicsPath* gdiPlusPath = dynamic_cast<GdiplusGraphicsPath*> (_path);
	if (gdiPlusPath && pGraphics)
	{
		GdiplusDrawScope drawScope (pGraphics, currentState.clipRect, getCurrentTransform ());

		Gdiplus::GraphicsPath* path = gdiPlusPath->getGraphicsPath ();

		if (t)
		{
			Gdiplus::Matrix matrix;
			convert (matrix, *t);
			path = path->Clone ();
			path->Transform (&matrix);
		}

		if (mode == kPathStroked)
		{
			pGraphics->DrawPath (getPen (), path);
		}
		else
		{
			path->SetFillMode (mode == kPathFilledEvenOdd ? Gdiplus::FillModeAlternate : Gdiplus::FillModeWinding);
			pGraphics->FillPath (getBrush (), path);
		}
		if (path != gdiPlusPath->getGraphicsPath ())
			delete path;
	}
}
//-----------------------------------------------------------------------------
void GdiplusDrawContext::fillRadialGradient (CGraphicsPath* _path, const CGradient& gradient, const CPoint& center, CCoord radius, const CPoint& originOffset, bool evenOdd, CGraphicsTransform* t)
{
#if DEBUG
	DebugPrint ("WARNING: GdiplusDrawContext::fillRadialGradient is not working as expected ! FIXME\n");
#endif
	GdiplusGraphicsPath* gdiPlusPath = dynamic_cast<GdiplusGraphicsPath*> (_path);
	if (gdiPlusPath && pGraphics)
	{
		GdiplusDrawScope drawScope (pGraphics, currentState.clipRect, getCurrentTransform ());

		Gdiplus::GraphicsPath* path = gdiPlusPath->getGraphicsPath ();

		if (t)
		{
			Gdiplus::Matrix matrix;
			convert (matrix, *t);
			path = path->Clone ();
			path->Transform (&matrix);
		}

		path->SetFillMode (evenOdd ? Gdiplus::FillModeAlternate : Gdiplus::FillModeWinding);
		Gdiplus::PointF c1p ((Gdiplus::REAL)(center.x + originOffset.x), (Gdiplus::REAL)(center.y + originOffset.y));

		CRect boundingBox = gdiPlusPath->getBoundingBox ();
		Gdiplus::GraphicsPath brushPath;
		brushPath.AddEllipse ((Gdiplus::REAL)boundingBox.left, (Gdiplus::REAL)boundingBox.top, (Gdiplus::REAL)boundingBox.getWidth (), (Gdiplus::REAL)boundingBox.getHeight ());
		Gdiplus::Matrix graphicsMatrix;
		pGraphics->GetTransform (&graphicsMatrix);
		brushPath.Transform (&graphicsMatrix);

		Gdiplus::PathGradientBrush brush (&brushPath);
		// set center
		brush.SetCenterPoint (c1p);
		// set the colors
		Gdiplus::Color* colors = new Gdiplus::Color [gradient.getColorStops ().size ()];
		Gdiplus::REAL* positions = new Gdiplus::REAL [gradient.getColorStops ().size ()];
		uint32_t index = 0;
		for (CGradient::ColorStopMap::const_iterator it = gradient.getColorStops ().begin (); it != gradient.getColorStops ().end (); ++it, ++index)
		{
			CColor color = it->second;
			color.alpha = (int8_t)((float)color.alpha * currentState.globalAlpha);
			colors[index] = createGdiPlusColor (color);
			positions[index] = (Gdiplus::REAL)it->first;
		}
		brush.SetCenterColor (colors[0]);
		INT count = static_cast<INT> (gradient.getColorStops ().size ()) - 1;
		brush.SetSurroundColors (colors+1, &count);

		pGraphics->FillPath (&brush, path);
		if (path != gdiPlusPath->getGraphicsPath ())
			delete path;
		delete [] colors;
		delete [] positions;
	}
}
Beispiel #3
0
//-----------------------------------------------------------------------------
CGContextRef CGDrawContext::beginCGContext (bool swapYAxis, bool integralOffset)
{
    if (cgContext)
    {
        if (currentState.clipRect.isEmpty ())
            return 0;

        CGContextSaveGState (cgContext);

        CGRect cgClipRect = CGRectFromCRect (currentState.clipRect);
        if (integralOffset)
            cgClipRect = pixelAlligned (cgClipRect);
        CGContextClipToRect (cgContext, cgClipRect);
#if DEBUG
        if (showClip)
        {
            CGContextSetRGBFillColor (cgContext, 1, 0, 0, 0.5);
            CGContextFillRect (cgContext, cgClipRect);
        }
#endif

        if (getCurrentTransform ().isInvariant () == false)
        {
            CGraphicsTransform t = getCurrentTransform ();
            if (integralOffset)
            {
                CGPoint p = pixelAlligned (CGPointFromCPoint (CPoint (t.dx, t.dy)));
                t.dx = p.x;
                t.dy = p.y;
            }
            CGContextConcatCTM (cgContext, QuartzGraphicsPath::createCGAffineTransform (t));
        }

        if (!swapYAxis)
            CGContextScaleCTM (cgContext, 1, -1);

        return cgContext;
    }
    return 0;
}
//-----------------------------------------------------------------------------
void GdiplusDrawContext::drawLine (const LinePair& line)
{
	if (pGraphics && pPen)
	{
		GdiplusDrawScope drawScope (pGraphics, currentState.clipRect, getCurrentTransform ());

		CPoint p1 (line.first);
		CPoint p2 (line.second);

		pGraphics->TranslateTransform (0.5f, 0.5f);
		pGraphics->DrawLine (pPen, (Gdiplus::REAL)p1.x, (Gdiplus::REAL)p1.y, (Gdiplus::REAL)p2.x, (Gdiplus::REAL)p2.y);
		pGraphics->TranslateTransform (-0.5f, -0.5f);
	}
}
//-----------------------------------------------------------------------------
void GdiplusDrawContext::drawEllipse (const CRect &_rect, const CDrawStyle drawStyle)
{
	if (pGraphics)
	{
		GdiplusDrawScope drawScope (pGraphics, currentState.clipRect, getCurrentTransform ());

		CRect rect (_rect);
		rect.normalize ();
		if (pBrush && (drawStyle == kDrawFilled || drawStyle == kDrawFilledAndStroked))
		{
			pGraphics->FillEllipse (pBrush, (Gdiplus::REAL)rect.left, (Gdiplus::REAL)rect.top, (Gdiplus::REAL)rect.getWidth (), (Gdiplus::REAL)rect.getHeight ());
		}
		if (pPen && (drawStyle == kDrawStroked || drawStyle == kDrawFilledAndStroked))
		{
			pGraphics->DrawEllipse (pPen, (Gdiplus::REAL)rect.left, (Gdiplus::REAL)rect.top, (Gdiplus::REAL)rect.getWidth (), (Gdiplus::REAL)rect.getHeight ());
		}
	}
}
//-----------------------------------------------------------------------------
void GdiplusDrawContext::fillLinearGradient (CGraphicsPath* _path, const CGradient& gradient, const CPoint& startPoint, const CPoint& endPoint, bool evenOdd, CGraphicsTransform* t)
{
#if DEBUG
	DebugPrint ("WARNING: GdiplusDrawContext::fillLinearGradient is not working as expected ! FIXME");
#endif
	GdiplusGraphicsPath* gdiPlusPath = dynamic_cast<GdiplusGraphicsPath*> (_path);
	if (gdiPlusPath && pGraphics)
	{
		GdiplusDrawScope drawScope (pGraphics, currentState.clipRect, getCurrentTransform ());

		Gdiplus::GraphicsPath* path = gdiPlusPath->getGraphicsPath ();

		if (t)
		{
			Gdiplus::Matrix matrix;
			convert (matrix, *t);
			path = path->Clone ();
			path->Transform (&matrix);
		}

		Gdiplus::Color* colors = new Gdiplus::Color [gradient.getColorStops ().size ()];
		Gdiplus::REAL* positions = new Gdiplus::REAL [gradient.getColorStops ().size ()];
		uint32_t index = 0;
		for (CGradient::ColorStopMap::const_iterator it = gradient.getColorStops ().begin (); it != gradient.getColorStops ().end (); ++it, ++index)
		{
			CColor color = it->second;
			color.alpha = (int8_t)((float)color.alpha * currentState.globalAlpha);
			colors[index] = createGdiPlusColor (color);
			positions[index] = (Gdiplus::REAL)it->first;
		}

		Gdiplus::PointF c1p ((Gdiplus::REAL)(startPoint.x), (Gdiplus::REAL)(startPoint.y));
		Gdiplus::PointF c2p ((Gdiplus::REAL)(endPoint.x), (Gdiplus::REAL)(endPoint.y));
		Gdiplus::LinearGradientBrush brush (c1p, c2p, colors[0], colors[gradient.getColorStops ().size () - 1]);
		brush.SetInterpolationColors (colors, positions, static_cast<INT> (gradient.getColorStops ().size ()));
		path->SetFillMode (evenOdd ? Gdiplus::FillModeAlternate : Gdiplus::FillModeWinding);

		pGraphics->FillPath (&brush, path);
		if (path != gdiPlusPath->getGraphicsPath ())
			delete path;
		delete [] colors;
		delete [] positions;
	}
}
//-----------------------------------------------------------------------------
void GdiplusDrawContext::drawArc (const CRect& rect, const float _startAngle, const float _endAngle, const CDrawStyle drawStyle)
{
	if (pGraphics)
	{
		GdiplusDrawScope drawScope (pGraphics, currentState.clipRect, getCurrentTransform ());

		float endAngle = _endAngle;
		if (endAngle < _startAngle)
			endAngle += 360.f;
		endAngle = fabs (endAngle - _startAngle);
		Gdiplus::RectF r ((Gdiplus::REAL)rect.left, (Gdiplus::REAL)rect.top, (Gdiplus::REAL)rect.getWidth (), (Gdiplus::REAL)rect.getHeight ());
		Gdiplus::GraphicsPath path;
		path.AddArc (r, _startAngle, endAngle);
		if (drawStyle == kDrawFilled || drawStyle == kDrawFilledAndStroked)
			pGraphics->FillPath (pBrush, &path);
		if (drawStyle == kDrawStroked || drawStyle == kDrawFilledAndStroked)
			pGraphics->DrawPath (pPen, &path);
	}
}
QPoint GraphicsWidget::pickCell(const QPointF &pos) const
{
    //transform the weird skewed coordinates back to
	QPointF localPos = getCurrentTransform().inverted().map(pos);

	int roundedX = qRound(localPos.x());
	int roundedY = qRound(localPos.y());

    //subtract the square grid cell we're on from the floating point location
	float compX = localPos.x() - roundedX;
	float compY = localPos.y() - roundedY;

    //if the point is inside the hexagon then we know it would have been inside the hexagon when it was unskewed
    if (sign(compX) == sign(compY) || DISPLAY_HEXAGON.containsPoint(QPointF(compX, compY), Qt::OddEvenFill))
	{
		return QPoint(roundedX, roundedY);
	}
	else
	{
		//we can tell if the correct hexagon is above, below, left, or right purely by comparing compX and compY
		//if compX + compY is greater than zero, we know it must be y+1 or x+1
		if (compX + compY > 0) {

			//if compY is greater than compX, it is y+1
			if (compY > compX)
				return QPoint(roundedX, roundedY + 1);
			else
				return QPoint(roundedX + 1, roundedY);
		}
		else
		{
			//it must be y-1 or x-1

			//if compY is less than compX, it must be y-1
			if (compY < compX)
				return QPoint(roundedX, roundedY - 1);
			else
				return QPoint(roundedX - 1, roundedY);
		}
	}
}
Beispiel #9
0
//-----------------------------------------------------------------------------
void D2DDrawContext::drawBitmap (CBitmap* bitmap, const CRect& dest, const CPoint& offset, float alpha)
{
	if (renderTarget == 0)
		return;
	D2DApplyClip ac (this);
	if (ac.isEmpty ())
		return;
	
	double transformedScaleFactor = getScaleFactor ();
	CGraphicsTransform t = getCurrentTransform ();
	if (t.m11 == t.m22 && t.m12 == 0 && t.m21 == 0)
		transformedScaleFactor *= t.m11;
	IPlatformBitmap* platformBitmap = bitmap->getBestPlatformBitmapForScaleFactor (transformedScaleFactor);
	D2DBitmap* d2dBitmap = platformBitmap ? dynamic_cast<D2DBitmap*> (platformBitmap) : 0;
	if (d2dBitmap)
	{
		if (d2dBitmap->getSource ())
		{
			ID2D1Bitmap* d2d1Bitmap = D2DBitmapCache::instance ()->getBitmap (d2dBitmap, renderTarget);
			if (d2d1Bitmap)
			{
				double bitmapScaleFactor = platformBitmap->getScaleFactor ();
				CGraphicsTransform bitmapTransform;
				bitmapTransform.scale (bitmapScaleFactor, bitmapScaleFactor);
				Transform transform (*this, bitmapTransform.inverse ());

				CRect d (dest);
				d.makeIntegral ();
				CRect source (dest);
				source.offset (-source.left, -source.top);
				source.offset (offset.x, offset.y);

				bitmapTransform.transform (source);

				D2D1_RECT_F sourceRect = makeD2DRect (source);
				renderTarget->DrawBitmap (d2d1Bitmap, makeD2DRect (d), alpha * currentState.globalAlpha, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, &sourceRect);
			}
		}
	}
}
//-----------------------------------------------------------------------------
void GdiplusDrawContext::drawRect (const CRect &_rect, const CDrawStyle drawStyle)
{
	if (pGraphics)
	{
		GdiplusDrawScope drawScope (pGraphics, currentState.clipRect, getCurrentTransform ());

		CRect rect (_rect);
		rect.normalize ();
		if (pBrush && (drawStyle == kDrawFilled || drawStyle == kDrawFilledAndStroked))
		{
			Gdiplus::RectF r ((Gdiplus::REAL)rect.left, (Gdiplus::REAL)rect.top, (Gdiplus::REAL)rect.getWidth (), (Gdiplus::REAL)rect.getHeight ());
			pGraphics->FillRectangle (pBrush, r);
		}
		if (pPen && (drawStyle == kDrawStroked || drawStyle == kDrawFilledAndStroked))
		{
			Gdiplus::RectF r ((Gdiplus::REAL)rect.left, (Gdiplus::REAL)rect.top, (Gdiplus::REAL)rect.getWidth () - 1, (Gdiplus::REAL)rect.getHeight () - 1);
			pGraphics->TranslateTransform (0.5f, 0.5f);
			pGraphics->DrawRectangle (pPen, r);
			pGraphics->TranslateTransform (-0.5f, -0.5f);
		}
	}
}
Beispiel #11
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawBitmap (CBitmap* bitmap, const CRect& inRect, const CPoint& inOffset, float alpha)
{
    if (bitmap == 0 || alpha == 0.f)
        return;
    double transformedScaleFactor = scaleFactor;
    CGraphicsTransform t = getCurrentTransform ();
    if (t.m11 == t.m22 && t.m12 == 0 && t.m21 == 0)
        transformedScaleFactor *= t.m11;
    IPlatformBitmap* platformBitmap = bitmap->getBestPlatformBitmapForScaleFactor (transformedScaleFactor);
    CGBitmap* cgBitmap = platformBitmap ? dynamic_cast<CGBitmap*> (platformBitmap) : 0;
    CGImageRef image = cgBitmap ? cgBitmap->getCGImage () : 0;
    if (image)
    {
        CGContextRef context = beginCGContext (false, true);
        if (context)
        {
            CGLayerRef layer = cgBitmap->getCGLayer ();
            if (layer == 0)
            {
                BitmapDrawCountMap::iterator it = bitmapDrawCount.find (cgBitmap);
                if (it == bitmapDrawCount.end ())
                {
                    bitmapDrawCount.insert (std::pair<CGBitmap*, int32_t> (cgBitmap, 1));
                }
                else
                {
                    it->second++;
                    layer = cgBitmap->createCGLayer (context);
                }
            }

            drawCGImageRef (context, image, layer, cgBitmap->getScaleFactor (), inRect, inOffset, alpha, bitmap);

            releaseCGContext (context);
        }
    }
}
//-----------------------------------------------------------------------------
void GdiplusDrawContext::drawPolygon (const PointList& polygonPointList, const CDrawStyle drawStyle)
{
	if (polygonPointList.size () == 0)
		return;

	GdiplusDrawScope drawScope (pGraphics, currentState.clipRect, getCurrentTransform ());

	Gdiplus::PointF points[30];
	Gdiplus::PointF* polyPoints;
	bool allocated = false;
	if (polygonPointList.size () > 30)
	{
		polyPoints = new Gdiplus::PointF[polygonPointList.size ()];
		allocated = true;
	}
	else
		polyPoints = points;
	
	for (uint32_t i = 0; i < polygonPointList.size (); i++)
	{
		polyPoints[i].X = (Gdiplus::REAL)(polygonPointList[i].x);
		polyPoints[i].Y = (Gdiplus::REAL)(polygonPointList[i].y);
	}

	if (drawStyle == kDrawFilled || drawStyle == kDrawFilledAndStroked)
		pGraphics->FillPolygon (pBrush, polyPoints, static_cast<INT> (polygonPointList.size ()));
	if (drawStyle == kDrawFilledAndStroked || drawStyle == kDrawStroked)
	{
		pGraphics->TranslateTransform (0.5f, 0.5f);
		pGraphics->DrawPolygon (pPen, polyPoints, static_cast<INT> (polygonPointList.size ()));
		pGraphics->TranslateTransform (-0.5f, -0.5f);
	}

	if (allocated)
		delete[] polyPoints;
}
void GraphicsWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

	//set up painting with antialiasing etc
	QPainter painter;

	painter.begin(&elements);
	painter.setRenderHint(QPainter::Antialiasing);
	painter.setRenderHint(QPainter::HighQualityAntialiasing);
	painter.setRenderHint(QPainter::SmoothPixmapTransform);

	//transform coordinates to fit everything neatly on the screen
	painter.save();
	painter.setWorldTransform(getCurrentTransform());

	if (grid != nullptr)
	{
		//loop through and draw each entry
		for (const auto& cell: grid->getCells())
		{
			GridEntry &entry = grid->getEntry(cell);
			if (entry.modified) {
				entry.modified = false;
				painter.save();

				painter.translate(cell.x(), cell.y());

				QPen pen(Qt::black);
				pen.setWidthF(0);

				painter.setPen(pen);
				if (entry.type == GridEntry::Wall)
					painter.setBrush(Qt::darkBlue);

				else if (entry.type == GridEntry::Start)
					painter.setBrush(Qt::yellow);

				else if (entry.type == GridEntry::End)
					painter.setBrush(Qt::red);

				else if (entry.path)
					painter.setBrush(Qt::white);

				else if (entry.searched)
					painter.setBrush(Qt::cyan);
				
				else
					painter.setBrush(Qt::darkGreen);

                painter.drawConvexPolygon(DISPLAY_HEXAGON);

				painter.restore();
			}
		}
	}

	painter.restore();
	painter.setPen(Qt::white);

	QPainter screenPainter(this);
	screenPainter.fillRect(rect(), QBrush(Qt::black));
	screenPainter.drawImage(0, 0, elements);
}
//-----------------------------------------------------------------------------
void GdiplusDrawContext::drawBitmap (CBitmap* cbitmap, const CRect& dest, const CPoint& offset, float alpha)
{
	alpha *= currentState.globalAlpha;
	if (alpha == 0.f || pGraphics == 0)
		return;
	IPlatformBitmap* platformBitmap = cbitmap ? cbitmap->getPlatformBitmap () : 0;
	GdiplusBitmap* gpb = platformBitmap ? dynamic_cast<GdiplusBitmap*> (platformBitmap) : 0;
	Gdiplus::Bitmap* bitmap = gpb ? gpb->getBitmap () : 0;
	if (bitmap)
	{
		GdiplusDrawScope drawScope (pGraphics, currentState.clipRect, getCurrentTransform ());

		Gdiplus::ImageAttributes imageAtt;
		if (alpha != 1.f)
		{
			// introducing the alpha blend matrix
			Gdiplus::ColorMatrix colorMatrix =
			{
				1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
				0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
				0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
				0.0f, 0.0f, 0.0f, alpha, 0.0f,
				0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
			};
			// create the imageattribute modifier
			imageAtt.SetColorMatrix (&colorMatrix, Gdiplus::ColorMatrixFlagsDefault,
				Gdiplus::ColorAdjustTypeBitmap);
#if 1
			Gdiplus::Rect	myDestRect(
				(INT)dest.left,
				(INT)dest.top,
				(INT)dest.getWidth (),
				(INT)dest.getHeight ());
			pGraphics->DrawImage (
				bitmap,
				myDestRect,
				(INT)offset.x,
				(INT)offset.y,
				(INT)dest.getWidth (),
				(INT)dest.getHeight (),
				Gdiplus::UnitPixel,
				&imageAtt);
#else
			// create a temporary bitmap to prevent OutOfMemory errors
			Gdiplus::Bitmap myBitmapBuffer ((INT)dest.getWidth (), (INT)dest.getHeight (),PixelFormat32bppARGB);
			// create a graphics context for the temporary bitmap
			Gdiplus::Graphics* myGraphicsBuffer = Gdiplus::Graphics::FromImage (&myBitmapBuffer);
			// copy the rectangle we want to paint to the temporary bitmap
			Gdiplus::Rect myTransRect(
				0,
				0,
				(INT)dest.getWidth (),
				(INT)dest.getHeight ());
			// transfer the bitmap (without modification by imageattr!)
			myGraphicsBuffer->DrawImage (
				bitmap,myTransRect,
				(INT)offset.x,
				(INT)offset.y,
				(INT)dest.getWidth (),
				(INT)dest.getHeight (),
				Gdiplus::UnitPixel,
				0);
			// now transfer the temporary to the real context at the advised location
			Gdiplus::Rect myDestRect (
				(INT)dest.left,
				(INT)dest.top,
				(INT)dest.getWidth (),
				(INT)dest.getHeight ());
			// transfer from temporary bitmap to real context (with imageattr)
			pGraphics->DrawImage (
				&myBitmapBuffer,
				myDestRect,
				(INT)0,
				(INT)0,
				(INT)dest.getWidth (),
				(INT)dest.getHeight (),
				Gdiplus::UnitPixel,
				&imageAtt);
			// delete the temporary context of the temporary bitmap
			delete myGraphicsBuffer;
#endif
		}
		else
		{
			Gdiplus::Rect	myDestRect(
				(INT)dest.left,
				(INT)dest.top,
				(INT)dest.getWidth (),
				(INT)dest.getHeight ());
			pGraphics->DrawImage (
				bitmap,
				myDestRect,
				(INT)offset.x,
				(INT)offset.y,
				(INT)dest.getWidth (),
				(INT)dest.getHeight (),
				Gdiplus::UnitPixel,
				0);
		}
	}
}
Beispiel #15
0
//-----------------------------------------------------------------------------
void CDrawContext::setClipRect (const CRect &clip)
{
	currentState.clipRect = clip;
	getCurrentTransform ().transform (currentState.clipRect);
}
Beispiel #16
0
//-----------------------------------------------------------------------------
CRect& CDrawContext::getClipRect (CRect &clip) const
{
	clip = currentState.clipRect;
	getCurrentTransform ().inverse ().transform (clip);
	return clip;
}