GtCanvas* gt_canvas_cairo_file_new(GtStyle *style,
                                   GtGraphicsOutType output_type,
                                   GtUword width, GtUword height,
                                   GtImageInfo *image_info,
                                   GtError *err)
{
  GtCanvas *canvas;
  GtColor bgcolor = {1.0, 1.0, 1.0, 1.0};
  GtCanvasCairoFile *ccf;
  GtStyleQueryStatus status;
  double margins = 10.0;
  gt_assert(style && width > 0 && height > 0);

  status = gt_style_get_color(style, "format", "background_color", &bgcolor,
                              NULL, err);
  switch (status) {
    case GT_STYLE_QUERY_ERROR:
      return NULL;
    case GT_STYLE_QUERY_NOT_SET:
      bgcolor.red = bgcolor.green = bgcolor.blue = bgcolor.alpha = 1.0;
      break;
    default:
      break;
    }
  if (gt_style_get_num(style,
                       "format", "margins", &margins,
                       NULL, err) == GT_STYLE_QUERY_ERROR) {
    return NULL;
  }

  canvas = gt_canvas_create(gt_canvas_cairo_file_class());
  canvas->pvt->g = gt_graphics_cairo_new(output_type, width, height);
  (void) gt_graphics_set_background_color(canvas->pvt->g, bgcolor);
  (void) gt_graphics_set_margins(canvas->pvt->g, margins, 0);
  canvas->pvt->margins = margins;
  if (image_info)
    gt_image_info_set_height(image_info, height);
  canvas->pvt->sty = style;
  canvas->pvt->y += 0.5;
  canvas->pvt->ii = image_info;
  canvas->pvt->width = width;
  canvas->pvt->height = height;
  canvas->pvt->bt = NULL;
  ccf = canvas_cairo_file_cast(canvas);
  ccf->type = output_type;
  return canvas;
}
Пример #2
0
int gt_canvas_cairo_visit_custom_track(GtCanvas *canvas,
                                       GtCustomTrack *ct,
                                       GtError *err)
{
  bool show_track_captions = true;
  double space;
  int had_err = 0;
  GtColor color;
  gt_assert(canvas && ct);

  if (gt_style_get_bool(canvas->pvt->sty,
                        "format", "show_track_captions",
                        &show_track_captions,
                        NULL, err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }
  if (gt_style_get_color(canvas->pvt->sty, "format", "track_title_color",
                         &color, NULL, err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }

  if (show_track_captions)
  {
    double theight = gt_graphics_get_text_height(canvas->pvt->g),
           captionspace = CAPTION_BAR_SPACE_DEFAULT;
    if (gt_style_get_num(canvas->pvt->sty,
                         "format", "track_caption_font_size",
                         &theight, NULL, err) == GT_STYLE_QUERY_ERROR) {
      return -1;
    }
    /* draw track title */
    gt_graphics_set_font(canvas->pvt->g,
                           "Sans",
                           SLANT_NORMAL,
                           WEIGHT_NORMAL,
                           theight);
    gt_graphics_draw_colored_text(canvas->pvt->g,
                                  canvas->pvt->margins,
                                  canvas->pvt->y,
                                  color,
                                  gt_custom_track_get_title(ct));
    if (gt_style_get_num(canvas->pvt->sty,
                         "format", "track_caption_space",
                         &captionspace, NULL, err) == GT_STYLE_QUERY_ERROR) {
      return -1;
    }
    canvas->pvt->y += theight + captionspace;
  }

  /* call rendering function */
  had_err = gt_custom_track_render(ct,
                                   canvas->pvt->g,
                                   canvas->pvt->y,
                                   canvas->pvt->viewrange,
                                   canvas->pvt->sty,
                                   err);
  canvas->pvt->y += gt_custom_track_get_height(ct);

  /* put spacers after track */
  space = TRACK_VSPACE_DEFAULT;
  if (gt_style_get_num(canvas->pvt->sty, "format", "track_vspace", &space,
                       NULL, err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }
  canvas->pvt->y += space;

  return had_err;
}
Пример #3
0
int gt_canvas_cairo_visit_track_pre(GtCanvas *canvas, GtTrack *track,
                                    GtError *err)
{
  int had_err = 0;
  unsigned long exceeded;
  bool show_track_captions = true;

  GtColor color;

  gt_assert(canvas && track);

  if (gt_style_get_bool(canvas->pvt->sty,
                        "format", "show_track_captions",
                        &show_track_captions,
                        NULL, err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }
  if (gt_style_get_color(canvas->pvt->sty,
                         "format", "track_title_color",
                         &color, NULL, err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }

  /* debug */
  gt_log_log("processing track %s", gt_str_get(gt_track_get_title(track)));

  if (show_track_captions)
  {
    double theight      = gt_graphics_get_text_height(canvas->pvt->g),
           captionspace = CAPTION_BAR_SPACE_DEFAULT;
    if (gt_style_get_num(canvas->pvt->sty,
                          "format", "track_caption_font_size",
                          &theight, NULL, err) == GT_STYLE_QUERY_ERROR) {
      return -1;
    }
    if (gt_style_get_num(canvas->pvt->sty,
                         "format", "track_caption_space",
                         &captionspace, NULL, err ) == GT_STYLE_QUERY_ERROR) {
      return -1;
    }
    gt_graphics_set_font(canvas->pvt->g,
                         "Sans",
                         SLANT_NORMAL,
                         WEIGHT_NORMAL,
                         theight);
    canvas->pvt->y += theight;
    /* draw track title */
    gt_graphics_draw_colored_text(canvas->pvt->g,
                                  canvas->pvt->margins,
                                  canvas->pvt->y,
                                  color,
                                  gt_str_get(gt_track_get_title(track)));
    /* draw 'line maximum exceeded' message */
    if ((exceeded = gt_track_get_number_of_discarded_blocks(track)) > 0)
    {
      char buf[BUFSIZ];
      const char *msg;
      double width;
      GtColor red;
      red.red   = LINE_EXCEEDED_MSG_R;
      red.green = LINE_EXCEEDED_MSG_G;
      red.blue  = LINE_EXCEEDED_MSG_B;
      red.alpha = 1.0;
      if (exceeded == 1) {
        msg = "(1 block not shown due to exceeded line limit)";
        strncpy(buf, msg, BUFSIZ);
      } else {
        msg = "(%lu blocks not shown due to exceeded line limit)";
        /*@ignore@*/
        snprintf(buf, BUFSIZ, msg, exceeded);
        /*@end@*/
      }
      width = gt_graphics_get_text_width(canvas->pvt->g,
                                         gt_str_get(gt_track_get_title(track)));
      gt_graphics_draw_colored_text(canvas->pvt->g,
                                    canvas->pvt->margins+width+10.0,
                                    canvas->pvt->y,
                                    red,
                                    buf);
    }
    canvas->pvt->y += captionspace;
  }
  return had_err;
}
Пример #4
0
int gt_canvas_cairo_visit_block(GtCanvas *canvas, GtBlock *block,
                                GtError *err)
{
  int had_err = 0, arrow_status = ARROW_NONE;
  GtRange block_range;
  GtDrawingRange draw_range;
  GtColor grey, fillcolor, strokecolor;
  double block_start,
         block_width,
         bar_height = BAR_HEIGHT_DEFAULT,
         min_len_block = MIN_LEN_BLOCK_DEFAULT,
         arrow_width = ARROW_WIDTH_DEFAULT,
         stroke_width = STROKE_WIDTH_DEFAULT;
  const char *caption, *btype;
  GtStrand strand;
  double maxbarheight;
  btype = gt_block_get_type(block);

  gt_assert(canvas && block);

  grey.red = grey.green = grey.blue = DEFAULT_GREY_TONE;
  grey.alpha = 0.5;
  strand = gt_block_get_strand(block);
  block_range = gt_block_get_range(block);
  if (gt_block_get_max_height(block, &maxbarheight, canvas->pvt->sty, err)) {
    return -1;
  }
  if (gt_style_get_num(canvas->pvt->sty, "format", "bar_height", &bar_height,
                       NULL, err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }
  if (gt_style_get_num(canvas->pvt->sty, "format", "min_len_block",
                       &min_len_block,NULL, err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }
  if (gt_style_get_num(canvas->pvt->sty, "format", "arrow_width", &arrow_width,
                       NULL, err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }
  if (gt_style_get_num(canvas->pvt->sty, "format", "stroke_width",
                       &stroke_width, NULL, err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }
  if (gt_style_get_color_with_track(canvas->pvt->sty,
                                 btype, "stroke", &strokecolor,
                                 gt_block_get_top_level_feature(block),
                                 gt_track_get_title(canvas->pvt->current_track),
                                 err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }

  if (strand == GT_STRAND_REVERSE || strand == GT_STRAND_BOTH)
    arrow_status = ARROW_LEFT;
  if (strand == GT_STRAND_FORWARD || strand == GT_STRAND_BOTH)
    arrow_status = (arrow_status == ARROW_LEFT ? ARROW_BOTH : ARROW_RIGHT);

  /* calculate scaled drawing coordinates for this canvas */
  draw_range = gt_coords_calc_generic_range(block_range,
                                            canvas->pvt->viewrange);
  draw_range.start *= canvas->pvt->width-2*canvas->pvt->margins;
  draw_range.end *= canvas->pvt->width-2*canvas->pvt->margins;
  block_start = draw_range.start + canvas->pvt->margins;
  block_width = draw_range.end - draw_range.start;

  /* draw block caption */
  if (gt_block_caption_is_visible(block))
  {
    caption = gt_str_get(gt_block_get_caption(block));
    if (caption)
    {
      double theight = gt_graphics_get_text_height(canvas->pvt->g),
             captionspace = CAPTION_BAR_SPACE_DEFAULT;
      if (gt_style_get_num(canvas->pvt->sty,
                           "format", "block_caption_space",
                           &captionspace, NULL, err) == GT_STYLE_QUERY_ERROR) {
        return -1;
      }
      if (gt_style_get_num(canvas->pvt->sty,
                          "format", "block_caption_font_size",
                          &theight, NULL, err) == GT_STYLE_QUERY_ERROR) {
        return -1;
      }
      gt_graphics_set_font(canvas->pvt->g,
                           "Sans",
                           SLANT_NORMAL,
                           WEIGHT_NORMAL,
                           theight);
      gt_graphics_draw_text_clip(canvas->pvt->g,
                                 block_start,
                                 canvas->pvt->y - bar_height/2
                                                - captionspace,
                                 caption);
    }
  }

  /* do not draw further details in very small blocks */
  if (!gt_block_has_only_one_fullsize_element(block)
       && gt_double_smaller_double(block_width, min_len_block))
  {
    /* optimise drawing for very narrow blocks,
       if <= 1px/pt width, draw as simple lines */
    if (canvas->pvt->bt && draw_range.end-draw_range.start <= 1.1)
    {
      if (!gt_bittab_bit_is_set(canvas->pvt->bt,
                                (unsigned long) draw_range.start)) {
        gt_graphics_draw_vertical_line(canvas->pvt->g,
                                       block_start,
                                       canvas->pvt->y - bar_height/2,
                                       strokecolor,
                                       bar_height,
                                       stroke_width);
        gt_bittab_set_bit(canvas->pvt->bt, (unsigned long) draw_range.start);
      }
    } else {
      if (gt_style_get_color_with_track(canvas->pvt->sty,
                             btype, "fill",
                             &fillcolor,
                             gt_block_get_top_level_feature(block),
                             gt_track_get_title(canvas->pvt->current_track),
                             err) == GT_STYLE_QUERY_ERROR) {
        return -1;
      }

      gt_graphics_draw_box(canvas->pvt->g,
                           block_start,
                           canvas->pvt->y - bar_height/2,
                           block_width,
                           bar_height,
                           fillcolor,
                           arrow_status,
                           arrow_width,
                           stroke_width,
                           strokecolor,
                           true);

      /* draw arrowheads at clipped margins */
      if (draw_range.clip == CLIPPED_LEFT || draw_range.clip == CLIPPED_BOTH)
          gt_graphics_draw_arrowhead(canvas->pvt->g,
                                     canvas->pvt->margins - 10,
                                     canvas->pvt->y - 4,
                                     grey,
                                     ARROW_LEFT);
      if (draw_range.clip == CLIPPED_RIGHT || draw_range.clip == CLIPPED_BOTH)
          gt_graphics_draw_arrowhead(canvas->pvt->g,
                                     canvas->pvt->width-canvas->pvt->margins
                                       + 10,
                                     canvas->pvt->y - 4,
                                     grey,
                                     ARROW_RIGHT);
    }

    /* register coordinates in GtImageInfo object if available */
    if (canvas->pvt->ii)
    {
      GtRecMap *rm = gt_rec_map_new(block_start,
                                    canvas->pvt->y - bar_height/2,
                                    block_start + block_width,
                                    canvas->pvt->y + bar_height/2,
                                    (GtFeatureNode*) /* XXX */
                                      gt_block_get_top_level_feature(block));
      gt_image_info_add_rec_map(canvas->pvt->ii, rm);
      gt_rec_map_set_omitted_children(rm, true);
    }
    /* signal break */
    return 1;
  }

  /* get stroke color */
  if (gt_style_get_color(canvas->pvt->sty,
                         "format", "default_stroke_color",
                         &strokecolor, NULL, err) == GT_STYLE_QUERY_ERROR) {
    return -1;
  }

  /* draw parent block boundaries */
  gt_graphics_draw_dashes(canvas->pvt->g,
                          block_start,
                          canvas->pvt->y - bar_height/2,
                          block_width,
                          bar_height,
                          ARROW_NONE,
                          arrow_width,
                          stroke_width,
                          strokecolor);
  return had_err;
}