#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68.
+# Generated by GNU Autoconf 2.69.
#
# Copyright (c) 1999-2012, International Business Machines Corporation and others. All Rights Reserved.
#
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
else
exitcode=1; echo positional parameters were not saved.
fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- # Preserve -v and -x to the replacement shell.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
- esac
- exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
fi
if test x$as_have_required = xno; then :
} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
if $ac_init_version; then
cat <<\_ACEOF
configure
-generated by GNU Autoconf 2.68
+generated by GNU Autoconf 2.69
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
main ()
{
static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
main ()
{
static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
main ()
{
static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
running configure, to aid debugging if configure makes a mistake.
It was created by $as_me, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_U_MAKE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+ as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+ as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="${ac_tool_prefix}ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
# output the Makefiles
-ac_config_files="$ac_config_files icudefs.mk Makefile data/pkgdataMakefile config/Makefile.inc config/icu.pc config/pkgdataMakefile data/Makefile stubdata/Makefile common/Makefile i18n/Makefile layout/Makefile layoutex/Makefile io/Makefile extra/Makefile extra/uconv/Makefile extra/uconv/pkgdataMakefile extra/scrptrun/Makefile tools/Makefile tools/ctestfw/Makefile tools/toolutil/Makefile tools/makeconv/Makefile tools/genrb/Makefile tools/genccode/Makefile tools/gencmn/Makefile tools/gencnval/Makefile tools/gendict/Makefile tools/gentest/Makefile tools/gennorm2/Makefile tools/genbrk/Makefile tools/gensprep/Makefile tools/icuinfo/Makefile tools/icupkg/Makefile tools/icuswap/Makefile tools/pkgdata/Makefile tools/tzcode/Makefile tools/gencfu/Makefile test/Makefile test/compat/Makefile test/testdata/Makefile test/testdata/pkgdataMakefile test/hdrtst/Makefile test/intltest/Makefile test/cintltst/Makefile test/iotest/Makefile test/letest/Makefile test/perf/Makefile test/perf/collationperf/Makefile test/perf/collperf/Makefile test/perf/dicttrieperf/Makefile test/perf/ubrkperf/Makefile test/perf/charperf/Makefile test/perf/convperf/Makefile test/perf/normperf/Makefile test/perf/DateFmtPerf/Makefile test/perf/howExpensiveIs/Makefile test/perf/strsrchperf/Makefile test/perf/unisetperf/Makefile test/perf/usetperf/Makefile test/perf/ustrperf/Makefile test/perf/utfperf/Makefile test/perf/utrie2perf/Makefile samples/Makefile samples/date/Makefile samples/cal/Makefile samples/layout/Makefile"
+ac_config_files="$ac_config_files icudefs.mk Makefile data/pkgdataMakefile config/Makefile.inc config/icu.pc config/pkgdataMakefile data/Makefile stubdata/Makefile common/Makefile i18n/Makefile layout/Makefile layoutex/Makefile io/Makefile extra/Makefile extra/uconv/Makefile extra/uconv/pkgdataMakefile extra/scrptrun/Makefile tools/Makefile tools/ctestfw/Makefile tools/toolutil/Makefile tools/makeconv/Makefile tools/genrb/Makefile tools/genccode/Makefile tools/gencmn/Makefile tools/gencnval/Makefile tools/gendict/Makefile tools/gentest/Makefile tools/gennorm2/Makefile tools/genbrk/Makefile tools/gensprep/Makefile tools/icuinfo/Makefile tools/icupkg/Makefile tools/icuswap/Makefile tools/pkgdata/Makefile tools/tzcode/Makefile tools/gencfu/Makefile test/Makefile test/compat/Makefile test/testdata/Makefile test/testdata/pkgdataMakefile test/hdrtst/Makefile test/intltest/Makefile test/cintltst/Makefile test/iotest/Makefile test/letest/Makefile test/perf/Makefile test/perf/collationperf/Makefile test/perf/collperf/Makefile test/perf/dicttrieperf/Makefile test/perf/ubrkperf/Makefile test/perf/charperf/Makefile test/perf/convperf/Makefile test/perf/normperf/Makefile test/perf/DateFmtPerf/Makefile test/perf/howExpensiveIs/Makefile test/perf/strsrchperf/Makefile test/perf/unisetperf/Makefile test/perf/usetperf/Makefile test/perf/ustrperf/Makefile test/perf/utfperf/Makefile test/perf/utrie2perf/Makefile test/perf/leperf/Makefile samples/Makefile samples/date/Makefile samples/cal/Makefile samples/layout/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# values after options handling.
ac_log="
This file was extended by $as_me, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
config.status
-configured by $0, generated by GNU Autoconf 2.68,
+configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
"test/perf/ustrperf/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/ustrperf/Makefile" ;;
"test/perf/utfperf/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/utfperf/Makefile" ;;
"test/perf/utrie2perf/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/utrie2perf/Makefile" ;;
+ "test/perf/leperf/Makefile") CONFIG_FILES="$CONFIG_FILES test/perf/leperf/Makefile" ;;
"samples/Makefile") CONFIG_FILES="$CONFIG_FILES samples/Makefile" ;;
"samples/date/Makefile") CONFIG_FILES="$CONFIG_FILES samples/date/Makefile" ;;
"samples/cal/Makefile") CONFIG_FILES="$CONFIG_FILES samples/cal/Makefile" ;;
test/perf/ustrperf/Makefile \
test/perf/utfperf/Makefile \
test/perf/utrie2perf/Makefile \
+ test/perf/leperf/Makefile \
samples/Makefile samples/date/Makefile \
samples/cal/Makefile samples/layout/Makefile])
AC_OUTPUT
--- /dev/null
+/***************************************************************************
+*
+* Copyright (C) 1998-2013, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+************************************************************************/
+
+#include <stdio.h>
+
+#include "LETypes.h"
+#include "FontObject.h"
+#include "LESwaps.h"
+
+FontObject::FontObject(char *fileName)
+ : directory(NULL), numTables(0), searchRange(0),entrySelector(0),
+ cmapTable(NULL), cmSegCount(0), cmSearchRange(0), cmEntrySelector(0),
+ cmEndCodes(NULL), cmStartCodes(NULL), cmIdDelta(0), cmIdRangeOffset(0),
+ headTable(NULL), hmtxTable(NULL), numGlyphs(0), numOfLongHorMetrics(0), file(NULL)
+{
+ file = fopen(fileName, "rb");
+
+ if (file == NULL) {
+ printf("?? Couldn't open %s", fileName);
+ return;
+ }
+
+ SFNTDirectory tempDir;
+
+ fread(&tempDir, sizeof tempDir, 1, file);
+
+ numTables = SWAPW(tempDir.numTables);
+ searchRange = SWAPW(tempDir.searchRange) >> 4;
+ entrySelector = SWAPW(tempDir.entrySelector);
+ rangeShift = SWAPW(tempDir.rangeShift) >> 4;
+
+ int dirSize = sizeof tempDir + ((numTables - ANY_NUMBER) * sizeof(DirectoryEntry));
+
+ directory = (SFNTDirectory *) new char[dirSize];
+
+ fseek(file, 0L, SEEK_SET);
+ fread(directory, sizeof(char), dirSize, file);
+
+ initUnicodeCMAP();
+}
+
+FontObject::~FontObject()
+{
+ fclose(file);
+ delete[] directory;
+ delete[] cmapTable;
+ delete[] headTable;
+ delete[] hmtxTable;
+}
+
+void FontObject::deleteTable(void *table)
+{
+ delete[] (char *) table;
+}
+
+DirectoryEntry *FontObject::findTable(LETag tag)
+{
+ le_uint16 table = 0;
+ le_uint16 probe = 1 << entrySelector;
+
+ if (SWAPL(directory->tableDirectory[rangeShift].tag) <= tag) {
+ table = rangeShift;
+ }
+
+ while (probe > (1 << 0)) {
+ probe >>= 1;
+
+ if (SWAPL(directory->tableDirectory[table + probe].tag) <= tag) {
+ table += probe;
+ }
+ }
+
+ if (SWAPL(directory->tableDirectory[table].tag) == tag) {
+ return &directory->tableDirectory[table];
+ }
+
+ return NULL;
+}
+
+void *FontObject::readTable(LETag tag, le_uint32 *length)
+{
+ DirectoryEntry *entry = findTable(tag);
+
+ if (entry == NULL) {
+ *length = 0;
+ return NULL;
+ }
+
+ *length = SWAPL(entry->length);
+
+ void *table = new char[*length];
+
+ fseek(file, SWAPL(entry->offset), SEEK_SET);
+ fread(table, sizeof(char), *length, file);
+
+ return table;
+}
+
+CMAPEncodingSubtable *FontObject::findCMAP(le_uint16 platformID, le_uint16 platformSpecificID)
+{
+ LETag cmapTag = 0x636D6170; // 'cmap'
+
+ if (cmapTable == NULL) {
+ le_uint32 length;
+
+ cmapTable = (CMAPTable *) readTable(cmapTag, &length);
+ }
+
+ if (cmapTable != NULL) {
+ le_uint16 i;
+ le_uint16 nSubtables = SWAPW(cmapTable->numberSubtables);
+
+
+ for (i = 0; i < nSubtables; i += 1) {
+ CMAPEncodingSubtableHeader *esh = &cmapTable->encodingSubtableHeaders[i];
+
+ if (SWAPW(esh->platformID) == platformID &&
+ SWAPW(esh->platformSpecificID) == platformSpecificID) {
+ return (CMAPEncodingSubtable *) ((char *) cmapTable + SWAPL(esh->encodingOffset));
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void FontObject::initUnicodeCMAP()
+{
+ CMAPEncodingSubtable *encodingSubtable = findCMAP(3, 1);
+
+ if (encodingSubtable == 0 ||
+ SWAPW(encodingSubtable->format) != 4) {
+ printf("Can't find unicode 'cmap'");
+ return;
+ }
+
+ CMAPFormat4Encoding *header = (CMAPFormat4Encoding *) encodingSubtable;
+
+ cmSegCount = SWAPW(header->segCountX2) / 2;
+ cmSearchRange = SWAPW(header->searchRange);
+ cmEntrySelector = SWAPW(header->entrySelector);
+ cmRangeShift = SWAPW(header->rangeShift) / 2;
+ cmEndCodes = &header->endCodes[0];
+ cmStartCodes = &header->endCodes[cmSegCount + 1]; // + 1 for reservedPad...
+ cmIdDelta = &cmStartCodes[cmSegCount];
+ cmIdRangeOffset = &cmIdDelta[cmSegCount];
+}
+
+LEGlyphID FontObject::unicodeToGlyph(LEUnicode32 unicode32)
+{
+ if (unicode32 >= 0x10000) {
+ return 0;
+ }
+
+ LEUnicode16 unicode = (LEUnicode16) unicode32;
+ le_uint16 index = 0;
+ le_uint16 probe = 1 << cmEntrySelector;
+ LEGlyphID result = 0;
+
+ if (SWAPW(cmStartCodes[cmRangeShift]) <= unicode) {
+ index = cmRangeShift;
+ }
+
+ while (probe > (1 << 0)) {
+ probe >>= 1;
+
+ if (SWAPW(cmStartCodes[index + probe]) <= unicode) {
+ index += probe;
+ }
+ }
+
+ if (unicode >= SWAPW(cmStartCodes[index]) && unicode <= SWAPW(cmEndCodes[index])) {
+ if (cmIdRangeOffset[index] == 0) {
+ result = (LEGlyphID) unicode;
+ } else {
+ le_uint16 offset = unicode - SWAPW(cmStartCodes[index]);
+ le_uint16 rangeOffset = SWAPW(cmIdRangeOffset[index]);
+ le_uint16 *glyphIndexTable = (le_uint16 *) ((char *) &cmIdRangeOffset[index] + rangeOffset);
+
+ result = SWAPW(glyphIndexTable[offset]);
+ }
+
+ result += SWAPW(cmIdDelta[index]);
+ } else {
+ result = 0;
+ }
+
+ return result;
+}
+
+le_uint16 FontObject::getUnitsPerEM()
+{
+ if (headTable == NULL) {
+ LETag headTag = 0x68656164; // 'head'
+ le_uint32 length;
+
+ headTable = (HEADTable *) readTable(headTag, &length);
+ }
+
+ return SWAPW(headTable->unitsPerEm);
+}
+
+le_uint16 FontObject::getGlyphAdvance(LEGlyphID glyph)
+{
+ if (hmtxTable == NULL) {
+ LETag maxpTag = 0x6D617870; // 'maxp'
+ LETag hheaTag = 0x68686561; // 'hhea'
+ LETag hmtxTag = 0x686D7478; // 'hmtx'
+ le_uint32 length;
+ HHEATable *hheaTable;
+ MAXPTable *maxpTable = (MAXPTable *) readTable(maxpTag, &length);
+
+ numGlyphs = SWAPW(maxpTable->numGlyphs);
+ deleteTable(maxpTable);
+
+ hheaTable = (HHEATable *) readTable(hheaTag, &length);
+ numOfLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
+ deleteTable(hheaTable);
+
+ hmtxTable = (HMTXTable *) readTable(hmtxTag, &length);
+ }
+
+ le_uint16 index = glyph;
+
+ if (glyph >= numGlyphs) {
+ return 0;
+ }
+
+ if (glyph >= numOfLongHorMetrics) {
+ index = numOfLongHorMetrics - 1;
+ }
+
+ return SWAPW(hmtxTable->hMetrics[index].advanceWidth);
+}
+
+
--- /dev/null
+/***************************************************************************
+*
+* Copyright (C) 1998-2013, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+************************************************************************/
+
+
+#ifndef __FONTOBJECT_H
+#define __FONTOBJECT_H
+
+#include <stdio.h>
+
+#include "LETypes.h"
+
+
+#ifndef ANY_NUMBER
+#define ANY_NUMBER 1
+#endif
+
+struct DirectoryEntry
+{
+ le_uint32 tag;
+ le_uint32 checksum;
+ le_uint32 offset;
+ le_uint32 length;
+};
+
+struct SFNTDirectory
+{
+ le_uint32 scalerType;
+ le_uint16 numTables;
+ le_uint16 searchRange;
+ le_uint16 entrySelector;
+ le_uint16 rangeShift;
+ DirectoryEntry tableDirectory[ANY_NUMBER];
+};
+
+
+struct CMAPEncodingSubtableHeader
+{
+ le_uint16 platformID;
+ le_uint16 platformSpecificID;
+ le_uint32 encodingOffset;
+};
+
+struct CMAPTable
+{
+ le_uint16 version;
+ le_uint16 numberSubtables;
+ CMAPEncodingSubtableHeader encodingSubtableHeaders[ANY_NUMBER];
+};
+
+struct CMAPEncodingSubtable
+{
+ le_uint16 format;
+ le_uint16 length;
+ le_uint16 language;
+};
+
+struct CMAPFormat0Encoding : CMAPEncodingSubtable
+{
+ le_uint8 glyphIndexArray[256];
+};
+
+struct CMAPFormat2Subheader
+{
+ le_uint16 firstCode;
+ le_uint16 entryCount;
+ le_int16 idDelta;
+ le_uint16 idRangeOffset;
+};
+
+struct CMAPFormat2Encoding : CMAPEncodingSubtable
+{
+ le_uint16 subHeadKeys[256];
+ CMAPFormat2Subheader subheaders[ANY_NUMBER];
+};
+
+struct CMAPFormat4Encoding : CMAPEncodingSubtable
+{
+ le_uint16 segCountX2;
+ le_uint16 searchRange;
+ le_uint16 entrySelector;
+ le_uint16 rangeShift;
+ le_uint16 endCodes[ANY_NUMBER];
+// le_uint16 reservedPad;
+// le_uint16 startCodes[ANY_NUMBER];
+// le_uint16 idDelta[ANY_NUMBER];
+// le_uint16 idRangeOffset[ANY_NUMBER];
+// le_uint16 glyphIndexArray[ANY_NUMBER];
+};
+
+struct CMAPFormat6Encoding : CMAPEncodingSubtable
+{
+ le_uint16 firstCode;
+ le_uint16 entryCount;
+ le_uint16 glyphIndexArray[ANY_NUMBER];
+};
+
+typedef le_int32 fixed;
+
+struct BigDate
+{
+ le_uint32 bc;
+ le_uint32 ad;
+};
+
+struct HEADTable
+{
+ fixed version;
+ fixed fontRevision;
+ le_uint32 checksumAdjustment;
+ le_uint32 magicNumber;
+ le_uint16 flags;
+ le_uint16 unitsPerEm;
+ BigDate created;
+ BigDate modified;
+ le_int16 xMin;
+ le_int16 yMin;
+ le_int16 xMax;
+ le_int16 yMax;
+ le_int16 lowestRecPPEM;
+ le_int16 fontDirectionHint;
+ le_int16 indexToLocFormat;
+ le_int16 glyphDataFormat;
+};
+
+struct MAXPTable
+{
+ fixed version;
+ le_uint16 numGlyphs;
+ le_uint16 maxPoints;
+ le_uint16 maxContours;
+ le_uint16 maxComponentPoints;
+ le_uint16 maxComponentContours;
+ le_uint16 maxZones;
+ le_uint16 maxTwilightPoints;
+ le_uint16 maxStorage;
+ le_uint16 maxFunctionDefs;
+ le_uint16 maxInstructionDefs;
+ le_uint16 maxStackElements;
+ le_uint16 maxSizeOfInstructions;
+ le_uint16 maxComponentElements;
+ le_uint16 maxComponentDepth;
+};
+
+struct HHEATable
+{
+ fixed version;
+ le_int16 ascent;
+ le_int16 descent;
+ le_int16 lineGap;
+ le_uint16 advanceWidthMax;
+ le_int16 minLeftSideBearing;
+ le_int16 minRightSideBearing;
+ le_int16 xMaxExtent;
+ le_int16 caretSlopeRise;
+ le_int16 caretSlopeRun;
+ le_int16 caretOffset;
+ le_int16 reserved1;
+ le_int16 reserved2;
+ le_int16 reserved3;
+ le_int16 reserved4;
+ le_int16 metricDataFormat;
+ le_uint16 numOfLongHorMetrics;
+};
+
+struct LongHorMetric
+{
+ le_uint16 advanceWidth;
+ le_int16 leftSideBearing;
+};
+
+struct HMTXTable
+{
+ LongHorMetric hMetrics[ANY_NUMBER]; // ANY_NUMBER = numOfLongHorMetrics from hhea table
+// le_int16 leftSideBearing[ANY_NUMBER]; // ANY_NUMBER = numGlyphs - numOfLongHorMetrics
+};
+
+class FontObject
+{
+public:
+ FontObject(char *fontName);
+ ~FontObject();
+
+ void *readTable(LETag tag, le_uint32 *length);
+ void deleteTable(void *table);
+
+ LEGlyphID unicodeToGlyph(LEUnicode32 unicode);
+
+#if 0
+ le_uint32 unicodesToGlyphs(LEUnicode *chars, le_uint32 nChars, LEGlyphID *glyphs,
+ le_uint32 *charIndices, le_bool rightToLeft);
+#endif
+
+ le_uint16 getUnitsPerEM();
+
+ le_uint16 getGlyphAdvance(LEGlyphID glyph);
+
+private:
+ FontObject();
+
+ DirectoryEntry *findTable(LETag tag);
+ CMAPEncodingSubtable *findCMAP(le_uint16 platformID, le_uint16 platformSpecificID);
+ void initUnicodeCMAP();
+
+ SFNTDirectory *directory;
+ le_uint16 numTables;
+ le_uint16 searchRange;
+ le_uint16 entrySelector;
+ le_uint16 rangeShift;
+
+ CMAPTable *cmapTable;
+ le_uint16 cmSegCount;
+ le_uint16 cmSearchRange;
+ le_uint16 cmEntrySelector;
+ le_uint16 cmRangeShift;
+ le_uint16 *cmEndCodes;
+ le_uint16 *cmStartCodes;
+ le_uint16 *cmIdDelta;
+ le_uint16 *cmIdRangeOffset;
+
+ HEADTable *headTable;
+
+ HMTXTable *hmtxTable;
+ le_uint16 numGlyphs;
+ le_uint16 numOfLongHorMetrics;
+
+ FILE *file;
+
+};
+
+#endif
+
--- /dev/null
+/*
+ **********************************************************************
+ * Copyright (C) 2003-2013, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ **********************************************************************
+ */
+
+#include "layout/LETypes.h"
+
+//#include "letest.h"
+#include "FontTableCache.h"
+
+#define TABLE_CACHE_INIT 5
+#define TABLE_CACHE_GROW 5
+
+struct FontTableCacheEntry
+{
+ LETag tag;
+ const void *table;
+ size_t length;
+};
+
+FontTableCache::FontTableCache()
+ : fTableCacheCurr(0), fTableCacheSize(TABLE_CACHE_INIT)
+{
+ fTableCache = LE_NEW_ARRAY(FontTableCacheEntry, fTableCacheSize);
+
+ if (fTableCache == NULL) {
+ fTableCacheSize = 0;
+ return;
+ }
+
+ for (int i = 0; i < fTableCacheSize; i += 1) {
+ fTableCache[i].tag = 0;
+ fTableCache[i].table = NULL;
+ fTableCache[i].length = 0;
+ }
+}
+
+FontTableCache::~FontTableCache()
+{
+ for (int i = fTableCacheCurr - 1; i >= 0; i -= 1) {
+ LE_DELETE_ARRAY(fTableCache[i].table);
+
+ fTableCache[i].tag = 0;
+ fTableCache[i].table = NULL;
+ fTableCache[i].length = 0;
+ }
+
+ fTableCacheCurr = 0;
+
+ LE_DELETE_ARRAY(fTableCache);
+}
+
+void FontTableCache::freeFontTable(const void *table) const
+{
+ LE_DELETE_ARRAY(table);
+}
+
+const void *FontTableCache::find(LETag tableTag, size_t &length) const
+{
+ for (int i = 0; i < fTableCacheCurr; i += 1) {
+ if (fTableCache[i].tag == tableTag) {
+ length = fTableCache[i].length;
+ return fTableCache[i].table;
+ }
+ }
+
+ const void *table = readFontTable(tableTag, length);
+
+ ((FontTableCache *) this)->add(tableTag, table, length);
+
+ return table;
+}
+
+void FontTableCache::add(LETag tableTag, const void *table, size_t length)
+{
+ if (fTableCacheCurr >= fTableCacheSize) {
+ le_int32 newSize = fTableCacheSize + TABLE_CACHE_GROW;
+
+ fTableCache = (FontTableCacheEntry *) LE_GROW_ARRAY(fTableCache, newSize);
+
+ for (le_int32 i = fTableCacheSize; i < newSize; i += 1) {
+ fTableCache[i].tag = 0;
+ fTableCache[i].table = NULL;
+ fTableCache[i].length = 0;
+ }
+
+ fTableCacheSize = newSize;
+ }
+
+ fTableCache[fTableCacheCurr].tag = tableTag;
+ fTableCache[fTableCacheCurr].table = table;
+ fTableCache[fTableCacheCurr].length = length;
+
+ fTableCacheCurr += 1;
+}
--- /dev/null
+/*
+ **********************************************************************
+ * Copyright (C) 2003-2013, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ **********************************************************************
+ */
+
+#ifndef __FONTTABLECACHE_H
+
+#define __FONTTABLECACHE_H
+
+#include "layout/LETypes.h"
+
+U_NAMESPACE_USE
+
+struct FontTableCacheEntry;
+
+class FontTableCache
+{
+public:
+ FontTableCache();
+
+ virtual ~FontTableCache();
+
+ const void *find(LETag tableTag, size_t &length) const;
+
+protected:
+ virtual const void *readFontTable(LETag tableTag, size_t &length) const = 0;
+ virtual void freeFontTable(const void *table) const;
+
+private:
+
+ void add(LETag tableTag, const void *table, size_t length);
+
+ FontTableCacheEntry *fTableCache;
+ le_int32 fTableCacheCurr;
+ le_int32 fTableCacheSize;
+};
+
+#endif
+
--- /dev/null
+## Makefile.in for ICU - test/perf/collperf
+## Copyright (c) 2001-2013, International Business Machines Corporation and
+## others. All Rights Reserved.
+
+## Source directory information
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+top_builddir = ../../..
+
+include $(top_builddir)/icudefs.mk
+
+-include Makefile.local
+
+## Build directory information
+subdir = test/perf/leperf
+
+## Extra files to remove for 'make clean'
+CLEANFILES = *~ $(DEPS)
+
+## Target information
+TARGET = leperf
+
+CPPFLAGS += -I$(top_srcdir)/common -I$(top_srcdir)/layout/.. -I$(top_srcdir)/tools/toolutil -I$(top_srcdir)/tools/ctestfw -I$(top_srcdir)/io -I$(top_srcdir)/i18n
+LIBS = $(LIBCTESTFW) $(LIBICUIO) $(LIBICULE) $(LIBICUUC) $(LIBICUI18N) $(LIBICUTOOLUTIL) $(DEFAULT_LIBS) $(LIB_M)
+
+OBJECTS = $(TARGET).o
+
+DEPS = $(OBJECTS:.o=.d)
+
+## List of phony targets
+.PHONY : all all-local install install-local clean clean-local \
+distclean distclean-local dist dist-local check check-local
+
+## Clear suffix list
+.SUFFIXES :
+
+## List of standard targets
+all: all-local
+install: install-local
+clean: clean-local
+distclean : distclean-local
+dist: dist-local
+check: all check-local
+
+all-local: $(TARGET)
+
+install-local:
+
+dist-local:
+
+clean-local:
+ test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
+ $(RMV) $(OBJECTS) $(TARGET)
+
+distclean-local: clean-local
+ $(RMV) Makefile
+
+check-local: all-local
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(TARGET) : $(OBJECTS)
+ $(LINK.cc) -o $@ $^ $(LIBS)
+ $(POST_BUILD_STEP)
+
+invoke:
+ @$(RMV) current.out
+# following is bash specific
+ set -o pipefail && ( ICU_DATA=$${ICU_DATA:-$(top_builddir)/data/} TZ=PST8PDT $(INVOKE) ./$(TARGET) $(INVOCATION) | tee current.out )
+
+ifeq (,$(MAKECMDGOALS))
+-include $(DEPS)
+else
+ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),)
+ifneq ($(patsubst %install,,$(MAKECMDGOALS)),)
+-include $(DEPS)
+endif
+endif
+endif
+
--- /dev/null
+/*
+ *******************************************************************************
+ *
+ * Copyright (C) 1999-2013, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ *
+ *******************************************************************************
+ * file name: PortableFontInstance.cpp
+ *
+ * created on: 11/22/1999
+ * created by: Eric R. Mader
+ */
+
+#include <stdio.h>
+
+#include "layout/LETypes.h"
+#include "layout/LEFontInstance.h"
+#include "layout/LESwaps.h"
+
+#include "PortableFontInstance.h"
+
+//#include "letest.h"
+#include "sfnt.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#if 0
+static const char *letagToStr(LETag tag, char *str) {
+ str[0]= 0xFF & (tag>>24);
+ str[1]= 0xFF & (tag>>16);
+ str[2]= 0xFF & (tag>>8);
+ str[3]= 0xFF & (tag>>0);
+ str[4]= 0;
+ return str;
+}
+#endif
+
+//
+// Finds the high bit by binary searching
+// through the bits in n.
+//
+le_int8 PortableFontInstance::highBit(le_int32 value)
+{
+ if (value <= 0) {
+ return -32;
+ }
+
+ le_uint8 bit = 0;
+
+ if (value >= 1 << 16) {
+ value >>= 16;
+ bit += 16;
+ }
+
+ if (value >= 1 << 8) {
+ value >>= 8;
+ bit += 8;
+ }
+
+ if (value >= 1 << 4) {
+ value >>= 4;
+ bit += 4;
+ }
+
+ if (value >= 1 << 2) {
+ value >>= 2;
+ bit += 2;
+ }
+
+ if (value >= 1 << 1) {
+ value >>= 1;
+ bit += 1;
+ }
+
+ return bit;
+}
+
+PortableFontInstance::PortableFontInstance(const char *fileName, float pointSize, LEErrorCode &status)
+ : fFile(NULL), fPointSize(pointSize), fUnitsPerEM(0), fFontChecksum(0), fAscent(0), fDescent(0), fLeading(0),
+ fDirectory(NULL), fNAMETable(NULL), fNameCount(0), fNameStringOffset(0), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0)
+{
+ if (LE_FAILURE(status)) {
+ return;
+ }
+
+ // open the font file
+ fFile = fopen(fileName, "rb");
+ //printf("Open Font: %s\n", fileName);
+
+ if (fFile == NULL) {
+ printf("%s:%d: %s: FNF\n", __FILE__, __LINE__, fileName);
+ status = LE_FONT_FILE_NOT_FOUND_ERROR;
+ return;
+ }
+
+ // read in the directory
+ SFNTDirectory tempDir;
+
+ fread(&tempDir, sizeof tempDir, 1, fFile);
+
+ le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
+ const LETag headTag = LE_HEAD_TABLE_TAG;
+ const LETag hheaTag = LE_HHEA_TABLE_TAG;
+ const HEADTable *headTable = NULL;
+ const HHEATable *hheaTable = NULL;
+// const NAMETable *nameTable = NULL;
+ le_uint16 numTables = 0;
+
+ fDirectory = (const SFNTDirectory *) LE_NEW_ARRAY(char, dirSize);
+
+ if (fDirectory == NULL) {
+ printf("%s:%d: %s: malloc err\n", __FILE__, __LINE__, fileName);
+ status = LE_MEMORY_ALLOCATION_ERROR;
+ goto error_exit;
+ }
+
+ fseek(fFile, 0L, SEEK_SET);
+ fread((void *) fDirectory, sizeof(char), dirSize, fFile);
+
+ //
+ // We calculate these numbers 'cause some fonts
+ // have bogus values for them in the directory header.
+ //
+ numTables = SWAPW(fDirectory->numTables);
+ fDirPower = 1 << highBit(numTables);
+ fDirExtra = numTables - fDirPower;
+
+ // read unitsPerEm from 'head' table
+ headTable = (const HEADTable *) readFontTable(headTag);
+
+ if (headTable == NULL) {
+ status = LE_MISSING_FONT_TABLE_ERROR;
+ printf("%s:%d: %s: missing head table\n", __FILE__, __LINE__, fileName);
+ goto error_exit;
+ }
+
+ fUnitsPerEM = SWAPW(headTable->unitsPerEm);
+ fFontChecksum = SWAPL(headTable->checksumAdjustment);
+ freeFontTable(headTable);
+
+ //nameTable = (NAMETable *) readFontTable(nameTag);
+
+ //if (nameTable == NULL) {
+ // status = LE_MISSING_FONT_TABLE_ERROR;
+ // goto error_exit;
+ //}
+
+ //fFontVersionString = findName(nameTable, NAME_VERSION_STRING, PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH);
+
+ //if (fFontVersionString == NULL) {
+ // status = LE_MISSING_FONT_TABLE_ERROR;
+ // goto error_exit;
+ //}
+
+ //freeFontTable(nameTable);
+
+ hheaTable = (HHEATable *) readFontTable(hheaTag);
+
+ if (hheaTable == NULL) {
+ printf("%s:%d: %s: missing hhea table\n", __FILE__, __LINE__, fileName);
+ status = LE_MISSING_FONT_TABLE_ERROR;
+ goto error_exit;
+ }
+
+ fAscent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
+ fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
+ fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
+
+ fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
+
+ freeFontTable((void *) hheaTable);
+
+ fCMAPMapper = findUnicodeMapper();
+
+ if (fCMAPMapper == NULL) {
+ printf("%s:%d: %s: can't load cmap\n", __FILE__, __LINE__, fileName);
+ status = LE_MISSING_FONT_TABLE_ERROR;
+ goto error_exit;
+ }
+
+ return;
+
+error_exit:
+ fclose(fFile);
+ fFile = NULL;
+ return;
+}
+
+PortableFontInstance::~PortableFontInstance()
+{
+ if (fFile != NULL) {
+ fclose(fFile);
+
+ freeFontTable(fHMTXTable);
+ freeFontTable(fNAMETable);
+
+ delete fCMAPMapper;
+
+ LE_DELETE_ARRAY(fDirectory);
+ }
+}
+
+const DirectoryEntry *PortableFontInstance::findTable(LETag tag) const
+{
+ if (fDirectory != NULL) {
+ le_uint16 table = 0;
+ le_uint16 probe = fDirPower;
+
+ if (SWAPL(fDirectory->tableDirectory[fDirExtra].tag) <= tag) {
+ table = fDirExtra;
+ }
+
+ while (probe > (1 << 0)) {
+ probe >>= 1;
+
+ if (SWAPL(fDirectory->tableDirectory[table + probe].tag) <= tag) {
+ table += probe;
+ }
+ }
+
+ if (SWAPL(fDirectory->tableDirectory[table].tag) == tag) {
+ return &fDirectory->tableDirectory[table];
+ }
+ }
+
+ return NULL;
+}
+
+const void *PortableFontInstance::readTable(LETag tag, le_uint32 *length) const
+{
+ const DirectoryEntry *entry = findTable(tag);
+
+ if (entry == NULL) {
+ *length = 0;
+ return NULL;
+ }
+
+ *length = SWAPL(entry->length);
+
+ void *table = LE_NEW_ARRAY(char, *length);
+
+ if (table != NULL) {
+ fseek(fFile, SWAPL(entry->offset), SEEK_SET);
+ fread(table, sizeof(char), *length, fFile);
+ }
+
+ return table;
+}
+
+const void *PortableFontInstance::getFontTable(LETag tableTag) const
+{
+ size_t ignored;
+ return getFontTable(tableTag, ignored);
+}
+
+const void *PortableFontInstance::getFontTable(LETag tableTag, size_t &length) const
+{
+ return FontTableCache::find(tableTag, length);
+}
+
+const void *PortableFontInstance::readFontTable(LETag tableTag, size_t &length) const
+{
+ le_uint32 len;
+
+ const void *data= readTable(tableTag, &len);
+ length = len;
+ //char tag5[5];
+ //printf("Read %s, result %p #%d\n", letagToStr(tableTag,tag5), data,len);
+ return data;
+}
+
+CMAPMapper *PortableFontInstance::findUnicodeMapper()
+{
+ LETag cmapTag = LE_CMAP_TABLE_TAG;
+ const CMAPTable *cmap = (CMAPTable *) readFontTable(cmapTag);
+
+ if (cmap == NULL) {
+ return NULL;
+ }
+
+ return CMAPMapper::createUnicodeMapper(cmap);
+}
+
+const char *PortableFontInstance::getNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
+{
+ if (fNAMETable == NULL) {
+ LETag nameTag = LE_NAME_TABLE_TAG;
+ PortableFontInstance *realThis = (PortableFontInstance *) this;
+
+ realThis->fNAMETable = (const NAMETable *) readFontTable(nameTag);
+
+ if (realThis->fNAMETable != NULL) {
+ realThis->fNameCount = SWAPW(realThis->fNAMETable->count);
+ realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset);
+ }
+ }
+
+ for(le_int32 i = 0; i < fNameCount; i += 1) {
+ const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
+
+ if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID &&
+ SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
+ char *name = ((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset);
+ le_uint16 length = SWAPW(nameRecord->length);
+ char *result = LE_NEW_ARRAY(char, length + 2);
+
+ LE_ARRAY_COPY(result, name, length);
+ result[length] = result[length + 1] = 0;
+
+ return result;
+ }
+ }
+
+ return NULL;
+}
+
+const LEUnicode16 *PortableFontInstance::getUnicodeNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
+{
+ if (fNAMETable == NULL) {
+ LETag nameTag = LE_NAME_TABLE_TAG;
+ PortableFontInstance *realThis = (PortableFontInstance *) this;
+
+ realThis->fNAMETable = (const NAMETable *) readFontTable(nameTag);
+
+ if (realThis->fNAMETable != NULL) {
+ realThis->fNameCount = SWAPW(realThis->fNAMETable->count);
+ realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset);
+ }
+ }
+
+ for(le_int32 i = 0; i < fNameCount; i += 1) {
+ const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
+
+ if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID &&
+ SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
+ LEUnicode16 *name = (LEUnicode16 *) (((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset));
+ le_uint16 length = SWAPW(nameRecord->length) / 2;
+ LEUnicode16 *result = LE_NEW_ARRAY(LEUnicode16, length + 2);
+
+ for (le_int32 c = 0; c < length; c += 1) {
+ result[c] = SWAPW(name[c]);
+ }
+
+ result[length] = 0;
+
+ return result;
+ }
+ }
+
+ return NULL;
+}
+
+void PortableFontInstance::deleteNameString(const char *name) const
+{
+ LE_DELETE_ARRAY(name);
+}
+
+void PortableFontInstance::deleteNameString(const LEUnicode16 *name) const
+{
+ LE_DELETE_ARRAY(name);
+}
+
+void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
+{
+ TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
+
+ if (fHMTXTable == NULL) {
+ LETag maxpTag = LE_MAXP_TABLE_TAG;
+ LETag hmtxTag = LE_HMTX_TABLE_TAG;
+ const MAXPTable *maxpTable = (MAXPTable *) readFontTable(maxpTag);
+ PortableFontInstance *realThis = (PortableFontInstance *) this;
+
+ if (maxpTable != NULL) {
+ realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs);
+ freeFontTable(maxpTable);
+ }
+
+ realThis->fHMTXTable = (const HMTXTable *) readFontTable(hmtxTag);
+ }
+
+ le_uint16 index = ttGlyph;
+
+ if (ttGlyph >= fNumGlyphs || fHMTXTable == NULL) {
+ advance.fX = advance.fY = 0;
+ return;
+ }
+
+ if (ttGlyph >= fNumLongHorMetrics) {
+ index = fNumLongHorMetrics - 1;
+ }
+
+ advance.fX = xUnitsToPoints(SWAPW(fHMTXTable->hMetrics[index].advanceWidth));
+ advance.fY = 0;
+}
+
+le_bool PortableFontInstance::getGlyphPoint(LEGlyphID /*glyph*/, le_int32 /*pointNumber*/, LEPoint &/*point*/) const
+{
+ return FALSE;
+}
+
+le_int32 PortableFontInstance::getUnitsPerEM() const
+{
+ return fUnitsPerEM;
+}
+
+le_uint32 PortableFontInstance::getFontChecksum() const
+{
+ return fFontChecksum;
+}
+
+le_uint32 PortableFontInstance::getRawChecksum() const
+{
+ // how big is it?
+ // fseek(fFile, 0L, SEEK_END);
+ // long size = ftell(fFile);
+ le_int32 chksum = 0;
+ // now, calculate
+ fseek(fFile, 0L, SEEK_SET);
+ int r;
+ int count =0;
+ while((r = fgetc(fFile)) != EOF) {
+ chksum += r;
+ count ++;
+ }
+ return (le_uint32) chksum; // cast to signed
+}
+
+le_int32 PortableFontInstance::getAscent() const
+{
+ return fAscent;
+}
+
+le_int32 PortableFontInstance::getDescent() const
+{
+ return fDescent;
+}
+
+le_int32 PortableFontInstance::getLeading() const
+{
+ return fLeading;
+}
+
+// We really want to inherit this method from the superclass, but some compilers
+// issue a warning if we don't implement it...
+LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const
+{
+ return LEFontInstance::mapCharToGlyph(ch, mapper, filterZeroWidth);
+}
+
+// We really want to inherit this method from the superclass, but some compilers
+// issue a warning if we don't implement it...
+LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
+{
+ return LEFontInstance::mapCharToGlyph(ch, mapper);
+}
+
+LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch) const
+{
+ return fCMAPMapper->unicodeToGlyph(ch);
+}
+
+float PortableFontInstance::getXPixelsPerEm() const
+{
+ return fPointSize;
+}
+
+float PortableFontInstance::getYPixelsPerEm() const
+{
+ return fPointSize;
+}
+
+float PortableFontInstance::getScaleFactorX() const
+{
+ return 1.0;
+}
+
+float PortableFontInstance::getScaleFactorY() const
+{
+ return 1.0;
+}
--- /dev/null
+
+/*
+ *******************************************************************************
+ *
+ * Copyright (C) 1999-2013, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ *
+ *******************************************************************************
+ * file name: PortableFontInstance.h
+ *
+ * created on: 11/12/1999
+ * created by: Eric R. Mader
+ */
+
+#ifndef __PORTABLEFONTINSTANCE_H
+#define __PORTABLEFONTINSTANCE_H
+
+#include <stdio.h>
+
+#include "layout/LETypes.h"
+#include "layout/LEFontInstance.h"
+
+#include "FontTableCache.h"
+
+#include "sfnt.h"
+#include "cmaps.h"
+
+class PortableFontInstance : public LEFontInstance, protected FontTableCache
+{
+private:
+ FILE *fFile;
+
+ float fPointSize;
+ le_int32 fUnitsPerEM;
+ le_uint32 fFontChecksum;
+ le_int32 fAscent;
+ le_int32 fDescent;
+ le_int32 fLeading;
+
+ const SFNTDirectory *fDirectory;
+ le_uint16 fDirPower;
+ le_uint16 fDirExtra;
+
+ float fDeviceScaleX;
+ float fDeviceScaleY;
+
+ const NAMETable *fNAMETable;
+ le_uint16 fNameCount;
+ le_uint16 fNameStringOffset;
+
+ CMAPMapper *fCMAPMapper;
+
+ const HMTXTable *fHMTXTable;
+ le_uint16 fNumGlyphs;
+ le_uint16 fNumLongHorMetrics;
+
+ static le_int8 highBit(le_int32 value);
+
+ const DirectoryEntry *findTable(LETag tag) const;
+ const void *readTable(LETag tag, le_uint32 *length) const;
+ void getMetrics();
+
+ CMAPMapper *findUnicodeMapper();
+
+protected:
+ const void *readFontTable(LETag tableTag) const { size_t ignored; return readFontTable(tableTag, ignored); }
+ const void *readFontTable(LETag tableTag, size_t &length) const;
+
+public:
+ PortableFontInstance(const char *fileName, float pointSize, LEErrorCode &status);
+
+ virtual ~PortableFontInstance();
+
+ virtual const void *getFontTable(LETag tableTag) const;
+ virtual const void *getFontTable(LETag tableTag, size_t &length) const;
+
+ virtual const char *getNameString(le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language) const;
+
+ virtual const LEUnicode16 *getUnicodeNameString(le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language) const;
+
+ virtual void deleteNameString(const char *name) const;
+
+ virtual void deleteNameString(const LEUnicode16 *name) const;
+
+ virtual le_int32 getUnitsPerEM() const;
+
+ virtual le_uint32 getFontChecksum() const;
+
+ virtual le_uint32 getRawChecksum() const;
+
+ virtual le_int32 getAscent() const;
+
+ virtual le_int32 getDescent() const;
+
+ virtual le_int32 getLeading() const;
+
+ // We really want to inherit this method from the superclass, but some compilers
+ // issue a warning if we don't implement it...
+ virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const;
+
+ // We really want to inherit this method from the superclass, but some compilers
+ // issue a warning if we don't implement it...
+ virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const;
+
+ virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch) const;
+
+ virtual void getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const;
+
+ virtual le_bool getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const;
+
+ float getXPixelsPerEm() const;
+
+ float getYPixelsPerEm() const;
+
+ float getScaleFactorX() const;
+
+ float getScaleFactorY() const;
+
+};
+
+#endif
--- /dev/null
+/*
+ *******************************************************************************
+ *
+ * Copyright (C) 1999-2013, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ *
+ *******************************************************************************
+ * file name: SimpleFontInstance.cpp
+ *
+ * created on: 03/30/2006
+ * created by: Eric R. Mader
+ */
+
+#include "unicode/utypes.h"
+#include "unicode/uchar.h"
+
+#include "layout/LETypes.h"
+#include "layout/LEFontInstance.h"
+
+#include "layout/CanonShaping.h"
+#include "SimpleFontInstance.h"
+
+SimpleFontInstance::SimpleFontInstance(float pointSize, LEErrorCode &status)
+ : fPointSize(pointSize), fAscent(0), fDescent(0)
+{
+ if (LE_FAILURE(status)) {
+ return;
+ }
+
+ fAscent = (le_int32) yUnitsToPoints(2000.0);
+ fDescent = (le_int32) yUnitsToPoints(600.0);
+
+ return;
+}
+
+SimpleFontInstance::~SimpleFontInstance()
+{
+ // nothing to do...
+}
+
+const void *SimpleFontInstance::getFontTable(LETag tableTag) const
+{
+ if (tableTag == LE_GSUB_TABLE_TAG) {
+ return CanonShaping::glyphSubstitutionTable;
+ }
+
+ if (tableTag == LE_GDEF_TABLE_TAG) {
+ return CanonShaping::glyphDefinitionTable;
+ }
+
+ return NULL;
+}
+
+void SimpleFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
+{
+#if 0
+ if (u_getCombiningClass((UChar32) glyph) == 0) {
+ advance.fX = xUnitsToPoints(2048);
+ } else {
+ advance.fX = 0;
+ }
+#else
+ advance.fX = xUnitsToPoints(2048);
+#endif
+
+ advance.fY = 0;
+}
+
+le_int32 SimpleFontInstance::getUnitsPerEM() const
+{
+ return 2048;
+}
+
+le_int32 SimpleFontInstance::getAscent() const
+{
+ return fAscent;
+}
+
+le_int32 SimpleFontInstance::getDescent() const
+{
+ return fDescent;
+}
+
+le_int32 SimpleFontInstance::getLeading() const
+{
+ return 0;
+}
+
+// We really want to inherit this method from the superclass, but some compilers
+// issue a warning if we don't implement it...
+LEGlyphID SimpleFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const
+{
+ return LEFontInstance::mapCharToGlyph(ch, mapper, filterZeroWidth);
+}
+
+// We really want to inherit this method from the superclass, but some compilers
+// issue a warning if we don't implement it...
+LEGlyphID SimpleFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
+{
+ return LEFontInstance::mapCharToGlyph(ch, mapper);
+}
+
+LEGlyphID SimpleFontInstance::mapCharToGlyph(LEUnicode32 ch) const
+{
+ return (LEGlyphID) ch;
+}
+
+float SimpleFontInstance::getXPixelsPerEm() const
+{
+ return fPointSize;
+}
+
+float SimpleFontInstance::getYPixelsPerEm() const
+{
+ return fPointSize;
+}
+
+float SimpleFontInstance::getScaleFactorX() const
+{
+ return 1.0;
+}
+
+float SimpleFontInstance::getScaleFactorY() const
+{
+ return 1.0;
+}
+
+le_bool SimpleFontInstance::getGlyphPoint(LEGlyphID /*glyph*/, le_int32 /*pointNumber*/, LEPoint &/*point*/) const
+{
+ return FALSE;
+}
+
--- /dev/null
+/*
+ *******************************************************************************
+ *
+ * Copyright (C) 1999-2013, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ *
+ *******************************************************************************
+ * file name: SimpleFontInstance.h
+ *
+ * created on: 03/30/2006
+ * created by: Eric R. Mader
+ */
+
+#ifndef __SIMPLEFONTINSTANCE_H
+#define __SIMPLEFONTINSTANCE_H
+
+#include "layout/LETypes.h"
+#include "layout/LEFontInstance.h"
+
+U_NAMESPACE_USE
+
+class SimpleFontInstance : public LEFontInstance
+{
+private:
+ float fPointSize;
+ le_int32 fAscent;
+ le_int32 fDescent;
+
+protected:
+ const void *readFontTable(LETag tableTag) const;
+
+public:
+ SimpleFontInstance(float pointSize, LEErrorCode &status);
+
+ virtual ~SimpleFontInstance();
+
+ virtual const void *getFontTable(LETag tableTag) const;
+
+ virtual le_int32 getUnitsPerEM() const;
+
+ virtual le_int32 getAscent() const;
+
+ virtual le_int32 getDescent() const;
+
+ virtual le_int32 getLeading() const;
+
+ // We really want to inherit this method from the superclass, but some compilers
+ // issue a warning if we don't implement it...
+ virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const;
+
+ // We really want to inherit this method from the superclass, but some compilers
+ // issue a warning if we don't implement it...
+ virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const;
+
+ virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch) const;
+
+ virtual void getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const;
+
+ virtual le_bool getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const;
+
+ float getXPixelsPerEm() const;
+
+ float getYPixelsPerEm() const;
+
+ float getScaleFactorX() const;
+
+ float getScaleFactorY() const;
+
+};
+
+#endif
--- /dev/null
+/*
+ *
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "loengine.h"
+#include "PortableFontInstance.h"
+#include "SimpleFontInstance.h"
+
+U_CDECL_BEGIN
+
+le_font *le_portableFontOpen(const char *fileName,
+ float pointSize,
+ LEErrorCode *status)
+{
+ return (le_font *) new PortableFontInstance(fileName, pointSize, *status);
+}
+
+le_font *le_simpleFontOpen(float pointSize,
+ LEErrorCode *status)
+{
+ return (le_font *) new SimpleFontInstance(pointSize, *status);
+}
+
+void le_fontClose(le_font *font)
+{
+ LEFontInstance *fontInstance = (LEFontInstance *) font;
+
+ delete fontInstance;
+}
+
+const char *le_getNameString(le_font *font, le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language)
+{
+ PortableFontInstance *pfi = (PortableFontInstance *) font;
+
+ return pfi->getNameString(nameID, platform, encoding, language);
+}
+
+const LEUnicode16 *le_getUnicodeNameString(le_font *font, le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language)
+{
+ PortableFontInstance *pfi = (PortableFontInstance *) font;
+
+ return pfi->getUnicodeNameString(nameID, platform, encoding, language);
+}
+
+void le_deleteNameString(le_font *font, const char *name)
+{
+ PortableFontInstance *pfi = (PortableFontInstance *) font;
+
+ pfi->deleteNameString(name);
+}
+
+void le_deleteUnicodeNameString(le_font *font, const LEUnicode16 *name)
+{
+ PortableFontInstance *pfi = (PortableFontInstance *) font;
+
+ pfi->deleteNameString(name);
+}
+
+le_uint32 le_getFontChecksum(le_font *font)
+{
+ PortableFontInstance *pfi = (PortableFontInstance *) font;
+
+ return pfi->getFontChecksum();
+}
+
+U_CDECL_END
--- /dev/null
+/*
+ *
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __CFONTS_H
+#define __CFONTS_H
+
+#include "LETypes.h"
+#include "loengine.h"
+
+le_font *le_portableFontOpen(const char *fileName,
+ float pointSize,
+ LEErrorCode *status);
+
+le_font *le_simpleFontOpen(float pointSize,
+ LEErrorCode *status);
+
+void le_fontClose(le_font *font);
+
+const char *le_getNameString(le_font *font, le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language);
+
+const LEUnicode16 *le_getUnicodeNameString(le_font *font, le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language);
+
+void le_deleteNameString(le_font *font, const char *name);
+
+void le_deleteUnicodeNameString(le_font *font, const LEUnicode16 *name);
+
+le_uint32 le_getFontChecksum(le_font *font);
+
+#endif
--- /dev/null
+/***************************************************************************
+*
+* Copyright (C) 1998-2013, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+************************************************************************/
+
+#include "layout/LETypes.h"
+#include "layout/LESwaps.h"
+
+#include "sfnt.h"
+#include "cmaps.h"
+#include <stdio.h>
+
+#define SWAPU16(code) ((LEUnicode16) SWAPW(code))
+#define SWAPU32(code) ((LEUnicode32) SWAPL(code))
+
+//
+// Finds the high bit by binary searching
+// through the bits in value.
+//
+le_int8 highBit(le_uint32 value)
+{
+ le_uint8 bit = 0;
+
+ if (value >= 1 << 16) {
+ value >>= 16;
+ bit += 16;
+ }
+
+ if (value >= 1 << 8) {
+ value >>= 8;
+ bit += 8;
+ }
+
+ if (value >= 1 << 4) {
+ value >>= 4;
+ bit += 4;
+ }
+
+ if (value >= 1 << 2) {
+ value >>= 2;
+ bit += 2;
+ }
+
+ if (value >= 1 << 1) {
+ value >>= 1;
+ bit += 1;
+ }
+
+ return bit;
+}
+
+CMAPMapper *CMAPMapper::createUnicodeMapper(const CMAPTable *cmap)
+{
+ le_uint16 i;
+ le_uint16 nSubtables = SWAPW(cmap->numberSubtables);
+ const CMAPEncodingSubtable *subtable = NULL;
+ le_bool found = FALSE;
+ le_uint16 foundPlatformID = 0xFFFF;
+ le_uint16 foundPlatformSpecificID = 0xFFFF;
+ le_uint32 foundOffset = 0;
+ le_uint16 foundTable = 0xFFFF;
+ // first pass, look for MS table. (preferred?)
+ for (i = 0; i < nSubtables && !found; i += 1) {
+ const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i];
+
+ le_uint16 platformID = SWAPW(esh->platformID);
+ le_uint16 platformSpecificID = SWAPW(esh->platformSpecificID);
+ if (platformID == 3) { // microsoft
+ switch (platformSpecificID) {
+ case 1: // Unicode BMP (UCS-2)
+ case 10: // Unicode UCS-4
+ foundOffset = SWAPL(esh->encodingOffset);
+ foundPlatformID = platformID;
+ foundPlatformSpecificID = platformSpecificID;
+ found = TRUE;
+ foundTable = i;
+ break;
+
+ //default:
+ // printf("%s:%d: microsoft (3) platform specific ID %d (wanted 1 or 10) for subtable %d/%d\n", __FILE__, __LINE__, (SWAPW(esh->platformSpecificID)), i, nSubtables);
+ }
+ } else {
+ //printf("%s:%d: platform ID %d (wanted 3, microsoft) for subtable %d/%d\n", __FILE__, __LINE__, (SWAPW(esh->platformID)), i, nSubtables);
+ }
+ }
+
+ // second pass, allow non MS table
+ // first pass, look for MS table. (preferred?)
+ for (i = 0; i < nSubtables && !found; i += 1) {
+ const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i];
+ le_uint16 platformID = SWAPW(esh->platformID);
+ le_uint16 platformSpecificID = SWAPW(esh->platformSpecificID);
+ //printf("%s:%d: table %d/%d has platform:specific %d:%d\n", __FILE__, __LINE__, i, nSubtables, platformID, platformSpecificID);
+ switch(platformID) {
+ case 0: // Unicode platform
+ switch(platformSpecificID) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ foundOffset = SWAPL(esh->encodingOffset);
+ foundPlatformID = platformID;
+ foundPlatformSpecificID = platformSpecificID;
+ foundTable = i;
+ found = TRUE;
+ break;
+
+ default: printf("Error: table %d (psid %d) is unknown. Skipping.\n", i, platformSpecificID); break;
+ }
+ break;
+
+ //default:
+ //printf("Skipping platform id %d\n", platformID);
+ }
+ }
+
+
+ if (found)
+ {
+ subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + foundOffset);
+ //printf("%s:%d: using subtable #%d/%d type %d:%d\n", __FILE__, __LINE__, foundTable, nSubtables, foundPlatformID, foundPlatformSpecificID);
+ } else {
+ printf("%s:%d: could not find subtable.\n", __FILE__, __LINE__);
+ return NULL;
+ }
+
+ le_uint16 tableFormat = SWAPW(subtable->format);
+ //printf("%s:%d: table format %d\n", __FILE__, __LINE__, tableFormat);
+
+ switch (tableFormat) {
+ case 4:
+ return new CMAPFormat4Mapper(cmap, (const CMAPFormat4Encoding *) subtable);
+
+ case 12:
+ {
+ const CMAPFormat12Encoding *encoding = (const CMAPFormat12Encoding *) subtable;
+
+ return new CMAPGroupMapper(cmap, encoding->groups, SWAPL(encoding->nGroups));
+ }
+
+ default:
+ break;
+ }
+
+ printf("%s:%d: Unknown format %x.\n", __FILE__, __LINE__, (SWAPW(subtable->format)));
+ return NULL;
+}
+
+CMAPFormat4Mapper::CMAPFormat4Mapper(const CMAPTable *cmap, const CMAPFormat4Encoding *header)
+ : CMAPMapper(cmap)
+{
+ le_uint16 segCount = SWAPW(header->segCountX2) / 2;
+
+ fEntrySelector = SWAPW(header->entrySelector);
+ fRangeShift = SWAPW(header->rangeShift) / 2;
+ fEndCodes = &header->endCodes[0];
+ fStartCodes = &header->endCodes[segCount + 1]; // + 1 for reservedPad...
+ fIdDelta = &fStartCodes[segCount];
+ fIdRangeOffset = &fIdDelta[segCount];
+}
+
+LEGlyphID CMAPFormat4Mapper::unicodeToGlyph(LEUnicode32 unicode32) const
+{
+ if (unicode32 >= 0x10000) {
+ return 0;
+ }
+
+ LEUnicode16 unicode = (LEUnicode16) unicode32;
+ le_uint16 index = 0;
+ le_uint16 probe = 1 << fEntrySelector;
+ TTGlyphID result = 0;
+
+ if (SWAPU16(fStartCodes[fRangeShift]) <= unicode) {
+ index = fRangeShift;
+ }
+
+ while (probe > (1 << 0)) {
+ probe >>= 1;
+
+ if (SWAPU16(fStartCodes[index + probe]) <= unicode) {
+ index += probe;
+ }
+ }
+
+ if (unicode >= SWAPU16(fStartCodes[index]) && unicode <= SWAPU16(fEndCodes[index])) {
+ if (fIdRangeOffset[index] == 0) {
+ result = (TTGlyphID) unicode;
+ } else {
+ le_uint16 offset = unicode - SWAPU16(fStartCodes[index]);
+ le_uint16 rangeOffset = SWAPW(fIdRangeOffset[index]);
+ le_uint16 *glyphIndexTable = (le_uint16 *) ((char *) &fIdRangeOffset[index] + rangeOffset);
+
+ result = SWAPW(glyphIndexTable[offset]);
+ }
+
+ result += SWAPW(fIdDelta[index]);
+ } else {
+ result = 0;
+ }
+
+ return LE_SET_GLYPH(0, result);
+}
+
+CMAPFormat4Mapper::~CMAPFormat4Mapper()
+{
+ // parent destructor does it all
+}
+
+CMAPGroupMapper::CMAPGroupMapper(const CMAPTable *cmap, const CMAPGroup *groups, le_uint32 nGroups)
+ : CMAPMapper(cmap), fGroups(groups)
+{
+ le_uint8 bit = highBit(nGroups);
+ fPower = 1 << bit;
+ fRangeOffset = nGroups - fPower;
+}
+
+LEGlyphID CMAPGroupMapper::unicodeToGlyph(LEUnicode32 unicode32) const
+{
+ le_int32 probe = fPower;
+ le_int32 range = 0;
+
+ if (SWAPU32(fGroups[fRangeOffset].startCharCode) <= unicode32) {
+ range = fRangeOffset;
+ }
+
+ while (probe > (1 << 0)) {
+ probe >>= 1;
+
+ if (SWAPU32(fGroups[range + probe].startCharCode) <= unicode32) {
+ range += probe;
+ }
+ }
+
+ if (SWAPU32(fGroups[range].startCharCode) <= unicode32 && SWAPU32(fGroups[range].endCharCode) >= unicode32) {
+ return (LEGlyphID) (SWAPU32(fGroups[range].startGlyphCode) + unicode32 - SWAPU32(fGroups[range].startCharCode));
+ }
+
+ return 0;
+}
+
+CMAPGroupMapper::~CMAPGroupMapper()
+{
+ // parent destructor does it all
+}
+
--- /dev/null
+/***************************************************************************
+*
+* Copyright (C) 1998-2013, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+************************************************************************/
+
+
+#ifndef __CMAPS_H
+#define __CMAPS_H
+
+#include "layout/LETypes.h"
+//#include "letest.h"
+#include "sfnt.h"
+
+class CMAPMapper
+{
+public:
+ virtual LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const = 0;
+
+ virtual ~CMAPMapper();
+
+ static CMAPMapper *createUnicodeMapper(const CMAPTable *cmap);
+
+protected:
+ CMAPMapper(const CMAPTable *cmap);
+
+ CMAPMapper() {};
+
+private:
+ const CMAPTable *fcmap;
+};
+
+class CMAPFormat4Mapper : public CMAPMapper
+{
+public:
+ CMAPFormat4Mapper(const CMAPTable *cmap, const CMAPFormat4Encoding *header);
+
+ virtual ~CMAPFormat4Mapper();
+
+ virtual LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const;
+
+protected:
+ CMAPFormat4Mapper() {};
+
+private:
+ le_uint16 fEntrySelector;
+ le_uint16 fRangeShift;
+ const le_uint16 *fEndCodes;
+ const le_uint16 *fStartCodes;
+ const le_uint16 *fIdDelta;
+ const le_uint16 *fIdRangeOffset;
+};
+
+class CMAPGroupMapper : public CMAPMapper
+{
+public:
+ CMAPGroupMapper(const CMAPTable *cmap, const CMAPGroup *groups, le_uint32 nGroups);
+
+ virtual ~CMAPGroupMapper();
+
+ virtual LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const;
+
+protected:
+ CMAPGroupMapper() {};
+
+private:
+ le_int32 fPower;
+ le_int32 fRangeOffset;
+ const CMAPGroup *fGroups;
+};
+
+inline CMAPMapper::CMAPMapper(const CMAPTable *cmap)
+ : fcmap(cmap)
+{
+ // nothing else to do
+}
+
+inline CMAPMapper::~CMAPMapper()
+{
+ LE_DELETE_ARRAY(fcmap);
+}
+
+#endif
+
--- /dev/null
+/***************************************************************************
+*
+* Copyright (C) 2013, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+************************************************************************/
+
+#include "unicode/utimer.h"
+#include "unicode/ustdio.h"
+#include "layout/LETypes.h"
+#include "layout/LayoutEngine.h"
+#include "layout/LEScripts.h"
+#include "SimpleFontInstance.h"
+#include "PortableFontInstance.h"
+
+class Params {
+public:
+ LEFontInstance *font;
+ LEUnicode *chars;
+ le_int32 charLen;
+ ScriptCodes script;
+ le_int32 glyphCount;
+};
+
+LEUnicode ArabChars[] = {
+ 0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068, 0x0020, // "English "
+ 0x0645, 0x0627, 0x0646, 0x062A, 0x0648, 0x0634, // MEM ALIF KAF NOON TEH WAW SHEEN
+ 0x0020, 0x0074, 0x0065, 0x0078, 0x0074, 0x02E, 0 // " text."
+ };
+
+void iterate(void * p) {
+ Params* params = (Params*) p;
+
+ LEErrorCode status = LE_NO_ERROR;
+ LEFontInstance *font = params->font;
+ LayoutEngine *engine = LayoutEngine::layoutEngineFactory(font, params->script, -1, status);
+ LEGlyphID *glyphs = NULL;
+ le_int32 *indices = NULL;
+ float *positions = NULL;
+ le_int32 glyphCount = 0;
+ LEUnicode *chars = params->chars;
+ glyphCount = engine->layoutChars(chars, 0, params->charLen, params->charLen, TRUE, 0.0, 0.0, status);
+ glyphs = LE_NEW_ARRAY(LEGlyphID, glyphCount + 10);
+ indices = LE_NEW_ARRAY(le_int32, glyphCount + 10);
+ positions = LE_NEW_ARRAY(float, glyphCount + 10);
+ engine->getGlyphs(glyphs, status);
+ params->glyphCount = glyphCount;
+
+
+ delete glyphs;
+ delete indices;
+ delete positions;
+ delete engine;
+ //delete font;
+}
+
+int main(int argc, const char *argv[]) {
+ double len=10.0;
+ for(int i=1;i<argc;i++) {
+ puts("arg:");
+ puts(argv[i]);
+ if(argv[i][0]=='p') {
+ printf("hit enter-pid=%d", getpid());
+ getchar();
+ } else if(argv[i][0]>='0' && argv[i][0]<='9') {
+ len = (1.0)*(argv[i][0]-'0');
+ }
+ }
+ u_printf("leperf: Testing %s for %.fs...\n", U_ICU_VERSION, len);
+ LEErrorCode status = LE_NO_ERROR;
+ //uloc_setDefault("en_US", &status);
+ Params p;
+
+#if 0
+ p.script = arabScriptCode;
+ p.chars = ArabChars;
+ p.charLen = sizeof(ArabChars)/sizeof(ArabChars[0]);
+#else
+ p.script = latnScriptCode;
+ p.chars = new LEUnicode[257];
+ for(int i=0;i<256;i++) {
+ p.chars[i] = i+1;
+ }
+ p.chars[256] = 0;
+ p.charLen = 256;
+#endif
+
+ int32_t loopCount;
+ double timeTaken;
+ double timeNs;
+#if 0
+ p.font = new SimpleFontInstance(12, status);
+ u_printf("leperf: Running SFI...\r");
+ timeTaken = utimer_loopUntilDone(len, &loopCount, iterate, &p);
+ u_printf("leperf: SFI .. took %.fs %.2fns/ea\nleperf: .. iter= %d\n", timeTaken, 1000000000.0*(timeTaken/(double)loopCount), (int32_t)loopCount);
+ delete p.font;
+#endif
+ PortableFontInstance *font;
+ LEErrorCode fontStatus = LE_NO_ERROR;
+ const char *fontPath = "myfont.ttf";
+
+ font = new PortableFontInstance(fontPath, 12, fontStatus);
+
+ p.font = font;
+ loopCount=0;
+ u_printf("leperf: testing %s\n", fontPath);
+ u_printf("leperf: Running ...\r");
+ timeTaken = utimer_loopUntilDone(len, &loopCount, iterate, &p);
+ timeNs = 1000000000.0*(timeTaken/(double)loopCount);
+ u_printf("leperf: PFI .. took %.fs %.2fns/ea\nleperf: .. iter= %d\n", timeTaken, timeNs, (int32_t)loopCount);
+ u_printf("leperf: DATA|\"%s\"|%.2f|\n", U_ICU_VERSION, timeNs);
+ u_printf("leperf: glyphs=%d\n", p.glyphCount);
+ return 0;
+}
+
+// hack - #include these for easier build.
+#include "SimpleFontInstance.cpp"
+#include "PortableFontInstance.cpp"
+#include "cmaps.cpp"
+#include "FontTableCache.cpp"
--- /dev/null
+/***************************************************************************
+*
+* Copyright (C) 2013, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+************************************************************************/
+/**
+ * Usage:
+ * build against a configured (but not built) ICU.
+ * example: cc -O2 test_LETableReference.cpp -I. -I/xsrl/II/include -I/xsrl/E/icu/source/tools/ctestfw
+ */
+#include "unicode/utimer.h"
+#include "LETableReference.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ITEM_COUNT 10000
+
+long *items = 0;
+
+struct OneObject {
+ long items[ITEM_COUNT];
+};
+
+struct Long {
+ long v;
+};
+
+struct CompObject {
+ Long items[ITEM_COUNT];
+};
+
+
+void time_null(void * /*ref*/) {
+ for(int i=0;i<ITEM_COUNT;i++) {
+ if(items[i]==2) {
+ return;
+ }
+ }
+ puts("error");
+ abort();
+}
+
+void time_obj(void * ref) {
+ OneObject &obj = *((OneObject*)ref);
+ for(int i=0;i<ITEM_COUNT;i++) {
+ if(obj.items[i]==2) {
+ return;
+ }
+ }
+ puts("error");
+ abort();
+}
+void time_obj2(void * ref) {
+ long *items2 = ((OneObject*)ref)->items;
+ for(int i=0;i<ITEM_COUNT;i++) {
+ if(items2[i]==2) {
+ return;
+ }
+ }
+ puts("error");
+ abort();
+}
+
+void time_letr1(void * ref) {
+ OneObject &obj = *((OneObject*)ref);
+ LETableReference data((const le_uint8*)ref, sizeof(OneObject));
+ LEErrorCode success = LE_NO_ERROR;
+
+ LEReferenceTo<OneObject> stuff(data, success);
+ if(LE_FAILURE(success)) {
+ puts("failure");
+ abort();
+ }
+ long *items2 = ((OneObject*)ref)->items;
+ for(int i=0;i<ITEM_COUNT;i++) {
+ if(items[i]==2) {
+ return;
+ }
+ }
+ puts("error");
+ abort();
+}
+
+
+void time_letr2(void * ref) {
+ OneObject &obj = *((OneObject*)ref);
+ LETableReference data((const le_uint8*)ref, sizeof(OneObject));
+ LEErrorCode success = LE_NO_ERROR;
+
+ long *items2 = ((OneObject*)ref)->items;
+ for(int i=0;i<ITEM_COUNT;i++) {
+ LEReferenceTo<OneObject> stuff(data, success);
+ if(LE_FAILURE(success)) {
+ puts("failure");
+ abort();
+ }
+ if(items[i]==2) {
+ return;
+ }
+ }
+ puts("error");
+ abort();
+}
+
+static void time_letr3(void * ref) {
+ LETableReference data((const le_uint8*)ref, sizeof(OneObject));
+ LEErrorCode success = LE_NO_ERROR;
+ LEReferenceTo<CompObject> comp(data, success);
+ LEReferenceToArrayOf<Long> longs(comp, success, (size_t)0, ITEM_COUNT);
+ if(LE_FAILURE(success)) {
+ puts("failure");
+ abort();
+ }
+
+ for(int i=0;i<ITEM_COUNT;i++) {
+ const Long &item = longs.getObject(i, success);
+ if(LE_FAILURE(success)) {
+ puts("failure");
+ abort();
+ }
+ if(item.v==2) {
+ return;
+ }
+ }
+ puts("error");
+ abort();
+}
+
+
+int main() {
+ double runTime = 2.0;
+ printf("Test of LETableReference<> timing. %.1fs per run.\n", runTime);
+ items = new long[ITEM_COUNT];
+ OneObject *oo = new OneObject();
+ CompObject *oo2 = new CompObject();
+ for(int i=0;i<ITEM_COUNT-1;i++) {
+ items[i] = oo->items[i] = oo2->items[i].v = (i%1024)+3;
+ }
+ items[ITEM_COUNT-1] = oo->items[ITEM_COUNT-1] = oo2->items[ITEM_COUNT-1].v = 2; // last one
+
+ puts("will call once..");
+ time_letr3((void*)oo2);
+ puts("testing all..");
+
+ int32_t loopCount;
+ double time_taken;
+
+#define showTime(x,y) printf("%s:\ttesting...\r", #x); fflush(stdout); \
+ time_taken = utimer_loopUntilDone(runTime, &loopCount, x, y); \
+ printf("%s:\t%.1fs\t#%d\t%.1f/s\n", #x, time_taken, loopCount, loopCount/(double)time_taken);
+
+ // clear out cache
+ {
+ double oldTime = runTime;
+ runTime = 0.25;
+ showTime(time_null, NULL);
+ showTime(time_null, NULL);
+ showTime(time_null, NULL);
+ showTime(time_null, NULL);
+ runTime = oldTime;
+ }
+ puts("-- ready to start --");
+
+
+ showTime(time_null, NULL);
+ showTime(time_obj, (void*)oo);
+ showTime(time_obj2, (void*)oo);
+ showTime(time_letr1, (void*)oo2);
+ showTime(time_letr2, (void*)oo2);
+ showTime(time_letr3, (void*)oo2);
+ showTime(time_null, NULL);
+
+ delete [] items;
+ delete oo;
+ delete oo2;
+}
--- /dev/null
+/***************************************************************************
+*
+* Copyright (C) 1998-2013, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+************************************************************************/
+
+#ifndef __SFNT_H
+#define __SFNT_H
+
+#include "layout/LETypes.h"
+
+U_NAMESPACE_USE
+
+#ifndef ANY_NUMBER
+#define ANY_NUMBER 1
+#endif
+
+struct DirectoryEntry
+{
+ le_uint32 tag;
+ le_uint32 checksum;
+ le_uint32 offset;
+ le_uint32 length;
+};
+
+#ifndef __cplusplus
+typedef struct DirectoryEntry DirectoryEntry;
+#endif
+
+struct SFNTDirectory
+{
+ le_uint32 scalerType;
+ le_uint16 numTables;
+ le_uint16 searchRange;
+ le_uint16 entrySelector;
+ le_uint16 rangeShift;
+ DirectoryEntry tableDirectory[ANY_NUMBER];
+};
+
+#ifndef __cplusplus
+typedef struct SFNTDirectory SFNTDirectory;
+#endif
+
+
+struct CMAPEncodingSubtableHeader
+{
+ le_uint16 platformID;
+ le_uint16 platformSpecificID;
+ le_uint32 encodingOffset;
+};
+
+#ifndef __cplusplus
+typedef struct CMAPEncodingSubtableHeader CMAPEncodingSubtableHeader;
+#endif
+
+struct CMAPTable
+{
+ le_uint16 version;
+ le_uint16 numberSubtables;
+ CMAPEncodingSubtableHeader encodingSubtableHeaders[ANY_NUMBER];
+};
+
+#ifndef __cplusplus
+typedef struct CMAPTable CMAPTable;
+#endif
+
+struct CMAPEncodingSubtable
+{
+ le_uint16 format;
+ le_uint16 length;
+ le_uint16 language;
+};
+
+#ifndef __cplusplus
+typedef struct CMAPEncodingSubtable CMAPEncodingSubtable;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat0Encoding : CMAPEncodingSubtable
+{
+ le_uint8 glyphIndexArray[256];
+};
+#else
+struct CMAPFormat0Encoding
+{
+ CMAPEncodingSubtable base;
+
+ le_uint8 glyphIndexArray[256];
+};
+
+typedef struct CMAPFormat0Encoding CMAPFormat0Encoding;
+#endif
+
+struct CMAPFormat2Subheader
+{
+ le_uint16 firstCode;
+ le_uint16 entryCount;
+ le_int16 idDelta;
+ le_uint16 idRangeOffset;
+};
+
+#ifndef __cplusplus
+typedef struct CMAPFormat2Subheader CMAPFormat2Subheader;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat2Encoding : CMAPEncodingSubtable
+{
+ le_uint16 subHeadKeys[256];
+ CMAPFormat2Subheader subheaders[ANY_NUMBER];
+};
+#else
+struct CMAPFormat2Encoding
+{
+ CMAPEncodingSubtable base;
+
+ le_uint16 subHeadKeys[256];
+ CMAPFormat2Subheader subheaders[ANY_NUMBER];
+};
+
+typedef struct CMAPFormat2Encoding CMAPFormat2Encoding;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat4Encoding : CMAPEncodingSubtable
+{
+ le_uint16 segCountX2;
+ le_uint16 searchRange;
+ le_uint16 entrySelector;
+ le_uint16 rangeShift;
+ le_uint16 endCodes[ANY_NUMBER];
+/*
+ le_uint16 reservedPad;
+ le_uint16 startCodes[ANY_NUMBER];
+ le_uint16 idDelta[ANY_NUMBER];
+ le_uint16 idRangeOffset[ANY_NUMBER];
+ le_uint16 glyphIndexArray[ANY_NUMBER];
+*/
+};
+#else
+struct CMAPFormat4Encoding
+{
+ CMAPEncodingSubtable base;
+
+ le_uint16 segCountX2;
+ le_uint16 searchRange;
+ le_uint16 entrySelector;
+ le_uint16 rangeShift;
+ le_uint16 endCodes[ANY_NUMBER];
+/*
+// le_uint16 reservedPad;
+// le_uint16 startCodes[ANY_NUMBER];
+// le_uint16 idDelta[ANY_NUMBER];
+// le_uint16 idRangeOffset[ANY_NUMBER];
+// le_uint16 glyphIndexArray[ANY_NUMBER];
+*/
+};
+
+typedef struct CMAPFormat4Encoding CMAPFormat4Encoding;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat6Encoding : CMAPEncodingSubtable
+{
+ le_uint16 firstCode;
+ le_uint16 entryCount;
+ le_uint16 glyphIndexArray[ANY_NUMBER];
+};
+#else
+struct CMAPFormat6Encoding
+{
+ CMAPEncodingSubtable base;
+
+ le_uint16 firstCode;
+ le_uint16 entryCount;
+ le_uint16 glyphIndexArray[ANY_NUMBER];
+};
+
+typedef struct CMAPFormat6Encoding CMAPFormat6Encoding;
+#endif
+
+struct CMAPEncodingSubtable32
+{
+ le_uint32 format;
+ le_uint32 length;
+ le_uint32 language;
+};
+
+#ifndef __cplusplus
+typedef struct CMAPEncodingSubtable32 CMAPEncodingSubtable32;
+#endif
+
+struct CMAPGroup
+{
+ le_uint32 startCharCode;
+ le_uint32 endCharCode;
+ le_uint32 startGlyphCode;
+};
+
+#ifndef __cplusplus
+typedef struct CMAPGroup CMAPGroup;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat8Encoding : CMAPEncodingSubtable32
+{
+ le_uint32 is32[65536/32];
+ le_uint32 nGroups;
+ CMAPGroup groups[ANY_NUMBER];
+};
+#else
+struct CMAPFormat8Encoding
+{
+ CMAPEncodingSubtable32 base;
+
+ le_uint32 is32[65536/32];
+ le_uint32 nGroups;
+ CMAPGroup groups[ANY_NUMBER];
+};
+
+typedef struct CMAPFormat8Encoding CMAPFormat8Encoding;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat10Encoding : CMAPEncodingSubtable32
+{
+ le_uint32 startCharCode;
+ le_uint32 numCharCodes;
+ le_uint16 glyphs[ANY_NUMBER];
+};
+#else
+struct CMAPFormat10Encoding
+{
+ CMAPEncodingSubtable32 base;
+
+ le_uint32 startCharCode;
+ le_uint32 numCharCodes;
+ le_uint16 glyphs[ANY_NUMBER];
+};
+
+typedef struct CMAPFormat10Encoding CMAPFormat10Encoding;
+#endif
+
+#ifdef __cplusplus
+struct CMAPFormat12Encoding : CMAPEncodingSubtable32
+{
+ le_uint32 nGroups;
+ CMAPGroup groups[ANY_NUMBER];
+};
+#else
+struct CMAPFormat12Encoding
+{
+ CMAPEncodingSubtable32 base;
+
+ le_uint32 nGroups;
+ CMAPGroup groups[ANY_NUMBER];
+};
+
+typedef struct CMAPFormat12Encoding CMAPFormat12Encoding;
+#endif
+
+typedef le_int32 fixed;
+
+struct BigDate
+{
+ le_uint32 bc;
+ le_uint32 ad;
+};
+
+#ifndef __cplusplus
+typedef struct BigDate BigDate;
+#endif
+
+struct HEADTable
+{
+ fixed version;
+ fixed fontRevision;
+ le_uint32 checksumAdjustment;
+ le_uint32 magicNumber;
+ le_uint16 flags;
+ le_uint16 unitsPerEm;
+ BigDate created;
+ BigDate modified;
+ le_int16 xMin;
+ le_int16 yMin;
+ le_int16 xMax;
+ le_int16 yMax;
+ le_int16 lowestRecPPEM;
+ le_int16 fontDirectionHint;
+ le_int16 indexToLocFormat;
+ le_int16 glyphDataFormat;
+};
+
+#ifndef __cplusplus
+typedef struct HEADTable HEADTable;
+#endif
+
+struct MAXPTable
+{
+ fixed version;
+ le_uint16 numGlyphs;
+ le_uint16 maxPoints;
+ le_uint16 maxContours;
+ le_uint16 maxComponentPoints;
+ le_uint16 maxComponentContours;
+ le_uint16 maxZones;
+ le_uint16 maxTwilightPoints;
+ le_uint16 maxStorage;
+ le_uint16 maxFunctionDefs;
+ le_uint16 maxInstructionDefs;
+ le_uint16 maxStackElements;
+ le_uint16 maxSizeOfInstructions;
+ le_uint16 maxComponentElements;
+ le_uint16 maxComponentDepth;
+};
+
+#ifndef __cplusplus
+typedef struct MAXPTable MAXPTable;
+#endif
+
+struct HHEATable
+{
+ fixed version;
+ le_int16 ascent;
+ le_int16 descent;
+ le_int16 lineGap;
+ le_uint16 advanceWidthMax;
+ le_int16 minLeftSideBearing;
+ le_int16 minRightSideBearing;
+ le_int16 xMaxExtent;
+ le_int16 caretSlopeRise;
+ le_int16 caretSlopeRun;
+ le_int16 caretOffset;
+ le_int16 reserved1;
+ le_int16 reserved2;
+ le_int16 reserved3;
+ le_int16 reserved4;
+ le_int16 metricDataFormat;
+ le_uint16 numOfLongHorMetrics;
+};
+
+#ifndef __cplusplus
+typedef struct HHEATable HHEATable;
+#endif
+
+struct LongHorMetric
+{
+ le_uint16 advanceWidth;
+ le_int16 leftSideBearing;
+};
+
+#ifndef __cplusplus
+typedef struct LongHorMetric LongHorMetric;
+#endif
+
+struct HMTXTable
+{
+ LongHorMetric hMetrics[ANY_NUMBER]; /* ANY_NUMBER = numOfLongHorMetrics from hhea table */
+/* le_int16 leftSideBearing[ANY_NUMBER]; ANY_NUMBER = numGlyphs - numOfLongHorMetrics */
+};
+
+#ifndef __cplusplus
+typedef struct HMTXTable HMTXTable;
+#endif
+
+enum PlatformID
+{
+ PLATFORM_UNICODE = 0,
+ PLATFORM_MACINTOSH = 1,
+ PLATFORM_ISO = 2,
+ PLATFORM_MICROSOFT = 3,
+ PLATFORM_CUSTOM = 4
+};
+
+enum MacintoshEncodingID
+{
+ MACINTOSH_ROMAN = 0
+};
+
+enum MacintoshLanguageID
+{
+ MACINTOSH_ENGLISH = 0
+};
+
+enum MicrosoftEncodingID
+{
+ MICROSOFT_UNICODE_BMP = 1,
+ MICROSOFT_UNICODE_FULL = 10
+};
+
+enum MicrosoftLanguageID
+{
+ MICROSOFT_ENGLISH = 0x409
+};
+
+enum NameID
+{
+ NAME_COPYRIGHT_NOTICE = 0,
+ NAME_FONT_FAMILY = 1,
+ NAME_FONT_SUB_FAMILY = 2,
+ NAME_UNIQUE_FONT_ID = 3,
+ NAME_FULL_FONT_NAME = 4,
+ NAME_VERSION_STRING = 5,
+ NAME_POSTSCRIPT_NAME = 6,
+ NAME_TRADEMARK = 7,
+ NAME_MANUFACTURER = 8,
+ NAME_DESIGNER = 9,
+ NAME_DESCRIPTION = 10,
+ NAME_VENDOR_URL = 11,
+ NAME_DESIGNER_URL = 12,
+ NAME_LICENSE_DESCRIPTION = 13,
+ NAME_LICENSE_URL = 14,
+ NAME_RESERVED = 15,
+ NAME_PREFERRED_FAMILY = 16,
+ NAME_PREFERRED_SUB_FAMILY = 17,
+ NAME_COMPATIBLE_FULL = 18,
+ NAME_SAMPLE_TEXT = 19,
+ NAME_POSTSCRIPT_CID = 20
+};
+
+struct NameRecord
+{
+ le_uint16 platformID;
+ le_uint16 encodingID;
+ le_uint16 languageID;
+ le_uint16 nameID;
+ le_uint16 length;
+ le_uint16 offset;
+};
+
+#ifndef __cplusplus
+typedef struct NameRecord NameRecord;
+#endif
+
+struct NAMETable
+{
+ le_uint16 version;
+ le_uint16 count;
+ le_uint16 stringOffset;
+ NameRecord nameRecords[ANY_NUMBER];
+};
+
+#ifndef __cplusplus
+typedef struct NAMETable NAMETable;
+#endif
+
+#endif
+
--- /dev/null
+/*
+ *******************************************************************************
+ *
+ * Copyright (C) 1999-2013, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ *
+ *******************************************************************************
+ */
+
+#include "unicode/utypes.h"
+#include "unicode/uclean.h"
+#include "unicode/uchar.h"
+#include "unicode/unistr.h"
+#include "unicode/uscript.h"
+#include "unicode/putil.h"
+#include "unicode/ctest.h"
+
+#include "layout/LETypes.h"
+#include "layout/LEScripts.h"
+
+#include "letsutil.h"
+#include "letest.h"
+
+#include "xmlreader.h"
+
+#include "xmlparser.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+//U_NAMESPACE_USE
+
+#define CH_COMMA 0x002C
+
+static le_uint32 *getHexArray(const UnicodeString &numbers, int32_t &arraySize)
+{
+ int32_t offset = -1;
+
+ arraySize = 1;
+ while((offset = numbers.indexOf(CH_COMMA, offset + 1)) >= 0) {
+ arraySize += 1;
+ }
+
+ le_uint32 *array = NEW_ARRAY(le_uint32, arraySize);
+ char number[16];
+ le_int32 count = 0;
+ le_int32 start = 0, end = 0;
+ le_int32 len = 0;
+
+ // trim leading whitespace
+ while(u_isUWhiteSpace(numbers[start])) {
+ start += 1;
+ }
+
+ while((end = numbers.indexOf(CH_COMMA, start)) >= 0) {
+ len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
+ number[len] = '\0';
+ start = end + 1;
+
+ sscanf(number, "%x", &array[count++]);
+
+ // trim whitespace following the comma
+ while(u_isUWhiteSpace(numbers[start])) {
+ start += 1;
+ }
+ }
+
+ // trim trailing whitespace
+ end = numbers.length();
+ while(u_isUWhiteSpace(numbers[end - 1])) {
+ end -= 1;
+ }
+
+ len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
+ number[len] = '\0';
+ sscanf(number, "%x", &array[count]);
+
+ return array;
+}
+
+static float *getFloatArray(const UnicodeString &numbers, int32_t &arraySize)
+{
+ int32_t offset = -1;
+
+ arraySize = 1;
+ while((offset = numbers.indexOf(CH_COMMA, offset + 1)) >= 0) {
+ arraySize += 1;
+ }
+
+ float *array = NEW_ARRAY(float, arraySize);
+ char number[32];
+ le_int32 count = 0;
+ le_int32 start = 0, end = 0;
+ le_int32 len = 0;
+
+ // trim leading whitespace
+ while(u_isUWhiteSpace(numbers[start])) {
+ start += 1;
+ }
+
+ while((end = numbers.indexOf(CH_COMMA, start)) >= 0) {
+ len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
+ number[len] = '\0';
+ start = end + 1;
+
+ sscanf(number, "%f", &array[count++]);
+
+ // trim whiteapce following the comma
+ while(u_isUWhiteSpace(numbers[start])) {
+ start += 1;
+ }
+ }
+
+ while(u_isUWhiteSpace(numbers[start])) {
+ start += 1;
+ }
+
+ // trim trailing whitespace
+ end = numbers.length();
+ while(u_isUWhiteSpace(numbers[end - 1])) {
+ end -= 1;
+ }
+
+ len = numbers.extract(start, end - start, number, ARRAY_SIZE(number), US_INV);
+ number[len] = '\0';
+ sscanf(number, "%f", &array[count]);
+
+ return array;
+}
+
+U_CDECL_BEGIN
+void readTestFile(const char *testFilePath, TestCaseCallback callback)
+{
+#if !UCONFIG_NO_REGULAR_EXPRESSIONS
+ UErrorCode status = U_ZERO_ERROR;
+ UXMLParser *parser = UXMLParser::createParser(status);
+ UXMLElement *root = parser->parseFile(testFilePath, status);
+
+ if (root == NULL) {
+ log_err("Could not open the test data file: %s\n", testFilePath);
+ delete parser;
+ return;
+ }
+
+ UnicodeString test_case = UNICODE_STRING_SIMPLE("test-case");
+ UnicodeString test_text = UNICODE_STRING_SIMPLE("test-text");
+ UnicodeString test_font = UNICODE_STRING_SIMPLE("test-font");
+ UnicodeString result_glyphs = UNICODE_STRING_SIMPLE("result-glyphs");
+ UnicodeString result_indices = UNICODE_STRING_SIMPLE("result-indices");
+ UnicodeString result_positions = UNICODE_STRING_SIMPLE("result-positions");
+
+ // test-case attributes
+ UnicodeString id_attr = UNICODE_STRING_SIMPLE("id");
+ UnicodeString script_attr = UNICODE_STRING_SIMPLE("script");
+ UnicodeString lang_attr = UNICODE_STRING_SIMPLE("lang");
+
+ // test-font attributes
+ UnicodeString name_attr = UNICODE_STRING_SIMPLE("name");
+ UnicodeString ver_attr = UNICODE_STRING_SIMPLE("version");
+ UnicodeString cksum_attr = UNICODE_STRING_SIMPLE("checksum");
+
+ const UXMLElement *testCase;
+ int32_t tc = 0;
+
+ while((testCase = root->nextChildElement(tc)) != NULL) {
+ if (testCase->getTagName().compare(test_case) == 0) {
+ char *id = getCString(testCase->getAttribute(id_attr));
+ char *script = getCString(testCase->getAttribute(script_attr));
+ char *lang = getCString(testCase->getAttribute(lang_attr));
+ char *fontName = NULL;
+ char *fontVer = NULL;
+ char *fontCksum = NULL;
+ const UXMLElement *element;
+ int32_t ec = 0;
+ int32_t charCount = 0;
+ int32_t typoFlags = 3; // kerning + ligatures...
+ UScriptCode scriptCode;
+ le_int32 languageCode = -1;
+ UnicodeString text, glyphs, indices, positions;
+ int32_t glyphCount = 0, indexCount = 0, positionCount = 0;
+ TestResult expected = {0, NULL, NULL, NULL};
+
+ uscript_getCode(script, &scriptCode, 1, &status);
+ if (LE_FAILURE(status)) {
+ log_err("invalid script name: %s.\n", script);
+ goto free_c_strings;
+ }
+
+ if (lang != NULL) {
+ languageCode = getLanguageCode(lang);
+
+ if (languageCode < 0) {
+ log_err("invalid language name: %s.\n", lang);
+ goto free_c_strings;
+ }
+ }
+
+ while((element = testCase->nextChildElement(ec)) != NULL) {
+ UnicodeString tag = element->getTagName();
+
+ // TODO: make sure that each element is only used once.
+ if (tag.compare(test_font) == 0) {
+ fontName = getCString(element->getAttribute(name_attr));
+ fontVer = getCString(element->getAttribute(ver_attr));
+ fontCksum = getCString(element->getAttribute(cksum_attr));
+
+ } else if (tag.compare(test_text) == 0) {
+ text = element->getText(TRUE);
+ charCount = text.length();
+ } else if (tag.compare(result_glyphs) == 0) {
+ glyphs = element->getText(TRUE);
+ } else if (tag.compare(result_indices) == 0) {
+ indices = element->getText(TRUE);
+ } else if (tag.compare(result_positions) == 0) {
+ positions = element->getText(TRUE);
+ } else {
+ // an unknown tag...
+ char *cTag = getCString(&tag);
+
+ log_info("Test %s: unknown element with tag \"%s\"\n", id, cTag);
+ freeCString(cTag);
+ }
+ }
+
+ expected.glyphs = (LEGlyphID *) getHexArray(glyphs, glyphCount);
+ expected.indices = (le_int32 *) getHexArray(indices, indexCount);
+ expected.positions = getFloatArray(positions, positionCount);
+
+ expected.glyphCount = glyphCount;
+
+ if (glyphCount < charCount || indexCount != glyphCount || positionCount < glyphCount * 2 + 2) {
+ log_err("Test %s: inconsistent input data: charCount = %d, glyphCount = %d, indexCount = %d, positionCount = %d\n",
+ id, charCount, glyphCount, indexCount, positionCount);
+ goto free_expected;
+ };
+
+ (*callback)(id, fontName, fontVer, fontCksum, scriptCode, languageCode, text.getBuffer(), charCount, &expected);
+
+free_expected:
+ DELETE_ARRAY(expected.positions);
+ DELETE_ARRAY(expected.indices);
+ DELETE_ARRAY(expected.glyphs);
+
+free_c_strings:
+ freeCString(fontCksum);
+ freeCString(fontVer);
+ freeCString(fontName);
+ freeCString(lang);
+ freeCString(script);
+ freeCString(id);
+ }
+ }
+
+ delete root;
+ delete parser;
+#endif
+}
+U_CDECL_END
--- /dev/null
+/*
+ *
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __XMLREADER_H
+#define __XMLREADER_H
+
+#include "LETypes.h"
+#include "letest.h"
+
+typedef void (*TestCaseCallback) (const char *testID,
+ const char *fontName,
+ const char *fontVersion,
+ const char *fontChecksum,
+ le_int32 scriptCode,
+ le_int32 languageCode,
+ const LEUnicode *text,
+ le_int32 charCount,
+ TestResult *expected);
+
+U_CAPI void readTestFile(const char *testFilePath, TestCaseCallback callback);
+
+#endif