Changing lower letter to upper letter in SVG - svg

Svg File
I am working on a graphics application where I can only use Arc, Line, cubic and Quadratic bézier. I have an SVG file, which is a bit long but I just took first few path elements to build to see the output. I wrote a small application which replaces lower letters to upper letters and produced a simple SVG file which consists upper causes and consists only four SVG commands. I have created two paths with original for and the second path with a modified version to confirm my output. Everything seems work fine excluding lower letter ‘m’. The result is not correct. I am not sure way. Any help should be very much appreciated. What mistake I am making? To see the converted version you have to uncomment the send path

There are several things wrong with your SVG.
Your path consists of eleven subpaths. Each of the subpaths form a very thin horizontal rectangle. For example, look at the first subpath:
M 21.52,184.48, H 91.11, v-.07, H21.54, l 0,.07 Z
That's a rectangle that is 91px wide and 0.07 pixels high. A rectangle that is 7/100 of a pixel high is going to be very faint at best. It is visible in Firefox, but Chrome seems to be culling it completely for some reason.
Your fill is invalid.
fill="New_Gradient_35"
should be:
fill="url(#New_Gradient_35)"
Your path definition is invalid. There should not be commas before a path command letter.
M21.52,184.48,H91.11,v-.07,H21.54,l0,.07Z,
should be
M21.52,184.48H91.11v-.07H21.54l0,.07Z
Chrome is a little forgiving. It will allow commas after a coordinate value, but not after a path command. So it doesn't mind:
M21.52,184.48,H91.11,v-.07,H21.54,l0,.07Z
but it doesn't like the comma between the Z and the M:
M21.52,184.48,H91.11,v-.07,H21.54,l0,.07Z,
M ...etc...
Firefox doesn't accept either comma.
You are specifying a stroke colour, but your stroke-width is "0", so your stroke will not be drawn. But perhaps that was intentional.
If you fix these issues, you get a more successful result. I'm not sure if it was what you are expecting though. It doesn't look much like a letter "m" to me.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 498.9 498.9" width="100%" height="100%">
<linearGradient id="New_Gradient_35" x1="369.44" y1="1293.18" x2="137.44" y2="718.97" gradientTransform="translate(15.85 -609.22)" gradientUnits="userSpaceOnUse">
<stop offset="0.07"/>
<stop offset="0.93" stop-color="#454d51"/>
</linearGradient>
<title>Test One</title>
<g id="Case">
<path fill="url(#New_Gradient_35)" stroke-width="0" stroke="red" d="M21.52,184.48H91.11v-.07H21.54l0,.07Z
M469,147.4q1.62,0,3.21,.12l-406.4,0c.67,-.05,1.35,-.09,2,-.12l401.16,0Z
m8.55,.76,.22,0H60.82l.56,-.1h6l-5.47,.06Z
m1,.2,.7,.15,-419.89,0,.4,-.09,418.79,0Z
m2.21,.5,.31,.08H185.41v-.07Z
m1.88,.5,.37,.11H55.54l.23,-.07,426.9,0Z
m.74,.22,.16,0,-428.69,0,.43,-.13,428.11,0Z
m.85,.27,.47,.15H227.91l-63.75,0v0l58.44,-.08Z
m.8,.27,.23,.08,-432.07,0,.35,-.12,431.49,0Z
m.55,.19,.33,.12,-433.37,0,.39,-.14Z
m.83,.31,.2,.08H51.93l.2,-.08Z" />
</g>
</svg>

Related

how does fill-rule="evenodd" work on a star SVG

I saw the following svg shape when i was trying to understand fill-rule in SVG
<div class="contain-demo">
<svg width="250px" height="250px" viewBox="0 0 250 250">
<desc>Yellow star with intersecting paths to demonstrate evenodd value.</desc>
<polygon fill="#F9F38C" fill-rule="evenodd" stroke="#E5D50C" stroke-width="5" stroke-linejoin="round" points="47.773,241.534 123.868,8.466 200.427,241.534 7.784,98.208 242.216,98.208 " />
</svg>
</div>
Please note the following:
The SVG has just one path.
The SVG has intersecting points.
if i change fill-rule="nonzero" the entire SVG get the fill.
Currently with fill-rule="evenodd" applied the SVG's central area does't get the fill.
Why is it that with fill-rule="evenodd" the central portion of the star SVG is not filled ?
I did read the spec for fill-rule="evenodd"
This value determines the "insideness" of a point in the shape by
drawing a ray from that point to infinity in any direction and
counting the number of path segments from the given shape that the ray
crosses. If this number is odd, the point is inside; if even, the
point is outside.
But i still don't understand why when i apply fill-rule="evenodd", the middle of the star is not filled. Can somebody please explain this ?
This is how the mechanism works. Pick a point in the center, draw lines to infinity in any direction - they always cross an even number of path segments -which means that they are "outside" and their areas don't get filled.
Pick a point in the filled triangles - if you draw lines to infinity in any direction - they always cross an odd number of path segments and thus, they are "inside" and their area should be filled.

