📄 export.cpp
字号:
Indent(false);
bUseGroupLine = false;
fprintf(oFile, "%s</g>\n", indent);
Indent(false);
fprintf(oFile, "%s</g>\n", indent);
}
return true;
}
void
ExportSVG::Indent(bool ind)
{
int i = strlen(indent);
if(i > 20 && ind) return;
if(ind) strcat(indent, " ");
else if(i>2) indent[i-3] = 0;
}
void
ExportSVG::AddToOutput(char *txt)
{
if((strlen(txt) + strlen(output) + strlen(indent)) < 110)strcat(output, txt);
else {
fprintf(oFile, "%s%s\n", indent, output);
if(!bOutputPending) Indent(true);
bOutputPending = true;
strcpy(output, txt);
}
}
char *
ExportSVG::ColName(DWORD col)
{
static char txt1[20], txt2[20];
static int sw;
switch(col) {
case 0x00000000: return "black";
case 0x000000ff: return "red";
case 0x0000ff00: return "lime";
case 0x0000ffff: return "yellow";
case 0x00ff0000: return "blue";
case 0x00ff00ff: return "magenta";
case 0x00ffff00: return "cyan";
case 0x00ffffff: return "white";
}
sw++;
if(sw & 0x01) {
sprintf(txt1, "rgb(%d,%d,%d)", col & 0xff, (col>>8) & 0xff, (col>>16) &0xff);
return txt1;
}
else {
sprintf(txt2, "rgb(%d,%d,%d)", col & 0xff, (col>>8) & 0xff, (col>>16) &0xff);
return txt2;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Entry point to export graph to *.svg
void DoExportSvg(GraphObj *g, char *FileName, DWORD flags)
{
ExportSVG *ex;
ex = new ExportSVG(g, FileName, flags);
if(ex->StartPage()) {
g->DoPlot(ex);
ex->EndPage();
}
HideTextCursor();
delete(ex);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// export to *.eps file (encapsulated post script).
// This code is based on information from the following book
// G. Born, 'Referenzhandbuch Dateiformate',
// Addison-Wesley ISBN 3-89319-815-6
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class ExportEPS:public anyOutput {
public:
HatchOut *hgo;
ExportEPS(GraphObj *g, char *FileName, DWORD flags);
~ExportEPS();
bool SetLine(LineDEF *lDef);
bool SetFill(FillDEF *fill);
bool SetTextSpec(TextDEF *set);
bool StartPage();
bool EndPage();
bool oCircle(int x1, int y1, int x2, int y2, char* nam = 0L);
bool oPolyline(POINT * pts, int cp, char *nam = 0L);
bool oRectangle(int x1, int y1, int x2, int y2, char *nam = 0L);
bool oSolidLine(POINT *p);
bool oTextOut(int x, int y, char *txt, int cb);
bool oPolygon(POINT *pts, int cp, char *nam = 0L);
private:
RECT BoundBox;
fRECT SolLines[2000];
int nSolLines;
GraphObj *go;
char *name;
FILE *oFile;
DWORD CurrCol;
float ix2eps(int x);
float iy2eps(int y);
char *col2eps(DWORD color);
void FlushSolLines();
void AddSolLine(float x1, float y1, float x2, float y2);
};
ExportEPS::ExportEPS(GraphObj *g, char *FileName, DWORD flags)
{
hgo =0L;
nSolLines = 0;
DeskRect.left = DeskRect.top = 0;
DeskRect.right = DeskRect.bottom = 0x4fffffff;
dFillCol = 0xffffffffL;
hres = vres = 720.0f;
go = g;
if(FileName)name = strdup(FileName);
else name = 0L;
oFile = 0L;
}
ExportEPS::~ExportEPS()
{
if(hgo) delete hgo;
if(name) free(name);
}
bool
ExportEPS::SetLine(LineDEF *lDef)
{
if(LineWidth != lDef->width || dLineCol != lDef->color) {
FlushSolLines();
LineWidth = lDef->width;
CurrCol = dLineCol = lDef->color;
fprintf(oFile, "\nnewpath %.1f setlinewidth %s ",
un2fix(LineWidth)/10.0f, col2eps(dLineCol));
}
dPattern = lDef->pattern;
RLP.finc = (float)(256.0/un2fix(lDef->patlength*8.0));
RLP.fp = 0.0;
return true;
}
bool
ExportEPS::SetFill(FillDEF *fill)
{
if(!fill) return false;
if((fill->type & 0xff) != FILL_NONE) {
if(!hgo) hgo = new HatchOut(this);
if(hgo) hgo->SetFill(fill);
}
else {
if(hgo) delete hgo;
hgo = 0L;
}
dFillCol = fill->color;
dFillCol2 = fill->color2;
return true;
}
bool
ExportEPS::SetTextSpec(TextDEF *set)
{
char FontName[30];
if(!set->iSize && set->fSize > 0.0f) set->iSize = un2iy(set->fSize);
if(!set->iSize) return false;
if(set->iSize == TxtSet.iSize && set->Style == TxtSet.Style &&
set->Font == TxtSet.Font){
anyOutput::SetTextSpec(set);
return true;
}
anyOutput::SetTextSpec(set);
switch(TxtSet.Font) {
case FONT_TIMES: sprintf(FontName, "(Times"); break;
case FONT_COURIER: sprintf(FontName, "(Courier"); break;
default: sprintf(FontName, "(Helvetica"); break; //Helvetica
}
if(TxtSet.Style & TXS_BOLD) strcat(FontName, "-Bold");
if(TxtSet.Style & TXS_ITALIC) strcat(FontName, "-Italic");
strcat(FontName, ")");
fprintf(oFile, "\n%s findfont %d scalefont setfont ", FontName, TxtSet.iSize/10);
return true;
}
bool
ExportEPS::StartPage()
{
time_t ti;
if(!go) return false;
ti = time(0L);
BoundBox.top = BoundBox.left = 0;
BoundBox.right = un2ix(go->GetSize(SIZE_GRECT_RIGHT) - go->GetSize(SIZE_GRECT_LEFT))/10;
BoundBox.bottom = un2iy(go->GetSize(SIZE_GRECT_BOTTOM) - go->GetSize(SIZE_GRECT_TOP))/10;
BoundBox.right++; BoundBox.bottom++;
if(name) {
oFile = fopen(name, "w");
if(!oFile) {
ErrorBox("Could not open\noutput file!");
return false;
}
}
else oFile = stdout;
VPorg.fy = -un2fiy(go->GetSize(SIZE_GRECT_TOP));
VPorg.fx = -un2fix(go->GetSize(SIZE_GRECT_LEFT));
fprintf(oFile, "%%!PS-Adobe-1.0 EPSF-3.0\n"
"%%%%BoundingBox: %d %d %d %d\n", BoundBox.left, BoundBox.top,
BoundBox.right, BoundBox.bottom);
fprintf(oFile, "%%%%Title: %s\n", name);
fprintf(oFile,"%%%%Creator: RLPlot version "SZ_VERSION"\n");
fprintf(oFile,"%%%%CreationDate: %s", ctime(&ti));
fprintf(oFile, "%%%%Pages: 1\n%%%%DocumentFonts: (atend)\n");
fprintf(oFile, "%%%%EndComments\n"
"%%%%BeginProlog\n"
"%%%%EndProlog\n"
"%%%%Page: 1 1");
return true;
}
bool
ExportEPS::EndPage()
{
fprintf(oFile, "\nshowpage\n%%%%Trailer\n");
fprintf(oFile, "%%%%DocumentFonts: Helvetica\n");
fprintf(oFile, "%%%%EOF\n");
fclose (oFile);
return true;
}
bool
ExportEPS::oCircle(int x1, int y1, int x2, int y2, char* nam)
{
FlushSolLines();
if((x2 - x1) == (y2 -y1)) {
fprintf(oFile, "\nnewpath %.1f %.1f %.1f 0 360 arc ", ix2eps((x1+x2)/2),
iy2eps((y1+y2)/2), (float)(x2-x1)/20.0f);
fprintf(oFile, "%s fill", col2eps(CurrCol = dFillCol));
if(hgo){
hgo->oCircle(x1, y1, x2, y2);
FlushSolLines();
}
fprintf(oFile, "\nnewpath %.1f %.1f %.1f 0 360 arc ", ix2eps((x1+x2)/2),
iy2eps((y1+y2)/2), (float)(x2-x1)/20.0f);
fprintf(oFile, "%s stroke", col2eps(CurrCol = dLineCol));
}
else if(x1 != x2 && y1 != y2){
fprintf(oFile, "\ngsave %.1f %.1f translate", (ix2eps((x1+x2)>>1)),
(iy2eps((y1+y2)>>1)));
if(abs(x2-x1) > abs(y2-y1)) {
fprintf(oFile, " 1 %lf scale", fabs(((double)(y2-y1))/((double)(x2-x1))));
fprintf(oFile, " 0 0 %.1lf 0 360 arc ", fabs(((double)(x2-x1))/20.0));
fprintf(oFile, "%s fill", col2eps(CurrCol = dFillCol));
fprintf(oFile, "\n 0 0 %.1lf 0 360 arc ", fabs(((double)(x2-x1))/20.0));
}
else {
fprintf(oFile, " %lf 1 scale", fabs(((double)(x2-x1))/((double)(y2-y1))));
fprintf(oFile, " 0 0 %.1lf 0 360 arc ", fabs(((double)(y2-y1))/20.0));
fprintf(oFile, "%s fill", col2eps(CurrCol = dFillCol));
fprintf(oFile, "\n 0 0 %.1lf 0 360 arc ", fabs(((double)(y2-y1))/20.0));
}
fprintf(oFile, "%s stroke grestore", col2eps(CurrCol = dLineCol));
if(hgo){
hgo->oCircle(x1, y1, x2, y2);
FlushSolLines();
}
}
return true;
}
bool
ExportEPS::oPolyline(POINT * pts, int cp, char *nam)
{
int i, j;
if(cp <1) return false;
if (dPattern){
for (i = 1; i < cp; i++) PatLine(pts[i-1], pts[i]);
return true;
}
else if(cp == 2) return oSolidLine(pts);
FlushSolLines();
if(CurrCol != dLineCol) {
fprintf(oFile, "\n%s ", col2eps(CurrCol = dLineCol));
}
for(i = cp-1, j = 0; i >= 0; i--, j++) {
if(!(j & 0x07)) fprintf(oFile, "\n");
fprintf(oFile, " %.1f %.1f", ix2eps(pts[i].x), iy2eps(pts[i].y));
}
fprintf(oFile, " moveto %d {lineto} repeat stroke ", cp-1);
return true;
}
bool
ExportEPS::oRectangle(int x1, int y1, int x2, int y2, char *nam)
{
FlushSolLines();
fprintf(oFile, "\n%.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f moveto 4 {lineto}"
" repeat %s fill", ix2eps(x1), iy2eps(y1), ix2eps(x1), iy2eps(y2), ix2eps(x2), iy2eps(y2),
ix2eps(x2), iy2eps(y1), ix2eps(x1), iy2eps(y1), col2eps(CurrCol = dFillCol));
if(hgo) hgo->oRectangle(x1, y1, x2, y2, 0L);
fprintf(oFile, "\n%.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f moveto 4 {lineto}"
" repeat %s stroke", ix2eps(x1), iy2eps(y1), ix2eps(x1), iy2eps(y2), ix2eps(x2), iy2eps(y2),
ix2eps(x2), iy2eps(y1), ix2eps(x1), iy2eps(y1), col2eps(CurrCol = dLineCol));
return true;
}
bool
ExportEPS::oSolidLine(POINT *p)
{
if(CurrCol != dLineCol) {
FlushSolLines();
fprintf(oFile, "\n%s ", col2eps(CurrCol = dLineCol));
}
AddSolLine(ix2eps(p[0].x), iy2eps(p[0].y), ix2eps(p[1].x), iy2eps(p[1].y));
return true;
}
bool
ExportEPS::oTextOut(int x, int y, char *txt, int cb)
{
int h, ix, iy, w;
float fx, fy;
FlushSolLines();
oGetTextExtent(txt, cb, &w, &h);
if(TxtSet.Align & TXA_VCENTER) iy = y + h/3;
else if(TxtSet.Align & TXA_VBOTTOM) iy = y;
else iy = y + iround(h*.8);
if(TxtSet.Align & TXA_HRIGHT) ix = x-w;
else if(TxtSet.Align & TXA_HCENTER) ix = x-w/2;
else ix = x;
fprintf(oFile,"\n");
if(fabs(TxtSet.RotBL) >.01 || fabs(TxtSet.RotCHAR) >.01) {
fprintf(oFile, "gsave %.1f %.1f translate %f rotate %.1f %.1f moveto\n",
ix2eps(x), iy2eps(y), TxtSet.RotBL, (float)(ix-x)/10.0f, (float)(iy-y)/-10.0f);
if(CurrCol != TxtSet.ColTxt) fprintf(oFile, "%s ", col2eps(CurrCol = TxtSet.ColTxt));
fprintf(oFile, "(%s) show grestore ", txt);
}
else {
fx = ix2eps(ix); fy = iy2eps(iy);
if(CurrCol != TxtSet.ColTxt) fprintf(oFile, "%s ", col2eps(CurrCol = TxtSet.ColTxt));
fprintf(oFile,"%.1f %.1f moveto (%s) show ", fx, fy, txt);
}
return true;
}
bool
ExportEPS::oPolygon(POINT *pts, int cp, char *nam)
{
int i, j;
if(cp <1) return false;
if(cp == 2) return oSolidLine(pts);
FlushSolLines();
for(i = cp-1, j = 0; i >= 0; i--, j++) {
if(!(j & 0x07)) fprintf(oFile, "\n");
fprintf(oFile, " %.1f %.1f", ix2eps(pts[i].x), iy2eps(pts[i].y));
}
fprintf(oFile, " moveto %d {lineto} repeat %s fill ", cp-1, col2eps(CurrCol = dFillCol));
if(hgo) hgo->oPolygon(pts, cp);
return oPolyline(pts, cp);
}
float
ExportEPS::ix2eps(int x)
{
return (float)x/10.0f;
}
float
ExportEPS::iy2eps(int y)
{
return (float)y/-10.0f + (float)BoundBox.bottom;
}
char *
ExportEPS::col2eps(DWORD color)
{
static char txt[50];
char tmptxt[10];
float r, g, b;
r = (float)(color & 0xff)/255.0f;
g = (float)((color>>8)&0xff)/255.0f;
b = (float)((color>>16)&0xff)/255.0f;
WriteFloatToBuff(tmptxt, r); strcpy(txt, tmptxt+1);
WriteFloatToBuff(tmptxt, g); strcat(txt, tmptxt);
WriteFloatToBuff(tmptxt, b); strcat(txt, tmptxt);
strcat(txt, " setrgbcolor");
return txt;
}
void
ExportEPS::FlushSolLines()
{
int i, j;
if(nSolLines <1) {
nSolLines = 0;
return;
}
if(nSolLines == 1) {
fprintf(oFile, "\n%.1f %.1f moveto %.1f %.1f lineto stroke ",
SolLines[0].Ymin, SolLines[0].Ymax, SolLines[0].Xmin, SolLines[0].Xmax);
nSolLines = 0;
return;
}
for(i = nSolLines-1, j = 0; i >=0; i--, j++) {
if(!(j & 0x03)) fprintf(oFile, "\n");
fprintf(oFile, " %.1f %.1f %.1f %.1f", SolLines[i].Xmin, SolLines[i].Xmax,
SolLines[i].Ymin, SolLines[i].Ymax);
}
if(j > 8 && ((j & 0x3) >=2 || (j & 0x03) == 0)) fprintf(oFile, "\n");
fprintf(oFile, " %d {moveto lineto} repeat stroke ", nSolLines);
nSolLines = 0;
}
void
ExportEPS::AddSolLine(float x1, float y1, float x2, float y2)
{
if(nSolLines >= 2000) FlushSolLines();
SolLines[nSolLines].Ymin = x1; SolLines[nSolLines].Ymax = y1;
SolLines[nSolLines].Xmin = x2; SolLines[nSolLines].Xmax = y2;
nSolLines++;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Entry point to export graph to *.eps
void DoExportEps(GraphObj *g, char *FileName, DWORD flags)
{
ExportEPS *ex;
ex = new ExportEPS(g, FileName, flags);
if(ex->StartPage()) {
g->DoPlot(ex);
ex->EndPage();
}
delete(ex);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -