%D \module
%D   [       file=font-fil,
%D        version=2011.01.13, % (copied fron font-ini)
%D          title=\CONTEXT\ Font Macros,
%D       subtitle=Classes and Files,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{ConTeXt Font Macros / Classes and Files}

\unprotect

%D Personally I think that using \TEX\ macro packages is
%D complicated by the way fonts are handled. Apart from the
%D many encodings, we also deal with different naming schemes.
%D Confronted with this problem, I decided to change the
%D definitions into:
%D
%D \starttyping
%D \definebodyfont [12pt] [rm] [tf=Times-Roman at 12pt]
%D \stoptyping
%D
%D combined with for instance:
%D
%D \starttyping
%D \definefontsynonym [Times-Roman] [tir]
%D \stoptyping

% \definetypeface[palatino][rm][serif][palatino,allbold][default]
%
% \startfontclass[palatino]
%   \definefontsynonym [Serif]        [SerifBold]
%   \definefontsynonym [SerifItalic]  [SerifBoldItalic]
%   \definefontsynonym [SerifSlanted] [SerifBoldSlanted]
%   \definefontsynonym [SerifCaps]    [SerifBold]
% \stopfontclass
%
% \setupbodyfont[palatino]

\let\fontclass\empty

\unexpanded\def\startfontclass
  {\dosingleempty\font_basics_start_font_class}

\def\font_basics_start_font_class[#class]%
  {\pushmacro\fontclass
   \doifelse{#class}\v!each
     {\let\fontclass\empty}
     {\doifsomething{#class}{\def\fontclass{#class}}}}

\unexpanded\def\stopfontclass
  {\popmacro\fontclass}

\def\classfont#class#name{#class#name} % \definefont[whatever][\classfont{xx}{yy} at 10pt]

%D \macros
%D   {definefontsynonym, doifelsefontsynonym,
%D    expandfontsynonym, truefontname, truefontdata}
%D
%D While looking for fonts, fontsynonyms are used for accessing
%D the files!
%D
%D \starttyping
%D \definefontsynonym[Serif][Lucida-Bright]
%D \definefontsynonym[Lucida-Bright][lbr][encoding=texnansi]
%D \stoptyping

\installcorenamespace {fontfile} % file synonyms

\let\m_font_name\empty
\let\m_font_file\empty

\def \defaultfontfile{\truefontname{Normal}} % was cmtt10, but that one is gone
\edef\nullfontname   {\fontname\nullfont}

\unexpanded\def\definefontsynonym[#name]#crap[#file]%
  {\edef\m_font_name{#name}%
   \edef\m_font_file{#file}%
   \ifx\fontclass\empty
      \expandafter\font_basics_define_font_synonym_nop
   \else
      \expandafter\font_basics_define_font_synonym_yes
   \fi}

\def\font_basics_define_font_synonym_nop
  {\expandafter\let\csname\??fontfile\m_font_name\endcsname\m_font_file
   \doifelsenextoptionalcs\font_basics_define_font_synonym_nop_opt\font_basics_define_font_synonym_nop_nil}

\def\font_basics_define_font_synonym_yes
  {\expandafter\let\csname\??fontfile\fontclass\m_font_name\endcsname\m_font_file
   \doifelsenextoptionalcs\font_basics_define_font_synonym_yes_opt\font_basics_define_font_synonym_yes_nil}

\def\font_basics_define_font_synonym_nop_opt[#specification]%
  {\let\p_features  \undefined
   \let\p_fallbacks \undefined
   \let\p_goodies   \undefined
   \let\p_designsize\undefined
   \expandafter\font_basics_get_font_parameter_nop#specification,]=,}

\def\font_basics_define_font_synonym_yes_opt[#specification]%
  {\let\p_features  \undefined
   \let\p_fallbacks \undefined
   \let\p_goodies   \undefined
   \let\p_designsize\undefined
   \expandafter\font_basics_get_font_parameter_yes#specification,]=,}

\def\font_basics_get_font_parameter_nop#key=#value,%
  {\if]#key%
     \font_basics_get_font_parameter_nop_finish
   \else
     \expandafter\normaldef\csname p_#key\endcsname{#value}%
     \expandafter\font_basics_get_font_parameter_nop
   \fi}

\def\font_basics_get_font_parameter_yes#key=#value,%
  {\if]#key%
     \font_basics_get_font_parameter_yes_finish
   \else
     \expandafter\normaldef\csname p_#key\endcsname{#value}%
     \expandafter\font_basics_get_font_parameter_yes
   \fi}

% helpers, some day these will be toks and counts

% \def\fntsetdefname {\global\let\somefontname\defaultfontfile}
% \def\fntsetsomename{\gdef\somefontname} % takes argument
% \def\fntsetnopsize {\let\somefontsize\empty}
% \def\fntsetsomesize{\def\somefontsize}  % takes argument

% happens later, else mkvi parsing gets into troubles

% end of helpers

% we could collect them in one macro (but no expansion)

\def\font_basics_define_font_synonym_nop_nil
  {\expandafter\let\csname\??fontfile\m_font_name\s!features  \endcsname\undefined
   \expandafter\let\csname\??fontfile\m_font_name\s!fallbacks \endcsname\undefined
   \expandafter\let\csname\??fontfile\m_font_name\s!goodies   \endcsname\undefined
   \expandafter\let\csname\??fontfile\m_font_name\s!designsize\endcsname\undefined}

\def\font_basics_define_font_synonym_yes_nil
  {\global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!features  \endcsname\undefined
   \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!fallbacks \endcsname\undefined
   \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!goodies   \endcsname\undefined
   \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!designsize\endcsname\undefined}

\def\font_basics_get_font_parameter_nop_finish
  {\expandafter\let\csname\??fontfile\m_font_name\s!features  \endcsname\p_features
   \expandafter\let\csname\??fontfile\m_font_name\s!fallbacks \endcsname\p_fallbacks
   \expandafter\let\csname\??fontfile\m_font_name\s!goodies   \endcsname\p_goodies
   \expandafter\let\csname\??fontfile\m_font_name\s!designsize\endcsname\p_designsize}

\def\font_basics_get_font_parameter_yes_finish
  {\global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!features  \endcsname\p_features
   \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!fallbacks \endcsname\p_fallbacks
   \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!goodies   \endcsname\p_goodies
   \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!designsize\endcsname\p_designsize}

%\definefontsynonym [KopFont] [\fontclassname{officina}{SerifBold}]
%
%\defineclassfontsynonym [KopFont] [officina] [SerifBold]

\unexpanded\def\defineclassfontsynonym
  {\dotripleargument\font_basics_define_class_font_synonym}

%\definefontsynonym[#tag][\fontclassname{#class}{#fileortag}]}

\def\font_basics_define_class_font_synonym[#tag][#class][#fileortag]% needs testing
  {\expandafter\normaldef\csname\??fontfile\fontclass#tag\endcsname{\fontclassname{#class}{#fileortag}}%
   \font_basics_define_font_synonym_yes_nil}

\let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater

\unexpanded\def\setupfontsynonym
  {\dodoubleempty\dosetupfontsynonym}

\def\dosetupfontsynonym[#name][#settings]% not yet supported, will do when needed
  {}

% todo: replace * by ... less messy with features

\def\truefontname#name%
  {\expandafter\font_helpers_true_fontname#name*\empty*\relax}

\def\font_helpers_true_fontname#name*#first#rest*#crap\relax
  {\ifcsname\??fontfile\fontclass#name\endcsname
     \ifx#first\empty
       \expandafter\truefontname\csname\??fontfile\fontclass#name\endcsname
     \else
       \expandafter\font_helpers_true_fontname_check\csname\??fontfile\fontclass#name\endcsname*#first#rest%
     \fi
   \else\ifcsname\??fontfile\defaultfontclass#name\endcsname
     \ifx#first\empty
       \expandafter\truefontname\csname\??fontfile\defaultfontclass#name\endcsname
     \else
       \expandafter\font_helpers_true_fontname_check\csname\??fontfile\defaultfontclass#name\endcsname*#first#rest%
     \fi
   \else\ifcsname\??fontfile#name\endcsname
     \ifx#first\empty
       \expandafter\truefontname\csname\??fontfile#name\endcsname
     \else
       \expandafter\font_helpers_true_fontname_check\csname\??fontfile#name\endcsname*#first#rest%
     \fi
   \else
     #name\ifx#first\empty\else*#first#rest\fi
   \fi\fi\fi}

\def\font_helpers_true_fontname_check#name%
  {\expandafter\font_helpers_true_fontname_check_indeed#name*\relax}

\def\font_helpers_true_fontname_check_indeed#name*#crap\relax
  {\ifcsname\??fontfile\fontclass#name\endcsname
     \expandafter\font_helpers_true_fontname_check\csname\??fontfile\fontclass#name\endcsname
   \else\ifcsname\??fontfile\defaultfontclass#name\endcsname
     \expandafter\font_helpers_true_fontname_check\csname\??fontfile\defaultfontclass#name\endcsname
   \else\ifcsname\??fontfile#name\endcsname
     \expandafter\font_helpers_true_fontname_check\csname\??fontfile#name\endcsname
   \else
     #name%
   \fi\fi\fi}

\def\expandfontsynonym#command#name% one level expansion
  {\ifcsname\??fontfile\fontclass#name\endcsname
     \expandafter\normaldef\expandafter#command\expandafter{\csname\??fontfile\fontclass#name\endcsname}%
   \else\ifcsname\??fontfile\defaultfontclass#2\endcsname
     \expandafter\normaldef\expandafter#command\expandafter{\csname\??fontfile\defaultfontclass#name\endcsname}%
   \fi\fi}

\def\doifelsefontsynonym#name%
  {\ifcsname\??fontfile\fontclass#name\endcsname
     \singleexpandafter\firstoftwoarguments
   \else\ifcsname\??fontfile\defaultfontclass#name\endcsname
     \doubleexpandafter\firstoftwoarguments
   \else
     \doubleexpandafter\secondoftwoarguments
   \fi\fi}

\let\doiffontsynonymelse\doifelsefontsynonym

%D \macros
%D   {tracedfontname}
%D
%D A goody:

\def\tracedfontname#name%
  {#name\ifcsname\??fontfile\fontclass#name\endcsname
     \expandafter\tracedfontname\csname\??fontfile\fontclass#name\endcsname
   \else\ifcsname\??fontfile#name\endcsname
     \expandafter\tracedfontname\csname\??fontfile#name\endcsname
   \fi\fi}

%D \macros
%D   {fontclass, defaultfontclass}
%D
%D The fontclass model was introduced a while after we implement
%D the basic font model and at that time we still defaulted to
%D no model at all. Nowadays we default to the \type {modern}
%D fontclass.

\let\fontclass       \empty
\let\defaultfontclass\empty

\def\fontclassname#class#name%
  {\ifcsname\??fontfile#class#name\endcsname
     \fontclassname{#class}{\csname\??fontfile#class#name\endcsname}%
   \else\ifcsname\??fontfile#name\endcsname
     \fontclassname{#class}{\csname\??fontfile#name\endcsname}%
   \else
     #2%
   \fi\fi}

%D Files or names can have properties and these need to be consulted
%D at some point. They can inherit them.

% Why these expanded and rscale not ... maybe not worth the trouble (delayed
% expansion actually would be better i.e. macros in feature specs). Test
% without pre-expansion.

\def\font_helpers_update_font_class_parameters
  {\edef\m_font_class_direction {\ifcsname\??fontclass\fontclass\fontstyle\s!direction \endcsname\csname\??fontclass\fontclass\fontstyle\s!direction \endcsname\fi}%
   \edef\m_font_class_features  {\ifcsname\??fontclass\fontclass\fontstyle\s!features  \endcsname\csname\??fontclass\fontclass\fontstyle\s!features  \endcsname\fi}%
   \edef\m_font_class_fallbacks {\ifcsname\??fontclass\fontclass\fontstyle\s!fallbacks \endcsname\csname\??fontclass\fontclass\fontstyle\s!fallbacks \endcsname\fi}%
   \edef\m_font_class_goodies   {\ifcsname\??fontclass\fontclass\fontstyle\s!goodies   \endcsname\csname\??fontclass\fontclass\fontstyle\s!goodies   \endcsname\fi}%
   \edef\m_font_class_designsize{\ifcsname\??fontclass\fontclass\fontstyle\s!designsize\endcsname\csname\??fontclass\fontclass\fontstyle\s!designsize\endcsname\fi}}

% resolve

\def\font_helpers_set_features_yes#name%
  {\ifcsname\??fontfile\fontclass#name\s!features \endcsname \edef\m_font_features  % class + symbolic_name
    {\csname\??fontfile\fontclass#name\s!features \endcsname}\else
   \ifcsname\??fontfile          #name\s!features \endcsname \edef\m_font_features  % symbolic_name
    {\csname\??fontfile          #name\s!features \endcsname}\else
   \ifcsname\??fontfile\fontclass            #name\endcsname\expandafter\font_helpers_set_features_yes    % class + parent_name
     \csname\??fontfile\fontclass            #name\endcsname \else
   \ifcsname\??fontfile                      #name\endcsname \expandafter\font_helpers_set_features_yes    % parent_name
     \csname\??fontfile                      #name\endcsname \else
   \let\m_font_features\empty\fi\fi\fi\fi}

\def\font_helpers_set_fallbacks_yes#name%
  {\ifcsname\??fontfile\fontclass#name\s!fallbacks\endcsname \edef\m_font_fallbacks
    {\csname\??fontfile\fontclass#name\s!fallbacks\endcsname}\else
   \ifcsname\??fontfile          #name\s!fallbacks\endcsname \edef\m_font_fallbacks
    {\csname\??fontfile          #name\s!fallbacks\endcsname}\else
   \ifcsname\??fontfile\fontclass            #name\endcsname \expandafter\font_helpers_set_fallbacks_yes
     \csname\??fontfile\fontclass            #name\endcsname \else
   \ifcsname\??fontfile                      #name\endcsname \expandafter\font_helpers_set_fallbacks_yes
     \csname\??fontfile                      #name\endcsname \else
   \let\m_font_fallbacks\empty\fi\fi\fi\fi}

\def\font_helpers_set_goodies_yes#name%
  {\ifcsname\??fontfile\fontclass#name\s!goodies  \endcsname \edef\m_font_goodies
    {\csname\??fontfile\fontclass#name\s!goodies  \endcsname}\else
   \ifcsname\??fontfile          #name\s!goodies  \endcsname \edef\m_font_goodies
    {\csname\??fontfile          #name\s!goodies  \endcsname}\else
   \ifcsname\??fontfile\fontclass            #name\endcsname \expandafter\font_helpers_set_goodies_yes
     \csname\??fontfile\fontclass            #name\endcsname \else
   \ifcsname\??fontfile                      #name\endcsname \expandafter\font_helpers_set_goodies_yes
     \csname\??fontfile                      #name\endcsname \else
   \let\m_font_goodies\empty\fi\fi\fi\fi}

\def\font_helpers_set_designsize_yes#name%
  {\ifcsname\??fontfile\fontclass#name\s!designsize\endcsname \edef\m_font_designsize
    {\csname\??fontfile\fontclass#name\s!designsize\endcsname}\else
   \ifcsname\??fontfile          #name\s!designsize\endcsname \edef\m_font_designsize
    {\csname\??fontfile          #name\s!designsize\endcsname}\else
   \ifcsname\??fontfile\fontclass             #name\endcsname \expandafter\font_helpers_set_designsize_yes
     \csname\??fontfile\fontclass             #name\endcsname \else
   \ifcsname\??fontfile                       #name\endcsname \expandafter\font_helpers_set_designsize_yes
     \csname\??fontfile                       #name\endcsname \else
   \let\m_font_designsize\empty\fi\fi\fi\fi}

\def\font_helpers_set_features_nop#name%
  {\ifcsname\??fontfile#name\s!features \endcsname \edef\m_font_features
    {\csname\??fontfile#name\s!features \endcsname}\else
   \ifcsname\??fontfile            #name\endcsname \expandafter\font_helpers_set_features_nop
     \csname\??fontfile            #name\endcsname \else
   \let\m_font_features\empty\fi\fi}

\def\font_helpers_set_fallbacks_nop#name%
  {\ifcsname\??fontfile#name\s!fallbacks\endcsname \edef\m_font_fallbacks
    {\csname\??fontfile#name\s!fallbacks\endcsname}\else
   \ifcsname\??fontfile            #name\endcsname \expandafter\font_helpers_set_fallbacks_nop
     \csname\??fontfile            #name\endcsname \else
   \let\m_font_fallbacks\empty\fi\fi}

\def\font_helpers_set_goodies_nop#name%
  {\ifcsname\??fontfile#name\s!goodies  \endcsname \edef\m_font_goodies
    {\csname\??fontfile#name\s!goodies  \endcsname}\else
   \ifcsname\??fontfile            #name\endcsname \expandafter\font_helpers_set_goodies_nop
     \csname\??fontfile            #name\endcsname \else
   \let\m_font_goodies\empty\fi\fi}

\def\font_helpers_set_designsize_nop#name%
  {\ifcsname\??fontfile#name\s!designsize\endcsname \edef\m_font_designsize
    {\csname\??fontfile#name\s!designsize\endcsname}\else
   \ifcsname\??fontfile             #name\endcsname \expandafter\font_helpers_set_designsize_nop
     \csname\??fontfile             #name\endcsname \else
   \let\m_font_designsize\empty\fi\fi}

\def\font_helpers_update_font_parameters_yes
  {\font_helpers_set_features_yes  \somefontname
   \font_helpers_set_fallbacks_yes \somefontname
   \font_helpers_set_goodies_yes   \somefontname
   \font_helpers_set_designsize_yes\somefontname}

\def\font_helpers_update_font_parameters_nop
  {\font_helpers_set_features_nop  \somefontname
   \font_helpers_set_fallbacks_nop \somefontname
   \font_helpers_set_goodies_nop   \somefontname
   \font_helpers_set_designsize_nop\somefontname}

\def\font_helpers_update_font_parameters
 {\ifx\fontclass\empty\font_helpers_update_font_parameters_nop\else\font_helpers_update_font_parameters_yes\fi}

\installcorenamespace{fontclass}

% we can pack them

\unexpanded\def\savefontclassparameters#style#rscale#features#fallbacks#goodies#designsize#direction%
  {\setxvalue{\??fontclass\fontclass#style\s!rscale    }{#rscale}%
   \setxvalue{\??fontclass\fontclass#style\s!features  }{#features}%
   \setxvalue{\??fontclass\fontclass#style\s!fallbacks }{#fallbacks}%
   \setxvalue{\??fontclass\fontclass#style\s!goodies   }{#goodies}%
   \setxvalue{\??fontclass\fontclass#style\s!designsize}{#designsize}%
   \setxvalue{\??fontclass\fontclass#style\s!direction }{#direction}}

\protect \endinput
