Support gzip-compressed SVGs in OpenType+SVG fonts
This commit is contained in:
parent
6641b605e4
commit
60affebbd1
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Binary file not shown.
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue