CMS 3D CMS Logo

List of all members | Public Member Functions | Public Attributes | Static Public Attributes
svgfig.Path Class Reference

Public Member Functions

def __init__ (self, d=[], attr)
 
def __repr__ (self)
 
def parse (self, pathdata)
 
def parse_boolean (self, index, pathdata)
 
def parse_command (self, index, pathdata)
 
def parse_number (self, index, pathdata)
 
def parse_whitespace (self, index, pathdata)
 
def SVG (self, trans=None)
 

Public Attributes

 attr
 
 d
 

Static Public Attributes

dictionary defaults = {}
 

Detailed Description

Path represents an SVG path, an arbitrary set of curves and
straight segments. Unlike SVG("path", d="..."), Path stores
coordinates as a list of numbers, rather than a string, so that it is
transformable in a Fig.

Path(d, attribute=value)

d                       required        path data
attribute=value pairs   keyword list    SVG attributes

See http://www.w3.org/TR/SVG/paths.html for specification of paths
from text.

Internally, Path data is a list of tuples with these definitions:

    * ("Z/z",): close the current path
    * ("H/h", x) or ("V/v", y): a horizontal or vertical line
      segment to x or y
    * ("M/m/L/l/T/t", x, y, global): moveto, lineto, or smooth
      quadratic curveto point (x, y). If global=True, (x, y) should
      not be transformed.
    * ("S/sQ/q", cx, cy, cglobal, x, y, global): polybezier or
      smooth quadratic curveto point (x, y) using (cx, cy) as a
      control point. If cglobal or global=True, (cx, cy) or (x, y)
      should not be transformed.
    * ("C/c", c1x, c1y, c1global, c2x, c2y, c2global, x, y, global):
      cubic curveto point (x, y) using (c1x, c1y) and (c2x, c2y) as
      control points. If c1global, c2global, or global=True, (c1x, c1y),
      (c2x, c2y), or (x, y) should not be transformed.
    * ("A/a", rx, ry, rglobal, x-axis-rotation, angle, large-arc-flag,
      sweep-flag, x, y, global): arcto point (x, y) using the
      aforementioned parameters.
    * (",/.", rx, ry, rglobal, angle, x, y, global): an ellipse at
      point (x, y) with radii (rx, ry). If angle is 0, the whole
      ellipse is drawn; otherwise, a partial ellipse is drawn.

Definition at line 1021 of file svgfig.py.

Constructor & Destructor Documentation

def svgfig.Path.__init__ (   self,
  d = [],
  attr 
)

Definition at line 1063 of file svgfig.py.

1063  def __init__(self, d=[], **attr):
1064  if isinstance(d, str): self.d = self.parse(d)
1065  else: self.d = list(d)
1066 
1067  self.attr = dict(self.defaults)
1068  self.attr.update(attr)
1069 
dictionary defaults
Definition: svgfig.py:1058
def parse(self, pathdata)
Definition: svgfig.py:1118
def __init__(self, d=[], attr)
Definition: svgfig.py:1063
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run

Member Function Documentation

def svgfig.Path.__repr__ (   self)

Definition at line 1060 of file svgfig.py.

References svgfig.SVG.attr, svgfig.Path.attr, svgfig.Fig.d, svgfig.Plot.d, svgfig.Frame.d, and svgfig.Path.d.

Referenced by data_sources.json_file.__str__().

1060  def __repr__(self):
1061  return "<Path (%d nodes) %s>" % (len(self.d), self.attr)
1062 
def __repr__(self)
Definition: svgfig.py:1060
def svgfig.Path.parse (   self,
  pathdata 
)
Parses text-commands, converting them into a list of tuples.
Called by the constructor.

Definition at line 1118 of file svgfig.py.

References svgfig.Path.parse_boolean(), svgfig.Path.parse_command(), svgfig.Path.parse_number(), and svgfig.Path.parse_whitespace().

