svg graphic: fixed and scalable - svg

I draw graphics for my program in corel draw (x6),
after that export it as svg files, and my program
uses this svg files.
Let's say I draw "arrow" in corel draw program.
It consists of tip and line.
I need to show this "arrow" in my program,
but I need "tip" part to be not scalable,
while "line" should be scalable.
The most simple solution which works, split "arrow"
into two parts, convert "tip" part to bitmap during program starts.
But it requires too much time for complex pictures.
And I wonder, is it possible in svg format to say this part should
not be scaled, and this should? And how this can be exported from corel draw?
I found something suitable in corel draw, to play with scale for diffrent parts of picture,
but during export to svg all my definitions was lost.

Unfortunately, there is no concept of a non-scaling element. At my last job, I worked with the SVG working group to try to get this feature introduced (nonscaling elements are really useful in engineering drawings), and it is on the roadmap for SVG 2.
The issue is SVG-ISSUE-2400.
The way to do this for now, is to implement a zoom event, that dynamically rescales nonscaling elements when the zoom level changes.

Related

Logic for "Erase SVG Stroke"?

Problem
Hi,
So I have noticed that software like Microsoft Edge and OneNote and Notability, store hand drawn strokes as vector curves or lines. They also provide the ability to erase strokes, by dragging the eraser over them.
I wanted to implement something similar in my software, an SVG Animation and Creation bundle, and I have come up with the logic for the freehand stroke to SVG curve, a demo is available here:
https://phantomzback.github.io/SvgFreehandDrawDemo/polylineTest.html
It uses the polyline tag with the cursor positions, and path simplification is something I also plan to implement. But before that, I need a way to detect if the eraser has gone over the stroke. I have an approach but I am not sure how great of an approach it is. I'd appreciate advice on how this can be improved or alternative methods to tackle the problem.
Current Idea
Find the pixels where the stroke is rendered, and save it in an array. Then, check for if the eraser tool is active and goes over that stroke. If it does, delete this stroke.
Finding the pixels shouldn't be very hard since a polyline is a bunch of points and lines drawn between them. But I plan on adding support for paths later, for which a better approach might be needed.
Thanks in advance!

How do I alter the stroke width along a path/line?

Having read the SVG2 draft, I am slightly disappointed to learn that there will be no new line caps than the standard 3. The new arc line join is brilliant however, but not what this question is about (I just wanted to mention that).
I had been hoping for a cap that ends in a triangle. But given my use case, that might not be ideal either.
As far as I can gather, Adobe Illustrator - which I do not use myself - allows the width of a stroke to be variable. This is useful when drawing from a drawing tablet, to highlight the pressure of the lines. It's true, this functionality exists in many bitmap drawing programs, but is there a way to achieve this effect in SVG, without having to draw multiple lines?
The idea is that each node should have a width, and the lines should then 'smoothly' scale the width between each node that had a different width.
Is this possible? And if not, could it be considered?
P.S. I should point out, that this is more a thought experiment and an idea than something that hinders my process. More of a nice to have than need to have.
While this may not be a true answer (SVG standard wise at least), it turns out that in the current trunk version of Inkscape, this feature called PowerStroke already exists. There are some screenshots of PowerStroke.
This should satisfy my quest for the time being.
It turns out - as well - that the arc line joins was actually suggested by Inkscape as well, they are just called extrapolate in Inkscape.

Troubles resizing SVG in Raphael

