File: diadissect.py

package info (click to toggle)
dia 0.97.3%2Bgit20160930-9
  • links: PTS
  • area: main
  • in suites: bullseye
  • size: 54,372 kB
  • sloc: ansic: 155,065; xml: 16,326; python: 6,641; cpp: 4,935; makefile: 3,833; sh: 540; perl: 137; sed: 19
file content (164 lines) | stat: -rw-r--r-- 6,191 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#
# Dissect a diagram by rendering it and accumulating invalid
# renderer calls to object selection.
#
# Copyright (c) 2014 Hans Breuer <hans@breuer.org>
#
#    This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

import sys, string, dia

##
# \brief A dissecting renderer for Dia
#
# Check the diagram by rendering it and report anomalies with their
# call and the causing object.
#
# \extends _DiaPyRenderer
# \ingroup ExportFilters
class DissectRenderer :
	def __init__ (self) :
		self.f = None
		self.current_objects = []
		self.warnings = []
		self.errors = []
		self.font = None
	def _open(self, filename) :
		self.f = open(filename, "w")
	def begin_render (self, data, filename) :
		self._open (filename)
		self.extents = data.extents
		try :
			# this can fail for two reason:
			#  1) data.diagram is None, e.g. when running from pure bindings
			#  2) there is no member data.diagram because Dia is just too old
			self.f.write ("# Dissect %s\n" % (data.diagram.filename,))
		except :
			self.f.write ("# Dissect %s\n" % (filename,))
	def end_render (self) :
		self.f.write('%d error(s) %d warning(s)\n' % (len(self.errors), len(self.warnings)))
		self.f.close ()
	def Warning (self, msg) :
		self.warnings.append ((self.current_objects[-1], msg))
		if self.f :
			self.f.write ("Warning: %s, %s\n" % (self.current_objects[-1], msg))
	def Error (self, msg) :
		self.errors.append ((self.current_objects[-1], msg))
		if self.f :
			self.f.write ("Error: %s, %s\n" % (self.current_objects[-1], msg))
	def draw_object (self, object, matrix) :
		self.current_objects.append (object)
		# XXX: check matrix
		# don't forget to render the object
		object.draw (self)
		del self.current_objects[-1]
	def set_linewidth (self, width) :
		# width==0 is hairline
		if width < 0 or width > 10 :
			self.Warning ("linewidth out of range")
	def set_linecaps (self, mode) :
		if mode < 0 or mode > 2 :
			self.Error ("linecaps '%d' unknown" % (mode,))
	def set_linejoin (self, mode) :
		if mode < 0 or mode > 2 :
			self.Error ("linejoin '%d' unknown" % (mode,))
	def set_linestyle (self, style, dash_length) :
		if style < 0 or style > 4 :
			self.Error ("linestyle '%d' unknown" % (style,))
		if dash_length < 0.001 or dash_length > 1 :
			self.Warning ("dashlength '%f' out of range" % (dash_length,))
	def set_fillstyle (self, style) :
		# currently only 'solid' so not used anywhere else
		if style != 0 :
			self.Error ("fillstyle '%d' unknown" % (style,))
	def set_font (self, font, size) :
		self.font = font
		self.font_size = size
	def draw_line (self, start, end, color) :
		pass # can anything go wrong here ?
	def draw_polyline (self, points, color) :
		if len(points) < 2 :
			self.Error ("draw_polyline with too few points")
	def _polygon (self, points, fun) :
		if len(points) < 3 :
			self.Error ("%s with too few points" % (fun,))
	def draw_polygon (self, points, fill, stroke) :
		self._polygon(points, "draw_polygon")
	# obsolete with recent Dia
	def fill_polygon (self, points, color) :
		self._polygon(points, "draw_polygon")
	def _rect (self, rect, fun) :
		if rect.top > rect.bottom :
			self.Warning ("%s negative height" % (fun,))
		if rect.left > rect.right :
			self.Warning ("%s negative width" % (fun,))
	def draw_rect (self, rect, fill, stroke) :
		self._rect (rect, "draw_rect")
	def draw_rounded_rect (self, rect, fill, stroke, rounding) :
		# XXX: check rounding to be positive (smaller than half width, height?)
		self._rect (rect, "draw_rect")
	def _arc (self, center, width, height, angle1, angle2, fun) :
		if width <= 0 :
			self.Warning ("%s width too small" % (fun,))
		if height <= 0 :
			self.Warning ("%s height too small" % (fun,))
		# angles
		rot = 0.0
		if angle1 < angle2 :
			rot = angle2 - angle1
		else :
			rot = angle1 - angle2
		if rot <= 0 or rot >= 360 :
			self.Warning ("%s bad rotation %g,%g" % (fun, angle1, angle2))
	def draw_arc (self, center, width, height, angle1, angle2, color) :
		self._arc(center, width, height, angle1, angle2, "draw_arc")
	def fill_arc (self, center, width, height, angle1, angle2, color) :
		self._arc(center, width, height, angle1, angle2, "fill_arc")
	def draw_ellipse (self, center, width, height, fill, stroke) :
		self._arc(center, width, height, 0, 360, "draw_ellipse")
	def _bezier (self, bezpoints, fun) :
		nMoves = 0
		for bp in bezpoints :
			if bp.type == 0 : # BEZ_MOVE_TO
				nMoves = nMoves + 1
				if nMoves > 1 :
					self.Warning ("%s move-to within", (fun,))
			elif bp.type == 1 : # BEZ_LINE_TO
				pass
			elif bp.type == 2 : # BEZ_CURVE_TO
				pass
			else :
				self.Error ("%s invalid BezPoint type='%d'" % (fun, bp.type,))
	def draw_bezier (self, bezpoints, color) :
		if len(bezpoints) < 2 :
			self.Error ("draw_bezier too few points");
		self._bezier (bezpoints, "draw_bezier")
	def fill_bezier (self, bezpoints, color) :
		if len(bezpoints) < 3 :
			self.Error ("fill_bezier too few points");
		self._bezier (bezpoints, "fill_bezier")
	def draw_string (self, text, pos, alignment, color) :
		if len(text) < 1 :
			self.Warning ("draw_string empty text")
		if alignment < 0 or alignment > 2 :
			self.Error ("draw_string unknown alignmern '%d'" % (alignment,))
	def draw_image (self, point, width, height, image) :
		if width <= 0 :
			self.Warning ("draw_image width too small")
		if height <= 0 :
			self.Warning ("draw_image height too small")
		# XXX: check image, e.g. existing file name
# dia-python keeps a reference to the renderer class and uses it on demand
dia.register_export ("Dissect", "dissect", DissectRenderer())