void get_offsets( struct text_label *this_label, struct termentry *t, int *htic, int *vtic) { if ((this_label->lp_properties.flags & LP_SHOW_POINTS)) { *htic = (pointsize * t->h_tic * 0.5); *vtic = (pointsize * t->v_tic * 0.5); } else { *htic = 0; *vtic = 0; } if (is_3d_plot) { int htic2, vtic2; map3d_position_r(&(this_label->offset), &htic2, &vtic2, "get_offsets"); *htic += htic2; *vtic += vtic2; } else { double htic2, vtic2; map_position_r(&(this_label->offset), &htic2, &vtic2, "get_offsets"); *htic += (int)htic2; *vtic += (int)vtic2; } }
void apply_head_properties(struct arrow_style_type *arrow_properties) { curr_arrow_headfilled = arrow_properties->headfill; curr_arrow_headfixedsize = arrow_properties->head_fixedsize; curr_arrow_headlength = 0; if (arrow_properties->head_length > 0) { /* set head length+angle for term->arrow */ double xtmp, ytmp; struct position headsize = {first_axes,graph,graph,0.,0.,0.}; headsize.x = arrow_properties->head_length; headsize.scalex = arrow_properties->head_lengthunit; map_position_r(&headsize, &xtmp, &ytmp, "arrow"); curr_arrow_headangle = arrow_properties->head_angle; curr_arrow_headbackangle = arrow_properties->head_backangle; curr_arrow_headlength = xtmp; } }
void multiplot_start() { TBOOLEAN set_spacing = FALSE; TBOOLEAN set_margins = FALSE; c_token++; /* Only a few options are possible if we are already in multiplot mode */ /* So far we have "next". Maybe also "previous", "clear"? */ if (multiplot) { if (equals(c_token, "next")) { c_token++; if (!mp_layout.auto_layout) int_error(c_token, "only valid inside an auto-layout multiplot"); multiplot_next(); return; } else if (almost_equals(c_token, "prev$ious")) { c_token++; if (!mp_layout.auto_layout) int_error(c_token, "only valid inside an auto-layout multiplot"); multiplot_previous(); return; } else { term_end_multiplot(); } } /* FIXME: more options should be reset/initialized each time */ mp_layout.auto_layout = FALSE; mp_layout.auto_layout_margins = FALSE; mp_layout.current_panel = 0; mp_layout.title.noenhanced = FALSE; free(mp_layout.title.text); mp_layout.title.text = NULL; free(mp_layout.title.font); mp_layout.title.font = NULL; /* Parse options */ while (!END_OF_COMMAND) { if (almost_equals(c_token, "ti$tle")) { c_token++; mp_layout.title.text = try_to_get_string(); continue; } if (equals(c_token, "font")) { c_token++; mp_layout.title.font = try_to_get_string(); continue; } if (almost_equals(c_token,"enh$anced")) { mp_layout.title.noenhanced = FALSE; c_token++; continue; } if (almost_equals(c_token,"noenh$anced")) { mp_layout.title.noenhanced = TRUE; c_token++; continue; } if (almost_equals(c_token, "lay$out")) { if (mp_layout.auto_layout) int_error(c_token, "too many layout commands"); else mp_layout.auto_layout = TRUE; c_token++; if (END_OF_COMMAND) { int_error(c_token,"expecting '<num_cols>,<num_rows>'"); } /* read row,col */ mp_layout.num_rows = int_expression(); if (END_OF_COMMAND || !equals(c_token,",") ) int_error(c_token, "expecting ', <num_cols>'"); c_token++; if (END_OF_COMMAND) int_error(c_token, "expecting <num_cols>"); mp_layout.num_cols = int_expression(); /* remember current values of the plot size and the margins */ mp_layout.prev_xsize = xsize; mp_layout.prev_ysize = ysize; mp_layout.prev_xoffset = xoffset; mp_layout.prev_yoffset = yoffset; mp_layout.prev_lmargin = lmargin; mp_layout.prev_rmargin = rmargin; mp_layout.prev_bmargin = bmargin; mp_layout.prev_tmargin = tmargin; mp_layout.act_row = 0; mp_layout.act_col = 0; continue; } /* The remaining options are only valid for auto-layout mode */ if (!mp_layout.auto_layout) int_error(c_token, "only valid in the context of an auto-layout command"); switch(lookup_table(&set_multiplot_tbl[0],c_token)) { case S_MULTIPLOT_COLUMNSFIRST: mp_layout.row_major = TRUE; c_token++; break; case S_MULTIPLOT_ROWSFIRST: mp_layout.row_major = FALSE; c_token++; break; case S_MULTIPLOT_DOWNWARDS: mp_layout.downwards = TRUE; c_token++; break; case S_MULTIPLOT_UPWARDS: mp_layout.downwards = FALSE; c_token++; break; case S_MULTIPLOT_SCALE: c_token++; mp_layout.xscale = real_expression(); mp_layout.yscale = mp_layout.xscale; if (!END_OF_COMMAND && equals(c_token,",") ) { c_token++; if (END_OF_COMMAND) { int_error(c_token, "expecting <yscale>"); } mp_layout.yscale = real_expression(); } break; case S_MULTIPLOT_OFFSET: c_token++; mp_layout.xoffset = real_expression(); mp_layout.yoffset = mp_layout.xoffset; if (!END_OF_COMMAND && equals(c_token,",") ) { c_token++; if (END_OF_COMMAND) { int_error(c_token, "expecting <yoffset>"); } mp_layout.yoffset = real_expression(); } break; case S_MULTIPLOT_MARGINS: c_token++; if (END_OF_COMMAND) int_error(c_token,"expecting '<left>,<right>,<bottom>,<top>'"); mp_layout.lmargin.scalex = screen; mp_layout_set_margin_or_spacing(&(mp_layout.lmargin)); if (!END_OF_COMMAND && equals(c_token,",") ) { c_token++; if (END_OF_COMMAND) int_error(c_token, "expecting <right>"); mp_layout.rmargin.scalex = mp_layout.lmargin.scalex; mp_layout_set_margin_or_spacing(&(mp_layout.rmargin)); } else { int_error(c_token, "expecting <right>"); } if (!END_OF_COMMAND && equals(c_token,",") ) { c_token++; if (END_OF_COMMAND) int_error(c_token, "expecting <top>"); mp_layout.bmargin.scalex = mp_layout.rmargin.scalex; mp_layout_set_margin_or_spacing(&(mp_layout.bmargin)); } else { int_error(c_token, "expecting <bottom>"); } if (!END_OF_COMMAND && equals(c_token,",") ) { c_token++; if (END_OF_COMMAND) int_error(c_token, "expecting <bottom>"); mp_layout.tmargin.scalex = mp_layout.bmargin.scalex; mp_layout_set_margin_or_spacing(&(mp_layout.tmargin)); } else { int_error(c_token, "expection <top>"); } set_margins = TRUE; break; case S_MULTIPLOT_SPACING: c_token++; if (END_OF_COMMAND) int_error(c_token,"expecting '<xspacing>,<yspacing>'"); mp_layout.xspacing.scalex = screen; mp_layout_set_margin_or_spacing(&(mp_layout.xspacing)); mp_layout.yspacing = mp_layout.xspacing; if (!END_OF_COMMAND && equals(c_token, ",")) { c_token++; if (END_OF_COMMAND) int_error(c_token, "expecting <yspacing>"); mp_layout_set_margin_or_spacing(&(mp_layout.yspacing)); } set_spacing = TRUE; break; default: int_error(c_token,"invalid or duplicate option"); break; } } if (set_spacing || set_margins) { if (set_spacing && set_margins) { if (mp_layout.lmargin.x >= 0 && mp_layout.rmargin.x >= 0 && mp_layout.tmargin.x >= 0 && mp_layout.bmargin.x >= 0 && mp_layout.xspacing.x >= 0 && mp_layout.yspacing.x >= 0) mp_layout.auto_layout_margins = TRUE; else int_error(NO_CARET, "must give positive margin and spacing values"); } else if (set_spacing) { int_warn(NO_CARET, "must give margins and spacing, continue with auto margins."); } else if (set_margins) { mp_layout.auto_layout_margins = TRUE; mp_layout.xspacing.scalex = screen; mp_layout.xspacing.x = 0.05; mp_layout.yspacing.scalex = screen; mp_layout.yspacing.x = 0.05; int_warn(NO_CARET, "must give margins and spacing, continue with spacing of 0.05"); } /* Sanity check that screen tmargin is > screen bmargin */ if (mp_layout.bmargin.scalex == screen && mp_layout.tmargin.scalex == screen) if (mp_layout.bmargin.x > mp_layout.tmargin.x) { double tmp = mp_layout.bmargin.x; mp_layout.bmargin.x = mp_layout.tmargin.x; mp_layout.tmargin.x = tmp; } } /* If we reach here, then the command has been successfully parsed. * Aug 2013: call term_start_plot() before setting multiplot so that * the wxt and qt terminals will reset the plot count to 0 before * ignoring subsequent TERM_LAYER_RESET requests. */ term_start_plot(); multiplot = TRUE; fill_gpval_integer("GPVAL_MULTIPLOT", 1); /* Place overall title before doing anything else */ if (mp_layout.title.text) { double tmpx, tmpy; unsigned int x, y; char *p = mp_layout.title.text; map_position_r(&(mp_layout.title.offset), &tmpx, &tmpy, "mp title"); x = term->xmax / 2 + tmpx; y = term->ymax - term->v_char + tmpy;; ignore_enhanced(mp_layout.title.noenhanced); apply_pm3dcolor(&(mp_layout.title.textcolor)); write_multiline(x, y, mp_layout.title.text, CENTRE, JUST_TOP, 0, mp_layout.title.font); reset_textcolor(&(mp_layout.title.textcolor)); ignore_enhanced(FALSE); /* Calculate fractional height of title compared to entire page */ /* If it would fill the whole page, forget it! */ for (y=1; *p; p++) if (*p == '\n') y++; /* Oct 2012 - v_char depends on the font used */ if (mp_layout.title.font && *mp_layout.title.font) term->set_font(mp_layout.title.font); mp_layout.title_height = (double)(y * term->v_char) / (double)term->ymax; if (mp_layout.title.font && *mp_layout.title.font) term->set_font(""); if (mp_layout.title_height > 0.9) mp_layout.title_height = 0.05; } else { mp_layout.title_height = 0.0; } if (mp_layout.auto_layout_margins) mp_layout_margins_and_spacing(); else mp_layout_size_and_offset(); }
/* Finally the main colour smooth box drawing routine */ void draw_color_smooth_box(int plot_mode) { double tmp; FILE *out = gppsfile; /* either gpoutfile or PSLATEX_auxfile */ if (color_box.where == SMCOLOR_BOX_NO) return; if (!term->filled_polygon) return; /* firstly, choose some good position of the color box user's position like that (?): else { x_from = color_box.xlow; x_to = color_box.xhigh; } */ if (color_box.where == SMCOLOR_BOX_USER) { if (!is_3d_plot) { double xtemp, ytemp; map_position(&color_box.origin, &color_box.bounds.xleft, &color_box.bounds.ybot, "cbox"); map_position_r(&color_box.size, &xtemp, &ytemp, "cbox"); color_box.bounds.xright = xtemp; color_box.bounds.ytop = ytemp; } else if (splot_map && is_3d_plot) { /* In map view mode we allow any coordinate system for placement */ double xtemp, ytemp; map3d_position_double(&color_box.origin, &xtemp, &ytemp, "cbox"); color_box.bounds.xleft = xtemp; color_box.bounds.ybot = ytemp; map3d_position_r(&color_box.size, &color_box.bounds.xright, &color_box.bounds.ytop, "cbox"); } else { /* But in full 3D mode we only allow screen coordinates */ color_box.bounds.xleft = color_box.origin.x * (term->xmax) + 0.5; color_box.bounds.ybot = color_box.origin.y * (term->ymax) + 0.5; color_box.bounds.xright = color_box.size.x * (term->xmax-1) + 0.5; color_box.bounds.ytop = color_box.size.y * (term->ymax-1) + 0.5; } color_box.bounds.xright += color_box.bounds.xleft; color_box.bounds.ytop += color_box.bounds.ybot; } else { /* color_box.where == SMCOLOR_BOX_DEFAULT */ if (plot_mode == MODE_SPLOT && !splot_map) { /* HBB 20031215: new code. Constants fixed to what the result * of the old code in default view (set view 60,30,1,1) * happened to be. Somebody fix them if they're not right! */ color_box.bounds.xleft = xmiddle + 0.709 * xscaler; color_box.bounds.xright = xmiddle + 0.778 * xscaler; color_box.bounds.ybot = ymiddle - 0.147 * yscaler; color_box.bounds.ytop = ymiddle + 0.497 * yscaler; } else if (is_3d_plot) { /* MWS 09-Dec-05, make color box full size for splot maps. */ double dx = (X_AXIS.max - X_AXIS.min); map3d_xy(X_AXIS.max + dx * 0.025, Y_AXIS.min, base_z, &color_box.bounds.xleft, &color_box.bounds.ybot); map3d_xy(X_AXIS.max + dx * 0.075, Y_AXIS.max, ceiling_z, &color_box.bounds.xright, &color_box.bounds.ytop); } else { /* 2D plot */ struct position default_origin = {graph,graph,graph, 1.025, 0, 0}; struct position default_size = {graph,graph,graph, 0.05, 1.0, 0}; double xtemp, ytemp; map_position(&default_origin, &color_box.bounds.xleft, &color_box.bounds.ybot, "cbox"); color_box.bounds.xleft += color_box.xoffset; map_position_r(&default_size, &xtemp, &ytemp, "cbox"); color_box.bounds.xright = xtemp + color_box.bounds.xleft; color_box.bounds.ytop = ytemp + color_box.bounds.ybot; } /* now corrections for outer tics */ if (color_box.rotation == 'v') { int cblen = (CB_AXIS.tic_in ? -1 : 1) * CB_AXIS.ticscale * (term->h_tic); /* positive for outer tics */ int ylen = (Y_AXIS.tic_in ? -1 : 1) * Y_AXIS.ticscale * (term->h_tic); /* positive for outer tics */ if ((cblen > 0) && (CB_AXIS.ticmode & TICS_MIRROR)) { color_box.bounds.xleft += cblen; color_box.bounds.xright += cblen; } if ((ylen > 0) && (axis_array[FIRST_Y_AXIS].ticmode & TICS_MIRROR)) { color_box.bounds.xleft += ylen; color_box.bounds.xright += ylen; } } } if (color_box.bounds.ybot > color_box.bounds.ytop) { /* switch them */ tmp = color_box.bounds.ytop; color_box.bounds.ytop = color_box.bounds.ybot; color_box.bounds.ybot = tmp; } /* Optimized version of the smooth colour box in postscript. Advantage: only few lines of code is written into the output file. */ if (gppsfile) draw_inside_color_smooth_box_postscript(out); else draw_inside_color_smooth_box_bitmap(out); if (color_box.border) { /* now make boundary around the colour box */ if (color_box.border_lt_tag >= 0) { /* user specified line type */ struct lp_style_type lp = border_lp; lp_use_properties(&lp, color_box.border_lt_tag); term_apply_lp_properties(&lp); } else { /* black solid colour should be chosen, so it's border linetype */ term_apply_lp_properties(&border_lp); } newpath(); (term->move) (color_box.bounds.xleft, color_box.bounds.ybot); (term->vector) (color_box.bounds.xright, color_box.bounds.ybot); (term->vector) (color_box.bounds.xright, color_box.bounds.ytop); (term->vector) (color_box.bounds.xleft, color_box.bounds.ytop); (term->vector) (color_box.bounds.xleft, color_box.bounds.ybot); closepath(); /* Set line properties to some value, this also draws lines in postscript terminals. */ term_apply_lp_properties(&border_lp); } /* draw tics */ if (axis_array[COLOR_AXIS].ticmode) { term_apply_lp_properties(&border_lp); /* border linetype */ gen_tics(COLOR_AXIS, cbtick_callback ); } /* write the colour box label */ if (CB_AXIS.label.text) { int x, y; apply_pm3dcolor(&(CB_AXIS.label.textcolor),term); if (color_box.rotation == 'h') { int len = CB_AXIS.ticscale * (CB_AXIS.tic_in ? 1 : -1) * (term->v_tic); map3d_position_r(&(CB_AXIS.label.offset), &x, &y, "smooth_box"); x += (color_box.bounds.xleft + color_box.bounds.xright) / 2; #define DEFAULT_Y_DISTANCE 1.0 y += color_box.bounds.ybot + (- DEFAULT_Y_DISTANCE - 1.7) * term->v_char; #undef DEFAULT_Y_DISTANCE if (len < 0) y += len; if (x<0) x = 0; if (y<0) y = 0; write_multiline(x, y, CB_AXIS.label.text, CENTRE, JUST_CENTRE, 0, CB_AXIS.label.font); } else { int len = CB_AXIS.ticscale * (CB_AXIS.tic_in ? -1 : 1) * (term->h_tic); /* calculate max length of cb-tics labels */ widest_tic_strlen = 0; if (CB_AXIS.ticmode & TICS_ON_BORDER) { widest_tic_strlen = 0; /* reset the global variable */ gen_tics(COLOR_AXIS, /* 0, */ widest_tic_callback); } map3d_position_r(&(CB_AXIS.label.offset), &x, &y, "smooth_box"); #define DEFAULT_X_DISTANCE 0.0 x += color_box.bounds.xright + (widest_tic_strlen + DEFAULT_X_DISTANCE + 1.5) * term->h_char; #undef DEFAULT_X_DISTANCE if (len > 0) x += len; y += (color_box.bounds.ybot + color_box.bounds.ytop) / 2; if (x<0) x = 0; if (y<0) y = 0; if ((*term->text_angle)(CB_AXIS.label.rotate)) { write_multiline(x, y, CB_AXIS.label.text, CENTRE, JUST_TOP, CB_AXIS.label.rotate, CB_AXIS.label.font); (*term->text_angle)(0); } else { write_multiline(x, y, CB_AXIS.label.text, LEFT, JUST_TOP, 0, CB_AXIS.label.font); } } reset_textcolor(&(CB_AXIS.label.textcolor),term); } }