#
#		Python GUI - Fonts - Gtk
#

import sys
import pango, gtk
from gtk import gdk
from GFonts import Font as GFont

class Font(GFont):

    _gdk_font = None

#	def _from_gdk_font(cls, gdk_font):
#		font = cls.__new__(cls)
#		font._gdk_font = gdk_font
#		return font
#	
#	_from_gdk_font = classmethod(_from_gdk_font)
    
    def _from_pango_description(cls, pango_description):
        font = cls.__new__(cls)
        font._pango_description = pango_description
        return font
    
    _from_pango_description = classmethod(_from_pango_description)

    def __init__(self, family, size = 12, style = []):
        if 'italic' in style:
            pango_style = pango.STYLE_ITALIC
        else:
            pango_style = pango.STYLE_NORMAL
        if 'bold' in style:
            pango_weight = pango.WEIGHT_BOLD
        else:
            pango_weight = pango.WEIGHT_NORMAL
        pfd = pango.FontDescription()
        pfd.set_family(family)
        pfd.set_size(size * pango.SCALE)
        pfd.set_style(pango_style)
        pfd.set_weight(pango_weight)
        self._pango_description = pfd
    
    def get_family(self):
        return self._pango_description.get_family()
    
    def get_size(self):
        return self.self._pango_description.get_size()
    
    def get_style(self):
        style = []
        pfd = self._pango_description
        if pfd.get_weight() > pango.WEIGHT_NORMAL:
            style.append('bold')
        if pfd.get_style() <> pango.STYLE_NORMAL:
            style.append('italic')
        return style
    
    def get_ascent(self):
        return self._get_gdk_font().ascent
    
    def get_descent(self):
        return self._get_gdk_font().ascent

    def get_height(self):
        gdk_font = self._get_gdk_font()
        return gdk_font.ascent + gdk_font.descent
    
    def _get_gdk_font(self):
        gdk_font = self._gdk_font
        if not gdk_font:
            gdk_font = gdk.font_from_description(self._pango_description)
            self._gdk_font = gdk_font
        return gdk_font

#	def get_ascent(self):
#		pfm = self._get_pango_metrics()
#		return pfm.ascent
#	
#	def get_descent(self):
#		self._get_pango_metrics()
#		return self._descent
#	
#	def get_height(self):
#		self._get_pango_metrics()
#		return self._ascent + self._descent
#	
#	def _get_pango_metrics(self):
#		pfm = self._pango_metrics
#		if not pfm:
#			pfm = _pango_context.get_metrics(self._pango_description)
#			self._pango_metrics = pfm
#			self._ascent = pfm.ascent / pango.SCALE
#			self._descent = pfm.descent / pango.SCALE
#		return pfm
    
    def width(self, s, start = 0, end = sys.maxint):
        gdk_width = self._get_gdk_font().width
        end = min(end, len(s)) # Gtk doesn't seem to check this
        return gdk_width(s, end) - gdk_width(s, start)

    def x_to_pos(self, s, x):
        if x <= 0:
            return 0
        gdk_width = self._get_gdk_font().width
        lo = 0
        x_lo = 0
        hi = len(s)
        x_hi = gdk_width(s, hi)
        if x >= x_hi:
            return hi
        # Invariant: x_lo <= x < x_hi
        while hi - lo > 1:
            mid = (lo + hi) >> 1
            x_mid = gdk_width(s, mid)
            if x < x_mid:
                hi = mid
                x_hi = x_mid
            else:
                lo = mid
                x_lo = x_mid
        # x_lo and x_hi now bound the char containing x
        if x - x_lo < x_hi - x:
            return lo
        else:
            return hi
    


    def _set_mac_specs(self, mac_font, mac_size, mac_face):
        self._mac_font = mac_font
        self._mac_size = mac_size
        self._mac_face = mac_face
        self._mac_info = None
    
    def _mac_get_info(self):
        info = self._mac_info
        if not info:
            import Windows
            old_port = GetPort()
            SetPort(_mac_dummy_port)
            self._mac_set_font()
            info = GetFontInfo()
            SetPort(old_port)
            self._mac_info = info
        return info
    
    def _mac_set_font(self):
        TextFont(self._mac_font)
        TextFace(self._mac_face)
        TextSize(self._mac_size)


_pango_context = gtk.Label().create_pango_context()
