//=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // "elib.cc" // Encapsulatex PostScript 生成システム // Copyright(C) by Naoki Watanabe. // All rights reserved. // Last revised on Sep 7th, 1998. //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* #include #include #include "elib.h" // EPSファイル内でのfont指定の命令文字列 static char* EPS_Font_Names[4]={ "/Times-Roman", "/Times-Italic", "/Times-Bold", "/Times-BoldItalic" }; //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // EPS用GCの制御機構の定義 //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* #define MM2PT (72.0/25.4) //---- EPSGCを生成して初期化する関数 ------------- EPSGC ECreateEPSGC( Display*, EPSID, unsigned long, EPSGCValues* ) { EPSGC egc = new EPSGCValues; egc->foreground = 0; egc->background = 1; egc->font_no = 0; egc->font_size = 0; return egc; } //---- EPSGCを解放する関数 ----------------------- void EFreeEPSGC( Display*, EPSGC egc ) { delete egc; } //---- EPSGCにForeground色を設定する関数 --------- void ESetForeground( Display*, EPSGC egc, u_long fg ) { egc->foreground = fg; } //---- EPSGCに fontを設定する関数 ---------------- void ESetFont( Display*, EPSGC egc, int _font_no, int _font_size ) { egc->font_no = _font_no; egc->font_size = _font_size; } //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // EPS描画関数の定義 //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* //---- EPSを開いて初期化する関数 ----------------- EPSID ECreateFile( Display*, const char* fname, u_int win_w, u_int win_h, u_int eps_w, u_int eps_h ) { EPSID eps = new EPSIDValues; eps_w = u_int(eps_w *MM2PT); eps_h = u_int(eps_w * win_h/win_w); eps->cugc = ECreateEPSGC(0,0,0,0); eps->DOT2PT = (double)eps_w/win_w; if( (eps->fptr = fopen( fname, "wt" )) == NULL ){ delete eps; return NULL; } fprintf( eps->fptr, "%%!PS-Adobe-2.0 EPSF-2.0\n" "%%%%BoundingBox: 0 0 %d %d\n", eps_w, eps_h ); fprintf( eps->fptr, "newpath 0 0 moveto %d 0 lineto %d %d lineto 0 %d lineto " "closepath clip\n", eps_w, eps_w, eps_h, eps_h ); fprintf( eps->fptr, "0 %d translate 0.125 -0.125 scale\n", eps_h ); fprintf( eps->fptr, "/Dict 200 dict def\n" "Dict begin\n" "Dict /mtrx matrix put\n" "/sc {scale} bind def\n" "/gr {grestore} bind def\n" "/gs {gsave} bind def\n" "/srgb {setrgbcolor} bind def\n" "/sd {setdash} bind def\n" "/slw {setlinewidth} bind def\n" "/slc {setlinecap} bind def\n" "/slj {setlinejoin} bind def\n" "/ff {findfont} bind def\n" "/sf {setfont} bind def\n" "/scf {scalefont} bind def\n" "/n {newpath} bind def\n" "/m {moveto} bind def\n" "/l {lineto} bind def\n" "/p {moveto 0 currentlinewidth rlineto stroke} bind def\n" "/cp {closepath} bind def\n" "/s {stroke} bind def\n" "/ef {eofill} bind def\n" "/sh {show} bind def\n" ); fprintf( eps->fptr, "/EllipseArc {\n" " /endangle exch def /startangle exch def\n" " /yrad exch def /xrad exch def\n" " /y exch def /x exch def\n" " /savematrix mtrx currentmatrix def\n" " x y translate xrad yrad sc 0 0 1 startangle endangle arc closepath\n" " savematrix setmatrix\n" "} def\n" ); return eps; } //---- EPSを閉じる関数 --------------------------- void ECloseFile( Display*, EPSID eps ) { fprintf( eps->fptr, "end\n" ); delete eps; } //---- 色を登録する関数 -------------------------- void EDefineColor( EPSID eps, EPSGC, u_long pixel, u_short red, u_short green, u_short blue ) { fprintf( eps->fptr, "/c%06lx {%5.3f %5.3f %5.3f srgb} bind def\n", pixel, (double)red/65535, (double)green/65535, (double)blue/65535 ); } //---- EPSGCを適宜出力する関数 ----------------- void EDrawEPSGC( EPSID eps, EPSGC egc ) { if( eps->cugc->foreground != egc->foreground ){ eps->cugc->foreground = egc->foreground; fprintf( eps->fptr, "c%06x\n", egc->foreground ); } } //---- Font形式を適宜出力する関数 -------------- void EDrawFont( EPSID eps, EPSGC egc ) { if( eps->cugc->font_no == egc->font_no && eps->cugc->font_size == egc->font_size ) return; eps->cugc->font_no = egc->font_no; eps->cugc->font_size = egc->font_size; fprintf( eps->fptr, "%s ff %d scf sf\n", EPS_Font_Names[egc->font_no], eps->Pt(egc->font_size) ); } //---- 点を描く関数 -------------------------- void EDrawPoint( Display*, EPSID eps, EPSGC egc, int x, int y ) { EDrawEPSGC( eps, egc ); fprintf( eps->fptr, "n %d %d p s\n", eps->Pt(x), eps->Pt(y) ); } //---- 線分を描く関数 ------------------------ void EDrawLine( Display*, EPSID eps, EPSGC egc, int x1, int y1, int x2, int y2 ) { EDrawEPSGC( eps, egc ); fprintf( eps->fptr, "n %d %d m %d %d l s\n", eps->Pt(x1), eps->Pt(y1), eps->Pt(x2), eps->Pt(y2) ); } //---- 長方形を描く関数 ---------------------- void EDrawRectangle( Display*, EPSID eps, EPSGC egc, int xo, int yo, u_int w, u_int h ) { EDrawEPSGC( eps, egc ); int x1, x2, y1, y2; x1 = eps->Pt(xo); y1 = eps->Pt(yo); x2 = eps->Pt(xo+w); y2 = eps->Pt(yo+h); fprintf( eps->fptr, "n %d %d m %d %d l %d %d l %d %d l cp s\n", x1, y1, x2, y1, x2, y2, x1, y2 ); } //---- 長方形を塗る関数 ---------------------- void EFillRectangle( Display*, EPSID eps, EPSGC egc, int xo, int yo, u_int w, u_int h ) { EDrawEPSGC( eps, egc ); int x1, x2, y1, y2; x1 = eps->Pt(xo); y1 = eps->Pt(yo); x2 = eps->Pt(xo+w); y2 = eps->Pt(yo+h); fprintf( eps->fptr, "n %d %d m %d %d l %d %d l %d %d l cp ef\n", x1, y1, x2, y1, x2, y2, x1, y2 ); } //---- 連続線分を描く関数 ------------------------- void EDrawLines( Display*, EPSID eps, EPSGC egc, XPoint p[], int np, int mode ) { EDrawEPSGC( eps, egc ); if( mode == CoordModePrevious ){ int px=p[0].x, py=p[0].y; for( int i=1 ; ifptr, "n %d %d m ", eps->Pt(p[0].x), eps->Pt(p[0].y) ); for( int i=1 ; ifptr, "%d %d l ", eps->Pt(p[i].x), eps->Pt(p[i].y) ); } fprintf( eps->fptr, "s\n" ); } //---- 多角形を描く関数 ---------------------- void EDrawPolygon( Display*, EPSID eps, EPSGC egc, XPoint p[], int np, int mode ) { EDrawEPSGC( eps, egc ); if( mode == CoordModePrevious ){ int px=p[0].x, py=p[0].y; for( int i=1 ; ifptr, "n %d %d m ", eps->Pt(p[0].x), eps->Pt(p[0].y) ); for( int i=1 ; ifptr, "%d %d l ", eps->Pt(p[i].x), eps->Pt(p[i].y) ); } fprintf( eps->fptr, "cp s\n" ); } //---- 多角形を塗る関数 ---------------------- void EFillPolygon( Display*, EPSID eps, EPSGC egc, XPoint p[], int np, int, int mode ) { EDrawEPSGC( eps, egc ); if( mode == CoordModePrevious ){ int px=p[0].x, py=p[0].y; for( int i=1 ; ifptr, "n %d %d m ", eps->Pt(p[0].x), eps->Pt(p[0].y) ); for( int i=1 ; ifptr, "%d %d l ", eps->Pt(p[i].x), eps->Pt(p[i].y) ); } fprintf( eps->fptr, "cp ef\n" ); } //---- 円弧を描く関数 ------------------------ // ang1, ang2は意味を持たず、真円、真楕円のみを描く //------------------------------------------------ void EDrawArc( Display*, EPSID eps, EPSGC egc, int xo, int yo, u_int w, u_int h, int, int ) { EDrawEPSGC( eps, egc ); int xc, yc, a, b; a = eps->Pt(w/2); b = eps->Pt(h/2); xc = eps->Pt(xo) + a; yc = eps->Pt(yo) + b; if( w == h ){ fprintf( eps->fptr, "n %d %d %d 0 360 arc s\n", xc, yc, a ); }else{ fprintf( eps->fptr, "n %d %d %d %d 0 360 EllipseArc s\n", xc, yc, a, b ); } } //---- 円弧を塗る関数 ------------------------ // ang1, ang2は意味を持たず、真円、真楕円のみを描く //------------------------------------------------ void EFillArc( Display*, EPSID eps, EPSGC egc, int xo, int yo, u_int w, u_int h, int ang1, int ang2 ) { EDrawEPSGC( eps, egc ); int xc, yc, a, b; a = eps->Pt(w/2); b = eps->Pt(h/2); xc = eps->Pt(xo) + a; yc = eps->Pt(yo) + b; if( w == h ){ fprintf( eps->fptr, "n %d %d %d %d %d arc ef\n", xc, yc, a, ang1, ang2 ); }else{ fprintf( eps->fptr, "n %d %d %d %d %d %d EllipseArc ef\n", xc, yc, a, b, ang1, ang2 ); } } //---- 文字を描く関数(英数字のみ) ------------ void EDrawString( Display*, EPSID eps, EPSGC egc, int x, int y, const char* str, int ) { EDrawEPSGC( eps, egc ); EDrawFont( eps, egc ); fprintf( eps->fptr, "n %d %d m (%s) gs 1 -1 sc sh gr\n", eps->Pt(x), eps->Pt(y), str ); }