⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 export.cpp

📁 Linux/windows 环境下跨平台开发程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
	wmfRect rc = {7, 0x41B, iy2, ix2, iy1, ix1};
	
	write(oFile, &rc, 14);
}

void
ExportWMF::wmfSelectObject(unsigned short o)
{
	wmfObjShort so  = {4, 0x12D, o};

	write(oFile, &so, 8);
}

void
ExportWMF::wmfSetBkColor(DWORD col)
{
	wmfObjCol co = {5, 0x201};

	write(oFile, &co, 6);
	write(oFile, &col, 4);
}

void
ExportWMF::wmfSetBkMode(unsigned m)
{
	wmfObjShort mo = {5, 0x102, m & 0xffff};
	unsigned short p;

	write(oFile, &mo, 8);
	p = m>>16;
	write(oFile, &p, 2);
}

//cmSetMapMode()
//cmSetPolyFillMode()

void
ExportWMF::wmfSetTextAlign(unsigned a)
{
	wmfObjShort ao = {5, 0x12E, a & 0xffff};
	unsigned short p;

	write(oFile, &ao, 8);
	p = a>>16;
	write(oFile, &p, 2);
}

void
ExportWMF::wmfSetTextColor(DWORD col)
{
	wmfObjCol tc = {5, 0x209};

	write(oFile, &tc, 6);
	write(oFile, &col, 4);
}

//cmSetWindowExt()
//cmSetWindowOrg()

