public GFXPath GetTextPath(string txt, Transform2d transform) { GFNGlyph glyph; if (txt == null) { return(null); } GFXPath res = new GFXPath(); foreach (char ch in txt) { if (CharLUT.TryGetValue(ch, out glyph)) { GFXPath glyphpath = glyph.Path.TransformCopy(transform); res.AppendPath(glyphpath); transform = Transform2d.Translate(glyph.DX, 0.0) * transform; //move to next character } } return(res); }
private Transform2d GetTextPositionTransform(GFNFont fnt, string txt, double x, double y, double size, double angle, TextAlign align, Transform2d t) { //computes the transformation needed to transform text drawn at origo to get to the wanted position Transform2d res = Transform2d.Translate(x, y); if (angle != 0.0) { res = Transform2d.Rotate(angle) * res; } if (align != TextAlign.BaseLeft) { double dx, dy; GetTextAlignDXDY(fnt, txt, size, align, out dx, out dy); res = Transform2d.Translate(dx, dy) * res; } res = Transform2d.Scale(size / fnt.CapHeight) * res; if (t != null) { return(res * t); } return(res); }
/// <summary> /// Computes the extents of the path, if the path had been transformed with /// the given transform. /// </summary> /// <param name="t"></param> /// <returns></returns> public Box2d GetTransformedExtents(Transform2d t) { Box2d res = new Box2d(); double penx = 0.0, peny = 0.0; double x, y; foreach (GFXPathMoveTo node in PathPoints) { if (node is GFXPathLineTo) { t.Apply(node.X, node.Y, out x, out y, true); res.Append(x, y); t.Apply(penx, peny, out x, out y, true); res.Append(x, y); } else if (node is GFXPathArcTo) { res.Append(GeomUtil.GetTransformedArcExtents(penx, peny, node.X, node.Y, ((GFXPathArcTo)node).Bulge, t)); } else if (node is GFXPathBezierTo) { GFXPathBezierTo bn = (GFXPathBezierTo)node; res.Append(GeomUtil.GetTransformedBezierExtents(penx, peny, bn.XC1, bn.YC1, bn.XC2, bn.YC2, bn.X, bn.Y, t)); } penx = node.X; peny = node.Y; } return(res); }
/// <summary> /// /// </summary> /// <param name="other"></param> /// <param name="tolerance"></param> /// <returns></returns> public bool ApproxEquals(ref Transform2d other, double tolerance = SlurMath.ZeroTolerance) { return (Translation.ApproxEquals(other.Translation, tolerance) && Rotation.ApproxEquals(other.Rotation, tolerance) && Scale.ApproxEquals(other.Scale, tolerance)); }
public static EvalAtNormTime <Transform2d> Transform2(Transform2d startValue, Transform2d endValue, TwoValueEasing mode) { var translateEval = Vector2_2(startValue.translation, endValue.translation, mode); var scaleEval = Vector2_2(startValue.scale, endValue.scale, mode); var rotateEval = Float2(startValue.rotation, endValue.rotation, mode); return(time => new Transform2d(translateEval(time), scaleEval(time), rotateEval(time))); }
public void TransformFlatten(double tol, Transform2d t, FlattenCallback lcb) { double penx = 0.0, peny = 0.0; foreach (GFXPathMoveTo node in PathPoints) { node.TransformFlatten(ref penx, ref peny, tol, t, lcb); } }
public static void FlattenEllipse(double centerx, double centery, double aradius, double bradius, double tilt, double flattentol, bool firstpoint, FlattenCallback lcb) { //draw it as a transformed unit size arcs double cst = Math.Cos(tilt); double sit = Math.Sin(tilt); Transform2d tr = new Transform2d(Math.Cos(tilt) * aradius, Math.Sin(tilt) * aradius, Math.Cos(tilt + MathUtil.Deg90) * bradius, Math.Sin(tilt + MathUtil.Deg90) * bradius, centerx, centery); TransformFlattenArc(1.0, 0.0, -1.0, 0.0, 1.0, firstpoint, flattentol, tr, lcb); TransformFlattenArc(-1.0, 0.0, 1.0, 0.0, 1.0, false, flattentol, tr, lcb); }
public virtual void DrawTextT(string txt, double x, double y, double size, double angle, TextAlign align) { //TODO: make work with multiline text GFNFont fnt = FindFont(Font); Transform2d tr = GetTextPositionTransform(fnt, txt, x, y, size, angle, align, null); var oldt = Transform; Transform = tr * oldt; fnt.DrawString(this, txt, tr); Transform = oldt; }
public virtual GFXPath GetTextPath(string txt, double x, double y, double size, double angle, TextAlign align, Transform2d t) { GFNFont fnt = FindFont(Font); if (fnt == null) { return(null); } Transform2d tr = GetTextPositionTransform(fnt, txt, x, y, size, angle, align, t); return(fnt.GetTextPath(txt, tr)); }
public void DrawString(Painter painter, string txt, Transform2d xform) { /*double scale = txtsize / capheight; * Transform2 tr = Transform2.Scale(scale)*Transform2.Translate(align_dx,align_dy)*Transform2.Rotate(angle)*Transform2.Translate(x, y); * * var oldt = painter.Transform; * painter.Transform = tr * painter.Transform;*/ foreach (char ch in txt) { double dx = DrawGlyphT(ch, painter); painter.Transform = Transform2d.Translate(dx, 0.0) * painter.Transform; } //painter.Transform = oldt; }
public static void EllipticArcToBeziers(double cx, double cy, double aradius, double bradius, double tilt, double startangle, double sweepangle, List <double> xy) { int cnt = xy.Count; double startpar = EllipseAngleToParam(startangle, aradius, bradius); double endpar = EllipseAngleToParam(startangle + sweepangle, aradius, bradius); if (sweepangle >= MathUtil.Deg360) { //full ellipse endpar = startpar + MathUtil.Deg360; } else if (sweepangle <= -MathUtil.Deg360) { endpar = startpar - MathUtil.Deg360; } else if (sweepangle > 0.0) //ccw { if (endpar <= startpar) { endpar += MathUtil.Deg360; } } else //cw { if (endpar >= startpar) { endpar -= MathUtil.Deg360; } } double sweepparam = endpar - startpar; double bulge = GetArcBulgeFromSweepAngle(sweepparam); ArcToBeziers(Math.Cos(startpar), Math.Sin(startpar), Math.Cos(endpar), Math.Sin(endpar), bulge, xy); //transform bezier circular arc to elliptical arc Transform2d tr = Transform2d.Stretch(aradius, bradius) * Transform2d.Rotate(tilt) * Transform2d.Translate(cx, cy); for (int l = cnt; l < xy.Count; l += 2) { double tx, ty; tr.Apply(xy[l], xy[l + 1], out tx, out ty, true); xy[l] = tx; xy[l + 1] = ty; } }
/// <summary> /// Strokes a path using GDI /// </summary> /// <param name="trans"></param> public void InternalStrokePath(GFXPath path, Transform2d trans, bool forceclosed, bool allowmodifypath) { int cx = 0, cy = 0, nx, ny; if (trans == null || trans.IsIdentity) { path.Flatten(flattentol, (x, y, moveto) => { if (moveto) { cx = GFXUtil.FloatToInt(x); cy = GFXUtil.FloatToInt(y); } else { nx = GFXUtil.FloatToInt(x); ny = GFXUtil.FloatToInt(y); DrawLine(nx, ny, cx, cy); //target.Add(nx, ny, cx, cy, currentobject); cx = nx; cy = ny; } }); } else { path.TransformFlatten(flattentol, trans, (x, y, moveto) => { if (moveto) { cx = GFXUtil.FloatToInt(x); cy = GFXUtil.FloatToInt(y); } else { nx = GFXUtil.FloatToInt(x); ny = GFXUtil.FloatToInt(y); //target.Add(nx, ny, cx, cy, currentobject); DrawLine(nx, ny, cx, cy); cx = nx; cy = ny; } }); } }
public GFXPath TransformCopy(Transform2d tr) { GFXPath res = new GFXPath(); double x1, y1, x2, y2, x3, y3, b; bool mirror = tr.Determinant < 0.0; foreach (GFXPathMoveTo mt in PathPoints) { if (mt is GFXPathBezierTo) { var bez = mt as GFXPathBezierTo; tr.Apply(bez.XC1, bez.YC1, out x1, out y1, true); tr.Apply(bez.XC2, bez.YC2, out x2, out y2, true); tr.Apply(bez.X, bez.Y, out x3, out y3, true); res.PathPoints.Add(new GFXPathBezierTo(x1, y1, x2, y2, x3, y3)); } else if (mt is GFXPathArcTo) { var arc = mt as GFXPathArcTo; tr.Apply(arc.X, arc.Y, out x1, out y1, true); b = mirror ? -arc.Bulge : arc.Bulge; res.PathPoints.Add(new GFXPathArcTo(x1, y1, b)); } else if (mt is GFXPathLineTo) { var lin = mt as GFXPathLineTo; tr.Apply(lin.X, lin.Y, out x1, out y1, true); res.PathPoints.Add(new GFXPathLineTo(x1, y1)); } else if (mt is GFXPathCloseSubPath) { var clp = mt as GFXPathCloseSubPath; tr.Apply(clp.X, clp.Y, out x1, out y1, true); res.PathPoints.Add(new GFXPathCloseSubPath(x1, y1)); } else //move to { tr.Apply(mt.X, mt.Y, out x1, out y1, true); res.PathPoints.Add(new GFXPathMoveTo(x1, y1)); } } return(res); }
public GraphicAttributes(Painter p) { Color = p.Color; Opacity = p.Opacity; AntiGrain = p.AntiGrain; Hatch = p.Hatch; FillStyle = p.FillStyle; LineWidth = p.LineWidth; LineStyle = p.LineStyle; LineStyleDashes = p.LineStyleDashes; EndCaps = p.EndCaps; LineJoin = p.LineJoin; Pattern = p.Pattern; Transform = p.Transform; Clip = p.Clip; PatternTransform = p.PatternTransform; FillMode = p.FillMode; Font = p.Font; }
/// <summary> /// Default constructor sets all attributes to their default value. /// Use DefaultAttributes to access an instance of this. /// </summary> private GraphicAttributes() { Color = RGB.Black; Opacity = 1.0; AntiGrain = false; Hatch = Hatch.Cross; FillStyle = FillStyle.Solid; LineWidth = 0.0; LineStyle = LineStyle.Continuous; LineStyleDashes = Painter.DefaultLineStyleDashes; EndCaps = EndCap.Flat; LineJoin = LineJoin.Bevel; Pattern = null; Transform = Transform2d.Identity; Clip = null; PatternTransform = Transform2d.Identity; FillMode = FillMode.EvenOdd; Font = null; }
public static void FlattenEllipticArc(double centerx, double centery, double aradius, double bradius, double tilt, double startangle, double sweepangle, double flattentol, bool firstpoint, FlattenCallback lcb) { //check if full ellipse if (Math.Abs(sweepangle) >= MathUtil.Deg360 - MathUtil.Epsilon) { FlattenEllipse(centerx, centery, aradius, bradius, tilt, flattentol, firstpoint, lcb); return; } double startparam = EllipseAngleToParam(startangle, aradius, bradius); double endparam = EllipseAngleToParam(startangle + sweepangle, aradius, bradius); double sweepparam; if (sweepangle > 0.0) //ccw { while (endparam < startparam) { endparam += MathUtil.Deg360; } sweepparam = endparam - startparam; } else { //cw while (endparam > startparam) { endparam -= MathUtil.Deg360; } sweepparam = endparam - startparam; } //draw it as a transformed unit size arc double cst = Math.Cos(tilt); double sit = Math.Sin(tilt); Transform2d tr = new Transform2d(Math.Cos(tilt) * aradius, Math.Sin(tilt) * aradius, Math.Cos(tilt + MathUtil.Deg90) * bradius, Math.Sin(tilt + MathUtil.Deg90) * bradius, centerx, centery); double x1 = Math.Cos(startparam); double y1 = Math.Sin(startparam); double x2 = Math.Cos(endparam); double y2 = Math.Sin(endparam); double bulge = GetArcBulgeFromSweepAngle(sweepparam); //should work with negative sweeps as well TransformFlattenArc(x1, y1, x2, y2, bulge, firstpoint, flattentol, tr, lcb); }
void OnDrawAreaWheel(object sender, WheelEventArgs e) { Drawing drw = CurrentDrawing; if (drw != null) { double scale; if (e.Delta < 0) { scale = 0.8; } else { scale = 1.0 / 0.8; } drw.ViewTransform = drw.ViewTransform * Transform2d.Translate(-cursorpixel.X, -cursorpixel.Y) * Transform2d.Scale(scale) * Transform2d.Translate(cursorpixel.X, cursorpixel.Y); drawarea.Redraw(); } }
/// <summary> /// Checks if this path, after a given transformation will have a bounding box smaller than a given size. THis can be done quickly since the /// check can be terminated as soon as it finds a segment large enough. /// </summary> public bool IsTransformedSmallerThan(Transform2d tr, double maxwidth, double maxheight) { double penx = 0.0, peny = 0.0; Box2d ext = new Box2d(); foreach (GFXPathMoveTo mt in PathPoints) { if (mt is GFXPathBezierTo) { var bez = mt as GFXPathBezierTo; Box2d bext = GeomUtil.GetTransformedBezierExtents(penx, peny, bez.XC1, bez.YC1, bez.XC2, bez.YC2, bez.X, bez.Y, tr); ext.Append(bext); } else if (mt is GFXPathArcTo) { var arc = mt as GFXPathArcTo; Box2d aext = GeomUtil.GetTransformedArcExtents(penx, peny, arc.X, arc.Y, arc.Bulge, tr); ext.Append(aext); } else if (mt is GFXPathLineTo) { double x1, y1, x2, y2; tr.Apply(penx, peny, out x1, out y1, true); tr.Apply(mt.X, mt.Y, out x2, out y2, true); ext.Append(x1, y1, x2, y2); } // closepath and moveto needs no special handling... if (!ext.Empty && (ext.Width > maxwidth || ext.Height > maxheight)) { return(false); } penx = mt.X; peny = mt.Y; } return(true); }
void OnDrawAreaMotion(object sender, MotionEventArgs e) { Drawing drw = CurrentDrawing; if (drw != null) { var size = drawarea.PhysicalSize; drawarea.Focused = true; //need focus for accepting wheel events var newcursorpixel = new Point2i(e.X, size.Height - e.Y - 1); double dx = newcursorpixel.X - cursorpixel.X; double dy = newcursorpixel.Y - cursorpixel.Y; cursorpixel = newcursorpixel; if (e.Status.HasFlag(KeyStatus.MiddleButton)) { drw.ViewTransform = drw.ViewTransform * Transform2d.Translate(dx, dy); drawarea.Redraw(); return; } RedrawOverlay(); } else { trackingpos = null; } // w.Caption = viewtransform.ToString(); // pt.ToString() + " " + e.Status.ToString(); //Caption = e.X.ToString(); SetCoordText(); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="transform"></param> /// <param name="other"></param> /// <returns></returns> public static IField2d <T> CreateTransformed <T>(IField2d <T> other, Transform2d transform) { transform.Invert(); return(Create(p => other.ValueAt(transform.Apply(p)))); }
/// <summary> /// Creates a relative transformation from t0 to t1. /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <returns></returns> public static Transform2d CreateFromTo(Transform2d from, Transform2d to) { return(to.Apply(from.Inverse)); }
public PortalableMovement(IPortalCommon instance, Line startEnd, Transform2d previous) { Instance = instance; StartEnd = startEnd; Previous = previous; }
/// <summary> /// Applies the inverse of this transformation to the given transformation. /// </summary> /// <param name="other"></param> public void ApplyInverse(ref Transform2d other, ref Transform2d result) { result.Rotation = Rotation.ApplyInverse(other.Rotation); result.Translation = ApplyInverse(other.Translation); result.Scale = other.Scale / Scale; }
/// <summary> /// Applies the inverse of this transformation to the given transformation in place. /// </summary> /// <param name="other"></param> public void ApplyInverse(ref Transform2d other) { ApplyInverse(ref other, ref other); }
/// <summary> /// Applies the inverse of this transformation to the given transformation. /// </summary> /// <param name="other"></param> public Transform2d ApplyInverse(Transform2d other) { ApplyInverse(ref other, ref other); return(other); }
/// <summary> /// Applies this transformation to the given transformation in place. /// </summary> /// <param name="other"></param> public void Apply(ref Transform2d other) { Apply(ref other, ref other); }
/// <summary> /// Applies this transformation to the given transformation. /// </summary> /// <param name="other"></param> public Transform2d Apply(Transform2d other) { Apply(ref other, ref other); return(other); }
public override GFXPath GetTextPath(string txt, double x, double y, double size, double angle, TextAlign align, Transform2d t) { return(null); //not in this painter }
public override GFXPath GetTextPath(string txt, double x, double y, double size, double angle, TextAlign align, Transform2d t) { return(MainPainter.GetTextPath(txt, x, y, size, angle, align, t)); }
internal override void TransformFlatten(ref double penx, ref double peny, double tol, Transform2d t, FlattenCallback lcb) { penx = X; peny = Y; double tx, ty; t.Apply(penx, peny, out tx, out ty, true); lcb(tx, ty, false); }
internal override void TransformFlatten(ref double penx, ref double peny, double tol, Transform2d t, FlattenCallback lcb) { GeomUtil.TransformFlattenArc(penx, peny, X, Y, Bulge, false, tol, t, lcb); penx = X; peny = Y; }