#include "ET++.ph" #include "Converter.h" #include "Class.h" #include "Data.h" #include "Bitmap.h" #include "String.h" #include "Ink.h" #include "TypeMatcher.h" #include "ET_stdio.h" static const Symbol cDocTypeXPM("XPM"); //---- XPMMatcher -------------------------------------------------------------- class XPMMatcher: public TypeMatcher { public: XPMMatcher() : TypeMatcher(cDocTypeXPM, "xpm", 0, TRUE) { } bool MatchContents(Data*, const char *b, int len); Bitmap *GetBitmap() { return gImageIcon; } }; bool XPMMatcher::MatchContents(Data*, const char *b, int) { if (strncmp(b, "! XPM", 5) == 0) return TRUE; if (strncmp(b, "/* XPM */", 9) == 0) return TRUE; return FALSE; } static XPMMatcher xpmmatcher; //---- XPMConverter ------------------------------------------------------------ class XPMConverter : public Converter { public: MetaDef(XPMConverter); XPMConverter() { } const char *AsString() { return "XPM"; } Object *Convert(Data *data, Class *want); bool CanConvert(Data *data, Class *want) { return data->Type() == cDocTypeXPM && want == Meta(Bitmap); } bool CanConvertTo(Object *op) { return op->IsKindOf(Bitmap); } bool ConvertTo(Data *data, Object *op); private: int Getchar(); int getline(char **b); private: FILE *ifp; int line, eof, inside; }; NewMetaImpl0(XPMConverter,Converter); int XPMConverter::getline(char **b) { static char buf[2048]; int c; register char *cp= buf; for (;;) { c= Getchar(); if (c == '\n' || c == EOF) { *cp= 0; *b= buf; return cp-buf; } *cp++= c; } } int XPMConverter::Getchar() { int c; restart: if (eof) return EOF; c= fgetc(ifp); if (c == EOF) { eof= 1; return c; } if (c == '"') { inside= !inside; if (!inside) return '\n'; goto restart; } if (!inside) goto restart; return c; } Object *XPMConverter::Convert(Data *data, Class*) { char *msg= 0; Object *bm= 0; FILE *fp= fopen(data->Name(), "r"); if (fp) { int i= 0; char buf[1000], *lines[200]; fgets(buf, 1000, fp); if (strncmp(buf, "/* XPM */", 9) == 0) { char *bp; ifp= fp; eof= inside= 0; while (getline(&bp)) lines[i++]= strsave(bp); } else if (strncmp(buf, "! XPM", 5) == 0) { while (fgets(buf, 1000, fp)) { for (char *cp= buf; *cp; cp++) if (*cp == '\n') *cp= 0; lines[i++]= strsave(buf); } } lines[i]= 0; bm= new Bitmap((const char**)lines); for (i= 0; lines[i]; i++) delete lines[i]; fclose(fp); } else msg= "can't open file\n"; if (msg) fprintf(stderr, "XPMConverter::Convert: %s\n", msg); return bm; } bool XPMConverter::ConvertTo(Data *data, Object *op) { int x, y; Bitmap *bm= (Bitmap*) op; Point e(bm->Size()); FILE *ofp; RGB c; char *cp, name[100]; if ((ofp= fopen((char*) data->Name(), "w")) == 0) return FALSE; strcpy(name, data->ShortName()); if (cp= strchr(name, '.')) *cp= 0; int s= (int) bm->MaxPixelValue()+1; fprintf(ofp, "/* XPM */\n"); fprintf(ofp, "static char *%s[] = {\n", name); fprintf(ofp, "/* %s pixmap\n", name); fprintf(ofp, " * width height ncolors chars_per_pixel */\n"); fprintf(ofp, "\"%d %d %d 1\",\n", e.x, e.y, s); for (x= 0; x < s; x++) { fprintf(ofp, "\"%c c ", x+'0'); bm->PixelToRGB(x, &c); char *nm= gInkManager->FindName(c, TRUE); if (nm) fprintf(ofp, "%s\",\n", nm); else fprintf(ofp, "#%02x%02x%02x\",\n", c.red, c.green, c.blue); } fprintf(ofp, "/* pixels */\n"); for (y= 0; y < e.y; y++) { fprintf(ofp, "\""); for (x= 0; x < e.x; x++) fputc((char)(bm->GetPixel(x, y)+'0'), ofp); fprintf(ofp, "\",\n"); } fprintf(ofp, "0\n"); fprintf(ofp, "} ;\n\n"); fclose(ofp); return FALSE; }