-
Notifications
You must be signed in to change notification settings - Fork 2
CSSTranscodingHelper
Found in the io.sf.carte.echosvg.transcoder.util
package, it is an utility for transcoding documents that use modern CSS, bypassing the EchoSVG style computations which (except for selectors) are mostly tied to the old CSS2.
To obtain the best results, your document should define style properties in a style sheet or the style attribute, instead of using style-like attributes like font-size
.
For example it is preferable:
<text style="font-size: 20px;">
to:
<text font-size="20">
Modern CSS is allowed, with most of the following specifications being supported:
-
Selectors Level 4.
-
Values and Units Level 4 (
calc()
, viewport-based units). -
Values and Units Level 5 (advanced
attr()
). -
Color Level 4 (
color(display-p3 -0.61 1.09 -0.22)
) andcolor-mix
from Level 5. -
Custom properties Level 1 (
var()
). -
Properties and Values API Level 1 (
@property
rule). -
Media Queries Level 4 (
@media screen and (400px <= width <= 700px)
). -
Conditional Rules Level 4 (
@supports (color: lch(45% 30 60))
).
As an example of what the helper can do, please see this test document. All of the CSS shown there is supported.
Wrap your transcoder with the helper, and proceed with it:
Transcoder transcoder = new PNGTranscoder();
CSSTranscodingHelper helper = new CSSTranscodingHelper(transcoder);
helper.transcode(input, output);
and that's all.
Media Queries use the SVG viewport dimensions by default, but you can set the dimensions used by queries by setting the SVGAbstractTranscoder.KEY_WIDTH
and SVGAbstractTranscoder.KEY_HEIGHT
transcoding hints. And the target medium (screen, print, etc.) can be set via the SVGAbstractTranscoder.KEY_MEDIA
hint.
For example:
Transcoder transcoder = new PNGTranscoder();
CSSTranscodingHelper helper = new CSSTranscodingHelper(transcoder);
helper.getTranscoder().addTranscodingHint(SVGAbstractTranscoder.KEY_MEDIA, "screen");
helper.getTranscoder().addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, 450);
helper.getTranscoder().addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, 500);
String uri = "https://www.example.com/my_image.svg";
java.io.Reader reader = ... [SVG document reader]
java.io.OutputStream os = ... [where to write the image]
TranscoderOutput output = new TranscoderOutput(os);
helper.transcode(reader, uri, output, null);
or alternatively:
TranscoderInput input = new TranscoderInput(reader);
input.setURI(uri);
TranscoderOutput output = new TranscoderOutput(os);
helper.transcode(input, output);
You can enable the dark mode with
helper.setDarkMode(true);
You can also render <svg>
elements that are located inside an HTML document. By default, the first <svg>
element (in document order) will be used, but you can point to a specific one using a CSS selector. For example:
helper.transcode(reader, uri, output, "#mySvg");
alternatively:
TranscoderInput input = new TranscoderInput(reader);
input.setURI(uri);
TranscoderOutput output = new TranscoderOutput(os);
helper.getTranscoder().addTranscodingHint(SVGAbstractTranscoder.KEY_SVG_SELECTOR, "#mySvg");
helper.transcode(input, output);
And instead of the default XML parser (perfectly valid for XHTML) you can use an HTML one. You could use the validator.nu HTML parser (one of the parsers used by the Firefox browser). For that, you have to add the dependency first:
implementation group: 'nu.validator', name: 'htmlparser', version: '1.4.16'
<dependency>
<groupId>nu.validator</groupId>
<artifactId>htmlparser</artifactId>
<version>1.4.16</version>
</dependency>
and then
HtmlParser parser = new HtmlParser(XmlViolationPolicy.ALTER_INFOSET);
parser.setCommentPolicy(XmlViolationPolicy.ALLOW);
parser.setXmlnsPolicy(XmlViolationPolicy.ALLOW);
helper.setXMLReader(parser);
helper.setHTMLEmbedding(true);
Note that calling setHTMLEmbedding(boolean)
is not required if the document uri ends with .html
.
The processing of foreign elements located inside a <foreignObject>
is performed via SVG 1.2 features. Therefore, if a document contains foreign elements, the <svg>
element should either not have a version
attribute, or that attribute's value must be 1.2
or 2
.