Inkscape.org
Beyond the Basics Fill attribute of text not working
  1. #1
    unsigned_char_array unsigned_char_array @unsigned_char_array

    Fill attribute of text not working. I have an exported image from adobe XD. The color of the text renders correctly in Firefox and Chrome, but not in inkscape.
    If I add the text manually in inkscape it does work. So the bottom text does render properly
     

    Test Text
  2. #2
    Polygon Polygon @Polygon🌶

    The first line has a "none" attribute in the Fill+Stroke setting. Th second line has 70% transparency applied.

    This is how it looks here:

  3. #3
    unsigned_char_array unsigned_char_array @unsigned_char_array

    This is the fill attribute line of the top text:
    fill="rgba(255,255,255,0.7)"
    It should be semi transparent white and should look grey.

    In Chrome and firefox it looks ok, but not in inkscape.
    It only works if I use the style attribute like in the botton text:
    style="font-size:74.6667px;fill:#ffffff;fill-opacity:0.7"
    I cannot change the export

     

  4. #4
    Paddy_CAD Paddy_CAD @Paddy_CAD

    I found a related discussion in a five-year-old bug report.
    https://gitlab.com/inkscape/inbox/-/issues/1195

    This colour representation doesn't exist in SVG1.1 so current and earlier Inkscape versions don't understand it. It's been added to Inkscape 1.5 (in development and not tested by me) as part of the ongoing progress toward SVG2 implementation.

    Perhaps 1.4.1 will include the new code. Until then, I can only suggest using a regex text editor to find and replace the offending colours in your files.

  5. #5
    unsigned_char_array unsigned_char_array @unsigned_char_array
    *

    Thanks. I've written a python script which uses regex that fixes it.
    I've also tried it with an xml parser, but I don't like how they screw up formatting and pretty printing is buggy as it ignores the xml:space="preserve" attribute and adds or removes significant spaces from text fields.

    My code works with rgba colors, but also with hex colors with alpha (4 or 8 digits).
    rgba is simple to split, but hex colors required calculation since the opacity value only supports decimal and percentages not hex values.
    I've also found that stroke and flood-color can use colors with transparency so my code supports those too.
    I've only done limited testing so any feedback is appreciated.

    Here is my code:

    import re
     
    bad_image_path = "test_text.svg"
    converted_image_path = "test_text_converted.svg"
     
    with open(bad_image_path, 'r', encoding='utf8') as f:
        svg_string = f.read()
     
    # test_str = ("fill=\"#11223380\"\n"
    #   "fill=\"#1238\"\n"
    #   "stroke=\"#11223380\"\n"
    #   "flood-color=\"#11223380\"\n"
    #   "fill=\"rgba(1,2,3,0.4)\"\n"
    #   "fill=\"rgba(1,2,3,40%)\"\n"
    #   "stroke=\"rgba(5,6,7,0.8)\"\n"
    #   "flood-color=\"rgba(5,6,7,0.8)\"\n")
    # svg_string = test_str
     
    # replace split rgba colors in color and opacity:
    regex = r"(fill|stroke|flood)(-color)?\s*=\s*\"rgba\(([^\,)]+),([^\,)]+),([^\,)]+),([^\,)]+)\)\""
    subst = "\\1\\2=\"rgb(\\3,\\4,\\5)\" \\1-opacity=\"\\6\""
    result = re.sub(regex, subst, svg_string, 0, re.MULTILINE)
     
    # replace split hex colors with alpha in color and opacity:
    regex = r"(fill|stroke|flood-color)\s*=\s*\"#([[:xdigit:]]{4}|[[:xdigit:]]{8})\"".replace("[[:xdigit:]]","[0-9a-fA-F]")
     
    def hex_color_substitutor(match_obj):
        a = match_obj.group(1)
        if match_obj.group(1) == "flood-color":
            b = "flood"
        else:
            b = a
        b += "-opacity"
     
        if len(match_obj.group(2)) == 4:
            color_value = match_obj.group(2)[:3]
            opacity_float = float(int(match_obj.group(2)[3:4], base=16)/15)
        else:
            color_value = match_obj.group(2)[:6]  
            opacity_float = float(int(match_obj.group(2)[6:8], base=16)/255)  
       
        #limit to 3 decimal digits, remove unnecessary trailing zeros and decimal point:
        opacity_value = f"{opacity_float:.3f}".rstrip('0').rstrip('.')
     
        return f'{a}="#{color_value}" {b}="{opacity_value}"'
     
    result = re.sub(regex, hex_color_substitutor, result)
     
    with open(converted_image_path, 'w', encoding='utf8') as f:
        f.write(result)

    Latest code is here:

    https://github.com/ChrisIdema/svg_alpha_fix

Inkscape Inkscape.org Inkscape Forum Beyond the Basics Fill attribute of text not working