/*---------------------------------------------------------------------------- draw.c (convert tpv format to Windows Metafile) This file is a part of Topaz systems Copyright: Hisao Kawaura, All rights reserved 1997 - 98 This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----------------------------------------------------------------------------*/ #include #include #include #include #include #include "vectdefs.h" #include "pointdefs.h" #include "col.h" #include "kanji.h" #include "Parray.h" #include "topazvalues.h" unsigned int w = 640, h = 450; int x = 100, y = 100; unsigned int border = 1; double unit = 20.0; double margin = 0.0; RECT Brect; //current status Capcolor currentcol, forecol, backcol; Capfont currentfo; unsigned int forecolor, backcolor; int currentlinewidth = 0; int currentcapstyle = 1; int currentjoinstyle = 0; int linestyle = LINESTYLESOLID; int fillstyle = FILLSTYLESOLID; int currentfillrule = FILLRULEEVENODD; int paintmode = 0; std::string title; int paperx, papery; int penstyle = PS_SOLID; double mag = 1; int shiftx = 0, shifty = 0; int cdepth = 2; Parray *xpa; #define buffersize 1024 #define JOBVIEW 0 #define JOBCLIP 1 #define JOBPRN 2 typedef struct xlfd_table { char name[256]; }XLFDENTRY; char dash1[] = {2,2}; HPEN pen, open; HBRUSH forebrush, oforebrush; HBRUSH backbrush, obackbrush; HFONT hf, ohf; LOGFONT lf; double posix(double x) { double f = (x - shiftx) * mag; if (f > (double)MAXSHORT) f = (double)MAXSHORT; else if (f < -(double)MAXSHORT) f = -(double)MAXSHORT; return f; } double posiy(double y) { double f = (y - shifty) * mag; if (f > (double)MAXSHORT) f = (double)MAXSHORT; else if (f < -(double)MAXSHORT) f = -(double)MAXSHORT; return f; } void convminus(const char *s) { char *p; p = (char *)s; while(*p != 0) { if (*p == '-') *p = '~'; p++; } } bool iscommentline(const char *s) { char *p; p = (char *)s; while (*p != 0) { if ((*p != ' ') && (*p != '\t')) { if (*p == '#') return true; else return false; } else p++; } return false; } bool getcapcolor(char *str, Capcolor *col) { char *p; Capcolor tempcol; char buff[buffersize], stemp[3]; int tokencount; p = (char *)str; strcpy(buff, ""); tokencount = 0; do { if (*p == ',') { if(tokencount == 0) tempcol.red = (unsigned long)atol(buff) / 256; else if(tokencount == 1) tempcol.green = (unsigned long)atol(buff) / 256; else return false; tokencount++; strcpy(buff, ""); } else if (*p != '\n') { stemp[0] = *p; stemp[1] = 0; strcat(buff, stemp); } p++; }while(*p != 0); if(tokencount == 2) { tempcol.blue = (unsigned long)atol(buff) / 256; *col = tempcol; return true; } else return false; } bool getcaptext(char *str, char *out) { char *p; char buff[buffersize], stemp[3]; p = (char *)str; strcpy(buff, ""); while(*p != 0 && *p != '\n' && *p != '\r') { stemp[0] = *p; stemp[1] = 0; strcat(buff, stemp); p++; } strcpy(out, buff); } bool getcapfont(char *str, Capfont *fo) { char *p; Capfont tempfo; char buff[buffersize], stemp[3]; int tokencount; p = (char *)str; strcpy(buff, ""); tokencount = 0; do { if (*p == ',') { if(tokencount == 0) tempfo.face = atoi(buff); else if(tokencount == 1) tempfo.size = (int)(atof(buff) * mag); else return false; tokencount++; strcpy(buff, ""); } else if (*p != '\n') { stemp[0] = *p; stemp[1] = 0; strcat(buff, stemp); } p++; }while(*p != 0); if(tokencount == 2) { tempfo.angle = atof(buff) * 10.0; *fo = tempfo; return true; } else return false; } bool getcappoint(char *str, doublepoint *dp) { char *p; doublepoint tdp; char buff[buffersize], stemp[3]; int tokencount; p = (char *)str; strcpy(buff, ""); tokencount = 0; do { if (*p == ',') { if(tokencount == 0) tdp.x = posix(atof(buff)); else return false; tokencount++; strcpy(buff, ""); } else if (*p != '\n') { stemp[0] = *p; stemp[1] = 0; strcat(buff, stemp); } p++; }while(*p != 0); if(tokencount == 1) { tdp.y = posiy(atof(buff)); *dp = tdp; return true; } else return false; } bool drawline(HDC dc, FILE *in, char *str, METAFILEPICT *mpict, int jobtype, double printmagx, double printmagy, double printshiftx, double printshifty) { int i, itemp; char *p; char temp[10]; doublepoint dp; bool lineflag = false; int arc_x, arc_y, arc_x1, arc_x2, arc_y1, arc_y2; unsigned int arc_w, arc_h; std::string text; double ftemp1, ftemp2, ftemp3, ftemp4; char s1[100], s2[100], s3[100], s4[100], stemp[1000]; char buffer[buffersize], buffer1[buffersize]; unsigned char kanji[2]; POINT txp; unsigned int xcol; RECT xrect; if (!iscommentline(str)) { p = str; //command if (*p == '/') { p++; if (strlen(p) == 4) { temp[0] = *p; temp[1] = *(p + 1); temp[2] = *(p + 2); temp[3] = 0; //Moveto if (strcmp(temp, "MVT") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcappoint(buffer, &dp) == false) return false; if (lineflag == false) { txp.x = (short)dp.x; txp.y = (short)dp.y; xpa->add(&txp); } } //Lineto else if (strcmp(temp, "LNT") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcappoint(buffer, &dp) == false) return false; txp.x = (short)dp.x; txp.y = (short)dp.y; xpa->add(&txp); lineflag = true; } //Polygon else if (strcmp(temp, "PLY") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; itemp = atoi(buffer); xpa->setbuff(0); for (i = 0; i < itemp; i++) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcappoint(buffer, &dp) == false) return false; txp.x = (short)dp.x; txp.y = (short)dp.y; xpa->add(&txp); } // fill inside area if (fillstyle != FILLSTYLENULL) forebrush = CreateSolidBrush((unsigned long)backcolor); else forebrush = (HBRUSH)GetStockObject(NULL_BRUSH); oforebrush = (HBRUSH)SelectObject(dc, forebrush); // draw edge if (linestyle != LINESTYLENULL) pen = CreatePen(penstyle, currentlinewidth, (unsigned long)forecolor); else pen = (HPEN)GetStockObject(NULL_PEN); open = (HPEN)SelectObject(dc, pen); // close path txp.x = (*xpa)[0].x; txp.y = (*xpa)[0].y; xpa->add(&txp); Polygon(dc, &(*xpa)[0], xpa->getarraylength()); SelectObject(dc, open); DeleteObject(pen); SelectObject(dc, oforebrush); DeleteObject(forebrush); // flush buffer xpa->setbuff(0); } //Ellipse else if (strcmp(temp, "ELP") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcappoint(buffer, &dp) == false) return false; arc_x1 = (short)dp.x; arc_y1 = (short)dp.y; if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcappoint(buffer, &dp) == false) return false; arc_x2 = (short)dp.x; arc_y2 = (short)dp.y; // fill inside area if (fillstyle != FILLSTYLENULL) forebrush = CreateSolidBrush((unsigned long)backcolor); else forebrush = (HBRUSH)GetStockObject(NULL_BRUSH); oforebrush = (HBRUSH)SelectObject(dc, forebrush); // draw edge if (linestyle != LINESTYLENULL) pen = CreatePen(penstyle, currentlinewidth, (unsigned long)forecolor); else pen = (HPEN)GetStockObject(NULL_PEN); open = (HPEN)SelectObject(dc, pen); Ellipse(dc, arc_x1, arc_y1, arc_x2, arc_y2); SelectObject(dc, open); DeleteObject(pen); } //Begin Path else if (strcmp(temp, "BGP") == 0) { lineflag = false; } //Close Path else if (strcmp(temp, "CSP") == 0) { if (xpa->getarraylength() > 0) { txp.x = (*xpa)[0].x; txp.y = (*xpa)[0].y; xpa->add(&txp); } } //Stroke Path else if (strcmp(temp, "SRP") == 0) { if (linestyle != LINESTYLENULL) pen = CreatePen(penstyle, currentlinewidth, (unsigned long)forecolor); else pen = (HPEN)GetStockObject(NULL_PEN); open = (HPEN)SelectObject(dc, pen); Polyline(dc, &(*xpa)[0], xpa->getarraylength()); SelectObject(dc, open); DeleteObject(pen); xpa->setbuff(0); lineflag = false; } // select foreground color else if (strcmp(temp, "FCL") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcapcolor(buffer, &forecol) == false) return false; forecolor = RGB(forecol.red, forecol.green, forecol.blue); } // select background color else if (strcmp(temp, "BCL") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcapcolor(buffer, &backcol) == false) return false; backcolor = RGB(backcol.red, backcol.green, backcol.blue); } // select font else if (strcmp(temp, "LFT") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcapfont(buffer, ¤tfo) == false) return false; memset(&lf, 0, sizeof(lf)); lf.lfHeight = -currentfo.size; lf.lfEscapement = (int)currentfo.angle % 3600; lf.lfOrientation = lf.lfEscapement; switch(currentfo.face) { case 0: case 1: case 2: case 3: strcpy(lf.lfFaceName, "Times New Roman"); break; case 4: case 5: case 6: case 7: strcpy(lf.lfFaceName, "Arial"); break; case 8: case 9: case 10: case 11: strcpy(lf.lfFaceName, "Courier New"); break; case 12: strcpy(lf.lfFaceName, "Symbol"); break; case 1000: strcpy(lf.lfFaceName, "‚l‚r –¾’©"); break; case 1004: strcpy(lf.lfFaceName, "‚l‚r ƒSƒVƒbƒN"); break; default: strcpy(lf.lfFaceName, "Times New Roman"); } switch(currentfo.face) { case 0: case 1: case 4: case 5: case 8: case 9: case 12: case 1000: case 1004: lf.lfItalic = 0; break; case 2: case 3: case 6: case 7: case 10: case 11: lf.lfItalic = 1; break; default: lf.lfItalic = 0; } switch(currentfo.face) { case 0: case 2: case 4: case 6: case 8: case 10: case 12: case 1000: case 1004: lf.lfWeight = 0; break; case 1: case 3: case 5: case 7: case 9: case 11: lf.lfWeight = FW_BOLD; break; default: lf.lfWeight = 0; } switch(currentfo.face) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: lf.lfCharSet = ANSI_CHARSET; break; case 12: lf.lfCharSet = SYMBOL_CHARSET; break; case 1000: case 1004: lf.lfCharSet = SHIFTJIS_CHARSET; break; default: lf.lfCharSet = ANSI_CHARSET; } } // draw text else if (strcmp(temp, "DTX") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcappoint(buffer, &dp) == false) return false; if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcaptext(buffer, buffer1) == false) return false; hf = CreateFontIndirect(&lf); ohf = (HFONT)SelectObject(dc, hf); SetTextColor(dc,forecolor); TextOut(dc, (short)dp.x, (short)dp.y, buffer1, strlen(buffer1)); SelectObject(dc, ohf); DeleteObject(hf); } //set paint mode else if (strcmp(temp, "PMD") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; //thickness paintmode = atoi(buffer); if (paintmode == 0) SetROP2(dc, R2_COPYPEN); else if (paintmode == 1) SetROP2(dc, R2_NOTXORPEN); } //set line style else if (strcmp(temp, "LSY") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; //thickness currentlinewidth = (int)((double)atoi(buffer) * mag); if (fgets(buffer, sizeof(buffer), in) == NULL) return false; //capstyle switch(atoi(buffer)) { case LINECAPBUTT: currentcapstyle = PS_ENDCAP_SQUARE; break; case LINECAPROUND: currentcapstyle = PS_ENDCAP_ROUND; break; case LINECAPPROJECTING: currentcapstyle = PS_ENDCAP_FLAT; break; } if (fgets(buffer, sizeof(buffer), in) == NULL) return false; //joinstyle switch(atoi(buffer)) { case LINEJOINMITER: currentjoinstyle = PS_JOIN_MITER; break; case LINEJOINROUND: currentjoinstyle = PS_JOIN_ROUND; break; case LINEJOINBEVEL: currentjoinstyle = PS_JOIN_BEVEL; break; } if (fgets(buffer, sizeof(buffer), in) == NULL) return false; //linestyle linestyle = atoi(buffer); } //set fill style else if (strcmp(temp, "FSY") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; // fillrule switch(atoi(buffer)) { case FILLRULEEVENODD: currentfillrule = ALTERNATE; break; case FILLRULEWINDING: currentfillrule = WINDING; break; } if (fgets(buffer, sizeof(buffer), in) == NULL) return false; //fillstyle fillstyle = atoi(buffer); SetPolyFillMode(dc, currentfillrule); } //setcliprect else if (strcmp(temp, "RCP") == 0) { RestoreDC(dc, -1); } else if (strcmp(temp, "CRT") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcappoint(buffer, &dp) == false) return false; xrect.left = (short)dp.x; xrect.top = (short)dp.y; if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcappoint(buffer, &dp) == false) return false; xrect.right = (unsigned short)dp.x; xrect.bottom = (unsigned short)dp.y; SaveDC(dc); IntersectClipRect(dc, xrect.left, xrect.top, xrect.right, xrect.bottom); } // paper else if (strcmp(temp, "PAR") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; sscanf(buffer, "%d,%d\n", &paperx, &papery); } //clear window else if (strcmp(temp, "CLR") == 0) { SetMapMode(dc, MM_ANISOTROPIC); switch(jobtype) { case JOBVIEW: SetWindowOrgEx(dc, 0, 0, NULL); SetWindowExtEx(dc, (int)(100.0 * unit), (int)(100.0 * unit), NULL); SetViewportOrgEx(dc, 0, 0, NULL); SetViewportExtEx(dc, 100, 100, NULL); break; case JOBPRN: SetWindowOrgEx(dc, (int)printshiftx, (int)printshifty, NULL); SetWindowExtEx(dc, (int)(100.0 * unit), (int)(100.0 * unit), NULL); SetViewportOrgEx(dc, 0, 0, NULL); SetViewportExtEx(dc, (int)(printmagx * 100.0), (int)(printmagy * 100.0), NULL); break; case JOBCLIP: SetWindowOrgEx(dc, Brect.left, Brect.top, NULL); SetWindowExtEx(dc, mpict->xExt, mpict->yExt, NULL); break; } if (jobtype == JOBVIEW) { forebrush = (HBRUSH)GetStockObject(WHITE_BRUSH); oforebrush = (HBRUSH)SelectObject(dc, forebrush); pen = (HPEN)GetStockObject(BLACK_PEN); open = (HPEN)SelectObject(dc, pen); Rectangle(dc, 0, 0, MAXSHORT, MAXSHORT); MoveToEx(dc, (int)posix(0), (int)posiy(0), NULL); LineTo(dc, (int)posix(paperx), (int)posiy(0)); LineTo(dc, (int)posix(paperx), (int)posiy(papery)); LineTo(dc, (int)posix(0), (int)posiy(papery)); LineTo(dc, (int)posix(0), (int)posiy(0)); SelectObject(dc, open); DeleteObject(pen); SelectObject(dc, oforebrush); DeleteObject(forebrush); } SetBkMode(dc, TRANSPARENT); xcol = 0; SetTextAlign(dc, TA_BASELINE); } //set temporary line style (for xor draw) else if (strcmp(temp, "STD") == 0) { paintmode == 0; penstyle = PS_DOT; } //restore line style (fromr xor draw mode) else if (strcmp(temp, "RLS") == 0) { paintmode == 1; penstyle = PS_SOLID; } // mag else if (strcmp(temp, "MAG") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; //thickness if (jobtype == JOBVIEW) mag = atof(buffer); else mag = 1.0; } // shift else if (strcmp(temp, "SFT") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (jobtype == JOBVIEW) sscanf(buffer, "%d,%d\n", &shiftx, &shifty); else { shiftx = 0; shifty = 0; } } else if (strcmp(temp, "BBX") == 0) { if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcappoint(buffer, &dp) == false) return false; xrect.left = (short)dp.x; xrect.top = (short)dp.y; if (fgets(buffer, sizeof(buffer), in) == NULL) return false; if (getcappoint(buffer, &dp) == false) return false; xrect.right = (unsigned short)dp.x; xrect.bottom = (unsigned short)dp.y; if (jobtype == JOBCLIP && mpict != NULL) { Brect.left = xrect.left - (int)margin; Brect.top = xrect.top - (int)margin; Brect.right = xrect.right + (int)margin; Brect.bottom = xrect.bottom + (int)margin; mpict->xExt = Brect.right - Brect.left; mpict->yExt = Brect.bottom - Brect.top; } } } } } return true; }