I'm generating some simple svg for data visualization and as part of that I need
to render several lines of text. I'm using the simple text/textspan. However when
determining when to break the line, I need to know the width of the string. Note that I am not using javascript, these are static svg diagrams. My manual mockups work fine on all three platforms(Mac/Windows 10/Linux) in several different browser. I've been searching, but all attempts to find anything about string widths involves dynamic SVG and javascript. Is there any data anywhere on the character widths of the default fonts? I'm using rather simple svg. I'm using the default transform and coordinate space as well. Or do I have to write a javascript test page to return the widths?
Thanks.
The standard font is determined by settings of the renderer. Browsers will use the same font they use for HTML content, set by the user and depending on fonts installed on their system. That means text size will differ for each end user.
There is no way around measuring the text after rendering.
Related
he following banner is an example of what i want:
https://top.gg/api/widget/535064930727100427.svg
https://top.gg/api/widget/698275428976164945.svg
It's automatically generated and contains dynamic text which causes the "background color" to automatically adjust its size to it as well as have a border radius.
The text and shapes are all paths when I look at the source.
I would like to know how this has been accomplished as SVG itself does not support a dynamic border radius and background color by default.
Somewhere in the SVG source of the links above it showsid="surface19" and I did some research to see what piece of software or library provides such ID's. The text also seems to automatically be converted to paths, so it's not a hand-written SVG that gets modified programmatically from what it seems.
I did a lot of research before asking this question.
I would like to generate some diagram style graphics using SVG and use text in the diagrams. My problem is, how to know the size of the text in advance to be able to adjust the rest of the layout accordingly. To make this explicit: I'm not talking about SVG in a browser. I would like to work with fixed units and generate PDF for printing for example. So if I use a 12pt font, it should also be printed as 12pt font.
To have a more concrete example: Lets assume I have the three strings "bla", "blablub" and "blubblablub". I would like to print them in a given 12pt font, determine the string size and enclosing boxes and draw the biggest sized box around all of them. The idea is to have equally sized boxed around all, based on the longest text.
Could somebody give me a hint how to do that or why it is not possible? Searching for this topic, I only get some JavaScript tricks in the browser, which usually involves rendering the text and then re-rendering everything again.
Is there a nice and easy way to to have the functionality of lengthAdjust (together with textLength) for shrinking text if necessary (if too wide) but never attempting to stretch it?
Two possible solutions for a SVG generated through JS come to my mind:
Count characters (or rather grapheme clusters) and based on that (together with some heuristics unless a fixed-width size font is used) determine whether to set textLength or not.
First do it without textLength set and then determine using getBBox() whether the text needs some shrinking in which case textLength will be set.
Both solutions are IMHO quite ugly (and possibly buggy from my recollections of past encounters with getBBox()). Is there maybe some nicer solution I missed?
Have a look at this: https://stackoverflow.com/a/39886640/1925631
Essentially, make a path which spans the exact coordinates where you want to spread your text on a path. Measure this path. Then, measure how many pixels your text requires, with a font-size of 1px (and other desired font-features). Now adjust the font-size to fill your desired percentage of the available path advance width. Adjust start-offset and text-anchor. Now finally calculate your author specified textLength and choose a lengthAdjust value to get exact alignment on low precision / non-conformant renderers.
Finally, if you need to support viewers without text on a path rendering support, you can use a conformant viewer with javascript support to create a backwards compatible/fallback version. Render the content and use the SVG DOM api to fetch the x, y and rotate values for each character/glyph, now create a new SVG DOM representation with those attributes specified. You might need javascript to calculate absolute width and height for the root svg element as well, and a correctly specified viewBox, and cascade/resolve/convert all css selectors/rules/properties to inline attributes. But this way you can get cross-platform, cross-browser/viewer rendering of text, with a single compilation step per immutable source file version.
I've also made a gist to ease the last step, of resolving the css and removing all classNames, while preserving the rendered end-result: https://gist.github.com/msand/4b37d3ce04246f83cb28fdbfe4716ecc
This is for the purpose of a single universal svg + javascript codebase, and web+ios+android software development (based on react + react-native + react-native-svg)
is it possible to create a stroke with a dynamic width with SVG? I want to achieve a Calligraphy look like here, here or here.
Is this even possible? It seems customization of strokes in SVG is fairly limited. Even gradients in strokes seem to be non-trivial (see here).
There is a proposal to add into SVG standard a mechanism, that does exactly what you want:
http://www.w3.org/Graphics/SVG/WG/wiki/Proposals/Variable_width_stroke
http://lists.w3.org/Archives/Public/www-svg/2013May/0041.html
There's even an example implementation available here:
https://rawgit.com/birtles/curvy/master/index.html
It is, however, by no means official and we cannot be even sure it'll ever be.
Until then you'll need to stick to Bezier curves and object filling:
You can also use calligraphic fonts, for example - Tangerine available on Google CDN:
This approach requires less work since you don't need to draw everything from scratch, but then again, using third party fonts leaves you with little control over the final result.
You can't dynamically adjust the stroke of a path element. However you could draw a path, use a fill color on it instead of stroke, then double back upon the letters at a slight distance away from the original line.
Also, if you are using the SVG on the web then you can use css fonts on text elements. There are some pretty good cursive fonts that you can use for free... just check google web fonts.
I'm interested how to construct certain kinds of layout in RTF documents, ideally using techniques that do not depend only on the most recent RTF standards, and that are "native", i.e., they do not involve embedding other representations, like picture files. In particular:
In Postscript and DVI, I can specify a coordinate at any time that the next text will be printed at: can this be done with RTF?
Can RTF compose characters through overstriking?
Can lines, outline boxes and filled boxes be drawn, with their geometry specified either absolutely, or relative to text?
You can use the \pvpg \phpg \posx123 \posy123 construct after
you start a paragraph with \pard to position it relative to the top left of the page. See: http://biblioscape.com/rtf15_spec.htm#Heading39
Yes, but it's rather involved, and I think it was only introduced in RTF 1.5. See the drawing objects section of the spec. Here is a basic example of drawing a box (I'm not sure it's entirely valid but it should give you an idea of how to work with drawing objects):
{\rtf1\ansi\deff0
{\pard {\*\do
\dobxcolumn \dobypara
\dprect \dpx0 \dpy0 \dpxsize1000 \dpysize1000 \dplinew25
}\par}
}
If you're doing any work with RTF it's worth picking up O'Reilly's RTF Pocket Guide.
I don't believe this is possible. You'd need to use tabs and newlines to get the text where you want it.
Not really, unless \strike and \strikedl count.
http://www.biblioscape.com/rtf15_spec.htm#Heading52 says drawing objects are an option, and so is inserting images, but neither are really "native", both being absent in the first RTF specs. (And the latter is a bad choice for i.e. just a line.)