Space between SVG stroke and fill

Filling and stroking a circle with the same color and a stroke-width exceeding a certain size, produces a strange transparent region “between” the two paint regions. What is going on?
This is happening in both Chrome and Firefox, so it may be to spec, but I couldn’t find any language in the spec about this behavior.
Fiddle
<svg viewBox="0 0 300 300">
<circle cx="100" cy="100" r="8"
stroke="#000" stroke-width="40"
fill="#000"/>
</svg>
Produces this rendering:
As Robert Longson noted, the issue shows up when a stroke overlaps itself in such a way that it creates a donut-hole when you convert the stroke outline to a separate path (depending on the winding-order / fill-rule calculations).
The gap between the fill and stroke in your particular example is caused by the "inside" edge of the stroke extending across the entire fill region and out the other side.
It gets really weird when you have dashed strokes, as shown in the examples from Tavmjong Bah's discussion article.
This is, unfortunately, neither according to the SVG spec nor against the spec. Instead, the spec at this point of time has left the matter undefined.
SVG working group discussion is here.
At this point, WebKit, Blink, and Firefox on Mac/Android draw strokes with cut-outs, using the Skia graphics library or Apple's CoreGraphics.
IE/Edge and Firefox on Windows/Linux just draw the total stroke, without cut-outs, as do Inkscape and Illustrator and most PDF-rendering software (the PDF spec itself is non-committal).
Everyone I've discussed this with agrees that the cut-outs are a sub-optimal result. But with so many browsers using rendering engines that do it this way, the SVG working group wasn't willing to make the more-intuitive stroke behavior a strict requirement. So instead, the SVG 2 spec has a warning-to-authors with a sample figure:
At this point, the best prospect for making a change would be to file issues (or contribute code) on the Skia library. If it was changed, that puts pressure on Apple to update to match, and the SVG spec would be able to make it official.
I found that adding stroke-linecap="round" style="stroke-dasharray: 1000" fixes the issue by introducing virtual dashes
<svg viewBox="0 0 300 300">
<circle cx="100" cy="100" r="8"
stroke="#000" stroke-width="40"
fill="#0F0" stroke-linecap="round" style="stroke-dasharray: 1000" />
</svg>
It's an artifact because the stroke width is so big it crosses the centre of the circle. It shouldn't happen but it's easily avoided by increasing r and decreasing the stroke-width.

How can I have a cumulative translate within an SVG patternTransform?

