Beispiel #1
0
        public override Size Draw(DrawingContext drawingContext)
        {
            // format margins and padding for raster images
            var margin  = GetMarginValue(DepictionGenerator.DefaultPixelMargin);
            var padding = GetPaddingValue(DefaultPaddingFactor * margin);
            var scale   = model.GetScale();
            var zoom    = model.GetZoomFactor();

            // row and col offsets for alignment
            var yOffset = new double[nRow + 1];
            var xOffset = new double[nCol + 1];

            var required = Dimensions.OfGrid(elements, yOffset, xOffset).Scale(scale * zoom);
            var total    = CalcTotalDimensions(margin, padding, required, null);
            var fitting  = CalcFitting(margin, padding, required, null);

            var visitor = WPFDrawVisitor.ForVectorGraphics(drawingContext);

            if (model.GetBackgroundColor() != Colors.Transparent)
            {
                visitor.Visit(new RectangleElement(new Point(0, 0), total.width, total.height, true, model.GetBackgroundColor()), Transform.Identity);
            }

            // compound the zoom, fitting and scaling into a single value
            var rescale = zoom * fitting * scale;

            // x,y base coordinates include the margin and centering (only if fitting to a size)
            var xBase = margin + (total.width - 2 * margin - (nCol - 1) * padding - (rescale * xOffset[nCol])) / 2;
            var yBase = margin + (total.height - 2 * margin - (nRow - 1) * padding - (rescale * yOffset[nRow])) / 2;

            for (int i = 0; i < elements.Count; i++)
            {
                var row = i / nCol;
                var col = i % nCol;

                // skip empty elements
                var bounds = this.elements[i];
                if (bounds.IsEmpty())
                {
                    continue;
                }

                // calculate the 'view' bounds:
                //  amount of padding depends on which row or column we are in.
                //  the width/height of this col/row can be determined by the next offset
                var x = xBase + col * padding + rescale * xOffset[col];
                var y = yBase + row * padding + rescale * yOffset[row];
                var w = rescale * (xOffset[col + 1] - xOffset[col]);
                var h = rescale * (yOffset[row + 1] - yOffset[row]);

                Draw(visitor, zoom, bounds, new Rect(x, y, w, h));
            }

            return(new Size(total.width, total.height));
        }
