/// <summary> /// /// </summary> /// <param name="gfx"></param> /// <param name="qbezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object gfx, XQBezier qbezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _gfx = gfx as Graphics; Brush brush = ToSolidBrush(qbezier.Style.Fill); Pen pen = ToPen(qbezier.Style, _scaleToPage); double x1 = qbezier.Point1.X; double y1 = qbezier.Point1.Y; double x2 = qbezier.Point1.X + (2.0 * (qbezier.Point2.X - qbezier.Point1.X)) / 3.0; double y2 = qbezier.Point1.Y + (2.0 * (qbezier.Point2.Y - qbezier.Point1.Y)) / 3.0; double x3 = x2 + (qbezier.Point3.X - qbezier.Point1.X) / 3.0; double y3 = y2 + (qbezier.Point3.Y - qbezier.Point1.Y) / 3.0; double x4 = qbezier.Point3.X; double y4 = qbezier.Point3.Y; if (qbezier.IsFilled) { var path = new GraphicsPath(); path.AddBezier( _scaleToPage(x1 + dx), _scaleToPage(y1 + dy), _scaleToPage(x2 + dx), _scaleToPage(y2 + dy), _scaleToPage(x3 + dx), _scaleToPage(y3 + dy), _scaleToPage(x4 + dx), _scaleToPage(y4 + dy)); _gfx.FillPath(brush, path); } if (qbezier.IsStroked) { _gfx.DrawBezier( pen, _scaleToPage(x1 + dx), _scaleToPage(y1 + dy), _scaleToPage(x2 + dx), _scaleToPage(y2 + dy), _scaleToPage(x3 + dx), _scaleToPage(y3 + dy), _scaleToPage(x4 + dx), _scaleToPage(y4 + dy)); } brush.Dispose(); pen.Dispose(); }
/// <summary> /// Binding shape properties to Record data. /// </summary> /// <param name="r">The external data record used for binding.</param> public abstract void Bind(Record r);
/// <summary> /// /// </summary> /// <param name="r"></param> public override void Bind(Record r) { var record = r ?? this.Data.Record; _point1.TryToBind("Point1", this.Data.Bindings, record); _point2.TryToBind("Point2", this.Data.Bindings, record); _point3.TryToBind("Point3", this.Data.Bindings, record); _point4.TryToBind("Point4", this.Data.Bindings, record); }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="renderer"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public override void Draw(object dc, IRenderer renderer, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var record = r ?? this.Data.Record; if (State.Flags.HasFlag(ShapeStateFlags.Visible)) { renderer.Draw(dc, this, dx, dy, db, record); } if (renderer.State.SelectedShape != null) { if (this == renderer.State.SelectedShape) { var points = this.GetAllPoints(); foreach (var point in points) { point.Draw(dc, renderer, dx, dy, db, record); } } else { var points = this.GetAllPoints(); foreach (var point in points) { if (point == renderer.State.SelectedShape) { point.Draw(dc, renderer, dx, dy, db, record); } } } } if (renderer.State.SelectedShapes != null) { if (renderer.State.SelectedShapes.Contains(this)) { var points = this.GetAllPoints(); foreach (var point in points) { point.Draw(dc, renderer, dx, dy, db, record); } } } }
/// <summary> /// /// </summary> /// <param name="r"></param> public override void Bind(Record r) { base.Bind(r ?? this.Data.Record); }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="text"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XText text, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = text.Style; if (style == null) return; var tbind = text.BindToTextProperty(db, r); if (string.IsNullOrEmpty(tbind)) return; double thickness = style.Thickness / _state.Zoom; double half = thickness / 2.0; Tuple<Brush, Pen> cache = null; Brush fill; Pen stroke; if (_enableStyleCache && _styleCache.TryGetValue(style, out cache)) { fill = cache.Item1; stroke = cache.Item2; } else { fill = CreateBrush(style.Fill); stroke = CreatePen(style, thickness); if (_enableStyleCache) _styleCache.Add(style, Tuple.Create(fill, stroke)); } var rect = CreateRect( text.TopLeft, text.BottomRight, dx, dy); Tuple<string, FormattedText, ShapeStyle> tcache = null; FormattedText ft; string ct; if (_enableTextCache && _textCache.TryGetValue(text, out tcache) && string.Compare(tcache.Item1, tbind) == 0 && tcache.Item3 == style) { ct = tcache.Item1; ft = tcache.Item2; _dc.DrawText( ft, GetTextOrigin(style, ref rect, ft)); } else { var ci = CultureInfo.InvariantCulture; var fontStyle = System.Windows.FontStyles.Normal; if (style.TextStyle.FontStyle.Flags.HasFlag(Kaliber3D.Render.FontStyleFlags.Italic)) { fontStyle = System.Windows.FontStyles.Italic; } var fontWeight = FontWeights.Regular; if (style.TextStyle.FontStyle.Flags.HasFlag(Kaliber3D.Render.FontStyleFlags.Bold)) { fontWeight = FontWeights.Bold; } var tf = new Typeface( new FontFamily(style.TextStyle.FontName), fontStyle, fontWeight, FontStretches.Normal); ft = new FormattedText( tbind, ci, ci.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight, tf, style.TextStyle.FontSize > 0.0 ? style.TextStyle.FontSize : double.Epsilon, stroke.Brush, null, TextFormattingMode.Ideal); if (style.TextStyle.FontStyle.Flags.HasFlag(Kaliber3D.Render.FontStyleFlags.Underline) || style.TextStyle.FontStyle.Flags.HasFlag(Kaliber3D.Render.FontStyleFlags.Strikeout)) { var decorations = new TextDecorationCollection(); if (style.TextStyle.FontStyle.Flags.HasFlag(Kaliber3D.Render.FontStyleFlags.Underline)) { decorations = new TextDecorationCollection( decorations.Union(TextDecorations.Underline)); } if (style.TextStyle.FontStyle.Flags.HasFlag(Kaliber3D.Render.FontStyleFlags.Strikeout)) { decorations = new TextDecorationCollection( decorations.Union(TextDecorations.Strikethrough)); } ft.SetTextDecorations(decorations); } if (_enableTextCache) { var tuple = Tuple.Create(tbind, ft, style); if (_textCache.ContainsKey(text)) { _textCache[text] = tuple; } else { _textCache.Add(text, tuple); } } _dc.DrawText( ft, GetTextOrigin(style, ref rect, ft)); } }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="path"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XPath path, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { if (path.Geometry == null) return; var _dc = dc as DrawingContext; var style = path.Style; if (style == null) return; double thickness = style.Thickness / _state.Zoom; double half = thickness / 2.0; Tuple<Brush, Pen> cache = null; Brush fill; Pen stroke; if (_enableStyleCache && _styleCache.TryGetValue(style, out cache)) { fill = cache.Item1; stroke = cache.Item2; } else { fill = CreateBrush(style.Fill); stroke = CreatePen(style, thickness); if (_enableStyleCache) _styleCache.Add(style, Tuple.Create(fill, stroke)); } Tuple<XPathGeometry, StreamGeometry, ShapeStyle> pcache = null; StreamGeometry sg; if (_enablePathCache && _pathCache.TryGetValue(path, out pcache) && pcache.Item1 == path.Geometry && pcache.Item3 == style) { sg = pcache.Item2; _dc.DrawGeometry(path.IsFilled ? fill : null, path.IsStroked ? stroke : null, sg); } else { sg = path.Geometry.ToStreamGeometry(); if (_enablePathCache) { var tuple = Tuple.Create(path.Geometry, sg, style); if (_pathCache.ContainsKey(path)) { _pathCache[path] = tuple; } else { _pathCache.Add(path, tuple); } } _dc.DrawGeometry(path.IsFilled ? fill : null, path.IsStroked ? stroke : null, sg); } }
/// <summary> /// /// </summary> /// <param name="propertyName"></param> /// <param name="bindings"></param> /// <param name="record"></param> public void TryToBind(string propertyName, ImmutableArray<ShapeBinding> bindings, Record record) { string propertyNameX = propertyName + ".X"; string propertyNameY = propertyName + ".Y"; TryToBind(bindings, record, propertyNameX, propertyNameY); }
/// <summary> /// /// </summary> /// <param name="binding"></param> /// <param name="r"></param> /// <param name="value"></param> private static void BindToDouble(ShapeBinding binding, Record r, ref double value) { var columns = r.Columns; for (int i = 0; i < columns.Length; i++) { if (columns[i].Name != binding.Path) continue; double result; bool success = double.TryParse( r.Values[i].Content, NumberStyles.Any, CultureInfo.InvariantCulture, out result); if (success) { value = result; break; } } }
/// <summary> /// /// </summary> /// <param name="record"></param> public void Add(Record record) { if (record == null) return; record.PropertyChanged += RecordObserver; if (record.Values != null) { Add(record.Values); } Verbose("Add Record: " + record.Id); }
/// <summary> /// /// </summary> /// <param name="record"></param> public void Remove(Record record) { if (record == null) return; record.PropertyChanged -= RecordObserver; if (record.Values != null) { Remove(record.Values); } Verbose("Remove Record: " + record.Id); }
/// <summary> /// /// </summary> /// <param name="gfx"></param> /// <param name="path"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object gfx, XPath path, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _gfx = gfx as Graphics; var gp = path.Geometry.ToGraphicsPath(dx, dy, _scaleToPage); if (path.IsFilled && path.IsStroked) { var brush = ToSolidBrush(path.Style.Fill); var pen = ToPen(path.Style, _scaleToPage); _gfx.FillPath( brush, gp); _gfx.DrawPath( pen, gp); brush.Dispose(); pen.Dispose(); } else if (path.IsFilled && !path.IsStroked) { var brush = ToSolidBrush(path.Style.Fill); _gfx.FillPath( brush, gp); brush.Dispose(); } else if (!path.IsFilled && path.IsStroked) { var pen = ToPen(path.Style, _scaleToPage); _gfx.DrawPath( pen, gp); pen.Dispose(); } }
/// <summary> /// /// </summary> /// <param name="gfx"></param> /// <param name="image"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object gfx, XImage image, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _gfx = gfx as Graphics; Brush brush = ToSolidBrush(image.Style.Stroke); var rect = CreateRect( image.TopLeft, image.BottomRight, dx, dy); var srect = new RectangleF( _scaleToPage(rect.X), _scaleToPage(rect.Y), _scaleToPage(rect.Width), _scaleToPage(rect.Height)); if (image.IsFilled) { _gfx.FillRectangle( ToSolidBrush(image.Style.Fill), srect); } if (image.IsStroked) { _gfx.DrawRectangle( ToPen(image.Style, _scaleToPage), srect.X, srect.Y, srect.Width, srect.Height); } if (_enableImageCache && _biCache.ContainsKey(image.Path)) { _gfx.DrawImage(_biCache[image.Path], srect); } else { if (_state.ImageCache == null || string.IsNullOrEmpty(image.Path)) return; var bytes = _state.ImageCache.GetImage(image.Path); if (bytes != null) { var ms = new System.IO.MemoryStream(bytes); var bi = Image.FromStream(ms); ms.Dispose(); if (_enableImageCache) _biCache[image.Path] = bi; _gfx.DrawImage(bi, srect); if (!_enableImageCache) bi.Dispose(); } } brush.Dispose(); }
/// <summary> /// /// </summary> /// <param name="gfx"></param> /// <param name="text"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object gfx, XText text, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _gfx = gfx as Graphics; var tbind = text.BindToTextProperty(db, r); if (string.IsNullOrEmpty(tbind)) return; Brush brush = ToSolidBrush(text.Style.Stroke); var fontStyle = System.Drawing.FontStyle.Regular; if (text.Style.TextStyle.FontStyle.Flags.HasFlag(Kaliber3D.Render.FontStyleFlags.Bold)) { fontStyle |= System.Drawing.FontStyle.Bold; } if (text.Style.TextStyle.FontStyle.Flags.HasFlag(Kaliber3D.Render.FontStyleFlags.Italic)) { fontStyle |= System.Drawing.FontStyle.Italic; } if (text.Style.TextStyle.FontStyle.Flags.HasFlag(Kaliber3D.Render.FontStyleFlags.Underline)) { fontStyle |= System.Drawing.FontStyle.Underline; } if (text.Style.TextStyle.FontStyle.Flags.HasFlag(Kaliber3D.Render.FontStyleFlags.Strikeout)) { fontStyle |= System.Drawing.FontStyle.Strikeout; } Font font = new Font( text.Style.TextStyle.FontName, (float)(text.Style.TextStyle.FontSize * _textScaleFactor), fontStyle); var rect = CreateRect( text.TopLeft, text.BottomRight, dx, dy); var srect = new RectangleF( _scaleToPage(rect.X), _scaleToPage(rect.Y), _scaleToPage(rect.Width), _scaleToPage(rect.Height)); var format = new StringFormat(); switch (text.Style.TextStyle.TextHAlignment) { case TextHAlignment.Left: format.Alignment = StringAlignment.Near; break; case TextHAlignment.Center: format.Alignment = StringAlignment.Center; break; case TextHAlignment.Right: format.Alignment = StringAlignment.Far; break; } switch (text.Style.TextStyle.TextVAlignment) { case TextVAlignment.Top: format.LineAlignment = StringAlignment.Near; break; case TextVAlignment.Center: format.LineAlignment = StringAlignment.Center; break; case TextVAlignment.Bottom: format.LineAlignment = StringAlignment.Far; break; } format.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.NoClip; format.Trimming = StringTrimming.None; _gfx.DrawString( tbind, font, ToSolidBrush(text.Style.Stroke), srect, format); brush.Dispose(); font.Dispose(); }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="arc"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XArc arc, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = arc.Style; if (style == null) return; double thickness = style.Thickness / _state.Zoom; double half = thickness / 2.0; Tuple<Brush, Pen> cache = null; Brush fill; Pen stroke; if (_enableStyleCache && _styleCache.TryGetValue(style, out cache)) { fill = cache.Item1; stroke = cache.Item2; } else { fill = CreateBrush(style.Fill); stroke = CreatePen(style, thickness); if (_enableStyleCache) _styleCache.Add(style, Tuple.Create(fill, stroke)); } var a = WpfArc.FromXArc(arc, dx, dy); PathGeometry pg = null; if (_enableArcCache && _arcCache.TryGetValue(arc, out pg)) { var pf = pg.Figures[0]; pf.StartPoint = new Point(a.Start.X, a.Start.Y); pf.IsFilled = arc.IsFilled; var segment = pf.Segments[0] as ArcSegment; segment.Point = new Point(a.End.X, a.End.Y); segment.Size = new Size(a.Radius.Width, a.Radius.Height); segment.IsLargeArc = a.IsLargeArc; segment.IsStroked = arc.IsStroked; } else { var pf = new PathFigure() { StartPoint = new Point(a.Start.X, a.Start.Y), IsFilled = arc.IsFilled }; var segment = new ArcSegment( new Point(a.End.X, a.End.Y), new Size(a.Radius.Width, a.Radius.Height), 0.0, a.IsLargeArc, SweepDirection.Clockwise, arc.IsStroked); //segment.Freeze(); pf.Segments.Add(segment); //pf.Freeze(); pg = new PathGeometry(); pg.Figures.Add(pf); //pg.Freeze(); if (_enableArcCache) _arcCache.Add(arc, pg); } DrawPathGeometryInternal(_dc, half, fill, stroke, arc.IsStroked, arc.IsFilled, pg); }
/// <summary> /// /// </summary> /// <param name="bindings"></param> /// <param name="r"></param> /// <param name="propertyNameX"></param> /// <param name="propertyNameY"></param> private void TryToBind( ImmutableArray<ShapeBinding> bindings, Record r, string propertyNameX, string propertyNameY) { if (r == null || bindings == null || bindings.Length <= 0) return; if (r.Columns == null || r.Values == null || r.Columns.Length != r.Values.Length) return; foreach (var binding in bindings) { if (string.IsNullOrEmpty(binding.Property) || string.IsNullOrEmpty(binding.Path)) continue; if (binding.Property == propertyNameX) { BindToDouble(binding, r, ref _x); } else if (binding.Property == propertyNameY) { BindToDouble(binding, r, ref _y); } } }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="qbezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XQBezier qbezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = qbezier.Style; if (style == null) return; double thickness = style.Thickness / _state.Zoom; double half = thickness / 2.0; Tuple<Brush, Pen> cache = null; Brush fill; Pen stroke; if (_enableStyleCache && _styleCache.TryGetValue(style, out cache)) { fill = cache.Item1; stroke = cache.Item2; } else { fill = CreateBrush(style.Fill); stroke = CreatePen(style, thickness); if (_enableStyleCache) _styleCache.Add(style, Tuple.Create(fill, stroke)); } PathGeometry pg = null; if (_enableQBezierCache && _qbezierCache.TryGetValue(qbezier, out pg)) { var pf = pg.Figures[0]; pf.StartPoint = new Point(qbezier.Point1.X + dx, qbezier.Point1.Y + dy); pf.IsFilled = qbezier.IsFilled; var qbs = pf.Segments[0] as QuadraticBezierSegment; qbs.Point1 = new Point(qbezier.Point2.X + dx, qbezier.Point2.Y + dy); qbs.Point2 = new Point(qbezier.Point3.X + dx, qbezier.Point3.Y + dy); qbs.IsStroked = qbezier.IsStroked; } else { var pf = new PathFigure() { StartPoint = new Point(qbezier.Point1.X + dx, qbezier.Point1.Y + dy), IsFilled = qbezier.IsFilled }; var qbs = new QuadraticBezierSegment( new Point(qbezier.Point2.X + dx, qbezier.Point2.Y + dy), new Point(qbezier.Point3.X + dx, qbezier.Point3.Y + dy), qbezier.IsStroked); //bs.Freeze(); pf.Segments.Add(qbs); //pf.Freeze(); pg = new PathGeometry(); pg.Figures.Add(pf); //pg.Freeze(); if (_enableQBezierCache) _qbezierCache.Add(qbezier, pg); } DrawPathGeometryInternal(_dc, half, fill, stroke, qbezier.IsStroked, qbezier.IsFilled, pg); }
/// <summary> /// /// </summary> /// <param name="r"></param> public override void Bind(Record r) { var record = r ?? this.Data.Record; var bindings = this.Data.Bindings; string propertyNameX = "X"; string propertyNameY = "Y"; TryToBind(bindings, record, propertyNameX, propertyNameY); }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="image"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XImage image, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { if (image.Path == null) return; var _dc = dc as DrawingContext; var style = image.Style; if (style == null) return; double thickness = style.Thickness / _state.Zoom; double half = thickness / 2.0; Tuple<Brush, Pen> cache = null; Brush fill; Pen stroke; if (_enableStyleCache && _styleCache.TryGetValue(style, out cache)) { fill = cache.Item1; stroke = cache.Item2; } else { fill = CreateBrush(style.Fill); stroke = CreatePen(style, thickness); if (_enableStyleCache) _styleCache.Add(style, Tuple.Create(fill, stroke)); } var rect = CreateRect( image.TopLeft, image.BottomRight, dx, dy); DrawRectangleInternal(_dc, half, fill, stroke, image.IsStroked, image.IsFilled, ref rect); if (_enableImageCache && _biCache.ContainsKey(image.Path)) { try { _dc.DrawImage(_biCache[image.Path], rect); } catch (Exception ex) { Debug.Print(ex.Message); Debug.Print(ex.StackTrace); } } else { if (_state.ImageCache == null || string.IsNullOrEmpty(image.Path)) return; try { var bytes = _state.ImageCache.GetImage(image.Path); if (bytes != null) { var ms = new System.IO.MemoryStream(bytes); var bi = new BitmapImage(); bi.BeginInit(); bi.StreamSource = ms; bi.EndInit(); bi.Freeze(); if (_enableImageCache) _biCache[image.Path] = bi; _dc.DrawImage(bi, rect); } } catch (Exception ex) { Debug.Print(ex.Message); Debug.Print(ex.StackTrace); } } }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="container"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, Container container, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; DrawBackground(_dc, container.Template); DrawBackground(_dc, container); foreach (var layer in container.Layers) { if (layer.IsVisible) { Draw(dc, layer, db, r); } } }
/// <summary> /// /// </summary> /// <param name="r"></param> public override void Bind(Record r) { // TODO: Implement Bind() method. }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="layer"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, Layer layer, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; foreach (var shape in layer.Shapes) { shape.Bind(r); } foreach (var shape in layer.Shapes) { if (shape.State.Flags.HasFlag(_state.DrawShapeState.Flags)) { shape.Draw(_dc, this, 0, 0, db, r); } } }
/// <summary> /// /// </summary> /// <param name="r"></param> public override void Bind(Record r) { var record = r ?? this.Data.Record; _start.TryToBind("Start", this.Data.Bindings, record); _end.TryToBind("End", this.Data.Bindings, record); }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="line"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XLine line, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = line.Style; if (style == null) return; double zoom = _state.Zoom; double thicknessLine = style.Thickness / zoom; double halfLine = thicknessLine / 2.0; double thicknessStartArrow = style.StartArrowStyle.Thickness / zoom; double halfStartArrow = thicknessStartArrow / 2.0; double thicknessEndArrow = style.EndArrowStyle.Thickness / zoom; double halfEndArrow = thicknessEndArrow / 2.0; // line style Tuple<Brush, Pen> lineCache = null; Brush fillLine; Pen strokeLine; if (_enableStyleCache && _styleCache.TryGetValue(style, out lineCache)) { fillLine = lineCache.Item1; strokeLine = lineCache.Item2; } else { fillLine = CreateBrush(style.Fill); strokeLine = CreatePen(style, thicknessLine); if (_enableStyleCache) _styleCache.Add(style, Tuple.Create(fillLine, strokeLine)); } // start arrow style Tuple<Brush, Pen> startArrowCache = null; Brush fillStartArrow; Pen strokeStartArrow; if (_enableArrowStyleCache && _arrowStyleCache.TryGetValue(style.StartArrowStyle, out startArrowCache)) { fillStartArrow = startArrowCache.Item1; strokeStartArrow = startArrowCache.Item2; } else { fillStartArrow = CreateBrush(style.StartArrowStyle.Fill); strokeStartArrow = CreatePen(style.StartArrowStyle, thicknessStartArrow); if (_enableArrowStyleCache) _arrowStyleCache.Add(style.StartArrowStyle, Tuple.Create(fillStartArrow, strokeStartArrow)); } // end arrow style Tuple<Brush, Pen> endArrowCache = null; Brush fillEndArrow; Pen strokeEndArrow; if (_enableArrowStyleCache && _arrowStyleCache.TryGetValue(style.EndArrowStyle, out endArrowCache)) { fillEndArrow = endArrowCache.Item1; strokeEndArrow = endArrowCache.Item2; } else { fillEndArrow = CreateBrush(style.EndArrowStyle.Fill); strokeEndArrow = CreatePen(style.EndArrowStyle, thicknessEndArrow); if (_enableArrowStyleCache) _arrowStyleCache.Add(style.EndArrowStyle, Tuple.Create(fillEndArrow, strokeEndArrow)); } // line max length double x1 = line.Start.X + dx; double y1 = line.Start.Y + dy; double x2 = line.End.X + dx; double y2 = line.End.Y + dy; XLine.SetMaxLength(line, ref x1, ref y1, ref x2, ref y2); // arrow transforms var sas = style.StartArrowStyle; var eas = style.EndArrowStyle; double a1 = Math.Atan2(y1 - y2, x1 - x2) * 180.0 / Math.PI; double a2 = Math.Atan2(y2 - y1, x2 - x1) * 180.0 / Math.PI; bool doRectTransform1 = a1 % 90.0 != 0.0; bool doRectTransform2 = a2 % 90.0 != 0.0; var t1 = new RotateTransform(a1, x1, y1); var t2 = new RotateTransform(a2, x2, y2); Point pt1; Point pt2; // draw start arrow double radiusX1 = sas.RadiusX; double radiusY1 = sas.RadiusY; double sizeX1 = 2.0 * radiusX1; double sizeY1 = 2.0 * radiusY1; switch (sas.ArrowType) { default: case ArrowType.None: { pt1 = new Point(x1, y1); } break; case ArrowType.Rectangle: { pt1 = t1.Transform(new Point(x1 - sizeX1, y1)); var rect = new Rect(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); if (doRectTransform1) { _dc.PushTransform(t1); DrawRectangleInternal(_dc, halfStartArrow, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect); _dc.Pop(); } else { var bounds = t1.TransformBounds(rect); DrawRectangleInternal(_dc, halfStartArrow, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref bounds); } } break; case ArrowType.Ellipse: { pt1 = t1.Transform(new Point(x1 - sizeX1, y1)); _dc.PushTransform(t1); var c = new Point(x1 - radiusX1, y1); DrawEllipseInternal(_dc, halfStartArrow, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref c, radiusX1, radiusY1); _dc.Pop(); } break; case ArrowType.Arrow: { pt1 = t1.Transform(new Point(x1, y1)); var p11 = t1.Transform(new Point(x1 - sizeX1, y1 + sizeY1)); var p21 = t1.Transform(new Point(x1, y1)); var p12 = t1.Transform(new Point(x1 - sizeX1, y1 - sizeY1)); var p22 = t1.Transform(new Point(x1, y1)); DrawLineInternal(_dc, halfStartArrow, strokeStartArrow, sas.IsStroked, ref p11, ref p21); DrawLineInternal(_dc, halfStartArrow, strokeStartArrow, sas.IsStroked, ref p12, ref p22); } break; } // draw end arrow double radiusX2 = eas.RadiusX; double radiusY2 = eas.RadiusY; double sizeX2 = 2.0 * radiusX2; double sizeY2 = 2.0 * radiusY2; switch (eas.ArrowType) { default: case ArrowType.None: { pt2 = new Point(x2, y2); } break; case ArrowType.Rectangle: { pt2 = t2.Transform(new Point(x2 - sizeX2, y2)); var rect = new Rect(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); if (doRectTransform2) { _dc.PushTransform(t2); DrawRectangleInternal(_dc, halfEndArrow, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect); _dc.Pop(); } else { var bounds = t2.TransformBounds(rect); DrawRectangleInternal(_dc, halfEndArrow, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref bounds); } } break; case ArrowType.Ellipse: { pt2 = t2.Transform(new Point(x2 - sizeX2, y2)); _dc.PushTransform(t2); var c = new Point(x2 - radiusX2, y2); DrawEllipseInternal(_dc, halfEndArrow, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref c, radiusX2, radiusY2); _dc.Pop(); } break; case ArrowType.Arrow: { pt2 = t2.Transform(new Point(x2, y2)); var p11 = t2.Transform(new Point(x2 - sizeX2, y2 + sizeY2)); var p21 = t2.Transform(new Point(x2, y2)); var p12 = t2.Transform(new Point(x2 - sizeX2, y2 - sizeY2)); var p22 = t2.Transform(new Point(x2, y2)); DrawLineInternal(_dc, halfEndArrow, strokeEndArrow, eas.IsStroked, ref p11, ref p21); DrawLineInternal(_dc, halfEndArrow, strokeEndArrow, eas.IsStroked, ref p12, ref p22); } break; } // draw line using points from arrow transforms DrawLineInternal(_dc, halfLine, strokeLine, line.IsStroked, ref pt1, ref pt2); }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="renderer"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public override void Draw(object dc, IRenderer renderer, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var record = r ?? this.Data.Record; if (State.Flags.HasFlag(ShapeStateFlags.Visible)) { renderer.Draw(dc, this, dx, dy, db, record); base.Draw(dc, renderer, dx, dy, db, record); } }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="rectangle"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XRectangle rectangle, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = rectangle.Style; if (style == null) return; double thickness = style.Thickness / _state.Zoom; double half = thickness / 2.0; Tuple<Brush, Pen> cache = null; Brush fill; Pen stroke; if (_enableStyleCache && _styleCache.TryGetValue(style, out cache)) { fill = cache.Item1; stroke = cache.Item2; } else { fill = CreateBrush(style.Fill); stroke = CreatePen(style, thickness); if (_enableStyleCache) _styleCache.Add(style, Tuple.Create(fill, stroke)); } var rect = CreateRect( rectangle.TopLeft, rectangle.BottomRight, dx, dy); DrawRectangleInternal( _dc, half, fill, stroke, rectangle.IsStroked, rectangle.IsFilled, ref rect); if (rectangle.IsGrid) { DrawGridInternal( _dc, half, stroke, ref rect, rectangle.OffsetX, rectangle.OffsetY, rectangle.CellWidth, rectangle.CellHeight, true); } }
/// <summary> /// Draw shape using current renderer. /// </summary> /// <param name="dc">The generic drawing context object</param> /// <param name="renderer">The generic renderer object used to draw shape.</param> /// <param name="dx">The X axis draw position offset.</param> /// <param name="dy">The Y axis draw position offset.</param> /// <param name="db">The properties database used for binding.</param> /// <param name="r">The external data record used for binding.</param> public abstract void Draw(object dc, IRenderer renderer, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r);
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="ellipse"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XEllipse ellipse, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = ellipse.Style; if (style == null) return; double thickness = style.Thickness / _state.Zoom; double half = thickness / 2.0; Tuple<Brush, Pen> cache = null; Brush fill; Pen stroke; if (_enableStyleCache && _styleCache.TryGetValue(style, out cache)) { fill = cache.Item1; stroke = cache.Item2; } else { fill = CreateBrush(style.Fill); stroke = CreatePen(style, thickness); if (_enableStyleCache) _styleCache.Add(style, Tuple.Create(fill, stroke)); } var rect = CreateRect( ellipse.TopLeft, ellipse.BottomRight, dx, dy); double rx = rect.Width / 2.0; double ry = rect.Height / 2.0; var center = new Point(rect.X + rx, rect.Y + ry); DrawEllipseInternal( _dc, half, fill, stroke, ellipse.IsStroked, ellipse.IsFilled, ref center, rx, ry); }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="renderer"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public override void Draw(object dc, IRenderer renderer, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var record = r ?? this.Data.Record; if (State.Flags.HasFlag(ShapeStateFlags.Visible)) { renderer.Draw(dc, this, dx, dy, db, record); } if (renderer.State.SelectedShape != null) { if (this == renderer.State.SelectedShape) { _point1.Draw(dc, renderer, dx, dy, db, record); _point2.Draw(dc, renderer, dx, dy, db, record); _point3.Draw(dc, renderer, dx, dy, db, record); _point4.Draw(dc, renderer, dx, dy, db, record); } else if (_point1 == renderer.State.SelectedShape) { _point1.Draw(dc, renderer, dx, dy, db, record); } else if (_point2 == renderer.State.SelectedShape) { _point2.Draw(dc, renderer, dx, dy, db, record); } else if (_point3 == renderer.State.SelectedShape) { _point3.Draw(dc, renderer, dx, dy, db, record); } else if (_point4 == renderer.State.SelectedShape) { _point4.Draw(dc, renderer, dx, dy, db, record); } } if (renderer.State.SelectedShapes != null) { if (renderer.State.SelectedShapes.Contains(this)) { _point1.Draw(dc, renderer, dx, dy, db, record); _point2.Draw(dc, renderer, dx, dy, db, record); _point3.Draw(dc, renderer, dx, dy, db, record); _point4.Draw(dc, renderer, dx, dy, db, record); } } }
/// <summary> /// /// </summary> /// <param name="gfx"></param> /// <param name="bezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object gfx, XBezier bezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _gfx = gfx as Graphics; Brush brush = ToSolidBrush(bezier.Style.Fill); Pen pen = ToPen(bezier.Style, _scaleToPage); if (bezier.IsFilled) { var path = new GraphicsPath(); path.AddBezier( _scaleToPage(bezier.Point1.X), _scaleToPage(bezier.Point1.Y), _scaleToPage(bezier.Point2.X), _scaleToPage(bezier.Point2.Y), _scaleToPage(bezier.Point3.X), _scaleToPage(bezier.Point3.Y), _scaleToPage(bezier.Point4.X), _scaleToPage(bezier.Point4.Y)); _gfx.FillPath(brush, path); } if (bezier.IsStroked) { _gfx.DrawBezier( pen, _scaleToPage(bezier.Point1.X), _scaleToPage(bezier.Point1.Y), _scaleToPage(bezier.Point2.X), _scaleToPage(bezier.Point2.Y), _scaleToPage(bezier.Point3.X), _scaleToPage(bezier.Point3.Y), _scaleToPage(bezier.Point4.X), _scaleToPage(bezier.Point4.Y)); } brush.Dispose(); pen.Dispose(); }