I am trying to draw this svg of europe using raphael. For each path in the svg, I've parsed it and do: r.path([countrypath]). This works, but the problem is that it is gigantic. For example, some of the paths look like M 11689.234, 6005.2561... It isn't even coming close to fitting on a 500x500 canvas. How do I resize this? Raphael's scale/translate don't seem to work, or I don't know how to use it. I noticed in the SVG each path has transform="translate(5.875e-4,7.538462e-5)" Do I need to somehow change the viewBox? Or change the svg path's somehow before it touches Raphael?
you can use scale(Xtimes,Ytimes,centreX,centreY)
where Xtimes,Ytimes are the proportion reduction if you select 0.2 the images would be reduced to 1/5th
and
centreX, centreY are relative coordinates where you should select 0,0 so that all paths/parts of svg are scaled down uniformly and relatively
if you select scale(0.2,0.2,0,0) your image would be properly reduced to 1/5th
I actual picked out quite a large SVG of the world yesterday and fed it through the SVGTOHTML converter.
You will find the tool and associated info #
http://www.irunmywebsite.com/raphael/svgsource.php
I set up a whole load of resources for Raphael #
http://www.irunmywebsite.com/raphael/raphaelsource.php
Amongst these you will find the world map wrapped in the scale pluton provided by Zeven!
The 20minute exercise delivered this...
http://www.irunmywebsite.com/raphael/colourmap2.php
Hopefully this will help you or someone with a similar problem in the future.
Also note that you can simplify paths in SVG editors as well as scale them before you put them in the SVGTOHTML converter.
Quite often maps can be drawn to extreme detail but simplifying them will greatly reduce path length.
You have two options either use what I did, use the .transform("transform string") to scale the paths, the transform string can be sww,hh,xx,yy where ww and hh is by how much you want to scale the path.
.transform("s0.25,0.25,0,0");
You can find an EXAMPLE HERE or jsfiddle HERE.
Or use
paper.scaleAll(n);
where n is the amount by you want to scale the whole paper by. First create the path in the page and then scale the paper object by maybe half
paper.scaleAll(0.5);
You can find the library and examples for the Scale.Raphaeljs library in the link below:
Scale Raphael library
Translating by such a small amount seems a bit wasteful, it's ~0 anyway, I doubt you'd see much of a difference if you stripped off the transform attributes that look like that.
Yes, changing the viewBox could make it fit to whatever you wanted in all viewers that support SVG, but raphael itself doesn't support viewBox (you'd have to provide some VML fallback yourself).
Either preprocess the path data to fit your particular use (probably a good idea anyway, it always helps to keep the filesize down, wikipedia maps are usually quite large) or use raphael's scale function to scale the paths to a proper size.
Update: Raphaƫl v2.0 and later does support viewBox (via the setViewBox method).
You can use the Raphael attribute 'translation', which takes an x,y delta. ie:
r.path([countryPath]).attr({translation:'-11689, -6005'});
To make it more reusable for multiple paths, you could parse the x and y values from the M in your svg path. When I did this, it turned out that I didn't want my path to be exactly on the 0,0 since that sent it over the canvas as well -- might take some adjustment depending on the height and width of your element.

How to generate sprite art assets for different resolution screens?

