public void Render(List <PrimitiveInfo> commands, IProxyDrawingContext dc)
        {
            Toolbox.EmitEvent(EventTrace.Event.WClientDRXRasterStart);

            int width  = (int)Math.Round(m_bounds.Width * Configuration.RasterizationDPI / 96);
            int height = (int)Math.Round(m_bounds.Height * Configuration.RasterizationDPI / 96);

            if ((width >= 1) && (height >= 1)) // Skip shape which is too small
            {
                Matrix mat = Utility.CreateMappingTransform(m_bounds, width, height);

                RenderTargetBitmap brushImage = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);

                DrawingVisual visual = new DrawingVisual();

                // clip image to the primitives it contains
                Geometry clip = null;

                using (DrawingContext ctx = visual.RenderOpen())
                {
                    ctx.PushTransform(new MatrixTransform(mat));

                    m_primitives.Sort();

                    foreach (int i in m_primitives)
                    {
                        Primitive primitive = commands[i].primitive;

                        // Fix bug 1396393: Can't use AddToCluster without fixing that bug.
                        // We need to clip cluster to primitives in case primitives have clipping.
                        Debug.Assert(GetPrimitiveIntersectAction() == PrimitiveIntersectAction.ClipToCluster);

                        bool     empty;
                        Geometry geometry = Utility.Intersect(primitive.GetShapeGeometry(), primitive.Clip, Matrix.Identity, out empty);

                        if (!empty)
                        {
                            primitive.OnRender(ctx);

                            // clip cluster to this clipped primitive. we must have geometry information,
                            // otherwise the primitive will be clipped away.
                            Debug.Assert(geometry != null, "No geometry available for primitive");

                            if (clip == null)
                            {
                                clip = geometry;
                            }
                            else
                            {
                                CombinedGeometry cg = new CombinedGeometry();

                                // Opt-out of inheritance through the new Freezable.
                                cg.CanBeInheritanceContext = false;
                                cg.GeometryCombineMode     = GeometryCombineMode.Union;
                                cg.Geometry1 = clip;
                                cg.Geometry2 = geometry;

                                clip = cg;
                            }
                        }

                        commands[i] = null; // Command can be deleted after cluster is rendered
                    }

                    ctx.Pop();
                }

                brushImage.Render(visual);

                Toolbox.EmitEvent(EventTrace.Event.WClientDRXRasterEnd);

                dc.DrawImage(new ImageProxy(brushImage), m_bounds, clip, Matrix.Identity);
            }
        }
Exemple #2
0
        /// <summary>
        /// Resolve object overlapping in a primitive tree.
        /// Send broken down drawing primitives to _dc.
        /// </summary>
        /// <param name="dc"></param>
        /// <param name="disjoint">True if all output primitives need to be disjoint</param>
        public void AlphaFlatten(IProxyDrawingContext dc, bool disjoint)
        {
            List <PrimitiveInfo> commands = _dl.Commands;

            if (commands == null)
            {
                return;
            }

            int count = commands.Count;

            _dc = dc;

            bool needFlattening = true;

            if (Configuration.BlendAlphaWithWhite || Configuration.ForceAlphaOpaque)
            {
                needFlattening = false;
            }
            else if (!disjoint)
            {
                needFlattening = false;

                for (int i = 0; i < count; i++)
                {
                    PrimitiveInfo info = commands[i];

                    if (!info.primitive.IsOpaque)
                    {
                        needFlattening = true;
                        break;
                    }
                }
            }

            if (needFlattening)
            {
#if DEBUG
                Console.WriteLine();
                Console.WriteLine("Stage 2: Calculating intersections using bounding boxes");
                Console.WriteLine();
#endif
                // Still need all the primitive, for removal by opaque covering and white primitive removal
                _dl.CalculateIntersections(count);
            }

#if DEBUG
            if (Configuration.Verbose >= 2)
            {
                Console.WriteLine();
                Console.WriteLine("Original display list");
                Console.WriteLine();

                DisplayList.PrintPrimitive(null, -1, true);

                for (int i = 0; i < count; i++)
                {
                    DisplayList.PrintPrimitive(commands[i], i, true);
                }

                Console.WriteLine();

                Console.WriteLine("Primitives in display list: {0}", count);

                Console.WriteLine();
            }
#endif

            if (needFlattening)
            {
                DisplayListOptimization(commands, count, disjoint);
            }

#if DEBUG
            for (int i = 0; i < count; i++)
            {
                if (commands[i] != null)
                {
                    commands[i].SetID(i);
                }
            }

            Console.WriteLine();
            Console.WriteLine("Stage 4: Alpha flattening");
            Console.WriteLine();
#endif
            for (int i = 0; i < count; i++)
            {
                PrimitiveInfo info = commands[i];

                if (info == null)
                {
                    continue;
                }

                String desp = null;
#if DEBUG
                if (Configuration.Verbose >= 2)
                {
                    Console.Write(i);
                    Console.Write(": ");
                }

                desp = info.id;
#endif

                if (info.m_cluster != null)
                {
                    info.m_cluster.Render(commands, dc);
                }
                else
                {
                    AlphaRender(info.primitive, info.overlap, info.overlapHasTransparency, disjoint, desp);
                }

#if DEBUG
                if (Configuration.Verbose >= 2)
                {
                    Console.WriteLine("");
                }
#endif
            }

            _dc = null;
        }