ICU-10234 check in layout engine perf test

X-SVN-Rev: 33861
This commit is contained in:
Steven R. Loomis 2013-06-27 17:37:58 +00:00
parent 70fc2d25ba
commit f4d12ea183
20 changed files with 3080 additions and 104 deletions

219
icu4c/source/configure vendored
View file

@ -1,13 +1,11 @@
#! /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
@ -136,6 +134,31 @@ export LANGUAGE
# 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
@ -169,7 +192,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
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'\" &&
@ -214,21 +238,25 @@ IFS=$as_save_IFS
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 :
@ -330,6 +358,14 @@ $as_echo X"$as_dir" |
} # 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
@ -451,6 +487,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
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).
@ -485,16 +525,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... 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
@ -506,28 +546,8 @@ else
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'"
@ -1223,8 +1243,6 @@ target=$target_alias
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
@ -1490,9 +1508,9 @@ test -n "$ac_init_help" && exit $ac_status
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.
@ -1645,7 +1663,7 @@ $as_echo "$ac_try_echo"; } >&5
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
@ -1723,7 +1741,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) >= 0)];
test_array [0] = 0
test_array [0] = 0;
return test_array [0];
;
return 0;
@ -1739,7 +1758,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
test_array [0] = 0
test_array [0] = 0;
return test_array [0];
;
return 0;
@ -1765,7 +1785,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) < 0)];
test_array [0] = 0
test_array [0] = 0;
return test_array [0];
;
return 0;
@ -1781,7 +1802,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) >= $ac_mid)];
test_array [0] = 0
test_array [0] = 0;
return test_array [0];
;
return 0;
@ -1815,7 +1837,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
test_array [0] = 0
test_array [0] = 0;
return test_array [0];
;
return 0;
@ -1942,7 +1965,7 @@ $as_echo "$ac_try_echo"; } >&5
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
@ -2173,7 +2196,7 @@ This file contains any messages produced by compilers while
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 $@
@ -2764,7 +2787,7 @@ do
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
@ -2808,7 +2831,7 @@ do
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
@ -3252,8 +3275,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* 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);
@ -3368,7 +3390,7 @@ do
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
@ -3412,7 +3434,7 @@ do
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
@ -3794,7 +3816,7 @@ case $as_dir/ in #((
# 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.
@ -3915,7 +3937,7 @@ do
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
@ -3991,7 +4013,7 @@ do
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
@ -4110,7 +4132,7 @@ do
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
@ -4176,7 +4198,7 @@ do
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
@ -5200,7 +5222,7 @@ do
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
@ -5240,7 +5262,7 @@ do
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
@ -5294,7 +5316,7 @@ do
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
@ -5334,7 +5356,7 @@ do
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
@ -7325,7 +7347,7 @@ echo "CXXFLAGS=$CXXFLAGS"
# 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
@ -7771,16 +7793,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... 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
@ -7840,28 +7862,16 @@ else
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'"
@ -7883,7 +7893,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# 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
@ -7936,10 +7946,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
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."
@ -8017,7 +8027,7 @@ fi
_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'
@ -8107,6 +8117,7 @@ do
"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" ;;

View file

@ -1265,6 +1265,7 @@ AC_CONFIG_FILES([icudefs.mk \
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

View file

@ -0,0 +1,240 @@
/***************************************************************************
*
* 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);
}

View file

@ -0,0 +1,235 @@
/***************************************************************************
*
* 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

View file

@ -0,0 +1,97 @@
/*
**********************************************************************
* 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;
}

View file

@ -0,0 +1,41 @@
/*
**********************************************************************
* 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

View file

@ -0,0 +1,83 @@
## 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

View file

@ -0,0 +1,481 @@
/*
*******************************************************************************
*
* 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;
}

View file

@ -0,0 +1,121 @@
/*
*******************************************************************************
*
* 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

View file

@ -0,0 +1,132 @@
/*
*******************************************************************************
*
* 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;
}

View file

@ -0,0 +1,71 @@
/*
*******************************************************************************
*
* 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

View file

@ -0,0 +1,69 @@
/*
*
* (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

View file

@ -0,0 +1,32 @@
/*
*
* (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

View file

@ -0,0 +1,247 @@
/***************************************************************************
*
* 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
}

View file

@ -0,0 +1,85 @@
/***************************************************************************
*
* 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

View file

@ -0,0 +1,120 @@
/***************************************************************************
*
* 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"

View file

@ -0,0 +1,177 @@
/***************************************************************************
*
* 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;
}

View file

@ -0,0 +1,449 @@
/***************************************************************************
*
* 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

View file

@ -0,0 +1,259 @@
/*
*******************************************************************************
*
* 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

View file

@ -0,0 +1,25 @@
/*
*
* (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