//----------------------------------------------------------------------------- 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 (); } }
//----------------------------------------------------------------------------- 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 (); } }
//----------------------------------------------------------------------------- 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 (); } }
void VGraphicPath::SetPosBy(GReal inHoriz, GReal inVert) { #if !GRAPHIC_MIXED_GDIPLUS_D2D if (!VWinD2DGraphicContext::IsAvailable()) { #endif Gdiplus::Matrix matrix; matrix.Translate(inHoriz, inVert); fPath->Transform(&matrix); #if !GRAPHIC_MIXED_GDIPLUS_D2D } #endif #if ENABLE_D2D if (VWinD2DGraphicContext::IsAvailable() && fPathD2D) { End(); VAffineTransform mat; mat.SetTranslation( inHoriz, inVert); D2D1_MATRIX_3X2_F matNative; mat.ToNativeMatrix((D2D_MATRIX_REF)&matNative); ID2D1Geometry *sourcePath = fPathD2D; ID2D1TransformedGeometry *thisPath = NULL; VWinD2DGraphicContext::GetMutexFactory().Lock(); bool ok = SUCCEEDED(VWinD2DGraphicContext::GetFactory()->CreateTransformedGeometry( sourcePath, &matNative, &thisPath)); VWinD2DGraphicContext::GetMutexFactory().Unlock(); xbox_assert(ok); if (ok) { fPathD2D = thisPath; sourcePath->Release(); } else return; } #endif fPolygon.SetPosBy(inHoriz, inVert); if (fComputeBoundsAccurate) { VPoint translate( (SmallReal)inHoriz, (SmallReal)inVert); if (fPathMin != GP_BOUNDS_MIN_DEFAULT) fPathMin += translate; if (fPathMax != GP_BOUNDS_MAX_DEFAULT) fPathMax += translate; } _ComputeBounds(); if (fCreateStorageForCrispEdges) { fDrawCmds.push_back( VGraphicPathDrawCmd( GPDCT_SET_POS_BY, inHoriz, inVert)); fCurTransform.Translate( inHoriz, inVert, VAffineTransform::MatrixOrderAppend); } }
//----------------------------------------------------------------------------- void D2DDrawContext::drawGraphicsPath (CGraphicsPath* _path, PathDrawMode mode, CGraphicsTransform* t) { if (renderTarget == 0) return; D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path); if (d2dPath == 0) return; ID2D1PathGeometry* path = d2dPath->getPath (mode == kPathFilledEvenOdd ? 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 (); } getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Translation ((FLOAT)getOffset ().x, (FLOAT)getOffset ().y)); if (mode == kPathFilled || mode == kPathFilledEvenOdd) getRenderTarget ()->FillGeometry (geometry, getFillBrush ()); else if (mode == kPathStroked) getRenderTarget ()->DrawGeometry (geometry, getStrokeBrush (), (FLOAT)getLineWidth (), getStrokeStyle ()); getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Identity ()); geometry->Release (); } }
void VGraphicPath::Widen(const GReal inStrokeWidth, ID2D1StrokeStyle* inStrokeStyle) { xbox_assert(inStrokeStyle); End(); if (fPathD2D != NULL) { CComPtr<ID2D1StrokeStyle> strokeStyle = (ID2D1StrokeStyle *)inStrokeStyle; ID2D1Geometry *oldPath = fPathD2D; //create new path ID2D1PathGeometry *newPath = NULL; VWinD2DGraphicContext::GetMutexFactory().Lock(); HRESULT hr = VWinD2DGraphicContext::GetFactory()->CreatePathGeometry( &newPath); xbox_assert(SUCCEEDED(hr)); VWinD2DGraphicContext::GetMutexFactory().Unlock(); //widen current path CComPtr<ID2D1GeometrySink> thisGeomSink; if (SUCCEEDED(newPath->Open(&thisGeomSink))) { thisGeomSink->SetFillMode( fFillMode == FILLRULE_EVENODD ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING); if (!SUCCEEDED(oldPath->Widen( inStrokeWidth, strokeStyle, NULL, 0.0f, thisGeomSink))) { newPath->Release(); return; } thisGeomSink->Close(); } fPathD2D = newPath; oldPath->Release(); fCreateStorageForCrispEdges = false; fHasBezier = false; fDrawCmds.clear(); fCurTransform.MakeIdentity(); } }
//----------------------------------------------------------------------------- void D2DDrawContext::drawGraphicsPath (CGraphicsPath* _path, PathDrawMode mode, CGraphicsTransform* t) { if (renderTarget == 0) return; bool halfPointOffset = (mode == kPathStroked || 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 (mode == kPathFilledEvenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING, currentState.drawMode.integralMode () ? this : 0, t); if (path) { if (mode == kPathFilled || mode == kPathFilledEvenOdd) getRenderTarget ()->FillGeometry (path, getFillBrush ()); else if (mode == kPathStroked) getRenderTarget ()->DrawGeometry (path, getStrokeBrush (), (FLOAT)getLineWidth (), getStrokeStyle ()); path->Release (); } }
/** combine current path with the specified path @remarks does not update internal polygon used only by D2D impl for path clipping implementation */ void VGraphicPath::_Combine( const VGraphicPath& inPath, bool inIntersect) { End(); //ensure proper combination if current path or input path is empty if (inPath.GetBounds().GetWidth() == 0.0f || inPath.GetBounds().GetHeight() == 0.0f) { //input path is empty if (inIntersect) Clear(); return; } if (GetBounds().GetWidth() == 0.0f || GetBounds().GetHeight() == 0.0f) { //current path is empty if (inIntersect) return; else *this = inPath; return; } //combine D2D path if appropriate //TODO: make it work for Gdiplus::GraphicPath too ? if (fPathD2D != NULL && inPath.GetImplPathD2D()) { ID2D1Geometry *oldPath = fPathD2D; //create new path ID2D1PathGeometry *newPath = NULL; VWinD2DGraphicContext::GetMutexFactory().Lock(); HRESULT hr = VWinD2DGraphicContext::GetFactory()->CreatePathGeometry( &newPath); xbox_assert(SUCCEEDED(hr)); VWinD2DGraphicContext::GetMutexFactory().Unlock(); //combine current path with input path CComPtr<ID2D1GeometrySink> thisGeomSink; if (SUCCEEDED(newPath->Open(&thisGeomSink))) { thisGeomSink->SetFillMode( fFillMode == FILLRULE_EVENODD ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING); if (!SUCCEEDED(oldPath->CombineWithGeometry( inPath.GetImplPathD2D(), inIntersect ? D2D1_COMBINE_MODE_INTERSECT : D2D1_COMBINE_MODE_UNION, NULL, 0.0f, thisGeomSink ))) { newPath->Release(); return; } thisGeomSink->Close(); } fPathD2D = newPath; oldPath->Release(); if (inIntersect) fBounds.Intersect( inPath.GetBounds()); else fBounds.Union( inPath.GetBounds()); fCreateStorageForCrispEdges = false; fHasBezier = false; fDrawCmds.clear(); fCurTransform.MakeIdentity(); } }