Text along a path (GNU Emacs)

 

SVG specifications allows flowing text along a curve via textPath element. This opens up possibilities for cool text effects e.g. Formula Editor in GNU Emacs.

This fix for librsvg was  available in 2014 [4]. But this wasn't applied for some reason. However, librsvg has moved to Rust since then. The code below is pre-Rust version of librsvg.


sample.svg

<?xml version="1.0" encoding="UTF-8"?>
<svg height="300" width="800" xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
    <path id="my_path1" d="M 50 100 Q 25 10 180 100 T 350 100 T 520 100 T 690 100" fill="transparent" />
    <text>
        <textPath xlink:href ="#my_path1" font-size="34"> Text along a path looks awesome!!
        </textPath>
    </text>
</svg>

 

Text wrapping

Text wrapping using inline-size attribute (new implementation). This allows for pixel-precise fonts. In other words, instead of restrictions based on points (=1/72 of an inch) for font-size, one can specify pixel-size. How do you verify? In this case (monospace font), it's simple: 200px / 25px = 8 chars !


sample.svg

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
     width="100" height="300">

  <path d="M 0,25 H 120 M 0,225 H 120 M 62.5,25 V 2" stroke="red"/>
  <text x="62.5" y="25" inline-size="200"
    style="font: 25px IPAMincho; inline-size: 200px; writing-mode: vertical-rl;">
    テキストは10文字後に折り返されます。</text>

</svg>

  

CSS Parsing

libcroco is the CSS parsing engine behind the C version of librsvg. Some useful code snippets for the same.

    char *str = "body { font: 20px \"Noto Naskh Arabic\", serif; inline-size: 200px; direction: rtl;}";

    CRStatement *stmt = cr_statement_parse_from_buf (str, CR_UTF_8);
    CRSelector *selectors;
    cr_statement_ruleset_get_declarations (stmt, &selectors);
    CRDeclaration *declarations;
    cr_statement_ruleset_get_declarations (stmt, &declarations);
    printf("\n%d %s", cr_declaration_nr_props (declarations),
           cr_declaration_to_string (declarations, 2));
    for (int i = 0; i < cr_declaration_nr_props (declarations); i += 1) {
        CRDeclaration *decl = cr_declaration_get_from_list (declarations, i);
        const char *property = cr_string_peek_raw_str (decl->property);
        const char *value = cr_term_to_string (decl->value);
        printf ("%s: %s important: %d\n", property, value, decl->important);
    }

 

Code

 

References

 
 
 
 

Comments

Popular posts from this blog

GNU Emacs as a Comic Book Reader

Data Visualization with GNU Emacs

Tinylisp and Multi-threaded Emacs