• Tk 9: image -format svg -scaletowidth not working?

    From Mark Summerfield@21:1/5 to All on Mon Jul 8 09:52:26 2024
    I am trying to use the -format svg -scaletowidth option without success.

    Given this svg file "test.svg" (copied from W3CSchools):

    <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
    <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4"
    fill="yellow" />
    </svg>

    This program works fine:

    #!/usr/bin/env wish9
    proc icon {svg {width 0}} {
    set opt [expr {$width ? "-format svg -scaletowidth $width" : ""}]
    image create photo -file $svg {*}$opt
    }
    ttk::button .button -command {destroy .} -image [icon test.svg]
    grid .button

    But if I want to scale the image to 24 pixels (e.g., for a menu item):

    #!/usr/bin/env wish9
    proc icon {svg {width 0}} {
    set opt [expr {$width ? "-format svg -scaletowidth $width" : ""}]
    image create photo -file $svg {*}$opt
    }
    ttk::button .button -command {destroy .} -image [icon test.svg 24]
    grid .button

    It fails with this error:

    Error in startup script: unknown option "-scaletowidth"
    while executing
    "image create photo -file $svg {*}$opt"
    (procedure "icon" line 3)
    invoked from within
    "icon test.svg 24"
    invoked from within
    "ttk::button .button -command {destroy .} -image [icon test.svg 24]"
    (file "./svgtest2.tcl" line 8)

    Can someone tell me what I'm doing wrong?

    I'm using Tcl/Tk 9.0b2 on Debian Linux.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Mon Jul 8 14:27:54 2024
    Am 08.07.2024 um 14:16 schrieb Ralf Fassel:
    * Mark Summerfield <[email protected]>
    | It fails with this error:

    | Error in startup script: unknown option "-scaletowidth"
    | while executing
    | "image create photo -file $svg {*}$opt"
    | (procedure "icon" line 3)
    | invoked from within
    | "icon test.svg 24"
    | invoked from within
    | "ttk::button .button -command {destroy .} -image [icon test.svg 24]"
    | (file "./svgtest2.tcl" line 8)

    | Can someone tell me what I'm doing wrong?

    | I'm using Tcl/Tk 9.0b2 on Debian Linux.

    The manpage says:

    Image formats may support sub-options, which are specified using
    additional words in the value to the -format option.

    This sounds to me as if you need to specify the additional options like -scaletowidth *with* the -format option, like so:

    -format [list svg -scaletowidth 24]

    instead of

    -format svg -scaletowidth 24

    R'

    Mark,
    sorry for the odd format. It is always bad, if internals expose on user
    level. This is an internal issue. There is only the "-format" string
    which is communicated to the image format driver. Instead of adding
    something like "driver options", this format string was extended to a list.
    I would love to change this one day...

    Thank you for your understanding,
    Harald

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Mon Jul 8 14:16:45 2024
    * Mark Summerfield <[email protected]>
    | It fails with this error:

    | Error in startup script: unknown option "-scaletowidth"
    | while executing
    | "image create photo -file $svg {*}$opt"
    | (procedure "icon" line 3)
    | invoked from within
    | "icon test.svg 24"
    | invoked from within
    | "ttk::button .button -command {destroy .} -image [icon test.svg 24]"
    | (file "./svgtest2.tcl" line 8)

    | Can someone tell me what I'm doing wrong?

    | I'm using Tcl/Tk 9.0b2 on Debian Linux.

    The manpage says:

    Image formats may support sub-options, which are specified using
    additional words in the value to the -format option.

    This sounds to me as if you need to specify the additional options like -scaletowidth *with* the -format option, like so:

    -format [list svg -scaletowidth 24]

    instead of

    -format svg -scaletowidth 24

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Tue Jul 9 10:13:19 2024
    Am 09.07.2024 um 09:26 schrieb Mark Summerfield:
    I think adding support for SVG images is a real plus for Tk.

    Yes, it is essential. All internal images in Tk 9 are now svg and are scaleable.

    The exact same svg image code is available for Tk 8.6 as an extension here:

    https://github.com/oehhar/tksvg

    The prebuild dlls are helful for many use-cases...

    And thanks to Mikko Mononen (nanosvg), Christian Gollwitzer (tksvg) and
    Csaba Nemeti (scalable Tk) !

    Take care,
    Harald

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Summerfield@21:1/5 to Ralf Fassel on Tue Jul 9 07:26:58 2024
    On Mon, 08 Jul 2024 14:16:45 +0200, Ralf Fassel wrote:

    * Mark Summerfield <[email protected]>
    [snip]
    | Can someone tell me what I'm doing wrong?

    | I'm using Tcl/Tk 9.0b2 on Debian Linux.

    The manpage says:

    Image formats may support sub-options, which are specified using
    additional words in the value to the -format option.

    This sounds to me as if you need to specify the additional options like -scaletowidth *with* the -format option, like so:

    -format [list svg -scaletowidth 24]

    instead of

    -format svg -scaletowidth 24

    Thank you, I'm now using:

    proc util::icon {svg {width 0}} {
    set opt [expr {$width ? [list -format [list svg -scaletowidth $width]]
    \
    : ""}]
    image create photo -file $::PATH/images/$svg {*}$opt
    }

    And when I call this for menu items I use:

    set width [expr {int(16 * [tk scaling])}]
    ...
    -image [util::icon new.svg $width]

    The 'int' is *essential* since -scaletowidth won't accept a real.

    I think adding support for SVG images is a real plus for Tk.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From nemethi@21:1/5 to All on Tue Jul 9 11:15:38 2024
    Am 09.07.24 um 09:26 schrieb Mark Summerfield:
    On Mon, 08 Jul 2024 14:16:45 +0200, Ralf Fassel wrote:

    * Mark Summerfield <[email protected]>
    [snip]
    | Can someone tell me what I'm doing wrong?

    | I'm using Tcl/Tk 9.0b2 on Debian Linux.

    The manpage says:

    Image formats may support sub-options, which are specified using
    additional words in the value to the -format option.

    This sounds to me as if you need to specify the additional options like
    -scaletowidth *with* the -format option, like so:

    -format [list svg -scaletowidth 24]

    instead of

    -format svg -scaletowidth 24

    Thank you, I'm now using:

    proc util::icon {svg {width 0}} {
    set opt [expr {$width ? [list -format [list svg -scaletowidth $width]]
    \
    : ""}]
    image create photo -file $::PATH/images/$svg {*}$opt
    }

    And when I call this for menu items I use:

    set width [expr {int(16 * [tk scaling])}]
    ...
    -image [util::icon new.svg $width]

    The 'int' is *essential* since -scaletowidth won't accept a real.

    I think adding support for SVG images is a real plus for Tk.

    The way you are using [tk scaling] is not quite correct. I guess your intention was to scale 16 x 16 px images according to the display's (or
    Tk's) scaling level. However, [tk scaling] is the number of pixels per
    point, hence it is not appropriate for scaling a width given in pixels.

    The recommended method in Tk 9 is to use the variable tk::svgFmt when
    creating scaling-aware images (see man tk_svgFmt). This variable is set
    at Tk initialization time to {svg -scale 1.0}, {svg -scale 1.25}, etc.,
    and is updated automatically if you increase the scaling with the aid of
    the "tk scaling" command. For example, if you invoke "tk scaling
    1.666666" or "tk scaling 1.7" then tk::svgFmt will automatically become
    {svg -scale 1.25}, hence its use as the value of the -format option will
    result in images of the size 20 x 20 px.

    --
    Csaba Nemethi https://www.nemethi.de mailto:[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Summerfield@21:1/5 to nemethi on Tue Jul 9 09:55:46 2024
    On Tue, 9 Jul 2024 11:15:38 +0200, nemethi wrote:

    [snip]
    The way you are using [tk scaling] is not quite correct. I guess your intention was to scale 16 x 16 px images according to the display's (or
    Tk's) scaling level. However, [tk scaling] is the number of pixels per point, hence it is not appropriate for scaling a width given in pixels.

    The recommended method in Tk 9 is to use the variable tk::svgFmt when creating scaling-aware images (see man tk_svgFmt). This variable is set
    at Tk initialization time to {svg -scale 1.0}, {svg -scale 1.25}, etc.,
    and is updated automatically if you increase the scaling with the aid of
    the "tk scaling" command. For example, if you invoke "tk scaling
    1.666666" or "tk scaling 1.7" then tk::svgFmt will automatically become
    {svg -scale 1.25}, hence its use as the value of the -format option will result in images of the size 20 x 20 px.

    when I try:

    puts $tk::svgFmt

    I get "Error in startup script: can't read "tk::svgFmt": no such variable"

    But in any case it wouldn't give me what I want.

    I have svg images that I'm using as icons that happen to have a notional
    size of 48x48 px. The scale factor of 16 * [tk scaling] simply represents
    the size that works for me (i.e., makes the icons a little taller than a capital letter), say for the File menu's "New" menu item. So I'm not
    really scaling to a particular pixel size, just a size that works visually
    and that should work at different scales on different screens (although I haven't yet tried that).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From nemethi@21:1/5 to All on Tue Jul 9 13:03:55 2024
    Am 09.07.24 um 11:55 schrieb Mark Summerfield:
    On Tue, 9 Jul 2024 11:15:38 +0200, nemethi wrote:

    [snip]
    The way you are using [tk scaling] is not quite correct. I guess your
    intention was to scale 16 x 16 px images according to the display's (or
    Tk's) scaling level. However, [tk scaling] is the number of pixels per
    point, hence it is not appropriate for scaling a width given in pixels.

    The recommended method in Tk 9 is to use the variable tk::svgFmt when
    creating scaling-aware images (see man tk_svgFmt). This variable is set
    at Tk initialization time to {svg -scale 1.0}, {svg -scale 1.25}, etc.,
    and is updated automatically if you increase the scaling with the aid of
    the "tk scaling" command. For example, if you invoke "tk scaling
    1.666666" or "tk scaling 1.7" then tk::svgFmt will automatically become
    {svg -scale 1.25}, hence its use as the value of the -format option will
    result in images of the size 20 x 20 px.

    when I try:

    puts $tk::svgFmt

    I get "Error in startup script: can't read "tk::svgFmt": no such variable"

    But in any case it wouldn't give me what I want.

    I have svg images that I'm using as icons that happen to have a notional
    size of 48x48 px. The scale factor of 16 * [tk scaling] simply represents
    the size that works for me (i.e., makes the icons a little taller than a capital letter), say for the File menu's "New" menu item. So I'm not
    really scaling to a particular pixel size, just a size that works visually and that should work at different scales on different screens (although I haven't yet tried that).

    In Tk 9 it makes a difference whether you write $tk::svgFmt or
    $::tk::svgFmt -- the former will only work at global level.

    --
    Csaba Nemethi https://www.nemethi.de mailto:[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Summerfield@21:1/5 to nemethi on Wed Jul 10 07:21:34 2024
    On Tue, 9 Jul 2024 13:03:55 +0200, nemethi wrote:
    [snip]

    In Tk 9 it makes a difference whether you write $tk::svgFmt or
    $::tk::svgFmt -- the former will only work at global level.

    Yes of course, sorry, still getting used to that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)