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

📄 export.cpp

📁 Linux/windows 环境下跨平台开发程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//Export.cpp, Copyright (c) 2002, 2003, 2004 R.Lackner
//export graph files
//
//    This file is part of RLPlot.
//
//    RLPlot is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//    RLPlot 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 General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with RLPlot; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
#include "rlplot.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <fcntl.h>				//file open flags
#include <sys/stat.h>			//I/O flags

#ifdef _WINDOWS
	#include <io.h>					//for read/write
#else
	#define O_BINARY 0x0
	#include <unistd.h>
#endif

extern Default defs;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// export to *.wmf file (windows meta file)
// this code is based on information from the following books
// G. Born, 'Referenzhandbuch Dateiformate', 
//     Addison-Wesley ISBN 3-89319-815-6
// T. Hogan, 'Die PC-referenz f黵 Programmierer',
//     Microsoft Press: Systema Verlag GmbH ISBN 3-89390-250-3
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef struct {
	unsigned short mtType, mtHeader, mtVersion, mtSize0, mtSize1, mtNoObj;
	unsigned mtMaxRec;
	unsigned short mtnoPar;
}wmf_header;

class ExportWMF:public anyOutput {
public:
	HatchOut *hgo;

	ExportWMF(GraphObj *g, char *FileName, float res, DWORD flags);
	~ExportWMF();
	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 oFile;
	unsigned file_size, rec_size;
	wmf_header header;
	unsigned short currGDIobj, maxGDIobj;
	unsigned short hPen, hBrush, hFont;
	GraphObj *go;
	char *name;

	unsigned short wmfCreateSolidBrush(DWORD color);
	unsigned short wmfCreateFontIndirect(short, short, short, short, short, unsigned char,
		unsigned char, unsigned char, unsigned char, unsigned char, unsigned char,
		unsigned char, unsigned char, char *);
	unsigned short wmfCreateSolidPen(DWORD color, unsigned short width);
	void wmfDeleteObject(unsigned short obj);
	void wmfEllipse(unsigned short, unsigned short, unsigned short, unsigned short);
	void wmfPolyline(POINT *pts, unsigned short cp);
	void wmfPolygon(POINT *pts, unsigned short cp);
	void wmfRectangle(unsigned short, unsigned short, unsigned short, unsigned short);
	void wmfSelectObject(unsigned short o);
	void wmfSetBkColor(DWORD col);
	void wmfSetBkMode(unsigned m);
	void wmfSetTextAlign(unsigned a);
	void wmfSetTextColor(DWORD col);
	void wmfTextOut(unsigned short, unsigned short, char *, unsigned short);
};

ExportWMF::ExportWMF(GraphObj *g, char *FileName, float res, DWORD flags)
{
	currGDIobj = maxGDIobj = 0;
	hgo =0L;
	DeskRect.left = DeskRect.top = 0;
	DeskRect.right = DeskRect.bottom = 0x4fffffff;
	dFillCol = 0xffffffffL;
	hPen = 0xffff, hBrush = 0xffff, hFont = 0xffff;
	hres = vres = res;
	go = g;
	if(FileName)name = strdup(FileName);
	else name = 0L;
	oFile = 0;
	rec_size = 28;
	header.mtType = 1;
	header.mtHeader = 9;
	header.mtVersion = 0x300;
	header.mtSize0 = 1000;
	header.mtSize1 = 0;
	header.mtNoObj = 64;
	header.mtMaxRec = 100;
	header.mtnoPar = 0;
}

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//overloaded functions from the anyOutput class
bool
ExportWMF::SetLine(LineDEF *lDef)
{
	unsigned short iw;

	if(hPen == 0xffff || lDef->width != LineWidth || lDef->width != LineWidth || 
		lDef->pattern != dPattern || lDef->color != dLineCol) {
		LineWidth = lDef->width;
		iw = (unsigned short)(0.5 + un2fix(lDef->width));
		dPattern = lDef->pattern;
		RLP.finc = 256.0/((float)(un2fix(lDef->patlength*8.0)));
		RLP.fp = 0.0;
		if(iLine == iw && dLineCol == lDef->color && hPen != 0xffff) return true;
		iLine = iw;
		dLineCol = lDef->color;
		if(hPen != 0xffff) wmfDeleteObject(hPen);
		iw = iw > 0 ? iw : 1;
		hPen = wmfCreateSolidPen(dLineCol, iw);
		wmfSelectObject(hPen);
		}
	return true;
}

bool
ExportWMF::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;
		}
	if(dFillCol != fill->color) {
		if(hBrush != 0xffff) wmfDeleteObject(hBrush);
		hBrush = wmfCreateSolidBrush(dFillCol = fill->color);
		wmfSelectObject(hBrush);
		}
	dFillCol2 = fill->color2;
	return true;
}

