bool IProxyDrawingContext.DrawGlyphs(GlyphRun glyphrun, Geometry clip, Matrix trans, BrushProxy foreground) { Debug.Assert(!_costing, "in costing mode DrawyGlyphs"); BrushProxy bp = BrushProxy.BlendColorWithBrush(false, Colors.White, foreground, false); Brush b = bp.Brush; if ((b == null) || (b is DrawingBrush)) { return(false); } if (clip != null) { _dc.PushClip(clip); } if (!trans.IsIdentity) { _dc.PushTransform(trans); } #if DEBUG _seq++; _dc.Comment("-> DrawGlyphRun " + _seq); #endif _dc.DrawGlyphRun(b, glyphrun); #if DEBUG _dc.Comment("<- DrawGlyphRun " + _seq); if (Configuration.Verbose >= 2) { Console.WriteLine(" DrawGlyphRun(" + _comment + ")"); } #endif if (!trans.IsIdentity) { _dc.PopTransform(); } if (clip != null) { _dc.PopClip(); } return(true); }
void IProxyDrawingContext.DrawGeometry(BrushProxy brush, PenProxy pen, Geometry geometry, Geometry clip, Matrix brushTrans, ProxyDrawingFlags flags) { Debug.Assert(brushTrans.IsIdentity, "brushTrans not supported"); if ((brush == null) && (pen == null)) { return; } if (!_costing && (clip != null)) { _dc.PushClip(clip); } if (brush != null) { brush = BrushProxy.BlendColorWithBrush(false, Colors.White, brush, false); } // Simplification, pushing transformation if (geometry is LineGeometry) { LineGeometry line = geometry.CloneCurrentValue() as LineGeometry; line.StartPoint = geometry.Transform.Value.Transform(line.StartPoint); line.EndPoint = geometry.Transform.Value.Transform(line.EndPoint); line.Transform = Transform.Identity; } if ((brush != null) && (brush.BrushList != null)) // List of brushes { Debug.Assert(pen == null, "no pen"); if (_costing) { FillGeometry(brush.BrushList[0] as BrushProxy, brush.BrushList, 1, geometry); } else { bool rasterize = BetterRasterize(brush, geometry); if (!rasterize) { rasterize = !FillGeometry(brush.BrushList[0] as BrushProxy, brush.BrushList, 1, geometry); } if (rasterize) { bool empty = false; if (clip != null) { // Fix bug 1506957: Clip geometry prior to rasterizing to prevent excessive // rasterization bitmap size. geometry = Utility.Intersect(geometry, clip, Matrix.Identity, out empty); } if (!empty) { RasterizeGeometry(brush, geometry); } } } } else // Single Avalon brush or pen { Pen p = null; BrushProxy strokeBrush = null; if (pen != null) // Blend pen with White { p = pen.GetPen(true); strokeBrush = pen.StrokeBrush; if (!strokeBrush.IsOpaque()) { strokeBrush = BrushProxy.BlendColorWithBrush(false, Colors.White, strokeBrush, false); } } Brush b = null; if (_costing) { if (brush != null) { // DrawingBrush is always rasterized onward from this stage. // Avoid the cost of creating new DrawingBrush in GetRealBrush during costing if ((brush.Brush != null) && (brush.Brush is DrawingBrush)) { b = brush.Brush; } else { b = brush.GetRealBrush(); } } _cost += DrawGeometryCost(b, p, geometry); } else { if (brush != null) { b = brush.GetRealBrush(); } #if DEBUG _seq++; _dc.Comment("-> DrawGeometry " + _seq + ' ' + _comment); #endif if (p == null) { _dc.DrawGeometry(b, null, null, geometry); } else { _dc.DrawGeometry(b, p, strokeBrush.GetRealBrush(), geometry); } #if DEBUG _dc.Comment("<- DrawGeometry" + _seq + ' ' + _comment); if (Configuration.Verbose >= 2) { Console.WriteLine(" DrawGeometry(" + _comment + ")"); } #endif } } if (!_costing && (clip != null)) { _dc.PopClip(); } }
// Breaking RadialGradientBrush apart to simplify drawing private bool RadialFillGeometry(BrushProxy radial, BrushProxy other, bool pre, ArrayList brushes, int from, Geometry shape) { bool opacityOnly = false; RadialGradientBrush b = null; double opacity = 0; b = radial.Brush as RadialGradientBrush; BrushProxy saveMask = radial.OpacityMask; double saveOpacity = radial.Opacity; if (b != null) { opacity = radial.Opacity; } else { b = saveMask.Brush as RadialGradientBrush; opacity = saveMask.Opacity; opacityOnly = true; Debug.Assert(b != null, "RadialGradientBrush expected"); } radial.OpacityMask = null; // Need to give flattener BrushProxy's opacity, which includes Brush's opacity and // opacity pushed from parent primitives. RadialGradientFlattener rf = new RadialGradientFlattener(b, shape, opacity); int steps = rf.Steps; if (_costing) { if (steps > Configuration.MaxGradientSteps) // Avoid decomposition if there are too many steps { _cost = 1; return(true); } } else { _dc.PushClip(shape); } bool result = true; for (int i = steps; i > 0; i--) { Color color; Geometry slice = rf.GetSlice(i, out color); BrushProxy blend = null; if (opacityOnly) { radial.Opacity = saveOpacity * Utility.NormalizeOpacity(color.ScA); if (pre) { blend = radial.BlendBrush(other); } else { blend = other.BlendBrush(radial); } } else { if (saveMask == null) { blend = BrushProxy.BlendColorWithBrush(false, color, other, !pre); } else { blend = BrushProxy.BlendColorWithBrush(false, color, saveMask, false); if (pre) { blend = blend.BlendBrush(other); } else { blend = other.BlendBrush(blend); } } } result = FillGeometry(blend, brushes, from, slice); if (!result) { break; } // Break when we already know decomposition of gradient is more costly if (_costing && (_cost > 0)) { break; } } radial.OpacityMask = saveMask; radial.Opacity = saveOpacity; if (!_costing) { _dc.PopClip(); } return(result); }