#!/bin/sh
#
# TTFM's module for XFree86 X-TrueType server, both 3.3.x or 4.x.
#
# This script is distributed under the revised BSD license.
#
# For any problem reports or suggestions, please contact
# Jing-Tang Keith Jang <keith@FreeBSD.org>.
#

#
# Here's how X-TT and X-freetype are used in respective ttfm modules:
#
# X-TT: Add ${face}-0 and iso10646-1 in XLFD if supported by font.
#       ai(automatic italic) to set italic, ds(double strike) to set bold.
# X-freetype: Add ${face}-0 and iso10646-1 in XLFD if supported by font.
#             X-freetype can't generate italic/oblique/bold automatically.
#
# The iso10646-1 counterpart will also be generated automatically.
#

# Name & version
export NAME; NAME="X-TT Font Manager"
export VERSION; VERSION=0.9.3

# Global constants

export PREFIX; PREFIX=/usr/local
export X11BASE; X11BASE=/usr/X11R6
export PATH; PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PREFIX/bin:$PREFIX/sbin:$X11BASE/bin
export TEMPFILE; TEMPFILE="`mktemp /tmp/ttfm.tmp.XXXXXXXXXX`"
export DefaultFontPath; DefaultFontPath=$PREFIX/share/fonts/TrueType
export XTTFFONTPATH; XTTFFONTPATH="${X11BASE}/lib/X11/fonts/TrueType"
export TTFINFOPATH; TTFINFOPATH="${PREFIX}/bin/ttfinfo"
export AlIASPATTERN; ALIASPATTERN="\"added by ttfm - \$targetname - \$fontencoding\""
export DEFAULTMING_NAME; DEFAULTMING_NAME="default_ming"
export DEFAULTKAI_NAME; DEFAULTKAI_NAME="default_kai"

# Who am I?
print_name()
{
    echo "$NAME $VERSION"
}


# Usage
Usage()
{
    echo
    echo "$NAME $VERSION"
    echo
    echo "Usage: $NAME [option]"
    echo
    echo "       --add <file>...    install ttf font"
    echo "       --remove <file>... remove ttf font from the system"
    echo "       --list             list all ttf fonts on the system"
    echo "       --setdefault <file> "
    echo "                          set default font to file"
    echo "       --setdefault_kai <file> "
    echo "                          set default \kai font to file"
    echo "       --setdefault_ming <file> "
    echo "                          set default \ming font to file"
    echo "       --help             show this info"
    echo
}


# List all ttf fonts installed in $XTTFFONTPATH
list_fonts()
{
    if [ -f $XTTFFONTPATH/fonts.dir ]; then
        echo "Installed TTF fonts:"
        echo
        # Don't print italic and bold font descriptions
        sed -e "1d" -e "/ai=/d" -e "/ds=/d" -e "s/.*://g" ${XTTFFONTPATH}/fonts.dir
        echo
    else
        echo "No TTF fonts installed."
    fi
}


# Remove ttf fonts
remove_fonts()
{
    for f in "$@"; do
        targetname=`basename $f`

        # Update fonts.scale
        rm -f $TEMPFILE
        if [ ! -r $XTTFFONTPATH/fonts.scale ]; then
            touch $XTTFFONTPATH/fonts.scale
        fi
        sed -e "/$targetname/d" $XTTFFONTPATH/fonts.scale > $TEMPFILE
        i=`cat $TEMPFILE |wc -l`
        sed -e "1s/[0-9]*/`expr $i - 1`/" $TEMPFILE > $XTTFFONTPATH/fonts.scale

        # Update fonts.dir, encodings.dir is needed for the sake of xfs.
        if [ -r $XTTFFONTPATH/../encodings/large/encodings.dir ]; then
            mkfontdir -e $XTTFFONTPATH/../encodings/large $XTTFFONTPATH
        else
            mkfontdir $XTTFFONTPATH
        fi

        # Update fonts.alias
        rm -f $TEMPFILE
        ALIASPATTERN=`eval echo $ALIASPATTERN`
        sed -e "/$ALIASPATTERN/d" $XTTFFONTPATH/fonts.alias > $TEMPFILE
        mv -f $TEMPFILE $XTTFFONTPATH/fonts.alias

    done
}