bool
ExportWMF::SetTextSpec(TextDEF *set)
{
	unsigned char lfcs, lfpaf;
	char *face;
	bool IsModified, RetVal;

	switch(set->Font){
	case FONT_HELVETICA:
	default:
		lfcs = 0;
		lfpaf = 2 | 2<<4;
		face = "Arial";
		break;
	case FONT_TIMES:
		lfcs = 0;
		lfpaf = 2 | 1<<4;
		face = "Times New Roman";
		break;
	case FONT_COURIER:
		lfcs = 2;
		lfpaf = 1 | 3<<4;
		face = "Courier New";
		break;
		}
	if(!set->iSize && set->fSize > 0.001f) set->iSize = un2iy(set->fSize);
	if(!set->iSize) return false;
	if(hFont == 0xffff || TxtSet.iSize != set->iSize || TxtSet.Style != set->Style ||
		TxtSet.RotBL != set->RotBL || TxtSet.RotCHAR != set->RotCHAR ||
		TxtSet.Font != set->Font || TxtSet.fSize != set->fSize) IsModified = true;
	else IsModified = false;
	RetVal = anyOutput::SetTextSpec(set);
	if (IsModified && RetVal) {
		hFont = wmfCreateFontIndirect(TxtSet.iSize, 0, 
			iround(TxtSet.RotBL*10), iround(TxtSet.RotBL*10), 
			(TxtSet.Style & TXS_BOLD) ? 700 : 400,
			(TxtSet.Style & TXS_ITALIC) ? 1 : 0,
			(TxtSet.Style & TXS_UNDERLINE) ? 1 : 0,
			0, lfcs, 0, 0, 2, lfpaf, face);
		}
	if(hFont != 0xffff) wmfSelectObject(hFont);
	return true;
}

bool 
ExportWMF::StartPage()
{
	if(!go) return false;
	if(name) {
		if(-1 ==(oFile = open(name, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
			S_IWRITE | S_IREAD))) {
			ErrorBox("Could not open output file");
			return false;
			}
		}
	else {
		oFile = 2;		//stdout
		}
	VPorg.fy = -un2fiy(go->GetSize(SIZE_GRECT_TOP));
	VPorg.fx = -un2fix(go->GetSize(SIZE_GRECT_LEFT));
	write(oFile, &header, 18);
	return true;
}

bool
ExportWMF::EndPage()
{
	unsigned short end_token[3] = {3, 0, 0};

	write(oFile, &end_token, 6);
//	file_size = tell(oFile);
	file_size = lseek(oFile, 0L, SEEK_CUR);
	lseek(oFile, 0L, SEEK_SET);
	header.mtSize0 = (file_size>>1)&0xffff;
	header.mtSize1 = file_size>>17;
	header.mtNoObj = maxGDIobj;
	header.mtMaxRec = rec_size;
	write(oFile, &header, 18);
	oFile = close(oFile);
	return true;
}

bool
ExportWMF::oCircle(int x1, int y1, int x2, int y2, char* nam)
{
	wmfEllipse(x1, y1, x2, y2);
	if(hgo) return hgo->oCircle(x1, y1, x2, y2);
	return true;
}

bool
ExportWMF::oPolyline(POINT * pts, int cp, char * nam)
{
	int i;

	if(cp < 1) return false;
	if (dPattern) for (i = 1; i < cp; i++) PatLine(pts[i-1], pts[i]);
	else wmfPolyline(pts, cp);
	return true;
}

bool
ExportWMF::oRectangle(int x1, int y1, int x2, int y2, char *nam)
{
	wmfRectangle(x1, y1, x2, y2);
	if(hgo) return hgo->oRectangle(x1, y1, x2, y2, 0L);
	return true;
}

bool
ExportWMF::oSolidLine(POINT *p)
{
	wmfPolyline(p, 2);
	return true;
}

bool
ExportWMF::oTextOut(int x, int y, char *txt, int cb)
{
	if(!txt || !txt[0]) return false;
	if(hFont != 0xffff) wmfSelectObject(hFont);
	wmfSetTextColor(TxtSet.ColTxt);
	wmfSetBkColor(TxtSet.ColBg);
	wmfSetTextAlign(((TxtSet.Align & TXA_HRIGHT) ? 2 : (TxtSet.Align &
		TXA_HCENTER) ? 6 : 0) | ((TxtSet.Align & TXA_VBOTTOM) ?	8 : 0));
	wmfSetBkMode(TxtSet.Mode ? 1 : 2);
	wmfTextOut(x, (TxtSet.Align & TXA_VCENTER) ? y - TxtSet.iSize/2 : y, txt, 
		(cb > 0) ? cb : strlen(txt));
	return true;
}

