
"Text rendering using Cairo and Pango."

import cairo
import pango
import pangocairo

from glitch.cairo.draw import CairoTexture

class Text(CairoTexture):
    "Text rendering using Cairo and Pango."

    def __init__(self, text, font_spec='Sans 64',
            bg=(0, 0, 0, 0), fg=(1, 1, 1, 1), **kw):
        """
        @param text: The text to render.
        @param font_spec: A Pango font description string.
        @param bg: The background color, as an ARGB tuple.
        @param fg: The foreground color, as an ARGB tuple.
        """

        self.text = text
        self.font_spec = font_spec
        self.bg = bg
        self.fg = fg
        (width, height) = self._measure_fake()
        CairoTexture.__init__(self, width, height, **kw)

    def make_font_description(self):
        return pango.FontDescription(self.font_spec)

    def _measure_fake(self):
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
        cr = cairo.Context(surface)
        return self.measure(cr)

    def measure(self, cr):
        pcr = pangocairo.CairoContext(cr)
        layout = self.make_layout(pcr)
        (logical, inked) = layout.get_pixel_extents()
        (ix, iy, iw, ih) = inked
        return (iw, ih)

    def make_layout(self, pcr):
        layout = pcr.create_layout()
        desc = self.make_font_description()
        layout.set_font_description(desc)
        layout.set_text(self.text)
        return layout

    def _clear(self, cr):
        cr.save()
        cr.set_operator(cairo.OPERATOR_SOURCE)
        cr.rectangle(0, 0, self.width, self.height)
        cr.set_source_rgba(*self.bg)
        cr.fill()
        cr.restore()

    def _debug(self, cr):
        cr.set_source_rgb(0.6, 0.6, 0.6)
        cr.rectangle(0, 0, self.width, self.height)
        cr.stroke()
        # XXX: This should be at the baseline, not at the bottom.
        cr.move_to(0, self.height)
        cr.rel_line_to(self.width, 0)
        cr.set_source_rgb(1, 0, 0)
        cr.stroke()

    def draw_cairo(self, cr):
        self._clear(cr)
        #self._debug(cr)
        pcr = pangocairo.CairoContext(cr)
        layout = self.make_layout(pcr)
        cr.set_source_rgba(*self.fg)
        pcr.show_layout(layout)

