# -*- coding: utf-8 -*-
"""
Загрузка шрифтов из файла.

Использование:
    face = create_cairo_font_face_for_file("Arial.ttf", 0)
    ...
    ctx.set_font_face(face)
"""
import sys
import ctypes
import cairo
from os.path import exists

__author__ = "Zasimov Alexey"
__email__ = "zasimov-a@yandex-team.ru"


def _get_freetype_so():
    if sys.platform == 'darwin':
        return "/opt/local/lib/libfreetype.6.dylib"
    else:
        return "libfreetype.so.6"


def _get_cairo_so():
    if sys.platform == 'darwin':
        return "/opt/local/lib/libcairo.2.dylib"
    else:
        return "libcairo.so.2"


_PyCairoContext = None
_initialized = False
CAIRO_STATUS_SUCCESS = 0
FT_Err_Ok = 0
_freetype_so = None
_cairo_so = None
_ft_lib = None
_surface = None
_ft_destroy_key = None


def create_cairo_font_face_for_file(filename, faceindex=0, loadoptions=0):
    global _initialized
    global _freetype_so
    global _cairo_so
    global _ft_lib
    global _surface
    global _PyCairoContext
    global _ft_destroy_key

    if not exists(filename):
        raise IOError("Font file is not exists: %s" % filename)

    if not _initialized:

        # find shared objects
        _freetype_so = ctypes.CDLL(_get_freetype_so())
        _cairo_so = ctypes.CDLL(_get_cairo_so())

        _cairo_so.cairo_ft_font_face_create_for_ft_face.restype = ctypes.c_void_p
        _cairo_so.cairo_ft_font_face_create_for_ft_face.argtypes = [ctypes.c_void_p, ctypes.c_int]

        _cairo_so.cairo_font_face_get_user_data.restype = ctypes.c_void_p
        _cairo_so.cairo_font_face_get_user_data.argtypes = (ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p)

        _cairo_so.cairo_set_font_face.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
        _cairo_so.cairo_font_face_status.argtypes = [ctypes.c_void_p]
        _cairo_so.cairo_font_face_destroy.argtypes = (ctypes.c_void_p,)
        _cairo_so.cairo_status.argtypes = [ctypes.c_void_p]

        # initialize freetype
        _ft_lib = ctypes.c_void_p()
        if FT_Err_Ok != _freetype_so.FT_Init_FreeType(ctypes.byref(_ft_lib)):
            raise Exception("Error initialising FreeType library.")

        class PycairoContext(ctypes.Structure):
            _fields_ = [("PyObject_HEAD", ctypes.c_byte * object.__basicsize__),
                        ("ctx", ctypes.c_void_p),
                        ("base", ctypes.c_void_p)]

        _PyCairoContext = PycairoContext

        _surface = cairo.ImageSurface(cairo.FORMAT_A8, 0, 0)
        _ft_destroy_key = ctypes.c_int()

        _initialized = True

    # create freetype face
    ft_face = ctypes.c_void_p()
    cairo_ctx = cairo.Context(_surface)
    cairo_t = _PyCairoContext.from_address(id(cairo_ctx)).ctx

    errorcode = _freetype_so.FT_New_Face(_ft_lib, filename.encode("utf-8"), faceindex, ctypes.byref(ft_face))
    if FT_Err_Ok != errorcode:
        raise Exception("Error creating FreeType font face for " + filename, 'error code:', errorcode)

    # create cairo font face for freetype face
    cr_face = _cairo_so.cairo_ft_font_face_create_for_ft_face(ft_face, loadoptions)
    if CAIRO_STATUS_SUCCESS != _cairo_so.cairo_font_face_status(cr_face):
        raise Exception("Error creating cairo font face for " + filename)

    _cairo_so.cairo_set_font_face(cairo_t, cr_face)
    if CAIRO_STATUS_SUCCESS != _cairo_so.cairo_status(cairo_t):
        raise Exception("Error creating cairo font face for " + filename)

    return cairo_ctx.get_font_face()


if __name__ == '__main__':

    face = create_cairo_font_face_for_file("Arial.ttf", 0)

    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 128, 128)

    ctx = cairo.Context(surface)

    ctx.set_font_face(face)
    ctx.set_font_size(30)
    ctx.move_to(0, 44)
    ctx.show_text("Hello,")

    ctx.move_to(30, 74)
    ctx.show_text("world!")

    del ctx

    surface.write_to_png("hello.png")
