/// <summary>コンストラクタ。</summary>
		public VirtualGraphics()
			{
			Layers = new VirtualLayerCollection( this );
			Background = Color.Black;
			AxesLine = null;
			Mirroring = new SizeD( 1, 1 );
			}
        /// <summary>
        /// Render the IDrawable List to the master frame.
        /// </summary>
        /// <param name="frameSize"></param>
        /// <param name="zoom"></param>
        public void Render(SizeD frameSize, double zoom = 1.0) {
            if (zoom <= 0)
                throw new ArgumentException("zoom factor must not be negative!");

                Image _oldframe = _frame;
                _frame = new Bitmap(
                    (int)Math.Max(1, frameSize.Width * zoom),
                    (int)Math.Max(1, frameSize.Height * zoom));

                using (var G = Graphics.FromImage(_frame)) {
                    G.SmoothingMode = SmoothingMode.AntiAlias;
                    G.ScaleTransform((float)zoom, (float)zoom);

                    if (OnPostRender != null)
                        OnPostRender(this, new RenderEventArgs(G));

                    if (BackGroundColor.HasValue)
                        G.Clear(BackGroundColor.Value);

                    lock (_groupsSYNC) {
                        foreach (var group in _groups) {
                            group.Draw(G);
                        }
                    }

                    if (OnPastRender != null)
                        OnPastRender(this, new RenderEventArgs(G));


                if (_oldframe != null)
                    _oldframe.Dispose();
            }

        }
		private void UpdateSize(SizeD newSize)
		{
			Size = newSize;
			BarkerEntityShape parent = (BarkerEntityShape)ParentShape;
			parent.Size = new SizeD(newSize.Width, parent.Size.Height + newSize.Height);
		}
 private Size DiagramToImage(SizeD worldSize)
 {
     Debug.Assert(Enabled);
     if (Enabled)
     {
         Debug.Assert(Enabled);
         var ds = DiagramClientView.WorldToDevice(worldSize);
         return new Size((int)(ds.Width * _imageScale), (int)(ds.Height * _imageScale));
     }
     else
     {
         return Size.Empty;
     }
 }
		/// <summary>
		/// Pulled directly from Reflector disassembly
		/// </summary>
		private static AnchorPoint TestHitAnchor(BinaryLinkShape linkShape, LineSegment segment, SizeD tolerance, PointD hitPoint)
		{
			RectangleD ed1 = new RectangleD(0, 0, tolerance.Width * 2, tolerance.Height * 2);
			NodeShape shape1 = null;
			bool flag1 = false;
			if (linkShape != null)
			{
				PointD td1;
				if (segment.IsStartSegment && segment.IsEndSegment)
				{
					if (ClosestEnd(segment, hitPoint))
					{
						td1 = segment.StartPoint;
						shape1 = linkShape.FromShape;
						flag1 = true;
					}
					else
					{
						td1 = segment.EndPoint;
						shape1 = linkShape.ToShape;
					}
				}
				else if (segment.IsStartSegment)
				{
					td1 = segment.StartPoint;
					shape1 = linkShape.FromShape;
					flag1 = true;
				}
				else if (segment.IsEndSegment)
				{
					td1 = segment.EndPoint;
					shape1 = linkShape.ToShape;
				}
				else
				{
					return null;
				}
				if ((shape1 != null) && !shape1.IsPort)
				{
					ed1.Offset(td1.X - tolerance.Width, td1.Y - tolerance.Height);
					if (ed1.Contains(hitPoint))
					{
						return new AnchorPoint(linkShape, segment, shape1, tolerance, flag1);
					}
				}
			}
			return null;
		}
		/// <summary>
		/// Replacement for LinkShapeGeometry.DrawDecorator
		/// </summary>
#if VISUALSTUDIO_10_0
		protected static new void DrawDecorator(DiagramPaintEventArgs e, IGeometryHost geometryHost, float rotation, PointD centerRight, LinkDecorator decorator, SizeD size)
		{
		private static void ExcludeDecorator(Graphics g, ObliqueBinaryLinkShapeGeometry geometry, LinkDecorator decorator, PointD fromPoint, PointD toPoint, SizeD size)
		{
		/// <summary>全体像の表示をするよう、ビュー座標を変更します。</summary>
		/// <param name="g"></param>
		/// <param name="padding"></param>
		public void MoveViewToPerspective(Graphics g, SizeD padding)
			{
			RectangleD world = GetGraphicsRegion(), view = g.VisibleClipBounds;

			double scaleW = world.Size.W != 0 ? ( view.Size.W - 2 * padding.W ) / world.Size.W : 1;
			double scaleH = world.Size.H != 0 ? ( view.Size.H - 2 * padding.H ) / world.Size.H : 1;
			double scale;
			if( scaleW < scaleH )
				{
				scale = scaleW;
				this.ViewOffset = new PointD( padding.W, ( view.Size.H - scale * world.Size.H ) / 2 );
				}
			else
				{
				scale = scaleH;
				this.ViewOffset = new PointD( ( view.Size.W - scale * world.Size.W ) / 2, padding.H );
				}

			if( Mirroring.W == -1 )
				this.ViewOffset = new PointD( view.RightBottom.X - this.ViewOffset.X, this.ViewOffset.Y );
			if( Mirroring.H == -1 )
				this.ViewOffset = new PointD( this.ViewOffset.X, view.RightBottom.Y - this.ViewOffset.Y );

			this.ViewScale = new SizeD( scale, scale );
			this.GlobalOffset = world.Location;
			}
		public StructureViewer(FormBase parent)
			: base( parent )
			{
			InitializeComponent();
			PerspectivePadding = new SizeD( 12, 12 );
			}
		private void UpdateSize(SizeD newSize)
		{
			Size = newSize;
			TableShape parent = (TableShape)ParentShape;
			parent.Size = new SizeD(newSize.Width, parent.Size.Height + newSize.Height);
		}
 /// <summary>
 /// Measure text size. If text contains complex script, we will be using TextRenderer.MeasureText API to calc the size.
 /// </summary>
 internal static SizeD Measure(Graphics graphics, string text, Font font, SizeD maximumSize, StringFormat format)
 {
     if (ScriptIsComplex(text))
     {
         Size proposedSize = new Size((int)((maximumSize.Width * graphics.DpiX) * graphics.PageScale), (int)((maximumSize.Height * graphics.DpiY) * graphics.PageScale));
         using (Font font2 = new Font(font.Name, font.Size * graphics.PageScale, font.Style, GraphicsUnit.Inch, font.GdiCharSet, font.GdiVerticalFont))
         {
             TextFormatFlags textFormatFlagsFromStringFormat = GetTextFormatFlagsFromStringFormat(format);
             TextRenderingHint textRenderingHint = graphics.TextRenderingHint;
             graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
             Size size2 = TextRenderer.MeasureText(graphics, text, font2, proposedSize, textFormatFlagsFromStringFormat);
             graphics.TextRenderingHint = textRenderingHint;
             size2.Width += 5;
             size2.Height += size2.Height / font2.Height;
             size2.Width = Math.Min(size2.Width, proposedSize.Width);
             size2.Height = Math.Min(size2.Height, proposedSize.Height);
             return new SizeD((double)(((float)size2.Width) / graphics.DpiX), (double)(((float)size2.Height) / graphics.DpiY));
         }
     }
     SizeF ef = graphics.MeasureString(text, font, SizeD.ToSizeF(maximumSize), format);
     return new SizeD((double)ef.Width, (double)ef.Height);
 }