# This is where we do the XLFD dirty work.
install_xfont()
{
    # Set all the attributes
    targetname=$1
    facenum=$2
    faceindex=$3
    fontfoundry=$4
    fontfamily=$5
    fontweight=$6
    fontslant=$7
    fontwidth=$8
    fontproperties=$9
    fontencoding=${10}

    # Create and update fonts.scale
    touch $XTTFFONTPATH/fonts.scale
    # Delete the first line, and duplicate entries if exist.
    # We can't use uniq(1) here, since filenames may start with numbers.
    sed -e "1d" $XTTFFONTPATH/fonts.scale |grep -iv "$fontfoundry-$fontfamily.*-$fontencoding$" > $TEMPFILE

    # Set font parameters
    # Speed up font rendering
    fontparam="vl=y:"
    # Specify the font face index
    if [ $facenum -gt 1 ]; then
        fontparam="fn=$faceindex:$fontparam"
    fi
    echo "${fontparam}$targetname -$fontfoundry-$fontfamily-$fontweight-$fontslant-$fontwidth--0-0-0-0-$fontproperties-0-$fontencoding" >> $TEMPFILE
    # If it's medium-r, make a {medium,bold}-{i,r} full suite
    if [ "X$fontweight" = "Xmedium" ] && [ "X$fontslant" = "Xr" ]; then
        echo "${fontparam}ai=0.3:$targetname -$fontfoundry-$fontfamily-medium-i-$fontwidth--0-0-0-0-$fontproperties-0-$fontencoding" >> $TEMPFILE
        echo "${fontparam}ds=y:$targetname -$fontfoundry-$fontfamily-bold-r-$fontwidth--0-0-0-0-$fontproperties-0-$fontencoding" >> $TEMPFILE
        echo "${fontparam}ds=y:ai=0.3:$targetname -$fontfoundry-$fontfamily-bold-i-$fontwidth--0-0-0-0-$fontproperties-0-$fontencoding" >> $TEMPFILE
    fi
    echo `cat $TEMPFILE |wc -l` > $XTTFFONTPATH/fonts.scale
    cat $TEMPFILE >> $XTTFFONTPATH/fonts.scale

    # Update fonts.dir, encodings.dir is needed for the sake of xfs.
    if [ -r $XTTFFONTPATH/../encodings/large/encodings.dir ]; then
        mkfontdir -e $XTTFFONTPATH/../encodings/large $XTTFFONTPATH
    else
        mkfontdir $XTTFFONTPATH
    fi

    # Update fonts.alias
    ALIASPATTERN=`eval echo $ALIASPATTERN`
    touch $XTTFFONTPATH/fonts.alias
    cp -f $XTTFFONTPATH/fonts.alias $TEMPFILE
    # These numbers are from original Xtt ttfm-module and MS's font manager.
    for pixel in 8 9 10 11 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 \
                     44 46 48 52 56 60 64 68 72; do
        pixel0=`expr $pixel \* 10`
        # Use " to wrap blank chars within fontnames
        echo "\"-alias$fontfoundry-$fontfamily-$fontweight-$fontslant-$fontwidth--$pixel-${pixel0}-0-0-$fontproperties-${pixel0}-$fontencoding\" \"-$fontfoundry-$fontfamily-$fontweight-$fontslant-$fontwidth--$pixel-${pixel0}-0-0-$fontproperties-${pixel0}-$fontencoding\" ! $ALIASPATTERN" >> $TEMPFILE
        # If it's medium-r, make a {medium,bold}-{i,r} full suite
        echo "\"-alias$fontfoundry-$fontfamily-medium-i-$fontwidth--$pixel-${pixel0}-0-0-$fontproperties-${pixel0}-$fontencoding\" \"-$fontfoundry-$fontfamily-medium-i-$fontwidth--$pixel-${pixel0}-0-0-$fontproperties-${pixel0}-$fontencoding\" ! $ALIASPATTERN" >> $TEMPFILE
        echo "\"-alias$fontfoundry-$fontfamily-bold-r-$fontwidth--$pixel-${pixel0}-0-0-$fontproperties-${pixel0}-$fontencoding\" \"-$fontfoundry-$fontfamily-bold-r-$fontwidth--$pixel-${pixel0}-0-0-$fontproperties-${pixel0}-$fontencoding\" ! $ALIASPATTERN" >> $TEMPFILE
        echo "\"-alias$fontfoundry-$fontfamily-bold-i-$fontwidth--$pixel-${pixel0}-0-0-$fontproperties-${pixel0}-$fontencoding\" \"-$fontfoundry-$fontfamily-bold-i-$fontwidth--$pixel-${pixel0}-0-0-$fontproperties-${pixel0}-$fontencoding\" ! $ALIASPATTERN" >> $TEMPFILE
    done

    sort $TEMPFILE |uniq > $XTTFFONTPATH/fonts.alias
    # Reset $ALIASPATTERN
    export AlIASPATTERN; ALIASPATTERN="\"added by ttfm - \$targetname - \$fontencoding\""

    # Deal with xfs
    #xset fp rehash
    #xfs restart
}