Consider the following SVG:
<?xml version="1.0" standalone="no"?>
<svg width="600" height="600" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<pattern id="Pattern0" patternTransform="skewX(5)" x="0" y="0" width="0.1" height="0.042">
<line x1="0" x2="1200" y1="0" y2="0" stroke-dasharray="25,25" style="stroke:#000000;stroke-width:1" />
</pattern>
</defs>
<rect fill="url(#Pattern0)" width="600" height="600" style="stroke:#0000FF;stroke-width:1" />
</svg>
Here's the fiddle to see it in action.
I'm trying to stagger the dashed lines in this pattern by some offset. The example above is a horizontal line, but the real lines may be rotated to any angle. The offset should be defined in the same units as the dasharray.
Adding a patternTransform="translate(x)" to the pattern doesn't work -- it just offsets the position of the entire repeated pattern instead of translating each repeated line in a cumulative fashion. Same goes for adding transform="translate(x)" to the line.
Adding a patternTransform="skewX(x)" works for horizontal lines and patternTransform="skewY(x)" works for vertical ones, but it doesn't work right at all for lines at other angles. Also, skewX/skewY require an angle as the argument, and I really need to move the lines based on the same units as the dashArray.
EDIT: Without boring anyone with the gory details, my ultimate goal is to translate AutoCAD hatch patterns into SVG files that I can use as background images in HTML. To see a little about how these patterns work, please see some of the examples here:
AutoCAD 2010 User Documentation (Note the three links on the left -- overview, dashed lines, and multiple lines).
I would love to use an SVG pattern to do this, but it's looking more and more like I'll have to return to previous attempts of using a loop to create individual lines. I was trying to avoid this because frankly I've forgotten way too much high school trig and getting enough lines (at an arbitrary angles) to fill the canvas is eluding me.
There isn't a short-cut way to create a staggered pattern. You'll need to draw out a set of staggered lines yourself, up to the point where you can get the effect you want with a repeating (possibly skewed or rotated) rectangular grid.
To get the effect of two dashed lines, with the dashes offset to each other, your repeating tile needs to have two lines.
<?xml version="1.0" standalone="no"?>
<svg width="600" height="600" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<pattern id="Pattern0" patternUnits="userSpaceOnUse"
x="0" y="0" width="100%" height="8.4%"
style="stroke:#000000;stroke-width:1;
stroke-dasharray:25,25; " >
<line x1="0" x2="100%" y1="1%" y2="1%" />
<line x1="0" x2="100%" y1="5.2%" y2="5.2%"
style="stroke-dashoffset:25" />
</pattern>
</defs>
<rect fill="url(#Pattern0)" width="600" height="600"
style="stroke:#0000FF;stroke-width:1" />
</svg>
Explanation of the changes:
I've changed to userSpaceOnUse units to define the pattern tile. This ensures that percentages defined when drawing the pattern are interpretted the same way as percentages drawn when defining the size of the tile. (User space is default for patternContentUnits.) The rectangle in your sample was the same size as the user space, so it wasn't making a difference, but it does if you change the size of the rectangle.
If you really wanted the spacing of the lines to be proportional to the size of the rectangle being filled, this is a problem. You could change both patternUnits and patternContentUnits to objectBoundingBox (the default for patternUnits), but then you have to define all your stroke properties relative to the rectangle size as well.
I've doubled the height of the tile, so that it is equivalent to two of your original tiles. One tile now includes two horizontal lines.
I've offset the first line slightly so it doesn't get cut off by the edge of the tile (you were only getting a half-pixel stroke width displayed, and the difference becomes obvious if the second line isn't similarly clipped).
I've added the second line, with the dash pattern offset, at a vertical position that is half the tile height below the first line (1% + 8.4%/2 = 5.2%).
Like #Robert Longson, I'm not 100% certain I understand what you're asking, so if this isn't the effect you want please post a drawing of what you're trying to achieve.

Space between hexagons in SVG

I've tried to make some hexagon-based map in SVG. Unfortunately, there are white spaces between fields.
I've disabled fields' borders (stroke="none stroke-width="0"), rounded all floating points to integers and made sure that hexagons have common points (no space between them). It didn't help.
Two screenshots shows same SVG in different magnifications http://imgur.com/GLiJs,gi3pt
Source code is here: http://pastebin.com/hqwTKW4M (remember to change extension to svg, after download).
Setting shape-rendering property to 'crispEdges' for all hexagons (or group of them) solves this issue. E.g.
<polygon
points="0,90 45,12 135,12 180,90 135,168 45,168"
fill="green" stroke="none" stroke-width="0"
shape-rendering="crispEdges" />
http://www.w3.org/TR/SVG/painting.html#ShapeRenderingProperty

Using a clipping path with a positioned object in Webkit

Consider this simple SVG file:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:x="http://www.w3.org/1999/xlink"
viewBox="0 0 353 150">
<defs>
<clipPath id="walk0"><rect width="44" height="70" /></clipPath>
<image id="img" x:href="http://phrogz.net/tmp/walking-girl2.png"
width="353" height="70" />
</defs>
<use x:href="#img" clip-path="url(#walk0)" />
<use x:href="#img" y="80" clip-path="url(#walk0)" />
</svg>
The intent is to have two copies of the spritesheet clipped to the same region, with the second copy 80 units lower down. This works as intended in Firefox (the clipping path is applied before the y offset). In Chrome and Safari, however, the second image is not shown. (The clipping path is applied using global SVG unit space, and hence shows an empty area of the image.)
1) Which one of these browsers is correct?, or
2) What is the simplest, standards-based way to achieve this goal?
I can work around the problem by using wrapping <g> elements with transforms; this works in both Firefox and Chrome. But I'm hoping that there's a simpler way to achieve the same results in a correct and cross-browser manner.
FWIW, I also tried setting clipPathUnits="objectBoundingBox" on the clipPath, but this always produced an unclipped image. This was true even when I wrapped the <image> in a <symbol> with an explicit viewBox, height and width and referenced that with the <use> instead of the <image>. Either I don't understand how objectBoundingBox is supposed to work, or support for it is currently broken. It is certainly possible that the answer is the former instead of the latter. ;)
The easiest, standards-compliant way to differentiate between these is to use the SVG test suite provided by W3.org. This suite provides tests for use structs that you can play with to determine compliance, among many others.
The problem is how your y value is being parsed, which is causing your figure to translate out of the second frame, but only in some browsers. This is the correct, cross-browser way to specify the desired translation:
<use x:href="#img" clip-path="url(#walk0)"transform="translate(0,80)"/>
I would assume the dubious parsing with respect to the current clipping pane is a regression.

Resources