bool
ExportWMF::oPolygon(POINT *pts, int cp, char *nam)
{
	wmfPolygon(pts, cp);
	if(hgo) return hgo->oPolygon(pts, cp);
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//templates for wmf file records
typedef struct{
	unsigned Size;
	unsigned short Id;
	unsigned short Value;
}wmfObjShort;

typedef struct{
	unsigned Size;
	unsigned short Id;
}wmfObjCol;

typedef struct{
	unsigned Size;
	unsigned short Id;
	unsigned short Style;
	DWORD Col;
	unsigned short Hatch;
}wmfLogBrush;

typedef struct{
	unsigned Size;
	unsigned short Id;
	short lfh, lfw, lfesc, lfori, lfwei;
	unsigned char lfita, lfund, lfsto, lfcse, lfopre, lfclp, lfqua, lfpaqu;
	char face[32];
}wmfLogFont;

typedef struct{
	unsigned Size;
	unsigned short Id;
	unsigned short Style;
	unsigned Width;
	DWORD col;
}wmfLogPen;

typedef struct{
	unsigned Size;
	unsigned short Id;
	unsigned short x1, y1, x2, y2;
}wmfRect;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//the following routines resemble the corresponding GDI calls
unsigned short
ExportWMF::wmfCreateSolidBrush(DWORD color)
{
	wmfLogBrush lb = {7, 0x2fc, 0, color, 0};

	write(oFile, &lb, 14);
	currGDIobj++;
	maxGDIobj = currGDIobj > maxGDIobj ? currGDIobj : maxGDIobj;
	return currGDIobj-1;
}

unsigned short
ExportWMF::wmfCreateFontIndirect(short lfHeight, short lfWidth, short lfEscapement,
	short lfOrientation, short lfWeight, unsigned char lfItalic, unsigned char lfUnderline,
	unsigned char lfStrikeOut, unsigned char lfCharSet, unsigned char lfOutPrecision, 
	unsigned char lfClipPrecision, unsigned char lfQuality, unsigned char lfPitchAndFamily,
	char *FaceName)
{
	wmfLogFont lf = {28, 0x2fb, lfHeight, lfWidth, lfEscapement, lfOrientation, lfWeight,
		lfItalic, lfUnderline, lfStrikeOut, lfCharSet, lfOutPrecision, lfClipPrecision,
		lfQuality, lfPitchAndFamily, "Arial"};

	if(FaceName && FaceName[0]) strcpy(lf.face, FaceName);
	write(oFile, &lf, 56);
	currGDIobj++;
	maxGDIobj = currGDIobj > maxGDIobj ? currGDIobj : maxGDIobj;
	return currGDIobj-1;
}

unsigned short
ExportWMF::wmfCreateSolidPen(DWORD color, unsigned short width)
{
	wmfLogPen lp = {8, 0x2fa, 0, width, color};

	write(oFile, &lp, 16);
	currGDIobj++;
	maxGDIobj = currGDIobj > maxGDIobj ? currGDIobj : maxGDIobj;
	return currGDIobj-1;
}

void
ExportWMF::wmfDeleteObject(unsigned short obj)
{
	wmfObjShort wo = {4, 0x1f0, obj};

	if(currGDIobj == obj+1) {
//		write(oFile, &wo, 8);
//		currGDIobj--;
		}
}

void
ExportWMF::wmfEllipse(unsigned short ix1, unsigned short iy1, unsigned short ix2, unsigned short iy2)
{
	wmfRect rc = {7, 0x418, iy2, ix2, iy1, ix1};
	
	write(oFile, &rc, 14);
}

void
ExportWMF::wmfPolyline(POINT *pts, unsigned short cp)
{
	wmfObjShort pl = {4+cp*2, 0x325, cp};
	unsigned short v[2];
	int i;

	write(oFile, &pl, 8);
	for(i = 0; i < cp; i++) {
		v[0] = (unsigned short)pts[i].x;
		v[1] = (unsigned short)pts[i].y;
		write(oFile, &v, 4);
		}
	if(pl.Size > rec_size) rec_size = pl.Size;
}

void
ExportWMF::wmfPolygon(POINT *pts, unsigned short cp)
{
	wmfObjShort pl = {4+cp*2, 0x324, cp};
	unsigned short v[2];
	int i;

	write(oFile, &pl, 8);
	for(i = 0; i < cp; i++) {
		v[0] = (unsigned short)pts[i].x;
		v[1] = (unsigned short)pts[i].y;
		write(oFile, &v, 4);
		}
	if(pl.Size > rec_size) rec_size = pl.Size;
}

void
ExportWMF::wmfRectangle(unsigned short ix1, unsigned short iy1, unsigned short ix2, unsigned short iy2)

⌨️ 快捷键说明

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