admin管理员组文章数量:1178539
I want to retrieve the outline information of font glyphs as bézier paths in HTML5. This would allow me to randomize the outlines:
In Cocoa, I would use appendBezierPathWithGlyph:inFont:
. In Java, I would use TextLayout.getOutline()
. How does this work in JavaScript?
I discovered that Mozilla has mozPathText
but I can't get it to work.
I want to retrieve the outline information of font glyphs as bézier paths in HTML5. This would allow me to randomize the outlines:
In Cocoa, I would use appendBezierPathWithGlyph:inFont:
. In Java, I would use TextLayout.getOutline()
. How does this work in JavaScript?
I discovered that Mozilla has mozPathText
but I can't get it to work.
3 Answers
Reset to default 33Out of necessity I've created my own library called opentype.js. It parses OpenType, TrueType, PostScript and WOFF fonts.
Here's how it parses a typeface:
- Load the
.ttf
/.otf
file using aXMLHttpRequest
. - Parse the
glyf
andloca
table to extract the letter shapes (glyphs). - Parse the
cmap
table which contains the mapping from characters to glyphs. - Parse the
head
andhmtx
table to get the metrics, basically the spacing between each letter.
Then it can create a bézier path:
- Convert the letters of the text into glyphs.
- Convert the coordinates of the glyph to quadratic curves.
- Adjust the spacing using kerning information.
This results in a path that you can draw using the HTML5 canvas:
var font = opentype.parseFont(arrayBuffer);
var path = font.getPath("Hello, World!", {x:0, y:150, fontSize:72});
path.draw(ctx);
The demo website has a live example.
Low-level parsing
In JavaScript you will have to manually parse the typeface file and extract the path data you need. AFAIK there is no helper-library for this at the moment so you are left to do this yourselves.
To parse a file you will also need to upload it manually and parse it as raw data using the new File API and possible typed arrays for binary font formats (ttf).
It's possible to write a very long answer for this as this is rather low-level stuff and to broad to be covered here (IMHO). However, here are the file format specifications for the common font files:
- WOFF (recommended)
- Embedded OpenType
- Open type
- Open Font
- TrueType
- Type 1 (PDF)
But there is another approach you can take as an intermediate step saving you a lot of pain:
Pre-parse
Select the typefaces you want to use. Run them through Java/Cocoa/.NET (WPF) or whatever you prefer and build arrays containing the information you need (for example, WPF gives you the path data for each glyph). Convert them to JavaScript arrays or JSON objects and use those for the render and manipulation. The resulting points will be in em
values which are easy to scale.
Now you can simply go through the arrays and render the path segment type (line, bezier etc.) and modify the point positions.
mozPathText
is for canvas and just holds the text path (currently Path API is not exposed in any browser, but will in the future - however, it cannot be used for this as the low-level path data per glyph isn't available for many reason, legal reasons possibly being one).
Trace
The third approach is to sort of "OCR" the glyphs on the canvas by tracing each individual glyph and try to build paths from it's traced outline.
This can be done in several way - one way is to parse line by line and group pixels based on distance/connectivity and then iterate through the group/region using neural networks or fill algorithms to find the outer boundaries for the glyph.
Or - you can draw the text as outlines and just trace the connected pixels for each shape and use that as a line path.
In this case you may run into challenges that may seem simple enough but can turn out to not be.
Example: the letter O
consist of an outer path and an inner path. The inner path punches a "hole" in the outer path. You cannot define this behavior directly just by defining paths in canvas so you need to add "cuts" between the two paths after you have determined they belong to each other, and then join them at the cuts.
Using different composite modes may help in creating the illusion of such but you will still need to determine which path is the solid part and which will be drawn as the "hole".
Warp/distortion
A final approach is to not use glyph paths at all but just warp the bitmap using interpolation and warp grid (typically used in connection with 3D textures):
http://davis.wpi.edu/~matt/courses/morph/2d.htm
Warping (pdf)
Morphing (pdf)
Define your own fonts/paths (manual trace)
The more obvious option perhaps: define your own font paths from scratch. A bit more work in the area of either making a font designer or by manually tracing an image, or defining the paths manually. A "font-plotter" (using a trace image) is not so complicated but require patience.
You can use a canvas in the browser to record the lines you are plotting and use smoothing algorithms (cardinal spline + knee detection) to get nice round curves and sharp corners.
It all depends on what result you want in the end and how much work you are willing to put down. There is unfortunately no free ticket in this regard as the internal data isn't exposed (and probably won't be in the future either).
With SVG it's possible in some browsers to do the reverse of what you're asking: specify custom font glyphs as bezier paths, and then lay out text using them. You could possibly import an SVG font and then perform your transformations on that. But even though SVG is now widely supported, SVG fonts are not. Only Safari, Chrome, and Opera currently have support for them.
If you want to do these types of transformations with system fonts in a vector way, that's not possible in any browser that I know of. There's simply no API in HTML or SVG to get the outline path of an installed glyph. (Maybe there's something you can use in a plugin like Flash, I haven't checked out their text API for a while.)
If you're okay doing it the raster way, you can use a hidden canvas element to lay out your text in an off screen buffer and then get a pixel map of the result. You can then perform pixel-based transformations on it and draw that into a second, visible canvas element.
本文标签: htmlHow do I get glyph outlines of a letter as b233zier paths using JavaScriptStack Overflow
版权声明:本文标题:html - How do I get glyph outlines of a letter as bézier paths using JavaScript? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738066910a2058076.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
canvas
and usegetImageData()
to derive the data. – alex Commented Jun 28, 2013 at 7:47save as>svg
. in the settings pickfont: type>svg, subsetting>all
. this will give you a file with svg paths for each character, eg<glyph unicode="=" horiz-adv-x="596" d="M556,337l0,60l-516,0l0,-60M556,141l0,60l-516,0l0,-60z"/>
. there's only a handful of commands and this should be really easy to parse, modify and draw into a canvas. see w3.org/TR/SVG/paths.html#PathDataMovetoCommands – kritzikratzi Commented Jul 2, 2013 at 22:50