Пример #1
0
 def _where_to_draw_from_and_to( self, b):
   def fix_bbox( a):
     x, y = a.x, a.y
     data = self._vertex_to_bbox.get( a, None)
     if data:
       (ox, oy), bbox = data
       dx = x - ox
       dy = y - oy
       bbox = [bbox[0]+dx,bbox[1]+dy,bbox[2]+dx,bbox[3]+dy]
       return bbox
     return None
   # at first check if the bboxes are not overlapping
   atom1, atom2 = b.vertices
   x1, y1 = atom1.x, atom1.y
   x2, y2 = atom2.x, atom2.y
   bbox1 = fix_bbox( atom1)
   bbox2 = fix_bbox( atom2)
   if bbox1 and bbox2 and geometry.do_rectangles_intersect( bbox1, bbox2):
     return None
   # then we continue with computation
   if bbox1:
     x1, y1 = geometry.intersection_of_line_and_rect( (x1,y1,x2,y2), bbox1, round_edges=0)
   if bbox2:
     x2, y2 = geometry.intersection_of_line_and_rect( (x1,y1,x2,y2), bbox2, round_edges=0)
   if geometry.point_distance( x1, y1, x2, y2) <= 1.0:
     return None
   else:
     return (x1, y1, x2, y2)
Пример #2
0
    def _where_to_draw_from_and_to(self, b):
        def fix_bbox(a):
            x, y = a.x, a.y
            data = self._vertex_to_bbox.get(a, None)
            if data:
                (ox, oy), bbox = data
                dx = x - ox
                dy = y - oy
                bbox = [bbox[0] + dx, bbox[1] + dy, bbox[2] + dx, bbox[3] + dy]
                return bbox
            return None

        # at first check if the bboxes are not overlapping
        atom1, atom2 = b.vertices
        x1, y1 = atom1.x, atom1.y
        x2, y2 = atom2.x, atom2.y
        bbox1 = fix_bbox(atom1)
        bbox2 = fix_bbox(atom2)
        if bbox1 and bbox2 and geometry.do_rectangles_intersect(bbox1, bbox2):
            return None
        # then we continue with computation
        if bbox1:
            x1, y1 = geometry.intersection_of_line_and_rect((x1, y1, x2, y2),
                                                            bbox1,
                                                            round_edges=0)
        if bbox2:
            x2, y2 = geometry.intersection_of_line_and_rect((x1, y1, x2, y2),
                                                            bbox2,
                                                            round_edges=0)
        if geometry.point_distance(x1, y1, x2, y2) <= 1.0:
            return None
        else:
            return (x1, y1, x2, y2)
Пример #3
0
  def _draw_vertex( self, v):
    pos = sum( [(a.x < v.x) and -1 or 1 for a in v.neighbors if abs(a.x-v.x)>0.2])
    if 'show_symbol' in v.properties_:
      show_symbol = v.properties_['show_symbol']
    else:
      show_symbol = (v.symbol != "C" or v.degree == 0 or self.show_carbon_symbol)
    if show_symbol:
      x = v.x
      y = v.y
      text = v.symbol
      hs = ""
      if self.show_hydrogens_on_hetero or v.properties_.get( 'show_hydrogens', False):
        if v.free_valency == 1:
          hs = "H"
        elif v.free_valency > 1:
          hs = "H<sub>%d</sub>" % v.free_valency
      if not hs:
        pos = -1
      if pos <= 0:
        text += hs
      else:
        text = hs + text
      # charge
      charge = ""
      if v.charge == 1:
        charge = "<sup>+</sup>"
      elif v.charge == -1:
        charge = "<sup>&#x2212;</sup>"
      elif v.charge > 1:
        charge = "<sup>%d+</sup>" % v.charge
      elif v.charge < -1:
        charge = "<sup>%d&#x2212;</sup>" % abs( v.charge)
      if charge:
        if self._is_there_place( v, v.x+3, v.y-2) or v.charge < 0:
          # we place negative charge regardless of available place
          # otherwise minus might be mistaken for a bond
          text += charge
          charge = ""
      
      # coloring
      if self.color_atoms:
        color = self.atom_colors.get( v.symbol, (0,0,0))
      else:
        color = (0,0,0)
      center_letter = pos <= 0 and 'first' or 'last'
      bbox = self._draw_text( (x,y), text, center_letter=center_letter, color=color)
      self._vertex_to_bbox[v] = ((x,y), geometry.expand_rectangle( bbox, self.space_around_atom))

      # sometimes charge is done here, if it wasn't done before
      if charge:
        assert v.charge > 0
        # if charge was not dealt with we change its appearance from 2+ to ++
        charge = v.charge * "+"
        if self._is_there_place( v, v.x, v.y-10):
          angle = 1.5*math.pi
        elif self._is_there_place( v, v.x, v.y+10):
          angle = 0.5*math.pi
        else:
          angle = self._find_place_around_atom( v)
        self.context.set_font_size( self.subscript_size_ratio * self.font_size)
        xbearing, ybearing, width, height, x_advance, y_advance = self.context.text_extents( charge)
        x0 = v.x + 40*math.cos( angle)
        y0 = v.y + 40*math.sin( angle)
        line = (v.x,v.y,x0,y0)
        charge_bbox = [x0-0.5*width,y0-0.5*height,x0+0.5*width,y0+0.5*height]
        x1, y1 = geometry.intersection_of_line_and_rect( line, bbox, round_edges=0)
        x2, y2 = geometry.intersection_of_line_and_rect( line, charge_bbox, round_edges=0)
        x2, y2 = geometry.elongate_line( x1,y1,x2,y2, -self.space_around_atom)
        x = x0 + x1 - x2
        y = y0 + y1 - y2
        # draw
        self.context.set_source_rgb( *color)
        self.context.move_to( round( x-xbearing-0.5*width), round( y+0.5*height))
        self.context.show_text( charge)
