Hi, what about adding a way to specify units for the SVG output? SVG supports several units[1]: em, ex, px, pt, pc, cm, mm, in, and percentages; but cairo hardcodes the document units to be pt. What about a function like cairo_svg_surface_set_unit(surface, unit) ? The units can be passed as enum values and the function would set the right unit identifier as a string to use when writing the <svg> element in _cairo_svg_document_finish() If the idea looks good I can work on a patch. Thanks, Antonio [1] http://www.w3.org/TR/SVG/coords.html
This would be useful in librsvg as well. The rsvg-convert(1) utility can extract an object from an existing SVG file and render it to another SVG. We'd like to preserve the units used in the original SVG file. GNOME would like to use that to do: rsvg-convert --export-id=some-icon-name -o some-icon-name.svg big-file-with-all-icons.svg
Hi Federico, if the signature cairo_svg_surface_set_unit(surface, unit) looks OK to you I can come up with a proper patch to cairo. Are the cairo upstream developers interested in this functionality? Thanks, Antonio
Antonio, sorry for the extreme delay in reply, but I'd certainly be interested in seeing your patch. Inkscape supports the various SVG units so may be worth referencing. I don't know if it applies here but Inkscape also needed to update the dpi assumptions for the units, so that's something to be aware of.
Hi Bryce, I'll try to come up with something in the next few weeks after taking a look at what Inkscape does. Thanks, Antonio
Created attachment 134799 [details] [review] svg: add a new function to specify the SVG document units Hi, the attached patch shows what I have in mind, it adds a cairo_svg_surface_set_document_unit() function to allow users to set a unit for the width and height values of the root <svg> element. In particular my use case is to draw on the surface thinking in pixels and still have the expected result when generating SVG output. Currently this is not possible because cairo hadcodes the unit as "pt" in the generated SVG file. I noticed that rsvg behaves quite sanely with any of the units while Inkscape doesn't seem to like the relative ones (em, ex, %). Finally, since the change only affects the header of the generated output file I have the feeling that there is no need to deal with dpi in cairo: editors and rasterizers will do that if appropriate. Thanks, Antonio
Created attachment 134800 [details] Example program for cairo_svg_surface_set_document_unit() Here is an example program for cairo_svg_surface_set_document_unit().
Seems like it would be ok for the api to just take the string that is printed, rather than defining an enumeration in Cairo that will have to be updated if svg's set of units changes.
Please post API proposals to the mailing list for discussion.
Comment # 8 on bug 90166 from Adrian Johnson The proposed api in this bug https://bugs.freedesktop.org/show_bug.cgi?id=90166 uses an enumeration for each of the svg unit types, but nothing is ever done with that enumeration other than to print a 2-letter string into the svg output. I propose a better api would be to just accept the string and print it without any checking. This would remove the need to modify cairo on any svg updates that add new units, and also probably makes it much easier to copy the units from one svg to another. Proposed api: void cairo_svg_surface_set_document_unit (cairo_surface_t*, const char*) The string pointer must point at a valid svg unit type, such as "pt" or "em". NULL is the same as "" (which means "user" units). The function should do some basic sanity checks (maximum length, and only printing ASCII) and is a no-op if it fails. On Wed, Oct 11, 2017 at 1:45 PM, <bugzilla-daemon@freedesktop.org> wrote: > Comment # 8 on bug 90166 from Adrian Johnson > > Please post API proposals to the mailing list for discussion. > > ________________________________ > You are receiving this mail because: > > You are watching the QA Contact of the bug.
(In reply to Bill Spitzak from comment #9) > [...] > Proposed api: > > void cairo_svg_surface_set_document_unit (cairo_surface_t*, const char*) > > The string pointer must point at a valid svg unit type, such as "pt" > or "em". NULL is the same as "" (which means "user" units). The > function should do some basic sanity checks (maximum length, and only > printing ASCII) and is a no-op if it fails. > Hi Bill, the API I propose is modeled after cairo_svg_surface_restrict_to_version() which also uses an enum, so cairo users are already familiar with this approach, and I think it's OK for a few more reasons: 1. IMHO it's a little more robust, it allows to produce only valid documents (after we discuss if relative units are OK to use). 2. The implementation is simple, hence more verifiable, for instance there is no need to escape special characters like " to assure that the XML is well formed. 3. The event of new units being added to the SVG spec seems quite rare, so having cairo react to that (even in a minor release) seems OK considering the benefits of 1. and 2. Sanitizing user strings is a bother, when possible I prefer avoiding a problem rather than having to solve it. Ah, after writing the reply I noticed you already posted to cairo@cairographics.org, I'll subscribe and follow up over there as well. Ciao, Antonio
Created attachment 135226 [details] [review] svg: add a new function to specify the SVG document unit v2 Hi, here is v2 of the patch. Changes since v1: * Reoder the units: put the USER unit as the first one as this seems to be the default unit according to the SVG specification. * Fix some minor typos in comments, reword some sentences in the documentation. * Mention that the default unit for SVG documents generated by cairo is "pt". * Add a getter function to retrieve the current unit of a SVG surface. NOTE: In the documentation blocks I left the parameter name to @surface even though the actual parameter in the code is called abstract_surface, because this is how it's done in other places like cairo_svg_surface_restrict_to_version(). Ciao, Antonio
Created attachment 135227 [details] Example program for cairo_svg_surface_set_document_unit() An here is an updated test program.
commit 15559b54af473d720da9e03b0e769c54a53505a9 Author: Antonio Ospite <ao2@ao2.it> AuthorDate: Wed Oct 11 18:51:13 2017 +0200 Commit: Bryce Harrington <bryce@osg.samsung.com> CommitDate: Mon Dec 4 13:58:34 2017 -0800 svg: add a new function to specify the SVG document unit Add a cairo_svg_surface_set_document_unit() function to allow users to set a unit for the width and height values of the root <svg> element. In particular this allows to draw in pixels and still have the expected result when generating SVG output. Add also the correspondent getter function. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=90166 Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.