#
# Add ttf fonts
#
# It's assumed that FreeBSD ports/packages install fonts in $DefaultFontPath,
# and we'll make a symbolic in $XTTFFONTPATH.
#
add_fonts()
{
    for addfile in $@; do
        targetname=`basename "$addfile"`
        srcdir=`dirname "$addfile"`
        # --add *.ttf
        if [ $srcdir = '.' ]; then
            srcdir=`pwd`
        fi

        # Some sanity checking
        if [ ! -d $DefaultFontPath ]; then mkdir -p $DefaultFontPath; fi
        if [ ! -d $XTTFFONTPATH ]; then mkdir -p $XTTFFONTPATH; fi
        if [ ! -r "$srcdir/$targetname" ]; then continue; fi
        if [ ! -r "$DefaultFontPath/$targetname" ]; then
            ln -s "$srcdir/$targetname" $DefaultFontPath
        fi
        if [ ! -r "$XTTFFONTPATH/$targetname" ]; then
            ln -s "$DefaultFontPath/$targetname" $XTTFFONTPATH
        fi
        touch $XTTFFONTPATH/fonts.dir
        if [ -n "`grep ^$targetname $XTTFFONTPATH/fonts.dir`" ] && [ -r $XTTFFONTPATH/$targetname ]; then continue; fi

        # Now get font table entries
        if [ ! -x $TTFINFOPATH ]; then
            echo "ttfinfo not installed."
            exit 1
        else
            # Get font face number
            eval `echo 0 | $TTFINFOPATH -c ${XTTFFONTPATH}/${targetname} 2> /dev/null | grep "TTFINFO_FACE_NUM"`
        fi

        # Install all font faces in the font
        fn=0
        while [ $fn -le $(($TTFINFO_FACE_NUM - 1)) ]; do
            eval `echo $fn | $TTFINFOPATH -c ${XTTFFONTPATH}/${targetname} 2> /dev/null`

        # Set fontname from the filename if it's unknown.
        # I assume there's no ttf filename like "-----.ttf".
        if [ "$TTFINFO_FONT_NAME" = "unknown" ]; then
            TTFINFO_FONT_NAME=`echo $targetname |cut -d "." -f 1 |sed -e "s/-//g"`
        fi

        # Extract slant/property/encoding, then install.
        MAPNUM=1
        while [ $MAPNUM -le $TTFINFO_MAPNUM ]; do
            eval TTFINFO_FONTMAP=\$TTFINFO_FONTMAP${MAPNUM}
            fontslant=`echo $TTFINFO_FONTMAP |cut -d "-" -f 5`
            fontproperty=`echo $TTFINFO_FONTMAP |cut -d "-" -f 12`
            encoding1=`echo $TTFINFO_FONTMAP |cut -d "-" -f 14`
            encoding2=`echo $TTFINFO_FONTMAP |cut -d "-" -f 15`
            fontencoding=$encoding1-$encoding2
            install_xfont "$targetname" "$TTFINFO_FACE_NUM" "$TTFINFO_FACE_INDEX" "$TTFINFO_FOUNDRY_NAME" "$TTFINFO_FONT_NAME" $TTFINFO_WEIGHT_NAME $fontslant $TTFINFO_WIDTH $fontproperty "$fontencoding"

	    # Preliminary support for HKSCS
	    if [ "$fontencoding" = "big5-0" ]; then
		install_xfont "$targetname" "$TTFINFO_FACE_NUM" "$TTFINFO_FACE_INDEX" "$TTFINFO_FOUNDRY_NAME" "$TTFINFO_FONT_NAME" $TTFINFO_WEIGHT_NAME $fontslant $TTFINFO_WIDTH $fontproperty "big5hkscs-0"
		install_xfont "$targetname" "$TTFINFO_FACE_NUM" "$TTFINFO_FACE_INDEX" "$TTFINFO_FOUNDRY_NAME" "$TTFINFO_FONT_NAME" $TTFINFO_WEIGHT_NAME $fontslant $TTFINFO_WIDTH $fontproperty "hkscs-1"
	    fi
	    # Preliminary support for GB18030
	    if [ "$fontencoding" = "gb2312.1980-0" ]; then
		install_xfont "$targetname" "$TTFINFO_FACE_NUM" "$TTFINFO_FACE_INDEX" "$TTFINFO_FOUNDRY_NAME" "$TTFINFO_FONT_NAME" $TTFINFO_WEIGHT_NAME $fontslant $TTFINFO_WIDTH $fontproperty "gb18030-0"
		install_xfont "$targetname" "$TTFINFO_FACE_NUM" "$TTFINFO_FACE_INDEX" "$TTFINFO_FOUNDRY_NAME" "$TTFINFO_FONT_NAME" $TTFINFO_WEIGHT_NAME $fontslant $TTFINFO_WIDTH $fontproperty "gb18030.2000-0"
		install_xfont "$targetname" "$TTFINFO_FACE_NUM" "$TTFINFO_FACE_INDEX" "$TTFINFO_FOUNDRY_NAME" "$TTFINFO_FONT_NAME" $TTFINFO_WEIGHT_NAME $fontslant $TTFINFO_WIDTH $fontproperty "gb18030.2000-1"
		install_xfont "$targetname" "$TTFINFO_FACE_NUM" "$TTFINFO_FACE_INDEX" "$TTFINFO_FOUNDRY_NAME" "$TTFINFO_FONT_NAME" $TTFINFO_WEIGHT_NAME $fontslant $TTFINFO_WIDTH $fontproperty "gbk-0"
	    fi
	    
            MAPNUM=`expr $MAPNUM + 1`
        done
        # Check and install if iso10646 is supported.
        CMAPNUM=0
        while [ $CMAPNUM -lt $TTFINFO_NUMCMAP ]; do
            eval TTFINFO_CMAPNAME=\$TTFINFO_CMAPNAME$CMAPNUM
            if [ -n "`echo $TTFINFO_CMAPNAME |grep Unicode`" ]; then
                fontproperty=`echo $TTFINFO_FONTMAP | cut -d "-" -f 12`
                fontencoding="iso10646-1"
                ALIASPATTERN=`eval echo $ALIASPATTERN`
                # LAME CODE ALERT :-)
		isoxlfd=`grep "${targetname}.*-${fontproperty}-.*" ${XTTFFONTPATH}/fonts.dir |sed -e "s/-[a-z0-9]*-[0-9]$/-iso10646-1/" |sed -e "s/${targetname} //"`
                TTFINFO_FOUNDRY_NAME=`echo $isoxlfd |cut -d "-" -f 2`
                TTFINFO_FONT_NAME=`echo $isoxlfd |cut -d "-" -f 3`
                TTFINFO_WEIGHT_NAME=`echo $isoxlfd |cut -d "-" -f 4`
                fontslant=`echo $isoxlfd |cut -d "-" -f 5`
                TTFINFO_WIDTH=`echo $isoxlfd |cut -d "-" -f 6`
                install_xfont "$targetname" "$TTFINFO_FACE_NUM" "$TTFINFO_FACE_INDEX" "$TTFINFO_FOUNDRY_NAME" "$TTFINFO_FONT_NAME" $TTFINFO_WEIGHT_NAME $fontslant $TTFINFO_WIDTH $fontproperty "$fontencoding"
            break
            fi
            CMAPNUM=`expr $CMAPNUM + 1`
        done
        fn=$(($fn+1))
        done	# for fn
    done
}


