示例#1
0
//-----------------------------------------------------------------------------
void D2DDrawContext::fillLinearGradient (CGraphicsPath* _path, const CGradient& gradient, const CPoint& startPoint, const CPoint& endPoint, bool evenOdd, CGraphicsTransform* t)
{
    if (renderTarget == 0)
        return;

    D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path);
    if (d2dPath == 0)
        return;

    ID2D1PathGeometry* path = d2dPath->getPath (evenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING);
    if (path)
    {
        D2DApplyClip ac (this);

        ID2D1Geometry* geometry = 0;
        if (t)
        {
            ID2D1TransformedGeometry* tg = 0;
            D2D1_MATRIX_3X2_F matrix;
            matrix._11 = (FLOAT)t->m11;
            matrix._12 = (FLOAT)t->m12;
            matrix._21 = (FLOAT)t->m21;
            matrix._22 = (FLOAT)t->m22;
            matrix._31 = (FLOAT)t->dx;
            matrix._32 = (FLOAT)t->dy;
            getD2DFactory ()->CreateTransformedGeometry (path, matrix, &tg);
            geometry = tg;
        }
        else
        {
            geometry = path;
            geometry->AddRef ();
        }

        ID2D1GradientStopCollection* collection = 0;
        D2D1_GRADIENT_STOP gradientStops[2];
        gradientStops[0].position = (FLOAT)gradient.getColor1Start ();
        gradientStops[1].position = (FLOAT)gradient.getColor2Start ();
        gradientStops[0].color = D2D1::ColorF (gradient.getColor1 ().red/255.f, gradient.getColor1 ().green/255.f, gradient.getColor1 ().blue/255.f, gradient.getColor1 ().alpha/255.f * currentState.globalAlpha);
        gradientStops[1].color = D2D1::ColorF (gradient.getColor2 ().red/255.f, gradient.getColor2 ().green/255.f, gradient.getColor2 ().blue/255.f, gradient.getColor2 ().alpha/255.f * currentState.globalAlpha);

        if (SUCCEEDED (getRenderTarget ()->CreateGradientStopCollection (gradientStops, 2, &collection)))
        {
            ID2D1LinearGradientBrush* brush = 0;
            D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES properties;
            properties.startPoint = makeD2DPoint (startPoint);
            properties.endPoint = makeD2DPoint (endPoint);
            if (SUCCEEDED (getRenderTarget ()->CreateLinearGradientBrush (properties, collection, &brush)))
            {
                getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Translation ((FLOAT)getOffset ().x, (FLOAT)getOffset ().y));
                getRenderTarget ()->FillGeometry (geometry, brush);
                getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Identity ());
                brush->Release ();
            }
            collection->Release ();
        }

        geometry->Release ();
    }
}
示例#2
0
// once again, this is based on the Microsoft sample above
static void drawOpacitySlider(struct colorDialog *c, ID2D1RenderTarget *rt)
{
	D2D1_SIZE_F size;
	D2D1_RECT_F rect;
	D2D1_GRADIENT_STOP stops[2];
	ID2D1GradientStopCollection *collection;
	D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES lprop;
	D2D1_BRUSH_PROPERTIES bprop;
	ID2D1LinearGradientBrush *brush;
	double hypot;
	D2D1_POINT_2F center;
	HRESULT hr;

	size = realGetSize(rt);
	rect.left = 0;
	rect.top = 0;
	rect.right = size.width;
	rect.bottom = size.height * (5.0 / 6.0);		// bottommost sixth for arrow

	drawGrid(rt, &rect);

	stops[0].position = 0.0;
	stops[0].color.r = 0.0;
	stops[0].color.g = 0.0;
	stops[0].color.b = 0.0;
	stops[0].color.a = 1.0;
	stops[1].position = 1.0;
	stops[1].color.r = 1.0;		// this is the XAML color Transparent, as in the source
	stops[1].color.g = 1.0;
	stops[1].color.b = 1.0;
	stops[1].color.a = 0.0;
	hr = rt->CreateGradientStopCollection(stops, 2,
		// note that in this case this gamma is explicitly specified by the original
		D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP,
		&collection);
	if (hr != S_OK)
		logHRESULT(L"error creating stop collection for opacity slider gradient", hr);
	ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES));
	lprop.startPoint.x = 0;
	lprop.startPoint.y = (rect.bottom - rect.top) / 2;
	lprop.endPoint.x = size.width;
	lprop.endPoint.y = (rect.bottom - rect.top) / 2;
	ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES));
	bprop.opacity = 1.0;
	bprop.transform._11 = 1;
	bprop.transform._22 = 1;
	hr = rt->CreateLinearGradientBrush(&lprop, &bprop,
		collection, &brush);
	if (hr != S_OK)
		logHRESULT(L"error creating gradient brush for opacity slider", hr);
	rt->FillRectangle(&rect, brush);
	brush->Release();
	collection->Release();

	// now draw a black arrow
	center.x = (1 - c->a) * size.width;
	center.y = size.height;
	hypot = size.height - rect.bottom;
	drawArrow(rt, center, hypot);
}
示例#3
0
//-----------------------------------------------------------------------------
void D2DDrawContext::fillLinearGradient (CGraphicsPath* _path, const CGradient& gradient, const CPoint& startPoint, const CPoint& endPoint, bool evenOdd, CGraphicsTransform* t)
{
	if (renderTarget == 0)
		return;

	bool halfPointOffset = currentState.drawMode.integralMode () ? ((((int32_t)currentState.frameWidth) % 2) != 0) : false;
	D2DApplyClip ac (this, halfPointOffset);
	if (ac.isEmpty ())
		return;
	
	D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path);
	if (d2dPath == 0)
		return;

	ID2D1Geometry* path = d2dPath->createPath (evenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING, this, t);
	if (path)
	{

		ID2D1GradientStopCollection* collection = createGradientStopCollection (gradient);
		if (collection)
		{
			ID2D1LinearGradientBrush* brush = 0;
			D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES properties;
			properties.startPoint = makeD2DPoint (startPoint);
			properties.endPoint = makeD2DPoint (endPoint);
			if (SUCCEEDED (getRenderTarget ()->CreateLinearGradientBrush (properties, collection, &brush)))
			{
				getRenderTarget ()->FillGeometry (path, brush);
				brush->Release ();
			}
			collection->Release ();
		}
		path->Release ();
	}
}
示例#4
0
//-----------------------------------------------------------------------------
void D2DDrawContext::fillRadialGradient (CGraphicsPath* _path, const CGradient& gradient, const CPoint& center, CCoord radius, const CPoint& originOffset, bool evenOdd, CGraphicsTransform* t)
{
	if (renderTarget == 0)
		return;

	D2DApplyClip ac (this);
	if (ac.isEmpty ())
		return;
	
	D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path);
	if (d2dPath == 0)
		return;

	ID2D1Geometry* path = d2dPath->createPath (evenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING);
	if (path)
	{
		ID2D1Geometry* geometry = 0;
		if (t)
		{
			ID2D1TransformedGeometry* tg = 0;
			getD2DFactory ()->CreateTransformedGeometry (path, convert (*t), &tg);
			geometry = tg;
		}
		else
		{
			geometry = path;
			geometry->AddRef ();
		}
		ID2D1GradientStopCollection* collection = createGradientStopCollection (gradient);
		if (collection)
		{
			// brush properties
			ID2D1RadialGradientBrush* brush = 0;
			D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES properties;
			properties.center = makeD2DPoint (center);
			properties.gradientOriginOffset = makeD2DPoint (originOffset);
			properties.radiusX = (FLOAT)radius;
			properties.radiusY = (FLOAT)radius;

			if (SUCCEEDED (getRenderTarget ()->CreateRadialGradientBrush (properties, collection, &brush)))
			{
				getRenderTarget ()->FillGeometry (geometry, brush);
				brush->Release ();
			}
			collection->Release ();
		}
		geometry->Release ();
		path->Release ();
	}
}
示例#5
0
static void drawHSlider(struct colorDialog *c, ID2D1RenderTarget *rt)
{
	D2D1_SIZE_F size;
	D2D1_RECT_F rect;
	D2D1_GRADIENT_STOP stops[nStops];
	double r, g, b;
	int i;
	double h;
	ID2D1GradientStopCollection *collection;
	D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES lprop;
	D2D1_BRUSH_PROPERTIES bprop;
	ID2D1LinearGradientBrush *brush;
	double hypot;
	D2D1_POINT_2F center;
	HRESULT hr;

	size = realGetSize(rt);
	rect.left = size.width / 6;		// leftmost sixth for arrow
	rect.top = 0;
	rect.right = size.width;
	rect.bottom = size.height;

	for (i = 0; i < nStops; i++) {
		h = ((double) (i * degPerStop)) / 360.0;
		if (i == (nStops - 1))
			h = 0;
		hsv2RGB(h, 1.0, 1.0, &r, &g, &b);
		stops[i].position = ((double) i) * stopIncr;
		stops[i].color.r = r;
		stops[i].color.g = g;
		stops[i].color.b = b;
		stops[i].color.a = 1.0;
	}
	// and pin the last one
	stops[i - 1].position = 1.0;

	hr = rt->CreateGradientStopCollection(stops, nStops,
		// note that in this case this gamma is explicitly specified by the original
		D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP,
		&collection);
	if (hr != S_OK)
		logHRESULT(L"error creating stop collection for H slider gradient", hr);
	ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES));
	lprop.startPoint.x = (rect.right - rect.left) / 2;
	lprop.startPoint.y = 0;
	lprop.endPoint.x = (rect.right - rect.left) / 2;
	lprop.endPoint.y = size.height;
	ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES));
	bprop.opacity = 1.0;
	bprop.transform._11 = 1;
	bprop.transform._22 = 1;
	hr = rt->CreateLinearGradientBrush(&lprop, &bprop,
		collection, &brush);
	if (hr != S_OK)
		logHRESULT(L"error creating gradient brush for H slider", hr);
	rt->FillRectangle(&rect, brush);
	brush->Release();
	collection->Release();

	// now draw a black arrow
	center.x = 0;
	center.y = c->h * size.height;
	hypot = rect.left;
	drawArrow(rt, center, hypot);
}
示例#6
0
// this interesting approach comes from http://blogs.msdn.com/b/wpfsdk/archive/2006/10/26/uncommon-dialogs--font-chooser-and-color-picker-dialogs.aspx
static void drawSVChooser(struct colorDialog *c, ID2D1RenderTarget *rt)
{
	D2D1_SIZE_F size;
	D2D1_RECT_F rect;
	double rTop, gTop, bTop;
	D2D1_GRADIENT_STOP stops[2];
	ID2D1GradientStopCollection *collection;
	D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES lprop;
	D2D1_BRUSH_PROPERTIES bprop;
	ID2D1LinearGradientBrush *brush;
	ID2D1LinearGradientBrush *opacity;
	ID2D1Layer *layer;
	D2D1_LAYER_PARAMETERS layerparams;
	D2D1_ELLIPSE mparam;
	D2D1_COLOR_F mcolor;
	ID2D1SolidColorBrush *markerBrush;
	HRESULT hr;

	size = realGetSize(rt);
	rect.left = 0;
	rect.top = 0;
	rect.right = size.width;
	rect.bottom = size.height;

	drawGrid(rt, &rect);

	// first, draw a vertical gradient from the current hue at max S/V to black
	// the source example draws it upside down; let's do so too just to be safe
	hsv2RGB(c->h, 1.0, 1.0, &rTop, &gTop, &bTop);
	stops[0].position = 0;
	stops[0].color.r = 0.0;
	stops[0].color.g = 0.0;
	stops[0].color.b = 0.0;
	stops[0].color.a = 1.0;
	stops[1].position = 1;
	stops[1].color.r = rTop;
	stops[1].color.g = gTop;
	stops[1].color.b = bTop;
	stops[1].color.a = 1.0;
	hr = rt->CreateGradientStopCollection(stops, 2,
		D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP,
		&collection);
	if (hr != S_OK)
		logHRESULT(L"error making gradient stop collection for first gradient in SV chooser", hr);
	ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES));
	lprop.startPoint.x = size.width / 2;
	lprop.startPoint.y = size.height;
	lprop.endPoint.x = size.width / 2;
	lprop.endPoint.y = 0;
	// TODO decide what to do about the duplication of this
	ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES));
	bprop.opacity = c->a;		// note this part; we also use it below for the layer
	bprop.transform._11 = 1;
	bprop.transform._22 = 1;
	hr = rt->CreateLinearGradientBrush(&lprop, &bprop,
		collection, &brush);
	if (hr != S_OK)
		logHRESULT(L"error making gradient brush for first gradient in SV chooser", hr);
	rt->FillRectangle(&rect, brush);
	brush->Release();
	collection->Release();

	// second, create an opacity mask for the third step: a horizontal gradientthat goes from opaque to translucent
	stops[0].position = 0;
	stops[0].color.r = 0.0;
	stops[0].color.g = 0.0;
	stops[0].color.b = 0.0;
	stops[0].color.a = 1.0;
	stops[1].position = 1;
	stops[1].color.r = 0.0;
	stops[1].color.g = 0.0;
	stops[1].color.b = 0.0;
	stops[1].color.a = 0.0;
	hr = rt->CreateGradientStopCollection(stops, 2,
		D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP,
		&collection);
	if (hr != S_OK)
		logHRESULT(L"error making gradient stop collection for opacity mask gradient in SV chooser", hr);
	ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES));
	lprop.startPoint.x = 0;
	lprop.startPoint.y = size.height / 2;
	lprop.endPoint.x = size.width;
	lprop.endPoint.y = size.height / 2;
	ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES));
	bprop.opacity = 1.0;
	bprop.transform._11 = 1;
	bprop.transform._22 = 1;
	hr = rt->CreateLinearGradientBrush(&lprop, &bprop,
		collection, &opacity);
	if (hr != S_OK)
		logHRESULT(L"error making gradient brush for opacity mask gradient in SV chooser", hr);
	collection->Release();

	// finally, make a vertical gradient from white at the top to black at the bottom (right side up this time) and with the previous opacity mask
	stops[0].position = 0;
	stops[0].color.r = 1.0;
	stops[0].color.g = 1.0;
	stops[0].color.b = 1.0;
	stops[0].color.a = 1.0;
	stops[1].position = 1;
	stops[1].color.r = 0.0;
	stops[1].color.g = 0.0;
	stops[1].color.b = 0.0;
	stops[1].color.a = 1.0;
	hr = rt->CreateGradientStopCollection(stops, 2,
		D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP,
		&collection);
	if (hr != S_OK)
		logHRESULT(L"error making gradient stop collection for second gradient in SV chooser", hr);
	ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES));
	lprop.startPoint.x = size.width / 2;
	lprop.startPoint.y = 0;
	lprop.endPoint.x = size.width / 2;
	lprop.endPoint.y = size.height;
	ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES));
	bprop.opacity = 1.0;
	bprop.transform._11 = 1;
	bprop.transform._22 = 1;
	hr = rt->CreateLinearGradientBrush(&lprop, &bprop,
		collection, &brush);
	if (hr != S_OK)
		logHRESULT(L"error making gradient brush for second gradient in SV chooser", hr);
	// oh but wait we can't use FillRectangle() with an opacity mask
	// and we can't use FillGeometry() with both an opacity mask and a non-bitmap
	// layers it is!
	hr = rt->CreateLayer(&size, &layer);
	if (hr != S_OK)
		logHRESULT(L"error making layer for second gradient in SV chooser", hr);
	ZeroMemory(&layerparams, sizeof (D2D1_LAYER_PARAMETERS));
	layerparams.contentBounds = rect;
	// TODO make sure these are right
	layerparams.geometricMask = NULL;
	layerparams.maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
	layerparams.maskTransform._11 = 1;
	layerparams.maskTransform._22 = 1;
	layerparams.opacity = c->a;			// here's the other use of c->a to note
	layerparams.opacityBrush = opacity;
	layerparams.layerOptions = D2D1_LAYER_OPTIONS_NONE;
	rt->PushLayer(&layerparams, layer);
	rt->FillRectangle(&rect, brush);
	rt->PopLayer();
	layer->Release();
	brush->Release();
	collection->Release();
	opacity->Release();

	// and now we just draw the marker
	ZeroMemory(&mparam, sizeof (D2D1_ELLIPSE));
	mparam.point.x = c->s * size.width;
	mparam.point.y = (1 - c->v) * size.height;
	mparam.radiusX = 7;
	mparam.radiusY = 7;
	// TODO make the color contrast?
	mcolor.r = 1.0;
	mcolor.g = 1.0;
	mcolor.b = 1.0;
	mcolor.a = 1.0;
	bprop.opacity = 1.0;		// the marker should always be opaque
	hr = rt->CreateSolidColorBrush(&mcolor, &bprop, &markerBrush);
	if (hr != S_OK)
		logHRESULT(L"error creating brush for SV chooser marker", hr);
	rt->DrawEllipse(&mparam, markerBrush, 2, NULL);
	markerBrush->Release();
}
// Create device resources
HRESULT DemoApp::CreateDeviceResources()
{
	HRESULT hr = S_OK;
	if (!m_pRenderTarget)
	{
		RECT rc;
		GetClientRect(m_hwnd, &rc);

		D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);

		// Create a Direct2D render target
		hr = m_pD2DFactory->CreateHwndRenderTarget(
			D2D1::RenderTargetProperties(),
			D2D1::HwndRenderTargetProperties(m_hwnd, size),
			&m_pRenderTarget);
		if (SUCCEEDED(hr))
		{
			// Create a black brush
			hr = m_pRenderTarget->CreateSolidColorBrush(
				D2D1::ColorF(D2D1::ColorF::Black),
				&m_pBlackBrush);
		}
		if (SUCCEEDED(hr))
		{
			ID2D1GradientStopCollection *pGradientStops = NULL;
			static const D2D1_GRADIENT_STOP stops[]=
			{
				{0.f,{0.f,1.f,1.f,0.25f}},
				{1.f,{0.f,0.f,1.f,1.f}}
			};

			hr = m_pRenderTarget->CreateGradientStopCollection(
				stops, ARRAYSIZE(stops),
				&pGradientStops);
			if (SUCCEEDED(hr))
			{
				hr = m_pRenderTarget->CreateLinearGradientBrush(
					D2D1::LinearGradientBrushProperties(
						D2D1::Point2F(100, 0),
						D2D1::Point2F(100, 200)),
					D2D1::BrushProperties(),
					pGradientStops,
					&m_pLinearGradientBrush);
				pGradientStops->Release();
			}
		}

		// Create a bitmap from an application resource
		hr = LoadResourceBitmap(
			m_pRenderTarget,
			m_pWICFactory,
			L"SampleImage",
			L"Image",
			100, 0,
			&m_pBitmap);
		if (SUCCEEDED(hr))
		{
			// Create a bitmap by loading it from a file
			hr = LoadBitmapFromFile(
				m_pRenderTarget,
				m_pWICFactory,
				L".\\sampleImage.jpg",
				100, 0,
				&m_pAnotherBitmap);
		}
		if (SUCCEEDED(hr))
			hr = CreateGridPatternBrush(m_pRenderTarget, &m_pGridPatternBitmapBrush);
	}

	return hr;
}