/// <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> /// 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); }