svg support in image.d

This commit is contained in:
Adam D. Ruppe 2020-08-18 17:54:43 -04:00
parent 97a4c51715
commit 59d7a30734
5 changed files with 39 additions and 0 deletions

2
cgi.d
View File

@ -9169,6 +9169,8 @@ string contentTypeFromFileExtension(string filename) {
return "text/css";
if(filename.endsWith(".js"))
return "application/javascript";
if(filename.endsWith(".wasm"))
return "application/wasm";
if(filename.endsWith(".mp3"))
return "audio/mpeg";
return null;

View File

@ -99,6 +99,7 @@
"arsd-official:color_base":"*",
"arsd-official:png":"*",
"arsd-official:bmp":"*",
"arsd-official:svg":"*",
"arsd-official:jpeg":"*"
},
"dflags": [

View File

@ -2,6 +2,8 @@
// FIXME: eaders are supposed to be case insensitive. ugh.
// FIXME: need timeout controls
/++
This is version 2 of my http/1.1 client implementation.

33
image.d
View File

@ -10,11 +10,35 @@ public import arsd.bmp;
public import arsd.targa;
public import arsd.pcx;
public import arsd.dds;
public import arsd.svg;
import core.memory;
static if (__traits(compiles, { import iv.vfs; })) enum ArsdImageHasIVVFS = true; else enum ArsdImageHasIVVFS = false;
MemoryImage readSvg(string filename) {
import std.file;
return readSvg(cast(const(ubyte)[]) readText(filename));
}
MemoryImage readSvg(const(ubyte)[] rawData) {
// Load
NSVG* image = nsvgParse(cast(const(char)[]) rawData);
if(image is null)
return null;
int w = cast(int) image.width + 1;
int h = cast(int) image.height + 1;
NSVGrasterizer rast = nsvgCreateRasterizer();
auto img = new TrueColorImage(w, h);
rasterize(rast, image, 0, 0, 1, img.imageData.bytes.ptr, w, h, w*4);
image.kill();
return img;
}
private bool strEquCI (const(char)[] s0, const(char)[] s1) pure nothrow @trusted @nogc {
if (s0.length != s1.length) return false;
@ -38,6 +62,7 @@ enum ImageFileFormat {
Gif, /// we can't load it yet, but we can at least detect it
Pcx, /// can load 8BPP and 24BPP pcx images
Dds, /// can load ARGB8888, DXT1, DXT3, DXT5 dds images (without mipmaps)
Svg, /// will rasterize simple svg images
}
@ -59,6 +84,7 @@ public ImageFileFormat guessImageFormatFromExtension (const(char)[] filename) {
if (strEquCI(ext, "tga")) return ImageFileFormat.Tga;
if (strEquCI(ext, "pcx")) return ImageFileFormat.Pcx;
if (strEquCI(ext, "dds")) return ImageFileFormat.Dds;
if (strEquCI(ext, "svg")) return ImageFileFormat.Svg;
return ImageFileFormat.Unknown;
}
@ -206,6 +232,11 @@ public ImageFileFormat guessImageFormatFromMemory (const(void)[] membuf) {
}
if (guessPcx()) return ImageFileFormat.Pcx;
// kinda lame svg detection but don't want to parse too much of it here
if (buf.length > 6 && buf.ptr[0] == '<') {
return ImageFileFormat.Svg;
}
// dunno
return ImageFileFormat.Unknown;
}
@ -242,6 +273,7 @@ public MemoryImage loadImageFromFile(T:const(char)[]) (T filename) {
case ImageFileFormat.Gif: throw new Exception("arsd has no GIF loader yet");
case ImageFileFormat.Tga: return loadTga(filename);
case ImageFileFormat.Pcx: return loadPcx(filename);
case ImageFileFormat.Svg: static if (is(T == string)) return readSvg(filename); else return readSvg(filename.idup);
case ImageFileFormat.Dds:
static if (ArsdImageHasIVVFS) {
auto fl = VFile(filename);
@ -269,6 +301,7 @@ public MemoryImage loadImageFromMemory (const(void)[] membuf) {
case ImageFileFormat.Gif: throw new Exception("arsd has no GIF loader yet");
case ImageFileFormat.Tga: return loadTgaMem(membuf);
case ImageFileFormat.Pcx: return loadPcxMem(membuf);
case ImageFileFormat.Svg: return readSvg(cast(const(ubyte)[]) membuf);
case ImageFileFormat.Dds: return ddsLoadFromMemory(membuf);
}
}

View File

@ -1,6 +1,7 @@
/*
FIXME: i kinda do want a catch type filter e.g. catch(Exception f)
and perhaps overloads
FIXME: I also kinda want implicit construction of structs at times.