; ***************************************************************************
; copyright   : (C) 2025 by Martin Preuss
; email       : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome".                              *
; * Please see toplevel file COPYING of that project for license details.   *
; ***************************************************************************

#ifndef AQH_AVR_FONT_MAIN_ASM
#define AQH_AVR_FONT_MAIN_ASM



; ***************************************************************************
; code

.cseg



; ---------------------------------------------------------------------------
; @routine FONT_RenderChar

; @param R16    character to write
; @param R1:R0  background color
; @param R3:R2  foreground color
; @param Z      pointer to font
; @param X      pointer to RAM to store data to
; @return r18   char width in pixel
; @return r19   char height in pixel
; @clobbers any, !Z

FONT_RenderChar:
  ldi r23, FONT_FN_RENDER
  rjmp fontCallHandler
; @end




; ---------------------------------------------------------------------------
; @routine FONT_GetCharWidth

; @param  Z      pointer to font
; @param  R16    character for which to determine size
; @return R16    character width for given character set
; @clobbers any, !Z

FONT_GetCharWidth:
  ldi r23, FONT_FN_GETCHARWIDTH
  rjmp fontCallHandler
; @end



; ---------------------------------------------------------------------------
; @routine FONT_GetCharHeight

; @param  Z      pointer to font
; @return R16    character height for given character set
; @clobbers any, !Z

FONT_GetCharHeight:
  ldi r23, FONT_FN_GETCHARHEIGHT
  rjmp fontCallHandler
; @end



; ---------------------------------------------------------------------------
; @routine FONT_GetStringWidthFlash

; @param  Z       pointer to font
; @param  X       pointer to null-terminated string in flash
; @return R17:R16 character width for given character set (in pixel)
; @clobbers any, !Z

FONT_GetStringWidthFlash:
  ldi r23, FONT_FN_GETSTRINGWIDTH
  rjmp fontCallHandler
; @end



; ---------------------------------------------------------------------------
; @routine FONT_GetStringHeightFlash

; @param  Z      pointer to font
; @param  X      pointer to null-terminated string in flash
; @return R16    character width for given character set
; @clobbers any, !Z

FONT_GetStringHeightFlash:
  ldi r23, FONT_FN_GETSTRINGHEIGHT
  rjmp fontCallHandler
; @end





; ---------------------------------------------------------------------------
; @routine fontCallHandler
;
; @param r23 function number
; @param Z   pointer to font

fontCallHandler:
  lpm r17, Z+
  push r17
  lpm r17, Z
  push r17
  sbiw zh:zl, 1
  ret
; @end




; ---------------------------------------------------------------------------
; @routine FONT_GenericHandler
;
; Generic handler for font functions.
; @param R23 function to call (see @ref FONT_FN_RENDER et al)

FONT_GenericHandler:
  cpi r23, FONT_FN_GETCHARWIDTH
  breq fontGenericFnGetCharWidth
  cpi r23, FONT_FN_GETCHARHEIGHT
  breq fontGenericFnGetCharHeight
  cpi r23, FONT_FN_GETSTRINGWIDTH
  breq fontGenericFnGetStringWidth
  cpi r23, FONT_FN_GETSTRINGHEIGHT
  breq fontGenericFnGetStringHeight
  ret

fontGenericFnGetCharWidth:
  adiw zh:zl, FONT_OFFS_WIDTH
  lpm r16, Z
  sbiw zh:zl, FONT_OFFS_WIDTH
  ret

fontGenericFnGetCharHeight:
  adiw zh:zl, FONT_OFFS_HEIGHT
  lpm r16, Z
  sbiw zh:zl, FONT_OFFS_HEIGHT
  ret

fontGenericFnGetStringWidth:
  clr r16                         ; sum (LOW)
  clr r17                         ; sum (HIGH)
  adiw zh:zl, FONT_OFFS_WIDTH
  lpm r19, Z
  sbiw zh:zl, FONT_OFFS_WIDTH
  push zl
    push zh
      mov zl, xl
      mov zh, xh
fontGenericFnGetStringWidth_loop:
        lpm r18, Z+               ; current byte in string
        tst r18
        breq fontGenericFnGetStringWidth_loopEnd
        add r16, r19              ; add char width to sum
        adc r17, r19
        sub r17, r19
      rjmp fontGenericFnGetStringWidth_loop
fontGenericFnGetStringWidth_loopEnd:
    pop zh
  pop zl
  ret

fontGenericFnGetStringHeight:
  rjmp fontGenericFnGetCharHeight ; for now monospace fonts only
; @end



#endif ; AQH_AVR_FONT_MAIN_ASM

