| ... | ... |
@@ -450,6 +450,9 @@ class XDotAttrParser: |
| 450 | 450 |
self.parser = parser |
| 451 | 451 |
self.buf = self.unescape(buf) |
| 452 | 452 |
self.pos = 0 |
| 453 |
+ |
|
| 454 |
+ self.pen = Pen() |
|
| 455 |
+ self.shapes = [] |
|
| 453 | 456 |
|
| 454 | 457 |
def __nonzero__(self): |
| 455 | 458 |
return self.pos < len(self.buf) |
| ... | ... |
@@ -495,7 +498,7 @@ class XDotAttrParser: |
| 495 | 498 |
p.append((x, y)) |
| 496 | 499 |
return p |
| 497 | 500 |
|
| 498 |
- def read_color(self, fallback=(0,0,0,1)): |
|
| 501 |
+ def read_color(self): |
|
| 499 | 502 |
# See http://www.graphviz.org/doc/info/attrs.html#k:color |
| 500 | 503 |
c = self.read_text() |
| 501 | 504 |
c1 = c[:1] |
| ... | ... |
@@ -516,86 +519,130 @@ class XDotAttrParser: |
| 516 | 519 |
a = 1.0 |
| 517 | 520 |
return r, g, b, a |
| 518 | 521 |
else: |
| 519 |
- try: |
|
| 520 |
- color = gtk.gdk.color_parse(c) |
|
| 521 |
- except ValueError: |
|
| 522 |
- sys.stderr.write("unknown color '%s'\n" % c)
|
|
| 523 |
- return fallback |
|
| 524 |
- s = 1.0/65535.0 |
|
| 525 |
- r = color.red*s |
|
| 526 |
- g = color.green*s |
|
| 527 |
- b = color.blue*s |
|
| 528 |
- a = 1.0 |
|
| 529 |
- return r, g, b, a |
|
| 522 |
+ return self.lookup_color(c) |
|
| 523 |
+ |
|
| 524 |
+ def lookup_color(self, c): |
|
| 525 |
+ try: |
|
| 526 |
+ color = gtk.gdk.color_parse(c) |
|
| 527 |
+ except ValueError: |
|
| 528 |
+ sys.stderr.write("unknown color '%s'\n" % c)
|
|
| 529 |
+ return None |
|
| 530 |
+ s = 1.0/65535.0 |
|
| 531 |
+ r = color.red*s |
|
| 532 |
+ g = color.green*s |
|
| 533 |
+ b = color.blue*s |
|
| 534 |
+ a = 1.0 |
|
| 535 |
+ return r, g, b, a |
|
| 530 | 536 |
|
| 531 | 537 |
def parse(self): |
| 532 |
- shapes = [] |
|
| 533 |
- pen = Pen() |
|
| 534 | 538 |
s = self |
| 535 | 539 |
|
| 536 | 540 |
while s: |
| 537 | 541 |
op = s.read_code() |
| 538 | 542 |
if op == "c": |
| 539 |
- pen.color = s.read_color(fallback=pen.color) |
|
| 543 |
+ color = s.read_color() |
|
| 544 |
+ if color is not None: |
|
| 545 |
+ self.handle_color(color, filled=False) |
|
| 540 | 546 |
elif op == "C": |
| 541 |
- pen.fillcolor = s.read_color(fallback=pen.fillcolor) |
|
| 547 |
+ color = s.read_color() |
|
| 548 |
+ if color is not None: |
|
| 549 |
+ self.handle_color(color, filled=True) |
|
| 542 | 550 |
elif op == "S": |
| 551 |
+ # http://www.graphviz.org/doc/info/attrs.html#k:style |
|
| 543 | 552 |
style = s.read_text() |
| 544 | 553 |
if style.startswith("setlinewidth("):
|
| 545 | 554 |
lw = style.split("(")[1].split(")")[0]
|
| 546 |
- pen.linewidth = float(lw) |
|
| 547 |
- elif style == "solid": |
|
| 548 |
- pen.dash = () |
|
| 549 |
- elif style == "dashed": |
|
| 550 |
- pen.dash = (6, ) # 6pt on, 6pt off |
|
| 555 |
+ lw = float(lw) |
|
| 556 |
+ self.handle_linewidth(lw) |
|
| 557 |
+ elif style in ("solid", "dashed"):
|
|
| 558 |
+ self.handle_linestyle(style) |
|
| 551 | 559 |
elif op == "F": |
| 552 |
- pen.fontsize = s.read_float() |
|
| 553 |
- pen.fontname = s.read_text() |
|
| 560 |
+ size = s.read_float() |
|
| 561 |
+ name = s.read_text() |
|
| 562 |
+ self.handle_font(size, name) |
|
| 554 | 563 |
elif op == "T": |
| 555 | 564 |
x, y = s.read_point() |
| 556 | 565 |
j = s.read_number() |
| 557 | 566 |
w = s.read_number() |
| 558 | 567 |
t = s.read_text() |
| 559 |
- shapes.append(TextShape(pen, x, y, j, w, t)) |
|
| 568 |
+ self.handle_text(x, y, j, w, t) |
|
| 560 | 569 |
elif op == "E": |
| 561 | 570 |
x0, y0 = s.read_point() |
| 562 | 571 |
w = s.read_number() |
| 563 | 572 |
h = s.read_number() |
| 564 |
- # xdot uses this to mean "draw a filled shape with an outline" |
|
| 565 |
- shapes.append(EllipseShape(pen, x0, y0, w, h, filled=True)) |
|
| 566 |
- shapes.append(EllipseShape(pen, x0, y0, w, h)) |
|
| 573 |
+ self.handle_ellipse(x0, y0, w, h, filled=False) |
|
| 567 | 574 |
elif op == "e": |
| 568 | 575 |
x0, y0 = s.read_point() |
| 569 | 576 |
w = s.read_number() |
| 570 | 577 |
h = s.read_number() |
| 571 |
- shapes.append(EllipseShape(pen, x0, y0, w, h)) |
|
| 578 |
+ self.handle_ellipse(x0, y0, w, h, filled=False) |
|
| 572 | 579 |
elif op == "L": |
| 573 |
- p = self.read_polygon() |
|
| 574 |
- shapes.append(LineShape(pen, p)) |
|
| 580 |
+ points = self.read_polygon() |
|
| 581 |
+ self.handle_line(points) |
|
| 575 | 582 |
elif op == "B": |
| 576 |
- p = self.read_polygon() |
|
| 577 |
- shapes.append(BezierShape(pen, p)) |
|
| 583 |
+ points = self.read_polygon() |
|
| 584 |
+ self.handle_bezier(points, filled=False) |
|
| 578 | 585 |
elif op == "b": |
| 579 | 586 |
p = self.read_polygon() |
| 580 |
- # xdot uses this to mean "draw a filled shape with an outline" |
|
| 581 |
- shapes.append(BezierShape(pen, p, filled=True)) |
|
| 582 |
- shapes.append(BezierShape(pen, p)) |
|
| 587 |
+ self.handle_bezier(points, filled=True) |
|
| 583 | 588 |
elif op == "P": |
| 584 |
- p = self.read_polygon() |
|
| 585 |
- # xdot uses this to mean "draw a filled shape with an outline" |
|
| 586 |
- shapes.append(PolygonShape(pen, p, filled=True)) |
|
| 587 |
- shapes.append(PolygonShape(pen, p)) |
|
| 589 |
+ points = self.read_polygon() |
|
| 590 |
+ self.handle_polygon(points, filled=True) |
|
| 588 | 591 |
elif op == "p": |
| 589 |
- p = self.read_polygon() |
|
| 590 |
- shapes.append(PolygonShape(pen, p)) |
|
| 592 |
+ points = self.read_polygon() |
|
| 593 |
+ self.handle_polygon(points, filled=False) |
|
| 591 | 594 |
else: |
| 592 | 595 |
sys.stderr.write("unknown xdot opcode '%s'\n" % op)
|
| 593 | 596 |
break |
| 594 |
- return shapes |
|
| 595 | 597 |
|
| 598 |
+ return self.shapes |
|
| 599 |
+ |
|
| 596 | 600 |
def transform(self, x, y): |
| 597 | 601 |
return self.parser.transform(x, y) |
| 598 | 602 |
|
| 603 |
+ def handle_color(self, color, filled=False): |
|
| 604 |
+ if filled: |
|
| 605 |
+ self.pen.fillcolor = color |
|
| 606 |
+ else: |
|
| 607 |
+ self.pen.color = color |
|
| 608 |
+ |
|
| 609 |
+ def handle_linewidth(self, linewidth): |
|
| 610 |
+ self.pen.linewidth = linewidth |
|
| 611 |
+ |
|
| 612 |
+ def handle_linestyle(self, style): |
|
| 613 |
+ if style == "solid": |
|
| 614 |
+ self.pen.dash = () |
|
| 615 |
+ elif style == "dashed": |
|
| 616 |
+ self.pen.dash = (6, ) # 6pt on, 6pt off |
|
| 617 |
+ |
|
| 618 |
+ def handle_font(self, size, name): |
|
| 619 |
+ self.pen.fontsize = size |
|
| 620 |
+ self.pen.fontname = name |
|
| 621 |
+ |
|
| 622 |
+ def handle_text(self, x, y, j, w, t): |
|
| 623 |
+ self.shapes.append(TextShape(self.pen, x, y, j, w, t)) |
|
| 624 |
+ |
|
| 625 |
+ def handle_ecllipse(self, x0, y0, w, h): |
|
| 626 |
+ if filled: |
|
| 627 |
+ # xdot uses this to mean "draw a filled shape with an outline" |
|
| 628 |
+ self.shapes.append(EclipseShape(self.pen, x0, y0, w, h, filled=True)) |
|
| 629 |
+ self.shapes.append(PolygonShape(self.pen, x0, y0, w, h)) |
|
| 630 |
+ |
|
| 631 |
+ def handle_line(self, points): |
|
| 632 |
+ self.shapes.append(LineShape(self.pen, points)) |
|
| 633 |
+ |
|
| 634 |
+ def handle_bezier(self, points, filled=False): |
|
| 635 |
+ if filled: |
|
| 636 |
+ # xdot uses this to mean "draw a filled shape with an outline" |
|
| 637 |
+ self.shapes.append(BezierShape(self.pen, points, filled=True)) |
|
| 638 |
+ self.shapes.append(BezierShape(self.pen, points)) |
|
| 639 |
+ |
|
| 640 |
+ def handle_polygon(self, points, filled=False): |
|
| 641 |
+ if filled: |
|
| 642 |
+ # xdot uses this to mean "draw a filled shape with an outline" |
|
| 643 |
+ self.shapes.append(PolygonShape(self.pen, points, filled=True)) |
|
| 644 |
+ self.shapes.append(PolygonShape(self.pen, points)) |
|
| 645 |
+ |
|
| 599 | 646 |
|
| 600 | 647 |
EOF = -1 |
| 601 | 648 |
SKIP = -2 |