css4j / echosvg

SVG implementation in the Java™ Language, fork of Apache Batik, supporting level 4 selectors and colors.
Apache License 2.0
39 stars 2 forks source link

transcoder: add a CSS rendering helper utility (issue#35) #60

Closed carlosame closed 2 years ago

carlosame commented 2 years ago

CSSTranscodingHelper

Utility for transcoding documents that use modern CSS, bypassing the EchoSVG style computations.

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">  

Supported CSS

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)). • 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 3 (@supports (color: lch(45% 30 60))).

Configuring for Media Queries

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 re = ... [SVG document reader]
   java.io.OutputStream os = ... [where to write the image]

   TranscoderOutput dst = new TranscoderOutput(os);

   helper.transcode(re, uri, dst, null);

Using a selector

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(re, uri, dst, "#mySvg");

Foreign Elements

The processing of foreign elements 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.

carlosame commented 2 years ago

Thank you @bfiics for your feedback. I'm pushing a new version where I added a dark-mode toggle, and also a setXMLReader method that allows an arbitrary document parser (even an HTML5 parser) to be used.

I plan to merge this today.

bfiics commented 2 years ago

Keep up the good work man!