Exemplo n.º 1
0
/* Actually draws a page.  If page is NULL, uses the first open page. */
static void
export_draw_page (PAGE *page)
{
  const GList *contents;
  GList *iter;
  cairo_t *cr;

  cr = eda_renderer_get_cairo_context (renderer);

  if (page == NULL) {
    const GList *pages = geda_list_get_glist (toplevel->pages);
    g_assert (pages != NULL && pages->data != NULL);
    page = (PAGE *) pages->data;
  }

  /* Draw background */
  eda_cairo_set_source_color (cr, OUTPUT_BACKGROUND_COLOR,
                              eda_renderer_get_color_map (renderer));
  cairo_paint (cr);

  /* Draw objects & cues */
  contents = s_page_objects (page);
  for (iter = (GList *) contents; iter != NULL; iter = g_list_next (iter))
    eda_renderer_draw (renderer, (OBJECT *) iter->data);
  for (iter = (GList *) contents; iter != NULL; iter = g_list_next (iter))
    eda_renderer_draw_cues (renderer, (OBJECT *) iter->data);
}
Exemplo n.º 2
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void
o_move_draw_rubber (GschemToplevel *w_current,
                    EdaRenderer *renderer)
{
  GList *s_iter;
  int diff_x, diff_y;
  gboolean net_rubber_band_mode;

  g_return_if_fail (w_current != NULL);

  o_place_draw_rubber (w_current, renderer);

  net_rubber_band_mode = gschem_options_get_net_rubber_band_mode (w_current->options);

  if (!net_rubber_band_mode)
    return;

  diff_x = w_current->second_wx - w_current->first_wx;
  diff_y = w_current->second_wy - w_current->first_wy;

  for (s_iter = w_current->stretch_list;
       s_iter != NULL; s_iter = g_list_next (s_iter)) {
    STRETCH *s_current = s_iter->data;
    OBJECT *object = s_current->object;
    int whichone = s_current->whichone;

    /* We can only stretch nets and buses */
    switch (object->type) {
      case OBJ_NET:
      case OBJ_BUS:
        break;
    default:
      continue;
    }

    g_return_if_fail ((whichone >= 0) && (whichone < 2));

    /* Apply stretch */
    object->line->x[whichone] += diff_x;
    object->line->y[whichone] += diff_y;

    /* Draw stretched object */
    eda_renderer_draw (renderer, object);

    /* Restore original geometry */
    object->line->x[whichone] -= diff_x;
    object->line->y[whichone] -= diff_y;
  }
}
Exemplo n.º 3
0
/*! \brief Draw path from GschemToplevel object.
 *  \par Function Description
 *  This function draws a path with an exclusive or function over the sheet.
 *  The color of the box is <B>SELECT_COLOR</B>. The path is
 *  described by the two points (<B>w_current->first_wx</B>,
 *  <B>w_current->first_wy</B>) and (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>).
 *
 *  \param [in] w_current  The GschemToplevel object.
 */
void
o_path_draw_rubber_grips (GschemToplevel *w_current, EdaRenderer *renderer)
{
  OBJECT object;

  /* Setup a fake object to pass the drawing routine */
  memset (&object, 0, sizeof (OBJECT));
  object.type = OBJ_PATH;
  object.color = SELECT_COLOR;
  object.line_width = 0; /* clamped to 1 pixel in circle_path */
  object.path = path_copy_modify (w_current->which_object->path, 0, 0,
                                  w_current->second_wx,
                                  w_current->second_wy, w_current->which_grip);

  eda_renderer_draw (renderer, &object);
  g_free (object.path->sections);
  g_free (object.path);
}
Exemplo n.º 4
0
/*! \brief Draw path creation preview.
 * \par Function Description
 * Draw a preview of the path currently being drawn, including a
 * helper line showing the control point of the node being drawn (if
 * applicable).
 */
