Beispiel #1
0
        /// <summary>
        /// Returns the bounding box of the shape and the label for the given
        /// cell state and its children if recurse is true.
        /// </summary>
        /// <param name="state">Cell state whose bounding box should be returned.</param>
        /// <param name="recurse">Boolean indicating if the children should be included.</param>
        public mxRectangle GetBoundingBox(mxCellState state, Boolean recurse)
        {
            mxRectangle bbox = null;

            if (state != null)
            {
                if (state.BoundingBox != null)
                {
                    bbox = (mxRectangle)state.BoundingBox.Clone();
                }

                if (recurse)
                {
                    mxIGraphModel model      = graph.Model;
                    int           childCount = model.GetChildCount(state.Cell);

                    for (int i = 0; i < childCount; i++)
                    {
                        mxRectangle bounds = GetBoundingBox(
                            GetState(model.GetChildAt(state.Cell, i)), true);

                        if (bounds != null)
                        {
                            if (bbox == null)
                            {
                                bbox = bounds;
                            }
                            else
                            {
                                bbox.Add(bounds);
                            }
                        }
                    }
                }
            }

            return(bbox);
        }
Beispiel #2
0
        /// <summary>
        /// Returns the bounding box of the rotated rectangle.
        /// </summary>
        public static mxRectangle GetBoundingBox(mxRectangle rect, double rotation)
        {
            // TODO: Check use of GraphicsPath (see mxGdiCanvas.DrawText)
            mxRectangle result = null;

            if (rect != null && rotation != 0)
            {
                double rad = ToRadians(rotation);
                double cos = Math.Cos(rad);
                double sin = Math.Sin(rad);

                mxPoint cx = new mxPoint(rect.X + rect.Width / 2,
                    rect.Y + rect.Height / 2);

                mxPoint p1 = new mxPoint(rect.X, rect.Y);
                mxPoint p2 = new mxPoint(rect.X + rect.Width, rect.Y);
                mxPoint p3 = new mxPoint(p2.X, rect.Y + rect.Height);
                mxPoint p4 = new mxPoint(rect.X, p3.Y);

                p1 = GetRotatedPoint(p1, cos, sin, cx);
                p2 = GetRotatedPoint(p2, cos, sin, cx);
                p3 = GetRotatedPoint(p3, cos, sin, cx);
                p4 = GetRotatedPoint(p4, cos, sin, cx);

                result = new mxRectangle((int)p1.X, (int)p1.Y, 0,
                        0);
                result.Add(new mxRectangle(p2.X, p2.Y, 0, 0));
                result.Add(new mxRectangle(p3.X, p3.Y, 0, 0));
                result.Add(new mxRectangle(p4.X, p4.Y, 0, 0));
            }

            return result;
        }
Beispiel #3
0
        /// <summary>
        /// Updates the bounding box in the given cell state.
        /// </summary>
        /// <param name="state">Cell state whose bounding box should be
        /// updated.</param>
        /// <returns></returns>
        public mxRectangle UpdateBoundingBox(mxCellState state)
        {
            // Gets the cell bounds and adds shadows and markers
            mxRectangle rect = new mxRectangle(state.GetRectangle());
            Dictionary <string, Object> style = state.Style;

            // Adds extra pixels for the marker and stroke assuming
            // that the border stroke is centered around the bounds
            // and the first pixel is drawn inside the bounds
            double strokeWidth = Math.Max(1, Math.Round(mxUtils.GetInt(style,
                                                                       mxConstants.STYLE_STROKEWIDTH, 1)
                                                        * scale));

            strokeWidth -= Math.Max(1, strokeWidth / 2);

            if (graph.Model.IsEdge(state.Cell))
            {
                int ms = 0;

                if (style.ContainsKey(mxConstants.STYLE_ENDARROW) ||
                    style.ContainsKey(mxConstants.STYLE_STARTARROW))
                {
                    ms = (int)Math.Round(mxConstants.DEFAULT_MARKERSIZE * scale);
                }

                // Adds the strokewidth
                rect.Grow(ms + strokeWidth);

                // Adds worst case border for an arrow shape
                if (mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "").Equals(
                        mxConstants.SHAPE_ARROW))
                {
                    rect.Grow(mxConstants.ARROW_WIDTH / 2);
                }
            }
            else
            {
                rect.Grow(strokeWidth);
            }

            // Adds extra pixels for the shadow
            if (mxUtils.IsTrue(style, mxConstants.STYLE_SHADOW))
            {
                rect.Width  += mxConstants.SHADOW_OFFSETX;
                rect.Height += mxConstants.SHADOW_OFFSETY;
            }

            // Adds oversize images in labels
            if (mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "").Equals(
                    mxConstants.SHAPE_LABEL))
            {
                if (mxUtils.GetString(style, mxConstants.STYLE_IMAGE) != null)
                {
                    double w = mxUtils.GetInt(style,
                                              mxConstants.STYLE_IMAGE_WIDTH,
                                              mxConstants.DEFAULT_IMAGESIZE) * scale;
                    double h = mxUtils.GetInt(style,
                                              mxConstants.STYLE_IMAGE_HEIGHT,
                                              mxConstants.DEFAULT_IMAGESIZE) * scale;

                    double x = state.X;
                    double y = 0;

                    string imgAlign = mxUtils
                                      .GetString(style, mxConstants.STYLE_IMAGE_ALIGN,
                                                 mxConstants.ALIGN_LEFT);
                    string imgValign = mxUtils.GetString(style,
                                                         mxConstants.STYLE_IMAGE_VERTICAL_ALIGN,
                                                         mxConstants.ALIGN_MIDDLE);

                    if (imgAlign.Equals(mxConstants.ALIGN_RIGHT))
                    {
                        x += state.Width - w;
                    }
                    else if (imgAlign.Equals(mxConstants.ALIGN_CENTER))
                    {
                        x += (state.Width - w) / 2;
                    }

                    if (imgValign.Equals(mxConstants.ALIGN_TOP))
                    {
                        y = state.Y;
                    }
                    else if (imgValign.Equals(mxConstants.ALIGN_BOTTOM))
                    {
                        y = state.Y + state.Height - h;
                    }
                    else
                    {
                        y = state.Y + (state.Height - h) / 2;
                    }

                    rect.Add(new mxRectangle(x, y, w, h));
                }
            }

            // Adds the rotated bounds to the bounding box if the
            // shape is rotated
            double      rotation = mxUtils.GetDouble(style, mxConstants.STYLE_ROTATION);
            mxRectangle bbox     = mxUtils.GetBoundingBox(rect, rotation);

            // Add the rotated bounding box to the non-rotated so
            // that all handles are also covered
            if (bbox != null)
            {
                rect.Add(bbox);
            }

            // Unifies the cell bounds and the label bounds
            if (!mxUtils.GetString(style, mxConstants.STYLE_OVERFLOW, "").Equals("hidden"))
            {
                rect.Add(state.LabelBounds);
            }

            state.BoundingBox = rect;

            return(rect);
        }
