GtDrawingRange gt_coords_calc_generic_range(GtRange node_range, GtRange viewrange) { GtDrawingRange converted_range; converted_range.clip = CLIPPED_NONE; node_range.end++; /* scale coordinates to target image width */ if (node_range.start < viewrange.start ) converted_range.clip = CLIPPED_LEFT; converted_range.start = gt_coords_convert_point(viewrange, node_range.start); if (node_range.end > viewrange.end+1) converted_range.clip = (converted_range.clip == CLIPPED_LEFT ? CLIPPED_BOTH : CLIPPED_RIGHT); converted_range.end = gt_coords_convert_point(viewrange, node_range.end); return converted_range; }
/* Renders a ruler with dynamic scale labeling and optional grid. */ int gt_canvas_cairo_draw_ruler(GtCanvas *canvas, GtRange viewrange, GtError *err) { double step, minorstep, vmajor, vminor, theight = gt_graphics_get_text_height(canvas->pvt->g); long base_length, tick; GtColor rulercol, gridcol; GtStr *left_str, *right_str, *unit; char str[BUFSIZ]; GtStyleQueryStatus rval; bool showgrid = true; gt_assert(canvas); if (gt_style_get_bool(canvas->pvt->sty, "format", "show_grid", &showgrid, NULL, err) == GT_STYLE_QUERY_ERROR) { return -1; } if (gt_style_get_num(canvas->pvt->sty, "format", "ruler_font_size", &theight, NULL, err) == GT_STYLE_QUERY_ERROR) { return -1; } /* get unit value from style, default: empty */ unit = gt_str_new(); if (gt_style_get_str(canvas->pvt->sty, "format", "unit", unit, NULL, err) == GT_STYLE_QUERY_ERROR) { gt_str_delete(unit); return -1; } /* get additional description texts from style */ left_str = gt_str_new(); rval = gt_style_get_str(canvas->pvt->sty, "format", "ruler_left_text", left_str, NULL, err); switch (rval) { case GT_STYLE_QUERY_NOT_SET: gt_str_append_cstr(left_str, FIVE_PRIME_STRING); break; case GT_STYLE_QUERY_ERROR: gt_str_delete(unit); gt_str_delete(left_str); return -1; break; /* shouldn't reach this */ default: break; } right_str = gt_str_new(); rval = gt_style_get_str(canvas->pvt->sty, "format", "ruler_right_text", right_str, NULL, err); switch (rval) { case GT_STYLE_QUERY_NOT_SET: gt_str_append_cstr(right_str, THREE_PRIME_STRING); break; case GT_STYLE_QUERY_ERROR: gt_str_delete(unit); gt_str_delete(left_str); gt_str_delete(right_str); return -1; break; /* shouldn't reach this */ default: break; } /* reset font to default */ gt_graphics_set_font(canvas->pvt->g, "Sans", SLANT_NORMAL, WEIGHT_NORMAL, theight); rulercol.red = rulercol.green = rulercol.blue = RULER_GREY; rulercol.alpha = 1.0; gridcol.red = gridcol.green = gridcol.blue = GRID_GREY; gridcol.alpha = 1.0; /* determine range and step of the scale */ base_length = gt_range_length(&viewrange); /* determine tick steps */ step = pow(10,ceil(log10(base_length))-1); minorstep = step/10.0; /* calculate starting positions */ vminor = (double) (floor(viewrange.start / minorstep))*minorstep; vmajor = (double) (floor(viewrange.start / step))*step; /* draw major ticks */ for (tick = vmajor; tick <= viewrange.end; tick += step) { double drawtick = (gt_coords_convert_point(viewrange, tick) * (canvas->pvt->width-2*canvas->pvt->margins)) + canvas->pvt->margins; if (tick < viewrange.start) continue; gt_graphics_draw_vertical_line(canvas->pvt->g, drawtick, canvas->pvt->y + 30, rulercol, 10, 1.0); gt_format_ruler_label(str, tick, gt_str_get(unit), BUFSIZ); gt_graphics_draw_text_centered(canvas->pvt->g, drawtick, canvas->pvt->y + 20, str); } /* draw minor ticks */ if (minorstep >= 1) { for (tick = vminor; tick <= viewrange.end; tick += minorstep) { double drawtick; if (tick < viewrange.start) continue; drawtick = (gt_coords_convert_point(viewrange, tick) * (canvas->pvt->width-2*canvas->pvt->margins)) + canvas->pvt->margins; if (showgrid) { gt_graphics_draw_vertical_line(canvas->pvt->g, drawtick, canvas->pvt->y + 40, gridcol, canvas->pvt->height - 40 - 15, 1.0); } gt_graphics_draw_vertical_line(canvas->pvt->g, drawtick, canvas->pvt->y + 35, rulercol, 5, 1.0); } } /* draw ruler line */ gt_graphics_draw_horizontal_line(canvas->pvt->g, canvas->pvt->margins, canvas->pvt->y + 40, rulercol, canvas->pvt->width - 2 * canvas->pvt->margins, 1.25); gt_graphics_draw_text_right(canvas->pvt->g, canvas->pvt->margins - 10, canvas->pvt->y + 39 + (theight/2), gt_str_get(left_str)); gt_graphics_draw_text(canvas->pvt->g, canvas->pvt->width - canvas->pvt->margins + 10, canvas->pvt->y + 39 + (theight/2), gt_str_get(right_str)); gt_str_delete(unit); gt_str_delete(left_str); gt_str_delete(right_str); return 0; }