... | ... |
@@ -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 |