#lang racket/base
(require racket/class
	 racket/draw
         ffi/unsafe
         racket/draw/private/local
         racket/draw/unsafe/pango
         "types.rkt"
         "utils.rkt")

(provide 
 (protect-out font->hfont
              logfont->pango-family
              (struct-out LOGFONTW) _LOGFONTW _LOGFONTW-pointer))


(define display-font-map
  (pango_win32_font_map_for_display))

(define display-context
  (pango_font_map_create_context display-font-map))

(define font-cache (pango_win32_font_cache_new))

(define (scale-font f)
  (if (= 1 (->screen 1))
      f
      (make-font #:size (->screen (send f get-point-size))
		 #:face (send f get-face)
		 #:family (send f get-family)
		 #:style (send f get-style)
		 #:weight (send f get-weight)
		 #:underlined? (send f get-underlined)
		 #:smoothing (send f get-smoothing)
		 #:size-in-pixels? (send f get-size-in-pixels)
		 #:hinting (send f get-hinting))))

(define (font->hfont f)
  (let* ([pfont (or (pango_font_map_load_font display-font-map
					      display-context
					      (send (scale-font f) get-pango))
		    ;; font load failed, so fall back to default
		    ;; font with the same size and style:
		    (pango_font_map_load_font display-font-map
					      display-context
					      (send (make-font 
						     #:size (send f get-point-size)
						     #:style (send f get-style)
						     #:weight (send f get-weight)
						     #:size-in-pixels? (send f get-size-in-pixels))
						    get-pango)))]
         [logfont (and pfont
		       (pango_win32_font_logfont pfont))])
    (and logfont
	 (begin0
	  (pango_win32_font_cache_load font-cache logfont)
	  (g_free logfont)))))

;; ----------------------------------------

(define-cstruct _LOGFONTW
  ([lfHeight  _LONG]
   [lfWidth  _LONG]
   [lfEscapement  _LONG]
   [lfOrientation  _LONG]
   [lfWeight  _LONG]
   [lfItalic  _BYTE]
   [lfUnderline  _BYTE]
   [lfStrikeOut  _BYTE]
   [lfCharSet  _BYTE]
   [lfOutPrecision  _BYTE]
   [lfClipPrecision  _BYTE]
   [lfQuality  _BYTE]
   [lfPitchAndFamily  _BYTE]
   [lfFaceName (_array _uint16 32)]))

(define (logfont->pango-family logfontw)
  ;; We'll allocate `logfont' as LOGFONTW but use it as LOGFONTA:
  (define logfont (cast (malloc _LOGFONTW) _pointer (_gcable _LOGFONTW-pointer)))
  (memcpy logfont logfontw (ctype-sizeof _LOGFONTW))
  (WideCharToMultiByte 0 0 
                       (array-ptr (LOGFONTW-lfFaceName logfontw)) -1
                       (array-ptr (LOGFONTW-lfFaceName logfont)) 32
                       #f #f)
  (define desc
    (pango_win32_font_description_from_logfont logfont))
  (if desc
      (pango_font_description_get_family desc)
      ;; random fallback:
      "Arial"))
