brndnmtthws / conky

Light-weight system monitor for X, Wayland (sort of), and other things, too
https://conky.cc
GNU General Public License v3.0
7.17k stars 615 forks source link

How to draw SVG image at x,y position with lua? #1144

Closed ohnonot closed 2 years ago

ohnonot commented 2 years ago

It is possible to draw SVG images with lua. But I haven't been able to get any sort of documentation or even a list of available functions for this. All I found is this (and this) - the example script works, but whatever I do I cannot figure out how to draw the image at a specific x,y location. It always draws the image at 0,0.

It is possible that I'm missing something obvious (I'm fairly new to conky's lua scripting abilities), but afaics the function rsvg_handle_render_cairo_sub does not take any positional x,y arguments, and I see nothing else that would do that.

Maybe I have to first create some sort of rectangle within an existing cairo surface and tell the rsvg function(s) to paint to that?

$ conky --version
conky 1.12.2_pre compiled 2021-09-26 for Linux x86_64

Compiled in features:

System config file: /etc/conky/conky.conf
Package library path: /usr/lib/conky

 General:
  * math
  * hddtemp
  * portmon
  * IPv6
  * Curl
  * Weather (METAR)
  * support for IBM/Lenovo notebooks
  * builtin default configuration
  * old configuration syntax
  * Imlib2
  * OSS mixer support
  * apcupsd
  * iostats
  * ncurses
  * Internationalization support

 Lua bindings:
  * Cairo
  * Imlib2
  * RSVG
 X11:
  * Xdamage extension
  * Xinerama extension (virtual display)
  * Xshape extension (click through)
  * XDBE (double buffer extension)
  * Xft
  * ARGB visual
  * Own window

 Music detection:
  * CMUS
  * MPD
  * MOC

 Default values:
  * Netdevice: eno1
  * Local configfile: $HOME/.conkyrc
  * Localedir: /usr/share/locale
  * Maximum netdevices: 256
  * Maximum text size: 16384
  * Size text buffer: 256
ohnonot commented 2 years ago

Got it.

It is as I suspected:

Maybe I have to first create some sort of rectangle within an existing cairo surface and tell the rsvg function(s) to paint to that?

Example function to draw an SVG image at x,y, scaled to w,h:

require 'cairo'
require 'rsvg'

function conky_draw_svg_file(path,x,y,w,h)
   local rh = rsvg_create_handle_from_file(path)
   local rd = RsvgDimensionData:create()
   rsvg_handle_get_dimensions(rh, rd)
   iw, ih, em, ex = rd:get()
   if w and h then
      do_scale=1
   else
      do_scale=0
      w=iw
      h=ih
   end
   local cs = cairo_xlib_surface_create(conky_window.display, conky_window.drawable, conky_window.visual,x+w,y+h)
   local cr = cairo_create (cs)
   cairo_translate (cr, x, y)
   if do_scale == 1 then
      cairo_scale (cr, w/iw, h/ih)
   end
   rsvg_handle_render_cairo(rh, cr)
   rsvg_destroy_handle(rh)
   cairo_surface_destroy(cs)
end

Sorry for the noise.