void
ExportWMF::wmfTextOut(unsigned short ix1, unsigned short iy1, char *txt, unsigned short cb)
{
	wmfObjShort to  = {6, 0x521, cb};
	unsigned short le, v[2] = {iy1, ix1};

	le = cb &1 ? cb+1 : cb;
	to.Size += le>>1;
	write(oFile, &to, 8);
	write(oFile, txt, le);
	write(oFile, &v, 4);	
	if(to.Size > rec_size) rec_size = to.Size;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Entry point to export graph to Windows Meta File
void DoExportWmf(GraphObj *g, char *FileName, float res, DWORD flags)
{
	ExportWMF *ex;
	
	ex = new ExportWMF(g, FileName, res, flags);
	if(ex->StartPage()) {
		g->DoPlot(ex);
		ex->EndPage();
		}
	delete(ex);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// export to *.svg file (scalable vector graphic)
// this code is based on information from the following books
// H. Spona, 'Das Einsteigerseminar SVG-Webgrafiken mit XML',
//     vmi, ISBN 3-8266-7181-3
// M. Salathe, 'SVG Scalabe Vector Graphics ...f黵 professionelle Einsteiger',
//     M&T, ISBN 3-8272-6188-0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class ExportSVG:public anyOutput {
public:
	HatchOut *hgo;

	ExportSVG(GraphObj *g, char *FileName, DWORD flags);
	~ExportSVG();
	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:
	int iLineWidth;
	bool bUseGroupLine, bOutputPending;
	GraphObj *go;
	char *name, indent[80], output[120], tHatchStyle[80];
	FILE *oFile;
	DWORD flags;

	void Indent(bool ind);
	void AddToOutput(char *txt);
	char *ColName(DWORD col);
};

ExportSVG::ExportSVG(GraphObj *g, char *FileName, DWORD flg)
{
	hgo =0L;
	DeskRect.left = DeskRect.top = 0;
	DeskRect.right = DeskRect.bottom = 0x4fffffff;
	dFillCol = 0xffffffffL;
	hres = vres = 1000.0f;
	go = g;
	if(FileName)name = strdup(FileName);
	else name = 0L;
	oFile = 0L;
	flags = flg;
	strcpy(indent, "   ");
	strcpy(tHatchStyle, "style=\"stroke:black; stroke-width:1\"");
	bUseGroupLine = false;
}

ExportSVG::~ExportSVG()
{
	if(hgo) delete hgo;
	if(name) free(name);
}

bool
ExportSVG::SetLine(LineDEF *lDef)
{
	LineWidth = lDef->width;
	if(1 >(iLineWidth  = iround(un2fix(lDef->width)))) iLineWidth = 1;
	dPattern = lDef->pattern;
	dLineCol = lDef->color;
	RLP.finc = (float)(256.0/un2fix(lDef->patlength*8.0));
	RLP.fp = 0.0;
	return true;
}

bool
ExportSVG::SetFill(FillDEF *fill)
{
	int iL; 

	if(!fill) return false;
	if((fill->type & 0xff) != FILL_NONE) {
		if(!hgo) hgo = new HatchOut(this);
		if(hgo) hgo->SetFill(fill);
		if(fill->hatch) {
			if(1 >(iL  = iround(un2fix(fill->hatch->width)))) iL = 1;
			sprintf(tHatchStyle, "style=\"fill:none; stroke:%s; stroke-width:%d\"",
				ColName(fill->hatch->color), iL);
			}
		}
	else {
		if(hgo) delete hgo;
		hgo = 0L;
		}
	dFillCol = fill->color;
	dFillCol2 = fill->color2;
	return true;
}

bool
ExportSVG::SetTextSpec(TextDEF *set)
{
	if(!set->iSize && set->fSize > 0.0f) set->iSize = un2iy(set->fSize);
	if(!set->iSize) return false;
	return anyOutput::SetTextSpec(set);
}

bool 
ExportSVG::StartPage()
{
	int w, h;

	if(!go) return false;
	w = un2ix(go->GetSize(SIZE_GRECT_RIGHT) - go->GetSize(SIZE_GRECT_LEFT))/10;
	h = un2iy(go->GetSize(SIZE_GRECT_BOTTOM) - go->GetSize(SIZE_GRECT_TOP))/10;
	w++; h++;
	if(name) {
		oFile = fopen(name, "w");
		if(!oFile) {
			ErrorBox("Could not open\noutput file!");
			return false;
			}
		}
	else oFile = stdout;
	if(flags & 0x01) fprintf(oFile, "Content-Type: image/svg+xml\n\n");
	VPorg.fy = -un2fiy(go->GetSize(SIZE_GRECT_TOP));
	VPorg.fx = -un2fix(go->GetSize(SIZE_GRECT_LEFT));
	fprintf(oFile, "<?xml version=\"1.0\"?>\n"
		"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20001102//EN\"\n"
		"   \"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd\">\n");
	fprintf(oFile, "<svg %s width=\"%d\" height=\"%d\" style=\"stroke-linecap:round\">\n", 
		defs.svgAttr ? defs.svgAttr : "", w, h);
	if(defs.svgScript) {
		fprintf(oFile, "<defs>\n<script type=\"text/ecmascript\"><![CDATA[\n");
		fprintf(oFile, "\n%s\n", defs.svgScript);
		fprintf(oFile, "\n]]></script>\n</defs>\n\n");
		}
	fprintf(oFile, "<g transform=\"scale(0.1)\" style=\"font-family:Helvetica\">\n");
	return true;
}

bool
ExportSVG::EndPage()
{
	fprintf(oFile, "</g>\n</svg>\n");
	fclose (oFile);
	return true;
}

bool
ExportSVG::oCircle(int x1, int y1, int x2, int y2, char* nam)
{
	if(x1 > x2) Swap(x1, x2);
	if(y1 > y2) Swap(y1, y2);

	if(hgo){
		fprintf(oFile, "%s<g>  <!-- %s with pattern -->\n", indent, 
			(x2-x1) == (y2-y1) ? "circle" : "ellipse");
		Indent(true);
		}
	fprintf(oFile, "%s<%s%s%s%s cx=\"%d\" cy=\"%d\" ", indent,
		(x2-x1) == (y2-y1) ? "circle" : "ellipse", nam? " name=\"" : "", 
		nam ? nam : "", nam ? "\"" : "", (x1+x2)/2, (y1+y2)/2);
	if((x2-x1) == (y2-y1)) fprintf(oFile, "r=\"%d\"", (x2-x1)/2);
	else fprintf(oFile, "rx=\"%d\" ry=\"%d\"", (x2-x1)/2, (y2-y1)/2);
	fprintf(oFile, " style=\"fill:%s; stroke:%s; stroke-width:%d\"/>\n",
		ColName(dFillCol), ColName(dLineCol), iLineWidth);
	if(hgo) {
		fprintf(oFile, "%s<g %s>  <!-- hatch -->\n", indent, tHatchStyle);
		Indent(true);
		bUseGroupLine = true;
		hgo->oCircle(x1, y1, x2, y2);
		Indent(false);
		bUseGroupLine = false;
		fprintf(oFile, "%s</g>\n", indent);
		Indent(false);
		fprintf(oFile, "%s</g>\n", indent);
		}
	return true;
}

bool
ExportSVG::oPolyline(POINT *pts, int cp, char *nam)
{
	int i;
	char tmptxt[40];

	if(cp < 2) return false;
	if (dPattern){
		fprintf(oFile, "%s<g style=\"stroke:%s; stroke-width:%d; stroke-linecap:round\">"
			"<!-- pattern line -->\n", indent, ColName(dLineCol), iLineWidth);
		Indent(true);
		bUseGroupLine = true;
		for (i = 1; i < cp; i++) PatLine(pts[i-1], pts[i]);
		Indent(false);
		fprintf(oFile, "%s</g>\n", indent);
		bUseGroupLine = false;
		}
	else {
		if(cp == 2) return oSolidLine(pts);
		bOutputPending = false;
		sprintf(output, "<polyline points=\""); 
		for(i = 0; i < cp; i++) {
			sprintf(tmptxt, "%d %d ", pts[i].x, pts[i].y);
			AddToOutput(tmptxt);
			}
		i = strlen(output);
		if(i) output[i-1] = 0;
		strcat(output, "\"");
		if(!bUseGroupLine) {
			strcpy(tmptxt, " style = \"fill:none; ");
			AddToOutput(tmptxt);
			sprintf(tmptxt, "; stroke:%s; ", ColName(dLineCol));
			AddToOutput(tmptxt);
			sprintf(tmptxt, "stroke-width:%d\"/>",iLineWidth);
			AddToOutput(tmptxt);
			}
		else strcat(output, "/>");
		fprintf(oFile, "%s%s\n", indent, output);
		if(bOutputPending)Indent(false);
		}
	return true;
}

bool
ExportSVG::oRectangle(int x1, int y1, int x2, int y2, char *nam)
{
	if(x1 > x2) Swap(x1, x2);
	if(y1 > y2) Swap(y1, y2);
	if(hgo){
		fprintf(oFile, "%s<g>  <!-- rectangle with pattern -->\n", indent);
		Indent(true);
		}
	fprintf(oFile, "%s<rect%s%s%s x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "
		"style=\"fill:%s; stroke:%s; stroke-width:%d\"/>\n",
		indent, nam? " name=\"" : "", nam ? nam : "", nam ? "\"" : "",
		x1, y1, x2-x1-1, y2-y1-1, ColName(dFillCol), ColName(dLineCol), iLineWidth);
	if(hgo) {
		fprintf(oFile, "%s<g %s>  <!-- hatch -->\n", indent, tHatchStyle);
		Indent(true);
		bUseGroupLine = true;
		hgo->oRectangle(x1, y1, x2, y2, 0L);
		Indent(false);
		bUseGroupLine = false;
		fprintf(oFile, "%s</g>\n", indent);
		Indent(false);
		fprintf(oFile, "%s</g>\n", indent);
		}
	return true;
}

bool
ExportSVG::oSolidLine(POINT *p)
{
	if(bUseGroupLine) fprintf(oFile, "%s<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"/>\n",
		indent, p[0].x, p[0].y, p[1].x, p[1].y);
	else fprintf(oFile, "%s<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" "
		"style=\"stroke:%s; stroke-width:%d\"/>\n",
		indent, p[0].x, p[0].y, p[1].x, p[1].y, ColName(dLineCol), iLineWidth);
	return true;
}

bool
ExportSVG::oTextOut(int x, int y, char *txt, int cb)
{
	int i, h, ix, iy;
	char tmptxt[140], *nt;

	if(!txt || !txt[0]) return false;
	else h = TxtSet.iSize;
	if(TxtSet.Align & TXA_VCENTER) iy = y + h/3;
	else if(TxtSet.Align & TXA_VBOTTOM) iy = y;
	else iy = y + iround(h * 0.8);
	ix = x;
	if((TxtSet.Style & TXS_SUB) || (TxtSet.Style & TXS_SUPER)) h = iround((double)TxtSet.iSize * 0.8);
	if(TxtSet.Style & TXS_SUB) {
		if((TxtSet.Align & TXA_VCENTER) == TXA_VCENTER) iy +=un2iy(TxtSet.fSize*0.4);
		else if((TxtSet.Align & TXA_VBOTTOM) == TXA_VBOTTOM) iy += un2iy(TxtSet.fSize*0.2);
		else if((TxtSet.Align & TXA_VTOP) == TXA_VTOP) iy += un2iy(TxtSet.fSize*.6);
		}
	else if(TxtSet.Style & TXS_SUPER) {
		if((TxtSet.Align & TXA_VCENTER) == TXA_VCENTER) iy -= un2iy(TxtSet.fSize*0.4);
		else if((TxtSet.Align & TXA_VBOTTOM) == TXA_VBOTTOM) iy -= un2iy(TxtSet.fSize*0.6);
		else if((TxtSet.Align & TXA_VTOP) == TXA_VTOP) iy -= un2iy(TxtSet.fSize*0.2);
		}
	sprintf(output, "<text x=\"%d\" y=\"%d\" ", ix, iy);
	if(fabs(TxtSet.RotBL) >.01 || fabs(TxtSet.RotCHAR) >.01) {
		sprintf(tmptxt,"transform=\"rotate(%.0f,%d,%d)\" ", -TxtSet.RotBL, ix, iy);
		strcat(output, tmptxt);
		}
	strcpy(tmptxt, "style=\"font-family:");
	switch(TxtSet.Font) {
	case FONT_TIMES:	strcat(tmptxt, "Times;");		break;
	case FONT_COURIER:	strcat(tmptxt, "Courier;");		break;
	default:			strcat(tmptxt, "Helvetica;");	break;
		}
	if(TxtSet.Style & TXS_ITALIC) strcat(tmptxt, " font-style:italic;");
	if(TxtSet.Style & TXS_BOLD) strcat(tmptxt, " font-weight:bold;");
	if(TxtSet.Style & TXS_UNDERLINE) strcat(tmptxt, " text-decoration:underline;");
	AddToOutput(tmptxt);
	sprintf(tmptxt, " fill:%s; stroke:%s; ", ColName(TxtSet.ColTxt),
		ColName(TxtSet.ColTxt));
	AddToOutput(tmptxt);
	sprintf(tmptxt, "font-size:%d; text-anchor:%s \">", h, 
		(TxtSet.Align & TXA_HRIGHT) ? "end" : (TxtSet.Align & TXA_HCENTER) ? "middle":"start");
	AddToOutput(tmptxt);
	nt = str2xml(txt);
	if((TxtSet.Style & TXS_SUB) || (TxtSet.Style & TXS_SUPER)) {
		for(i = strlen(nt)+6, nt[i+1]=0; i > 5; i--) {
			nt[i] = nt[i-6];
			}
		nt[0] = '&';		nt[1] = 'n';		nt[2] = 'b';
		nt[3] = 's';		nt[4] = 'p';		nt[5] = ';';
		}
	if((strlen(indent)+strlen(nt)+strlen(output)) <110) strcat(output, nt);
	else {
		fprintf(oFile, "%s%s\n", indent, output);
		strcpy(output, nt);
		}
	if((strlen(indent) + strlen(output)) <104) 
		fprintf(oFile, "%s%s</text>\n", indent, output);
	else {
		fprintf(oFile, "%s%s\n", indent, output);
		fprintf(oFile, "</text>\n");
		}
	return true;
}

bool
ExportSVG::oPolygon(POINT *pts, int cp, char *nam)
{
	int i;
	char tmptxt[40];

	if(cp <3) return false;
	if(hgo){
		fprintf(oFile, "%s<g>  <!-- polygon with pattern -->\n", indent);
		Indent(true);
		}
	bOutputPending = false;
	sprintf(output, "<polygon%s%s%s points=\"",
		nam? " name=\"" : "", nam ? nam : "", nam ? "\"" : ""); 
	for(i = 0; i < cp; i++) {
		sprintf(tmptxt, "%d %d ", pts[i].x, pts[i].y);
		AddToOutput(tmptxt);
		}
	i = strlen(output);
	if(i) output[i-1] = 0;
	strcat(output, "\" ");
	sprintf(tmptxt, "style=\"fill:%s; ", ColName(dFillCol));
	AddToOutput(tmptxt);
	sprintf(tmptxt, "stroke:%s; ", ColName(dLineCol));
	AddToOutput(tmptxt);
	sprintf(tmptxt, "stroke-width:%d\"/>",iLineWidth);
	AddToOutput(tmptxt);
	if(output)fprintf(oFile, "%s%s\n", indent, output);
	if(bOutputPending)Indent(false);
	if(hgo) {
		fprintf(oFile, "%s<g %s>  <!-- hatch -->\n", indent, tHatchStyle);
		Indent(true);
		bUseGroupLine = true;
		hgo->oPolygon(pts, cp);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -