-
Notifications
You must be signed in to change notification settings - Fork 483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Suport for WOFF File Format #43
Comments
It would be cool to support WOFF. I haven't looked at the spec yet, but because of the compression it is more bandwith-friendly with minimal changes. |
Yes, I guess uncompressing would be easy via the zlib.js. However, I couldn't really understand what the underlying format of WOFF (after decompression) would be, as far as I understood it could be any of TTF, OpenType etc? Btw., here's an implementation of reading WOFF Headers, might help: |
I'd be happy to see WOFF support too! |
I made an example of woff to otf conversion: http://jsbin.com/rijuvad. It uses https://github.com/arty-name/woff2otf (which is based on python version), which uses https://github.com/nodeca/pako/blob/master/dist/pako_inflate.min.js. The text above is rendered by opentype.js draw() function and the text below is normal fillText: There is also newer woff2, but the support is currently so low that basically using woff (and SVG/EOT/TTF/OTF) are needed at least few years to the future: |
opentype.min.js is 79.9 KB. woff2otf.min.js is 1.13KB. pako_inflate.min.js. is 22.19KB. Pako says it is "Almost as fast in modern JS engines as C implementation". Could this be the method to allow loading WOFF into opentype.js? If reverse is needed (is it?), then there is need for also Pako deflate which is 26.3 KB. Other possibility is to make use of browser's native deflate/inflate, if "the lock" is some day removed. So far I have not found a native way, but it surely is there, because browser can decompress on the fly files that are deflated on server and browser can read/write compressed PNG files. |
Cool! I'll look at Pako next week. |
I was a bit worried about adding 22.19KB Pako Inflate to opentype.js, and fortunately I found another library, Imaya zlib.js, which is only 6.82KB and seems to be significantly faster than Pako (at least in this very limited test with one woff font). Devongovett send then a message (see below) and provided even smaller library Tiny-Inflate, which is only 3.74KB. And this provided to be even faster than Imaya. TINY-INFLATE: IMAYA: PAKO: (All times are measured in Chrome OSX Macbook Pro Mid 2010. Fastest of ten samples.) If I understand the things right, woff can have multiple compressed/non-compressed tables, which means that every table needs to be decompressed individually. The following confirms that: The main body of the file consists of the same collection of font data tables as the input sfnt font, stored in the same order, except that each table MAY be compressed, and the sfnt table directory is replaced by the WOFF table directory. ( http://www.w3.org/TR/2012/REC-WOFF-20121213/#OverallStructure ) And arty-name:s woff2otf does just this table "separation" and calls inflate every time when compressed table is found. I assume that usually webfont glyph amount and other tabledata are tried to keep as minimal as possible, so such inflate library that can decompress fast many small data blocks is the winner. Of course it is wise to test with many different woff:s before making a decision which inflate library to choose. |
If you're worried about file size, https://github.com/devongovett/tiny-inflate is only 1.3KB min+gzipped. Probably not the fastest library, but it's definitely one of the smallest. FWIW, not sure how you're measuring performance, but pako has been the fastest library in my tests, and according to their own benchmarks. |
I got also Tiny-Inflate working. It gave Data error, but it was some 2-byte header which had to be stripped: http://jsbin.com/qiwase/edit?html,js,output This is how I measured the performance: TINY-INFLATE:
IMAYA:
PAKO:
If you find any flaws in performance measuring, please report. EDIT: Maybe those |
I made a SO question about the native DEFLATE/INFLATE support: http://stackoverflow.com/questions/32838795/native-deflate-inflate-in-browsers. Hopefully this is coming to browsers some day. Until it we have to make use of libraries. |
I got also Tiny-Inflate working by stripping a 2-byte header from compressed buffers before inflation, and in addition to that it is tiny, it is also fast: only 6 ms in my test. Pako advertises itself to be the fastest, and devongovett says that tiny-inflate is slower than Pako, but this test shows opposite. Maybe this is due to that the buffer lengths are rather small:
I updated the above messages of mine to include also Tiny-Inflate. |
@timo22345 try to do couple of dummy passes before measurement. JS JIT needs to collect stat to warm up and reoptimize underlying code. |
@puzrin Thanks for the tip! I just tried that, but can't get it to go below 33ms in OSX Chrome. |
@puzrin Yes, you were right. It was my measurement. I was pressing always the JSBIN run button. When I added an own Execute button, the code runs in minimum of 1.5 ms. The first run is always about 35ms, but then the next is 2 - 20 ms and finally when warmed up the final higher speed is reached. Funny! This is the code with Execute-button: |
This "warming up" means that those other libs also run faster after warmup. The performer in unwarmed test (Tiny-Inflate) runs also in 1.2 - 1.5 ms when warmed up (using Execute-button): I have to test these libs more with larger fonts and report here the results in various font sizes. |
You can do estimate without any additional measurements :) . Inflate speed is usually 30-100 mb/sec, depending on implementation. Font size is << 10mb. Unpacking will take 0.3 sec in worst case (that will never happen in real world). |
@timo22345 Using your examples, tiny-inflate runs always faster here (Firefox: ≈6ms before warm-up, ≈1ms after). With its tiny size, it could be a winner. |
That looks awesome! I'll look at tiny-inflate on Monday. |
Okay, I tried with both Pako and tiny-inflate. For tiny-inflate, I had to strip the two-byte header as @timo22345 suggested (Thanks Timo!). Both seem to be working fine, but since tiny-inflate is smaller, I prefert it over Pako. The code is in the woff-support branch, if anyone wants to check it out. I'll test some more with different fonts, then release later this week. |
@fdb, FYI there is raw deflate stream, and wrapped deflate data. Wrapped data has 2-bytes header and 4-bytes Adler checksum tail. I guess, tiny deflate supports raw streams only, but that's enougth for your needs. |
Are there any plans to support Web-Fonts (WOFF) i.e. to read from Google-Fonts and the such? As far as I understood, on could actually use zlib.js to decompress the woff format?
The text was updated successfully, but these errors were encountered: