package provide Freetype::fttypes 0.1

if {![info exists _source([file tail [info script]])]} {
package require Freetype::ft2build
#package require $FT_CONFIG_CONFIG
package require $FT_SYSTEM
package require $FT_IMAGE
package require $FT_ERRORS


ffidl::typedef FT_Int16  sint16
ffidl::typedef FT_UInt16 uint16
ffidl::typedef FT_Int32  sint32
ffidl::typedef FT_UInt32 uint32


ffidl::typedef FT_Bool      {unsigned char}
ffidl::typedef FT_FWord     short
ffidl::typedef FT_UFWord    {unsigned short}
ffidl::typedef FT_Char      char
ffidl::typedef FT_Byte      {unsigned char}
ffidl::typedef FT_Bytes     pointer
ffidl::typedef FT_Tag       uint32
ffidl::typedef FT_String    char
ffidl::typedef FT_Short     short
ffidl::typedef FT_UShort    {unsigned short}
ffidl::typedef FT_Int       int
ffidl::typedef FT_UInt      uint32
ffidl::typedef FT_Long      long
ffidl::typedef FT_ULong     {unsigned long}
ffidl::typedef FT_F2Dot14   short
ffidl::typedef FT_F26Dot6   long
ffidl::typedef FT_Fixed     long
ffidl::typedef FT_Error     int
ffidl::typedef FT_Pointer   pointer
ffidl::typedef FT_Offset    size_t
ffidl::typedef FT_PtrDist   pointer


ft::struct define FT_UnitVector {
    {x int - FT_F2Dot14 1 FT_F2Dot14}
    {y int - FT_F2Dot14 1 FT_F2Dot14}
}

ft::struct define FT_Matrix {
    {xx int - FT_Fixed 1 FT_Fixed}
    {xy int - FT_Fixed 1 FT_Fixed}
    {yx int - FT_Fixed 1 FT_Fixed}
    {yy int - FT_Fixed 1 FT_Fixed}
}

ft::struct define FT_Data {
    {pointer int - pointer 1 pointer}
    {length  int - FT_Int  1 FT_Int}
}

ft::struct define FT_Generic {
    {data      int - pointer      1 pointer}
    {finalizer int - pointer-proc 1 pointer}
}

proc FT_MAKE_TAG {x1 x2 x3 x4} {
    if {$x1 eq ""} {set v1 0} else {binary scan $x1 c v1}
    if {$x2 eq ""} {set v2 0} else {binary scan $x2 c v2}
    if {$x3 eq ""} {set v3 0} else {binary scan $x3 c v3}
    if {$x4 eq ""} {set v4 0} else {binary scan $x4 c v4}
    return [expr {($v1 << 24) | ($v2 << 16) | ($v3 << 8) | $v4}]
}

ft::struct define FT_ListNode {
    {prev object * FT_ListNode 1 pointer}
    {next object * FT_ListNode 1 pointer}
    {data int    - pointer     1 pointer}
}

ft::struct define FT_List {
    {head object * FT_ListNode 1 pointer}
    {tail object * FT_ListNode 1 pointer}
}

proc FT_IS_EMPTY {obj} { return [epxr {[$obj get head] == 0}] }
proc FT_BOOL {x} {expr {bool($x)}}

proc FT_ERR_XCAT {x y} {return $x$y}
proc FT_ERR_CAT {x y} {FT_ERR_XCAT $x $y}

proc FT_ERR {e} {FT_ERR_CAT $::FT_ERR_PREFIX $e}
proc FT_ERROR_BASE {x} {expr {[uplevel #0 set $x] & 0xFF}}
proc FT_ERROR_MODULE {x} {expr {[uplevel #0 set $x] & 0xFF00}}

proc FT_ERR_EQ {x e} {
    expr {[FT_ERROR_BASE $x] == [FT_ERROR_BASE [FT_ERR $e]]}}
proc FT_ERR_NEQ {x e} {expr {[FT_ERROR_BASE $x] != [FT_ERROR_BASE [FT_ERR $e]]}}

set _source([file tail [info script]]) 1
}
