//----------------------------------------------------------------------------- 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; } }
Gdiplus::Brush* GetGdiBrush(IPDBrush* brush, PDBrushType brushType = BRUSH_NONE) { Gdiplus::Brush* pBrush = NULL; if (brushType == BRUSH_NONE) { if (brush) brush->get_brushType(&brushType); } if (brushType == (PDBrushType)tomUndefined) { } else if (brushType == BRUSH_COLOR) { CComPtr<IPDColor> color; brush->get_tintedRGBColor(&color); if (color) { double red; color->getChannel(0, &red); double green; color->getChannel(1, &green); double blue; color->getChannel(2, &blue); pBrush = new Gdiplus::SolidBrush(Gdiplus::Color(255, red, green, blue)); } } else if (brushType == BRUSH_GRADIENT) { CComPtr<IPDGradient> gradient; brush->get_gradient(&gradient); if (gradient) { PDGradientType gradientType; gradient->get_type(&gradientType); double x1; brush->get_x1(&x1); double y1; brush->get_y1(&y1); double x2; brush->get_x2(&x2); double y2; brush->get_y2(&y2); CArray<Gdiplus::REAL, Gdiplus::REAL> offsets; CArray<Gdiplus::Color,Gdiplus::Color&> colors; CreateGradient(offsets, colors, gradient); if (gradientType == GRADIENT_LINEAR) { Gdiplus::LinearGradientBrush* pGradBrush = new Gdiplus::LinearGradientBrush( Gdiplus::Point(x1, y1), Gdiplus::Point(x2, y2), Gdiplus::Color(0,0,0,0), Gdiplus::Color(0,0,0,0)); pGradBrush->SetInterpolationColors(colors.GetData(), offsets.GetData(), colors.GetSize()); pBrush = pGradBrush; } else if (gradientType == GRADIENT_RADIAL) { double dx = x2-x1; double dy = y2-y1; double radius = sqrt(dx*dx+dy*dy); Gdiplus::GraphicsPath path; path.AddEllipse((float)(x1-radius), (float)(y1-radius), (float)(x1+radius), (float)(y1+radius)); Gdiplus::PathGradientBrush* pGradBrush = new Gdiplus::PathGradientBrush(&path); pGradBrush->SetInterpolationColors(colors.GetData(), offsets.GetData(), colors.GetSize()); pBrush = pGradBrush; } else ATLASSERT(0); } } else if (brushType == BRUSH_PATTERN) { CComPtr<IPDSwatch> swatch; brush->get_swatch(&swatch); CComQIPtr<IPDSwatchPattern> swatchPattern = swatch; CComPtr<IPDObjectGroup> objectGroup; swatchPattern->get_objectGroup(&objectGroup); if (objectGroup) { CPDObjectGroup* pGroup = static_cast<CPDObjectGroup*>(objectGroup.p); RectD bounds; pGroup->get_bounds(&bounds); Gdiplus::Bitmap bitmap(bounds.Width, bounds.Height); { Gdiplus::Graphics graphics(&bitmap); //graphics.ScaleTransform(swatchRect.Width()/bounds.Width, swatchRect.Height()/bounds.Height); graphics.TranslateTransform(-bounds.X, -bounds.Y); pGroup->Render(NULL, &graphics, 1, 1/*TODO*/); } Gdiplus::TextureBrush* pTexBrush = new Gdiplus::TextureBrush(&bitmap); pBrush = pTexBrush; } } return pBrush; }