With fabric 2.0 text got a major lift up. A huge work.
This is an high level introduction of the internal process of rendering a text in fabric.js.
If you want to develop your own text feature, you should read this page, to get an idea of what is going on
before dig in to the js files following the code.
There are 2 main topic i would like to talk about, measuring the text and rendering it on the canvas element.
_splitTextIntoLines,
fabric divides the text in lines ( searching for the newLine char ),
and split text into graphemes. If you do not know what are graphemes, make a pause, search on internet and get it clear.fabric.util.graphemeSplit
that you can override with the one that supports your specific use case.HTMLCanvasElement
provide us a measureText
method that will tell us how large is a char, with cross browser
differences as in web best tradition.fabric.charsWidthCache
with a set of sub properties and objects:- charsWidthCache - arial_normal_normal - F: 100 - a: 90 - Fa: 185 - b: 90 - ab: 180 - arial_bold_normal
Now those information gets saved in this organized cache so that the next time we find the same couple or the
same char, we just retrieve the information and we do not have to measure again.
We measure at 200px because the ms family of browsers is giving back rounded results and this was causing
rounding errors in cursor placements when the canvas or text were scaled. by much.
We only measure at one size. we assume that a font gliph at size 100 is double wide than one at size 50.
This assumption works for us and gives us the ability to measure a gliph only once.
So we get a glyph width and couple width, by difference we know how large is that char near the preceding one.
We take note of everything in an array of bounding boxes for our text. In those boxes we save what we call
the width
and the kernedWidth
of that character.
if we have some charspacing ( positive or negative ) that number get added to both width and kernedWith in the glyph bounding box.
Before textDecoration
was a string containing a list of space separated values of `underline` `overline` and `strikethorugh`
Each of this options now got a boolean and textDecoration property is gone.
var myText = new fabric.Text('fabric 2.0', { underline: true, overline: true });