#
# Set default font, accept kai or ming(default) only, all others will be
# treated as ming.
#
# It's assumed that FreeBSD ports/packages install fonts in $DefaultFontPath,
# and we'll make a symbolic in $XTTFFONTPATH.
#
# I'm not sure if -default-*-iso10646-1 should be created.
#
setdefault()
{
    face=$1
    fontfile=`basename $2`
    srcdir=`dirname "$addfile"`
    # --add *.ttf
    if [ $srcdir = '.' ]; then
        srcdir=`pwd`
    fi

    # Some sanity checking
    if [ ! -d $DefaultFontPath ]; then mkdir -p $DefaultFontPath; fi
    if [ ! -d $XTTFFONTPATH ]; then mkdir -p $XTTFFONTPATH; fi
    if [ ! -r "$srcdir/$fontfile" ]; then continue; fi
    if [ ! -r "$DefaultFontPath/$fontfile" ]; then
        ln -s "$srcdir/$fontfile" $DefaultFontPath
    fi
    if [ ! -r "$XTTFFONTPATH/$fontfile" ]; then
        ln -s "$DefaultFontPath/$fontfile" $XTTFFONTPATH
    fi

    # Now get font table entries
    if [ ! -x $TTFINFOPATH ]; then
        echo "ttfinfo not installed."
        exit 1
    else
        eval `$TTFINFOPATH -c $XTTFFONTPATH/$fontfile`
    fi

    # Extract slant/property/encoding, then install.
    i=1
    while [ $i -le $TTFINFO_MAPNUM ]; do
        eval TTFINFO_FONTMAP=\$TTFINFO_FONTMAP$i
        fontslant=`echo $TTFINFO_FONTMAP |cut -d "-" -f 5`
        fontproperty=`echo $TTFINFO_FONTMAP |cut -d "-" -f 12`
        encoding1=`echo $TTFINFO_FONTMAP |cut -d "-" -f 14`
        encoding2=`echo $TTFINFO_FONTMAP |cut -d "-" -f 15`
        fontencoding=$encoding1-$encoding2

        # Who needs default-ming-*-iso8859-1 anyway? :-)
        if [ $fontencoding != "big5-0" ] && [ $fontencoding != "gb2312.1980-0" ]; then
            i=`expr $i + 1`
            continue
        fi

        # Overwrite foundry & fontname fields in XLFD, and create
        # $XTTFFONTPATH/default-${kai,ming}-${big5-0,gb2312.1980-0}
        TTFINFO_FOUNDRY_NAME="default"
        if [ "$face" = "kai" ];then
            targetname=$DEFAULTKAI_NAME-$fontencoding.ttf
            TTFINFO_FONT_NAME="kai"
        else
            targetname=$DEFAULTMING_NAME-$fontencoding.ttf
            TTFINFO_FONT_NAME="ming"
        fi
        # Demanding users want to change default font.
        if [ -r "$XTTFFONTPATH/$targetname" ]; then
            remove_fonts "$XTTFFONTPATH/$targetname"
            rm -f "$XTTFFONTPATH/$targetname"
        fi
        ln -sf "$XTTFFONTPATH/$fontfile" "$XTTFFONTPATH/$targetname"

        echo "Set $2 as ${fontencoding}'s default $face font."
        install_xfont "$targetname" "$TTFINFO_FACE_NUM" "$TTFINFO_FACE_INDEX" "$TTFINFO_FOUNDRY_NAME" "$TTFINFO_FONT_NAME" $TTFINFO_WEIGHT_NAME $fontslant $TTFINFO_WIDTH $fontproperty "$fontencoding"
        i=`expr $i + 1`

    done
}



