Calculate exact font size

I need a way to find the exact size and position of the glyph relative to its bounding box.

We use D3.js to create an SVG with a title, a smaller line, and short text. To a large extent, these are:

Lorem ipsum

Lorem ipsum dolor

Lorem ipsum dolor sit amet,
consectetur adipisicing elit,
sed do eiusmod time
incididunt ut labore et dolore
magna aliqua

As in this example, I need the text to be left-aligned regardless of the font size.

The problem is that each line bounding box is aligned, not glyphs. Because of what headings look indented. How can I calculate this space between the bounding box and the glyph so that I can align the text correctly?

A colleague sat down and manually measured this for an English font that works very well. We could probably do this in Adobe Illustrator, but we need information for fonts in English, Chinese, and Arabic. To do this manually is more or less impossible.

The only solution I can come up with is to type each character in the canvas element and display each pixel to see where the glyph begins and ends.

What I think would be ideal is a way to use SVG font path information to find extremes, so we get exact numbers instead of estimates. Our estimates have a large margin of error. Is there a way to do this using node.js?

An example of what SVG looks like:

<svg viewBox="0,0,1008,1424" height="1052px" width="744px" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(50,150)" class="container"> <g transform="translate(0,205)" class="textContainer"> <g fill="white" font-family="serif" font-size="" class="header"> <text> <tspan y="147.7104222717285" style="" font-size="208" x="-21.8359375">Lorem ipsum</tspan> </text> <text> <tspan y="201.46275431823733" style="" font-size="45" x="-4.72412109375">Lorem ipsum dolor</tspan> </text> </g> <g lengthAdjust="spacingAndGlyphs" textLength="297" fill="white" transform="translate(0,214)" font-family="sans-serif" class="paragraph" font-size="14"> <text y="16.8" x="0">Lorem ipsum dolor sit amet,</text> <text y="33.6" x="0">consectetur adipisicing elit,</text> <text y="50.4" x="0">sed do eiusmod tempor</text> <text y="67.2" x="0">incididunt ut labore et dolore</text> <text y="84" x="0">magna aliqua</text> </g> </g> </g> </svg> 

These are the x and y values ​​for the text and tspan elements that we need to calculate, and the negative x values ​​in particular. Note. In fact, we do not use the serif or sans-serif font families, we use our own font. I do not think that the English font is designed to use the Internet. We used fontsquirrel.com to create the SVG font file.

Update

SVG fonts looked like the most logical option, since you have all the information about the path in the file that can be read in node. You just need to interpret it. But we discovered and decided to go with opentype.js , which works with otf and ttf fonts.

I would still like to know if this is possible with SVG fonts.

+7
svg glyph
source share
2 answers

I think this can do what you want. Note that this requires jQuery and is a bit hacked. You can set the line height in css object.

 function glyphSize(glyph,css){ var span = $('<div>'); span.text(glyph); span.css({ display:'inline-block', position:'fixed', top:'100%' }).css(css); $('body').append(span); var out = { width:span.width(), height:span.height() } span.remove(); return out; } var size = glyphSize('a',{ 'font-family':'fantasy, sans-serif' // css to apply to the test element }); /* size = { width:7, height:20 } */ 

edit: quick demo here

+1
source share

I saw your question and ran into a problem myself. In my opinion, I decided it is very simple. I just created a new text element with an opacity of 0.0. I add it to svg, get bbox and delete it. Bbox contains width and height:

 getBBox : function(svgId, text, styleClass) { // Add tmp text element to the SVG var tempSvgTextElement = d3.select("#" + svgId) .append("text") .style("opacity", 0.0) .attr("class", styleClass); var tSpanTextNode = document.createTextNode(text); var svgTSpan = tempSvgTextElement.append("tspan").attr("class", styleClass).node(); svgTSpan.appendChild(tSpanTextNode); var bbox = tempSvgTextElement.node().getBBox(); tempSvgTextElement.remove(); return bbox; } 
0
source share

All Articles