Browse code

Add underlined/bolded/italic/superscripted/subscripted text.

Emilien Kofman authored on 20/02/2015 09:46:09 • Jose Fonseca committed on 20/02/2015 10:28:30
Showing 2 changed files

1 1
new file mode 100644
... ...
@@ -0,0 +1,6 @@
1
+digraph G {
2
+    Foo[label=<<B>Hello</B><SUP>world</SUP>>]
3
+    Bar[label=<<U><I><S>Hel</S>lo</I></U><SUB><B>world</B></SUB>>]
4
+
5
+    Foo->Bar
6
+}
... ...
@@ -56,6 +56,14 @@ class Pen:
56 56
         self.linewidth = 1.0
57 57
         self.fontsize = 14.0
58 58
         self.fontname = "Times-Roman"
59
+        self.bold = False
60
+        self.italic = False
61
+        self.underline = False
62
+        self.superscript = False
63
+        self.subscript = False
64
+        self.strikethrough = False
65
+        self.overline = False
66
+
59 67
         self.dash = ()
60 68
 
61 69
     def copy(self):
... ...
@@ -102,9 +110,9 @@ class TextShape(Shape):
102 110
         self.pen = pen.copy()
103 111
         self.x = x
104 112
         self.y = y
105
-        self.j = j
106
-        self.w = w
107
-        self.t = t
113
+        self.j = j  # Centering
114
+        self.w = w  # width
115
+        self.t = t  # text
108 116
 
109 117
     def draw(self, cr, highlight=False):
110 118
 
... ...
@@ -129,8 +137,28 @@ class TextShape(Shape):
129 137
 
130 138
             # set font
131 139
             font = pango.FontDescription()
140
+            attrs = pango.AttrList()
141
+
142
+            # set font attributes
143
+            if self.pen.bold:
144
+                font.set_weight(pango.WEIGHT_BOLD)
145
+            if self.pen.italic:
146
+                font.set_style(pango.STYLE_ITALIC)
147
+            if self.pen.underline:
148
+                underline = pango.AttrUnderline(pango.UNDERLINE_SINGLE, 0, len(self.t))
149
+                attrs.insert(underline)
150
+            if self.pen.strikethrough:
151
+                st =  pango.AttrStrikethrough(True, 0, len(self.t))
152
+                attrs.insert(st)
153
+
154
+            layout.set_attributes(attrs)
155
+
156
+            fontsize = self.pen.fontsize
157
+            if self.pen.superscript or self.pen.subscript:
158
+                fontsize /= 1.5
159
+
132 160
             font.set_family(self.pen.fontname)
133
-            font.set_absolute_size(self.pen.fontsize*pango.SCALE)
161
+            font.set_absolute_size(fontsize*pango.SCALE)
134 162
             layout.set_font_description(font)
135 163
 
136 164
             # set text
... ...
@@ -146,6 +174,7 @@ class TextShape(Shape):
146 174
         width, height = layout.get_size()
147 175
         width = float(width)/pango.SCALE
148 176
         height = float(height)/pango.SCALE
177
+
149 178
         # we know the width that dot thinks this text should have
150 179
         # we do not necessarily have a font with the same metrics
151 180
         # scale it so that the text fits inside its box
... ...
@@ -166,7 +195,10 @@ class TextShape(Shape):
166 195
         else:
167 196
             assert 0
168 197
 
169
-        y = self.y - height + descent
198
+        if self.pen.superscript:
199
+            y = self.y - 1.5*height
200
+        else:
201
+            y = self.y - height + descent
170 202
 
171 203
         cr.move_to(x, y)
172 204
 
... ...
@@ -718,9 +750,15 @@ class XDotAttrParser:
718 750
         self.pen.fontname = name
719 751
 
720 752
     def handle_font_characteristics(self, flags):
721
-        # TODO
722
-        if flags != 0:
723
-            sys.stderr.write("warning: font characteristics not supported yet\n")
753
+        self.pen.bold = bool(flags & BOLD)
754
+        self.pen.italic = bool(flags & ITALIC)
755
+        self.pen.underline = bool(flags & UNDERLINE)
756
+        self.pen.superscript = bool(flags & SUPERSCRIPT)
757
+        self.pen.subscript = bool(flags & SUBSCRIPT)
758
+        self.pen.strikethrough = bool(flags & STRIKE_THROUGH)
759
+        self.pen.overline = bool(flags & OVERLINE)
760
+        if self.pen.overline:
761
+            sys.stderr.write('warning: overlined text not supported yet\n')
724 762
 
725 763
     def handle_text(self, x, y, j, w, t):
726 764
         self.shapes.append(TextShape(self.pen, x, y, j, w, t))