I'm working on a game using OpenGL displaying sprites, i.e. 2d quad-mapped graphics with no projection, that will be displayed on several different resolution screens. (i.e. iPhone retina/non-retina, iPad.. my next project the problem will expand to desktop resolutions which are far more numerous)
I'm OK with handling different aspect ratios, that can be handled by opengl and my placement of the sprites. I'm also OK with slightly different resolutions - use same art and either border the screen, or display a little bit more info.. but when things start to grow/shrink by like 50%+ it's a major issue.
What is standard procedure for generating the art assets in this situation? Generate for the largest resolution and just let OpenGL worry about resizing during it's rasterizing, or do people generate art sets for each main resolution?
Rasterized sprite art tends to get ugly when it's stretched (interpolated), so I'm concerned.. but generating different sizes really means for practical purposes I have to go with vector drawings and export several resolutions. Limits the artist and is somewhat complicated as far as loading and managing the assets
(Yes, I can "just try it" to an extent, but I already have an idea of the results. I'm looking for solutions people use and angles I maybe wouldn't have thought of. This question does have an answer(s) it's not subjective or lazy)
You are correct that scaling bitmaps tends to make sprites bad. There are a couple of ways of dealing with that:
Draw them (pixelart) at all required resolutions. That is a lot of work but gives you full control.
Draw them (vectors) and render them at all required resolutions. Less work but scaling up or down beyond 50% or 200% might give bad results.
Draw them (3D appliction) and render them at all required resolutions. Quite some work but a very consistent set of sprites.
For each of these options you are free to post-process the bitmaps to clean them up or add details but if you do this for options 2 and 3, you are breaking the chain and will have to apply the changes again when rendering the same set again.
An other option is to limit the variation of resolutions.
As far as I know it is very common in the (game) industry to make all (or the most used/visible) sprites as pixel perfect as possible. This is what they pay the artists for...

Advanced Text Rendering with Direct3D

Let me describe the "battlefield" of my task:
Multi-room audio/video chat with more than 1M users;
Custom Direct3D renderer;
What I need to implement is a TextOverVideo feature. The Text itself goes via network and is to be rendered on the recipient side with Direct3D renderer. AFAIK, it is commonly used in game development to create your own texture with letters/numbers and draw this items. Because our application must support many languages, we ought to use a standard. That's why I've been working with ID3DXFont interface but I've found out some unsatisfied limitations.
What I've faced is a lack of scalability. E.g. if user is resizing video window I have to RE-create D3DXFont with new D3DXFONT_DESC while he's doing that. I think it is unacceptable.
That is why the ONLY solution I see (due to my skills) is somehow render the text to a texture and therefore draw sprite with scaling, translation etc.
So, I'm not sure if I go into the correct direction. Please help with advice, experience, literature, sources...
Your question is a bit unclear. As I understand it, you want easily scalable font.
I think it is unacceptable
As far as I know, this is standard behavior for fonts - even for system fonts. They aren't supposed to be easily scalable.
Possible solutions:
Use ID3DXRenderTarget for rendering text onto texture. Font will be filtered when you scale it up too much. Some people will think that it looks ugly.
Write custom library that supports vector fonts. I.e. - it should be able to extract font outline from font, and build text from it. It will be MUCH slower than ID3DXFont (which is already slower than traditional "texture" fonts). Text will be easily scalable. Using this way, you are very likely to get visible artifacts ("noise") for small text. I wouldn't use that approach unless you want huge letters (40+ pixels). Freetype library may have functions for processing font outlines.
Or you could try using D3DXCreateText. This will create 3D text for ONE string. Won't be fast at all.
I'd forget about it. As long as user is happy about overall performance, improving font rendering routines (so their behavior looks nice to you) is not worth the effort.
--EDIT--
About ID3DXRenderTarget.
EVen if you use ID3DXRenderTarget, you'll need ID3DXFont. I.e. you use ID3DXFont to render text onto texture, and then use texture to blit text onto screen.
Because you said that performance is critical, you can delay creation of new ID3DXFont until user stops resizing video. I.e. When user starts resizing video, you use old font, but upscale it using texture. There will be filtering, of course. Once user stops resizing, you create new font when you have time. you probably can do that in separate thread, but I'm not sure about it. OR you could simply always render text in the same resolution as video. This way you won't have to worry about resizing it (it still will be filtered - along with the video). Some video players work this way.
Few more things about ID3DXFont. There is one problem with ID3DXFont - it is slow in situations where you need a lot of text (but you still need it, because it supports unicode, and writing texturefont with unicode support is pain). Last time I worked with it I optimized things by caching commonly used strings in the textures. I.e. any string that was drawn more than 3 frames in the row were rendered onto D3DFMT_A8R8G8B8 texture/render target, and then I've been copying that string from texture instead of using ID3DXFont. Strings that weren't rendered for a while, were removed from texture. That gave some serious boost. This solution, however is tricky - monitoring empty space in the texture, removing unused strings, and defragmenting the texture isn't exactly trivial (there is nothing exceptionally complicated, but it is easy to make a mistake). You won't need such complicated system unless your screen is literally covered by text.
ID3DXFont fonts are flat, always parallel to the screen. D3DXCreateText are meshes that can be scaled and rotated.
Texture fonts are fuzzy and don't look very clear. Not good for an app that uses lots of small text.
I am writing an app that can create 500 text meshes, each mesh averaging 3,000-5,000 vertices. The text meshes are created once, then are static. I get 700 fps on a GeForce 8800.

Resources