SVG textLength doesn't work, any other solution? - text

I'm having some troubles with texts in SVG, anyone could help me please?
I'd like to fit a text inside a polygone I already drew. The center of the text is perfect, but I can't control the size of the text.
Whatever I put for textLength, the text remains the same with inkscape.
<text id="monId" x="100" y="70" textLength="100" lengthAdjust="spacingAndGlyphs" fill="red" stroke="darkred" stroke-width=".2" alignment-baseline="middle" text-anchor="middle">Mon texte</text>
How to control the length (and the height) of the text? text-font works to change the size, but it doesn't show me the precise size. What does text-font="55" means precisely in a relation with the length of the text? I tried text-font="55px" but it doesn't change anything : it is way bigger than 55 pixels.
Thank you very much

Maybe you are looking for letter spacing and line spacing in inkscape:
Letter spacing
Alt +> expand line/paragraph by 1
Shift + Alt +> expand line/paragraph by 10 pixels
Alt +< contract line/paragraph by 1 pixel
Shift + Alt +< contract line/paragraph by 10 pixels
These commands (only when editing text) adjust letter spacing in the current line (regular text) or paragraph (flowed text).
The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment.
Line spacing
Ctrl + Alt +> make the text object taller by 1 pixel
Shift + Ctrl + Alt +> make the text object taller by 10 pixels
Ctrl + Alt +< make the text object shorter by 1 pixel
Shift + Ctrl + Alt +< make the text object shorter by 10 pixels
These commands (only when editing text) adjust line spacing in the entire text object (regular or flowed).
The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment.
Source: Inkscape shortcuts

Related

Get layout metrics in MathJax

I'm wondering if it's possible to extract the metrics for the baseline of the mrow elements in a rendered mathjax equation, specificically using the SVG Output Jax.
For example, the mml-sample page (raw version here ) has a block element with 3 mrow elements, and I'm wondering if it's possible to extract the position (preferably, the x and y positions of endpoints) of the baselines of these elements.
Here's the short answer: Fork a copy of Mathjax and then set the removable flag on the 'g' elements to false, to prevent the <g> elements that represent the nesting in the original MML from being removed -- an by doing this the origin of the baseline can be read from the transform="translate(...)" and transform="scale(...)" attributes
Next, export any other metrics, such as:
svg.H: Height above the baseline of the entire (sub) expression (un-scaled)
svg.D: Depth below the baseline of the entire (sub) expression (un-scaled)
svg.w: Width of the rendered expression (un-scaled)
svg.r: right margin (un-scaled)
svg.l: left margin (un-scaled)
svg.scale: Scaling factor
here and here with something like:
svg.element.setAttribute("fm",
"{D:" + SVG.Fixed(svg.D,2) +
",H:" + SVG.Fixed(svg.H,2) +
",r:" + SVG.Fixed(svg.r,2) +
",l:" + SVG.Fixed(svg.l,2) +
",w:" + SVG.Fixed(svg.w,2) +
",s:" + SVG.Fixed(svg.scale,5) +
"}");
Optionally, to reduce the extent of unnecessary nesting, change svg.removeable to (svg.removeable || svg.element.nodeName === "g") in this if statement

How to add centered text with gm for node (graphicsmagick/imagemagick)?

This relates to the "gm" extension for node, http://aheckmann.github.io/gm/docs.html
I need to add some text centered around a bounding box (horizontally is enough). The function drawText() requires x,y coordinates, but there is no way to draw centered text.
I would otherwise need a function which can return the width of a text string in the font/size given, so I can calculate my starting x position in javascript, before calling drawText().
You can use the region and gravity functions this way:
gm(filePath)
.region(WIDTH, HEIGHT, X, Y)
.gravity('Center')
.fill(color)
.fontSize(textFontSize)
.font(font)
.drawText(0, 0, 'This text will be centered inside the region')

Proper way to calculate the height and width of a SVG text