Beispiel #2
0
        public override Size Draw(DrawingContext g2)
        {
            // we use the AWT for vector graphics if though we're raster because
            // fractional strokes can be figured out by interpolation, without
            // when we shrink diagrams bonds can look too bold/chubby
            // format margins and padding for raster images
            var scale   = model.GetScale();
            var zoom    = model.GetZoomFactor();
            var margin  = GetMarginValue(DepictionGenerator.DefaultPixelMargin);
            var padding = GetPaddingValue(DefaultPaddingFactor * margin);

            // work out the required space of the main and side components separately
            // will draw these in two passes (main then side) hence want different offsets for each
            var nSideCol = xOffsetSide.Length - 1;
            var nSideRow = yOffsetSide.Length - 1;

            var sideRequired  = sideDim.Scale(scale * zoom);
            var mainRequired  = mainDim.Scale(scale * zoom);
            var condRequired  = condDim.Scale(scale * zoom);
            var titleRequired = new Dimensions(title.Width, title.Height).Scale(scale * zoom);

            var firstRowHeight = scale * zoom * yOffsets[1];
            var total          = CalcTotalDimensions(margin, padding, mainRequired, sideRequired, titleRequired, firstRowHeight, null);
            var fitting        = CalcFitting(margin, padding, mainRequired, sideRequired, titleRequired, firstRowHeight, null);

            var visitor = WPFDrawVisitor.ForVectorGraphics(g2);

            if (model.GetBackgroundColor() != Colors.Transparent)
            {
                visitor.Visit(new RectangleElement(new Point(0, 0), total.width, total.height, true, model.GetBackgroundColor()), Transform.Identity);
            }

            // compound the zoom, fitting and scaling into a single value
            var    rescale        = zoom * fitting * scale;
            double mainCompOffset = 0;

            // shift product x-offset to make room for the arrow / side components
            mainCompOffset = fitting * sideRequired.height + nSideRow * padding - fitting * firstRowHeight / 2;
            for (int i = arrowIdx + 1; i < xOffsets.Length; i++)
            {
                xOffsets[i] += sideRequired.width * 1 / (scale * zoom);
            }

            // MAIN COMPONENTS DRAW
            // x,y base coordinates include the margin and centering (only if fitting to a size)
            var totalRequiredWidth  = 2 * margin + Math.Max(0, nCol - 1) * padding + Math.Max(0, nSideCol - 1) * padding + (rescale * xOffsets[nCol]);
            var totalRequiredHeight = 2 * margin + Math.Max(0, nRow - 1) * padding + (!title.IsEmpty() ? padding : 0) + Math.Max(mainCompOffset, 0) + fitting * mainRequired.height + fitting * Math.Max(0, titleRequired.height);
            var xBase = margin + (total.width - totalRequiredWidth) / 2;
            var yBase = margin + Math.Max(mainCompOffset, 0) + (total.height - totalRequiredHeight) / 2;

            for (int i = 0; i < mainComp.Count; i++)
            {
                var row = i / nCol;
                var col = i % nCol;

                // calculate the 'view' bounds:
                //  amount of padding depends on which row or column we are in.
                //  the width/height of this col/row can be determined by the next offset
                var x = xBase + col * padding + rescale * xOffsets[col];
                var y = yBase + row * padding + rescale * yOffsets[row];
                var w = rescale * (xOffsets[col + 1] - xOffsets[col]);
                var h = rescale * (yOffsets[row + 1] - yOffsets[row]);

                // intercept arrow draw and make it as big as need
                if (i == arrowIdx)
                {
                    w = rescale * (xOffsets[i + 1] - xOffsets[i]) + Math.Max(0, nSideCol - 1) * padding;
                    Draw(visitor,
                         1, // no zoom since arrows is drawn as big as needed
                         CreateArrow(w, arrowHeight * rescale),
                         MakeRect(x, y, w, h));
                    continue;
                }

                // extra padding from the side components
                if (i > arrowIdx)
                {
                    x += Math.Max(0, nSideCol - 1) * padding;
                }

                // skip empty elements
                Bounds bounds = this.mainComp[i];
                if (bounds.IsEmpty())
                {
                    continue;
                }

                Draw(visitor, zoom, bounds, MakeRect(x, y, w, h));
            }

            // RXN TITLE DRAW
            if (!title.IsEmpty())
            {
                var y = yBase + nRow * padding + rescale * yOffsets[nRow];
                var h = rescale * title.Height;
                Draw(visitor, zoom, title, MakeRect(0, y, total.width, h));
            }

            // SIDE COMPONENTS DRAW
            xBase += arrowIdx * padding + rescale * xOffsets[arrowIdx];
            yBase -= mainCompOffset;
            for (int i = 0; i < sideComps.Count; i++)
            {
                var row = i / nSideCol;
                var col = i % nSideCol;

                // calculate the 'view' bounds:
                //  amount of padding depends on which row or column we are in.
                //  the width/height of this col/row can be determined by the next offset
                var x = xBase + col * padding + rescale * xOffsetSide[col];
                var y = yBase + row * padding + rescale * yOffsetSide[row];
                var w = rescale * (xOffsetSide[col + 1] - xOffsetSide[col]);
                var h = rescale * (yOffsetSide[row + 1] - yOffsetSide[row]);

                Draw(visitor, zoom, sideComps[i], MakeRect(x, y, w, h));
            }

            // CONDITIONS DRAW
            if (!conditions.IsEmpty())
            {
                yBase += mainCompOffset;                      // back to top
                yBase += (fitting * mainRequired.height) / 2; // now on center line (arrow)
                yBase += arrowHeight;                         // now just bellow
                Draw(visitor, zoom, conditions, MakeRect(xBase,
                                                         yBase,
                                                         fitting * condRequired.width, fitting * condRequired.height));
            }

            // reset shared xOffsets
            for (int i = arrowIdx + 1; i < xOffsets.Length; i++)
            {
                xOffsets[i] -= sideRequired.width * 1 / (scale * zoom);
            }

            return(new Size(total.width, total.height));
        }