domingo, 6 de maio de 2007

Renderizando SVG

Saudações. Esse é meu primeiro post aqui, então uma pequena apresentação. Meu nome é Luiz Carlos Irber Júnior, estudante de Engenharia de Computação da UFSCar. Estou desenvolvendo, junto com o Fabio Navarro e o pessoal do LEC, o Comics (nome provisório, sugestões são bem vindas), um editor de HQ para o XO. Outra hora faço uma apresentação melhorzinha dele, agora quero postar um trecho de código que pode ser útil para vocês também.

Renderizando SVG no XO

O XO, como vocês sabem, possui restrições de espaço disponível para armazenar informação. Logo um dos pilares do Comics é que o máximo possível das imagens devam ser SVG, para poupar espaço (se puder ser SVGZ, melhor ainda). Mas isso leva a questão: como renderizar SVG no XO?
Obviamente o pessoal da OLPC já pensou nisso, e disponibiliza uma biblioteca chamada rsvg nos builds. Eis um pequeno exemplo de como usá-la:
#!/usr/bin/env python

import gtk
import rsvg
import cairo

class Main(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)

self.svg = rsvg.Handle('flag_brasil.svg')

draw_area = gtk.DrawingArea()
draw_area.connect('expose-event', self.expose_cb)

self.add(draw_area)
self.show_all()

def expose_cb(self, widget, event):
context = widget.window.cairo_create()
self.svg.render_cairo(context)

if __name__ == '__main__':
app = Main()
gtk.main()
Esse pequeno script em Python define uma classe chamada Main derivada de gtk.Window. Dentro desta janela da GTK é adicionada uma Drawing Area, mas poderia ser qualquer outro widget, inclusive um que você tenha definido. As partes realmente importantes são
self.svg = rsvg.Handle('flag_brasil.svg')
que cria um Handle (que contém outras funções bem interessantes, consultem a documentação para mais detalhes) para um arquivo SVG, e a função
def expose_cb(self, widget, event):
context = widget.window.cairo_create()
self.svg.render_cairo(context)
que fica responsável pela exibição da imagem. Essa função é executada a cada vez que o widget recebe um sinal de expose, ou seja, toda vez que ele tenha que ser desenhado na tela. Note que o atributo window de um widget só está disponível quando gtk.main() está rodando, assim não adianta tentar renderizar o SVG antes que o widget tenha seus recursos alocados no X. Um screenshot:

Lembrando que não é necessário se restringir a exibir a imagem, como eu fiz. Nessa função você pode utilizar outros comandos do Cairo para desenhar o que você quiser. Devo confessar que eu era um tanto preconceituoso com Cairo, mas funciona que é uma beleza depois que se pega o jeito. Se você ainda não pegou o jeito, esse tutorial pode ajudar bastante.

Happy Hacking!

2 comentários:

José Antonio Rocha disse...

Comix... (sugestão de nome)

Luiz Irber disse...

O problema com Comix é que já existe um software para desktop chamado Comix, que serve para a leitura de HQs scaneadas.
A gente chegou a pensar em XOmics, mas achou completamente disparatado... trocadilhos tem limites =D