From 6f120338edb03bbdf7224f1b4d5560caf61bb002 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Tue, 19 May 2009 07:23:56 +0000 Subject: Add ability to copy SVGs to the clipboard and save in IFF DR2D format. svn path=/trunk/netsurf/; revision=7523 --- amiga/iff_dr2d.c | 395 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 395 insertions(+) create mode 100644 amiga/iff_dr2d.c (limited to 'amiga/iff_dr2d.c') diff --git a/amiga/iff_dr2d.c b/amiga/iff_dr2d.c new file mode 100644 index 000000000..4779e3241 --- /dev/null +++ b/amiga/iff_dr2d.c @@ -0,0 +1,395 @@ +/* + * Copyright 2009 Chris Young + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf 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; version 2 of the License. + * + * NetSurf 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, see . + */ + +#ifdef WITH_NS_SVG + +#include +#include +#include +#include +#include "iff_dr2d.h" +#include + +struct ColorRegister cm[1000]; +ULONG numcols; + +ULONG findcolour(ULONG newcol) +{ + ULONG i; + ULONG colour = 0xFFFFFFFF; + UBYTE red,grn,blu; + + red = svgtiny_RED(newcol); + grn = svgtiny_GREEN(newcol); + blu = svgtiny_BLUE(newcol); + + for(i=0;ierror_line, + diagram->error_message); + break; + default: + fprintf(stderr, "unknown svgtiny_code %i", code); + break; + } + fprintf(stderr, "\n"); + } + + if(!(PushChunk(iffh,ID_DR2D,ID_FORM,IFFSIZE_UNKNOWN))) + { + if(!(PushChunk(iffh,0,ID_NAME,IFFSIZE_UNKNOWN))) + { + WriteChunkBytes(iffh,url,strlen(url)); + PopChunk(iffh); + } + + if(!(PushChunk(iffh,0,ID_ANNO,18))) + { + WriteChunkBytes(iffh,"Created by NetSurf",18); + PopChunk(iffh); + } + + if(!(PushChunk(iffh,0,ID_DRHD,16))) + { + struct drhd_struct drhd; + drhd.XLeft = (float) 0.0; + drhd.YTop = (float) 0.0; + drhd.XRight = (float) diagram->width; + drhd.YBot = (float) diagram->height; + + WriteChunkBytes(iffh,&drhd,16); + PopChunk(iffh); + } + + if(!(PushChunk(iffh,0,ID_DASH,IFFSIZE_UNKNOWN))) + { + struct dash_struct dash; + dash.DashID = 1; + dash.NumDashes = 0; + + WriteChunkBytes(iffh,&dash,sizeof(struct dash_struct)); + PopChunk(iffh); + } + + if(!(PushChunk(iffh,0,ID_CMAP,IFFSIZE_UNKNOWN))) + { + for (i = 0; i != diagram->shape_count; i++) { + if(diagram->shape[i].fill != svgtiny_TRANSPARENT) + { + addcolour(diagram->shape[i].fill); + } + + if(diagram->shape[i].stroke != svgtiny_TRANSPARENT) + { + addcolour(diagram->shape[i].stroke); + } + } + + WriteChunkBytes(iffh,cm,3*numcols); + PopChunk(iffh); + } + + for (i = 0; i != diagram->shape_count; i++) { + attr = AllocVec(sizeof(struct attr_struct),MEMF_CLEAR | MEMF_PRIVATE); + if (diagram->shape[i].fill == svgtiny_TRANSPARENT) + attr->FillType = FT_NONE; + else + { + attr->FillType = FT_COLOR; + attr->FillValue = findcolour(diagram->shape[i].fill); + } + if (diagram->shape[i].stroke == svgtiny_TRANSPARENT) + attr->DashPattern = 0; + else + { + attr->DashPattern = 1; + attr->EdgeValue = findcolour(diagram->shape[i].stroke); + } + attr->EdgeThick = (float) diagram->shape[i].stroke_width; + + if(!(PushChunk(iffh,0,ID_ATTR,IFFSIZE_UNKNOWN))) + { + WriteChunkBytes(iffh,attr,14); + PopChunk(iffh); + } + FreeVec(attr); + + if (diagram->shape[i].path) { + union { + float PolyPoints; + ULONG val; + } poly[(diagram->shape[i].path_length)*2]; + + USHORT NumPoints; + long type; + float curx,cury; + + curx = 0.0; + cury = 0.0; + NumPoints = 0; + type = ID_OPLY; + + for (j = 0; + j != diagram->shape[i].path_length; ) { + switch ((int) diagram->shape[i].path[j]) { + case svgtiny_PATH_MOVE: + if(j != 0) + { + poly[NumPoints*2].val = INDICATOR; + poly[(NumPoints*2)+1].val = IND_MOVETO; + NumPoints++; + } + poly[(NumPoints*2)].PolyPoints = diagram->shape[i].path[j + 1]; + poly[(NumPoints*2)+1].PolyPoints = diagram->shape[i].path[j + 2]; + NumPoints++; + curx = (float) diagram->shape[i].path[j + 1]; + cury = (float) diagram->shape[i].path[j + 2]; + + j += 3; + break; + case svgtiny_PATH_CLOSE: + type = ID_CPLY; + j += 1; + break; + case svgtiny_PATH_LINE: + poly[(NumPoints*2)].PolyPoints = (float) diagram->shape[i].path[j + 1]; + poly[(NumPoints*2)+1].PolyPoints = (float) diagram->shape[i].path[j + 2]; + NumPoints++; + curx = (float) diagram->shape[i].path[j + 1]; + cury = (float) diagram->shape[i].path[j + 2]; + j += 3; + break; + case svgtiny_PATH_BEZIER: + poly[NumPoints*2].val = INDICATOR; + poly[(NumPoints*2)+1].val = IND_CURVE; + NumPoints++; + poly[(NumPoints*2)].PolyPoints = curx; + poly[(NumPoints*2)+1].PolyPoints = cury; + NumPoints++; + poly[(NumPoints*2)].PolyPoints = (float) diagram->shape[i].path[j + 1]; + poly[(NumPoints*2)+1].PolyPoints = (float) diagram->shape[i].path[j + 2]; + NumPoints++; + poly[(NumPoints*2)].PolyPoints = (float) diagram->shape[i].path[j + 3]; + poly[(NumPoints*2)+1].PolyPoints = (float) diagram->shape[i].path[j + 4]; + NumPoints++; + poly[(NumPoints*2)].PolyPoints = (float) diagram->shape[i].path[j + 5]; + poly[(NumPoints*2)+1].PolyPoints = (float) diagram->shape[i].path[j + 6]; + curx = poly[(NumPoints*2)].PolyPoints; + cury = poly[(NumPoints*2)+1].PolyPoints; + NumPoints++; + j += 7; + break; + default: + printf("error\n"); + j += 1; + } + } + if(!(PushChunk(iffh,0,type,IFFSIZE_UNKNOWN))) + { + WriteChunkBytes(iffh,&NumPoints,sizeof(USHORT)); + WriteChunkBytes(iffh,poly,NumPoints*2*4); + PopChunk(iffh); + } + } else if (diagram->shape[i].text) { + stxt = AllocVec(sizeof(struct stxt_struct),MEMF_CLEAR); + stxt->BaseX = diagram->shape[i].text_x; + stxt->BaseY = diagram->shape[i].text_y; + stxt->NumChars = strlen(diagram->shape[i].text); + if(!fons_written) + { + fons = AllocVec(sizeof(struct fons_struct),MEMF_CLEAR); + if(!(PushChunk(iffh,0,ID_FONS,IFFSIZE_UNKNOWN))) + { + WriteChunkBytes(iffh,fons,sizeof(struct fons_struct)); + WriteChunkBytes(iffh,"Topaz",5); + PopChunk(iffh); + } + FreeVec(fons); + fons_written = TRUE; + } + + if(!(PushChunk(iffh,0,ID_STXT,IFFSIZE_UNKNOWN))) + { + WriteChunkBytes(iffh,stxt,26); + WriteChunkBytes(iffh,diagram->shape[i].text,strlen(diagram->shape[i].text)); + PopChunk(iffh); + } + FreeVec(stxt); + } + } + + PopChunk(iffh); + } + + svgtiny_free(diagram); + + return 0; +} + +#ifndef AMIGA_DR2D_STANDALONE +bool ami_save_svg(struct content *c,char *filename) +{ + struct IFFHandle *iffh; + + if(iffh = AllocIFF()) + { + if(iffh->iff_Stream = Open(filename,MODE_NEWFILE)) + { + InitIFFasDOS(iffh); + } + else return false; + } + + if((OpenIFF(iffh,IFFF_WRITE))) return false; + + ami_svg_to_dr2d(iffh,c->source_data,c->source_size,c->url); + + if(iffh) CloseIFF(iffh); + if(iffh->iff_Stream) Close((BPTR)iffh->iff_Stream); + if(iffh) FreeIFF(iffh); + +} +#else +/* + * This code can be compiled as a standalone program for testing etc. + * Use something like the following line: + * gcc -o svg2dr2d iff_dr2d.c -lauto -lsvgtiny -lxml2 -lpthread -lz -use-dynld + * -DWITH_NS_SVG -DAMIGA_DR2D_STANDALONE -D__USE_INLINE__ + */ +const char USED ver[] = "\0$VER: svg2dr2d 1.1 (18.05.2009)\0"; + +int main(int argc, char **argv) +{ + BPTR fh = 0; + char *buffer; + size_t n; + struct IFFHandle *iffh = NULL; + int64 size; + LONG rarray[] = {0,0}; + struct RDArgs *args; + STRPTR template = "SVG=INPUT/A,DR2D=OUTPUT/A"; + enum + { + A_SVG, + A_DR2D + }; + + args = ReadArgs(template,rarray,NULL); + + if(!args) + { + printf("Required argument missing\n"); + return 20; + } + + if(fh = Open((char *)rarray[A_SVG],MODE_OLDFILE)) + { + size = GetFileSize(fh); + + buffer = AllocVec((uint32)size,MEMF_PRIVATE); + + Read(fh,buffer,(uint32)size); + Close(fh); + } + else + { + printf("Unable to open file\n"); + return 20; + } + FreeVec(buffer); + + if(iffh = AllocIFF()) + { + if(iffh->iff_Stream = Open((char *)rarray[A_DR2D],MODE_NEWFILE)) + { + InitIFFasDOS(iffh); + } + else return 20; + } + + if((OpenIFF(iffh,IFFF_WRITE))) return 20; + + ami_svg_to_dr2d(iffh,buffer,size,(char *)rarray[A_SVG]); + + if(iffh) CloseIFF(iffh); + if(iffh->iff_Stream) Close((BPTR)iffh->iff_Stream); + if(iffh) FreeIFF(iffh); + FreeArgs(args); +} + +#endif // AMIGA_DR2D_STANDALONE +#endif // WITH_NS_SVG -- cgit v1.2.3