void
o_path_draw_rubber (GschemToplevel *w_current, EdaRenderer *renderer)
{
  OBJECT object;
  int added_sections = 0;

  /* Draw a helper for when we're dragging a control point */
  if (w_current->first_wx != w_current->second_wx
      || w_current->first_wy != w_current->second_wy) {
    double wwidth = 0;
    cairo_t *cr = eda_renderer_get_cairo_context (renderer);
    GArray *color_map = eda_renderer_get_color_map (renderer);
    int flags = eda_renderer_get_cairo_flags (renderer);

    eda_cairo_line (cr, flags, END_NONE, wwidth,
                    w_current->first_wx, w_current->first_wy,
                    w_current->second_wx, w_current->second_wy);

    eda_cairo_set_source_color (cr, SELECT_COLOR, color_map);
    eda_cairo_stroke (cr, flags, TYPE_SOLID, END_NONE, wwidth, -1, -1);
  }
  /* Now draw the rest of the path */

  /* Calculate any new sections */
  added_sections = path_next_sections (w_current);

  /* Setup a fake object to pass the drawing routine */
  memset (&object, 0, sizeof (OBJECT));
  object.type = OBJ_PATH;
  object.color = SELECT_COLOR;
  object.line_width = 0; /* clamped to 1 pixel in circle_path */
  object.path = w_current->temp_path;

  eda_renderer_draw (renderer, &object);

  /* Throw away the added sections again */
  w_current->temp_path->num_sections -= added_sections;
}
Exemplo n.º 5
0
/*! \brief Draw a page.
 * \par Function Description
 * Draws the \a page on the Cairo context \a cr, which should have
 * dimensions \a cr_width and \a cr_height.  If the Pango context \a
 * pc is provided, it is used for rendering of text.  The parameter \a
 * is_color controls whether to enable color printing, and \a
 * is_raster should be set if drawing to a raster surface such as an
 * image.
 *
 * \param toplevel A #TOPLEVEL structure.
 * \param page     The #PAGE to be rendered.
 * \param cr       The Cairo context to render to.
 * \param pc       A Pango context for text rendering, or NULL.
 * \param cr_width The width of the drawing area.
 * \param cr_height The height of the drawing area.
 * \param is_color TRUE if drawing should be in color; FALSE otherwise.
 * \param is_raster TRUE if drawing to a raster image surface; FALSE otherwise.
 */
static void
x_print_draw_page (TOPLEVEL *toplevel, PAGE *page,
                   cairo_t *cr, PangoContext *pc,
                   double cr_width, double cr_height,
                   gboolean is_color, gboolean is_raster)
{
  EdaRenderer *renderer;
  cairo_matrix_t mtx;
  GArray *color_map;
  int status, wx_min, wy_min, wx_max, wy_max;
  double w_width, w_height, scale;
  GList *iter;

  /* First, calculate a transformation matrix for the cairo
   * context. We want to center the extents of the page in the
   * available page area. */
  status = world_get_object_glist_bounds (toplevel, s_page_objects (page),
                                          &wx_min, &wy_min, &wx_max, &wy_max);
  /* If there are no printable objects, draw nothing. */
  if (!status) return;

  w_width = wx_max - wx_min;
  w_height = wy_max - wy_min;
  scale = fmin (cr_width / w_width, cr_height / w_height);
  cairo_matrix_init (&mtx,
                     scale, 0,
                     0, -scale,
                     - (wx_min + 0.5*w_width) * scale + 0.5*cr_width,
                     (wy_min + 0.5*w_height) * scale + 0.5*cr_height);

  /* Second, build the color map.  If no color printing is desired,
   * transform the print color map into a black-and-white color map by
   * making the background color transparent and replacing all other
   * enabled colors with solid black. */
  color_map = g_array_sized_new (FALSE, FALSE, sizeof(GedaColor), MAX_COLORS);
  color_map = g_array_append_vals (color_map, print_colors, MAX_COLORS);
  if (!is_color) {
    int i;
    for (i = 0; i < MAX_COLORS; i++) {
      GedaColor *c = &g_array_index (color_map, GedaColor, i);
      if (!c->enabled) continue;

      /* Disable background color & fully-transparent colors */
      if (c->a == 0 || i == BACKGROUND_COLOR) {
        c->enabled = FALSE;
        continue;
      }

      /* Set any remaining colors solid black */
      c->r = 0;
      c->g = 0;
      c->b = 0;
      c->a = ~0;
    }
  }

  /* Thirdly, create and initialise a renderer */
  renderer = EDA_RENDERER (g_object_new (EDA_TYPE_RENDERER,
                                         "cairo-context", cr,
                                         "pango-context", pc,
                                         "color-map", color_map,
                                         "render-flags", is_raster ? EDA_RENDERER_FLAG_HINTING : 0,
                                         NULL));

  /* Finally, actually do drawing */
  cairo_save (cr);
  cairo_transform (cr, &mtx);

  /* Draw background */
  eda_cairo_set_source_color (cr, BACKGROUND_COLOR, color_map);
  cairo_paint (cr);

  /* Draw all objects and cues */
  for (iter = (GList *) s_page_objects (page);
       iter != NULL;
       iter = g_list_next (iter)) {
    eda_renderer_draw (renderer, (OBJECT *) iter->data);
  }
  for (iter = (GList *) s_page_objects (page);
       iter != NULL;
       iter = g_list_next (iter)) {
    eda_renderer_draw_cues (renderer, (OBJECT *) iter->data);
  }

  cairo_restore (cr);

  g_object_unref (renderer);
  g_array_free (color_map, TRUE);
}
Exemplo n.º 6
0
/*! \brief Draw a bounding box or outline for OBJECT placement
 *  \par Function Description
 *  This function draws either the OBJECTS in the place list
 *  or a rectangle around their bounding box, depending upon the
 *  currently selected w_current->actionfeedback_mode. This takes the
 *  value BOUNDINGBOX or OUTLINE.
 *
 * The function applies manhatten mode constraints to the coordinates
 * before drawing if the CONTROL key is recording as being pressed in
 * the w_current structure.
 *
 *  \param w_current   GschemToplevel which we're drawing for.
 *  \param renderer    Renderer to use for drawing.
 */
