def add_plus_mark( self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( o.atom.line_color), fill_color=self.paper.any_color_to_rgb_string( o.atom.area_color), stroke_width=Screen.px_to_cm( 1)) style_name = self.get_appropriate_style_name( s) # we must process oval first - it would otherwise cover the lines for i in o.items: if self.paper.type( i) == "oval": x, y, x2, y2 = map( Screen.px_to_cm, self.paper.coords( i)) size = Screen.px_to_cm( o.size) dom_extensions.elementUnder( page, 'draw:ellipse', (( 'svg:x', '%fcm' % x), ( 'svg:y', '%fcm' % y), ( 'svg:width', '%fcm' % size), ( 'svg:height', '%fcm' % size), ( 'draw:style-name', style_name))) for i in o.items: if self.paper.type( i) == "line": coords = self.paper.coords( i) # because some weird bug in tcl/tk i had to hack the coordinates in marks.py # the hack is reversed here in order to get the coords back # I also reduce the size of the mark a little #if o.items.index( i) == 1: # coords[0] += 0 # coords[2] += -1 #elif o.items.index( i) == 2: # coords[1] += 0 # coords[3] += -1 # end of hack coords = map( Screen.px_to_cm, coords) self.create_oo_line( coords, page, style_name)
def get_package(self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" a = doc.createElement('text') a.setAttribute('id', self.id) if self.area_color != '': a.setAttribute('background-color', self.area_color) if self.font_size != self.paper.standard.font_size \ or self.font_family != self.paper.standard.font_family \ or self.line_color != self.paper.standard.line_color: font = dom_extensions.elementUnder( a, 'font', attributes=(('size', str(self.font_size)), ('family', self.font_family))) if self.line_color != self.paper.standard.line_color: font.setAttribute('color', self.line_color) x, y = Screen.px_to_text_with_unit((self.x, self.y)) dom_extensions.elementUnder(a, 'point', attributes=(('x', x), ('y', y))) ftext = dom_extensions.elementUnder(a, 'ftext') ftext.appendChild(doc.createTextNode(self.xml_ftext)) return a
def get_package( self, doc, items=None): if not items: to_export = self.children else: to_export = items mol = doc.createElement('molecule') mol.setAttribute( 'name', self.name) mol.setAttribute( 'id', self.id) if self.display_form: mol.appendChild( dom.parseString( '<display-form>%s</display-form>' % self.display_form).childNodes[0]) if self.t_atom: if self.t_bond_second and self.t_bond_first: dom_extensions.elementUnder( mol, 'template', ( ('atom', str( self.t_atom.id)), ('bond_first', str( self.t_bond_first.id)), ('bond_second', str( self.t_bond_second.id)))) else: dom_extensions.elementUnder( mol, 'template', ( ('atom', str( self.t_atom.id)),)) for i in to_export: mol.appendChild( i.get_package( doc)) if 1: #not items: # (we do not save fragments if the molecule is not guaranteed to be saved whole) old # now the approach is - you must know what you do! self.check_fragments() [mol.appendChild( f.get_package( doc)) for f in self.fragments] for ud in self.user_data: mol.appendChild( ud) return mol
def add_atom( self, a): """adds atom item to SVG document""" if a.show: item = a.selector x1, y1 = a.get_xy() x, y, x2, y2 = self.paper.bbox( item) if a.area_color != '': # it is not needed to export the rectangle in case its transparent dom_extensions.elementUnder( self.group, 'rect', (( 'x', self.convert( x)), ( 'y', self.convert( y)), ( 'width', self.convert( x2-x)), ( 'height', self.convert( y2-y)), ( 'fill', self.cc( a.area_color)), ( 'stroke', self.cc( a.area_color)))) # some fine tuning y1 += a.font.metrics('descent') + Tuning.SVG.text_y_shift x += Tuning.SVG.text_x_shift ## hack to compensate for the wrong measuring of text text = ftext_to_svg_dom( a.xml_ftext) dom_extensions.setAttributes( text, (( "x", self.convert( x)), ( "y", self.convert( y1)), ( "font-family", a.font_family), ( "font-size", '%d%s' % (a.font_size, pt_or_px)), ( 'fill', self.cc( a.line_color)))) # set the text length but only for text longer than threshold if (x2-x) > 50: text.setAttribute( 'textLength', "%.1f" % (x2-x)) self.group.appendChild( text) if hasattr( a, "marks"): for m in a.marks: self.group.appendChild( m.get_svg_element( self.document))
def add_atom(self, a): """adds atom item to SVG document""" if a.show: item = a.selector x1, y1 = a.get_xy() x, y, x2, y2 = self.paper.bbox(item) if a.area_color != '': # it is not needed to export the rectangle in case its transparent dom_extensions.elementUnder( self.group, 'rect', (('x', self.convert(x)), ('y', self.convert(y)), ('width', self.convert(x2 - x)), ('height', self.convert(y2 - y)), ('fill', self.cc(a.area_color)), ('stroke', self.cc(a.area_color)))) # some fine tuning y1 += a.font.metrics('descent') + Tuning.SVG.text_y_shift x += Tuning.SVG.text_x_shift ## hack to compensate for the wrong measuring of text text = ftext_to_svg_dom(a.xml_ftext) dom_extensions.setAttributes( text, (("x", self.convert(x)), ("y", self.convert(y1)), ("font-family", a.font_family), ("font-size", '%d%s' % (a.font_size, pt_or_px)), ('fill', self.cc(a.line_color)))) # set the text length but only for text longer than threshold if (x2 - x) > 50: text.setAttribute('textLength', "%.1f" % (x2 - x)) self.group.appendChild(text) if hasattr(a, "marks"): for m in a.marks: self.group.appendChild(m.get_svg_element(self.document))
def create_oo_line(self, coords, page, gr_style_name): x1, y1, x2, y2 = coords dom_extensions.elementUnder( page, 'draw:line', (('svg:x1', '%fcm' % x1), ('svg:y1', '%fcm' % y1), ('svg:x2', '%fcm' % x2), ('svg:y2', '%fcm' % y2), ('draw:layer', 'layout'), ('draw:style-name', gr_style_name)))
def add_plus_mark(self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string(o.atom.line_color), fill_color=self.paper.any_color_to_rgb_string(o.atom.area_color), stroke_width=Screen.px_to_cm(1)) style_name = self.get_appropriate_style_name(s) # we must process oval first - it would otherwise cover the lines for i in o.items: if self.paper.type(i) == "oval": x, y, x2, y2 = map(Screen.px_to_cm, self.paper.coords(i)) size = Screen.px_to_cm(o.size) dom_extensions.elementUnder(page, 'draw:ellipse', (('svg:x', '%fcm' % x), ('svg:y', '%fcm' % y), ('svg:width', '%fcm' % size), ('svg:height', '%fcm' % size), ('draw:style-name', style_name))) for i in o.items: if self.paper.type(i) == "line": coords = self.paper.coords(i) # because some weird bug in tcl/tk i had to hack the coordinates in marks.py # the hack is reversed here in order to get the coords back # I also reduce the size of the mark a little #if o.items.index( i) == 1: # coords[0] += 0 # coords[2] += -1 #elif o.items.index( i) == 2: # coords[1] += 0 # coords[3] += -1 # end of hack coords = map(Screen.px_to_cm, coords) self.create_oo_line(coords, page, style_name)
def get_package(self, doc, items=None): if not items: to_export = self.children else: to_export = items mol = doc.createElement('molecule') mol.setAttribute('name', self.name) mol.setAttribute('id', self.id) if self.display_form: mol.appendChild( dom.parseString('<display-form>%s</display-form>' % self.display_form).childNodes[0]) if self.t_atom: if self.t_bond_second and self.t_bond_first: dom_extensions.elementUnder( mol, 'template', (('atom', str(self.t_atom.id)), ('bond_first', str(self.t_bond_first.id)), ('bond_second', str(self.t_bond_second.id)))) else: dom_extensions.elementUnder(mol, 'template', (('atom', str(self.t_atom.id)), )) for i in to_export: mol.appendChild(i.get_package(doc)) if 1: #not items: # (we do not save fragments if the molecule is not guaranteed to be saved whole) old # now the approach is - you must know what you do! self.check_fragments() [mol.appendChild(f.get_package(doc)) for f in self.fragments] for ud in self.user_data: mol.appendChild(ud) return mol
def add_text(self, t): """Add text item to SVG document. """ x1, y1 = t.get_xy() x, y, x2, y2 = t.ftext.bbox( complete=True) _x, y, _x2, y2 = t.ftext.bbox( complete=False) if t.area_color: # it is not needed to export the rectangle in case its transparent dom_extensions.elementUnder( self.group, 'rect', (( 'x', self.convert( x)), ( 'y', self.convert( y)), ( 'width', self.convert( x2-x)), ( 'height', self.convert( y2-y)), ( 'fill', self.cc( t.area_color)), ( 'stroke', self.cc( t.area_color)))) y1 += (y2-y)/4.0 x += 2 ## hack to compensate for the wrong measuring of text text = ftext_dom_to_svg_dom(dom.parseString(t.ftext.sanitized_text().encode('utf-8')), self.document, replace_minus=t.paper.get_paper_property('replace_minus')) dom_extensions.setAttributes( text, (( "x", self.convert( x)), ( "y", self.convert( y1)), ( "font-family", t.font_family), ( "font-size", '%d%s' % (t.font_size, pt_or_px)), ( 'fill', self.cc( t.line_color)), ( 'textLength', "%d" % (x2-x+len( [1 for i in t.xml_ftext if i=="-" and t.paper.get_paper_property( 'replace_minus')]))))) self.group.appendChild( text)
def add_text(self, t): """Add text item to SVG document. """ x1, y1 = t.get_xy() x, y, x2, y2 = t.ftext.bbox(complete=True) _x, y, _x2, y2 = t.ftext.bbox(complete=False) if t.area_color: # it is not needed to export the rectangle in case its transparent dom_extensions.elementUnder(self.group, 'rect', (('x', self.convert(x)), ('y', self.convert(y)), ('width', self.convert(x2 - x)), ('height', self.convert(y2 - y)), ('fill', self.cc(t.area_color)), ('stroke', self.cc(t.area_color)))) y1 += (y2 - y) / 4.0 x += 2 ## hack to compensate for the wrong measuring of text text = ftext_dom_to_svg_dom( dom.parseString(t.ftext.sanitized_text().encode('utf-8')), self.document, replace_minus=t.paper.get_paper_property('replace_minus')) dom_extensions.setAttributes( text, (("x", self.convert(x)), ("y", self.convert(y1)), ("font-family", t.font_family), ("font-size", '%d%s' % (t.font_size, pt_or_px)), ('fill', self.cc(t.line_color)), ('textLength', "%d" % (x2 - x + len([ 1 for i in t.xml_ftext if i == "-" and t.paper.get_paper_property('replace_minus') ]))))) self.group.appendChild(text)
def get_package(self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" yes_no = ['no', 'yes'] on_off = ['off', 'on'] a = doc.createElement('atom') a.setAttribute('id', str(self.id)) # charge if self.charge: a.setAttribute("charge", str(self.charge)) #show attribute is set only when non default if (self.show and self.symbol == 'C') or (not self.show and self.symbol != 'C'): a.setAttribute('show', yes_no[self.show]) if self.show: a.setAttribute('pos', self.pos) if self.font_size != self.paper.standard.font_size \ or self.font_family != self.paper.standard.font_family \ or self.line_color != self.paper.standard.line_color: font = dom_extensions.elementUnder( a, 'font', attributes=(('size', str(self.font_size)), ('family', self.font_family))) if self.line_color != self.paper.standard.line_color: font.setAttribute('color', self.line_color) a.setAttribute('name', self.symbol) if self.show_hydrogens: a.setAttribute('hydrogens', on_off[self.show_hydrogens]) if self.area_color != self.paper.standard.area_color: a.setAttribute('background-color', self.area_color) # needed to support transparent handling of molecular size x, y, z = map(Screen.px_to_text_with_unit, self.get_xyz(real=1)) if self.z: dom_extensions.elementUnder(a, 'point', attributes=(('x', x), ('y', y), ('z', z))) else: dom_extensions.elementUnder(a, 'point', attributes=(('x', x), ('y', y))) # marks for o in self.marks: a.appendChild(o.get_package(doc)) # multiplicity if self.multiplicity != 1: a.setAttribute('multiplicity', str(self.multiplicity)) # valency a.setAttribute('valency', str(self.valency)) # number if self.number: a.setAttribute('number', self.number) a.setAttribute('show_number', data.booleans[int(self.show_number)]) # free_sites if self.free_sites: a.setAttribute('free_sites', str(self.free_sites)) return a
def add_bond( self, b, page): """adds bond item to page""" s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( b.line_color), stroke_width=Screen.px_to_cm( b.line_width)) style_name = self.get_appropriate_style_name( s) l_group = page # items to export line_items, items = b.get_exportable_items() # the export itself if b.type in 'nhd': for i in items: coords = map( Screen.px_to_cm, self.paper.coords( i)) self.create_oo_line( coords, page, style_name) elif b.type == 'o': for i in items: x, y, x2, y2 = map( Screen.px_to_cm, self.paper.coords( i)) size = Screen.px_to_cm( x2-x) dom_extensions.elementUnder( page, 'draw:ellipse', (( 'svg:x', '%fcm' % x), ( 'svg:y', '%fcm' % y), ( 'svg:width', '%fcm' % size), ( 'svg:height', '%fcm' % size), ( 'draw:style-name', style_name))) elif b.type == 'b': # bold bonds width is determined by the wedge_width s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( b.line_color), stroke_width=Screen.px_to_cm( b.wedge_width)) b_style_name = self.get_appropriate_style_name( s) for i in items: coords = map( Screen.px_to_cm, self.paper.coords( i)) self.create_oo_line( coords, page, b_style_name) elif b.type == 'w': s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( b.line_color), fill_color=self.paper.any_color_to_rgb_string( b.line_color), stroke_width=Screen.px_to_cm( b.line_width)) style_name = self.get_appropriate_style_name( s) for i in items: coords = map( Screen.px_to_cm, self.paper.coords( i)) point_array = [] for i in range( 0, len( coords), 2): point_array.append( (coords[i], coords[i+1])) self.create_oo_polygon( point_array, page, style_name) elif b.type == 'a': s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( b.line_color), stroke_width=Screen.px_to_cm( b.line_width)) style_name = self.get_appropriate_style_name( s) for i in items: coords = self.paper.coords( i) points = [] for j in range( 0, len( coords), 2): points.append( ( Screen.px_to_cm( coords[j]), Screen.px_to_cm(coords[j+1]))) self.create_oo_polyline( points, page, style_name) # line_items for i in line_items: coords = map( Screen.px_to_cm, self.paper.coords( i)) self.create_oo_line( coords, page, style_name)
def to_dom( self, doc): style = doc.createElement( 'style:style') dom_extensions.setAttributes( style, (('style:family', self.family), ('style:name', self.name))) dom_extensions.elementUnder( style, 'style:properties', (( 'fo:font-size', self.font_size), ( 'fo:font-family', self.font_family), ( 'fo:text-align', 'center'), ( 'fo:color', self.color))) return style
def _draw_rectangle( self, parent, coords, fill_color="#fff", stroke_color="#fff"): x, y, x2, y2 = coords dom_extensions.elementUnder( parent, 'rect', (( 'x', str( x)), ( 'y', str( y)), ( 'width', str( x2-x)), ( 'height', str( y2-y)), ( 'fill', fill_color), ( 'stroke', stroke_color)))
def create_oo_line( self, coords, page, gr_style_name): x1, y1, x2, y2 = coords dom_extensions.elementUnder( page, 'draw:line', (( 'svg:x1', '%fcm' % x1), ( 'svg:y1', '%fcm' % y1), ( 'svg:x2', '%fcm' % x2), ( 'svg:y2', '%fcm' % y2), ( 'draw:layer', 'layout'), ( 'draw:style-name', gr_style_name)))
def to_dom(self, doc): style = doc.createElement('style:style') dom_extensions.setAttributes(style, (('style:family', self.family), ('style:name', self.name))) dom_extensions.elementUnder(style, 'style:properties', (('fo:font-size', self.font_size), ('fo:font-family', self.font_family), ('fo:text-align', 'center'), ('fo:color', self.color))) return style
def _draw_rectangle(self, parent, coords, fill_color="#fff", stroke_color="#fff"): x, y, x2, y2 = coords dom_extensions.elementUnder( parent, 'rect', (('x', str(x)), ('y', str(y)), ('width', str(x2 - x)), ('height', str(y2 - y)), ('fill', fill_color), ('stroke', stroke_color)))
def to_dom( self, doc): style = doc.createElement( 'style:style') dom_extensions.setAttributes( style, (('style:family', self.family), ('style:name', self.name))) dom_extensions.elementUnder( style, 'style:paragraph-properties', (#( 'fo:font-size', self.font_size), #( 'fo:font-family', self.font_family), ( 'fo:text-align', 'center'), #( 'fo:color', self.color), ( 'fo:margin-left', "0cm"), ( 'fo:margin-right', "0cm"), ( 'fo:text-indent', "0cm"))) return style
def add_oval( self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( o.line_color), fill_color=self.paper.any_color_to_rgb_string( o.area_color), stroke_width=Screen.px_to_cm( o.line_width)) style_name = self.get_appropriate_style_name( s) x, y, x2, y2 = map( Screen.px_to_cm, o.coords) dom_extensions.elementUnder( page, 'draw:ellipse', (( 'svg:x', '%fcm' % x), ( 'svg:y', '%fcm' % y), ( 'svg:width', '%fcm' % (x2-x)), ( 'svg:height', '%fcm' % (y2-y)), ( 'draw:style-name', style_name)))
def get_package(self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" y = ['no', 'yes'] on_off = ['off', 'on'] a = doc.createElement('group') a.setAttribute('id', str(self.id)) a.setAttribute('pos', self.pos) # group type if self.group_type: a.setAttribute('group-type', self.group_type) else: raise ValueError("trying to save group without set group-type") if self.font_size != self.paper.standard.font_size \ or self.font_family != self.paper.standard.font_family \ or self.line_color != self.paper.standard.line_color: font = dom_extensions.elementUnder( a, 'font', attributes=(('size', str(self.font_size)), ('family', self.font_family))) if self.line_color != self.paper.standard.line_color: font.setAttribute('color', self.line_color) a.setAttribute('name', self.symbol) if self.area_color != self.paper.standard.area_color: a.setAttribute('background-color', self.area_color) # needed to support transparent handling of molecular size x, y, z = map(Screen.px_to_text_with_unit, self.get_xyz(real=1)) if self.z: dom_extensions.elementUnder(a, 'point', attributes=(('x', x), ('y', y), ('z', z))) else: dom_extensions.elementUnder(a, 'point', attributes=(('x', x), ('y', y))) # marks for o in self.marks: a.appendChild(o.get_package(doc)) # number if self.number: a.setAttribute('number', self.number) a.setAttribute('show_number', data.booleans[int(self.show_number)]) return a
def add_radical_mark( self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string( o.atom.line_color), fill_color=self.paper.any_color_to_rgb_string( o.atom.line_color), stroke_width=Screen.px_to_cm( 0.1)) style_name = self.get_appropriate_style_name( s) for i in o.items: x, y, x2, y2 = map( Screen.px_to_cm, self.paper.coords( i)) size = Screen.px_to_cm( o.size) dom_extensions.elementUnder( page, 'draw:ellipse', (( 'svg:x', '%fcm' % x), ( 'svg:y', '%fcm' % y), ( 'svg:width', '%fcm' % size), ( 'svg:height', '%fcm' % size), ( 'draw:style-name', style_name)))
def create_oo_text( self, ftext, coords, page, para_style_name, txt_style_name, gr_style_name): x, y, x2, y2 = coords box = dom_extensions.elementUnder( page, 'draw:text-box', (( 'svg:x', '%fcm' % x), ( 'svg:y', '%fcm' % y), ( 'svg:width', '%fcm' % (x2-x)), ( 'svg:height', '%fcm' % (y2-y)), ( 'draw:style-name', gr_style_name), ( 'draw:text-style-name', para_style_name))) text = dom_extensions.elementUnder( box, 'text:p', (('text:style-name', para_style_name),)) oo_text = dom_extensions.elementUnder( text, 'text:span', (('text:style-name', '%s' % txt_style_name),)) to_parse = dom.parseString( ftext).childNodes[0] self.ftext_dom_to_oo_dom( to_parse, oo_text)
def tranform_dom(self, dom): if dom.nodeName == "cdml": cdml = dom else: cdml = dom.getElementsByTagName("cdml")[0] if cdml.getElementsByTagName("standard"): return standard = dom_ext.elementUnder( cdml, "standard", (("font_family", "helvetica"), ("font_size", "12"), ("line_width", "1.0px")) ) dom_ext.elementUnder( standard, "bond", (("double-ratio", "1"), ("length", "1.0cm"), ("width", "6.0px"), ("wedge-width", "2.0px")) ) dom_ext.elementUnder(standard, "arrow", (("length", "1.6cm"),))
def get_package(self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" pls = doc.createElement('plus') pls.setAttribute('id', self.id) x, y = Screen.px_to_text_with_unit((self.x, self.y)) dom_extensions.elementUnder(pls, 'point', (('x', x), ('y', y))) pls.setAttribute('font_size', str(self.font_size)) if self.line_color != '#000': pls.setAttribute('color', self.line_color) if self.area_color != '#ffffff': pls.setAttribute('background-color', self.area_color) return pls
def add_radical_mark(self, o, page): s = graphics_style( stroke_color=self.paper.any_color_to_rgb_string(o.atom.line_color), fill_color=self.paper.any_color_to_rgb_string(o.atom.line_color), stroke_width=Screen.px_to_cm(0.1)) style_name = self.get_appropriate_style_name(s) for i in o.items: x, y, x2, y2 = map(Screen.px_to_cm, self.paper.coords(i)) size = Screen.px_to_cm(o.size) dom_extensions.elementUnder( page, 'draw:ellipse', (('svg:x', '%fcm' % x), ('svg:y', '%fcm' % y), ('svg:width', '%fcm' % size), ('svg:height', '%fcm' % size), ('draw:style-name', style_name)))
def mol_to_svg(self, mol, before=None, after=None): """before and after should be methods or functions that will take one argument - svg_out instance and do whatever it wants with it - usually adding something to the resulting DOM tree""" self.document = dom.Document() top = dom_extensions.elementUnder( self.document, "svg", attributes=(("xmlns", "http://www.w3.org/2000/svg"), ("version", "1.0"))) self.top = dom_extensions.elementUnder(top, "g", attributes=(("stroke", "#000"), ("stroke-width", "1.0"))) x1, y1, x2, y2 = None, None, None, None for v in mol.vertices: if x1 == None or x1 > v.x: x1 = v.x if x2 == None or x2 < v.x: x2 = v.x if y1 == None or y1 > v.y: y1 = v.y if y2 == None or y2 < v.y: y2 = v.y w = int(x2 - x1 + 2 * self.margin) h = int(y2 - y1 + 2 * self.margin) top.setAttribute("width", str(w)) top.setAttribute("height", str(h)) self.transformer = transform.transform() self.transformer.set_move(-x1 + self.margin, -y1 + self.margin) self.molecule = mol if before: before(self) for e in copy.copy(mol.edges): self._draw_edge(e) for v in mol.vertices: self._draw_vertex(v) if after: after(self) return self.document
def get_package( self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" yes_no = ['no','yes'] on_off = ['off','on'] a = doc.createElement('atom') a.setAttribute( 'id', str( self.id)) # charge if self.charge: a.setAttribute( "charge", str( self.charge)) #show attribute is set only when non default if (self.show and self.symbol=='C') or (not self.show and self.symbol!='C'): a.setAttribute('show', yes_no[ self.show]) if self.show: a.setAttribute( 'pos', self.pos) if self.font_size != self.paper.standard.font_size \ or self.font_family != self.paper.standard.font_family \ or self.line_color != self.paper.standard.line_color: font = dom_extensions.elementUnder( a, 'font', attributes=(('size', str( self.font_size)), ('family', self.font_family))) if self.line_color != self.paper.standard.line_color: font.setAttribute( 'color', self.line_color) a.setAttribute( 'name', self.symbol) if self.show_hydrogens: a.setAttribute('hydrogens', on_off[self.show_hydrogens]) if self.area_color != self.paper.standard.area_color: a.setAttribute( 'background-color', self.area_color) # needed to support transparent handling of molecular size x, y, z = map( Screen.px_to_text_with_unit, self.get_xyz( real=1)) if self.z: dom_extensions.elementUnder( a, 'point', attributes=(('x', x), ('y', y), ('z', z))) else: dom_extensions.elementUnder( a, 'point', attributes=(('x', x), ('y', y))) # marks for o in self.marks: a.appendChild( o.get_package( doc)) # multiplicity if self.multiplicity != 1: a.setAttribute( 'multiplicity', str( self.multiplicity)) # valency a.setAttribute( 'valency', str( self.valency)) # number if self.number: a.setAttribute( 'number', self.number) a.setAttribute( 'show_number', data.booleans[ int( self.show_number)]) # free_sites if self.free_sites: a.setAttribute( 'free_sites', str( self.free_sites)) return a
def get_svg_element( self, doc): e = doc.createElement( 'g') for i in self.items: x1, y1, x2, y2 = self.paper.coords( i) x = (x1 + x2)/2 y = (y1 + y2)/2 dom_extensions.elementUnder( e, 'ellipse', (( 'cx', str( x)), ( 'cy', str( y)), ( 'rx', str( self.size /2)), ( 'ry', str( self.size /2)), ( 'fill', self.line_color), ( 'stroke', self.line_color), ( 'stroke-width', '1'))) return e
def tranform_dom(self, dom): if dom.nodeName == 'cdml': cdml = dom else: cdml = dom.getElementsByTagName('cdml')[0] if cdml.getElementsByTagName('standard'): return standard = dom_ext.elementUnder(cdml, 'standard', (('font_family', 'helvetica'), ('font_size', '12'), ('line_width', '1.0px'))) dom_ext.elementUnder(standard, 'bond', (('double-ratio', '1'), ('length', '1.0cm'), ('width', '6.0px'), ('wedge-width', '2.0px'))) dom_ext.elementUnder(standard, 'arrow', (('length', '1.6cm'), ))
def get_package( self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" pls = doc.createElement('plus') pls.setAttribute( 'id', self.id) x, y = Screen.px_to_text_with_unit( (self.x, self.y)) dom_extensions.elementUnder( pls, 'point', (('x', x), ('y', y))) pls.setAttribute('font_size', str( self.font_size)) if self.line_color != '#000': pls.setAttribute( 'color', self.line_color) if self.area_color != '#ffffff': pls.setAttribute( 'background-color', self.area_color) return pls
def create_oo_bezier2(self, points, page, gr_style_name): points_txt = "" for (sx, sy, cxa, cya, cxb, cyb, ex, ey) in geometry.tkspline_to_cubic_bezier(points): if not points_txt: points_txt += "m %d %d c " % (1000 * (sx), 1000 * (sy)) points_txt += "%d %d %d %d %d %d " % (1000 * (cxa - sx), 1000 * (cya - sy), 1000 * (cxb - sx), 1000 * (cyb - sy), 1000 * (ex - sx), 1000 * (ey - sy)) print(points_txt) w = self.paper.get_paper_property('size_x') / 10.0 h = self.paper.get_paper_property('size_y') / 10.0 #wpx = Screen.cm_to_px( w) #hpx = Screen.cm_to_px( h) #print('svg:viewBox', '0 0 %d %d' % (wpx*1000,hpx*1000)) print('svg:viewBox', '0 0 %d %d' % (w * 1000, h * 1000)) line = dom_extensions.elementUnder( page, 'draw:path', (('svg:x', '0cm'), ('svg:y', '0cm'), ('svg:width', '%fcm' % w), ('svg:height', '%fcm' % h), ('svg:viewBox', '0 0 %d %d' % (w * 1000, h * 1000)), ('svg:d', points_txt), ('draw:layer', 'layout'), ('draw:style-name', gr_style_name)))
def create_oo_text( self, ftext, coords, page, para_style_name, txt_style_name, gr_style_name): x, y, x2, y2 = coords frame = dom_extensions.elementUnder( page, 'draw:frame', (( 'svg:x', '%fcm' % x), ( 'svg:y', '%fcm' % y), ( 'svg:width', '%fcm' % (x2-x)), ( 'svg:height', '%fcm' % (y2-y)), ( 'draw:layer', 'layout'), ( 'draw:style-name', gr_style_name), ( 'draw:text-style-name', para_style_name))) box = dom_extensions.elementUnder( frame, 'draw:text-box') text = dom_extensions.elementUnder( box, 'text:p', (('text:style-name', para_style_name),)) oo_text = dom_extensions.elementUnder( text, 'text:span', (('text:style-name', '%s' % txt_style_name),)) to_parse = dom.parseString( ftext).childNodes[0] self.ftext_dom_to_oo_dom( to_parse, oo_text)
def create_oo_bezier( self, points, page, gr_style_name): ps = reduce( operator.add, map( geometry.quadratic_beziere_to_polyline, geometry.tkspline_to_quadratic_bezier( points))) maxX, maxY, minX, minY = None,None,None,None for (x,y) in ps: if not maxX or x > maxX: maxX = x if not minX or x < minX: minX = x if not maxY or y > maxY: maxY = y if not minY or y < minY: minY = y points_txt = "" for (sx, sy, cxa, cya, cxb, cyb, ex, ey) in geometry.tkspline_to_cubic_bezier( points): if not points_txt: points_txt += "m %d %d c " % (1000*(sx-minX), 1000*(sy-minY)) points_txt += "%d %d %d %d %d %d " % (1000*(cxa-sx),1000*(cya-sy),1000*(cxb-sx),1000*(cyb-sy),1000*(ex-sx),1000*(ey-sy)) line = dom_extensions.elementUnder( page, 'draw:path', (( 'svg:x', '%fcm' % minX), ( 'svg:y', '%fcm' % minY), ( 'svg:width', '%fcm' % (maxX-minX)), ( 'svg:height', '%fcm' % (maxY-minY)), ( 'svg:viewBox', '0 0 %d %d' % ((maxX-minX)*1000,(maxY-minY)*1000)), ( 'svg:d', points_txt), ( 'draw:layer', 'layout'), ( 'draw:style-name', gr_style_name)))
def create_oo_bezier( self, points, page, gr_style_name): ps = [j for i in map(geometry.quadratic_beziere_to_polyline, geometry.tkspline_to_quadratic_bezier(points)) for j in i] maxX, maxY, minX, minY = None,None,None,None for (x,y) in ps: if not maxX or x > maxX: maxX = x if not minX or x < minX: minX = x if not maxY or y > maxY: maxY = y if not minY or y < minY: minY = y points_txt = "" for (sx, sy, cxa, cya, cxb, cyb, ex, ey) in geometry.tkspline_to_cubic_bezier( points): if not points_txt: points_txt += "m %d %d c " % (1000*(sx-minX), 1000*(sy-minY)) points_txt += "%d %d %d %d %d %d " % (1000*(cxa-sx),1000*(cya-sy),1000*(cxb-sx),1000*(cyb-sy),1000*(ex-sx),1000*(ey-sy)) line = dom_extensions.elementUnder( page, 'draw:path', (( 'svg:x', '%fcm' % minX), ( 'svg:y', '%fcm' % minY), ( 'svg:width', '%fcm' % (maxX-minX)), ( 'svg:height', '%fcm' % (maxY-minY)), ( 'svg:viewBox', '0 0 %d %d' % ((maxX-minX)*1000,(maxY-minY)*1000)), ( 'svg:d', points_txt), ( 'draw:layer', 'layout'), ( 'draw:style-name', gr_style_name)))
def get_package( self, doc): if not self.records or sum( map( len, self.records.values())) == 0: return None e = doc.createElement( 'external-data') for dclass in self.records: if self.records[ dclass]: ecls = dom_ext.elementUnder( e, "class", (("name", dclass),)) for obj in self.records[ dclass]: eobj = dom_ext.elementUnder( ecls, "object", (("ref", obj.id),("type", obj.object_type))) for cat in self.records[ dclass][ obj]: val = self.get_data( dclass, obj, cat) if hasattr( val, 'id'): val = val.id ecat = dom_ext.elementUnder( eobj, "value", (("category", cat), ("value", str( val)))) return e
def write_to_file( self, name): out = dom.Document() root = dom_ext.elementUnder( out, 'cml') for m in self.paper.molecules: mol = dom_ext.elementUnder( root, 'molecule') if m.id: mol.setAttribute( 'id', m.id) atoms = dom_ext.elementUnder( mol, 'atomArray') for a in m.atoms: atoms.appendChild( self.CML_atom( atom=a, scaling=self.scale).get_CML_dom( out)) bonds = dom_ext.elementUnder( mol, 'bondArray') for b in m.bonds: bonds.appendChild( self.CML_bond( bond=b).get_CML_dom( out)) dom_ext.safe_indent( root) with open(name, 'wb') as f: f.write(out.toxml('utf-8'))
def ftext_dom_to_oo_dom(self, ftext, oo_dom): if ftext.nodeValue: # style inherited from parents parents = dom_extensions.getParentNameList(ftext) font_weight, font_style, text_position = None, None, None if 'b' in parents: font_weight = 'bold' if 'i' in parents: font_style = 'italic' if 'sub' in parents: text_position = "sub 70%" if 'sup' in parents: text_position = "super 70%" if ftext.parentNode.nodeName == 'ftext': oo_dom.appendChild( oo_dom.ownerDocument.createTextNode(ftext.nodeValue)) else: st = span_style(font_style=font_style, font_weight=font_weight, text_position=text_position) element = dom_extensions.elementUnder( oo_dom, 'text:span', (('text:style-name', self.get_appropriate_style_name(st)), )) element.appendChild( oo_dom.ownerDocument.createTextNode(ftext.nodeValue)) else: for el in ftext.childNodes: self.ftext_dom_to_oo_dom(el, oo_dom)
def _create_parent(self, item, top): if self.group_items: parent = dom_extensions.elementUnder(top, "g") if 'svg_id' in item.properties_: parent.setAttribute("id", item.properties_['svg_id']) else: parent = self.top return parent
def mol_to_svg( self, mol, before=None, after=None): """before and after should be methods or functions that will take one argument - svg_out instance and do whatever it wants with it - usually adding something to the resulting DOM tree""" self.document = dom.Document() top = dom_extensions.elementUnder( self.document, "svg", attributes=(("xmlns", "http://www.w3.org/2000/svg"), ("version", "1.0"))) self.top = dom_extensions.elementUnder( top, "g", attributes=(("stroke", "#000"), ("stroke-width", "1.0"))) x1, y1, x2, y2 = None, None, None, None for v in mol.vertices: if x1 == None or x1 > v.x: x1 = v.x if x2 == None or x2 < v.x: x2 = v.x if y1 == None or y1 > v.y: y1 = v.y if y2 == None or y2 < v.y: y2 = v.y w = int( x2 - x1 + 2*self.margin) h = int( y2 - y1 + 2*self.margin) top.setAttribute( "width", str( w)) top.setAttribute( "height", str( h)) self.transformer = transform.transform() self.transformer.set_move( -x1+self.margin, -y1+self.margin) self.molecule = mol if before: before( self) for e in copy.copy( mol.edges): self._draw_edge( e) for v in mol.vertices: self._draw_vertex( v) if after: after( self) return self.document
def _draw_line( self, parent, start, end, line_width=1, capstyle=""): x1, y1 = start x2, y2 = end line = dom_extensions.elementUnder( parent, 'line', (( 'x1', str( x1)), ( 'y1', str( y1)), ( 'x2', str( x2)), ( 'y2', str( y2))))
def _create_parent( self, item, top): if self.group_items: parent = dom_extensions.elementUnder( top, "g") if 'svg_id' in item.properties_: parent.setAttribute( "id", item.properties_['svg_id']) else: parent = self.top return parent
def to_dom( self, doc): style = doc.createElement( 'style:style') dom_extensions.setAttributes( style, (('style:family', self.family), ('style:name', self.name))) prop = dom_extensions.elementUnder( style, 'style:properties', (( 'fo:font-size', self.font_size), ( 'fo:font-family', self.font_family), ( 'fo:font-style', self.font_style), ( 'fo:font-weight', self.font_weight))) return style
def to_dom( self, doc): style = doc.createElement( 'style:style') dom_extensions.setAttributes( style, (('style:family', self.family), ('style:name', self.name))) prop = dom_extensions.elementUnder( style, 'style:text-properties', (( 'fo:font-size', self.font_size), ( 'fo:font-family', self.font_family), ( 'fo:font-style', self.font_style), ( 'fo:font-weight', self.font_weight))) return style
def tranform_dom( self, dom): if dom.nodeName == 'cdml': cdml = dom else: cdml = dom.getElementsByTagName('cdml')[0] if cdml.getElementsByTagName( 'standard'): return standard = dom_ext.elementUnder( cdml, 'standard', (('font_family','helvetica'), ('font_size','12'), ('line_width','1.0px'))) dom_ext.elementUnder( standard, 'bond', (('double-ratio','1'), ('length','1.0cm'), ('width','6.0px'), ('wedge-width','2.0px'))) dom_ext.elementUnder( standard, 'arrow', (('length','1.6cm'),))
def get_package( self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" a = doc.createElement('text') a.setAttribute( 'id', self.id) if self.area_color != '': a.setAttribute( 'background-color', self.area_color) if self.font_size != self.paper.standard.font_size \ or self.font_family != self.paper.standard.font_family \ or self.line_color != self.paper.standard.line_color: font = dom_extensions.elementUnder( a, 'font', attributes=(('size', str( self.font_size)), ('family', self.font_family))) if self.line_color != self.paper.standard.line_color: font.setAttribute( 'color', self.line_color) x, y = Screen.px_to_text_with_unit( (self.x, self.y)) dom_extensions.elementUnder( a, 'point', attributes=(('x', x),('y', y))) ftext = dom_extensions.elementUnder( a, 'ftext') ftext.appendChild( doc.createTextNode( self.xml_ftext)) return a
def add_plus(self, p): """adds plus item to SVG document""" item = p.item x1, y1 = p.get_xy() x, y, x2, y2 = self.paper.bbox(item) if p.area_color: # it is not needed to export the rectangle in case its transparent dom_extensions.elementUnder(self.group, 'rect', (('x', self.convert(x)), ('y', self.convert(y)), ('width', self.convert(x2 - x)), ('height', self.convert(y2 - y)), ('fill', self.cc(p.area_color)), ('stroke', self.cc(p.area_color)))) y1 += (y2 - y) / 4.0 text = dom_extensions.textOnlyElementUnder( self.group, 'text', '+', (('font-size', "%d%s" % (p.font_size, pt_or_px)), ('font-family', p.font_family), ("x", self.convert(x)), ("y", self.convert(round(y1))), ('fill', self.cc(p.line_color))))
def add_rect( self, o): x1, y1, x2, y2 = o.coords el = dom_extensions.elementUnder( self.group, 'rect', (( 'x', self.convert( x1)), ( 'y', self.convert( y1)), ( 'width', self.convert( x2-x1)), ( 'height', self.convert( y2-y1)), ( 'stroke-width', str( o.line_width)))) el.setAttribute( 'fill', self.cc( o.area_color)) el.setAttribute( 'stroke', self.cc( o.line_color))
def add_polygon(self, o): ps = '' for (x, y) in [p.get_xy() for p in o.points]: ps += '%.2f,%.2f ' % (x, y) poly = dom_extensions.elementUnder( self.group, 'polygon', (('points', ps), ('stroke-width', str(o.line_width)), ('fill-rule', 'evenodd'))) poly.setAttribute('fill', self.cc(o.area_color)) poly.setAttribute('stroke', self.cc(o.line_color))
def add_polygon( self, o): ps = '' for (x,y) in [p.get_xy() for p in o.points]: ps += '%.2f,%.2f ' % (x,y) poly = dom_extensions.elementUnder( self.group, 'polygon', (( 'points', ps), ( 'stroke-width', str( o.line_width)), ( 'fill-rule', 'evenodd'))) poly.setAttribute( 'fill', self.cc( o.area_color)) poly.setAttribute( 'stroke', self.cc( o.line_color))
def add_rect(self, o): x1, y1, x2, y2 = o.coords el = dom_extensions.elementUnder(self.group, 'rect', (('x', self.convert(x1)), ('y', self.convert(y1)), ('width', self.convert(x2 - x1)), ('height', self.convert(y2 - y1)), ('stroke-width', str(o.line_width)))) el.setAttribute('fill', self.cc(o.area_color)) el.setAttribute('stroke', self.cc(o.line_color))
def add_oval( self, o): x1, y1, x2, y2 = o.coords el = dom_extensions.elementUnder( self.group, 'ellipse', (( 'cx', self.convert( (x2+x1)/2)), ( 'cy', self.convert( (y2+y1)/2)), ( 'rx', self.convert( (x2-x1)/2)), ( 'ry', self.convert( (y2-y1)/2)), ( 'stroke-width', str( o.line_width)))) el.setAttribute( 'fill', self.cc( o.area_color)) el.setAttribute( 'stroke', self.cc( o.line_color))
def add_oval(self, o): x1, y1, x2, y2 = o.coords el = dom_extensions.elementUnder( self.group, 'ellipse', (('cx', self.convert( (x2 + x1) / 2)), ('cy', self.convert( (y2 + y1) / 2)), ('rx', self.convert( (x2 - x1) / 2)), ('ry', self.convert((y2 - y1) / 2)), ('stroke-width', str(o.line_width)))) el.setAttribute('fill', self.cc(o.area_color)) el.setAttribute('stroke', self.cc(o.line_color))
def get_package( self, doc): """returns a DOM element describing the object in CDML, doc is the parent document which is used for element creation (the returned element is not inserted into the document)""" y = ['no','yes'] on_off = ['off','on'] a = doc.createElement('group') a.setAttribute( 'id', str( self.id)) a.setAttribute( 'pos', self.pos) # group type if self.group_type: a.setAttribute( 'group-type', self.group_type) else: raise ValueError, "trying to save group without set group-type" if self.font_size != self.paper.standard.font_size \ or self.font_family != self.paper.standard.font_family \ or self.line_color != self.paper.standard.line_color: font = dom_extensions.elementUnder( a, 'font', attributes=(('size', str( self.font_size)), ('family', self.font_family))) if self.line_color != self.paper.standard.line_color: font.setAttribute( 'color', self.line_color) a.setAttribute( 'name', self.symbol) if self.area_color != self.paper.standard.area_color: a.setAttribute( 'background-color', self.area_color) # needed to support transparent handling of molecular size x, y, z = map( Screen.px_to_text_with_unit, self.get_xyz( real=1)) if self.z: dom_extensions.elementUnder( a, 'point', attributes=(('x', x), ('y', y), ('z', z))) else: dom_extensions.elementUnder( a, 'point', attributes=(('x', x), ('y', y))) # marks for o in self.marks: a.appendChild( o.get_package( doc)) # number if self.number: a.setAttribute( 'number', self.number) a.setAttribute( 'show_number', data.booleans[ int( self.show_number)]) return a
def add_plus( self, p): """adds plus item to SVG document""" item = p.item x1, y1 = p.get_xy() x, y, x2, y2 = self.paper.bbox( item) if p.area_color: # it is not needed to export the rectangle in case its transparent dom_extensions.elementUnder( self.group, 'rect', (( 'x', self.convert( x)), ( 'y', self.convert( y)), ( 'width', self.convert( x2-x)), ( 'height', self.convert( y2-y)), ( 'fill', self.cc( p.area_color)), ( 'stroke', self.cc( p.area_color)))) y1 += (y2-y)/4.0 text = dom_extensions.textOnlyElementUnder( self.group, 'text', '+', (('font-size', "%d%s" % (p.font_size, pt_or_px)), ('font-family', p.font_family), ( "x", self.convert( x)), ( "y", self.convert( round( y1))), ( 'fill', self.cc( p.line_color))))