1118  def parse(self, pathdata):
1119  """Parses text-commands, converting them into a list of tuples.
1120  Called by the constructor."""
1121  output = []
1122  index = 0
1123  while True:
1124  command, index, pathdata = self.parse_command(index, pathdata)
1125  index, pathdata = self.parse_whitespace(index, pathdata)
1126 
1127  if command == None and index == len(pathdata): break # this is the normal way out of the loop
1128  if command in ("Z", "z"):
1129  output.append((command,))
1130 
1131  ######################
1132  elif command in ("H", "h", "V", "v"):
1133  errstring = "Path command \"%s\" requires a number at index %d" % (command, index)
1134  num1, index, pathdata = self.parse_number(index, pathdata)
1135  if num1 == None: raise ValueError(errstring)
1136 
1137  while num1 != None:
1138  output.append((command, num1))
1139  num1, index, pathdata = self.parse_number(index, pathdata)
1140 
1141  ######################
1142  elif command in ("M", "m", "L", "l", "T", "t"):
1143  errstring = "Path command \"%s\" requires an x,y pair at index %d" % (command, index)
1144  num1, index, pathdata = self.parse_number(index, pathdata)
1145  num2, index, pathdata = self.parse_number(index, pathdata)
1146 
1147  if num1 == None: raise ValueError(errstring)
1148 
1149  while num1 != None:
1150  if num2 == None: raise ValueError(errstring)
1151  output.append((command, num1, num2, False))
1152 
1153  num1, index, pathdata = self.parse_number(index, pathdata)
1154  num2, index, pathdata = self.parse_number(index, pathdata)
1155 
1156  ######################
1157  elif command in ("S", "s", "Q", "q"):
1158  errstring = "Path command \"%s\" requires a cx,cy,x,y quadruplet at index %d" % (command, index)
1159  num1, index, pathdata = self.parse_number(index, pathdata)
1160  num2, index, pathdata = self.parse_number(index, pathdata)
1161  num3, index, pathdata = self.parse_number(index, pathdata)
1162  num4, index, pathdata = self.parse_number(index, pathdata)
1163 
1164  if num1 == None: raise ValueError(errstring)
1165 
1166  while num1 != None:
1167  if num2 == None or num3 == None or num4 == None: raise ValueError(errstring)
1168  output.append((command, num1, num2, False, num3, num4, False))
1169 
1170  num1, index, pathdata = self.parse_number(index, pathdata)
1171  num2, index, pathdata = self.parse_number(index, pathdata)
1172  num3, index, pathdata = self.parse_number(index, pathdata)
1173  num4, index, pathdata = self.parse_number(index, pathdata)
1174 
1175  ######################
1176  elif command in ("C", "c"):
1177  errstring = "Path command \"%s\" requires a c1x,c1y,c2x,c2y,x,y sextuplet at index %d" % (command, index)
1178  num1, index, pathdata = self.parse_number(index, pathdata)
1179  num2, index, pathdata = self.parse_number(index, pathdata)
1180  num3, index, pathdata = self.parse_number(index, pathdata)
1181  num4, index, pathdata = self.parse_number(index, pathdata)
1182  num5, index, pathdata = self.parse_number(index, pathdata)
1183  num6, index, pathdata = self.parse_number(index, pathdata)
1184 
1185  if num1 == None: raise ValueError(errstring)
1186 
1187  while num1 != None:
1188  if num2 == None or num3 == None or num4 == None or num5 == None or num6 == None: raise ValueError(errstring)
1189 
1190  output.append((command, num1, num2, False, num3, num4, False, num5, num6, False))
1191 
1192  num1, index, pathdata = self.parse_number(index, pathdata)
1193  num2, index, pathdata = self.parse_number(index, pathdata)
1194  num3, index, pathdata = self.parse_number(index, pathdata)
1195  num4, index, pathdata = self.parse_number(index, pathdata)
1196  num5, index, pathdata = self.parse_number(index, pathdata)
1197  num6, index, pathdata = self.parse_number(index, pathdata)
1198 
1199  ######################
1200  elif command in ("A", "a"):
1201  errstring = "Path command \"%s\" requires a rx,ry,angle,large-arc-flag,sweep-flag,x,y septuplet at index %d" % (command, index)
1202  num1, index, pathdata = self.parse_number(index, pathdata)
1203  num2, index, pathdata = self.parse_number(index, pathdata)
1204  num3, index, pathdata = self.parse_number(index, pathdata)
1205  num4, index, pathdata = self.parse_boolean(index, pathdata)
1206  num5, index, pathdata = self.parse_boolean(index, pathdata)
1207  num6, index, pathdata = self.parse_number(index, pathdata)
1208  num7, index, pathdata = self.parse_number(index, pathdata)
1209 
1210  if num1 == None: raise ValueError(errstring)
1211 
1212  while num1 != None:
1213  if num2 == None or num3 == None or num4 == None or num5 == None or num6 == None or num7 == None: raise ValueError(errstring)
1214 
1215  output.append((command, num1, num2, False, num3, num4, num5, num6, num7, False))
1216 
1217  num1, index, pathdata = self.parse_number(index, pathdata)
1218  num2, index, pathdata = self.parse_number(index, pathdata)
1219  num3, index, pathdata = self.parse_number(index, pathdata)
1220  num4, index, pathdata = self.parse_boolean(index, pathdata)
1221  num5, index, pathdata = self.parse_boolean(index, pathdata)
1222  num6, index, pathdata = self.parse_number(index, pathdata)
1223  num7, index, pathdata = self.parse_number(index, pathdata)
1224 
1225  return output
1226 
def parse_number(self, index, pathdata)
Definition: svgfig.py:1087
def parse(self, pathdata)
Definition: svgfig.py:1118
def parse_boolean(self, index, pathdata)
Definition: svgfig.py:1105
def parse_whitespace(self, index, pathdata)
Definition: svgfig.py:1070
def parse_command(self, index, pathdata)
Definition: svgfig.py:1075
def svgfig.Path.parse_boolean (   self,
  index,
  pathdata 
)
Part of Path's text-command parsing algorithm; used internally.

Definition at line 1105 of file svgfig.py.

References createfilelist.int, and svgfig.Path.parse_whitespace().

Referenced by svgfig.Path.parse().

1105  def parse_boolean(self, index, pathdata):
1106  """Part of Path's text-command parsing algorithm; used internally."""
1107  index, pathdata = self.parse_whitespace(index, pathdata)
1108 
1109  if index >= len(pathdata): return None, index, pathdata
1110  first_digit = pathdata[index]
1111 
1112  if first_digit in ("0", "1"):
1113  index += 1
1114  return int(first_digit), index, pathdata
1115  else:
1116  return None, index, pathdata
1117 
def parse_boolean(self, index, pathdata)
Definition: svgfig.py:1105
def parse_whitespace(self, index, pathdata)
Definition: svgfig.py:1070
def svgfig.Path.parse_command (   self,
  index,
  pathdata 
)
Part of Path's text-command parsing algorithm; used internally.

Definition at line 1075 of file svgfig.py.

References svgfig.Path.parse_whitespace().

Referenced by svgfig.Path.parse().

1075  def parse_command(self, index, pathdata):
1076  """Part of Path's text-command parsing algorithm; used internally."""
1077  index, pathdata = self.parse_whitespace(index, pathdata)
1078 
1079  if index >= len(pathdata): return None, index, pathdata
1080  command = pathdata[index]
1081  if "A" <= command <= "Z" or "a" <= command <= "z":
1082  index += 1
1083  return command, index, pathdata
1084  else:
1085  return None, index, pathdata
1086 
def parse_whitespace(self, index, pathdata)
Definition: svgfig.py:1070
def parse_command(self, index, pathdata)
Definition: svgfig.py:1075
def svgfig.Path.parse_number (   self,
  index,
  pathdata 
)
Part of Path's text-command parsing algorithm; used internally.

Definition at line 1087 of file svgfig.py.

References objects.autophobj.float, and svgfig.Path.parse_whitespace().

Referenced by svgfig.Path.parse().

1087  def parse_number(self, index, pathdata):
1088  """Part of Path's text-command parsing algorithm; used internally."""
1089  index, pathdata = self.parse_whitespace(index, pathdata)
1090 
1091  if index >= len(pathdata): return None, index, pathdata
1092  first_digit = pathdata[index]
1093 
1094  if "0" <= first_digit <= "9" or first_digit in ("-", "+", "."):
1095  start = index
1096  while index < len(pathdata) and ("0" <= pathdata[index] <= "9" or pathdata[index] in ("-", "+", ".", "e", "E")):
1097  index += 1
1098  end = index
1099 
1100  index = end
1101  return float(pathdata[start:end]), index, pathdata
1102  else:
1103  return None, index, pathdata
1104 
def parse_number(self, index, pathdata)
Definition: svgfig.py:1087
def parse_whitespace(self, index, pathdata)
Definition: svgfig.py:1070
def svgfig.Path.parse_whitespace (   self,
  index,
  pathdata 
)
Part of Path's text-command parsing algorithm; used internally.

Definition at line 1070 of file svgfig.py.

Referenced by svgfig.Path.parse(), svgfig.Path.parse_boolean(), svgfig.Path.parse_command(), and svgfig.Path.parse_number().

