; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Fonts managing library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


iglobal
  if used FontAttr.mono | used FontAttr.size | used FontAttr.weight | used FontAttr.italic
    label FontAttr byte
    .mono db ',Mono', 0
    .size db ':pixelsize=', 0
    .weight db ':weight=', 0
    .italic db ':slant=italic', 0
    .regular db ':slant=roman', 0


;fwLight     = 0
;fwDemilight = 1
;fwNormal    = 2
;fwMedium    = 3
;fwDemibold  = 4
;fwBold      = 5
;fwExtraBold = 6
;fwBlack     = 7

    .font_weights db 0, 55, 80, 100, 180, 200, 205, 210
  end if
endg


;initialize InitFonts
;begin
;        cinvoke FcInit
;        return
;endp
;
;
;finalize FinalizeFonts
;begin
;        cinvoke FcFini
;        return
;endp



proc FTCRequester as FT_Face_Requester
.res dd ?
.idx dd ?
.face dd ?
begin
        pushad

        mov     esi, [.face_id]

        stdcall StrDup, [esi+__TFont.hFontFace]
        mov     ebx, eax

        test    [esi+__TFont.flags], ffMonospaced
        jz      @f
        stdcall StrCat, ebx, FontAttr.mono
@@:
        mov     eax, [esi+__TFont.weight]
        and     eax, 7
        movzx   eax, byte [FontAttr.font_weights+eax]

        stdcall StrCat, ebx, FontAttr.weight
        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        push    eax
        stdcall StrCat, ebx, eax
        stdcall StrDel ; from the stack

        mov     eax, FontAttr.regular
        test    [esi+__TFont.flags], ffItalic
        jz      @f
        mov     eax, FontAttr.italic
@@:
        stdcall StrCat, ebx, eax
        stdcall StrPtr, ebx

;        OutputLn eax

        cinvoke FcNameParse, eax
        stdcall StrDel, ebx

        test    eax, eax
        jnz     @f

        cinvoke FcNameParse, txt "Helvetica"
        DebugMsg "Error: Bad pattern fallback."

@@:
        mov     ebx, eax

        cinvoke FcDefaultSubstitute, ebx
        cinvoke FcConfigSubstitute, 0, ebx, 0

        lea     eax, [.res]
        cinvoke FcFontMatch, 0, ebx, eax
        push    eax

        cinvoke FcPatternDestroy, ebx
        pop     ebx

;        if defined options.DebugMode & options.DebugMode
;          cinvoke FcPatternPrint, ebx
;        end if

        lea     eax, [.res]
        cinvoke FcPatternGetString, ebx, FC_FILE, 0, eax

        OutputLn [.res]

        lea     eax, [.idx]
        cinvoke FcPatternGetInteger, ebx, FC_INDEX, 0, eax

        mov     edi, [.pFace]
        mov     eax, [.res]
        cinvoke FT_New_Face, [FTLibrary], eax, [.idx], edi

.finish:
        mov     [esp+4*regEAX], eax
        cinvoke FcPatternDestroy, ebx
        popad
        cret
endp



FC_FILE text 'file'
FC_INDEX text 'index'
FC_PIXEL_SIZE  text 'pixelsize'



body FontCreate
begin
        push    edx

        stdcall GetMem, sizeof.__TFont
        mov     edx, eax

        stdcall StrDupMem, [.font_name]
        mov     [edx+__TFont.hFontFace], eax

        mov     eax, [.size]
        mov     [edx+__TFont.height], eax
        mov     eax, [.weight]
        mov     [edx+__TFont.weight], eax
        mov     eax, [.flags]
        mov     [edx+__TFont.flags], eax

        mov     eax, edx
        pop     edx
        return
endp



body FontDestroy
begin
        pushad
        mov     edi, [.pFont]

        cinvoke FTC_Manager_RemoveFaceID, [FTCManager], edi
        stdcall StrDel, [edi+__TFont.hFontFace]
        stdcall FreeMem, edi

        popad
        return
endp


; returns some font metrics
;
; Arguments:
;    .font - the font
; Returns:
;    EAX - the line height of the font.
;    EBX - the ascender of the font.
;    EDX - the descender of the font.

body GetFontMetrics
.scaler  FTC_ScalerRec
.size    dd ?
begin
        push    ecx

        mov     edx, [.font]
        xor     ecx, ecx

        mov     [.scaler.face_id], edx
        mov     [.scaler.width], ecx

        mov     eax, [edx+__TFont.height]
        inc     ecx

        mov     [.scaler.height], eax
        mov     [.scaler.pixel], ecx    ; ecx = 1

        lea     eax, [.scaler]
        lea     edx, [.size]
        cinvoke FTC_Manager_LookupSize, [FTCManager], eax, edx
        test    eax, eax
        jnz     .error

        mov     edx, [.size]

        mov     eax, [edx+FT_SizeRec.metrics.height]
        mov     ebx, [edx+FT_SizeRec.metrics.ascender]
        mov     edx, [edx+FT_SizeRec.metrics.descender]

        sar     eax, 6
        sar     ebx, 6
        sar     edx, 6

        clc
        pop     ecx
        return

.error:
        stc
        pop     ecx
        return
endp