Beispiel #4
0
        /// <summary>
        /// Updates the bounding box in the given cell state.
        /// </summary>
        /// <param name="state">Cell state whose bounding box should be
        /// updated.</param>
        /// <returns></returns>
        public mxRectangle UpdateBoundingBox(mxCellState state)
        {
            // Gets the cell bounds and adds shadows and markers
            mxRectangle rect = new mxRectangle(state.GetRectangle());
            Dictionary<string, Object> style = state.Style;

            // Adds extra pixels for the marker and stroke assuming
            // that the border stroke is centered around the bounds
            // and the first pixel is drawn inside the bounds
            double strokeWidth = Math.Max(1, Math.Round(mxUtils.GetInt(style,
                    mxConstants.STYLE_STROKEWIDTH, 1)
                    * scale));
            strokeWidth -= Math.Max(1, strokeWidth / 2);

            if (graph.Model.IsEdge(state.Cell))
            {
                int ms = 0;

                if (style.ContainsKey(mxConstants.STYLE_ENDARROW)
                        || style.ContainsKey(mxConstants.STYLE_STARTARROW))
                {
                    ms = (int) Math.Round(mxConstants.DEFAULT_MARKERSIZE * scale);
                }

                // Adds the strokewidth
                rect.Grow(ms + strokeWidth);

                // Adds worst case border for an arrow shape
                if (mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "").Equals(
                        mxConstants.SHAPE_ARROW))
                {
                    rect.Grow(mxConstants.ARROW_WIDTH / 2);
                }
            }
            else
            {
                rect.Grow(strokeWidth);
            }

            // Adds extra pixels for the shadow
            if (mxUtils.IsTrue(style, mxConstants.STYLE_SHADOW))
            {
                rect.Width += mxConstants.SHADOW_OFFSETX;
                rect.Height += mxConstants.SHADOW_OFFSETY;
            }

            // Adds oversize images in labels
            if (mxUtils.GetString(style, mxConstants.STYLE_SHAPE, "").Equals(
                    mxConstants.SHAPE_LABEL))
            {
                if (mxUtils.GetString(style, mxConstants.STYLE_IMAGE) != null)
                {
                    double w = mxUtils.GetInt(style,
                            mxConstants.STYLE_IMAGE_WIDTH,
                            mxConstants.DEFAULT_IMAGESIZE) * scale;
                    double h = mxUtils.GetInt(style,
                            mxConstants.STYLE_IMAGE_HEIGHT,
                            mxConstants.DEFAULT_IMAGESIZE) * scale;

                    double x = state.X;
                    double y = 0;

                    string imgAlign = mxUtils
                            .GetString(style, mxConstants.STYLE_IMAGE_ALIGN,
                                    mxConstants.ALIGN_LEFT);
                    string imgValign = mxUtils.GetString(style,
                            mxConstants.STYLE_IMAGE_VERTICAL_ALIGN,
                            mxConstants.ALIGN_MIDDLE);

                    if (imgAlign.Equals(mxConstants.ALIGN_RIGHT))
                    {
                        x += state.Width - w;
                    }
                    else if (imgAlign.Equals(mxConstants.ALIGN_CENTER))
                    {
                        x += (state.Width - w) / 2;
                    }

                    if (imgValign.Equals(mxConstants.ALIGN_TOP))
                    {
                        y = state.Y;
                    }
                    else if (imgValign.Equals(mxConstants.ALIGN_BOTTOM))
                    {
                        y = state.Y + state.Height - h;
                    }
                    else
                    {
                        y = state.Y + (state.Height - h) / 2;
                    }

                    rect.Add(new mxRectangle(x, y, w, h));
                }
            }

            // Adds the rotated bounds to the bounding box if the
            // shape is rotated
            double rotation = mxUtils.GetDouble(style, mxConstants.STYLE_ROTATION);
            mxRectangle bbox = mxUtils.GetBoundingBox(rect, rotation);

            // Add the rotated bounding box to the non-rotated so
            // that all handles are also covered
            if (bbox != null)
            {
                rect.Add(bbox);
            }

            // Unifies the cell bounds and the label bounds
            if (!mxUtils.GetString(style, mxConstants.STYLE_OVERFLOW, "").Equals("hidden"))
            {
                rect.Add(state.LabelBounds);
            }

            state.BoundingBox = rect;

            return rect;
        }