diff options
author | Chris Young <chris@unsatisfactorysoftware.co.uk> | 2009-05-19 07:23:56 +0000 |
---|---|---|
committer | Chris Young <chris@unsatisfactorysoftware.co.uk> | 2009-05-19 07:23:56 +0000 |
commit | 6f120338edb03bbdf7224f1b4d5560caf61bb002 (patch) | |
tree | 90161e3be8f111dc224a0c1b0c98e61098abeee1 /amiga | |
parent | efe2151c9a1d811b7b28d2f8c169688e7615ea11 (diff) | |
download | netsurf-6f120338edb03bbdf7224f1b4d5560caf61bb002.tar.gz netsurf-6f120338edb03bbdf7224f1b4d5560caf61bb002.tar.bz2 |
Add ability to copy SVGs to the clipboard and save in IFF DR2D format.
svn path=/trunk/netsurf/; revision=7523
Diffstat (limited to 'amiga')
-rwxr-xr-x | amiga/clipboard.c | 14 | ||||
-rwxr-xr-x | amiga/clipboard.h | 1 | ||||
-rwxr-xr-x | amiga/context_menu.c | 31 | ||||
-rw-r--r-- | amiga/download.c | 16 | ||||
-rwxr-xr-x | amiga/gui.c | 4 | ||||
-rw-r--r-- | amiga/iff_dr2d.c | 395 | ||||
-rw-r--r-- | amiga/iff_dr2d.h | 105 | ||||
-rwxr-xr-x | amiga/menu.c | 22 |
8 files changed, 576 insertions, 12 deletions
diff --git a/amiga/clipboard.c b/amiga/clipboard.c index 51b8e3100..fd4289d06 100755 --- a/amiga/clipboard.c +++ b/amiga/clipboard.c @@ -30,6 +30,7 @@ #include <datatypes/pictureclass.h> #include <proto/datatypes.h> #include "amiga/bitmap.h" +#include "amiga/iff_dr2d.h" struct IFFHandle *iffh = NULL; @@ -245,3 +246,16 @@ bool ami_easy_clipboard_bitmap(struct bitmap *bitmap) DisposeDTObject(dto); } } + +bool ami_easy_clipboard_svg(struct content *c) +{ + if(c->type != CONTENT_SVG) return false; + + if(!(OpenIFF(iffh,IFFF_WRITE))) + { + ami_svg_to_dr2d(iffh,c->source_data,c->source_size,c->url); + CloseIFF(iffh); + } + + return true; +} diff --git a/amiga/clipboard.h b/amiga/clipboard.h index 806420566..9fccf01d0 100755 --- a/amiga/clipboard.h +++ b/amiga/clipboard.h @@ -23,4 +23,5 @@ void ami_clipboard_init(void); void ami_clipboard_free(void); bool ami_easy_clipboard(char *text); bool ami_easy_clipboard_bitmap(struct bitmap *bitmap); +bool ami_easy_clipboard_svg(struct content *c); #endif diff --git a/amiga/context_menu.c b/amiga/context_menu.c index b5f02f0da..7f60d4963 100755 --- a/amiga/context_menu.c +++ b/amiga/context_menu.c @@ -33,6 +33,7 @@ #include <proto/asl.h> #include "desktop/textinput.h" #include "amiga/bitmap.h" +#include "amiga/iff_dr2d.h" uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved); @@ -280,9 +281,18 @@ uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved) case CMID_CLIPOBJ: object = (struct content *)userdata; - object->bitmap->url = object->url; - object->bitmap->title = object->title; - ami_easy_clipboard_bitmap(object->bitmap); + if(object->bitmap) + { + object->bitmap->url = object->url; + object->bitmap->title = object->title; + ami_easy_clipboard_bitmap(object->bitmap); + } +#ifdef WITH_NS_SVG + else if(object->type == CONTENT_SVG) + { + ami_easy_clipboard_svg(object); + } +#endif break; case CMID_SAVEOBJ: @@ -322,9 +332,18 @@ uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved) char fname[1024]; strlcpy(&fname,savereq->fr_Drawer,1024); AddPart(fname,savereq->fr_File,1024); - object->bitmap->url = object->url; - object->bitmap->title = object->title; - bitmap_save(object->bitmap,fname,0); + if(object->bitmap) + { + object->bitmap->url = object->url; + object->bitmap->title = object->title; + bitmap_save(object->bitmap,fname,0); + } +#ifdef WITH_NS_SVG + else if(object->type == CONTENT_SVG) + { + ami_save_svg(object,fname); + } +#endif SetComment(fname,object->url); ami_update_pointer(gwin->win,GUI_POINTER_DEFAULT); } diff --git a/amiga/download.c b/amiga/download.c index fe9f370f5..5eeeccab1 100644 --- a/amiga/download.c +++ b/amiga/download.c @@ -31,6 +31,7 @@ #include "amiga/options.h" #include "amiga/save_complete.h" #include "amiga/bitmap.h" +#include "amiga/iff_dr2d.h" #include "content/fetch.h" @@ -368,10 +369,19 @@ void ami_drag_save(struct Window *win) case GUI_SAVE_OBJECT_NATIVE: { struct content *c = drag_save_data; - c->bitmap->url = c->url; - c->bitmap->title = c->title; AddPart(path,c->title,1024); - bitmap_save(c->bitmap,path,0); + if(c->bitmap) + { + c->bitmap->url = c->url; + c->bitmap->title = c->title; + bitmap_save(c->bitmap,path,0); + } +#ifdef WITH_NS_SVG + else if(c->type == CONTENT_SVG) + { + ami_save_svg(c,path); + } +#endif } break; } diff --git a/amiga/gui.c b/amiga/gui.c index e8b3743f2..6526811d4 100755 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -2797,7 +2797,11 @@ void gui_window_new_content(struct gui_window *g) OffMenu(g->shared->win,AMI_MENU_CLEAR); OffMenu(g->shared->win,AMI_MENU_FIND); +#ifdef WITH_NS_SVG + if(c->bitmap || c->type == CONTENT_SVG) +#else if(c->bitmap) +#endif { OnMenu(g->shared->win,AMI_MENU_COPY); OnMenu(g->shared->win,AMI_MENU_SAVEAS_IFF); 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 <chris@unsatisfactorysoftware.co.uk> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifdef WITH_NS_SVG + +#include <stdio.h> +#include <svgtiny.h> +#include <proto/exec.h> +#include <string.h> +#include "iff_dr2d.h" +#include <proto/dos.h> + +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;i<numcols;i++) + { + if((cm[i].red == red) && (cm[i].green == grn) && (cm[i].blue == blu)) + colour = i; + } + + return colour; +} + +void addcolour(ULONG newcol) +{ + int i; + ULONG colour; + UBYTE red,grn,blu; + + colour = findcolour(newcol); + + if(colour == 0xFFFFFFFF) + { + cm[numcols].red = svgtiny_RED(newcol); + cm[numcols].green = svgtiny_GREEN(newcol); + cm[numcols].blue = svgtiny_BLUE(newcol); + + numcols++; + } +} + +bool ami_svg_to_dr2d(struct IFFHandle *iffh,char *buffer, uint32 size, char *url) +{ + struct svgtiny_diagram *diagram; + svgtiny_code code; + unsigned int i; + unsigned int j; + BOOL fons_written = FALSE; + struct fons_struct *fons; + struct stxt_struct *stxt; + struct attr_struct *attr; + + /* create svgtiny object */ + diagram = svgtiny_create(); + if (!diagram) { + fprintf(stderr, "svgtiny_create failed\n"); + return 1; + } + + /* parse */ + code = svgtiny_parse(diagram, buffer, size, url, 1000, 1000); + if (code != svgtiny_OK) { + fprintf(stderr, "svgtiny_parse failed: "); + switch (code) { + case svgtiny_OUT_OF_MEMORY: + fprintf(stderr, "svgtiny_OUT_OF_MEMORY"); + break; + case svgtiny_LIBXML_ERROR: + fprintf(stderr, "svgtiny_LIBXML_ERROR"); + break; + case svgtiny_NOT_SVG: + fprintf(stderr, "svgtiny_NOT_SVG"); + break; + case svgtiny_SVG_ERROR: + fprintf(stderr, "svgtiny_SVG_ERROR: line %i: %s", + diagram->error_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 diff --git a/amiga/iff_dr2d.h b/amiga/iff_dr2d.h new file mode 100644 index 000000000..19286a62b --- /dev/null +++ b/amiga/iff_dr2d.h @@ -0,0 +1,105 @@ +/* + * Copyright 2009 Chris Young <chris@unsatisfactorysoftware.co.uk> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifdef WITH_NS_SVG +#ifndef AMIGA_IFF_DR2D_H +#define AMIGA_IFF_DR2D_H +#include <proto/iffparse.h> +#include <datatypes/pictureclass.h> +#include <stdbool.h> +#ifndef AMIGA_DR2D_STANDALONE +#include "content/content.h" +#endif + +#define ID_DR2D MAKE_ID('D','R','2','D') +#define ID_DRHD MAKE_ID('D','R','H','D') +#define ID_ATTR MAKE_ID('A','T','T','R') +#define ID_CPLY MAKE_ID('C','P','L','Y') +#define ID_OPLY MAKE_ID('O','P','L','Y') +#define ID_STXT MAKE_ID('S','T','X','T') +#define ID_DASH MAKE_ID('D','A','S','H') +//#define ID_CMAP MAKE_ID('C','M','A','P') in dt/pictureclass +//#define ID_NAME MAKE_ID('N','A','M','E') in dt/datatypes +#define ID_ANNO MAKE_ID('A','N','N','O') +#define ID_FONS MAKE_ID('F','O','N','S') + +struct drhd_struct { + float XLeft, YTop, XRight, YBot; +}; + +struct poly_struct { + USHORT NumPoints; +// float PolyPoints[]; // 2*numpoints +}; + +#define INDICATOR 0xFFFFFFFF +#define IND_SPLINE 0x00000001 +#define IND_MOVETO 0x00000002 +#define IND_CURVE 0x00000001 + +struct fons_struct { + UBYTE FontID; /* ID the font is referenced by */ + UBYTE Pad1; /* Always 0 */ + UBYTE Proportional; /* Is it proportional? */ + UBYTE Serif; /* does it have serifs? */ +}; + +struct stxt_struct { + UBYTE Pad0; /* Always 0 (for future expansion) */ + UBYTE WhichFont; /* Which font to use */ + float CharW, CharH, /* W/H of an individual char */ + BaseX, BaseY, /* Start of baseline */ + Rotation; /* Angle of text (in degrees) */ + uint16 NumChars; + //char TextChars[NumChars]; +}; + +/* Various fill types */ +#define FT_NONE 0 /* No fill */ +#define FT_COLOR 1 /* Fill with color from palette */ +#define FT_OBJECTS 2 /* Fill with tiled objects */ + +struct attr_struct { + UBYTE FillType; /* One of FT_*, above */ + UBYTE JoinType; /* One of JT_*, below */ + UBYTE DashPattern; /* ID of edge dash pattern */ + UBYTE ArrowHead; /* ID of arrowhead to use */ + USHORT FillValue; /* Color or object with which to fill */ + USHORT EdgeValue; /* Edge color index */ + USHORT WhichLayer; /* ID of layer it's in */ + float EdgeThick; /* Line width */ +}; + +/* Join types */ +#define JT_NONE 0 /* Don't do line joins */ +#define JT_MITER 1 /* Mitered join */ +#define JT_BEVEL 2 /* Beveled join */ +#define JT_ROUND 3 /* Round join */ + +struct dash_struct { + USHORT DashID; /* ID of the dash pattern */ + USHORT NumDashes; /* Should always be even */ +// IEEE Dashes[NumDashes]; /* On-off pattern */ +}; + +bool ami_svg_to_dr2d(struct IFFHandle *iffh,char *buffer, uint32 size, char *url); +#ifndef AMIGA_DR2D_STANDALONE +bool ami_save_svg(struct content *c,char *filename); +#endif +#endif // AMIGA_IFF_DR2D_H +#endif // WITH_NS_SVG diff --git a/amiga/menu.c b/amiga/menu.c index b25c861ea..b96321372 100755 --- a/amiga/menu.c +++ b/amiga/menu.c @@ -43,6 +43,7 @@ #include "amiga/search.h" #include "amiga/history_local.h" #include "amiga/bitmap.h" +#include "amiga/iff_dr2d.h" #include "amiga/clipboard.h" #include "content/fetch.h" @@ -526,9 +527,18 @@ void ami_menupick(ULONG code,struct gui_window_2 *gwin,struct MenuItem *item) strlcpy(&fname,savereq->fr_Drawer,1024); AddPart(fname,savereq->fr_File,1024); ami_update_pointer(gwin->win,GUI_POINTER_WAIT); - gwin->bw->current_content->bitmap->url = gwin->bw->current_content->url; - gwin->bw->current_content->bitmap->title = gwin->bw->current_content->title; - bitmap_save(gwin->bw->current_content->bitmap,fname,0); + if(gwin->bw->current_content->bitmap) + { + gwin->bw->current_content->bitmap->url = gwin->bw->current_content->url; + gwin->bw->current_content->bitmap->title = gwin->bw->current_content->title; + bitmap_save(gwin->bw->current_content->bitmap,fname,0); + } +#ifdef WITH_NS_SVG + else if(gwin->bw->current_content->type == CONTENT_SVG) + { + ami_save_svg(gwin->bw->current_content,fname); + } +#endif SetComment(fname,gwin->bw->current_content->url); ami_update_pointer(gwin->win,GUI_POINTER_DEFAULT); } @@ -587,6 +597,12 @@ void ami_menupick(ULONG code,struct gui_window_2 *gwin,struct MenuItem *item) gwin->bw->current_content->bitmap->title = gwin->bw->current_content->title; ami_easy_clipboard_bitmap(gwin->bw->current_content->bitmap); } +#ifdef WITH_NS_SVG + else if(gwin->bw->current_content->type == CONTENT_SVG) + { + ami_easy_clipboard_svg(gwin->bw->current_content); + } +#endif break; case 1: // paste |