I need to calculate the height and width of a svg text element. Is there a way to do so without actually adding it to the DOM of my page? I need only the measures not the actual element.
I am using neither d3 nor Raphael, but only plain JavaScript. (Maybe I should use one of the former for my calculations?)
What I am after is just a function like imagettfbbox in PHP, but in plain JavaScript. Is there such a thing? Or is it easy to write?
Since I am not actually using the text elements it seems strange to me to add them and hide them (I also have read somewhere that Firefox has problems with calculating the bbox of hidden elements, Calculating vertical height of a SVG text). But maybe this is the only way to go? Will I have to work with opacity in that case? Do I destroy the element somehow afterwards?
Maybe there is no good way to achieve exactly what I was after. However, giving up the "without actually adding it to the DOM of my page" part, the following function seems to achieve my goal.
function bboxText( svgDocument, string ) {
var data = svgDocument.createTextNode( string );
var svgElement = svgDocument.createElementNS( svgns, "text" );
svgElement.appendChild(data);
svgDocument.documentElement.appendChild( svgElement );
var bbox = svgElement.getBBox();
svgElement.parentNode.removeChild(svgElement);
return bbox;
}
Edit:
A note on the calculation of the height: the height of the bbox returned, i.e. bbox.height, is always the full height of the glyph, i.e. a will have the same height as A. And I could not find a way to calculate them more exactly.
However, one can calculate the height of uppercase accented characters, e.g. Ä. This will be just the negative of the y coordinate of the bbox, i.e. -bbox.y.
Using this one can calculate, for example, some coordinates for vertical alignment. For example to emulate the dominantBaseline attribute set to text-before-edge, text-after-edge, and central.
text-before-edge: dy = -bbox.y
text-after-edge: dy = -bbox.height -bbox.y
central: dy = -bbox.y -bbox.height/2
Where dy is the vertical translation. This can be used to get around limitations of some applications that do not support these alignments set by attributes.
I have encountered a similar problem in VB.Net !
I written a VB.Net program that generate a SVG file and that needs to compute width of text to compute next vertical bar position as you can see in following image
The B line vertical bar is positionned in computing max text width of A line elements.
To do that in Console VB.Net application, I execute following lines of code
Private Sub WriteTextInfo(sInfo As String)
If sInfo <> "" Then
'display Text in SVG file
sw.WriteLine("<text x ='" & (xPos + 10) & "' y='" & yPos & "' fill='black' font-family='Arial' font-size='20'>" & sInfo & "</text>")
'Create Font object as defined in <text> SVG tag
Dim font As New Font("Arial", 20.0F)
'Compute width of text in pixels
Dim xSize = TextRenderer.MeasureText(sInfo, font)
'Divide pixels witdh by a factor 1.4 to obtain SVG width !
Dim iWidth As Decimal = Math.Truncate(CDec(xSize.Width) / 1.4)
'If new vertical position is greater than old vertical position
If xPos + iWidth > xPosMax Then
xPosMax = xPos + iWidth
End If
End If
End Sub
In resume, I compute text's width in pixels using TextRenderer.MeasureText() function and I divide this number by 1.4 to obtain SVG width.
1.4 value is obtained by experiment relatively to my case !
To use TextRendered and Font objects, I have added reference to
System.Drawing
System.Windows.Forms
As you can see, I don't use any DOM method to compute text's width because I compute it in VB.Net program.

How to find custom shape speicific area?

please , see following image, here you can see blue rectangle is custom shape bounds and custom shape is shoe , i want to find area of a portion written in image and i want that area in form of rectangle
do is there any path iterator concept ?
Note
custom shape i derived from image of the same size.
I would do it like this:
1.create table for all bounding box-rect perimeter lines
each value in it will represent the empty space length form border line to shape
something like this:
the values are found by simple image scanning until first non space color found
2.now bruteforce find the biggest rectangle area
x,y = top left corner
for xs = 1 to bounding box width
now scan the max valid height of rectangle from x to x + xs (x grows to the right)
// it should be the min y0[x..x+xs]
remember the biggest valid area/size combination
do this for all 4 combinations (star from the other corners)
I now Brute-force is slow but
you can divide perimeter lines not by pixels but with some step instead
also I am sure this can be optimized somehow
for example by derivation of perimeter find the extremes and check from them backwards
when the size will start shrinking then stop ...
of course take in mind that on complicated shapes this optimization will not work ...

Line width in raphaeljs

Is it real to make line with 1px weight in SVG or raphaeljs?
The follow code
var p = Paper.path("M1 1 L50 1");
p.attr("stroke", "#D7D7D7");
p.attr("stroke-width", "1");
p.attr("opacity", 0.5);
draw line which looks like 2px or 3px. Any alternative?
When SVG lines lie at their apparently correct coordinates they actually lie inbetween pixels, so when you state M1 1 L50 1 it paints half a pixel on the top and the other half in the bottom of the pixel, making it look like a thick, semitransparent line.
To solve this problem you need to either paint at half pixels, or translate your elements half a pixel, ie. element.translate(0.5, 0.5)
You can see the blurry and sharp lines here:
http://jsfiddle.net/k8AKy/
You should also use the Paper.renderfix() function since you do not know which browser your users will be using.
From the documentation
Fixes the issue of Firefox and IE9 regarding subpixel rendering. If
paper is dependant on other elements after reflow it could shift half
pixel which cause for lines to lost their crispness. This method fixes
the issue.
This links take you point what's going wrong with integer coordinates and why +0.5 was fixed edge blurring (with nice pictures!!):
http://diveintohtml5.info/canvas.html#pixel-madness
http://kilianvalkhof.com/2010/design/the-problem-with-svg-and-canvas/
Compare:
with +0.5:
You can avoid +0.5 by:
SVG_Area.setAttribute("viewBox", "0.5 0.5 " + width + " " + height);
or by wrapper:
function fiXY(x) { return parseInt(x) + 0.5; }
var rect = document.createElementNS(SVGobj.svgNS, "rect");
rect.setAttribute("x", fiXY(x));
rect.setAttribute("y", fiXY(y));
or by:
SVG_Area.setAttribute("shape-rendering", "crispEdges");
which effect on all shapes in you SVG image....

Resources