Bump version to 6.4.7.2.M8
[LibreOffice.git] / solenv / gdb / libreoffice / basegfx.py
blobc14968c91eb27d987375e08b901f5c1950edb63b
1 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 import gdb
11 import six
13 from libreoffice.util import printing
15 class B2DRangePrinter(object):
16 '''Prints a B2DRange object.'''
18 def __init__(self, typename, value):
19 self.typename = typename
20 self.value = value
21 # inject children() func dynamically
22 if not self._isEmpty():
23 self.children = self._children
25 def to_string(self):
26 if self._isEmpty():
27 return "empty %s" % (self.typename)
28 else:
29 return "%s" % (self.typename)
31 def _isEmpty(self):
32 return (self.value['maRangeX']['mnMinimum'] > self.value['maRangeX']['mnMaximum']
33 or self.value['maRangeY']['mnMinimum'] > self.value['maRangeY']['mnMaximum'])
35 def _children(self):
36 left = self.value['maRangeX']['mnMinimum']
37 top = self.value['maRangeY']['mnMinimum']
38 right = self.value['maRangeX']['mnMaximum']
39 bottom = self.value['maRangeY']['mnMaximum']
40 children = [('left', left), ('top', top), ('right', right), ('bottom', bottom)]
41 return children.__iter__()
43 class B2DPolygonPrinter(object):
44 '''Prints a B2DPolygon object.'''
46 def __init__(self, typename, value):
47 self.typename = typename
48 self.value = value
49 # inject children() func dynamically
50 if not self._isEmpty():
51 self.children = self._children
53 def to_string(self):
54 if self._isEmpty():
55 return "empty %s" % (self.typename)
56 else:
57 return "%s %s" % ('bezier curve' if self._hasCurves() else 'straight line',
58 self.typename)
60 def _count(self):
61 # It's a call into the inferior (being debugged) process.
62 # Will not work with core dumps and can cause a deadlock.
63 return int(gdb.parse_and_eval(
64 "(('basegfx::B2DPolygon' *) {})->count()".format(self.value.address)))
66 def _isEmpty(self):
67 return self._count() == 0
69 def _hasCurves(self):
70 # It's a call into the inferior (being debugged) process.
71 # Will not work with core dumps and can cause a deadlock.
72 return int(gdb.parse_and_eval(
73 "(('basegfx::B2DPolygon' *) {})->areControlPointsUsed()".format(self.value.address))) != 0
75 def _children(self):
76 if self._hasCurves():
77 return self._bezierIterator(self._count(), self.value)
78 else:
79 return self._plainIterator(self._count(), self.value)
81 class _plainIterator(six.Iterator):
82 def __init__(self, count, value):
83 self.count = count
84 self.value = value
85 self.index = 0
87 def __iter__(self):
88 return self
90 def __next__(self):
91 if self.index >= self.count:
92 raise StopIteration()
93 points = self.value['mpPolygon']['m_pimpl'].dereference()['m_value']['maPoints']['maVector']
94 currPoint = (points['_M_impl']['_M_start'] + self.index).dereference()
95 # doesn't work?
96 #currPoint = gdb.parse_and_eval(
97 # '((basegfx::B2DPolygon*)%d)->getB2DPoint(%d)' % (
98 # self.value.address, self.index))
99 self.index += 1
100 return ('point %d' % (self.index-1),
101 '(%15f, %15f)' % (currPoint['mfX'], currPoint['mfY']))
103 class _bezierIterator(six.Iterator):
104 def __init__(self, count, value):
105 self.count = count
106 self.value = value
107 self.index = 0
109 def __iter__(self):
110 return self
112 def __next__(self):
113 if self.index >= self.count:
114 raise StopIteration()
115 points = self.value['mpPolygon']['m_pimpl'].dereference()['m_value']['maPoints']['maVector']
116 currPoint = (points['_M_impl']['_M_start'] + self.index).dereference()
117 #currPoint = gdb.parse_and_eval(
118 # '((basegfx::B2DPolygon*)%d)->getB2DPoint(%d)' % (
119 # self.value.address, self.index))
121 # It's a call into the inferior (being debugged) process.
122 # Will not work with core dumps and can cause a deadlock.
123 prevControl = gdb.parse_and_eval(
124 "(('basegfx::B2DPolygon' *) {})->getPrevControlPoint({:d})".format(self.value.address, self.index))
125 # It's a call into the inferior (being debugged) process.
126 # Will not work with core dumps and can cause a deadlock.
127 nextControl = gdb.parse_and_eval(
128 "(('basegfx::B2DPolygon' *) {})->getNextControlPoint({:d})".format(self.value.address, self.index))
129 self.index += 1
130 return ('point %d' % (self.index-1),
131 'p: (%15f, %15f) c-1: (%15f, %15f) c1: (%15f, %15f)' %
132 (currPoint['mfX'], currPoint['mfY'],
133 prevControl['mfX'], prevControl['mfY'],
134 nextControl['mfX'], nextControl['mfY']))
136 class B2DPolyPolygonPrinter(object):
137 '''Prints a B2DPolyPolygon object.'''
139 def __init__(self, typename, value):
140 self.typename = typename
141 self.value = value
143 def to_string(self):
144 if self._isEmpty():
145 return "empty %s" % (self.typename)
146 else:
147 return "%s %s with %d sub-polygon(s)" % ('closed' if self._isClosed() else 'open',
148 self.typename,
149 self._count())
151 def _count(self):
152 # It's a call into the inferior (being debugged) process.
153 # Will not work with core dumps and can cause a deadlock.
154 return int(gdb.parse_and_eval(
155 "(('basegfx::B2DPolyPolygon' *) {})->count()".format(self.value.address)))
157 def _isClosed(self):
158 # It's a call into the inferior (being debugged) process.
159 # Will not work with core dumps and can cause a deadlock.
160 return int(gdb.parse_and_eval(
161 "(('basegfx::B2DPolyPolygon' *) {})->isClosed()".format(self.value.address))) != 0
163 def _isEmpty(self):
164 return self._count() == 0
166 def children(self):
167 if self.value['mpPolyPolygon']['m_pimpl'].type.code in (gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_MEMBERPTR):
168 if self.value['mpPolyPolygon']['m_pimpl']:
169 try:
170 vector = self.value['mpPolyPolygon']['m_pimpl'].dereference()['m_value']['maPolygons']
171 import libstdcxx.v6.printers as std
172 return std.StdVectorPrinter("std::vector", vector).children()
173 except RuntimeError:
174 gdb.write("Cannot access memory at address " + str(self.value['mpPolyPolygon']['m_pimpl'].address))
176 return None
178 printer = None
180 def build_pretty_printers():
181 global printer
183 printer = printing.Printer('libreoffice/basegfx')
185 # basic types
186 printer.add('basegfx::B2DRange', B2DRangePrinter)
187 printer.add('basegfx::B2DPolygon', B2DPolygonPrinter)
188 printer.add('basegfx::B2DPolyPolygon', B2DPolyPolygonPrinter)
190 def register_pretty_printers(obj):
191 printing.register_pretty_printer(printer, obj)
193 build_pretty_printers()
195 # vim:set shiftwidth=4 softtabstop=4 expandtab: