(********************************************************************)
(*                                                                  *)
(*  font.s7i      Defines the font interface                        *)
(*  Copyright (C) 2010  Thomas Mertes                               *)
(*                                                                  *)
(*  This file is part of the Seed7 Runtime Library.                 *)
(*                                                                  *)
(*  The Seed7 Runtime Library is free software; you can             *)
(*  redistribute it and/or modify it under the terms of the GNU     *)
(*  Lesser General Public License as published by the Free Software *)
(*  Foundation; either version 2.1 of the License, or (at your      *)
(*  option) any later version.                                      *)
(*                                                                  *)
(*  The Seed7 Runtime Library is distributed in the hope that it    *)
(*  will be useful, but WITHOUT ANY WARRANTY; without even the      *)
(*  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *)
(*  PURPOSE.  See the GNU Lesser General Public License for more    *)
(*  details.                                                        *)
(*                                                                  *)
(*  You should have received a copy of the GNU Lesser General       *)
(*  Public License along with this program; if not, write to the    *)
(*  Free Software Foundation, Inc., 51 Franklin Street,             *)
(*  Fifth Floor, Boston, MA  02110-1301, USA.                       *)
(*                                                                  *)
(********************************************************************)


(**
 *  Interface type for fonts.
 *  The font interface is implemented with ''emptyFont'',
 *  ''fontProperties'', [[bitmapfont|bitmapFont]] and [[vectorfont|vectorFont]].
 *)
const type: font is sub object interface;


(**
 *  Get the height of the letter 'x' for a given font.
 *  The height measured in pixels.
 *  @return the pixel height of 'x' for ''aFont''.
 *)
const func integer: xHeight (in font: aFont)                 is DYNAMIC;


(**
 *  Get the height of capital letters for a given font.
 *  The height measured in pixels.
 *  @return the capital letter height of ''aFont''.
 *)
const func integer: capHeight (in font: aFont)               is DYNAMIC;


(**
 *  Get the height of a font.
 *  This is the height necessary to display a line with all chars
 *  of a font. The line height is measured in pixels.
 *  @return the line height of ''aFont''.
 *)
const func integer: lineHeight (in font: aFont)              is DYNAMIC;


(**
 *  Get the ascent of a font.
 *  The ascent is the distance between xHeight and the height of the
 *  tallest lower-case letter. The ascent is measured in pixels.
 *  @return the ascent pixels of ''aFont''.
 *)
const func integer: ascent (in font: aFont)                  is DYNAMIC;


(**
 *  Get the descent of a font.
 *  The descent is the maximum distance that a letter extends below
 *  the baseline of a font. The descent is measured in pixels.
 *  @return the descent pixels of ''aFont''.
 *)
const func integer: descent (in font: aFont)                 is DYNAMIC;


const func integer: baseLineDelta (in font: aFont)           is DYNAMIC;


(**
 *  Get the maximum column width of a font.
 *  The width of all chars in a font is checked to get the maximum
 *  column width. The maximum column width is measured in pixels.
 *  @return the maximum column width of ''aFont''.
 *)
const func integer: columnWidth (in font: aFont)             is DYNAMIC;


(**
 *  Get the spacing between the chars of a font.
 *  The character spacing is measured in pixels.
 *  @return the spacing between the chars of ''aFont''.
 *)
const func integer: characterSpacing (in font: aFont)        is DYNAMIC;


(**
 *  Get the pixel width of a string displayed with a font.
 *  @return the pixel width of ''stri'' displayed with ''aFont''.
 *)
const func integer: width (in font: aFont, in string: stri)  is DYNAMIC;


(**
 *  If a string is displayed with a font, how many chars fit in a width.
 *  The width is specified in pixels. The expression:
 *   numOfCharsInWidth(aFont, stri, width(aFont, stri))
 *  will always be equivalent to
 *   length(stri);
 *  @return the number of chars from ''stri'' that fit into ''allowedWidth''
 *          if ''stri'' is displayed with ''aFont''.
 *)
const func integer: numOfCharsInWidth (in font: aFont,
    in string: stri, in integer: allowedWidth)               is DYNAMIC;


(**
 *  Compare two font values.
 *  This function does neither compare font contents nor font names.
 *  The order of two fonts is determined by comparing the memory
 *  positions of their internal data representation. Therefore the
 *  result of ''compare'' is arbitrary and may change if the
 *  program is executed again. Inside a program the result of
 *  ''compare'' is consistent and can be used to maintain hash
 *  tables.
 *  @return -1, 0 or 1 if the first argument is considered to be
 *          respectively less than, equal to, or greater than the
 *          second.
 *)
const func integer: compare (in font: font1, in font: font2) is action "ITF_CMP";


(**
 *  Compute the hash value of a font.
 *  @return the hash value.
 *)
const func integer: hashCode (in font: aFont)                is action "ITF_HASHCODE";


(**
 *  Font implementation type to represent an empty font.
 *)
const type: emptyFont is new struct
  end struct;


type_implements_interface(emptyFont, font);

const font: (attr font) . value                              is emptyFont.value;


(**
 *  Font implementation type to manage font properties.
 *)
const type: fontProperties is sub emptyFont struct
    var integer: xHeight          is 0;
    var integer: capHeight        is 0;
    var integer: lineHeight       is 0;
    var integer: ascent           is 0;
    var integer: descent          is 0;
    var integer: baseLineDelta    is 0;
    var integer: columnWidth      is 0;
    var integer: characterSpacing is 0;
  end struct;


type_implements_interface(fontProperties, font);


const func integer: xHeight (in fontProperties: bmpFont) is
  return bmpFont.xHeight;

const func integer: capHeight (in fontProperties: bmpFont) is
  return bmpFont.capHeight;

const func integer: lineHeight (in fontProperties: bmpFont) is
  return bmpFont.lineHeight;

const func integer: ascent (in fontProperties: bmpFont) is
  return bmpFont.ascent;

const func integer: descent (in fontProperties: bmpFont) is
  return bmpFont.descent;

const func integer: baseLineDelta (in fontProperties: bmpFont) is
  return bmpFont.baseLineDelta;

const func integer: columnWidth (in fontProperties: bmpFont) is
  return bmpFont.columnWidth;

const func integer: characterSpacing (in fontProperties: bmpFont) is
  return bmpFont.characterSpacing;