diff options
author | Gaming4JC <g4jc@hyperbola.info> | 2019-05-23 19:47:59 -0400 |
---|---|---|
committer | Gaming4JC <g4jc@hyperbola.info> | 2019-05-23 19:47:59 -0400 |
commit | 73f9b2c70d4653fb47c7f60d6c11aa26a0c0b850 (patch) | |
tree | 5d1337e6614872da0c5fc28f4232852598cc98d3 | |
parent | 372fccddf49146f9a0847564959d36ba3bef2e62 (diff) | |
download | uxp-73f9b2c70d4653fb47c7f60d6c11aa26a0c0b850.tar.gz |
Issue #1101 - Support gzip-compressed SVGs in OpenType+SVG fonts
-rw-r--r-- | gfx/thebes/gfxSVGGlyphs.cpp | 38 | ||||
-rw-r--r-- | layout/reftests/text-svgglyphs/reftest.list | 1 | ||||
-rw-r--r-- | layout/reftests/text-svgglyphs/resources/svg-gz.ttf | bin | 0 -> 113804 bytes | |||
-rw-r--r-- | layout/reftests/text-svgglyphs/svg-glyph-compressed-ref.html | 15 | ||||
-rw-r--r-- | layout/reftests/text-svgglyphs/svg-glyph-compressed.html | 15 |
5 files changed, 69 insertions, 0 deletions
diff --git a/gfx/thebes/gfxSVGGlyphs.cpp b/gfx/thebes/gfxSVGGlyphs.cpp index a7615eca82..23f68f590c 100644 --- a/gfx/thebes/gfxSVGGlyphs.cpp +++ b/gfx/thebes/gfxSVGGlyphs.cpp @@ -31,6 +31,7 @@ #include "nsSMILAnimationController.h" #include "gfxContext.h" #include "harfbuzz/hb.h" +#include "zlib.h" #include "mozilla/dom/ImageTracker.h" #define SVG_CONTENT_TYPE NS_LITERAL_CSTRING("image/svg+xml") @@ -285,7 +286,44 @@ gfxSVGGlyphsDocument::gfxSVGGlyphsDocument(const uint8_t *aBuffer, gfxSVGGlyphs *aSVGGlyphs) : mOwner(aSVGGlyphs) { + if (aBufLen >= 14 && aBuffer[0] == 31 && aBuffer[1] == 139) { + // It's a gzip-compressed document; decompress it before parsing. + // The original length (modulo 2^32) is found in the last 4 bytes + // of the data, stored in little-endian format. We read it as + // individual bytes to avoid possible alignment issues. + // (Note that if the original length was >2^32, then origLen here + // will be incorrect; but then the inflate() call will not return + // Z_STREAM_END and we'll bail out safely.) + size_t origLen = (size_t(aBuffer[aBufLen - 1]) << 24) + + (size_t(aBuffer[aBufLen - 2]) << 16) + + (size_t(aBuffer[aBufLen - 3]) << 8) + + size_t(aBuffer[aBufLen - 4]); + AutoTArray<uint8_t, 4096> outBuf; + if (outBuf.SetLength(origLen, mozilla::fallible)) { + z_stream s = {0}; + s.next_in = const_cast<Byte*>(aBuffer); + s.avail_in = aBufLen; + s.next_out = outBuf.Elements(); + s.avail_out = outBuf.Length(); + // The magic number 16 here is the zlib flag to expect gzip format, + // see http://www.zlib.net/manual.html#Advanced + if (Z_OK == inflateInit2(&s, 16 + MAX_WBITS)) { + int result = inflate(&s, Z_FINISH); + if (Z_STREAM_END == result) { + MOZ_ASSERT(size_t(s.next_out - outBuf.Elements()) == origLen); + ParseDocument(outBuf.Elements(), outBuf.Length()); + } else { + NS_WARNING("Failed to decompress SVG glyphs document"); + } + inflateEnd(&s); + } + } else { + NS_WARNING("Failed to allocate memory for SVG glyphs document"); + } + } else { ParseDocument(aBuffer, aBufLen); + } + if (!mDocument) { NS_WARNING("Could not parse SVG glyphs document"); return; diff --git a/layout/reftests/text-svgglyphs/reftest.list b/layout/reftests/text-svgglyphs/reftest.list index 6f328ab739..7ff341f429 100644 --- a/layout/reftests/text-svgglyphs/reftest.list +++ b/layout/reftests/text-svgglyphs/reftest.list @@ -21,3 +21,4 @@ pref(gfx.font_rendering.opentype_svg.enabled,true) fails == svg-glyph-mask.sv pref(gfx.font_rendering.opentype_svg.enabled,true) == svg-glyph-paint-server.svg svg-glyph-paint-server-ref.svg pref(gfx.font_rendering.opentype_svg.enabled,true) == svg-glyph-transform.svg svg-glyph-transform-ref.svg pref(gfx.font_rendering.opentype_svg.enabled,true) == svg-glyph-extents.html svg-glyph-extents-ref.html +pref(gfx.font_rendering.opentype_svg.enabled,true) == svg-glyph-compressed.html svg-glyph-compressed-ref.html diff --git a/layout/reftests/text-svgglyphs/resources/svg-gz.ttf b/layout/reftests/text-svgglyphs/resources/svg-gz.ttf Binary files differnew file mode 100644 index 0000000000..3a9660224a --- /dev/null +++ b/layout/reftests/text-svgglyphs/resources/svg-gz.ttf diff --git a/layout/reftests/text-svgglyphs/svg-glyph-compressed-ref.html b/layout/reftests/text-svgglyphs/svg-glyph-compressed-ref.html new file mode 100644 index 0000000000..9bbfeb7483 --- /dev/null +++ b/layout/reftests/text-svgglyphs/svg-glyph-compressed-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>Test for compressed SVG glyphs</title> +<style> + @font-face { + font-family: test; + src: url(resources/svg.woff); /* uses uncompressed SVG documents */ + } + html { width: 400px; height: 400px; background-color: white; } + body { margin: 0; } + div { font: 200px test; color: fuchsia; line-height: 1; stroke: none; } +</style> +</head><body><div>abcdefg</div> +<div>LMNOPQR</div> +</body></html>
\ No newline at end of file diff --git a/layout/reftests/text-svgglyphs/svg-glyph-compressed.html b/layout/reftests/text-svgglyphs/svg-glyph-compressed.html new file mode 100644 index 0000000000..e8123bba69 --- /dev/null +++ b/layout/reftests/text-svgglyphs/svg-glyph-compressed.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>Test for compressed SVG glyphs</title> +<style> + @font-face { + font-family: test; + src: url(resources/svg-gz.ttf); /* copy of svg.woff using gzip-compressed SVG documents */ + } + html { width: 400px; height: 400px; background-color: white; } + body { margin: 0; } + div { font: 200px test; color: fuchsia; line-height: 1; stroke: none; } +</style> +</head><body><div>abcdefg</div> +<div>LMNOPQR</div> +</body></html>
\ No newline at end of file |