#
# main program
#

if [ $# -lt 1 ]; then
    Usage
    exit 1
fi

ARG=$1
shift 1

case $ARG in
--help)
    Usage
    ;;
--name)
    echo "$NAME $VERSION"
    ;;
--list)
    list_fonts
    ;;
--add)
    if [ $# -lt 1 ]; then
        echo "Missing font filename argument."
        Usage
        exit 1
    fi
    add_fonts $@
    echo "Adding $@."
    ;;
--remove)
    if [ $# -lt 1 ]; then
        echo "Missing font filename argument."
        Usage
        exit 1
    fi
    remove_fonts $@
    echo "Removing $@."
    ;;
--setdefault|--setdefault_ming)
    if [ $# -lt 1 ]; then
        echo "Missing font filename arguments."
        Usage
        exit 1
    elif [ $# -gt 1 ]; then
        echo "Only need one font filename."
        Usage
        exit 1
    fi
    setdefault ming $1
    ;;
--setdefault_kai)
    if [ $# -lt 1 ]; then
        echo "Missing font filename arguments."
        Usage
        exit 1
    elif [ $# -gt 1 ]; then
        echo "Only need one font filename."
        Usage
        exit 1
    fi
    setdefault kai $1
    ;;
*)
    Usage
    exit 1
    ;;
esac

rm -f $TEMPFILE
exit 0


# ChangeLog
#
# $Log: xttfm.ttfm,v $
# Revision 1.2  2001/01/31 09:30:13  keith
# Change VERSION to 0.9.3, no other changes.
#
# Revision 1.1.1.1  2000/12/16 18:56:41  keith
# Import of TTFM 0.9.2
#
# Revision 1.3  2000/11/10 14:25:37  Keith
# Log entry was added.
#
# * Wed Nov 8 2000 Jing-Tang Keith Jang <keith@FreeBSD.org>
# - Branch from xttfm.ttfm to xttfm-sh.ttfm.  It's a rewritten
#   Bourne shell script to drop tcl dependency.
#
# * Wed Feb  2 2000 Yuan-Chung Cheng <platin@linux.org.tw>
# - /usr/sbin/chkfontpath -q -a /usr/X11R6/lib/X11/fonts/TrueType
#
# * Fri Jan  7 2000 Chih-Wei Huang <cwhuang@linux.org.tw>
# - reload xfs after add & remove font
#
# * Mon Nov  8 1999 Yuan-Chung Cheng <platin@linux.org.tw>
# - merge --setdefault_ming and --setdefault_kai proc.
#
# * Mon Nov  8 1999 Yuan-Chung Cheng <platin@linux.org.tw>
# - --add, --setdefault, --setdefault_ming, --setdefault_kai
#
# * Fri Nov  5 1999 Yuan-Chung Cheng <platin@linux.org.tw>
# - rewrite from ttfinst.tk to handle X fonts non-interactively
#