void
o_place_draw_rubber (GschemToplevel *w_current, EdaRenderer *renderer)
{
  int diff_x, diff_y;
  cairo_t *cr = eda_renderer_get_cairo_context (renderer);

  g_return_if_fail (w_current != NULL);

  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);
  g_return_if_fail (page->place_list != NULL);

  /* Don't worry about the previous drawing method and movement
   * constraints, use with the current settings */
  w_current->last_drawb_mode = w_current->actionfeedback_mode;
  w_current->drawbounding_action_mode = (w_current->CONTROLKEY &&
                                         ! ((w_current->event_state == PASTEMODE) ||
                                            (w_current->event_state == COMPMODE) ||
                                            (w_current->event_state == TEXTMODE)))
                                        ? CONSTRAINED : FREE;

  /* Calculate delta of X-Y positions from buffer's origin */
  diff_x = w_current->second_wx - w_current->first_wx;
  diff_y = w_current->second_wy - w_current->first_wy;

  /* Adjust the coordinates according to the movement constraints */
  if (w_current->drawbounding_action_mode == CONSTRAINED ) {
    if (abs(diff_x) >= abs(diff_y)) {
      w_current->second_wy = w_current->first_wy;
      diff_y = 0;
    } else {
      w_current->second_wx = w_current->first_wx;
      diff_x = 0;
    }
  }

  /* Translate the cairo context to the required offset before drawing. */
  cairo_save (cr);
  cairo_translate (cr, diff_x, diff_y);

  /* Draw with the appropriate mode */
  if (w_current->last_drawb_mode == BOUNDINGBOX) {
    GArray *map = eda_renderer_get_color_map (renderer);
    int flags = eda_renderer_get_cairo_flags (renderer);
    int left, top, bottom, right;

    /* Find the bounds of the drawing to be done */
    world_get_object_glist_bounds (page->toplevel,
                                   page->place_list,
                                   &left, &top, &right, &bottom);

    /* Draw box outline */
    eda_cairo_box (cr, flags, 0, left, top, right, bottom);
    eda_cairo_set_source_color (cr, BOUNDINGBOX_COLOR, map);
    eda_cairo_stroke (cr, flags, TYPE_SOLID, END_NONE, 0, -1, -1);
  } else {
    GList *iter;
    for (iter = page->place_list; iter != NULL;
         iter = g_list_next (iter)) {
      eda_renderer_draw (renderer, (OBJECT *) iter->data);
    }
  }
  cairo_restore (cr);
}