1070  def parse_whitespace(self, index, pathdata):
1071  """Part of Path's text-command parsing algorithm; used internally."""
1072  while index < len(pathdata) and pathdata[index] in (" ", "\t", "\r", "\n", ","): index += 1
1073  return index, pathdata
1074 
def parse_whitespace(self, index, pathdata)
Definition: svgfig.py:1070
def svgfig.Path.SVG (   self,
  trans = None 
)
Apply the transformation "trans" and return an SVG object.

Definition at line 1227 of file svgfig.py.

References svgfig.SVG.attr, svgfig.Path.attr, svgfig.Fig.d, svgfig.Plot.d, svgfig.Frame.d, svgfig.Path.d, join(), and svgfig.totrans().

1227  def SVG(self, trans=None):
1228  """Apply the transformation "trans" and return an SVG object."""
1229  if isinstance(trans, str): trans = totrans(trans)
1230 
1231  x, y, X, Y = None, None, None, None
1232  output = []
1233  for datum in self.d:
1234  if not isinstance(datum, (tuple, list)):
1235  raise TypeError("pathdata elements must be tuples/lists")
1236 
1237  command = datum[0]
1238 
1239  ######################
1240  if command in ("Z", "z"):
1241  x, y, X, Y = None, None, None, None
1242  output.append("Z")
1243 
1244  ######################
1245  elif command in ("H", "h", "V", "v"):
1246  command, num1 = datum
1247 
1248  if command == "H" or (command == "h" and x == None): x = num1
1249  elif command == "h": x += num1
1250  elif command == "V" or (command == "v" and y == None): y = num1
1251  elif command == "v": y += num1
1252 
1253  if trans == None: X, Y = x, y
1254  else: X, Y = trans(x, y)
1255 
1256  output.append("L%g %g" % (X, Y))
1257 
1258  ######################
1259  elif command in ("M", "m", "L", "l", "T", "t"):
1260  command, num1, num2, isglobal12 = datum
1261 
1262  if trans == None or isglobal12:
1263  if command.isupper() or X == None or Y == None:
1264  X, Y = num1, num2
1265  else:
1266  X += num1
1267  Y += num2
1268  x, y = X, Y
1269 
1270  else:
1271  if command.isupper() or x == None or y == None:
1272  x, y = num1, num2
1273  else:
1274  x += num1
1275  y += num2
1276  X, Y = trans(x, y)
1277 
1278  COMMAND = command.capitalize()
1279  output.append("%s%g %g" % (COMMAND, X, Y))
1280 
1281  ######################
1282  elif command in ("S", "s", "Q", "q"):
1283  command, num1, num2, isglobal12, num3, num4, isglobal34 = datum
1284 
1285  if trans == None or isglobal12:
1286  if command.isupper() or X == None or Y == None:
1287  CX, CY = num1, num2
1288  else:
1289  CX = X + num1
1290  CY = Y + num2
1291 
1292  else:
1293  if command.isupper() or x == None or y == None:
1294  cx, cy = num1, num2
1295  else:
1296  cx = x + num1
1297  cy = y + num2
1298  CX, CY = trans(cx, cy)
1299 
1300  if trans == None or isglobal34:
1301  if command.isupper() or X == None or Y == None:
1302  X, Y = num3, num4
1303  else:
1304  X += num3
1305  Y += num4
1306  x, y = X, Y
1307 
1308  else:
1309  if command.isupper() or x == None or y == None:
1310  x, y = num3, num4
1311  else:
1312  x += num3
1313  y += num4
1314  X, Y = trans(x, y)
1315 
1316  COMMAND = command.capitalize()
1317  output.append("%s%g %g %g %g" % (COMMAND, CX, CY, X, Y))
1318 
1319  ######################
1320  elif command in ("C", "c"):
1321  command, num1, num2, isglobal12, num3, num4, isglobal34, num5, num6, isglobal56 = datum
1322 
1323  if trans == None or isglobal12:
1324  if command.isupper() or X == None or Y == None:
1325  C1X, C1Y = num1, num2
1326  else:
1327  C1X = X + num1
1328  C1Y = Y + num2
1329 
1330  else:
1331  if command.isupper() or x == None or y == None:
1332  c1x, c1y = num1, num2
1333  else:
1334  c1x = x + num1
1335  c1y = y + num2
1336  C1X, C1Y = trans(c1x, c1y)
1337 
1338  if trans == None or isglobal34:
1339  if command.isupper() or X == None or Y == None:
1340  C2X, C2Y = num3, num4
1341  else:
1342  C2X = X + num3
1343  C2Y = Y + num4
1344 
1345  else:
1346  if command.isupper() or x == None or y == None:
1347  c2x, c2y = num3, num4
1348  else:
1349  c2x = x + num3
1350  c2y = y + num4
1351  C2X, C2Y = trans(c2x, c2y)
1352 
1353  if trans == None or isglobal56:
1354  if command.isupper() or X == None or Y == None:
1355  X, Y = num5, num6
1356  else:
1357  X += num5
1358  Y += num6
1359  x, y = X, Y
1360 
1361  else:
1362  if command.isupper() or x == None or y == None:
1363  x, y = num5, num6
1364  else:
1365  x += num5
1366  y += num6
1367  X, Y = trans(x, y)
1368 
1369  COMMAND = command.capitalize()
1370  output.append("%s%g %g %g %g %g %g" % (COMMAND, C1X, C1Y, C2X, C2Y, X, Y))
1371 
1372  ######################
1373  elif command in ("A", "a"):
1374  command, num1, num2, isglobal12, angle, large_arc_flag, sweep_flag, num3, num4, isglobal34 = datum
1375 
1376  oldx, oldy = x, y
1377  OLDX, OLDY = X, Y
1378 
1379  if trans == None or isglobal34:
1380  if command.isupper() or X == None or Y == None:
1381  X, Y = num3, num4
1382  else:
1383  X += num3
1384  Y += num4
1385  x, y = X, Y
1386 
1387  else:
1388  if command.isupper() or x == None or y == None:
1389  x, y = num3, num4
1390  else:
1391  x += num3
1392  y += num4
1393  X, Y = trans(x, y)
1394 
1395  if x != None and y != None:
1396  centerx, centery = (x + oldx)/2., (y + oldy)/2.
1397  CENTERX, CENTERY = (X + OLDX)/2., (Y + OLDY)/2.
1398 
1399  if trans == None or isglobal12:
1400  RX = CENTERX + num1
1401  RY = CENTERY + num2
1402 
1403  else:
1404  rx = centerx + num1
1405  ry = centery + num2
1406  RX, RY = trans(rx, ry)
1407 
1408  COMMAND = command.capitalize()
1409  output.append("%s%g %g %g %d %d %g %g" % (COMMAND, RX - CENTERX, RY - CENTERY, angle, large_arc_flag, sweep_flag, X, Y))
1410 
1411  elif command in (",", "."):
1412  command, num1, num2, isglobal12, angle, num3, num4, isglobal34 = datum
1413  if trans == None or isglobal34:
1414  if command == "." or X == None or Y == None:
1415  X, Y = num3, num4
1416  else:
1417  X += num3
1418  Y += num4
1419  x, y = None, None
1420 
1421  else:
1422  if command == "." or x == None or y == None:
1423  x, y = num3, num4
1424  else:
1425  x += num3
1426  y += num4
1427  X, Y = trans(x, y)
1428 
1429  if trans == None or isglobal12:
1430  RX = X + num1
1431  RY = Y + num2
1432 
1433  else:
1434  rx = x + num1
1435  ry = y + num2
1436  RX, RY = trans(rx, ry)
1437 
1438  RX, RY = RX - X, RY - Y
1439 
1440  X1, Y1 = X + RX * math.cos(angle*math.pi/180.), Y + RX * math.sin(angle*math.pi/180.)
1441  X2, Y2 = X + RY * math.sin(angle*math.pi/180.), Y - RY * math.cos(angle*math.pi/180.)
1442  X3, Y3 = X - RX * math.cos(angle*math.pi/180.), Y - RX * math.sin(angle*math.pi/180.)
1443  X4, Y4 = X - RY * math.sin(angle*math.pi/180.), Y + RY * math.cos(angle*math.pi/180.)
1444 
1445  output.append("M%g %gA%g %g %g 0 0 %g %gA%g %g %g 0 0 %g %gA%g %g %g 0 0 %g %gA%g %g %g 0 0 %g %g" \
1446  % (X1, Y1, RX, RY, angle, X2, Y2, RX, RY, angle, X3, Y3, RX, RY, angle, X4, Y4, RX, RY, angle, X1, Y1))
1447 
1448  return SVG("path", d="".join(output), **self.attr)
1449 
def SVG(self, trans=None)
Definition: svgfig.py:1227
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def totrans(expr, vars=("x","y"), globals=None, locals=None)
Definition: svgfig.py:598

Member Data Documentation

svgfig.Path.attr
svgfig.Path.d
dictionary svgfig.Path.defaults = {}
static

Definition at line 1058 of file svgfig.py.

Referenced by tree.Tree.reset(), and tree.Tree.var().