Пример #4
0
    def _draw_vertex(self, v):
        pos = sum([(a.x < v.x) and -1 or 1 for a in v.neighbors
                   if abs(a.x - v.x) > 0.2])
        if 'show_symbol' in v.properties_:
            show_symbol = v.properties_['show_symbol']
        else:
            show_symbol = (v.symbol != "C" or v.degree == 0
                           or self.show_carbon_symbol)
        if show_symbol:
            x = v.x
            y = v.y
            text = v.symbol
            hs = ""
            if self.show_hydrogens_on_hetero or v.properties_.get(
                    'show_hydrogens', False):
                if v.free_valency == 1:
                    hs = "H"
                elif v.free_valency > 1:
                    hs = "H<sub>%d</sub>" % v.free_valency
            if not hs:
                pos = -1
            if pos <= 0:
                text += hs
            else:
                text = hs + text
            # charge
            charge = ""
            if v.charge == 1:
                charge = "<sup>+</sup>"
            elif v.charge == -1:
                charge = "<sup>&#x2212;</sup>"
            elif v.charge > 1:
                charge = "<sup>%d+</sup>" % v.charge
            elif v.charge < -1:
                charge = "<sup>%d&#x2212;</sup>" % abs(v.charge)
            if charge:
                if self._is_there_place(v, v.x + 3, v.y - 2) or v.charge < 0:
                    # we place negative charge regardless of available place
                    # otherwise minus might be mistaken for a bond
                    text += charge
                    charge = ""

            # coloring
            if self.color_atoms:
                color = self.atom_colors.get(v.symbol, (0, 0, 0))
            else:
                color = (0, 0, 0)
            center_letter = pos <= 0 and 'first' or 'last'
            bbox = self._draw_text((x, y),
                                   text,
                                   center_letter=center_letter,
                                   color=color)
            self._vertex_to_bbox[v] = ((x, y),
                                       geometry.expand_rectangle(
                                           bbox, self.space_around_atom))

            # sometimes charge is done here, if it wasn't done before
            if charge:
                assert v.charge > 0
                # if charge was not dealt with we change its appearance from 2+ to ++
                charge = v.charge * "+"
                if self._is_there_place(v, v.x, v.y - 10):
                    angle = 1.5 * math.pi
                elif self._is_there_place(v, v.x, v.y + 10):
                    angle = 0.5 * math.pi
                else:
                    angle = self._find_place_around_atom(v)
                self.context.set_font_size(self.subscript_size_ratio *
                                           self.font_size)
                xbearing, ybearing, width, height, x_advance, y_advance = self.context.text_extents(
                    charge)
                x0 = v.x + 40 * math.cos(angle)
                y0 = v.y + 40 * math.sin(angle)
                line = (v.x, v.y, x0, y0)
                charge_bbox = [
                    x0 - 0.5 * width, y0 - 0.5 * height, x0 + 0.5 * width,
                    y0 + 0.5 * height
                ]
                x1, y1 = geometry.intersection_of_line_and_rect(line,
                                                                bbox,
                                                                round_edges=0)
                x2, y2 = geometry.intersection_of_line_and_rect(line,
                                                                charge_bbox,
                                                                round_edges=0)
                x2, y2 = geometry.elongate_line(x1, y1, x2, y2,
                                                -self.space_around_atom)
                x = x0 + x1 - x2
                y = y0 + y1 - y2
                # draw
                self.context.set_source_rgb(*color)
                self.context.move_to(round(x - xbearing - 0.5 * width),
                                     round(y + 0.5 * height))
                self.context.show_text(charge)