📄 g2_fig.c
字号:
/******************************************************************************* Copyright (C) 1998-2004 Ljubomir Milanovic & Horst Wagner** This file is part of the g2 library**** This library is free software; you can redistribute it and/or** modify it under the terms of the GNU Lesser General Public** License as published by the Free Software Foundation; either** version 2.1 of the License, or (at your option) any later version.**** This library is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU** Lesser General Public License for more details.**** You should have received a copy of the GNU Lesser General Public** License along with this library; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA******************************************************************************/#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <limits.h>#include <math.h>#include <string.h>#include "g2.h"#include "g2_device.h"#include "g2_util.h"#include "g2_config.h"#include "g2_FIG.h"#include "g2_FIG_P.h"#include "g2_FIG_funix.h"#ifndef PI#define PI 3.14159265358979323846#endif /* PI */static int N_FIG=0;static g2_FIG_device *g2_FIG_dev=NULL;/** * \ingroup physdev * \defgroup FIG FIG * * FIG devices generate output in the FIG 3.2 format. For more details * about FIG format and xfig application please visit http://www.xfig.org . * * \note FIG is a vector-oriented (as oposed to pixel-oriented) format. * Therefore ::g2_image function and splines are not optimally supported. *//** * * Create a FIG device. g2 uses A4 paper size (landscape orientation) as default. * * \param file_name fig file name * * \return physical device id * * \ingroup FIG */G2L int g2_open_FIG(const char *file_name){ g2_FIG_device *figout=NULL; int pid=-1, i; int vid; FILE *fp; if((fp=fopen(file_name, "w"))==NULL) { g2_log(Error, "g2_attach_PS: Error! Can not open file '%s'\n", file_name); return -1; } if(g2_FIG_dev==NULL) { g2_FIG_dev=g2_malloc(sizeof(g2_FIG_device)); N_FIG=1; /* first FIG device */ figout=&g2_FIG_dev[N_FIG-1]; pid=0; } else { for(i=0;i<N_FIG;i++) { /* find free place */ if(g2_FIG_dev[i].fp==NULL) { figout=&g2_FIG_dev[i]; pid=i; break; } } if(i==N_FIG) { /* free place not avail. */ N_FIG++; g2_FIG_dev=g2_realloc(g2_FIG_dev, sizeof(g2_FIG_device)*N_FIG); figout=&g2_FIG_dev[N_FIG-1]; pid=N_FIG-1; } } vid = g2_register_physical_device(pid, NULL, g2_IntCoor, g2_FIG_funix, 1200./80., -1200./80., 0.0, 595/72*1200-160); /* -180 is a hand-made correcture factor */ /* init FIG structures */ figout->fp=fp; figout->pen_color=1; figout->thickness=-1; figout->font_size=-1; figout->N_inks=0; /* write file header (incl. color placeholder) */ g2_FIG_write_file_header(figout); /* g2 settings callbacks */ g2_allocate_basic_colors(vid); g2_pen(vid, 1); g2_set_line_width(vid, 1); g2_set_dash(vid, 0, NULL); g2_set_font_size(vid, 12); return vid;}/* * * Write header for fig file * */int g2_FIG_write_file_header(g2_FIG_device *fig){ int i; fprintf(fig->fp, "#FIG 3.2\n"); fprintf(fig->fp, "#Creator: g2 %s\n", G2_VERSION); fprintf(fig->fp, "Landscape\n"); fprintf(fig->fp, "Flush Left\n"); fprintf(fig->fp, "Metric\n"); fprintf(fig->fp, "A4\n"); fprintf(fig->fp, "100\n"); fprintf(fig->fp, "Single\n"); fprintf(fig->fp, "-2\n"); fprintf(fig->fp, "1200 2\n"); /* write placeholder for all colors */ fgetpos(fig->fp, &(fig->color_file_pos)); for(i=0;i<512;i++) fprintf(fig->fp, "0 %3d #%02x%02x%02x\n",32+i, 0xff, 0xff, 0xff); return 0;}/* * * Delete FIG device * */int g2_FIG_delete(int pid, void *pdp){ int i; g2_FIG_device *fig=&g2_FIG_dev[pid]; /* now write all defined colors to the reserved place */ fsetpos(fig->fp, &(fig->color_file_pos)); for(i=0;i<fig->N_inks;i++) { fprintf(fig->fp, "0 %3d #%02x%02x%02x\n", 32+i, (int)fig->inks[i].red, (int)fig->inks[i].green, (int)fig->inks[i].blue); } fclose(fig->fp); fig->fp=NULL; /* free place */ return 0;}int g2_FIG_ink(int pid, void *pdp, double red, double green, double blue){ /* the fig pen space is betwen 32 and 543, total of 512 colors, in g2 implementation from 0000 to 0777. On the other hand ink space is between #000000 and #ffffff. */ g2_FIG_device *fig=&g2_FIG_dev[pid]; if(fig->N_inks>=512) return -1; fig->inks[fig->N_inks].red = red*0xff; fig->inks[fig->N_inks].green = green*0xff; fig->inks[fig->N_inks].blue = blue*0xff; return fig->N_inks++;}int g2_FIG_pen(int pid, void *pdp, int color){ g2_FIG_device *fig=&g2_FIG_dev[pid]; if(color>=fig->N_inks) { return -1; } fig->pen_color = 32+color; return 0;}int g2_FIG_set_background(int pid, void *pdp, int color){ return -1;}int g2_FIG_clear_palette(int pid, void *pdp){ return -1;}int g2_FIG_set_line_width(int pid, void *pdp, int w){ g2_FIG_device *fig=&g2_FIG_dev[pid]; fig->thickness = w*80./1200.; return 0;}int g2_FIG_set_dash(int pid, void *pdp, int N, int *data){ g2_FIG_device *fig=&g2_FIG_dev[pid]; int black, white; if(N==0 || data==NULL) { fig->line_style=0; fig->style_val=-1; return 0; } if(N<2) { return -1; } black = data[0]*80./1200.; /* FIG format has no sofistificated dash concept */ white = data[1]*80./1200.; /* we will do out best */ if(black<4) { fig->line_style = 2; } else { fig->line_style = 1; } fig->style_val = white; return 0;}int g2_FIG_set_font_size(int pid, void *pdp, int size){ g2_FIG_device *fig=&g2_FIG_dev[pid]; fig->font_size = size*72./1200.; return 0;}int g2_FIG_clear(int pid, void *pdp){ return -1;}int g2_FIG_flush(int pid, void *pdp){ g2_FIG_device *fig=&g2_FIG_dev[pid]; fflush(fig->fp); return 0;}int g2_FIG_plot(int pid, void *pdp, int x, int y){ g2_FIG_device *fig=&g2_FIG_dev[pid]; fprintf(fig->fp, "2 1 0 %d %d -1 1 1 -1 -1 1 0 -1 0 0 2\n", 1, fig->pen_color); fprintf(fig->fp, " %d %d\n %d %d\n", x, y, x+1, y); return 0;}int g2_FIG_line(int pid, void *pdp, int x1, int y1, int x2, int y2){ g2_FIG_device *fig=&g2_FIG_dev[pid]; fprintf(fig->fp, "2 1 %d %d %d -1 1 1 -1 %d 1 0 -1 0 0 2\n", fig->line_style, fig->thickness, fig->pen_color, fig->style_val); fprintf(fig->fp, " %d %d\n %d %d\n", x1, y1, x2, y2); return 0;}int g2_FIG_poly_line(int pid, void *pdp, int N, int *points){ g2_FIG_device *fig=&g2_FIG_dev[pid]; int i; fprintf(fig->fp,"2 1 %d %d %d -1 1 1 -1 %d 1 0 -1 0 0 %d\n", fig->line_style, fig->thickness, fig->pen_color, fig->style_val, N); for(i=0;i<2*N;i+=2) { fprintf(fig->fp, " %d %d\n", points[i], points[i+1]); } return 0;}int g2_FIG_polygon(int pid, void *pdp, int N, int *points){ g2_FIG_device *fig=&g2_FIG_dev[pid]; int i; if(N<2) { return -1; } fprintf(fig->fp,"2 3 %d %d %d -1 1 1 -1 %d 1 0 -1 0 0 %d\n", fig->line_style, fig->thickness, fig->pen_color, fig->style_val, N+1); for(i=0;i<2*N;i+=2) { fprintf(fig->fp, " %d %d\n", points[i], points[i+1]); } fprintf(fig->fp, " %d %d\n", points[0], points[1]); return 0;}int g2_FIG_filled_polygon(int pid, void *pdp, int N, int *points){ g2_FIG_device *fig=&g2_FIG_dev[pid]; int i; if(N<2) { return -1; } fprintf(fig->fp,"2 3 %d %d %d %d 1 1 20 %d 1 0 -1 0 0 %d\n", fig->line_style, fig->thickness, fig->pen_color, fig->pen_color, fig->style_val, N+1); for(i=0;i<2*N;i+=2) { fprintf(fig->fp, " %d %d\n", points[i], points[i+1]); } fprintf(fig->fp, " %d %d\n", points[0], points[1]); return 0;}int g2_FIG_arc(int pid, void *pdp, int x, int y, int r1, int r2, double a1, double a2){ g2_FIG_device *fig=&g2_FIG_dev[pid]; double a0, d; double a0_rad, da_rad; int N, i; a0=fmod(a1, 360.) + (a1<0? 360:0); /* map a1 to [0, 360) */ d=a2>a1? a2-a1:a2-a1+360; N=3+d/18; a0_rad = a0*2.*PI/360.; da_rad = d*2.*PI/360./(N-1); fprintf(fig->fp, "3 2 %d %d %d -1 1 -1-1 %d 0 0 0 %d\n", fig->line_style, fig->thickness, fig->pen_color, fig->style_val, N); for(i=0;i<N;i++) { fprintf(fig->fp, " %d %d\n", (int)(x+r1*cos(a0_rad+i*da_rad)), (int)(y-r2*sin(a0_rad+i*da_rad))); } fprintf(fig->fp, " -1"); for(i=1;i<N-1;i++) { fprintf(fig->fp, " -1"); } fprintf(fig->fp, " -1\n"); return 0;}int g2_FIG_filled_arc(int pid, void *pdp, int x, int y, int r1, int r2, double a1, double a2){ g2_FIG_device *fig=&g2_FIG_dev[pid]; double a0, d; double a0_rad, da_rad; int N, i; a0=fmod(a1, 360.) + (a1<0? 360:0); /* map a1 to [0, 360) */ d=a2>a1? a2-a1:a2-a1+360; N=3+d/18; a0_rad = a0*2.*PI/360.; da_rad = d*2.*PI/360./(N-1); fprintf(fig->fp, "3 2 %d %d %d %d 1 -1 20 %d 0 0 0 %d\n", fig->line_style, fig->thickness, fig->pen_color, fig->pen_color, fig->style_val, N+2); for(i=0;i<N;i++) { fprintf(fig->fp, " %d %d\n", (int)(x+r1*cos(a0_rad+i*da_rad)), (int)(y-r2*sin(a0_rad+i*da_rad))); } fprintf(fig->fp, " %d %d\n", x, y); fprintf(fig->fp, " %d %d\n", (int)(x+r1*cos(a0_rad+0*da_rad)), (int)(y-r2*sin(a0_rad+0*da_rad))); fprintf(fig->fp, " 0"); for(i=1;i<N-1;i++) { fprintf(fig->fp, " -1"); } fprintf(fig->fp, " 0 0 0\n"); return 0;}int g2_FIG_ellipse(int pid, void *pdp, int x, int y, int r1, int r2){ g2_FIG_device *fig=&g2_FIG_dev[pid]; fprintf(fig->fp,"1 1 %d %d %d -1 1 -1 -1 %d 1 0.0 %d %d %d %d %d %d %d %d\n", fig->line_style, fig->thickness, fig->pen_color, fig->style_val, x, y, r1, r2, x, y, x+r1, y+r2); return 0;}int g2_FIG_filled_ellipse(int pid, void *pdp, int x, int y, int r1, int r2){ g2_FIG_device *fig=&g2_FIG_dev[pid]; fprintf(fig->fp,"1 1 %d %d %d %d 1 -1 20 %d 1 0.0 %d %d %d %d %d %d %d %d\n", fig->line_style, fig->thickness, fig->pen_color, fig->pen_color, fig->style_val, x, y, r1, r2, x, y, x+r1, y+r2); return 0;} int g2_FIG_draw_string(int pid, void *pdp, int x, int y, const char *text){ const char *c; g2_FIG_device *fig=&g2_FIG_dev[pid]; if(fig->font_size<=0) return 0; fprintf(fig->fp,"4 0 %d 1 -1 0 %d 0 5 %d %d %d %d ", fig->pen_color, fig->font_size, fig->font_size, fig->font_size*strlen(text), x, y); for(c=text;*c;c++) { if(*c=='\\') fputc('\\', fig->fp); /* escape \\ */ fputc(*c, fig->fp); } fprintf(fig->fp,"\\001\n"); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -