diff options
| -rw-r--r-- | core/array.cpp | 4 | ||||
| -rw-r--r-- | core/array.h | 1 | ||||
| -rw-r--r-- | core/bind/core_bind.cpp | 14 | ||||
| -rw-r--r-- | core/bind/core_bind.h | 4 | ||||
| -rw-r--r-- | core/io/image_loader.cpp | 3 | ||||
| -rw-r--r-- | core/math/geometry.cpp | 14 | ||||
| -rw-r--r-- | core/object_type_db.cpp | 2 | ||||
| -rw-r--r-- | core/os/os.cpp | 5 | ||||
| -rw-r--r-- | core/variant_call.cpp | 2 | ||||
| -rw-r--r-- | core/variant_op.cpp | 10 | ||||
| -rw-r--r-- | doc/base/classes.xml | 82 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/compress.c | 2 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/deflate.c | 12 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/deflate.h | 2 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/infback.c | 2 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/inffast.c | 6 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/inflate.c | 64 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/inftrees.c | 14 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/trees.c | 14 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/uncompr.c | 2 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/zconf.h | 39 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/zconf.in.h | 332 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/zlib.h | 48 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/zutil.c | 2 | ||||
| -rw-r--r-- | drivers/builtin_zlib/zlib/zutil.h | 9 | ||||
| -rw-r--r-- | drivers/etc1/rg_etc1.cpp | 28 | ||||
| -rw-r--r-- | drivers/freetype/SCsub | 95 | ||||
| -rw-r--r-- | drivers/freetype/freetype/include/freetype/ftcffdrv.h | 151 | ||||
| -rw-r--r-- | drivers/freetype/freetype/include/freetype/ftttdrv.h | 150 | ||||
| -rw-r--r-- | drivers/freetype/freetype/include/ftoption.h | 833 | ||||
| -rw-r--r-- | drivers/freetype/freetype/src/autofit/afglobal.c | 304 | ||||
| -rw-r--r-- | drivers/freetype/freetype/src/autofit/afglobal.h | 109 | ||||
| -rw-r--r-- | drivers/freetype/freetype/src/autofit/afloader.c | 561 | ||||
| -rw-r--r-- | drivers/freetype/freetype/src/autofit/afmodule.c | 264 | ||||
| -rw-r--r-- | drivers/freetype/freetype/src/autofit/aftypes.h | 378 | ||||
| -rw-r--r-- | drivers/freetype/freetype/src/base/Jamfile | 60 | ||||
| -rw-r--r-- | drivers/freetype/freetype/src/base/ftcalc.c | 974 | ||||
| -rw-r--r-- | drivers/freetype/freetype/src/base/ftpatent.c | 286 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/config/ftconfig.h (renamed from drivers/freetype/freetype/include/freetype/config/ftconfig.h) | 211 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/config/ftheader.h (renamed from drivers/freetype/freetype/include/freetype/config/ftheader.h) | 25 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/config/ftmodule.h (renamed from drivers/freetype/freetype/include/freetype/config/ftmodule.h) | 0 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/config/ftoption.h (renamed from drivers/freetype/freetype/include/freetype/config/ftoption.h) | 248 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/config/ftstdlib.h (renamed from drivers/freetype/freetype/include/freetype/config/ftstdlib.h) | 16 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/freetype.h (renamed from drivers/freetype/freetype/include/freetype/freetype.h) | 798 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftadvanc.h (renamed from drivers/freetype/freetype/include/freetype/ftadvanc.h) | 21 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftautoh.h (renamed from drivers/freetype/freetype/include/freetype/ftautoh.h) | 184 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftbbox.h (renamed from drivers/freetype/freetype/include/freetype/ftbbox.h) | 13 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftbdf.h (renamed from drivers/freetype/freetype/include/freetype/ftbdf.h) | 15 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftbitmap.h (renamed from drivers/freetype/freetype/include/freetype/ftbitmap.h) | 27 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftbzip2.h (renamed from drivers/freetype/freetype/include/freetype/ftbzip2.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftcache.h (renamed from drivers/freetype/freetype/include/freetype/ftcache.h) | 28 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftcffdrv.h | 262 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftchapters.h (renamed from drivers/freetype/freetype/include/freetype/ftchapters.h) | 17 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftcid.h (renamed from drivers/freetype/freetype/include/freetype/ftcid.h) | 16 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/fterrdef.h (renamed from drivers/freetype/freetype/include/freetype/fterrdef.h) | 233 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/fterrors.h (renamed from drivers/freetype/freetype/include/freetype/fterrors.h) | 118 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftfntfmt.h (renamed from drivers/freetype/freetype/include/freetype/ftxf86.h) | 42 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftgasp.h (renamed from drivers/freetype/freetype/include/freetype/ftgasp.h) | 11 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftglyph.h (renamed from drivers/freetype/freetype/include/freetype/ftglyph.h) | 35 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftgxval.h (renamed from drivers/freetype/freetype/include/freetype/ftgxval.h) | 41 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftgzip.h (renamed from drivers/freetype/freetype/include/freetype/ftgzip.h) | 56 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftimage.h (renamed from drivers/freetype/freetype/include/freetype/ftimage.h) | 252 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftincrem.h (renamed from drivers/freetype/freetype/include/freetype/ftincrem.h) | 11 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftlcdfil.h (renamed from drivers/freetype/freetype/include/freetype/ftlcdfil.h) | 187 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftlist.h (renamed from drivers/freetype/freetype/include/freetype/ftlist.h) | 21 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftlzw.h (renamed from drivers/freetype/freetype/include/freetype/ftlzw.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftmac.h (renamed from drivers/freetype/freetype/include/freetype/ftmac.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftmm.h (renamed from drivers/freetype/freetype/include/freetype/ftmm.h) | 48 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftmodapi.h (renamed from drivers/freetype/freetype/include/freetype/ftmodapi.h) | 72 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftmoderr.h (renamed from drivers/freetype/freetype/include/freetype/ftmoderr.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftotval.h (renamed from drivers/freetype/freetype/include/freetype/ftotval.h) | 37 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftoutln.h (renamed from drivers/freetype/freetype/include/freetype/ftoutln.h) | 52 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftpfr.h (renamed from drivers/freetype/freetype/include/freetype/ftpfr.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftrender.h (renamed from drivers/freetype/freetype/include/freetype/ftrender.h) | 18 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftsizes.h (renamed from drivers/freetype/freetype/include/freetype/ftsizes.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftsnames.h (renamed from drivers/freetype/freetype/include/freetype/ftsnames.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftstroke.h (renamed from drivers/freetype/freetype/include/freetype/ftstroke.h) | 50 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftsynth.h (renamed from drivers/freetype/freetype/include/freetype/ftsynth.h) | 17 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftsystem.h (renamed from drivers/freetype/freetype/include/freetype/ftsystem.h) | 18 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/fttrigon.h (renamed from drivers/freetype/freetype/include/freetype/fttrigon.h) | 16 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftttdrv.h | 327 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/fttypes.h (renamed from drivers/freetype/freetype/include/freetype/fttypes.h) | 20 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ftwinfnt.h (renamed from drivers/freetype/freetype/include/freetype/ftwinfnt.h) | 19 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/autohint.h (renamed from drivers/freetype/freetype/include/freetype/internal/autohint.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftcalc.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftcalc.h) | 305 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftdebug.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftdebug.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftdriver.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftdriver.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftgloadr.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftgloadr.h) | 58 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/fthash.h | 136 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftmemory.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftmemory.h) | 38 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftobjs.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftobjs.h) | 87 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftpic.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftpic.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftrfork.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftrfork.h) | 22 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftserv.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftserv.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftstream.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftstream.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/fttrace.h (renamed from drivers/freetype/freetype/include/freetype/internal/fttrace.h) | 4 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/ftvalid.h (renamed from drivers/freetype/freetype/include/freetype/internal/ftvalid.h) | 30 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/internal.h (renamed from drivers/freetype/freetype/include/freetype/internal/internal.h) | 4 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/psaux.h (renamed from drivers/freetype/freetype/include/freetype/internal/psaux.h) | 28 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/pshints.h (renamed from drivers/freetype/freetype/include/freetype/internal/pshints.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svbdf.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svbdf.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svcid.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svcid.h) | 9 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svfntfmt.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svxf86nm.h) | 32 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svgldict.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svgldict.h) | 11 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svgxval.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svgxval.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svkern.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svkern.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svmm.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svmm.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svotval.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svotval.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svpfr.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svpfr.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svpostnm.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svpostnm.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svprop.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svprop.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svpscmap.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svpscmap.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svpsinfo.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svpsinfo.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svsfnt.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svsfnt.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svttcmap.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svttcmap.h) | 19 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svtteng.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svtteng.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svttglyf.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svttglyf.h) | 9 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/services/svwinfnt.h (renamed from drivers/freetype/freetype/include/freetype/internal/services/svwinfnt.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/sfnt.h (renamed from drivers/freetype/freetype/include/freetype/internal/sfnt.h) | 67 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/t1types.h (renamed from drivers/freetype/freetype/include/freetype/internal/t1types.h) | 28 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/internal/tttypes.h (renamed from drivers/freetype/freetype/include/freetype/internal/tttypes.h) | 156 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/t1tables.h (renamed from drivers/freetype/freetype/include/freetype/t1tables.h) | 131 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ttnameid.h (renamed from drivers/freetype/freetype/include/freetype/ttnameid.h) | 240 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/tttables.h (renamed from drivers/freetype/freetype/include/freetype/tttables.h) | 108 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/tttags.h (renamed from drivers/freetype/freetype/include/freetype/tttags.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/include/freetype/ttunpat.h (renamed from drivers/freetype/freetype/include/freetype/ttunpat.h) | 22 | ||||
| -rw-r--r-- | drivers/freetype/include/ft2build.h (renamed from drivers/freetype/ft2build.h) | 36 | ||||
| -rw-r--r-- | drivers/freetype/src/Jamfile (renamed from drivers/freetype/freetype/src/Jamfile) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/Jamfile (renamed from drivers/freetype/freetype/src/autofit/Jamfile) | 20 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afangles.c (renamed from drivers/freetype/freetype/src/autofit/afangles.c) | 64 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afangles.h (renamed from drivers/freetype/freetype/src/autofit/afangles.h) | 0 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afblue.c | 459 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afblue.cin (renamed from drivers/freetype/freetype/src/autofit/aflatin2.h) | 34 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afblue.dat | 718 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afblue.h | 308 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afblue.hin | 146 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afcjk.c (renamed from drivers/freetype/freetype/src/autofit/afcjk.c) | 906 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afcjk.h (renamed from drivers/freetype/freetype/src/autofit/afcjk.h) | 73 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afcover.h | 105 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afdummy.c (renamed from drivers/freetype/freetype/src/autofit/afdummy.c) | 51 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afdummy.h (renamed from drivers/freetype/freetype/src/autofit/afdummy.h) | 14 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/aferrors.h (renamed from drivers/freetype/freetype/src/autofit/aferrors.h) | 11 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afglobal.c | 515 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afglobal.h | 173 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afhints.c (renamed from drivers/freetype/freetype/src/autofit/afhints.c) | 776 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afhints.h (renamed from drivers/freetype/freetype/src/autofit/afhints.h) | 187 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afindic.c (renamed from drivers/freetype/freetype/src/autofit/afindic.c) | 84 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afindic.h (renamed from drivers/freetype/freetype/src/autofit/afindic.h) | 15 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/aflatin.c (renamed from drivers/freetype/freetype/src/autofit/aflatin.c) | 1741 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/aflatin.h (renamed from drivers/freetype/freetype/src/autofit/aflatin.h) | 94 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/aflatin2.c (renamed from drivers/freetype/freetype/src/autofit/aflatin2.c) | 157 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/aflatin2.h | 46 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afloader.c | 676 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afloader.h (renamed from drivers/freetype/freetype/src/autofit/afloader.h) | 34 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afmodule.c | 486 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afmodule.h (renamed from drivers/freetype/freetype/src/autofit/afmodule.h) | 30 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afpic.c (renamed from drivers/freetype/freetype/src/autofit/afpic.c) | 67 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afpic.h (renamed from drivers/freetype/freetype/src/autofit/afpic.h) | 55 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afranges.c | 714 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afranges.h | 47 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afscript.h | 245 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afshaper.c | 683 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afshaper.h | 72 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afstyles.h | 301 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/aftypes.h | 650 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afwarp.c (renamed from drivers/freetype/freetype/src/autofit/afwarp.c) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afwarp.h (renamed from drivers/freetype/freetype/src/autofit/afwarp.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/afwrtsys.h | 52 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/autofit.c (renamed from drivers/freetype/freetype/src/autofit/autofit.c) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/module.mk (renamed from drivers/freetype/freetype/src/autofit/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/autofit/rules.mk (renamed from drivers/freetype/freetype/src/autofit/rules.mk) | 16 | ||||
| -rw-r--r-- | drivers/freetype/src/base/Jamfile | 88 | ||||
| -rw-r--r-- | drivers/freetype/src/base/basepic.c (renamed from drivers/freetype/freetype/src/base/basepic.c) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/base/basepic.h (renamed from drivers/freetype/freetype/src/base/basepic.h) | 17 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftadvanc.c (renamed from drivers/freetype/freetype/src/base/ftadvanc.c) | 24 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftapi.c (renamed from drivers/freetype/freetype/src/base/ftapi.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftbase.c (renamed from drivers/freetype/freetype/src/base/ftbase.c) | 3 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftbase.h (renamed from drivers/freetype/freetype/src/base/ftbase.h) | 13 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftbbox.c (renamed from drivers/freetype/freetype/src/base/ftbbox.c) | 434 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftbdf.c (renamed from drivers/freetype/freetype/src/base/ftbdf.c) | 43 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftbitmap.c (renamed from drivers/freetype/freetype/src/base/ftbitmap.c) | 275 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftcalc.c | 1003 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftcid.c (renamed from drivers/freetype/freetype/src/base/ftcid.c) | 3 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftdbgmem.c (renamed from drivers/freetype/freetype/src/base/ftdbgmem.c) | 131 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftdebug.c (renamed from drivers/freetype/freetype/src/base/ftdebug.c) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftfntfmt.c (renamed from drivers/freetype/freetype/src/base/ftxf86.c) | 29 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftfstype.c (renamed from drivers/freetype/freetype/src/base/ftfstype.c) | 4 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftgasp.c (renamed from drivers/freetype/freetype/src/base/ftgasp.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftgloadr.c (renamed from drivers/freetype/freetype/src/base/ftgloadr.c) | 17 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftglyph.c (renamed from drivers/freetype/freetype/src/base/ftglyph.c) | 100 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftgxval.c (renamed from drivers/freetype/freetype/src/base/ftgxval.c) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/base/fthash.c | 339 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftinit.c (renamed from drivers/freetype/freetype/src/base/ftinit.c) | 30 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftlcdfil.c (renamed from drivers/freetype/freetype/src/base/ftlcdfil.c) | 75 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftmac.c (renamed from drivers/freetype/freetype/src/base/ftmac.c) | 37 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftmm.c (renamed from drivers/freetype/freetype/src/base/ftmm.c) | 32 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftobjs.c (renamed from drivers/freetype/freetype/src/base/ftobjs.c) | 624 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftotval.c (renamed from drivers/freetype/freetype/src/base/ftotval.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftoutln.c (renamed from drivers/freetype/freetype/src/base/ftoutln.c) | 245 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftpatent.c | 51 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftpfr.c (renamed from drivers/freetype/freetype/src/base/ftpfr.c) | 15 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftpic.c (renamed from drivers/freetype/freetype/src/base/ftpic.c) | 4 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftrfork.c (renamed from drivers/freetype/freetype/src/base/ftrfork.c) | 91 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftsnames.c (renamed from drivers/freetype/freetype/src/base/ftsnames.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftstream.c (renamed from drivers/freetype/freetype/src/base/ftstream.c) | 95 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftstroke.c (renamed from drivers/freetype/freetype/src/base/ftstroke.c) | 151 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftsynth.c (renamed from drivers/freetype/freetype/src/base/ftsynth.c) | 34 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftsystem.c (renamed from drivers/freetype/freetype/src/base/ftsystem.c) | 16 | ||||
| -rw-r--r-- | drivers/freetype/src/base/fttrigon.c (renamed from drivers/freetype/freetype/src/base/fttrigon.c) | 168 | ||||
| -rw-r--r-- | drivers/freetype/src/base/fttype1.c (renamed from drivers/freetype/freetype/src/base/fttype1.c) | 45 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftutil.c (renamed from drivers/freetype/freetype/src/base/ftutil.c) | 77 | ||||
| -rw-r--r-- | drivers/freetype/src/base/ftwinfnt.c (renamed from drivers/freetype/freetype/src/base/ftwinfnt.c) | 22 | ||||
| -rw-r--r-- | drivers/freetype/src/base/md5.c (renamed from drivers/freetype/freetype/src/base/md5.c) | 108 | ||||
| -rw-r--r-- | drivers/freetype/src/base/md5.h (renamed from drivers/freetype/freetype/src/base/md5.h) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/base/rules.mk (renamed from drivers/freetype/freetype/src/base/rules.mk) | 21 | ||||
| -rw-r--r-- | drivers/freetype/src/bdf/Jamfile (renamed from drivers/freetype/freetype/src/bdf/Jamfile) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/bdf/README (renamed from drivers/freetype/freetype/src/bdf/README) | 0 | ||||
| -rw-r--r-- | drivers/freetype/src/bdf/bdf.c (renamed from drivers/freetype/freetype/src/bdf/bdf.c) | 0 | ||||
| -rw-r--r-- | drivers/freetype/src/bdf/bdf.h (renamed from drivers/freetype/freetype/src/bdf/bdf.h) | 41 | ||||
| -rw-r--r-- | drivers/freetype/src/bdf/bdfdrivr.c (renamed from drivers/freetype/freetype/src/bdf/bdfdrivr.c) | 112 | ||||
| -rw-r--r-- | drivers/freetype/src/bdf/bdfdrivr.h (renamed from drivers/freetype/freetype/src/bdf/bdfdrivr.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/bdf/bdferror.h (renamed from drivers/freetype/freetype/src/bdf/bdferror.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/bdf/bdflib.c (renamed from drivers/freetype/freetype/src/bdf/bdflib.c) | 719 | ||||
| -rw-r--r-- | drivers/freetype/src/bdf/module.mk (renamed from drivers/freetype/freetype/src/bdf/module.mk) | 0 | ||||
| -rw-r--r-- | drivers/freetype/src/bdf/rules.mk (renamed from drivers/freetype/freetype/src/bdf/rules.mk) | 5 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/Jamfile (renamed from drivers/freetype/freetype/src/cache/Jamfile) | 16 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcache.c (renamed from drivers/freetype/freetype/src/cache/ftcache.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcbasic.c (renamed from drivers/freetype/freetype/src/cache/ftcbasic.c) | 103 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftccache.c (renamed from drivers/freetype/freetype/src/cache/ftccache.c) | 30 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftccache.h (renamed from drivers/freetype/freetype/src/cache/ftccache.h) | 48 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftccback.h (renamed from drivers/freetype/freetype/src/cache/ftccback.h) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftccmap.c (renamed from drivers/freetype/freetype/src/cache/ftccmap.c) | 20 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcerror.h (renamed from drivers/freetype/freetype/src/cache/ftcerror.h) | 11 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcglyph.c (renamed from drivers/freetype/freetype/src/cache/ftcglyph.c) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcglyph.h (renamed from drivers/freetype/freetype/src/cache/ftcglyph.h) | 16 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcimage.c (renamed from drivers/freetype/freetype/src/cache/ftcimage.c) | 11 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcimage.h (renamed from drivers/freetype/freetype/src/cache/ftcimage.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcmanag.c (renamed from drivers/freetype/freetype/src/cache/ftcmanag.c) | 52 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcmanag.h (renamed from drivers/freetype/freetype/src/cache/ftcmanag.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcmru.c (renamed from drivers/freetype/freetype/src/cache/ftcmru.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcmru.h (renamed from drivers/freetype/freetype/src/cache/ftcmru.h) | 14 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcsbits.c (renamed from drivers/freetype/freetype/src/cache/ftcsbits.c) | 18 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/ftcsbits.h (renamed from drivers/freetype/freetype/src/cache/ftcsbits.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/cache/rules.mk (renamed from drivers/freetype/freetype/src/cache/rules.mk) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/Jamfile (renamed from drivers/freetype/freetype/src/cff/Jamfile) | 20 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2arrst.c (renamed from drivers/freetype/freetype/src/cff/cf2arrst.c) | 4 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2arrst.h (renamed from drivers/freetype/freetype/src/cff/cf2arrst.h) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2blues.c (renamed from drivers/freetype/freetype/src/cff/cf2blues.c) | 13 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2blues.h (renamed from drivers/freetype/freetype/src/cff/cf2blues.h) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2error.c (renamed from drivers/freetype/freetype/src/cff/cf2error.c) | 0 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2error.h (renamed from drivers/freetype/freetype/src/cff/cf2error.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2fixed.h (renamed from drivers/freetype/freetype/src/cff/cf2fixed.h) | 28 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2font.c (renamed from drivers/freetype/freetype/src/cff/cf2font.c) | 211 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2font.h (renamed from drivers/freetype/freetype/src/cff/cf2font.h) | 16 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2ft.c (renamed from drivers/freetype/freetype/src/cff/cf2ft.c) | 129 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2ft.h (renamed from drivers/freetype/freetype/src/cff/cf2ft.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2glue.h (renamed from drivers/freetype/freetype/src/cff/cf2glue.h) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2hints.c (renamed from drivers/freetype/freetype/src/cff/cf2hints.c) | 228 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2hints.h (renamed from drivers/freetype/freetype/src/cff/cf2hints.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2intrp.c (renamed from drivers/freetype/freetype/src/cff/cf2intrp.c) | 467 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2intrp.h (renamed from drivers/freetype/freetype/src/cff/cf2intrp.h) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2read.c (renamed from drivers/freetype/freetype/src/cff/cf2read.c) | 0 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2read.h (renamed from drivers/freetype/freetype/src/cff/cf2read.h) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2stack.c (renamed from drivers/freetype/freetype/src/cff/cf2stack.c) | 84 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2stack.h (renamed from drivers/freetype/freetype/src/cff/cf2stack.h) | 11 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cf2types.h (renamed from drivers/freetype/freetype/src/cff/cf2types.h) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cff.c (renamed from drivers/freetype/freetype/src/cff/cff.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffcmap.c (renamed from drivers/freetype/freetype/src/cff/cffcmap.c) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffcmap.h (renamed from drivers/freetype/freetype/src/cff/cffcmap.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffdrivr.c (renamed from drivers/freetype/freetype/src/cff/cffdrivr.c) | 245 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffdrivr.h (renamed from drivers/freetype/freetype/src/cff/cffdrivr.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cfferrs.h (renamed from drivers/freetype/freetype/src/cff/cfferrs.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffgload.c (renamed from drivers/freetype/freetype/src/cff/cffgload.c) | 317 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffgload.h (renamed from drivers/freetype/freetype/src/cff/cffgload.h) | 18 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffload.c (renamed from drivers/freetype/freetype/src/cff/cffload.c) | 87 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffload.h (renamed from drivers/freetype/freetype/src/cff/cffload.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffobjs.c (renamed from drivers/freetype/freetype/src/cff/cffobjs.c) | 147 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffobjs.h (renamed from drivers/freetype/freetype/src/cff/cffobjs.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffparse.c (renamed from drivers/freetype/freetype/src/cff/cffparse.c) | 302 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffparse.h (renamed from drivers/freetype/freetype/src/cff/cffparse.h) | 31 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffpic.c (renamed from drivers/freetype/freetype/src/cff/cffpic.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cffpic.h (renamed from drivers/freetype/freetype/src/cff/cffpic.h) | 16 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cfftoken.h (renamed from drivers/freetype/freetype/src/cff/cfftoken.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/cfftypes.h (renamed from drivers/freetype/freetype/src/cff/cfftypes.h) | 15 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/module.mk (renamed from drivers/freetype/freetype/src/cff/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/cff/rules.mk (renamed from drivers/freetype/freetype/src/cff/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/Jamfile (renamed from drivers/freetype/freetype/src/cid/Jamfile) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/ciderrs.h (renamed from drivers/freetype/freetype/src/cid/ciderrs.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidgload.c (renamed from drivers/freetype/freetype/src/cid/cidgload.c) | 88 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidgload.h (renamed from drivers/freetype/freetype/src/cid/cidgload.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidload.c (renamed from drivers/freetype/freetype/src/cid/cidload.c) | 226 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidload.h (renamed from drivers/freetype/freetype/src/cid/cidload.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidobjs.c (renamed from drivers/freetype/freetype/src/cid/cidobjs.c) | 25 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidobjs.h (renamed from drivers/freetype/freetype/src/cid/cidobjs.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidparse.c (renamed from drivers/freetype/freetype/src/cid/cidparse.c) | 106 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidparse.h (renamed from drivers/freetype/freetype/src/cid/cidparse.h) | 32 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidriver.c (renamed from drivers/freetype/freetype/src/cid/cidriver.c) | 68 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidriver.h (renamed from drivers/freetype/freetype/src/cid/cidriver.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/cidtoken.h (renamed from drivers/freetype/freetype/src/cid/cidtoken.h) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/module.mk (renamed from drivers/freetype/freetype/src/cid/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/rules.mk (renamed from drivers/freetype/freetype/src/cid/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/cid/type1cid.c (renamed from drivers/freetype/freetype/src/cid/type1cid.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/Jamfile (renamed from drivers/freetype/freetype/src/gxvalid/Jamfile) | 29 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/README (renamed from drivers/freetype/freetype/src/gxvalid/README) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvalid.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvalid.c) | 3 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvalid.h (renamed from drivers/freetype/freetype/src/gxvalid/gxvalid.h) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvbsln.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvbsln.c) | 59 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvcommn.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvcommn.c) | 308 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvcommn.h (renamed from drivers/freetype/freetype/src/gxvalid/gxvcommn.h) | 96 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxverror.h (renamed from drivers/freetype/freetype/src/gxvalid/gxverror.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvfeat.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvfeat.c) | 40 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvfeat.h (renamed from drivers/freetype/freetype/src/gxvalid/gxvfeat.h) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvfgen.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvfgen.c) | 3 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvjust.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvjust.c) | 206 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvkern.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvkern.c) | 162 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvlcar.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvlcar.c) | 45 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmod.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmod.c) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmod.h (renamed from drivers/freetype/freetype/src/gxvalid/gxvmod.h) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmort.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmort.c) | 49 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmort.h (renamed from drivers/freetype/freetype/src/gxvalid/gxvmort.h) | 23 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmort0.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmort0.c) | 19 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmort1.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmort1.c) | 61 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmort2.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmort2.c) | 49 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmort4.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmort4.c) | 21 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmort5.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmort5.c) | 33 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmorx.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmorx.c) | 32 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmorx.h (renamed from drivers/freetype/freetype/src/gxvalid/gxvmorx.h) | 19 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmorx0.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmorx0.c) | 19 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmorx1.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmorx1.c) | 57 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmorx2.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmorx2.c) | 54 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmorx4.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmorx4.c) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvmorx5.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvmorx5.c) | 37 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvopbd.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvopbd.c) | 35 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvprop.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvprop.c) | 43 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/gxvtrak.c (renamed from drivers/freetype/freetype/src/gxvalid/gxvtrak.c) | 58 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/module.mk (renamed from drivers/freetype/freetype/src/gxvalid/module.mk) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/gxvalid/rules.mk (renamed from drivers/freetype/freetype/src/gxvalid/rules.mk) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/Jamfile (renamed from drivers/freetype/freetype/src/otvalid/Jamfile) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/module.mk (renamed from drivers/freetype/freetype/src/otvalid/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvalid.c (renamed from drivers/freetype/freetype/src/otvalid/otvalid.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvalid.h (renamed from drivers/freetype/freetype/src/otvalid/otvalid.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvbase.c (renamed from drivers/freetype/freetype/src/otvalid/otvbase.c) | 52 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvcommn.c (renamed from drivers/freetype/freetype/src/otvalid/otvcommn.c) | 172 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvcommn.h (renamed from drivers/freetype/freetype/src/otvalid/otvcommn.h) | 164 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otverror.h (renamed from drivers/freetype/freetype/src/otvalid/otverror.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvgdef.c (renamed from drivers/freetype/freetype/src/otvalid/otvgdef.c) | 38 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvgpos.c (renamed from drivers/freetype/freetype/src/otvalid/otvgpos.c) | 192 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvgpos.h (renamed from drivers/freetype/freetype/src/otvalid/otvgpos.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvgsub.c (renamed from drivers/freetype/freetype/src/otvalid/otvgsub.c) | 116 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvjstf.c (renamed from drivers/freetype/freetype/src/otvalid/otvjstf.c) | 85 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvmath.c (renamed from drivers/freetype/freetype/src/otvalid/otvmath.c) | 76 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvmod.c (renamed from drivers/freetype/freetype/src/otvalid/otvmod.c) | 4 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/otvmod.h (renamed from drivers/freetype/freetype/src/otvalid/otvmod.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/otvalid/rules.mk (renamed from drivers/freetype/freetype/src/otvalid/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/Jamfile (renamed from drivers/freetype/freetype/src/pcf/Jamfile) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/README (renamed from drivers/freetype/freetype/src/pcf/README) | 0 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/module.mk (renamed from drivers/freetype/freetype/src/pcf/module.mk) | 0 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/pcf.c (renamed from drivers/freetype/freetype/src/pcf/pcf.c) | 0 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/pcf.h (renamed from drivers/freetype/freetype/src/pcf/pcf.h) | 15 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/pcfdrivr.c (renamed from drivers/freetype/freetype/src/pcf/pcfdrivr.c) | 155 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/pcfdrivr.h (renamed from drivers/freetype/freetype/src/pcf/pcfdrivr.h) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/pcferror.h (renamed from drivers/freetype/freetype/src/pcf/pcferror.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/pcfread.c (renamed from drivers/freetype/freetype/src/pcf/pcfread.c) | 252 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/pcfread.h (renamed from drivers/freetype/freetype/src/pcf/pcfread.h) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/pcfutil.c (renamed from drivers/freetype/freetype/src/pcf/pcfutil.c) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/pcfutil.h (renamed from drivers/freetype/freetype/src/pcf/pcfutil.h) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/pcf/rules.mk (renamed from drivers/freetype/freetype/src/pcf/rules.mk) | 5 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/Jamfile (renamed from drivers/freetype/freetype/src/pfr/Jamfile) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/module.mk (renamed from drivers/freetype/freetype/src/pfr/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfr.c (renamed from drivers/freetype/freetype/src/pfr/pfr.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrcmap.c (renamed from drivers/freetype/freetype/src/pfr/pfrcmap.c) | 19 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrcmap.h (renamed from drivers/freetype/freetype/src/pfr/pfrcmap.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrdrivr.c (renamed from drivers/freetype/freetype/src/pfr/pfrdrivr.c) | 63 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrdrivr.h (renamed from drivers/freetype/freetype/src/pfr/pfrdrivr.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrerror.h (renamed from drivers/freetype/freetype/src/pfr/pfrerror.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrgload.c (renamed from drivers/freetype/freetype/src/pfr/pfrgload.c) | 69 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrgload.h (renamed from drivers/freetype/freetype/src/pfr/pfrgload.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrload.c (renamed from drivers/freetype/freetype/src/pfr/pfrload.c) | 206 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrload.h (renamed from drivers/freetype/freetype/src/pfr/pfrload.h) | 25 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrobjs.c (renamed from drivers/freetype/freetype/src/pfr/pfrobjs.c) | 67 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrobjs.h (renamed from drivers/freetype/freetype/src/pfr/pfrobjs.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrsbit.c (renamed from drivers/freetype/freetype/src/pfr/pfrsbit.c) | 268 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrsbit.h (renamed from drivers/freetype/freetype/src/pfr/pfrsbit.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/pfrtypes.h (renamed from drivers/freetype/freetype/src/pfr/pfrtypes.h) | 126 | ||||
| -rw-r--r-- | drivers/freetype/src/pfr/rules.mk (renamed from drivers/freetype/freetype/src/pfr/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/Jamfile (renamed from drivers/freetype/freetype/src/psaux/Jamfile) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/afmparse.c (renamed from drivers/freetype/freetype/src/psaux/afmparse.c) | 45 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/afmparse.h (renamed from drivers/freetype/freetype/src/psaux/afmparse.h) | 11 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/module.mk (renamed from drivers/freetype/freetype/src/psaux/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/psaux.c (renamed from drivers/freetype/freetype/src/psaux/psaux.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/psauxerr.h (renamed from drivers/freetype/freetype/src/psaux/psauxerr.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/psauxmod.c (renamed from drivers/freetype/freetype/src/psaux/psauxmod.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/psauxmod.h (renamed from drivers/freetype/freetype/src/psaux/psauxmod.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/psconv.c (renamed from drivers/freetype/freetype/src/psaux/psconv.c) | 15 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/psconv.h (renamed from drivers/freetype/freetype/src/psaux/psconv.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/psobjs.c (renamed from drivers/freetype/freetype/src/psaux/psobjs.c) | 67 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/psobjs.h (renamed from drivers/freetype/freetype/src/psaux/psobjs.h) | 18 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/rules.mk (renamed from drivers/freetype/freetype/src/psaux/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/t1cmap.c (renamed from drivers/freetype/freetype/src/psaux/t1cmap.c) | 32 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/t1cmap.h (renamed from drivers/freetype/freetype/src/psaux/t1cmap.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/t1decode.c (renamed from drivers/freetype/freetype/src/psaux/t1decode.c) | 60 | ||||
| -rw-r--r-- | drivers/freetype/src/psaux/t1decode.h (renamed from drivers/freetype/freetype/src/psaux/t1decode.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/Jamfile (renamed from drivers/freetype/freetype/src/pshinter/Jamfile) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/module.mk (renamed from drivers/freetype/freetype/src/pshinter/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshalgo.c (renamed from drivers/freetype/freetype/src/pshinter/pshalgo.c) | 150 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshalgo.h (renamed from drivers/freetype/freetype/src/pshinter/pshalgo.h) | 55 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshglob.c (renamed from drivers/freetype/freetype/src/pshinter/pshglob.c) | 20 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshglob.h (renamed from drivers/freetype/freetype/src/pshinter/pshglob.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshinter.c (renamed from drivers/freetype/freetype/src/pshinter/pshinter.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshmod.c (renamed from drivers/freetype/freetype/src/pshinter/pshmod.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshmod.h (renamed from drivers/freetype/freetype/src/pshinter/pshmod.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshnterr.h (renamed from drivers/freetype/freetype/src/pshinter/pshnterr.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshpic.c (renamed from drivers/freetype/freetype/src/pshinter/pshpic.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshpic.h (renamed from drivers/freetype/freetype/src/pshinter/pshpic.h) | 16 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshrec.c (renamed from drivers/freetype/freetype/src/pshinter/pshrec.c) | 193 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/pshrec.h (renamed from drivers/freetype/freetype/src/pshinter/pshrec.h) | 18 | ||||
| -rw-r--r-- | drivers/freetype/src/pshinter/rules.mk (renamed from drivers/freetype/freetype/src/pshinter/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/psnames/Jamfile (renamed from drivers/freetype/freetype/src/psnames/Jamfile) | 6 | ||||
| -rw-r--r-- | drivers/freetype/src/psnames/module.mk (renamed from drivers/freetype/freetype/src/psnames/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/psnames/psmodule.c (renamed from drivers/freetype/freetype/src/psnames/psmodule.c) | 38 | ||||
| -rw-r--r-- | drivers/freetype/src/psnames/psmodule.h (renamed from drivers/freetype/freetype/src/psnames/psmodule.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/psnames/psnamerr.h (renamed from drivers/freetype/freetype/src/psnames/psnamerr.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/psnames/psnames.c (renamed from drivers/freetype/freetype/src/psnames/psnames.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/psnames/pspic.c (renamed from drivers/freetype/freetype/src/psnames/pspic.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/psnames/pspic.h (renamed from drivers/freetype/freetype/src/psnames/pspic.h) | 18 | ||||
| -rw-r--r-- | drivers/freetype/src/psnames/pstables.h (renamed from drivers/freetype/freetype/src/psnames/pstables.h) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/psnames/rules.mk (renamed from drivers/freetype/freetype/src/psnames/rules.mk) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/Jamfile (renamed from drivers/freetype/freetype/src/raster/Jamfile) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/ftmisc.h (renamed from drivers/freetype/freetype/src/raster/ftmisc.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/ftraster.c (renamed from drivers/freetype/freetype/src/raster/ftraster.c) | 812 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/ftraster.h (renamed from drivers/freetype/freetype/src/raster/ftraster.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/ftrend1.c (renamed from drivers/freetype/freetype/src/raster/ftrend1.c) | 114 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/ftrend1.h (renamed from drivers/freetype/freetype/src/raster/ftrend1.h) | 14 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/module.mk (renamed from drivers/freetype/freetype/src/raster/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/raster.c (renamed from drivers/freetype/freetype/src/raster/raster.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/rasterrs.h (renamed from drivers/freetype/freetype/src/raster/rasterrs.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/rastpic.c (renamed from drivers/freetype/freetype/src/raster/rastpic.c) | 22 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/rastpic.h (renamed from drivers/freetype/freetype/src/raster/rastpic.h) | 18 | ||||
| -rw-r--r-- | drivers/freetype/src/raster/rules.mk (renamed from drivers/freetype/freetype/src/raster/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/Jamfile (renamed from drivers/freetype/freetype/src/sfnt/Jamfile) | 15 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/module.mk (renamed from drivers/freetype/freetype/src/sfnt/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/pngshim.c (renamed from drivers/freetype/freetype/src/sfnt/pngshim.c) | 92 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/pngshim.h (renamed from drivers/freetype/freetype/src/sfnt/pngshim.h) | 14 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/rules.mk (renamed from drivers/freetype/freetype/src/sfnt/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/sfdriver.c (renamed from drivers/freetype/freetype/src/sfnt/sfdriver.c) | 58 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/sfdriver.h (renamed from drivers/freetype/freetype/src/sfnt/sfdriver.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/sferrors.h (renamed from drivers/freetype/freetype/src/sfnt/sferrors.h) | 11 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/sfnt.c (renamed from drivers/freetype/freetype/src/sfnt/sfnt.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/sfntpic.c (renamed from drivers/freetype/freetype/src/sfnt/sfntpic.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/sfntpic.h (renamed from drivers/freetype/freetype/src/sfnt/sfntpic.h) | 20 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/sfobjs.c (renamed from drivers/freetype/freetype/src/sfnt/sfobjs.c) | 594 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/sfobjs.h (renamed from drivers/freetype/freetype/src/sfnt/sfobjs.h) | 17 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttbdf.c (renamed from drivers/freetype/freetype/src/sfnt/ttbdf.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttbdf.h (renamed from drivers/freetype/freetype/src/sfnt/ttbdf.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttcmap.c (renamed from drivers/freetype/freetype/src/sfnt/ttcmap.c) | 502 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttcmap.h (renamed from drivers/freetype/freetype/src/sfnt/ttcmap.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttcmapc.h (renamed from drivers/freetype/freetype/src/sfnt/ttcmapc.h) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttkern.c (renamed from drivers/freetype/freetype/src/sfnt/ttkern.c) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttkern.h (renamed from drivers/freetype/freetype/src/sfnt/ttkern.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttload.c (renamed from drivers/freetype/freetype/src/sfnt/ttload.c) | 186 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttload.h (renamed from drivers/freetype/freetype/src/sfnt/ttload.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttmtx.c (renamed from drivers/freetype/freetype/src/sfnt/ttmtx.c) | 25 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttmtx.h (renamed from drivers/freetype/freetype/src/sfnt/ttmtx.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttpost.c (renamed from drivers/freetype/freetype/src/sfnt/ttpost.c) | 46 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttpost.h (renamed from drivers/freetype/freetype/src/sfnt/ttpost.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttsbit.c (renamed from drivers/freetype/freetype/src/sfnt/ttsbit.c) | 818 | ||||
| -rw-r--r-- | drivers/freetype/src/sfnt/ttsbit.h (renamed from drivers/freetype/freetype/src/sfnt/ttsbit.h) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/Jamfile (renamed from drivers/freetype/freetype/src/smooth/Jamfile) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/ftgrays.c (renamed from drivers/freetype/freetype/src/smooth/ftgrays.c) | 1190 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/ftgrays.h (renamed from drivers/freetype/freetype/src/smooth/ftgrays.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/ftsmerrs.h (renamed from drivers/freetype/freetype/src/smooth/ftsmerrs.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/ftsmooth.c (renamed from drivers/freetype/freetype/src/smooth/ftsmooth.c) | 153 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/ftsmooth.h (renamed from drivers/freetype/freetype/src/smooth/ftsmooth.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/ftspic.c (renamed from drivers/freetype/freetype/src/smooth/ftspic.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/ftspic.h (renamed from drivers/freetype/freetype/src/smooth/ftspic.h) | 13 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/module.mk (renamed from drivers/freetype/freetype/src/smooth/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/rules.mk (renamed from drivers/freetype/freetype/src/smooth/rules.mk) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/smooth/smooth.c (renamed from drivers/freetype/freetype/src/smooth/smooth.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/Jamfile (renamed from drivers/freetype/freetype/src/truetype/Jamfile) | 12 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/module.mk (renamed from drivers/freetype/freetype/src/truetype/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/rules.mk (renamed from drivers/freetype/freetype/src/truetype/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/truetype.c (renamed from drivers/freetype/freetype/src/truetype/truetype.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttdriver.c (renamed from drivers/freetype/freetype/src/truetype/ttdriver.c) | 96 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttdriver.h (renamed from drivers/freetype/freetype/src/truetype/ttdriver.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/tterrors.h (renamed from drivers/freetype/freetype/src/truetype/tterrors.h) | 11 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttgload.c (renamed from drivers/freetype/freetype/src/truetype/ttgload.c) | 1065 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttgload.h (renamed from drivers/freetype/freetype/src/truetype/ttgload.h) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttgxvar.c (renamed from drivers/freetype/freetype/src/truetype/ttgxvar.c) | 1109 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttgxvar.h (renamed from drivers/freetype/freetype/src/truetype/ttgxvar.h) | 18 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttinterp.c (renamed from drivers/freetype/freetype/src/truetype/ttinterp.c) | 6752 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttinterp.h (renamed from drivers/freetype/freetype/src/truetype/ttinterp.h) | 233 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttobjs.c (renamed from drivers/freetype/freetype/src/truetype/ttobjs.c) | 360 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttobjs.h (renamed from drivers/freetype/freetype/src/truetype/ttobjs.h) | 43 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttpic.c (renamed from drivers/freetype/freetype/src/truetype/ttpic.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttpic.h (renamed from drivers/freetype/freetype/src/truetype/ttpic.h) | 18 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttpload.c (renamed from drivers/freetype/freetype/src/truetype/ttpload.c) | 52 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttpload.h (renamed from drivers/freetype/freetype/src/truetype/ttpload.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttsubpix.c (renamed from drivers/freetype/freetype/src/truetype/ttsubpix.c) | 98 | ||||
| -rw-r--r-- | drivers/freetype/src/truetype/ttsubpix.h (renamed from drivers/freetype/freetype/src/truetype/ttsubpix.h) | 53 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/Jamfile (renamed from drivers/freetype/freetype/src/type1/Jamfile) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/module.mk (renamed from drivers/freetype/freetype/src/type1/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/rules.mk (renamed from drivers/freetype/freetype/src/type1/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1afm.c (renamed from drivers/freetype/freetype/src/type1/t1afm.c) | 26 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1afm.h (renamed from drivers/freetype/freetype/src/type1/t1afm.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1driver.c (renamed from drivers/freetype/freetype/src/type1/t1driver.c) | 137 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1driver.h (renamed from drivers/freetype/freetype/src/type1/t1driver.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1errors.h (renamed from drivers/freetype/freetype/src/type1/t1errors.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1gload.c (renamed from drivers/freetype/freetype/src/type1/t1gload.c) | 45 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1gload.h (renamed from drivers/freetype/freetype/src/type1/t1gload.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1load.c (renamed from drivers/freetype/freetype/src/type1/t1load.c) | 404 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1load.h (renamed from drivers/freetype/freetype/src/type1/t1load.h) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1objs.c (renamed from drivers/freetype/freetype/src/type1/t1objs.c) | 28 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1objs.h (renamed from drivers/freetype/freetype/src/type1/t1objs.h) | 8 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1parse.c (renamed from drivers/freetype/freetype/src/type1/t1parse.c) | 72 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1parse.h (renamed from drivers/freetype/freetype/src/type1/t1parse.h) | 14 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/t1tokens.h (renamed from drivers/freetype/freetype/src/type1/t1tokens.h) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/type1/type1.c (renamed from drivers/freetype/freetype/src/type1/type1.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/Jamfile (renamed from drivers/freetype/freetype/src/type42/Jamfile) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/module.mk (renamed from drivers/freetype/freetype/src/type42/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/rules.mk (renamed from drivers/freetype/freetype/src/type42/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/t42drivr.c (renamed from drivers/freetype/freetype/src/type42/t42drivr.c) | 55 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/t42drivr.h (renamed from drivers/freetype/freetype/src/type42/t42drivr.h) | 9 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/t42error.h (renamed from drivers/freetype/freetype/src/type42/t42error.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/t42objs.c (renamed from drivers/freetype/freetype/src/type42/t42objs.c) | 51 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/t42objs.h (renamed from drivers/freetype/freetype/src/type42/t42objs.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/t42parse.c (renamed from drivers/freetype/freetype/src/type42/t42parse.c) | 246 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/t42parse.h (renamed from drivers/freetype/freetype/src/type42/t42parse.h) | 13 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/t42types.h (renamed from drivers/freetype/freetype/src/type42/t42types.h) | 11 | ||||
| -rw-r--r-- | drivers/freetype/src/type42/type42.c (renamed from drivers/freetype/freetype/src/type42/type42.c) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/winfonts/Jamfile (renamed from drivers/freetype/freetype/src/winfonts/Jamfile) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/winfonts/fnterrs.h (renamed from drivers/freetype/freetype/src/winfonts/fnterrs.h) | 10 | ||||
| -rw-r--r-- | drivers/freetype/src/winfonts/module.mk (renamed from drivers/freetype/freetype/src/winfonts/module.mk) | 2 | ||||
| -rw-r--r-- | drivers/freetype/src/winfonts/rules.mk (renamed from drivers/freetype/freetype/src/winfonts/rules.mk) | 7 | ||||
| -rw-r--r-- | drivers/freetype/src/winfonts/winfnt.c (renamed from drivers/freetype/freetype/src/winfonts/winfnt.c) | 166 | ||||
| -rw-r--r-- | drivers/freetype/src/winfonts/winfnt.h (renamed from drivers/freetype/freetype/src/winfonts/winfnt.h) | 8 | ||||
| -rw-r--r-- | drivers/rtaudio/RtAudio.cpp | 74 | ||||
| -rw-r--r-- | drivers/rtaudio/RtAudio.h | 58 | ||||
| -rw-r--r-- | drivers/rtaudio/RtError.h | 60 | ||||
| -rw-r--r-- | modules/gdscript/gd_parser.cpp | 11 | ||||
| -rw-r--r-- | platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java | 172 | ||||
| -rw-r--r-- | platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java | 335 | ||||
| -rw-r--r-- | platform/x11/detect.py | 5 | ||||
| -rw-r--r-- | platform/x11/joystick_linux.cpp | 4 | ||||
| -rw-r--r-- | platform/x11/key_mapping_x11.cpp | 1 | ||||
| -rw-r--r-- | platform/x11/os_x11.cpp | 183 | ||||
| -rw-r--r-- | scene/2d/parallax_layer.cpp | 19 | ||||
| -rw-r--r-- | scene/3d/immediate_geometry.cpp | 2 | ||||
| -rw-r--r-- | scene/3d/immediate_geometry.h | 4 | ||||
| -rw-r--r-- | scene/gui/color_picker.cpp | 3 | ||||
| -rw-r--r-- | scene/gui/file_dialog.cpp | 19 | ||||
| -rw-r--r-- | scene/gui/file_dialog.h | 2 | ||||
| -rw-r--r-- | scene/gui/graph_node.cpp | 5 | ||||
| -rw-r--r-- | scene/gui/item_list.cpp | 25 | ||||
| -rw-r--r-- | scene/gui/text_edit.cpp | 28 | ||||
| -rw-r--r-- | scene/gui/text_edit.h | 2 | ||||
| -rw-r--r-- | scene/main/viewport.cpp | 16 | ||||
| -rw-r--r-- | scene/resources/curve.cpp | 6 | ||||
| -rw-r--r-- | scene/resources/surface_tool.cpp | 1 | ||||
| -rw-r--r-- | tools/editor/animation_editor.cpp | 10 | ||||
| -rw-r--r-- | tools/editor/animation_editor.h | 2 | ||||
| -rw-r--r-- | tools/editor/code_editor.cpp | 5 | ||||
| -rw-r--r-- | tools/editor/editor_file_system.cpp | 2 | ||||
| -rw-r--r-- | tools/editor/editor_node.cpp | 18 | ||||
| -rw-r--r-- | tools/editor/editor_node.h | 3 | ||||
| -rw-r--r-- | tools/editor/editor_settings.cpp | 4 | ||||
| -rw-r--r-- | tools/editor/filesystem_dock.cpp | 10 | ||||
| -rw-r--r-- | tools/editor/icons/2x/icon_group.png | bin | 782 -> 207 bytes | |||
| -rw-r--r-- | tools/editor/icons/2x/icon_object.png | bin | 675 -> 500 bytes | |||
| -rw-r--r-- | tools/editor/icons/2x/icon_ungroup.png | bin | 300 -> 202 bytes | |||
| -rw-r--r-- | tools/editor/icons/icon_group.png | bin | 406 -> 177 bytes | |||
| -rw-r--r-- | tools/editor/icons/icon_object.png | bin | 440 -> 354 bytes | |||
| -rw-r--r-- | tools/editor/icons/icon_ungroup.png | bin | 176 -> 170 bytes | |||
| -rw-r--r-- | tools/editor/icons/source/icon_group.svg | 1057 | ||||
| -rw-r--r-- | tools/editor/icons/source/icon_object.svg | 31 | ||||
| -rw-r--r-- | tools/editor/icons/source/icon_ungroup.svg | 75 | ||||
| -rw-r--r-- | tools/editor/io_plugins/editor_mesh_import_plugin.cpp | 1 | ||||
| -rw-r--r-- | tools/editor/plugins/animation_player_editor_plugin.cpp | 15 | ||||
| -rw-r--r-- | tools/editor/plugins/texture_region_editor_plugin.cpp | 14 | ||||
| -rw-r--r-- | tools/editor/project_manager.cpp | 134 | ||||
| -rw-r--r-- | tools/editor/project_manager.h | 1 | ||||
| -rw-r--r-- | tools/editor/resources_dock.cpp | 4 | ||||
| -rw-r--r-- | tools/editor/scene_tree_dock.cpp | 29 | ||||
| -rw-r--r-- | tools/editor/scene_tree_dock.h | 4 |
583 files changed, 32726 insertions, 21029 deletions
diff --git a/core/array.cpp b/core/array.cpp index bb8e527304..23792f90fc 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -200,6 +200,10 @@ int Array::count(const Variant& p_value) const { return amount; } +bool Array::has(const Variant& p_value) const { + return _p->array.find(p_value, 0) != -1; +} + void Array::remove(int p_pos) { _p->array.remove(p_pos); diff --git a/core/array.h b/core/array.h index 096660653e..dfc902525c 100644 --- a/core/array.h +++ b/core/array.h @@ -75,6 +75,7 @@ public: int rfind(const Variant& p_value, int p_from=-1) const; int find_last(const Variant& p_value) const; int count(const Variant& p_value) const; + bool has(const Variant& p_value) const; void erase(const Variant& p_value); diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index e56684dc5e..3e2f8ff263 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -894,6 +894,17 @@ void _OS::print_resources_by_type(const Vector<String>& p_types) { }; +bool _OS::has_virtual_keyboard() const { + return OS::get_singleton()->has_virtual_keyboard(); +} + +void _OS::show_virtual_keyboard(const String& p_existing_text) { + OS::get_singleton()->show_virtual_keyboard(p_existing_text, Rect2()); +} + +void _OS::hide_virtual_keyboard() { + OS::get_singleton()->hide_virtual_keyboard(); +} void _OS::print_all_resources(const String& p_to_file ) { @@ -1123,6 +1134,9 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("dump_memory_to_file","file"),&_OS::dump_memory_to_file); ObjectTypeDB::bind_method(_MD("dump_resources_to_file","file"),&_OS::dump_resources_to_file); + ObjectTypeDB::bind_method(_MD("has_virtual_keyboard"),&_OS::has_virtual_keyboard); + ObjectTypeDB::bind_method(_MD("show_virtual_keyboard", "existing_text"),&_OS::show_virtual_keyboard,DEFVAL("")); + ObjectTypeDB::bind_method(_MD("hide_virtual_keyboard"),&_OS::hide_virtual_keyboard); ObjectTypeDB::bind_method(_MD("print_resources_in_use","short"),&_OS::print_resources_in_use,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("print_all_resources","tofile"),&_OS::print_all_resources,DEFVAL("")); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 9ca439a454..14203ae863 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -205,6 +205,10 @@ public: void dump_memory_to_file(const String& p_file); void dump_resources_to_file(const String& p_file); + bool has_virtual_keyboard() const; + void show_virtual_keyboard(const String& p_existing_text=""); + void hide_virtual_keyboard(); + void print_resources_in_use(bool p_short=false); void print_all_resources(const String& p_to_file); void print_all_textures_by_size(); diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 05bad97e90..ac6c00dc61 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -51,7 +51,7 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom Error err; f=FileAccess::open(p_file,FileAccess::READ,&err); if (!f) { - print_line("ERROR OPENING FILE: "+p_file); + ERR_PRINTS("Error opening file: "+p_file); return err; } } @@ -76,7 +76,6 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom } - print_line("NO LOADER?"); if (!p_custom) memdelete(f); diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp index 5b767212f5..790903eff5 100644 --- a/core/math/geometry.cpp +++ b/core/math/geometry.cpp @@ -629,7 +629,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro // create and initialize cells to zero - print_line("Wrapper: Initializing Cells"); + //print_line("Wrapper: Initializing Cells"); uint8_t ***cell_status=memnew_arr(uint8_t**,div_x); for(int i=0;i<div_x;i++) { @@ -648,7 +648,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro } // plot faces into cells - print_line("Wrapper (1/6): Plotting Faces"); + //print_line("Wrapper (1/6): Plotting Faces"); for (int i=0;i<face_count;i++) { @@ -663,7 +663,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro // determine which cells connect to the outside by traversing the outside and recursively flood-fill marking - print_line("Wrapper (2/6) Flood Filling"); + //print_line("Wrapper (2/6): Flood Filling"); for (int i=0;i<div_x;i++) { @@ -694,7 +694,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro // build faces for the inside-outside cell divisors - print_line("Wrapper (3/6): Building Faces"); + //print_line("Wrapper (3/6): Building Faces"); DVector<Face3> wrapped_faces; @@ -709,7 +709,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro } } - print_line("Wrapper (4/6): Transforming Back Vertices"); + //print_line("Wrapper (4/6): Transforming Back Vertices"); // transform face vertices to global coords @@ -728,7 +728,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro } // clean up grid - print_line("Wrapper (5/6): Grid Cleanup"); + //print_line("Wrapper (5/6): Grid Cleanup"); for(int i=0;i<div_x;i++) { @@ -744,7 +744,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro if (p_error) *p_error=voxelsize.length(); - print_line("Wrapper (6/6): Finished."); + //print_line("Wrapper (6/6): Finished."); return wrapped_faces; } diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp index 5f97df39a6..4998263961 100644 --- a/core/object_type_db.cpp +++ b/core/object_type_db.cpp @@ -828,7 +828,7 @@ MethodBind* ObjectTypeDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , c TypeInfo *type=types.getptr(instance_type); if (!type) { - print_line("couldn't bind method "+mdname+" for instance: "+instance_type); + ERR_PRINTS("Couldn't bind method '"+mdname+"' for instance: "+instance_type); memdelete(p_bind); ERR_FAIL_COND_V(!type,NULL); } diff --git a/core/os/os.cpp b/core/os/os.cpp index 284bcb30cb..5f86962048 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -209,18 +209,15 @@ bool OS::has_virtual_keyboard() const { return false; } -void OS::show_virtual_keyboard(const String& p_existing_text,const Rect2& p_screen_rect) { - +void OS::show_virtual_keyboard(const String& p_existing_text,const Rect2& p_screen_rect) { } void OS::hide_virtual_keyboard(){ - } - void OS::print_all_resources(String p_to_file) { ERR_FAIL_COND(p_to_file!="" && _OSPRF); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 7da4cef115..7956c14c2c 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -474,6 +474,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM2R(Array,rfind); VCALL_LOCALMEM1R(Array,find_last); VCALL_LOCALMEM1R(Array,count); + VCALL_LOCALMEM1R(Array,has); VCALL_LOCALMEM1(Array,erase); VCALL_LOCALMEM0(Array,sort); VCALL_LOCALMEM2(Array,sort_custom); @@ -1516,6 +1517,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC2(ARRAY,INT,Array,rfind,NIL,"what",INT,"from",varray(-1)); ADDFUNC1(ARRAY,INT,Array,find_last,NIL,"value",varray()); ADDFUNC1(ARRAY,INT,Array,count,NIL,"value",varray()); + ADDFUNC1(ARRAY,BOOL,Array,has,NIL,"value",varray()); ADDFUNC0(ARRAY,NIL,Array,pop_back,varray()); ADDFUNC0(ARRAY,NIL,Array,pop_front,varray()); ADDFUNC0(ARRAY,NIL,Array,sort,varray()); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 9182dcde1a..c537ed230f 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -600,6 +600,7 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& case REAL: { _RETURN( *reinterpret_cast<const Quat*>(p_a._data._mem) * p_b._data._real); } break; + default: {} }; r_valid=false; return; @@ -618,6 +619,7 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& _RETURN( *p_a._data._matrix3 * *p_b._data._matrix3 ); }; + default: {} } ; r_valid=false; return; @@ -635,6 +637,7 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& _RETURN( *p_a._data._transform * *p_b._data._transform ); }; + default: {} } ; r_valid=false; return; @@ -999,7 +1002,7 @@ Variant Variant::get_named(const StringName& p_index, bool *r_valid) const { DEFAULT_OP_ARRAY_CMD(m_name, DVector<dv_type>, if(skip_cond) return;, arr->set(index, p_value);return) #define DEFAULT_OP_DVECTOR_GET(m_name, dv_type)\ - DEFAULT_OP_ARRAY_CMD(m_name, const DVector<dv_type>, 0, return arr->get(index)) + DEFAULT_OP_ARRAY_CMD(m_name, const DVector<dv_type>, ;, return arr->get(index)) void Variant::set(const Variant& p_index, const Variant& p_value, bool *r_valid) { @@ -2417,7 +2420,7 @@ Variant Variant::get(const Variant& p_index, bool *r_valid) const { return *res; } } break; // 20 - DEFAULT_OP_ARRAY_CMD(ARRAY, const Array, 0, return (*arr)[index]) + DEFAULT_OP_ARRAY_CMD(ARRAY, const Array, ;, return (*arr)[index]) DEFAULT_OP_DVECTOR_GET(RAW_ARRAY, uint8_t) DEFAULT_OP_DVECTOR_GET(INT_ARRAY, int) DEFAULT_OP_DVECTOR_GET(REAL_ARRAY, real_t) @@ -2994,6 +2997,7 @@ bool Variant::iter_init(Variant& r_iter,bool &valid) const { return true; } break; + default: {} } @@ -3137,6 +3141,7 @@ bool Variant::iter_next(Variant& r_iter,bool &valid) const { r_iter=idx; return true; } break; + default: {} } @@ -3279,6 +3284,7 @@ Variant Variant::iter_get(const Variant& r_iter,bool &r_valid) const { #endif return arr->get(idx); } break; + default: {} } diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 3f203170b3..4c2a0fe7ba 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -15688,9 +15688,14 @@ </class> <class name="ImmediateGeometry" inherits="GeometryInstance" category="Core"> <brief_description> + Node to draw simple geometry from code, ala OpenGL 1.x </brief_description> <description> </description> + ImmediateGeometry is a node used for displaying simple geometry created from code, very similar to how glBegin() and glEnd() worked in old versions of OpenGL (1.x). + Simply call [method begin()], and add vertices. For custom vertex colors, uvs, normal, etc. call one of the set_ functions below before adding each vertex. When done, call [method end] + Calls to begin/end are accumulative and all geometry is added together. To clear all the geometry, call [method clear]. + If a material override is set, and this material contains a texture, it's possible to override the texture used in this material for every begin/end set of calls. <methods> <method name="add_sphere"> <argument index="0" name="lats" type="int"> @@ -15700,12 +15705,14 @@ <argument index="2" name="radius" type="float"> </argument> <description> + Simple helper to draw an uvsphere, with given latitudes, longitude and radius. </description> </method> <method name="add_vertex"> <argument index="0" name="pos" type="Vector3"> </argument> <description> + Add a vertex with the currently set color/uv/etc. </description> </method> <method name="begin"> @@ -15714,44 +15721,53 @@ <argument index="1" name="texture" type="Texture"> </argument> <description> + Begin drawing (And optionally pass a texture override). When done call end(). For more information on how this works, search for glBegin() glEnd() references. + For the type of primitive, use the [Mesh].PRIMITIVE_* enumerations. </description> </method> <method name="clear"> <description> + Clear everything that was drawn using begin/end. </description> </method> <method name="end"> <description> + Call this when done adding a batch of geometry, otherwise it can't be displayed. </description> </method> <method name="set_color"> <argument index="0" name="color" type="Color"> </argument> <description> + Set the color that the next vertex will use to be drawn. </description> </method> <method name="set_normal"> <argument index="0" name="normal" type="Vector3"> </argument> <description> + Set the normal that the next vertex will use to be drawn. </description> </method> <method name="set_tangent"> <argument index="0" name="tangent" type="Plane"> </argument> <description> + Set the tangent (and binormal facing) that the next vertex will use to be drawn. </description> </method> <method name="set_uv"> <argument index="0" name="uv" type="Vector2"> </argument> <description> + Set the UV that the next vertex will use to be drawn. </description> </method> <method name="set_uv2"> <argument index="0" name="uv" type="Vector2"> </argument> <description> + Set the second layer of UV that the next vertex will use to be drawn. </description> </method> </methods> @@ -22721,6 +22737,18 @@ <description> </description> </method> + <method name="has_virtual_keyboard" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns true if the platform has a virtual keyboard, false otherwise. + </description> + </method> + <method name="hide_virtual_keyboard"> + <description> + Hides the virtual keyboard if it is shown, does nothing otherwise. + </description> + </method> <method name="is_debug_build" qualifiers="const"> <return type="bool"> </return> @@ -23038,6 +23066,13 @@ <description> </description> </method> + <method name="show_virtual_keyboard"> + <argument index="0" name="existing_text" type="String"> + </argument> + <description> + Shows the virtual keyboard if the platform has one. The [i]existing_text[/i] parameter is useful for implementing your own LineEdit, as it tells the virtual keyboard what text has already been typed (the virtual keyboard uses it for auto-correct and predictions). + </description> + </method> </methods> <constants> <constant name="DAY_SUNDAY" value="0"> @@ -31099,24 +31134,29 @@ Simple regular expression matcher. </brief_description> <description> - Class for finding text patterns in a string using regular expressions. Regular expressions are a way to define patterns of text to be searched. - This class only finds patterns in a string. It can not perform replacements. - Usage of regular expressions is too long to be explained here, but Internet is full of tutorials and detailed explanations. + Class for finding text patterns in a string using regular expressions. It can not perform replacements. Regular expressions are a way to define patterns of text to be searched. Details on writing patterns are too long to explain here but the Internet is full of tutorials and detailed explanations. + Once created, the RegEx object needs to be compiled with the pattern before it can be used. The pattern must be escaped first for gdscript before it is escaped for the expression. For example: + [code]var exp = RegEx.new()[/code] + [code]exp.compile("\\d+")[/code] + would be read by RegEx as [code]\d+[/code] + Similarly: + [code]exp.compile("\"(?:\\\\.|[^\"])*\"")[/code] + would be read as [code]"(?:\\.|[^"])*"[/code] Currently supported features: - Capturing [code]()[/code] and non-capturing [code](?:)[/code] groups - Any character [code].[/code] - Shorthand character classes [code]\w \W \s \S \d \D[/code] - User-defined character classes such as [code][A-Za-z][/code] - Simple quantifiers [code]?[/code], [code]*[/code] and [code]+[/code] - Range quantifiers [code]{x,y}[/code] - Lazy (non-greedy) quantifiers [code]*?[/code] - Beginning [code]^[/code] and end [code]$[/code] anchors - Alternation [code]|[/code] - Backreferences [code]\1[/code] and [code]\g{1}[/code] - POSIX character classes [code][[:alnum:]][/code] - Lookahead [code](?=)[/code], [code](?!)[/code] and lookbehind [code](?<=)[/code], [code](?<!)[/code] - ASCII [code]\xFF[/code] and Unicode [code]\uFFFF[/code] code points (in a style similar to Python) - Word boundaries [code]\b[/code], [code]\B[/code] + * Capturing [code]()[/code] and non-capturing [code](?:)[/code] groups + * Any character [code].[/code] + * Shorthand character classes [code]\w \W \s \S \d \D[/code] + * User-defined character classes such as [code][A-Za-z][/code] + * Simple quantifiers [code]?[/code], [code]*[/code] and [code]+[/code] + * Range quantifiers [code]{x,y}[/code] + * Lazy (non-greedy) quantifiers [code]*?[/code] + * Beginning [code]^[/code] and end [code]$[/code] anchors + * Alternation [code]|[/code] + * Backreferences [code]\1[/code] and [code]\g{1}[/code] + * POSIX character classes [code][[:alnum:]][/code] + * Lookahead [code](?=)[/code], [code](?!)[/code] and lookbehind [code](?<=)[/code], [code](?<!)[/code] + * ASCII [code]\xFF[/code] and Unicode [code]\uFFFF[/code] code points (in a style similar to Python) + * Word boundaries [code]\b[/code], [code]\B[/code] </description> <methods> <method name="clear"> @@ -34120,28 +34160,28 @@ <return type="bool"> </return> <description> - Return true if horizontal scrool is allowed. + Return true if horizontal scroll is allowed. </description> </method> <method name="is_v_scroll_enabled" qualifiers="const"> <return type="bool"> </return> <description> - Return true if vertical scrool is allowed. + Return true if vertical scroll is allowed. </description> </method> <method name="set_enable_h_scroll"> <argument index="0" name="enable" type="bool"> </argument> <description> - Set allows horizontal scrool. + Set allows horizontal scroll. </description> </method> <method name="set_enable_v_scroll"> <argument index="0" name="enable" type="bool"> </argument> <description> - Set allows vertical scrool. + Set allows vertical scroll. </description> </method> <method name="set_h_scroll"> diff --git a/drivers/builtin_zlib/zlib/compress.c b/drivers/builtin_zlib/zlib/compress.c index ea4dfbe9d7..6e9762676a 100644 --- a/drivers/builtin_zlib/zlib/compress.c +++ b/drivers/builtin_zlib/zlib/compress.c @@ -29,7 +29,7 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) z_stream stream; int err; - stream.next_in = (Bytef*)source; + stream.next_in = (z_const Bytef *)source; stream.avail_in = (uInt)sourceLen; #ifdef MAXSEG_64K /* Check for source > 64K on 16-bit machine: */ diff --git a/drivers/builtin_zlib/zlib/deflate.c b/drivers/builtin_zlib/zlib/deflate.c index 9e4c2cbc8a..696957705b 100644 --- a/drivers/builtin_zlib/zlib/deflate.c +++ b/drivers/builtin_zlib/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.7 Copyright 1995-2012 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -305,7 +305,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + strm->msg = ERR_MSG(Z_MEM_ERROR); deflateEnd (strm); return Z_MEM_ERROR; } @@ -329,7 +329,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) uInt str, n; int wrap; unsigned avail; - unsigned char *next; + z_const unsigned char *next; if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) return Z_STREAM_ERROR; @@ -359,7 +359,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) avail = strm->avail_in; next = strm->next_in; strm->avail_in = dictLength; - strm->next_in = (Bytef *)dictionary; + strm->next_in = (z_const Bytef *)dictionary; fill_window(s); while (s->lookahead >= MIN_MATCH) { str = s->strstart; @@ -513,6 +513,8 @@ int ZEXPORT deflateParams(strm, level, strategy) strm->total_in != 0) { /* Flush the last buffer: */ err = deflate(strm, Z_BLOCK); + if (err == Z_BUF_ERROR && s->pending == 0) + err = Z_OK; } if (s->level != level) { s->level = level; diff --git a/drivers/builtin_zlib/zlib/deflate.h b/drivers/builtin_zlib/zlib/deflate.h index fbac44d908..ce0299edd1 100644 --- a/drivers/builtin_zlib/zlib/deflate.h +++ b/drivers/builtin_zlib/zlib/deflate.h @@ -104,7 +104,7 @@ typedef struct internal_state { int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ gz_headerp gzhead; /* gzip header information to write */ uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ + Byte method; /* can only be DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ diff --git a/drivers/builtin_zlib/zlib/infback.c b/drivers/builtin_zlib/zlib/infback.c index 981aff17c2..f3833c2e43 100644 --- a/drivers/builtin_zlib/zlib/infback.c +++ b/drivers/builtin_zlib/zlib/infback.c @@ -255,7 +255,7 @@ out_func out; void FAR *out_desc; { struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ + z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ diff --git a/drivers/builtin_zlib/zlib/inffast.c b/drivers/builtin_zlib/zlib/inffast.c index 2f1d60b43b..bda59ceb6a 100644 --- a/drivers/builtin_zlib/zlib/inffast.c +++ b/drivers/builtin_zlib/zlib/inffast.c @@ -1,5 +1,5 @@ /* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010 Mark Adler + * Copyright (C) 1995-2008, 2010, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -69,8 +69,8 @@ z_streamp strm; unsigned start; /* inflate()'s starting value for strm->avail_out */ { struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *end; /* while out < end, enough space available */ diff --git a/drivers/builtin_zlib/zlib/inflate.c b/drivers/builtin_zlib/zlib/inflate.c index 47418a1e1e..870f89bb4d 100644 --- a/drivers/builtin_zlib/zlib/inflate.c +++ b/drivers/builtin_zlib/zlib/inflate.c @@ -93,11 +93,12 @@ /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); +local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, + unsigned copy)); #ifdef BUILDFIXED void makefixed OF((void)); #endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, +local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, unsigned len)); int ZEXPORT inflateResetKeep(strm) @@ -375,12 +376,13 @@ void makefixed() output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ -local int updatewindow(strm, out) +local int updatewindow(strm, end, copy) z_streamp strm; -unsigned out; +const Bytef *end; +unsigned copy; { struct inflate_state FAR *state; - unsigned copy, dist; + unsigned dist; state = (struct inflate_state FAR *)strm->state; @@ -400,19 +402,18 @@ unsigned out; } /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + zmemcpy(state->window, end - state->wsize, state->wsize); state->wnext = 0; state->whave = state->wsize; } else { dist = state->wsize - state->wnext; if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + zmemcpy(state->window + state->wnext, end - copy, dist); copy -= dist; if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); + zmemcpy(state->window, end - copy, copy); state->wnext = copy; state->whave = state->wsize; } @@ -606,7 +607,7 @@ z_streamp strm; int flush; { struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ + z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ @@ -920,7 +921,7 @@ int flush; while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; - state->lencode = (code const FAR *)(state->next); + state->lencode = (const code FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); @@ -994,7 +995,7 @@ int flush; values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; - state->lencode = (code const FAR *)(state->next); + state->lencode = (const code FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); @@ -1003,7 +1004,7 @@ int flush; state->mode = BAD; break; } - state->distcode = (code const FAR *)(state->next); + state->distcode = (const code FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); @@ -1230,7 +1231,7 @@ int flush; RESTORE(); if (state->wsize || (out != strm->avail_out && state->mode < BAD && (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, out)) { + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; } @@ -1264,6 +1265,29 @@ z_streamp strm; return Z_OK; } +int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) +z_streamp strm; +Bytef *dictionary; +uInt *dictLength; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; @@ -1271,8 +1295,6 @@ uInt dictLength; { struct inflate_state FAR *state; unsigned long dictid; - unsigned char *next; - unsigned avail; int ret; /* check state */ @@ -1291,13 +1313,7 @@ uInt dictLength; /* copy dictionary to window using updatewindow(), which will amend the existing dictionary if appropriate */ - next = strm->next_out; - avail = strm->avail_out; - strm->next_out = (Bytef *)dictionary + dictLength; - strm->avail_out = 0; - ret = updatewindow(strm, dictLength); - strm->avail_out = avail; - strm->next_out = next; + ret = updatewindow(strm, dictionary + dictLength, dictLength); if (ret) { state->mode = MEM; return Z_MEM_ERROR; @@ -1337,7 +1353,7 @@ gz_headerp head; */ local unsigned syncsearch(have, buf, len) unsigned FAR *have; -unsigned char FAR *buf; +const unsigned char FAR *buf; unsigned len; { unsigned got; diff --git a/drivers/builtin_zlib/zlib/inftrees.c b/drivers/builtin_zlib/zlib/inftrees.c index abcd7c45ed..44d89cf24e 100644 --- a/drivers/builtin_zlib/zlib/inftrees.c +++ b/drivers/builtin_zlib/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2012 Mark Adler + * Copyright (C) 1995-2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.7 Copyright 1995-2012 Mark Adler "; + " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -62,7 +62,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 78, 68}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, @@ -208,8 +208,8 @@ unsigned short FAR *work; mask = used - 1; /* mask for comparing low */ /* check available table space */ - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) return 1; /* process all codes and make table entries */ @@ -277,8 +277,8 @@ unsigned short FAR *work; /* check for enough space */ used += 1U << curr; - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) return 1; /* point entry in root table to sub-table */ diff --git a/drivers/builtin_zlib/zlib/trees.c b/drivers/builtin_zlib/zlib/trees.c index 8c32b214b1..1fd7759ef0 100644 --- a/drivers/builtin_zlib/zlib/trees.c +++ b/drivers/builtin_zlib/zlib/trees.c @@ -146,8 +146,8 @@ local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); local int build_bl_tree OF((deflate_state *s)); local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); +local void compress_block OF((deflate_state *s, const ct_data *ltree, + const ct_data *dtree)); local int detect_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); @@ -972,7 +972,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { #endif send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); #ifdef DEBUG s->compressed_len += 3 + s->static_len; #endif @@ -980,7 +981,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) send_bits(s, (DYN_TREES<<1)+last, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); #ifdef DEBUG s->compressed_len += 3 + s->opt_len; #endif @@ -1057,8 +1059,8 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc) */ local void compress_block(s, ltree, dtree) deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ + const ct_data *ltree; /* literal tree */ + const ct_data *dtree; /* distance tree */ { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ diff --git a/drivers/builtin_zlib/zlib/uncompr.c b/drivers/builtin_zlib/zlib/uncompr.c index ad98be3a5d..242e9493df 100644 --- a/drivers/builtin_zlib/zlib/uncompr.c +++ b/drivers/builtin_zlib/zlib/uncompr.c @@ -30,7 +30,7 @@ int ZEXPORT uncompress (dest, destLen, source, sourceLen) z_stream stream; int err; - stream.next_in = (Bytef*)source; + stream.next_in = (z_const Bytef *)source; stream.avail_in = (uInt)sourceLen; /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; diff --git a/drivers/builtin_zlib/zlib/zconf.h b/drivers/builtin_zlib/zlib/zconf.h index fbf0f03bae..f44af82fc2 100644 --- a/drivers/builtin_zlib/zlib/zconf.h +++ b/drivers/builtin_zlib/zlib/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2012 Jean-loup Gailly. + * Copyright (C) 1995-2013 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -14,10 +14,10 @@ * Even better than compiling with -DZ_PREFIX would be to use configure to set * this permanently in zconf.h using "./configure --zprefix". */ - + #define Z_PREFIX #define Z_SOLO - + #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ # define Z_PREFIX_SET @@ -25,6 +25,7 @@ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits # define _tr_flush_block z__tr_flush_block # define _tr_init z__tr_init # define _tr_stored_block z__tr_stored_block @@ -81,6 +82,7 @@ # define gzopen_w z_gzopen_w # endif # define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf # define gzputc z_gzputc # define gzputs z_gzputs # define gzread z_gzread @@ -107,6 +109,7 @@ # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 # define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine @@ -392,20 +395,14 @@ typedef uLong FAR uLongf; typedef Byte *voidp; #endif -/* ./configure may #define Z_U4 here */ - #if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) # include <limits.h> # if (UINT_MAX == 0xffffffffUL) # define Z_U4 unsigned -# else -# if (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# else -# if (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -# endif +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short # endif #endif @@ -429,10 +426,16 @@ typedef uLong FAR uLongf; # endif #endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include <stdarg.h> /* for va_list */ +# endif +#endif + #ifdef _WIN32 -# ifndef Z_SOLO -# include <stddef.h> /* for wchar_t */ -# endif +# ifndef Z_SOLO +# include <stddef.h> /* for wchar_t */ +# endif #endif /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and @@ -441,7 +444,7 @@ typedef uLong FAR uLongf; * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as * equivalently requesting no 64-bit operations */ -#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 # undef _LARGEFILE64_SOURCE #endif @@ -449,7 +452,7 @@ typedef uLong FAR uLongf; # define Z_HAVE_UNISTD_H #endif #ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE) +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) # include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ # ifdef VMS # include <unixio.h> /* for off_t */ diff --git a/drivers/builtin_zlib/zlib/zconf.in.h b/drivers/builtin_zlib/zlib/zconf.in.h deleted file mode 100644 index 03a9431c8b..0000000000 --- a/drivers/builtin_zlib/zlib/zconf.in.h +++ /dev/null @@ -1,332 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include <windows.h> - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include <sys/types.h> /* for off_t */ -# include <unistd.h> /* for SEEK_* and off_t */ -# ifdef VMS -# include <unixio.h> /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/drivers/builtin_zlib/zlib/zlib.h b/drivers/builtin_zlib/zlib/zlib.h index 3edf3acdb5..3e0c7672ac 100644 --- a/drivers/builtin_zlib/zlib/zlib.h +++ b/drivers/builtin_zlib/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.7, May 2nd, 2012 + version 1.2.8, April 28th, 2013 - Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.7" -#define ZLIB_VERNUM 0x1270 +#define ZLIB_VERSION "1.2.8" +#define ZLIB_VERNUM 0x1280 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 7 +#define ZLIB_VER_REVISION 8 #define ZLIB_VER_SUBREVISION 0 /* @@ -839,6 +839,21 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflate(). */ +ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* Skips invalid compressed data until a possible full flush point (see above @@ -846,7 +861,7 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); available input is skipped. No output is provided. inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurences of this + All full flush points have this pattern, but not all occurrences of this pattern are full flush points. inflateSync returns Z_OK if a possible full flush point has been found, @@ -1007,7 +1022,8 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, the version of the header file. */ -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef unsigned (*in_func) OF((void FAR *, + z_const unsigned char FAR * FAR *)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, @@ -1015,11 +1031,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, out_func out, void FAR *out_desc)); /* inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. @@ -1736,6 +1753,13 @@ ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, const char *mode)); #endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif #ifdef __cplusplus } diff --git a/drivers/builtin_zlib/zlib/zutil.c b/drivers/builtin_zlib/zlib/zutil.c index 65e0d3b72b..23d2ebef00 100644 --- a/drivers/builtin_zlib/zlib/zutil.c +++ b/drivers/builtin_zlib/zlib/zutil.c @@ -14,7 +14,7 @@ struct internal_state {int dummy;}; /* for buggy compilers */ #endif -const char * const z_errmsg[10] = { +z_const char * const z_errmsg[10] = { "need dictionary", /* Z_NEED_DICT 2 */ "stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */ diff --git a/drivers/builtin_zlib/zlib/zutil.h b/drivers/builtin_zlib/zlib/zutil.h index 4e3dcc6ae9..24ab06b1cf 100644 --- a/drivers/builtin_zlib/zlib/zutil.h +++ b/drivers/builtin_zlib/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2012 Jean-loup Gailly. + * Copyright (C) 1995-2013 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -44,13 +44,13 @@ typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) + return (strm->msg = ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ @@ -168,7 +168,8 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif /* provide prototypes for these when building zlib without LFS */ -#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); #endif diff --git a/drivers/etc1/rg_etc1.cpp b/drivers/etc1/rg_etc1.cpp index 47dcb57e6b..8e28b53f9d 100644 --- a/drivers/etc1/rg_etc1.cpp +++ b/drivers/etc1/rg_etc1.cpp @@ -4,15 +4,19 @@ // For more information Ericsson Texture Compression (ETC/ETC1), see: // http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt // +// v1.04 - 5/15/14 - Fix signed vs. unsigned subtraction problem (noticed when compiled with gcc) in pack_etc1_block_init(). +// This issue would cause an assert when this func. was called in debug. (Note this module was developed/testing with MSVC, +// I still need to test it throughly when compiled with gcc.) +// // v1.03 - 5/12/13 - Initial public release #include "rg_etc1.h" #include <stdlib.h> -#include <string.h> +#include <memory.h> #include <assert.h> //#include <stdio.h> #include <math.h> -#include <stdio.h> + #pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union #if defined(_DEBUG) || defined(DEBUG) @@ -23,16 +27,6 @@ namespace rg_etc1 { - - inline long labs(long val) { - return val < 0 ? -val : val; - } - - inline int intabs(int val) { - - return val<0?-val:val; - } - typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint; @@ -372,7 +366,6 @@ namespace rg_etc1 static uint8 g_quant5_tab[256+16]; - static const int g_etc1_inten_tables[cETC1IntenModifierValues][cETC1SelectorValues] = { { -8, -2, 2, 8 }, { -17, -5, 5, 17 }, { -29, -9, 9, 29 }, { -42, -13, 13, 42 }, @@ -437,7 +430,7 @@ namespace rg_etc1 0x0428, 0x071C, 0x0735, 0x0E05, 0x0C17, 0xFFFF }, { 0x0520, 0x0A23, 0x0927, 0xFFFF }, { 0x0B11, 0x1209, 0x013B, 0x052F, 0xFFFF }, { 0x0616, 0x081E, 0x0D19, 0xFFFF }, { 0x0522, 0x0704, 0x0A0A, 0x0A31, 0x0D03, 0x0C15, 0x1007, 0x082B, 0x072D, 0x0F1D, 0xFFFF }, { 0x0C01, 0x0933, 0x0A25, 0x0637, 0x0E1B, 0xFFFF }, { 0x042A, 0x0B21, 0x0929, 0x180D, 0xFFFF }, { - 0x0530, 0x0614, 0x0336, 0x0908, 0x0439, 0x150B, 0x111F, 0xFFFF }, { 0x0600, 0x0524, 0x0806, 0x0238, 0x0C13, 0x0F05, + 0x0530, 0x0614, 0x0336, 0x0908, 0x0439, 0x150B, 0x111F, 0xFFFF }, { 0x0600, 0x0524, 0x0806, 0x0238, 0x0C13, 0x0F05, 0x0D17, 0xFFFF }, { 0x071A, 0x0B23, 0x0835, 0x0A27, 0xFFFF }, { 0x1309, 0x023B, 0x062F, 0xFFFF }, { 0x0612, 0x0434, 0x013A, 0x0C11, 0x0E19, 0xFFFF }, { 0x0526, 0x0C0C, 0x032E, 0x0B31, 0x0E03, 0x0D15, 0x1107, 0x092B, 0xFFFF }, { 0x0D01, 0x0A33, 0x0B25, 0x0737, 0x0F1B, 0x082D, 0x101D, 0xFFFF }, { 0x0610, 0x0A29, 0x190D, 0xFFFF }, { 0x0718, 0x042C, 0x0C21, @@ -1810,7 +1803,7 @@ namespace rg_etc1 { if (block_inten[0] > m_pSorted_luma[n - 1]) { - const uint min_error = intabs(block_inten[0] - m_pSorted_luma[n - 1]); + const uint min_error = labs(block_inten[0] - m_pSorted_luma[n - 1]); if (min_error >= trial_solution.m_error) continue; } @@ -1824,7 +1817,7 @@ namespace rg_etc1 { if (m_pSorted_luma[0] > block_inten[3]) { - const uint min_error = intabs(m_pSorted_luma[0] - block_inten[3]); + const uint min_error = labs(m_pSorted_luma[0] - block_inten[3]); if (min_error >= trial_solution.m_error) continue; } @@ -1917,7 +1910,6 @@ done: { int v = etc1_decode_value(diff, inten, selector, packed_c); uint err = labs(v - static_cast<int>(color)); - //printf("err: %d - %u = %u\n",v,color,err); if (err < best_error) { best_error = err; @@ -2370,7 +2362,7 @@ found_perfect_match: int dr = best_results[1].m_block_color_unscaled.r - best_results[0].m_block_color_unscaled.r; int dg = best_results[1].m_block_color_unscaled.g - best_results[0].m_block_color_unscaled.g; int db = best_results[1].m_block_color_unscaled.b - best_results[0].m_block_color_unscaled.b; - RG_ETC1_ASSERT(best_use_color4 || ((rg_etc1::minimum(dr, dg, db) >= cETC1ColorDeltaMin) && (rg_etc1::maximum(dr, dg, db) <= cETC1ColorDeltaMax))); + RG_ETC1_ASSERT(best_use_color4 || (rg_etc1::minimum(dr, dg, db) >= cETC1ColorDeltaMin) && (rg_etc1::maximum(dr, dg, db) <= cETC1ColorDeltaMax)); if (best_use_color4) { diff --git a/drivers/freetype/SCsub b/drivers/freetype/SCsub index c0921c683a..0c7ab91ba2 100644 --- a/drivers/freetype/SCsub +++ b/drivers/freetype/SCsub @@ -1,59 +1,58 @@ Import('env') ft_sources=[\ -"freetype/src/pfr/pfr.c",\ -"freetype/src/psaux/psaux.c",\ -"freetype/src/pcf/pcf.c",\ -"freetype/src/otvalid/otvalid.c",\ -"freetype/src/raster/raster.c",\ -"freetype/src/type1/type1.c",\ -"freetype/src/pshinter/pshinter.c",\ -"freetype/src/cff/cff.c",\ -"freetype/src/truetype/truetype.c",\ -"freetype/src/bdf/bdf.c",\ -"freetype/src/cache/ftcache.c",\ -"freetype/src/sfnt/sfnt.c",\ -"freetype/src/winfonts/winfnt.c",\ -"freetype/src/psnames/psnames.c",\ -"freetype/src/cid/type1cid.c",\ -"freetype/src/autofit/autofit.c",\ -"freetype/src/gxvalid/gxvalid.c",\ -"freetype/src/smooth/smooth.c",\ -"freetype/src/type42/type42.c",\ -"freetype/src/base/ftapi.c",\ -"freetype/src/base/ftbase.c",\ -"freetype/src/base/ftbbox.c",\ -"freetype/src/base/ftbdf.c",\ -"freetype/src/base/ftbitmap.c",\ -"freetype/src/base/ftcid.c",\ -"freetype/src/base/ftdebug.c",\ -"freetype/src/base/ftfstype.c",\ -"freetype/src/base/ftgasp.c",\ -"freetype/src/base/ftglyph.c",\ -"freetype/src/base/ftgxval.c",\ -"freetype/src/base/ftinit.c",\ -"freetype/src/base/ftlcdfil.c",\ -"freetype/src/base/ftmm.c",\ -"freetype/src/base/ftotval.c",\ -"freetype/src/base/ftpatent.c",\ -"freetype/src/base/ftpfr.c",\ -"freetype/src/base/ftpic.c",\ -"freetype/src/base/ftstroke.c",\ -"freetype/src/base/ftsynth.c",\ -"freetype/src/base/ftsystem.c",\ -"freetype/src/base/fttype1.c",\ -"freetype/src/base/ftwinfnt.c",\ -"freetype/src/base/ftxf86.c",\ - +"src/autofit/autofit.c",\ +"src/base/ftapi.c",\ +"src/base/ftbase.c",\ +"src/base/ftbbox.c",\ +"src/base/ftbdf.c",\ +"src/base/ftbitmap.c",\ +"src/base/ftcid.c",\ +"src/base/ftdebug.c",\ +"src/base/ftfntfmt.c",\ +"src/base/ftfstype.c",\ +"src/base/ftgasp.c",\ +"src/base/ftglyph.c",\ +"src/base/ftgxval.c",\ +"src/base/ftinit.c",\ +"src/base/ftlcdfil.c",\ +"src/base/ftmm.c",\ +"src/base/ftotval.c",\ +"src/base/ftpatent.c",\ +"src/base/ftpfr.c",\ +"src/base/ftpic.c",\ +"src/base/ftstroke.c",\ +"src/base/ftsynth.c",\ +"src/base/ftsystem.c",\ +"src/base/fttype1.c",\ +"src/base/ftwinfnt.c",\ +"src/bdf/bdf.c",\ +"src/cache/ftcache.c",\ +"src/cff/cff.c",\ +"src/cid/type1cid.c",\ +"src/gxvalid/gxvalid.c",\ +"src/otvalid/otvalid.c",\ +"src/pcf/pcf.c",\ +"src/pfr/pfr.c",\ +"src/psaux/psaux.c",\ +"src/pshinter/pshinter.c",\ +"src/psnames/psnames.c",\ +"src/raster/raster.c",\ +"src/sfnt/sfnt.c",\ +"src/smooth/smooth.c",\ +"src/truetype/truetype.c",\ +"src/type1/type1.c",\ +"src/type42/type42.c",\ +"src/winfonts/winfnt.c",\ ] if (env["freetype"]=="builtin"): -#fix for windows command line i too long, split in two libraries + # fix for Windows' shell miserably failing on long lines, split in two libraries half1=[] half2=[] for x in ft_sources: - if (x.find("freetype/src/base")==0): + if (x.find("src/base")==0 or x.find("src/sfnt")==0): half2.append(x) else: half1.append(x) @@ -63,9 +62,7 @@ if (env["freetype"]=="builtin"): lib = env.Library("freetype_builtin2",half1) env.Append(LIBS=[lib]) -# lib = env.Library("freetype_builtin",ft_sources) -# env.Prepend(LIBS=[lib]) - + env.Append(CPPPATH=["#drivers/freetype/include"]) Export('env') diff --git a/drivers/freetype/freetype/include/freetype/ftcffdrv.h b/drivers/freetype/freetype/include/freetype/ftcffdrv.h deleted file mode 100644 index ccbcbccaa8..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftcffdrv.h +++ /dev/null @@ -1,151 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcffdrv.h */ -/* */ -/* FreeType API for controlling the CFF driver (specification only). */ -/* */ -/* Copyright 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __FTCFFDRV_H__ -#define __FTCFFDRV_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /************************************************************************** - * - * @section: - * cff_driver - * - * @title: - * The CFF driver - * - * @abstract: - * Controlling the CFF driver module. - * - * @description: - * While FreeType's CFF driver doesn't expose API functions by itself, - * it is possible to control its behaviour with @FT_Property_Set and - * @FT_Property_Get. The following lists the available properties - * together with the necessary macros and structures. - * - * The CFF driver's module name is `cff'. - * - */ - - - /************************************************************************** - * - * @property: - * hinting-engine - * - * @description: - * Thanks to Adobe, which contributed a new hinting (and parsing) - * engine, an application can select between `freetype' and `adobe' if - * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration - * macro isn't defined, `hinting-engine' does nothing. - * - * The default engine is `freetype' if CFF_CONFIG_OPTION_OLD_ENGINE is - * defined, and `adobe' otherwise. - * - * The following example code demonstrates how to select Adobe's hinting - * engine (omitting the error handling). - * - * { - * FT_Library library; - * FT_Face face; - * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "cff", - * "hinting-engine", &hinting_engine ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - */ - - - /************************************************************************** - * - * @enum: - * FT_CFF_HINTING_XXX - * - * @description: - * A list of constants used for the @hinting-engine property to select - * the hinting engine for CFF fonts. - * - * @values: - * FT_CFF_HINTING_FREETYPE :: - * Use the old FreeType hinting engine. - * - * FT_CFF_HINTING_ADOBE :: - * Use the hinting engine contributed by Adobe. - * - */ -#define FT_CFF_HINTING_FREETYPE 0 -#define FT_CFF_HINTING_ADOBE 1 - - - /************************************************************************** - * - * @property: - * no-stem-darkening - * - * @description: - * By default, the Adobe CFF engine darkens stems at smaller sizes, - * regardless of hinting, to enhance contrast. Setting this property, - * stem darkening gets switched off. - * - * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set. - * - * { - * FT_Library library; - * FT_Face face; - * FT_Bool no_stem_darkening = TRUE; - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "cff", - * "no-stem-darkening", &no_stem_darkening ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - */ - - - /* */ - -FT_END_HEADER - - -#endif /* __FTCFFDRV_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftttdrv.h b/drivers/freetype/freetype/include/freetype/ftttdrv.h deleted file mode 100644 index d5d3f1ccc1..0000000000 --- a/drivers/freetype/freetype/include/freetype/ftttdrv.h +++ /dev/null @@ -1,150 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftttdrv.h */ -/* */ -/* FreeType API for controlling the TrueType driver */ -/* (specification only). */ -/* */ -/* Copyright 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __FTTTDRV_H__ -#define __FTTTDRV_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#ifdef FREETYPE_H -#error "freetype.h of FreeType 1 has been loaded!" -#error "Please fix the directory search order for header files" -#error "so that freetype.h of FreeType 2 is found first." -#endif - - -FT_BEGIN_HEADER - - - /************************************************************************** - * - * @section: - * tt_driver - * - * @title: - * The TrueType driver - * - * @abstract: - * Controlling the TrueType driver module. - * - * @description: - * While FreeType's TrueType driver doesn't expose API functions by - * itself, it is possible to control its behaviour with @FT_Property_Set - * and @FT_Property_Get. The following lists the available properties - * together with the necessary macros and structures. - * - * The TrueType driver's module name is `truetype'. - * - */ - - - /************************************************************************** - * - * @property: - * interpreter-version - * - * @description: - * Currently, two versions are available which represent the bytecode - * interpreter with and without subpixel hinting support, - * respectively. The default is subpixel support if - * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel - * support otherwise (since it isn't available then). - * - * If subpixel hinting is on, many TrueType bytecode instructions - * behave differently compared to B/W or grayscale rendering. The - * main idea is to render at a much increased horizontal resolution, - * then sampling down the created output to subpixel precision. - * However, many older fonts are not suited to this and must be - * specially taken care of by applying (hardcoded) font-specific - * tweaks. - * - * Details on subpixel hinting and some of the necessary tweaks can be - * found in Greg Hitchcock's whitepaper at - * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. - * - * The following example code demonstrates how to activate subpixel - * hinting (omitting the error handling). - * - * { - * FT_Library library; - * FT_Face face; - * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_38; - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "truetype", - * "interpreter-version", - * &interpreter_version ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - */ - - - /************************************************************************** - * - * @enum: - * TT_INTERPRETER_VERSION_XXX - * - * @description: - * A list of constants used for the @interpreter-version property to - * select the hinting engine for Truetype fonts. - * - * The numeric value in the constant names represents the version - * number as returned by the `GETINFO' bytecode instruction. - * - * @values: - * TT_INTERPRETER_VERSION_35 :: - * Version~35 corresponds to MS rasterizer v.1.7 as used e.g. in - * Windows~98; only grayscale and B/W rasterizing is supported. - * - * TT_INTERPRETER_VERSION_38 :: - * Version~38 corresponds to MS rasterizer v.1.9; it is roughly - * equivalent to the hinting provided by DirectWrite ClearType (as - * can be found, for example, in the Internet Explorer~9 running on - * Windows~7). - * - * @note: - * This property controls the behaviour of the bytecode interpreter - * and thus how outlines get hinted. It does *not* control how glyph - * get rasterized! In particular, it does not control subpixel color - * filtering. - * - * If FreeType has not been compiled with configuration option - * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 causes an - * `FT_Err_Unimplemented_Feature' error. - * - */ -#define TT_INTERPRETER_VERSION_35 35 -#define TT_INTERPRETER_VERSION_38 38 - - - /* */ - -FT_END_HEADER - - -#endif /* __FTTTDRV_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/include/ftoption.h b/drivers/freetype/freetype/include/ftoption.h deleted file mode 100644 index c9f4708691..0000000000 --- a/drivers/freetype/freetype/include/ftoption.h +++ /dev/null @@ -1,833 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoption.h (for development) */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __FTOPTION_H__ -#define __FTOPTION_H__ - - -#include <ft2build.h> - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /* */ - /* USER-SELECTABLE CONFIGURATION MACROS */ - /* */ - /* This file contains the default configuration macro definitions for */ - /* a standard build of the FreeType library. There are three ways to */ - /* use this file to build project-specific versions of the library: */ - /* */ - /* - You can modify this file by hand, but this is not recommended in */ - /* cases where you would like to build several versions of the */ - /* library from a single source directory. */ - /* */ - /* - You can put a copy of this file in your build directory, more */ - /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ - /* is the name of a directory that is included _before_ the FreeType */ - /* include path during compilation. */ - /* */ - /* The default FreeType Makefiles and Jamfiles use the build */ - /* directory `builds/<system>' by default, but you can easily change */ - /* that for your own projects. */ - /* */ - /* - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it */ - /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ - /* locate this file during the build. For example, */ - /* */ - /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ - /* #include <freetype/config/ftheader.h> */ - /* */ - /* will use `$BUILD/myftoptions.h' instead of this file for macro */ - /* definitions. */ - /* */ - /* Note also that you can similarly pre-define the macro */ - /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ - /* that are statically linked to the library at compile time. By */ - /* default, this file is <freetype/config/ftmodule.h>. */ - /* */ - /* We highly recommend using the third method whenever possible. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Uncomment the line below if you want to activate sub-pixel rendering */ - /* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ - /* */ - /* Note that this feature is covered by several Microsoft patents */ - /* and should not be activated in any default build of the library. */ - /* */ - /* This macro has no impact on the FreeType API, only on its */ - /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ - /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ - /* the original size in case this macro isn't defined; however, each */ - /* triplet of subpixels has R=G=B. */ - /* */ - /* This is done to allow FreeType clients to run unmodified, forcing */ - /* them to display normal gray-level anti-aliased glyphs. */ - /* */ -#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING - - - /*************************************************************************/ - /* */ - /* Many compilers provide a non-ANSI 64-bit data type that can be used */ - /* by FreeType to speed up some computations. However, this will create */ - /* some problems when compiling the library in strict ANSI mode. */ - /* */ - /* For this reason, the use of 64-bit integers is normally disabled when */ - /* the __STDC__ macro is defined. You can however disable this by */ - /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ - /* */ - /* For most compilers, this will only create compilation warnings when */ - /* building the library. */ - /* */ - /* ObNote: The compiler-specific 64-bit integers are detected in the */ - /* file `ftconfig.h' either statically or through the */ - /* `configure' script on supported platforms. */ - /* */ -#undef FT_CONFIG_OPTION_FORCE_INT64 - - - /*************************************************************************/ - /* */ - /* If this macro is defined, do not try to use an assembler version of */ - /* performance-critical functions (e.g. FT_MulFix). You should only do */ - /* that to verify that the assembler function works properly, or to */ - /* execute benchmark tests of the various implementations. */ -/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ - - - /*************************************************************************/ - /* */ - /* If this macro is defined, try to use an inlined assembler version of */ - /* the `FT_MulFix' function, which is a `hotspot' when loading and */ - /* hinting glyphs, and which should be executed as fast as possible. */ - /* */ - /* Note that if your compiler or CPU is not supported, this will default */ - /* to the standard and portable implementation found in `ftcalc.c'. */ - /* */ -#define FT_CONFIG_OPTION_INLINE_MULFIX - - - /*************************************************************************/ - /* */ - /* LZW-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `compress' program. This is mostly used to parse many of the PCF */ - /* files that come with various X11 distributions. The implementation */ - /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ - /* (see src/lzw/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#undef FT_CONFIG_OPTION_USE_LZW - - - /*************************************************************************/ - /* */ - /* Gzip-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `gzip' program. This is mostly used to parse many of the PCF files */ - /* that come with XFree86. The implementation uses `zlib' to */ - /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. See also */ - /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ - /* */ -#undef FT_CONFIG_OPTION_USE_ZLIB - - - /*************************************************************************/ - /* */ - /* ZLib library selection */ - /* */ - /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ - /* It allows FreeType's `ftgzip' component to link to the system's */ - /* installation of the ZLib library. This is useful on systems like */ - /* Unix or VMS where it generally is already available. */ - /* */ - /* If you let it undefined, the component will use its own copy */ - /* of the zlib sources instead. These have been modified to be */ - /* included directly within the component and *not* export external */ - /* function names. This allows you to link any program with FreeType */ - /* _and_ ZLib without linking conflicts. */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ - - - /*************************************************************************/ - /* */ - /* Bzip2-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `bzip2' program. This is mostly used to parse many of the PCF */ - /* files that come with XFree86. The implementation uses `libbz2' to */ - /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ - /* Contrary to gzip, bzip2 currently is not included and need to use */ - /* the system available bzip2 implementation. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#undef FT_CONFIG_OPTION_USE_BZIP2 - - - /*************************************************************************/ - /* */ - /* PNG bitmap support. */ - /* */ - /* FreeType now handles loading color bitmap glyphs in the PNG format. */ - /* This requires help from the external libpng library. Uncompressed */ - /* color bitmaps do not need any external libraries and will be */ - /* supported regardless of this configuration. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#undef FT_CONFIG_OPTION_USE_PNG - - - /*************************************************************************/ - /* */ - /* Define to disable the use of file stream functions and types, FILE, */ - /* fopen() etc. Enables the use of smaller system libraries on embedded */ - /* systems that have multiple system libraries, some with or without */ - /* file stream support, in the cases where file stream support is not */ - /* necessary such as memory loading of font files. */ - /* */ -/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ - - - /*************************************************************************/ - /* */ - /* DLL export compilation */ - /* */ - /* When compiling FreeType as a DLL, some systems/compilers need a */ - /* special keyword in front OR after the return type of function */ - /* declarations. */ - /* */ - /* Two macros are used within the FreeType source code to define */ - /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ - /* */ - /* FT_EXPORT( return_type ) */ - /* */ - /* is used in a function declaration, as in */ - /* */ - /* FT_EXPORT( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ); */ - /* */ - /* */ - /* FT_EXPORT_DEF( return_type ) */ - /* */ - /* is used in a function definition, as in */ - /* */ - /* FT_EXPORT_DEF( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ) */ - /* { */ - /* ... some code ... */ - /* return FT_Err_Ok; */ - /* } */ - /* */ - /* You can provide your own implementation of FT_EXPORT and */ - /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ - /* will be later automatically defined as `extern return_type' to */ - /* allow normal compilation. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_EXPORT(x) extern x */ -/* #define FT_EXPORT_DEF(x) x */ - - - /*************************************************************************/ - /* */ - /* Glyph Postscript Names handling */ - /* */ - /* By default, FreeType 2 is compiled with the `psnames' module. This */ - /* module is in charge of converting a glyph name string into a */ - /* Unicode value, or return a Macintosh standard glyph name for the */ - /* use with the TrueType `post' table. */ - /* */ - /* Undefine this macro if you do not want `psnames' compiled in your */ - /* build of FreeType. This has the following effects: */ - /* */ - /* - The TrueType driver will provide its own set of glyph names, */ - /* if you build it to support postscript names in the TrueType */ - /* `post' table. */ - /* */ - /* - The Type 1 driver will not be able to synthesize a Unicode */ - /* charmap out of the glyphs found in the fonts. */ - /* */ - /* You would normally undefine this configuration macro when building */ - /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ - /* */ -#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Postscript Names to Unicode Values support */ - /* */ - /* By default, FreeType 2 is built with the `PSNames' module compiled */ - /* in. Among other things, the module is used to convert a glyph name */ - /* into a Unicode value. This is especially useful in order to */ - /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ - /* through a big table named the `Adobe Glyph List' (AGL). */ - /* */ - /* Undefine this macro if you do not want the Adobe Glyph List */ - /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthesize a Unicode charmap out of the glyphs found in the */ - /* fonts. */ - /* */ -#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - - /*************************************************************************/ - /* */ - /* Support for Mac fonts */ - /* */ - /* Define this macro if you want support for outline fonts in Mac */ - /* format (mac dfont, mac resource, macbinary containing a mac */ - /* resource) on non-Mac platforms. */ - /* */ - /* Note that the `FOND' resource isn't checked. */ - /* */ -#define FT_CONFIG_OPTION_MAC_FONTS - - - /*************************************************************************/ - /* */ - /* Guessing methods to access embedded resource forks */ - /* */ - /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ - /* GNU/Linux). */ - /* */ - /* Resource forks which include fonts data are stored sometimes in */ - /* locations which users or developers don't expected. In some cases, */ - /* resource forks start with some offset from the head of a file. In */ - /* other cases, the actual resource fork is stored in file different */ - /* from what the user specifies. If this option is activated, */ - /* FreeType tries to guess whether such offsets or different file */ - /* names must be used. */ - /* */ - /* Note that normal, direct access of resource forks is controlled via */ - /* the FT_CONFIG_OPTION_MAC_FONTS option. */ - /* */ -#ifdef FT_CONFIG_OPTION_MAC_FONTS -#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#endif - - - /*************************************************************************/ - /* */ - /* Allow the use of FT_Incremental_Interface to load typefaces that */ - /* contain no glyph data, but supply it via a callback function. */ - /* This is required by clients supporting document formats which */ - /* supply font data incrementally as the document is parsed, such */ - /* as the Ghostscript interpreter for the PostScript language. */ - /* */ -#define FT_CONFIG_OPTION_INCREMENTAL - - - /*************************************************************************/ - /* */ - /* The size in bytes of the render pool used by the scan-line converter */ - /* to do all of its work. */ - /* */ - /* This must be greater than 4KByte if you use FreeType to rasterize */ - /* glyphs; otherwise, you may set it to zero to avoid unnecessary */ - /* allocation of the render pool. */ - /* */ -#define FT_RENDER_POOL_SIZE 16384L - - - /*************************************************************************/ - /* */ - /* FT_MAX_MODULES */ - /* */ - /* The maximum number of modules that can be registered in a single */ - /* FreeType library object. 32 is the default. */ - /* */ -#define FT_MAX_MODULES 32 - - - /*************************************************************************/ - /* */ - /* Debug level */ - /* */ - /* FreeType can be compiled in debug or trace mode. In debug mode, */ - /* errors are reported through the `ftdebug' component. In trace */ - /* mode, additional messages are sent to the standard output during */ - /* execution. */ - /* */ - /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ - /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ - /* */ - /* Don't define any of these macros to compile in `release' mode! */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -#define FT_DEBUG_LEVEL_ERROR -#define FT_DEBUG_LEVEL_TRACE - - - /*************************************************************************/ - /* */ - /* Autofitter debugging */ - /* */ - /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ - /* control the autofitter behaviour for debugging purposes with global */ - /* boolean variables (consequently, you should *never* enable this */ - /* while compiling in `release' mode): */ - /* */ - /* _af_debug_disable_horz_hints */ - /* _af_debug_disable_vert_hints */ - /* _af_debug_disable_blue_hints */ - /* */ - /* Additionally, the following functions provide dumps of various */ - /* internal autofit structures to stdout (using `printf'): */ - /* */ - /* af_glyph_hints_dump_points */ - /* af_glyph_hints_dump_segments */ - /* af_glyph_hints_dump_edges */ - /* */ - /* As an argument, they use another global variable: */ - /* */ - /* _af_debug_hints */ - /* */ - /* Please have a look at the `ftgrid' demo program to see how those */ - /* variables and macros should be used. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -#define FT_DEBUG_AUTOFIT - - - /*************************************************************************/ - /* */ - /* Memory Debugging */ - /* */ - /* FreeType now comes with an integrated memory debugger that is */ - /* capable of detecting simple errors like memory leaks or double */ - /* deletes. To compile it within your build of the library, you */ - /* should define FT_DEBUG_MEMORY here. */ - /* */ - /* Note that the memory debugger is only activated at runtime when */ - /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -#define FT_DEBUG_MEMORY - - - /*************************************************************************/ - /* */ - /* Module errors */ - /* */ - /* If this macro is set (which is _not_ the default), the higher byte */ - /* of an error code gives the module in which the error has occurred, */ - /* while the lower byte is the real error code. */ - /* */ - /* Setting this macro makes sense for debugging purposes only, since */ - /* it would break source compatibility of certain programs that use */ - /* FreeType 2. */ - /* */ - /* More details can be found in the files ftmoderr.h and fterrors.h. */ - /* */ -#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS - - - /*************************************************************************/ - /* */ - /* Position Independent Code */ - /* */ - /* If this macro is set (which is _not_ the default), FreeType2 will */ - /* avoid creating constants that require address fixups. Instead the */ - /* constants will be moved into a struct and additional intialization */ - /* code will be used. */ - /* */ - /* Setting this macro is needed for systems that prohibit address */ - /* fixups, such as BREW. */ - /* */ -/* #define FT_CONFIG_OPTION_PIC */ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ - /* embedded bitmaps in all formats using the SFNT module (namely */ - /* TrueType & OpenType). */ - /* */ -#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ - /* load and enumerate the glyph Postscript names in a TrueType or */ - /* OpenType file. */ - /* */ - /* Note that when you do not compile the `PSNames' module by undefining */ - /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ - /* contain additional code used to read the PS Names table from a font. */ - /* */ - /* (By default, the module uses `PSNames' to extract glyph names.) */ - /* */ -#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ - /* access the internal name table in a SFNT-based format like TrueType */ - /* or OpenType. The name table contains various strings used to */ - /* describe the font, like family name, copyright, version, etc. It */ - /* does not contain any glyph name though. */ - /* */ - /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftsnames.h'. */ - /* */ -#define TT_CONFIG_OPTION_SFNT_NAMES - - - /*************************************************************************/ - /* */ - /* TrueType CMap support */ - /* */ - /* Here you can fine-tune which TrueType CMap table format shall be */ - /* supported. */ -#define TT_CONFIG_CMAP_FORMAT_0 -#define TT_CONFIG_CMAP_FORMAT_2 -#define TT_CONFIG_CMAP_FORMAT_4 -#define TT_CONFIG_CMAP_FORMAT_6 -#define TT_CONFIG_CMAP_FORMAT_8 -#define TT_CONFIG_CMAP_FORMAT_10 -#define TT_CONFIG_CMAP_FORMAT_12 -#define TT_CONFIG_CMAP_FORMAT_13 -#define TT_CONFIG_CMAP_FORMAT_14 - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ - /* a bytecode interpreter in the TrueType driver. */ - /* */ - /* By undefining this, you will only compile the code necessary to load */ - /* TrueType glyphs without hinting. */ - /* */ - /* Do not #undef this macro here, since the build system might */ - /* define it for certain configurations only. */ - /* */ -#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ - /* replaces the native TrueType hinting mechanism when anything but */ - /* FT_RENDER_MODE_MONO is requested. */ - /* */ - /* Enabling this causes the TrueType driver to ignore instructions under */ - /* certain conditions. This is done in accordance with the guide here, */ - /* with some minor differences: */ - /* */ - /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ - /* By undefining this, you only compile the code necessary to hint */ - /* TrueType glyphs with native TT hinting. */ - /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ - /* */ -#define TT_CONFIG_OPTION_SUBPIXEL_HINTING - - - /*************************************************************************/ - /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ - /* TrueType hinting have expired worldwide since May 2010; this option */ - /* is now deprecated. */ - /* */ - /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ - /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ - /* */ - /* This macro is only useful for a small number of font files (mostly */ - /* for Asian scripts) that require bytecode interpretation to properly */ - /* load glyphs. For all other fonts, this produces unpleasant results, */ - /* thus the unpatented interpreter is never used to load glyphs from */ - /* TrueType fonts unless one of the following two options is used. */ - /* */ - /* - The unpatented interpreter is explicitly activated by the user */ - /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ - /* when opening the FT_Face. */ - /* */ - /* - FreeType detects that the FT_Face corresponds to one of the */ - /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ - /* contains a hard-coded list of font names and other matching */ - /* parameters (see function `tt_face_init' in file */ - /* `src/truetype/ttobjs.c'). */ - /* */ - /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ - /* */ - /* { */ - /* FT_Parameter parameter; */ - /* FT_Open_Args open_args; */ - /* */ - /* */ - /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ - /* */ - /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ - /* open_args.pathname = my_font_pathname; */ - /* open_args.num_params = 1; */ - /* open_args.params = ¶meter; */ - /* */ - /* error = FT_Open_Face( library, &open_args, index, &face ); */ - /* ... */ - /* } */ - /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ - /* bytecode interpreter with a huge switch statement, rather than a call */ - /* table. This results in smaller and faster code for a number of */ - /* architectures. */ - /* */ - /* Note however that on some compiler/processor combinations, undefining */ - /* this macro will generate faster, though larger, code. */ - /* */ -#define TT_CONFIG_OPTION_INTERPRETER_SWITCH - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ - /* TrueType glyph loader to use Apple's definition of how to handle */ - /* component offsets in composite glyphs. */ - /* */ - /* Apple and MS disagree on the default behavior of component offsets */ - /* in composites. Apple says that they should be scaled by the scaling */ - /* factors in the transformation matrix (roughly, it's more complex) */ - /* while MS says they should not. OpenType defines two bits in the */ - /* composite flags array which can be used to disambiguate, but old */ - /* fonts will not have them. */ - /* */ - /* http://www.microsoft.com/typography/otspec/glyf.htm */ - /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ - /* */ -#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ - /* support for Apple's distortable font technology (fvar, gvar, cvar, */ - /* and avar tables). This has many similarities to Type 1 Multiple */ - /* Masters support. */ - /* */ -#define TT_CONFIG_OPTION_GX_VAR_SUPPORT - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ - /* an embedded `BDF ' table within SFNT-based bitmap formats. */ - /* */ -#define TT_CONFIG_OPTION_BDF - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ - /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ - /* required. */ - /* */ -#define T1_MAX_DICT_DEPTH 5 - - - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ -#define T1_MAX_SUBRS_CALLS 16 - - - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ - /* minimum of 16 is required. */ - /* */ - /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ - /* */ -#define T1_MAX_CHARSTRINGS_OPERANDS 256 - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ - /* files into an existing face. Note that if set, the T1 driver will be */ - /* unable to produce kerning distances. */ - /* */ -#undef T1_CONFIG_OPTION_NO_AFM - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of the Multiple Masters font support in the Type 1 */ - /* driver. */ - /* */ -#undef T1_CONFIG_OPTION_NO_MM_SUPPORT - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** C F F D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ - /* engine gets compiled into FreeType. If defined, it is possible to */ - /* switch between the two engines using the `hinting-engine' property of */ - /* the cff driver module. */ - /* */ -/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ - /* support. */ - /* */ -#define AF_CONFIG_OPTION_CJK - - /*************************************************************************/ - /* */ - /* Compile autofit module with Indic script support. */ - /* */ -#define AF_CONFIG_OPTION_INDIC - - /*************************************************************************/ - /* */ - /* Compile autofit module with warp hinting. The idea of the warping */ - /* code is to slightly scale and shift a glyph within a single dimension */ - /* so that as much of its segments are aligned (more or less) on the */ - /* grid. To find out the optimal scaling and shifting value, various */ - /* parameter combinations are tried and scored. */ - /* */ - /* This experimental option is only active if the render mode is */ - /* FT_RENDER_MODE_LIGHT. */ - /* */ -#define AF_CONFIG_OPTION_USE_WARPER - - /* */ - - - /* - * This macro is obsolete. Support has been removed in FreeType - * version 2.5. - */ -/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ - - - /* - * This macro is defined if either unpatented or native TrueType - * hinting is requested by the definitions above. - */ -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#define TT_USE_BYTECODE_INTERPRETER -#undef TT_CONFIG_OPTION_UNPATENTED_HINTING -#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING -#define TT_USE_BYTECODE_INTERPRETER -#endif - -FT_END_HEADER - - -#endif /* __FTOPTION_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afglobal.c b/drivers/freetype/freetype/src/autofit/afglobal.c deleted file mode 100644 index 3e41465756..0000000000 --- a/drivers/freetype/freetype/src/autofit/afglobal.c +++ /dev/null @@ -1,304 +0,0 @@ -/***************************************************************************/ -/* */ -/* afglobal.c */ -/* */ -/* Auto-fitter routines to compute global hinting values (body). */ -/* */ -/* Copyright 2003-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include "afglobal.h" -#include "afdummy.h" -#include "aflatin.h" -#include "afcjk.h" -#include "afindic.h" -#include "afpic.h" - -#include "aferrors.h" - -#ifdef FT_OPTION_AUTOFIT2 -#include "aflatin2.h" -#endif - -#ifndef FT_CONFIG_OPTION_PIC - - /* when updating this table, don't forget to update */ - /* AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */ - - /* populate this list when you add new scripts */ - static AF_ScriptClass const af_script_classes[] = - { - &af_dummy_script_class, -#ifdef FT_OPTION_AUTOFIT2 - &af_latin2_script_class, -#endif - &af_latin_script_class, - &af_cjk_script_class, - &af_indic_script_class, - NULL /* do not remove */ - }; - -#endif /* !FT_CONFIG_OPTION_PIC */ - - - /* Compute the script index of each glyph within a given face. */ - - static FT_Error - af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) - { - FT_Error error; - FT_Face face = globals->face; - FT_CharMap old_charmap = face->charmap; - FT_Byte* gscripts = globals->glyph_scripts; - FT_UInt ss; - FT_UInt i; - - - /* the value AF_SCRIPT_NONE means `uncovered glyph' */ - FT_MEM_SET( globals->glyph_scripts, - AF_SCRIPT_NONE, - globals->glyph_count ); - - error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); - if ( error ) - { - /* - * Ignore this error; we simply use the fallback script. - * XXX: Shouldn't we rather disable hinting? - */ - error = FT_Err_Ok; - goto Exit; - } - - /* scan each script in a Unicode charmap */ - for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) - { - AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; - AF_Script_UniRange range; - - - if ( clazz->script_uni_ranges == NULL ) - continue; - - /* - * Scan all Unicode points in the range and set the corresponding - * glyph script index. - */ - for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) - { - FT_ULong charcode = range->first; - FT_UInt gindex; - - - gindex = FT_Get_Char_Index( face, charcode ); - - if ( gindex != 0 && - gindex < (FT_ULong)globals->glyph_count && - gscripts[gindex] == AF_SCRIPT_NONE ) - gscripts[gindex] = (FT_Byte)ss; - - for (;;) - { - charcode = FT_Get_Next_Char( face, charcode, &gindex ); - - if ( gindex == 0 || charcode > range->last ) - break; - - if ( gindex < (FT_ULong)globals->glyph_count && - gscripts[gindex] == AF_SCRIPT_NONE ) - gscripts[gindex] = (FT_Byte)ss; - } - } - } - - /* mark ASCII digits */ - for ( i = 0x30; i <= 0x39; i++ ) - { - FT_UInt gindex = FT_Get_Char_Index( face, i ); - - - if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) - gscripts[gindex] |= AF_DIGIT; - } - - Exit: - /* - * By default, all uncovered glyphs are set to the fallback script. - * XXX: Shouldn't we disable hinting or do something similar? - */ - if ( globals->module->fallback_script != AF_SCRIPT_NONE ) - { - FT_Long nn; - - - for ( nn = 0; nn < globals->glyph_count; nn++ ) - { - if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_NONE ) - { - gscripts[nn] &= ~AF_SCRIPT_NONE; - gscripts[nn] |= globals->module->fallback_script; - } - } - } - - FT_Set_Charmap( face, old_charmap ); - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - af_face_globals_new( FT_Face face, - AF_FaceGlobals *aglobals, - AF_Module module ) - { - FT_Error error; - FT_Memory memory; - AF_FaceGlobals globals = NULL; - - - memory = face->memory; - - if ( FT_ALLOC( globals, sizeof ( *globals ) + - face->num_glyphs * sizeof ( FT_Byte ) ) ) - goto Exit; - - globals->face = face; - globals->glyph_count = face->num_glyphs; - globals->glyph_scripts = (FT_Byte*)( globals + 1 ); - globals->module = module; - - error = af_face_globals_compute_script_coverage( globals ); - if ( error ) - { - af_face_globals_free( globals ); - globals = NULL; - } - - globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX; - - Exit: - *aglobals = globals; - return error; - } - - - FT_LOCAL_DEF( void ) - af_face_globals_free( AF_FaceGlobals globals ) - { - if ( globals ) - { - FT_Memory memory = globals->face->memory; - FT_UInt nn; - - - for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ ) - { - if ( globals->metrics[nn] ) - { - AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[nn]; - - - FT_ASSERT( globals->metrics[nn]->clazz == clazz ); - - if ( clazz->script_metrics_done ) - clazz->script_metrics_done( globals->metrics[nn] ); - - FT_FREE( globals->metrics[nn] ); - } - } - - globals->glyph_count = 0; - globals->glyph_scripts = NULL; /* no need to free this one! */ - globals->face = NULL; - - FT_FREE( globals ); - } - } - - - FT_LOCAL_DEF( FT_Error ) - af_face_globals_get_metrics( AF_FaceGlobals globals, - FT_UInt gindex, - FT_UInt options, - AF_ScriptMetrics *ametrics ) - { - AF_ScriptMetrics metrics = NULL; - FT_UInt gidx; - AF_ScriptClass clazz; - FT_UInt script = options & 15; - const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) / - sizeof ( AF_SCRIPT_CLASSES_GET[0] ); - FT_Error error = FT_Err_Ok; - - - if ( gindex >= (FT_ULong)globals->glyph_count ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - gidx = script; - if ( gidx == 0 || gidx + 1 >= script_max ) - gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_NONE; - - clazz = AF_SCRIPT_CLASSES_GET[gidx]; - if ( script == 0 ) - script = clazz->script; - - metrics = globals->metrics[clazz->script]; - if ( metrics == NULL ) - { - /* create the global metrics object if necessary */ - FT_Memory memory = globals->face->memory; - - - if ( FT_ALLOC( metrics, clazz->script_metrics_size ) ) - goto Exit; - - metrics->clazz = clazz; - metrics->globals = globals; - - if ( clazz->script_metrics_init ) - { - error = clazz->script_metrics_init( metrics, globals->face ); - if ( error ) - { - if ( clazz->script_metrics_done ) - clazz->script_metrics_done( metrics ); - - FT_FREE( metrics ); - goto Exit; - } - } - - globals->metrics[clazz->script] = metrics; - } - - Exit: - *ametrics = metrics; - - return error; - } - - - FT_LOCAL_DEF( FT_Bool ) - af_face_globals_is_digit( AF_FaceGlobals globals, - FT_UInt gindex ) - { - if ( gindex < (FT_ULong)globals->glyph_count ) - return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT ); - - return (FT_Bool)0; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afglobal.h b/drivers/freetype/freetype/src/autofit/afglobal.h deleted file mode 100644 index 2e24900822..0000000000 --- a/drivers/freetype/freetype/src/autofit/afglobal.h +++ /dev/null @@ -1,109 +0,0 @@ -/***************************************************************************/ -/* */ -/* afglobal.h */ -/* */ -/* Auto-fitter routines to compute global hinting values */ -/* (specification). */ -/* */ -/* Copyright 2003-2005, 2007, 2009, 2011-2012 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __AFGLOBAL_H__ -#define __AFGLOBAL_H__ - - -#include "aftypes.h" -#include "afmodule.h" - - -FT_BEGIN_HEADER - - - /* - * Default values and flags for both autofitter globals (found in - * AF_ModuleRec) and face globals (in AF_FaceGlobalsRec). - */ - - /* index of fallback script in `af_script_classes' */ -#define AF_SCRIPT_FALLBACK 2 - /* a bit mask indicating an uncovered glyph */ -#define AF_SCRIPT_NONE 0x7F - /* if this flag is set, we have an ASCII digit */ -#define AF_DIGIT 0x80 - - /* `increase-x-height' property */ -#define AF_PROP_INCREASE_X_HEIGHT_MIN 6 -#define AF_PROP_INCREASE_X_HEIGHT_MAX 0 - - - /************************************************************************/ - /************************************************************************/ - /***** *****/ - /***** F A C E G L O B A L S *****/ - /***** *****/ - /************************************************************************/ - /************************************************************************/ - - - /* - * Note that glyph_scripts[] is used to map each glyph into - * an index into the `af_script_classes' array. - * - */ - typedef struct AF_FaceGlobalsRec_ - { - FT_Face face; - FT_Long glyph_count; /* same as face->num_glyphs */ - FT_Byte* glyph_scripts; - - /* per-face auto-hinter properties */ - FT_UInt increase_x_height; - - AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; - - AF_Module module; /* to access global properties */ - - } AF_FaceGlobalsRec; - - - /* - * model the global hints data for a given face, decomposed into - * script-specific items - */ - - FT_LOCAL( FT_Error ) - af_face_globals_new( FT_Face face, - AF_FaceGlobals *aglobals, - AF_Module module ); - - FT_LOCAL( FT_Error ) - af_face_globals_get_metrics( AF_FaceGlobals globals, - FT_UInt gindex, - FT_UInt options, - AF_ScriptMetrics *ametrics ); - - FT_LOCAL( void ) - af_face_globals_free( AF_FaceGlobals globals ); - - FT_LOCAL_DEF( FT_Bool ) - af_face_globals_is_digit( AF_FaceGlobals globals, - FT_UInt gindex ); - - /* */ - - -FT_END_HEADER - -#endif /* __AFGLOBAL_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afloader.c b/drivers/freetype/freetype/src/autofit/afloader.c deleted file mode 100644 index 17a6fb7c3b..0000000000 --- a/drivers/freetype/freetype/src/autofit/afloader.c +++ /dev/null @@ -1,561 +0,0 @@ -/***************************************************************************/ -/* */ -/* afloader.c */ -/* */ -/* Auto-fitter glyph loading routines (body). */ -/* */ -/* Copyright 2003-2009, 2011-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include "afglobal.h" -#include "afloader.h" -#include "afhints.h" -#include "aferrors.h" -#include "afmodule.h" - - - /* Initialize glyph loader. */ - - FT_LOCAL_DEF( FT_Error ) - af_loader_init( AF_Module module ) - { - AF_Loader loader = module->loader; - FT_Memory memory = module->root.library->memory; - - - FT_ZERO( loader ); - - af_glyph_hints_init( &loader->hints, memory ); -#ifdef FT_DEBUG_AUTOFIT - _af_debug_hints = &loader->hints; -#endif - return FT_GlyphLoader_New( memory, &loader->gloader ); - } - - - /* Reset glyph loader and compute globals if necessary. */ - - FT_LOCAL_DEF( FT_Error ) - af_loader_reset( AF_Module module, - FT_Face face ) - { - FT_Error error = FT_Err_Ok; - AF_Loader loader = module->loader; - - - loader->face = face; - loader->globals = (AF_FaceGlobals)face->autohint.data; - - FT_GlyphLoader_Rewind( loader->gloader ); - - if ( loader->globals == NULL ) - { - error = af_face_globals_new( face, &loader->globals, module ); - if ( !error ) - { - face->autohint.data = - (FT_Pointer)loader->globals; - face->autohint.finalizer = - (FT_Generic_Finalizer)af_face_globals_free; - } - } - - return error; - } - - - /* Finalize glyph loader. */ - - FT_LOCAL_DEF( void ) - af_loader_done( AF_Module module ) - { - AF_Loader loader = module->loader; - - - af_glyph_hints_done( &loader->hints ); - - loader->face = NULL; - loader->globals = NULL; - -#ifdef FT_DEBUG_AUTOFIT - _af_debug_hints = NULL; -#endif - FT_GlyphLoader_Done( loader->gloader ); - loader->gloader = NULL; - } - - - /* Load a single glyph component. This routine calls itself */ - /* recursively, if necessary, and does the main work of */ - /* `af_loader_load_glyph.' */ - - static FT_Error - af_loader_load_g( AF_Loader loader, - AF_Scaler scaler, - FT_UInt glyph_index, - FT_Int32 load_flags, - FT_UInt depth ) - { - FT_Error error; - FT_Face face = loader->face; - FT_GlyphLoader gloader = loader->gloader; - AF_ScriptMetrics metrics = loader->metrics; - AF_GlyphHints hints = &loader->hints; - FT_GlyphSlot slot = face->glyph; - FT_Slot_Internal internal = slot->internal; - FT_Int32 flags; - - - flags = load_flags | FT_LOAD_LINEAR_DESIGN; - error = FT_Load_Glyph( face, glyph_index, flags ); - if ( error ) - goto Exit; - - loader->transformed = internal->glyph_transformed; - if ( loader->transformed ) - { - FT_Matrix inverse; - - - loader->trans_matrix = internal->glyph_matrix; - loader->trans_delta = internal->glyph_delta; - - inverse = loader->trans_matrix; - FT_Matrix_Invert( &inverse ); - FT_Vector_Transform( &loader->trans_delta, &inverse ); - } - - switch ( slot->format ) - { - case FT_GLYPH_FORMAT_OUTLINE: - /* translate the loaded glyph when an internal transform is needed */ - if ( loader->transformed ) - FT_Outline_Translate( &slot->outline, - loader->trans_delta.x, - loader->trans_delta.y ); - - /* copy the outline points in the loader's current */ - /* extra points which are used to keep original glyph coordinates */ - error = FT_GLYPHLOADER_CHECK_POINTS( gloader, - slot->outline.n_points + 4, - slot->outline.n_contours ); - if ( error ) - goto Exit; - - FT_ARRAY_COPY( gloader->current.outline.points, - slot->outline.points, - slot->outline.n_points ); - - FT_ARRAY_COPY( gloader->current.outline.contours, - slot->outline.contours, - slot->outline.n_contours ); - - FT_ARRAY_COPY( gloader->current.outline.tags, - slot->outline.tags, - slot->outline.n_points ); - - gloader->current.outline.n_points = slot->outline.n_points; - gloader->current.outline.n_contours = slot->outline.n_contours; - - /* compute original horizontal phantom points (and ignore */ - /* vertical ones) */ - loader->pp1.x = hints->x_delta; - loader->pp1.y = hints->y_delta; - loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, - hints->x_scale ) + hints->x_delta; - loader->pp2.y = hints->y_delta; - - /* be sure to check for spacing glyphs */ - if ( slot->outline.n_points == 0 ) - goto Hint_Metrics; - - /* now load the slot image into the auto-outline and run the */ - /* automatic hinting process */ - if ( metrics->clazz->script_hints_apply ) - metrics->clazz->script_hints_apply( hints, - &gloader->current.outline, - metrics ); - - /* we now need to adjust the metrics according to the change in */ - /* width/positioning that occurred during the hinting process */ - if ( scaler->render_mode != FT_RENDER_MODE_LIGHT ) - { - FT_Pos old_rsb, old_lsb, new_lsb; - FT_Pos pp1x_uh, pp2x_uh; - AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; - AF_Edge edge1 = axis->edges; /* leftmost edge */ - AF_Edge edge2 = edge1 + - axis->num_edges - 1; /* rightmost edge */ - - - if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) - { - old_rsb = loader->pp2.x - edge2->opos; - old_lsb = edge1->opos; - new_lsb = edge1->pos; - - /* remember unhinted values to later account */ - /* for rounding errors */ - - pp1x_uh = new_lsb - old_lsb; - pp2x_uh = edge2->pos + old_rsb; - - /* prefer too much space over too little space */ - /* for very small sizes */ - - if ( old_lsb < 24 ) - pp1x_uh -= 8; - - if ( old_rsb < 24 ) - pp2x_uh += 8; - - loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); - loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); - - if ( loader->pp1.x >= new_lsb && old_lsb > 0 ) - loader->pp1.x -= 64; - - if ( loader->pp2.x <= edge2->pos && old_rsb > 0 ) - loader->pp2.x += 64; - - slot->lsb_delta = loader->pp1.x - pp1x_uh; - slot->rsb_delta = loader->pp2.x - pp2x_uh; - } - else - { - FT_Pos pp1x = loader->pp1.x; - FT_Pos pp2x = loader->pp2.x; - - - loader->pp1.x = FT_PIX_ROUND( pp1x ); - loader->pp2.x = FT_PIX_ROUND( pp2x ); - - slot->lsb_delta = loader->pp1.x - pp1x; - slot->rsb_delta = loader->pp2.x - pp2x; - } - } - else - { - FT_Pos pp1x = loader->pp1.x; - FT_Pos pp2x = loader->pp2.x; - - - loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); - loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); - - slot->lsb_delta = loader->pp1.x - pp1x; - slot->rsb_delta = loader->pp2.x - pp2x; - } - - /* good, we simply add the glyph to our loader's base */ - FT_GlyphLoader_Add( gloader ); - break; - - case FT_GLYPH_FORMAT_COMPOSITE: - { - FT_UInt nn, num_subglyphs = slot->num_subglyphs; - FT_UInt num_base_subgs, start_point; - FT_SubGlyph subglyph; - - - start_point = gloader->base.outline.n_points; - - /* first of all, copy the subglyph descriptors in the glyph loader */ - error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs ); - if ( error ) - goto Exit; - - FT_ARRAY_COPY( gloader->current.subglyphs, - slot->subglyphs, - num_subglyphs ); - - gloader->current.num_subglyphs = num_subglyphs; - num_base_subgs = gloader->base.num_subglyphs; - - /* now read each subglyph independently */ - for ( nn = 0; nn < num_subglyphs; nn++ ) - { - FT_Vector pp1, pp2; - FT_Pos x, y; - FT_UInt num_points, num_new_points, num_base_points; - - - /* gloader.current.subglyphs can change during glyph loading due */ - /* to re-allocation -- we must recompute the current subglyph on */ - /* each iteration */ - subglyph = gloader->base.subglyphs + num_base_subgs + nn; - - pp1 = loader->pp1; - pp2 = loader->pp2; - - num_base_points = gloader->base.outline.n_points; - - error = af_loader_load_g( loader, scaler, subglyph->index, - load_flags, depth + 1 ); - if ( error ) - goto Exit; - - /* recompute subglyph pointer */ - subglyph = gloader->base.subglyphs + num_base_subgs + nn; - - if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) - { - pp1 = loader->pp1; - pp2 = loader->pp2; - } - else - { - loader->pp1 = pp1; - loader->pp2 = pp2; - } - - num_points = gloader->base.outline.n_points; - num_new_points = num_points - num_base_points; - - /* now perform the transformation required for this subglyph */ - - if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | - FT_SUBGLYPH_FLAG_XY_SCALE | - FT_SUBGLYPH_FLAG_2X2 ) ) - { - FT_Vector* cur = gloader->base.outline.points + - num_base_points; - FT_Vector* limit = cur + num_new_points; - - - for ( ; cur < limit; cur++ ) - FT_Vector_Transform( cur, &subglyph->transform ); - } - - /* apply offset */ - - if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) ) - { - FT_Int k = subglyph->arg1; - FT_UInt l = subglyph->arg2; - FT_Vector* p1; - FT_Vector* p2; - - - if ( start_point + k >= num_base_points || - l >= (FT_UInt)num_new_points ) - { - error = FT_THROW( Invalid_Composite ); - goto Exit; - } - - l += num_base_points; - - /* for now, only use the current point coordinates; */ - /* we eventually may consider another approach */ - p1 = gloader->base.outline.points + start_point + k; - p2 = gloader->base.outline.points + start_point + l; - - x = p1->x - p2->x; - y = p1->y - p2->y; - } - else - { - x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta; - y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta; - - x = FT_PIX_ROUND( x ); - y = FT_PIX_ROUND( y ); - } - - { - FT_Outline dummy = gloader->base.outline; - - - dummy.points += num_base_points; - dummy.n_points = (short)num_new_points; - - FT_Outline_Translate( &dummy, x, y ); - } - } - } - break; - - default: - /* we don't support other formats (yet?) */ - error = FT_THROW( Unimplemented_Feature ); - } - - Hint_Metrics: - if ( depth == 0 ) - { - FT_BBox bbox; - FT_Vector vvector; - - - vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX; - vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY; - vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale ); - vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale ); - - /* transform the hinted outline if needed */ - if ( loader->transformed ) - { - FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); - FT_Vector_Transform( &vvector, &loader->trans_matrix ); - } -#if 1 - /* we must translate our final outline by -pp1.x and compute */ - /* the new metrics */ - if ( loader->pp1.x ) - FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); -#endif - FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); - - bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); - bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); - bbox.xMax = FT_PIX_CEIL( bbox.xMax ); - bbox.yMax = FT_PIX_CEIL( bbox.yMax ); - - slot->metrics.width = bbox.xMax - bbox.xMin; - slot->metrics.height = bbox.yMax - bbox.yMin; - slot->metrics.horiBearingX = bbox.xMin; - slot->metrics.horiBearingY = bbox.yMax; - - slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x ); - slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y ); - - /* for mono-width fonts (like Andale, Courier, etc.) we need */ - /* to keep the original rounded advance width; ditto for */ - /* digits if all have the same advance width */ -#if 0 - if ( !FT_IS_FIXED_WIDTH( slot->face ) ) - slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - else - slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, - x_scale ); -#else - if ( scaler->render_mode != FT_RENDER_MODE_LIGHT && - ( FT_IS_FIXED_WIDTH( slot->face ) || - ( af_face_globals_is_digit( loader->globals, glyph_index ) && - metrics->digits_have_same_width ) ) ) - { - slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, - metrics->scaler.x_scale ); - - /* Set delta values to 0. Otherwise code that uses them is */ - /* going to ruin the fixed advance width. */ - slot->lsb_delta = 0; - slot->rsb_delta = 0; - } - else - { - /* non-spacing glyphs must stay as-is */ - if ( slot->metrics.horiAdvance ) - slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - } -#endif - - slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, - metrics->scaler.y_scale ); - - slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); - slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); - - /* now copy outline into glyph slot */ - FT_GlyphLoader_Rewind( internal->loader ); - error = FT_GlyphLoader_CopyPoints( internal->loader, gloader ); - if ( error ) - goto Exit; - - /* reassign all outline fields except flags to protect them */ - slot->outline.n_contours = internal->loader->base.outline.n_contours; - slot->outline.n_points = internal->loader->base.outline.n_points; - slot->outline.points = internal->loader->base.outline.points; - slot->outline.tags = internal->loader->base.outline.tags; - slot->outline.contours = internal->loader->base.outline.contours; - - slot->format = FT_GLYPH_FORMAT_OUTLINE; - } - - Exit: - return error; - } - - - /* Load a glyph. */ - - FT_LOCAL_DEF( FT_Error ) - af_loader_load_glyph( AF_Module module, - FT_Face face, - FT_UInt gindex, - FT_Int32 load_flags ) - { - FT_Error error; - FT_Size size = face->size; - AF_Loader loader = module->loader; - AF_ScalerRec scaler; - - - if ( !size ) - return FT_THROW( Invalid_Argument ); - - FT_ZERO( &scaler ); - - scaler.face = face; - scaler.x_scale = size->metrics.x_scale; - scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ - scaler.y_scale = size->metrics.y_scale; - scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ - - scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); - scaler.flags = 0; /* XXX: fix this */ - - error = af_loader_reset( module, face ); - if ( !error ) - { - AF_ScriptMetrics metrics; - FT_UInt options = 0; - - -#ifdef FT_OPTION_AUTOFIT2 - /* XXX: undocumented hook to activate the latin2 hinter */ - if ( load_flags & ( 1UL << 20 ) ) - options = 2; -#endif - - error = af_face_globals_get_metrics( loader->globals, gindex, - options, &metrics ); - if ( !error ) - { - loader->metrics = metrics; - - if ( metrics->clazz->script_metrics_scale ) - metrics->clazz->script_metrics_scale( metrics, &scaler ); - else - metrics->scaler = scaler; - - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; - load_flags &= ~FT_LOAD_RENDER; - - if ( metrics->clazz->script_hints_init ) - { - error = metrics->clazz->script_hints_init( &loader->hints, - metrics ); - if ( error ) - goto Exit; - } - - error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); - } - } - Exit: - return error; - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afmodule.c b/drivers/freetype/freetype/src/autofit/afmodule.c deleted file mode 100644 index b1bb5ee0ed..0000000000 --- a/drivers/freetype/freetype/src/autofit/afmodule.c +++ /dev/null @@ -1,264 +0,0 @@ -/***************************************************************************/ -/* */ -/* afmodule.c */ -/* */ -/* Auto-fitter module implementation (body). */ -/* */ -/* Copyright 2003-2006, 2009, 2011-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include "afglobal.h" -#include "afmodule.h" -#include "afloader.h" -#include "aferrors.h" -#include "afpic.h" - -#ifdef FT_DEBUG_AUTOFIT - int _af_debug_disable_horz_hints; - int _af_debug_disable_vert_hints; - int _af_debug_disable_blue_hints; - void* _af_debug_hints; -#endif - -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_AUTOHINTER_H -#include FT_SERVICE_PROPERTIES_H - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_afmodule - - - FT_Error - af_property_get_face_globals( FT_Face face, - AF_FaceGlobals* aglobals, - AF_Module module ) - { - FT_Error error = FT_Err_Ok; - AF_FaceGlobals globals; - - - if ( !face ) - return FT_THROW( Invalid_Argument ); - - globals = (AF_FaceGlobals)face->autohint.data; - if ( !globals ) - { - /* trigger computation of the global script data */ - /* in case it hasn't been done yet */ - error = af_face_globals_new( face, &globals, module ); - if ( !error ) - { - face->autohint.data = - (FT_Pointer)globals; - face->autohint.finalizer = - (FT_Generic_Finalizer)af_face_globals_free; - } - } - - if ( !error ) - *aglobals = globals; - - return error; - } - - - FT_Error - af_property_set( FT_Module ft_module, - const char* property_name, - const void* value ) - { - FT_Error error = FT_Err_Ok; - AF_Module module = (AF_Module)ft_module; - - - if ( !ft_strcmp( property_name, "fallback-script" ) ) - { - FT_UInt* fallback_script = (FT_UInt*)value; - - - module->fallback_script = *fallback_script; - - return error; - } - else if ( !ft_strcmp( property_name, "increase-x-height" ) ) - { - FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; - AF_FaceGlobals globals; - - - error = af_property_get_face_globals( prop->face, &globals, module ); - if ( !error ) - globals->increase_x_height = prop->limit; - - return error; - } - - FT_TRACE0(( "af_property_set: missing property `%s'\n", - property_name )); - return FT_THROW( Missing_Property ); - } - - - FT_Error - af_property_get( FT_Module ft_module, - const char* property_name, - void* value ) - { - FT_Error error = FT_Err_Ok; - AF_Module module = (AF_Module)ft_module; - FT_UInt fallback_script = module->fallback_script; - - - if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) - { - FT_Prop_GlyphToScriptMap* prop = (FT_Prop_GlyphToScriptMap*)value; - AF_FaceGlobals globals; - - - error = af_property_get_face_globals( prop->face, &globals, module ); - if ( !error ) - prop->map = globals->glyph_scripts; - - return error; - } - else if ( !ft_strcmp( property_name, "fallback-script" ) ) - { - FT_UInt* val = (FT_UInt*)value; - - - *val = fallback_script; - - return error; - } - else if ( !ft_strcmp( property_name, "increase-x-height" ) ) - { - FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; - AF_FaceGlobals globals; - - - error = af_property_get_face_globals( prop->face, &globals, module ); - if ( !error ) - prop->limit = globals->increase_x_height; - - return error; - } - - - FT_TRACE0(( "af_property_get: missing property `%s'\n", - property_name )); - return FT_THROW( Missing_Property ); - } - - - FT_DEFINE_SERVICE_PROPERTIESREC( - af_service_properties, - (FT_Properties_SetFunc)af_property_set, - (FT_Properties_GetFunc)af_property_get ) - - - FT_DEFINE_SERVICEDESCREC1( - af_services, - FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET ) - - - FT_CALLBACK_DEF( FT_Module_Interface ) - af_get_interface( FT_Module module, - const char* module_interface ) - { - /* AF_SERVICES_GET derefers `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - FT_Library library; - - - if ( !module ) - return NULL; - library = module->library; - if ( !library ) - return NULL; -#else - FT_UNUSED( module ); -#endif - - return ft_service_list_lookup( AF_SERVICES_GET, module_interface ); - } - - - FT_CALLBACK_DEF( FT_Error ) - af_autofitter_init( FT_Module ft_module ) /* AF_Module */ - { - AF_Module module = (AF_Module)ft_module; - - - module->fallback_script = AF_SCRIPT_FALLBACK; - - return af_loader_init( module ); - } - - - FT_CALLBACK_DEF( void ) - af_autofitter_done( FT_Module ft_module ) /* AF_Module */ - { - AF_Module module = (AF_Module)ft_module; - - - af_loader_done( module ); - } - - - FT_CALLBACK_DEF( FT_Error ) - af_autofitter_load_glyph( AF_Module module, - FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - FT_UNUSED( size ); - - return af_loader_load_glyph( module, slot->face, - glyph_index, load_flags ); - } - - - FT_DEFINE_AUTOHINTER_INTERFACE( - af_autofitter_interface, - NULL, /* reset_face */ - NULL, /* get_global_hints */ - NULL, /* done_global_hints */ - (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph ) /* load_glyph */ - - - FT_DEFINE_MODULE( - autofit_module_class, - - FT_MODULE_HINTER, - sizeof ( AF_ModuleRec ), - - "autofitter", - 0x10000L, /* version 1.0 of the autofitter */ - 0x20000L, /* requires FreeType 2.0 or above */ - - (const void*)&AF_INTERFACE_GET, - - (FT_Module_Constructor)af_autofitter_init, - (FT_Module_Destructor) af_autofitter_done, - (FT_Module_Requester) af_get_interface ) - - -/* END */ diff --git a/drivers/freetype/freetype/src/autofit/aftypes.h b/drivers/freetype/freetype/src/autofit/aftypes.h deleted file mode 100644 index 9acd7ad6d2..0000000000 --- a/drivers/freetype/freetype/src/autofit/aftypes.h +++ /dev/null @@ -1,378 +0,0 @@ -/***************************************************************************/ -/* */ -/* aftypes.h */ -/* */ -/* Auto-fitter types (specification only). */ -/* */ -/* Copyright 2003-2009, 2011-2012 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /************************************************************************* - * - * The auto-fitter is a complete rewrite of the old auto-hinter. - * Its main feature is the ability to differentiate between different - * scripts in order to apply language-specific rules. - * - * The code has also been compartmentized into several entities that - * should make algorithmic experimentation easier than with the old - * code. - * - * Finally, we get rid of the Catharon license, since this code is - * released under the FreeType one. - * - *************************************************************************/ - - -#ifndef __AFTYPES_H__ -#define __AFTYPES_H__ - -#include <ft2build.h> - -#include FT_FREETYPE_H -#include FT_OUTLINE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** D E B U G G I N G *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#ifdef FT_DEBUG_AUTOFIT - -#include FT_CONFIG_STANDARD_LIBRARY_H - -extern int _af_debug_disable_horz_hints; -extern int _af_debug_disable_vert_hints; -extern int _af_debug_disable_blue_hints; -extern void* _af_debug_hints; - -#endif /* FT_DEBUG_AUTOFIT */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** U T I L I T Y S T U F F *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct AF_WidthRec_ - { - FT_Pos org; /* original position/width in font units */ - FT_Pos cur; /* current/scaled position/width in device sub-pixels */ - FT_Pos fit; /* current/fitted position/width in device sub-pixels */ - - } AF_WidthRec, *AF_Width; - - - FT_LOCAL( void ) - af_sort_pos( FT_UInt count, - FT_Pos* table ); - - FT_LOCAL( void ) - af_sort_and_quantize_widths( FT_UInt* count, - AF_Width widths, - FT_Pos threshold ); - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** A N G L E T Y P E S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * The auto-fitter doesn't need a very high angular accuracy; - * this allows us to speed up some computations considerably with a - * light Cordic algorithm (see afangles.c). - */ - - typedef FT_Int AF_Angle; - - -#define AF_ANGLE_PI 256 -#define AF_ANGLE_2PI ( AF_ANGLE_PI * 2 ) -#define AF_ANGLE_PI2 ( AF_ANGLE_PI / 2 ) -#define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 ) - - -#if 0 - /* - * compute the angle of a given 2-D vector - */ - FT_LOCAL( AF_Angle ) - af_angle_atan( FT_Pos dx, - FT_Pos dy ); - - - /* - * compute `angle2 - angle1'; the result is always within - * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1] - */ - FT_LOCAL( AF_Angle ) - af_angle_diff( AF_Angle angle1, - AF_Angle angle2 ); -#endif /* 0 */ - - -#define AF_ANGLE_DIFF( result, angle1, angle2 ) \ - FT_BEGIN_STMNT \ - AF_Angle _delta = (angle2) - (angle1); \ - \ - \ - _delta %= AF_ANGLE_2PI; \ - if ( _delta < 0 ) \ - _delta += AF_ANGLE_2PI; \ - \ - if ( _delta > AF_ANGLE_PI ) \ - _delta -= AF_ANGLE_2PI; \ - \ - result = _delta; \ - FT_END_STMNT - - - /* opaque handle to glyph-specific hints -- see `afhints.h' for more - * details - */ - typedef struct AF_GlyphHintsRec_* AF_GlyphHints; - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** S C A L E R S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * A scaler models the target pixel device that will receive the - * auto-hinted glyph image. - */ - - typedef enum AF_ScalerFlags_ - { - AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */ - AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */ - AF_SCALER_FLAG_NO_ADVANCE = 4 /* disable advance hinting */ - - } AF_ScalerFlags; - - - typedef struct AF_ScalerRec_ - { - FT_Face face; /* source font face */ - FT_Fixed x_scale; /* from font units to 1/64th device pixels */ - FT_Fixed y_scale; /* from font units to 1/64th device pixels */ - FT_Pos x_delta; /* in 1/64th device pixels */ - FT_Pos y_delta; /* in 1/64th device pixels */ - FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc. */ - FT_UInt32 flags; /* additional control flags, see above */ - - } AF_ScalerRec, *AF_Scaler; - - -#define AF_SCALER_EQUAL_SCALES( a, b ) \ - ( (a)->x_scale == (b)->x_scale && \ - (a)->y_scale == (b)->y_scale && \ - (a)->x_delta == (b)->x_delta && \ - (a)->y_delta == (b)->y_delta ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** S C R I P T S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* - * The list of known scripts. Each different script corresponds to the - * following information: - * - * - A set of Unicode ranges to test whether the face supports the - * script. - * - * - A specific global analyzer that will compute global metrics - * specific to the script. - * - * - A specific glyph analyzer that will compute segments and - * edges for each glyph covered by the script. - * - * - A specific grid-fitting algorithm that will distort the - * scaled glyph outline according to the results of the glyph - * analyzer. - * - * Note that a given analyzer and/or grid-fitting algorithm can be - * used by more than one script. - */ - - typedef enum AF_Script_ - { - AF_SCRIPT_DUMMY = 0, - AF_SCRIPT_LATIN = 1, - AF_SCRIPT_CJK = 2, - AF_SCRIPT_INDIC = 3, -#ifdef FT_OPTION_AUTOFIT2 - AF_SCRIPT_LATIN2 = 4, -#endif - - /* add new scripts here. Don't forget to update the list in */ - /* `afglobal.c'. */ - - AF_SCRIPT_MAX /* do not remove */ - - } AF_Script; - - - typedef struct AF_ScriptClassRec_ const* AF_ScriptClass; - typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; - - typedef struct AF_ScriptMetricsRec_ - { - AF_ScriptClass clazz; - AF_ScalerRec scaler; - FT_Bool digits_have_same_width; - - AF_FaceGlobals globals; /* to access properties */ - - } AF_ScriptMetricsRec, *AF_ScriptMetrics; - - - /* This function parses an FT_Face to compute global metrics for - * a specific script. - */ - typedef FT_Error - (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics, - FT_Face face ); - - typedef void - (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics, - AF_Scaler scaler ); - - typedef void - (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics ); - - - typedef FT_Error - (*AF_Script_InitHintsFunc)( AF_GlyphHints hints, - AF_ScriptMetrics metrics ); - - typedef void - (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints, - FT_Outline* outline, - AF_ScriptMetrics metrics ); - - - typedef struct AF_Script_UniRangeRec_ - { - FT_UInt32 first; - FT_UInt32 last; - - } AF_Script_UniRangeRec; - -#define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) } - - typedef const AF_Script_UniRangeRec *AF_Script_UniRange; - - - typedef struct AF_ScriptClassRec_ - { - AF_Script script; - AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */ - FT_UInt32 standard_char; /* for default width and height */ - - FT_Offset script_metrics_size; - AF_Script_InitMetricsFunc script_metrics_init; - AF_Script_ScaleMetricsFunc script_metrics_scale; - AF_Script_DoneMetricsFunc script_metrics_done; - - AF_Script_InitHintsFunc script_hints_init; - AF_Script_ApplyHintsFunc script_hints_apply; - - } AF_ScriptClassRec; - - - /* Declare and define vtables for classes */ -#ifndef FT_CONFIG_OPTION_PIC - -#define AF_DECLARE_SCRIPT_CLASS( script_class ) \ - FT_CALLBACK_TABLE const AF_ScriptClassRec \ - script_class; - -#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, def_char, \ - m_size, \ - m_init, m_scale, m_done, h_init, h_apply ) \ - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec script_class = \ - { \ - script_, \ - ranges, \ - def_char, \ - \ - m_size, \ - \ - m_init, \ - m_scale, \ - m_done, \ - \ - h_init, \ - h_apply \ - }; - -#else /* FT_CONFIG_OPTION_PIC */ - -#define AF_DECLARE_SCRIPT_CLASS( script_class ) \ - FT_LOCAL( void ) \ - FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ); - -#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, def_char, \ - m_size, \ - m_init, m_scale, m_done, h_init, h_apply ) \ - FT_LOCAL_DEF( void ) \ - FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ) \ - { \ - ac->script = script_; \ - ac->script_uni_ranges = ranges; \ - ac->default_char = def_char; \ - \ - ac->script_metrics_size = m_size; \ - \ - ac->script_metrics_init = m_init; \ - ac->script_metrics_scale = m_scale; \ - ac->script_metrics_done = m_done; \ - \ - ac->script_hints_init = h_init; \ - ac->script_hints_apply = h_apply; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* */ - -FT_END_HEADER - -#endif /* __AFTYPES_H__ */ - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/Jamfile b/drivers/freetype/freetype/src/base/Jamfile deleted file mode 100644 index 832e8b8424..0000000000 --- a/drivers/freetype/freetype/src/base/Jamfile +++ /dev/null @@ -1,60 +0,0 @@ -# FreeType 2 src/base Jamfile -# -# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - -SubDir FT2_TOP $(FT2_SRC_DIR) base ; - - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = ftadvanc ftcalc ftdbgmem ftgloadr - ftobjs ftoutln ftrfork ftsnames - ftstream fttrigon ftutil - basepic ftpic - ; - } - else - { - _sources = ftbase ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# Add the optional/replaceable files. -# -{ - local _sources = bbox bdf bitmap debug gasp - glyph gxval init lcdfil mm - otval pfr stroke synth system - type1 winfnt xf86 patent - ; - - Library $(FT2_LIB) : ft$(_sources).c ; -} - -# Add Macintosh-specific file to the library when necessary. -# -if $(MAC) -{ - Library $(FT2_LIB) : ftmac.c ; -} -else if $(OS) = MACOSX -{ - if $(FT2_MULTI) - { - Library $(FT2_LIB) : ftmac.c ; - } -} - -# end of src/base Jamfile diff --git a/drivers/freetype/freetype/src/base/ftcalc.c b/drivers/freetype/freetype/src/base/ftcalc.c deleted file mode 100644 index 0ec0d78930..0000000000 --- a/drivers/freetype/freetype/src/base/ftcalc.c +++ /dev/null @@ -1,974 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcalc.c */ -/* */ -/* Arithmetic computations (body). */ -/* */ -/* Copyright 1996-2006, 2008, 2012-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Support for 1-complement arithmetic has been totally dropped in this */ - /* release. You can still write your own code if you need it. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Implementing basic computation routines. */ - /* */ - /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ - /* and FT_FloorFix() are declared in freetype.h. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_GLYPH_H -#include FT_TRIGONOMETRY_H -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H - -#ifdef FT_MULFIX_INLINED -#undef FT_MulFix -#endif - -/* we need to emulate a 64-bit data type if a real one isn't available */ - -#ifndef FT_LONG64 - - typedef struct FT_Int64_ - { - FT_UInt32 lo; - FT_UInt32 hi; - - } FT_Int64; - -#endif /* !FT_LONG64 */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_calc - - - /* The following three functions are available regardless of whether */ - /* FT_LONG64 is defined. */ - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_RoundFix( FT_Fixed a ) - { - return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL - : -((-a + 0x8000L ) & ~0xFFFFL ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_CeilFix( FT_Fixed a ) - { - return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL - : -((-a + 0xFFFFL ) & ~0xFFFFL ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_FloorFix( FT_Fixed a ) - { - return ( a >= 0 ) ? a & ~0xFFFFL - : -((-a) & ~0xFFFFL ); - } - - - FT_BASE_DEF ( FT_Int ) - FT_MSB( FT_UInt32 z ) - { - FT_Int shift = 0; - - /* determine msb bit index in `shift' */ - if ( z >= ( 1L << 16 ) ) - { - z >>= 16; - shift += 16; - } - if ( z >= ( 1L << 8 ) ) - { - z >>= 8; - shift += 8; - } - if ( z >= ( 1L << 4 ) ) - { - z >>= 4; - shift += 4; - } - if ( z >= ( 1L << 2 ) ) - { - z >>= 2; - shift += 2; - } - if ( z >= ( 1L << 1 ) ) - { - z >>= 1; - shift += 1; - } - - return shift; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Fixed ) - FT_Hypot( FT_Fixed x, - FT_Fixed y ) - { - FT_Vector v; - - - v.x = x; - v.y = y; - - return FT_Vector_Length( &v ); - } - - -#ifdef FT_LONG64 - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) - { - FT_Int s; - FT_Long d; - - - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } - - d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c - : 0x7FFFFFFFL ); - - return ( s > 0 ) ? d : -d; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) - { - FT_Int s; - FT_Long d; - - - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } - - d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c - : 0x7FFFFFFFL ); - - return ( s > 0 ) ? d : -d; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) - { -#ifdef FT_MULFIX_ASSEMBLER - - return FT_MULFIX_ASSEMBLER( a, b ); - -#else - - FT_Int s = 1; - FT_Long c; - - - if ( a < 0 ) - { - a = -a; - s = -1; - } - - if ( b < 0 ) - { - b = -b; - s = -s; - } - - c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); - - return ( s > 0 ) ? c : -c; - -#endif /* FT_MULFIX_ASSEMBLER */ - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = 1; - if ( a < 0 ) - { - a = -a; - s = -1; - } - if ( b < 0 ) - { - b = -b; - s = -s; - } - - if ( b == 0 ) - /* check for division by 0 */ - q = 0x7FFFFFFFL; - else - /* compute result directly */ - q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b ); - - return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); - } - - -#else /* !FT_LONG64 */ - - - static void - ft_multo64( FT_UInt32 x, - FT_UInt32 y, - FT_Int64 *z ) - { - FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; - - - lo1 = x & 0x0000FFFFU; hi1 = x >> 16; - lo2 = y & 0x0000FFFFU; hi2 = y >> 16; - - lo = lo1 * lo2; - i1 = lo1 * hi2; - i2 = lo2 * hi1; - hi = hi1 * hi2; - - /* Check carry overflow of i1 + i2 */ - i1 += i2; - hi += (FT_UInt32)( i1 < i2 ) << 16; - - hi += i1 >> 16; - i1 = i1 << 16; - - /* Check carry overflow of i1 + lo */ - lo += i1; - hi += ( lo < i1 ); - - z->lo = lo; - z->hi = hi; - } - - - static FT_UInt32 - ft_div64by32( FT_UInt32 hi, - FT_UInt32 lo, - FT_UInt32 y ) - { - FT_UInt32 r, q; - FT_Int i; - - - q = 0; - r = hi; - - if ( r >= y ) - return (FT_UInt32)0x7FFFFFFFL; - - i = 32; - do - { - r <<= 1; - q <<= 1; - r |= lo >> 31; - - if ( r >= y ) - { - r -= y; - q |= 1; - } - lo <<= 1; - } while ( --i ); - - return q; - } - - - static void - FT_Add64( FT_Int64* x, - FT_Int64* y, - FT_Int64 *z ) - { - register FT_UInt32 lo, hi; - - - lo = x->lo + y->lo; - hi = x->hi + y->hi + ( lo < x->lo ); - - z->lo = lo; - z->hi = hi; - } - - - /* documentation is in freetype.h */ - - /* The FT_MulDiv function has been optimized thanks to ideas from */ - /* Graham Asher. The trick is to optimize computation when everything */ - /* fits within 32-bits (a rather common case). */ - /* */ - /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */ - /* */ - /* 46340 is FLOOR(SQRT(2^31-1)). */ - /* */ - /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */ - /* */ - /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */ - /* */ - /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */ - /* */ - /* and 2*0x157F0 = 176096 */ - /* */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) - { - long s; - - - /* XXX: this function does not allow 64-bit arguments */ - if ( a == 0 || b == c ) - return a; - - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); - - if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) - a = ( a * b + ( c >> 1 ) ) / c; - - else if ( (FT_Int32)c > 0 ) - { - FT_Int64 temp, temp2; - - - ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); - - temp2.hi = 0; - temp2.lo = (FT_UInt32)(c >> 1); - FT_Add64( &temp, &temp2, &temp ); - a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); - } - else - a = 0x7FFFFFFFL; - - return ( s < 0 ? -a : a ); - } - - - FT_BASE_DEF( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) - { - long s; - - - if ( a == 0 || b == c ) - return a; - - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); - - if ( a <= 46340L && b <= 46340L && c > 0 ) - a = a * b / c; - - else if ( (FT_Int32)c > 0 ) - { - FT_Int64 temp; - - - ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); - a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); - } - else - a = 0x7FFFFFFFL; - - return ( s < 0 ? -a : a ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) - { -#ifdef FT_MULFIX_ASSEMBLER - - return FT_MULFIX_ASSEMBLER( a, b ); - -#elif 0 - - /* - * This code is nonportable. See comment below. - * - * However, on a platform where right-shift of a signed quantity fills - * the leftmost bits by copying the sign bit, it might be faster. - */ - - FT_Long sa, sb; - FT_ULong ua, ub; - - - if ( a == 0 || b == 0x10000L ) - return a; - - /* - * This is a clever way of converting a signed number `a' into its - * absolute value (stored back into `a') and its sign. The sign is - * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' - * was negative. (Similarly for `b' and `sb'). - * - * Unfortunately, it doesn't work (at least not portably). - * - * It makes the assumption that right-shift on a negative signed value - * fills the leftmost bits by copying the sign bit. This is wrong. - * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, - * the result of right-shift of a negative signed value is - * implementation-defined. At least one implementation fills the - * leftmost bits with 0s (i.e., it is exactly the same as an unsigned - * right shift). This means that when `a' is negative, `sa' ends up - * with the value 1 rather than -1. After that, everything else goes - * wrong. - */ - sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); - a = ( a ^ sa ) - sa; - sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); - b = ( b ^ sb ) - sb; - - ua = (FT_ULong)a; - ub = (FT_ULong)b; - - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000U ) >> 16; - else - { - FT_ULong al = ua & 0xFFFFU; - - - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); - } - - sa ^= sb, - ua = (FT_ULong)(( ua ^ sa ) - sa); - - return (FT_Long)ua; - -#else /* 0 */ - - FT_Long s; - FT_ULong ua, ub; - - - if ( a == 0 || b == 0x10000L ) - return a; - - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - - ua = (FT_ULong)a; - ub = (FT_ULong)b; - - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000UL ) >> 16; - else - { - FT_ULong al = ua & 0xFFFFUL; - - - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); - } - - return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); - -#endif /* 0 */ - - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ) - { - FT_Int32 s; - FT_UInt32 q; - - - /* XXX: this function does not allow 64-bit arguments */ - s = (FT_Int32)a; a = FT_ABS( a ); - s ^= (FT_Int32)b; b = FT_ABS( b ); - - if ( (FT_UInt32)b == 0 ) - { - /* check for division by 0 */ - q = (FT_UInt32)0x7FFFFFFFL; - } - else if ( ( a >> 16 ) == 0 ) - { - /* compute result directly */ - q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b; - } - else - { - /* we need more bits; we have to do it by hand */ - FT_Int64 temp, temp2; - - - temp.hi = (FT_Int32)( a >> 16 ); - temp.lo = (FT_UInt32)a << 16; - temp2.hi = 0; - temp2.lo = (FT_UInt32)( b >> 1 ); - FT_Add64( &temp, &temp2, &temp ); - q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - -#if 0 - - /* documentation is in ftcalc.h */ - - FT_EXPORT_DEF( void ) - FT_MulTo64( FT_Int32 x, - FT_Int32 y, - FT_Int64 *z ) - { - FT_Int32 s; - - - s = x; x = FT_ABS( x ); - s ^= y; y = FT_ABS( y ); - - ft_multo64( x, y, z ); - - if ( s < 0 ) - { - z->lo = (FT_UInt32)-(FT_Int32)z->lo; - z->hi = ~z->hi + !( z->lo ); - } - } - - - /* apparently, the second version of this code is not compiled correctly */ - /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ - -#if 1 - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q, r, i, lo; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = x->lo / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - r = x->hi; - lo = x->lo; - - if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */ - return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL ); - /* Return Max/Min Int32 if division overflow. */ - /* This includes division by zero! */ - q = 0; - for ( i = 0; i < 32; i++ ) - { - r <<= 1; - q <<= 1; - r |= lo >> 31; - - if ( r >= (FT_UInt32)y ) - { - r -= y; - q |= 1; - } - lo <<= 1; - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - -#else /* 0 */ - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = ( x->lo + ( y >> 1 ) ) / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - q = ft_div64by32( x->hi, x->lo, y ); - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - -#endif /* 0 */ - -#endif /* 0 */ - - -#endif /* FT_LONG64 */ - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( void ) - FT_Matrix_Multiply( const FT_Matrix* a, - FT_Matrix *b ) - { - FT_Fixed xx, xy, yx, yy; - - - if ( !a || !b ) - return; - - xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); - xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); - yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); - yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Matrix_Invert( FT_Matrix* matrix ) - { - FT_Pos delta, xx, yy; - - - if ( !matrix ) - return FT_THROW( Invalid_Argument ); - - /* compute discriminant */ - delta = FT_MulFix( matrix->xx, matrix->yy ) - - FT_MulFix( matrix->xy, matrix->yx ); - - if ( !delta ) - return FT_THROW( Invalid_Argument ); /* matrix can't be inverted */ - - matrix->xy = - FT_DivFix( matrix->xy, delta ); - matrix->yx = - FT_DivFix( matrix->yx, delta ); - - xx = matrix->xx; - yy = matrix->yy; - - matrix->xx = FT_DivFix( yy, delta ); - matrix->yy = FT_DivFix( xx, delta ); - - return FT_Err_Ok; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( void ) - FT_Matrix_Multiply_Scaled( const FT_Matrix* a, - FT_Matrix *b, - FT_Long scaling ) - { - FT_Fixed xx, xy, yx, yy; - - FT_Long val = 0x10000L * scaling; - - - if ( !a || !b ) - return; - - xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); - xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); - yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); - yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( void ) - FT_Vector_Transform_Scaled( FT_Vector* vector, - const FT_Matrix* matrix, - FT_Long scaling ) - { - FT_Pos xz, yz; - - FT_Long val = 0x10000L * scaling; - - - if ( !vector || !matrix ) - return; - - xz = FT_MulDiv( vector->x, matrix->xx, val ) + - FT_MulDiv( vector->y, matrix->xy, val ); - - yz = FT_MulDiv( vector->x, matrix->yx, val ) + - FT_MulDiv( vector->y, matrix->yy, val ); - - vector->x = xz; - vector->y = yz; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Int32 ) - FT_SqrtFixed( FT_Int32 x ) - { - FT_UInt32 root, rem_hi, rem_lo, test_div; - FT_Int count; - - - root = 0; - - if ( x > 0 ) - { - rem_hi = 0; - rem_lo = x; - count = 24; - do - { - rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); - rem_lo <<= 2; - root <<= 1; - test_div = ( root << 1 ) + 1; - - if ( rem_hi >= test_div ) - { - rem_hi -= test_div; - root += 1; - } - } while ( --count ); - } - - return (FT_Int32)root; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Int ) - ft_corner_orientation( FT_Pos in_x, - FT_Pos in_y, - FT_Pos out_x, - FT_Pos out_y ) - { - FT_Long result; /* avoid overflow on 16-bit system */ - - - /* deal with the trivial cases quickly */ - if ( in_y == 0 ) - { - if ( in_x >= 0 ) - result = out_y; - else - result = -out_y; - } - else if ( in_x == 0 ) - { - if ( in_y >= 0 ) - result = -out_x; - else - result = out_x; - } - else if ( out_y == 0 ) - { - if ( out_x >= 0 ) - result = in_y; - else - result = -in_y; - } - else if ( out_x == 0 ) - { - if ( out_y >= 0 ) - result = -in_x; - else - result = in_x; - } - else /* general case */ - { -#ifdef FT_LONG64 - - FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; - - - if ( delta == 0 ) - result = 0; - else - result = 1 - 2 * ( delta < 0 ); - -#else - - FT_Int64 z1, z2; - - - /* XXX: this function does not allow 64-bit arguments */ - ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); - ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); - - if ( z1.hi > z2.hi ) - result = +1; - else if ( z1.hi < z2.hi ) - result = -1; - else if ( z1.lo > z2.lo ) - result = +1; - else if ( z1.lo < z2.lo ) - result = -1; - else - result = 0; - -#endif - } - - /* XXX: only the sign of return value, +1/0/-1 must be used */ - return (FT_Int)result; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Int ) - ft_corner_is_flat( FT_Pos in_x, - FT_Pos in_y, - FT_Pos out_x, - FT_Pos out_y ) - { - FT_Pos ax = in_x; - FT_Pos ay = in_y; - - FT_Pos d_in, d_out, d_corner; - - - if ( ax < 0 ) - ax = -ax; - if ( ay < 0 ) - ay = -ay; - d_in = ax + ay; - - ax = out_x; - if ( ax < 0 ) - ax = -ax; - ay = out_y; - if ( ay < 0 ) - ay = -ay; - d_out = ax + ay; - - ax = out_x + in_x; - if ( ax < 0 ) - ax = -ax; - ay = out_y + in_y; - if ( ay < 0 ) - ay = -ay; - d_corner = ax + ay; - - return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); - } - - -/* END */ diff --git a/drivers/freetype/freetype/src/base/ftpatent.c b/drivers/freetype/freetype/src/base/ftpatent.c deleted file mode 100644 index 82b42f0343..0000000000 --- a/drivers/freetype/freetype/src/base/ftpatent.c +++ /dev/null @@ -1,286 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftpatent.c */ -/* */ -/* FreeType API for checking patented TrueType bytecode instructions */ -/* (body). */ -/* */ -/* Copyright 2007, 2008, 2010 by David Turner. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_TRUETYPE_TAGS_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_STREAM_H -#include FT_SERVICE_SFNT_H -#include FT_SERVICE_TRUETYPE_GLYF_H - - - static FT_Bool - _tt_check_patents_in_range( FT_Stream stream, - FT_ULong size ) - { - FT_Bool result = FALSE; - FT_Error error; - FT_Bytes p, end; - - - if ( FT_FRAME_ENTER( size ) ) - return 0; - - p = stream->cursor; - end = p + size; - - while ( p < end ) - { - switch (p[0]) - { - case 0x06: /* SPvTL // */ - case 0x07: /* SPvTL + */ - case 0x08: /* SFvTL // */ - case 0x09: /* SFvTL + */ - case 0x0A: /* SPvFS */ - case 0x0B: /* SFvFS */ - result = TRUE; - goto Exit; - - case 0x40: - if ( p + 1 >= end ) - goto Exit; - - p += p[1] + 2; - break; - - case 0x41: - if ( p + 1 >= end ) - goto Exit; - - p += p[1] * 2 + 2; - break; - - case 0x71: /* DELTAP2 */ - case 0x72: /* DELTAP3 */ - case 0x73: /* DELTAC0 */ - case 0x74: /* DELTAC1 */ - case 0x75: /* DELTAC2 */ - result = TRUE; - goto Exit; - - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - p += ( p[0] - 0xB0 ) + 2; - break; - - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - p += ( p[0] - 0xB8 ) * 2 + 3; - break; - - default: - p += 1; - break; - } - } - - Exit: - FT_UNUSED( error ); - FT_FRAME_EXIT(); - return result; - } - - - static FT_Bool - _tt_check_patents_in_table( FT_Face face, - FT_ULong tag ) - { - FT_Stream stream = face->stream; - FT_Error error = FT_Err_Ok; - FT_Service_SFNT_Table service; - FT_Bool result = FALSE; - - - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - - if ( service ) - { - FT_UInt i = 0; - FT_ULong tag_i = 0, offset_i = 0, length_i = 0; - - - for ( i = 0; !error && tag_i != tag ; i++ ) - error = service->table_info( face, i, - &tag_i, &offset_i, &length_i ); - - if ( error || - FT_STREAM_SEEK( offset_i ) ) - goto Exit; - - result = _tt_check_patents_in_range( stream, length_i ); - } - - Exit: - return result; - } - - - static FT_Bool - _tt_face_check_patents( FT_Face face ) - { - FT_Stream stream = face->stream; - FT_UInt gindex; - FT_Error error; - FT_Bool result; - - FT_Service_TTGlyf service; - - - result = _tt_check_patents_in_table( face, TTAG_fpgm ); - if ( result ) - goto Exit; - - result = _tt_check_patents_in_table( face, TTAG_prep ); - if ( result ) - goto Exit; - - FT_FACE_FIND_SERVICE( face, service, TT_GLYF ); - if ( service == NULL ) - goto Exit; - - for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ ) - { - FT_ULong offset, num_ins, size; - FT_Int num_contours; - - - offset = service->get_location( face, gindex, &size ); - if ( size == 0 ) - continue; - - if ( FT_STREAM_SEEK( offset ) || - FT_READ_SHORT( num_contours ) ) - continue; - - if ( num_contours >= 0 ) /* simple glyph */ - { - if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) ) - continue; - } - else /* compound glyph */ - { - FT_Bool has_instr = 0; - - - if ( FT_STREAM_SKIP( 8 ) ) - continue; - - /* now read each component */ - for (;;) - { - FT_UInt flags, toskip; - - - if( FT_READ_USHORT( flags ) ) - break; - - toskip = 2 + 1 + 1; - - if ( ( flags & ( 1 << 0 ) ) != 0 ) /* ARGS_ARE_WORDS */ - toskip += 2; - - if ( ( flags & ( 1 << 3 ) ) != 0 ) /* WE_HAVE_A_SCALE */ - toskip += 2; - else if ( ( flags & ( 1 << 6 ) ) != 0 ) /* WE_HAVE_X_Y_SCALE */ - toskip += 4; - else if ( ( flags & ( 1 << 7 ) ) != 0 ) /* WE_HAVE_A_2x2 */ - toskip += 8; - - if ( ( flags & ( 1 << 8 ) ) != 0 ) /* WE_HAVE_INSTRUCTIONS */ - has_instr = 1; - - if ( FT_STREAM_SKIP( toskip ) ) - goto NextGlyph; - - if ( ( flags & ( 1 << 5 ) ) == 0 ) /* MORE_COMPONENTS */ - break; - } - - if ( !has_instr ) - goto NextGlyph; - } - - if ( FT_READ_USHORT( num_ins ) ) - continue; - - result = _tt_check_patents_in_range( stream, num_ins ); - if ( result ) - goto Exit; - - NextGlyph: - ; - } - - Exit: - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Bool ) - FT_Face_CheckTrueTypePatents( FT_Face face ) - { - FT_Bool result = FALSE; - - - if ( face && FT_IS_SFNT( face ) ) - result = _tt_face_check_patents( face ); - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Bool ) - FT_Face_SetUnpatentedHinting( FT_Face face, - FT_Bool value ) - { - FT_Bool result = FALSE; - - -#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ - !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) - if ( face && FT_IS_SFNT( face ) ) - { - result = !face->internal->ignore_unpatented_hinter; - face->internal->ignore_unpatented_hinter = !value; - } -#else - FT_UNUSED( face ); - FT_UNUSED( value ); -#endif - - return result; - } - -/* END */ diff --git a/drivers/freetype/freetype/include/freetype/config/ftconfig.h b/drivers/freetype/include/freetype/config/ftconfig.h index 5dce30ef3e..157a704fa8 100644 --- a/drivers/freetype/freetype/include/freetype/config/ftconfig.h +++ b/drivers/freetype/include/freetype/config/ftconfig.h @@ -4,7 +4,7 @@ /* */ /* ANSI-specific configuration file (specification only). */ /* */ -/* Copyright 1996-2004, 2006-2008, 2010-2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,16 +27,16 @@ /* Note however that if some specific modifications are needed, we */ /* advise you to place a modified copy in your build directory. */ /* */ - /* The build directory is usually `freetype/builds/<system>', and */ - /* contains system-specific files that are always included first when */ - /* building the library. */ + /* The build directory is usually `builds/<system>', and contains */ + /* system-specific files that are always included first when building */ + /* the library. */ /* */ - /* This ANSI version should stay in `include/freetype/config'. */ + /* This ANSI version should stay in `include/config/'. */ /* */ /*************************************************************************/ -#ifndef __FTCONFIG_H__ -#define __FTCONFIG_H__ +#ifndef FTCONFIG_H_ +#define FTCONFIG_H_ #include <ft2build.h> #include FT_CONFIG_OPTIONS_H @@ -53,7 +53,7 @@ FT_BEGIN_HEADER /* These macros can be toggled to suit a specific system. The current */ /* ones are defaults used to compile FreeType in an ANSI C environment */ /* (16bit compilers are also supported). Copy this file to your own */ - /* `freetype/builds/<system>' directory, and edit it to port the engine. */ + /* `builds/<system>' directory, and edit it to port the engine. */ /* */ /*************************************************************************/ @@ -266,6 +266,21 @@ FT_BEGIN_HEADER #define FT_INT64 long #define FT_UINT64 unsigned long + /*************************************************************************/ + /* */ + /* A 64-bit data type may create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable other 64-bit data */ + /* types if __STDC__ is defined. You can however ignore this rule */ + /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L + +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + #elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ /* this compiler provides the __int64 type */ @@ -300,27 +315,9 @@ FT_BEGIN_HEADER #define FT_INT64 long long int #define FT_UINT64 unsigned long long int -#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ - - - /*************************************************************************/ - /* */ - /* A 64-bit data type will create compilation problems if you compile */ - /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */ - /* is defined. You can however ignore this rule by defining the */ - /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ - /* */ -#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) - -#ifdef __STDC__ - - /* undefine the 64-bit macros in strict ANSI compilation mode */ -#undef FT_LONG64 -#undef FT_INT64 - -#endif /* __STDC__ */ +#endif /* __STDC_VERSION__ >= 199901L */ -#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ #ifdef FT_LONG64 typedef FT_INT64 FT_Int64; @@ -328,150 +325,25 @@ FT_BEGIN_HEADER #endif + /*************************************************************************/ + /* */ + /* miscellaneous */ + /* */ + /*************************************************************************/ + + #define FT_BEGIN_STMNT do { #define FT_END_STMNT } while ( 0 ) #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT -#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER - /* Provide assembler fragments for performance-critical functions. */ - /* These must be defined `static __inline__' with GCC. */ - -#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm - { - smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ - mov a, t, asr #31 /* a = (hi >> 31) */ - add a, a, #0x8000 /* a += 0x8000 */ - adds t2, t2, a /* t2 += a */ - adc t, t, #0 /* t += carry */ - mov a, t2, lsr #16 /* a = t2 >> 16 */ - orr a, a, t, lsl #16 /* a |= t << 16 */ - } - return a; - } - -#endif /* __CC_ARM || __ARMCC__ */ - - -#ifdef __GNUC__ - -#if defined( __arm__ ) && !defined( __thumb__ ) && \ - !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm__ __volatile__ ( - "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ - "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ - "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ - "adds %1, %1, %0\n\t" /* %1 += %0 */ - "adc %2, %2, #0\n\t" /* %2 += carry */ - "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ - "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ - : "=r"(a), "=&r"(t2), "=&r"(t) - : "r"(a), "r"(b) - : "cc" ); - return a; - } - -#endif /* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */ - -#if defined( __i386__ ) -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - - __asm__ __volatile__ ( - "imul %%edx\n" - "movl %%edx, %%ecx\n" - "sarl $31, %%ecx\n" - "addl $0x8000, %%ecx\n" - "addl %%ecx, %%eax\n" - "adcl $0, %%edx\n" - "shrl $16, %%eax\n" - "shll $16, %%edx\n" - "addl %%edx, %%eax\n" - : "=a"(result), "=d"(b) - : "a"(a), "d"(b) - : "%ecx", "cc" ); - return result; - } - -#endif /* i386 */ - -#endif /* __GNUC__ */ - - -#ifdef _MSC_VER /* Visual C++ */ - -#ifdef _M_IX86 - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - __asm - { - mov eax, a - mov edx, b - imul edx - mov ecx, edx - sar ecx, 31 - add ecx, 8000h - add eax, ecx - adc edx, 0 - shr eax, 16 - shl edx, 16 - add eax, edx - mov result, eax - } - return result; - } - -#endif /* _M_IX86 */ - -#endif /* _MSC_VER */ - -#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ - - -#ifdef FT_CONFIG_OPTION_INLINE_MULFIX -#ifdef FT_MULFIX_ASSEMBLER -#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER -#endif + /* typeof condition taken from gnulib's `intprops.h' header file */ +#if ( __GNUC__ >= 2 || \ + defined( __IBM__TYPEOF__ ) || \ + ( __SUNPRO_C >= 0x5110 && !__STDC__ ) ) +#define FT_TYPEOF( type ) (__typeof__ (type)) +#else +#define FT_TYPEOF( type ) /* empty */ #endif @@ -492,6 +364,9 @@ FT_BEGIN_HEADER #endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ +#define FT_LOCAL_ARRAY( x ) extern const x +#define FT_LOCAL_ARRAY_DEF( x ) const x + #ifndef FT_BASE @@ -592,7 +467,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCONFIG_H__ */ +#endif /* FTCONFIG_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/config/ftheader.h b/drivers/freetype/include/freetype/config/ftheader.h index 8371a31611..68e14834d4 100644 --- a/drivers/freetype/freetype/include/freetype/config/ftheader.h +++ b/drivers/freetype/include/freetype/config/ftheader.h @@ -4,7 +4,7 @@ /* */ /* Build macros of the FreeType 2 library. */ /* */ -/* Copyright 1996-2008, 2010, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __FT_HEADER_H__ -#define __FT_HEADER_H__ +#ifndef FTHEADER_H_ +#define FTHEADER_H_ /*@***********************************************************************/ @@ -710,14 +710,16 @@ /************************************************************************* * * @macro: - * FT_XFREE86_H + * FT_FONT_FORMATS_H * * @description: * A macro used in #include statements to name the file containing the - * FreeType~2 API which provides functions specific to the XFree86 and - * X.Org X11 servers. + * FreeType~2 API which provides functions specific to font formats. */ -#define FT_XFREE86_H <freetype/ftxf86.h> +#define FT_FONT_FORMATS_H <freetype/ftfntfmt.h> + + /* deprecated */ +#define FT_XFREE86_H FT_FONT_FORMATS_H /************************************************************************* @@ -751,8 +753,7 @@ * FT_UNPATENTED_HINTING_H * * @description: - * A macro used in #include statements to name the file containing the - * FreeType~2 API which performs color filtering for subpixel rendering. + * Deprecated. */ #define FT_UNPATENTED_HINTING_H <freetype/ttunpat.h> @@ -764,7 +765,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType~2 API which performs color filtering for subpixel rendering. + * FreeType~2 API which performs incremental glyph loading. */ #define FT_INCREMENTAL_H <freetype/ftincrem.h> @@ -817,7 +818,7 @@ /* - * Include internal headers definitions from <freetype/internal/...> + * Include internal headers definitions from <internal/...> * only when building the library. */ #ifdef FT2_BUILD_LIBRARY @@ -826,7 +827,7 @@ #endif /* FT2_BUILD_LIBRARY */ -#endif /* __FT2_BUILD_H__ */ +#endif /* FTHEADER_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/config/ftmodule.h b/drivers/freetype/include/freetype/config/ftmodule.h index 76d271a74b..76d271a74b 100644 --- a/drivers/freetype/freetype/include/freetype/config/ftmodule.h +++ b/drivers/freetype/include/freetype/config/ftmodule.h diff --git a/drivers/freetype/freetype/include/freetype/config/ftoption.h b/drivers/freetype/include/freetype/config/ftoption.h index d162780665..afd32f1cda 100644 --- a/drivers/freetype/freetype/include/freetype/config/ftoption.h +++ b/drivers/freetype/include/freetype/config/ftoption.h @@ -4,7 +4,7 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTOPTION_H__ -#define __FTOPTION_H__ +#ifndef FTOPTION_H_ +#define FTOPTION_H_ #include <ft2build.h> @@ -61,7 +61,7 @@ FT_BEGIN_HEADER /* that are statically linked to the library at compile time. By */ /* default, this file is <freetype/config/ftmodule.h>. */ /* */ - /* We highly recommend using the third method whenever possible. */ + /* We highly recommend using the third method whenever possible. */ /* */ /*************************************************************************/ @@ -148,7 +148,7 @@ FT_BEGIN_HEADER /* */ /* Define this macro if you want to enable this `feature'. */ /* */ -#define FT_CONFIG_OPTION_USE_LZW +/* #define FT_CONFIG_OPTION_USE_LZW */ // -GODOT- /*************************************************************************/ @@ -163,7 +163,7 @@ FT_BEGIN_HEADER /* Define this macro if you want to enable this `feature'. See also */ /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ /* */ -#define FT_CONFIG_OPTION_USE_ZLIB +/* #define FT_CONFIG_OPTION_USE_ZLIB */ // -GODOT- /*************************************************************************/ @@ -216,7 +216,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* PNG bitmap support. */ + /* PNG bitmap support. */ /* */ /* FreeType now handles loading color bitmap glyphs in the PNG format. */ /* This requires help from the external libpng library. Uncompressed */ @@ -230,6 +230,19 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ + /* HarfBuzz support. */ + /* */ + /* FreeType uses the HarfBuzz library to improve auto-hinting of */ + /* OpenType fonts. If available, many glyphs not directly addressable */ + /* by a font's character map will be hinted also. */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */ + + + /*************************************************************************/ + /* */ /* DLL export compilation */ /* */ /* When compiling FreeType as a DLL, some systems/compilers need a */ @@ -365,10 +378,6 @@ FT_BEGIN_HEADER /* The size in bytes of the render pool used by the scan-line converter */ /* to do all of its work. */ /* */ - /* This must be greater than 4KByte if you use FreeType to rasterize */ - /* glyphs; otherwise, you may set it to zero to avoid unnecessary */ - /* allocation of the render pool. */ - /* */ #define FT_RENDER_POOL_SIZE 16384L @@ -422,6 +431,8 @@ FT_BEGIN_HEADER /* af_glyph_hints_dump_points */ /* af_glyph_hints_dump_segments */ /* af_glyph_hints_dump_edges */ + /* af_glyph_hints_get_num_segments */ + /* af_glyph_hints_get_segment_offset */ /* */ /* As an argument, they use another global variable: */ /* */ @@ -528,7 +539,7 @@ FT_BEGIN_HEADER /* does not contain any glyph name though. */ /* */ /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftsnames.h'. */ + /* `ftsnames.h'. */ /* */ #define TT_CONFIG_OPTION_SFNT_NAMES @@ -575,86 +586,53 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ - /* replaces the native TrueType hinting mechanism when anything but */ - /* FT_RENDER_MODE_MONO is requested. */ - /* */ - /* Enabling this causes the TrueType driver to ignore instructions under */ - /* certain conditions. This is done in accordance with the guide here, */ - /* with some minor differences: */ - /* */ - /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ - /* By undefining this, you only compile the code necessary to hint */ - /* TrueType glyphs with native TT hinting. */ - /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ + /* subpixel hinting support into the TrueType driver. This modifies the */ + /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */ + /* requested. */ /* */ -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - /*************************************************************************/ - /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ - /* TrueType hinting have expired worldwide since May 2010; this option */ - /* is now deprecated. */ - /* */ - /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ - /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ - /* */ - /* This macro is only useful for a small number of font files (mostly */ - /* for Asian scripts) that require bytecode interpretation to properly */ - /* load glyphs. For all other fonts, this produces unpleasant results, */ - /* thus the unpatented interpreter is never used to load glyphs from */ - /* TrueType fonts unless one of the following two options is used. */ - /* */ - /* - The unpatented interpreter is explicitly activated by the user */ - /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ - /* when opening the FT_Face. */ + /* In particular, it modifies the bytecode interpreter to interpret (or */ + /* not) instructions in a certain way so that all TrueType fonts look */ + /* like they do in a Windows ClearType (DirectWrite) environment. See */ + /* [1] for a technical overview on what this means. See `ttinterp.h' */ + /* for more details on the LEAN option. */ /* */ - /* - FreeType detects that the FT_Face corresponds to one of the */ - /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ - /* contains a hard-coded list of font names and other matching */ - /* parameters (see function `tt_face_init' in file */ - /* `src/truetype/ttobjs.c'). */ + /* There are three options. */ /* */ - /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ + /* 1. This option is associated with the `Infinality' moniker. */ + /* Contributed by an individual nicknamed Infinality with the goal of */ + /* making TrueType fonts render better than on Windows. A high */ + /* amount of configurability and flexibility, down to rules for */ + /* single glyphs in fonts, but also very slow. Its experimental and */ + /* slow nature and the original developer losing interest meant that */ + /* this option was never enabled in default builds. */ /* */ - /* { */ - /* FT_Parameter parameter; */ - /* FT_Open_Args open_args; */ + /* 2. The new default mode for the TrueType driver. The Infinality code */ + /* base was stripped to the bare minimum and all configurability */ + /* removed in the name of speed and simplicity. The configurability */ + /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */ + /* Courier. Legacy fonts are fonts that modify vertical stems to */ + /* achieve clean black-and-white bitmaps. The new mode focuses on */ + /* applying a minimal set of rules to all fonts indiscriminately so */ + /* that modern and web fonts render well while legacy fonts render */ + /* okay. */ /* */ + /* 3. Compile both. */ /* */ - /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ - /* */ - /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ - /* open_args.pathname = my_font_pathname; */ - /* open_args.num_params = 1; */ - /* open_args.params = ¶meter; */ - /* */ - /* error = FT_Open_Face( library, &open_args, index, &face ); */ - /* ... */ - /* } */ - /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ - - - /*************************************************************************/ + /* By undefining these, you get rendering behavior like on Windows */ + /* without ClearType, i.e., Windows XP without ClearType enabled and */ + /* Win9x (interpreter version v35). Or not, depending on how much */ + /* hinting blood and testing tears the font designer put into a given */ + /* font. If you define one or both subpixel hinting options, you can */ + /* switch between between v35 and the ones you define. */ /* */ - /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ - /* bytecode interpreter with a huge switch statement, rather than a call */ - /* table. This results in smaller and faster code for a number of */ - /* architectures. */ + /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ + /* defined. */ /* */ - /* Note however that on some compiler/processor combinations, undefining */ - /* this macro will generate faster, though larger, code. */ + /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ /* */ -#define TT_CONFIG_OPTION_INTERPRETER_SWITCH +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ /*************************************************************************/ @@ -671,7 +649,7 @@ FT_BEGIN_HEADER /* fonts will not have them. */ /* */ /* http://www.microsoft.com/typography/otspec/glyf.htm */ - /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */ /* */ #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED @@ -695,6 +673,24 @@ FT_BEGIN_HEADER /*************************************************************************/ + /* */ + /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum */ + /* number of bytecode instructions executed for a single run of the */ + /* bytecode interpreter, needed to prevent infinite loops. You don't */ + /* want to change this except for very special situations (e.g., making */ + /* a library fuzzer spend less time to handle broken fonts). */ + /* */ + /* It is not expected that this value is ever modified by a configuring */ + /* script; instead, it gets surrounded with #ifndef ... #endif so that */ + /* the value can be set as a preprocessor option on the compiler's */ + /* command line. */ + /* */ +#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES +#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L +#endif + + + /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ @@ -760,12 +756,36 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ + /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is */ + /* possible to set up the default values of the four control points that */ + /* define the stem darkening behaviour of the (new) CFF engine. For */ + /* more details please read the documentation of the */ + /* `darkening-parameters' property of the cff driver module (file */ + /* `ftcffdrv.h'), which allows the control at run-time. */ + /* */ + /* Do *not* undefine these macros! */ + /* */ +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 + + + /*************************************************************************/ + /* */ /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ /* engine gets compiled into FreeType. If defined, it is possible to */ /* switch between the two engines using the `hinting-engine' property of */ /* the cff driver module. */ /* */ -#define CFF_CONFIG_OPTION_OLD_ENGINE +/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ /*************************************************************************/ @@ -798,36 +818,72 @@ FT_BEGIN_HEADER /* grid. To find out the optimal scaling and shifting value, various */ /* parameter combinations are tried and scored. */ /* */ - /* This experimental option is only active if the render mode is */ - /* FT_RENDER_MODE_LIGHT. */ + /* This experimental option is active only if the rendering mode is */ + /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the */ + /* `warping' property of the auto-hinter (see file `ftautoh.h' for more */ + /* information; by default it is switched off). */ /* */ -/* #define AF_CONFIG_OPTION_USE_WARPER */ +#define AF_CONFIG_OPTION_USE_WARPER /* */ /* - * This macro is obsolete. Support has been removed in FreeType - * version 2.5. + * This macro is obsolete. Support has been removed in FreeType + * version 2.5. */ /* #define FT_CONFIG_OPTION_OLD_INTERNALS */ /* - * This macro is defined if either unpatented or native TrueType - * hinting is requested by the definitions above. + * This macro is defined if native TrueType hinting is requested by the + * definitions above. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER -#undef TT_CONFIG_OPTION_UNPATENTED_HINTING -#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING -#define TT_USE_BYTECODE_INTERPRETER + +#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1 +#define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY +#endif + +#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2 +#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL +#endif +#endif + + + /* + * Check CFF darkening parameters. The checks are the same as in function + * `cff_property_set' in file `cffdrivr.c'. + */ +#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500 +#error "Invalid CFF darkening parameters!" #endif FT_END_HEADER -#endif /* __FTOPTION_H__ */ +#endif /* FTOPTION_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/config/ftstdlib.h b/drivers/freetype/include/freetype/config/ftstdlib.h index b940efc427..562e255810 100644 --- a/drivers/freetype/freetype/include/freetype/config/ftstdlib.h +++ b/drivers/freetype/include/freetype/config/ftstdlib.h @@ -5,7 +5,7 @@ /* ANSI-specific library and header configuration file (specification */ /* only). */ /* */ -/* Copyright 2002-2007, 2009, 2011-2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,14 +23,13 @@ /* FreeType normally requires. It also defines macros to rename the */ /* standard functions within the FreeType source code. */ /* */ - /* Load a file which defines __FTSTDLIB_H__ before this one to override */ - /* it. */ + /* Load a file which defines FTSTDLIB_H_ before this one to override it. */ /* */ /*************************************************************************/ -#ifndef __FTSTDLIB_H__ -#define __FTSTDLIB_H__ +#ifndef FTSTDLIB_H_ +#define FTSTDLIB_H_ #include <stddef.h> @@ -64,6 +63,8 @@ #define FT_INT_MAX INT_MAX #define FT_INT_MIN INT_MIN #define FT_UINT_MAX UINT_MAX +#define FT_LONG_MIN LONG_MIN +#define FT_LONG_MAX LONG_MAX #define FT_ULONG_MAX ULONG_MAX @@ -141,8 +142,7 @@ /**********************************************************************/ -#define ft_atol atol -#define ft_labs labs +#define ft_atol atol /**********************************************************************/ @@ -168,7 +168,7 @@ #include <stdarg.h> -#endif /* __FTSTDLIB_H__ */ +#endif /* FTSTDLIB_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/freetype.h b/drivers/freetype/include/freetype/freetype.h index fe46d22978..45e10c48a2 100644 --- a/drivers/freetype/freetype/include/freetype/freetype.h +++ b/drivers/freetype/include/freetype/freetype.h @@ -4,7 +4,7 @@ /* */ /* FreeType high-level API and common types (specification only). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FREETYPE_H__ -#define __FREETYPE_H__ +#ifndef FREETYPE_H_ +#define FREETYPE_H_ #ifndef FT_FREETYPE_H @@ -42,6 +42,38 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ + /* header_inclusion */ + /* */ + /* <Title> */ + /* FreeType's header inclusion scheme */ + /* */ + /* <Abstract> */ + /* How client applications should include FreeType header files. */ + /* */ + /* <Description> */ + /* To be as flexible as possible (and for historical reasons), */ + /* FreeType uses a very special inclusion scheme to load header */ + /* files, for example */ + /* */ + /* { */ + /* #include <ft2build.h> */ + /* */ + /* #include FT_FREETYPE_H */ + /* #include FT_OUTLINE_H */ + /* } */ + /* */ + /* A compiler and its preprocessor only needs an include path to find */ + /* the file `ft2build.h'; the exact locations and names of the other */ + /* FreeType header files are hidden by preprocessor macro names, */ + /* loaded by `ft2build.h'. The API documentation always gives the */ + /* header macro name needed for a particular function. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ /* user_allocation */ /* */ /* <Title> */ @@ -81,7 +113,8 @@ FT_BEGIN_HEADER /* The FreeType~2 base font interface. */ /* */ /* <Description> */ - /* This section describes the public high-level API of FreeType~2. */ + /* This section describes the most important public high-level API */ + /* functions of FreeType~2. */ /* */ /* <Order> */ /* FT_Library */ @@ -90,6 +123,7 @@ FT_BEGIN_HEADER /* FT_GlyphSlot */ /* FT_CharMap */ /* FT_Encoding */ + /* FT_ENC_TAG */ /* */ /* FT_FaceRec */ /* */ @@ -98,14 +132,30 @@ FT_BEGIN_HEADER /* FT_FACE_FLAG_FIXED_WIDTH */ /* FT_FACE_FLAG_HORIZONTAL */ /* FT_FACE_FLAG_VERTICAL */ + /* FT_FACE_FLAG_COLOR */ /* FT_FACE_FLAG_SFNT */ + /* FT_FACE_FLAG_CID_KEYED */ + /* FT_FACE_FLAG_TRICKY */ /* FT_FACE_FLAG_KERNING */ /* FT_FACE_FLAG_MULTIPLE_MASTERS */ /* FT_FACE_FLAG_GLYPH_NAMES */ /* FT_FACE_FLAG_EXTERNAL_STREAM */ - /* FT_FACE_FLAG_FAST_GLYPHS */ /* FT_FACE_FLAG_HINTER */ /* */ + /* FT_HAS_HORIZONTAL */ + /* FT_HAS_VERTICAL */ + /* FT_HAS_KERNING */ + /* FT_HAS_FIXED_SIZES */ + /* FT_HAS_GLYPH_NAMES */ + /* FT_HAS_MULTIPLE_MASTERS */ + /* FT_HAS_COLOR */ + /* */ + /* FT_IS_SFNT */ + /* FT_IS_SCALABLE */ + /* FT_IS_FIXED_WIDTH */ + /* FT_IS_CID_KEYED */ + /* FT_IS_TRICKY */ + /* */ /* FT_STYLE_FLAG_BOLD */ /* FT_STYLE_FLAG_ITALIC */ /* */ @@ -123,6 +173,7 @@ FT_BEGIN_HEADER /* */ /* FT_New_Face */ /* FT_Done_Face */ + /* FT_Reference_Face */ /* FT_New_Memory_Face */ /* FT_Open_Face */ /* FT_Open_Args */ @@ -135,10 +186,13 @@ FT_BEGIN_HEADER /* FT_Request_Size */ /* FT_Select_Size */ /* FT_Size_Request_Type */ + /* FT_Size_RequestRec */ /* FT_Size_Request */ /* FT_Set_Transform */ /* FT_Load_Glyph */ /* FT_Get_Char_Index */ + /* FT_Get_First_Char */ + /* FT_Get_Next_Char */ /* FT_Get_Name_Index */ /* FT_Load_Char */ /* */ @@ -155,11 +209,11 @@ FT_BEGIN_HEADER /* FT_LOAD_NO_SCALE */ /* FT_LOAD_NO_HINTING */ /* FT_LOAD_NO_BITMAP */ - /* FT_LOAD_CROP_BITMAP */ + /* FT_LOAD_NO_AUTOHINT */ + /* FT_LOAD_COLOR */ /* */ /* FT_LOAD_VERTICAL_LAYOUT */ /* FT_LOAD_IGNORE_TRANSFORM */ - /* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ /* FT_LOAD_FORCE_AUTOHINT */ /* FT_LOAD_NO_RECURSE */ /* FT_LOAD_PEDANTIC */ @@ -170,6 +224,8 @@ FT_BEGIN_HEADER /* FT_LOAD_TARGET_LCD */ /* FT_LOAD_TARGET_LCD_V */ /* */ + /* FT_LOAD_TARGET_MODE */ + /* */ /* FT_Render_Glyph */ /* FT_Render_Mode */ /* FT_Get_Kerning */ @@ -183,14 +239,22 @@ FT_BEGIN_HEADER /* FT_Set_Charmap */ /* FT_Get_Charmap_Index */ /* */ - /* FT_FSTYPE_INSTALLABLE_EMBEDDING */ - /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING */ - /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING */ - /* FT_FSTYPE_EDITABLE_EMBEDDING */ - /* FT_FSTYPE_NO_SUBSETTING */ - /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY */ - /* */ /* FT_Get_FSType_Flags */ + /* FT_Get_SubGlyph_Info */ + /* */ + /* FT_Face_Internal */ + /* FT_Size_Internal */ + /* FT_Slot_Internal */ + /* */ + /* FT_FACE_FLAG_XXX */ + /* FT_STYLE_FLAG_XXX */ + /* FT_OPEN_XXX */ + /* FT_LOAD_XXX */ + /* FT_LOAD_TARGET_XXX */ + /* FT_SUBGLYPH_FLAG_XXX */ + /* FT_FSTYPE_XXX */ + /* */ + /* FT_HAS_FAST_GLYPHS */ /* */ /*************************************************************************/ @@ -329,8 +393,11 @@ FT_BEGIN_HEADER /* It also embeds a memory manager (see @FT_Memory), as well as a */ /* scan-line converter object (see @FT_Raster). */ /* */ - /* In multi-threaded applications, make sure that the same FT_Library */ - /* object or any of its children doesn't get accessed in parallel. */ + /* In multi-threaded applications it is easiest to use one */ + /* `FT_Library' object per thread. In case this is too cumbersome, */ + /* a single `FT_Library' object across threads is possible also */ + /* (since FreeType version 2.5.6), as long as a mutex lock is used */ + /* around @FT_New_Face and @FT_Done_Face. */ /* */ /* <Note> */ /* Library objects are normally created by @FT_Init_FreeType, and */ @@ -343,6 +410,13 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ + /* <Section> */ + /* module_management */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ /* <Type> */ /* FT_Module */ /* */ @@ -382,6 +456,13 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ + /* <Section> */ + /* base_interface */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ /* <Type> */ /* FT_Face */ /* */ @@ -398,6 +479,14 @@ FT_BEGIN_HEADER /* */ /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ /* */ + /* An `FT_Face' object can only be safely used from one thread at a */ + /* time. Similarly, creation and destruction of `FT_Face' with the */ + /* same @FT_Library object can only be done from one thread at a */ + /* time. On the other hand, functions like @FT_Load_Glyph and its */ + /* siblings are thread-safe and do not need the lock to be held as */ + /* long as the same `FT_Face' object is not used from multiple */ + /* threads at the same time. */ + /* */ /* <Also> */ /* See @FT_FaceRec for the publicly accessible fields of a given face */ /* object. */ @@ -417,7 +506,8 @@ FT_BEGIN_HEADER /* <Note> */ /* Each @FT_Face has an _active_ @FT_Size object that is used by */ /* functions like @FT_Load_Glyph to determine the scaling */ - /* transformation which is used to load and hint glyphs and metrics. */ + /* transformation that in turn is used to load and hint glyphs and */ + /* metrics. */ /* */ /* You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, */ /* @FT_Request_Size or even @FT_Select_Size to change the content */ @@ -551,16 +641,21 @@ FT_BEGIN_HEADER /* */ /* FT_ENCODING_MS_SYMBOL :: */ /* Corresponds to the Microsoft Symbol encoding, used to encode */ - /* mathematical symbols in the 32..255 character code range. For */ - /* more information, see `http://www.ceviz.net/symbol.htm'. */ + /* mathematical symbols and wingdings. For more information, see */ + /* `http://www.microsoft.com/typography/otspec/recom.htm', */ + /* `http://www.kostis.net/charsets/symbol.htm', and */ + /* `http://www.kostis.net/charsets/wingding.htm'. */ + /* */ + /* This encoding uses character codes from the PUA (Private Unicode */ + /* Area) in the range U+F020-U+F0FF. */ /* */ /* FT_ENCODING_SJIS :: */ /* Corresponds to Japanese SJIS encoding. More info at */ - /* at `http://langsupport.japanreference.com/encoding.shtml'. */ + /* `http://en.wikipedia.org/wiki/Shift_JIS'. */ /* See note on multi-byte encodings below. */ /* */ /* FT_ENCODING_GB2312 :: */ - /* Corresponds to an encoding system for Simplified Chinese as used */ + /* Corresponds to an encoding system for Simplified Chinese as */ /* used in mainland China. */ /* */ /* FT_ENCODING_BIG5 :: */ @@ -570,7 +665,7 @@ FT_BEGIN_HEADER /* FT_ENCODING_WANSUNG :: */ /* Corresponds to the Korean encoding system known as Wansung. */ /* For more information see */ - /* `http://www.microsoft.com/typography/unicode/949.txt'. */ + /* `https://msdn.microsoft.com/en-US/goglobal/cc305154'. */ /* */ /* FT_ENCODING_JOHAB :: */ /* The Korean standard character set (KS~C 5601-1992), which */ @@ -645,10 +740,10 @@ FT_BEGIN_HEADER /* FT_ENCODING_APPLE_ROMAN). */ /* */ /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ - /* @FT_Get_CMap_Language_ID to query the Mac language ID which may */ + /* @FT_Get_CMap_Language_ID to query the Mac language ID that may */ /* be needed to be able to distinguish Apple encoding variants. See */ /* */ - /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt */ /* */ /* to get an idea how to do that. Basically, if the language ID */ /* is~0, don't use it, otherwise subtract 1 from the language ID. */ @@ -690,15 +785,8 @@ FT_BEGIN_HEADER } FT_Encoding; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_encoding_xxx */ - /* */ - /* <Description> */ - /* These constants are deprecated; use the corresponding @FT_Encoding */ - /* values instead. */ - /* */ + /* these constants are deprecated; use the corresponding `FT_Encoding' */ + /* values instead */ #define ft_encoding_none FT_ENCODING_NONE #define ft_encoding_unicode FT_ENCODING_UNICODE #define ft_encoding_symbol FT_ENCODING_MS_SYMBOL @@ -787,17 +875,36 @@ FT_BEGIN_HEADER /* font formats can have multiple faces in */ /* a font file. */ /* */ - /* face_index :: The index of the face in the font file. It */ - /* is set to~0 if there is only one face in */ + /* face_index :: This field holds two different values. */ + /* Bits 0-15 are the index of the face in the */ + /* font file (starting with value~0). They */ + /* are set to~0 if there is only one face in */ /* the font file. */ /* */ + /* Bits 16-30 are relevant to GX variation */ + /* fonts only, holding the named instance */ + /* index for the current face index (starting */ + /* with value~1; value~0 indicates font access */ + /* without GX variation data). For non-GX */ + /* fonts, bits 16-30 are ignored. If we have */ + /* the third named instance of face~4, say, */ + /* `face_index' is set to 0x00030004. */ + /* */ + /* Bit 31 is always zero (this is, */ + /* `face_index' is always a positive value). */ + /* */ /* face_flags :: A set of bit flags that give important */ /* information about the face; see */ /* @FT_FACE_FLAG_XXX for the details. */ /* */ - /* style_flags :: A set of bit flags indicating the style of */ - /* the face; see @FT_STYLE_FLAG_XXX for the */ - /* details. */ + /* style_flags :: The lower 16~bits contain a set of bit */ + /* flags indicating the style of the face; see */ + /* @FT_STYLE_FLAG_XXX for the details. Bits */ + /* 16-30 hold the number of named instances */ + /* available for the current face if we have a */ + /* GX variation (sub)font. Bit 31 is always */ + /* zero (this is, `style_flags' is always a */ + /* positive value). */ /* */ /* num_glyphs :: The number of glyphs in the face. If the */ /* face is scalable and has sbits (see */ @@ -808,7 +915,7 @@ FT_BEGIN_HEADER /* highest CID used in the font. */ /* */ /* family_name :: The face's family name. This is an ASCII */ - /* string, usually in English, which describes */ + /* string, usually in English, that describes */ /* the typeface's family (like `Times New */ /* Roman', `Bodoni', `Garamond', etc). This */ /* is a least common denominator used to list */ @@ -819,8 +926,13 @@ FT_BEGIN_HEADER /* Can be NULL (e.g., in fonts embedded in a */ /* PDF file). */ /* */ + /* In case the font doesn't provide a specific */ + /* family name entry, FreeType tries to */ + /* synthesize one, deriving it from other name */ + /* entries. */ + /* */ /* style_name :: The face's style name. This is an ASCII */ - /* string, usually in English, which describes */ + /* string, usually in English, that describes */ /* the typeface's style (like `Italic', */ /* `Bold', `Condensed', etc). Not all font */ /* formats provide a style name, so this field */ @@ -991,7 +1103,7 @@ FT_BEGIN_HEADER /* FT_FACE_FLAG_SCALABLE :: */ /* Indicates that the face contains outline glyphs. This doesn't */ /* prevent bitmap strikes, i.e., a face can have both this and */ - /* and @FT_FACE_FLAG_FIXED_SIZES set. */ + /* @FT_FACE_FLAG_FIXED_SIZES set. */ /* */ /* FT_FACE_FLAG_FIXED_SIZES :: */ /* Indicates that the face contains bitmap strikes. See also the */ @@ -1054,7 +1166,7 @@ FT_BEGIN_HEADER /* exist make FT_Load_Glyph return successfully; in all other cases */ /* you get an `FT_Err_Invalid_Argument' error. */ /* */ - /* Note that CID-keyed fonts which are in an SFNT wrapper don't */ + /* Note that CID-keyed fonts that are in an SFNT wrapper don't */ /* have this flag set since the glyphs are accessed in the normal */ /* way (using contiguous indices); the `CID-ness' isn't visible to */ /* the application. */ @@ -1062,11 +1174,11 @@ FT_BEGIN_HEADER /* FT_FACE_FLAG_TRICKY :: */ /* Set if the font is `tricky', this is, it always needs the */ /* font format's native hinting engine to get a reasonable result. */ - /* A typical example is the Chinese font `mingli.ttf' which uses */ + /* A typical example is the Chinese font `mingli.ttf' that uses */ /* TrueType bytecode instructions to move and scale all of its */ /* subglyphs. */ /* */ - /* It is not possible to autohint such fonts using */ + /* It is not possible to auto-hint such fonts using */ /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ /* @FT_LOAD_NO_HINTING. You have to set both @FT_LOAD_NO_HINTING */ /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ @@ -1075,6 +1187,10 @@ FT_BEGIN_HEADER /* Currently, there are about a dozen TrueType fonts in the list of */ /* tricky fonts; they are hard-coded in file `ttobjs.c'. */ /* */ + /* FT_FACE_FLAG_COLOR :: */ + /* Set if the font has color glyph tables. To access color glyphs */ + /* use @FT_LOAD_COLOR. */ + /* */ #define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) #define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) @@ -1089,6 +1205,7 @@ FT_BEGIN_HEADER #define FT_FACE_FLAG_HINTER ( 1L << 11 ) #define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) #define FT_FACE_FLAG_TRICKY ( 1L << 13 ) +#define FT_FACE_FLAG_COLOR ( 1L << 14 ) /************************************************************************* @@ -1105,7 +1222,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_HORIZONTAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) + ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL ) /************************************************************************* @@ -1119,7 +1236,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_VERTICAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_VERTICAL ) + ( (face)->face_flags & FT_FACE_FLAG_VERTICAL ) /************************************************************************* @@ -1133,7 +1250,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_KERNING( face ) \ - ( face->face_flags & FT_FACE_FLAG_KERNING ) + ( (face)->face_flags & FT_FACE_FLAG_KERNING ) /************************************************************************* @@ -1148,7 +1265,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_SCALABLE( face ) \ - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + ( (face)->face_flags & FT_FACE_FLAG_SCALABLE ) /************************************************************************* @@ -1167,7 +1284,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_SFNT( face ) \ - ( face->face_flags & FT_FACE_FLAG_SFNT ) + ( (face)->face_flags & FT_FACE_FLAG_SFNT ) /************************************************************************* @@ -1182,7 +1299,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_FIXED_WIDTH( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) + ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) /************************************************************************* @@ -1197,7 +1314,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_FIXED_SIZES( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES ) /************************************************************************* @@ -1223,7 +1340,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_GLYPH_NAMES( face ) \ - ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) + ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) /************************************************************************* @@ -1238,7 +1355,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_MULTIPLE_MASTERS( face ) \ - ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) /************************************************************************* @@ -1256,7 +1373,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_CID_KEYED( face ) \ - ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED ) /************************************************************************* @@ -1270,7 +1387,21 @@ FT_BEGIN_HEADER * */ #define FT_IS_TRICKY( face ) \ - ( face->face_flags & FT_FACE_FLAG_TRICKY ) + ( (face)->face_flags & FT_FACE_FLAG_TRICKY ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_COLOR( face ) + * + * @description: + * A macro that returns true whenever a face object contains + * tables for color glyphs. + * + */ +#define FT_HAS_COLOR( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_COLOR ) /*************************************************************************/ @@ -1279,7 +1410,7 @@ FT_BEGIN_HEADER /* FT_STYLE_FLAG_XXX */ /* */ /* <Description> */ - /* A list of bit-flags used to indicate the style of a given face. */ + /* A list of bit flags used to indicate the style of a given face. */ /* These are used in the `style_flags' field of @FT_FaceRec. */ /* */ /* <Values> */ @@ -1394,9 +1525,9 @@ FT_BEGIN_HEADER /* <Fields> */ /* face :: Handle to the parent face object. */ /* */ - /* generic :: A typeless pointer, which is unused by the FreeType */ - /* library or any of its drivers. It can be used by */ - /* client applications to link their own data to each size */ + /* generic :: A typeless pointer, unused by the FreeType library or */ + /* any of its drivers. It can be used by client */ + /* applications to link their own data to each size */ /* object. */ /* */ /* metrics :: Metrics for this size object. This field is read-only. */ @@ -1464,10 +1595,10 @@ FT_BEGIN_HEADER /* listed through a direct, single-linked list */ /* using its `next' field. */ /* */ - /* generic :: A typeless pointer which is unused by the */ - /* FreeType library or any of its drivers. It */ - /* can be used by client applications to link */ - /* their own data to each glyph slot object. */ + /* generic :: A typeless pointer unused by the FreeType */ + /* library or any of its drivers. It can be */ + /* used by client applications to link their own */ + /* data to each glyph slot object. */ /* */ /* metrics :: The metrics of the last loaded glyph in the */ /* slot. The returned values depend on the last */ @@ -1494,8 +1625,8 @@ FT_BEGIN_HEADER /* */ /* advance :: This shorthand is, depending on */ /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ - /* advance width for the glyph (in 26.6 */ - /* fractional pixel format). As specified with */ + /* (hinted) advance width for the glyph, in 26.6 */ + /* fractional pixel format. As specified with */ /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ /* `horiAdvance' or the `vertAdvance' value of */ /* `metrics' field. */ @@ -1514,15 +1645,15 @@ FT_BEGIN_HEADER /* change between calls of @FT_Load_Glyph and a */ /* few other functions. */ /* */ - /* bitmap_left :: This is the bitmap's left bearing expressed */ - /* in integer pixels. Of course, this is only */ - /* valid if the format is */ - /* @FT_GLYPH_FORMAT_BITMAP. */ + /* bitmap_left :: The bitmap's left bearing expressed in */ + /* integer pixels. Only valid if the format is */ + /* @FT_GLYPH_FORMAT_BITMAP, this is, if the */ + /* glyph slot contains a bitmap. */ /* */ - /* bitmap_top :: This is the bitmap's top bearing expressed in */ - /* integer pixels. Remember that this is the */ - /* distance from the baseline to the top-most */ - /* glyph scanline, upwards y~coordinates being */ + /* bitmap_top :: The bitmap's top bearing expressed in integer */ + /* pixels. Remember that this is the distance */ + /* from the baseline to the top-most glyph */ + /* scanline, upwards y~coordinates being */ /* *positive*. */ /* */ /* outline :: The outline descriptor for the current glyph */ @@ -1536,7 +1667,6 @@ FT_BEGIN_HEADER /* This field is only valid for the composite */ /* glyph format that should normally only be */ /* loaded with the @FT_LOAD_NO_RECURSE flag. */ - /* For now this is internal to FreeType. */ /* */ /* subglyphs :: An array of subglyph descriptors for */ /* composite glyphs. There are `num_subglyphs' */ @@ -1557,11 +1687,11 @@ FT_BEGIN_HEADER /* needs to know about the image format. */ /* */ /* lsb_delta :: The difference between hinted and unhinted */ - /* left side bearing while autohinting is */ + /* left side bearing while auto-hinting is */ /* active. Zero otherwise. */ /* */ /* rsb_delta :: The difference between hinted and unhinted */ - /* right side bearing while autohinting is */ + /* right side bearing while auto-hinting is */ /* active. Zero otherwise. */ /* */ /* <Note> */ @@ -1584,7 +1714,7 @@ FT_BEGIN_HEADER /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ /* */ /* <Note> */ - /* Here a small pseudo code fragment which shows how to use */ + /* Here is a small pseudo code fragment that shows how to use */ /* `lsb_delta' and `rsb_delta': */ /* */ /* { */ @@ -1677,8 +1807,8 @@ FT_BEGIN_HEADER /* use @FT_New_Library instead, followed by a call to */ /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ /* */ - /* For multi-threading applications each thread should have its own */ - /* FT_Library object. */ + /* See the documentation of @FT_Library and @FT_Face for */ + /* multi-threading issues. */ /* */ /* If you need reference-counting (cf. @FT_Reference_Library), use */ /* @FT_New_Library and @FT_Done_Library. */ @@ -1712,7 +1842,7 @@ FT_BEGIN_HEADER /* FT_OPEN_XXX */ /* */ /* <Description> */ - /* A list of bit-field constants used within the `flags' field of the */ + /* A list of bit field constants used within the `flags' field of the */ /* @FT_Open_Args structure. */ /* */ /* <Values> */ @@ -1727,16 +1857,6 @@ FT_BEGIN_HEADER /* */ /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ /* */ - /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ - /* */ - /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ - /* */ - /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ - /* */ - /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ - /* */ - /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ - /* */ /* <Note> */ /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ /* flags are mutually exclusive. */ @@ -1747,11 +1867,14 @@ FT_BEGIN_HEADER #define FT_OPEN_DRIVER 0x8 #define FT_OPEN_PARAMS 0x10 -#define ft_open_memory FT_OPEN_MEMORY /* deprecated */ -#define ft_open_stream FT_OPEN_STREAM /* deprecated */ -#define ft_open_pathname FT_OPEN_PATHNAME /* deprecated */ -#define ft_open_driver FT_OPEN_DRIVER /* deprecated */ -#define ft_open_params FT_OPEN_PARAMS /* deprecated */ + + /* these constants are deprecated; use the corresponding `FT_OPEN_XXX' */ + /* values instead */ +#define ft_open_memory FT_OPEN_MEMORY +#define ft_open_stream FT_OPEN_STREAM +#define ft_open_pathname FT_OPEN_PATHNAME +#define ft_open_driver FT_OPEN_DRIVER +#define ft_open_params FT_OPEN_PARAMS /*************************************************************************/ @@ -1813,25 +1936,25 @@ FT_BEGIN_HEADER /* opening a new face. */ /* */ /* <Note> */ - /* The stream type is determined by the contents of `flags' which */ + /* The stream type is determined by the contents of `flags' that */ /* are tested in the following order by @FT_Open_Face: */ /* */ - /* If the `FT_OPEN_MEMORY' bit is set, assume that this is a */ + /* If the @FT_OPEN_MEMORY bit is set, assume that this is a */ /* memory file of `memory_size' bytes, located at `memory_address'. */ - /* The data are are not copied, and the client is responsible for */ + /* The data are not copied, and the client is responsible for */ /* releasing and destroying them _after_ the corresponding call to */ /* @FT_Done_Face. */ /* */ - /* Otherwise, if the `FT_OPEN_STREAM' bit is set, assume that a */ + /* Otherwise, if the @FT_OPEN_STREAM bit is set, assume that a */ /* custom input stream `stream' is used. */ /* */ - /* Otherwise, if the `FT_OPEN_PATHNAME' bit is set, assume that this */ + /* Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this */ /* is a normal file and use `pathname' to open it. */ /* */ - /* If the `FT_OPEN_DRIVER' bit is set, @FT_Open_Face only tries to */ + /* If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to */ /* open the file with the driver whose handler is in `driver'. */ /* */ - /* If the `FT_OPEN_PARAMS' bit is set, the parameters given by */ + /* If the @FT_OPEN_PARAMS bit is set, the parameters given by */ /* `num_params' and `params' is used. They are ignored otherwise. */ /* */ /* Ideally, both the `pathname' and `params' fields should be tagged */ @@ -1866,13 +1989,12 @@ FT_BEGIN_HEADER /* <Input> */ /* pathname :: A path to the font file. */ /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ + /* face_index :: See @FT_Open_Face for a detailed description of this */ + /* parameter. */ /* */ /* <Output> */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ - /* See @FT_Open_Face for more details. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -1894,7 +2016,7 @@ FT_BEGIN_HEADER /* FT_New_Memory_Face */ /* */ /* <Description> */ - /* This function calls @FT_Open_Face to open a font which has been */ + /* This function calls @FT_Open_Face to open a font that has been */ /* loaded into memory. */ /* */ /* <InOut> */ @@ -1905,13 +2027,12 @@ FT_BEGIN_HEADER /* */ /* file_size :: The size of the memory chunk used by the font data. */ /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ + /* face_index :: See @FT_Open_Face for a detailed description of this */ + /* parameter. */ /* */ /* <Output> */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ - /* See @FT_Open_Face for more details. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -1940,35 +2061,55 @@ FT_BEGIN_HEADER /* library :: A handle to the library resource. */ /* */ /* <Input> */ - /* args :: A pointer to an `FT_Open_Args' structure which must */ + /* args :: A pointer to an `FT_Open_Args' structure that must */ /* be filled by the caller. */ /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ + /* face_index :: This field holds two different values. Bits 0-15 */ + /* are the index of the face in the font file (starting */ + /* with value~0). Set it to~0 if there is only one */ + /* face in the font file. */ + /* */ + /* Bits 16-30 are relevant to GX variation fonts only, */ + /* specifying the named instance index for the current */ + /* face index (starting with value~1; value~0 makes */ + /* FreeType ignore named instances). For non-GX fonts, */ + /* bits 16-30 are ignored. Assuming that you want to */ + /* access the third named instance in face~4, */ + /* `face_index' should be set to 0x00030004. If you */ + /* want to access face~4 without GX variation handling, */ + /* simply set `face_index' to value~4. */ + /* */ + /* FT_Open_Face and its siblings can be used to quickly */ + /* check whether the font format of a given font */ + /* resource is supported by FreeType. In general, if */ + /* the `face_index' argument is negative, the */ + /* function's return value is~0 if the font format is */ + /* recognized, or non-zero otherwise. The function */ + /* allocates a more or less empty face handle in */ + /* `*aface' (if `aface' isn't NULL); the only two */ + /* useful fields in this special case are */ + /* `face->num_faces' and `face->style_flags'. For any */ + /* negative value of `face_index', `face->num_faces' */ + /* gives the number of faces within the font file. For */ + /* the negative value `-(N+1)' (with `N' a 16-bit */ + /* value), bits 16-30 in `face->style_flags' give the */ + /* number of named instances in face `N' if we have a */ + /* GX variation font (or zero otherwise). After */ + /* examination, the returned @FT_Face structure should */ + /* be deallocated with a call to @FT_Done_Face. */ /* */ /* <Output> */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ - /* See note below. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ + /* slot for the face object that can be accessed directly through */ /* `face->glyph'. */ /* */ - /* FT_Open_Face can be used to quickly check whether the font */ - /* format of a given font resource is supported by FreeType. If the */ - /* `face_index' field is negative, the function's return value is~0 */ - /* if the font format is recognized, or non-zero otherwise; */ - /* the function returns a more or less empty face handle in `*aface' */ - /* (if `aface' isn't NULL). The only useful field in this special */ - /* case is `face->num_faces' which gives the number of faces within */ - /* the font file. After examination, the returned @FT_Face structure */ - /* should be deallocated with a call to @FT_Done_Face. */ - /* */ /* Each new face object created with this function also owns a */ /* default @FT_Size object, accessible as `face->size'. */ /* */ @@ -1979,6 +2120,74 @@ FT_BEGIN_HEADER /* See the discussion of reference counters in the description of */ /* @FT_Reference_Face. */ /* */ + /* To loop over all faces, use code similar to the following snippet */ + /* (omitting the error handling). */ + /* */ + /* { */ + /* ... */ + /* FT_Face face; */ + /* FT_Long i, num_faces; */ + /* */ + /* */ + /* error = FT_Open_Face( library, args, -1, &face ); */ + /* if ( error ) { ... } */ + /* */ + /* num_faces = face->num_faces; */ + /* FT_Done_Face( face ); */ + /* */ + /* for ( i = 0; i < num_faces; i++ ) */ + /* { */ + /* ... */ + /* error = FT_Open_Face( library, args, i, &face ); */ + /* ... */ + /* FT_Done_Face( face ); */ + /* ... */ + /* } */ + /* } */ + /* */ + /* To loop over all valid values for `face_index', use something */ + /* similar to the following snippet, again without error handling. */ + /* The code accesses all faces immediately (thus only a single call */ + /* of `FT_Open_Face' within the do-loop), with and without named */ + /* instances. */ + /* */ + /* { */ + /* ... */ + /* FT_Face face; */ + /* */ + /* FT_Long num_faces = 0; */ + /* FT_Long num_instances = 0; */ + /* */ + /* FT_Long face_idx = 0; */ + /* FT_Long instance_idx = 0; */ + /* */ + /* */ + /* do */ + /* { */ + /* FT_Long id = ( instance_idx << 16 ) + face_idx; */ + /* */ + /* */ + /* error = FT_Open_Face( library, args, id, &face ); */ + /* if ( error ) { ... } */ + /* */ + /* num_faces = face->num_faces; */ + /* num_instances = face->style_flags >> 16; */ + /* */ + /* ... */ + /* */ + /* FT_Done_Face( face ); */ + /* */ + /* if ( instance_idx < num_instances ) */ + /* instance_idx++; */ + /* else */ + /* { */ + /* face_idx++; */ + /* instance_idx = 0; */ + /* } */ + /* */ + /* } while ( face_idx < num_faces ) */ + /* } */ + /* */ FT_EXPORT( FT_Error ) FT_Open_Face( FT_Library library, const FT_Open_Args* args, @@ -2023,7 +2232,7 @@ FT_BEGIN_HEADER /* face :: The target face object. */ /* */ /* <Input> */ - /* parameters :: A pointer to @FT_Open_Args which must be filled by */ + /* parameters :: A pointer to @FT_Open_Args that must be filled by */ /* the caller. */ /* */ /* <Return> */ @@ -2054,7 +2263,7 @@ FT_BEGIN_HEADER /* then only destroys a face if the counter is~1, otherwise it simply */ /* decrements the counter. */ /* */ - /* This function helps in managing life-cycles of structures which */ + /* This function helps in managing life-cycles of structures that */ /* reference @FT_Face objects. */ /* */ /* <Input> */ @@ -2130,9 +2339,9 @@ FT_BEGIN_HEADER /* used to determine both scaling values. */ /* */ /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ - /* The real dimension. The sum of the the `ascender' and (minus */ - /* of) the `descender' fields of @FT_FaceRec are used to determine */ - /* both scaling values. */ + /* The real dimension. The sum of the `ascender' and (minus of) */ + /* the `descender' fields of @FT_FaceRec are used to determine both */ + /* scaling values. */ /* */ /* FT_SIZE_REQUEST_TYPE_BBOX :: */ /* The font bounding box. The width and height of the `bbox' field */ @@ -2249,6 +2458,8 @@ FT_BEGIN_HEADER /* glyph relative to this size. For more information refer to */ /* `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html' */ /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ FT_EXPORT( FT_Error ) FT_Request_Size( FT_Face face, FT_Size_Request req ); @@ -2323,6 +2534,8 @@ FT_BEGIN_HEADER /* constrained, to this pixel size. Refer to @FT_Request_Size to */ /* understand how requested sizes relate to actual sizes. */ /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, FT_UInt pixel_width, @@ -2361,10 +2574,14 @@ FT_BEGIN_HEADER /* the details. */ /* */ /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ - /* returned for invalid CID values (this is, for CID values which */ + /* returned for invalid CID values (this is, for CID values that */ /* don't have a corresponding glyph in the font). See the discussion */ /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ /* */ + /* If you receive `FT_Err_Glyph_Too_Big', try getting the glyph */ + /* outline at EM size, then scale it manually and fill it as a */ + /* graphics operation. */ + /* */ FT_EXPORT( FT_Error ) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, @@ -2412,7 +2629,7 @@ FT_BEGIN_HEADER * FT_LOAD_XXX * * @description: - * A list of bit-field constants used with @FT_Load_Glyph to indicate + * A list of bit field constants used with @FT_Load_Glyph to indicate * what kind of operations to perform during glyph loading. * * @values: @@ -2481,11 +2698,6 @@ FT_BEGIN_HEADER * Indicates that the auto-hinter is preferred over the font's native * hinter. See also the note below. * - * FT_LOAD_CROP_BITMAP :: - * Indicates that the font driver should crop the loaded bitmap glyph - * (i.e., remove all space around its black bits). Not all drivers - * implement this. - * * FT_LOAD_PEDANTIC :: * Indicates that the font driver should perform pedantic verifications * during glyph loading. This is mostly used to detect broken glyphs @@ -2496,18 +2708,12 @@ FT_BEGIN_HEADER * result in partially hinted or distorted glyphs in case a glyph's * bytecode is buggy. * - * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: - * Ignored. Deprecated. - * * FT_LOAD_NO_RECURSE :: - * This flag is only used internally. It merely indicates that the - * font driver should not load composite glyphs recursively. Instead, - * it should set the `num_subglyph' and `subglyphs' values of the - * glyph slot accordingly, and set `glyph->format' to - * @FT_GLYPH_FORMAT_COMPOSITE. - * - * The description of sub-glyphs is not available to client - * applications for now. + * Indicate that the font driver should not load composite glyphs + * recursively. Instead, it should set the `num_subglyph' and + * `subglyphs' values of the glyph slot accordingly, and set + * `glyph->format' to @FT_GLYPH_FORMAT_COMPOSITE. The description of + * subglyphs can then be accessed with @FT_Get_SubGlyph_Info. * * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. * @@ -2540,6 +2746,22 @@ FT_BEGIN_HEADER * bitmaps transparently. Those bitmaps will be in the * @FT_PIXEL_MODE_GRAY format. * + * FT_LOAD_COMPUTE_METRICS :: + * This flag sets computing glyph metrics without the use of bundled + * metrics tables (for example, the `hdmx' table in TrueType fonts). + * Well-behaving fonts have optimized bundled metrics and these should + * be used. This flag is mainly used by font validating or font + * editing applications, which need to ignore, verify, or edit those + * tables. + * + * Currently, this flag is only implemented for TrueType fonts. + * + * FT_LOAD_CROP_BITMAP :: + * Ignored. Deprecated. + * + * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: + * Ignored. Deprecated. + * * @note: * By default, hinting is enabled and the font's native hinter (see * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can @@ -2579,6 +2801,7 @@ FT_BEGIN_HEADER #define FT_LOAD_NO_AUTOHINT ( 1L << 15 ) /* Bits 16..19 are used by `FT_LOAD_TARGET_' */ #define FT_LOAD_COLOR ( 1L << 20 ) +#define FT_LOAD_COMPUTE_METRICS ( 1L << 21 ) /* */ @@ -2601,9 +2824,6 @@ FT_BEGIN_HEADER * have specified (e.g., the TrueType bytecode interpreter). You can set * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. * - * Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it - * always implies @FT_LOAD_FORCE_AUTOHINT. - * * @values: * FT_LOAD_TARGET_NORMAL :: * This corresponds to the default hinting algorithm, optimized for @@ -2611,11 +2831,14 @@ FT_BEGIN_HEADER * @FT_LOAD_TARGET_MONO instead. * * FT_LOAD_TARGET_LIGHT :: - * A lighter hinting algorithm for non-monochrome modes. Many - * generated glyphs are more fuzzy but better resemble its original - * shape. A bit like rendering on Mac OS~X. - * - * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. + * A lighter hinting algorithm for gray-level modes. Many generated + * glyphs are fuzzier but better resemble their original shape. This + * is achieved by snapping glyphs to the pixel grid only vertically + * (Y-axis), as is done by Microsoft's ClearType and Adobe's + * proprietary font renderer. This preserves inter-glyph spacing in + * horizontal text. The snapping is done either by the native font + * driver if the driver itself and the font support it or by the + * auto-hinter. * * FT_LOAD_TARGET_MONO :: * Strong hinting algorithm that should only be used for monochrome @@ -2635,8 +2858,8 @@ FT_BEGIN_HEADER * `load_flags'. They can't be ORed. * * If @FT_LOAD_RENDER is also set, the glyph is rendered in the - * corresponding mode (i.e., the mode which matches the used algorithm - * best). An exeption is FT_LOAD_TARGET_MONO since it implies + * corresponding mode (i.e., the mode that matches the used algorithm + * best). An exception is FT_LOAD_TARGET_MONO since it implies * @FT_LOAD_MONOCHROME. * * You can use a hinting algorithm that doesn't correspond to the same @@ -2722,7 +2945,10 @@ FT_BEGIN_HEADER /* field in the @FT_GlyphSlotRec structure gives the format of the */ /* returned bitmap. */ /* */ - /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity, */ + /* indicating pixel coverage. Use linear alpha blending and gamma */ + /* correction to correctly render non-monochrome glyph bitmaps onto a */ + /* surface; see @FT_Render_Glyph. */ /* */ /* <Values> */ /* FT_RENDER_MODE_NORMAL :: */ @@ -2776,19 +3002,8 @@ FT_BEGIN_HEADER } FT_Render_Mode; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_render_mode_xxx */ - /* */ - /* <Description> */ - /* These constants are deprecated. Use the corresponding */ - /* @FT_Render_Mode values instead. */ - /* */ - /* <Values> */ - /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ - /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ - /* */ + /* these constants are deprecated; use the corresponding */ + /* `FT_Render_Mode' values instead */ #define ft_render_mode_normal FT_RENDER_MODE_NORMAL #define ft_render_mode_mono FT_RENDER_MODE_MONO @@ -2815,6 +3030,87 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* To get meaningful results, font scaling values must be set with */ + /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ + /* */ + /* When FreeType outputs a bitmap of a glyph, it really outputs an */ + /* alpha coverage map. If a pixel is completely covered by a */ + /* filled-in outline, the bitmap contains 0xFF at that pixel, meaning */ + /* that 0xFF/0xFF fraction of that pixel is covered, meaning the */ + /* pixel is 100% black (or 0% bright). If a pixel is only 50% */ + /* covered (value 0x80), the pixel is made 50% black (50% bright or a */ + /* middle shade of grey). 0% covered means 0% black (100% bright or */ + /* white). */ + /* */ + /* On high-DPI screens like on smartphones and tablets, the pixels */ + /* are so small that their chance of being completely covered and */ + /* therefore completely black are fairly good. On the low-DPI */ + /* screens, however, the situation is different. The pixels are too */ + /* large for most of the details of a glyph and shades of gray are */ + /* the norm rather than the exception. */ + /* */ + /* This is relevant because all our screens have a second problem: */ + /* they are not linear. 1~+~1 is not~2. Twice the value does not */ + /* result in twice the brightness. When a pixel is only 50% covered, */ + /* the coverage map says 50% black, and this translates to a pixel */ + /* value of 128 when you use 8~bits per channel (0-255). However, */ + /* this does not translate to 50% brightness for that pixel on our */ + /* sRGB and gamma~2.2 screens. Due to their non-linearity, they */ + /* dwell longer in the darks and only a pixel value of about 186 */ + /* results in 50% brightness – 128 ends up too dark on both bright */ + /* and dark backgrounds. The net result is that dark text looks */ + /* burnt-out, pixely and blotchy on bright background, bright text */ + /* too frail on dark backgrounds, and colored text on colored */ + /* background (for example, red on green) seems to have dark halos or */ + /* `dirt' around it. The situation is especially ugly for diagonal */ + /* stems like in `w' glyph shapes where the quality of FreeType's */ + /* anti-aliasing depends on the correct display of grays. On */ + /* high-DPI screens where smaller, fully black pixels reign supreme, */ + /* this doesn't matter, but on our low-DPI screens with all the gray */ + /* shades, it does. 0% and 100% brightness are the same things in */ + /* linear and non-linear space, just all the shades in-between */ + /* aren't. */ + /* */ + /* The blending function for placing text over a background is */ + /* */ + /* { */ + /* dst = alpha * src + (1 - alpha) * dst , */ + /* } */ + /* */ + /* which is known as the OVER operator. */ + /* */ + /* To correctly composite an antialiased pixel of a glyph onto a */ + /* surface, */ + /* */ + /* 1. take the foreground and background colors (e.g., in sRGB space) */ + /* and apply gamma to get them in a linear space, */ + /* */ + /* 2. use OVER to blend the two linear colors using the glyph pixel */ + /* as the alpha value (remember, the glyph bitmap is an alpha */ + /* coverage bitmap), and */ + /* */ + /* 3. apply inverse gamma to the blended pixel and write it back to */ + /* the image. */ + /* */ + /* Internal testing at Adobe found that a target inverse gamma of~1.8 */ + /* for step~3 gives good results across a wide range of displays with */ + /* an sRGB gamma curve or a similar one. */ + /* */ + /* This process can cost performance. There is an approximation that */ + /* does not need to know about the background color; see */ + /* https://bel.fi/alankila/lcd/ and */ + /* https://bel.fi/alankila/lcd/alpcor.html for details. */ + /* */ + /* *ATTENTION*: Linear blending is even more important when dealing */ + /* with subpixel-rendered glyphs to prevent color-fringing! A */ + /* subpixel-rendered glyph must first be filtered with a filter that */ + /* gives equal weight to the three color primaries and does not */ + /* exceed a sum of 0x100, see section @lcd_filtering. Then the */ + /* only difference to gray linear blending is that subpixel-rendered */ + /* linear blending is done 3~times per pixel: red foreground subpixel */ + /* to red background subpixel and so on for green and blue. */ + /* */ FT_EXPORT( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, FT_Render_Mode render_mode ); @@ -2830,15 +3126,22 @@ FT_BEGIN_HEADER /* @FT_Get_Kerning. */ /* */ /* <Values> */ - /* FT_KERNING_DEFAULT :: Return scaled and grid-fitted kerning */ - /* distances (value is~0). */ + /* FT_KERNING_DEFAULT :: Return grid-fitted kerning distances in */ + /* pixels (value is~0). Whether they are */ + /* scaled depends on @FT_LOAD_NO_SCALE. */ /* */ - /* FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning */ - /* distances. */ + /* FT_KERNING_UNFITTED :: Return un-grid-fitted kerning distances in */ + /* 26.6 fractional pixels. Whether they are */ + /* scaled depends on @FT_LOAD_NO_SCALE. */ /* */ /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ /* units. */ /* */ + /* <Note> */ + /* FT_KERNING_DEFAULT returns full pixel values; it also makes */ + /* FreeType heuristically scale down kerning distances at small ppem */ + /* values so that they don't become too big. */ + /* */ typedef enum FT_Kerning_Mode_ { FT_KERNING_DEFAULT = 0, @@ -2848,39 +3151,10 @@ FT_BEGIN_HEADER } FT_Kerning_Mode; - /*************************************************************************/ - /* */ - /* <Const> */ - /* ft_kerning_default */ - /* */ - /* <Description> */ - /* This constant is deprecated. Please use @FT_KERNING_DEFAULT */ - /* instead. */ - /* */ + /* these constants are deprecated; use the corresponding */ + /* `FT_Kerning_Mode' values instead */ #define ft_kerning_default FT_KERNING_DEFAULT - - - /*************************************************************************/ - /* */ - /* <Const> */ - /* ft_kerning_unfitted */ - /* */ - /* <Description> */ - /* This constant is deprecated. Please use @FT_KERNING_UNFITTED */ - /* instead. */ - /* */ #define ft_kerning_unfitted FT_KERNING_UNFITTED - - - /*************************************************************************/ - /* */ - /* <Const> */ - /* ft_kerning_unscaled */ - /* */ - /* <Description> */ - /* This constant is deprecated. Please use @FT_KERNING_UNSCALED */ - /* instead. */ - /* */ #define ft_kerning_unscaled FT_KERNING_UNSCALED @@ -2904,9 +3178,10 @@ FT_BEGIN_HEADER /* kerning vector. */ /* */ /* <Output> */ - /* akerning :: The kerning vector. This is either in font units */ - /* or in pixels (26.6 format) for scalable formats, */ - /* and in pixels for fixed-sizes formats. */ + /* akerning :: The kerning vector. This is either in font units, */ + /* fractional pixels (26.6 format), or pixels for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -3001,9 +3276,8 @@ FT_BEGIN_HEADER /* glyph index~0 always corresponds to the `missing glyph' (called */ /* `.notdef'). */ /* */ - /* This function is not compiled within the library if the config */ - /* macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in */ - /* `include/freetype/config/ftoptions.h'. */ + /* This function always returns an error if the config macro */ + /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoption.h'. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph_Name( FT_Face face, @@ -3059,8 +3333,8 @@ FT_BEGIN_HEADER /* */ /* Because many fonts contain more than a single cmap for Unicode */ /* encoding, this function has some special code to select the one */ - /* which covers Unicode best (`best' in the sense that a UCS-4 cmap */ - /* is preferred to a UCS-2 cmap). It is thus preferable to */ + /* that covers Unicode best (`best' in the sense that a UCS-4 cmap is */ + /* preferred to a UCS-2 cmap). It is thus preferable to */ /* @FT_Set_Charmap in this case. */ /* */ FT_EXPORT( FT_Error ) @@ -3192,6 +3466,13 @@ FT_BEGIN_HEADER /* } */ /* } */ /* */ + /* Be aware that character codes can have values up to 0xFFFFFFFF; */ + /* this might happen for non-Unicode or malformed cmaps. However, */ + /* even with regular Unicode encoding, so-called `last resort fonts' */ + /* (using SFNT cmap format 13, see function @FT_Get_CMap_Format) */ + /* normally have entries for all Unicode characters up to 0x1FFFFF, */ + /* which can cause *a lot* of iterations. */ + /* */ /* Note that `*agindex' is set to~0 if the charmap is empty. The */ /* result itself can be~0 in two cases: if the charmap is empty or */ /* if the value~0 is the first valid character code. */ @@ -3351,8 +3632,9 @@ FT_BEGIN_HEADER /* @FT_Get_FSType_Flags; they inform client applications of embedding */ /* and subsetting restrictions associated with a font. */ /* */ - /* See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for */ - /* more details. */ + /* See */ + /* http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/FontPolicies.pdf */ + /* for more details. */ /* */ /* <Values> */ /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ @@ -3386,6 +3668,9 @@ FT_BEGIN_HEADER /* bitmaps available in the font, then the font is unembeddable. */ /* */ /* <Note> */ + /* The flags are ORed together, thus more than a single value can be */ + /* returned. */ + /* */ /* While the fsType flags can indicate that a font may be embedded, a */ /* license with the font vendor may be separately required to use the */ /* font in this way. */ @@ -3414,7 +3699,7 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* Use this function rather than directly reading the `fs_type' field */ - /* in the @PS_FontInfoRec structure which is only guaranteed to */ + /* in the @PS_FontInfoRec structure, which is only guaranteed to */ /* return the correct results for Type~1 fonts. */ /* */ /* <Since> */ @@ -3451,8 +3736,8 @@ FT_BEGIN_HEADER /* */ /* http://www.unicode.org/reports/tr37/ */ /* */ - /* To date (November 2012), the character with the most variants is */ - /* U+9089, having 31 such IVS. */ + /* To date (November 2014), the character with the most variants is */ + /* U+9089, having 32 such IVS. */ /* */ /* Adobe and MS decided to support IVS with a new cmap subtable */ /* (format~14). It is an odd subtable because it is not a mapping of */ @@ -3594,7 +3879,7 @@ FT_BEGIN_HEADER /* The character codepoint in Unicode. */ /* */ /* <Return> */ - /* A pointer to an array of variant selector code points which are */ + /* A pointer to an array of variant selector code points that are */ /* active for the given character, or NULL if the corresponding list */ /* is empty. */ /* */ @@ -3628,7 +3913,7 @@ FT_BEGIN_HEADER /* The variant selector code point in Unicode. */ /* */ /* <Return> */ - /* A list of all the code points which are specified by this selector */ + /* A list of all the code points that are specified by this selector */ /* (both default and non-default codes are returned) or NULL if there */ /* is no valid cmap or the variant selector is invalid. */ /* */ @@ -3703,12 +3988,6 @@ FT_BEGIN_HEADER FT_Long c ); - /* */ - - /* The following #if 0 ... #endif is for the documentation formatter, */ - /* hiding the internal `FT_MULFIX_INLINED' macro. */ - -#if 0 /*************************************************************************/ /* */ /* <Function> */ @@ -3742,17 +4021,6 @@ FT_BEGIN_HEADER FT_MulFix( FT_Long a, FT_Long b ); - /* */ -#endif - -#ifdef FT_MULFIX_INLINED -#define FT_MulFix( a, b ) FT_MULFIX_INLINED( a, b ) -#else - FT_EXPORT( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ); -#endif - /*************************************************************************/ /* */ @@ -3765,18 +4033,12 @@ FT_BEGIN_HEADER /* used to divide a given value by a 16.16 fixed-point factor. */ /* */ /* <Input> */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ + /* a :: The numerator. */ + /* b :: The denominator. Use a 16.16 factor here. */ /* */ /* <Return> */ /* The result of `(a*0x10000)/b'. */ /* */ - /* <Note> */ - /* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */ - /* 32~bits, then the division is computed directly. Otherwise, we */ - /* use a specialized version of @FT_MulDiv. */ - /* */ FT_EXPORT( FT_Long ) FT_DivFix( FT_Long a, FT_Long b ); @@ -3794,7 +4056,8 @@ FT_BEGIN_HEADER /* a :: The number to be rounded. */ /* */ /* <Return> */ - /* The result of `(a + 0x8000) & -0x10000'. */ + /* `a' rounded to nearest 16.16 fixed integer, halfway cases away */ + /* from zero. */ /* */ FT_EXPORT( FT_Fixed ) FT_RoundFix( FT_Fixed a ); @@ -3813,7 +4076,7 @@ FT_BEGIN_HEADER /* a :: The number for which the ceiling function is to be computed. */ /* */ /* <Return> */ - /* The result of `(a + 0x10000 - 1) & -0x10000'. */ + /* `a' rounded towards plus infinity. */ /* */ FT_EXPORT( FT_Fixed ) FT_CeilFix( FT_Fixed a ); @@ -3832,7 +4095,7 @@ FT_BEGIN_HEADER /* a :: The number for which the floor function is to be computed. */ /* */ /* <Return> */ - /* The result of `a & -0x10000'. */ + /* `a' rounded towards minus infinity. */ /* */ FT_EXPORT( FT_Fixed ) FT_FloorFix( FT_Fixed a ); @@ -3876,6 +4139,18 @@ FT_BEGIN_HEADER /* even a new release of FreeType with only documentation changes */ /* increases the version number. */ /* */ + /* <Order> */ + /* FT_Library_Version */ + /* */ + /* FREETYPE_MAJOR */ + /* FREETYPE_MINOR */ + /* FREETYPE_PATCH */ + /* */ + /* FT_Face_CheckTrueTypePatents */ + /* FT_Face_SetUnpatentedHinting */ + /* */ + /* FREETYPE_XXX */ + /* */ /*************************************************************************/ @@ -3900,8 +4175,8 @@ FT_BEGIN_HEADER * */ #define FREETYPE_MAJOR 2 -#define FREETYPE_MINOR 5 -#define FREETYPE_PATCH 0 +#define FREETYPE_MINOR 6 +#define FREETYPE_PATCH 5 /*************************************************************************/ @@ -3946,20 +4221,13 @@ FT_BEGIN_HEADER /* FT_Face_CheckTrueTypePatents */ /* */ /* <Description> */ - /* Parse all bytecode instructions of a TrueType font file to check */ - /* whether any of the patented opcodes are used. This is only useful */ - /* if you want to be able to use the unpatented hinter with */ - /* fonts that do *not* use these opcodes. */ - /* */ - /* Note that this function parses *all* glyph instructions in the */ - /* font file, which may be slow. */ + /* Deprecated, does nothing. */ /* */ /* <Input> */ /* face :: A face handle. */ /* */ /* <Return> */ - /* 1~if this is a TrueType font that uses one of the patented */ - /* opcodes, 0~otherwise. */ + /* Always returns false. */ /* */ /* <Note> */ /* Since May 2010, TrueType hinting is no longer patented. */ @@ -3977,9 +4245,7 @@ FT_BEGIN_HEADER /* FT_Face_SetUnpatentedHinting */ /* */ /* <Description> */ - /* Enable or disable the unpatented hinter for a given face. */ - /* Only enable it if you have determined that the face doesn't */ - /* use any patented opcodes (see @FT_Face_CheckTrueTypePatents). */ + /* Deprecated, does nothing. */ /* */ /* <Input> */ /* face :: A face handle. */ @@ -3987,9 +4253,7 @@ FT_BEGIN_HEADER /* value :: New boolean setting. */ /* */ /* <Return> */ - /* The old setting value. This will always be false if this is not */ - /* an SFNT font, or if the unpatented hinter is not compiled in this */ - /* instance of the library. */ + /* Always returns false. */ /* */ /* <Note> */ /* Since May 2010, TrueType hinting is no longer patented. */ @@ -4006,7 +4270,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FREETYPE_H__ */ +#endif /* FREETYPE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftadvanc.h b/drivers/freetype/include/freetype/ftadvanc.h index 012b74b812..023dd84b7a 100644 --- a/drivers/freetype/freetype/include/freetype/ftadvanc.h +++ b/drivers/freetype/include/freetype/ftadvanc.h @@ -4,7 +4,7 @@ /* */ /* Quick computation of advance widths (specification only). */ /* */ -/* Copyright 2008, 2013 by */ +/* Copyright 2008-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTADVANC_H__ -#define __FTADVANC_H__ +#ifndef FTADVANC_H_ +#define FTADVANC_H_ #include <ft2build.h> @@ -48,6 +48,11 @@ FT_BEGIN_HEADER * @description: * This section contains functions to quickly extract advance values * without handling glyph outlines, if possible. + * + * @order: + * FT_Get_Advance + * FT_Get_Advances + * */ @@ -64,15 +69,15 @@ FT_BEGIN_HEADER /* corresponding hinting mode or font driver doesn't allow for very */ /* quick advance computation. */ /* */ - /* Typically, glyphs which are either unscaled, unhinted, bitmapped, */ + /* Typically, glyphs that are either unscaled, unhinted, bitmapped, */ /* or light-hinted can have their advance width computed very */ /* quickly. */ /* */ - /* Normal and bytecode hinted modes, which require loading, scaling, */ + /* Normal and bytecode hinted modes that require loading, scaling, */ /* and hinting of the glyph outline, are extremely slow by */ /* comparison. */ /* */ -#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000UL +#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000L /*************************************************************************/ @@ -171,12 +176,12 @@ FT_BEGIN_HEADER FT_Int32 load_flags, FT_Fixed *padvances ); -/* */ + /* */ FT_END_HEADER -#endif /* __FTADVANC_H__ */ +#endif /* FTADVANC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftautoh.h b/drivers/freetype/include/freetype/ftautoh.h index 5e1153a1c1..40c8003c4a 100644 --- a/drivers/freetype/freetype/include/freetype/ftautoh.h +++ b/drivers/freetype/include/freetype/ftautoh.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for controlling the auto-hinter (specification only). */ /* */ -/* Copyright 2012, 2013 by */ +/* Copyright 2012-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTAUTOH_H__ -#define __FTAUTOH_H__ +#ifndef FTAUTOH_H_ +#define FTAUTOH_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -79,7 +79,7 @@ FT_BEGIN_HEADER * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an * array with `num_glyphs' elements, as found in the font's @FT_Face * structure. The `glyph-to-script-map' property returns a pointer to - * this array which can be modified as needed. Note that the + * this array, which can be modified as needed. Note that the * modification should happen before the first glyph gets processed by * the auto-hinter so that the global analysis of the font shapes * actually uses the modified mapping. @@ -219,8 +219,8 @@ FT_BEGIN_HEADER * U+0F00 - U+0FFF // Tibetan * U+1900 - U+194F // Limbu * U+1B80 - U+1BBF // Sundanese - * U+1C80 - U+1CDF // Meetei Mayak * U+A800 - U+A82F // Syloti Nagri + * U+ABC0 - U+ABFF // Meetei Mayek * U+11800 - U+118DF // Sharada * } * @@ -245,12 +245,12 @@ FT_BEGIN_HEADER * The data exchange structure for the @glyph-to-script-map property. * */ - typedef struct FT_Prop_GlyphToScriptMap_ - { - FT_Face face; - FT_Byte* map; + typedef struct FT_Prop_GlyphToScriptMap_ + { + FT_Face face; + FT_UShort* map; - } FT_Prop_GlyphToScriptMap; + } FT_Prop_GlyphToScriptMap; /************************************************************************** @@ -282,12 +282,57 @@ FT_BEGIN_HEADER * This property can be used with @FT_Property_Get also. * * It's important to use the right timing for changing this value: The - * creation of the glyph-to-script map which eventually uses the + * creation of the glyph-to-script map that eventually uses the * fallback script value gets triggered either by setting or reading a * face-specific property like @glyph-to-script-map, or by auto-hinting * any glyph from that face. In particular, if you have already created * an @FT_Face structure but not loaded any glyph (using the - * auto-hinter), a change of the fallback glyph will affect this face. + * auto-hinter), a change of the fallback script will affect this face. + * + */ + + + /************************************************************************** + * + * @property: + * default-script + * + * @description: + * *Experimental* *only* + * + * If FreeType gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make + * the HarfBuzz library access OpenType features for getting better + * glyph coverages, this property sets the (auto-fitter) script to be + * used for the default (OpenType) script data of a font's GSUB table. + * Features for the default script are intended for all scripts not + * explicitly handled in GSUB; an example is a `dlig' feature, + * containing the combination of the characters `T', `E', and `L' to + * form a `TEL' ligature. + * + * By default, this is @FT_AUTOHINTER_SCRIPT_LATIN. Using the + * `default-script' property, this default value can be changed. + * + * { + * FT_Library library; + * FT_UInt default_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "default-script", &default_script ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * It's important to use the right timing for changing this value: The + * creation of the glyph-to-script map that eventually uses the + * default script value gets triggered either by setting or reading a + * face-specific property like @glyph-to-script-map, or by auto-hinting + * any glyph from that face. In particular, if you have already created + * an @FT_Face structure but not loaded any glyph (using the + * auto-hinter), a change of the default script will affect this face. * */ @@ -339,19 +384,120 @@ FT_BEGIN_HEADER * The data exchange structure for the @increase-x-height property. * */ - typedef struct FT_Prop_IncreaseXHeight_ - { - FT_Face face; - FT_UInt limit; + typedef struct FT_Prop_IncreaseXHeight_ + { + FT_Face face; + FT_UInt limit; + + } FT_Prop_IncreaseXHeight; + + + /************************************************************************** + * + * @property: + * warping + * + * @description: + * *Experimental* *only* + * + * If FreeType gets compiled with option AF_CONFIG_OPTION_USE_WARPER to + * activate the warp hinting code in the auto-hinter, this property + * switches warping on and off. + * + * Warping only works in `light' auto-hinting mode. The idea of the + * code is to slightly scale and shift a glyph along the non-hinted + * dimension (which is usually the horizontal axis) so that as much of + * its segments are aligned (more or less) to the grid. To find out a + * glyph's optimal scaling and shifting value, various parameter + * combinations are tried and scored. + * + * By default, warping is off. The example below shows how to switch on + * warping (omitting the error handling). + * + * { + * FT_Library library; + * FT_Bool warping = 1; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "warping", &warping ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * The warping code can also change advance widths. Have a look at the + * `lsb_delta' and `rsb_delta' fields in the @FT_GlyphSlotRec structure + * for details on improving inter-glyph distances while rendering. + * + * Since warping is a global property of the auto-hinter it is best to + * change its value before rendering any face. Otherwise, you should + * reload all faces that get auto-hinted in `light' hinting mode. + * + */ + + + /************************************************************************** + * + * @property: + * no-stem-darkening[autofit] + * + * @description: + * *Experimental* *only,* *requires* *linear* *alpha* *blending* *and* + * *gamma* *correction* + * + * Stem darkening emboldens glyphs at smaller sizes to make them more + * readable on common low-DPI screens when using linear alpha blending + * and gamma correction, see @FT_Render_Glyph. When not using linear + * alpha blending and gamma correction, glyphs will appear heavy and + * fuzzy! + * + * Gamma correction essentially lightens fonts since shades of grey are + * shifted to higher pixel values (=~higher brightness) to match the + * original intention to the reality of our screens. The side-effect is + * that glyphs `thin out'. Mac OS~X and Adobe's proprietary font + * rendering library implement a counter-measure: stem darkening at + * smaller sizes where shades of gray dominate. By emboldening a glyph + * slightly in relation to its pixel size, individual pixels get higher + * coverage of filled-in outlines and are therefore `blacker'. This + * counteracts the `thinning out' of glyphs, making text remain readable + * at smaller sizes. All glyphs that pass through the auto-hinter will + * be emboldened unless this property is set to TRUE. + * + * See the description of the CFF driver for algorithmic details. Total + * consistency with the CFF driver is currently not achieved because the + * emboldening method differs and glyphs must be scaled down on the + * Y-axis to keep outline points inside their precomputed blue zones. + * The smaller the size (especially 9ppem and down), the higher the loss + * of emboldening versus the CFF driver. + * + */ + + + /************************************************************************** + * + * @property: + * darkening-parameters[autofit] + * + * @description: + * *Experimental* *only* + * + * See the description of the CFF driver for details. This + * implementation appropriates the + * CFF_CONFIG_OPTION_DARKENING_PARAMETER_* #defines for consistency. + * Note the differences described in @no-stem-darkening[autofit]. + * + */ - } FT_Prop_IncreaseXHeight; + /* */ - /* */ FT_END_HEADER -#endif /* __FTAUTOH_H__ */ +#endif /* FTAUTOH_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftbbox.h b/drivers/freetype/include/freetype/ftbbox.h index 976691956f..2a4d214416 100644 --- a/drivers/freetype/freetype/include/freetype/ftbbox.h +++ b/drivers/freetype/include/freetype/ftbbox.h @@ -4,7 +4,7 @@ /* */ /* FreeType exact bbox computation (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2007, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,8 +27,8 @@ /*************************************************************************/ -#ifndef __FTBBOX_H__ -#define __FTBBOX_H__ +#ifndef FTBBOX_H_ +#define FTBBOX_H_ #include <ft2build.h> @@ -60,7 +60,7 @@ FT_BEGIN_HEADER /* <Description> */ /* Compute the exact bounding box of an outline. This is slower */ /* than computing the control box. However, it uses an advanced */ - /* algorithm which returns _very_ quickly when the two boxes */ + /* algorithm that returns _very_ quickly when the two boxes */ /* coincide. Otherwise, the outline Bézier arcs are traversed to */ /* extract their extrema. */ /* */ @@ -78,20 +78,19 @@ FT_BEGIN_HEADER /* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get */ /* reasonable values for the BBox it is necessary to load the glyph */ /* at a large ppem value (so that the hinting instructions can */ - /* properly shift and scale the subglyphs), then extracting the BBox */ + /* properly shift and scale the subglyphs), then extracting the BBox, */ /* which can be eventually converted back to font units. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Get_BBox( FT_Outline* outline, FT_BBox *abbox ); - /* */ FT_END_HEADER -#endif /* __FTBBOX_H__ */ +#endif /* FTBBOX_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftbdf.h b/drivers/freetype/include/freetype/ftbdf.h index 4f8baf8401..016dba086d 100644 --- a/drivers/freetype/freetype/include/freetype/ftbdf.h +++ b/drivers/freetype/include/freetype/ftbdf.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (specification). */ /* */ -/* Copyright 2002, 2003, 2004, 2006, 2009 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBDF_H__ -#define __FTBDF_H__ +#ifndef FTBDF_H_ +#define FTBDF_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -53,7 +53,7 @@ FT_BEGIN_HEADER /********************************************************************** * * @enum: - * FT_PropertyType + * BDF_PropertyType * * @description: * A list of BDF property types. @@ -106,7 +106,8 @@ FT_BEGIN_HEADER * The property type. * * u.atom :: - * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. + * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. May be + * NULL, indicating an empty string. * * u.integer :: * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. @@ -199,11 +200,11 @@ FT_BEGIN_HEADER const char* prop_name, BDF_PropertyRec *aproperty ); - /* */ + /* */ FT_END_HEADER -#endif /* __FTBDF_H__ */ +#endif /* FTBDF_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftbitmap.h b/drivers/freetype/include/freetype/ftbitmap.h index 7dbf5ba3fe..0eac7b9d7d 100644 --- a/drivers/freetype/freetype/include/freetype/ftbitmap.h +++ b/drivers/freetype/include/freetype/ftbitmap.h @@ -4,7 +4,7 @@ /* */ /* FreeType utility functions for bitmaps (specification). */ /* */ -/* Copyright 2004-2006, 2008, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBITMAP_H__ -#define __FTBITMAP_H__ +#ifndef FTBITMAP_H_ +#define FTBITMAP_H_ #include <ft2build.h> @@ -45,7 +45,9 @@ FT_BEGIN_HEADER /* Handling FT_Bitmap objects. */ /* */ /* <Description> */ - /* This section contains functions for converting FT_Bitmap objects. */ + /* This section contains functions for handling @FT_Bitmap objects. */ + /* Note that none of the functions changes the bitmap's `flow' (as */ + /* indicated by the sign of the `pitch' field in `FT_Bitmap'). */ /* */ /*************************************************************************/ @@ -53,7 +55,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Function> */ - /* FT_Bitmap_New */ + /* FT_Bitmap_Init */ /* */ /* <Description> */ /* Initialize a pointer to an @FT_Bitmap structure. */ @@ -61,6 +63,14 @@ FT_BEGIN_HEADER /* <InOut> */ /* abitmap :: A pointer to the bitmap structure. */ /* */ + /* <Note> */ + /* A deprecated name for the same function is `FT_Bitmap_New'. */ + /* */ + FT_EXPORT( void ) + FT_Bitmap_Init( FT_Bitmap *abitmap ); + + + /* deprecated */ FT_EXPORT( void ) FT_Bitmap_New( FT_Bitmap *abitmap ); @@ -122,6 +132,9 @@ FT_BEGIN_HEADER /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ /* */ + /* Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format */ + /* are converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp). */ + /* */ FT_EXPORT( FT_Error ) FT_Bitmap_Embolden( FT_Library library, FT_Bitmap* bitmap, @@ -197,7 +210,7 @@ FT_BEGIN_HEADER /* FT_Bitmap_Done */ /* */ /* <Description> */ - /* Destroy a bitmap object created with @FT_Bitmap_New. */ + /* Destroy a bitmap object initialized with @FT_Bitmap_Init. */ /* */ /* <Input> */ /* library :: A handle to a library object. */ @@ -221,7 +234,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBITMAP_H__ */ +#endif /* FTBITMAP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftbzip2.h b/drivers/freetype/include/freetype/ftbzip2.h index 1bf81b15e8..b7f2eee87d 100644 --- a/drivers/freetype/freetype/include/freetype/ftbzip2.h +++ b/drivers/freetype/include/freetype/ftbzip2.h @@ -4,7 +4,7 @@ /* */ /* Bzip2-compressed stream support. */ /* */ -/* Copyright 2010 by */ +/* Copyright 2010-2016 by */ /* Joel Klinghed. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBZIP2_H__ -#define __FTBZIP2_H__ +#ifndef FTBZIP2_H_ +#define FTBZIP2_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -91,12 +91,12 @@ FT_BEGIN_HEADER FT_Stream_OpenBzip2( FT_Stream stream, FT_Stream source ); - /* */ + /* */ FT_END_HEADER -#endif /* __FTBZIP2_H__ */ +#endif /* FTBZIP2_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftcache.h b/drivers/freetype/include/freetype/ftcache.h index 4ec9587cf6..883c88d5d2 100644 --- a/drivers/freetype/freetype/include/freetype/ftcache.h +++ b/drivers/freetype/include/freetype/ftcache.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache subsystem (specification). */ /* */ -/* Copyright 1996-2008, 2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCACHE_H__ -#define __FTCACHE_H__ +#ifndef FTCACHE_H_ +#define FTCACHE_H_ #include <ft2build.h> @@ -156,7 +156,7 @@ FT_BEGIN_HEADER * @note: * Never use NULL as a valid @FTC_FaceID. * - * Face IDs are passed by the client to the cache manager, which calls, + * Face IDs are passed by the client to the cache manager that calls, * when needed, the @FTC_Face_Requester to translate them into new * @FT_Face objects. * @@ -209,10 +209,10 @@ FT_BEGIN_HEADER typedef FT_Error (*FTC_Face_Requester)( FTC_FaceID face_id, FT_Library library, - FT_Pointer request_data, + FT_Pointer req_data, FT_Face* aface ); - /* */ + /* */ /*************************************************************************/ @@ -667,8 +667,8 @@ FT_BEGIN_HEADER typedef struct FTC_ImageTypeRec_ { FTC_FaceID face_id; - FT_Int width; - FT_Int height; + FT_UInt width; + FT_UInt height; FT_Int32 flags; } FTC_ImageTypeRec; @@ -749,7 +749,7 @@ FT_BEGIN_HEADER /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ - /* anode :: Used to return the address of of the corresponding cache */ + /* anode :: Used to return the address of the corresponding cache */ /* node after incrementing its reference count (see note */ /* below). */ /* */ @@ -802,7 +802,7 @@ FT_BEGIN_HEADER /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ - /* anode :: Used to return the address of of the corresponding */ + /* anode :: Used to return the address of the corresponding */ /* cache node after incrementing its reference count */ /* (see note below). */ /* */ @@ -957,7 +957,7 @@ FT_BEGIN_HEADER /* <Output> */ /* sbit :: A handle to a small bitmap descriptor. */ /* */ - /* anode :: Used to return the address of of the corresponding cache */ + /* anode :: Used to return the address of the corresponding cache */ /* node after incrementing its reference count (see note */ /* below). */ /* */ @@ -1012,7 +1012,7 @@ FT_BEGIN_HEADER /* <Output> */ /* sbit :: A handle to a small bitmap descriptor. */ /* */ - /* anode :: Used to return the address of of the corresponding */ + /* anode :: Used to return the address of the corresponding */ /* cache node after incrementing its reference count */ /* (see note below). */ /* */ @@ -1046,12 +1046,12 @@ FT_BEGIN_HEADER FTC_SBit *sbit, FTC_Node *anode ); + /* */ - /* */ FT_END_HEADER -#endif /* __FTCACHE_H__ */ +#endif /* FTCACHE_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftcffdrv.h b/drivers/freetype/include/freetype/ftcffdrv.h new file mode 100644 index 0000000000..ad34541fdb --- /dev/null +++ b/drivers/freetype/include/freetype/ftcffdrv.h @@ -0,0 +1,262 @@ +/***************************************************************************/ +/* */ +/* ftcffdrv.h */ +/* */ +/* FreeType API for controlling the CFF driver (specification only). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef FTCFFDRV_H_ +#define FTCFFDRV_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * cff_driver + * + * @title: + * The CFF driver + * + * @abstract: + * Controlling the CFF driver module. + * + * @description: + * While FreeType's CFF driver doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. The list below gives the available properties + * together with the necessary macros and structures. + * + * The CFF driver's module name is `cff'. + * + * *Hinting* *and* *antialiasing* *principles* *of* *the* *new* *engine* + * + * The rasterizer is positioning horizontal features (e.g., ascender + * height & x-height, or crossbars) on the pixel grid and minimizing the + * amount of antialiasing applied to them, while placing vertical + * features (vertical stems) on the pixel grid without hinting, thus + * representing the stem position and weight accurately. Sometimes the + * vertical stems may be only partially black. In this context, + * `antialiasing' means that stems are not positioned exactly on pixel + * borders, causing a fuzzy appearance. + * + * There are two principles behind this approach. + * + * 1) No hinting in the horizontal direction: Unlike `superhinted' + * TrueType, which changes glyph widths to accommodate regular + * inter-glyph spacing, Adobe's approach is `faithful to the design' in + * representing both the glyph width and the inter-glyph spacing + * designed for the font. This makes the screen display as close as it + * can be to the result one would get with infinite resolution, while + * preserving what is considered the key characteristics of each glyph. + * Note that the distances between unhinted and grid-fitted positions at + * small sizes are comparable to kerning values and thus would be + * noticeable (and distracting) while reading if hinting were applied. + * + * One of the reasons to not hint horizontally is antialiasing for LCD + * screens: The pixel geometry of modern displays supplies three + * vertical sub-pixels as the eye moves horizontally across each visible + * pixel. On devices where we can be certain this characteristic is + * present a rasterizer can take advantage of the sub-pixels to add + * increments of weight. In Western writing systems this turns out to + * be the more critical direction anyway; the weights and spacing of + * vertical stems (see above) are central to Armenian, Cyrillic, Greek, + * and Latin type designs. Even when the rasterizer uses greyscale + * antialiasing instead of color (a necessary compromise when one + * doesn't know the screen characteristics), the unhinted vertical + * features preserve the design's weight and spacing much better than + * aliased type would. + * + * 2) Alignment in the vertical direction: Weights and spacing along the + * y~axis are less critical; what is much more important is the visual + * alignment of related features (like cap-height and x-height). The + * sense of alignment for these is enhanced by the sharpness of grid-fit + * edges, while the cruder vertical resolution (full pixels instead of + * 1/3 pixels) is less of a problem. + * + * On the technical side, horizontal alignment zones for ascender, + * x-height, and other important height values (traditionally called + * `blue zones') as defined in the font are positioned independently, + * each being rounded to the nearest pixel edge, taking care of + * overshoot suppression at small sizes, stem darkening, and scaling. + * + * Hstems (this is, hint values defined in the font to help align + * horizontal features) that fall within a blue zone are said to be + * `captured' and are aligned to that zone. Uncaptured stems are moved + * in one of four ways, top edge up or down, bottom edge up or down. + * Unless there are conflicting hstems, the smallest movement is taken + * to minimize distortion. + * + * @order: + * hinting-engine[cff] + * no-stem-darkening[cff] + * darkening-parameters[cff] + * + */ + + + /************************************************************************** + * + * @property: + * hinting-engine[cff] + * + * @description: + * Thanks to Adobe, which contributed a new hinting (and parsing) + * engine, an application can select between `freetype' and `adobe' if + * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration + * macro isn't defined, `hinting-engine' does nothing. + * + * The default engine is `freetype' if CFF_CONFIG_OPTION_OLD_ENGINE is + * defined, and `adobe' otherwise. + * + * The following example code demonstrates how to select Adobe's hinting + * engine (omitting the error handling). + * + * { + * FT_Library library; + * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "hinting-engine", &hinting_engine ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + + /************************************************************************** + * + * @enum: + * FT_CFF_HINTING_XXX + * + * @description: + * A list of constants used for the @hinting-engine[cff] property to + * select the hinting engine for CFF fonts. + * + * @values: + * FT_CFF_HINTING_FREETYPE :: + * Use the old FreeType hinting engine. + * + * FT_CFF_HINTING_ADOBE :: + * Use the hinting engine contributed by Adobe. + * + */ +#define FT_CFF_HINTING_FREETYPE 0 +#define FT_CFF_HINTING_ADOBE 1 + + + /************************************************************************** + * + * @property: + * no-stem-darkening[cff] + * + * @description: + * By default, the Adobe CFF engine darkens stems at smaller sizes, + * regardless of hinting, to enhance contrast. This feature requires + * a rendering system with proper gamma correction. Setting this + * property, stem darkening gets switched off. + * + * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set. + * + * { + * FT_Library library; + * FT_Bool no_stem_darkening = TRUE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "no-stem-darkening", &no_stem_darkening ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + + /************************************************************************** + * + * @property: + * darkening-parameters[cff] + * + * @description: + * By default, the Adobe CFF engine darkens stems as follows (if the + * `no-stem-darkening' property isn't set): + * + * { + * stem width <= 0.5px: darkening amount = 0.4px + * stem width = 1px: darkening amount = 0.275px + * stem width = 1.667px: darkening amount = 0.275px + * stem width >= 2.333px: darkening amount = 0px + * } + * + * and piecewise linear in-between. At configuration time, these four + * control points can be set with the macro + * `CFF_CONFIG_OPTION_DARKENING_PARAMETERS'. At runtime, the control + * points can be changed using the `darkening-parameters' property, as + * the following example demonstrates. + * + * { + * FT_Library library; + * FT_Int darken_params[8] = { 500, 300, // x1, y1 + * 1000, 200, // x2, y2 + * 1500, 100, // x3, y3 + * 2000, 0 }; // x4, y4 + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "darkening-parameters", darken_params ); + * } + * + * The x~values give the stem width, and the y~values the darkening + * amount. The unit is 1000th of pixels. All coordinate values must be + * positive; the x~values must be monotonically increasing; the + * y~values must be monotonically decreasing and smaller than or + * equal to 500 (corresponding to half a pixel); the slope of each + * linear piece must be shallower than -1 (e.g., -.4). + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + /* */ + + +FT_END_HEADER + + +#endif /* FTCFFDRV_H_ */ + + +/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftchapters.h b/drivers/freetype/include/freetype/ftchapters.h index c55670d1d2..ab4389530e 100644 --- a/drivers/freetype/freetype/include/freetype/ftchapters.h +++ b/drivers/freetype/include/freetype/ftchapters.h @@ -1,7 +1,7 @@ /***************************************************************************/ /* */ /* This file defines the structure of the FreeType reference. */ -/* It is used by the python script which generates the HTML files. */ +/* It is used by the python script that generates the HTML files. */ /* */ /***************************************************************************/ @@ -15,6 +15,7 @@ /* General Remarks */ /* */ /* <Sections> */ +/* header_inclusion */ /* user_allocation */ /* */ /***************************************************************************/ @@ -118,3 +119,17 @@ /* lcd_filtering */ /* */ /***************************************************************************/ + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* error_codes */ +/* */ +/* <Title> */ +/* Error Codes */ +/* */ +/* <Sections> */ +/* error_enumerations */ +/* error_code_values */ +/* */ +/***************************************************************************/ diff --git a/drivers/freetype/freetype/include/freetype/ftcid.h b/drivers/freetype/include/freetype/ftcid.h index 203a30caf8..e1bc9fe015 100644 --- a/drivers/freetype/freetype/include/freetype/ftcid.h +++ b/drivers/freetype/include/freetype/ftcid.h @@ -4,7 +4,8 @@ /* */ /* FreeType API for accessing CID font information (specification). */ /* */ -/* Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal. */ +/* Copyright 2007-2016 by */ +/* Dereg Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCID_H__ -#define __FTCID_H__ +#ifndef FTCID_H_ +#define FTCID_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -96,8 +97,8 @@ FT_BEGIN_HEADER * * @description: * Retrieve the type of the input face, CID keyed or not. In - * constrast to the @FT_IS_CID_KEYED macro this function returns - * successfully also for CID-keyed fonts in an SNFT wrapper. + * contrast to the @FT_IS_CID_KEYED macro this function returns + * successfully also for CID-keyed fonts in an SFNT wrapper. * * @input: * face :: @@ -156,11 +157,12 @@ FT_BEGIN_HEADER FT_UInt glyph_index, FT_UInt *cid ); - /* */ + /* */ + FT_END_HEADER -#endif /* __FTCID_H__ */ +#endif /* FTCID_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/fterrdef.h b/drivers/freetype/include/freetype/fterrdef.h index 76c7b9e36f..3f53dd5820 100644 --- a/drivers/freetype/freetype/include/freetype/fterrdef.h +++ b/drivers/freetype/include/freetype/fterrdef.h @@ -4,7 +4,7 @@ /* */ /* FreeType error codes (specification). */ /* */ -/* Copyright 2002, 2004, 2006, 2007, 2010-2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,234 +16,261 @@ /***************************************************************************/ - /*******************************************************************/ - /*******************************************************************/ - /***** *****/ - /***** LIST OF ERROR CODES/MESSAGES *****/ - /***** *****/ - /*******************************************************************/ - /*******************************************************************/ + /*************************************************************************/ + /* */ + /* <Section> */ + /* error_code_values */ + /* */ + /* <Title> */ + /* Error Code Values */ + /* */ + /* <Abstract> */ + /* All possible error codes returned by FreeType functions. */ + /* */ + /* <Description> */ + /* The list below is taken verbatim from the file `fterrdef.h' */ + /* (loaded automatically by including `FT_FREETYPE_H'). The first */ + /* argument of the `FT_ERROR_DEF_' macro is the error label; by */ + /* default, the prefix `FT_Err_' gets added so that you get error */ + /* names like `FT_Err_Cannot_Open_Resource'. The second argument is */ + /* the error code, and the last argument an error string, which is not */ + /* used by FreeType. */ + /* */ + /* Within your application you should *only* use error names and */ + /* *never* its numeric values! The latter might (and actually do) */ + /* change in forthcoming FreeType versions. */ + /* */ + /* Macro `FT_NOERRORDEF_' defines `FT_Err_Ok', which is always zero. */ + /* See the `Error Enumerations' subsection how to automatically */ + /* generate a list of error strings. */ + /* */ + /*************************************************************************/ - /* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */ - /* including this file. */ - + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Err_XXX */ + /* */ + /*************************************************************************/ /* generic errors */ - FT_NOERRORDEF_( Ok, 0x00, \ + FT_NOERRORDEF_( Ok, 0x00, "no error" ) - FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \ + FT_ERRORDEF_( Cannot_Open_Resource, 0x01, "cannot open resource" ) - FT_ERRORDEF_( Unknown_File_Format, 0x02, \ + FT_ERRORDEF_( Unknown_File_Format, 0x02, "unknown file format" ) - FT_ERRORDEF_( Invalid_File_Format, 0x03, \ + FT_ERRORDEF_( Invalid_File_Format, 0x03, "broken file" ) - FT_ERRORDEF_( Invalid_Version, 0x04, \ + FT_ERRORDEF_( Invalid_Version, 0x04, "invalid FreeType version" ) - FT_ERRORDEF_( Lower_Module_Version, 0x05, \ + FT_ERRORDEF_( Lower_Module_Version, 0x05, "module version is too low" ) - FT_ERRORDEF_( Invalid_Argument, 0x06, \ + FT_ERRORDEF_( Invalid_Argument, 0x06, "invalid argument" ) - FT_ERRORDEF_( Unimplemented_Feature, 0x07, \ + FT_ERRORDEF_( Unimplemented_Feature, 0x07, "unimplemented feature" ) - FT_ERRORDEF_( Invalid_Table, 0x08, \ + FT_ERRORDEF_( Invalid_Table, 0x08, "broken table" ) - FT_ERRORDEF_( Invalid_Offset, 0x09, \ + FT_ERRORDEF_( Invalid_Offset, 0x09, "broken offset within table" ) - FT_ERRORDEF_( Array_Too_Large, 0x0A, \ + FT_ERRORDEF_( Array_Too_Large, 0x0A, "array allocation size too large" ) - FT_ERRORDEF_( Missing_Module, 0x0B, \ + FT_ERRORDEF_( Missing_Module, 0x0B, "missing module" ) - FT_ERRORDEF_( Missing_Property, 0x0C, \ + FT_ERRORDEF_( Missing_Property, 0x0C, "missing property" ) /* glyph/character errors */ - FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \ + FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, "invalid glyph index" ) - FT_ERRORDEF_( Invalid_Character_Code, 0x11, \ + FT_ERRORDEF_( Invalid_Character_Code, 0x11, "invalid character code" ) - FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \ + FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, "unsupported glyph image format" ) - FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \ + FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, "cannot render this glyph format" ) - FT_ERRORDEF_( Invalid_Outline, 0x14, \ + FT_ERRORDEF_( Invalid_Outline, 0x14, "invalid outline" ) - FT_ERRORDEF_( Invalid_Composite, 0x15, \ + FT_ERRORDEF_( Invalid_Composite, 0x15, "invalid composite glyph" ) - FT_ERRORDEF_( Too_Many_Hints, 0x16, \ + FT_ERRORDEF_( Too_Many_Hints, 0x16, "too many hints" ) - FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \ + FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, "invalid pixel size" ) /* handle errors */ - FT_ERRORDEF_( Invalid_Handle, 0x20, \ + FT_ERRORDEF_( Invalid_Handle, 0x20, "invalid object handle" ) - FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \ + FT_ERRORDEF_( Invalid_Library_Handle, 0x21, "invalid library handle" ) - FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \ + FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, "invalid module handle" ) - FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \ + FT_ERRORDEF_( Invalid_Face_Handle, 0x23, "invalid face handle" ) - FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \ + FT_ERRORDEF_( Invalid_Size_Handle, 0x24, "invalid size handle" ) - FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \ + FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, "invalid glyph slot handle" ) - FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \ + FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, "invalid charmap handle" ) - FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \ + FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, "invalid cache manager handle" ) - FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \ + FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, "invalid stream handle" ) /* driver errors */ - FT_ERRORDEF_( Too_Many_Drivers, 0x30, \ + FT_ERRORDEF_( Too_Many_Drivers, 0x30, "too many modules" ) - FT_ERRORDEF_( Too_Many_Extensions, 0x31, \ + FT_ERRORDEF_( Too_Many_Extensions, 0x31, "too many extensions" ) /* memory errors */ - FT_ERRORDEF_( Out_Of_Memory, 0x40, \ + FT_ERRORDEF_( Out_Of_Memory, 0x40, "out of memory" ) - FT_ERRORDEF_( Unlisted_Object, 0x41, \ + FT_ERRORDEF_( Unlisted_Object, 0x41, "unlisted object" ) /* stream errors */ - FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \ + FT_ERRORDEF_( Cannot_Open_Stream, 0x51, "cannot open stream" ) - FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \ + FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, "invalid stream seek" ) - FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \ + FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, "invalid stream skip" ) - FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \ + FT_ERRORDEF_( Invalid_Stream_Read, 0x54, "invalid stream read" ) - FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \ + FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, "invalid stream operation" ) - FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \ + FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, "invalid frame operation" ) - FT_ERRORDEF_( Nested_Frame_Access, 0x57, \ + FT_ERRORDEF_( Nested_Frame_Access, 0x57, "nested frame access" ) - FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \ + FT_ERRORDEF_( Invalid_Frame_Read, 0x58, "invalid frame read" ) /* raster errors */ - FT_ERRORDEF_( Raster_Uninitialized, 0x60, \ + FT_ERRORDEF_( Raster_Uninitialized, 0x60, "raster uninitialized" ) - FT_ERRORDEF_( Raster_Corrupted, 0x61, \ + FT_ERRORDEF_( Raster_Corrupted, 0x61, "raster corrupted" ) - FT_ERRORDEF_( Raster_Overflow, 0x62, \ + FT_ERRORDEF_( Raster_Overflow, 0x62, "raster overflow" ) - FT_ERRORDEF_( Raster_Negative_Height, 0x63, \ + FT_ERRORDEF_( Raster_Negative_Height, 0x63, "negative height while rastering" ) /* cache errors */ - FT_ERRORDEF_( Too_Many_Caches, 0x70, \ + FT_ERRORDEF_( Too_Many_Caches, 0x70, "too many registered caches" ) /* TrueType and SFNT errors */ - FT_ERRORDEF_( Invalid_Opcode, 0x80, \ + FT_ERRORDEF_( Invalid_Opcode, 0x80, "invalid opcode" ) - FT_ERRORDEF_( Too_Few_Arguments, 0x81, \ + FT_ERRORDEF_( Too_Few_Arguments, 0x81, "too few arguments" ) - FT_ERRORDEF_( Stack_Overflow, 0x82, \ + FT_ERRORDEF_( Stack_Overflow, 0x82, "stack overflow" ) - FT_ERRORDEF_( Code_Overflow, 0x83, \ + FT_ERRORDEF_( Code_Overflow, 0x83, "code overflow" ) - FT_ERRORDEF_( Bad_Argument, 0x84, \ + FT_ERRORDEF_( Bad_Argument, 0x84, "bad argument" ) - FT_ERRORDEF_( Divide_By_Zero, 0x85, \ + FT_ERRORDEF_( Divide_By_Zero, 0x85, "division by zero" ) - FT_ERRORDEF_( Invalid_Reference, 0x86, \ + FT_ERRORDEF_( Invalid_Reference, 0x86, "invalid reference" ) - FT_ERRORDEF_( Debug_OpCode, 0x87, \ + FT_ERRORDEF_( Debug_OpCode, 0x87, "found debug opcode" ) - FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \ + FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, "found ENDF opcode in execution stream" ) - FT_ERRORDEF_( Nested_DEFS, 0x89, \ + FT_ERRORDEF_( Nested_DEFS, 0x89, "nested DEFS" ) - FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \ + FT_ERRORDEF_( Invalid_CodeRange, 0x8A, "invalid code range" ) - FT_ERRORDEF_( Execution_Too_Long, 0x8B, \ + FT_ERRORDEF_( Execution_Too_Long, 0x8B, "execution context too long" ) - FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \ + FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, "too many function definitions" ) - FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \ + FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, "too many instruction definitions" ) - FT_ERRORDEF_( Table_Missing, 0x8E, \ + FT_ERRORDEF_( Table_Missing, 0x8E, "SFNT font table missing" ) - FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \ + FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, "horizontal header (hhea) table missing" ) - FT_ERRORDEF_( Locations_Missing, 0x90, \ + FT_ERRORDEF_( Locations_Missing, 0x90, "locations (loca) table missing" ) - FT_ERRORDEF_( Name_Table_Missing, 0x91, \ + FT_ERRORDEF_( Name_Table_Missing, 0x91, "name table missing" ) - FT_ERRORDEF_( CMap_Table_Missing, 0x92, \ + FT_ERRORDEF_( CMap_Table_Missing, 0x92, "character map (cmap) table missing" ) - FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \ + FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, "horizontal metrics (hmtx) table missing" ) - FT_ERRORDEF_( Post_Table_Missing, 0x94, \ + FT_ERRORDEF_( Post_Table_Missing, 0x94, "PostScript (post) table missing" ) - FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \ + FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, "invalid horizontal metrics" ) - FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \ + FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, "invalid character map (cmap) format" ) - FT_ERRORDEF_( Invalid_PPem, 0x97, \ + FT_ERRORDEF_( Invalid_PPem, 0x97, "invalid ppem value" ) - FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \ + FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, "invalid vertical metrics" ) - FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \ + FT_ERRORDEF_( Could_Not_Find_Context, 0x99, "could not find context" ) - FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \ + FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, "invalid PostScript (post) table format" ) - FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \ + FT_ERRORDEF_( Invalid_Post_Table, 0x9B, "invalid PostScript (post) table" ) /* CFF, CID, and Type 1 errors */ - FT_ERRORDEF_( Syntax_Error, 0xA0, \ + FT_ERRORDEF_( Syntax_Error, 0xA0, "opcode syntax error" ) - FT_ERRORDEF_( Stack_Underflow, 0xA1, \ + FT_ERRORDEF_( Stack_Underflow, 0xA1, "argument stack underflow" ) - FT_ERRORDEF_( Ignore, 0xA2, \ + FT_ERRORDEF_( Ignore, 0xA2, "ignore" ) - FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, \ + FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, "no Unicode glyph name found" ) - FT_ERRORDEF_( Glyph_Too_Big, 0xA4, \ - "glyph to big for hinting" ) + FT_ERRORDEF_( Glyph_Too_Big, 0xA4, + "glyph too big for hinting" ) /* BDF errors */ - FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \ + FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, "`STARTFONT' field missing" ) - FT_ERRORDEF_( Missing_Font_Field, 0xB1, \ + FT_ERRORDEF_( Missing_Font_Field, 0xB1, "`FONT' field missing" ) - FT_ERRORDEF_( Missing_Size_Field, 0xB2, \ + FT_ERRORDEF_( Missing_Size_Field, 0xB2, "`SIZE' field missing" ) - FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, \ + FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, "`FONTBOUNDINGBOX' field missing" ) - FT_ERRORDEF_( Missing_Chars_Field, 0xB4, \ + FT_ERRORDEF_( Missing_Chars_Field, 0xB4, "`CHARS' field missing" ) - FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, \ + FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, "`STARTCHAR' field missing" ) - FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, \ + FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, "`ENCODING' field missing" ) - FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, \ + FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, "`BBX' field missing" ) - FT_ERRORDEF_( Bbx_Too_Big, 0xB8, \ + FT_ERRORDEF_( Bbx_Too_Big, 0xB8, "`BBX' too big" ) - FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, \ + FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, "Font header corrupted or missing fields" ) - FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, \ + FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, "Font glyphs corrupted or missing fields" ) + /* */ + /* END */ diff --git a/drivers/freetype/freetype/include/freetype/fterrors.h b/drivers/freetype/include/freetype/fterrors.h index 0fa3e4dce1..e15bfb001e 100644 --- a/drivers/freetype/freetype/include/freetype/fterrors.h +++ b/drivers/freetype/include/freetype/fterrors.h @@ -4,7 +4,7 @@ /* */ /* FreeType error code handling (specification). */ /* */ -/* Copyright 1996-2002, 2004, 2007, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,70 +18,98 @@ /*************************************************************************/ /* */ - /* This special header file is used to define the handling of FT2 */ - /* enumeration constants. It can also be used to generate error message */ - /* strings with a small macro trick explained below. */ + /* <Section> */ + /* error_enumerations */ /* */ - /* I - Error Formats */ - /* ----------------- */ + /* <Title> */ + /* Error Enumerations */ + /* */ + /* <Abstract> */ + /* How to handle errors and error strings. */ + /* */ + /* <Description> */ + /* The header file `fterrors.h' (which is automatically included by */ + /* `freetype.h' defines the handling of FreeType's enumeration */ + /* constants. It can also be used to generate error message strings */ + /* with a small macro trick explained below. */ + /* */ + /* *Error* *Formats* */ /* */ /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ - /* defined in ftoption.h in order to make the higher byte indicate */ + /* defined in `ftoption.h' in order to make the higher byte indicate */ /* the module where the error has happened (this is not compatible */ - /* with standard builds of FreeType 2). See the file `ftmoderr.h' for */ - /* more details. */ + /* with standard builds of FreeType 2, however). See the file */ + /* `ftmoderr.h' for more details. */ /* */ + /* *Error* *Message* *Strings* */ /* */ - /* II - Error Message strings */ - /* -------------------------- */ - /* */ - /* The error definitions below are made through special macros that */ - /* allow client applications to build a table of error message strings */ - /* if they need it. The strings are not included in a normal build of */ - /* FreeType 2 to save space (most client applications do not use */ - /* them). */ + /* Error definitions are set up with special macros that allow client */ + /* applications to build a table of error message strings. The */ + /* strings are not included in a normal build of FreeType 2 to */ + /* save space (most client applications do not use them). */ /* */ /* To do so, you have to define the following macros before including */ - /* this file: */ + /* this file. */ /* */ - /* FT_ERROR_START_LIST :: */ - /* This macro is called before anything else to define the start of */ - /* the error list. It is followed by several FT_ERROR_DEF calls */ - /* (see below). */ + /* { */ + /* FT_ERROR_START_LIST */ + /* } */ /* */ - /* FT_ERROR_DEF( e, v, s ) :: */ - /* This macro is called to define one single error. */ - /* `e' is the error code identifier (e.g. FT_Err_Invalid_Argument). */ - /* `v' is the error numerical value. */ - /* `s' is the corresponding error string. */ + /* This macro is called before anything else to define the start of */ + /* the error list. It is followed by several FT_ERROR_DEF calls. */ /* */ - /* FT_ERROR_END_LIST :: */ - /* This macro ends the list. */ + /* { */ + /* FT_ERROR_DEF( e, v, s ) */ + /* } */ /* */ - /* Additionally, you have to undefine __FTERRORS_H__ before #including */ + /* This macro is called to define one single error. `e' is the error */ + /* code identifier (e.g., `Invalid_Argument'), `v' is the error's */ + /* numerical value, and `s' is the corresponding error string. */ + /* */ + /* { */ + /* FT_ERROR_END_LIST */ + /* } */ + /* */ + /* This macro ends the list. */ + /* */ + /* Additionally, you have to undefine `FTERRORS_H_' before #including */ /* this file. */ /* */ - /* Here is a simple example: */ + /* Here is a simple example. */ /* */ + /* { */ + /* #undef FTERRORS_H_ */ + /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ + /* #define FT_ERROR_START_LIST { */ + /* #define FT_ERROR_END_LIST { 0, NULL } }; */ + /* */ + /* const struct */ /* { */ - /* #undef __FTERRORS_H__ */ - /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ - /* #define FT_ERROR_START_LIST { */ - /* #define FT_ERROR_END_LIST { 0, 0 } }; */ + /* int err_code; */ + /* const char* err_msg; */ + /* } ft_errors[] = */ /* */ - /* const struct */ - /* { */ - /* int err_code; */ - /* const char* err_msg; */ - /* } ft_errors[] = */ + /* #include FT_ERRORS_H */ + /* } */ /* */ - /* #include FT_ERRORS_H */ - /* } */ + /* Note that `FT_Err_Ok' is _not_ defined with `FT_ERRORDEF' but with */ + /* `FT_NOERRORDEF'; it is always zero. */ /* */ /*************************************************************************/ - -#ifndef __FTERRORS_H__ + /* */ + + /* In previous FreeType versions we used `__FTERRORS_H__'. However, */ + /* using two successive underscores in a non-system symbol name */ + /* violates the C (and C++) standard, so it was changed to the */ + /* current form. In spite of this, we have to make */ + /* */ + /* #undefine __FTERRORS_H__ */ + /* */ + /* work for backwards compatibility. */ + /* */ +#if !( defined( FTERRORS_H_ ) && defined ( __FTERRORS_H__ ) ) +#define FTERRORS_H_ #define __FTERRORS_H__ @@ -192,7 +220,7 @@ #undef FT_ERR_PREFIX #endif -#endif /* __FTERRORS_H__ */ +#endif /* !(FTERRORS_H_ && __FTERRORS_H__) */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftxf86.h b/drivers/freetype/include/freetype/ftfntfmt.h index 8c68afdcc5..bd423247bb 100644 --- a/drivers/freetype/freetype/include/freetype/ftxf86.h +++ b/drivers/freetype/include/freetype/ftfntfmt.h @@ -1,10 +1,10 @@ /***************************************************************************/ /* */ -/* ftxf86.h */ +/* ftfntfmt.h */ /* */ -/* Support functions for X11. */ +/* Support functions for font formats. */ /* */ -/* Copyright 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTXF86_H__ -#define __FTXF86_H__ +#ifndef FTFNTFMT_H_ +#define FTFNTFMT_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -49,22 +49,20 @@ FT_BEGIN_HEADER /* however, there are special cases (like in PDF devices) where it is */ /* important to differentiate, in spite of FreeType's uniform API. */ /* */ - /* This function is in the X11/xf86 namespace for historical reasons */ - /* and in no way depends on that windowing system. */ - /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ - /* FT_Get_X11_Font_Format */ + /* FT_Get_Font_Format */ /* */ /* <Description> */ - /* Return a string describing the format of a given face, using values */ - /* which can be used as an X11 FONT_PROPERTY. Possible values are */ - /* `TrueType', `Type~1', `BDF', `PCF', `Type~42', `CID~Type~1', `CFF', */ - /* `PFR', and `Windows~FNT'. */ + /* Return a string describing the format of a given face. Possible */ + /* values are `TrueType', `Type~1', `BDF', `PCF', `Type~42', */ + /* `CID~Type~1', `CFF', `PFR', and `Windows~FNT'. */ + /* */ + /* The return value is suitable to be used as an X11 FONT_PROPERTY. */ /* */ /* <Input> */ /* face :: */ @@ -73,11 +71,25 @@ FT_BEGIN_HEADER /* <Return> */ /* Font format string. NULL in case of error. */ /* */ + /* <Note> */ + /* A deprecated name for the same function is */ + /* `FT_Get_X11_Font_Format'. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_Font_Format( FT_Face face ); + + + /* deprecated */ FT_EXPORT( const char* ) FT_Get_X11_Font_Format( FT_Face face ); - /* */ + + /* */ + FT_END_HEADER -#endif /* __FTXF86_H__ */ +#endif /* FTFNTFMT_H_ */ + + +/* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftgasp.h b/drivers/freetype/include/freetype/ftgasp.h index 453d4fa42c..3f5b3bc695 100644 --- a/drivers/freetype/freetype/include/freetype/ftgasp.h +++ b/drivers/freetype/include/freetype/ftgasp.h @@ -4,7 +4,7 @@ /* */ /* Access of TrueType's `gasp' table (specification). */ /* */ -/* Copyright 2007, 2008, 2011 by */ +/* Copyright 2007-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef _FT_GASP_H_ -#define _FT_GASP_H_ +#ifndef FTGASP_H_ +#define FTGASP_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -120,9 +120,10 @@ FT_Get_Gasp( FT_Face face, FT_UInt ppem ); -/* */ + /* */ -#endif /* _FT_GASP_H_ */ + +#endif /* FTGASP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftglyph.h b/drivers/freetype/include/freetype/ftglyph.h index 31dc33187d..d9840a81fc 100644 --- a/drivers/freetype/freetype/include/freetype/ftglyph.h +++ b/drivers/freetype/include/freetype/ftglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (specification). */ /* */ -/* Copyright 1996-2003, 2006, 2008, 2009, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,8 +29,8 @@ /*************************************************************************/ -#ifndef __FTGLYPH_H__ -#define __FTGLYPH_H__ +#ifndef FTGLYPH_H_ +#define FTGLYPH_H_ #include <ft2build.h> @@ -325,22 +325,8 @@ FT_BEGIN_HEADER } FT_Glyph_BBox_Mode; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_glyph_bbox_xxx */ - /* */ - /* <Description> */ - /* These constants are deprecated. Use the corresponding */ - /* @FT_Glyph_BBox_Mode values instead. */ - /* */ - /* <Values> */ - /* ft_glyph_bbox_unscaled :: See @FT_GLYPH_BBOX_UNSCALED. */ - /* ft_glyph_bbox_subpixels :: See @FT_GLYPH_BBOX_SUBPIXELS. */ - /* ft_glyph_bbox_gridfit :: See @FT_GLYPH_BBOX_GRIDFIT. */ - /* ft_glyph_bbox_truncate :: See @FT_GLYPH_BBOX_TRUNCATE. */ - /* ft_glyph_bbox_pixels :: See @FT_GLYPH_BBOX_PIXELS. */ - /* */ + /* these constants are deprecated; use the corresponding */ + /* `FT_Glyph_BBox_Mode' values instead */ #define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED #define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS #define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT @@ -358,17 +344,17 @@ FT_BEGIN_HEADER /* outline's points, including Bézier control points. Though it */ /* coincides with the exact bounding box for most glyphs, it can be */ /* slightly larger in some situations (like when rotating an outline */ - /* which contains Bézier outside arcs). */ + /* that contains Bézier outside arcs). */ /* */ /* Computing the control box is very fast, while getting the bounding */ /* box can take much more time as it needs to walk over all segments */ /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component which is dedicated to this single task. */ + /* `ftbbox' component, which is dedicated to this single task. */ /* */ /* <Input> */ /* glyph :: A handle to the source glyph object. */ /* */ - /* mode :: The mode which indicates how to interpret the returned */ + /* mode :: The mode that indicates how to interpret the returned */ /* bounding box values. */ /* */ /* <Output> */ @@ -388,7 +374,7 @@ FT_BEGIN_HEADER /* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get */ /* reasonable values for the CBox it is necessary to load the glyph */ /* at a large ppem value (so that the hinting instructions can */ - /* properly shift and scale the subglyphs), then extracting the CBox */ + /* properly shift and scale the subglyphs), then extracting the CBox, */ /* which can be eventually converted back to font units. */ /* */ /* Note that the maximum coordinates are exclusive, which means that */ @@ -603,13 +589,12 @@ FT_BEGIN_HEADER FT_EXPORT( FT_Error ) FT_Matrix_Invert( FT_Matrix* matrix ); - /* */ FT_END_HEADER -#endif /* __FTGLYPH_H__ */ +#endif /* FTGLYPH_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftgxval.h b/drivers/freetype/include/freetype/ftgxval.h index 497015c101..a58e86a040 100644 --- a/drivers/freetype/freetype/include/freetype/ftgxval.h +++ b/drivers/freetype/include/freetype/ftgxval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating TrueTypeGX/AAT tables (specification). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004-2016 by */ /* Masatake YAMATO, Redhat K.K, */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __FTGXVAL_H__ -#define __FTGXVAL_H__ +#ifndef FTGXVAL_H_ +#define FTGXVAL_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -57,9 +57,19 @@ FT_BEGIN_HEADER /* some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, */ /* trak, prop, lcar). */ /* */ + /* <Order> */ + /* FT_TrueTypeGX_Validate */ + /* FT_TrueTypeGX_Free */ + /* */ + /* FT_ClassicKern_Validate */ + /* FT_ClassicKern_Free */ + /* */ + /* FT_VALIDATE_GX_LENGTH */ + /* FT_VALIDATE_GXXXX */ + /* FT_VALIDATE_CKERNXXX */ + /* */ /*************************************************************************/ - /*************************************************************************/ /* */ /* */ @@ -171,8 +181,6 @@ FT_BEGIN_HEADER FT_VALIDATE_lcar ) - /* */ - /********************************************************************** * * @function: @@ -180,7 +188,7 @@ FT_BEGIN_HEADER * * @description: * Validate various TrueTypeGX tables to assure that all offsets and - * indices are valid. The idea is that a higher-level library which + * indices are valid. The idea is that a higher-level library that * actually does the text layout can access those tables without * error checking (which can be quite time consuming). * @@ -189,7 +197,7 @@ FT_BEGIN_HEADER * A handle to the input face. * * validation_flags :: - * A bit field which specifies the tables to be validated. See + * A bit field that specifies the tables to be validated. See * @FT_VALIDATE_GXXXX for possible values. * * table_length :: @@ -221,8 +229,6 @@ FT_BEGIN_HEADER FT_UInt table_length ); - /* */ - /********************************************************************** * * @function: @@ -248,8 +254,6 @@ FT_BEGIN_HEADER FT_Bytes table ); - /* */ - /********************************************************************** * * @enum: @@ -277,8 +281,6 @@ FT_BEGIN_HEADER #define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE ) - /* */ - /********************************************************************** * * @function: @@ -286,7 +288,7 @@ FT_BEGIN_HEADER * * @description: * Validate classic (16-bit format) kern table to assure that the offsets - * and indices are valid. The idea is that a higher-level library which + * and indices are valid. The idea is that a higher-level library that * actually does the text layout can access those tables without error * checking (which can be quite time consuming). * @@ -299,7 +301,7 @@ FT_BEGIN_HEADER * A handle to the input face. * * validation_flags :: - * A bit field which specifies the dialect to be validated. See + * A bit field that specifies the dialect to be validated. See * @FT_VALIDATE_CKERNXXX for possible values. * * @output: @@ -320,8 +322,6 @@ FT_BEGIN_HEADER FT_Bytes *ckern_table ); - /* */ - /********************************************************************** * * @function: @@ -346,13 +346,12 @@ FT_BEGIN_HEADER FT_ClassicKern_Free( FT_Face face, FT_Bytes table ); - - /* */ + /* */ FT_END_HEADER -#endif /* __FTGXVAL_H__ */ +#endif /* FTGXVAL_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftgzip.h b/drivers/freetype/include/freetype/ftgzip.h index acbc4f0327..3932ce6887 100644 --- a/drivers/freetype/freetype/include/freetype/ftgzip.h +++ b/drivers/freetype/include/freetype/ftgzip.h @@ -4,7 +4,7 @@ /* */ /* Gzip-compressed stream support. */ /* */ -/* Copyright 2002, 2003, 2004, 2006 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTGZIP_H__ -#define __FTGZIP_H__ +#ifndef FTGZIP_H_ +#define FTGZIP_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -91,12 +91,58 @@ FT_BEGIN_HEADER FT_Stream_OpenGzip( FT_Stream stream, FT_Stream source ); - /* */ + + /************************************************************************ + * + * @function: + * FT_Gzip_Uncompress + * + * @description: + * Decompress a zipped input buffer into an output buffer. This function + * is modeled after zlib's `uncompress' function. + * + * @input: + * memory :: + * A FreeType memory handle. + * + * input :: + * The input buffer. + * + * input_len :: + * The length of the input buffer. + * + * @output: + * output:: + * The output buffer. + * + * @inout: + * output_len :: + * Before calling the function, this is the total size of the output + * buffer, which must be large enough to hold the entire uncompressed + * data (so the size of the uncompressed data must be known in + * advance). After calling the function, `output_len' is the size of + * the used data in `output'. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with zlib support. + */ + FT_EXPORT( FT_Error ) + FT_Gzip_Uncompress( FT_Memory memory, + FT_Byte* output, + FT_ULong* output_len, + const FT_Byte* input, + FT_ULong input_len ); + + /* */ FT_END_HEADER -#endif /* __FTGZIP_H__ */ +#endif /* FTGZIP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftimage.h b/drivers/freetype/include/freetype/ftimage.h index 3b826b1d32..28b2704e80 100644 --- a/drivers/freetype/freetype/include/freetype/ftimage.h +++ b/drivers/freetype/include/freetype/ftimage.h @@ -5,7 +5,7 @@ /* FreeType glyph image formats and default raster interface */ /* (specification). */ /* */ -/* Copyright 1996-2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,12 +24,12 @@ /*************************************************************************/ -#ifndef __FTIMAGE_H__ -#define __FTIMAGE_H__ +#ifndef FTIMAGE_H_ +#define FTIMAGE_H_ - /* _STANDALONE_ is from ftgrays.c */ -#ifndef _STANDALONE_ + /* STANDALONE_ is from ftgrays.c */ +#ifndef STANDALONE_ #include <ft2build.h> #endif @@ -193,67 +193,14 @@ FT_BEGIN_HEADER } FT_Pixel_Mode; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_pixel_mode_xxx */ - /* */ - /* <Description> */ - /* A list of deprecated constants. Use the corresponding */ - /* @FT_Pixel_Mode values instead. */ - /* */ - /* <Values> */ - /* ft_pixel_mode_none :: See @FT_PIXEL_MODE_NONE. */ - /* ft_pixel_mode_mono :: See @FT_PIXEL_MODE_MONO. */ - /* ft_pixel_mode_grays :: See @FT_PIXEL_MODE_GRAY. */ - /* ft_pixel_mode_pal2 :: See @FT_PIXEL_MODE_GRAY2. */ - /* ft_pixel_mode_pal4 :: See @FT_PIXEL_MODE_GRAY4. */ - /* */ + /* these constants are deprecated; use the corresponding `FT_Pixel_Mode' */ + /* values instead. */ #define ft_pixel_mode_none FT_PIXEL_MODE_NONE #define ft_pixel_mode_mono FT_PIXEL_MODE_MONO #define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY #define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 #define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 - /* */ - -#if 0 - - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Palette_Mode */ - /* */ - /* <Description> */ - /* THIS TYPE IS DEPRECATED. DO NOT USE IT! */ - /* */ - /* An enumeration type to describe the format of a bitmap palette, */ - /* used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ - /* */ - /* <Values> */ - /* ft_palette_mode_rgb :: The palette is an array of 3-byte RGB */ - /* records. */ - /* */ - /* ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA */ - /* records. */ - /* */ - /* <Note> */ - /* As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by */ - /* FreeType, these types are not handled by the library itself. */ - /* */ - typedef enum FT_Palette_Mode_ - { - ft_palette_mode_rgb = 0, - ft_palette_mode_rgba, - - ft_palette_mode_max /* do not remove */ - - } FT_Palette_Mode; - - /* */ - -#endif - /*************************************************************************/ /* */ @@ -311,20 +258,15 @@ FT_BEGIN_HEADER /* field is intended for paletted pixel modes. Not */ /* used currently. */ /* */ - /* <Note> */ - /* For now, the only pixel modes supported by FreeType are mono and */ - /* grays. However, drivers might be added in the future to support */ - /* more `colorful' options. */ - /* */ typedef struct FT_Bitmap_ { - int rows; - int width; + unsigned int rows; + unsigned int width; int pitch; unsigned char* buffer; - short num_grays; - char pixel_mode; - char palette_mode; + unsigned short num_grays; + unsigned char pixel_mode; + unsigned char palette_mode; void* palette; } FT_Bitmap; @@ -381,7 +323,7 @@ FT_BEGIN_HEADER /* */ /* flags :: A set of bit flags used to characterize the outline */ /* and give hints to the scan-converter and hinter on */ - /* how to convert/grid-fit it. See @FT_OUTLINE_FLAGS. */ + /* how to convert/grid-fit it. See @FT_OUTLINE_XXX. */ /* */ /* <Note> */ /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ @@ -402,6 +344,8 @@ FT_BEGIN_HEADER } FT_Outline; + /* */ + /* Following limits must be consistent with */ /* FT_Outline.{n_contours,n_points} */ #define FT_OUTLINE_CONTOURS_MAX SHRT_MAX @@ -411,7 +355,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Enum> */ - /* FT_OUTLINE_FLAGS */ + /* FT_OUTLINE_XXX */ /* */ /* <Description> */ /* A list of bit-field constants use for the flags in an outline's */ @@ -492,24 +436,8 @@ FT_BEGIN_HEADER #define FT_OUTLINE_SINGLE_PASS 0x200 - /************************************************************************* - * - * @enum: - * ft_outline_flags - * - * @description: - * These constants are deprecated. Please use the corresponding - * @FT_OUTLINE_FLAGS values. - * - * @values: - * ft_outline_none :: See @FT_OUTLINE_NONE. - * ft_outline_owner :: See @FT_OUTLINE_OWNER. - * ft_outline_even_odd_fill :: See @FT_OUTLINE_EVEN_ODD_FILL. - * ft_outline_reverse_fill :: See @FT_OUTLINE_REVERSE_FILL. - * ft_outline_ignore_dropouts :: See @FT_OUTLINE_IGNORE_DROPOUTS. - * ft_outline_high_precision :: See @FT_OUTLINE_HIGH_PRECISION. - * ft_outline_single_pass :: See @FT_OUTLINE_SINGLE_PASS. - */ + /* these constants are deprecated; use the corresponding */ + /* `FT_OUTLINE_XXX' values instead */ #define ft_outline_none FT_OUTLINE_NONE #define ft_outline_owner FT_OUTLINE_OWNER #define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL @@ -555,7 +483,7 @@ FT_BEGIN_HEADER /* <Input> */ /* to :: A pointer to the target point of the `move to'. */ /* */ - /* user :: A typeless pointer which is passed from the caller of the */ + /* user :: A typeless pointer, which is passed from the caller of the */ /* decomposition function. */ /* */ /* <Return> */ @@ -582,7 +510,7 @@ FT_BEGIN_HEADER /* <Input> */ /* to :: A pointer to the target point of the `line to'. */ /* */ - /* user :: A typeless pointer which is passed from the caller of the */ + /* user :: A typeless pointer, which is passed from the caller of the */ /* decomposition function. */ /* */ /* <Return> */ @@ -613,7 +541,7 @@ FT_BEGIN_HEADER /* */ /* to :: A pointer to the target end point of the conic arc. */ /* */ - /* user :: A typeless pointer which is passed from the caller of */ + /* user :: A typeless pointer, which is passed from the caller of */ /* the decomposition function. */ /* */ /* <Return> */ @@ -645,7 +573,7 @@ FT_BEGIN_HEADER /* */ /* to :: A pointer to the target end point. */ /* */ - /* user :: A typeless pointer which is passed from the caller of */ + /* user :: A typeless pointer, which is passed from the caller of */ /* the decomposition function. */ /* */ /* <Return> */ @@ -796,22 +724,8 @@ FT_BEGIN_HEADER } FT_Glyph_Format; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* ft_glyph_format_xxx */ - /* */ - /* <Description> */ - /* A list of deprecated constants. Use the corresponding */ - /* @FT_Glyph_Format values instead. */ - /* */ - /* <Values> */ - /* ft_glyph_format_none :: See @FT_GLYPH_FORMAT_NONE. */ - /* ft_glyph_format_composite :: See @FT_GLYPH_FORMAT_COMPOSITE. */ - /* ft_glyph_format_bitmap :: See @FT_GLYPH_FORMAT_BITMAP. */ - /* ft_glyph_format_outline :: See @FT_GLYPH_FORMAT_OUTLINE. */ - /* ft_glyph_format_plotter :: See @FT_GLYPH_FORMAT_PLOTTER. */ - /* */ + /* these constants are deprecated; use the corresponding */ + /* `FT_Glyph_Format' values instead. */ #define ft_glyph_format_none FT_GLYPH_FORMAT_NONE #define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE #define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP @@ -833,11 +747,11 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* A raster is a scan converter, in charge of rendering an outline into */ - /* a a bitmap. This section contains the public API for rasters. */ + /* a bitmap. This section contains the public API for rasters. */ /* */ /* Note that in FreeType 2, all rasters are now encapsulated within */ - /* specific modules called `renderers'. See `freetype/ftrender.h' for */ - /* more details on renderers. */ + /* specific modules called `renderers'. See `ftrender.h' for more */ + /* details on renderers. */ /* */ /*************************************************************************/ @@ -856,6 +770,21 @@ FT_BEGIN_HEADER /* <Description> */ /* This section contains technical definitions. */ /* */ + /* <Order> */ + /* FT_Raster */ + /* FT_Span */ + /* FT_SpanFunc */ + /* */ + /* FT_Raster_Params */ + /* FT_RASTER_FLAG_XXX */ + /* */ + /* FT_Raster_NewFunc */ + /* FT_Raster_DoneFunc */ + /* FT_Raster_ResetFunc */ + /* FT_Raster_SetModeFunc */ + /* FT_Raster_RenderFunc */ + /* FT_Raster_Funcs */ + /* */ /*************************************************************************/ @@ -865,8 +794,8 @@ FT_BEGIN_HEADER /* FT_Raster */ /* */ /* <Description> */ - /* A handle (pointer) to a raster object. Each object can be used */ - /* independently to convert an outline into a bitmap or pixmap. */ + /* An opaque handle (pointer) to a raster object. Each object can be */ + /* used independently to convert an outline into a bitmap or pixmap. */ /* */ typedef struct FT_RasterRec_* FT_Raster; @@ -877,8 +806,8 @@ FT_BEGIN_HEADER /* FT_Span */ /* */ /* <Description> */ - /* A structure used to model a single span of gray (or black) pixels */ - /* when rendering a monochrome or anti-aliased bitmap. */ + /* A structure used to model a single span of gray pixels when */ + /* rendering an anti-aliased bitmap. */ /* */ /* <Fields> */ /* x :: The span's horizontal start position. */ @@ -886,13 +815,12 @@ FT_BEGIN_HEADER /* len :: The span's length in pixels. */ /* */ /* coverage :: The span color/coverage, ranging from 0 (background) */ - /* to 255 (foreground). Only used for anti-aliased */ - /* rendering. */ + /* to 255 (foreground). */ /* */ /* <Note> */ /* This structure is used by the span drawing callback type named */ - /* @FT_SpanFunc which takes the y~coordinate of the span as a */ - /* a parameter. */ + /* @FT_SpanFunc that takes the y~coordinate of the span as a */ + /* parameter. */ /* */ /* The coverage value is always between 0 and 255. If you want less */ /* gray values, the callback function has to reduce them. */ @@ -957,22 +885,7 @@ FT_BEGIN_HEADER /* FT_Raster_BitTest_Func */ /* */ /* <Description> */ - /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ - /* */ - /* A function used as a call-back by the monochrome scan-converter */ - /* to test whether a given target pixel is already set to the drawing */ - /* `color'. These tests are crucial to implement drop-out control */ - /* per-se the TrueType spec. */ - /* */ - /* <Input> */ - /* y :: The pixel's y~coordinate. */ - /* */ - /* x :: The pixel's x~coordinate. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* <Return> */ - /* 1~if the pixel is `set', 0~otherwise. */ + /* Deprecated, unimplemented. */ /* */ typedef int (*FT_Raster_BitTest_Func)( int y, @@ -986,21 +899,7 @@ FT_BEGIN_HEADER /* FT_Raster_BitSet_Func */ /* */ /* <Description> */ - /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ - /* */ - /* A function used as a call-back by the monochrome scan-converter */ - /* to set an individual target pixel. This is crucial to implement */ - /* drop-out control according to the TrueType specification. */ - /* */ - /* <Input> */ - /* y :: The pixel's y~coordinate. */ - /* */ - /* x :: The pixel's x~coordinate. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* <Return> */ - /* 1~if the pixel is `set', 0~otherwise. */ + /* Deprecated, unimplemented. */ /* */ typedef void (*FT_Raster_BitSet_Func)( int y, @@ -1034,8 +933,8 @@ FT_BEGIN_HEADER /* pixmap's buffer _must_ be zeroed before */ /* rendering. */ /* */ - /* Note that for now, direct rendering is */ - /* only possible with anti-aliased glyphs. */ + /* Direct rendering is only possible with */ + /* anti-aliased glyphs. */ /* */ /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ /* rendering mode. If set, the output will */ @@ -1053,7 +952,8 @@ FT_BEGIN_HEADER #define FT_RASTER_FLAG_DIRECT 0x2 #define FT_RASTER_FLAG_CLIP 0x4 - /* deprecated */ + /* these constants are deprecated; use the corresponding */ + /* `FT_RASTER_FLAG_XXX' values instead */ #define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT #define ft_raster_flag_aa FT_RASTER_FLAG_AA #define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT @@ -1079,11 +979,11 @@ FT_BEGIN_HEADER /* */ /* gray_spans :: The gray span drawing callback. */ /* */ - /* black_spans :: The black span drawing callback. UNIMPLEMENTED! */ + /* black_spans :: Unused. */ /* */ - /* bit_test :: The bit test callback. UNIMPLEMENTED! */ + /* bit_test :: Unused. */ /* */ - /* bit_set :: The bit set callback. UNIMPLEMENTED! */ + /* bit_set :: Unused. */ /* */ /* user :: User-supplied data that is passed to each drawing */ /* callback. */ @@ -1100,15 +1000,9 @@ FT_BEGIN_HEADER /* */ /* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ /* raster will call the `gray_spans' callback to draw gray pixel */ - /* spans, in the case of an aa glyph bitmap, it will call */ - /* `black_spans', and `bit_test' and `bit_set' in the case of a */ - /* monochrome bitmap. This allows direct composition over a */ - /* pre-existing bitmap through user-provided callbacks to perform the */ - /* span drawing/composition. */ - /* */ - /* Note that the `bit_test' and `bit_set' callbacks are required when */ - /* rendering a monochrome bitmap, as they are crucial to implement */ - /* correct drop-out control as defined in the TrueType specification. */ + /* spans. This allows direct composition over a pre-existing bitmap */ + /* through user-provided callbacks to perform the span drawing and */ + /* composition. Not supported by the monochrome rasterizer. */ /* */ typedef struct FT_Raster_Params_ { @@ -1116,9 +1010,9 @@ FT_BEGIN_HEADER const void* source; int flags; FT_SpanFunc gray_spans; - FT_SpanFunc black_spans; /* doesn't work! */ - FT_Raster_BitTest_Func bit_test; /* doesn't work! */ - FT_Raster_BitSet_Func bit_set; /* doesn't work! */ + FT_SpanFunc black_spans; /* unused */ + FT_Raster_BitTest_Func bit_test; /* unused */ + FT_Raster_BitSet_Func bit_set; /* unused */ void* user; FT_BBox clip_box; @@ -1179,10 +1073,10 @@ FT_BEGIN_HEADER /* FT_Raster_ResetFunc */ /* */ /* <Description> */ - /* FreeType provides an area of memory called the `render pool', */ - /* available to all registered rasters. This pool can be freely used */ - /* during a given scan-conversion but is shared by all rasters. Its */ - /* content is thus transient. */ + /* FreeType used to provide an area of memory called the `render */ + /* pool' available to all registered rasters. This was not thread */ + /* safe however and now FreeType never allocates this pool. NULL */ + /* is always passed in as pool_base. */ /* */ /* This function is called each time the render pool changes, or just */ /* after a new raster object is created. */ @@ -1195,10 +1089,9 @@ FT_BEGIN_HEADER /* pool_size :: The size in bytes of the render pool. */ /* */ /* <Note> */ - /* Rasters can ignore the render pool and rely on dynamic memory */ + /* Rasters should ignore the render pool and rely on dynamic or stack */ /* allocation if they want to (a handle to the memory allocator is */ - /* passed to the raster constructor). However, this is not */ - /* recommended for efficiency purposes. */ + /* passed to the raster constructor). */ /* */ typedef void (*FT_Raster_ResetFunc)( FT_Raster raster, @@ -1265,7 +1158,7 @@ FT_BEGIN_HEADER /* XXX: For now, the standard raster doesn't support direct */ /* composition but this should change for the final release (see */ /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ - /* for examples of distinct implementations which support direct */ + /* for examples of distinct implementations that support direct */ /* composition). */ /* */ typedef int @@ -1305,13 +1198,12 @@ FT_BEGIN_HEADER } FT_Raster_Funcs; - /* */ FT_END_HEADER -#endif /* __FTIMAGE_H__ */ +#endif /* FTIMAGE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftincrem.h b/drivers/freetype/include/freetype/ftincrem.h index aaf689ff16..46b58b7917 100644 --- a/drivers/freetype/freetype/include/freetype/ftincrem.h +++ b/drivers/freetype/include/freetype/ftincrem.h @@ -4,7 +4,7 @@ /* */ /* FreeType incremental loading (specification). */ /* */ -/* Copyright 2002, 2003, 2006, 2007, 2008, 2010 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTINCREM_H__ -#define __FTINCREM_H__ +#ifndef FTINCREM_H_ +#define FTINCREM_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -45,7 +45,7 @@ FT_BEGIN_HEADER * @description: * This section contains various functions used to perform so-called * `incremental' glyph loading. This is a mode where all glyphs loaded - * from a given @FT_Face are provided by the client application, + * from a given @FT_Face are provided by the client application. * * Apart from that, all other tables are loaded normally from the font * file. This mode is useful when FreeType is used within another @@ -345,9 +345,10 @@ FT_BEGIN_HEADER /* */ + FT_END_HEADER -#endif /* __FTINCREM_H__ */ +#endif /* FTINCREM_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftlcdfil.h b/drivers/freetype/include/freetype/ftlcdfil.h index 8b253f118b..e06a8957f5 100644 --- a/drivers/freetype/freetype/include/freetype/ftlcdfil.h +++ b/drivers/freetype/include/freetype/ftlcdfil.h @@ -5,7 +5,7 @@ /* FreeType API for color filtering of subpixel bitmap glyphs */ /* (specification). */ /* */ -/* Copyright 2006, 2007, 2008, 2010 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __FT_LCD_FILTER_H__ -#define __FT_LCD_FILTER_H__ +#ifndef FTLCDFIL_H_ +#define FTLCDFIL_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -41,56 +41,91 @@ FT_BEGIN_HEADER * LCD Filtering * * @abstract: - * Reduce color fringes of LCD-optimized bitmaps. + * Reduce color fringes of subpixel-rendered bitmaps. * * @description: - * The @FT_Library_SetLcdFilter API can be used to specify a low-pass - * filter which is then applied to LCD-optimized bitmaps generated - * through @FT_Render_Glyph. This is useful to reduce color fringes - * which would occur with unfiltered rendering. + * Subpixel rendering exploits the color-striped structure of LCD + * pixels, increasing the available resolution in the direction of the + * stripe (usually horizontal RGB) by a factor of~3. Since these + * subpixels are color pixels, using them unfiltered creates severe + * color fringes. Use the @FT_Library_SetLcdFilter API to specify a + * low-pass filter, which is then applied to subpixel-rendered bitmaps + * generated through @FT_Render_Glyph. The filter sacrifices some of + * the higher resolution to reduce color fringes, making the glyph image + * slightly blurrier. Positional improvements will remain. * * Note that no filter is active by default, and that this function is * *not* implemented in default builds of the library. You need to * #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file - * in order to activate it. - * - * FreeType generates alpha coverage maps, which are linear by nature. - * For instance, the value 0x80 in bitmap representation means that - * (within numerical precision) 0x80/0xff fraction of that pixel is - * covered by the glyph's outline. The blending function for placing - * text over a background is - * - * { - * dst = alpha * src + (1 - alpha) * dst , - * } - * - * which is known as OVER. However, when calculating the output of the - * OVER operator, the source colors should first be transformed to a - * linear color space, then alpha blended in that space, and transformed - * back to the output color space. - * - * When linear light blending is used, the default FIR5 filtering - * weights (as given by FT_LCD_FILTER_DEFAULT) are no longer optimal, as - * they have been designed for black on white rendering while lacking - * gamma correction. To preserve color neutrality, weights for a FIR5 - * filter should be chosen according to two free parameters `a' and `c', - * and the FIR weights should be - * - * { - * [a - c, a + c, 2 * a, a + c, a - c] . - * } - * - * This formula generates equal weights for all the color primaries - * across the filter kernel, which makes it colorless. One suggested - * set of weights is - * - * { - * [0x10, 0x50, 0x60, 0x50, 0x10] , - * } - * - * where `a' has value 0x30 and `b' value 0x20. The weights in filter - * may have a sum larger than 0x100, which increases coloration slightly - * but also improves contrast. + * in order to activate it and explicitly call @FT_Library_SetLcdFilter + * to enable it. + * + * A filter should have two properties: + * + * 1) It should be normalized, meaning the sum of the 5~components + * should be 256 (0x100). It is possible to go above or under this + * target sum, however: going under means tossing out contrast, going + * over means invoking clamping and thereby non-linearities that + * increase contrast somewhat at the expense of greater distortion + * and color-fringing. Contrast is better enhanced through stem + * darkening. + * + * 2) It should be color-balanced, meaning a filter `{~a, b, c, b, a~}' + * where a~+ b~=~c. It distributes the computed coverage for one + * subpixel to all subpixels equally, sacrificing some won resolution + * but drastically reducing color-fringing. Positioning improvements + * remain! Note that color-fringing can only really be minimized + * when using a color-balanced filter and alpha-blending the glyph + * onto a surface in linear space; see @FT_Render_Glyph. + * + * Regarding the form, a filter can be a `boxy' filter or a `beveled' + * filter. Boxy filters are sharper but are less forgiving of non-ideal + * gamma curves of a screen (viewing angles!), beveled filters are + * fuzzier but more tolerant. + * + * Examples: + * + * - [0x10 0x40 0x70 0x40 0x10] is beveled and neither balanced nor + * normalized. + * + * - [0x1A 0x33 0x4D 0x33 0x1A] is beveled and balanced but not + * normalized. + * + * - [0x19 0x33 0x66 0x4c 0x19] is beveled and normalized but not + * balanced. + * + * - [0x00 0x4c 0x66 0x4c 0x00] is boxily beveled and normalized but not + * balanced. + * + * - [0x00 0x55 0x56 0x55 0x00] is boxy, normalized, and almost + * balanced. + * + * - [0x08 0x4D 0x56 0x4D 0x08] is beveled, normalized and, almost + * balanced. + * + * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, + * @FT_Load_Glyph, and @FT_Load_Char. It does _not_ affect the output + * of @FT_Outline_Render and @FT_Outline_Get_Bitmap. + * + * If this feature is activated, the dimensions of LCD glyph bitmaps are + * either wider or taller than the dimensions of the corresponding + * outline with regard to the pixel grid. For example, for + * @FT_RENDER_MODE_LCD, the filter adds 3~subpixels to the left, and + * 3~subpixels to the right. The bitmap offset values are adjusted + * accordingly, so clients shouldn't need to modify their layout and + * glyph positioning code when enabling the filter. + * + * It is important to understand that linear alpha blending and gamma + * correction is critical for correctly rendering glyphs onto surfaces + * without artifacts and even more critical when subpixel rendering is + * involved. + * + * Each of the 3~alpha values (subpixels) is independently used to blend + * one color channel. That is, red alpha blends the red channel of the + * text color with the red channel of the background pixel. The + * distribution of density values by the color-balanced filter assumes + * alpha blending is done in linear space; only then color artifacts + * cancel out. */ @@ -111,10 +146,23 @@ FT_BEGIN_HEADER * The default filter reduces color fringes considerably, at the cost * of a slight blurriness in the output. * + * It is a beveled, normalized, and color-balanced five-tap filter + * that is more forgiving to screens with non-ideal gamma curves and + * viewing angles. Note that while color-fringing is reduced, it can + * only be minimized by using linear alpha blending and gamma + * correction to render glyphs onto surfaces. The default filter + * weights are [0x08 0x4D 0x56 0x4D 0x08]. + * * FT_LCD_FILTER_LIGHT :: - * The light filter is a variant that produces less blurriness at the - * cost of slightly more color fringes than the default one. It might - * be better, depending on taste, your monitor, or your personal vision. + * The light filter is a variant that is sharper at the cost of + * slightly more color fringes than the default one. + * + * It is a boxy, normalized, and color-balanced three-tap filter that + * is less forgiving to screens with non-ideal gamma curves and + * viewing angles. This filter works best when the rendering system + * uses linear alpha blending and gamma correction to render glyphs + * onto surfaces. The light filter weights are + * [0x00 0x55 0x56 0x55 0x00]. * * FT_LCD_FILTER_LEGACY :: * This filter corresponds to the original libXft color filter. It @@ -126,14 +174,23 @@ FT_BEGIN_HEADER * This filter is only provided for comparison purposes, and might be * disabled or stay unsupported in the future. * + * FT_LCD_FILTER_LEGACY1 :: + * For historical reasons, the FontConfig library returns a different + * enumeration value for legacy LCD filtering. To make code work that + * (incorrectly) forwards FontConfig's enumeration value to + * @FT_Library_SetLcdFilter without proper mapping, it is thus easiest + * to have another enumeration value, which is completely equal to + * `FT_LCD_FILTER_LEGACY'. + * * @since: - * 2.3.0 + * 2.3.0 (`FT_LCD_FILTER_LEGACY1' since 2.6.2) */ typedef enum FT_LcdFilter_ { FT_LCD_FILTER_NONE = 0, FT_LCD_FILTER_DEFAULT = 1, FT_LCD_FILTER_LIGHT = 2, + FT_LCD_FILTER_LEGACY1 = 3, FT_LCD_FILTER_LEGACY = 16, FT_LCD_FILTER_MAX /* do not remove */ @@ -176,22 +233,6 @@ FT_BEGIN_HEADER * defined in your build of the library, which should correspond to all * default builds of FreeType. * - * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, - * @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char. - * - * It does _not_ affect the output of @FT_Outline_Render and - * @FT_Outline_Get_Bitmap. - * - * If this feature is activated, the dimensions of LCD glyph bitmaps are - * either larger or taller than the dimensions of the corresponding - * outline with regards to the pixel grid. For example, for - * @FT_RENDER_MODE_LCD, the filter adds up to 3~pixels to the left, and - * up to 3~pixels to the right. - * - * The bitmap offset values are adjusted correctly, so clients shouldn't - * need to modify their layout and glyph positioning code when enabling - * the filter. - * * @since: * 2.3.0 */ @@ -206,11 +247,8 @@ FT_BEGIN_HEADER * FT_Library_SetLcdFilterWeights * * @description: - * Use this function to override the filter weights selected by - * @FT_Library_SetLcdFilter. By default, FreeType uses the quintuple - * (0x00, 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10, - * 0x40, 0x70, 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and - * FT_LCD_FILTER_LEGACY. + * This function can be used to enable LCD filter with custom weights, + * instead of using presets in @FT_Library_SetLcdFilter. * * @input: * library :: @@ -230,9 +268,6 @@ FT_BEGIN_HEADER * defined in your build of the library, which should correspond to all * default builds of FreeType. * - * This function must be called after @FT_Library_SetLcdFilter to have - * any effect. - * * @since: * 2.4.0 */ @@ -245,7 +280,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FT_LCD_FILTER_H__ */ +#endif /* FTLCDFIL_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftlist.h b/drivers/freetype/include/freetype/ftlist.h index bb6f7f119d..82f437ac61 100644 --- a/drivers/freetype/freetype/include/freetype/ftlist.h +++ b/drivers/freetype/include/freetype/ftlist.h @@ -4,7 +4,7 @@ /* */ /* Generic list support for FreeType (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2007, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +24,8 @@ /*************************************************************************/ -#ifndef __FTLIST_H__ -#define __FTLIST_H__ +#ifndef FTLIST_H_ +#define FTLIST_H_ #include <ft2build.h> @@ -173,7 +173,7 @@ FT_BEGIN_HEADER /* FT_List_Iterator */ /* */ /* <Description> */ - /* An FT_List iterator function which is called during a list parse */ + /* An FT_List iterator function that is called during a list parse */ /* by @FT_List_Iterate. */ /* */ /* <Input> */ @@ -200,7 +200,7 @@ FT_BEGIN_HEADER /* <Input> */ /* list :: A handle to the list. */ /* iterator :: An iterator function, called on each node of the list. */ - /* user :: A user-supplied field which is passed as the second */ + /* user :: A user-supplied field that is passed as the second */ /* argument to the iterator. */ /* */ /* <Return> */ @@ -218,7 +218,7 @@ FT_BEGIN_HEADER /* FT_List_Destructor */ /* */ /* <Description> */ - /* An @FT_List iterator function which is called during a list */ + /* An @FT_List iterator function that is called during a list */ /* finalization by @FT_List_Finalize to destroy all elements in a */ /* given list. */ /* */ @@ -248,11 +248,11 @@ FT_BEGIN_HEADER /* list :: A handle to the list. */ /* */ /* destroy :: A list destructor that will be applied to each element */ - /* of the list. */ + /* of the list. Set this to NULL if not needed. */ /* */ - /* memory :: The current memory object which handles deallocation. */ + /* memory :: The current memory object that handles deallocation. */ /* */ - /* user :: A user-supplied field which is passed as the last */ + /* user :: A user-supplied field that is passed as the last */ /* argument to the destructor. */ /* */ /* <Note> */ @@ -265,13 +265,12 @@ FT_BEGIN_HEADER FT_Memory memory, void* user ); - /* */ FT_END_HEADER -#endif /* __FTLIST_H__ */ +#endif /* FTLIST_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftlzw.h b/drivers/freetype/include/freetype/ftlzw.h index 00d40169a7..582e2c1465 100644 --- a/drivers/freetype/freetype/include/freetype/ftlzw.h +++ b/drivers/freetype/include/freetype/ftlzw.h @@ -4,7 +4,7 @@ /* */ /* LZW-compressed stream support. */ /* */ -/* Copyright 2004, 2006 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTLZW_H__ -#define __FTLZW_H__ +#ifndef FTLZW_H_ +#define FTLZW_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -88,12 +88,12 @@ FT_BEGIN_HEADER FT_Stream_OpenLZW( FT_Stream stream, FT_Stream source ); - /* */ + /* */ FT_END_HEADER -#endif /* __FTLZW_H__ */ +#endif /* FTLZW_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftmac.h b/drivers/freetype/include/freetype/ftmac.h index ab5bab5170..adb15cadf3 100644 --- a/drivers/freetype/freetype/include/freetype/ftmac.h +++ b/drivers/freetype/include/freetype/ftmac.h @@ -4,7 +4,7 @@ /* */ /* Additional Mac-specific API. */ /* */ -/* Copyright 1996-2001, 2004, 2006, 2007 by */ +/* Copyright 1996-2016 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,15 +18,15 @@ /***************************************************************************/ /* */ -/* NOTE: Include this file after <freetype/freetype.h> and after any */ +/* NOTE: Include this file after FT_FREETYPE_H and after any */ /* Mac-specific headers (because this header uses Mac types such as */ /* Handle, FSSpec, FSRef, etc.) */ /* */ /***************************************************************************/ -#ifndef __FTMAC_H__ -#define __FTMAC_H__ +#ifndef FTMAC_H_ +#define FTMAC_H_ #include <ft2build.h> @@ -168,7 +168,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Return a pathname of the disk file and face index for given font */ - /* name which is handled by ATS framework. */ + /* name that is handled by ATS framework. */ /* */ /* <Input> */ /* fontName :: Mac OS name of the font in ATS framework. */ @@ -268,7 +268,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTMAC_H__ */ +#endif /* FTMAC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftmm.h b/drivers/freetype/include/freetype/ftmm.h index 3aefb9e4f2..6c05f0c390 100644 --- a/drivers/freetype/freetype/include/freetype/ftmm.h +++ b/drivers/freetype/include/freetype/ftmm.h @@ -4,7 +4,7 @@ /* */ /* FreeType Multiple Master font interface (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2006, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMM_H__ -#define __FTMM_H__ +#ifndef FTMM_H_ +#define FTMM_H_ #include <ft2build.h> @@ -95,8 +95,8 @@ FT_BEGIN_HEADER /* */ /* num_designs :: Number of designs; should be normally 2^num_axis */ /* even though the Type~1 specification strangely */ - /* allows for intermediate designs to be present. This */ - /* number cannot exceed~16. */ + /* allows for intermediate designs to be present. */ + /* This number cannot exceed~16. */ /* */ /* axis :: A table of axis descriptors. */ /* */ @@ -196,16 +196,20 @@ FT_BEGIN_HEADER /* number of designs). */ /* */ /* num_namedstyles :: The number of named styles; only meaningful for */ - /* GX which allows certain design coordinates to */ + /* GX that allows certain design coordinates to */ /* have a string ID (in the `name' table) */ /* associated with them. The font can tell the */ /* user that, for example, Weight=1.5 is `Bold'. */ /* */ - /* axis :: A table of axis descriptors. */ + /* axis :: An axis descriptor table. */ /* GX fonts contain slightly more data than MM. */ + /* Memory management of this pointer is done */ + /* internally by FreeType. */ /* */ - /* namedstyles :: A table of named styles. */ + /* namedstyle :: A named style table. */ /* Only meaningful with GX. */ + /* Memory management of this pointer is done */ + /* internally by FreeType. */ /* */ typedef struct FT_MM_Var_ { @@ -218,9 +222,6 @@ FT_BEGIN_HEADER } FT_MM_Var; - /* */ - - /*************************************************************************/ /* */ /* <Function> */ @@ -258,8 +259,8 @@ FT_BEGIN_HEADER /* */ /* <Output> */ /* amaster :: The Multiple Masters/GX var descriptor. */ - /* Allocates a data structure, which the user must free */ - /* (a single call to FT_FREE will do it). */ + /* Allocates a data structure, which the user must */ + /* deallocate with `free' after use. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -284,8 +285,10 @@ FT_BEGIN_HEADER /* face :: A handle to the source face. */ /* */ /* <Input> */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ + /* num_coords :: The number of available design coordinates. If it */ + /* is larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use default values for the remaining axes. */ /* */ /* coords :: An array of design coordinates. */ /* */ @@ -311,8 +314,10 @@ FT_BEGIN_HEADER /* face :: A handle to the source face. */ /* */ /* <Input> */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ + /* num_coords :: The number of available design coordinates. If it */ + /* is larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use default values for the remaining axes. */ /* */ /* coords :: An array of design coordinates. */ /* */ @@ -338,8 +343,10 @@ FT_BEGIN_HEADER /* face :: A handle to the source face. */ /* */ /* <Input> */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ + /* num_coords :: The number of available design coordinates. If it */ + /* is larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use default values for the remaining axes. */ /* */ /* coords :: The design coordinates array (each element must be */ /* between 0 and 1.0). */ @@ -366,13 +373,12 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); - /* */ FT_END_HEADER -#endif /* __FTMM_H__ */ +#endif /* FTMM_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftmodapi.h b/drivers/freetype/include/freetype/ftmodapi.h index 8abffb558f..b4d2758efa 100644 --- a/drivers/freetype/freetype/include/freetype/ftmodapi.h +++ b/drivers/freetype/include/freetype/ftmodapi.h @@ -4,7 +4,7 @@ /* */ /* FreeType modules public interface (specification). */ /* */ -/* Copyright 1996-2003, 2006, 2008-2010, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMODAPI_H__ -#define __FTMODAPI_H__ +#ifndef FTMODAPI_H_ +#define FTMODAPI_H_ #include <ft2build.h> @@ -63,7 +63,7 @@ FT_BEGIN_HEADER /* psaux */ /* pshinter */ /* psnames */ - /* raster1, raster5 */ + /* raster1 */ /* sfnt */ /* smooth, smooth-lcd, smooth-lcdv */ /* truetype */ @@ -75,6 +75,33 @@ FT_BEGIN_HEADER /* */ /* Note that the FreeType Cache sub-system is not a FreeType module. */ /* */ + /* <Order> */ + /* FT_Module */ + /* FT_Module_Constructor */ + /* FT_Module_Destructor */ + /* FT_Module_Requester */ + /* FT_Module_Class */ + /* */ + /* FT_Add_Module */ + /* FT_Get_Module */ + /* FT_Remove_Module */ + /* FT_Add_Default_Modules */ + /* */ + /* FT_Property_Set */ + /* FT_Property_Get */ + /* */ + /* FT_New_Library */ + /* FT_Done_Library */ + /* FT_Reference_Library */ + /* */ + /* FT_Renderer */ + /* FT_Renderer_Class */ + /* */ + /* FT_Get_Renderer */ + /* FT_Set_Renderer */ + /* */ + /* FT_Set_Debug_Hook */ + /* */ /*************************************************************************/ @@ -84,12 +111,14 @@ FT_BEGIN_HEADER #define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ #define FT_MODULE_STYLER 8 /* this module is a styler */ -#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ /* scalable fonts */ -#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ /* support vector outlines */ -#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ /* own hinter */ +#define FT_MODULE_DRIVER_HINTS_LIGHTLY 0x800 /* the driver's hinter */ + /* produces LIGHT hints */ /* deprecated values */ @@ -98,9 +127,10 @@ FT_BEGIN_HEADER #define ft_module_hinter FT_MODULE_HINTER #define ft_module_styler FT_MODULE_STYLER -#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE -#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES -#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER +#define ft_module_driver_hints_lightly FT_MODULE_DRIVER_HINTS_LIGHTLY typedef FT_Pointer FT_Module_Interface; @@ -298,7 +328,7 @@ FT_BEGIN_HEADER * Note that only a few modules have properties. * * value :: - * A generic pointer to a variable or structure which gives the new + * A generic pointer to a variable or structure that gives the new * value of the property. The exact definition of `value' is * dependent on the property; see the `Synopsis' subsection of the * module's documentation. @@ -364,7 +394,7 @@ FT_BEGIN_HEADER * * @inout: * value :: - * A generic pointer to a variable or structure which gives the + * A generic pointer to a variable or structure that gives the * value of the property. The exact definition of `value' is * dependent on the property; see the `Synopsis' subsection of the * module's documentation. @@ -418,7 +448,7 @@ FT_BEGIN_HEADER /* @FT_Done_Library then only destroys a library if the counter is~1, */ /* otherwise it simply decrements the counter. */ /* */ - /* This function helps in managing life-cycles of structures which */ + /* This function helps in managing life-cycles of structures that */ /* reference @FT_Library objects. */ /* */ /* <Input> */ @@ -442,7 +472,9 @@ FT_BEGIN_HEADER /* <Description> */ /* This function is used to create a new FreeType library instance */ /* from a given memory object. It is thus possible to use libraries */ - /* with distinct memory allocators within the same program. */ + /* with distinct memory allocators within the same program. Note, */ + /* however, that the used @FT_Memory structure is expected to remain */ + /* valid for the life of the @FT_Library object. */ /* */ /* Normally, you would call this function (followed by a call to */ /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ @@ -491,7 +523,7 @@ FT_BEGIN_HEADER FT_EXPORT( FT_Error ) FT_Done_Library( FT_Library library ); -/* */ + /* */ typedef void (*FT_DebugHook_Func)( void* arg ); @@ -581,12 +613,7 @@ FT_BEGIN_HEADER * The library doesn't implement any kind of bytecode interpreter. * * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: - * The library implements a bytecode interpreter that doesn't - * support the patented operations of the TrueType virtual machine. - * - * Its main use is to load certain Asian fonts which position and - * scale glyph components with bytecode instructions. It produces - * bad output for most other fonts. + * Deprecated and removed. * * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: * The library implements a bytecode interpreter that covers @@ -629,13 +656,12 @@ FT_BEGIN_HEADER FT_EXPORT( FT_TrueTypeEngineType ) FT_Get_TrueType_Engine_Type( FT_Library library ); - /* */ FT_END_HEADER -#endif /* __FTMODAPI_H__ */ +#endif /* FTMODAPI_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftmoderr.h b/drivers/freetype/include/freetype/ftmoderr.h index 5a27db151a..2a7671c816 100644 --- a/drivers/freetype/freetype/include/freetype/ftmoderr.h +++ b/drivers/freetype/include/freetype/ftmoderr.h @@ -4,7 +4,7 @@ /* */ /* FreeType module error offsets (specification). */ /* */ -/* Copyright 2001-2005, 2010, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,7 +74,7 @@ /* with something like */ /* */ /* { */ - /* #undef __FTMODERR_H__ */ + /* #undef FTMODERR_H_ */ /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ /* #define FT_MODERR_START_LIST { */ /* #define FT_MODERR_END_LIST { 0, 0 } }; */ @@ -91,8 +91,8 @@ /*************************************************************************/ -#ifndef __FTMODERR_H__ -#define __FTMODERR_H__ +#ifndef FTMODERR_H_ +#define FTMODERR_H_ /*******************************************************************/ @@ -188,7 +188,7 @@ #undef FT_NEED_EXTERN_C -#endif /* __FTMODERR_H__ */ +#endif /* FTMODERR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftotval.h b/drivers/freetype/include/freetype/ftotval.h index 027f2e8865..3e6e18d8a6 100644 --- a/drivers/freetype/freetype/include/freetype/ftotval.h +++ b/drivers/freetype/include/freetype/ftotval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (specification). */ /* */ -/* Copyright 2004, 2005, 2006, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,8 +27,8 @@ /***************************************************************************/ -#ifndef __FTOTVAL_H__ -#define __FTOTVAL_H__ +#ifndef FTOTVAL_H_ +#define FTOTVAL_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -58,6 +58,12 @@ FT_BEGIN_HEADER /* This section contains the declaration of functions to validate */ /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ /* */ + /* <Order> */ + /* FT_OpenType_Validate */ + /* FT_OpenType_Free */ + /* */ + /* FT_VALIDATE_OTXXX */ + /* */ /*************************************************************************/ @@ -100,14 +106,12 @@ FT_BEGIN_HEADER #define FT_VALIDATE_JSTF 0x1000 #define FT_VALIDATE_MATH 0x2000 -#define FT_VALIDATE_OT FT_VALIDATE_BASE | \ - FT_VALIDATE_GDEF | \ - FT_VALIDATE_GPOS | \ - FT_VALIDATE_GSUB | \ - FT_VALIDATE_JSTF | \ - FT_VALIDATE_MATH - - /* */ +#define FT_VALIDATE_OT ( FT_VALIDATE_BASE | \ + FT_VALIDATE_GDEF | \ + FT_VALIDATE_GPOS | \ + FT_VALIDATE_GSUB | \ + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH ) /********************************************************************** * @@ -116,7 +120,7 @@ FT_BEGIN_HEADER * * @description: * Validate various OpenType tables to assure that all offsets and - * indices are valid. The idea is that a higher-level library which + * indices are valid. The idea is that a higher-level library that * actually does the text layout can access those tables without * error checking (which can be quite time consuming). * @@ -125,7 +129,7 @@ FT_BEGIN_HEADER * A handle to the input face. * * validation_flags :: - * A bit field which specifies the tables to be validated. See + * A bit field that specifies the tables to be validated. See * @FT_VALIDATE_OTXXX for possible values. * * @output: @@ -165,8 +169,6 @@ FT_BEGIN_HEADER FT_Bytes *GSUB_table, FT_Bytes *JSTF_table ); - /* */ - /********************************************************************** * * @function: @@ -191,13 +193,12 @@ FT_BEGIN_HEADER FT_OpenType_Free( FT_Face face, FT_Bytes table ); - - /* */ + /* */ FT_END_HEADER -#endif /* __FTOTVAL_H__ */ +#endif /* FTOTVAL_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftoutln.h b/drivers/freetype/include/freetype/ftoutln.h index fd69f28292..6a6451207c 100644 --- a/drivers/freetype/freetype/include/freetype/ftoutln.h +++ b/drivers/freetype/include/freetype/ftoutln.h @@ -5,7 +5,7 @@ /* Support for the FT_Outline type used to store glyph shapes of */ /* most scalable font formats (specification). */ /* */ -/* Copyright 1996-2003, 2005-2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __FTOUTLN_H__ -#define __FTOUTLN_H__ +#ifndef FTOUTLN_H_ +#define FTOUTLN_H_ #include <ft2build.h> @@ -52,7 +52,6 @@ FT_BEGIN_HEADER /* */ /* <Order> */ /* FT_Outline */ - /* FT_OUTLINE_FLAGS */ /* FT_Outline_New */ /* FT_Outline_Done */ /* FT_Outline_Copy */ @@ -68,13 +67,17 @@ FT_BEGIN_HEADER /* */ /* FT_Outline_Get_Bitmap */ /* FT_Outline_Render */ - /* */ /* FT_Outline_Decompose */ /* FT_Outline_Funcs */ - /* FT_Outline_MoveTo_Func */ - /* FT_Outline_LineTo_Func */ - /* FT_Outline_ConicTo_Func */ - /* FT_Outline_CubicTo_Func */ + /* FT_Outline_MoveToFunc */ + /* FT_Outline_LineToFunc */ + /* FT_Outline_ConicToFunc */ + /* FT_Outline_CubicToFunc */ + /* */ + /* FT_Orientation */ + /* FT_Outline_Get_Orientation */ + /* */ + /* FT_OUTLINE_XXX */ /* */ /*************************************************************************/ @@ -97,7 +100,7 @@ FT_BEGIN_HEADER /* operations. */ /* */ /* <InOut> */ - /* user :: A typeless pointer which is passed to each */ + /* user :: A typeless pointer that is passed to each */ /* emitter during the decomposition. It can be */ /* used to store the state during the */ /* decomposition. */ @@ -105,6 +108,13 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* A contour that contains a single point only is represented by a */ + /* `move to' operation followed by `line to' to the same point. In */ + /* most cases, it is best to filter this out before using the */ + /* outline for stroking purposes (otherwise it would result in a */ + /* visible dot when round caps are used). */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Decompose( FT_Outline* outline, const FT_Outline_Funcs* func_interface, @@ -217,12 +227,12 @@ FT_BEGIN_HEADER /* the outline's points, including Bézier control points. Though it */ /* coincides with the exact bounding box for most glyphs, it can be */ /* slightly larger in some situations (like when rotating an outline */ - /* which contains Bézier outside arcs). */ + /* that contains Bézier outside arcs). */ /* */ /* Computing the control box is very fast, while getting the bounding */ /* box can take much more time as it needs to walk over all segments */ /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component which is dedicated to this single task. */ + /* `ftbbox' component, which is dedicated to this single task. */ /* */ /* <Input> */ /* outline :: A pointer to the source outline descriptor. */ @@ -344,10 +354,13 @@ FT_BEGIN_HEADER /* */ /* { */ /* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); */ - /* if ( face->slot->format == FT_GLYPH_FORMAT_OUTLINE ) */ - /* FT_Outline_Embolden( &face->slot->outline, strength ); */ + /* if ( face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) */ + /* FT_Outline_Embolden( &face->glyph->outline, strength ); */ /* } */ /* */ + /* To get meaningful results, font scaling values must be set with */ + /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Embolden( FT_Outline* outline, FT_Pos strength ); @@ -525,9 +538,11 @@ FT_BEGIN_HEADER * * @description: * This function analyzes a glyph outline and tries to compute its - * fill orientation (see @FT_Orientation). This is done by computing - * the direction of each global horizontal and/or vertical extrema - * within the outline. + * fill orientation (see @FT_Orientation). This is done by integrating + * the total area covered by the outline. The positive integral + * corresponds to the clockwise orientation and @FT_ORIENTATION_POSTSCRIPT + * is returned. The negative integral corresponds to the counter-clockwise + * orientation and @FT_ORIENTATION_TRUETYPE is returned. * * Note that this will return @FT_ORIENTATION_TRUETYPE for empty * outlines. @@ -543,13 +558,12 @@ FT_BEGIN_HEADER FT_EXPORT( FT_Orientation ) FT_Outline_Get_Orientation( FT_Outline* outline ); - /* */ FT_END_HEADER -#endif /* __FTOUTLN_H__ */ +#endif /* FTOUTLN_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftpfr.h b/drivers/freetype/include/freetype/ftpfr.h index 0b7b7d427c..2e1bff2f67 100644 --- a/drivers/freetype/freetype/include/freetype/ftpfr.h +++ b/drivers/freetype/include/freetype/ftpfr.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing PFR-specific data (specification only). */ /* */ -/* Copyright 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTPFR_H__ -#define __FTPFR_H__ +#ifndef FTPFR_H_ +#define FTPFR_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -161,12 +161,12 @@ FT_BEGIN_HEADER FT_UInt gindex, FT_Pos *aadvance ); - /* */ + /* */ FT_END_HEADER -#endif /* __FTPFR_H__ */ +#endif /* FTPFR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftrender.h b/drivers/freetype/include/freetype/ftrender.h index dd0229b815..9f7ed9e9d9 100644 --- a/drivers/freetype/freetype/include/freetype/ftrender.h +++ b/drivers/freetype/include/freetype/ftrender.h @@ -4,7 +4,7 @@ /* */ /* FreeType renderer modules public interface (specification). */ /* */ -/* Copyright 1996-2001, 2005, 2006, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTRENDER_H__ -#define __FTRENDER_H__ +#ifndef FTRENDER_H_ +#define FTRENDER_H_ #include <ft2build.h> @@ -212,13 +212,8 @@ FT_BEGIN_HEADER /* */ /* This doesn't change the current renderer for other formats. */ /* */ - /* Currently, only the B/W renderer, if compiled with */ - /* FT_RASTER_OPTION_ANTI_ALIASING (providing a 5-levels */ - /* anti-aliasing mode; this option must be set directly in */ - /* `ftraster.c' and is undefined by default) accepts a single tag */ - /* `pal5' to set its gray palette as a character string with */ - /* 5~elements. Consequently, the third and fourth argument are zero */ - /* normally. */ + /* Currently, no FreeType renderer module uses `parameters'; you */ + /* should thus always pass NULL as the value. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Renderer( FT_Library library, @@ -226,13 +221,12 @@ FT_BEGIN_HEADER FT_UInt num_params, FT_Parameter* parameters ); - /* */ FT_END_HEADER -#endif /* __FTRENDER_H__ */ +#endif /* FTRENDER_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftsizes.h b/drivers/freetype/include/freetype/ftsizes.h index 3e548cc39f..55e0d5ccfd 100644 --- a/drivers/freetype/freetype/include/freetype/ftsizes.h +++ b/drivers/freetype/include/freetype/ftsizes.h @@ -4,7 +4,7 @@ /* */ /* FreeType size objects management (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2006, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,8 +25,8 @@ /*************************************************************************/ -#ifndef __FTSIZES_H__ -#define __FTSIZES_H__ +#ifndef FTSIZES_H_ +#define FTSIZES_H_ #include <ft2build.h> @@ -129,7 +129,7 @@ FT_BEGIN_HEADER /* <Description> */ /* Even though it is possible to create several size objects for a */ /* given face (see @FT_New_Size for details), functions like */ - /* @FT_Load_Glyph or @FT_Load_Char only use the one which has been */ + /* @FT_Load_Glyph or @FT_Load_Char only use the one that has been */ /* activated last to determine the `current character pixel size'. */ /* */ /* This function can be used to `activate' a previously created size */ @@ -153,7 +153,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSIZES_H__ */ +#endif /* FTSIZES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftsnames.h b/drivers/freetype/include/freetype/ftsnames.h index 485e4e162e..a7b51c2cba 100644 --- a/drivers/freetype/freetype/include/freetype/ftsnames.h +++ b/drivers/freetype/include/freetype/ftsnames.h @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2009, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,8 +19,8 @@ /***************************************************************************/ -#ifndef __FT_SFNT_NAMES_H__ -#define __FT_SFNT_NAMES_H__ +#ifndef FTSNAMES_H_ +#define FTSNAMES_H_ #include <ft2build.h> @@ -169,7 +169,7 @@ FT_BEGIN_HEADER * A constant used as the tag of @FT_Parameter structures to make * FT_Open_Face() ignore preferred family subfamily names in `name' * table since OpenType version 1.4. For backwards compatibility with - * legacy systems which has 4-face-per-family restriction. + * legacy systems that have a 4-face-per-family restriction. * */ #define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) @@ -184,7 +184,7 @@ FT_BEGIN_HEADER * A constant used as the tag of @FT_Parameter structures to make * FT_Open_Face() ignore preferred subfamily names in `name' table since * OpenType version 1.4. For backwards compatibility with legacy - * systems which has 4-face-per-family restriction. + * systems that have a 4-face-per-family restriction. * */ #define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p', 's' ) @@ -194,7 +194,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FT_SFNT_NAMES_H__ */ +#endif /* FTSNAMES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftstroke.h b/drivers/freetype/include/freetype/ftstroke.h index a498e4a883..b3b9922dad 100644 --- a/drivers/freetype/freetype/include/freetype/ftstroke.h +++ b/drivers/freetype/include/freetype/ftstroke.h @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (specification). */ /* */ -/* Copyright 2002-2006, 2008, 2009, 2011-2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FT_STROKE_H__ -#define __FT_STROKE_H__ +#ifndef FTSTROKE_H_ +#define FTSTROKE_H_ #include <ft2build.h> #include FT_OUTLINE_H @@ -46,6 +46,38 @@ FT_BEGIN_HEADER * This can be useful to generate `bordered' glyph, i.e., glyphs * displayed with a coloured (and anti-aliased) border around their * shape. + * + * @order: + * FT_Stroker + * + * FT_Stroker_LineJoin + * FT_Stroker_LineCap + * FT_StrokerBorder + * + * FT_Outline_GetInsideBorder + * FT_Outline_GetOutsideBorder + * + * FT_Glyph_Stroke + * FT_Glyph_StrokeBorder + * + * FT_Stroker_New + * FT_Stroker_Set + * FT_Stroker_Rewind + * FT_Stroker_ParseOutline + * FT_Stroker_Done + * + * FT_Stroker_BeginSubPath + * FT_Stroker_EndSubPath + * + * FT_Stroker_LineTo + * FT_Stroker_ConicTo + * FT_Stroker_CubicTo + * + * FT_Stroker_GetBorderCounts + * FT_Stroker_ExportBorder + * FT_Stroker_GetCounts + * FT_Stroker_Export + * */ @@ -55,7 +87,7 @@ FT_BEGIN_HEADER * FT_Stroker * * @description: - * Opaque handler to a path stroker object. + * Opaque handle to a path stroker object. */ typedef struct FT_StrokerRec_* FT_Stroker; @@ -276,6 +308,8 @@ FT_BEGIN_HEADER * @note: * The radius is expressed in the same units as the outline * coordinates. + * + * This function calls @FT_Stroker_Rewind automatically. */ FT_EXPORT( void ) FT_Stroker_Set( FT_Stroker stroker, @@ -570,10 +604,10 @@ FT_BEGIN_HEADER * receive all new data. * * When an outline, or a sub-path, is `closed', the stroker generates - * two independent `border' outlines, named `left' and `right' + * two independent `border' outlines, named `left' and `right'. * * When the outline, or a sub-path, is `opened', the stroker merges - * the `border' outlines with caps. The `left' border receives all + * the `border' outlines with caps. The `left' border receives all * points, while the `right' border becomes empty. * * Use the function @FT_Stroker_Export instead if you want to @@ -736,11 +770,11 @@ FT_BEGIN_HEADER FT_Bool inside, FT_Bool destroy ); - /* */ + /* */ FT_END_HEADER -#endif /* __FT_STROKE_H__ */ +#endif /* FTSTROKE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftsynth.h b/drivers/freetype/include/freetype/ftsynth.h index 2074503cf6..fdfcb6912b 100644 --- a/drivers/freetype/freetype/include/freetype/ftsynth.h +++ b/drivers/freetype/include/freetype/ftsynth.h @@ -5,7 +5,7 @@ /* FreeType synthesizing code for emboldening and slanting */ /* (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2006, 2008, 2012 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -37,12 +37,12 @@ /* Main reason for not lifting the functions in this module to a */ /* `standard' API is that the used parameters for emboldening and */ /* slanting are not configurable. Consider the functions as a */ - /* code resource which should be copied into the application and */ + /* code resource that should be copied into the application and */ /* adapted to the particular needs. */ -#ifndef __FTSYNTH_H__ -#define __FTSYNTH_H__ +#ifndef FTSYNTH_H_ +#define FTSYNTH_H_ #include <ft2build.h> @@ -62,8 +62,10 @@ FT_BEGIN_HEADER /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ /* */ /* For emboldened outlines the height, width, and advance metrics are */ - /* increased by the strength of the emboldening. You can also call */ - /* @FT_Outline_Get_CBox to get precise values. */ + /* increased by the strength of the emboldening -- this even affects */ + /* mono-width fonts! */ + /* */ + /* You can also call @FT_Outline_Get_CBox to get precise values. */ FT_EXPORT( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); @@ -73,9 +75,10 @@ FT_BEGIN_HEADER /* */ + FT_END_HEADER -#endif /* __FTSYNTH_H__ */ +#endif /* FTSYNTH_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftsystem.h b/drivers/freetype/include/freetype/ftsystem.h index e07460c55d..a75f958022 100644 --- a/drivers/freetype/freetype/include/freetype/ftsystem.h +++ b/drivers/freetype/include/freetype/ftsystem.h @@ -4,7 +4,7 @@ /* */ /* FreeType low-level system interface definition (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSYSTEM_H__ -#define __FTSYSTEM_H__ +#ifndef FTSYSTEM_H_ +#define FTSYSTEM_H_ #include <ft2build.h> @@ -192,6 +192,10 @@ FT_BEGIN_HEADER * @description: * A handle to an input stream. * + * @also: + * See @FT_StreamRec for the publicly accessible fields of a given + * stream object. + * */ typedef struct FT_StreamRec_* FT_Stream; @@ -285,6 +289,11 @@ FT_BEGIN_HEADER * size :: * The stream size in bytes. * + * In case of compressed streams where the size is unknown before + * actually doing the decompression, the value is set to 0x7FFFFFFF. + * (Note that this size value can occur for normal streams also; it is + * thus just a hint.) + * * pos :: * The current position within the stream. * @@ -335,13 +344,12 @@ FT_BEGIN_HEADER } FT_StreamRec; - /* */ FT_END_HEADER -#endif /* __FTSYSTEM_H__ */ +#endif /* FTSYSTEM_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/fttrigon.h b/drivers/freetype/include/freetype/fttrigon.h index 65143cb8c8..f789b524cb 100644 --- a/drivers/freetype/freetype/include/freetype/fttrigon.h +++ b/drivers/freetype/include/freetype/fttrigon.h @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (specification). */ /* */ -/* Copyright 2001, 2003, 2005, 2007, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTTRIGON_H__ -#define __FTTRIGON_H__ +#ifndef FTTRIGON_H_ +#define FTTRIGON_H_ #include FT_FREETYPE_H @@ -225,8 +225,8 @@ FT_BEGIN_HEADER * * @description: * Return the unit vector corresponding to a given angle. After the - * call, the value of `vec.x' will be `sin(angle)', and the value of - * `vec.y' will be `cos(angle)'. + * call, the value of `vec.x' will be `cos(angle)', and the value of + * `vec.y' will be `sin(angle)'. * * This function is useful to retrieve both the sinus and cosinus of a * given angle quickly. @@ -237,7 +237,7 @@ FT_BEGIN_HEADER * * @input: * angle :: - * The address of angle. + * The input angle. * */ FT_EXPORT( void ) @@ -259,7 +259,7 @@ FT_BEGIN_HEADER * * @input: * angle :: - * The address of angle. + * The input angle. * */ FT_EXPORT( void ) @@ -344,7 +344,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTTRIGON_H__ */ +#endif /* FTTRIGON_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/ftttdrv.h b/drivers/freetype/include/freetype/ftttdrv.h new file mode 100644 index 0000000000..0d868bc259 --- /dev/null +++ b/drivers/freetype/include/freetype/ftttdrv.h @@ -0,0 +1,327 @@ +/***************************************************************************/ +/* */ +/* ftttdrv.h */ +/* */ +/* FreeType API for controlling the TrueType driver */ +/* (specification only). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef FTTTDRV_H_ +#define FTTTDRV_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * tt_driver + * + * @title: + * The TrueType driver + * + * @abstract: + * Controlling the TrueType driver module. + * + * @description: + * While FreeType's TrueType driver doesn't expose API functions by + * itself, it is possible to control its behaviour with @FT_Property_Set + * and @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * The TrueType driver's module name is `truetype'. + * + * We start with a list of definitions, kindly provided by Greg + * Hitchcock. + * + * _Bi-Level_ _Rendering_ + * + * Monochromatic rendering, exclusively used in the early days of + * TrueType by both Apple and Microsoft. Microsoft's GDI interface + * supported hinting of the right-side bearing point, such that the + * advance width could be non-linear. Most often this was done to + * achieve some level of glyph symmetry. To enable reasonable + * performance (e.g., not having to run hinting on all glyphs just to + * get the widths) there was a bit in the head table indicating if the + * side bearing was hinted, and additional tables, `hdmx' and `LTSH', to + * cache hinting widths across multiple sizes and device aspect ratios. + * + * _Font_ _Smoothing_ + * + * Microsoft's GDI implementation of anti-aliasing. Not traditional + * anti-aliasing as the outlines were hinted before the sampling. The + * widths matched the bi-level rendering. + * + * _ClearType_ _Rendering_ + * + * Technique that uses physical subpixels to improve rendering on LCD + * (and other) displays. Because of the higher resolution, many methods + * of improving symmetry in glyphs through hinting the right-side + * bearing were no longer necessary. This lead to what GDI calls + * `natural widths' ClearType, see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec21. Since hinting + * has extra resolution, most non-linearity went away, but it is still + * possible for hints to change the advance widths in this mode. + * + * _ClearType_ _Compatible_ _Widths_ + * + * One of the earliest challenges with ClearType was allowing the + * implementation in GDI to be selected without requiring all UI and + * documents to reflow. To address this, a compatible method of + * rendering ClearType was added where the font hints are executed once + * to determine the width in bi-level rendering, and then re-run in + * ClearType, with the difference in widths being absorbed in the font + * hints for ClearType (mostly in the white space of hints); see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec20. Somewhat by + * definition, compatible width ClearType allows for non-linear widths, + * but only when the bi-level version has non-linear widths. + * + * _ClearType_ _Subpixel_ _Positioning_ + * + * One of the nice benefits of ClearType is the ability to more crisply + * display fractional widths; unfortunately, the GDI model of integer + * bitmaps did not support this. However, the WPF and Direct Write + * frameworks do support fractional widths. DWrite calls this `natural + * mode', not to be confused with GDI's `natural widths'. Subpixel + * positioning, in the current implementation of Direct Write, + * unfortunately does not support hinted advance widths, see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec22. Note that the + * TrueType interpreter fully allows the advance width to be adjusted in + * this mode, just the DWrite client will ignore those changes. + * + * _ClearType_ _Backwards_ _Compatibility_ + * + * This is a set of exceptions made in the TrueType interpreter to + * minimize hinting techniques that were problematic with the extra + * resolution of ClearType; see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec1 and + * http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx. + * This technique is not to be confused with ClearType compatible + * widths. ClearType backwards compatibility has no direct impact on + * changing advance widths, but there might be an indirect impact on + * disabling some deltas. This could be worked around in backwards + * compatibility mode. + * + * _Native_ _ClearType_ _Mode_ + * + * (Not to be confused with `natural widths'.) This mode removes all + * the exceptions in the TrueType interpreter when running with + * ClearType. Any issues on widths would still apply, though. + * + */ + + + /************************************************************************** + * + * @property: + * interpreter-version + * + * @description: + + * Currently, three versions are available, two representing the + * bytecode interpreter with subpixel hinting support (old `Infinality' + * code and new stripped-down and higher performance `minimal' code) and + * one without, respectively. The default is subpixel support if + * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel support + * otherwise (since it isn't available then). + * + * If subpixel hinting is on, many TrueType bytecode instructions behave + * differently compared to B/W or grayscale rendering (except if `native + * ClearType' is selected by the font). Microsoft's main idea is to + * render at a much increased horizontal resolution, then sampling down + * the created output to subpixel precision. However, many older fonts + * are not suited to this and must be specially taken care of by + * applying (hardcoded) tweaks in Microsoft's interpreter. + * + * Details on subpixel hinting and some of the necessary tweaks can be + * found in Greg Hitchcock's whitepaper at + * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. + * Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2, + * or 6x5 supersampling) like discussed in the paper. Depending on the + * chosen interpreter, it simply ignores instructions on vertical stems + * to arrive at very similar results. + * + * The following example code demonstrates how to deactivate subpixel + * hinting (omitting the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_35; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "truetype", + * "interpreter-version", + * &interpreter_version ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + + /************************************************************************** + * + * @enum: + * TT_INTERPRETER_VERSION_XXX + * + * @description: + * A list of constants used for the @interpreter-version property to + * select the hinting engine for Truetype fonts. + * + * The numeric value in the constant names represents the version + * number as returned by the `GETINFO' bytecode instruction. + * + * @values: + * TT_INTERPRETER_VERSION_35 :: + * Version~35 corresponds to MS rasterizer v.1.7 as used e.g. in + * Windows~98; only grayscale and B/W rasterizing is supported. + * + * TT_INTERPRETER_VERSION_38 :: + * Version~38 corresponds to MS rasterizer v.1.9; it is roughly + * equivalent to the hinting provided by DirectWrite ClearType (as can + * be found, for example, in the Internet Explorer~9 running on + * Windows~7). It is used in FreeType to select the `Infinality' + * subpixel hinting code. The code may be removed in a future + * version. + * + * TT_INTERPRETER_VERSION_40 :: + * Version~40 corresponds to MS rasterizer v.2.1; it is roughly + * equivalent to the hinting provided by DirectWrite ClearType (as can + * be found, for example, in Microsoft's Edge Browser on Windows~10). + * It is used in FreeType to select the `minimal' subpixel hinting + * code, a stripped-down and higher performance version of the + * `Infinality' code. + * + * @note: + * This property controls the behaviour of the bytecode interpreter + * and thus how outlines get hinted. It does *not* control how glyph + * get rasterized! In particular, it does not control subpixel color + * filtering. + * + * If FreeType has not been compiled with the configuration option + * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 or~40 causes + * an `FT_Err_Unimplemented_Feature' error. + * + * Depending on the graphics framework, Microsoft uses different + * bytecode and rendering engines. As a consequence, the version + * numbers returned by a call to the `GETINFO' bytecode instruction are + * more convoluted than desired. + * + * Here are two tables that try to shed some light on the possible + * values for the MS rasterizer engine, together with the additional + * features introduced by it. + * + * { + * GETINFO framework version feature + * ------------------------------------------------------------------- + * 3 GDI (Win 3.1), v1.0 16-bit, first version + * TrueImage + * 33 GDI (Win NT 3.1), v1.5 32-bit + * HP Laserjet + * 34 GDI (Win 95) v1.6 font smoothing, + * new SCANTYPE opcode + * 35 GDI (Win 98/2000) v1.7 (UN)SCALED_COMPONENT_OFFSET + * bits in composite glyphs + * 36 MGDI (Win CE 2) v1.6+ classic ClearType + * 37 GDI (XP and later), v1.8 ClearType + * GDI+ old (before Vista) + * 38 GDI+ old (Vista, Win 7), v1.9 subpixel ClearType, + * WPF Y-direction ClearType, + * additional error checking + * 39 DWrite (before Win 8) v2.0 subpixel ClearType flags + * in GETINFO opcode, + * bug fixes + * 40 GDI+ (after Win 7), v2.1 Y-direction ClearType flag + * DWrite (Win 8) in GETINFO opcode, + * Gray ClearType + * } + * + * The `version' field gives a rough orientation only, since some + * applications provided certain features much earlier (as an example, + * Microsoft Reader used subpixel and Y-direction ClearType already in + * Windows 2000). Similarly, updates to a given framework might include + * improved hinting support. + * + * { + * version sampling rendering comment + * x y x y + * -------------------------------------------------------------- + * v1.0 normal normal B/W B/W bi-level + * v1.6 high high gray gray grayscale + * v1.8 high normal color-filter B/W (GDI) ClearType + * v1.9 high high color-filter gray Color ClearType + * v2.1 high normal gray B/W Gray ClearType + * v2.1 high high gray gray Gray ClearType + * } + * + * Color and Gray ClearType are the two available variants of + * `Y-direction ClearType', meaning grayscale rasterization along the + * Y-direction; the name used in the TrueType specification for this + * feature is `symmetric smoothing'. `Classic ClearType' is the + * original algorithm used before introducing a modified version in + * Win~XP. Another name for v1.6's grayscale rendering is `font + * smoothing', and `Color ClearType' is sometimes also called `DWrite + * ClearType'. To differentiate between today's Color ClearType and the + * earlier ClearType variant with B/W rendering along the vertical axis, + * the latter is sometimes called `GDI ClearType'. + * + * `Normal' and `high' sampling describe the (virtual) resolution to + * access the rasterized outline after the hinting process. `Normal' + * means 1 sample per grid line (i.e., B/W). In the current Microsoft + * implementation, `high' means an extra virtual resolution of 16x16 (or + * 16x1) grid lines per pixel for bytecode instructions like `MIRP'. + * After hinting, these 16 grid lines are mapped to 6x5 (or 6x1) grid + * lines for color filtering if Color ClearType is activated. + * + * Note that `Gray ClearType' is essentially the same as v1.6's + * grayscale rendering. However, the GETINFO instruction handles it + * differently: v1.6 returns bit~12 (hinting for grayscale), while v2.1 + * returns bits~13 (hinting for ClearType), 18 (symmetrical smoothing), + * and~19 (Gray ClearType). Also, this mode respects bits 2 and~3 for + * the version~1 gasp table exclusively (like Color ClearType), while + * v1.6 only respects the values of version~0 (bits 0 and~1). + * + * Keep in mind that the features of the above interpreter versions + * might not map exactly to FreeType features or behavior because it is + * a fundamentally different library with different internals. + * + */ +#define TT_INTERPRETER_VERSION_35 35 +#define TT_INTERPRETER_VERSION_38 38 +#define TT_INTERPRETER_VERSION_40 40 + + /* */ + + +FT_END_HEADER + + +#endif /* FTTTDRV_H_ */ + + +/* END */ diff --git a/drivers/freetype/freetype/include/freetype/fttypes.h b/drivers/freetype/include/freetype/fttypes.h index 027e59ce11..2673e79c3c 100644 --- a/drivers/freetype/freetype/include/freetype/fttypes.h +++ b/drivers/freetype/include/freetype/fttypes.h @@ -4,7 +4,7 @@ /* */ /* FreeType simple types definitions (specification only). */ /* */ -/* Copyright 1996-2002, 2004, 2006-2009, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTTYPES_H__ -#define __FTTYPES_H__ +#ifndef FTTYPES_H_ +#define FTTYPES_H_ #include <ft2build.h> @@ -57,6 +57,8 @@ FT_BEGIN_HEADER /* FT_UInt16 */ /* FT_Int32 */ /* FT_UInt32 */ + /* FT_Int64 */ + /* FT_UInt64 */ /* FT_Short */ /* FT_UShort */ /* FT_Long */ @@ -78,7 +80,9 @@ FT_BEGIN_HEADER /* FT_F2Dot14 */ /* FT_UnitVector */ /* FT_F26Dot6 */ + /* FT_Data */ /* */ + /* FT_MAKE_TAG */ /* */ /* FT_Generic */ /* FT_Generic_Finalizer */ @@ -418,7 +422,7 @@ FT_BEGIN_HEADER /* details of usage. */ /* */ /* <Input> */ - /* The address of the FreeType object which is under finalization. */ + /* The address of the FreeType object that is under finalization. */ /* Its client data is accessed through its `generic' field. */ /* */ typedef void (*FT_Generic_Finalizer)(void* object); @@ -466,8 +470,8 @@ FT_BEGIN_HEADER /* FT_MAKE_TAG */ /* */ /* <Description> */ - /* This macro converts four-letter tags which are used to label */ - /* TrueType tables into an unsigned long to be used within FreeType. */ + /* This macro converts four-letter tags that are used to label */ + /* TrueType tables into an unsigned long, to be used within FreeType. */ /* */ /* <Note> */ /* The produced values *must* be 32-bit integers. Don't redefine */ @@ -567,9 +571,9 @@ FT_BEGIN_HEADER } FT_ListRec; - /* */ + #define FT_IS_EMPTY( list ) ( (list).head == 0 ) #define FT_BOOL( x ) ( (FT_Bool)( x ) ) @@ -592,7 +596,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTTYPES_H__ */ +#endif /* FTTYPES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ftwinfnt.h b/drivers/freetype/include/freetype/ftwinfnt.h index ea33353536..a1a715baa1 100644 --- a/drivers/freetype/freetype/include/freetype/ftwinfnt.h +++ b/drivers/freetype/include/freetype/ftwinfnt.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows fnt-specific data. */ /* */ -/* Copyright 2003, 2004, 2008 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTWINFNT_H__ -#define __FTWINFNT_H__ +#ifndef FTWINFNT_H_ +#define FTWINFNT_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -58,9 +58,10 @@ FT_BEGIN_HEADER * @description: * A list of valid values for the `charset' byte in * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX - * encodings (except for cp1361) can be found at ftp://ftp.unicode.org - * in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory. cp1361 is - * roughly a superset of MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. + * encodings (except for cp1361) can be found at + * ftp://ftp.unicode.org/Public in the MAPPINGS/VENDORS/MICSFT/WINDOWS + * subdirectory. cp1361 is roughly a superset of + * MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. * * @values: * FT_WinFNT_ID_DEFAULT :: @@ -94,7 +95,7 @@ FT_BEGIN_HEADER * second default codepage that most international versions of * Windows have. It is one of the OEM codepages from * - * http://www.microsoft.com/globaldev/reference/cphome.mspx, + * https://msdn.microsoft.com/en-us/goglobal/bb964655, * * and is used for the `DOS boxes', to support legacy applications. * A German Windows version for example usually uses ANSI codepage @@ -258,12 +259,12 @@ FT_BEGIN_HEADER FT_Get_WinFNT_Header( FT_Face face, FT_WinFNT_HeaderRec *aheader ); - /* */ + FT_END_HEADER -#endif /* __FTWINFNT_H__ */ +#endif /* FTWINFNT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/autohint.h b/drivers/freetype/include/freetype/internal/autohint.h index 545de938c2..7ef82b8f3c 100644 --- a/drivers/freetype/freetype/include/freetype/internal/autohint.h +++ b/drivers/freetype/include/freetype/internal/autohint.h @@ -4,7 +4,7 @@ /* */ /* High-level `autohint' module-specific interface (specification). */ /* */ -/* Copyright 1996-2002, 2007, 2009, 2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +24,8 @@ /*************************************************************************/ -#ifndef __AUTOHINT_H__ -#define __AUTOHINT_H__ +#ifndef AUTOHINT_H_ +#define AUTOHINT_H_ /*************************************************************************/ @@ -238,7 +238,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AUTOHINT_H__ */ +#endif /* AUTOHINT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftcalc.h b/drivers/freetype/include/freetype/internal/ftcalc.h index faac3a3867..8a884f680a 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftcalc.h +++ b/drivers/freetype/include/freetype/internal/ftcalc.h @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (specification). */ /* */ -/* Copyright 1996-2006, 2008, 2009, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCALC_H__ -#define __FTCALC_H__ +#ifndef FTCALC_H_ +#define FTCALC_H_ #include <ft2build.h> @@ -29,31 +29,222 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* <Function> */ - /* FT_FixedSqrt */ - /* */ - /* <Description> */ - /* Computes the square root of a 16.16 fixed-point value. */ - /* */ - /* <Input> */ - /* x :: The value to compute the root for. */ - /* */ - /* <Return> */ - /* The result of `sqrt(x)'. */ - /* */ - /* <Note> */ - /* This function is not very fast. */ - /* */ - FT_BASE( FT_Int32 ) - FT_SqrtFixed( FT_Int32 x ); - - - /*************************************************************************/ - /* */ /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ /* */ /*************************************************************************/ +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + /* Provide assembler fragments for performance-critical functions. */ + /* These must be defined `static __inline__' with GCC. */ + +#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ + +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 t, t2; + + + __asm + { + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ + mov a, t, asr #31 /* a = (hi >> 31) */ + add a, a, #0x8000 /* a += 0x8000 */ + adds t2, t2, a /* t2 += a */ + adc t, t, #0 /* t += carry */ + mov a, t2, lsr #16 /* a = t2 >> 16 */ + orr a, a, t, lsl #16 /* a |= t << 16 */ + } + return a; + } + +#endif /* __CC_ARM || __ARMCC__ */ + + +#ifdef __GNUC__ + +#if defined( __arm__ ) && \ + ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \ + !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 t, t2; + + + __asm__ __volatile__ ( + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ +#if defined( __clang__ ) && defined( __thumb2__ ) + "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ +#else + "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ +#endif + "adds %1, %1, %0\n\t" /* %1 += %0 */ + "adc %2, %2, #0\n\t" /* %2 += carry */ + "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ + "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ + : "=r"(a), "=&r"(t2), "=&r"(t) + : "r"(a), "r"(b) + : "cc" ); + return a; + } + +#endif /* __arm__ && */ + /* ( __thumb2__ || !__thumb__ ) && */ + /* !( __CC_ARM || __ARMCC__ ) */ + + +#if defined( __i386__ ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 result; + + + __asm__ __volatile__ ( + "imul %%edx\n" + "movl %%edx, %%ecx\n" + "sarl $31, %%ecx\n" + "addl $0x8000, %%ecx\n" + "addl %%ecx, %%eax\n" + "adcl $0, %%edx\n" + "shrl $16, %%eax\n" + "shll $16, %%edx\n" + "addl %%edx, %%eax\n" + : "=a"(result), "=d"(b) + : "a"(a), "d"(b) + : "%ecx", "cc" ); + return result; + } + +#endif /* i386 */ + +#endif /* __GNUC__ */ + + +#ifdef _MSC_VER /* Visual C++ */ + +#ifdef _M_IX86 + +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 result; + + __asm + { + mov eax, a + mov edx, b + imul edx + mov ecx, edx + sar ecx, 31 + add ecx, 8000h + add eax, ecx + adc edx, 0 + shr eax, 16 + shl edx, 16 + add eax, edx + mov result, eax + } + return result; + } + +#endif /* _M_IX86 */ + +#endif /* _MSC_VER */ + + +#if defined( __GNUC__ ) && defined( __x86_64__ ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64 + + static __inline__ FT_Int32 + FT_MulFix_x86_64( FT_Int32 a, + FT_Int32 b ) + { + /* Temporarily disable the warning that C90 doesn't support */ + /* `long long'. */ +#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlong-long" +#endif + +#if 1 + /* Technically not an assembly fragment, but GCC does a really good */ + /* job at inlining it and generating good machine code for it. */ + long long ret, tmp; + + + ret = (long long)a * b; + tmp = ret >> 63; + ret += 0x8000 + tmp; + + return (FT_Int32)( ret >> 16 ); +#else + + /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */ + /* code from the lines below. The main issue is that `wide_a' is not */ + /* properly initialized by sign-extending `a'. Instead, the generated */ + /* machine code assumes that the register that contains `a' on input */ + /* can be used directly as a 64-bit value, which is wrong most of the */ + /* time. */ + long long wide_a = (long long)a; + long long wide_b = (long long)b; + long long result; + + + __asm__ __volatile__ ( + "imul %2, %1\n" + "mov %1, %0\n" + "sar $63, %0\n" + "lea 0x8000(%1, %0), %0\n" + "sar $16, %0\n" + : "=&r"(result), "=&r"(wide_a) + : "r"(wide_b) + : "cc" ); + + return (FT_Int32)result; +#endif + +#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 ) +#pragma GCC diagnostic pop +#endif + } + +#endif /* __GNUC__ && __x86_64__ */ + +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + + +#ifdef FT_CONFIG_OPTION_INLINE_MULFIX +#ifdef FT_MULFIX_ASSEMBLER +#define FT_MulFix( a, b ) FT_MULFIX_ASSEMBLER( (FT_Int32)(a), (FT_Int32)(b) ) +#endif +#endif + /*************************************************************************/ /* */ @@ -109,6 +300,18 @@ FT_BEGIN_HEADER /* + * This function normalizes a vector and returns its original length. + * The normalized vector is a 16.16 fixed-point unit vector with length + * close to 0x10000. The accuracy of the returned length is limited to + * 16 bits also. The function utilizes quick inverse square root + * approximation without divisions and square roots relying on Newton's + * iterations instead. + */ + FT_BASE( FT_UInt32 ) + FT_Vector_NormLen( FT_Vector* vector ); + + + /* * Return -1, 0, or +1, depending on the orientation of a given corner. * We use the Cartesian coordinate system, with positive vertical values * going upwards. The function returns +1 if the corner turns to the @@ -120,10 +323,11 @@ FT_BEGIN_HEADER FT_Pos out_x, FT_Pos out_y ); + /* * Return TRUE if a corner is flat or nearly flat. This is equivalent to - * saying that the angle difference between the `in' and `out' vectors is - * very small. + * saying that the corner point is close to its neighbors, or inside an + * ellipse defined by the neighbor focal points to be more precise. */ FT_BASE( FT_Int ) ft_corner_is_flat( FT_Pos in_x, @@ -135,9 +339,31 @@ FT_BEGIN_HEADER /* * Return the most significant bit index. */ + +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER +#if defined( __GNUC__ ) && \ + ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) ) + +#if FT_SIZEOF_INT == 4 + +#define FT_MSB( x ) ( 31 - __builtin_clz( x ) ) + +#elif FT_SIZEOF_LONG == 4 + +#define FT_MSB( x ) ( 31 - __builtin_clzl( x ) ) + +#endif + +#endif /* __GNUC__ */ +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + +#ifndef FT_MSB + FT_BASE( FT_Int ) FT_MSB( FT_UInt32 z ); +#endif + /* * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses @@ -148,6 +374,31 @@ FT_BEGIN_HEADER FT_Fixed y ); +#if 0 + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_SqrtFixed */ + /* */ + /* <Description> */ + /* Computes the square root of a 16.16 fixed-point value. */ + /* */ + /* <Input> */ + /* x :: The value to compute the root for. */ + /* */ + /* <Return> */ + /* The result of `sqrt(x)'. */ + /* */ + /* <Note> */ + /* This function is not very fast. */ + /* */ + FT_BASE( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ); + +#endif /* 0 */ + + #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) @@ -161,7 +412,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCALC_H__ */ +#endif /* FTCALC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftdebug.h b/drivers/freetype/include/freetype/internal/ftdebug.h index 58a3916d7e..d110457157 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftdebug.h +++ b/drivers/freetype/include/freetype/internal/ftdebug.h @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (specification). */ /* */ -/* Copyright 1996-2002, 2004, 2006-2009, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +21,8 @@ /***************************************************************************/ -#ifndef __FTDEBUG_H__ -#define __FTDEBUG_H__ +#ifndef FTDEBUG_H_ +#define FTDEBUG_H_ #include <ft2build.h> @@ -140,7 +140,7 @@ FT_BEGIN_HEADER /* This function may be useful if you want to control FreeType 2's */ /* debug level in your application. */ /* */ - FT_BASE( const char * ) + FT_BASE( const char* ) FT_Trace_Get_Name( FT_Int idx ); @@ -249,7 +249,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTDEBUG_H__ */ +#endif /* FTDEBUG_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftdriver.h b/drivers/freetype/include/freetype/internal/ftdriver.h index 940218e62d..3e1e66e979 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftdriver.h +++ b/drivers/freetype/include/freetype/internal/ftdriver.h @@ -4,7 +4,7 @@ /* */ /* FreeType font driver interface (specification). */ /* */ -/* Copyright 1996-2003, 2006, 2008, 2011-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTDRIVER_H__ -#define __FTDRIVER_H__ +#ifndef FTDRIVER_H_ +#define FTDRIVER_H_ #include <ft2build.h> @@ -213,7 +213,7 @@ FT_BEGIN_HEADER /* And when it is no longer needed a `destroy' function needs to be */ /* called to release that allocation. */ /* */ - /* `fcinit.c' (ft_create_default_module_classes) already contains a */ + /* `ftinit.c' (ft_create_default_module_classes) already contains a */ /* mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -403,7 +403,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTDRIVER_H__ */ +#endif /* FTDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftgloadr.h b/drivers/freetype/include/freetype/internal/ftgloadr.h index ce4dc6c9cc..bebf5dbba2 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftgloadr.h +++ b/drivers/freetype/include/freetype/internal/ftgloadr.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (specification). */ /* */ -/* Copyright 2002, 2003, 2005, 2006 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTGLOADR_H__ -#define __FTGLOADR_H__ +#ifndef FTGLOADR_H_ +#define FTGLOADR_H_ #include <ft2build.h> @@ -36,24 +36,6 @@ FT_BEGIN_HEADER /* The glyph loader is an internal object used to load several glyphs */ /* together (for example, in the case of composites). */ /* */ - /* <Note> */ - /* The glyph loader implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - typedef struct FT_GlyphLoaderRec_* FT_GlyphLoader ; - - -#if 0 /* moved to freetype.h in version 2.2 */ -#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 -#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 -#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 -#define FT_SUBGLYPH_FLAG_SCALE 8 -#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 -#define FT_SUBGLYPH_FLAG_2X2 0x80 -#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 -#endif - - typedef struct FT_SubGlyphRec_ { FT_Int index; @@ -89,7 +71,7 @@ FT_BEGIN_HEADER void* other; /* for possible future extension? */ - } FT_GlyphLoaderRec; + } FT_GlyphLoaderRec, *FT_GlyphLoader; /* create new empty glyph loader */ @@ -121,21 +103,25 @@ FT_BEGIN_HEADER FT_UInt n_contours ); -#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ - ( (_count) == 0 || ((_loader)->base.outline.n_points + \ - (_loader)->current.outline.n_points + \ - (unsigned long)(_count)) <= (_loader)->max_points ) +#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ + ( (_count) == 0 || \ + ( (FT_UInt)(_loader)->base.outline.n_points + \ + (FT_UInt)(_loader)->current.outline.n_points + \ + (FT_UInt)(_count) ) <= (_loader)->max_points ) -#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ - ( (_count) == 0 || ((_loader)->base.outline.n_contours + \ - (_loader)->current.outline.n_contours + \ - (unsigned long)(_count)) <= (_loader)->max_contours ) +#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ + ( (_count) == 0 || \ + ( (FT_UInt)(_loader)->base.outline.n_contours + \ + (FT_UInt)(_loader)->current.outline.n_contours + \ + (FT_UInt)(_count) ) <= (_loader)->max_contours ) -#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours ) \ - ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ - FT_GLYPHLOADER_CHECK_C( _loader, _contours ) ) \ - ? 0 \ - : FT_GlyphLoader_CheckPoints( (_loader), (_points), (_contours) ) ) +#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points, _contours ) \ + ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ + FT_GLYPHLOADER_CHECK_C( _loader, _contours ) ) \ + ? 0 \ + : FT_GlyphLoader_CheckPoints( (_loader), \ + (FT_UInt)(_points), \ + (FT_UInt)(_contours) ) ) /* check that there is enough space to add `n_subs' sub-glyphs to */ @@ -162,7 +148,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTGLOADR_H__ */ +#endif /* FTGLOADR_H_ */ /* END */ diff --git a/drivers/freetype/include/freetype/internal/fthash.h b/drivers/freetype/include/freetype/internal/fthash.h new file mode 100644 index 0000000000..f22f9d5d39 --- /dev/null +++ b/drivers/freetype/include/freetype/internal/fthash.h @@ -0,0 +1,136 @@ +/***************************************************************************/ +/* */ +/* fthash.h */ +/* */ +/* Hashing functions (specification). */ +/* */ +/***************************************************************************/ + +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2015 + * Francesco Zappa Nardelli + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#ifndef FTHASH_H_ +#define FTHASH_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef union FT_Hashkey_ + { + FT_Int num; + const char* str; + + } FT_Hashkey; + + + typedef struct FT_HashnodeRec_ + { + FT_Hashkey key; + size_t data; + + } FT_HashnodeRec; + + typedef struct FT_HashnodeRec_ *FT_Hashnode; + + + typedef FT_ULong + (*FT_Hash_LookupFunc)( FT_Hashkey* key ); + + typedef FT_Bool + (*FT_Hash_CompareFunc)( FT_Hashkey* a, + FT_Hashkey* b ); + + + typedef struct FT_HashRec_ + { + FT_UInt limit; + FT_UInt size; + FT_UInt used; + + FT_Hash_LookupFunc lookup; + FT_Hash_CompareFunc compare; + + FT_Hashnode* table; + + } FT_HashRec; + + typedef struct FT_HashRec_ *FT_Hash; + + + FT_Error + ft_hash_str_init( FT_Hash hash, + FT_Memory memory ); + + FT_Error + ft_hash_num_init( FT_Hash hash, + FT_Memory memory ); + + void + ft_hash_str_free( FT_Hash hash, + FT_Memory memory ); + +#define ft_hash_num_free ft_hash_str_free + + FT_Error + ft_hash_str_insert( const char* key, + size_t data, + FT_Hash hash, + FT_Memory memory ); + + FT_Error + ft_hash_num_insert( FT_Int num, + size_t data, + FT_Hash hash, + FT_Memory memory ); + + size_t* + ft_hash_str_lookup( const char* key, + FT_Hash hash ); + + size_t* + ft_hash_num_lookup( FT_Int num, + FT_Hash hash ); + + +FT_END_HEADER + + +#endif /* FTHASH_H_ */ + + +/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftmemory.h b/drivers/freetype/include/freetype/internal/ftmemory.h index 3d51aeec69..8c06fc21a5 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftmemory.h +++ b/drivers/freetype/include/freetype/internal/ftmemory.h @@ -4,7 +4,7 @@ /* */ /* The FreeType memory management macros (specification). */ /* */ -/* Copyright 1996-2002, 2004-2007, 2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMEMORY_H__ -#define __FTMEMORY_H__ +#ifndef FTMEMORY_H_ +#define FTMEMORY_H_ #include <ft2build.h> @@ -65,13 +65,15 @@ FT_BEGIN_HEADER #ifdef __cplusplus - extern "C++" +extern "C++" +{ template <typename T> inline T* cplusplus_typeof( T*, void *v ) { return static_cast <T*> ( v ); } +} #define FT_ASSIGNP( p, val ) (p) = cplusplus_typeof( (p), (val) ) @@ -215,11 +217,14 @@ FT_BEGIN_HEADER #define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 ) -#define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count ) +#define FT_MEM_SET( dest, byte, count ) \ + ft_memset( dest, byte, (FT_Offset)(count) ) -#define FT_MEM_COPY( dest, source, count ) ft_memcpy( dest, source, count ) +#define FT_MEM_COPY( dest, source, count ) \ + ft_memcpy( dest, source, (FT_Offset)(count) ) -#define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count ) +#define FT_MEM_MOVE( dest, source, count ) \ + ft_memmove( dest, source, (FT_Offset)(count) ) #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) @@ -227,14 +232,19 @@ FT_BEGIN_HEADER #define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) -#define FT_ARRAY_ZERO( dest, count ) \ - FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) ) +#define FT_ARRAY_ZERO( dest, count ) \ + FT_MEM_ZERO( dest, \ + (FT_Offset)(count) * sizeof ( *(dest) ) ) -#define FT_ARRAY_COPY( dest, source, count ) \ - FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) ) +#define FT_ARRAY_COPY( dest, source, count ) \ + FT_MEM_COPY( dest, \ + source, \ + (FT_Offset)(count) * sizeof ( *(dest) ) ) -#define FT_ARRAY_MOVE( dest, source, count ) \ - FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) ) +#define FT_ARRAY_MOVE( dest, source, count ) \ + FT_MEM_MOVE( dest, \ + source, \ + (FT_Offset)(count) * sizeof ( *(dest) ) ) /* @@ -372,7 +382,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTMEMORY_H__ */ +#endif /* FTMEMORY_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftobjs.h b/drivers/freetype/include/freetype/internal/ftobjs.h index 701c850eb7..e3fa32083b 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftobjs.h +++ b/drivers/freetype/include/freetype/internal/ftobjs.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (specification). */ /* */ -/* Copyright 1996-2006, 2008, 2010, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,8 @@ /*************************************************************************/ -#ifndef __FTOBJS_H__ -#define __FTOBJS_H__ +#ifndef FTOBJS_H_ +#define FTOBJS_H_ #include <ft2build.h> #include FT_RENDER_H @@ -72,25 +72,28 @@ FT_BEGIN_HEADER #define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) - -#define FT_PAD_FLOOR( x, n ) ( (x) & ~((n)-1) ) + /* + * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' + * algorithm. We use alpha = 1, beta = 3/8, giving us results with a + * largest error less than 7% compared to the exact value. + */ +#define FT_HYPOT( x, y ) \ + ( x = FT_ABS( x ), \ + y = FT_ABS( y ), \ + x > y ? x + ( 3 * y >> 3 ) \ + : y + ( 3 * x >> 3 ) ) + + /* we use FT_TYPEOF to suppress signedness compilation warnings */ +#define FT_PAD_FLOOR( x, n ) ( (x) & ~FT_TYPEOF( x )( (n)-1 ) ) #define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n ) #define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n ) -#define FT_PIX_FLOOR( x ) ( (x) & ~63 ) +#define FT_PIX_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 ) #define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) #define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) /* - * Return the highest power of 2 that is <= value; this correspond to - * the highest bit in a given 32-bit value. - */ - FT_BASE( FT_UInt32 ) - ft_highpow2( FT_UInt32 value ); - - - /* * character classification functions -- since these are used to parse * font files, we must not use those in <ctypes.h> which are * locale-dependent @@ -338,12 +341,6 @@ FT_BEGIN_HEADER /* this data when first opened. This field exists only if */ /* @FT_CONFIG_OPTION_INCREMENTAL is defined. */ /* */ - /* ignore_unpatented_hinter :: */ - /* This boolean flag instructs the glyph loader to ignore the */ - /* native font hinter, if one is found. This is exclusively used */ - /* in the case when the unpatented hinter is compiled within the */ - /* library. */ - /* */ /* refcount :: */ /* A counter initialized to~1 at the time an @FT_Face structure is */ /* created. @FT_Reference_Face increments this counter, and */ @@ -362,7 +359,6 @@ FT_BEGIN_HEADER FT_Incremental_InterfaceRec* incremental_interface; #endif - FT_Bool ignore_unpatented_hinter; FT_Int refcount; } FT_Face_InternalRec; @@ -402,7 +398,7 @@ FT_BEGIN_HEADER /* glyph_hints :: Format-specific glyph hints management. */ /* */ -#define FT_GLYPH_OWN_BITMAP 0x1 +#define FT_GLYPH_OWN_BITMAP 0x1U typedef struct FT_Slot_InternalRec_ { @@ -503,6 +499,9 @@ FT_BEGIN_HEADER #define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ FT_MODULE_DRIVER_HAS_HINTER ) +#define FT_DRIVER_HINTS_LIGHTLY( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_HINTS_LIGHTLY ) + /*************************************************************************/ /* */ @@ -611,12 +610,12 @@ FT_BEGIN_HEADER #define FT_REQUEST_WIDTH( req ) \ ( (req)->horiResolution \ - ? (FT_Pos)( (req)->width * (req)->horiResolution + 36 ) / 72 \ + ? ( (req)->width * (FT_Pos)(req)->horiResolution + 36 ) / 72 \ : (req)->width ) #define FT_REQUEST_HEIGHT( req ) \ ( (req)->vertResolution \ - ? (FT_Pos)( (req)->height * (req)->vertResolution + 36 ) / 72 \ + ? ( (req)->height * (FT_Pos)(req)->vertResolution + 36 ) / 72 \ : (req)->height ) @@ -738,9 +737,8 @@ FT_BEGIN_HEADER /* faces_list :: The list of faces currently opened by this */ /* driver. */ /* */ - /* glyph_loader :: The glyph loader for all faces managed by this */ - /* driver. This object isn't defined for unscalable */ - /* formats. */ + /* glyph_loader :: Unused. Used to be glyph loader for all faces */ + /* managed by this driver. */ /* */ typedef struct FT_DriverRec_ { @@ -770,13 +768,6 @@ FT_BEGIN_HEADER #define FT_DEBUG_HOOK_TRUETYPE 0 - /* Set this debug hook to a non-null pointer to force unpatented hinting */ - /* for all faces when both TT_USE_BYTECODE_INTERPRETER and */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. This is only used */ - /* during debugging. */ -#define FT_DEBUG_HOOK_UNPATENTED_HINTING 1 - - typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap, FT_Render_Mode render_mode, FT_Library library ); @@ -842,7 +833,7 @@ FT_BEGIN_HEADER /* filtering callback function. */ /* */ /* pic_container :: Contains global structs and tables, instead */ - /* of defining them globallly. */ + /* of defining them globally. */ /* */ /* refcount :: A counter initialized to~1 at the time an */ /* @FT_Library structure is created. */ @@ -980,8 +971,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Outline_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1039,8 +1030,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Raster_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1099,8 +1090,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Glyph_Class struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated stcture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1173,11 +1164,11 @@ FT_BEGIN_HEADER /* <Description> */ /* Used to initialize an instance of FT_Renderer_Class struct. */ /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion will need */ - /* to be called with a pointer where the allocated structure is */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function will */ + /* need to be called with a pointer where the allocated structure is */ /* returned. And when it is no longer needed a `destroy' function */ /* needs to be called to release that allocation. */ - /* `fcinit.c' (ft_create_default_module_classes) already contains */ + /* `ftinit.c' (ft_create_default_module_classes) already contains */ /* a mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -1377,11 +1368,11 @@ FT_BEGIN_HEADER /* <Description> */ /* Used to initialize an instance of an FT_Module_Class struct. */ /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion needs to */ - /* be called with a pointer where the allocated structure is */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs */ + /* to be called with a pointer where the allocated structure is */ /* returned. And when it is no longer needed a `destroy' function */ /* needs to be called to release that allocation. */ - /* `fcinit.c' (ft_create_default_module_classes) already contains */ + /* `ftinit.c' (ft_create_default_module_classes) already contains */ /* a mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -1563,7 +1554,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTOBJS_H__ */ +#endif /* FTOBJS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftpic.h b/drivers/freetype/include/freetype/internal/ftpic.h index 485ce7a24e..6d800a08a1 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftpic.h +++ b/drivers/freetype/include/freetype/internal/ftpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services (declaration). */ /* */ -/* Copyright 2009, 2012 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,8 @@ /*************************************************************************/ -#ifndef __FTPIC_H__ -#define __FTPIC_H__ +#ifndef FTPIC_H_ +#define FTPIC_H_ FT_BEGIN_HEADER @@ -65,7 +65,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTPIC_H__ */ +#endif /* FTPIC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftrfork.h b/drivers/freetype/include/freetype/internal/ftrfork.h index 6307f2d0c5..b923401e68 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftrfork.h +++ b/drivers/freetype/include/freetype/internal/ftrfork.h @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (specification). */ /* */ -/* Copyright 2004, 2006, 2007, 2012 by */ +/* Copyright 2004-2016 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +21,8 @@ /***************************************************************************/ -#ifndef __FTRFORK_H__ -#define __FTRFORK_H__ +#ifndef FTRFORK_H_ +#define FTRFORK_H_ #include <ft2build.h> @@ -44,7 +44,7 @@ FT_BEGIN_HEADER typedef struct FT_RFork_Ref_ { FT_UShort res_id; - FT_ULong offset; + FT_Long offset; } FT_RFork_Ref; @@ -83,7 +83,7 @@ FT_BEGIN_HEADER /* this array is a storage in non-PIC mode, so ; is needed in END */ #define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ - const type name[] = { + static const type name[] = { #define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \ { raccess_guess_ ## func_suffix, \ FT_RFork_Rule_ ## type_suffix }, @@ -94,7 +94,7 @@ FT_BEGIN_HEADER /* this array is a function in PIC mode, so no ; is needed in END */ #define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ void \ - FT_Init_ ## name( type* storage ) \ + FT_Init_Table_ ## name( type* storage ) \ { \ type* local = storage; \ \ @@ -224,6 +224,13 @@ FT_BEGIN_HEADER /* tag :: */ /* The resource tag. */ /* */ + /* sort_by_res_id :: */ + /* A Boolean to sort the fragmented resource by their ids. */ + /* The fragmented resources for `POST' resource should be sorted */ + /* to restore Type1 font properly. For `sfnt' resources, sorting */ + /* may induce a different order of the faces in comparison to that */ + /* by QuickDraw API. */ + /* */ /* <Output> */ /* offsets :: */ /* The stream offsets for the resource data specified by `tag'. */ @@ -246,13 +253,14 @@ FT_BEGIN_HEADER FT_Long map_offset, FT_Long rdata_pos, FT_Long tag, + FT_Bool sort_by_res_id, FT_Long **offsets, FT_Long *count ); FT_END_HEADER -#endif /* __FTRFORK_H__ */ +#endif /* FTRFORK_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftserv.h b/drivers/freetype/include/freetype/internal/ftserv.h index cd5fbd0fac..91897177ba 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftserv.h +++ b/drivers/freetype/include/freetype/internal/ftserv.h @@ -4,7 +4,7 @@ /* */ /* The FreeType services (specification only). */ /* */ -/* Copyright 2003-2007, 2009, 2012, 2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,8 +28,8 @@ /*************************************************************************/ -#ifndef __FTSERV_H__ -#define __FTSERV_H__ +#ifndef FTSERV_H_ +#define FTSERV_H_ FT_BEGIN_HEADER @@ -750,14 +750,14 @@ FT_BEGIN_HEADER #define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h> #define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> #define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> -#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h> +#define FT_SERVICE_FONT_FORMAT_H <freetype/internal/services/svfntfmt.h> #define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h> /* */ FT_END_HEADER -#endif /* __FTSERV_H__ */ +#endif /* FTSERV_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftstream.h b/drivers/freetype/include/freetype/internal/ftstream.h index 2661858320..6d04875657 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftstream.h +++ b/drivers/freetype/include/freetype/internal/ftstream.h @@ -4,7 +4,7 @@ /* */ /* Stream handling (specification). */ /* */ -/* Copyright 1996-2002, 2004-2006, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSTREAM_H__ -#define __FTSTREAM_H__ +#ifndef FTSTREAM_H_ +#define FTSTREAM_H_ #include <ft2build.h> @@ -361,7 +361,7 @@ FT_BEGIN_HEADER FT_Long distance ); /* return current stream position */ - FT_BASE( FT_Long ) + FT_BASE( FT_ULong ) FT_Stream_Pos( FT_Stream stream ); /* read bytes from a stream into a user-allocated buffer, returns an */ @@ -530,7 +530,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSTREAM_H__ */ +#endif /* FTSTREAM_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/fttrace.h b/drivers/freetype/include/freetype/internal/fttrace.h index a9d98b60aa..efb3355954 100644 --- a/drivers/freetype/freetype/include/freetype/internal/fttrace.h +++ b/drivers/freetype/include/freetype/internal/fttrace.h @@ -4,7 +4,7 @@ /* */ /* Tracing handling (specification only). */ /* */ -/* Copyright 2002, 2004-2007, 2009, 2011-2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -148,5 +148,7 @@ FT_TRACE_DEF( afcjk ) FT_TRACE_DEF( aflatin ) FT_TRACE_DEF( aflatin2 ) FT_TRACE_DEF( afwarp ) +FT_TRACE_DEF( afshaper ) +FT_TRACE_DEF( afglobal ) /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/ftvalid.h b/drivers/freetype/include/freetype/internal/ftvalid.h index 12ad03685a..aac92c9af8 100644 --- a/drivers/freetype/freetype/include/freetype/internal/ftvalid.h +++ b/drivers/freetype/include/freetype/internal/ftvalid.h @@ -4,7 +4,7 @@ /* */ /* FreeType validation support (specification). */ /* */ -/* Copyright 2004, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTVALID_H__ -#define __FTVALID_H__ +#ifndef FTVALID_H_ +#define FTVALID_H_ #include <ft2build.h> #include FT_CONFIG_STANDARD_LIBRARY_H /* for ft_setjmp and ft_longjmp */ @@ -87,13 +87,13 @@ FT_BEGIN_HEADER /* validator structure */ typedef struct FT_ValidatorRec_ { + ft_jmp_buf jump_buffer; /* used for exception handling */ + const FT_Byte* base; /* address of table in memory */ const FT_Byte* limit; /* `base' + sizeof(table) in memory */ FT_ValidationLevel level; /* validation level */ FT_Error error; /* error returned. 0 means success */ - ft_jmp_buf jump_buffer; /* used for exception handling */ - } FT_ValidatorRec; #if defined( _MSC_VER ) @@ -126,36 +126,34 @@ FT_BEGIN_HEADER /* Calls ft_validate_error. Assumes that the `valid' local variable */ /* holds a pointer to the current validator object. */ /* */ - /* Use preprocessor prescan to pass FT_ERR_PREFIX. */ - /* */ -#define FT_INVALID( _prefix, _error ) FT_INVALID_( _prefix, _error ) -#define FT_INVALID_( _prefix, _error ) \ - ft_validator_error( valid, _prefix ## _error ) +#define FT_INVALID( _error ) FT_INVALID_( _error ) +#define FT_INVALID_( _error ) \ + ft_validator_error( valid, FT_THROW( _error ) ) /* called when a broken table is detected */ #define FT_INVALID_TOO_SHORT \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + FT_INVALID( Invalid_Table ) /* called when an invalid offset is detected */ #define FT_INVALID_OFFSET \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Offset ) + FT_INVALID( Invalid_Offset ) /* called when an invalid format/value is detected */ #define FT_INVALID_FORMAT \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + FT_INVALID( Invalid_Table ) /* called when an invalid glyph index is detected */ #define FT_INVALID_GLYPH_ID \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Glyph_Index ) + FT_INVALID( Invalid_Glyph_Index ) /* called when an invalid field value is detected */ #define FT_INVALID_DATA \ - FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + FT_INVALID( Invalid_Table ) FT_END_HEADER -#endif /* __FTVALID_H__ */ +#endif /* FTVALID_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/internal.h b/drivers/freetype/include/freetype/internal/internal.h index 262afcfa8a..8c3c14c12a 100644 --- a/drivers/freetype/freetype/include/freetype/internal/internal.h +++ b/drivers/freetype/include/freetype/internal/internal.h @@ -4,7 +4,7 @@ /* */ /* Internal header files (specification only). */ /* */ -/* Copyright 1996-2004, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,6 +30,7 @@ #define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> #define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> #define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> +#define FT_INTERNAL_HASH_H <freetype/internal/fthash.h> #define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> #define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> #define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> @@ -43,7 +44,6 @@ #define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> #define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> -#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h> #define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> diff --git a/drivers/freetype/freetype/include/freetype/internal/psaux.h b/drivers/freetype/include/freetype/internal/psaux.h index e903114f84..15dedfd28e 100644 --- a/drivers/freetype/freetype/include/freetype/internal/psaux.h +++ b/drivers/freetype/include/freetype/internal/psaux.h @@ -5,7 +5,7 @@ /* Auxiliary functions and data structures related to PostScript fonts */ /* (specification). */ /* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,13 +17,14 @@ /***************************************************************************/ -#ifndef __PSAUX_H__ -#define __PSAUX_H__ +#ifndef PSAUX_H_ +#define PSAUX_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_HASH_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H @@ -71,10 +72,10 @@ FT_BEGIN_HEADER (*done)( PS_Table table ); FT_Error - (*add)( PS_Table table, - FT_Int idx, - void* object, - FT_PtrDist length ); + (*add)( PS_Table table, + FT_Int idx, + void* object, + FT_UInt length ); void (*release)( PS_Table table ); @@ -122,12 +123,12 @@ FT_BEGIN_HEADER FT_Byte* block; /* current memory block */ FT_Offset cursor; /* current cursor in memory block */ FT_Offset capacity; /* current size of memory block */ - FT_Long init; + FT_ULong init; FT_Int max_elems; FT_Int num_elems; FT_Byte** elements; /* addresses of table elements */ - FT_PtrDist* lengths; /* lengths of table elements */ + FT_UInt* lengths; /* lengths of table elements */ FT_Memory memory; PS_Table_FuncsRec funcs; @@ -365,7 +366,7 @@ FT_BEGIN_HEADER (*to_bytes)( PS_Parser parser, FT_Byte* bytes, FT_Offset max_bytes, - FT_Long* pnum_bytes, + FT_ULong* pnum_bytes, FT_Bool delimiters ); FT_Int @@ -675,9 +676,10 @@ FT_BEGIN_HEADER FT_Byte** glyph_names; FT_Int lenIV; /* internal for sub routine calls */ - FT_UInt num_subrs; + FT_Int num_subrs; FT_Byte** subrs; - FT_PtrDist* subrs_len; /* array of subrs length (optional) */ + FT_UInt* subrs_len; /* array of subrs length (optional) */ + FT_Hash subrs_hash; /* used if `num_subrs' was massaged */ FT_Matrix font_matrix; FT_Vector font_offset; @@ -871,7 +873,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSAUX_H__ */ +#endif /* PSAUX_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/pshints.h b/drivers/freetype/include/freetype/internal/pshints.h index 3fb18dc2d5..e60dc9cd55 100644 --- a/drivers/freetype/freetype/include/freetype/internal/pshints.h +++ b/drivers/freetype/include/freetype/internal/pshints.h @@ -6,7 +6,7 @@ /* recorders (specification only). These are used to support native */ /* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ /* */ -/* Copyright 2001-2003, 2005-2007, 2009, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,8 +18,8 @@ /***************************************************************************/ -#ifndef __PSHINTS_H__ -#define __PSHINTS_H__ +#ifndef PSHINTS_H_ +#define PSHINTS_H_ #include <ft2build.h> @@ -45,7 +45,7 @@ FT_BEGIN_HEADER T1_Private* private_dict, PSH_Globals* aglobals ); - typedef FT_Error + typedef void (*PSH_Globals_SetScaleFunc)( PSH_Globals globals, FT_Fixed x_scale, FT_Fixed y_scale, @@ -465,7 +465,7 @@ FT_BEGIN_HEADER typedef void (*T2_Hints_StemsFunc)( T2_Hints hints, FT_UInt dimension, - FT_UInt count, + FT_Int count, FT_Fixed* coordinates ); @@ -716,7 +716,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHINTS_H__ */ +#endif /* PSHINTS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svbdf.h b/drivers/freetype/include/freetype/internal/services/svbdf.h index 0974752a79..c24475fc20 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svbdf.h +++ b/drivers/freetype/include/freetype/internal/services/svbdf.h @@ -4,7 +4,7 @@ /* */ /* The FreeType BDF services (specification). */ /* */ -/* Copyright 2003, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVBDF_H__ -#define __SVBDF_H__ +#ifndef SVBDF_H_ +#define SVBDF_H_ #include FT_BDF_H #include FT_INTERNAL_SERVICE_H @@ -76,7 +76,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVBDF_H__ */ +#endif /* SVBDF_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svcid.h b/drivers/freetype/include/freetype/internal/services/svcid.h index 6be3f9374d..dbbe6044a4 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svcid.h +++ b/drivers/freetype/include/freetype/internal/services/svcid.h @@ -4,7 +4,8 @@ /* */ /* The FreeType CID font services (specification). */ /* */ -/* Copyright 2007, 2009, 2012 by Derek Clegg, Michael Toftdal. */ +/* Copyright 2007-2016 by */ +/* Derek Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVCID_H__ -#define __SVCID_H__ +#ifndef SVCID_H_ +#define SVCID_H_ #include FT_INTERNAL_SERVICE_H @@ -83,7 +84,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVCID_H__ */ +#endif /* SVCID_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svxf86nm.h b/drivers/freetype/include/freetype/internal/services/svfntfmt.h index ca5d884a83..bd295c9c6b 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svxf86nm.h +++ b/drivers/freetype/include/freetype/internal/services/svfntfmt.h @@ -1,10 +1,10 @@ /***************************************************************************/ /* */ -/* svxf86nm.h */ +/* svfntfmt.h */ /* */ -/* The FreeType XFree86 services (specification only). */ +/* The FreeType font format service (specification only). */ /* */ -/* Copyright 2003 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVXF86NM_H__ -#define __SVXF86NM_H__ +#ifndef SVFNTFMT_H_ +#define SVFNTFMT_H_ #include FT_INTERNAL_SERVICE_H @@ -31,17 +31,17 @@ FT_BEGIN_HEADER * is a simple constant string pointer. */ -#define FT_SERVICE_ID_XF86_NAME "xf86-driver-name" +#define FT_SERVICE_ID_FONT_FORMAT "font-format" -#define FT_XF86_FORMAT_TRUETYPE "TrueType" -#define FT_XF86_FORMAT_TYPE_1 "Type 1" -#define FT_XF86_FORMAT_BDF "BDF" -#define FT_XF86_FORMAT_PCF "PCF" -#define FT_XF86_FORMAT_TYPE_42 "Type 42" -#define FT_XF86_FORMAT_CID "CID Type 1" -#define FT_XF86_FORMAT_CFF "CFF" -#define FT_XF86_FORMAT_PFR "PFR" -#define FT_XF86_FORMAT_WINFNT "Windows FNT" +#define FT_FONT_FORMAT_TRUETYPE "TrueType" +#define FT_FONT_FORMAT_TYPE_1 "Type 1" +#define FT_FONT_FORMAT_BDF "BDF" +#define FT_FONT_FORMAT_PCF "PCF" +#define FT_FONT_FORMAT_TYPE_42 "Type 42" +#define FT_FONT_FORMAT_CID "CID Type 1" +#define FT_FONT_FORMAT_CFF "CFF" +#define FT_FONT_FORMAT_PFR "PFR" +#define FT_FONT_FORMAT_WINFNT "Windows FNT" /* */ @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVXF86NM_H__ */ +#endif /* SVFNTFMT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svgldict.h b/drivers/freetype/include/freetype/internal/services/svgldict.h index 1d12534725..fff29bc40c 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svgldict.h +++ b/drivers/freetype/include/freetype/internal/services/svgldict.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph dictionary services (specification). */ /* */ -/* Copyright 2003, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVGLDICT_H__ -#define __SVGLDICT_H__ +#ifndef SVGLDICT_H_ +#define SVGLDICT_H_ #include FT_INTERNAL_SERVICE_H @@ -85,4 +85,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVGLDICT_H__ */ +#endif /* SVGLDICT_H_ */ + + +/* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svgxval.h b/drivers/freetype/include/freetype/internal/services/svgxval.h index 2cdab50655..fb8ffba83c 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svgxval.h +++ b/drivers/freetype/include/freetype/internal/services/svgxval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating TrueTypeGX/AAT tables (specification). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004-2016 by */ /* Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __SVGXVAL_H__ -#define __SVGXVAL_H__ +#ifndef SVGXVAL_H_ +#define SVGXVAL_H_ #include FT_GX_VALIDATE_H #include FT_INTERNAL_VALIDATE_H @@ -66,7 +66,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVGXVAL_H__ */ +#endif /* SVGXVAL_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svkern.h b/drivers/freetype/include/freetype/internal/services/svkern.h index 1488adf493..a636f1af1c 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svkern.h +++ b/drivers/freetype/include/freetype/internal/services/svkern.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Kerning service (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVKERN_H__ -#define __SVKERN_H__ +#ifndef SVKERN_H_ +#define SVKERN_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVKERN_H__ */ +#endif /* SVKERN_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svmm.h b/drivers/freetype/include/freetype/internal/services/svmm.h index b08a663d66..b78a19f8e0 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svmm.h +++ b/drivers/freetype/include/freetype/internal/services/svmm.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Multiple Masters and GX var services (specification). */ /* */ -/* Copyright 2003, 2004, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVMM_H__ -#define __SVMM_H__ +#ifndef SVMM_H_ +#define SVMM_H_ #include FT_INTERNAL_SERVICE_H @@ -107,7 +107,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVMM_H__ */ +#endif /* SVMM_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svotval.h b/drivers/freetype/include/freetype/internal/services/svotval.h index 970bbd5759..bc929d4bd9 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svotval.h +++ b/drivers/freetype/include/freetype/internal/services/svotval.h @@ -4,7 +4,7 @@ /* */ /* The FreeType OpenType validation service (specification). */ /* */ -/* Copyright 2004, 2006 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVOTVAL_H__ -#define __SVOTVAL_H__ +#ifndef SVOTVAL_H_ +#define SVOTVAL_H_ #include FT_OPENTYPE_VALIDATE_H #include FT_INTERNAL_VALIDATE_H @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVOTVAL_H__ */ +#endif /* SVOTVAL_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svpfr.h b/drivers/freetype/include/freetype/internal/services/svpfr.h index 462786f9ce..d0f7c4df95 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svpfr.h +++ b/drivers/freetype/include/freetype/internal/services/svpfr.h @@ -4,7 +4,7 @@ /* */ /* Internal PFR service functions (specification). */ /* */ -/* Copyright 2003, 2006 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPFR_H__ -#define __SVPFR_H__ +#ifndef SVPFR_H_ +#define SVPFR_H_ #include FT_PFR_H #include FT_INTERNAL_SERVICE_H @@ -60,7 +60,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPFR_H__ */ +#endif /* SVPFR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svpostnm.h b/drivers/freetype/include/freetype/internal/services/svpostnm.h index a76b4fe057..f124380050 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svpostnm.h +++ b/drivers/freetype/include/freetype/internal/services/svpostnm.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript name services (specification). */ /* */ -/* Copyright 2003, 2007, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPOSTNM_H__ -#define __SVPOSTNM_H__ +#ifndef SVPOSTNM_H_ +#define SVPOSTNM_H_ #include FT_INTERNAL_SERVICE_H @@ -75,7 +75,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPOSTNM_H__ */ +#endif /* SVPOSTNM_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svprop.h b/drivers/freetype/include/freetype/internal/services/svprop.h index 22da0bbc69..870e90ed7c 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svprop.h +++ b/drivers/freetype/include/freetype/internal/services/svprop.h @@ -4,7 +4,7 @@ /* */ /* The FreeType property service (specification). */ /* */ -/* Copyright 2012 by */ +/* Copyright 2012-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPROP_H__ -#define __SVPROP_H__ +#ifndef SVPROP_H_ +#define SVPROP_H_ FT_BEGIN_HEADER @@ -75,7 +75,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPROP_H__ */ +#endif /* SVPROP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svpscmap.h b/drivers/freetype/include/freetype/internal/services/svpscmap.h index 030948ea64..9acc21690f 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svpscmap.h +++ b/drivers/freetype/include/freetype/internal/services/svpscmap.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript charmap service (specification). */ /* */ -/* Copyright 2003, 2006, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPSCMAP_H__ -#define __SVPSCMAP_H__ +#ifndef SVPSCMAP_H_ +#define SVPSCMAP_H_ #include FT_INTERNAL_OBJECTS_H @@ -171,7 +171,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPSCMAP_H__ */ +#endif /* SVPSCMAP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svpsinfo.h b/drivers/freetype/include/freetype/internal/services/svpsinfo.h index 4bfb506711..f2c8060440 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svpsinfo.h +++ b/drivers/freetype/include/freetype/internal/services/svpsinfo.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript info service (specification). */ /* */ -/* Copyright 2003, 2004, 2009, 2011, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPSINFO_H__ -#define __SVPSINFO_H__ +#ifndef SVPSINFO_H_ +#define SVPSINFO_H_ #include FT_INTERNAL_SERVICE_H #include FT_INTERNAL_TYPE1_TYPES_H @@ -105,7 +105,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPSINFO_H__ */ +#endif /* SVPSINFO_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svsfnt.h b/drivers/freetype/include/freetype/internal/services/svsfnt.h index d3835aa1c2..0f38cf195f 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svsfnt.h +++ b/drivers/freetype/include/freetype/internal/services/svsfnt.h @@ -4,7 +4,7 @@ /* */ /* The FreeType SFNT table loading service (specification). */ /* */ -/* Copyright 2003, 2004, 2009, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVSFNT_H__ -#define __SVSFNT_H__ +#ifndef SVSFNT_H_ +#define SVSFNT_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -97,7 +97,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVSFNT_H__ */ +#endif /* SVSFNT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svttcmap.h b/drivers/freetype/include/freetype/internal/services/svttcmap.h index 83994aaf8a..772c72189e 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svttcmap.h +++ b/drivers/freetype/include/freetype/internal/services/svttcmap.h @@ -4,10 +4,8 @@ /* */ /* The FreeType TrueType/sfnt cmap extra information service. */ /* */ -/* Copyright 2003 by */ -/* Masatake YAMATO, Redhat K.K. */ -/* */ -/* Copyright 2003, 2008, 2009, 2012 by */ +/* Copyright 2003-2016 by */ +/* Masatake YAMATO, Redhat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +19,8 @@ /* Development of this service is support of Information-technology Promotion Agency, Japan. */ -#ifndef __SVTTCMAP_H__ -#define __SVTTCMAP_H__ +#ifndef SVTTCMAP_H_ +#define SVTTCMAP_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -47,14 +45,15 @@ FT_BEGIN_HEADER /* <Fields> */ /* language :: */ /* The language ID used in Mac fonts. Definitions of values are in */ - /* freetype/ttnameid.h. */ + /* `ttnameid.h'. */ /* */ /* format :: */ - /* The cmap format. OpenType 1.5 defines the formats 0 (byte */ + /* The cmap format. OpenType 1.6 defines the formats 0 (byte */ /* encoding table), 2~(high-byte mapping through table), 4~(segment */ /* mapping to delta values), 6~(trimmed table mapping), 8~(mixed */ /* 16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented */ - /* coverage), and 14 (Unicode Variation Sequences). */ + /* coverage), 13~(last resort font), and 14 (Unicode Variation */ + /* Sequences). */ /* */ typedef struct TT_CMapInfo_ { @@ -101,7 +100,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTCMAP_H__ */ +#endif /* SVTTCMAP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svtteng.h b/drivers/freetype/include/freetype/internal/services/svtteng.h index 58e02a6f9d..c55061a034 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svtteng.h +++ b/drivers/freetype/include/freetype/internal/services/svtteng.h @@ -4,7 +4,7 @@ /* */ /* The FreeType TrueType engine query service (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVTTENG_H__ -#define __SVTTENG_H__ +#ifndef SVTTENG_H_ +#define SVTTENG_H_ #include FT_INTERNAL_SERVICE_H #include FT_MODULE_H @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTENG_H__ */ +#endif /* SVTTENG_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svttglyf.h b/drivers/freetype/include/freetype/internal/services/svttglyf.h index 369eb8421b..c33edd46de 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svttglyf.h +++ b/drivers/freetype/include/freetype/internal/services/svttglyf.h @@ -4,7 +4,8 @@ /* */ /* The FreeType TrueType glyph service. */ /* */ -/* Copyright 2007, 2009, 2012 by David Turner. */ +/* Copyright 2007-2016 by */ +/* David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -14,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __SVTTGLYF_H__ -#define __SVTTGLYF_H__ +#ifndef SVTTGLYF_H_ +#define SVTTGLYF_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -62,7 +63,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTGLYF_H__ */ +#endif /* SVTTGLYF_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/services/svwinfnt.h b/drivers/freetype/include/freetype/internal/services/svwinfnt.h index 57f7765d92..c2f6d4c6d3 100644 --- a/drivers/freetype/freetype/include/freetype/internal/services/svwinfnt.h +++ b/drivers/freetype/include/freetype/internal/services/svwinfnt.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Windows FNT/FONT service (specification). */ /* */ -/* Copyright 2003 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVWINFNT_H__ -#define __SVWINFNT_H__ +#ifndef SVWINFNT_H_ +#define SVWINFNT_H_ #include FT_INTERNAL_SERVICE_H #include FT_WINFONTS_H @@ -44,7 +44,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVWINFNT_H__ */ +#endif /* SVWINFNT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/sfnt.h b/drivers/freetype/include/freetype/internal/sfnt.h index 6b5e41f1ad..e139315a1f 100644 --- a/drivers/freetype/freetype/include/freetype/internal/sfnt.h +++ b/drivers/freetype/include/freetype/internal/sfnt.h @@ -4,7 +4,7 @@ /* */ /* High-level `sfnt' driver interface (specification). */ /* */ -/* Copyright 1996-2006, 2009, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFNT_H__ -#define __SFNT_H__ +#ifndef SFNT_H_ +#define SFNT_H_ #include <ft2build.h> @@ -44,7 +44,9 @@ FT_BEGIN_HEADER /* face :: A handle to the target face object. */ /* */ /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ /* */ /* num_params :: The number of additional parameters. */ /* */ @@ -87,7 +89,9 @@ FT_BEGIN_HEADER /* face :: A handle to the target face object. */ /* */ /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ /* */ /* num_params :: The number of additional parameters. */ /* */ @@ -405,14 +409,18 @@ FT_BEGIN_HEADER /* <Input> */ /* face :: A handle to the target face object. */ /* */ - /* stream :: The input stream. */ - /* */ /* vertical :: A boolean flag. If set, load vertical metrics. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ + /* gindex :: The glyph index. */ /* */ - typedef FT_Error + /* <Output> */ + /* abearing :: The horizontal (or vertical) bearing. Set to zero in */ + /* case of error. */ + /* */ + /* aadvance :: The horizontal (or vertical) advance. Set to zero in */ + /* case of error. */ + /* */ + typedef void (*TT_Get_Metrics_Func)( TT_Face face, FT_Bool vertical, FT_UInt gindex, @@ -423,6 +431,33 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <FuncType> */ + /* TT_Get_Name_Func */ + /* */ + /* <Description> */ + /* From the `name' table, return a given ENGLISH name record in */ + /* ASCII. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* nameid :: The name id of the name record to return. */ + /* */ + /* <InOut> */ + /* name :: The address of an allocated string pointer. NULL if */ + /* no name is present. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_Name_Func)( TT_Face face, + FT_UShort nameid, + FT_String** name ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ /* TT_Load_Table_Func */ /* */ /* <Description> */ @@ -552,6 +587,8 @@ FT_BEGIN_HEADER TT_Get_Metrics_Func get_metrics; + TT_Get_Name_Func get_name; + } SFNT_Interface; @@ -590,7 +627,8 @@ FT_BEGIN_HEADER free_eblc_, \ set_sbit_strike_, \ load_strike_metrics_, \ - get_metrics_ ) \ + get_metrics_, \ + get_name_ ) \ static const SFNT_Interface class_ = \ { \ goto_table_, \ @@ -622,6 +660,7 @@ FT_BEGIN_HEADER set_sbit_strike_, \ load_strike_metrics_, \ get_metrics_, \ + get_name_, \ }; #else /* FT_CONFIG_OPTION_PIC */ @@ -659,7 +698,8 @@ FT_BEGIN_HEADER free_eblc_, \ set_sbit_strike_, \ load_strike_metrics_, \ - get_metrics_ ) \ + get_metrics_, \ + get_name_ ) \ void \ FT_Init_Class_ ## class_( FT_Library library, \ SFNT_Interface* clazz ) \ @@ -695,13 +735,14 @@ FT_BEGIN_HEADER clazz->set_sbit_strike = set_sbit_strike_; \ clazz->load_strike_metrics = load_strike_metrics_; \ clazz->get_metrics = get_metrics_; \ + clazz->get_name = get_name_; \ } #endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER -#endif /* __SFNT_H__ */ +#endif /* SFNT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/t1types.h b/drivers/freetype/include/freetype/internal/t1types.h index e20237c14d..494c011fc7 100644 --- a/drivers/freetype/freetype/include/freetype/internal/t1types.h +++ b/drivers/freetype/include/freetype/internal/t1types.h @@ -5,7 +5,7 @@ /* Basic Type1/Type2 type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,14 +17,15 @@ /***************************************************************************/ -#ifndef __T1TYPES_H__ -#define __T1TYPES_H__ +#ifndef T1TYPES_H_ +#define T1TYPES_H_ #include <ft2build.h> #include FT_TYPE1_TABLES_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_HASH_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H @@ -106,12 +107,13 @@ FT_BEGIN_HEADER FT_Int num_subrs; FT_Byte** subrs; - FT_PtrDist* subrs_len; + FT_UInt* subrs_len; + FT_Hash subrs_hash; FT_Int num_glyphs; FT_String** glyph_names; /* array of glyph names */ FT_Byte** charstrings; /* array of glyph charstrings */ - FT_PtrDist* charstrings_len; + FT_UInt* charstrings_len; FT_Byte paint_type; FT_Byte font_type; @@ -127,7 +129,7 @@ FT_BEGIN_HEADER typedef struct CID_SubrsRec_ { - FT_UInt num_subrs; + FT_Int num_subrs; FT_Byte** code; } CID_SubrsRec, *CID_Subrs; @@ -157,10 +159,10 @@ FT_BEGIN_HEADER typedef struct AFM_KernPairRec_ { - FT_Int index1; - FT_Int index2; - FT_Int x; - FT_Int y; + FT_UInt index1; + FT_UInt index2; + FT_Int x; + FT_Int y; } AFM_KernPairRec, *AFM_KernPair; @@ -171,9 +173,9 @@ FT_BEGIN_HEADER FT_Fixed Ascender; FT_Fixed Descender; AFM_TrackKern TrackKerns; /* free if non-NULL */ - FT_Int NumTrackKern; + FT_UInt NumTrackKern; AFM_KernPair KernPairs; /* free if non-NULL */ - FT_Int NumKernPair; + FT_UInt NumKernPair; } AFM_FontInfoRec, *AFM_FontInfo; @@ -249,7 +251,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1TYPES_H__ */ +#endif /* T1TYPES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/internal/tttypes.h b/drivers/freetype/include/freetype/internal/tttypes.h index 1bbfe499c5..4110d50285 100644 --- a/drivers/freetype/freetype/include/freetype/internal/tttypes.h +++ b/drivers/freetype/include/freetype/internal/tttypes.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2002, 2004-2008, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTTYPES_H__ -#define __TTTYPES_H__ +#ifndef TTTYPES_H_ +#define TTTYPES_H_ #include <ft2build.h> @@ -140,6 +140,75 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Struct> */ + /* WOFF_HeaderRec */ + /* */ + /* <Description> */ + /* WOFF file format header. */ + /* */ + /* <Fields> */ + /* See */ + /* */ + /* http://www.w3.org/TR/WOFF/#WOFFHeader */ + /* */ + typedef struct WOFF_HeaderRec_ + { + FT_ULong signature; + FT_ULong flavor; + FT_ULong length; + FT_UShort num_tables; + FT_UShort reserved; + FT_ULong totalSfntSize; + FT_UShort majorVersion; + FT_UShort minorVersion; + FT_ULong metaOffset; + FT_ULong metaLength; + FT_ULong metaOrigLength; + FT_ULong privOffset; + FT_ULong privLength; + + } WOFF_HeaderRec, *WOFF_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* WOFF_TableRec */ + /* */ + /* <Description> */ + /* This structure describes a given table of a WOFF font. */ + /* */ + /* <Fields> */ + /* Tag :: A four-bytes tag describing the table. */ + /* */ + /* Offset :: The offset of the table from the start of the WOFF */ + /* font in its resource. */ + /* */ + /* CompLength :: Compressed table length (in bytes). */ + /* */ + /* OrigLength :: Uncompressed table length (in bytes). */ + /* */ + /* CheckSum :: The table checksum. This value can be ignored. */ + /* */ + /* OrigOffset :: The uncompressed table file offset. This value gets */ + /* computed while constructing the (uncompressed) SFNT */ + /* header. It is not contained in the WOFF file. */ + /* */ + typedef struct WOFF_TableRec_ + { + FT_ULong Tag; /* table ID */ + FT_ULong Offset; /* table file offset */ + FT_ULong CompLength; /* compressed table length */ + FT_ULong OrigLength; /* uncompressed table length */ + FT_ULong CheckSum; /* uncompressed checksum */ + + FT_ULong OrigOffset; /* uncompressed table file offset */ + /* (not in the WOFF file) */ + } WOFF_TableRec, *WOFF_Table; + + + /*************************************************************************/ + /* */ + /* <Struct> */ /* TT_LongMetricsRec */ /* */ /* <Description> */ @@ -353,16 +422,16 @@ FT_BEGIN_HEADER /* */ typedef struct TT_SBit_MetricsRec_ { - FT_Byte height; - FT_Byte width; + FT_UShort height; + FT_UShort width; - FT_Char horiBearingX; - FT_Char horiBearingY; - FT_Byte horiAdvance; + FT_Short horiBearingX; + FT_Short horiBearingY; + FT_UShort horiAdvance; - FT_Char vertBearingX; - FT_Char vertBearingY; - FT_Byte vertAdvance; + FT_Short vertBearingX; + FT_Short vertBearingY; + FT_UShort vertAdvance; } TT_SBit_MetricsRec, *TT_SBit_Metrics; @@ -545,8 +614,7 @@ FT_BEGIN_HEADER /* in use by other platforms (e.g. Newton). */ /* For details, please see */ /* */ - /* http://fonts.apple.com/ */ - /* TTRefMan/RM06/Chap6bloc.html */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html */ /* */ /* hori :: The line metrics for horizontal layouts. */ /* */ @@ -566,8 +634,7 @@ FT_BEGIN_HEADER /* flags :: Is this a vertical or horizontal strike? For */ /* details, please see */ /* */ - /* http://fonts.apple.com/ */ - /* TTRefMan/RM06/Chap6bloc.html */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html */ /* */ typedef struct TT_SBit_StrikeRec_ { @@ -979,6 +1046,20 @@ FT_BEGIN_HEADER (*TT_Loader_EndGlyphFunc)( TT_Loader loader ); + typedef enum TT_SbitTableType_ + { + TT_SBIT_TABLE_TYPE_NONE = 0, + TT_SBIT_TABLE_TYPE_EBLC, /* `EBLC' (Microsoft), */ + /* `bloc' (Apple) */ + TT_SBIT_TABLE_TYPE_CBLC, /* `CBLC' (Google) */ + TT_SBIT_TABLE_TYPE_SBIX, /* `sbix' (Apple) */ + + /* do not remove */ + TT_SBIT_TABLE_TYPE_MAX + + } TT_SbitTableType; + + /*************************************************************************/ /* */ /* TrueType Face Type */ @@ -1030,7 +1111,7 @@ FT_BEGIN_HEADER /* This field also contains the associated */ /* vertical metrics table (`vmtx'), if found. */ /* IMPORTANT: The contents of this field is */ - /* undefined if the `verticalInfo' field is */ + /* undefined if the `vertical_info' field is */ /* unset. */ /* */ /* num_names :: The number of name records within this */ @@ -1090,13 +1171,6 @@ FT_BEGIN_HEADER /* */ /* pclt :: The `pclt' SFNT table. */ /* */ - /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */ - /* sizes, embedded in this font. */ - /* */ - /* sbit_strikes :: An array of sbit strikes embedded in this */ - /* font. This table is optional in a */ - /* TrueType/OpenType font. */ - /* */ /* num_sbit_scales :: The number of sbit scales for this font. */ /* */ /* sbit_scales :: Array of sbit scales embedded in this */ @@ -1159,9 +1233,6 @@ FT_BEGIN_HEADER /* interpreters field is also used to hook */ /* the debugger in `ttdebug'. */ /* */ - /* unpatented_hinting :: If true, use only unpatented methods in */ - /* the bytecode interpreter. */ - /* */ /* doblend :: A boolean which is set if the font should */ /* be blended (this is for GX var). */ /* */ @@ -1260,10 +1331,6 @@ FT_BEGIN_HEADER /* used to hook the debugger for the `ttdebug' utility. */ TT_Interpreter interpreter; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Use unpatented hinting only. */ - FT_Bool unpatented_hinting; -#endif /***********************************************************************/ /* */ @@ -1302,6 +1369,7 @@ FT_BEGIN_HEADER FT_Byte* sbit_table; FT_ULong sbit_table_size; + TT_SbitTableType sbit_table_type; FT_UInt sbit_num_strikes; FT_Byte* kern_table; @@ -1318,12 +1386,12 @@ FT_BEGIN_HEADER FT_ULong horz_metrics_offset; FT_ULong vert_metrics_offset; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* since 2.4.12 */ FT_ULong sph_found_func_flags; /* special functions found */ /* for this face */ FT_Bool sph_compatibility_mode; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ } TT_FaceRec; @@ -1363,7 +1431,7 @@ FT_BEGIN_HEADER { FT_Memory memory; FT_UShort max_points; - FT_UShort max_contours; + FT_Short max_contours; FT_UShort n_points; /* number of points in zone */ FT_Short n_contours; /* number of contours */ @@ -1382,11 +1450,23 @@ FT_BEGIN_HEADER /* handle to execution context */ typedef struct TT_ExecContextRec_* TT_ExecContext; + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Size */ + /* */ + /* <Description> */ + /* A handle to a TrueType size object. */ + /* */ + typedef struct TT_SizeRec_* TT_Size; + + /* glyph loader structure */ typedef struct TT_LoaderRec_ { - FT_Face face; - FT_Size size; + TT_Face face; + TT_Size size; FT_GlyphSlot glyph; FT_GlyphLoader gloader; @@ -1402,7 +1482,6 @@ FT_BEGIN_HEADER FT_Int advance; FT_Int linear; FT_Bool linear_def; - FT_Bool preserve_pps; FT_Vector pp1; FT_Vector pp2; @@ -1429,12 +1508,15 @@ FT_BEGIN_HEADER FT_Byte* cursor; FT_Byte* limit; + /* since version 2.6.2 */ + FT_ListRec composites; + } TT_LoaderRec; FT_END_HEADER -#endif /* __TTTYPES_H__ */ +#endif /* TTTYPES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/t1tables.h b/drivers/freetype/include/freetype/t1tables.h index a14255e5f5..e272324ba2 100644 --- a/drivers/freetype/freetype/include/freetype/t1tables.h +++ b/drivers/freetype/include/freetype/t1tables.h @@ -5,7 +5,7 @@ /* Basic Type 1/Type 2 tables definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __T1TABLES_H__ -#define __T1TABLES_H__ +#ifndef T1TABLES_H_ +#define T1TABLES_H_ #include <ft2build.h> @@ -49,6 +49,26 @@ FT_BEGIN_HEADER /* This section contains the definition of Type 1-specific tables, */ /* including structures related to other PostScript font formats. */ /* */ + /* <Order> */ + /* PS_FontInfoRec */ + /* PS_FontInfo */ + /* PS_PrivateRec */ + /* PS_Private */ + /* */ + /* CID_FaceDictRec */ + /* CID_FaceDict */ + /* CID_FaceInfoRec */ + /* CID_FaceInfo */ + /* */ + /* FT_Has_PS_Glyph_Names */ + /* FT_Get_PS_Font_Info */ + /* FT_Get_PS_Font_Private */ + /* FT_Get_PS_Font_Value */ + /* */ + /* T1_Blend_Flags */ + /* T1_EncodingType */ + /* PS_Dict_Keys */ + /* */ /*************************************************************************/ @@ -190,14 +210,30 @@ FT_BEGIN_HEADER /* given blend dictionary (font info or private). Used to support */ /* Multiple Masters fonts. */ /* */ + /* <Values> */ + /* T1_BLEND_UNDERLINE_POSITION :: */ + /* T1_BLEND_UNDERLINE_THICKNESS :: */ + /* T1_BLEND_ITALIC_ANGLE :: */ + /* T1_BLEND_BLUE_VALUES :: */ + /* T1_BLEND_OTHER_BLUES :: */ + /* T1_BLEND_STANDARD_WIDTH :: */ + /* T1_BLEND_STANDARD_HEIGHT :: */ + /* T1_BLEND_STEM_SNAP_WIDTHS :: */ + /* T1_BLEND_STEM_SNAP_HEIGHTS :: */ + /* T1_BLEND_BLUE_SCALE :: */ + /* T1_BLEND_BLUE_SHIFT :: */ + /* T1_BLEND_FAMILY_BLUES :: */ + /* T1_BLEND_FAMILY_OTHER_BLUES :: */ + /* T1_BLEND_FORCE_BOLD :: */ + /* */ typedef enum T1_Blend_Flags_ { - /*# required fields in a FontInfo blend dictionary */ + /* required fields in a FontInfo blend dictionary */ T1_BLEND_UNDERLINE_POSITION = 0, T1_BLEND_UNDERLINE_THICKNESS, T1_BLEND_ITALIC_ANGLE, - /*# required fields in a Private blend dictionary */ + /* required fields in a Private blend dictionary */ T1_BLEND_BLUE_VALUES, T1_BLEND_OTHER_BLUES, T1_BLEND_STANDARD_WIDTH, @@ -210,15 +246,13 @@ FT_BEGIN_HEADER T1_BLEND_FAMILY_OTHER_BLUES, T1_BLEND_FORCE_BOLD, - /*# never remove */ - T1_BLEND_MAX + T1_BLEND_MAX /* do not remove */ } T1_Blend_Flags; - /* */ - - /*# backwards compatible definitions */ + /* these constants are deprecated; use the corresponding */ + /* `T1_Blend_Flags' values instead */ #define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION #define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS #define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE @@ -235,6 +269,8 @@ FT_BEGIN_HEADER #define t1_blend_force_bold T1_BLEND_FORCE_BOLD #define t1_blend_max T1_BLEND_MAX + /* */ + /* maximum number of Multiple Masters designs, as defined in the spec */ #define T1_MAX_MM_DESIGNS 16 @@ -333,10 +369,17 @@ FT_BEGIN_HEADER /* */ typedef struct CID_FaceDictRec_* CID_FaceDict; - /* */ - - /* backwards-compatible definition */ + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FontDict */ + /* */ + /* <Description> */ + /* This type is equivalent to @CID_FaceDictRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ typedef CID_FaceDictRec CID_FontDict; @@ -449,8 +492,9 @@ FT_BEGIN_HEADER * FreeType error code. 0~means success. * * @note: - * The string pointers within the font info structure are owned by - * the face and don't need to be freed by the caller. + * String pointers within the @PS_FontInfoRec structure are owned by + * the face and don't need to be freed by the caller. Missing entries + * in the font's FontInfo dictionary are represented by NULL pointers. * * If the font's format is not PostScript-based, this function will * return the `FT_Err_Invalid_Argument' error code. @@ -503,6 +547,13 @@ FT_BEGIN_HEADER /* An enumeration describing the `Encoding' entry in a Type 1 */ /* dictionary. */ /* */ + /* <Values> */ + /* T1_ENCODING_TYPE_NONE :: */ + /* T1_ENCODING_TYPE_ARRAY :: */ + /* T1_ENCODING_TYPE_STANDARD :: */ + /* T1_ENCODING_TYPE_ISOLATIN1 :: */ + /* T1_ENCODING_TYPE_EXPERT :: */ + /* */ typedef enum T1_EncodingType_ { T1_ENCODING_TYPE_NONE = 0, @@ -523,6 +574,54 @@ FT_BEGIN_HEADER /* An enumeration used in calls to @FT_Get_PS_Font_Value to identify */ /* the Type~1 dictionary entry to retrieve. */ /* */ + /* <Values> */ + /* PS_DICT_FONT_TYPE :: */ + /* PS_DICT_FONT_MATRIX :: */ + /* PS_DICT_FONT_BBOX :: */ + /* PS_DICT_PAINT_TYPE :: */ + /* PS_DICT_FONT_NAME :: */ + /* PS_DICT_UNIQUE_ID :: */ + /* PS_DICT_NUM_CHAR_STRINGS :: */ + /* PS_DICT_CHAR_STRING_KEY :: */ + /* PS_DICT_CHAR_STRING :: */ + /* PS_DICT_ENCODING_TYPE :: */ + /* PS_DICT_ENCODING_ENTRY :: */ + /* PS_DICT_NUM_SUBRS :: */ + /* PS_DICT_SUBR :: */ + /* PS_DICT_STD_HW :: */ + /* PS_DICT_STD_VW :: */ + /* PS_DICT_NUM_BLUE_VALUES :: */ + /* PS_DICT_BLUE_VALUE :: */ + /* PS_DICT_BLUE_FUZZ :: */ + /* PS_DICT_NUM_OTHER_BLUES :: */ + /* PS_DICT_OTHER_BLUE :: */ + /* PS_DICT_NUM_FAMILY_BLUES :: */ + /* PS_DICT_FAMILY_BLUE :: */ + /* PS_DICT_NUM_FAMILY_OTHER_BLUES :: */ + /* PS_DICT_FAMILY_OTHER_BLUE :: */ + /* PS_DICT_BLUE_SCALE :: */ + /* PS_DICT_BLUE_SHIFT :: */ + /* PS_DICT_NUM_STEM_SNAP_H :: */ + /* PS_DICT_STEM_SNAP_H :: */ + /* PS_DICT_NUM_STEM_SNAP_V :: */ + /* PS_DICT_STEM_SNAP_V :: */ + /* PS_DICT_FORCE_BOLD :: */ + /* PS_DICT_RND_STEM_UP :: */ + /* PS_DICT_MIN_FEATURE :: */ + /* PS_DICT_LEN_IV :: */ + /* PS_DICT_PASSWORD :: */ + /* PS_DICT_LANGUAGE_GROUP :: */ + /* PS_DICT_VERSION :: */ + /* PS_DICT_NOTICE :: */ + /* PS_DICT_FULL_NAME :: */ + /* PS_DICT_FAMILY_NAME :: */ + /* PS_DICT_WEIGHT :: */ + /* PS_DICT_IS_FIXED_PITCH :: */ + /* PS_DICT_UNDERLINE_POSITION :: */ + /* PS_DICT_UNDERLINE_THICKNESS :: */ + /* PS_DICT_FS_TYPE :: */ + /* PS_DICT_ITALIC_ANGLE :: */ + /* */ typedef enum PS_Dict_Keys_ { /* conventionally in the font dictionary */ @@ -656,7 +755,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1TABLES_H__ */ +#endif /* T1TABLES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ttnameid.h b/drivers/freetype/include/freetype/ttnameid.h index 173f88c950..ce707f1645 100644 --- a/drivers/freetype/freetype/include/freetype/ttnameid.h +++ b/drivers/freetype/include/freetype/ttnameid.h @@ -4,7 +4,7 @@ /* */ /* TrueType name ID definitions (specification only). */ /* */ -/* Copyright 1996-2004, 2006-2008, 2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTNAMEID_H__ -#define __TTNAMEID_H__ +#ifndef TTNAMEID_H_ +#define TTNAMEID_H_ #include <ft2build.h> @@ -321,7 +321,7 @@ FT_BEGIN_HEADER /* */ /* The canonical source for the Apple assigned Language ID's is at */ /* */ - /* https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html */ /* */ #define TT_MAC_LANGID_ENGLISH 0 #define TT_MAC_LANGID_FRENCH 1 @@ -470,26 +470,26 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_ARABIC_GENERAL 0x0001 #define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 #define TT_MS_LANGID_ARABIC_IRAQ 0x0801 -#define TT_MS_LANGID_ARABIC_EGYPT 0x0c01 +#define TT_MS_LANGID_ARABIC_EGYPT 0x0C01 #define TT_MS_LANGID_ARABIC_LIBYA 0x1001 #define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 #define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 -#define TT_MS_LANGID_ARABIC_TUNISIA 0x1c01 +#define TT_MS_LANGID_ARABIC_TUNISIA 0x1C01 #define TT_MS_LANGID_ARABIC_OMAN 0x2001 #define TT_MS_LANGID_ARABIC_YEMEN 0x2401 #define TT_MS_LANGID_ARABIC_SYRIA 0x2801 -#define TT_MS_LANGID_ARABIC_JORDAN 0x2c01 +#define TT_MS_LANGID_ARABIC_JORDAN 0x2C01 #define TT_MS_LANGID_ARABIC_LEBANON 0x3001 #define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 #define TT_MS_LANGID_ARABIC_UAE 0x3801 -#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3c01 +#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3C01 #define TT_MS_LANGID_ARABIC_QATAR 0x4001 #define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 #define TT_MS_LANGID_CATALAN_SPAIN 0x0403 #define TT_MS_LANGID_CHINESE_GENERAL 0x0004 #define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 #define TT_MS_LANGID_CHINESE_PRC 0x0804 -#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0c04 +#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0C04 #define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 #if 1 /* this looks like the correct value */ @@ -507,7 +507,7 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_DANISH_DENMARK 0x0406 #define TT_MS_LANGID_GERMAN_GERMANY 0x0407 #define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 -#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0c07 +#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0C07 #define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 #define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 #define TT_MS_LANGID_GREEK_GREECE 0x0408 @@ -520,69 +520,69 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 #define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 #define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 -#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0c09 +#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0C09 #define TT_MS_LANGID_ENGLISH_CANADA 0x1009 #define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 #define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 -#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1c09 +#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1C09 #define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 #define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 #define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 -#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2c09 +#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2C09 #define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 #define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 #define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 -#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3c09 +#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3C09 #define TT_MS_LANGID_ENGLISH_INDIA 0x4009 #define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 #define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 -#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040a -#define TT_MS_LANGID_SPANISH_MEXICO 0x080a -#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0c0a -#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100a -#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140a -#define TT_MS_LANGID_SPANISH_PANAMA 0x180a -#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1c0a -#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200a -#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240a -#define TT_MS_LANGID_SPANISH_PERU 0x280a -#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2c0a -#define TT_MS_LANGID_SPANISH_ECUADOR 0x300a -#define TT_MS_LANGID_SPANISH_CHILE 0x340a -#define TT_MS_LANGID_SPANISH_URUGUAY 0x380a -#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3c0a -#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400a -#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440a -#define TT_MS_LANGID_SPANISH_HONDURAS 0x480a -#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4c0a -#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500a -#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540a +#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040A +#define TT_MS_LANGID_SPANISH_MEXICO 0x080A +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0C0A +#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100A +#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140A +#define TT_MS_LANGID_SPANISH_PANAMA 0x180A +#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1C0A +#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200A +#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240A +#define TT_MS_LANGID_SPANISH_PERU 0x280A +#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2C0A +#define TT_MS_LANGID_SPANISH_ECUADOR 0x300A +#define TT_MS_LANGID_SPANISH_CHILE 0x340A +#define TT_MS_LANGID_SPANISH_URUGUAY 0x380A +#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3C0A +#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400A +#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440A +#define TT_MS_LANGID_SPANISH_HONDURAS 0x480A +#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4C0A +#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500A +#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540A /* The following ID blatantly violate MS specs by using a */ /* sublanguage > 0x1F. */ -#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40aU -#define TT_MS_LANGID_FINNISH_FINLAND 0x040b -#define TT_MS_LANGID_FRENCH_FRANCE 0x040c -#define TT_MS_LANGID_FRENCH_BELGIUM 0x080c -#define TT_MS_LANGID_FRENCH_CANADA 0x0c0c -#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100c -#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140c -#define TT_MS_LANGID_FRENCH_MONACO 0x180c -#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1c0c -#define TT_MS_LANGID_FRENCH_REUNION 0x200c -#define TT_MS_LANGID_FRENCH_CONGO 0x240c +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40AU +#define TT_MS_LANGID_FINNISH_FINLAND 0x040B +#define TT_MS_LANGID_FRENCH_FRANCE 0x040C +#define TT_MS_LANGID_FRENCH_BELGIUM 0x080C +#define TT_MS_LANGID_FRENCH_CANADA 0x0C0C +#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100C +#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140C +#define TT_MS_LANGID_FRENCH_MONACO 0x180C +#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1C0C +#define TT_MS_LANGID_FRENCH_REUNION 0x200C +#define TT_MS_LANGID_FRENCH_CONGO 0x240C /* which was formerly: */ #define TT_MS_LANGID_FRENCH_ZAIRE TT_MS_LANGID_FRENCH_CONGO -#define TT_MS_LANGID_FRENCH_SENEGAL 0x280c -#define TT_MS_LANGID_FRENCH_CAMEROON 0x2c0c -#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300c -#define TT_MS_LANGID_FRENCH_MALI 0x340c -#define TT_MS_LANGID_FRENCH_MOROCCO 0x380c -#define TT_MS_LANGID_FRENCH_HAITI 0x3c0c - /* and another violation of the spec (see 0xE40aU) */ -#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40cU -#define TT_MS_LANGID_HEBREW_ISRAEL 0x040d -#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040e -#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040f +#define TT_MS_LANGID_FRENCH_SENEGAL 0x280C +#define TT_MS_LANGID_FRENCH_CAMEROON 0x2C0C +#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300C +#define TT_MS_LANGID_FRENCH_MALI 0x340C +#define TT_MS_LANGID_FRENCH_MOROCCO 0x380C +#define TT_MS_LANGID_FRENCH_HAITI 0x3C0C + /* and another violation of the spec (see 0xE40AU) */ +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40CU +#define TT_MS_LANGID_HEBREW_ISRAEL 0x040D +#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040E +#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040F #define TT_MS_LANGID_ITALIAN_ITALY 0x0410 #define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 #define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 @@ -600,27 +600,27 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 #define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 #define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 -#define TT_MS_LANGID_CROATIAN_CROATIA 0x041a -#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081a -#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0c1a +#define TT_MS_LANGID_CROATIAN_CROATIA 0x041A +#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081A +#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0C1A #if 0 /* this used to be this value, but it looks like we were wrong */ -#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101a +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101A #else /* current sources say */ -#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101a -#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141a +#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101A +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141A /* and XPsp2 Platform SDK added (2004-07-26) */ /* Names are shortened to be significant within 40 chars. */ -#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181a -#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181a +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181A +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181A #endif -#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041b -#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041c -#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041d -#define TT_MS_LANGID_SWEDISH_FINLAND 0x081d -#define TT_MS_LANGID_THAI_THAILAND 0x041e -#define TT_MS_LANGID_TURKISH_TURKEY 0x041f +#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041B +#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041C +#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041D +#define TT_MS_LANGID_SWEDISH_FINLAND 0x081D +#define TT_MS_LANGID_THAI_THAILAND 0x041E +#define TT_MS_LANGID_TURKISH_TURKEY 0x041F #define TT_MS_LANGID_URDU_PAKISTAN 0x0420 #define TT_MS_LANGID_URDU_INDIA 0x0820 #define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 @@ -633,13 +633,13 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 #define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 #define TT_MS_LANGID_FARSI_IRAN 0x0429 -#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042a -#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042b -#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042c -#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082c -#define TT_MS_LANGID_BASQUE_SPAIN 0x042d -#define TT_MS_LANGID_SORBIAN_GERMANY 0x042e -#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042f +#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042A +#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042B +#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042C +#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082C +#define TT_MS_LANGID_BASQUE_SPAIN 0x042D +#define TT_MS_LANGID_SORBIAN_GERMANY 0x042E +#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042F #define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 #define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 #define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 @@ -650,32 +650,32 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 #define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 #define TT_MS_LANGID_HINDI_INDIA 0x0439 -#define TT_MS_LANGID_MALTESE_MALTA 0x043a +#define TT_MS_LANGID_MALTESE_MALTA 0x043A /* Added by XPsp2 Platform SDK (2004-07-26) */ -#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043b -#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083b -#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3b -#define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103b -#define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143b -#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183b -#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3b -#define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203b -#define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243b +#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043B +#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083B +#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3B +#define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103B +#define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143B +#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183B +#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3B +#define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203B +#define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243B /* ... and we also keep our old identifier... */ -#define TT_MS_LANGID_SAAMI_LAPONIA 0x043b +#define TT_MS_LANGID_SAAMI_LAPONIA 0x043B #if 0 /* this seems to be a previous inversion */ -#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c -#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C #else -#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c -#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C #endif -#define TT_MS_LANGID_YIDDISH_GERMANY 0x043d -#define TT_MS_LANGID_MALAY_MALAYSIA 0x043e -#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083e -#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043f +#define TT_MS_LANGID_YIDDISH_GERMANY 0x043D +#define TT_MS_LANGID_MALAY_MALAYSIA 0x043E +#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083E +#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043F #define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440 /* alias declared in Windows 2000 */ #define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ @@ -693,12 +693,12 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_GUJARATI_INDIA 0x0447 #define TT_MS_LANGID_ORIYA_INDIA 0x0448 #define TT_MS_LANGID_TAMIL_INDIA 0x0449 -#define TT_MS_LANGID_TELUGU_INDIA 0x044a -#define TT_MS_LANGID_KANNADA_INDIA 0x044b -#define TT_MS_LANGID_MALAYALAM_INDIA 0x044c -#define TT_MS_LANGID_ASSAMESE_INDIA 0x044d -#define TT_MS_LANGID_MARATHI_INDIA 0x044e -#define TT_MS_LANGID_SANSKRIT_INDIA 0x044f +#define TT_MS_LANGID_TELUGU_INDIA 0x044A +#define TT_MS_LANGID_KANNADA_INDIA 0x044B +#define TT_MS_LANGID_MALAYALAM_INDIA 0x044C +#define TT_MS_LANGID_ASSAMESE_INDIA 0x044D +#define TT_MS_LANGID_MARATHI_INDIA 0x044E +#define TT_MS_LANGID_SANSKRIT_INDIA 0x044F #define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 #define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN 0x0850 #define TT_MS_LANGID_TIBETAN_CHINA 0x0451 @@ -732,13 +732,13 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 #define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 /* Missing a LCID for Sindhi in Devanagari script */ -#define TT_MS_LANGID_SYRIAC_SYRIA 0x045a -#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045b -#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045c -#define TT_MS_LANGID_INUKTITUT_CANADA 0x045d -#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045e -#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045f -#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085f +#define TT_MS_LANGID_SYRIAC_SYRIA 0x045A +#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045B +#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045C +#define TT_MS_LANGID_INUKTITUT_CANADA 0x045D +#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045E +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045F +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085F /* Missing a LCID for Tifinagh script */ #define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */ @@ -758,15 +758,15 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 #define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 #define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 -#define TT_MS_LANGID_YORUBA_NIGERIA 0x046a -#define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046b -#define TT_MS_LANGID_QUECHUA_ECUADOR 0x086b -#define TT_MS_LANGID_QUECHUA_PERU 0x0c6b -#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046c +#define TT_MS_LANGID_YORUBA_NIGERIA 0x046A +#define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046B +#define TT_MS_LANGID_QUECHUA_ECUADOR 0x086B +#define TT_MS_LANGID_QUECHUA_PERU 0x0C6B +#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046C /* Also spelled by XPsp2 Platform SDK (2004-07-26) */ #define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ TT_MS_LANGID_SEPEDI_SOUTH_AFRICA - /* language codes 0x046d, 0x046e and 0x046f are (still) unknown. */ + /* language codes 0x046D, 0x046E and 0x046F are (still) unknown. */ #define TT_MS_LANGID_IGBO_NIGERIA 0x0470 #define TT_MS_LANGID_KANURI_NIGERIA 0x0471 #define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 @@ -783,12 +783,12 @@ FT_BEGIN_HEADER /* studying). */ #define TT_MS_LANGID_YI_CHINA 0x0478 #define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 - /* language codes from 0x047a to 0x047f are (still) unknown. */ + /* language codes from 0x047A to 0x047F are (still) unknown. */ #define TT_MS_LANGID_UIGHUR_CHINA 0x0480 #define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 #if 0 /* not deemed useful for fonts */ -#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04ff +#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04FF #endif @@ -1208,7 +1208,7 @@ FT_BEGIN_HEADER /* */ /* Here some alias #defines in order to be clearer. */ /* */ - /* These are not always #defined to stay within the 31~character limit */ + /* These are not always #defined to stay within the 31~character limit, */ /* which some compilers have. */ /* */ /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ @@ -1231,7 +1231,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTNAMEID_H__ */ +#endif /* TTNAMEID_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/tttables.h b/drivers/freetype/include/freetype/tttables.h index fe07117b0b..1c075dcf66 100644 --- a/drivers/freetype/freetype/include/freetype/tttables.h +++ b/drivers/freetype/include/freetype/tttables.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType tables definitions and interface */ /* (specification only). */ /* */ -/* Copyright 1996-2005, 2008-2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTTABLES_H__ -#define __TTTABLES_H__ +#ifndef TTTABLES_H_ +#define TTTABLES_H_ #include <ft2build.h> @@ -48,6 +48,25 @@ FT_BEGIN_HEADER /* This section contains the definition of TrueType-specific tables */ /* as well as some routines used to access and process them. */ /* */ + /* <Order> */ + /* TT_Header */ + /* TT_HoriHeader */ + /* TT_VertHeader */ + /* TT_OS2 */ + /* TT_Postscript */ + /* TT_PCLT */ + /* TT_MaxProfile */ + /* */ + /* FT_Sfnt_Tag */ + /* FT_Get_Sfnt_Table */ + /* FT_Load_Sfnt_Table */ + /* FT_Sfnt_Table_Info */ + /* */ + /* FT_Get_CMap_Language_ID */ + /* FT_Get_CMap_Format */ + /* */ + /* FT_PARAM_TAG_UNPATENTED_HINTING */ + /* */ /*************************************************************************/ @@ -170,8 +189,8 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields which */ - /* are different. */ + /* be identical except for the names of their fields, */ + /* which are different. */ /* */ /* This ensures that a single function in the `ttload' */ /* module is able to read both the horizontal and vertical */ @@ -296,8 +315,8 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields which */ - /* are different. */ + /* be identical except for the names of their fields, */ + /* which are different. */ /* */ /* This ensures that a single function in the `ttload' */ /* module is able to read both the horizontal and vertical */ @@ -340,12 +359,11 @@ FT_BEGIN_HEADER /* TT_OS2 */ /* */ /* <Description> */ - /* A structure used to model a TrueType OS/2 table. This is the long */ - /* table version. All fields comply to the TrueType specification. */ + /* A structure used to model a TrueType OS/2 table. All fields */ + /* comply to the OpenType specification. */ /* */ - /* Note that we now support old Mac fonts which do not include an */ - /* OS/2 table. In this case, the `version' field is always set to */ - /* 0xFFFF. */ + /* Note that we now support old Mac fonts that do not include an OS/2 */ + /* table. In this case, the `version' field is always set to 0xFFFF. */ /* */ typedef struct TT_OS2_ { @@ -353,7 +371,7 @@ FT_BEGIN_HEADER FT_Short xAvgCharWidth; FT_UShort usWeightClass; FT_UShort usWidthClass; - FT_Short fsType; + FT_UShort fsType; FT_Short ySubscriptXSize; FT_Short ySubscriptYSize; FT_Short ySubscriptXOffset; @@ -384,12 +402,12 @@ FT_BEGIN_HEADER FT_UShort usWinAscent; FT_UShort usWinDescent; - /* only version 1 tables: */ + /* only version 1 and higher: */ FT_ULong ulCodePageRange1; /* Bits 0-31 */ FT_ULong ulCodePageRange2; /* Bits 32-63 */ - /* only version 2 tables: */ + /* only version 2 and higher: */ FT_Short sxHeight; FT_Short sCapHeight; @@ -397,6 +415,11 @@ FT_BEGIN_HEADER FT_UShort usBreakChar; FT_UShort usMaxContext; + /* only version 5 and higher: */ + + FT_UShort usLowerOpticalPointSize; /* in twips (1/20th points) */ + FT_UShort usUpperOpticalPointSize; /* in twips (1/20th points) */ + } TT_OS2; @@ -465,7 +488,7 @@ FT_BEGIN_HEADER /* TT_MaxProfile */ /* */ /* <Description> */ - /* The maximum profile is a table containing many max values which */ + /* The maximum profile is a table containing many max values, which */ /* can be used to pre-allocate arrays. This ensures that no memory */ /* allocation occurs during a glyph load. */ /* */ @@ -555,21 +578,44 @@ FT_BEGIN_HEADER /* An enumeration used to specify the index of an SFNT table. */ /* Used in the @FT_Get_Sfnt_Table API function. */ /* */ + /* <Values> */ + /* FT_SFNT_HEAD :: To access the font's @TT_Header structure. */ + /* */ + /* FT_SFNT_MAXP :: To access the font's @TT_MaxProfile structure. */ + /* */ + /* FT_SFNT_OS2 :: To access the font's @TT_OS2 structure. */ + /* */ + /* FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure. */ + /* */ + /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader structure. */ + /* */ + /* FT_SFNT_POST :: To access the font's @TT_Postscript structure. */ + /* */ + /* FT_SFNT_PCLT :: To access the font's @TT_PCLT structure. */ + /* */ typedef enum FT_Sfnt_Tag_ { - ft_sfnt_head = 0, /* TT_Header */ - ft_sfnt_maxp = 1, /* TT_MaxProfile */ - ft_sfnt_os2 = 2, /* TT_OS2 */ - ft_sfnt_hhea = 3, /* TT_HoriHeader */ - ft_sfnt_vhea = 4, /* TT_VertHeader */ - ft_sfnt_post = 5, /* TT_Postscript */ - ft_sfnt_pclt = 6, /* TT_PCLT */ + FT_SFNT_HEAD, + FT_SFNT_MAXP, + FT_SFNT_OS2, + FT_SFNT_HHEA, + FT_SFNT_VHEA, + FT_SFNT_POST, + FT_SFNT_PCLT, - sfnt_max /* internal end mark */ + FT_SFNT_MAX } FT_Sfnt_Tag; - /* */ + /* these constants are deprecated; use the corresponding `FT_Sfnt_Tag' */ + /* values instead */ +#define ft_sfnt_head FT_SFNT_HEAD +#define ft_sfnt_maxp FT_SFNT_MAXP +#define ft_sfnt_os2 FT_SFNT_OS2 +#define ft_sfnt_hhea FT_SFNT_HHEA +#define ft_sfnt_vhea FT_SFNT_VHEA +#define ft_sfnt_post FT_SFNT_POST +#define ft_sfnt_pclt FT_SFNT_PCLT /*************************************************************************/ @@ -607,7 +653,7 @@ FT_BEGIN_HEADER /* */ /* */ /* vert_header = */ - /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, ft_sfnt_vhea ); */ + /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, FT_SFNT_VHEA ); */ /* } */ /* */ FT_EXPORT( void* ) @@ -672,6 +718,12 @@ FT_BEGIN_HEADER * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); * if ( error ) { ... could not load table ... } * } + * + * Note that structures like @TT_Header or @TT_OS2 can't be used with + * this function; they are limited to @FT_Get_Sfnt_Table. Reason is that + * those structures depend on the processor architecture, with varying + * size (e.g. 32bit vs. 64bit) or order (big endian vs. little endian). + * */ FT_EXPORT( FT_Error ) FT_Load_Sfnt_Table( FT_Face face, @@ -730,7 +782,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Return TrueType/sfnt specific cmap language ID. Definitions of */ - /* language ID values are in `freetype/ttnameid.h'. */ + /* language ID values are in `ttnameid.h'. */ /* */ /* <Input> */ /* charmap :: */ @@ -771,7 +823,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTTABLES_H__ */ +#endif /* TTTABLES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/tttags.h b/drivers/freetype/include/freetype/tttags.h index be8c524edb..f3c9aa5fc7 100644 --- a/drivers/freetype/freetype/include/freetype/tttags.h +++ b/drivers/freetype/include/freetype/tttags.h @@ -4,7 +4,7 @@ /* */ /* Tags for TrueType and OpenType tables (specification only). */ /* */ -/* Copyright 1996-2001, 2004, 2005, 2007, 2008, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTAGS_H__ -#define __TTAGS_H__ +#ifndef TTAGS_H_ +#define TTAGS_H_ #include <ft2build.h> @@ -88,6 +88,7 @@ FT_BEGIN_HEADER #define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) #define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) #define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) +#define TTAG_sbix FT_MAKE_TAG( 's', 'b', 'i', 'x' ) #define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) #define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) #define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) @@ -99,11 +100,12 @@ FT_BEGIN_HEADER #define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) #define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) #define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) +#define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' ) FT_END_HEADER -#endif /* __TTAGS_H__ */ +#endif /* TTAGS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/include/freetype/ttunpat.h b/drivers/freetype/include/freetype/ttunpat.h index a0162759b7..ca4676baf8 100644 --- a/drivers/freetype/freetype/include/freetype/ttunpat.h +++ b/drivers/freetype/include/freetype/ttunpat.h @@ -2,9 +2,10 @@ /* */ /* ttunpat.h */ /* */ -/* Definitions for the unpatented TrueType hinting system */ +/* Definitions for the unpatented TrueType hinting system. */ +/* Obsolete, retained for backwards compatibility. */ /* */ -/* Copyright 2003, 2006 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* Written by Graham Asher <graham.asher@btinternet.com> */ @@ -18,8 +19,8 @@ /***************************************************************************/ -#ifndef __TTUNPAT_H__ -#define __TTUNPAT_H__ +#ifndef TTUNPAT_H_ +#define TTUNPAT_H_ #include <ft2build.h> @@ -41,19 +42,22 @@ FT_BEGIN_HEADER * FT_PARAM_TAG_UNPATENTED_HINTING * * @description: - * A constant used as the tag of an @FT_Parameter structure to indicate - * that unpatented methods only should be used by the TrueType bytecode - * interpreter for a typeface opened by @FT_Open_Face. + * Deprecated. + * + * Previously: A constant used as the tag of an @FT_Parameter structure to + * indicate that unpatented methods only should be used by the TrueType + * bytecode interpreter for a typeface opened by @FT_Open_Face. * */ #define FT_PARAM_TAG_UNPATENTED_HINTING FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) - /* */ + /* */ + FT_END_HEADER -#endif /* __TTUNPAT_H__ */ +#endif /* TTUNPAT_H_ */ /* END */ diff --git a/drivers/freetype/ft2build.h b/drivers/freetype/include/ft2build.h index 5137b50f38..1e8a9b4994 100644 --- a/drivers/freetype/ft2build.h +++ b/drivers/freetype/include/ft2build.h @@ -3,9 +3,8 @@ /* ft2build.h */ /* */ /* FreeType 2 build and setup macros. */ -/* (Generic version) */ /* */ -/* Copyright 1996-2001, 2003, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,25 +16,28 @@ /***************************************************************************/ - /* - * This is a development version of <ft2build.h> that is used - * to build the library in debug mode. Its only difference with - * the reference is that it forces the use of the local `ftoption.h' - * which contains different settings for all configuration macros. - * - * To use it, you must define the environment variable FT2_BUILD_INCLUDE - * to point to the directory containing these two files (`ft2build.h' and - * `ftoption.h'), then invoke Jam as usual. - */ + /*************************************************************************/ + /* */ + /* This is the `entry point' for FreeType header file inclusions. It is */ + /* the only header file which should be included directly; all other */ + /* FreeType header files should be accessed with macro names (after */ + /* including `ft2build.h'). */ + /* */ + /* A typical example is */ + /* */ + /* #include <ft2build.h> */ + /* #include FT_FREETYPE_H */ + /* */ + /*************************************************************************/ -#ifndef __FT2_BUILD_DEVEL_H__ -#define __FT2_BUILD_DEVEL_H__ -#define FT_CONFIG_OPTIONS_H <ftoption.h> +#ifndef FT2BUILD_H_ +#define FT2BUILD_H_ + #define FT2_BUILD_LIBRARY -#include <freetype/include/freetype/config/ftheader.h> +#include <freetype/config/ftheader.h> -#endif /* __FT2_BUILD_DEVEL_H__ */ +#endif /* FT2BUILD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/Jamfile b/drivers/freetype/src/Jamfile index 76ee0f46e6..ebc036983e 100644 --- a/drivers/freetype/freetype/src/Jamfile +++ b/drivers/freetype/src/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src Jamfile # -# Copyright 2001, 2002 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -11,12 +11,6 @@ SubDir FT2_TOP $(FT2_SRC_DIR) ; -# The file <freetype/internal/internal.h> is used to define macros that are -# later used in #include statements. It needs to be parsed in order to -# record these definitions. -# -HDRMACRO [ FT2_SubDir $(FT2_INCLUDE_DIR) internal internal.h ] ; - for xx in $(FT2_COMPONENTS) { SubInclude FT2_TOP $(FT2_SRC_DIR) $(xx) ; diff --git a/drivers/freetype/freetype/src/autofit/Jamfile b/drivers/freetype/src/autofit/Jamfile index 2714765b5b..638b229724 100644 --- a/drivers/freetype/freetype/src/autofit/Jamfile +++ b/drivers/freetype/src/autofit/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/autofit Jamfile # -# Copyright 2003, 2004, 2005, 2006, 2007, 2009 by +# Copyright 2003-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,11 +17,25 @@ SubDir FT2_TOP src autofit ; # define FT2_AUTOFIT2 to enable experimental latin hinter replacement if $(FT2_AUTOFIT2) { - DEFINES += FT_OPTION_AUTOFIT2 ; + CCFLAGS += FT_OPTION_AUTOFIT2 ; } if $(FT2_MULTI) { - _sources = afangles afglobal afhints aflatin afcjk afindic afloader afmodule afdummy afwarp afpic ; + _sources = afangles + afblue + afcjk + afdummy + afglobal + afhints + afindic + aflatin + afloader + afmodule + afpic + afranges + afshaper + afwarp + ; if $(FT2_AUTOFIT2) { diff --git a/drivers/freetype/freetype/src/autofit/afangles.c b/drivers/freetype/src/autofit/afangles.c index b44a5ba2c6..b856e57a8b 100644 --- a/drivers/freetype/freetype/src/autofit/afangles.c +++ b/drivers/freetype/src/autofit/afangles.c @@ -5,7 +5,7 @@ /* Routines used to compute vector angles with limited accuracy */ /* and very high speed. It also contains sorting routines (body). */ /* */ -/* Copyright 2003-2006, 2011-2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,66 +20,6 @@ #include "aftypes.h" -#if 0 - - FT_LOCAL_DEF( FT_Int ) - af_corner_is_flat( FT_Pos x_in, - FT_Pos y_in, - FT_Pos x_out, - FT_Pos y_out ) - { - FT_Pos ax = x_in; - FT_Pos ay = y_in; - - FT_Pos d_in, d_out, d_corner; - - - if ( ax < 0 ) - ax = -ax; - if ( ay < 0 ) - ay = -ay; - d_in = ax + ay; - - ax = x_out; - if ( ax < 0 ) - ax = -ax; - ay = y_out; - if ( ay < 0 ) - ay = -ay; - d_out = ax + ay; - - ax = x_out + x_in; - if ( ax < 0 ) - ax = -ax; - ay = y_out + y_in; - if ( ay < 0 ) - ay = -ay; - d_corner = ax + ay; - - return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); - } - - - FT_LOCAL_DEF( FT_Int ) - af_corner_orientation( FT_Pos x_in, - FT_Pos y_in, - FT_Pos x_out, - FT_Pos y_out ) - { - FT_Pos delta; - - - delta = x_in * y_out - y_in * x_out; - - if ( delta == 0 ) - return 0; - else - return 1 - 2 * ( delta < 0 ); - } - -#endif /* 0 */ - - /* * We are not using `af_angle_atan' anymore, but we keep the source * code below just in case... @@ -319,7 +259,7 @@ sum += table[j].org; table[j].org = 0; } - table[cur_idx].org = sum / j; + table[cur_idx].org = sum / (FT_Pos)j; if ( i < *count - 1 ) { diff --git a/drivers/freetype/freetype/src/autofit/afangles.h b/drivers/freetype/src/autofit/afangles.h index f33f9e108e..f33f9e108e 100644 --- a/drivers/freetype/freetype/src/autofit/afangles.h +++ b/drivers/freetype/src/autofit/afangles.h diff --git a/drivers/freetype/src/autofit/afblue.c b/drivers/freetype/src/autofit/afblue.c new file mode 100644 index 0000000000..95786ed6f2 --- /dev/null +++ b/drivers/freetype/src/autofit/afblue.c @@ -0,0 +1,459 @@ +/* This file has been generated by the Perl script `afblue.pl', */ +/* using data from file `afblue.dat'. */ + +/***************************************************************************/ +/* */ +/* afblue.c */ +/* */ +/* Auto-fitter data for blue strings (body). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "aftypes.h" + + + FT_LOCAL_ARRAY_DEF( char ) + af_blue_strings[] = + { + /* */ + '\xD8', '\xA7', ' ', '\xD8', '\xA5', ' ', '\xD9', '\x84', ' ', '\xD9', '\x83', ' ', '\xD8', '\xB7', ' ', '\xD8', '\xB8', /* ا إ ل ك ط ظ */ + '\0', + '\xD8', '\xAA', ' ', '\xD8', '\xAB', ' ', '\xD8', '\xB7', ' ', '\xD8', '\xB8', ' ', '\xD9', '\x83', /* ت ث ط ظ ك */ + '\0', + '\xD9', '\x80', /* ـ */ + '\0', + '\xD4', '\xB1', ' ', '\xD5', '\x84', ' ', '\xD5', '\x92', ' ', '\xD5', '\x93', ' ', '\xD4', '\xB2', ' ', '\xD4', '\xB3', ' ', '\xD4', '\xB4', ' ', '\xD5', '\x95', /* Ա Մ Ւ Փ Բ Գ Դ Օ */ + '\0', + '\xD5', '\x92', ' ', '\xD5', '\x88', ' ', '\xD5', '\x93', ' ', '\xD5', '\x83', ' ', '\xD5', '\x87', ' ', '\xD5', '\x8D', ' ', '\xD5', '\x8F', ' ', '\xD5', '\x95', /* Ւ Ո Փ Ճ Շ Ս Տ Օ */ + '\0', + '\xD5', '\xA5', ' ', '\xD5', '\xA7', ' ', '\xD5', '\xAB', ' ', '\xD5', '\xB4', ' ', '\xD5', '\xBE', ' ', '\xD6', '\x83', ' ', '\xD6', '\x86', ' ', '\xD6', '\x83', /* ե է ի մ վ փ ֆ փ */ + '\0', + '\xD5', '\xA1', ' ', '\xD5', '\xB5', ' ', '\xD6', '\x82', ' ', '\xD5', '\xBD', ' ', '\xD5', '\xA3', ' ', '\xD5', '\xBB', ' ', '\xD6', '\x80', ' ', '\xD6', '\x85', /* ա յ ւ ս գ ջ ր օ */ + '\0', + '\xD5', '\xB0', ' ', '\xD5', '\xB8', ' ', '\xD5', '\xB3', ' ', '\xD5', '\xA1', ' ', '\xD5', '\xA5', ' ', '\xD5', '\xAE', ' ', '\xD5', '\xBD', ' ', '\xD6', '\x85', /* հ ո ճ ա ե ծ ս օ */ + '\0', + '\xD5', '\xA2', ' ', '\xD5', '\xA8', ' ', '\xD5', '\xAB', ' ', '\xD5', '\xAC', ' ', '\xD5', '\xB2', ' ', '\xD5', '\xBA', ' ', '\xD6', '\x83', ' ', '\xD6', '\x81', /* բ ը ի լ ղ պ փ ց */ + '\0', + '\xE0', '\xA6', '\x85', ' ', '\xE0', '\xA6', '\xA1', ' ', '\xE0', '\xA6', '\xA4', ' ', '\xE0', '\xA6', '\xA8', ' ', '\xE0', '\xA6', '\xAC', ' ', '\xE0', '\xA6', '\xAD', ' ', '\xE0', '\xA6', '\xB2', ' ', '\xE0', '\xA6', '\x95', /* অ ড ত ন ব ভ ল ক */ + '\0', + '\xE0', '\xA6', '\x87', ' ', '\xE0', '\xA6', '\x9F', ' ', '\xE0', '\xA6', '\xA0', ' ', '\xE0', '\xA6', '\xBF', ' ', '\xE0', '\xA7', '\x80', ' ', '\xE0', '\xA7', '\x88', ' ', '\xE0', '\xA7', '\x97', /* ই ট ঠ ি ী ৈ ৗ */ + '\0', + '\xE0', '\xA6', '\x93', ' ', '\xE0', '\xA6', '\x8F', ' ', '\xE0', '\xA6', '\xA1', ' ', '\xE0', '\xA6', '\xA4', ' ', '\xE0', '\xA6', '\xA8', ' ', '\xE0', '\xA6', '\xAC', ' ', '\xE0', '\xA6', '\xB2', ' ', '\xE0', '\xA6', '\x95', /* ও এ ড ত ন ব ল ক */ + '\0', + '\xE1', '\x8F', '\x86', ' ', '\xE1', '\x8E', '\xBB', ' ', '\xE1', '\x8E', '\xAC', ' ', '\xE1', '\x8F', '\x83', ' ', '\xE1', '\x8E', '\xA4', ' ', '\xE1', '\x8F', '\xA3', ' ', '\xE1', '\x8E', '\xA6', ' ', '\xE1', '\x8F', '\x95', /* Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ */ + '\0', + '\xEA', '\xAE', '\x92', ' ', '\xEA', '\xAE', '\xA4', ' ', '\xEA', '\xAE', '\xB6', ' ', '\xEA', '\xAD', '\xB4', ' ', '\xEA', '\xAD', '\xBE', ' ', '\xEA', '\xAE', '\x97', ' ', '\xEA', '\xAE', '\x9D', ' ', '\xEA', '\xAE', '\xBF', /* ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ */ + '\0', + '\xEA', '\xAE', '\x96', ' ', '\xEA', '\xAD', '\xBC', ' ', '\xEA', '\xAE', '\x93', ' ', '\xEA', '\xAE', '\xA0', ' ', '\xEA', '\xAE', '\xB3', ' ', '\xEA', '\xAD', '\xB6', ' ', '\xEA', '\xAE', '\xA5', ' ', '\xEA', '\xAE', '\xBB', /* ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ */ + '\0', + '\xE1', '\x8F', '\xB8', ' ', '\xEA', '\xAE', '\x90', ' ', '\xEA', '\xAD', '\xB9', ' ', '\xEA', '\xAD', '\xBB', /* ᏸ ꮐ ꭹ ꭻ */ + '\0', + '\xD0', '\x91', ' ', '\xD0', '\x92', ' ', '\xD0', '\x95', ' ', '\xD0', '\x9F', ' ', '\xD0', '\x97', ' ', '\xD0', '\x9E', ' ', '\xD0', '\xA1', ' ', '\xD0', '\xAD', /* Б В Е П З О С Э */ + '\0', + '\xD0', '\x91', ' ', '\xD0', '\x92', ' ', '\xD0', '\x95', ' ', '\xD0', '\xA8', ' ', '\xD0', '\x97', ' ', '\xD0', '\x9E', ' ', '\xD0', '\xA1', ' ', '\xD0', '\xAD', /* Б В Е Ш З О С Э */ + '\0', + '\xD1', '\x85', ' ', '\xD0', '\xBF', ' ', '\xD0', '\xBD', ' ', '\xD1', '\x88', ' ', '\xD0', '\xB5', ' ', '\xD0', '\xB7', ' ', '\xD0', '\xBE', ' ', '\xD1', '\x81', /* х п н ш е з о с */ + '\0', + '\xD1', '\x80', ' ', '\xD1', '\x83', ' ', '\xD1', '\x84', /* р у ф */ + '\0', + '\xE0', '\xA4', '\x95', ' ', '\xE0', '\xA4', '\xAE', ' ', '\xE0', '\xA4', '\x85', ' ', '\xE0', '\xA4', '\x86', ' ', '\xE0', '\xA4', '\xA5', ' ', '\xE0', '\xA4', '\xA7', ' ', '\xE0', '\xA4', '\xAD', ' ', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */ + '\0', + '\xE0', '\xA4', '\x88', ' ', '\xE0', '\xA4', '\x90', ' ', '\xE0', '\xA4', '\x93', ' ', '\xE0', '\xA4', '\x94', ' ', '\xE0', '\xA4', '\xBF', ' ', '\xE0', '\xA5', '\x80', ' ', '\xE0', '\xA5', '\x8B', ' ', '\xE0', '\xA5', '\x8C', /* ई ऐ ओ औ ि ी ो ौ */ + '\0', + '\xE0', '\xA4', '\x95', ' ', '\xE0', '\xA4', '\xAE', ' ', '\xE0', '\xA4', '\x85', ' ', '\xE0', '\xA4', '\x86', ' ', '\xE0', '\xA4', '\xA5', ' ', '\xE0', '\xA4', '\xA7', ' ', '\xE0', '\xA4', '\xAD', ' ', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */ + '\0', + '\xE0', '\xA5', '\x81', ' ', '\xE0', '\xA5', '\x83', /* ु ृ */ + '\0', + '\xE1', '\x88', '\x80', ' ', '\xE1', '\x88', '\x83', ' ', '\xE1', '\x8B', '\x98', ' ', '\xE1', '\x8D', '\x90', ' ', '\xE1', '\x88', '\x9B', ' ', '\xE1', '\x89', '\xA0', ' ', '\xE1', '\x8B', '\x8B', ' ', '\xE1', '\x8B', '\x90', /* ሀ ሃ ዘ ፐ ማ በ ዋ ዐ */ + '\0', + '\xE1', '\x88', '\x88', ' ', '\xE1', '\x88', '\x90', ' ', '\xE1', '\x89', '\xA0', ' ', '\xE1', '\x8B', '\x98', ' ', '\xE1', '\x88', '\x80', ' ', '\xE1', '\x88', '\xAA', ' ', '\xE1', '\x8B', '\x90', ' ', '\xE1', '\x8C', '\xA8', /* ለ ሐ በ ዘ ሀ ሪ ዐ ጨ */ + '\0', + '\xE1', '\x83', '\x92', ' ', '\xE1', '\x83', '\x93', ' ', '\xE1', '\x83', '\x94', ' ', '\xE1', '\x83', '\x95', ' ', '\xE1', '\x83', '\x97', ' ', '\xE1', '\x83', '\x98', ' ', '\xE1', '\x83', '\x9D', ' ', '\xE1', '\x83', '\xA6', /* გ დ ე ვ თ ი ო ღ */ + '\0', + '\xE1', '\x83', '\x90', ' ', '\xE1', '\x83', '\x96', ' ', '\xE1', '\x83', '\x9B', ' ', '\xE1', '\x83', '\xA1', ' ', '\xE1', '\x83', '\xA8', ' ', '\xE1', '\x83', '\xAB', ' ', '\xE1', '\x83', '\xAE', ' ', '\xE1', '\x83', '\x9E', /* ა ზ მ ს შ ძ ხ პ */ + '\0', + '\xE1', '\x83', '\xA1', ' ', '\xE1', '\x83', '\xAE', ' ', '\xE1', '\x83', '\xA5', ' ', '\xE1', '\x83', '\x96', ' ', '\xE1', '\x83', '\x9B', ' ', '\xE1', '\x83', '\xA8', ' ', '\xE1', '\x83', '\xA9', ' ', '\xE1', '\x83', '\xAC', /* ს ხ ქ ზ მ შ ჩ წ */ + '\0', + '\xE1', '\x83', '\x94', ' ', '\xE1', '\x83', '\x95', ' ', '\xE1', '\x83', '\x9F', ' ', '\xE1', '\x83', '\xA2', ' ', '\xE1', '\x83', '\xA3', ' ', '\xE1', '\x83', '\xA4', ' ', '\xE1', '\x83', '\xA5', ' ', '\xE1', '\x83', '\xA7', /* ე ვ ჟ ტ უ ფ ქ ყ */ + '\0', + '\xE1', '\x82', '\xB1', ' ', '\xE1', '\x82', '\xA7', ' ', '\xE1', '\x82', '\xB9', ' ', '\xE1', '\x82', '\xBC', ' ', '\xE1', '\x82', '\xA4', ' ', '\xE1', '\x82', '\xA5', ' ', '\xE1', '\x82', '\xB3', ' ', '\xE1', '\x82', '\xBA', /* Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ */ + '\0', + '\xE1', '\x82', '\xA4', ' ', '\xE1', '\x82', '\xA5', ' ', '\xE1', '\x82', '\xA7', ' ', '\xE1', '\x82', '\xA8', ' ', '\xE1', '\x82', '\xA6', ' ', '\xE1', '\x82', '\xB1', ' ', '\xE1', '\x82', '\xAA', ' ', '\xE1', '\x82', '\xAB', /* Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ */ + '\0', + '\xE2', '\xB4', '\x81', ' ', '\xE2', '\xB4', '\x97', ' ', '\xE2', '\xB4', '\x82', ' ', '\xE2', '\xB4', '\x84', ' ', '\xE2', '\xB4', '\x85', ' ', '\xE2', '\xB4', '\x87', ' ', '\xE2', '\xB4', '\x94', ' ', '\xE2', '\xB4', '\x96', /* ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ */ + '\0', + '\xE2', '\xB4', '\x88', ' ', '\xE2', '\xB4', '\x8C', ' ', '\xE2', '\xB4', '\x96', ' ', '\xE2', '\xB4', '\x8E', ' ', '\xE2', '\xB4', '\x83', ' ', '\xE2', '\xB4', '\x86', ' ', '\xE2', '\xB4', '\x8B', ' ', '\xE2', '\xB4', '\xA2', /* ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ */ + '\0', + '\xE2', '\xB4', '\x90', ' ', '\xE2', '\xB4', '\x91', ' ', '\xE2', '\xB4', '\x93', ' ', '\xE2', '\xB4', '\x95', ' ', '\xE2', '\xB4', '\x99', ' ', '\xE2', '\xB4', '\x9B', ' ', '\xE2', '\xB4', '\xA1', ' ', '\xE2', '\xB4', '\xA3', /* ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ */ + '\0', + '\xE2', '\xB4', '\x84', ' ', '\xE2', '\xB4', '\x85', ' ', '\xE2', '\xB4', '\x94', ' ', '\xE2', '\xB4', '\x95', ' ', '\xE2', '\xB4', '\x81', ' ', '\xE2', '\xB4', '\x82', ' ', '\xE2', '\xB4', '\x98', ' ', '\xE2', '\xB4', '\x9D', /* ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ */ + '\0', + '\xCE', '\x93', ' ', '\xCE', '\x92', ' ', '\xCE', '\x95', ' ', '\xCE', '\x96', ' ', '\xCE', '\x98', ' ', '\xCE', '\x9F', ' ', '\xCE', '\xA9', /* Γ Β Ε Ζ Θ Ο Ω */ + '\0', + '\xCE', '\x92', ' ', '\xCE', '\x94', ' ', '\xCE', '\x96', ' ', '\xCE', '\x9E', ' ', '\xCE', '\x98', ' ', '\xCE', '\x9F', /* Β Δ Ζ Ξ Θ Ο */ + '\0', + '\xCE', '\xB2', ' ', '\xCE', '\xB8', ' ', '\xCE', '\xB4', ' ', '\xCE', '\xB6', ' ', '\xCE', '\xBB', ' ', '\xCE', '\xBE', /* β θ δ ζ λ ξ */ + '\0', + '\xCE', '\xB1', ' ', '\xCE', '\xB5', ' ', '\xCE', '\xB9', ' ', '\xCE', '\xBF', ' ', '\xCF', '\x80', ' ', '\xCF', '\x83', ' ', '\xCF', '\x84', ' ', '\xCF', '\x89', /* α ε ι ο π σ τ ω */ + '\0', + '\xCE', '\xB2', ' ', '\xCE', '\xB3', ' ', '\xCE', '\xB7', ' ', '\xCE', '\xBC', ' ', '\xCF', '\x81', ' ', '\xCF', '\x86', ' ', '\xCF', '\x87', ' ', '\xCF', '\x88', /* β γ η μ ρ φ χ ψ */ + '\0', + '\xE0', '\xAA', '\xA4', ' ', '\xE0', '\xAA', '\xA8', ' ', '\xE0', '\xAA', '\x8B', ' ', '\xE0', '\xAA', '\x8C', ' ', '\xE0', '\xAA', '\x9B', ' ', '\xE0', '\xAA', '\x9F', ' ', '\xE0', '\xAA', '\xB0', ' ', '\xE0', '\xAB', '\xA6', /* ત ન ઋ ઌ છ ટ ર ૦ */ + '\0', + '\xE0', '\xAA', '\x96', ' ', '\xE0', '\xAA', '\x97', ' ', '\xE0', '\xAA', '\x98', ' ', '\xE0', '\xAA', '\x9E', ' ', '\xE0', '\xAA', '\x87', ' ', '\xE0', '\xAA', '\x88', ' ', '\xE0', '\xAA', '\xA0', ' ', '\xE0', '\xAA', '\x9C', /* ખ ગ ઘ ઞ ઇ ઈ ઠ જ */ + '\0', + '\xE0', '\xAA', '\x88', ' ', '\xE0', '\xAA', '\x8A', ' ', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAB', '\x80', ' ', '\xE0', '\xAA', '\xB2', '\xE0', '\xAB', '\x80', ' ', '\xE0', '\xAA', '\xB6', '\xE0', '\xAB', '\x8D', '\xE0', '\xAA', '\x9A', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAA', '\x9C', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAA', '\xB8', '\xE0', '\xAB', '\x80', /* ઈ ઊ િ ી લી શ્ચિ જિ સી */ + '\0', + '\xE0', '\xAB', '\x81', ' ', '\xE0', '\xAB', '\x83', ' ', '\xE0', '\xAB', '\x84', ' ', '\xE0', '\xAA', '\x96', '\xE0', '\xAB', '\x81', ' ', '\xE0', '\xAA', '\x9B', '\xE0', '\xAB', '\x83', ' ', '\xE0', '\xAA', '\x9B', '\xE0', '\xAB', '\x84', /* ુ ૃ ૄ ખુ છૃ છૄ */ + '\0', + '\xE0', '\xAB', '\xA6', ' ', '\xE0', '\xAB', '\xA7', ' ', '\xE0', '\xAB', '\xA8', ' ', '\xE0', '\xAB', '\xA9', ' ', '\xE0', '\xAB', '\xAD', /* ૦ ૧ ૨ ૩ ૭ */ + '\0', + '\xE0', '\xA8', '\x95', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x99', ' ', '\xE0', '\xA8', '\x9A', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA4', ' ', '\xE0', '\xA8', '\xA7', ' ', '\xE0', '\xA8', '\xB8', /* ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ */ + '\0', + '\xE0', '\xA8', '\x95', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x99', ' ', '\xE0', '\xA8', '\x9A', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA4', ' ', '\xE0', '\xA8', '\xA7', ' ', '\xE0', '\xA8', '\xB8', /* ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ */ + '\0', + '\xE0', '\xA8', '\x87', ' ', '\xE0', '\xA8', '\x88', ' ', '\xE0', '\xA8', '\x89', ' ', '\xE0', '\xA8', '\x8F', ' ', '\xE0', '\xA8', '\x93', ' ', '\xE0', '\xA9', '\xB3', ' ', '\xE0', '\xA8', '\xBF', ' ', '\xE0', '\xA9', '\x80', /* ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ */ + '\0', + '\xE0', '\xA8', '\x85', ' ', '\xE0', '\xA8', '\x8F', ' ', '\xE0', '\xA8', '\x93', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA0', ' ', '\xE0', '\xA8', '\xB0', ' ', '\xE0', '\xA8', '\xB8', /* ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ */ + '\0', + '\xE0', '\xA9', '\xA6', ' ', '\xE0', '\xA9', '\xA7', ' ', '\xE0', '\xA9', '\xA8', ' ', '\xE0', '\xA9', '\xA9', ' ', '\xE0', '\xA9', '\xAD', /* ੦ ੧ ੨ ੩ ੭ */ + '\0', + '\xD7', '\x91', ' ', '\xD7', '\x93', ' ', '\xD7', '\x94', ' ', '\xD7', '\x97', ' ', '\xD7', '\x9A', ' ', '\xD7', '\x9B', ' ', '\xD7', '\x9D', ' ', '\xD7', '\xA1', /* ב ד ה ח ך כ ם ס */ + '\0', + '\xD7', '\x91', ' ', '\xD7', '\x98', ' ', '\xD7', '\x9B', ' ', '\xD7', '\x9D', ' ', '\xD7', '\xA1', ' ', '\xD7', '\xA6', /* ב ט כ ם ס צ */ + '\0', + '\xD7', '\xA7', ' ', '\xD7', '\x9A', ' ', '\xD7', '\x9F', ' ', '\xD7', '\xA3', ' ', '\xD7', '\xA5', /* ק ך ן ף ץ */ + '\0', + '\xE0', '\xB2', '\x87', ' ', '\xE0', '\xB2', '\x8A', ' ', '\xE0', '\xB2', '\x90', ' ', '\xE0', '\xB2', '\xA3', ' ', '\xE0', '\xB2', '\xB8', '\xE0', '\xB2', '\xBE', ' ', '\xE0', '\xB2', '\xA8', '\xE0', '\xB2', '\xBE', ' ', '\xE0', '\xB2', '\xA6', '\xE0', '\xB2', '\xBE', ' ', '\xE0', '\xB2', '\xB0', '\xE0', '\xB2', '\xBE', /* ಇ ಊ ಐ ಣ ಸಾ ನಾ ದಾ ರಾ */ + '\0', + '\xE0', '\xB2', '\x85', ' ', '\xE0', '\xB2', '\x89', ' ', '\xE0', '\xB2', '\x8E', ' ', '\xE0', '\xB2', '\xB2', ' ', '\xE0', '\xB3', '\xA6', ' ', '\xE0', '\xB3', '\xA8', ' ', '\xE0', '\xB3', '\xAC', ' ', '\xE0', '\xB3', '\xAD', /* ಅ ಉ ಎ ಲ ೦ ೨ ೬ ೭ */ + '\0', + '\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x91', ' ', '\xE1', '\x9E', '\x93', ' ', '\xE1', '\x9E', '\xA7', ' ', '\xE1', '\x9E', '\xA9', ' ', '\xE1', '\x9E', '\xB6', /* ខ ទ ន ឧ ឩ ា */ + '\0', + '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x80', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x82', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x90', /* ក្ក ក្ខ ក្គ ក្ថ */ + '\0', + '\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x83', ' ', '\xE1', '\x9E', '\x85', ' ', '\xE1', '\x9E', '\x8B', ' ', '\xE1', '\x9E', '\x94', ' ', '\xE1', '\x9E', '\x98', ' ', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\xB2', /* ខ ឃ ច ឋ ប ម យ ឲ */ + '\0', + '\xE1', '\x9E', '\x8F', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x9A', ' ', '\xE1', '\x9E', '\x9A', '\xE1', '\x9F', '\x80', ' ', '\xE1', '\x9E', '\xB2', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\xA2', '\xE1', '\x9E', '\xBF', /* ត្រ រៀ ឲ្យ អឿ */ + '\0', + '\xE1', '\x9E', '\x93', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x8F', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x9A', '\xE1', '\x9F', '\x83', ' ', '\xE1', '\x9E', '\x84', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x81', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x94', '\xE1', '\x9F', '\x80', ' ', '\xE1', '\x9E', '\x85', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x9A', '\xE1', '\x9F', '\x80', ' ', '\xE1', '\x9E', '\x93', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x8F', '\xE1', '\x9E', '\xBF', ' ', '\xE1', '\x9E', '\x9B', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x94', '\xE1', '\x9E', '\xBF', /* ន្ត្រៃ ង្ខ្យ ក្បៀ ច្រៀ ន្តឿ ល្បឿ */ + '\0', + '\xE1', '\xA7', '\xA0', ' ', '\xE1', '\xA7', '\xA1', /* ᧠ ᧡ */ + '\0', + '\xE1', '\xA7', '\xB6', ' ', '\xE1', '\xA7', '\xB9', /* ᧶ ᧹ */ + '\0', + '\xE0', '\xBA', '\xB2', ' ', '\xE0', '\xBA', '\x94', ' ', '\xE0', '\xBA', '\xAD', ' ', '\xE0', '\xBA', '\xA1', ' ', '\xE0', '\xBA', '\xA5', ' ', '\xE0', '\xBA', '\xA7', ' ', '\xE0', '\xBA', '\xA3', ' ', '\xE0', '\xBA', '\x87', /* າ ດ ອ ມ ລ ວ ຣ ງ */ + '\0', + '\xE0', '\xBA', '\xB2', ' ', '\xE0', '\xBA', '\xAD', ' ', '\xE0', '\xBA', '\x9A', ' ', '\xE0', '\xBA', '\x8D', ' ', '\xE0', '\xBA', '\xA3', ' ', '\xE0', '\xBA', '\xAE', ' ', '\xE0', '\xBA', '\xA7', ' ', '\xE0', '\xBA', '\xA2', /* າ ອ ບ ຍ ຣ ຮ ວ ຢ */ + '\0', + '\xE0', '\xBA', '\x9B', ' ', '\xE0', '\xBA', '\xA2', ' ', '\xE0', '\xBA', '\x9F', ' ', '\xE0', '\xBA', '\x9D', /* ປ ຢ ຟ ຝ */ + '\0', + '\xE0', '\xBB', '\x82', ' ', '\xE0', '\xBB', '\x84', ' ', '\xE0', '\xBB', '\x83', /* ໂ ໄ ໃ */ + '\0', + '\xE0', '\xBA', '\x87', ' ', '\xE0', '\xBA', '\x8A', ' ', '\xE0', '\xBA', '\x96', ' ', '\xE0', '\xBA', '\xBD', ' ', '\xE0', '\xBB', '\x86', ' ', '\xE0', '\xBA', '\xAF', /* ງ ຊ ຖ ຽ ໆ ຯ */ + '\0', + 'T', ' ', 'H', ' ', 'E', ' ', 'Z', ' ', 'O', ' ', 'C', ' ', 'Q', ' ', 'S', /* T H E Z O C Q S */ + '\0', + 'H', ' ', 'E', ' ', 'Z', ' ', 'L', ' ', 'O', ' ', 'C', ' ', 'U', ' ', 'S', /* H E Z L O C U S */ + '\0', + 'f', ' ', 'i', ' ', 'j', ' ', 'k', ' ', 'd', ' ', 'b', ' ', 'h', /* f i j k d b h */ + '\0', + 'x', ' ', 'z', ' ', 'r', ' ', 'o', ' ', 'e', ' ', 's', ' ', 'c', /* x z r o e s c */ + '\0', + 'p', ' ', 'q', ' ', 'g', ' ', 'j', ' ', 'y', /* p q g j y */ + '\0', + '\xE2', '\x82', '\x80', ' ', '\xE2', '\x82', '\x83', ' ', '\xE2', '\x82', '\x85', ' ', '\xE2', '\x82', '\x87', ' ', '\xE2', '\x82', '\x88', /* ₀ ₃ ₅ ₇ ₈ */ + '\0', + '\xE2', '\x82', '\x80', ' ', '\xE2', '\x82', '\x81', ' ', '\xE2', '\x82', '\x82', ' ', '\xE2', '\x82', '\x83', ' ', '\xE2', '\x82', '\x88', /* ₀ ₁ ₂ ₃ ₈ */ + '\0', + '\xE1', '\xB5', '\xA2', ' ', '\xE2', '\xB1', '\xBC', ' ', '\xE2', '\x82', '\x95', ' ', '\xE2', '\x82', '\x96', ' ', '\xE2', '\x82', '\x97', /* ᵢ ⱼ ₕ ₖ ₗ */ + '\0', + '\xE2', '\x82', '\x90', ' ', '\xE2', '\x82', '\x91', ' ', '\xE2', '\x82', '\x92', ' ', '\xE2', '\x82', '\x93', ' ', '\xE2', '\x82', '\x99', ' ', '\xE2', '\x82', '\x9B', ' ', '\xE1', '\xB5', '\xA5', ' ', '\xE1', '\xB5', '\xA4', ' ', '\xE1', '\xB5', '\xA3', /* ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ */ + '\0', + '\xE1', '\xB5', '\xA6', ' ', '\xE1', '\xB5', '\xA7', ' ', '\xE1', '\xB5', '\xA8', ' ', '\xE1', '\xB5', '\xA9', ' ', '\xE2', '\x82', '\x9A', /* ᵦ ᵧ ᵨ ᵩ ₚ */ + '\0', + '\xE2', '\x81', '\xB0', ' ', '\xC2', '\xB3', ' ', '\xE2', '\x81', '\xB5', ' ', '\xE2', '\x81', '\xB7', ' ', '\xE1', '\xB5', '\x80', ' ', '\xE1', '\xB4', '\xB4', ' ', '\xE1', '\xB4', '\xB1', ' ', '\xE1', '\xB4', '\xBC', /* ⁰ ³ ⁵ ⁷ ᵀ ᴴ ᴱ ᴼ */ + '\0', + '\xE2', '\x81', '\xB0', ' ', '\xC2', '\xB9', ' ', '\xC2', '\xB2', ' ', '\xC2', '\xB3', ' ', '\xE1', '\xB4', '\xB1', ' ', '\xE1', '\xB4', '\xB8', ' ', '\xE1', '\xB4', '\xBC', ' ', '\xE1', '\xB5', '\x81', /* ⁰ ¹ ² ³ ᴱ ᴸ ᴼ ᵁ */ + '\0', + '\xE1', '\xB5', '\x87', ' ', '\xE1', '\xB5', '\x88', ' ', '\xE1', '\xB5', '\x8F', ' ', '\xCA', '\xB0', ' ', '\xCA', '\xB2', ' ', '\xE1', '\xB6', '\xA0', ' ', '\xE2', '\x81', '\xB1', /* ᵇ ᵈ ᵏ ʰ ʲ ᶠ ⁱ */ + '\0', + '\xE1', '\xB5', '\x89', ' ', '\xE1', '\xB5', '\x92', ' ', '\xCA', '\xB3', ' ', '\xCB', '\xA2', ' ', '\xCB', '\xA3', ' ', '\xE1', '\xB6', '\x9C', ' ', '\xE1', '\xB6', '\xBB', /* ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ */ + '\0', + '\xE1', '\xB5', '\x96', ' ', '\xCA', '\xB8', ' ', '\xE1', '\xB5', '\x8D', /* ᵖ ʸ ᵍ */ + '\0', + '\xE0', '\xB4', '\x92', ' ', '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xB1', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xAA', ' ', '\xE0', '\xB4', '\x9A', '\xE0', '\xB5', '\x8D', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xAA', '\xE0', '\xB5', '\x8D', '\xE0', '\xB4', '\xAA', /* ഒ ട ഠ റ ച പ ച്ച പ്പ */ + '\0', + '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xA7', ' ', '\xE0', '\xB4', '\xB6', ' ', '\xE0', '\xB4', '\x98', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xA5', ' ', '\xE0', '\xB4', '\xB2', /* ട ഠ ധ ശ ഘ ച ഥ ല */ + '\0', + '\xE1', '\x80', '\x81', ' ', '\xE1', '\x80', '\x82', ' ', '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\xA5', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* ခ ဂ င ဒ ဝ ၥ ၊ ။ */ + '\0', + '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x8E', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x95', ' ', '\xE1', '\x80', '\x97', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* င ဎ ဒ ပ ဗ ဝ ၊ ။ */ + '\0', + '\xE1', '\x80', '\xA9', ' ', '\xE1', '\x80', '\xBC', ' ', '\xE1', '\x81', '\x8D', ' ', '\xE1', '\x81', '\x8F', ' ', '\xE1', '\x81', '\x86', ' ', '\xE1', '\x80', '\xAB', ' ', '\xE1', '\x80', '\xAD', /* ဩ ြ ၍ ၏ ၆ ါ ိ */ + '\0', + '\xE1', '\x80', '\x89', ' ', '\xE1', '\x80', '\x8A', ' ', '\xE1', '\x80', '\xA5', ' ', '\xE1', '\x80', '\xA9', ' ', '\xE1', '\x80', '\xA8', ' ', '\xE1', '\x81', '\x82', ' ', '\xE1', '\x81', '\x85', ' ', '\xE1', '\x81', '\x89', /* ဉ ည ဥ ဩ ဨ ၂ ၅ ၉ */ + '\0', + '\xE0', '\xB6', '\x89', ' ', '\xE0', '\xB6', '\x9A', ' ', '\xE0', '\xB6', '\x9D', ' ', '\xE0', '\xB6', '\xB3', ' ', '\xE0', '\xB6', '\xB4', ' ', '\xE0', '\xB6', '\xBA', ' ', '\xE0', '\xB6', '\xBD', ' ', '\xE0', '\xB7', '\x86', /* ඉ ක ඝ ඳ ප ය ල ෆ */ + '\0', + '\xE0', '\xB6', '\x91', ' ', '\xE0', '\xB6', '\x94', ' ', '\xE0', '\xB6', '\x9D', ' ', '\xE0', '\xB6', '\xA2', ' ', '\xE0', '\xB6', '\xA7', ' ', '\xE0', '\xB6', '\xAE', ' ', '\xE0', '\xB6', '\xB0', ' ', '\xE0', '\xB6', '\xBB', /* එ ඔ ඝ ජ ට ථ ධ ර */ + '\0', + '\xE0', '\xB6', '\xAF', ' ', '\xE0', '\xB6', '\xB3', ' ', '\xE0', '\xB6', '\x8B', ' ', '\xE0', '\xB6', '\xBD', ' ', '\xE0', '\xB6', '\xAD', '\xE0', '\xB7', '\x96', ' ', '\xE0', '\xB6', '\xAD', '\xE0', '\xB7', '\x94', ' ', '\xE0', '\xB6', '\xB6', '\xE0', '\xB7', '\x94', ' ', '\xE0', '\xB6', '\xAF', '\xE0', '\xB7', '\x94', /* ද ඳ උ ල තූ තු බු දු */ + '\0', + '\xE0', '\xAE', '\x89', ' ', '\xE0', '\xAE', '\x92', ' ', '\xE0', '\xAE', '\x93', ' ', '\xE0', '\xAE', '\xB1', ' ', '\xE0', '\xAE', '\x88', ' ', '\xE0', '\xAE', '\x95', ' ', '\xE0', '\xAE', '\x99', ' ', '\xE0', '\xAE', '\x9A', /* உ ஒ ஓ ற ஈ க ங ச */ + '\0', + '\xE0', '\xAE', '\x95', ' ', '\xE0', '\xAE', '\x9A', ' ', '\xE0', '\xAE', '\xB2', ' ', '\xE0', '\xAE', '\xB6', ' ', '\xE0', '\xAE', '\x89', ' ', '\xE0', '\xAE', '\x99', ' ', '\xE0', '\xAE', '\x9F', ' ', '\xE0', '\xAE', '\xAA', /* க ச ல ஶ உ ங ட ப */ + '\0', + '\xE0', '\xB0', '\x87', ' ', '\xE0', '\xB0', '\x8C', ' ', '\xE0', '\xB0', '\x99', ' ', '\xE0', '\xB0', '\x9E', ' ', '\xE0', '\xB0', '\xA3', ' ', '\xE0', '\xB0', '\xB1', ' ', '\xE0', '\xB1', '\xAF', /* ఇ ఌ ఙ ఞ ణ ఱ ౯ */ + '\0', + '\xE0', '\xB0', '\x85', ' ', '\xE0', '\xB0', '\x95', ' ', '\xE0', '\xB0', '\x9A', ' ', '\xE0', '\xB0', '\xB0', ' ', '\xE0', '\xB0', '\xBD', ' ', '\xE0', '\xB1', '\xA8', ' ', '\xE0', '\xB1', '\xAC', /* అ క చ ర ఽ ౨ ౬ */ + '\0', + '\xE0', '\xB8', '\x9A', ' ', '\xE0', '\xB9', '\x80', ' ', '\xE0', '\xB9', '\x81', ' ', '\xE0', '\xB8', '\xAD', ' ', '\xE0', '\xB8', '\x81', ' ', '\xE0', '\xB8', '\xB2', /* บ เ แ อ ก า */ + '\0', + '\xE0', '\xB8', '\x9A', ' ', '\xE0', '\xB8', '\x9B', ' ', '\xE0', '\xB8', '\xA9', ' ', '\xE0', '\xB8', '\xAF', ' ', '\xE0', '\xB8', '\xAD', ' ', '\xE0', '\xB8', '\xA2', ' ', '\xE0', '\xB8', '\xAE', /* บ ป ษ ฯ อ ย ฮ */ + '\0', + '\xE0', '\xB8', '\x9B', ' ', '\xE0', '\xB8', '\x9D', ' ', '\xE0', '\xB8', '\x9F', /* ป ฝ ฟ */ + '\0', + '\xE0', '\xB9', '\x82', ' ', '\xE0', '\xB9', '\x83', ' ', '\xE0', '\xB9', '\x84', /* โ ใ ไ */ + '\0', + '\xE0', '\xB8', '\x8E', ' ', '\xE0', '\xB8', '\x8F', ' ', '\xE0', '\xB8', '\xA4', ' ', '\xE0', '\xB8', '\xA6', /* ฎ ฏ ฤ ฦ */ + '\0', + '\xE0', '\xB8', '\x8D', ' ', '\xE0', '\xB8', '\x90', /* ญ ฐ */ + '\0', + '\xE0', '\xB9', '\x90', ' ', '\xE0', '\xB9', '\x91', ' ', '\xE0', '\xB9', '\x93', /* ๐ ๑ ๓ */ +#ifdef AF_CONFIG_OPTION_CJK + '\0', + '\xE4', '\xBB', '\x96', ' ', '\xE4', '\xBB', '\xAC', ' ', '\xE4', '\xBD', '\xA0', ' ', '\xE4', '\xBE', '\x86', ' ', '\xE5', '\x80', '\x91', ' ', '\xE5', '\x88', '\xB0', ' ', '\xE5', '\x92', '\x8C', ' ', '\xE5', '\x9C', '\xB0', /* 他 们 你 來 們 到 和 地 */ + ' ', '\xE5', '\xAF', '\xB9', ' ', '\xE5', '\xB0', '\x8D', ' ', '\xE5', '\xB0', '\xB1', ' ', '\xE5', '\xB8', '\xAD', ' ', '\xE6', '\x88', '\x91', ' ', '\xE6', '\x97', '\xB6', ' ', '\xE6', '\x99', '\x82', ' ', '\xE6', '\x9C', '\x83', /* 对 對 就 席 我 时 時 會 */ + ' ', '\xE6', '\x9D', '\xA5', ' ', '\xE7', '\x82', '\xBA', ' ', '\xE8', '\x83', '\xBD', ' ', '\xE8', '\x88', '\xB0', ' ', '\xE8', '\xAA', '\xAA', ' ', '\xE8', '\xAF', '\xB4', ' ', '\xE8', '\xBF', '\x99', ' ', '\xE9', '\x80', '\x99', /* 来 為 能 舰 說 说 这 這 */ + ' ', '\xE9', '\xBD', '\x8A', ' ', '|', /* 齊 | */ + ' ', '\xE5', '\x86', '\x9B', ' ', '\xE5', '\x90', '\x8C', ' ', '\xE5', '\xB7', '\xB2', ' ', '\xE6', '\x84', '\xBF', ' ', '\xE6', '\x97', '\xA2', ' ', '\xE6', '\x98', '\x9F', ' ', '\xE6', '\x98', '\xAF', ' ', '\xE6', '\x99', '\xAF', /* 军 同 已 愿 既 星 是 景 */ + ' ', '\xE6', '\xB0', '\x91', ' ', '\xE7', '\x85', '\xA7', ' ', '\xE7', '\x8E', '\xB0', ' ', '\xE7', '\x8F', '\xBE', ' ', '\xE7', '\x90', '\x86', ' ', '\xE7', '\x94', '\xA8', ' ', '\xE7', '\xBD', '\xAE', ' ', '\xE8', '\xA6', '\x81', /* 民 照 现 現 理 用 置 要 */ + ' ', '\xE8', '\xBB', '\x8D', ' ', '\xE9', '\x82', '\xA3', ' ', '\xE9', '\x85', '\x8D', ' ', '\xE9', '\x87', '\x8C', ' ', '\xE9', '\x96', '\x8B', ' ', '\xE9', '\x9B', '\xB7', ' ', '\xE9', '\x9C', '\xB2', ' ', '\xE9', '\x9D', '\xA2', /* 軍 那 配 里 開 雷 露 面 */ + ' ', '\xE9', '\xA1', '\xBE', /* 顾 */ + '\0', + '\xE4', '\xB8', '\xAA', ' ', '\xE4', '\xB8', '\xBA', ' ', '\xE4', '\xBA', '\xBA', ' ', '\xE4', '\xBB', '\x96', ' ', '\xE4', '\xBB', '\xA5', ' ', '\xE4', '\xBB', '\xAC', ' ', '\xE4', '\xBD', '\xA0', ' ', '\xE4', '\xBE', '\x86', /* 个 为 人 他 以 们 你 來 */ + ' ', '\xE5', '\x80', '\x8B', ' ', '\xE5', '\x80', '\x91', ' ', '\xE5', '\x88', '\xB0', ' ', '\xE5', '\x92', '\x8C', ' ', '\xE5', '\xA4', '\xA7', ' ', '\xE5', '\xAF', '\xB9', ' ', '\xE5', '\xB0', '\x8D', ' ', '\xE5', '\xB0', '\xB1', /* 個 們 到 和 大 对 對 就 */ + ' ', '\xE6', '\x88', '\x91', ' ', '\xE6', '\x97', '\xB6', ' ', '\xE6', '\x99', '\x82', ' ', '\xE6', '\x9C', '\x89', ' ', '\xE6', '\x9D', '\xA5', ' ', '\xE7', '\x82', '\xBA', ' ', '\xE8', '\xA6', '\x81', ' ', '\xE8', '\xAA', '\xAA', /* 我 时 時 有 来 為 要 說 */ + ' ', '\xE8', '\xAF', '\xB4', ' ', '|', /* 说 | */ + ' ', '\xE4', '\xB8', '\xBB', ' ', '\xE4', '\xBA', '\x9B', ' ', '\xE5', '\x9B', '\xA0', ' ', '\xE5', '\xAE', '\x83', ' ', '\xE6', '\x83', '\xB3', ' ', '\xE6', '\x84', '\x8F', ' ', '\xE7', '\x90', '\x86', ' ', '\xE7', '\x94', '\x9F', /* 主 些 因 它 想 意 理 生 */ + ' ', '\xE7', '\x95', '\xB6', ' ', '\xE7', '\x9C', '\x8B', ' ', '\xE7', '\x9D', '\x80', ' ', '\xE7', '\xBD', '\xAE', ' ', '\xE8', '\x80', '\x85', ' ', '\xE8', '\x87', '\xAA', ' ', '\xE8', '\x91', '\x97', ' ', '\xE8', '\xA3', '\xA1', /* 當 看 着 置 者 自 著 裡 */ + ' ', '\xE8', '\xBF', '\x87', ' ', '\xE8', '\xBF', '\x98', ' ', '\xE8', '\xBF', '\x9B', ' ', '\xE9', '\x80', '\xB2', ' ', '\xE9', '\x81', '\x8E', ' ', '\xE9', '\x81', '\x93', ' ', '\xE9', '\x82', '\x84', ' ', '\xE9', '\x87', '\x8C', /* 过 还 进 進 過 道 還 里 */ + ' ', '\xE9', '\x9D', '\xA2', /* 面 */ +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + '\0', + ' ', '\xE4', '\xBA', '\x9B', ' ', '\xE4', '\xBB', '\xAC', ' ', '\xE4', '\xBD', '\xA0', ' ', '\xE4', '\xBE', '\x86', ' ', '\xE5', '\x80', '\x91', ' ', '\xE5', '\x88', '\xB0', ' ', '\xE5', '\x92', '\x8C', ' ', '\xE5', '\x9C', '\xB0', /* 些 们 你 來 們 到 和 地 */ + ' ', '\xE5', '\xA5', '\xB9', ' ', '\xE5', '\xB0', '\x86', ' ', '\xE5', '\xB0', '\x87', ' ', '\xE5', '\xB0', '\xB1', ' ', '\xE5', '\xB9', '\xB4', ' ', '\xE5', '\xBE', '\x97', ' ', '\xE6', '\x83', '\x85', ' ', '\xE6', '\x9C', '\x80', /* 她 将 將 就 年 得 情 最 */ + ' ', '\xE6', '\xA0', '\xB7', ' ', '\xE6', '\xA8', '\xA3', ' ', '\xE7', '\x90', '\x86', ' ', '\xE8', '\x83', '\xBD', ' ', '\xE8', '\xAA', '\xAA', ' ', '\xE8', '\xAF', '\xB4', ' ', '\xE8', '\xBF', '\x99', ' ', '\xE9', '\x80', '\x99', /* 样 樣 理 能 說 说 这 這 */ + ' ', '\xE9', '\x80', '\x9A', ' ', '|', /* 通 | */ + ' ', '\xE5', '\x8D', '\xB3', ' ', '\xE5', '\x90', '\x97', ' ', '\xE5', '\x90', '\xA7', ' ', '\xE5', '\x90', '\xAC', ' ', '\xE5', '\x91', '\xA2', ' ', '\xE5', '\x93', '\x81', ' ', '\xE5', '\x93', '\x8D', ' ', '\xE5', '\x97', '\x8E', /* 即 吗 吧 听 呢 品 响 嗎 */ + ' ', '\xE5', '\xB8', '\x88', ' ', '\xE5', '\xB8', '\xAB', ' ', '\xE6', '\x94', '\xB6', ' ', '\xE6', '\x96', '\xAD', ' ', '\xE6', '\x96', '\xB7', ' ', '\xE6', '\x98', '\x8E', ' ', '\xE7', '\x9C', '\xBC', ' ', '\xE9', '\x96', '\x93', /* 师 師 收 断 斷 明 眼 間 */ + ' ', '\xE9', '\x97', '\xB4', ' ', '\xE9', '\x99', '\x85', ' ', '\xE9', '\x99', '\x88', ' ', '\xE9', '\x99', '\x90', ' ', '\xE9', '\x99', '\xA4', ' ', '\xE9', '\x99', '\xB3', ' ', '\xE9', '\x9A', '\x8F', ' ', '\xE9', '\x9A', '\x9B', /* 间 际 陈 限 除 陳 随 際 */ + ' ', '\xE9', '\x9A', '\xA8', /* 隨 */ + '\0', + '\xE4', '\xBA', '\x8B', ' ', '\xE5', '\x89', '\x8D', ' ', '\xE5', '\xAD', '\xB8', ' ', '\xE5', '\xB0', '\x86', ' ', '\xE5', '\xB0', '\x87', ' ', '\xE6', '\x83', '\x85', ' ', '\xE6', '\x83', '\xB3', ' ', '\xE6', '\x88', '\x96', /* 事 前 學 将 將 情 想 或 */ + ' ', '\xE6', '\x94', '\xBF', ' ', '\xE6', '\x96', '\xAF', ' ', '\xE6', '\x96', '\xB0', ' ', '\xE6', '\xA0', '\xB7', ' ', '\xE6', '\xA8', '\xA3', ' ', '\xE6', '\xB0', '\x91', ' ', '\xE6', '\xB2', '\x92', ' ', '\xE6', '\xB2', '\xA1', /* 政 斯 新 样 樣 民 沒 没 */ + ' ', '\xE7', '\x84', '\xB6', ' ', '\xE7', '\x89', '\xB9', ' ', '\xE7', '\x8E', '\xB0', ' ', '\xE7', '\x8F', '\xBE', ' ', '\xE7', '\x90', '\x83', ' ', '\xE7', '\xAC', '\xAC', ' ', '\xE7', '\xB6', '\x93', ' ', '\xE8', '\xB0', '\x81', /* 然 特 现 現 球 第 經 谁 */ + ' ', '\xE8', '\xB5', '\xB7', ' ', '|', /* 起 | */ + ' ', '\xE4', '\xBE', '\x8B', ' ', '\xE5', '\x88', '\xA5', ' ', '\xE5', '\x88', '\xAB', ' ', '\xE5', '\x88', '\xB6', ' ', '\xE5', '\x8A', '\xA8', ' ', '\xE5', '\x8B', '\x95', ' ', '\xE5', '\x90', '\x97', ' ', '\xE5', '\x97', '\x8E', /* 例 別 别 制 动 動 吗 嗎 */ + ' ', '\xE5', '\xA2', '\x9E', ' ', '\xE6', '\x8C', '\x87', ' ', '\xE6', '\x98', '\x8E', ' ', '\xE6', '\x9C', '\x9D', ' ', '\xE6', '\x9C', '\x9F', ' ', '\xE6', '\x9E', '\x84', ' ', '\xE7', '\x89', '\xA9', ' ', '\xE7', '\xA1', '\xAE', /* 增 指 明 朝 期 构 物 确 */ + ' ', '\xE7', '\xA7', '\x8D', ' ', '\xE8', '\xAA', '\xBF', ' ', '\xE8', '\xB0', '\x83', ' ', '\xE8', '\xB2', '\xBB', ' ', '\xE8', '\xB4', '\xB9', ' ', '\xE9', '\x82', '\xA3', ' ', '\xE9', '\x83', '\xBD', ' ', '\xE9', '\x96', '\x93', /* 种 調 调 費 费 那 都 間 */ + ' ', '\xE9', '\x97', '\xB4', /* 间 */ +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ +#endif /* AF_CONFIG_OPTION_CJK */ + '\0', + + }; + + + /* stringsets are specific to styles */ + FT_LOCAL_ARRAY_DEF( AF_Blue_StringRec ) + af_blue_stringsets[] = + { + /* */ + { AF_BLUE_STRING_ARABIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ARABIC_BOTTOM, 0 }, + { AF_BLUE_STRING_ARABIC_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ARMENIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_BENGALI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_BENGALI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_BENGALI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_BENGALI_BASE, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_CHEROKEE_CAPITAL, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CHEROKEE_CAPITAL, 0 }, + { AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CHEROKEE_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_CHEROKEE_SMALL, 0 }, + { AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_CYRILLIC_SMALL, 0 }, + { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_DEVANAGARI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_DEVANAGARI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_DEVANAGARI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_DEVANAGARI_BASE, 0 }, + { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_ETHIOPIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ETHIOPIC_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM, 0 }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM, 0 }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_GREEK_SMALL_BETA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GREEK_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GREEK_SMALL, 0 }, + { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GUJARATI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GUJARATI_BOTTOM, 0 }, + { AF_BLUE_STRING_GUJARATI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GUJARATI_DESCENDER, 0 }, + { AF_BLUE_STRING_GUJARATI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GURMUKHI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GURMUKHI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GURMUKHI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GURMUKHI_BOTTOM, 0 }, + { AF_BLUE_STRING_GURMUKHI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_LONG }, + { AF_BLUE_STRING_HEBREW_BOTTOM, 0 }, + { AF_BLUE_STRING_HEBREW_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_KANNADA_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP }, + { AF_BLUE_STRING_KHMER_BOTTOM, 0 }, + { AF_BLUE_STRING_KHMER_DESCENDER, 0 }, + { AF_BLUE_STRING_KHMER_LARGE_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_LAO_BOTTOM, 0 }, + { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LAO_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_LATIN_SMALL, 0 }, + { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SUBS_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_LATIN_SUBS_SMALL, 0 }, + { AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SUPS_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_LATIN_SUPS_SMALL, 0 }, + { AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MALAYALAM_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_MYANMAR_BOTTOM, 0 }, + { AF_BLUE_STRING_MYANMAR_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MYANMAR_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_SINHALA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_SINHALA_BOTTOM, 0 }, + { AF_BLUE_STRING_SINHALA_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_TAMIL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_TAMIL_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_TELUGU_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_THAI_BOTTOM, 0 }, + { AF_BLUE_STRING_THAI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_THAI_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_THAI_DESCENDER, 0 }, + { AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0 }, + { AF_BLUE_STRING_THAI_DIGIT_TOP, 0 }, + { AF_BLUE_STRING_MAX, 0 }, +#ifdef AF_CONFIG_OPTION_CJK + { AF_BLUE_STRING_CJK_TOP, AF_BLUE_PROPERTY_CJK_TOP }, + { AF_BLUE_STRING_CJK_BOTTOM, 0 }, +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + { AF_BLUE_STRING_CJK_LEFT, AF_BLUE_PROPERTY_CJK_HORIZ }, + { AF_BLUE_STRING_CJK_RIGHT, AF_BLUE_PROPERTY_CJK_HORIZ | + AF_BLUE_PROPERTY_CJK_RIGHT }, +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + { AF_BLUE_STRING_MAX, 0 }, +#endif /* AF_CONFIG_OPTION_CJK */ + + }; + + +/* END */ diff --git a/drivers/freetype/freetype/src/autofit/aflatin2.h b/drivers/freetype/src/autofit/afblue.cin index cbfa395522..0c3cae818f 100644 --- a/drivers/freetype/freetype/src/autofit/aflatin2.h +++ b/drivers/freetype/src/autofit/afblue.cin @@ -1,10 +1,10 @@ /***************************************************************************/ /* */ -/* aflatin2.h */ +/* afblue.c */ /* */ -/* Auto-fitter hinting routines for latin script (specification). */ +/* Auto-fitter data for blue strings (body). */ /* */ -/* Copyright 2003-2007, 2012 by */ +/* Copyright 2013-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,24 +16,24 @@ /***************************************************************************/ -#ifndef __AFLATIN2_H__ -#define __AFLATIN2_H__ +#include "aftypes.h" -#include "afhints.h" + FT_LOCAL_ARRAY_DEF( char ) + af_blue_strings[] = + { + /* */ +@AF_BLUE_STRINGS_ARRAY@ + }; -FT_BEGIN_HEADER - - /* the latin-specific script class */ - - AF_DECLARE_SCRIPT_CLASS( af_latin2_script_class ) - -/* */ - -FT_END_HEADER - -#endif /* __AFLATIN_H__ */ + /* stringsets are specific to styles */ + FT_LOCAL_ARRAY_DEF( AF_Blue_StringRec ) + af_blue_stringsets[] = + { + /* */ +@AF_BLUE_STRINGSETS_ARRAY@ + }; /* END */ diff --git a/drivers/freetype/src/autofit/afblue.dat b/drivers/freetype/src/autofit/afblue.dat new file mode 100644 index 0000000000..0734ec71f0 --- /dev/null +++ b/drivers/freetype/src/autofit/afblue.dat @@ -0,0 +1,718 @@ +// afblue.dat +// +// Auto-fitter data for blue strings. +// +// Copyright 2013-2016 by +// David Turner, Robert Wilhelm, and Werner Lemberg. +// +// This file is part of the FreeType project, and may only be used, +// modified, and distributed under the terms of the FreeType project +// license, LICENSE.TXT. By continuing to use, modify, or distribute +// this file you indicate that you have read the license and +// understand and accept it fully. + + +// This file contains data specific to blue zones. It gets processed by +// a script to simulate `jagged arrays', with enumeration values holding +// offsets into the arrays. +// +// The format of the file is rather simple: A section starts with three +// labels separated by whitespace and followed by a colon (everything in a +// single line); the first label gives the name of the enumeration template, +// the second the name of the array template, and the third the name of the +// `maximum' template. The script then fills the corresponding templates +// (indicated by `@' characters around the name). +// +// A section contains one or more data records. Each data record consists +// of two or more lines. The first line holds the enumeration name, and the +// remaining lines the corresponding array data. +// +// There are two possible representations for array data. +// +// - A string of characters or character clusters (for example, representing +// Aksharas, Devanagari syllables) in UTF-8 encoding enclosed in double +// quotes, using C syntax, where the elements are separated by spaces. +// There can be only one string per line, thus the starting and ending +// double quote must be the first and last character in the line, +// respectively, ignoring whitespace before and after the string. If +// there are multiple strings (in multiple lines), they are concatenated +// to a single string. In the output, a string gets represented as a +// series of singles bytes, followed by a zero byte. The enumeration +// values simply hold byte offsets to the start of the corresponding +// strings. +// +// For strings, the `maximum' template holds the maximum number of +// non-space characters in all strings. +// +// - Data blocks enclosed in balanced braces, which get copied verbatim and +// which can span multiple lines. The opening brace of a block must be +// the first character of a line (ignoring whitespace), and the closing +// brace the last (ignoring whitespace also). The script appends a comma +// character after each block and counts the number of blocks to set the +// enumeration values. +// +// For data blocks, the `maximum' template holds the maximum number of +// array elements. +// +// A section can contain either strings only or data blocks only. +// +// A comment line starts with `//'; it gets removed. A preprocessor +// directive line (using the standard syntax of `cpp') starts with `#' and +// gets copied verbatim to both the enumeration and the array. Whitespace +// outside of a string is insignificant. +// +// Preprocessor directives are ignored while the script computes maximum +// values; this essentially means that the maximum values can easily be too +// large. Given that the purpose of those values is to create local +// fixed-size arrays at compile time for further processing of the blue zone +// data, this isn't a problem. Note the final zero byte of a string is not +// counted. Note also that the count holds the number of UTF-8 encoded +// characters, not bytes. + + +// The blue zone string data, to be used in the blue stringsets below. + +AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: + + AF_BLUE_STRING_ARABIC_TOP + "ا إ ل ك ط ظ" + AF_BLUE_STRING_ARABIC_BOTTOM + "ت ث ط ظ ك" + // We don't necessarily have access to medial forms via Unicode in case + // Arabic presentational forms are missing. The only character that is + // guaranteed to have the same vertical position with joining (this is, + // non-isolated) forms is U+0640, ARABIC TATWEEL, which must join both + // round and flat curves. + AF_BLUE_STRING_ARABIC_JOIN + "ـ" + + AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP + "Ա Մ Ւ Փ Բ Գ Դ Օ" + AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM + "Ւ Ո Փ Ճ Շ Ս Տ Օ" + AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER + "ե է ի մ վ փ ֆ փ" + AF_BLUE_STRING_ARMENIAN_SMALL_TOP + "ա յ ւ ս գ ջ ր օ" + AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM + "հ ո ճ ա ե ծ ս օ" + AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER + "բ ը ի լ ղ պ փ ց" + + AF_BLUE_STRING_BENGALI_BASE + "অ ড ত ন ব ভ ল ক" + AF_BLUE_STRING_BENGALI_TOP + "ই ট ঠ ি ী ৈ ৗ" + AF_BLUE_STRING_BENGALI_HEAD + "ও এ ড ত ন ব ল ক" + + AF_BLUE_STRING_CHEROKEE_CAPITAL + "Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ" + AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER + "ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ" + AF_BLUE_STRING_CHEROKEE_SMALL + "ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ" + AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER + "ᏸ ꮐ ꭹ ꭻ" + + AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP + "Б В Е П З О С Э" + AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM + "Б В Е Ш З О С Э" + AF_BLUE_STRING_CYRILLIC_SMALL + "х п н ш е з о с" + AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER + "р у ф" + + AF_BLUE_STRING_DEVANAGARI_BASE + "क म अ आ थ ध भ श" + AF_BLUE_STRING_DEVANAGARI_TOP + "ई ऐ ओ औ ि ी ो ौ" + // note that some fonts have extreme variation in the height of the + // round head elements; for this reason we also define the `base' + // blue zone, which must be always present + AF_BLUE_STRING_DEVANAGARI_HEAD + "क म अ आ थ ध भ श" + AF_BLUE_STRING_DEVANAGARI_BOTTOM + "ु ृ" + + AF_BLUE_STRING_ETHIOPIC_TOP + "ሀ ሃ ዘ ፐ ማ በ ዋ ዐ" + AF_BLUE_STRING_ETHIOPIC_BOTTOM + "ለ ሐ በ ዘ ሀ ሪ ዐ ጨ" + + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP + "გ დ ე ვ თ ი ო ღ" + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM + "ა ზ მ ს შ ძ ხ პ" + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER + "ს ხ ქ ზ მ შ ჩ წ" + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER + "ე ვ ჟ ტ უ ფ ქ ყ" + + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP + "Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ" + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM + "Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ" + + AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP + "ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ" + AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM + "ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ" + AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER + "ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ" + AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER + "ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ" + + AF_BLUE_STRING_GREEK_CAPITAL_TOP + "Γ Β Ε Ζ Θ Ο Ω" + AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM + "Β Δ Ζ Ξ Θ Ο" + AF_BLUE_STRING_GREEK_SMALL_BETA_TOP + "β θ δ ζ λ ξ" + AF_BLUE_STRING_GREEK_SMALL + "α ε ι ο π σ τ ω" + AF_BLUE_STRING_GREEK_SMALL_DESCENDER + "β γ η μ ρ φ χ ψ" + + AF_BLUE_STRING_GUJARATI_TOP + "ત ન ઋ ઌ છ ટ ર ૦" + AF_BLUE_STRING_GUJARATI_BOTTOM + "ખ ગ ઘ ઞ ઇ ઈ ઠ જ" + AF_BLUE_STRING_GUJARATI_ASCENDER + "ઈ ઊ િ ી લી શ્ચિ જિ સી" + AF_BLUE_STRING_GUJARATI_DESCENDER + "ુ ૃ ૄ ખુ છૃ છૄ" + AF_BLUE_STRING_GUJARATI_DIGIT_TOP + "૦ ૧ ૨ ૩ ૭" + + AF_BLUE_STRING_GURMUKHI_BASE + "ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ" + AF_BLUE_STRING_GURMUKHI_HEAD + "ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ" + AF_BLUE_STRING_GURMUKHI_TOP + "ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ" + AF_BLUE_STRING_GURMUKHI_BOTTOM + "ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ" + AF_BLUE_STRING_GURMUKHI_DIGIT_TOP + "੦ ੧ ੨ ੩ ੭" + + AF_BLUE_STRING_HEBREW_TOP + "ב ד ה ח ך כ ם ס" + AF_BLUE_STRING_HEBREW_BOTTOM + "ב ט כ ם ס צ" + AF_BLUE_STRING_HEBREW_DESCENDER + "ק ך ן ף ץ" + + AF_BLUE_STRING_KANNADA_TOP + "ಇ ಊ ಐ ಣ ಸಾ ನಾ ದಾ ರಾ" + AF_BLUE_STRING_KANNADA_BOTTOM + "ಅ ಉ ಎ ಲ ೦ ೨ ೬ ೭" + + AF_BLUE_STRING_KHMER_TOP + "ខ ទ ន ឧ ឩ ា" + AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP + "ក្ក ក្ខ ក្គ ក្ថ" + AF_BLUE_STRING_KHMER_BOTTOM + "ខ ឃ ច ឋ ប ម យ ឲ" + AF_BLUE_STRING_KHMER_DESCENDER + "ត្រ រៀ ឲ្យ អឿ" + AF_BLUE_STRING_KHMER_LARGE_DESCENDER + "ន្ត្រៃ ង្ខ្យ ក្បៀ ច្រៀ ន្តឿ ល្បឿ" + + AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP + "᧠ ᧡" + AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM + "᧶ ᧹" + + AF_BLUE_STRING_LAO_TOP + "າ ດ ອ ມ ລ ວ ຣ ງ" + AF_BLUE_STRING_LAO_BOTTOM + "າ ອ ບ ຍ ຣ ຮ ວ ຢ" + AF_BLUE_STRING_LAO_ASCENDER + "ປ ຢ ຟ ຝ" + AF_BLUE_STRING_LAO_LARGE_ASCENDER + "ໂ ໄ ໃ" + AF_BLUE_STRING_LAO_DESCENDER + "ງ ຊ ຖ ຽ ໆ ຯ" + + AF_BLUE_STRING_LATIN_CAPITAL_TOP + "T H E Z O C Q S" + AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM + "H E Z L O C U S" + AF_BLUE_STRING_LATIN_SMALL_F_TOP + "f i j k d b h" + AF_BLUE_STRING_LATIN_SMALL + "x z r o e s c" + AF_BLUE_STRING_LATIN_SMALL_DESCENDER + "p q g j y" + + // we assume that both the subscript and superscript ranges + // don't contain oldstyle digits (actually, most fonts probably + // have digits only in those ranges) + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP + "₀ ₃ ₅ ₇ ₈" + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM + "₀ ₁ ₂ ₃ ₈" + AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP + "ᵢ ⱼ ₕ ₖ ₗ" + AF_BLUE_STRING_LATIN_SUBS_SMALL + "ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ" + AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER + "ᵦ ᵧ ᵨ ᵩ ₚ" + + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP + "⁰ ³ ⁵ ⁷ ᵀ ᴴ ᴱ ᴼ" + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM + "⁰ ¹ ² ³ ᴱ ᴸ ᴼ ᵁ" + AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP + "ᵇ ᵈ ᵏ ʰ ʲ ᶠ ⁱ" + AF_BLUE_STRING_LATIN_SUPS_SMALL + "ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ" + AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER + "ᵖ ʸ ᵍ" + + AF_BLUE_STRING_MALAYALAM_TOP + "ഒ ട ഠ റ ച പ ച്ച പ്പ" + AF_BLUE_STRING_MALAYALAM_BOTTOM + "ട ഠ ധ ശ ഘ ച ഥ ല" + + AF_BLUE_STRING_MYANMAR_TOP + "ခ ဂ င ဒ ဝ ၥ ၊ ။" + AF_BLUE_STRING_MYANMAR_BOTTOM + "င ဎ ဒ ပ ဗ ဝ ၊ ။" + AF_BLUE_STRING_MYANMAR_ASCENDER + "ဩ ြ ၍ ၏ ၆ ါ ိ" + AF_BLUE_STRING_MYANMAR_DESCENDER + "ဉ ည ဥ ဩ ဨ ၂ ၅ ၉" + + AF_BLUE_STRING_SINHALA_TOP + "ඉ ක ඝ ඳ ප ය ල ෆ" + AF_BLUE_STRING_SINHALA_BOTTOM + "එ ඔ ඝ ජ ට ථ ධ ර" + AF_BLUE_STRING_SINHALA_DESCENDER + "ද ඳ උ ල තූ තු බු දු" + + AF_BLUE_STRING_TAMIL_TOP + "உ ஒ ஓ ற ஈ க ங ச" + AF_BLUE_STRING_TAMIL_BOTTOM + "க ச ல ஶ உ ங ட ப" + + AF_BLUE_STRING_TELUGU_TOP + "ఇ ఌ ఙ ఞ ణ ఱ ౯" + AF_BLUE_STRING_TELUGU_BOTTOM + "అ క చ ర ఽ ౨ ౬" + + AF_BLUE_STRING_THAI_TOP + "บ เ แ อ ก า" + AF_BLUE_STRING_THAI_BOTTOM + "บ ป ษ ฯ อ ย ฮ" + AF_BLUE_STRING_THAI_ASCENDER + "ป ฝ ฟ" + AF_BLUE_STRING_THAI_LARGE_ASCENDER + "โ ใ ไ" + AF_BLUE_STRING_THAI_DESCENDER + "ฎ ฏ ฤ ฦ" + AF_BLUE_STRING_THAI_LARGE_DESCENDER + "ญ ฐ" + AF_BLUE_STRING_THAI_DIGIT_TOP + "๐ ๑ ๓" + + +#ifdef AF_CONFIG_OPTION_CJK + + AF_BLUE_STRING_CJK_TOP + "他 们 你 來 們 到 和 地" + " 对 對 就 席 我 时 時 會" + " 来 為 能 舰 說 说 这 這" + " 齊 |" + " 军 同 已 愿 既 星 是 景" + " 民 照 现 現 理 用 置 要" + " 軍 那 配 里 開 雷 露 面" + " 顾" + AF_BLUE_STRING_CJK_BOTTOM + "个 为 人 他 以 们 你 來" + " 個 們 到 和 大 对 對 就" + " 我 时 時 有 来 為 要 說" + " 说 |" + " 主 些 因 它 想 意 理 生" + " 當 看 着 置 者 自 著 裡" + " 过 还 进 進 過 道 還 里" + " 面" + +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + + AF_BLUE_STRING_CJK_LEFT + " 些 们 你 來 們 到 和 地" + " 她 将 將 就 年 得 情 最" + " 样 樣 理 能 說 说 这 這" + " 通 |" + " 即 吗 吧 听 呢 品 响 嗎" + " 师 師 收 断 斷 明 眼 間" + " 间 际 陈 限 除 陳 随 際" + " 隨" + AF_BLUE_STRING_CJK_RIGHT + "事 前 學 将 將 情 想 或" + " 政 斯 新 样 樣 民 沒 没" + " 然 特 现 現 球 第 經 谁" + " 起 |" + " 例 別 别 制 动 動 吗 嗎" + " 增 指 明 朝 期 构 物 确" + " 种 調 调 費 费 那 都 間" + " 间" + +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + +#endif /* AF_CONFIG_OPTION_CJK */ + + +// The blue zone stringsets, as used in the script styles, cf. `afstyles.h'. +// +// The AF_BLUE_PROPERTY_XXX flags are defined in `afblue.h'; here some +// explanations. +// +// A blue zone in general is defined by a reference and an overshoot line. +// During the hinting process, all coordinate values between those two lines +// are set equal to the reference value, provided that the blue zone is not +// wider than 0.75 pixels (otherwise the blue zone gets ignored). All +// entries must have `AF_BLUE_STRING_MAX' as the final line. +// +// During the glyph analysis, edges are sorted from bottom to top, and then +// sequentially checked, edge by edge, against the blue zones in the order +// given below. +// +// +// latin auto-hinter +// ----------------- +// +// Characters in a blue string are automatically classified as having a flat +// (reference) or a round (overshoot) extremum. The blue zone is then set +// up by the mean values of all flat extrema and all round extrema, +// respectively. Only horizontal blue zones (i.e., adjusting vertical +// coordinate values) are supported. +// +// Some scripts like Khmer need character composition to get all necessary +// blue zones, since Unicode only provides an abstract data model that +// doesn't represent all possible glyph shapes. For such character +// clusters, the HarfBuzz library is used to convert them into the +// corresponding glyphs. The largest glyph element (where `largest' can be +// either `largest ascender' or `largest descender') then defines the +// corresponding flat or round extremum. +// +// For the latin auto-hinter, the overshoot should be larger than the +// reference for top zones, and vice versa for bottom zones. +// +// LATIN_TOP +// Take the maximum flat and round coordinate values of the blue string +// characters for computing the blue zone's reference and overshoot +// values. +// +// If not set, take the minimum values. +// +// Mutually exclusive with `LATIN_SUB_TOP'. +// +// LATIN_SUB_TOP +// For all glyphs of a character cluster, compute the maximum flat +// and round coordinate values of each component, then take the +// smallest of the maximum values. The idea is to get the top of +// subscript glyphs, as used in Khmer, for example. Note that +// this mechanism doesn't work for ordinary ligatures. +// +// This flags indicates a secondary blue zone: It gets removed if +// there is a non-LATIN_SUB_TOP blue zone at the same coordinate +// value (after scaling). +// +// Mutually exclusive with `LATIN_TOP'. +// +// LATIN_NEUTRAL +// Ignore round extrema and define the blue zone with flat values only. +// Both top and bottom of contours can match. This is useful for +// scripts like Devanagari where vowel signs attach to the base +// character and are implemented as components of composite glyphs. +// +// If not set, both round and flat extrema are taken into account. +// Additionally, only the top or the bottom of a contour can match, +// depending on the LATIN_TOP flag. +// +// Neutral blue zones should always follow non-neutral blue zones. +// +// LATIN_X_HEIGHT +// Scale all glyphs vertically from the corresponding script to make the +// reference line of this blue zone align on the grid. The scaling +// takes place before all other blue zones get aligned to the grid. +// Only one blue character string of a script style can have this flag. +// +// LATIN_LONG +// Apply an additional constraint for blue zone values: Don't +// necessarily use the extremum as-is but a segment of the topmost (or +// bottommost) contour that is longer than a heuristic threshold, and +// which is not too far away vertically from the real extremum. This +// ensures that small bumps in the outline are ignored (for example, the +// `vertical serifs' found in many Hebrew glyph designs). +// +// The segment must be at least EM/25 font units long, and the distance +// to the extremum must be smaller than EM/4. +// +// +// cjk auto-hinter +// --------------- +// +// Characters in a blue string are *not* automatically classified. Instead, +// first come the characters used for the overshoot value, then the +// character `|', then the characters used for the reference value +// (everything separated by space characters). The blue zone is then set up +// by the mean values of all reference values and all overshoot values, +// respectively. Both horizontal and vertical blue zones (i.e., adjusting +// vertical and horizontal coordinate values, respectively) are supported. +// +// For the cjk auto-hinter, the overshoot should be smaller than the +// reference for top zones, and vice versa for bottom zones. +// +// CJK_TOP +// Take the maximum flat and round coordinate values of the blue string +// characters. If not set, take the minimum values. +// +// CJK_RIGHT +// A synonym for CJK_TOP. If CJK_HORIZ is set, this flag indicates the +// right blue zone, taking horizontal maximum values. +// +// CJK_HORIZ +// Define a blue zone for horizontal hinting (i.e., vertical blue +// zones). If not set, this is a blue zone for vertical hinting. + + +AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: + + AF_BLUE_STRINGSET_ARAB + { AF_BLUE_STRING_ARABIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ARABIC_BOTTOM, 0 } + { AF_BLUE_STRING_ARABIC_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_ARMN + { AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ARMENIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_BENG + { AF_BLUE_STRING_BENGALI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_BENGALI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_BENGALI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_BENGALI_BASE, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_CHER + { AF_BLUE_STRING_CHEROKEE_CAPITAL, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CHEROKEE_CAPITAL, 0 } + { AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CHEROKEE_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_CHEROKEE_SMALL, 0 } + { AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_CYRL + { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_CYRILLIC_SMALL, 0 } + { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_DEVA + { AF_BLUE_STRING_DEVANAGARI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_DEVANAGARI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_DEVANAGARI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_DEVANAGARI_BASE, 0 } + { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_ETHI + { AF_BLUE_STRING_ETHIOPIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ETHIOPIC_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + // blue zones for Mtavruli are missing (not yet defined in Unicode) + AF_BLUE_STRINGSET_GEOR + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 } + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GEOK + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM, 0 } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM, 0 } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GREK + { AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_GREEK_SMALL_BETA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GREEK_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GREEK_SMALL, 0 } + { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GUJR + { AF_BLUE_STRING_GUJARATI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GUJARATI_BOTTOM, 0 } + { AF_BLUE_STRING_GUJARATI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GUJARATI_DESCENDER, 0 } + { AF_BLUE_STRING_GUJARATI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GURU + { AF_BLUE_STRING_GURMUKHI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GURMUKHI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GURMUKHI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GURMUKHI_BOTTOM, 0 } + { AF_BLUE_STRING_GURMUKHI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_HEBR + { AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_LONG } + { AF_BLUE_STRING_HEBREW_BOTTOM, 0 } + { AF_BLUE_STRING_HEBREW_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_KNDA + { AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_KANNADA_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_KHMR + { AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP } + { AF_BLUE_STRING_KHMER_BOTTOM, 0 } + { AF_BLUE_STRING_KHMER_DESCENDER, 0 } + { AF_BLUE_STRING_KHMER_LARGE_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_KHMS + { AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_LAO + { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_LAO_BOTTOM, 0 } + { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LAO_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_LATN + { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_LATIN_SMALL, 0 } + { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_LATB + { AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SUBS_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_LATIN_SUBS_SMALL, 0 } + { AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_LATP + { AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SUPS_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_LATIN_SUPS_SMALL, 0 } + { AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_MLYM + { AF_BLUE_STRING_MALAYALAM_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_MYMR + { AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_MYANMAR_BOTTOM, 0 } + { AF_BLUE_STRING_MYANMAR_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MYANMAR_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_NONE + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_SINH + { AF_BLUE_STRING_SINHALA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_SINHALA_BOTTOM, 0 } + { AF_BLUE_STRING_SINHALA_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_TAML + { AF_BLUE_STRING_TAMIL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_TAMIL_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_TELU + { AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_TELUGU_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_THAI + { AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_THAI_BOTTOM, 0 } + { AF_BLUE_STRING_THAI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_THAI_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_THAI_DESCENDER, 0 } + { AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0 } + { AF_BLUE_STRING_THAI_DIGIT_TOP, 0 } + { AF_BLUE_STRING_MAX, 0 } + + +#ifdef AF_CONFIG_OPTION_CJK + + AF_BLUE_STRINGSET_HANI + { AF_BLUE_STRING_CJK_TOP, AF_BLUE_PROPERTY_CJK_TOP } + { AF_BLUE_STRING_CJK_BOTTOM, 0 } +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + { AF_BLUE_STRING_CJK_LEFT, AF_BLUE_PROPERTY_CJK_HORIZ } + { AF_BLUE_STRING_CJK_RIGHT, AF_BLUE_PROPERTY_CJK_HORIZ | + AF_BLUE_PROPERTY_CJK_RIGHT } +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + { AF_BLUE_STRING_MAX, 0 } + +#endif /* AF_CONFIG_OPTION_CJK */ + + +// END diff --git a/drivers/freetype/src/autofit/afblue.h b/drivers/freetype/src/autofit/afblue.h new file mode 100644 index 0000000000..41f838e457 --- /dev/null +++ b/drivers/freetype/src/autofit/afblue.h @@ -0,0 +1,308 @@ +/* This file has been generated by the Perl script `afblue.pl', */ +/* using data from file `afblue.dat'. */ + +/***************************************************************************/ +/* */ +/* afblue.h */ +/* */ +/* Auto-fitter data for blue strings (specification). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef AFBLUE_H_ +#define AFBLUE_H_ + + +FT_BEGIN_HEADER + + + /* an auxiliary macro to decode a UTF-8 character -- since we only use */ + /* hard-coded, self-converted data, no error checking is performed */ +#define GET_UTF8_CHAR( ch, p ) \ + do \ + { \ + ch = (unsigned char)*p++; \ + if ( ch >= 0x80 ) \ + { \ + FT_UInt len_; \ + \ + \ + if ( ch < 0xE0 ) \ + { \ + len_ = 1; \ + ch &= 0x1F; \ + } \ + else if ( ch < 0xF0 ) \ + { \ + len_ = 2; \ + ch &= 0x0F; \ + } \ + else \ + { \ + len_ = 3; \ + ch &= 0x07; \ + } \ + \ + for ( ; len_ > 0; len_-- ) \ + ch = ( ch << 6 ) | ( *p++ & 0x3F ); \ + } \ + } while ( 0 ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** B L U E S T R I N G S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* At the bottommost level, we define strings for finding blue zones. */ + + +#define AF_BLUE_STRING_MAX_LEN 51 + + /* The AF_Blue_String enumeration values are offsets into the */ + /* `af_blue_strings' array. */ + + typedef enum AF_Blue_String_ + { + AF_BLUE_STRING_ARABIC_TOP = 0, + AF_BLUE_STRING_ARABIC_BOTTOM = 18, + AF_BLUE_STRING_ARABIC_JOIN = 33, + AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP = 36, + AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM = 60, + AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER = 84, + AF_BLUE_STRING_ARMENIAN_SMALL_TOP = 108, + AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM = 132, + AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER = 156, + AF_BLUE_STRING_BENGALI_BASE = 180, + AF_BLUE_STRING_BENGALI_TOP = 212, + AF_BLUE_STRING_BENGALI_HEAD = 240, + AF_BLUE_STRING_CHEROKEE_CAPITAL = 272, + AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER = 304, + AF_BLUE_STRING_CHEROKEE_SMALL = 336, + AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER = 368, + AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 384, + AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 408, + AF_BLUE_STRING_CYRILLIC_SMALL = 432, + AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 456, + AF_BLUE_STRING_DEVANAGARI_BASE = 465, + AF_BLUE_STRING_DEVANAGARI_TOP = 497, + AF_BLUE_STRING_DEVANAGARI_HEAD = 529, + AF_BLUE_STRING_DEVANAGARI_BOTTOM = 561, + AF_BLUE_STRING_ETHIOPIC_TOP = 569, + AF_BLUE_STRING_ETHIOPIC_BOTTOM = 601, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP = 633, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM = 665, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER = 697, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER = 729, + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP = 761, + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM = 793, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP = 825, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM = 857, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER = 889, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER = 921, + AF_BLUE_STRING_GREEK_CAPITAL_TOP = 953, + AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 974, + AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 992, + AF_BLUE_STRING_GREEK_SMALL = 1010, + AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 1034, + AF_BLUE_STRING_GUJARATI_TOP = 1058, + AF_BLUE_STRING_GUJARATI_BOTTOM = 1090, + AF_BLUE_STRING_GUJARATI_ASCENDER = 1122, + AF_BLUE_STRING_GUJARATI_DESCENDER = 1172, + AF_BLUE_STRING_GUJARATI_DIGIT_TOP = 1205, + AF_BLUE_STRING_GURMUKHI_BASE = 1225, + AF_BLUE_STRING_GURMUKHI_HEAD = 1257, + AF_BLUE_STRING_GURMUKHI_TOP = 1289, + AF_BLUE_STRING_GURMUKHI_BOTTOM = 1321, + AF_BLUE_STRING_GURMUKHI_DIGIT_TOP = 1353, + AF_BLUE_STRING_HEBREW_TOP = 1373, + AF_BLUE_STRING_HEBREW_BOTTOM = 1397, + AF_BLUE_STRING_HEBREW_DESCENDER = 1415, + AF_BLUE_STRING_KANNADA_TOP = 1430, + AF_BLUE_STRING_KANNADA_BOTTOM = 1474, + AF_BLUE_STRING_KHMER_TOP = 1506, + AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 1530, + AF_BLUE_STRING_KHMER_BOTTOM = 1570, + AF_BLUE_STRING_KHMER_DESCENDER = 1602, + AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 1636, + AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 1723, + AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 1731, + AF_BLUE_STRING_LAO_TOP = 1739, + AF_BLUE_STRING_LAO_BOTTOM = 1771, + AF_BLUE_STRING_LAO_ASCENDER = 1803, + AF_BLUE_STRING_LAO_LARGE_ASCENDER = 1819, + AF_BLUE_STRING_LAO_DESCENDER = 1831, + AF_BLUE_STRING_LATIN_CAPITAL_TOP = 1855, + AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 1871, + AF_BLUE_STRING_LATIN_SMALL_F_TOP = 1887, + AF_BLUE_STRING_LATIN_SMALL = 1901, + AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 1915, + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 1925, + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 1945, + AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 1965, + AF_BLUE_STRING_LATIN_SUBS_SMALL = 1985, + AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 2021, + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 2041, + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 2072, + AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 2101, + AF_BLUE_STRING_LATIN_SUPS_SMALL = 2127, + AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 2152, + AF_BLUE_STRING_MALAYALAM_TOP = 2163, + AF_BLUE_STRING_MALAYALAM_BOTTOM = 2207, + AF_BLUE_STRING_MYANMAR_TOP = 2239, + AF_BLUE_STRING_MYANMAR_BOTTOM = 2271, + AF_BLUE_STRING_MYANMAR_ASCENDER = 2303, + AF_BLUE_STRING_MYANMAR_DESCENDER = 2331, + AF_BLUE_STRING_SINHALA_TOP = 2363, + AF_BLUE_STRING_SINHALA_BOTTOM = 2395, + AF_BLUE_STRING_SINHALA_DESCENDER = 2427, + AF_BLUE_STRING_TAMIL_TOP = 2471, + AF_BLUE_STRING_TAMIL_BOTTOM = 2503, + AF_BLUE_STRING_TELUGU_TOP = 2535, + AF_BLUE_STRING_TELUGU_BOTTOM = 2563, + AF_BLUE_STRING_THAI_TOP = 2591, + AF_BLUE_STRING_THAI_BOTTOM = 2615, + AF_BLUE_STRING_THAI_ASCENDER = 2643, + AF_BLUE_STRING_THAI_LARGE_ASCENDER = 2655, + AF_BLUE_STRING_THAI_DESCENDER = 2667, + AF_BLUE_STRING_THAI_LARGE_DESCENDER = 2683, + AF_BLUE_STRING_THAI_DIGIT_TOP = 2691, + af_blue_1_1 = 2702, +#ifdef AF_CONFIG_OPTION_CJK + AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1, + AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203, + af_blue_1_1_1 = af_blue_1_1 + 404, +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + AF_BLUE_STRING_CJK_LEFT = af_blue_1_1_1 + 1, + AF_BLUE_STRING_CJK_RIGHT = af_blue_1_1_1 + 204, + af_blue_1_1_2 = af_blue_1_1_1 + 405, +#else + af_blue_1_1_2 = af_blue_1_1_1 + 0, +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + af_blue_1_2 = af_blue_1_1_2 + 0, +#else + af_blue_1_2 = af_blue_1_1 + 0, +#endif /* AF_CONFIG_OPTION_CJK */ + + + AF_BLUE_STRING_MAX /* do not remove */ + + } AF_Blue_String; + + + FT_LOCAL_ARRAY( char ) + af_blue_strings[]; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** B L U E S T R I N G S E T S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* The next level is to group blue strings into style-specific sets. */ + + + /* Properties are specific to a writing system. We assume that a given */ + /* blue string can't be used in more than a single writing system, which */ + /* is a safe bet. */ +#define AF_BLUE_PROPERTY_LATIN_TOP ( 1U << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_LATIN_SUB_TOP ( 1U << 1 ) +#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 2 ) +#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 3 ) +#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 4 ) + +#define AF_BLUE_PROPERTY_CJK_TOP ( 1U << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1U << 1 ) /* must have value 2 */ +#define AF_BLUE_PROPERTY_CJK_RIGHT AF_BLUE_PROPERTY_CJK_TOP + + +#define AF_BLUE_STRINGSET_MAX_LEN 8 + + /* The AF_Blue_Stringset enumeration values are offsets into the */ + /* `af_blue_stringsets' array. */ + + typedef enum AF_Blue_Stringset_ + { + AF_BLUE_STRINGSET_ARAB = 0, + AF_BLUE_STRINGSET_ARMN = 4, + AF_BLUE_STRINGSET_BENG = 11, + AF_BLUE_STRINGSET_CHER = 16, + AF_BLUE_STRINGSET_CYRL = 23, + AF_BLUE_STRINGSET_DEVA = 29, + AF_BLUE_STRINGSET_ETHI = 35, + AF_BLUE_STRINGSET_GEOR = 38, + AF_BLUE_STRINGSET_GEOK = 43, + AF_BLUE_STRINGSET_GREK = 50, + AF_BLUE_STRINGSET_GUJR = 57, + AF_BLUE_STRINGSET_GURU = 63, + AF_BLUE_STRINGSET_HEBR = 69, + AF_BLUE_STRINGSET_KNDA = 73, + AF_BLUE_STRINGSET_KHMR = 76, + AF_BLUE_STRINGSET_KHMS = 82, + AF_BLUE_STRINGSET_LAO = 85, + AF_BLUE_STRINGSET_LATN = 91, + AF_BLUE_STRINGSET_LATB = 98, + AF_BLUE_STRINGSET_LATP = 105, + AF_BLUE_STRINGSET_MLYM = 112, + AF_BLUE_STRINGSET_MYMR = 115, + AF_BLUE_STRINGSET_NONE = 120, + AF_BLUE_STRINGSET_SINH = 121, + AF_BLUE_STRINGSET_TAML = 125, + AF_BLUE_STRINGSET_TELU = 128, + AF_BLUE_STRINGSET_THAI = 131, + af_blue_2_1 = 139, +#ifdef AF_CONFIG_OPTION_CJK + AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0, + af_blue_2_1_1 = af_blue_2_1 + 2, +#ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT + af_blue_2_1_2 = af_blue_2_1_1 + 2, +#else + af_blue_2_1_2 = af_blue_2_1_1 + 0, +#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ + af_blue_2_2 = af_blue_2_1_2 + 1, +#else + af_blue_2_2 = af_blue_2_1 + 0, +#endif /* AF_CONFIG_OPTION_CJK */ + + + AF_BLUE_STRINGSET_MAX /* do not remove */ + + } AF_Blue_Stringset; + + + typedef struct AF_Blue_StringRec_ + { + AF_Blue_String string; + FT_UShort properties; + + } AF_Blue_StringRec; + + + FT_LOCAL_ARRAY( AF_Blue_StringRec ) + af_blue_stringsets[]; + +/* */ + +FT_END_HEADER + + +#endif /* AFBLUE_H_ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afblue.hin b/drivers/freetype/src/autofit/afblue.hin new file mode 100644 index 0000000000..dd44e77254 --- /dev/null +++ b/drivers/freetype/src/autofit/afblue.hin @@ -0,0 +1,146 @@ +/***************************************************************************/ +/* */ +/* afblue.h */ +/* */ +/* Auto-fitter data for blue strings (specification). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef AFBLUE_H_ +#define AFBLUE_H_ + + +FT_BEGIN_HEADER + + + /* an auxiliary macro to decode a UTF-8 character -- since we only use */ + /* hard-coded, self-converted data, no error checking is performed */ +#define GET_UTF8_CHAR( ch, p ) \ + do \ + { \ + ch = (unsigned char)*p++; \ + if ( ch >= 0x80 ) \ + { \ + FT_UInt len_; \ + \ + \ + if ( ch < 0xE0 ) \ + { \ + len_ = 1; \ + ch &= 0x1F; \ + } \ + else if ( ch < 0xF0 ) \ + { \ + len_ = 2; \ + ch &= 0x0F; \ + } \ + else \ + { \ + len_ = 3; \ + ch &= 0x07; \ + } \ + \ + for ( ; len_ > 0; len_-- ) \ + ch = ( ch << 6 ) | ( *p++ & 0x3F ); \ + } \ + } while ( 0 ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** B L U E S T R I N G S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* At the bottommost level, we define strings for finding blue zones. */ + + +#define AF_BLUE_STRING_MAX_LEN @AF_BLUE_STRING_MAX_LEN@ + + /* The AF_Blue_String enumeration values are offsets into the */ + /* `af_blue_strings' array. */ + + typedef enum AF_Blue_String_ + { +@AF_BLUE_STRING_ENUM@ + + AF_BLUE_STRING_MAX /* do not remove */ + + } AF_Blue_String; + + + FT_LOCAL_ARRAY( char ) + af_blue_strings[]; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** B L U E S T R I N G S E T S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* The next level is to group blue strings into style-specific sets. */ + + + /* Properties are specific to a writing system. We assume that a given */ + /* blue string can't be used in more than a single writing system, which */ + /* is a safe bet. */ +#define AF_BLUE_PROPERTY_LATIN_TOP ( 1U << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_LATIN_SUB_TOP ( 1U << 1 ) +#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 2 ) +#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 3 ) +#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 4 ) + +#define AF_BLUE_PROPERTY_CJK_TOP ( 1U << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1U << 1 ) /* must have value 2 */ +#define AF_BLUE_PROPERTY_CJK_RIGHT AF_BLUE_PROPERTY_CJK_TOP + + +#define AF_BLUE_STRINGSET_MAX_LEN @AF_BLUE_STRINGSET_MAX_LEN@ + + /* The AF_Blue_Stringset enumeration values are offsets into the */ + /* `af_blue_stringsets' array. */ + + typedef enum AF_Blue_Stringset_ + { +@AF_BLUE_STRINGSET_ENUM@ + + AF_BLUE_STRINGSET_MAX /* do not remove */ + + } AF_Blue_Stringset; + + + typedef struct AF_Blue_StringRec_ + { + AF_Blue_String string; + FT_UShort properties; + + } AF_Blue_StringRec; + + + FT_LOCAL_ARRAY( AF_Blue_StringRec ) + af_blue_stringsets[]; + +/* */ + +FT_END_HEADER + + +#endif /* AFBLUE_H_ */ + + +/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afcjk.c b/drivers/freetype/src/autofit/afcjk.c index f69a528e3b..4823c1d7f8 100644 --- a/drivers/freetype/freetype/src/autofit/afcjk.c +++ b/drivers/freetype/src/autofit/afcjk.c @@ -2,9 +2,9 @@ /* */ /* afcjk.c */ /* */ -/* Auto-fitter hinting routines for CJK script (body). */ +/* Auto-fitter hinting routines for CJK writing system (body). */ /* */ -/* Copyright 2006-2013 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,7 +26,8 @@ #include FT_ADVANCES_H #include FT_INTERNAL_DEBUG_H -#include "aftypes.h" +#include "afglobal.h" +#include "afpic.h" #include "aflatin.h" @@ -73,6 +74,12 @@ AF_GlyphHintsRec hints[1]; + FT_TRACE5(( "\n" + "cjk standard widths computation (style `%s')\n" + "===================================================\n" + "\n", + af_style_names[metrics->root.style_class->style] )); + af_glyph_hints_init( hints, face->memory ); metrics->axis[AF_DIMENSION_HORZ].width_count = 0; @@ -80,17 +87,75 @@ { FT_Error error; - FT_UInt glyph_index; + FT_ULong glyph_index; int dim; AF_CJKMetricsRec dummy[1]; AF_Scaler scaler = &dummy->root.scaler; +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = metrics->root.globals; +#endif + + AF_StyleClass style_class = metrics->root.style_class; + AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET + [style_class->script]; + + void* shaper_buf; + const char* p; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_ULong ch = 0; +#endif + + p = script_class->standard_charstring; + shaper_buf = af_shaper_buf_create( face ); + + /* We check a list of standard characters. The first match wins. */ + + glyph_index = 0; + while ( *p ) + { + unsigned int num_idx; + +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; +#endif + + + while ( *p == ' ' ) + p++; - glyph_index = FT_Get_Char_Index( face, - metrics->root.clazz->standard_char ); - if ( glyph_index == 0 ) +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif + + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) + continue; + + /* otherwise exit loop if we have a result */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + NULL, + NULL ); + if ( glyph_index ) + break; + } + + af_shaper_buf_destroy( face, shaper_buf ); + + if ( !glyph_index ) + goto Exit; + + if ( !glyph_index ) goto Exit; + FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n", + ch, glyph_index )); + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); if ( error || face->glyph->outline.n_points <= 0 ) goto Exit; @@ -108,7 +173,7 @@ scaler->render_mode = FT_RENDER_MODE_NORMAL; scaler->flags = 0; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy ); error = af_glyph_hints_reload( hints, &face->glyph->outline ); if ( error ) @@ -122,11 +187,21 @@ FT_UInt num_widths = 0; - error = af_latin_hints_compute_segments( hints, (AF_Dimension)dim ); + error = af_latin_hints_compute_segments( hints, + (AF_Dimension)dim ); if ( error ) goto Exit; - af_latin_hints_link_segments( hints, (AF_Dimension)dim ); + /* + * We assume that the glyphs selected for the stem width + * computation are `featureless' enough so that the linking + * algorithm works fine without adjustments of its scoring + * function. + */ + af_latin_hints_link_segments( hints, + 0, + NULL, + (AF_Dimension)dim ); seg = axhints->segments; limit = seg + axhints->num_segments; @@ -151,7 +226,7 @@ } /* this also replaces multiple almost identical stem widths */ - /* with a single one (the value 100 is heuristic) */ + /* with a single one (the value 100 is heuristic) */ af_sort_and_quantize_widths( &num_widths, axis->widths, dummy->units_per_em / 100 ); axis->width_count = num_widths; @@ -171,264 +246,239 @@ axis->edge_distance_threshold = stdw / 5; axis->standard_width = stdw; axis->extra_light = 0; + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_UInt i; + + + FT_TRACE5(( "%s widths:\n", + dim == AF_DIMENSION_VERT ? "horizontal" + : "vertical" )); + + FT_TRACE5(( " %d (standard)", axis->standard_width )); + for ( i = 1; i < axis->width_count; i++ ) + FT_TRACE5(( " %d", axis->widths[i].org )); + + FT_TRACE5(( "\n" )); + } +#endif } } + FT_TRACE5(( "\n" )); + af_glyph_hints_done( hints ); } -#define AF_CJK_MAX_TEST_CHARACTERS 32 + /* Find all blue zones. */ + static void + af_cjk_metrics_init_blues( AF_CJKMetrics metrics, + FT_Face face ) + { + FT_Pos fills[AF_BLUE_STRING_MAX_LEN]; + FT_Pos flats[AF_BLUE_STRING_MAX_LEN]; - /* Each blue zone has two types of fill and unfill, this is, */ - /* filling the entire glyph square or not. */ + FT_UInt num_fills; + FT_UInt num_flats; - enum - { - AF_CJK_BLUE_TYPE_FILL, - AF_CJK_BLUE_TYPE_UNFILL, - AF_CJK_BLUE_TYPE_MAX - }; + FT_Bool fill; + AF_CJKBlue blue; + FT_Error error; + AF_CJKAxis axis; + FT_Outline outline; - /* Put some common and representative Han Ideographs characters here. */ - static const FT_ULong af_cjk_hani_blue_chars[AF_CJK_BLUE_MAX] - [AF_CJK_BLUE_TYPE_MAX] - [AF_CJK_MAX_TEST_CHARACTERS] = - { - { - { - 0x4ED6, 0x4EEC, 0x4F60, 0x4F86, 0x5011, 0x5230, 0x548C, 0x5730, - 0x5BF9, 0x5C0D, 0x5C31, 0x5E2D, 0x6211, 0x65F6, 0x6642, 0x6703, - 0x6765, 0x70BA, 0x80FD, 0x8230, 0x8AAA, 0x8BF4, 0x8FD9, 0x9019, - 0x9F4A /* top fill */ - }, - { - 0x519B, 0x540C, 0x5DF2, 0x613F, 0x65E2, 0x661F, 0x662F, 0x666F, - 0x6C11, 0x7167, 0x73B0, 0x73FE, 0x7406, 0x7528, 0x7F6E, 0x8981, - 0x8ECD, 0x90A3, 0x914D, 0x91CC, 0x958B, 0x96F7, 0x9732, 0x9762, - 0x987E /* top unfill */ - } - }, - { - { - 0x4E2A, 0x4E3A, 0x4EBA, 0x4ED6, 0x4EE5, 0x4EEC, 0x4F60, 0x4F86, - 0x500B, 0x5011, 0x5230, 0x548C, 0x5927, 0x5BF9, 0x5C0D, 0x5C31, - 0x6211, 0x65F6, 0x6642, 0x6709, 0x6765, 0x70BA, 0x8981, 0x8AAA, - 0x8BF4 /* bottom fill */ - }, - { - 0x4E3B, 0x4E9B, 0x56E0, 0x5B83, 0x60F3, 0x610F, 0x7406, 0x751F, - 0x7576, 0x770B, 0x7740, 0x7F6E, 0x8005, 0x81EA, 0x8457, 0x88E1, - 0x8FC7, 0x8FD8, 0x8FDB, 0x9032, 0x904E, 0x9053, 0x9084, 0x91CC, - 0x9762 /* bottom unfill */ - } - }, -#ifndef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT - { {0x0000}, {0x0000} }, - { {0x0000}, {0x0000} } -#else - { - { - 0x4E9B, 0x4EEC, 0x4F60, 0x4F86, 0x5011, 0x5230, 0x548C, 0x5730, - 0x5979, 0x5C06, 0x5C07, 0x5C31, 0x5E74, 0x5F97, 0x60C5, 0x6700, - 0x6837, 0x6A23, 0x7406, 0x80FD, 0x8AAA, 0x8BF4, 0x8FD9, 0x9019, - 0x901A /* left fill */ - }, - { - 0x5373, 0x5417, 0x5427, 0x542C, 0x5462, 0x54C1, 0x54CD, 0x55CE, - 0x5E08, 0x5E2B, 0x6536, 0x65AD, 0x65B7, 0x660E, 0x773C, 0x9593, - 0x95F4, 0x9645, 0x9648, 0x9650, 0x9664, 0x9673, 0x968F, 0x969B, - 0x96A8 /* left unfill */ - } - }, - { - { - 0x4E8B, 0x524D, 0x5B78, 0x5C06, 0x5C07, 0x60C5, 0x60F3, 0x6216, - 0x653F, 0x65AF, 0x65B0, 0x6837, 0x6A23, 0x6C11, 0x6C92, 0x6CA1, - 0x7136, 0x7279, 0x73B0, 0x73FE, 0x7403, 0x7B2C, 0x7D93, 0x8C01, - 0x8D77 /* right fill */ - }, - { - 0x4F8B, 0x5225, 0x522B, 0x5236, 0x52A8, 0x52D5, 0x5417, 0x55CE, - 0x589E, 0x6307, 0x660E, 0x671D, 0x671F, 0x6784, 0x7269, 0x786E, - 0x79CD, 0x8ABF, 0x8C03, 0x8CBB, 0x8D39, 0x90A3, 0x90FD, 0x9593, - 0x95F4 /* right unfill */ - } - } -#endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ - }; + AF_StyleClass sc = metrics->root.style_class; + AF_Blue_Stringset bss = sc->blue_stringset; + const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; - /* Calculate blue zones for all the CJK_BLUE_XXX's. */ + void* shaper_buf; - static void - af_cjk_metrics_init_blues( AF_CJKMetrics metrics, - FT_Face face, - const FT_ULong blue_chars - [AF_CJK_BLUE_MAX] - [AF_CJK_BLUE_TYPE_MAX] - [AF_CJK_MAX_TEST_CHARACTERS] ) - { - FT_Pos fills[AF_CJK_MAX_TEST_CHARACTERS]; - FT_Pos flats[AF_CJK_MAX_TEST_CHARACTERS]; - FT_Int num_fills; - FT_Int num_flats; + /* we walk over the blue character strings as specified in the */ + /* style's entry in the `af_blue_stringset' array, computing its */ + /* extremum points (depending on the string properties) */ - FT_Int bb; - AF_CJKBlue blue; - FT_Error error; - AF_CJKAxis axis; - FT_GlyphSlot glyph = face->glyph; + FT_TRACE5(( "cjk blue zones computation\n" + "==========================\n" + "\n" )); -#ifdef FT_DEBUG_LEVEL_TRACE - FT_String* cjk_blue_name[AF_CJK_BLUE_MAX] = { - (FT_String*)"top", - (FT_String*)"bottom", - (FT_String*)"left", - (FT_String*)"right" - }; - FT_String* cjk_blue_type_name[AF_CJK_BLUE_TYPE_MAX] = { - (FT_String*)"filled", - (FT_String*)"unfilled" - }; -#endif + shaper_buf = af_shaper_buf_create( face ); + + for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) + { + const char* p = &af_blue_strings[bs->string]; + FT_Pos* blue_ref; + FT_Pos* blue_shoot; - /* We compute the blues simply by loading each character from the */ - /* `blue_chars[blues]' string, then computing its extreme points */ - /* (depending blue zone type etc.). */ + if ( AF_CJK_IS_HORIZ_BLUE( bs ) ) + axis = &metrics->axis[AF_DIMENSION_HORZ]; + else + axis = &metrics->axis[AF_DIMENSION_VERT]; - FT_TRACE5(( "cjk blue zones computation\n" )); - FT_TRACE5(( "------------------------------------------------\n" )); +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_String* cjk_blue_name[4] = + { + (FT_String*)"bottom", /* -- , -- */ + (FT_String*)"top", /* -- , TOP */ + (FT_String*)"left", /* HORIZ, -- */ + (FT_String*)"right" /* HORIZ, TOP */ + }; - for ( bb = 0; bb < AF_CJK_BLUE_MAX; bb++ ) - { - FT_Int fill_type; - FT_Pos* blue_ref; - FT_Pos* blue_shoot; + FT_TRACE5(( "blue zone %d (%s):\n", + axis->blue_count, + cjk_blue_name[AF_CJK_IS_HORIZ_BLUE( bs ) | + AF_CJK_IS_TOP_BLUE( bs ) ] )); + } +#endif /* FT_DEBUG_LEVEL_TRACE */ num_fills = 0; num_flats = 0; - for ( fill_type = 0; fill_type < AF_CJK_BLUE_TYPE_MAX; fill_type++ ) + fill = 1; /* start with characters that define fill values */ + FT_TRACE5(( " [overshoot values]\n" )); + + while ( *p ) { - const FT_ULong* p = blue_chars[bb][fill_type]; - const FT_ULong* limit = p + AF_CJK_MAX_TEST_CHARACTERS; - FT_Bool fill = FT_BOOL( - fill_type == AF_CJK_BLUE_TYPE_FILL ); + FT_ULong glyph_index; + FT_Pos best_pos; /* same as points.y or points.x, resp. */ + FT_Int best_point; + FT_Vector* points; + unsigned int num_idx; - FT_TRACE5(( "cjk blue %s/%s\n", cjk_blue_name[bb], - cjk_blue_type_name[fill_type] )); +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; + FT_ULong ch; +#endif - for ( ; p < limit && *p; p++ ) - { - FT_UInt glyph_index; - FT_Pos best_pos; /* same as points.y */ - FT_Int best_point; - FT_Vector* points; + while ( *p == ' ' ) + p++; +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif - FT_TRACE5(( " U+%lX...", *p )); + /* switch to characters that define flat values */ + if ( *p == '|' ) + { + fill = 0; + FT_TRACE5(( " [reference values]\n" )); + p++; + continue; + } - /* load the character in the face -- skip unknown or empty ones */ - glyph_index = FT_Get_Char_Index( face, *p ); - if ( glyph_index == 0 ) - { - FT_TRACE5(( "unavailable\n" )); - continue; - } + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) + continue; - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error || glyph->outline.n_points <= 0 ) - { - FT_TRACE5(( "no outline\n" )); - continue; - } + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + NULL, + NULL ); + if ( glyph_index == 0 ) + { + FT_TRACE5(( " U+%04lX unavailable\n", ch )); + continue; + } - /* now compute min or max point indices and coordinates */ - points = glyph->outline.points; - best_point = -1; - best_pos = 0; /* make compiler happy */ + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + outline = face->glyph->outline; + if ( error || outline.n_points <= 2 ) + { + FT_TRACE5(( " U+%04lX contains no (usable) outlines\n", ch )); + continue; + } - { - FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; + /* now compute min or max point indices and coordinates */ + points = outline.points; + best_point = -1; + best_pos = 0; /* make compiler happy */ + { + FT_Int nn; + FT_Int first = 0; + FT_Int last = -1; - for ( nn = 0; - nn < glyph->outline.n_contours; - first = last + 1, nn++ ) - { - FT_Int pp; + + for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) + { + FT_Int pp; - last = glyph->outline.contours[nn]; + last = outline.contours[nn]; - /* Avoid single-point contours since they are never */ - /* rasterized. In some fonts, they correspond to mark */ - /* attachment points which are way outside of the glyph's */ - /* real outline. */ - if ( last <= first ) - continue; + /* Avoid single-point contours since they are never rasterized. */ + /* In some fonts, they correspond to mark attachment points */ + /* which are way outside of the glyph's real outline. */ + if ( last <= first ) + continue; - switch ( bb ) + if ( AF_CJK_IS_HORIZ_BLUE( bs ) ) + { + if ( AF_CJK_IS_RIGHT_BLUE( bs ) ) { - case AF_CJK_BLUE_TOP: for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y > best_pos ) + if ( best_point < 0 || points[pp].x > best_pos ) { best_point = pp; - best_pos = points[pp].y; + best_pos = points[pp].x; } - break; - - case AF_CJK_BLUE_BOTTOM: + } + else + { for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y < best_pos ) + if ( best_point < 0 || points[pp].x < best_pos ) { best_point = pp; - best_pos = points[pp].y; + best_pos = points[pp].x; } - break; - - case AF_CJK_BLUE_LEFT: + } + } + else + { + if ( AF_CJK_IS_TOP_BLUE( bs ) ) + { for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].x < best_pos ) + if ( best_point < 0 || points[pp].y > best_pos ) { best_point = pp; - best_pos = points[pp].x; + best_pos = points[pp].y; } - break; - - case AF_CJK_BLUE_RIGHT: + } + else + { for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].x > best_pos ) + if ( best_point < 0 || points[pp].y < best_pos ) { best_point = pp; - best_pos = points[pp].x; + best_pos = points[pp].y; } - break; - - default: - ; } } - FT_TRACE5(( "best_pos=%5ld\n", best_pos )); } - if ( fill ) - fills[num_fills++] = best_pos; - else - flats[num_flats++] = best_pos; + FT_TRACE5(( " U+%04lX: best_pos = %5ld\n", ch, best_pos )); } - } + + if ( fill ) + fills[num_fills++] = best_pos; + else + flats[num_flats++] = best_pos; + + } /* end while loop */ if ( num_flats == 0 && num_fills == 0 ) { @@ -436,34 +486,30 @@ * we couldn't find a single glyph to compute this blue zone, * we will simply ignore it then */ - FT_TRACE5(( "empty\n" )); + FT_TRACE5(( " empty\n" )); continue; } - /* we have computed the contents of the `fill' and `flats' tables, */ - /* now determine the reference position of the blue -- */ - /* we simply take the median value after a simple sort */ - af_sort_pos( num_flats, flats ); + /* we have computed the contents of the `fill' and `flats' tables, */ + /* now determine the reference and overshoot position of the blue -- */ + /* we simply take the median value after a simple sort */ af_sort_pos( num_fills, fills ); + af_sort_pos( num_flats, flats ); - if ( AF_CJK_BLUE_TOP == bb || AF_CJK_BLUE_BOTTOM == bb ) - axis = &metrics->axis[AF_DIMENSION_VERT]; - else - axis = &metrics->axis[AF_DIMENSION_HORZ]; - - blue = & axis->blues[axis->blue_count]; - blue_ref = & blue->ref.org; - blue_shoot = & blue->shoot.org; + blue = &axis->blues[axis->blue_count]; + blue_ref = &blue->ref.org; + blue_shoot = &blue->shoot.org; axis->blue_count++; + if ( num_flats == 0 ) { - *blue_ref = fills[num_fills / 2]; + *blue_ref = *blue_shoot = fills[num_fills / 2]; } else if ( num_fills == 0 ) { - *blue_ref = flats[num_flats / 2]; + *blue_ref = *blue_shoot = flats[num_flats / 2]; } else @@ -481,51 +527,71 @@ FT_Bool under_ref = FT_BOOL( shoot < ref ); - if ( ( AF_CJK_BLUE_TOP == bb || - AF_CJK_BLUE_RIGHT == bb ) ^ under_ref ) - *blue_shoot = *blue_ref = ( shoot + ref ) / 2; + /* AF_CJK_IS_TOP_BLUE covers `right' and `top' */ + if ( AF_CJK_IS_TOP_BLUE( bs ) ^ under_ref ) + { + *blue_ref = + *blue_shoot = ( shoot + ref ) / 2; + + FT_TRACE5(( " [reference smaller than overshoot," + " taking mean value]\n" )); + } } blue->flags = 0; - if ( AF_CJK_BLUE_TOP == bb ) - blue->flags |= AF_CJK_BLUE_IS_TOP; - else if ( AF_CJK_BLUE_RIGHT == bb ) - blue->flags |= AF_CJK_BLUE_IS_RIGHT; + if ( AF_CJK_IS_TOP_BLUE( bs ) ) + blue->flags |= AF_CJK_BLUE_TOP; - FT_TRACE5(( "-- cjk %s bluezone ref = %ld shoot = %ld\n", - cjk_blue_name[bb], *blue_ref, *blue_shoot )); - } + FT_TRACE5(( " -> reference = %ld\n" + " overshoot = %ld\n", + *blue_ref, *blue_shoot )); + + } /* end for loop */ + + af_shaper_buf_destroy( face, shaper_buf ); + + FT_TRACE5(( "\n" )); return; } /* Basically the Latin version with type AF_CJKMetrics for metrics. */ + FT_LOCAL_DEF( void ) af_cjk_metrics_check_digits( AF_CJKMetrics metrics, FT_Face face ) { - FT_UInt i; FT_Bool started = 0, same_width = 1; FT_Fixed advance, old_advance = 0; + void* shaper_buf; + + /* in all supported charmaps, digits have character codes 0x30-0x39 */ + const char digits[] = "0 1 2 3 4 5 6 7 8 9"; + const char* p; + - /* check whether all ASCII digits have the same advance width; */ - /* digit `0' is 0x30 in all supported charmaps */ - for ( i = 0x30; i <= 0x39; i++ ) + p = digits; + shaper_buf = af_shaper_buf_create( face ); + + while ( *p ) { - FT_UInt glyph_index; + FT_ULong glyph_index; + unsigned int num_idx; - glyph_index = FT_Get_Char_Index( face, i ); - if ( glyph_index == 0 ) + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) continue; - if ( FT_Get_Advance( face, glyph_index, - FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM, - &advance ) ) + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + &advance, + NULL ); + if ( !glyph_index ) continue; if ( started ) @@ -543,10 +609,14 @@ } } + af_shaper_buf_destroy( face, shaper_buf ); + metrics->root.digits_have_same_width = same_width; } + /* Initialize global metrics. */ + FT_LOCAL_DEF( FT_Error ) af_cjk_metrics_init( AF_CJKMetrics metrics, FT_Face face ) @@ -556,21 +626,21 @@ metrics->units_per_em = face->units_per_EM; - if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) - face->charmap = NULL; - else + if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) { af_cjk_metrics_init_widths( metrics, face ); - af_cjk_metrics_init_blues( metrics, face, af_cjk_hani_blue_chars ); + af_cjk_metrics_init_blues( metrics, face ); af_cjk_metrics_check_digits( metrics, face ); } FT_Set_Charmap( face, oldmap ); - return FT_Err_Ok; } + /* Adjust scaling value, then scale and shift widths */ + /* and blue zones (if applicable) for given dimension. */ + static void af_cjk_metrics_scale_dim( AF_CJKMetrics metrics, AF_Scaler scaler, @@ -582,8 +652,6 @@ FT_UInt nn; - axis = &metrics->axis[dim]; - if ( dim == AF_DIMENSION_HORZ ) { scale = scaler->x_scale; @@ -595,6 +663,8 @@ delta = scaler->y_delta; } + axis = &metrics->axis[dim]; + if ( axis->org_scale == scale && axis->org_delta == delta ) return; @@ -650,12 +720,13 @@ blue->shoot.fit = blue->ref.fit - delta2; - FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]: " - "ref: cur=%.2f fit=%.2f shoot: cur=%.2f fit=%.2f\n", - ( dim == AF_DIMENSION_HORZ ) ? 'H' : 'V', - nn, blue->ref.org, blue->shoot.org, - blue->ref.cur / 64.0, blue->ref.fit / 64.0, - blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); + FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]:\n" + " ref: cur=%.2f fit=%.2f\n" + " shoot: cur=%.2f fit=%.2f\n", + ( dim == AF_DIMENSION_HORZ ) ? 'H' : 'V', + nn, blue->ref.org, blue->shoot.org, + blue->ref.cur / 64.0, blue->ref.fit / 64.0, + blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); blue->flags |= AF_CJK_BLUE_ACTIVE; } @@ -663,10 +734,14 @@ } + /* Scale global values in both directions. */ + FT_LOCAL_DEF( void ) af_cjk_metrics_scale( AF_CJKMetrics metrics, AF_Scaler scaler ) { + /* we copy the whole structure since the x and y scaling values */ + /* are not modified, contrary to e.g. the `latin' auto-hinter */ metrics->root.scaler = *scaler; af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); @@ -674,6 +749,22 @@ } + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + FT_LOCAL_DEF( void ) + af_cjk_get_standard_widths( AF_CJKMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -682,6 +773,9 @@ /*************************************************************************/ /*************************************************************************/ + + /* Walk over all contours and compute its segments. */ + static FT_Error af_cjk_hints_compute_segments( AF_GlyphHints hints, AF_Dimension dim ) @@ -703,8 +797,8 @@ { AF_Point pt = seg->first; AF_Point last = seg->last; - AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); - AF_Flags f1; + FT_UInt f0 = pt->flags & AF_FLAG_CONTROL; + FT_UInt f1; seg->flags &= ~AF_EDGE_ROUND; @@ -712,7 +806,7 @@ for ( ; pt != last; f0 = f1 ) { pt = pt->next; - f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); + f1 = pt->flags & AF_FLAG_CONTROL; if ( !f0 && !f1 ) break; @@ -748,10 +842,6 @@ /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { - /* the fake segments are for metrics hinting only */ - if ( seg1->first == seg1->last ) - continue; - if ( seg1->dir != major_dir ) continue; @@ -850,19 +940,19 @@ if ( link == seg2 ) { - seg->link = 0; + seg->link = NULL; seg->serif = link1; } else if ( link == link2 ) { - seg->link = 0; + seg->link = NULL; seg->serif = seg1; } } } else { - seg1->link = link1->link = 0; + seg1->link = link1->link = NULL; break; } @@ -876,15 +966,12 @@ if ( seg2 ) { - seg2->num_linked++; if ( seg2->link != seg1 ) { - seg1->link = 0; + seg1->link = NULL; if ( seg2->score < dist_threshold || seg1->score < seg2->score * 4 ) seg1->serif = seg2->link; - else - seg2->num_linked--; } } } @@ -938,7 +1025,7 @@ for ( seg = segments; seg < segment_limit; seg++ ) { - AF_Edge found = 0; + AF_Edge found = NULL; FT_Pos best = 0xFFFFU; FT_Int ee; @@ -1001,7 +1088,7 @@ /* insert a new edge in the list and */ /* sort according to the position */ error = af_axis_hints_new_edge( axis, seg->pos, - (AF_Direction)seg->dir, + (AF_Direction)seg->dir, 0, memory, &edge ); if ( error ) goto Exit; @@ -1011,10 +1098,11 @@ edge->first = seg; edge->last = seg; + edge->dir = seg->dir; edge->fpos = seg->pos; - edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + edge->opos = FT_MulFix( seg->pos, scale ); + edge->pos = edge->opos; seg->edge_next = seg; - edge->dir = seg->dir; } else { @@ -1026,25 +1114,26 @@ } } - /*********************************************************************/ - /* */ - /* Good, we now compute each edge's properties according to segments */ - /* found on its position. Basically, these are as follows. */ - /* */ - /* - edge's main direction */ - /* - stem edge, serif edge or both (which defaults to stem then) */ - /* - rounded edge, straight or both (which defaults to straight) */ - /* - link for edge */ - /* */ - /*********************************************************************/ - - /* first of all, set the `edge' field in each segment -- this is */ - /* required in order to compute edge links */ - /* */ - /* Note that removing this loop and setting the `edge' field of each */ - /* segment directly in the code above slows down execution speed for */ - /* some reasons on platforms like the Sun. */ + /******************************************************************/ + /* */ + /* Good, we now compute each edge's properties according to the */ + /* segments found on its position. Basically, these are */ + /* */ + /* - the edge's main direction */ + /* - stem edge, serif edge or both (which defaults to stem then) */ + /* - rounded edge, straight or both (which defaults to straight) */ + /* - link for edge */ + /* */ + /******************************************************************/ + + /* first of all, set the `edge' field in each segment -- this is */ + /* required in order to compute edge links */ + /* + * Note that removing this loop and setting the `edge' field of each + * segment directly in the code above slows down execution speed for + * some reasons on platforms like the Sun. + */ { AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; @@ -1144,7 +1233,7 @@ /* Example: the `c' in cour.pfa at size 13 */ if ( edge->serif && edge->link ) - edge->serif = 0; + edge->serif = NULL; } } @@ -1153,6 +1242,8 @@ } + /* Detect segments and edges for given dimension. */ + static FT_Error af_cjk_hints_detect_features( AF_GlyphHints hints, AF_Dimension dim ) @@ -1171,7 +1262,9 @@ } - FT_LOCAL_DEF( void ) + /* Compute all edges which lie within blue zones. */ + + static void af_cjk_hints_compute_blue_edges( AF_GlyphHints hints, AF_CJKMetrics metrics, AF_Dimension dim ) @@ -1218,10 +1311,10 @@ /* zone, check for left edges */ /* */ /* of course, that's for TrueType */ - is_top_right_blue = - FT_BOOL( ( ( blue->flags & AF_CJK_BLUE_IS_TOP ) != 0 ) || - ( ( blue->flags & AF_CJK_BLUE_IS_RIGHT ) != 0 ) ); - is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); + is_top_right_blue = + (FT_Byte)( ( blue->flags & AF_CJK_BLUE_TOP ) != 0 ); + is_major_dir = + FT_BOOL( edge->dir == axis->major_dir ); /* if it is a top zone, the edge must be against the major */ /* direction; if it is a bottom zone, it must be in the major */ @@ -1258,6 +1351,8 @@ } + /* Initalize hinting engine. */ + FT_LOCAL_DEF( FT_Error ) af_cjk_hints_init( AF_GlyphHints hints, AF_CJKMetrics metrics ) @@ -1266,7 +1361,7 @@ FT_UInt32 scaler_flags, other_flags; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics ); /* * correct x_scale and y_scale when needed, since they may have @@ -1280,7 +1375,7 @@ /* compute flags depending on render mode, etc. */ mode = metrics->root.scaler.render_mode; -#ifdef AF_CONFIG_OPTION_USE_WARPER +#if 0 /* AF_CONFIG_OPTION_USE_WARPER */ if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; #endif @@ -1313,10 +1408,16 @@ scaler_flags |= AF_SCALER_FLAG_NO_ADVANCE; +#ifdef AF_CONFIG_OPTION_USE_WARPER + /* get (global) warper flag */ + if ( !metrics->root.globals->module->warping ) + scaler_flags |= AF_SCALER_FLAG_NO_WARPER; +#endif + hints->scaler_flags = scaler_flags; hints->other_flags = other_flags; - return 0; + return FT_Err_Ok; } @@ -1328,18 +1429,18 @@ /*************************************************************************/ /*************************************************************************/ - /* snap a given width in scaled coordinates to one of the */ - /* current standard widths */ + /* Snap a given width in scaled coordinates to one of the */ + /* current standard widths. */ static FT_Pos af_cjk_snap_width( AF_Width widths, - FT_Int count, + FT_UInt count, FT_Pos width ) { - int n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - FT_Pos scaled; + FT_UInt n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; for ( n = 0; n < count; n++ ) @@ -1376,17 +1477,19 @@ } - /* compute the snapped width of a given stem */ + /* Compute the snapped width of a given stem. */ + /* There is a lot of voodoo in this function; changing the hard-coded */ + /* parameters influence the whole hinting process. */ static FT_Pos af_cjk_compute_stem_width( AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, - AF_Edge_Flags base_flags, - AF_Edge_Flags stem_flags ) + FT_UInt base_flags, + FT_UInt stem_flags ) { - AF_CJKMetrics metrics = (AF_CJKMetrics) hints->metrics; - AF_CJKAxis axis = & metrics->axis[dim]; + AF_CJKMetrics metrics = (AF_CJKMetrics)hints->metrics; + AF_CJKAxis axis = &metrics->axis[dim]; FT_Pos dist = width; FT_Int sign = 0; FT_Bool vertical = FT_BOOL( dim == AF_DIMENSION_VERT ); @@ -1422,7 +1525,7 @@ } if ( dist < 54 ) - dist += ( 54 - dist ) / 2 ; + dist += ( 54 - dist ) / 2; else if ( dist < 3 * 64 ) { FT_Pos delta; @@ -1497,7 +1600,7 @@ } - /* align one stem edge relative to the previous stem edge */ + /* Align one stem edge relative to the previous stem edge. */ static void af_cjk_align_linked_edge( AF_GlyphHints hints, @@ -1507,16 +1610,24 @@ { FT_Pos dist = stem_edge->opos - base_edge->opos; - FT_Pos fitted_width = af_cjk_compute_stem_width( - hints, dim, dist, - (AF_Edge_Flags)base_edge->flags, - (AF_Edge_Flags)stem_edge->flags ); + FT_Pos fitted_width = af_cjk_compute_stem_width( hints, dim, dist, + base_edge->flags, + stem_edge->flags ); stem_edge->pos = base_edge->pos + fitted_width; + + FT_TRACE5(( " CJKLINK: edge %d @%d (opos=%.2f) linked to %.2f," + " dist was %.2f, now %.2f\n", + stem_edge - hints->axis[dim].edges, stem_edge->fpos, + stem_edge->opos / 64.0, stem_edge->pos / 64.0, + dist / 64.0, fitted_width / 64.0 )); } + /* Shift the coordinates of the `serif' edge by the same amount */ + /* as the corresponding `base' edge has been moved already. */ + static void af_cjk_align_serif_edge( AF_GlyphHints hints, AF_Edge base, @@ -1579,8 +1690,8 @@ org_len = edge2->opos - edge->opos; cur_len = af_cjk_compute_stem_width( hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + edge->flags, + edge2->flags ); org_center = ( edge->opos + edge2->opos ) / 2 + anchor; cur_pos1 = org_center - cur_len / 2; @@ -1670,6 +1781,8 @@ } + /* The main grid-fitting routine. */ + static void af_cjk_hint_edges( AF_GlyphHints hints, AF_Dimension dim ) @@ -1679,16 +1792,22 @@ AF_Edge edge_limit = edges + axis->num_edges; FT_PtrDist n_edges; AF_Edge edge; - AF_Edge anchor = 0; + AF_Edge anchor = NULL; FT_Pos delta = 0; FT_Int skipped = 0; FT_Bool has_last_stem = FALSE; FT_Pos last_stem_pos = 0; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_UInt num_actions = 0; +#endif + + + FT_TRACE5(( "cjk %s edge hinting (style `%s')\n", + dim == AF_DIMENSION_VERT ? "horizontal" : "vertical", + af_style_names[hints->metrics->style_class->style] )); /* we begin by aligning all stems relative to the blue zone */ - FT_TRACE5(( "==== cjk hinting %s edges =====\n", - dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); if ( AF_HINTS_DO_BLUES( hints ) ) { @@ -1719,10 +1838,14 @@ if ( !edge1 ) continue; - FT_TRACE5(( "CJKBLUE: edge %d @%d (opos=%.2f) snapped to (%.2f), " - "was (%.2f)\n", - edge1-edges, edge1->fpos, edge1->opos / 64.0, blue->fit / 64.0, - edge1->pos / 64.0 )); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE5(( " CJKBLUE: edge %d @%d (opos=%.2f) snapped to %.2f," + " was %.2f\n", + edge1 - edges, edge1->fpos, edge1->opos / 64.0, + blue->fit / 64.0, edge1->pos / 64.0 )); + + num_actions++; +#endif edge1->pos = blue->fit; edge1->flags |= AF_EDGE_DONE; @@ -1731,6 +1854,10 @@ { af_cjk_align_linked_edge( hints, dim, edge1, edge2 ); edge2->flags |= AF_EDGE_DONE; + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions++; +#endif } if ( !anchor ) @@ -1772,6 +1899,7 @@ } /* now align the stem */ + /* this should not happen, but it's better to be safe */ if ( edge2->blue_edge ) { @@ -1779,6 +1907,11 @@ af_cjk_align_linked_edge( hints, dim, edge2, edge ); edge->flags |= AF_EDGE_DONE; + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions++; +#endif + continue; } @@ -1786,6 +1919,11 @@ { af_cjk_align_linked_edge( hints, dim, edge2, edge ); edge->flags |= AF_EDGE_DONE; + +#ifdef FT_DEBUG_LEVEL_TRACE + num_actions++; +#endif + /* We rarely reaches here it seems; * usually the two edges belonging * to one stem are marked as DONE together @@ -1953,7 +2091,7 @@ } if ( !skipped ) - return; + goto Exit; /* * now hint the remaining edges (serifs and single) in order @@ -1973,7 +2111,7 @@ } if ( !skipped ) - return; + goto Exit; for ( edge = edges; edge < edge_limit; edge++ ) { @@ -2011,6 +2149,16 @@ } } } + + Exit: + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !num_actions ) + FT_TRACE5(( " (none)\n" )); + FT_TRACE5(( "\n" )); +#endif + + return; } @@ -2104,8 +2252,11 @@ } + /* Apply the complete hinting algorithm to a CJK glyph. */ + FT_LOCAL_DEF( FT_Error ) - af_cjk_hints_apply( AF_GlyphHints hints, + af_cjk_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline, AF_CJKMetrics metrics ) { @@ -2113,6 +2264,7 @@ int dim; FT_UNUSED( metrics ); + FT_UNUSED( glyph_index ); error = af_glyph_hints_reload( hints, outline ); @@ -2120,7 +2272,13 @@ goto Exit; /* analyze glyph outline */ +#ifdef AF_CONFIG_OPTION_USE_WARPER + if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) || + AF_HINTS_DO_HORIZONTAL( hints ) ) +#else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) +#endif { error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ ); if ( error ) @@ -2146,8 +2304,9 @@ { #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL ) + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; @@ -2169,12 +2328,6 @@ } } -#if 0 - af_glyph_hints_dump_points( hints ); - af_glyph_hints_dump_segments( hints ); - af_glyph_hints_dump_edges( hints ); -#endif - af_glyph_hints_save( hints, outline ); Exit: @@ -2191,84 +2344,43 @@ /*************************************************************************/ - /* this corresponds to Unicode 6.0 */ + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_cjk_writing_system_class, - static const AF_Script_UniRangeRec af_cjk_uniranges[] = - { - AF_UNIRANGE_REC( 0x1100UL, 0x11FFUL ), /* Hangul Jamo */ - AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */ - AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */ - AF_UNIRANGE_REC( 0x2FF0UL, 0x2FFFUL ), /* Ideographic Description Characters */ - AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */ - AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */ - AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */ - AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */ - AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */ - AF_UNIRANGE_REC( 0x3190UL, 0x319FUL ), /* Kanbun */ - AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */ - AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */ - AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */ - AF_UNIRANGE_REC( 0x3200UL, 0x32FFUL ), /* Enclosed CJK Letters and Months */ - AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */ - AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */ - AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */ - AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */ - AF_UNIRANGE_REC( 0xA960UL, 0xA97FUL ), /* Hangul Jamo Extended-A */ - AF_UNIRANGE_REC( 0xAC00UL, 0xD7AFUL ), /* Hangul Syllables */ - AF_UNIRANGE_REC( 0xD7B0UL, 0xD7FFUL ), /* Hangul Jamo Extended-B */ - AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */ - AF_UNIRANGE_REC( 0xFE10UL, 0xFE1FUL ), /* Vertical forms */ - AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */ - AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */ - AF_UNIRANGE_REC( 0x1B000UL, 0x1B0FFUL ), /* Kana Supplement */ - AF_UNIRANGE_REC( 0x1D300UL, 0x1D35FUL ), /* Tai Xuan Hing Symbols */ - AF_UNIRANGE_REC( 0x1F200UL, 0x1F2FFUL ), /* Enclosed Ideographic Supplement */ - AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */ - AF_UNIRANGE_REC( 0x2A700UL, 0x2B73FUL ), /* CJK Unified Ideographs Extension C */ - AF_UNIRANGE_REC( 0x2B740UL, 0x2B81FUL ), /* CJK Unified Ideographs Extension D */ - AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class, - AF_SCRIPT_CJK, - af_cjk_uniranges, - 0x7530, /* 田 */ + AF_WRITING_SYSTEM_CJK, sizeof ( AF_CJKMetricsRec ), - (AF_Script_InitMetricsFunc) af_cjk_metrics_init, - (AF_Script_ScaleMetricsFunc)af_cjk_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init, + (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)af_cjk_get_standard_widths, - (AF_Script_InitHintsFunc) af_cjk_hints_init, - (AF_Script_ApplyHintsFunc) af_cjk_hints_apply + (AF_WritingSystem_InitHintsFunc) af_cjk_hints_init, + (AF_WritingSystem_ApplyHintsFunc) af_cjk_hints_apply ) + #else /* !AF_CONFIG_OPTION_CJK */ - static const AF_Script_UniRangeRec af_cjk_uniranges[] = - { - AF_UNIRANGE_REC( 0UL, 0UL ) - }; + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_cjk_writing_system_class, - AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class, - AF_SCRIPT_CJK, - af_cjk_uniranges, - 0, + AF_WRITING_SYSTEM_CJK, sizeof ( AF_CJKMetricsRec ), - (AF_Script_InitMetricsFunc) NULL, - (AF_Script_ScaleMetricsFunc)NULL, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, + (AF_WritingSystem_ScaleMetricsFunc)NULL, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)NULL, - (AF_Script_InitHintsFunc) NULL, - (AF_Script_ApplyHintsFunc) NULL + (AF_WritingSystem_InitHintsFunc) NULL, + (AF_WritingSystem_ApplyHintsFunc) NULL ) + #endif /* !AF_CONFIG_OPTION_CJK */ diff --git a/drivers/freetype/freetype/src/autofit/afcjk.h b/drivers/freetype/src/autofit/afcjk.h index ab816f20b1..40d1184386 100644 --- a/drivers/freetype/freetype/src/autofit/afcjk.h +++ b/drivers/freetype/src/autofit/afcjk.h @@ -2,9 +2,9 @@ /* */ /* afcjk.h */ /* */ -/* Auto-fitter hinting routines for CJK script (specification). */ +/* Auto-fitter hinting routines for CJK writing system (specification). */ /* */ -/* Copyright 2006, 2007, 2011, 2012 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFCJK_H__ -#define __AFCJK_H__ +#ifndef AFCJK_H_ +#define AFCJK_H_ #include "afhints.h" #include "aflatin.h" @@ -26,41 +26,39 @@ FT_BEGIN_HEADER - /* the CJK-specific script class */ + /* the CJK-specific writing system */ - AF_DECLARE_SCRIPT_CLASS( af_cjk_script_class ) + AF_DECLARE_WRITING_SYSTEM_CLASS( af_cjk_writing_system_class ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C J K G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ - /* CJK (global) metrics management */ /* * CJK glyphs tend to fill the square. So we have both vertical and * horizontal blue zones. But some glyphs have flat bounding strokes that * leave some space between neighbour glyphs. */ - enum - { - AF_CJK_BLUE_TOP, - AF_CJK_BLUE_BOTTOM, - AF_CJK_BLUE_LEFT, - AF_CJK_BLUE_RIGHT, - - AF_CJK_BLUE_MAX - }; +#define AF_CJK_IS_TOP_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_CJK_TOP ) +#define AF_CJK_IS_HORIZ_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_CJK_HORIZ ) +#define AF_CJK_IS_RIGHT_BLUE AF_CJK_IS_TOP_BLUE #define AF_CJK_MAX_WIDTHS 16 -#define AF_CJK_MAX_BLUES AF_CJK_BLUE_MAX - enum - { - AF_CJK_BLUE_ACTIVE = 1 << 0, - AF_CJK_BLUE_IS_TOP = 1 << 1, - AF_CJK_BLUE_IS_RIGHT = 1 << 2, - AF_CJK_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment */ - /* optimization */ - AF_CJK_BLUE_FLAG_MAX - }; +#define AF_CJK_BLUE_ACTIVE ( 1U << 0 ) /* zone height is <= 3/4px */ +#define AF_CJK_BLUE_TOP ( 1U << 1 ) /* result of AF_CJK_IS_TOP_BLUE */ +#define AF_CJK_BLUE_ADJUSTMENT ( 1U << 2 ) /* used for scale adjustment */ + /* optimization */ typedef struct AF_CJKBlueRec_ @@ -77,16 +75,16 @@ FT_BEGIN_HEADER FT_Fixed scale; FT_Pos delta; - FT_UInt width_count; - AF_WidthRec widths[AF_CJK_MAX_WIDTHS]; - FT_Pos edge_distance_threshold; - FT_Pos standard_width; - FT_Bool extra_light; + FT_UInt width_count; /* number of used widths */ + AF_WidthRec widths[AF_CJK_MAX_WIDTHS]; /* widths array */ + FT_Pos edge_distance_threshold; /* used for creating edges */ + FT_Pos standard_width; /* the default stem thickness */ + FT_Bool extra_light; /* is standard width very light? */ /* used for horizontal metrics too for CJK */ FT_Bool control_overshoot; FT_UInt blue_count; - AF_CJKBlueRec blues[AF_CJK_BLUE_MAX]; + AF_CJKBlueRec blues[AF_BLUE_STRINGSET_MAX]; FT_Fixed org_scale; FT_Pos org_delta; @@ -96,9 +94,9 @@ FT_BEGIN_HEADER typedef struct AF_CJKMetricsRec_ { - AF_ScriptMetricsRec root; - FT_UInt units_per_em; - AF_CJKAxisRec axis[AF_DIMENSION_MAX]; + AF_StyleMetricsRec root; + FT_UInt units_per_em; + AF_CJKAxisRec axis[AF_DIMENSION_MAX]; } AF_CJKMetricsRec, *AF_CJKMetrics; @@ -117,7 +115,8 @@ FT_BEGIN_HEADER AF_CJKMetrics metrics ); FT_LOCAL( FT_Error ) - af_cjk_hints_apply( AF_GlyphHints hints, + af_cjk_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline, AF_CJKMetrics metrics ); @@ -136,7 +135,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFCJK_H__ */ +#endif /* AFCJK_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afcover.h b/drivers/freetype/src/autofit/afcover.h new file mode 100644 index 0000000000..1c39a707ef --- /dev/null +++ b/drivers/freetype/src/autofit/afcover.h @@ -0,0 +1,105 @@ +/***************************************************************************/ +/* */ +/* afcover.h */ +/* */ +/* Auto-fitter coverages (specification only). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /* This header file can be included multiple times. */ + /* Define `COVERAGE' as needed. */ + + + /* Add new coverages here. The first and second arguments are the */ + /* coverage name in lowercase and uppercase, respectively, followed */ + /* by a description string. The last four arguments are the four */ + /* characters defining the corresponding OpenType feature. */ + +#if 0 + /* XXX: It's not possible to define blue zone characters in advance. */ + COVERAGE( alternative_fractions, ALTERNATIVE_FRACTIONS, + "alternative fractions", + 'a', 'f', 'r', 'c' ) +#endif + + COVERAGE( petite_capitals_from_capitals, PETITE_CAPITALS_FROM_CAPITALS, + "petite capitals from capitals", + 'c', '2', 'c', 'p' ) + + COVERAGE( small_capitals_from_capitals, SMALL_CAPITALS_FROM_CAPITALS, + "small capitals from capitals", + 'c', '2', 's', 'c' ) + +#if 0 + /* XXX: Only digits are in this coverage, however, both normal style */ + /* and oldstyle representation forms are possible. */ + COVERAGE( denominators, DENOMINATORS, + "denominators", + 'd', 'n', 'o', 'm' ) +#endif + +#if 0 + /* XXX: It's not possible to define blue zone characters in advance. */ + COVERAGE( fractions, FRACTIONS, + "fractions", + 'f', 'r', 'a', 'c' ) +#endif + +#if 0 + /* XXX: Only digits are in this coverage, however, both normal style */ + /* and oldstyle representation forms are possible. */ + COVERAGE( numerators, NUMERATORS, + "numerators", + 'n', 'u', 'm', 'r' ) +#endif + + COVERAGE( ordinals, ORDINALS, + "ordinals", + 'o', 'r', 'd', 'n' ) + + COVERAGE( petite_capitals, PETITE_CAPITALS, + "petite capitals", + 'p', 'c', 'a', 'p' ) + + COVERAGE( ruby, RUBY, + "ruby", + 'r', 'u', 'b', 'y' ) + + COVERAGE( scientific_inferiors, SCIENTIFIC_INFERIORS, + "scientific inferiors", + 's', 'i', 'n', 'f' ) + + COVERAGE( small_capitals, SMALL_CAPITALS, + "small capitals", + 's', 'm', 'c', 'p' ) + + COVERAGE( subscript, SUBSCRIPT, + "subscript", + 's', 'u', 'b', 's' ) + + COVERAGE( superscript, SUPERSCRIPT, + "superscript", + 's', 'u', 'p', 's' ) + + COVERAGE( titling, TITLING, + "titling", + 't', 'i', 't', 'l' ) + +#if 0 + /* to be always excluded */ + COVERAGE(nalt, 'n', 'a', 'l', 't'); /* Alternate Annotation Forms (?) */ + COVERAGE(ornm, 'o', 'r', 'n', 'm'); /* Ornaments (?) */ +#endif + + +/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afdummy.c b/drivers/freetype/src/autofit/afdummy.c index 22944559da..f3960c85fd 100644 --- a/drivers/freetype/freetype/src/autofit/afdummy.c +++ b/drivers/freetype/src/autofit/afdummy.c @@ -5,7 +5,7 @@ /* Auto-fitter dummy routines to be used if no hinting should be */ /* performed (body). */ /* */ -/* Copyright 2003-2005, 2011, 2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,39 +23,52 @@ static FT_Error - af_dummy_hints_init( AF_GlyphHints hints, - AF_ScriptMetrics metrics ) + af_dummy_hints_init( AF_GlyphHints hints, + AF_StyleMetrics metrics ) { - af_glyph_hints_rescale( hints, - metrics ); + af_glyph_hints_rescale( hints, metrics ); + + hints->x_scale = metrics->scaler.x_scale; + hints->y_scale = metrics->scaler.y_scale; + hints->x_delta = metrics->scaler.x_delta; + hints->y_delta = metrics->scaler.y_delta; + return FT_Err_Ok; } static FT_Error - af_dummy_hints_apply( AF_GlyphHints hints, + af_dummy_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline ) { - FT_UNUSED( hints ); - FT_UNUSED( outline ); + FT_Error error; - return FT_Err_Ok; + FT_UNUSED( glyph_index ); + + + error = af_glyph_hints_reload( hints, outline ); + if ( !error ) + af_glyph_hints_save( hints, outline ); + + return error; } - AF_DEFINE_SCRIPT_CLASS( af_dummy_script_class, - AF_SCRIPT_DUMMY, - NULL, - 0, + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_dummy_writing_system_class, + + AF_WRITING_SYSTEM_DUMMY, - sizeof ( AF_ScriptMetricsRec ), + sizeof ( AF_StyleMetricsRec ), - (AF_Script_InitMetricsFunc) NULL, - (AF_Script_ScaleMetricsFunc)NULL, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, + (AF_WritingSystem_ScaleMetricsFunc)NULL, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)NULL, - (AF_Script_InitHintsFunc) af_dummy_hints_init, - (AF_Script_ApplyHintsFunc) af_dummy_hints_apply + (AF_WritingSystem_InitHintsFunc) af_dummy_hints_init, + (AF_WritingSystem_ApplyHintsFunc) af_dummy_hints_apply ) diff --git a/drivers/freetype/freetype/src/autofit/afdummy.h b/drivers/freetype/src/autofit/afdummy.h index 95d8f8cf19..7e58d1a9a5 100644 --- a/drivers/freetype/freetype/src/autofit/afdummy.h +++ b/drivers/freetype/src/autofit/afdummy.h @@ -5,7 +5,7 @@ /* Auto-fitter dummy routines to be used if no hinting should be */ /* performed (specification). */ /* */ -/* Copyright 2003-2005, 2011 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,26 +17,24 @@ /***************************************************************************/ -#ifndef __AFDUMMY_H__ -#define __AFDUMMY_H__ +#ifndef AFDUMMY_H_ +#define AFDUMMY_H_ #include "aftypes.h" FT_BEGIN_HEADER - /* A dummy script metrics class used when no hinting should - * be performed. This is the default for non-latin glyphs! - */ + /* A dummy writing system used when no hinting should be performed. */ - AF_DECLARE_SCRIPT_CLASS( af_dummy_script_class ) + AF_DECLARE_WRITING_SYSTEM_CLASS( af_dummy_writing_system_class ) /* */ FT_END_HEADER -#endif /* __AFDUMMY_H__ */ +#endif /* AFDUMMY_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/autofit/aferrors.h b/drivers/freetype/src/autofit/aferrors.h index 50e1a22dd5..53c01f64dd 100644 --- a/drivers/freetype/freetype/src/autofit/aferrors.h +++ b/drivers/freetype/src/autofit/aferrors.h @@ -4,7 +4,7 @@ /* */ /* Autofitter error codes (specification only). */ /* */ -/* Copyright 2005, 2012 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __AFERRORS_H__ -#define __AFERRORS_H__ +#ifndef AFERRORS_H_ +#define AFERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX AF_Err_ @@ -36,6 +36,7 @@ #include FT_ERRORS_H -#endif /* __AFERRORS_H__ */ +#endif /* AFERRORS_H_ */ + /* END */ diff --git a/drivers/freetype/src/autofit/afglobal.c b/drivers/freetype/src/autofit/afglobal.c new file mode 100644 index 0000000000..ac6dcafc0f --- /dev/null +++ b/drivers/freetype/src/autofit/afglobal.c @@ -0,0 +1,515 @@ +/***************************************************************************/ +/* */ +/* afglobal.c */ +/* */ +/* Auto-fitter routines to compute global hinting values (body). */ +/* */ +/* Copyright 2003-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "afglobal.h" +#include "afranges.h" +#include "afshaper.h" +#include FT_INTERNAL_DEBUG_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_afglobal + + + /* get writing system specific header files */ +#undef WRITING_SYSTEM +#define WRITING_SYSTEM( ws, WS ) /* empty */ +#include "afwrtsys.h" + +#include "aferrors.h" +#include "afpic.h" + + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + AF_DEFINE_SCRIPT_CLASS( \ + af_ ## s ## _script_class, \ + AF_SCRIPT_ ## S, \ + af_ ## s ## _uniranges, \ + af_ ## s ## _nonbase_uniranges, \ + AF_ ## H, \ + ss ) + +#include "afscript.h" + + +#undef STYLE +#define STYLE( s, S, d, ws, sc, ss, c ) \ + AF_DEFINE_STYLE_CLASS( \ + af_ ## s ## _style_class, \ + AF_STYLE_ ## S, \ + ws, \ + sc, \ + ss, \ + c ) + +#include "afstyles.h" + + +#ifndef FT_CONFIG_OPTION_PIC + +#undef WRITING_SYSTEM +#define WRITING_SYSTEM( ws, WS ) \ + &af_ ## ws ## _writing_system_class, + + FT_LOCAL_ARRAY_DEF( AF_WritingSystemClass ) + af_writing_system_classes[] = + { + +#include "afwrtsys.h" + + NULL /* do not remove */ + }; + + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + &af_ ## s ## _script_class, + + FT_LOCAL_ARRAY_DEF( AF_ScriptClass ) + af_script_classes[] = + { + +#include "afscript.h" + + NULL /* do not remove */ + }; + + +#undef STYLE +#define STYLE( s, S, d, ws, sc, ss, c ) \ + &af_ ## s ## _style_class, + + FT_LOCAL_ARRAY_DEF( AF_StyleClass ) + af_style_classes[] = + { + +#include "afstyles.h" + + NULL /* do not remove */ + }; + +#endif /* !FT_CONFIG_OPTION_PIC */ + + +#ifdef FT_DEBUG_LEVEL_TRACE + +#undef STYLE +#define STYLE( s, S, d, ws, sc, ss, c ) #s, + + FT_LOCAL_ARRAY_DEF( char* ) + af_style_names[] = + { + +#include "afstyles.h" + + }; + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + /* Compute the style index of each glyph within a given face. */ + + static FT_Error + af_face_globals_compute_style_coverage( AF_FaceGlobals globals ) + { + FT_Error error; + FT_Face face = globals->face; + FT_CharMap old_charmap = face->charmap; + FT_UShort* gstyles = globals->glyph_styles; + FT_UInt ss; + FT_UInt i; + FT_UInt dflt = ~0U; /* a non-valid value */ + + + /* the value AF_STYLE_UNASSIGNED means `uncovered glyph' */ + for ( i = 0; i < (FT_UInt)globals->glyph_count; i++ ) + gstyles[i] = AF_STYLE_UNASSIGNED; + + error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); + if ( error ) + { + /* + * Ignore this error; we simply use the fallback style. + * XXX: Shouldn't we rather disable hinting? + */ + error = FT_Err_Ok; + goto Exit; + } + + /* scan each style in a Unicode charmap */ + for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + { + AF_StyleClass style_class = + AF_STYLE_CLASSES_GET[ss]; + AF_ScriptClass script_class = + AF_SCRIPT_CLASSES_GET[style_class->script]; + AF_Script_UniRange range; + + + if ( script_class->script_uni_ranges == NULL ) + continue; + + /* + * Scan all Unicode points in the range and set the corresponding + * glyph style index. + */ + if ( style_class->coverage == AF_COVERAGE_DEFAULT ) + { + if ( (FT_UInt)style_class->script == + globals->module->default_script ) + dflt = ss; + + for ( range = script_class->script_uni_ranges; + range->first != 0; + range++ ) + { + FT_ULong charcode = range->first; + FT_UInt gindex; + + + gindex = FT_Get_Char_Index( face, charcode ); + + if ( gindex != 0 && + gindex < (FT_ULong)globals->glyph_count && + ( gstyles[gindex] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED ) + gstyles[gindex] = (FT_UShort)ss; + + for (;;) + { + charcode = FT_Get_Next_Char( face, charcode, &gindex ); + + if ( gindex == 0 || charcode > range->last ) + break; + + if ( gindex < (FT_ULong)globals->glyph_count && + ( gstyles[gindex] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED ) + gstyles[gindex] = (FT_UShort)ss; + } + } + + /* do the same for the script's non-base characters */ + for ( range = script_class->script_uni_nonbase_ranges; + range->first != 0; + range++ ) + { + FT_ULong charcode = range->first; + FT_UInt gindex; + + + gindex = FT_Get_Char_Index( face, charcode ); + + if ( gindex != 0 && + gindex < (FT_ULong)globals->glyph_count && + ( gstyles[gindex] & AF_STYLE_MASK ) == (FT_UShort)ss ) + gstyles[gindex] |= AF_NONBASE; + + for (;;) + { + charcode = FT_Get_Next_Char( face, charcode, &gindex ); + + if ( gindex == 0 || charcode > range->last ) + break; + + if ( gindex < (FT_ULong)globals->glyph_count && + ( gstyles[gindex] & AF_STYLE_MASK ) == (FT_UShort)ss ) + gstyles[gindex] |= AF_NONBASE; + } + } + } + else + { + /* get glyphs not directly addressable by cmap */ + af_shaper_get_coverage( globals, style_class, gstyles, 0 ); + } + } + + /* handle the remaining default OpenType features ... */ + for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + { + AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; + + + if ( style_class->coverage == AF_COVERAGE_DEFAULT ) + af_shaper_get_coverage( globals, style_class, gstyles, 0 ); + } + + /* ... and finally the default OpenType features of the default script */ + af_shaper_get_coverage( globals, AF_STYLE_CLASSES_GET[dflt], gstyles, 1 ); + + /* mark ASCII digits */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt gindex = FT_Get_Char_Index( face, i ); + + + if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) + gstyles[gindex] |= AF_DIGIT; + } + + Exit: + /* + * By default, all uncovered glyphs are set to the fallback style. + * XXX: Shouldn't we disable hinting or do something similar? + */ + if ( globals->module->fallback_style != AF_STYLE_UNASSIGNED ) + { + FT_Long nn; + + + for ( nn = 0; nn < globals->glyph_count; nn++ ) + { + if ( ( gstyles[nn] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED ) + { + gstyles[nn] &= ~AF_STYLE_MASK; + gstyles[nn] |= globals->module->fallback_style; + } + } + } + +#ifdef FT_DEBUG_LEVEL_TRACE + + FT_TRACE4(( "\n" + "style coverage\n" + "==============\n" + "\n" )); + + for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + { + AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; + FT_UInt count = 0; + FT_Long idx; + + + FT_TRACE4(( "%s:\n", af_style_names[style_class->style] )); + + for ( idx = 0; idx < globals->glyph_count; idx++ ) + { + if ( ( gstyles[idx] & AF_STYLE_MASK ) == style_class->style ) + { + if ( !( count % 10 ) ) + FT_TRACE4(( " " )); + + FT_TRACE4(( " %d", idx )); + count++; + + if ( !( count % 10 ) ) + FT_TRACE4(( "\n" )); + } + } + + if ( !count ) + FT_TRACE4(( " (none)\n" )); + if ( count % 10 ) + FT_TRACE4(( "\n" )); + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + FT_Set_Charmap( face, old_charmap ); + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + af_face_globals_new( FT_Face face, + AF_FaceGlobals *aglobals, + AF_Module module ) + { + FT_Error error; + FT_Memory memory; + AF_FaceGlobals globals = NULL; + + + memory = face->memory; + + /* we allocate an AF_FaceGlobals structure together */ + /* with the glyph_styles array */ + if ( FT_ALLOC( globals, + sizeof ( *globals ) + + (FT_ULong)face->num_glyphs * sizeof ( FT_UShort ) ) ) + goto Exit; + + globals->face = face; + globals->glyph_count = face->num_glyphs; + /* right after the globals structure come the glyph styles */ + globals->glyph_styles = (FT_UShort*)( globals + 1 ); + globals->module = module; + globals->stem_darkening_for_ppem = 0; + globals->darken_x = 0; + globals->darken_y = 0; + globals->standard_vertical_width = 0; + globals->standard_horizontal_width = 0; + globals->scale_down_factor = 0; + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + globals->hb_font = hb_ft_font_create( face, NULL ); + globals->hb_buf = hb_buffer_create(); +#endif + + error = af_face_globals_compute_style_coverage( globals ); + if ( error ) + { + af_face_globals_free( globals ); + globals = NULL; + } + else + globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX; + + Exit: + *aglobals = globals; + return error; + } + + + FT_LOCAL_DEF( void ) + af_face_globals_free( AF_FaceGlobals globals ) + { + if ( globals ) + { + FT_Memory memory = globals->face->memory; + FT_UInt nn; + + + for ( nn = 0; nn < AF_STYLE_MAX; nn++ ) + { + if ( globals->metrics[nn] ) + { + AF_StyleClass style_class = + AF_STYLE_CLASSES_GET[nn]; + AF_WritingSystemClass writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; + + + if ( writing_system_class->style_metrics_done ) + writing_system_class->style_metrics_done( globals->metrics[nn] ); + + FT_FREE( globals->metrics[nn] ); + } + } + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + hb_font_destroy( globals->hb_font ); + globals->hb_font = NULL; + + hb_buffer_destroy( globals->hb_buf ); + globals->hb_buf = NULL; +#endif + + globals->glyph_count = 0; + globals->stem_darkening_for_ppem = 0; + globals->darken_x = 0; + globals->darken_y = 0; + globals->standard_vertical_width = 0; + globals->standard_horizontal_width = 0; + globals->scale_down_factor = 0; + /* no need to free this one! */ + globals->glyph_styles = NULL; + globals->face = NULL; + + FT_FREE( globals ); + } + } + + + FT_LOCAL_DEF( FT_Error ) + af_face_globals_get_metrics( AF_FaceGlobals globals, + FT_UInt gindex, + FT_UInt options, + AF_StyleMetrics *ametrics ) + { + AF_StyleMetrics metrics = NULL; + + AF_Style style = (AF_Style)options; + AF_WritingSystemClass writing_system_class; + AF_StyleClass style_class; + + FT_Error error = FT_Err_Ok; + + + if ( gindex >= (FT_ULong)globals->glyph_count ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* if we have a forced style (via `options'), use it, */ + /* otherwise look into `glyph_styles' array */ + if ( style == AF_STYLE_NONE_DFLT || style + 1 >= AF_STYLE_MAX ) + style = (AF_Style)( globals->glyph_styles[gindex] & + AF_STYLE_UNASSIGNED ); + + style_class = AF_STYLE_CLASSES_GET[style]; + writing_system_class = AF_WRITING_SYSTEM_CLASSES_GET + [style_class->writing_system]; + + metrics = globals->metrics[style]; + if ( metrics == NULL ) + { + /* create the global metrics object if necessary */ + FT_Memory memory = globals->face->memory; + + + if ( FT_ALLOC( metrics, writing_system_class->style_metrics_size ) ) + goto Exit; + + metrics->style_class = style_class; + metrics->globals = globals; + + if ( writing_system_class->style_metrics_init ) + { + error = writing_system_class->style_metrics_init( metrics, + globals->face ); + if ( error ) + { + if ( writing_system_class->style_metrics_done ) + writing_system_class->style_metrics_done( metrics ); + + FT_FREE( metrics ); + goto Exit; + } + } + + globals->metrics[style] = metrics; + } + + Exit: + *ametrics = metrics; + + return error; + } + + + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ) + { + if ( gindex < (FT_ULong)globals->glyph_count ) + return (FT_Bool)( globals->glyph_styles[gindex] & AF_DIGIT ); + + return (FT_Bool)0; + } + + +/* END */ diff --git a/drivers/freetype/src/autofit/afglobal.h b/drivers/freetype/src/autofit/afglobal.h new file mode 100644 index 0000000000..ce6b9e8f26 --- /dev/null +++ b/drivers/freetype/src/autofit/afglobal.h @@ -0,0 +1,173 @@ +/***************************************************************************/ +/* */ +/* afglobal.h */ +/* */ +/* Auto-fitter routines to compute global hinting values */ +/* (specification). */ +/* */ +/* Copyright 2003-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef AFGLOBAL_H_ +#define AFGLOBAL_H_ + + +#include "aftypes.h" +#include "afmodule.h" +#include "afshaper.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL_ARRAY( AF_WritingSystemClass ) + af_writing_system_classes[]; + + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + AF_DECLARE_SCRIPT_CLASS( af_ ## s ## _script_class ) + +#include "afscript.h" + + FT_LOCAL_ARRAY( AF_ScriptClass ) + af_script_classes[]; + + +#undef STYLE +#define STYLE( s, S, d, ws, sc, ss, c ) \ + AF_DECLARE_STYLE_CLASS( af_ ## s ## _style_class ) + +#include "afstyles.h" + + FT_LOCAL_ARRAY( AF_StyleClass ) + af_style_classes[]; + + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_LOCAL_ARRAY( char* ) + af_style_names[]; +#endif + + + /* + * Default values and flags for both autofitter globals (found in + * AF_ModuleRec) and face globals (in AF_FaceGlobalsRec). + */ + + /* index of fallback style in `af_style_classes' */ +#ifdef AF_CONFIG_OPTION_CJK +#define AF_STYLE_FALLBACK AF_STYLE_HANI_DFLT +#else +#define AF_STYLE_FALLBACK AF_STYLE_NONE_DFLT +#endif + /* default script for OpenType; ignored if HarfBuzz isn't used */ +#define AF_SCRIPT_DEFAULT AF_SCRIPT_LATN + + /* a bit mask for AF_DIGIT and AF_NONBASE */ +#define AF_STYLE_MASK 0x3FFF + /* an uncovered glyph */ +#define AF_STYLE_UNASSIGNED AF_STYLE_MASK + + /* if this flag is set, we have an ASCII digit */ +#define AF_DIGIT 0x8000U + /* if this flag is set, we have a non-base character */ +#define AF_NONBASE 0x4000U + + /* `increase-x-height' property */ +#define AF_PROP_INCREASE_X_HEIGHT_MIN 6 +#define AF_PROP_INCREASE_X_HEIGHT_MAX 0 + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** F A C E G L O B A L S *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + /* + * Note that glyph_styles[] maps each glyph to an index into the + * `af_style_classes' array. + * + */ + typedef struct AF_FaceGlobalsRec_ + { + FT_Face face; + FT_Long glyph_count; /* same as face->num_glyphs */ + FT_UShort* glyph_styles; + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + hb_font_t* hb_font; + hb_buffer_t* hb_buf; /* for feature comparison */ +#endif + + /* per-face auto-hinter properties */ + FT_UInt increase_x_height; + + AF_StyleMetrics metrics[AF_STYLE_MAX]; + + /* Compute darkening amount once per size. Use this to check whether */ + /* darken_{x,y} needs to be recomputed. */ + FT_UShort stem_darkening_for_ppem; + /* Copy from e.g. AF_LatinMetrics.axis[AF_DIMENSION_HORZ] */ + /* to compute the darkening amount. */ + FT_Pos standard_vertical_width; + /* Copy from e.g. AF_LatinMetrics.axis[AF_DIMENSION_VERT] */ + /* to compute the darkening amount. */ + FT_Pos standard_horizontal_width; + /* The actual amount to darken a glyph along the X axis. */ + FT_Pos darken_x; + /* The actual amount to darken a glyph along the Y axis. */ + FT_Pos darken_y; + /* Amount to scale down by to keep emboldened points */ + /* on the Y-axis in pre-computed blue zones. */ + FT_Fixed scale_down_factor; + AF_Module module; /* to access global properties */ + + } AF_FaceGlobalsRec; + + + /* + * model the global hints data for a given face, decomposed into + * style-specific items + */ + + FT_LOCAL( FT_Error ) + af_face_globals_new( FT_Face face, + AF_FaceGlobals *aglobals, + AF_Module module ); + + FT_LOCAL( FT_Error ) + af_face_globals_get_metrics( AF_FaceGlobals globals, + FT_UInt gindex, + FT_UInt options, + AF_StyleMetrics *ametrics ); + + FT_LOCAL( void ) + af_face_globals_free( AF_FaceGlobals globals ); + + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ); + + /* */ + + +FT_END_HEADER + +#endif /* AFGLOBAL_H_ */ + + +/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afhints.c b/drivers/freetype/src/autofit/afhints.c index e8defaa88d..6c3d032d1c 100644 --- a/drivers/freetype/freetype/src/autofit/afhints.c +++ b/drivers/freetype/src/autofit/afhints.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (body). */ /* */ -/* Copyright 2003-2007, 2009-2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -43,7 +43,15 @@ AF_Segment segment = NULL; - if ( axis->num_segments >= axis->max_segments ) + if ( axis->num_segments < AF_SEGMENTS_EMBEDDED ) + { + if ( axis->segments == NULL ) + { + axis->segments = axis->embedded.segments; + axis->max_segments = AF_SEGMENTS_EMBEDDED; + } + } + else if ( axis->num_segments >= axis->max_segments ) { FT_Int old_max = axis->max_segments; FT_Int new_max = old_max; @@ -60,8 +68,18 @@ if ( new_max < old_max || new_max > big_max ) new_max = big_max; - if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) ) - goto Exit; + if ( axis->segments == axis->embedded.segments ) + { + if ( FT_NEW_ARRAY( axis->segments, new_max ) ) + goto Exit; + ft_memcpy( axis->segments, axis->embedded.segments, + sizeof ( axis->embedded.segments ) ); + } + else + { + if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) ) + goto Exit; + } axis->max_segments = new_max; } @@ -74,12 +92,14 @@ } - /* Get new edge for given axis, direction, and position. */ + /* Get new edge for given axis, direction, and position, */ + /* without initializing the edge itself. */ FT_LOCAL( FT_Error ) af_axis_hints_new_edge( AF_AxisHints axis, FT_Int fpos, AF_Direction dir, + FT_Bool top_to_bottom_hinting, FT_Memory memory, AF_Edge *anedge ) { @@ -88,7 +108,15 @@ AF_Edge edges; - if ( axis->num_edges >= axis->max_edges ) + if ( axis->num_edges < AF_EDGES_EMBEDDED ) + { + if ( axis->edges == NULL ) + { + axis->edges = axis->embedded.edges; + axis->max_edges = AF_EDGES_EMBEDDED; + } + } + else if ( axis->num_edges >= axis->max_edges ) { FT_Int old_max = axis->max_edges; FT_Int new_max = old_max; @@ -105,8 +133,18 @@ if ( new_max < old_max || new_max > big_max ) new_max = big_max; - if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) ) - goto Exit; + if ( axis->edges == axis->embedded.edges ) + { + if ( FT_NEW_ARRAY( axis->edges, new_max ) ) + goto Exit; + ft_memcpy( axis->edges, axis->embedded.edges, + sizeof ( axis->embedded.edges ) ); + } + else + { + if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) ) + goto Exit; + } axis->max_edges = new_max; } @@ -116,7 +154,8 @@ while ( edge > edges ) { - if ( edge[-1].fpos < fpos ) + if ( top_to_bottom_hinting ? ( edge[-1].fpos > fpos ) + : ( edge[-1].fpos < fpos ) ) break; /* we want the edge with same position and minor direction */ @@ -130,10 +169,6 @@ axis->num_edges++; - FT_ZERO( edge ); - edge->fpos = (FT_Short)fpos; - edge->dir = (FT_Char)dir; - Exit: *anedge = edge; return error; @@ -144,6 +179,17 @@ #include FT_CONFIG_STANDARD_LIBRARY_H + /* The dump functions are used in the `ftgrid' demo program, too. */ +#define AF_DUMP( varformat ) \ + do \ + { \ + if ( to_stdout ) \ + printf varformat; \ + else \ + FT_TRACE7( varformat ); \ + } while ( 0 ) + + static const char* af_dir_str( AF_Direction dir ) { @@ -172,41 +218,146 @@ } -#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 ) +#define AF_INDEX_NUM( ptr, base ) (int)( (ptr) ? ( (ptr) - (base) ) : -1 ) + + + static char* + af_print_idx( char* p, + int idx ) + { + if ( idx == -1 ) + { + p[0] = '-'; + p[1] = '-'; + p[2] = '\0'; + } + else + ft_sprintf( p, "%d", idx ); + + return p; + } + + + static int + af_get_segment_index( AF_GlyphHints hints, + int point_idx, + int dimension ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Point point = hints->points + point_idx; + AF_Segment segments = axis->segments; + AF_Segment limit = segments + axis->num_segments; + AF_Segment segment; + + + for ( segment = segments; segment < limit; segment++ ) + { + if ( segment->first <= segment->last ) + { + if ( point >= segment->first && point <= segment->last ) + break; + } + else + { + AF_Point p = segment->first; + + + for (;;) + { + if ( point == p ) + goto Exit; + + if ( p == segment->last ) + break; + + p = p->next; + } + } + } + + Exit: + if ( segment == limit ) + return -1; + + return (int)( segment - segments ); + } + + + static int + af_get_edge_index( AF_GlyphHints hints, + int segment_idx, + int dimension ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Edge edges = axis->edges; + AF_Segment segment = axis->segments + segment_idx; + + + return segment_idx == -1 ? -1 : AF_INDEX_NUM( segment->edge, edges ); + } #ifdef __cplusplus extern "C" { #endif void - af_glyph_hints_dump_points( AF_GlyphHints hints ) + af_glyph_hints_dump_points( AF_GlyphHints hints, + FT_Bool to_stdout ) { - AF_Point points = hints->points; - AF_Point limit = points + hints->num_points; - AF_Point point; + AF_Point points = hints->points; + AF_Point limit = points + hints->num_points; + AF_Point* contour = hints->contours; + AF_Point* climit = contour + hints->num_contours; + AF_Point point; + + AF_DUMP(( "Table of points:\n" )); - FT_TRACE7(( "Table of points:\n" - " [ index | xorg | yorg | xscale | yscale" - " | xfit | yfit | flags ]\n" )); + if ( hints->num_points ) + AF_DUMP(( " index hedge hseg vedge vseg flags " + " xorg yorg xscale yscale xfit yfit" )); + else + AF_DUMP(( " (none)\n" )); for ( point = points; point < limit; point++ ) - FT_TRACE7(( " [ %5d | %5d | %5d | %6.2f | %6.2f" - " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n", - point - points, - point->fx, - point->fy, - point->ox / 64.0, - point->oy / 64.0, - point->x / 64.0, - point->y / 64.0, - ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ', - ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ', - ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ', - ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ', - ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ', - ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' ')); - FT_TRACE7(( "\n" )); + { + int point_idx = AF_INDEX_NUM( point, points ); + int segment_idx_0 = af_get_segment_index( hints, point_idx, 0 ); + int segment_idx_1 = af_get_segment_index( hints, point_idx, 1 ); + + char buf1[16], buf2[16], buf3[16], buf4[16]; + + + /* insert extra newline at the beginning of a contour */ + if ( contour < climit && *contour == point ) + { + AF_DUMP(( "\n" )); + contour++; + } + + AF_DUMP(( " %5d %5s %5s %5s %5s %s" + " %5d %5d %7.2f %7.2f %7.2f %7.2f\n", + point_idx, + af_print_idx( buf1, + af_get_edge_index( hints, segment_idx_1, 1 ) ), + af_print_idx( buf2, segment_idx_1 ), + af_print_idx( buf3, + af_get_edge_index( hints, segment_idx_0, 0 ) ), + af_print_idx( buf4, segment_idx_0 ), + ( point->flags & AF_FLAG_NEAR ) + ? " near " + : ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) + ? " weak " + : "strong", + + point->fx, + point->fy, + point->ox / 64.0, + point->oy / 64.0, + point->x / 64.0, + point->y / 64.0 )); + } + AF_DUMP(( "\n" )); } #ifdef __cplusplus } @@ -214,7 +365,7 @@ static const char* - af_edge_flags_to_string( AF_Edge_Flags flags ) + af_edge_flags_to_string( FT_UInt flags ) { static char temp[32]; int pos = 0; @@ -247,7 +398,8 @@ extern "C" { #endif void - af_glyph_hints_dump_segments( AF_GlyphHints hints ) + af_glyph_hints_dump_segments( AF_GlyphHints hints, + FT_Bool to_stdout ) { FT_Int dimension; @@ -261,35 +413,39 @@ AF_Segment limit = segments + axis->num_segments; AF_Segment seg; + char buf1[16], buf2[16], buf3[16]; - FT_TRACE7(( "Table of %s segments:\n", - dimension == AF_DIMENSION_HORZ ? "vertical" - : "horizontal" )); + + AF_DUMP(( "Table of %s segments:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" + : "horizontal" )); if ( axis->num_segments ) - FT_TRACE7(( " [ index | pos | dir | from" - " | to | link | serif | edge" - " | height | extra | flags ]\n" )); + AF_DUMP(( " index pos dir from to" + " link serif edge" + " height extra flags\n" )); else - FT_TRACE7(( " (none)\n" )); + AF_DUMP(( " (none)\n" )); for ( seg = segments; seg < limit; seg++ ) - FT_TRACE7(( " [ %5d | %5.2g | %5s | %4d" - " | %4d | %4d | %5d | %4d" - " | %6d | %5d | %11s ]\n", - seg - segments, - dimension == AF_DIMENSION_HORZ - ? (int)seg->first->ox / 64.0 - : (int)seg->first->oy / 64.0, - af_dir_str( (AF_Direction)seg->dir ), - AF_INDEX_NUM( seg->first, points ), - AF_INDEX_NUM( seg->last, points ), - AF_INDEX_NUM( seg->link, segments ), - AF_INDEX_NUM( seg->serif, segments ), - AF_INDEX_NUM( seg->edge, edges ), - seg->height, - seg->height - ( seg->max_coord - seg->min_coord ), - af_edge_flags_to_string( (AF_Edge_Flags)seg->flags ) )); - FT_TRACE7(( "\n" )); + AF_DUMP(( " %5d %5.2g %5s %4d %4d" + " %4s %5s %4s" + " %6d %5d %11s\n", + AF_INDEX_NUM( seg, segments ), + dimension == AF_DIMENSION_HORZ + ? (int)seg->first->ox / 64.0 + : (int)seg->first->oy / 64.0, + af_dir_str( (AF_Direction)seg->dir ), + AF_INDEX_NUM( seg->first, points ), + AF_INDEX_NUM( seg->last, points ), + + af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ), + af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ), + af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ), + + seg->height, + seg->height - ( seg->max_coord - seg->min_coord ), + af_edge_flags_to_string( seg->flags ) )); + AF_DUMP(( "\n" )); } } #ifdef __cplusplus @@ -332,7 +488,9 @@ af_glyph_hints_get_segment_offset( AF_GlyphHints hints, FT_Int dimension, FT_Int idx, - FT_Pos* offset ) + FT_Pos *offset, + FT_Bool *is_blue, + FT_Pos *blue_offset ) { AF_Dimension dim; AF_AxisHints axis; @@ -349,9 +507,18 @@ if ( idx < 0 || idx >= axis->num_segments ) return FT_THROW( Invalid_Argument ); - seg = &axis->segments[idx]; - *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox - : seg->first->oy; + seg = &axis->segments[idx]; + *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox + : seg->first->oy; + if ( seg->edge ) + *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 ); + else + *is_blue = FALSE; + + if ( *is_blue ) + *blue_offset = seg->edge->blue_edge->cur; + else + *blue_offset = 0; return FT_Err_Ok; } @@ -366,7 +533,8 @@ extern "C" { #endif void - af_glyph_hints_dump_edges( AF_GlyphHints hints ) + af_glyph_hints_dump_edges( AF_GlyphHints hints, + FT_Bool to_stdout ) { FT_Int dimension; @@ -378,99 +546,43 @@ AF_Edge limit = edges + axis->num_edges; AF_Edge edge; + char buf1[16], buf2[16]; + /* * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges * since they have a constant X coordinate. */ - FT_TRACE7(( "Table of %s edges:\n", - dimension == AF_DIMENSION_HORZ ? "vertical" - : "horizontal" )); + AF_DUMP(( "Table of %s edges:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" + : "horizontal" )); if ( axis->num_edges ) - FT_TRACE7(( " [ index | pos | dir | link" - " | serif | blue | opos | pos | flags ]\n" )); + AF_DUMP(( " index pos dir link serif" + " blue opos pos flags\n" )); else - FT_TRACE7(( " (none)\n" )); + AF_DUMP(( " (none)\n" )); for ( edge = edges; edge < limit; edge++ ) - FT_TRACE7(( " [ %5d | %5.2g | %5s | %4d" - " | %5d | %c | %5.2f | %5.2f | %11s ]\n", - edge - edges, - (int)edge->opos / 64.0, - af_dir_str( (AF_Direction)edge->dir ), - AF_INDEX_NUM( edge->link, edges ), - AF_INDEX_NUM( edge->serif, edges ), - edge->blue_edge ? 'y' : 'n', - edge->opos / 64.0, - edge->pos / 64.0, - af_edge_flags_to_string( (AF_Edge_Flags)edge->flags ) )); - FT_TRACE7(( "\n" )); + AF_DUMP(( " %5d %5.2g %5s %4s %5s" + " %c %5.2f %5.2f %11s\n", + AF_INDEX_NUM( edge, edges ), + (int)edge->opos / 64.0, + af_dir_str( (AF_Direction)edge->dir ), + af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ), + af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ), + + edge->blue_edge ? 'y' : 'n', + edge->opos / 64.0, + edge->pos / 64.0, + af_edge_flags_to_string( edge->flags ) )); + AF_DUMP(( "\n" )); } } #ifdef __cplusplus } #endif -#else /* !FT_DEBUG_AUTOFIT */ - - /* these empty stubs are only used to link the `ftgrid' test program */ - /* if debugging is disabled */ - -#ifdef __cplusplus - extern "C" { -#endif - - void - af_glyph_hints_dump_points( AF_GlyphHints hints ) - { - FT_UNUSED( hints ); - } - - - void - af_glyph_hints_dump_segments( AF_GlyphHints hints ) - { - FT_UNUSED( hints ); - } - - - FT_Error - af_glyph_hints_get_num_segments( AF_GlyphHints hints, - FT_Int dimension, - FT_Int* num_segments ) - { - FT_UNUSED( hints ); - FT_UNUSED( dimension ); - FT_UNUSED( num_segments ); - - return 0; - } - - - FT_Error - af_glyph_hints_get_segment_offset( AF_GlyphHints hints, - FT_Int dimension, - FT_Int idx, - FT_Pos* offset ) - { - FT_UNUSED( hints ); - FT_UNUSED( dimension ); - FT_UNUSED( idx ); - FT_UNUSED( offset ); - - return 0; - } - - - void - af_glyph_hints_dump_edges( AF_GlyphHints hints ) - { - FT_UNUSED( hints ); - } - -#ifdef __cplusplus - } -#endif +#undef AF_DUMP #endif /* !FT_DEBUG_AUTOFIT */ @@ -511,15 +623,15 @@ else { dir = AF_DIR_DOWN; - ll = dy; + ll = -dy; ss = dx; } } - /* return no direction if arm lengths differ too much */ + /* return no direction if arm lengths do not differ enough */ /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */ - ss *= 14; - if ( FT_ABS( ll ) <= FT_ABS( ss ) ) + /* the long arm is never negative */ + if ( ll <= 14 * FT_ABS( ss ) ) dir = AF_DIR_NONE; return dir; @@ -530,7 +642,8 @@ af_glyph_hints_init( AF_GlyphHints hints, FT_Memory memory ) { - FT_ZERO( hints ); + /* no need to initialize the embedded items */ + FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) ); hints->memory = memory; } @@ -538,13 +651,15 @@ FT_LOCAL_DEF( void ) af_glyph_hints_done( AF_GlyphHints hints ) { - FT_Memory memory = hints->memory; + FT_Memory memory; int dim; if ( !( hints && hints->memory ) ) return; + memory = hints->memory; + /* * note that we don't need to free the segment and edge * buffers since they are really within the hints->points array @@ -556,20 +671,24 @@ axis->num_segments = 0; axis->max_segments = 0; - FT_FREE( axis->segments ); + if ( axis->segments != axis->embedded.segments ) + FT_FREE( axis->segments ); axis->num_edges = 0; axis->max_edges = 0; - FT_FREE( axis->edges ); + if ( axis->edges != axis->embedded.edges ) + FT_FREE( axis->edges ); } - FT_FREE( hints->contours ); + if ( hints->contours != hints->embedded.contours ) + FT_FREE( hints->contours ); hints->max_contours = 0; hints->num_contours = 0; - FT_FREE( hints->points ); - hints->num_points = 0; + if ( hints->points != hints->embedded.points ) + FT_FREE( hints->points ); hints->max_points = 0; + hints->num_points = 0; hints->memory = NULL; } @@ -578,8 +697,8 @@ /* Reset metrics. */ FT_LOCAL_DEF( void ) - af_glyph_hints_rescale( AF_GlyphHints hints, - AF_ScriptMetrics metrics ) + af_glyph_hints_rescale( AF_GlyphHints hints, + AF_StyleMetrics metrics ) { hints->metrics = metrics; hints->scaler_flags = metrics->scaler.flags; @@ -613,15 +732,27 @@ /* first of all, reallocate the contours array if necessary */ new_max = (FT_UInt)outline->n_contours; - old_max = hints->max_contours; - if ( new_max > old_max ) + old_max = (FT_UInt)hints->max_contours; + + if ( new_max <= AF_CONTOURS_EMBEDDED ) { - new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */ + if ( hints->contours == NULL ) + { + hints->contours = hints->embedded.contours; + hints->max_contours = AF_CONTOURS_EMBEDDED; + } + } + else if ( new_max > old_max ) + { + if ( hints->contours == hints->embedded.contours ) + hints->contours = NULL; + + new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */ if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) goto Exit; - hints->max_contours = new_max; + hints->max_contours = (FT_Int)new_max; } /* @@ -630,15 +761,27 @@ * hint metrics appropriately */ new_max = (FT_UInt)( outline->n_points + 2 ); - old_max = hints->max_points; - if ( new_max > old_max ) + old_max = (FT_UInt)hints->max_points; + + if ( new_max <= AF_POINTS_EMBEDDED ) + { + if ( hints->points == NULL ) + { + hints->points = hints->embedded.points; + hints->max_points = AF_POINTS_EMBEDDED; + } + } + else if ( new_max > old_max ) { - new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */ + if ( hints->points == hints->embedded.points ) + hints->points = NULL; + + new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */ if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) goto Exit; - hints->max_points = new_max; + hints->max_points = (FT_Int)new_max; } hints->num_points = outline->n_points; @@ -673,23 +816,37 @@ AF_Point point; AF_Point point_limit = points + hints->num_points; + /* value 20 in `near_limit' is heuristic */ + FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM; + FT_Int near_limit = 20 * units_per_em / 2048; + /* compute coordinates & Bezier flags, next and prev */ { FT_Vector* vec = outline->points; char* tag = outline->tags; - AF_Point end = points + outline->contours[0]; + FT_Short endpoint = outline->contours[0]; + AF_Point end = points + endpoint; AF_Point prev = end; FT_Int contour_index = 0; for ( point = points; point < point_limit; point++, vec++, tag++ ) { + FT_Pos out_x, out_y; + + + point->in_dir = (FT_Char)AF_DIR_NONE; + point->out_dir = (FT_Char)AF_DIR_NONE; + point->fx = (FT_Short)vec->x; point->fy = (FT_Short)vec->y; point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; + end->fx = (FT_Short)outline->points[endpoint].x; + end->fy = (FT_Short)outline->points[endpoint].y; + switch ( FT_CURVE_TAG( *tag ) ) { case FT_CURVE_TAG_CONIC: @@ -702,6 +859,12 @@ point->flags = AF_FLAG_NONE; } + out_x = point->fx - prev->fx; + out_y = point->fy - prev->fy; + + if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) + prev->flags |= AF_FLAG_NEAR; + point->prev = prev; prev->next = point; prev = point; @@ -710,8 +873,9 @@ { if ( ++contour_index < outline->n_contours ) { - end = points + outline->contours[contour_index]; - prev = end; + endpoint = outline->contours[contour_index]; + end = points + endpoint; + prev = end; } } } @@ -732,60 +896,221 @@ } } - /* compute directions of in & out vectors */ { - AF_Point first = points; - AF_Point prev = NULL; - FT_Pos in_x = 0; - FT_Pos in_y = 0; - AF_Direction in_dir = AF_DIR_NONE; + /* + * Compute directions of `in' and `out' vectors. + * + * Note that distances between points that are very near to each + * other are accumulated. In other words, the auto-hinter either + * prepends the small vectors between near points to the first + * non-near vector, or the sum of small vector lengths exceeds a + * threshold, thus `grouping' the small vectors. All intermediate + * points are tagged as weak; the directions are adjusted also to + * be equal to the accumulated one. + */ + FT_Int near_limit2 = 2 * near_limit - 1; - for ( point = points; point < point_limit; point++ ) + AF_Point* contour; + AF_Point* contour_limit = hints->contours + hints->num_contours; + + + for ( contour = hints->contours; contour < contour_limit; contour++ ) { - AF_Point next; - FT_Pos out_x, out_y; + AF_Point first = *contour; + AF_Point next, prev, curr; + FT_Pos out_x, out_y; - if ( point == first ) + + /* since the first point of a contour could be part of a */ + /* series of near points, go backwards to find the first */ + /* non-near point and adjust `first' */ + + point = first; + prev = first->prev; + + while ( prev != first ) { - prev = first->prev; - in_x = first->fx - prev->fx; - in_y = first->fy - prev->fy; - in_dir = af_direction_compute( in_x, in_y ); - first = prev + 1; + out_x = point->fx - prev->fx; + out_y = point->fy - prev->fy; + + /* + * We use Taxicab metrics to measure the vector length. + * + * Note that the accumulated distances so far could have the + * opposite direction of the distance measured here. For this + * reason we use `near_limit2' for the comparison to get a + * non-near point even in the worst case. + */ + if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 ) + break; + + point = prev; + prev = prev->prev; } - point->in_dir = (FT_Char)in_dir; + /* adjust first point */ + first = point; + + /* now loop over all points of the contour to get */ + /* `in' and `out' vector directions */ + + curr = first; + + /* + * We abuse the `u' and `v' fields to store index deltas to the + * next and previous non-near point, respectively. + * + * To avoid problems with not having non-near points, we point to + * `first' by default as the next non-near point. + * + */ + curr->u = (FT_Pos)( first - curr ); + first->v = -curr->u; + + out_x = 0; + out_y = 0; + + next = first; + do + { + AF_Direction out_dir; + + + point = next; + next = point->next; + + out_x += next->fx - point->fx; + out_y += next->fy - point->fy; + + if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) + { + next->flags |= AF_FLAG_WEAK_INTERPOLATION; + continue; + } + + curr->u = (FT_Pos)( next - curr ); + next->v = -curr->u; + + out_dir = af_direction_compute( out_x, out_y ); + + /* adjust directions for all points inbetween; */ + /* the loop also updates position of `curr' */ + curr->out_dir = (FT_Char)out_dir; + for ( curr = curr->next; curr != next; curr = curr->next ) + { + curr->in_dir = (FT_Char)out_dir; + curr->out_dir = (FT_Char)out_dir; + } + next->in_dir = (FT_Char)out_dir; + + curr->u = (FT_Pos)( first - curr ); + first->v = -curr->u; + + out_x = 0; + out_y = 0; + + } while ( next != first ); + } + + /* + * The next step is to `simplify' an outline's topology so that we + * can identify local extrema more reliably: A series of + * non-horizontal or non-vertical vectors pointing into the same + * quadrant are handled as a single, long vector. From a + * topological point of the view, the intermediate points are of no + * interest and thus tagged as weak. + */ + + for ( point = points; point < point_limit; point++ ) + { + if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) + continue; + + if ( point->in_dir == AF_DIR_NONE && + point->out_dir == AF_DIR_NONE ) + { + /* check whether both vectors point into the same quadrant */ + + FT_Pos in_x, in_y; + FT_Pos out_x, out_y; + + AF_Point next_u = point + point->u; + AF_Point prev_v = point + point->v; + + + in_x = point->fx - prev_v->fx; + in_y = point->fy - prev_v->fy; - next = point->next; - out_x = next->fx - point->fx; - out_y = next->fy - point->fy; + out_x = next_u->fx - point->fx; + out_y = next_u->fy - point->fy; - in_dir = af_direction_compute( out_x, out_y ); - point->out_dir = (FT_Char)in_dir; + if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 ) + { + /* yes, so tag current point as weak */ + /* and update index deltas */ + + point->flags |= AF_FLAG_WEAK_INTERPOLATION; + + prev_v->u = (FT_Pos)( next_u - prev_v ); + next_u->v = -prev_v->u; + } + } + } + + /* + * Finally, check for remaining weak points. Everything else not + * collected in edges so far is then implicitly classified as strong + * points. + */ - /* check for weak points */ + for ( point = points; point < point_limit; point++ ) + { + if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) + continue; if ( point->flags & AF_FLAG_CONTROL ) { + /* control points are always weak */ Is_Weak_Point: point->flags |= AF_FLAG_WEAK_INTERPOLATION; } else if ( point->out_dir == point->in_dir ) { if ( point->out_dir != AF_DIR_NONE ) + { + /* current point lies on a horizontal or */ + /* vertical segment (but doesn't start or end it) */ goto Is_Weak_Point; + } - if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) ) - goto Is_Weak_Point; + { + AF_Point next_u = point + point->u; + AF_Point prev_v = point + point->v; + + + if ( ft_corner_is_flat( point->fx - prev_v->fx, + point->fy - prev_v->fy, + next_u->fx - point->fx, + next_u->fy - point->fy ) ) + { + /* either the `in' or the `out' vector is much more */ + /* dominant than the other one, so tag current point */ + /* as weak and update index deltas */ + + prev_v->u = (FT_Pos)( next_u - prev_v ); + next_u->v = -prev_v->u; + + goto Is_Weak_Point; + } + } } else if ( point->in_dir == -point->out_dir ) + { + /* current point forms a spike */ goto Is_Weak_Point; - - in_x = out_x; - in_y = out_y; - prev = point; + } } } } @@ -916,7 +1241,7 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - AF_Flags touch_flag; + FT_UInt touch_flag; if ( dim == AF_DIMENSION_HORZ ) @@ -942,8 +1267,7 @@ /* if this point is candidate to weak interpolation, we */ /* interpolate it after all strong points have been processed */ - if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) && - !( point->flags & AF_FLAG_INFLECTION ) ) + if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ) continue; if ( dim == AF_DIMENSION_VERT ) @@ -1098,33 +1422,27 @@ AF_Point ref2 ) { AF_Point p; - FT_Pos u; - FT_Pos v1 = ref1->v; - FT_Pos v2 = ref2->v; - FT_Pos d1 = ref1->u - v1; - FT_Pos d2 = ref2->u - v2; + FT_Pos u, v1, v2, u1, u2, d1, d2; if ( p1 > p2 ) return; - if ( v1 == v2 ) + if ( ref1->v > ref2->v ) { - for ( p = p1; p <= p2; p++ ) - { - u = p->v; - - if ( u <= v1 ) - u += d1; - else - u += d2; - - p->u = u; - } - return; + p = ref1; + ref1 = ref2; + ref2 = p; } - if ( v1 < v2 ) + v1 = ref1->v; + v2 = ref2->v; + u1 = ref1->u; + u2 = ref2->u; + d1 = u1 - v1; + d2 = u2 - v2; + + if ( u1 == u2 || v1 == v2 ) { for ( p = p1; p <= p2; p++ ) { @@ -1135,23 +1453,26 @@ else if ( u >= v2 ) u += d2; else - u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + u = u1; p->u = u; } } else { + FT_Fixed scale = FT_DivFix( u2 - u1, v2 - v1 ); + + for ( p = p1; p <= p2; p++ ) { u = p->v; - if ( u <= v2 ) - u += d2; - else if ( u >= v1 ) + if ( u <= v1 ) u += d1; + else if ( u >= v2 ) + u += d2; else - u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + u = u1 + FT_MulFix( u - v1, scale ); p->u = u; } @@ -1170,7 +1491,7 @@ AF_Point point_limit = points + hints->num_points; AF_Point* contour = hints->contours; AF_Point* contour_limit = contour + hints->num_contours; - AF_Flags touch_flag; + FT_UInt touch_flag; AF_Point point; AF_Point end_point; AF_Point first_point; @@ -1199,8 +1520,6 @@ } } - point = points; - for ( ; contour < contour_limit; contour++ ) { AF_Point first_touched, last_touched; @@ -1223,7 +1542,6 @@ } first_touched = point; - last_touched = point; for (;;) { diff --git a/drivers/freetype/freetype/src/autofit/afhints.h b/drivers/freetype/src/autofit/afhints.h index 776b3c844e..5142e6ed21 100644 --- a/drivers/freetype/freetype/src/autofit/afhints.h +++ b/drivers/freetype/src/autofit/afhints.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (specification). */ /* */ -/* Copyright 2003-2008, 2010-2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFHINTS_H__ -#define __AFHINTS_H__ +#ifndef AFHINTS_H_ +#define AFHINTS_H_ #include "aftypes.h" @@ -27,7 +27,7 @@ FT_BEGIN_HEADER /* * The definition of outline glyph hints. These are shared by all - * script analysis routines (until now). + * writing system analysis routines (until now). */ typedef enum AF_Dimension_ @@ -62,33 +62,34 @@ FT_BEGIN_HEADER * * by David Turner and Werner Lemberg * - * http://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf + * http://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf + * + * with appropriate updates. * * * Segments * * `af_{cjk,latin,...}_hints_compute_segments' are the functions to - * find segments in an outline. A segment is a series of consecutive - * points that are approximately aligned along a coordinate axis. The - * analysis to do so is specific to a script. + * find segments in an outline. * - * A segment must have at least two points, except in the case of - * `fake' segments that are generated to hint metrics appropriately, - * and which consist of a single point. + * A segment is a series of at least two consecutive points that are + * approximately aligned along a coordinate axis. The analysis to do + * so is specific to a writing system. * * * Edges * + * `af_{cjk,latin,...}_hints_compute_edges' are the functions to find + * edges. + * * As soon as segments are defined, the auto-hinter groups them into * edges. An edge corresponds to a single position on the main * dimension that collects one or more segments (allowing for a small * threshold). * - * The auto-hinter first tries to grid fit edges, then to align - * segments on the edges unless it detects that they form a serif. - * - * `af_{cjk,latin,...}_hints_compute_edges' are the functions to find - * edges; they are specific to a script. + * As an example, the `latin' writing system first tries to grid-fit + * edges, then to align segments on the edges unless it detects that + * they form a serif. * * * A H @@ -107,6 +108,8 @@ FT_BEGIN_HEADER * * Stems * + * Stems are detected by `af_{cjk,latin,...}_hint_edges'. + * * Segments need to be `linked' to other ones in order to detect stems. * A stem is made of two segments that face each other in opposite * directions and that are sufficiently close to each other. Using @@ -127,17 +130,21 @@ FT_BEGIN_HEADER * The best candidate is stored in field `link' in structure * `AF_Segment'. * - * Stems are detected by `af_{cjk,latin,...}_hint_edges'. - * * In the above ASCII drawing, the best candidate for both AB and CD is * GH, while the best candidate for GH is AB. Similarly, the best * candidate for EF and GH is AB, while the best candidate for AB is * GH. * + * The detection and handling of stems is dependent on the writing + * system. + * * * Serifs * - * On the opposite, a serif has + * Serifs are detected by `af_{cjk,latin,...}_hint_edges'. + * + * In comparison to a stem, a serif (as handled by the auto-hinter + * module that takes care of the `latin' writing system) has * * best segment_1 = segment_2 && best segment_2 != segment_1 * @@ -147,8 +154,6 @@ FT_BEGIN_HEADER * The best candidate is stored in field `serif' in structure * `AF_Segment' (and `link' is set to NULL). * - * Serifs are detected by `af_{cjk,latin,...}_hint_edges'. - * * * Touched points * @@ -169,18 +174,19 @@ FT_BEGIN_HEADER * * Strong Points * - * Experience has shown that points which are not part of an edge need - * to be interpolated linearly between their two closest edges, even if - * these are not part of the contour of those particular points. - * Typical candidates for this are + * Experience has shown that points not part of an edge need to be + * interpolated linearly between their two closest edges, even if these + * are not part of the contour of those particular points. Typical + * candidates for this are * * - angle points (i.e., points where the `in' and `out' direction * differ greatly) * * - inflection points (i.e., where the `in' and `out' angles are the - * same, but the curvature changes sign) + * same, but the curvature changes sign) [currently, such points + * aren't handled specially in the auto-hinter] * - * `af_glyph_hints_align_strong_points' is the function which takes + * `af_glyph_hints_align_strong_points' is the function that takes * care of such situations; it is equivalent to the TrueType `IP' * hinting instruction. * @@ -201,45 +207,30 @@ FT_BEGIN_HEADER /* point hint flags */ - typedef enum AF_Flags_ - { - AF_FLAG_NONE = 0, - - /* point type flags */ - AF_FLAG_CONIC = 1 << 0, - AF_FLAG_CUBIC = 1 << 1, - AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC, - - /* point extremum flags */ - AF_FLAG_EXTREMA_X = 1 << 2, - AF_FLAG_EXTREMA_Y = 1 << 3, +#define AF_FLAG_NONE 0 - /* point roundness flags */ - AF_FLAG_ROUND_X = 1 << 4, - AF_FLAG_ROUND_Y = 1 << 5, + /* point type flags */ +#define AF_FLAG_CONIC ( 1U << 0 ) +#define AF_FLAG_CUBIC ( 1U << 1 ) +#define AF_FLAG_CONTROL ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) - /* point touch flags */ - AF_FLAG_TOUCH_X = 1 << 6, - AF_FLAG_TOUCH_Y = 1 << 7, + /* point touch flags */ +#define AF_FLAG_TOUCH_X ( 1U << 2 ) +#define AF_FLAG_TOUCH_Y ( 1U << 3 ) - /* candidates for weak interpolation have this flag set */ - AF_FLAG_WEAK_INTERPOLATION = 1 << 8, + /* candidates for weak interpolation have this flag set */ +#define AF_FLAG_WEAK_INTERPOLATION ( 1U << 4 ) - /* all inflection points in the outline have this flag set */ - AF_FLAG_INFLECTION = 1 << 9 - - } AF_Flags; + /* the distance to the next point is very small */ +#define AF_FLAG_NEAR ( 1U << 5 ) /* edge hint flags */ - typedef enum AF_Edge_Flags_ - { - AF_EDGE_NORMAL = 0, - AF_EDGE_ROUND = 1 << 0, - AF_EDGE_SERIF = 1 << 1, - AF_EDGE_DONE = 1 << 2 - - } AF_Edge_Flags; +#define AF_EDGE_NORMAL 0 +#define AF_EDGE_ROUND ( 1U << 0 ) +#define AF_EDGE_SERIF ( 1U << 1 ) +#define AF_EDGE_DONE ( 1U << 2 ) +#define AF_EDGE_NEUTRAL ( 1U << 3 ) /* edge aligns to a neutral blue zone */ typedef struct AF_PointRec_* AF_Point; @@ -278,7 +269,6 @@ FT_BEGIN_HEADER AF_Segment link; /* (stem) link segment */ AF_Segment serif; /* primary segment for serifs */ - FT_Pos num_linked; /* number of linked segments */ FT_Pos score; /* used during stem matching */ FT_Pos len; /* used during stem matching */ @@ -301,7 +291,6 @@ FT_BEGIN_HEADER AF_Width blue_edge; /* non-NULL if this is a blue edge */ AF_Edge link; /* link edge */ AF_Edge serif; /* primary edge for serifs */ - FT_Short num_linked; /* number of linked edges */ FT_Int score; /* used during stem matching */ AF_Segment first; /* first segment in edge */ @@ -309,6 +298,8 @@ FT_BEGIN_HEADER } AF_EdgeRec; +#define AF_SEGMENTS_EMBEDDED 18 /* number of embedded segments */ +#define AF_EDGES_EMBEDDED 12 /* number of embedded edges */ typedef struct AF_AxisHintsRec_ { @@ -325,36 +316,55 @@ FT_BEGIN_HEADER AF_Direction major_dir; /* either vertical or horizontal */ + /* two arrays to avoid allocation penalty */ + struct + { + AF_SegmentRec segments[AF_SEGMENTS_EMBEDDED]; + AF_EdgeRec edges[AF_EDGES_EMBEDDED]; + } embedded; + + } AF_AxisHintsRec, *AF_AxisHints; +#define AF_POINTS_EMBEDDED 96 /* number of embedded points */ +#define AF_CONTOURS_EMBEDDED 8 /* number of embedded contours */ + typedef struct AF_GlyphHintsRec_ { - FT_Memory memory; + FT_Memory memory; + + FT_Fixed x_scale; + FT_Pos x_delta; - FT_Fixed x_scale; - FT_Pos x_delta; + FT_Fixed y_scale; + FT_Pos y_delta; - FT_Fixed y_scale; - FT_Pos y_delta; + FT_Int max_points; /* number of allocated points */ + FT_Int num_points; /* number of used points */ + AF_Point points; /* points array */ - FT_Int max_points; /* number of allocated points */ - FT_Int num_points; /* number of used points */ - AF_Point points; /* points array */ + FT_Int max_contours; /* number of allocated contours */ + FT_Int num_contours; /* number of used contours */ + AF_Point* contours; /* contours array */ - FT_Int max_contours; /* number of allocated contours */ - FT_Int num_contours; /* number of used contours */ - AF_Point* contours; /* contours array */ + AF_AxisHintsRec axis[AF_DIMENSION_MAX]; - AF_AxisHintsRec axis[AF_DIMENSION_MAX]; + FT_UInt32 scaler_flags; /* copy of scaler flags */ + FT_UInt32 other_flags; /* free for style-specific */ + /* implementations */ + AF_StyleMetrics metrics; - FT_UInt32 scaler_flags; /* copy of scaler flags */ - FT_UInt32 other_flags; /* free for script-specific */ - /* implementations */ - AF_ScriptMetrics metrics; + FT_Pos xmin_delta; /* used for warping */ + FT_Pos xmax_delta; - FT_Pos xmin_delta; /* used for warping */ - FT_Pos xmax_delta; + /* Two arrays to avoid allocation penalty. */ + /* The `embedded' structure must be the last element! */ + struct + { + AF_Point contours[AF_CONTOURS_EMBEDDED]; + AF_PointRec points[AF_POINTS_EMBEDDED]; + } embedded; } AF_GlyphHintsRec; @@ -373,9 +383,6 @@ FT_BEGIN_HEADER ( !_af_debug_disable_vert_hints && \ !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) ) -#define AF_HINTS_DO_ADVANCE( h ) \ - !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE ) - #define AF_HINTS_DO_BLUES( h ) ( !_af_debug_disable_blue_hints ) #else /* !FT_DEBUG_AUTOFIT */ @@ -386,12 +393,17 @@ FT_BEGIN_HEADER #define AF_HINTS_DO_VERTICAL( h ) \ !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) +#define AF_HINTS_DO_BLUES( h ) 1 + +#endif /* !FT_DEBUG_AUTOFIT */ + + #define AF_HINTS_DO_ADVANCE( h ) \ !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE ) -#define AF_HINTS_DO_BLUES( h ) 1 +#define AF_HINTS_DO_WARP( h ) \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_WARPER ) -#endif /* !FT_DEBUG_AUTOFIT */ FT_LOCAL( AF_Direction ) @@ -408,6 +420,7 @@ FT_BEGIN_HEADER af_axis_hints_new_edge( AF_AxisHints axis, FT_Int fpos, AF_Direction dir, + FT_Bool top_to_bottom_hinting, FT_Memory memory, AF_Edge *edge ); @@ -416,8 +429,8 @@ FT_BEGIN_HEADER FT_Memory memory ); FT_LOCAL( void ) - af_glyph_hints_rescale( AF_GlyphHints hints, - AF_ScriptMetrics metrics ); + af_glyph_hints_rescale( AF_GlyphHints hints, + AF_StyleMetrics metrics ); FT_LOCAL( FT_Error ) af_glyph_hints_reload( AF_GlyphHints hints, @@ -461,7 +474,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFHINTS_H__ */ +#endif /* AFHINTS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/autofit/afindic.c b/drivers/freetype/src/autofit/afindic.c index 8c24972598..097a2b2995 100644 --- a/drivers/freetype/freetype/src/autofit/afindic.c +++ b/drivers/freetype/src/autofit/afindic.c @@ -2,9 +2,9 @@ /* */ /* afindic.c */ /* */ -/* Auto-fitter hinting routines for Indic scripts (body). */ +/* Auto-fitter hinting routines for Indic writing system (body). */ /* */ -/* Copyright 2007, 2011-2013 by */ +/* Copyright 2007-2016 by */ /* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -79,12 +79,29 @@ static FT_Error - af_indic_hints_apply( AF_GlyphHints hints, + af_indic_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline, AF_CJKMetrics metrics ) { /* use CJK routines */ - return af_cjk_hints_apply( hints, outline, metrics ); + return af_cjk_hints_apply( glyph_index, hints, outline, metrics ); + } + + + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + static void + af_indic_get_standard_widths( AF_CJKMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; } @@ -97,60 +114,43 @@ /*************************************************************************/ - static const AF_Script_UniRangeRec af_indic_uniranges[] = - { -#if 0 - AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ -#endif - AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), /* Indic Range */ - AF_UNIRANGE_REC( 0x0F00UL, 0x0FFFUL), /* Tibetan */ - AF_UNIRANGE_REC( 0x1900UL, 0x194FUL), /* Limbu */ - AF_UNIRANGE_REC( 0x1B80UL, 0x1BBFUL), /* Sundanese */ - AF_UNIRANGE_REC( 0x1C80UL, 0x1CDFUL), /* Meetei Mayak */ - AF_UNIRANGE_REC( 0xA800UL, 0xA82FUL), /* Syloti Nagri */ - AF_UNIRANGE_REC( 0x11800UL, 0x118DFUL), /* Sharada */ - AF_UNIRANGE_REC( 0UL, 0UL) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_indic_script_class, - AF_SCRIPT_INDIC, - af_indic_uniranges, - 'o', /* XXX */ + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_indic_writing_system_class, + + AF_WRITING_SYSTEM_INDIC, sizeof ( AF_CJKMetricsRec ), - (AF_Script_InitMetricsFunc) af_indic_metrics_init, - (AF_Script_ScaleMetricsFunc)af_indic_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init, + (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)af_indic_get_standard_widths, - (AF_Script_InitHintsFunc) af_indic_hints_init, - (AF_Script_ApplyHintsFunc) af_indic_hints_apply + (AF_WritingSystem_InitHintsFunc) af_indic_hints_init, + (AF_WritingSystem_ApplyHintsFunc) af_indic_hints_apply ) + #else /* !AF_CONFIG_OPTION_INDIC */ - static const AF_Script_UniRangeRec af_indic_uniranges[] = - { - { 0, 0 } - }; + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_indic_writing_system_class, - AF_DEFINE_SCRIPT_CLASS( af_indic_script_class, - AF_SCRIPT_INDIC, - af_indic_uniranges, - 0, + AF_WRITING_SYSTEM_INDIC, sizeof ( AF_CJKMetricsRec ), - (AF_Script_InitMetricsFunc) NULL, - (AF_Script_ScaleMetricsFunc)NULL, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, + (AF_WritingSystem_ScaleMetricsFunc)NULL, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)NULL, - (AF_Script_InitHintsFunc) NULL, - (AF_Script_ApplyHintsFunc) NULL + (AF_WritingSystem_InitHintsFunc) NULL, + (AF_WritingSystem_ApplyHintsFunc) NULL ) + #endif /* !AF_CONFIG_OPTION_INDIC */ diff --git a/drivers/freetype/freetype/src/autofit/afindic.h b/drivers/freetype/src/autofit/afindic.h index c252cf20da..0772e07a29 100644 --- a/drivers/freetype/freetype/src/autofit/afindic.h +++ b/drivers/freetype/src/autofit/afindic.h @@ -2,9 +2,10 @@ /* */ /* afindic.h */ /* */ -/* Auto-fitter hinting routines for Indic scripts (specification). */ +/* Auto-fitter hinting routines for Indic writing system */ +/* (specification). */ /* */ -/* Copyright 2007, 2012 by */ +/* Copyright 2007-2016 by */ /* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +17,8 @@ /***************************************************************************/ -#ifndef __AFINDIC_H__ -#define __AFINDIC_H__ +#ifndef AFINDIC_H_ +#define AFINDIC_H_ #include "afhints.h" @@ -25,16 +26,16 @@ FT_BEGIN_HEADER - /* the Indic-specific script class */ + /* the `indic' writing system */ - AF_DECLARE_SCRIPT_CLASS( af_indic_script_class ) + AF_DECLARE_WRITING_SYSTEM_CLASS( af_indic_writing_system_class ) /* */ FT_END_HEADER -#endif /* __AFINDIC_H__ */ +#endif /* AFINDIC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/autofit/aflatin.c b/drivers/freetype/src/autofit/aflatin.c index ef0157a13e..7ccf3f6e37 100644 --- a/drivers/freetype/freetype/src/autofit/aflatin.c +++ b/drivers/freetype/src/autofit/aflatin.c @@ -2,9 +2,9 @@ /* */ /* aflatin.c */ /* */ -/* Auto-fitter hinting routines for latin script (body). */ +/* Auto-fitter hinting routines for latin writing system (body). */ /* */ -/* Copyright 2003-2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,6 +21,7 @@ #include FT_INTERNAL_DEBUG_H #include "afglobal.h" +#include "afpic.h" #include "aflatin.h" #include "aferrors.h" @@ -40,6 +41,10 @@ #define FT_COMPONENT trace_aflatin + /* needed for computation of round vs. flat segments */ +#define FLAT_THRESHOLD( x ) ( x / 14 ) + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -60,8 +65,11 @@ AF_GlyphHintsRec hints[1]; - FT_TRACE5(( "standard widths computation\n" - "===========================\n\n" )); + FT_TRACE5(( "\n" + "latin standard widths computation (style `%s')\n" + "=====================================================\n" + "\n", + af_style_names[metrics->root.style_class->style] )); af_glyph_hints_init( hints, face->memory ); @@ -70,19 +78,76 @@ { FT_Error error; - FT_UInt glyph_index; + FT_ULong glyph_index; int dim; AF_LatinMetricsRec dummy[1]; AF_Scaler scaler = &dummy->root.scaler; +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = metrics->root.globals; +#endif + + AF_StyleClass style_class = metrics->root.style_class; + AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET + [style_class->script]; + + void* shaper_buf; + const char* p; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_ULong ch = 0; +#endif + + p = script_class->standard_charstring; + shaper_buf = af_shaper_buf_create( face ); + + /* + * We check a list of standard characters to catch features like + * `c2sc' (small caps from caps) that don't contain lowercase letters + * by definition, or other features that mainly operate on numerals. + * The first match wins. + */ + + glyph_index = 0; + while ( *p ) + { + unsigned int num_idx; + +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; +#endif + + + while ( *p == ' ' ) + p++; + +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif + + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) + continue; + + /* otherwise exit loop if we have a result */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + NULL, + NULL ); + if ( glyph_index ) + break; + } - glyph_index = FT_Get_Char_Index( face, - metrics->root.clazz->standard_char ); - if ( glyph_index == 0 ) + af_shaper_buf_destroy( face, shaper_buf ); + + if ( !glyph_index ) goto Exit; - FT_TRACE5(( "standard character: 0x%X (glyph index %d)\n", - metrics->root.clazz->standard_char, glyph_index )); + FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n", + ch, glyph_index )); error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); if ( error || face->glyph->outline.n_points <= 0 ) @@ -101,7 +166,7 @@ scaler->render_mode = FT_RENDER_MODE_NORMAL; scaler->flags = 0; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy ); error = af_glyph_hints_reload( hints, &face->glyph->outline ); if ( error ) @@ -120,7 +185,15 @@ if ( error ) goto Exit; + /* + * We assume that the glyphs selected for the stem width + * computation are `featureless' enough so that the linking + * algorithm works fine without adjustments of its scoring + * function. + */ af_latin_hints_link_segments( hints, + 0, + NULL, (AF_Dimension)dim ); seg = axhints->segments; @@ -146,22 +219,21 @@ } /* this also replaces multiple almost identical stem widths */ - /* with a single one (the value 100 is heuristic) */ + /* with a single one (the value 100 is heuristic) */ af_sort_and_quantize_widths( &num_widths, axis->widths, dummy->units_per_em / 100 ); axis->width_count = num_widths; } - Exit: + Exit: for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { AF_LatinAxis axis = &metrics->axis[dim]; FT_Pos stdw; - stdw = ( axis->width_count > 0 ) - ? axis->widths[0].org - : AF_LATIN_CONSTANT( metrics, 50 ); + stdw = ( axis->width_count > 0 ) ? axis->widths[0].org + : AF_LATIN_CONSTANT( metrics, 50 ); /* let's try 20% of the smallest width */ axis->edge_distance_threshold = stdw / 5; @@ -193,22 +265,6 @@ } - -#define AF_LATIN_MAX_TEST_CHARACTERS 12 - - - static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES] - [AF_LATIN_MAX_TEST_CHARACTERS + 1] = - { - "THEZOCQS", - "HEZLOCUS", - "fijkdbh", - "xzroesc", - "xzroesc", - "pqgjy" - }; - - /* Find all blue zones. Flat segments give the reference points, */ /* round segments the overshoot positions. */ @@ -216,203 +272,575 @@ af_latin_metrics_init_blues( AF_LatinMetrics metrics, FT_Face face ) { - FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; - FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; - FT_Int num_flats; - FT_Int num_rounds; - FT_Int bb; + FT_Pos flats [AF_BLUE_STRING_MAX_LEN]; + FT_Pos rounds[AF_BLUE_STRING_MAX_LEN]; + + FT_UInt num_flats; + FT_UInt num_rounds; + AF_LatinBlue blue; FT_Error error; - AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; + AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; FT_Outline outline; + AF_StyleClass sc = metrics->root.style_class; + + AF_Blue_Stringset bss = sc->blue_stringset; + const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; + + FT_Pos flat_threshold = FLAT_THRESHOLD( metrics->units_per_em ); + + void* shaper_buf; + + + /* we walk over the blue character strings as specified in the */ + /* style's entry in the `af_blue_stringset' array */ - /* we compute the blues simply by loading each character from the */ - /* `af_latin_blue_chars[blues]' string, then finding its top-most or */ - /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ + FT_TRACE5(( "latin blue zones computation\n" + "============================\n" + "\n" )); - FT_TRACE5(( "blue zones computation\n" - "======================\n\n" )); + shaper_buf = af_shaper_buf_create( face ); - for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) { - const char* p = af_latin_blue_chars[bb]; - const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; + const char* p = &af_blue_strings[bs->string]; FT_Pos* blue_ref; FT_Pos* blue_shoot; + FT_Pos ascender; + FT_Pos descender; - FT_TRACE5(( "blue zone %d:\n", bb )); +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_Bool have_flag = 0; + + + FT_TRACE5(( "blue zone %d", axis->blue_count )); + + if ( bs->properties ) + { + FT_TRACE5(( " (" )); + + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) + { + FT_TRACE5(( "top" )); + have_flag = 1; + } + else if ( AF_LATIN_IS_SUB_TOP_BLUE( bs ) ) + { + FT_TRACE5(( "sub top" )); + have_flag = 1; + } + + if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) + { + if ( have_flag ) + FT_TRACE5(( ", " )); + FT_TRACE5(( "neutral" )); + have_flag = 1; + } + + if ( AF_LATIN_IS_X_HEIGHT_BLUE( bs ) ) + { + if ( have_flag ) + FT_TRACE5(( ", " )); + FT_TRACE5(( "small top" )); + have_flag = 1; + } + + if ( AF_LATIN_IS_LONG_BLUE( bs ) ) + { + if ( have_flag ) + FT_TRACE5(( ", " )); + FT_TRACE5(( "long" )); + } + + FT_TRACE5(( ")" )); + } + + FT_TRACE5(( ":\n" )); + } +#endif /* FT_DEBUG_LEVEL_TRACE */ num_flats = 0; num_rounds = 0; + ascender = 0; + descender = 0; - for ( ; p < limit && *p; p++ ) + while ( *p ) { - FT_UInt glyph_index; - FT_Pos best_y; /* same as points.y */ + FT_ULong glyph_index; + FT_Long y_offset; FT_Int best_point, best_contour_first, best_contour_last; FT_Vector* points; - FT_Bool round = 0; + FT_Pos best_y_extremum; /* same as points.y */ + FT_Bool best_round = 0; - /* load the character in the face -- skip unknown or empty ones */ - glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); - if ( glyph_index == 0 ) - continue; + unsigned int i, num_idx; - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - outline = face->glyph->outline; - if ( error || outline.n_points <= 0 ) +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; + FT_ULong ch; +#endif + + + while ( *p == ' ' ) + p++; + +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif + + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + + if ( !num_idx ) + { + FT_TRACE5(( " U+%04lX unavailable\n", ch )); continue; + } - /* now compute min or max point indices and coordinates */ - points = outline.points; - best_point = -1; - best_y = 0; /* make compiler happy */ - best_contour_first = 0; /* ditto */ - best_contour_last = 0; /* ditto */ + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) + best_y_extremum = FT_INT_MIN; + else + best_y_extremum = FT_INT_MAX; + /* iterate over all glyph elements of the character cluster */ + /* and get the data of the `biggest' one */ + for ( i = 0; i < num_idx; i++ ) { - FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; + FT_Pos best_y; + FT_Bool round = 0; - for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + i, + NULL, + &y_offset ); + if ( glyph_index == 0 ) { - FT_Int old_best_point = best_point; - FT_Int pp; + FT_TRACE5(( " U+%04lX unavailable\n", ch )); + continue; + } + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + outline = face->glyph->outline; + /* reject glyphs that don't produce any rendering */ + if ( error || outline.n_points <= 2 ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( num_idx == 1 ) + FT_TRACE5(( " U+%04lX contains no (usable) outlines\n", ch )); + else + FT_TRACE5(( " component %d of cluster starting with U+%04lX" + " contains no (usable) outlines\n", i, ch )); +#endif + continue; + } + /* now compute min or max point indices and coordinates */ + points = outline.points; + best_point = -1; + best_y = 0; /* make compiler happy */ + best_contour_first = 0; /* ditto */ + best_contour_last = 0; /* ditto */ - last = outline.contours[nn]; + { + FT_Int nn; + FT_Int first = 0; + FT_Int last = -1; - /* Avoid single-point contours since they are never rasterized. */ - /* In some fonts, they correspond to mark attachment points */ - /* which are way outside of the glyph's real outline. */ - if ( last <= first ) - continue; - if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y > best_y ) + FT_Int old_best_point = best_point; + FT_Int pp; + + + last = outline.contours[nn]; + + /* Avoid single-point contours since they are never */ + /* rasterized. In some fonts, they correspond to mark */ + /* attachment points that are way outside of the glyph's */ + /* real outline. */ + if ( last <= first ) + continue; + + if ( AF_LATIN_IS_TOP_BLUE( bs ) || + AF_LATIN_IS_SUB_TOP_BLUE( bs ) ) + { + for ( pp = first; pp <= last; pp++ ) { - best_point = pp; - best_y = points[pp].y; + if ( best_point < 0 || points[pp].y > best_y ) + { + best_point = pp; + best_y = points[pp].y; + ascender = FT_MAX( ascender, best_y + y_offset ); + } + else + descender = FT_MIN( descender, points[pp].y + y_offset ); } - } - else - { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y < best_y ) + } + else + { + for ( pp = first; pp <= last; pp++ ) { - best_point = pp; - best_y = points[pp].y; + if ( best_point < 0 || points[pp].y < best_y ) + { + best_point = pp; + best_y = points[pp].y; + descender = FT_MIN( descender, best_y + y_offset ); + } + else + ascender = FT_MAX( ascender, points[pp].y + y_offset ); } + } + + if ( best_point != old_best_point ) + { + best_contour_first = first; + best_contour_last = last; + } } + } - if ( best_point != old_best_point ) + /* now check whether the point belongs to a straight or round */ + /* segment; we first need to find in which contour the extremum */ + /* lies, then inspect its previous and next points */ + if ( best_point >= 0 ) + { + FT_Pos best_x = points[best_point].x; + FT_Int prev, next; + FT_Int best_segment_first, best_segment_last; + FT_Int best_on_point_first, best_on_point_last; + FT_Pos dist; + + + best_segment_first = best_point; + best_segment_last = best_point; + + if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON ) { - best_contour_first = first; - best_contour_last = last; + best_on_point_first = best_point; + best_on_point_last = best_point; + } + else + { + best_on_point_first = -1; + best_on_point_last = -1; } - } - FT_TRACE5(( " %c %ld", *p, best_y )); - } - /* now check whether the point belongs to a straight or round */ - /* segment; we first need to find in which contour the extremum */ - /* lies, then inspect its previous and next points */ - if ( best_point >= 0 ) - { - FT_Pos best_x = points[best_point].x; - FT_Int prev, next; - FT_Int best_on_point_first, best_on_point_last; - FT_Pos dist; + /* look for the previous and next points on the contour */ + /* that are not on the same Y coordinate, then threshold */ + /* the `closeness'... */ + prev = best_point; + next = prev; + do + { + if ( prev > best_contour_first ) + prev--; + else + prev = best_contour_last; - if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON ) - { - best_on_point_first = best_point; - best_on_point_last = best_point; - } - else - { - best_on_point_first = -1; - best_on_point_last = -1; - } + dist = FT_ABS( points[prev].y - best_y ); + /* accept a small distance or a small angle (both values are */ + /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ + if ( dist > 5 ) + if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) + break; - /* look for the previous and next points that are not on the */ - /* same Y coordinate, then threshold the `closeness'... */ - prev = best_point; - next = prev; + best_segment_first = prev; - do - { - if ( prev > best_contour_first ) - prev--; - else - prev = best_contour_last; + if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON ) + { + best_on_point_first = prev; + if ( best_on_point_last < 0 ) + best_on_point_last = prev; + } - dist = FT_ABS( points[prev].y - best_y ); - /* accept a small distance or a small angle (both values are */ - /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ - if ( dist > 5 ) - if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) - break; + } while ( prev != best_point ); - if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON ) + do { - best_on_point_first = prev; - if ( best_on_point_last < 0 ) - best_on_point_last = prev; + if ( next < best_contour_last ) + next++; + else + next = best_contour_first; + + dist = FT_ABS( points[next].y - best_y ); + if ( dist > 5 ) + if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) + break; + + best_segment_last = next; + + if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON ) + { + best_on_point_last = next; + if ( best_on_point_first < 0 ) + best_on_point_first = next; + } + + } while ( next != best_point ); + + if ( AF_LATIN_IS_LONG_BLUE( bs ) ) + { + /* If this flag is set, we have an additional constraint to */ + /* get the blue zone distance: Find a segment of the topmost */ + /* (or bottommost) contour that is longer than a heuristic */ + /* threshold. This ensures that small bumps in the outline */ + /* are ignored (for example, the `vertical serifs' found in */ + /* many Hebrew glyph designs). */ + + /* If this segment is long enough, we are done. Otherwise, */ + /* search the segment next to the extremum that is long */ + /* enough, has the same direction, and a not too large */ + /* vertical distance from the extremum. Note that the */ + /* algorithm doesn't check whether the found segment is */ + /* actually the one (vertically) nearest to the extremum. */ + + /* heuristic threshold value */ + FT_Pos length_threshold = metrics->units_per_em / 25; + + + dist = FT_ABS( points[best_segment_last].x - + points[best_segment_first].x ); + + if ( dist < length_threshold && + best_segment_last - best_segment_first + 2 <= + best_contour_last - best_contour_first ) + { + /* heuristic threshold value */ + FT_Pos height_threshold = metrics->units_per_em / 4; + + FT_Int first; + FT_Int last; + FT_Bool hit; + + /* we intentionally declare these two variables */ + /* outside of the loop since various compilers emit */ + /* incorrect warning messages otherwise, talking about */ + /* `possibly uninitialized variables' */ + FT_Int p_first = 0; /* make compiler happy */ + FT_Int p_last = 0; + + FT_Bool left2right; + + + /* compute direction */ + prev = best_point; + + do + { + if ( prev > best_contour_first ) + prev--; + else + prev = best_contour_last; + + if ( points[prev].x != best_x ) + break; + + } while ( prev != best_point ); + + /* skip glyph for the degenerate case */ + if ( prev == best_point ) + continue; + + left2right = FT_BOOL( points[prev].x < points[best_point].x ); + + first = best_segment_last; + last = first; + hit = 0; + + do + { + FT_Bool l2r; + FT_Pos d; + + + if ( !hit ) + { + /* no hit; adjust first point */ + first = last; + + /* also adjust first and last on point */ + if ( FT_CURVE_TAG( outline.tags[first] ) == + FT_CURVE_TAG_ON ) + { + p_first = first; + p_last = first; + } + else + { + p_first = -1; + p_last = -1; + } + + hit = 1; + } + + if ( last < best_contour_last ) + last++; + else + last = best_contour_first; + + if ( FT_ABS( best_y - points[first].y ) > height_threshold ) + { + /* vertical distance too large */ + hit = 0; + continue; + } + + /* same test as above */ + dist = FT_ABS( points[last].y - points[first].y ); + if ( dist > 5 ) + if ( FT_ABS( points[last].x - points[first].x ) <= + 20 * dist ) + { + hit = 0; + continue; + } + + if ( FT_CURVE_TAG( outline.tags[last] ) == FT_CURVE_TAG_ON ) + { + p_last = last; + if ( p_first < 0 ) + p_first = last; + } + + l2r = FT_BOOL( points[first].x < points[last].x ); + d = FT_ABS( points[last].x - points[first].x ); + + if ( l2r == left2right && + d >= length_threshold ) + { + /* all constraints are met; update segment after */ + /* finding its end */ + do + { + if ( last < best_contour_last ) + last++; + else + last = best_contour_first; + + d = FT_ABS( points[last].y - points[first].y ); + if ( d > 5 ) + if ( FT_ABS( points[next].x - points[first].x ) <= + 20 * dist ) + { + if ( last > best_contour_first ) + last--; + else + last = best_contour_last; + break; + } + + p_last = last; + + if ( FT_CURVE_TAG( outline.tags[last] ) == + FT_CURVE_TAG_ON ) + { + p_last = last; + if ( p_first < 0 ) + p_first = last; + } + + } while ( last != best_segment_first ); + + best_y = points[first].y; + + best_segment_first = first; + best_segment_last = last; + + best_on_point_first = p_first; + best_on_point_last = p_last; + + break; + } + + } while ( last != best_segment_first ); + } } - } while ( prev != best_point ); + /* for computing blue zones, we add the y offset as returned */ + /* by the currently used OpenType feature -- for example, */ + /* superscript glyphs might be identical to subscript glyphs */ + /* with a vertical shift */ + best_y += y_offset; - do - { - if ( next < best_contour_last ) - next++; +#ifdef FT_DEBUG_LEVEL_TRACE + if ( num_idx == 1 ) + FT_TRACE5(( " U+%04lX: best_y = %5ld", ch, best_y )); else - next = best_contour_first; + FT_TRACE5(( " component %d of cluster starting with U+%04lX:" + " best_y = %5ld", i, ch, best_y )); +#endif - dist = FT_ABS( points[next].y - best_y ); - if ( dist > 5 ) - if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) - break; + /* now set the `round' flag depending on the segment's kind: */ + /* */ + /* - if the horizontal distance between the first and last */ + /* `on' point is larger than a heuristic threshold */ + /* we have a flat segment */ + /* - if either the first or the last point of the segment is */ + /* an `off' point, the segment is round, otherwise it is */ + /* flat */ + if ( best_on_point_first >= 0 && + best_on_point_last >= 0 && + ( FT_ABS( points[best_on_point_last].x - + points[best_on_point_first].x ) ) > + flat_threshold ) + round = 0; + else + round = FT_BOOL( + FT_CURVE_TAG( outline.tags[best_segment_first] ) != + FT_CURVE_TAG_ON || + FT_CURVE_TAG( outline.tags[best_segment_last] ) != + FT_CURVE_TAG_ON ); - if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON ) + if ( round && AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) { - best_on_point_last = next; - if ( best_on_point_first < 0 ) - best_on_point_first = next; + /* only use flat segments for a neutral blue zone */ + FT_TRACE5(( " (round, skipped)\n" )); + continue; } - } while ( next != best_point ); + FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); + } - /* now set the `round' flag depending on the segment's kind */ - /* (value 8 is heuristic) */ - if ( best_on_point_first >= 0 && - best_on_point_last >= 0 && - (FT_UInt)( FT_ABS( points[best_on_point_last].x - - points[best_on_point_first].x ) ) > - metrics->units_per_em / 8 ) - round = 0; + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) + { + if ( best_y > best_y_extremum ) + { + best_y_extremum = best_y; + best_round = round; + } + } else - round = FT_BOOL( - FT_CURVE_TAG( outline.tags[prev] ) != FT_CURVE_TAG_ON || - FT_CURVE_TAG( outline.tags[next] ) != FT_CURVE_TAG_ON ); + { + if ( best_y < best_y_extremum ) + { + best_y_extremum = best_y; + best_round = round; + } + } + + } /* end for loop */ - FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); + if ( !( best_y_extremum == FT_INT_MIN || + best_y_extremum == FT_INT_MAX ) ) + { + if ( best_round ) + rounds[num_rounds++] = best_y_extremum; + else + flats[num_flats++] = best_y_extremum; } - if ( round ) - rounds[num_rounds++] = best_y; - else - flats[num_flats++] = best_y; - } + } /* end while loop */ if ( num_flats == 0 && num_rounds == 0 ) { @@ -448,7 +876,7 @@ } else { - *blue_ref = flats[num_flats / 2]; + *blue_ref = flats [num_flats / 2]; *blue_shoot = rounds[num_rounds / 2]; } @@ -462,7 +890,8 @@ FT_Bool over_ref = FT_BOOL( shoot > ref ); - if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) + if ( ( AF_LATIN_IS_TOP_BLUE( bs ) || + AF_LATIN_IS_SUB_TOP_BLUE( bs) ) ^ over_ref ) { *blue_ref = *blue_shoot = ( shoot + ref ) / 2; @@ -472,22 +901,32 @@ } } + blue->ascender = ascender; + blue->descender = descender; + blue->flags = 0; - if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) blue->flags |= AF_LATIN_BLUE_TOP; + if ( AF_LATIN_IS_SUB_TOP_BLUE( bs ) ) + blue->flags |= AF_LATIN_BLUE_SUB_TOP; + if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) + blue->flags |= AF_LATIN_BLUE_NEUTRAL; /* * The following flag is used later to adjust the y and x scales * in order to optimize the pixel grid alignment of the top of small * letters. */ - if ( bb == AF_LATIN_BLUE_SMALL_TOP ) + if ( AF_LATIN_IS_X_HEIGHT_BLUE( bs ) ) blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; FT_TRACE5(( " -> reference = %ld\n" " overshoot = %ld\n", *blue_ref, *blue_shoot )); - } + + } /* end for loop */ + + af_shaper_buf_destroy( face, shaper_buf ); FT_TRACE5(( "\n" )); @@ -501,26 +940,36 @@ af_latin_metrics_check_digits( AF_LatinMetrics metrics, FT_Face face ) { - FT_UInt i; FT_Bool started = 0, same_width = 1; FT_Fixed advance, old_advance = 0; + void* shaper_buf; + + /* in all supported charmaps, digits have character codes 0x30-0x39 */ + const char digits[] = "0 1 2 3 4 5 6 7 8 9"; + const char* p; - /* digit `0' is 0x30 in all supported charmaps */ - for ( i = 0x30; i <= 0x39; i++ ) + + p = digits; + shaper_buf = af_shaper_buf_create( face ); + + while ( *p ) { - FT_UInt glyph_index; + FT_ULong glyph_index; + unsigned int num_idx; - glyph_index = FT_Get_Char_Index( face, i ); - if ( glyph_index == 0 ) + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) continue; - if ( FT_Get_Advance( face, glyph_index, - FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM, - &advance ) ) + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + &advance, + NULL ); + if ( !glyph_index ) continue; if ( started ) @@ -538,6 +987,8 @@ } } + af_shaper_buf_destroy( face, shaper_buf ); + metrics->root.digits_have_same_width = same_width; } @@ -650,7 +1101,54 @@ else #endif if ( dim == AF_DIMENSION_VERT ) - scale = FT_MulDiv( scale, fitted, scaled ); + { + FT_Pos max_height; + FT_Pos dist; + FT_Fixed new_scale; + + + new_scale = FT_MulDiv( scale, fitted, scaled ); + + /* the scaling should not change the result by more than two pixels */ + max_height = metrics->units_per_em; + + for ( nn = 0; nn < Axis->blue_count; nn++ ) + { + max_height = FT_MAX( max_height, Axis->blues[nn].ascender ); + max_height = FT_MAX( max_height, -Axis->blues[nn].descender ); + } + + dist = FT_ABS( FT_MulFix( max_height, new_scale - scale ) ); + dist &= ~127; + + if ( dist == 0 ) + { + scale = new_scale; + + FT_TRACE5(( + "af_latin_metrics_scale_dim:" + " x height alignment (style `%s'):\n" + " " + " vertical scaling changed from %.4f to %.4f (by %d%%)\n" + "\n", + af_style_names[metrics->root.style_class->style], + axis->org_scale / 65536.0, + scale / 65536.0, + ( fitted - scaled ) * 100 / scaled )); + } +#ifdef FT_DEBUG_LEVEL_TRACE + else + { + FT_TRACE5(( + "af_latin_metrics_scale_dim:" + " x height alignment (style `%s'):\n" + " " + " excessive vertical scaling abandoned\n" + "\n", + af_style_names[metrics->root.style_class->style] )); + } +#endif + } } } } @@ -669,6 +1167,10 @@ metrics->root.scaler.y_delta = delta; } + FT_TRACE5(( "%s widths (style `%s')\n", + dim == AF_DIMENSION_HORZ ? "horizontal" : "vertical", + af_style_names[metrics->root.style_class->style] )); + /* scale the widths */ for ( nn = 0; nn < axis->width_count; nn++ ) { @@ -677,15 +1179,34 @@ width->cur = FT_MulFix( width->org, scale ); width->fit = width->cur; + + FT_TRACE5(( " %d scaled to %.2f\n", + width->org, + width->cur / 64.0 )); } + FT_TRACE5(( "\n" )); + /* an extra-light axis corresponds to a standard width that is */ /* smaller than 5/8 pixels */ axis->extra_light = (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( axis->extra_light ) + FT_TRACE5(( "`%s' style is extra light (at current resolution)\n" + "\n", + af_style_names[metrics->root.style_class->style] )); +#endif + if ( dim == AF_DIMENSION_VERT ) { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( axis->blue_count ) + FT_TRACE5(( "blue zones (style `%s')\n", + af_style_names[metrics->root.style_class->style] )); +#endif + /* scale the blue zones */ for ( nn = 0; nn < axis->blue_count; nn++ ) { @@ -759,6 +1280,61 @@ blue->flags |= AF_LATIN_BLUE_ACTIVE; } } + + /* use sub-top blue zone only if it doesn't overlap with */ + /* another (non-sup-top) blue zone; otherwise, the */ + /* effect would be similar to a neutral blue zone, which */ + /* is not desired here */ + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = &axis->blues[nn]; + FT_UInt i; + + + if ( !( blue->flags & AF_LATIN_BLUE_SUB_TOP ) ) + continue; + if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) + continue; + + for ( i = 0; i < axis->blue_count; i++ ) + { + AF_LatinBlue b = &axis->blues[i]; + + + if ( b->flags & AF_LATIN_BLUE_SUB_TOP ) + continue; + if ( !( b->flags & AF_LATIN_BLUE_ACTIVE ) ) + continue; + + if ( b->ref.fit <= blue->shoot.fit && + b->shoot.fit >= blue->ref.fit ) + { + blue->flags &= ~AF_LATIN_BLUE_ACTIVE; + break; + } + } + } + +#ifdef FT_DEBUG_LEVEL_TRACE + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = &axis->blues[nn]; + + + FT_TRACE5(( " reference %d: %d scaled to %.2f%s\n" + " overshoot %d: %d scaled to %.2f%s\n", + nn, + blue->ref.org, + blue->ref.fit / 64.0, + blue->flags & AF_LATIN_BLUE_ACTIVE ? "" + : " (inactive)", + nn, + blue->shoot.org, + blue->shoot.fit / 64.0, + blue->flags & AF_LATIN_BLUE_ACTIVE ? "" + : " (inactive)" )); + } +#endif } } @@ -778,6 +1354,22 @@ } + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + FT_LOCAL_DEF( void ) + af_latin_get_standard_widths( AF_LatinMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -793,14 +1385,17 @@ af_latin_hints_compute_segments( AF_GlyphHints hints, AF_Dimension dim ) { - AF_AxisHints axis = &hints->axis[dim]; - FT_Memory memory = hints->memory; - FT_Error error = FT_Err_Ok; - AF_Segment segment = NULL; - AF_SegmentRec seg0; - AF_Point* contour = hints->contours; - AF_Point* contour_limit = contour + hints->num_contours; - AF_Direction major_dir, segment_dir; + AF_LatinMetrics metrics = (AF_LatinMetrics)hints->metrics; + AF_AxisHints axis = &hints->axis[dim]; + FT_Memory memory = hints->memory; + FT_Error error = FT_Err_Ok; + AF_Segment segment = NULL; + AF_SegmentRec seg0; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + AF_Direction major_dir, segment_dir; + + FT_Pos flat_threshold = FLAT_THRESHOLD( metrics->units_per_em ); FT_ZERO( &seg0 ); @@ -841,16 +1436,35 @@ /* do each contour separately */ for ( ; contour < contour_limit; contour++ ) { - AF_Point point = contour[0]; - AF_Point last = point->prev; - int on_edge = 0; - FT_Pos min_pos = 32000; /* minimum segment pos != min_coord */ - FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ - FT_Bool passed; - + AF_Point point = contour[0]; + AF_Point last = point->prev; + int on_edge = 0; + + /* we call values measured along a segment (point->v) */ + /* `coordinates', and values orthogonal to it (point->u) */ + /* `positions' */ + FT_Pos min_pos = 32000; + FT_Pos max_pos = -32000; + FT_Pos min_coord = 32000; + FT_Pos max_coord = -32000; + FT_UShort min_flags = AF_FLAG_NONE; + FT_UShort max_flags = AF_FLAG_NONE; + FT_Pos min_on_coord = 32000; + FT_Pos max_on_coord = -32000; + + FT_Bool passed; + + AF_Segment prev_segment = NULL; + + FT_Pos prev_min_pos = min_pos; + FT_Pos prev_max_pos = max_pos; + FT_Pos prev_min_coord = min_coord; + FT_Pos prev_max_coord = max_coord; + FT_UShort prev_min_flags = min_flags; + FT_UShort prev_max_flags = max_flags; + FT_Pos prev_min_on_coord = min_on_coord; + FT_Pos prev_max_on_coord = max_on_coord; - if ( point == last ) /* skip singletons -- just in case */ - continue; if ( FT_ABS( last->out_dir ) == major_dir && FT_ABS( point->out_dir ) == major_dir ) @@ -881,40 +1495,181 @@ if ( on_edge ) { + /* get minimum and maximum position */ u = point->u; if ( u < min_pos ) min_pos = u; if ( u > max_pos ) max_pos = u; + /* get minimum and maximum coordinate together with flags */ + v = point->v; + if ( v < min_coord ) + { + min_coord = v; + min_flags = point->flags; + } + if ( v > max_coord ) + { + max_coord = v; + max_flags = point->flags; + } + + /* get minimum and maximum coordinate of `on' points */ + if ( !( point->flags & AF_FLAG_CONTROL ) ) + { + v = point->v; + if ( v < min_on_coord ) + min_on_coord = v; + if ( v > max_on_coord ) + max_on_coord = v; + } + if ( point->out_dir != segment_dir || point == last ) { - /* we are just leaving an edge; record a new segment! */ - segment->last = point; - segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); - - /* a segment is round if either its first or last point */ - /* is a control point */ - if ( ( segment->first->flags | point->flags ) & - AF_FLAG_CONTROL ) - segment->flags |= AF_EDGE_ROUND; + /* check whether the new segment's start point is identical to */ + /* the previous segment's end point; for example, this might */ + /* happen for spikes */ - /* compute segment size */ - min_pos = max_pos = point->v; + if ( !prev_segment || segment->first != prev_segment->last ) + { + /* points are different: we are just leaving an edge, thus */ + /* record a new segment */ + + segment->last = point; + segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + + /* a segment is round if either its first or last point */ + /* is a control point, and the length of the on points */ + /* inbetween doesn't exceed a heuristic limit */ + if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && + ( max_on_coord - min_on_coord ) < flat_threshold ) + segment->flags |= AF_EDGE_ROUND; + + segment->min_coord = (FT_Short)min_coord; + segment->max_coord = (FT_Short)max_coord; + segment->height = segment->max_coord - segment->min_coord; + + prev_segment = segment; + prev_min_pos = min_pos; + prev_max_pos = max_pos; + prev_min_coord = min_coord; + prev_max_coord = max_coord; + prev_min_flags = min_flags; + prev_max_flags = max_flags; + prev_min_on_coord = min_on_coord; + prev_max_on_coord = max_on_coord; + } + else + { + /* points are the same: we don't create a new segment but */ + /* merge the current segment with the previous one */ - v = segment->first->v; - if ( v < min_pos ) - min_pos = v; - if ( v > max_pos ) - max_pos = v; + if ( prev_segment->last->in_dir == point->in_dir ) + { + /* we have identical directions (this can happen for */ + /* degenerate outlines that move zig-zag along the main */ + /* axis without changing the coordinate value of the other */ + /* axis, and where the segments have just been merged): */ + /* unify segments */ + + /* update constraints */ - segment->min_coord = (FT_Short)min_pos; - segment->max_coord = (FT_Short)max_pos; - segment->height = (FT_Short)( segment->max_coord - - segment->min_coord ); + if ( prev_min_pos < min_pos ) + min_pos = prev_min_pos; + if ( prev_max_pos > max_pos ) + max_pos = prev_max_pos; + + if ( prev_min_coord < min_coord ) + { + min_coord = prev_min_coord; + min_flags = prev_min_flags; + } + if ( prev_max_coord > max_coord ) + { + max_coord = prev_max_coord; + max_flags = prev_max_flags; + } + + if ( prev_min_on_coord < min_on_coord ) + min_on_coord = prev_min_on_coord; + if ( prev_max_on_coord > max_on_coord ) + max_on_coord = prev_max_on_coord; + + prev_segment->last = point; + prev_segment->pos = (FT_Short)( ( min_pos + + max_pos ) >> 1 ); + + if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && + ( max_on_coord - min_on_coord ) < flat_threshold ) + prev_segment->flags |= AF_EDGE_ROUND; + else + prev_segment->flags &= ~AF_EDGE_ROUND; + + prev_segment->min_coord = (FT_Short)min_coord; + prev_segment->max_coord = (FT_Short)max_coord; + prev_segment->height = prev_segment->max_coord - + prev_segment->min_coord; + } + else + { + /* we have different directions; use the properties of the */ + /* longer segment and discard the other one */ + + if ( FT_ABS( prev_max_coord - prev_min_coord ) > + FT_ABS( max_coord - min_coord ) ) + { + /* discard current segment */ + + if ( min_pos < prev_min_pos ) + prev_min_pos = min_pos; + if ( max_pos > prev_max_pos ) + prev_max_pos = max_pos; + + prev_segment->last = point; + prev_segment->pos = (FT_Short)( ( prev_min_pos + + prev_max_pos ) >> 1 ); + } + else + { + /* discard previous segment */ + + if ( prev_min_pos < min_pos ) + min_pos = prev_min_pos; + if ( prev_max_pos > max_pos ) + max_pos = prev_max_pos; + + segment->last = point; + segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + + if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && + ( max_on_coord - min_on_coord ) < flat_threshold ) + segment->flags |= AF_EDGE_ROUND; + + segment->min_coord = (FT_Short)min_coord; + segment->max_coord = (FT_Short)max_coord; + segment->height = segment->max_coord - + segment->min_coord; + + *prev_segment = *segment; + + prev_min_pos = min_pos; + prev_max_pos = max_pos; + prev_min_coord = min_coord; + prev_max_coord = max_coord; + prev_min_flags = min_flags; + prev_max_flags = max_flags; + prev_min_on_coord = min_on_coord; + prev_max_on_coord = max_on_coord; + } + } + + axis->num_segments--; + } on_edge = 0; segment = NULL; + /* fall through */ } } @@ -927,22 +1682,63 @@ passed = 1; } - if ( !on_edge && FT_ABS( point->out_dir ) == major_dir ) + /* if we are not on an edge, check whether the major direction */ + /* coincides with the current point's `out' direction, or */ + /* whether we have a single-point contour */ + if ( !on_edge && + ( FT_ABS( point->out_dir ) == major_dir || + point == point->prev ) ) { /* this is the start of a new segment! */ segment_dir = (AF_Direction)point->out_dir; - /* clear all segment fields */ error = af_axis_hints_new_segment( axis, memory, &segment ); if ( error ) goto Exit; - segment[0] = seg0; - segment->dir = (FT_Char)segment_dir; - min_pos = max_pos = point->u; - segment->first = point; - segment->last = point; - on_edge = 1; + /* clear all segment fields */ + segment[0] = seg0; + + segment->dir = (FT_Char)segment_dir; + segment->first = point; + segment->last = point; + + /* `af_axis_hints_new_segment' reallocates memory, */ + /* thus we have to refresh the `prev_segment' pointer */ + if ( prev_segment ) + prev_segment = segment - 1; + + min_pos = max_pos = point->u; + min_coord = max_coord = point->v; + min_flags = max_flags = point->flags; + + if ( point->flags & AF_FLAG_CONTROL ) + { + min_on_coord = 32000; + max_on_coord = -32000; + } + else + min_on_coord = max_on_coord = point->v; + + on_edge = 1; + + if ( point == point->prev ) + { + /* we have a one-point segment: this is a one-point */ + /* contour with `in' and `out' direction set to */ + /* AF_DIR_NONE */ + segment->pos = (FT_Short)min_pos; + + if (point->flags & AF_FLAG_CONTROL) + segment->flags |= AF_EDGE_ROUND; + + segment->min_coord = (FT_Short)point->v; + segment->max_coord = (FT_Short)point->v; + segment->height = 0; + + on_edge = 0; + segment = NULL; + } } point = point->next; @@ -966,9 +1762,6 @@ FT_Pos last_v = last->v; - if ( first == last ) - continue; - if ( first_v < last_v ) { AF_Point p; @@ -1007,31 +1800,44 @@ } - /* Link segments to form stems and serifs. */ + /* Link segments to form stems and serifs. If `width_count' and */ + /* `widths' are non-zero, use them to fine-tune the scoring function. */ FT_LOCAL_DEF( void ) af_latin_hints_link_segments( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ) { AF_AxisHints axis = &hints->axis[dim]; AF_Segment segments = axis->segments; AF_Segment segment_limit = segments + axis->num_segments; - FT_Pos len_threshold, len_score; + FT_Pos len_threshold, len_score, dist_score, max_width; AF_Segment seg1, seg2; + if ( width_count ) + max_width = widths[width_count - 1].org; + else + max_width = 0; + + /* a heuristic value to set up a minimum value for overlapping */ len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); if ( len_threshold == 0 ) len_threshold = 1; + /* a heuristic value to weight lengths */ len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); + /* a heuristic value to weight distances (no call to */ + /* AF_LATIN_CONSTANT needed, since we work on multiples */ + /* of the stem width) */ + dist_score = 3000; + /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { - /* the fake segments are introduced to hint the metrics -- */ - /* we must never link them to anything */ - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + if ( seg1->dir != axis->major_dir ) continue; /* search for stems having opposite directions, */ @@ -1045,10 +1851,9 @@ if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 ) { /* compute distance between the two segments */ - FT_Pos dist = pos2 - pos1; - FT_Pos min = seg1->min_coord; - FT_Pos max = seg1->max_coord; - FT_Pos len, score; + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len; if ( min < seg2->min_coord ) @@ -1058,15 +1863,49 @@ max = seg2->max_coord; /* compute maximum coordinate difference of the two segments */ + /* (this is, how much they overlap) */ len = max - min; if ( len >= len_threshold ) { - /* small coordinate differences cause a higher score, and */ - /* segments with a greater distance cause a higher score also */ - score = dist + len_score / len; + /* + * The score is the sum of two demerits indicating the + * `badness' of a fit, measured along the segments' main axis + * and orthogonal to it, respectively. + * + * o The less overlapping along the main axis, the worse it + * is, causing a larger demerit. + * + * o The nearer the orthogonal distance to a stem width, the + * better it is, causing a smaller demerit. For simplicity, + * however, we only increase the demerit for values that + * exceed the largest stem width. + */ + + FT_Pos dist = pos2 - pos1; + + FT_Pos dist_demerit, score; + + + if ( max_width ) + { + /* distance demerits are based on multiples of `max_width'; */ + /* we scale by 1024 for getting more precision */ + FT_Pos delta = ( dist << 10 ) / max_width - ( 1 << 10 ); + + + if ( delta > 10000 ) + dist_demerit = 32000; + else if ( delta > 0 ) + dist_demerit = delta * delta / dist_score; + else + dist_demerit = 0; + } + else + dist_demerit = dist; /* default if no widths available */ + + score = dist_demerit + len_score / len; /* and we search for the smallest score */ - /* of the sum of the two values */ if ( score < seg1->score ) { seg1->score = score; @@ -1111,6 +1950,12 @@ FT_Memory memory = hints->memory; AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; + AF_StyleClass style_class = hints->metrics->style_class; + AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET + [style_class->script]; + + FT_Bool top_to_bottom_hinting = 0; + AF_Segment segments = axis->segments; AF_Segment segment_limit = segments + axis->num_segments; AF_Segment seg; @@ -1133,6 +1978,9 @@ : AF_DIR_RIGHT; #endif + if ( dim == AF_DIMENSION_VERT ) + top_to_bottom_hinting = script_class->top_to_bottom_hinting; + /* * We ignore all segments that are less than 1 pixel in length * to avoid many problems with serif fonts. We compute the @@ -1174,7 +2022,10 @@ FT_Int ee; - if ( seg->height < segment_length_threshold ) + /* ignore too short segments and, in this loop, */ + /* one-point segments without a direction */ + if ( seg->height < segment_length_threshold || + seg->dir == AF_DIR_NONE ) continue; /* A special case for serif edges: If they are smaller than */ @@ -1210,6 +2061,7 @@ /* sort according to the position */ error = af_axis_hints_new_edge( axis, seg->pos, (AF_Direction)seg->dir, + top_to_bottom_hinting, memory, &edge ); if ( error ) goto Exit; @@ -1235,6 +2087,44 @@ } } + /* we loop again over all segments to catch one-point segments */ + /* without a direction: if possible, link them to existing edges */ + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge found = NULL; + FT_Int ee; + + + if ( seg->dir != AF_DIR_NONE ) + continue; + + /* look for an edge corresponding to the segment */ + for ( ee = 0; ee < axis->num_edges; ee++ ) + { + AF_Edge edge = axis->edges + ee; + FT_Pos dist; + + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold ) + { + found = edge; + break; + } + } + + /* one-point segments without a match are ignored */ + if ( found ) + { + seg->edge_next = found->first; + found->last->edge_next = seg; + found->last = seg; + } + } + /******************************************************************/ /* */ @@ -1385,7 +2275,7 @@ /* Example: the `c' in cour.pfa at size 13 */ if ( edge->serif && edge->link ) - edge->serif = 0; + edge->serif = NULL; } } @@ -1398,6 +2288,8 @@ FT_LOCAL_DEF( FT_Error ) af_latin_hints_detect_features( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ) { FT_Error error; @@ -1406,7 +2298,7 @@ error = af_latin_hints_compute_segments( hints, dim ); if ( !error ) { - af_latin_hints_link_segments( hints, dim ); + af_latin_hints_link_segments( hints, width_count, widths, dim ); error = af_latin_hints_compute_edges( hints, dim ); } @@ -1417,7 +2309,7 @@ /* Compute all edges which lie within blue zones. */ - FT_LOCAL_DEF( void ) + static void af_latin_hints_compute_blue_edges( AF_GlyphHints hints, AF_LatinMetrics metrics ) { @@ -1435,8 +2327,9 @@ for ( ; edge < edge_limit; edge++ ) { FT_UInt bb; - AF_Width best_blue = NULL; - FT_Pos best_dist; /* initial threshold */ + AF_Width best_blue = NULL; + FT_Bool best_blue_is_neutral = 0; + FT_Pos best_dist; /* initial threshold */ /* compute the initial threshold as a fraction of the EM size */ @@ -1450,24 +2343,27 @@ for ( bb = 0; bb < latin->blue_count; bb++ ) { AF_LatinBlue blue = latin->blues + bb; - FT_Bool is_top_blue, is_major_dir; + FT_Bool is_top_blue, is_neutral_blue, is_major_dir; /* skip inactive blue zones (i.e., those that are too large) */ if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) continue; - /* if it is a top zone, check for right edges -- if it is a bottom */ - /* zone, check for left edges */ - /* */ - /* of course, that's for TrueType */ - is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); - is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); - - /* if it is a top zone, the edge must be against the major */ - /* direction; if it is a bottom zone, it must be in the major */ - /* direction */ - if ( is_top_blue ^ is_major_dir ) + /* if it is a top zone, check for right edges (against the major */ + /* direction); if it is a bottom zone, check for left edges (in */ + /* the major direction) -- this assumes the TrueType convention */ + /* for the orientation of contours */ + is_top_blue = + (FT_Byte)( ( blue->flags & ( AF_LATIN_BLUE_TOP | + AF_LATIN_BLUE_SUB_TOP ) ) != 0 ); + is_neutral_blue = + (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_NEUTRAL ) != 0); + is_major_dir = + FT_BOOL( edge->dir == axis->major_dir ); + + /* neutral blue zones are handled for both directions */ + if ( is_top_blue ^ is_major_dir || is_neutral_blue ) { FT_Pos dist; @@ -1480,15 +2376,19 @@ dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { - best_dist = dist; - best_blue = &blue->ref; + best_dist = dist; + best_blue = &blue->ref; + best_blue_is_neutral = is_neutral_blue; } /* now compare it to the overshoot position and check whether */ /* the edge is rounded, and whether the edge is over the */ /* reference position of a top zone, or under the reference */ - /* position of a bottom zone */ - if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) + /* position of a bottom zone (provided we don't have a */ + /* neutral blue zone) */ + if ( edge->flags & AF_EDGE_ROUND && + dist != 0 && + !is_neutral_blue ) { FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); @@ -1502,8 +2402,9 @@ dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { - best_dist = dist; - best_blue = &blue->shoot; + best_dist = dist; + best_blue = &blue->shoot; + best_blue_is_neutral = is_neutral_blue; } } } @@ -1511,7 +2412,11 @@ } if ( best_blue ) + { edge->blue_edge = best_blue; + if ( best_blue_is_neutral ) + edge->flags |= AF_EDGE_NEUTRAL; + } } } @@ -1527,7 +2432,7 @@ FT_Face face = metrics->root.scaler.face; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics ); /* * correct x_scale and y_scale if needed, since they may have @@ -1575,11 +2480,20 @@ /* * In `light' hinting mode we disable horizontal hinting completely. * We also do it if the face is italic. + * + * However, if warping is enabled (which only works in `light' hinting + * mode), advance widths get adjusted, too. */ if ( mode == FT_RENDER_MODE_LIGHT || ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; +#ifdef AF_CONFIG_OPTION_USE_WARPER + /* get (global) warper flag */ + if ( !metrics->root.globals->module->warping ) + scaler_flags |= AF_SCALER_FLAG_NO_WARPER; +#endif + hints->scaler_flags = scaler_flags; hints->other_flags = other_flags; @@ -1600,13 +2514,13 @@ static FT_Pos af_latin_snap_width( AF_Width widths, - FT_Int count, + FT_UInt count, FT_Pos width ) { - int n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - FT_Pos scaled; + FT_UInt n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; for ( n = 0; n < count; n++ ) @@ -1651,11 +2565,12 @@ af_latin_compute_stem_width( AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, - AF_Edge_Flags base_flags, - AF_Edge_Flags stem_flags ) + FT_Pos base_delta, + FT_UInt base_flags, + FT_UInt stem_flags ) { - AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; - AF_LatinAxis axis = & metrics->axis[dim]; + AF_LatinMetrics metrics = (AF_LatinMetrics)hints->metrics; + AF_LatinAxis axis = &metrics->axis[dim]; FT_Pos dist = width; FT_Int sign = 0; FT_Int vertical = ( dim == AF_DIMENSION_VERT ); @@ -1728,7 +2643,39 @@ dist += delta; } else - dist = ( dist + 32 ) & ~63; + { + /* A stem's end position depends on two values: the start */ + /* position and the stem length. The former gets usually */ + /* rounded to the grid, while the latter gets rounded also if it */ + /* exceeds a certain length (see below in this function). This */ + /* `double rounding' can lead to a great difference to the */ + /* original, unhinted position; this normally doesn't matter for */ + /* large PPEM values, but for small sizes it can easily make */ + /* outlines collide. For this reason, we adjust the stem length */ + /* by a small amount depending on the PPEM value in case the */ + /* former and latter rounding both point into the same */ + /* direction. */ + + FT_Pos bdelta = 0; + + + if ( ( ( width > 0 ) && ( base_delta > 0 ) ) || + ( ( width < 0 ) && ( base_delta < 0 ) ) ) + { + FT_UInt ppem = metrics->root.scaler.face->size->metrics.x_ppem; + + + if ( ppem < 10 ) + bdelta = base_delta; + else if ( ppem < 30 ) + bdelta = ( base_delta * (FT_Pos)( 30 - ppem ) ) / 20; + + if ( bdelta < 0 ) + bdelta = -bdelta; + } + + dist = ( dist - bdelta + 32 ) & ~63; + } } } else @@ -1817,19 +2764,24 @@ AF_Edge base_edge, AF_Edge stem_edge ) { - FT_Pos dist = stem_edge->opos - base_edge->opos; + FT_Pos dist, base_delta; + FT_Pos fitted_width; - FT_Pos fitted_width = af_latin_compute_stem_width( - hints, dim, dist, - (AF_Edge_Flags)base_edge->flags, - (AF_Edge_Flags)stem_edge->flags ); + + dist = stem_edge->opos - base_edge->opos; + base_delta = base_edge->pos - base_edge->opos; + + fitted_width = af_latin_compute_stem_width( hints, dim, + dist, base_delta, + base_edge->flags, + stem_edge->flags ); stem_edge->pos = base_edge->pos + fitted_width; FT_TRACE5(( " LINK: edge %d (opos=%.2f) linked to %.2f," " dist was %.2f, now %.2f\n", - stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0, + stem_edge - hints->axis[dim].edges, stem_edge->opos / 64.0, stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 )); } @@ -1861,7 +2813,7 @@ /* The main grid-fitting routine. */ - FT_LOCAL_DEF( void ) + static void af_latin_hint_edges( AF_GlyphHints hints, AF_Dimension dim ) { @@ -1873,13 +2825,23 @@ AF_Edge anchor = NULL; FT_Int has_serifs = 0; + AF_StyleClass style_class = hints->metrics->style_class; + AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET + [style_class->script]; + + FT_Bool top_to_bottom_hinting = 0; + #ifdef FT_DEBUG_LEVEL_TRACE - FT_UInt num_actions = 0; + FT_UInt num_actions = 0; #endif - FT_TRACE5(( "%s edge hinting\n", - dim == AF_DIMENSION_VERT ? "horizontal" : "vertical" )); + FT_TRACE5(( "latin %s edge hinting (style `%s')\n", + dim == AF_DIMENSION_VERT ? "horizontal" : "vertical", + af_style_names[hints->metrics->style_class->style] )); + + if ( dim == AF_DIMENSION_VERT ) + top_to_bottom_hinting = script_class->top_to_bottom_hinting; /* we begin by aligning all stems relative to the blue zone */ /* if needed -- that's only for horizontal edges */ @@ -1895,14 +2857,41 @@ if ( edge->flags & AF_EDGE_DONE ) continue; - blue = edge->blue_edge; edge1 = NULL; edge2 = edge->link; + /* + * If a stem contains both a neutral and a non-neutral blue zone, + * skip the neutral one. Otherwise, outlines with different + * directions might be incorrectly aligned at the same vertical + * position. + * + * If we have two neutral blue zones, skip one of them. + * + */ + if ( edge->blue_edge && edge2 && edge2->blue_edge ) + { + FT_Byte neutral = edge->flags & AF_EDGE_NEUTRAL; + FT_Byte neutral2 = edge2->flags & AF_EDGE_NEUTRAL; + + + if ( neutral2 ) + { + edge2->blue_edge = NULL; + edge2->flags &= ~AF_EDGE_NEUTRAL; + } + else if ( neutral ) + { + edge->blue_edge = NULL; + edge->flags &= ~AF_EDGE_NEUTRAL; + } + } + + blue = edge->blue_edge; if ( blue ) edge1 = edge; - /* flip edges if the other stem is aligned to a blue zone */ + /* flip edges if the other edge is aligned to a blue zone */ else if ( edge2 && edge2->blue_edge ) { blue = edge2->blue_edge; @@ -1969,7 +2958,7 @@ /* this should not happen, but it's better to be safe */ if ( edge2->blue_edge ) { - FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2-edges )); + FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2 - edges )); af_latin_align_linked_edge( hints, dim, edge2, edge ); edge->flags |= AF_EDGE_DONE; @@ -1989,10 +2978,10 @@ org_len = edge2->opos - edge->opos; - cur_len = af_latin_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + cur_len = af_latin_compute_stem_width( hints, dim, + org_len, 0, + edge->flags, + edge2->flags ); /* some voodoo to specially round edges for small stem widths; */ /* the idea is to align the center of a stem, then shifting */ @@ -2059,10 +3048,10 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_latin_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + cur_len = af_latin_compute_stem_width( hints, dim, + org_len, 0, + edge->flags, + edge2->flags ); if ( edge2->flags & AF_EDGE_DONE ) { @@ -2120,10 +3109,10 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_latin_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + cur_len = af_latin_compute_stem_width( hints, dim, + org_len, 0, + edge->flags, + edge2->flags ); cur_pos1 = FT_PIX_ROUND( org_pos ); delta1 = cur_pos1 + ( cur_len >> 1 ) - org_center; @@ -2152,16 +3141,25 @@ edge->flags |= AF_EDGE_DONE; edge2->flags |= AF_EDGE_DONE; - if ( edge > edges && edge->pos < edge[-1].pos ) + if ( edge > edges && + ( top_to_bottom_hinting ? ( edge->pos > edge[-1].pos ) + : ( edge->pos < edge[-1].pos ) ) ) { + /* don't move if stem would (almost) disappear otherwise; */ + /* the ad-hoc value 16 corresponds to 1/4px */ + if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 ) + { #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, + edge->pos / 64.0, + edge[-1].pos / 64.0 )); - num_actions++; + num_actions++; #endif - edge->pos = edge[-1].pos; + edge->pos = edge[-1].pos; + } } } } @@ -2313,29 +3311,46 @@ #endif edge->flags |= AF_EDGE_DONE; - if ( edge > edges && edge->pos < edge[-1].pos ) + if ( edge > edges && + ( top_to_bottom_hinting ? ( edge->pos > edge[-1].pos ) + : ( edge->pos < edge[-1].pos ) ) ) { + /* don't move if stem would (almost) disappear otherwise; */ + /* the ad-hoc value 16 corresponds to 1/4px */ + if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 ) + { #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, + edge->pos / 64.0, + edge[-1].pos / 64.0 )); - num_actions++; + num_actions++; #endif - edge->pos = edge[-1].pos; + edge->pos = edge[-1].pos; + } } - if ( edge + 1 < edge_limit && - edge[1].flags & AF_EDGE_DONE && - edge->pos > edge[1].pos ) + if ( edge + 1 < edge_limit && + edge[1].flags & AF_EDGE_DONE && + ( top_to_bottom_hinting ? ( edge->pos < edge[1].pos ) + : ( edge->pos > edge[1].pos ) ) ) { + /* don't move if stem would (almost) disappear otherwise; */ + /* the ad-hoc value 16 corresponds to 1/4px */ + if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 ) + { #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[1].pos / 64.0 )); + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, + edge->pos / 64.0, + edge[1].pos / 64.0 )); - num_actions++; + num_actions++; #endif - edge->pos = edge[1].pos; + edge->pos = edge[1].pos; + } } } } @@ -2351,13 +3366,16 @@ /* Apply the complete hinting algorithm to a latin glyph. */ static FT_Error - af_latin_hints_apply( AF_GlyphHints hints, + af_latin_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline, AF_LatinMetrics metrics ) { FT_Error error; int dim; + AF_LatinAxis axis; + error = af_glyph_hints_reload( hints, outline ); if ( error ) @@ -2365,24 +3383,35 @@ /* analyze glyph outline */ #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || - AF_HINTS_DO_HORIZONTAL( hints ) ) + if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) || + AF_HINTS_DO_HORIZONTAL( hints ) ) #else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) #endif { - error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); + axis = &metrics->axis[AF_DIMENSION_HORZ]; + error = af_latin_hints_detect_features( hints, + axis->width_count, + axis->widths, + AF_DIMENSION_HORZ ); if ( error ) goto Exit; } if ( AF_HINTS_DO_VERTICAL( hints ) ) { - error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); + axis = &metrics->axis[AF_DIMENSION_VERT]; + error = af_latin_hints_detect_features( hints, + axis->width_count, + axis->widths, + AF_DIMENSION_VERT ); if ( error ) goto Exit; - af_latin_hints_compute_blue_edges( hints, metrics ); + /* apply blue zones to base characters only */ + if ( !( metrics->root.globals->glyph_styles[glyph_index] & AF_NONBASE ) ) + af_latin_hints_compute_blue_edges( hints, metrics ); } /* grid-fit the outline */ @@ -2390,7 +3419,8 @@ { #ifdef AF_CONFIG_OPTION_USE_WARPER if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) + metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; @@ -2403,7 +3433,7 @@ scale, delta ); continue; } -#endif +#endif /* AF_CONFIG_OPTION_USE_WARPER */ if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) @@ -2414,6 +3444,7 @@ af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); } } + af_glyph_hints_save( hints, outline ); Exit: @@ -2430,56 +3461,20 @@ /*************************************************************************/ - /* XXX: this should probably fine tuned to differentiate better between */ - /* scripts... */ + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_latin_writing_system_class, - static const AF_Script_UniRangeRec af_latin_uniranges[] = - { - AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ - AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */ - AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ - AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ - AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ - AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */ - AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ - AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */ - AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ - AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */ - AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */ - AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */ - AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */ - AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ - AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ - AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ - AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ - AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */ - AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ - AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */ - AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */ - AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */ - AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */ - AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */ - AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */ - AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */ - AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */ - AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplement */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - AF_DEFINE_SCRIPT_CLASS( af_latin_script_class, - AF_SCRIPT_LATIN, - af_latin_uniranges, - 'o', + AF_WRITING_SYSTEM_LATIN, sizeof ( AF_LatinMetricsRec ), - (AF_Script_InitMetricsFunc) af_latin_metrics_init, - (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init, + (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths, - (AF_Script_InitHintsFunc) af_latin_hints_init, - (AF_Script_ApplyHintsFunc) af_latin_hints_apply + (AF_WritingSystem_InitHintsFunc) af_latin_hints_init, + (AF_WritingSystem_ApplyHintsFunc) af_latin_hints_apply ) diff --git a/drivers/freetype/freetype/src/autofit/aflatin.h b/drivers/freetype/src/autofit/aflatin.h index d9170b3dcc..fe6bbd801a 100644 --- a/drivers/freetype/freetype/src/autofit/aflatin.h +++ b/drivers/freetype/src/autofit/aflatin.h @@ -2,9 +2,10 @@ /* */ /* aflatin.h */ /* */ -/* Auto-fitter hinting routines for latin script (specification). */ +/* Auto-fitter hinting routines for latin writing system */ +/* (specification). */ /* */ -/* Copyright 2003-2007, 2009, 2011-2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,18 +17,17 @@ /***************************************************************************/ -#ifndef __AFLATIN_H__ -#define __AFLATIN_H__ +#ifndef AFLATIN_H_ +#define AFLATIN_H_ #include "afhints.h" FT_BEGIN_HEADER + /* the `latin' writing system */ - /* the latin-specific script class */ - - AF_DECLARE_SCRIPT_CLASS( af_latin_script_class ) + AF_DECLARE_WRITING_SYSTEM_CLASS( af_latin_writing_system_class ) /* constants are given with units_per_em == 2048 in mind */ @@ -46,48 +46,40 @@ FT_BEGIN_HEADER /* * The following declarations could be embedded in the file `aflatin.c'; - * they have been made semi-public to allow alternate script hinters to - * re-use some of them. + * they have been made semi-public to allow alternate writing system + * hinters to re-use some of them. */ - /* Latin (global) metrics management */ - - enum - { - AF_LATIN_BLUE_CAPITAL_TOP, - AF_LATIN_BLUE_CAPITAL_BOTTOM, - AF_LATIN_BLUE_SMALL_F_TOP, - AF_LATIN_BLUE_SMALL_TOP, - AF_LATIN_BLUE_SMALL_BOTTOM, - AF_LATIN_BLUE_SMALL_MINOR, - - AF_LATIN_BLUE_MAX - }; - - -#define AF_LATIN_IS_TOP_BLUE( b ) ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \ - (b) == AF_LATIN_BLUE_SMALL_F_TOP || \ - (b) == AF_LATIN_BLUE_SMALL_TOP ) +#define AF_LATIN_IS_TOP_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_TOP ) +#define AF_LATIN_IS_SUB_TOP_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_SUB_TOP ) +#define AF_LATIN_IS_NEUTRAL_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_NEUTRAL ) +#define AF_LATIN_IS_X_HEIGHT_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_X_HEIGHT ) +#define AF_LATIN_IS_LONG_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_LONG ) #define AF_LATIN_MAX_WIDTHS 16 -#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX - enum - { - AF_LATIN_BLUE_ACTIVE = 1 << 0, /* set if zone height is <= 3/4px */ - AF_LATIN_BLUE_TOP = 1 << 1, /* result of AF_LATIN_IS_TOP_BLUE */ - AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */ - /* optimization */ - AF_LATIN_BLUE_FLAG_MAX - }; +#define AF_LATIN_BLUE_ACTIVE ( 1U << 0 ) /* zone height is <= 3/4px */ +#define AF_LATIN_BLUE_TOP ( 1U << 1 ) /* we have a top blue zone */ +#define AF_LATIN_BLUE_SUB_TOP ( 1U << 2 ) /* we have a subscript top */ + /* blue zone */ +#define AF_LATIN_BLUE_NEUTRAL ( 1U << 3 ) /* we have neutral blue zone */ +#define AF_LATIN_BLUE_ADJUSTMENT ( 1U << 4 ) /* used for scale adjustment */ + /* optimization */ typedef struct AF_LatinBlueRec_ { AF_WidthRec ref; AF_WidthRec shoot; + FT_Pos ascender; + FT_Pos descender; FT_UInt flags; } AF_LatinBlueRec, *AF_LatinBlue; @@ -106,7 +98,7 @@ FT_BEGIN_HEADER /* ignored for horizontal metrics */ FT_UInt blue_count; - AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX]; + AF_LatinBlueRec blues[AF_BLUE_STRINGSET_MAX]; FT_Fixed org_scale; FT_Pos org_delta; @@ -116,9 +108,9 @@ FT_BEGIN_HEADER typedef struct AF_LatinMetricsRec_ { - AF_ScriptMetricsRec root; - FT_UInt units_per_em; - AF_LatinAxisRec axis[AF_DIMENSION_MAX]; + AF_StyleMetricsRec root; + FT_UInt units_per_em; + AF_LatinAxisRec axis[AF_DIMENSION_MAX]; } AF_LatinMetricsRec, *AF_LatinMetrics; @@ -148,15 +140,11 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ - enum - { - AF_LATIN_HINTS_HORZ_SNAP = 1 << 0, /* enable stem width snapping */ - AF_LATIN_HINTS_VERT_SNAP = 1 << 1, /* enable stem height snapping */ - AF_LATIN_HINTS_STEM_ADJUST = 1 << 2, /* enable stem width/height */ - /* adjustment */ - AF_LATIN_HINTS_MONO = 1 << 3 /* indicate monochrome */ - /* rendering */ - }; +#define AF_LATIN_HINTS_HORZ_SNAP ( 1U << 0 ) /* stem width snapping */ +#define AF_LATIN_HINTS_VERT_SNAP ( 1U << 1 ) /* stem height snapping */ +#define AF_LATIN_HINTS_STEM_ADJUST ( 1U << 2 ) /* stem width/height */ + /* adjustment */ +#define AF_LATIN_HINTS_MONO ( 1U << 3 ) /* monochrome rendering */ #define AF_LATIN_HINTS_DO_HORZ_SNAP( h ) \ @@ -174,7 +162,7 @@ FT_BEGIN_HEADER /* * The next functions shouldn't normally be exported. However, other - * scripts might like to use these functions as-is. + * writing systems might like to use these functions as-is. */ FT_LOCAL( FT_Error ) af_latin_hints_compute_segments( AF_GlyphHints hints, @@ -182,6 +170,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) af_latin_hints_link_segments( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ); FT_LOCAL( FT_Error ) @@ -190,13 +180,15 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) af_latin_hints_detect_features( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ); /* */ FT_END_HEADER -#endif /* __AFLATIN_H__ */ +#endif /* AFLATIN_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/autofit/aflatin2.c b/drivers/freetype/src/autofit/aflatin2.c index b1e9658d5d..5db4a41141 100644 --- a/drivers/freetype/freetype/src/autofit/aflatin2.c +++ b/drivers/freetype/src/autofit/aflatin2.c @@ -1,10 +1,15 @@ +/* ATTENTION: This file doesn't compile. It is only here as a reference */ +/* of an alternative latin hinting algorithm that was always */ +/* marked as experimental. */ + + /***************************************************************************/ /* */ /* aflatin2.c */ /* */ -/* Auto-fitter hinting routines for latin script (body). */ +/* Auto-fitter hinting routines for latin writing system (body). */ /* */ -/* Copyright 2003-2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -76,8 +81,9 @@ AF_Scaler scaler = &dummy->root.scaler; - glyph_index = FT_Get_Char_Index( face, - metrics->root.clazz->standard_char ); + glyph_index = FT_Get_Char_Index( + face, + metrics->root.style_class->standard_char ); if ( glyph_index == 0 ) goto Exit; @@ -94,7 +100,7 @@ scaler->render_mode = FT_RENDER_MODE_NORMAL; scaler->flags = 0; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy ); error = af_glyph_hints_reload( hints, &face->glyph->outline ); if ( error ) @@ -409,11 +415,11 @@ blue->flags |= AF_LATIN_BLUE_TOP; /* - * The following flags is used later to adjust the y and x scales + * The following flag is used later to adjust the y and x scales * in order to optimize the pixel grid alignment of the top of small * letters. */ - if ( bb == AF_LATIN_BLUE_SMALL_TOP ) + if ( AF_LATIN_IS_X_HEIGHT_BLUE( bb ) ) blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; FT_TRACE5(( " -> reference = %ld\n" @@ -692,6 +698,22 @@ } + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + FT_LOCAL_DEF( void ) + af_latin2_get_standard_widths( AF_LatinMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -834,8 +856,8 @@ { AF_Point pt = first; AF_Point last = point; - AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); - AF_Flags f1; + FT_UInt f0 = pt->flags & AF_FLAG_CONTROL; + FT_UInt f1; segment->flags &= ~AF_EDGE_ROUND; @@ -843,7 +865,7 @@ for ( ; pt != last; f0 = f1 ) { pt = pt->next; - f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL ); + f1 = pt->flags & AF_FLAG_CONTROL; if ( !f0 && !f1 ) break; @@ -889,9 +911,6 @@ FT_Pos last_v = last->v; - if ( first == last ) - continue; - if ( first_v < last_v ) { p = first->prev; @@ -983,7 +1002,7 @@ #ifdef AF_SORT_SEGMENTS for ( seg1 = segments; seg1 < segment_mid; seg1++ ) { - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + if ( seg1->dir != axis->major_dir ) continue; for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ ) @@ -991,9 +1010,7 @@ /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { - /* the fake segments are introduced to hint the metrics -- */ - /* we must never link them to anything */ - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + if ( seg1->dir != axis->major_dir ) continue; for ( seg2 = segments; seg2 < segment_limit; seg2++ ) @@ -1052,7 +1069,7 @@ { if ( seg2->link != seg1 ) { - seg1->link = 0; + seg1->link = NULL; seg1->serif = seg2->link; } } @@ -1132,7 +1149,7 @@ for ( seg = segments; seg < segment_limit; seg++ ) { - AF_Edge found = 0; + AF_Edge found = NULL; FT_Int ee; @@ -1183,7 +1200,7 @@ /* insert a new edge in the list and */ /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, + error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, 0, memory, &edge ); if ( error ) goto Exit; @@ -1193,9 +1210,10 @@ edge->first = seg; edge->last = seg; - edge->fpos = seg->pos; edge->dir = seg->dir; - edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + edge->fpos = seg->pos; + edge->opos = FT_MulFix( seg->pos, scale ); + edge->pos = edge->opos; seg->edge_next = seg; } else @@ -1358,7 +1376,7 @@ /* Example: the `c' in cour.pfa at size 13 */ if ( edge->serif && edge->link ) - edge->serif = 0; + edge->serif = NULL; } } @@ -1385,7 +1403,7 @@ } - FT_LOCAL_DEF( void ) + static void af_latin2_hints_compute_blue_edges( AF_GlyphHints hints, AF_LatinMetrics metrics ) { @@ -1500,7 +1518,7 @@ FT_Face face = metrics->root.scaler.face; - af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics ); /* * correct x_scale and y_scale if needed, since they may have @@ -1516,9 +1534,7 @@ #if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */ if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) - { metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; - } #endif scaler_flags = hints->scaler_flags; @@ -1555,6 +1571,12 @@ ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; +#ifdef AF_CONFIG_OPTION_USE_WARPER + /* get (global) warper flag */ + if ( !metrics->root.globals->module->warping ) + scaler_flags |= AF_SCALER_FLAG_NO_WARPER; +#endif + hints->scaler_flags = scaler_flags; hints->other_flags = other_flags; @@ -1575,13 +1597,13 @@ static FT_Pos af_latin2_snap_width( AF_Width widths, - FT_Int count, + FT_UInt count, FT_Pos width ) { - int n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - FT_Pos scaled; + FT_UInt n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; for ( n = 0; n < count; n++ ) @@ -1624,8 +1646,8 @@ af_latin2_compute_stem_width( AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, - AF_Edge_Flags base_flags, - AF_Edge_Flags stem_flags ) + FT_UInt base_flags, + FT_UInt stem_flags ) { AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; AF_LatinAxis axis = & metrics->axis[dim]; @@ -1796,10 +1818,9 @@ { FT_Pos dist = stem_edge->opos - base_edge->opos; - FT_Pos fitted_width = af_latin2_compute_stem_width( - hints, dim, dist, - (AF_Edge_Flags)base_edge->flags, - (AF_Edge_Flags)stem_edge->flags ); + FT_Pos fitted_width = af_latin2_compute_stem_width( hints, dim, dist, + base_edge->flags, + stem_edge->flags ); stem_edge->pos = base_edge->pos + fitted_width; @@ -1833,7 +1854,7 @@ /*************************************************************************/ - FT_LOCAL_DEF( void ) + static void af_latin2_hint_edges( AF_GlyphHints hints, AF_Dimension dim ) { @@ -1841,7 +1862,7 @@ AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; AF_Edge edge; - AF_Edge anchor = 0; + AF_Edge anchor = NULL; FT_Int has_serifs = 0; FT_Pos anchor_drift = 0; @@ -1945,10 +1966,9 @@ org_len = edge2->opos - edge->opos; - cur_len = af_latin2_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + cur_len = af_latin2_compute_stem_width( hints, dim, org_len, + edge->flags, + edge2->flags ); if ( cur_len <= 64 ) u_off = d_off = 32; else @@ -2010,10 +2030,9 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_latin2_compute_stem_width( - hints, dim, org_len, - (AF_Edge_Flags)edge->flags, - (AF_Edge_Flags)edge2->flags ); + cur_len = af_latin2_compute_stem_width( hints, dim, org_len, + edge->flags, + edge2->flags ); org_left = org_pos + ( ( org_len - cur_len ) >> 1 ); org_right = org_pos + ( ( org_len + cur_len ) >> 1 ); @@ -2302,13 +2321,16 @@ static FT_Error - af_latin2_hints_apply( AF_GlyphHints hints, + af_latin2_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, FT_Outline* outline, AF_LatinMetrics metrics ) { FT_Error error; int dim; + FT_UNUSED( glyph_index ); + error = af_glyph_hints_reload( hints, outline ); if ( error ) @@ -2316,8 +2338,9 @@ /* analyze glyph outline */ #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || - AF_HINTS_DO_HORIZONTAL( hints ) ) + if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) || + AF_HINTS_DO_HORIZONTAL( hints ) ) #else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) #endif @@ -2340,8 +2363,9 @@ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) ) + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; @@ -2352,7 +2376,7 @@ af_glyph_hints_scale_dim( hints, dim, scale, delta ); continue; } -#endif +#endif /* AF_CONFIG_OPTION_USE_WARPER */ if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) @@ -2379,27 +2403,20 @@ /*************************************************************************/ - static const AF_Script_UniRangeRec af_latin2_uniranges[] = - { - AF_UNIRANGE_REC( 32UL, 127UL ), /* TODO: Add new Unicode ranges here! */ - AF_UNIRANGE_REC( 160UL, 255UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - + AF_DEFINE_WRITING_SYSTEM_CLASS( + af_latin2_writing_system_class, - AF_DEFINE_SCRIPT_CLASS( af_latin2_script_class, - AF_SCRIPT_LATIN2, - af_latin2_uniranges, - 'o', + AF_WRITING_SYSTEM_LATIN2, sizeof ( AF_LatinMetricsRec ), - (AF_Script_InitMetricsFunc) af_latin2_metrics_init, - (AF_Script_ScaleMetricsFunc)af_latin2_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init, + (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale, + (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths, - (AF_Script_InitHintsFunc) af_latin2_hints_init, - (AF_Script_ApplyHintsFunc) af_latin2_hints_apply + (AF_WritingSystem_InitHintsFunc) af_latin2_hints_init, + (AF_WritingSystem_ApplyHintsFunc) af_latin2_hints_apply ) diff --git a/drivers/freetype/src/autofit/aflatin2.h b/drivers/freetype/src/autofit/aflatin2.h new file mode 100644 index 0000000000..f83f704289 --- /dev/null +++ b/drivers/freetype/src/autofit/aflatin2.h @@ -0,0 +1,46 @@ +/* ATTENTION: This file doesn't compile. It is only here as a reference */ +/* of an alternative latin hinting algorithm that was always */ +/* marked as experimental. */ + + +/***************************************************************************/ +/* */ +/* aflatin2.h */ +/* */ +/* Auto-fitter hinting routines for latin writing system */ +/* (specification). */ +/* */ +/* Copyright 2003-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef AFLATIN2_H_ +#define AFLATIN2_H_ + +#include "afhints.h" + + +FT_BEGIN_HEADER + + + /* the `latin' writing system */ + + AF_DECLARE_WRITING_SYSTEM_CLASS( af_latin2_writing_system_class ) + + +/* */ + +FT_END_HEADER + +#endif /* AFLATIN_H_ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afloader.c b/drivers/freetype/src/autofit/afloader.c new file mode 100644 index 0000000000..26bba065bb --- /dev/null +++ b/drivers/freetype/src/autofit/afloader.c @@ -0,0 +1,676 @@ +/***************************************************************************/ +/* */ +/* afloader.c */ +/* */ +/* Auto-fitter glyph loading routines (body). */ +/* */ +/* Copyright 2003-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "afglobal.h" +#include "afloader.h" +#include "afhints.h" +#include "aferrors.h" +#include "afmodule.h" +#include "afpic.h" + +#include FT_INTERNAL_CALC_H + + + /* Initialize glyph loader. */ + + FT_LOCAL_DEF( void ) + af_loader_init( AF_Loader loader, + AF_GlyphHints hints ) + { + FT_ZERO( loader ); + + loader->hints = hints; + } + + + /* Reset glyph loader and compute globals if necessary. */ + + FT_LOCAL_DEF( FT_Error ) + af_loader_reset( AF_Loader loader, + AF_Module module, + FT_Face face ) + { + FT_Error error = FT_Err_Ok; + + + loader->face = face; + loader->globals = (AF_FaceGlobals)face->autohint.data; + + if ( loader->globals == NULL ) + { + error = af_face_globals_new( face, &loader->globals, module ); + if ( !error ) + { + face->autohint.data = + (FT_Pointer)loader->globals; + face->autohint.finalizer = + (FT_Generic_Finalizer)af_face_globals_free; + } + } + + return error; + } + + + /* Finalize glyph loader. */ + + FT_LOCAL_DEF( void ) + af_loader_done( AF_Loader loader ) + { + loader->face = NULL; + loader->globals = NULL; + loader->hints = NULL; + } + + +#define af_intToFixed( i ) \ + ( (FT_Fixed)( (FT_UInt32)(i) << 16 ) ) +#define af_fixedToInt( x ) \ + ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) +#define af_floatToFixed( f ) \ + ( (FT_Fixed)( (f) * 65536.0 + 0.5 ) ) + + + /* Do the main work of `af_loader_load_glyph'. Note that we never */ + /* have to deal with composite glyphs as those get loaded into */ + /* FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. */ + /* In the rare cases where FT_LOAD_NO_RECURSE is set, it implies */ + /* FT_LOAD_NO_SCALE and as such the auto-hinter is never called. */ + + static FT_Error + af_loader_load_g( AF_Loader loader, + AF_Scaler scaler, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + AF_Module module = loader->globals->module; + + FT_Error error; + FT_Face face = loader->face; + AF_StyleMetrics metrics = loader->metrics; + AF_GlyphHints hints = loader->hints; + FT_GlyphSlot slot = face->glyph; + FT_Slot_Internal internal = slot->internal; + FT_GlyphLoader gloader = internal->loader; + FT_Int32 flags; + + + flags = load_flags | FT_LOAD_LINEAR_DESIGN; + error = FT_Load_Glyph( face, glyph_index, flags ); + if ( error ) + goto Exit; + + /* + * Apply stem darkening (emboldening) here before hints are applied to + * the outline. Glyphs are scaled down proportionally to the + * emboldening so that curve points don't fall outside their precomputed + * blue zones. + * + * Any emboldening done by the font driver (e.g., the CFF driver) + * doesn't reach here because the autohinter loads the unprocessed + * glyphs in font units for analysis (functions `af_*_metrics_init_*') + * and then above to prepare it for the rasterizers by itself, + * independently of the font driver. So emboldening must be done here, + * within the autohinter. + * + * All glyphs to be autohinted pass through here one by one. The + * standard widths can therefore change from one glyph to the next, + * depending on what script a glyph is assigned to (each script has its + * own set of standard widths and other metrics). The darkening amount + * must therefore be recomputed for each size and + * `standard_{vertical,horizontal}_width' change. + */ + if ( !module->no_stem_darkening ) + { + AF_FaceGlobals globals = loader->globals; + AF_WritingSystemClass writing_system_class; + + FT_Pos stdVW = 0; + FT_Pos stdHW = 0; + + FT_Bool size_changed = face->size->metrics.x_ppem + != globals->stem_darkening_for_ppem; + + FT_Fixed em_size = af_intToFixed( face->units_per_EM ); + FT_Fixed em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size ); + + FT_Matrix scale_down_matrix = { 0x10000L, 0, 0, 0x10000L }; + + + /* Skip stem darkening for broken fonts. */ + if ( !face->units_per_EM ) + goto After_Emboldening; + + /* + * We depend on the writing system (script analyzers) to supply + * standard widths for the script of the glyph we are looking at. If + * it can't deliver, stem darkening is effectively disabled. + */ + writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[metrics->style_class->writing_system]; + + if ( writing_system_class->style_metrics_getstdw ) + writing_system_class->style_metrics_getstdw( metrics, + &stdHW, + &stdVW ); + else + goto After_Emboldening; + + + if ( size_changed || + ( stdVW > 0 && stdVW != globals->standard_vertical_width ) ) + { + FT_Fixed darken_by_font_units_x, darken_x; + + + darken_by_font_units_x = + af_intToFixed( af_loader_compute_darkening( loader, + face, + stdVW ) ); + darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x, + face->size->metrics.x_scale ), + em_ratio ); + + globals->standard_vertical_width = stdVW; + globals->stem_darkening_for_ppem = face->size->metrics.x_ppem; + globals->darken_x = af_fixedToInt( darken_x ); + } + + if ( size_changed || + ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) ) + { + FT_Fixed darken_by_font_units_y, darken_y; + + + darken_by_font_units_y = + af_intToFixed( af_loader_compute_darkening( loader, + face, + stdHW ) ); + darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y, + face->size->metrics.y_scale ), + em_ratio ); + + globals->standard_horizontal_width = stdHW; + globals->stem_darkening_for_ppem = face->size->metrics.x_ppem; + globals->darken_y = af_fixedToInt( darken_y ); + + /* + * Scale outlines down on the Y-axis to keep them inside their blue + * zones. The stronger the emboldening, the stronger the + * downscaling (plus heuristical padding to prevent outlines still + * falling out their zones due to rounding). + * + * Reason: `FT_Outline_Embolden' works by shifting the rightmost + * points of stems farther to the right, and topmost points farther + * up. This positions points on the Y-axis outside their + * pre-computed blue zones and leads to distortion when applying the + * hints in the code further below. Code outside this emboldening + * block doesn't know we are presenting it with modified outlines + * the analyzer didn't see! + * + * An unfortunate side effect of downscaling is that the emboldening + * effect is slightly decreased. The loss becomes more pronounced + * versus the CFF driver at smaller sizes, e.g., at 9ppem and below. + */ + globals->scale_down_factor = + FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ), + em_size ); + } + + FT_Outline_EmboldenXY( &slot->outline, + globals->darken_x, + globals->darken_y ); + + scale_down_matrix.yy = globals->scale_down_factor; + FT_Outline_Transform( &slot->outline, &scale_down_matrix ); + } + + After_Emboldening: + loader->transformed = internal->glyph_transformed; + if ( loader->transformed ) + { + FT_Matrix inverse; + + + loader->trans_matrix = internal->glyph_matrix; + loader->trans_delta = internal->glyph_delta; + + inverse = loader->trans_matrix; + if ( !FT_Matrix_Invert( &inverse ) ) + FT_Vector_Transform( &loader->trans_delta, &inverse ); + } + + switch ( slot->format ) + { + case FT_GLYPH_FORMAT_OUTLINE: + /* translate the loaded glyph when an internal transform is needed */ + if ( loader->transformed ) + FT_Outline_Translate( &slot->outline, + loader->trans_delta.x, + loader->trans_delta.y ); + + /* compute original horizontal phantom points (and ignore */ + /* vertical ones) */ + loader->pp1.x = hints->x_delta; + loader->pp1.y = hints->y_delta; + loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, + hints->x_scale ) + hints->x_delta; + loader->pp2.y = hints->y_delta; + + /* be sure to check for spacing glyphs */ + if ( slot->outline.n_points == 0 ) + goto Hint_Metrics; + + /* now load the slot image into the auto-outline and run the */ + /* automatic hinting process */ + { +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = loader->globals; +#endif + AF_StyleClass style_class = metrics->style_class; + AF_WritingSystemClass writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; + + + if ( writing_system_class->style_hints_apply ) + writing_system_class->style_hints_apply( glyph_index, + hints, + &gloader->base.outline, + metrics ); + } + + /* we now need to adjust the metrics according to the change in */ + /* width/positioning that occurred during the hinting process */ + if ( scaler->render_mode != FT_RENDER_MODE_LIGHT ) + { + FT_Pos old_rsb, old_lsb, new_lsb; + FT_Pos pp1x_uh, pp2x_uh; + AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; + AF_Edge edge1 = axis->edges; /* leftmost edge */ + AF_Edge edge2 = edge1 + + axis->num_edges - 1; /* rightmost edge */ + + + if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) + { + old_rsb = loader->pp2.x - edge2->opos; + old_lsb = edge1->opos; + new_lsb = edge1->pos; + + /* remember unhinted values to later account */ + /* for rounding errors */ + + pp1x_uh = new_lsb - old_lsb; + pp2x_uh = edge2->pos + old_rsb; + + /* prefer too much space over too little space */ + /* for very small sizes */ + + if ( old_lsb < 24 ) + pp1x_uh -= 8; + + if ( old_rsb < 24 ) + pp2x_uh += 8; + + loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); + loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); + + if ( loader->pp1.x >= new_lsb && old_lsb > 0 ) + loader->pp1.x -= 64; + + if ( loader->pp2.x <= edge2->pos && old_rsb > 0 ) + loader->pp2.x += 64; + + slot->lsb_delta = loader->pp1.x - pp1x_uh; + slot->rsb_delta = loader->pp2.x - pp2x_uh; + } + else + { + FT_Pos pp1x = loader->pp1.x; + FT_Pos pp2x = loader->pp2.x; + + + loader->pp1.x = FT_PIX_ROUND( pp1x ); + loader->pp2.x = FT_PIX_ROUND( pp2x ); + + slot->lsb_delta = loader->pp1.x - pp1x; + slot->rsb_delta = loader->pp2.x - pp2x; + } + } + else + { + FT_Pos pp1x = loader->pp1.x; + FT_Pos pp2x = loader->pp2.x; + + + loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); + loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); + + slot->lsb_delta = loader->pp1.x - pp1x; + slot->rsb_delta = loader->pp2.x - pp2x; + } + + break; + + default: + /* we don't support other formats (yet?) */ + error = FT_THROW( Unimplemented_Feature ); + } + + Hint_Metrics: + { + FT_BBox bbox; + FT_Vector vvector; + + + vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX; + vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY; + vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale ); + vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale ); + + /* transform the hinted outline if needed */ + if ( loader->transformed ) + { + FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); + FT_Vector_Transform( &vvector, &loader->trans_matrix ); + } +#if 1 + /* we must translate our final outline by -pp1.x and compute */ + /* the new metrics */ + if ( loader->pp1.x ) + FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); +#endif + FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); + + bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); + bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); + bbox.xMax = FT_PIX_CEIL( bbox.xMax ); + bbox.yMax = FT_PIX_CEIL( bbox.yMax ); + + slot->metrics.width = bbox.xMax - bbox.xMin; + slot->metrics.height = bbox.yMax - bbox.yMin; + slot->metrics.horiBearingX = bbox.xMin; + slot->metrics.horiBearingY = bbox.yMax; + + slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x ); + slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y ); + + /* for mono-width fonts (like Andale, Courier, etc.) we need */ + /* to keep the original rounded advance width; ditto for */ + /* digits if all have the same advance width */ +#if 0 + if ( !FT_IS_FIXED_WIDTH( slot->face ) ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + else + slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, + x_scale ); +#else + if ( scaler->render_mode != FT_RENDER_MODE_LIGHT && + ( FT_IS_FIXED_WIDTH( slot->face ) || + ( af_face_globals_is_digit( loader->globals, glyph_index ) && + metrics->digits_have_same_width ) ) ) + { + slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, + metrics->scaler.x_scale ); + + /* Set delta values to 0. Otherwise code that uses them is */ + /* going to ruin the fixed advance width. */ + slot->lsb_delta = 0; + slot->rsb_delta = 0; + } + else + { + /* non-spacing glyphs must stay as-is */ + if ( slot->metrics.horiAdvance ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + } +#endif + + slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, + metrics->scaler.y_scale ); + + slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); + slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); + +#if 0 + /* reassign all outline fields except flags to protect them */ + slot->outline.n_contours = internal->loader->base.outline.n_contours; + slot->outline.n_points = internal->loader->base.outline.n_points; + slot->outline.points = internal->loader->base.outline.points; + slot->outline.tags = internal->loader->base.outline.tags; + slot->outline.contours = internal->loader->base.outline.contours; +#endif + + slot->format = FT_GLYPH_FORMAT_OUTLINE; + } + + Exit: + return error; + } + + + /* Load a glyph. */ + + FT_LOCAL_DEF( FT_Error ) + af_loader_load_glyph( AF_Loader loader, + AF_Module module, + FT_Face face, + FT_UInt gindex, + FT_Int32 load_flags ) + { + FT_Error error; + FT_Size size = face->size; + AF_ScalerRec scaler; + + + if ( !size ) + return FT_THROW( Invalid_Size_Handle ); + + FT_ZERO( &scaler ); + + scaler.face = face; + scaler.x_scale = size->metrics.x_scale; + scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ + scaler.y_scale = size->metrics.y_scale; + scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ + + scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); + scaler.flags = 0; /* XXX: fix this */ + + error = af_loader_reset( loader, module, face ); + if ( !error ) + { + AF_StyleMetrics metrics; + FT_UInt options = AF_STYLE_NONE_DFLT; + + +#ifdef FT_OPTION_AUTOFIT2 + /* XXX: undocumented hook to activate the latin2 writing system */ + if ( load_flags & ( 1UL << 20 ) ) + options = AF_STYLE_LTN2_DFLT; +#endif + + error = af_face_globals_get_metrics( loader->globals, gindex, + options, &metrics ); + if ( !error ) + { +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = loader->globals; +#endif + AF_StyleClass style_class = metrics->style_class; + AF_WritingSystemClass writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; + + + loader->metrics = metrics; + + if ( writing_system_class->style_metrics_scale ) + writing_system_class->style_metrics_scale( metrics, &scaler ); + else + metrics->scaler = scaler; + + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; + load_flags &= ~FT_LOAD_RENDER; + + if ( writing_system_class->style_hints_init ) + { + error = writing_system_class->style_hints_init( loader->hints, + metrics ); + if ( error ) + goto Exit; + } + + error = af_loader_load_g( loader, &scaler, gindex, load_flags ); + } + } + Exit: + return error; + } + + + /* + * Compute amount of font units the face should be emboldened by, in + * analogy to the CFF driver's `cf2_computeDarkening' function. See there + * for details of the algorithm. + * + * XXX: Currently a crude adaption of the original algorithm. Do better? + */ + FT_LOCAL_DEF( FT_Int32 ) + af_loader_compute_darkening( AF_Loader loader, + FT_Face face, + FT_Pos standard_width ) + { + AF_Module module = loader->globals->module; + + FT_UShort units_per_EM; + FT_Fixed ppem, em_ratio; + FT_Fixed stem_width, stem_width_per_1000, scaled_stem, darken_amount; + FT_Int log_base_2; + FT_Int x1, y1, x2, y2, x3, y3, x4, y4; + + + ppem = FT_MAX( af_intToFixed( 4 ), + af_intToFixed( face->size->metrics.x_ppem ) ); + units_per_EM = face->units_per_EM; + + em_ratio = FT_DivFix( af_intToFixed( 1000 ), + af_intToFixed ( units_per_EM ) ); + if ( em_ratio < af_floatToFixed( .01 ) ) + { + /* If something goes wrong, don't embolden. */ + return 0; + } + + x1 = module->darken_params[0]; + y1 = module->darken_params[1]; + x2 = module->darken_params[2]; + y2 = module->darken_params[3]; + x3 = module->darken_params[4]; + y3 = module->darken_params[5]; + x4 = module->darken_params[6]; + y4 = module->darken_params[7]; + + if ( standard_width <= 0 ) + { + stem_width = af_intToFixed( 75 ); /* taken from cf2font.c */ + stem_width_per_1000 = stem_width; + } + else + { + stem_width = af_intToFixed( standard_width ); + stem_width_per_1000 = FT_MulFix( stem_width, em_ratio ); + } + + log_base_2 = FT_MSB( (FT_UInt32)stem_width_per_1000 ) + + FT_MSB( (FT_UInt32)ppem ); + + if ( log_base_2 >= 46 ) + { + /* possible overflow */ + scaled_stem = af_intToFixed( x4 ); + } + else + scaled_stem = FT_MulFix( stem_width_per_1000, ppem ); + + /* now apply the darkening parameters */ + if ( scaled_stem < af_intToFixed( x1 ) ) + darken_amount = FT_DivFix( af_intToFixed( y1 ), ppem ); + + else if ( scaled_stem < af_intToFixed( x2 ) ) + { + FT_Int xdelta = x2 - x1; + FT_Int ydelta = y2 - y1; + FT_Int x = stem_width_per_1000 - + FT_DivFix( af_intToFixed( x1 ), ppem ); + + + if ( !xdelta ) + goto Try_x3; + + darken_amount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( af_intToFixed( y1 ), ppem ); + } + + else if ( scaled_stem < af_intToFixed( x3 ) ) + { + Try_x3: + { + FT_Int xdelta = x3 - x2; + FT_Int ydelta = y3 - y2; + FT_Int x = stem_width_per_1000 - + FT_DivFix( af_intToFixed( x2 ), ppem ); + + + if ( !xdelta ) + goto Try_x4; + + darken_amount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( af_intToFixed( y2 ), ppem ); + } + } + + else if ( scaled_stem < af_intToFixed( x4 ) ) + { + Try_x4: + { + FT_Int xdelta = x4 - x3; + FT_Int ydelta = y4 - y3; + FT_Int x = stem_width_per_1000 - + FT_DivFix( af_intToFixed( x3 ), ppem ); + + + if ( !xdelta ) + goto Use_y4; + + darken_amount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( af_intToFixed( y3 ), ppem ); + } + } + + else + { + Use_y4: + darken_amount = FT_DivFix( af_intToFixed( y4 ), ppem ); + } + + /* Convert darken_amount from per 1000 em to true character space. */ + return af_fixedToInt( FT_DivFix( darken_amount, em_ratio ) ); + } + + +/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afloader.h b/drivers/freetype/src/autofit/afloader.h index 1f34d17cce..0062eb9b07 100644 --- a/drivers/freetype/freetype/src/autofit/afloader.h +++ b/drivers/freetype/src/autofit/afloader.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter glyph loading routines (specification). */ /* */ -/* Copyright 2003-2005, 2011-2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,17 +16,16 @@ /***************************************************************************/ -#ifndef __AFLOADER_H__ -#define __AFLOADER_H__ +#ifndef AFLOADER_H_ +#define AFLOADER_H_ #include "afhints.h" +#include "afmodule.h" #include "afglobal.h" FT_BEGIN_HEADER - typedef struct AF_ModuleRec_* AF_Module; - /* * The autofitter module's (global) data structure to communicate with * actual fonts. If necessary, `local' data like the current face, the @@ -42,9 +41,8 @@ FT_BEGIN_HEADER AF_FaceGlobals globals; /* current glyph data */ - FT_GlyphLoader gloader; - AF_GlyphHintsRec hints; - AF_ScriptMetrics metrics; + AF_GlyphHints hints; + AF_StyleMetrics metrics; FT_Bool transformed; FT_Matrix trans_matrix; FT_Vector trans_delta; @@ -55,31 +53,39 @@ FT_BEGIN_HEADER } AF_LoaderRec, *AF_Loader; - FT_LOCAL( FT_Error ) - af_loader_init( AF_Module module ); + FT_LOCAL( void ) + af_loader_init( AF_Loader loader, + AF_GlyphHints hints ); FT_LOCAL( FT_Error ) - af_loader_reset( AF_Module module, + af_loader_reset( AF_Loader loader, + AF_Module module, FT_Face face ); FT_LOCAL( void ) - af_loader_done( AF_Module module ); + af_loader_done( AF_Loader loader ); FT_LOCAL( FT_Error ) - af_loader_load_glyph( AF_Module module, + af_loader_load_glyph( AF_Loader loader, + AF_Module module, FT_Face face, FT_UInt gindex, FT_Int32 load_flags ); + FT_LOCAL_DEF( FT_Int32 ) + af_loader_compute_darkening( AF_Loader loader, + FT_Face face, + FT_Pos standard_width ); + /* */ FT_END_HEADER -#endif /* __AFLOADER_H__ */ +#endif /* AFLOADER_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afmodule.c b/drivers/freetype/src/autofit/afmodule.c new file mode 100644 index 0000000000..4127382c00 --- /dev/null +++ b/drivers/freetype/src/autofit/afmodule.c @@ -0,0 +1,486 @@ +/***************************************************************************/ +/* */ +/* afmodule.c */ +/* */ +/* Auto-fitter module implementation (body). */ +/* */ +/* Copyright 2003-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "afglobal.h" +#include "afmodule.h" +#include "afloader.h" +#include "aferrors.h" +#include "afpic.h" + +#ifdef FT_DEBUG_AUTOFIT + +#ifndef FT_MAKE_OPTION_SINGLE_OBJECT + +#ifdef __cplusplus + extern "C" { +#endif + extern void + af_glyph_hints_dump_segments( AF_GlyphHints hints, + FT_Bool to_stdout ); + extern void + af_glyph_hints_dump_points( AF_GlyphHints hints, + FT_Bool to_stdout ); + extern void + af_glyph_hints_dump_edges( AF_GlyphHints hints, + FT_Bool to_stdout ); +#ifdef __cplusplus + } +#endif + +#endif + + int _af_debug_disable_horz_hints; + int _af_debug_disable_vert_hints; + int _af_debug_disable_blue_hints; + + /* we use a global object instead of a local one for debugging */ + AF_GlyphHintsRec _af_debug_hints_rec[1]; + + void* _af_debug_hints = _af_debug_hints_rec; +#endif + +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_AUTOHINTER_H +#include FT_SERVICE_PROPERTIES_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_afmodule + + + static FT_Error + af_property_get_face_globals( FT_Face face, + AF_FaceGlobals* aglobals, + AF_Module module ) + { + FT_Error error = FT_Err_Ok; + AF_FaceGlobals globals; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + globals = (AF_FaceGlobals)face->autohint.data; + if ( !globals ) + { + /* trigger computation of the global style data */ + /* in case it hasn't been done yet */ + error = af_face_globals_new( face, &globals, module ); + if ( !error ) + { + face->autohint.data = + (FT_Pointer)globals; + face->autohint.finalizer = + (FT_Generic_Finalizer)af_face_globals_free; + } + } + + if ( !error ) + *aglobals = globals; + + return error; + } + + + static FT_Error + af_property_set( FT_Module ft_module, + const char* property_name, + const void* value ) + { + FT_Error error = FT_Err_Ok; + AF_Module module = (AF_Module)ft_module; + + + if ( !ft_strcmp( property_name, "fallback-script" ) ) + { + FT_UInt* fallback_script = (FT_UInt*)value; + + FT_UInt ss; + + + /* We translate the fallback script to a fallback style that uses */ + /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its */ + /* coverage value. */ + for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + { + AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; + + + if ( (FT_UInt)style_class->script == *fallback_script && + style_class->coverage == AF_COVERAGE_DEFAULT ) + { + module->fallback_style = ss; + break; + } + } + + if ( !AF_STYLE_CLASSES_GET[ss] ) + { + FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n", + fallback_script, property_name )); + return FT_THROW( Invalid_Argument ); + } + + return error; + } + else if ( !ft_strcmp( property_name, "default-script" ) ) + { + FT_UInt* default_script = (FT_UInt*)value; + + + module->default_script = *default_script; + + return error; + } + else if ( !ft_strcmp( property_name, "increase-x-height" ) ) + { + FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; + AF_FaceGlobals globals; + + + error = af_property_get_face_globals( prop->face, &globals, module ); + if ( !error ) + globals->increase_x_height = prop->limit; + + return error; + } +#ifdef AF_CONFIG_OPTION_USE_WARPER + else if ( !ft_strcmp( property_name, "warping" ) ) + { + FT_Bool* warping = (FT_Bool*)value; + + + module->warping = *warping; + + return error; + } +#endif /* AF_CONFIG_OPTION_USE_WARPER */ + else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = (FT_Int*)value; + + FT_Int x1 = darken_params[0]; + FT_Int y1 = darken_params[1]; + FT_Int x2 = darken_params[2]; + FT_Int y2 = darken_params[3]; + FT_Int x3 = darken_params[4]; + FT_Int y3 = darken_params[5]; + FT_Int x4 = darken_params[6]; + FT_Int y4 = darken_params[7]; + + + if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || + y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || + x1 > x2 || x2 > x3 || x3 > x4 || + y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) + return FT_THROW( Invalid_Argument ); + + module->darken_params[0] = x1; + module->darken_params[1] = y1; + module->darken_params[2] = x2; + module->darken_params[3] = y2; + module->darken_params[4] = x3; + module->darken_params[5] = y3; + module->darken_params[6] = x4; + module->darken_params[7] = y4; + + return error; + } + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { + FT_Bool* no_stem_darkening = (FT_Bool*)value; + + + module->no_stem_darkening = *no_stem_darkening; + + return error; + } + + FT_TRACE0(( "af_property_set: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + static FT_Error + af_property_get( FT_Module ft_module, + const char* property_name, + void* value ) + { + FT_Error error = FT_Err_Ok; + AF_Module module = (AF_Module)ft_module; + FT_UInt fallback_style = module->fallback_style; + FT_UInt default_script = module->default_script; +#ifdef AF_CONFIG_OPTION_USE_WARPER + FT_Bool warping = module->warping; +#endif + + + if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) + { + FT_Prop_GlyphToScriptMap* prop = (FT_Prop_GlyphToScriptMap*)value; + AF_FaceGlobals globals; + + + error = af_property_get_face_globals( prop->face, &globals, module ); + if ( !error ) + prop->map = globals->glyph_styles; + + return error; + } + else if ( !ft_strcmp( property_name, "fallback-script" ) ) + { + FT_UInt* val = (FT_UInt*)value; + + AF_StyleClass style_class = AF_STYLE_CLASSES_GET[fallback_style]; + + + *val = style_class->script; + + return error; + } + else if ( !ft_strcmp( property_name, "default-script" ) ) + { + FT_UInt* val = (FT_UInt*)value; + + + *val = default_script; + + return error; + } + else if ( !ft_strcmp( property_name, "increase-x-height" ) ) + { + FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; + AF_FaceGlobals globals; + + + error = af_property_get_face_globals( prop->face, &globals, module ); + if ( !error ) + prop->limit = globals->increase_x_height; + + return error; + } +#ifdef AF_CONFIG_OPTION_USE_WARPER + else if ( !ft_strcmp( property_name, "warping" ) ) + { + FT_Bool* val = (FT_Bool*)value; + + + *val = warping; + + return error; + } +#endif /* AF_CONFIG_OPTION_USE_WARPER */ + else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = module->darken_params; + FT_Int* val = (FT_Int*)value; + + + val[0] = darken_params[0]; + val[1] = darken_params[1]; + val[2] = darken_params[2]; + val[3] = darken_params[3]; + val[4] = darken_params[4]; + val[5] = darken_params[5]; + val[6] = darken_params[6]; + val[7] = darken_params[7]; + + return error; + } + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { + FT_Bool no_stem_darkening = module->no_stem_darkening; + FT_Bool* val = (FT_Bool*)value; + + + *val = no_stem_darkening; + + return error; + } + + FT_TRACE0(( "af_property_get: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + FT_DEFINE_SERVICE_PROPERTIESREC( + af_service_properties, + (FT_Properties_SetFunc)af_property_set, /* set_property */ + (FT_Properties_GetFunc)af_property_get ) /* get_property */ + + + FT_DEFINE_SERVICEDESCREC1( + af_services, + FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET ) + + + FT_CALLBACK_DEF( FT_Module_Interface ) + af_get_interface( FT_Module module, + const char* module_interface ) + { + /* AF_SERVICES_GET dereferences `library' in PIC mode */ +#ifdef FT_CONFIG_OPTION_PIC + FT_Library library; + + + if ( !module ) + return NULL; + library = module->library; + if ( !library ) + return NULL; +#else + FT_UNUSED( module ); +#endif + + return ft_service_list_lookup( AF_SERVICES_GET, module_interface ); + } + + + FT_CALLBACK_DEF( FT_Error ) + af_autofitter_init( FT_Module ft_module ) /* AF_Module */ + { + AF_Module module = (AF_Module)ft_module; + + + module->fallback_style = AF_STYLE_FALLBACK; + module->default_script = AF_SCRIPT_DEFAULT; +#ifdef AF_CONFIG_OPTION_USE_WARPER + module->warping = 0; +#endif + module->no_stem_darkening = TRUE; + + module->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + module->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; + module->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2; + module->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2; + module->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3; + module->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3; + module->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4; + module->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + af_autofitter_done( FT_Module ft_module ) /* AF_Module */ + { + FT_UNUSED( ft_module ); + +#ifdef FT_DEBUG_AUTOFIT + if ( _af_debug_hints_rec->memory ) + af_glyph_hints_done( _af_debug_hints_rec ); +#endif + } + + + FT_CALLBACK_DEF( FT_Error ) + af_autofitter_load_glyph( AF_Module module, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory = module->root.library->memory; + +#ifdef FT_DEBUG_AUTOFIT + + /* in debug mode, we use a global object that survives this routine */ + + AF_GlyphHints hints = _af_debug_hints_rec; + AF_LoaderRec loader[1]; + + FT_UNUSED( size ); + + + if ( hints->memory ) + af_glyph_hints_done( hints ); + + af_glyph_hints_init( hints, memory ); + af_loader_init( loader, hints ); + + error = af_loader_load_glyph( loader, module, slot->face, + glyph_index, load_flags ); + + af_glyph_hints_dump_points( hints, 0 ); + af_glyph_hints_dump_segments( hints, 0 ); + af_glyph_hints_dump_edges( hints, 0 ); + + af_loader_done( loader ); + + return error; + +#else /* !FT_DEBUG_AUTOFIT */ + + AF_GlyphHintsRec hints[1]; + AF_LoaderRec loader[1]; + + FT_UNUSED( size ); + + + af_glyph_hints_init( hints, memory ); + af_loader_init( loader, hints ); + + error = af_loader_load_glyph( loader, module, slot->face, + glyph_index, load_flags ); + + af_loader_done( loader ); + af_glyph_hints_done( hints ); + + return error; + +#endif /* !FT_DEBUG_AUTOFIT */ + } + + + FT_DEFINE_AUTOHINTER_INTERFACE( + af_autofitter_interface, + NULL, /* reset_face */ + NULL, /* get_global_hints */ + NULL, /* done_global_hints */ + (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph ) /* load_glyph */ + + + FT_DEFINE_MODULE( + autofit_module_class, + + FT_MODULE_HINTER, + sizeof ( AF_ModuleRec ), + + "autofitter", + 0x10000L, /* version 1.0 of the autofitter */ + 0x20000L, /* requires FreeType 2.0 or above */ + + (const void*)&AF_INTERFACE_GET, + + (FT_Module_Constructor)af_autofitter_init, + (FT_Module_Destructor) af_autofitter_done, + (FT_Module_Requester) af_get_interface ) + + +/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afmodule.h b/drivers/freetype/src/autofit/afmodule.h index c4e8f8f66a..e65db5f5cb 100644 --- a/drivers/freetype/freetype/src/autofit/afmodule.h +++ b/drivers/freetype/src/autofit/afmodule.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter module implementation (specification). */ /* */ -/* Copyright 2003, 2004, 2005 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,43 +16,43 @@ /***************************************************************************/ -#ifndef __AFMODULE_H__ -#define __AFMODULE_H__ +#ifndef AFMODULE_H_ +#define AFMODULE_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_MODULE_H -#include "afloader.h" - FT_BEGIN_HEADER /* - * This is the `extended' FT_Module structure which holds the - * autofitter's global data. Right before hinting a glyph, the data - * specific to the glyph's face (blue zones, stem widths, etc.) are - * loaded into `loader' (see function `af_loader_reset'). + * This is the `extended' FT_Module structure that holds the + * autofitter's global data. */ typedef struct AF_ModuleRec_ { FT_ModuleRec root; - FT_UInt fallback_script; - - AF_LoaderRec loader[1]; + FT_UInt fallback_style; + FT_UInt default_script; +#ifdef AF_CONFIG_OPTION_USE_WARPER + FT_Bool warping; +#endif + FT_Bool no_stem_darkening; + FT_Int darken_params[8]; - } AF_ModuleRec; + } AF_ModuleRec, *AF_Module; -FT_DECLARE_MODULE(autofit_module_class) +FT_DECLARE_MODULE( autofit_module_class ) FT_END_HEADER -#endif /* __AFMODULE_H__ */ +#endif /* AFMODULE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/autofit/afpic.c b/drivers/freetype/src/autofit/afpic.c index 45e1448c08..3cbd9168e3 100644 --- a/drivers/freetype/freetype/src/autofit/afpic.c +++ b/drivers/freetype/src/autofit/afpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for autofit module. */ /* */ -/* Copyright 2009-2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,7 @@ #include FT_FREETYPE_H #include FT_INTERNAL_OBJECTS_H #include "afpic.h" +#include "afglobal.h" #include "aferrors.h" @@ -42,14 +43,11 @@ FT_AutoHinter_InterfaceRec* clazz ); - /* forward declaration of PIC init functions from script classes */ -#include "aflatin.h" -#ifdef FT_OPTION_AUTOFIT2 -#include "aflatin2.h" -#endif -#include "afcjk.h" -#include "afdummy.h" -#include "afindic.h" + /* forward declaration of PIC init functions from writing system classes */ +#undef WRITING_SYSTEM +#define WRITING_SYSTEM( ws, WS ) /* empty */ + +#include "afwrtsys.h" void @@ -100,27 +98,44 @@ FT_Init_Class_af_service_properties( &container->af_service_properties ); - for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) - { + for ( ss = 0; ss < AF_WRITING_SYSTEM_MAX; ss++ ) + container->af_writing_system_classes[ss] = + &container->af_writing_system_classes_rec[ss]; + container->af_writing_system_classes[AF_WRITING_SYSTEM_MAX] = NULL; + + for ( ss = 0; ss < AF_SCRIPT_MAX; ss++ ) container->af_script_classes[ss] = &container->af_script_classes_rec[ss]; - } - container->af_script_classes[AF_SCRIPT_CLASSES_COUNT - 1] = NULL; + container->af_script_classes[AF_SCRIPT_MAX] = NULL; + + for ( ss = 0; ss < AF_STYLE_MAX; ss++ ) + container->af_style_classes[ss] = + &container->af_style_classes_rec[ss]; + container->af_style_classes[AF_STYLE_MAX] = NULL; + +#undef WRITING_SYSTEM +#define WRITING_SYSTEM( ws, WS ) \ + FT_Init_Class_af_ ## ws ## _writing_system_class( \ + &container->af_writing_system_classes_rec[ss++] ); + + ss = 0; +#include "afwrtsys.h" + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, sss ) \ + FT_Init_Class_af_ ## s ## _script_class( \ + &container->af_script_classes_rec[ss++] ); + + ss = 0; +#include "afscript.h" + +#undef STYLE +#define STYLE( s, S, d, ws, sc, bss, c ) \ + FT_Init_Class_af_ ## s ## _style_class( \ + &container->af_style_classes_rec[ss++] ); - /* add call to initialization function when you add new scripts */ ss = 0; - FT_Init_Class_af_dummy_script_class( - &container->af_script_classes_rec[ss++] ); -#ifdef FT_OPTION_AUTOFIT2 - FT_Init_Class_af_latin2_script_class( - &container->af_script_classes_rec[ss++] ); -#endif - FT_Init_Class_af_latin_script_class( - &container->af_script_classes_rec[ss++] ); - FT_Init_Class_af_cjk_script_class( - &container->af_script_classes_rec[ss++] ); - FT_Init_Class_af_indic_script_class( - &container->af_script_classes_rec[ss++] ); +#include "afstyles.h" FT_Init_Class_af_autofitter_interface( library, &container->af_autofitter_interface ); diff --git a/drivers/freetype/freetype/src/autofit/afpic.h b/drivers/freetype/src/autofit/afpic.h index 0acf803894..98a45a26ba 100644 --- a/drivers/freetype/freetype/src/autofit/afpic.h +++ b/drivers/freetype/src/autofit/afpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for autofit module. */ /* */ -/* Copyright 2009, 2011-2012 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,22 +16,22 @@ /***************************************************************************/ -#ifndef __AFPIC_H__ -#define __AFPIC_H__ +#ifndef AFPIC_H_ +#define AFPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H #ifndef FT_CONFIG_OPTION_PIC -#define AF_SERVICES_GET af_services -#define AF_SERVICE_PROPERTIES_GET af_service_properties +#define AF_SERVICES_GET af_services +#define AF_SERVICE_PROPERTIES_GET af_service_properties -#define AF_SCRIPT_CLASSES_GET af_script_classes -#define AF_INTERFACE_GET af_autofitter_interface +#define AF_WRITING_SYSTEM_CLASSES_GET af_writing_system_classes +#define AF_SCRIPT_CLASSES_GET af_script_classes +#define AF_STYLE_CLASSES_GET af_style_classes +#define AF_INTERFACE_GET af_autofitter_interface #else /* FT_CONFIG_OPTION_PIC */ @@ -40,24 +40,29 @@ FT_BEGIN_HEADER #include "aftypes.h" - /* increase these when you add new scripts, */ - /* and update autofit_module_class_pic_init */ -#ifdef FT_OPTION_AUTOFIT2 -#define AF_SCRIPT_CLASSES_COUNT 6 -#else -#define AF_SCRIPT_CLASSES_COUNT 5 -#endif - -#define AF_SCRIPT_CLASSES_REC_COUNT ( AF_SCRIPT_CLASSES_COUNT - 1 ) +FT_BEGIN_HEADER typedef struct AFModulePIC_ { FT_ServiceDescRec* af_services; FT_Service_PropertiesRec af_service_properties; - AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT]; - AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT]; + AF_WritingSystemClass af_writing_system_classes + [AF_WRITING_SYSTEM_MAX + 1]; + AF_WritingSystemClassRec af_writing_system_classes_rec + [AF_WRITING_SYSTEM_MAX]; + + AF_ScriptClass af_script_classes + [AF_SCRIPT_MAX + 1]; + AF_ScriptClassRec af_script_classes_rec + [AF_SCRIPT_MAX]; + + AF_StyleClass af_style_classes + [AF_STYLE_MAX + 1]; + AF_StyleClassRec af_style_classes_rec + [AF_STYLE_MAX]; + FT_AutoHinter_InterfaceRec af_autofitter_interface; } AFModulePIC; @@ -71,8 +76,12 @@ FT_BEGIN_HEADER #define AF_SERVICE_PROPERTIES_GET \ ( GET_PIC( library )->af_service_properties ) +#define AF_WRITING_SYSTEM_CLASSES_GET \ + ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_writing_system_classes ) #define AF_SCRIPT_CLASSES_GET \ ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_script_classes ) +#define AF_STYLE_CLASSES_GET \ + ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_style_classes ) #define AF_INTERFACE_GET \ ( GET_PIC( library )->af_autofitter_interface ) @@ -84,13 +93,13 @@ FT_BEGIN_HEADER FT_Error autofit_module_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __AFPIC_H__ */ +#endif /* AFPIC_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afranges.c b/drivers/freetype/src/autofit/afranges.c new file mode 100644 index 0000000000..732f3d1629 --- /dev/null +++ b/drivers/freetype/src/autofit/afranges.c @@ -0,0 +1,714 @@ +/***************************************************************************/ +/* */ +/* afranges.c */ +/* */ +/* Auto-fitter Unicode script ranges (body). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "afranges.h" + + /* + * The algorithm for assigning properties and styles to the `glyph_styles' + * array is as follows (cf. the implementation in + * `af_face_globals_compute_style_coverage'). + * + * Walk over all scripts (as listed in `afscript.h'). + * + * For a given script, walk over all styles (as listed in `afstyles.h'). + * The order of styles is important and should be as follows. + * + * - First come styles based on OpenType features (small caps, for + * example). Since features rely on glyph indices, thus completely + * bypassing character codes, no properties are assigned. + * + * - Next comes the default style, using the character ranges as defined + * below. This also assigns properties. + * + * Note that there also exist fallback scripts, mainly covering + * superscript and subscript glyphs of a script that are not present as + * OpenType features. Fallback scripts are defined below, also + * assigning properties; they are applied after the corresponding + * script. + * + */ + + + /* XXX Check base character ranges again: */ + /* Right now, they are quickly derived by visual inspection. */ + /* I can imagine that fine-tuning is necessary. */ + + /* for the auto-hinter, a `non-base character' is something that should */ + /* not be affected by blue zones, regardless of whether this is a */ + /* spacing or no-spacing glyph */ + + /* the `ta_xxxx_nonbase_uniranges' ranges must be strict subsets */ + /* of the corresponding `ta_xxxx_uniranges' ranges */ + + + const AF_Script_UniRangeRec af_arab_uniranges[] = + { + AF_UNIRANGE_REC( 0x0600, 0x06FF ), /* Arabic */ + AF_UNIRANGE_REC( 0x0750, 0x07FF ), /* Arabic Supplement */ + AF_UNIRANGE_REC( 0x08A0, 0x08FF ), /* Arabic Extended-A */ + AF_UNIRANGE_REC( 0xFB50, 0xFDFF ), /* Arabic Presentation Forms-A */ + AF_UNIRANGE_REC( 0xFE70, 0xFEFF ), /* Arabic Presentation Forms-B */ + AF_UNIRANGE_REC( 0x1EE00, 0x1EEFF ), /* Arabic Mathematical Alphabetic Symbols */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_arab_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0600, 0x0605 ), + AF_UNIRANGE_REC( 0x0610, 0x061A ), + AF_UNIRANGE_REC( 0x064B, 0x065F ), + AF_UNIRANGE_REC( 0x0670, 0x0670 ), + AF_UNIRANGE_REC( 0x06D6, 0x06DC ), + AF_UNIRANGE_REC( 0x06DF, 0x06E4 ), + AF_UNIRANGE_REC( 0x06E7, 0x06E8 ), + AF_UNIRANGE_REC( 0x06EA, 0x06ED ), + AF_UNIRANGE_REC( 0x08D4, 0x08E1 ), + AF_UNIRANGE_REC( 0x08E3, 0x08FF ), + AF_UNIRANGE_REC( 0xFBB2, 0xFBC1 ), + AF_UNIRANGE_REC( 0xFE70, 0xFE70 ), + AF_UNIRANGE_REC( 0xFE72, 0xFE72 ), + AF_UNIRANGE_REC( 0xFE74, 0xFE74 ), + AF_UNIRANGE_REC( 0xFE76, 0xFE76 ), + AF_UNIRANGE_REC( 0xFE78, 0xFE78 ), + AF_UNIRANGE_REC( 0xFE7A, 0xFE7A ), + AF_UNIRANGE_REC( 0xFE7C, 0xFE7C ), + AF_UNIRANGE_REC( 0xFE7E, 0xFE7E ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_armn_uniranges[] = + { + AF_UNIRANGE_REC( 0x0530, 0x058F ), /* Armenian */ + AF_UNIRANGE_REC( 0xFB13, 0xFB17 ), /* Alphab. Present. Forms (Armenian) */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_armn_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0559, 0x055F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_beng_uniranges[] = + { + AF_UNIRANGE_REC( 0x0980, 0x09FF ), /* Bengali */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_beng_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0981, 0x0981 ), + AF_UNIRANGE_REC( 0x09BC, 0x09BC ), + AF_UNIRANGE_REC( 0x09C1, 0x09C4 ), + AF_UNIRANGE_REC( 0x09CD, 0x09CD ), + AF_UNIRANGE_REC( 0x09E2, 0x09E3 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_cher_uniranges[] = + { + AF_UNIRANGE_REC( 0x13A0, 0x13FF ), /* Cherokee */ + AF_UNIRANGE_REC( 0xAB70, 0xABBF ), /* Cherokee Supplement */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_cher_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_cyrl_uniranges[] = + { + AF_UNIRANGE_REC( 0x0400, 0x04FF ), /* Cyrillic */ + AF_UNIRANGE_REC( 0x0500, 0x052F ), /* Cyrillic Supplement */ + AF_UNIRANGE_REC( 0x2DE0, 0x2DFF ), /* Cyrillic Extended-A */ + AF_UNIRANGE_REC( 0xA640, 0xA69F ), /* Cyrillic Extended-B */ + AF_UNIRANGE_REC( 0x1C80, 0x1C8F ), /* Cyrillic Extended-C */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_cyrl_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0483, 0x0489 ), + AF_UNIRANGE_REC( 0x2DE0, 0x2DFF ), + AF_UNIRANGE_REC( 0xA66F, 0xA67F ), + AF_UNIRANGE_REC( 0xA69E, 0xA69F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + /* There are some characters in the Devanagari Unicode block that are */ + /* generic to Indic scripts; we omit them so that their presence doesn't */ + /* trigger Devanagari. */ + + const AF_Script_UniRangeRec af_deva_uniranges[] = + { + AF_UNIRANGE_REC( 0x0900, 0x093B ), /* Devanagari */ + /* omitting U+093C nukta */ + AF_UNIRANGE_REC( 0x093D, 0x0950 ), /* ... continued */ + /* omitting U+0951 udatta, U+0952 anudatta */ + AF_UNIRANGE_REC( 0x0953, 0x0963 ), /* ... continued */ + /* omitting U+0964 danda, U+0965 double danda */ + AF_UNIRANGE_REC( 0x0966, 0x097F ), /* ... continued */ + AF_UNIRANGE_REC( 0x20B9, 0x20B9 ), /* (new) Rupee sign */ + AF_UNIRANGE_REC( 0xA8E0, 0xA8FF ), /* Devanagari Extended */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_deva_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0900, 0x0902 ), + AF_UNIRANGE_REC( 0x093A, 0x093A ), + AF_UNIRANGE_REC( 0x0941, 0x0948 ), + AF_UNIRANGE_REC( 0x094D, 0x094D ), + AF_UNIRANGE_REC( 0x0953, 0x0957 ), + AF_UNIRANGE_REC( 0x0962, 0x0963 ), + AF_UNIRANGE_REC( 0xA8E0, 0xA8F1 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_ethi_uniranges[] = + { + AF_UNIRANGE_REC( 0x1200, 0x137F ), /* Ethiopic */ + AF_UNIRANGE_REC( 0x1380, 0x139F ), /* Ethiopic Supplement */ + AF_UNIRANGE_REC( 0x2D80, 0x2DDF ), /* Ethiopic Extended */ + AF_UNIRANGE_REC( 0xAB00, 0xAB2F ), /* Ethiopic Extended-A */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_ethi_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x135D, 0x135F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_geor_uniranges[] = + { + AF_UNIRANGE_REC( 0x10D0, 0x10FF ), /* Georgian (Mkhedruli) */ +#if 0 + /* the following range is proposed for inclusion in Unicode */ + AF_UNIRANGE_REC( 0x1C90, 0x1CBF ), /* Georgian (Mtavruli) */ +#endif + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_geor_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_geok_uniranges[] = + { + /* Khutsuri */ + AF_UNIRANGE_REC( 0x10A0, 0x10CD ), /* Georgian (Asomtavruli) */ + AF_UNIRANGE_REC( 0x2D00, 0x2D2D ), /* Georgian (Nuskhuri) */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_geok_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_grek_uniranges[] = + { + AF_UNIRANGE_REC( 0x0370, 0x03FF ), /* Greek and Coptic */ + AF_UNIRANGE_REC( 0x1F00, 0x1FFF ), /* Greek Extended */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_grek_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x037A, 0x037A ), + AF_UNIRANGE_REC( 0x0384, 0x0385 ), + AF_UNIRANGE_REC( 0x1FBD, 0x1FC1 ), + AF_UNIRANGE_REC( 0x1FCD, 0x1FCF ), + AF_UNIRANGE_REC( 0x1FDD, 0x1FDF ), + AF_UNIRANGE_REC( 0x1FED, 0x1FEF ), + AF_UNIRANGE_REC( 0x1FFD, 0x1FFE ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_gujr_uniranges[] = + { + AF_UNIRANGE_REC( 0x0A80, 0x0AFF ), /* Gujarati */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_gujr_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0A81, 0x0A82 ), + AF_UNIRANGE_REC( 0x0ABC, 0x0ABC ), + AF_UNIRANGE_REC( 0x0AC1, 0x0AC8 ), + AF_UNIRANGE_REC( 0x0ACD, 0x0ACD ), + AF_UNIRANGE_REC( 0x0AE2, 0x0AE3 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_guru_uniranges[] = + { + AF_UNIRANGE_REC( 0x0A00, 0x0A7F ), /* Gurmukhi */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_guru_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0A01, 0x0A02 ), + AF_UNIRANGE_REC( 0x0A3C, 0x0A3C ), + AF_UNIRANGE_REC( 0x0A41, 0x0A51 ), + AF_UNIRANGE_REC( 0x0A70, 0x0A71 ), + AF_UNIRANGE_REC( 0x0A75, 0x0A75 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_hebr_uniranges[] = + { + AF_UNIRANGE_REC( 0x0590, 0x05FF ), /* Hebrew */ + AF_UNIRANGE_REC( 0xFB1D, 0xFB4F ), /* Alphab. Present. Forms (Hebrew) */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_hebr_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0591, 0x05BF ), + AF_UNIRANGE_REC( 0x05C1, 0x05C2 ), + AF_UNIRANGE_REC( 0x05C4, 0x05C5 ), + AF_UNIRANGE_REC( 0x05C7, 0x05C7 ), + AF_UNIRANGE_REC( 0xFB1E, 0xFB1E ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_knda_uniranges[] = + { + AF_UNIRANGE_REC( 0x0C80, 0x0CFF ), /* Kannada */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_knda_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0C81, 0x0C81 ), + AF_UNIRANGE_REC( 0x0CBC, 0x0CBC ), + AF_UNIRANGE_REC( 0x0CBF, 0x0CBF ), + AF_UNIRANGE_REC( 0x0CC6, 0x0CC6 ), + AF_UNIRANGE_REC( 0x0CCC, 0x0CCD ), + AF_UNIRANGE_REC( 0x0CE2, 0x0CE3 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_khmr_uniranges[] = + { + AF_UNIRANGE_REC( 0x1780, 0x17FF ), /* Khmer */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_khmr_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x17B7, 0x17BD ), + AF_UNIRANGE_REC( 0x17C6, 0x17C6 ), + AF_UNIRANGE_REC( 0x17C9, 0x17D3 ), + AF_UNIRANGE_REC( 0x17DD, 0x17DD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_khms_uniranges[] = + { + AF_UNIRANGE_REC( 0x19E0, 0x19FF ), /* Khmer Symbols */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_khms_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_lao_uniranges[] = + { + AF_UNIRANGE_REC( 0x0E80, 0x0EFF ), /* Lao */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_lao_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0EB1, 0x0EB1 ), + AF_UNIRANGE_REC( 0x0EB4, 0x0EBC ), + AF_UNIRANGE_REC( 0x0EC8, 0x0ECD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_latn_uniranges[] = + { + AF_UNIRANGE_REC( 0x0020, 0x007F ), /* Basic Latin (no control chars) */ + AF_UNIRANGE_REC( 0x00A0, 0x00A9 ), /* Latin-1 Supplement (no control chars) */ + AF_UNIRANGE_REC( 0x00AB, 0x00B1 ), /* ... continued */ + AF_UNIRANGE_REC( 0x00B4, 0x00B8 ), /* ... continued */ + AF_UNIRANGE_REC( 0x00BB, 0x00FF ), /* ... continued */ + AF_UNIRANGE_REC( 0x0100, 0x017F ), /* Latin Extended-A */ + AF_UNIRANGE_REC( 0x0180, 0x024F ), /* Latin Extended-B */ + AF_UNIRANGE_REC( 0x0250, 0x02AF ), /* IPA Extensions */ + AF_UNIRANGE_REC( 0x02B9, 0x02DF ), /* Spacing Modifier Letters */ + AF_UNIRANGE_REC( 0x02E5, 0x02FF ), /* ... continued */ + AF_UNIRANGE_REC( 0x0300, 0x036F ), /* Combining Diacritical Marks */ + AF_UNIRANGE_REC( 0x1AB0, 0x1ABE ), /* Combining Diacritical Marks Extended */ + AF_UNIRANGE_REC( 0x1D00, 0x1D2B ), /* Phonetic Extensions */ + AF_UNIRANGE_REC( 0x1D6B, 0x1D77 ), /* ... continued */ + AF_UNIRANGE_REC( 0x1D79, 0x1D7F ), /* ... continued */ + AF_UNIRANGE_REC( 0x1D80, 0x1D9A ), /* Phonetic Extensions Supplement */ + AF_UNIRANGE_REC( 0x1DC0, 0x1DFF ), /* Combining Diacritical Marks Supplement */ + AF_UNIRANGE_REC( 0x1E00, 0x1EFF ), /* Latin Extended Additional */ + AF_UNIRANGE_REC( 0x2000, 0x206F ), /* General Punctuation */ + AF_UNIRANGE_REC( 0x20A0, 0x20B8 ), /* Currency Symbols ... */ + AF_UNIRANGE_REC( 0x20BA, 0x20CF ), /* ... except new Rupee sign */ + AF_UNIRANGE_REC( 0x2150, 0x218F ), /* Number Forms */ + AF_UNIRANGE_REC( 0x2C60, 0x2C7B ), /* Latin Extended-C */ + AF_UNIRANGE_REC( 0x2C7E, 0x2C7F ), /* ... continued */ + AF_UNIRANGE_REC( 0x2E00, 0x2E7F ), /* Supplemental Punctuation */ + AF_UNIRANGE_REC( 0xA720, 0xA76F ), /* Latin Extended-D */ + AF_UNIRANGE_REC( 0xA771, 0xA7F7 ), /* ... continued */ + AF_UNIRANGE_REC( 0xA7FA, 0xA7FF ), /* ... continued */ + AF_UNIRANGE_REC( 0xAB30, 0xAB5B ), /* Latin Extended-E */ + AF_UNIRANGE_REC( 0xAB60, 0xAB6F ), /* ... continued */ + AF_UNIRANGE_REC( 0xFB00, 0xFB06 ), /* Alphab. Present. Forms (Latin Ligs) */ + AF_UNIRANGE_REC( 0x1D400, 0x1D7FF ), /* Mathematical Alphanumeric Symbols */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_latn_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x005E, 0x0060 ), + AF_UNIRANGE_REC( 0x007E, 0x007E ), + AF_UNIRANGE_REC( 0x00A8, 0x00A9 ), + AF_UNIRANGE_REC( 0x00AE, 0x00B0 ), + AF_UNIRANGE_REC( 0x00B4, 0x00B4 ), + AF_UNIRANGE_REC( 0x00B8, 0x00B8 ), + AF_UNIRANGE_REC( 0x00BC, 0x00BE ), + AF_UNIRANGE_REC( 0x02B9, 0x02DF ), + AF_UNIRANGE_REC( 0x02E5, 0x02FF ), + AF_UNIRANGE_REC( 0x0300, 0x036F ), + AF_UNIRANGE_REC( 0x1AB0, 0x1ABE ), + AF_UNIRANGE_REC( 0x1DC0, 0x1DFF ), + AF_UNIRANGE_REC( 0x2017, 0x2017 ), + AF_UNIRANGE_REC( 0x203E, 0x203E ), + AF_UNIRANGE_REC( 0xA788, 0xA788 ), + AF_UNIRANGE_REC( 0xA7F8, 0xA7FA ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_latb_uniranges[] = + { + AF_UNIRANGE_REC( 0x1D62, 0x1D6A ), /* some small subscript letters */ + AF_UNIRANGE_REC( 0x2080, 0x209C ), /* subscript digits and letters */ + AF_UNIRANGE_REC( 0x2C7C, 0x2C7C ), /* latin subscript small letter j */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_latb_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_latp_uniranges[] = + { + AF_UNIRANGE_REC( 0x00AA, 0x00AA ), /* feminine ordinal indicator */ + AF_UNIRANGE_REC( 0x00B2, 0x00B3 ), /* superscript two and three */ + AF_UNIRANGE_REC( 0x00B9, 0x00BA ), /* superscript one, masc. ord. indic. */ + AF_UNIRANGE_REC( 0x02B0, 0x02B8 ), /* some latin superscript mod. letters */ + AF_UNIRANGE_REC( 0x02E0, 0x02E4 ), /* some IPA modifier letters */ + AF_UNIRANGE_REC( 0x1D2C, 0x1D61 ), /* latin superscript modifier letters */ + AF_UNIRANGE_REC( 0x1D78, 0x1D78 ), /* modifier letter cyrillic en */ + AF_UNIRANGE_REC( 0x1D9B, 0x1DBF ), /* more modifier letters */ + AF_UNIRANGE_REC( 0x2070, 0x207F ), /* superscript digits and letters */ + AF_UNIRANGE_REC( 0x2C7D, 0x2C7D ), /* modifier letter capital v */ + AF_UNIRANGE_REC( 0xA770, 0xA770 ), /* modifier letter us */ + AF_UNIRANGE_REC( 0xA7F8, 0xA7F9 ), /* more modifier letters */ + AF_UNIRANGE_REC( 0xAB5C, 0xAB5F ), /* more modifier letters */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_latp_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_mlym_uniranges[] = + { + AF_UNIRANGE_REC( 0x0D00, 0x0D7F ), /* Malayalam */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_mlym_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0D01, 0x0D01 ), + AF_UNIRANGE_REC( 0x0D4D, 0x0D4E ), + AF_UNIRANGE_REC( 0x0D62, 0x0D63 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_mymr_uniranges[] = + { + AF_UNIRANGE_REC( 0x1000, 0x109F ), /* Myanmar */ + AF_UNIRANGE_REC( 0xA9E0, 0xA9FF ), /* Myanmar Extended-B */ + AF_UNIRANGE_REC( 0xAA60, 0xAA7F ), /* Myanmar Extended-A */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_mymr_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x102D, 0x1030 ), + AF_UNIRANGE_REC( 0x1032, 0x1037 ), + AF_UNIRANGE_REC( 0x103A, 0x103A ), + AF_UNIRANGE_REC( 0x103D, 0x103E ), + AF_UNIRANGE_REC( 0x1058, 0x1059 ), + AF_UNIRANGE_REC( 0x105E, 0x1060 ), + AF_UNIRANGE_REC( 0x1071, 0x1074 ), + AF_UNIRANGE_REC( 0x1082, 0x1082 ), + AF_UNIRANGE_REC( 0x1085, 0x1086 ), + AF_UNIRANGE_REC( 0x108D, 0x108D ), + AF_UNIRANGE_REC( 0xA9E5, 0xA9E5 ), + AF_UNIRANGE_REC( 0xAA7C, 0xAA7C ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_none_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_none_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_sinh_uniranges[] = + { + AF_UNIRANGE_REC( 0x0D80, 0x0DFF ), /* Sinhala */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_sinh_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0DCA, 0x0DCA ), + AF_UNIRANGE_REC( 0x0DD2, 0x0DD6 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_taml_uniranges[] = + { + AF_UNIRANGE_REC( 0x0B80, 0x0BFF ), /* Tamil */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_taml_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0B82, 0x0B82 ), + AF_UNIRANGE_REC( 0x0BC0, 0x0BC2 ), + AF_UNIRANGE_REC( 0x0BCD, 0x0BCD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_telu_uniranges[] = + { + AF_UNIRANGE_REC( 0x0C00, 0x0C7F ), /* Telugu */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_telu_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0C00, 0x0C00 ), + AF_UNIRANGE_REC( 0x0C3E, 0x0C40 ), + AF_UNIRANGE_REC( 0x0C46, 0x0C56 ), + AF_UNIRANGE_REC( 0x0C62, 0x0C63 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_thai_uniranges[] = + { + AF_UNIRANGE_REC( 0x0E00, 0x0E7F ), /* Thai */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_thai_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0E31, 0x0E31 ), + AF_UNIRANGE_REC( 0x0E34, 0x0E3A ), + AF_UNIRANGE_REC( 0x0E47, 0x0E4E ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + +#ifdef AF_CONFIG_OPTION_INDIC + + const AF_Script_UniRangeRec af_limb_uniranges[] = + { + AF_UNIRANGE_REC( 0x1900, 0x194F ), /* Limbu */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_limb_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x1920, 0x1922 ), + AF_UNIRANGE_REC( 0x1927, 0x1934 ), + AF_UNIRANGE_REC( 0x1937, 0x193B ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_orya_uniranges[] = + { + AF_UNIRANGE_REC( 0x0B00, 0x0B7F ), /* Oriya */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_orya_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0B01, 0x0B02 ), + AF_UNIRANGE_REC( 0x0B3C, 0x0B3C ), + AF_UNIRANGE_REC( 0x0B3F, 0x0B3F ), + AF_UNIRANGE_REC( 0x0B41, 0x0B44 ), + AF_UNIRANGE_REC( 0x0B4D, 0x0B56 ), + AF_UNIRANGE_REC( 0x0B62, 0x0B63 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_sund_uniranges[] = + { + AF_UNIRANGE_REC( 0x1B80, 0x1BBF ), /* Sundanese */ + AF_UNIRANGE_REC( 0x1CC0, 0x1CCF ), /* Sundanese Supplement */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_sund_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x1B80, 0x1B82 ), + AF_UNIRANGE_REC( 0x1BA1, 0x1BAD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_sylo_uniranges[] = + { + AF_UNIRANGE_REC( 0xA800, 0xA82F ), /* Syloti Nagri */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_sylo_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0xA802, 0xA802 ), + AF_UNIRANGE_REC( 0xA806, 0xA806 ), + AF_UNIRANGE_REC( 0xA80B, 0xA80B ), + AF_UNIRANGE_REC( 0xA825, 0xA826 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_tibt_uniranges[] = + { + AF_UNIRANGE_REC( 0x0F00, 0x0FFF ), /* Tibetan */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_tibt_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0F18, 0x0F19 ), + AF_UNIRANGE_REC( 0x0F35, 0x0F35 ), + AF_UNIRANGE_REC( 0x0F37, 0x0F37 ), + AF_UNIRANGE_REC( 0x0F39, 0x0F39 ), + AF_UNIRANGE_REC( 0x0F3E, 0x0F3F ), + AF_UNIRANGE_REC( 0x0F71, 0x0F7E ), + AF_UNIRANGE_REC( 0x0F80, 0x0F84 ), + AF_UNIRANGE_REC( 0x0F86, 0x0F87 ), + AF_UNIRANGE_REC( 0x0F8D, 0x0FBC ), + AF_UNIRANGE_REC( 0, 0 ) + }; + +#endif /* !AF_CONFIG_OPTION_INDIC */ + +#ifdef AF_CONFIG_OPTION_CJK + + /* this corresponds to Unicode 6.0 */ + + const AF_Script_UniRangeRec af_hani_uniranges[] = + { + AF_UNIRANGE_REC( 0x1100, 0x11FF ), /* Hangul Jamo */ + AF_UNIRANGE_REC( 0x2E80, 0x2EFF ), /* CJK Radicals Supplement */ + AF_UNIRANGE_REC( 0x2F00, 0x2FDF ), /* Kangxi Radicals */ + AF_UNIRANGE_REC( 0x2FF0, 0x2FFF ), /* Ideographic Description Characters */ + AF_UNIRANGE_REC( 0x3000, 0x303F ), /* CJK Symbols and Punctuation */ + AF_UNIRANGE_REC( 0x3040, 0x309F ), /* Hiragana */ + AF_UNIRANGE_REC( 0x30A0, 0x30FF ), /* Katakana */ + AF_UNIRANGE_REC( 0x3100, 0x312F ), /* Bopomofo */ + AF_UNIRANGE_REC( 0x3130, 0x318F ), /* Hangul Compatibility Jamo */ + AF_UNIRANGE_REC( 0x3190, 0x319F ), /* Kanbun */ + AF_UNIRANGE_REC( 0x31A0, 0x31BF ), /* Bopomofo Extended */ + AF_UNIRANGE_REC( 0x31C0, 0x31EF ), /* CJK Strokes */ + AF_UNIRANGE_REC( 0x31F0, 0x31FF ), /* Katakana Phonetic Extensions */ + AF_UNIRANGE_REC( 0x3300, 0x33FF ), /* CJK Compatibility */ + AF_UNIRANGE_REC( 0x3400, 0x4DBF ), /* CJK Unified Ideographs Extension A */ + AF_UNIRANGE_REC( 0x4DC0, 0x4DFF ), /* Yijing Hexagram Symbols */ + AF_UNIRANGE_REC( 0x4E00, 0x9FFF ), /* CJK Unified Ideographs */ + AF_UNIRANGE_REC( 0xA960, 0xA97F ), /* Hangul Jamo Extended-A */ + AF_UNIRANGE_REC( 0xAC00, 0xD7AF ), /* Hangul Syllables */ + AF_UNIRANGE_REC( 0xD7B0, 0xD7FF ), /* Hangul Jamo Extended-B */ + AF_UNIRANGE_REC( 0xF900, 0xFAFF ), /* CJK Compatibility Ideographs */ + AF_UNIRANGE_REC( 0xFE10, 0xFE1F ), /* Vertical forms */ + AF_UNIRANGE_REC( 0xFE30, 0xFE4F ), /* CJK Compatibility Forms */ + AF_UNIRANGE_REC( 0xFF00, 0xFFEF ), /* Halfwidth and Fullwidth Forms */ + AF_UNIRANGE_REC( 0x1B000, 0x1B0FF ), /* Kana Supplement */ + AF_UNIRANGE_REC( 0x1D300, 0x1D35F ), /* Tai Xuan Hing Symbols */ + AF_UNIRANGE_REC( 0x20000, 0x2A6DF ), /* CJK Unified Ideographs Extension B */ + AF_UNIRANGE_REC( 0x2A700, 0x2B73F ), /* CJK Unified Ideographs Extension C */ + AF_UNIRANGE_REC( 0x2B740, 0x2B81F ), /* CJK Unified Ideographs Extension D */ + AF_UNIRANGE_REC( 0x2F800, 0x2FA1F ), /* CJK Compatibility Ideographs Supplement */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_hani_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x302A, 0x302F ), + AF_UNIRANGE_REC( 0x3190, 0x319F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + +#endif /* !AF_CONFIG_OPTION_CJK */ + +/* END */ diff --git a/drivers/freetype/src/autofit/afranges.h b/drivers/freetype/src/autofit/afranges.h new file mode 100644 index 0000000000..1a0e4b1535 --- /dev/null +++ b/drivers/freetype/src/autofit/afranges.h @@ -0,0 +1,47 @@ +/***************************************************************************/ +/* */ +/* afranges.h */ +/* */ +/* Auto-fitter Unicode script ranges (specification). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef AFRANGES_H_ +#define AFRANGES_H_ + + +#include "aftypes.h" + + +FT_BEGIN_HEADER + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + extern const AF_Script_UniRangeRec af_ ## s ## _uniranges[]; + +#include "afscript.h" + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + extern const AF_Script_UniRangeRec af_ ## s ## _nonbase_uniranges[]; + +#include "afscript.h" + + /* */ + +FT_END_HEADER + +#endif /* AFRANGES_H_ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afscript.h b/drivers/freetype/src/autofit/afscript.h new file mode 100644 index 0000000000..33c3012981 --- /dev/null +++ b/drivers/freetype/src/autofit/afscript.h @@ -0,0 +1,245 @@ +/***************************************************************************/ +/* */ +/* afscript.h */ +/* */ +/* Auto-fitter scripts (specification only). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /* The following part can be included multiple times. */ + /* Define `SCRIPT' as needed. */ + + + /* Add new scripts here. The first and second arguments are the */ + /* script name in lowercase and uppercase, respectively, followed */ + /* by a description string. Then comes the corresponding HarfBuzz */ + /* script name tag, followed by a string of standard characters (to */ + /* derive the standard width and height of stems). */ + /* */ + /* Note that fallback scripts only have a default style, thus we */ + /* use `HB_SCRIPT_INVALID' as the HarfBuzz script name tag for */ + /* them. */ + + SCRIPT( arab, ARAB, + "Arabic", + HB_SCRIPT_ARABIC, + HINTING_BOTTOM_TO_TOP, + "\xD9\x84 \xD8\xAD \xD9\x80" ) /* ل ح ـ */ + + SCRIPT( armn, ARMN, + "Armenian", + HB_SCRIPT_ARMENIAN, + HINTING_BOTTOM_TO_TOP, + "\xD6\x85 \xD5\x95" ) /* օ Օ */ + + /* there are no simple forms for letters; we thus use two digit shapes */ + SCRIPT( beng, BENG, + "Bengali", + HB_SCRIPT_BENGALI, + HINTING_TOP_TO_BOTTOM, + "\xE0\xA7\xA6 \xE0\xA7\xAA" ) /* ০ ৪ */ + + SCRIPT( cher, CHER, + "Cherokee", + HB_SCRIPT_CHEROKEE, + HINTING_BOTTOM_TO_TOP, + "\xE1\x8E\xA4 \xE1\x8F\x85 \xEA\xAE\x95" ) /* Ꭴ Ꮕ ꮕ */ + + SCRIPT( cyrl, CYRL, + "Cyrillic", + HB_SCRIPT_CYRILLIC, + HINTING_BOTTOM_TO_TOP, + "\xD0\xBE \xD0\x9E" ) /* о О */ + + SCRIPT( deva, DEVA, + "Devanagari", + HB_SCRIPT_DEVANAGARI, + HINTING_TOP_TO_BOTTOM, + "\xE0\xA4\xA0 \xE0\xA4\xB5 \xE0\xA4\x9F" ) /* ठ व ट */ + + SCRIPT( ethi, ETHI, + "Ethiopic", + HB_SCRIPT_ETHIOPIC, + HINTING_BOTTOM_TO_TOP, + "\xE1\x8B\x90" ) /* ዐ */ + + SCRIPT( geor, GEOR, + "Georgian (Mkhedruli)", + HB_SCRIPT_GEORGIAN, + HINTING_BOTTOM_TO_TOP, + "\xE1\x83\x98 \xE1\x83\x94 \xE1\x83\x90" ) /* ი ე ა */ + + SCRIPT( geok, GEOK, + "Georgian (Khutsuri)", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "\xE1\x82\xB6 \xE1\x82\xB1 \xE2\xB4\x99" ) /* Ⴖ Ⴑ ⴙ */ + + SCRIPT( grek, GREK, + "Greek", + HB_SCRIPT_GREEK, + HINTING_BOTTOM_TO_TOP, + "\xCE\xBF \xCE\x9F" ) /* ο Ο */ + + SCRIPT( gujr, GUJR, + "Gujarati", + HB_SCRIPT_GUJARATI, + HINTING_BOTTOM_TO_TOP, + "\xE0\xAA\x9F \xE0\xAB\xA6" ) /* ટ ૦ */ + + SCRIPT( guru, GURU, + "Gurmukhi", + HB_SCRIPT_GURMUKHI, + HINTING_TOP_TO_BOTTOM, + "\xE0\xA8\xA0 \xE0\xA8\xB0 \xE0\xA9\xA6" ) /* ਠ ਰ ੦ */ + + SCRIPT( hebr, HEBR, + "Hebrew", + HB_SCRIPT_HEBREW, + HINTING_BOTTOM_TO_TOP, + "\xD7\x9D" ) /* ם */ + + SCRIPT( knda, KNDA, + "Kannada", + HB_SCRIPT_KANNADA, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB3\xA6 \xE0\xB2\xAC" ) /* ೦ ಬ */ + + /* only digit zero has a simple shape in the Khmer script */ + SCRIPT( khmr, KHMR, + "Khmer", + HB_SCRIPT_KHMER, + HINTING_BOTTOM_TO_TOP, + "\xE1\x9F\xA0" ) /* ០ */ + + SCRIPT( khms, KHMS, + "Khmer Symbols", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "\xE1\xA7\xA1 \xE1\xA7\xAA" ) /* ᧡ ᧪ */ + + /* only digit zero has a simple shape in the Lao script */ + SCRIPT( lao, LAO, + "Lao", + HB_SCRIPT_LAO, + HINTING_BOTTOM_TO_TOP, + "\xE0\xBB\x90" ) /* ໐ */ + + SCRIPT( latn, LATN, + "Latin", + HB_SCRIPT_LATIN, + HINTING_BOTTOM_TO_TOP, + "o O 0" ) + + SCRIPT( latb, LATB, + "Latin Subscript Fallback", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "\xE2\x82\x92 \xE2\x82\x80" ) /* ₒ ₀ */ + + SCRIPT( latp, LATP, + "Latin Superscript Fallback", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "\xE1\xB5\x92 \xE1\xB4\xBC \xE2\x81\xB0" ) /* ᵒ ᴼ ⁰ */ + + SCRIPT( mlym, MLYM, + "Malayalam", + HB_SCRIPT_MALAYALAM, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB4\xA0 \xE0\xB4\xB1" ) /* ഠ റ */ + + SCRIPT( mymr, MYMR, + "Myanmar", + HB_SCRIPT_MYANMAR, + HINTING_BOTTOM_TO_TOP, + "\xE1\x80\x9D \xE1\x80\x84 \xE1\x80\x82" ) /* ဝ င ဂ */ + + SCRIPT( none, NONE, + "no script", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "" ) + + SCRIPT( sinh, SINH, + "Sinhala", + HB_SCRIPT_SINHALA, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB6\xA7" ) /* ට */ + + /* only digit zero has a simple (round) shape in the Tamil script */ + SCRIPT( taml, TAML, + "Tamil", + HB_SCRIPT_TAMIL, + HINTING_BOTTOM_TO_TOP, + "\xE0\xAF\xA6" ) /* ௦ */ + + /* there are no simple forms for letters; we thus use two digit shapes */ + SCRIPT( telu, TELU, + "Telugu", + HB_SCRIPT_TELUGU, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB1\xA6 \xE0\xB1\xA7" ) /* ౦ ౧ */ + + SCRIPT( thai, THAI, + "Thai", + HB_SCRIPT_THAI, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB8\xB2 \xE0\xB9\x85 \xE0\xB9\x90" ) /* า ๅ ๐ */ + +#ifdef AF_CONFIG_OPTION_INDIC + + SCRIPT( limb, LIMB, + "Limbu", + HB_SCRIPT_LIMBU, + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ + + SCRIPT( orya, ORYA, + "Oriya", + HB_SCRIPT_ORIYA, + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ + + SCRIPT( sund, SUND, + "Sundanese", + HB_SCRIPT_SUNDANESE, + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ + + SCRIPT( sylo, SYLO, + "Syloti Nagri", + HB_SCRIPT_SYLOTI_NAGRI, + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ + + SCRIPT( tibt, TIBT, + "Tibetan", + HB_SCRIPT_TIBETAN, + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ + +#endif /* AF_CONFIG_OPTION_INDIC */ + +#ifdef AF_CONFIG_OPTION_CJK + + SCRIPT( hani, HANI, + "CJKV ideographs", + HB_SCRIPT_HAN, + HINTING_BOTTOM_TO_TOP, + "\xE7\x94\xB0 \xE5\x9B\x97" ) /* 田 囗 */ + +#endif /* AF_CONFIG_OPTION_CJK */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afshaper.c b/drivers/freetype/src/autofit/afshaper.c new file mode 100644 index 0000000000..6d13b65859 --- /dev/null +++ b/drivers/freetype/src/autofit/afshaper.c @@ -0,0 +1,683 @@ +/***************************************************************************/ +/* */ +/* afshaper.c */ +/* */ +/* HarfBuzz interface for accessing OpenType features (body). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include "afglobal.h" +#include "aftypes.h" +#include "afshaper.h" + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_afshaper + + + /* + * We use `sets' (in the HarfBuzz sense, which comes quite near to the + * usual mathematical meaning) to manage both lookups and glyph indices. + * + * 1. For each coverage, collect lookup IDs in a set. Note that an + * auto-hinter `coverage' is represented by one `feature', and a + * feature consists of an arbitrary number of (font specific) `lookup's + * that actually do the mapping job. Please check the OpenType + * specification for more details on features and lookups. + * + * 2. Create glyph ID sets from the corresponding lookup sets. + * + * 3. The glyph set corresponding to AF_COVERAGE_DEFAULT is computed + * with all lookups specific to the OpenType script activated. It + * relies on the order of AF_DEFINE_STYLE_CLASS entries so that + * special coverages (like `oldstyle figures') don't get overwritten. + * + */ + + + /* load coverage tags */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + static const hb_tag_t name ## _coverage[] = \ + { \ + HB_TAG( tag1, tag2, tag3, tag4 ), \ + HB_TAG_NONE \ + }; + + +#include "afcover.h" + + + /* define mapping between coverage tags and AF_Coverage */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + name ## _coverage, + + + static const hb_tag_t* coverages[] = + { +#include "afcover.h" + + NULL /* AF_COVERAGE_DEFAULT */ + }; + + + /* load HarfBuzz script tags */ +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) h, + + + static const hb_script_t scripts[] = + { +#include "afscript.h" + }; + + + FT_Error + af_shaper_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_UShort* gstyles, + FT_Bool default_script ) + { + hb_face_t* face; + + hb_set_t* gsub_lookups; /* GSUB lookups for a given script */ + hb_set_t* gsub_glyphs; /* glyphs covered by GSUB lookups */ + hb_set_t* gpos_lookups; /* GPOS lookups for a given script */ + hb_set_t* gpos_glyphs; /* glyphs covered by GPOS lookups */ + + hb_script_t script; + const hb_tag_t* coverage_tags; + hb_tag_t script_tags[] = { HB_TAG_NONE, + HB_TAG_NONE, + HB_TAG_NONE, + HB_TAG_NONE }; + + hb_codepoint_t idx; +#ifdef FT_DEBUG_LEVEL_TRACE + int count; +#endif + + + if ( !globals || !style_class || !gstyles ) + return FT_THROW( Invalid_Argument ); + + face = hb_font_get_face( globals->hb_font ); + + gsub_lookups = hb_set_create(); + gsub_glyphs = hb_set_create(); + gpos_lookups = hb_set_create(); + gpos_glyphs = hb_set_create(); + + coverage_tags = coverages[style_class->coverage]; + script = scripts[style_class->script]; + + /* Convert a HarfBuzz script tag into the corresponding OpenType */ + /* tag or tags -- some Indic scripts like Devanagari have an old */ + /* and a new set of features. */ + hb_ot_tags_from_script( script, + &script_tags[0], + &script_tags[1] ); + + /* `hb_ot_tags_from_script' usually returns HB_OT_TAG_DEFAULT_SCRIPT */ + /* as the second tag. We change that to HB_TAG_NONE except for the */ + /* default script. */ + if ( default_script ) + { + if ( script_tags[0] == HB_TAG_NONE ) + script_tags[0] = HB_OT_TAG_DEFAULT_SCRIPT; + else + { + if ( script_tags[1] == HB_TAG_NONE ) + script_tags[1] = HB_OT_TAG_DEFAULT_SCRIPT; + else if ( script_tags[1] != HB_OT_TAG_DEFAULT_SCRIPT ) + script_tags[2] = HB_OT_TAG_DEFAULT_SCRIPT; + } + } + else + { + /* we use non-standard tags like `khms' for special purposes; */ + /* HarfBuzz maps them to `DFLT', which we don't want to handle here */ + if ( script_tags[0] == HB_OT_TAG_DEFAULT_SCRIPT ) + goto Exit; + + if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT ) + script_tags[1] = HB_TAG_NONE; + } + + hb_ot_layout_collect_lookups( face, + HB_OT_TAG_GSUB, + script_tags, + NULL, + coverage_tags, + gsub_lookups ); + + if ( hb_set_is_empty( gsub_lookups ) ) + goto Exit; /* nothing to do */ + + hb_ot_layout_collect_lookups( face, + HB_OT_TAG_GPOS, + script_tags, + NULL, + coverage_tags, + gpos_lookups ); + + FT_TRACE4(( "GSUB lookups (style `%s'):\n" + " ", + af_style_names[style_class->style] )); + +#ifdef FT_DEBUG_LEVEL_TRACE + count = 0; +#endif + + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups, &idx ); ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " %d", idx )); + count++; +#endif + + /* get output coverage of GSUB feature */ + hb_ot_layout_lookup_collect_glyphs( face, + HB_OT_TAG_GSUB, + idx, + NULL, + NULL, + NULL, + gsub_glyphs ); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE4(( " (none)" )); + FT_TRACE4(( "\n\n" )); +#endif + + FT_TRACE4(( "GPOS lookups (style `%s'):\n" + " ", + af_style_names[style_class->style] )); + +#ifdef FT_DEBUG_LEVEL_TRACE + count = 0; +#endif + + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gpos_lookups, &idx ); ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " %d", idx )); + count++; +#endif + + /* get input coverage of GPOS feature */ + hb_ot_layout_lookup_collect_glyphs( face, + HB_OT_TAG_GPOS, + idx, + NULL, + gpos_glyphs, + NULL, + NULL ); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE4(( " (none)" )); + FT_TRACE4(( "\n\n" )); +#endif + + /* + * We now check whether we can construct blue zones, using glyphs + * covered by the feature only. In case there is not a single zone + * (this is, not a single character is covered), we skip this coverage. + * + */ + if ( style_class->coverage != AF_COVERAGE_DEFAULT ) + { + AF_Blue_Stringset bss = style_class->blue_stringset; + const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; + + FT_Bool found = 0; + + + for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) + { + const char* p = &af_blue_strings[bs->string]; + + + while ( *p ) + { + hb_codepoint_t ch; + + + GET_UTF8_CHAR( ch, p ); + + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups, + &idx ); ) + { + hb_codepoint_t gidx = FT_Get_Char_Index( globals->face, ch ); + + + if ( hb_ot_layout_lookup_would_substitute( face, idx, + &gidx, 1, 1 ) ) + { + found = 1; + break; + } + } + } + } + + if ( !found ) + { + FT_TRACE4(( " no blue characters found; style skipped\n" )); + goto Exit; + } + } + + /* + * Various OpenType features might use the same glyphs at different + * vertical positions; for example, superscript and subscript glyphs + * could be the same. However, the auto-hinter is completely + * agnostic of OpenType features after the feature analysis has been + * completed: The engine then simply receives a glyph index and returns a + * hinted and usually rendered glyph. + * + * Consider the superscript feature of font `pala.ttf': Some of the + * glyphs are `real', this is, they have a zero vertical offset, but + * most of them are small caps glyphs shifted up to the superscript + * position (this is, the `sups' feature is present in both the GSUB and + * GPOS tables). The code for blue zones computation actually uses a + * feature's y offset so that the `real' glyphs get correct hints. But + * later on it is impossible to decide whether a glyph index belongs to, + * say, the small caps or superscript feature. + * + * For this reason, we don't assign a style to a glyph if the current + * feature covers the glyph in both the GSUB and the GPOS tables. This + * is quite a broad condition, assuming that + * + * (a) glyphs that get used in multiple features are present in a + * feature without vertical shift, + * + * and + * + * (b) a feature's GPOS data really moves the glyph vertically. + * + * Not fulfilling condition (a) makes a font larger; it would also + * reduce the number of glyphs that could be addressed directly without + * using OpenType features, so this assumption is rather strong. + * + * Condition (b) is much weaker, and there might be glyphs which get + * missed. However, the OpenType features we are going to handle are + * primarily located in GSUB, and HarfBuzz doesn't provide an API to + * directly get the necessary information from the GPOS table. A + * possible solution might be to directly parse the GPOS table to find + * out whether a glyph gets shifted vertically, but this is something I + * would like to avoid if not really necessary. + * + * Note that we don't follow this logic for the default coverage. + * Complex scripts like Devanagari have mandatory GPOS features to + * position many glyph elements, using mark-to-base or mark-to-ligature + * tables; the number of glyphs missed due to condition (b) would be far + * too large. + * + */ + if ( style_class->coverage != AF_COVERAGE_DEFAULT ) + hb_set_subtract( gsub_glyphs, gpos_glyphs ); + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " glyphs without GPOS data (`*' means already assigned)" )); + count = 0; +#endif + + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_glyphs, &idx ); ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !( count % 10 ) ) + FT_TRACE4(( "\n" + " " )); + + FT_TRACE4(( " %d", idx )); + count++; +#endif + + /* glyph indices returned by `hb_ot_layout_lookup_collect_glyphs' */ + /* can be arbitrary: some fonts use fake indices for processing */ + /* internal to GSUB or GPOS, which is fully valid */ + if ( idx >= (hb_codepoint_t)globals->glyph_count ) + continue; + + if ( gstyles[idx] == AF_STYLE_UNASSIGNED ) + gstyles[idx] = (FT_UShort)style_class->style; +#ifdef FT_DEBUG_LEVEL_TRACE + else + FT_TRACE4(( "*" )); +#endif + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE4(( "\n" + " (none)" )); + FT_TRACE4(( "\n\n" )); +#endif + + Exit: + hb_set_destroy( gsub_lookups ); + hb_set_destroy( gsub_glyphs ); + hb_set_destroy( gpos_lookups ); + hb_set_destroy( gpos_glyphs ); + + return FT_Err_Ok; + } + + + /* construct HarfBuzz features */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + static const hb_feature_t name ## _feature[] = \ + { \ + { \ + HB_TAG( tag1, tag2, tag3, tag4 ), \ + 1, 0, (unsigned int)-1 \ + } \ + }; + + +#include "afcover.h" + + + /* define mapping between HarfBuzz features and AF_Coverage */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + name ## _feature, + + + static const hb_feature_t* features[] = + { +#include "afcover.h" + + NULL /* AF_COVERAGE_DEFAULT */ + }; + + + void* + af_shaper_buf_create( FT_Face face ) + { + FT_UNUSED( face ); + + return (void*)hb_buffer_create(); + } + + + void + af_shaper_buf_destroy( FT_Face face, + void* buf ) + { + FT_UNUSED( face ); + + hb_buffer_destroy( (hb_buffer_t*)buf ); + } + + + const char* + af_shaper_get_cluster( const char* p, + AF_StyleMetrics metrics, + void* buf_, + unsigned int* count ) + { + AF_StyleClass style_class; + const hb_feature_t* feature; + FT_Int upem; + const char* q; + int len; + + hb_buffer_t* buf = (hb_buffer_t*)buf_; + hb_font_t* font; + hb_codepoint_t dummy; + + + upem = (FT_Int)metrics->globals->face->units_per_EM; + style_class = metrics->style_class; + feature = features[style_class->coverage]; + + font = metrics->globals->hb_font; + + /* we shape at a size of units per EM; this means font units */ + hb_font_set_scale( font, upem, upem ); + + while ( *p == ' ' ) + p++; + + /* count bytes up to next space (or end of buffer) */ + q = p; + while ( !( *q == ' ' || *q == '\0' ) ) + GET_UTF8_CHAR( dummy, q ); + len = (int)( q - p ); + + /* feed character(s) to the HarfBuzz buffer */ + hb_buffer_clear_contents( buf ); + hb_buffer_add_utf8( buf, p, len, 0, len ); + + /* we let HarfBuzz guess the script and writing direction */ + hb_buffer_guess_segment_properties( buf ); + + /* shape buffer, which means conversion from character codes to */ + /* glyph indices, possibly applying a feature */ + hb_shape( font, buf, feature, feature ? 1 : 0 ); + + if ( feature ) + { + hb_buffer_t* hb_buf = metrics->globals->hb_buf; + + unsigned int gcount; + hb_glyph_info_t* ginfo; + + unsigned int hb_gcount; + hb_glyph_info_t* hb_ginfo; + + + /* we have to check whether applying a feature does actually change */ + /* glyph indices; otherwise the affected glyph or glyphs aren't */ + /* available at all in the feature */ + + hb_buffer_clear_contents( hb_buf ); + hb_buffer_add_utf8( hb_buf, p, len, 0, len ); + hb_buffer_guess_segment_properties( hb_buf ); + hb_shape( font, hb_buf, NULL, 0 ); + + ginfo = hb_buffer_get_glyph_infos( buf, &gcount ); + hb_ginfo = hb_buffer_get_glyph_infos( hb_buf, &hb_gcount ); + + if ( gcount == hb_gcount ) + { + unsigned int i; + + + for (i = 0; i < gcount; i++ ) + if ( ginfo[i].codepoint != hb_ginfo[i].codepoint ) + break; + + if ( i == gcount ) + { + /* both buffers have identical glyph indices */ + hb_buffer_clear_contents( buf ); + } + } + } + + *count = hb_buffer_get_length( buf ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( feature && *count > 1 ) + FT_TRACE1(( "af_shaper_get_cluster:" + " input character mapped to multiple glyphs\n" )); +#endif + + return q; + } + + + FT_ULong + af_shaper_get_elem( AF_StyleMetrics metrics, + void* buf_, + unsigned int idx, + FT_Long* advance, + FT_Long* y_offset ) + { + hb_buffer_t* buf = (hb_buffer_t*)buf_; + hb_glyph_info_t* ginfo; + hb_glyph_position_t* gpos; + unsigned int gcount; + + FT_UNUSED( metrics ); + + + ginfo = hb_buffer_get_glyph_infos( buf, &gcount ); + gpos = hb_buffer_get_glyph_positions( buf, &gcount ); + + if ( idx >= gcount ) + return 0; + + if ( advance ) + *advance = gpos[idx].x_advance; + if ( y_offset ) + *y_offset = gpos[idx].y_offset; + + return ginfo[idx].codepoint; + } + + +#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */ + + + FT_Error + af_shaper_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_UShort* gstyles, + FT_Bool default_script ) + { + FT_UNUSED( globals ); + FT_UNUSED( style_class ); + FT_UNUSED( gstyles ); + FT_UNUSED( default_script ); + + return FT_Err_Ok; + } + + + void* + af_shaper_buf_create( FT_Face face ) + { + FT_Error error; + FT_Memory memory = face->memory; + FT_ULong* buf; + + + FT_MEM_ALLOC( buf, sizeof ( FT_ULong ) ); + + return (void*)buf; + } + + + void + af_shaper_buf_destroy( FT_Face face, + void* buf ) + { + FT_Memory memory = face->memory; + + + FT_FREE( buf ); + } + + + const char* + af_shaper_get_cluster( const char* p, + AF_StyleMetrics metrics, + void* buf_, + unsigned int* count ) + { + FT_Face face = metrics->globals->face; + FT_ULong ch, dummy = 0; + FT_ULong* buf = (FT_ULong*)buf_; + + + while ( *p == ' ' ) + p++; + + GET_UTF8_CHAR( ch, p ); + + /* since we don't have an engine to handle clusters, */ + /* we scan the characters but return zero */ + while ( !( *p == ' ' || *p == '\0' ) ) + GET_UTF8_CHAR( dummy, p ); + + if ( dummy ) + { + *buf = 0; + *count = 0; + } + else + { + *buf = FT_Get_Char_Index( face, ch ); + *count = 1; + } + + return p; + } + + + FT_ULong + af_shaper_get_elem( AF_StyleMetrics metrics, + void* buf_, + unsigned int idx, + FT_Long* advance, + FT_Long* y_offset ) + { + FT_Face face = metrics->globals->face; + FT_ULong glyph_index = *(FT_ULong*)buf_; + + FT_UNUSED( idx ); + + + if ( advance ) + FT_Get_Advance( face, + glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + advance ); + + if ( y_offset ) + *y_offset = 0; + + return glyph_index; + } + + +#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afshaper.h b/drivers/freetype/src/autofit/afshaper.h new file mode 100644 index 0000000000..0d41f78762 --- /dev/null +++ b/drivers/freetype/src/autofit/afshaper.h @@ -0,0 +1,72 @@ +/***************************************************************************/ +/* */ +/* afshaper.h */ +/* */ +/* HarfBuzz interface for accessing OpenType features (specification). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef AFSHAPER_H_ +#define AFSHAPER_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + +#include <hb.h> +#include <hb-ot.h> +#include <hb-ft.h> + +#endif + + +FT_BEGIN_HEADER + + FT_Error + af_shaper_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_UShort* gstyles, + FT_Bool default_script ); + + + void* + af_shaper_buf_create( FT_Face face ); + + void + af_shaper_buf_destroy( FT_Face face, + void* buf ); + + const char* + af_shaper_get_cluster( const char* p, + AF_StyleMetrics metrics, + void* buf_, + unsigned int* count ); + + FT_ULong + af_shaper_get_elem( AF_StyleMetrics metrics, + void* buf_, + unsigned int idx, + FT_Long* x_advance, + FT_Long* y_offset ); + + /* */ + +FT_END_HEADER + +#endif /* AFSHAPER_H_ */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/afstyles.h b/drivers/freetype/src/autofit/afstyles.h new file mode 100644 index 0000000000..e83a95bb59 --- /dev/null +++ b/drivers/freetype/src/autofit/afstyles.h @@ -0,0 +1,301 @@ +/***************************************************************************/ +/* */ +/* afstyles.h */ +/* */ +/* Auto-fitter styles (specification only). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /* The following part can be included multiple times. */ + /* Define `STYLE' as needed. */ + + + /* Add new styles here. The first and second arguments are the */ + /* style name in lowercase and uppercase, respectively, followed */ + /* by a description string. The next arguments are the */ + /* corresponding writing system, script, blue stringset, and */ + /* coverage. */ + /* */ + /* Note that styles using `AF_COVERAGE_DEFAULT' should always */ + /* come after styles with other coverages. Also note that */ + /* fallback scripts only use `AF_COVERAGE_DEFAULT' for its */ + /* style. */ + /* */ + /* Example: */ + /* */ + /* STYLE( cyrl_dflt, CYRL_DFLT, */ + /* "Cyrillic default style", */ + /* AF_WRITING_SYSTEM_LATIN, */ + /* AF_SCRIPT_CYRL, */ + /* AF_BLUE_STRINGSET_CYRL, */ + /* AF_COVERAGE_DEFAULT ) */ + +#undef STYLE_LATIN +#define STYLE_LATIN( s, S, f, F, ds, df, C ) \ + STYLE( s ## _ ## f, S ## _ ## F, \ + ds " " df " style", \ + AF_WRITING_SYSTEM_LATIN, \ + AF_SCRIPT_ ## S, \ + AF_BLUE_STRINGSET_ ## S, \ + AF_COVERAGE_ ## C ) + +#undef META_STYLE_LATIN +#define META_STYLE_LATIN( s, S, ds ) \ + STYLE_LATIN( s, S, c2cp, C2CP, ds, \ + "petite capitals from capitals", \ + PETITE_CAPITALS_FROM_CAPITALS ) \ + STYLE_LATIN( s, S, c2sc, C2SC, ds, \ + "small capitals from capitals", \ + SMALL_CAPITALS_FROM_CAPITALS ) \ + STYLE_LATIN( s, S, ordn, ORDN, ds, \ + "ordinals", \ + ORDINALS ) \ + STYLE_LATIN( s, S, pcap, PCAP, ds, \ + "petite capitals", \ + PETITE_CAPITALS ) \ + STYLE_LATIN( s, S, sinf, SINF, ds, \ + "scientific inferiors", \ + SCIENTIFIC_INFERIORS ) \ + STYLE_LATIN( s, S, smcp, SMCP, ds, \ + "small capitals", \ + SMALL_CAPITALS ) \ + STYLE_LATIN( s, S, subs, SUBS, ds, \ + "subscript", \ + SUBSCRIPT ) \ + STYLE_LATIN( s, S, sups, SUPS, ds, \ + "superscript", \ + SUPERSCRIPT ) \ + STYLE_LATIN( s, S, titl, TITL, ds, \ + "titling", \ + TITLING ) \ + STYLE_LATIN( s, S, dflt, DFLT, ds, \ + "default", \ + DEFAULT ) + + + STYLE( arab_dflt, ARAB_DFLT, + "Arabic default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_ARAB, + AF_BLUE_STRINGSET_ARAB, + AF_COVERAGE_DEFAULT ) + + STYLE( armn_dflt, ARMN_DFLT, + "Armenian default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_ARMN, + AF_BLUE_STRINGSET_ARMN, + AF_COVERAGE_DEFAULT ) + + STYLE( beng_dflt, BENG_DFLT, + "Bengali default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_BENG, + AF_BLUE_STRINGSET_BENG, + AF_COVERAGE_DEFAULT ) + + STYLE( cher_dflt, CHER_DFLT, + "Cherokee default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_CHER, + AF_BLUE_STRINGSET_CHER, + AF_COVERAGE_DEFAULT ) + + META_STYLE_LATIN( cyrl, CYRL, "Cyrillic" ) + + STYLE( deva_dflt, DEVA_DFLT, + "Devanagari default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_DEVA, + AF_BLUE_STRINGSET_DEVA, + AF_COVERAGE_DEFAULT ) + + STYLE( ethi_dflt, ETHI_DFLT, + "Ethiopic default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_ETHI, + AF_BLUE_STRINGSET_ETHI, + AF_COVERAGE_DEFAULT ) + + STYLE( geor_dflt, GEOR_DFLT, + "Georgian (Mkhedruli) default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GEOR, + AF_BLUE_STRINGSET_GEOR, + AF_COVERAGE_DEFAULT ) + + STYLE( geok_dflt, GEOK_DFLT, + "Georgian (Khutsuri) default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GEOK, + AF_BLUE_STRINGSET_GEOK, + AF_COVERAGE_DEFAULT ) + + META_STYLE_LATIN( grek, GREK, "Greek" ) + + STYLE( gujr_dflt, GUJR_DFLT, + "Gujarati default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GUJR, + AF_BLUE_STRINGSET_GUJR, + AF_COVERAGE_DEFAULT ) + + STYLE( guru_dflt, GURU_DFLT, + "Gurmukhi default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GURU, + AF_BLUE_STRINGSET_GURU, + AF_COVERAGE_DEFAULT ) + + STYLE( hebr_dflt, HEBR_DFLT, + "Hebrew default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_HEBR, + AF_BLUE_STRINGSET_HEBR, + AF_COVERAGE_DEFAULT ) + + STYLE( knda_dflt, KNDA_DFLT, + "Kannada default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KNDA, + AF_BLUE_STRINGSET_KNDA, + AF_COVERAGE_DEFAULT ) + + STYLE( khmr_dflt, KHMR_DFLT, + "Khmer default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KHMR, + AF_BLUE_STRINGSET_KHMR, + AF_COVERAGE_DEFAULT ) + + STYLE( khms_dflt, KHMS_DFLT, + "Khmer Symbols default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KHMS, + AF_BLUE_STRINGSET_KHMS, + AF_COVERAGE_DEFAULT ) + + STYLE( lao_dflt, LAO_DFLT, + "Lao default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_LAO, + AF_BLUE_STRINGSET_LAO, + AF_COVERAGE_DEFAULT ) + + META_STYLE_LATIN( latn, LATN, "Latin" ) + + STYLE( latb_dflt, LATB_DFLT, + "Latin subscript fallback default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_LATB, + AF_BLUE_STRINGSET_LATB, + AF_COVERAGE_DEFAULT ) + + STYLE( latp_dflt, LATP_DFLT, + "Latin superscript fallback default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_LATP, + AF_BLUE_STRINGSET_LATP, + AF_COVERAGE_DEFAULT ) + +#ifdef FT_OPTION_AUTOFIT2 + STYLE( ltn2_dflt, LTN2_DFLT, + "Latin 2 default style", + AF_WRITING_SYSTEM_LATIN2, + AF_SCRIPT_LATN, + AF_BLUE_STRINGSET_LATN, + AF_COVERAGE_DEFAULT ) +#endif + + STYLE( mlym_dflt, MLYM_DFLT, + "Malayalam default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_MLYM, + AF_BLUE_STRINGSET_MLYM, + AF_COVERAGE_DEFAULT ) + + STYLE( mymr_dflt, MYMR_DFLT, + "Myanmar default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_MYMR, + AF_BLUE_STRINGSET_MYMR, + AF_COVERAGE_DEFAULT ) + + STYLE( none_dflt, NONE_DFLT, + "no style", + AF_WRITING_SYSTEM_DUMMY, + AF_SCRIPT_NONE, + AF_BLUE_STRINGSET_NONE, + AF_COVERAGE_DEFAULT ) + + STYLE( sinh_dflt, SINH_DFLT, + "Sinhala default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_SINH, + AF_BLUE_STRINGSET_SINH, + AF_COVERAGE_DEFAULT ) + + STYLE( taml_dflt, TAML_DFLT, + "Tamil default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_TAML, + AF_BLUE_STRINGSET_TAML, + AF_COVERAGE_DEFAULT ) + + STYLE( telu_dflt, TELU_DFLT, + "Telugu default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_TELU, + AF_BLUE_STRINGSET_TELU, + AF_COVERAGE_DEFAULT ) + + STYLE( thai_dflt, THAI_DFLT, + "Thai default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_THAI, + AF_BLUE_STRINGSET_THAI, + AF_COVERAGE_DEFAULT ) + +#ifdef AF_CONFIG_OPTION_INDIC + + /* no blue stringset support for the Indic writing system yet */ +#undef STYLE_DEFAULT_INDIC +#define STYLE_DEFAULT_INDIC( s, S, d ) \ + STYLE( s ## _dflt, S ## _DFLT, \ + d " default style", \ + AF_WRITING_SYSTEM_INDIC, \ + AF_SCRIPT_ ## S, \ + (AF_Blue_Stringset)0, \ + AF_COVERAGE_DEFAULT ) + + STYLE_DEFAULT_INDIC( limb, LIMB, "Limbu" ) + STYLE_DEFAULT_INDIC( orya, ORYA, "Oriya" ) + STYLE_DEFAULT_INDIC( sund, SUND, "Sundanese" ) + STYLE_DEFAULT_INDIC( sylo, SYLO, "Syloti Nagri" ) + STYLE_DEFAULT_INDIC( tibt, TIBT, "Tibetan" ) + +#endif /* AF_CONFIG_OPTION_INDIC */ + +#ifdef AF_CONFIG_OPTION_CJK + + STYLE( hani_dflt, HANI_DFLT, + "CJKV ideographs default style", + AF_WRITING_SYSTEM_CJK, + AF_SCRIPT_HANI, + AF_BLUE_STRINGSET_HANI, + AF_COVERAGE_DEFAULT ) + +#endif /* AF_CONFIG_OPTION_CJK */ + + +/* END */ diff --git a/drivers/freetype/src/autofit/aftypes.h b/drivers/freetype/src/autofit/aftypes.h new file mode 100644 index 0000000000..ef62043c8a --- /dev/null +++ b/drivers/freetype/src/autofit/aftypes.h @@ -0,0 +1,650 @@ +/***************************************************************************/ +/* */ +/* aftypes.h */ +/* */ +/* Auto-fitter types (specification only). */ +/* */ +/* Copyright 2003-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /************************************************************************* + * + * The auto-fitter is a complete rewrite of the old auto-hinter. + * Its main feature is the ability to differentiate between different + * writing systems and scripts in order to apply specific rules. + * + * The code has also been compartmentalized into several entities that + * should make algorithmic experimentation easier than with the old + * code. + * + *************************************************************************/ + + +#ifndef AFTYPES_H_ +#define AFTYPES_H_ + +#include <ft2build.h> + +#include FT_FREETYPE_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "afblue.h" + +#ifdef FT_DEBUG_AUTOFIT +#include FT_CONFIG_STANDARD_LIBRARY_H +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** D E B U G G I N G *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#ifdef FT_DEBUG_AUTOFIT + +extern int _af_debug_disable_horz_hints; +extern int _af_debug_disable_vert_hints; +extern int _af_debug_disable_blue_hints; +extern void* _af_debug_hints; + +#endif /* FT_DEBUG_AUTOFIT */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** U T I L I T Y S T U F F *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AF_WidthRec_ + { + FT_Pos org; /* original position/width in font units */ + FT_Pos cur; /* current/scaled position/width in device sub-pixels */ + FT_Pos fit; /* current/fitted position/width in device sub-pixels */ + + } AF_WidthRec, *AF_Width; + + + FT_LOCAL( void ) + af_sort_pos( FT_UInt count, + FT_Pos* table ); + + FT_LOCAL( void ) + af_sort_and_quantize_widths( FT_UInt* count, + AF_Width widths, + FT_Pos threshold ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** A N G L E T Y P E S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The auto-fitter doesn't need a very high angular accuracy; + * this allows us to speed up some computations considerably with a + * light Cordic algorithm (see afangles.c). + */ + + typedef FT_Int AF_Angle; + + +#define AF_ANGLE_PI 256 +#define AF_ANGLE_2PI ( AF_ANGLE_PI * 2 ) +#define AF_ANGLE_PI2 ( AF_ANGLE_PI / 2 ) +#define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 ) + + +#if 0 + /* + * compute the angle of a given 2-D vector + */ + FT_LOCAL( AF_Angle ) + af_angle_atan( FT_Pos dx, + FT_Pos dy ); + + + /* + * compute `angle2 - angle1'; the result is always within + * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1] + */ + FT_LOCAL( AF_Angle ) + af_angle_diff( AF_Angle angle1, + AF_Angle angle2 ); +#endif /* 0 */ + + +#define AF_ANGLE_DIFF( result, angle1, angle2 ) \ + FT_BEGIN_STMNT \ + AF_Angle _delta = (angle2) - (angle1); \ + \ + \ + while ( _delta <= -AF_ANGLE_PI ) \ + _delta += AF_ANGLE_2PI; \ + \ + while ( _delta > AF_ANGLE_PI ) \ + _delta -= AF_ANGLE_2PI; \ + \ + result = _delta; \ + FT_END_STMNT + + + /* opaque handle to glyph-specific hints -- see `afhints.h' for more + * details + */ + typedef struct AF_GlyphHintsRec_* AF_GlyphHints; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S C A L E R S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * A scaler models the target pixel device that will receive the + * auto-hinted glyph image. + */ + +#define AF_SCALER_FLAG_NO_HORIZONTAL 1U /* disable horizontal hinting */ +#define AF_SCALER_FLAG_NO_VERTICAL 2U /* disable vertical hinting */ +#define AF_SCALER_FLAG_NO_ADVANCE 4U /* disable advance hinting */ +#define AF_SCALER_FLAG_NO_WARPER 8U /* disable warper */ + + + typedef struct AF_ScalerRec_ + { + FT_Face face; /* source font face */ + FT_Fixed x_scale; /* from font units to 1/64th device pixels */ + FT_Fixed y_scale; /* from font units to 1/64th device pixels */ + FT_Pos x_delta; /* in 1/64th device pixels */ + FT_Pos y_delta; /* in 1/64th device pixels */ + FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc. */ + FT_UInt32 flags; /* additional control flags, see above */ + + } AF_ScalerRec, *AF_Scaler; + + +#define AF_SCALER_EQUAL_SCALES( a, b ) \ + ( (a)->x_scale == (b)->x_scale && \ + (a)->y_scale == (b)->y_scale && \ + (a)->x_delta == (b)->x_delta && \ + (a)->y_delta == (b)->y_delta ) + + + typedef struct AF_StyleMetricsRec_* AF_StyleMetrics; + + /* This function parses an FT_Face to compute global metrics for + * a specific style. + */ + typedef FT_Error + (*AF_WritingSystem_InitMetricsFunc)( AF_StyleMetrics metrics, + FT_Face face ); + + typedef void + (*AF_WritingSystem_ScaleMetricsFunc)( AF_StyleMetrics metrics, + AF_Scaler scaler ); + + typedef void + (*AF_WritingSystem_DoneMetricsFunc)( AF_StyleMetrics metrics ); + + typedef void + (*AF_WritingSystem_GetStdWidthsFunc)( AF_StyleMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ); + + + typedef FT_Error + (*AF_WritingSystem_InitHintsFunc)( AF_GlyphHints hints, + AF_StyleMetrics metrics ); + + typedef void + (*AF_WritingSystem_ApplyHintsFunc)( FT_UInt glyph_index, + AF_GlyphHints hints, + FT_Outline* outline, + AF_StyleMetrics metrics ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** W R I T I N G S Y S T E M S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * For the auto-hinter, a writing system consists of multiple scripts that + * can be handled similarly *in a typographical way*; the relationship is + * not based on history. For example, both the Greek and the unrelated + * Armenian scripts share the same features like ascender, descender, + * x-height, etc. Essentially, a writing system is covered by a + * submodule of the auto-fitter; it contains + * + * - a specific global analyzer that computes global metrics specific to + * the script (based on script-specific characters to identify ascender + * height, x-height, etc.), + * + * - a specific glyph analyzer that computes segments and edges for each + * glyph covered by the script, + * + * - a specific grid-fitting algorithm that distorts the scaled glyph + * outline according to the results of the glyph analyzer. + */ + +#define AFWRTSYS_H_ /* don't load header files */ +#undef WRITING_SYSTEM +#define WRITING_SYSTEM( ws, WS ) \ + AF_WRITING_SYSTEM_ ## WS, + + /* The list of known writing systems. */ + typedef enum AF_WritingSystem_ + { + +#include "afwrtsys.h" + + AF_WRITING_SYSTEM_MAX /* do not remove */ + + } AF_WritingSystem; + +#undef AFWRTSYS_H_ + + + typedef struct AF_WritingSystemClassRec_ + { + AF_WritingSystem writing_system; + + FT_Offset style_metrics_size; + AF_WritingSystem_InitMetricsFunc style_metrics_init; + AF_WritingSystem_ScaleMetricsFunc style_metrics_scale; + AF_WritingSystem_DoneMetricsFunc style_metrics_done; + AF_WritingSystem_GetStdWidthsFunc style_metrics_getstdw; + + AF_WritingSystem_InitHintsFunc style_hints_init; + AF_WritingSystem_ApplyHintsFunc style_hints_apply; + + } AF_WritingSystemClassRec; + + typedef const AF_WritingSystemClassRec* AF_WritingSystemClass; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S C R I P T S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * Each script is associated with two sets of Unicode ranges to test + * whether the font face supports the script, and which non-base + * characters the script contains. + * + * We use four-letter script tags from the OpenType specification, + * extended by `NONE', which indicates `no script'. + */ + +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) \ + AF_SCRIPT_ ## S, + + /* The list of known scripts. */ + typedef enum AF_Script_ + { + +#include "afscript.h" + + AF_SCRIPT_MAX /* do not remove */ + + } AF_Script; + + + typedef struct AF_Script_UniRangeRec_ + { + FT_UInt32 first; + FT_UInt32 last; + + } AF_Script_UniRangeRec; + +#define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) } + + typedef const AF_Script_UniRangeRec* AF_Script_UniRange; + + + typedef struct AF_ScriptClassRec_ + { + AF_Script script; + + /* last element in the ranges must be { 0, 0 } */ + AF_Script_UniRange script_uni_ranges; + AF_Script_UniRange script_uni_nonbase_ranges; + + FT_Bool top_to_bottom_hinting; + + const char* standard_charstring; /* for default width and height */ + + } AF_ScriptClassRec; + + typedef const AF_ScriptClassRec* AF_ScriptClass; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C O V E R A G E S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * Usually, a font contains more glyphs than can be addressed by its + * character map. + * + * In the PostScript font world, encoding vectors specific to a given + * task are used to select such glyphs, and these glyphs can be often + * recognized by having a suffix in its glyph names. For example, a + * superscript glyph `A' might be called `A.sup'. Unfortunately, this + * naming scheme is not standardized and thus unusable for us. + * + * In the OpenType world, a better solution was invented, namely + * `features', which cleanly separate a character's input encoding from + * the corresponding glyph's appearance, and which don't use glyph names + * at all. For our purposes, and slightly generalized, an OpenType + * feature is a name of a mapping that maps character codes to + * non-standard glyph indices (features get used for other things also). + * For example, the `sups' feature provides superscript glyphs, thus + * mapping character codes like `A' or `B' to superscript glyph + * representation forms. How this mapping happens is completely + * uninteresting to us. + * + * For the auto-hinter, a `coverage' represents all glyphs of an OpenType + * feature collected in a set (as listed below) that can be hinted + * together. To continue the above example, superscript glyphs must not + * be hinted together with normal glyphs because the blue zones + * completely differ. + * + * Note that FreeType itself doesn't compute coverages; it only provides + * the glyphs addressable by the default Unicode character map. Instead, + * we use the HarfBuzz library (if available), which has many functions + * exactly for this purpose. + * + * AF_COVERAGE_DEFAULT is special: It should cover everything that isn't + * listed separately (including the glyphs addressable by the character + * map). In case HarfBuzz isn't available, it exactly covers the glyphs + * addressable by the character map. + * + */ + +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + AF_COVERAGE_ ## NAME, + + + typedef enum AF_Coverage_ + { +#include "afcover.h" + + AF_COVERAGE_DEFAULT + + } AF_Coverage; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S T Y L E S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The topmost structure for modelling the auto-hinter glyph input data + * is a `style class', grouping everything together. + */ + +#undef STYLE +#define STYLE( s, S, d, ws, sc, ss, c ) \ + AF_STYLE_ ## S, + + /* The list of known styles. */ + typedef enum AF_Style_ + { + +#include "afstyles.h" + + AF_STYLE_MAX /* do not remove */ + + } AF_Style; + + + typedef struct AF_StyleClassRec_ + { + AF_Style style; + + AF_WritingSystem writing_system; + AF_Script script; + AF_Blue_Stringset blue_stringset; + AF_Coverage coverage; + + } AF_StyleClassRec; + + typedef const AF_StyleClassRec* AF_StyleClass; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S T Y L E M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; + + /* This is the main structure that combines everything. Autofit modules */ + /* specific to writing systems derive their structures from it, for */ + /* example `AF_LatinMetrics'. */ + + typedef struct AF_StyleMetricsRec_ + { + AF_StyleClass style_class; + AF_ScalerRec scaler; + FT_Bool digits_have_same_width; + + AF_FaceGlobals globals; /* to access properties */ + + } AF_StyleMetricsRec; + + +#define AF_HINTING_BOTTOM_TO_TOP 0 +#define AF_HINTING_TOP_TO_BOTTOM 1 + + + /* Declare and define vtables for classes */ +#ifndef FT_CONFIG_OPTION_PIC + +#define AF_DECLARE_WRITING_SYSTEM_CLASS( writing_system_class ) \ + FT_CALLBACK_TABLE const AF_WritingSystemClassRec \ + writing_system_class; + +#define AF_DEFINE_WRITING_SYSTEM_CLASS( \ + writing_system_class, \ + system, \ + m_size, \ + m_init, \ + m_scale, \ + m_done, \ + m_stdw, \ + h_init, \ + h_apply ) \ + FT_CALLBACK_TABLE_DEF \ + const AF_WritingSystemClassRec writing_system_class = \ + { \ + system, \ + \ + m_size, \ + \ + m_init, \ + m_scale, \ + m_done, \ + m_stdw, \ + \ + h_init, \ + h_apply \ + }; + + +#define AF_DECLARE_SCRIPT_CLASS( script_class ) \ + FT_CALLBACK_TABLE const AF_ScriptClassRec \ + script_class; + +#define AF_DEFINE_SCRIPT_CLASS( \ + script_class, \ + script, \ + ranges, \ + nonbase_ranges, \ + top_to_bottom, \ + std_charstring ) \ + FT_CALLBACK_TABLE_DEF \ + const AF_ScriptClassRec script_class = \ + { \ + script, \ + ranges, \ + nonbase_ranges, \ + top_to_bottom, \ + std_charstring, \ + }; + + +#define AF_DECLARE_STYLE_CLASS( style_class ) \ + FT_CALLBACK_TABLE const AF_StyleClassRec \ + style_class; + +#define AF_DEFINE_STYLE_CLASS( \ + style_class, \ + style, \ + writing_system, \ + script, \ + blue_stringset, \ + coverage ) \ + FT_CALLBACK_TABLE_DEF \ + const AF_StyleClassRec style_class = \ + { \ + style, \ + writing_system, \ + script, \ + blue_stringset, \ + coverage \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define AF_DECLARE_WRITING_SYSTEM_CLASS( writing_system_class ) \ + FT_LOCAL( void ) \ + FT_Init_Class_ ## writing_system_class( AF_WritingSystemClassRec* ac ); + +#define AF_DEFINE_WRITING_SYSTEM_CLASS( \ + writing_system_class, \ + system, \ + m_size, \ + m_init, \ + m_scale, \ + m_done, \ + h_init, \ + h_apply ) \ + FT_LOCAL_DEF( void ) \ + FT_Init_Class_ ## writing_system_class( AF_WritingSystemClassRec* ac ) \ + { \ + ac->writing_system = system; \ + \ + ac->style_metrics_size = m_size; \ + \ + ac->style_metrics_init = m_init; \ + ac->style_metrics_scale = m_scale; \ + ac->style_metrics_done = m_done; \ + ac->style_metrics_getstdw = m_stdw; \ + \ + ac->style_hints_init = h_init; \ + ac->style_hints_apply = h_apply; \ + } + + +#define AF_DECLARE_SCRIPT_CLASS( script_class ) \ + FT_LOCAL( void ) \ + FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ); + +#define AF_DEFINE_SCRIPT_CLASS( \ + script_class, \ + script_, \ + ranges, \ + nonbase_ranges, \ + top_to_bottom, \ + std_charstring ) \ + FT_LOCAL_DEF( void ) \ + FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ) \ + { \ + ac->script = script_; \ + ac->script_uni_ranges = ranges; \ + ac->script_uni_nonbase_ranges = nonbase_ranges; \ + ac->top_to_bottom_hinting = top_to_bottom; \ + ac->standard_charstring = std_charstring; \ + } + + +#define AF_DECLARE_STYLE_CLASS( style_class ) \ + FT_LOCAL( void ) \ + FT_Init_Class_ ## style_class( AF_StyleClassRec* ac ); + +#define AF_DEFINE_STYLE_CLASS( \ + style_class, \ + style_, \ + writing_system_, \ + script_, \ + blue_stringset_, \ + coverage_ ) \ + FT_LOCAL_DEF( void ) \ + FT_Init_Class_ ## style_class( AF_StyleClassRec* ac ) \ + { \ + ac->style = style_; \ + ac->writing_system = writing_system_; \ + ac->script = script_; \ + ac->blue_stringset = blue_stringset_; \ + ac->coverage = coverage_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* */ + +FT_END_HEADER + +#endif /* AFTYPES_H_ */ + + +/* END */ diff --git a/drivers/freetype/freetype/src/autofit/afwarp.c b/drivers/freetype/src/autofit/afwarp.c index 34a97ffc57..ce1806c9d3 100644 --- a/drivers/freetype/freetype/src/autofit/afwarp.c +++ b/drivers/freetype/src/autofit/afwarp.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter warping algorithm (body). */ /* */ -/* Copyright 2006, 2007, 2011 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -76,10 +76,10 @@ FT_Pos xx2, AF_WarpScore base_distort, AF_Segment segments, - FT_UInt num_segments ) + FT_Int num_segments ) { FT_Int idx_min, idx_max, idx0; - FT_UInt nn; + FT_Int nn; AF_WarpScore scores[65]; @@ -171,7 +171,7 @@ FT_Fixed org_scale; FT_Pos org_delta; - FT_UInt nn, num_points, num_segments; + FT_Int nn, num_points, num_segments; FT_Int X1, X2; FT_Int w; @@ -193,7 +193,7 @@ warper->best_scale = org_scale; warper->best_delta = org_delta; - warper->best_score = INT_MIN; + warper->best_score = FT_INT_MIN; warper->best_distort = 0; axis = &hints->axis[dim]; diff --git a/drivers/freetype/freetype/src/autofit/afwarp.h b/drivers/freetype/src/autofit/afwarp.h index 7343fdd5ef..6d96f86d73 100644 --- a/drivers/freetype/freetype/src/autofit/afwarp.h +++ b/drivers/freetype/src/autofit/afwarp.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter warping algorithm (specification). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFWARP_H__ -#define __AFWARP_H__ +#ifndef AFWARP_H_ +#define AFWARP_H_ #include "afhints.h" @@ -25,7 +25,7 @@ FT_BEGIN_HEADER #define AF_WARPER_SCALE -#define AF_WARPER_FLOOR( x ) ( (x) & ~63 ) +#define AF_WARPER_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 ) #define AF_WARPER_CEIL( x ) AF_WARPER_FLOOR( (x) + 63 ) @@ -58,7 +58,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFWARP_H__ */ +#endif /* AFWARP_H_ */ /* END */ diff --git a/drivers/freetype/src/autofit/afwrtsys.h b/drivers/freetype/src/autofit/afwrtsys.h new file mode 100644 index 0000000000..842f4921a4 --- /dev/null +++ b/drivers/freetype/src/autofit/afwrtsys.h @@ -0,0 +1,52 @@ +/***************************************************************************/ +/* */ +/* afwrtsys.h */ +/* */ +/* Auto-fitter writing systems (specification only). */ +/* */ +/* Copyright 2013-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef AFWRTSYS_H_ +#define AFWRTSYS_H_ + + /* Since preprocessor directives can't create other preprocessor */ + /* directives, we have to include the header files manually. */ + +#include "afdummy.h" +#include "aflatin.h" +#include "afcjk.h" +#include "afindic.h" +#ifdef FT_OPTION_AUTOFIT2 +#include "aflatin2.h" +#endif + +#endif /* AFWRTSYS_H_ */ + + + /* The following part can be included multiple times. */ + /* Define `WRITING_SYSTEM' as needed. */ + + + /* Add new writing systems here. The arguments are the writing system */ + /* name in lowercase and uppercase, respectively. */ + + WRITING_SYSTEM( dummy, DUMMY ) + WRITING_SYSTEM( latin, LATIN ) + WRITING_SYSTEM( cjk, CJK ) + WRITING_SYSTEM( indic, INDIC ) +#ifdef FT_OPTION_AUTOFIT2 + WRITING_SYSTEM( latin2, LATIN2 ) +#endif + + +/* END */ diff --git a/drivers/freetype/freetype/src/autofit/autofit.c b/drivers/freetype/src/autofit/autofit.c index 3883a0a706..dda9aeb6d7 100644 --- a/drivers/freetype/freetype/src/autofit/autofit.c +++ b/drivers/freetype/src/autofit/autofit.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter module (body). */ /* */ -/* Copyright 2003-2007, 2011 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,9 +20,12 @@ #include <ft2build.h> #include "afpic.c" #include "afangles.c" +#include "afblue.c" #include "afglobal.c" #include "afhints.c" +#include "afranges.c" + #include "afdummy.c" #include "aflatin.c" #ifdef FT_OPTION_AUTOFIT2 @@ -31,6 +34,8 @@ #include "afcjk.c" #include "afindic.c" +#include "afshaper.c" + #include "afloader.c" #include "afmodule.c" diff --git a/drivers/freetype/freetype/src/autofit/module.mk b/drivers/freetype/src/autofit/module.mk index 6ec60912ab..98f0612b99 100644 --- a/drivers/freetype/freetype/src/autofit/module.mk +++ b/drivers/freetype/src/autofit/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2003, 2004, 2005, 2006 by +# Copyright 2003-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/autofit/rules.mk b/drivers/freetype/src/autofit/rules.mk index b76bb79ab4..1ef4704649 100644 --- a/drivers/freetype/freetype/src/autofit/rules.mk +++ b/drivers/freetype/src/autofit/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2003, 2004, 2005, 2006, 2007, 2011 by +# Copyright 2003-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,12 +20,16 @@ AUTOF_DIR := $(SRC_DIR)/autofit # compilation flags for the driver # -AUTOF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(AUTOF_DIR)) +AUTOF_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(AUTOF_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # AUTOF driver sources (i.e., C files) # AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ + $(AUTOF_DIR)/afblue.c \ $(AUTOF_DIR)/afcjk.c \ $(AUTOF_DIR)/afdummy.c \ $(AUTOF_DIR)/afglobal.c \ @@ -35,13 +39,19 @@ AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ $(AUTOF_DIR)/afloader.c \ $(AUTOF_DIR)/afmodule.c \ $(AUTOF_DIR)/afpic.c \ + $(AUTOF_DIR)/afranges.c \ + $(AUTOF_DIR)/afshaper.c \ $(AUTOF_DIR)/afwarp.c # AUTOF driver headers # AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \ + $(AUTOF_DIR)/afcover.h \ $(AUTOF_DIR)/aferrors.h \ - $(AUTOF_DIR)/aftypes.h + $(AUTOF_DIR)/afscript.h \ + $(AUTOF_DIR)/afstyles.h \ + $(AUTOF_DIR)/aftypes.h \ + $(AUTOF_DIR)/afwrtsys.h # AUTOF driver object(s) diff --git a/drivers/freetype/src/base/Jamfile b/drivers/freetype/src/base/Jamfile new file mode 100644 index 0000000000..cfc69657fe --- /dev/null +++ b/drivers/freetype/src/base/Jamfile @@ -0,0 +1,88 @@ +# FreeType 2 src/base Jamfile +# +# Copyright 2001-2016 by +# David Turner, Robert Wilhelm, and Werner Lemberg. +# +# This file is part of the FreeType project, and may only be used, modified, +# and distributed under the terms of the FreeType project license, +# LICENSE.TXT. By continuing to use, modify, or distribute this file you +# indicate that you have read the license and understand and accept it +# fully. + +SubDir FT2_TOP $(FT2_SRC_DIR) base ; + + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = basepic + ftadvanc + ftcalc + ftdbgmem + ftgloadr + fthash + ftobjs + ftoutln + ftpic + ftrfork + ftsnames + ftstream + fttrigon + ftutil + ; + } + else + { + _sources = ftbase ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# Add the optional/replaceable files. +# +{ + local _sources = ftapi + ftbbox + ftbdf + ftbitmap + ftcid + ftdebug + ftfntfmt + ftfstype + ftgasp + ftglyph + ftgxval + ftinit + ftlcdfil + ftmm + ftotval + ftpatent + ftpfr + ftstroke + ftsynth + ftsystem + fttype1 + ftwinfnt + ; + + Library $(FT2_LIB) : $(_sources).c ; +} + +# Add Macintosh-specific file to the library when necessary. +# +if $(MAC) +{ + Library $(FT2_LIB) : ftmac.c ; +} +else if $(OS) = MACOSX +{ + if $(FT2_MULTI) + { + Library $(FT2_LIB) : ftmac.c ; + } +} + +# end of src/base Jamfile diff --git a/drivers/freetype/freetype/src/base/basepic.c b/drivers/freetype/src/base/basepic.c index 0af770ebc2..f2cea90d7c 100644 --- a/drivers/freetype/freetype/src/base/basepic.c +++ b/drivers/freetype/src/base/basepic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009, 2012 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,7 @@ /* forward declaration of PIC init function from ftrfork.c */ /* (not modularized) */ void - FT_Init_Table_raccess_guess_table( ft_raccess_guess_rec* record ); + FT_Init_Table_ft_raccess_guess_table( ft_raccess_guess_rec* record ); #endif /* forward declaration of PIC init functions from ftinit.c */ @@ -92,7 +92,7 @@ FT_Init_Class_ft_bitmap_glyph_class( &container->ft_bitmap_glyph_class ); #ifdef FT_CONFIG_OPTION_MAC_FONTS - FT_Init_Table_raccess_guess_table( + FT_Init_Table_ft_raccess_guess_table( (ft_raccess_guess_rec*)&container->ft_raccess_guess_table ); #endif diff --git a/drivers/freetype/freetype/src/base/basepic.h b/drivers/freetype/src/base/basepic.h index 329d7c8fd6..a1a75a0bad 100644 --- a/drivers/freetype/freetype/src/base/basepic.h +++ b/drivers/freetype/src/base/basepic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,14 +16,13 @@ /***************************************************************************/ -#ifndef __BASEPIC_H__ -#define __BASEPIC_H__ +#ifndef BASEPIC_H_ +#define BASEPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H + #ifndef FT_CONFIG_OPTION_PIC #define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class @@ -43,6 +42,8 @@ FT_BEGIN_HEADER #endif +FT_BEGIN_HEADER + typedef struct BasePIC_ { FT_Module_Class** default_module_classes; @@ -78,13 +79,13 @@ FT_BEGIN_HEADER FT_Error ft_base_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __BASEPIC_H__ */ +#endif /* BASEPIC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/base/ftadvanc.c b/drivers/freetype/src/base/ftadvanc.c index 52078478df..9e2ab89845 100644 --- a/drivers/freetype/freetype/src/base/ftadvanc.c +++ b/drivers/freetype/src/base/ftadvanc.c @@ -4,7 +4,7 @@ /* */ /* Quick computation of advance widths (body). */ /* */ -/* Copyright 2008, 2009, 2011, 2013 by */ +/* Copyright 2008-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -60,10 +60,12 @@ /* - unscaled load */ /* - unhinted load */ /* - light-hinted load */ + /* - neither a MM nor a GX font */ -#define LOAD_ADVANCE_FAST_CHECK( flags ) \ - ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ - FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) +#define LOAD_ADVANCE_FAST_CHECK( face, flags ) \ + ( ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ + FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) && \ + !FT_HAS_MULTIPLE_MASTERS( face ) ) /* documentation is in ftadvanc.h */ @@ -80,11 +82,14 @@ if ( !face ) return FT_THROW( Invalid_Face_Handle ); + if ( !padvance ) + return FT_THROW( Invalid_Argument ); + if ( gindex >= (FT_UInt)face->num_glyphs ) return FT_THROW( Invalid_Glyph_Index ); func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) ) { FT_Error error; @@ -118,6 +123,9 @@ if ( !face ) return FT_THROW( Invalid_Face_Handle ); + if ( !padvances ) + return FT_THROW( Invalid_Argument ); + num = (FT_UInt)face->num_glyphs; end = start + count; if ( start >= num || end < start || end > num ) @@ -127,7 +135,7 @@ return FT_Err_Ok; func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) ) { error = func( face, start, count, flags, padvances ); if ( !error ) @@ -151,8 +159,8 @@ /* scale from 26.6 to 16.16 */ padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) - ? face->glyph->advance.y << 10 - : face->glyph->advance.x << 10; + ? face->glyph->advance.y * 1024 + : face->glyph->advance.x * 1024; } return error; diff --git a/drivers/freetype/freetype/src/base/ftapi.c b/drivers/freetype/src/base/ftapi.c index 8914d1f4e9..b94c3eb9fb 100644 --- a/drivers/freetype/freetype/src/base/ftapi.c +++ b/drivers/freetype/src/base/ftapi.c @@ -4,7 +4,7 @@ /* */ /* The FreeType compatibility functions (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/base/ftbase.c b/drivers/freetype/src/base/ftbase.c index 5e5d70ec4b..ab1af6f9f3 100644 --- a/drivers/freetype/freetype/src/base/ftbase.c +++ b/drivers/freetype/src/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,7 @@ #include "ftcalc.c" #include "ftdbgmem.c" #include "ftgloadr.c" +#include "fthash.c" #include "ftobjs.c" #include "ftoutln.c" #include "ftrfork.c" diff --git a/drivers/freetype/freetype/src/base/ftbase.h b/drivers/freetype/src/base/ftbase.h index 51a1db18b8..717fdaae24 100644 --- a/drivers/freetype/freetype/src/base/ftbase.h +++ b/drivers/freetype/src/base/ftbase.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private functions used in base module (specification). */ /* */ -/* Copyright 2008, 2010 by */ +/* Copyright 2008-2016 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBASE_H__ -#define __FTBASE_H__ +#ifndef FTBASE_H_ +#define FTBASE_H_ #include <ft2build.h> @@ -27,6 +27,11 @@ FT_BEGIN_HEADER + /* MacOS resource fork cannot exceed 16MB at least for Carbon code; */ + /* see https://support.microsoft.com/en-us/kb/130437 */ +#define FT_MAC_RFORK_MAX_LEN 0x00FFFFFFUL + + /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */ /* font, and try to load a face specified by the face_index. */ FT_LOCAL( FT_Error ) @@ -63,7 +68,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBASE_H__ */ +#endif /* FTBASE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/base/ftbbox.c b/drivers/freetype/src/base/ftbbox.c index 6d1c44cb2e..d3e45ffa0d 100644 --- a/drivers/freetype/freetype/src/base/ftbbox.c +++ b/drivers/freetype/src/base/ftbbox.c @@ -4,7 +4,7 @@ /* */ /* FreeType bbox computation (body). */ /* */ -/* Copyright 1996-2002, 2004, 2006, 2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -42,16 +42,35 @@ } TBBox_Rec; +#define FT_UPDATE_BBOX( p, bbox ) \ + FT_BEGIN_STMNT \ + if ( p->x < bbox.xMin ) \ + bbox.xMin = p->x; \ + if ( p->x > bbox.xMax ) \ + bbox.xMax = p->x; \ + if ( p->y < bbox.yMin ) \ + bbox.yMin = p->y; \ + if ( p->y > bbox.yMax ) \ + bbox.yMax = p->y; \ + FT_END_STMNT + +#define CHECK_X( p, bbox ) \ + ( p->x < bbox.xMin || p->x > bbox.xMax ) + +#define CHECK_Y( p, bbox ) \ + ( p->y < bbox.yMin || p->y > bbox.yMax ) + + /*************************************************************************/ /* */ /* <Function> */ /* BBox_Move_To */ /* */ /* <Description> */ - /* This function is used as a `move_to' and `line_to' emitter during */ + /* This function is used as a `move_to' emitter during */ /* FT_Outline_Decompose(). It simply records the destination point */ - /* in `user->last'; no further computations are necessary since we */ - /* use the cbox as the starting bbox which must be refined. */ + /* in `user->last'. We also update bbox in case contour starts with */ + /* an implicit `on' point. */ /* */ /* <Input> */ /* to :: A pointer to the destination vector. */ @@ -66,17 +85,42 @@ BBox_Move_To( FT_Vector* to, TBBox_Rec* user ) { + FT_UPDATE_BBOX( to, user->bbox ); + user->last = *to; return 0; } -#define CHECK_X( p, bbox ) \ - ( p->x < bbox.xMin || p->x > bbox.xMax ) + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Line_To */ + /* */ + /* <Description> */ + /* This function is used as a `line_to' emitter during */ + /* FT_Outline_Decompose(). It simply records the destination point */ + /* in `user->last'; no further computations are necessary because */ + /* bbox already contains both explicit ends of the line segment. */ + /* */ + /* <Input> */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: A pointer to the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + static int + BBox_Line_To( FT_Vector* to, + TBBox_Rec* user ) + { + user->last = *to; -#define CHECK_Y( p, bbox ) \ - ( p->y < bbox.yMin || p->y > bbox.yMax ) + return 0; + } /*************************************************************************/ @@ -85,7 +129,7 @@ /* BBox_Conic_Check */ /* */ /* <Description> */ - /* Finds the extrema of a 1-dimensional conic Bezier curve and update */ + /* Find the extrema of a 1-dimensional conic Bezier curve and update */ /* a bounding range. This version uses direct computation, as it */ /* doesn't need square roots. */ /* */ @@ -108,30 +152,19 @@ FT_Pos* min, FT_Pos* max ) { - if ( y1 <= y3 && y2 == y1 ) /* flat arc */ - goto Suite; - - if ( y1 < y3 ) - { - if ( y2 >= y1 && y2 <= y3 ) /* ascending arc */ - goto Suite; - } - else - { - if ( y2 >= y3 && y2 <= y1 ) /* descending arc */ - { - y2 = y1; - y1 = y3; - y3 = y2; - goto Suite; - } - } - - y1 = y3 = y1 - FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 ); - - Suite: - if ( y1 < *min ) *min = y1; - if ( y3 > *max ) *max = y3; + /* This function is only called when a control off-point is outside */ + /* the bbox that contains all on-points. It finds a local extremum */ + /* within the segment, equal to (y1*y3 - y2*y2)/(y1 - 2*y2 + y3). */ + /* Or, offsetting from y2, we get */ + + y1 -= y2; + y3 -= y2; + y2 += FT_MulDiv( y1, y3, y1 + y3 ); + + if ( y2 < *min ) + *min = y2; + if ( y2 > *max ) + *max = y2; } @@ -166,8 +199,8 @@ FT_Vector* to, TBBox_Rec* user ) { - /* we don't need to check `to' since it is always an `on' point, thus */ - /* within the bbox */ + /* in case `to' is implicit and not included in bbox yet */ + FT_UPDATE_BBOX( to, user->bbox ); if ( CHECK_X( control, user->bbox ) ) BBox_Conic_Check( user->last.x, @@ -195,9 +228,9 @@ /* BBox_Cubic_Check */ /* */ /* <Description> */ - /* Finds the extrema of a 1-dimensional cubic Bezier curve and */ - /* updates a bounding range. This version uses splitting because we */ - /* don't want to use square roots and extra accuracy. */ + /* Find the extrema of a 1-dimensional cubic Bezier curve and */ + /* update a bounding range. This version uses iterative splitting */ + /* because it is faster than the exact solution with square roots. */ /* */ /* <Input> */ /* p1 :: The start coordinate. */ @@ -213,28 +246,52 @@ /* */ /* max :: The address of the current maximum. */ /* */ + static FT_Pos + cubic_peak( FT_Pos q1, + FT_Pos q2, + FT_Pos q3, + FT_Pos q4 ) + { + FT_Pos peak = 0; + FT_Int shift; -#if 0 - static void - BBox_Cubic_Check( FT_Pos p1, - FT_Pos p2, - FT_Pos p3, - FT_Pos p4, - FT_Pos* min, - FT_Pos* max ) - { - FT_Pos q1, q2, q3, q4; + /* This function finds a peak of a cubic segment if it is above 0 */ + /* using iterative bisection of the segment, or returns 0. */ + /* The fixed-point arithmetic of bisection is inherently stable */ + /* but may loose accuracy in the two lowest bits. To compensate, */ + /* we upscale the segment if there is room. Large values may need */ + /* to be downscaled to avoid overflows during bisection. */ + /* It is called with either q2 or q3 positive, which is necessary */ + /* for the peak to exist and avoids undefined FT_MSB. */ + shift = 27 - FT_MSB( (FT_UInt32)( FT_ABS( q1 ) | + FT_ABS( q2 ) | + FT_ABS( q3 ) | + FT_ABS( q4 ) ) ); - q1 = p1; - q2 = p2; - q3 = p3; - q4 = p4; + if ( shift > 0 ) + { + /* upscaling too much just wastes time */ + if ( shift > 2 ) + shift = 2; + + q1 <<= shift; + q2 <<= shift; + q3 <<= shift; + q4 <<= shift; + } + else + { + q1 >>= -shift; + q2 >>= -shift; + q3 >>= -shift; + q4 >>= -shift; + } - /* for a conic segment to possibly reach new maximum */ - /* one of its off-points must be above the current value */ - while ( q2 > *max || q3 > *max ) + /* for a peak to exist above 0, the cubic segment must have */ + /* at least one of its control off-points above 0. */ + while ( q2 > 0 || q3 > 0 ) { /* determine which half contains the maximum and split */ if ( q1 + q2 > q3 + q4 ) /* first half */ @@ -260,232 +317,49 @@ q3 = q3 / 2; } - /* check if either end reached the maximum */ + /* check whether either end reached the maximum */ if ( q1 == q2 && q1 >= q3 ) { - *max = q1; + peak = q1; break; } if ( q3 == q4 && q2 <= q4 ) { - *max = q4; - break; - } - } - - q1 = p1; - q2 = p2; - q3 = p3; - q4 = p4; - - /* for a conic segment to possibly reach new minimum */ - /* one of its off-points must be below the current value */ - while ( q2 < *min || q3 < *min ) - { - /* determine which half contains the minimum and split */ - if ( q1 + q2 < q3 + q4 ) /* first half */ - { - q4 = q4 + q3; - q3 = q3 + q2; - q2 = q2 + q1; - q4 = q4 + q3; - q3 = q3 + q2; - q4 = ( q4 + q3 ) / 8; - q3 = q3 / 4; - q2 = q2 / 2; - } - else /* second half */ - { - q1 = q1 + q2; - q2 = q2 + q3; - q3 = q3 + q4; - q1 = q1 + q2; - q2 = q2 + q3; - q1 = ( q1 + q2 ) / 8; - q2 = q2 / 4; - q3 = q3 / 2; - } - - /* check if either end reached the minimum */ - if ( q1 == q2 && q1 <= q3 ) - { - *min = q1; - break; - } - if ( q3 == q4 && q2 >= q4 ) - { - *min = q4; + peak = q4; break; } } - } -#else - - static void - test_cubic_extrema( FT_Pos y1, - FT_Pos y2, - FT_Pos y3, - FT_Pos y4, - FT_Fixed u, - FT_Pos* min, - FT_Pos* max ) - { - /* FT_Pos a = y4 - 3*y3 + 3*y2 - y1; */ - FT_Pos b = y3 - 2*y2 + y1; - FT_Pos c = y2 - y1; - FT_Pos d = y1; - FT_Pos y; - FT_Fixed uu; - - FT_UNUSED ( y4 ); - - - /* The polynomial is */ - /* */ - /* P(x) = a*x^3 + 3b*x^2 + 3c*x + d , */ - /* */ - /* dP/dx = 3a*x^2 + 6b*x + 3c . */ - /* */ - /* However, we also have */ - /* */ - /* dP/dx(u) = 0 , */ - /* */ - /* which implies by subtraction that */ - /* */ - /* P(u) = b*u^2 + 2c*u + d . */ - - if ( u > 0 && u < 0x10000L ) - { - uu = FT_MulFix( u, u ); - y = d + FT_MulFix( c, 2*u ) + FT_MulFix( b, uu ); + if ( shift > 0 ) + peak >>= shift; + else + peak <<= -shift; - if ( y < *min ) *min = y; - if ( y > *max ) *max = y; - } + return peak; } static void - BBox_Cubic_Check( FT_Pos y1, - FT_Pos y2, - FT_Pos y3, - FT_Pos y4, + BBox_Cubic_Check( FT_Pos p1, + FT_Pos p2, + FT_Pos p3, + FT_Pos p4, FT_Pos* min, FT_Pos* max ) { - /* always compare first and last points */ - if ( y1 < *min ) *min = y1; - else if ( y1 > *max ) *max = y1; - - if ( y4 < *min ) *min = y4; - else if ( y4 > *max ) *max = y4; - - /* now, try to see if there are split points here */ - if ( y1 <= y4 ) - { - /* flat or ascending arc test */ - if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 ) - return; - } - else /* y1 > y4 */ - { - /* descending arc test */ - if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 ) - return; - } - - /* There are some split points. Find them. */ - /* We already made sure that a, b, and c below cannot be all zero. */ - { - FT_Pos a = y4 - 3*y3 + 3*y2 - y1; - FT_Pos b = y3 - 2*y2 + y1; - FT_Pos c = y2 - y1; - FT_Pos d; - FT_Fixed t; - FT_Int shift; - - - /* We need to solve `ax^2+2bx+c' here, without floating points! */ - /* The trick is to normalize to a different representation in order */ - /* to use our 16.16 fixed-point routines. */ - /* */ - /* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */ - /* These values must fit into a single 16.16 value. */ - /* */ - /* We normalize a, b, and c to `8.16' fixed-point values to ensure */ - /* that their product is held in a `16.16' value including the sign. */ - /* Necessarily, we need to shift `a', `b', and `c' so that the most */ - /* significant bit of their absolute values is at position 22. */ - /* */ - /* This also means that we are using 23 bits of precision to compute */ - /* the zeros, independently of the range of the original polynomial */ - /* coefficients. */ - /* */ - /* This algorithm should ensure reasonably accurate values for the */ - /* zeros. Note that they are only expressed with 16 bits when */ - /* computing the extrema (the zeros need to be in 0..1 exclusive */ - /* to be considered part of the arc). */ - - shift = FT_MSB( FT_ABS( a ) | FT_ABS( b ) | FT_ABS( c ) ); - - if ( shift > 22 ) - { - shift -= 22; - - /* this loses some bits of precision, but we use 23 of them */ - /* for the computation anyway */ - a >>= shift; - b >>= shift; - c >>= shift; - } - else - { - shift = 22 - shift; + /* This function is only called when a control off-point is outside */ + /* the bbox that contains all on-points. So at least one of the */ + /* conditions below holds and cubic_peak is called with at least one */ + /* non-zero argument. */ - a <<= shift; - b <<= shift; - c <<= shift; - } + if ( p2 > *max || p3 > *max ) + *max += cubic_peak( p1 - *max, p2 - *max, p3 - *max, p4 - *max ); - /* handle a == 0 */ - if ( a == 0 ) - { - if ( b != 0 ) - { - t = - FT_DivFix( c, b ) / 2; - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - } - else - { - /* solve the equation now */ - d = FT_MulFix( b, b ) - FT_MulFix( a, c ); - if ( d < 0 ) - return; - - if ( d == 0 ) - { - /* there is a single split point at -b/a */ - t = - FT_DivFix( b, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - else - { - /* there are two solutions; we need to filter them */ - d = FT_SqrtFixed( (FT_Int32)d ); - t = - FT_DivFix( b - d, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - - t = - FT_DivFix( b + d, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - } - } + /* now flip the signs to update the minimum */ + if ( p2 < *min || p3 < *min ) + *min -= cubic_peak( *min - p1, *min - p2, *min - p3, *min - p4 ); } -#endif - /*************************************************************************/ /* */ @@ -521,8 +395,9 @@ FT_Vector* to, TBBox_Rec* user ) { - /* we don't need to check `to' since it is always an `on' point, thus */ - /* within the bbox */ + /* We don't need to check `to' since it is always an on-point, */ + /* thus within the bbox. Only segments with an off-point outside */ + /* the bbox can possibly reach new extreme values. */ if ( CHECK_X( control1, user->bbox ) || CHECK_X( control2, user->bbox ) ) @@ -547,22 +422,26 @@ return 0; } -FT_DEFINE_OUTLINE_FUNCS(bbox_interface, + + FT_DEFINE_OUTLINE_FUNCS(bbox_interface, (FT_Outline_MoveTo_Func) BBox_Move_To, - (FT_Outline_LineTo_Func) BBox_Move_To, + (FT_Outline_LineTo_Func) BBox_Line_To, (FT_Outline_ConicTo_Func)BBox_Conic_To, (FT_Outline_CubicTo_Func)BBox_Cubic_To, 0, 0 ) + /* documentation is in ftbbox.h */ FT_EXPORT_DEF( FT_Error ) FT_Outline_Get_BBox( FT_Outline* outline, FT_BBox *abbox ) { - FT_BBox cbox; - FT_BBox bbox; + FT_BBox cbox = { 0x7FFFFFFFL, 0x7FFFFFFFL, + -0x7FFFFFFFL, -0x7FFFFFFFL }; + FT_BBox bbox = { 0x7FFFFFFFL, 0x7FFFFFFFL, + -0x7FFFFFFFL, -0x7FFFFFFFL }; FT_Vector* vec; FT_UShort n; @@ -586,32 +465,13 @@ FT_DEFINE_OUTLINE_FUNCS(bbox_interface, /* coincide, we exit immediately. */ vec = outline->points; - bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x; - bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y; - vec++; - for ( n = 1; n < outline->n_points; n++ ) + for ( n = 0; n < outline->n_points; n++ ) { - FT_Pos x = vec->x; - FT_Pos y = vec->y; - - - /* update control box */ - if ( x < cbox.xMin ) cbox.xMin = x; - if ( x > cbox.xMax ) cbox.xMax = x; - - if ( y < cbox.yMin ) cbox.yMin = y; - if ( y > cbox.yMax ) cbox.yMax = y; + FT_UPDATE_BBOX( vec, cbox); if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON ) - { - /* update bbox for `on' points only */ - if ( x < bbox.xMin ) bbox.xMin = x; - if ( x > bbox.xMax ) bbox.xMax = x; - - if ( y < bbox.yMin ) bbox.yMin = y; - if ( y > bbox.yMax ) bbox.yMax = y; - } + FT_UPDATE_BBOX( vec, bbox); vec++; } diff --git a/drivers/freetype/freetype/src/base/ftbdf.c b/drivers/freetype/src/base/ftbdf.c index 5755f8558d..4aafc2b98e 100644 --- a/drivers/freetype/freetype/src/base/ftbdf.c +++ b/drivers/freetype/src/base/ftbdf.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (body). */ /* */ -/* Copyright 2002-2004, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,8 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_BDF_H @@ -32,19 +34,18 @@ const char* encoding = NULL; const char* registry = NULL; + FT_Service_BDF service; - error = FT_ERR( Invalid_Argument ); - - if ( face ) - { - FT_Service_BDF service; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); - FT_FACE_FIND_SERVICE( face, service, BDF ); + FT_FACE_FIND_SERVICE( face, service, BDF ); - if ( service && service->get_charset_id ) - error = service->get_charset_id( face, &encoding, ®istry ); - } + if ( service && service->get_charset_id ) + error = service->get_charset_id( face, &encoding, ®istry ); + else + error = FT_THROW( Invalid_Argument ); if ( acharset_encoding ) *acharset_encoding = encoding; @@ -65,23 +66,25 @@ { FT_Error error; + FT_Service_BDF service; - error = FT_ERR( Invalid_Argument ); - aproperty->type = BDF_PROPERTY_TYPE_NONE; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); - if ( face ) - { - FT_Service_BDF service; + if ( !aproperty ) + return FT_THROW( Invalid_Argument ); + aproperty->type = BDF_PROPERTY_TYPE_NONE; - FT_FACE_FIND_SERVICE( face, service, BDF ); + FT_FACE_FIND_SERVICE( face, service, BDF ); - if ( service && service->get_property ) - error = service->get_property( face, prop_name, aproperty ); - } + if ( service && service->get_property ) + error = service->get_property( face, prop_name, aproperty ); + else + error = FT_THROW( Invalid_Argument ); - return error; + return error; } diff --git a/drivers/freetype/freetype/src/base/ftbitmap.c b/drivers/freetype/src/base/ftbitmap.c index 975818e14f..24fead3e15 100644 --- a/drivers/freetype/freetype/src/base/ftbitmap.c +++ b/drivers/freetype/src/base/ftbitmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility functions for bitmaps (body). */ /* */ -/* Copyright 2004-2009, 2011, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,9 +31,20 @@ /* documentation is in ftbitmap.h */ FT_EXPORT_DEF( void ) + FT_Bitmap_Init( FT_Bitmap *abitmap ) + { + if ( abitmap ) + *abitmap = null_bitmap; + } + + + /* deprecated function name; retained for ABI compatibility */ + + FT_EXPORT_DEF( void ) FT_Bitmap_New( FT_Bitmap *abitmap ) { - *abitmap = null_bitmap; + if ( abitmap ) + *abitmap = null_bitmap; } @@ -44,25 +55,42 @@ const FT_Bitmap *source, FT_Bitmap *target) { - FT_Memory memory = library->memory; + FT_Memory memory; FT_Error error = FT_Err_Ok; - FT_Int pitch = source->pitch; - FT_ULong size; + FT_Int pitch; + FT_ULong size; + + FT_Int source_pitch_sign, target_pitch_sign; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !source || !target ) + return FT_THROW( Invalid_Argument ); if ( source == target ) return FT_Err_Ok; + source_pitch_sign = source->pitch < 0 ? -1 : 1; + target_pitch_sign = target->pitch < 0 ? -1 : 1; + if ( source->buffer == NULL ) { *target = *source; + if ( source_pitch_sign != target_pitch_sign ) + target->pitch = -target->pitch; return FT_Err_Ok; } + memory = library->memory; + pitch = source->pitch; + if ( pitch < 0 ) pitch = -pitch; - size = (FT_ULong)( pitch * source->rows ); + size = (FT_ULong)pitch * source->rows; if ( target->buffer ) { @@ -70,9 +98,9 @@ FT_ULong target_size; - if ( target_pitch < 0 ) + if ( target_pitch < 0 ) target_pitch = -target_pitch; - target_size = (FT_ULong)( target_pitch * target->rows ); + target_size = (FT_ULong)target_pitch * target->rows; if ( target_size != size ) (void)FT_QREALLOC( target->buffer, target_size, size ); @@ -89,13 +117,35 @@ *target = *source; target->buffer = p; - FT_MEM_COPY( target->buffer, source->buffer, size ); + if ( source_pitch_sign == target_pitch_sign ) + FT_MEM_COPY( target->buffer, source->buffer, size ); + else + { + /* take care of bitmap flow */ + FT_UInt i; + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + + + t += (FT_ULong)pitch * ( target->rows - 1 ); + + for ( i = target->rows; i > 0; i-- ) + { + FT_ARRAY_COPY( t, s, pitch ); + + s += pitch; + t -= pitch; + } + } } return error; } + /* Enlarge `bitmap' horizontally and vertically by `xpixels' */ + /* and `ypixels', respectively. */ + static FT_Error ft_bitmap_assure_buffer( FT_Memory memory, FT_Bitmap* bitmap, @@ -106,7 +156,7 @@ int pitch; int new_pitch; FT_UInt bpp; - FT_Int i, width, height; + FT_UInt i, width, height; unsigned char* buffer = NULL; @@ -120,21 +170,21 @@ { case FT_PIXEL_MODE_MONO: bpp = 1; - new_pitch = ( width + xpixels + 7 ) >> 3; + new_pitch = (int)( ( width + xpixels + 7 ) >> 3 ); break; case FT_PIXEL_MODE_GRAY2: bpp = 2; - new_pitch = ( width + xpixels + 3 ) >> 2; + new_pitch = (int)( ( width + xpixels + 3 ) >> 2 ); break; case FT_PIXEL_MODE_GRAY4: bpp = 4; - new_pitch = ( width + xpixels + 1 ) >> 1; + new_pitch = (int)( ( width + xpixels + 1 ) >> 1 ); break; case FT_PIXEL_MODE_GRAY: case FT_PIXEL_MODE_LCD: case FT_PIXEL_MODE_LCD_V: bpp = 8; - new_pitch = ( width + xpixels ); + new_pitch = (int)( width + xpixels ); break; default: return FT_THROW( Invalid_Glyph_Format ); @@ -144,17 +194,17 @@ if ( ypixels == 0 && new_pitch <= pitch ) { /* zero the padding */ - FT_Int bit_width = pitch * 8; - FT_Int bit_last = ( width + xpixels ) * bpp; + FT_UInt bit_width = (FT_UInt)pitch * 8; + FT_UInt bit_last = ( width + xpixels ) * bpp; if ( bit_last < bit_width ) { FT_Byte* line = bitmap->buffer + ( bit_last >> 3 ); FT_Byte* end = bitmap->buffer + pitch; - FT_Int shift = bit_last & 7; + FT_UInt shift = bit_last & 7; FT_UInt mask = 0xFF00U >> shift; - FT_Int count = height; + FT_UInt count = height; for ( ; count > 0; count--, line += pitch, end += pitch ) @@ -168,33 +218,38 @@ write++; } if ( write < end ) - FT_MEM_ZERO( write, end-write ); + FT_MEM_ZERO( write, end - write ); } } return FT_Err_Ok; } + /* otherwise allocate new buffer */ if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) ) return error; + /* new rows get added at the top of the bitmap, */ + /* thus take care of the flow direction */ if ( bitmap->pitch > 0 ) { - FT_Int len = ( width * bpp + 7 ) >> 3; + FT_UInt len = ( width * bpp + 7 ) >> 3; for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ), - bitmap->buffer + pitch * i, len ); + FT_MEM_COPY( buffer + (FT_UInt)new_pitch * ( ypixels + i ), + bitmap->buffer + (FT_UInt)pitch * i, + len ); } else { - FT_Int len = ( width * bpp + 7 ) >> 3; + FT_UInt len = ( width * bpp + 7 ) >> 3; for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + new_pitch * i, - bitmap->buffer + pitch * i, len ); + FT_MEM_COPY( buffer + (FT_UInt)new_pitch * i, + bitmap->buffer + (FT_UInt)pitch * i, + len ); } FT_FREE( bitmap->buffer ); @@ -220,7 +275,8 @@ { FT_Error error; unsigned char* p; - FT_Int i, x, y, pitch; + FT_Int i, x, pitch; + FT_UInt y; FT_Int xstr, ystr; @@ -248,17 +304,11 @@ case FT_PIXEL_MODE_GRAY4: { FT_Bitmap tmp; - FT_Int align; - if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 ) - align = ( bitmap->width + xstr + 3 ) / 4; - else - align = ( bitmap->width + xstr + 1 ) / 2; - - FT_Bitmap_New( &tmp ); - - error = FT_Bitmap_Convert( library, bitmap, &tmp, align ); + /* convert to 8bpp */ + FT_Bitmap_Init( &tmp ); + error = FT_Bitmap_Convert( library, bitmap, &tmp, 1 ); if ( error ) return error; @@ -285,21 +335,23 @@ return FT_Err_Ok; } - error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr ); + error = ft_bitmap_assure_buffer( library->memory, bitmap, + (FT_UInt)xstr, (FT_UInt)ystr ); if ( error ) return error; + /* take care of bitmap flow */ pitch = bitmap->pitch; if ( pitch > 0 ) p = bitmap->buffer + pitch * ystr; else { pitch = -pitch; - p = bitmap->buffer + pitch * ( bitmap->rows - 1 ); + p = bitmap->buffer + (FT_UInt)pitch * ( bitmap->rows - 1 ); } /* for each row */ - for ( y = 0; y < bitmap->rows ; y++ ) + for ( y = 0; y < bitmap->rows; y++ ) { /* * Horizontally: @@ -309,7 +361,7 @@ */ for ( x = pitch - 1; x >= 0; x-- ) { - unsigned char tmp; + unsigned char tmp; tmp = p[x]; @@ -324,7 +376,7 @@ p[x] |= p[x - 1] << ( 8 - i ); #if 0 - if ( p[x] == 0xff ) + if ( p[x] == 0xFF ) break; #endif } @@ -334,12 +386,12 @@ { if ( p[x] + p[x - i] > bitmap->num_grays - 1 ) { - p[x] = (unsigned char)(bitmap->num_grays - 1); + p[x] = (unsigned char)( bitmap->num_grays - 1 ); break; } else { - p[x] = (unsigned char)(p[x] + p[x-i]); + p[x] = (unsigned char)( p[x] + p[x - i] ); if ( p[x] == bitmap->num_grays - 1 ) break; } @@ -368,63 +420,56 @@ p += bitmap->pitch; } - bitmap->width += xstr; - bitmap->rows += ystr; + bitmap->width += (FT_UInt)xstr; + bitmap->rows += (FT_UInt)ystr; return FT_Err_Ok; } - FT_Byte + static FT_Byte ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra ) { - FT_Long a = bgra[3]; - FT_Long b = bgra[0]; - FT_Long g = bgra[1]; - FT_Long r = bgra[2]; - FT_Long l; + FT_UInt a = bgra[3]; + FT_UInt l; + /* Short-circuit transparent color to avoid division by zero. */ + if ( !a ) + return 0; + /* * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722 * coefficients for RGB channels *on the linear colors*. * A gamma of 2.2 is fair to assume. And then, we need to * undo the premultiplication too. * - * http://accessibility.kde.org/hsl-adjusted.php + * http://accessibility.kde.org/hsl-adjusted.php + * + * We do the computation with integers only, applying a gamma of 2.0. + * We guarantee 32-bit arithmetic to avoid overflow but the resulting + * luminosity fits into 16 bits. * - * We do the computation with integers only. */ - /* Undo premultification, get the number in a 16.16 form. */ - b = FT_MulDiv( b, 65536, a ); - g = FT_MulDiv( g, 65536, a ); - r = FT_MulDiv( r, 65536, a ); - a = a * 256; - - /* Apply gamma of 2.0 instead of 2.2. */ - b = FT_MulFix( b, b ); - g = FT_MulFix( g, g ); - r = FT_MulFix( r, r ); - - /* Apply coefficients. */ - b = FT_MulFix( b, 4731 /* 0.0722 * 65536 */ ); - g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ ); - r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ ); - - l = r + g + b; + l = ( 4732UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] + + 46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] + + 13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2] ) >> 16; /* - * Final transparency can be determined this way: + * Final transparency can be determined as follows. * * - If alpha is zero, we want 0. * - If alpha is zero and luminosity is zero, we want 255. * - If alpha is zero and luminosity is one, we want 0. * - * So the formula is a * (1 - l). + * So the formula is a * (1 - l) = a - l * a. + * + * We still need to undo premultiplication by dividing l by a*a. + * */ - return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 ); + return (FT_Byte)( a - l / a ); } @@ -439,10 +484,16 @@ FT_Error error = FT_Err_Ok; FT_Memory memory; + FT_Byte* s; + FT_Byte* t; + if ( !library ) return FT_THROW( Invalid_Library_Handle ); + if ( !source || !target ) + return FT_THROW( Invalid_Argument ); + memory = library->memory; switch ( source->pixel_mode ) @@ -455,13 +506,15 @@ case FT_PIXEL_MODE_LCD_V: case FT_PIXEL_MODE_BGRA: { - FT_Int pad; - FT_Long old_size; + FT_Int pad, old_target_pitch, target_pitch; + FT_ULong old_size; + + old_target_pitch = target->pitch; + if ( old_target_pitch < 0 ) + old_target_pitch = -old_target_pitch; - old_size = target->rows * target->pitch; - if ( old_size < 0 ) - old_size = -old_size; + old_size = target->rows * (FT_UInt)old_target_pitch; target->pixel_mode = FT_PIXEL_MODE_GRAY; target->rows = source->rows; @@ -470,21 +523,23 @@ pad = 0; if ( alignment > 0 ) { - pad = source->width % alignment; + pad = (FT_Int)source->width % alignment; if ( pad != 0 ) pad = alignment - pad; } - target->pitch = source->width + pad; + target_pitch = (FT_Int)source->width + pad; - if ( target->pitch > 0 && - (FT_ULong)target->rows > FT_ULONG_MAX / target->pitch ) + if ( target_pitch > 0 && + (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch ) return FT_THROW( Invalid_Argument ); - if ( target->rows * target->pitch > old_size && + if ( target->rows * (FT_ULong)target_pitch > old_size && FT_QREALLOC( target->buffer, - old_size, target->rows * target->pitch ) ) + old_size, target->rows * (FT_UInt)target_pitch ) ) return error; + + target->pitch = target->pitch < 0 ? -target_pitch : target_pitch; } break; @@ -492,13 +547,20 @@ error = FT_THROW( Invalid_Argument ); } + s = source->buffer; + t = target->buffer; + + /* take care of bitmap flow */ + if ( source->pitch < 0 ) + s -= source->pitch * (FT_Int)( source->rows - 1 ); + if ( target->pitch < 0 ) + t -= target->pitch * (FT_Int)( target->rows - 1 ); + switch ( source->pixel_mode ) { case FT_PIXEL_MODE_MONO: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; + FT_UInt i; target->num_grays = 2; @@ -507,7 +569,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; /* get the full bytes */ @@ -555,12 +617,8 @@ case FT_PIXEL_MODE_LCD: case FT_PIXEL_MODE_LCD_V: { - FT_Int width = source->width; - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int s_pitch = source->pitch; - FT_Int t_pitch = target->pitch; - FT_Int i; + FT_UInt width = source->width; + FT_UInt i; target->num_grays = 256; @@ -569,8 +627,8 @@ { FT_ARRAY_COPY( t, s, width ); - s += s_pitch; - t += t_pitch; + s += source->pitch; + t += target->pitch; } } break; @@ -578,9 +636,7 @@ case FT_PIXEL_MODE_GRAY2: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; + FT_UInt i; target->num_grays = 4; @@ -589,7 +645,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; /* get the full bytes */ @@ -630,9 +686,7 @@ case FT_PIXEL_MODE_GRAY4: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; + FT_UInt i; target->num_grays = 16; @@ -641,7 +695,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; /* get the full bytes */ @@ -666,13 +720,10 @@ } break; + case FT_PIXEL_MODE_BGRA: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int s_pitch = source->pitch; - FT_Int t_pitch = target->pitch; - FT_Int i; + FT_UInt i; target->num_grays = 256; @@ -681,7 +732,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; for ( j = source->width; j > 0; j-- ) @@ -692,8 +743,8 @@ tt += 1; } - s += s_pitch; - t += t_pitch; + s += source->pitch; + t += target->pitch; } } break; @@ -718,7 +769,7 @@ FT_Error error; - FT_Bitmap_New( &bitmap ); + FT_Bitmap_Init( &bitmap ); error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); if ( error ) return error; diff --git a/drivers/freetype/src/base/ftcalc.c b/drivers/freetype/src/base/ftcalc.c new file mode 100644 index 0000000000..67549d0c43 --- /dev/null +++ b/drivers/freetype/src/base/ftcalc.c @@ -0,0 +1,1003 @@ +/***************************************************************************/ +/* */ +/* ftcalc.c */ +/* */ +/* Arithmetic computations (body). */ +/* */ +/* Copyright 1996-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Support for 1-complement arithmetic has been totally dropped in this */ + /* release. You can still write your own code if you need it. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Implementing basic computation routines. */ + /* */ + /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ + /* and FT_FloorFix() are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_GLYPH_H +#include FT_TRIGONOMETRY_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H + + +#ifdef FT_MULFIX_ASSEMBLER +#undef FT_MulFix +#endif + +/* we need to emulate a 64-bit data type if a real one isn't available */ + +#ifndef FT_LONG64 + + typedef struct FT_Int64_ + { + FT_UInt32 lo; + FT_UInt32 hi; + + } FT_Int64; + +#endif /* !FT_LONG64 */ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_calc + + + /* transfer sign leaving a positive number */ +#define FT_MOVE_SIGN( x, s ) \ + FT_BEGIN_STMNT \ + if ( x < 0 ) \ + { \ + x = -x; \ + s = -s; \ + } \ + FT_END_STMNT + + /* The following three functions are available regardless of whether */ + /* FT_LONG64 is defined. */ + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_RoundFix( FT_Fixed a ) + { + return ( a + 0x8000L - ( a < 0 ) ) & ~0xFFFFL; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_CeilFix( FT_Fixed a ) + { + return ( a + 0xFFFFL ) & ~0xFFFFL; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_FloorFix( FT_Fixed a ) + { + return a & ~0xFFFFL; + } + +#ifndef FT_MSB + + FT_BASE_DEF ( FT_Int ) + FT_MSB( FT_UInt32 z ) + { + FT_Int shift = 0; + + + /* determine msb bit index in `shift' */ + if ( z & 0xFFFF0000UL ) + { + z >>= 16; + shift += 16; + } + if ( z & 0x0000FF00UL ) + { + z >>= 8; + shift += 8; + } + if ( z & 0x000000F0UL ) + { + z >>= 4; + shift += 4; + } + if ( z & 0x0000000CUL ) + { + z >>= 2; + shift += 2; + } + if ( z & 0x00000002UL ) + { + /* z >>= 1; */ + shift += 1; + } + + return shift; + } + +#endif /* !FT_MSB */ + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Fixed ) + FT_Hypot( FT_Fixed x, + FT_Fixed y ) + { + FT_Vector v; + + + v.x = x; + v.y = y; + + return FT_Vector_Length( &v ); + } + + +#ifdef FT_LONG64 + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulDiv( FT_Long a_, + FT_Long b_, + FT_Long c_ ) + { + FT_Int s = 1; + FT_UInt64 a, b, c, d; + FT_Long d_; + + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); + + a = (FT_UInt64)a_; + b = (FT_UInt64)b_; + c = (FT_UInt64)c_; + + d = c > 0 ? ( a * b + ( c >> 1 ) ) / c + : 0x7FFFFFFFUL; + + d_ = (FT_Long)d; + + return s < 0 ? -d_ : d_; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Long ) + FT_MulDiv_No_Round( FT_Long a_, + FT_Long b_, + FT_Long c_ ) + { + FT_Int s = 1; + FT_UInt64 a, b, c, d; + FT_Long d_; + + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); + + a = (FT_UInt64)a_; + b = (FT_UInt64)b_; + c = (FT_UInt64)c_; + + d = c > 0 ? a * b / c + : 0x7FFFFFFFUL; + + d_ = (FT_Long)d; + + return s < 0 ? -d_ : d_; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulFix( FT_Long a_, + FT_Long b_ ) + { +#ifdef FT_MULFIX_ASSEMBLER + + return FT_MULFIX_ASSEMBLER( (FT_Int32)a_, (FT_Int32)b_ ); + +#else + + FT_Int64 ab = (FT_Int64)a_ * (FT_Int64)b_; + + /* this requires arithmetic right shift of signed numbers */ + return (FT_Long)( ( ab + 0x8000L - ( ab < 0 ) ) >> 16 ); + +#endif /* FT_MULFIX_ASSEMBLER */ + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_DivFix( FT_Long a_, + FT_Long b_ ) + { + FT_Int s = 1; + FT_UInt64 a, b, q; + FT_Long q_; + + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + + a = (FT_UInt64)a_; + b = (FT_UInt64)b_; + + q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b + : 0x7FFFFFFFUL; + + q_ = (FT_Long)q; + + return s < 0 ? -q_ : q_; + } + + +#else /* !FT_LONG64 */ + + + static void + ft_multo64( FT_UInt32 x, + FT_UInt32 y, + FT_Int64 *z ) + { + FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; + + + lo1 = x & 0x0000FFFFU; hi1 = x >> 16; + lo2 = y & 0x0000FFFFU; hi2 = y >> 16; + + lo = lo1 * lo2; + i1 = lo1 * hi2; + i2 = lo2 * hi1; + hi = hi1 * hi2; + + /* Check carry overflow of i1 + i2 */ + i1 += i2; + hi += (FT_UInt32)( i1 < i2 ) << 16; + + hi += i1 >> 16; + i1 = i1 << 16; + + /* Check carry overflow of i1 + lo */ + lo += i1; + hi += ( lo < i1 ); + + z->lo = lo; + z->hi = hi; + } + + + static FT_UInt32 + ft_div64by32( FT_UInt32 hi, + FT_UInt32 lo, + FT_UInt32 y ) + { + FT_UInt32 r, q; + FT_Int i; + + + if ( hi >= y ) + return (FT_UInt32)0x7FFFFFFFL; + + /* We shift as many bits as we can into the high register, perform */ + /* 32-bit division with modulo there, then work through the remaining */ + /* bits with long division. This optimization is especially noticeable */ + /* for smaller dividends that barely use the high register. */ + + i = 31 - FT_MSB( hi ); + r = ( hi << i ) | ( lo >> ( 32 - i ) ); lo <<= i; /* left 64-bit shift */ + q = r / y; + r -= q * y; /* remainder */ + + i = 32 - i; /* bits remaining in low register */ + do + { + q <<= 1; + r = ( r << 1 ) | ( lo >> 31 ); lo <<= 1; + + if ( r >= y ) + { + r -= y; + q |= 1; + } + } while ( --i ); + + return q; + } + + + static void + FT_Add64( FT_Int64* x, + FT_Int64* y, + FT_Int64 *z ) + { + FT_UInt32 lo, hi; + + + lo = x->lo + y->lo; + hi = x->hi + y->hi + ( lo < x->lo ); + + z->lo = lo; + z->hi = hi; + } + + + /* The FT_MulDiv function has been optimized thanks to ideas from */ + /* Graham Asher and Alexei Podtelezhnikov. The trick is to optimize */ + /* a rather common case when everything fits within 32-bits. */ + /* */ + /* We compute 'a*b+c/2', then divide it by 'c' (all positive values). */ + /* */ + /* The product of two positive numbers never exceeds the square of */ + /* its mean values. Therefore, we always avoid the overflow by */ + /* imposing */ + /* */ + /* (a + b) / 2 <= sqrt(X - c/2) , */ + /* */ + /* where X = 2^32 - 1, the maximum unsigned 32-bit value, and using */ + /* unsigned arithmetic. Now we replace `sqrt' with a linear function */ + /* that is smaller or equal for all values of c in the interval */ + /* [0;X/2]; it should be equal to sqrt(X) and sqrt(3X/4) at the */ + /* endpoints. Substituting the linear solution and explicit numbers */ + /* we get */ + /* */ + /* a + b <= 131071.99 - c / 122291.84 . */ + /* */ + /* In practice, we should use a faster and even stronger inequality */ + /* */ + /* a + b <= 131071 - (c >> 16) */ + /* */ + /* or, alternatively, */ + /* */ + /* a + b <= 129894 - (c >> 17) . */ + /* */ + /* FT_MulFix, on the other hand, is optimized for a small value of */ + /* the first argument, when the second argument can be much larger. */ + /* This can be achieved by scaling the second argument and the limit */ + /* in the above inequalities. For example, */ + /* */ + /* a + (b >> 8) <= (131071 >> 4) */ + /* */ + /* covers the practical range of use. The actual test below is a bit */ + /* tighter to avoid the border case overflows. */ + /* */ + /* In the case of FT_DivFix, the exact overflow check */ + /* */ + /* a << 16 <= X - c/2 */ + /* */ + /* is scaled down by 2^16 and we use */ + /* */ + /* a <= 65535 - (c >> 17) . */ + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulDiv( FT_Long a_, + FT_Long b_, + FT_Long c_ ) + { + FT_Int s = 1; + FT_UInt32 a, b, c; + + + /* XXX: this function does not allow 64-bit arguments */ + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); + + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + c = (FT_UInt32)c_; + + if ( c == 0 ) + a = 0x7FFFFFFFUL; + + else if ( a + b <= 129894UL - ( c >> 17 ) ) + a = ( a * b + ( c >> 1 ) ) / c; + + else + { + FT_Int64 temp, temp2; + + + ft_multo64( a, b, &temp ); + + temp2.hi = 0; + temp2.lo = c >> 1; + + FT_Add64( &temp, &temp2, &temp ); + + /* last attempt to ditch long division */ + a = temp.hi == 0 ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); + } + + a_ = (FT_Long)a; + + return s < 0 ? -a_ : a_; + } + + + FT_BASE_DEF( FT_Long ) + FT_MulDiv_No_Round( FT_Long a_, + FT_Long b_, + FT_Long c_ ) + { + FT_Int s = 1; + FT_UInt32 a, b, c; + + + /* XXX: this function does not allow 64-bit arguments */ + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); + + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + c = (FT_UInt32)c_; + + if ( c == 0 ) + a = 0x7FFFFFFFUL; + + else if ( a + b <= 131071UL ) + a = a * b / c; + + else + { + FT_Int64 temp; + + + ft_multo64( a, b, &temp ); + + /* last attempt to ditch long division */ + a = temp.hi == 0 ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); + } + + a_ = (FT_Long)a; + + return s < 0 ? -a_ : a_; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulFix( FT_Long a_, + FT_Long b_ ) + { +#ifdef FT_MULFIX_ASSEMBLER + + return FT_MULFIX_ASSEMBLER( a_, b_ ); + +#elif 0 + + /* + * This code is nonportable. See comment below. + * + * However, on a platform where right-shift of a signed quantity fills + * the leftmost bits by copying the sign bit, it might be faster. + */ + + FT_Long sa, sb; + FT_UInt32 a, b; + + + /* + * This is a clever way of converting a signed number `a' into its + * absolute value (stored back into `a') and its sign. The sign is + * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' + * was negative. (Similarly for `b' and `sb'). + * + * Unfortunately, it doesn't work (at least not portably). + * + * It makes the assumption that right-shift on a negative signed value + * fills the leftmost bits by copying the sign bit. This is wrong. + * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, + * the result of right-shift of a negative signed value is + * implementation-defined. At least one implementation fills the + * leftmost bits with 0s (i.e., it is exactly the same as an unsigned + * right shift). This means that when `a' is negative, `sa' ends up + * with the value 1 rather than -1. After that, everything else goes + * wrong. + */ + sa = ( a_ >> ( sizeof ( a_ ) * 8 - 1 ) ); + a = ( a_ ^ sa ) - sa; + sb = ( b_ >> ( sizeof ( b_ ) * 8 - 1 ) ); + b = ( b_ ^ sb ) - sb; + + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + + if ( a + ( b >> 8 ) <= 8190UL ) + a = ( a * b + 0x8000U ) >> 16; + else + { + FT_UInt32 al = a & 0xFFFFUL; + + + a = ( a >> 16 ) * b + al * ( b >> 16 ) + + ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 ); + } + + sa ^= sb; + a = ( a ^ sa ) - sa; + + return (FT_Long)a; + +#else /* 0 */ + + FT_Int s = 1; + FT_UInt32 a, b; + + + /* XXX: this function does not allow 64-bit arguments */ + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + + if ( a + ( b >> 8 ) <= 8190UL ) + a = ( a * b + 0x8000UL ) >> 16; + else + { + FT_UInt32 al = a & 0xFFFFUL; + + + a = ( a >> 16 ) * b + al * ( b >> 16 ) + + ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 ); + } + + a_ = (FT_Long)a; + + return s < 0 ? -a_ : a_; + +#endif /* 0 */ + + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_DivFix( FT_Long a_, + FT_Long b_ ) + { + FT_Int s = 1; + FT_UInt32 a, b, q; + FT_Long q_; + + + /* XXX: this function does not allow 64-bit arguments */ + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + + if ( b == 0 ) + { + /* check for division by 0 */ + q = 0x7FFFFFFFUL; + } + else if ( a <= 65535UL - ( b >> 17 ) ) + { + /* compute result directly */ + q = ( ( a << 16 ) + ( b >> 1 ) ) / b; + } + else + { + /* we need more bits; we have to do it by hand */ + FT_Int64 temp, temp2; + + + temp.hi = a >> 16; + temp.lo = a << 16; + temp2.hi = 0; + temp2.lo = b >> 1; + + FT_Add64( &temp, &temp2, &temp ); + q = ft_div64by32( temp.hi, temp.lo, b ); + } + + q_ = (FT_Long)q; + + return s < 0 ? -q_ : q_; + } + + +#endif /* !FT_LONG64 */ + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix *b ) + { + FT_Fixed xx, xy, yx, yy; + + + if ( !a || !b ) + return; + + xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); + xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); + yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); + yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ) + { + FT_Pos delta, xx, yy; + + + if ( !matrix ) + return FT_THROW( Invalid_Argument ); + + /* compute discriminant */ + delta = FT_MulFix( matrix->xx, matrix->yy ) - + FT_MulFix( matrix->xy, matrix->yx ); + + if ( !delta ) + return FT_THROW( Invalid_Argument ); /* matrix can't be inverted */ + + matrix->xy = - FT_DivFix( matrix->xy, delta ); + matrix->yx = - FT_DivFix( matrix->yx, delta ); + + xx = matrix->xx; + yy = matrix->yy; + + matrix->xx = FT_DivFix( yy, delta ); + matrix->yy = FT_DivFix( xx, delta ); + + return FT_Err_Ok; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ) + { + FT_Fixed xx, xy, yx, yy; + + FT_Long val = 0x10000L * scaling; + + + if ( !a || !b ) + return; + + xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); + xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); + yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); + yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ) + { + FT_Pos xz, yz; + + FT_Long val = 0x10000L * scaling; + + + if ( !vector || !matrix ) + return; + + xz = FT_MulDiv( vector->x, matrix->xx, val ) + + FT_MulDiv( vector->y, matrix->xy, val ); + + yz = FT_MulDiv( vector->x, matrix->yx, val ) + + FT_MulDiv( vector->y, matrix->yy, val ); + + vector->x = xz; + vector->y = yz; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_UInt32 ) + FT_Vector_NormLen( FT_Vector* vector ) + { + FT_Int32 x_ = vector->x; + FT_Int32 y_ = vector->y; + FT_Int32 b, z; + FT_UInt32 x, y, u, v, l; + FT_Int sx = 1, sy = 1, shift; + + + FT_MOVE_SIGN( x_, sx ); + FT_MOVE_SIGN( y_, sy ); + + x = (FT_UInt32)x_; + y = (FT_UInt32)y_; + + /* trivial cases */ + if ( x == 0 ) + { + if ( y > 0 ) + vector->y = sy * 0x10000; + return y; + } + else if ( y == 0 ) + { + if ( x > 0 ) + vector->x = sx * 0x10000; + return x; + } + + /* Estimate length and prenormalize by shifting so that */ + /* the new approximate length is between 2/3 and 4/3. */ + /* The magic constant 0xAAAAAAAAUL (2/3 of 2^32) helps */ + /* achieve this in 16.16 fixed-point representation. */ + l = x > y ? x + ( y >> 1 ) + : y + ( x >> 1 ); + + shift = 31 - FT_MSB( l ); + shift -= 15 + ( l >= ( 0xAAAAAAAAUL >> shift ) ); + + if ( shift > 0 ) + { + x <<= shift; + y <<= shift; + + /* re-estimate length for tiny vectors */ + l = x > y ? x + ( y >> 1 ) + : y + ( x >> 1 ); + } + else + { + x >>= -shift; + y >>= -shift; + l >>= -shift; + } + + /* lower linear approximation for reciprocal length minus one */ + b = 0x10000 - (FT_Int32)l; + + x_ = (FT_Int32)x; + y_ = (FT_Int32)y; + + /* Newton's iterations */ + do + { + u = (FT_UInt32)( x_ + ( x_ * b >> 16 ) ); + v = (FT_UInt32)( y_ + ( y_ * b >> 16 ) ); + + /* Normalized squared length in the parentheses approaches 2^32. */ + /* On two's complement systems, converting to signed gives the */ + /* difference with 2^32 even if the expression wraps around. */ + z = -(FT_Int32)( u * u + v * v ) / 0x200; + z = z * ( ( 0x10000 + b ) >> 8 ) / 0x10000; + + b += z; + + } while ( z > 0 ); + + vector->x = sx < 0 ? -(FT_Pos)u : (FT_Pos)u; + vector->y = sy < 0 ? -(FT_Pos)v : (FT_Pos)v; + + /* Conversion to signed helps to recover from likely wrap around */ + /* in calculating the prenormalized length, because it gives the */ + /* correct difference with 2^32 on two's complement systems. */ + l = (FT_UInt32)( 0x10000 + (FT_Int32)( u * x + v * y ) / 0x10000 ); + if ( shift > 0 ) + l = ( l + ( 1 << ( shift - 1 ) ) ) >> shift; + else + l <<= -shift; + + return l; + } + + +#if 0 + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ) + { + FT_UInt32 root, rem_hi, rem_lo, test_div; + FT_Int count; + + + root = 0; + + if ( x > 0 ) + { + rem_hi = 0; + rem_lo = (FT_UInt32)x; + count = 24; + do + { + rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); + rem_lo <<= 2; + root <<= 1; + test_div = ( root << 1 ) + 1; + + if ( rem_hi >= test_div ) + { + rem_hi -= test_div; + root += 1; + } + } while ( --count ); + } + + return (FT_Int32)root; + } + +#endif /* 0 */ + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Int ) + ft_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ) + { +#ifdef FT_LONG64 + + FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; + + + return ( delta > 0 ) - ( delta < 0 ); + +#else + + FT_Int result; + + + if ( (FT_ULong)FT_ABS( in_x ) + (FT_ULong)FT_ABS( out_y ) <= 131071UL && + (FT_ULong)FT_ABS( in_y ) + (FT_ULong)FT_ABS( out_x ) <= 131071UL ) + { + FT_Long z1 = in_x * out_y; + FT_Long z2 = in_y * out_x; + + + if ( z1 > z2 ) + result = +1; + else if ( z1 < z2 ) + result = -1; + else + result = 0; + } + else /* products might overflow 32 bits */ + { + FT_Int64 z1, z2; + + + /* XXX: this function does not allow 64-bit arguments */ + ft_multo64( (FT_UInt32)in_x, (FT_UInt32)out_y, &z1 ); + ft_multo64( (FT_UInt32)in_y, (FT_UInt32)out_x, &z2 ); + + if ( z1.hi > z2.hi ) + result = +1; + else if ( z1.hi < z2.hi ) + result = -1; + else if ( z1.lo > z2.lo ) + result = +1; + else if ( z1.lo < z2.lo ) + result = -1; + else + result = 0; + } + + /* XXX: only the sign of return value, +1/0/-1 must be used */ + return result; + +#endif + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Int ) + ft_corner_is_flat( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ) + { + FT_Pos ax = in_x + out_x; + FT_Pos ay = in_y + out_y; + + FT_Pos d_in, d_out, d_hypot; + + + /* The idea of this function is to compare the length of the */ + /* hypotenuse with the `in' and `out' length. The `corner' */ + /* represented by `in' and `out' is flat if the hypotenuse's */ + /* length isn't too large. */ + /* */ + /* This approach has the advantage that the angle between */ + /* `in' and `out' is not checked. In case one of the two */ + /* vectors is `dominant', this is, much larger than the */ + /* other vector, we thus always have a flat corner. */ + /* */ + /* hypotenuse */ + /* x---------------------------x */ + /* \ / */ + /* \ / */ + /* in \ / out */ + /* \ / */ + /* o */ + /* Point */ + + d_in = FT_HYPOT( in_x, in_y ); + d_out = FT_HYPOT( out_x, out_y ); + d_hypot = FT_HYPOT( ax, ay ); + + /* now do a simple length comparison: */ + /* */ + /* d_in + d_out < 17/16 d_hypot */ + + return ( d_in + d_out - d_hypot ) < ( d_hypot >> 4 ); + } + + +/* END */ diff --git a/drivers/freetype/freetype/src/base/ftcid.c b/drivers/freetype/src/base/ftcid.c index 741879d922..251bbd009a 100644 --- a/drivers/freetype/freetype/src/base/ftcid.c +++ b/drivers/freetype/src/base/ftcid.c @@ -4,7 +4,8 @@ /* */ /* FreeType API for accessing CID font information. */ /* */ -/* Copyright 2007, 2009, 2013 by Derek Clegg, Michael Toftdal. */ +/* Copyright 2007-2016 by */ +/* Derek Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ diff --git a/drivers/freetype/freetype/src/base/ftdbgmem.c b/drivers/freetype/src/base/ftdbgmem.c index 6fb86fe77d..6ab5072748 100644 --- a/drivers/freetype/freetype/src/base/ftdbgmem.c +++ b/drivers/freetype/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001-2006, 2009, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,7 @@ #include FT_CONFIG_STANDARD_LIBRARY_H - FT_BASE_DEF( const char* ) _ft_debug_file = 0; + FT_BASE_DEF( const char* ) _ft_debug_file = NULL; FT_BASE_DEF( long ) _ft_debug_lineno = 0; extern void @@ -47,7 +47,7 @@ typedef struct FT_MemTableRec_* FT_MemTable; -#define FT_MEM_VAL( addr ) ((FT_PtrDist)(FT_Pointer)( addr )) +#define FT_MEM_VAL( addr ) ( (FT_PtrDist)(FT_Pointer)( addr ) ) /* * This structure holds statistics for a single allocation/release @@ -76,7 +76,7 @@ /* - * We don't need a resizable array for the memory sources, because + * We don't need a resizable array for the memory sources because * their number is pretty limited within FreeType. */ #define FT_MEM_SOURCE_BUCKETS 128 @@ -85,8 +85,8 @@ * This structure holds information related to a single allocated * memory block. If KEEPALIVE is defined, blocks that are freed by * FreeType are never released to the system. Instead, their `size' - * field is set to -size. This is mainly useful to detect double frees, - * at the price of large memory footprint during execution. + * field is set to `-size'. This is mainly useful to detect double + * frees, at the price of a large memory footprint during execution. */ typedef struct FT_MemNodeRec_ { @@ -111,20 +111,20 @@ */ typedef struct FT_MemTableRec_ { - FT_ULong size; - FT_ULong nodes; + FT_Long size; + FT_Long nodes; FT_MemNode* buckets; - FT_ULong alloc_total; - FT_ULong alloc_current; - FT_ULong alloc_max; - FT_ULong alloc_count; + FT_Long alloc_total; + FT_Long alloc_current; + FT_Long alloc_max; + FT_Long alloc_count; FT_Bool bound_total; - FT_ULong alloc_total_max; + FT_Long alloc_total_max; FT_Bool bound_count; - FT_ULong alloc_count_max; + FT_Long alloc_count_max; FT_MemSource sources[FT_MEM_SOURCE_BUCKETS]; @@ -142,14 +142,14 @@ #define FT_MEM_SIZE_MIN 7 #define FT_MEM_SIZE_MAX 13845163 -#define FT_FILENAME( x ) ((x) ? (x) : "unknown file") +#define FT_FILENAME( x ) ( (x) ? (x) : "unknown file" ) /* * Prime numbers are ugly to handle. It would be better to implement * L-Hashing, which is 10% faster and doesn't require divisions. */ - static const FT_UInt ft_mem_primes[] = + static const FT_Int ft_mem_primes[] = { 7, 11, @@ -189,10 +189,10 @@ }; - static FT_ULong - ft_mem_closest_prime( FT_ULong num ) + static FT_Long + ft_mem_closest_prime( FT_Long num ) { - FT_UInt i; + size_t i; for ( i = 0; @@ -204,7 +204,7 @@ } - extern void + static void ft_mem_debug_panic( const char* fmt, ... ) { @@ -254,19 +254,20 @@ static void ft_mem_table_resize( FT_MemTable table ) { - FT_ULong new_size; + FT_Long new_size; new_size = ft_mem_closest_prime( table->nodes ); if ( new_size != table->size ) { FT_MemNode* new_buckets; - FT_ULong i; + FT_Long i; new_buckets = (FT_MemNode *) - ft_mem_table_alloc( table, - new_size * sizeof ( FT_MemNode ) ); + ft_mem_table_alloc( + table, + new_size * (FT_Long)sizeof ( FT_MemNode ) ); if ( new_buckets == NULL ) return; @@ -282,7 +283,7 @@ while ( node ) { next = node->link; - hash = FT_MEM_VAL( node->address ) % new_size; + hash = FT_MEM_VAL( node->address ) % (FT_PtrDist)new_size; pnode = new_buckets + hash; node->link = pnode[0]; @@ -325,8 +326,9 @@ table->free = memory->free; table->buckets = (FT_MemNode *) - memory->alloc( memory, - table->size * sizeof ( FT_MemNode ) ); + memory->alloc( + memory, + table->size * (FT_Long)sizeof ( FT_MemNode ) ); if ( table->buckets ) FT_ARRAY_ZERO( table->buckets, table->size ); else @@ -343,9 +345,9 @@ static void ft_mem_table_destroy( FT_MemTable table ) { - FT_ULong i; - FT_Long leak_count = 0; - FT_ULong leaks = 0; + FT_Long i; + FT_Long leak_count = 0; + FT_Long leaks = 0; FT_DumpMemory( table->memory ); @@ -359,13 +361,14 @@ while ( node ) { next = node->link; - node->link = 0; + node->link = NULL; if ( node->size > 0 ) { printf( "leaked memory block at address %p, size %8ld in (%s:%ld)\n", - node->address, node->size, + (void*)node->address, + node->size, FT_FILENAME( node->source->file_name ), node->source->line_no ); @@ -381,7 +384,7 @@ ft_mem_table_free( table, node ); node = next; } - table->buckets[i] = 0; + table->buckets[i] = NULL; } ft_mem_table_free( table, table->buckets ); @@ -430,7 +433,7 @@ hash = FT_MEM_VAL( address ); - pnode = table->buckets + ( hash % table->size ); + pnode = table->buckets + ( hash % (FT_PtrDist)table->size ); for (;;) { @@ -460,14 +463,14 @@ (FT_UInt32)( 5 * _ft_debug_lineno ); pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS]; - for ( ;; ) + for (;;) { node = *pnode; if ( node == NULL ) break; - if ( node->file_name == _ft_debug_file && - node->line_no == _ft_debug_lineno ) + if ( node->file_name == _ft_debug_file && + node->line_no == _ft_debug_lineno ) goto Exit; pnode = &node->link; @@ -485,11 +488,11 @@ node->max_blocks = 0; node->all_blocks = 0; - node->cur_size = 0; - node->max_size = 0; - node->all_size = 0; + node->cur_size = 0; + node->max_size = 0; + node->all_size = 0; - node->cur_max = 0; + node->cur_max = 0; node->link = NULL; node->hash = hash; @@ -503,7 +506,7 @@ static void ft_mem_table_set( FT_MemTable table, FT_Byte* address, - FT_ULong size, + FT_Long size, FT_Long delta ) { FT_MemNode *pnode, node; @@ -558,7 +561,7 @@ source->max_blocks = source->cur_blocks; } - if ( size > (FT_ULong)source->cur_max ) + if ( size > source->cur_max ) source->cur_max = size; if ( delta != 0 ) @@ -671,7 +674,7 @@ } - extern FT_Pointer + static FT_Pointer ft_mem_debug_alloc( FT_Memory memory, FT_Long size ) { @@ -688,14 +691,14 @@ return NULL; /* return NULL if this allocation would overflow the maximum heap size */ - if ( table->bound_total && - table->alloc_total_max - table->alloc_current > (FT_ULong)size ) + if ( table->bound_total && + table->alloc_total_max - table->alloc_current > size ) return NULL; block = (FT_Byte *)ft_mem_table_alloc( table, size ); if ( block ) { - ft_mem_table_set( table, block, (FT_ULong)size, 0 ); + ft_mem_table_set( table, block, size, 0 ); table->alloc_count++; } @@ -707,7 +710,7 @@ } - extern void + static void ft_mem_debug_free( FT_Memory memory, FT_Pointer block ) { @@ -731,7 +734,7 @@ } - extern FT_Pointer + static FT_Pointer ft_mem_debug_realloc( FT_Memory memory, FT_Long cur_size, FT_Long new_size, @@ -787,21 +790,22 @@ table->alloc_count >= table->alloc_count_max ) return NULL; - delta = (FT_Long)( new_size - cur_size ); + delta = new_size - cur_size; /* return NULL if this allocation would overflow the maximum heap size */ - if ( delta > 0 && - table->bound_total && - table->alloc_current + (FT_ULong)delta > table->alloc_total_max ) + if ( delta > 0 && + table->bound_total && + table->alloc_current + delta > table->alloc_total_max ) return NULL; - new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size ); + new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size ); if ( new_block == NULL ) return NULL; ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); - ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size ); + ft_memcpy( new_block, block, cur_size < new_size ? (size_t)cur_size + : (size_t)new_size ); ft_mem_table_remove( table, (FT_Byte*)block, delta ); @@ -844,7 +848,7 @@ if ( total_max > 0 ) { table->bound_total = 1; - table->alloc_total_max = (FT_ULong)total_max; + table->alloc_total_max = total_max; } } @@ -857,7 +861,7 @@ if ( total_count > 0 ) { table->bound_count = 1; - table->alloc_count_max = (FT_ULong)total_count; + table->alloc_count_max = total_count; } } @@ -896,7 +900,6 @@ } - static int ft_mem_source_compare( const void* p1, const void* p2 ) @@ -925,7 +928,7 @@ FT_MemSource* bucket = table->sources; FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS; FT_MemSource* sources; - FT_UInt nn, count; + FT_Int nn, count; const char* fmt; @@ -939,8 +942,9 @@ count++; } - sources = (FT_MemSource*)ft_mem_table_alloc( - table, sizeof ( *sources ) * count ); + sources = (FT_MemSource*) + ft_mem_table_alloc( + table, count * (FT_Long)sizeof ( *sources ) ); count = 0; for ( bucket = table->sources; bucket < limit; bucket++ ) @@ -952,7 +956,10 @@ sources[count++] = source; } - ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare ); + ft_qsort( sources, + (size_t)count, + sizeof ( *sources ), + ft_mem_source_compare ); printf( "FreeType Memory Dump: " "current=%ld max=%ld total=%ld count=%ld\n", diff --git a/drivers/freetype/freetype/src/base/ftdebug.c b/drivers/freetype/src/base/ftdebug.c index b9156d15ee..40925d14a0 100644 --- a/drivers/freetype/freetype/src/base/ftdebug.c +++ b/drivers/freetype/src/base/ftdebug.c @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2008, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -152,8 +152,8 @@ /* the memory and stream components which are set to 7 and 5, */ /* respectively. */ /* */ - /* See the file <include/freetype/internal/fttrace.h> for details of the */ - /* available toggle names. */ + /* See the file `include/freetype/internal/fttrace.h' for details of */ + /* the available toggle names. */ /* */ /* The level must be between 0 and 7; 0 means quiet (except for serious */ /* runtime errors), and 7 means _very_ verbose. */ diff --git a/drivers/freetype/freetype/src/base/ftxf86.c b/drivers/freetype/src/base/ftfntfmt.c index a4bf767dfa..c6eb3190c6 100644 --- a/drivers/freetype/freetype/src/base/ftxf86.c +++ b/drivers/freetype/src/base/ftfntfmt.c @@ -1,10 +1,10 @@ /***************************************************************************/ /* */ -/* ftxf86.c */ +/* ftfntfmt.c */ /* */ -/* FreeType utility file for X11 support (body). */ +/* FreeType utility file for font formats (body). */ /* */ -/* Copyright 2002, 2003, 2004 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,12 +17,27 @@ #include <ft2build.h> -#include FT_XFREE86_H +#include FT_FONT_FORMATS_H #include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H - /* documentation is in ftxf86.h */ + /* documentation is in ftfntfmt.h */ + + FT_EXPORT_DEF( const char* ) + FT_Get_Font_Format( FT_Face face ) + { + const char* result = NULL; + + + if ( face ) + FT_FACE_FIND_SERVICE( face, result, FONT_FORMAT ); + + return result; + } + + + /* deprecated function name; retained for ABI compatibility */ FT_EXPORT_DEF( const char* ) FT_Get_X11_Font_Format( FT_Face face ) @@ -31,7 +46,7 @@ if ( face ) - FT_FACE_FIND_SERVICE( face, result, XF86_NAME ); + FT_FACE_FIND_SERVICE( face, result, FONT_FORMAT ); return result; } diff --git a/drivers/freetype/freetype/src/base/ftfstype.c b/drivers/freetype/src/base/ftfstype.c index d0ef7b7c1b..ae56c8fc8d 100644 --- a/drivers/freetype/freetype/src/base/ftfstype.c +++ b/drivers/freetype/src/base/ftfstype.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file to access FSType data (body). */ /* */ -/* Copyright 2008, 2009 by */ +/* Copyright 2008-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -51,7 +51,7 @@ /* look at FSType before fsType for Type42 */ - if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL && + if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, FT_SFNT_OS2 ) ) != NULL && os2->version != 0xFFFFU ) return os2->fsType; diff --git a/drivers/freetype/freetype/src/base/ftgasp.c b/drivers/freetype/src/base/ftgasp.c index 8485d29259..e38e55b6c0 100644 --- a/drivers/freetype/freetype/src/base/ftgasp.c +++ b/drivers/freetype/src/base/ftgasp.c @@ -4,7 +4,7 @@ /* */ /* Access of TrueType's `gasp' table (body). */ /* */ -/* Copyright 2007 by */ +/* Copyright 2007-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/base/ftgloadr.c b/drivers/freetype/src/base/ftgloadr.c index 3cc5c7a805..c4f0ff70f4 100644 --- a/drivers/freetype/freetype/src/base/ftgloadr.c +++ b/drivers/freetype/src/base/ftgloadr.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (body). */ /* */ -/* Copyright 2002-2006, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -212,7 +212,8 @@ /* check points & tags */ - new_max = base->n_points + current->n_points + n_points; + new_max = (FT_UInt)base->n_points + (FT_UInt)current->n_points + + n_points; old_max = loader->max_points; if ( new_max > old_max ) @@ -245,7 +246,7 @@ /* check contours */ old_max = loader->max_contours; - new_max = base->n_contours + current->n_contours + + new_max = (FT_UInt)base->n_contours + (FT_UInt)current->n_contours + n_contours; if ( new_max > old_max ) { @@ -329,9 +330,9 @@ FT_GlyphLoad base; FT_GlyphLoad current; - FT_UInt n_curr_contours; - FT_UInt n_base_points; - FT_UInt n; + FT_Int n_curr_contours; + FT_Int n_base_points; + FT_Int n; if ( !loader ) @@ -365,8 +366,8 @@ FT_GlyphLoader source ) { FT_Error error; - FT_UInt num_points = source->base.outline.n_points; - FT_UInt num_contours = source->base.outline.n_contours; + FT_UInt num_points = (FT_UInt)source->base.outline.n_points; + FT_UInt num_contours = (FT_UInt)source->base.outline.n_contours; error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours ); diff --git a/drivers/freetype/freetype/src/base/ftglyph.c b/drivers/freetype/src/base/ftglyph.c index 5dd28a8c52..c2376dd03a 100644 --- a/drivers/freetype/freetype/src/base/ftglyph.c +++ b/drivers/freetype/src/base/ftglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2005, 2007, 2008, 2010, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -82,7 +82,7 @@ } else { - FT_Bitmap_New( &glyph->bitmap ); + FT_Bitmap_Init( &glyph->bitmap ); error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap ); } @@ -125,10 +125,10 @@ FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - cbox->xMin = glyph->left << 6; - cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 ); - cbox->yMax = glyph->top << 6; - cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 ); + cbox->xMin = glyph->left * 64; + cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width * 64 ); + cbox->yMax = glyph->top * 64; + cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows * 64 ); } @@ -173,7 +173,9 @@ } /* allocate new outline */ - error = FT_Outline_New( library, source->n_points, source->n_contours, + error = FT_Outline_New( library, + (FT_UInt)source->n_points, + source->n_contours, &glyph->outline ); if ( error ) goto Exit; @@ -205,8 +207,10 @@ FT_Library library = FT_GLYPH( source )->library; - error = FT_Outline_New( library, source->outline.n_points, - source->outline.n_contours, &target->outline ); + error = FT_Outline_New( library, + (FT_UInt)source->outline.n_points, + source->outline.n_contours, + &target->outline ); if ( !error ) FT_Outline_Copy( &source->outline, &target->outline ); @@ -287,7 +291,7 @@ FT_Glyph glyph = NULL; - *aglyph = 0; + *aglyph = NULL; if ( !FT_ALLOC( glyph, clazz->glyph_size ) ) { @@ -314,13 +318,13 @@ /* check arguments */ - if ( !target ) + if ( !target || !source || !source->clazz ) { error = FT_THROW( Invalid_Argument ); goto Exit; } - *target = 0; + *target = NULL; if ( !source || !source->clazz ) { @@ -359,7 +363,7 @@ FT_Error error; FT_Glyph glyph; - const FT_Glyph_Class* clazz = 0; + const FT_Glyph_Class* clazz = NULL; if ( !slot ) @@ -399,9 +403,9 @@ if ( error ) goto Exit; - /* copy advance while converting it to 16.16 format */ - glyph->advance.x = slot->advance.x << 10; - glyph->advance.y = slot->advance.y << 10; + /* copy advance while converting 26.6 to 16.16 format */ + glyph->advance.x = slot->advance.x * 1024; + glyph->advance.y = slot->advance.y * 1024; /* now import the image from the glyph slot */ error = clazz->glyph_init( glyph, slot ); @@ -424,15 +428,16 @@ FT_Matrix* matrix, FT_Vector* delta ) { - const FT_Glyph_Class* clazz; - FT_Error error = FT_Err_Ok; + FT_Error error = FT_Err_Ok; if ( !glyph || !glyph->clazz ) error = FT_THROW( Invalid_Argument ); else { - clazz = glyph->clazz; + const FT_Glyph_Class* clazz = glyph->clazz; + + if ( clazz->glyph_transform ) { /* transform glyph image */ @@ -466,38 +471,33 @@ if ( !glyph || !glyph->clazz ) return; - else + + clazz = glyph->clazz; + if ( !clazz->glyph_bbox ) + return; + + /* retrieve bbox in 26.6 coordinates */ + clazz->glyph_bbox( glyph, acbox ); + + /* perform grid fitting if needed */ + if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || + bbox_mode == FT_GLYPH_BBOX_PIXELS ) { - clazz = glyph->clazz; - if ( !clazz->glyph_bbox ) - return; - else - { - /* retrieve bbox in 26.6 coordinates */ - clazz->glyph_bbox( glyph, acbox ); - - /* perform grid fitting if needed */ - if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || - bbox_mode == FT_GLYPH_BBOX_PIXELS ) - { - acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); - acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); - acbox->xMax = FT_PIX_CEIL( acbox->xMax ); - acbox->yMax = FT_PIX_CEIL( acbox->yMax ); - } - - /* convert to integer pixels if needed */ - if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || - bbox_mode == FT_GLYPH_BBOX_PIXELS ) - { - acbox->xMin >>= 6; - acbox->yMin >>= 6; - acbox->xMax >>= 6; - acbox->yMax >>= 6; - } - } + acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); + acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); + acbox->xMax = FT_PIX_CEIL( acbox->xMax ); + acbox->yMax = FT_PIX_CEIL( acbox->yMax ); + } + + /* convert to integer pixels if needed */ + if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || + bbox_mode == FT_GLYPH_BBOX_PIXELS ) + { + acbox->xMin >>= 6; + acbox->yMin >>= 6; + acbox->xMax >>= 6; + acbox->yMax >>= 6; } - return; } @@ -516,7 +516,7 @@ FT_BitmapGlyph bitmap = NULL; const FT_Glyph_Class* clazz; - /* FT_BITMAP_GLYPH_CLASS_GET derefers `library' in PIC mode */ + /* FT_BITMAP_GLYPH_CLASS_GET dereferences `library' in PIC mode */ FT_Library library; diff --git a/drivers/freetype/freetype/src/base/ftgxval.c b/drivers/freetype/src/base/ftgxval.c index a8ec44ac00..6667b371a1 100644 --- a/drivers/freetype/freetype/src/base/ftgxval.c +++ b/drivers/freetype/src/base/ftgxval.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating TrueTyepGX/AAT tables (body). */ /* */ -/* Copyright 2004-2006, 2010, 2013 by */ +/* Copyright 2004-2016 by */ /* Masatake YAMATO, Redhat K.K, */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -50,7 +50,7 @@ goto Exit; } - if ( tables == NULL ) + if ( !tables ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -102,7 +102,7 @@ goto Exit; } - if ( ckern_table == NULL ) + if ( !ckern_table ) { error = FT_THROW( Invalid_Argument ); goto Exit; diff --git a/drivers/freetype/src/base/fthash.c b/drivers/freetype/src/base/fthash.c new file mode 100644 index 0000000000..21bc8dd5b4 --- /dev/null +++ b/drivers/freetype/src/base/fthash.c @@ -0,0 +1,339 @@ +/***************************************************************************/ +/* */ +/* fthash.c */ +/* */ +/* Hashing functions (body). */ +/* */ +/***************************************************************************/ + +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2015 + * Francesco Zappa Nardelli + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_HASH_H +#include FT_INTERNAL_MEMORY_H + + +#define INITIAL_HT_SIZE 241 + + + static FT_ULong + hash_str_lookup( FT_Hashkey* key ) + { + const char* kp = key->str; + FT_ULong res = 0; + + + /* Mocklisp hash function. */ + while ( *kp ) + res = ( res << 5 ) - res + (FT_ULong)*kp++; + + return res; + } + + + static FT_ULong + hash_num_lookup( FT_Hashkey* key ) + { + FT_ULong num = (FT_ULong)key->num; + FT_ULong res; + + + /* Mocklisp hash function. */ + res = num & 0xFF; + res = ( res << 5 ) - res + ( ( num >> 8 ) & 0xFF ); + res = ( res << 5 ) - res + ( ( num >> 16 ) & 0xFF ); + res = ( res << 5 ) - res + ( ( num >> 24 ) & 0xFF ); + + return res; + } + + + static FT_Bool + hash_str_compare( FT_Hashkey* a, + FT_Hashkey* b ) + { + if ( a->str[0] == b->str[0] && + ft_strcmp( a->str, b->str ) == 0 ) + return 1; + + return 0; + } + + + static FT_Bool + hash_num_compare( FT_Hashkey* a, + FT_Hashkey* b ) + { + if ( a->num == b->num ) + return 1; + + return 0; + } + + + static FT_Hashnode* + hash_bucket( FT_Hashkey key, + FT_Hash hash ) + { + FT_ULong res = 0; + FT_Hashnode* bp = hash->table; + FT_Hashnode* ndp; + + + res = (hash->lookup)( &key ); + + ndp = bp + ( res % hash->size ); + while ( *ndp ) + { + if ( (hash->compare)( &(*ndp)->key, &key ) ) + break; + + ndp--; + if ( ndp < bp ) + ndp = bp + ( hash->size - 1 ); + } + + return ndp; + } + + + static FT_Error + hash_rehash( FT_Hash hash, + FT_Memory memory ) + { + FT_Hashnode* obp = hash->table; + FT_Hashnode* bp; + FT_Hashnode* nbp; + + FT_UInt i, sz = hash->size; + FT_Error error = FT_Err_Ok; + + + hash->size <<= 1; + hash->limit = hash->size / 3; + + if ( FT_NEW_ARRAY( hash->table, hash->size ) ) + goto Exit; + + for ( i = 0, bp = obp; i < sz; i++, bp++ ) + { + if ( *bp ) + { + nbp = hash_bucket( (*bp)->key, hash ); + *nbp = *bp; + } + } + + FT_FREE( obp ); + + Exit: + return error; + } + + + static FT_Error + hash_init( FT_Hash hash, + FT_Bool is_num, + FT_Memory memory ) + { + FT_UInt sz = INITIAL_HT_SIZE; + FT_Error error; + + + hash->size = sz; + hash->limit = sz / 3; + hash->used = 0; + + if ( is_num ) + { + hash->lookup = hash_num_lookup; + hash->compare = hash_num_compare; + } + else + { + hash->lookup = hash_str_lookup; + hash->compare = hash_str_compare; + } + + FT_MEM_NEW_ARRAY( hash->table, sz ); + + return error; + } + + + FT_Error + ft_hash_str_init( FT_Hash hash, + FT_Memory memory ) + { + return hash_init( hash, 0, memory ); + } + + + FT_Error + ft_hash_num_init( FT_Hash hash, + FT_Memory memory ) + { + return hash_init( hash, 1, memory ); + } + + + void + ft_hash_str_free( FT_Hash hash, + FT_Memory memory ) + { + if ( hash ) + { + FT_UInt sz = hash->size; + FT_Hashnode* bp = hash->table; + FT_UInt i; + + + for ( i = 0; i < sz; i++, bp++ ) + FT_FREE( *bp ); + + FT_FREE( hash->table ); + } + } + + + /* `ft_hash_num_free' is the same as `ft_hash_str_free' */ + + + static FT_Error + hash_insert( FT_Hashkey key, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashnode nn; + FT_Hashnode* bp = hash_bucket( key, hash ); + FT_Error error = FT_Err_Ok; + + + nn = *bp; + if ( !nn ) + { + if ( FT_NEW( nn ) ) + goto Exit; + *bp = nn; + + nn->key = key; + nn->data = data; + + if ( hash->used >= hash->limit ) + { + error = hash_rehash( hash, memory ); + if ( error ) + goto Exit; + } + + hash->used++; + } + else + nn->data = data; + + Exit: + return error; + } + + + FT_Error + ft_hash_str_insert( const char* key, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashkey hk; + + + hk.str = key; + + return hash_insert( hk, data, hash, memory ); + } + + + FT_Error + ft_hash_num_insert( FT_Int num, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashkey hk; + + + hk.num = num; + + return hash_insert( hk, data, hash, memory ); + } + + + static size_t* + hash_lookup( FT_Hashkey key, + FT_Hash hash ) + { + FT_Hashnode* np = hash_bucket( key, hash ); + + + return (*np) ? &(*np)->data + : NULL; + } + + + size_t* + ft_hash_str_lookup( const char* key, + FT_Hash hash ) + { + FT_Hashkey hk; + + + hk.str = key; + + return hash_lookup( hk, hash ); + } + + + size_t* + ft_hash_num_lookup( FT_Int num, + FT_Hash hash ) + { + FT_Hashkey hk; + + + hk.num = num; + + return hash_lookup( hk, hash ); + } + + +/* END */ diff --git a/drivers/freetype/freetype/src/base/ftinit.c b/drivers/freetype/src/base/ftinit.c index 85f321fd2d..c2dd0a7b37 100644 --- a/drivers/freetype/freetype/src/base/ftinit.c +++ b/drivers/freetype/src/base/ftinit.c @@ -4,7 +4,7 @@ /* */ /* FreeType initialization layer (body). */ /* */ -/* Copyright 1996-2002, 2005, 2007, 2009, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -138,7 +138,7 @@ #include FT_CONFIG_MODULES_H FT_FREE( classes ); - pic_container->default_module_classes = 0; + pic_container->default_module_classes = NULL; } @@ -164,7 +164,7 @@ memory = library->memory; - pic_container->default_module_classes = 0; + pic_container->default_module_classes = NULL; if ( FT_ALLOC( classes, sizeof ( FT_Module_Class* ) * ( FT_NUM_MODULE_CLASSES + 1 ) ) ) @@ -172,8 +172,8 @@ /* initialize all pointers to 0, especially the last one */ for ( i = 0; i < FT_NUM_MODULE_CLASSES; i++ ) - classes[i] = 0; - classes[FT_NUM_MODULE_CLASSES] = 0; + classes[i] = NULL; + classes[FT_NUM_MODULE_CLASSES] = NULL; i = 0; @@ -235,6 +235,8 @@ FT_Memory memory; + /* check of `alibrary' delayed to `FT_New_Library' */ + /* First of all, allocate a new system object -- this function is part */ /* of the system-specific component, i.e. `ftsystem.c'. */ @@ -263,17 +265,19 @@ FT_EXPORT_DEF( FT_Error ) FT_Done_FreeType( FT_Library library ) { - if ( library ) - { - FT_Memory memory = library->memory; + FT_Memory memory; - /* Discard the library object */ - FT_Done_Library( library ); + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); - /* discard memory manager */ - FT_Done_Memory( memory ); - } + memory = library->memory; + + /* Discard the library object */ + FT_Done_Library( library ); + + /* discard memory manager */ + FT_Done_Memory( memory ); return FT_Err_Ok; } diff --git a/drivers/freetype/freetype/src/base/ftlcdfil.c b/drivers/freetype/src/base/ftlcdfil.c index 852fb32982..8bcbed7aab 100644 --- a/drivers/freetype/freetype/src/base/ftlcdfil.c +++ b/drivers/freetype/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ /* */ -/* Copyright 2006, 2008-2010, 2013 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -46,9 +46,16 @@ FT_Byte* line = bitmap->buffer; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + + /* `fir' and `pix' must be at least 32 bit wide, since the sum of */ + /* the values in `weights' can exceed 0xFF */ + for ( ; height > 0; height--, line += bitmap->pitch ) { - FT_UInt fir[5]; + FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ FT_UInt val1, xx; @@ -57,7 +64,6 @@ fir[1] = weights[3] * val1; fir[2] = weights[4] * val1; fir[3] = 0; - fir[4] = 0; val1 = line[1]; fir[0] += weights[1] * val1; @@ -78,7 +84,7 @@ fir[3] = weights[4] * val; pix >>= 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); line[xx - 2] = (FT_Byte)pix; } @@ -87,11 +93,11 @@ pix = fir[0] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); line[xx - 2] = (FT_Byte)pix; pix = fir[1] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); line[xx - 1] = (FT_Byte)pix; } } @@ -104,10 +110,14 @@ FT_Int pitch = bitmap->pitch; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + for ( ; width > 0; width--, column++ ) { FT_Byte* col = column; - FT_UInt fir[5]; + FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ FT_UInt val1, yy; @@ -116,7 +126,6 @@ fir[1] = weights[3] * val1; fir[2] = weights[4] * val1; fir[3] = 0; - fir[4] = 0; col += pitch; val1 = col[0]; @@ -139,7 +148,7 @@ fir[3] = weights[4] * val; pix >>= 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); col[-2 * pitch] = (FT_Byte)pix; col += pitch; } @@ -149,11 +158,11 @@ pix = fir[0] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); col[-2 * pitch] = (FT_Byte)pix; pix = fir[1] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); col[-pitch] = (FT_Byte)pix; } } @@ -173,7 +182,7 @@ FT_UInt height = (FT_UInt)bitmap->rows; FT_Int pitch = bitmap->pitch; - static const int filters[3][3] = + static const unsigned int filters[3][3] = { { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 }, { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 }, @@ -189,6 +198,10 @@ FT_Byte* line = bitmap->buffer; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + for ( ; height > 0; height--, line += pitch ) { FT_UInt xx; @@ -228,10 +241,14 @@ FT_Byte* column = bitmap->buffer; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + for ( ; width > 0; width--, column++ ) { FT_Byte* col = column; - FT_Byte* col_end = col + height * pitch; + FT_Byte* col_end = col + (FT_Int)height * pitch; for ( ; col < col_end; col += 3 * pitch ) @@ -272,10 +289,15 @@ FT_Library_SetLcdFilterWeights( FT_Library library, unsigned char *weights ) { - if ( !library || !weights ) + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !weights ) return FT_THROW( Invalid_Argument ); ft_memcpy( library->lcd_weights, weights, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; return FT_Err_Ok; } @@ -285,16 +307,14 @@ FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ) { + static const FT_Byte default_filter[5] = + { 0x08, 0x4d, 0x56, 0x4d, 0x08 }; static const FT_Byte light_filter[5] = { 0x00, 0x55, 0x56, 0x55, 0x00 }; - /* the values here sum up to a value larger than 256, */ - /* providing a cheap gamma correction */ - static const FT_Byte default_filter[5] = - { 0x10, 0x40, 0x70, 0x40, 0x10 }; if ( !library ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Library_Handle ); switch ( filter ) { @@ -304,25 +324,9 @@ break; case FT_LCD_FILTER_DEFAULT: -#if defined( FT_FORCE_LEGACY_LCD_FILTER ) - - library->lcd_filter_func = _ft_lcd_filter_legacy; - library->lcd_extra = 0; - -#elif defined( FT_FORCE_LIGHT_LCD_FILTER ) - - ft_memcpy( library->lcd_weights, light_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; - -#else - ft_memcpy( library->lcd_weights, default_filter, 5 ); library->lcd_filter_func = _ft_lcd_filter_fir; library->lcd_extra = 2; - -#endif - break; case FT_LCD_FILTER_LIGHT: @@ -334,6 +338,7 @@ #ifdef USE_LEGACY case FT_LCD_FILTER_LEGACY: + case FT_LCD_FILTER_LEGACY1: library->lcd_filter_func = _ft_lcd_filter_legacy; library->lcd_extra = 0; break; diff --git a/drivers/freetype/freetype/src/base/ftmac.c b/drivers/freetype/src/base/ftmac.c index 5b5aae61cc..e97fdbfc22 100644 --- a/drivers/freetype/freetype/src/base/ftmac.c +++ b/drivers/freetype/src/base/ftmac.c @@ -8,7 +8,7 @@ /* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */ /* classic platforms built by MPW. */ /* */ -/* Copyright 1996-2009, 2013 by */ +/* Copyright 1996-2016 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -227,6 +227,9 @@ FT_Error err; + if ( !fontName || !face_index ) + return FT_THROW( Invalid_Argument); + err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); if ( err ) return err; @@ -256,6 +259,9 @@ FT_Error err; + if ( !fontName || !face_index ) + return FT_THROW( Invalid_Argument ); + err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); if ( err ) return err; @@ -440,9 +446,10 @@ style = (StyleTable*)p; p += sizeof ( StyleTable ); string_count = EndianS16_BtoN( *(short*)(p) ); + string_count = FT_MIN( 64, string_count ); p += sizeof ( short ); - for ( i = 0; i < string_count && i < 64; i++ ) + for ( i = 0; i < string_count; i++ ) { names[i] = p; p += names[i][0]; @@ -459,7 +466,7 @@ ps_name[ps_name_len] = 0; } if ( style->indexes[face_index] > 1 && - style->indexes[face_index] <= FT_MIN( string_count, 64 ) ) + style->indexes[face_index] <= string_count ) { unsigned char* suffixes = names[style->indexes[face_index] - 1]; @@ -611,11 +618,11 @@ total_size += 6; /* code + 4 bytes chunk length */ } - total_size += GetHandleSize( post_data ) - 2; + total_size += (FT_ULong)GetHandleSize( post_data ) - 2; last_code = code; - /* detect integer overflows */ - if ( total_size < old_total_size ) + /* detect resource fork overflow */ + if ( FT_MAC_RFORK_MAX_LEN < total_size ) { error = FT_THROW( Array_Too_Large ); goto Error; @@ -740,6 +747,11 @@ return FT_THROW( Invalid_Handle ); sfnt_size = (FT_ULong)GetHandleSize( sfnt ); + + /* detect resource fork overflow */ + if ( FT_MAC_RFORK_MAX_LEN < sfnt_size ) + return FT_THROW( Array_Too_Large ); + if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) ) { ReleaseResource( sfnt ); @@ -852,6 +864,8 @@ FT_Error error = FT_Err_Ok; + /* check of `library' and `aface' delayed to `FT_New_Face_From_XXX' */ + GetResInfo( fond, &fond_id, &fond_type, fond_name ); if ( ResError() != noErr || fond_type != TTAG_FOND ) return FT_THROW( Invalid_File_Format ); @@ -963,7 +977,6 @@ if ( !pathname ) return FT_THROW( Invalid_Argument ); - error = FT_Err_Ok; *aface = NULL; /* try resourcefork based font: LWFN, FFIL */ @@ -998,10 +1011,14 @@ { FT_Error error; FT_Open_Args args; - OSErr err; - UInt8 pathname[PATH_MAX]; + + OSErr err; + UInt8 pathname[PATH_MAX]; + /* check of `library' and `aface' delayed to */ + /* `FT_New_Face_From_Resource' */ + if ( !ref ) return FT_THROW( Invalid_Argument ); @@ -1048,6 +1065,8 @@ FSRef ref; + /* check of `library' and `aface' delayed to `FT_New_Face_From_FSRef' */ + if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr ) return FT_THROW( Invalid_Argument ); else diff --git a/drivers/freetype/freetype/src/base/ftmm.c b/drivers/freetype/src/base/ftmm.c index 18ff879bfc..6b759ca467 100644 --- a/drivers/freetype/freetype/src/base/ftmm.c +++ b/drivers/freetype/src/base/ftmm.c @@ -4,7 +4,7 @@ /* */ /* Multiple Master font support (body). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2009, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -72,6 +72,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !amaster ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -94,6 +99,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !amaster ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -117,6 +127,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -140,6 +155,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -163,6 +183,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -189,6 +214,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { diff --git a/drivers/freetype/freetype/src/base/ftobjs.c b/drivers/freetype/src/base/ftobjs.c index 157bf45634..c2dc6183b0 100644 --- a/drivers/freetype/freetype/src/base/ftobjs.c +++ b/drivers/freetype/src/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -55,10 +55,19 @@ #pragma warning( disable : 4244 ) #endif /* _MSC_VER */ - /* it's easiest to include `md5.c' directly */ -#define free md5_free /* suppress a shadow warning */ + /* It's easiest to include `md5.c' directly. However, since OpenSSL */ + /* also provides the same functions, there might be conflicts if */ + /* both FreeType and OpenSSL are built as static libraries. For */ + /* this reason, we put the MD5 stuff into the `FT_' namespace. */ +#define MD5_u32plus FT_MD5_u32plus +#define MD5_CTX FT_MD5_CTX +#define MD5_Init FT_MD5_Init +#define MD5_Update FT_MD5_Update +#define MD5_Final FT_MD5_Final + +#undef HAVE_OPENSSL + #include "md5.c" -#undef free #if defined( _MSC_VER ) #pragma warning( pop ) @@ -160,7 +169,7 @@ FT_Stream stream = NULL; - *astream = 0; + *astream = NULL; if ( !library ) return FT_THROW( Invalid_Library_Handle ); @@ -180,7 +189,7 @@ /* create a memory-based stream */ FT_Stream_OpenMemory( stream, (const FT_Byte*)args->memory_base, - args->memory_size ); + (FT_ULong)args->memory_size ); } #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT @@ -355,10 +364,10 @@ slot->bitmap_left = 0; slot->bitmap_top = 0; slot->num_subglyphs = 0; - slot->subglyphs = 0; - slot->control_data = 0; + slot->subglyphs = NULL; + slot->control_data = NULL; slot->control_len = 0; - slot->other = 0; + slot->other = NULL; slot->format = FT_GLYPH_FORMAT_NONE; slot->linearHoriAdvance = 0; @@ -389,7 +398,7 @@ if ( FT_DRIVER_USES_OUTLINES( driver ) ) { FT_GlyphLoader_Done( slot->internal->loader ); - slot->internal->loader = 0; + slot->internal->loader = NULL; } FT_FREE( slot->internal ); @@ -410,7 +419,10 @@ FT_GlyphSlot slot = NULL; - if ( !face || !face->driver ) + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !face->driver ) return FT_THROW( Invalid_Argument ); driver = face->driver; @@ -437,7 +449,7 @@ *aslot = slot; } else if ( aslot ) - *aslot = 0; + *aslot = NULL; Exit: @@ -510,6 +522,7 @@ internal->transform_matrix.xy = 0; internal->transform_matrix.yx = 0; internal->transform_matrix.yy = 0x10000L; + matrix = &internal->transform_matrix; } else @@ -525,6 +538,7 @@ { internal->transform_delta.x = 0; internal->transform_delta.y = 0; + delta = &internal->transform_delta; } else @@ -667,11 +681,18 @@ /* the check for `num_locations' assures that we actually */ /* test for instructions in a TTF and not in a CFF-based OTF */ - if ( mode == FT_RENDER_MODE_LIGHT || - face->internal->ignore_unpatented_hinter || + /* */ + /* since `maxSizeOfInstructions' might be unreliable, we */ + /* check the size of the `fpgm' and `prep' tables, too -- */ + /* the assumption is that there don't exist real TTFs where */ + /* both `fpgm' and `prep' tables are missing */ + if ( ( mode == FT_RENDER_MODE_LIGHT && + !FT_DRIVER_HINTS_LIGHTLY( driver ) ) || ( FT_IS_SFNT( face ) && ttface->num_locations && - ttface->max_profile.maxSizeOfInstructions == 0 ) ) + ttface->max_profile.maxSizeOfInstructions == 0 && + ttface->font_program_size == 0 && + ttface->cvt_program_size == 0 ) ) autohint = TRUE; } } @@ -922,7 +943,7 @@ (FT_List_Destructor)destroy_size, memory, driver ); - face->size = 0; + face->size = NULL; /* now discard client data */ if ( face->generic.finalizer ) @@ -940,7 +961,7 @@ face->stream, ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); - face->stream = 0; + face->stream = NULL; /* get rid of it */ if ( face->internal ) @@ -958,10 +979,6 @@ (FT_List_Destructor)destroy_face, driver->root.memory, driver ); - - /* check whether we need to drop the driver's glyph loader */ - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - FT_GlyphLoader_Done( driver->glyph_loader ); } @@ -1035,14 +1052,6 @@ ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif face->charmap = cur[0]; return FT_Err_Ok; } @@ -1057,14 +1066,6 @@ { if ( cur[0]->encoding == FT_ENCODING_UNICODE ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif face->charmap = cur[0]; return FT_Err_Ok; } @@ -1106,17 +1107,7 @@ if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && FT_Get_CMap_Format( cur[0] ) == 14 ) - { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UVS cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif return cur[0]; - } } return NULL; @@ -1133,7 +1124,8 @@ /* */ static FT_Error open_face( FT_Driver driver, - FT_Stream stream, + FT_Stream *astream, + FT_Bool external_stream, FT_Long face_index, FT_Int num_params, FT_Parameter* params, @@ -1141,10 +1133,11 @@ { FT_Memory memory; FT_Driver_Class clazz; - FT_Face face = 0; - FT_Error error, error2; + FT_Face face = NULL; FT_Face_Internal internal = NULL; + FT_Error error, error2; + clazz = driver->clazz; memory = driver->root.memory; @@ -1155,7 +1148,11 @@ face->driver = driver; face->memory = memory; - face->stream = stream; + face->stream = *astream; + + /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ + if ( external_stream ) + face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; if ( FT_NEW( internal ) ) goto Fail; @@ -1167,7 +1164,7 @@ int i; - face->internal->incremental_interface = 0; + face->internal->incremental_interface = NULL; for ( i = 0; i < num_params && !face->internal->incremental_interface; i++ ) if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) @@ -1177,11 +1174,12 @@ #endif if ( clazz->init_face ) - error = clazz->init_face( stream, + error = clazz->init_face( *astream, face, (FT_Int)face_index, num_params, params ); + *astream = face->stream; /* Stream may have been changed. */ if ( error ) goto Fail; @@ -1208,7 +1206,7 @@ clazz->done_face( face ); FT_FREE( internal ); FT_FREE( face ); - *aface = 0; + *aface = NULL; } return error; @@ -1231,7 +1229,7 @@ FT_Open_Args args; - /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + /* test for valid `library' and `aface' delayed to `FT_Open_Face' */ if ( !pathname ) return FT_THROW( Invalid_Argument ); @@ -1257,7 +1255,7 @@ FT_Open_Args args; - /* test for valid `library' and `face' delayed to FT_Open_Face() */ + /* test for valid `library' and `face' delayed to `FT_Open_Face' */ if ( !file_base ) return FT_THROW( Invalid_Argument ); @@ -1311,8 +1309,8 @@ FT_FREE( stream->base ); stream->size = 0; - stream->base = 0; - stream->close = 0; + stream->base = NULL; + stream->close = NULL; } @@ -1336,7 +1334,7 @@ if ( !base ) return FT_THROW( Invalid_Argument ); - *astream = 0; + *astream = NULL; memory = library->memory; if ( FT_NEW( stream ) ) goto Exit; @@ -1388,13 +1386,13 @@ } #ifdef FT_MACINTOSH - /* At this point, face_index has served its purpose; */ + /* At this point, the face index has served its purpose; */ /* whoever calls this function has already used it to */ /* locate the correct font data. We should not propagate */ /* this index to FT_Open_Face() (unless it is negative). */ if ( face_index > 0 ) - face_index = 0; + face_index &= 0x7FFF0000L; /* retain GX data */ #endif error = FT_Open_Face( library, &args, face_index, aface ); @@ -1420,7 +1418,7 @@ /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ /* format too. Here, since we can't expect that the TrueType font */ - /* driver is loaded unconditially, we must parse the font by */ + /* driver is loaded unconditionally, we must parse the font by */ /* ourselves. We are only interested in the name of the table and */ /* the offset. */ @@ -1485,6 +1483,7 @@ if ( face_index >= 0 && pstable_index == face_index ) return FT_Err_Ok; } + return FT_THROW( Table_Missing ); } @@ -1500,7 +1499,7 @@ FT_Error error; FT_Memory memory = library->memory; FT_ULong offset, length; - FT_Long pos; + FT_ULong pos; FT_Bool is_sfnt_cid; FT_Byte* sfnt_ps = NULL; @@ -1508,7 +1507,11 @@ FT_UNUSED( params ); - pos = FT_Stream_Pos( stream ); + /* ignore GX stuff */ + if ( face_index > 0 ) + face_index &= 0xFFFFL; + + pos = FT_STREAM_POS(); error = ft_lookup_PS_in_sfnt_stream( stream, face_index, @@ -1518,7 +1521,21 @@ if ( error ) goto Exit; - if ( FT_Stream_Seek( stream, pos + offset ) ) + if ( offset > stream->size ) + { + FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table offset\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + else if ( length > stream->size - offset ) + { + FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + error = FT_Stream_Seek( stream, pos + offset ); + if ( error ) goto Exit; if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) @@ -1526,7 +1543,10 @@ error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); if ( error ) + { + FT_FREE( sfnt_ps ); goto Exit; + } error = open_face_from_buffer( library, sfnt_ps, @@ -1571,9 +1591,9 @@ FT_Memory memory = library->memory; FT_Byte* pfb_data = NULL; int i, type, flags; - FT_Long len; - FT_Long pfb_len, pfb_pos, pfb_lenpos; - FT_Long rlen, temp; + FT_ULong len; + FT_ULong pfb_len, pfb_pos, pfb_lenpos; + FT_ULong rlen, temp; if ( face_index == -1 ) @@ -1586,14 +1606,39 @@ pfb_len = 0; for ( i = 0; i < resource_cnt; ++i ) { - error = FT_Stream_Seek( stream, offsets[i] ); + error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) goto Exit; - if ( FT_READ_LONG( temp ) ) + if ( FT_READ_ULONG( temp ) ) + goto Exit; + + /* FT2 allocator takes signed long buffer length, + * too large value causing overflow should be checked + */ + FT_TRACE4(( " POST fragment #%d: length=0x%08x" + " total pfb_len=0x%08x\n", + i, temp, pfb_len + temp + 6)); + if ( FT_MAC_RFORK_MAX_LEN < temp || + FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 ) + { + FT_TRACE2(( " MacOS resource length cannot exceed" + " 0x%08x\n", FT_MAC_RFORK_MAX_LEN )); + error = FT_THROW( Invalid_Offset ); goto Exit; + } + pfb_len += temp + 6; } + FT_TRACE2(( " total buffer size to concatenate %d" + " POST fragments: 0x%08x\n", + resource_cnt, pfb_len + 2)); + if ( pfb_len + 2 < 6 ) { + FT_TRACE2(( " too long fragment length makes" + " pfb_len confused: pfb_len=0x%08x\n", pfb_len )); + error = FT_THROW( Array_Too_Large ); + goto Exit; + } if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) goto Exit; @@ -1610,19 +1655,33 @@ type = 1; for ( i = 0; i < resource_cnt; ++i ) { - error = FT_Stream_Seek( stream, offsets[i] ); + error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) goto Exit2; - if ( FT_READ_LONG( rlen ) ) - goto Exit; + if ( FT_READ_ULONG( rlen ) ) + goto Exit2; + + /* FT2 allocator takes signed long buffer length, + * too large fragment length causing overflow should be checked + */ + if ( 0x7FFFFFFFUL < rlen ) + { + error = FT_THROW( Invalid_Offset ); + goto Exit2; + } + if ( FT_READ_USHORT( flags ) ) - goto Exit; + goto Exit2; FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", i, offsets[i], rlen, flags )); + error = FT_ERR( Array_Too_Large ); /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ + { + FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", i )); continue; + } /* the flags are part of the resource, so rlen >= 2. */ /* but some fonts declare rlen = 0 for empty fragment */ @@ -1635,6 +1694,8 @@ len += rlen; else { + FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer" + " %p + 0x%08x\n", i, pfb_data, pfb_lenpos )); if ( pfb_lenpos + 3 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_lenpos ] = (FT_Byte)( len ); @@ -1645,6 +1706,8 @@ if ( ( flags >> 8 ) == 5 ) /* End of font mark */ break; + FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer" + " %p + 0x%08x\n", i, pfb_data, pfb_pos )); if ( pfb_pos + 6 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_pos++] = 0x80; @@ -1660,16 +1723,18 @@ pfb_data[pfb_pos++] = 0; } - error = FT_ERR( Cannot_Open_Resource ); if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len ) goto Exit2; + FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer" + " %p + 0x%08x\n", i, rlen, pfb_data, pfb_pos )); error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); if ( error ) goto Exit2; pfb_pos += rlen; } + error = FT_ERR( Array_Too_Large ); if ( pfb_pos + 2 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_pos++] = 0x80; @@ -1690,6 +1755,13 @@ aface ); Exit2: + if ( error == FT_ERR( Array_Too_Large ) ) + FT_TRACE2(( " Abort due to too-short buffer to store" + " all POST fragments\n" )); + else if ( error == FT_ERR( Invalid_Offset ) ) + FT_TRACE2(( " Abort due to invalid offset in a POST fragment\n" )); + if ( error ) + error = FT_ERR( Cannot_Open_Resource ); FT_FREE( pfb_data ); Exit: @@ -1700,7 +1772,7 @@ /* The resource header says we've got resource_cnt `sfnt' */ /* (TrueType/OpenType) resources in this file. Look through */ /* them for the one indicated by face_index, load it into mem, */ - /* pass it on the the truetype driver and return it. */ + /* pass it on to the truetype driver, and return it. */ /* */ static FT_Error Mac_Read_sfnt_Resource( FT_Library library, @@ -1713,18 +1785,18 @@ FT_Memory memory = library->memory; FT_Byte* sfnt_data = NULL; FT_Error error; - FT_Long flag_offset; + FT_ULong flag_offset; FT_Long rlen; int is_cff; FT_Long face_index_in_resource = 0; - if ( face_index == -1 ) - face_index = 0; + if ( face_index < 0 ) + face_index = -face_index - 1; if ( face_index >= resource_cnt ) return FT_THROW( Cannot_Open_Resource ); - flag_offset = offsets[face_index]; + flag_offset = (FT_ULong)offsets[face_index]; error = FT_Stream_Seek( stream, flag_offset ); if ( error ) goto Exit; @@ -1733,6 +1805,8 @@ goto Exit; if ( rlen == -1 ) return FT_THROW( Cannot_Open_Resource ); + if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN ) + return FT_THROW( Invalid_Offset ); error = open_face_PS_from_sfnt_stream( library, stream, @@ -1743,19 +1817,22 @@ goto Exit; /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ - if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) + error = FT_Stream_Seek( stream, flag_offset + 4 ); + if ( error ) goto Exit; - if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) + if ( FT_ALLOC( sfnt_data, rlen ) ) return error; - error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); - if ( error ) + error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, (FT_ULong)rlen ); + if ( error ) { + FT_FREE( sfnt_data ); goto Exit; + } is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); error = open_face_from_buffer( library, sfnt_data, - rlen, + (FT_ULong)rlen, face_index_in_resource, is_cff ? "cff" : "truetype", aface ); @@ -1789,9 +1866,10 @@ if ( error ) return error; + /* POST resources must be sorted to concatenate properly */ error = FT_Raccess_Get_DataOffsets( library, stream, map_offset, rdara_pos, - TTAG_POST, + TTAG_POST, TRUE, &data_offsets, &count ); if ( !error ) { @@ -1804,9 +1882,11 @@ return error; } + /* sfnt resources should not be sorted to preserve the face order by + QuickDraw API */ error = FT_Raccess_Get_DataOffsets( library, stream, map_offset, rdara_pos, - TTAG_sfnt, + TTAG_sfnt, FALSE, &data_offsets, &count ); if ( !error ) { @@ -1849,13 +1929,14 @@ if ( error ) goto Exit; - if ( header[ 0] != 0 || - header[74] != 0 || - header[82] != 0 || - header[ 1] == 0 || - header[ 1] > 33 || - header[63] != 0 || - header[2 + header[1]] != 0 ) + if ( header[ 0] != 0 || + header[74] != 0 || + header[82] != 0 || + header[ 1] == 0 || + header[ 1] > 33 || + header[63] != 0 || + header[2 + header[1]] != 0 || + header[0x53] > 0x7F ) return FT_THROW( Unknown_File_Format ); dlen = ( header[0x53] << 24 ) | @@ -1866,7 +1947,7 @@ rlen = ( header[0x57] << 24 ) | ( header[0x58] << 16 ) | ( header[0x59] << 8 ) | - header[0x5a]; + header[0x5A]; #endif /* 0 */ offset = 128 + ( ( dlen + 127 ) & ~127 ); @@ -1890,7 +1971,7 @@ FT_Memory memory = library->memory; FT_Error error = FT_ERR( Unknown_File_Format ); - int i; + FT_UInt i; char * file_names[FT_RACCESS_N_RULES]; FT_Long offsets[FT_RACCESS_N_RULES]; @@ -1898,7 +1979,7 @@ FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */ FT_Open_Args args2; - FT_Stream stream2 = 0; + FT_Stream stream2 = NULL; FT_Raccess_Guess( library, stream, @@ -1992,7 +2073,11 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_raccess - FT_TRACE3(( "Try as dfont: %s ...", args->pathname )); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE3(( "Try as dfont: " )); + if ( !( args->flags & FT_OPEN_MEMORY ) ) + FT_TRACE3(( "%s ...", args->pathname )); +#endif error = IsMacResource( library, stream, 0, face_index, aface ); @@ -2034,8 +2119,7 @@ FT_Module* limit; - /* test for valid `library' delayed to */ - /* FT_Stream_New() */ + /* test for valid `library' delayed to `FT_Stream_New' */ if ( ( !aface && face_index >= 0 ) || !args ) return FT_THROW( Invalid_Argument ); @@ -2060,7 +2144,7 @@ if ( FT_MODULE_IS_DRIVER( driver ) ) { FT_Int num_params = 0; - FT_Parameter* params = 0; + FT_Parameter* params = NULL; if ( args->flags & FT_OPEN_PARAMS ) @@ -2069,7 +2153,7 @@ params = args->params; } - error = open_face( driver, stream, face_index, + error = open_face( driver, &stream, external_stream, face_index, num_params, params, &face ); if ( !error ) goto Success; @@ -2094,7 +2178,7 @@ if ( FT_MODULE_IS_DRIVER( cur[0] ) ) { FT_Int num_params = 0; - FT_Parameter* params = 0; + FT_Parameter* params = NULL; driver = FT_DRIVER( cur[0] ); @@ -2105,7 +2189,7 @@ params = args->params; } - error = open_face( driver, stream, face_index, + error = open_face( driver, &stream, external_stream, face_index, num_params, params, &face ); if ( !error ) goto Success; @@ -2115,7 +2199,8 @@ FT_ERR_EQ( error, Table_Missing ) ) { /* TrueType but essential tables are missing */ - if ( FT_Stream_Seek( stream, 0 ) ) + error = FT_Stream_Seek( stream, 0 ); + if ( error ) break; error = open_face_PS_from_sfnt_stream( library, @@ -2174,10 +2259,6 @@ Success: FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); - /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ - if ( external_stream ) - face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; - /* add the face object to its driver's list */ if ( FT_NEW( node ) ) goto Fail; @@ -2286,7 +2367,7 @@ FT_Open_Args open; - /* test for valid `face' delayed to FT_Attach_Stream() */ + /* test for valid `face' delayed to `FT_Attach_Stream' */ if ( !filepathname ) return FT_THROW( Invalid_Argument ); @@ -2312,7 +2393,7 @@ FT_Driver_Class clazz; - /* test for valid `parameters' delayed to FT_Stream_New() */ + /* test for valid `parameters' delayed to `FT_Stream_New' */ if ( !face ) return FT_THROW( Invalid_Face_Handle ); @@ -2348,6 +2429,9 @@ FT_EXPORT_DEF( FT_Error ) FT_Reference_Face( FT_Face face ) { + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + face->internal->refcount++; return FT_Err_Ok; @@ -2406,20 +2490,20 @@ FT_Driver driver; FT_Driver_Class clazz; - FT_Size size = 0; - FT_ListNode node = 0; + FT_Size size = NULL; + FT_ListNode node = NULL; if ( !face ) return FT_THROW( Invalid_Face_Handle ); if ( !asize ) - return FT_THROW( Invalid_Size_Handle ); + return FT_THROW( Invalid_Argument ); if ( !face->driver ) return FT_THROW( Invalid_Driver_Handle ); - *asize = 0; + *asize = NULL; driver = face->driver; clazz = driver->clazz; @@ -2432,7 +2516,7 @@ size->face = face; /* for now, do not use any internal fields in size objects */ - size->internal = 0; + size->internal = NULL; if ( clazz->init_size ) error = clazz->init_size( size ); @@ -2490,7 +2574,7 @@ if ( face->size == size ) { - face->size = 0; + face->size = NULL; if ( face->sizes_list.head ) face->size = (FT_Size)(face->sizes_list.head->data); } @@ -2923,6 +3007,8 @@ FT_Size_RequestRec req; + /* check of `face' delayed to `FT_Request_Size' */ + if ( !char_width ) char_width = char_height; else if ( !char_height ) @@ -2961,6 +3047,8 @@ FT_Size_RequestRec req; + /* check of `face' delayed to `FT_Request_Size' */ + if ( pixel_width == 0 ) pixel_width = pixel_height; else if ( pixel_height == 0 ) @@ -2972,14 +3060,14 @@ pixel_height = 1; /* use `>=' to avoid potential compiler warning on 16bit platforms */ - if ( pixel_width >= 0xFFFFU ) - pixel_width = 0xFFFFU; + if ( pixel_width >= 0xFFFFU ) + pixel_width = 0xFFFFU; if ( pixel_height >= 0xFFFFU ) pixel_height = 0xFFFFU; req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; - req.width = pixel_width << 6; - req.height = pixel_height << 6; + req.width = (FT_Long)( pixel_width << 6 ); + req.height = (FT_Long)( pixel_height << 6 ); req.horiResolution = 0; req.vertResolution = 0; @@ -3026,18 +3114,37 @@ if ( kern_mode != FT_KERNING_UNFITTED ) { + FT_Pos orig_x = akerning->x; + FT_Pos orig_y = akerning->y; + + /* we scale down kerning values for small ppem values */ /* to avoid that rounding makes them too big. */ /* `25' has been determined heuristically. */ if ( face->size->metrics.x_ppem < 25 ) - akerning->x = FT_MulDiv( akerning->x, + akerning->x = FT_MulDiv( orig_x, face->size->metrics.x_ppem, 25 ); if ( face->size->metrics.y_ppem < 25 ) - akerning->y = FT_MulDiv( akerning->y, + akerning->y = FT_MulDiv( orig_y, face->size->metrics.y_ppem, 25 ); akerning->x = FT_PIX_ROUND( akerning->x ); akerning->y = FT_PIX_ROUND( akerning->y ); + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_Pos orig_x_rounded = FT_PIX_ROUND( orig_x ); + FT_Pos orig_y_rounded = FT_PIX_ROUND( orig_y ); + + + if ( akerning->x != orig_x_rounded || + akerning->y != orig_y_rounded ) + FT_TRACE5(( "FT_Get_Kerning: horizontal kerning" + " (%d, %d) scaled down to (%d, %d) pixels\n", + orig_x_rounded / 64, orig_y_rounded / 64, + akerning->x / 64, akerning->y / 64 )); + } +#endif } } } @@ -3111,15 +3218,6 @@ { if ( cur[0]->encoding == encoding ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), " - "but in too late position to cache\n", - cur - face->charmaps )); - continue; - } -#endif face->charmap = cur[0]; return 0; } @@ -3143,8 +3241,9 @@ return FT_THROW( Invalid_Face_Handle ); cur = face->charmaps; - if ( !cur ) + if ( !cur || !charmap ) return FT_THROW( Invalid_CharMap_Handle ); + if ( FT_Get_CMap_Format( charmap ) == 14 ) return FT_THROW( Invalid_Argument ); @@ -3154,19 +3253,11 @@ { if ( cur[0] == charmap ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), " - "but in too late position to cache\n", - cur - face->charmaps )); - continue; - } -#endif face->charmap = cur[0]; - return 0; + return FT_Err_Ok; } } + return FT_THROW( Invalid_Argument ); } @@ -3188,15 +3279,6 @@ FT_ASSERT( i < charmap->face->num_charmaps ); -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( i > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), " - "but in too late position to cache\n", - i )); - return -i; - } -#endif return i; } @@ -3333,8 +3415,12 @@ FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); FT_TRACE1(( " 0x%x is truncated\n", charcode )); } + result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); + if ( result >= (FT_UInt)face->num_glyphs ) + result = 0; } + return result; } @@ -3349,10 +3435,11 @@ FT_UInt gindex = 0; + /* only do something if we have a charmap, and we have glyphs at all */ if ( face && face->charmap && face->num_glyphs ) { gindex = FT_Get_Char_Index( face, 0 ); - if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs ) + if ( gindex == 0 ) result = FT_Get_Next_Char( face, 0, &gindex ); } @@ -3380,8 +3467,10 @@ FT_CMap cmap = FT_CMAP( face->charmap ); - do { + do + { gindex = cmap->clazz->char_next( cmap, &code ); + } while ( gindex >= (FT_UInt)face->num_glyphs ); result = ( gindex == 0 ) ? 0 : code; @@ -3404,8 +3493,9 @@ FT_UInt result = 0; - if ( face && face->charmap && - face->charmap->encoding == FT_ENCODING_UNICODE ) + if ( face && + face->charmap && + face->charmap->encoding == FT_ENCODING_UNICODE ) { FT_CharMap charmap = find_variant_selector_charmap( face ); FT_CMap ucmap = FT_CMAP( face->charmap ); @@ -3583,7 +3673,9 @@ FT_UInt result = 0; - if ( face && FT_HAS_GLYPH_NAMES( face ) ) + if ( face && + FT_HAS_GLYPH_NAMES( face ) && + glyph_name ) { FT_Service_GlyphDict service; @@ -3608,27 +3700,30 @@ FT_Pointer buffer, FT_UInt buffer_max ) { - FT_Error error = FT_ERR( Invalid_Argument ); + FT_Error error; + FT_Service_GlyphDict service; - /* clean up buffer */ - if ( buffer && buffer_max > 0 ) - ((FT_Byte*)buffer)[0] = 0; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); - if ( face && - (FT_Long)glyph_index <= face->num_glyphs && - FT_HAS_GLYPH_NAMES( face ) ) - { - FT_Service_GlyphDict service; + if ( !buffer || buffer_max == 0 ) + return FT_THROW( Invalid_Argument ); + /* clean up buffer */ + ((FT_Byte*)buffer)[0] = '\0'; - FT_FACE_LOOKUP_SERVICE( face, - service, - GLYPH_DICT ); + if ( (FT_Long)glyph_index >= face->num_glyphs ) + return FT_THROW( Invalid_Glyph_Index ); - if ( service && service->get_name ) - error = service->get_name( face, glyph_index, buffer, buffer_max ); - } + if ( !FT_HAS_GLYPH_NAMES( face ) ) + return FT_THROW( Invalid_Argument ); + + FT_FACE_LOOKUP_SERVICE( face, service, GLYPH_DICT ); + if ( service && service->get_name ) + error = service->get_name( face, glyph_index, buffer, buffer_max ); + else + error = FT_THROW( Invalid_Argument ); return error; } @@ -3669,7 +3764,7 @@ FT_Get_Sfnt_Table( FT_Face face, FT_Sfnt_Tag tag ) { - void* table = 0; + void* table = NULL; FT_Service_SFNT_Table service; @@ -3719,6 +3814,8 @@ FT_ULong offset; + /* test for valid `length' delayed to `service->table_info' */ + if ( !face || !FT_IS_SFNT( face ) ) return FT_THROW( Invalid_Face_Handle ); @@ -3786,12 +3883,12 @@ FT_Face face; - if ( size == NULL ) - return FT_THROW( Invalid_Argument ); + if ( !size ) + return FT_THROW( Invalid_Size_Handle ); face = size->face; - if ( face == NULL || face->driver == NULL ) - return FT_THROW( Invalid_Argument ); + if ( !face || !face->driver ) + return FT_THROW( Invalid_Face_Handle ); /* we don't need anything more complex than that; all size objects */ /* are already listed by the face */ @@ -3820,7 +3917,7 @@ FT_ListNode* node ) { FT_ListNode cur; - FT_Renderer result = 0; + FT_Renderer result = NULL; if ( !library ) @@ -3832,7 +3929,7 @@ { if ( *node ) cur = (*node)->next; - *node = 0; + *node = NULL; } while ( cur ) @@ -3933,11 +4030,17 @@ static void ft_remove_renderer( FT_Module module ) { - FT_Library library = module->library; - FT_Memory memory = library->memory; + FT_Library library; + FT_Memory memory; FT_ListNode node; + library = module->library; + if ( !library ) + return; + + memory = library->memory; + node = FT_List_Find( &library->renderers, module ); if ( node ) { @@ -3964,7 +4067,7 @@ FT_Get_Renderer( FT_Library library, FT_Glyph_Format format ) { - /* test for valid `library' delayed to FT_Lookup_Renderer() */ + /* test for valid `library' delayed to `FT_Lookup_Renderer' */ return FT_Lookup_Renderer( library, format, 0 ); } @@ -3981,12 +4084,26 @@ FT_ListNode node; FT_Error error = FT_Err_Ok; + FT_Renderer_SetModeFunc set_mode; + if ( !library ) - return FT_THROW( Invalid_Library_Handle ); + { + error = FT_THROW( Invalid_Library_Handle ); + goto Exit; + } if ( !renderer ) - return FT_THROW( Invalid_Argument ); + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( num_params > 0 && !parameters ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } node = FT_List_Find( &library->renderers, renderer ); if ( !node ) @@ -4000,18 +4117,14 @@ if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE ) library->cur_renderer = renderer; - if ( num_params > 0 ) - { - FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode; - + set_mode = renderer->clazz->set_mode; - for ( ; num_params > 0; num_params-- ) - { - error = set_mode( renderer, parameters->tag, parameters->data ); - if ( error ) - break; - parameters++; - } + for ( ; num_params > 0; num_params-- ) + { + error = set_mode( renderer, parameters->tag, parameters->data ); + if ( error ) + break; + parameters++; } Exit: @@ -4036,8 +4149,7 @@ default: { - FT_ListNode node = 0; - FT_Bool update = 0; + FT_ListNode node = NULL; /* small shortcut for the very common case */ @@ -4064,13 +4176,7 @@ /* now, look for another renderer that supports the same */ /* format. */ renderer = FT_Lookup_Renderer( library, slot->format, &node ); - update = 1; } - - /* if we changed the current renderer for the glyph image format */ - /* we need to select it as the next current one */ - if ( !error && update && renderer ) - FT_Set_Renderer( library, renderer, 0, 0 ); } } @@ -4079,35 +4185,51 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_bitmap - /* we convert to a single bitmap format for computing the checksum */ - { - FT_Bitmap bitmap; - FT_Error err; - - - FT_Bitmap_New( &bitmap ); + /* + * Computing the MD5 checksum is expensive, unnecessarily distorting a + * possible profiling of FreeType if compiled with tracing support. For + * this reason, we execute the following code only if explicitly + * requested. + */ - err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); - if ( !err ) + /* we use FT_TRACE3 in this block */ + if ( ft_trace_levels[trace_bitmap] >= 3 ) + { + /* we convert to a single bitmap format for computing the checksum */ + if ( !error ) { - MD5_CTX ctx; - unsigned char md5[16]; - int i; + FT_Bitmap bitmap; + FT_Error err; - MD5_Init( &ctx); - MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch ); - MD5_Final( md5, &ctx ); + FT_Bitmap_Init( &bitmap ); - FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" - " ", - bitmap.rows, bitmap.pitch )); - for ( i = 0; i < 16; i++ ) - FT_TRACE3(( "%02X", md5[i] )); - FT_TRACE3(( "\n" )); - } + /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */ + err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); + if ( !err ) + { + MD5_CTX ctx; + unsigned char md5[16]; + int i; + unsigned int rows = bitmap.rows; + unsigned int pitch = (unsigned int)bitmap.pitch; + + + MD5_Init( &ctx ); + if ( bitmap.buffer ) + MD5_Update( &ctx, bitmap.buffer, rows * pitch ); + MD5_Final( md5, &ctx ); + + FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" + " ", + rows, pitch )); + for ( i = 0; i < 16; i++ ) + FT_TRACE3(( "%02X", md5[i] )); + FT_TRACE3(( "\n" )); + } - FT_Bitmap_Done( library, &bitmap ); + FT_Bitmap_Done( library, &bitmap ); + } } #undef FT_COMPONENT @@ -4174,7 +4296,7 @@ if ( library && library->auto_hinter == module ) - library->auto_hinter = 0; + library->auto_hinter = NULL; /* if the module is a renderer */ if ( FT_MODULE_IS_RENDERER( module ) ) @@ -4201,7 +4323,7 @@ { FT_Error error; FT_Memory memory; - FT_Module module; + FT_Module module = NULL; FT_UInt nn; @@ -4270,17 +4392,10 @@ /* if the module is a font driver */ if ( FT_MODULE_IS_DRIVER( module ) ) { - /* allocate glyph loader if needed */ FT_Driver driver = FT_DRIVER( module ); driver->clazz = (FT_Driver_Class)module->clazz; - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - { - error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); - if ( error ) - goto Fail; - } } if ( clazz->module_init ) @@ -4297,15 +4412,6 @@ return error; Fail: - if ( FT_MODULE_IS_DRIVER( module ) ) - { - FT_Driver driver = FT_DRIVER( module ); - - - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - FT_GlyphLoader_Done( driver->glyph_loader ); - } - if ( FT_MODULE_IS_RENDERER( module ) ) { FT_Renderer renderer = FT_RENDERER( module ); @@ -4328,7 +4434,7 @@ FT_Get_Module( FT_Library library, const char* module_name ) { - FT_Module result = 0; + FT_Module result = NULL; FT_Module* cur; FT_Module* limit; @@ -4440,7 +4546,7 @@ cur[0] = cur[1]; cur++; } - limit[0] = 0; + limit[0] = NULL; /* destroy the module */ Destroy_Module( module ); @@ -4453,7 +4559,7 @@ } - FT_Error + static FT_Error ft_property_do( FT_Library library, const FT_String* module_name, const FT_String* property_name, @@ -4583,6 +4689,9 @@ FT_EXPORT_DEF( FT_Error ) FT_Reference_Library( FT_Library library ) { + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + library->refcount++; return FT_Err_Ok; @@ -4599,7 +4708,7 @@ FT_Error error; - if ( !memory ) + if ( !memory || !alibrary ) return FT_THROW( Invalid_Argument ); #ifdef FT_DEBUG_LEVEL_ERROR @@ -4620,12 +4729,9 @@ goto Fail; #endif - /* allocate the render pool */ - library->raster_pool_size = FT_RENDER_POOL_SIZE; -#if FT_RENDER_POOL_SIZE > 0 - if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) - goto Fail; -#endif + /* we don't use raster_pool anymore. */ + library->raster_pool_size = 0; + library->raster_pool = NULL; library->version_major = FREETYPE_MAJOR; library->version_minor = FREETYPE_MINOR; @@ -4638,8 +4744,8 @@ return FT_Err_Ok; - Fail: #ifdef FT_CONFIG_OPTION_PIC + Fail: ft_pic_container_destroy( library ); #endif FT_FREE( library ); @@ -4768,16 +4874,12 @@ if ( module ) { Destroy_Module( module ); - library->modules[n] = 0; + library->modules[n] = NULL; } } } #endif - /* Destroy raster objects */ - FT_FREE( library->raster_pool ); - library->raster_pool_size = 0; - #ifdef FT_CONFIG_OPTION_PIC /* Destroy pic container contents */ ft_pic_container_destroy( library ); @@ -4861,6 +4963,8 @@ *p_arg1 = subg->arg1; *p_arg2 = subg->arg2; *p_transform = subg->transform; + + error = FT_Err_Ok; } return error; diff --git a/drivers/freetype/freetype/src/base/ftotval.c b/drivers/freetype/src/base/ftotval.c index 5fc73d76ab..fe54e0228a 100644 --- a/drivers/freetype/freetype/src/base/ftotval.c +++ b/drivers/freetype/src/base/ftotval.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (body). */ /* */ -/* Copyright 2004, 2006, 2008, 2010, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/base/ftoutln.c b/drivers/freetype/src/base/ftoutln.c index 54ca5cdcf6..fc28225c6a 100644 --- a/drivers/freetype/freetype/src/base/ftoutln.c +++ b/drivers/freetype/src/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2008, 2010, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,7 +42,7 @@ static - const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; + const FT_Outline null_outline = { 0, 0, NULL, NULL, NULL, 0 }; /* documentation is in ftoutln.h */ @@ -52,8 +52,9 @@ const FT_Outline_Funcs* func_interface, void* user ) { -#undef SCALED -#define SCALED( x ) ( ( (x) << shift ) - delta ) +#undef SCALED +#define SCALED( x ) ( ( (x) < 0 ? -( -(x) << shift ) \ + : ( (x) << shift ) ) - delta ) FT_Vector v_last; FT_Vector v_control; @@ -73,7 +74,10 @@ FT_Pos delta; - if ( !outline || !func_interface ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !func_interface ) return FT_THROW( Invalid_Argument ); shift = func_interface->shift; @@ -128,7 +132,7 @@ v_start.x = ( v_start.x + v_last.x ) / 2; v_start.y = ( v_start.y + v_last.y ) / 2; - v_last = v_start; + /* v_last = v_start; */ } point--; tags--; @@ -276,7 +280,7 @@ if ( error ) goto Exit; - first = last + 1; + first = (FT_UInt)last + 1; } FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); @@ -317,7 +321,7 @@ FT_NEW_ARRAY( anoutline->contours, numContours ) ) goto Fail; - anoutline->n_points = (FT_UShort)numPoints; + anoutline->n_points = (FT_Short)numPoints; anoutline->n_contours = (FT_Short)numContours; anoutline->flags |= FT_OUTLINE_OWNER; @@ -362,7 +366,7 @@ /* empty glyph? */ if ( n_points == 0 && n_contours == 0 ) - return 0; + return FT_Err_Ok; /* check point and contour counts */ if ( n_points <= 0 || n_contours <= 0 ) @@ -384,7 +388,7 @@ goto Bad; /* XXX: check the tags array */ - return 0; + return FT_Err_Ok; } Bad: @@ -401,19 +405,24 @@ FT_Int is_owner; - if ( !source || !target || - source->n_points != target->n_points || + if ( !source || !target ) + return FT_THROW( Invalid_Outline ); + + if ( source->n_points != target->n_points || source->n_contours != target->n_contours ) return FT_THROW( Invalid_Argument ); if ( source == target ) return FT_Err_Ok; - FT_ARRAY_COPY( target->points, source->points, source->n_points ); - - FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + if ( source->n_points ) + { + FT_ARRAY_COPY( target->points, source->points, source->n_points ); + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + } - FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); + if ( source->n_contours ) + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); /* copy all flags, except the `FT_OUTLINE_OWNER' one */ is_owner = target->flags & FT_OUTLINE_OWNER; @@ -430,20 +439,21 @@ FT_Outline_Done_Internal( FT_Memory memory, FT_Outline* outline ) { - if ( memory && outline ) - { - if ( outline->flags & FT_OUTLINE_OWNER ) - { - FT_FREE( outline->points ); - FT_FREE( outline->tags ); - FT_FREE( outline->contours ); - } - *outline = null_outline; + if ( !outline ) + return FT_THROW( Invalid_Outline ); - return FT_Err_Ok; - } - else + if ( !memory ) return FT_THROW( Invalid_Argument ); + + if ( outline->flags & FT_OUTLINE_OWNER ) + { + FT_FREE( outline->points ); + FT_FREE( outline->tags ); + FT_FREE( outline->contours ); + } + *outline = null_outline; + + return FT_Err_Ok; } @@ -576,11 +586,13 @@ { char* p = outline->tags + first; char* q = outline->tags + last; - char swap; while ( p < q ) { + char swap; + + swap = *p; *p = *q; *q = swap; @@ -604,7 +616,6 @@ FT_Raster_Params* params ) { FT_Error error; - FT_Bool update = FALSE; FT_Renderer renderer; FT_ListNode node; @@ -612,7 +623,10 @@ if ( !library ) return FT_THROW( Invalid_Library_Handle ); - if ( !outline || !params ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !params ) return FT_THROW( Invalid_Argument ); renderer = library->cur_renderer; @@ -635,14 +649,8 @@ /* format */ renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, &node ); - update = TRUE; } - /* if we changed the current renderer for the glyph image format */ - /* we need to select it as the next current one */ - if ( !error && update && renderer ) - FT_Set_Renderer( library, renderer, 0, 0 ); - return error; } @@ -660,7 +668,7 @@ if ( !abitmap ) return FT_THROW( Invalid_Argument ); - /* other checks are delayed to FT_Outline_Render() */ + /* other checks are delayed to `FT_Outline_Render' */ params.target = abitmap; params.flags = 0; @@ -721,7 +729,8 @@ #if 0 #define FT_OUTLINE_GET_CONTOUR( outline, c, first, last ) \ - do { \ + do \ + { \ (first) = ( c > 0 ) ? (outline)->points + \ (outline)->contours[c - 1] + 1 \ : (outline)->points; \ @@ -902,13 +911,12 @@ FT_Pos ystrength ) { FT_Vector* points; - FT_Vector v_prev, v_first, v_next, v_cur; - FT_Int c, n, first; + FT_Int c, first, last; FT_Int orientation; if ( !outline ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Outline ); xstrength /= 2; ystrength /= 2; @@ -929,87 +937,98 @@ first = 0; for ( c = 0; c < outline->n_contours; c++ ) { - FT_Vector in, out, shift; - FT_Fixed l_in, l_out, l, q, d; - int last = outline->contours[c]; + FT_Vector in, out, anchor, shift; + FT_Fixed l_in, l_out, l_anchor = 0, l, q, d; + FT_Int i, j, k; - v_first = points[first]; - v_prev = points[last]; - v_cur = v_first; + l_in = 0; + last = outline->contours[c]; - /* compute incoming normalized vector */ - in.x = v_cur.x - v_prev.x; - in.y = v_cur.y - v_prev.y; - l_in = FT_Vector_Length( &in ); - if ( l_in ) - { - in.x = FT_DivFix( in.x, l_in ); - in.y = FT_DivFix( in.y, l_in ); - } + /* pacify compiler */ + in.x = in.y = anchor.x = anchor.y = 0; - for ( n = first; n <= last; n++ ) + /* Counter j cycles though the points; counter i advances only */ + /* when points are moved; anchor k marks the first moved point. */ + for ( i = last, j = first, k = -1; + j != i && i != k; + j = j < last ? j + 1 : first ) { - if ( n < last ) - v_next = points[n + 1]; - else - v_next = v_first; + if ( j != k ) + { + out.x = points[j].x - points[i].x; + out.y = points[j].y - points[i].y; + l_out = (FT_Fixed)FT_Vector_NormLen( &out ); - /* compute outgoing normalized vector */ - out.x = v_next.x - v_cur.x; - out.y = v_next.y - v_cur.y; - l_out = FT_Vector_Length( &out ); - if ( l_out ) + if ( l_out == 0 ) + continue; + } + else { - out.x = FT_DivFix( out.x, l_out ); - out.y = FT_DivFix( out.y, l_out ); + out = anchor; + l_out = l_anchor; } - d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y ); - - /* shift only if turn is less than ~160 degrees */ - if ( d > -0xF000L ) + if ( l_in != 0 ) { - d = d + 0x10000L; + if ( k < 0 ) + { + k = i; + anchor = in; + l_anchor = l_in; + } - /* shift components are aligned along lateral bisector */ - /* and directed according to the outline orientation. */ - shift.x = in.y + out.y; - shift.y = in.x + out.x; + d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y ); - if ( orientation == FT_ORIENTATION_TRUETYPE ) - shift.x = -shift.x; - else - shift.y = -shift.y; + /* shift only if turn is less than ~160 degrees */ + if ( d > -0xF000L ) + { + d = d + 0x10000L; - /* restrict shift magnitude to better handle collapsing segments */ - q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x ); - if ( orientation == FT_ORIENTATION_TRUETYPE ) - q = -q; + /* shift components along lateral bisector in proper orientation */ + shift.x = in.y + out.y; + shift.y = in.x + out.x; - l = FT_MIN( l_in, l_out ); + if ( orientation == FT_ORIENTATION_TRUETYPE ) + shift.x = -shift.x; + else + shift.y = -shift.y; - /* non-strict inequalities avoid divide-by-zero when q == l == 0 */ - if ( FT_MulFix( xstrength, q ) <= FT_MulFix( d, l ) ) - shift.x = FT_MulDiv( shift.x, xstrength, d ); - else - shift.x = FT_MulDiv( shift.x, l, q ); + /* restrict shift magnitude to better handle collapsing segments */ + q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x ); + if ( orientation == FT_ORIENTATION_TRUETYPE ) + q = -q; + + l = FT_MIN( l_in, l_out ); + + /* non-strict inequalities avoid divide-by-zero when q == l == 0 */ + if ( FT_MulFix( xstrength, q ) <= FT_MulFix( l, d ) ) + shift.x = FT_MulDiv( shift.x, xstrength, d ); + else + shift.x = FT_MulDiv( shift.x, l, q ); - if ( FT_MulFix( ystrength, q ) <= FT_MulFix( d, l ) ) - shift.y = FT_MulDiv( shift.y, ystrength, d ); + if ( FT_MulFix( ystrength, q ) <= FT_MulFix( l, d ) ) + shift.y = FT_MulDiv( shift.y, ystrength, d ); + else + shift.y = FT_MulDiv( shift.y, l, q ); + } else - shift.y = FT_MulDiv( shift.y, l, q ); + shift.x = shift.y = 0; + + for ( ; + i != j; + i = i < last ? i + 1 : first ) + { + points[i].x += xstrength + shift.x; + points[i].y += ystrength + shift.y; + } } else - shift.x = shift.y = 0; - - outline->points[n].x = v_cur.x + xstrength + shift.x; - outline->points[n].y = v_cur.y + ystrength + shift.y; + i = j; - in = out; - l_in = l_out; - v_cur = v_next; + in = out; + l_in = l_out; } first = last + 1; @@ -1038,14 +1057,19 @@ /* We use the nonzero winding rule to find the orientation. */ /* Since glyph outlines behave much more `regular' than arbitrary */ /* cubic or quadratic curves, this test deals with the polygon */ - /* only which is spanned up by the control points. */ + /* only that is spanned up by the control points. */ FT_Outline_Get_CBox( outline, &cbox ); - xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14; + /* Handle collapsed outlines to avoid undefined FT_MSB. */ + if ( cbox.xMin == cbox.xMax || cbox.yMin == cbox.yMax ) + return FT_ORIENTATION_NONE; + + xshift = FT_MSB( (FT_UInt32)( FT_ABS( cbox.xMax ) | + FT_ABS( cbox.xMin ) ) ) - 14; xshift = FT_MAX( xshift, 0 ); - yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14; + yshift = FT_MSB( (FT_UInt32)( cbox.yMax - cbox.yMin ) ) - 14; yshift = FT_MAX( yshift, 0 ); points = outline->points; @@ -1056,13 +1080,16 @@ FT_Int last = outline->contours[c]; - v_prev = points[last]; + v_prev.x = points[last].x >> xshift; + v_prev.y = points[last].y >> yshift; for ( n = first; n <= last; n++ ) { - v_cur = points[n]; - area += ( ( v_cur.y - v_prev.y ) >> yshift ) * - ( ( v_cur.x + v_prev.x ) >> xshift ); + v_cur.x = points[n].x >> xshift; + v_cur.y = points[n].y >> yshift; + + area += ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ); + v_prev = v_cur; } diff --git a/drivers/freetype/src/base/ftpatent.c b/drivers/freetype/src/base/ftpatent.c new file mode 100644 index 0000000000..4861be130e --- /dev/null +++ b/drivers/freetype/src/base/ftpatent.c @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* ftpatent.c */ +/* */ +/* FreeType API for checking patented TrueType bytecode instructions */ +/* (body). Obsolete, retained for backwards compatibility. */ +/* */ +/* Copyright 2007-2016 by */ +/* David Turner. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TRUETYPE_GLYF_H + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Face_CheckTrueTypePatents( FT_Face face ) + { + FT_UNUSED( face ); + + return FALSE; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Face_SetUnpatentedHinting( FT_Face face, + FT_Bool value ) + { + FT_UNUSED( face ); + FT_UNUSED( value ); + + return FALSE; + } + +/* END */ diff --git a/drivers/freetype/freetype/src/base/ftpfr.c b/drivers/freetype/src/base/ftpfr.c index 0ba955f01f..81faa529c3 100644 --- a/drivers/freetype/freetype/src/base/ftpfr.c +++ b/drivers/freetype/src/base/ftpfr.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing PFR-specific data (body). */ /* */ -/* Copyright 2002-2004, 2008, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,7 +50,7 @@ if ( !face ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Face_Handle ); service = ft_pfr_check( face ); if ( service ) @@ -106,6 +106,9 @@ if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !avector ) return FT_THROW( Invalid_Argument ); service = ft_pfr_check( face ); @@ -130,11 +133,15 @@ FT_Service_PfrMetrics service; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !aadvance ) + return FT_THROW( Invalid_Argument ); + service = ft_pfr_check( face ); if ( service ) - { error = service->get_advance( face, gindex, aadvance ); - } else /* XXX: TODO: PROVIDE ADVANCE-LOADING METHOD TO ALL FONT DRIVERS */ error = FT_THROW( Invalid_Argument ); diff --git a/drivers/freetype/freetype/src/base/ftpic.c b/drivers/freetype/src/base/ftpic.c index 1c87101696..03769dba22 100644 --- a/drivers/freetype/freetype/src/base/ftpic.c +++ b/drivers/freetype/src/base/ftpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services (body). */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,7 +29,7 @@ ft_pic_container_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; + FT_Error error; FT_MEM_SET( pic_container, 0, sizeof ( *pic_container ) ); diff --git a/drivers/freetype/freetype/src/base/ftrfork.c b/drivers/freetype/src/base/ftrfork.c index 804911721d..4660c971cf 100644 --- a/drivers/freetype/freetype/src/base/ftrfork.c +++ b/drivers/freetype/src/base/ftrfork.c @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (body). */ /* */ -/* Copyright 2004-2010, 2013 by */ +/* Copyright 2004-2016 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ @@ -29,6 +29,7 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_RFORK_H #include "basepic.h" +#include "ftbase.h" #undef FT_COMPONENT #define FT_COMPONENT trace_raccess @@ -62,7 +63,7 @@ FT_UNUSED( library ); - error = FT_Stream_Seek( stream, rfork_offset ); + error = FT_Stream_Seek( stream, (FT_ULong)rfork_offset ); if ( error ) return error; @@ -70,25 +71,36 @@ if ( error ) return error; - *rdata_pos = rfork_offset + ( ( head[0] << 24 ) | - ( head[1] << 16 ) | - ( head[2] << 8 ) | - head[3] ); - map_pos = rfork_offset + ( ( head[4] << 24 ) | - ( head[5] << 16 ) | - ( head[6] << 8 ) | - head[7] ); - rdata_len = ( head[ 8] << 24 ) | - ( head[ 9] << 16 ) | - ( head[10] << 8 ) | - head[11]; + /* ensure positive values */ + if ( head[0] >= 0x80 || head[4] >= 0x80 || head[8] >= 0x80 ) + return FT_THROW( Unknown_File_Format ); + + *rdata_pos = ( head[ 0] << 24 ) | + ( head[ 1] << 16 ) | + ( head[ 2] << 8 ) | + head[ 3]; + map_pos = ( head[ 4] << 24 ) | + ( head[ 5] << 16 ) | + ( head[ 6] << 8 ) | + head[ 7]; + rdata_len = ( head[ 8] << 24 ) | + ( head[ 9] << 16 ) | + ( head[10] << 8 ) | + head[11]; /* map_len = head[12] .. head[15] */ - if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset ) + if ( *rdata_pos != map_pos - rdata_len || map_pos == 0 ) + return FT_THROW( Unknown_File_Format ); + + if ( FT_LONG_MAX - rfork_offset < *rdata_pos || + FT_LONG_MAX - rfork_offset < map_pos ) return FT_THROW( Unknown_File_Format ); - error = FT_Stream_Seek( stream, map_pos ); + *rdata_pos += rfork_offset; + map_pos += rfork_offset; + + error = FT_Stream_Seek( stream, (FT_ULong)map_pos ); if ( error ) return error; @@ -123,7 +135,7 @@ if ( type_list == -1 ) return FT_THROW( Unknown_File_Format ); - error = FT_Stream_Seek( stream, map_pos + type_list ); + error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) ); if ( error ) return error; @@ -151,6 +163,7 @@ FT_Long map_offset, FT_Long rdata_pos, FT_Long tag, + FT_Bool sort_by_res_id, FT_Long **offsets, FT_Long *count ) { @@ -163,7 +176,8 @@ FT_RFork_Ref *ref = NULL; - error = FT_Stream_Seek( stream, map_offset ); + FT_TRACE3(( "\n" )); + error = FT_Stream_Seek( stream, (FT_ULong)map_offset ); if ( error ) return error; @@ -179,17 +193,19 @@ return error; FT_TRACE2(( "Resource tags: %c%c%c%c\n", - (char)( 0xff & ( tag_internal >> 24 ) ), - (char)( 0xff & ( tag_internal >> 16 ) ), - (char)( 0xff & ( tag_internal >> 8 ) ), - (char)( 0xff & ( tag_internal >> 0 ) ) )); + (char)( 0xFF & ( tag_internal >> 24 ) ), + (char)( 0xFF & ( tag_internal >> 16 ) ), + (char)( 0xFF & ( tag_internal >> 8 ) ), + (char)( 0xFF & ( tag_internal >> 0 ) ) )); + FT_TRACE3(( " : subcount=%d, suboffset=0x%04x\n", + subcnt, rpos )); if ( tag_internal == tag ) { *count = subcnt + 1; rpos += map_offset; - error = FT_Stream_Seek( stream, rpos ); + error = FT_Stream_Seek( stream, (FT_ULong)rpos ); if ( error ) return error; @@ -208,11 +224,24 @@ goto Exit; ref[j].offset = temp & 0xFFFFFFL; + FT_TRACE3(( " [%d]:" + " resource_id=0x%04x, offset=0x%08x\n", + j, ref[j].res_id, ref[j].offset )); } - ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), - ( int(*)(const void*, const void*) ) - ft_raccess_sort_ref_by_id ); + if (sort_by_res_id) + { + ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, const void*) ) + ft_raccess_sort_ref_by_id ); + + FT_TRACE3(( " -- sort resources by their ids --\n" )); + for ( j = 0; j < *count; ++ j ) { + FT_TRACE3(( " [%d]:" + " resource_id=0x%04x, offset=0x%08x\n", + j, ref[j].res_id, ref[j].offset )); + } + } if ( FT_NEW_ARRAY( offsets_internal, *count ) ) goto Exit; @@ -374,7 +403,7 @@ errors[i] = FT_Err_Ok; if ( errors[i] ) - continue ; + continue; errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library, stream, base_name, @@ -695,9 +724,9 @@ FT_UShort n_of_entries; int i; - FT_UInt32 entry_id, entry_offset, entry_length = 0; + FT_Int32 entry_id, entry_offset, entry_length = 0; - const FT_UInt32 resource_fork_entry_id = 0x2; + const FT_Int32 resource_fork_entry_id = 0x2; FT_UNUSED( library ); FT_UNUSED( base_file_name ); @@ -795,7 +824,9 @@ tmp = ft_strrchr( original_name, '/' ); if ( tmp ) { - ft_strncpy( new_name, original_name, tmp - original_name + 1 ); + ft_strncpy( new_name, + original_name, + (size_t)( tmp - original_name + 1 ) ); new_name[tmp - original_name + 1] = '\0'; slash = tmp + 1; } diff --git a/drivers/freetype/freetype/src/base/ftsnames.c b/drivers/freetype/src/base/ftsnames.c index 260e91c148..ce7964118c 100644 --- a/drivers/freetype/freetype/src/base/ftsnames.c +++ b/drivers/freetype/src/base/ftsnames.c @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2001, 2002, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/base/ftstream.c b/drivers/freetype/src/base/ftstream.c index d965333daa..bb512a7ccb 100644 --- a/drivers/freetype/freetype/src/base/ftstream.c +++ b/drivers/freetype/src/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2002, 2004-2006, 2008-2011, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,9 +39,9 @@ stream->base = (FT_Byte*) base; stream->size = size; stream->pos = 0; - stream->cursor = 0; - stream->read = 0; - stream->close = 0; + stream->cursor = NULL; + stream->read = NULL; + stream->close = NULL; } @@ -95,11 +95,11 @@ if ( distance < 0 ) return FT_THROW( Invalid_Stream_Operation ); - return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); + return FT_Stream_Seek( stream, stream->pos + (FT_ULong)distance ); } - FT_BASE_DEF( FT_Long ) + FT_BASE_DEF( FT_ULong ) FT_Stream_Pos( FT_Stream stream ) { return stream->pos; @@ -203,8 +203,8 @@ *pbytes = (FT_Byte*)stream->cursor; /* equivalent to FT_Stream_ExitFrame(), with no memory block release */ - stream->cursor = 0; - stream->limit = 0; + stream->cursor = NULL; + stream->limit = NULL; } return error; @@ -226,7 +226,7 @@ FT_FREE( *pbytes ); #endif } - *pbytes = 0; + *pbytes = NULL; } @@ -260,7 +260,9 @@ #ifdef FT_DEBUG_MEMORY /* assume _ft_debug_file and _ft_debug_lineno are already set */ - stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error ); + stream->base = (unsigned char*)ft_mem_qalloc( memory, + (FT_Long)count, + &error ); if ( error ) goto Exit; #else @@ -333,8 +335,8 @@ FT_FREE( stream->base ); #endif } - stream->cursor = 0; - stream->limit = 0; + stream->cursor = NULL; + stream->limit = NULL; } @@ -348,7 +350,7 @@ result = 0; if ( stream->cursor < stream->limit ) - result = *stream->cursor++; + result = (FT_Char)*stream->cursor++; return result; } @@ -357,8 +359,8 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_GetUShort( FT_Stream stream ) { - FT_Byte* p; - FT_Short result; + FT_Byte* p; + FT_UShort result; FT_ASSERT( stream && stream->cursor ); @@ -376,8 +378,8 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_GetUShortLE( FT_Stream stream ) { - FT_Byte* p; - FT_Short result; + FT_Byte* p; + FT_UShort result; FT_ASSERT( stream && stream->cursor ); @@ -396,7 +398,7 @@ FT_Stream_GetUOffset( FT_Stream stream ) { FT_Byte* p; - FT_Long result; + FT_ULong result; FT_ASSERT( stream && stream->cursor ); @@ -414,7 +416,7 @@ FT_Stream_GetULong( FT_Stream stream ) { FT_Byte* p; - FT_Long result; + FT_ULong result; FT_ASSERT( stream && stream->cursor ); @@ -432,7 +434,7 @@ FT_Stream_GetULongLE( FT_Stream stream ) { FT_Byte* p; - FT_Long result; + FT_ULong result; FT_ASSERT( stream && stream->cursor ); @@ -471,7 +473,7 @@ } stream->pos++; - return result; + return (FT_Char)result; Fail: *error = FT_THROW( Invalid_Stream_Operation ); @@ -485,11 +487,11 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_ReadUShort( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_UShort result = 0; FT_ASSERT( stream ); @@ -506,9 +508,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_USHORT( p ); @@ -532,11 +532,11 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_ReadUShortLE( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_UShort result = 0; FT_ASSERT( stream ); @@ -553,9 +553,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_USHORT_LE( p ); @@ -579,11 +577,11 @@ FT_BASE_DEF( FT_ULong ) FT_Stream_ReadUOffset( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { FT_Byte reads[3]; - FT_Byte* p = 0; - FT_Long result = 0; + FT_Byte* p = 0; + FT_ULong result = 0; FT_ASSERT( stream ); @@ -600,9 +598,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_UOFF3( p ); @@ -626,11 +622,11 @@ FT_BASE_DEF( FT_ULong ) FT_Stream_ReadULong( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; + FT_Byte* p = 0; + FT_ULong result = 0; FT_ASSERT( stream ); @@ -647,9 +643,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_ULONG( p ); @@ -673,11 +667,11 @@ FT_BASE_DEF( FT_ULong ) FT_Stream_ReadULongLE( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; + FT_Byte* p = 0; + FT_ULong result = 0; FT_ASSERT( stream ); @@ -694,9 +688,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_ULONG_LE( p ); @@ -728,9 +720,12 @@ FT_Byte* cursor; - if ( !fields || !stream ) + if ( !fields ) return FT_THROW( Invalid_Argument ); + if ( !stream ) + return FT_THROW( Invalid_Stream_Handle ); + cursor = stream->cursor; error = FT_Err_Ok; @@ -783,7 +778,7 @@ case ft_frame_short_be: case ft_frame_ushort_be: /* read a 2-byte big-endian short */ - value = FT_NEXT_USHORT( cursor) ; + value = FT_NEXT_USHORT( cursor ); sign_shift = 16; break; diff --git a/drivers/freetype/freetype/src/base/ftstroke.c b/drivers/freetype/src/base/ftstroke.c index ee61ceca0e..4f3c4937b5 100644 --- a/drivers/freetype/freetype/src/base/ftstroke.c +++ b/drivers/freetype/src/base/ftstroke.c @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002-2006, 2008-2011, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,16 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + + + /* declare an extern to access `ft_outline_glyph_class' globally */ + /* allocated in `ftglyph.c', and use the FT_OUTLINE_GLYPH_CLASS_GET */ + /* macro to access it when FT_CONFIG_OPTION_PIC is defined */ +#ifndef FT_CONFIG_OPTION_PIC + FT_CALLBACK_TABLE const FT_Glyph_Class ft_outline_glyph_class; +#endif + /* documentation is in ftstroke.h */ @@ -347,7 +357,7 @@ ft_stroke_border_close( FT_StrokeBorder border, FT_Bool reverse ) { - FT_UInt start = border->start; + FT_UInt start = (FT_UInt)border->start; FT_UInt count = border->num_points; @@ -599,7 +609,7 @@ if ( border->start >= 0 ) ft_stroke_border_close( border, FALSE ); - border->start = border->num_points; + border->start = (FT_Int)border->num_points; border->movable = FALSE; return ft_stroke_border_lineto( border, to, FALSE ); @@ -702,9 +712,10 @@ FT_Outline* outline ) { /* copy point locations */ - FT_ARRAY_COPY( outline->points + outline->n_points, - border->points, - border->num_points ); + if ( border->num_points ) + FT_ARRAY_COPY( outline->points + outline->n_points, + border->points, + border->num_points ); /* copy tags */ { @@ -742,7 +753,7 @@ } } - outline->n_points = (short)( outline->n_points + border->num_points ); + outline->n_points += (short)border->num_points; FT_ASSERT( FT_Outline_Check( outline ) == 0 ); } @@ -795,6 +806,9 @@ if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !astroker ) return FT_THROW( Invalid_Argument ); memory = library->memory; @@ -822,14 +836,17 @@ FT_Stroker_LineJoin line_join, FT_Fixed miter_limit ) { + if ( !stroker ) + return; + stroker->radius = radius; stroker->line_cap = line_cap; stroker->line_join = line_join; stroker->miter_limit = miter_limit; /* ensure miter limit has sensible value */ - if ( stroker->miter_limit < 0x10000 ) - stroker->miter_limit = 0x10000; + if ( stroker->miter_limit < 0x10000L ) + stroker->miter_limit = 0x10000L; /* save line join style: */ /* line join style can be temporarily changed when stroking curves */ @@ -993,7 +1010,9 @@ /* Only intersect borders if between two lineto's and both */ /* lines are long enough (line_length is zero for curves). */ - if ( !border->movable || line_length == 0 ) + /* Also avoid U-turns of nearly 180 degree. */ + if ( !border->movable || line_length == 0 || + theta > 0x59C000 || theta < -0x59C000 ) intersect = FALSE; else { @@ -1002,7 +1021,8 @@ FT_Tan( theta ) ) ); - intersect = FT_BOOL( stroker->line_length >= min_length && + intersect = FT_BOOL( min_length && + stroker->line_length >= min_length && line_length >= min_length ); } @@ -1213,11 +1233,8 @@ goto Exit; /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - /* otherwise, the inside side is 1 */ - if ( turn < 0 ) - inside_side = 1; + inside_side = ( turn < 0 ); /* process the inside side */ error = ft_stroker_inside( stroker, inside_side, line_length ); @@ -1225,7 +1242,7 @@ goto Exit; /* process the outside side */ - error = ft_stroker_outside( stroker, 1 - inside_side, line_length ); + error = ft_stroker_outside( stroker, !inside_side, line_length ); Exit: return error; @@ -1287,6 +1304,9 @@ FT_Fixed line_length; + if ( !stroker || !to ) + return FT_THROW( Invalid_Argument ); + delta.x = to->x - stroker->center.x; delta.y = to->y - stroker->center.y; @@ -1360,6 +1380,12 @@ FT_Bool first_arc = TRUE; + if ( !stroker || !control || !to ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + /* if all control points are coincident, this is a no-op; */ /* avoid creating a spurious corner */ if ( FT_IS_SMALL( stroker->center.x - control->x ) && @@ -1556,6 +1582,12 @@ FT_Bool first_arc = TRUE; + if ( !stroker || !control1 || !control2 || !to ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + /* if all control points are coincident, this is a no-op; */ /* avoid creating a spurious corner */ if ( FT_IS_SMALL( stroker->center.x - control1->x ) && @@ -1758,6 +1790,9 @@ FT_Vector* to, FT_Bool open ) { + if ( !stroker || !to ) + return FT_THROW( Invalid_Argument ); + /* We cannot process the first point, because there is not enough */ /* information regarding its corner/cap. The latter will be processed */ /* in the `FT_Stroker_EndSubPath' routine. */ @@ -1797,7 +1832,7 @@ FT_ASSERT( left->start >= 0 ); - new_points = left->num_points - left->start; + new_points = (FT_Int)left->num_points - left->start; if ( new_points > 0 ) { error = ft_stroke_border_grow( right, (FT_UInt)new_points ); @@ -1837,8 +1872,8 @@ } } - left->num_points = left->start; - right->num_points += new_points; + left->num_points = (FT_UInt)left->start; + right->num_points += (FT_UInt)new_points; right->movable = FALSE; left->movable = FALSE; @@ -1858,6 +1893,12 @@ FT_Error error = FT_Err_Ok; + if ( !stroker ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + if ( stroker->subpath_open ) { FT_StrokeBorder right = stroker->borders; @@ -1910,11 +1951,8 @@ if ( turn != 0 ) { /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - /* otherwise, the inside side is 1 */ - if ( turn < 0 ) - inside_side = 1; + inside_side = ( turn < 0 ); error = ft_stroker_inside( stroker, inside_side, @@ -1924,7 +1962,7 @@ /* process the outside side */ error = ft_stroker_outside( stroker, - 1 - inside_side, + !inside_side, stroker->subpath_line_length ); if ( error ) goto Exit; @@ -1983,6 +2021,12 @@ FT_Error error; + if ( !stroker ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + error = ft_stroke_border_get_counts( stroker->borders + 0, &count1, &count2 ); if ( error ) @@ -1997,8 +2041,12 @@ num_contours = count2 + count4; Exit: - *anum_points = num_points; - *anum_contours = num_contours; + if ( anum_points ) + *anum_points = num_points; + + if ( anum_contours ) + *anum_contours = num_contours; + return error; } @@ -2010,6 +2058,9 @@ FT_StrokerBorder border, FT_Outline* outline ) { + if ( !stroker || !outline ) + return; + if ( border == FT_STROKER_BORDER_LEFT || border == FT_STROKER_BORDER_RIGHT ) { @@ -2059,7 +2110,10 @@ FT_Int tag; /* current point's state */ - if ( !outline || !stroker ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !stroker ) return FT_THROW( Invalid_Argument ); FT_Stroker_Rewind( stroker ); @@ -2071,7 +2125,7 @@ FT_UInt last; /* index of last point in contour */ - last = outline->contours[n]; + last = (FT_UInt)outline->contours[n]; limit = outline->points + last; /* skip empty points; we don't stroke these */ @@ -2242,15 +2296,6 @@ } - /* declare an extern to access `ft_outline_glyph_class' globally */ - /* allocated in `ftglyph.c', and use the FT_OUTLINE_GLYPH_CLASS_GET */ - /* macro to access it when FT_CONFIG_OPTION_PIC is defined */ -#ifndef FT_CONFIG_OPTION_PIC - extern const FT_Glyph_Class ft_outline_glyph_class; -#endif -#include "basepic.h" - - /* documentation is in ftstroke.h */ FT_EXPORT_DEF( FT_Error ) @@ -2258,18 +2303,20 @@ FT_Stroker stroker, FT_Bool destroy ) { - FT_Error error = FT_ERR( Invalid_Argument ); - FT_Glyph glyph = NULL; + FT_Error error = FT_ERR( Invalid_Argument ); + FT_Glyph glyph = NULL; + + /* for FT_OUTLINE_GLYPH_CLASS_GET (in PIC mode) */ FT_Library library = stroker->library; FT_UNUSED( library ); - if ( pglyph == NULL ) + if ( !pglyph ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + if ( !glyph || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -2293,12 +2340,14 @@ if ( error ) goto Fail; - (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); + FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); FT_Outline_Done( glyph->library, outline ); error = FT_Outline_New( glyph->library, - num_points, num_contours, outline ); + num_points, + (FT_Int)num_contours, + outline ); if ( error ) goto Fail; @@ -2334,18 +2383,20 @@ FT_Bool inside, FT_Bool destroy ) { - FT_Error error = FT_ERR( Invalid_Argument ); - FT_Glyph glyph = NULL; + FT_Error error = FT_ERR( Invalid_Argument ); + FT_Glyph glyph = NULL; + + /* for FT_OUTLINE_GLYPH_CLASS_GET (in PIC mode) */ FT_Library library = stroker->library; FT_UNUSED( library ); - if ( pglyph == NULL ) + if ( !pglyph ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + if ( !glyph || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -2379,14 +2430,14 @@ if ( error ) goto Fail; - (void)FT_Stroker_GetBorderCounts( stroker, border, - &num_points, &num_contours ); + FT_Stroker_GetBorderCounts( stroker, border, + &num_points, &num_contours ); FT_Outline_Done( glyph->library, outline ); error = FT_Outline_New( glyph->library, num_points, - num_contours, + (FT_Int)num_contours, outline ); if ( error ) goto Fail; diff --git a/drivers/freetype/freetype/src/base/ftsynth.c b/drivers/freetype/src/base/ftsynth.c index 241d37f426..4b66a33c3f 100644 --- a/drivers/freetype/freetype/src/base/ftsynth.c +++ b/drivers/freetype/src/base/ftsynth.c @@ -4,7 +4,7 @@ /* */ /* FreeType synthesizing code for emboldening and slanting (body). */ /* */ -/* Copyright 2000-2006, 2010, 2012 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -48,9 +48,14 @@ FT_GlyphSlot_Oblique( FT_GlyphSlot slot ) { FT_Matrix transform; - FT_Outline* outline = &slot->outline; + FT_Outline* outline; + if ( !slot ) + return; + + outline = &slot->outline; + /* only oblique outline glyphs */ if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) return; @@ -84,12 +89,18 @@ FT_EXPORT_DEF( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) { - FT_Library library = slot->library; - FT_Face face = slot->face; + FT_Library library; + FT_Face face; FT_Error error; FT_Pos xstr, ystr; + if ( !slot ) + return; + + library = slot->library; + face = slot->face; + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && slot->format != FT_GLYPH_FORMAT_BITMAP ) return; @@ -100,10 +111,8 @@ ystr = xstr; if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* ignore error */ - (void)FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); - } + FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); + else /* slot->format == FT_GLYPH_FORMAT_BITMAP */ { /* round to full pixels */ @@ -139,10 +148,11 @@ if ( slot->advance.y ) slot->advance.y += ystr; - slot->metrics.width += xstr; - slot->metrics.height += ystr; - slot->metrics.horiAdvance += xstr; - slot->metrics.vertAdvance += ystr; + slot->metrics.width += xstr; + slot->metrics.height += ystr; + slot->metrics.horiAdvance += xstr; + slot->metrics.vertAdvance += ystr; + slot->metrics.horiBearingY += ystr; /* XXX: 16-bit overflow case must be excluded before here */ if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) diff --git a/drivers/freetype/freetype/src/base/ftsystem.c b/drivers/freetype/src/base/ftsystem.c index 2c6ddac10c..ac1f01c8bc 100644 --- a/drivers/freetype/freetype/src/base/ftsystem.c +++ b/drivers/freetype/src/base/ftsystem.c @@ -4,7 +4,7 @@ /* */ /* ANSI-specific FreeType low-level system interface (body). */ /* */ -/* Copyright 1996-2002, 2006, 2008-2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -71,7 +71,7 @@ { FT_UNUSED( memory ); - return ft_smalloc( size ); + return ft_smalloc( (size_t)size ); } @@ -104,7 +104,7 @@ FT_UNUSED( memory ); FT_UNUSED( cur_size ); - return ft_srealloc( block, new_size ); + return ft_srealloc( block, (size_t)new_size ); } @@ -171,7 +171,7 @@ stream->descriptor.pointer = NULL; stream->size = 0; - stream->base = 0; + stream->base = NULL; } @@ -212,7 +212,7 @@ file = STREAM_FILE( stream ); if ( stream->pos != offset ) - ft_fseek( file, offset, SEEK_SET ); + ft_fseek( file, (long)offset, SEEK_SET ); return (unsigned long)ft_fread( buffer, 1, count, file ); } @@ -232,7 +232,7 @@ stream->descriptor.pointer = NULL; stream->pathname.pointer = (char*)filepathname; - stream->base = 0; + stream->base = NULL; stream->pos = 0; stream->read = NULL; stream->close = NULL; @@ -247,7 +247,7 @@ } ft_fseek( file, 0, SEEK_END ); - stream->size = ft_ftell( file ); + stream->size = (unsigned long)ft_ftell( file ); if ( !stream->size ) { FT_ERROR(( "FT_Stream_Open:" )); @@ -292,7 +292,7 @@ memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) ); if ( memory ) { - memory->user = 0; + memory->user = NULL; memory->alloc = ft_alloc; memory->realloc = ft_realloc; memory->free = ft_free; diff --git a/drivers/freetype/freetype/src/base/fttrigon.c b/drivers/freetype/src/base/fttrigon.c index 4ffdcb77f1..7b582c8a3d 100644 --- a/drivers/freetype/freetype/src/base/fttrigon.c +++ b/drivers/freetype/src/base/fttrigon.c @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (body). */ /* */ -/* Copyright 2001-2005, 2012-2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ /* this table was generated for FT_PI = 180L << 16, i.e. degrees */ #define FT_TRIG_MAX_ITERS 23 - static const FT_Fixed + static const FT_Angle ft_trig_arctan_table[] = { 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, @@ -60,17 +60,21 @@ static FT_Fixed ft_trig_downscale( FT_Fixed val ) { - FT_Fixed s; - FT_Int64 v; + FT_Int s = 1; - s = val; - val = FT_ABS( val ); + if ( val < 0 ) + { + val = -val; + s = -1; + } - v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL; - val = (FT_Fixed)( v >> 32 ); + /* 0x40000000 comes from regression analysis between true */ + /* and CORDIC hypotenuse, so it minimizes the error */ + val = (FT_Fixed)( + ( (FT_UInt64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); - return ( s >= 0 ) ? val : -val; + return s < 0 ? -val : val; } #else /* !FT_LONG64 */ @@ -79,38 +83,53 @@ static FT_Fixed ft_trig_downscale( FT_Fixed val ) { - FT_Fixed s; - FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3; + FT_Int s = 1; + FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; + + + if ( val < 0 ) + { + val = -val; + s = -1; + } + lo1 = (FT_UInt32)val & 0x0000FFFFU; + hi1 = (FT_UInt32)val >> 16; + lo2 = FT_TRIG_SCALE & 0x0000FFFFU; + hi2 = FT_TRIG_SCALE >> 16; - s = val; - val = FT_ABS( val ); + lo = lo1 * lo2; + i1 = lo1 * hi2; + i2 = lo2 * hi1; + hi = hi1 * hi2; - v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)( val & 0xFFFFL ); + /* Check carry overflow of i1 + i2 */ + i1 += i2; + hi += (FT_UInt32)( i1 < i2 ) << 16; - k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */ - k2 = (FT_UInt32)( FT_TRIG_SCALE & 0xFFFFL ); /* constant */ + hi += i1 >> 16; + i1 = i1 << 16; - hi = k1 * v1; - lo1 = k1 * v2 + k2 * v1; /* can't overflow */ + /* Check carry overflow of i1 + lo */ + lo += i1; + hi += ( lo < i1 ); - lo2 = ( k2 * v2 ) >> 16; - lo3 = FT_MAX( lo1, lo2 ); - lo1 += lo2; + /* 0x40000000 comes from regression analysis between true */ + /* and CORDIC hypotenuse, so it minimizes the error */ - hi += lo1 >> 16; - if ( lo1 < lo3 ) - hi += (FT_UInt32)0x10000UL; + /* Check carry overflow of lo + 0x40000000 */ + lo += 0x40000000UL; + hi += ( lo < 0x40000000UL ); - val = (FT_Fixed)hi; + val = (FT_Fixed)hi; - return ( s >= 0 ) ? val : -val; + return s < 0 ? -val : val; } #endif /* !FT_LONG64 */ + /* undefined and never called for zero vector */ static FT_Int ft_trig_prenorm( FT_Vector* vec ) { @@ -121,7 +140,7 @@ x = vec->x; y = vec->y; - shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) ); + shift = FT_MSB( (FT_UInt32)( FT_ABS( x ) | FT_ABS( y ) ) ); if ( shift <= FT_TRIG_SAFE_MSB ) { @@ -147,7 +166,7 @@ { FT_Int i; FT_Fixed x, y, xtemp, b; - const FT_Fixed *arctanptr; + const FT_Angle *arctanptr; x = vec->x; @@ -202,7 +221,7 @@ FT_Angle theta; FT_Int i; FT_Fixed x, y, xtemp, b; - const FT_Fixed *arctanptr; + const FT_Angle *arctanptr; x = vec->x; @@ -261,11 +280,12 @@ } } - /* round theta */ + /* round theta to acknowledge its error that mostly comes */ + /* from accumulated rounding errors in the arctan table */ if ( theta >= 0 ) - theta = FT_PAD_ROUND( theta, 32 ); + theta = FT_PAD_ROUND( theta, 16 ); else - theta = -FT_PAD_ROUND( -theta, 32 ); + theta = -FT_PAD_ROUND( -theta, 16 ); vec->x = x; vec->y = theta; @@ -280,11 +300,9 @@ FT_Vector v; - v.x = FT_TRIG_SCALE >> 8; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); + FT_Vector_Unit( &v, angle ); - return ( v.x + 0x80L ) >> 8; + return v.x; } @@ -293,7 +311,12 @@ FT_EXPORT_DEF( FT_Fixed ) FT_Sin( FT_Angle angle ) { - return FT_Cos( FT_ANGLE_PI2 - angle ); + FT_Vector v; + + + FT_Vector_Unit( &v, angle ); + + return v.y; } @@ -305,9 +328,7 @@ FT_Vector v; - v.x = FT_TRIG_SCALE >> 8; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); + FT_Vector_Unit( &v, angle ); return FT_DivFix( v.y, v.x ); } @@ -340,6 +361,9 @@ FT_Vector_Unit( FT_Vector* vec, FT_Angle angle ) { + if ( !vec ) + return; + vec->x = FT_TRIG_SCALE >> 8; vec->y = 0; ft_trig_pseudo_rotate( vec, angle ); @@ -366,30 +390,32 @@ FT_Vector v; - v.x = vec->x; - v.y = vec->y; + if ( !vec || !angle ) + return; - if ( angle && ( v.x != 0 || v.y != 0 ) ) - { - shift = ft_trig_prenorm( &v ); - ft_trig_pseudo_rotate( &v, angle ); - v.x = ft_trig_downscale( v.x ); - v.y = ft_trig_downscale( v.y ); + v = *vec; - if ( shift > 0 ) - { - FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); + if ( v.x == 0 && v.y == 0 ) + return; + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_rotate( &v, angle ); + v.x = ft_trig_downscale( v.x ); + v.y = ft_trig_downscale( v.y ); - vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; - vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; - } - else - { - shift = -shift; - vec->x = (FT_Pos)( (FT_ULong)v.x << shift ); - vec->y = (FT_Pos)( (FT_ULong)v.y << shift ); - } + if ( shift > 0 ) + { + FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); + + + vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; + vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; + } + else + { + shift = -shift; + vec->x = (FT_Pos)( (FT_ULong)v.x << shift ); + vec->y = (FT_Pos)( (FT_ULong)v.y << shift ); } } @@ -403,6 +429,9 @@ FT_Vector v; + if ( !vec ) + return 0; + v = *vec; /* handle trivial cases */ @@ -422,7 +451,7 @@ v.x = ft_trig_downscale( v.x ); if ( shift > 0 ) - return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift; + return ( v.x + ( 1L << ( shift - 1 ) ) ) >> shift; return (FT_Fixed)( (FT_UInt32)v.x << -shift ); } @@ -439,6 +468,9 @@ FT_Vector v; + if ( !vec || !length || !angle ) + return; + v = *vec; if ( v.x == 0 && v.y == 0 ) @@ -449,8 +481,8 @@ v.x = ft_trig_downscale( v.x ); - *length = ( shift >= 0 ) ? ( v.x >> shift ) - : (FT_Fixed)( (FT_UInt32)v.x << -shift ); + *length = shift >= 0 ? ( v.x >> shift ) + : (FT_Fixed)( (FT_UInt32)v.x << -shift ); *angle = v.y; } @@ -462,6 +494,9 @@ FT_Fixed length, FT_Angle angle ) { + if ( !vec ) + return; + vec->x = length; vec->y = 0; @@ -478,11 +513,10 @@ FT_Angle delta = angle2 - angle1; - delta %= FT_ANGLE_2PI; - if ( delta < 0 ) + while ( delta <= -FT_ANGLE_PI ) delta += FT_ANGLE_2PI; - if ( delta > FT_ANGLE_PI ) + while ( delta > FT_ANGLE_PI ) delta -= FT_ANGLE_2PI; return delta; diff --git a/drivers/freetype/freetype/src/base/fttype1.c b/drivers/freetype/src/base/fttype1.c index c1f9931dbb..5c0fce8686 100644 --- a/drivers/freetype/freetype/src/base/fttype1.c +++ b/drivers/freetype/src/base/fttype1.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for PS names support (body). */ /* */ -/* Copyright 2002-2004, 2011 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,7 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_SERVICE_H #include FT_SERVICE_POSTSCRIPT_INFO_H @@ -28,19 +29,22 @@ FT_Get_PS_Font_Info( FT_Face face, PS_FontInfoRec* afont_info ) { - FT_Error error = FT_ERR( Invalid_Argument ); + FT_Error error; + FT_Service_PsInfo service; - if ( face ) - { - FT_Service_PsInfo service = NULL; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + if ( !afont_info ) + return FT_THROW( Invalid_Argument ); - FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); - if ( service && service->ps_get_font_info ) - error = service->ps_get_font_info( face, afont_info ); - } + if ( service && service->ps_get_font_info ) + error = service->ps_get_font_info( face, afont_info ); + else + error = FT_THROW( Invalid_Argument ); return error; } @@ -51,8 +55,8 @@ FT_EXPORT_DEF( FT_Int ) FT_Has_PS_Glyph_Names( FT_Face face ) { - FT_Int result = 0; - FT_Service_PsInfo service = NULL; + FT_Int result = 0; + FT_Service_PsInfo service; if ( face ) @@ -73,19 +77,22 @@ FT_Get_PS_Font_Private( FT_Face face, PS_PrivateRec* afont_private ) { - FT_Error error = FT_ERR( Invalid_Argument ); + FT_Error error; + FT_Service_PsInfo service; - if ( face ) - { - FT_Service_PsInfo service = NULL; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + if ( !afont_private ) + return FT_THROW( Invalid_Argument ); - FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); - if ( service && service->ps_get_font_private ) - error = service->ps_get_font_private( face, afont_private ); - } + if ( service && service->ps_get_font_private ) + error = service->ps_get_font_private( face, afont_private ); + else + error = FT_THROW( Invalid_Argument ); return error; } diff --git a/drivers/freetype/freetype/src/base/ftutil.c b/drivers/freetype/src/base/ftutil.c index 879d027529..fad7d1a5fb 100644 --- a/drivers/freetype/freetype/src/base/ftutil.c +++ b/drivers/freetype/src/base/ftutil.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for memory and list management (body). */ /* */ -/* Copyright 2002, 2004-2007, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -180,7 +180,7 @@ FT_Error *p_error ) { FT_Error error; - FT_Pointer p = ft_mem_qalloc( memory, size, &error ); + FT_Pointer p = ft_mem_qalloc( memory, (FT_Long)size, &error ); if ( !error && address ) @@ -245,6 +245,9 @@ FT_ListNode cur; + if ( !list ) + return NULL; + cur = list->head; while ( cur ) { @@ -254,7 +257,7 @@ cur = cur->next; } - return (FT_ListNode)0; + return NULL; } @@ -264,10 +267,15 @@ FT_List_Add( FT_List list, FT_ListNode node ) { - FT_ListNode before = list->tail; + FT_ListNode before; + + + if ( !list || !node ) + return; + before = list->tail; - node->next = 0; + node->next = NULL; node->prev = before; if ( before ) @@ -285,11 +293,16 @@ FT_List_Insert( FT_List list, FT_ListNode node ) { - FT_ListNode after = list->head; + FT_ListNode after; + + + if ( !list || !node ) + return; + after = list->head; node->next = after; - node->prev = 0; + node->prev = NULL; if ( !after ) list->tail = node; @@ -309,6 +322,9 @@ FT_ListNode before, after; + if ( !list || !node ) + return; + before = node->prev; after = node->next; @@ -333,6 +349,9 @@ FT_ListNode before, after; + if ( !list || !node ) + return; + before = node->prev; after = node->next; @@ -347,7 +366,7 @@ else list->tail = before; - node->prev = 0; + node->prev = NULL; node->next = list->head; list->head->prev = node; list->head = node; @@ -357,14 +376,19 @@ /* documentation is in ftlist.h */ FT_EXPORT_DEF( FT_Error ) - FT_List_Iterate( FT_List list, - FT_List_Iterator iterator, - void* user ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ) { - FT_ListNode cur = list->head; + FT_ListNode cur; FT_Error error = FT_Err_Ok; + if ( !list || !iterator ) + return FT_THROW( Invalid_Argument ); + + cur = list->head; + while ( cur ) { FT_ListNode next = cur->next; @@ -392,6 +416,9 @@ FT_ListNode cur; + if ( !list || !memory ) + return; + cur = list->head; while ( cur ) { @@ -406,30 +433,8 @@ cur = next; } - list->head = 0; - list->tail = 0; - } - - - FT_BASE_DEF( FT_UInt32 ) - ft_highpow2( FT_UInt32 value ) - { - FT_UInt32 value2; - - - /* - * We simply clear the lowest bit in each iteration. When - * we reach 0, we know that the previous value was our result. - */ - for ( ;; ) - { - value2 = value & (value - 1); /* clear lowest bit */ - if ( value2 == 0 ) - break; - - value = value2; - } - return value; + list->head = NULL; + list->tail = NULL; } diff --git a/drivers/freetype/freetype/src/base/ftwinfnt.c b/drivers/freetype/src/base/ftwinfnt.c index 463ae761d8..89e9155098 100644 --- a/drivers/freetype/freetype/src/base/ftwinfnt.c +++ b/drivers/freetype/src/base/ftwinfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows FNT specific info (body). */ /* */ -/* Copyright 2003, 2004 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,7 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_WINFONTS_H #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_WINFNT_H @@ -32,17 +33,18 @@ FT_Error error; - error = FT_ERR( Invalid_Argument ); + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); - if ( face != NULL ) - { - FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); + if ( !header ) + return FT_THROW( Invalid_Argument ); - if ( service != NULL ) - { - error = service->get_header( face, header ); - } - } + FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); + + if ( service ) + error = service->get_header( face, header ); + else + error = FT_THROW( Invalid_Argument ); return error; } diff --git a/drivers/freetype/freetype/src/base/md5.c b/drivers/freetype/src/base/md5.c index 2f01c9302c..b235e17a56 100644 --- a/drivers/freetype/freetype/src/base/md5.c +++ b/drivers/freetype/src/base/md5.c @@ -50,7 +50,8 @@ */ #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define H(x, y, z) (((x) ^ (y)) ^ (z)) +#define H2(x, y, z) ((x) ^ ((y) ^ (z))) #define I(x, y, z) ((y) ^ ((x) | ~(z))) /* @@ -62,12 +63,19 @@ (a) += (b); /* - * SET reads 4 input bytes in little-endian byte order and stores them - * in a properly aligned word in host byte order. + * SET reads 4 input bytes in little-endian byte order and stores them in a + * properly aligned word in host byte order. * - * The check for little-endian architectures that tolerate unaligned - * memory accesses is just an optimization. Nothing will break if it - * doesn't work. + * The check for little-endian architectures that tolerate unaligned memory + * accesses is just an optimization. Nothing will break if it fails to detect + * a suitable architecture. + * + * Unfortunately, this optimization may be a C strict aliasing rules violation + * if the caller's data buffer has effective type that cannot be aliased by + * MD5_u32plus. In practice, this problem may occur if these MD5 routines are + * inlined into a calling function, or with future and dangerously advanced + * link-time optimizations. For the time being, keeping these MD5 routines in + * their own translation unit avoids the problem. */ #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) #define SET(n) \ @@ -86,16 +94,16 @@ #endif /* - * This processes one or more 64-byte data blocks, but does NOT update - * the bit counters. There are no alignment requirements. + * This processes one or more 64-byte data blocks, but does NOT update the bit + * counters. There are no alignment requirements. */ -static void *body(MD5_CTX *ctx, void *data, unsigned long size) +static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) { - unsigned char *ptr; + const unsigned char *ptr; MD5_u32plus a, b, c, d; MD5_u32plus saved_a, saved_b, saved_c, saved_d; - ptr = (unsigned char *)data; + ptr = (const unsigned char *)data; a = ctx->a; b = ctx->b; @@ -146,21 +154,21 @@ static void *body(MD5_CTX *ctx, void *data, unsigned long size) /* Round 3 */ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) - STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) - STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) - STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) - STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) - STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) - STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) - STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) - STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) + STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) /* Round 4 */ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) @@ -207,10 +215,10 @@ void MD5_Init(MD5_CTX *ctx) ctx->hi = 0; } -void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) +void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) { MD5_u32plus saved_lo; - unsigned long used, free; + unsigned long used, available; saved_lo = ctx->lo; if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) @@ -220,16 +228,16 @@ void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) used = saved_lo & 0x3f; if (used) { - free = 64 - used; + available = 64 - used; - if (size < free) { + if (size < available) { memcpy(&ctx->buffer[used], data, size); return; } - memcpy(&ctx->buffer[used], data, free); - data = (unsigned char *)data + free; - size -= free; + memcpy(&ctx->buffer[used], data, available); + data = (const unsigned char *)data + available; + size -= available; body(ctx, ctx->buffer, 64); } @@ -241,53 +249,41 @@ void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) memcpy(ctx->buffer, data, size); } +#define OUT(dst, src) \ + (dst)[0] = (unsigned char)(src); \ + (dst)[1] = (unsigned char)((src) >> 8); \ + (dst)[2] = (unsigned char)((src) >> 16); \ + (dst)[3] = (unsigned char)((src) >> 24); + void MD5_Final(unsigned char *result, MD5_CTX *ctx) { - unsigned long used, free; + unsigned long used, available; used = ctx->lo & 0x3f; ctx->buffer[used++] = 0x80; - free = 64 - used; + available = 64 - used; - if (free < 8) { - memset(&ctx->buffer[used], 0, free); + if (available < 8) { + memset(&ctx->buffer[used], 0, available); body(ctx, ctx->buffer, 64); used = 0; - free = 64; + available = 64; } - memset(&ctx->buffer[used], 0, free - 8); + memset(&ctx->buffer[used], 0, available - 8); ctx->lo <<= 3; - ctx->buffer[56] = ctx->lo; - ctx->buffer[57] = ctx->lo >> 8; - ctx->buffer[58] = ctx->lo >> 16; - ctx->buffer[59] = ctx->lo >> 24; - ctx->buffer[60] = ctx->hi; - ctx->buffer[61] = ctx->hi >> 8; - ctx->buffer[62] = ctx->hi >> 16; - ctx->buffer[63] = ctx->hi >> 24; + OUT(&ctx->buffer[56], ctx->lo) + OUT(&ctx->buffer[60], ctx->hi) body(ctx, ctx->buffer, 64); - result[0] = ctx->a; - result[1] = ctx->a >> 8; - result[2] = ctx->a >> 16; - result[3] = ctx->a >> 24; - result[4] = ctx->b; - result[5] = ctx->b >> 8; - result[6] = ctx->b >> 16; - result[7] = ctx->b >> 24; - result[8] = ctx->c; - result[9] = ctx->c >> 8; - result[10] = ctx->c >> 16; - result[11] = ctx->c >> 24; - result[12] = ctx->d; - result[13] = ctx->d >> 8; - result[14] = ctx->d >> 16; - result[15] = ctx->d >> 24; + OUT(&result[0], ctx->a) + OUT(&result[4], ctx->b) + OUT(&result[8], ctx->c) + OUT(&result[12], ctx->d) memset(ctx, 0, sizeof(*ctx)); } diff --git a/drivers/freetype/freetype/src/base/md5.h b/drivers/freetype/src/base/md5.h index f1a6857640..2da44bf355 100644 --- a/drivers/freetype/freetype/src/base/md5.h +++ b/drivers/freetype/src/base/md5.h @@ -39,7 +39,7 @@ typedef struct { } MD5_CTX; extern void MD5_Init(MD5_CTX *ctx); -extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size); +extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); #endif diff --git a/drivers/freetype/freetype/src/base/rules.mk b/drivers/freetype/src/base/rules.mk index e932191157..aa424c5463 100644 --- a/drivers/freetype/freetype/src/base/rules.mk +++ b/drivers/freetype/src/base/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002-2009, 2013 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -19,11 +19,14 @@ # BASE_OBJ_S: The single-object base layer. # BASE_OBJ_M: A list of all objects for a multiple-objects build. # BASE_EXT_OBJ: A list of base layer extensions, i.e., components found -# in `freetype/src/base' which are not compiled within the -# base layer proper. +# in `src/base' which are not compiled within the base +# layer proper. -BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) +BASE_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(BASE_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # Base layer sources @@ -33,12 +36,15 @@ BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) # All files listed here should be included in `ftbase.c' (for a `single' # build). # -BASE_SRC := $(BASE_DIR)/ftadvanc.c \ +BASE_SRC := $(BASE_DIR)/basepic.c \ + $(BASE_DIR)/ftadvanc.c \ $(BASE_DIR)/ftcalc.c \ $(BASE_DIR)/ftdbgmem.c \ $(BASE_DIR)/ftgloadr.c \ + $(BASE_DIR)/fthash.c \ $(BASE_DIR)/ftobjs.c \ $(BASE_DIR)/ftoutln.c \ + $(BASE_DIR)/ftpic.c \ $(BASE_DIR)/ftrfork.c \ $(BASE_DIR)/ftsnames.c \ $(BASE_DIR)/ftstream.c \ @@ -51,8 +57,9 @@ ifneq ($(ftmac_c),) endif # for simplicity, we also handle `md5.c' (which gets included by `ftobjs.h') -BASE_H := $(BASE_DIR)/ftbase.h \ - $(BASE_DIR)/md5.c \ +BASE_H := $(BASE_DIR)/basepic.h \ + $(BASE_DIR)/ftbase.h \ + $(BASE_DIR)/md5.c \ $(BASE_DIR)/md5.h # Base layer `extensions' sources diff --git a/drivers/freetype/freetype/src/bdf/Jamfile b/drivers/freetype/src/bdf/Jamfile index da23ccd0ad..2f0147bbba 100644 --- a/drivers/freetype/freetype/src/bdf/Jamfile +++ b/drivers/freetype/src/bdf/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/bdf Jamfile # -# Copyright 2002 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,9 @@ SubDir FT2_TOP $(FT2_SRC_DIR) bdf ; if $(FT2_MULTI) { - _sources = bdfdrivr bdflib ; + _sources = bdfdrivr + bdflib + ; } else { diff --git a/drivers/freetype/freetype/src/bdf/README b/drivers/freetype/src/bdf/README index b761aba2b2..b761aba2b2 100644 --- a/drivers/freetype/freetype/src/bdf/README +++ b/drivers/freetype/src/bdf/README diff --git a/drivers/freetype/freetype/src/bdf/bdf.c b/drivers/freetype/src/bdf/bdf.c index f95fb76225..f95fb76225 100644 --- a/drivers/freetype/freetype/src/bdf/bdf.c +++ b/drivers/freetype/src/bdf/bdf.c diff --git a/drivers/freetype/freetype/src/bdf/bdf.h b/drivers/freetype/src/bdf/bdf.h index d11be6f147..9012727c7e 100644 --- a/drivers/freetype/freetype/src/bdf/bdf.h +++ b/drivers/freetype/src/bdf/bdf.h @@ -22,8 +22,8 @@ */ -#ifndef __BDF_H__ -#define __BDF_H__ +#ifndef BDF_H_ +#define BDF_H_ /* @@ -33,6 +33,7 @@ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_HASH_H FT_BEGIN_HEADER @@ -40,12 +41,12 @@ FT_BEGIN_HEADER /* Imported from bdfP.h */ -#define _bdf_glyph_modified( map, e ) \ - ( (map)[(e) >> 5] & ( 1 << ( (e) & 31 ) ) ) -#define _bdf_set_glyph_modified( map, e ) \ - ( (map)[(e) >> 5] |= ( 1 << ( (e) & 31 ) ) ) -#define _bdf_clear_glyph_modified( map, e ) \ - ( (map)[(e) >> 5] &= ~( 1 << ( (e) & 31 ) ) ) +#define _bdf_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] & ( 1UL << ( (e) & 31 ) ) ) +#define _bdf_set_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] |= ( 1UL << ( (e) & 31 ) ) ) +#define _bdf_clear_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] &= ~( 1UL << ( (e) & 31 ) ) ) /* end of bdfP.h */ @@ -157,24 +158,6 @@ FT_BEGIN_HEADER } bdf_glyph_t; - typedef struct _hashnode_ - { - const char* key; - size_t data; - - } _hashnode, *hashnode; - - - typedef struct hashtable_ - { - int limit; - int size; - int used; - hashnode* table; - - } hashtable; - - typedef struct bdf_glyphlist_t_ { unsigned short pad; /* Pad to 4-byte boundary. */ @@ -194,7 +177,7 @@ FT_BEGIN_HEADER char* name; /* Name of the font. */ bdf_bbx_t bbx; /* Font bounding box. */ - long point_size; /* Point size of the font. */ + unsigned long point_size; /* Point size of the font. */ unsigned long resolution_x; /* Font horizontal resolution. */ unsigned long resolution_y; /* Font vertical resolution. */ @@ -238,7 +221,7 @@ FT_BEGIN_HEADER bdf_property_t* user_props; unsigned long nuser_props; - hashtable proptbl; + FT_HashRec proptbl; } bdf_font_t; @@ -291,7 +274,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __BDF_H__ */ +#endif /* BDF_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/bdf/bdfdrivr.c b/drivers/freetype/src/bdf/bdfdrivr.c index 0ea0a5ea5e..a381cf68f5 100644 --- a/drivers/freetype/freetype/src/bdf/bdfdrivr.c +++ b/drivers/freetype/src/bdf/bdfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for bdf files - Copyright (C) 2001-2008, 2011, 2013 by + Copyright (C) 2001-2008, 2011, 2013, 2014 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -33,7 +33,7 @@ THE SOFTWARE. #include FT_TRUETYPE_IDS_H #include FT_SERVICE_BDF_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include "bdf.h" #include "bdfdrivr.h" @@ -106,7 +106,7 @@ THE SOFTWARE. mid = ( min + max ) >> 1; - code = encodings[mid].enc; + code = (FT_ULong)encodings[mid].enc; if ( charcode == code ) { @@ -146,7 +146,7 @@ THE SOFTWARE. mid = ( min + max ) >> 1; - code = encodings[mid].enc; + code = (FT_ULong)encodings[mid].enc; if ( charcode == code ) { @@ -165,7 +165,7 @@ THE SOFTWARE. charcode = 0; if ( min < cmap->num_encodings ) { - charcode = encodings[min].enc; + charcode = (FT_ULong)encodings[min].enc; result = encodings[min].glyph + 1; } @@ -182,7 +182,7 @@ THE SOFTWARE. } - FT_CALLBACK_TABLE_DEF + static const FT_CMap_ClassRec bdf_cmap_class = { sizeof ( BDF_CMapRec ), @@ -243,8 +243,6 @@ THE SOFTWARE. !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) strings[0] = (char *)(prop->value.atom); - len = 0; - for ( len = 0, nn = 0; nn < 4; nn++ ) { lengths[nn] = 0; @@ -351,7 +349,6 @@ THE SOFTWARE. FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_TRACE2(( "BDF driver\n" )); @@ -375,6 +372,20 @@ THE SOFTWARE. /* we have a bdf font: let's construct the face object */ face->bdffont = font; + + /* BDF could not have multiple face in single font file. + * XXX: non-zero face_index is already invalid argument, but + * Type1, Type42 driver has a convention to return + * an invalid argument error when the font could be + * opened by the specified driver. + */ + if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) + { + FT_ERROR(( "BDF_Face_Init: invalid face index\n" )); + BDF_Face_Done( bdfface ); + return FT_THROW( Invalid_Argument ); + } + { bdf_property_t* prop = NULL; @@ -388,9 +399,10 @@ THE SOFTWARE. bdfface->num_faces = 1; bdfface->face_index = 0; - bdfface->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_FAST_GLYPHS; + + bdfface->face_flags |= FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_FAST_GLYPHS; prop = bdf_get_font_property( font, "SPACING" ); if ( prop && prop->format == BDF_ATOM && @@ -409,14 +421,14 @@ THE SOFTWARE. goto Exit; } else - bdfface->family_name = 0; + bdfface->family_name = NULL; if ( ( error = bdf_interpret_style( face ) ) != 0 ) goto Exit; /* the number of glyphs (with one slot for the undefined glyph */ /* at position 0 and all unencoded glyphs) */ - bdfface->num_glyphs = font->glyphs_size + 1; + bdfface->num_glyphs = (FT_Long)( font->glyphs_size + 1 ); bdfface->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) ) @@ -483,7 +495,7 @@ THE SOFTWARE. { (face->en_table[n]).enc = cur[n].encoding; FT_TRACE4(( " idx %d, val 0x%lX\n", n, cur[n].encoding )); - (face->en_table[n]).glyph = (FT_Short)n; + (face->en_table[n]).glyph = (FT_UShort)n; if ( cur[n].encoding == font->default_char ) { @@ -498,7 +510,7 @@ THE SOFTWARE. /* charmaps */ { - bdf_property_t *charset_registry = 0, *charset_encoding = 0; + bdf_property_t *charset_registry, *charset_encoding; FT_Bool unicode_charmap = 0; @@ -604,9 +616,9 @@ THE SOFTWARE. FT_Select_Metrics( size->face, strike_index ); - size->metrics.ascender = bdffont->font_ascent << 6; - size->metrics.descender = -bdffont->font_descent << 6; - size->metrics.max_advance = bdffont->bbx.width << 6; + size->metrics.ascender = bdffont->font_ascent * 64; + size->metrics.descender = -bdffont->font_descent * 64; + size->metrics.max_advance = bdffont->bbx.width * 64; return FT_Err_Ok; } @@ -668,12 +680,20 @@ THE SOFTWARE. FT_UNUSED( load_flags ); - if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) + if ( !face ) + { + error = FT_THROW( Invalid_Face_Handle ); + goto Exit; + } + + if ( glyph_index >= (FT_UInt)face->num_glyphs ) { error = FT_THROW( Invalid_Argument ); goto Exit; } + FT_TRACE1(( "BDF_Glyph_Load: glyph index %d\n", glyph_index )); + /* index 0 is the undefined glyph */ if ( glyph_index == 0 ) glyph_index = bdf->default_glyph; @@ -715,18 +735,18 @@ THE SOFTWARE. slot->bitmap_left = glyph.bbx.x_offset; slot->bitmap_top = glyph.bbx.ascent; - slot->metrics.horiAdvance = glyph.dwidth << 6; - slot->metrics.horiBearingX = glyph.bbx.x_offset << 6; - slot->metrics.horiBearingY = glyph.bbx.ascent << 6; - slot->metrics.width = bitmap->width << 6; - slot->metrics.height = bitmap->rows << 6; + slot->metrics.horiAdvance = (FT_Pos)( glyph.dwidth * 64 ); + slot->metrics.horiBearingX = (FT_Pos)( glyph.bbx.x_offset * 64 ); + slot->metrics.horiBearingY = (FT_Pos)( glyph.bbx.ascent * 64 ); + slot->metrics.width = (FT_Pos)( bitmap->width * 64 ); + slot->metrics.height = (FT_Pos)( bitmap->rows * 64 ); /* * XXX DWIDTH1 and VVECTOR should be parsed and * used here, provided such fonts do exist. */ ft_synthesize_vertical_metrics( &slot->metrics, - bdf->bdffont->bbx.height << 6 ); + bdf->bdffont->bbx.height * 64 ); Exit: return error; @@ -804,8 +824,8 @@ THE SOFTWARE. static const FT_Service_BDFRec bdf_service_bdf = { - (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, - (FT_BDF_GetPropertyFunc) bdf_get_bdf_property + (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, /* get_charset_id */ + (FT_BDF_GetPropertyFunc) bdf_get_bdf_property /* get_property */ }; @@ -817,8 +837,8 @@ THE SOFTWARE. static const FT_ServiceDescRec bdf_services[] = { - { FT_SERVICE_ID_BDF, &bdf_service_bdf }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF }, + { FT_SERVICE_ID_BDF, &bdf_service_bdf }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_BDF }, { NULL, NULL } }; @@ -846,32 +866,32 @@ THE SOFTWARE. 0x10000L, 0x20000L, - 0, + 0, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - bdf_driver_requester + 0, /* FT_Module_Constructor module_init */ + 0, /* FT_Module_Destructor module_done */ + bdf_driver_requester /* FT_Module_Requester get_interface */ }, sizeof ( BDF_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - BDF_Face_Init, - BDF_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ + BDF_Face_Init, /* FT_Face_InitFunc init_face */ + BDF_Face_Done, /* FT_Face_DoneFunc done_face */ + 0, /* FT_Size_InitFunc init_size */ + 0, /* FT_Size_DoneFunc done_size */ + 0, /* FT_Slot_InitFunc init_slot */ + 0, /* FT_Slot_DoneFunc done_slot */ - BDF_Glyph_Load, + BDF_Glyph_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - BDF_Size_Request, - BDF_Size_Select + BDF_Size_Request, /* FT_Size_RequestFunc request_size */ + BDF_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/freetype/src/bdf/bdfdrivr.h b/drivers/freetype/src/bdf/bdfdrivr.h index ca0dae50d2..94550818c1 100644 --- a/drivers/freetype/freetype/src/bdf/bdfdrivr.h +++ b/drivers/freetype/src/bdf/bdfdrivr.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __BDFDRIVR_H__ -#define __BDFDRIVR_H__ +#ifndef BDFDRIVR_H_ +#define BDFDRIVR_H_ #include <ft2build.h> #include FT_INTERNAL_DRIVER_H @@ -43,7 +43,7 @@ FT_BEGIN_HEADER typedef struct BDF_encoding_el_ { - FT_ULong enc; + FT_Long enc; FT_UShort glyph; } BDF_encoding_el; @@ -74,7 +74,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __BDFDRIVR_H__ */ +#endif /* BDFDRIVR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/bdf/bdferror.h b/drivers/freetype/src/bdf/bdferror.h index ea545aca06..b462c7d3b5 100644 --- a/drivers/freetype/freetype/src/bdf/bdferror.h +++ b/drivers/freetype/src/bdf/bdferror.h @@ -26,12 +26,12 @@ /* */ /*************************************************************************/ -#ifndef __BDFERROR_H__ -#define __BDFERROR_H__ +#ifndef BDFERROR_H_ +#define BDFERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX BDF_Err_ @@ -39,7 +39,7 @@ #include FT_ERRORS_H -#endif /* __BDFERROR_H__ */ +#endif /* BDFERROR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/bdf/bdflib.c b/drivers/freetype/src/bdf/bdflib.c index 0b8412d9eb..e1dce954ff 100644 --- a/drivers/freetype/freetype/src/bdf/bdflib.c +++ b/drivers/freetype/src/bdf/bdflib.c @@ -1,6 +1,6 @@ /* * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001-2013 + * Copyright 2001-2014 * Francesco Zappa Nardelli * * Permission is hereby granted, free of charge, to any person obtaining a @@ -169,6 +169,18 @@ sizeof ( _bdf_properties[0] ); + /* An auxiliary macro to parse properties, to be used in conditionals. */ + /* It behaves like `strncmp' but also tests the following character */ + /* whether it is a whitespace or NULL. */ + /* `property' is a constant string of length `n' to compare with. */ +#define _bdf_strncmp( name, property, n ) \ + ( ft_strncmp( name, property, n ) || \ + !( name[n] == ' ' || \ + name[n] == '\0' || \ + name[n] == '\n' || \ + name[n] == '\r' || \ + name[n] == '\t' ) ) + /* Auto correction messages. */ #define ACMSG1 "FONT_ASCENT property missing. " \ "Added `FONT_ASCENT %hd'.\n" @@ -189,6 +201,7 @@ #define ACMSG14 "Glyph %ld extra columns removed.\n" #define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n" #define ACMSG16 "Glyph %ld missing columns padded with zero bits.\n" +#define ACMSG17 "Adjusting number of glyphs to %ld.\n" /* Error messages. */ #define ERRMSG1 "[line %ld] Missing `%s' line.\n" @@ -208,164 +221,6 @@ /*************************************************************************/ /* */ - /* Hash table utilities for the properties. */ - /* */ - /*************************************************************************/ - - /* XXX: Replace this with FreeType's hash functions */ - - -#define INITIAL_HT_SIZE 241 - - typedef void - (*hash_free_func)( hashnode node ); - - static hashnode* - hash_bucket( const char* key, - hashtable* ht ) - { - const char* kp = key; - unsigned long res = 0; - hashnode* bp = ht->table, *ndp; - - - /* Mocklisp hash function. */ - while ( *kp ) - res = ( res << 5 ) - res + *kp++; - - ndp = bp + ( res % ht->size ); - while ( *ndp ) - { - kp = (*ndp)->key; - if ( kp[0] == key[0] && ft_strcmp( kp, key ) == 0 ) - break; - ndp--; - if ( ndp < bp ) - ndp = bp + ( ht->size - 1 ); - } - - return ndp; - } - - - static FT_Error - hash_rehash( hashtable* ht, - FT_Memory memory ) - { - hashnode* obp = ht->table, *bp, *nbp; - int i, sz = ht->size; - FT_Error error = FT_Err_Ok; - - - ht->size <<= 1; - ht->limit = ht->size / 3; - - if ( FT_NEW_ARRAY( ht->table, ht->size ) ) - goto Exit; - - for ( i = 0, bp = obp; i < sz; i++, bp++ ) - { - if ( *bp ) - { - nbp = hash_bucket( (*bp)->key, ht ); - *nbp = *bp; - } - } - FT_FREE( obp ); - - Exit: - return error; - } - - - static FT_Error - hash_init( hashtable* ht, - FT_Memory memory ) - { - int sz = INITIAL_HT_SIZE; - FT_Error error = FT_Err_Ok; - - - ht->size = sz; - ht->limit = sz / 3; - ht->used = 0; - - if ( FT_NEW_ARRAY( ht->table, sz ) ) - goto Exit; - - Exit: - return error; - } - - - static void - hash_free( hashtable* ht, - FT_Memory memory ) - { - if ( ht != 0 ) - { - int i, sz = ht->size; - hashnode* bp = ht->table; - - - for ( i = 0; i < sz; i++, bp++ ) - FT_FREE( *bp ); - - FT_FREE( ht->table ); - } - } - - - static FT_Error - hash_insert( char* key, - size_t data, - hashtable* ht, - FT_Memory memory ) - { - hashnode nn; - hashnode* bp = hash_bucket( key, ht ); - FT_Error error = FT_Err_Ok; - - - nn = *bp; - if ( !nn ) - { - if ( FT_NEW( nn ) ) - goto Exit; - *bp = nn; - - nn->key = key; - nn->data = data; - - if ( ht->used >= ht->limit ) - { - error = hash_rehash( ht, memory ); - if ( error ) - goto Exit; - } - ht->used++; - } - else - nn->data = data; - - Exit: - return error; - } - - - static hashnode - hash_lookup( const char* key, - hashtable* ht ) - { - hashnode *np = hash_bucket( key, ht ); - - - return *np; - } - - - /*************************************************************************/ - /* */ /* Utility types and functions. */ /* */ /*************************************************************************/ @@ -420,6 +275,7 @@ _bdf_list_t list; FT_Memory memory; + unsigned long size; /* the stream size */ } _bdf_parse_t; @@ -558,10 +414,11 @@ char* line, unsigned long linelen ) { - int mult, final_empty; - char *sp, *ep, *end; - char seps[32]; - FT_Error error = FT_Err_Ok; + unsigned long final_empty; + int mult; + char *sp, *ep, *end; + char seps[32]; + FT_Error error = FT_Err_Ok; /* Initialize the list. */ @@ -670,7 +527,7 @@ unsigned long lineno, buf_size; int refill, hold, to_skip; ptrdiff_t bytes, start, end, cursor, avail; - char* buf = 0; + char* buf = NULL; FT_Memory memory = stream->memory; FT_Error error = FT_Err_Ok; @@ -691,7 +548,6 @@ lineno = 1; buf[0] = 0; start = 0; - end = 0; avail = 0; cursor = 0; refill = 1; @@ -704,7 +560,7 @@ { bytes = (ptrdiff_t)FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor, - (FT_ULong)( buf_size - cursor ) ); + buf_size - (unsigned long)cursor ); avail = cursor + bytes; cursor = 0; refill = 0; @@ -749,7 +605,7 @@ if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) ) goto Exit; - cursor = buf_size; + cursor = (ptrdiff_t)buf_size; buf_size = new_size; } else @@ -770,8 +626,8 @@ hold = buf[end]; buf[end] = 0; - /* XXX: Use encoding independent value for 0x1a */ - if ( buf[start] != '#' && buf[start] != 0x1a && end > start ) + /* XXX: Use encoding independent value for 0x1A */ + if ( buf[start] != '#' && buf[start] != 0x1A && end > start ) { error = (*cb)( buf + start, (unsigned long)( end - start ), lineno, (void*)&cb, client_data ); @@ -812,25 +668,17 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static const unsigned char odigits[32] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - static const unsigned char ddigits[32] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -838,88 +686,40 @@ static const unsigned char hdigits[32] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, - 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, + 0x7E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; - /* Routine to convert an ASCII string into an unsigned long integer. */ + /* Routine to convert a decimal ASCII string to an unsigned long integer. */ static unsigned long - _bdf_atoul( char* s, - char** end, - int base ) + _bdf_atoul( char* s ) { - unsigned long v; - const unsigned char* dmap; + unsigned long v; if ( s == 0 || *s == 0 ) return 0; - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } - - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = v * base + a2i[(int)*s]; - - if ( end != 0 ) - *end = s; + for ( v = 0; sbitset( ddigits, *s ); s++ ) + v = v * 10 + a2i[(int)*s]; return v; } - /* Routine to convert an ASCII string into an signed long integer. */ + /* Routine to convert a decimal ASCII string to a signed long integer. */ static long - _bdf_atol( char* s, - char** end, - int base ) + _bdf_atol( char* s ) { - long v, neg; - const unsigned char* dmap; + long v, neg; if ( s == 0 || *s == 0 ) return 0; - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - /* Check for a minus sign. */ neg = 0; if ( *s == '-' ) @@ -928,53 +728,40 @@ neg = 1; } - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } + for ( v = 0; sbitset( ddigits, *s ); s++ ) + v = v * 10 + a2i[(int)*s]; - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = v * base + a2i[(int)*s]; + return ( !neg ) ? v : -v; + } - if ( end != 0 ) - *end = s; - return ( !neg ) ? v : -v; + /* Routine to convert a decimal ASCII string to an unsigned short integer. */ + static unsigned short + _bdf_atous( char* s ) + { + unsigned short v; + + + if ( s == 0 || *s == 0 ) + return 0; + + for ( v = 0; sbitset( ddigits, *s ); s++ ) + v = (unsigned short)( v * 10 + a2i[(int)*s] ); + + return v; } - /* Routine to convert an ASCII string into an signed short integer. */ + /* Routine to convert a decimal ASCII string to a signed short integer. */ static short - _bdf_atos( char* s, - char** end, - int base ) + _bdf_atos( char* s ) { - short v, neg; - const unsigned char* dmap; + short v, neg; if ( s == 0 || *s == 0 ) return 0; - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - /* Check for a minus. */ neg = 0; if ( *s == '-' ) @@ -983,20 +770,8 @@ neg = 1; } - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } - - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = (short)( v * base + a2i[(int)*s] ); - - if ( end != 0 ) - *end = s; + for ( v = 0; sbitset( ddigits, *s ); s++ ) + v = (short)( v * 10 + a2i[(int)*s] ); return (short)( ( !neg ) ? v : -v ); } @@ -1037,7 +812,7 @@ /* First check whether the property has */ /* already been added or not. If it has, then */ /* simply ignore it. */ - if ( hash_lookup( name, &(font->proptbl) ) ) + if ( ft_hash_str_lookup( name, &(font->proptbl) ) ) goto Exit; if ( FT_RENEW_ARRAY( font->user_props, @@ -1062,7 +837,7 @@ n = _num_bdf_properties + font->nuser_props; - error = hash_insert( p->name, n, &(font->proptbl), memory ); + error = ft_hash_str_insert( p->name, n, &(font->proptbl), memory ); if ( error ) goto Exit; @@ -1073,25 +848,23 @@ } - FT_LOCAL_DEF( bdf_property_t * ) + FT_LOCAL_DEF( bdf_property_t* ) bdf_get_property( char* name, bdf_font_t* font ) { - hashnode hn; - size_t propid; + size_t* propid; if ( name == 0 || *name == 0 ) return 0; - if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 ) + if ( ( propid = ft_hash_str_lookup( name, &(font->proptbl) ) ) == NULL ) return 0; - propid = hn->data; - if ( propid >= _num_bdf_properties ) - return font->user_props + ( propid - _num_bdf_properties ); + if ( *propid >= _num_bdf_properties ) + return font->user_props + ( *propid - _num_bdf_properties ); - return (bdf_property_t*)_bdf_properties + propid; + return (bdf_property_t*)_bdf_properties + *propid; } @@ -1104,30 +877,30 @@ /* Parse flags. */ -#define _BDF_START 0x0001 -#define _BDF_FONT_NAME 0x0002 -#define _BDF_SIZE 0x0004 -#define _BDF_FONT_BBX 0x0008 -#define _BDF_PROPS 0x0010 -#define _BDF_GLYPHS 0x0020 -#define _BDF_GLYPH 0x0040 -#define _BDF_ENCODING 0x0080 -#define _BDF_SWIDTH 0x0100 -#define _BDF_DWIDTH 0x0200 -#define _BDF_BBX 0x0400 -#define _BDF_BITMAP 0x0800 +#define BDF_START_ 0x0001U +#define BDF_FONT_NAME_ 0x0002U +#define BDF_SIZE_ 0x0004U +#define BDF_FONT_BBX_ 0x0008U +#define BDF_PROPS_ 0x0010U +#define BDF_GLYPHS_ 0x0020U +#define BDF_GLYPH_ 0x0040U +#define BDF_ENCODING_ 0x0080U +#define BDF_SWIDTH_ 0x0100U +#define BDF_DWIDTH_ 0x0200U +#define BDF_BBX_ 0x0400U +#define BDF_BITMAP_ 0x0800U -#define _BDF_SWIDTH_ADJ 0x1000 +#define BDF_SWIDTH_ADJ_ 0x1000U -#define _BDF_GLYPH_BITS ( _BDF_GLYPH | \ - _BDF_ENCODING | \ - _BDF_SWIDTH | \ - _BDF_DWIDTH | \ - _BDF_BBX | \ - _BDF_BITMAP ) +#define BDF_GLYPH_BITS_ ( BDF_GLYPH_ | \ + BDF_ENCODING_ | \ + BDF_SWIDTH_ | \ + BDF_DWIDTH_ | \ + BDF_BBX_ | \ + BDF_BITMAP_ ) -#define _BDF_GLYPH_WIDTH_CHECK 0x40000000UL -#define _BDF_GLYPH_HEIGHT_CHECK 0x80000000UL +#define BDF_GLYPH_WIDTH_CHECK_ 0x40000000UL +#define BDF_GLYPH_HEIGHT_CHECK_ 0x80000000UL static FT_Error @@ -1299,8 +1072,7 @@ char* value, unsigned long lineno ) { - size_t propid; - hashnode hn; + size_t* propid; bdf_property_t *prop, *fp; FT_Memory memory = font->memory; FT_Error error = FT_Err_Ok; @@ -1309,11 +1081,12 @@ /* First, check whether the property already exists in the font. */ - if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 ) + if ( ( propid = ft_hash_str_lookup( name, + (FT_Hash)font->internal ) ) != NULL ) { /* The property already exists in the font, so simply replace */ /* the value of the property with the current value. */ - fp = font->props + hn->data; + fp = font->props + *propid; switch ( fp->format ) { @@ -1329,11 +1102,11 @@ break; case BDF_INTEGER: - fp->value.l = _bdf_atol( value, 0, 10 ); + fp->value.l = _bdf_atol( value ); break; case BDF_CARDINAL: - fp->value.ul = _bdf_atoul( value, 0, 10 ); + fp->value.ul = _bdf_atoul( value ); break; default: @@ -1345,16 +1118,16 @@ /* See whether this property type exists yet or not. */ /* If not, create it. */ - hn = hash_lookup( name, &(font->proptbl) ); - if ( hn == 0 ) + propid = ft_hash_str_lookup( name, &(font->proptbl) ); + if ( propid == NULL ) { error = bdf_create_property( name, BDF_ATOM, font ); if ( error ) goto Exit; - hn = hash_lookup( name, &(font->proptbl) ); + propid = ft_hash_str_lookup( name, &(font->proptbl) ); } - /* Allocate another property if this is overflow. */ + /* Allocate another property if this is overflowing. */ if ( font->props_used == font->props_size ) { if ( font->props_size == 0 ) @@ -1375,11 +1148,10 @@ font->props_size++; } - propid = hn->data; - if ( propid >= _num_bdf_properties ) - prop = font->user_props + ( propid - _num_bdf_properties ); + if ( *propid >= _num_bdf_properties ) + prop = font->user_props + ( *propid - _num_bdf_properties ); else - prop = (bdf_property_t*)_bdf_properties + propid; + prop = (bdf_property_t*)_bdf_properties + *propid; fp = font->props + font->props_used; @@ -1399,23 +1171,23 @@ break; case BDF_INTEGER: - fp->value.l = _bdf_atol( value, 0, 10 ); + fp->value.l = _bdf_atol( value ); break; case BDF_CARDINAL: - fp->value.ul = _bdf_atoul( value, 0, 10 ); + fp->value.ul = _bdf_atoul( value ); break; } /* If the property happens to be a comment, then it doesn't need */ /* to be added to the internal hash table. */ - if ( ft_memcmp( name, "COMMENT", 7 ) != 0 ) + if ( _bdf_strncmp( name, "COMMENT", 7 ) != 0 ) { /* Add the property to the font property table. */ - error = hash_insert( fp->name, - font->props_used, - (hashtable *)font->internal, - memory ); + error = ft_hash_str_insert( fp->name, + font->props_used, + (FT_Hash)font->internal, + memory ); if ( error ) goto Exit; } @@ -1427,13 +1199,13 @@ /* FONT_ASCENT and FONT_DESCENT need to be assigned if they are */ /* present, and the SPACING property should override the default */ /* spacing. */ - if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 ) + if ( _bdf_strncmp( name, "DEFAULT_CHAR", 12 ) == 0 ) font->default_char = fp->value.l; - else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 ) + else if ( _bdf_strncmp( name, "FONT_ASCENT", 11 ) == 0 ) font->font_ascent = fp->value.l; - else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 ) + else if ( _bdf_strncmp( name, "FONT_DESCENT", 12 ) == 0 ) font->font_descent = fp->value.l; - else if ( ft_memcmp( name, "SPACING", 7 ) == 0 ) + else if ( _bdf_strncmp( name, "SPACING", 7 ) == 0 ) { if ( !fp->value.atom ) { @@ -1491,7 +1263,7 @@ memory = font->memory; /* Check for a comment. */ - if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 ) { linelen -= 7; @@ -1506,9 +1278,9 @@ } /* The very first thing expected is the number of glyphs. */ - if ( !( p->flags & _BDF_GLYPHS ) ) + if ( !( p->flags & BDF_GLYPHS_ ) ) { - if ( ft_memcmp( line, "CHARS", 5 ) != 0 ) + if ( _bdf_strncmp( line, "CHARS", 5 ) != 0 ) { FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" )); error = FT_THROW( Missing_Chars_Field ); @@ -1518,7 +1290,14 @@ error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 ); + p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1] ); + + /* We need at least 20 bytes per glyph. */ + if ( p->cnt > p->size / 20 ) + { + p->cnt = font->glyphs_size = p->size / 20; + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG17, p->cnt )); + } /* Make sure the number of glyphs is non-zero. */ if ( p->cnt == 0 ) @@ -1536,44 +1315,60 @@ if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) ) goto Exit; - p->flags |= _BDF_GLYPHS; + p->flags |= BDF_GLYPHS_; goto Exit; } /* Check for the ENDFONT field. */ - if ( ft_memcmp( line, "ENDFONT", 7 ) == 0 ) + if ( _bdf_strncmp( line, "ENDFONT", 7 ) == 0 ) { + if ( p->flags & BDF_GLYPH_BITS_ ) + { + /* Missing ENDCHAR field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENDCHAR" )); + error = FT_THROW( Corrupted_Font_Glyphs ); + goto Exit; + } + /* Sort the glyphs by encoding. */ ft_qsort( (char *)font->glyphs, font->glyphs_used, sizeof ( bdf_glyph_t ), by_encoding ); - p->flags &= ~_BDF_START; + p->flags &= ~BDF_START_; goto Exit; } /* Check for the ENDCHAR field. */ - if ( ft_memcmp( line, "ENDCHAR", 7 ) == 0 ) + if ( _bdf_strncmp( line, "ENDCHAR", 7 ) == 0 ) { p->glyph_enc = 0; - p->flags &= ~_BDF_GLYPH_BITS; + p->flags &= ~BDF_GLYPH_BITS_; goto Exit; } /* Check whether a glyph is being scanned but should be */ /* ignored because it is an unencoded glyph. */ - if ( ( p->flags & _BDF_GLYPH ) && + if ( ( p->flags & BDF_GLYPH_ ) && p->glyph_enc == -1 && p->opts->keep_unencoded == 0 ) goto Exit; /* Check for the STARTCHAR field. */ - if ( ft_memcmp( line, "STARTCHAR", 9 ) == 0 ) + if ( _bdf_strncmp( line, "STARTCHAR", 9 ) == 0 ) { + if ( p->flags & BDF_GLYPH_BITS_ ) + { + /* Missing ENDCHAR field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENDCHAR" )); + error = FT_THROW( Missing_Startchar_Field ); + goto Exit; + } + /* Set the character name in the parse info first until the */ /* encoding can be checked for an unencoded character. */ FT_FREE( p->glyph_name ); @@ -1598,7 +1393,7 @@ FT_MEM_COPY( p->glyph_name, s, slen + 1 ); - p->flags |= _BDF_GLYPH; + p->flags |= BDF_GLYPH_; FT_TRACE4(( DBGMSG1, lineno, s )); @@ -1606,9 +1401,9 @@ } /* Check for the ENCODING field. */ - if ( ft_memcmp( line, "ENCODING", 8 ) == 0 ) + if ( _bdf_strncmp( line, "ENCODING", 8 ) == 0 ) { - if ( !( p->flags & _BDF_GLYPH ) ) + if ( !( p->flags & BDF_GLYPH_ ) ) { /* Missing STARTCHAR field. */ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" )); @@ -1620,7 +1415,7 @@ if ( error ) goto Exit; - p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 ); + p->glyph_enc = _bdf_atol( p->list.field[1] ); /* Normalize negative encoding values. The specification only */ /* allows -1, but we can be more generous here. */ @@ -1629,7 +1424,7 @@ /* Check for alternative encoding format. */ if ( p->glyph_enc == -1 && p->list.used > 2 ) - p->glyph_enc = _bdf_atol( p->list.field[2], 0, 10 ); + p->glyph_enc = _bdf_atol( p->list.field[2] ); if ( p->glyph_enc < -1 ) p->glyph_enc = -1; @@ -1684,7 +1479,7 @@ glyph->encoding = p->glyph_enc; /* Reset the initial glyph info. */ - p->glyph_name = 0; + p->glyph_name = NULL; } else { @@ -1705,21 +1500,26 @@ glyph = font->unencoded + font->unencoded_used; glyph->name = p->glyph_name; - glyph->encoding = font->unencoded_used++; + glyph->encoding = (long)font->unencoded_used++; + + /* Reset the initial glyph info. */ + p->glyph_name = NULL; } else + { /* Free up the glyph name if the unencoded shouldn't be */ /* kept. */ FT_FREE( p->glyph_name ); + } - p->glyph_name = 0; + p->glyph_name = NULL; } /* Clear the flags that might be added when width and height are */ /* checked for consistency. */ - p->flags &= ~( _BDF_GLYPH_WIDTH_CHECK | _BDF_GLYPH_HEIGHT_CHECK ); + p->flags &= ~( BDF_GLYPH_WIDTH_CHECK_ | BDF_GLYPH_HEIGHT_CHECK_ ); - p->flags |= _BDF_ENCODING; + p->flags |= BDF_ENCODING_; goto Exit; } @@ -1731,16 +1531,16 @@ glyph = font->glyphs + ( font->glyphs_used - 1 ); /* Check whether a bitmap is being constructed. */ - if ( p->flags & _BDF_BITMAP ) + if ( p->flags & BDF_BITMAP_ ) { /* If there are more rows than are specified in the glyph metrics, */ /* ignore the remaining lines. */ if ( p->row >= (unsigned long)glyph->bbx.height ) { - if ( !( p->flags & _BDF_GLYPH_HEIGHT_CHECK ) ) + if ( !( p->flags & BDF_GLYPH_HEIGHT_CHECK_ ) ) { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding )); - p->flags |= _BDF_GLYPH_HEIGHT_CHECK; + p->flags |= BDF_GLYPH_HEIGHT_CHECK_; font->modified = 1; } @@ -1765,10 +1565,10 @@ /* If any line has not enough columns, */ /* indicate they have been padded with zero bits. */ if ( i < nibbles && - !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) + !( p->flags & BDF_GLYPH_WIDTH_CHECK_ ) ) { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG16, glyph->encoding )); - p->flags |= _BDF_GLYPH_WIDTH_CHECK; + p->flags |= BDF_GLYPH_WIDTH_CHECK_; font->modified = 1; } @@ -1780,10 +1580,10 @@ /* If any line has extra columns, indicate they have been removed. */ if ( i == nibbles && sbitset( hdigits, line[nibbles] ) && - !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) + !( p->flags & BDF_GLYPH_WIDTH_CHECK_ ) ) { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding )); - p->flags |= _BDF_GLYPH_WIDTH_CHECK; + p->flags |= BDF_GLYPH_WIDTH_CHECK_; font->modified = 1; } @@ -1792,34 +1592,34 @@ } /* Expect the SWIDTH (scalable width) field next. */ - if ( ft_memcmp( line, "SWIDTH", 6 ) == 0 ) + if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 ) { - if ( !( p->flags & _BDF_ENCODING ) ) + if ( !( p->flags & BDF_ENCODING_ ) ) goto Missing_Encoding; error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); - p->flags |= _BDF_SWIDTH; + glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1] ); + p->flags |= BDF_SWIDTH_; goto Exit; } /* Expect the DWIDTH (scalable width) field next. */ - if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 ) + if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 ) { - if ( !( p->flags & _BDF_ENCODING ) ) + if ( !( p->flags & BDF_ENCODING_ ) ) goto Missing_Encoding; error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); + glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1] ); - if ( !( p->flags & _BDF_SWIDTH ) ) + if ( !( p->flags & BDF_SWIDTH_ ) ) { /* Missing SWIDTH field. Emit an auto correction message and set */ /* the scalable width from the device width. */ @@ -1831,24 +1631,24 @@ font->resolution_x ) ); } - p->flags |= _BDF_DWIDTH; + p->flags |= BDF_DWIDTH_; goto Exit; } /* Expect the BBX field next. */ - if ( ft_memcmp( line, "BBX", 3 ) == 0 ) + if ( _bdf_strncmp( line, "BBX", 3 ) == 0 ) { - if ( !( p->flags & _BDF_ENCODING ) ) + if ( !( p->flags & BDF_ENCODING_ ) ) goto Missing_Encoding; error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - glyph->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); - glyph->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); - glyph->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); - glyph->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + glyph->bbx.width = _bdf_atous( p->list.field[1] ); + glyph->bbx.height = _bdf_atous( p->list.field[2] ); + glyph->bbx.x_offset = _bdf_atos( p->list.field[3] ); + glyph->bbx.y_offset = _bdf_atos( p->list.field[4] ); /* Generate the ascent and descent of the character. */ glyph->bbx.ascent = (short)( glyph->bbx.height + glyph->bbx.y_offset ); @@ -1865,7 +1665,7 @@ p->minlb = (short)FT_MIN( glyph->bbx.x_offset, p->minlb ); p->maxlb = (short)FT_MAX( glyph->bbx.x_offset, p->maxlb ); - if ( !( p->flags & _BDF_DWIDTH ) ) + if ( !( p->flags & BDF_DWIDTH_ ) ) { /* Missing DWIDTH field. Emit an auto correction message and set */ /* the device width to the glyph width. */ @@ -1894,22 +1694,22 @@ else _bdf_set_glyph_modified( font->nmod, glyph->encoding ); - p->flags |= _BDF_SWIDTH_ADJ; + p->flags |= BDF_SWIDTH_ADJ_; font->modified = 1; } } - p->flags |= _BDF_BBX; + p->flags |= BDF_BBX_; goto Exit; } /* And finally, gather up the bitmap. */ - if ( ft_memcmp( line, "BITMAP", 6 ) == 0 ) + if ( _bdf_strncmp( line, "BITMAP", 6 ) == 0 ) { unsigned long bitmap_size; - if ( !( p->flags & _BDF_BBX ) ) + if ( !( p->flags & BDF_BBX_ ) ) { /* Missing BBX field. */ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" )); @@ -1934,7 +1734,7 @@ goto Exit; p->row = 0; - p->flags |= _BDF_BITMAP; + p->flags |= BDF_BITMAP_; goto Exit; } @@ -1949,7 +1749,7 @@ error = FT_THROW( Missing_Encoding_Field ); Exit: - if ( error && ( p->flags & _BDF_GLYPH ) ) + if ( error && ( p->flags & BDF_GLYPH_ ) ) FT_FREE( p->glyph_name ); return error; @@ -1979,7 +1779,7 @@ p = (_bdf_parse_t *) client_data; /* Check for the end of the properties. */ - if ( ft_memcmp( line, "ENDPROPERTIES", 13 ) == 0 ) + if ( _bdf_strncmp( line, "ENDPROPERTIES", 13 ) == 0 ) { /* If the FONT_ASCENT or FONT_DESCENT properties have not been */ /* encountered yet, then make sure they are added as properties and */ @@ -2013,19 +1813,19 @@ p->font->modified = 1; } - p->flags &= ~_BDF_PROPS; + p->flags &= ~BDF_PROPS_; *next = _bdf_parse_glyphs; goto Exit; } /* Ignore the _XFREE86_GLYPH_RANGES properties. */ - if ( ft_memcmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 ) + if ( _bdf_strncmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 ) goto Exit; /* Handle COMMENT fields and properties in a special way to preserve */ /* the spacing. */ - if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 ) { name = value = line; value += 7; @@ -2089,7 +1889,7 @@ /* Check for a comment. This is done to handle those fonts that have */ /* comments before the STARTFONT line for some reason. */ - if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 ) { if ( p->opts->keep_comments != 0 && p->font != 0 ) { @@ -2111,11 +1911,11 @@ goto Exit; } - if ( !( p->flags & _BDF_START ) ) + if ( !( p->flags & BDF_START_ ) ) { memory = p->memory; - if ( ft_memcmp( line, "STARTFONT", 9 ) != 0 ) + if ( _bdf_strncmp( line, "STARTFONT", 9 ) != 0 ) { /* we don't emit an error message since this code gets */ /* explicitly caught one level higher */ @@ -2123,7 +1923,7 @@ goto Exit; } - p->flags = _BDF_START; + p->flags = BDF_START_; font = p->font = 0; if ( FT_NEW( font ) ) @@ -2138,22 +1938,22 @@ bdf_property_t* prop; - error = hash_init( &(font->proptbl), memory ); + error = ft_hash_str_init( &(font->proptbl), memory ); if ( error ) goto Exit; for ( i = 0, prop = (bdf_property_t*)_bdf_properties; i < _num_bdf_properties; i++, prop++ ) { - error = hash_insert( prop->name, i, - &(font->proptbl), memory ); + error = ft_hash_str_insert( prop->name, i, + &(font->proptbl), memory ); if ( error ) goto Exit; } } - if ( FT_ALLOC( p->font->internal, sizeof ( hashtable ) ) ) + if ( FT_ALLOC( p->font->internal, sizeof ( FT_HashRec ) ) ) goto Exit; - error = hash_init( (hashtable *)p->font->internal,memory ); + error = ft_hash_str_init( (FT_Hash)p->font->internal, memory ); if ( error ) goto Exit; p->font->spacing = p->opts->font_spacing; @@ -2163,9 +1963,9 @@ } /* Check for the start of the properties. */ - if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 ) + if ( _bdf_strncmp( line, "STARTPROPERTIES", 15 ) == 0 ) { - if ( !( p->flags & _BDF_FONT_BBX ) ) + if ( !( p->flags & BDF_FONT_BBX_ ) ) { /* Missing the FONTBOUNDINGBOX field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" )); @@ -2176,8 +1976,18 @@ error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; + /* at this point, `p->font' can't be NULL */ - p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 ); + p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1] ); + /* We need at least 4 bytes per property. */ + if ( p->cnt > p->size / 4 ) + { + p->font->props_size = 0; + + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "STARTPROPERTIES" )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } if ( FT_NEW_ARRAY( p->font->props, p->cnt ) ) { @@ -2185,16 +1995,16 @@ goto Exit; } - p->flags |= _BDF_PROPS; + p->flags |= BDF_PROPS_; *next = _bdf_parse_properties; goto Exit; } /* Check for the FONTBOUNDINGBOX field. */ - if ( ft_memcmp( line, "FONTBOUNDINGBOX", 15 ) == 0 ) + if ( _bdf_strncmp( line, "FONTBOUNDINGBOX", 15 ) == 0 ) { - if ( !( p->flags & _BDF_SIZE ) ) + if ( !( p->flags & BDF_SIZE_ ) ) { /* Missing the SIZE field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" )); @@ -2206,24 +2016,24 @@ if ( error ) goto Exit; - p->font->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); - p->font->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); + p->font->bbx.width = _bdf_atous( p->list.field[1] ); + p->font->bbx.height = _bdf_atous( p->list.field[2] ); - p->font->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); - p->font->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + p->font->bbx.x_offset = _bdf_atos( p->list.field[3] ); + p->font->bbx.y_offset = _bdf_atos( p->list.field[4] ); p->font->bbx.ascent = (short)( p->font->bbx.height + p->font->bbx.y_offset ); p->font->bbx.descent = (short)( -p->font->bbx.y_offset ); - p->flags |= _BDF_FONT_BBX; + p->flags |= BDF_FONT_BBX_; goto Exit; } /* The next thing to check for is the FONT field. */ - if ( ft_memcmp( line, "FONT", 4 ) == 0 ) + if ( _bdf_strncmp( line, "FONT", 4 ) == 0 ) { error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) @@ -2252,15 +2062,15 @@ if ( error ) goto Exit; - p->flags |= _BDF_FONT_NAME; + p->flags |= BDF_FONT_NAME_; goto Exit; } /* Check for the SIZE field. */ - if ( ft_memcmp( line, "SIZE", 4 ) == 0 ) + if ( _bdf_strncmp( line, "SIZE", 4 ) == 0 ) { - if ( !( p->flags & _BDF_FONT_NAME ) ) + if ( !( p->flags & BDF_FONT_NAME_ ) ) { /* Missing the FONT field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" )); @@ -2272,52 +2082,46 @@ if ( error ) goto Exit; - p->font->point_size = _bdf_atoul( p->list.field[1], 0, 10 ); - p->font->resolution_x = _bdf_atoul( p->list.field[2], 0, 10 ); - p->font->resolution_y = _bdf_atoul( p->list.field[3], 0, 10 ); + p->font->point_size = _bdf_atoul( p->list.field[1] ); + p->font->resolution_x = _bdf_atoul( p->list.field[2] ); + p->font->resolution_y = _bdf_atoul( p->list.field[3] ); /* Check for the bits per pixel field. */ if ( p->list.used == 5 ) { - unsigned short bitcount, i, shift; + unsigned short bpp; - p->font->bpp = (unsigned short)_bdf_atos( p->list.field[4], 0, 10 ); + bpp = (unsigned short)_bdf_atos( p->list.field[4] ); - /* Only values 1, 2, 4, 8 are allowed. */ - shift = p->font->bpp; - bitcount = 0; - for ( i = 0; shift > 0; i++ ) - { - if ( shift & 1 ) - bitcount = i; - shift >>= 1; - } - - shift = (short)( ( bitcount > 3 ) ? 8 : ( 1 << bitcount ) ); + /* Only values 1, 2, 4, 8 are allowed for greymap fonts. */ + if ( bpp > 4 ) + p->font->bpp = 8; + else if ( bpp > 2 ) + p->font->bpp = 4; + else if ( bpp > 1 ) + p->font->bpp = 2; + else + p->font->bpp = 1; - if ( p->font->bpp > shift || p->font->bpp != shift ) - { - /* select next higher value */ - p->font->bpp = (unsigned short)( shift << 1 ); + if ( p->font->bpp != bpp ) FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp )); - } } else p->font->bpp = 1; - p->flags |= _BDF_SIZE; + p->flags |= BDF_SIZE_; goto Exit; } /* Check for the CHARS field -- font properties are optional */ - if ( ft_memcmp( line, "CHARS", 5 ) == 0 ) + if ( _bdf_strncmp( line, "CHARS", 5 ) == 0 ) { char nbuf[128]; - if ( !( p->flags & _BDF_FONT_BBX ) ) + if ( !( p->flags & BDF_FONT_BBX_ ) ) { /* Missing the FONTBOUNDINGBOX field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" )); @@ -2376,8 +2180,8 @@ unsigned long lineno = 0; /* make compiler happy */ _bdf_parse_t *p = NULL; - FT_Memory memory = extmemory; - FT_Error error = FT_Err_Ok; + FT_Memory memory = extmemory; /* needed for FT_NEW */ + FT_Error error = FT_Err_Ok; if ( FT_NEW( p ) ) @@ -2386,6 +2190,7 @@ memory = NULL; p->opts = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts ); p->minlb = 32767; + p->size = stream->size; p->memory = extmemory; /* only during font creation */ _bdf_list_init( &p->list, extmemory ); @@ -2399,7 +2204,6 @@ { /* If the font is not proportional, set the font's monowidth */ /* field to the width of the font bounding box. */ - memory = p->font->memory; if ( p->font->spacing != BDF_PROPORTIONAL ) p->font->monowidth = p->font->bbx.width; @@ -2458,27 +2262,27 @@ p->font->bbx.height = (unsigned short)( p->maxas + p->maxds ); } - if ( p->flags & _BDF_SWIDTH_ADJ ) + if ( p->flags & BDF_SWIDTH_ADJ_ ) FT_TRACE2(( "bdf_load_font: " ACMSG8 )); } } - if ( p->flags & _BDF_START ) + if ( p->flags & BDF_START_ ) { /* The ENDFONT field was never reached or did not exist. */ - if ( !( p->flags & _BDF_GLYPHS ) ) + if ( !( p->flags & BDF_GLYPHS_ ) ) { /* Error happened while parsing header. */ FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno )); error = FT_THROW( Corrupted_Font_Header ); - goto Exit; + goto Fail; } else { /* Error happened when parsing glyphs. */ FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno )); error = FT_THROW( Corrupted_Font_Glyphs ); - goto Exit; + goto Fail; } } @@ -2509,6 +2313,7 @@ memory = extmemory; + FT_FREE( p->glyph_name ); FT_FREE( p ); } @@ -2544,7 +2349,7 @@ /* Free up the internal hash table of property names. */ if ( font->internal ) { - hash_free( (hashtable *)font->internal, memory ); + ft_hash_str_free( (FT_Hash)font->internal, memory ); FT_FREE( font->internal ); } @@ -2589,7 +2394,7 @@ FT_FREE( font->overflow.glyphs ); /* bdf_cleanup */ - hash_free( &(font->proptbl), memory ); + ft_hash_str_free( &(font->proptbl), memory ); /* Free up the user defined properties. */ for ( prop = font->user_props, i = 0; @@ -2610,15 +2415,15 @@ bdf_get_font_property( bdf_font_t* font, const char* name ) { - hashnode hn; + size_t* propid; if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 ) return 0; - hn = hash_lookup( name, (hashtable *)font->internal ); + propid = ft_hash_str_lookup( name, (FT_Hash)font->internal ); - return hn ? ( font->props + hn->data ) : 0; + return propid ? ( font->props + *propid ) : 0; } diff --git a/drivers/freetype/freetype/src/bdf/module.mk b/drivers/freetype/src/bdf/module.mk index fe06ae8e06..fe06ae8e06 100644 --- a/drivers/freetype/freetype/src/bdf/module.mk +++ b/drivers/freetype/src/bdf/module.mk diff --git a/drivers/freetype/freetype/src/bdf/rules.mk b/drivers/freetype/src/bdf/rules.mk index 6ff1614dde..d1dd76b1c3 100644 --- a/drivers/freetype/freetype/src/bdf/rules.mk +++ b/drivers/freetype/src/bdf/rules.mk @@ -32,7 +32,10 @@ BDF_DIR := $(SRC_DIR)/bdf -BDF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(BDF_DIR)) +BDF_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(BDF_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # bdf driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/cache/Jamfile b/drivers/freetype/src/cache/Jamfile index 340cff7742..da6551015b 100644 --- a/drivers/freetype/freetype/src/cache/Jamfile +++ b/drivers/freetype/src/cache/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/cache Jamfile # -# Copyright 2001, 2003, 2004 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -11,25 +11,19 @@ SubDir FT2_TOP $(FT2_SRC_DIR) cache ; -# The file <freetype/ftcache.h> contains some macro definitions that are -# later used in #include statements related to the cache sub-system. It -# needs to be parsed through a HDRMACRO rule for macro definitions. -# -HDRMACRO [ FT2_SubDir include ftcache.h ] ; - { local _sources ; if $(FT2_MULTI) { - _sources = ftcmru - ftcmanag + _sources = ftcbasic ftccache ftcglyph - ftcsbits ftcimage - ftcbasic + ftcmanag ftccmap + ftcmru + ftcsbits ; } else diff --git a/drivers/freetype/freetype/src/cache/ftcache.c b/drivers/freetype/src/cache/ftcache.c index d41e91e5ec..50941df4c4 100644 --- a/drivers/freetype/freetype/src/cache/ftcache.c +++ b/drivers/freetype/src/cache/ftcache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType Caching sub-system (body only). */ /* */ -/* Copyright 2000-2001, 2003 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/cache/ftcbasic.c b/drivers/freetype/src/cache/ftcbasic.c index 84d336d5d6..8e6de8c41c 100644 --- a/drivers/freetype/freetype/src/cache/ftcbasic.c +++ b/drivers/freetype/src/cache/ftcbasic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType basic cache interface (body). */ /* */ -/* Copyright 2003-2007, 2009-2011, 2013 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,8 +45,8 @@ FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ (a)->load_flags == (b)->load_flags ) -#define FTC_BASIC_ATTR_HASH( a ) \ - ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags ) +#define FTC_BASIC_ATTR_HASH( a ) \ + ( FTC_SCALER_HASH( &(a)->scaler ) + 31 * (a)->load_flags ) typedef struct FTC_BasicQueryRec_ @@ -110,10 +110,9 @@ return result; if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs ) - { - FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " )); - FT_TRACE1(( "in this face, truncated\n", face->num_glyphs )); - } + FT_TRACE1(( "ftc_basic_family_get_count:" + " too large number of glyphs in this face, truncated\n", + face->num_glyphs )); if ( !error ) result = (FT_UInt)face->num_glyphs; @@ -139,8 +138,10 @@ FT_Face face = size->face; - error = FT_Load_Glyph( face, gindex, - family->attrs.load_flags | FT_LOAD_RENDER ); + error = FT_Load_Glyph( + face, + gindex, + (FT_Int)family->attrs.load_flags | FT_LOAD_RENDER ); if ( !error ) *aface = face; } @@ -170,7 +171,9 @@ { face = size->face; - error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); + error = FT_Load_Glyph( face, + gindex, + (FT_Int)family->attrs.load_flags ); if ( !error ) { if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || @@ -229,7 +232,7 @@ * */ - FT_CALLBACK_TABLE_DEF + static const FTC_IFamilyClassRec ftc_basic_image_family_class = { { @@ -243,7 +246,7 @@ }; - FT_CALLBACK_TABLE_DEF + static const FTC_GCacheClassRec ftc_basic_image_cache_class = { { @@ -284,10 +287,10 @@ FTC_BasicQueryRec query; FTC_Node node = 0; /* make compiler happy */ FT_Error error; - FT_PtrDist hash; + FT_Offset hash; - /* some argument checks are delayed to FTC_Cache_Lookup */ + /* some argument checks are delayed to `FTC_Cache_Lookup' */ if ( !aglyph ) { error = FT_THROW( Invalid_Argument ); @@ -298,18 +301,15 @@ if ( anode ) *anode = NULL; - { - if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); - } + if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX ) + FT_TRACE1(( "FTC_ImageCache_Lookup:" + " higher bits in load_flags 0x%x are dropped\n", + (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); - query.attrs.scaler.face_id = type->face_id; - query.attrs.scaler.width = type->width; - query.attrs.scaler.height = type->height; - query.attrs.load_flags = (FT_UInt)type->flags; - } + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.load_flags = (FT_UInt)type->flags; query.attrs.scaler.pixel = 1; query.attrs.scaler.x_res = 0; /* make compilers happy */ @@ -360,10 +360,10 @@ FTC_BasicQueryRec query; FTC_Node node = 0; /* make compiler happy */ FT_Error error; - FT_PtrDist hash; + FT_Offset hash; - /* some argument checks are delayed to FTC_Cache_Lookup */ + /* some argument checks are delayed to `FTC_Cache_Lookup' */ if ( !aglyph || !scaler ) { error = FT_THROW( Invalid_Argument ); @@ -374,12 +374,11 @@ if ( anode ) *anode = NULL; - /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */ if ( load_flags > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); - } + FT_TRACE1(( "FTC_ImageCache_LookupScaler:" + " higher bits in load_flags 0x%x are dropped\n", + load_flags & ~((FT_ULong)FT_UINT_MAX) )); query.attrs.scaler = scaler[0]; query.attrs.load_flags = (FT_UInt)load_flags; @@ -415,7 +414,7 @@ * */ - FT_CALLBACK_TABLE_DEF + static const FTC_SFamilyClassRec ftc_basic_sbit_family_class = { { @@ -430,7 +429,7 @@ }; - FT_CALLBACK_TABLE_DEF + static const FTC_GCacheClassRec ftc_basic_sbit_cache_class = { { @@ -471,30 +470,27 @@ FT_Error error; FTC_BasicQueryRec query; FTC_Node node = 0; /* make compiler happy */ - FT_PtrDist hash; + FT_Offset hash; if ( anode ) *anode = NULL; - /* other argument checks delayed to FTC_Cache_Lookup */ + /* other argument checks delayed to `FTC_Cache_Lookup' */ if ( !ansbit ) return FT_THROW( Invalid_Argument ); *ansbit = NULL; - { - if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); - } + if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX ) + FT_TRACE1(( "FTC_ImageCache_Lookup:" + " higher bits in load_flags 0x%x are dropped\n", + (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); - query.attrs.scaler.face_id = type->face_id; - query.attrs.scaler.width = type->width; - query.attrs.scaler.height = type->height; - query.attrs.load_flags = (FT_UInt)type->flags; - } + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.load_flags = (FT_UInt)type->flags; query.attrs.scaler.pixel = 1; query.attrs.scaler.x_res = 0; /* make compilers happy */ @@ -549,24 +545,23 @@ FT_Error error; FTC_BasicQueryRec query; FTC_Node node = 0; /* make compiler happy */ - FT_PtrDist hash; + FT_Offset hash; if ( anode ) *anode = NULL; - /* other argument checks delayed to FTC_Cache_Lookup */ + /* other argument checks delayed to `FTC_Cache_Lookup' */ if ( !ansbit || !scaler ) return FT_THROW( Invalid_Argument ); *ansbit = NULL; - /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */ if ( load_flags > FT_UINT_MAX ) - { - FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); - FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); - } + FT_TRACE1(( "FTC_ImageCache_LookupScaler:" + " higher bits in load_flags 0x%x are dropped\n", + load_flags & ~((FT_ULong)FT_UINT_MAX) )); query.attrs.scaler = scaler[0]; query.attrs.load_flags = (FT_UInt)load_flags; diff --git a/drivers/freetype/freetype/src/cache/ftccache.c b/drivers/freetype/src/cache/ftccache.c index f20dd4502c..3b1a4bc7e4 100644 --- a/drivers/freetype/freetype/src/cache/ftccache.c +++ b/drivers/freetype/src/cache/ftccache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType internal cache interface (body). */ /* */ -/* Copyright 2000-2007, 2009-2011, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,19 +85,19 @@ /* get a top bucket for specified hash from cache, - * body for FTC_NODE__TOP_FOR_HASH( cache, hash ) + * body for FTC_NODE_TOP_FOR_HASH( cache, hash ) */ FT_LOCAL_DEF( FTC_Node* ) - ftc_get_top_node_for_hash( FTC_Cache cache, - FT_PtrDist hash ) + ftc_get_top_node_for_hash( FTC_Cache cache, + FT_Offset hash ) { FTC_Node* pnode; - FT_UInt idx; + FT_Offset idx; - idx = (FT_UInt)( hash & cache->mask ); + idx = hash & cache->mask; if ( idx < cache->p ) - idx = (FT_UInt)( hash & ( 2 * cache->mask + 1 ) ); + idx = hash & ( 2 * cache->mask + 1 ); pnode = cache->buckets + idx; return pnode; } @@ -224,7 +224,7 @@ ftc_node_hash_unlink( FTC_Node node0, FTC_Cache cache ) { - FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node0->hash ); + FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node0->hash ); for (;;) @@ -257,7 +257,7 @@ ftc_node_hash_link( FTC_Node node, FTC_Cache cache ) { - FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node->hash ); + FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node->hash ); node->link = *pnode; @@ -414,7 +414,7 @@ static void ftc_cache_add( FTC_Cache cache, - FT_PtrDist hash, + FT_Offset hash, FTC_Node node ) { node->hash = hash; @@ -442,7 +442,7 @@ FT_LOCAL_DEF( FT_Error ) FTC_Cache_NewNode( FTC_Cache cache, - FT_PtrDist hash, + FT_Offset hash, FT_Pointer query, FTC_Node *anode ) { @@ -481,7 +481,7 @@ FT_LOCAL_DEF( FT_Error ) FTC_Cache_Lookup( FTC_Cache cache, - FT_PtrDist hash, + FT_Offset hash, FT_Pointer query, FTC_Node *anode ) { @@ -498,7 +498,7 @@ return FT_THROW( Invalid_Argument ); /* Go to the `top' node of the list sharing same masked hash */ - bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash ); + bucket = pnode = FTC_NODE_TOP_FOR_HASH( cache, hash ); /* Lookup a node with exactly same hash and queried properties. */ /* NOTE: _nodcomp() may change the linked list to reduce memory. */ @@ -518,7 +518,7 @@ if ( list_changed ) { /* Update bucket by modified linked list */ - bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash ); + bucket = pnode = FTC_NODE_TOP_FOR_HASH( cache, hash ); /* Update pnode by modified linked list */ while ( *pnode != node ) @@ -576,7 +576,7 @@ FTC_Node* pnode = bucket; - for ( ;; ) + for (;;) { FTC_Node node = *pnode; FT_Bool list_changed = FALSE; diff --git a/drivers/freetype/freetype/src/cache/ftccache.h b/drivers/freetype/src/cache/ftccache.h index 4155f320e0..1b1295951f 100644 --- a/drivers/freetype/freetype/src/cache/ftccache.h +++ b/drivers/freetype/src/cache/ftccache.h @@ -4,7 +4,7 @@ /* */ /* FreeType internal cache interface (specification). */ /* */ -/* Copyright 2000-2007, 2009-2011, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,16 +16,16 @@ /***************************************************************************/ -#ifndef __FTCCACHE_H__ -#define __FTCCACHE_H__ +#ifndef FTCCACHE_H_ +#define FTCCACHE_H_ #include "ftcmru.h" FT_BEGIN_HEADER -#define _FTC_FACE_ID_HASH( i ) \ - ((FT_PtrDist)(( (FT_PtrDist)(i) >> 3 ) ^ ( (FT_PtrDist)(i) << 7 ))) +#define FTC_FACE_ID_HASH( i ) \ + ( ( (FT_Offset)(i) >> 3 ) ^ ( (FT_Offset)(i) << 7 ) ) /* handle to cache object */ typedef struct FTC_CacheRec_* FTC_Cache; @@ -59,7 +59,7 @@ FT_BEGIN_HEADER { FTC_MruNodeRec mru; /* circular mru list pointer */ FTC_Node link; /* used for hashing */ - FT_PtrDist hash; /* used for hashing too */ + FT_Offset hash; /* used for hashing too */ FT_UShort cache_index; /* index of cache the node belongs to */ FT_Short ref_count; /* reference count for this node */ @@ -69,20 +69,20 @@ FT_BEGIN_HEADER #define FTC_NODE( x ) ( (FTC_Node)(x) ) #define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) -#define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next ) -#define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev ) +#define FTC_NODE_NEXT( x ) FTC_NODE( (x)->mru.next ) +#define FTC_NODE_PREV( x ) FTC_NODE( (x)->mru.prev ) #ifdef FTC_INLINE -#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ +#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \ ( ( cache )->buckets + \ ( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) \ ? ( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) \ : ( ( hash ) & ( cache )->mask ) ) ) #else FT_LOCAL( FTC_Node* ) - ftc_get_top_node_for_hash( FTC_Cache cache, - FT_PtrDist hash ); -#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ + ftc_get_top_node_for_hash( FTC_Cache cache, + FT_Offset hash ); +#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \ ftc_get_top_node_for_hash( ( cache ), ( hash ) ) #endif @@ -179,14 +179,14 @@ FT_BEGIN_HEADER #ifndef FTC_INLINE FT_LOCAL( FT_Error ) FTC_Cache_Lookup( FTC_Cache cache, - FT_PtrDist hash, + FT_Offset hash, FT_Pointer query, FTC_Node *anode ); #endif FT_LOCAL( FT_Error ) FTC_Cache_NewNode( FTC_Cache cache, - FT_PtrDist hash, + FT_Offset hash, FT_Pointer query, FTC_Node *anode ); @@ -211,7 +211,7 @@ FT_BEGIN_HEADER FT_BEGIN_STMNT \ FTC_Node *_bucket, *_pnode, _node; \ FTC_Cache _cache = FTC_CACHE(cache); \ - FT_PtrDist _hash = (FT_PtrDist)(hash); \ + FT_Offset _hash = (FT_Offset)(hash); \ FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ FT_Bool _list_changed = FALSE; \ \ @@ -220,7 +220,7 @@ FT_BEGIN_HEADER node = NULL; \ \ /* Go to the `top' node of the list sharing same masked hash */ \ - _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ + _bucket = _pnode = FTC_NODE_TOP_FOR_HASH( _cache, _hash ); \ \ /* Look up a node with identical hash and queried properties. */ \ /* NOTE: _nodcomp() may change the linked list to reduce memory. */ \ @@ -228,7 +228,7 @@ FT_BEGIN_HEADER { \ _node = *_pnode; \ if ( _node == NULL ) \ - goto _NewNode; \ + goto NewNode_; \ \ if ( _node->hash == _hash && \ _nodcomp( _node, query, _cache, &_list_changed ) ) \ @@ -240,7 +240,7 @@ FT_BEGIN_HEADER if ( _list_changed ) \ { \ /* Update _bucket by possibly modified linked list */ \ - _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ + _bucket = _pnode = FTC_NODE_TOP_FOR_HASH( _cache, _hash ); \ \ /* Update _pnode by possibly modified linked list */ \ while ( *_pnode != _node ) \ @@ -248,7 +248,7 @@ FT_BEGIN_HEADER if ( *_pnode == NULL ) \ { \ FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" )); \ - goto _NewNode; \ + goto NewNode_; \ } \ else \ _pnode = &((*_pnode)->link); \ @@ -273,12 +273,12 @@ FT_BEGIN_HEADER FTC_MruNode_Up( (FTC_MruNode*)_nl, \ (FTC_MruNode)_node ); \ } \ - goto _Ok; \ + goto Ok_; \ \ - _NewNode: \ + NewNode_: \ error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ \ - _Ok: \ + Ok_: \ node = _node; \ FT_END_STMNT @@ -325,7 +325,7 @@ FT_BEGIN_HEADER break; \ \ _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ - if ( _try_done > 0 && ( list_changed ) ) \ + if ( _try_done > 0 && ( list_changed != NULL ) ) \ *(FT_Bool*)( list_changed ) = TRUE; \ \ if ( _try_done == 0 ) \ @@ -346,7 +346,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCCACHE_H__ */ +#endif /* FTCCACHE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cache/ftccback.h b/drivers/freetype/src/cache/ftccback.h index 9528279273..279e94d923 100644 --- a/drivers/freetype/freetype/src/cache/ftccback.h +++ b/drivers/freetype/src/cache/ftccback.h @@ -4,7 +4,7 @@ /* */ /* Callback functions of the caching sub-system (specification only). */ /* */ -/* Copyright 2004-2006, 2011, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __FTCCBACK_H__ -#define __FTCCBACK_H__ +#ifndef FTCCBACK_H_ +#define FTCCBACK_H_ #include <ft2build.h> #include FT_CACHE_H @@ -86,6 +86,7 @@ FTC_Manager manager ); -#endif /* __FTCCBACK_H__ */ +#endif /* FTCCBACK_H_ */ + /* END */ diff --git a/drivers/freetype/freetype/src/cache/ftccmap.c b/drivers/freetype/src/cache/ftccmap.c index 848349be2d..41a0ce97dd 100644 --- a/drivers/freetype/freetype/src/cache/ftccmap.c +++ b/drivers/freetype/src/cache/ftccmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType CharMap cache (body) */ /* */ -/* Copyright 2000-2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,7 +50,7 @@ /* compute a query/node hash */ #define FTC_CMAP_HASH( faceid, index, charcode ) \ - ( _FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ + ( FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ ( (charcode) / FTC_CMAP_INDICES_MAX ) ) /* the charmap query */ @@ -63,8 +63,6 @@ } FTC_CMapQueryRec, *FTC_CMapQuery; #define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x)) -#define FTC_CMAP_QUERY_HASH( x ) \ - FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) /* the cmap cache node */ typedef struct FTC_CMapNodeRec_ @@ -78,8 +76,6 @@ } FTC_CMapNodeRec, *FTC_CMapNode; #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) -#define FTC_CMAP_NODE_HASH( x ) \ - FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ @@ -202,7 +198,7 @@ /*************************************************************************/ - FT_CALLBACK_TABLE_DEF + static const FTC_CacheClassRec ftc_cmap_cache_class = { ftc_cmap_node_new, @@ -242,7 +238,7 @@ FTC_Node node; FT_Error error; FT_UInt gindex = 0; - FT_PtrDist hash; + FT_Offset hash; FT_Int no_cmap_change = 0; @@ -267,7 +263,7 @@ query.cmap_index = (FT_UInt)cmap_index; query.char_code = char_code; - hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); + hash = FTC_CMAP_HASH( face_id, (FT_UInt)cmap_index, char_code ); #if 1 FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, @@ -301,12 +297,6 @@ if ( error ) goto Exit; -#ifdef FT_MAX_CHARMAP_CACHEABLE - /* something rotten can happen with rogue clients */ - if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE ) - return 0; /* XXX: should return appropriate error */ -#endif - if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) { FT_CharMap old, cmap = NULL; diff --git a/drivers/freetype/freetype/src/cache/ftcerror.h b/drivers/freetype/src/cache/ftcerror.h index 0e055709bb..1fd7357a8b 100644 --- a/drivers/freetype/freetype/src/cache/ftcerror.h +++ b/drivers/freetype/src/cache/ftcerror.h @@ -4,7 +4,7 @@ /* */ /* Caching sub-system error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __FTCERROR_H__ -#define __FTCERROR_H__ +#ifndef FTCERROR_H_ +#define FTCERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX FTC_Err_ @@ -36,6 +36,7 @@ #include FT_ERRORS_H -#endif /* __FTCERROR_H__ */ +#endif /* FTCERROR_H_ */ + /* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcglyph.c b/drivers/freetype/src/cache/ftcglyph.c index 441e177238..c4046812dd 100644 --- a/drivers/freetype/freetype/src/cache/ftcglyph.c +++ b/drivers/freetype/src/cache/ftcglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType Glyph Image (FT_Glyph) cache (body). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2009, 2011 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -106,7 +106,7 @@ FTC_Family_Init( FTC_Family family, FTC_Cache cache ) { - FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS( cache ); + FTC_GCacheClass clazz = FTC_CACHE_GCACHE_CLASS( cache ); family->clazz = clazz->family_class; @@ -185,7 +185,7 @@ FT_LOCAL_DEF( FT_Error ) FTC_GCache_Lookup( FTC_GCache cache, - FT_PtrDist hash, + FT_Offset hash, FT_UInt gindex, FTC_GQuery query, FTC_Node *anode ) diff --git a/drivers/freetype/freetype/src/cache/ftcglyph.h b/drivers/freetype/src/cache/ftcglyph.h index 5fed19cb8f..dc7be06f03 100644 --- a/drivers/freetype/freetype/src/cache/ftcglyph.h +++ b/drivers/freetype/src/cache/ftcglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType abstract glyph cache (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -113,8 +113,8 @@ /*************************************************************************/ -#ifndef __FTCGLYPH_H__ -#define __FTCGLYPH_H__ +#ifndef FTCGLYPH_H_ +#define FTCGLYPH_H_ #include <ft2build.h> @@ -245,10 +245,10 @@ FT_BEGIN_HEADER #define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(x)) -#define FTC_CACHE__GCACHE_CLASS( x ) \ +#define FTC_CACHE_GCACHE_CLASS( x ) \ FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) -#define FTC_CACHE__FAMILY_CLASS( x ) \ - ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class ) +#define FTC_CACHE_FAMILY_CLASS( x ) \ + ( (FTC_MruListClass)FTC_CACHE_GCACHE_CLASS( x )->family_class ) /* convenience function; use it instead of FTC_Manager_Register_Cache */ @@ -260,7 +260,7 @@ FT_BEGIN_HEADER #ifndef FTC_INLINE FT_LOCAL( FT_Error ) FTC_GCache_Lookup( FTC_GCache cache, - FT_PtrDist hash, + FT_Offset hash, FT_UInt gindex, FTC_GQuery query, FTC_Node *anode ); @@ -323,7 +323,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCGLYPH_H__ */ +#endif /* FTCGLYPH_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcimage.c b/drivers/freetype/src/cache/ftcimage.c index c242ece021..74040aa745 100644 --- a/drivers/freetype/freetype/src/cache/ftcimage.c +++ b/drivers/freetype/src/cache/ftcimage.c @@ -4,7 +4,7 @@ /* */ /* FreeType Image cache (body). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2010 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,7 @@ #include FT_CACHE_H #include "ftcimage.h" #include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_OBJECTS_H #include "ftccback.h" #include "ftcerror.h" @@ -69,7 +70,7 @@ FTC_GNode gnode = FTC_GNODE( inode ); FTC_Family family = gquery->family; FT_UInt gindex = gquery->gindex; - FTC_IFamilyClass clazz = FTC_CACHE__IFAMILY_CLASS( cache ); + FTC_IFamilyClass clazz = FTC_CACHE_IFAMILY_CLASS( cache ); /* initialize its inner fields */ @@ -122,7 +123,7 @@ bitg = (FT_BitmapGlyph)glyph; - size = bitg->bitmap.rows * ft_labs( bitg->bitmap.pitch ) + + size = bitg->bitmap.rows * (FT_Offset)FT_ABS( bitg->bitmap.pitch ) + sizeof ( *bitg ); } break; @@ -133,9 +134,9 @@ outg = (FT_OutlineGlyph)glyph; - size = outg->outline.n_points * + size = (FT_Offset)outg->outline.n_points * ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) + - outg->outline.n_contours * sizeof ( FT_Short ) + + (FT_Offset)outg->outline.n_contours * sizeof ( FT_Short ) + sizeof ( *outg ); } break; diff --git a/drivers/freetype/freetype/src/cache/ftcimage.h b/drivers/freetype/src/cache/ftcimage.h index 20d5d3e07d..25aa43b97e 100644 --- a/drivers/freetype/freetype/src/cache/ftcimage.h +++ b/drivers/freetype/src/cache/ftcimage.h @@ -4,7 +4,7 @@ /* */ /* FreeType Generic Image cache (specification) */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2006 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,8 +32,8 @@ /*************************************************************************/ -#ifndef __FTCIMAGE_H__ -#define __FTCIMAGE_H__ +#ifndef FTCIMAGE_H_ +#define FTCIMAGE_H_ #include <ft2build.h> @@ -72,8 +72,8 @@ FT_BEGIN_HEADER #define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x)) -#define FTC_CACHE__IFAMILY_CLASS( x ) \ - FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class ) +#define FTC_CACHE_IFAMILY_CLASS( x ) \ + FTC_IFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS(x)->family_class ) /* can be used as a @FTC_Node_FreeFunc */ @@ -101,7 +101,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCIMAGE_H__ */ +#endif /* FTCIMAGE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcmanag.c b/drivers/freetype/src/cache/ftcmanag.c index 4eb2c5bfd6..661a32af5b 100644 --- a/drivers/freetype/freetype/src/cache/ftcmanag.c +++ b/drivers/freetype/src/cache/ftcmanag.c @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (body). */ /* */ -/* Copyright 2000-2006, 2008-2010, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,8 +34,6 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_cache -#define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data ) - static FT_Error ftc_scaler_lookup_size( FTC_Manager manager, @@ -60,8 +58,11 @@ if ( scaler->pixel ) error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height ); else - error = FT_Set_Char_Size( face, scaler->width, scaler->height, - scaler->x_res, scaler->y_res ); + error = FT_Set_Char_Size( face, + (FT_F26Dot6)scaler->width, + (FT_F26Dot6)scaler->height, + scaler->x_res, + scaler->y_res ); if ( error ) { FT_Done_Size( size ); @@ -151,7 +152,7 @@ } - FT_CALLBACK_TABLE_DEF + static const FTC_MruListClassRec ftc_size_list_class = { sizeof ( FTC_SizeNodeRec ), @@ -186,7 +187,7 @@ FTC_MruNode mrunode; - if ( asize == NULL ) + if ( !asize || !scaler ) return FT_THROW( Invalid_Argument ); *asize = NULL; @@ -290,7 +291,7 @@ } - FT_CALLBACK_TABLE_DEF + static const FTC_MruListClassRec ftc_face_list_class = { sizeof ( FTC_FaceNodeRec), @@ -313,7 +314,7 @@ FTC_MruNode mrunode; - if ( aface == NULL ) + if ( !aface ) return FT_THROW( Invalid_Argument ); *aface = NULL; @@ -366,6 +367,9 @@ if ( !library ) return FT_THROW( Invalid_Library_Handle ); + if ( !amanager || !requester ) + return FT_THROW( Invalid_Argument ); + memory = library->memory; if ( FT_NEW( manager ) ) @@ -451,11 +455,11 @@ FT_EXPORT_DEF( void ) FTC_Manager_Reset( FTC_Manager manager ) { - if ( manager ) - { - FTC_MruList_Reset( &manager->sizes ); - FTC_MruList_Reset( &manager->faces ); - } + if ( !manager ) + return; + + FTC_MruList_Reset( &manager->sizes ); + FTC_MruList_Reset( &manager->faces ); FTC_Manager_FlushN( manager, manager->num_nodes ); } @@ -490,7 +494,7 @@ else weight += cache->clazz.node_weight( node, cache ); - node = FTC_NODE__NEXT( node ); + node = FTC_NODE_NEXT( node ); } while ( node != first ); @@ -509,7 +513,7 @@ do { count++; - node = FTC_NODE__NEXT( node ); + node = FTC_NODE_NEXT( node ); } while ( node != first ); @@ -552,13 +556,13 @@ return; /* go to last node -- it's a circular list */ - node = FTC_NODE__PREV( first ); + node = FTC_NODE_PREV( first ); do { FTC_Node prev; - prev = ( node == first ) ? NULL : FTC_NODE__PREV( node ); + prev = ( node == first ) ? NULL : FTC_NODE_PREV( node ); if ( node->ref_count <= 0 ) ftc_node_destroy( node, manager ); @@ -637,10 +641,10 @@ return 0; /* go to last node - it's a circular list */ - node = FTC_NODE__PREV(first); + node = FTC_NODE_PREV(first); for ( result = 0; result < count; ) { - FTC_Node prev = FTC_NODE__PREV( node ); + FTC_Node prev = FTC_NODE_PREV( node ); /* don't touch locked nodes */ @@ -667,6 +671,10 @@ { FT_UInt nn; + + if ( !manager ) + return; + /* this will remove all FTC_SizeNode that correspond to * the face_id as well */ @@ -685,7 +693,9 @@ FTC_Node_Unref( FTC_Node node, FTC_Manager manager ) { - if ( node && (FT_UInt)node->cache_index < manager->num_caches ) + if ( node && + manager && + (FT_UInt)node->cache_index < manager->num_caches ) node->ref_count--; } diff --git a/drivers/freetype/freetype/src/cache/ftcmanag.h b/drivers/freetype/src/cache/ftcmanag.h index 0aec33c584..f2c434a135 100644 --- a/drivers/freetype/freetype/src/cache/ftcmanag.h +++ b/drivers/freetype/src/cache/ftcmanag.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2010, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -59,8 +59,8 @@ /*************************************************************************/ -#ifndef __FTCMANAG_H__ -#define __FTCMANAG_H__ +#ifndef FTCMANAG_H_ +#define FTCMANAG_H_ #include <ft2build.h> @@ -161,7 +161,7 @@ FT_BEGIN_HEADER (a)->y_res == (b)->y_res ) ) ) #define FTC_SCALER_HASH( q ) \ - ( _FTC_FACE_ID_HASH( (q)->face_id ) + \ + ( FTC_FACE_ID_HASH( (q)->face_id ) + \ (q)->width + (q)->height*7 + \ ( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) ) @@ -169,7 +169,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCMANAG_H__ */ +#endif /* FTCMANAG_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcmru.c b/drivers/freetype/src/cache/ftcmru.c index dc8b4cc397..d107584a19 100644 --- a/drivers/freetype/freetype/src/cache/ftcmru.c +++ b/drivers/freetype/src/cache/ftcmru.c @@ -4,7 +4,7 @@ /* */ /* FreeType MRU support (body). */ /* */ -/* Copyright 2003, 2004, 2006, 2009 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/cache/ftcmru.h b/drivers/freetype/src/cache/ftcmru.h index 6fccf11781..ae3c4ce23a 100644 --- a/drivers/freetype/freetype/src/cache/ftcmru.h +++ b/drivers/freetype/src/cache/ftcmru.h @@ -4,7 +4,7 @@ /* */ /* Simple MRU list-cache (specification). */ /* */ -/* Copyright 2000-2001, 2003-2006, 2010, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -40,8 +40,8 @@ /*************************************************************************/ -#ifndef __FTCMRU_H__ -#define __FTCMRU_H__ +#ifndef FTCMRU_H_ +#define FTCMRU_H_ #include <ft2build.h> @@ -181,15 +181,15 @@ FT_BEGIN_HEADER FTC_MruNode_Up( _pfirst, _node ); \ \ node = _node; \ - goto _MruOk; \ + goto MruOk_; \ } \ _node = _node->next; \ \ - } while ( _node != _first) ; \ + } while ( _node != _first); \ } \ \ error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \ - _MruOk: \ + MruOk_: \ ; \ FT_END_STMNT @@ -240,7 +240,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCMRU_H__ */ +#endif /* FTCMRU_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cache/ftcsbits.c b/drivers/freetype/src/cache/ftcsbits.c index 6df1c19930..d6f1ddcd4e 100644 --- a/drivers/freetype/freetype/src/cache/ftcsbits.c +++ b/drivers/freetype/src/cache/ftcsbits.c @@ -4,7 +4,7 @@ /* */ /* FreeType sbits manager (body). */ /* */ -/* Copyright 2000-2006, 2009-2011, 2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,7 +52,9 @@ if ( pitch < 0 ) pitch = -pitch; - size = (FT_ULong)( pitch * bitmap->rows ); + size = (FT_ULong)pitch * bitmap->rows; + if ( !size ) + return FT_Err_Ok; if ( !FT_ALLOC( sbit->buffer, size ) ) FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); @@ -142,12 +144,12 @@ goto BadGlyph; } - /* Check that our values fit into 8-bit containers! */ + /* Check whether our values fit into 8-bit containers! */ /* If this is not the case, our bitmap is too large */ /* and we will leave it as `missing' with sbit.buffer = 0 */ -#define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) -#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) +#define CHECK_CHAR( d ) ( temp = (FT_Char)d, (FT_Int) temp == (FT_Int) d ) +#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, (FT_UInt)temp == (FT_UInt)d ) /* horizontal advance in pixels */ xadvance = ( slot->advance.x + 32 ) >> 6; @@ -181,7 +183,7 @@ /* now, compute size */ if ( asize ) - *asize = FT_ABS( sbit->pitch ) * sbit->height; + *asize = (FT_ULong)FT_ABS( sbit->pitch ) * sbit->height; } /* glyph loading successful */ @@ -215,7 +217,7 @@ FT_UInt gindex = gquery->gindex; FTC_Family family = gquery->family; - FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); + FTC_SFamilyClass clazz = FTC_CACHE_SFAMILY_CLASS( cache ); FT_UInt total; FT_UInt node_count; @@ -302,7 +304,7 @@ pitch = -pitch; /* add the size of a given glyph image */ - size += pitch * sbit->height; + size += (FT_Offset)pitch * sbit->height; } } diff --git a/drivers/freetype/freetype/src/cache/ftcsbits.h b/drivers/freetype/src/cache/ftcsbits.h index df55dca806..a0600ede09 100644 --- a/drivers/freetype/freetype/src/cache/ftcsbits.h +++ b/drivers/freetype/src/cache/ftcsbits.h @@ -4,7 +4,7 @@ /* */ /* A small-bitmap cache (specification). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2006, 2011 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCSBITS_H__ -#define __FTCSBITS_H__ +#ifndef FTCSBITS_H_ +#define FTCSBITS_H_ #include <ft2build.h> @@ -64,8 +64,8 @@ FT_BEGIN_HEADER #define FTC_SFAMILY_CLASS( x ) ((FTC_SFamilyClass)(x)) -#define FTC_CACHE__SFAMILY_CLASS( x ) \ - FTC_SFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS( x )->family_class ) +#define FTC_CACHE_SFAMILY_CLASS( x ) \ + FTC_SFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS( x )->family_class ) FT_LOCAL( void ) @@ -97,7 +97,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCSBITS_H__ */ +#endif /* FTCSBITS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cache/rules.mk b/drivers/freetype/src/cache/rules.mk index ed75a6a91f..827e259f90 100644 --- a/drivers/freetype/freetype/src/cache/rules.mk +++ b/drivers/freetype/src/cache/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2000, 2001, 2003, 2004, 2006, 2008 by +# Copyright 2000-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,9 +17,13 @@ # CACHE_DIR := $(SRC_DIR)/cache + # compilation flags for the driver # -CACHE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CACHE_DIR)) +CACHE_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(CACHE_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # Cache driver sources (i.e., C files) @@ -33,6 +37,7 @@ CACHE_DRV_SRC := $(CACHE_DIR)/ftcbasic.c \ $(CACHE_DIR)/ftcmru.c \ $(CACHE_DIR)/ftcsbits.c + # Cache driver headers # CACHE_DRV_H := $(CACHE_DIR)/ftccache.h \ diff --git a/drivers/freetype/freetype/src/cff/Jamfile b/drivers/freetype/src/cff/Jamfile index 6705d3cfdb..8067e6b29c 100644 --- a/drivers/freetype/freetype/src/cff/Jamfile +++ b/drivers/freetype/src/cff/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/cff Jamfile # -# Copyright 2001, 2002 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,23 @@ SubDir FT2_TOP $(FT2_SRC_DIR) cff ; if $(FT2_MULTI) { - _sources = cffdrivr cffgload cffload cffobjs cffparse cffcmap cffpic ; + _sources = cffcmap + cffdrivr + cffgload + cffload + cffobjs + cffparse + cffpic + cf2arrst + cf2blues + cf2error + cf2font + cf2ft + cf2hints + cf2intrp + cf2read + cf2stack + ; } else { diff --git a/drivers/freetype/freetype/src/cff/cf2arrst.c b/drivers/freetype/src/cff/cf2arrst.c index c8d6f13098..89f3e9f1d7 100644 --- a/drivers/freetype/freetype/src/cff/cf2arrst.c +++ b/drivers/freetype/src/cff/cf2arrst.c @@ -101,10 +101,10 @@ FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ FT_Memory memory = arrstack->memory; /* for FT_REALLOC */ - FT_Long newSize = (FT_Long)( numElements * arrstack->sizeItem ); + size_t newSize = numElements * arrstack->sizeItem; - if ( numElements > LONG_MAX / arrstack->sizeItem ) + if ( numElements > FT_LONG_MAX / arrstack->sizeItem ) goto exit; diff --git a/drivers/freetype/freetype/src/cff/cf2arrst.h b/drivers/freetype/src/cff/cf2arrst.h index ff5ad8b126..3c21a3b672 100644 --- a/drivers/freetype/freetype/src/cff/cf2arrst.h +++ b/drivers/freetype/src/cff/cf2arrst.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2ARRST_H__ -#define __CF2ARRST_H__ +#ifndef CF2ARRST_H_ +#define CF2ARRST_H_ #include "cf2error.h" @@ -94,7 +94,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2ARRST_H__ */ +#endif /* CF2ARRST_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2blues.c b/drivers/freetype/src/cff/cf2blues.c index 5b348398af..250f89e0df 100644 --- a/drivers/freetype/freetype/src/cff/cf2blues.c +++ b/drivers/freetype/src/cff/cf2blues.c @@ -4,7 +4,7 @@ /* */ /* Adobe's code for handling Blue Zones (body). */ /* */ -/* Copyright 2009-2013 Adobe Systems Incorporated. */ +/* Copyright 2009-2014 Adobe Systems Incorporated. */ /* */ /* This software, and all works of authorship, whether in source or */ /* object code form as indicated by the copyright notice(s) included */ @@ -86,11 +86,13 @@ size_t i; CF2_Fixed emBoxBottom, emBoxTop; +#if 0 CF2_Int unitsPerEm = font->unitsPerEm; if ( unitsPerEm == 0 ) unitsPerEm = 1000; +#endif FT_ZERO( blues ); blues->scale = font->innerTransform.d; @@ -406,11 +408,10 @@ /* Note: constant changed from 0.5 to 0.6 to avoid a problem with */ /* 10ppem Arial */ - blues->boost = FT_MulFix( - cf2_floatToFixed( .6 ), - ( cf2_intToFixed( 1 ) - - FT_DivFix( blues->scale, - blues->blueScale ) ) ); + blues->boost = cf2_floatToFixed( .6 ) - + FT_MulDiv( cf2_floatToFixed ( .6 ), + blues->scale, + blues->blueScale ); if ( blues->boost > 0x7FFF ) { /* boost must remain less than 0.5, or baseline could go negative */ diff --git a/drivers/freetype/freetype/src/cff/cf2blues.h b/drivers/freetype/src/cff/cf2blues.h index 2f38fcad8f..96fb60f38d 100644 --- a/drivers/freetype/freetype/src/cff/cf2blues.h +++ b/drivers/freetype/src/cff/cf2blues.h @@ -65,8 +65,8 @@ */ -#ifndef __CF2BLUES_H__ -#define __CF2BLUES_H__ +#ifndef CF2BLUES_H_ +#define CF2BLUES_H_ #include "cf2glue.h" @@ -179,7 +179,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2BLUES_H__ */ +#endif /* CF2BLUES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2error.c b/drivers/freetype/src/cff/cf2error.c index b5595a3d1f..b5595a3d1f 100644 --- a/drivers/freetype/freetype/src/cff/cf2error.c +++ b/drivers/freetype/src/cff/cf2error.c diff --git a/drivers/freetype/freetype/src/cff/cf2error.h b/drivers/freetype/src/cff/cf2error.h index 6453ebcb7b..512edd1d21 100644 --- a/drivers/freetype/freetype/src/cff/cf2error.h +++ b/drivers/freetype/src/cff/cf2error.h @@ -36,13 +36,13 @@ /***************************************************************************/ -#ifndef __CF2ERROR_H__ -#define __CF2ERROR_H__ +#ifndef CF2ERROR_H_ +#define CF2ERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CF2_Err_ @@ -70,7 +70,7 @@ FT_BEGIN_HEADER * Upon a function call if the error code is anything other than * `FT_Err_Ok', which is guaranteed to be zero, we * will return without altering that error. This will allow the - * error to propogate and be handled at the appropriate location in + * error to propagate and be handled at the appropriate location in * the code. * * This allows a style of code where the error code is initialized @@ -113,7 +113,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2ERROR_H__ */ +#endif /* CF2ERROR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2fixed.h b/drivers/freetype/src/cff/cf2fixed.h index ed1452a7da..74af37708b 100644 --- a/drivers/freetype/freetype/src/cff/cf2fixed.h +++ b/drivers/freetype/src/cff/cf2fixed.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2FIXED_H__ -#define __CF2FIXED_H__ +#ifndef CF2FIXED_H_ +#define CF2FIXED_H_ FT_BEGIN_HEADER @@ -57,22 +57,22 @@ FT_BEGIN_HEADER /* in C 89, left and right shift of negative numbers is */ /* implementation specific behaviour in the general case */ -#define cf2_intToFixed( i ) \ +#define cf2_intToFixed( i ) \ ( (CF2_Fixed)( (FT_UInt32)(i) << 16 ) ) -#define cf2_fixedToInt( x ) \ +#define cf2_fixedToInt( x ) \ ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) -#define cf2_fixedRound( x ) \ - ( (CF2_Fixed)( ( (x) + 0x8000 ) & 0xFFFF0000L ) ) -#define cf2_floatToFixed( f ) \ +#define cf2_fixedRound( x ) \ + ( (CF2_Fixed)( ( (FT_UInt32)(x) + 0x8000U ) & 0xFFFF0000UL ) ) +#define cf2_floatToFixed( f ) \ ( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) ) -#define cf2_fixedAbs( x ) \ +#define cf2_fixedAbs( x ) \ ( (x) < 0 ? -(x) : (x) ) -#define cf2_fixedFloor( x ) \ - ( (CF2_Fixed)( (x) & 0xFFFF0000L ) ) -#define cf2_fixedFraction( x ) \ +#define cf2_fixedFloor( x ) \ + ( (CF2_Fixed)( (FT_UInt32)(x) & 0xFFFF0000UL ) ) +#define cf2_fixedFraction( x ) \ ( (x) - cf2_fixedFloor( x ) ) -#define cf2_fracToFixed( x ) \ - ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 ) \ +#define cf2_fracToFixed( x ) \ + ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 ) \ : ( ( (x) + 0x2000 ) >> 14 ) ) @@ -89,7 +89,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2FIXED_H__ */ +#endif /* CF2FIXED_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2font.c b/drivers/freetype/src/cff/cf2font.c index 479d9125d1..83fd348f2d 100644 --- a/drivers/freetype/freetype/src/cff/cf2font.c +++ b/drivers/freetype/src/cff/cf2font.c @@ -4,7 +4,7 @@ /* */ /* Adobe's code for font instances (body). */ /* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* Copyright 2007-2014 Adobe Systems Incorporated. */ /* */ /* This software, and all works of authorship, whether in source or */ /* object code form as indicated by the copyright notice(s) included */ @@ -36,6 +36,9 @@ /***************************************************************************/ +#include <ft2build.h> +#include FT_INTERNAL_CALC_H + #include "cf2ft.h" #include "cf2glue.h" @@ -51,11 +54,61 @@ CF2_Fixed stemWidth, CF2_Fixed* darkenAmount, CF2_Fixed boldenAmount, - FT_Bool stemDarkened ) + FT_Bool stemDarkened, + FT_Int* darkenParams ) { + /* + * Total darkening amount is computed in 1000 unit character space + * using the modified 5 part curve as Adobe's Avalon rasterizer. + * The darkening amount is smaller for thicker stems. + * It becomes zero when the stem is thicker than 2.333 pixels. + * + * By default, we use + * + * darkenAmount = 0.4 pixels if scaledStem <= 0.5 pixels, + * darkenAmount = 0.275 pixels if 1 <= scaledStem <= 1.667 pixels, + * darkenAmount = 0 pixel if scaledStem >= 2.333 pixels, + * + * and piecewise linear in-between: + * + * + * darkening + * ^ + * | + * | (x1,y1) + * |--------+ + * | \ + * | \ + * | \ (x3,y3) + * | +----------+ + * | (x2,y2) \ + * | \ + * | \ + * | +----------------- + * | (x4,y4) + * +---------------------------------------------> stem + * thickness + * + * + * This corresponds to the following values for the + * `darkening-parameters' property: + * + * (x1, y1) = (500, 400) + * (x2, y2) = (1000, 275) + * (x3, y3) = (1667, 275) + * (x4, y4) = (2333, 0) + * + */ + /* Internal calculations are done in units per thousand for */ - /* convenience. */ + /* convenience. The x axis is scaled stem width in */ + /* thousandths of a pixel. That is, 1000 is 1 pixel. */ + /* The y axis is darkening amount in thousandths of a pixel.*/ + /* In the code, below, dividing by ppem and */ + /* adjusting for emRatio converts darkenAmount to character */ + /* space (font units). */ CF2_Fixed stemWidthPer1000, scaledStem; + FT_Int logBase2; *darkenAmount = 0; @@ -69,59 +122,107 @@ if ( stemDarkened ) { + FT_Int x1 = darkenParams[0]; + FT_Int y1 = darkenParams[1]; + FT_Int x2 = darkenParams[2]; + FT_Int y2 = darkenParams[3]; + FT_Int x3 = darkenParams[4]; + FT_Int y3 = darkenParams[5]; + FT_Int x4 = darkenParams[6]; + FT_Int y4 = darkenParams[7]; + + /* convert from true character space to 1000 unit character space; */ /* add synthetic emboldening effect */ - /* we have to assure that the computation of `scaledStem' */ - /* and `stemWidthPer1000' don't overflow */ + /* `stemWidthPer1000' will not overflow for a legitimate font */ stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio ); - if ( emRatio > CF2_FIXED_ONE && - stemWidthPer1000 <= ( stemWidth + boldenAmount ) ) + /* `scaledStem' can easily overflow, so we must clamp its maximum */ + /* value; the test doesn't need to be precise, but must be */ + /* conservative. The clamp value (default 2333) where */ + /* `darkenAmount' is zero is well below the overflow value of */ + /* 32767. */ + /* */ + /* FT_MSB computes the integer part of the base 2 logarithm. The */ + /* number of bits for the product is 1 or 2 more than the sum of */ + /* logarithms; remembering that the 16 lowest bits of the fraction */ + /* are dropped this is correct to within a factor of almost 4. */ + /* For example, 0x80.0000 * 0x80.0000 = 0x4000.0000 is 23+23 and */ + /* is flagged as possible overflow because 0xFF.FFFF * 0xFF.FFFF = */ + /* 0xFFFF.FE00 is also 23+23. */ + + logBase2 = FT_MSB( (FT_UInt32)stemWidthPer1000 ) + + FT_MSB( (FT_UInt32)ppem ); + + if ( logBase2 >= 46 ) + /* possible overflow */ + scaledStem = cf2_intToFixed( x4 ); + else + scaledStem = FT_MulFix( stemWidthPer1000, ppem ); + + /* now apply the darkening parameters */ + + if ( scaledStem < cf2_intToFixed( x1 ) ) + *darkenAmount = FT_DivFix( cf2_intToFixed( y1 ), ppem ); + + else if ( scaledStem < cf2_intToFixed( x2 ) ) { - stemWidthPer1000 = 0; /* to pacify compiler */ - scaledStem = cf2_intToFixed( 2333 ); + FT_Int xdelta = x2 - x1; + FT_Int ydelta = y2 - y1; + FT_Int x = stemWidthPer1000 - + FT_DivFix( cf2_intToFixed( x1 ), ppem ); + + + if ( !xdelta ) + goto Try_x3; + + *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( cf2_intToFixed( y1 ), ppem ); } - else + + else if ( scaledStem < cf2_intToFixed( x3 ) ) { - scaledStem = FT_MulFix( stemWidthPer1000, ppem ); + Try_x3: + { + FT_Int xdelta = x3 - x2; + FT_Int ydelta = y3 - y2; + FT_Int x = stemWidthPer1000 - + FT_DivFix( cf2_intToFixed( x2 ), ppem ); + + + if ( !xdelta ) + goto Try_x4; + + *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( cf2_intToFixed( y2 ), ppem ); + } + } - if ( ppem > CF2_FIXED_ONE && - scaledStem <= stemWidthPer1000 ) - scaledStem = cf2_intToFixed( 2333 ); + else if ( scaledStem < cf2_intToFixed( x4 ) ) + { + Try_x4: + { + FT_Int xdelta = x4 - x3; + FT_Int ydelta = y4 - y3; + FT_Int x = stemWidthPer1000 - + FT_DivFix( cf2_intToFixed( x3 ), ppem ); + + + if ( !xdelta ) + goto Use_y4; + + *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( cf2_intToFixed( y3 ), ppem ); + } } - /* - * Total darkening amount is computed in 1000 unit character space - * using the modified 5 part curve as Avalon rasterizer. - * The darkening amount is smaller for thicker stems. - * It becomes zero when the stem is thicker than 2.333 pixels. - * - * In Avalon rasterizer, - * - * darkenAmount = 0.5 pixels if scaledStem <= 0.5 pixels, - * darkenAmount = 0.333 pixels if 1 <= scaledStem <= 1.667 pixels, - * darkenAmount = 0 pixel if scaledStem >= 2.333 pixels, - * - * and piecewise linear in-between. - * - */ - if ( scaledStem < cf2_intToFixed( 500 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 400 ), ppem ); - - else if ( scaledStem < cf2_intToFixed( 1000 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 525 ), ppem ) - - FT_MulFix( stemWidthPer1000, - cf2_floatToFixed( .25 ) ); - - else if ( scaledStem < cf2_intToFixed( 1667 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 275 ), ppem ); - - else if ( scaledStem < cf2_intToFixed( 2333 ) ) - *darkenAmount = FT_DivFix( cf2_intToFixed( 963 ), ppem ) - - FT_MulFix( stemWidthPer1000, - cf2_floatToFixed( .413 ) ); + else + { + Use_y4: + *darkenAmount = FT_DivFix( cf2_intToFixed( y4 ), ppem ); + } /* use half the amount on each side and convert back to true */ /* character space */ @@ -143,13 +244,14 @@ /* pointer to parsed font object */ CFF_Decoder* decoder = font->decoder; - FT_Bool needExtraSetup; + FT_Bool needExtraSetup = FALSE; /* character space units */ CF2_Fixed boldenX = font->syntheticEmboldeningAmountX; CF2_Fixed boldenY = font->syntheticEmboldeningAmountY; - CF2_Fixed ppem; + CFF_SubFont subFont; + CF2_Fixed ppem; /* clear previous error */ @@ -157,8 +259,12 @@ /* if a CID fontDict has changed, we need to recompute some cached */ /* data */ - needExtraSetup = - (FT_Bool)( font->lastSubfont != cf2_getSubfont( decoder ) ); + subFont = cf2_getSubfont( decoder ); + if ( font->lastSubfont != subFont ) + { + font->lastSubfont = subFont; + needExtraSetup = TRUE; + } /* if ppem has changed, we need to recompute some cached data */ /* note: because of CID font matrix concatenation, ppem and transform */ @@ -268,7 +374,8 @@ font->stdVW, &font->darkenX, boldenX, - FALSE ); + FALSE, + font->darkenParams ); } else cf2_computeDarkening( emRatio, @@ -276,7 +383,8 @@ font->stdVW, &font->darkenX, 0, - font->stemDarkened ); + font->stemDarkened, + font->darkenParams ); #if 0 /* since hstem is measured in the y-direction, we use the `d' member */ @@ -303,7 +411,8 @@ font->stdHW, &font->darkenY, boldenY, - font->stemDarkened ); + font->stemDarkened, + font->darkenParams ); if ( font->darkenX != 0 || font->darkenY != 0 ) font->darkened = TRUE; diff --git a/drivers/freetype/freetype/src/cff/cf2font.h b/drivers/freetype/src/cff/cf2font.h index f9dd1bbd40..bd05e69e7b 100644 --- a/drivers/freetype/freetype/src/cff/cf2font.h +++ b/drivers/freetype/src/cff/cf2font.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2FONT_H__ -#define __CF2FONT_H__ +#ifndef CF2FONT_H_ +#define CF2FONT_H_ #include "cf2ft.h" @@ -48,7 +48,13 @@ FT_BEGIN_HEADER #define CF2_OPERAND_STACK_SIZE 48 -#define CF2_MAX_SUBR 10 /* maximum subroutine nesting */ +#define CF2_MAX_SUBR 16 /* maximum subroutine nesting; */ + /* only 10 are allowed but there exist */ + /* fonts like `HiraKakuProN-W3.ttf' */ + /* (Hiragino Kaku Gothic ProN W3; */ + /* 8.2d6e1; 2014-12-19) that exceed */ + /* this limit */ +#define CF2_STORAGE_SIZE 32 /* typedef is in `cf2glue.h' */ @@ -85,6 +91,8 @@ FT_BEGIN_HEADER /* i.e. darkenX != 0 || darkenY != 0 */ FT_Bool stemDarkened; + FT_Int darkenParams[8]; /* 1000 unit character space */ + /* variables that depend on both FontDict and Transform */ CF2_Fixed stdVW; /* in character space; depends on dict entry */ CF2_Fixed stdHW; /* in character space; depends on dict entry */ @@ -108,7 +116,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2FONT_H__ */ +#endif /* CF2FONT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2ft.c b/drivers/freetype/src/cff/cf2ft.c index c09a0244a8..55f3206ac2 100644 --- a/drivers/freetype/freetype/src/cff/cf2ft.c +++ b/drivers/freetype/src/cff/cf2ft.c @@ -4,7 +4,7 @@ /* */ /* FreeType Glue Component to Adobe's Interpreter (body). */ /* */ -/* Copyright 2013 Adobe Systems Incorporated. */ +/* Copyright 2013-2014 Adobe Systems Incorporated. */ /* */ /* This software, and all works of authorship, whether in source or */ /* object code form as indicated by the copyright notice(s) included */ @@ -61,7 +61,9 @@ FT_ASSERT( unitsPerEm > 0 ); - FT_ASSERT( transform->a > 0 && transform->d > 0 ); + if ( transform->a <= 0 || transform->d <= 0 ) + return FT_THROW( Invalid_Size_Handle ); + FT_ASSERT( transform->b == 0 && transform->c == 0 ); FT_ASSERT( transform->tx == 0 && transform->ty == 0 ); @@ -140,6 +142,8 @@ cf2_builder_lineTo( CF2_OutlineCallbacks callbacks, const CF2_CallbackParams params ) { + FT_Error error; + /* downcast the object pointer */ CF2_Outline outline = (CF2_Outline)callbacks; CFF_Builder* builder; @@ -154,15 +158,27 @@ { /* record the move before the line; also check points and set */ /* `path_begun' */ - cff_builder_start_point( builder, - params->pt0.x, - params->pt0.y ); + error = cff_builder_start_point( builder, + params->pt0.x, + params->pt0.y ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } } /* `cff_builder_add_point1' includes a check_points call for one point */ - cff_builder_add_point1( builder, - params->pt1.x, - params->pt1.y ); + error = cff_builder_add_point1( builder, + params->pt1.x, + params->pt1.y ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } } @@ -170,6 +186,8 @@ cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks, const CF2_CallbackParams params ) { + FT_Error error; + /* downcast the object pointer */ CF2_Outline outline = (CF2_Outline)callbacks; CFF_Builder* builder; @@ -184,13 +202,25 @@ { /* record the move before the line; also check points and set */ /* `path_begun' */ - cff_builder_start_point( builder, - params->pt0.x, - params->pt0.y ); + error = cff_builder_start_point( builder, + params->pt0.x, + params->pt0.y ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } } /* prepare room for 3 points: 2 off-curve, 1 on-curve */ - cff_check_points( builder, 3 ); + error = cff_check_points( builder, 3 ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } cff_builder_add_point( builder, params->pt1.x, @@ -236,10 +266,8 @@ if ( *hinted ) { - *x_scale = FT_DivFix( decoder->builder.glyph->x_scale, - cf2_intToFixed( 64 ) ); - *y_scale = FT_DivFix( decoder->builder.glyph->y_scale, - cf2_intToFixed( 64 ) ); + *x_scale = ( decoder->builder.glyph->x_scale + 32 ) / 64; + *y_scale = ( decoder->builder.glyph->y_scale + 32 ) / 64; } else { @@ -344,13 +372,25 @@ if ( scaled && !driver->no_stem_darkening ) font->renderingFlags |= CF2_FlagsDarkened; + font->darkenParams[0] = driver->darken_params[0]; + font->darkenParams[1] = driver->darken_params[1]; + font->darkenParams[2] = driver->darken_params[2]; + font->darkenParams[3] = driver->darken_params[3]; + font->darkenParams[4] = driver->darken_params[4]; + font->darkenParams[5] = driver->darken_params[5]; + font->darkenParams[6] = driver->darken_params[6]; + font->darkenParams[7] = driver->darken_params[7]; + /* now get an outline for this glyph; */ /* also get units per em to validate scale */ font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder ); - error2 = cf2_checkTransform( &transform, font->unitsPerEm ); - if ( error2 ) - return error2; + if ( scaled ) + { + error2 = cf2_checkTransform( &transform, font->unitsPerEm ); + if ( error2 ) + return error2; + } error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth ); if ( error2 ) @@ -380,8 +420,16 @@ FT_ASSERT( decoder && decoder->builder.face && decoder->builder.face->root.size ); - FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem ); + /* + * Note that `y_ppem' can be zero if there wasn't a call to + * `FT_Set_Char_Size' or something similar. However, this isn't a + * problem since we come to this place in the code only if + * FT_LOAD_NO_SCALE is set (the other case gets caught by + * `cf2_checkTransform'). The ppem value is needed to compute the stem + * darkening, which is disabled for getting the unscaled outline. + * + */ return cf2_intToFixed( decoder->builder.face->root.size->metrics.y_ppem ); } @@ -496,17 +544,22 @@ /* return 0 on success */ FT_LOCAL_DEF( CF2_Int ) cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ) { - FT_ASSERT( decoder && decoder->globals ); + CF2_UInt idx; + + + FT_ASSERT( decoder ); FT_ZERO( buf ); - idx += decoder->globals_bias; + idx = (CF2_UInt)( subrNum + decoder->globals_bias ); if ( idx >= decoder->num_globals ) return TRUE; /* error */ + FT_ASSERT( decoder->globals ); + buf->start = buf->ptr = decoder->globals[idx]; buf->end = decoder->globals[idx + 1]; @@ -519,7 +572,7 @@ /* used for seac component */ FT_LOCAL_DEF( FT_Error ) cf2_getSeacComponent( CFF_Decoder* decoder, - CF2_UInt code, + CF2_Int code, CF2_Buffer buf ) { CF2_Int gid; @@ -532,12 +585,21 @@ FT_ZERO( buf ); - gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code ); - if ( gid < 0 ) - return FT_THROW( Invalid_Glyph_Format ); +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Incremental fonts don't necessarily have valid charsets. */ + /* They use the character code, not the glyph index, in this case. */ + if ( decoder->builder.face->root.internal->incremental_interface ) + gid = code; + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code ); + if ( gid < 0 ) + return FT_THROW( Invalid_Glyph_Format ); + } error = cff_get_glyph_data( decoder->builder.face, - gid, + (CF2_UInt)gid, &charstring, &len ); /* TODO: for now, just pass the FreeType error through */ @@ -569,17 +631,22 @@ FT_LOCAL_DEF( CF2_Int ) cf2_initLocalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ) { - FT_ASSERT( decoder && decoder->locals ); + CF2_UInt idx; + + + FT_ASSERT( decoder ); FT_ZERO( buf ); - idx += decoder->locals_bias; + idx = (CF2_UInt)( subrNum + decoder->locals_bias ); if ( idx >= decoder->num_locals ) return TRUE; /* error */ + FT_ASSERT( decoder->locals ); + buf->start = buf->ptr = decoder->locals[idx]; buf->end = decoder->locals[idx + 1]; diff --git a/drivers/freetype/freetype/src/cff/cf2ft.h b/drivers/freetype/src/cff/cf2ft.h index 731da3ca8c..8e55e841a0 100644 --- a/drivers/freetype/freetype/src/cff/cf2ft.h +++ b/drivers/freetype/src/cff/cf2ft.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2FT_H__ -#define __CF2FT_H__ +#ifndef CF2FT_H_ +#define CF2FT_H_ #include "cf2types.h" @@ -99,18 +99,18 @@ FT_BEGIN_HEADER FT_LOCAL( CF2_Int ) cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ); FT_LOCAL( FT_Error ) cf2_getSeacComponent( CFF_Decoder* decoder, - CF2_UInt code, + CF2_Int code, CF2_Buffer buf ); FT_LOCAL( void ) cf2_freeSeacComponent( CFF_Decoder* decoder, CF2_Buffer buf ); FT_LOCAL( CF2_Int ) cf2_initLocalRegionBuffer( CFF_Decoder* decoder, - CF2_UInt idx, + CF2_Int subrNum, CF2_Buffer buf ); FT_LOCAL( CF2_Fixed ) @@ -141,7 +141,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2FT_H__ */ +#endif /* CF2FT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2glue.h b/drivers/freetype/src/cff/cf2glue.h index a24da39e93..56a7c248f4 100644 --- a/drivers/freetype/freetype/src/cff/cf2glue.h +++ b/drivers/freetype/src/cff/cf2glue.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2GLUE_H__ -#define __CF2GLUE_H__ +#ifndef CF2GLUE_H_ +#define CF2GLUE_H_ /* common includes for other modules */ @@ -138,7 +138,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2GLUE_H__ */ +#endif /* CF2GLUE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2hints.c b/drivers/freetype/src/cff/cf2hints.c index 96bd49f186..bbbe8e3c32 100644 --- a/drivers/freetype/freetype/src/cff/cf2hints.c +++ b/drivers/freetype/src/cff/cf2hints.c @@ -4,7 +4,7 @@ /* */ /* Adobe's code for handling CFF hints (body). */ /* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* Copyright 2007-2014 Adobe Systems Incorporated. */ /* */ /* This software, and all works of authorship, whether in source or */ /* object code form as indicated by the copyright notice(s) included */ @@ -304,9 +304,6 @@ cf2_hintmap_map( CF2_HintMap hintmap, CF2_Fixed csCoord ) { - FT_ASSERT( hintmap->isValid ); /* must call Build before Map */ - FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES ); - if ( hintmap->count == 0 || ! hintmap->hinted ) { /* there are no hints; use uniform scale and zero offset */ @@ -317,6 +314,7 @@ /* start linear search from last hit */ CF2_UInt i = hintmap->lastIndex; + FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES ); /* search up */ while ( i < hintmap->count - 1 && @@ -589,29 +587,39 @@ } /* paired edges must be in proper order */ - FT_ASSERT( !isPair || - topHintEdge->csCoord >= bottomHintEdge->csCoord ); + if ( isPair && + topHintEdge->csCoord < bottomHintEdge->csCoord ) + return; /* linear search to find index value of insertion point */ indexInsert = 0; for ( ; indexInsert < hintmap->count; indexInsert++ ) { - if ( hintmap->edge[indexInsert].csCoord > firstHintEdge->csCoord ) + if ( hintmap->edge[indexInsert].csCoord >= firstHintEdge->csCoord ) break; } /* - * Discard any hints that overlap in character space. Most often, - * this is while building the initial map, but in theory, it can also - * occur because of darkening. + * Discard any hints that overlap in character space. Most often, this + * is while building the initial map, where captured hints from all + * zones are combined. Define overlap to include hints that `touch' + * (overlap zero). Hiragino Sans/Gothic fonts have numerous hints that + * touch. Some fonts have non-ideographic glyphs that overlap our + * synthetic hints. + * + * Overlap also occurs when darkening stem hints that are close. * */ if ( indexInsert < hintmap->count ) { - /* we are inserting before an existing edge: */ + /* we are inserting before an existing edge: */ + /* verify that an existing edge is not the same */ + if ( hintmap->edge[indexInsert].csCoord == firstHintEdge->csCoord ) + return; /* ignore overlapping stem hint */ + /* verify that a new pair does not straddle the next edge */ - if ( isPair && - hintmap->edge[indexInsert].csCoord < secondHintEdge->csCoord ) + if ( isPair && + hintmap->edge[indexInsert].csCoord <= secondHintEdge->csCoord ) return; /* ignore overlapping stem hint */ /* verify that we are not inserting between paired edges */ @@ -645,8 +653,27 @@ firstHintEdge->csCoord ); } - /* discard any hints that overlap in device space; this can occur */ - /* because locked hints have been moved to align with blue zones */ + /* + * Discard any hints that overlap in device space; this can occur + * because locked hints have been moved to align with blue zones. + * + * TODO: Although we might correct this later during adjustment, we + * don't currently have a way to delete a conflicting hint once it has + * been inserted. See v2.030 MinionPro-Regular, 12 ppem darkened, + * initial hint map for second path, glyph 945 (the perispomeni (tilde) + * in U+1F6E, Greek omega with psili and perispomeni). Darkening is + * 25. Pair 667,747 initially conflicts in design space with top edge + * 660. This is because 667 maps to 7.87, and the top edge was + * captured by a zone at 8.0. The pair is later successfully inserted + * in a zone without the top edge. In this zone it is adjusted to 8.0, + * and no longer conflicts with the top edge in design space. This + * means it can be included in yet a later zone which does have the top + * edge hint. This produces a small mismatch between the first and + * last points of this path, even though the hint masks are the same. + * The density map difference is tiny (1/256). + * + */ + if ( indexInsert > 0 ) { /* we are inserting after an existing edge */ @@ -671,10 +698,10 @@ /* make room to insert */ { - CF2_Int iSrc = hintmap->count - 1; - CF2_Int iDst = isPair ? hintmap->count + 1 : hintmap->count; + CF2_UInt iSrc = hintmap->count - 1; + CF2_UInt iDst = isPair ? hintmap->count + 1 : hintmap->count; - CF2_Int count = hintmap->count - indexInsert; + CF2_UInt count = hintmap->count - indexInsert; if ( iDst >= CF2_MAX_HINT_EDGES ) @@ -753,6 +780,8 @@ cf2_hintmask_setAll( hintMask, cf2_arrstack_size( hStemHintArray ) + cf2_arrstack_size( vStemHintArray ) ); + if ( !cf2_hintmask_isValid( hintMask ) ) + return; /* too many stem hints */ } /* begin by clearing the map */ @@ -764,9 +793,12 @@ maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask ); /* use the hStem hints only, which are first in the mask */ - /* TODO: compare this to cffhintmaskGetBitCount */ bitCount = cf2_arrstack_size( hStemHintArray ); + /* Defense-in-depth. Should never return here. */ + if ( bitCount > hintMask->bitCount ) + return; + /* synthetic embox hints get highest priority */ if ( font->blues.doEmBoxHints ) { @@ -1035,6 +1067,7 @@ glyphpath->moveIsPending = TRUE; glyphpath->pathIsOpen = FALSE; + glyphpath->pathIsClosing = FALSE; glyphpath->elemIsQueued = FALSE; } @@ -1175,12 +1208,16 @@ /* * Push the cached element (glyphpath->prevElem*) to the outline * consumer. When a darkening offset is used, the end point of the - * cached element may be adjusted to an intersection point or it may be - * connected by a line to the current element. This calculation must - * use a HintMap that was valid at the time the element was saved. For - * the first point in a subpath, that is a saved HintMap. For most - * elements, it just means the caller has delayed building a HintMap - * from the current HintMask. + * cached element may be adjusted to an intersection point or we may + * synthesize a connecting line to the current element. If we are + * closing a subpath, we may also generate a connecting line to the start + * point. + * + * This is where Character Space (CS) is converted to Device Space (DS) + * using a hint map. This calculation must use a HintMap that was valid + * at the time the element was saved. For the first point in a subpath, + * that is a saved HintMap. For most elements, it just means the caller + * has delayed building a HintMap from the current HintMask. * * Transform each point with outerTransform and call the outline * callbacks. This is a general 3x3 transform: @@ -1250,16 +1287,32 @@ params.op = CF2_PathOpLineTo; /* note: pt2 and pt3 are unused */ - cf2_glyphpath_hintPoint( glyphpath, - hintmap, - ¶ms.pt1, - glyphpath->prevElemP1.x, - glyphpath->prevElemP1.y ); - glyphpath->callbacks->lineTo( glyphpath->callbacks, ¶ms ); + if ( close ) + { + /* use first hint map if closing */ + cf2_glyphpath_hintPoint( glyphpath, + &glyphpath->firstHintMap, + ¶ms.pt1, + glyphpath->prevElemP1.x, + glyphpath->prevElemP1.y ); + } + else + { + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt1, + glyphpath->prevElemP1.x, + glyphpath->prevElemP1.y ); + } - glyphpath->currentDS = params.pt1; + /* output only non-zero length lines */ + if ( params.pt0.x != params.pt1.x || params.pt0.y != params.pt1.y ) + { + glyphpath->callbacks->lineTo( glyphpath->callbacks, ¶ms ); + glyphpath->currentDS = params.pt1; + } break; case CF2_PathOpCubeTo: @@ -1296,11 +1349,24 @@ /* note: at the end of a subpath, we might do both, so use `nextP0' */ /* before we change it, below */ - cf2_glyphpath_hintPoint( glyphpath, - hintmap, - ¶ms.pt1, - nextP0->x, - nextP0->y ); + if ( close ) + { + /* if we are closing the subpath, then nextP0 is in the first */ + /* hint zone */ + cf2_glyphpath_hintPoint( glyphpath, + &glyphpath->firstHintMap, + ¶ms.pt1, + nextP0->x, + nextP0->y ); + } + else + { + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt1, + nextP0->x, + nextP0->y ); + } if ( params.pt1.x != glyphpath->currentDS.x || params.pt1.y != glyphpath->currentDS.y ) @@ -1496,7 +1562,7 @@ { /* -y */ *x = -glyphpath->xOffset; - *y = glyphpath->xOffset; + *y = glyphpath->yOffset; } else { @@ -1511,6 +1577,16 @@ } + /* + * The functions cf2_glyphpath_{moveTo,lineTo,curveTo,closeOpenPath} are + * called by the interpreter with Character Space (CS) coordinates. Each + * path element is placed into a queue of length one to await the + * calculation of the following element. At that time, the darkening + * offset of the following element is known and joins can be computed, + * including possible modification of this element, before mapping to + * Device Space (DS) and passing it on to the outline consumer. + * + */ FT_LOCAL_DEF( void ) cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath, CF2_Fixed x, @@ -1548,10 +1624,46 @@ { CF2_Fixed xOffset, yOffset; FT_Vector P0, P1; + FT_Bool newHintMap; + /* + * New hints will be applied after cf2_glyphpath_pushPrevElem has run. + * In case this is a synthesized closing line, any new hints should be + * delayed until this path is closed (`cf2_hintmask_isNew' will be + * called again before the next line or curve). + */ - /* can't compute offset of zero length line, so ignore them */ - if ( glyphpath->currentCS.x == x && glyphpath->currentCS.y == y ) + /* true if new hint map not on close */ + newHintMap = cf2_hintmask_isNew( glyphpath->hintMask ) && + !glyphpath->pathIsClosing; + + /* + * Zero-length lines may occur in the charstring. Because we cannot + * compute darkening offsets or intersections from zero-length lines, + * it is best to remove them and avoid artifacts. However, zero-length + * lines in CS at the start of a new hint map can generate non-zero + * lines in DS due to hint substitution. We detect a change in hint + * map here and pass those zero-length lines along. + */ + + /* + * Note: Find explicitly closed paths here with a conditional + * breakpoint using + * + * !gp->pathIsClosing && gp->start.x == x && gp->start.y == y + * + */ + + if ( glyphpath->currentCS.x == x && + glyphpath->currentCS.y == y && + !newHintMap ) + /* + * Ignore zero-length lines in CS where the hint map is the same + * because the line in DS will also be zero length. + * + * Ignore zero-length lines when we synthesize a closing line because + * the close will be handled in cf2_glyphPath_pushPrevElem. + */ return; cf2_glyphpath_computeOffset( glyphpath, @@ -1581,7 +1693,8 @@ if ( glyphpath->elemIsQueued ) { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ); + FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) || + glyphpath->hintMap.count == 0 ); cf2_glyphpath_pushPrevElem( glyphpath, &glyphpath->hintMap, @@ -1597,7 +1710,7 @@ glyphpath->prevElemP1 = P1; /* update current map */ - if ( cf2_hintmask_isNew( glyphpath->hintMask ) ) + if ( newHintMap ) cf2_hintmap_build( &glyphpath->hintMap, glyphpath->hStemHintArray, glyphpath->vStemHintArray, @@ -1667,7 +1780,8 @@ if ( glyphpath->elemIsQueued ) { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ); + FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) || + glyphpath->hintMap.count == 0 ); cf2_glyphpath_pushPrevElem( glyphpath, &glyphpath->hintMap, @@ -1703,29 +1817,29 @@ { if ( glyphpath->pathIsOpen ) { - FT_ASSERT( cf2_hintmap_isValid( &glyphpath->firstHintMap ) ); + /* + * A closing line in Character Space line is always generated below + * with `cf2_glyphPath_lineTo'. It may be ignored later if it turns + * out to be zero length in Device Space. + */ + glyphpath->pathIsClosing = TRUE; - /* since we need to apply an offset to the implicit lineto, we make */ - /* it explicit here */ cf2_glyphpath_lineTo( glyphpath, glyphpath->start.x, glyphpath->start.y ); - /* Draw previous element (the explicit LineTo we just created, */ - /* above) and connect it to the start point, but with the offset we */ - /* saved from the first element. */ - /* Use the saved HintMap, too. */ - FT_ASSERT( glyphpath->elemIsQueued ); - - cf2_glyphpath_pushPrevElem( glyphpath, - &glyphpath->firstHintMap, - &glyphpath->offsetStart0, - glyphpath->offsetStart1, - TRUE ); + /* empty the final element from the queue and close the path */ + if ( glyphpath->elemIsQueued ) + cf2_glyphpath_pushPrevElem( glyphpath, + &glyphpath->hintMap, + &glyphpath->offsetStart0, + glyphpath->offsetStart1, + TRUE ); /* reset state machine */ glyphpath->moveIsPending = TRUE; glyphpath->pathIsOpen = FALSE; + glyphpath->pathIsClosing = FALSE; glyphpath->elemIsQueued = FALSE; } } diff --git a/drivers/freetype/freetype/src/cff/cf2hints.h b/drivers/freetype/src/cff/cf2hints.h index c4fa922a39..a8984542a0 100644 --- a/drivers/freetype/freetype/src/cff/cf2hints.h +++ b/drivers/freetype/src/cff/cf2hints.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2HINTS_H__ -#define __CF2HINTS_H__ +#ifndef CF2HINTS_H_ +#define CF2HINTS_H_ FT_BEGIN_HEADER @@ -204,6 +204,7 @@ FT_BEGIN_HEADER #endif FT_Bool pathIsOpen; /* true after MoveTo */ + FT_Bool pathIsClosing; /* true when synthesizing closepath line */ FT_Bool darken; /* true if stem darkening */ FT_Bool moveIsPending; /* true between MoveTo and offset MoveTo */ @@ -219,7 +220,7 @@ FT_BEGIN_HEADER /* character space miter limit threshold */ CF2_Fixed miterLimit; - /* vertical/horzizontal snap distance in character space */ + /* vertical/horizontal snap distance in character space */ CF2_Fixed snapThreshold; FT_Vector offsetStart0; /* first and second points of first */ @@ -229,7 +230,8 @@ FT_BEGIN_HEADER FT_Vector currentCS; /* current point, device space */ FT_Vector currentDS; - FT_Vector start; /* start point of subpath */ + /* start point of subpath, character space */ + FT_Vector start; /* the following members constitute the `queue' of one element */ FT_Bool elemIsQueued; @@ -281,7 +283,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2HINTS_H__ */ +#endif /* CF2HINTS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2intrp.c b/drivers/freetype/src/cff/cf2intrp.c index 5610917cc3..7d663dd0ec 100644 --- a/drivers/freetype/freetype/src/cff/cf2intrp.c +++ b/drivers/freetype/src/cff/cf2intrp.c @@ -4,7 +4,7 @@ /* */ /* Adobe's CFF Interpreter (body). */ /* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* Copyright 2007-2014 Adobe Systems Incorporated. */ /* */ /* This software, and all works of authorship, whether in source or */ /* object code form as indicated by the copyright notice(s) included */ @@ -43,6 +43,7 @@ #include "cf2font.h" #include "cf2stack.h" #include "cf2hints.h" +#include "cf2intrp.h" #include "cf2error.h" @@ -183,7 +184,7 @@ return; FT_ASSERT( hintmask->byteCount > 0 ); - FT_ASSERT( hintmask->byteCount < + FT_ASSERT( hintmask->byteCount <= sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) ); /* set mask to all ones */ @@ -292,7 +293,8 @@ /* variable accumulates delta values from operand stack */ CF2_Fixed position = hintOffset; - if ( hasWidthArg && ! *haveWidth ) + + if ( hasWidthArg && !*haveWidth ) *width = cf2_stack_getReal( opStack, 0 ) + cf2_getNominalWidthX( font->decoder ); @@ -445,6 +447,8 @@ CF2_Stack opStack = NULL; FT_Byte op1; /* first opcode byte */ + CF2_F16Dot16 storage[CF2_STORAGE_SIZE]; /* for `put' and `get' */ + /* instruction limit; 20,000,000 matches Avalon */ FT_UInt32 instructionLimit = 20000000UL; @@ -593,8 +597,11 @@ /* never add hints after the mask is computed */ if ( cf2_hintmask_isValid( &hintMask ) ) + { FT_TRACE4(( "cf2_interpT2CharString:" " invalid horizontal hint mask\n" )); + break; + } cf2_doStems( font, opStack, @@ -604,7 +611,7 @@ 0 ); if ( font->decoder->width_only ) - goto exit; + goto exit; break; @@ -614,8 +621,11 @@ /* never add hints after the mask is computed */ if ( cf2_hintmask_isValid( &hintMask ) ) + { FT_TRACE4(( "cf2_interpT2CharString:" " invalid vertical hint mask\n" )); + break; + } cf2_doStems( font, opStack, @@ -625,7 +635,7 @@ 0 ); if ( font->decoder->width_only ) - goto exit; + goto exit; break; @@ -639,7 +649,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; curY += cf2_stack_popFixed( opStack ); @@ -739,7 +749,7 @@ case cf2_cmdCALLGSUBR: case cf2_cmdCALLSUBR: { - CF2_UInt subrIndex; + CF2_Int subrNum; FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr" @@ -754,19 +764,22 @@ /* push our current CFF charstring region on subrStack */ charstring = (CF2_Buffer) - cf2_arrstack_getPointer( &subrStack, - charstringIndex + 1 ); + cf2_arrstack_getPointer( + &subrStack, + (size_t)charstringIndex + 1 ); /* set up the new CFF region and pointer */ - subrIndex = cf2_stack_popInt( opStack ); + subrNum = cf2_stack_popInt( opStack ); switch ( op1 ) { case cf2_cmdCALLGSUBR: - FT_TRACE4(( "(%d)\n", subrIndex + decoder->globals_bias )); + FT_TRACE4(( " (idx %d, entering level %d)\n", + subrNum + decoder->globals_bias, + charstringIndex + 1 )); if ( cf2_initGlobalRegionBuffer( decoder, - subrIndex, + subrNum, charstring ) ) { lastError = FT_THROW( Invalid_Glyph_Format ); @@ -776,10 +789,12 @@ default: /* cf2_cmdCALLSUBR */ - FT_TRACE4(( "(%d)\n", subrIndex + decoder->locals_bias )); + FT_TRACE4(( " (idx %d, entering level %d)\n", + subrNum + decoder->locals_bias, + charstringIndex + 1 )); if ( cf2_initLocalRegionBuffer( decoder, - subrIndex, + subrNum, charstring ) ) { lastError = FT_THROW( Invalid_Glyph_Format ); @@ -792,7 +807,7 @@ continue; /* do not clear the stack */ case cf2_cmdRETURN: - FT_TRACE4(( " return\n" )); + FT_TRACE4(( " return (leaving level %d)\n", charstringIndex )); if ( charstringIndex < 1 ) { @@ -803,8 +818,9 @@ /* restore position in previous charstring */ charstring = (CF2_Buffer) - cf2_arrstack_getPointer( &subrStack, - --charstringIndex ); + cf2_arrstack_getPointer( + &subrStack, + (CF2_UInt)--charstringIndex ); continue; /* do not clear the stack */ case cf2_cmdESC: @@ -820,84 +836,189 @@ break; - /* TODO: should these operators be supported? */ - case cf2_escAND: /* in spec */ - FT_TRACE4(( " and\n" )); + case cf2_escAND: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; - CF2_FIXME; - break; - case cf2_escOR: /* in spec */ - FT_TRACE4(( " or\n" )); + FT_TRACE4(( " and\n" )); - CF2_FIXME; - break; + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); - case cf2_escNOT: /* in spec */ - FT_TRACE4(( " not\n" )); + cf2_stack_pushInt( opStack, arg1 && arg2 ); + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escOR: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; - case cf2_escABS: /* in spec */ - FT_TRACE4(( " abs\n" )); - CF2_FIXME; - break; + FT_TRACE4(( " or\n" )); - case cf2_escADD: /* in spec */ - FT_TRACE4(( " add\n" )); + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); - CF2_FIXME; - break; + cf2_stack_pushInt( opStack, arg1 || arg2 ); + } + continue; /* do not clear the stack */ - case cf2_escSUB: /* in spec */ - FT_TRACE4(( " sub\n" )); + case cf2_escNOT: + { + CF2_F16Dot16 arg; - CF2_FIXME; - break; - case cf2_escDIV: /* in spec */ - FT_TRACE4(( " div\n" )); + FT_TRACE4(( " not\n" )); - CF2_FIXME; - break; + arg = cf2_stack_popFixed( opStack ); - case cf2_escNEG: /* in spec */ - FT_TRACE4(( " neg\n" )); + cf2_stack_pushInt( opStack, !arg ); + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escABS: + { + CF2_F16Dot16 arg; - case cf2_escEQ: /* in spec */ - FT_TRACE4(( " eq\n" )); - CF2_FIXME; - break; + FT_TRACE4(( " abs\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, FT_ABS( arg ) ); + } + continue; /* do not clear the stack */ + + case cf2_escADD: + { + CF2_F16Dot16 summand1; + CF2_F16Dot16 summand2; + + + FT_TRACE4(( " add\n" )); - case cf2_escDROP: /* in spec */ + summand2 = cf2_stack_popFixed( opStack ); + summand1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, summand1 + summand2 ); + } + continue; /* do not clear the stack */ + + case cf2_escSUB: + { + CF2_F16Dot16 minuend; + CF2_F16Dot16 subtrahend; + + + FT_TRACE4(( " sub\n" )); + + subtrahend = cf2_stack_popFixed( opStack ); + minuend = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, minuend - subtrahend ); + } + continue; /* do not clear the stack */ + + case cf2_escDIV: + { + CF2_F16Dot16 dividend; + CF2_F16Dot16 divisor; + + + FT_TRACE4(( " div\n" )); + + divisor = cf2_stack_popFixed( opStack ); + dividend = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) ); + } + continue; /* do not clear the stack */ + + case cf2_escNEG: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " neg\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, -arg ); + } + continue; /* do not clear the stack */ + + case cf2_escEQ: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " eq\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushInt( opStack, arg1 == arg2 ); + } + continue; /* do not clear the stack */ + + case cf2_escDROP: FT_TRACE4(( " drop\n" )); - CF2_FIXME; - break; + (void)cf2_stack_popFixed( opStack ); + continue; /* do not clear the stack */ - case cf2_escPUT: /* in spec */ - FT_TRACE4(( " put\n" )); + case cf2_escPUT: + { + CF2_F16Dot16 val; + CF2_Int idx; - CF2_FIXME; - break; - case cf2_escGET: /* in spec */ - FT_TRACE4(( " get\n" )); + FT_TRACE4(( " put\n" )); - CF2_FIXME; - break; + idx = cf2_stack_popInt( opStack ); + val = cf2_stack_popFixed( opStack ); - case cf2_escIFELSE: /* in spec */ - FT_TRACE4(( " ifelse\n" )); + if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + storage[idx] = val; + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escGET: + { + CF2_Int idx; + + + FT_TRACE4(( " get\n" )); + + idx = cf2_stack_popInt( opStack ); + + if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + cf2_stack_pushFixed( opStack, storage[idx] ); + } + continue; /* do not clear the stack */ + + case cf2_escIFELSE: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + CF2_F16Dot16 cond1; + CF2_F16Dot16 cond2; + + + FT_TRACE4(( " ifelse\n" )); + + cond2 = cf2_stack_popFixed( opStack ); + cond1 = cf2_stack_popFixed( opStack ); + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 ); + } + continue; /* do not clear the stack */ case cf2_escRANDOM: /* in spec */ FT_TRACE4(( " random\n" )); @@ -905,41 +1026,126 @@ CF2_FIXME; break; - case cf2_escMUL: /* in spec */ - FT_TRACE4(( " mul\n" )); + case cf2_escMUL: + { + CF2_F16Dot16 factor1; + CF2_F16Dot16 factor2; - CF2_FIXME; - break; - case cf2_escSQRT: /* in spec */ - FT_TRACE4(( " sqrt\n" )); + FT_TRACE4(( " mul\n" )); - CF2_FIXME; - break; + factor2 = cf2_stack_popFixed( opStack ); + factor1 = cf2_stack_popFixed( opStack ); - case cf2_escDUP: /* in spec */ - FT_TRACE4(( " dup\n" )); + cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) ); + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escSQRT: + { + CF2_F16Dot16 arg; - case cf2_escEXCH: /* in spec */ - FT_TRACE4(( " exch\n" )); - CF2_FIXME; - break; + FT_TRACE4(( " sqrt\n" )); + + arg = cf2_stack_popFixed( opStack ); + if ( arg > 0 ) + { + FT_Fixed root = arg; + FT_Fixed new_root; + + + /* Babylonian method */ + for (;;) + { + new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1; + if ( new_root == root ) + break; + root = new_root; + } + arg = new_root; + } + else + arg = 0; - case cf2_escINDEX: /* in spec */ - FT_TRACE4(( " index\n" )); + cf2_stack_pushFixed( opStack, arg ); + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escDUP: + { + CF2_F16Dot16 arg; - case cf2_escROLL: /* in spec */ - FT_TRACE4(( " roll\n" )); - CF2_FIXME; - break; + FT_TRACE4(( " dup\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, arg ); + cf2_stack_pushFixed( opStack, arg ); + } + continue; /* do not clear the stack */ + + case cf2_escEXCH: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " exch\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, arg2 ); + cf2_stack_pushFixed( opStack, arg1 ); + } + continue; /* do not clear the stack */ + + case cf2_escINDEX: + { + CF2_Int idx; + CF2_UInt size; + + + FT_TRACE4(( " index\n" )); + + idx = cf2_stack_popInt( opStack ); + size = cf2_stack_count( opStack ); + + if ( size > 0 ) + { + /* for `cf2_stack_getReal', index 0 is bottom of stack */ + CF2_UInt gr_idx; + + + if ( idx < 0 ) + gr_idx = size - 1; + else if ( (CF2_UInt)idx >= size ) + gr_idx = 0; + else + gr_idx = size - 1 - (CF2_UInt)idx; + + cf2_stack_pushFixed( opStack, + cf2_stack_getReal( opStack, gr_idx ) ); + } + } + continue; /* do not clear the stack */ + + case cf2_escROLL: + { + CF2_Int idx; + CF2_Int count; + + + FT_TRACE4(( " roll\n" )); + + idx = cf2_stack_popInt( opStack ); + count = cf2_stack_popInt( opStack ); + + cf2_stack_roll( opStack, count, idx ); + } + continue; /* do not clear the stack */ case cf2_escHFLEX: { @@ -1072,7 +1278,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; /* close path if still open */ cf2_glyphpath_closeOpenPath( &glyphPath ); @@ -1082,8 +1288,8 @@ /* must be either 4 or 5 -- */ /* this is a (deprecated) implied `seac' operator */ - CF2_UInt achar; - CF2_UInt bchar; + CF2_Int achar; + CF2_Int bchar; CF2_BufferRec component; CF2_Fixed dummyWidth; /* ignore component width */ FT_Error error2; @@ -1104,8 +1310,8 @@ error2 = cf2_getSeacComponent( decoder, achar, &component ); if ( error2 ) { - lastError = error2; /* pass FreeType error through */ - goto exit; + lastError = error2; /* pass FreeType error through */ + goto exit; } cf2_interpT2CharString( font, &component, @@ -1141,15 +1347,16 @@ /* `cf2_hintmask_read' (which also traces the mask bytes) */ FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" )); - /* if there are arguments on the stack, there this is an */ - /* implied cf2_cmdVSTEMHM */ - if ( cf2_stack_count( opStack ) != 0 ) + /* never add hints after the mask is computed */ + if ( cf2_stack_count( opStack ) > 1 && + cf2_hintmask_isValid( &hintMask ) ) { - /* never add hints after the mask is computed */ - if ( cf2_hintmask_isValid( &hintMask ) ) - FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" )); + FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" )); + break; } + /* if there are arguments on the stack, there this is an */ + /* implied cf2_cmdVSTEMHM */ cf2_doStems( font, opStack, &vStemHintArray, @@ -1158,7 +1365,7 @@ 0 ); if ( font->decoder->width_only ) - goto exit; + goto exit; if ( op1 == cf2_cmdHINTMASK ) { @@ -1217,7 +1424,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; curY += cf2_stack_popFixed( opStack ); curX += cf2_stack_popFixed( opStack ); @@ -1236,7 +1443,7 @@ haveWidth = TRUE; if ( font->decoder->width_only ) - goto exit; + goto exit; curX += cf2_stack_popFixed( opStack ); @@ -1284,10 +1491,16 @@ case cf2_cmdVVCURVETO: { - CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt count, count1 = cf2_stack_count( opStack ); CF2_UInt index = 0; + /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */ + /* we enforce it by clearing the second bit */ + /* (and sorting the stack indexing to suit) */ + count = count1 & ~2U; + index += count1 - count; + FT_TRACE4(( " vvcurveto\n" )); while ( index < count ) @@ -1323,10 +1536,16 @@ case cf2_cmdHHCURVETO: { - CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt count, count1 = cf2_stack_count( opStack ); CF2_UInt index = 0; + /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */ + /* we enforce it by clearing the second bit */ + /* (and sorting the stack indexing to suit) */ + count = count1 & ~2U; + index += count1 - count; + FT_TRACE4(( " hhcurveto\n" )); while ( index < count ) @@ -1363,12 +1582,19 @@ case cf2_cmdVHCURVETO: case cf2_cmdHVCURVETO: { - CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt count, count1 = cf2_stack_count( opStack ); CF2_UInt index = 0; FT_Bool alternate = op1 == cf2_cmdHVCURVETO; + /* if `cf2_stack_count' isn't of the form 8n, 8n+1, */ + /* 8n+4, or 8n+5, we enforce it by clearing the */ + /* second bit */ + /* (and sorting the stack indexing to suit) */ + count = count1 & ~2U; + index += count1 - count; + FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" )); while ( index < count ) @@ -1430,9 +1656,12 @@ { CF2_Int v; + CF2_Int byte1 = cf2_buf_readByte( charstring ); + CF2_Int byte2 = cf2_buf_readByte( charstring ); - v = (FT_Short)( ( cf2_buf_readByte( charstring ) << 8 ) | - cf2_buf_readByte( charstring ) ); + + v = (FT_Short)( ( byte1 << 8 ) | + byte2 ); FT_TRACE4(( " %d", v )); @@ -1494,12 +1723,16 @@ { CF2_Fixed v; + FT_UInt32 byte1 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte2 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte3 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte4 = (FT_UInt32)cf2_buf_readByte( charstring ); + - v = (CF2_Fixed) - ( ( (FT_UInt32)cf2_buf_readByte( charstring ) << 24 ) | - ( (FT_UInt32)cf2_buf_readByte( charstring ) << 16 ) | - ( (FT_UInt32)cf2_buf_readByte( charstring ) << 8 ) | - (FT_UInt32)cf2_buf_readByte( charstring ) ); + v = (CF2_Fixed)( ( byte1 << 24 ) | + ( byte2 << 16 ) | + ( byte3 << 8 ) | + byte4 ); FT_TRACE4(( " %.2f", v / 65536.0 )); diff --git a/drivers/freetype/freetype/src/cff/cf2intrp.h b/drivers/freetype/src/cff/cf2intrp.h index b5d8947838..ec030e8944 100644 --- a/drivers/freetype/freetype/src/cff/cf2intrp.h +++ b/drivers/freetype/src/cff/cf2intrp.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2INTRP_H__ -#define __CF2INTRP_H__ +#ifndef CF2INTRP_H_ +#define CF2INTRP_H_ #include "cf2ft.h" @@ -77,7 +77,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2INTRP_H__ */ +#endif /* CF2INTRP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2read.c b/drivers/freetype/src/cff/cf2read.c index 2b429e3eeb..2b429e3eeb 100644 --- a/drivers/freetype/freetype/src/cff/cf2read.c +++ b/drivers/freetype/src/cff/cf2read.c diff --git a/drivers/freetype/freetype/src/cff/cf2read.h b/drivers/freetype/src/cff/cf2read.h index 7ef7c8c149..b0b0db803a 100644 --- a/drivers/freetype/freetype/src/cff/cf2read.h +++ b/drivers/freetype/src/cff/cf2read.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2READ_H__ -#define __CF2READ_H__ +#ifndef CF2READ_H_ +#define CF2READ_H_ FT_BEGIN_HEADER @@ -62,7 +62,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2READ_H__ */ +#endif /* CF2READ_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2stack.c b/drivers/freetype/src/cff/cf2stack.c index 8332b5d91a..6fafd901f3 100644 --- a/drivers/freetype/freetype/src/cff/cf2stack.c +++ b/drivers/freetype/src/cff/cf2stack.c @@ -145,7 +145,7 @@ /* Note: type mismatch is silently cast */ - /* TODO: check this */ + /* TODO: check this */ FT_LOCAL_DEF( CF2_Fixed ) cf2_stack_popFixed( CF2_Stack stack ) { @@ -170,7 +170,7 @@ /* Note: type mismatch is silently cast */ - /* TODO: check this */ + /* TODO: check this */ FT_LOCAL_DEF( CF2_Fixed ) cf2_stack_getReal( CF2_Stack stack, CF2_UInt idx ) @@ -195,6 +195,86 @@ } + FT_LOCAL( void ) + cf2_stack_roll( CF2_Stack stack, + CF2_Int count, + CF2_Int shift ) + { + /* we initialize this variable to avoid compiler warnings */ + CF2_StackNumber last = { { 0 }, CF2_NumberInt }; + + CF2_Int start_idx, idx, i; + + + if ( count < 2 ) + return; /* nothing to do (values 0 and 1), or undefined value */ + + if ( (CF2_UInt)count > cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; + } + + if ( shift < 0 ) + shift = -( ( -shift ) % count ); + else + shift %= count; + + if ( shift == 0 ) + return; /* nothing to do */ + + /* We use the following algorithm to do the rolling, */ + /* which needs two temporary variables only. */ + /* */ + /* Example: */ + /* */ + /* count = 8 */ + /* shift = 2 */ + /* */ + /* stack indices before roll: 7 6 5 4 3 2 1 0 */ + /* stack indices after roll: 1 0 7 6 5 4 3 2 */ + /* */ + /* The value of index 0 gets moved to index 2, while */ + /* the old value of index 2 gets moved to index 4, */ + /* and so on. We thus have the following copying */ + /* chains for shift value 2. */ + /* */ + /* 0 -> 2 -> 4 -> 6 -> 0 */ + /* 1 -> 3 -> 5 -> 7 -> 1 */ + /* */ + /* If `count' and `shift' are incommensurable, we */ + /* have a single chain only. Otherwise, increase */ + /* the start index by 1 after the first chain, then */ + /* do the next chain until all elements in all */ + /* chains are handled. */ + + start_idx = -1; + idx = -1; + for ( i = 0; i < count; i++ ) + { + CF2_StackNumber tmp; + + + if ( start_idx == idx ) + { + start_idx++; + idx = start_idx; + last = stack->buffer[idx]; + } + + idx += shift; + if ( idx >= count ) + idx -= count; + else if ( idx < 0 ) + idx += count; + + tmp = stack->buffer[idx]; + stack->buffer[idx] = last; + last = tmp; + } + } + + FT_LOCAL_DEF( void ) cf2_stack_clear( CF2_Stack stack ) { diff --git a/drivers/freetype/freetype/src/cff/cf2stack.h b/drivers/freetype/src/cff/cf2stack.h index 7d6d1961fe..e740a7ac41 100644 --- a/drivers/freetype/freetype/src/cff/cf2stack.h +++ b/drivers/freetype/src/cff/cf2stack.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2STACK_H__ -#define __CF2STACK_H__ +#ifndef CF2STACK_H_ +#define CF2STACK_H_ FT_BEGIN_HEADER @@ -94,13 +94,18 @@ FT_BEGIN_HEADER CF2_UInt idx ); FT_LOCAL( void ) + cf2_stack_roll( CF2_Stack stack, + CF2_Int count, + CF2_Int idx ); + + FT_LOCAL( void ) cf2_stack_clear( CF2_Stack stack ); FT_END_HEADER -#endif /* __CF2STACK_H__ */ +#endif /* CF2STACK_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cf2types.h b/drivers/freetype/src/cff/cf2types.h index ac6a02266e..5b7e1239af 100644 --- a/drivers/freetype/freetype/src/cff/cf2types.h +++ b/drivers/freetype/src/cff/cf2types.h @@ -36,8 +36,8 @@ /***************************************************************************/ -#ifndef __CF2TYPES_H__ -#define __CF2TYPES_H__ +#ifndef CF2TYPES_H_ +#define CF2TYPES_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -72,7 +72,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CF2TYPES_H__ */ +#endif /* CF2TYPES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cff.c b/drivers/freetype/src/cff/cff.c index c3840b5838..86ca1be040 100644 --- a/drivers/freetype/freetype/src/cff/cff.c +++ b/drivers/freetype/src/cff/cff.c @@ -4,7 +4,7 @@ /* */ /* FreeType OpenType driver component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/cff/cffcmap.c b/drivers/freetype/src/cff/cffcmap.c index f6e03c6420..3ef48328c5 100644 --- a/drivers/freetype/freetype/src/cff/cffcmap.c +++ b/drivers/freetype/src/cff/cffcmap.c @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002-2007, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -33,12 +33,15 @@ /*************************************************************************/ FT_CALLBACK_DEF( FT_Error ) - cff_cmap_encoding_init( CFF_CMapStd cmap ) + cff_cmap_encoding_init( CFF_CMapStd cmap, + FT_Pointer pointer ) { TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); CFF_Font cff = (CFF_Font)face->extra.data; CFF_Encoding encoding = &cff->encoding; + FT_UNUSED( pointer ); + cmap->gids = encoding->codes; @@ -135,7 +138,8 @@ FT_CALLBACK_DEF( FT_Error ) - cff_cmap_unicode_init( PS_Unicodes unicodes ) + cff_cmap_unicode_init( PS_Unicodes unicodes, + FT_Pointer pointer ) { TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -143,6 +147,8 @@ CFF_Charset charset = &cff->charset; FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + FT_UNUSED( pointer ); + /* can't build Unicode map for CID-keyed font */ /* because we don't know glyph names. */ diff --git a/drivers/freetype/freetype/src/cff/cffcmap.h b/drivers/freetype/src/cff/cffcmap.h index 3f7f67bbe0..23795d5090 100644 --- a/drivers/freetype/freetype/src/cff/cffcmap.h +++ b/drivers/freetype/src/cff/cffcmap.h @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002, 2003, 2006 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFCMAP_H__ -#define __CFFCMAP_H__ +#ifndef CFFCMAP_H_ +#define CFFCMAP_H_ #include "cffobjs.h" @@ -61,7 +61,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFCMAP_H__ */ +#endif /* CFFCMAP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cffdrivr.c b/drivers/freetype/src/cff/cffdrivr.c index c8ca96ba49..950a9605c3 100644 --- a/drivers/freetype/freetype/src/cff/cffdrivr.c +++ b/drivers/freetype/src/cff/cffdrivr.c @@ -4,7 +4,7 @@ /* */ /* OpenType font driver implementation (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,7 @@ #include "cfferrs.h" #include "cffpic.h" -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_GLYPH_DICT_H #include FT_SERVICE_PROPERTIES_H #include FT_CFF_DRIVER_H @@ -64,11 +64,6 @@ /*************************************************************************/ -#undef PAIR_TAG -#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ - (FT_ULong)right ) - - /*************************************************************************/ /* */ /* <Function> */ @@ -121,9 +116,6 @@ } -#undef PAIR_TAG - - /*************************************************************************/ /* */ /* <Function> */ @@ -164,6 +156,8 @@ if ( !slot ) return FT_THROW( Invalid_Slot_Handle ); + FT_TRACE1(( "cff_glyph_load: glyph index %d\n", glyph_index )); + /* check whether we want a scaled outline or bitmap */ if ( !size ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; @@ -201,6 +195,68 @@ FT_GlyphSlot slot = face->glyph; + if ( FT_IS_SFNT( face ) ) + { + /* OpenType 1.7 mandates that the data from `hmtx' table be used; */ + /* it is no longer necessary that those values are identical to */ + /* the values in the `CFF' table */ + + TT_Face ttface = (TT_Face)face; + FT_Short dummy; + + + if ( flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* check whether we have data from the `vmtx' table at all; */ + /* otherwise we extract the info from the CFF glyphstrings */ + /* (instead of synthesizing a global value using the `OS/2' */ + /* table) */ + if ( !ttface->vertical_info ) + goto Missing_Table; + + for ( nn = 0; nn < count; nn++ ) + { + FT_UShort ah; + + + ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface, + 1, + start + nn, + &dummy, + &ah ); + + FT_TRACE5(( " idx %d: advance height %d font units\n", + start + nn, ah )); + advances[nn] = ah; + } + } + else + { + /* check whether we have data from the `hmtx' table at all */ + if ( !ttface->horizontal.number_Of_HMetrics ) + goto Missing_Table; + + for ( nn = 0; nn < count; nn++ ) + { + FT_UShort aw; + + + ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface, + 0, + start + nn, + &dummy, + &aw ); + + FT_TRACE5(( " idx %d: advance width %d font units\n", + start + nn, aw )); + advances[nn] = aw; + } + } + + return error; + } + + Missing_Table: flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; for ( nn = 0; nn < count; nn++ ) @@ -302,8 +358,8 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( cff_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)cff_get_name_index + (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)cff_get_name_index /* name_index */ ) @@ -350,7 +406,7 @@ font_info->italic_angle = dict->italic_angle; font_info->is_fixed_pitch = dict->is_fixed_pitch; font_info->underline_position = (FT_Short)dict->underline_position; - font_info->underline_thickness = (FT_Short)dict->underline_thickness; + font_info->underline_thickness = (FT_UShort)dict->underline_thickness; cff->font_info = font_info; } @@ -365,11 +421,13 @@ FT_DEFINE_SERVICE_PSINFOREC( cff_service_ps_info, - (PS_GetFontInfoFunc) cff_ps_get_font_info, - (PS_GetFontExtraFunc) NULL, - (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, - (PS_GetFontPrivateFunc)NULL, /* unsupported with CFF fonts */ - (PS_GetFontValueFunc) NULL /* not implemented */ + (PS_GetFontInfoFunc) cff_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) NULL, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, /* ps_has_glyph_names */ + /* unsupported with CFF fonts */ + (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ ) @@ -381,16 +439,34 @@ static const char* cff_get_ps_name( CFF_Face face ) { - CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Font cff = (CFF_Font)face->extra.data; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + + /* following the OpenType specification 1.7, we return the name stored */ + /* in the `name' table for a CFF wrapped into an SFNT container */ + + if ( FT_IS_SFNT( FT_FACE( face ) ) && sfnt ) + { + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); + FT_Service_PsFontName service = + (FT_Service_PsFontName)ft_module_get_service( + sfnt_module, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME ); + if ( service && service->get_ps_font_name ) + return service->get_ps_font_name( FT_FACE( face ) ); + } + return (const char*)cff->font_name; } FT_DEFINE_SERVICE_PSFONTNAMEREC( cff_service_ps_name, - (FT_PsName_GetFunc)cff_get_ps_name + (FT_PsName_GetFunc)cff_get_ps_name /* get_ps_font_name */ ) @@ -437,7 +513,7 @@ FT_DEFINE_SERVICE_TTCMAPSREC( cff_service_get_cmap_info, - (TT_CMap_Info_GetFunc)cff_get_cmap_info + (TT_CMap_Info_GetFunc)cff_get_cmap_info /* get_cmap_info */ ) @@ -567,9 +643,12 @@ FT_DEFINE_SERVICE_CIDREC( cff_service_cid_info, - (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, - (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, - (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index + (FT_CID_GetRegistryOrderingSupplementFunc) + cff_get_ros, /* get_ros */ + (FT_CID_GetIsInternallyCIDKeyedFunc) + cff_get_is_cid, /* get_is_cid */ + (FT_CID_GetCIDFromGlyphIndexFunc) + cff_get_cid_from_glyph_index /* get_cid_from_glyph_index */ ) @@ -586,17 +665,50 @@ CFF_Driver driver = (CFF_Driver)module; - if ( !ft_strcmp( property_name, "hinting-engine" ) ) + if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = (FT_Int*)value; + + FT_Int x1 = darken_params[0]; + FT_Int y1 = darken_params[1]; + FT_Int x2 = darken_params[2]; + FT_Int y2 = darken_params[3]; + FT_Int x3 = darken_params[4]; + FT_Int y3 = darken_params[5]; + FT_Int x4 = darken_params[6]; + FT_Int y4 = darken_params[7]; + + + if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || + y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || + x1 > x2 || x2 > x3 || x3 > x4 || + y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) + return FT_THROW( Invalid_Argument ); + + driver->darken_params[0] = x1; + driver->darken_params[1] = y1; + driver->darken_params[2] = x2; + driver->darken_params[3] = y2; + driver->darken_params[4] = x3; + driver->darken_params[5] = y3; + driver->darken_params[6] = x4; + driver->darken_params[7] = y4; + + return error; + } + else if ( !ft_strcmp( property_name, "hinting-engine" ) ) { FT_UInt* hinting_engine = (FT_UInt*)value; -#ifndef CFF_CONFIG_OPTION_OLD_ENGINE - if ( *hinting_engine != FT_CFF_HINTING_ADOBE ) - error = FT_ERR( Unimplemented_Feature ); - else + if ( *hinting_engine == FT_CFF_HINTING_ADOBE +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + || *hinting_engine == FT_CFF_HINTING_FREETYPE #endif + ) driver->hinting_engine = *hinting_engine; + else + error = FT_ERR( Unimplemented_Feature ); return error; } @@ -624,13 +736,28 @@ FT_Error error = FT_Err_Ok; CFF_Driver driver = (CFF_Driver)module; - FT_UInt hinting_engine = driver->hinting_engine; - FT_Bool no_stem_darkening = driver->no_stem_darkening; + if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = driver->darken_params; + FT_Int* val = (FT_Int*)value; + + + val[0] = darken_params[0]; + val[1] = darken_params[1]; + val[2] = darken_params[2]; + val[3] = darken_params[3]; + val[4] = darken_params[4]; + val[5] = darken_params[5]; + val[6] = darken_params[6]; + val[7] = darken_params[7]; - if ( !ft_strcmp( property_name, "hinting-engine" ) ) + return error; + } + else if ( !ft_strcmp( property_name, "hinting-engine" ) ) { - FT_UInt* val = (FT_UInt*)value; + FT_UInt hinting_engine = driver->hinting_engine; + FT_UInt* val = (FT_UInt*)value; *val = hinting_engine; @@ -639,7 +766,8 @@ } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { - FT_Bool* val = (FT_Bool*)value; + FT_Bool no_stem_darkening = driver->no_stem_darkening; + FT_Bool* val = (FT_Bool*)value; *val = no_stem_darkening; @@ -655,8 +783,8 @@ FT_DEFINE_SERVICE_PROPERTIESREC( cff_service_properties, - (FT_Properties_SetFunc)cff_property_set, - (FT_Properties_GetFunc)cff_property_get ) + (FT_Properties_SetFunc)cff_property_set, /* set_property */ + (FT_Properties_GetFunc)cff_property_get ) /* get_property */ /*************************************************************************/ @@ -674,7 +802,7 @@ #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES FT_DEFINE_SERVICEDESCREC7( cff_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, @@ -685,7 +813,7 @@ #else FT_DEFINE_SERVICEDESCREC6( cff_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, @@ -704,7 +832,7 @@ FT_Module_Interface result; - /* CFF_SERVICES_GET derefers `library' in PIC mode */ + /* CFF_SERVICES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC if ( !driver ) return NULL; @@ -744,9 +872,10 @@ FT_DEFINE_DRIVER( cff_driver_class, - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | - FT_MODULE_DRIVER_HAS_HINTER, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER | + FT_MODULE_DRIVER_HINTS_LIGHTLY, sizeof ( CFF_DriverRec ), "cff", @@ -755,31 +884,29 @@ 0, /* module-specific interface */ - cff_driver_init, - cff_driver_done, - cff_get_interface, + cff_driver_init, /* FT_Module_Constructor module_init */ + cff_driver_done, /* FT_Module_Destructor module_done */ + cff_get_interface, /* FT_Module_Requester get_interface */ - /* now the specific driver fields */ sizeof ( TT_FaceRec ), sizeof ( CFF_SizeRec ), sizeof ( CFF_GlyphSlotRec ), - cff_face_init, - cff_face_done, - cff_size_init, - cff_size_done, - cff_slot_init, - cff_slot_done, - - cff_glyph_load, + cff_face_init, /* FT_Face_InitFunc init_face */ + cff_face_done, /* FT_Face_DoneFunc done_face */ + cff_size_init, /* FT_Size_InitFunc init_size */ + cff_size_done, /* FT_Size_DoneFunc done_size */ + cff_slot_init, /* FT_Slot_InitFunc init_slot */ + cff_slot_done, /* FT_Slot_DoneFunc done_slot */ - cff_get_kerning, - 0, /* FT_Face_AttachFunc */ - cff_get_advances, + cff_glyph_load, /* FT_Slot_LoadFunc load_glyph */ - cff_size_request, + cff_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + cff_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ - CFF_SIZE_SELECT + cff_size_request, /* FT_Size_RequestFunc request_size */ + CFF_SIZE_SELECT /* FT_Size_SelectFunc select_size */ ) diff --git a/drivers/freetype/freetype/src/cff/cffdrivr.h b/drivers/freetype/src/cff/cffdrivr.h index 50e8138701..d7b0598374 100644 --- a/drivers/freetype/freetype/src/cff/cffdrivr.h +++ b/drivers/freetype/src/cff/cffdrivr.h @@ -4,7 +4,7 @@ /* */ /* High-level OpenType driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFDRIVER_H__ -#define __CFFDRIVER_H__ +#ifndef CFFDRIVER_H_ +#define CFFDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFDRIVER_H__ */ +#endif /* CFFDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cfferrs.h b/drivers/freetype/src/cff/cfferrs.h index 801d73ec6b..e7fc6eb71c 100644 --- a/drivers/freetype/freetype/src/cff/cfferrs.h +++ b/drivers/freetype/src/cff/cfferrs.h @@ -4,7 +4,7 @@ /* */ /* CFF error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __CFFERRS_H__ -#define __CFFERRS_H__ +#ifndef CFFERRS_H_ +#define CFFERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CFF_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __CFFERRS_H__ */ +#endif /* CFFERRS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cffgload.c b/drivers/freetype/src/cff/cffgload.c index 6a8494fa9f..752c18ed92 100644 --- a/drivers/freetype/freetype/src/cff/cffgload.c +++ b/drivers/freetype/src/cff/cffgload.c @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -273,8 +273,8 @@ builder->current = &loader->current.outline; FT_GlyphLoader_Rewind( loader ); - builder->hints_globals = 0; - builder->hints_funcs = 0; + builder->hints_globals = NULL; + builder->hints_funcs = NULL; if ( hinting && size ) { @@ -434,7 +434,7 @@ goto Exit; } - FT_TRACE3(( "glyph index %d (subfont %d):\n", glyph_index, fd_index )); + FT_TRACE3(( " in subfont %d:\n", fd_index )); sub = cff->subfonts[fd_index]; @@ -447,10 +447,6 @@ builder->hints_globals = (void *)internal->subfonts[fd_index]; } } -#ifdef FT_DEBUG_LEVEL_TRACE - else - FT_TRACE3(( "glyph index %d:\n", glyph_index )); -#endif decoder->num_locals = sub->local_subrs_index.count; decoder->locals = sub->local_subrs; @@ -650,7 +646,7 @@ for ( n = 0; n < cff->num_glyphs; n++ ) { if ( cff->charset.sids[n] == glyph_sid ) - return n; + return (FT_Int)n; } return -1; @@ -676,7 +672,7 @@ *pointer = (FT_Byte*)data.pointer; - *length = data.length; + *length = (FT_ULong)data.length; return error; } @@ -684,7 +680,7 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ { - CFF_Font cff = (CFF_Font)(face->extra.data); + CFF_Font cff = (CFF_Font)(face->extra.data); return cff_index_access_element( &cff->charstrings_index, glyph_index, @@ -707,11 +703,11 @@ /* callback function. */ if ( face->root.internal->incremental_interface ) { - FT_Data data; + FT_Data data; data.pointer = *pointer; - data.length = length; + data.length = (FT_Int)length; face->root.internal->incremental_interface->funcs->free_glyph_data( face->root.internal->incremental_interface->object, &data ); @@ -823,14 +819,14 @@ FT_GlyphLoader_Prepare( builder->loader ); /* First load `bchar' in builder */ - error = cff_get_glyph_data( face, bchar_index, + error = cff_get_glyph_data( face, (FT_UInt)bchar_index, &charstring, &charstring_len ); if ( !error ) { /* the seac operator must not be nested */ decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, - charstring_len ); + charstring_len, 0 ); decoder->seac = FALSE; cff_free_glyph_data( face, &charstring, charstring_len ); @@ -853,14 +849,14 @@ builder->pos_y = ady; /* Now load `achar' on top of the base outline. */ - error = cff_get_glyph_data( face, achar_index, + error = cff_get_glyph_data( face, (FT_UInt)achar_index, &charstring, &charstring_len ); if ( !error ) { /* the seac operator must not be nested */ decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, - charstring_len ); + charstring_len, 0 ); decoder->seac = FALSE; cff_free_glyph_data( face, &charstring, charstring_len ); @@ -899,13 +895,17 @@ /* */ /* charstring_len :: The length in bytes of the charstring stream. */ /* */ + /* in_dict :: Set to 1 if function is called from top or */ + /* private DICT (needed for Multiple Master CFFs). */ + /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) cff_decoder_parse_charstrings( CFF_Decoder* decoder, FT_Byte* charstring_base, - FT_ULong charstring_len ) + FT_ULong charstring_len, + FT_Bool in_dict ) { FT_Error error; CFF_Decoder_Zone* zone; @@ -917,6 +917,10 @@ FT_Fixed* stack; FT_Int charstring_type = decoder->cff->top_font.font_dict.charstring_type; + FT_UShort num_designs = + decoder->cff->top_font.font_dict.num_designs; + FT_UShort num_axes = + decoder->cff->top_font.font_dict.num_axes; T2_Hints_Funcs hinter; @@ -926,10 +930,10 @@ decoder->read_width = 1; /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ - (FT_PtrDist)(char*)&decoder ^ - (FT_PtrDist)(char*)&charstring_base ) & - FT_ULONG_MAX ) ; + seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed ^ + (FT_Offset)(char*)&decoder ^ + (FT_Offset)(char*)&charstring_base ) & + FT_ULONG_MAX ); seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; if ( seed == 0 ) seed = 0x7384; @@ -1245,6 +1249,44 @@ if ( op == cff_op_unknown ) continue; + /* in Multiple Master CFFs, T2 charstrings can appear in */ + /* dictionaries, but some operators are prohibited */ + if ( in_dict ) + { + switch ( op ) + { + case cff_op_hstem: + case cff_op_vstem: + case cff_op_vmoveto: + case cff_op_rlineto: + case cff_op_hlineto: + case cff_op_vlineto: + case cff_op_rrcurveto: + case cff_op_hstemhm: + case cff_op_hintmask: + case cff_op_cntrmask: + case cff_op_rmoveto: + case cff_op_hmoveto: + case cff_op_vstemhm: + case cff_op_rcurveline: + case cff_op_rlinecurve: + case cff_op_vvcurveto: + case cff_op_hhcurveto: + case cff_op_vhcurveto: + case cff_op_hvcurveto: + case cff_op_hflex: + case cff_op_flex: + case cff_op_hflex1: + case cff_op_flex1: + case cff_op_callsubr: + case cff_op_callgsubr: + goto MM_Error; + + default: + break; + } + } + /* check arguments */ req_args = cff_argument_counts[op]; if ( req_args & CFF_COUNT_CHECK_WIDTH ) @@ -1282,7 +1324,9 @@ case cff_op_endchar: /* If there is a width specified for endchar, we either have */ /* 1 argument or 5 arguments. We like to argue. */ - set_width_ok = ( num_args == 5 ) || ( num_args == 1 ); + set_width_ok = in_dict + ? 0 + : ( ( num_args == 5 ) || ( num_args == 1 ) ); break; default: @@ -1377,12 +1421,12 @@ { if ( op == cff_op_hintmask ) hinter->hintmask( hinter->hints, - builder->current->n_points, - decoder->num_hints, + (FT_UInt)builder->current->n_points, + (FT_UInt)decoder->num_hints, ip ); else hinter->counter( hinter->hints, - decoder->num_hints, + (FT_UInt)decoder->num_hints, ip ); } @@ -1975,6 +2019,10 @@ return error; case cff_op_endchar: + /* in dictionaries, `endchar' simply indicates end of data */ + if ( in_dict ) + return error; + FT_TRACE4(( " endchar\n" )); /* We are going to emulate the seac operator. */ @@ -1993,23 +2041,22 @@ } else { - if ( !error ) - error = FT_Err_Ok; - cff_builder_close_contour( builder ); /* close hints recording session */ if ( hinter ) { if ( hinter->close( hinter->hints, - builder->current->n_points ) ) + (FT_UInt)builder->current->n_points ) ) goto Syntax_Error; /* apply hints to the loaded glyph outline now */ - hinter->apply( hinter->hints, - builder->current, - (PSH_Globals)builder->hints_globals, - decoder->hint_mode ); + error = hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + if ( error ) + goto Fail; } /* add current outline to the glyph slot */ @@ -2087,15 +2134,14 @@ if ( args[0] > 0 ) { - FT_Int count = 9; - FT_Fixed root = args[0]; + FT_Fixed root = args[0]; FT_Fixed new_root; for (;;) { new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; - if ( new_root == root || count <= 0 ) + if ( new_root == root ) break; root = new_root; } @@ -2204,6 +2250,10 @@ FT_TRACE4(( " put\n" )); + /* the Type2 specification before version 16-March-2000 */ + /* didn't give a hard-coded size limit of the temporary */ + /* storage array; instead, an argument of the */ + /* `MultipleMaster' operator set the size */ if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) decoder->buildchar[idx] = val; } @@ -2226,14 +2276,68 @@ break; case cff_op_store: - FT_TRACE4(( " store\n")); + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ - goto Unimplemented; + /* since we currently don't handle interpolation of multiple */ + /* master fonts, this is a no-op */ + FT_TRACE4(( " store\n")); + break; case cff_op_load: - FT_TRACE4(( " load\n" )); + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ + { + FT_Int reg_idx = (FT_Int)args[0]; + FT_Int idx = (FT_Int)args[1]; + FT_Int count = (FT_Int)args[2]; - goto Unimplemented; + + FT_TRACE4(( " load\n" )); + + /* since we currently don't handle interpolation of multiple */ + /* master fonts, we store a vector [1 0 0 ...] in the */ + /* temporary storage array regardless of the Registry index */ + if ( reg_idx >= 0 && reg_idx <= 2 && + idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS && + count >= 0 && count <= num_axes ) + { + FT_Int end, i; + + + end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS ); + + if ( idx < end ) + decoder->buildchar[idx] = 1 << 16; + + for ( i = idx + 1; i < end; i++ ) + decoder->buildchar[i] = 0; + } + } + break; + + case cff_op_blend: + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ + { + FT_Int num_results = (FT_Int)( args[0] >> 16 ); + + + FT_TRACE4(( " blend\n" )); + + if ( num_results < 0 ) + goto Syntax_Error; + + if ( num_results * (FT_Int)num_designs > num_args ) + goto Stack_Underflow; + + /* since we currently don't handle interpolation of multiple */ + /* master fonts, return the `num_results' values of the */ + /* first master */ + args -= num_results * ( num_designs - 1 ); + num_args -= num_results * ( num_designs - 1 ); + } + break; case cff_op_dotsection: /* this operator is deprecated and ignored by the parser */ @@ -2363,11 +2467,23 @@ } break; - case cff_op_eq: + case cff_op_not: { FT_Fixed cond = !args[0]; + FT_TRACE4(( " not\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_eq: + { + FT_Fixed cond = args[0] == args[1]; + + FT_TRACE4(( " eq\n" )); args[0] = cond ? 0x10000L : 0; @@ -2394,7 +2510,9 @@ decoder->locals_bias ); - FT_TRACE4(( " callsubr(%d)\n", idx )); + FT_TRACE4(( " callsubr (idx %d, entering level %d)\n", + idx, + zone - decoder->zones + 1 )); if ( idx >= decoder->num_locals ) { @@ -2436,7 +2554,9 @@ decoder->globals_bias ); - FT_TRACE4(( " callgsubr(%d)\n", idx )); + FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n", + idx, + zone - decoder->zones + 1 )); if ( idx >= decoder->num_globals ) { @@ -2473,7 +2593,8 @@ break; case cff_op_return: - FT_TRACE4(( " return\n" )); + FT_TRACE4(( " return (leaving level %d)\n", + decoder->zone - decoder->zones )); if ( decoder->zone <= decoder->zones ) { @@ -2489,7 +2610,6 @@ break; default: - Unimplemented: FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); if ( ip[-1] == 12 ) @@ -2513,6 +2633,11 @@ Fail: return error; + MM_Error: + FT_TRACE4(( "cff_decoder_parse_charstrings:" + " invalid opcode found in top DICT charstring\n")); + return FT_THROW( Invalid_File_Format ); + Syntax_Error: FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); return FT_THROW( Invalid_File_Format ); @@ -2586,7 +2711,8 @@ if ( !error ) error = cff_decoder_parse_charstrings( &decoder, charstring, - charstring_len ); + charstring_len, + 0 ); cff_free_glyph_data( face, &charstring, &charstring_len ); } @@ -2674,7 +2800,7 @@ error = sfnt->load_sbit_image( face, size->strike_index, glyph_index, - (FT_Int)load_flags, + (FT_UInt)load_flags, stream, &glyph->root.bitmap, &metrics ); @@ -2715,23 +2841,23 @@ /* compute linear advance widths */ - ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, - glyph_index, - &dummy, - &advance ); + (void)( (SFNT_Service)face->sfnt )->get_metrics( face, 0, + glyph_index, + &dummy, + &advance ); glyph->root.linearHoriAdvance = advance; has_vertical_info = FT_BOOL( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ); - /* get the vertical metrics from the vtmx table if we have one */ + /* get the vertical metrics from the vmtx table if we have one */ if ( has_vertical_info ) { - ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, - glyph_index, - &dummy, - &advance ); + (void)( (SFNT_Service)face->sfnt )->get_metrics( face, 1, + glyph_index, + &dummy, + &advance ); glyph->root.linearVertAdvance = advance; } else @@ -2762,16 +2888,16 @@ /* this scaling is only relevant if the PS hinter isn't active */ if ( cff->num_subfonts ) { - FT_ULong top_upm, sub_upm; - FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, - glyph_index ); + FT_Long top_upm, sub_upm; + FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, + glyph_index ); if ( fd_index >= cff->num_subfonts ) fd_index = (FT_Byte)( cff->num_subfonts - 1 ); - top_upm = cff->top_font.font_dict.units_per_em; - sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; + top_upm = (FT_Long)cff->top_font.font_dict.units_per_em; + sub_upm = (FT_Long)cff->subfonts[fd_index]->font_dict.units_per_em; font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; @@ -2837,7 +2963,8 @@ if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE ) error = cff_decoder_parse_charstrings( &decoder, charstring, - charstring_len ); + charstring_len, + 0 ); else #endif { @@ -2872,7 +2999,7 @@ /* fonts. */ if ( face->root.internal->incremental_interface ) { - glyph->root.control_data = 0; + glyph->root.control_data = NULL; glyph->root.control_len = 0; } else @@ -2889,7 +3016,7 @@ { glyph->root.control_data = csindex->bytes + csindex->offsets[glyph_index] - 1; - glyph->root.control_len = charstring_len; + glyph->root.control_len = (FT_Long)charstring_len; } } @@ -2949,19 +3076,36 @@ { FT_BBox cbox; FT_Glyph_Metrics* metrics = &glyph->root.metrics; - FT_Vector advance; FT_Bool has_vertical_info; - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.glyph_width; - glyph->root.linearHoriAdvance = decoder.glyph_width; + if ( face->horizontal.number_Of_HMetrics ) + { + FT_Short horiBearingX = 0; + FT_UShort horiAdvance = 0; + + + ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, + glyph_index, + &horiBearingX, + &horiAdvance ); + metrics->horiAdvance = horiAdvance; + metrics->horiBearingX = horiBearingX; + glyph->root.linearHoriAdvance = horiAdvance; + } + else + { + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = decoder.glyph_width; + glyph->root.linearHoriAdvance = decoder.glyph_width; + } + glyph->root.internal->glyph_transformed = 0; has_vertical_info = FT_BOOL( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ); - /* get the vertical metrics from the vtmx table if we have one */ + /* get the vertical metrics from the vmtx table if we have one */ if ( has_vertical_info ) { FT_Short vertBearingY = 0; @@ -2996,26 +3140,27 @@ glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; - if ( !( font_matrix.xx == 0x10000L && - font_matrix.yy == 0x10000L && - font_matrix.xy == 0 && - font_matrix.yx == 0 ) ) + /* apply the font matrix, if any */ + if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L || + font_matrix.xy != 0 || font_matrix.yx != 0 ) + { FT_Outline_Transform( &glyph->root.outline, &font_matrix ); - if ( !( font_offset.x == 0 && - font_offset.y == 0 ) ) - FT_Outline_Translate( &glyph->root.outline, - font_offset.x, font_offset.y ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, + font_matrix.xx ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, + font_matrix.yy ); + } - advance.x = metrics->horiAdvance; - advance.y = 0; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->horiAdvance = advance.x + font_offset.x; + if ( font_offset.x || font_offset.y ) + { + FT_Outline_Translate( &glyph->root.outline, + font_offset.x, + font_offset.y ); - advance.x = 0; - advance.y = metrics->vertAdvance; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->vertAdvance = advance.y + font_offset.y; + metrics->horiAdvance += font_offset.x; + metrics->vertAdvance += font_offset.y; + } if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling ) { diff --git a/drivers/freetype/freetype/src/cff/cffgload.h b/drivers/freetype/src/cff/cffgload.h index 41df7db692..b875fbed90 100644 --- a/drivers/freetype/freetype/src/cff/cffgload.h +++ b/drivers/freetype/src/cff/cffgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2004, 2006-2009, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFGLOAD_H__ -#define __CFFGLOAD_H__ +#ifndef CFFGLOAD_H_ +#define CFFGLOAD_H_ #include <ft2build.h> @@ -29,7 +29,12 @@ FT_BEGIN_HEADER #define CFF_MAX_OPERANDS 48 -#define CFF_MAX_SUBRS_CALLS 32 +#define CFF_MAX_SUBRS_CALLS 16 /* maximum subroutine nesting; */ + /* only 10 are allowed but there exist */ + /* fonts like `HiraKakuProN-W3.ttf' */ + /* (Hiragino Kaku Gothic ProN W3; */ + /* 8.2d6e1; 2014-12-19) that exceed */ + /* this limit */ #define CFF_MAX_TRANS_ELEMENTS 32 @@ -222,7 +227,8 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) cff_decoder_parse_charstrings( CFF_Decoder* decoder, FT_Byte* charstring_base, - FT_ULong charstring_len ); + FT_ULong charstring_len, + FT_Bool in_dict ); #endif FT_LOCAL( FT_Error ) @@ -234,7 +240,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFGLOAD_H__ */ +#endif /* CFFGLOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cffload.c b/drivers/freetype/src/cff/cffload.c index 64b497168d..3d1bda97b9 100644 --- a/drivers/freetype/freetype/src/cff/cffload.c +++ b/drivers/freetype/src/cff/cffload.c @@ -4,7 +4,7 @@ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -357,7 +357,7 @@ case 3: for ( ; p < p_end; p += 3, poff++ ) - poff[0] = FT_PEEK_OFF3( p ); + poff[0] = FT_PEEK_UOFF3( p ); break; default: @@ -382,13 +382,15 @@ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table, - FT_Byte** pool ) + FT_Byte** pool, + FT_ULong* pool_size ) { FT_Error error = FT_Err_Ok; FT_Memory memory = idx->stream->memory; FT_Byte** t = NULL; FT_Byte* new_bytes = NULL; + FT_ULong new_size; *table = NULL; @@ -400,10 +402,11 @@ goto Exit; } - if ( idx->count > 0 && - !FT_NEW_ARRAY( t, idx->count + 1 ) && - ( !pool || !FT_ALLOC( new_bytes, - idx->data_size + idx->count ) ) ) + new_size = idx->data_size + idx->count; + + if ( idx->count > 0 && + !FT_NEW_ARRAY( t, idx->count + 1 ) && + ( !pool || !FT_ALLOC( new_bytes, new_size ) ) ) { FT_ULong n, cur_offset; FT_ULong extra = 0; @@ -414,7 +417,7 @@ cur_offset = idx->offsets[0] - 1; /* sanity check */ - if ( cur_offset >= idx->data_size ) + if ( cur_offset != 0 ) { FT_TRACE0(( "cff_index_get_pointers:" " invalid first offset value %d set to zero\n", @@ -432,11 +435,11 @@ FT_ULong next_offset = idx->offsets[n] - 1; - /* empty slot + two sanity checks for invalid offset tables */ - if ( next_offset == 0 || - next_offset < cur_offset || - ( next_offset >= idx->data_size && n < idx->count ) ) + /* two sanity checks for invalid offset tables */ + if ( next_offset < cur_offset ) next_offset = cur_offset; + else if ( next_offset > idx->data_size ) + next_offset = idx->data_size; if ( !pool ) t[n] = org_bytes + next_offset; @@ -459,6 +462,8 @@ if ( pool ) *pool = new_bytes; + if ( pool_size ) + *pool_size = new_size; } Exit: @@ -501,8 +506,8 @@ { element++; off2 = cff_index_read_offset( idx, &error ); - } - while ( off2 == 0 && element < idx->count ); + + } while ( off2 == 0 && element < idx->count ); } } else /* use offsets table */ @@ -689,6 +694,13 @@ if ( FT_READ_USHORT( num_ranges ) ) goto Exit; + if ( !num_ranges ) + { + FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + fdselect->data_size = num_ranges * 3 + 2; Load_Data: @@ -719,7 +731,7 @@ break; case 3: - /* first, compare to cache */ + /* first, compare to the cache */ if ( (FT_UInt)( glyph_index - fdselect->cache_first ) < fdselect->cache_count ) { @@ -727,7 +739,7 @@ break; } - /* then, lookup the ranges array */ + /* then, look up the ranges array */ { FT_Byte* p = fdselect->data; FT_Byte* p_limit = p + fdselect->data_size; @@ -750,7 +762,7 @@ /* update cache */ fdselect->cache_first = first; - fdselect->cache_count = limit-first; + fdselect->cache_count = limit - first; fdselect->cache_fd = fd2; break; } @@ -802,7 +814,7 @@ /* When multiple GIDs map to the same CID, we choose the lowest */ /* GID. This is not described in any spec, but it matches the */ /* behaviour of recent Acroread versions. */ - for ( j = num_glyphs - 1; j >= 0 ; j-- ) + for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- ) charset->cids[charset->sids[j]] = (FT_UShort)j; charset->max_cid = max_cid; @@ -864,8 +876,8 @@ FT_UShort glyph_sid; - /* If the the offset is greater than 2, we have to parse the */ - /* charset table. */ + /* If the offset is greater than 2, we have to parse the charset */ + /* table. */ if ( offset > 2 ) { FT_UInt j; @@ -1309,7 +1321,12 @@ CFF_Private priv = &font->private_dict; - cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); + cff_parser_init( &parser, + CFF_CODE_TOPDICT, + &font->font_dict, + library, + 0, + 0 ); /* set defaults */ FT_MEM_ZERO( top, sizeof ( *top ) ); @@ -1363,7 +1380,12 @@ priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); - cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); + cff_parser_init( &parser, + CFF_CODE_PRIVATE, + priv, + library, + top->num_designs, + top->num_axes ); if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || FT_FRAME_ENTER( font->font_dict.private_size ) ) @@ -1393,7 +1415,7 @@ goto Exit; error = cff_index_get_pointers( &font->local_subrs_index, - &font->local_subrs, NULL ); + &font->local_subrs, NULL, NULL ); if ( error ) goto Exit; } @@ -1440,7 +1462,7 @@ FT_ULong base_offset; CFF_FontRecDict dict; CFF_IndexRec string_index; - FT_Int subfont_index; + FT_UInt subfont_index; FT_ZERO( font ); @@ -1471,16 +1493,17 @@ /* read the name, top dict, string and global subrs index */ if ( FT_SET_ERROR( cff_index_init( &font->name_index, - stream, 0 ) ) || + stream, 0 ) ) || FT_SET_ERROR( cff_index_init( &font->font_dict_index, - stream, 0 ) ) || + stream, 0 ) ) || FT_SET_ERROR( cff_index_init( &string_index, - stream, 1 ) ) || + stream, 1 ) ) || FT_SET_ERROR( cff_index_init( &font->global_subrs_index, - stream, 1 ) ) || + stream, 1 ) ) || FT_SET_ERROR( cff_index_get_pointers( &string_index, &font->strings, - &font->string_pool ) ) ) + &font->string_pool, + &font->string_pool_size ) ) ) goto Exit; font->num_strings = string_index.count; @@ -1488,9 +1511,9 @@ if ( pure_cff ) { /* well, we don't really forget the `disabled' fonts... */ - subfont_index = face_index; + subfont_index = (FT_UInt)( face_index & 0xFFFF ); - if ( subfont_index >= (FT_Int)font->name_index.count ) + if ( face_index > 0 && subfont_index >= font->name_index.count ) { FT_ERROR(( "cff_font_load:" " invalid subfont index for pure CFF font (%d)\n", @@ -1607,7 +1630,7 @@ font->num_glyphs = font->charstrings_index.count; error = cff_index_get_pointers( &font->global_subrs_index, - &font->global_subrs, NULL ); + &font->global_subrs, NULL, NULL ); if ( error ) goto Exit; diff --git a/drivers/freetype/freetype/src/cff/cffload.h b/drivers/freetype/src/cff/cffload.h index 804961964b..1dd07baf11 100644 --- a/drivers/freetype/freetype/src/cff/cffload.h +++ b/drivers/freetype/src/cff/cffload.h @@ -4,7 +4,7 @@ /* */ /* OpenType & CFF data/program tables loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2007, 2008, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFLOAD_H__ -#define __CFFLOAD_H__ +#ifndef CFFLOAD_H_ +#define CFFLOAD_H_ #include <ft2build.h> @@ -77,7 +77,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFLOAD_H__ */ +#endif /* CFFLOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cffobjs.c b/drivers/freetype/src/cff/cffobjs.c index dd750d1041..0f0769677f 100644 --- a/drivers/freetype/freetype/src/cff/cffobjs.c +++ b/drivers/freetype/src/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -226,8 +226,8 @@ CFF_Font font = (CFF_Font)face->extra.data; CFF_Internal internal = (CFF_Internal)size->internal; - FT_ULong top_upm = font->top_font.font_dict.units_per_em; - FT_UInt i; + FT_Long top_upm = (FT_Long)font->top_font.font_dict.units_per_em; + FT_UInt i; funcs->set_scale( internal->topfont, @@ -237,7 +237,7 @@ for ( i = font->num_subfonts; i > 0; i-- ) { CFF_SubFont sub = font->subfonts[i - 1]; - FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Long sub_upm = (FT_Long)sub->font_dict.units_per_em; FT_Pos x_scale, y_scale; @@ -298,8 +298,8 @@ CFF_Font font = (CFF_Font)cffface->extra.data; CFF_Internal internal = (CFF_Internal)size->internal; - FT_ULong top_upm = font->top_font.font_dict.units_per_em; - FT_UInt i; + FT_Long top_upm = (FT_Long)font->top_font.font_dict.units_per_em; + FT_UInt i; funcs->set_scale( internal->topfont, @@ -309,7 +309,7 @@ for ( i = font->num_subfonts; i > 0; i-- ) { CFF_SubFont sub = font->subfonts[i - 1]; - FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Long sub_upm = (FT_Long)sub->font_dict.units_per_em; FT_Pos x_scale, y_scale; @@ -342,7 +342,7 @@ FT_LOCAL_DEF( void ) cff_slot_done( FT_GlyphSlot slot ) { - slot->internal->glyph_hints = 0; + slot->internal->glyph_hints = NULL; } @@ -583,16 +583,24 @@ if ( error ) goto Exit; + /* if we are performing a simple font format check, exit immediately */ + /* (this is here for pure CFF) */ + if ( face_index < 0 ) + { + cffface->num_faces = (FT_Long)cff->num_faces; + return FT_Err_Ok; + } + cff->pshinter = pshinter; cff->psnames = psnames; - cffface->face_index = face_index; + cffface->face_index = face_index & 0xFFFF; /* Complement the root flags with some interesting information. */ /* Note that this is only necessary for pure CFF and CEF fonts; */ /* SFNT based fonts use the `name' table instead. */ - cffface->num_glyphs = cff->num_glyphs; + cffface->num_glyphs = (FT_Long)cff->num_glyphs; dict = &cff->top_font.font_dict; @@ -617,11 +625,44 @@ FT_TRACE4(( "SIDs\n" )); /* dump string index, including default strings for convenience */ - for ( idx = 0; idx < cff->num_strings + 390; idx++ ) + for ( idx = 0; idx <= 390; idx++ ) { s = cff_index_get_sid_string( cff, idx ); if ( s ) - FT_TRACE4((" %5d %s\n", idx, s )); + FT_TRACE4(( " %5d %s\n", idx, s )); + } + + /* In Multiple Master CFFs, two SIDs hold the Normalize Design */ + /* Vector (NDV) and Convert Design Vector (CDV) charstrings, */ + /* which may contain NULL bytes in the middle of the data, too. */ + /* We thus access `cff->strings' directly. */ + for ( idx = 1; idx < cff->num_strings; idx++ ) + { + FT_Byte* s1 = cff->strings[idx - 1]; + FT_Byte* s2 = cff->strings[idx]; + FT_PtrDist s1len = s2 - s1 - 1; /* without the final NULL byte */ + FT_PtrDist l; + + + FT_TRACE4(( " %5d ", idx + 390 )); + for ( l = 0; l < s1len; l++ ) + FT_TRACE4(( "%c", s1[l] )); + FT_TRACE4(( "\n" )); + } + + /* print last element */ + if ( cff->num_strings ) + { + FT_Byte* s1 = cff->strings[cff->num_strings - 1]; + FT_Byte* s2 = cff->string_pool + cff->string_pool_size; + FT_PtrDist s1len = s2 - s1 - 1; + FT_PtrDist l; + + + FT_TRACE4(( " %5d ", cff->num_strings + 390 )); + for ( l = 0; l < s1len; l++ ) + FT_TRACE4(( "%c", s1[l] )); + FT_TRACE4(( "\n" )); } } #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -629,10 +670,11 @@ if ( !dict->has_font_matrix ) dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; - /* Normalize the font matrix so that `matrix->xx' is 1; the */ - /* scaling is done with `units_per_em' then (at this point, */ - /* it already contains the scaling factor, but without */ - /* normalization of the matrix). */ + /* Normalize the font matrix so that `matrix->yy' is 1; if */ + /* it is zero, we use `matrix->yx' instead. The scaling is */ + /* done with `units_per_em' then (at this point, it already */ + /* contains the scaling factor, but without normalization */ + /* of the matrix). */ /* */ /* Note that the offsets must be expressed in integer font */ /* units. */ @@ -641,12 +683,15 @@ FT_Matrix* matrix = &dict->font_matrix; FT_Vector* offset = &dict->font_offset; FT_ULong* upm = &dict->units_per_em; - FT_Fixed temp = FT_ABS( matrix->yy ); + FT_Fixed temp; + temp = matrix->yy ? FT_ABS( matrix->yy ) + : FT_ABS( matrix->yx ); + if ( temp != 0x10000L ) { - *upm = FT_DivFix( *upm, temp ); + *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp ); matrix->xx = FT_DivFix( matrix->xx, temp ); matrix->yx = FT_DivFix( matrix->yx, temp ); @@ -682,7 +727,8 @@ if ( top->has_font_matrix ) { if ( top->units_per_em > 1 && sub->units_per_em > 1 ) - scaling = FT_MIN( top->units_per_em, sub->units_per_em ); + scaling = (FT_Long)FT_MIN( top->units_per_em, + sub->units_per_em ); else scaling = 1; @@ -693,9 +739,10 @@ &top->font_matrix, scaling ); - sub->units_per_em = FT_MulDiv( sub->units_per_em, - top->units_per_em, - scaling ); + sub->units_per_em = (FT_ULong) + FT_MulDiv( (FT_Long)sub->units_per_em, + (FT_Long)top->units_per_em, + scaling ); } } else @@ -709,11 +756,14 @@ matrix = &sub->font_matrix; offset = &sub->font_offset; upm = &sub->units_per_em; - temp = FT_ABS( matrix->yy ); + + temp = matrix->yy ? FT_ABS( matrix->yy ) + : FT_ABS( matrix->yx ); + if ( temp != 0x10000L ) { - *upm = FT_DivFix( *upm, temp ); + *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp ); matrix->xx = FT_DivFix( matrix->xx, temp ); matrix->yx = FT_DivFix( matrix->yx, temp ); @@ -733,13 +783,13 @@ /* set up num_faces */ - cffface->num_faces = cff->num_faces; + cffface->num_faces = (FT_Long)cff->num_faces; /* compute number of glyphs */ if ( dict->cid_registry != 0xFFFFU ) - cffface->num_glyphs = cff->charset.max_cid + 1; + cffface->num_glyphs = (FT_Long)( cff->charset.max_cid + 1 ); else - cffface->num_glyphs = cff->charstrings_index.count; + cffface->num_glyphs = (FT_Long)cff->charstrings_index.count; /* set global bbox, as well as EM size */ cffface->bbox.xMin = dict->font_bbox.xMin >> 16; @@ -763,7 +813,9 @@ (FT_Short)( dict->underline_thickness >> 16 ); /* retrieve font family & style name */ - cffface->family_name = cff_index_get_name( cff, face_index ); + cffface->family_name = cff_index_get_name( + cff, + (FT_UInt)( face_index & 0xFFFF ) ); if ( cffface->family_name ) { char* full = cff_index_get_sid_string( cff, @@ -866,7 +918,7 @@ flags |= FT_FACE_FLAG_KERNING; #endif - cffface->face_flags = flags; + cffface->face_flags |= flags; /*******************************************************************/ /* */ @@ -943,16 +995,6 @@ if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) goto Exit; -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "cff_face_init: no Unicode cmap is found, " - "and too many subtables (%d) to add synthesized cmap\n", - nn )); - goto Exit; - } -#endif - /* we didn't find a Unicode charmap -- synthesize one */ cmaprec.face = cffface; cmaprec.platform_id = TT_PLATFORM_MICROSOFT; @@ -973,15 +1015,6 @@ cffface->charmap = cffface->charmaps[nn]; Skip_Unicode: -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( nn > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "cff_face_init: Unicode cmap is found, " - "but too many preceding subtables (%d) to access\n", - nn - 1 )); - goto Exit; - } -#endif if ( encoding->count > 0 ) { FT_CMap_Class clazz; @@ -1055,13 +1088,23 @@ CFF_Driver driver = (CFF_Driver)module; - /* set default property values */ + /* set default property values, cf. `ftcffdrv.h' */ #ifdef CFF_CONFIG_OPTION_OLD_ENGINE - driver->hinting_engine = FT_CFF_HINTING_FREETYPE; + driver->hinting_engine = FT_CFF_HINTING_FREETYPE; #else - driver->hinting_engine = FT_CFF_HINTING_ADOBE; + driver->hinting_engine = FT_CFF_HINTING_ADOBE; #endif - driver->no_stem_darkening = FALSE; + + driver->no_stem_darkening = TRUE; + + driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; + driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2; + driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2; + driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3; + driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3; + driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4; + driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4; return FT_Err_Ok; } diff --git a/drivers/freetype/freetype/src/cff/cffobjs.h b/drivers/freetype/src/cff/cffobjs.h index b375c20c74..9dc77536bd 100644 --- a/drivers/freetype/freetype/src/cff/cffobjs.h +++ b/drivers/freetype/src/cff/cffobjs.h @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (specification). */ /* */ -/* Copyright 1996-2004, 2006-2008, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFOBJS_H__ -#define __CFFOBJS_H__ +#ifndef CFFOBJS_H_ +#define CFFOBJS_H_ #include <ft2build.h> @@ -121,6 +121,8 @@ FT_BEGIN_HEADER FT_UInt hinting_engine; FT_Bool no_stem_darkening; + FT_Int darken_params[8]; + } CFF_DriverRec; @@ -177,7 +179,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFOBJS_H__ */ +#endif /* CFFOBJS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cffparse.c b/drivers/freetype/src/cff/cffparse.c index 96222120b0..a4f986b67c 100644 --- a/drivers/freetype/freetype/src/cff/cffparse.c +++ b/drivers/freetype/src/cff/cffparse.c @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (body) */ /* */ -/* Copyright 1996-2004, 2007-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,6 +23,7 @@ #include "cfferrs.h" #include "cffpic.h" +#include "cffgload.h" /*************************************************************************/ @@ -39,7 +40,9 @@ cff_parser_init( CFF_Parser parser, FT_UInt code, void* object, - FT_Library library) + FT_Library library, + FT_UShort num_designs, + FT_UShort num_axes ) { FT_MEM_ZERO( parser, sizeof ( *parser ) ); @@ -47,6 +50,8 @@ parser->object_code = code; parser->object = object; parser->library = library; + parser->num_designs = num_designs; + parser->num_axes = num_axes; } @@ -66,7 +71,6 @@ goto Bad; val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] ); - p += 2; } else if ( v == 29 ) { @@ -77,7 +81,6 @@ ( (FT_ULong)p[1] << 16 ) | ( (FT_ULong)p[2] << 8 ) | (FT_ULong)p[3] ); - p += 4; } else if ( v < 247 ) { @@ -89,7 +92,6 @@ goto Bad; val = ( v - 247 ) * 256 + p[0] + 108; - p++; } else { @@ -97,7 +99,6 @@ goto Bad; val = -( v - 251 ) * 256 - p[0] - 108; - p++; } Exit: @@ -133,7 +134,7 @@ FT_Long* scaling ) { FT_Byte* p = start; - FT_UInt nib; + FT_Int nib; FT_UInt phase; FT_Long result, number, exponent; @@ -170,7 +171,7 @@ } /* Get the nibble. */ - nib = ( p[0] >> phase ) & 0xF; + nib = (FT_Int)( p[0] >> phase ) & 0xF; phase = 4 - phase; if ( nib == 0xE ) @@ -192,7 +193,7 @@ } /* Read fraction part, if any. */ - if ( nib == 0xa ) + if ( nib == 0xA ) for (;;) { /* If we entered this iteration with phase == 4, we need */ @@ -520,7 +521,11 @@ if ( parser->top >= parser->stack + 6 ) { - FT_Long scaling; + FT_Fixed values[6]; + FT_Long scalings[6]; + + FT_Long min_scaling, max_scaling; + int i; error = FT_Err_Ok; @@ -529,22 +534,36 @@ /* We expect a well-formed font matrix, this is, the matrix elements */ /* `xx' and `yy' are of approximately the same magnitude. To avoid */ - /* loss of precision, we use the magnitude of element `xx' to scale */ - /* all other elements. The scaling factor is then contained in the */ - /* `units_per_em' value. */ + /* loss of precision, we use the magnitude of the largest matrix */ + /* element to scale all other elements. The scaling factor is then */ + /* contained in the `units_per_em' value. */ - matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); + max_scaling = FT_LONG_MIN; + min_scaling = FT_LONG_MAX; - scaling = -scaling; + for ( i = 0; i < 6; i++ ) + { + values[i] = cff_parse_fixed_dynamic( data++, &scalings[i] ); + if ( values[i] ) + { + if ( scalings[i] > max_scaling ) + max_scaling = scalings[i]; + if ( scalings[i] < min_scaling ) + min_scaling = scalings[i]; + } + } - if ( scaling < 0 || scaling > 9 ) + if ( max_scaling < -9 || + max_scaling > 0 || + ( max_scaling - min_scaling ) < 0 || + ( max_scaling - min_scaling ) > 9 ) { /* Return default matrix in case of unlikely values. */ FT_TRACE1(( "cff_parse_font_matrix:" - " strange scaling value for xx element (%d),\n" + " strange scaling values (minimum %d, maximum %d),\n" " " - " using default matrix\n", scaling )); + " using default matrix\n", min_scaling, max_scaling )); matrix->xx = 0x10000L; matrix->yx = 0; @@ -557,13 +576,42 @@ goto Exit; } - matrix->yx = cff_parse_fixed_scaled( data++, scaling ); - matrix->xy = cff_parse_fixed_scaled( data++, scaling ); - matrix->yy = cff_parse_fixed_scaled( data++, scaling ); - offset->x = cff_parse_fixed_scaled( data++, scaling ); - offset->y = cff_parse_fixed_scaled( data, scaling ); + for ( i = 0; i < 6; i++ ) + { + FT_Fixed value = values[i]; + FT_Long divisor, half_divisor; + + + if ( !value ) + continue; + + divisor = power_tens[max_scaling - scalings[i]]; + half_divisor = divisor >> 1; + + if ( value < 0 ) + { + if ( FT_LONG_MIN + half_divisor < value ) + values[i] = ( value - half_divisor ) / divisor; + else + values[i] = FT_LONG_MIN / divisor; + } + else + { + if ( FT_LONG_MAX - half_divisor > value ) + values[i] = ( value + half_divisor ) / divisor; + else + values[i] = FT_LONG_MAX / divisor; + } + } + + matrix->xx = values[0]; + matrix->yx = values[1]; + matrix->xy = values[2]; + matrix->yy = values[3]; + offset->x = values[4]; + offset->y = values[5]; - *upm = power_tens[scaling]; + *upm = (FT_ULong)power_tens[-max_scaling]; FT_TRACE4(( " [%f %f %f %f %f %f]\n", (double)matrix->xx / *upm / 65536, @@ -621,14 +669,84 @@ if ( parser->top >= parser->stack + 2 ) { - dict->private_size = cff_parse_num( data++ ); - dict->private_offset = cff_parse_num( data ); + FT_Long tmp; + + + tmp = cff_parse_num( data++ ); + if ( tmp < 0 ) + { + FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + dict->private_size = (FT_ULong)tmp; + + tmp = cff_parse_num( data ); + if ( tmp < 0 ) + { + FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + dict->private_offset = (FT_ULong)tmp; + FT_TRACE4(( " %lu %lu\n", dict->private_size, dict->private_offset )); error = FT_Err_Ok; } + Fail: + return error; + } + + + /* The `MultipleMaster' operator comes before any */ + /* top DICT operators that contain T2 charstrings. */ + + static FT_Error + cff_parse_multiple_master( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Error error; + + +#ifdef FT_DEBUG_LEVEL_TRACE + /* beautify tracing message */ + if ( ft_trace_levels[FT_COMPONENT] < 4 ) + FT_TRACE1(( "Multiple Master CFFs not supported yet," + " handling first master design only\n" )); + else + FT_TRACE1(( " (not supported yet," + " handling first master design only)\n" )); +#endif + + error = FT_ERR( Stack_Underflow ); + + /* currently, we handle only the first argument */ + if ( parser->top >= parser->stack + 5 ) + { + FT_Long num_designs = cff_parse_num( parser->stack ); + + + if ( num_designs > 16 || num_designs < 2 ) + { + FT_ERROR(( "cff_parse_multiple_master:" + " Invalid number of designs\n" )); + error = FT_THROW( Invalid_File_Format ); + } + else + { + dict->num_designs = (FT_UShort)num_designs; + dict->num_axes = (FT_UShort)( parser->top - parser->stack - 4 ); + + parser->num_designs = dict->num_designs; + parser->num_axes = dict->num_axes; + + error = FT_Err_Ok; + } + } + return error; } @@ -956,7 +1074,7 @@ if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) goto Stack_Overflow; - *parser->top ++ = p; + *parser->top++ = p; /* now, skip it */ if ( v == 30 ) @@ -985,6 +1103,136 @@ else if ( v > 246 ) p += 1; } +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + else if ( v == 31 ) + { + /* a Type 2 charstring */ + + CFF_Decoder decoder; + CFF_FontRec cff_rec; + FT_Byte* charstring_base; + FT_ULong charstring_len; + + FT_Fixed* stack; + FT_Byte* q; + + + charstring_base = ++p; + + /* search `endchar' operator */ + for (;;) + { + if ( p >= limit ) + goto Exit; + if ( *p == 14 ) + break; + p++; + } + + charstring_len = (FT_ULong)( p - charstring_base ) + 1; + + /* construct CFF_Decoder object */ + FT_MEM_ZERO( &decoder, sizeof ( decoder ) ); + FT_MEM_ZERO( &cff_rec, sizeof ( cff_rec ) ); + + cff_rec.top_font.font_dict.num_designs = parser->num_designs; + cff_rec.top_font.font_dict.num_axes = parser->num_axes; + decoder.cff = &cff_rec; + + error = cff_decoder_parse_charstrings( &decoder, + charstring_base, + charstring_len, + 1 ); + + /* Now copy the stack data in the temporary decoder object, */ + /* converting it back to charstring number representations */ + /* (this is ugly, I know). */ + /* */ + /* We overwrite the original top DICT charstring under the */ + /* assumption that the charstring representation of the result */ + /* of `cff_decoder_parse_charstrings' is shorter, which should */ + /* be always true. */ + + q = charstring_base - 1; + stack = decoder.stack; + + while ( stack < decoder.top ) + { + FT_ULong num; + FT_Bool neg; + + + if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) + goto Stack_Overflow; + + *parser->top++ = q; + + if ( *stack < 0 ) + { + num = (FT_ULong)-*stack; + neg = 1; + } + else + { + num = (FT_ULong)*stack; + neg = 0; + } + + if ( num & 0xFFFFU ) + { + if ( neg ) + num = (FT_ULong)-num; + + *q++ = 255; + *q++ = ( num & 0xFF000000U ) >> 24; + *q++ = ( num & 0x00FF0000U ) >> 16; + *q++ = ( num & 0x0000FF00U ) >> 8; + *q++ = num & 0x000000FFU; + } + else + { + num >>= 16; + + if ( neg ) + { + if ( num <= 107 ) + *q++ = (FT_Byte)( 139 - num ); + else if ( num <= 1131 ) + { + *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 ); + *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); + } + else + { + num = (FT_ULong)-num; + + *q++ = 28; + *q++ = (FT_Byte)( num >> 8 ); + *q++ = (FT_Byte)( num & 0xFF ); + } + } + else + { + if ( num <= 107 ) + *q++ = (FT_Byte)( num + 139 ); + else if ( num <= 1131 ) + { + *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 ); + *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); + } + else + { + *q++ = 28; + *q++ = (FT_Byte)( num >> 8 ); + *q++ = (FT_Byte)( num & 0xFF ); + } + } + } + + stack++; + } + } +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ else { /* This is not a number, hence it's an operator. Compute its code */ diff --git a/drivers/freetype/freetype/src/cff/cffparse.h b/drivers/freetype/src/cff/cffparse.h index 61d91ed2e2..a95970edcb 100644 --- a/drivers/freetype/freetype/src/cff/cffparse.h +++ b/drivers/freetype/src/cff/cffparse.h @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (specification) */ /* */ -/* Copyright 1996-2003, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFF_PARSE_H__ -#define __CFF_PARSE_H__ +#ifndef CFFPARSE_H_ +#define CFFPARSE_H_ #include <ft2build.h> @@ -36,16 +36,19 @@ FT_BEGIN_HEADER typedef struct CFF_ParserRec_ { - FT_Library library; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* cursor; + FT_Library library; + FT_Byte* start; + FT_Byte* limit; + FT_Byte* cursor; - FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; - FT_Byte** top; + FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; + FT_Byte** top; - FT_UInt object_code; - void* object; + FT_UInt object_code; + void* object; + + FT_UShort num_designs; /* a copy of `CFF_FontRecDict->num_designs' */ + FT_UShort num_axes; /* a copy of `CFF_FontRecDict->num_axes' */ } CFF_ParserRec, *CFF_Parser; @@ -54,7 +57,9 @@ FT_BEGIN_HEADER cff_parser_init( CFF_Parser parser, FT_UInt code, void* object, - FT_Library library); + FT_Library library, + FT_UShort num_designs, + FT_UShort num_axes ); FT_LOCAL( FT_Error ) cff_parser_run( CFF_Parser parser, @@ -100,7 +105,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFF_PARSE_H__ */ +#endif /* CFFPARSE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cffpic.c b/drivers/freetype/src/cff/cffpic.c index f22e4f0d53..a0bc34fd5f 100644 --- a/drivers/freetype/freetype/src/cff/cffpic.c +++ b/drivers/freetype/src/cff/cffpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for cff module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/cff/cffpic.h b/drivers/freetype/src/cff/cffpic.h index 50bab4c173..bed6b35a86 100644 --- a/drivers/freetype/freetype/src/cff/cffpic.h +++ b/drivers/freetype/src/cff/cffpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for cff module. */ /* */ -/* Copyright 2009, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,10 @@ /***************************************************************************/ -#ifndef __CFFPIC_H__ -#define __CFFPIC_H__ +#ifndef CFFPIC_H_ +#define CFFPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H @@ -49,6 +47,8 @@ FT_BEGIN_HEADER #include FT_SERVICE_PROPERTIES_H +FT_BEGIN_HEADER + typedef struct CffModulePIC_ { FT_ServiceDescRec* cff_services; @@ -96,13 +96,13 @@ FT_BEGIN_HEADER FT_Error cff_driver_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __CFFPIC_H__ */ +#endif /* CFFPIC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/cfftoken.h b/drivers/freetype/src/cff/cfftoken.h index bcb4276a78..22637c780b 100644 --- a/drivers/freetype/freetype/src/cff/cfftoken.h +++ b/drivers/freetype/src/cff/cfftoken.h @@ -4,7 +4,7 @@ /* */ /* CFF token definitions (specification only). */ /* */ -/* Copyright 1996-2003, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,6 +38,9 @@ CFF_FIELD_NUM ( 13, unique_id, "UniqueID" ) CFF_FIELD_CALLBACK( 5, font_bbox, "FontBBox" ) CFF_FIELD_NUM ( 0x108, stroke_width, "StrokeWidth" ) +#if 0 + CFF_FIELD_DELTA ( 14, xuid, 16, "XUID" ) +#endif CFF_FIELD_NUM ( 15, charset_offset, "charset" ) CFF_FIELD_NUM ( 16, encoding_offset, "Encoding" ) CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" ) @@ -48,8 +51,13 @@ #if 0 CFF_FIELD_STRING ( 0x116, base_font_name, "BaseFontName" ) CFF_FIELD_DELTA ( 0x117, base_font_blend, 16, "BaseFontBlend" ) +#endif + + /* the next two operators were removed from the Type2 specification */ + /* in version 16-March-2000 */ CFF_FIELD_CALLBACK( 0x118, multiple_master, "MultipleMaster" ) - CFF_FIELD_CALLBACK( 0x119, blend_axis_types, "BlendAxisTypes" ) +#if 0 + CFF_FIELD_CALLBACK( 0x11A, blend_axis_types, "BlendAxisTypes" ) #endif CFF_FIELD_CALLBACK( 0x11E, cid_ros, "ROS" ) diff --git a/drivers/freetype/freetype/src/cff/cfftypes.h b/drivers/freetype/src/cff/cfftypes.h index 8727446664..4426c7e4f1 100644 --- a/drivers/freetype/freetype/src/cff/cfftypes.h +++ b/drivers/freetype/src/cff/cfftypes.h @@ -5,7 +5,7 @@ /* Basic OpenType/CFF type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2003, 2006-2008, 2010-2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __CFFTYPES_H__ -#define __CFFTYPES_H__ +#ifndef CFFTYPES_H_ +#define CFFTYPES_H_ #include <ft2build.h> @@ -145,6 +145,12 @@ FT_BEGIN_HEADER FT_ULong cid_fd_select_offset; FT_UInt cid_font_name; + /* the next fields come from the data of the deprecated */ + /* `MultipleMaster' operator; they are needed to parse the (also */ + /* deprecated) `blend' operator in Type 2 charstrings */ + FT_UShort num_designs; + FT_UShort num_axes; + } CFF_FontRecDictRec, *CFF_FontRecDict; @@ -250,6 +256,7 @@ FT_BEGIN_HEADER FT_UInt num_strings; FT_Byte** strings; FT_Byte* string_pool; + FT_ULong string_pool_size; CFF_SubFontRec top_font; FT_UInt num_subfonts; @@ -278,7 +285,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFTYPES_H__ */ +#endif /* CFFTYPES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cff/module.mk b/drivers/freetype/src/cff/module.mk index ef1391c279..1b4781afed 100644 --- a/drivers/freetype/freetype/src/cff/module.mk +++ b/drivers/freetype/src/cff/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/cff/rules.mk b/drivers/freetype/src/cff/rules.mk index 13115c2550..92f68b1ede 100644 --- a/drivers/freetype/freetype/src/cff/rules.mk +++ b/drivers/freetype/src/cff/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2001, 2003, 2011, 2013 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -18,7 +18,10 @@ CFF_DIR := $(SRC_DIR)/cff -CFF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CFF_DIR)) +CFF_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(CFF_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # CFF driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/cid/Jamfile b/drivers/freetype/src/cid/Jamfile index ebeaed54ea..4b4eea17d9 100644 --- a/drivers/freetype/freetype/src/cid/Jamfile +++ b/drivers/freetype/src/cid/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/cid Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,12 @@ SubDir FT2_TOP $(FT2_SRC_DIR) cid ; if $(FT2_MULTI) { - _sources = cidobjs cidload cidgload cidriver cidparse ; + _sources = cidgload + cidload + cidobjs + cidparse + cidriver + ; } else { diff --git a/drivers/freetype/freetype/src/cid/ciderrs.h b/drivers/freetype/src/cid/ciderrs.h index ef13155504..1dc98c7cdd 100644 --- a/drivers/freetype/freetype/src/cid/ciderrs.h +++ b/drivers/freetype/src/cid/ciderrs.h @@ -4,7 +4,7 @@ /* */ /* CID error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __CIDERRS_H__ -#define __CIDERRS_H__ +#ifndef CIDERRS_H_ +#define CIDERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CID_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __CIDERRS_H__ */ +#endif /* CIDERRS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cid/cidgload.c b/drivers/freetype/src/cid/cidgload.c index a1a8658693..c7b95593ee 100644 --- a/drivers/freetype/freetype/src/cid/cidgload.c +++ b/drivers/freetype/src/cid/cidgload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2007, 2009, 2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -44,10 +44,10 @@ CID_Face face = (CID_Face)decoder->builder.face; CID_FaceInfo cid = &face->cid; FT_Byte* p; - FT_UInt fd_select; + FT_ULong fd_select; FT_Stream stream = face->cid_stream; FT_Error error = FT_Err_Ok; - FT_Byte* charstring = 0; + FT_Byte* charstring = NULL; FT_Memory memory = face->root.memory; FT_ULong glyph_length = 0; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -58,7 +58,7 @@ #endif - FT_TRACE4(( "cid_load_glyph: glyph index %d\n", glyph_index )); + FT_TRACE1(( "cid_load_glyph: glyph index %d\n", glyph_index )); #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -75,11 +75,11 @@ goto Exit; p = (FT_Byte*)glyph_data.pointer; - fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); if ( glyph_data.length != 0 ) { - glyph_length = glyph_data.length - cid->fd_bytes; + glyph_length = (FT_ULong)( glyph_data.length - cid->fd_bytes ); (void)FT_ALLOC( charstring, glyph_length ); if ( !error ) ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, @@ -99,8 +99,8 @@ /* For ordinary fonts read the CID font dictionary index */ /* and charstring offset from the CIDMap. */ { - FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; - FT_ULong off1; + FT_UInt entry_len = (FT_UInt)( cid->fd_bytes + cid->gd_bytes ); + FT_ULong off1, off2; if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + @@ -108,18 +108,23 @@ FT_FRAME_ENTER( 2 * entry_len ) ) goto Exit; - p = (FT_Byte*)stream->cursor; - fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); - off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); - p += cid->fd_bytes; - glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; + p = (FT_Byte*)stream->cursor; + fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + off1 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + p += cid->fd_bytes; + off2 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); FT_FRAME_EXIT(); - if ( fd_select >= (FT_UInt)cid->num_dicts ) + if ( fd_select >= (FT_ULong)cid->num_dicts || + off2 > stream->size || + off1 > off2 ) { + FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); error = FT_THROW( Invalid_Offset ); goto Exit; } + + glyph_length = off2 - off1; if ( glyph_length == 0 ) goto Exit; if ( FT_ALLOC( charstring, glyph_length ) ) @@ -133,13 +138,14 @@ { CID_FaceDict dict; CID_Subrs cid_subrs = face->subrs + fd_select; - FT_Int cs_offset; + FT_UInt cs_offset; /* Set up subrs */ - decoder->num_subrs = cid_subrs->num_subrs; - decoder->subrs = cid_subrs->code; - decoder->subrs_len = 0; + decoder->num_subrs = cid_subrs->num_subrs; + decoder->subrs = cid_subrs->code; + decoder->subrs_len = 0; + decoder->subrs_hash = NULL; /* Set up font matrix */ dict = cid->font_dicts + fd_select; @@ -151,7 +157,13 @@ /* Decode the charstring. */ /* Adjustment for seed bytes. */ - cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); + cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0; + if ( cs_offset > glyph_length ) + { + FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); + error = FT_THROW( Invalid_Offset ); + goto Exit; + } /* Decrypt only if lenIV >= 0. */ if ( decoder->lenIV >= 0 ) @@ -159,11 +171,9 @@ error = decoder->funcs.parse_charstrings( decoder, charstring + cs_offset, - (FT_Int)glyph_length - cs_offset ); + glyph_length - cs_offset ); } - FT_FREE( charstring ); - #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ @@ -188,6 +198,8 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ Exit: + FT_FREE( charstring ); + return error; } @@ -357,7 +369,6 @@ { FT_BBox cbox; FT_Glyph_Metrics* metrics = &cidglyph->metrics; - FT_Vector advance; /* copy the _unscaled_ advance width */ @@ -377,22 +388,27 @@ if ( cidsize->metrics.y_ppem < 24 ) cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; - /* apply the font matrix */ - FT_Outline_Transform( &cidglyph->outline, &font_matrix ); + /* apply the font matrix, if any */ + if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L || + font_matrix.xy != 0 || font_matrix.yx != 0 ) + { + FT_Outline_Transform( &cidglyph->outline, &font_matrix ); - FT_Outline_Translate( &cidglyph->outline, - font_offset.x, - font_offset.y ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, + font_matrix.xx ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, + font_matrix.yy ); + } - advance.x = metrics->horiAdvance; - advance.y = 0; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->horiAdvance = advance.x + font_offset.x; + if ( font_offset.x || font_offset.y ) + { + FT_Outline_Translate( &cidglyph->outline, + font_offset.x, + font_offset.y ); - advance.x = 0; - advance.y = metrics->vertAdvance; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->vertAdvance = advance.y + font_offset.y; + metrics->horiAdvance += font_offset.x; + metrics->vertAdvance += font_offset.y; + } if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) { diff --git a/drivers/freetype/freetype/src/cid/cidgload.h b/drivers/freetype/src/cid/cidgload.h index a0a91bfea8..62d664b3af 100644 --- a/drivers/freetype/freetype/src/cid/cidgload.h +++ b/drivers/freetype/src/cid/cidgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2004 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDGLOAD_H__ -#define __CIDGLOAD_H__ +#ifndef CIDGLOAD_H_ +#define CIDGLOAD_H_ #include <ft2build.h> @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDGLOAD_H__ */ +#endif /* CIDGLOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cid/cidload.c b/drivers/freetype/src/cid/cidload.c index f2a18ea510..d4f1ad1a7f 100644 --- a/drivers/freetype/freetype/src/cid/cidload.c +++ b/drivers/freetype/src/cid/cidload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (body). */ /* */ -/* Copyright 1996-2006, 2009, 2011-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,7 +38,7 @@ /* read a single offset */ - FT_LOCAL_DEF( FT_Long ) + FT_LOCAL_DEF( FT_ULong ) cid_get_offset( FT_Byte* *start, FT_Byte offsize ) { @@ -53,7 +53,7 @@ } *start = p; - return (FT_Long)result; + return result; } @@ -150,8 +150,6 @@ cid_parse_font_matrix( CID_Face face, CID_Parser* parser ) { - FT_Matrix* matrix; - FT_Vector* offset; CID_FaceDict dict; FT_Face root = (FT_Face)&face->root; FT_Fixed temp[6]; @@ -160,29 +158,41 @@ if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) { + FT_Matrix* matrix; + FT_Vector* offset; + FT_Int result; + + dict = face->cid.font_dicts + parser->num_dict; matrix = &dict->font_matrix; offset = &dict->font_offset; - (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); + /* input is scaled by 1000 to accommodate default FontMatrix */ + result = cid_parser_to_fixed_array( parser, 6, temp, 3 ); - temp_scale = FT_ABS( temp[3] ); + if ( result < 6 ) + return FT_THROW( Invalid_File_Format ); - /* Set Units per EM based on FontMatrix values. We set the value to */ - /* 1000 / temp_scale, because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed, from psobjs.c). */ + temp_scale = FT_ABS( temp[3] ); - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + if ( temp_scale == 0 ) + { + FT_ERROR(( "cid_parse_font_matrix: invalid font matrix\n" )); + return FT_THROW( Invalid_File_Format ); + } - /* we need to scale the values by 1.0/temp[3] */ + /* atypical case */ if ( temp_scale != 0x10000L ) { + /* set units per EM based on FontMatrix values */ + root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + temp[0] = FT_DivFix( temp[0], temp_scale ); temp[1] = FT_DivFix( temp[1], temp_scale ); temp[2] = FT_DivFix( temp[2], temp_scale ); temp[4] = FT_DivFix( temp[4], temp_scale ); temp[5] = FT_DivFix( temp[5], temp_scale ); - temp[3] = 0x10000L; + temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L; } matrix->xx = temp[0]; @@ -195,8 +205,7 @@ offset->y = temp[5] >> 16; } - return FT_Err_Ok; /* this is a callback function; */ - /* we must return an error code */ + return FT_Err_Ok; } @@ -206,11 +215,43 @@ { CID_FaceInfo cid = &face->cid; FT_Memory memory = face->root.memory; + FT_Stream stream = parser->stream; FT_Error error = FT_Err_Ok; FT_Long num_dicts; num_dicts = cid_parser_to_int( parser ); + if ( num_dicts < 0 ) + { + FT_ERROR(( "parse_fd_array: invalid number of dictionaries\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* + * A single entry in the FDArray must (at least) contain the following + * structure elements. + * + * %ADOBeginFontDict 18 + * X dict begin 13 + * /FontMatrix [X X X X] 22 + * /Private X dict begin 22 + * end 4 + * end 4 + * %ADOEndFontDict 16 + * + * This needs 18+13+22+22+4+4+16=99 bytes or more. Normally, you also + * need a `dup X' at the very beginning and a `put' at the end, so a + * rough guess using 100 bytes as the minimum is justified. + */ + if ( (FT_ULong)num_dicts > stream->size / 100 ) + { + FT_TRACE0(( "parse_fd_array: adjusting FDArray size" + " (from %d to %d)\n", + num_dicts, + stream->size / 100 )); + num_dicts = (FT_Long)( stream->size / 100 ); + } if ( !cid->font_dicts ) { @@ -220,7 +261,7 @@ if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) goto Exit; - cid->num_dicts = (FT_UInt)num_dicts; + cid->num_dicts = num_dicts; /* don't forget to set a few defaults */ for ( n = 0; n < cid->num_dicts; n++ ) @@ -279,7 +320,7 @@ cid_parse_dict( CID_Face face, CID_Loader* loader, FT_Byte* base, - FT_Long size ) + FT_ULong size ) { CID_Parser* parser = &loader->parser; @@ -331,11 +372,11 @@ /* look for immediates */ if ( *cur == '/' && cur + 2 < limit ) { - FT_PtrDist len; + FT_UInt len; cur++; - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); if ( len > 0 && len < 22 ) { @@ -352,10 +393,10 @@ if ( !name ) break; - if ( cur[0] == name[0] && - len == (FT_PtrDist)ft_strlen( (const char*)name ) ) + if ( cur[0] == name[0] && + len == ft_strlen( (const char*)name ) ) { - FT_PtrDist n; + FT_UInt n; for ( n = 1; n < len; n++ ) @@ -380,7 +421,14 @@ cur = parser->root.cursor; } + + if ( !face->cid.num_dicts ) + { + FT_ERROR(( "cid_parse_dict: No font dictionary found\n" )); + return FT_THROW( Invalid_File_Format ); + } } + return parser->root.error; } @@ -396,7 +444,7 @@ FT_Int n; CID_Subrs subr; FT_UInt max_offsets = 0; - FT_ULong* offsets = 0; + FT_ULong* offsets = NULL; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -413,13 +461,6 @@ FT_Byte* p; - /* Check for possible overflow. */ - if ( num_subrs == FT_UINT_MAX ) - { - error = FT_THROW( Syntax_Error ); - goto Fail; - } - /* reallocate offsets array if needed */ if ( num_subrs + 1 > max_offsets ) { @@ -439,8 +480,8 @@ } /* read the subrmap's offsets */ - if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || - FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) + if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || + FT_FRAME_ENTER( ( num_subrs + 1 ) * (FT_UInt)dict->sd_bytes ) ) goto Fail; p = (FT_Byte*)stream->cursor; @@ -452,14 +493,25 @@ /* offsets must be ordered */ for ( count = 1; count <= num_subrs; count++ ) if ( offsets[count - 1] > offsets[count] ) + { + FT_ERROR(( "cid_read_subrs: offsets are not ordered\n" )); + error = FT_THROW( Invalid_File_Format ); goto Fail; + } + + if ( offsets[num_subrs] > stream->size - cid->data_offset ) + { + FT_ERROR(( "cid_read_subrs: too large `subrs' offsets\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } /* now, compute the size of subrs charstrings, */ /* allocate, and read them */ data_len = offsets[num_subrs] - offsets[0]; if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || - FT_ALLOC( subr->code[0], data_len ) ) + FT_ALLOC( subr->code[0], data_len ) ) goto Fail; if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || @@ -489,7 +541,7 @@ } } - subr->num_subrs = num_subrs; + subr->num_subrs = (FT_Int)num_subrs; } Exit: @@ -535,7 +587,7 @@ static FT_Error cid_hex_to_binary( FT_Byte* data, - FT_Long data_len, + FT_ULong data_len, FT_ULong offset, CID_Face face ) { @@ -639,6 +691,12 @@ CID_Parser* parser; FT_Memory memory = face->root.memory; FT_Error error; + FT_Int n; + + CID_FaceInfo cid = &face->cid; + + FT_ULong binary_length; + FT_ULong entry_len; cid_init_loader( &loader, face ); @@ -663,6 +721,17 @@ if ( parser->binary_length ) { + if ( parser->binary_length > + face->root.stream->size - parser->data_offset ) + { + FT_TRACE0(( "cid_face_open: adjusting length of binary data\n" + " (from %d to %d bytes)\n", + parser->binary_length, + face->root.stream->size - parser->data_offset )); + parser->binary_length = face->root.stream->size - + parser->data_offset; + } + /* we must convert the data section from hexadecimal to binary */ if ( FT_ALLOC( face->binary_data, parser->binary_length ) || cid_hex_to_binary( face->binary_data, parser->binary_length, @@ -671,14 +740,95 @@ FT_Stream_OpenMemory( face->cid_stream, face->binary_data, parser->binary_length ); - face->cid.data_offset = 0; + cid->data_offset = 0; } else { - *face->cid_stream = *face->root.stream; - face->cid.data_offset = loader.parser.data_offset; + *face->cid_stream = *face->root.stream; + cid->data_offset = loader.parser.data_offset; + } + + /* sanity tests */ + + if ( cid->fd_bytes < 0 || cid->gd_bytes < 1 ) + { + FT_ERROR(( "cid_parse_dict:" + " Invalid `FDBytes' or `GDBytes' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* allow at most 32bit offsets */ + if ( cid->fd_bytes > 4 || cid->gd_bytes > 4 ) + { + FT_ERROR(( "cid_parse_dict:" + " Values of `FDBytes' or `GDBytes' larger than 4\n" + " " + " are not supported\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + binary_length = face->cid_stream->size - cid->data_offset; + entry_len = (FT_ULong)( cid->fd_bytes + cid->gd_bytes ); + + for ( n = 0; n < cid->num_dicts; n++ ) + { + CID_FaceDict dict = cid->font_dicts + n; + + + if ( dict->sd_bytes < 0 ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SDBytes' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( dict->sd_bytes > 4 ) + { + FT_ERROR(( "cid_parse_dict:" + " Values of `SDBytes' larger than 4" + " are not supported\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( dict->subrmap_offset > binary_length ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SubrMapOffset' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* `num_subrs' is scanned as a signed integer */ + if ( (FT_Int)dict->num_subrs < 0 || + ( dict->sd_bytes && + dict->num_subrs > ( binary_length - dict->subrmap_offset ) / + (FT_UInt)dict->sd_bytes ) ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SubrCount' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } + + if ( cid->cidmap_offset > binary_length ) + { + FT_ERROR(( "cid_parse_dict: Invalid `CIDMapOffset' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( entry_len && + cid->cid_count > + ( binary_length - cid->cidmap_offset ) / entry_len ) + { + FT_ERROR(( "cid_parse_dict: Invalid `CIDCount' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; } + /* we can now safely proceed */ error = cid_read_subrs( face ); Exit: diff --git a/drivers/freetype/freetype/src/cid/cidload.h b/drivers/freetype/src/cid/cidload.h index 8c172ffee2..680f0d8fc5 100644 --- a/drivers/freetype/freetype/src/cid/cidload.h +++ b/drivers/freetype/src/cid/cidload.h @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDLOAD_H__ -#define __CIDLOAD_H__ +#ifndef CIDLOAD_H_ +#define CIDLOAD_H_ #include <ft2build.h> @@ -36,7 +36,7 @@ FT_BEGIN_HEADER } CID_Loader; - FT_LOCAL( FT_Long ) + FT_LOCAL( FT_ULong ) cid_get_offset( FT_Byte** start, FT_Byte offsize ); @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDLOAD_H__ */ +#endif /* CIDLOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cid/cidobjs.c b/drivers/freetype/src/cid/cidobjs.c index 46555e2dc8..2d2600fd4c 100644 --- a/drivers/freetype/freetype/src/cid/cidobjs.c +++ b/drivers/freetype/src/cid/cidobjs.c @@ -4,7 +4,7 @@ /* */ /* CID objects manager (body). */ /* */ -/* Copyright 1996-2006, 2008, 2010-2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -49,7 +49,7 @@ FT_LOCAL_DEF( void ) cid_slot_done( FT_GlyphSlot slot ) { - slot->internal->glyph_hints = 0; + slot->internal->glyph_hints = NULL; } @@ -122,7 +122,7 @@ if ( funcs ) funcs->destroy( (PSH_Globals)cidsize->internal ); - cidsize->internal = 0; + cidsize->internal = NULL; } } @@ -243,8 +243,8 @@ FT_FREE( cid->registry ); FT_FREE( cid->ordering ); - cidface->family_name = 0; - cidface->style_name = 0; + cidface->family_name = NULL; + cidface->style_name = NULL; FT_FREE( face->binary_data ); FT_FREE( face->cid_stream ); @@ -334,7 +334,7 @@ /* check the face index */ /* XXX: handle CID fonts with more than a single face */ - if ( face_index != 0 ) + if ( ( face_index & 0xFFFF ) != 0 ) { FT_ERROR(( "cid_face_init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); @@ -351,13 +351,14 @@ PS_FontInfo info = &cid->font_info; - cidface->num_glyphs = cid->cid_count; + cidface->num_glyphs = (FT_Long)cid->cid_count; cidface->num_charmaps = 0; - cidface->face_index = face_index; - cidface->face_flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ - FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ - FT_FACE_FLAG_HINTER; /* has native hinter */ + cidface->face_index = face_index & 0xFFFF; + + cidface->face_flags |= FT_FACE_FLAG_SCALABLE | /* scalable outlines */ + FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ + FT_FACE_FLAG_HINTER; /* has native hinter */ if ( info->is_fixed_pitch ) cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; @@ -420,7 +421,7 @@ /* no embedded bitmap support */ cidface->num_fixed_sizes = 0; - cidface->available_sizes = 0; + cidface->available_sizes = NULL; cidface->bbox.xMin = cid->font_bbox.xMin >> 16; cidface->bbox.yMin = cid->font_bbox.yMin >> 16; diff --git a/drivers/freetype/freetype/src/cid/cidobjs.h b/drivers/freetype/src/cid/cidobjs.h index aee346d1c8..5dd377a9f8 100644 --- a/drivers/freetype/freetype/src/cid/cidobjs.h +++ b/drivers/freetype/src/cid/cidobjs.h @@ -4,7 +4,7 @@ /* */ /* CID objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDOBJS_H__ -#define __CIDOBJS_H__ +#ifndef CIDOBJS_H_ +#define CIDOBJS_H_ #include <ft2build.h> @@ -148,7 +148,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDOBJS_H__ */ +#endif /* CIDOBJS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cid/cidparse.c b/drivers/freetype/src/cid/cidparse.c index 53df3155d1..73aca2ac6a 100644 --- a/drivers/freetype/freetype/src/cid/cidparse.c +++ b/drivers/freetype/src/cid/cidparse.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (body). */ /* */ -/* Copyright 1996-2007, 2009, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -47,6 +47,12 @@ /*************************************************************************/ +#define STARTDATA "StartData" +#define STARTDATA_LEN ( sizeof ( STARTDATA ) - 1 ) +#define SFNTS "/sfnts" +#define SFNTS_LEN ( sizeof ( SFNTS ) - 1 ) + + FT_LOCAL_DEF( FT_Error ) cid_parser_new( CID_Parser* parser, FT_Stream stream, @@ -85,51 +91,79 @@ /* now, read the rest of the file until we find */ /* `StartData' or `/sfnts' */ { - FT_Byte buffer[256 + 10]; - FT_Long read_len = 256 + 10; /* same as signed FT_Stream->size */ - FT_Byte* p = buffer; + /* + * The algorithm is as follows (omitting the case with less than 256 + * bytes to fill for simplicity). + * + * 1. Fill the buffer with 256 + STARTDATA_LEN bytes. + * + * 2. Search for the STARTDATA and SFNTS strings at positions + * buffer[0], buffer[1], ..., + * buffer[255 + STARTDATA_LEN - SFNTS_LEN]. + * + * 3. Move the last STARTDATA_LEN bytes to buffer[0]. + * + * 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN. + * + * 5. Repeat with step 2. + * + */ + FT_Byte buffer[256 + STARTDATA_LEN + 1]; + + /* values for the first loop */ + FT_ULong read_len = 256 + STARTDATA_LEN; + FT_ULong read_offset = 0; + FT_Byte* p = buffer; for ( offset = FT_STREAM_POS(); ; offset += 256 ) { - FT_Long stream_len; /* same as signed FT_Stream->size */ + FT_ULong stream_len; stream_len = stream->size - FT_STREAM_POS(); - if ( stream_len == 0 ) - { - FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } read_len = FT_MIN( read_len, stream_len ); if ( FT_STREAM_READ( p, read_len ) ) goto Exit; - if ( read_len < 256 ) - p[read_len] = '\0'; + /* ensure that we do not compare with data beyond the buffer */ + p[read_len] = '\0'; - limit = p + read_len - 10; + limit = p + read_len - SFNTS_LEN; for ( p = buffer; p < limit; p++ ) { - if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) + if ( p[0] == 'S' && + ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 ) { /* save offset of binary data after `StartData' */ - offset += (FT_ULong)( p - buffer + 10 ); + offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN; goto Found; } - else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) + else if ( p[1] == 's' && + ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 ) { - offset += (FT_ULong)( p - buffer + 7 ); + offset += (FT_ULong)( p - buffer ) + SFNTS_LEN; goto Found; } } - FT_MEM_MOVE( buffer, p, 10 ); - read_len = 256; - p = buffer + 10; + if ( read_offset + read_len < STARTDATA_LEN ) + { + FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + FT_MEM_MOVE( buffer, + buffer + read_offset + read_len - STARTDATA_LEN, + STARTDATA_LEN ); + + /* values for the next loop */ + read_len = 256; + read_offset = STARTDATA_LEN; + p = buffer + read_offset; } } @@ -165,7 +199,7 @@ limit = parser->root.limit; cur = parser->root.cursor; - while ( cur < limit ) + while ( cur < limit - SFNTS_LEN ) { if ( parser->root.error ) { @@ -173,16 +207,28 @@ goto Exit; } - if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) + if ( cur[0] == 'S' && + cur < limit - STARTDATA_LEN && + ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 ) { if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) - parser->binary_length = ft_atol( (const char *)arg2 ); + { + FT_Long tmp = ft_atol( (const char *)arg2 ); + + + if ( tmp < 0 ) + { + FT_ERROR(( "cid_parser_new: invalid length of hex data\n" )); + error = FT_THROW( Invalid_File_Format ); + } + else + parser->binary_length = (FT_ULong)tmp; + } - limit = parser->root.limit; - cur = parser->root.cursor; goto Exit; } - else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 ) + else if ( cur[1] == 's' && + ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 ) { FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" )); error = FT_THROW( Unknown_File_Format ); @@ -207,6 +253,12 @@ } +#undef STARTDATA +#undef STARTDATA_LEN +#undef SFNTS +#undef SFNTS_LEN + + FT_LOCAL_DEF( void ) cid_parser_done( CID_Parser* parser ) { diff --git a/drivers/freetype/freetype/src/cid/cidparse.h b/drivers/freetype/src/cid/cidparse.h index ca37deab93..7268dc6ae8 100644 --- a/drivers/freetype/freetype/src/cid/cidparse.h +++ b/drivers/freetype/src/cid/cidparse.h @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDPARSE_H__ -#define __CIDPARSE_H__ +#ifndef CIDPARSE_H_ +#define CIDPARSE_H_ #include <ft2build.h> @@ -64,11 +64,11 @@ FT_BEGIN_HEADER FT_Stream stream; FT_Byte* postscript; - FT_Long postscript_len; + FT_ULong postscript_len; FT_ULong data_offset; - FT_Long binary_length; + FT_ULong binary_length; CID_FaceInfo cid; FT_Int num_dict; @@ -92,32 +92,32 @@ FT_BEGIN_HEADER /* */ /*************************************************************************/ -#define cid_parser_skip_spaces( p ) \ +#define cid_parser_skip_spaces( p ) \ (p)->root.funcs.skip_spaces( &(p)->root ) -#define cid_parser_skip_PS_token( p ) \ +#define cid_parser_skip_PS_token( p ) \ (p)->root.funcs.skip_PS_token( &(p)->root ) -#define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root ) -#define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) +#define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root ) +#define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) -#define cid_parser_to_coord_array( p, m, c ) \ +#define cid_parser_to_coord_array( p, m, c ) \ (p)->root.funcs.to_coord_array( &(p)->root, m, c ) -#define cid_parser_to_fixed_array( p, m, f, t ) \ +#define cid_parser_to_fixed_array( p, m, f, t ) \ (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) -#define cid_parser_to_token( p, t ) \ +#define cid_parser_to_token( p, t ) \ (p)->root.funcs.to_token( &(p)->root, t ) -#define cid_parser_to_token_array( p, t, m, c ) \ +#define cid_parser_to_token_array( p, t, m, c ) \ (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) -#define cid_parser_load_field( p, f, o ) \ +#define cid_parser_load_field( p, f, o ) \ (p)->root.funcs.load_field( &(p)->root, f, o, 0, 0 ) -#define cid_parser_load_field_table( p, f, o ) \ +#define cid_parser_load_field_table( p, f, o ) \ (p)->root.funcs.load_field_table( &(p)->root, f, o, 0, 0 ) FT_END_HEADER -#endif /* __CIDPARSE_H__ */ +#endif /* CIDPARSE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cid/cidriver.c b/drivers/freetype/src/cid/cidriver.c index 6132a27763..64141ab6b1 100644 --- a/drivers/freetype/freetype/src/cid/cidriver.c +++ b/drivers/freetype/src/cid/cidriver.c @@ -4,7 +4,7 @@ /* */ /* CID driver interface (body). */ /* */ -/* Copyright 1996-2004, 2006, 2008, 2009, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,7 +24,7 @@ #include "ciderrs.h" #include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_POSTSCRIPT_INFO_H #include FT_SERVICE_CID_H @@ -59,7 +59,7 @@ static const FT_Service_PsFontNameRec cid_service_ps_name = { - (FT_PsName_GetFunc) cid_get_postscript_name + (FT_PsName_GetFunc)cid_get_postscript_name /* get_ps_font_name */ }; @@ -88,11 +88,14 @@ static const FT_Service_PsInfoRec cid_service_ps_info = { - (PS_GetFontInfoFunc) cid_ps_get_font_info, - (PS_GetFontExtraFunc) cid_ps_get_font_extra, - (PS_HasGlyphNamesFunc) NULL, /* unsupported with CID fonts */ - (PS_GetFontPrivateFunc)NULL, /* unsupported */ - (PS_GetFontValueFunc) NULL /* not implemented */ + (PS_GetFontInfoFunc) cid_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) cid_ps_get_font_extra, /* ps_get_font_extra */ + /* unsupported with CID fonts */ + (PS_HasGlyphNamesFunc) NULL, /* ps_has_glyph_names */ + /* unsupported */ + (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ }; @@ -155,9 +158,12 @@ static const FT_Service_CIDRec cid_service_cid_info = { - (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros, - (FT_CID_GetIsInternallyCIDKeyedFunc) cid_get_is_cid, - (FT_CID_GetCIDFromGlyphIndexFunc) cid_get_cid_from_glyph_index + (FT_CID_GetRegistryOrderingSupplementFunc) + cid_get_ros, /* get_ros */ + (FT_CID_GetIsInternallyCIDKeyedFunc) + cid_get_is_cid, /* get_is_cid */ + (FT_CID_GetCIDFromGlyphIndexFunc) + cid_get_cid_from_glyph_index /* get_cid_from_glyph_index */ }; @@ -168,7 +174,7 @@ static const FT_ServiceDescRec cid_services[] = { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CID }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CID }, { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, { FT_SERVICE_ID_CID, &cid_service_cid_info }, @@ -190,46 +196,42 @@ FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec t1cid_driver_class = { - /* first of all, the FT_Module_Class fields */ { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | FT_MODULE_DRIVER_HAS_HINTER, - sizeof ( FT_DriverRec ), + "t1cid", /* module name */ 0x10000L, /* version 1.0 of driver */ 0x20000L, /* requires FreeType 2.0 */ - 0, + 0, /* module-specific interface */ - cid_driver_init, - cid_driver_done, - cid_get_interface + cid_driver_init, /* FT_Module_Constructor module_init */ + cid_driver_done, /* FT_Module_Destructor module_done */ + cid_get_interface /* FT_Module_Requester get_interface */ }, - /* then the other font drivers fields */ sizeof ( CID_FaceRec ), sizeof ( CID_SizeRec ), sizeof ( CID_GlyphSlotRec ), - cid_face_init, - cid_face_done, - - cid_size_init, - cid_size_done, - cid_slot_init, - cid_slot_done, - - cid_slot_load_glyph, + cid_face_init, /* FT_Face_InitFunc init_face */ + cid_face_done, /* FT_Face_DoneFunc done_face */ + cid_size_init, /* FT_Size_InitFunc init_size */ + cid_size_done, /* FT_Size_DoneFunc done_size */ + cid_slot_init, /* FT_Slot_InitFunc init_slot */ + cid_slot_done, /* FT_Slot_DoneFunc done_slot */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ + cid_slot_load_glyph, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetAdvancesFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - cid_size_request, - 0 /* FT_Size_SelectFunc */ + cid_size_request, /* FT_Size_RequestFunc request_size */ + 0 /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/freetype/src/cid/cidriver.h b/drivers/freetype/src/cid/cidriver.h index 3c45e06886..a359a78907 100644 --- a/drivers/freetype/freetype/src/cid/cidriver.h +++ b/drivers/freetype/src/cid/cidriver.h @@ -4,7 +4,7 @@ /* */ /* High-level CID driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDRIVER_H__ -#define __CIDRIVER_H__ +#ifndef CIDRIVER_H_ +#define CIDRIVER_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDRIVER_H__ */ +#endif /* CIDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/cid/cidtoken.h b/drivers/freetype/src/cid/cidtoken.h index 904cb09cf4..9c773fd094 100644 --- a/drivers/freetype/freetype/src/cid/cidtoken.h +++ b/drivers/freetype/src/cid/cidtoken.h @@ -4,7 +4,7 @@ /* */ /* CID token definitions (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/cid/module.mk b/drivers/freetype/src/cid/module.mk index ce30bfd7ae..d9585d7816 100644 --- a/drivers/freetype/freetype/src/cid/module.mk +++ b/drivers/freetype/src/cid/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/cid/rules.mk b/drivers/freetype/src/cid/rules.mk index f362744612..f33aab00d6 100644 --- a/drivers/freetype/freetype/src/cid/rules.mk +++ b/drivers/freetype/src/cid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -18,7 +18,10 @@ CID_DIR := $(SRC_DIR)/cid -CID_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CID_DIR)) +CID_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(CID_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # CID driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/cid/type1cid.c b/drivers/freetype/src/cid/type1cid.c index 0b866e97c4..de3bdf7705 100644 --- a/drivers/freetype/freetype/src/cid/type1cid.c +++ b/drivers/freetype/src/cid/type1cid.c @@ -4,7 +4,7 @@ /* */ /* FreeType OpenType driver component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/gxvalid/Jamfile b/drivers/freetype/src/gxvalid/Jamfile index 88049a625d..9738677e05 100644 --- a/drivers/freetype/freetype/src/gxvalid/Jamfile +++ b/drivers/freetype/src/gxvalid/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/gxvalid Jamfile # -# Copyright 2005 by +# Copyright 2005-2016 by # suzuki toshiya, Masatake YAMATO and Red Hat K.K. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,10 +17,29 @@ SubDir FT2_TOP $(FT2_SRC_DIR) gxvalid ; if $(FT2_MULTI) { - _sources = gxvcommn gxvfeat gxvbsln gxvtrak gxvopbd gxvprop - gxvmort gxvmort0 gxvmort1 gxvmort2 gxvmort4 gxvmort5 - gxvmorx gxvmorx0 gxvmorx1 gxvmorx2 gxvmorx4 gxvmorx5 - gxvlcar gxvkern gxvmod gxvjust ; + _sources = gxvbsln + gxvcommn + gxvfeat + gxvjust + gxvkern + gxvlcar + gxvmod + gxvmort + gxvmort0 + gxvmort1 + gxvmort2 + gxvmort4 + gxvmort5 + gxvmorx + gxvmorx0 + gxvmorx1 + gxvmorx2 + gxvmorx4 + gxvmorx5 + gxvopbd + gxvprop + gxvtrak + ; } else { diff --git a/drivers/freetype/freetype/src/gxvalid/README b/drivers/freetype/src/gxvalid/README index 28e535b0bc..d3ac49c3e2 100644 --- a/drivers/freetype/freetype/src/gxvalid/README +++ b/drivers/freetype/src/gxvalid/README @@ -518,7 +518,7 @@ gxvalid: TrueType GX validator ------------------------------------------------------------------------ -Copyright 2004, 2005, 2007 by +Copyright 2004-2016 by suzuki toshiya, Masatake YAMATO, Red hat K.K., David Turner, Robert Wilhelm, and Werner Lemberg. diff --git a/drivers/freetype/freetype/src/gxvalid/gxvalid.c b/drivers/freetype/src/gxvalid/gxvalid.c index bc36e675d1..7fb868cad1 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvalid.c +++ b/drivers/freetype/src/gxvalid/gxvalid.c @@ -4,7 +4,8 @@ /* */ /* FreeType validator for TrueTypeGX/AAT tables (body only). */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvalid.h b/drivers/freetype/src/gxvalid/gxvalid.h index 27be9ecca8..7a3ab795ef 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvalid.h +++ b/drivers/freetype/src/gxvalid/gxvalid.h @@ -4,7 +4,8 @@ /* */ /* TrueTyeeGX/AAT table validation (specification only). */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVALID_H__ -#define __GXVALID_H__ +#ifndef GXVALID_H_ +#define GXVALID_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -101,7 +102,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __GXVALID_H__ */ +#endif /* GXVALID_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvbsln.c b/drivers/freetype/src/gxvalid/gxvbsln.c index 3d10031563..493b20c31a 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvbsln.c +++ b/drivers/freetype/src/gxvalid/gxvbsln.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT bsln table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -72,10 +73,10 @@ static void gxv_bsln_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_UShort v = value_p->u; - FT_UShort* ctlPoints; + FT_UShort v = value_p->u; + FT_UShort* ctlPoints; FT_UNUSED( glyph ); @@ -124,7 +125,7 @@ gxv_bsln_LookupFmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -135,7 +136,7 @@ offset = (FT_UShort)( base_value_p->u + ( relative_gindex * sizeof ( FT_UShort ) ) ); - p = valid->lookuptbl_head + offset; + p = gxvalid->lookuptbl_head + offset; limit = lookuptbl_limit; GXV_LIMIT_CHECK( 2 ); @@ -148,7 +149,7 @@ static void gxv_bsln_parts_fmt0_validate( FT_Bytes tables, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = tables; @@ -158,7 +159,7 @@ /* deltas */ GXV_LIMIT_CHECK( 2 * GXV_BSLN_VALUE_COUNT ); - valid->table_data = NULL; /* No ctlPoints here. */ + gxvalid->table_data = NULL; /* No ctlPoints here. */ GXV_EXIT; } @@ -167,7 +168,7 @@ static void gxv_bsln_parts_fmt1_validate( FT_Bytes tables, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = tables; @@ -175,15 +176,15 @@ GXV_NAME_ENTER( "parts format 1" ); /* deltas */ - gxv_bsln_parts_fmt0_validate( p, limit, valid ); + gxv_bsln_parts_fmt0_validate( p, limit, gxvalid ); /* mappingData */ - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_bsln_LookupValue_validate; - valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_bsln_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; gxv_LookupTable_validate( p + 2 * GXV_BSLN_VALUE_COUNT, limit, - valid ); + gxvalid ); GXV_EXIT; } @@ -192,7 +193,7 @@ static void gxv_bsln_parts_fmt2_validate( FT_Bytes tables, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = tables; @@ -211,7 +212,7 @@ stdGlyph = FT_NEXT_USHORT( p ); GXV_TRACE(( " (stdGlyph = %u)\n", stdGlyph )); - gxv_glyphid_validate( stdGlyph, valid ); + gxv_glyphid_validate( stdGlyph, gxvalid ); /* Record the position of ctlPoints */ GXV_BSLN_DATA( ctlPoints_p ) = p; @@ -226,7 +227,7 @@ FT_INVALID_DATA; } else - gxv_ctlPoint_validate( stdGlyph, (FT_Short)ctlPoint, valid ); + gxv_ctlPoint_validate( stdGlyph, ctlPoint, gxvalid ); } GXV_EXIT; @@ -236,7 +237,7 @@ static void gxv_bsln_parts_fmt3_validate( FT_Bytes tables, FT_Bytes limit, - GXV_Validator valid) + GXV_Validator gxvalid) { FT_Bytes p = tables; @@ -244,15 +245,15 @@ GXV_NAME_ENTER( "parts format 3" ); /* stdGlyph + ctlPoints */ - gxv_bsln_parts_fmt2_validate( p, limit, valid ); + gxv_bsln_parts_fmt2_validate( p, limit, gxvalid ); /* mappingData */ - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_bsln_LookupValue_validate; - valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_bsln_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; gxv_LookupTable_validate( p + ( 2 + 2 * GXV_BSLN_VALUE_COUNT ), limit, - valid ); + gxvalid ); GXV_EXIT; } @@ -271,8 +272,8 @@ FT_Face face, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_bsln_DataRec bslnrec; GXV_bsln_Data bsln = &bslnrec; @@ -293,9 +294,9 @@ }; - valid->root = ftvalid; - valid->table_data = bsln; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = bsln; + gxvalid->face = face; FT_TRACE3(( "validating `bsln' table\n" )); GXV_INIT; @@ -320,7 +321,7 @@ bsln->defaultBaseline = defaultBaseline; - fmt_funcs_table[format]( p, limit, valid ); + fmt_funcs_table[format]( p, limit, gxvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvcommn.c b/drivers/freetype/src/gxvalid/gxvcommn.c index 2ac80be8c7..4b5e41539a 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvcommn.c +++ b/drivers/freetype/src/gxvalid/gxvcommn.c @@ -4,8 +4,8 @@ /* */ /* TrueTypeGX/AAT common tables validation (body). */ /* */ -/* Copyright 2004, 2005, 2009, 2010, 2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,7 +65,7 @@ FT_UShort* buff, FT_UInt nmemb, FT_UShort limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UInt i; @@ -130,7 +130,7 @@ FT_ULong* buff, FT_UInt nmemb, FT_ULong limit, - GXV_Validator valid) + GXV_Validator gxvalid) { FT_UInt i; @@ -182,7 +182,7 @@ FT_Bytes limit, FT_Byte* min, FT_Byte* max, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -202,7 +202,7 @@ *max = (FT_Byte)FT_MAX( *max, val ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } @@ -211,7 +211,7 @@ FT_Bytes limit, FT_UShort* min, FT_UShort* max, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -231,7 +231,7 @@ *max = (FT_Byte)FT_MAX( *max, val ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } @@ -256,7 +256,7 @@ static void gxv_BinSrchHeader_check_consistency( GXV_BinSrchHeader* binSrchHeader, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort searchRange; FT_UShort entrySelector; @@ -329,7 +329,7 @@ FT_Bytes limit, FT_UShort* unitSize_p, FT_UShort* nUnits_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_BinSrchHeader binSrchHeader; @@ -359,7 +359,7 @@ binSrchHeader.rangeShift = FT_NEXT_USHORT( p ); GXV_TRACE(( "nUnits %d\n", binSrchHeader.nUnits )); - gxv_BinSrchHeader_check_consistency( &binSrchHeader, valid ); + gxv_BinSrchHeader_check_consistency( &binSrchHeader, gxvalid ); if ( *unitSize_p == 0 ) *unitSize_p = binSrchHeader.unitSize; @@ -367,7 +367,7 @@ if ( *nUnits_p == 0 ) *nUnits_p = binSrchHeader.nUnits; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -422,7 +422,7 @@ static void gxv_LookupTable_fmt0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort i; @@ -432,24 +432,24 @@ GXV_NAME_ENTER( "LookupTable format 0" ); - GXV_LIMIT_CHECK( 2 * valid->face->num_glyphs ); + GXV_LIMIT_CHECK( 2 * gxvalid->face->num_glyphs ); - for ( i = 0; i < valid->face->num_glyphs; i++ ) + for ( i = 0; i < gxvalid->face->num_glyphs; i++ ) { GXV_LIMIT_CHECK( 2 ); if ( p + 2 >= limit ) /* some fonts have too-short fmt0 array */ { GXV_TRACE(( "too short, glyphs %d - %d are missing\n", - i, valid->face->num_glyphs )); + i, gxvalid->face->num_glyphs )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); break; } - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - valid->lookupval_func( i, &value, valid ); + value = GXV_LOOKUP_VALUE_LOAD( p, gxvalid->lookupval_sign ); + gxvalid->lookupval_func( i, &value, gxvalid ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -473,12 +473,12 @@ static void gxv_LookupTable_fmt2_skip_endmarkers( FT_Bytes table, FT_UShort unitSize, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; - while ( ( p + 4 ) < valid->root->limit ) + while ( ( p + 4 ) < gxvalid->root->limit ) { if ( p[0] != 0xFF || p[1] != 0xFF || /* lastGlyph */ p[2] != 0xFF || p[3] != 0xFF ) /* firstGlyph */ @@ -486,14 +486,14 @@ p += unitSize; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_LookupTable_fmt2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort gid; @@ -509,8 +509,8 @@ GXV_NAME_ENTER( "LookupTable format 2" ); unitSize = nUnits = 0; - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); - p += valid->subtable_length; + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid ); + p += gxvalid->subtable_length; GXV_UNITSIZE_VALIDATE( "format2", unitSize, nUnits, 6 ); @@ -519,10 +519,10 @@ GXV_LIMIT_CHECK( 2 + 2 + 2 ); lastGlyph = FT_NEXT_USHORT( p ); firstGlyph = FT_NEXT_USHORT( p ); - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); + value = GXV_LOOKUP_VALUE_LOAD( p, gxvalid->lookupval_sign ); - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( lastGlyph, valid ); + gxv_glyphid_validate( firstGlyph, gxvalid ); + gxv_glyphid_validate( lastGlyph, gxvalid ); if ( lastGlyph < gid ) { @@ -539,7 +539,7 @@ unit, lastGlyph, firstGlyph )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - if ( valid->root->level == FT_VALIDATE_TIGHT ) + if ( gxvalid->root->level == FT_VALIDATE_TIGHT ) continue; /* ftxvalidator silently skips such an entry */ FT_TRACE4(( "continuing with exchanged values\n" )); @@ -549,13 +549,13 @@ } for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) - valid->lookupval_func( gid, &value, valid ); + gxvalid->lookupval_func( gid, &value, gxvalid ); } - gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); - p += valid->subtable_length; + gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, gxvalid ); + p += gxvalid->subtable_length; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -564,7 +564,7 @@ static void gxv_LookupTable_fmt4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort unit; @@ -581,8 +581,8 @@ GXV_NAME_ENTER( "LookupTable format 4" ); unitSize = nUnits = 0; - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); - p += valid->subtable_length; + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid ); + p += gxvalid->subtable_length; GXV_UNITSIZE_VALIDATE( "format4", unitSize, nUnits, 6 ); @@ -592,8 +592,8 @@ lastGlyph = FT_NEXT_USHORT( p ); firstGlyph = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( lastGlyph, valid ); + gxv_glyphid_validate( firstGlyph, gxvalid ); + gxv_glyphid_validate( lastGlyph, gxvalid ); if ( lastGlyph < gid ) { @@ -610,7 +610,7 @@ unit, lastGlyph, firstGlyph )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); - if ( valid->root->level == FT_VALIDATE_TIGHT ) + if ( gxvalid->root->level == FT_VALIDATE_TIGHT ) continue; /* ftxvalidator silently skips such an entry */ FT_TRACE4(( "continuing with exchanged values\n" )); @@ -624,19 +624,19 @@ for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) { - value = valid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ), + value = gxvalid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ), &base_value, limit, - valid ); + gxvalid ); - valid->lookupval_func( gid, &value, valid ); + gxvalid->lookupval_func( gid, &value, gxvalid ); } } - gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); - p += valid->subtable_length; + gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, gxvalid ); + p += gxvalid->subtable_length; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -645,26 +645,26 @@ static void gxv_LookupTable_fmt6_skip_endmarkers( FT_Bytes table, FT_UShort unitSize, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; - while ( p < valid->root->limit ) + while ( p < gxvalid->root->limit ) { if ( p[0] != 0xFF || p[1] != 0xFF ) break; p += unitSize; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_LookupTable_fmt6_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort unit; @@ -679,8 +679,8 @@ GXV_NAME_ENTER( "LookupTable format 6" ); unitSize = nUnits = 0; - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); - p += valid->subtable_length; + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid ); + p += gxvalid->subtable_length; GXV_UNITSIZE_VALIDATE( "format6", unitSize, nUnits, 4 ); @@ -688,9 +688,9 @@ { GXV_LIMIT_CHECK( 2 + 2 ); glyph = FT_NEXT_USHORT( p ); - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); + value = GXV_LOOKUP_VALUE_LOAD( p, gxvalid->lookupval_sign ); - if ( gxv_glyphid_validate( glyph, valid ) ) + if ( gxv_glyphid_validate( glyph, gxvalid ) ) GXV_TRACE(( " endmarker found within defined range" " (entry %d < nUnits=%d)\n", unit, nUnits )); @@ -703,13 +703,13 @@ } prev_glyph = glyph; - valid->lookupval_func( glyph, &value, valid ); + gxvalid->lookupval_func( glyph, &value, gxvalid ); } - gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, valid ); - p += valid->subtable_length; + gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, gxvalid ); + p += gxvalid->subtable_length; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -718,7 +718,7 @@ static void gxv_LookupTable_fmt8_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort i; @@ -735,18 +735,18 @@ firstGlyph = FT_NEXT_USHORT( p ); glyphCount = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( (FT_UShort)( firstGlyph + glyphCount ), valid ); + gxv_glyphid_validate( firstGlyph, gxvalid ); + gxv_glyphid_validate( (FT_UShort)( firstGlyph + glyphCount ), gxvalid ); /* valueArray */ for ( i = 0; i < glyphCount; i++ ) { GXV_LIMIT_CHECK( 2 ); - value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - valid->lookupval_func( (FT_UShort)( firstGlyph + i ), &value, valid ); + value = GXV_LOOKUP_VALUE_LOAD( p, gxvalid->lookupval_sign ); + gxvalid->lookupval_func( (FT_UShort)( firstGlyph + i ), &value, gxvalid ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -754,7 +754,7 @@ FT_LOCAL_DEF( void ) gxv_LookupTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort format; @@ -778,7 +778,7 @@ GXV_NAME_ENTER( "LookupTable" ); /* lookuptbl_head may be used in fmt4 transit function. */ - valid->lookuptbl_head = table; + gxvalid->lookuptbl_head = table; /* format */ GXV_LIMIT_CHECK( 2 ); @@ -792,10 +792,10 @@ if ( func == NULL ) FT_INVALID_FORMAT; - func( p, limit, valid ); - p += valid->subtable_length; + func( p, limit, gxvalid ); + p += gxvalid->subtable_length; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -811,7 +811,7 @@ FT_LOCAL_DEF( FT_Int ) gxv_glyphid_validate( FT_UShort gid, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Face face; @@ -822,7 +822,7 @@ return 1; } - face = valid->face; + face = gxvalid->face; if ( face->num_glyphs < gid ) { GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n", @@ -844,18 +844,18 @@ FT_LOCAL_DEF( void ) gxv_ctlPoint_validate( FT_UShort gid, - FT_Short ctl_point, - GXV_Validator valid ) + FT_UShort ctl_point, + GXV_Validator gxvalid ) { FT_Face face; FT_Error error; FT_GlyphSlot glyph; FT_Outline outline; - short n_points; + FT_UShort n_points; - face = valid->face; + face = gxvalid->face; error = FT_Load_Glyph( face, gid, @@ -865,8 +865,7 @@ glyph = face->glyph; outline = glyph->outline; - n_points = outline.n_points; - + n_points = (FT_UShort)outline.n_points; if ( !( ctl_point < n_points ) ) FT_INVALID_DATA; @@ -885,7 +884,7 @@ gxv_sfntName_validate( FT_UShort name_index, FT_UShort min_index, FT_UShort max_index, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_SfntName name; FT_UInt i; @@ -897,11 +896,11 @@ if ( name_index < min_index || max_index < name_index ) FT_INVALID_FORMAT; - nnames = FT_Get_Sfnt_Name_Count( valid->face ); + nnames = FT_Get_Sfnt_Name_Count( gxvalid->face ); for ( i = 0; i < nnames; i++ ) { - if ( FT_Get_Sfnt_Name( valid->face, i, &name ) != FT_Err_Ok ) - continue ; + if ( FT_Get_Sfnt_Name( gxvalid->face, i, &name ) != FT_Err_Ok ) + continue; if ( name.name_id == name_index ) goto Out; @@ -944,7 +943,7 @@ FT_UShort* length_p, FT_UShort stateSize, FT_Byte* maxClassID_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_Bytes limit = table + *length_p; @@ -965,7 +964,7 @@ if ( !nGlyphs ) goto Out; - gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs ), valid ); + gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs ), gxvalid ); { FT_Byte nGlyphInClass[256]; @@ -1022,9 +1021,9 @@ FT_UShort stateSize, FT_Byte* maxState_p, FT_Byte* maxEntry_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table; + FT_Bytes p = table; FT_Bytes limit = table + *length_p; FT_Byte clazz; FT_Byte entry; @@ -1076,7 +1075,7 @@ FT_Byte maxClassID, FT_Bytes statetable_table, FT_Bytes statetable_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_Bytes limit = table + *length_p; @@ -1160,22 +1159,17 @@ case GXV_GLYPHOFFSET_LONG: glyphOffset.l = FT_NEXT_LONG( p ); break; - - default: - GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); - goto Exit; } - if ( NULL != valid->statetable.entry_validate_func ) - valid->statetable.entry_validate_func( state, - flags, - &glyphOffset, - statetable_table, - statetable_limit, - valid ); + if ( NULL != gxvalid->statetable.entry_validate_func ) + gxvalid->statetable.entry_validate_func( state, + flags, + &glyphOffset, + statetable_table, + statetable_limit, + gxvalid ); } - Exit: *length_p = (FT_UShort)( p - table ); GXV_EXIT; @@ -1192,7 +1186,7 @@ FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort o[3]; FT_UShort* l[3]; @@ -1206,14 +1200,14 @@ l[1] = stateArray_length_p; l[2] = entryTable_length_p; - gxv_set_length_by_ushort_offset( o, l, buff, 3, table_size, valid ); + gxv_set_length_by_ushort_offset( o, l, buff, 3, table_size, gxvalid ); } FT_LOCAL_DEF( void ) gxv_StateTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort stateSize; FT_UShort classTable; /* offset to Class(Sub)Table */ @@ -1250,11 +1244,11 @@ if ( stateSize > 0xFF ) FT_INVALID_DATA; - if ( valid->statetable.optdata_load_func != NULL ) - valid->statetable.optdata_load_func( p, limit, valid ); + if ( gxvalid->statetable.optdata_load_func != NULL ) + gxvalid->statetable.optdata_load_func( p, limit, gxvalid ); - if ( valid->statetable.subtable_setup_func != NULL) - setup_func = valid->statetable.subtable_setup_func; + if ( gxvalid->statetable.subtable_setup_func != NULL) + setup_func = gxvalid->statetable.subtable_setup_func; else setup_func = gxv_StateTable_subtable_setup; @@ -1265,7 +1259,7 @@ &classTable_length, &stateArray_length, &entryTable_length, - valid ); + gxvalid ); GXV_TRACE(( "StateTable Subtables\n" )); @@ -1274,7 +1268,7 @@ &classTable_length, stateSize, &maxClassID, - valid ); + gxvalid ); else maxClassID = (FT_Byte)( stateSize - 1 ); @@ -1285,10 +1279,12 @@ stateSize, &maxState, &maxEntry, - valid ); + gxvalid ); else { +#if 0 maxState = 1; /* 0:start of text, 1:start of line are predefined */ +#endif maxEntry = 0; } @@ -1304,7 +1300,7 @@ maxClassID, table, limit, - valid ); + gxvalid ); GXV_EXIT; } @@ -1320,7 +1316,7 @@ FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_ULong o[3]; FT_ULong* l[3]; @@ -1334,21 +1330,21 @@ l[1] = stateArray_length_p; l[2] = entryTable_length_p; - gxv_set_length_by_ulong_offset( o, l, buff, 3, table_size, valid ); + gxv_set_length_by_ulong_offset( o, l, buff, 3, table_size, gxvalid ); } static void gxv_XClassTable_lookupval_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UNUSED( glyph ); - if ( value_p->u >= valid->xstatetable.nClasses ) + if ( value_p->u >= gxvalid->xstatetable.nClasses ) FT_INVALID_DATA; - if ( value_p->u > valid->xstatetable.maxClassID ) - valid->xstatetable.maxClassID = value_p->u; + if ( value_p->u > gxvalid->xstatetable.maxClassID ) + gxvalid->xstatetable.maxClassID = value_p->u; } @@ -1382,7 +1378,7 @@ gxv_XClassTable_lookupfmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -1393,7 +1389,7 @@ offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); - p = valid->lookuptbl_head + offset; + p = gxvalid->lookuptbl_head + offset; limit = lookuptbl_limit; GXV_LIMIT_CHECK ( 2 ); @@ -1410,7 +1406,7 @@ FT_ULong stateSize, FT_UShort* maxState_p, FT_UShort* maxEntry_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_Bytes limit = table + *length_p; @@ -1447,7 +1443,7 @@ GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n", *maxState_p, *maxEntry_p )); - *length_p = p - table; + *length_p = (FT_ULong)( p - table ); GXV_EXIT; } @@ -1461,7 +1457,7 @@ FT_UShort maxClassID, FT_Bytes xstatetable_table, FT_Bytes xstatetable_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_Bytes limit = table + *length_p; @@ -1476,7 +1472,7 @@ if ( ( p + ( maxEntry + 1 ) * entrySize ) > limit ) FT_INVALID_TOO_SHORT; - for (entry = 0; entry <= maxEntry ; entry++ ) + for (entry = 0; entry <= maxEntry; entry++ ) { FT_UShort newState_idx; FT_UShort flags; @@ -1538,17 +1534,17 @@ goto Exit; } - if ( NULL != valid->xstatetable.entry_validate_func ) - valid->xstatetable.entry_validate_func( state, - flags, - &glyphOffset, - xstatetable_table, - xstatetable_limit, - valid ); + if ( NULL != gxvalid->xstatetable.entry_validate_func ) + gxvalid->xstatetable.entry_validate_func( state, + flags, + &glyphOffset, + xstatetable_table, + xstatetable_limit, + gxvalid ); } Exit: - *length_p = p - table; + *length_p = (FT_ULong)( p - table ); GXV_EXIT; } @@ -1557,7 +1553,7 @@ FT_LOCAL_DEF( void ) gxv_XStateTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* StateHeader members */ FT_ULong classTable; /* offset to Class(Sub)Table */ @@ -1580,68 +1576,72 @@ GXV_TRACE(( "XStateTable header\n" )); GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); - valid->xstatetable.nClasses = FT_NEXT_ULONG( p ); + gxvalid->xstatetable.nClasses = FT_NEXT_ULONG( p ); classTable = FT_NEXT_ULONG( p ); stateArray = FT_NEXT_ULONG( p ); entryTable = FT_NEXT_ULONG( p ); - GXV_TRACE(( "nClasses =0x%08x\n", valid->xstatetable.nClasses )); + GXV_TRACE(( "nClasses =0x%08x\n", gxvalid->xstatetable.nClasses )); GXV_TRACE(( "offset to classTable=0x%08x\n", classTable )); GXV_TRACE(( "offset to stateArray=0x%08x\n", stateArray )); GXV_TRACE(( "offset to entryTable=0x%08x\n", entryTable )); - if ( valid->xstatetable.nClasses > 0xFFFFU ) + if ( gxvalid->xstatetable.nClasses > 0xFFFFU ) FT_INVALID_DATA; GXV_TRACE(( "StateTable Subtables\n" )); - if ( valid->xstatetable.optdata_load_func != NULL ) - valid->xstatetable.optdata_load_func( p, limit, valid ); + if ( gxvalid->xstatetable.optdata_load_func != NULL ) + gxvalid->xstatetable.optdata_load_func( p, limit, gxvalid ); - if ( valid->xstatetable.subtable_setup_func != NULL ) - setup_func = valid->xstatetable.subtable_setup_func; + if ( gxvalid->xstatetable.subtable_setup_func != NULL ) + setup_func = gxvalid->xstatetable.subtable_setup_func; else setup_func = gxv_XStateTable_subtable_setup; - setup_func( limit - table, + setup_func( (FT_ULong)( limit - table ), classTable, stateArray, entryTable, &classTable_length, &stateArray_length, &entryTable_length, - valid ); + gxvalid ); if ( classTable != 0 ) { - valid->xstatetable.maxClassID = 0; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_XClassTable_lookupval_validate; - valid->lookupfmt4_trans = gxv_XClassTable_lookupfmt4_transit; + gxvalid->xstatetable.maxClassID = 0; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_XClassTable_lookupval_validate; + gxvalid->lookupfmt4_trans = gxv_XClassTable_lookupfmt4_transit; gxv_LookupTable_validate( table + classTable, table + classTable + classTable_length, - valid ); - if ( valid->subtable_length < classTable_length ) - classTable_length = valid->subtable_length; + gxvalid ); +#if 0 + if ( gxvalid->subtable_length < classTable_length ) + classTable_length = gxvalid->subtable_length; +#endif } else { /* XXX: check range? */ - valid->xstatetable.maxClassID = - (FT_UShort)( valid->xstatetable.nClasses - 1 ); + gxvalid->xstatetable.maxClassID = + (FT_UShort)( gxvalid->xstatetable.nClasses - 1 ); } if ( stateArray != 0 ) gxv_XStateArray_validate( table + stateArray, &stateArray_length, - valid->xstatetable.maxClassID, - valid->xstatetable.nClasses, + gxvalid->xstatetable.maxClassID, + gxvalid->xstatetable.nClasses, &maxState, &maxEntry, - valid ); + gxvalid ); else { +#if 0 maxState = 1; /* 0:start of text, 1:start of line are predefined */ +#endif maxEntry = 0; } @@ -1653,10 +1653,10 @@ &entryTable_length, maxEntry, stateArray_length, - valid->xstatetable.maxClassID, + gxvalid->xstatetable.maxClassID, table, limit, - valid ); + gxvalid ); GXV_EXIT; } @@ -1713,7 +1713,7 @@ FT_LOCAL_DEF( void ) gxv_odtect_validate( GXV_odtect_Range odtect, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UInt i, j; @@ -1727,6 +1727,7 @@ odtect->range[j].start, odtect->range[j].length ) ) { +#ifdef FT_DEBUG_LEVEL_TRACE if ( odtect->range[i].name || odtect->range[j].name ) GXV_TRACE(( "found overlap between range %d and range %d\n", i, j )); @@ -1734,6 +1735,7 @@ GXV_TRACE(( "found overlap between `%s' and `%s\'\n", odtect->range[i].name, odtect->range[j].name )); +#endif FT_INVALID_OFFSET; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvcommn.h b/drivers/freetype/src/gxvalid/gxvcommn.h index 1ff87e4423..9470c8412b 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvcommn.h +++ b/drivers/freetype/src/gxvalid/gxvcommn.h @@ -4,8 +4,8 @@ /* */ /* TrueTypeGX/AAT common tables validation (specification). */ /* */ -/* Copyright 2004, 2005, 2012 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,8 +39,8 @@ */ -#ifndef __GXVCOMMN_H__ -#define __GXVCOMMN_H__ +#ifndef GXVCOMMN_H_ +#define GXVCOMMN_H_ #include <ft2build.h> @@ -62,7 +62,7 @@ FT_BEGIN_HEADER #undef GXV_LOAD_UNUSED_VARS /* debug purpose */ -#define IS_PARANOID_VALIDATION ( valid->root->level >= FT_VALIDATE_PARANOID ) +#define IS_PARANOID_VALIDATION ( gxvalid->root->level >= FT_VALIDATE_PARANOID ) #define GXV_SET_ERR_IF_PARANOID( err ) { if ( IS_PARANOID_VALIDATION ) ( err ); } /*************************************************************************/ @@ -81,7 +81,7 @@ FT_BEGIN_HEADER typedef void (*GXV_Validate_Func)( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); /* ====================== LookupTable Validator ======================== */ @@ -106,13 +106,13 @@ FT_BEGIN_HEADER typedef void (*GXV_Lookup_Value_Validate_Func)( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef GXV_LookupValueDesc (*GXV_Lookup_Fmt4_Transit_Func)( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); /* ====================== StateTable Validator ========================= */ @@ -131,10 +131,10 @@ FT_BEGIN_HEADER #define GXV_GLYPHOFFSET_FMT( table ) \ - ( valid->table.entry_glyphoffset_fmt ) + ( gxvalid->table.entry_glyphoffset_fmt ) #define GXV_GLYPHOFFSET_SIZE( table ) \ - ( valid->table.entry_glyphoffset_fmt / 2 ) + ( gxvalid->table.entry_glyphoffset_fmt / 2 ) /* ----------------------- 16bit StateTable ---------------------------- */ @@ -160,7 +160,7 @@ FT_BEGIN_HEADER FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef void (*GXV_StateTable_Entry_Validate_Func)( @@ -169,12 +169,12 @@ FT_BEGIN_HEADER GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes statetable_table, FT_Bytes statetable_limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef void (*GXV_StateTable_OptData_Load_Func)( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef struct GXV_StateTable_ValidatorRec_ { @@ -202,7 +202,7 @@ FT_BEGIN_HEADER FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef void (*GXV_XStateTable_Entry_Validate_Func)( @@ -211,7 +211,7 @@ FT_BEGIN_HEADER GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes xstatetable_table, FT_Bytes xstatetable_limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); typedef GXV_StateTable_OptData_Load_Func GXV_XStateTable_OptData_Load_Func; @@ -263,35 +263,35 @@ FT_BEGIN_HEADER #define GXV_TABLE_DATA( tag, field ) \ - ( ( (GXV_ ## tag ## _Data)valid->table_data )->field ) + ( ( (GXV_ ## tag ## _Data)gxvalid->table_data )->field ) #undef FT_INVALID_ -#define FT_INVALID_( _prefix, _error ) \ - ft_validator_error( valid->root, _prefix ## _error ) +#define FT_INVALID_( _error ) \ + ft_validator_error( gxvalid->root, FT_THROW( _error ) ) #define GXV_LIMIT_CHECK( _count ) \ FT_BEGIN_STMNT \ - if ( p + _count > ( limit? limit : valid->root->limit ) ) \ + if ( p + _count > ( limit? limit : gxvalid->root->limit ) ) \ FT_INVALID_TOO_SHORT; \ FT_END_STMNT #ifdef FT_DEBUG_LEVEL_TRACE -#define GXV_INIT valid->debug_indent = 0 +#define GXV_INIT gxvalid->debug_indent = 0 #define GXV_NAME_ENTER( name ) \ FT_BEGIN_STMNT \ - valid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + gxvalid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", gxvalid->debug_indent, 0 )); \ FT_TRACE4(( "%s table\n", name )); \ FT_END_STMNT -#define GXV_EXIT valid->debug_indent -= 2 +#define GXV_EXIT gxvalid->debug_indent -= 2 #define GXV_TRACE( s ) \ FT_BEGIN_STMNT \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + FT_TRACE4(( "%*.s", gxvalid->debug_indent, 0 )); \ FT_TRACE4( s ); \ FT_END_STMNT @@ -318,7 +318,7 @@ FT_BEGIN_HEADER FT_BEGIN_STMNT \ { \ if ( (a) & 3 ) \ - FT_INVALID_OFFSET ; \ + FT_INVALID_OFFSET; \ } \ FT_END_STMNT @@ -338,7 +338,7 @@ FT_BEGIN_HEADER \ \ for ( b = p; b < (FT_Bytes)p + len; b++ ) \ - FT_TRACE1(("\\x%02x", *b)) ; \ + FT_TRACE1(("\\x%02x", *b)); \ } \ FT_END_STMNT @@ -349,10 +349,10 @@ FT_BEGIN_HEADER \ \ for ( b = p; b < (FT_Bytes)p + len; b++ ) \ - if ( 0x40 < *b && *b < 0x7e ) \ - FT_TRACE1(("%c", *b)) ; \ + if ( 0x40 < *b && *b < 0x7E ) \ + FT_TRACE1(("%c", *b)); \ else \ - FT_TRACE1(("\\x%02x", *b)) ; \ + FT_TRACE1(("\\x%02x", *b)); \ } \ FT_END_STMNT @@ -373,12 +373,12 @@ FT_BEGIN_HEADER FT_Bytes limit, FT_UShort* unitSize_p, FT_UShort* nUnits_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_LookupTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); /*************************************************************************/ @@ -391,7 +391,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Int ) gxv_glyphid_validate( FT_UShort gid, - GXV_Validator valid ); + GXV_Validator gxvalid ); /*************************************************************************/ @@ -404,8 +404,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) gxv_ctlPoint_validate( FT_UShort gid, - FT_Short ctl_point, - GXV_Validator valid ); + FT_UShort ctl_point, + GXV_Validator gxvalid ); /*************************************************************************/ @@ -420,7 +420,7 @@ FT_BEGIN_HEADER gxv_sfntName_validate( FT_UShort name_index, FT_UShort min_index, FT_UShort max_index, - GXV_Validator valid ); + GXV_Validator gxvalid ); /*************************************************************************/ @@ -439,7 +439,7 @@ FT_BEGIN_HEADER FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_XStateTable_subtable_setup( FT_ULong table_size, @@ -449,17 +449,17 @@ FT_BEGIN_HEADER FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_StateTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_XStateTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); /*************************************************************************/ @@ -475,14 +475,14 @@ FT_BEGIN_HEADER FT_Bytes limit, FT_Byte* min, FT_Byte* max, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_array_getlimits_ushort( FT_Bytes table, FT_Bytes limit, FT_UShort* min, FT_UShort* max, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_set_length_by_ushort_offset( FT_UShort* offset, @@ -490,7 +490,7 @@ FT_BEGIN_HEADER FT_UShort* buff, FT_UInt nmemb, FT_UShort limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_set_length_by_ulong_offset( FT_ULong* offset, @@ -498,19 +498,19 @@ FT_BEGIN_HEADER FT_ULong* buff, FT_UInt nmemb, FT_ULong limit, - GXV_Validator valid); + GXV_Validator gxvalid); #define GXV_SUBTABLE_OFFSET_CHECK( _offset ) \ FT_BEGIN_STMNT \ - if ( (_offset) > valid->subtable_length ) \ + if ( (_offset) > gxvalid->subtable_length ) \ FT_INVALID_OFFSET; \ FT_END_STMNT #define GXV_SUBTABLE_LIMIT_CHECK( _count ) \ FT_BEGIN_STMNT \ - if ( ( p + (_count) - valid->subtable_start ) > \ - valid->subtable_length ) \ + if ( ( p + (_count) - gxvalid->subtable_start ) > \ + gxvalid->subtable_length ) \ FT_INVALID_TOO_SHORT; \ FT_END_STMNT @@ -556,7 +556,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) gxv_odtect_validate( GXV_odtect_Range odtect, - GXV_Validator valid ); + GXV_Validator gxvalid ); #define GXV_ODTECT( n, odtect ) \ @@ -576,7 +576,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __GXVCOMMN_H__ */ +#endif /* GXVCOMMN_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxverror.h b/drivers/freetype/src/gxvalid/gxverror.h index c573b72de7..2e53355ce4 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxverror.h +++ b/drivers/freetype/src/gxvalid/gxverror.h @@ -4,8 +4,8 @@ /* */ /* TrueTypeGX/AAT validation module error codes (specification only). */ /* */ -/* Copyright 2004, 2005, 2012-2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,12 +32,12 @@ /* */ /*************************************************************************/ -#ifndef __GXVERROR_H__ -#define __GXVERROR_H__ +#ifndef GXVERROR_H_ +#define GXVERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX GXV_Err_ @@ -45,7 +45,7 @@ #include FT_ERRORS_H -#endif /* __GXVERROR_H__ */ +#endif /* GXVERROR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvfeat.c b/drivers/freetype/src/gxvalid/gxvfeat.c index 6f75650991..5bff7c261d 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvfeat.c +++ b/drivers/freetype/src/gxvalid/gxvfeat.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT feat table validation (body). */ /* */ -/* Copyright 2004, 2005, 2008, 2012 by */ +/* Copyright 2004-2016 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -82,7 +82,7 @@ gxv_feat_registry_validate( FT_UShort feature, FT_UShort nSettings, FT_Bool exclusive, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_NAME_ENTER( "feature in registry" ); @@ -108,7 +108,7 @@ { /* Don't use here. Apple is reserved. */ GXV_TRACE(( "feature number %d is reserved by Apple\n", feature )); - if ( valid->root->level >= FT_VALIDATE_TIGHT ) + if ( gxvalid->root->level >= FT_VALIDATE_TIGHT ) FT_INVALID_DATA; } @@ -117,7 +117,7 @@ GXV_TRACE(( "feature %d: nSettings %d != defined nSettings %d\n", feature, nSettings, gxv_feat_registry[feature].nSettings )); - if ( valid->root->level >= FT_VALIDATE_TIGHT ) + if ( gxvalid->root->level >= FT_VALIDATE_TIGHT ) FT_INVALID_DATA; } @@ -125,7 +125,7 @@ { GXV_TRACE(( "exclusive flag %d differs from predefined value\n", exclusive )); - if ( valid->root->level >= FT_VALIDATE_TIGHT ) + if ( gxvalid->root->level >= FT_VALIDATE_TIGHT ) FT_INVALID_DATA; } @@ -137,7 +137,7 @@ static void gxv_feat_name_index_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -153,7 +153,7 @@ gxv_sfntName_validate( (FT_UShort)nameIndex, 255, 32768U, - valid ); + gxvalid ); GXV_EXIT; } @@ -163,7 +163,7 @@ gxv_feat_setting_validate( FT_Bytes table, FT_Bytes limit, FT_Bool exclusive, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort setting; @@ -179,7 +179,7 @@ if ( exclusive && ( setting & 1 ) == 0 ) FT_INVALID_DATA; - gxv_feat_name_index_validate( p, limit, valid ); + gxv_feat_name_index_validate( p, limit, gxvalid ); GXV_FEAT_DATA( setting ) = setting; @@ -190,7 +190,7 @@ static void gxv_feat_name_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UInt reserved_size = GXV_FEAT_DATA( reserved_size ); @@ -240,14 +240,14 @@ FT_INVALID_FORMAT; } - gxv_feat_registry_validate( feature, nSettings, exclusive, valid ); + gxv_feat_registry_validate( feature, nSettings, exclusive, gxvalid ); - gxv_feat_name_index_validate( p, limit, valid ); + gxv_feat_name_index_validate( p, limit, gxvalid ); - p = valid->root->base + settingTable; + p = gxvalid->root->base + settingTable; for ( last_setting = -1, i = 0; i < nSettings; i++ ) { - gxv_feat_setting_validate( p, limit, exclusive, valid ); + gxv_feat_setting_validate( p, limit, exclusive, gxvalid ); if ( (FT_Int)GXV_FEAT_DATA( setting ) <= last_setting ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); @@ -274,8 +274,8 @@ FT_Face face, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_feat_DataRec featrec; GXV_feat_Data feat = &featrec; @@ -289,9 +289,9 @@ FT_Int last_feature; - valid->root = ftvalid; - valid->table_data = feat; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = feat; + gxvalid->face = face; FT_TRACE3(( "validating `feat' table\n" )); GXV_INIT; @@ -323,7 +323,7 @@ for ( last_feature = -1, i = 0; i < featureNameCount; i++ ) { - gxv_feat_name_validate( p, limit, valid ); + gxv_feat_name_validate( p, limit, gxvalid ); if ( (FT_Int)GXV_FEAT_DATA( feature ) <= last_feature ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); diff --git a/drivers/freetype/freetype/src/gxvalid/gxvfeat.h b/drivers/freetype/src/gxvalid/gxvfeat.h index 049d23a0b9..284bada891 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvfeat.h +++ b/drivers/freetype/src/gxvalid/gxvfeat.h @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT feat table validation (specification). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVFEAT_H__ -#define __GXVFEAT_H__ +#ifndef GXVFEAT_H_ +#define GXVFEAT_H_ #include "gxvalid.h" @@ -166,7 +167,7 @@ }; -#endif /* __GXVFEAT_H__ */ +#endif /* GXVFEAT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvfgen.c b/drivers/freetype/src/gxvalid/gxvfgen.c index e48778a2a1..667dac3cde 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvfgen.c +++ b/drivers/freetype/src/gxvalid/gxvfgen.c @@ -5,7 +5,8 @@ /* Generate feature registry data for gxv `feat' validator. */ /* This program is derived from gxfeatreg.c in gxlayout. */ /* */ -/* Copyright 2004, 2005, 2006 by Masatake YAMATO and Redhat K.K. */ +/* Copyright 2004-2016 by */ +/* Masatake YAMATO and Redhat K.K. */ /* */ /* This file may only be used, */ /* modified, and distributed under the terms of the FreeType project */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvjust.c b/drivers/freetype/src/gxvalid/gxvjust.c index 7816e0b7fb..20d29bfbc8 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvjust.c +++ b/drivers/freetype/src/gxvalid/gxvjust.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT just table validation (body). */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,7 +42,7 @@ /* * referred `just' table format specification: - * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6just.html + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6just.html * last updated 2000. * ---------------------------------------------- * [JUST HEADER]: GXV_JUST_HEADER_SIZE @@ -69,14 +70,14 @@ static void gxv_just_check_max_gid( FT_UShort gid, const FT_String* msg_tag, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - if ( gid < valid->face->num_glyphs ) + if ( gid < gxvalid->face->num_glyphs ) return; GXV_TRACE(( "just table includes too large %s" " GID=%d > %d (in maxp)\n", - msg_tag, gid, valid->face->num_glyphs )); + msg_tag, gid, gxvalid->face->num_glyphs )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } @@ -84,7 +85,7 @@ static void gxv_just_wdp_entry_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong justClass; @@ -112,7 +113,7 @@ #endif /* According to Apple spec, only 7bits in justClass is used */ - if ( ( justClass & 0xFFFFFF80 ) != 0 ) + if ( ( justClass & 0xFFFFFF80UL ) != 0 ) { GXV_TRACE(( "just table includes non-zero value" " in unused justClass higher bits" @@ -120,14 +121,14 @@ GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_just_wdc_entry_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong count, i; @@ -138,20 +139,20 @@ for ( i = 0; i < count; i++ ) { GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count )); - gxv_just_wdp_entry_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_just_wdp_entry_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_just_widthDeltaClusters_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table ; + FT_Bytes p = table; FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max ); FT_UInt i; @@ -163,11 +164,11 @@ for ( i = 0; p <= wdc_end; i++ ) { - gxv_just_wdc_entry_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_just_wdc_entry_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -176,7 +177,7 @@ static void gxv_just_actSubrecord_type0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -191,8 +192,8 @@ GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); - lowerLimit = FT_NEXT_ULONG( p ); - upperLimit = FT_NEXT_ULONG( p ); + lowerLimit = FT_NEXT_LONG( p ); + upperLimit = FT_NEXT_LONG( p ); #ifdef GXV_LOAD_UNUSED_VARS order = FT_NEXT_USHORT( p ); #else @@ -214,17 +215,17 @@ GXV_LIMIT_CHECK( 2 ); glyphs = FT_NEXT_USHORT( p ); - gxv_just_check_max_gid( glyphs, "type0:glyphs", valid ); + gxv_just_check_max_gid( glyphs, "type0:glyphs", gxvalid ); } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_just_actSubrecord_type1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort addGlyph; @@ -233,20 +234,20 @@ GXV_LIMIT_CHECK( 2 ); addGlyph = FT_NEXT_USHORT( p ); - gxv_just_check_max_gid( addGlyph, "type1:addGlyph", valid ); + gxv_just_check_max_gid( addGlyph, "type1:addGlyph", gxvalid ); - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_just_actSubrecord_type2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; #ifdef GXV_LOAD_UNUSED_VARS - FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */ + FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */ #endif FT_UShort addGlyph; FT_UShort substGlyph; @@ -262,18 +263,18 @@ substGlyph = FT_NEXT_USHORT( p ); if ( addGlyph != 0xFFFF ) - gxv_just_check_max_gid( addGlyph, "type2:addGlyph", valid ); + gxv_just_check_max_gid( addGlyph, "type2:addGlyph", gxvalid ); - gxv_just_check_max_gid( substGlyph, "type2:substGlyph", valid ); + gxv_just_check_max_gid( substGlyph, "type2:substGlyph", gxvalid ); - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } static void gxv_just_actSubrecord_type4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong variantsAxis; @@ -284,13 +285,13 @@ GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); variantsAxis = FT_NEXT_ULONG( p ); - minimumLimit = FT_NEXT_ULONG( p ); - noStretchValue = FT_NEXT_ULONG( p ); - maximumLimit = FT_NEXT_ULONG( p ); + minimumLimit = FT_NEXT_LONG( p ); + noStretchValue = FT_NEXT_LONG( p ); + maximumLimit = FT_NEXT_LONG( p ); - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); - if ( variantsAxis != 0x64756374 ) /* 'duct' */ + if ( variantsAxis != 0x64756374L ) /* 'duct' */ GXV_TRACE(( "variantsAxis 0x%08x is non default value", variantsAxis )); @@ -310,7 +311,7 @@ static void gxv_just_actSubrecord_type5_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort flags; @@ -324,9 +325,9 @@ if ( flags ) GXV_TRACE(( "type5: nonzero value 0x%04x in unused flags\n", flags )); - gxv_just_check_max_gid( glyph, "type5:glyph", valid ); + gxv_just_check_max_gid( glyph, "type5:glyph", gxvalid ); - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); } @@ -334,7 +335,7 @@ static void gxv_just_actSubrecord_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort actionClass; @@ -354,21 +355,21 @@ GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); if ( actionType == 0 ) - gxv_just_actSubrecord_type0_validate( p, limit, valid ); + gxv_just_actSubrecord_type0_validate( p, limit, gxvalid ); else if ( actionType == 1 ) - gxv_just_actSubrecord_type1_validate( p, limit, valid ); + gxv_just_actSubrecord_type1_validate( p, limit, gxvalid ); else if ( actionType == 2 ) - gxv_just_actSubrecord_type2_validate( p, limit, valid ); + gxv_just_actSubrecord_type2_validate( p, limit, gxvalid ); else if ( actionType == 3 ) ; /* Stretch glyph action: no actionData */ else if ( actionType == 4 ) - gxv_just_actSubrecord_type4_validate( p, limit, valid ); + gxv_just_actSubrecord_type4_validate( p, limit, gxvalid ); else if ( actionType == 5 ) - gxv_just_actSubrecord_type5_validate( p, limit, valid ); + gxv_just_actSubrecord_type5_validate( p, limit, gxvalid ); else FT_INVALID_DATA; - valid->subtable_length = actionLength; + gxvalid->subtable_length = actionLength; GXV_EXIT; } @@ -377,7 +378,7 @@ static void gxv_just_pcActionRecord_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong actionCount; @@ -390,11 +391,11 @@ for ( i = 0; i < actionCount; i++ ) { - gxv_just_actSubrecord_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_just_actSubrecord_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -403,7 +404,7 @@ static void gxv_just_pcTable_LookupValue_entry_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UNUSED( glyph ); @@ -417,19 +418,19 @@ static void gxv_just_pcLookupTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table; + FT_Bytes p = table; GXV_NAME_ENTER( "just pcLookupTable" ); GXV_JUST_DATA( pc_offset_max ) = 0x0000; GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate; - gxv_LookupTable_validate( p, limit, valid ); + gxv_LookupTable_validate( p, limit, gxvalid ); /* subtable_length is set by gxv_LookupTable_validate() */ @@ -440,20 +441,20 @@ static void gxv_just_postcompTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_NAME_ENTER( "just postcompTable" ); - gxv_just_pcLookupTable_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_just_pcLookupTable_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; - gxv_just_pcActionRecord_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_just_pcActionRecord_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -466,7 +467,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS /* TODO: validate markClass & currentClass */ @@ -480,7 +481,7 @@ FT_UNUSED( glyphOffset_p ); FT_UNUSED( table ); FT_UNUSED( limit ); - FT_UNUSED( valid ); + FT_UNUSED( gxvalid ); #ifndef GXV_LOAD_UNUSED_VARS FT_UNUSED( flags ); @@ -496,7 +497,7 @@ static void gxv_just_justClassTable_validate ( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort length; @@ -521,14 +522,14 @@ GXV_TRACE(( " justClassTable: nonzero value (0x%08x)" " in unused subFeatureFlags\n", subFeatureFlags )); - valid->statetable.optdata = NULL; - valid->statetable.optdata_load_func = NULL; - valid->statetable.subtable_setup_func = NULL; - valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = + gxvalid->statetable.optdata = NULL; + gxvalid->statetable.optdata_load_func = NULL; + gxvalid->statetable.subtable_setup_func = NULL; + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; + gxvalid->statetable.entry_validate_func = gxv_just_classTable_entry_validate; - gxv_StateTable_validate( p, table + length, valid ); + gxv_StateTable_validate( p, table + length, gxvalid ); /* subtable_length is set by gxv_LookupTable_validate() */ @@ -539,7 +540,7 @@ static void gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UNUSED( glyph ); @@ -553,7 +554,7 @@ static void gxv_just_justData_lookuptable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -561,10 +562,10 @@ GXV_JUST_DATA( wdc_offset_max ) = 0x0000; GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_just_wdcTable_LookupValue_validate; - gxv_LookupTable_validate( p, limit, valid ); + gxv_LookupTable_validate( p, limit, gxvalid ); /* subtable_length is set by gxv_LookupTable_validate() */ @@ -578,7 +579,7 @@ static void gxv_just_justData_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* * following 3 offsets are measured from the start of `just' @@ -604,36 +605,36 @@ GXV_TRACE(( " (wdcTableOffset = 0x%04x)\n", wdcTableOffset )); GXV_TRACE(( " (pcTableOffset = 0x%04x)\n", pcTableOffset )); - gxv_just_justData_lookuptable_validate( p, limit, valid ); - gxv_odtect_add_range( p, valid->subtable_length, + gxv_just_justData_lookuptable_validate( p, limit, gxvalid ); + gxv_odtect_add_range( p, gxvalid->subtable_length, "just_LookupTable", odtect ); if ( wdcTableOffset ) { gxv_just_widthDeltaClusters_validate( - valid->root->base + wdcTableOffset, limit, valid ); - gxv_odtect_add_range( valid->root->base + wdcTableOffset, - valid->subtable_length, "just_wdcTable", odtect ); + gxvalid->root->base + wdcTableOffset, limit, gxvalid ); + gxv_odtect_add_range( gxvalid->root->base + wdcTableOffset, + gxvalid->subtable_length, "just_wdcTable", odtect ); } if ( pcTableOffset ) { - gxv_just_postcompTable_validate( valid->root->base + pcTableOffset, - limit, valid ); - gxv_odtect_add_range( valid->root->base + pcTableOffset, - valid->subtable_length, "just_pcTable", odtect ); + gxv_just_postcompTable_validate( gxvalid->root->base + pcTableOffset, + limit, gxvalid ); + gxv_odtect_add_range( gxvalid->root->base + pcTableOffset, + gxvalid->subtable_length, "just_pcTable", odtect ); } if ( justClassTableOffset ) { gxv_just_justClassTable_validate( - valid->root->base + justClassTableOffset, limit, valid ); - gxv_odtect_add_range( valid->root->base + justClassTableOffset, - valid->subtable_length, "just_justClassTable", + gxvalid->root->base + justClassTableOffset, limit, gxvalid ); + gxv_odtect_add_range( gxvalid->root->base + justClassTableOffset, + gxvalid->subtable_length, "just_justClassTable", odtect ); } - gxv_odtect_validate( odtect, valid ); + gxv_odtect_validate( odtect, gxvalid ); GXV_EXIT; } @@ -647,8 +648,8 @@ FT_Bytes p = table; FT_Bytes limit = 0; - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_just_DataRec justrec; GXV_just_Data just = &justrec; @@ -662,21 +663,22 @@ GXV_ODTECT_INIT( odtect ); - valid->root = ftvalid; - valid->table_data = just; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = just; + gxvalid->face = face; FT_TRACE3(( "validating `just' table\n" )); GXV_INIT; - limit = valid->root->limit; + limit = gxvalid->root->limit; GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 ); version = FT_NEXT_ULONG( p ); format = FT_NEXT_USHORT( p ); horizOffset = FT_NEXT_USHORT( p ); vertOffset = FT_NEXT_USHORT( p ); - gxv_odtect_add_range( table, p - table, "just header", odtect ); + gxv_odtect_add_range( table, (FT_ULong)( p - table ), + "just header", odtect ); /* Version 1.0 (always:2000) */ @@ -696,19 +698,19 @@ /* validate justData */ if ( 0 < horizOffset ) { - gxv_just_justData_validate( table + horizOffset, limit, valid ); - gxv_odtect_add_range( table + horizOffset, valid->subtable_length, + gxv_just_justData_validate( table + horizOffset, limit, gxvalid ); + gxv_odtect_add_range( table + horizOffset, gxvalid->subtable_length, "horizJustData", odtect ); } if ( 0 < vertOffset ) { - gxv_just_justData_validate( table + vertOffset, limit, valid ); - gxv_odtect_add_range( table + vertOffset, valid->subtable_length, + gxv_just_justData_validate( table + vertOffset, limit, gxvalid ); + gxv_odtect_add_range( table + vertOffset, gxvalid->subtable_length, "vertJustData", odtect ); } - gxv_odtect_validate( odtect, valid ); + gxv_odtect_validate( odtect, gxvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvkern.c b/drivers/freetype/src/gxvalid/gxvkern.c index 557c5f1fe4..ee1ab36f70 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvkern.c +++ b/drivers/freetype/src/gxvalid/gxvkern.c @@ -4,8 +4,8 @@ /* */ /* TrueTypeGX/AAT kern table validation (body). */ /* */ -/* Copyright 2004-2007, 2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -79,20 +79,20 @@ #define GXV_KERN_DATA( field ) GXV_TABLE_DATA( kern, field ) -#define KERN_IS_CLASSIC( valid ) \ +#define KERN_IS_CLASSIC( gxvalid ) \ ( KERN_VERSION_CLASSIC == GXV_KERN_DATA( version ) ) -#define KERN_IS_NEW( valid ) \ +#define KERN_IS_NEW( gxvalid ) \ ( KERN_VERSION_NEW == GXV_KERN_DATA( version ) ) -#define KERN_DIALECT( valid ) \ +#define KERN_DIALECT( gxvalid ) \ GXV_KERN_DATA( dialect_request ) -#define KERN_ALLOWS_MS( valid ) \ - ( KERN_DIALECT( valid ) & KERN_DIALECT_MS ) -#define KERN_ALLOWS_APPLE( valid ) \ - ( KERN_DIALECT( valid ) & KERN_DIALECT_APPLE ) +#define KERN_ALLOWS_MS( gxvalid ) \ + ( KERN_DIALECT( gxvalid ) & KERN_DIALECT_MS ) +#define KERN_ALLOWS_APPLE( gxvalid ) \ + ( KERN_DIALECT( gxvalid ) & KERN_DIALECT_APPLE ) -#define GXV_KERN_HEADER_SIZE ( KERN_IS_NEW( valid ) ? 8 : 4 ) -#define GXV_KERN_SUBTABLE_HEADER_SIZE ( KERN_IS_NEW( valid ) ? 8 : 6 ) +#define GXV_KERN_HEADER_SIZE ( KERN_IS_NEW( gxvalid ) ? 8 : 4 ) +#define GXV_KERN_SUBTABLE_HEADER_SIZE ( KERN_IS_NEW( gxvalid ) ? 8 : 6 ) /*************************************************************************/ @@ -110,7 +110,7 @@ gxv_kern_subtable_fmt0_pairs_validate( FT_Bytes table, FT_Bytes limit, FT_UShort nPairs, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort i; @@ -134,11 +134,11 @@ /* left */ gid_left = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( gid_left, valid ); + gxv_glyphid_validate( gid_left, gxvalid ); /* right */ gid_right = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( gid_right, valid ); + gxv_glyphid_validate( gid_right, gxvalid ); /* Pairs of left and right GIDs must be unique and sorted. */ GXV_TRACE(( "left gid = %u, right gid = %u\n", gid_left, gid_right )); @@ -171,7 +171,7 @@ static void gxv_kern_subtable_fmt0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; @@ -186,10 +186,10 @@ /* nPairs, searchRange, entrySelector, rangeShift */ GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, valid ); + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, gxvalid ); p += 2 + 2 + 2 + 2; - gxv_kern_subtable_fmt0_pairs_validate( p, limit, nPairs, valid ); + gxv_kern_subtable_fmt0_pairs_validate( p, limit, nPairs, gxvalid ); GXV_EXIT; } @@ -209,11 +209,11 @@ static void gxv_kern_subtable_fmt1_valueTable_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_kern_fmt1_StateOptRecData optdata = - (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; + (GXV_kern_fmt1_StateOptRecData)gxvalid->statetable.optdata; GXV_LIMIT_CHECK( 2 ); @@ -232,14 +232,14 @@ FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort o[4]; FT_UShort *l[4]; FT_UShort buff[5]; GXV_kern_fmt1_StateOptRecData optdata = - (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; + (GXV_kern_fmt1_StateOptRecData)gxvalid->statetable.optdata; o[0] = classTable; @@ -251,7 +251,7 @@ l[2] = entryTable_length_p; l[3] = &(optdata->valueTable_length); - gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid ); + gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, gxvalid ); } @@ -265,7 +265,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort push; @@ -289,7 +289,7 @@ { GXV_kern_fmt1_StateOptRecData vt_rec = - (GXV_kern_fmt1_StateOptRecData)valid->statetable.optdata; + (GXV_kern_fmt1_StateOptRecData)gxvalid->statetable.optdata; FT_Bytes p; @@ -311,7 +311,7 @@ static void gxv_kern_subtable_fmt1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_kern_fmt1_StateOptRec vt_rec; @@ -319,18 +319,18 @@ GXV_NAME_ENTER( "kern subtable format 1" ); - valid->statetable.optdata = + gxvalid->statetable.optdata = &vt_rec; - valid->statetable.optdata_load_func = + gxvalid->statetable.optdata_load_func = gxv_kern_subtable_fmt1_valueTable_load; - valid->statetable.subtable_setup_func = + gxvalid->statetable.subtable_setup_func = gxv_kern_subtable_fmt1_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = + gxvalid->statetable.entry_validate_func = gxv_kern_subtable_fmt1_entry_validate; - gxv_StateTable_validate( p, limit, valid ); + gxv_StateTable_validate( p, limit, gxvalid ); GXV_EXIT; } @@ -373,7 +373,7 @@ gxv_kern_subtable_fmt2_clstbl_validate( FT_Bytes table, FT_Bytes limit, GXV_kern_ClassSpec spec, - GXV_Validator valid ) + GXV_Validator gxvalid ) { const FT_String* tag = GXV_KERN_FMT2_DATA( class_tag[spec] ); GXV_odtect_Range odtect = GXV_KERN_FMT2_DATA( odtect ); @@ -391,13 +391,13 @@ GXV_TRACE(( " %s firstGlyph=%d, nGlyphs=%d\n", tag, firstGlyph, nGlyphs )); - gxv_glyphid_validate( firstGlyph, valid ); - gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs - 1 ), valid ); + gxv_glyphid_validate( firstGlyph, gxvalid ); + gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs - 1 ), gxvalid ); gxv_array_getlimits_ushort( p, p + ( 2 * nGlyphs ), &( GXV_KERN_FMT2_DATA( offset_min[spec] ) ), &( GXV_KERN_FMT2_DATA( offset_max[spec] ) ), - valid ); + gxvalid ); gxv_odtect_add_range( table, 2 * nGlyphs, tag, odtect ); @@ -408,7 +408,7 @@ static void gxv_kern_subtable_fmt2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_ODTECT( 3, odtect ); GXV_kern_subtable_fmt2_DataRec fmt2_rec = @@ -439,10 +439,10 @@ GXV_LIMIT_CHECK( GXV_KERN_FMT2_DATA( array ) ); gxv_kern_subtable_fmt2_clstbl_validate( table + leftOffsetTable, limit, - GXV_KERN_CLS_L, valid ); + GXV_KERN_CLS_L, gxvalid ); gxv_kern_subtable_fmt2_clstbl_validate( table + rightOffsetTable, limit, - GXV_KERN_CLS_R, valid ); + GXV_KERN_CLS_R, gxvalid ); if ( GXV_KERN_FMT2_DATA( offset_min[GXV_KERN_CLS_L] ) + GXV_KERN_FMT2_DATA( offset_min[GXV_KERN_CLS_R] ) @@ -455,7 +455,7 @@ - GXV_KERN_FMT2_DATA( array ), "array", odtect ); - gxv_odtect_validate( odtect, valid ); + gxv_odtect_validate( odtect, gxvalid ); GXV_EXIT; } @@ -466,7 +466,7 @@ static void gxv_kern_subtable_fmt3_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; FT_UShort glyphCount; @@ -485,10 +485,10 @@ rightClassCount = FT_NEXT_BYTE( p ); flags = FT_NEXT_BYTE( p ); - if ( valid->face->num_glyphs != glyphCount ) + if ( gxvalid->face->num_glyphs != glyphCount ) { GXV_TRACE(( "maxGID=%d, but glyphCount=%d\n", - valid->face->num_glyphs, glyphCount )); + gxvalid->face->num_glyphs, glyphCount )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } @@ -509,8 +509,8 @@ GXV_LIMIT_CHECK( glyphCount ); - gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, valid ); - p += valid->subtable_length; + gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, gxvalid ); + p += gxvalid->subtable_length; if ( leftClassCount < max ) FT_INVALID_DATA; @@ -524,8 +524,8 @@ GXV_LIMIT_CHECK( glyphCount ); - gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, valid ); - p += valid->subtable_length; + gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, gxvalid ); + p += gxvalid->subtable_length; if ( rightClassCount < max ) FT_INVALID_DATA; @@ -549,7 +549,7 @@ } } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -558,7 +558,7 @@ static FT_Bool gxv_kern_coverage_new_apple_validate( FT_UShort coverage, FT_UShort* format, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* new Apple-dialect */ #ifdef GXV_LOAD_TRACE_VARS @@ -567,7 +567,7 @@ FT_Bool kernVariation; #endif - FT_UNUSED( valid ); + FT_UNUSED( gxvalid ); /* reserved bits = 0 */ @@ -595,7 +595,7 @@ static FT_Bool gxv_kern_coverage_classic_apple_validate( FT_UShort coverage, FT_UShort* format, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* classic Apple-dialect */ #ifdef GXV_LOAD_TRACE_VARS @@ -605,7 +605,7 @@ /* check expected flags, but don't check if MS-dialect is impossible */ - if ( !( coverage & 0xFD00 ) && KERN_ALLOWS_MS( valid ) ) + if ( !( coverage & 0xFD00 ) && KERN_ALLOWS_MS( gxvalid ) ) return FALSE; /* reserved bits = 0 */ @@ -636,7 +636,7 @@ static FT_Bool gxv_kern_coverage_classic_microsoft_validate( FT_UShort coverage, FT_UShort* format, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* classic Microsoft-dialect */ #ifdef GXV_LOAD_TRACE_VARS @@ -646,7 +646,7 @@ FT_Bool override; #endif - FT_UNUSED( valid ); + FT_UNUSED( gxvalid ); /* reserved bits = 0 */ @@ -686,49 +686,49 @@ static GXV_kern_Dialect gxv_kern_coverage_validate( FT_UShort coverage, FT_UShort* format, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_kern_Dialect result = KERN_DIALECT_UNKNOWN; GXV_NAME_ENTER( "validating coverage" ); - GXV_TRACE(( "interprete coverage 0x%04x by Apple style\n", coverage )); + GXV_TRACE(( "interpret coverage 0x%04x by Apple style\n", coverage )); - if ( KERN_IS_NEW( valid ) ) + if ( KERN_IS_NEW( gxvalid ) ) { if ( gxv_kern_coverage_new_apple_validate( coverage, format, - valid ) ) + gxvalid ) ) { result = KERN_DIALECT_APPLE; goto Exit; } } - if ( KERN_IS_CLASSIC( valid ) && KERN_ALLOWS_APPLE( valid ) ) + if ( KERN_IS_CLASSIC( gxvalid ) && KERN_ALLOWS_APPLE( gxvalid ) ) { if ( gxv_kern_coverage_classic_apple_validate( coverage, format, - valid ) ) + gxvalid ) ) { result = KERN_DIALECT_APPLE; goto Exit; } } - if ( KERN_IS_CLASSIC( valid ) && KERN_ALLOWS_MS( valid ) ) + if ( KERN_IS_CLASSIC( gxvalid ) && KERN_ALLOWS_MS( gxvalid ) ) { if ( gxv_kern_coverage_classic_microsoft_validate( coverage, format, - valid ) ) + gxvalid ) ) { result = KERN_DIALECT_MS; goto Exit; } } - GXV_TRACE(( "cannot interprete coverage, broken kern subtable\n" )); + GXV_TRACE(( "cannot interpret coverage, broken kern subtable\n" )); Exit: GXV_EXIT; @@ -739,7 +739,7 @@ static void gxv_kern_subtable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; #ifdef GXV_LOAD_TRACE_VARS @@ -761,7 +761,7 @@ u16[1] = FT_NEXT_USHORT( p ); /* Apple: length_lo MS: length */ coverage = FT_NEXT_USHORT( p ); - switch ( gxv_kern_coverage_validate( coverage, &format, valid ) ) + switch ( gxv_kern_coverage_validate( coverage, &format, gxvalid ) ) { case KERN_DIALECT_MS: #ifdef GXV_LOAD_TRACE_VARS @@ -779,13 +779,13 @@ #ifdef GXV_LOAD_TRACE_VARS version = 0; #endif - length = ( u16[0] << 16 ) + u16[1]; + length = ( (FT_ULong)u16[0] << 16 ) + u16[1]; #ifdef GXV_LOAD_TRACE_VARS tupleIndex = 0; #endif GXV_TRACE(( "Subtable length = %d\n", length )); - if ( KERN_IS_NEW( valid ) ) + if ( KERN_IS_NEW( gxvalid ) ) { GXV_LIMIT_CHECK( 2 ); #ifdef GXV_LOAD_TRACE_VARS @@ -806,18 +806,18 @@ /* formats 1, 2, 3 require the position of the start of this subtable */ if ( format == 0 ) - gxv_kern_subtable_fmt0_validate( table, table + length, valid ); + gxv_kern_subtable_fmt0_validate( table, table + length, gxvalid ); else if ( format == 1 ) - gxv_kern_subtable_fmt1_validate( table, table + length, valid ); + gxv_kern_subtable_fmt1_validate( table, table + length, gxvalid ); else if ( format == 2 ) - gxv_kern_subtable_fmt2_validate( table, table + length, valid ); + gxv_kern_subtable_fmt2_validate( table, table + length, gxvalid ); else if ( format == 3 ) - gxv_kern_subtable_fmt3_validate( table, table + length, valid ); + gxv_kern_subtable_fmt3_validate( table, table + length, gxvalid ); else FT_INVALID_DATA; Exit: - valid->subtable_length = length; + gxvalid->subtable_length = length; GXV_EXIT; } @@ -837,8 +837,8 @@ GXV_kern_Dialect dialect_request, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_kern_DataRec kernrec; GXV_kern_Data kern = &kernrec; @@ -850,13 +850,13 @@ FT_UInt i; - valid->root = ftvalid; - valid->table_data = kern; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = kern; + gxvalid->face = face; FT_TRACE3(( "validating `kern' table\n" )); GXV_INIT; - KERN_DIALECT( valid ) = dialect_request; + KERN_DIALECT( gxvalid ) = dialect_request; GXV_LIMIT_CHECK( 2 ); GXV_KERN_DATA( version ) = (GXV_kern_Version)FT_NEXT_USHORT( p ); @@ -865,12 +865,12 @@ if ( 0x0001 < GXV_KERN_DATA( version ) ) FT_INVALID_FORMAT; - else if ( KERN_IS_CLASSIC( valid ) ) + else if ( KERN_IS_CLASSIC( gxvalid ) ) { GXV_LIMIT_CHECK( 2 ); nTables = FT_NEXT_USHORT( p ); } - else if ( KERN_IS_NEW( valid ) ) + else if ( KERN_IS_NEW( gxvalid ) ) { if ( classic_only ) FT_INVALID_FORMAT; @@ -886,8 +886,8 @@ { GXV_TRACE(( "validating subtable %d/%d\n", i, nTables )); /* p should be 32bit-aligned? */ - gxv_kern_subtable_validate( p, 0, valid ); - p += valid->subtable_length; + gxv_kern_subtable_validate( p, 0, gxvalid ); + p += gxvalid->subtable_length; } FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/freetype/src/gxvalid/gxvlcar.c b/drivers/freetype/src/gxvalid/gxvlcar.c index f14fa5b131..d31b6410bd 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvlcar.c +++ b/drivers/freetype/src/gxvalid/gxvlcar.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT lcar table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,16 +66,16 @@ /*************************************************************************/ static void - gxv_lcar_partial_validate( FT_UShort partial, + gxv_lcar_partial_validate( FT_Short partial, FT_UShort glyph, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_NAME_ENTER( "partial" ); if ( GXV_LCAR_DATA( format ) != 1 ) goto Exit; - gxv_ctlPoint_validate( glyph, partial, valid ); + gxv_ctlPoint_validate( glyph, (FT_UShort)partial, gxvalid ); Exit: GXV_EXIT; @@ -84,10 +85,10 @@ static void gxv_lcar_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = valid->root->base + value_p->u; - FT_Bytes limit = valid->root->limit; + FT_Bytes p = gxvalid->root->base + value_p->u; + FT_Bytes limit = gxvalid->root->limit; FT_UShort count; FT_Short partial; FT_UShort i; @@ -102,7 +103,7 @@ for ( i = 0; i < count; i++ ) { partial = FT_NEXT_SHORT( p ); - gxv_lcar_partial_validate( partial, glyph, valid ); + gxv_lcar_partial_validate( partial, glyph, gxvalid ); } GXV_EXIT; @@ -113,7 +114,7 @@ +------ lcar --------------------+ | | | +===============+ | - | | looup header | | + | | lookup header | | | +===============+ | | | BinSrchHeader | | | +===============+ | @@ -148,7 +149,7 @@ gxv_lcar_LookupFmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -160,8 +161,8 @@ /* XXX: check range? */ offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); - p = valid->root->base + offset; - limit = valid->root->limit; + p = gxvalid->root->base + offset; + limit = gxvalid->root->limit; GXV_LIMIT_CHECK ( 2 ); value.u = FT_NEXT_USHORT( p ); @@ -185,8 +186,8 @@ { FT_Bytes p = table; FT_Bytes limit = 0; - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_lcar_DataRec lcarrec; GXV_lcar_Data lcar = &lcarrec; @@ -194,15 +195,15 @@ FT_Fixed version; - valid->root = ftvalid; - valid->table_data = lcar; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = lcar; + gxvalid->face = face; FT_TRACE3(( "validating `lcar' table\n" )); GXV_INIT; GXV_LIMIT_CHECK( 4 + 2 ); - version = FT_NEXT_ULONG( p ); + version = FT_NEXT_LONG( p ); GXV_LCAR_DATA( format ) = FT_NEXT_USHORT( p ); if ( version != 0x00010000UL) @@ -211,10 +212,10 @@ if ( GXV_LCAR_DATA( format ) > 1 ) FT_INVALID_FORMAT; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_lcar_LookupValue_validate; - valid->lookupfmt4_trans = gxv_lcar_LookupFmt4_transit; - gxv_LookupTable_validate( p, limit, valid ); + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_lcar_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_lcar_LookupFmt4_transit; + gxv_LookupTable_validate( p, limit, gxvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmod.c b/drivers/freetype/src/gxvalid/gxvmod.c index 278d47688a..e589a7fb79 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmod.c +++ b/drivers/freetype/src/gxvalid/gxvmod.c @@ -4,8 +4,8 @@ /* */ /* FreeType's TrueTypeGX/AAT validation module implementation (body). */ /* */ -/* Copyright 2004-2006, 2013 */ -/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -235,14 +235,14 @@ static const FT_Service_GXvalidateRec gxvalid_interface = { - gxv_validate + gxv_validate /* validate */ }; static const FT_Service_CKERNvalidateRec ckernvalid_interface = { - classic_kern_validate + classic_kern_validate /* validate */ }; diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmod.h b/drivers/freetype/src/gxvalid/gxvmod.h index 22732ba992..8b82e91070 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmod.h +++ b/drivers/freetype/src/gxvalid/gxvmod.h @@ -5,7 +5,8 @@ /* FreeType's TrueTypeGX/AAT validation module implementation */ /* (specification). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,8 +26,8 @@ /***************************************************************************/ -#ifndef __GXVMOD_H__ -#define __GXVMOD_H__ +#ifndef GXVMOD_H_ +#define GXVMOD_H_ #include <ft2build.h> #include FT_MODULE_H @@ -44,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __GXVMOD_H__ */ +#endif /* GXVMOD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort.c b/drivers/freetype/src/gxvalid/gxvmort.c index 5356e67ca7..b83a2b2c0f 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort.c +++ b/drivers/freetype/src/gxvalid/gxvmort.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT mort table validation (body). */ /* */ -/* Copyright 2005, 2013 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -40,7 +41,7 @@ static void gxv_mort_feature_validate( GXV_mort_feature f, - GXV_Validator valid ) + GXV_Validator gxvalid ) { if ( f->featureType >= gxv_feat_registry_length ) { @@ -89,7 +90,7 @@ gxv_mort_featurearray_validate( FT_Bytes table, FT_Bytes limit, FT_ULong nFeatureFlags, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong i; @@ -106,23 +107,24 @@ f.enableFlags = FT_NEXT_ULONG( p ); f.disableFlags = FT_NEXT_ULONG( p ); - gxv_mort_feature_validate( &f, valid ); + gxv_mort_feature_validate( &f, gxvalid ); } if ( !IS_GXV_MORT_FEATURE_OFF( f ) ) FT_INVALID_DATA; - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } FT_LOCAL_DEF( void ) gxv_mort_coverage_validate( FT_UShort coverage, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_UNUSED( valid ); + FT_UNUSED( gxvalid ); +#ifdef FT_DEBUG_LEVEL_TRACE if ( coverage & 0x8000U ) GXV_TRACE(( " this subtable is for vertical text only\n" )); else @@ -141,6 +143,7 @@ if ( coverage & 0x1FF8 ) GXV_TRACE(( " coverage has non-zero bits in reserved area\n" )); +#endif } @@ -148,7 +151,7 @@ gxv_mort_subtables_validate( FT_Bytes table, FT_Bytes limit, FT_UShort nSubtables, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -196,7 +199,7 @@ rest = length - ( 2 + 2 + 4 ); GXV_LIMIT_CHECK( rest ); - gxv_mort_coverage_validate( coverage, valid ); + gxv_mort_coverage_validate( coverage, gxvalid ); if ( type > 5 ) FT_INVALID_FORMAT; @@ -205,13 +208,13 @@ if ( func == NULL ) GXV_TRACE(( "morx type %d is reserved\n", type )); - func( p, p + rest, valid ); + func( p, p + rest, gxvalid ); p += rest; /* TODO: validate subFeatureFlags */ } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -220,7 +223,7 @@ static void gxv_mort_chain_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; #ifdef GXV_LOAD_UNUSED_VARS @@ -244,10 +247,10 @@ nSubtables = FT_NEXT_USHORT( p ); gxv_mort_featurearray_validate( p, table + chainLength, - nFeatureFlags, valid ); - p += valid->subtable_length; - gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid ); - valid->subtable_length = chainLength; + nFeatureFlags, gxvalid ); + p += gxvalid->subtable_length; + gxv_mort_subtables_validate( p, table + chainLength, nSubtables, gxvalid ); + gxvalid->subtable_length = chainLength; /* TODO: validate defaultFlags */ GXV_EXIT; @@ -259,8 +262,8 @@ FT_Face face, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; FT_Bytes p = table; FT_Bytes limit = 0; FT_ULong version; @@ -268,9 +271,9 @@ FT_ULong i; - valid->root = ftvalid; - valid->face = face; - limit = valid->root->limit; + gxvalid->root = ftvalid; + gxvalid->face = face; + limit = gxvalid->root->limit; FT_TRACE3(( "validating `mort' table\n" )); GXV_INIT; @@ -286,8 +289,8 @@ { GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); - gxv_mort_chain_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_mort_chain_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; } FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort.h b/drivers/freetype/src/gxvalid/gxvmort.h index 1e5a1f5ab6..5fd228212a 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort.h +++ b/drivers/freetype/src/gxvalid/gxvmort.h @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT common definition for mort table (specification). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVMORT_H__ -#define __GXVMORT_H__ +#ifndef GXVMORT_H_ +#define GXVMORT_H_ #include "gxvalid.h" #include "gxvcommn.h" @@ -55,39 +56,39 @@ gxv_mort_featurearray_validate( FT_Bytes table, FT_Bytes limit, FT_ULong nFeatureFlags, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_coverage_validate( FT_UShort coverage, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_subtable_type0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_subtable_type1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_subtable_type2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_subtable_type4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_mort_subtable_type5_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); -#endif /* __GXVMORT_H__ */ +#endif /* GXVMORT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort0.c b/drivers/freetype/src/gxvalid/gxvmort0.c index b136ceda27..e11f5ddc49 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort0.c +++ b/drivers/freetype/src/gxvalid/gxvmort0.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type0 (Indic Script Rearrangement) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,7 +68,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort markFirst; FT_UShort dontAdvance; @@ -125,7 +126,7 @@ FT_LOCAL_DEF( void ) gxv_mort_subtable_type0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -135,14 +136,14 @@ GXV_LIMIT_CHECK( GXV_STATETABLE_HEADER_SIZE ); - valid->statetable.optdata = NULL; - valid->statetable.optdata_load_func = NULL; - valid->statetable.subtable_setup_func = NULL; - valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = + gxvalid->statetable.optdata = NULL; + gxvalid->statetable.optdata_load_func = NULL; + gxvalid->statetable.subtable_setup_func = NULL; + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; + gxvalid->statetable.entry_validate_func = gxv_mort_subtable_type0_entry_validate; - gxv_StateTable_validate( p, limit, valid ); + gxv_StateTable_validate( p, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort1.c b/drivers/freetype/src/gxvalid/gxvmort1.c index 1c17a5d92a..fd761d0692 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort1.c +++ b/drivers/freetype/src/gxvalid/gxvmort1.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type1 (Contextual Substitution) subtable. */ /* */ -/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -53,12 +54,12 @@ static void gxv_mort_subtable_type1_substitutionTable_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_mort_subtable_type1_StateOptRecData optdata = - (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type1_StateOptRecData)gxvalid->statetable.optdata; GXV_LIMIT_CHECK( 2 ); @@ -74,14 +75,14 @@ FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort o[4]; FT_UShort *l[4]; FT_UShort buff[5]; GXV_mort_subtable_type1_StateOptRecData optdata = - (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type1_StateOptRecData)gxvalid->statetable.optdata; o[0] = classTable; @@ -93,7 +94,7 @@ l[2] = entryTable_length_p; l[3] = &( optdata->substitutionTable_length ); - gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid ); + gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, gxvalid ); } @@ -102,7 +103,7 @@ FT_Short wordOffset, const FT_String* tag, FT_Byte state, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort substTable; FT_UShort substTable_limit; @@ -113,16 +114,16 @@ substTable = ((GXV_mort_subtable_type1_StateOptRec *) - (valid->statetable.optdata))->substitutionTable; + (gxvalid->statetable.optdata))->substitutionTable; substTable_limit = (FT_UShort)( substTable + ((GXV_mort_subtable_type1_StateOptRec *) - (valid->statetable.optdata))->substitutionTable_length ); + (gxvalid->statetable.optdata))->substitutionTable_length ); - valid->min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 ); - valid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 ); - valid->max_gid = (FT_UShort)( FT_MAX( valid->max_gid, - valid->face->num_glyphs ) ); + gxvalid->min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 ); + gxvalid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 ); + gxvalid->max_gid = (FT_UShort)( FT_MAX( gxvalid->max_gid, + gxvalid->face->num_glyphs ) ); /* XXX: check range? */ @@ -137,7 +138,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort setMark; @@ -155,7 +156,7 @@ setMark = (FT_UShort)( flags >> 15 ); dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); #endif - reserved = (FT_Short)( flags & 0x3FFF ); + reserved = (FT_UShort)( flags & 0x3FFF ); markOffset = (FT_Short)( glyphOffset_p->ul >> 16 ); currentOffset = (FT_Short)( glyphOffset_p->ul ); @@ -169,29 +170,29 @@ gxv_mort_subtable_type1_offset_to_subst_validate( markOffset, "markOffset", state, - valid ); + gxvalid ); gxv_mort_subtable_type1_offset_to_subst_validate( currentOffset, "currentOffset", state, - valid ); + gxvalid ); } static void gxv_mort_subtable_type1_substTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort num_gids = (FT_UShort)( ((GXV_mort_subtable_type1_StateOptRec *) - (valid->statetable.optdata))->substitutionTable_length / 2 ); + (gxvalid->statetable.optdata))->substitutionTable_length / 2 ); FT_UShort i; GXV_NAME_ENTER( "validating contents of substitutionTable" ); - for ( i = 0; i < num_gids ; i ++ ) + for ( i = 0; i < num_gids; i++ ) { FT_UShort dst_gid; @@ -202,11 +203,11 @@ if ( dst_gid >= 0xFFFFU ) continue; - if ( dst_gid < valid->min_gid || valid->max_gid < dst_gid ) + if ( dst_gid < gxvalid->min_gid || gxvalid->max_gid < dst_gid ) { GXV_TRACE(( "substTable include a strange gid[%d]=%d >" " out of define range (%d..%d)\n", - i, dst_gid, valid->min_gid, valid->max_gid )); + i, dst_gid, gxvalid->min_gid, gxvalid->max_gid )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } } @@ -223,7 +224,7 @@ FT_LOCAL_DEF( void ) gxv_mort_subtable_type1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -234,23 +235,23 @@ GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE ); - valid->statetable.optdata = + gxvalid->statetable.optdata = &st_rec; - valid->statetable.optdata_load_func = + gxvalid->statetable.optdata_load_func = gxv_mort_subtable_type1_substitutionTable_load; - valid->statetable.subtable_setup_func = + gxvalid->statetable.subtable_setup_func = gxv_mort_subtable_type1_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_ULONG; - valid->statetable.entry_validate_func = + gxvalid->statetable.entry_validate_func = gxv_mort_subtable_type1_entry_validate; - gxv_StateTable_validate( p, limit, valid ); + gxv_StateTable_validate( p, limit, gxvalid ); gxv_mort_subtable_type1_substTable_validate( table + st_rec.substitutionTable, table + st_rec.substitutionTable + st_rec.substitutionTable_length, - valid ); + gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort2.c b/drivers/freetype/src/gxvalid/gxvmort2.c index 9e08fb792a..08455dec6b 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort2.c +++ b/drivers/freetype/src/gxvalid/gxvmort2.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type2 (Ligature Substitution) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -57,11 +58,11 @@ static void gxv_mort_subtable_type2_opttable_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table; + FT_Bytes p = table; GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type2_StateOptRecData)gxvalid->statetable.optdata; GXV_LIMIT_CHECK( 2 + 2 + 2 ); @@ -86,14 +87,14 @@ FT_UShort *classTable_length_p, FT_UShort *stateArray_length_p, FT_UShort *entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UShort o[6]; FT_UShort *l[6]; FT_UShort buff[7]; GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type2_StateOptRecData)gxvalid->statetable.optdata; GXV_NAME_ENTER( "subtable boundaries setup" ); @@ -111,7 +112,7 @@ l[4] = &(optdata->componentTable_length); l[5] = &(optdata->ligatureTable_length); - gxv_set_length_by_ushort_offset( o, l, buff, 6, table_size, valid ); + gxv_set_length_by_ushort_offset( o, l, buff, 6, table_size, gxvalid ); GXV_TRACE(( "classTable: offset=0x%04x length=0x%04x\n", classTable, *classTable_length_p )); @@ -137,11 +138,11 @@ gxv_mort_subtable_type2_ligActionOffset_validate( FT_Bytes table, FT_UShort ligActionOffset, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* access ligActionTable */ GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type2_StateOptRecData)gxvalid->statetable.optdata; FT_Bytes lat_base = table + optdata->ligActionTable; FT_Bytes p = table + ligActionOffset; @@ -214,7 +215,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort setComponent; @@ -236,16 +237,16 @@ if ( 0 < offset ) gxv_mort_subtable_type2_ligActionOffset_validate( table, offset, - valid ); + gxvalid ); } static void gxv_mort_subtable_type2_ligatureTable_validate( FT_Bytes table, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_mort_subtable_type2_StateOptRecData optdata = - (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type2_StateOptRecData)gxvalid->statetable.optdata; FT_Bytes p = table + optdata->ligatureTable; FT_Bytes limit = table + optdata->ligatureTable @@ -264,7 +265,7 @@ GXV_LIMIT_CHECK( 2 ); lig_gid = FT_NEXT_USHORT( p ); - if ( valid->face->num_glyphs < lig_gid ) + if ( gxvalid->face->num_glyphs < lig_gid ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } } @@ -275,7 +276,7 @@ FT_LOCAL_DEF( void ) gxv_mort_subtable_type2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -286,23 +287,23 @@ GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE ); - valid->statetable.optdata = + gxvalid->statetable.optdata = &lig_rec; - valid->statetable.optdata_load_func = + gxvalid->statetable.optdata_load_func = gxv_mort_subtable_type2_opttable_load; - valid->statetable.subtable_setup_func = + gxvalid->statetable.subtable_setup_func = gxv_mort_subtable_type2_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->statetable.entry_validate_func = + gxvalid->statetable.entry_validate_func = gxv_mort_subtable_type2_entry_validate; - gxv_StateTable_validate( p, limit, valid ); + gxv_StateTable_validate( p, limit, gxvalid ); - p += valid->subtable_length; - gxv_mort_subtable_type2_ligatureTable_validate( table, valid ); + p += gxvalid->subtable_length; + gxv_mort_subtable_type2_ligatureTable_validate( table, gxvalid ); - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort4.c b/drivers/freetype/src/gxvalid/gxvmort4.c index 83470988c0..6f7bbb8710 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort4.c +++ b/drivers/freetype/src/gxvalid/gxvmort4.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type4 (Non-Contextual Glyph Substitution) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,11 +42,11 @@ static void gxv_mort_subtable_type4_lookupval_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UNUSED( glyph ); - gxv_glyphid_validate( value_p->u, valid ); + gxv_glyphid_validate( value_p->u, gxvalid ); } /* @@ -80,7 +81,7 @@ FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -91,7 +92,7 @@ offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); - p = valid->lookuptbl_head + offset; + p = gxvalid->lookuptbl_head + offset; limit = lookuptbl_limit; GXV_LIMIT_CHECK( 2 ); @@ -104,7 +105,7 @@ FT_LOCAL_DEF( void ) gxv_mort_subtable_type4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -112,11 +113,11 @@ GXV_NAME_ENTER( "mort chain subtable type4 " "(Non-Contextual Glyph Substitution)" ); - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_mort_subtable_type4_lookupval_validate; - valid->lookupfmt4_trans = gxv_mort_subtable_type4_lookupfmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_mort_subtable_type4_lookupval_validate; + gxvalid->lookupfmt4_trans = gxv_mort_subtable_type4_lookupfmt4_transit; - gxv_LookupTable_validate( p, limit, valid ); + gxv_LookupTable_validate( p, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmort5.c b/drivers/freetype/src/gxvalid/gxvmort5.c index 32cfb03639..54ddbe2b15 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmort5.c +++ b/drivers/freetype/src/gxvalid/gxvmort5.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type5 (Contextual Glyph Insertion) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -70,10 +71,10 @@ FT_UShort* classTable_length_p, FT_UShort* stateArray_length_p, FT_UShort* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_mort_subtable_type5_StateOptRecData optdata = - (GXV_mort_subtable_type5_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type5_StateOptRecData)gxvalid->statetable.optdata; gxv_StateTable_subtable_setup( table_size, @@ -83,7 +84,7 @@ classTable_length_p, stateArray_length_p, entryTable_length_p, - valid ); + gxvalid ); optdata->classTable = classTable; optdata->stateArray = stateArray; @@ -100,7 +101,7 @@ FT_UShort count, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* * We don't know the range of insertion-glyph-list. @@ -109,7 +110,7 @@ FT_Bytes p = table + offset; GXV_mort_subtable_type5_StateOptRecData optdata = - (GXV_mort_subtable_type5_StateOptRecData)valid->statetable.optdata; + (GXV_mort_subtable_type5_StateOptRecData)gxvalid->statetable.optdata; if ( optdata->classTable < offset && offset < optdata->classTable + *(optdata->classTable_length_p) ) @@ -145,7 +146,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_Bool setMark; @@ -184,7 +185,7 @@ currentInsertCount, table, limit, - valid ); + gxvalid ); } if ( 0 != markedInsertList && 0 != markedInsertCount ) @@ -193,7 +194,7 @@ markedInsertCount, table, limit, - valid ); + gxvalid ); } } @@ -201,7 +202,7 @@ FT_LOCAL_DEF( void ) gxv_mort_subtable_type5_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -213,18 +214,18 @@ GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE5_HEADER_SIZE ); - valid->statetable.optdata = + gxvalid->statetable.optdata = et; - valid->statetable.optdata_load_func = + gxvalid->statetable.optdata_load_func = NULL; - valid->statetable.subtable_setup_func = + gxvalid->statetable.subtable_setup_func = gxv_mort_subtable_type5_subtable_setup; - valid->statetable.entry_glyphoffset_fmt = + gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_ULONG; - valid->statetable.entry_validate_func = + gxvalid->statetable.entry_validate_func = gxv_mort_subtable_type5_entry_validate; - gxv_StateTable_validate( p, limit, valid ); + gxv_StateTable_validate( p, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx.c b/drivers/freetype/src/gxvalid/gxvmorx.c index 5ae04d3212..a3abe435a6 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx.c +++ b/drivers/freetype/src/gxvalid/gxvmorx.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT morx table validation (body). */ /* */ -/* Copyright 2005, 2008, 2013 by */ +/* Copyright 2005-2016 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -42,7 +42,7 @@ gxv_morx_subtables_validate( FT_Bytes table, FT_Bytes limit, FT_UShort nSubtables, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -93,7 +93,7 @@ /* morx coverage consists of mort_coverage & 16bit padding */ gxv_mort_coverage_validate( (FT_UShort)( ( coverage >> 16 ) | coverage ), - valid ); + gxvalid ); if ( type > 5 ) FT_INVALID_FORMAT; @@ -101,13 +101,13 @@ if ( func == NULL ) GXV_TRACE(( "morx type %d is reserved\n", type )); - func( p, p + rest, valid ); + func( p, p + rest, gxvalid ); /* TODO: subFeatureFlags should be unique in a table? */ p += rest; } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -116,7 +116,7 @@ static void gxv_morx_chain_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; #ifdef GXV_LOAD_UNUSED_VARS @@ -140,16 +140,16 @@ nSubtables = FT_NEXT_ULONG( p ); /* feature-array of morx is same with that of mort */ - gxv_mort_featurearray_validate( p, limit, nFeatureFlags, valid ); - p += valid->subtable_length; + gxv_mort_featurearray_validate( p, limit, nFeatureFlags, gxvalid ); + p += gxvalid->subtable_length; if ( nSubtables >= 0x10000L ) FT_INVALID_DATA; gxv_morx_subtables_validate( p, table + chainLength, - (FT_UShort)nSubtables, valid ); + (FT_UShort)nSubtables, gxvalid ); - valid->subtable_length = chainLength; + gxvalid->subtable_length = chainLength; /* TODO: defaultFlags should be compared with the flags in tables */ @@ -162,8 +162,8 @@ FT_Face face, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; FT_Bytes p = table; FT_Bytes limit = 0; FT_ULong version; @@ -171,8 +171,8 @@ FT_ULong i; - valid->root = ftvalid; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->face = face; FT_TRACE3(( "validating `morx' table\n" )); GXV_INIT; @@ -188,8 +188,8 @@ { GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); - gxv_morx_chain_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_morx_chain_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; } FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx.h b/drivers/freetype/src/gxvalid/gxvmorx.h index 28c1a44f6f..9ba25c14a4 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx.h +++ b/drivers/freetype/src/gxvalid/gxvmorx.h @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT common definition for morx table (specification). */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVMORX_H__ -#define __GXVMORX_H__ +#ifndef GXVMORX_H_ +#define GXVMORX_H_ #include "gxvalid.h" @@ -38,30 +39,30 @@ FT_LOCAL( void ) gxv_morx_subtable_type0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_morx_subtable_type1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_morx_subtable_type2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_morx_subtable_type4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); FT_LOCAL( void ) gxv_morx_subtable_type5_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ); + GXV_Validator gxvalid ); -#endif /* __GXVMORX_H__ */ +#endif /* GXVMORX_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx0.c b/drivers/freetype/src/gxvalid/gxvmorx0.c index 6a736c1775..4abb7368f2 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx0.c +++ b/drivers/freetype/src/gxvalid/gxvmorx0.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type0 (Indic Script Rearrangement) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +46,7 @@ GXV_XStateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort markFirst; @@ -85,7 +86,7 @@ FT_LOCAL_DEF( void ) gxv_morx_subtable_type0_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -95,14 +96,14 @@ GXV_LIMIT_CHECK( GXV_STATETABLE_HEADER_SIZE ); - valid->xstatetable.optdata = NULL; - valid->xstatetable.optdata_load_func = NULL; - valid->xstatetable.subtable_setup_func = NULL; - valid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; - valid->xstatetable.entry_validate_func = + gxvalid->xstatetable.optdata = NULL; + gxvalid->xstatetable.optdata_load_func = NULL; + gxvalid->xstatetable.subtable_setup_func = NULL; + gxvalid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; + gxvalid->xstatetable.entry_validate_func = gxv_morx_subtable_type0_entry_validate; - gxv_XStateTable_validate( p, limit, valid ); + gxv_XStateTable_validate( p, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx1.c b/drivers/freetype/src/gxvalid/gxvmorx1.c index ce0009a16f..e581848c2b 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx1.c +++ b/drivers/freetype/src/gxvalid/gxvmorx1.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type1 (Contextual Substitution) subtable. */ /* */ -/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -55,12 +56,12 @@ static void gxv_morx_subtable_type1_substitutionTable_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type1_StateOptRecData)gxvalid->xstatetable.optdata; GXV_LIMIT_CHECK( 2 ); @@ -76,14 +77,14 @@ FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_ULong o[4]; FT_ULong *l[4]; FT_ULong buff[5]; GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type1_StateOptRecData)gxvalid->xstatetable.optdata; o[0] = classTable; @@ -95,7 +96,7 @@ l[2] = entryTable_length_p; l[3] = &(optdata->substitutionTable_length); - gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid ); + gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, gxvalid ); } @@ -106,7 +107,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_TRACE_VARS FT_UShort setMark; @@ -117,7 +118,7 @@ FT_Short currentIndex; GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type1_StateOptRecData)gxvalid->xstatetable.optdata; FT_UNUSED( state ); FT_UNUSED( table ); @@ -148,24 +149,24 @@ if ( optdata->substitutionTable_num_lookupTables < markIndex + 1 ) optdata->substitutionTable_num_lookupTables = - (FT_Short)( markIndex + 1 ); + (FT_UShort)( markIndex + 1 ); if ( optdata->substitutionTable_num_lookupTables < currentIndex + 1 ) optdata->substitutionTable_num_lookupTables = - (FT_Short)( currentIndex + 1 ); + (FT_UShort)( currentIndex + 1 ); } static void gxv_morx_subtable_type1_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_UNUSED( glyph ); /* for the non-debugging case */ GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value_p->u )); - if ( value_p->u > valid->face->num_glyphs ) + if ( value_p->u > gxvalid->face->num_glyphs ) FT_INVALID_GLYPH_ID; } @@ -175,7 +176,7 @@ FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -186,7 +187,7 @@ offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); - p = valid->lookuptbl_head + offset; + p = gxvalid->lookuptbl_head + offset; limit = lookuptbl_limit; GXV_LIMIT_CHECK ( 2 ); @@ -202,19 +203,19 @@ static void gxv_morx_subtable_type1_substitutionTable_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort i; GXV_morx_subtable_type1_StateOptRecData optdata = - (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type1_StateOptRecData)gxvalid->xstatetable.optdata; /* TODO: calculate offset/length for each lookupTables */ - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_morx_subtable_type1_LookupValue_validate; - valid->lookupfmt4_trans = gxv_morx_subtable_type1_LookupFmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_morx_subtable_type1_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_morx_subtable_type1_LookupFmt4_transit; for ( i = 0; i < optdata->substitutionTable_num_lookupTables; i++ ) { @@ -224,7 +225,7 @@ GXV_LIMIT_CHECK( 4 ); offset = FT_NEXT_ULONG( p ); - gxv_LookupTable_validate( table + offset, limit, valid ); + gxv_LookupTable_validate( table + offset, limit, gxvalid ); } /* TODO: overlapping of lookupTables in substitutionTable */ @@ -239,7 +240,7 @@ FT_LOCAL_DEF( void ) gxv_morx_subtable_type1_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -252,23 +253,23 @@ st_rec.substitutionTable_num_lookupTables = 0; - valid->xstatetable.optdata = + gxvalid->xstatetable.optdata = &st_rec; - valid->xstatetable.optdata_load_func = + gxvalid->xstatetable.optdata_load_func = gxv_morx_subtable_type1_substitutionTable_load; - valid->xstatetable.subtable_setup_func = + gxvalid->xstatetable.subtable_setup_func = gxv_morx_subtable_type1_subtable_setup; - valid->xstatetable.entry_glyphoffset_fmt = + gxvalid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_ULONG; - valid->xstatetable.entry_validate_func = + gxvalid->xstatetable.entry_validate_func = gxv_morx_subtable_type1_entry_validate; - gxv_XStateTable_validate( p, limit, valid ); + gxv_XStateTable_validate( p, limit, gxvalid ); gxv_morx_subtable_type1_substitutionTable_validate( table + st_rec.substitutionTable, table + st_rec.substitutionTable + st_rec.substitutionTable_length, - valid ); + gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx2.c b/drivers/freetype/src/gxvalid/gxvmorx2.c index 9d2b0bc4af..9495cca489 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx2.c +++ b/drivers/freetype/src/gxvalid/gxvmorx2.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type2 (Ligature Substitution) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,12 +59,12 @@ static void gxv_morx_subtable_type2_opttable_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type2_StateOptRecData)gxvalid->xstatetable.optdata; GXV_LIMIT_CHECK( 4 + 4 + 4 ); @@ -88,14 +89,14 @@ FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_ULong o[6]; FT_ULong* l[6]; FT_ULong buff[7]; GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type2_StateOptRecData)gxvalid->xstatetable.optdata; GXV_NAME_ENTER( "subtable boundaries setup" ); @@ -113,7 +114,7 @@ l[4] = &(optdata->componentTable_length); l[5] = &(optdata->ligatureTable_length); - gxv_set_length_by_ulong_offset( o, l, buff, 6, table_size, valid ); + gxv_set_length_by_ulong_offset( o, l, buff, 6, table_size, gxvalid ); GXV_TRACE(( "classTable: offset=0x%08x length=0x%08x\n", classTable, *classTable_length_p )); @@ -142,11 +143,11 @@ gxv_morx_subtable_type2_ligActionIndex_validate( FT_Bytes table, FT_UShort ligActionIndex, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* access ligActionTable */ GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type2_StateOptRecData)gxvalid->xstatetable.optdata; FT_Bytes lat_base = table + optdata->ligActionTable; FT_Bytes p = lat_base + @@ -188,7 +189,8 @@ /* it is different from the location offset in mort */ if ( ( offset & 0x3FFF0000UL ) == 0x3FFF0000UL ) { /* negative offset */ - gid_limit = valid->face->num_glyphs - ( offset & 0x0000FFFFUL ); + gid_limit = gxvalid->face->num_glyphs - + (FT_Long)( offset & 0x0000FFFFUL ); if ( gid_limit > 0 ) return; @@ -198,9 +200,9 @@ offset & 0xFFFFU )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET ); } - else if ( ( offset & 0x3FFF0000UL ) == 0x0000000UL ) + else if ( ( offset & 0x3FFF0000UL ) == 0x00000000UL ) { /* positive offset */ - if ( (FT_Long)offset < valid->face->num_glyphs ) + if ( (FT_Long)offset < gxvalid->face->num_glyphs ) return; GXV_TRACE(( "ligature action table includes" @@ -225,7 +227,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort setComponent; @@ -253,16 +255,16 @@ if ( 0 < ligActionIndex ) gxv_morx_subtable_type2_ligActionIndex_validate( - table, ligActionIndex, valid ); + table, ligActionIndex, gxvalid ); } static void gxv_morx_subtable_type2_ligatureTable_validate( FT_Bytes table, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_morx_subtable_type2_StateOptRecData optdata = - (GXV_morx_subtable_type2_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type2_StateOptRecData)gxvalid->xstatetable.optdata; FT_Bytes p = table + optdata->ligatureTable; FT_Bytes limit = table + optdata->ligatureTable @@ -281,7 +283,7 @@ GXV_LIMIT_CHECK( 2 ); lig_gid = FT_NEXT_USHORT( p ); - if ( lig_gid < valid->face->num_glyphs ) + if ( lig_gid < gxvalid->face->num_glyphs ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } } @@ -293,7 +295,7 @@ FT_LOCAL_DEF( void ) gxv_morx_subtable_type2_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -304,21 +306,23 @@ GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE2_HEADER_SIZE ); - valid->xstatetable.optdata = + gxvalid->xstatetable.optdata = &lig_rec; - valid->xstatetable.optdata_load_func = + gxvalid->xstatetable.optdata_load_func = gxv_morx_subtable_type2_opttable_load; - valid->xstatetable.subtable_setup_func = + gxvalid->xstatetable.subtable_setup_func = gxv_morx_subtable_type2_subtable_setup; - valid->xstatetable.entry_glyphoffset_fmt = + gxvalid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_USHORT; - valid->xstatetable.entry_validate_func = + gxvalid->xstatetable.entry_validate_func = gxv_morx_subtable_type2_entry_validate; - gxv_XStateTable_validate( p, limit, valid ); + gxv_XStateTable_validate( p, limit, gxvalid ); - p += valid->subtable_length; - gxv_morx_subtable_type2_ligatureTable_validate( table, valid ); +#if 0 + p += gxvalid->subtable_length; +#endif + gxv_morx_subtable_type2_ligatureTable_validate( table, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx4.c b/drivers/freetype/src/gxvalid/gxvmorx4.c index c0d2f78e39..3b7731bbce 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx4.c +++ b/drivers/freetype/src/gxvalid/gxvmorx4.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT morx table validation */ /* body for "morx" type4 (Non-Contextual Glyph Substitution) subtable. */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,12 +42,12 @@ FT_LOCAL_DEF( void ) gxv_morx_subtable_type4_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_NAME_ENTER( "morx chain subtable type4 " "(Non-Contextual Glyph Substitution)" ); - gxv_mort_subtable_type4_validate( table, limit, valid ); + gxv_mort_subtable_type4_validate( table, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvmorx5.c b/drivers/freetype/src/gxvalid/gxvmorx5.c index d8cf700797..0e96166c02 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvmorx5.c +++ b/drivers/freetype/src/gxvalid/gxvmorx5.c @@ -5,7 +5,8 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type5 (Contextual Glyph Insertion) subtable. */ /* */ -/* Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -64,12 +65,12 @@ static void gxv_morx_subtable_type5_insertionGlyphList_load( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_morx_subtable_type5_StateOptRecData optdata = - (GXV_morx_subtable_type5_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type5_StateOptRecData)gxvalid->xstatetable.optdata; GXV_LIMIT_CHECK( 4 ); @@ -85,14 +86,14 @@ FT_ULong* classTable_length_p, FT_ULong* stateArray_length_p, FT_ULong* entryTable_length_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_ULong o[4]; FT_ULong* l[4]; FT_ULong buff[5]; GXV_morx_subtable_type5_StateOptRecData optdata = - (GXV_morx_subtable_type5_StateOptRecData)valid->xstatetable.optdata; + (GXV_morx_subtable_type5_StateOptRecData)gxvalid->xstatetable.optdata; o[0] = classTable; @@ -104,7 +105,7 @@ l[2] = entryTable_length_p; l[3] = &(optdata->insertionGlyphList_length); - gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid ); + gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, gxvalid ); } @@ -113,9 +114,9 @@ FT_UShort count, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table + table_index * 2; + FT_Bytes p = table + table_index * 2; #ifndef GXV_LOAD_TRACE_VARS @@ -143,7 +144,7 @@ GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_Bool setMark; @@ -180,20 +181,20 @@ gxv_morx_subtable_type5_InsertList_validate( currentInsertList, currentInsertCount, table, limit, - valid ); + gxvalid ); if ( markedInsertList && 0 != markedInsertCount ) gxv_morx_subtable_type5_InsertList_validate( markedInsertList, markedInsertCount, table, limit, - valid ); + gxvalid ); } FT_LOCAL_DEF( void ) gxv_morx_subtable_type5_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; @@ -205,18 +206,18 @@ GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE5_HEADER_SIZE ); - valid->xstatetable.optdata = + gxvalid->xstatetable.optdata = et; - valid->xstatetable.optdata_load_func = + gxvalid->xstatetable.optdata_load_func = gxv_morx_subtable_type5_insertionGlyphList_load; - valid->xstatetable.subtable_setup_func = + gxvalid->xstatetable.subtable_setup_func = gxv_morx_subtable_type5_subtable_setup; - valid->xstatetable.entry_glyphoffset_fmt = + gxvalid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_ULONG; - valid->xstatetable.entry_validate_func = + gxvalid->xstatetable.entry_validate_func = gxv_morx_subtable_type5_entry_validate; - gxv_XStateTable_validate( p, limit, valid ); + gxv_XStateTable_validate( p, limit, gxvalid ); GXV_EXIT; } diff --git a/drivers/freetype/freetype/src/gxvalid/gxvopbd.c b/drivers/freetype/src/gxvalid/gxvopbd.c index e125060946..e3ba082e16 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvopbd.c +++ b/drivers/freetype/src/gxvalid/gxvopbd.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT opbd table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,11 +69,11 @@ static void gxv_opbd_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { /* offset in LookupTable is measured from the head of opbd table */ - FT_Bytes p = valid->root->base + value_p->u; - FT_Bytes limit = valid->root->limit; + FT_Bytes p = gxvalid->root->base + value_p->u; + FT_Bytes limit = gxvalid->root->limit; FT_Short delta_value; int i; @@ -90,7 +91,7 @@ if ( delta_value == -1 ) continue; - gxv_ctlPoint_validate( glyph, delta_value, valid ); + gxv_ctlPoint_validate( glyph, (FT_UShort)delta_value, gxvalid ); } else /* format 0, value is distance */ continue; @@ -134,12 +135,12 @@ gxv_opbd_LookupFmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { GXV_LookupValueDesc value; FT_UNUSED( lookuptbl_limit ); - FT_UNUSED( valid ); + FT_UNUSED( gxvalid ); /* XXX: check range? */ value.u = (FT_UShort)( base_value_p->u + @@ -162,8 +163,8 @@ FT_Face face, FT_Validator ftvalid ) { - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_opbd_DataRec opbdrec; GXV_opbd_Data opbd = &opbdrec; FT_Bytes p = table; @@ -172,9 +173,9 @@ FT_ULong version; - valid->root = ftvalid; - valid->table_data = opbd; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = opbd; + gxvalid->face = face; FT_TRACE3(( "validating `opbd' table\n" )); GXV_INIT; @@ -196,12 +197,12 @@ if ( 0x0001 < GXV_OPBD_DATA( format ) ) FT_INVALID_FORMAT; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_opbd_LookupValue_validate; - valid->lookupfmt4_trans = gxv_opbd_LookupFmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_opbd_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_opbd_LookupFmt4_transit; - gxv_LookupTable_validate( p, limit, valid ); - p += valid->subtable_length; + gxv_LookupTable_validate( p, limit, gxvalid ); + p += gxvalid->subtable_length; if ( p > table + GXV_OPBD_DATA( valueOffset_min ) ) { diff --git a/drivers/freetype/freetype/src/gxvalid/gxvprop.c b/drivers/freetype/src/gxvalid/gxvprop.c index 0be21336f8..61b3aeee30 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvprop.c +++ b/drivers/freetype/src/gxvalid/gxvprop.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT prop table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -75,7 +76,7 @@ static void gxv_prop_zero_advance_validate( FT_UShort gid, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Face face; FT_Error error; @@ -84,7 +85,7 @@ GXV_NAME_ENTER( "zero advance" ); - face = valid->face; + face = gxvalid->face; error = FT_Load_Glyph( face, gid, @@ -109,10 +110,10 @@ static void gxv_prop_property_validate( FT_UShort property, FT_UShort glyph, - GXV_Validator valid ) + GXV_Validator gxvalid ) { if ( glyph != 0 && ( property & GXV_PROP_FLOATER ) ) - gxv_prop_zero_advance_validate( glyph, valid ); + gxv_prop_zero_advance_validate( glyph, gxvalid ); if ( property & GXV_PROP_USE_COMPLEMENTARY_BRACKET ) { @@ -145,7 +146,7 @@ else { /* The gid for complement must be the face. */ - gxv_glyphid_validate( (FT_UShort)( glyph + complement ), valid ); + gxv_glyphid_validate( (FT_UShort)( glyph + complement ), gxvalid ); } } else @@ -187,9 +188,9 @@ static void gxv_prop_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - gxv_prop_property_validate( value_p->u, glyph, valid ); + gxv_prop_property_validate( value_p->u, glyph, gxvalid ); } @@ -224,7 +225,7 @@ gxv_prop_LookupFmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p; FT_Bytes limit; @@ -234,7 +235,7 @@ /* XXX: check range? */ offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); - p = valid->lookuptbl_head + offset; + p = gxvalid->lookuptbl_head + offset; limit = lookuptbl_limit; GXV_LIMIT_CHECK ( 2 ); @@ -259,8 +260,8 @@ { FT_Bytes p = table; FT_Bytes limit = 0; - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_prop_DataRec proprec; GXV_prop_Data prop = &proprec; @@ -270,15 +271,15 @@ FT_UShort defaultProp; - valid->root = ftvalid; - valid->table_data = prop; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = prop; + gxvalid->face = face; FT_TRACE3(( "validating `prop' table\n" )); GXV_INIT; GXV_LIMIT_CHECK( 4 + 2 + 2 ); - version = FT_NEXT_ULONG( p ); + version = FT_NEXT_LONG( p ); format = FT_NEXT_USHORT( p ); defaultProp = FT_NEXT_USHORT( p ); @@ -303,7 +304,7 @@ FT_INVALID_FORMAT; } - gxv_prop_property_validate( defaultProp, 0, valid ); + gxv_prop_property_validate( defaultProp, 0, gxvalid ); if ( format == 0 ) { @@ -315,11 +316,11 @@ /* format == 1 */ GXV_PROP_DATA( version ) = version; - valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; - valid->lookupval_func = gxv_prop_LookupValue_validate; - valid->lookupfmt4_trans = gxv_prop_LookupFmt4_transit; + gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; + gxvalid->lookupval_func = gxv_prop_LookupValue_validate; + gxvalid->lookupfmt4_trans = gxv_prop_LookupFmt4_transit; - gxv_LookupTable_validate( p, limit, valid ); + gxv_LookupTable_validate( p, limit, gxvalid ); Exit: FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/freetype/src/gxvalid/gxvtrak.c b/drivers/freetype/src/gxvalid/gxvtrak.c index 11fbd7ccfb..0f07c04e2a 100644 --- a/drivers/freetype/freetype/src/gxvalid/gxvtrak.c +++ b/drivers/freetype/src/gxvalid/gxvtrak.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT trak table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004-2016 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -48,7 +49,7 @@ /* * referred track table format specification: - * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6trak.html + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html * last update was 1996. * ---------------------------------------------- * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN @@ -93,9 +94,9 @@ gxv_trak_trackTable_validate( FT_Bytes table, FT_Bytes limit, FT_UShort nTracks, - GXV_Validator valid ) + GXV_Validator gxvalid ) { - FT_Bytes p = table; + FT_Bytes p = table; FT_Fixed track, t; FT_UShort nameIndex; @@ -110,7 +111,7 @@ GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) ); - for ( i = 0; i < nTracks; i ++ ) + for ( i = 0; i < nTracks; i++ ) { p = table + i * ( 4 + 2 + 2 ); track = FT_NEXT_LONG( p ); @@ -122,9 +123,9 @@ if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) ) GXV_TRAK_DATA( trackValueOffset_max ) = offset; - gxv_sfntName_validate( nameIndex, 256, 32767, valid ); + gxv_sfntName_validate( nameIndex, 256, 32767, gxvalid ); - for ( j = i; j < nTracks; j ++ ) + for ( j = i; j < nTracks; j++ ) { p = table + j * ( 4 + 2 + 2 ); t = FT_NEXT_LONG( p ); @@ -134,7 +135,7 @@ } } - valid->subtable_length = p - table; + gxvalid->subtable_length = (FT_ULong)( p - table ); GXV_EXIT; } @@ -142,7 +143,7 @@ static void gxv_trak_trackData_validate( FT_Bytes table, FT_Bytes limit, - GXV_Validator valid ) + GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort nTracks; @@ -161,34 +162,35 @@ nSizes = FT_NEXT_USHORT( p ); sizeTableOffset = FT_NEXT_ULONG( p ); - gxv_odtect_add_range( table, p - table, "trackData header", odtect ); + gxv_odtect_add_range( table, (FT_ULong)( p - table ), + "trackData header", odtect ); /* validate trackTable */ - gxv_trak_trackTable_validate( p, limit, nTracks, valid ); - gxv_odtect_add_range( p, valid->subtable_length, + gxv_trak_trackTable_validate( p, limit, nTracks, gxvalid ); + gxv_odtect_add_range( p, gxvalid->subtable_length, "trackTable", odtect ); /* sizeTable is array of FT_Fixed, don't check contents */ - p = valid->root->base + sizeTableOffset; + p = gxvalid->root->base + sizeTableOffset; GXV_LIMIT_CHECK( nSizes * 4 ); gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect ); /* validate trackValueOffet */ - p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min ); + p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_min ); if ( limit - p < nTracks * nSizes * 2 ) GXV_TRACE(( "too short trackValue array\n" )); - p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max ); + p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_max ); GXV_LIMIT_CHECK( nSizes * 2 ); - gxv_odtect_add_range( valid->root->base + gxv_odtect_add_range( gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_min ), GXV_TRAK_DATA( trackValueOffset_max ) - GXV_TRAK_DATA( trackValueOffset_min ) + nSizes * 2, "trackValue array", odtect ); - gxv_odtect_validate( odtect, valid ); + gxv_odtect_validate( odtect, gxvalid ); GXV_EXIT; } @@ -210,8 +212,8 @@ FT_Bytes p = table; FT_Bytes limit = 0; - GXV_ValidatorRec validrec; - GXV_Validator valid = &validrec; + GXV_ValidatorRec gxvalidrec; + GXV_Validator gxvalid = &gxvalidrec; GXV_trak_DataRec trakrec; GXV_trak_Data trak = &trakrec; @@ -225,11 +227,11 @@ GXV_ODTECT( 3, odtect ); GXV_ODTECT_INIT( odtect ); - valid->root = ftvalid; - valid->table_data = trak; - valid->face = face; + gxvalid->root = ftvalid; + gxvalid->table_data = trak; + gxvalid->face = face; - limit = valid->root->limit; + limit = gxvalid->root->limit; FT_TRACE3(( "validating `trak' table\n" )); GXV_INIT; @@ -265,19 +267,19 @@ /* validate trackData */ if ( 0 < horizOffset ) { - gxv_trak_trackData_validate( table + horizOffset, limit, valid ); - gxv_odtect_add_range( table + horizOffset, valid->subtable_length, + gxv_trak_trackData_validate( table + horizOffset, limit, gxvalid ); + gxv_odtect_add_range( table + horizOffset, gxvalid->subtable_length, "horizJustData", odtect ); } if ( 0 < vertOffset ) { - gxv_trak_trackData_validate( table + vertOffset, limit, valid ); - gxv_odtect_add_range( table + vertOffset, valid->subtable_length, + gxv_trak_trackData_validate( table + vertOffset, limit, gxvalid ); + gxv_odtect_add_range( table + vertOffset, gxvalid->subtable_length, "vertJustData", odtect ); } - gxv_odtect_validate( odtect, valid ); + gxv_odtect_validate( odtect, gxvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/freetype/src/gxvalid/module.mk b/drivers/freetype/src/gxvalid/module.mk index 9fd098e2c5..b431384a5c 100644 --- a/drivers/freetype/freetype/src/gxvalid/module.mk +++ b/drivers/freetype/src/gxvalid/module.mk @@ -2,9 +2,9 @@ # FreeType 2 gxvalid module definition # -# Copyright 2004, 2005, 2006 -# by suzuki toshiya, Masatake YAMATO, Red Hat K.K., -# David Turner, Robert Wilhelm, and Werner Lemberg. +# Copyright 2004-2016 by +# suzuki toshiya, Masatake YAMATO, Red Hat K.K., +# David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, # and distributed under the terms of the FreeType project license, diff --git a/drivers/freetype/freetype/src/gxvalid/rules.mk b/drivers/freetype/src/gxvalid/rules.mk index 57bc0823db..424f2a6377 100644 --- a/drivers/freetype/freetype/src/gxvalid/rules.mk +++ b/drivers/freetype/src/gxvalid/rules.mk @@ -3,7 +3,8 @@ # -# Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., +# Copyright 2004-2016 by +# suzuki toshiya, Masatake YAMATO, Red Hat K.K., # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +21,10 @@ GXV_DIR := $(SRC_DIR)/gxvalid # compilation flags for the driver # -GXV_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(GXV_DIR)) +GXV_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(GXV_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # GXV driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/otvalid/Jamfile b/drivers/freetype/src/otvalid/Jamfile index b457143de4..eded89ab9f 100644 --- a/drivers/freetype/freetype/src/otvalid/Jamfile +++ b/drivers/freetype/src/otvalid/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/otvalid Jamfile # -# Copyright 2004 by +# Copyright 2004-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,15 @@ SubDir FT2_TOP $(FT2_SRC_DIR) otvalid ; if $(FT2_MULTI) { - _sources = otvbase otvcommn otvgdef otvgpos otvgsub otvjstf otvmod otvmath ; + _sources = otvbase + otvcommn + otvgdef + otvgpos + otvgsub + otvjstf + otvmath + otvmod + ; } else { diff --git a/drivers/freetype/freetype/src/otvalid/module.mk b/drivers/freetype/src/otvalid/module.mk index 9cadde55e4..b929cdbab0 100644 --- a/drivers/freetype/freetype/src/otvalid/module.mk +++ b/drivers/freetype/src/otvalid/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2004, 2006 by +# Copyright 2004-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/otvalid/otvalid.c b/drivers/freetype/src/otvalid/otvalid.c index d5c2b75abb..932a974a31 100644 --- a/drivers/freetype/freetype/src/otvalid/otvalid.c +++ b/drivers/freetype/src/otvalid/otvalid.c @@ -4,7 +4,7 @@ /* */ /* FreeType validator for OpenType tables (body only). */ /* */ -/* Copyright 2004, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/otvalid/otvalid.h b/drivers/freetype/src/otvalid/otvalid.h index eb99b9cc48..93438a0639 100644 --- a/drivers/freetype/freetype/src/otvalid/otvalid.h +++ b/drivers/freetype/src/otvalid/otvalid.h @@ -4,7 +4,7 @@ /* */ /* OpenType table validation (specification only). */ /* */ -/* Copyright 2004, 2008 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __OTVALID_H__ -#define __OTVALID_H__ +#ifndef OTVALID_H_ +#define OTVALID_H_ #include <ft2build.h> @@ -72,7 +72,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVALID_H__ */ +#endif /* OTVALID_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvbase.c b/drivers/freetype/src/otvalid/otvbase.c index d742d2dc95..e86e8bb2f0 100644 --- a/drivers/freetype/freetype/src/otvalid/otvbase.c +++ b/drivers/freetype/src/otvalid/otvbase.c @@ -4,7 +4,7 @@ /* */ /* OpenType BASE table validation (body). */ /* */ -/* Copyright 2004, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,7 +32,7 @@ static void otv_BaseCoord_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BaseCoordFormat; @@ -58,7 +58,7 @@ case 3: /* BaseCoordFormat3 */ OTV_LIMIT_CHECK( 2 ); /* DeviceTable */ - otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid ); break; default: @@ -71,7 +71,7 @@ static void otv_BaseTagList_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BaseTagCount; @@ -93,7 +93,7 @@ static void otv_BaseValues_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BaseCoordCount; @@ -112,7 +112,7 @@ /* BaseCoord */ for ( ; BaseCoordCount > 0; BaseCoordCount-- ) - otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; } @@ -120,7 +120,7 @@ static void otv_MinMax_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; @@ -144,11 +144,11 @@ OTV_SIZE_CHECK( MinCoord ); if ( MinCoord ) - otv_BaseCoord_validate( table + MinCoord, valid ); + otv_BaseCoord_validate( table + MinCoord, otvalid ); OTV_SIZE_CHECK( MaxCoord ); if ( MaxCoord ) - otv_BaseCoord_validate( table + MaxCoord, valid ); + otv_BaseCoord_validate( table + MaxCoord, otvalid ); OTV_LIMIT_CHECK( FeatMinMaxCount * 8 ); @@ -162,11 +162,11 @@ OTV_SIZE_CHECK( MinCoord ); if ( MinCoord ) - otv_BaseCoord_validate( table + MinCoord, valid ); + otv_BaseCoord_validate( table + MinCoord, otvalid ); OTV_SIZE_CHECK( MaxCoord ); if ( MaxCoord ) - otv_BaseCoord_validate( table + MaxCoord, valid ); + otv_BaseCoord_validate( table + MaxCoord, otvalid ); } OTV_EXIT; @@ -175,7 +175,7 @@ static void otv_BaseScript_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; @@ -198,11 +198,11 @@ OTV_SIZE_CHECK( BaseValues ); if ( BaseValues ) - otv_BaseValues_validate( table + BaseValues, valid ); + otv_BaseValues_validate( table + BaseValues, otvalid ); OTV_SIZE_CHECK( DefaultMinMax ); if ( DefaultMinMax ) - otv_MinMax_validate( table + DefaultMinMax, valid ); + otv_MinMax_validate( table + DefaultMinMax, otvalid ); OTV_LIMIT_CHECK( BaseLangSysCount * 6 ); @@ -211,7 +211,7 @@ { p += 4; /* skip BaseLangSysTag */ - otv_MinMax_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_MinMax_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; @@ -220,7 +220,7 @@ static void otv_BaseScriptList_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BaseScriptCount; @@ -241,7 +241,7 @@ p += 4; /* skip BaseScriptTag */ /* BaseScript */ - otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; @@ -250,7 +250,7 @@ static void otv_Axis_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; @@ -267,10 +267,10 @@ OTV_SIZE_CHECK( BaseTagList ); if ( BaseTagList ) - otv_BaseTagList_validate( table + BaseTagList, valid ); + otv_BaseTagList_validate( table + BaseTagList, otvalid ); /* BaseScriptList */ - otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; } @@ -280,16 +280,16 @@ otv_BASE_validate( FT_Bytes table, FT_Validator ftvalid ) { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; + OTV_ValidatorRec otvalidrec; + OTV_Validator otvalid = &otvalidrec; + FT_Bytes p = table; FT_UInt table_size; OTV_OPTIONAL_TABLE( HorizAxis ); OTV_OPTIONAL_TABLE( VertAxis ); - valid->root = ftvalid; + otvalid->root = ftvalid; FT_TRACE3(( "validating BASE table\n" )); OTV_INIT; @@ -304,12 +304,12 @@ OTV_OPTIONAL_OFFSET( HorizAxis ); OTV_SIZE_CHECK( HorizAxis ); if ( HorizAxis ) - otv_Axis_validate( table + HorizAxis, valid ); + otv_Axis_validate( table + HorizAxis, otvalid ); OTV_OPTIONAL_OFFSET( VertAxis ); OTV_SIZE_CHECK( VertAxis ); if ( VertAxis ) - otv_Axis_validate( table + VertAxis, valid ); + otv_Axis_validate( table + VertAxis, otvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/freetype/src/otvalid/otvcommn.c b/drivers/freetype/src/otvalid/otvcommn.c index a4f885b51f..2e88e102be 100644 --- a/drivers/freetype/freetype/src/otvalid/otvcommn.c +++ b/drivers/freetype/src/otvalid/otvcommn.c @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (body). */ /* */ -/* Copyright 2004, 2005, 2006, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,7 +39,7 @@ FT_LOCAL_DEF( void ) otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid, + OTV_Validator otvalid, FT_Int expected_count ) { FT_Bytes p = table; @@ -74,7 +74,7 @@ gid = FT_NEXT_USHORT( p ); - if ( gid >= valid->glyph_count ) + if ( gid >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; } @@ -104,7 +104,7 @@ if ( Start > End || StartCoverageIndex != total ) FT_INVALID_DATA; - if ( End >= valid->glyph_count ) + if ( End >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; if ( n > 0 && Start <= last ) @@ -219,7 +219,7 @@ FT_LOCAL_DEF( void ) otv_ClassDef_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt ClassFormat; @@ -249,7 +249,7 @@ OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */ - if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count ) + if ( StartGlyph + GlyphCount - 1 >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; } break; @@ -276,7 +276,7 @@ if ( Start > End || ( n > 0 && Start <= last ) ) FT_INVALID_DATA; - if ( End >= valid->glyph_count ) + if ( End >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; last = End; @@ -305,7 +305,7 @@ FT_LOCAL_DEF( void ) otv_Device_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt StartSize, EndSize, DeltaFormat, count; @@ -339,12 +339,12 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->type_count */ - /* uses valid->type_funcs */ + /* uses otvalid->type_count */ + /* uses otvalid->type_funcs */ FT_LOCAL_DEF( void ) otv_Lookup_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt LookupType, SubTableCount; @@ -360,10 +360,10 @@ OTV_TRACE(( " (type %d)\n", LookupType )); - if ( LookupType == 0 || LookupType > valid->type_count ) + if ( LookupType == 0 || LookupType > otvalid->type_count ) FT_INVALID_DATA; - validate = valid->type_funcs[LookupType - 1]; + validate = otvalid->type_funcs[LookupType - 1]; OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount )); @@ -371,7 +371,7 @@ /* SubTable */ for ( ; SubTableCount > 0; SubTableCount-- ) - validate( table + FT_NEXT_USHORT( p ), valid ); + validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; } @@ -381,7 +381,7 @@ FT_LOCAL_DEF( void ) otv_LookupList_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt LookupCount; @@ -396,11 +396,11 @@ OTV_LIMIT_CHECK( LookupCount * 2 ); - valid->lookup_count = LookupCount; + otvalid->lookup_count = LookupCount; /* Lookup */ for ( ; LookupCount > 0; LookupCount-- ) - otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Lookup_validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; } @@ -421,11 +421,11 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->lookup_count */ + /* uses otvalid->lookup_count */ FT_LOCAL_DEF( void ) otv_Feature_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt LookupCount; @@ -443,7 +443,7 @@ /* LookupListIndex */ for ( ; LookupCount > 0; LookupCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) FT_INVALID_DATA; OTV_EXIT; @@ -457,12 +457,12 @@ } - /* sets valid->lookup_count */ + /* sets otvalid->lookup_count */ FT_LOCAL_DEF( void ) otv_FeatureList_validate( FT_Bytes table, FT_Bytes lookups, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt FeatureCount; @@ -477,7 +477,7 @@ OTV_LIMIT_CHECK( FeatureCount * 2 ); - valid->lookup_count = otv_LookupList_get_count( lookups ); + otvalid->lookup_count = otv_LookupList_get_count( lookups ); /* FeatureRecord */ for ( ; FeatureCount > 0; FeatureCount-- ) @@ -485,7 +485,7 @@ p += 4; /* skip FeatureTag */ /* Feature */ - otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Feature_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; @@ -501,11 +501,11 @@ /*************************************************************************/ - /* uses valid->extra1 (number of features) */ + /* uses otvalid->extra1 (number of features) */ FT_LOCAL_DEF( void ) otv_LangSys_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt ReqFeatureIndex; @@ -522,14 +522,14 @@ OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex )); OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); - if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 ) + if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= otvalid->extra1 ) FT_INVALID_DATA; OTV_LIMIT_CHECK( FeatureCount * 2 ); /* FeatureIndex */ for ( ; FeatureCount > 0; FeatureCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; OTV_EXIT; @@ -546,7 +546,7 @@ FT_LOCAL_DEF( void ) otv_Script_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_UInt DefaultLangSys, LangSysCount; FT_Bytes p = table; @@ -561,7 +561,7 @@ OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount )); if ( DefaultLangSys != 0 ) - otv_LangSys_validate( table + DefaultLangSys, valid ); + otv_LangSys_validate( table + DefaultLangSys, otvalid ); OTV_LIMIT_CHECK( LangSysCount * 6 ); @@ -571,19 +571,19 @@ p += 4; /* skip LangSysTag */ /* LangSys */ - otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_LangSys_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; } - /* sets valid->extra1 (number of features) */ + /* sets otvalid->extra1 (number of features) */ FT_LOCAL_DEF( void ) otv_ScriptList_validate( FT_Bytes table, FT_Bytes features, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_UInt ScriptCount; FT_Bytes p = table; @@ -598,14 +598,14 @@ OTV_LIMIT_CHECK( ScriptCount * 6 ); - valid->extra1 = otv_Feature_get_count( features ); + otvalid->extra1 = otv_Feature_get_count( features ); /* ScriptRecord */ for ( ; ScriptCount > 0; ScriptCount-- ) { p += 4; /* skip ScriptTag */ - otv_Script_validate( table + FT_NEXT_USHORT( p ), valid ); /* Script */ + otv_Script_validate( table + FT_NEXT_USHORT( p ), otvalid ); /* Script */ } OTV_EXIT; @@ -640,7 +640,7 @@ FT_LOCAL_DEF( void ) otv_x_Ox( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count; @@ -656,13 +656,13 @@ OTV_LIMIT_CHECK( Count * 2 ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; for ( ; Count > 0; Count-- ) - func( table + FT_NEXT_USHORT( p ), valid ); + func( table + FT_NEXT_USHORT( p ), otvalid ); - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } @@ -670,7 +670,7 @@ FT_LOCAL_DEF( void ) otv_u_C_x_Ox( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count, Coverage; @@ -687,27 +687,27 @@ OTV_TRACE(( " (Count = %d)\n", Count )); - otv_Coverage_validate( table + Coverage, valid, Count ); + otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)Count ); OTV_LIMIT_CHECK( Count * 2 ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; for ( ; Count > 0; Count-- ) - func( table + FT_NEXT_USHORT( p ), valid ); + func( table + FT_NEXT_USHORT( p ), otvalid ); - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } - /* uses valid->extra1 (if > 0: array value limit) */ + /* uses otvalid->extra1 (if > 0: array value limit) */ FT_LOCAL_DEF( void ) otv_x_ux( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count; @@ -722,10 +722,10 @@ OTV_LIMIT_CHECK( Count * 2 ); - if ( valid->extra1 ) + if ( otvalid->extra1 ) { for ( ; Count > 0; Count-- ) - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; } @@ -736,11 +736,11 @@ /* `ux' in the function's name is not really correct since only x-1 */ /* elements are tested */ - /* uses valid->extra1 (array value limit) */ + /* uses otvalid->extra1 (array value limit) */ FT_LOCAL_DEF( void ) otv_x_y_ux_sy( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count1, Count2; @@ -766,7 +766,7 @@ if ( FT_NEXT_USHORT( p ) >= Count1 ) FT_INVALID_DATA; - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; } @@ -777,11 +777,11 @@ /* `uy' in the function's name is not really correct since only y-1 */ /* elements are tested */ - /* uses valid->extra1 (array value limit) */ + /* uses otvalid->extra1 (array value limit) */ FT_LOCAL_DEF( void ) otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BacktrackCount, InputCount, LookaheadCount; @@ -825,7 +825,7 @@ if ( FT_NEXT_USHORT( p ) >= InputCount ) FT_INVALID_DATA; - if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; } @@ -833,11 +833,11 @@ } - /* sets valid->extra1 (valid->lookup_count) */ + /* sets otvalid->extra1 (valid->lookup_count) */ FT_LOCAL_DEF( void ) otv_u_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Coverage, ClassDef, ClassSetCount; @@ -855,14 +855,14 @@ OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount )); - otv_Coverage_validate( table + Coverage, valid, -1 ); - otv_ClassDef_validate( table + ClassDef, valid ); + otv_Coverage_validate( table + Coverage, otvalid, -1 ); + otv_ClassDef_validate( table + ClassDef, otvalid ); OTV_LIMIT_CHECK( ClassSetCount * 2 ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = valid->lookup_count; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; + otvalid->extra1 = otvalid->lookup_count; for ( ; ClassSetCount > 0; ClassSetCount-- ) { @@ -870,20 +870,20 @@ if ( offset ) - func( table + offset, valid ); + func( table + offset, otvalid ); } - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } - /* uses valid->lookup_count */ + /* uses otvalid->lookup_count */ FT_LOCAL_DEF( void ) otv_u_x_y_Ox_sy( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt GlyphCount, Count, count1; @@ -903,14 +903,14 @@ OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 ); for ( count1 = GlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); for ( ; Count > 0; Count-- ) { if ( FT_NEXT_USHORT( p ) >= GlyphCount ) FT_INVALID_DATA; - if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) FT_INVALID_DATA; } @@ -918,11 +918,11 @@ } - /* sets valid->extra1 (valid->lookup_count) */ + /* sets otvalid->extra1 (valid->lookup_count) */ FT_LOCAL_DEF( void ) otv_u_O_O_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Coverage; @@ -944,17 +944,17 @@ OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount )); - otv_Coverage_validate( table + Coverage, valid, -1 ); + otv_Coverage_validate( table + Coverage, otvalid, -1 ); - otv_ClassDef_validate( table + BacktrackClassDef, valid ); - otv_ClassDef_validate( table + InputClassDef, valid ); - otv_ClassDef_validate( table + LookaheadClassDef, valid ); + otv_ClassDef_validate( table + BacktrackClassDef, otvalid ); + otv_ClassDef_validate( table + InputClassDef, otvalid ); + otv_ClassDef_validate( table + LookaheadClassDef, otvalid ); OTV_LIMIT_CHECK( ChainClassSetCount * 2 ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = valid->lookup_count; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; + otvalid->extra1 = otvalid->lookup_count; for ( ; ChainClassSetCount > 0; ChainClassSetCount-- ) { @@ -962,20 +962,20 @@ if ( offset ) - func( table + offset, valid ); + func( table + offset, otvalid ); } - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } - /* uses valid->lookup_count */ + /* uses otvalid->lookup_count */ FT_LOCAL_DEF( void ) otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount; @@ -994,7 +994,7 @@ OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); InputGlyphCount = FT_NEXT_USHORT( p ); @@ -1003,7 +1003,7 @@ OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 ); for ( count1 = InputGlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); @@ -1012,7 +1012,7 @@ OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); count2 = FT_NEXT_USHORT( p ); @@ -1025,7 +1025,7 @@ if ( FT_NEXT_USHORT( p ) >= InputGlyphCount ) FT_INVALID_DATA; - if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) FT_INVALID_DATA; } diff --git a/drivers/freetype/freetype/src/otvalid/otvcommn.h b/drivers/freetype/src/otvalid/otvcommn.h index 898887fc95..44e0c63793 100644 --- a/drivers/freetype/freetype/src/otvalid/otvcommn.h +++ b/drivers/freetype/src/otvalid/otvcommn.h @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (specification). */ /* */ -/* Copyright 2004, 2005, 2007, 2009 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __OTVCOMMN_H__ -#define __OTVCOMMN_H__ +#ifndef OTVCOMMN_H_ +#define OTVCOMMN_H_ #include <ft2build.h> @@ -39,7 +39,7 @@ FT_BEGIN_HEADER typedef struct OTV_ValidatorRec_* OTV_Validator; typedef void (*OTV_Validate_Func)( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); typedef struct OTV_ValidatorRec_ { @@ -67,8 +67,8 @@ FT_BEGIN_HEADER #undef FT_INVALID_ -#define FT_INVALID_( _prefix, _error ) \ - ft_validator_error( valid->root, _prefix ## _error ) +#define FT_INVALID_( _error ) \ + ft_validator_error( otvalid->root, FT_THROW( _error ) ) #define OTV_OPTIONAL_TABLE( _table ) FT_UShort _table; \ FT_Bytes _table ## _p @@ -81,7 +81,7 @@ FT_BEGIN_HEADER #define OTV_LIMIT_CHECK( _count ) \ FT_BEGIN_STMNT \ - if ( p + (_count) > valid->root->limit ) \ + if ( p + (_count) > otvalid->root->limit ) \ FT_INVALID_TOO_SHORT; \ FT_END_STMNT @@ -89,7 +89,7 @@ FT_BEGIN_HEADER FT_BEGIN_STMNT \ if ( _size > 0 && _size < table_size ) \ { \ - if ( valid->root->level == FT_VALIDATE_PARANOID ) \ + if ( otvalid->root->level == FT_VALIDATE_PARANOID ) \ FT_INVALID_OFFSET; \ else \ { \ @@ -117,79 +117,79 @@ FT_BEGIN_HEADER #ifdef FT_DEBUG_LEVEL_TRACE -#define OTV_NEST1( x ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->debug_function_name[0] = OTV_NAME( x ); \ +#define OTV_NEST1( x ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ + otvalid->debug_function_name[0] = OTV_NAME( x ); \ FT_END_STMNT -#define OTV_NEST2( x, y ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ - valid->debug_function_name[0] = OTV_NAME( x ); \ - valid->debug_function_name[1] = OTV_NAME( y ); \ +#define OTV_NEST2( x, y ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ + otvalid->func[1] = OTV_FUNC( y ); \ + otvalid->debug_function_name[0] = OTV_NAME( x ); \ + otvalid->debug_function_name[1] = OTV_NAME( y ); \ FT_END_STMNT -#define OTV_NEST3( x, y, z ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ - valid->func[2] = OTV_FUNC( z ); \ - valid->debug_function_name[0] = OTV_NAME( x ); \ - valid->debug_function_name[1] = OTV_NAME( y ); \ - valid->debug_function_name[2] = OTV_NAME( z ); \ +#define OTV_NEST3( x, y, z ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ + otvalid->func[1] = OTV_FUNC( y ); \ + otvalid->func[2] = OTV_FUNC( z ); \ + otvalid->debug_function_name[0] = OTV_NAME( x ); \ + otvalid->debug_function_name[1] = OTV_NAME( y ); \ + otvalid->debug_function_name[2] = OTV_NAME( z ); \ FT_END_STMNT -#define OTV_INIT valid->debug_indent = 0 +#define OTV_INIT otvalid->debug_indent = 0 -#define OTV_ENTER \ - FT_BEGIN_STMNT \ - valid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4(( "%s table\n", \ - valid->debug_function_name[valid->nesting_level] )); \ +#define OTV_ENTER \ + FT_BEGIN_STMNT \ + otvalid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ + FT_TRACE4(( "%s table\n", \ + otvalid->debug_function_name[otvalid->nesting_level] )); \ FT_END_STMNT -#define OTV_NAME_ENTER( name ) \ - FT_BEGIN_STMNT \ - valid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4(( "%s table\n", name )); \ +#define OTV_NAME_ENTER( name ) \ + FT_BEGIN_STMNT \ + otvalid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ + FT_TRACE4(( "%s table\n", name )); \ FT_END_STMNT -#define OTV_EXIT valid->debug_indent -= 2 +#define OTV_EXIT otvalid->debug_indent -= 2 -#define OTV_TRACE( s ) \ - FT_BEGIN_STMNT \ - FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ - FT_TRACE4( s ); \ +#define OTV_TRACE( s ) \ + FT_BEGIN_STMNT \ + FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ + FT_TRACE4( s ); \ FT_END_STMNT #else /* !FT_DEBUG_LEVEL_TRACE */ -#define OTV_NEST1( x ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ +#define OTV_NEST1( x ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ FT_END_STMNT -#define OTV_NEST2( x, y ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ +#define OTV_NEST2( x, y ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ + otvalid->func[1] = OTV_FUNC( y ); \ FT_END_STMNT -#define OTV_NEST3( x, y, z ) \ - FT_BEGIN_STMNT \ - valid->nesting_level = 0; \ - valid->func[0] = OTV_FUNC( x ); \ - valid->func[1] = OTV_FUNC( y ); \ - valid->func[2] = OTV_FUNC( z ); \ +#define OTV_NEST3( x, y, z ) \ + FT_BEGIN_STMNT \ + otvalid->nesting_level = 0; \ + otvalid->func[0] = OTV_FUNC( x ); \ + otvalid->func[1] = OTV_FUNC( y ); \ + otvalid->func[2] = OTV_FUNC( z ); \ FT_END_STMNT #define OTV_INIT do { } while ( 0 ) @@ -202,7 +202,7 @@ FT_BEGIN_HEADER #endif /* !FT_DEBUG_LEVEL_TRACE */ -#define OTV_RUN valid->func[0] +#define OTV_RUN otvalid->func[0] /*************************************************************************/ @@ -215,7 +215,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid, + OTV_Validator otvalid, FT_Int expected_count ); /* return first covered glyph */ @@ -241,7 +241,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_ClassDef_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -254,7 +254,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Device_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -267,11 +267,11 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Lookup_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); FT_LOCAL( void ) otv_LookupList_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -284,13 +284,13 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Feature_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /* lookups must already be validated */ FT_LOCAL( void ) otv_FeatureList_validate( FT_Bytes table, FT_Bytes lookups, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -303,7 +303,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_LangSys_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -316,13 +316,13 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Script_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); /* features must already be validated */ FT_LOCAL( void ) otv_ScriptList_validate( FT_Bytes table, FT_Bytes features, - OTV_Validator valid ); + OTV_Validator otvalid ); /*************************************************************************/ @@ -349,7 +349,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_x_Ox ( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define AlternateSubstFormat1Func otv_u_C_x_Ox #define ChainContextPosFormat1Func otv_u_C_x_Ox @@ -361,7 +361,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_u_C_x_Ox( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define AlternateSetFunc otv_x_ux #define AttachPointFunc otv_x_ux @@ -372,7 +372,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_x_ux( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define PosClassRuleFunc otv_x_y_ux_sy #define PosRuleFunc otv_x_y_ux_sy @@ -381,7 +381,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_x_y_ux_sy( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define ChainPosClassRuleFunc otv_x_ux_y_uy_z_uz_p_sp #define ChainPosRuleFunc otv_x_ux_y_uy_z_uz_p_sp @@ -390,35 +390,35 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define ContextPosFormat2Func otv_u_O_O_x_Onx #define ContextSubstFormat2Func otv_u_O_O_x_Onx FT_LOCAL( void ) otv_u_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define ContextPosFormat3Func otv_u_x_y_Ox_sy #define ContextSubstFormat3Func otv_u_x_y_Ox_sy FT_LOCAL( void ) otv_u_x_y_Ox_sy( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define ChainContextPosFormat2Func otv_u_O_O_O_O_x_Onx #define ChainContextSubstFormat2Func otv_u_O_O_O_O_x_Onx FT_LOCAL( void ) otv_u_O_O_O_O_x_Onx( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); #define ChainContextPosFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp #define ChainContextSubstFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp FT_LOCAL( void ) otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator otvalid ); FT_LOCAL( FT_UInt ) @@ -431,7 +431,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVCOMMN_H__ */ +#endif /* OTVCOMMN_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otverror.h b/drivers/freetype/src/otvalid/otverror.h index b6f00c9dba..e7c8db0d58 100644 --- a/drivers/freetype/freetype/src/otvalid/otverror.h +++ b/drivers/freetype/src/otvalid/otverror.h @@ -4,7 +4,7 @@ /* */ /* OpenType validation module error codes (specification only). */ /* */ -/* Copyright 2004, 2005, 2012, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __OTVERROR_H__ -#define __OTVERROR_H__ +#ifndef OTVERROR_H_ +#define OTVERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX OTV_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __OTVERROR_H__ */ +#endif /* OTVERROR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvgdef.c b/drivers/freetype/src/otvalid/otvgdef.c index 3633ad0de1..f19e300e51 100644 --- a/drivers/freetype/freetype/src/otvalid/otvgdef.c +++ b/drivers/freetype/src/otvalid/otvgdef.c @@ -4,7 +4,7 @@ /* */ /* OpenType GDEF table validation (body). */ /* */ -/* Copyright 2004, 2005, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ static void otv_O_x_Ox( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_Bytes Coverage; @@ -61,20 +61,20 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - otv_Coverage_validate( Coverage, valid, GlyphCount ); + otv_Coverage_validate( Coverage, otvalid, (FT_Int)GlyphCount ); if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) FT_INVALID_DATA; OTV_LIMIT_CHECK( GlyphCount * 2 ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = 0; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; + otvalid->extra1 = 0; for ( ; GlyphCount > 0; GlyphCount-- ) - func( table + FT_NEXT_USHORT( p ), valid ); + func( table + FT_NEXT_USHORT( p ), otvalid ); - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } @@ -92,7 +92,7 @@ static void otv_CaretValue_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt CaretValueFormat; @@ -122,7 +122,7 @@ OTV_LIMIT_CHECK( 2 ); /* DeviceTable */ - otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid ); break; default: @@ -141,7 +141,7 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->glyph_count */ + /* sets otvalid->glyph_count */ FT_LOCAL_DEF( void ) otv_GDEF_validate( FT_Bytes table, @@ -150,8 +150,8 @@ FT_UInt glyph_count, FT_Validator ftvalid ) { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; + OTV_ValidatorRec otvalidrec; + OTV_Validator otvalid = &otvalidrec; FT_Bytes p = table; FT_UInt table_size; FT_Bool need_MarkAttachClassDef; @@ -162,7 +162,7 @@ OTV_OPTIONAL_TABLE( MarkAttachClassDef ); - valid->root = ftvalid; + otvalid->root = ftvalid; FT_TRACE3(( "validating GDEF table\n" )); OTV_INIT; @@ -186,19 +186,19 @@ else table_size = 10; /* OpenType < 1.2 */ - valid->glyph_count = glyph_count; + otvalid->glyph_count = glyph_count; OTV_OPTIONAL_OFFSET( GlyphClassDef ); OTV_SIZE_CHECK( GlyphClassDef ); if ( GlyphClassDef ) - otv_ClassDef_validate( table + GlyphClassDef, valid ); + otv_ClassDef_validate( table + GlyphClassDef, otvalid ); OTV_OPTIONAL_OFFSET( AttachListOffset ); OTV_SIZE_CHECK( AttachListOffset ); if ( AttachListOffset ) { OTV_NEST2( AttachList, AttachPoint ); - OTV_RUN( table + AttachListOffset, valid ); + OTV_RUN( table + AttachListOffset, otvalid ); } OTV_OPTIONAL_OFFSET( LigCaretListOffset ); @@ -206,7 +206,7 @@ if ( LigCaretListOffset ) { OTV_NEST3( LigCaretList, LigGlyph, CaretValue ); - OTV_RUN( table + LigCaretListOffset, valid ); + OTV_RUN( table + LigCaretListOffset, otvalid ); } if ( need_MarkAttachClassDef ) @@ -214,7 +214,7 @@ OTV_OPTIONAL_OFFSET( MarkAttachClassDef ); OTV_SIZE_CHECK( MarkAttachClassDef ); if ( MarkAttachClassDef ) - otv_ClassDef_validate( table + MarkAttachClassDef, valid ); + otv_ClassDef_validate( table + MarkAttachClassDef, otvalid ); } FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/freetype/src/otvalid/otvgpos.c b/drivers/freetype/src/otvalid/otvgpos.c index 49b46183a3..e904ea5d6c 100644 --- a/drivers/freetype/freetype/src/otvalid/otvgpos.c +++ b/drivers/freetype/src/otvalid/otvgpos.c @@ -4,7 +4,7 @@ /* */ /* OpenType GPOS table validation (body). */ /* */ -/* Copyright 2002, 2004, 2005, 2006, 2007, 2008 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -57,7 +57,7 @@ static void otv_x_sxy( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count, count1, table_size; @@ -71,26 +71,26 @@ OTV_TRACE(( " (Count = %d)\n", Count )); - OTV_LIMIT_CHECK( Count * valid->extra1 * 2 ); + OTV_LIMIT_CHECK( Count * otvalid->extra1 * 2 ); - table_size = Count * valid->extra1 * 2 + 2; + table_size = Count * otvalid->extra1 * 2 + 2; for ( ; Count > 0; Count-- ) - for ( count1 = valid->extra1; count1 > 0; count1-- ) + for ( count1 = otvalid->extra1; count1 > 0; count1-- ) { OTV_OPTIONAL_TABLE( anchor_offset ); OTV_OPTIONAL_OFFSET( anchor_offset ); - if ( valid->extra2 ) + if ( otvalid->extra2 ) { OTV_SIZE_CHECK( anchor_offset ); if ( anchor_offset ) - otv_Anchor_validate( table + anchor_offset, valid ); + otv_Anchor_validate( table + anchor_offset, otvalid ); } else - otv_Anchor_validate( table + anchor_offset, valid ); + otv_Anchor_validate( table + anchor_offset, otvalid ); } OTV_EXIT; @@ -101,11 +101,11 @@ #define MarkLigPosFormat1Func otv_u_O_O_u_O_O #define MarkMarkPosFormat1Func otv_u_O_O_u_O_O - /* sets valid->extra1 (class count) */ + /* sets otvalid->extra1 (class count) */ static void otv_u_O_O_u_O_O( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Coverage1, Coverage2, ClassCount; @@ -124,18 +124,18 @@ Array1 = FT_NEXT_USHORT( p ); Array2 = FT_NEXT_USHORT( p ); - otv_Coverage_validate( table + Coverage1, valid, -1 ); - otv_Coverage_validate( table + Coverage2, valid, -1 ); + otv_Coverage_validate( table + Coverage1, otvalid, -1 ); + otv_Coverage_validate( table + Coverage2, otvalid, -1 ); - otv_MarkArray_validate( table + Array1, valid ); + otv_MarkArray_validate( table + Array1, otvalid ); - valid->nesting_level++; - func = valid->func[valid->nesting_level]; - valid->extra1 = ClassCount; + otvalid->nesting_level++; + func = otvalid->func[otvalid->nesting_level]; + otvalid->extra1 = ClassCount; - func( table + Array2, valid ); + func( table + Array2, otvalid ); - valid->nesting_level--; + otvalid->nesting_level--; OTV_EXIT; } @@ -163,12 +163,12 @@ } - /* uses valid->extra3 (pointer to base table) */ + /* uses otvalid->extra3 (pointer to base table) */ static void otv_ValueRecord_validate( FT_Bytes table, FT_UInt format, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt count; @@ -222,11 +222,11 @@ /* ValueRecord is part of an array -- getting the correct table */ /* size is probably not worth the trouble */ - table_size = p - valid->extra3; + table_size = p - otvalid->extra3; OTV_SIZE_CHECK( device ); if ( device ) - otv_Device_validate( valid->extra3 + device, valid ); + otv_Device_validate( otvalid->extra3 + device, otvalid ); } format >>= 1; } @@ -245,7 +245,7 @@ static void otv_Anchor_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt AnchorFormat; @@ -285,11 +285,11 @@ OTV_SIZE_CHECK( XDeviceTable ); if ( XDeviceTable ) - otv_Device_validate( table + XDeviceTable, valid ); + otv_Device_validate( table + XDeviceTable, otvalid ); OTV_SIZE_CHECK( YDeviceTable ); if ( YDeviceTable ) - otv_Device_validate( table + YDeviceTable, valid ); + otv_Device_validate( table + YDeviceTable, otvalid ); } break; @@ -311,7 +311,7 @@ static void otv_MarkArray_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt MarkCount; @@ -331,7 +331,7 @@ { p += 2; /* skip Class */ /* MarkAnchor */ - otv_Anchor_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Anchor_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; @@ -346,11 +346,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra3 (pointer to base table) */ + /* sets otvalid->extra3 (pointer to base table) */ static void otv_SinglePos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -363,7 +363,7 @@ OTV_TRACE(( " (format %d)\n", PosFormat )); - valid->extra3 = table; + otvalid->extra3 = table; switch ( PosFormat ) { @@ -376,8 +376,8 @@ Coverage = FT_NEXT_USHORT( p ); ValueFormat = FT_NEXT_USHORT( p ); - otv_Coverage_validate( table + Coverage, valid, -1 ); - otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */ + otv_Coverage_validate( table + Coverage, otvalid, -1 ); + otv_ValueRecord_validate( p, ValueFormat, otvalid ); /* Value */ } break; @@ -395,14 +395,16 @@ len_value = otv_value_length( ValueFormat ); - otv_Coverage_validate( table + Coverage, valid, ValueCount ); + otv_Coverage_validate( table + Coverage, + otvalid, + (FT_Int)ValueCount ); OTV_LIMIT_CHECK( ValueCount * len_value ); /* Value */ for ( ; ValueCount > 0; ValueCount-- ) { - otv_ValueRecord_validate( p, ValueFormat, valid ); + otv_ValueRecord_validate( p, ValueFormat, otvalid ); p += len_value; } } @@ -428,7 +430,7 @@ otv_PairSet_validate( FT_Bytes table, FT_UInt format1, FT_UInt format2, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt value_len1, value_len2, PairValueCount; @@ -452,11 +454,11 @@ p += 2; /* skip SecondGlyph */ if ( format1 ) - otv_ValueRecord_validate( p, format1, valid ); /* Value1 */ + otv_ValueRecord_validate( p, format1, otvalid ); /* Value1 */ p += value_len1; if ( format2 ) - otv_ValueRecord_validate( p, format2, valid ); /* Value2 */ + otv_ValueRecord_validate( p, format2, otvalid ); /* Value2 */ p += value_len2; } @@ -464,11 +466,11 @@ } - /* sets valid->extra3 (pointer to base table) */ + /* sets otvalid->extra3 (pointer to base table) */ static void otv_PairPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -481,7 +483,7 @@ OTV_TRACE(( " (format %d)\n", PosFormat )); - valid->extra3 = table; + otvalid->extra3 = table; switch ( PosFormat ) { @@ -498,14 +500,14 @@ OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount )); - otv_Coverage_validate( table + Coverage, valid, -1 ); + otv_Coverage_validate( table + Coverage, otvalid, -1 ); OTV_LIMIT_CHECK( PairSetCount * 2 ); /* PairSetOffset */ for ( ; PairSetCount > 0; PairSetCount-- ) otv_PairSet_validate( table + FT_NEXT_USHORT( p ), - ValueFormat1, ValueFormat2, valid ); + ValueFormat1, ValueFormat2, otvalid ); } break; @@ -530,9 +532,9 @@ len_value1 = otv_value_length( ValueFormat1 ); len_value2 = otv_value_length( ValueFormat2 ); - otv_Coverage_validate( table + Coverage, valid, -1 ); - otv_ClassDef_validate( table + ClassDef1, valid ); - otv_ClassDef_validate( table + ClassDef2, valid ); + otv_Coverage_validate( table + Coverage, otvalid, -1 ); + otv_ClassDef_validate( table + ClassDef1, otvalid ); + otv_ClassDef_validate( table + ClassDef2, otvalid ); OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 * ( len_value1 + len_value2 ) ); @@ -545,12 +547,12 @@ { if ( ValueFormat1 ) /* Value1 */ - otv_ValueRecord_validate( p, ValueFormat1, valid ); + otv_ValueRecord_validate( p, ValueFormat1, otvalid ); p += len_value1; if ( ValueFormat2 ) /* Value2 */ - otv_ValueRecord_validate( p, ValueFormat2, valid ); + otv_ValueRecord_validate( p, ValueFormat2, otvalid ); p += len_value2; } } @@ -575,7 +577,7 @@ static void otv_CursivePos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -605,7 +607,9 @@ OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount )); - otv_Coverage_validate( table + Coverage, valid, EntryExitCount ); + otv_Coverage_validate( table + Coverage, + otvalid, + (FT_Int)EntryExitCount ); OTV_LIMIT_CHECK( EntryExitCount * 4 ); @@ -619,11 +623,11 @@ OTV_SIZE_CHECK( EntryAnchor ); if ( EntryAnchor ) - otv_Anchor_validate( table + EntryAnchor, valid ); + otv_Anchor_validate( table + EntryAnchor, otvalid ); OTV_SIZE_CHECK( ExitAnchor ); if ( ExitAnchor ) - otv_Anchor_validate( table + ExitAnchor, valid ); + otv_Anchor_validate( table + ExitAnchor, otvalid ); } } break; @@ -647,11 +651,11 @@ /* UNDOCUMENTED (in OpenType 1.5): */ /* BaseRecord tables can contain NULL pointers. */ - /* sets valid->extra2 (1) */ + /* sets otvalid->extra2 (1) */ static void otv_MarkBasePos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -667,9 +671,9 @@ switch ( PosFormat ) { case 1: - valid->extra2 = 1; + otvalid->extra2 = 1; OTV_NEST2( MarkBasePosFormat1, BaseArray ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -688,11 +692,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra2 (1) */ + /* sets otvalid->extra2 (1) */ static void otv_MarkLigPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -708,9 +712,9 @@ switch ( PosFormat ) { case 1: - valid->extra2 = 1; + otvalid->extra2 = 1; OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -729,11 +733,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra2 (0) */ + /* sets otvalid->extra2 (0) */ static void otv_MarkMarkPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -749,9 +753,9 @@ switch ( PosFormat ) { case 1: - valid->extra2 = 0; + otvalid->extra2 = 0; OTV_NEST2( MarkMarkPosFormat1, Mark2Array ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -770,11 +774,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (lookup count) */ + /* sets otvalid->extra1 (lookup count) */ static void otv_ContextPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -794,9 +798,9 @@ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ - valid->extra1 = valid->lookup_count; + otvalid->extra1 = otvalid->lookup_count; OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 2: @@ -805,12 +809,12 @@ /* meaningful results */ OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 3: OTV_NEST1( ContextPosFormat3 ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -829,11 +833,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (lookup count) */ + /* sets otvalid->extra1 (lookup count) */ static void otv_ChainContextPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -853,10 +857,10 @@ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ - valid->extra1 = valid->lookup_count; + otvalid->extra1 = otvalid->lookup_count; OTV_NEST3( ChainContextPosFormat1, ChainPosRuleSet, ChainPosRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 2: @@ -866,12 +870,12 @@ OTV_NEST3( ChainContextPosFormat2, ChainPosClassSet, ChainPosClassRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 3: OTV_NEST1( ChainContextPosFormat3 ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -890,11 +894,11 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->type_funcs */ + /* uses otvalid->type_funcs */ static void otv_ExtensionPos_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt PosFormat; @@ -923,8 +927,8 @@ if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 ) FT_INVALID_DATA; - validate = valid->type_funcs[ExtensionLookupType - 1]; - validate( table + ExtensionOffset, valid ); + validate = otvalid->type_funcs[ExtensionLookupType - 1]; + validate( table + ExtensionOffset, otvalid ); } break; @@ -950,17 +954,17 @@ }; - /* sets valid->type_count */ - /* sets valid->type_funcs */ + /* sets otvalid->type_count */ + /* sets otvalid->type_funcs */ FT_LOCAL_DEF( void ) otv_GPOS_subtable_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { - valid->type_count = 9; - valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; + otvalid->type_count = 9; + otvalid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; - otv_Lookup_validate( table, valid ); + otv_Lookup_validate( table, otvalid ); } @@ -972,7 +976,7 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->glyph_count */ + /* sets otvalid->glyph_count */ FT_LOCAL_DEF( void ) otv_GPOS_validate( FT_Bytes table, @@ -980,12 +984,12 @@ FT_Validator ftvalid ) { OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; + OTV_Validator otvalid = &validrec; FT_Bytes p = table; FT_UInt ScriptList, FeatureList, LookupList; - valid->root = ftvalid; + otvalid->root = ftvalid; FT_TRACE3(( "validating GPOS table\n" )); OTV_INIT; @@ -999,16 +1003,16 @@ FeatureList = FT_NEXT_USHORT( p ); LookupList = FT_NEXT_USHORT( p ); - valid->type_count = 9; - valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; - valid->glyph_count = glyph_count; + otvalid->type_count = 9; + otvalid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; + otvalid->glyph_count = glyph_count; otv_LookupList_validate( table + LookupList, - valid ); + otvalid ); otv_FeatureList_validate( table + FeatureList, table + LookupList, - valid ); + otvalid ); otv_ScriptList_validate( table + ScriptList, table + FeatureList, - valid ); + otvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/freetype/src/otvalid/otvgpos.h b/drivers/freetype/src/otvalid/otvgpos.h index 14ca408261..2c09e64f97 100644 --- a/drivers/freetype/freetype/src/otvalid/otvgpos.h +++ b/drivers/freetype/src/otvalid/otvgpos.h @@ -4,7 +4,7 @@ /* */ /* OpenType GPOS table validator (specification). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __OTVGPOS_H__ -#define __OTVGPOS_H__ +#ifndef OTVGPOS_H_ +#define OTVGPOS_H_ FT_BEGIN_HEADER @@ -30,7 +30,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVGPOS_H__ */ +#endif /* OTVGPOS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/otvalid/otvgsub.c b/drivers/freetype/src/otvalid/otvgsub.c index ed499d1e92..c2b28569f1 100644 --- a/drivers/freetype/freetype/src/otvalid/otvgsub.c +++ b/drivers/freetype/src/otvalid/otvgsub.c @@ -4,7 +4,7 @@ /* */ /* OpenType GSUB table validation (body). */ /* */ -/* Copyright 2004, 2005, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,11 +38,11 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->glyph_count */ + /* uses otvalid->glyph_count */ static void otv_SingleSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -68,14 +68,14 @@ Coverage = table + FT_NEXT_USHORT( p ); DeltaGlyphID = FT_NEXT_SHORT( p ); - otv_Coverage_validate( Coverage, valid, -1 ); + otv_Coverage_validate( Coverage, otvalid, -1 ); - idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID; + idx = (FT_Long)otv_Coverage_get_first( Coverage ) + DeltaGlyphID; if ( idx < 0 ) FT_INVALID_DATA; - idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID; - if ( (FT_UInt)idx >= valid->glyph_count ) + idx = (FT_Long)otv_Coverage_get_last( Coverage ) + DeltaGlyphID; + if ( (FT_UInt)idx >= otvalid->glyph_count ) FT_INVALID_DATA; } break; @@ -91,13 +91,15 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - otv_Coverage_validate( table + Coverage, valid, GlyphCount ); + otv_Coverage_validate( table + Coverage, + otvalid, + (FT_Int)GlyphCount ); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* Substitute */ for ( ; GlyphCount > 0; GlyphCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) + if ( FT_NEXT_USHORT( p ) >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; } break; @@ -118,11 +120,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (glyph count) */ + /* sets otvalid->extra1 (glyph count) */ static void otv_MultipleSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -138,9 +140,9 @@ switch ( SubstFormat ) { case 1: - valid->extra1 = valid->glyph_count; + otvalid->extra1 = otvalid->glyph_count; OTV_NEST2( MultipleSubstFormat1, Sequence ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -159,11 +161,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (glyph count) */ + /* sets otvalid->extra1 (glyph count) */ static void otv_AlternateSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -179,9 +181,9 @@ switch ( SubstFormat ) { case 1: - valid->extra1 = valid->glyph_count; + otvalid->extra1 = otvalid->glyph_count; OTV_NEST2( AlternateSubstFormat1, AlternateSet ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -202,11 +204,11 @@ #define LigatureFunc otv_Ligature_validate - /* uses valid->glyph_count */ + /* uses otvalid->glyph_count */ static void otv_Ligature_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt LigatureGlyph, CompCount; @@ -216,7 +218,7 @@ OTV_LIMIT_CHECK( 4 ); LigatureGlyph = FT_NEXT_USHORT( p ); - if ( LigatureGlyph >= valid->glyph_count ) + if ( LigatureGlyph >= otvalid->glyph_count ) FT_INVALID_DATA; CompCount = FT_NEXT_USHORT( p ); @@ -238,7 +240,7 @@ static void otv_LigatureSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -255,7 +257,7 @@ { case 1: OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -274,11 +276,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (lookup count) */ + /* sets otvalid->extra1 (lookup count) */ static void otv_ContextSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -298,9 +300,9 @@ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ - valid->extra1 = valid->lookup_count; + otvalid->extra1 = otvalid->lookup_count; OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 2: @@ -309,12 +311,12 @@ /* meaningful results */ OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 3: OTV_NEST1( ContextSubstFormat3 ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -333,11 +335,11 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra1 (lookup count) */ + /* sets otvalid->extra1 (lookup count) */ static void otv_ChainContextSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -357,10 +359,10 @@ /* context rules since even invalid glyph indices/classes return */ /* meaningful results */ - valid->extra1 = valid->lookup_count; + otvalid->extra1 = otvalid->lookup_count; OTV_NEST3( ChainContextSubstFormat1, ChainSubRuleSet, ChainSubRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 2: @@ -370,12 +372,12 @@ OTV_NEST3( ChainContextSubstFormat2, ChainSubClassSet, ChainSubClassRule ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; case 3: OTV_NEST1( ChainContextSubstFormat3 ); - OTV_RUN( table, valid ); + OTV_RUN( table, otvalid ); break; default: @@ -394,11 +396,11 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->type_funcs */ + /* uses otvalid->type_funcs */ static void otv_ExtensionSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; @@ -429,8 +431,8 @@ ExtensionLookupType > 8 ) FT_INVALID_DATA; - validate = valid->type_funcs[ExtensionLookupType - 1]; - validate( table + ExtensionOffset, valid ); + validate = otvalid->type_funcs[ExtensionLookupType - 1]; + validate( table + ExtensionOffset, otvalid ); } break; @@ -450,11 +452,11 @@ /*************************************************************************/ /*************************************************************************/ - /* uses valid->glyph_count */ + /* uses otvalid->glyph_count */ static void otv_ReverseChainSingleSubst_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table, Coverage; FT_UInt SubstFormat; @@ -477,12 +479,12 @@ OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); - otv_Coverage_validate( Coverage, valid, -1 ); + otv_Coverage_validate( Coverage, otvalid, -1 ); OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); @@ -491,7 +493,7 @@ OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); GlyphCount = FT_NEXT_USHORT( p ); @@ -504,7 +506,7 @@ /* Substitute */ for ( ; GlyphCount > 0; GlyphCount-- ) - if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) + if ( FT_NEXT_USHORT( p ) >= otvalid->glyph_count ) FT_INVALID_DATA; break; @@ -538,22 +540,22 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->type_count */ - /* sets valid->type_funcs */ - /* sets valid->glyph_count */ + /* sets otvalid->type_count */ + /* sets otvalid->type_funcs */ + /* sets otvalid->glyph_count */ FT_LOCAL_DEF( void ) otv_GSUB_validate( FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid ) { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; + OTV_ValidatorRec otvalidrec; + OTV_Validator otvalid = &otvalidrec; + FT_Bytes p = table; FT_UInt ScriptList, FeatureList, LookupList; - valid->root = ftvalid; + otvalid->root = ftvalid; FT_TRACE3(( "validating GSUB table\n" )); OTV_INIT; @@ -567,16 +569,16 @@ FeatureList = FT_NEXT_USHORT( p ); LookupList = FT_NEXT_USHORT( p ); - valid->type_count = 8; - valid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs; - valid->glyph_count = glyph_count; + otvalid->type_count = 8; + otvalid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs; + otvalid->glyph_count = glyph_count; otv_LookupList_validate( table + LookupList, - valid ); + otvalid ); otv_FeatureList_validate( table + FeatureList, table + LookupList, - valid ); + otvalid ); otv_ScriptList_validate( table + ScriptList, table + FeatureList, - valid ); + otvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/freetype/src/otvalid/otvjstf.c b/drivers/freetype/src/otvalid/otvjstf.c index a616a23432..e19c1c1213 100644 --- a/drivers/freetype/freetype/src/otvalid/otvjstf.c +++ b/drivers/freetype/src/otvalid/otvjstf.c @@ -4,7 +4,7 @@ /* */ /* OpenType JSTF table validation (body). */ /* */ -/* Copyright 2004, 2007 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,13 +34,13 @@ #define JstfPriorityFunc otv_JstfPriority_validate #define JstfLookupFunc otv_GPOS_subtable_validate - /* uses valid->extra1 (GSUB lookup count) */ - /* uses valid->extra2 (GPOS lookup count) */ - /* sets valid->extra1 (counter) */ + /* uses otvalid->extra1 (GSUB lookup count) */ + /* uses otvalid->extra2 (GPOS lookup count) */ + /* sets otvalid->extra1 (counter) */ static void otv_JstfPriority_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; @@ -63,34 +63,34 @@ OTV_LIMIT_CHECK( 20 ); - gsub_lookup_count = valid->extra1; - gpos_lookup_count = valid->extra2; + gsub_lookup_count = otvalid->extra1; + gpos_lookup_count = otvalid->extra2; table_size = 20; - valid->extra1 = gsub_lookup_count; + otvalid->extra1 = gsub_lookup_count; OTV_OPTIONAL_OFFSET( ShrinkageEnableGSUB ); OTV_SIZE_CHECK( ShrinkageEnableGSUB ); if ( ShrinkageEnableGSUB ) - otv_x_ux( table + ShrinkageEnableGSUB, valid ); + otv_x_ux( table + ShrinkageEnableGSUB, otvalid ); OTV_OPTIONAL_OFFSET( ShrinkageDisableGSUB ); OTV_SIZE_CHECK( ShrinkageDisableGSUB ); if ( ShrinkageDisableGSUB ) - otv_x_ux( table + ShrinkageDisableGSUB, valid ); + otv_x_ux( table + ShrinkageDisableGSUB, otvalid ); - valid->extra1 = gpos_lookup_count; + otvalid->extra1 = gpos_lookup_count; OTV_OPTIONAL_OFFSET( ShrinkageEnableGPOS ); OTV_SIZE_CHECK( ShrinkageEnableGPOS ); if ( ShrinkageEnableGPOS ) - otv_x_ux( table + ShrinkageEnableGPOS, valid ); + otv_x_ux( table + ShrinkageEnableGPOS, otvalid ); OTV_OPTIONAL_OFFSET( ShrinkageDisableGPOS ); OTV_SIZE_CHECK( ShrinkageDisableGPOS ); if ( ShrinkageDisableGPOS ) - otv_x_ux( table + ShrinkageDisableGPOS, valid ); + otv_x_ux( table + ShrinkageDisableGPOS, otvalid ); OTV_OPTIONAL_OFFSET( ShrinkageJstfMax ); OTV_SIZE_CHECK( ShrinkageJstfMax ); @@ -98,32 +98,32 @@ { /* XXX: check lookup types? */ OTV_NEST2( JstfMax, JstfLookup ); - OTV_RUN( table + ShrinkageJstfMax, valid ); + OTV_RUN( table + ShrinkageJstfMax, otvalid ); } - valid->extra1 = gsub_lookup_count; + otvalid->extra1 = gsub_lookup_count; OTV_OPTIONAL_OFFSET( ExtensionEnableGSUB ); OTV_SIZE_CHECK( ExtensionEnableGSUB ); if ( ExtensionEnableGSUB ) - otv_x_ux( table + ExtensionEnableGSUB, valid ); + otv_x_ux( table + ExtensionEnableGSUB, otvalid ); OTV_OPTIONAL_OFFSET( ExtensionDisableGSUB ); OTV_SIZE_CHECK( ExtensionDisableGSUB ); if ( ExtensionDisableGSUB ) - otv_x_ux( table + ExtensionDisableGSUB, valid ); + otv_x_ux( table + ExtensionDisableGSUB, otvalid ); - valid->extra1 = gpos_lookup_count; + otvalid->extra1 = gpos_lookup_count; OTV_OPTIONAL_OFFSET( ExtensionEnableGPOS ); OTV_SIZE_CHECK( ExtensionEnableGPOS ); if ( ExtensionEnableGPOS ) - otv_x_ux( table + ExtensionEnableGPOS, valid ); + otv_x_ux( table + ExtensionEnableGPOS, otvalid ); OTV_OPTIONAL_OFFSET( ExtensionDisableGPOS ); OTV_SIZE_CHECK( ExtensionDisableGPOS ); if ( ExtensionDisableGPOS ) - otv_x_ux( table + ExtensionDisableGPOS, valid ); + otv_x_ux( table + ExtensionDisableGPOS, otvalid ); OTV_OPTIONAL_OFFSET( ExtensionJstfMax ); OTV_SIZE_CHECK( ExtensionJstfMax ); @@ -131,22 +131,22 @@ { /* XXX: check lookup types? */ OTV_NEST2( JstfMax, JstfLookup ); - OTV_RUN( table + ExtensionJstfMax, valid ); + OTV_RUN( table + ExtensionJstfMax, otvalid ); } - valid->extra1 = gsub_lookup_count; - valid->extra2 = gpos_lookup_count; + otvalid->extra1 = gsub_lookup_count; + otvalid->extra2 = gpos_lookup_count; OTV_EXIT; } - /* sets valid->extra (glyph count) */ - /* sets valid->func1 (otv_JstfPriority_validate) */ + /* sets otvalid->extra (glyph count) */ + /* sets otvalid->func1 (otv_JstfPriority_validate) */ static void otv_JstfScript_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; @@ -170,16 +170,16 @@ OTV_SIZE_CHECK( ExtGlyph ); if ( ExtGlyph ) { - valid->extra1 = valid->glyph_count; + otvalid->extra1 = otvalid->glyph_count; OTV_NEST1( ExtenderGlyph ); - OTV_RUN( table + ExtGlyph, valid ); + OTV_RUN( table + ExtGlyph, otvalid ); } OTV_SIZE_CHECK( DefJstfLangSys ); if ( DefJstfLangSys ) { OTV_NEST2( JstfLangSys, JstfPriority ); - OTV_RUN( table + DefJstfLangSys, valid ); + OTV_RUN( table + DefJstfLangSys, otvalid ); } OTV_LIMIT_CHECK( 6 * JstfLangSysCount ); @@ -190,16 +190,16 @@ { p += 4; /* skip JstfLangSysTag */ - OTV_RUN( table + FT_NEXT_USHORT( p ), valid ); + OTV_RUN( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; } - /* sets valid->extra1 (GSUB lookup count) */ - /* sets valid->extra2 (GPOS lookup count) */ - /* sets valid->glyph_count */ + /* sets otvalid->extra1 (GSUB lookup count) */ + /* sets otvalid->extra2 (GPOS lookup count) */ + /* sets otvalid->glyph_count */ FT_LOCAL_DEF( void ) otv_JSTF_validate( FT_Bytes table, @@ -208,13 +208,14 @@ FT_UInt glyph_count, FT_Validator ftvalid ) { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; + OTV_ValidatorRec otvalidrec; + OTV_Validator otvalid = &otvalidrec; FT_Bytes p = table; FT_UInt JstfScriptCount; - valid->root = ftvalid; + otvalid->root = ftvalid; + FT_TRACE3(( "validating JSTF table\n" )); OTV_INIT; @@ -231,16 +232,16 @@ OTV_LIMIT_CHECK( JstfScriptCount * 6 ); if ( gsub ) - valid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub ); + otvalid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub ); else - valid->extra1 = 0; + otvalid->extra1 = 0; if ( gpos ) - valid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos ); + otvalid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos ); else - valid->extra2 = 0; + otvalid->extra2 = 0; - valid->glyph_count = glyph_count; + otvalid->glyph_count = glyph_count; /* JstfScriptRecord */ for ( ; JstfScriptCount > 0; JstfScriptCount-- ) @@ -248,7 +249,7 @@ p += 4; /* skip JstfScriptTag */ /* JstfScript */ - otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), otvalid ); } FT_TRACE4(( "\n" )); diff --git a/drivers/freetype/freetype/src/otvalid/otvmath.c b/drivers/freetype/src/otvalid/otvmath.c index 96f841f2a9..6c785b6fda 100644 --- a/drivers/freetype/freetype/src/otvalid/otvmath.c +++ b/drivers/freetype/src/otvalid/otvmath.c @@ -4,7 +4,7 @@ /* */ /* OpenType MATH table validation (body). */ /* */ -/* Copyright 2007, 2008 by */ +/* Copyright 2007-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* Written by George Williams. */ @@ -44,7 +44,7 @@ static void otv_MathConstants_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt i; @@ -66,7 +66,7 @@ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); + otv_Device_validate( table + DeviceTableOffset, otvalid ); } OTV_EXIT; @@ -84,11 +84,11 @@ static void otv_MathItalicsCorrectionInfo_validate( FT_Bytes table, - OTV_Validator valid, + OTV_Validator otvalid, FT_Int isItalic ) { FT_Bytes p = table; - FT_UInt i, cnt, table_size ; + FT_UInt i, cnt, table_size; OTV_OPTIONAL_TABLE( Coverage ); OTV_OPTIONAL_TABLE( DeviceTableOffset ); @@ -108,7 +108,7 @@ table_size = 4 + 4 * cnt; OTV_SIZE_CHECK( Coverage ); - otv_Coverage_validate( table + Coverage, valid, cnt ); + otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt ); for ( i = 0; i < cnt; ++i ) { @@ -116,7 +116,7 @@ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); + otv_Device_validate( table + DeviceTableOffset, otvalid ); } OTV_EXIT; @@ -133,7 +133,7 @@ static void otv_MathKern_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt i, cnt, table_size; @@ -157,7 +157,7 @@ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); + otv_Device_validate( table + DeviceTableOffset, otvalid ); } /* One more Kerning value */ @@ -167,7 +167,7 @@ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); + otv_Device_validate( table + DeviceTableOffset, otvalid ); } OTV_EXIT; @@ -176,7 +176,7 @@ static void otv_MathKernInfo_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt i, j, cnt, table_size; @@ -196,7 +196,7 @@ table_size = 4 + 8 * cnt; OTV_SIZE_CHECK( Coverage ); - otv_Coverage_validate( table + Coverage, valid, cnt ); + otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt ); for ( i = 0; i < cnt; ++i ) { @@ -205,7 +205,7 @@ OTV_OPTIONAL_OFFSET( MKRecordOffset ); OTV_SIZE_CHECK( MKRecordOffset ); if ( MKRecordOffset ) - otv_MathKern_validate( table + MKRecordOffset, valid ); + otv_MathKern_validate( table + MKRecordOffset, otvalid ); } } @@ -223,7 +223,7 @@ static void otv_MathGlyphInfo_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment; @@ -241,22 +241,22 @@ if ( MathItalicsCorrectionInfo ) otv_MathItalicsCorrectionInfo_validate( - table + MathItalicsCorrectionInfo, valid, TRUE ); + table + MathItalicsCorrectionInfo, otvalid, TRUE ); /* Italic correction and Top Accent Attachment have the same format */ if ( MathTopAccentAttachment ) otv_MathItalicsCorrectionInfo_validate( - table + MathTopAccentAttachment, valid, FALSE ); + table + MathTopAccentAttachment, otvalid, FALSE ); if ( ExtendedShapeCoverage ) { OTV_NAME_ENTER( "ExtendedShapeCoverage" ); - otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 ); + otv_Coverage_validate( table + ExtendedShapeCoverage, otvalid, -1 ); OTV_EXIT; } if ( MathKernInfo ) - otv_MathKernInfo_validate( table + MathKernInfo, valid ); + otv_MathKernInfo_validate( table + MathKernInfo, otvalid ); OTV_EXIT; } @@ -272,7 +272,7 @@ static void otv_GlyphAssembly_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt pcnt, table_size; @@ -294,7 +294,7 @@ OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) - otv_Device_validate( table + DeviceTableOffset, valid ); + otv_Device_validate( table + DeviceTableOffset, otvalid ); for ( i = 0; i < pcnt; ++i ) { @@ -302,7 +302,7 @@ gid = FT_NEXT_USHORT( p ); - if ( gid >= valid->glyph_count ) + if ( gid >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; p += 2*4; /* skip the Start, End, Full, and Flags fields */ } @@ -313,7 +313,7 @@ static void otv_MathGlyphConstruction_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt vcnt, table_size; @@ -338,14 +338,14 @@ gid = FT_NEXT_USHORT( p ); - if ( gid >= valid->glyph_count ) + if ( gid >= otvalid->glyph_count ) FT_INVALID_GLYPH_ID; p += 2; /* skip the size */ } OTV_SIZE_CHECK( GlyphAssembly ); if ( GlyphAssembly ) - otv_GlyphAssembly_validate( table+GlyphAssembly, valid ); + otv_GlyphAssembly_validate( table+GlyphAssembly, otvalid ); /* OTV_EXIT; */ } @@ -353,7 +353,7 @@ static void otv_MathVariants_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt vcnt, hcnt, i, table_size; @@ -378,24 +378,24 @@ OTV_SIZE_CHECK( VCoverage ); if ( VCoverage ) - otv_Coverage_validate( table + VCoverage, valid, vcnt ); + otv_Coverage_validate( table + VCoverage, otvalid, (FT_Int)vcnt ); OTV_SIZE_CHECK( HCoverage ); if ( HCoverage ) - otv_Coverage_validate( table + HCoverage, valid, hcnt ); + otv_Coverage_validate( table + HCoverage, otvalid, (FT_Int)hcnt ); for ( i = 0; i < vcnt; ++i ) { OTV_OPTIONAL_OFFSET( Offset ); OTV_SIZE_CHECK( Offset ); - otv_MathGlyphConstruction_validate( table + Offset, valid ); + otv_MathGlyphConstruction_validate( table + Offset, otvalid ); } for ( i = 0; i < hcnt; ++i ) { OTV_OPTIONAL_OFFSET( Offset ); OTV_SIZE_CHECK( Offset ); - otv_MathGlyphConstruction_validate( table + Offset, valid ); + otv_MathGlyphConstruction_validate( table + Offset, otvalid ); } OTV_EXIT; @@ -410,20 +410,20 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->glyph_count */ + /* sets otvalid->glyph_count */ FT_LOCAL_DEF( void ) otv_MATH_validate( FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid ) { - OTV_ValidatorRec validrec; - OTV_Validator valid = &validrec; - FT_Bytes p = table; + OTV_ValidatorRec otvalidrec; + OTV_Validator otvalid = &otvalidrec; + FT_Bytes p = table; FT_UInt MathConstants, MathGlyphInfo, MathVariants; - valid->root = ftvalid; + otvalid->root = ftvalid; FT_TRACE3(( "validating MATH table\n" )); OTV_INIT; @@ -437,14 +437,14 @@ MathGlyphInfo = FT_NEXT_USHORT( p ); MathVariants = FT_NEXT_USHORT( p ); - valid->glyph_count = glyph_count; + otvalid->glyph_count = glyph_count; otv_MathConstants_validate( table + MathConstants, - valid ); + otvalid ); otv_MathGlyphInfo_validate( table + MathGlyphInfo, - valid ); + otvalid ); otv_MathVariants_validate ( table + MathVariants, - valid ); + otvalid ); FT_TRACE4(( "\n" )); } diff --git a/drivers/freetype/freetype/src/otvalid/otvmod.c b/drivers/freetype/src/otvalid/otvmod.c index 37c6e869dd..972bd1baac 100644 --- a/drivers/freetype/freetype/src/otvalid/otvmod.c +++ b/drivers/freetype/src/otvalid/otvmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType's OpenType validation module implementation (body). */ /* */ -/* Copyright 2004-2008, 2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -240,7 +240,7 @@ static const FT_Service_OTvalidateRec otvalid_interface = { - otv_validate + otv_validate /* validate */ }; diff --git a/drivers/freetype/freetype/src/otvalid/otvmod.h b/drivers/freetype/src/otvalid/otvmod.h index f7e1550787..e464030ab0 100644 --- a/drivers/freetype/freetype/src/otvalid/otvmod.h +++ b/drivers/freetype/src/otvalid/otvmod.h @@ -5,7 +5,7 @@ /* FreeType's OpenType validation module implementation */ /* (specification). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __OTVMOD_H__ -#define __OTVMOD_H__ +#ifndef OTVMOD_H_ +#define OTVMOD_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVMOD_H__ */ +#endif /* OTVMOD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/otvalid/rules.mk b/drivers/freetype/src/otvalid/rules.mk index 53bd41e5e7..077447fcb6 100644 --- a/drivers/freetype/freetype/src/otvalid/rules.mk +++ b/drivers/freetype/src/otvalid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2004, 2007 by +# Copyright 2004-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ OTV_DIR := $(SRC_DIR)/otvalid # compilation flags for the driver # -OTV_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(OTV_DIR)) +OTV_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(OTV_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # OTV driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/pcf/Jamfile b/drivers/freetype/src/pcf/Jamfile index 752fcac2a1..9ebe6a2cbd 100644 --- a/drivers/freetype/freetype/src/pcf/Jamfile +++ b/drivers/freetype/src/pcf/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/pcf Jamfile # -# Copyright 2001, 2003 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,10 @@ SubDir FT2_TOP $(FT2_SRC_DIR) pcf ; if $(FT2_MULTI) { - _sources = pcfdrivr pcfread pcfutil ; + _sources = pcfdrivr + pcfread + pcfutil + ; } else { diff --git a/drivers/freetype/freetype/src/pcf/README b/drivers/freetype/src/pcf/README index 10eff15fbe..10eff15fbe 100644 --- a/drivers/freetype/freetype/src/pcf/README +++ b/drivers/freetype/src/pcf/README diff --git a/drivers/freetype/freetype/src/pcf/module.mk b/drivers/freetype/src/pcf/module.mk index df383ff0fb..df383ff0fb 100644 --- a/drivers/freetype/freetype/src/pcf/module.mk +++ b/drivers/freetype/src/pcf/module.mk diff --git a/drivers/freetype/freetype/src/pcf/pcf.c b/drivers/freetype/src/pcf/pcf.c index 11d5b7b2a0..11d5b7b2a0 100644 --- a/drivers/freetype/freetype/src/pcf/pcf.c +++ b/drivers/freetype/src/pcf/pcf.c diff --git a/drivers/freetype/freetype/src/pcf/pcf.h b/drivers/freetype/src/pcf/pcf.h index af0ffc3378..c726e5ec6b 100644 --- a/drivers/freetype/freetype/src/pcf/pcf.h +++ b/drivers/freetype/src/pcf/pcf.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCF_H__ -#define __PCF_H__ +#ifndef PCF_H_ +#define PCF_H_ #include <ft2build.h> @@ -148,9 +148,9 @@ FT_BEGIN_HEADER int nprops; PCF_Property properties; - FT_Long nmetrics; + FT_ULong nmetrics; PCF_Metric metrics; - FT_Long nencodings; + FT_ULong nencodings; PCF_Encoding encodings; FT_Short defaultChar; @@ -226,12 +226,13 @@ FT_BEGIN_HEADER #define GLYPHPADOPTIONS 4 /* I'm not sure about this */ FT_LOCAL( FT_Error ) - pcf_load_font( FT_Stream, - PCF_Face ); + pcf_load_font( FT_Stream stream, + PCF_Face face, + FT_Long face_index ); FT_END_HEADER -#endif /* __PCF_H__ */ +#endif /* PCF_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcfdrivr.c b/drivers/freetype/src/pcf/pcfdrivr.c index df25a645a0..0996d10793 100644 --- a/drivers/freetype/freetype/src/pcf/pcfdrivr.c +++ b/drivers/freetype/src/pcf/pcfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for pcf files - Copyright (C) 2000-2004, 2006-2011, 2013 by + Copyright (C) 2000-2004, 2006-2011, 2013, 2014 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -48,7 +48,7 @@ THE SOFTWARE. #define FT_COMPONENT trace_pcfread #include FT_SERVICE_BDF_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H /*************************************************************************/ @@ -64,7 +64,7 @@ THE SOFTWARE. typedef struct PCF_CMapRec_ { FT_CMapRec root; - FT_UInt num_encodings; + FT_ULong num_encodings; PCF_Encoding encodings; } PCF_CMapRec, *PCF_CMap; @@ -80,7 +80,7 @@ THE SOFTWARE. FT_UNUSED( init_data ); - cmap->num_encodings = (FT_UInt)face->nencodings; + cmap->num_encodings = face->nencodings; cmap->encodings = face->encodings; return FT_Err_Ok; @@ -104,7 +104,7 @@ THE SOFTWARE. { PCF_CMap cmap = (PCF_CMap)pcfcmap; PCF_Encoding encodings = cmap->encodings; - FT_UInt min, max, mid; + FT_ULong min, max, mid; FT_UInt result = 0; @@ -117,7 +117,7 @@ THE SOFTWARE. mid = ( min + max ) >> 1; - code = encodings[mid].enc; + code = (FT_ULong)encodings[mid].enc; if ( charcode == code ) { @@ -141,7 +141,7 @@ THE SOFTWARE. { PCF_CMap cmap = (PCF_CMap)pcfcmap; PCF_Encoding encodings = cmap->encodings; - FT_UInt min, max, mid; + FT_ULong min, max, mid; FT_ULong charcode = *acharcode + 1; FT_UInt result = 0; @@ -155,7 +155,7 @@ THE SOFTWARE. mid = ( min + max ) >> 1; - code = encodings[mid].enc; + code = (FT_ULong)encodings[mid].enc; if ( charcode == code ) { @@ -172,7 +172,7 @@ THE SOFTWARE. charcode = 0; if ( min < cmap->num_encodings ) { - charcode = encodings[min].enc; + charcode = (FT_ULong)encodings[min].enc; result = encodings[min].glyph + 1; } @@ -189,7 +189,7 @@ THE SOFTWARE. } - FT_CALLBACK_TABLE_DEF + static const FT_CMap_ClassRec pcf_cmap_class = { sizeof ( PCF_CMapRec ), @@ -218,25 +218,24 @@ THE SOFTWARE. FT_FREE( face->metrics ); /* free properties */ + if ( face->properties ) { - PCF_Property prop; - FT_Int i; + FT_Int i; - if ( face->properties ) + for ( i = 0; i < face->nprops; i++ ) { - for ( i = 0; i < face->nprops; i++ ) + PCF_Property prop = &face->properties[i]; + + + if ( prop ) { - prop = &face->properties[i]; - - if ( prop ) - { - FT_FREE( prop->name ); - if ( prop->isString ) - FT_FREE( prop->value.atom ); - } + FT_FREE( prop->name ); + if ( prop->isString ) + FT_FREE( prop->value.atom ); } } + FT_FREE( face->properties ); } @@ -264,16 +263,15 @@ THE SOFTWARE. FT_Parameter* params ) { PCF_Face face = (PCF_Face)pcfface; - FT_Error error = FT_Err_Ok; + FT_Error error; FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_TRACE2(( "PCF driver\n" )); - error = pcf_load_font( stream, face ); + error = pcf_load_font( stream, face, face_index ); if ( error ) { PCF_Face_Done( pcfface ); @@ -334,7 +332,7 @@ THE SOFTWARE. stream = pcfface->stream; - error = pcf_load_font( stream, face ); + error = pcf_load_font( stream, face, face_index ); if ( error ) goto Fail; @@ -347,6 +345,21 @@ THE SOFTWARE. #endif } + /* PCF cannot have multiple faces in a single font file. + * XXX: A non-zero face_index is already an invalid argument, but + * Type1, Type42 drivers have a convention to return + * an invalid argument error when the font could be + * opened by the specified driver. + */ + if ( face_index < 0 ) + goto Exit; + else if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) + { + FT_ERROR(( "PCF_Face_Init: invalid face index\n" )); + PCF_Face_Done( pcfface ); + return FT_THROW( Invalid_Argument ); + } + /* set up charmap */ { FT_String *charset_registry = face->charset_registry; @@ -420,9 +433,9 @@ THE SOFTWARE. FT_Select_Metrics( size->face, strike_index ); - size->metrics.ascender = accel->fontAscent << 6; - size->metrics.descender = -accel->fontDescent << 6; - size->metrics.max_advance = accel->maxbounds.characterWidth << 6; + size->metrics.ascender = accel->fontAscent * 64; + size->metrics.descender = -accel->fontDescent * 64; + size->metrics.max_advance = accel->maxbounds.characterWidth * 64; return FT_Err_Ok; } @@ -477,14 +490,20 @@ THE SOFTWARE. FT_Error error = FT_Err_Ok; FT_Bitmap* bitmap = &slot->bitmap; PCF_Metric metric; - FT_Offset bytes; + FT_ULong bytes; FT_UNUSED( load_flags ); - FT_TRACE4(( "load_glyph %d ---", glyph_index )); + FT_TRACE1(( "PCF_Glyph_Load: glyph index %d\n", glyph_index )); - if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs ) + if ( !face ) + { + error = FT_THROW( Invalid_Face_Handle ); + goto Exit; + } + + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -497,8 +516,10 @@ THE SOFTWARE. metric = face->metrics + glyph_index; - bitmap->rows = metric->ascent + metric->descent; - bitmap->width = metric->rightSideBearing - metric->leftSideBearing; + bitmap->rows = (unsigned int)( metric->ascent + + metric->descent ); + bitmap->width = (unsigned int)( metric->rightSideBearing - + metric->leftSideBearing ); bitmap->num_grays = 1; bitmap->pixel_mode = FT_PIXEL_MODE_MONO; @@ -510,19 +531,19 @@ THE SOFTWARE. switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) ) { case 1: - bitmap->pitch = ( bitmap->width + 7 ) >> 3; + bitmap->pitch = (int)( ( bitmap->width + 7 ) >> 3 ); break; case 2: - bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1; + bitmap->pitch = (int)( ( ( bitmap->width + 15 ) >> 4 ) << 1 ); break; case 4: - bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2; + bitmap->pitch = (int)( ( ( bitmap->width + 31 ) >> 5 ) << 2 ); break; case 8: - bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3; + bitmap->pitch = (int)( ( ( bitmap->width + 63 ) >> 6 ) << 3 ); break; default: @@ -530,7 +551,7 @@ THE SOFTWARE. } /* XXX: to do: are there cases that need repadding the bitmap? */ - bytes = bitmap->pitch * bitmap->rows; + bytes = (FT_ULong)bitmap->pitch * bitmap->rows; error = ft_glyphslot_alloc_bitmap( slot, (FT_ULong)bytes ); if ( error ) @@ -565,18 +586,16 @@ THE SOFTWARE. slot->bitmap_left = metric->leftSideBearing; slot->bitmap_top = metric->ascent; - slot->metrics.horiAdvance = metric->characterWidth << 6; - slot->metrics.horiBearingX = metric->leftSideBearing << 6; - slot->metrics.horiBearingY = metric->ascent << 6; - slot->metrics.width = ( metric->rightSideBearing - - metric->leftSideBearing ) << 6; - slot->metrics.height = bitmap->rows << 6; + slot->metrics.horiAdvance = (FT_Pos)( metric->characterWidth * 64 ); + slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 ); + slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 ); + slot->metrics.width = (FT_Pos)( ( metric->rightSideBearing - + metric->leftSideBearing ) * 64 ); + slot->metrics.height = (FT_Pos)( bitmap->rows * 64 ); ft_synthesize_vertical_metrics( &slot->metrics, ( face->accel.fontAscent + - face->accel.fontDescent ) << 6 ); - - FT_TRACE4(( " --- ok\n" )); + face->accel.fontDescent ) * 64 ); Exit: return error; @@ -640,8 +659,8 @@ THE SOFTWARE. static const FT_Service_BDFRec pcf_service_bdf = { - (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, - (FT_BDF_GetPropertyFunc) pcf_get_bdf_property + (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, /* get_charset_id */ + (FT_BDF_GetPropertyFunc) pcf_get_bdf_property /* get_property */ }; @@ -653,8 +672,8 @@ THE SOFTWARE. static const FT_ServiceDescRec pcf_services[] = { - { FT_SERVICE_ID_BDF, &pcf_service_bdf }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF }, + { FT_SERVICE_ID_BDF, &pcf_service_bdf }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PCF }, { NULL, NULL } }; @@ -681,32 +700,32 @@ THE SOFTWARE. 0x10000L, 0x20000L, - 0, + 0, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - pcf_driver_requester + 0, /* FT_Module_Constructor module_init */ + 0, /* FT_Module_Destructor module_done */ + pcf_driver_requester /* FT_Module_Requester get_interface */ }, sizeof ( PCF_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - PCF_Face_Init, - PCF_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ + PCF_Face_Init, /* FT_Face_InitFunc init_face */ + PCF_Face_Done, /* FT_Face_DoneFunc done_face */ + 0, /* FT_Size_InitFunc init_size */ + 0, /* FT_Size_DoneFunc done_size */ + 0, /* FT_Slot_InitFunc init_slot */ + 0, /* FT_Slot_DoneFunc done_slot */ - PCF_Glyph_Load, + PCF_Glyph_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - PCF_Size_Request, - PCF_Size_Select + PCF_Size_Request, /* FT_Size_RequestFunc request_size */ + PCF_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/freetype/src/pcf/pcfdrivr.h b/drivers/freetype/src/pcf/pcfdrivr.h index 54614951b5..29d30497cd 100644 --- a/drivers/freetype/freetype/src/pcf/pcfdrivr.h +++ b/drivers/freetype/src/pcf/pcfdrivr.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCFDRIVR_H__ -#define __PCFDRIVR_H__ +#ifndef PCFDRIVR_H_ +#define PCFDRIVR_H_ #include <ft2build.h> #include FT_INTERNAL_DRIVER_H @@ -42,7 +42,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFDRIVR_H__ */ +#endif /* PCFDRIVR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcferror.h b/drivers/freetype/src/pcf/pcferror.h index e51fff8ea6..add8ef2230 100644 --- a/drivers/freetype/freetype/src/pcf/pcferror.h +++ b/drivers/freetype/src/pcf/pcferror.h @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __PCFERROR_H__ -#define __PCFERROR_H__ +#ifndef PCFERROR_H_ +#define PCFERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PCF_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __PCFERROR_H__ */ +#endif /* PCFERROR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcfread.c b/drivers/freetype/src/pcf/pcfread.c index 3c1bb7dfa2..a86b45d6bf 100644 --- a/drivers/freetype/freetype/src/pcf/pcfread.c +++ b/drivers/freetype/src/pcf/pcfread.c @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000-2010, 2012, 2013 by + Copyright 2000-2010, 2012-2014 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -78,7 +78,7 @@ THE SOFTWARE. FT_FRAME_START( 16 ), FT_FRAME_ULONG_LE( type ), FT_FRAME_ULONG_LE( format ), - FT_FRAME_ULONG_LE( size ), + FT_FRAME_ULONG_LE( size ), /* rounded up to a multiple of 4 */ FT_FRAME_ULONG_LE( offset ), FT_FRAME_END }; @@ -95,16 +95,29 @@ THE SOFTWARE. FT_Memory memory = FT_FACE( face )->memory; FT_UInt n; + FT_ULong size; - if ( FT_STREAM_SEEK ( 0 ) || - FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) ) + + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ_FIELDS( pcf_toc_header, toc ) ) return FT_THROW( Cannot_Open_Resource ); - if ( toc->version != PCF_FILE_VERSION || - toc->count > FT_ARRAY_MAX( face->toc.tables ) || - toc->count == 0 ) + if ( toc->version != PCF_FILE_VERSION || + toc->count == 0 ) + return FT_THROW( Invalid_File_Format ); + + if ( stream->size < 16 ) return FT_THROW( Invalid_File_Format ); + /* we need 16 bytes per TOC entry */ + if ( toc->count > stream->size >> 4 ) + { + FT_TRACE0(( "pcf_read_TOC: adjusting number of tables" + " (from %d to %d)\n", + toc->count, stream->size >> 4 )); + toc->count = stream->size >> 4; + } + if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) return FT_THROW( Out_Of_Memory ); @@ -144,13 +157,62 @@ THE SOFTWARE. if ( ( tables[i].size > tables[i + 1].offset ) || ( tables[i].offset > tables[i + 1].offset - tables[i].size ) ) - return FT_THROW( Invalid_Offset ); + { + error = FT_THROW( Invalid_Offset ); + goto Exit; + } } if ( !have_change ) break; } + /* + * We now check whether the `size' and `offset' values are reasonable: + * `offset' + `size' must not exceed the stream size. + * + * Note, however, that X11's `pcfWriteFont' routine (used by the + * `bdftopcf' program to create PDF font files) has two special + * features. + * + * - It always assigns the accelerator table a size of 100 bytes in the + * TOC, regardless of its real size, which can vary between 34 and 72 + * bytes. + * + * - Due to the way the routine is designed, it ships out the last font + * table with its real size, ignoring the TOC's size value. Since + * the TOC size values are always rounded up to a multiple of 4, the + * difference can be up to three bytes for all tables except the + * accelerator table, for which the difference can be as large as 66 + * bytes. + * + */ + + tables = face->toc.tables; + size = stream->size; + + for ( n = 0; n < toc->count - 1; n++ ) + { + /* we need two checks to avoid overflow */ + if ( ( tables->size > size ) || + ( tables->offset > size - tables->size ) ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + tables++; + } + + /* only check `tables->offset' for last table element ... */ + if ( ( tables->offset > size ) ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + /* ... and adjust `tables->size' to the real value if necessary */ + if ( tables->size > size - tables->offset ) + tables->size = size - tables->offset; + #ifdef FT_DEBUG_LEVEL_TRACE { @@ -380,7 +442,7 @@ THE SOFTWARE. int i; - for ( i = 0 ; i < face->nprops && !found; i++ ) + for ( i = 0; i < face->nprops && !found; i++ ) { if ( !ft_strcmp( properties[i].name, prop ) ) found = 1; @@ -397,14 +459,14 @@ THE SOFTWARE. pcf_get_properties( FT_Stream stream, PCF_Face face ) { - PCF_ParseProperty props = 0; + PCF_ParseProperty props = NULL; PCF_Property properties = NULL; FT_ULong nprops, i; FT_ULong format, size; FT_Error error; FT_Memory memory = FT_FACE( face )->memory; FT_ULong string_size; - FT_String* strings = 0; + FT_String* strings = NULL; error = pcf_seek_to_table_type( stream, @@ -434,9 +496,9 @@ THE SOFTWARE. goto Bail; FT_TRACE4(( " nprop = %d (truncate %d props)\n", - (int)nprops, nprops - (int)nprops )); + (int)nprops, nprops - (FT_ULong)(int)nprops )); - nprops = (int)nprops; + nprops = (FT_ULong)(int)nprops; /* rough estimate */ if ( nprops > size / PCF_PROPERTY_SIZE ) @@ -569,7 +631,7 @@ THE SOFTWARE. FT_Error error; FT_Memory memory = FT_FACE( face )->memory; FT_ULong format, size; - PCF_Metric metrics = 0; + PCF_Metric metrics = NULL; FT_ULong nmetrics, i; @@ -631,24 +693,40 @@ THE SOFTWARE. return FT_THROW( Out_Of_Memory ); metrics = face->metrics; - for ( i = 0; i < nmetrics; i++ ) + for ( i = 0; i < nmetrics; i++, metrics++ ) { - error = pcf_get_metric( stream, format, metrics + i ); + error = pcf_get_metric( stream, format, metrics ); - metrics[i].bits = 0; + metrics->bits = 0; FT_TRACE5(( " idx %d: width=%d, " "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n", i, - ( metrics + i )->characterWidth, - ( metrics + i )->leftSideBearing, - ( metrics + i )->rightSideBearing, - ( metrics + i )->ascent, - ( metrics + i )->descent, - ( metrics + i )->attributes )); + metrics->characterWidth, + metrics->leftSideBearing, + metrics->rightSideBearing, + metrics->ascent, + metrics->descent, + metrics->attributes )); if ( error ) break; + + /* sanity checks -- those values are used in `PCF_Glyph_Load' to */ + /* compute a glyph's bitmap dimensions, thus setting them to zero in */ + /* case of an error disables this particular glyph only */ + if ( metrics->rightSideBearing < metrics->leftSideBearing || + metrics->ascent + metrics->descent < 0 ) + { + metrics->characterWidth = 0; + metrics->leftSideBearing = 0; + metrics->rightSideBearing = 0; + metrics->ascent = 0; + metrics->descent = 0; + + FT_TRACE0(( "pcf_get_metrics:" + " invalid metrics for glyph %d\n", i )); + } } if ( error ) @@ -699,8 +777,7 @@ THE SOFTWARE. FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); - /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */ - if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics ) + if ( nbitmaps != face->nmetrics ) return FT_THROW( Invalid_File_Format ); if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) @@ -728,9 +805,10 @@ THE SOFTWARE. if ( error ) goto Bail; - sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; + sizebitmaps = (FT_ULong)bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; - FT_TRACE4(( " padding %d implies a size of %ld\n", i, bitmapSizes[i] )); + FT_TRACE4(( " padding %d implies a size of %ld\n", + i, bitmapSizes[i] )); } FT_TRACE4(( " %d bitmaps, padding index %ld\n", @@ -750,7 +828,7 @@ THE SOFTWARE. " invalid offset to bitmap data of glyph %d\n", i )); } else - face->metrics[i].bits = stream->pos + offsets[i]; + face->metrics[i].bits = stream->pos + (FT_ULong)offsets[i]; } face->bitmapsFormat = format; @@ -770,8 +848,10 @@ THE SOFTWARE. FT_ULong format, size; int firstCol, lastCol; int firstRow, lastRow; - int nencoding, encodingOffset; - int i, j, k; + FT_ULong nencoding; + FT_UShort encodingOffset; + int i, j; + FT_ULong k; PCF_Encoding encoding = NULL; @@ -812,12 +892,22 @@ THE SOFTWARE. if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) return FT_THROW( Invalid_File_Format ); + /* sanity checks */ + if ( firstCol < 0 || + firstCol > lastCol || + lastCol > 0xFF || + firstRow < 0 || + firstRow > lastRow || + lastRow > 0xFF ) + return FT_THROW( Invalid_Table ); + FT_TRACE4(( "pdf_get_encodings:\n" )); FT_TRACE4(( " firstCol %d, lastCol %d, firstRow %d, lastRow %d\n", firstCol, lastCol, firstRow, lastRow )); - nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 ); + nencoding = (FT_ULong)( lastCol - firstCol + 1 ) * + (FT_ULong)( lastRow - firstRow + 1 ); if ( FT_NEW_ARRAY( encoding, nencoding ) ) return FT_THROW( Out_Of_Memory ); @@ -831,15 +921,19 @@ THE SOFTWARE. { for ( j = firstCol; j <= lastCol; j++ ) { + /* X11's reference implementation uses the equivalent to */ + /* `FT_GET_SHORT', however PCF fonts with more than 32768 */ + /* characters (e.g. `unifont.pcf') clearly show that an */ + /* unsigned value is needed. */ if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - encodingOffset = FT_GET_SHORT(); + encodingOffset = FT_GET_USHORT(); else - encodingOffset = FT_GET_SHORT_LE(); + encodingOffset = FT_GET_USHORT_LE(); - if ( encodingOffset != -1 ) + if ( encodingOffset != 0xFFFFU ) { encoding[k].enc = i * 256 + j; - encoding[k].glyph = (FT_Short)encodingOffset; + encoding[k].glyph = encodingOffset; FT_TRACE5(( " code %d (0x%04X): idx %d\n", encoding[k].enc, encoding[k].enc, encoding[k].glyph )); @@ -1094,9 +1188,11 @@ THE SOFTWARE. FT_LOCAL_DEF( FT_Error ) pcf_load_font( FT_Stream stream, - PCF_Face face ) + PCF_Face face, + FT_Long face_index ) { - FT_Error error = FT_Err_Ok; + FT_Face root = FT_FACE( face ); + FT_Error error; FT_Memory memory = FT_FACE( face )->memory; FT_Bool hasBDFAccelerators; @@ -1105,6 +1201,13 @@ THE SOFTWARE. if ( error ) goto Exit; + root->num_faces = 1; + root->face_index = 0; + + /* If we are performing a simple font format check, exit immediately. */ + if ( face_index < 0 ) + return FT_Err_Ok; + error = pcf_get_properties( stream, face ); if ( error ) goto Exit; @@ -1147,15 +1250,12 @@ THE SOFTWARE. /* now construct the face object */ { - FT_Face root = FT_FACE( face ); PCF_Property prop; - root->num_faces = 1; - root->face_index = 0; - root->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_FAST_GLYPHS; + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_FAST_GLYPHS; if ( face->accel.constantWidth ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; @@ -1179,7 +1279,7 @@ THE SOFTWARE. * * This implies bumping the number of `available' glyphs by 1. */ - root->num_glyphs = face->nmetrics + 1; + root->num_glyphs = (FT_Long)( face->nmetrics + 1 ); root->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) @@ -1192,51 +1292,91 @@ THE SOFTWARE. FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + /* for simplicity, we take absolute values of integer properties */ + #if 0 bsize->height = face->accel.maxbounds.ascent << 6; #endif - bsize->height = (FT_Short)( face->accel.fontAscent + - face->accel.fontDescent ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( face->accel.fontAscent + face->accel.fontDescent < 0 ) + FT_TRACE0(( "pcf_load_font: negative height\n" )); +#endif + bsize->height = FT_ABS( (FT_Short)( face->accel.fontAscent + + face->accel.fontDescent ) ); prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop ) - bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "pcf_load_font: negative average width\n" )); +#endif + bsize->width = FT_ABS( (FT_Short)( ( prop->value.l ) + 5 ) / 10 ); + } else - bsize->width = (FT_Short)( bsize->height * 2/3 ); + bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 ); prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "pcf_load_font: negative point size\n" )); +#endif /* convert from 722.7 decipoints to 72 points per inch */ - bsize->size = - (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); + bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), + 64 * 7200, + 72270L ); + } prop = pcf_find_property( face, "PIXEL_SIZE" ); if ( prop ) - bsize->y_ppem = (FT_Short)prop->value.l << 6; + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "pcf_load_font: negative pixel size\n" )); +#endif + bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6; + } prop = pcf_find_property( face, "RESOLUTION_X" ); if ( prop ) - resolution_x = (FT_Short)prop->value.l; + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "pcf_load_font: negative X resolution\n" )); +#endif + resolution_x = FT_ABS( (FT_Short)prop->value.l ); + } prop = pcf_find_property( face, "RESOLUTION_Y" ); if ( prop ) - resolution_y = (FT_Short)prop->value.l; + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "pcf_load_font: negative Y resolution\n" )); +#endif + resolution_y = FT_ABS( (FT_Short)prop->value.l ); + } if ( bsize->y_ppem == 0 ) { bsize->y_ppem = bsize->size; if ( resolution_y ) - bsize->y_ppem = bsize->y_ppem * resolution_y / 72; + bsize->y_ppem = FT_MulDiv( bsize->y_ppem, resolution_y, 72 ); } if ( resolution_x && resolution_y ) - bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + bsize->x_ppem = FT_MulDiv( bsize->y_ppem, + resolution_x, + resolution_y ); else bsize->x_ppem = bsize->y_ppem; } /* set up charset */ { - PCF_Property charset_registry = 0, charset_encoding = 0; + PCF_Property charset_registry, charset_encoding; charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); diff --git a/drivers/freetype/freetype/src/pcf/pcfread.h b/drivers/freetype/src/pcf/pcfread.h index c9524f1346..bed30e5030 100644 --- a/drivers/freetype/freetype/src/pcf/pcfread.h +++ b/drivers/freetype/src/pcf/pcfread.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCFREAD_H__ -#define __PCFREAD_H__ +#ifndef PCFREAD_H_ +#define PCFREAD_H_ #include <ft2build.h> @@ -39,7 +39,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFREAD_H__ */ +#endif /* PCFREAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pcf/pcfutil.c b/drivers/freetype/src/pcf/pcfutil.c index b91274f935..0451ee8def 100644 --- a/drivers/freetype/freetype/src/pcf/pcfutil.c +++ b/drivers/freetype/src/pcf/pcfutil.c @@ -66,11 +66,11 @@ in this Software without prior written authorization from The Open Group. TwoByteSwap( unsigned char* buf, size_t nbytes ) { - unsigned char c; - - for ( ; nbytes >= 2; nbytes -= 2, buf += 2 ) { + unsigned char c; + + c = buf[0]; buf[0] = buf[1]; buf[1] = c; @@ -85,11 +85,11 @@ in this Software without prior written authorization from The Open Group. FourByteSwap( unsigned char* buf, size_t nbytes ) { - unsigned char c; - - for ( ; nbytes >= 4; nbytes -= 4, buf += 4 ) { + unsigned char c; + + c = buf[0]; buf[0] = buf[3]; buf[3] = c; diff --git a/drivers/freetype/freetype/src/pcf/pcfutil.h b/drivers/freetype/src/pcf/pcfutil.h index ce10fb541d..be986e756b 100644 --- a/drivers/freetype/freetype/src/pcf/pcfutil.h +++ b/drivers/freetype/src/pcf/pcfutil.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCFUTIL_H__ -#define __PCFUTIL_H__ +#ifndef PCFUTIL_H_ +#define PCFUTIL_H_ #include <ft2build.h> @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFUTIL_H__ */ +#endif /* PCFUTIL_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pcf/rules.mk b/drivers/freetype/src/pcf/rules.mk index 78641528fa..1b55daf4f4 100644 --- a/drivers/freetype/freetype/src/pcf/rules.mk +++ b/drivers/freetype/src/pcf/rules.mk @@ -30,7 +30,10 @@ PCF_DIR := $(SRC_DIR)/pcf -PCF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PCF_DIR)) +PCF_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(PCF_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # pcf driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/pfr/Jamfile b/drivers/freetype/src/pfr/Jamfile index 9e2f2b8d05..a5b294b79a 100644 --- a/drivers/freetype/freetype/src/pfr/Jamfile +++ b/drivers/freetype/src/pfr/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/pfr Jamfile # -# Copyright 2002 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,13 @@ SubDir FT2_TOP $(FT2_SRC_DIR) pfr ; if $(FT2_MULTI) { - _sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ; + _sources = pfrcmap + pfrdrivr + pfrgload + pfrload + pfrobjs + pfrsbit + ; } else { diff --git a/drivers/freetype/freetype/src/pfr/module.mk b/drivers/freetype/src/pfr/module.mk index 8d1d28a9d2..bf7808c72f 100644 --- a/drivers/freetype/freetype/src/pfr/module.mk +++ b/drivers/freetype/src/pfr/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2002, 2006 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/pfr/pfr.c b/drivers/freetype/src/pfr/pfr.c index eb2c4edb7e..1a433960a5 100644 --- a/drivers/freetype/freetype/src/pfr/pfr.c +++ b/drivers/freetype/src/pfr/pfr.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR driver component. */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/pfr/pfrcmap.c b/drivers/freetype/src/pfr/pfrcmap.c index 740c433d66..a1439c2e9f 100644 --- a/drivers/freetype/freetype/src/pfr/pfrcmap.c +++ b/drivers/freetype/src/pfr/pfrcmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR cmap handling (body). */ /* */ -/* Copyright 2002, 2007, 2009, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,11 +25,14 @@ FT_CALLBACK_DEF( FT_Error ) - pfr_cmap_init( PFR_CMap cmap ) + pfr_cmap_init( PFR_CMap cmap, + FT_Pointer pointer ) { FT_Error error = FT_Err_Ok; PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); + FT_UNUSED( pointer ); + cmap->num_chars = face->phy_font.num_chars; cmap->chars = face->phy_font.chars; @@ -67,14 +70,16 @@ pfr_cmap_char_index( PFR_CMap cmap, FT_UInt32 char_code ) { - FT_UInt min = 0; - FT_UInt max = cmap->num_chars; - FT_UInt mid; - PFR_Char gchar; + FT_UInt min = 0; + FT_UInt max = cmap->num_chars; while ( min < max ) { + PFR_Char gchar; + FT_UInt mid; + + mid = min + ( max - min ) / 2; gchar = cmap->chars + mid; @@ -125,7 +130,7 @@ } if ( gchar->char_code < char_code ) - min = mid+1; + min = mid + 1; else max = mid; } diff --git a/drivers/freetype/freetype/src/pfr/pfrcmap.h b/drivers/freetype/src/pfr/pfrcmap.h index a626953054..4a8a4d0a67 100644 --- a/drivers/freetype/freetype/src/pfr/pfrcmap.h +++ b/drivers/freetype/src/pfr/pfrcmap.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR cmap handling (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRCMAP_H__ -#define __PFRCMAP_H__ +#ifndef PFRCMAP_H_ +#define PFRCMAP_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRCMAP_H__ */ +#endif /* PFRCMAP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrdrivr.c b/drivers/freetype/src/pfr/pfrdrivr.c index 4c43947bf4..b81c15e560 100644 --- a/drivers/freetype/freetype/src/pfr/pfrdrivr.c +++ b/drivers/freetype/src/pfr/pfrdrivr.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR driver interface (body). */ /* */ -/* Copyright 2002-2004, 2006, 2008, 2010, 2011, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_SERVICE_PFR_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include "pfrdrivr.h" #include "pfrobjs.h" @@ -37,18 +37,20 @@ PFR_PhyFont phys = &face->phy_font; - pfr_face_get_kerning( pfrface, left, right, avector ); + (void)pfr_face_get_kerning( pfrface, left, right, avector ); /* convert from metrics to outline units when necessary */ if ( phys->outline_resolution != phys->metrics_resolution ) { if ( avector->x != 0 ) - avector->x = FT_MulDiv( avector->x, phys->outline_resolution, - phys->metrics_resolution ); + avector->x = FT_MulDiv( avector->x, + (FT_Long)phys->outline_resolution, + (FT_Long)phys->metrics_resolution ); if ( avector->y != 0 ) - avector->y = FT_MulDiv( avector->x, phys->outline_resolution, - phys->metrics_resolution ); + avector->y = FT_MulDiv( avector->y, + (FT_Long)phys->outline_resolution, + (FT_Long)phys->metrics_resolution ); } return FT_Err_Ok; @@ -118,10 +120,10 @@ if ( size ) { x_scale = FT_DivFix( size->metrics.x_ppem << 6, - phys->metrics_resolution ); + (FT_Long)phys->metrics_resolution ); y_scale = FT_DivFix( size->metrics.y_ppem << 6, - phys->metrics_resolution ); + (FT_Long)phys->metrics_resolution ); } if ( ametrics_x_scale ) @@ -134,12 +136,12 @@ } - FT_CALLBACK_TABLE_DEF + static const FT_Service_PfrMetricsRec pfr_metrics_service_rec = { - pfr_get_metrics, - pfr_face_get_kerning, - pfr_get_advance + pfr_get_metrics, /* get_metrics */ + pfr_face_get_kerning, /* get_kerning */ + pfr_get_advance /* get_advance */ }; @@ -151,7 +153,7 @@ static const FT_ServiceDescRec pfr_services[] = { { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PFR }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PFR }, { NULL, NULL } }; @@ -179,31 +181,32 @@ 0x10000L, 0x20000L, - NULL, + 0, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - pfr_get_service + 0, /* FT_Module_Constructor module_init */ + 0, /* FT_Module_Destructor module_done */ + pfr_get_service /* FT_Module_Requester get_interface */ }, sizeof ( PFR_FaceRec ), sizeof ( PFR_SizeRec ), sizeof ( PFR_SlotRec ), - pfr_face_init, - pfr_face_done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - pfr_slot_init, - pfr_slot_done, + pfr_face_init, /* FT_Face_InitFunc init_face */ + pfr_face_done, /* FT_Face_DoneFunc done_face */ + 0, /* FT_Size_InitFunc init_size */ + 0, /* FT_Size_DoneFunc done_size */ + pfr_slot_init, /* FT_Slot_InitFunc init_slot */ + pfr_slot_done, /* FT_Slot_DoneFunc done_slot */ + + pfr_slot_load, /* FT_Slot_LoadFunc load_glyph */ - pfr_slot_load, + pfr_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - pfr_get_kerning, - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ - 0, /* FT_Size_RequestFunc */ - 0, /* FT_Size_SelectFunc */ + 0, /* FT_Size_RequestFunc request_size */ + 0, /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/freetype/src/pfr/pfrdrivr.h b/drivers/freetype/src/pfr/pfrdrivr.h index 75f86c5cdd..32b2d9eab3 100644 --- a/drivers/freetype/freetype/src/pfr/pfrdrivr.h +++ b/drivers/freetype/src/pfr/pfrdrivr.h @@ -4,7 +4,7 @@ /* */ /* High-level Type PFR driver interface (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRDRIVR_H__ -#define __PFRDRIVR_H__ +#ifndef PFRDRIVR_H_ +#define PFRDRIVR_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRDRIVR_H__ */ +#endif /* PFRDRIVR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrerror.h b/drivers/freetype/src/pfr/pfrerror.h index 94dc8c5e1c..9305f8fb58 100644 --- a/drivers/freetype/freetype/src/pfr/pfrerror.h +++ b/drivers/freetype/src/pfr/pfrerror.h @@ -4,7 +4,7 @@ /* */ /* PFR error codes (specification only). */ /* */ -/* Copyright 2002, 2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __PFRERROR_H__ -#define __PFRERROR_H__ +#ifndef PFRERROR_H_ +#define PFRERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PFR_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __PFRERROR_H__ */ +#endif /* PFRERROR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrgload.c b/drivers/freetype/src/pfr/pfrgload.c index 88b4d66a13..f9cd1f63bb 100644 --- a/drivers/freetype/freetype/src/pfr/pfrgload.c +++ b/drivers/freetype/src/pfr/pfrgload.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR glyph loader (body). */ /* */ -/* Copyright 2002, 2003, 2005, 2007, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -92,8 +92,8 @@ if ( outline->n_contours > 0 ) first = outline->contours[outline->n_contours - 1]; - /* if the last point falls on the same location than the first one */ - /* we need to delete it */ + /* if the last point falls on the same location as the first one */ + /* we need to delete it */ if ( last > first ) { FT_Vector* p1 = outline->points + first; @@ -143,7 +143,7 @@ error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 ); if ( !error ) { - FT_UInt n = outline->n_points; + FT_Int n = outline->n_points; outline->points[n] = *to; @@ -215,8 +215,10 @@ /* check that there is space for a new contour and a new point */ error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 ); if ( !error ) + { /* add new start point */ error = pfr_glyph_line_to( glyph, to ); + } return error; } @@ -304,8 +306,8 @@ glyph->y_control = glyph->x_control + x_count; - mask = 0; - x = 0; + mask = 0; + x = 0; for ( i = 0; i < count; i++ ) { @@ -331,10 +333,10 @@ mask >>= 1; } - /* XXX: for now we ignore the secondary stroke and edge definitions */ - /* since we don't want to support native PFR hinting */ - /* */ - if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + /* XXX: we ignore the secondary stroke and edge definitions */ + /* since we don't support native PFR hinting */ + /* */ + if ( flags & PFR_GLYPH_SINGLE_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); if ( error ) @@ -366,27 +368,27 @@ switch ( format >> 4 ) { - case 0: /* end glyph */ + case 0: /* end glyph */ FT_TRACE6(( "- end glyph" )); args_count = 0; break; - case 1: /* general line operation */ + case 1: /* general line operation */ FT_TRACE6(( "- general line" )); goto Line1; - case 4: /* move to inside contour */ + case 4: /* move to inside contour */ FT_TRACE6(( "- move to inside" )); goto Line1; - case 5: /* move to outside contour */ + case 5: /* move to outside contour */ FT_TRACE6(( "- move to outside" )); Line1: args_format = format_low; args_count = 1; break; - case 2: /* horizontal line to */ + case 2: /* horizontal line to */ FT_TRACE6(( "- horizontal line to cx.%d", format_low )); if ( format_low >= x_count ) goto Failure; @@ -396,7 +398,7 @@ args_count = 0; break; - case 3: /* vertical line to */ + case 3: /* vertical line to */ FT_TRACE6(( "- vertical line to cy.%d", format_low )); if ( format_low >= y_count ) goto Failure; @@ -406,19 +408,19 @@ args_count = 0; break; - case 6: /* horizontal to vertical curve */ + case 6: /* horizontal to vertical curve */ FT_TRACE6(( "- hv curve " )); args_format = 0xB8E; args_count = 3; break; - case 7: /* vertical to horizontal curve */ + case 7: /* vertical to horizontal curve */ FT_TRACE6(( "- vh curve" )); args_format = 0xE2B; args_count = 3; break; - default: /* general curve to */ + default: /* general curve to */ FT_TRACE6(( "- general curve" )); args_count = 4; args_format = format_low; @@ -439,14 +441,14 @@ { case 0: /* 8-bit index */ PFR_CHECK( 1 ); - idx = PFR_NEXT_BYTE( p ); + idx = PFR_NEXT_BYTE( p ); if ( idx >= x_count ) goto Failure; cur->x = glyph->x_control[idx]; FT_TRACE7(( " cx#%d", idx )); break; - case 1: /* 16-bit value */ + case 1: /* 16-bit absolute value */ PFR_CHECK( 2 ); cur->x = PFR_NEXT_SHORT( p ); FT_TRACE7(( " x.%d", cur->x )); @@ -516,22 +518,22 @@ /* */ switch ( format >> 4 ) { - case 0: /* end glyph => EXIT */ + case 0: /* end glyph => EXIT */ pfr_glyph_end( glyph ); goto Exit; - case 1: /* line operations */ + case 1: /* line operations */ case 2: case 3: error = pfr_glyph_line_to( glyph, pos ); goto Test_Error; - case 4: /* move to inside contour */ - case 5: /* move to outside contour */ + case 4: /* move to inside contour */ + case 5: /* move to outside contour */ error = pfr_glyph_move_to( glyph, pos ); goto Test_Error; - default: /* curve operations */ + default: /* curve operations */ error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); Test_Error: /* test error condition */ @@ -577,10 +579,11 @@ /* ignore extra items when present */ /* */ - if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + if ( flags & PFR_GLYPH_COMPOUND_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); - if (error) goto Exit; + if ( error ) + goto Exit; } /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ @@ -632,14 +635,14 @@ if ( format & PFR_SUBGLYPH_XSCALE ) { PFR_CHECK( 2 ); - subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4; + subglyph->x_scale = PFR_NEXT_SHORT( p ) * 16; } subglyph->y_scale = 0x10000L; if ( format & PFR_SUBGLYPH_YSCALE ) { PFR_CHECK( 2 ); - subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4; + subglyph->y_scale = PFR_NEXT_SHORT( p ) * 16; } /* read offset */ @@ -693,7 +696,7 @@ if ( format & PFR_SUBGLYPH_3BYTE_OFFSET ) { PFR_CHECK( 3 ); - subglyph->gps_offset = PFR_NEXT_LONG( p ); + subglyph->gps_offset = PFR_NEXT_ULONG( p ); } else { @@ -736,7 +739,7 @@ if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND ) { - FT_Int n, old_count, count; + FT_UInt n, old_count, count; FT_GlyphLoader loader = glyph->loader; FT_Outline* base = &loader->base.outline; @@ -763,7 +766,7 @@ PFR_SubGlyph subglyph; - FT_TRACE4(( "subglyph %d:\n", n )); + FT_TRACE4(( " subglyph %d:\n", n )); subglyph = glyph->subs + old_count + n; old_points = base->n_points; diff --git a/drivers/freetype/freetype/src/pfr/pfrgload.h b/drivers/freetype/src/pfr/pfrgload.h index 7cc7a8702a..908d4378a4 100644 --- a/drivers/freetype/freetype/src/pfr/pfrgload.h +++ b/drivers/freetype/src/pfr/pfrgload.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR glyph loader (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRGLOAD_H__ -#define __PFRGLOAD_H__ +#ifndef PFRGLOAD_H_ +#define PFRGLOAD_H_ #include "pfrtypes.h" @@ -43,7 +43,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRGLOAD_H__ */ +#endif /* PFRGLOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrload.c b/drivers/freetype/src/pfr/pfrload.c index c19fceb1ee..e509e70b5d 100644 --- a/drivers/freetype/freetype/src/pfr/pfrload.c +++ b/drivers/freetype/src/pfr/pfrload.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR loader (body). */ /* */ -/* Copyright 2002-2005, 2007, 2009, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,93 @@ #define FT_COMPONENT trace_pfr + /* + * The overall structure of a PFR file is as follows. + * + * PFR header + * 58 bytes (contains nPhysFonts) + * + * Logical font directory (size at most 2^16 bytes) + * 2 bytes (nLogFonts) + * + nLogFonts * 5 bytes + * + * ==> nLogFonts <= 13106 + * + * Logical font section (size at most 2^24 bytes) + * nLogFonts * logFontRecord + * + * logFontRecord (size at most 2^16 bytes) + * 12 bytes (fontMatrix) + * + 1 byte (flags) + * + 0-5 bytes (depending on `flags') + * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags') + * + 5 bytes (physical font info) + * + 0-1 bytes (depending on PFR header) + * + * ==> minimum size 18 bytes + * + * Physical font section (size at most 2^24 bytes) + * nPhysFonts * (physFontRecord + * + nBitmapSizes * nBmapChars * bmapCharRecord) + * + * physFontRecord (size at most 2^24 bytes) + * 14 bytes (font info) + * + 1 byte (flags) + * + 0-2 (depending on `flags') + * + 0-? (structure too complicated to be shown here; depending on + * `flags'; contains `nBitmapSizes' and `nBmapChars') + * + 3 bytes (nAuxBytes) + * + nAuxBytes + * + 1 byte (nBlueValues) + * + 2 * nBlueValues + * + 6 bytes (hinting data) + * + 2 bytes (nCharacters) + * + nCharacters * (4-10 bytes) (depending on `flags') + * + * ==> minimum size 27 bytes + * + * bmapCharRecord + * 4-7 bytes + * + * Glyph program strings (three possible types: simpleGps, compoundGps, + * and bitmapGps; size at most 2^24 bytes) + * simpleGps (size at most 2^16 bytes) + * 1 byte (flags) + * 1-2 bytes (n[XY]orus, depending on `flags') + * 0-(64+512*2) = 0-1088 bytes (depending on `n[XY]orus') + * 0-? (structure too complicated to be shown here; depending on + * `flags') + * 1-? glyph data (faintly resembling PS Type 1 charstrings) + * + * ==> minimum size 3 bytes + * + * compoundGps (size at most 2^16 bytes) + * 1 byte (nElements <= 63, flags) + * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags') + * + nElements * (6-14 bytes) + * + * bitmapGps (size at most 2^16 bytes) + * 1 byte (flags) + * 3-13 bytes (position info, depending on `flags') + * 0-? bitmap data + * + * ==> minimum size 4 bytes + * + * PFR trailer + * 8 bytes + * + * + * ==> minimum size of a valid PFR: + * 58 (header) + * + 2 (nLogFonts) + * + 27 (1 physFontRecord) + * + 8 (trailer) + * ----- + * 95 bytes + * + */ + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -75,7 +162,8 @@ if ( extra->type == item_type ) { error = extra->parser( p, p + item_size, item_data ); - if ( error ) goto Exit; + if ( error ) + goto Exit; break; } @@ -179,11 +267,12 @@ if ( header->signature != 0x50465230L || /* "PFR0" */ header->version > 4 || header->header_size < 58 || - header->signature2 != 0x0d0a ) /* CR/LF */ + header->signature2 != 0x0D0A ) /* CR/LF */ { result = 0; } - return result; + + return result; } @@ -199,20 +288,37 @@ FT_LOCAL_DEF( FT_Error ) pfr_log_font_count( FT_Stream stream, FT_UInt32 section_offset, - FT_UInt *acount ) + FT_Long *acount ) { FT_Error error; FT_UInt count; FT_UInt result = 0; - if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) + if ( FT_STREAM_SEEK( section_offset ) || + FT_READ_USHORT( count ) ) + goto Exit; + + /* check maximum value and a rough minimum size: */ + /* - no more than 13106 log fonts */ + /* - we need 5 bytes for a log header record */ + /* - we need at least 18 bytes for a log font record */ + /* - the overall size is at least 95 bytes plus the */ + /* log header and log font records */ + if ( count > ( ( 1 << 16 ) - 2 ) / 5 || + 2 + count * 5 >= stream->size - section_offset || + 95 + count * ( 5 + 18 ) >= stream->size ) + { + FT_ERROR(( "pfr_log_font_count:" + " invalid number of logical fonts\n" )); + error = FT_THROW( Invalid_Table ); goto Exit; + } result = count; Exit: - *acount = result; + *acount = (FT_Long)result; return error; } @@ -254,13 +360,14 @@ FT_UInt local; - if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + if ( FT_STREAM_SEEK( offset ) || + FT_FRAME_ENTER( size ) ) goto Exit; p = stream->cursor; limit = p + size; - PFR_CHECK(13); + PFR_CHECK( 13 ); log_font->matrix[0] = PFR_NEXT_LONG( p ); log_font->matrix[1] = PFR_NEXT_LONG( p ); @@ -276,7 +383,7 @@ if ( flags & PFR_LOG_2BYTE_STROKE ) local++; - if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) + if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER ) local += 3; } if ( flags & PFR_LOG_BOLD ) @@ -308,10 +415,11 @@ if ( flags & PFR_LOG_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); - if (error) goto Fail; + if ( error ) + goto Fail; } - PFR_CHECK(5); + PFR_CHECK( 5 ); log_font->phys_size = PFR_NEXT_USHORT( p ); log_font->phys_offset = PFR_NEXT_ULONG( p ); if ( size_increment ) @@ -358,7 +466,7 @@ PFR_CHECK( 5 ); - p += 3; /* skip bctSize */ + p += 3; /* skip bctSize */ flags0 = PFR_NEXT_BYTE( p ); count = PFR_NEXT_BYTE( p ); @@ -434,12 +542,12 @@ } - /* Load font ID. This is a so-called "unique" name that is rather - * long and descriptive (like "Tiresias ScreenFont v7.51"). + /* Load font ID. This is a so-called `unique' name that is rather + * long and descriptive (like `Tiresias ScreenFont v7.51'). * * Note that a PFR font's family name is contained in an *undocumented* - * string of the "auxiliary data" portion of a physical font record. This - * may also contain the "real" style name! + * string of the `auxiliary data' portion of a physical font record. This + * may also contain the `real' style name! * * If no family name is present, the font ID is used instead for the * family. @@ -449,9 +557,9 @@ FT_Byte* limit, PFR_PhyFont phy_font ) { - FT_Error error = FT_Err_Ok; - FT_Memory memory = phy_font->memory; - FT_PtrDist len = limit - p; + FT_Error error = FT_Err_Ok; + FT_Memory memory = phy_font->memory; + FT_UInt len = (FT_UInt)( limit - p ); if ( phy_font->font_id != NULL ) @@ -507,7 +615,7 @@ Too_Short: error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_exta_item_load_stem_snaps:" + FT_ERROR(( "pfr_extra_item_load_stem_snaps:" " invalid stem snaps table\n" )); goto Exit; } @@ -525,8 +633,6 @@ FT_Memory memory = phy_font->memory; - FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); - if ( FT_NEW( item ) ) goto Exit; @@ -535,7 +641,8 @@ item->pair_count = PFR_NEXT_BYTE( p ); item->base_adj = PFR_NEXT_SHORT( p ); item->flags = PFR_NEXT_BYTE( p ); - item->offset = phy_font->offset + ( p - phy_font->cursor ); + item->offset = phy_font->offset + + (FT_Offset)( p - phy_font->cursor ); #ifndef PFR_CONFIG_NO_CHECKS item->pair_size = 3; @@ -611,7 +718,6 @@ } - static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = { { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info }, @@ -622,7 +728,8 @@ }; - /* Loads a name from the auxiliary data. Since this extracts undocumented + /* + * Load a name from the auxiliary data. Since this extracts undocumented * strings from the font file, we need to be careful here. */ static FT_Error @@ -636,12 +743,14 @@ FT_UInt n, ok; + if ( *astring ) + FT_FREE( *astring ); + if ( len > 0 && p[len - 1] == 0 ) len--; - /* check that each character is ASCII for making sure not to - load garbage - */ + /* check that each character is ASCII */ + /* for making sure not to load garbage */ ok = ( len > 0 ); for ( n = 0; n < len; n++ ) if ( p[n] < 32 || p[n] > 127 ) @@ -658,6 +767,7 @@ FT_MEM_COPY( result, p, len ); result[len] = 0; } + Exit: *astring = result; return error; @@ -728,7 +838,8 @@ phy_font->kern_items = NULL; phy_font->kern_items_tail = &phy_font->kern_items; - if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + if ( FT_STREAM_SEEK( offset ) || + FT_FRAME_ENTER( size ) ) goto Exit; phy_font->cursor = stream->cursor; @@ -756,16 +867,16 @@ /* load the extra items when present */ if ( flags & PFR_PHY_EXTRA_ITEMS ) { - error = pfr_extra_items_parse( &p, limit, - pfr_phy_font_extra_items, phy_font ); + error = pfr_extra_items_parse( &p, limit, + pfr_phy_font_extra_items, phy_font ); if ( error ) goto Fail; } - /* In certain fonts, the auxiliary bytes contain interesting */ - /* information. These are not in the specification but can be */ - /* guessed by looking at the content of a few PFR0 fonts. */ + /* In certain fonts, the auxiliary bytes contain interesting */ + /* information. These are not in the specification but can be */ + /* guessed by looking at the content of a few PFR0 fonts. */ PFR_CHECK( 3 ); num_aux = PFR_NEXT_ULONG( p ); @@ -775,7 +886,7 @@ FT_Byte* q2; - PFR_CHECK( num_aux ); + PFR_CHECK_SIZE( num_aux ); p += num_aux; while ( num_aux > 0 ) @@ -796,9 +907,8 @@ switch ( type ) { case 1: - /* this seems to correspond to the font's family name, - * padded to 16-bits with one zero when necessary - */ + /* this seems to correspond to the font's family name, padded to */ + /* an even number of bytes with a zero byte appended if needed */ error = pfr_aux_name_load( q, length - 4U, memory, &phy_font->family_name ); if ( error ) @@ -813,13 +923,11 @@ phy_font->ascent = PFR_NEXT_SHORT( q ); phy_font->descent = PFR_NEXT_SHORT( q ); phy_font->leading = PFR_NEXT_SHORT( q ); - q += 16; break; case 3: - /* this seems to correspond to the font's style name, - * padded to 16-bits with one zero when necessary - */ + /* this seems to correspond to the font's style name, padded to */ + /* an even number of bytes with a zero byte appended if needed */ error = pfr_aux_name_load( q, length - 4U, memory, &phy_font->style_name ); if ( error ) @@ -865,10 +973,7 @@ phy_font->num_chars = count = PFR_NEXT_USHORT( p ); - phy_font->chars_offset = offset + ( p - stream->cursor ); - - if ( FT_NEW_ARRAY( phy_font->chars, count ) ) - goto Fail; + phy_font->chars_offset = offset + (FT_Offset)( p - stream->cursor ); Size = 1 + 1 + 2; if ( flags & PFR_PHY_2BYTE_CHARCODE ) @@ -886,7 +991,10 @@ if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) Size += 1; - PFR_CHECK( count * Size ); + PFR_CHECK_SIZE( count * Size ); + + if ( FT_NEW_ARRAY( phy_font->chars, count ) ) + goto Fail; for ( n = 0; n < count; n++ ) { @@ -899,7 +1007,7 @@ cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) ? PFR_NEXT_SHORT( p ) - : (FT_Int) phy_font->standard_advance; + : phy_font->standard_advance; #if 0 cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) diff --git a/drivers/freetype/freetype/src/pfr/pfrload.h b/drivers/freetype/src/pfr/pfrload.h index ed010715d1..0f7a2bb239 100644 --- a/drivers/freetype/freetype/src/pfr/pfrload.h +++ b/drivers/freetype/src/pfr/pfrload.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR loader (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRLOAD_H__ -#define __PFRLOAD_H__ +#ifndef PFRLOAD_H_ +#define PFRLOAD_H_ #include "pfrobjs.h" #include FT_INTERNAL_STREAM_H @@ -25,14 +25,19 @@ FT_BEGIN_HEADER + /* some size checks should be always done (mainly to prevent */ + /* excessive allocation for malformed data), ... */ +#define PFR_CHECK_SIZE( x ) do \ + { \ + if ( p + (x) > limit ) \ + goto Too_Short; \ + } while ( 0 ) + + /* ... and some only if intensive checking is explicitly requested */ #ifdef PFR_CONFIG_NO_CHECKS #define PFR_CHECK( x ) do { } while ( 0 ) #else -#define PFR_CHECK( x ) do \ - { \ - if ( p + (x) > limit ) \ - goto Too_Short; \ - } while ( 0 ) +#define PFR_CHECK PFR_CHECK_SIZE #endif #define PFR_NEXT_BYTE( p ) FT_NEXT_BYTE( p ) @@ -85,7 +90,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) pfr_log_font_count( FT_Stream stream, FT_UInt32 log_section_offset, - FT_UInt *acount ); + FT_Long *acount ); /* load a pfr logical font entry */ FT_LOCAL( FT_Error ) @@ -112,7 +117,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRLOAD_H__ */ +#endif /* PFRLOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrobjs.c b/drivers/freetype/src/pfr/pfrobjs.c index 75fc4c3f1f..769a3b6164 100644 --- a/drivers/freetype/freetype/src/pfr/pfrobjs.c +++ b/drivers/freetype/src/pfr/pfrobjs.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (body). */ /* */ -/* Copyright 2002-2008, 2010-2011, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,6 +23,7 @@ #include "pfrsbit.h" #include FT_OUTLINE_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include FT_TRUETYPE_IDS_H #include "pfrerror.h" @@ -93,7 +94,7 @@ /* check face index */ { - FT_UInt num_faces; + FT_Long num_faces; error = pfr_log_font_count( stream, @@ -108,7 +109,7 @@ if ( face_index < 0 ) goto Exit; - if ( face_index >= pfrface->num_faces ) + if ( ( face_index & 0xFFFF ) >= pfrface->num_faces ) { FT_ERROR(( "pfr_face_init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); @@ -117,9 +118,11 @@ /* load the face */ error = pfr_log_font_load( - &face->log_font, stream, face_index, - face->header.log_dir_offset, - FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); + &face->log_font, + stream, + (FT_UInt)( face_index & 0xFFFF ), + face->header.log_dir_offset, + FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); if ( error ) goto Exit; @@ -135,12 +138,13 @@ PFR_PhyFont phy_font = &face->phy_font; - pfrface->face_index = face_index; - pfrface->num_glyphs = phy_font->num_chars + 1; - pfrface->face_flags = FT_FACE_FLAG_SCALABLE; + pfrface->face_index = face_index & 0xFFFF; + pfrface->num_glyphs = (FT_Long)phy_font->num_chars + 1; - /* if all characters point to the same gps_offset 0, we */ - /* assume that the font only contains bitmaps */ + pfrface->face_flags |= FT_FACE_FLAG_SCALABLE; + + /* if gps_offset == 0 for all characters, we */ + /* assume that the font only contains bitmaps */ { FT_UInt nn; @@ -162,7 +166,7 @@ } } - if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) + if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( phy_font->flags & PFR_PHY_VERTICAL ) @@ -176,7 +180,7 @@ if ( phy_font->num_kern_pairs > 0 ) pfrface->face_flags |= FT_FACE_FLAG_KERNING; - /* If no family name was found in the "undocumented" auxiliary + /* If no family name was found in the `undocumented' auxiliary * data, use the font ID instead. This sucks but is better than * nothing. */ @@ -185,12 +189,12 @@ pfrface->family_name = phy_font->font_id; /* note that the style name can be NULL in certain PFR fonts, - * probably meaning "Regular" + * probably meaning `Regular' */ pfrface->style_name = phy_font->style_name; pfrface->num_fixed_sizes = 0; - pfrface->available_sizes = 0; + pfrface->available_sizes = NULL; pfrface->bbox = phy_font->bbox; pfrface->units_per_EM = (FT_UShort)phy_font->outline_resolution; @@ -216,13 +220,13 @@ strike = phy_font->strikes; for ( n = 0; n < count; n++, size++, strike++ ) { - size->height = (FT_UShort)strike->y_ppm; - size->width = (FT_UShort)strike->x_ppm; - size->size = strike->y_ppm << 6; - size->x_ppem = strike->x_ppm << 6; - size->y_ppem = strike->y_ppm << 6; + size->height = (FT_Short)strike->y_ppm; + size->width = (FT_Short)strike->x_ppm; + size->size = (FT_Pos)( strike->y_ppm << 6 ); + size->x_ppem = (FT_Pos)( strike->x_ppm << 6 ); + size->y_ppem = (FT_Pos)( strike->y_ppm << 6 ); } - pfrface->num_fixed_sizes = count; + pfrface->num_fixed_sizes = (FT_Int)count; } /* now compute maximum advance width */ @@ -262,13 +266,13 @@ error = FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); #if 0 - /* Select default charmap */ + /* select default charmap */ if ( pfrface->num_charmaps ) pfrface->charmap = pfrface->charmaps[0]; #endif } - /* check whether we've loaded any kerning pairs */ + /* check whether we have loaded any kerning pairs */ if ( phy_font->num_kern_pairs ) pfrface->face_flags |= FT_FACE_FLAG_KERNING; } @@ -324,6 +328,8 @@ FT_ULong gps_offset; + FT_TRACE1(( "pfr_slot_load: glyph index %d\n", gindex )); + if ( gindex > 0 ) gindex--; @@ -362,7 +368,7 @@ FT_BBox cbox; FT_Glyph_Metrics* metrics = &pfrslot->metrics; FT_Pos advance; - FT_Int em_metrics, em_outline; + FT_UInt em_metrics, em_outline; FT_Bool scaling; @@ -386,7 +392,9 @@ em_outline = face->phy_font.outline_resolution; if ( em_metrics != em_outline ) - advance = FT_MulDiv( advance, em_outline, em_metrics ); + advance = FT_MulDiv( advance, + (FT_Long)em_outline, + (FT_Long)em_metrics ); if ( face->phy_font.flags & PFR_PHY_VERTICAL ) metrics->vertAdvance = advance; @@ -396,7 +404,7 @@ pfrslot->linearHoriAdvance = metrics->horiAdvance; pfrslot->linearVertAdvance = metrics->vertAdvance; - /* make-up vertical metrics(?) */ + /* make up vertical metrics(?) */ metrics->vertBearingX = 0; metrics->vertBearingY = 0; @@ -512,12 +520,12 @@ { FT_UInt count = item->pair_count; FT_UInt size = item->pair_size; - FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count ); + FT_UInt power = 1 << FT_MSB( count ); FT_UInt probe = power * size; FT_UInt extra = count - power; FT_Byte* base = stream->cursor; - FT_Bool twobytes = FT_BOOL( item->flags & 1 ); - FT_Bool twobyte_adj = FT_BOOL( item->flags & 2 ); + FT_Bool twobytes = FT_BOOL( item->flags & PFR_KERN_2BYTE_CHAR ); + FT_Bool twobyte_adj = FT_BOOL( item->flags & PFR_KERN_2BYTE_ADJ ); FT_Byte* p; FT_UInt32 cpair; @@ -590,4 +598,5 @@ return error; } + /* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrobjs.h b/drivers/freetype/src/pfr/pfrobjs.h index f6aa8b44cc..335aca8854 100644 --- a/drivers/freetype/freetype/src/pfr/pfrobjs.h +++ b/drivers/freetype/src/pfr/pfrobjs.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (specification). */ /* */ -/* Copyright 2002, 2003, 2004 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFROBJS_H__ -#define __PFROBJS_H__ +#ifndef PFROBJS_H_ +#define PFROBJS_H_ #include "pfrtypes.h" @@ -90,7 +90,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFROBJS_H__ */ +#endif /* PFROBJS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrsbit.c b/drivers/freetype/src/pfr/pfrsbit.c index 2da1500707..144f50c0b3 100644 --- a/drivers/freetype/freetype/src/pfr/pfrsbit.c +++ b/drivers/freetype/src/pfr/pfrsbit.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR bitmap loader (body). */ /* */ -/* Copyright 2002, 2003, 2006, 2009, 2010, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -37,11 +37,11 @@ typedef struct PFR_BitWriter_ { - FT_Byte* line; /* current line start */ - FT_Int pitch; /* line size in bytes */ - FT_Int width; /* width in pixels/bits */ - FT_Int rows; /* number of remaining rows to scan */ - FT_Int total; /* total number of bits to draw */ + FT_Byte* line; /* current line start */ + FT_Int pitch; /* line size in bytes */ + FT_UInt width; /* width in pixels/bits */ + FT_UInt rows; /* number of remaining rows to scan */ + FT_UInt total; /* total number of bits to draw */ } PFR_BitWriterRec, *PFR_BitWriter; @@ -59,7 +59,7 @@ if ( !decreasing ) { - writer->line += writer->pitch * ( target->rows-1 ); + writer->line += writer->pitch * (FT_Int)( target->rows - 1 ); writer->pitch = -writer->pitch; } } @@ -70,15 +70,15 @@ FT_Byte* p, FT_Byte* limit ) { - FT_Int n, reload; - FT_Int left = writer->width; + FT_UInt n, reload; + FT_UInt left = writer->width; FT_Byte* cur = writer->line; FT_UInt mask = 0x80; FT_UInt val = 0; FT_UInt c = 0; - n = (FT_Int)( limit - p ) * 8; + n = (FT_UInt)( limit - p ) * 8; if ( n > writer->total ) n = writer->total; @@ -110,7 +110,7 @@ cur[0] = (FT_Byte)c; mask = 0x80; c = 0; - cur ++; + cur++; } } @@ -124,8 +124,9 @@ FT_Byte* p, FT_Byte* limit ) { - FT_Int n, phase, count, counts[2], reload; - FT_Int left = writer->width; + FT_Int phase, count, counts[2]; + FT_UInt n, reload; + FT_UInt left = writer->width; FT_Byte* cur = writer->line; FT_UInt mask = 0x80; FT_UInt c = 0; @@ -175,7 +176,7 @@ if ( --left <= 0 ) { - cur[0] = (FT_Byte) c; + cur[0] = (FT_Byte)c; left = writer->width; mask = 0x80; @@ -188,7 +189,7 @@ cur[0] = (FT_Byte)c; mask = 0x80; c = 0; - cur ++; + cur++; } reload = ( --count <= 0 ); @@ -204,8 +205,9 @@ FT_Byte* p, FT_Byte* limit ) { - FT_Int n, phase, count, reload; - FT_Int left = writer->width; + FT_Int phase, count; + FT_UInt n, reload; + FT_UInt left = writer->width; FT_Byte* cur = writer->line; FT_UInt mask = 0x80; FT_UInt c = 0; @@ -239,7 +241,7 @@ if ( --left <= 0 ) { - cur[0] = (FT_Byte) c; + cur[0] = (FT_Byte)c; c = 0; mask = 0x80; left = writer->width; @@ -252,7 +254,7 @@ cur[0] = (FT_Byte)c; c = 0; mask = 0x80; - cur ++; + cur++; } reload = ( --count <= 0 ); @@ -275,49 +277,99 @@ pfr_lookup_bitmap_data( FT_Byte* base, FT_Byte* limit, FT_UInt count, - FT_UInt flags, + FT_UInt* flags, FT_UInt char_code, FT_ULong* found_offset, FT_ULong* found_size ) { - FT_UInt left, right, char_len; - FT_Bool two = FT_BOOL( flags & 1 ); + FT_UInt min, max, char_len; + FT_Bool two = FT_BOOL( *flags & PFR_BITMAP_2BYTE_CHARCODE ); FT_Byte* buff; char_len = 4; - if ( two ) char_len += 1; - if ( flags & 2 ) char_len += 1; - if ( flags & 4 ) char_len += 1; + if ( two ) + char_len += 1; + if ( *flags & PFR_BITMAP_2BYTE_SIZE ) + char_len += 1; + if ( *flags & PFR_BITMAP_3BYTE_OFFSET ) + char_len += 1; + + if ( !( *flags & PFR_BITMAP_CHARCODES_VALIDATED ) ) + { + FT_Byte* p; + FT_Byte* lim; + FT_UInt code; + FT_Long prev_code; - left = 0; - right = count; - while ( left < right ) - { - FT_UInt middle, code; + *flags |= PFR_BITMAP_VALID_CHARCODES; + prev_code = -1; + lim = base + count * char_len; + + if ( lim > limit ) + { + FT_TRACE0(( "pfr_lookup_bitmap_data:" + " number of bitmap records too large,\n" + " " + " thus ignoring all bitmaps in this strike\n" )); + *flags &= ~PFR_BITMAP_VALID_CHARCODES; + } + else + { + /* check whether records are sorted by code */ + for ( p = base; p < lim; p += char_len ) + { + if ( two ) + code = FT_PEEK_USHORT( p ); + else + code = *p; + + if ( (FT_Long)code <= prev_code ) + { + FT_TRACE0(( "pfr_lookup_bitmap_data:" + " bitmap records are not sorted,\n" + " " + " thus ignoring all bitmaps in this strike\n" )); + *flags &= ~PFR_BITMAP_VALID_CHARCODES; + break; + } + + prev_code = code; + } + } + + *flags |= PFR_BITMAP_CHARCODES_VALIDATED; + } + + /* ignore bitmaps in case table is not valid */ + /* (this might be sanitized, but PFR is dead...) */ + if ( !( *flags & PFR_BITMAP_VALID_CHARCODES ) ) + goto Fail; + + min = 0; + max = count; + /* binary search */ + while ( min < max ) + { + FT_UInt mid, code; - middle = ( left + right ) >> 1; - buff = base + middle * char_len; - /* check that we are not outside of the table -- */ - /* this is possible with broken fonts... */ - if ( buff + char_len > limit ) - goto Fail; + mid = ( min + max ) >> 1; + buff = base + mid * char_len; if ( two ) code = PFR_NEXT_USHORT( buff ); else code = PFR_NEXT_BYTE( buff ); - if ( code == char_code ) - goto Found_It; - - if ( code < char_code ) - left = middle; + if ( char_code < code ) + max = mid; + else if ( char_code > code ) + min = mid + 1; else - right = middle; + goto Found_It; } Fail: @@ -327,20 +379,20 @@ return; Found_It: - if ( flags & 2 ) + if ( *flags & PFR_BITMAP_2BYTE_SIZE ) *found_size = PFR_NEXT_USHORT( buff ); else *found_size = PFR_NEXT_BYTE( buff ); - if ( flags & 4 ) + if ( *flags & PFR_BITMAP_3BYTE_OFFSET ) *found_offset = PFR_NEXT_ULONG( buff ); else *found_offset = PFR_NEXT_USHORT( buff ); } - /* load bitmap metrics. "*padvance" must be set to the default value */ - /* before calling this function... */ + /* load bitmap metrics. `*padvance' must be set to the default value */ + /* before calling this function */ /* */ static FT_Error pfr_load_bitmap_metrics( FT_Byte** pdata, @@ -355,7 +407,7 @@ { FT_Error error = FT_Err_Ok; FT_Byte flags; - FT_Char b; + FT_Byte b; FT_Byte* p = *pdata; FT_Long xpos, ypos, advance; FT_UInt xsize, ysize; @@ -374,8 +426,8 @@ { case 0: PFR_CHECK( 1 ); - b = PFR_NEXT_INT8( p ); - xpos = b >> 4; + b = PFR_NEXT_BYTE( p ); + xpos = (FT_Char)b >> 4; ypos = ( (FT_Char)( b << 4 ) ) >> 4; break; @@ -442,7 +494,7 @@ case 1: PFR_CHECK( 1 ); - advance = PFR_NEXT_INT8( p ) << 8; + advance = PFR_NEXT_INT8( p ) * 256; break; case 2: @@ -507,8 +559,7 @@ break; default: - FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); - error = FT_THROW( Invalid_File_Format ); + ; } } @@ -541,7 +592,7 @@ character = &phys->chars[glyph_index]; - /* Look-up a bitmap strike corresponding to the current */ + /* look up a bitmap strike corresponding to the current */ /* character dimensions */ { FT_UInt n; @@ -552,9 +603,7 @@ { if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem && strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem ) - { goto Found_Strike; - } strike++; } @@ -565,17 +614,20 @@ Found_Strike: - /* Now lookup the glyph's position within the file */ + /* now look up the glyph's position within the file */ { FT_UInt char_len; char_len = 4; - if ( strike->flags & 1 ) char_len += 1; - if ( strike->flags & 2 ) char_len += 1; - if ( strike->flags & 4 ) char_len += 1; - - /* Access data directly in the frame to speed lookups */ + if ( strike->flags & PFR_BITMAP_2BYTE_CHARCODE ) + char_len += 1; + if ( strike->flags & PFR_BITMAP_2BYTE_SIZE ) + char_len += 1; + if ( strike->flags & PFR_BITMAP_3BYTE_OFFSET ) + char_len += 1; + + /* access data directly in the frame to speed lookups */ if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) || FT_FRAME_ENTER( char_len * strike->num_bitmaps ) ) goto Exit; @@ -583,7 +635,7 @@ pfr_lookup_bitmap_data( stream->cursor, stream->limit, strike->num_bitmaps, - strike->flags, + &strike->flags, character->char_code, &gps_offset, &gps_size ); @@ -592,7 +644,7 @@ if ( gps_size == 0 ) { - /* Could not find a bitmap program string for this glyph */ + /* could not find a bitmap program string for this glyph */ error = FT_THROW( Invalid_Argument ); goto Exit; } @@ -609,16 +661,16 @@ advance = character->advance; if ( phys->metrics_resolution != phys->outline_resolution ) advance = FT_MulDiv( advance, - phys->outline_resolution, - phys->metrics_resolution ); + (FT_Long)phys->outline_resolution, + (FT_Long)phys->metrics_resolution ); glyph->root.linearHoriAdvance = advance; - /* compute default advance, i.e., scaled advance. This can be */ - /* overridden in the bitmap header of certain glyphs. */ + /* compute default advance, i.e., scaled advance; this can be */ + /* overridden in the bitmap header of certain glyphs */ advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8, character->advance, - phys->metrics_resolution ); + (FT_Long)phys->metrics_resolution ); if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) || FT_FRAME_ENTER( gps_size ) ) @@ -630,13 +682,66 @@ &xpos, &ypos, &xsize, &ysize, &advance, &format ); + if ( error ) + goto Exit1; /* - * XXX: on 16bit system, we return an error for huge bitmap - * which causes a size truncation, because truncated - * size properties makes bitmap glyph broken. + * Before allocating the target bitmap, we check whether the given + * bitmap dimensions are valid, depending on the image format. + * + * Format 0: We have a stream of pixels (with 8 pixels per byte). + * + * (xsize * ysize + 7) / 8 <= gps_size + * + * Format 1: Run-length encoding; the high nibble holds the number of + * white bits, the low nibble the number of black bits. In + * other words, a single byte can represent at most 15 + * pixels. + * + * xsize * ysize <= 15 * gps_size + * + * Format 2: Run-length encoding; the high byte holds the number of + * white bits, the low byte the number of black bits. In + * other words, two bytes can represent at most 255 pixels. + * + * xsize * ysize <= 255 * (gps_size + 1) / 2 */ - if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX ) + switch ( format ) + { + case 0: + if ( ( (FT_ULong)xsize * ysize + 7 ) / 8 > gps_size ) + error = FT_THROW( Invalid_Table ); + break; + case 1: + if ( (FT_ULong)xsize * ysize > 15 * gps_size ) + error = FT_THROW( Invalid_Table ); + break; + case 2: + if ( (FT_ULong)xsize * ysize > 255 * ( ( gps_size + 1 ) / 2 ) ) + error = FT_THROW( Invalid_Table ); + break; + default: + FT_ERROR(( "pfr_slot_load_bitmap: invalid image type\n" )); + error = FT_THROW( Invalid_Table ); + } + + if ( error ) + { + if ( FT_ERR_EQ( error, Invalid_Table ) ) + FT_ERROR(( "pfr_slot_load_bitmap: invalid bitmap dimensions\n" )); + goto Exit1; + } + + /* + * XXX: on 16bit systems we return an error for huge bitmaps + * that cause size truncation, because truncated + * size properties make bitmap glyphs broken. + */ + if ( xpos > FT_INT_MAX || + xpos < FT_INT_MIN || + ysize > FT_INT_MAX || + ypos > FT_INT_MAX - (FT_Long)ysize || + ypos + (FT_Long)ysize < FT_INT_MIN ) { FT_TRACE1(( "pfr_slot_load_bitmap:" )); FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n", @@ -651,16 +756,16 @@ /* Set up glyph bitmap and metrics */ /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */ - glyph->root.bitmap.width = (FT_Int)xsize; - glyph->root.bitmap.rows = (FT_Int)ysize; + glyph->root.bitmap.width = xsize; + glyph->root.bitmap.rows = ysize; glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3; glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO; /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */ glyph->root.metrics.width = (FT_Pos)xsize << 6; glyph->root.metrics.height = (FT_Pos)ysize << 6; - glyph->root.metrics.horiBearingX = xpos << 6; - glyph->root.metrics.horiBearingY = ypos << 6; + glyph->root.metrics.horiBearingX = xpos * 64; + glyph->root.metrics.horiBearingY = ypos * 64; glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; glyph->root.metrics.vertBearingY = 0; @@ -668,26 +773,26 @@ /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */ glyph->root.bitmap_left = (FT_Int)xpos; - glyph->root.bitmap_top = (FT_Int)(ypos + ysize); + glyph->root.bitmap_top = (FT_Int)( ypos + (FT_Long)ysize ); /* Allocate and read bitmap data */ { - FT_ULong len = glyph->root.bitmap.pitch * ysize; + FT_ULong len = (FT_ULong)glyph->root.bitmap.pitch * ysize; error = ft_glyphslot_alloc_bitmap( &glyph->root, len ); if ( !error ) - { error = pfr_load_bitmap_bits( p, stream->limit, format, - FT_BOOL(face->header.color_flags & 2), + FT_BOOL( face->header.color_flags & + PFR_FLAG_INVERT_BITMAP ), &glyph->root.bitmap ); - } } } + Exit1: FT_FRAME_EXIT(); } @@ -695,4 +800,5 @@ return error; } + /* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrsbit.h b/drivers/freetype/src/pfr/pfrsbit.h index 015e9e6dad..94ead28ca7 100644 --- a/drivers/freetype/freetype/src/pfr/pfrsbit.h +++ b/drivers/freetype/src/pfr/pfrsbit.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR bitmap loader (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRSBIT_H__ -#define __PFRSBIT_H__ +#ifndef PFRSBIT_H_ +#define PFRSBIT_H_ #include "pfrobjs.h" @@ -30,7 +30,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFR_SBIT_H__ */ +#endif /* PFRSBIT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pfr/pfrtypes.h b/drivers/freetype/src/pfr/pfrtypes.h index 918310814c..bd6c2cd30c 100644 --- a/drivers/freetype/freetype/src/pfr/pfrtypes.h +++ b/drivers/freetype/src/pfr/pfrtypes.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR data structures (specification only). */ /* */ -/* Copyright 2002, 2003, 2005, 2007 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRTYPES_H__ -#define __PFRTYPES_H__ +#ifndef PFRTYPES_H_ +#define PFRTYPES_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -69,12 +69,8 @@ FT_BEGIN_HEADER /* used in `color_flags' field of the PFR_Header */ - typedef enum PFR_HeaderFlags_ - { - PFR_FLAG_BLACK_PIXEL = 1, - PFR_FLAG_INVERT_BITMAP = 2 - - } PFR_HeaderFlags; +#define PFR_FLAG_BLACK_PIXEL 0x01U +#define PFR_FLAG_INVERT_BITMAP 0x02U /************************************************************************/ @@ -96,36 +92,27 @@ FT_BEGIN_HEADER } PFR_LogFontRec, *PFR_LogFont; - typedef enum PFR_LogFlags_ - { - PFR_LOG_EXTRA_ITEMS = 0x40, - PFR_LOG_2BYTE_BOLD = 0x20, - PFR_LOG_BOLD = 0x10, - PFR_LOG_2BYTE_STROKE = 8, - PFR_LOG_STROKE = 4, - PFR_LINE_JOIN_MASK = 3 +#define PFR_LINE_JOIN_MITER 0x00U +#define PFR_LINE_JOIN_ROUND 0x01U +#define PFR_LINE_JOIN_BEVEL 0x02U +#define PFR_LINE_JOIN_MASK ( PFR_LINE_JOIN_ROUND | PFR_LINE_JOIN_BEVEL ) - } PFR_LogFlags; - - - typedef enum PFR_LineJoinFlags_ - { - PFR_LINE_JOIN_MITER = 0, - PFR_LINE_JOIN_ROUND = 1, - PFR_LINE_JOIN_BEVEL = 2 - - } PFR_LineJoinFlags; +#define PFR_LOG_STROKE 0x04U +#define PFR_LOG_2BYTE_STROKE 0x08U +#define PFR_LOG_BOLD 0x10U +#define PFR_LOG_2BYTE_BOLD 0x20U +#define PFR_LOG_EXTRA_ITEMS 0x40U /************************************************************************/ - typedef enum PFR_BitmapFlags_ - { - PFR_BITMAP_3BYTE_OFFSET = 4, - PFR_BITMAP_2BYTE_SIZE = 2, - PFR_BITMAP_2BYTE_CHARCODE = 1 +#define PFR_BITMAP_2BYTE_CHARCODE 0x01U +#define PFR_BITMAP_2BYTE_SIZE 0x02U +#define PFR_BITMAP_3BYTE_OFFSET 0x04U - } PFR_BitmapFlags; + /*not part of the specification but used for implementation */ +#define PFR_BITMAP_CHARCODES_VALIDATED 0x40U +#define PFR_BITMAP_VALID_CHARCODES 0x80U typedef struct PFR_BitmapCharRec_ @@ -137,15 +124,11 @@ FT_BEGIN_HEADER } PFR_BitmapCharRec, *PFR_BitmapChar; - typedef enum PFR_StrikeFlags_ - { - PFR_STRIKE_2BYTE_COUNT = 0x10, - PFR_STRIKE_3BYTE_OFFSET = 0x08, - PFR_STRIKE_3BYTE_SIZE = 0x04, - PFR_STRIKE_2BYTE_YPPM = 0x02, - PFR_STRIKE_2BYTE_XPPM = 0x01 - - } PFR_StrikeFlags; +#define PFR_STRIKE_2BYTE_XPPM 0x01U +#define PFR_STRIKE_2BYTE_YPPM 0x02U +#define PFR_STRIKE_3BYTE_SIZE 0x04U +#define PFR_STRIKE_3BYTE_OFFSET 0x08U +#define PFR_STRIKE_2BYTE_COUNT 0x10U typedef struct PFR_StrikeRec_ @@ -229,7 +212,7 @@ FT_BEGIN_HEADER FT_UInt metrics_resolution; FT_BBox bbox; FT_UInt flags; - FT_UInt standard_advance; + FT_Int standard_advance; FT_Int ascent; /* optional, bbox.yMax if not present */ FT_Int descent; /* optional, bbox.yMin if not present */ @@ -260,44 +243,35 @@ FT_BEGIN_HEADER PFR_KernItem* kern_items_tail; /* not part of the spec, but used during load */ - FT_Long bct_offset; + FT_ULong bct_offset; FT_Byte* cursor; } PFR_PhyFontRec, *PFR_PhyFont; - typedef enum PFR_PhyFlags_ - { - PFR_PHY_EXTRA_ITEMS = 0x80, - PFR_PHY_3BYTE_GPS_OFFSET = 0x20, - PFR_PHY_2BYTE_GPS_SIZE = 0x10, - PFR_PHY_ASCII_CODE = 0x08, - PFR_PHY_PROPORTIONAL = 0x04, - PFR_PHY_2BYTE_CHARCODE = 0x02, - PFR_PHY_VERTICAL = 0x01 - - } PFR_PhyFlags; +#define PFR_PHY_VERTICAL 0x01U +#define PFR_PHY_2BYTE_CHARCODE 0x02U +#define PFR_PHY_PROPORTIONAL 0x04U +#define PFR_PHY_ASCII_CODE 0x08U +#define PFR_PHY_2BYTE_GPS_SIZE 0x10U +#define PFR_PHY_3BYTE_GPS_OFFSET 0x20U +#define PFR_PHY_EXTRA_ITEMS 0x80U - typedef enum PFR_KernFlags_ - { - PFR_KERN_2BYTE_CHAR = 0x01, - PFR_KERN_2BYTE_ADJ = 0x02 - - } PFR_KernFlags; +#define PFR_KERN_2BYTE_CHAR 0x01U +#define PFR_KERN_2BYTE_ADJ 0x02U /************************************************************************/ - typedef enum PFR_GlyphFlags_ - { - PFR_GLYPH_IS_COMPOUND = 0x80, - PFR_GLYPH_EXTRA_ITEMS = 0x08, - PFR_GLYPH_1BYTE_XYCOUNT = 0x04, - PFR_GLYPH_XCOUNT = 0x02, - PFR_GLYPH_YCOUNT = 0x01 +#define PFR_GLYPH_YCOUNT 0x01U +#define PFR_GLYPH_XCOUNT 0x02U +#define PFR_GLYPH_1BYTE_XYCOUNT 0x04U + +#define PFR_GLYPH_SINGLE_EXTRA_ITEMS 0x08U +#define PFR_GLYPH_COMPOUND_EXTRA_ITEMS 0x40U - } PFR_GlyphFlags; +#define PFR_GLYPH_IS_COMPOUND 0x80U /* controlled coordinate */ @@ -321,14 +295,10 @@ FT_BEGIN_HEADER } PFR_SubGlyphRec, *PFR_SubGlyph; - typedef enum PFR_SubgGlyphFlags_ - { - PFR_SUBGLYPH_3BYTE_OFFSET = 0x80, - PFR_SUBGLYPH_2BYTE_SIZE = 0x40, - PFR_SUBGLYPH_YSCALE = 0x20, - PFR_SUBGLYPH_XSCALE = 0x10 - - } PFR_SubGlyphFlags; +#define PFR_SUBGLYPH_XSCALE 0x10U +#define PFR_SUBGLYPH_YSCALE 0x20U +#define PFR_SUBGLYPH_2BYTE_SIZE 0x40U +#define PFR_SUBGLYPH_3BYTE_OFFSET 0x80U typedef struct PFR_GlyphRec_ @@ -356,7 +326,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRTYPES_H__ */ +#endif /* PFRTYPES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pfr/rules.mk b/drivers/freetype/src/pfr/rules.mk index 60b96c7415..39bb9e941a 100644 --- a/drivers/freetype/freetype/src/pfr/rules.mk +++ b/drivers/freetype/src/pfr/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002, 2003 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ PFR_DIR := $(SRC_DIR)/pfr # compilation flags for the driver # -PFR_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PFR_DIR)) +PFR_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(PFR_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # pfr driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/psaux/Jamfile b/drivers/freetype/src/psaux/Jamfile index faeded9044..9270eec687 100644 --- a/drivers/freetype/freetype/src/psaux/Jamfile +++ b/drivers/freetype/src/psaux/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/psaux Jamfile # -# Copyright 2001, 2002 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,8 +16,12 @@ SubDir FT2_TOP $(FT2_SRC_DIR) psaux ; if $(FT2_MULTI) { - _sources = psauxmod psobjs t1decode t1cmap - psconv afmparse + _sources = afmparse + psauxmod + psconv + psobjs + t1cmap + t1decode ; } else diff --git a/drivers/freetype/freetype/src/psaux/afmparse.c b/drivers/freetype/src/psaux/afmparse.c index 6a40e110dc..9fb0ac0e2b 100644 --- a/drivers/freetype/freetype/src/psaux/afmparse.c +++ b/drivers/freetype/src/psaux/afmparse.c @@ -4,7 +4,7 @@ /* */ /* AFM parser (body). */ /* */ -/* Copyright 2006-2010, 2012, 2013 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -75,8 +75,8 @@ #define AFM_STREAM_KEY_BEGIN( stream ) \ (char*)( (stream)->cursor - 1 ) -#define AFM_STREAM_KEY_LEN( stream, key ) \ - ( (char*)(stream)->cursor - key - 1 ) +#define AFM_STREAM_KEY_LEN( stream, key ) \ + (FT_Offset)( (char*)(stream)->cursor - key - 1 ) #define AFM_STATUS_EOC( stream ) \ ( (stream)->status >= AFM_STREAM_STATUS_EOC ) @@ -369,11 +369,11 @@ FT_LOCAL_DEF( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_UInt n ) + FT_Int n ) { AFM_Stream stream = parser->stream; char* str; - FT_UInt i; + FT_Int i; if ( n > AFM_MAX_ARGUMENTS ) @@ -446,7 +446,7 @@ FT_Offset* len ) { AFM_Stream stream = parser->stream; - char* key = 0; /* make stupid compiler happy */ + char* key = NULL; /* make stupid compiler happy */ if ( line ) @@ -562,7 +562,7 @@ } - FT_LOCAL_DEF( FT_Error ) + static FT_Error afm_parser_read_int( AFM_Parser parser, FT_Int* aint ) { @@ -590,11 +590,17 @@ char* key; FT_Offset len; int n = -1; + FT_Int tmp; - if ( afm_parser_read_int( parser, &fi->NumTrackKern ) ) + if ( afm_parser_read_int( parser, &tmp ) ) goto Fail; + if ( tmp < 0 ) + goto Fail; + + fi->NumTrackKern = (FT_UInt)tmp; + if ( fi->NumTrackKern ) { FT_Memory memory = parser->memory; @@ -615,7 +621,7 @@ case AFM_TOKEN_TRACKKERN: n++; - if ( n >= fi->NumTrackKern ) + if ( n >= (int)fi->NumTrackKern ) goto Fail; tk = fi->TrackKerns + n; @@ -639,7 +645,7 @@ case AFM_TOKEN_ENDTRACKKERN: case AFM_TOKEN_ENDKERNDATA: case AFM_TOKEN_ENDFONTMETRICS: - fi->NumTrackKern = n + 1; + fi->NumTrackKern = (FT_UInt)( n + 1 ); return FT_Err_Ok; case AFM_TOKEN_UNKNOWN: @@ -688,11 +694,17 @@ char* key; FT_Offset len; int n = -1; + FT_Int tmp; + + if ( afm_parser_read_int( parser, &tmp ) ) + goto Fail; - if ( afm_parser_read_int( parser, &fi->NumKernPair ) ) + if ( tmp < 0 ) goto Fail; + fi->NumKernPair = (FT_UInt)tmp; + if ( fi->NumKernPair ) { FT_Memory memory = parser->memory; @@ -720,7 +732,7 @@ n++; - if ( n >= fi->NumKernPair ) + if ( n >= (int)fi->NumKernPair ) goto Fail; kp = fi->KernPairs + n; @@ -733,8 +745,9 @@ if ( r < 3 ) goto Fail; - kp->index1 = shared_vals[0].u.i; - kp->index2 = shared_vals[1].u.i; + /* index values can't be negative */ + kp->index1 = shared_vals[0].u.u; + kp->index2 = shared_vals[1].u.u; if ( token == AFM_TOKEN_KPY ) { kp->x = 0; @@ -752,7 +765,7 @@ case AFM_TOKEN_ENDKERNPAIRS: case AFM_TOKEN_ENDKERNDATA: case AFM_TOKEN_ENDFONTMETRICS: - fi->NumKernPair = n + 1; + fi->NumKernPair = (FT_UInt)( n + 1 ); ft_qsort( fi->KernPairs, fi->NumKernPair, sizeof ( AFM_KernPairRec ), afm_compare_kern_pairs ); @@ -815,7 +828,7 @@ static FT_Error afm_parser_skip_section( AFM_Parser parser, - FT_UInt n, + FT_Int n, AFM_Token end_section ) { char* key; diff --git a/drivers/freetype/freetype/src/psaux/afmparse.h b/drivers/freetype/src/psaux/afmparse.h index 35d96046c5..6d8b193ffc 100644 --- a/drivers/freetype/freetype/src/psaux/afmparse.h +++ b/drivers/freetype/src/psaux/afmparse.h @@ -4,7 +4,7 @@ /* */ /* AFM parser (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFMPARSE_H__ -#define __AFMPARSE_H__ +#ifndef AFMPARSE_H_ +#define AFMPARSE_H_ #include <ft2build.h> @@ -61,6 +61,7 @@ FT_BEGIN_HEADER char* s; FT_Fixed f; FT_Int i; + FT_UInt u; FT_Bool b; } u; @@ -72,7 +73,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_UInt n ); + FT_Int n ); /* read the next key from the next line or column */ FT_LOCAL( char* ) @@ -82,7 +83,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFMPARSE_H__ */ +#endif /* AFMPARSE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/psaux/module.mk b/drivers/freetype/src/psaux/module.mk index 42bf6f5199..630c4f39dd 100644 --- a/drivers/freetype/freetype/src/psaux/module.mk +++ b/drivers/freetype/src/psaux/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/psaux/psaux.c b/drivers/freetype/src/psaux/psaux.c index a4b9c5c6e4..33b462ef15 100644 --- a/drivers/freetype/freetype/src/psaux/psaux.c +++ b/drivers/freetype/src/psaux/psaux.c @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript driver component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/psaux/psauxerr.h b/drivers/freetype/src/psaux/psauxerr.h index d52375f8cb..9739157fc4 100644 --- a/drivers/freetype/freetype/src/psaux/psauxerr.h +++ b/drivers/freetype/src/psaux/psauxerr.h @@ -4,7 +4,7 @@ /* */ /* PS auxiliary module error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __PSAUXERR_H__ -#define __PSAUXERR_H__ +#ifndef PSAUXERR_H_ +#define PSAUXERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSaux_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __PSAUXERR_H__ */ +#endif /* PSAUXERR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/psaux/psauxmod.c b/drivers/freetype/src/psaux/psauxmod.c index 4b1249d49b..80805e6951 100644 --- a/drivers/freetype/freetype/src/psaux/psauxmod.c +++ b/drivers/freetype/src/psaux/psauxmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript module implementation (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2006 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/psaux/psauxmod.h b/drivers/freetype/src/psaux/psauxmod.h index 1217236924..b1dbb06904 100644 --- a/drivers/freetype/freetype/src/psaux/psauxmod.h +++ b/drivers/freetype/src/psaux/psauxmod.h @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript module implementation (specification). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSAUXMOD_H__ -#define __PSAUXMOD_H__ +#ifndef PSAUXMOD_H_ +#define PSAUXMOD_H_ #include <ft2build.h> @@ -36,7 +36,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSAUXMOD_H__ */ +#endif /* PSAUXMOD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/psaux/psconv.c b/drivers/freetype/src/psaux/psconv.c index d0d8861c22..fdaca7fb5d 100644 --- a/drivers/freetype/freetype/src/psaux/psconv.c +++ b/drivers/freetype/src/psaux/psconv.c @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (body). */ /* */ -/* Copyright 2006, 2008, 2009, 2012-2013 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -124,7 +124,7 @@ if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) break; - c = ft_char_table[*p & 0x7f]; + c = ft_char_table[*p & 0x7F]; if ( c < 0 || c >= base ) break; @@ -245,12 +245,13 @@ if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) break; - c = ft_char_table[*p & 0x7f]; + c = ft_char_table[*p & 0x7F]; if ( c < 0 || c >= 10 ) break; - if ( decimal < 0xCCCCCCCL ) + /* only add digit if we don't overflow */ + if ( divider < 0xCCCCCCCL && decimal < 0xCCCCCCCL ) { decimal = decimal * 10 + c; @@ -488,8 +489,8 @@ if ( c OP 0x80 ) break; - c = ft_char_table[c & 0x7F]; - if ( (unsigned)c >= 16 ) + c = (FT_UInt)ft_char_table[c & 0x7F]; + if ( c >= 16 ) break; pad = ( pad << 4 ) | c; @@ -520,7 +521,7 @@ if ( *p OP 0x80 ) break; - c = ft_char_table[*p & 0x7f]; + c = ft_char_table[*p & 0x7F]; if ( (unsigned)c >= 16 ) break; diff --git a/drivers/freetype/freetype/src/psaux/psconv.h b/drivers/freetype/src/psaux/psconv.h index d91c762210..062de36413 100644 --- a/drivers/freetype/freetype/src/psaux/psconv.h +++ b/drivers/freetype/src/psaux/psconv.h @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (specification). */ /* */ -/* Copyright 2006, 2012 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSCONV_H__ -#define __PSCONV_H__ +#ifndef PSCONV_H_ +#define PSCONV_H_ #include <ft2build.h> @@ -65,7 +65,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSCONV_H__ */ +#endif /* PSCONV_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/psaux/psobjs.c b/drivers/freetype/src/psaux/psobjs.c index dd976d3a96..f208b5fc63 100644 --- a/drivers/freetype/freetype/src/psaux/psobjs.c +++ b/drivers/freetype/src/psaux/psobjs.c @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -81,7 +81,7 @@ table->max_elems = count; table->init = 0xDEADBEEFUL; table->num_elems = 0; - table->block = 0; + table->block = NULL; table->capacity = 0; table->cursor = 0; @@ -165,10 +165,10 @@ /* reallocation fails. */ /* */ FT_LOCAL_DEF( FT_Error ) - ps_table_add( PS_Table table, - FT_Int idx, - void* object, - FT_PtrDist length ) + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_UInt length ) { if ( idx < 0 || idx >= table->max_elems ) { @@ -176,12 +176,6 @@ return FT_THROW( Invalid_Argument ); } - if ( length < 0 ) - { - FT_ERROR(( "ps_table_add: invalid length\n" )); - return FT_THROW( Invalid_Argument ); - } - /* grow the base block if needed */ if ( table->cursor + length > table->capacity ) { @@ -600,6 +594,9 @@ error = FT_THROW( Invalid_File_Format ); } + if ( cur > limit ) + cur = limit; + parser->error = error; parser->cursor = cur; } @@ -625,8 +622,8 @@ token->type = T1_TOKEN_TYPE_NONE; - token->start = 0; - token->limit = 0; + token->start = NULL; + token->limit = NULL; /* first of all, skip leading whitespace */ ps_parser_skip_spaces( parser ); @@ -707,7 +704,7 @@ if ( !token->limit ) { - token->start = 0; + token->start = NULL; token->type = T1_TOKEN_TYPE_NONE; } @@ -847,6 +844,8 @@ /* first character must be a delimiter or a part of a number */ /* NB: `values' can be NULL if we just want to skip the */ /* array; in this case we ignore `max_values' */ + /* */ + /* return number of successfully parsed values */ static FT_Int ps_tofixedarray( FT_Byte* *acur, @@ -930,7 +929,7 @@ FT_Memory memory ) { FT_Byte* cur = *cursor; - FT_PtrDist len = 0; + FT_UInt len = 0; FT_Int count; FT_String* result; FT_Error error; @@ -970,7 +969,7 @@ } } - len = cur - *cursor; + len = (FT_UInt)( cur - *cursor ); if ( cur >= limit || FT_ALLOC( result, len + 1 ) ) return 0; @@ -1088,9 +1087,9 @@ for ( ; count > 0; count--, idx++ ) { - FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; + FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; FT_Long val; - FT_String* string; + FT_String* string = NULL; skip_spaces( &cur, limit ); @@ -1200,7 +1199,7 @@ result = ps_tofixedarray( &cur, limit, 4, temp, 0 ); - if ( result < 0 ) + if ( result < 4 ) { FT_ERROR(( "ps_parser_load_field:" " expected four integers in bounding box\n" )); @@ -1218,7 +1217,7 @@ case T1_FIELD_TYPE_MM_BBOX: { FT_Memory memory = parser->memory; - FT_Fixed* temp; + FT_Fixed* temp = NULL; FT_Int result; FT_UInt i; @@ -1228,20 +1227,22 @@ for ( i = 0; i < 4; i++ ) { - result = ps_tofixedarray( &cur, limit, max_objects, + result = ps_tofixedarray( &cur, limit, (FT_Int)max_objects, temp + i * max_objects, 0 ); - if ( result < 0 ) + if ( result < 0 || (FT_UInt)result < max_objects ) { FT_ERROR(( "ps_parser_load_field:" - " expected %d integers in the %s subarray\n" + " expected %d integer%s in the %s subarray\n" " " " of /FontBBox in the /Blend dictionary\n", - max_objects, + max_objects, max_objects > 1 ? "s" : "", i == 0 ? "first" : ( i == 1 ? "second" : ( i == 2 ? "third" : "fourth" ) ) )); error = FT_THROW( Invalid_File_Format ); + + FT_FREE( temp ); goto Exit; } @@ -1319,7 +1320,7 @@ goto Exit; } if ( (FT_UInt)num_elements > field->array_max ) - num_elements = field->array_max; + num_elements = (FT_Int)field->array_max; old_cursor = parser->cursor; old_limit = parser->limit; @@ -1336,7 +1337,15 @@ { parser->cursor = token->start; parser->limit = token->limit; - ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 ); + + error = ps_parser_load_field( parser, + &fieldrec, + objects, + max_objects, + 0 ); + if ( error ) + break; + fieldrec.offset += fieldrec.size; } @@ -1369,7 +1378,7 @@ ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, FT_Offset max_bytes, - FT_Long* pnum_bytes, + FT_ULong* pnum_bytes, FT_Bool delimiters ) { FT_Error error = FT_Err_Ok; @@ -1543,7 +1552,7 @@ FT_GlyphLoader_Rewind( loader ); builder->hints_globals = size->internal; - builder->hints_funcs = 0; + builder->hints_funcs = NULL; if ( hinting ) builder->hints_funcs = glyph->internal->glyph_hints; diff --git a/drivers/freetype/freetype/src/psaux/psobjs.h b/drivers/freetype/src/psaux/psobjs.h index e380c60dab..4c7178e79f 100644 --- a/drivers/freetype/freetype/src/psaux/psobjs.h +++ b/drivers/freetype/src/psaux/psobjs.h @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSOBJS_H__ -#define __PSOBJS_H__ +#ifndef PSOBJS_H_ +#define PSOBJS_H_ #include <ft2build.h> @@ -52,10 +52,10 @@ FT_BEGIN_HEADER FT_Memory memory ); FT_LOCAL( FT_Error ) - ps_table_add( PS_Table table, - FT_Int idx, - void* object, - FT_PtrDist length ); + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_UInt length ); FT_LOCAL( void ) ps_table_done( PS_Table table ); @@ -112,7 +112,7 @@ FT_BEGIN_HEADER ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, FT_Offset max_bytes, - FT_Long* pnum_bytes, + FT_ULong* pnum_bytes, FT_Bool delimiters ); @@ -206,7 +206,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSOBJS_H__ */ +#endif /* PSOBJS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/psaux/rules.mk b/drivers/freetype/src/psaux/rules.mk index 7a1be37b69..19787b5f82 100644 --- a/drivers/freetype/freetype/src/psaux/rules.mk +++ b/drivers/freetype/src/psaux/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002, 2003, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ PSAUX_DIR := $(SRC_DIR)/psaux # compilation flags for the driver # -PSAUX_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSAUX_DIR)) +PSAUX_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(PSAUX_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # PSAUX driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/psaux/t1cmap.c b/drivers/freetype/src/psaux/t1cmap.c index 9e5bd34ffe..43abb98615 100644 --- a/drivers/freetype/freetype/src/psaux/t1cmap.c +++ b/drivers/freetype/src/psaux/t1cmap.c @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (body). */ /* */ -/* Copyright 2002, 2003, 2006, 2007, 2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,7 +39,7 @@ FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; - cmap->num_glyphs = face->type1.num_glyphs; + cmap->num_glyphs = (FT_UInt)face->type1.num_glyphs; cmap->glyph_names = (const char* const*)face->type1.glyph_names; cmap->sid_to_string = psnames->adobe_std_strings; cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding @@ -120,8 +120,12 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_standard_init( T1_CMapStd cmap ) + t1_cmap_standard_init( T1_CMapStd cmap, + FT_Pointer pointer ) { + FT_UNUSED( pointer ); + + t1_cmap_std_init( cmap, 0 ); return 0; } @@ -142,8 +146,12 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_expert_init( T1_CMapStd cmap ) + t1_cmap_expert_init( T1_CMapStd cmap, + FT_Pointer pointer ) { + FT_UNUSED( pointer ); + + t1_cmap_std_init( cmap, 1 ); return 0; } @@ -172,14 +180,17 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_custom_init( T1_CMapCustom cmap ) + t1_cmap_custom_init( T1_CMapCustom cmap, + FT_Pointer pointer ) { T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); T1_Encoding encoding = &face->type1.encoding; + FT_UNUSED( pointer ); + - cmap->first = encoding->code_first; - cmap->count = (FT_UInt)( encoding->code_last - cmap->first ); + cmap->first = (FT_UInt)encoding->code_first; + cmap->count = (FT_UInt)encoding->code_last - cmap->first; cmap->indices = encoding->char_index; FT_ASSERT( cmap->indices != NULL ); @@ -272,16 +283,19 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_unicode_init( PS_Unicodes unicodes ) + t1_cmap_unicode_init( PS_Unicodes unicodes, + FT_Pointer pointer ) { T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); FT_Memory memory = FT_FACE_MEMORY( face ); FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + FT_UNUSED( pointer ); + return psnames->unicodes_init( memory, unicodes, - face->type1.num_glyphs, + (FT_UInt)face->type1.num_glyphs, (PS_GetGlyphNameFunc)&psaux_get_glyph_name, (PS_FreeGlyphNameFunc)NULL, (FT_Pointer)face ); diff --git a/drivers/freetype/freetype/src/psaux/t1cmap.h b/drivers/freetype/src/psaux/t1cmap.h index 7ae65d2fa1..5e1277dc63 100644 --- a/drivers/freetype/freetype/src/psaux/t1cmap.h +++ b/drivers/freetype/src/psaux/t1cmap.h @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (specification). */ /* */ -/* Copyright 2002, 2003, 2006 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1CMAP_H__ -#define __T1CMAP_H__ +#ifndef T1CMAP_H_ +#define T1CMAP_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -99,7 +99,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1CMAP_H__ */ +#endif /* T1CMAP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/psaux/t1decode.c b/drivers/freetype/src/psaux/t1decode.c index 6ce370bfaa..98f6ce1c87 100644 --- a/drivers/freetype/freetype/src/psaux/t1decode.c +++ b/drivers/freetype/src/psaux/t1decode.c @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,7 @@ #include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_INTERNAL_HASH_H #include FT_OUTLINE_H #include "t1decode.h" @@ -150,7 +151,7 @@ if ( name && name[0] == glyph_name[0] && ft_strcmp( name, glyph_name ) == 0 ) - return n; + return (FT_Int)n; } return -1; @@ -298,7 +299,7 @@ /* the seac operator must not be nested */ decoder->seac = TRUE; - error = t1_decoder_parse_glyph( decoder, bchar_index ); + error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index ); decoder->seac = FALSE; if ( error ) goto Exit; @@ -320,7 +321,7 @@ /* the seac operator must not be nested */ decoder->seac = TRUE; - error = t1_decoder_parse_glyph( decoder, achar_index ); + error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index ); decoder->seac = FALSE; if ( error ) goto Exit; @@ -381,10 +382,10 @@ /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ - (FT_PtrDist)(char*)&decoder ^ - (FT_PtrDist)(char*)&charstring_base ) & - FT_ULONG_MAX ) ; + seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed ^ + (FT_Offset)(char*)&decoder ^ + (FT_Offset)(char*)&charstring_base ) & + FT_ULONG_MAX ); seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; if ( seed == 0 ) seed = 0x7384; @@ -512,7 +513,7 @@ break; case 12: - if ( ip > limit ) + if ( ip >= limit ) { FT_ERROR(( "t1_decoder_parse_charstrings:" " invalid escape (12+EOF)\n" )); @@ -669,7 +670,7 @@ if ( large_int ) FT_TRACE4(( " %ld", value )); else - FT_TRACE4(( " %ld", Fix2Int( value ) )); + FT_TRACE4(( " %ld", value / 65536 )); #endif *top++ = value; @@ -796,7 +797,8 @@ known_othersubr_result_cnt = 1; if ( hinter ) - hinter->reset( hinter->hints, builder->current->n_points ); + hinter->reset( hinter->hints, + (FT_UInt)builder->current->n_points ); break; case 12: @@ -861,7 +863,7 @@ *values++ = tmp; } - known_othersubr_result_cnt = num_points; + known_othersubr_result_cnt = (FT_Int)num_points; break; } @@ -879,8 +881,8 @@ idx = Fix2Int( top[0] ); - if ( idx < 0 || - idx + blend->num_designs > decoder->len_buildchar ) + if ( idx < 0 || + (FT_UInt)idx + blend->num_designs > decoder->len_buildchar ) goto Unexpected_OtherSubr; ft_memcpy( &decoder->buildchar[idx], @@ -1094,14 +1096,17 @@ /* close hints recording session */ if ( hinter ) { - if ( hinter->close( hinter->hints, builder->current->n_points ) ) + if ( hinter->close( hinter->hints, + (FT_UInt)builder->current->n_points ) ) goto Syntax_Error; /* apply hints to the loaded glyph outline now */ - hinter->apply( hinter->hints, - builder->current, - (PSH_Globals)builder->hints_globals, - decoder->hint_mode ); + error = hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + if ( error ) + goto Fail; } /* add current outline to the glyph slot */ @@ -1344,7 +1349,20 @@ FT_TRACE4(( " callsubr" )); idx = Fix2Int( top[0] ); - if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) + + if ( decoder->subrs_hash ) + { + size_t* val = ft_hash_num_lookup( idx, + decoder->subrs_hash ); + + + if ( val ) + idx = *val; + else + idx = -1; + } + + if ( idx < 0 || idx >= decoder->num_subrs ) { FT_ERROR(( "t1_decoder_parse_charstrings:" " invalid subrs index\n" )); @@ -1577,7 +1595,7 @@ /* retrieve PSNames interface from list of current modules */ { - FT_Service_PsCMaps psnames = 0; + FT_Service_PsCMaps psnames; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); diff --git a/drivers/freetype/freetype/src/psaux/t1decode.h b/drivers/freetype/src/psaux/t1decode.h index 00728db501..0f5adfa156 100644 --- a/drivers/freetype/freetype/src/psaux/t1decode.h +++ b/drivers/freetype/src/psaux/t1decode.h @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (specification). */ /* */ -/* Copyright 2000-2001, 2002, 2003 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1DECODE_H__ -#define __T1DECODE_H__ +#ifndef T1DECODE_H_ +#define T1DECODE_H_ #include <ft2build.h> @@ -58,7 +58,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1DECODE_H__ */ +#endif /* T1DECODE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pshinter/Jamfile b/drivers/freetype/src/pshinter/Jamfile index 779f1b0b82..fcb225811e 100644 --- a/drivers/freetype/freetype/src/pshinter/Jamfile +++ b/drivers/freetype/src/pshinter/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/pshinter Jamfile # -# Copyright 2001, 2003 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,12 @@ SubDir FT2_TOP $(FT2_SRC_DIR) pshinter ; if $(FT2_MULTI) { - _sources = pshrec pshglob pshalgo pshmod pshpic ; + _sources = pshalgo + pshglob + pshmod + pshpic + pshrec + ; } else { diff --git a/drivers/freetype/freetype/src/pshinter/module.mk b/drivers/freetype/src/pshinter/module.mk index ed24eb7fa8..63110c46a6 100644 --- a/drivers/freetype/freetype/src/pshinter/module.mk +++ b/drivers/freetype/src/pshinter/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2001, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/pshinter/pshalgo.c b/drivers/freetype/src/pshinter/pshalgo.c index 343472ddb3..8f131be759 100644 --- a/drivers/freetype/freetype/src/pshinter/pshalgo.c +++ b/drivers/freetype/src/pshinter/pshalgo.c @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001-2010, 2012, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -30,16 +30,14 @@ #ifdef DEBUG_HINTER - PSH_Hint_Table ps_debug_hint_table = 0; - PSH_HintFunc ps_debug_hint_func = 0; - PSH_Glyph ps_debug_glyph = 0; + PSH_Hint_Table ps_debug_hint_table = NULL; + PSH_HintFunc ps_debug_hint_func = NULL; + PSH_Glyph ps_debug_glyph = NULL; #endif #define COMPUTE_INFLEXS /* compute inflection points to optimize `S' */ /* and similar glyphs */ -#define STRONGER /* slightly increase the contrast of smooth */ - /* hinting */ /*************************************************************************/ @@ -67,13 +65,13 @@ { FT_FREE( table->zones ); table->num_zones = 0; - table->zone = 0; + table->zone = NULL; FT_FREE( table->sort ); FT_FREE( table->hints ); table->num_hints = 0; table->max_hints = 0; - table->sort_global = 0; + table->sort_global = NULL; } @@ -121,7 +119,7 @@ PSH_Hint hint2; - hint->parent = 0; + hint->parent = NULL; for ( ; count > 0; count--, sorted++ ) { hint2 = sorted[0]; @@ -194,7 +192,7 @@ table->sort_global = table->sort + count; table->num_hints = 0; table->num_zones = 0; - table->zone = 0; + table->zone = NULL; /* initialize the `table->hints' array */ { @@ -781,7 +779,7 @@ * It turns out though that minimizing the total number of lit * pixels is also important, so position C), with one edge * aligned with a pixel boundary is actually preferable - * to A). There are also more possibile positions for C) than + * to A). There are also more possible positions for C) than * for A) or B), so it involves less distortion of the overall * character shape. */ @@ -804,7 +802,7 @@ } /* We choose between B) and C) above based on the amount - * of fractinal stem width; for small amounts, choose + * of fractional stem width; for small amounts, choose * C) always, for large amounts, B) always, and inbetween, * pick whichever one involves less stem movement. */ @@ -890,9 +888,6 @@ /*************************************************************************/ /*************************************************************************/ -#define PSH_ZONE_MIN -3200000L -#define PSH_ZONE_MAX +3200000L - #define xxDEBUG_ZONES @@ -910,10 +905,6 @@ zone->max ); } -#else - -#define psh_print_zone( x ) do { } while ( 0 ) - #endif /* DEBUG_ZONES */ @@ -925,103 +916,9 @@ /*************************************************************************/ /*************************************************************************/ -#if 1 - #define psh_corner_is_flat ft_corner_is_flat #define psh_corner_orientation ft_corner_orientation -#else - - FT_LOCAL_DEF( FT_Int ) - psh_corner_is_flat( FT_Pos x_in, - FT_Pos y_in, - FT_Pos x_out, - FT_Pos y_out ) - { - FT_Pos ax = x_in; - FT_Pos ay = y_in; - - FT_Pos d_in, d_out, d_corner; - - - if ( ax < 0 ) - ax = -ax; - if ( ay < 0 ) - ay = -ay; - d_in = ax + ay; - - ax = x_out; - if ( ax < 0 ) - ax = -ax; - ay = y_out; - if ( ay < 0 ) - ay = -ay; - d_out = ax + ay; - - ax = x_out + x_in; - if ( ax < 0 ) - ax = -ax; - ay = y_out + y_in; - if ( ay < 0 ) - ay = -ay; - d_corner = ax + ay; - - return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); - } - - static FT_Int - psh_corner_orientation( FT_Pos in_x, - FT_Pos in_y, - FT_Pos out_x, - FT_Pos out_y ) - { - FT_Int result; - - - /* deal with the trivial cases quickly */ - if ( in_y == 0 ) - { - if ( in_x >= 0 ) - result = out_y; - else - result = -out_y; - } - else if ( in_x == 0 ) - { - if ( in_y >= 0 ) - result = -out_x; - else - result = out_x; - } - else if ( out_y == 0 ) - { - if ( out_x >= 0 ) - result = in_y; - else - result = -in_y; - } - else if ( out_x == 0 ) - { - if ( out_y >= 0 ) - result = -in_x; - else - result = in_x; - } - else /* general case */ - { - long long delta = (long long)in_x * out_y - (long long)in_y * out_x; - - if ( delta == 0 ) - result = 0; - else - result = 1 - 2 * ( delta < 0 ); - } - - return result; - } - -#endif /* !1 */ - #ifdef COMPUTE_INFLEXS @@ -1149,7 +1046,7 @@ glyph->num_points = 0; glyph->num_contours = 0; - glyph->memory = 0; + glyph->memory = NULL; } @@ -1274,8 +1171,8 @@ FT_NEW_ARRAY( glyph->contours, outline->n_contours ) ) goto Exit; - glyph->num_points = outline->n_points; - glyph->num_contours = outline->n_contours; + glyph->num_points = (FT_UInt)outline->n_points; + glyph->num_contours = (FT_UInt)outline->n_contours; { FT_UInt first = 0, next, n; @@ -1285,15 +1182,15 @@ for ( n = 0; n < glyph->num_contours; n++ ) { - FT_Int count; + FT_UInt count; PSH_Point point; - next = outline->contours[n] + 1; + next = (FT_UInt)outline->contours[n] + 1; count = next - first; contour->start = points + first; - contour->count = (FT_UInt)count; + contour->count = count; if ( count > 0 ) { @@ -1406,7 +1303,6 @@ point = first; before = point; - after = point; do { @@ -1697,16 +1593,12 @@ mask++; for ( ; num_masks > 1; num_masks--, mask++ ) { - FT_UInt next; - FT_Int count; + FT_UInt next = FT_MIN( mask->end_point, glyph->num_points ); - next = mask->end_point > glyph->num_points - ? glyph->num_points - : mask->end_point; - count = next - first; - if ( count > 0 ) + if ( next > first ) { + FT_UInt count = next - first; PSH_Point point = glyph->points + first; @@ -2049,7 +1941,7 @@ /* count the number of strong points in this contour */ next = start + contour->count; fit_count = 0; - first = 0; + first = NULL; for ( point = start; point < next; point++ ) if ( psh_point_is_fitted( point ) ) @@ -2079,8 +1971,6 @@ start = first; do { - point = first; - /* skip consecutive fitted points */ for (;;) { diff --git a/drivers/freetype/freetype/src/pshinter/pshalgo.h b/drivers/freetype/src/pshinter/pshalgo.h index c70f31ea94..f1bda65013 100644 --- a/drivers/freetype/freetype/src/pshinter/pshalgo.h +++ b/drivers/freetype/src/pshinter/pshalgo.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (specification). */ /* */ -/* Copyright 2001-2003, 2008, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHALGO_H__ -#define __PSHALGO_H__ +#ifndef PSHALGO_H_ +#define PSHALGO_H_ #include "pshrec.h" @@ -30,15 +30,12 @@ FT_BEGIN_HEADER /* handle to Hint structure */ typedef struct PSH_HintRec_* PSH_Hint; - /* hint bit-flags */ - typedef enum PSH_Hint_Flags_ - { - PSH_HINT_GHOST = PS_HINT_FLAG_GHOST, - PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, - PSH_HINT_ACTIVE = 4, - PSH_HINT_FITTED = 8 - } PSH_Hint_Flags; + /* hint bit-flags */ +#define PSH_HINT_GHOST PS_HINT_FLAG_GHOST +#define PSH_HINT_BOTTOM PS_HINT_FLAG_BOTTOM +#define PSH_HINT_ACTIVE 4U +#define PSH_HINT_FITTED 8U #define psh_hint_is_active( x ) ( ( (x)->flags & PSH_HINT_ACTIVE ) != 0 ) @@ -49,6 +46,7 @@ FT_BEGIN_HEADER #define psh_hint_deactivate( x ) (x)->flags &= ~PSH_HINT_ACTIVE #define psh_hint_set_fitted( x ) (x)->flags |= PSH_HINT_FITTED + /* hint structure */ typedef struct PSH_HintRec_ { @@ -112,14 +110,12 @@ FT_BEGIN_HEADER #define PSH_DIR_IS_VERTICAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_VERTICAL ) - /* the following bit-flags are computed once by the glyph */ - /* analyzer, for both dimensions */ - enum - { - PSH_POINT_OFF = 1, /* point is off the curve */ - PSH_POINT_SMOOTH = 2, /* point is smooth */ - PSH_POINT_INFLEX = 4 /* point is inflection */ - }; + /* the following bit-flags are computed once by the glyph */ + /* analyzer, for both dimensions */ +#define PSH_POINT_OFF 1U /* point is off the curve */ +#define PSH_POINT_SMOOTH 2U /* point is smooth */ +#define PSH_POINT_INFLEX 4U /* point is inflection */ + #define psh_point_is_smooth( p ) ( (p)->flags & PSH_POINT_SMOOTH ) #define psh_point_is_off( p ) ( (p)->flags & PSH_POINT_OFF ) @@ -129,17 +125,16 @@ FT_BEGIN_HEADER #define psh_point_set_off( p ) (p)->flags |= PSH_POINT_OFF #define psh_point_set_inflex( p ) (p)->flags |= PSH_POINT_INFLEX + /* the following bit-flags are re-computed for each dimension */ - enum - { - PSH_POINT_STRONG = 16, /* point is strong */ - PSH_POINT_FITTED = 32, /* point is already fitted */ - PSH_POINT_EXTREMUM = 64, /* point is local extremum */ - PSH_POINT_POSITIVE = 128, /* extremum has positive contour flow */ - PSH_POINT_NEGATIVE = 256, /* extremum has negative contour flow */ - PSH_POINT_EDGE_MIN = 512, /* point is aligned to left/bottom stem edge */ - PSH_POINT_EDGE_MAX = 1024 /* point is aligned to top/right stem edge */ - }; +#define PSH_POINT_STRONG 16U /* point is strong */ +#define PSH_POINT_FITTED 32U /* point is already fitted */ +#define PSH_POINT_EXTREMUM 64U /* point is local extremum */ +#define PSH_POINT_POSITIVE 128U /* extremum has positive contour flow */ +#define PSH_POINT_NEGATIVE 256U /* extremum has negative contour flow */ +#define PSH_POINT_EDGE_MIN 512U /* point is aligned to left/bottom stem edge */ +#define PSH_POINT_EDGE_MAX 1024U /* point is aligned to top/right stem edge */ + #define psh_point_is_strong( p ) ( (p)->flags2 & PSH_POINT_STRONG ) #define psh_point_is_fitted( p ) ( (p)->flags2 & PSH_POINT_FITTED ) @@ -240,7 +235,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHALGO_H__ */ +#endif /* PSHALGO_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshglob.c b/drivers/freetype/src/pshinter/pshglob.c index 9285efc9e1..2ac5ef1558 100644 --- a/drivers/freetype/freetype/src/pshinter/pshglob.c +++ b/drivers/freetype/src/pshinter/pshglob.c @@ -5,7 +5,7 @@ /* PostScript hinter global hinting management (body). */ /* Inspired by the new auto-hinter module. */ /* */ -/* Copyright 2001-2004, 2006, 2010, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -23,7 +23,7 @@ #include "pshglob.h" #ifdef DEBUG_HINTER - PSH_Globals ps_debug_globals = 0; + PSH_Globals ps_debug_globals = NULL; #endif @@ -80,7 +80,7 @@ #if 0 - /* org_width is is font units, result in device pixels, 26.6 format */ + /* org_width is in font units, result in device pixels, 26.6 format */ FT_LOCAL_DEF( FT_Pos ) psh_dimension_snap_width( PSH_Dimension dimension, FT_Int org_width ) @@ -240,7 +240,7 @@ FT_Int family ) { PSH_Blue_Table top_table, bot_table; - FT_Int count_top, count_bot; + FT_UInt count_top, count_bot; if ( family ) @@ -339,7 +339,7 @@ bot = zone[1].org_bottom; delta = bot - top; - if ( delta < 2 * fuzz ) + if ( delta / 2 < fuzz ) zone[0].org_top = zone[1].org_bottom = top + delta / 2; else { @@ -369,7 +369,7 @@ { FT_UInt count; FT_UInt num; - PSH_Blue_Table table = 0; + PSH_Blue_Table table = NULL; /* */ /* Determine whether we need to suppress overshoots or */ @@ -635,7 +635,7 @@ FT_FREE( globals ); #ifdef DEBUG_HINTER - ps_debug_globals = 0; + ps_debug_globals = NULL; #endif } } @@ -750,14 +750,14 @@ } - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) psh_globals_set_scale( PSH_Globals globals, FT_Fixed x_scale, FT_Fixed y_scale, FT_Fixed x_delta, FT_Fixed y_delta ) { - PSH_Dimension dim = &globals->dimension[0]; + PSH_Dimension dim; dim = &globals->dimension[0]; @@ -780,8 +780,6 @@ psh_globals_scale_widths( globals, 1 ); psh_blues_scale_zones( &globals->blues, y_scale, y_delta ); } - - return 0; } diff --git a/drivers/freetype/freetype/src/pshinter/pshglob.h b/drivers/freetype/src/pshinter/pshglob.h index c511626157..45c957b6ef 100644 --- a/drivers/freetype/freetype/src/pshinter/pshglob.h +++ b/drivers/freetype/src/pshinter/pshglob.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinter global hinting management. */ /* */ -/* Copyright 2001, 2002, 2003 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHGLOB_H__ -#define __PSHGLOB_H__ +#ifndef PSHGLOB_H_ +#define PSHGLOB_H_ #include FT_FREETYPE_H @@ -167,7 +167,7 @@ FT_BEGIN_HEADER FT_Int org_width ); #endif - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) psh_globals_set_scale( PSH_Globals globals, FT_Fixed x_scale, FT_Fixed y_scale, @@ -190,7 +190,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHGLOB_H__ */ +#endif /* PSHGLOB_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshinter.c b/drivers/freetype/src/pshinter/pshinter.c index b35a2a91c5..614e0bb3d8 100644 --- a/drivers/freetype/freetype/src/pshinter/pshinter.c +++ b/drivers/freetype/src/pshinter/pshinter.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript Hinting module */ /* */ -/* Copyright 2001, 2003 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/pshinter/pshmod.c b/drivers/freetype/src/pshinter/pshmod.c index cdeaca18c9..fa4ad1f564 100644 --- a/drivers/freetype/freetype/src/pshinter/pshmod.c +++ b/drivers/freetype/src/pshinter/pshmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hinter module implementation (body). */ /* */ -/* Copyright 2001, 2002, 2007, 2009, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/pshinter/pshmod.h b/drivers/freetype/src/pshinter/pshmod.h index 0ae7e96f54..39112a9561 100644 --- a/drivers/freetype/freetype/src/pshinter/pshmod.h +++ b/drivers/freetype/src/pshinter/pshmod.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinter module interface (specification). */ /* */ -/* Copyright 2001 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHMOD_H__ -#define __PSHMOD_H__ +#ifndef PSHMOD_H_ +#define PSHMOD_H_ #include <ft2build.h> @@ -33,7 +33,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHMOD_H__ */ +#endif /* PSHMOD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshnterr.h b/drivers/freetype/src/pshinter/pshnterr.h index 7cc180f0ca..7a94588b87 100644 --- a/drivers/freetype/freetype/src/pshinter/pshnterr.h +++ b/drivers/freetype/src/pshinter/pshnterr.h @@ -4,7 +4,7 @@ /* */ /* PS Hinter error codes (specification only). */ /* */ -/* Copyright 2003, 2012 by */ +/* Copyright 2003-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __PSHNTERR_H__ -#define __PSHNTERR_H__ +#ifndef PSHNTERR_H_ +#define PSHNTERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSH_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __PSHNTERR_H__ */ +#endif /* PSHNTERR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshpic.c b/drivers/freetype/src/pshinter/pshpic.c index 568f4ac4b0..d0a3d8ebc9 100644 --- a/drivers/freetype/freetype/src/pshinter/pshpic.c +++ b/drivers/freetype/src/pshinter/pshpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for pshinter module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/pshinter/pshpic.h b/drivers/freetype/src/pshinter/pshpic.h index b46f853113..75ee573544 100644 --- a/drivers/freetype/freetype/src/pshinter/pshpic.h +++ b/drivers/freetype/src/pshinter/pshpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for pshinter module. */ /* */ -/* Copyright 2009, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,10 @@ /***************************************************************************/ -#ifndef __PSHPIC_H__ -#define __PSHPIC_H__ +#ifndef PSHPIC_H_ +#define PSHPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H @@ -33,6 +31,8 @@ FT_BEGIN_HEADER #include FT_INTERNAL_POSTSCRIPT_HINTS_H +FT_BEGIN_HEADER + typedef struct PSHinterPIC_ { PSHinter_Interface pshinter_interface; @@ -51,13 +51,13 @@ FT_BEGIN_HEADER FT_Error pshinter_module_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __PSHPIC_H__ */ +#endif /* PSHPIC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pshinter/pshrec.c b/drivers/freetype/src/pshinter/pshrec.c index cd66ea869a..d7cc4a0d21 100644 --- a/drivers/freetype/freetype/src/pshinter/pshrec.c +++ b/drivers/freetype/src/pshinter/pshrec.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hints recorder (body). */ /* */ -/* Copyright 2001-2004, 2007, 2009, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,7 +31,7 @@ #define FT_COMPONENT trace_pshrec #ifdef DEBUG_HINTER - PS_Hints ps_debug_hints = 0; + PS_Hints ps_debug_hints = NULL; int ps_debug_no_horz_hints = 0; int ps_debug_no_vert_hints = 0; #endif @@ -85,7 +85,7 @@ { FT_Error error = FT_Err_Ok; FT_UInt count; - PS_Hint hint = 0; + PS_Hint hint = NULL; count = table->num_hints; @@ -167,12 +167,12 @@ /* clear a given bit */ static void ps_mask_clear_bit( PS_Mask mask, - FT_Int idx ) + FT_UInt idx ) { FT_Byte* p; - if ( (FT_UInt)idx >= mask->num_bits ) + if ( idx >= mask->num_bits ) return; p = mask->bytes + ( idx >> 3 ); @@ -183,17 +183,14 @@ /* set a given bit, possibly grow the mask */ static FT_Error ps_mask_set_bit( PS_Mask mask, - FT_Int idx, + FT_UInt idx, FT_Memory memory ) { FT_Error error = FT_Err_Ok; FT_Byte* p; - if ( idx < 0 ) - goto Exit; - - if ( (FT_UInt)idx >= mask->num_bits ) + if ( idx >= mask->num_bits ) { error = ps_mask_ensure( mask, idx + 1, memory ); if ( error ) @@ -257,7 +254,7 @@ { FT_UInt count; FT_Error error = FT_Err_Ok; - PS_Mask mask = 0; + PS_Mask mask = NULL; count = table->num_masks; @@ -372,8 +369,8 @@ /* test whether two masks in a table intersect */ static FT_Int ps_mask_table_test_intersect( PS_Mask_Table table, - FT_Int index1, - FT_Int index2 ) + FT_UInt index1, + FT_UInt index2 ) { PS_Mask mask1 = table->masks + index1; PS_Mask mask2 = table->masks + index2; @@ -404,23 +401,25 @@ /* merge two masks, used by ps_mask_table_merge_all */ static FT_Error ps_mask_table_merge( PS_Mask_Table table, - FT_Int index1, - FT_Int index2, + FT_UInt index1, + FT_UInt index2, FT_Memory memory ) { - FT_UInt temp; FT_Error error = FT_Err_Ok; /* swap index1 and index2 so that index1 < index2 */ if ( index1 > index2 ) { + FT_UInt temp; + + temp = index1; index1 = index2; index2 = temp; } - if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks ) + if ( index1 < index2 && index2 < table->num_masks ) { /* we need to merge the bitsets of index1 and index2 with a */ /* simple union */ @@ -453,7 +452,7 @@ /* merge (unite) the bitsets */ read = mask2->bytes; write = mask1->bytes; - pos = (FT_UInt)( ( count2 + 7 ) >> 3 ); + pos = ( count2 + 7 ) >> 3; for ( ; pos > 0; pos-- ) { @@ -468,14 +467,17 @@ mask2->num_bits = 0; mask2->end_point = 0; - delta = table->num_masks - 1 - index2; /* number of masks to move */ + /* number of masks to move */ + delta = (FT_Int)( table->num_masks - 1 - index2 ); if ( delta > 0 ) { /* move to end of table for reuse */ PS_MaskRec dummy = *mask2; - ft_memmove( mask2, mask2 + 1, delta * sizeof ( PS_MaskRec ) ); + ft_memmove( mask2, + mask2 + 1, + (FT_UInt)delta * sizeof ( PS_MaskRec ) ); mask2[delta] = dummy; } @@ -502,13 +504,19 @@ FT_Error error = FT_Err_Ok; - for ( index1 = table->num_masks - 1; index1 > 0; index1-- ) + /* both loops go down to 0, thus FT_Int for index1 and index2 */ + for ( index1 = (FT_Int)table->num_masks - 1; index1 > 0; index1-- ) { for ( index2 = index1 - 1; index2 >= 0; index2-- ) { - if ( ps_mask_table_test_intersect( table, index1, index2 ) ) + if ( ps_mask_table_test_intersect( table, + (FT_UInt)index1, + (FT_UInt)index2 ) ) { - error = ps_mask_table_merge( table, index2, index1, memory ); + error = ps_mask_table_merge( table, + (FT_UInt)index2, + (FT_UInt)index1, + memory ); if ( error ) goto Exit; @@ -670,8 +678,8 @@ { PS_Mask mask; FT_UInt idx; - FT_UInt max = dim->hints.num_hints; - PS_Hint hint = dim->hints.hints; + FT_UInt max = dim->hints.num_hints; + PS_Hint hint = dim->hints.hints; for ( idx = 0; idx < max; idx++, hint++ ) @@ -742,17 +750,26 @@ } /* now, set the bits for our hints in the counter mask */ - error = ps_mask_set_bit( counter, hint1, memory ); - if ( error ) - goto Exit; + if ( hint1 >= 0 ) + { + error = ps_mask_set_bit( counter, (FT_UInt)hint1, memory ); + if ( error ) + goto Exit; + } - error = ps_mask_set_bit( counter, hint2, memory ); - if ( error ) - goto Exit; + if ( hint2 >= 0 ) + { + error = ps_mask_set_bit( counter, (FT_UInt)hint2, memory ); + if ( error ) + goto Exit; + } - error = ps_mask_set_bit( counter, hint3, memory ); - if ( error ) - goto Exit; + if ( hint3 >= 0 ) + { + error = ps_mask_set_bit( counter, (FT_UInt)hint3, memory ); + if ( error ) + goto Exit; + } Exit: return error; @@ -793,17 +810,16 @@ ps_dimension_done( &hints->dimension[1], memory ); hints->error = FT_Err_Ok; - hints->memory = 0; + hints->memory = NULL; } - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) ps_hints_init( PS_Hints hints, FT_Memory memory ) { FT_MEM_ZERO( hints, sizeof ( *hints ) ); hints->memory = memory; - return FT_Err_Ok; } @@ -812,78 +828,57 @@ ps_hints_open( PS_Hints hints, PS_Hint_Type hint_type ) { - switch ( hint_type ) - { - case PS_HINT_TYPE_1: - case PS_HINT_TYPE_2: - hints->error = FT_Err_Ok; - hints->hint_type = hint_type; - - ps_dimension_init( &hints->dimension[0] ); - ps_dimension_init( &hints->dimension[1] ); - break; + hints->error = FT_Err_Ok; + hints->hint_type = hint_type; - default: - hints->error = FT_THROW( Invalid_Argument ); - hints->hint_type = hint_type; - - FT_TRACE0(( "ps_hints_open: invalid charstring type\n" )); - break; - } + ps_dimension_init( &hints->dimension[0] ); + ps_dimension_init( &hints->dimension[1] ); } /* add one or more stems to the current hints table */ static void ps_hints_stem( PS_Hints hints, - FT_Int dimension, - FT_UInt count, + FT_UInt dimension, + FT_Int count, FT_Long* stems ) { - if ( !hints->error ) - { - /* limit "dimension" to 0..1 */ - if ( dimension < 0 || dimension > 1 ) - { - FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n", - dimension )); - dimension = ( dimension != 0 ); - } + PS_Dimension dim; - /* record the stems in the current hints/masks table */ - switch ( hints->hint_type ) - { - case PS_HINT_TYPE_1: /* Type 1 "hstem" or "vstem" operator */ - case PS_HINT_TYPE_2: /* Type 2 "hstem" or "vstem" operator */ - { - PS_Dimension dim = &hints->dimension[dimension]; + if ( hints->error ) + return; - for ( ; count > 0; count--, stems += 2 ) - { - FT_Error error; - FT_Memory memory = hints->memory; + /* limit "dimension" to 0..1 */ + if ( dimension > 1 ) + { + FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n", + dimension )); + dimension = ( dimension != 0 ); + } + /* record the stems in the current hints/masks table */ + /* (Type 1 & 2's `hstem' or `vstem' operators) */ + dim = &hints->dimension[dimension]; - error = ps_dimension_add_t1stem( - dim, (FT_Int)stems[0], (FT_Int)stems[1], - memory, NULL ); - if ( error ) - { - FT_ERROR(( "ps_hints_stem: could not add stem" - " (%d,%d) to hints table\n", stems[0], stems[1] )); + for ( ; count > 0; count--, stems += 2 ) + { + FT_Error error; + FT_Memory memory = hints->memory; - hints->error = error; - return; - } - } - break; - } - default: - FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n", - hints->hint_type )); - break; + error = ps_dimension_add_t1stem( dim, + (FT_Int)stems[0], + (FT_Int)stems[1], + memory, + NULL ); + if ( error ) + { + FT_ERROR(( "ps_hints_stem: could not add stem" + " (%d,%d) to hints table\n", stems[0], stems[1] )); + + hints->error = error; + return; } } } @@ -892,7 +887,7 @@ /* add one Type1 counter stem to the current hints table */ static void ps_hints_t1stem3( PS_Hints hints, - FT_Int dimension, + FT_UInt dimension, FT_Fixed* stems ) { FT_Error error = FT_Err_Ok; @@ -907,7 +902,7 @@ /* limit "dimension" to 0..1 */ - if ( dimension < 0 || dimension > 1 ) + if ( dimension > 1 ) { FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n", dimension )); @@ -1129,7 +1124,7 @@ static void t1_hints_stem( T1_Hints hints, - FT_Int dimension, + FT_UInt dimension, FT_Fixed* coords ) { FT_Pos stems[2]; @@ -1173,12 +1168,12 @@ static void t2_hints_stems( T2_Hints hints, - FT_Int dimension, + FT_UInt dimension, FT_Int count, FT_Fixed* coords ) { - FT_Pos stems[32], y, n; - FT_Int total = count; + FT_Pos stems[32], y; + FT_Int total = count, n; y = 0; diff --git a/drivers/freetype/freetype/src/pshinter/pshrec.h b/drivers/freetype/src/pshinter/pshrec.h index dcb3197f94..97e6f0ed51 100644 --- a/drivers/freetype/freetype/src/pshinter/pshrec.h +++ b/drivers/freetype/src/pshinter/pshrec.h @@ -4,7 +4,7 @@ /* */ /* Postscript (Type1/Type2) hints recorder (specification). */ /* */ -/* Copyright 2001, 2002, 2003, 2006, 2008 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,8 +28,8 @@ /**************************************************************************/ -#ifndef __PSHREC_H__ -#define __PSHREC_H__ +#ifndef PSHREC_H_ +#define PSHREC_H_ #include <ft2build.h> @@ -61,12 +61,8 @@ FT_BEGIN_HEADER /* hint flags */ - typedef enum PS_Hint_Flags_ - { - PS_HINT_FLAG_GHOST = 1, - PS_HINT_FLAG_BOTTOM = 2 - - } PS_Hint_Flags; +#define PS_HINT_FLAG_GHOST 1U +#define PS_HINT_FLAG_BOTTOM 2U /* hint descriptor */ @@ -141,7 +137,7 @@ FT_BEGIN_HEADER /* */ /* initialize hints recorder */ - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) ps_hints_init( PS_Hints hints, FT_Memory memory ); @@ -170,7 +166,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PS_HINTER_RECORD_H__ */ +#endif /* PSHREC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/pshinter/rules.mk b/drivers/freetype/src/pshinter/rules.mk index 888ece1058..67ecf7862f 100644 --- a/drivers/freetype/freetype/src/pshinter/rules.mk +++ b/drivers/freetype/src/pshinter/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2001, 2003, 2011 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ PSHINTER_DIR := $(SRC_DIR)/pshinter # compilation flags for the driver # -PSHINTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSHINTER_DIR)) +PSHINTER_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(PSHINTER_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # PSHINTER driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/psnames/Jamfile b/drivers/freetype/src/psnames/Jamfile index 06c0dda66f..35b8a99c8f 100644 --- a/drivers/freetype/freetype/src/psnames/Jamfile +++ b/drivers/freetype/src/psnames/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/psnames Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,9 @@ SubDir FT2_TOP $(FT2_SRC_DIR) psnames ; if $(FT2_MULTI) { - _sources = psmodule pspic ; + _sources = psmodule + pspic + ; } else { diff --git a/drivers/freetype/freetype/src/psnames/module.mk b/drivers/freetype/src/psnames/module.mk index a6e908257c..ba29af813c 100644 --- a/drivers/freetype/freetype/src/psnames/module.mk +++ b/drivers/freetype/src/psnames/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/psnames/psmodule.c b/drivers/freetype/src/psnames/psmodule.c index 0a5bcb7d2a..345402d7cc 100644 --- a/drivers/freetype/freetype/src/psnames/psmodule.c +++ b/drivers/freetype/src/psnames/psmodule.c @@ -4,7 +4,7 @@ /* */ /* PSNames module implementation (body). */ /* */ -/* Copyright 1996-2003, 2005-2008, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -312,7 +312,7 @@ /* we first allocate the table */ table->num_maps = 0; - table->maps = 0; + table->maps = NULL; if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) { @@ -525,31 +525,31 @@ FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, - (PS_Unicode_ValueFunc) ps_unicode_value, - (PS_Unicodes_InitFunc) ps_unicodes_init, - (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, - (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, + (PS_Unicode_ValueFunc) ps_unicode_value, /* unicode_value */ + (PS_Unicodes_InitFunc) ps_unicodes_init, /* unicodes_init */ + (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, /* unicodes_char_index */ + (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, /* unicodes_char_next */ - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + (PS_Macintosh_NameFunc) ps_get_macintosh_name, /* macintosh_name */ + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ - t1_standard_encoding, - t1_expert_encoding ) + t1_standard_encoding, /* adobe_std_encoding */ + t1_expert_encoding ) /* adobe_expert_encoding */ #else FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, - NULL, - NULL, - NULL, - NULL, + NULL, /* unicode_value */ + NULL, /* unicodes_init */ + NULL, /* unicodes_char_index */ + NULL, /* unicodes_char_next */ - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + (PS_Macintosh_NameFunc) ps_get_macintosh_name, /* macintosh_name */ + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ - t1_standard_encoding, - t1_expert_encoding ) + t1_standard_encoding, /* adobe_std_encoding */ + t1_expert_encoding ) /* adobe_expert_encoding */ #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ @@ -563,7 +563,7 @@ psnames_get_service( FT_Module module, const char* service_id ) { - /* PSCMAPS_SERVICES_GET derefers `library' in PIC mode */ + /* PSCMAPS_SERVICES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC FT_Library library; diff --git a/drivers/freetype/freetype/src/psnames/psmodule.h b/drivers/freetype/src/psnames/psmodule.h index 28fa14807c..ee3c6cb631 100644 --- a/drivers/freetype/freetype/src/psnames/psmodule.h +++ b/drivers/freetype/src/psnames/psmodule.h @@ -4,7 +4,7 @@ /* */ /* High-level PSNames module interface (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSMODULE_H__ -#define __PSMODULE_H__ +#ifndef PSMODULE_H_ +#define PSMODULE_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSMODULE_H__ */ +#endif /* PSMODULE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/psnames/psnamerr.h b/drivers/freetype/src/psnames/psnamerr.h index acda7f967e..3a9f65323b 100644 --- a/drivers/freetype/freetype/src/psnames/psnamerr.h +++ b/drivers/freetype/src/psnames/psnamerr.h @@ -4,7 +4,7 @@ /* */ /* PS names module error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __PSNAMERR_H__ -#define __PSNAMERR_H__ +#ifndef PSNAMERR_H_ +#define PSNAMERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSnames_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __PSNAMERR_H__ */ +#endif /* PSNAMERR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/psnames/psnames.c b/drivers/freetype/src/psnames/psnames.c index 1ede225dc9..e7b2c0b5ef 100644 --- a/drivers/freetype/freetype/src/psnames/psnames.c +++ b/drivers/freetype/src/psnames/psnames.c @@ -4,7 +4,7 @@ /* */ /* FreeType PSNames module component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/psnames/pspic.c b/drivers/freetype/src/psnames/pspic.c index 3820f65a74..a78ec5aa81 100644 --- a/drivers/freetype/freetype/src/psnames/pspic.c +++ b/drivers/freetype/src/psnames/pspic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for psnames module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/psnames/pspic.h b/drivers/freetype/src/psnames/pspic.h index 6ff002c603..48348765cf 100644 --- a/drivers/freetype/freetype/src/psnames/pspic.h +++ b/drivers/freetype/src/psnames/pspic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for psnames module. */ /* */ -/* Copyright 2009, 2012 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,14 +16,13 @@ /***************************************************************************/ -#ifndef __PSPIC_H__ -#define __PSPIC_H__ +#ifndef PSPIC_H_ +#define PSPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H + #ifndef FT_CONFIG_OPTION_PIC #define PSCMAPS_SERVICES_GET pscmaps_services @@ -33,6 +32,9 @@ FT_BEGIN_HEADER #include FT_SERVICE_POSTSCRIPT_CMAPS_H + +FT_BEGIN_HEADER + typedef struct PSModulePIC_ { FT_ServiceDescRec* pscmaps_services; @@ -54,13 +56,13 @@ FT_BEGIN_HEADER FT_Error psnames_module_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __PSPIC_H__ */ +#endif /* PSPIC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/psnames/pstables.h b/drivers/freetype/src/psnames/pstables.h index 0a6637f985..eb827fa5ea 100644 --- a/drivers/freetype/freetype/src/psnames/pstables.h +++ b/drivers/freetype/src/psnames/pstables.h @@ -4,7 +4,7 @@ /* */ /* PostScript glyph names. */ /* */ -/* Copyright 2005, 2008, 2011 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/psnames/rules.mk b/drivers/freetype/src/psnames/rules.mk index 4cd39a8ccf..9849f4053a 100644 --- a/drivers/freetype/freetype/src/psnames/rules.mk +++ b/drivers/freetype/src/psnames/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003, 2011 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ PSNAMES_DIR := $(SRC_DIR)/psnames # compilation flags for the driver # -PSNAMES_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSNAMES_DIR)) +PSNAMES_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(PSNAMES_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # PSNames driver sources (i.e., C files) @@ -46,7 +49,7 @@ PSNAMES_DRV_OBJ_S := $(OBJ_DIR)/psnames.$O # PSNames driver source file for single build # -PSNAMES_DRV_SRC_S := $(PSNAMES_DIR)/psmodule.c +PSNAMES_DRV_SRC_S := $(PSNAMES_DIR)/psnames.c # PSNames driver - single object diff --git a/drivers/freetype/freetype/src/raster/Jamfile b/drivers/freetype/src/raster/Jamfile index 4f60e87c78..2ec88f5601 100644 --- a/drivers/freetype/freetype/src/raster/Jamfile +++ b/drivers/freetype/src/raster/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/raster Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,10 @@ SubDir FT2_TOP $(FT2_SRC_DIR) raster ; if $(FT2_MULTI) { - _sources = ftraster ftrend1 rastpic ; + _sources = ftraster + ftrend1 + rastpic + ; } else { diff --git a/drivers/freetype/freetype/src/raster/ftmisc.h b/drivers/freetype/src/raster/ftmisc.h index 703155a429..981ce32279 100644 --- a/drivers/freetype/freetype/src/raster/ftmisc.h +++ b/drivers/freetype/src/raster/ftmisc.h @@ -5,7 +5,7 @@ /* Miscellaneous macros for stand-alone rasterizer (specification */ /* only). */ /* */ -/* Copyright 2005, 2009, 2010 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -24,8 +24,8 @@ /* */ /***************************************************/ -#ifndef __FTMISC_H__ -#define __FTMISC_H__ +#ifndef FTMISC_H_ +#define FTMISC_H_ /* memset */ @@ -37,7 +37,7 @@ #define FT_LOCAL_DEF( x ) static x - /* from include/freetype2/fttypes.h */ + /* from include/freetype/fttypes.h */ typedef unsigned char FT_Byte; typedef signed int FT_Int; @@ -54,7 +54,7 @@ (FT_ULong)_x4 ) - /* from include/freetype2/ftsystem.h */ + /* from include/freetype/ftsystem.h */ typedef struct FT_MemoryRec_* FT_Memory; @@ -136,7 +136,7 @@ return ( s > 0 ) ? d : -d; } -#endif /* __FTMISC_H__ */ +#endif /* FTMISC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/raster/ftraster.c b/drivers/freetype/src/raster/ftraster.c index bbd503d97d..0fa2f2687f 100644 --- a/drivers/freetype/freetype/src/raster/ftraster.c +++ b/drivers/freetype/src/raster/ftraster.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (body). */ /* */ -/* Copyright 1996-2003, 2005, 2007-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,18 +18,18 @@ /*************************************************************************/ /* */ /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* defining the STANDALONE_ macro when compiling it. You also need to */ /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ /* directory. Typically, you should do something like */ /* */ /* - copy `src/raster/ftraster.c' (this file) to your current directory */ /* */ - /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' */ - /* to your current directory */ + /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your */ + /* current directory */ /* */ - /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ + /* - compile `ftraster' with the STANDALONE_ macro defined, as in */ /* */ - /* cc -c -D_STANDALONE_ ftraster.c */ + /* cc -c -DSTANDALONE_ ftraster.c */ /* */ /* The renderer can be initialized with a call to */ /* `ft_standard_raster.raster_new'; a bitmap can be generated */ @@ -47,7 +47,11 @@ /* */ /*************************************************************************/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ + + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ +#define FT_RENDER_POOL_SIZE 16384L #define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> @@ -56,7 +60,7 @@ #include "ftmisc.h" #include "ftimage.h" -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include <ft2build.h> #include "ftraster.h" @@ -64,7 +68,7 @@ #include "rastpic.h" -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ /*************************************************************************/ @@ -150,14 +154,6 @@ /* define DEBUG_RASTER if you want to compile a debugging version */ /* #define DEBUG_RASTER */ - /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ - /* 5-levels anti-aliasing */ -/* #define FT_RASTER_OPTION_ANTI_ALIASING */ - - /* The size of the two-lines intermediate bitmap used */ - /* for anti-aliasing, in bytes. */ -#define RASTER_GRAY_LINES 2048 - /*************************************************************************/ /*************************************************************************/ @@ -177,7 +173,7 @@ #define FT_COMPONENT trace_raster -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /* Auxiliary macros for token concatenation. */ #define FT_ERR_XCAT( x, y ) x ## y @@ -199,6 +195,7 @@ #define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ #define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ #define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ #endif #ifndef FT_THROW @@ -227,7 +224,7 @@ raster_done_ \ }; -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include FT_INTERNAL_OBJECTS_H @@ -243,7 +240,7 @@ #define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ #ifndef FT_MEM_SET @@ -318,7 +315,7 @@ typedef union Alignment_ { - long l; + Long l; void* p; void (*f)(void); @@ -334,9 +331,9 @@ /* values for the `flags' bit field */ -#define Flow_Up 0x8 -#define Overshoot_Top 0x10 -#define Overshoot_Bottom 0x20 +#define Flow_Up 0x08U +#define Overshoot_Top 0x10U +#define Overshoot_Bottom 0x20U /* States of each line, arc, and profile */ @@ -358,14 +355,14 @@ FT_F26Dot6 X; /* current coordinate during sweep */ PProfile link; /* link to next profile (various purposes) */ PLong offset; /* start of profile's data in render pool */ - unsigned flags; /* Bit 0-2: drop-out mode */ + UShort flags; /* Bit 0-2: drop-out mode */ /* Bit 3: profile orientation (up/down) */ /* Bit 4: is top profile? */ /* Bit 5: is bottom profile? */ - long height; /* profile's height in scanlines */ - long start; /* profile's starting scanline */ + Long height; /* profile's height in scanlines */ + Long start; /* profile's starting scanline */ - unsigned countL; /* number of lines to step before this */ + Int countL; /* number of lines to step before this */ /* profile becomes drawable */ PProfile next; /* next profile in same contour, used */ @@ -387,7 +384,7 @@ #define AlignProfileSize \ - ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) ) + ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( Long ) ) #undef RAS_ARG @@ -451,13 +448,21 @@ #define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) #define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) #define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) -#define SCALED( x ) ( ( (ULong)(x) << ras.scale_shift ) - ras.precision_half ) +#define SCALED( x ) ( ( (x) < 0 ? -( -(x) << ras.scale_shift ) \ + : ( (x) << ras.scale_shift ) ) \ + - ras.precision_half ) #define IS_BOTTOM_OVERSHOOT( x ) \ (Bool)( CEILING( x ) - x >= ras.precision_half ) #define IS_TOP_OVERSHOOT( x ) \ (Bool)( x - FLOOR( x ) >= ras.precision_half ) +#if FT_RENDER_POOL_SIZE > 2048 +#define FT_MAX_BLACK_POOL ( FT_RENDER_POOL_SIZE / sizeof ( Long ) ) +#else +#define FT_MAX_BLACK_POOL ( 2048 / sizeof ( Long ) ) +#endif + /* The most used variables are positioned at the top of the structure. */ /* Thus, their offset can be coded with less opcodes, resulting in a */ /* smaller executable. */ @@ -514,9 +519,6 @@ Short traceIncr; /* sweep's increment in target bitmap */ - Short gray_min_x; /* current min x during gray rendering */ - Short gray_max_x; /* current max x during gray rendering */ - /* dispatch variables */ Function_Sweep_Init* Proc_Sweep_Init; @@ -529,45 +531,19 @@ Bool second_pass; /* indicates whether a horizontal pass */ /* should be performed to control */ /* drop-out accurately when calling */ - /* Render_Glyph. Note that there is */ - /* no horizontal pass during gray */ - /* rendering. */ + /* Render_Glyph. */ TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ black_TBand band_stack[16]; /* band stack used for sub-banding */ Int band_top; /* band stack top */ -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - Byte* grays; - - Byte gray_lines[RASTER_GRAY_LINES]; - /* Intermediate table used to render the */ - /* graylevels pixmaps. */ - /* gray_lines is a buffer holding two */ - /* monochrome scanlines */ - - Short gray_width; /* width in bytes of one monochrome */ - /* intermediate scanline of gray_lines. */ - /* Each gray pixel takes 2 bits long there */ - - /* The gray_lines must hold 2 lines, thus with size */ - /* in bytes of at least `gray_width*2'. */ - -#endif /* FT_RASTER_ANTI_ALIASING */ - }; typedef struct black_TRaster_ { - char* buffer; - long buffer_size; void* memory; - black_PWorker worker; - Byte grays[5]; - Short gray_width; } black_TRaster, *black_PRaster; @@ -583,70 +559,6 @@ #endif /* !FT_STATIC_RASTER */ -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - /* A lookup table used to quickly count set bits in four gray 2x2 */ - /* cells. The values of the table have been produced with the */ - /* following code: */ - /* */ - /* for ( i = 0; i < 256; i++ ) */ - /* { */ - /* l = 0; */ - /* j = i; */ - /* */ - /* for ( c = 0; c < 4; c++ ) */ - /* { */ - /* l <<= 4; */ - /* */ - /* if ( j & 0x80 ) l++; */ - /* if ( j & 0x40 ) l++; */ - /* */ - /* j = ( j << 2 ) & 0xFF; */ - /* } */ - /* printf( "0x%04X", l ); */ - /* } */ - /* */ - - static const short count_table[256] = - { - 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, - 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, - 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, - 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, - 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, - 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, - 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, - 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, - 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, - 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, - 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, - 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, - 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, - 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, - 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, - 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, - 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, - 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, - 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, - 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, - 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, - 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, - 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 - }; - -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ - - - /*************************************************************************/ /*************************************************************************/ /** **/ @@ -677,11 +589,11 @@ * approximating it as a straight segment. The default value of 32 (for * low accuracy) corresponds to * - * 32 / 64 == 0.5 pixels , + * 32 / 64 == 0.5 pixels, * * while for the high accuracy case we have * - * 256/ (1 << 12) = 0.0625 pixels . + * 256 / (1 << 12) = 0.0625 pixels. * * `precision_jitter' is an epsilon threshold used in * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier @@ -764,13 +676,13 @@ if ( overshoot ) ras.cProfile->flags |= Overshoot_Bottom; - FT_TRACE6(( "New ascending profile = %p\n", ras.cProfile )); + FT_TRACE6(( " new ascending profile = %p\n", ras.cProfile )); break; case Descending_State: if ( overshoot ) ras.cProfile->flags |= Overshoot_Top; - FT_TRACE6(( "New descending profile = %p\n", ras.cProfile )); + FT_TRACE6(( " new descending profile = %p\n", ras.cProfile )); break; default: @@ -825,7 +737,7 @@ PProfile oldProfile; - FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n", + FT_TRACE6(( " ending profile %p, start = %ld, height = %ld\n", ras.cProfile, ras.cProfile->start, h )); ras.cProfile->height = h; @@ -893,15 +805,14 @@ /* if it is <, simply insert it, ignore if == */ if ( n >= 0 && y > y_turns[n] ) - while ( n >= 0 ) + do { Int y2 = (Int)y_turns[n]; y_turns[n] = y; y = y2; - n--; - } + } while ( --n >= 0 ); if ( n < 0 ) { @@ -942,7 +853,7 @@ if ( n > 1 && p ) { - while ( n > 0 ) + do { Int bottom, top; @@ -970,8 +881,7 @@ return FAILURE; p = p->link; - n--; - } + } while ( --n ); } else ras.fProfile = NULL; @@ -1342,7 +1252,7 @@ start_arc = arc; - while ( arc >= start_arc && e <= e2 ) + do { ras.joint = FALSE; @@ -1375,7 +1285,7 @@ } arc -= degree; } - } + } while ( arc >= start_arc && e <= e2 ); Fin: ras.top = top; @@ -1813,7 +1723,7 @@ static Bool Decompose_Curve( RAS_ARGS UShort first, UShort last, - int flipped ) + Int flipped ) { FT_Vector v_last; FT_Vector v_control; @@ -1824,7 +1734,7 @@ FT_Vector* limit; char* tags; - unsigned tag; /* current point's state */ + UInt tag; /* current point's state */ points = ras.outline.points; @@ -1874,7 +1784,7 @@ v_start.x = ( v_start.x + v_last.x ) / 2; v_start.y = ( v_start.y + v_last.y ) / 2; - v_last = v_start; + /* v_last = v_start; */ } point--; tags--; @@ -2035,10 +1945,10 @@ /* rendering. */ /* */ static Bool - Convert_Glyph( RAS_ARGS int flipped ) + Convert_Glyph( RAS_ARGS Int flipped ) { - int i; - unsigned start; + Int i; + UInt start; ras.fProfile = NULL; @@ -2064,12 +1974,12 @@ ras.state = Unknown_State; ras.gProfile = NULL; - if ( Decompose_Curve( RAS_VARS (unsigned short)start, - ras.outline.contours[i], + if ( Decompose_Curve( RAS_VARS (UShort)start, + (UShort)ras.outline.contours[i], flipped ) ) return FAILURE; - start = ras.outline.contours[i] + 1; + start = (UShort)ras.outline.contours[i] + 1; /* we must now check whether the extreme arcs join or not */ if ( FRAC( ras.lastY ) == 0 && @@ -2083,7 +1993,8 @@ /* to be drawn. */ lastProfile = ras.cProfile; - if ( ras.cProfile->flags & Flow_Up ) + if ( ras.top != ras.cProfile->offset && + ( ras.cProfile->flags & Flow_Up ) ) o = IS_TOP_OVERSHOOT( ras.lastY ); else o = IS_BOTTOM_OVERSHOOT( ras.lastY ); @@ -2207,7 +2118,7 @@ while ( current ) { current->X = *current->offset; - current->offset += current->flags & Flow_Up ? 1 : -1; + current->offset += ( current->flags & Flow_Up ) ? 1 : -1; current->height--; current = current->link; } @@ -2267,10 +2178,7 @@ ras.traceIncr = (Short)-pitch; ras.traceOfs = -*min * pitch; if ( pitch > 0 ) - ras.traceOfs += ( ras.target.rows - 1 ) * pitch; - - ras.gray_min_x = 0; - ras.gray_max_x = 0; + ras.traceOfs += (Long)( ras.target.rows - 1 ) * pitch; } @@ -2284,23 +2192,34 @@ Long e1, e2; Byte* target; + Int dropOutControl = left->flags & 7; + FT_UNUSED( y ); FT_UNUSED( left ); FT_UNUSED( right ); + /* in high-precision mode, we need 12 digits after the comma to */ + /* represent multiples of 1/(1<<12) = 1/4096 */ + FT_TRACE7(( " y=%d x=[%.12f;%.12f], drop-out=%d", + y, + x1 / (double)ras.precision, + x2 / (double)ras.precision, + dropOutControl )); + /* Drop-out control */ e1 = TRUNC( CEILING( x1 ) ); - if ( x2 - x1 - ras.precision <= ras.precision_jitter ) + if ( dropOutControl != 2 && + x2 - x1 - ras.precision <= ras.precision_jitter ) e2 = e1; else e2 = TRUNC( FLOOR( x2 ) ); if ( e2 >= 0 && e1 < ras.bWidth ) { - int c1, c2; + Int c1, c2; Byte f1, f2; @@ -2309,17 +2228,14 @@ if ( e2 >= ras.bWidth ) e2 = ras.bWidth - 1; + FT_TRACE7(( " -> x=[%d;%d]", e1, e2 )); + c1 = (Short)( e1 >> 3 ); c2 = (Short)( e2 >> 3 ); f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); - if ( ras.gray_min_x > c1 ) - ras.gray_min_x = (short)c1; - if ( ras.gray_max_x < c2 ) - ras.gray_max_x = (short)c2; - target = ras.bTarget + ras.traceOfs + c1; c2 -= c1; @@ -2341,6 +2257,8 @@ else *target |= ( f1 & f2 ); } + + FT_TRACE7(( "\n" )); } @@ -2355,6 +2273,11 @@ Short c1, f1; + FT_TRACE7(( " y=%d x=[%.12f;%.12f]", + y, + x1 / (double)ras.precision, + x2 / (double)ras.precision )); + /* Drop-out control */ /* e2 x2 x1 e1 */ @@ -2387,6 +2310,8 @@ Int dropOutControl = left->flags & 7; + FT_TRACE7(( ", drop-out=%d", dropOutControl )); + if ( e1 == e2 + ras.precision ) { switch ( dropOutControl ) @@ -2433,14 +2358,14 @@ left->height <= 0 && !( left->flags & Overshoot_Top && x2 - x1 >= ras.precision_half ) ) - return; + goto Exit; /* lower stub test */ if ( right->next == left && left->start == y && !( left->flags & Overshoot_Bottom && x2 - x1 >= ras.precision_half ) ) - return; + goto Exit; if ( dropOutControl == 1 ) pxl = e2; @@ -2449,7 +2374,7 @@ break; default: /* modes 2, 3, 6, 7 */ - return; /* no drop-out control */ + goto Exit; /* no drop-out control */ } /* undocumented but confirmed: If the drop-out would result in a */ @@ -2470,26 +2395,26 @@ if ( e1 >= 0 && e1 < ras.bWidth && ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) - return; + goto Exit; } else - return; + goto Exit; } e1 = TRUNC( pxl ); if ( e1 >= 0 && e1 < ras.bWidth ) { + FT_TRACE7(( " -> x=%d (drop-out)", e1 )); + c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); - if ( ras.gray_min_x > c1 ) - ras.gray_min_x = c1; - if ( ras.gray_max_x < c1 ) - ras.gray_max_x = c1; - ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); } + + Exit: + FT_TRACE7(( "\n" )); } @@ -2536,32 +2461,39 @@ Long e1, e2; + FT_TRACE7(( " x=%d y=[%.12f;%.12f]", + y, + x1 / (double)ras.precision, + x2 / (double)ras.precision )); + e1 = CEILING( x1 ); e2 = FLOOR ( x2 ); if ( e1 == e2 ) { - Byte f1; - PByte bits; - - - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - e1 = TRUNC( e1 ); - if ( e1 >= 0 && e1 < ras.target.rows ) + if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) { + Byte f1; + PByte bits; PByte p; - p = bits - e1 * ras.target.pitch; + FT_TRACE7(( " -> y=%d (drop-out)", e1 )); + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); + p = bits - e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) - p += ( ras.target.rows - 1 ) * ras.target.pitch; + p += (Long)( ras.target.rows - 1 ) * ras.target.pitch; p[0] |= f1; } } + + FT_TRACE7(( "\n" )); } } @@ -2578,6 +2510,11 @@ Byte f1; + FT_TRACE7(( " x=%d y=[%.12f;%.12f]", + y, + x1 / (double)ras.precision, + x2 / (double)ras.precision )); + /* During the horizontal sweep, we only take care of drop-outs */ /* e1 + <-- pixel center */ @@ -2599,6 +2536,8 @@ Int dropOutControl = left->flags & 7; + FT_TRACE7(( ", dropout=%d", dropOutControl )); + if ( e1 == e2 + ras.precision ) { switch ( dropOutControl ) @@ -2620,14 +2559,14 @@ left->height <= 0 && !( left->flags & Overshoot_Top && x2 - x1 >= ras.precision_half ) ) - return; + goto Exit; /* leftmost stub test */ if ( right->next == left && left->start == y && !( left->flags & Overshoot_Bottom && x2 - x1 >= ras.precision_half ) ) - return; + goto Exit; if ( dropOutControl == 1 ) pxl = e2; @@ -2636,7 +2575,7 @@ break; default: /* modes 2, 3, 6, 7 */ - return; /* no drop-out control */ + goto Exit; /* no drop-out control */ } /* undocumented but confirmed: If the drop-out would result in a */ @@ -2644,7 +2583,7 @@ /* bounding box instead */ if ( pxl < 0 ) pxl = e1; - else if ( TRUNC( pxl ) >= ras.target.rows ) + else if ( (ULong)( TRUNC( pxl ) ) >= ras.target.rows ) pxl = e2; /* check that the other pixel isn't set */ @@ -2657,30 +2596,35 @@ bits -= e1 * ras.target.pitch; if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; + bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; - if ( e1 >= 0 && - e1 < ras.target.rows && - *bits & f1 ) - return; + if ( e1 >= 0 && + (ULong)e1 < ras.target.rows && + *bits & f1 ) + goto Exit; } else - return; + goto Exit; } - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - e1 = TRUNC( pxl ); - if ( e1 >= 0 && e1 < ras.target.rows ) + if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) { + FT_TRACE7(( " -> y=%d (drop-out)", e1 )); + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; + bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; bits[0] |= f1; } + + Exit: + FT_TRACE7(( "\n" )); } @@ -2692,249 +2636,6 @@ } -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - - /*************************************************************************/ - /* */ - /* Vertical Gray Sweep Procedure Set */ - /* */ - /* These two routines are used during the vertical gray-levels sweep */ - /* phase by the generic Draw_Sweep() function. */ - /* */ - /* NOTES */ - /* */ - /* - The target pixmap's width *must* be a multiple of 4. */ - /* */ - /* - You have to use the function Vertical_Sweep_Span() for the gray */ - /* span call. */ - /* */ - /*************************************************************************/ - - static void - Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, - Short* max ) - { - Long pitch, byte_len; - - - *min = *min & -2; - *max = ( *max + 3 ) & -2; - - ras.traceOfs = 0; - pitch = ras.target.pitch; - byte_len = -pitch; - ras.traceIncr = (Short)byte_len; - ras.traceG = ( *min / 2 ) * byte_len; - - if ( pitch > 0 ) - { - ras.traceG += ( ras.target.rows - 1 ) * pitch; - byte_len = -byte_len; - } - - ras.gray_min_x = (Short)byte_len; - ras.gray_max_x = -(Short)byte_len; - } - - - static void - Vertical_Gray_Sweep_Step( RAS_ARG ) - { - short* count = (short*)count_table; - Byte* grays; - - - ras.traceOfs += ras.gray_width; - - if ( ras.traceOfs > ras.gray_width ) - { - PByte pix; - - - pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; - grays = ras.grays; - - if ( ras.gray_max_x >= 0 ) - { - Long last_pixel = ras.target.width - 1; - Int last_cell = last_pixel >> 2; - Int last_bit = last_pixel & 3; - Bool over = 0; - - Int c1, c2; - PByte bit, bit2; - - - if ( ras.gray_max_x >= last_cell && last_bit != 3 ) - { - ras.gray_max_x = last_cell - 1; - over = 1; - } - - if ( ras.gray_min_x < 0 ) - ras.gray_min_x = 0; - - bit = ras.bTarget + ras.gray_min_x; - bit2 = bit + ras.gray_width; - - c1 = ras.gray_max_x - ras.gray_min_x; - - while ( c1 >= 0 ) - { - c2 = count[*bit] + count[*bit2]; - - if ( c2 ) - { - pix[0] = grays[(c2 >> 12) & 0x000F]; - pix[1] = grays[(c2 >> 8 ) & 0x000F]; - pix[2] = grays[(c2 >> 4 ) & 0x000F]; - pix[3] = grays[ c2 & 0x000F]; - - *bit = 0; - *bit2 = 0; - } - - bit++; - bit2++; - pix += 4; - c1--; - } - - if ( over ) - { - c2 = count[*bit] + count[*bit2]; - if ( c2 ) - { - switch ( last_bit ) - { - case 2: - pix[2] = grays[(c2 >> 4 ) & 0x000F]; - case 1: - pix[1] = grays[(c2 >> 8 ) & 0x000F]; - default: - pix[0] = grays[(c2 >> 12) & 0x000F]; - } - - *bit = 0; - *bit2 = 0; - } - } - } - - ras.traceOfs = 0; - ras.traceG += ras.traceIncr; - - ras.gray_min_x = 32000; - ras.gray_max_x = -32000; - } - } - - - static void - Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - /* nothing, really */ - FT_UNUSED_RASTER; - FT_UNUSED( y ); - FT_UNUSED( x1 ); - FT_UNUSED( x2 ); - FT_UNUSED( left ); - FT_UNUSED( right ); - } - - - static void - Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - PByte pixel; - - - /* During the horizontal sweep, we only take care of drop-outs */ - - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - - if ( e1 > e2 ) - { - Int dropOutControl = left->flags & 7; - - - if ( e1 == e2 + ras.precision ) - { - switch ( dropOutControl ) - { - case 0: /* simple drop-outs including stubs */ - e1 = e2; - break; - - case 4: /* smart drop-outs including stubs */ - e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - break; - - case 1: /* simple drop-outs excluding stubs */ - case 5: /* smart drop-outs excluding stubs */ - /* see Vertical_Sweep_Drop for details */ - - /* rightmost stub test */ - if ( left->next == right && left->height <= 0 ) - return; - - /* leftmost stub test */ - if ( right->next == left && left->start == y ) - return; - - if ( dropOutControl == 1 ) - e1 = e2; - else - e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - - break; - - default: /* modes 2, 3, 6, 7 */ - return; /* no drop-out control */ - } - } - else - return; - } - - if ( e1 >= 0 ) - { - Byte color; - - - if ( x2 - x1 >= ras.precision_half ) - color = ras.grays[2]; - else - color = ras.grays[1]; - - e1 = TRUNC( e1 ) / 2; - if ( e1 < ras.target.rows ) - { - pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; - if ( ras.target.pitch > 0 ) - pixel += ( ras.target.rows - 1 ) * ras.target.pitch; - - if ( pixel[0] == ras.grays[0] ) - pixel[0] = color; - } - } - } - - -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ - - /*************************************************************************/ /* */ /* Generic Sweep Drawing routine */ @@ -3004,7 +2705,7 @@ while ( P ) { - P->countL = (UShort)( P->start - min_Y ); + P->countL = P->start - min_Y; P = P->link; } @@ -3267,7 +2968,7 @@ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ - FT_LOCAL_DEF( FT_Error ) + static FT_Error Render_Glyph( RAS_ARG ) { FT_Error error; @@ -3290,10 +2991,12 @@ ras.dropOutControl += 1; } - ras.second_pass = (FT_Byte)( !( ras.outline.flags & - FT_OUTLINE_SINGLE_PASS ) ); + ras.second_pass = (Bool)( !( ras.outline.flags & + FT_OUTLINE_SINGLE_PASS ) ); /* Vertical Sweep */ + FT_TRACE7(( "Vertical pass (ftraster)\n" )); + ras.Proc_Sweep_Init = Vertical_Sweep_Init; ras.Proc_Sweep_Span = Vertical_Sweep_Span; ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; @@ -3301,9 +3004,9 @@ ras.band_top = 0; ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = (short)( ras.target.rows - 1 ); + ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 ); - ras.bWidth = (unsigned short)ras.target.width; + ras.bWidth = (UShort)ras.target.width; ras.bTarget = (Byte*)ras.target.buffer; if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) @@ -3312,6 +3015,8 @@ /* Horizontal Sweep */ if ( ras.second_pass && ras.dropOutControl != 2 ) { + FT_TRACE7(( "Horizontal pass (ftraster)\n" )); + ras.Proc_Sweep_Init = Horizontal_Sweep_Init; ras.Proc_Sweep_Span = Horizontal_Sweep_Span; ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; @@ -3319,7 +3024,7 @@ ras.band_top = 0; ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = (short)( ras.target.width - 1 ); + ras.band_stack[0].y_max = (Short)( ras.target.width - 1 ); if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) return error; @@ -3329,118 +3034,10 @@ } -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Render_Gray_Glyph */ - /* */ - /* <Description> */ - /* Render a glyph with grayscaling. Sub-banding if needed. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - Render_Gray_Glyph( RAS_ARG ) - { - Long pixel_width; - FT_Error error; - - - Set_High_Precision( RAS_VARS ras.outline.flags & - FT_OUTLINE_HIGH_PRECISION ); - ras.scale_shift = ras.precision_shift + 1; - - if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) - ras.dropOutControl = 2; - else - { - if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) - ras.dropOutControl = 4; - else - ras.dropOutControl = 0; - - if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) - ras.dropOutControl += 1; - } - - ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); - - /* Vertical Sweep */ - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = 2 * ras.target.rows - 1; - - ras.bWidth = ras.gray_width; - pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); - - if ( ras.bWidth > pixel_width ) - ras.bWidth = pixel_width; - - ras.bWidth = ras.bWidth * 8; - ras.bTarget = (Byte*)ras.gray_lines; - ras.gTarget = (Byte*)ras.target.buffer; - - ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; - ras.Proc_Sweep_Span = Vertical_Sweep_Span; - ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; - ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; - - error = Render_Single_Pass( RAS_VARS 0 ); - if ( error ) - return error; - - /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 2 ) - { - ras.Proc_Sweep_Init = Horizontal_Sweep_Init; - ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; - ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; - ras.Proc_Sweep_Step = Horizontal_Sweep_Step; - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = ras.target.width * 2 - 1; - - error = Render_Single_Pass( RAS_VARS 1 ); - if ( error ) - return error; - } - - return Raster_Err_None; - } - -#else /* !FT_RASTER_OPTION_ANTI_ALIASING */ - - FT_LOCAL_DEF( FT_Error ) - Render_Gray_Glyph( RAS_ARG ) - { - FT_UNUSED_RASTER; - - return FT_THROW( Unsupported ); - } - -#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */ - - static void ft_black_init( black_PRaster raster ) { -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - FT_UInt n; - - - /* set default 5-levels gray palette */ - for ( n = 0; n < 5; n++ ) - raster->grays[n] = n * 255 / 4; - - raster->gray_width = RASTER_GRAY_LINES / 2; -#else FT_UNUSED( raster ); -#endif } @@ -3448,7 +3045,7 @@ /**** a static object. *****/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ static int @@ -3475,7 +3072,7 @@ } -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ static int @@ -3509,73 +3106,46 @@ } -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ static void - ft_black_reset( black_PRaster raster, - char* pool_base, - long pool_size ) + ft_black_reset( FT_Raster raster, + PByte pool_base, + ULong pool_size ) { - if ( raster ) - { - if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 ) - { - black_PWorker worker = (black_PWorker)pool_base; - - - raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 ); - raster->buffer_size = (long)( pool_base + pool_size - - (char*)raster->buffer ); - raster->worker = worker; - } - else - { - raster->buffer = NULL; - raster->buffer_size = 0; - raster->worker = NULL; - } - } + FT_UNUSED( raster ); + FT_UNUSED( pool_base ); + FT_UNUSED( pool_size ); } - static void - ft_black_set_mode( black_PRaster raster, - unsigned long mode, - const char* palette ) + static int + ft_black_set_mode( FT_Raster raster, + ULong mode, + void* args ) { -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) - { - /* set 5-levels gray palette */ - raster->grays[0] = palette[0]; - raster->grays[1] = palette[1]; - raster->grays[2] = palette[2]; - raster->grays[3] = palette[3]; - raster->grays[4] = palette[4]; - } - -#else - FT_UNUSED( raster ); FT_UNUSED( mode ); - FT_UNUSED( palette ); + FT_UNUSED( args ); -#endif + return 0; } static int - ft_black_render( black_PRaster raster, + ft_black_render( FT_Raster raster, const FT_Raster_Params* params ) { const FT_Outline* outline = (const FT_Outline*)params->source; const FT_Bitmap* target_map = params->target; - black_PWorker worker; + black_TWorker worker[1]; + + Long buffer[FT_MAX_BLACK_POOL]; - if ( !raster || !raster->buffer || !raster->buffer_size ) + + if ( !raster ) return FT_THROW( Not_Ini ); if ( !outline ) @@ -3592,12 +3162,13 @@ outline->contours[outline->n_contours - 1] + 1 ) return FT_THROW( Invalid ); - worker = raster->worker; - /* this version of the raster does not support direct rendering, sorry */ if ( params->flags & FT_RASTER_FLAG_DIRECT ) return FT_THROW( Unsupported ); + if ( params->flags & FT_RASTER_FLAG_AA ) + return FT_THROW( Unsupported ); + if ( !target_map ) return FT_THROW( Invalid ); @@ -3608,33 +3179,40 @@ if ( !target_map->buffer ) return FT_THROW( Invalid ); + /* reject too large outline coordinates */ + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + for ( ; vec < limit; vec++ ) + { + if ( vec->x < -0x1000000L || vec->x > 0x1000000L || + vec->y < -0x1000000L || vec->y > 0x1000000L ) + return FT_THROW( Invalid ); + } + } + ras.outline = *outline; ras.target = *target_map; - worker->buff = (PLong) raster->buffer; - worker->sizeBuff = worker->buff + - raster->buffer_size / sizeof ( Long ); -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - worker->grays = raster->grays; - worker->gray_width = raster->gray_width; + worker->buff = buffer; + worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ - FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); -#endif - - return ( params->flags & FT_RASTER_FLAG_AA ) - ? Render_Gray_Glyph( RAS_VAR ) - : Render_Glyph( RAS_VAR ); + return Render_Glyph( RAS_VAR ); } - FT_DEFINE_RASTER_FUNCS( ft_standard_raster, + FT_DEFINE_RASTER_FUNCS( + ft_standard_raster, + FT_GLYPH_FORMAT_OUTLINE, + (FT_Raster_New_Func) ft_black_new, (FT_Raster_Reset_Func) ft_black_reset, (FT_Raster_Set_Mode_Func)ft_black_set_mode, (FT_Raster_Render_Func) ft_black_render, - (FT_Raster_Done_Func) ft_black_done - ) + (FT_Raster_Done_Func) ft_black_done ) /* END */ diff --git a/drivers/freetype/freetype/src/raster/ftraster.h b/drivers/freetype/src/raster/ftraster.h index 80fe46deba..65cd5f9609 100644 --- a/drivers/freetype/freetype/src/raster/ftraster.h +++ b/drivers/freetype/src/raster/ftraster.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTRASTER_H__ -#define __FTRASTER_H__ +#ifndef FTRASTER_H_ +#define FTRASTER_H_ #include <ft2build.h> @@ -33,14 +33,14 @@ FT_BEGIN_HEADER /* Uncomment the following line if you are using ftraster.c as a */ /* standalone module, fully independent of FreeType. */ /* */ -/* #define _STANDALONE_ */ +/* #define STANDALONE_ */ FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_standard_raster; FT_END_HEADER -#endif /* __FTRASTER_H__ */ +#endif /* FTRASTER_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/raster/ftrend1.c b/drivers/freetype/src/raster/ftrend1.c index aa7f6d5664..494f112234 100644 --- a/drivers/freetype/freetype/src/raster/ftrend1.c +++ b/drivers/freetype/src/raster/ftrend1.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer interface (body). */ /* */ -/* Copyright 1996-2003, 2005, 2006, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -104,7 +104,7 @@ { FT_Error error; FT_Outline* outline; - FT_BBox cbox; + FT_BBox cbox, cbox0; FT_UInt width, height, pitch; FT_Bitmap* bitmap; FT_Memory memory; @@ -120,38 +120,11 @@ } /* check rendering mode */ -#ifndef FT_CONFIG_OPTION_PIC if ( mode != FT_RENDER_MODE_MONO ) { /* raster1 is only capable of producing monochrome bitmaps */ - if ( render->clazz == &ft_raster1_renderer_class ) - return FT_THROW( Cannot_Render_Glyph ); + return FT_THROW( Cannot_Render_Glyph ); } - else - { - /* raster5 is only capable of producing 5-gray-levels bitmaps */ - if ( render->clazz == &ft_raster5_renderer_class ) - return FT_THROW( Cannot_Render_Glyph ); - } -#else /* FT_CONFIG_OPTION_PIC */ - /* When PIC is enabled, we cannot get to the class object */ - /* so instead we check the final character in the class name */ - /* ("raster5" or "raster1"). Yes this is a hack. */ - /* The "correct" thing to do is have different render function */ - /* for each of the classes. */ - if ( mode != FT_RENDER_MODE_MONO ) - { - /* raster1 is only capable of producing monochrome bitmaps */ - if ( render->clazz->root.module_name[6] == '1' ) - return FT_THROW( Cannot_Render_Glyph ); - } - else - { - /* raster5 is only capable of producing 5-gray-levels bitmaps */ - if ( render->clazz->root.module_name[6] == '5' ) - return FT_THROW( Cannot_Render_Glyph ); - } -#endif /* FT_CONFIG_OPTION_PIC */ outline = &slot->outline; @@ -160,14 +133,14 @@ FT_Outline_Translate( outline, origin->x, origin->y ); /* compute the control box, and grid fit it */ - FT_Outline_Get_CBox( outline, &cbox ); + FT_Outline_Get_CBox( outline, &cbox0 ); /* undocumented but confirmed: bbox values get rounded */ #if 1 - cbox.xMin = FT_PIX_ROUND( cbox.xMin ); - cbox.yMin = FT_PIX_ROUND( cbox.yMin ); - cbox.xMax = FT_PIX_ROUND( cbox.xMax ); - cbox.yMax = FT_PIX_ROUND( cbox.yMax ); + cbox.xMin = FT_PIX_ROUND( cbox0.xMin ); + cbox.yMin = FT_PIX_ROUND( cbox0.yMin ); + cbox.xMax = FT_PIX_ROUND( cbox0.xMax ); + cbox.yMax = FT_PIX_ROUND( cbox0.yMax ); #else cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); @@ -175,8 +148,28 @@ cbox.yMax = FT_PIX_CEIL( cbox.yMax ); #endif + /* If either `width' or `height' round to 0, try */ + /* explicitly rounding up/down. In the case of */ + /* glyphs containing only one very narrow feature, */ + /* this gives the drop-out compensation in the scan */ + /* conversion code a chance to do its stuff. */ width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); + if ( width == 0 ) + { + cbox.xMin = FT_PIX_FLOOR( cbox0.xMin ); + cbox.xMax = FT_PIX_CEIL( cbox0.xMax ); + + width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); + } + height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); + if ( height == 0 ) + { + cbox.yMin = FT_PIX_FLOOR( cbox0.yMin ); + cbox.yMax = FT_PIX_CEIL( cbox0.yMax ); + + height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); + } if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX ) { @@ -194,23 +187,12 @@ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } - /* allocate new one, depends on pixel format */ - if ( !( mode & FT_RENDER_MODE_MONO ) ) - { - /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ - pitch = FT_PAD_CEIL( width, 4 ); - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; - bitmap->num_grays = 256; - } - else - { - pitch = ( ( width + 15 ) >> 4 ) << 1; - bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - } + pitch = ( ( width + 15 ) >> 4 ) << 1; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; bitmap->width = width; bitmap->rows = height; - bitmap->pitch = pitch; + bitmap->pitch = (int)pitch; if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) ) goto Exit; @@ -225,9 +207,6 @@ params.source = outline; params.flags = 0; - if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY ) - params.flags |= FT_RASTER_FLAG_AA; - /* render outline into the bitmap */ error = render->raster_render( render->raster, ¶ms ); @@ -272,35 +251,4 @@ ) - /* This renderer is _NOT_ part of the default modules; you will need */ - /* to register it by hand in your application. It should only be */ - /* used for backwards-compatibility with FT 1.x anyway. */ - /* */ - FT_DEFINE_RENDERER( ft_raster5_renderer_class, - - FT_MODULE_RENDERER, - sizeof ( FT_RendererRec ), - - "raster5", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , - - FT_GLYPH_FORMAT_OUTLINE, - - (FT_Renderer_RenderFunc) ft_raster1_render, - (FT_Renderer_TransformFunc)ft_raster1_transform, - (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, - (FT_Renderer_SetModeFunc) ft_raster1_set_mode, - - (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET - ) - - /* END */ diff --git a/drivers/freetype/freetype/src/raster/ftrend1.h b/drivers/freetype/src/raster/ftrend1.h index 4cf128622a..a431f185d2 100644 --- a/drivers/freetype/freetype/src/raster/ftrend1.h +++ b/drivers/freetype/src/raster/ftrend1.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer interface (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTREND1_H__ -#define __FTREND1_H__ +#ifndef FTREND1_H_ +#define FTREND1_H_ #include <ft2build.h> @@ -29,16 +29,10 @@ FT_BEGIN_HEADER FT_DECLARE_RENDERER( ft_raster1_renderer_class ) - /* this renderer is _NOT_ part of the default modules, you'll need */ - /* to register it by hand in your application. It should only be */ - /* used for backwards-compatibility with FT 1.x anyway. */ - /* */ - FT_DECLARE_RENDERER( ft_raster5_renderer_class ) - FT_END_HEADER -#endif /* __FTREND1_H__ */ +#endif /* FTREND1_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/raster/module.mk b/drivers/freetype/src/raster/module.mk index cbff5df96e..f4a5f8e838 100644 --- a/drivers/freetype/freetype/src/raster/module.mk +++ b/drivers/freetype/src/raster/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/raster/raster.c b/drivers/freetype/src/raster/raster.c index 1202a116cd..5b21dcbc6a 100644 --- a/drivers/freetype/freetype/src/raster/raster.c +++ b/drivers/freetype/src/raster/raster.c @@ -4,7 +4,7 @@ /* */ /* FreeType monochrome rasterer module component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/raster/rasterrs.h b/drivers/freetype/src/raster/rasterrs.h index ab85c002a3..44da7fca56 100644 --- a/drivers/freetype/freetype/src/raster/rasterrs.h +++ b/drivers/freetype/src/raster/rasterrs.h @@ -4,7 +4,7 @@ /* */ /* monochrome renderer error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __RASTERRS_H__ -#define __RASTERRS_H__ +#ifndef RASTERRS_H_ +#define RASTERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX Raster_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __RASTERRS_H__ */ +#endif /* RASTERRS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/raster/rastpic.c b/drivers/freetype/src/raster/rastpic.c index 5e9f7cc9c4..dcfa92eef7 100644 --- a/drivers/freetype/freetype/src/raster/rastpic.c +++ b/drivers/freetype/src/raster/rastpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for raster module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -59,8 +59,9 @@ FT_Memory memory = library->memory; - /* since this function also serves raster5 renderer, */ - /* it implements reference counting */ + /* XXX: since this function also served the no longer available */ + /* raster5 renderer it uses reference counting, which could */ + /* be removed now */ if ( pic_container->raster ) { ((RasterPIC*)pic_container->raster)->ref_count++; @@ -82,21 +83,6 @@ return error; } - - /* re-route these init and free functions to the above functions */ - FT_Error - ft_raster5_renderer_class_pic_init( FT_Library library ) - { - return ft_raster1_renderer_class_pic_init( library ); - } - - - void - ft_raster5_renderer_class_pic_free( FT_Library library ) - { - ft_raster1_renderer_class_pic_free( library ); - } - #endif /* FT_CONFIG_OPTION_PIC */ diff --git a/drivers/freetype/freetype/src/raster/rastpic.h b/drivers/freetype/src/raster/rastpic.h index e0ddba624e..7815876383 100644 --- a/drivers/freetype/freetype/src/raster/rastpic.h +++ b/drivers/freetype/src/raster/rastpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for raster module. */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,15 +16,15 @@ /***************************************************************************/ -#ifndef __RASTPIC_H__ -#define __RASTPIC_H__ +#ifndef RASTPIC_H_ +#define RASTPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H +FT_BEGIN_HEADER + #ifndef FT_CONFIG_OPTION_PIC #define FT_STANDARD_RASTER_GET ft_standard_raster @@ -48,22 +48,16 @@ FT_BEGIN_HEADER void ft_raster1_renderer_class_pic_free( FT_Library library ); - void - ft_raster5_renderer_class_pic_free( FT_Library library ); - FT_Error ft_raster1_renderer_class_pic_init( FT_Library library ); - FT_Error - ft_raster5_renderer_class_pic_init( FT_Library library ); - #endif /* FT_CONFIG_OPTION_PIC */ /* */ FT_END_HEADER -#endif /* __RASTPIC_H__ */ +#endif /* RASTPIC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/raster/rules.mk b/drivers/freetype/src/raster/rules.mk index 0e0b5e4ebd..929faa3a95 100644 --- a/drivers/freetype/freetype/src/raster/rules.mk +++ b/drivers/freetype/src/raster/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003, 2008, 2009, 2011 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -19,7 +19,10 @@ RASTER_DIR := $(SRC_DIR)/raster # compilation flags for the driver # -RASTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(RASTER_DIR)) +RASTER_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(RASTER_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # raster driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/sfnt/Jamfile b/drivers/freetype/src/sfnt/Jamfile index cb20b1b04b..089cc269ba 100644 --- a/drivers/freetype/freetype/src/sfnt/Jamfile +++ b/drivers/freetype/src/sfnt/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/sfnt Jamfile # -# Copyright 2001, 2002, 2004, 2005 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,18 @@ SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; if $(FT2_MULTI) { - _sources = sfobjs sfdriver ttcmap ttmtx ttpost ttload ttsbit ttkern ttbdf sfntpic ; + _sources = pngshim + sfdriver + sfntpic + sfobjs + ttbdf + ttcmap + ttkern + ttload + ttmtx + ttpost + ttsbit + ; } else { diff --git a/drivers/freetype/freetype/src/sfnt/module.mk b/drivers/freetype/src/sfnt/module.mk index 95fd6a3143..ca19e096a3 100644 --- a/drivers/freetype/freetype/src/sfnt/module.mk +++ b/drivers/freetype/src/sfnt/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/sfnt/pngshim.c b/drivers/freetype/src/sfnt/pngshim.c index 408f879c34..2815759ccb 100644 --- a/drivers/freetype/freetype/src/sfnt/pngshim.c +++ b/drivers/freetype/src/sfnt/pngshim.c @@ -4,7 +4,8 @@ /* */ /* PNG Bitmap glyph support. */ /* */ -/* Copyright 2013 by Google, Inc. */ +/* Copyright 2013-2016 by */ +/* Google, Inc. */ /* Written by Stuart Gill and Behdad Esfahbod. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,11 +37,11 @@ /* This code is freely based on cairo-png.c. There's so many ways */ /* to call libpng, and the way cairo does it is defacto standard. */ - static int - multiply_alpha( int alpha, - int color ) + static unsigned int + multiply_alpha( unsigned int alpha, + unsigned int color ) { - int temp = ( alpha * color ) + 0x80; + unsigned int temp = alpha * color + 0x80; return ( temp + ( temp >> 8 ) ) >> 8; @@ -81,10 +82,10 @@ blue = multiply_alpha( alpha, blue ); } - base[0] = blue; - base[1] = green; - base[2] = red; - base[3] = alpha; + base[0] = (unsigned char)blue; + base[1] = (unsigned char)green; + base[2] = (unsigned char)red; + base[3] = (unsigned char)alpha; } } } @@ -109,9 +110,9 @@ unsigned int blue = base[2]; - base[0] = blue; - base[1] = green; - base[2] = red; + base[0] = (unsigned char)blue; + base[1] = (unsigned char)green; + base[2] = (unsigned char)red; base[3] = 0xFF; } } @@ -122,14 +123,14 @@ error_callback( png_structp png, png_const_charp error_msg ) { - FT_Error* error = png_get_error_ptr( png ); + FT_Error* error = (FT_Error*)png_get_error_ptr( png ); FT_UNUSED( error_msg ); *error = FT_THROW( Out_Of_Memory ); #ifdef PNG_SETJMP_SUPPORTED - longjmp( png_jmpbuf( png ), 1 ); + ft_longjmp( png_jmpbuf( png ), 1 ); #endif /* if we get here, then we have no choice but to abort ... */ } @@ -159,7 +160,7 @@ if ( FT_FRAME_ENTER( length ) ) { - FT_Error* e = png_get_error_ptr( png ); + FT_Error* e = (FT_Error*)png_get_error_ptr( png ); *e = FT_THROW( Invalid_Stream_Read ); @@ -174,16 +175,18 @@ } - static FT_Error - Load_SBit_Png( FT_Bitmap* map, + FT_LOCAL_DEF( FT_Error ) + Load_SBit_Png( FT_GlyphSlot slot, FT_Int x_offset, FT_Int y_offset, FT_Int pix_bits, TT_SBit_Metrics metrics, FT_Memory memory, FT_Byte* data, - FT_UInt png_len ) + FT_UInt png_len, + FT_Bool populate_map_and_metrics ) { + FT_Bitmap *map = &slot->bitmap; FT_Error error = FT_Err_Ok; FT_StreamRec stream; @@ -193,12 +196,21 @@ int bitdepth, color_type, interlace; FT_Int i; - png_byte* *rows; + png_byte* *rows = NULL; /* pacify compiler */ - if ( x_offset < 0 || x_offset + metrics->width > map->width || - y_offset < 0 || y_offset + metrics->height > map->rows || - pix_bits != 32 || map->pixel_mode != FT_PIXEL_MODE_BGRA ) + if ( x_offset < 0 || + y_offset < 0 ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( !populate_map_and_metrics && + ( (FT_UInt)x_offset + metrics->width > map->width || + (FT_UInt)y_offset + metrics->height > map->rows || + pix_bits != 32 || + map->pixel_mode != FT_PIXEL_MODE_BGRA ) ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -238,11 +250,41 @@ &bitdepth, &color_type, &interlace, NULL, NULL ); - if ( error != FT_Err_Ok || - (FT_Int)imgWidth != metrics->width || - (FT_Int)imgHeight != metrics->height ) + if ( error || + ( !populate_map_and_metrics && + ( (FT_Int)imgWidth != metrics->width || + (FT_Int)imgHeight != metrics->height ) ) ) goto DestroyExit; + if ( populate_map_and_metrics ) + { + FT_ULong size; + + + metrics->width = (FT_UShort)imgWidth; + metrics->height = (FT_UShort)imgHeight; + + map->width = metrics->width; + map->rows = metrics->height; + map->pixel_mode = FT_PIXEL_MODE_BGRA; + map->pitch = (int)( map->width * 4 ); + map->num_grays = 256; + + /* reject too large bitmaps similarly to the rasterizer */ + if ( map->rows > 0x7FFF || map->width > 0x7FFF ) + { + error = FT_THROW( Array_Too_Large ); + goto DestroyExit; + } + + /* this doesn't overflow: 0x7FFF * 0x7FFF * 4 < 2^32 */ + size = map->rows * (FT_ULong)map->pitch; + + error = ft_glyphslot_alloc_bitmap( slot, size ); + if ( error ) + goto DestroyExit; + } + /* convert palette/gray image to rgb */ if ( color_type == PNG_COLOR_TYPE_PALETTE ) png_set_palette_to_rgb( png ); diff --git a/drivers/freetype/freetype/src/sfnt/pngshim.h b/drivers/freetype/src/sfnt/pngshim.h index 8a2e69ccf9..ff05871332 100644 --- a/drivers/freetype/freetype/src/sfnt/pngshim.h +++ b/drivers/freetype/src/sfnt/pngshim.h @@ -4,7 +4,8 @@ /* */ /* PNG Bitmap glyph support. */ /* */ -/* Copyright 2013 by Google, Inc. */ +/* Copyright 2013-2016 by */ +/* Google, Inc. */ /* Written by Stuart Gill and Behdad Esfahbod. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +17,8 @@ /***************************************************************************/ -#ifndef __PNGSHIM_H__ -#define __PNGSHIM_H__ +#ifndef PNGSHIM_H_ +#define PNGSHIM_H_ #include <ft2build.h> @@ -29,20 +30,21 @@ FT_BEGIN_HEADER #ifdef FT_CONFIG_OPTION_USE_PNG FT_LOCAL( FT_Error ) - Load_SBit_Png( FT_Bitmap* map, + Load_SBit_Png( FT_GlyphSlot slot, FT_Int x_offset, FT_Int y_offset, FT_Int pix_bits, TT_SBit_Metrics metrics, FT_Memory memory, FT_Byte* data, - FT_UInt png_len ); + FT_UInt png_len, + FT_Bool populate_map_and_metrics ); #endif FT_END_HEADER -#endif /* __PNGSHIM_H__ */ +#endif /* PNGSHIM_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/rules.mk b/drivers/freetype/src/sfnt/rules.mk index a6c956ab65..e9fc421567 100644 --- a/drivers/freetype/freetype/src/sfnt/rules.mk +++ b/drivers/freetype/src/sfnt/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002-2007, 2009, 2011, 2013 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ SFNT_DIR := $(SRC_DIR)/sfnt # compilation flags for the driver # -SFNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR)) +SFNT_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # SFNT driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/sfnt/sfdriver.c b/drivers/freetype/src/sfnt/sfdriver.c index a368b8caea..47e8967752 100644 --- a/drivers/freetype/freetype/src/sfnt/sfdriver.c +++ b/drivers/freetype/src/sfnt/sfdriver.c @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (body). */ /* */ -/* Copyright 1996-2007, 2009-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -75,36 +75,36 @@ switch ( tag ) { - case ft_sfnt_head: + case FT_SFNT_HEAD: table = &face->header; break; - case ft_sfnt_hhea: + case FT_SFNT_HHEA: table = &face->horizontal; break; - case ft_sfnt_vhea: - table = face->vertical_info ? &face->vertical : 0; + case FT_SFNT_VHEA: + table = face->vertical_info ? &face->vertical : NULL; break; - case ft_sfnt_os2: - table = face->os2.version == 0xFFFFU ? 0 : &face->os2; + case FT_SFNT_OS2: + table = face->os2.version == 0xFFFFU ? NULL : &face->os2; break; - case ft_sfnt_post: + case FT_SFNT_POST: table = &face->postscript; break; - case ft_sfnt_maxp: + case FT_SFNT_MAXP: table = &face->max_profile; break; - case ft_sfnt_pclt: - table = face->pclt.Version ? &face->pclt : 0; + case FT_SFNT_PCLT: + table = face->pclt.Version ? &face->pclt : NULL; break; default: - table = 0; + table = NULL; } return table; @@ -139,9 +139,9 @@ FT_DEFINE_SERVICE_SFNT_TABLEREC( sfnt_service_sfnt_table, - (FT_SFNT_TableLoadFunc)tt_face_load_any, - (FT_SFNT_TableGetFunc) get_sfnt_table, - (FT_SFNT_TableInfoFunc)sfnt_table_info ) + (FT_SFNT_TableLoadFunc)tt_face_load_any, /* load_table */ + (FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */ + (FT_SFNT_TableInfoFunc)sfnt_table_info ) /* table_info */ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -205,8 +205,8 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( sfnt_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index ) + (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index ) /* name_index */ #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -266,7 +266,7 @@ { FT_Stream stream = face->name_table.stream; FT_String* r = (FT_String*)result; - FT_Byte* p = (FT_Byte*)name->string; + FT_Char* p; if ( FT_STREAM_SEEK( name->stringOffset ) || @@ -280,11 +280,11 @@ goto Exit; } - p = (FT_Byte*)stream->cursor; + p = (FT_Char*)stream->cursor; for ( ; len > 0; len--, p += 2 ) { - if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 ) + if ( p[0] == 0 && p[1] >= 32 ) *r++ = p[1]; } *r = '\0'; @@ -330,7 +330,7 @@ FT_DEFINE_SERVICE_PSFONTNAMEREC( sfnt_service_ps_name, - (FT_PsName_GetFunc)sfnt_get_ps_name ) + (FT_PsName_GetFunc)sfnt_get_ps_name ) /* get_ps_font_name */ /* @@ -338,7 +338,7 @@ */ FT_DEFINE_SERVICE_TTCMAPSREC( tt_service_get_cmap_info, - (TT_CMap_Info_GetFunc)tt_get_cmap_info ) + (TT_CMap_Info_GetFunc)tt_get_cmap_info ) /* get_cmap_info */ #ifdef TT_CONFIG_OPTION_BDF @@ -381,8 +381,8 @@ FT_DEFINE_SERVICE_BDFRec( sfnt_service_bdf, - (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop ) + (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, /* get_charset_id */ + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop ) /* get_property */ #endif /* TT_CONFIG_OPTION_BDF */ @@ -427,7 +427,7 @@ sfnt_get_interface( FT_Module module, const char* module_interface ) { - /* SFNT_SERVICES_GET derefers `library' in PIC mode */ + /* SFNT_SERVICES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC FT_Library library; @@ -499,13 +499,15 @@ tt_face_load_hmtx, /* see `ttsbit.h' and `sfnt.h' */ - PUT_EMBEDDED_BITMAPS( tt_face_load_eblc ), - PUT_EMBEDDED_BITMAPS( tt_face_free_eblc ), + PUT_EMBEDDED_BITMAPS( tt_face_load_sbit ), + PUT_EMBEDDED_BITMAPS( tt_face_free_sbit ), PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), - tt_face_get_metrics + tt_face_get_metrics, + + tt_face_get_name ) diff --git a/drivers/freetype/freetype/src/sfnt/sfdriver.h b/drivers/freetype/src/sfnt/sfdriver.h index 5de25d51ca..2694488e20 100644 --- a/drivers/freetype/freetype/src/sfnt/sfdriver.h +++ b/drivers/freetype/src/sfnt/sfdriver.h @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFDRIVER_H__ -#define __SFDRIVER_H__ +#ifndef SFDRIVER_H_ +#define SFDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SFDRIVER_H__ */ +#endif /* SFDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/sferrors.h b/drivers/freetype/src/sfnt/sferrors.h index e981e1d26f..c2f9fdfead 100644 --- a/drivers/freetype/freetype/src/sfnt/sferrors.h +++ b/drivers/freetype/src/sfnt/sferrors.h @@ -4,7 +4,7 @@ /* */ /* SFNT error codes (specification only). */ /* */ -/* Copyright 2001, 2004, 2012, 2013 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __SFERRORS_H__ -#define __SFERRORS_H__ +#ifndef SFERRORS_H_ +#define SFERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX SFNT_Err_ @@ -35,6 +35,7 @@ #include FT_ERRORS_H -#endif /* __SFERRORS_H__ */ +#endif /* SFERRORS_H_ */ + /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/sfnt.c b/drivers/freetype/src/sfnt/sfnt.c index d62ed4e0b5..952d6d425a 100644 --- a/drivers/freetype/freetype/src/sfnt/sfnt.c +++ b/drivers/freetype/src/sfnt/sfnt.c @@ -4,7 +4,7 @@ /* */ /* Single object library component. */ /* */ -/* Copyright 1996-2006, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/sfnt/sfntpic.c b/drivers/freetype/src/sfnt/sfntpic.c index b3fb24b3f0..1f596c0936 100644 --- a/drivers/freetype/freetype/src/sfnt/sfntpic.c +++ b/drivers/freetype/src/sfnt/sfntpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for sfnt module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/sfnt/sfntpic.h b/drivers/freetype/src/sfnt/sfntpic.h index b09a9141e0..5ce96d3938 100644 --- a/drivers/freetype/freetype/src/sfnt/sfntpic.h +++ b/drivers/freetype/src/sfnt/sfntpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for sfnt module. */ /* */ -/* Copyright 2009, 2012 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,10 @@ /***************************************************************************/ -#ifndef __SFNTPIC_H__ -#define __SFNTPIC_H__ +#ifndef SFNTPIC_H_ +#define SFNTPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H @@ -31,7 +29,6 @@ FT_BEGIN_HEADER #define SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict #define SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name #define TT_SERVICE_CMAP_INFO_GET tt_service_get_cmap_info -#define SFNT_SERVICES_GET sfnt_services #define TT_CMAP_CLASSES_GET tt_cmap_classes #define SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table #define SFNT_SERVICE_BDF_GET sfnt_service_bdf @@ -56,6 +53,8 @@ FT_BEGIN_HEADER #include "ttcmap.h" +FT_BEGIN_HEADER + typedef struct sfntModulePIC_ { FT_ServiceDescRec* sfnt_services; @@ -83,8 +82,6 @@ FT_BEGIN_HEADER ( GET_PIC( library )->sfnt_service_ps_name ) #define TT_SERVICE_CMAP_INFO_GET \ ( GET_PIC( library )->tt_service_get_cmap_info ) -#define SFNT_SERVICES_GET \ - ( GET_PIC( library )->sfnt_services ) #define TT_CMAP_CLASSES_GET \ ( GET_PIC( library )->tt_cmap_classes ) #define SFNT_SERVICE_SFNT_TABLE_GET \ @@ -102,13 +99,14 @@ FT_BEGIN_HEADER FT_Error sfnt_module_class_pic_init( FT_Library library ); + +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - -#endif /* __SFNTPIC_H__ */ +#endif /* SFNTPIC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/sfobjs.c b/drivers/freetype/src/sfnt/sfobjs.c index f975e71c3b..2e8c1ecde6 100644 --- a/drivers/freetype/freetype/src/sfnt/sfobjs.c +++ b/drivers/freetype/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2008, 2010-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,6 +27,7 @@ #include FT_TRUETYPE_TAGS_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SFNT_NAMES_H +#include FT_GZIP_H #include "sferrors.h" #ifdef TT_CONFIG_OPTION_BDF @@ -119,27 +120,9 @@ FT_Memory memory ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_get_name */ - /* */ - /* <Description> */ - /* Returns a given ENGLISH name record in ASCII. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* nameid :: The name id of the name record to return. */ - /* */ - /* <InOut> */ - /* name :: The address of a string pointer. NULL if no name is */ - /* present. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - static FT_Error + /* documentation is in sfnt.h */ + + FT_LOCAL_DEF( FT_Error ) tt_face_get_name( TT_Face face, FT_UShort nameid, FT_String** name ) @@ -347,6 +330,403 @@ } +#define WRITE_USHORT( p, v ) \ + do \ + { \ + *(p)++ = (FT_Byte)( (v) >> 8 ); \ + *(p)++ = (FT_Byte)( (v) >> 0 ); \ + \ + } while ( 0 ) + +#define WRITE_ULONG( p, v ) \ + do \ + { \ + *(p)++ = (FT_Byte)( (v) >> 24 ); \ + *(p)++ = (FT_Byte)( (v) >> 16 ); \ + *(p)++ = (FT_Byte)( (v) >> 8 ); \ + *(p)++ = (FT_Byte)( (v) >> 0 ); \ + \ + } while ( 0 ) + + + static void + sfnt_stream_close( FT_Stream stream ) + { + FT_Memory memory = stream->memory; + + + FT_FREE( stream->base ); + + stream->size = 0; + stream->base = NULL; + stream->close = NULL; + } + + + FT_CALLBACK_DEF( int ) + compare_offsets( const void* a, + const void* b ) + { + WOFF_Table table1 = *(WOFF_Table*)a; + WOFF_Table table2 = *(WOFF_Table*)b; + + FT_ULong offset1 = table1->Offset; + FT_ULong offset2 = table2->Offset; + + + if ( offset1 > offset2 ) + return 1; + else if ( offset1 < offset2 ) + return -1; + else + return 0; + } + + + /* Replace `face->root.stream' with a stream containing the extracted */ + /* SFNT of a WOFF font. */ + + static FT_Error + woff_open_font( FT_Stream stream, + TT_Face face ) + { + FT_Memory memory = stream->memory; + FT_Error error = FT_Err_Ok; + + WOFF_HeaderRec woff; + WOFF_Table tables = NULL; + WOFF_Table* indices = NULL; + + FT_ULong woff_offset; + + FT_Byte* sfnt = NULL; + FT_Stream sfnt_stream = NULL; + + FT_Byte* sfnt_header; + FT_ULong sfnt_offset; + + FT_Int nn; + FT_ULong old_tag = 0; + + static const FT_Frame_Field woff_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WOFF_HeaderRec + + FT_FRAME_START( 44 ), + FT_FRAME_ULONG ( signature ), + FT_FRAME_ULONG ( flavor ), + FT_FRAME_ULONG ( length ), + FT_FRAME_USHORT( num_tables ), + FT_FRAME_USHORT( reserved ), + FT_FRAME_ULONG ( totalSfntSize ), + FT_FRAME_USHORT( majorVersion ), + FT_FRAME_USHORT( minorVersion ), + FT_FRAME_ULONG ( metaOffset ), + FT_FRAME_ULONG ( metaLength ), + FT_FRAME_ULONG ( metaOrigLength ), + FT_FRAME_ULONG ( privOffset ), + FT_FRAME_ULONG ( privLength ), + FT_FRAME_END + }; + + + FT_ASSERT( stream == face->root.stream ); + FT_ASSERT( FT_STREAM_POS() == 0 ); + + if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) ) + return error; + + /* Make sure we don't recurse back here or hit TTC code. */ + if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf ) + return FT_THROW( Invalid_Table ); + + /* Miscellaneous checks. */ + if ( woff.length != stream->size || + woff.num_tables == 0 || + 44 + woff.num_tables * 20UL >= woff.length || + 12 + woff.num_tables * 16UL >= woff.totalSfntSize || + ( woff.totalSfntSize & 3 ) != 0 || + ( woff.metaOffset == 0 && ( woff.metaLength != 0 || + woff.metaOrigLength != 0 ) ) || + ( woff.metaLength != 0 && woff.metaOrigLength == 0 ) || + ( woff.privOffset == 0 && woff.privLength != 0 ) ) + { + FT_ERROR(( "woff_font_open: invalid WOFF header\n" )); + return FT_THROW( Invalid_Table ); + } + + /* Don't trust `totalSfntSize' before thorough checks. */ + if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) || + FT_NEW( sfnt_stream ) ) + goto Exit; + + sfnt_header = sfnt; + + /* Write sfnt header. */ + { + FT_UInt searchRange, entrySelector, rangeShift, x; + + + x = woff.num_tables; + entrySelector = 0; + while ( x ) + { + x >>= 1; + entrySelector += 1; + } + entrySelector--; + + searchRange = ( 1 << entrySelector ) * 16; + rangeShift = woff.num_tables * 16 - searchRange; + + WRITE_ULONG ( sfnt_header, woff.flavor ); + WRITE_USHORT( sfnt_header, woff.num_tables ); + WRITE_USHORT( sfnt_header, searchRange ); + WRITE_USHORT( sfnt_header, entrySelector ); + WRITE_USHORT( sfnt_header, rangeShift ); + } + + /* While the entries in the sfnt header must be sorted by the */ + /* tag value, the tables themselves are not. We thus have to */ + /* sort them by offset and check that they don't overlap. */ + + if ( FT_NEW_ARRAY( tables, woff.num_tables ) || + FT_NEW_ARRAY( indices, woff.num_tables ) ) + goto Exit; + + FT_TRACE2(( "\n" + " tag offset compLen origLen checksum\n" + " -------------------------------------------\n" )); + + if ( FT_FRAME_ENTER( 20L * woff.num_tables ) ) + goto Exit; + + for ( nn = 0; nn < woff.num_tables; nn++ ) + { + WOFF_Table table = tables + nn; + + table->Tag = FT_GET_TAG4(); + table->Offset = FT_GET_ULONG(); + table->CompLength = FT_GET_ULONG(); + table->OrigLength = FT_GET_ULONG(); + table->CheckSum = FT_GET_ULONG(); + + FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx %08lx\n", + (FT_Char)( table->Tag >> 24 ), + (FT_Char)( table->Tag >> 16 ), + (FT_Char)( table->Tag >> 8 ), + (FT_Char)( table->Tag ), + table->Offset, + table->CompLength, + table->OrigLength, + table->CheckSum )); + + if ( table->Tag <= old_tag ) + { + FT_FRAME_EXIT(); + + FT_ERROR(( "woff_font_open: table tags are not sorted\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + old_tag = table->Tag; + indices[nn] = table; + } + + FT_FRAME_EXIT(); + + /* Sort by offset. */ + + ft_qsort( indices, + woff.num_tables, + sizeof ( WOFF_Table ), + compare_offsets ); + + /* Check offsets and lengths. */ + + woff_offset = 44 + woff.num_tables * 20L; + sfnt_offset = 12 + woff.num_tables * 16L; + + for ( nn = 0; nn < woff.num_tables; nn++ ) + { + WOFF_Table table = indices[nn]; + + + if ( table->Offset != woff_offset || + table->CompLength > woff.length || + table->Offset > woff.length - table->CompLength || + table->OrigLength > woff.totalSfntSize || + sfnt_offset > woff.totalSfntSize - table->OrigLength || + table->CompLength > table->OrigLength ) + { + FT_ERROR(( "woff_font_open: invalid table offsets\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + table->OrigOffset = sfnt_offset; + + /* The offsets must be multiples of 4. */ + woff_offset += ( table->CompLength + 3 ) & ~3U; + sfnt_offset += ( table->OrigLength + 3 ) & ~3U; + } + + /* + * Final checks! + * + * We don't decode and check the metadata block. + * We don't check table checksums either. + * But other than those, I think we implement all + * `MUST' checks from the spec. + */ + + if ( woff.metaOffset ) + { + if ( woff.metaOffset != woff_offset || + woff.metaOffset + woff.metaLength > woff.length ) + { + FT_ERROR(( "woff_font_open:" + " invalid `metadata' offset or length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* We have padding only ... */ + woff_offset += woff.metaLength; + } + + if ( woff.privOffset ) + { + /* ... if it isn't the last block. */ + woff_offset = ( woff_offset + 3 ) & ~3U; + + if ( woff.privOffset != woff_offset || + woff.privOffset + woff.privLength > woff.length ) + { + FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* No padding for the last block. */ + woff_offset += woff.privLength; + } + + if ( sfnt_offset != woff.totalSfntSize || + woff_offset != woff.length ) + { + FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* Now use `totalSfntSize'. */ + if ( FT_REALLOC( sfnt, + 12 + woff.num_tables * 16UL, + woff.totalSfntSize ) ) + goto Exit; + + sfnt_header = sfnt + 12; + + /* Write the tables. */ + + for ( nn = 0; nn < woff.num_tables; nn++ ) + { + WOFF_Table table = tables + nn; + + + /* Write SFNT table entry. */ + WRITE_ULONG( sfnt_header, table->Tag ); + WRITE_ULONG( sfnt_header, table->CheckSum ); + WRITE_ULONG( sfnt_header, table->OrigOffset ); + WRITE_ULONG( sfnt_header, table->OrigLength ); + + /* Write table data. */ + if ( FT_STREAM_SEEK( table->Offset ) || + FT_FRAME_ENTER( table->CompLength ) ) + goto Exit; + + if ( table->CompLength == table->OrigLength ) + { + /* Uncompressed data; just copy. */ + ft_memcpy( sfnt + table->OrigOffset, + stream->cursor, + table->OrigLength ); + } + else + { +#ifdef FT_CONFIG_OPTION_USE_ZLIB + + /* Uncompress with zlib. */ + FT_ULong output_len = table->OrigLength; + + + error = FT_Gzip_Uncompress( memory, + sfnt + table->OrigOffset, &output_len, + stream->cursor, table->CompLength ); + if ( error ) + goto Exit; + if ( output_len != table->OrigLength ) + { + FT_ERROR(( "woff_font_open: compressed table length mismatch\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + +#else /* !FT_CONFIG_OPTION_USE_ZLIB */ + + error = FT_THROW( Unimplemented_Feature ); + goto Exit; + +#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ + } + + FT_FRAME_EXIT(); + + /* We don't check whether the padding bytes in the WOFF file are */ + /* actually '\0'. For the output, however, we do set them properly. */ + sfnt_offset = table->OrigOffset + table->OrigLength; + while ( sfnt_offset & 3 ) + { + sfnt[sfnt_offset] = '\0'; + sfnt_offset++; + } + } + + /* Ok! Finally ready. Swap out stream and return. */ + FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize ); + sfnt_stream->memory = stream->memory; + sfnt_stream->close = sfnt_stream_close; + + FT_Stream_Free( + face->root.stream, + ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); + + face->root.stream = sfnt_stream; + + face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; + + Exit: + FT_FREE( tables ); + FT_FREE( indices ); + + if ( error ) + { + FT_FREE( sfnt ); + FT_Stream_Close( sfnt_stream ); + FT_FREE( sfnt_stream ); + } + + return error; + } + + +#undef WRITE_USHORT +#undef WRITE_ULONG + + /* Fill in face->ttc_header. If the font is not a TTC, it is */ /* synthesized into a TTC with one offset table. */ static FT_Error @@ -373,11 +753,28 @@ face->ttc_header.version = 0; face->ttc_header.count = 0; + retry: offset = FT_STREAM_POS(); if ( FT_READ_ULONG( tag ) ) return error; + if ( tag == TTAG_wOFF ) + { + FT_TRACE2(( "sfnt_open_font: file is a WOFF; synthesizing SFNT\n" )); + + if ( FT_STREAM_SEEK( offset ) ) + return error; + + error = woff_open_font( stream, face ); + if ( error ) + return error; + + /* Swap out stream and retry! */ + stream = face->root.stream; + goto retry; + } + if ( tag != 0x00010000UL && tag != TTAG_ttcf && tag != TTAG_OTTO && @@ -444,13 +841,14 @@ FT_LOCAL_DEF( FT_Error ) sfnt_init_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { - FT_Error error; - FT_Library library = face->root.driver->root.library; - SFNT_Service sfnt; + FT_Error error; + FT_Library library = face->root.driver->root.library; + SFNT_Service sfnt; + FT_Int face_index; /* for now, parameters are unused */ @@ -480,22 +878,104 @@ if ( error ) return error; - FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index )); + /* Stream may have changed in sfnt_open_font. */ + stream = face->root.stream; + + FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_instance_index )); - if ( face_index < 0 ) - face_index = 0; + face_index = FT_ABS( face_instance_index ) & 0xFFFF; if ( face_index >= face->ttc_header.count ) - return FT_THROW( Invalid_Argument ); + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + face_index = 0; + } if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) return error; - /* check that we have a valid TrueType file */ + /* check whether we have a valid TrueType file */ error = sfnt->load_font_dir( face, stream ); if ( error ) return error; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + { + FT_ULong fvar_len; + + FT_ULong version; + FT_ULong offset; + + FT_UShort num_axes; + FT_UShort axis_size; + FT_UShort num_instances; + FT_UShort instance_size; + + FT_Int instance_index; + + + instance_index = FT_ABS( face_instance_index ) >> 16; + + /* test whether current face is a GX font with named instances */ + if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) || + fvar_len < 20 || + FT_READ_ULONG( version ) || + FT_READ_USHORT( offset ) || + FT_STREAM_SKIP( 2 ) || + FT_READ_USHORT( num_axes ) || + FT_READ_USHORT( axis_size ) || + FT_READ_USHORT( num_instances ) || + FT_READ_USHORT( instance_size ) ) + { + version = 0; + offset = 0; + num_axes = 0; + axis_size = 0; + num_instances = 0; + instance_size = 0; + } + + /* check that the data is bound by the table length; */ + /* based on similar code in function `TT_Get_MM_Var' */ + if ( version != 0x00010000UL || + axis_size != 20 || + num_axes > 0x3FFE || + instance_size != 4 + 4 * num_axes || + num_instances > 0x7EFF || + offset + + axis_size * num_axes + + instance_size * num_instances > fvar_len ) + num_instances = 0; + + /* we don't support Multiple Master CFFs yet */ + if ( !face->goto_table( face, TTAG_CFF, stream, 0 ) ) + num_instances = 0; + + /* we support at most 2^15 - 1 instances */ + if ( num_instances >= ( 1U << 15 ) - 1 ) + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + num_instances = 0; + } + + /* instance indices in `face_instance_index' start with index 1, */ + /* thus `>' and not `>=' */ + if ( instance_index > num_instances ) + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + num_instances = 0; + } + + face->root.style_flags = (FT_Long)num_instances << 16; + } +#endif + face->root.num_faces = face->ttc_header.count; face->root.face_index = face_index; @@ -504,7 +984,8 @@ #define LOAD_( x ) \ - do { \ + do \ + { \ FT_TRACE2(( "`" #x "' " )); \ FT_TRACE3(( "-->\n" )); \ \ @@ -519,7 +1000,8 @@ } while ( 0 ) #define LOADM_( x, vertical ) \ - do { \ + do \ + { \ FT_TRACE2(( "`%s" #x "' ", \ vertical ? "vertical " : "" )); \ FT_TRACE3(( "-->\n" )); \ @@ -535,7 +1017,8 @@ } while ( 0 ) #define GET_NAME( id, field ) \ - do { \ + do \ + { \ error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \ if ( error ) \ goto Exit; \ @@ -545,7 +1028,7 @@ FT_LOCAL_DEF( FT_Error ) sfnt_load_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { @@ -555,12 +1038,13 @@ #endif FT_Bool has_outline; FT_Bool is_apple_sbit; + FT_Bool is_apple_sbix; FT_Bool ignore_preferred_family = FALSE; FT_Bool ignore_preferred_subfamily = FALSE; SFNT_Service sfnt = (SFNT_Service)face->sfnt; - FT_UNUSED( face_index ); + FT_UNUSED( face_instance_index ); /* Check parameters */ @@ -608,6 +1092,13 @@ #endif is_apple_sbit = 0; + is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 ); + + /* Apple 'sbix' color bitmaps are rendered scaled and then the 'glyf' + * outline rendered on top. We don't support that yet, so just ignore + * the 'glyf' outline and advertise it as a bitmap-only font. */ + if ( is_apple_sbix ) + has_outline = FALSE; /* if this font doesn't contain outlines, we try to load */ /* a `bhed' table */ @@ -619,7 +1110,7 @@ /* load the font header (`head' table) if this isn't an Apple */ /* sbit font file */ - if ( !is_apple_sbit ) + if ( !is_apple_sbit || is_apple_sbix ) { LOAD_( head ); if ( error ) @@ -803,6 +1294,10 @@ /* */ /* Compute face flags. */ /* */ + if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_CBLC || + face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX ) + flags |= FT_FACE_FLAG_COLOR; /* color glyphs */ + if ( has_outline == TRUE ) flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */ @@ -871,7 +1366,7 @@ flags |= FT_STYLE_FLAG_ITALIC; } - root->style_flags = flags; + root->style_flags |= flags; /*********************************************************************/ /* */ @@ -931,7 +1426,7 @@ if ( em_size == 0 || face->os2.version == 0xFFFFU ) { - avgwidth = 0; + avgwidth = 1; em_size = 1; } @@ -1018,8 +1513,8 @@ root->ascender = face->horizontal.Ascender; root->descender = face->horizontal.Descender; - root->height = (FT_Short)( root->ascender - root->descender + - face->horizontal.Line_Gap ); + root->height = root->ascender - root->descender + + face->horizontal.Line_Gap; if ( !( root->ascender || root->descender ) ) { @@ -1030,23 +1525,24 @@ root->ascender = face->os2.sTypoAscender; root->descender = face->os2.sTypoDescender; - root->height = (FT_Short)( root->ascender - root->descender + - face->os2.sTypoLineGap ); + root->height = root->ascender - root->descender + + face->os2.sTypoLineGap; } else { root->ascender = (FT_Short)face->os2.usWinAscent; root->descender = -(FT_Short)face->os2.usWinDescent; - root->height = (FT_UShort)( root->ascender - root->descender ); + root->height = root->ascender - root->descender; } } } - root->max_advance_width = face->horizontal.advance_Width_Max; - root->max_advance_height = (FT_Short)( face->vertical_info - ? face->vertical.advance_Height_Max - : root->height ); + root->max_advance_width = + (FT_Short)face->horizontal.advance_Width_Max; + root->max_advance_height = + (FT_Short)( face->vertical_info ? face->vertical.advance_Height_Max + : root->height ); /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ /* Adjust underline position from top edge to centre of */ @@ -1156,7 +1652,7 @@ FT_FREE( face->postscript_name ); - face->sfnt = 0; + face->sfnt = NULL; } diff --git a/drivers/freetype/freetype/src/sfnt/sfobjs.h b/drivers/freetype/src/sfnt/sfobjs.h index 6241c93b39..60b5698edd 100644 --- a/drivers/freetype/freetype/src/sfnt/sfobjs.h +++ b/drivers/freetype/src/sfnt/sfobjs.h @@ -4,7 +4,7 @@ /* */ /* SFNT object management (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFOBJS_H__ -#define __SFOBJS_H__ +#ifndef SFOBJS_H_ +#define SFOBJS_H_ #include <ft2build.h> @@ -31,24 +31,29 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) sfnt_init_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ); FT_LOCAL( FT_Error ) sfnt_load_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ); FT_LOCAL( void ) sfnt_done_face( TT_Face face ); + FT_LOCAL( FT_Error ) + tt_face_get_name( TT_Face face, + FT_UShort nameid, + FT_String** name ); + FT_END_HEADER -#endif /* __SFDRIVER_H__ */ +#endif /* SFDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttbdf.c b/drivers/freetype/src/sfnt/ttbdf.c index 9401dae5f8..f891691118 100644 --- a/drivers/freetype/freetype/src/sfnt/ttbdf.c +++ b/drivers/freetype/src/sfnt/ttbdf.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded BDF properties (body). */ /* */ -/* Copyright 2005, 2006, 2010, 2013 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/sfnt/ttbdf.h b/drivers/freetype/src/sfnt/ttbdf.h index 48a10d6e9b..ae521c60b6 100644 --- a/drivers/freetype/freetype/src/sfnt/ttbdf.h +++ b/drivers/freetype/src/sfnt/ttbdf.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded BDF properties (specification). */ /* */ -/* Copyright 2005 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTBDF_H__ -#define __TTBDF_H__ +#ifndef TTBDF_H_ +#define TTBDF_H_ #include <ft2build.h> @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTBDF_H__ */ +#endif /* TTBDF_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttcmap.c b/drivers/freetype/src/sfnt/ttcmap.c index 1507202ea8..01255a887e 100644 --- a/drivers/freetype/freetype/src/sfnt/ttcmap.c +++ b/drivers/freetype/src/sfnt/ttcmap.c @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002-2010, 2012, 2013 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -51,6 +51,13 @@ #define TT_NEXT_ULONG FT_NEXT_ULONG + /* Too large glyph index return values are caught in `FT_Get_Char_Index' */ + /* and `FT_Get_Next_Char' (the latter calls the internal `next' function */ + /* again in this case). To mark character code return values as invalid */ + /* it is sufficient to set the corresponding glyph index return value to */ + /* zero. */ + + FT_CALLBACK_DEF( FT_Error ) tt_cmap_init( TT_CMap cmap, FT_Byte* table ) @@ -88,10 +95,16 @@ tt_cmap0_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; - FT_UInt length = TT_NEXT_USHORT( p ); + FT_Byte* p; + FT_UInt length; + if ( table + 2 + 2 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; /* skip format */ + length = TT_NEXT_USHORT( p ); + if ( table + length > valid->limit || length < 262 ) FT_INVALID_TOO_SHORT; @@ -193,7 +206,7 @@ /***** FORMAT 2 *****/ /***** *****/ /***** This is used for certain CJK encodings that encode text in a *****/ - /***** mixed 8/16 bits encoding along the following lines: *****/ + /***** mixed 8/16 bits encoding along the following lines. *****/ /***** *****/ /***** * Certain byte values correspond to an 8-bit character code *****/ /***** (typically in the range 0..127 for ASCII compatibility). *****/ @@ -203,19 +216,19 @@ /***** second byte of a 2-byte character). *****/ /***** *****/ /***** The following charmap lookup and iteration functions all *****/ - /***** assume that the value "charcode" correspond to following: *****/ + /***** assume that the value `charcode' fulfills the following. *****/ /***** *****/ - /***** - For one byte characters, "charcode" is simply the *****/ + /***** - For one byte characters, `charcode' is simply the *****/ /***** character code. *****/ /***** *****/ - /***** - For two byte characters, "charcode" is the 2-byte *****/ - /***** character code in big endian format. More exactly: *****/ + /***** - For two byte characters, `charcode' is the 2-byte *****/ + /***** character code in big endian format. More precisely: *****/ /***** *****/ /***** (charcode >> 8) is the first byte value *****/ /***** (charcode & 0xFF) is the second byte value *****/ /***** *****/ - /***** Note that not all values of "charcode" are valid according *****/ - /***** to these rules, and the function moderately check the *****/ + /***** Note that not all values of `charcode' are valid according *****/ + /***** to these rules, and the function moderately checks the *****/ /***** arguments. *****/ /***** *****/ /*************************************************************************/ @@ -243,7 +256,7 @@ /* table, i.e., it is the corresponding sub-header index multiplied */ /* by 8. */ /* */ - /* Each sub-header has the following format: */ + /* Each sub-header has the following format. */ /* */ /* NAME OFFSET TYPE DESCRIPTION */ /* */ @@ -258,11 +271,11 @@ /* according to the specification. */ /* */ /* If a character code is contained within a given sub-header, then */ - /* mapping it to a glyph index is done as follows: */ + /* mapping it to a glyph index is done as follows. */ /* */ /* * The value of `offset' is read. This is a _byte_ distance from the */ /* location of the `offset' field itself into a slice of the */ - /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ + /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[], too). */ /* */ /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ /* no glyph for the charcode. Otherwise, the value of `delta' is */ @@ -279,13 +292,20 @@ tt_cmap2_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; /* skip format */ - FT_UInt length = TT_PEEK_USHORT( p ); + FT_Byte* p; + FT_UInt length; + FT_UInt n, max_subs; - FT_Byte* keys; /* keys table */ - FT_Byte* subs; /* sub-headers */ - FT_Byte* glyph_ids; /* glyph ID array */ + FT_Byte* keys; /* keys table */ + FT_Byte* subs; /* sub-headers */ + FT_Byte* glyph_ids; /* glyph ID array */ + + + if ( table + 2 + 2 > valid->limit ) + FT_INVALID_TOO_SHORT; + p = table + 2; /* skip format */ + length = TT_NEXT_USHORT( p ); if ( table + length > valid->limit || length < 6 + 512 ) FT_INVALID_TOO_SHORT; @@ -313,16 +333,15 @@ FT_ASSERT( p == table + 518 ); subs = p; - glyph_ids = subs + (max_subs + 1) * 8; + glyph_ids = subs + ( max_subs + 1 ) * 8; if ( glyph_ids > valid->limit ) FT_INVALID_TOO_SHORT; /* parse sub-headers */ for ( n = 0; n <= max_subs; n++ ) { - FT_UInt first_code, code_count, offset; - FT_Int delta; - FT_Byte* ids; + FT_UInt first_code, code_count, offset; + FT_Int delta; first_code = TT_NEXT_USHORT( p ); @@ -344,8 +363,11 @@ /* check offset */ if ( offset != 0 ) { + FT_Byte* ids; + + ids = p - 2 + offset; - if ( ids < glyph_ids || ids + code_count*2 > table + length ) + if ( ids < glyph_ids || ids + code_count * 2 > table + length ) FT_INVALID_OFFSET; /* check glyph IDs */ @@ -360,7 +382,7 @@ idx = TT_NEXT_USHORT( p ); if ( idx != 0 ) { - idx = ( idx + delta ) & 0xFFFFU; + idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) FT_INVALID_GLYPH_ID; } @@ -421,6 +443,7 @@ } result = sub; } + Exit: return result; } @@ -457,9 +480,10 @@ idx = TT_PEEK_USHORT( p ); if ( idx != 0 ) - result = (FT_UInt)( idx + delta ) & 0xFFFFU; + result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; } } + return result; } @@ -509,7 +533,7 @@ if ( idx != 0 ) { - gindex = ( idx + delta ) & 0xFFFFU; + gindex = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; if ( gindex != 0 ) { result = charcode; @@ -750,7 +774,7 @@ if ( charcode < cmap->cur_start ) charcode = cmap->cur_start; - for ( ;; ) + for (;;) { FT_Byte* values = cmap->cur_values; FT_UInt end = cmap->cur_end; @@ -771,7 +795,7 @@ if ( gindex != 0 ) { - gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU ); + gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; if ( gindex != 0 ) { cmap->cur_charcode = charcode; @@ -785,7 +809,7 @@ { do { - FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU ); + FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; if ( gindex != 0 ) @@ -816,16 +840,20 @@ tt_cmap4_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; /* skip format */ - FT_UInt length = TT_NEXT_USHORT( p ); + FT_Byte* p; + FT_UInt length; + FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; FT_UInt num_segs; FT_Error error = FT_Err_Ok; - if ( length < 16 ) + if ( table + 2 + 2 > valid->limit ) FT_INVALID_TOO_SHORT; + p = table + 2; /* skip format */ + length = TT_NEXT_USHORT( p ); + /* in certain fonts, the `length' field is invalid and goes */ /* out of bound. We try to correct this here... */ if ( table + length > valid->limit ) @@ -836,6 +864,9 @@ length = (FT_UInt)( valid->limit - table ); } + if ( length < 16 ) + FT_INVALID_TOO_SHORT; + p = table + 6; num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */ @@ -951,7 +982,7 @@ /* segment if it contains only a single character. */ /* */ /* We thus omit the test here, delaying it to the */ - /* routines which actually access the cmap. */ + /* routines that actually access the cmap. */ else if ( n != num_segs - 1 || !( start == 0xFFFFU && end == 0xFFFFU ) ) { @@ -971,7 +1002,7 @@ idx = FT_NEXT_USHORT( p ); if ( idx != 0 ) { - idx = (FT_UInt)( idx + delta ) & 0xFFFFU; + idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) FT_INVALID_GLYPH_ID; @@ -1004,12 +1035,17 @@ FT_UInt32* pcharcode, FT_Bool next ) { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + FT_UInt num_segs2, start, end, offset; FT_Int delta; FT_UInt i, num_segs; FT_UInt32 charcode = *pcharcode; FT_UInt gindex = 0; FT_Byte* p; + FT_Byte* q; p = cmap->data + 6; @@ -1023,65 +1059,106 @@ if ( next ) charcode++; + if ( charcode > 0xFFFFU ) + return 0; + /* linear search */ - for ( ; charcode <= 0xFFFFU; charcode++ ) - { - FT_Byte* q; + p = cmap->data + 14; /* ends table */ + q = cmap->data + 16 + num_segs2; /* starts table */ + for ( i = 0; i < num_segs; i++ ) + { + end = TT_NEXT_USHORT( p ); + start = TT_NEXT_USHORT( q ); - p = cmap->data + 14; /* ends table */ - q = cmap->data + 16 + num_segs2; /* starts table */ + if ( charcode < start ) + { + if ( next ) + charcode = start; + else + break; + } - for ( i = 0; i < num_segs; i++ ) + Again: + if ( charcode <= end ) { - end = TT_NEXT_USHORT( p ); - start = TT_NEXT_USHORT( q ); + FT_Byte* r; - if ( charcode >= start && charcode <= end ) + + r = q - 2 + num_segs2; + delta = TT_PEEK_SHORT( r ); + r += num_segs2; + offset = TT_PEEK_USHORT( r ); + + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( i >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU ) { - p = q - 2 + num_segs2; - delta = TT_PEEK_SHORT( p ); - p += num_segs2; - offset = TT_PEEK_USHORT( p ); - - /* some fonts have an incorrect last segment; */ - /* we have to catch it */ - if ( i >= num_segs - 1 && - start == 0xFFFFU && end == 0xFFFFU ) + if ( offset && r + offset + 2 > limit ) { - TT_Face face = (TT_Face)cmap->cmap.charmap.face; - FT_Byte* limit = face->cmap_table + face->cmap_size; + delta = 1; + offset = 0; + } + } + if ( offset == 0xFFFFU ) + continue; - if ( offset && p + offset + 2 > limit ) - { - delta = 1; - offset = 0; - } - } + if ( offset ) + { + r += offset + ( charcode - start ) * 2; - if ( offset == 0xFFFFU ) + /* if r > limit, the whole segment is invalid */ + if ( next && r > limit ) continue; - if ( offset ) + gindex = TT_PEEK_USHORT( r ); + if ( gindex ) { - p += offset + ( charcode - start ) * 2; - gindex = TT_PEEK_USHORT( p ); - if ( gindex != 0 ) - gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; + if ( gindex >= (FT_UInt)face->root.num_glyphs ) + gindex = 0; } - else - gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; + } + else + { + gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; - break; + if ( next && gindex >= (FT_UInt)face->root.num_glyphs ) + { + /* we have an invalid glyph index; if there is an overflow, */ + /* we can adjust `charcode', otherwise the whole segment is */ + /* invalid */ + gindex = 0; + + if ( (FT_Int)charcode + delta < 0 && + (FT_Int)end + delta >= 0 ) + charcode = (FT_UInt)( -delta ); + + else if ( (FT_Int)charcode + delta < 0x10000L && + (FT_Int)end + delta >= 0x10000L ) + charcode = (FT_UInt)( 0x10000L - delta ); + + else + continue; + } + } + + if ( next && !gindex ) + { + if ( charcode >= 0xFFFFU ) + break; + + charcode++; + goto Again; } - } - if ( !next || gindex ) break; + } } - if ( next && gindex ) + if ( next ) *pcharcode = charcode; return gindex; @@ -1168,7 +1245,7 @@ mid = max + 1; /* search in segments before the current segment */ - for ( i = max ; i > 0; i-- ) + for ( i = max; i > 0; i-- ) { FT_UInt prev_end; FT_Byte* old_p; @@ -1272,10 +1349,10 @@ p += offset + ( charcode - start ) * 2; gindex = TT_PEEK_USHORT( p ); if ( gindex != 0 ) - gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; } else - gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; + gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; break; } @@ -1288,7 +1365,6 @@ /* if `charcode' is not in any segment, then `mid' is */ /* the segment nearest to `charcode' */ - /* */ if ( charcode > end ) { @@ -1421,7 +1497,7 @@ /* */ /* NAME OFFSET TYPE DESCRIPTION */ /* */ - /* format 0 USHORT must be 4 */ + /* format 0 USHORT must be 6 */ /* length 2 USHORT table length in bytes */ /* language 4 USHORT Mac language code */ /* */ @@ -1489,6 +1565,7 @@ p += 2 * idx; result = TT_PEEK_USHORT( p ); } + return result; } @@ -1509,7 +1586,7 @@ if ( char_code >= 0x10000UL ) - goto Exit; + return 0; if ( char_code < start ) char_code = start; @@ -1525,10 +1602,13 @@ result = char_code; break; } + + if ( char_code >= 0xFFFFU ) + return 0; + char_code++; } - Exit: *pchar_code = result; return gindex; } @@ -1580,7 +1660,7 @@ /***** *****/ /***** The purpose of this format is to easily map UTF-16 text to *****/ /***** glyph indices. Basically, the `char_code' must be in one of *****/ - /***** the following formats: *****/ + /***** the following formats. *****/ /***** *****/ /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ /***** Area (i.e. U+D800-U+DFFF). *****/ @@ -1593,7 +1673,7 @@ /***** The `is32' table embedded in the charmap indicates whether a *****/ /***** given 16-bit value is in the surrogates area or not. *****/ /***** *****/ - /***** So, for any given `char_code', we can assert the following: *****/ + /***** So, for any given `char_code', we can assert the following. *****/ /***** *****/ /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ /***** *****/ @@ -1647,7 +1727,8 @@ p = is32 + 8192; /* skip `is32' array */ num_groups = TT_NEXT_ULONG( p ); - if ( p + num_groups * 12 > valid->limit ) + /* p + num_groups * 12 > valid->limit ? */ + if ( num_groups > (FT_UInt32)( valid->limit - p ) / 12 ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ @@ -1672,7 +1753,12 @@ if ( valid->level >= FT_VALIDATE_TIGHT ) { - if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_UInt32 d = end - start; + + + /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */ + if ( d > TT_VALID_GLYPH_COUNT( valid ) || + start_id >= TT_VALID_GLYPH_COUNT( valid ) - d ) FT_INVALID_GLYPH_ID; count = (FT_UInt32)( end - start + 1 ); @@ -1742,7 +1828,10 @@ if ( char_code <= end ) { - result = (FT_UInt)( start_id + char_code - start ); + if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) + return 0; + + result = (FT_UInt)( start_id + ( char_code - start ) ); break; } } @@ -1754,8 +1843,9 @@ tt_cmap8_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { + FT_Face face = cmap->cmap.charmap.face; FT_UInt32 result = 0; - FT_UInt32 char_code = *pchar_code + 1; + FT_UInt32 char_code; FT_UInt gindex = 0; FT_Byte* table = cmap->data; FT_Byte* p = table + 8204; @@ -1763,6 +1853,11 @@ FT_UInt32 start, end, start_id; + if ( *pchar_code >= 0xFFFFFFFFUL ) + return 0; + + char_code = *pchar_code + 1; + p = table + 8208; for ( ; num_groups > 0; num_groups-- ) @@ -1774,18 +1869,38 @@ if ( char_code < start ) char_code = start; + Again: if ( char_code <= end ) { - gindex = (FT_UInt)( char_code - start + start_id ); - if ( gindex != 0 ) + /* ignore invalid group */ + if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) + continue; + + gindex = (FT_UInt)( start_id + ( char_code - start ) ); + + /* does first element of group point to `.notdef' glyph? */ + if ( gindex == 0 ) { - result = char_code; - goto Exit; + if ( char_code >= 0xFFFFFFFFUL ) + break; + + char_code++; + goto Again; } + + /* if `gindex' is invalid, the remaining values */ + /* in this group are invalid, too */ + if ( gindex >= (FT_UInt)face->num_glyphs ) + { + gindex = 0; + continue; + } + + result = char_code; + break; } } - Exit: *pchar_code = result; return gindex; } @@ -1870,7 +1985,9 @@ count = TT_NEXT_ULONG( p ); if ( length > (FT_ULong)( valid->limit - table ) || - length < 20 + count * 2 ) + /* length < 20 + count * 2 ? */ + length < 20 || + ( length - 20 ) / 2 < count ) FT_INVALID_TOO_SHORT; /* check glyph indices */ @@ -1900,14 +2017,20 @@ FT_Byte* p = table + 12; FT_UInt32 start = TT_NEXT_ULONG( p ); FT_UInt32 count = TT_NEXT_ULONG( p ); - FT_UInt32 idx = (FT_ULong)( char_code - start ); + FT_UInt32 idx; + + + if ( char_code < start ) + return 0; + idx = char_code - start; if ( idx < count ) { p += 2 * idx; result = TT_PEEK_USHORT( p ); } + return result; } @@ -1917,7 +2040,7 @@ FT_UInt32 *pchar_code ) { FT_Byte* table = cmap->data; - FT_UInt32 char_code = *pchar_code + 1; + FT_UInt32 char_code; FT_UInt gindex = 0; FT_Byte* p = table + 12; FT_UInt32 start = TT_NEXT_ULONG( p ); @@ -1925,10 +2048,15 @@ FT_UInt32 idx; + if ( *pchar_code >= 0xFFFFFFFFUL ) + return 0; + + char_code = *pchar_code + 1; + if ( char_code < start ) char_code = start; - idx = (FT_UInt32)( char_code - start ); + idx = char_code - start; p += 2 * idx; for ( ; idx < count; idx++ ) @@ -1936,6 +2064,10 @@ gindex = TT_NEXT_USHORT( p ); if ( gindex != 0 ) break; + + if ( char_code >= 0xFFFFFFFFUL ) + return 0; + char_code++; } @@ -2042,9 +2174,9 @@ tt_cmap12_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p; - FT_ULong length; - FT_ULong num_groups; + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; if ( table + 16 > valid->limit ) @@ -2057,7 +2189,9 @@ num_groups = TT_NEXT_ULONG( p ); if ( length > (FT_ULong)( valid->limit - table ) || - length < 16 + 12 * num_groups ) + /* length < 16 + 12 * num_groups ? */ + length < 16 || + ( length - 16 ) / 12 < num_groups ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ @@ -2079,7 +2213,12 @@ if ( valid->level >= FT_VALIDATE_TIGHT ) { - if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_UInt32 d = end - start; + + + /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */ + if ( d > TT_VALID_GLYPH_COUNT( valid ) || + start_id >= TT_VALID_GLYPH_COUNT( valid ) - d ) FT_INVALID_GLYPH_ID; } @@ -2097,6 +2236,7 @@ static void tt_cmap12_next( TT_CMap12 cmap ) { + FT_Face face = cmap->cmap.cmap.charmap.face; FT_Byte* p; FT_ULong start, end, start_id, char_code; FT_ULong n; @@ -2108,8 +2248,6 @@ char_code = cmap->cur_charcode + 1; - n = cmap->cur_group; - for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) { p = cmap->cmap.data + 16 + 12 * n; @@ -2120,18 +2258,38 @@ if ( char_code < start ) char_code = start; - for ( ; char_code <= end; char_code++ ) + Again: + if ( char_code <= end ) { - gindex = (FT_UInt)( start_id + char_code - start ); + /* ignore invalid group */ + if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) + continue; - if ( gindex ) + gindex = (FT_UInt)( start_id + ( char_code - start ) ); + + /* does first element of group point to `.notdef' glyph? */ + if ( gindex == 0 ) { - cmap->cur_charcode = char_code;; - cmap->cur_gindex = gindex; - cmap->cur_group = n; + if ( char_code >= 0xFFFFFFFFUL ) + goto Fail; - return; + char_code++; + goto Again; + } + + /* if `gindex' is invalid, the remaining values */ + /* in this group are invalid, too */ + if ( gindex >= (FT_UInt)face->num_glyphs ) + { + gindex = 0; + continue; } + + cmap->cur_charcode = char_code; + cmap->cur_gindex = gindex; + cmap->cur_group = n; + + return; } } @@ -2161,7 +2319,12 @@ end = 0xFFFFFFFFUL; if ( next ) + { + if ( char_code >= 0xFFFFFFFFUL ) + return 0; + char_code++; + } min = 0; max = num_groups; @@ -2182,20 +2345,24 @@ else { start_id = TT_PEEK_ULONG( p ); - gindex = (FT_UInt)( start_id + char_code - start ); + /* reject invalid glyph index */ + if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) + gindex = 0; + else + gindex = (FT_UInt)( start_id + ( char_code - start ) ); break; } } if ( next ) { + FT_Face face = cmap->cmap.charmap.face; TT_CMap12 cmap12 = (TT_CMap12)cmap; /* if `char_code' is not in any group, then `mid' is */ /* the group nearest to `char_code' */ - /* */ if ( char_code > end ) { @@ -2208,6 +2375,9 @@ cmap12->cur_charcode = char_code; cmap12->cur_group = mid; + if ( gindex >= (FT_UInt)face->num_glyphs ) + gindex = 0; + if ( !gindex ) { tt_cmap12_next( cmap12 ); @@ -2218,8 +2388,7 @@ else cmap12->cur_gindex = gindex; - if ( gindex ) - *pchar_code = cmap12->cur_charcode; + *pchar_code = cmap12->cur_charcode; } return gindex; @@ -2239,23 +2408,17 @@ FT_UInt32 *pchar_code ) { TT_CMap12 cmap12 = (TT_CMap12)cmap; - FT_ULong gindex; + FT_UInt gindex; - if ( cmap12->cur_charcode >= 0xFFFFFFFFUL ) - return 0; - /* no need to search */ if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) { tt_cmap12_next( cmap12 ); if ( cmap12->valid ) { - gindex = cmap12->cur_gindex; - - /* XXX: check cur_charcode overflow is expected */ - if ( gindex ) - *pchar_code = (FT_UInt32)cmap12->cur_charcode; + gindex = cmap12->cur_gindex; + *pchar_code = (FT_UInt32)cmap12->cur_charcode; } else gindex = 0; @@ -2263,8 +2426,7 @@ else gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); - /* XXX: check gindex overflow is expected */ - return (FT_UInt32)gindex; + return gindex; } @@ -2381,7 +2543,9 @@ num_groups = TT_NEXT_ULONG( p ); if ( length > (FT_ULong)( valid->limit - table ) || - length < 16 + 12 * num_groups ) + /* length < 16 + 12 * num_groups ? */ + length < 16 || + ( length - 16 ) / 12 < num_groups ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ @@ -2421,6 +2585,7 @@ static void tt_cmap13_next( TT_CMap13 cmap ) { + FT_Face face = cmap->cmap.cmap.charmap.face; FT_Byte* p; FT_ULong start, end, glyph_id, char_code; FT_ULong n; @@ -2432,8 +2597,6 @@ char_code = cmap->cur_charcode + 1; - n = cmap->cur_group; - for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) { p = cmap->cmap.data + 16 + 12 * n; @@ -2448,9 +2611,9 @@ { gindex = (FT_UInt)glyph_id; - if ( gindex ) + if ( gindex && gindex < (FT_UInt)face->num_glyphs ) { - cmap->cur_charcode = char_code;; + cmap->cur_charcode = char_code; cmap->cur_gindex = gindex; cmap->cur_group = n; @@ -2485,7 +2648,12 @@ end = 0xFFFFFFFFUL; if ( next ) + { + if ( char_code >= 0xFFFFFFFFUL ) + return 0; + char_code++; + } min = 0; max = num_groups; @@ -2513,6 +2681,7 @@ if ( next ) { + FT_Face face = cmap->cmap.charmap.face; TT_CMap13 cmap13 = (TT_CMap13)cmap; @@ -2530,6 +2699,9 @@ cmap13->cur_charcode = char_code; cmap13->cur_group = mid; + if ( gindex >= (FT_UInt)face->num_glyphs ) + gindex = 0; + if ( !gindex ) { tt_cmap13_next( cmap13 ); @@ -2540,8 +2712,7 @@ else cmap13->cur_gindex = gindex; - if ( gindex ) - *pchar_code = cmap13->cur_charcode; + *pchar_code = cmap13->cur_charcode; } return gindex; @@ -2564,18 +2735,14 @@ FT_UInt gindex; - if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) - return 0; - /* no need to search */ if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) { tt_cmap13_next( cmap13 ); if ( cmap13->valid ) { - gindex = cmap13->cur_gindex; - if ( gindex ) - *pchar_code = cmap13->cur_charcode; + gindex = cmap13->cur_gindex; + *pchar_code = cmap13->cur_charcode; } else gindex = 0; @@ -2756,13 +2923,22 @@ tt_cmap14_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; - FT_ULong length = TT_NEXT_ULONG( p ); - FT_ULong num_selectors = TT_NEXT_ULONG( p ); + FT_Byte* p; + FT_ULong length; + FT_ULong num_selectors; + if ( table + 2 + 4 + 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; + length = TT_NEXT_ULONG( p ); + num_selectors = TT_NEXT_ULONG( p ); + if ( length > (FT_ULong)( valid->limit - table ) || - length < 10 + 11 * num_selectors ) + /* length < 10 + 11 * num_selectors ? */ + length < 10 || + ( length - 10 ) / 11 < num_selectors ) FT_INVALID_TOO_SHORT; /* check selectors, they must be in increasing order */ @@ -2792,13 +2968,19 @@ /* through the normal Unicode cmap, no GIDs, just check order) */ if ( defOff != 0 ) { - FT_Byte* defp = table + defOff; - FT_ULong numRanges = TT_NEXT_ULONG( defp ); + FT_Byte* defp = table + defOff; + FT_ULong numRanges; FT_ULong i; - FT_ULong lastBase = 0; + FT_ULong lastBase = 0; - if ( defp + numRanges * 4 > valid->limit ) + if ( defp + 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + numRanges = TT_NEXT_ULONG( defp ); + + /* defp + numRanges * 4 > valid->limit ? */ + if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 ) FT_INVALID_TOO_SHORT; for ( i = 0; i < numRanges; ++i ) @@ -2820,12 +3002,18 @@ /* and the non-default table (these glyphs are specified here) */ if ( nondefOff != 0 ) { - FT_Byte* ndp = table + nondefOff; - FT_ULong numMappings = TT_NEXT_ULONG( ndp ); - FT_ULong i, lastUni = 0; + FT_Byte* ndp = table + nondefOff; + FT_ULong numMappings; + FT_ULong i, lastUni = 0; + + if ( ndp + 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + numMappings = TT_NEXT_ULONG( ndp ); - if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ) + /* numMappings * 5 > (FT_ULong)( valid->limit - ndp ) ? */ + if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 ) FT_INVALID_TOO_SHORT; for ( i = 0; i < numMappings; ++i ) @@ -2916,7 +3104,7 @@ if ( char_code < start ) max = mid; - else if ( char_code > start+cnt ) + else if ( char_code > start + cnt ) min = mid + 1; else return TRUE; @@ -3208,7 +3396,6 @@ { FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); - FT_UInt32 *ret; FT_Int i; FT_ULong defOff; FT_ULong nondefOff; @@ -3242,6 +3429,8 @@ FT_Byte* dp; FT_UInt di, ni, k; + FT_UInt32 *ret; + p = cmap->data + nondefOff; dp = cmap->data + defOff; @@ -3269,7 +3458,7 @@ ni = 1; i = 0; - for ( ;; ) + for (;;) { if ( nuni > duni + dcnt ) { @@ -3447,23 +3636,14 @@ /* only recognize format 0 */ if ( TT_NEXT_USHORT( p ) != 0 ) { - p -= 2; FT_ERROR(( "tt_face_build_cmaps:" " unsupported `cmap' table format = %d\n", - TT_PEEK_USHORT( p ) )); + TT_PEEK_USHORT( p - 2 ) )); return FT_THROW( Invalid_Table ); } num_cmaps = TT_NEXT_USHORT( p ); -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE ) - FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables (%d)\n" - " subtable #%d and higher are loaded" - " but cannot be searched\n", - num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 )); -#endif - for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) { FT_CharMapRec charmap; diff --git a/drivers/freetype/freetype/src/sfnt/ttcmap.h b/drivers/freetype/src/sfnt/ttcmap.h index 0fde1676bf..2273cbd961 100644 --- a/drivers/freetype/freetype/src/sfnt/ttcmap.h +++ b/drivers/freetype/src/sfnt/ttcmap.h @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002-2005, 2009, 2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTCMAP_H__ -#define __TTCMAP_H__ +#ifndef TTCMAP_H_ +#define TTCMAP_H_ #include <ft2build.h> @@ -152,7 +152,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTCMAP_H__ */ +#endif /* TTCMAP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttcmapc.h b/drivers/freetype/src/sfnt/ttcmapc.h index 2ea204309c..7c732fbd36 100644 --- a/drivers/freetype/freetype/src/sfnt/ttcmapc.h +++ b/drivers/freetype/src/sfnt/ttcmapc.h @@ -4,7 +4,7 @@ /* */ /* TT CMAP classes definitions (specification only). */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/sfnt/ttkern.c b/drivers/freetype/src/sfnt/ttkern.c index 60ee546d79..6f9fa522d5 100644 --- a/drivers/freetype/freetype/src/sfnt/ttkern.c +++ b/drivers/freetype/src/sfnt/ttkern.c @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -99,7 +99,7 @@ length = FT_NEXT_USHORT( p ); coverage = FT_NEXT_USHORT( p ); - if ( length <= 6 ) + if ( length <= 6 + 8 ) break; p_next += length; @@ -108,8 +108,8 @@ p_next = p_limit; /* only use horizontal kerning tables */ - if ( ( coverage & ~8 ) != 0x0001 || - p + 8 > p_limit ) + if ( ( coverage & ~8U ) != 0x0001 || + p + 8 > p_limit ) goto NextTable; num_pairs = FT_NEXT_USHORT( p ); @@ -183,7 +183,7 @@ FT_UInt right_glyph ) { FT_Int result = 0; - FT_UInt count, mask = 1; + FT_UInt count, mask; FT_Byte* p = face->kern_table; FT_Byte* p_limit = p + face->kern_table_size; @@ -196,7 +196,7 @@ count--, mask <<= 1 ) { FT_Byte* base = p; - FT_Byte* next = base; + FT_Byte* next; FT_UInt version = FT_NEXT_USHORT( p ); FT_UInt length = FT_NEXT_USHORT( p ); FT_UInt coverage = FT_NEXT_USHORT( p ); diff --git a/drivers/freetype/freetype/src/sfnt/ttkern.h b/drivers/freetype/src/sfnt/ttkern.h index df1da9b273..85dd5c31ae 100644 --- a/drivers/freetype/freetype/src/sfnt/ttkern.h +++ b/drivers/freetype/src/sfnt/ttkern.h @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2007 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTKERN_H__ -#define __TTKERN_H__ +#ifndef TTKERN_H_ +#define TTKERN_H_ #include <ft2build.h> @@ -46,7 +46,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTKERN_H__ */ +#endif /* TTKERN_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttload.c b/drivers/freetype/src/sfnt/ttload.c index fbe70f7974..2f5b2c3843 100644 --- a/drivers/freetype/freetype/src/sfnt/ttload.c +++ b/drivers/freetype/src/sfnt/ttload.c @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (body). */ /* */ -/* Copyright 1996-2010, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -151,7 +151,8 @@ /* Here, we */ /* */ - /* - check that `num_tables' is valid (and adjust it if necessary) */ + /* - check that `num_tables' is valid (and adjust it if necessary); */ + /* also return the number of valid table entries */ /* */ /* - look for a `head' table, check its size, and parse it to check */ /* whether its `magic' field is correctly set */ @@ -167,7 +168,8 @@ /* */ static FT_Error check_table_dir( SFNT_Header sfnt, - FT_Stream stream ) + FT_Stream stream, + FT_UShort* valid ) { FT_Error error; FT_UShort nn, valid_entries = 0; @@ -207,11 +209,28 @@ } /* we ignore invalid tables */ - if ( table.Offset + table.Length > stream->size ) + + if ( table.Offset > stream->size ) { FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); continue; } + else if ( table.Length > stream->size - table.Offset ) + { + /* Some tables have such a simple structure that clipping its */ + /* contents is harmless. This also makes FreeType less sensitive */ + /* to invalid table lengths (which programs like Acroread seem to */ + /* ignore in general). */ + + if ( table.Tag == TTAG_hmtx || + table.Tag == TTAG_vmtx ) + valid_entries++; + else + { + FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); + continue; + } + } else valid_entries++; @@ -236,7 +255,8 @@ */ if ( table.Length < 0x36 ) { - FT_TRACE2(( "check_table_dir: `head' table too small\n" )); + FT_TRACE2(( "check_table_dir:" + " `head' or `bhed' table too small\n" )); error = FT_THROW( Table_Missing ); goto Exit; } @@ -246,12 +266,8 @@ goto Exit; if ( magic != 0x5F0F3CF5UL ) - { FT_TRACE2(( "check_table_dir:" - " no magic number found in `head' table\n")); - error = FT_THROW( Table_Missing ); - goto Exit; - } + " invalid magic number in `head' or `bhed' table\n")); if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) ) goto Exit; @@ -262,11 +278,11 @@ has_meta = 1; } - sfnt->num_tables = valid_entries; + *valid = valid_entries; - if ( sfnt->num_tables == 0 ) + if ( !valid_entries ) { - FT_TRACE2(( "check_table_dir: no tables found\n" )); + FT_TRACE2(( "check_table_dir: no valid tables found\n" )); error = FT_THROW( Unknown_File_Format ); goto Exit; } @@ -322,8 +338,7 @@ SFNT_HeaderRec sfnt; FT_Error error; FT_Memory memory = stream->memory; - TT_TableRec* entry; - FT_Int nn; + FT_UShort nn, valid_entries; static const FT_Frame_Field offset_table_fields[] = { @@ -364,56 +379,114 @@ if ( sfnt.format_tag != TTAG_OTTO ) { /* check first */ - error = check_table_dir( &sfnt, stream ); + error = check_table_dir( &sfnt, stream, &valid_entries ); if ( error ) { FT_TRACE2(( "tt_face_load_font_dir:" " invalid table directory for TrueType\n" )); - goto Exit; } } + else + valid_entries = sfnt.num_tables; - face->num_tables = sfnt.num_tables; + face->num_tables = valid_entries; face->format_tag = sfnt.format_tag; if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) ) goto Exit; - if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || - FT_FRAME_ENTER( face->num_tables * 16L ) ) + if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || + FT_FRAME_ENTER( sfnt.num_tables * 16L ) ) goto Exit; - entry = face->dir_tables; - FT_TRACE2(( "\n" " tag offset length checksum\n" " ----------------------------------\n" )); + valid_entries = 0; for ( nn = 0; nn < sfnt.num_tables; nn++ ) { - entry->Tag = FT_GET_TAG4(); - entry->CheckSum = FT_GET_ULONG(); - entry->Offset = FT_GET_LONG(); - entry->Length = FT_GET_LONG(); + TT_TableRec entry; + FT_UShort i; + FT_Bool duplicate; + - /* ignore invalid tables */ - if ( entry->Offset + entry->Length > stream->size ) + entry.Tag = FT_GET_TAG4(); + entry.CheckSum = FT_GET_ULONG(); + entry.Offset = FT_GET_ULONG(); + entry.Length = FT_GET_ULONG(); + + /* ignore invalid tables that can't be sanitized */ + + if ( entry.Offset > stream->size ) continue; + else if ( entry.Length > stream->size - entry.Offset ) + { + if ( entry.Tag == TTAG_hmtx || + entry.Tag == TTAG_vmtx ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_ULong old_length = entry.Length; +#endif + + + /* make metrics table length a multiple of 4 */ + entry.Length = ( stream->size - entry.Offset ) & ~3U; + + FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx" + " (sanitized; original length %08lx)", + (FT_Char)( entry.Tag >> 24 ), + (FT_Char)( entry.Tag >> 16 ), + (FT_Char)( entry.Tag >> 8 ), + (FT_Char)( entry.Tag ), + entry.Offset, + entry.Length, + entry.CheckSum, + old_length )); + } + else + continue; + } +#ifdef FT_DEBUG_LEVEL_TRACE else + FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx", + (FT_Char)( entry.Tag >> 24 ), + (FT_Char)( entry.Tag >> 16 ), + (FT_Char)( entry.Tag >> 8 ), + (FT_Char)( entry.Tag ), + entry.Offset, + entry.Length, + entry.CheckSum )); +#endif + + /* ignore duplicate tables – the first one wins */ + duplicate = 0; + for ( i = 0; i < valid_entries; i++ ) { - FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n", - (FT_Char)( entry->Tag >> 24 ), - (FT_Char)( entry->Tag >> 16 ), - (FT_Char)( entry->Tag >> 8 ), - (FT_Char)( entry->Tag ), - entry->Offset, - entry->Length, - entry->CheckSum )); - entry++; + if ( face->dir_tables[i].Tag == entry.Tag ) + { + duplicate = 1; + break; + } + } + if ( duplicate ) + { + FT_TRACE2(( " (duplicate, ignored)\n" )); + continue; + } + else + { + FT_TRACE2(( "\n" )); + + /* we finally have a valid entry */ + face->dir_tables[valid_entries++] = entry; } } + /* final adjustment to number of tables */ + face->num_tables = valid_entries; + FT_FRAME_EXIT(); FT_TRACE2(( "table directory loaded\n\n" )); @@ -1006,7 +1079,8 @@ FT_FRAME_END }; - static const FT_Frame_Field os2_fields_extra[] = + /* `OS/2' version 1 and newer */ + static const FT_Frame_Field os2_fields_extra1[] = { FT_FRAME_START( 8 ), FT_FRAME_ULONG( ulCodePageRange1 ), @@ -1014,6 +1088,7 @@ FT_FRAME_END }; + /* `OS/2' version 2 and newer */ static const FT_Frame_Field os2_fields_extra2[] = { FT_FRAME_START( 10 ), @@ -1025,6 +1100,15 @@ FT_FRAME_END }; + /* `OS/2' version 5 and newer */ + static const FT_Frame_Field os2_fields_extra5[] = + { + FT_FRAME_START( 4 ), + FT_FRAME_USHORT( usLowerOpticalPointSize ), + FT_FRAME_USHORT( usUpperOpticalPointSize ), + FT_FRAME_END + }; + /* We now support old Mac fonts where the OS/2 table doesn't */ /* exist. Simply put, we set the `version' field to 0xFFFF */ @@ -1038,18 +1122,20 @@ if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) ) goto Exit; - os2->ulCodePageRange1 = 0; - os2->ulCodePageRange2 = 0; - os2->sxHeight = 0; - os2->sCapHeight = 0; - os2->usDefaultChar = 0; - os2->usBreakChar = 0; - os2->usMaxContext = 0; + os2->ulCodePageRange1 = 0; + os2->ulCodePageRange2 = 0; + os2->sxHeight = 0; + os2->sCapHeight = 0; + os2->usDefaultChar = 0; + os2->usBreakChar = 0; + os2->usMaxContext = 0; + os2->usLowerOpticalPointSize = 0; + os2->usUpperOpticalPointSize = 0xFFFF; if ( os2->version >= 0x0001 ) { /* only version 1 tables */ - if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) ) + if ( FT_STREAM_READ_FIELDS( os2_fields_extra1, os2 ) ) goto Exit; if ( os2->version >= 0x0002 ) @@ -1057,6 +1143,13 @@ /* only version 2 tables */ if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) ) goto Exit; + + if ( os2->version >= 0x0005 ) + { + /* only version 5 tables */ + if ( FT_STREAM_READ_FIELDS( os2_fields_extra5, os2 ) ) + goto Exit; + } } } @@ -1164,6 +1257,7 @@ FT_FRAME_USHORT( Style ), FT_FRAME_USHORT( TypeFamily ), FT_FRAME_USHORT( CapHeight ), + FT_FRAME_USHORT( SymbolSet ), FT_FRAME_BYTES ( TypeFace, 16 ), FT_FRAME_BYTES ( CharacterComplement, 8 ), FT_FRAME_BYTES ( FileName, 6 ), diff --git a/drivers/freetype/freetype/src/sfnt/ttload.h b/drivers/freetype/src/sfnt/ttload.h index 49a1aee163..bec42b94b4 100644 --- a/drivers/freetype/freetype/src/sfnt/ttload.h +++ b/drivers/freetype/src/sfnt/ttload.h @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTLOAD_H__ -#define __TTLOAD_H__ +#ifndef TTLOAD_H_ +#define TTLOAD_H_ #include <ft2build.h> @@ -106,7 +106,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTLOAD_H__ */ +#endif /* TTLOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttmtx.c b/drivers/freetype/src/sfnt/ttmtx.c index 371a9edabe..186f873dae 100644 --- a/drivers/freetype/freetype/src/sfnt/ttmtx.c +++ b/drivers/freetype/src/sfnt/ttmtx.c @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (body). */ /* */ -/* Copyright 2006-2009, 2011-2013 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -183,22 +183,25 @@ /* tt_face_get_metrics */ /* */ /* <Description> */ - /* Returns the horizontal or vertical metrics in font units for a */ - /* given glyph. The metrics are the left side bearing (resp. top */ - /* side bearing) and advance width (resp. advance height). */ + /* Return the horizontal or vertical metrics in font units for a */ + /* given glyph. The values are the left side bearing (top side */ + /* bearing for vertical metrics) and advance width (advance height */ + /* for vertical metrics). */ /* */ /* <Input> */ - /* header :: A pointer to either the horizontal or vertical metrics */ - /* structure. */ + /* face :: A pointer to the TrueType face structure. */ /* */ - /* idx :: The glyph index. */ + /* vertical :: If set to TRUE, get vertical metrics. */ + /* */ + /* gindex :: The glyph index. */ /* */ /* <Output> */ - /* bearing :: The bearing, either left side or top side. */ + /* abearing :: The bearing, either left side or top side. */ /* */ - /* advance :: The advance width resp. advance height. */ + /* aadvance :: The advance width or advance height, depending on */ + /* the `vertical' flag. */ /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) tt_face_get_metrics( TT_Face face, FT_Bool vertical, FT_UInt gindex, @@ -271,8 +274,6 @@ *abearing = 0; *aadvance = 0; } - - return FT_Err_Ok; } diff --git a/drivers/freetype/freetype/src/sfnt/ttmtx.h b/drivers/freetype/src/sfnt/ttmtx.h index 8b91a113d8..78395def33 100644 --- a/drivers/freetype/freetype/src/sfnt/ttmtx.h +++ b/drivers/freetype/src/sfnt/ttmtx.h @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTMTX_H__ -#define __TTMTX_H__ +#ifndef TTMTX_H_ +#define TTMTX_H_ #include <ft2build.h> @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_Bool vertical ); - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) tt_face_get_metrics( TT_Face face, FT_Bool vertical, FT_UInt gindex, @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTMTX_H__ */ +#endif /* TTMTX_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttpost.c b/drivers/freetype/src/sfnt/ttpost.c index 47a85c0c9f..3277f1ec4f 100644 --- a/drivers/freetype/freetype/src/sfnt/ttpost.c +++ b/drivers/freetype/src/sfnt/ttpost.c @@ -2,10 +2,10 @@ /* */ /* ttpost.c */ /* */ -/* Postcript name table processing for TrueType and OpenType fonts */ +/* PostScript name table processing for TrueType and OpenType fonts */ /* (body). */ /* */ -/* Copyright 1996-2003, 2006-2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,7 +52,7 @@ #include FT_SERVICE_POSTSCRIPT_CMAPS_H -#define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) +#define MAC_NAME( x ) (FT_String*)psnames->macintosh_name( (FT_UInt)(x) ) #else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -62,14 +62,14 @@ /* table of Mac names. Thus, it is possible to build a version of */ /* FreeType without the Type 1 driver & PSNames module. */ -#define MAC_NAME( x ) ( (FT_String*)tt_post_default_names[x] ) +#define MAC_NAME( x ) (FT_String*)tt_post_default_names[x] - /* the 258 default Mac PS glyph names */ + /* the 258 default Mac PS glyph names; see file `tools/glnames.py' */ static const FT_String* const tt_post_default_names[258] = { /* 0 */ - ".notdef", ".null", "CR", "space", "exclam", + ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", /* 10 */ "quotesingle", "parenleft", "parenright", "asterisk", "plus", @@ -120,7 +120,7 @@ "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", /* 170 */ - "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", + "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", /* 180 */ "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", @@ -144,8 +144,8 @@ "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve", /* 250 */ - "Idot", "Scedilla", "scedilla", "Cacute", "cacute", - "Ccaron", "ccaron", "dmacron", + "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dcroat", }; @@ -155,7 +155,7 @@ static FT_Error load_format_20( TT_Face face, FT_Stream stream, - FT_Long post_limit ) + FT_ULong post_limit ) { FT_Memory memory = stream->memory; FT_Error error; @@ -163,8 +163,8 @@ FT_Int num_glyphs; FT_UShort num_names; - FT_UShort* glyph_indices = 0; - FT_Char** name_strings = 0; + FT_UShort* glyph_indices = NULL; + FT_Char** name_strings = NULL; if ( FT_READ_USHORT( num_glyphs ) ) @@ -243,14 +243,17 @@ goto Fail1; } - if ( (FT_Int)len > post_limit || - FT_STREAM_POS() > post_limit - (FT_Int)len ) + if ( len > post_limit || + FT_STREAM_POS() > post_limit - len ) { + FT_Int d = (FT_Int)post_limit - (FT_Int)FT_STREAM_POS(); + + FT_ERROR(( "load_format_20:" " exceeding string length (%d)," " truncating at end of post table (%d byte left)\n", - len, post_limit - FT_STREAM_POS() )); - len = FT_MAX( 0, post_limit - FT_STREAM_POS() ); + len, d )); + len = (FT_UInt)FT_MAX( 0, d ); } if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) || @@ -307,13 +310,13 @@ static FT_Error load_format_25( TT_Face face, FT_Stream stream, - FT_Long post_limit ) + FT_ULong post_limit ) { FT_Memory memory = stream->memory; FT_Error error; FT_Int num_glyphs; - FT_Char* offset_table = 0; + FT_Char* offset_table = NULL; FT_UNUSED( post_limit ); @@ -377,7 +380,7 @@ FT_Error error; FT_Fixed format; FT_ULong post_len; - FT_Long post_limit; + FT_ULong post_limit; /* get a stream for the face's resource */ @@ -547,10 +550,7 @@ } if ( idx < (FT_UInt)table->num_glyphs ) /* paranoid checking */ - { - idx += table->offsets[idx]; - *PSname = MAC_NAME( idx ); - } + *PSname = MAC_NAME( (FT_Int)idx + table->offsets[idx] ); } /* nothing to do for format == 0x00030000L */ diff --git a/drivers/freetype/freetype/src/sfnt/ttpost.h b/drivers/freetype/src/sfnt/ttpost.h index 6f06d75a71..ede45fd84c 100644 --- a/drivers/freetype/freetype/src/sfnt/ttpost.h +++ b/drivers/freetype/src/sfnt/ttpost.h @@ -2,10 +2,10 @@ /* */ /* ttpost.h */ /* */ -/* Postcript name table processing for TrueType and OpenType fonts */ +/* PostScript name table processing for TrueType and OpenType fonts */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTPOST_H__ -#define __TTPOST_H__ +#ifndef TTPOST_H_ +#define TTPOST_H_ #include <ft2build.h> @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTPOST_H__ */ +#endif /* TTPOST_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/sfnt/ttsbit.c b/drivers/freetype/src/sfnt/ttsbit.c index cd3e5a4a00..e24e7d6cdd 100644 --- a/drivers/freetype/freetype/src/sfnt/ttsbit.c +++ b/drivers/freetype/src/sfnt/ttsbit.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (body). */ /* */ -/* Copyright 2005-2009, 2013 by */ +/* Copyright 2005-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* Copyright 2013 by Google, Inc. */ @@ -28,6 +28,7 @@ #include "sferrors.h" +#include "ttmtx.h" #include "pngshim.h" @@ -42,25 +43,36 @@ FT_LOCAL_DEF( FT_Error ) - tt_face_load_eblc( TT_Face face, + tt_face_load_sbit( TT_Face face, FT_Stream stream ) { - FT_Error error = FT_Err_Ok; - FT_Fixed version; - FT_ULong num_strikes, table_size; - FT_Byte* p; - FT_Byte* p_limit; - FT_UInt count; + FT_Error error; + FT_ULong table_size; + face->sbit_table = NULL; + face->sbit_table_size = 0; + face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; face->sbit_num_strikes = 0; - /* this table is optional */ error = face->goto_table( face, TTAG_CBLC, stream, &table_size ); - if ( error ) + if ( !error ) + face->sbit_table_type = TT_SBIT_TABLE_TYPE_CBLC; + else + { error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); + if ( error ) + error = face->goto_table( face, TTAG_bloc, stream, &table_size ); + if ( !error ) + face->sbit_table_type = TT_SBIT_TABLE_TYPE_EBLC; + } + if ( error ) - error = face->goto_table( face, TTAG_bloc, stream, &table_size ); + { + error = face->goto_table( face, TTAG_sbix, stream, &table_size ); + if ( !error ) + face->sbit_table_type = TT_SBIT_TABLE_TYPE_SBIX; + } if ( error ) goto Exit; @@ -71,53 +83,144 @@ goto Exit; } - if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) - goto Exit; + switch ( (FT_UInt)face->sbit_table_type ) + { + case TT_SBIT_TABLE_TYPE_EBLC: + case TT_SBIT_TABLE_TYPE_CBLC: + { + FT_Byte* p; + FT_Fixed version; + FT_ULong num_strikes; + FT_UInt count; - face->sbit_table_size = table_size; - p = face->sbit_table; - p_limit = p + table_size; + if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) + goto Exit; - version = FT_NEXT_ULONG( p ); - num_strikes = FT_NEXT_ULONG( p ); + face->sbit_table_size = table_size; - if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) - { - FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Fail; + p = face->sbit_table; + + version = FT_NEXT_LONG( p ); + num_strikes = FT_NEXT_ULONG( p ); + + if ( ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00020000UL && + ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00030000UL ) + { + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + if ( num_strikes >= 0x10000UL ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* + * Count the number of strikes available in the table. We are a bit + * paranoid there and don't trust the data. + */ + count = (FT_UInt)num_strikes; + if ( 8 + 48UL * count > table_size ) + count = (FT_UInt)( ( table_size - 8 ) / 48 ); + + face->sbit_num_strikes = count; + } + break; + + case TT_SBIT_TABLE_TYPE_SBIX: + { + FT_UShort version; + FT_UShort flags; + FT_ULong num_strikes; + FT_UInt count; + + + if ( FT_FRAME_ENTER( 8 ) ) + goto Exit; + + version = FT_GET_USHORT(); + flags = FT_GET_USHORT(); + num_strikes = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + if ( version < 1 ) + { + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + /* Bit 0 must always be `1'. */ + /* Bit 1 controls the overlay of bitmaps with outlines. */ + /* All other bits should be zero. */ + if ( !( flags == 1 || flags == 3 ) || + num_strikes >= 0x10000UL ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* we currently don't support bit 1; however, it is better to */ + /* draw at least something... */ + if ( flags == 3 ) + FT_TRACE1(( "tt_face_load_sbit_strikes:" + " sbix overlay not supported yet\n" + " " + " expect bad rendering results\n" )); + + /* + * Count the number of strikes available in the table. We are a bit + * paranoid there and don't trust the data. + */ + count = (FT_UInt)num_strikes; + if ( 8 + 4UL * count > table_size ) + count = (FT_UInt)( ( table_size - 8 ) / 4 ); + + if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) ) + goto Exit; + + face->sbit_table_size = 8 + count * 4; + if ( FT_FRAME_EXTRACT( face->sbit_table_size, face->sbit_table ) ) + goto Exit; + + face->sbit_num_strikes = count; + } + break; + + default: + error = FT_THROW( Unknown_File_Format ); + break; } - /* - * Count the number of strikes available in the table. We are a bit - * paranoid there and don't trust the data. - */ - count = (FT_UInt)num_strikes; - if ( 8 + 48UL * count > table_size ) - count = (FT_UInt)( ( p_limit - p ) / 48 ); + if ( !error ) + FT_TRACE3(( "sbit_num_strikes: %u\n", face->sbit_num_strikes )); - face->sbit_num_strikes = count; + return FT_Err_Ok; - FT_TRACE3(( "sbit_num_strikes: %u\n", count )); Exit: - return error; + if ( error ) + { + if ( face->sbit_table ) + FT_FRAME_RELEASE( face->sbit_table ); + face->sbit_table_size = 0; + face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; + } - Fail: - FT_FRAME_RELEASE( face->sbit_table ); - face->sbit_table_size = 0; - goto Exit; + return error; } FT_LOCAL_DEF( void ) - tt_face_free_eblc( TT_Face face ) + tt_face_free_sbit( TT_Face face ) { FT_Stream stream = face->root.stream; FT_FRAME_RELEASE( face->sbit_table ); face->sbit_table_size = 0; + face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; face->sbit_num_strikes = 0; } @@ -136,28 +239,151 @@ FT_ULong strike_index, FT_Size_Metrics* metrics ) { - FT_Byte* strike; - - if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) return FT_THROW( Invalid_Argument ); - strike = face->sbit_table + 8 + strike_index * 48; + switch ( (FT_UInt)face->sbit_table_type ) + { + case TT_SBIT_TABLE_TYPE_EBLC: + case TT_SBIT_TABLE_TYPE_CBLC: + { + FT_Byte* strike; + FT_Char max_before_bl; + FT_Char min_after_bl; + - metrics->x_ppem = (FT_UShort)strike[44]; - metrics->y_ppem = (FT_UShort)strike[45]; + strike = face->sbit_table + 8 + strike_index * 48; - metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ - metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ - metrics->height = metrics->ascender - metrics->descender; + metrics->x_ppem = (FT_UShort)strike[44]; + metrics->y_ppem = (FT_UShort)strike[45]; - /* XXX: Is this correct? */ - metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ - strike[18] + /* max_width */ - (FT_Char)strike[23] /* min_advance_SB */ - ) << 6; + metrics->ascender = (FT_Char)strike[16] * 64; /* hori.ascender */ + metrics->descender = (FT_Char)strike[17] * 64; /* hori.descender */ - return FT_Err_Ok; + /* Due to fuzzy wording in the EBLC documentation, we find both */ + /* positive and negative values for `descender'. Additionally, */ + /* many fonts have both `ascender' and `descender' set to zero */ + /* (which is definitely wrong). MS Windows simply ignores all */ + /* those values... For these reasons we apply some heuristics */ + /* to get a reasonable, non-zero value for the height. */ + + max_before_bl = (FT_Char)strike[24]; + min_after_bl = (FT_Char)strike[25]; + + if ( metrics->descender > 0 ) + { + /* compare sign of descender with `min_after_bl' */ + if ( min_after_bl < 0 ) + metrics->descender = -metrics->descender; + } + + else if ( metrics->descender == 0 ) + { + if ( metrics->ascender == 0 ) + { + FT_TRACE2(( "tt_face_load_strike_metrics:" + " sanitizing invalid ascender and descender\n" + " " + " values for strike (%d, %d)\n", + metrics->x_ppem, metrics->y_ppem )); + + /* sanitize buggy ascender and descender values */ + if ( max_before_bl || min_after_bl ) + { + metrics->ascender = max_before_bl * 64; + metrics->descender = min_after_bl * 64; + } + else + { + metrics->ascender = metrics->y_ppem * 64; + metrics->descender = 0; + } + } + } + +#if 0 + else + ; /* if we have a negative descender, simply use it */ +#endif + + metrics->height = metrics->ascender - metrics->descender; + if ( metrics->height == 0 ) + { + FT_TRACE2(( "tt_face_load_strike_metrics:" + " sanitizing invalid height value\n" + " " + " for strike (%d, %d)\n", + metrics->x_ppem, metrics->y_ppem )); + metrics->height = metrics->y_ppem * 64; + metrics->descender = metrics->ascender - metrics->height; + } + + /* Is this correct? */ + metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ + strike[18] + /* max_width */ + (FT_Char)strike[23] /* min_advance_SB */ + ) * 64; + return FT_Err_Ok; + } + + case TT_SBIT_TABLE_TYPE_SBIX: + { + FT_Stream stream = face->root.stream; + FT_UInt offset; + FT_UShort upem, ppem, resolution; + TT_HoriHeader *hori; + FT_ULong table_size; + FT_Pos ppem_; /* to reduce casts */ + + FT_Error error; + FT_Byte* p; + + + p = face->sbit_table + 8 + 4 * strike_index; + offset = FT_NEXT_ULONG( p ); + + error = face->goto_table( face, TTAG_sbix, stream, &table_size ); + if ( error ) + return error; + + if ( offset + 4 > table_size ) + return FT_THROW( Invalid_File_Format ); + + if ( FT_STREAM_SEEK( FT_STREAM_POS() + offset ) || + FT_FRAME_ENTER( 4 ) ) + return error; + + ppem = FT_GET_USHORT(); + resolution = FT_GET_USHORT(); + + FT_UNUSED( resolution ); /* What to do with this? */ + + FT_FRAME_EXIT(); + + upem = face->header.Units_Per_EM; + hori = &face->horizontal; + + metrics->x_ppem = ppem; + metrics->y_ppem = ppem; + + ppem_ = (FT_Pos)ppem; + + metrics->ascender = + FT_MulDiv( hori->Ascender, ppem_ * 64, upem ); + metrics->descender = + FT_MulDiv( hori->Descender, ppem_ * 64, upem ); + metrics->height = + FT_MulDiv( hori->Ascender - hori->Descender + hori->Line_Gap, + ppem_ * 64, upem ); + metrics->max_advance = + FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem ); + + return error; + } + + default: + return FT_THROW( Unknown_File_Format ); + } } @@ -234,9 +460,11 @@ p += 34; decoder->bit_depth = *p; - if ( decoder->strike_index_array > face->sbit_table_size || - decoder->strike_index_array + 8 * decoder->strike_index_count > - face->sbit_table_size ) + /* decoder->strike_index_array + */ + /* 8 * decoder->strike_index_count > face->sbit_table_size ? */ + if ( decoder->strike_index_array > face->sbit_table_size || + decoder->strike_index_count > + ( face->sbit_table_size - decoder->strike_index_array ) / 8 ) error = FT_THROW( Invalid_File_Format ); } @@ -253,13 +481,12 @@ static FT_Error - tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder, - FT_UInt load_flags ) + tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) { FT_Error error = FT_Err_Ok; FT_UInt width, height; FT_Bitmap* map = decoder->bitmap; - FT_Long size; + FT_ULong size; if ( !decoder->metrics_loaded ) @@ -271,48 +498,39 @@ width = decoder->metrics->width; height = decoder->metrics->height; - map->width = (int)width; - map->rows = (int)height; + map->width = width; + map->rows = height; switch ( decoder->bit_depth ) { case 1: map->pixel_mode = FT_PIXEL_MODE_MONO; - map->pitch = ( map->width + 7 ) >> 3; + map->pitch = (int)( ( map->width + 7 ) >> 3 ); map->num_grays = 2; break; case 2: map->pixel_mode = FT_PIXEL_MODE_GRAY2; - map->pitch = ( map->width + 3 ) >> 2; + map->pitch = (int)( ( map->width + 3 ) >> 2 ); map->num_grays = 4; break; case 4: map->pixel_mode = FT_PIXEL_MODE_GRAY4; - map->pitch = ( map->width + 1 ) >> 1; + map->pitch = (int)( ( map->width + 1 ) >> 1 ); map->num_grays = 16; break; case 8: map->pixel_mode = FT_PIXEL_MODE_GRAY; - map->pitch = map->width; + map->pitch = (int)( map->width ); map->num_grays = 256; break; case 32: - if ( load_flags & FT_LOAD_COLOR ) - { - map->pixel_mode = FT_PIXEL_MODE_BGRA; - map->pitch = map->width * 4; - map->num_grays = 256; - } - else - { - map->pixel_mode = FT_PIXEL_MODE_GRAY; - map->pitch = map->width; - map->num_grays = 256; - } + map->pixel_mode = FT_PIXEL_MODE_BGRA; + map->pitch = (int)( map->width * 4 ); + map->num_grays = 256; break; default: @@ -320,7 +538,7 @@ goto Exit; } - size = map->rows * map->pitch; + size = map->rows * (FT_ULong)map->pitch; /* check that there is no empty image */ if ( size == 0 ) @@ -368,13 +586,20 @@ p += 3; } + else + { + /* avoid uninitialized data in case there is no vertical info -- */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + } decoder->metrics_loaded = 1; *pp = p; return FT_Err_Ok; Fail: - FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" )); + FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table\n" )); return FT_THROW( Invalid_Argument ); } @@ -382,33 +607,35 @@ /* forward declaration */ static FT_Error tt_sbit_decoder_load_image( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_UInt glyph_index, FT_Int x_pos, - FT_Int y_pos ); + FT_Int y_pos, + FT_UInt recurse_count ); - typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, - FT_UInt load_flags, - FT_Byte* p, - FT_Byte* plimit, - FT_Int x_pos, - FT_Int y_pos ); + typedef FT_Error (*TT_SBitDecoder_LoadFunc)( + TT_SBitDecoder decoder, + FT_Byte* p, + FT_Byte* plimit, + FT_Int x_pos, + FT_Int y_pos, + FT_UInt recurse_count ); static FT_Error tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_Byte* line; - FT_Int bit_height, bit_width, pitch, width, height, line_bits, h; + FT_Int pitch, width, height, line_bits, h; + FT_UInt bit_height, bit_width; FT_Bitmap* bitmap; - FT_UNUSED( load_flags ); + FT_UNUSED( recurse_count ); /* check that we can write the glyph into the bitmap */ @@ -423,8 +650,8 @@ line_bits = width * decoder->bit_depth; - if ( x_pos < 0 || x_pos + width > bit_width || - y_pos < 0 || y_pos + height > bit_height ) + if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width || + y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height ) { FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:" " invalid bitmap dimensions\n" )); @@ -538,19 +765,20 @@ static FT_Error tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_Byte* line; - FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits; + FT_Int pitch, width, height, line_bits, h, nbits; + FT_UInt bit_height, bit_width; FT_Bitmap* bitmap; FT_UShort rval; - FT_UNUSED( load_flags ); + FT_UNUSED( recurse_count ); /* check that we can write the glyph into the bitmap */ @@ -565,8 +793,8 @@ line_bits = width * decoder->bit_depth; - if ( x_pos < 0 || x_pos + width > bit_width || - y_pos < 0 || y_pos + height > bit_height ) + if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width || + y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height ) { FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:" " invalid bitmap dimensions\n" )); @@ -581,6 +809,12 @@ goto Exit; } + if ( !line_bits || !height ) + { + /* nothing to do */ + goto Exit; + } + /* now do the blit */ /* adjust `line' to point to the first byte of the bitmap */ @@ -664,21 +898,21 @@ static FT_Error tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_UInt num_components, nn; - FT_Char horiBearingX = decoder->metrics->horiBearingX; - FT_Char horiBearingY = decoder->metrics->horiBearingY; - FT_Byte horiAdvance = decoder->metrics->horiAdvance; - FT_Char vertBearingX = decoder->metrics->vertBearingX; - FT_Char vertBearingY = decoder->metrics->vertBearingY; - FT_Byte vertAdvance = decoder->metrics->vertAdvance; + FT_Char horiBearingX = (FT_Char)decoder->metrics->horiBearingX; + FT_Char horiBearingY = (FT_Char)decoder->metrics->horiBearingY; + FT_Byte horiAdvance = (FT_Byte)decoder->metrics->horiAdvance; + FT_Char vertBearingX = (FT_Char)decoder->metrics->vertBearingX; + FT_Char vertBearingY = (FT_Char)decoder->metrics->vertBearingY; + FT_Byte vertAdvance = (FT_Byte)decoder->metrics->vertAdvance; if ( p + 2 > limit ) @@ -702,8 +936,11 @@ /* NB: a recursive call */ - error = tt_sbit_decoder_load_image( decoder, load_flags, gindex, - x_pos + dx, y_pos + dy ); + error = tt_sbit_decoder_load_image( decoder, + gindex, + x_pos + dx, + y_pos + dy, + recurse_count + 1 ); if ( error ) break; } @@ -732,16 +969,16 @@ static FT_Error tt_sbit_decoder_load_png( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_ULong png_len; - FT_UNUSED( load_flags ); + FT_UNUSED( recurse_count ); if ( limit - p < 4 ) @@ -759,14 +996,15 @@ goto Exit; } - error = Load_SBit_Png( decoder->bitmap, + error = Load_SBit_Png( decoder->face->root.glyph, x_pos, y_pos, decoder->bit_depth, decoder->metrics, decoder->stream->memory, p, - png_len ); + png_len, + FALSE ); Exit: if ( !error ) @@ -779,12 +1017,12 @@ static FT_Error tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_UInt glyph_format, FT_ULong glyph_start, FT_ULong glyph_size, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error; FT_Stream stream = decoder->stream; @@ -794,7 +1032,8 @@ /* seek into the EBDT table now */ - if ( glyph_start + glyph_size > decoder->ebdt_size ) + if ( !glyph_size || + glyph_start + glyph_size > decoder->ebdt_size ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -843,8 +1082,36 @@ break; case 2: - case 5: case 7: + { + /* Don't trust `glyph_format'. For example, Apple's main Korean */ + /* system font, `AppleMyungJo.ttf' (version 7.0d2e6), uses glyph */ + /* format 7, but the data is format 6. We check whether we have */ + /* an excessive number of bytes in the image: If it is equal to */ + /* the value for a byte-aligned glyph, use the other loading */ + /* routine. */ + /* */ + /* Note that for some (width,height) combinations, where the */ + /* width is not a multiple of 8, the sizes for bit- and */ + /* byte-aligned data are equal, for example (7,7) or (15,6). We */ + /* then prefer what `glyph_format' specifies. */ + + FT_UInt width = decoder->metrics->width; + FT_UInt height = decoder->metrics->height; + + FT_UInt bit_size = ( width * height + 7 ) >> 3; + FT_UInt byte_size = height * ( ( width + 7 ) >> 3 ); + + + if ( bit_size < byte_size && + byte_size == (FT_UInt)( p_limit - p ) ) + loader = tt_sbit_decoder_load_byte_aligned; + else + loader = tt_sbit_decoder_load_bit_aligned; + } + break; + + case 5: loader = tt_sbit_decoder_load_bit_aligned; break; @@ -859,12 +1126,15 @@ loader = tt_sbit_decoder_load_compound; break; -#ifdef FT_CONFIG_OPTION_USE_PNG case 17: /* small metrics, PNG image data */ case 18: /* big metrics, PNG image data */ case 19: /* metrics in EBLC, PNG image data */ +#ifdef FT_CONFIG_OPTION_USE_PNG loader = tt_sbit_decoder_load_png; break; +#else + error = FT_THROW( Unimplemented_Feature ); + goto Fail; #endif /* FT_CONFIG_OPTION_USE_PNG */ default: @@ -874,64 +1144,12 @@ if ( !decoder->bitmap_allocated ) { - error = tt_sbit_decoder_alloc_bitmap( decoder, load_flags ); + error = tt_sbit_decoder_alloc_bitmap( decoder ); if ( error ) goto Fail; } - if ( decoder->bit_depth == 32 && - decoder->bitmap->pixel_mode != FT_PIXEL_MODE_BGRA ) - { - /* Flatten color bitmaps if color was not requested. */ - - FT_Library library = decoder->face->root.glyph->library; - FT_Memory memory = decoder->stream->memory; - - FT_Bitmap color, *orig; - - - if ( decoder->bitmap->pixel_mode != FT_PIXEL_MODE_GRAY || - x_pos != 0 || y_pos != 0 ) - { - /* Shouldn't happen. */ - error = FT_THROW( Invalid_Table ); - goto Fail; - } - - FT_Bitmap_New( &color ); - - color.rows = decoder->bitmap->rows; - color.width = decoder->bitmap->width; - color.pitch = color.width * 4; - color.pixel_mode = FT_PIXEL_MODE_BGRA; - - if ( FT_ALLOC( color.buffer, color.rows * color.pitch ) ) - goto Fail; - - orig = decoder->bitmap; - decoder->bitmap = &color; - - error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); - - decoder->bitmap = orig; - - /* explicitly test against FT_Err_Ok to avoid compiler warnings */ - /* (we do an assignment within a conditional) */ - if ( error || - ( error = FT_Bitmap_Convert( library, - &color, - decoder->bitmap, - 1 ) ) != FT_Err_Ok ) - { - FT_Bitmap_Done( library, &color ); - goto Fail; - } - - FT_Bitmap_Done( library, &color ); - } - - else - error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); + error = loader( decoder, p, p_limit, x_pos, y_pos, recurse_count ); } Fail: @@ -944,16 +1162,11 @@ static FT_Error tt_sbit_decoder_load_image( TT_SBitDecoder decoder, - FT_UInt load_flags, FT_UInt glyph_index, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { - /* - * First, we find the correct strike range that applies to this - * glyph index. - */ - FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; FT_Byte* p_limit = decoder->eblc_limit; FT_ULong num_ranges = decoder->strike_index_count; @@ -961,6 +1174,17 @@ FT_ULong image_start = 0, image_end = 0, image_offset; + /* arbitrary recursion limit */ + if ( recurse_count > 100 ) + { + FT_TRACE4(( "tt_sbit_decoder_load_image:" + " recursion depth exceeded\n" )); + goto Failure; + } + + + /* First, we find the correct strike range that applies to this */ + /* glyph index. */ for ( ; num_ranges > 0; num_ranges-- ) { start = FT_NEXT_USHORT( p ); @@ -993,17 +1217,15 @@ switch ( index_format ) { case 1: /* 4-byte offsets relative to `image_offset' */ - { - p += 4 * ( glyph_index - start ); - if ( p + 8 > p_limit ) - goto NoBitmap; + p += 4 * ( glyph_index - start ); + if ( p + 8 > p_limit ) + goto NoBitmap; - image_start = FT_NEXT_ULONG( p ); - image_end = FT_NEXT_ULONG( p ); + image_start = FT_NEXT_ULONG( p ); + image_end = FT_NEXT_ULONG( p ); - if ( image_start == image_end ) /* missing glyph */ - goto NoBitmap; - } + if ( image_start == image_end ) /* missing glyph */ + goto NoBitmap; break; case 2: /* big metrics, constant image size */ @@ -1025,17 +1247,15 @@ break; case 3: /* 2-byte offsets relative to 'image_offset' */ - { - p += 2 * ( glyph_index - start ); - if ( p + 4 > p_limit ) - goto NoBitmap; + p += 2 * ( glyph_index - start ); + if ( p + 4 > p_limit ) + goto NoBitmap; - image_start = FT_NEXT_USHORT( p ); - image_end = FT_NEXT_USHORT( p ); + image_start = FT_NEXT_USHORT( p ); + image_end = FT_NEXT_USHORT( p ); - if ( image_start == image_end ) /* missing glyph */ - goto NoBitmap; - } + if ( image_start == image_end ) /* missing glyph */ + goto NoBitmap; break; case 4: /* sparse glyph array with (glyph,offset) pairs */ @@ -1049,7 +1269,8 @@ num_glyphs = FT_NEXT_ULONG( p ); /* overflow check for p + ( num_glyphs + 1 ) * 4 */ - if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) + if ( p + 4 > p_limit || + num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) goto NoBitmap; for ( mm = 0; mm < num_glyphs; mm++ ) @@ -1124,12 +1345,12 @@ image_format, glyph_index )); return tt_sbit_decoder_load_bitmap( decoder, - load_flags, image_format, image_start, image_end, x_pos, - y_pos ); + y_pos, + recurse_count ); Failure: return FT_THROW( Invalid_Table ); @@ -1142,6 +1363,130 @@ } + static FT_Error + tt_face_load_sbix_image( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_Stream stream, + FT_Bitmap *map, + TT_SBit_MetricsRec *metrics ) + { + FT_UInt sbix_pos, strike_offset, glyph_start, glyph_end; + FT_ULong table_size; + FT_Int originOffsetX, originOffsetY; + FT_Tag graphicType; + FT_Int recurse_depth = 0; + + FT_Error error; + FT_Byte* p; + + FT_UNUSED( map ); + + + metrics->width = 0; + metrics->height = 0; + + p = face->sbit_table + 8 + 4 * strike_index; + strike_offset = FT_NEXT_ULONG( p ); + + error = face->goto_table( face, TTAG_sbix, stream, &table_size ); + if ( error ) + return error; + sbix_pos = FT_STREAM_POS(); + + retry: + if ( glyph_index > (FT_UInt)face->root.num_glyphs ) + return FT_THROW( Invalid_Argument ); + + if ( strike_offset >= table_size || + table_size - strike_offset < 4 + glyph_index * 4 + 8 ) + return FT_THROW( Invalid_File_Format ); + + if ( FT_STREAM_SEEK( sbix_pos + strike_offset + 4 + glyph_index * 4 ) || + FT_FRAME_ENTER( 8 ) ) + return error; + + glyph_start = FT_GET_ULONG(); + glyph_end = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + if ( glyph_start == glyph_end ) + return FT_THROW( Invalid_Argument ); + if ( glyph_start > glyph_end || + glyph_end - glyph_start < 8 || + table_size - strike_offset < glyph_end ) + return FT_THROW( Invalid_File_Format ); + + if ( FT_STREAM_SEEK( sbix_pos + strike_offset + glyph_start ) || + FT_FRAME_ENTER( glyph_end - glyph_start ) ) + return error; + + originOffsetX = FT_GET_SHORT(); + originOffsetY = FT_GET_SHORT(); + + graphicType = FT_GET_TAG4(); + + switch ( graphicType ) + { + case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ): + if ( recurse_depth < 4 ) + { + glyph_index = FT_GET_USHORT(); + FT_FRAME_EXIT(); + recurse_depth++; + goto retry; + } + error = FT_THROW( Invalid_File_Format ); + break; + + case FT_MAKE_TAG( 'p', 'n', 'g', ' ' ): +#ifdef FT_CONFIG_OPTION_USE_PNG + error = Load_SBit_Png( face->root.glyph, + 0, + 0, + 32, + metrics, + stream->memory, + stream->cursor, + glyph_end - glyph_start - 8, + TRUE ); +#else + error = FT_THROW( Unimplemented_Feature ); +#endif + break; + + case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ): + case FT_MAKE_TAG( 't', 'i', 'f', 'f' ): + case FT_MAKE_TAG( 'r', 'g', 'b', 'l' ): /* used on iOS 7.1 */ + error = FT_THROW( Unknown_File_Format ); + break; + + default: + error = FT_THROW( Unimplemented_Feature ); + break; + } + + FT_FRAME_EXIT(); + + if ( !error ) + { + FT_Short abearing; + FT_UShort aadvance; + + + tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance ); + + metrics->horiBearingX = (FT_Short)originOffsetX; + metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height ); + metrics->horiAdvance = (FT_UShort)( aadvance * + face->root.size->metrics.x_ppem / + face->header.Units_Per_EM ); + } + + return error; + } + FT_LOCAL( FT_Error ) tt_face_load_sbit_image( TT_Face face, FT_ULong strike_index, @@ -1151,23 +1496,68 @@ FT_Bitmap *map, TT_SBit_MetricsRec *metrics ) { - TT_SBitDecoderRec decoder[1]; - FT_Error error; + FT_Error error = FT_Err_Ok; - FT_UNUSED( load_flags ); - FT_UNUSED( stream ); - FT_UNUSED( map ); + switch ( (FT_UInt)face->sbit_table_type ) + { + case TT_SBIT_TABLE_TYPE_EBLC: + case TT_SBIT_TABLE_TYPE_CBLC: + { + TT_SBitDecoderRec decoder[1]; - error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); - if ( !error ) + + error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); + if ( !error ) + { + error = tt_sbit_decoder_load_image( decoder, + glyph_index, + 0, + 0, + 0 ); + tt_sbit_decoder_done( decoder ); + } + } + break; + + case TT_SBIT_TABLE_TYPE_SBIX: + error = tt_face_load_sbix_image( face, + strike_index, + glyph_index, + stream, + map, + metrics ); + break; + + default: + error = FT_THROW( Unknown_File_Format ); + break; + } + + /* Flatten color bitmaps if color was not requested. */ + if ( !error && + !( load_flags & FT_LOAD_COLOR ) && + map->pixel_mode == FT_PIXEL_MODE_BGRA ) { - error = tt_sbit_decoder_load_image( decoder, - load_flags, - glyph_index, - 0, - 0 ); - tt_sbit_decoder_done( decoder ); + FT_Bitmap new_map; + FT_Library library = face->root.glyph->library; + + + FT_Bitmap_Init( &new_map ); + + /* Convert to 8bit grayscale. */ + error = FT_Bitmap_Convert( library, map, &new_map, 1 ); + if ( error ) + FT_Bitmap_Done( library, &new_map ); + else + { + map->pixel_mode = new_map.pixel_mode; + map->pitch = new_map.pitch; + map->num_grays = new_map.num_grays; + + ft_glyphslot_set_bitmap( face->root.glyph, new_map.buffer ); + face->root.glyph->internal->flags |= FT_GLYPH_OWN_BITMAP; + } } return error; diff --git a/drivers/freetype/freetype/src/sfnt/ttsbit.h b/drivers/freetype/src/sfnt/ttsbit.h index ea0b5f8ada..d8a8167083 100644 --- a/drivers/freetype/freetype/src/sfnt/ttsbit.h +++ b/drivers/freetype/src/sfnt/ttsbit.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (specification). */ /* */ -/* Copyright 1996-2008, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTSBIT_H__ -#define __TTSBIT_H__ +#ifndef TTSBIT_H_ +#define TTSBIT_H_ #include <ft2build.h> @@ -28,11 +28,11 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - tt_face_load_eblc( TT_Face face, + tt_face_load_sbit( TT_Face face, FT_Stream stream ); FT_LOCAL( void ) - tt_face_free_eblc( TT_Face face ); + tt_face_free_sbit( TT_Face face ); FT_LOCAL( FT_Error ) @@ -57,7 +57,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTSBIT_H__ */ +#endif /* TTSBIT_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/smooth/Jamfile b/drivers/freetype/src/smooth/Jamfile index a8496aa2c2..a388c11d91 100644 --- a/drivers/freetype/freetype/src/smooth/Jamfile +++ b/drivers/freetype/src/smooth/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/smooth Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,10 @@ SubDir FT2_TOP $(FT2_SRC_DIR) smooth ; if $(FT2_MULTI) { - _sources = ftgrays ftsmooth ftspic ; + _sources = ftgrays + ftsmooth + ftspic + ; } else { diff --git a/drivers/freetype/freetype/src/smooth/ftgrays.c b/drivers/freetype/src/smooth/ftgrays.c index 7532a35829..0bf3ac6ffb 100644 --- a/drivers/freetype/freetype/src/smooth/ftgrays.c +++ b/drivers/freetype/src/smooth/ftgrays.c @@ -4,7 +4,7 @@ /* */ /* A new `perfect' anti-aliasing renderer (body). */ /* */ -/* Copyright 2000-2003, 2005-2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,7 @@ /*************************************************************************/ /* */ /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* defining the STANDALONE_ macro when compiling it. You also need to */ /* put the files `ftgrays.h' and `ftimage.h' into the current */ /* compilation directory. Typically, you could do something like */ /* */ @@ -27,9 +27,9 @@ /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ /* same directory */ /* */ - /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ + /* - compile `ftgrays' with the STANDALONE_ macro defined, as in */ /* */ - /* cc -c -D_STANDALONE_ ftgrays.c */ + /* cc -c -DSTANDALONE_ ftgrays.c */ /* */ /* The renderer can be initialized with a call to */ /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ @@ -91,13 +91,37 @@ #define FT_COMPONENT trace_smooth -#ifdef _STANDALONE_ +#ifdef STANDALONE_ + + + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ +#define FT_RENDER_POOL_SIZE 16384L /* Auxiliary macros for token concatenation. */ #define FT_ERR_XCAT( x, y ) x ## y #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) + +#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) +#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) +#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) + + + /* + * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' + * algorithm. We use alpha = 1, beta = 3/8, giving us results with a + * largest error less than 7% compared to the exact value. + */ +#define FT_HYPOT( x, y ) \ + ( x = FT_ABS( x ), \ + y = FT_ABS( y ), \ + x > y ? x + ( 3 * y >> 3 ) \ + : y + ( 3 * x >> 3 ) ) + /* define this to dump debugging information */ /* #define FT_DEBUG_LEVEL_TRACE */ @@ -112,8 +136,10 @@ #include <string.h> #include <setjmp.h> #include <limits.h> -#define FT_UINT_MAX UINT_MAX -#define FT_INT_MAX INT_MAX +#define FT_CHAR_BIT CHAR_BIT +#define FT_UINT_MAX UINT_MAX +#define FT_INT_MAX INT_MAX +#define FT_ULONG_MAX ULONG_MAX #define ft_memset memset @@ -231,7 +257,7 @@ typedef ptrdiff_t FT_PtrDist; }; -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include <ft2build.h> @@ -249,7 +275,7 @@ typedef ptrdiff_t FT_PtrDist; #define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ #ifndef FT_MEM_SET @@ -277,7 +303,7 @@ typedef ptrdiff_t FT_PtrDist; #else /* FT_STATIC_RASTER */ -#define RAS_ARG /* empty */ +#define RAS_ARG void #define RAS_ARG_ /* empty */ #define RAS_VAR /* empty */ #define RAS_VAR_ /* empty */ @@ -293,23 +319,65 @@ typedef ptrdiff_t FT_PtrDist; #undef TRUNC #undef SCALED -#define ONE_PIXEL ( 1L << PIXEL_BITS ) -#define PIXEL_MASK ( -1L << PIXEL_BITS ) +#define ONE_PIXEL ( 1 << PIXEL_BITS ) #define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) -#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) +#define SUBPIXELS( x ) ( (TPos)(x) * ONE_PIXEL ) #define FLOOR( x ) ( (x) & -ONE_PIXEL ) #define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) #define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) #if PIXEL_BITS >= 6 -#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) +#define UPSCALE( x ) ( (x) * ( ONE_PIXEL >> 6 ) ) #define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) #else #define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) -#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) +#define DOWNSCALE( x ) ( (x) * ( 64 >> PIXEL_BITS ) ) #endif + /* Compute `dividend / divisor' and return both its quotient and */ + /* remainder, cast to a specific type. This macro also ensures that */ + /* the remainder is always positive. */ +#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \ + FT_BEGIN_STMNT \ + (quotient) = (type)( (dividend) / (divisor) ); \ + (remainder) = (type)( (dividend) % (divisor) ); \ + if ( (remainder) < 0 ) \ + { \ + (quotient)--; \ + (remainder) += (type)(divisor); \ + } \ + FT_END_STMNT + +#ifdef __arm__ + /* Work around a bug specific to GCC which make the compiler fail to */ + /* optimize a division and modulo operation on the same parameters */ + /* into a single call to `__aeabi_idivmod'. See */ + /* */ + /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 */ +#undef FT_DIV_MOD +#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \ + FT_BEGIN_STMNT \ + (quotient) = (type)( (dividend) / (divisor) ); \ + (remainder) = (type)( (dividend) - (quotient) * (divisor) ); \ + if ( (remainder) < 0 ) \ + { \ + (quotient)--; \ + (remainder) += (type)(divisor); \ + } \ + FT_END_STMNT +#endif /* __arm__ */ + + + /* These macros speed up repetitive divisions by replacing them */ + /* with multiplications and right shifts. */ +#define FT_UDIVPREP( b ) \ + long b ## _r = (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) +#define FT_UDIV( a, b ) \ + ( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \ + ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) ) + + /*************************************************************************/ /* */ /* TYPE DEFINITIONS */ @@ -319,38 +387,16 @@ typedef ptrdiff_t FT_PtrDist; /* need to define them to "float" or "double" when experimenting with */ /* new algorithms */ - typedef long TCoord; /* integer scanline/pixel coordinate */ typedef long TPos; /* sub-pixel coordinate */ - - /* determine the type used to store cell areas. This normally takes at */ - /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ - /* `long' instead of `int', otherwise bad things happen */ - -#if PIXEL_BITS <= 7 - - typedef int TArea; - -#else /* PIXEL_BITS >= 8 */ - - /* approximately determine the size of integers using an ANSI-C header */ -#if FT_UINT_MAX == 0xFFFFU - typedef long TArea; -#else - typedef int TArea; -#endif - -#endif /* PIXEL_BITS >= 8 */ - - - /* maximum number of gray spans in a call to the span callback */ -#define FT_MAX_GRAY_SPANS 32 + typedef int TCoord; /* integer scanline/pixel coordinate */ + typedef int TArea; /* cell areas, coordinate products */ typedef struct TCell_* PCell; typedef struct TCell_ { - TPos x; /* same with gray_TWorker.ex */ + TCoord x; /* same with gray_TWorker.ex */ TCoord cover; /* same with gray_TWorker.cover */ TArea area; PCell next; @@ -358,6 +404,17 @@ typedef ptrdiff_t FT_PtrDist; } TCell; + /* maximum number of gray spans in a call to the span callback */ +#define FT_MAX_GRAY_SPANS 32 + + /* maximum number of gray cells in the buffer */ +#if FT_RENDER_POOL_SIZE > 2048 +#define FT_MAX_GRAY_POOL ( FT_RENDER_POOL_SIZE / sizeof ( TCell ) ) +#else +#define FT_MAX_GRAY_POOL ( 2048 / sizeof ( TCell ) ) +#endif + + #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ /* We disable the warning `structure was padded due to */ /* __declspec(align())' in order to compile cleanly with */ @@ -368,10 +425,12 @@ typedef ptrdiff_t FT_PtrDist; typedef struct gray_TWorker_ { + ft_jmp_buf jump_buffer; + TCoord ex, ey; - TPos min_ex, max_ex; - TPos min_ey, max_ey; - TPos count_ex, count_ey; + TCoord min_ex, max_ex; + TCoord min_ey, max_ey; + TCoord count_ex, count_ey; TArea area; TCoord cover; @@ -381,17 +440,10 @@ typedef ptrdiff_t FT_PtrDist; FT_PtrDist max_cells; FT_PtrDist num_cells; - TCoord cx, cy; TPos x, y; - TPos last_ey; - - FT_Vector bez_stack[32 * 3 + 1]; - int lev_stack[32]; - FT_Outline outline; FT_Bitmap target; - FT_BBox clip_box; FT_Span gray_spans[FT_MAX_GRAY_SPANS]; int num_gray_spans; @@ -400,16 +452,7 @@ typedef ptrdiff_t FT_PtrDist; void* render_span_data; int span_y; - int band_size; - int band_shoot; - - ft_jmp_buf jump_buffer; - - void* buffer; - long buffer_size; - PCell* ycells; - TPos ycount; } gray_TWorker, *gray_PWorker; @@ -427,80 +470,37 @@ typedef ptrdiff_t FT_PtrDist; typedef struct gray_TRaster_ { - void* buffer; - long buffer_size; - int band_size; void* memory; - gray_PWorker worker; } gray_TRaster, *gray_PRaster; +#ifdef FT_DEBUG_LEVEL_TRACE - /*************************************************************************/ - /* */ - /* Initialize the cells table. */ - /* */ - static void - gray_init_cells( RAS_ARG_ void* buffer, - long byte_size ) - { - ras.buffer = buffer; - ras.buffer_size = byte_size; - - ras.ycells = (PCell*) buffer; - ras.cells = NULL; - ras.max_cells = 0; - ras.num_cells = 0; - ras.area = 0; - ras.cover = 0; - ras.invalid = 1; - } - - - /*************************************************************************/ - /* */ - /* Compute the outline bounding box. */ - /* */ + /* to be called while in the debugger -- */ + /* this function causes a compiler warning since it is unused otherwise */ static void - gray_compute_cbox( RAS_ARG ) + gray_dump_cells( RAS_ARG ) { - FT_Outline* outline = &ras.outline; - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; + int yindex; - if ( outline->n_points <= 0 ) + for ( yindex = 0; yindex < ras.count_ey; yindex++ ) { - ras.min_ex = ras.max_ex = 0; - ras.min_ey = ras.max_ey = 0; - return; - } - - ras.min_ex = ras.max_ex = vec->x; - ras.min_ey = ras.max_ey = vec->y; - - vec++; + PCell cell; - for ( ; vec < limit; vec++ ) - { - TPos x = vec->x; - TPos y = vec->y; + printf( "%3d:", yindex ); - if ( x < ras.min_ex ) ras.min_ex = x; - if ( x > ras.max_ex ) ras.max_ex = x; - if ( y < ras.min_ey ) ras.min_ey = y; - if ( y > ras.max_ey ) ras.max_ey = y; + for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) + printf( " (%3d, c:%4d, a:%6d)", + cell->x, cell->cover, cell->area ); + printf( "\n" ); } - - /* truncate the bounding box to integer pixels */ - ras.min_ex = ras.min_ex >> 6; - ras.min_ey = ras.min_ey >> 6; - ras.max_ex = ( ras.max_ex + 63 ) >> 6; - ras.max_ey = ( ras.max_ey + 63 ) >> 6; } +#endif /* FT_DEBUG_LEVEL_TRACE */ + /*************************************************************************/ /* */ @@ -510,7 +510,7 @@ typedef ptrdiff_t FT_PtrDist; gray_find_cell( RAS_ARG ) { PCell *pcell, cell; - TPos x = ras.ex; + TCoord x = ras.ex; if ( x > ras.count_ex ) @@ -548,7 +548,7 @@ typedef ptrdiff_t FT_PtrDist; static void gray_record_cell( RAS_ARG ) { - if ( !ras.invalid && ( ras.area | ras.cover ) ) + if ( ras.area | ras.cover ) { PCell cell = gray_find_cell( RAS_VAR ); @@ -597,12 +597,12 @@ typedef ptrdiff_t FT_PtrDist; ras.area = 0; ras.cover = 0; + ras.ex = ex; + ras.ey = ey; } - ras.ex = ex; - ras.ey = ey; - ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey || - ex >= ras.count_ex ); + ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey || + ex >= ras.count_ex ); } @@ -615,21 +615,21 @@ typedef ptrdiff_t FT_PtrDist; TCoord ey ) { if ( ex > ras.max_ex ) - ex = (TCoord)( ras.max_ex ); + ex = ras.max_ex; if ( ex < ras.min_ex ) - ex = (TCoord)( ras.min_ex - 1 ); + ex = ras.min_ex - 1; ras.area = 0; ras.cover = 0; ras.ex = ex - ras.min_ex; ras.ey = ey - ras.min_ey; - ras.last_ey = SUBPIXELS( ey ); ras.invalid = 0; gray_set_cell( RAS_VAR_ ex, ey ); } +#ifndef FT_LONG64 /*************************************************************************/ /* */ @@ -642,17 +642,13 @@ typedef ptrdiff_t FT_PtrDist; TPos x2, TCoord y2 ) { - TCoord ex1, ex2, fx1, fx2, delta, mod; - long p, first, dx; + TCoord ex1, ex2, fx1, fx2, first, delta, mod; + TPos p, dx; int incr; - dx = x2 - x1; - ex1 = TRUNC( x1 ); ex2 = TRUNC( x2 ); - fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); - fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); /* trivial case. Happens often */ if ( y1 == y2 ) @@ -661,6 +657,9 @@ typedef ptrdiff_t FT_PtrDist; return; } + fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); + fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); + /* everything is located in a single cell. That is easy! */ /* */ if ( ex1 == ex2 ) @@ -677,6 +676,7 @@ typedef ptrdiff_t FT_PtrDist; p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); first = ONE_PIXEL; incr = 1; + dx = x2 - x1; if ( dx < 0 ) { @@ -686,13 +686,7 @@ typedef ptrdiff_t FT_PtrDist; dx = -dx; } - delta = (TCoord)( p / dx ); - mod = (TCoord)( p % dx ); - if ( mod < 0 ) - { - delta--; - mod += (TCoord)dx; - } + FT_DIV_MOD( TCoord, p, dx, delta, mod ); ras.area += (TArea)(( fx1 + first ) * delta); ras.cover += delta; @@ -706,18 +700,12 @@ typedef ptrdiff_t FT_PtrDist; TCoord lift, rem; - p = ONE_PIXEL * ( y2 - y1 + delta ); - lift = (TCoord)( p / dx ); - rem = (TCoord)( p % dx ); - if ( rem < 0 ) - { - lift--; - rem += (TCoord)dx; - } + p = ONE_PIXEL * ( y2 - y1 + delta ); + FT_DIV_MOD( TCoord, p, dx, lift, rem ); mod -= (int)dx; - while ( ex1 != ex2 ) + do { delta = lift; mod += rem; @@ -732,7 +720,7 @@ typedef ptrdiff_t FT_PtrDist; y1 += delta; ex1 += incr; gray_set_cell( RAS_VAR_ ex1, ey ); - } + } while ( ex1 != ex2 ); } delta = y2 - y1; @@ -749,38 +737,21 @@ typedef ptrdiff_t FT_PtrDist; gray_render_line( RAS_ARG_ TPos to_x, TPos to_y ) { - TCoord ey1, ey2, fy1, fy2, mod; - TPos dx, dy, x, x2; - long p, first; - int delta, rem, lift, incr; + TCoord ey1, ey2, fy1, fy2, first, delta, mod; + TPos p, dx, dy, x, x2; + int incr; - ey1 = TRUNC( ras.last_ey ); + ey1 = TRUNC( ras.y ); ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ - fy1 = (TCoord)( ras.y - ras.last_ey ); - fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); - - dx = to_x - ras.x; - dy = to_y - ras.y; - - /* XXX: we should do something about the trivial case where dx == 0, */ - /* as it happens very often! */ /* perform vertical clipping */ - { - TCoord min, max; - + if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) || + ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) + goto End; - min = ey1; - max = ey2; - if ( ey1 > ey2 ) - { - min = ey2; - max = ey1; - } - if ( min >= ras.max_ey || max < ras.min_ey ) - goto End; - } + fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) ); + fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); /* everything is on a single scanline */ if ( ey1 == ey2 ) @@ -789,6 +760,9 @@ typedef ptrdiff_t FT_PtrDist; goto End; } + dx = to_x - ras.x; + dy = to_y - ras.y; + /* vertical line - avoid calling gray_render_scanline */ incr = 1; @@ -806,14 +780,14 @@ typedef ptrdiff_t FT_PtrDist; incr = -1; } - delta = (int)( first - fy1 ); + delta = first - fy1; ras.area += (TArea)two_fx * delta; ras.cover += delta; ey1 += incr; gray_set_cell( RAS_VAR_ ex, ey1 ); - delta = (int)( first + first - ONE_PIXEL ); + delta = first + first - ONE_PIXEL; area = (TArea)two_fx * delta; while ( ey1 != ey2 ) { @@ -824,7 +798,7 @@ typedef ptrdiff_t FT_PtrDist; gray_set_cell( RAS_VAR_ ex, ey1 ); } - delta = (int)( fy2 - ONE_PIXEL + first ); + delta = fy2 - ONE_PIXEL + first; ras.area += (TArea)two_fx * delta; ras.cover += delta; @@ -844,63 +818,191 @@ typedef ptrdiff_t FT_PtrDist; dy = -dy; } - delta = (int)( p / dy ); - mod = (int)( p % dy ); - if ( mod < 0 ) - { - delta--; - mod += (TCoord)dy; - } + FT_DIV_MOD( TCoord, p, dy, delta, mod ); x = ras.x + delta; - gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first ); + gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first ); ey1 += incr; gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); if ( ey1 != ey2 ) { - p = ONE_PIXEL * dx; - lift = (int)( p / dy ); - rem = (int)( p % dy ); - if ( rem < 0 ) - { - lift--; - rem += (int)dy; - } - mod -= (int)dy; + TCoord lift, rem; - while ( ey1 != ey2 ) + + p = ONE_PIXEL * dx; + FT_DIV_MOD( TCoord, p, dy, lift, rem ); + mod -= (TCoord)dy; + + do { delta = lift; mod += rem; if ( mod >= 0 ) { - mod -= (int)dy; + mod -= (TCoord)dy; delta++; } x2 = x + delta; - gray_render_scanline( RAS_VAR_ ey1, x, - (TCoord)( ONE_PIXEL - first ), x2, - (TCoord)first ); + gray_render_scanline( RAS_VAR_ ey1, + x, ONE_PIXEL - first, + x2, first ); x = x2; ey1 += incr; gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); - } + } while ( ey1 != ey2 ); } - gray_render_scanline( RAS_VAR_ ey1, x, - (TCoord)( ONE_PIXEL - first ), to_x, - fy2 ); + gray_render_scanline( RAS_VAR_ ey1, + x, ONE_PIXEL - first, + to_x, fy2 ); End: ras.x = to_x; ras.y = to_y; - ras.last_ey = SUBPIXELS( ey2 ); } +#else + + /*************************************************************************/ + /* */ + /* Render a straight line across multiple cells in any direction. */ + /* */ + static void + gray_render_line( RAS_ARG_ TPos to_x, + TPos to_y ) + { + TPos dx, dy, fx1, fy1, fx2, fy2; + TCoord ex1, ex2, ey1, ey2; + + + ey1 = TRUNC( ras.y ); + ey2 = TRUNC( to_y ); + + /* perform vertical clipping */ + if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) || + ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) + goto End; + + ex1 = TRUNC( ras.x ); + ex2 = TRUNC( to_x ); + + fx1 = ras.x - SUBPIXELS( ex1 ); + fy1 = ras.y - SUBPIXELS( ey1 ); + + dx = to_x - ras.x; + dy = to_y - ras.y; + + if ( ex1 == ex2 && ey1 == ey2 ) /* inside one cell */ + ; + else if ( dy == 0 ) /* ex1 != ex2 */ /* any horizontal line */ + { + ex1 = ex2; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } + else if ( dx == 0 ) + { + if ( dy > 0 ) /* vertical line up */ + do + { + fy2 = ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * fx1 * 2; + fy1 = 0; + ey1++; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ey1 != ey2 ); + else /* vertical line down */ + do + { + fy2 = 0; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * fx1 * 2; + fy1 = ONE_PIXEL; + ey1--; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ey1 != ey2 ); + } + else /* any other line */ + { + TPos prod = dx * fy1 - dy * fx1; + FT_UDIVPREP( dx ); + FT_UDIVPREP( dy ); + + + /* The fundamental value `prod' determines which side and the */ + /* exact coordinate where the line exits current cell. It is */ + /* also easily updated when moving from one cell to the next. */ + do + { + if ( prod <= 0 && + prod - dx * ONE_PIXEL > 0 ) /* left */ + { + fx2 = 0; + fy2 = (TPos)FT_UDIV( -prod, -dx ); + prod -= dy * ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = ONE_PIXEL; + fy1 = fy2; + ex1--; + } + else if ( prod - dx * ONE_PIXEL <= 0 && + prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 ) /* up */ + { + prod -= dx * ONE_PIXEL; + fx2 = (TPos)FT_UDIV( -prod, dy ); + fy2 = ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = fx2; + fy1 = 0; + ey1++; + } + else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 && + prod + dy * ONE_PIXEL >= 0 ) /* right */ + { + prod += dy * ONE_PIXEL; + fx2 = ONE_PIXEL; + fy2 = (TPos)FT_UDIV( prod, dx ); + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = 0; + fy1 = fy2; + ex1++; + } + else /* ( prod + dy * ONE_PIXEL < 0 && + prod > 0 ) down */ + { + fx2 = (TPos)FT_UDIV( prod, -dy ); + fy2 = 0; + prod += dx * ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = fx2; + fy1 = ONE_PIXEL; + ey1--; + } + + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ex1 != ex2 || ey1 != ey2 ); + } + + fx2 = to_x - SUBPIXELS( ex2 ); + fy2 = to_y - SUBPIXELS( ey2 ); + + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + + End: + ras.x = to_x; + ras.y = to_y; + } + +#endif static void gray_split_conic( FT_Vector* base ) @@ -926,73 +1028,64 @@ typedef ptrdiff_t FT_PtrDist; gray_render_conic( RAS_ARG_ const FT_Vector* control, const FT_Vector* to ) { + FT_Vector bez_stack[16 * 2 + 1]; /* enough to accommodate bisections */ + FT_Vector* arc = bez_stack; TPos dx, dy; - TPos min, max, y; - int top, level; - int* levels; - FT_Vector* arc; + int draw, split; - levels = ras.lev_stack; - - arc = ras.bez_stack; arc[0].x = UPSCALE( to->x ); arc[0].y = UPSCALE( to->y ); arc[1].x = UPSCALE( control->x ); arc[1].y = UPSCALE( control->y ); arc[2].x = ras.x; arc[2].y = ras.y; - top = 0; + + /* short-cut the arc that crosses the current band */ + if ( ( TRUNC( arc[0].y ) >= ras.max_ey && + TRUNC( arc[1].y ) >= ras.max_ey && + TRUNC( arc[2].y ) >= ras.max_ey ) || + ( TRUNC( arc[0].y ) < ras.min_ey && + TRUNC( arc[1].y ) < ras.min_ey && + TRUNC( arc[2].y ) < ras.min_ey ) ) + { + ras.x = arc[0].x; + ras.y = arc[0].y; + return; + } dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x ); dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y ); if ( dx < dy ) dx = dy; - if ( dx < ONE_PIXEL / 4 ) - goto Draw; - - /* short-cut the arc that crosses the current band */ - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - y = arc[2].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) - goto Draw; - - level = 0; - do + /* We can calculate the number of necessary bisections because */ + /* each bisection predictably reduces deviation exactly 4-fold. */ + /* Even 32-bit deviation would vanish after 16 bisections. */ + draw = 1; + while ( dx > ONE_PIXEL / 4 ) { - dx >>= 2; - level++; - } while ( dx > ONE_PIXEL / 4 ); - - levels[0] = level; + dx >>= 2; + draw <<= 1; + } + /* We use decrement counter to count the total number of segments */ + /* to draw starting from 2^level. Before each draw we split as */ + /* many times as there are trailing zeros in the counter. */ do { - level = levels[top]; - if ( level > 0 ) + split = 1; + while ( ( draw & split ) == 0 ) { gray_split_conic( arc ); arc += 2; - top++; - levels[top] = levels[top - 1] = level - 1; - continue; + split <<= 1; } - Draw: gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - top--; arc -= 2; - } while ( top >= 0 ); + } while ( --draw ); } @@ -1029,11 +1122,13 @@ typedef ptrdiff_t FT_PtrDist; const FT_Vector* control2, const FT_Vector* to ) { - FT_Vector* arc; - TPos min, max, y; + FT_Vector bez_stack[16 * 3 + 1]; /* enough to accommodate bisections */ + FT_Vector* arc = bez_stack; + TPos dx, dy, dx_, dy_; + TPos dx1, dy1, dx2, dy2; + TPos L, s, s_limit; - arc = ras.bez_stack; arc[0].x = UPSCALE( to->x ); arc[0].y = UPSCALE( to->y ); arc[1].x = UPSCALE( control2->x ); @@ -1043,29 +1138,20 @@ typedef ptrdiff_t FT_PtrDist; arc[3].x = ras.x; arc[3].y = ras.y; - /* Short-cut the arc that crosses the current band. */ - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - y = arc[2].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - y = arc[3].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) - goto Draw; + /* short-cut the arc that crosses the current band */ + if ( ( TRUNC( arc[0].y ) >= ras.max_ey && + TRUNC( arc[1].y ) >= ras.max_ey && + TRUNC( arc[2].y ) >= ras.max_ey && + TRUNC( arc[3].y ) >= ras.max_ey ) || + ( TRUNC( arc[0].y ) < ras.min_ey && + TRUNC( arc[1].y ) < ras.min_ey && + TRUNC( arc[2].y ) < ras.min_ey && + TRUNC( arc[3].y ) < ras.min_ey ) ) + { + ras.x = arc[0].x; + ras.y = arc[0].y; + return; + } for (;;) { @@ -1074,91 +1160,53 @@ typedef ptrdiff_t FT_PtrDist; /* F. Hain, at */ /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */ - { - TPos dx, dy, dx_, dy_; - TPos dx1, dy1, dx2, dy2; - TPos L, s, s_limit; - - - /* dx and dy are x and y components of the P0-P3 chord vector. */ - dx = arc[3].x - arc[0].x; - dy = arc[3].y - arc[0].y; - - /* L is an (under)estimate of the Euclidean distance P0-P3. */ - /* */ - /* If dx >= dy, then r = sqrt(dx^2 + dy^2) can be overestimated */ - /* with least maximum error by */ - /* */ - /* r_upperbound = dx + (sqrt(2) - 1) * dy , */ - /* */ - /* where sqrt(2) - 1 can be (over)estimated by 107/256, giving an */ - /* error of no more than 8.4%. */ - /* */ - /* Similarly, some elementary calculus shows that r can be */ - /* underestimated with least maximum error by */ - /* */ - /* r_lowerbound = sqrt(2 + sqrt(2)) / 2 * dx */ - /* + sqrt(2 - sqrt(2)) / 2 * dy . */ - /* */ - /* 236/256 and 97/256 are (under)estimates of the two algebraic */ - /* numbers, giving an error of no more than 8.1%. */ - - dx_ = FT_ABS( dx ); - dy_ = FT_ABS( dy ); - - /* This is the same as */ - /* */ - /* L = ( 236 * FT_MAX( dx_, dy_ ) */ - /* + 97 * FT_MIN( dx_, dy_ ) ) >> 8; */ - L = ( dx_ > dy_ ? 236 * dx_ + 97 * dy_ - : 97 * dx_ + 236 * dy_ ) >> 8; - - /* Avoid possible arithmetic overflow below by splitting. */ - if ( L > 32767 ) - goto Split; - - /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ - s_limit = L * (TPos)( ONE_PIXEL / 6 ); - - /* s is L * the perpendicular distance from P1 to the line P0-P3. */ - dx1 = arc[1].x - arc[0].x; - dy1 = arc[1].y - arc[0].y; - s = FT_ABS( dy * dx1 - dx * dy1 ); - - if ( s > s_limit ) - goto Split; - - /* s is L * the perpendicular distance from P2 to the line P0-P3. */ - dx2 = arc[2].x - arc[0].x; - dy2 = arc[2].y - arc[0].y; - s = FT_ABS( dy * dx2 - dx * dy2 ); - - if ( s > s_limit ) - goto Split; - - /* Split super curvy segments where the off points are so far - from the chord that the angles P0-P1-P3 or P0-P2-P3 become - acute as detected by appropriate dot products. */ - if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || - dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) - goto Split; - - /* No reason to split. */ - goto Draw; - } + /* dx and dy are x and y components of the P0-P3 chord vector. */ + dx = dx_ = arc[3].x - arc[0].x; + dy = dy_ = arc[3].y - arc[0].y; - Split: - gray_split_cubic( arc ); - arc += 3; - continue; + L = FT_HYPOT( dx_, dy_ ); + + /* Avoid possible arithmetic overflow below by splitting. */ + if ( L > 32767 ) + goto Split; + + /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ + s_limit = L * (TPos)( ONE_PIXEL / 6 ); + + /* s is L * the perpendicular distance from P1 to the line P0-P3. */ + dx1 = arc[1].x - arc[0].x; + dy1 = arc[1].y - arc[0].y; + s = FT_ABS( dy * dx1 - dx * dy1 ); + + if ( s > s_limit ) + goto Split; + + /* s is L * the perpendicular distance from P2 to the line P0-P3. */ + dx2 = arc[2].x - arc[0].x; + dy2 = arc[2].y - arc[0].y; + s = FT_ABS( dy * dx2 - dx * dy2 ); + + if ( s > s_limit ) + goto Split; + + /* Split super curvy segments where the off points are so far + from the chord that the angles P0-P1-P3 or P0-P2-P3 become + acute as detected by appropriate dot products. */ + if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || + dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) + goto Split; - Draw: gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - if ( arc == ras.bez_stack ) + if ( arc == bez_stack ) return; arc -= 3; + continue; + + Split: + gray_split_cubic( arc ); + arc += 3; } } @@ -1171,7 +1219,8 @@ typedef ptrdiff_t FT_PtrDist; /* record current cell, if any */ - gray_record_cell( RAS_VAR ); + if ( !ras.invalid ) + gray_record_cell( RAS_VAR ); /* start to a new position */ x = UPSCALE( to->x ); @@ -1179,8 +1228,8 @@ typedef ptrdiff_t FT_PtrDist; gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); - worker->x = x; - worker->y = y; + ras.x = x; + ras.y = y; return 0; } @@ -1228,7 +1277,7 @@ typedef ptrdiff_t FT_PtrDist; /* first of all, compute the scanline offset */ p = (unsigned char*)map->buffer - y * map->pitch; if ( map->pitch >= 0 ) - p += (unsigned)( ( map->rows - 1 ) * map->pitch ); + p += ( map->rows - 1 ) * (unsigned int)map->pitch; for ( ; count > 0; count--, spans++ ) { @@ -1237,29 +1286,25 @@ typedef ptrdiff_t FT_PtrDist; if ( coverage ) { + unsigned char* q = p + spans->x; + + /* For small-spans it is faster to do it by ourselves than * calling `memset'. This is mainly due to the cost of the * function call. */ - if ( spans->len >= 8 ) - FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len ); - else + switch ( spans->len ) { - unsigned char* q = p + spans->x; - - - switch ( spans->len ) - { - case 7: *q++ = (unsigned char)coverage; - case 6: *q++ = (unsigned char)coverage; - case 5: *q++ = (unsigned char)coverage; - case 4: *q++ = (unsigned char)coverage; - case 3: *q++ = (unsigned char)coverage; - case 2: *q++ = (unsigned char)coverage; - case 1: *q = (unsigned char)coverage; - default: - ; - } + case 7: *q++ = coverage; + case 6: *q++ = coverage; + case 5: *q++ = coverage; + case 4: *q++ = coverage; + case 3: *q++ = coverage; + case 2: *q++ = coverage; + case 1: *q = coverage; + case 0: break; + default: + FT_MEM_SET( q, coverage, spans->len ); } } } @@ -1269,7 +1314,7 @@ typedef ptrdiff_t FT_PtrDist; static void gray_hline( RAS_ARG_ TCoord x, TCoord y, - TPos area, + TArea area, TCoord acount ) { int coverage; @@ -1301,16 +1346,8 @@ typedef ptrdiff_t FT_PtrDist; coverage = 255; } - y += (TCoord)ras.min_ey; - x += (TCoord)ras.min_ex; - - /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ - if ( x >= 32767 ) - x = 32767; - - /* FT_Span.y is an integer, so limit our coordinates appropriately */ - if ( y >= FT_INT_MAX ) - y = FT_INT_MAX; + y += ras.min_ey; + x += ras.min_ex; if ( coverage ) { @@ -1321,10 +1358,10 @@ typedef ptrdiff_t FT_PtrDist; /* see whether we can add this span to the current list */ count = ras.num_gray_spans; span = ras.gray_spans + count - 1; - if ( count > 0 && - ras.span_y == y && - (int)span->x + span->len == (int)x && - span->coverage == coverage ) + if ( span->coverage == coverage && + span->x + span->len == x && + ras.span_y == y && + count > 0 ) { span->len = (unsigned short)( span->len + acount ); return; @@ -1356,7 +1393,6 @@ typedef ptrdiff_t FT_PtrDist; ras.num_gray_spans = 0; ras.span_y = (int)y; - count = 0; span = ras.gray_spans; } else @@ -1372,48 +1408,21 @@ typedef ptrdiff_t FT_PtrDist; } -#ifdef FT_DEBUG_LEVEL_TRACE - - /* to be called while in the debugger -- */ - /* this function causes a compiler warning since it is unused otherwise */ - static void - gray_dump_cells( RAS_ARG ) - { - int yindex; - - - for ( yindex = 0; yindex < ras.ycount; yindex++ ) - { - PCell cell; - - - printf( "%3d:", yindex ); - - for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) - printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); - printf( "\n" ); - } - } - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - static void - gray_sweep( RAS_ARG_ const FT_Bitmap* target ) + gray_sweep( RAS_ARG ) { int yindex; - FT_UNUSED( target ); - if ( ras.num_cells == 0 ) return; ras.num_gray_spans = 0; + ras.span_y = 0; FT_TRACE7(( "gray_sweep: start\n" )); - for ( yindex = 0; yindex < ras.ycount; yindex++ ) + for ( yindex = 0; yindex < ras.count_ey; yindex++ ) { PCell cell = ras.ycells[yindex]; TCoord cover = 0; @@ -1422,15 +1431,15 @@ typedef ptrdiff_t FT_PtrDist; for ( ; cell != NULL; cell = cell->next ) { - TPos area; + TArea area; if ( cell->x > x && cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + gray_hline( RAS_VAR_ x, yindex, (TArea)cover * ( ONE_PIXEL * 2 ), cell->x - x ); cover += cell->cover; - area = cover * ( ONE_PIXEL * 2 ) - cell->area; + area = (TArea)cover * ( ONE_PIXEL * 2 ) - cell->area; if ( area != 0 && cell->x >= 0 ) gray_hline( RAS_VAR_ cell->x, yindex, area, 1 ); @@ -1439,7 +1448,7 @@ typedef ptrdiff_t FT_PtrDist; } if ( cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + gray_hline( RAS_VAR_ x, yindex, (TArea)cover * ( ONE_PIXEL * 2 ), ras.count_ex - x ); } @@ -1470,11 +1479,11 @@ typedef ptrdiff_t FT_PtrDist; } -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /*************************************************************************/ /* */ - /* The following function should only compile in stand-alone mode, */ + /* The following functions should only compile in stand-alone mode, */ /* i.e., when building this component without the rest of FreeType. */ /* */ /*************************************************************************/ @@ -1532,7 +1541,10 @@ typedef ptrdiff_t FT_PtrDist; TPos delta; - if ( !outline || !func_interface ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !func_interface ) return FT_THROW( Invalid_Argument ); shift = func_interface->shift; @@ -1749,23 +1761,101 @@ typedef ptrdiff_t FT_PtrDist; return FT_THROW( Invalid_Outline ); } -#endif /* _STANDALONE_ */ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_CBox */ + /* */ + /* <Description> */ + /* Return an outline's `control box'. The control box encloses all */ + /* the outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* that contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component, which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* acbox :: The outline's control box. */ + /* */ + /* <Note> */ + /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ + /* */ + + static void + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ) + { + TPos xMin, yMin, xMax, yMax; + + + if ( outline && acbox ) + { + if ( outline->n_points == 0 ) + { + xMin = 0; + yMin = 0; + xMax = 0; + yMax = 0; + } + else + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + xMin = xMax = vec->x; + yMin = yMax = vec->y; + vec++; + + for ( ; vec < limit; vec++ ) + { + TPos x, y; + + + x = vec->x; + if ( x < xMin ) xMin = x; + if ( x > xMax ) xMax = x; + + y = vec->y; + if ( y < yMin ) yMin = y; + if ( y > yMax ) yMax = y; + } + } + acbox->xMin = xMin; + acbox->xMax = xMax; + acbox->yMin = yMin; + acbox->yMax = yMax; + } + } + +#endif /* STANDALONE_ */ typedef struct gray_TBand_ { - TPos min, max; + TCoord min, max; } gray_TBand; - FT_DEFINE_OUTLINE_FUNCS(func_interface, - (FT_Outline_MoveTo_Func) gray_move_to, - (FT_Outline_LineTo_Func) gray_line_to, - (FT_Outline_ConicTo_Func)gray_conic_to, - (FT_Outline_CubicTo_Func)gray_cubic_to, - 0, - 0 - ) + + FT_DEFINE_OUTLINE_FUNCS( + func_interface, + + (FT_Outline_MoveTo_Func) gray_move_to, + (FT_Outline_LineTo_Func) gray_line_to, + (FT_Outline_ConicTo_Func)gray_conic_to, + (FT_Outline_CubicTo_Func)gray_cubic_to, + 0, + 0 ) + static int gray_convert_glyph_inner( RAS_ARG ) @@ -1781,11 +1871,20 @@ typedef ptrdiff_t FT_PtrDist; if ( ft_setjmp( ras.jump_buffer ) == 0 ) { error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); - gray_record_cell( RAS_VAR ); + if ( !ras.invalid ) + gray_record_cell( RAS_VAR ); + + FT_TRACE7(( "band [%d..%d]: %d cells\n", + ras.min_ey, ras.max_ey, ras.num_cells )); } else + { error = FT_THROW( Memory_Overflow ); + FT_TRACE7(( "band [%d..%d]: to be bisected\n", + ras.min_ey, ras.max_ey )); + } + return error; } @@ -1793,87 +1892,59 @@ typedef ptrdiff_t FT_PtrDist; static int gray_convert_glyph( RAS_ARG ) { - gray_TBand bands[40]; - gray_TBand* volatile band; - int volatile n, num_bands; - TPos volatile min, max, max_y; - FT_BBox* clip; - + TCell buffer[FT_MAX_GRAY_POOL]; + TCoord band_size = FT_MAX_GRAY_POOL / 8; + int num_bands; + TCoord min, max, max_y; + gray_TBand bands[32]; /* enough to accommodate bisections */ + gray_TBand* band; - /* Set up state in the raster object */ - gray_compute_cbox( RAS_VAR ); - - /* clip to target bitmap, exit if nothing to do */ - clip = &ras.clip_box; - - if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || - ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax ) - return 0; - - if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin; - if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin; - - if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax; - if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax; - - ras.count_ex = ras.max_ex - ras.min_ex; - ras.count_ey = ras.max_ey - ras.min_ey; /* set up vertical bands */ - num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); - if ( num_bands == 0 ) - num_bands = 1; - if ( num_bands >= 39 ) - num_bands = 39; - - ras.band_shoot = 0; + if ( ras.count_ey > band_size ) + { + /* two divisions rounded up */ + num_bands = (int)( ( ras.count_ey + band_size - 1) / band_size ); + band_size = ( ras.count_ey + num_bands - 1 ) / num_bands; + } min = ras.min_ey; max_y = ras.max_ey; - for ( n = 0; n < num_bands; n++, min = max ) + for ( ; min < max_y; min = max ) { - max = min + ras.band_size; - if ( n == num_bands - 1 || max > max_y ) + max = min + band_size; + if ( max > max_y ) max = max_y; bands[0].min = min; bands[0].max = max; band = bands; - while ( band >= bands ) + do { - TPos bottom, top, middle; - int error; + TCoord bottom, top, middle; + int error; - { - PCell cells_max; - int yindex; - long cell_start, cell_end, cell_mod; + /* memory management */ + { + size_t ycount = (size_t)( band->max - band->min ); + size_t cell_start; - ras.ycells = (PCell*)ras.buffer; - ras.ycount = band->max - band->min; - - cell_start = sizeof ( PCell ) * ras.ycount; - cell_mod = cell_start % sizeof ( TCell ); - if ( cell_mod > 0 ) - cell_start += sizeof ( TCell ) - cell_mod; - cell_end = ras.buffer_size; - cell_end -= cell_end % sizeof ( TCell ); + cell_start = ( ycount * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / + sizeof ( TCell ); - cells_max = (PCell)( (char*)ras.buffer + cell_end ); - ras.cells = (PCell)( (char*)ras.buffer + cell_start ); - if ( ras.cells >= cells_max ) + if ( FT_MAX_GRAY_POOL - cell_start < 2 ) goto ReduceBands; - ras.max_cells = cells_max - ras.cells; - if ( ras.max_cells < 2 ) - goto ReduceBands; + ras.cells = buffer + cell_start; + ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - cell_start ); - for ( yindex = 0; yindex < ras.ycount; yindex++ ) - ras.ycells[yindex] = NULL; + ras.ycells = (PCell*)buffer; + while ( ycount ) + ras.ycells[--ycount] = NULL; } ras.num_cells = 0; @@ -1886,7 +1957,7 @@ typedef ptrdiff_t FT_PtrDist; if ( !error ) { - gray_sweep( RAS_VAR_ &ras.target ); + gray_sweep( RAS_VAR ); band--; continue; } @@ -1903,40 +1974,34 @@ typedef ptrdiff_t FT_PtrDist; /* be some problems. */ if ( middle == bottom ) { -#ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); -#endif return 1; } - if ( bottom-top >= ras.band_size ) - ras.band_shoot++; - band[1].min = bottom; band[1].max = middle; band[0].min = middle; band[0].max = top; band++; - } + } while ( band >= bands ); } - if ( ras.band_shoot > 8 && ras.band_size > 16 ) - ras.band_size = ras.band_size / 2; - return 0; } static int - gray_raster_render( gray_PRaster raster, + gray_raster_render( FT_Raster raster, const FT_Raster_Params* params ) { - const FT_Outline* outline = (const FT_Outline*)params->source; - const FT_Bitmap* target_map = params->target; - gray_PWorker worker; + const FT_Outline* outline = (const FT_Outline*)params->source; + const FT_Bitmap* target_map = params->target; + FT_BBox cbox, clip; + + gray_TWorker worker[1]; - if ( !raster || !raster->buffer || !raster->buffer_size ) + if ( !raster ) return FT_THROW( Invalid_Argument ); if ( !outline ) @@ -1953,8 +2018,6 @@ typedef ptrdiff_t FT_PtrDist; outline->contours[outline->n_contours - 1] + 1 ) return FT_THROW( Invalid_Outline ); - worker = raster->worker; - /* if direct mode is not set, we must have a target bitmap */ if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) { @@ -1973,32 +2036,51 @@ typedef ptrdiff_t FT_PtrDist; if ( !( params->flags & FT_RASTER_FLAG_AA ) ) return FT_THROW( Invalid_Mode ); + FT_Outline_Get_CBox( outline, &cbox ); + + /* reject too large outline coordinates */ + if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L || + cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L ) + return FT_THROW( Invalid_Outline ); + + /* truncate the bounding box to integer pixels */ + cbox.xMin = cbox.xMin >> 6; + cbox.yMin = cbox.yMin >> 6; + cbox.xMax = ( cbox.xMax + 63 ) >> 6; + cbox.yMax = ( cbox.yMax + 63 ) >> 6; + /* compute clipping box */ if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) { /* compute clip box from target pixmap */ - ras.clip_box.xMin = 0; - ras.clip_box.yMin = 0; - ras.clip_box.xMax = target_map->width; - ras.clip_box.yMax = target_map->rows; + clip.xMin = 0; + clip.yMin = 0; + clip.xMax = (FT_Pos)target_map->width; + clip.yMax = (FT_Pos)target_map->rows; } else if ( params->flags & FT_RASTER_FLAG_CLIP ) - ras.clip_box = params->clip_box; + clip = params->clip_box; else { - ras.clip_box.xMin = -32768L; - ras.clip_box.yMin = -32768L; - ras.clip_box.xMax = 32767L; - ras.clip_box.yMax = 32767L; + clip.xMin = -32768L; + clip.yMin = -32768L; + clip.xMax = 32767L; + clip.yMax = 32767L; } - gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size ); + /* clip to target bitmap, exit if nothing to do */ + ras.min_ex = FT_MAX( cbox.xMin, clip.xMin ); + ras.min_ey = FT_MAX( cbox.yMin, clip.yMin ); + ras.max_ex = FT_MIN( cbox.xMax, clip.xMax ); + ras.max_ey = FT_MIN( cbox.yMax, clip.yMax ); + + if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) + return 0; + + ras.count_ex = ras.max_ex - ras.min_ex; + ras.count_ey = ras.max_ey - ras.min_ey; ras.outline = *outline; - ras.num_cells = 0; - ras.invalid = 1; - ras.band_size = raster->band_size; - ras.num_gray_spans = 0; if ( params->flags & FT_RASTER_FLAG_DIRECT ) { @@ -2019,7 +2101,7 @@ typedef ptrdiff_t FT_PtrDist; /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ /**** a static object. *****/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ static int gray_raster_new( void* memory, @@ -2044,7 +2126,7 @@ typedef ptrdiff_t FT_PtrDist; FT_UNUSED( raster ); } -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ static int gray_raster_new( FT_Memory memory, @@ -2074,54 +2156,44 @@ typedef ptrdiff_t FT_PtrDist; FT_FREE( raster ); } -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ static void - gray_raster_reset( FT_Raster raster, - char* pool_base, - long pool_size ) + gray_raster_reset( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ) { - gray_PRaster rast = (gray_PRaster)raster; + FT_UNUSED( raster ); + FT_UNUSED( pool_base ); + FT_UNUSED( pool_size ); + } - if ( raster ) - { - if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 ) - { - gray_PWorker worker = (gray_PWorker)pool_base; - - - rast->worker = worker; - rast->buffer = pool_base + - ( ( sizeof ( gray_TWorker ) + - sizeof ( TCell ) - 1 ) & - ~( sizeof ( TCell ) - 1 ) ); - rast->buffer_size = (long)( ( pool_base + pool_size ) - - (char*)rast->buffer ) & - ~( sizeof ( TCell ) - 1 ); - rast->band_size = (int)( rast->buffer_size / - ( sizeof ( TCell ) * 8 ) ); - } - else - { - rast->buffer = NULL; - rast->buffer_size = 0; - rast->worker = NULL; - } - } + static int + gray_raster_set_mode( FT_Raster raster, + unsigned long mode, + void* args ) + { + FT_UNUSED( raster ); + FT_UNUSED( mode ); + FT_UNUSED( args ); + + + return 0; /* nothing to do */ } - FT_DEFINE_RASTER_FUNCS(ft_grays_raster, + FT_DEFINE_RASTER_FUNCS( + ft_grays_raster, + FT_GLYPH_FORMAT_OUTLINE, (FT_Raster_New_Func) gray_raster_new, (FT_Raster_Reset_Func) gray_raster_reset, - (FT_Raster_Set_Mode_Func)0, + (FT_Raster_Set_Mode_Func)gray_raster_set_mode, (FT_Raster_Render_Func) gray_raster_render, - (FT_Raster_Done_Func) gray_raster_done - ) + (FT_Raster_Done_Func) gray_raster_done ) /* END */ diff --git a/drivers/freetype/freetype/src/smooth/ftgrays.h b/drivers/freetype/src/smooth/ftgrays.h index f20f55f14b..21c2badcaf 100644 --- a/drivers/freetype/freetype/src/smooth/ftgrays.h +++ b/drivers/freetype/src/smooth/ftgrays.h @@ -4,7 +4,7 @@ /* */ /* FreeType smooth renderer declaration */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,15 +16,15 @@ /***************************************************************************/ -#ifndef __FTGRAYS_H__ -#define __FTGRAYS_H__ +#ifndef FTGRAYS_H_ +#define FTGRAYS_H_ #ifdef __cplusplus extern "C" { #endif -#ifdef _STANDALONE_ +#ifdef STANDALONE_ #include "ftimage.h" #else #include <ft2build.h> @@ -52,7 +52,7 @@ } #endif -#endif /* __FTGRAYS_H__ */ +#endif /* FTGRAYS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/smooth/ftsmerrs.h b/drivers/freetype/src/smooth/ftsmerrs.h index 413d2f1f70..a759b91c17 100644 --- a/drivers/freetype/freetype/src/smooth/ftsmerrs.h +++ b/drivers/freetype/src/smooth/ftsmerrs.h @@ -4,7 +4,7 @@ /* */ /* smooth renderer error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __FTSMERRS_H__ -#define __FTSMERRS_H__ +#ifndef FTSMERRS_H_ +#define FTSMERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX Smooth_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __FTSMERRS_H__ */ +#endif /* FTSMERRS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/smooth/ftsmooth.c b/drivers/freetype/src/smooth/ftsmooth.c index 89088cd091..79276765b1 100644 --- a/drivers/freetype/freetype/src/smooth/ftsmooth.c +++ b/drivers/freetype/src/smooth/ftsmooth.c @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (body). */ /* */ -/* Copyright 2000-2006, 2009-2013 by */ +/* Copyright 2000-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -103,25 +103,24 @@ FT_Render_Mode required_mode ) { FT_Error error; - FT_Outline* outline = NULL; + FT_Outline* outline = &slot->outline; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Memory memory = render->root.memory; FT_BBox cbox; + FT_Pos x_shift = 0; + FT_Pos y_shift = 0; + FT_Pos x_left, y_top; FT_Pos width, height, pitch; #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING FT_Pos height_org, width_org; #endif - FT_Bitmap* bitmap = &slot->bitmap; - FT_Memory memory = render->root.memory; FT_Int hmul = mode == FT_RENDER_MODE_LCD; FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; - FT_Pos x_shift = 0; - FT_Pos y_shift = 0; - FT_Pos x_left, y_top; FT_Raster_Params params; - FT_Bool have_translated_origin = FALSE; - FT_Bool have_outline_shifted = FALSE; - FT_Bool have_buffer = FALSE; + FT_Bool have_outline_shifted = FALSE; + FT_Bool have_buffer = FALSE; /* check glyph image format */ @@ -138,73 +137,45 @@ goto Exit; } - outline = &slot->outline; - - /* translate the outline to the new origin if needed */ if ( origin ) { - FT_Outline_Translate( outline, origin->x, origin->y ); - have_translated_origin = TRUE; + x_shift = origin->x; + y_shift = origin->y; } /* compute the control box, and grid fit it */ + /* taking into account the origin shift */ FT_Outline_Get_CBox( outline, &cbox ); - cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); - cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); - cbox.xMax = FT_PIX_CEIL( cbox.xMax ); - cbox.yMax = FT_PIX_CEIL( cbox.yMax ); + cbox.xMin = FT_PIX_FLOOR( cbox.xMin + x_shift ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin + y_shift ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax + x_shift ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax + y_shift ); - if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) - { - FT_ERROR(( "ft_smooth_render_generic: glyph too large:" - " xMin = %d, xMax = %d\n", - cbox.xMin >> 6, cbox.xMax >> 6 )); - error = FT_THROW( Raster_Overflow ); - goto Exit; - } - else - width = ( cbox.xMax - cbox.xMin ) >> 6; + x_shift -= cbox.xMin; + y_shift -= cbox.yMin; - if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) - { - FT_ERROR(( "ft_smooth_render_generic: glyph too large:" - " yMin = %d, yMax = %d\n", - cbox.yMin >> 6, cbox.yMax >> 6 )); - error = FT_THROW( Raster_Overflow ); - goto Exit; - } - else - height = ( cbox.yMax - cbox.yMin ) >> 6; + x_left = cbox.xMin >> 6; + y_top = cbox.yMax >> 6; + + width = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6; + height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6; #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING width_org = width; height_org = height; #endif - /* release old bitmap buffer */ - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - { - FT_FREE( bitmap->buffer ); - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - } - - /* allocate new one */ pitch = width; if ( hmul ) { - width = width * 3; - pitch = FT_PAD_CEIL( width, 4 ); + width *= 3; + pitch = FT_PAD_CEIL( width, 4 ); } if ( vmul ) height *= 3; - x_shift = (FT_Int) cbox.xMin; - y_shift = (FT_Int) cbox.yMin; - x_left = (FT_Int)( cbox.xMin >> 6 ); - y_top = (FT_Int)( cbox.yMax >> 6 ); - #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING if ( slot->library->lcd_filter_func ) @@ -214,23 +185,32 @@ if ( hmul ) { - x_shift -= 64 * ( extra >> 1 ); + x_shift += 64 * ( extra >> 1 ); + x_left -= extra >> 1; width += 3 * extra; pitch = FT_PAD_CEIL( width, 4 ); - x_left -= extra >> 1; } if ( vmul ) { - y_shift -= 64 * ( extra >> 1 ); - height += 3 * extra; + y_shift += 64 * ( extra >> 1 ); y_top += extra >> 1; + height += 3 * extra; } } #endif -#if FT_UINT_MAX > 0xFFFFU + /* + * XXX: on 16bit system, we return an error for huge bitmap + * to prevent an overflow. + */ + if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX || + x_left < FT_INT_MIN || y_top < FT_INT_MIN ) + { + error = FT_THROW( Invalid_Pixel_Size ); + goto Exit; + } /* Required check is (pitch * height < FT_ULONG_MAX), */ /* but we care realistic cases only. Always pitch <= width. */ @@ -242,25 +222,38 @@ goto Exit; } -#endif - - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; - bitmap->num_grays = 256; - bitmap->width = width; - bitmap->rows = height; - bitmap->pitch = pitch; - - /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -x_shift, -y_shift ); - have_outline_shifted = TRUE; + /* release old bitmap buffer */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } - if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) + /* allocate new one */ + if ( FT_ALLOC( bitmap->buffer, (FT_ULong)( pitch * height ) ) ) goto Exit; else have_buffer = TRUE; slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = (FT_Int)x_left; + slot->bitmap_top = (FT_Int)y_top; + + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->num_grays = 256; + bitmap->width = (unsigned int)width; + bitmap->rows = (unsigned int)height; + bitmap->pitch = pitch; + + /* translate outline to render it into the bitmap */ + if ( x_shift || y_shift ) + { + FT_Outline_Translate( outline, x_shift, y_shift ); + have_outline_shifted = TRUE; + } + /* set up parameters */ params.target = bitmap; params.source = outline; @@ -366,20 +359,6 @@ #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - /* - * XXX: on 16bit system, we return an error for huge bitmap - * to prevent an overflow. - */ - if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) - { - error = FT_THROW( Invalid_Pixel_Size ); - goto Exit; - } - - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = (FT_Int)x_left; - slot->bitmap_top = (FT_Int)y_top; - /* everything is fine; don't deallocate buffer */ have_buffer = FALSE; @@ -387,9 +366,7 @@ Exit: if ( have_outline_shifted ) - FT_Outline_Translate( outline, x_shift, y_shift ); - if ( have_translated_origin ) - FT_Outline_Translate( outline, -origin->x, -origin->y ); + FT_Outline_Translate( outline, -x_shift, -y_shift ); if ( have_buffer ) { FT_FREE( bitmap->buffer ); diff --git a/drivers/freetype/freetype/src/smooth/ftsmooth.h b/drivers/freetype/src/smooth/ftsmooth.h index 3708790df1..c7c28c244c 100644 --- a/drivers/freetype/freetype/src/smooth/ftsmooth.h +++ b/drivers/freetype/src/smooth/ftsmooth.h @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSMOOTH_H__ -#define __FTSMOOTH_H__ +#ifndef FTSMOOTH_H_ +#define FTSMOOTH_H_ #include <ft2build.h> @@ -43,7 +43,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSMOOTH_H__ */ +#endif /* FTSMOOTH_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/smooth/ftspic.c b/drivers/freetype/src/smooth/ftspic.c index 67a2b8310c..6c2b2329b3 100644 --- a/drivers/freetype/freetype/src/smooth/ftspic.c +++ b/drivers/freetype/src/smooth/ftspic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for smooth module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/smooth/ftspic.h b/drivers/freetype/src/smooth/ftspic.h index 334b51c3f1..fe76152770 100644 --- a/drivers/freetype/freetype/src/smooth/ftspic.h +++ b/drivers/freetype/src/smooth/ftspic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for smooth module. */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,14 +16,15 @@ /***************************************************************************/ -#ifndef __FTSPIC_H__ -#define __FTSPIC_H__ +#ifndef FTSPIC_H_ +#define FTSPIC_H_ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H + +FT_BEGIN_HEADER + #ifndef FT_CONFIG_OPTION_PIC #define FT_GRAYS_RASTER_GET ft_grays_raster @@ -68,7 +69,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSPIC_H__ */ +#endif /* FTSPIC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/smooth/module.mk b/drivers/freetype/src/smooth/module.mk index 47f6c04076..f3cb044039 100644 --- a/drivers/freetype/freetype/src/smooth/module.mk +++ b/drivers/freetype/src/smooth/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/smooth/rules.mk b/drivers/freetype/src/smooth/rules.mk index 88d0aa53ac..5e94f73519 100644 --- a/drivers/freetype/freetype/src/smooth/rules.mk +++ b/drivers/freetype/src/smooth/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003, 2011 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,9 +17,13 @@ # SMOOTH_DIR := $(SRC_DIR)/smooth + # compilation flags for the driver # -SMOOTH_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SMOOTH_DIR)) +SMOOTH_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(SMOOTH_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # smooth driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/smooth/smooth.c b/drivers/freetype/src/smooth/smooth.c index a8ac51f9f8..97ca3e5995 100644 --- a/drivers/freetype/freetype/src/smooth/smooth.c +++ b/drivers/freetype/src/smooth/smooth.c @@ -4,7 +4,7 @@ /* */ /* FreeType anti-aliasing rasterer module component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/truetype/Jamfile b/drivers/freetype/src/truetype/Jamfile index a8cccfe137..ecbb2dbdd2 100644 --- a/drivers/freetype/freetype/src/truetype/Jamfile +++ b/drivers/freetype/src/truetype/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/truetype Jamfile # -# Copyright 2001, 2004 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,15 @@ SubDir FT2_TOP $(FT2_SRC_DIR) truetype ; if $(FT2_MULTI) { - _sources = ttdriver ttobjs ttpload ttgload ttinterp ttgxvar ttpic ; + _sources = ttdriver + ttgload + ttgxvar + ttinterp + ttobjs + ttpic + ttpload + ttsubpix + ; } else { diff --git a/drivers/freetype/freetype/src/truetype/module.mk b/drivers/freetype/src/truetype/module.mk index baee81a773..80c9832b2c 100644 --- a/drivers/freetype/freetype/src/truetype/module.mk +++ b/drivers/freetype/src/truetype/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/truetype/rules.mk b/drivers/freetype/src/truetype/rules.mk index d4b69f578b..3bf7cf770d 100644 --- a/drivers/freetype/freetype/src/truetype/rules.mk +++ b/drivers/freetype/src/truetype/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2001, 2003-2004, 2011-2012 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ TT_DIR := $(SRC_DIR)/truetype # compilation flags for the driver # -TT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(TT_DIR)) +TT_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(TT_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # TrueType driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/truetype/truetype.c b/drivers/freetype/src/truetype/truetype.c index 576912b219..23e2ea00a7 100644 --- a/drivers/freetype/freetype/src/truetype/truetype.c +++ b/drivers/freetype/src/truetype/truetype.c @@ -4,7 +4,7 @@ /* */ /* FreeType TrueType driver component (body only). */ /* */ -/* Copyright 1996-2001, 2004, 2006, 2012 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/truetype/ttdriver.c b/drivers/freetype/src/truetype/ttdriver.c index fb25706ab8..c9d4081efe 100644 --- a/drivers/freetype/freetype/src/truetype/ttdriver.c +++ b/drivers/freetype/src/truetype/ttdriver.c @@ -4,7 +4,7 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include FT_MULTIPLE_MASTERS_H @@ -72,12 +72,17 @@ FT_UInt* interpreter_version = (FT_UInt*)value; -#ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( *interpreter_version != TT_INTERPRETER_VERSION_35 ) - error = FT_ERR( Unimplemented_Feature ); - else + if ( *interpreter_version == TT_INTERPRETER_VERSION_35 +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + || *interpreter_version == TT_INTERPRETER_VERSION_38 #endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + || *interpreter_version == TT_INTERPRETER_VERSION_40 +#endif + ) driver->interpreter_version = *interpreter_version; + else + error = FT_ERR( Unimplemented_Feature ); return error; } @@ -117,8 +122,8 @@ FT_DEFINE_SERVICE_PROPERTIESREC( tt_service_properties, - (FT_Properties_SetFunc)tt_property_set, - (FT_Properties_GetFunc)tt_property_get ) + (FT_Properties_SetFunc)tt_property_set, /* set_property */ + (FT_Properties_GetFunc)tt_property_get ) /* get_property */ /*************************************************************************/ @@ -134,11 +139,6 @@ /*************************************************************************/ -#undef PAIR_TAG -#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ - (FT_ULong)right ) - - /*************************************************************************/ /* */ /* <Function> */ @@ -191,9 +191,6 @@ } -#undef PAIR_TAG - - static FT_Error tt_get_advances( FT_Face ttface, FT_UInt start, @@ -202,7 +199,7 @@ FT_Fixed *advances ) { FT_UInt nn; - TT_Face face = (TT_Face) ttface; + TT_Face face = (TT_Face) ttface; /* XXX: TODO: check for sbits */ @@ -215,7 +212,8 @@ FT_UShort ah; - TT_Get_VMetrics( face, start + nn, &tsb, &ah ); + /* since we don't need `tsb', we use zero for `yMax' parameter */ + TT_Get_VMetrics( face, start + nn, 0, &tsb, &ah ); advances[nn] = ah; } } @@ -235,6 +233,7 @@ return FT_Err_Ok; } + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -266,7 +265,7 @@ /* use the scaled metrics, even when tt_size_reset fails */ FT_Select_Metrics( size->face, strike_index ); - tt_size_reset( ttsize ); + tt_size_reset( ttsize ); /* ignore return value */ } else { @@ -369,7 +368,7 @@ return FT_THROW( Invalid_Size_Handle ); if ( !face ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Face_Handle ); #ifdef FT_CONFIG_OPTION_INCREMENTAL if ( glyph_index >= (FT_UInt)face->num_glyphs && @@ -424,22 +423,19 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, - (FT_Get_MM_Func) NULL, - (FT_Set_MM_Design_Func) NULL, - (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, - (FT_Get_MM_Var_Func) TT_Get_MM_Var, - (FT_Set_Var_Design_Func)TT_Set_Var_Design ) + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)TT_Set_Var_Design ) /* set_var_design */ #endif + static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = { #ifdef TT_USE_BYTECODE_INTERPRETER -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_TRUETYPE_ENGINE_TYPE_UNPATENTED -#else FT_TRUETYPE_ENGINE_TYPE_PATENTED -#endif #else /* !TT_USE_BYTECODE_INTERPRETER */ @@ -448,14 +444,16 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ }; + FT_DEFINE_SERVICE_TTGLYFREC( tt_service_truetype_glyf, - (TT_Glyf_GetLocationFunc)tt_face_get_location ) + (TT_Glyf_GetLocationFunc)tt_face_get_location ) /* get_location */ + #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_DEFINE_SERVICEDESCREC5( tt_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, @@ -463,7 +461,7 @@ #else FT_DEFINE_SERVICEDESCREC4( tt_services, - FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) @@ -480,7 +478,7 @@ SFNT_Service sfnt; - /* TT_SERVICES_GET derefers `library' in PIC mode */ + /* TT_SERVICES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC if ( !driver ) return NULL; @@ -541,31 +539,31 @@ 0x10000L, /* driver version == 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or above */ - (void*)0, /* driver specific interface */ + 0, /* module-specific interface */ - tt_driver_init, - tt_driver_done, - tt_get_interface, + tt_driver_init, /* FT_Module_Constructor module_init */ + tt_driver_done, /* FT_Module_Destructor module_done */ + tt_get_interface, /* FT_Module_Requester get_interface */ sizeof ( TT_FaceRec ), sizeof ( TT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - tt_face_init, - tt_face_done, - tt_size_init, - tt_size_done, - tt_slot_init, - 0, /* FT_Slot_DoneFunc */ + tt_face_init, /* FT_Face_InitFunc init_face */ + tt_face_done, /* FT_Face_DoneFunc done_face */ + tt_size_init, /* FT_Size_InitFunc init_size */ + tt_size_done, /* FT_Size_DoneFunc done_size */ + tt_slot_init, /* FT_Slot_InitFunc init_slot */ + 0, /* FT_Slot_DoneFunc done_slot */ - tt_glyph_load, + tt_glyph_load, /* FT_Slot_LoadFunc load_glyph */ - tt_get_kerning, - 0, /* FT_Face_AttachFunc */ - tt_get_advances, + tt_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + tt_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ - tt_size_request, - TT_SIZE_SELECT + tt_size_request, /* FT_Size_RequestFunc request_size */ + TT_SIZE_SELECT /* FT_Size_SelectFunc select_size */ ) diff --git a/drivers/freetype/freetype/src/truetype/ttdriver.h b/drivers/freetype/src/truetype/ttdriver.h index aae00f2617..74392bbd02 100644 --- a/drivers/freetype/freetype/src/truetype/ttdriver.h +++ b/drivers/freetype/src/truetype/ttdriver.h @@ -4,7 +4,7 @@ /* */ /* High-level TrueType driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTDRIVER_H__ -#define __TTDRIVER_H__ +#ifndef TTDRIVER_H_ +#define TTDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTDRIVER_H__ */ +#endif /* TTDRIVER_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/truetype/tterrors.h b/drivers/freetype/src/truetype/tterrors.h index 78d138fab2..895989f5fd 100644 --- a/drivers/freetype/freetype/src/truetype/tterrors.h +++ b/drivers/freetype/src/truetype/tterrors.h @@ -4,7 +4,7 @@ /* */ /* TrueType error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __TTERRORS_H__ -#define __TTERRORS_H__ +#ifndef TTERRORS_H_ +#define TTERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX TT_Err_ @@ -36,6 +36,7 @@ #include FT_ERRORS_H -#endif /* __TTERRORS_H__ */ +#endif /* TTERRORS_H_ */ + /* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttgload.c b/drivers/freetype/src/truetype/ttgload.c index f640a6c78e..8be9b6ae65 100644 --- a/drivers/freetype/freetype/src/truetype/ttgload.c +++ b/drivers/freetype/src/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2013 */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,7 @@ #include FT_TRUETYPE_TAGS_H #include FT_OUTLINE_H #include FT_TRUETYPE_DRIVER_H +#include FT_LIST_H #include "ttgload.h" #include "ttpload.h" @@ -85,92 +86,94 @@ /*************************************************************************/ /* */ /* Return the vertical metrics in font units for a given glyph. */ - /* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */ - /* table, typoAscender/Descender from the `OS/2' table would be used */ - /* instead, and if there were no `OS/2' table, use ascender/descender */ - /* from the `hhea' table. But that is not what Microsoft's rasterizer */ - /* apparently does: It uses the ppem value as the advance height, and */ - /* sets the top side bearing to be zero. */ + /* See macro `TT_LOADER_SET_PP' below for explanations. */ /* */ FT_LOCAL_DEF( void ) TT_Get_VMetrics( TT_Face face, FT_UInt idx, + FT_Pos yMax, FT_Short* tsb, FT_UShort* ah ) { if ( face->vertical_info ) ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah ); -#if 1 /* Empirically determined, at variance with what MS said */ - - else - { - *tsb = 0; - *ah = face->root.units_per_EM; - } - -#else /* This is what MS said to do. It isn't what they do, however. */ - else if ( face->os2.version != 0xFFFFU ) { - *tsb = face->os2.sTypoAscender; - *ah = face->os2.sTypoAscender - face->os2.sTypoDescender; + *tsb = (FT_Short)( face->os2.sTypoAscender - yMax ); + *ah = (FT_UShort)FT_ABS( face->os2.sTypoAscender - + face->os2.sTypoDescender ); } + else { - *tsb = face->horizontal.Ascender; - *ah = face->horizontal.Ascender - face->horizontal.Descender; + *tsb = (FT_Short)( face->horizontal.Ascender - yMax ); + *ah = (FT_UShort)FT_ABS( face->horizontal.Ascender - + face->horizontal.Descender ); } -#endif - FT_TRACE5(( " advance height (font units): %d\n", *ah )); FT_TRACE5(( " top side bearing (font units): %d\n", *tsb )); } - static void + static FT_Error tt_get_metrics( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Face face = loader->face; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif + FT_Error error; + FT_Stream stream = loader->stream; + FT_Short left_bearing = 0, top_bearing = 0; FT_UShort advance_width = 0, advance_height = 0; + /* we must preserve the stream position */ + /* (which gets altered by the metrics functions) */ + FT_ULong pos = FT_STREAM_POS(); + TT_Get_HMetrics( face, glyph_index, &left_bearing, &advance_width ); TT_Get_VMetrics( face, glyph_index, + loader->bbox.yMax, &top_bearing, &advance_height ); + if ( FT_STREAM_SEEK( pos ) ) + return error; + loader->left_bearing = left_bearing; loader->advance = advance_width; loader->top_bearing = top_bearing; loader->vadvance = advance_height; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && + loader->exec ) { - if ( loader->exec ) - loader->exec->sph_tweak_flags = 0; + loader->exec->sph_tweak_flags = 0; - /* this may not be the right place for this, but it works */ - if ( loader->exec && loader->exec->ignore_x_mode ) - sph_set_tweaks( loader, glyph_index ); + /* This may not be the right place for this, but it works... */ + /* Note that we have to unconditionally load the tweaks since */ + /* it is possible that glyphs individually switch ClearType's */ + /* backwards compatibility mode on and off. */ + sph_set_tweaks( loader, glyph_index ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( !loader->linear_def ) { loader->linear_def = 1; loader->linear = advance_width; } + + return FT_Err_Ok; } @@ -180,7 +183,7 @@ tt_get_metrics_incr_overrides( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; FT_Short left_bearing = 0, top_bearing = 0; FT_UShort advance_width = 0, advance_height = 0; @@ -248,29 +251,6 @@ /*************************************************************************/ /* */ - /* Translates an array of coordinates. */ - /* */ - static void - translate_array( FT_UInt n, - FT_Vector* coords, - FT_Pos delta_x, - FT_Pos delta_y ) - { - FT_UInt k; - - - if ( delta_x ) - for ( k = 0; k < n; k++ ) - coords[k].x += delta_x; - - if ( delta_y ) - for ( k = 0; k < n; k++ ) - coords[k].y += delta_y; - } - - - /*************************************************************************/ - /* */ /* The following functions are used by default with TrueType fonts. */ /* However, they can be replaced by alternatives if we need to support */ /* TrueType-compressed formats (like MicroType) in the future. */ @@ -350,9 +330,9 @@ FT_GlyphLoader gloader = load->gloader; FT_Int n_contours = load->n_contours; FT_Outline* outline; - TT_Face face = (TT_Face)load->face; FT_UShort n_ins; FT_Int n_points; + FT_ULong tmp; FT_Byte *flag, *flag_limit; FT_Byte c, count; @@ -409,7 +389,7 @@ /* reading the bytecode instructions */ load->glyph->control_len = 0; - load->glyph->control_data = 0; + load->glyph->control_data = NULL; if ( p + 2 > limit ) goto Invalid_Outline; @@ -418,14 +398,7 @@ FT_TRACE5(( " Instructions size: %u\n", n_ins )); - if ( n_ins > face->max_profile.maxSizeOfInstructions ) - { - FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n", - n_ins )); - error = FT_THROW( Too_Many_Hints ); - goto Fail; - } - + /* check it */ if ( ( limit - p ) < n_ins ) { FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); @@ -437,10 +410,25 @@ if ( IS_HINTED( load->load_flags ) ) { + /* we don't trust `maxSizeOfInstructions' in the `maxp' table */ + /* and thus update the bytecode array size by ourselves */ + + tmp = load->exec->glyphSize; + error = Update_Max( load->exec->memory, + &tmp, + sizeof ( FT_Byte ), + (void*)&load->exec->glyphIns, + n_ins ); + + load->exec->glyphSize = (FT_UShort)tmp; + if ( error ) + return error; + load->glyph->control_len = n_ins; load->glyph->control_data = load->exec->glyphIns; - FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); + if ( n_ins ) + FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); } #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -550,8 +538,8 @@ *flag = (FT_Byte)( f & FT_CURVE_TAG_ON ); } - outline->n_points = (FT_UShort)n_points; - outline->n_contours = (FT_Short) n_contours; + outline->n_points = (FT_Short)n_points; + outline->n_contours = (FT_Short)n_contours; load->cursor = p; @@ -614,15 +602,31 @@ goto Invalid_Composite; /* read arguments */ - if ( subglyph->flags & ARGS_ARE_WORDS ) + if ( subglyph->flags & ARGS_ARE_XY_VALUES ) { - subglyph->arg1 = FT_NEXT_SHORT( p ); - subglyph->arg2 = FT_NEXT_SHORT( p ); + if ( subglyph->flags & ARGS_ARE_WORDS ) + { + subglyph->arg1 = FT_NEXT_SHORT( p ); + subglyph->arg2 = FT_NEXT_SHORT( p ); + } + else + { + subglyph->arg1 = FT_NEXT_CHAR( p ); + subglyph->arg2 = FT_NEXT_CHAR( p ); + } } else { - subglyph->arg1 = FT_NEXT_CHAR( p ); - subglyph->arg2 = FT_NEXT_CHAR( p ); + if ( subglyph->flags & ARGS_ARE_WORDS ) + { + subglyph->arg1 = (FT_Int)FT_NEXT_USHORT( p ); + subglyph->arg2 = (FT_Int)FT_NEXT_USHORT( p ); + } + else + { + subglyph->arg1 = (FT_Int)FT_NEXT_BYTE( p ); + subglyph->arg2 = (FT_Int)FT_NEXT_BYTE( p ); + } } /* read transform */ @@ -631,20 +635,20 @@ if ( subglyph->flags & WE_HAVE_A_SCALE ) { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; yy = xx; } else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; } else if ( subglyph->flags & WE_HAVE_A_2X2 ) { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + yx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + xy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; } subglyph->transform.xx = xx; @@ -657,6 +661,7 @@ } while ( subglyph->flags & MORE_COMPONENTS ); gloader->current.num_subglyphs = num_subglyphs; + FT_TRACE5(( " %d components\n", num_subglyphs )); #ifdef TT_USE_BYTECODE_INTERPRETER @@ -702,9 +707,10 @@ FT_UInt start_point, FT_UInt start_contour ) { - zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); - zone->n_contours = (FT_Short) ( load->outline.n_contours - - start_contour ); + zone->n_points = (FT_UShort)load->outline.n_points - + (FT_UShort)start_point; + zone->n_contours = load->outline.n_contours - + (FT_Short)start_contour; zone->org = load->extra_points + start_point; zone->cur = load->outline.points + start_point; zone->orus = load->extra_points2 + start_point; @@ -727,16 +733,16 @@ TT_Hint_Glyph( TT_Loader loader, FT_Bool is_composite ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Face face = (TT_Face)loader->face; +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif TT_GlyphZone zone = &loader->zone; - FT_Pos origin; #ifdef TT_USE_BYTECODE_INTERPRETER - FT_UInt n_ins; + FT_Long n_ins; #else FT_UNUSED( is_composite ); #endif @@ -745,25 +751,18 @@ #ifdef TT_USE_BYTECODE_INTERPRETER if ( loader->glyph->control_len > 0xFFFFL ) { - FT_TRACE1(( "TT_Hint_Glyph: too long instructions " )); - FT_TRACE1(( "(0x%lx byte) is truncated\n", + FT_TRACE1(( "TT_Hint_Glyph: too long instructions" )); + FT_TRACE1(( " (0x%lx byte) is truncated\n", loader->glyph->control_len )); } - n_ins = (FT_UInt)( loader->glyph->control_len ); -#endif + n_ins = loader->glyph->control_len; - origin = zone->cur[zone->n_points - 4].x; - origin = FT_PIX_ROUND( origin ) - origin; - if ( origin ) - translate_array( zone->n_points, zone->cur, origin, 0 ); - -#ifdef TT_USE_BYTECODE_INTERPRETER /* save original point position in org */ if ( n_ins > 0 ) FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); /* Reset graphics state. */ - loader->exec->GS = ((TT_Size)loader->size)->GS; + loader->exec->GS = loader->size->GS; /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ /* completely refer to the (already) hinted subglyphs. */ @@ -776,16 +775,18 @@ } else { - loader->exec->metrics.x_scale = - ((TT_Size)loader->size)->metrics.x_scale; - loader->exec->metrics.y_scale = - ((TT_Size)loader->size)->metrics.y_scale; + loader->exec->metrics.x_scale = loader->size->metrics.x_scale; + loader->exec->metrics.y_scale = loader->size->metrics.y_scale; } #endif - /* round pp2 and pp4 */ + /* round phantom points */ + zone->cur[zone->n_points - 4].x = + FT_PIX_ROUND( zone->cur[zone->n_points - 4].x ); zone->cur[zone->n_points - 3].x = FT_PIX_ROUND( zone->cur[zone->n_points - 3].x ); + zone->cur[zone->n_points - 2].y = + FT_PIX_ROUND( zone->cur[zone->n_points - 2].y ); zone->cur[zone->n_points - 1].y = FT_PIX_ROUND( zone->cur[zone->n_points - 1].y ); @@ -793,25 +794,19 @@ if ( n_ins > 0 ) { - FT_Bool debug; FT_Error error; FT_GlyphLoader gloader = loader->gloader; FT_Outline current_outline = gloader->current.outline; - error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph, - loader->exec->glyphIns, n_ins ); - if ( error ) - return error; + TT_Set_CodeRange( loader->exec, tt_coderange_glyph, + loader->exec->glyphIns, n_ins ); loader->exec->is_composite = is_composite; loader->exec->pts = *zone; - debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) && - ((TT_Size)loader->size)->debug ); - - error = TT_Run_Context( loader->exec, debug ); + error = TT_Run_Context( loader->exec ); if ( error && loader->exec->pedantic_hinting ) return error; @@ -822,16 +817,23 @@ #endif - /* save glyph phantom points */ - if ( !loader->preserve_pps ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Save possibly modified glyph phantom points unless in v40 backwards */ + /* compatibility mode, where no movement on the x axis means no reason */ + /* to change bearings or advance widths. */ + if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && + !loader->exec->backwards_compatibility ) ) { +#endif loader->pp1 = zone->cur[zone->n_points - 4]; loader->pp2 = zone->cur[zone->n_points - 3]; loader->pp3 = zone->cur[zone->n_points - 2]; loader->pp4 = zone->cur[zone->n_points - 1]; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL } +#endif -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) @@ -840,7 +842,7 @@ else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ return FT_Err_Ok; } @@ -884,28 +886,15 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( ((TT_Face)loader->face)->doblend ) + if ( loader->face->doblend ) { /* Deltas apply to the unscaled data. */ - FT_Vector* deltas; - FT_Memory memory = loader->face->memory; - FT_Int i; - - - error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), - loader->glyph_index, - &deltas, - n_points ); + error = TT_Vary_Apply_Glyph_Deltas( loader->face, + loader->glyph_index, + outline, + (FT_UInt)n_points ); if ( error ) return error; - - for ( i = 0; i < n_points; ++i ) - { - outline->points[i].x += deltas[i].x; - outline->points[i].y += deltas[i].y; - } - - FT_FREE( deltas ); } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -919,14 +908,14 @@ } { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Face face = (TT_Face)loader->face; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); FT_String* family = face->root.family_name; - FT_Int ppem = loader->size->metrics.x_ppem; + FT_UInt ppem = loader->size->metrics.x_ppem; FT_String* style = face->root.style_name; - FT_Int x_scale_factor = 1000; + FT_UInt x_scale_factor = 1000; #endif FT_Vector* vec = outline->points; @@ -938,7 +927,7 @@ FT_Bool do_scale = FALSE; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -953,9 +942,9 @@ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || x_scale_factor != 1000 ) { - x_scale = FT_MulDiv( ((TT_Size)loader->size)->metrics.x_scale, - x_scale_factor, 1000 ); - y_scale = ((TT_Size)loader->size)->metrics.y_scale; + x_scale = FT_MulDiv( loader->size->metrics.x_scale, + (FT_Long)x_scale_factor, 1000 ); + y_scale = loader->size->metrics.y_scale; /* compensate for any scaling by de/emboldening; */ /* the amount was determined via experimentation */ @@ -969,14 +958,14 @@ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { /* scale the glyph */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - x_scale = ((TT_Size)loader->size)->metrics.x_scale; - y_scale = ((TT_Size)loader->size)->metrics.y_scale; + x_scale = loader->size->metrics.x_scale; + y_scale = loader->size->metrics.y_scale; do_scale = TRUE; } @@ -1023,32 +1012,31 @@ FT_UInt start_point, FT_UInt num_base_points ) { - FT_GlyphLoader gloader = loader->gloader; - FT_Vector* base_vec = gloader->base.outline.points; - FT_UInt num_points = gloader->base.outline.n_points; + FT_GlyphLoader gloader = loader->gloader; + FT_Outline current; FT_Bool have_scale; FT_Pos x, y; + current.points = gloader->base.outline.points + + num_base_points; + current.n_points = gloader->base.outline.n_points - + (short)num_base_points; + have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE | WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2 ) ); /* perform the transform required for this subglyph */ if ( have_scale ) - { - FT_UInt i; - - - for ( i = num_base_points; i < num_points; i++ ) - FT_Vector_Transform( base_vec + i, &subglyph->transform ); - } + FT_Outline_Transform( ¤t, &subglyph->transform ); /* get offset */ if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) { - FT_UInt k = subglyph->arg1; - FT_UInt l = subglyph->arg2; + FT_UInt num_points = (FT_UInt)gloader->base.outline.n_points; + FT_UInt k = (FT_UInt)subglyph->arg1; + FT_UInt l = (FT_UInt)subglyph->arg2; FT_Vector* p1; FT_Vector* p2; @@ -1077,9 +1065,9 @@ if ( !x && !y ) return FT_Err_Ok; - /* Use a default value dependent on */ - /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */ - /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */ + /* Use a default value dependent on */ + /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old */ + /* TT fonts which don't set the xxx_COMPONENT_OFFSET bit. */ if ( have_scale && #ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED @@ -1091,17 +1079,17 @@ #if 0 - /*************************************************************************/ - /* */ - /* This algorithm is what Apple documents. But it doesn't work. */ - /* */ + /*******************************************************************/ + /* */ + /* This algorithm is what Apple documents. But it doesn't work. */ + /* */ int a = subglyph->transform.xx > 0 ? subglyph->transform.xx : -subglyph->transform.xx; int b = subglyph->transform.yx > 0 ? subglyph->transform.yx : -subglyph->transform.yx; int c = subglyph->transform.xy > 0 ? subglyph->transform.xy : -subglyph->transform.xy; - int d = subglyph->transform.yy > 0 ? subglyph->transform.yy + int d = subglyph->transform.yy > 0 ? subglyph->transform.yy : -subglyph->transform.yy; int m = a > b ? a : b; int n = c > d ? c : d; @@ -1114,12 +1102,12 @@ x = FT_MulFix( x, m ); y = FT_MulFix( y, n ); -#else /* 0 */ +#else /* 1 */ - /*************************************************************************/ - /* */ - /* This algorithm is a guess and works much better than the above. */ - /* */ + /*******************************************************************/ + /* */ + /* This algorithm is a guess and works much better than the above. */ + /* */ FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx, subglyph->transform.xy ); FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy, @@ -1129,14 +1117,14 @@ x = FT_MulFix( x, mac_xscale ); y = FT_MulFix( y, mac_yscale ); -#endif /* 0 */ +#endif /* 1 */ } if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) { - FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; - FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; + FT_Fixed x_scale = loader->size->metrics.x_scale; + FT_Fixed y_scale = loader->size->metrics.y_scale; x = FT_MulFix( x, x_scale ); @@ -1151,9 +1139,7 @@ } if ( x || y ) - translate_array( num_points - num_base_points, - base_vec + num_base_points, - x, y ); + FT_Outline_Translate( ¤t, x, y ); return FT_Err_Ok; } @@ -1215,24 +1201,26 @@ FT_TRACE5(( " Instructions size = %d\n", n_ins )); /* check it */ - max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions; + max_ins = loader->face->max_profile.maxSizeOfInstructions; if ( n_ins > max_ins ) { - /* acroread ignores this field, so we only do a rough safety check */ + /* don't trust `maxSizeOfInstructions'; */ + /* only do a rough safety check */ if ( (FT_Int)n_ins > loader->byte_len ) { - FT_TRACE1(( "TT_Process_Composite_Glyph: " - "too many instructions (%d) for glyph with length %d\n", + FT_TRACE1(( "TT_Process_Composite_Glyph:" + " too many instructions (%d) for glyph with length %d\n", n_ins, loader->byte_len )); return FT_THROW( Too_Many_Hints ); } - tmp = loader->exec->glyphSize; + tmp = loader->exec->glyphSize; error = Update_Max( loader->exec->memory, &tmp, sizeof ( FT_Byte ), (void*)&loader->exec->glyphIns, n_ins ); + loader->exec->glyphSize = (FT_UShort)tmp; if ( error ) return error; @@ -1254,7 +1242,7 @@ /* Some points are likely touched during execution of */ /* instructions on components. So let's untouch them. */ - for ( i = start_point; i < loader->zone.n_points; i++ ) + for ( i = 0; i < loader->zone.n_points; i++ ) loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH; loader->zone.n_points += 4; @@ -1263,20 +1251,155 @@ } - /* Calculate the four phantom points. */ - /* The first two stand for horizontal origin and advance. */ - /* The last two stand for vertical origin and advance. */ -#define TT_LOADER_SET_PP( loader ) \ - do { \ - (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \ - (loader)->pp1.y = 0; \ - (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \ - (loader)->pp2.y = 0; \ - (loader)->pp3.x = 0; \ - (loader)->pp3.y = (loader)->top_bearing + (loader)->bbox.yMax; \ - (loader)->pp4.x = 0; \ - (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \ - } while ( 0 ) + /* + * Calculate the phantom points + * + * Defining the right side bearing (rsb) as + * + * rsb = aw - (lsb + xmax - xmin) + * + * (with `aw' the advance width, `lsb' the left side bearing, and `xmin' + * and `xmax' the glyph's minimum and maximum x value), the OpenType + * specification defines the initial position of horizontal phantom points + * as + * + * pp1 = (round(xmin - lsb), 0) , + * pp2 = (round(pp1 + aw), 0) . + * + * Note that the rounding to the grid (in the device space) is not + * documented currently in the specification. + * + * However, the specification lacks the precise definition of vertical + * phantom points. Greg Hitchcock provided the following explanation. + * + * - a `vmtx' table is present + * + * For any glyph, the minimum and maximum y values (`ymin' and `ymax') + * are given in the `glyf' table, the top side bearing (tsb) and advance + * height (ah) are given in the `vmtx' table. The bottom side bearing + * (bsb) is then calculated as + * + * bsb = ah - (tsb + ymax - ymin) , + * + * and the initial position of vertical phantom points is + * + * pp3 = (x, round(ymax + tsb)) , + * pp4 = (x, round(pp3 - ah)) . + * + * See below for value `x'. + * + * - no `vmtx' table in the font + * + * If there is an `OS/2' table, we set + * + * DefaultAscender = sTypoAscender , + * DefaultDescender = sTypoDescender , + * + * otherwise we use data from the `hhea' table: + * + * DefaultAscender = Ascender , + * DefaultDescender = Descender . + * + * With these two variables we can now set + * + * ah = DefaultAscender - sDefaultDescender , + * tsb = DefaultAscender - yMax , + * + * and proceed as if a `vmtx' table was present. + * + * Usually we have + * + * x = aw / 2 , (1) + * + * but there is one compatibility case where it can be set to + * + * x = -DefaultDescender - + * ((DefaultAscender - DefaultDescender - aw) / 2) . (2) + * + * and another one with + * + * x = 0 . (3) + * + * In Windows, the history of those values is quite complicated, + * depending on the hinting engine (that is, the graphics framework). + * + * framework from to formula + * ---------------------------------------------------------- + * GDI Windows 98 current (1) + * (Windows 2000 for NT) + * GDI+ Windows XP Windows 7 (2) + * GDI+ Windows 8 current (3) + * DWrite Windows 7 current (3) + * + * For simplicity, FreeType uses (1) for grayscale subpixel hinting and + * (3) for everything else. + * + */ + static void + tt_loader_set_pp( TT_Loader loader ) + { + FT_Bool subpixel_hinting = 0; + FT_Bool grayscale = 0; + FT_Bool use_aw_2 = 0; + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face ); +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) + { + subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting + : 0; + grayscale = loader->exec ? loader->exec->grayscale + : 0; + } +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean + : 0; + grayscale = loader->exec ? loader->exec->grayscale_cleartype + : 0; + } +#endif + + use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale ); + + loader->pp1.x = loader->bbox.xMin - loader->left_bearing; + loader->pp1.y = 0; + loader->pp2.x = loader->pp1.x + loader->advance; + loader->pp2.y = 0; + + loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0; + loader->pp3.y = loader->bbox.yMax + loader->top_bearing; + loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0; + loader->pp4.y = loader->pp3.y - loader->vadvance; + } + + + /* a utility function to retrieve i-th node from given FT_List */ + static FT_ListNode + ft_list_get_node_at( FT_List list, + FT_UInt index ) + { + FT_ListNode cur; + + + if ( !list ) + return NULL; + + for ( cur = list->head; cur; cur = cur->next ) + { + if ( !index ) + return cur; + + index--; + } + + return NULL; + } /*************************************************************************/ @@ -1297,14 +1420,10 @@ FT_Error error = FT_Err_Ok; FT_Fixed x_scale, y_scale; FT_ULong offset; - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; FT_GlyphLoader gloader = loader->gloader; FT_Bool opened_frame = 0; -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Vector* deltas = NULL; -#endif - #ifdef FT_CONFIG_OPTION_INCREMENTAL FT_StreamRec inc_stream; FT_Data glyph_data; @@ -1312,6 +1431,11 @@ #endif +#ifdef FT_DEBUG_LEVEL_TRACE + if ( recurse_count ) + FT_TRACE5(( " nesting level: %d\n", recurse_count )); +#endif + /* some fonts have an incorrect value of `maxComponentDepth', */ /* thus we allow depth 1 to catch the majority of them */ if ( recurse_count > 1 && @@ -1321,19 +1445,21 @@ goto Exit; } +#ifndef FT_CONFIG_OPTION_INCREMENTAL /* check glyph index */ if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) { error = FT_THROW( Invalid_Glyph_Index ); goto Exit; } +#endif loader->glyph_index = glyph_index; if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - x_scale = ((TT_Size)loader->size)->metrics.x_scale; - y_scale = ((TT_Size)loader->size)->metrics.y_scale; + x_scale = loader->size->metrics.x_scale; + y_scale = loader->size->metrics.y_scale; } else { @@ -1341,8 +1467,6 @@ y_scale = 0x10000L; } - tt_get_metrics( loader, glyph_index ); - /* Set `offset' to the start of the glyph relative to the start of */ /* the `glyf' table, and `byte_len' to the length of the glyph in */ /* bytes. */ @@ -1366,7 +1490,8 @@ FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); FT_Stream_OpenMemory( &inc_stream, - glyph_data.pointer, glyph_data.length ); + glyph_data.pointer, + (FT_ULong)glyph_data.length ); loader->stream = &inc_stream; } @@ -1394,7 +1519,7 @@ error = face->access_glyph_frame( loader, glyph_index, loader->glyf_offset + offset, - loader->byte_len ); + (FT_UInt)loader->byte_len ); if ( error ) goto Exit; @@ -1402,7 +1527,17 @@ /* read glyph header first */ error = face->read_glyph_header( loader ); - if ( error || header_only ) + if ( error ) + goto Exit; + + /* the metrics must be computed after loading the glyph header */ + /* since we need the glyph's `yMax' value in case the vertical */ + /* metrics must be emulated */ + error = tt_get_metrics( loader, glyph_index ); + if ( error ) + goto Exit; + + if ( header_only ) goto Exit; } @@ -1413,12 +1548,16 @@ loader->bbox.yMin = 0; loader->bbox.yMax = 0; + error = tt_get_metrics( loader, glyph_index ); + if ( error ) + goto Exit; + if ( header_only ) goto Exit; /* must initialize points before (possibly) overriding */ /* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); + tt_loader_set_pp( loader ); #ifdef FT_CONFIG_OPTION_INCREMENTAL tt_get_metrics_incr_overrides( loader, glyph_index ); @@ -1426,32 +1565,64 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( ((TT_Face)(loader->face))->doblend ) + if ( loader->face->doblend ) { - /* this must be done before scaling */ - FT_Memory memory = loader->face->memory; + /* a small outline structure with four elements for */ + /* communication with `TT_Vary_Apply_Glyph_Deltas' */ + FT_Vector points[4]; + char tags[4] = { 1, 1, 1, 1 }; + short contours[4] = { 0, 1, 2, 3 }; + FT_Outline outline; + + + points[0].x = loader->pp1.x; + points[0].y = loader->pp1.y; + points[1].x = loader->pp2.x; + points[1].y = loader->pp2.y; + + points[2].x = loader->pp3.x; + points[2].y = loader->pp3.y; + points[3].x = loader->pp4.x; + points[3].y = loader->pp4.y; + + outline.n_points = 4; + outline.n_contours = 4; + outline.points = points; + outline.tags = tags; + outline.contours = contours; - - error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), - glyph_index, &deltas, 4 ); + /* this must be done before scaling */ + error = TT_Vary_Apply_Glyph_Deltas( loader->face, + glyph_index, + &outline, + (FT_UInt)outline.n_points ); if ( error ) goto Exit; - loader->pp1.x += deltas[0].x; loader->pp1.y += deltas[0].y; - loader->pp2.x += deltas[1].x; loader->pp2.y += deltas[1].y; - loader->pp3.x += deltas[2].x; loader->pp3.y += deltas[2].y; - loader->pp4.x += deltas[3].x; loader->pp4.y += deltas[3].y; + loader->pp1.x = points[0].x; + loader->pp1.y = points[0].y; + loader->pp2.x = points[1].x; + loader->pp2.y = points[1].y; - FT_FREE( deltas ); + loader->pp3.x = points[2].x; + loader->pp3.y = points[2].y; + loader->pp4.x = points[3].x; + loader->pp4.y = points[3].y; } -#endif +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + /* scale phantom points, if necessary; */ + /* they get rounded in `TT_Hint_Glyph' */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + /* pp1.y and pp2.y are always zero */ + + loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale ); loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); + loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale ); loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); } @@ -1459,9 +1630,9 @@ goto Exit; } - /* must initialize points before (possibly) overriding */ - /* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); + /* must initialize phantom points before (possibly) overriding */ + /* glyph metrics from the incremental interface */ + tt_loader_set_pp( loader ); #ifdef FT_CONFIG_OPTION_INCREMENTAL tt_get_metrics_incr_overrides( loader, glyph_index ); @@ -1497,13 +1668,51 @@ /* otherwise, load a composite! */ else if ( loader->n_contours == -1 ) { + FT_Memory memory = face->root.memory; + FT_UInt start_point; FT_UInt start_contour; FT_ULong ins_pos; /* position of composite instructions, if any */ + FT_ListNode node, node2; + + + /* + * We store the glyph index directly in the `node->data' pointer, + * following the glib solution (cf. macro `GUINT_TO_POINTER') with a + * double cast to make this portable. Note, however, that this needs + * pointers with a width of at least 32 bits. + */ - start_point = gloader->base.outline.n_points; - start_contour = gloader->base.outline.n_contours; + + /* clear the nodes filled by sibling chains */ + node = ft_list_get_node_at( &loader->composites, recurse_count ); + for ( node2 = node; node2; node2 = node2->next ) + node2->data = (void*)ULONG_MAX; + + /* check whether we already have a composite glyph with this index */ + if ( FT_List_Find( &loader->composites, + (void*)(unsigned long)glyph_index ) ) + { + FT_TRACE1(( "TT_Load_Composite_Glyph:" + " infinite recursion detected\n" )); + error = FT_THROW( Invalid_Composite ); + goto Exit; + } + + else if ( node ) + node->data = (void*)(unsigned long)glyph_index; + + else + { + if ( FT_NEW( node ) ) + goto Exit; + node->data = (void*)(unsigned long)glyph_index; + FT_List_Add( &loader->composites, node ); + } + + start_point = (FT_UInt)gloader->base.outline.n_points; + start_contour = (FT_UInt)gloader->base.outline.n_contours; /* for each subglyph, read composite header */ error = face->read_composite_glyph( loader ); @@ -1521,51 +1730,123 @@ if ( face->doblend ) { - FT_Int i, limit; + short i, limit; FT_SubGlyph subglyph; - FT_Memory memory = face->root.memory; + FT_Outline outline; + FT_Vector* points = NULL; + char* tags = NULL; + short* contours = NULL; + + + limit = (short)gloader->current.num_subglyphs; + + /* construct an outline structure for */ + /* communication with `TT_Vary_Apply_Glyph_Deltas' */ + outline.n_points = (short)( gloader->current.num_subglyphs + 4 ); + outline.n_contours = outline.n_points; - /* this provides additional offsets */ - /* for each component's translation */ + outline.points = NULL; + outline.tags = NULL; + outline.contours = NULL; - if ( ( error = TT_Vary_Get_Glyph_Deltas( + if ( FT_NEW_ARRAY( points, outline.n_points ) || + FT_NEW_ARRAY( tags, outline.n_points ) || + FT_NEW_ARRAY( contours, outline.n_points ) ) + goto Exit1; + + subglyph = gloader->current.subglyphs; + + for ( i = 0; i < limit; i++, subglyph++ ) + { + /* applying deltas for anchor points doesn't make sense, */ + /* but we don't have to specially check this since */ + /* unused delta values are zero anyways */ + points[i].x = subglyph->arg1; + points[i].y = subglyph->arg2; + tags[i] = 1; + contours[i] = i; + } + + points[i].x = loader->pp1.x; + points[i].y = loader->pp1.y; + tags[i] = 1; + contours[i] = i; + + i++; + points[i].x = loader->pp2.x; + points[i].y = loader->pp2.y; + tags[i] = 1; + contours[i] = i; + + i++; + points[i].x = loader->pp3.x; + points[i].y = loader->pp3.y; + tags[i] = 1; + contours[i] = i; + + i++; + points[i].x = loader->pp4.x; + points[i].y = loader->pp4.y; + tags[i] = 1; + contours[i] = i; + + outline.points = points; + outline.tags = tags; + outline.contours = contours; + + /* this call provides additional offsets */ + /* for each component's translation */ + if ( ( error = TT_Vary_Apply_Glyph_Deltas( face, glyph_index, - &deltas, - gloader->current.num_subglyphs + 4 )) != 0 ) - goto Exit; + &outline, + (FT_UInt)outline.n_points ) ) != 0 ) + goto Exit1; - subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs; - limit = gloader->current.num_subglyphs; + subglyph = gloader->current.subglyphs; - for ( i = 0; i < limit; ++i, ++subglyph ) + for ( i = 0; i < limit; i++, subglyph++ ) { - if ( subglyph->flags & ARGS_ARE_XY_VALUES ) - { - /* XXX: overflow check for subglyph->{arg1,arg2}. */ - /* deltas[i].{x,y} must be within signed 16-bit, */ - /* but the restriction of summed delta is not clear */ - subglyph->arg1 += (FT_Int16)deltas[i].x; - subglyph->arg2 += (FT_Int16)deltas[i].y; - } + /* XXX: overflow check for subglyph->{arg1,arg2}. */ + /* Deltas must be within signed 16-bit, */ + /* but the restriction of summed deltas is not clear */ + subglyph->arg1 = (FT_Int16)points[i].x; + subglyph->arg2 = (FT_Int16)points[i].y; } - loader->pp1.x += deltas[i + 0].x; loader->pp1.y += deltas[i + 0].y; - loader->pp2.x += deltas[i + 1].x; loader->pp2.y += deltas[i + 1].y; - loader->pp3.x += deltas[i + 2].x; loader->pp3.y += deltas[i + 2].y; - loader->pp4.x += deltas[i + 3].x; loader->pp4.y += deltas[i + 3].y; + loader->pp1.x = points[i + 0].x; + loader->pp1.y = points[i + 0].y; + loader->pp2.x = points[i + 1].x; + loader->pp2.y = points[i + 1].y; + + loader->pp3.x = points[i + 2].x; + loader->pp3.y = points[i + 2].y; + loader->pp4.x = points[i + 3].x; + loader->pp4.y = points[i + 3].y; - FT_FREE( deltas ); + Exit1: + FT_FREE( outline.points ); + FT_FREE( outline.tags ); + FT_FREE( outline.contours ); + + if ( error ) + goto Exit; } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + /* scale phantom points, if necessary; */ + /* they get rounded in `TT_Hint_Glyph' */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + /* pp1.y and pp2.y are always zero */ + + loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale ); loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); + loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale ); loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); } @@ -1586,7 +1867,7 @@ { FT_UInt n, num_base_points; - FT_SubGlyph subglyph = 0; + FT_SubGlyph subglyph = NULL; FT_UInt num_points = start_point; FT_UInt num_subglyphs = gloader->current.num_subglyphs; @@ -1615,16 +1896,19 @@ pp[2] = loader->pp3; pp[3] = loader->pp4; - num_base_points = gloader->base.outline.n_points; + num_base_points = (FT_UInt)gloader->base.outline.n_points; - error = load_truetype_glyph( loader, subglyph->index, - recurse_count + 1, FALSE ); + error = load_truetype_glyph( loader, + (FT_UInt)subglyph->index, + recurse_count + 1, + FALSE ); if ( error ) goto Exit; /* restore subglyph pointer */ subglyph = gloader->base.subglyphs + num_base_subgs + n; + /* restore phantom points if necessary */ if ( !( subglyph->flags & USE_MY_METRICS ) ) { loader->pp1 = pp[0]; @@ -1633,7 +1917,7 @@ loader->pp4 = pp[3]; } - num_points = gloader->base.outline.n_points; + num_points = (FT_UInt)gloader->base.outline.n_points; if ( num_points == num_base_points ) continue; @@ -1644,8 +1928,12 @@ /* (1): exists from the beginning */ /* (2): components that have been loaded so far */ /* (3): the newly loaded component */ - TT_Process_Composite_Component( loader, subglyph, start_point, - num_base_points ); + error = TT_Process_Composite_Component( loader, + subglyph, + start_point, + num_base_points ); + if ( error ) + goto Exit; } loader->stream = old_stream; @@ -1654,16 +1942,17 @@ /* process the glyph */ loader->ins_pos = ins_pos; if ( IS_HINTED( loader->load_flags ) && - #ifdef TT_USE_BYTECODE_INTERPRETER - subglyph->flags & WE_HAVE_INSTR && - #endif - num_points > start_point ) - TT_Process_Composite_Glyph( loader, start_point, start_contour ); - + { + error = TT_Process_Composite_Glyph( loader, + start_point, + start_contour ); + if ( error ) + goto Exit; + } } } else @@ -1699,15 +1988,16 @@ compute_glyph_metrics( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Face face = loader->face; +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif FT_BBox bbox; FT_Fixed y_scale; TT_GlyphSlot glyph = loader->glyph; - TT_Size size = (TT_Size)loader->size; + TT_Size size = loader->size; y_scale = 0x10000L; @@ -1727,9 +2017,18 @@ glyph->metrics.horiBearingY = bbox.yMax; glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - /* adjust advance width to the value contained in the hdmx table */ - if ( !face->postscript.isFixedPitch && - IS_HINTED( loader->load_flags ) ) + /* Adjust advance width to the value contained in the hdmx table */ + /* unless FT_LOAD_COMPUTE_METRICS is set or backwards compatibility */ + /* mode of the v40 interpreter is active. See `ttinterp.h' for */ + /* details on backwards compatibility mode. */ + if ( +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && + ( loader->exec && loader->exec->backwards_compatibility ) ) && +#endif + !face->postscript.isFixedPitch && + IS_HINTED( loader->load_flags ) && + !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) ) { FT_Byte* widthp; @@ -1738,7 +2037,7 @@ size->root.metrics.x_ppem, glyph_index ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -1752,15 +2051,15 @@ ( ( ignore_x_mode && loader->exec->compatible_widths ) || !ignore_x_mode || SPH_OPTION_BITMAP_WIDTHS ) ) - glyph->metrics.horiAdvance = *widthp << 6; + glyph->metrics.horiAdvance = *widthp * 64; } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { if ( widthp ) - glyph->metrics.horiAdvance = *widthp << 6; + glyph->metrics.horiAdvance = *widthp * 64; } } @@ -1891,7 +2190,7 @@ error = sfnt->load_sbit_image( face, size->strike_index, glyph_index, - (FT_Int)load_flags, + (FT_UInt)load_flags, stream, &glyph->bitmap, &metrics ); @@ -1900,16 +2199,16 @@ glyph->outline.n_points = 0; glyph->outline.n_contours = 0; - glyph->metrics.width = (FT_Pos)metrics.width << 6; - glyph->metrics.height = (FT_Pos)metrics.height << 6; + glyph->metrics.width = (FT_Pos)metrics.width * 64; + glyph->metrics.height = (FT_Pos)metrics.height * 64; - glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; - glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; - glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX * 64; + glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY * 64; + glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance * 64; - glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; - glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; - glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX * 64; + glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY * 64; + glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance * 64; glyph->format = FT_GLYPH_FORMAT_BITMAP; @@ -1938,11 +2237,17 @@ FT_Int32 load_flags, FT_Bool glyf_table_only ) { + FT_Error error; + TT_Face face; FT_Stream stream; #ifdef TT_USE_BYTECODE_INTERPRETER FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); #endif +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face ); +#endif face = (TT_Face)glyph->face; @@ -1956,72 +2261,97 @@ if ( IS_HINTED( load_flags ) && !glyf_table_only ) { TT_ExecContext exec; - FT_Bool grayscale; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); + FT_Bool grayscale = TRUE; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + FT_Bool subpixel_hinting_lean; + FT_Bool grayscale_cleartype; +#endif - FT_Bool subpixel_hinting = FALSE; - FT_Bool grayscale_hinting = TRUE; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + FT_Bool subpixel_hinting = FALSE; #if 0 /* not used yet */ FT_Bool compatible_widths; FT_Bool symmetrical_smoothing; FT_Bool bgr; + FT_Bool vertical_lcd; FT_Bool subpixel_positioned; + FT_Bool gray_cleartype; #endif -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ FT_Bool reexecute = FALSE; - if ( !size->cvt_ready ) + if ( size->bytecode_ready < 0 || size->cvt_ready < 0 ) { - FT_Error error = tt_size_ready_bytecode( size, pedantic ); - - + error = tt_size_ready_bytecode( size, pedantic ); if ( error ) return error; } + else if ( size->bytecode_ready ) + return size->bytecode_ready; + else if ( size->cvt_ready ) + return size->cvt_ready; /* query new execution context */ - exec = size->debug ? size->context - : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; + exec = size->context; if ( !exec ) return FT_THROW( Could_Not_Find_Context ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + subpixel_hinting_lean = TRUE; + grayscale_cleartype = !FT_BOOL( load_flags & + FT_LOAD_TARGET_LCD || + load_flags & + FT_LOAD_TARGET_LCD_V ); + exec->vertical_lcd_lean = FT_BOOL( load_flags & + FT_LOAD_TARGET_LCD_V ); + } + else + { + subpixel_hinting_lean = FALSE; + grayscale_cleartype = FALSE; + exec->vertical_lcd_lean = FALSE; + } +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { - subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) - != FT_RENDER_MODE_MONO ) && - SPH_OPTION_SET_SUBPIXEL ); + subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) != + FT_RENDER_MODE_MONO ) && + SPH_OPTION_SET_SUBPIXEL ); if ( subpixel_hinting ) - grayscale = grayscale_hinting = FALSE; + grayscale = FALSE; else if ( SPH_OPTION_SET_GRAYSCALE ) { - grayscale = grayscale_hinting = TRUE; - subpixel_hinting = FALSE; + grayscale = TRUE; + subpixel_hinting = FALSE; } else - grayscale = grayscale_hinting = FALSE; + grayscale = FALSE; if ( FT_IS_TRICKY( glyph->face ) ) - subpixel_hinting = grayscale_hinting = FALSE; + subpixel_hinting = FALSE; - exec->ignore_x_mode = subpixel_hinting || grayscale_hinting; + exec->ignore_x_mode = subpixel_hinting || grayscale; exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) exec->rasterizer_version = TT_INTERPRETER_VERSION_35; #if 1 exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS; - exec->symmetrical_smoothing = FALSE; + exec->symmetrical_smoothing = TRUE; exec->bgr = FALSE; + exec->vertical_lcd = FALSE; exec->subpixel_positioned = TRUE; + exec->gray_cleartype = FALSE; #else /* 0 */ exec->compatible_widths = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != @@ -2032,24 +2362,37 @@ exec->bgr = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != TT_LOAD_BGR ); + exec->vertical_lcd = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + TT_LOAD_VERTICAL_LCD ); exec->subpixel_positioned = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != TT_LOAD_SUBPIXEL_POSITIONED ); + exec->gray_cleartype = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + TT_LOAD_GRAY_CLEARTYPE ); #endif /* 0 */ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + grayscale = FT_BOOL( !subpixel_hinting_lean && + FT_LOAD_TARGET_MODE( load_flags ) != + FT_RENDER_MODE_MONO ); + else +#endif grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - FT_RENDER_MODE_MONO ); - } + FT_RENDER_MODE_MONO ); - TT_Load_Context( exec, face, size ); + error = TT_Load_Context( exec, face, size ); + if ( error ) + return error; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -2066,25 +2409,53 @@ /* a change from mono to grayscale rendering (and vice versa) */ /* requires a re-execution of the CVT program */ - if ( grayscale != exec->grayscale_hinting ) + if ( grayscale != exec->grayscale ) { FT_TRACE4(( "tt_loader_init: grayscale hinting change," " re-executing `prep' table\n" )); - exec->grayscale_hinting = grayscale_hinting; - reexecute = TRUE; + exec->grayscale = grayscale; + reexecute = TRUE; } } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + /* a change from mono to subpixel rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ + if ( subpixel_hinting_lean != exec->subpixel_hinting_lean ) + { + FT_TRACE4(( "tt_loader_init: subpixel hinting change," + " re-executing `prep' table\n" )); + + exec->subpixel_hinting_lean = subpixel_hinting_lean; + reexecute = TRUE; + } + + /* a change from colored to grayscale subpixel rendering (and */ + /* vice versa) requires a re-execution of the CVT program */ + if ( grayscale_cleartype != exec->grayscale_cleartype ) + { + FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change," + " re-executing `prep' table\n" )); + + exec->grayscale_cleartype = grayscale_cleartype; + reexecute = TRUE; + } + } +#endif + /* a change from mono to grayscale rendering (and vice versa) */ /* requires a re-execution of the CVT program */ if ( grayscale != exec->grayscale ) { - FT_TRACE4(( "tt_loader_init: grayscale change," + FT_TRACE4(( "tt_loader_init: grayscale hinting change," " re-executing `prep' table\n" )); exec->grayscale = grayscale; @@ -2099,10 +2470,12 @@ for ( i = 0; i < size->cvt_size; i++ ) size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - tt_size_run_prep( size, pedantic ); + error = tt_size_run_prep( size, pedantic ); + if ( error ) + return error; } - /* see whether the cvt program has disabled hinting */ + /* check whether the cvt program has disabled hinting */ if ( exec->GS.instruct_control & 1 ) load_flags |= FT_LOAD_NO_HINTING; @@ -2110,6 +2483,14 @@ if ( exec->GS.instruct_control & 2 ) exec->GS = tt_default_graphics_state; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* check whether we have a font hinted for ClearType -- */ + /* note that this flag can also be modified in a glyph's bytecode */ + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && + exec->GS.instruct_control & 4 ) + exec->ignore_x_mode = 0; +#endif + exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); loader->exec = exec; loader->instructions = exec->glyphIns; @@ -2130,8 +2511,7 @@ #endif { - FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 ); - + error = face->goto_table( face, TTAG_glyf, stream, 0 ); if ( FT_ERR_EQ( error, Table_Missing ) ) loader->glyf_offset = 0; @@ -2154,17 +2534,30 @@ loader->gloader = gloader; } - loader->load_flags = load_flags; + loader->load_flags = (FT_ULong)load_flags; - loader->face = (FT_Face)face; - loader->size = (FT_Size)size; + loader->face = face; + loader->size = size; loader->glyph = (FT_GlyphSlot)glyph; loader->stream = stream; + loader->composites.head = NULL; + loader->composites.tail = NULL; + return FT_Err_Ok; } + static void + tt_loader_done( TT_Loader loader ) + { + FT_List_Finalize( &loader->composites, + NULL, + loader->face->root.memory, + NULL ); + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -2202,7 +2595,7 @@ TT_LoaderRec loader; - error = FT_Err_Ok; + FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index )); #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS @@ -2221,16 +2614,20 @@ /* for the bbox we need the header only */ (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); + tt_loader_done( &loader ); glyph->linearHoriAdvance = loader.linear; - glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax - - loader.vadvance; + glyph->linearVertAdvance = loader.vadvance; - /* sanity check: if `horiAdvance' in the sbit metric */ - /* structure isn't set, use `linearHoriAdvance' */ + /* sanity checks: if `xxxAdvance' in the sbit metric */ + /* structure isn't set, use `linearXXXAdvance' */ if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance ) glyph->metrics.horiAdvance = FT_MulFix( glyph->linearHoriAdvance, size->root.metrics.x_scale ); + if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance ) + glyph->metrics.vertAdvance = + FT_MulFix( glyph->linearVertAdvance, + size->root.metrics.y_scale ); } return FT_Err_Ok; @@ -2310,9 +2707,11 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ - compute_glyph_metrics( &loader, glyph_index ); + error = compute_glyph_metrics( &loader, glyph_index ); } + tt_loader_done( &loader ); + /* Set the `high precision' bit flag. */ /* This is _critical_ to get correct output for monochrome */ /* TrueType glyphs at all sizes using the bytecode interpreter. */ diff --git a/drivers/freetype/freetype/src/truetype/ttgload.h b/drivers/freetype/src/truetype/ttgload.h index 05f75882dc..bfa29e4ff8 100644 --- a/drivers/freetype/freetype/src/truetype/ttgload.h +++ b/drivers/freetype/src/truetype/ttgload.h @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2006, 2008, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTGLOAD_H__ -#define __TTGLOAD_H__ +#ifndef TTGLOAD_H_ +#define TTGLOAD_H_ #include <ft2build.h> @@ -43,6 +43,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) TT_Get_VMetrics( TT_Face face, FT_UInt idx, + FT_Pos yMax, FT_Short* tsb, FT_UShort* ah ); @@ -55,7 +56,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTGLOAD_H__ */ +#endif /* TTGLOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttgxvar.c b/drivers/freetype/src/truetype/ttgxvar.c index 7899d3671d..9a02c5a8c1 100644 --- a/drivers/freetype/freetype/src/truetype/ttgxvar.c +++ b/drivers/freetype/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader */ /* */ -/* Copyright 2004-2013 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,7 @@ /* */ /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ /* */ - /* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html */ /* */ /* The documentation for `fvar' is inconsistent. At one point it says */ /* that `countSizePairs' should be 3, at another point 2. It should */ @@ -60,9 +60,9 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -#define FT_Stream_FTell( stream ) \ +#define FT_Stream_FTell( stream ) \ (FT_ULong)( (stream)->cursor - (stream)->base ) -#define FT_Stream_SeekSet( stream, off ) \ +#define FT_Stream_SeekSet( stream, off ) \ ( (stream)->cursor = (stream)->base + (off) ) @@ -96,8 +96,8 @@ #define ALL_POINTS (FT_UShort*)~(FT_PtrDist)0 -#define GX_PT_POINTS_ARE_WORDS 0x80 -#define GX_PT_POINT_RUN_COUNT_MASK 0x7F +#define GX_PT_POINTS_ARE_WORDS 0x80U +#define GX_PT_POINT_RUN_COUNT_MASK 0x7FU /*************************************************************************/ @@ -112,6 +112,8 @@ /* <Input> */ /* stream :: The data stream. */ /* */ + /* size :: The size of the table holding the data. */ + /* */ /* <Output> */ /* point_cnt :: The number of points read. A zero value means that */ /* all points in the glyph will be affected, without */ @@ -123,55 +125,77 @@ /* */ static FT_UShort* ft_var_readpackedpoints( FT_Stream stream, + FT_ULong size, FT_UInt *point_cnt ) { FT_UShort *points = NULL; - FT_Int n; - FT_Int runcnt; - FT_Int i; - FT_Int j; - FT_Int first; + FT_UInt n; + FT_UInt runcnt; + FT_UInt i, j; + FT_UShort first; FT_Memory memory = stream->memory; FT_Error error = FT_Err_Ok; FT_UNUSED( error ); - *point_cnt = n = FT_GET_BYTE(); + *point_cnt = 0; + + n = FT_GET_BYTE(); if ( n == 0 ) return ALL_POINTS; if ( n & GX_PT_POINTS_ARE_WORDS ) - n = FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 ); + { + n &= GX_PT_POINT_RUN_COUNT_MASK; + n <<= 8; + n |= FT_GET_BYTE(); + } + + if ( n > size ) + { + FT_TRACE1(( "ft_var_readpackedpoints: number of points too large\n" )); + return NULL; + } if ( FT_NEW_ARRAY( points, n ) ) return NULL; + *point_cnt = n; + i = 0; while ( i < n ) { runcnt = FT_GET_BYTE(); if ( runcnt & GX_PT_POINTS_ARE_WORDS ) { - runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK; - first = points[i++] = FT_GET_USHORT(); + runcnt &= GX_PT_POINT_RUN_COUNT_MASK; + first = FT_GET_USHORT(); + points[i++] = first; - if ( runcnt < 1 || i + runcnt >= n ) + if ( runcnt < 1 || i + runcnt > n ) goto Exit; - /* first point not included in runcount */ - for ( j = 0; j < runcnt; ++j ) - points[i++] = (FT_UShort)( first += FT_GET_USHORT() ); + /* first point not included in run count */ + for ( j = 0; j < runcnt; j++ ) + { + first += FT_GET_USHORT(); + points[i++] = first; + } } else { - first = points[i++] = FT_GET_BYTE(); + first = FT_GET_BYTE(); + points[i++] = first; - if ( runcnt < 1 || i + runcnt >= n ) + if ( runcnt < 1 || i + runcnt > n ) goto Exit; - for ( j = 0; j < runcnt; ++j ) - points[i++] = (FT_UShort)( first += FT_GET_BYTE() ); + for ( j = 0; j < runcnt; j++ ) + { + first += FT_GET_BYTE(); + points[i++] = first; + } } } @@ -180,12 +204,9 @@ } - enum - { - GX_DT_DELTAS_ARE_ZERO = 0x80, - GX_DT_DELTAS_ARE_WORDS = 0x40, - GX_DT_DELTA_RUN_COUNT_MASK = 0x3F - }; +#define GX_DT_DELTAS_ARE_ZERO 0x80U +#define GX_DT_DELTAS_ARE_WORDS 0x40U +#define GX_DT_DELTA_RUN_COUNT_MASK 0x3FU /*************************************************************************/ @@ -200,7 +221,9 @@ /* <Input> */ /* stream :: The data stream. */ /* */ - /* delta_cnt :: The number of to be read. */ + /* size :: The size of the table holding the data. */ + /* */ + /* delta_cnt :: The number of deltas to be read. */ /* */ /* <Return> */ /* An array of FT_Short containing the deltas for the affected */ @@ -210,18 +233,24 @@ /* */ static FT_Short* ft_var_readpackeddeltas( FT_Stream stream, - FT_Offset delta_cnt ) + FT_ULong size, + FT_UInt delta_cnt ) { FT_Short *deltas = NULL; - FT_UInt runcnt; - FT_Offset i; - FT_UInt j; + FT_UInt runcnt, cnt; + FT_UInt i, j; FT_Memory memory = stream->memory; FT_Error error = FT_Err_Ok; FT_UNUSED( error ); + if ( delta_cnt > size ) + { + FT_TRACE1(( "ft_var_readpackeddeltas: number of points too large\n" )); + return NULL; + } + if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) return NULL; @@ -229,34 +258,30 @@ while ( i < delta_cnt ) { runcnt = FT_GET_BYTE(); + cnt = runcnt & GX_DT_DELTA_RUN_COUNT_MASK; + if ( runcnt & GX_DT_DELTAS_ARE_ZERO ) { - /* runcnt zeroes get added */ - for ( j = 0; - j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; - ++j ) + /* `runcnt' zeroes get added */ + for ( j = 0; j <= cnt && i < delta_cnt; j++ ) deltas[i++] = 0; } else if ( runcnt & GX_DT_DELTAS_ARE_WORDS ) { - /* runcnt shorts from the stack */ - for ( j = 0; - j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; - ++j ) + /* `runcnt' shorts from the stack */ + for ( j = 0; j <= cnt && i < delta_cnt; j++ ) deltas[i++] = FT_GET_SHORT(); } else { - /* runcnt signed bytes from the stack */ - for ( j = 0; - j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; - ++j ) + /* `runcnt' signed bytes from the stack */ + for ( j = 0; j <= cnt && i < delta_cnt; j++ ) deltas[i++] = FT_GET_CHAR(); } - if ( j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) ) + if ( j <= cnt ) { - /* Bad format */ + /* bad format */ FT_FREE( deltas ); return NULL; } @@ -281,12 +306,12 @@ static void ft_var_load_avar( TT_Face face ) { - FT_Stream stream = FT_FACE_STREAM(face); + FT_Stream stream = FT_FACE_STREAM( face ); FT_Memory memory = stream->memory; GX_Blend blend = face->blend; GX_AVarSegment segment; FT_Error error = FT_Err_Ok; - FT_ULong version; + FT_Long version; FT_Long axisCount; FT_Int i, j; FT_ULong table_len; @@ -294,9 +319,15 @@ FT_UNUSED( error ); + FT_TRACE2(( "AVAR " )); + blend->avar_checked = TRUE; - if ( (error = face->goto_table( face, TTAG_avar, stream, &table_len )) != 0 ) + error = face->goto_table( face, TTAG_avar, stream, &table_len ); + if ( error ) + { + FT_TRACE2(( "is missing\n" )); return; + } if ( FT_FRAME_ENTER( table_len ) ) return; @@ -304,23 +335,37 @@ version = FT_GET_LONG(); axisCount = FT_GET_LONG(); - if ( version != 0x00010000L || - axisCount != (FT_Long)blend->mmvar->num_axis ) + if ( version != 0x00010000L ) + { + FT_TRACE2(( "bad table version\n" )); goto Exit; + } + + FT_TRACE2(( "loaded\n" )); + + if ( axisCount != (FT_Long)blend->mmvar->num_axis ) + { + FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `cvar'\n" + " table are different\n" )); + goto Exit; + } if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) ) goto Exit; segment = &blend->avar_segment[0]; - for ( i = 0; i < axisCount; ++i, ++segment ) + for ( i = 0; i < axisCount; i++, segment++ ) { + FT_TRACE5(( " axis %d:\n", i )); + segment->pairCount = FT_GET_USHORT(); - if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) + if ( (FT_ULong)segment->pairCount * 4 > table_len || + FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) { /* Failure. Free everything we have done so far. We must do */ /* it right now since loading the `avar' table is optional. */ - for ( j = i - 1; j >= 0; --j ) + for ( j = i - 1; j >= 0; j-- ) FT_FREE( blend->avar_segment[j].correspondence ); FT_FREE( blend->avar_segment ); @@ -328,13 +373,18 @@ goto Exit; } - for ( j = 0; j < segment->pairCount; ++j ) + for ( j = 0; j < segment->pairCount; j++ ) { - segment->correspondence[j].fromCoord = - FT_GET_SHORT() << 2; /* convert to Fixed */ - segment->correspondence[j].toCoord = - FT_GET_SHORT()<<2; /* convert to Fixed */ + /* convert to Fixed */ + segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4; + segment->correspondence[j].toCoord = FT_GET_SHORT() * 4; + + FT_TRACE5(( " mapping %.4f to %.4f\n", + segment->correspondence[j].fromCoord / 65536.0, + segment->correspondence[j].toCoord / 65536.0 )); } + + FT_TRACE5(( "\n" )); } Exit: @@ -361,8 +411,8 @@ /* ft_var_load_gvar */ /* */ /* <Description> */ - /* Parses the `gvar' table if present. If `fvar' is there, `gvar' */ - /* had better be there too. */ + /* Parse the `gvar' table if present. If `fvar' is there, `gvar' had */ + /* better be there too. */ /* */ /* <InOut> */ /* face :: The font face. */ @@ -373,7 +423,7 @@ static FT_Error ft_var_load_gvar( TT_Face face ) { - FT_Stream stream = FT_FACE_STREAM(face); + FT_Stream stream = FT_FACE_STREAM( face ); FT_Memory memory = stream->memory; GX_Blend blend = face->blend; FT_Error error; @@ -400,24 +450,67 @@ FT_FRAME_END }; - if ( (error = face->goto_table( face, TTAG_gvar, stream, &table_len )) != 0 ) + + FT_TRACE2(( "GVAR " )); + + if ( ( error = face->goto_table( face, + TTAG_gvar, + stream, + &table_len ) ) != 0 ) + { + FT_TRACE2(( "is missing\n" )); goto Exit; + } gvar_start = FT_STREAM_POS( ); if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) goto Exit; - blend->tuplecount = gvar_head.globalCoordCount; - blend->gv_glyphcnt = gvar_head.glyphCount; - offsetToData = gvar_start + gvar_head.offsetToData; + if ( gvar_head.version != 0x00010000L ) + { + FT_TRACE1(( "bad table version\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) + { + FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n" + " table are different\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* rough sanity check, ignoring offsets */ + if ( (FT_ULong)gvar_head.globalCoordCount * gvar_head.axisCount > + table_len / 2 ) + { + FT_TRACE1(( "ft_var_load_gvar:" + " invalid number of global coordinates\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } - if ( gvar_head.version != (FT_Long)0x00010000L || - gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) + /* rough sanity check: offsets can be either 2 or 4 bytes, */ + /* and a single variation needs at least 4 bytes per glyph */ + if ( (FT_ULong)gvar_head.glyphCount * + ( ( gvar_head.flags & 1 ) ? 8 : 6 ) > table_len ) { + FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } + FT_TRACE2(( "loaded\n" )); + + blend->gvar_size = table_len; + blend->tuplecount = gvar_head.globalCoordCount; + blend->gv_glyphcnt = gvar_head.glyphCount; + offsetToData = gvar_start + gvar_head.offsetToData; + + FT_TRACE5(( "gvar: there are %d shared coordinates:\n", + blend->tuplecount )); + if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) ) goto Exit; @@ -427,8 +520,8 @@ if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) goto Exit; - for ( i = 0; i <= blend->gv_glyphcnt; ++i ) - blend->glyphoffsets[i] = offsetToData + FT_GET_LONG(); + for ( i = 0; i <= blend->gv_glyphcnt; i++ ) + blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG(); FT_FRAME_EXIT(); } @@ -438,9 +531,9 @@ if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) ) goto Exit; - for ( i = 0; i <= blend->gv_glyphcnt; ++i ) + for ( i = 0; i <= blend->gv_glyphcnt; i++ ) blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2; - /* XXX: Undocumented: `*2'! */ + /* XXX: Undocumented: `*2'! */ FT_FRAME_EXIT(); } @@ -451,14 +544,24 @@ gvar_head.axisCount * blend->tuplecount ) ) goto Exit; - if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) || - FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) ) + if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) || + FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) ) goto Exit; - for ( i = 0; i < blend->tuplecount; ++i ) - for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; ++j ) + for ( i = 0; i < blend->tuplecount; i++ ) + { + FT_TRACE5(( " [ " )); + for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ ) + { blend->tuplecoords[i * gvar_head.axisCount + j] = - FT_GET_SHORT() << 2; /* convert to FT_Fixed */ + FT_GET_SHORT() * 4; /* convert to FT_Fixed */ + FT_TRACE5(( "%.4f ", + blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 )); + } + FT_TRACE5(( "]\n" )); + } + + FT_TRACE5(( "\n" )); FT_FRAME_EXIT(); } @@ -506,48 +609,100 @@ FT_Fixed apply = 0x10000L; - for ( i = 0; i < blend->num_axis; ++i ) + for ( i = 0; i < blend->num_axis; i++ ) { + FT_TRACE6(( " axis coordinate %d (%.4f):\n", + i, blend->normalizedcoords[i] / 65536.0 )); + if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) + FT_TRACE6(( " intermediate coordinates %d (%.4f, %.4f):\n", + i, + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + + /* It's not clear why (for intermediate tuples) we don't need */ + /* to check against start/end -- the documentation says we don't. */ + /* Similarly, it's unclear why we don't need to scale along the */ + /* axis. */ + if ( tuple_coords[i] == 0 ) - /* It's not clear why (for intermediate tuples) we don't need */ - /* to check against start/end -- the documentation says we don't. */ - /* Similarly, it's unclear why we don't need to scale along the */ - /* axis. */ + { + FT_TRACE6(( " tuple coordinate is zero, ignored\n", i )); continue; + } - else if ( blend->normalizedcoords[i] == 0 || - ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) || - ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) ) + if ( blend->normalizedcoords[i] == 0 ) { + FT_TRACE6(( " axis coordinate is zero, stop\n" )); apply = 0; break; } - else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) - /* not an intermediate tuple */ - apply = FT_MulFix( apply, - blend->normalizedcoords[i] > 0 - ? blend->normalizedcoords[i] - : -blend->normalizedcoords[i] ); - - else if ( blend->normalizedcoords[i] <= im_start_coords[i] || - blend->normalizedcoords[i] >= im_end_coords[i] ) + if ( blend->normalizedcoords[i] == tuple_coords[i] ) { - apply = 0; - break; + FT_TRACE6(( " tuple coordinate value %.4f fits perfectly\n", + tuple_coords[i] / 65536.0 )); + /* `apply' does not change */ + continue; } - else if ( blend->normalizedcoords[i] < tuple_coords[i] ) - apply = FT_MulDiv( apply, - blend->normalizedcoords[i] - im_start_coords[i], - tuple_coords[i] - im_start_coords[i] ); + if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) + { + /* not an intermediate tuple */ - else + if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) || + blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) ) + { + FT_TRACE6(( " tuple coordinate value %.4f is exceeded, stop\n", + tuple_coords[i] / 65536.0 )); + apply = 0; + break; + } + + FT_TRACE6(( " tuple coordinate value %.4f fits\n", + tuple_coords[i] / 65536.0 )); apply = FT_MulDiv( apply, - im_end_coords[i] - blend->normalizedcoords[i], - im_end_coords[i] - tuple_coords[i] ); + blend->normalizedcoords[i], + tuple_coords[i] ); + } + else + { + /* intermediate tuple */ + + if ( blend->normalizedcoords[i] < im_start_coords[i] || + blend->normalizedcoords[i] > im_end_coords[i] ) + { + FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] is exceeded," + " stop\n", + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + apply = 0; + break; + } + + else if ( blend->normalizedcoords[i] < tuple_coords[i] ) + { + FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n", + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + apply = FT_MulDiv( apply, + blend->normalizedcoords[i] - im_start_coords[i], + tuple_coords[i] - im_start_coords[i] ); + } + + else + { + FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n", + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + apply = FT_MulDiv( apply, + im_end_coords[i] - blend->normalizedcoords[i], + im_end_coords[i] - tuple_coords[i] ); + } + } } + FT_TRACE6(( " apply factor is %.4f\n", apply / 65536.0 )); + return apply; } @@ -577,9 +732,9 @@ typedef struct fvar_axis_ { FT_ULong axisTag; - FT_ULong minValue; - FT_ULong defaultValue; - FT_ULong maxValue; + FT_Fixed minValue; + FT_Fixed defaultValue; + FT_Fixed maxValue; FT_UShort flags; FT_UShort nameID; @@ -600,7 +755,8 @@ /* TT_Get_MM_Var initializes the blend structure. */ /* */ /* <Output> */ - /* master :: The `fvar' data (must be freed by caller). */ + /* master :: The `fvar' data (must be freed by caller). Can be NULL, */ + /* which makes this function simply load MM support. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ @@ -647,25 +803,37 @@ FT_FRAME_START( 20 ), FT_FRAME_ULONG ( axisTag ), - FT_FRAME_ULONG ( minValue ), - FT_FRAME_ULONG ( defaultValue ), - FT_FRAME_ULONG ( maxValue ), + FT_FRAME_LONG ( minValue ), + FT_FRAME_LONG ( defaultValue ), + FT_FRAME_LONG ( maxValue ), FT_FRAME_USHORT( flags ), FT_FRAME_USHORT( nameID ), FT_FRAME_END }; + /* read the font data and set up the internal representation */ + /* if not already done */ + if ( face->blend == NULL ) { + FT_TRACE2(( "FVAR " )); + /* both `fvar' and `gvar' must be present */ - if ( (error = face->goto_table( face, TTAG_gvar, - stream, &table_len )) != 0 ) + if ( ( error = face->goto_table( face, TTAG_gvar, + stream, &table_len ) ) != 0 ) + { + FT_TRACE1(( "\n" + "TT_Get_MM_Var: `gvar' table is missing\n" )); goto Exit; + } - if ( (error = face->goto_table( face, TTAG_fvar, - stream, &table_len )) != 0 ) + if ( ( error = face->goto_table( face, TTAG_fvar, + stream, &table_len ) ) != 0 ) + { + FT_TRACE1(( "is missing\n" )); goto Exit; + } fvar_start = FT_STREAM_POS( ); @@ -673,7 +841,12 @@ goto Exit; if ( fvar_head.version != (FT_Long)0x00010000L || +#if 0 + /* fonts like `JamRegular.ttf' have an incorrect value for */ + /* `countSizePairs'; since value 2 is hard-coded in `fvar' */ + /* version 1.0, we simply ignore it */ fvar_head.countSizePairs != 2 || +#endif fvar_head.axisSize != 20 || /* axisCount limit implied by 16-bit instanceSize */ fvar_head.axisCount > 0x3FFE || @@ -683,10 +856,16 @@ fvar_head.offsetToData + fvar_head.axisCount * 20U + fvar_head.instanceCount * fvar_head.instanceSize > table_len ) { + FT_TRACE1(( "\n" + "TT_Get_MM_Var: invalid `fvar' header\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } + FT_TRACE2(( "loaded\n" )); + + FT_TRACE5(( "number of GX style axes: %d\n", fvar_head.axisCount )); + if ( FT_NEW( face->blend ) ) goto Exit; @@ -702,6 +881,9 @@ goto Exit; face->blend->mmvar = mmvar; + /* set up pointers and offsets into the `mmvar' array; */ + /* the data gets filled in later on */ + mmvar->num_axis = fvar_head.axisCount; mmvar->num_designs = @@ -711,30 +893,32 @@ mmvar->num_namedstyles = fvar_head.instanceCount; mmvar->axis = - (FT_Var_Axis*)&(mmvar[1]); + (FT_Var_Axis*)&( mmvar[1] ); mmvar->namedstyle = - (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]); + (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] ); next_coords = - (FT_Fixed*)&(mmvar->namedstyle[fvar_head.instanceCount]); - for ( i = 0; i < fvar_head.instanceCount; ++i ) + (FT_Fixed*)&( mmvar->namedstyle[fvar_head.instanceCount] ); + for ( i = 0; i < fvar_head.instanceCount; i++ ) { mmvar->namedstyle[i].coords = next_coords; next_coords += fvar_head.axisCount; } next_name = (FT_String*)next_coords; - for ( i = 0; i < fvar_head.axisCount; ++i ) + for ( i = 0; i < fvar_head.axisCount; i++ ) { mmvar->axis[i].name = next_name; next_name += 5; } + /* now fill in the data */ + if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) ) goto Exit; a = mmvar->axis; - for ( i = 0; i < fvar_head.axisCount; ++i ) + for ( i = 0; i < fvar_head.axisCount; i++ ) { GX_FVar_Axis axis_rec; @@ -742,22 +926,30 @@ if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) ) goto Exit; a->tag = axis_rec.axisTag; - a->minimum = axis_rec.minValue; /* A Fixed */ - a->def = axis_rec.defaultValue; /* A Fixed */ - a->maximum = axis_rec.maxValue; /* A Fixed */ + a->minimum = axis_rec.minValue; + a->def = axis_rec.defaultValue; + a->maximum = axis_rec.maxValue; a->strid = axis_rec.nameID; a->name[0] = (FT_String)( a->tag >> 24 ); a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF ); a->name[2] = (FT_String)( ( a->tag >> 8 ) & 0xFF ); a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); - a->name[4] = 0; + a->name[4] = '\0'; - ++a; + FT_TRACE5(( " \"%s\": minimum=%.4f, default=%.4f, maximum=%.4f\n", + a->name, + a->minimum / 65536.0, + a->def / 65536.0, + a->maximum / 65536.0 )); + + a++; } + FT_TRACE5(( "\n" )); + ns = mmvar->namedstyle; - for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns ) + for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) { if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) goto Exit; @@ -765,13 +957,15 @@ ns->strid = FT_GET_USHORT(); (void) /* flags = */ FT_GET_USHORT(); - for ( j = 0; j < fvar_head.axisCount; ++j ) - ns->coords[j] = FT_GET_ULONG(); /* A Fixed */ + for ( j = 0; j < fvar_head.axisCount; j++ ) + ns->coords[j] = FT_GET_LONG(); FT_FRAME_EXIT(); } } + /* fill the output array if requested */ + if ( master != NULL ) { FT_UInt n; @@ -782,36 +976,36 @@ FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); mmvar->axis = - (FT_Var_Axis*)&(mmvar[1]); + (FT_Var_Axis*)&( mmvar[1] ); mmvar->namedstyle = - (FT_Var_Named_Style*)&(mmvar->axis[mmvar->num_axis]); + (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] ); next_coords = - (FT_Fixed*)&(mmvar->namedstyle[mmvar->num_namedstyles]); + (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] ); - for ( n = 0; n < mmvar->num_namedstyles; ++n ) + for ( n = 0; n < mmvar->num_namedstyles; n++ ) { mmvar->namedstyle[n].coords = next_coords; next_coords += mmvar->num_axis; } - a = mmvar->axis; + a = mmvar->axis; next_name = (FT_String*)next_coords; - for ( n = 0; n < mmvar->num_axis; ++n ) + for ( n = 0; n < mmvar->num_axis; n++ ) { a->name = next_name; /* standard PostScript names for some standard apple tags */ if ( a->tag == TTAG_wght ) - a->name = (char *)"Weight"; + a->name = (char*)"Weight"; else if ( a->tag == TTAG_wdth ) - a->name = (char *)"Width"; + a->name = (char*)"Width"; else if ( a->tag == TTAG_opsz ) - a->name = (char *)"OpticalSize"; + a->name = (char*)"OpticalSize"; else if ( a->tag == TTAG_slnt ) - a->name = (char *)"Slant"; + a->name = (char*)"Slant"; next_name += 5; - ++a; + a++; } *master = mmvar; @@ -837,9 +1031,12 @@ /* Initialize the blend structure with `gvar' data. */ /* */ /* <Input> */ - /* num_coords :: Must be the axis count of the font. */ + /* num_coords :: The number of available coordinates. If it is */ + /* larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use the default value (0) for the remaining axes. */ /* */ - /* coords :: An array of num_coords, each between [-1,1]. */ + /* coords :: An array of `num_coords', each between [-1,1]. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ @@ -868,33 +1065,44 @@ if ( face->blend == NULL ) { - if ( (error = TT_Get_MM_Var( face, NULL)) != 0 ) + if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) goto Exit; } blend = face->blend; mmvar = blend->mmvar; - if ( num_coords != mmvar->num_axis ) + if ( num_coords > mmvar->num_axis ) { - error = FT_THROW( Invalid_Argument ); - goto Exit; + FT_TRACE2(( "TT_Set_MM_Blend: only using first %d of %d coordinates\n", + mmvar->num_axis, num_coords )); + num_coords = mmvar->num_axis; } - for ( i = 0; i < num_coords; ++i ) + FT_TRACE5(( "normalized design coordinates:\n" )); + + for ( i = 0; i < num_coords; i++ ) + { + FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 )); if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) { + FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.4f\n" + " is out of range [-1;1]\n", + coords[i] / 65536.0 )); error = FT_THROW( Invalid_Argument ); goto Exit; } + } + + FT_TRACE5(( "\n" )); if ( blend->glyphoffsets == NULL ) - if ( (error = ft_var_load_gvar( face )) != 0 ) + if ( ( error = ft_var_load_gvar( face ) ) != 0 ) goto Exit; if ( blend->normalizedcoords == NULL ) { - if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) ) + if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) ) goto Exit; manageCvt = mcvt_modify; @@ -906,7 +1114,8 @@ else { manageCvt = mcvt_retain; - for ( i = 0; i < num_coords; ++i ) + + for ( i = 0; i < num_coords; i++ ) { if ( blend->normalizedcoords[i] != coords[i] ) { @@ -915,13 +1124,22 @@ } } + for ( ; i < mmvar->num_axis; i++ ) + { + if ( blend->normalizedcoords[i] != 0 ) + { + manageCvt = mcvt_load; + break; + } + } + /* If we don't change the blend coords then we don't need to do */ /* anything to the cvt table. It will be correct. Otherwise we */ /* no longer have the original cvt (it was modified when we set */ /* the blend last time), so we must reload and then modify it. */ } - blend->num_axis = num_coords; + blend->num_axis = mmvar->num_axis; FT_MEM_COPY( blend->normalizedcoords, coords, num_coords * sizeof ( FT_Fixed ) ); @@ -938,13 +1156,13 @@ FT_FREE( face->cvt ); face->cvt = NULL; - tt_face_load_cvt( face, face->root.stream ); + error = tt_face_load_cvt( face, face->root.stream ); break; case mcvt_modify: /* The original cvt table is in memory. All we need to do is */ /* apply the `cvar' table (if any). */ - tt_face_vary_cvt( face, face->root.stream ); + error = tt_face_vary_cvt( face, face->root.stream ); break; case mcvt_retain: @@ -973,7 +1191,10 @@ /* Initialize the blend struct with `gvar' data. */ /* */ /* <Input> */ - /* num_coords :: This must be the axis count of the font. */ + /* num_coords :: The number of available coordinates. If it is */ + /* larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use the default values for the remaining axes. */ /* */ /* coords :: A coordinate array with `num_coords' elements. */ /* */ @@ -997,17 +1218,19 @@ if ( face->blend == NULL ) { - if ( (error = TT_Get_MM_Var( face, NULL )) != 0 ) + if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) goto Exit; } blend = face->blend; mmvar = blend->mmvar; - if ( num_coords != mmvar->num_axis ) + if ( num_coords > mmvar->num_axis ) { - error = FT_THROW( Invalid_Argument ); - goto Exit; + FT_TRACE2(( "TT_Set_Var_Design:" + " only using first %d of %d coordinates\n", + mmvar->num_axis, num_coords )); + num_coords = mmvar->num_axis; } /* Axis normalization is a two stage process. First we normalize */ @@ -1017,32 +1240,52 @@ if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) goto Exit; + FT_TRACE5(( "design coordinates:\n" )); + a = mmvar->axis; - for ( i = 0; i < mmvar->num_axis; ++i, ++a ) + for ( i = 0; i < num_coords; i++, a++ ) { + FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 )); if ( coords[i] > a->maximum || coords[i] < a->minimum ) { + FT_TRACE1(( "TT_Set_Var_Design: normalized design coordinate %.4f\n" + " is out of range [%.4f;%.4f]\n", + coords[i] / 65536.0, + a->minimum / 65536.0, + a->maximum / 65536.0 )); error = FT_THROW( Invalid_Argument ); goto Exit; } if ( coords[i] < a->def ) - normalized[i] = -FT_DivFix( coords[i] - a->def, a->minimum - a->def ); + normalized[i] = -FT_DivFix( coords[i] - a->def, + a->minimum - a->def ); else if ( a->maximum == a->def ) normalized[i] = 0; else - normalized[i] = FT_DivFix( coords[i] - a->def, a->maximum - a->def ); + normalized[i] = FT_DivFix( coords[i] - a->def, + a->maximum - a->def ); } + FT_TRACE5(( "\n" )); + + for ( ; i < mmvar->num_axis; i++ ) + normalized[i] = 0; + if ( !blend->avar_checked ) ft_var_load_avar( face ); if ( blend->avar_segment != NULL ) { + FT_TRACE5(( "normalized design coordinates" + " before applying `avar' data:\n" )); + av = blend->avar_segment; - for ( i = 0; i < mmvar->num_axis; ++i, ++av ) + for ( i = 0; i < mmvar->num_axis; i++, av++ ) { - for ( j = 1; j < (FT_UInt)av->pairCount; ++j ) + for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) + { + FT_TRACE5(( " %.4f\n", normalized[i] / 65536.0 )); if ( normalized[i] < av->correspondence[j].fromCoord ) { normalized[i] = @@ -1054,10 +1297,11 @@ av->correspondence[j - 1].toCoord; break; } + } } } - error = TT_Set_MM_Blend( face, num_coords, normalized ); + error = TT_Set_MM_Blend( face, mmvar->num_axis, normalized ); Exit: FT_FREE( normalized ); @@ -1120,16 +1364,16 @@ if ( blend == NULL ) { - FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); - + FT_TRACE2(( "\n" + "tt_face_vary_cvt: no blend specified\n" )); error = FT_Err_Ok; goto Exit; } if ( face->cvt == NULL ) { - FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); - + FT_TRACE2(( "\n" + "tt_face_vary_cvt: no `cvt ' table\n" )); error = FT_Err_Ok; goto Exit; } @@ -1158,25 +1402,43 @@ goto FExit; } + FT_TRACE2(( "loaded\n" )); + if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) goto FExit; tupleCount = FT_GET_USHORT(); - offsetToData = table_start + FT_GET_USHORT(); + offsetToData = FT_GET_USHORT(); + + /* rough sanity test */ + if ( offsetToData + tupleCount * 4 > table_len ) + { + FT_TRACE2(( "tt_face_vary_cvt:" + " invalid CVT variation array header\n" )); + + error = FT_THROW( Invalid_Table ); + goto FExit; + } - /* The documentation implies there are flags packed into the */ - /* tuplecount, but John Jenkins says that shared points don't apply */ - /* to `cvar', and no other flags are defined. */ + offsetToData += table_start; - for ( i = 0; i < ( tupleCount & 0xFFF ); ++i ) + /* The documentation implies there are flags packed into */ + /* `tupleCount', but John Jenkins says that shared points don't apply */ + /* to `cvar', and no other flags are defined. */ + + FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount & 0xFFF )); + + for ( i = 0; i < ( tupleCount & 0xFFF ); i++ ) { FT_UInt tupleDataSize; FT_UInt tupleIndex; FT_Fixed apply; + FT_TRACE6(( " tuple %d:\n", i )); + tupleDataSize = FT_GET_USHORT(); tupleIndex = FT_GET_USHORT(); @@ -1185,8 +1447,8 @@ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { - for ( j = 0; j < blend->num_axis; ++j ) - tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ + for ( j = 0; j < blend->num_axis; j++ ) + tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ /* short frac to fixed */ } else @@ -1194,7 +1456,7 @@ /* skip this tuple; it makes no sense */ if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) - for ( j = 0; j < 2 * blend->num_axis; ++j ) + for ( j = 0; j < 2 * blend->num_axis; j++ ) (void)FT_GET_SHORT(); offsetToData += tupleDataSize; @@ -1203,10 +1465,10 @@ if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { - for ( j = 0; j < blend->num_axis; ++j ) - im_start_coords[j] = FT_GET_SHORT() << 2; - for ( j = 0; j < blend->num_axis; ++j ) - im_end_coords[j] = FT_GET_SHORT() << 2; + for ( j = 0; j < blend->num_axis; j++ ) + im_start_coords[j] = FT_GET_SHORT() * 4; + for ( j = 0; j < blend->num_axis; j++ ) + im_end_coords[j] = FT_GET_SHORT() * 4; } apply = ft_var_apply_tuple( blend, @@ -1228,30 +1490,82 @@ FT_Stream_SeekSet( stream, offsetToData ); - localpoints = ft_var_readpackedpoints( stream, &point_count ); + localpoints = ft_var_readpackedpoints( stream, + table_len, + &point_count ); deltas = ft_var_readpackeddeltas( stream, + table_len, point_count == 0 ? face->cvt_size : point_count ); if ( localpoints == NULL || deltas == NULL ) - /* failure, ignore it */; + ; /* failure, ignore it */ else if ( localpoints == ALL_POINTS ) { +#ifdef FT_DEBUG_LEVEL_TRACE + int count = 0; +#endif + + + FT_TRACE7(( " CVT deltas:\n" )); + /* this means that there are deltas for every entry in cvt */ - for ( j = 0; j < face->cvt_size; ++j ) - face->cvt[j] = (FT_Short)( face->cvt[j] + + for ( j = 0; j < face->cvt_size; j++ ) + { + FT_Long orig_cvt = face->cvt[j]; + + + face->cvt[j] = (FT_Short)( orig_cvt + FT_MulFix( deltas[j], apply ) ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( orig_cvt != face->cvt[j] ) + { + FT_TRACE7(( " %d: %d -> %d\n", + j, orig_cvt, face->cvt[j] )); + count++; + } +#endif + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE7(( " none\n" )); +#endif } else { - for ( j = 0; j < point_count; ++j ) +#ifdef FT_DEBUG_LEVEL_TRACE + int count = 0; +#endif + + + FT_TRACE7(( " CVT deltas:\n" )); + + for ( j = 0; j < point_count; j++ ) { - int pindex = localpoints[j]; + int pindex = localpoints[j]; + FT_Long orig_cvt = face->cvt[pindex]; + - face->cvt[pindex] = (FT_Short)( face->cvt[pindex] + + face->cvt[pindex] = (FT_Short)( orig_cvt + FT_MulFix( deltas[j], apply ) ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( orig_cvt != face->cvt[pindex] ) + { + FT_TRACE7(( " %d: %d -> %d\n", + pindex, orig_cvt, face->cvt[pindex] )); + count++; + } +#endif } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE7(( " none\n" )); +#endif } if ( localpoints != ALL_POINTS ) @@ -1263,6 +1577,8 @@ FT_Stream_SeekSet( stream, here ); } + FT_TRACE5(( "\n" )); + FExit: FT_FRAME_EXIT(); @@ -1275,13 +1591,230 @@ } + /* Shift the original coordinates of all points between indices `p1' */ + /* and `p2', using the same difference as given by index `ref'. */ + + /* modeled after `af_iup_shift' */ + + static void + tt_delta_shift( int p1, + int p2, + int ref, + FT_Vector* in_points, + FT_Vector* out_points ) + { + int p; + FT_Vector delta; + + + delta.x = out_points[ref].x - in_points[ref].x; + delta.y = out_points[ref].y - in_points[ref].y; + + if ( delta.x == 0 && delta.y == 0 ) + return; + + for ( p = p1; p < ref; p++ ) + { + out_points[p].x += delta.x; + out_points[p].y += delta.y; + } + + for ( p = ref + 1; p <= p2; p++ ) + { + out_points[p].x += delta.x; + out_points[p].y += delta.y; + } + } + + + /* Interpolate the original coordinates of all points with indices */ + /* between `p1' and `p2', using `ref1' and `ref2' as the reference */ + /* point indices. */ + + /* modeled after `af_iup_interp', `_iup_worker_interpolate', and */ + /* `Ins_IUP' */ + + static void + tt_delta_interpolate( int p1, + int p2, + int ref1, + int ref2, + FT_Vector* in_points, + FT_Vector* out_points ) + { + int p, i; + + FT_Pos out, in1, in2, out1, out2, d1, d2; + + + if ( p1 > p2 ) + return; + + /* handle both horizontal and vertical coordinates */ + for ( i = 0; i <= 1; i++ ) + { + /* shift array pointers so that we can access `foo.y' as `foo.x' */ + in_points = (FT_Vector*)( (FT_Pos*)in_points + i ); + out_points = (FT_Vector*)( (FT_Pos*)out_points + i ); + + if ( in_points[ref1].x > in_points[ref2].x ) + { + p = ref1; + ref1 = ref2; + ref2 = p; + } + + in1 = in_points[ref1].x; + in2 = in_points[ref2].x; + out1 = out_points[ref1].x; + out2 = out_points[ref2].x; + d1 = out1 - in1; + d2 = out2 - in2; + + if ( out1 == out2 || in1 == in2 ) + { + for ( p = p1; p <= p2; p++ ) + { + out = in_points[p].x; + + if ( out <= in1 ) + out += d1; + else if ( out >= in2 ) + out += d2; + else + out = out1; + + out_points[p].x = out; + } + } + else + { + FT_Fixed scale = FT_DivFix( out2 - out1, in2 - in1 ); + + + for ( p = p1; p <= p2; p++ ) + { + out = in_points[p].x; + + if ( out <= in1 ) + out += d1; + else if ( out >= in2 ) + out += d2; + else + out = out1 + FT_MulFix( out - in1, scale ); + + out_points[p].x = out; + } + } + } + } + + + /* Interpolate points without delta values, similar to */ + /* the `IUP' hinting instruction. */ + + /* modeled after `Ins_IUP */ + + static void + tt_handle_deltas( FT_Outline* outline, + FT_Vector* in_points, + FT_Bool* has_delta ) + { + FT_Vector* out_points; + + FT_Int first_point; + FT_Int end_point; + + FT_Int first_delta; + FT_Int cur_delta; + + FT_Int point; + FT_Short contour; + + + /* ignore empty outlines */ + if ( !outline->n_contours ) + return; + + out_points = outline->points; + + contour = 0; + point = 0; + + do + { + end_point = outline->contours[contour]; + first_point = point; + + /* search first point that has a delta */ + while ( point <= end_point && !has_delta[point] ) + point++; + + if ( point <= end_point ) + { + first_delta = point; + cur_delta = point; + + point++; + + while ( point <= end_point ) + { + /* search next point that has a delta */ + /* and interpolate intermediate points */ + if ( has_delta[point] ) + { + tt_delta_interpolate( cur_delta + 1, + point - 1, + cur_delta, + point, + in_points, + out_points ); + cur_delta = point; + } + + point++; + } + + /* shift contour if we only have a single delta */ + if ( cur_delta == first_delta ) + tt_delta_shift( first_point, + end_point, + cur_delta, + in_points, + out_points ); + else + { + /* otherwise handle remaining points */ + /* at the end and beginning of the contour */ + tt_delta_interpolate( cur_delta + 1, + end_point, + cur_delta, + first_delta, + in_points, + out_points ); + + if ( first_delta > 0 ) + tt_delta_interpolate( first_point, + first_delta - 1, + cur_delta, + first_delta, + in_points, + out_points ); + } + } + contour++; + + } while ( contour < outline->n_contours ); + } + + /*************************************************************************/ /* */ /* <Function> */ - /* TT_Vary_Get_Glyph_Deltas */ + /* TT_Vary_Apply_Glyph_Deltas */ /* */ /* <Description> */ - /* Load the appropriate deltas for the current glyph. */ + /* Apply the appropriate deltas to the current glyph. */ /* */ /* <Input> */ /* face :: A handle to the target face object. */ @@ -1291,22 +1824,24 @@ /* n_points :: The number of the points in the glyph, including */ /* phantom points. */ /* */ - /* <Output> */ - /* deltas :: The array of points to change. */ + /* <InOut> */ + /* outline :: The outline to change. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) - TT_Vary_Get_Glyph_Deltas( TT_Face face, - FT_UInt glyph_index, - FT_Vector* *deltas, - FT_UInt n_points ) + TT_Vary_Apply_Glyph_Deltas( TT_Face face, + FT_UInt glyph_index, + FT_Outline* outline, + FT_UInt n_points ) { FT_Stream stream = face->root.stream; FT_Memory memory = stream->memory; GX_Blend blend = face->blend; - FT_Vector* delta_xy = NULL; + + FT_Vector* points_org = NULL; + FT_Bool* has_delta = NULL; FT_Error error; FT_ULong glyph_start; @@ -1327,15 +1862,18 @@ if ( !face->doblend || blend == NULL ) return FT_THROW( Invalid_Argument ); - /* to be freed by the caller */ - if ( FT_NEW_ARRAY( delta_xy, n_points ) ) - goto Exit; - *deltas = delta_xy; - if ( glyph_index >= blend->gv_glyphcnt || blend->glyphoffsets[glyph_index] == blend->glyphoffsets[glyph_index + 1] ) - return FT_Err_Ok; /* no variation data for this glyph */ + { + FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" + " no variation data for this glyph\n" )); + return FT_Err_Ok; + } + + if ( FT_NEW_ARRAY( points_org, n_points ) || + FT_NEW_ARRAY( has_delta, n_points ) ) + goto Fail1; if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - @@ -1353,7 +1891,19 @@ goto Fail2; tupleCount = FT_GET_USHORT(); - offsetToData = glyph_start + FT_GET_USHORT(); + offsetToData = FT_GET_USHORT(); + + /* rough sanity test */ + if ( offsetToData + tupleCount * 4 > blend->gvar_size ) + { + FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" + " invalid glyph variation array header\n" )); + + error = FT_THROW( Invalid_Table ); + goto Fail2; + } + + offsetToData += glyph_start; if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) { @@ -1361,47 +1911,55 @@ FT_Stream_SeekSet( stream, offsetToData ); - sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); + sharedpoints = ft_var_readpackedpoints( stream, + blend->gvar_size, + &spoint_count ); offsetToData = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, here ); } - for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); ++i ) + FT_TRACE5(( "gvar: there are %d tuples:\n", + tupleCount & GX_TC_TUPLE_COUNT_MASK )); + + for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ ) { FT_UInt tupleDataSize; FT_UInt tupleIndex; FT_Fixed apply; + FT_TRACE6(( " tuple %d:\n", i )); + tupleDataSize = FT_GET_USHORT(); tupleIndex = FT_GET_USHORT(); if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { - for ( j = 0; j < blend->num_axis; ++j ) - tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ + for ( j = 0; j < blend->num_axis; j++ ) + tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ /* short frac to fixed */ } else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) { + FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" + " invalid tuple index\n" )); + error = FT_THROW( Invalid_Table ); - goto Fail3; + goto Fail2; } else - { FT_MEM_COPY( tuple_coords, - &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis], + &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis], blend->num_axis * sizeof ( FT_Fixed ) ); - } if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { - for ( j = 0; j < blend->num_axis; ++j ) - im_start_coords[j] = FT_GET_SHORT() << 2; - for ( j = 0; j < blend->num_axis; ++j ) - im_end_coords[j] = FT_GET_SHORT() << 2; + for ( j = 0; j < blend->num_axis; j++ ) + im_start_coords[j] = FT_GET_SHORT() * 4; + for ( j = 0; j < blend->num_axis; j++ ) + im_end_coords[j] = FT_GET_SHORT() * 4; } apply = ft_var_apply_tuple( blend, @@ -1422,7 +1980,9 @@ { FT_Stream_SeekSet( stream, offsetToData ); - localpoints = ft_var_readpackedpoints( stream, &point_count ); + localpoints = ft_var_readpackedpoints( stream, + blend->gvar_size, + &point_count ); points = localpoints; } else @@ -1432,9 +1992,11 @@ } deltas_x = ft_var_readpackeddeltas( stream, + blend->gvar_size, point_count == 0 ? n_points : point_count ); deltas_y = ft_var_readpackeddeltas( stream, + blend->gvar_size, point_count == 0 ? n_points : point_count ); @@ -1443,24 +2005,104 @@ else if ( points == ALL_POINTS ) { +#ifdef FT_DEBUG_LEVEL_TRACE + int count = 0; +#endif + + + FT_TRACE7(( " point deltas:\n" )); + /* this means that there are deltas for every point in the glyph */ - for ( j = 0; j < n_points; ++j ) + for ( j = 0; j < n_points; j++ ) { - delta_xy[j].x += FT_MulFix( deltas_x[j], apply ); - delta_xy[j].y += FT_MulFix( deltas_y[j], apply ); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Vector point_org = outline->points[j]; +#endif + + + outline->points[j].x += FT_MulFix( deltas_x[j], apply ); + outline->points[j].y += FT_MulFix( deltas_y[j], apply ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( ( point_org.x != outline->points[j].x ) || + ( point_org.y != outline->points[j].y ) ) + { + FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", + j, + point_org.x, + point_org.y, + outline->points[j].x, + outline->points[j].y )); + count++; + } +#endif } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE7(( " none\n" )); +#endif } + else if ( localpoints == NULL ) + ; /* failure, ignore it */ + else { - for ( j = 0; j < point_count; ++j ) +#ifdef FT_DEBUG_LEVEL_TRACE + int count = 0; +#endif + + + /* we have to interpolate the missing deltas similar to the */ + /* IUP bytecode instruction */ + for ( j = 0; j < n_points; j++ ) + { + points_org[j] = outline->points[j]; + has_delta[j] = FALSE; + } + + for ( j = 0; j < point_count; j++ ) { - if ( localpoints[j] >= n_points ) + FT_UShort idx = localpoints[j]; + + + if ( idx >= n_points ) continue; - delta_xy[localpoints[j]].x += FT_MulFix( deltas_x[j], apply ); - delta_xy[localpoints[j]].y += FT_MulFix( deltas_y[j], apply ); + has_delta[idx] = TRUE; + + outline->points[idx].x += FT_MulFix( deltas_x[j], apply ); + outline->points[idx].y += FT_MulFix( deltas_y[j], apply ); } + + /* no need to handle phantom points here, */ + /* since solitary points can't be interpolated */ + tt_handle_deltas( outline, + points_org, + has_delta ); + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE7(( " point deltas:\n" )); + + for ( j = 0; j < n_points; j++) + { + if ( ( points_org[j].x != outline->points[j].x ) || + ( points_org[j].y != outline->points[j].y ) ) + { + FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", + j, + points_org[j].x, + points_org[j].y, + outline->points[j].x, + outline->points[j].y )); + count++; + } + } + + if ( !count ) + FT_TRACE7(( " none\n" )); +#endif } if ( localpoints != ALL_POINTS ) @@ -1473,22 +2115,21 @@ FT_Stream_SeekSet( stream, here ); } - Fail3: + FT_TRACE5(( "\n" )); + + Fail2: + if ( sharedpoints != ALL_POINTS ) + FT_FREE( sharedpoints ); FT_FREE( tuple_coords ); FT_FREE( im_start_coords ); FT_FREE( im_end_coords ); - Fail2: FT_FRAME_EXIT(); Fail1: - if ( error ) - { - FT_FREE( delta_xy ); - *deltas = NULL; - } + FT_FREE( points_org ); + FT_FREE( has_delta ); - Exit: return error; } @@ -1499,7 +2140,7 @@ /* tt_done_blend */ /* */ /* <Description> */ - /* Frees the blend internal data structure. */ + /* Free the blend internal data structure. */ /* */ FT_LOCAL_DEF( void ) tt_done_blend( FT_Memory memory, @@ -1515,7 +2156,7 @@ if ( blend->avar_segment != NULL ) { - for ( i = 0; i < blend->num_axis; ++i ) + for ( i = 0; i < blend->num_axis; i++ ) FT_FREE( blend->avar_segment[i].correspondence ); FT_FREE( blend->avar_segment ); } diff --git a/drivers/freetype/freetype/src/truetype/ttgxvar.h b/drivers/freetype/src/truetype/ttgxvar.h index 82dfc4431f..aa8f6ea592 100644 --- a/drivers/freetype/freetype/src/truetype/ttgxvar.h +++ b/drivers/freetype/src/truetype/ttgxvar.h @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader (specification) */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004-2016 by */ /* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTGXVAR_H__ -#define __TTGXVAR_H__ +#ifndef TTGXVAR_H_ +#define TTGXVAR_H_ #include <ft2build.h> @@ -95,6 +95,8 @@ FT_BEGIN_HEADER FT_UInt gv_glyphcnt; FT_ULong* glyphoffsets; + FT_ULong gvar_size; + } GX_BlendRec; @@ -162,10 +164,10 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - TT_Vary_Get_Glyph_Deltas( TT_Face face, - FT_UInt glyph_index, - FT_Vector* *deltas, - FT_UInt n_points ); + TT_Vary_Apply_Glyph_Deltas( TT_Face face, + FT_UInt glyph_index, + FT_Outline* outline, + FT_UInt n_points ); FT_LOCAL( void ) @@ -176,7 +178,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTGXVAR_H__ */ +#endif /* TTGXVAR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttinterp.c b/drivers/freetype/src/truetype/ttinterp.c index e7ffb987ce..8fe83c5ea8 100644 --- a/drivers/freetype/freetype/src/truetype/ttinterp.c +++ b/drivers/freetype/src/truetype/ttinterp.c @@ -4,8 +4,8 @@ /* */ /* TrueType bytecode interpreter (body). */ /* */ -/* Copyright 1996-2013 */ -/* by David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* Copyright 1996-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -44,186 +44,34 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_ttinterp - /*************************************************************************/ - /* */ - /* In order to detect infinite loops in the code, we set up a counter */ - /* within the run loop. A single stroke of interpretation is now */ - /* limited to a maximum number of opcodes defined below. */ - /* */ -#define MAX_RUNNABLE_OPCODES 1000000L - - - /*************************************************************************/ - /* */ - /* There are two kinds of implementations: */ - /* */ - /* a. static implementation */ - /* */ - /* The current execution context is a static variable, which fields */ - /* are accessed directly by the interpreter during execution. The */ - /* context is named `cur'. */ - /* */ - /* This version is non-reentrant, of course. */ - /* */ - /* b. indirect implementation */ - /* */ - /* The current execution context is passed to _each_ function as its */ - /* first argument, and each field is thus accessed indirectly. */ - /* */ - /* This version is fully re-entrant. */ - /* */ - /* The idea is that an indirect implementation may be slower to execute */ - /* on low-end processors that are used in some systems (like 386s or */ - /* even 486s). */ - /* */ - /* As a consequence, the indirect implementation is now the default, as */ - /* its performance costs can be considered negligible in our context. */ - /* Note, however, that we kept the same source with macros because: */ - /* */ - /* - The code is kept very close in design to the Pascal code used for */ - /* development. */ - /* */ - /* - It's much more readable that way! */ - /* */ - /* - It's still open to experimentation and tuning. */ - /* */ - /*************************************************************************/ - - -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ - -#define CUR (*exc) /* see ttobjs.h */ - - /*************************************************************************/ - /* */ - /* This macro is used whenever `exec' is unused in a function, to avoid */ - /* stupid warnings from pedantic compilers. */ - /* */ -#define FT_UNUSED_EXEC FT_UNUSED( exc ) - -#else /* static implementation */ - -#define CUR cur - -#define FT_UNUSED_EXEC int __dummy = __dummy - - static - TT_ExecContextRec cur; /* static exec. context variable */ - /* apparently, we have a _lot_ of direct indexing when accessing */ - /* the static `cur', which makes the code bigger (due to all the */ - /* four bytes addresses). */ - -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ - - - /*************************************************************************/ - /* */ - /* The instruction argument stack. */ - /* */ -#define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */ +#define NO_SUBPIXEL_HINTING \ + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ + TT_INTERPRETER_VERSION_35 ) - - /*************************************************************************/ - /* */ - /* This macro is used whenever `args' is unused in a function, to avoid */ - /* stupid warnings from pedantic compilers. */ - /* */ -#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) - - -#define SUBPIXEL_HINTING \ - ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY +#define SUBPIXEL_HINTING_INFINALITY \ + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ TT_INTERPRETER_VERSION_38 ) +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL +#define SUBPIXEL_HINTING_MINIMAL \ + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ + TT_INTERPRETER_VERSION_40 ) +#endif - /*************************************************************************/ - /* */ - /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ - /* increase readability of the code. */ - /* */ - /*************************************************************************/ - - -#define SKIP_Code() \ - SkipCode( EXEC_ARG ) - -#define GET_ShortIns() \ - GetShortIns( EXEC_ARG ) - -#define NORMalize( x, y, v ) \ - Normalize( EXEC_ARG_ x, y, v ) - -#define SET_SuperRound( scale, flags ) \ - SetSuperRound( EXEC_ARG_ scale, flags ) - -#define ROUND_None( d, c ) \ - Round_None( EXEC_ARG_ d, c ) - -#define INS_Goto_CodeRange( range, ip ) \ - Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) - -#define CUR_Func_move( z, p, d ) \ - CUR.func_move( EXEC_ARG_ z, p, d ) - -#define CUR_Func_move_orig( z, p, d ) \ - CUR.func_move_orig( EXEC_ARG_ z, p, d ) - -#define CUR_Func_round( d, c ) \ - CUR.func_round( EXEC_ARG_ d, c ) - -#define CUR_Func_read_cvt( index ) \ - CUR.func_read_cvt( EXEC_ARG_ index ) - -#define CUR_Func_write_cvt( index, val ) \ - CUR.func_write_cvt( EXEC_ARG_ index, val ) - -#define CUR_Func_move_cvt( index, val ) \ - CUR.func_move_cvt( EXEC_ARG_ index, val ) - -#define CURRENT_Ratio() \ - Current_Ratio( EXEC_ARG ) - -#define CURRENT_Ppem() \ - Current_Ppem( EXEC_ARG ) - -#define CUR_Ppem() \ - Cur_PPEM( EXEC_ARG ) - -#define INS_SxVTL( a, b, c, d ) \ - Ins_SxVTL( EXEC_ARG_ a, b, c, d ) - -#define COMPUTE_Funcs() \ - Compute_Funcs( EXEC_ARG ) - -#define COMPUTE_Round( a ) \ - Compute_Round( EXEC_ARG_ a ) - -#define COMPUTE_Point_Displacement( a, b, c, d ) \ - Compute_Point_Displacement( EXEC_ARG_ a, b, c, d ) - -#define MOVE_Zp2_Point( a, b, c, t ) \ - Move_Zp2_Point( EXEC_ARG_ a, b, c, t ) - - -#define CUR_Func_project( v1, v2 ) \ - CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y ) +#define PROJECT( v1, v2 ) \ + exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) -#define CUR_Func_dualproj( v1, v2 ) \ - CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y ) +#define DUALPROJ( v1, v2 ) \ + exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) -#define CUR_fast_project( v ) \ - CUR.func_project( EXEC_ARG_ (v)->x, (v)->y ) +#define FAST_PROJECT( v ) \ + exc->func_project( exc, (v)->x, (v)->y ) -#define CUR_fast_dualproj( v ) \ - CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y ) - - - /*************************************************************************/ - /* */ - /* Instruction dispatch function, as used by the interpreter. */ - /* */ - typedef void (*TInstruction_Function)( INS_ARG ); +#define FAST_DUALPROJ( v ) \ + exc->func_dualproj( exc, (v)->x, (v)->y ) /*************************************************************************/ @@ -233,13 +81,6 @@ #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) - /*************************************************************************/ - /* */ - /* This macro computes (a*2^14)/b and complements TT_MulFix14. */ - /* */ -#define TT_DivFix14( a, b ) \ - FT_DivFix( a, (b) << 2 ) - #undef SUCCESS #define SUCCESS 0 @@ -247,16 +88,6 @@ #undef FAILURE #define FAILURE 1 -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define GUESS_VECTOR( V ) \ - if ( CUR.face->unpatented_hinting ) \ - { \ - CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \ - CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \ - } -#else -#define GUESS_VECTOR( V ) -#endif /*************************************************************************/ /* */ @@ -282,10 +113,7 @@ /* <InOut> */ /* exec :: The target execution context. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) TT_Goto_CodeRange( TT_ExecContext exec, FT_Int range, FT_Long IP ) @@ -303,14 +131,12 @@ /* which will return to the first byte *after* the code */ /* range, we test for IP <= Size instead of IP < Size. */ /* */ - FT_ASSERT( (FT_ULong)IP <= coderange->size ); + FT_ASSERT( IP <= coderange->size ); exec->code = coderange->base; exec->codeSize = coderange->size; exec->IP = IP; exec->curRange = range; - - return FT_Err_Ok; } @@ -332,10 +158,7 @@ /* <InOut> */ /* exec :: The target execution context. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) TT_Set_CodeRange( TT_ExecContext exec, FT_Int range, void* base, @@ -345,8 +168,6 @@ exec->codeRangeTable[range - 1].base = (FT_Byte*)base; exec->codeRangeTable[range - 1].size = length; - - return FT_Err_Ok; } @@ -364,13 +185,7 @@ /* <InOut> */ /* exec :: The target execution context. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Does not set the Error variable. */ - /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) TT_Clear_CodeRange( TT_ExecContext exec, FT_Int range ) { @@ -378,8 +193,6 @@ exec->codeRangeTable[range - 1].base = NULL; exec->codeRangeTable[range - 1].size = 0; - - return FT_Err_Ok; } @@ -403,13 +216,10 @@ /* */ /* memory :: A handle to the parent memory object. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ /* <Note> */ /* Only the glyph loader and debugger should call this function. */ /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) TT_Done_Context( TT_ExecContext exec ) { FT_Memory memory = exec->memory; @@ -436,8 +246,6 @@ exec->face = NULL; FT_FREE( exec ); - - return FT_Err_Ok; } @@ -481,8 +289,8 @@ exec->stackSize = 0; exec->glyphSize = 0; - exec->stack = NULL; - exec->glyphIns = NULL; + exec->stack = NULL; + exec->glyphIns = NULL; exec->face = NULL; exec->size = NULL; @@ -524,7 +332,7 @@ FT_LOCAL_DEF( FT_Error ) Update_Max( FT_Memory memory, FT_ULong* size, - FT_Long multiplier, + FT_ULong multiplier, void* _pbuff, FT_ULong new_max ) { @@ -617,13 +425,13 @@ /* XXX: We reserve a little more elements on the stack to deal safely */ /* with broken fonts like arialbs, courbs, timesbs, etc. */ - tmp = exec->stackSize; + tmp = (FT_ULong)exec->stackSize; error = Update_Max( exec->memory, &tmp, sizeof ( FT_F26Dot6 ), (void*)&exec->stack, maxp->maxStackElements + 32 ); - exec->stackSize = (FT_UInt)tmp; + exec->stackSize = (FT_Long)tmp; if ( error ) return error; @@ -664,13 +472,10 @@ /* <InOut> */ /* size :: A handle to the target size object. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ /* <Note> */ /* Only the glyph loader and debugger should call this function. */ /* */ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) TT_Save_Context( TT_ExecContext exec, TT_Size size ) { @@ -688,8 +493,6 @@ for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) size->codeRangeTable[i] = exec->codeRangeTable[i]; - - return FT_Err_Ok; } @@ -714,19 +517,10 @@ /* <Return> */ /* TrueType error code. 0 means success. */ /* */ - /* <Note> */ - /* Only the glyph loader and debugger should call this function. */ - /* */ FT_LOCAL_DEF( FT_Error ) - TT_Run_Context( TT_ExecContext exec, - FT_Bool debug ) + TT_Run_Context( TT_ExecContext exec ) { - FT_Error error; - - - if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) ) - != FT_Err_Ok ) - return error; + TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ); exec->zp0 = exec->pts; exec->zp1 = exec->pts; @@ -742,10 +536,6 @@ exec->GS.freeVector = exec->GS.projVector; exec->GS.dualVector = exec->GS.projVector; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - exec->GS.both_x_axis = TRUE; -#endif - exec->GS.round_state = 1; exec->GS.loop = 1; @@ -754,16 +544,7 @@ exec->top = 0; exec->callTop = 0; -#if 1 - FT_UNUSED( debug ); - return exec->face->interpreter( exec ); -#else - if ( !debug ) - return TT_RunIns( exec ); - else - return FT_Err_Ok; -#endif } @@ -781,10 +562,6 @@ { 0x4000, 0 }, { 0x4000, 0 }, -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - TRUE, -#endif - 1, 64, 1, TRUE, 68, 0, 0, 9, 3, 0, FALSE, 0, 1, 1, 1 @@ -796,32 +573,27 @@ FT_EXPORT_DEF( TT_ExecContext ) TT_New_Context( TT_Driver driver ) { - TT_ExecContext exec; - FT_Memory memory; - + FT_Memory memory; + FT_Error error; - memory = driver->root.root.memory; - exec = driver->context; + TT_ExecContext exec = NULL; - if ( !driver->context ) - { - FT_Error error; + if ( !driver ) + goto Fail; - /* allocate object */ - if ( FT_NEW( exec ) ) - goto Fail; + memory = driver->root.root.memory; - /* initialize it; in case of error this deallocates `exec' too */ - error = Init_Context( exec, memory ); - if ( error ) - goto Fail; + /* allocate object */ + if ( FT_NEW( exec ) ) + goto Fail; - /* store it into the driver */ - driver->context = exec; - } + /* initialize it; in case of error this deallocates `exec' too */ + error = Init_Context( exec, memory ); + if ( error ) + goto Fail; - return driver->context; + return exec; Fail: return NULL; @@ -868,8 +640,8 @@ /* SFvTL + */ PACK( 2, 0 ), /* SPvFS */ PACK( 2, 0 ), /* SFvFS */ PACK( 2, 0 ), - /* GPV */ PACK( 0, 2 ), - /* GFV */ PACK( 0, 2 ), + /* GPv */ PACK( 0, 2 ), + /* GFv */ PACK( 0, 2 ), /* SFvTPv */ PACK( 0, 0 ), /* ISECT */ PACK( 5, 0 ), @@ -998,8 +770,8 @@ /* INS_$83 */ PACK( 0, 0 ), /* INS_$84 */ PACK( 0, 0 ), /* ScanCTRL */ PACK( 1, 0 ), - /* SDPVTL[0] */ PACK( 2, 0 ), - /* SDPVTL[1] */ PACK( 2, 0 ), + /* SDPvTL[0] */ PACK( 2, 0 ), + /* SDPvTL[1] */ PACK( 2, 0 ), /* GetINFO */ PACK( 1, 1 ), /* IDEF */ PACK( 1, 0 ), /* ROLL */ PACK( 3, 3 ), @@ -1132,280 +904,284 @@ #ifdef FT_DEBUG_LEVEL_TRACE + /* the first hex digit gives the length of the opcode name; the space */ + /* after the digit is here just to increase readability of the source */ + /* code */ + static const char* const opcode_name[256] = { - "SVTCA y", - "SVTCA x", - "SPvTCA y", - "SPvTCA x", - "SFvTCA y", - "SFvTCA x", - "SPvTL ||", - "SPvTL +", - "SFvTL ||", - "SFvTL +", - "SPvFS", - "SFvFS", - "GPV", - "GFV", - "SFvTPv", - "ISECT", - - "SRP0", - "SRP1", - "SRP2", - "SZP0", - "SZP1", - "SZP2", - "SZPS", - "SLOOP", - "RTG", - "RTHG", - "SMD", - "ELSE", - "JMPR", - "SCvTCi", - "SSwCi", - "SSW", - - "DUP", - "POP", - "CLEAR", - "SWAP", - "DEPTH", - "CINDEX", - "MINDEX", - "AlignPTS", - "INS_$28", - "UTP", - "LOOPCALL", - "CALL", - "FDEF", - "ENDF", - "MDAP[0]", - "MDAP[1]", - - "IUP[0]", - "IUP[1]", - "SHP[0]", - "SHP[1]", - "SHC[0]", - "SHC[1]", - "SHZ[0]", - "SHZ[1]", - "SHPIX", - "IP", - "MSIRP[0]", - "MSIRP[1]", - "AlignRP", - "RTDG", - "MIAP[0]", - "MIAP[1]", - - "NPushB", - "NPushW", - "WS", - "RS", - "WCvtP", - "RCvt", - "GC[0]", - "GC[1]", - "SCFS", - "MD[0]", - "MD[1]", - "MPPEM", - "MPS", - "FlipON", - "FlipOFF", - "DEBUG", - - "LT", - "LTEQ", - "GT", - "GTEQ", - "EQ", - "NEQ", - "ODD", - "EVEN", - "IF", - "EIF", - "AND", - "OR", - "NOT", - "DeltaP1", - "SDB", - "SDS", - - "ADD", - "SUB", - "DIV", - "MUL", - "ABS", - "NEG", - "FLOOR", - "CEILING", - "ROUND[0]", - "ROUND[1]", - "ROUND[2]", - "ROUND[3]", - "NROUND[0]", - "NROUND[1]", - "NROUND[2]", - "NROUND[3]", - - "WCvtF", - "DeltaP2", - "DeltaP3", - "DeltaCn[0]", - "DeltaCn[1]", - "DeltaCn[2]", - "SROUND", - "S45Round", - "JROT", - "JROF", - "ROFF", - "INS_$7B", - "RUTG", - "RDTG", - "SANGW", - "AA", - - "FlipPT", - "FlipRgON", - "FlipRgOFF", - "INS_$83", - "INS_$84", - "ScanCTRL", - "SDVPTL[0]", - "SDVPTL[1]", - "GetINFO", - "IDEF", - "ROLL", - "MAX", - "MIN", - "ScanTYPE", - "InstCTRL", - "INS_$8F", - - "INS_$90", - "INS_$91", - "INS_$92", - "INS_$93", - "INS_$94", - "INS_$95", - "INS_$96", - "INS_$97", - "INS_$98", - "INS_$99", - "INS_$9A", - "INS_$9B", - "INS_$9C", - "INS_$9D", - "INS_$9E", - "INS_$9F", - - "INS_$A0", - "INS_$A1", - "INS_$A2", - "INS_$A3", - "INS_$A4", - "INS_$A5", - "INS_$A6", - "INS_$A7", - "INS_$A8", - "INS_$A9", - "INS_$AA", - "INS_$AB", - "INS_$AC", - "INS_$AD", - "INS_$AE", - "INS_$AF", - - "PushB[0]", - "PushB[1]", - "PushB[2]", - "PushB[3]", - "PushB[4]", - "PushB[5]", - "PushB[6]", - "PushB[7]", - "PushW[0]", - "PushW[1]", - "PushW[2]", - "PushW[3]", - "PushW[4]", - "PushW[5]", - "PushW[6]", - "PushW[7]", - - "MDRP[00]", - "MDRP[01]", - "MDRP[02]", - "MDRP[03]", - "MDRP[04]", - "MDRP[05]", - "MDRP[06]", - "MDRP[07]", - "MDRP[08]", - "MDRP[09]", - "MDRP[10]", - "MDRP[11]", - "MDRP[12]", - "MDRP[13]", - "MDRP[14]", - "MDRP[15]", - - "MDRP[16]", - "MDRP[17]", - "MDRP[18]", - "MDRP[19]", - "MDRP[20]", - "MDRP[21]", - "MDRP[22]", - "MDRP[23]", - "MDRP[24]", - "MDRP[25]", - "MDRP[26]", - "MDRP[27]", - "MDRP[28]", - "MDRP[29]", - "MDRP[30]", - "MDRP[31]", - - "MIRP[00]", - "MIRP[01]", - "MIRP[02]", - "MIRP[03]", - "MIRP[04]", - "MIRP[05]", - "MIRP[06]", - "MIRP[07]", - "MIRP[08]", - "MIRP[09]", - "MIRP[10]", - "MIRP[11]", - "MIRP[12]", - "MIRP[13]", - "MIRP[14]", - "MIRP[15]", - - "MIRP[16]", - "MIRP[17]", - "MIRP[18]", - "MIRP[19]", - "MIRP[20]", - "MIRP[21]", - "MIRP[22]", - "MIRP[23]", - "MIRP[24]", - "MIRP[25]", - "MIRP[26]", - "MIRP[27]", - "MIRP[28]", - "MIRP[29]", - "MIRP[30]", - "MIRP[31]" + "7 SVTCA y", + "7 SVTCA x", + "8 SPvTCA y", + "8 SPvTCA x", + "8 SFvTCA y", + "8 SFvTCA x", + "8 SPvTL ||", + "7 SPvTL +", + "8 SFvTL ||", + "7 SFvTL +", + "5 SPvFS", + "5 SFvFS", + "3 GPv", + "3 GFv", + "6 SFvTPv", + "5 ISECT", + + "4 SRP0", + "4 SRP1", + "4 SRP2", + "4 SZP0", + "4 SZP1", + "4 SZP2", + "4 SZPS", + "5 SLOOP", + "3 RTG", + "4 RTHG", + "3 SMD", + "4 ELSE", + "4 JMPR", + "6 SCvTCi", + "5 SSwCi", + "3 SSW", + + "3 DUP", + "3 POP", + "5 CLEAR", + "4 SWAP", + "5 DEPTH", + "6 CINDEX", + "6 MINDEX", + "8 AlignPTS", + "7 INS_$28", + "3 UTP", + "8 LOOPCALL", + "4 CALL", + "4 FDEF", + "4 ENDF", + "7 MDAP[0]", + "7 MDAP[1]", + + "6 IUP[0]", + "6 IUP[1]", + "6 SHP[0]", + "6 SHP[1]", + "6 SHC[0]", + "6 SHC[1]", + "6 SHZ[0]", + "6 SHZ[1]", + "5 SHPIX", + "2 IP", + "8 MSIRP[0]", + "8 MSIRP[1]", + "7 AlignRP", + "4 RTDG", + "7 MIAP[0]", + "7 MIAP[1]", + + "6 NPushB", + "6 NPushW", + "2 WS", + "2 RS", + "5 WCvtP", + "4 RCvt", + "5 GC[0]", + "5 GC[1]", + "4 SCFS", + "5 MD[0]", + "5 MD[1]", + "5 MPPEM", + "3 MPS", + "6 FlipON", + "7 FlipOFF", + "5 DEBUG", + + "2 LT", + "4 LTEQ", + "2 GT", + "4 GTEQ", + "2 EQ", + "3 NEQ", + "3 ODD", + "4 EVEN", + "2 IF", + "3 EIF", + "3 AND", + "2 OR", + "3 NOT", + "7 DeltaP1", + "3 SDB", + "3 SDS", + + "3 ADD", + "3 SUB", + "3 DIV", + "3 MUL", + "3 ABS", + "3 NEG", + "5 FLOOR", + "7 CEILING", + "8 ROUND[0]", + "8 ROUND[1]", + "8 ROUND[2]", + "8 ROUND[3]", + "9 NROUND[0]", + "9 NROUND[1]", + "9 NROUND[2]", + "9 NROUND[3]", + + "5 WCvtF", + "7 DeltaP2", + "7 DeltaP3", + "A DeltaCn[0]", + "A DeltaCn[1]", + "A DeltaCn[2]", + "6 SROUND", + "8 S45Round", + "4 JROT", + "4 JROF", + "4 ROFF", + "7 INS_$7B", + "4 RUTG", + "4 RDTG", + "5 SANGW", + "2 AA", + + "6 FlipPT", + "8 FlipRgON", + "9 FlipRgOFF", + "7 INS_$83", + "7 INS_$84", + "8 ScanCTRL", + "9 SDPvTL[0]", + "9 SDPvTL[1]", + "7 GetINFO", + "4 IDEF", + "4 ROLL", + "3 MAX", + "3 MIN", + "8 ScanTYPE", + "8 InstCTRL", + "7 INS_$8F", + + "7 INS_$90", + "7 INS_$91", + "7 INS_$92", + "7 INS_$93", + "7 INS_$94", + "7 INS_$95", + "7 INS_$96", + "7 INS_$97", + "7 INS_$98", + "7 INS_$99", + "7 INS_$9A", + "7 INS_$9B", + "7 INS_$9C", + "7 INS_$9D", + "7 INS_$9E", + "7 INS_$9F", + + "7 INS_$A0", + "7 INS_$A1", + "7 INS_$A2", + "7 INS_$A3", + "7 INS_$A4", + "7 INS_$A5", + "7 INS_$A6", + "7 INS_$A7", + "7 INS_$A8", + "7 INS_$A9", + "7 INS_$AA", + "7 INS_$AB", + "7 INS_$AC", + "7 INS_$AD", + "7 INS_$AE", + "7 INS_$AF", + + "8 PushB[0]", + "8 PushB[1]", + "8 PushB[2]", + "8 PushB[3]", + "8 PushB[4]", + "8 PushB[5]", + "8 PushB[6]", + "8 PushB[7]", + "8 PushW[0]", + "8 PushW[1]", + "8 PushW[2]", + "8 PushW[3]", + "8 PushW[4]", + "8 PushW[5]", + "8 PushW[6]", + "8 PushW[7]", + + "8 MDRP[00]", + "8 MDRP[01]", + "8 MDRP[02]", + "8 MDRP[03]", + "8 MDRP[04]", + "8 MDRP[05]", + "8 MDRP[06]", + "8 MDRP[07]", + "8 MDRP[08]", + "8 MDRP[09]", + "8 MDRP[10]", + "8 MDRP[11]", + "8 MDRP[12]", + "8 MDRP[13]", + "8 MDRP[14]", + "8 MDRP[15]", + + "8 MDRP[16]", + "8 MDRP[17]", + "8 MDRP[18]", + "8 MDRP[19]", + "8 MDRP[20]", + "8 MDRP[21]", + "8 MDRP[22]", + "8 MDRP[23]", + "8 MDRP[24]", + "8 MDRP[25]", + "8 MDRP[26]", + "8 MDRP[27]", + "8 MDRP[28]", + "8 MDRP[29]", + "8 MDRP[30]", + "8 MDRP[31]", + + "8 MIRP[00]", + "8 MIRP[01]", + "8 MIRP[02]", + "8 MIRP[03]", + "8 MIRP[04]", + "8 MIRP[05]", + "8 MIRP[06]", + "8 MIRP[07]", + "8 MIRP[08]", + "8 MIRP[09]", + "8 MIRP[10]", + "8 MIRP[11]", + "8 MIRP[12]", + "8 MIRP[13]", + "8 MIRP[14]", + "8 MIRP[15]", + + "8 MIRP[16]", + "8 MIRP[17]", + "8 MIRP[18]", + "8 MIRP[19]", + "8 MIRP[20]", + "8 MIRP[21]", + "8 MIRP[22]", + "8 MIRP[23]", + "8 MIRP[24]", + "8 MIRP[25]", + "8 MIRP[26]", + "8 MIRP[27]", + "8 MIRP[28]", + "8 MIRP[29]", + "8 MIRP[30]", + "8 MIRP[31]" }; #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -1437,8 +1213,107 @@ #undef PACK -#if 1 +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + +#if defined( __arm__ ) && \ + ( defined( __thumb2__ ) || !defined( __thumb__ ) ) + +#define TT_MulFix14 TT_MulFix14_arm + + static FT_Int32 + TT_MulFix14_arm( FT_Int32 a, + FT_Int b ) + { + FT_Int32 t, t2; + + +#if defined( __CC_ARM ) || defined( __ARMCC__ ) + + __asm + { + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ + mov a, t, asr #31 /* a = (hi >> 31) */ + add a, a, #0x2000 /* a += 0x2000 */ + adds t2, t2, a /* t2 += a */ + adc t, t, #0 /* t += carry */ + mov a, t2, lsr #14 /* a = t2 >> 14 */ + orr a, a, t, lsl #18 /* a |= t << 18 */ + } + +#elif defined( __GNUC__ ) + + __asm__ __volatile__ ( + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ +#if defined( __clang__ ) && defined( __thumb2__ ) + "add.w %0, %0, #0x2000\n\t" /* %0 += 0x2000 */ +#else + "add %0, %0, #0x2000\n\t" /* %0 += 0x2000 */ +#endif + "adds %1, %1, %0\n\t" /* %1 += %0 */ + "adc %2, %2, #0\n\t" /* %2 += carry */ + "mov %0, %1, lsr #14\n\t" /* %0 = %1 >> 16 */ + "orr %0, %0, %2, lsl #18\n\t" /* %0 |= %2 << 16 */ + : "=r"(a), "=&r"(t2), "=&r"(t) + : "r"(a), "r"(b) + : "cc" ); + +#endif + + return a; + } + +#endif /* __arm__ && ( __thumb2__ || !__thumb__ ) */ + +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + + +#if defined( __GNUC__ ) && \ + ( defined( __i386__ ) || defined( __x86_64__ ) ) + +#define TT_MulFix14 TT_MulFix14_long_long + + /* Temporarily disable the warning that C90 doesn't support `long long'. */ +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406 +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wlong-long" + + /* This is declared `noinline' because inlining the function results */ + /* in slower code. The `pure' attribute indicates that the result */ + /* only depends on the parameters. */ + static __attribute__(( noinline )) + __attribute__(( pure )) FT_Int32 + TT_MulFix14_long_long( FT_Int32 a, + FT_Int b ) + { + + long long ret = (long long)a * b; + + /* The following line assumes that right shifting of signed values */ + /* will actually preserve the sign bit. The exact behaviour is */ + /* undefined, but this is true on x86 and x86_64. */ + long long tmp = ret >> 63; + + + ret += 0x2000 + tmp; + + return (FT_Int32)( ret >> 14 ); + } + +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406 +#pragma GCC diagnostic pop +#endif + +#endif /* __GNUC__ && ( __i386__ || __x86_64__ ) */ + + +#ifndef TT_MulFix14 + + /* Compute (a*b)/2^14 with maximum accuracy and rounding. */ + /* This is optimized to be faster than calling FT_MulFix() */ + /* for platforms where sizeof(int) == 2. */ static FT_Int32 TT_MulFix14( FT_Int32 a, FT_Int b ) @@ -1470,37 +1345,50 @@ return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid; } -#else +#endif /* !TT_MulFix14 */ - /* compute (a*b)/2^14 with maximum accuracy and rounding */ - static FT_Int32 - TT_MulFix14( FT_Int32 a, - FT_Int b ) - { - FT_Int32 m, s, hi; - FT_UInt32 l, lo; +#if defined( __GNUC__ ) && \ + ( defined( __i386__ ) || \ + defined( __x86_64__ ) || \ + defined( __arm__ ) ) - /* compute ax*bx as 64-bit value */ - l = (FT_UInt32)( ( a & 0xFFFFU ) * b ); - m = ( a >> 16 ) * b; +#define TT_DotFix14 TT_DotFix14_long_long - lo = l + ( (FT_UInt32)m << 16 ); - hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l ); +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406 +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wlong-long" - /* divide the result by 2^14 with rounding */ - s = hi >> 31; - l = lo + (FT_UInt32)s; - hi += s + ( l < lo ); - lo = l; + static __attribute__(( pure )) FT_Int32 + TT_DotFix14_long_long( FT_Int32 ax, + FT_Int32 ay, + FT_Int bx, + FT_Int by ) + { + /* Temporarily disable the warning that C90 doesn't support */ + /* `long long'. */ - l = lo + 0x2000U; - hi += l < lo; + long long temp1 = (long long)ax * bx; + long long temp2 = (long long)ay * by; + + + temp1 += temp2; + temp2 = temp1 >> 63; + temp1 += 0x2000 + temp2; + + return (FT_Int32)( temp1 >> 14 ); - return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); } + +#if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406 +#pragma GCC diagnostic pop #endif +#endif /* __GNUC__ && (__arm__ || __i386__ || __x86_64__) */ + + +#ifndef TT_DotFix14 /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */ static FT_Int32 @@ -1543,6 +1431,8 @@ return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); } +#endif /* TT_DotFix14 */ + /*************************************************************************/ /* */ @@ -1557,48 +1447,43 @@ /* The aspect ratio in 16.16 format, always <= 1.0 . */ /* */ static FT_Long - Current_Ratio( EXEC_OP ) + Current_Ratio( TT_ExecContext exc ) { - if ( !CUR.tt_metrics.ratio ) + if ( !exc->tt_metrics.ratio ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - if ( CUR.GS.both_x_axis ) - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; - else - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; - } - else -#endif - { - if ( CUR.GS.projVector.y == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; + if ( exc->GS.projVector.y == 0 ) + exc->tt_metrics.ratio = exc->tt_metrics.x_ratio; - else if ( CUR.GS.projVector.x == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; + else if ( exc->GS.projVector.x == 0 ) + exc->tt_metrics.ratio = exc->tt_metrics.y_ratio; - else - { - FT_F26Dot6 x, y; + else + { + FT_F26Dot6 x, y; - x = TT_MulFix14( CUR.tt_metrics.x_ratio, - CUR.GS.projVector.x ); - y = TT_MulFix14( CUR.tt_metrics.y_ratio, - CUR.GS.projVector.y ); - CUR.tt_metrics.ratio = FT_Hypot( x, y ); - } + x = TT_MulFix14( exc->tt_metrics.x_ratio, + exc->GS.projVector.x ); + y = TT_MulFix14( exc->tt_metrics.y_ratio, + exc->GS.projVector.y ); + exc->tt_metrics.ratio = FT_Hypot( x, y ); } } - return CUR.tt_metrics.ratio; + return exc->tt_metrics.ratio; } - static FT_Long - Current_Ppem( EXEC_OP ) + FT_CALLBACK_DEF( FT_Long ) + Current_Ppem( TT_ExecContext exc ) + { + return exc->tt_metrics.ppem; + } + + + FT_CALLBACK_DEF( FT_Long ) + Current_Ppem_Stretched( TT_ExecContext exc ) { - return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() ); + return FT_MulFix( exc->tt_metrics.ppem, Current_Ratio( exc ) ); } @@ -1610,48 +1495,54 @@ FT_CALLBACK_DEF( FT_F26Dot6 ) - Read_CVT( EXEC_OP_ FT_ULong idx ) + Read_CVT( TT_ExecContext exc, + FT_ULong idx ) { - return CUR.cvt[idx]; + return exc->cvt[idx]; } FT_CALLBACK_DEF( FT_F26Dot6 ) - Read_CVT_Stretched( EXEC_OP_ FT_ULong idx ) + Read_CVT_Stretched( TT_ExecContext exc, + FT_ULong idx ) { - return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() ); + return FT_MulFix( exc->cvt[idx], Current_Ratio( exc ) ); } FT_CALLBACK_DEF( void ) - Write_CVT( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) + Write_CVT( TT_ExecContext exc, + FT_ULong idx, + FT_F26Dot6 value ) { - CUR.cvt[idx] = value; + exc->cvt[idx] = value; } FT_CALLBACK_DEF( void ) - Write_CVT_Stretched( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) + Write_CVT_Stretched( TT_ExecContext exc, + FT_ULong idx, + FT_F26Dot6 value ) { - CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() ); + exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) ); } FT_CALLBACK_DEF( void ) - Move_CVT( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) + Move_CVT( TT_ExecContext exc, + FT_ULong idx, + FT_F26Dot6 value ) { - CUR.cvt[idx] += value; + exc->cvt[idx] += value; } FT_CALLBACK_DEF( void ) - Move_CVT_Stretched( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ) + Move_CVT_Stretched( TT_ExecContext exc, + FT_ULong idx, + FT_F26Dot6 value ) { - CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() ); + exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) ); } @@ -1671,12 +1562,12 @@ /* This one could become a macro. */ /* */ static FT_Short - GetShortIns( EXEC_OP ) + GetShortIns( TT_ExecContext exc ) { - /* Reading a byte stream so there is no endianess (DaveP) */ - CUR.IP += 2; - return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) + - CUR.code[CUR.IP - 1] ); + /* Reading a byte stream so there is no endianness (DaveP) */ + exc->IP += 2; + return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) + + exc->code[exc->IP - 1] ); } @@ -1697,23 +1588,24 @@ /* SUCCESS or FAILURE. */ /* */ static FT_Bool - Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, - FT_ULong aIP ) + Ins_Goto_CodeRange( TT_ExecContext exc, + FT_Int aRange, + FT_Long aIP ) { TT_CodeRange* range; if ( aRange < 1 || aRange > 3 ) { - CUR.error = FT_THROW( Bad_Argument ); + exc->error = FT_THROW( Bad_Argument ); return FAILURE; } - range = &CUR.codeRangeTable[aRange - 1]; + range = &exc->codeRangeTable[aRange - 1]; if ( range->base == NULL ) /* invalid coderange */ { - CUR.error = FT_THROW( Invalid_CodeRange ); + exc->error = FT_THROW( Invalid_CodeRange ); return FAILURE; } @@ -1723,14 +1615,14 @@ if ( aIP > range->size ) { - CUR.error = FT_THROW( Code_Overflow ); + exc->error = FT_THROW( Code_Overflow ); return FAILURE; } - CUR.code = range->base; - CUR.codeSize = range->size; - CUR.IP = aIP; - CUR.curRange = aRange; + exc->code = range->base; + exc->codeSize = range->size; + exc->IP = aIP; + exc->curRange = aRange; return SUCCESS; } @@ -1753,37 +1645,57 @@ /* <InOut> */ /* zone :: The affected glyph zone. */ /* */ + /* <Note> */ + /* See `ttinterp.h' for details on backwards compatibility mode. */ + /* `Touches' the point. */ + /* */ static void - Direct_Move( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { FT_F26Dot6 v; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !CUR.face->unpatented_hinting ); -#endif - - v = CUR.GS.freeVector.x; + v = exc->GS.freeVector.x; if ( v != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || - ( !CUR.ignore_x_mode || - ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + ( !exc->ignore_x_mode || + ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) + zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Exception to the post-IUP curfew: Allow the x component of */ + /* diagonal moves, but only post-IUP. DejaVu tries to adjust */ + /* diagonal stems like on `Z' and `z' post-IUP. */ + if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility ) + zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + else +#endif + + if ( NO_SUBPIXEL_HINTING ) + zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } - v = CUR.GS.freeVector.y; + v = exc->GS.freeVector.y; if ( v != 0 ) { - zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) ) +#endif + zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1808,26 +1720,23 @@ /* zone :: The affected glyph zone. */ /* */ static void - Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move_Orig( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { FT_F26Dot6 v; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !CUR.face->unpatented_hinting ); -#endif - - v = CUR.GS.freeVector.x; + v = exc->GS.freeVector.x; if ( v != 0 ) - zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); + zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); - v = CUR.GS.freeVector.y; + v = exc->GS.freeVector.y; if ( v != 0 ) - zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); + zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); } @@ -1837,21 +1746,30 @@ /* */ /* The following versions are used whenever both vectors are both */ /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* See `ttinterp.h' for details on backwards compatibility mode. */ /* */ /*************************************************************************/ static void - Direct_Move_X( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move_X( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { - FT_UNUSED_EXEC; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode ) + zone->cur[point].x += distance; + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || - !CUR.ignore_x_mode ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility ) + zone->cur[point].x += distance; + else +#endif + + if ( NO_SUBPIXEL_HINTING ) zone->cur[point].x += distance; zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; @@ -1859,14 +1777,21 @@ static void - Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move_Y( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { - FT_UNUSED_EXEC; + FT_UNUSED( exc ); - zone->cur[point].y += distance; - zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && exc->iupy_called ) ) +#endif + zone->cur[point].y += distance; + + zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1881,22 +1806,24 @@ static void - Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move_Orig_X( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { - FT_UNUSED_EXEC; + FT_UNUSED( exc ); zone->org[point].x += distance; } static void - Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ) + Direct_Move_Orig_Y( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) { - FT_UNUSED_EXEC; + FT_UNUSED( exc ); zone->org[point].y += distance; } @@ -1925,18 +1852,19 @@ /* before rounding. */ /* */ static FT_F26Dot6 - Round_None( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_None( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { val = distance + compensation; - if ( distance && val < 0 ) + if ( val < 0 ) val = 0; } else @@ -1966,20 +1894,19 @@ /* Rounded distance. */ /* */ static FT_F26Dot6 - Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_To_Grid( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { - val = distance + compensation + 32; - if ( distance && val > 0 ) - val &= ~63; - else + val = FT_PIX_ROUND( distance + compensation ); + if ( val < 0 ) val = 0; } else @@ -1989,7 +1916,7 @@ val = 0; } - return val; + return val; } @@ -2010,25 +1937,26 @@ /* Rounded distance. */ /* */ static FT_F26Dot6 - Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_To_Half_Grid( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { val = FT_PIX_FLOOR( distance + compensation ) + 32; - if ( distance && val < 0 ) - val = 0; + if ( val < 0 ) + val = 32; } else { val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); if ( val > 0 ) - val = 0; + val = -32; } return val; @@ -2052,25 +1980,24 @@ /* Rounded distance. */ /* */ static FT_F26Dot6 - Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_Down_To_Grid( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { - val = distance + compensation; - if ( distance && val > 0 ) - val &= ~63; - else + val = FT_PIX_FLOOR( distance + compensation ); + if ( val < 0 ) val = 0; } else { - val = -( ( compensation - distance ) & -64 ); + val = -FT_PIX_FLOOR( compensation - distance ); if ( val > 0 ) val = 0; } @@ -2096,20 +2023,19 @@ /* Rounded distance. */ /* */ static FT_F26Dot6 - Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_Up_To_Grid( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { - val = distance + compensation + 63; - if ( distance && val > 0 ) - val &= ~63; - else + val = FT_PIX_CEIL( distance + compensation ); + if ( val < 0 ) val = 0; } else @@ -2140,20 +2066,19 @@ /* Rounded distance. */ /* */ static FT_F26Dot6 - Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_To_Double_Grid( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { - FT_F26Dot6 val; + FT_F26Dot6 val; - FT_UNUSED_EXEC; + FT_UNUSED( exc ); if ( distance >= 0 ) { - val = distance + compensation + 16; - if ( distance && val > 0 ) - val &= ~31; - else + val = FT_PAD_ROUND( distance + compensation, 32 ); + if ( val < 0 ) val = 0; } else @@ -2184,33 +2109,34 @@ /* Rounded distance. */ /* */ /* <Note> */ - /* The TrueType specification says very few about the relationship */ + /* The TrueType specification says very little about the relationship */ /* between rounding and engine compensation. However, it seems from */ /* the description of super round that we should add the compensation */ /* before rounding. */ /* */ static FT_F26Dot6 - Round_Super( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_Super( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; if ( distance >= 0 ) { - val = ( distance - CUR.phase + CUR.threshold + compensation ) & - -CUR.period; - if ( distance && val < 0 ) - val = 0; - val += CUR.phase; + val = ( distance - exc->phase + exc->threshold + compensation ) & + -exc->period; + val += exc->phase; + if ( val < 0 ) + val = exc->phase; } else { - val = -( ( CUR.threshold - CUR.phase - distance + compensation ) & - -CUR.period ); + val = -( ( exc->threshold - exc->phase - distance + compensation ) & + -exc->period ); + val -= exc->phase; if ( val > 0 ) - val = 0; - val -= CUR.phase; + val = -exc->phase; } return val; @@ -2238,27 +2164,28 @@ /* greater precision. */ /* */ static FT_F26Dot6 - Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) + Round_Super_45( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ) { FT_F26Dot6 val; if ( distance >= 0 ) { - val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / - CUR.period ) * CUR.period; - if ( distance && val < 0 ) - val = 0; - val += CUR.phase; + val = ( ( distance - exc->phase + exc->threshold + compensation ) / + exc->period ) * exc->period; + val += exc->phase; + if ( val < 0 ) + val = exc->phase; } else { - val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) / - CUR.period ) * CUR.period ); + val = -( ( ( exc->threshold - exc->phase - distance + compensation ) / + exc->period ) * exc->period ); + val -= exc->phase; if ( val > 0 ) - val = 0; - val -= CUR.phase; + val = -exc->phase; } return val; @@ -2277,40 +2204,41 @@ /* round_mode :: The rounding mode to be used. */ /* */ static void - Compute_Round( EXEC_OP_ FT_Byte round_mode ) + Compute_Round( TT_ExecContext exc, + FT_Byte round_mode ) { switch ( round_mode ) { case TT_Round_Off: - CUR.func_round = (TT_Round_Func)Round_None; + exc->func_round = (TT_Round_Func)Round_None; break; case TT_Round_To_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Grid; + exc->func_round = (TT_Round_Func)Round_To_Grid; break; case TT_Round_Up_To_Grid: - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; + exc->func_round = (TT_Round_Func)Round_Up_To_Grid; break; case TT_Round_Down_To_Grid: - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; + exc->func_round = (TT_Round_Func)Round_Down_To_Grid; break; case TT_Round_To_Half_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; + exc->func_round = (TT_Round_Func)Round_To_Half_Grid; break; case TT_Round_To_Double_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; + exc->func_round = (TT_Round_Func)Round_To_Double_Grid; break; case TT_Round_Super: - CUR.func_round = (TT_Round_Func)Round_Super; + exc->func_round = (TT_Round_Func)Round_Super; break; case TT_Round_Super_45: - CUR.func_round = (TT_Round_Func)Round_Super_45; + exc->func_round = (TT_Round_Func)Round_Super_45; break; } } @@ -2330,57 +2258,58 @@ /* selector :: The SROUND opcode. */ /* */ static void - SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, - FT_Long selector ) + SetSuperRound( TT_ExecContext exc, + FT_F2Dot14 GridPeriod, + FT_Long selector ) { switch ( (FT_Int)( selector & 0xC0 ) ) { case 0: - CUR.period = GridPeriod / 2; + exc->period = GridPeriod / 2; break; case 0x40: - CUR.period = GridPeriod; + exc->period = GridPeriod; break; case 0x80: - CUR.period = GridPeriod * 2; + exc->period = GridPeriod * 2; break; /* This opcode is reserved, but... */ - case 0xC0: - CUR.period = GridPeriod; + exc->period = GridPeriod; break; } switch ( (FT_Int)( selector & 0x30 ) ) { case 0: - CUR.phase = 0; + exc->phase = 0; break; case 0x10: - CUR.phase = CUR.period / 4; + exc->phase = exc->period / 4; break; case 0x20: - CUR.phase = CUR.period / 2; + exc->phase = exc->period / 2; break; case 0x30: - CUR.phase = CUR.period * 3 / 4; + exc->phase = exc->period * 3 / 4; break; } if ( ( selector & 0x0F ) == 0 ) - CUR.threshold = CUR.period - 1; + exc->threshold = exc->period - 1; else - CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8; + exc->threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * exc->period / 8; - CUR.period /= 256; - CUR.phase /= 256; - CUR.threshold /= 256; + /* convert to F26Dot6 format */ + exc->period >>= 8; + exc->phase >>= 8; + exc->threshold >>= 8; } @@ -2401,16 +2330,13 @@ /* The distance in F26dot6 format. */ /* */ static FT_F26Dot6 - Project( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) + Project( TT_ExecContext exc, + FT_Pos dx, + FT_Pos dy ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !CUR.face->unpatented_hinting ); -#endif - - return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, - CUR.GS.projVector.x, - CUR.GS.projVector.y ); + return TT_DotFix14( dx, dy, + exc->GS.projVector.x, + exc->GS.projVector.y ); } @@ -2431,12 +2357,13 @@ /* The distance in F26dot6 format. */ /* */ static FT_F26Dot6 - Dual_Project( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) + Dual_Project( TT_ExecContext exc, + FT_Pos dx, + FT_Pos dy ) { - return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, - CUR.GS.dualVector.x, - CUR.GS.dualVector.y ); + return TT_DotFix14( dx, dy, + exc->GS.dualVector.x, + exc->GS.dualVector.y ); } @@ -2457,10 +2384,11 @@ /* The distance in F26dot6 format. */ /* */ static FT_F26Dot6 - Project_x( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) + Project_x( TT_ExecContext exc, + FT_Pos dx, + FT_Pos dy ) { - FT_UNUSED_EXEC; + FT_UNUSED( exc ); FT_UNUSED( dy ); return dx; @@ -2484,10 +2412,11 @@ /* The distance in F26dot6 format. */ /* */ static FT_F26Dot6 - Project_y( EXEC_OP_ FT_Pos dx, - FT_Pos dy ) + Project_y( TT_ExecContext exc, + FT_Pos dx, + FT_Pos dy ) { - FT_UNUSED_EXEC; + FT_UNUSED( exc ); FT_UNUSED( dx ); return dy; @@ -2504,101 +2433,56 @@ /* to the current graphics state. */ /* */ static void - Compute_Funcs( EXEC_OP ) + Compute_Funcs( TT_ExecContext exc ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - /* If both vectors point rightwards along the x axis, set */ - /* `both-x-axis' true, otherwise set it false. The x values only */ - /* need be tested because the vector has been normalised to a unit */ - /* vector of length 0x4000 = unity. */ - CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 && - CUR.GS.freeVector.x == 0x4000 ); - - /* Throw away projection and freedom vector information */ - /* because the patents don't allow them to be stored. */ - /* The relevant US Patents are 5155805 and 5325479. */ - CUR.GS.projVector.x = 0; - CUR.GS.projVector.y = 0; - CUR.GS.freeVector.x = 0; - CUR.GS.freeVector.y = 0; - - if ( CUR.GS.both_x_axis ) - { - CUR.func_project = Project_x; - CUR.func_move = Direct_Move_X; - CUR.func_move_orig = Direct_Move_Orig_X; - } - else - { - CUR.func_project = Project_y; - CUR.func_move = Direct_Move_Y; - CUR.func_move_orig = Direct_Move_Orig_Y; - } - - if ( CUR.GS.dualVector.x == 0x4000 ) - CUR.func_dualproj = Project_x; - else if ( CUR.GS.dualVector.y == 0x4000 ) - CUR.func_dualproj = Project_y; - else - CUR.func_dualproj = Dual_Project; - - /* Force recalculation of cached aspect ratio */ - CUR.tt_metrics.ratio = 0; - - return; - } -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ - - if ( CUR.GS.freeVector.x == 0x4000 ) - CUR.F_dot_P = CUR.GS.projVector.x; - else if ( CUR.GS.freeVector.y == 0x4000 ) - CUR.F_dot_P = CUR.GS.projVector.y; + if ( exc->GS.freeVector.x == 0x4000 ) + exc->F_dot_P = exc->GS.projVector.x; + else if ( exc->GS.freeVector.y == 0x4000 ) + exc->F_dot_P = exc->GS.projVector.y; else - CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x + - (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >> - 14; - - if ( CUR.GS.projVector.x == 0x4000 ) - CUR.func_project = (TT_Project_Func)Project_x; - else if ( CUR.GS.projVector.y == 0x4000 ) - CUR.func_project = (TT_Project_Func)Project_y; + exc->F_dot_P = + ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x + + (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y ) >> 14; + + if ( exc->GS.projVector.x == 0x4000 ) + exc->func_project = (TT_Project_Func)Project_x; + else if ( exc->GS.projVector.y == 0x4000 ) + exc->func_project = (TT_Project_Func)Project_y; else - CUR.func_project = (TT_Project_Func)Project; + exc->func_project = (TT_Project_Func)Project; - if ( CUR.GS.dualVector.x == 0x4000 ) - CUR.func_dualproj = (TT_Project_Func)Project_x; - else if ( CUR.GS.dualVector.y == 0x4000 ) - CUR.func_dualproj = (TT_Project_Func)Project_y; + if ( exc->GS.dualVector.x == 0x4000 ) + exc->func_dualproj = (TT_Project_Func)Project_x; + else if ( exc->GS.dualVector.y == 0x4000 ) + exc->func_dualproj = (TT_Project_Func)Project_y; else - CUR.func_dualproj = (TT_Project_Func)Dual_Project; + exc->func_dualproj = (TT_Project_Func)Dual_Project; - CUR.func_move = (TT_Move_Func)Direct_Move; - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; + exc->func_move = (TT_Move_Func)Direct_Move; + exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig; - if ( CUR.F_dot_P == 0x4000L ) + if ( exc->F_dot_P == 0x4000L ) { - if ( CUR.GS.freeVector.x == 0x4000 ) + if ( exc->GS.freeVector.x == 0x4000 ) { - CUR.func_move = (TT_Move_Func)Direct_Move_X; - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; + exc->func_move = (TT_Move_Func)Direct_Move_X; + exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; } - else if ( CUR.GS.freeVector.y == 0x4000 ) + else if ( exc->GS.freeVector.y == 0x4000 ) { - CUR.func_move = (TT_Move_Func)Direct_Move_Y; - CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; + exc->func_move = (TT_Move_Func)Direct_Move_Y; + exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; } } /* at small sizes, F_dot_P can become too small, resulting */ /* in overflows and `spikes' in a number of glyphs like `w'. */ - if ( FT_ABS( CUR.F_dot_P ) < 0x400L ) - CUR.F_dot_P = 0x4000L; + if ( FT_ABS( exc->F_dot_P ) < 0x400L ) + exc->F_dot_P = 0x4000L; /* Disable cached aspect ratio */ - CUR.tt_metrics.ratio = 0; + exc->tt_metrics.ratio = 0; } @@ -2621,1104 +2505,49 @@ /* Returns FAILURE if a vector parameter is zero. */ /* */ /* <Note> */ - /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ + /* In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and */ /* R is undefined. */ /* */ static FT_Bool - Normalize( EXEC_OP_ FT_F26Dot6 Vx, - FT_F26Dot6 Vy, - FT_UnitVector* R ) + Normalize( FT_F26Dot6 Vx, + FT_F26Dot6 Vy, + FT_UnitVector* R ) { - FT_F26Dot6 W; + FT_Vector V; - FT_UNUSED_EXEC; - - if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L ) + if ( Vx == 0 && Vy == 0 ) { - if ( Vx == 0 && Vy == 0 ) - { - /* XXX: UNDOCUMENTED! It seems that it is possible to try */ - /* to normalize the vector (0,0). Return immediately. */ - return SUCCESS; - } - - Vx *= 0x4000; - Vy *= 0x4000; + /* XXX: UNDOCUMENTED! It seems that it is possible to try */ + /* to normalize the vector (0,0). Return immediately. */ + return SUCCESS; } - W = FT_Hypot( Vx, Vy ); - - R->x = (FT_F2Dot14)TT_DivFix14( Vx, W ); - R->y = (FT_F2Dot14)TT_DivFix14( Vy, W ); - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* Here we start with the implementation of the various opcodes. */ - /* */ - /*************************************************************************/ - + V.x = Vx; + V.y = Vy; - static FT_Bool - Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, - FT_UShort aIdx2, - FT_Int aOpc, - FT_UnitVector* Vec ) - { - FT_Long A, B, C; - FT_Vector* p1; - FT_Vector* p2; + FT_Vector_NormLen( &V ); - - if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || - BOUNDS( aIdx2, CUR.zp1.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); - return FAILURE; - } - - p1 = CUR.zp1.cur + aIdx2; - p2 = CUR.zp2.cur + aIdx1; - - A = p1->x - p2->x; - B = p1->y - p2->y; - - /* If p1 == p2, SPVTL and SFVTL behave the same as */ - /* SPVTCA[X] and SFVTCA[X], respectively. */ - /* */ - /* Confirmed by Greg Hitchcock. */ - - if ( A == 0 && B == 0 ) - { - A = 0x4000; - aOpc = 0; - } - - if ( ( aOpc & 1 ) != 0 ) - { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; - } - - NORMalize( A, B, Vec ); + R->x = (FT_F2Dot14)( V.x / 4 ); + R->y = (FT_F2Dot14)( V.y / 4 ); return SUCCESS; } - /* When not using the big switch statements, the interpreter uses a */ - /* call table defined later below in this source. Each opcode must */ - /* thus have a corresponding function, even trivial ones. */ - /* */ - /* They are all defined there. */ - -#define DO_SVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.freeVector.x = A; \ - CUR.GS.projVector.x = A; \ - CUR.GS.dualVector.x = A; \ - \ - CUR.GS.freeVector.y = B; \ - CUR.GS.projVector.y = B; \ - CUR.GS.dualVector.y = B; \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SPVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.projVector.x = A; \ - CUR.GS.dualVector.x = A; \ - \ - CUR.GS.projVector.y = B; \ - CUR.GS.dualVector.y = B; \ - \ - GUESS_VECTOR( freeVector ); \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.freeVector.x = A; \ - CUR.GS.freeVector.y = B; \ - \ - GUESS_VECTOR( projVector ); \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SPVTL \ - if ( INS_SxVTL( (FT_UShort)args[1], \ - (FT_UShort)args[0], \ - CUR.opcode, \ - &CUR.GS.projVector ) == SUCCESS ) \ - { \ - CUR.GS.dualVector = CUR.GS.projVector; \ - GUESS_VECTOR( freeVector ); \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTL \ - if ( INS_SxVTL( (FT_UShort)args[1], \ - (FT_UShort)args[0], \ - CUR.opcode, \ - &CUR.GS.freeVector ) == SUCCESS ) \ - { \ - GUESS_VECTOR( projVector ); \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTPV \ - GUESS_VECTOR( projVector ); \ - CUR.GS.freeVector = CUR.GS.projVector; \ - COMPUTE_Funcs(); - - -#define DO_SPVFS \ - { \ - FT_Short S; \ - FT_Long X, Y; \ - \ - \ - /* Only use low 16bits, then sign extend */ \ - S = (FT_Short)args[1]; \ - Y = (FT_Long)S; \ - S = (FT_Short)args[0]; \ - X = (FT_Long)S; \ - \ - NORMalize( X, Y, &CUR.GS.projVector ); \ - \ - CUR.GS.dualVector = CUR.GS.projVector; \ - GUESS_VECTOR( freeVector ); \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVFS \ - { \ - FT_Short S; \ - FT_Long X, Y; \ - \ - \ - /* Only use low 16bits, then sign extend */ \ - S = (FT_Short)args[1]; \ - Y = (FT_Long)S; \ - S = (FT_Short)args[0]; \ - X = S; \ - \ - NORMalize( X, Y, &CUR.GS.freeVector ); \ - GUESS_VECTOR( projVector ); \ - COMPUTE_Funcs(); \ - } - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define DO_GPV \ - if ( CUR.face->unpatented_hinting ) \ - { \ - args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ - args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ - } \ - else \ - { \ - args[0] = CUR.GS.projVector.x; \ - args[1] = CUR.GS.projVector.y; \ - } -#else -#define DO_GPV \ - args[0] = CUR.GS.projVector.x; \ - args[1] = CUR.GS.projVector.y; -#endif - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define DO_GFV \ - if ( CUR.face->unpatented_hinting ) \ - { \ - args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ - args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ - } \ - else \ - { \ - args[0] = CUR.GS.freeVector.x; \ - args[1] = CUR.GS.freeVector.y; \ - } -#else -#define DO_GFV \ - args[0] = CUR.GS.freeVector.x; \ - args[1] = CUR.GS.freeVector.y; -#endif - - -#define DO_SRP0 \ - CUR.GS.rp0 = (FT_UShort)args[0]; - - -#define DO_SRP1 \ - CUR.GS.rp1 = (FT_UShort)args[0]; - - -#define DO_SRP2 \ - CUR.GS.rp2 = (FT_UShort)args[0]; - - -#define DO_RTHG \ - CUR.GS.round_state = TT_Round_To_Half_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; - - -#define DO_RTG \ - CUR.GS.round_state = TT_Round_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Grid; - - -#define DO_RTDG \ - CUR.GS.round_state = TT_Round_To_Double_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; - - -#define DO_RUTG \ - CUR.GS.round_state = TT_Round_Up_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; - - -#define DO_RDTG \ - CUR.GS.round_state = TT_Round_Down_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; - - -#define DO_ROFF \ - CUR.GS.round_state = TT_Round_Off; \ - CUR.func_round = (TT_Round_Func)Round_None; - - -#define DO_SROUND \ - SET_SuperRound( 0x4000, args[0] ); \ - CUR.GS.round_state = TT_Round_Super; \ - CUR.func_round = (TT_Round_Func)Round_Super; - - -#define DO_S45ROUND \ - SET_SuperRound( 0x2D41, args[0] ); \ - CUR.GS.round_state = TT_Round_Super_45; \ - CUR.func_round = (TT_Round_Func)Round_Super_45; - - -#define DO_SLOOP \ - if ( args[0] < 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - else \ - CUR.GS.loop = args[0]; - - -#define DO_SMD \ - CUR.GS.minimum_distance = args[0]; - - -#define DO_SCVTCI \ - CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; - - -#define DO_SSWCI \ - CUR.GS.single_width_cutin = (FT_F26Dot6)args[0]; - - -#define DO_SSW \ - CUR.GS.single_width_value = FT_MulFix( args[0], \ - CUR.tt_metrics.scale ); - - -#define DO_FLIPON \ - CUR.GS.auto_flip = TRUE; - - -#define DO_FLIPOFF \ - CUR.GS.auto_flip = FALSE; - - -#define DO_SDB \ - CUR.GS.delta_base = (FT_Short)args[0]; - - -#define DO_SDS \ - CUR.GS.delta_shift = (FT_Short)args[0]; - - -#define DO_MD /* nothing */ - - -#define DO_MPPEM \ - args[0] = CURRENT_Ppem(); - - - /* Note: The pointSize should be irrelevant in a given font program; */ - /* we thus decide to return only the ppem. */ -#if 0 - -#define DO_MPS \ - args[0] = CUR.metrics.pointSize; - -#else - -#define DO_MPS \ - args[0] = CURRENT_Ppem(); - -#endif /* 0 */ - - -#define DO_DUP \ - args[1] = args[0]; - - -#define DO_CLEAR \ - CUR.new_top = 0; - - -#define DO_SWAP \ - { \ - FT_Long L; \ - \ - \ - L = args[0]; \ - args[0] = args[1]; \ - args[1] = L; \ - } - - -#define DO_DEPTH \ - args[0] = CUR.top; - - -#define DO_CINDEX \ - { \ - FT_Long L; \ - \ - \ - L = args[0]; \ - \ - if ( L <= 0 || L > CUR.args ) \ - { \ - if ( CUR.pedantic_hinting ) \ - CUR.error = FT_THROW( Invalid_Reference ); \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR.stack[CUR.args - L]; \ - } - - -#define DO_JROT \ - if ( args[1] != 0 ) \ - { \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.step_ins = FALSE; \ - } - - -#define DO_JMPR \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.step_ins = FALSE; - - -#define DO_JROF \ - if ( args[1] == 0 ) \ - { \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = FT_THROW( Bad_Argument ); \ - CUR.step_ins = FALSE; \ - } - - -#define DO_LT \ - args[0] = ( args[0] < args[1] ); - - -#define DO_LTEQ \ - args[0] = ( args[0] <= args[1] ); - - -#define DO_GT \ - args[0] = ( args[0] > args[1] ); - - -#define DO_GTEQ \ - args[0] = ( args[0] >= args[1] ); - - -#define DO_EQ \ - args[0] = ( args[0] == args[1] ); - - -#define DO_NEQ \ - args[0] = ( args[0] != args[1] ); - - -#define DO_ODD \ - args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 ); - - -#define DO_EVEN \ - args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 ); - - -#define DO_AND \ - args[0] = ( args[0] && args[1] ); - - -#define DO_OR \ - args[0] = ( args[0] || args[1] ); - - -#define DO_NOT \ - args[0] = !args[0]; - - -#define DO_ADD \ - args[0] += args[1]; - - -#define DO_SUB \ - args[0] -= args[1]; - - -#define DO_DIV \ - if ( args[1] == 0 ) \ - CUR.error = FT_THROW( Divide_By_Zero ); \ - else \ - args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] ); - - -#define DO_MUL \ - args[0] = FT_MulDiv( args[0], args[1], 64L ); - - -#define DO_ABS \ - args[0] = FT_ABS( args[0] ); - - -#define DO_NEG \ - args[0] = -args[0]; - - -#define DO_FLOOR \ - args[0] = FT_PIX_FLOOR( args[0] ); - - -#define DO_CEILING \ - args[0] = FT_PIX_CEIL( args[0] ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - -#define DO_RS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - ARRAY_BOUND_ERROR; \ - else \ - args[0] = 0; \ - } \ - else \ - { \ - /* subpixel hinting - avoid Typeman Dstroke and */ \ - /* IStroke and Vacuform rounds */ \ - \ - if ( SUBPIXEL_HINTING && \ - CUR.ignore_x_mode && \ - ( ( I == 24 && \ - ( CUR.face->sph_found_func_flags & \ - ( SPH_FDEF_SPACING_1 | \ - SPH_FDEF_SPACING_2 ) ) ) || \ - ( I == 22 && \ - ( CUR.sph_in_func_flags & \ - SPH_FDEF_TYPEMAN_STROKES ) ) || \ - ( I == 8 && \ - ( CUR.face->sph_found_func_flags & \ - SPH_FDEF_VACUFORM_ROUND_1 ) && \ - CUR.iup_called ) ) ) \ - args[0] = 0; \ - else \ - args[0] = CUR.storage[I]; \ - } \ - } - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - -#define DO_RS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - else \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR.storage[I]; \ - } - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -#define DO_WS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR.storage[I] = args[1]; \ - } - - -#define DO_RCVT \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - else \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR_Func_read_cvt( I ); \ - } - - -#define DO_WCVTP \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR_Func_write_cvt( I, args[1] ); \ - } - - -#define DO_WCVTF \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \ - } - - -#define DO_DEBUG \ - CUR.error = FT_THROW( Debug_OpCode ); - - -#define DO_ROUND \ - args[0] = CUR_Func_round( \ - args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); - - -#define DO_NROUND \ - args[0] = ROUND_None( args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); - - -#define DO_MAX \ - if ( args[1] > args[0] ) \ - args[0] = args[1]; - - -#define DO_MIN \ - if ( args[1] < args[0] ) \ - args[0] = args[1]; - - -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH - - -#undef ARRAY_BOUND_ERROR -#define ARRAY_BOUND_ERROR \ - { \ - CUR.error = FT_THROW( Invalid_Reference ); \ - return; \ - } - - - /*************************************************************************/ - /* */ - /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ - /* Opcode range: 0x00-0x01 */ - /* Stack: --> */ - /* */ - static void - Ins_SVTCA( INS_ARG ) - { - DO_SVTCA - } - - - /*************************************************************************/ - /* */ - /* SPVTCA[a]: Set PVector to Coordinate Axis */ - /* Opcode range: 0x02-0x03 */ - /* Stack: --> */ - /* */ - static void - Ins_SPVTCA( INS_ARG ) - { - DO_SPVTCA - } - - - /*************************************************************************/ - /* */ - /* SFVTCA[a]: Set FVector to Coordinate Axis */ - /* Opcode range: 0x04-0x05 */ - /* Stack: --> */ - /* */ - static void - Ins_SFVTCA( INS_ARG ) - { - DO_SFVTCA - } - - - /*************************************************************************/ - /* */ - /* SPVTL[a]: Set PVector To Line */ - /* Opcode range: 0x06-0x07 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_SPVTL( INS_ARG ) - { - DO_SPVTL - } - - - /*************************************************************************/ - /* */ - /* SFVTL[a]: Set FVector To Line */ - /* Opcode range: 0x08-0x09 */ - /* Stack: uint32 uint32 --> */ - /* */ - static void - Ins_SFVTL( INS_ARG ) - { - DO_SFVTL - } - - - /*************************************************************************/ - /* */ - /* SFVTPV[]: Set FVector To PVector */ - /* Opcode range: 0x0E */ - /* Stack: --> */ - /* */ - static void - Ins_SFVTPV( INS_ARG ) - { - DO_SFVTPV - } - - - /*************************************************************************/ - /* */ - /* SPVFS[]: Set PVector From Stack */ - /* Opcode range: 0x0A */ - /* Stack: f2.14 f2.14 --> */ - /* */ - static void - Ins_SPVFS( INS_ARG ) - { - DO_SPVFS - } - - - /*************************************************************************/ - /* */ - /* SFVFS[]: Set FVector From Stack */ - /* Opcode range: 0x0B */ - /* Stack: f2.14 f2.14 --> */ - /* */ - static void - Ins_SFVFS( INS_ARG ) - { - DO_SFVFS - } - - - /*************************************************************************/ - /* */ - /* GPV[]: Get Projection Vector */ - /* Opcode range: 0x0C */ - /* Stack: ef2.14 --> ef2.14 */ - /* */ - static void - Ins_GPV( INS_ARG ) - { - DO_GPV - } - - - /*************************************************************************/ - /* GFV[]: Get Freedom Vector */ - /* Opcode range: 0x0D */ - /* Stack: ef2.14 --> ef2.14 */ - /* */ - static void - Ins_GFV( INS_ARG ) - { - DO_GFV - } - - - /*************************************************************************/ - /* */ - /* SRP0[]: Set Reference Point 0 */ - /* Opcode range: 0x10 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SRP0( INS_ARG ) - { - DO_SRP0 - } - - - /*************************************************************************/ - /* */ - /* SRP1[]: Set Reference Point 1 */ - /* Opcode range: 0x11 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SRP1( INS_ARG ) - { - DO_SRP1 - } - - - /*************************************************************************/ - /* */ - /* SRP2[]: Set Reference Point 2 */ - /* Opcode range: 0x12 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SRP2( INS_ARG ) - { - DO_SRP2 - } - - - /*************************************************************************/ - /* */ - /* RTHG[]: Round To Half Grid */ - /* Opcode range: 0x19 */ - /* Stack: --> */ - /* */ - static void - Ins_RTHG( INS_ARG ) - { - DO_RTHG - } - - - /*************************************************************************/ - /* */ - /* RTG[]: Round To Grid */ - /* Opcode range: 0x18 */ - /* Stack: --> */ - /* */ - static void - Ins_RTG( INS_ARG ) - { - DO_RTG - } - - /*************************************************************************/ - /* RTDG[]: Round To Double Grid */ - /* Opcode range: 0x3D */ - /* Stack: --> */ /* */ - static void - Ins_RTDG( INS_ARG ) - { - DO_RTDG - } - - - /*************************************************************************/ - /* RUTG[]: Round Up To Grid */ - /* Opcode range: 0x7C */ - /* Stack: --> */ - /* */ - static void - Ins_RUTG( INS_ARG ) - { - DO_RUTG - } - - - /*************************************************************************/ - /* */ - /* RDTG[]: Round Down To Grid */ - /* Opcode range: 0x7D */ - /* Stack: --> */ - /* */ - static void - Ins_RDTG( INS_ARG ) - { - DO_RDTG - } - - - /*************************************************************************/ - /* */ - /* ROFF[]: Round OFF */ - /* Opcode range: 0x7A */ - /* Stack: --> */ - /* */ - static void - Ins_ROFF( INS_ARG ) - { - DO_ROFF - } - - - /*************************************************************************/ - /* */ - /* SROUND[]: Super ROUND */ - /* Opcode range: 0x76 */ - /* Stack: Eint8 --> */ - /* */ - static void - Ins_SROUND( INS_ARG ) - { - DO_SROUND - } - - - /*************************************************************************/ - /* */ - /* S45ROUND[]: Super ROUND 45 degrees */ - /* Opcode range: 0x77 */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_S45ROUND( INS_ARG ) - { - DO_S45ROUND - } - - - /*************************************************************************/ - /* */ - /* SLOOP[]: Set LOOP variable */ - /* Opcode range: 0x17 */ - /* Stack: int32? --> */ - /* */ - static void - Ins_SLOOP( INS_ARG ) - { - DO_SLOOP - } - - - /*************************************************************************/ - /* */ - /* SMD[]: Set Minimum Distance */ - /* Opcode range: 0x1A */ - /* Stack: f26.6 --> */ - /* */ - static void - Ins_SMD( INS_ARG ) - { - DO_SMD - } - - - /*************************************************************************/ - /* */ - /* SCVTCI[]: Set Control Value Table Cut In */ - /* Opcode range: 0x1D */ - /* Stack: f26.6 --> */ - /* */ - static void - Ins_SCVTCI( INS_ARG ) - { - DO_SCVTCI - } - - - /*************************************************************************/ - /* */ - /* SSWCI[]: Set Single Width Cut In */ - /* Opcode range: 0x1E */ - /* Stack: f26.6 --> */ - /* */ - static void - Ins_SSWCI( INS_ARG ) - { - DO_SSWCI - } - - - /*************************************************************************/ - /* */ - /* SSW[]: Set Single Width */ - /* Opcode range: 0x1F */ - /* Stack: int32? --> */ - /* */ - static void - Ins_SSW( INS_ARG ) - { - DO_SSW - } - - - /*************************************************************************/ - /* */ - /* FLIPON[]: Set auto-FLIP to ON */ - /* Opcode range: 0x4D */ - /* Stack: --> */ + /* Here we start with the implementation of the various opcodes. */ /* */ - static void - Ins_FLIPON( INS_ARG ) - { - DO_FLIPON - } - - /*************************************************************************/ - /* */ - /* FLIPOFF[]: Set auto-FLIP to OFF */ - /* Opcode range: 0x4E */ - /* Stack: --> */ - /* */ - static void - Ins_FLIPOFF( INS_ARG ) - { - DO_FLIPOFF - } - /*************************************************************************/ - /* */ - /* SANGW[]: Set ANGle Weight */ - /* Opcode range: 0x7E */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SANGW( INS_ARG ) - { - /* instruction not supported anymore */ - } - - - /*************************************************************************/ - /* */ - /* SDB[]: Set Delta Base */ - /* Opcode range: 0x5E */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SDB( INS_ARG ) - { - DO_SDB - } - - - /*************************************************************************/ - /* */ - /* SDS[]: Set Delta Shift */ - /* Opcode range: 0x5F */ - /* Stack: uint32 --> */ - /* */ - static void - Ins_SDS( INS_ARG ) - { - DO_SDS - } +#define ARRAY_BOUND_ERROR \ + do \ + { \ + exc->error = FT_THROW( Invalid_Reference ); \ + return; \ + } while (0) /*************************************************************************/ @@ -3728,9 +2557,10 @@ /* Stack: --> Euint16 */ /* */ static void - Ins_MPPEM( INS_ARG ) + Ins_MPPEM( TT_ExecContext exc, + FT_Long* args ) { - DO_MPPEM + args[0] = exc->func_cur_ppem( exc ); } @@ -3741,22 +2571,29 @@ /* Stack: --> Euint16 */ /* */ static void - Ins_MPS( INS_ARG ) + Ins_MPS( TT_ExecContext exc, + FT_Long* args ) { - DO_MPS + /* Note: The point size should be irrelevant in a given font program; */ + /* we thus decide to return only the PPEM value. */ +#if 0 + args[0] = exc->metrics.pointSize; +#else + args[0] = exc->func_cur_ppem( exc ); +#endif } /*************************************************************************/ /* */ - /* DUP[]: DUPlicate the top stack's element */ + /* DUP[]: DUPlicate the stack's top element */ /* Opcode range: 0x20 */ /* Stack: StkElt --> StkElt StkElt */ /* */ static void - Ins_DUP( INS_ARG ) + Ins_DUP( FT_Long* args ) { - DO_DUP + args[1] = args[0]; } @@ -3767,7 +2604,7 @@ /* Stack: StkElt --> */ /* */ static void - Ins_POP( INS_ARG ) + Ins_POP( void ) { /* nothing to do */ } @@ -3780,9 +2617,9 @@ /* Stack: StkElt... --> */ /* */ static void - Ins_CLEAR( INS_ARG ) + Ins_CLEAR( TT_ExecContext exc ) { - DO_CLEAR + exc->new_top = 0; } @@ -3793,9 +2630,14 @@ /* Stack: 2 * StkElt --> 2 * StkElt */ /* */ static void - Ins_SWAP( INS_ARG ) + Ins_SWAP( FT_Long* args ) { - DO_SWAP + FT_Long L; + + + L = args[0]; + args[0] = args[1]; + args[1] = L; } @@ -3806,74 +2648,10 @@ /* Stack: --> uint32 */ /* */ static void - Ins_DEPTH( INS_ARG ) - { - DO_DEPTH - } - - - /*************************************************************************/ - /* */ - /* CINDEX[]: Copy INDEXed element */ - /* Opcode range: 0x25 */ - /* Stack: int32 --> StkElt */ - /* */ - static void - Ins_CINDEX( INS_ARG ) - { - DO_CINDEX - } - - - /*************************************************************************/ - /* */ - /* EIF[]: End IF */ - /* Opcode range: 0x59 */ - /* Stack: --> */ - /* */ - static void - Ins_EIF( INS_ARG ) - { - /* nothing to do */ - } - - - /*************************************************************************/ - /* */ - /* JROT[]: Jump Relative On True */ - /* Opcode range: 0x78 */ - /* Stack: StkElt int32 --> */ - /* */ - static void - Ins_JROT( INS_ARG ) - { - DO_JROT - } - - - /*************************************************************************/ - /* */ - /* JMPR[]: JuMP Relative */ - /* Opcode range: 0x1C */ - /* Stack: int32 --> */ - /* */ - static void - Ins_JMPR( INS_ARG ) + Ins_DEPTH( TT_ExecContext exc, + FT_Long* args ) { - DO_JMPR - } - - - /*************************************************************************/ - /* */ - /* JROF[]: Jump Relative On False */ - /* Opcode range: 0x79 */ - /* Stack: StkElt int32 --> */ - /* */ - static void - Ins_JROF( INS_ARG ) - { - DO_JROF + args[0] = exc->top; } @@ -3884,9 +2662,9 @@ /* Stack: int32? int32? --> bool */ /* */ static void - Ins_LT( INS_ARG ) + Ins_LT( FT_Long* args ) { - DO_LT + args[0] = ( args[0] < args[1] ); } @@ -3897,9 +2675,9 @@ /* Stack: int32? int32? --> bool */ /* */ static void - Ins_LTEQ( INS_ARG ) + Ins_LTEQ( FT_Long* args ) { - DO_LTEQ + args[0] = ( args[0] <= args[1] ); } @@ -3910,9 +2688,9 @@ /* Stack: int32? int32? --> bool */ /* */ static void - Ins_GT( INS_ARG ) + Ins_GT( FT_Long* args ) { - DO_GT + args[0] = ( args[0] > args[1] ); } @@ -3923,9 +2701,9 @@ /* Stack: int32? int32? --> bool */ /* */ static void - Ins_GTEQ( INS_ARG ) + Ins_GTEQ( FT_Long* args ) { - DO_GTEQ + args[0] = ( args[0] >= args[1] ); } @@ -3936,9 +2714,9 @@ /* Stack: StkElt StkElt --> bool */ /* */ static void - Ins_EQ( INS_ARG ) + Ins_EQ( FT_Long* args ) { - DO_EQ + args[0] = ( args[0] == args[1] ); } @@ -3949,9 +2727,9 @@ /* Stack: StkElt StkElt --> bool */ /* */ static void - Ins_NEQ( INS_ARG ) + Ins_NEQ( FT_Long* args ) { - DO_NEQ + args[0] = ( args[0] != args[1] ); } @@ -3962,9 +2740,10 @@ /* Stack: f26.6 --> bool */ /* */ static void - Ins_ODD( INS_ARG ) + Ins_ODD( TT_ExecContext exc, + FT_Long* args ) { - DO_ODD + args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 ); } @@ -3975,9 +2754,10 @@ /* Stack: f26.6 --> bool */ /* */ static void - Ins_EVEN( INS_ARG ) + Ins_EVEN( TT_ExecContext exc, + FT_Long* args ) { - DO_EVEN + args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 ); } @@ -3988,9 +2768,9 @@ /* Stack: uint32 uint32 --> uint32 */ /* */ static void - Ins_AND( INS_ARG ) + Ins_AND( FT_Long* args ) { - DO_AND + args[0] = ( args[0] && args[1] ); } @@ -4001,9 +2781,9 @@ /* Stack: uint32 uint32 --> uint32 */ /* */ static void - Ins_OR( INS_ARG ) + Ins_OR( FT_Long* args ) { - DO_OR + args[0] = ( args[0] || args[1] ); } @@ -4014,9 +2794,9 @@ /* Stack: StkElt --> uint32 */ /* */ static void - Ins_NOT( INS_ARG ) + Ins_NOT( FT_Long* args ) { - DO_NOT + args[0] = !args[0]; } @@ -4027,9 +2807,9 @@ /* Stack: f26.6 f26.6 --> f26.6 */ /* */ static void - Ins_ADD( INS_ARG ) + Ins_ADD( FT_Long* args ) { - DO_ADD + args[0] += args[1]; } @@ -4040,9 +2820,9 @@ /* Stack: f26.6 f26.6 --> f26.6 */ /* */ static void - Ins_SUB( INS_ARG ) + Ins_SUB( FT_Long* args ) { - DO_SUB + args[0] -= args[1]; } @@ -4053,9 +2833,13 @@ /* Stack: f26.6 f26.6 --> f26.6 */ /* */ static void - Ins_DIV( INS_ARG ) + Ins_DIV( TT_ExecContext exc, + FT_Long* args ) { - DO_DIV + if ( args[1] == 0 ) + exc->error = FT_THROW( Divide_By_Zero ); + else + args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] ); } @@ -4066,9 +2850,9 @@ /* Stack: f26.6 f26.6 --> f26.6 */ /* */ static void - Ins_MUL( INS_ARG ) + Ins_MUL( FT_Long* args ) { - DO_MUL + args[0] = FT_MulDiv( args[0], args[1], 64L ); } @@ -4079,9 +2863,9 @@ /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_ABS( INS_ARG ) + Ins_ABS( FT_Long* args ) { - DO_ABS + args[0] = FT_ABS( args[0] ); } @@ -4092,9 +2876,9 @@ /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_NEG( INS_ARG ) + Ins_NEG( FT_Long* args ) { - DO_NEG + args[0] = -args[0]; } @@ -4105,9 +2889,9 @@ /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_FLOOR( INS_ARG ) + Ins_FLOOR( FT_Long* args ) { - DO_FLOOR + args[0] = FT_PIX_FLOOR( args[0] ); } @@ -4118,9 +2902,9 @@ /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_CEILING( INS_ARG ) + Ins_CEILING( FT_Long* args ) { - DO_CEILING + args[0] = FT_PIX_CEIL( args[0] ); } @@ -4131,9 +2915,42 @@ /* Stack: uint32 --> uint32 */ /* */ static void - Ins_RS( INS_ARG ) + Ins_RS( TT_ExecContext exc, + FT_Long* args ) { - DO_RS + FT_ULong I = (FT_ULong)args[0]; + + + if ( BOUNDSL( I, exc->storeSize ) ) + { + if ( exc->pedantic_hinting ) + ARRAY_BOUND_ERROR; + else + args[0] = 0; + } + else + { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* subpixel hinting - avoid Typeman Dstroke and */ + /* IStroke and Vacuform rounds */ + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + ( ( I == 24 && + ( exc->face->sph_found_func_flags & + ( SPH_FDEF_SPACING_1 | + SPH_FDEF_SPACING_2 ) ) ) || + ( I == 22 && + ( exc->sph_in_func_flags & + SPH_FDEF_TYPEMAN_STROKES ) ) || + ( I == 8 && + ( exc->face->sph_found_func_flags & + SPH_FDEF_VACUFORM_ROUND_1 ) && + exc->iup_called ) ) ) + args[0] = 0; + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + args[0] = exc->storage[I]; + } } @@ -4144,9 +2961,19 @@ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_WS( INS_ARG ) + Ins_WS( TT_ExecContext exc, + FT_Long* args ) { - DO_WS + FT_ULong I = (FT_ULong)args[0]; + + + if ( BOUNDSL( I, exc->storeSize ) ) + { + if ( exc->pedantic_hinting ) + ARRAY_BOUND_ERROR; + } + else + exc->storage[I] = args[1]; } @@ -4157,9 +2984,19 @@ /* Stack: f26.6 uint32 --> */ /* */ static void - Ins_WCVTP( INS_ARG ) + Ins_WCVTP( TT_ExecContext exc, + FT_Long* args ) { - DO_WCVTP + FT_ULong I = (FT_ULong)args[0]; + + + if ( BOUNDSL( I, exc->cvtSize ) ) + { + if ( exc->pedantic_hinting ) + ARRAY_BOUND_ERROR; + } + else + exc->func_write_cvt( exc, I, args[1] ); } @@ -4170,9 +3007,19 @@ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_WCVTF( INS_ARG ) + Ins_WCVTF( TT_ExecContext exc, + FT_Long* args ) { - DO_WCVTF + FT_ULong I = (FT_ULong)args[0]; + + + if ( BOUNDSL( I, exc->cvtSize ) ) + { + if ( exc->pedantic_hinting ) + ARRAY_BOUND_ERROR; + } + else + exc->cvt[I] = FT_MulFix( args[1], exc->tt_metrics.scale ); } @@ -4183,9 +3030,21 @@ /* Stack: uint32 --> f26.6 */ /* */ static void - Ins_RCVT( INS_ARG ) + Ins_RCVT( TT_ExecContext exc, + FT_Long* args ) { - DO_RCVT + FT_ULong I = (FT_ULong)args[0]; + + + if ( BOUNDSL( I, exc->cvtSize ) ) + { + if ( exc->pedantic_hinting ) + ARRAY_BOUND_ERROR; + else + args[0] = 0; + } + else + args[0] = exc->func_read_cvt( exc, I ); } @@ -4196,7 +3055,7 @@ /* Stack: uint32 --> */ /* */ static void - Ins_AA( INS_ARG ) + Ins_AA( void ) { /* intentionally no longer supported */ } @@ -4211,9 +3070,9 @@ /* Note: The original instruction pops a value from the stack. */ /* */ static void - Ins_DEBUG( INS_ARG ) + Ins_DEBUG( TT_ExecContext exc ) { - DO_DEBUG + exc->error = FT_THROW( Debug_OpCode ); } @@ -4224,9 +3083,13 @@ /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_ROUND( INS_ARG ) + Ins_ROUND( TT_ExecContext exc, + FT_Long* args ) { - DO_ROUND + args[0] = exc->func_round( + exc, + args[0], + exc->tt_metrics.compensations[exc->opcode - 0x68] ); } @@ -4237,9 +3100,13 @@ /* Stack: f26.6 --> f26.6 */ /* */ static void - Ins_NROUND( INS_ARG ) + Ins_NROUND( TT_ExecContext exc, + FT_Long* args ) { - DO_NROUND + args[0] = Round_None( + exc, + args[0], + exc->tt_metrics.compensations[exc->opcode - 0x6C] ); } @@ -4250,9 +3117,10 @@ /* Stack: int32? int32? --> int32 */ /* */ static void - Ins_MAX( INS_ARG ) + Ins_MAX( FT_Long* args ) { - DO_MAX + if ( args[1] > args[0] ) + args[0] = args[1]; } @@ -4263,22 +3131,13 @@ /* Stack: int32? int32? --> int32 */ /* */ static void - Ins_MIN( INS_ARG ) + Ins_MIN( FT_Long* args ) { - DO_MIN + if ( args[1] < args[0] ) + args[0] = args[1]; } -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - - /*************************************************************************/ - /* */ - /* The following functions are called as is within the switch statement. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ /* */ /* MINDEX[]: Move INDEXed element */ @@ -4286,44 +3145,69 @@ /* Stack: int32? --> StkElt */ /* */ static void - Ins_MINDEX( INS_ARG ) + Ins_MINDEX( TT_ExecContext exc, + FT_Long* args ) { FT_Long L, K; L = args[0]; - if ( L <= 0 || L > CUR.args ) + if ( L <= 0 || L > exc->args ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); } else { - K = CUR.stack[CUR.args - L]; + K = exc->stack[exc->args - L]; - FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ], - &CUR.stack[CUR.args - L + 1], + FT_ARRAY_MOVE( &exc->stack[exc->args - L ], + &exc->stack[exc->args - L + 1], ( L - 1 ) ); - CUR.stack[CUR.args - 1] = K; + exc->stack[exc->args - 1] = K; } } /*************************************************************************/ /* */ + /* CINDEX[]: Copy INDEXed element */ + /* Opcode range: 0x25 */ + /* Stack: int32 --> StkElt */ + /* */ + static void + Ins_CINDEX( TT_ExecContext exc, + FT_Long* args ) + { + FT_Long L; + + + L = args[0]; + + if ( L <= 0 || L > exc->args ) + { + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); + args[0] = 0; + } + else + args[0] = exc->stack[exc->args - L]; + } + + + /*************************************************************************/ + /* */ /* ROLL[]: ROLL top three elements */ /* Opcode range: 0x8A */ /* Stack: 3 * StkElt --> 3 * StkElt */ /* */ static void - Ins_ROLL( INS_ARG ) + Ins_ROLL( FT_Long* args ) { FT_Long A, B, C; - FT_UNUSED_EXEC; - A = args[2]; B = args[1]; @@ -4339,34 +3223,49 @@ /* */ /* MANAGING THE FLOW OF CONTROL */ /* */ - /* Instructions appear in the specification's order. */ - /* */ /*************************************************************************/ + /*************************************************************************/ + /* */ + /* SLOOP[]: Set LOOP variable */ + /* Opcode range: 0x17 */ + /* Stack: int32? --> */ + /* */ + static void + Ins_SLOOP( TT_ExecContext exc, + FT_Long* args ) + { + if ( args[0] < 0 ) + exc->error = FT_THROW( Bad_Argument ); + else + exc->GS.loop = args[0]; + } + + static FT_Bool - SkipCode( EXEC_OP ) + SkipCode( TT_ExecContext exc ) { - CUR.IP += CUR.length; + exc->IP += exc->length; - if ( CUR.IP < CUR.codeSize ) + if ( exc->IP < exc->codeSize ) { - CUR.opcode = CUR.code[CUR.IP]; + exc->opcode = exc->code[exc->IP]; - CUR.length = opcode_length[CUR.opcode]; - if ( CUR.length < 0 ) + exc->length = opcode_length[exc->opcode]; + if ( exc->length < 0 ) { - if ( CUR.IP + 1 >= CUR.codeSize ) + if ( exc->IP + 1 >= exc->codeSize ) goto Fail_Overflow; - CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; + exc->length = 2 - exc->length * exc->code[exc->IP + 1]; } - if ( CUR.IP + CUR.length <= CUR.codeSize ) + if ( exc->IP + exc->length <= exc->codeSize ) return SUCCESS; } Fail_Overflow: - CUR.error = FT_THROW( Code_Overflow ); + exc->error = FT_THROW( Code_Overflow ); return FAILURE; } @@ -4378,7 +3277,8 @@ /* Stack: StkElt --> */ /* */ static void - Ins_IF( INS_ARG ) + Ins_IF( TT_ExecContext exc, + FT_Long* args ) { FT_Int nIfs; FT_Bool Out; @@ -4392,10 +3292,10 @@ do { - if ( SKIP_Code() == FAILURE ) + if ( SkipCode( exc ) == FAILURE ) return; - switch ( CUR.opcode ) + switch ( exc->opcode ) { case 0x58: /* IF */ nIfs++; @@ -4421,21 +3321,19 @@ /* Stack: --> */ /* */ static void - Ins_ELSE( INS_ARG ) + Ins_ELSE( TT_ExecContext exc ) { FT_Int nIfs; - FT_UNUSED_ARG; - nIfs = 1; do { - if ( SKIP_Code() == FAILURE ) + if ( SkipCode( exc ) == FAILURE ) return; - switch ( CUR.opcode ) + switch ( exc->opcode ) { case 0x58: /* IF */ nIfs++; @@ -4451,9 +3349,71 @@ /*************************************************************************/ /* */ - /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ + /* EIF[]: End IF */ + /* Opcode range: 0x59 */ + /* Stack: --> */ + /* */ + static void + Ins_EIF( void ) + { + /* nothing to do */ + } + + + /*************************************************************************/ + /* */ + /* JMPR[]: JuMP Relative */ + /* Opcode range: 0x1C */ + /* Stack: int32 --> */ + /* */ + static void + Ins_JMPR( TT_ExecContext exc, + FT_Long* args ) + { + if ( args[0] == 0 && exc->args == 0 ) + exc->error = FT_THROW( Bad_Argument ); + exc->IP += args[0]; + if ( exc->IP < 0 || + ( exc->callTop > 0 && + exc->IP > exc->callStack[exc->callTop - 1].Def->end ) ) + exc->error = FT_THROW( Bad_Argument ); + exc->step_ins = FALSE; + } + + + /*************************************************************************/ + /* */ + /* JROT[]: Jump Relative On True */ + /* Opcode range: 0x78 */ + /* Stack: StkElt int32 --> */ + /* */ + static void + Ins_JROT( TT_ExecContext exc, + FT_Long* args ) + { + if ( args[1] != 0 ) + Ins_JMPR( exc, args ); + } + + + /*************************************************************************/ + /* */ + /* JROF[]: Jump Relative On False */ + /* Opcode range: 0x79 */ + /* Stack: StkElt int32 --> */ + /* */ + static void + Ins_JROF( TT_ExecContext exc, + FT_Long* args ) + { + if ( args[1] == 0 ) + Ins_JMPR( exc, args ); + } + + + /*************************************************************************/ /* */ - /* Instructions appear in the specification's order. */ + /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ /* */ /*************************************************************************/ @@ -4465,13 +3425,14 @@ /* Stack: uint32 --> */ /* */ static void - Ins_FDEF( INS_ARG ) + Ins_FDEF( TT_ExecContext exc, + FT_Long* args ) { FT_ULong n; TT_DefRecord* rec; TT_DefRecord* limit; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* arguments to opcodes are skipped by `SKIP_Code' */ FT_Byte opcode_pattern[9][12] = { /* #0 inline delta function 1 */ @@ -4569,15 +3530,15 @@ FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 }; FT_UShort i; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* some font programs are broken enough to redefine functions! */ /* We will then parse the current table. */ - rec = CUR.FDefs; - limit = rec + CUR.numFDefs; - n = args[0]; + rec = exc->FDefs; + limit = rec + exc->numFDefs; + n = (FT_ULong)args[0]; for ( ; rec < limit; rec++ ) { @@ -4588,33 +3549,33 @@ if ( rec == limit ) { /* check that there is enough room for new functions */ - if ( CUR.numFDefs >= CUR.maxFDefs ) + if ( exc->numFDefs >= exc->maxFDefs ) { - CUR.error = FT_THROW( Too_Many_Function_Defs ); + exc->error = FT_THROW( Too_Many_Function_Defs ); return; } - CUR.numFDefs++; + exc->numFDefs++; } /* Although FDEF takes unsigned 32-bit integer, */ /* func # must be within unsigned 16-bit integer */ if ( n > 0xFFFFU ) { - CUR.error = FT_THROW( Too_Many_Function_Defs ); + exc->error = FT_THROW( Too_Many_Function_Defs ); return; } - rec->range = CUR.curRange; + rec->range = exc->curRange; rec->opc = (FT_UInt16)n; - rec->start = CUR.IP + 1; + rec->start = exc->IP + 1; rec->active = TRUE; rec->inline_delta = FALSE; rec->sph_fdef_flags = 0x0000; - if ( n > CUR.maxFunc ) - CUR.maxFunc = (FT_UInt16)n; + if ( n > exc->maxFunc ) + exc->maxFunc = (FT_UInt16)n; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* We don't know for sure these are typeman functions, */ /* however they are only active when RS 22 is called */ if ( n >= 64 && n <= 66 ) @@ -4624,37 +3585,37 @@ /* Now skip the whole function definition. */ /* We don't allow nested IDEFS & FDEFs. */ - while ( SKIP_Code() == SUCCESS ) + while ( SkipCode( exc ) == SUCCESS ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { for ( i = 0; i < opcode_patterns; i++ ) { - if ( opcode_pointer[i] < opcode_size[i] && - CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) + if ( opcode_pointer[i] < opcode_size[i] && + exc->opcode == opcode_pattern[i][opcode_pointer[i]] ) { opcode_pointer[i] += 1; if ( opcode_pointer[i] == opcode_size[i] ) { - FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n", + FT_TRACE6(( "sph: Function %d, opcode ptrn: %d, %s %s\n", i, n, - CUR.face->root.family_name, - CUR.face->root.style_name )); + exc->face->root.family_name, + exc->face->root.style_name )); switch ( i ) { case 0: - rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1; + rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1; + exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1; break; case 1: - rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2; - CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2; + rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2; + exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2; break; case 2: @@ -4662,8 +3623,8 @@ { /* needs to be implemented still */ case 58: - rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE; - CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE; + rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE; + exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE; } break; @@ -4671,15 +3632,15 @@ switch ( n ) { case 0: - rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1; + rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1; + exc->face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1; } break; case 4: /* probably not necessary to detect anymore */ - rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1; + rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1; + exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1; break; case 5: @@ -4691,8 +3652,8 @@ case 4: case 7: case 8: - rec->sph_fdef_flags |= SPH_FDEF_SPACING_1; - CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1; + rec->sph_fdef_flags |= SPH_FDEF_SPACING_1; + exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1; } break; @@ -4705,20 +3666,20 @@ case 4: case 7: case 8: - rec->sph_fdef_flags |= SPH_FDEF_SPACING_2; - CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2; + rec->sph_fdef_flags |= SPH_FDEF_SPACING_2; + exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_2; } break; case 7: - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; + exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; break; case 8: #if 0 - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; + rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; + exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; #endif break; } @@ -4731,22 +3692,22 @@ } /* Set sph_compatibility_mode only when deltas are detected */ - CUR.face->sph_compatibility_mode = - ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) | - ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); + exc->face->sph_compatibility_mode = + ( ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) | + ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - switch ( CUR.opcode ) + switch ( exc->opcode ) { case 0x89: /* IDEF */ case 0x2C: /* FDEF */ - CUR.error = FT_THROW( Nested_DEFS ); + exc->error = FT_THROW( Nested_DEFS ); return; case 0x2D: /* ENDF */ - rec->end = CUR.IP; + rec->end = exc->IP; return; } } @@ -4760,40 +3721,37 @@ /* Stack: --> */ /* */ static void - Ins_ENDF( INS_ARG ) + Ins_ENDF( TT_ExecContext exc ) { TT_CallRec* pRec; - FT_UNUSED_ARG; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - CUR.sph_in_func_flags = 0x0000; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + exc->sph_in_func_flags = 0x0000; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ + if ( exc->callTop <= 0 ) /* We encountered an ENDF without a call */ { - CUR.error = FT_THROW( ENDF_In_Exec_Stream ); + exc->error = FT_THROW( ENDF_In_Exec_Stream ); return; } - CUR.callTop--; + exc->callTop--; - pRec = &CUR.callStack[CUR.callTop]; + pRec = &exc->callStack[exc->callTop]; pRec->Cur_Count--; - CUR.step_ins = FALSE; + exc->step_ins = FALSE; if ( pRec->Cur_Count > 0 ) { - CUR.callTop++; - CUR.IP = pRec->Cur_Restart; + exc->callTop++; + exc->IP = pRec->Def->start; } else /* Loop through the current function */ - INS_Goto_CodeRange( pRec->Caller_Range, - pRec->Caller_IP ); + Ins_Goto_CodeRange( exc, pRec->Caller_Range, pRec->Caller_IP ); /* Exit the current call frame. */ @@ -4812,7 +3770,8 @@ /* Stack: uint32? --> */ /* */ static void - Ins_CALL( INS_ARG ) + Ins_CALL( TT_ExecContext exc, + FT_Long* args ) { FT_ULong F; TT_CallRec* pCrec; @@ -4821,28 +3780,28 @@ /* first of all, check the index */ - F = args[0]; - if ( BOUNDSL( F, CUR.maxFunc + 1 ) ) + F = (FT_ULong)args[0]; + if ( BOUNDSL( F, exc->maxFunc + 1 ) ) goto Fail; /* Except for some old Apple fonts, all functions in a TrueType */ /* font are defined in increasing order, starting from 0. This */ /* means that we normally have */ /* */ - /* CUR.maxFunc+1 == CUR.numFDefs */ - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ + /* exc->maxFunc+1 == exc->numFDefs */ + /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */ /* */ /* If this isn't true, we need to look up the function table. */ - def = CUR.FDefs + F; - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) + def = exc->FDefs + F; + if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F ) { /* look up the FDefs table */ TT_DefRecord* limit; - def = CUR.FDefs; - limit = def + CUR.numFDefs; + def = exc->FDefs; + limit = def + exc->numFDefs; while ( def < limit && def->opc != F ) def++; @@ -4855,43 +3814,41 @@ if ( !def->active ) goto Fail; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - ( ( CUR.iup_called && - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || - ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + ( ( exc->iup_called && + ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || + ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) ) goto Fail; else - CUR.sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + exc->sph_in_func_flags = def->sph_fdef_flags; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* check the call stack */ - if ( CUR.callTop >= CUR.callSize ) + if ( exc->callTop >= exc->callSize ) { - CUR.error = FT_THROW( Stack_Overflow ); + exc->error = FT_THROW( Stack_Overflow ); return; } - pCrec = CUR.callStack + CUR.callTop; + pCrec = exc->callStack + exc->callTop; - pCrec->Caller_Range = CUR.curRange; - pCrec->Caller_IP = CUR.IP + 1; + pCrec->Caller_Range = exc->curRange; + pCrec->Caller_IP = exc->IP + 1; pCrec->Cur_Count = 1; - pCrec->Cur_Restart = def->start; - pCrec->Cur_End = def->end; + pCrec->Def = def; - CUR.callTop++; + exc->callTop++; - INS_Goto_CodeRange( def->range, - def->start ); + Ins_Goto_CodeRange( exc, def->range, def->start ); - CUR.step_ins = FALSE; + exc->step_ins = FALSE; return; Fail: - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); } @@ -4902,7 +3859,8 @@ /* Stack: uint32? Eint16? --> */ /* */ static void - Ins_LOOPCALL( INS_ARG ) + Ins_LOOPCALL( TT_ExecContext exc, + FT_Long* args ) { FT_ULong F; TT_CallRec* pCrec; @@ -4910,28 +3868,28 @@ /* first of all, check the index */ - F = args[1]; - if ( BOUNDSL( F, CUR.maxFunc + 1 ) ) + F = (FT_ULong)args[1]; + if ( BOUNDSL( F, exc->maxFunc + 1 ) ) goto Fail; /* Except for some old Apple fonts, all functions in a TrueType */ /* font are defined in increasing order, starting from 0. This */ /* means that we normally have */ /* */ - /* CUR.maxFunc+1 == CUR.numFDefs */ - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ + /* exc->maxFunc+1 == exc->numFDefs */ + /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */ /* */ /* If this isn't true, we need to look up the function table. */ - def = CUR.FDefs + F; - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) + def = exc->FDefs + F; + if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F ) { /* look up the FDefs table */ TT_DefRecord* limit; - def = CUR.FDefs; - limit = def + CUR.numFDefs; + def = exc->FDefs; + limit = def + exc->numFDefs; while ( def < limit && def->opc != F ) def++; @@ -4944,43 +3902,42 @@ if ( !def->active ) goto Fail; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) goto Fail; else - CUR.sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + exc->sph_in_func_flags = def->sph_fdef_flags; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* check stack */ - if ( CUR.callTop >= CUR.callSize ) + if ( exc->callTop >= exc->callSize ) { - CUR.error = FT_THROW( Stack_Overflow ); + exc->error = FT_THROW( Stack_Overflow ); return; } if ( args[0] > 0 ) { - pCrec = CUR.callStack + CUR.callTop; + pCrec = exc->callStack + exc->callTop; - pCrec->Caller_Range = CUR.curRange; - pCrec->Caller_IP = CUR.IP + 1; + pCrec->Caller_Range = exc->curRange; + pCrec->Caller_IP = exc->IP + 1; pCrec->Cur_Count = (FT_Int)args[0]; - pCrec->Cur_Restart = def->start; - pCrec->Cur_End = def->end; + pCrec->Def = def; - CUR.callTop++; + exc->callTop++; - INS_Goto_CodeRange( def->range, def->start ); + Ins_Goto_CodeRange( exc, def->range, def->start ); - CUR.step_ins = FALSE; + exc->step_ins = FALSE; } return; Fail: - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); } @@ -4991,7 +3948,8 @@ /* Stack: Eint8 --> */ /* */ static void - Ins_IDEF( INS_ARG ) + Ins_IDEF( TT_ExecContext exc, + FT_Long* args ) { TT_DefRecord* def; TT_DefRecord* limit; @@ -4999,8 +3957,8 @@ /* First of all, look for the same function in our table */ - def = CUR.IDefs; - limit = def + CUR.numIDefs; + def = exc->IDefs; + limit = def + exc->numIDefs; for ( ; def < limit; def++ ) if ( def->opc == (FT_ULong)args[0] ) @@ -5009,39 +3967,39 @@ if ( def == limit ) { /* check that there is enough room for a new instruction */ - if ( CUR.numIDefs >= CUR.maxIDefs ) + if ( exc->numIDefs >= exc->maxIDefs ) { - CUR.error = FT_THROW( Too_Many_Instruction_Defs ); + exc->error = FT_THROW( Too_Many_Instruction_Defs ); return; } - CUR.numIDefs++; + exc->numIDefs++; } /* opcode must be unsigned 8-bit integer */ if ( 0 > args[0] || args[0] > 0x00FF ) { - CUR.error = FT_THROW( Too_Many_Instruction_Defs ); + exc->error = FT_THROW( Too_Many_Instruction_Defs ); return; } def->opc = (FT_Byte)args[0]; - def->start = CUR.IP + 1; - def->range = CUR.curRange; + def->start = exc->IP + 1; + def->range = exc->curRange; def->active = TRUE; - if ( (FT_ULong)args[0] > CUR.maxIns ) - CUR.maxIns = (FT_Byte)args[0]; + if ( (FT_ULong)args[0] > exc->maxIns ) + exc->maxIns = (FT_Byte)args[0]; /* Now skip the whole function definition. */ /* We don't allow nested IDEFs & FDEFs. */ - while ( SKIP_Code() == SUCCESS ) + while ( SkipCode( exc ) == SUCCESS ) { - switch ( CUR.opcode ) + switch ( exc->opcode ) { case 0x89: /* IDEF */ case 0x2C: /* FDEF */ - CUR.error = FT_THROW( Nested_DEFS ); + exc->error = FT_THROW( Nested_DEFS ); return; case 0x2D: /* ENDF */ return; @@ -5054,8 +4012,6 @@ /* */ /* PUSHING DATA ONTO THE INTERPRETER STACK */ /* */ - /* Instructions appear in the specification's order. */ - /* */ /*************************************************************************/ @@ -5066,23 +4022,24 @@ /* Stack: --> uint32... */ /* */ static void - Ins_NPUSHB( INS_ARG ) + Ins_NPUSHB( TT_ExecContext exc, + FT_Long* args ) { FT_UShort L, K; - L = (FT_UShort)CUR.code[CUR.IP + 1]; + L = (FT_UShort)exc->code[exc->IP + 1]; - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) ) { - CUR.error = FT_THROW( Stack_Overflow ); + exc->error = FT_THROW( Stack_Overflow ); return; } for ( K = 1; K <= L; K++ ) - args[K - 1] = CUR.code[CUR.IP + K + 1]; + args[K - 1] = exc->code[exc->IP + K + 1]; - CUR.new_top += L; + exc->new_top += L; } @@ -5093,26 +4050,27 @@ /* Stack: --> int32... */ /* */ static void - Ins_NPUSHW( INS_ARG ) + Ins_NPUSHW( TT_ExecContext exc, + FT_Long* args ) { FT_UShort L, K; - L = (FT_UShort)CUR.code[CUR.IP + 1]; + L = (FT_UShort)exc->code[exc->IP + 1]; - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) ) { - CUR.error = FT_THROW( Stack_Overflow ); + exc->error = FT_THROW( Stack_Overflow ); return; } - CUR.IP += 2; + exc->IP += 2; for ( K = 0; K < L; K++ ) - args[K] = GET_ShortIns(); + args[K] = GetShortIns( exc ); - CUR.step_ins = FALSE; - CUR.new_top += L; + exc->step_ins = FALSE; + exc->new_top += L; } @@ -5123,21 +4081,22 @@ /* Stack: --> uint32... */ /* */ static void - Ins_PUSHB( INS_ARG ) + Ins_PUSHB( TT_ExecContext exc, + FT_Long* args ) { FT_UShort L, K; - L = (FT_UShort)( CUR.opcode - 0xB0 + 1 ); + L = (FT_UShort)( exc->opcode - 0xB0 + 1 ); - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) ) { - CUR.error = FT_THROW( Stack_Overflow ); + exc->error = FT_THROW( Stack_Overflow ); return; } for ( K = 1; K <= L; K++ ) - args[K - 1] = CUR.code[CUR.IP + K]; + args[K - 1] = exc->code[exc->IP + K]; } @@ -5148,25 +4107,26 @@ /* Stack: --> int32... */ /* */ static void - Ins_PUSHW( INS_ARG ) + Ins_PUSHW( TT_ExecContext exc, + FT_Long* args ) { FT_UShort L, K; - L = (FT_UShort)( CUR.opcode - 0xB8 + 1 ); + L = (FT_UShort)( exc->opcode - 0xB8 + 1 ); - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) ) { - CUR.error = FT_THROW( Stack_Overflow ); + exc->error = FT_THROW( Stack_Overflow ); return; } - CUR.IP++; + exc->IP++; for ( K = 0; K < L; K++ ) - args[K] = GET_ShortIns(); + args[K] = GetShortIns( exc ); - CUR.step_ins = FALSE; + exc->step_ins = FALSE; } @@ -5174,9 +4134,524 @@ /* */ /* MANAGING THE GRAPHICS STATE */ /* */ - /* Instructions appear in the specs' order. */ + /*************************************************************************/ + + + static FT_Bool + Ins_SxVTL( TT_ExecContext exc, + FT_UShort aIdx1, + FT_UShort aIdx2, + FT_UnitVector* Vec ) + { + FT_Long A, B, C; + FT_Vector* p1; + FT_Vector* p2; + + FT_Byte opcode = exc->opcode; + + + if ( BOUNDS( aIdx1, exc->zp2.n_points ) || + BOUNDS( aIdx2, exc->zp1.n_points ) ) + { + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); + return FAILURE; + } + + p1 = exc->zp1.cur + aIdx2; + p2 = exc->zp2.cur + aIdx1; + + A = p1->x - p2->x; + B = p1->y - p2->y; + + /* If p1 == p2, SPvTL and SFvTL behave the same as */ + /* SPvTCA[X] and SFvTCA[X], respectively. */ + /* */ + /* Confirmed by Greg Hitchcock. */ + + if ( A == 0 && B == 0 ) + { + A = 0x4000; + opcode = 0; + } + + if ( ( opcode & 1 ) != 0 ) + { + C = B; /* counter clockwise rotation */ + B = A; + A = -C; + } + + Normalize( A, B, Vec ); + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ + /* Opcode range: 0x00-0x01 */ + /* Stack: --> */ + /* */ + /* SPvTCA[a]: Set PVector to Coordinate Axis */ + /* Opcode range: 0x02-0x03 */ + /* Stack: --> */ + /* */ + /* SFvTCA[a]: Set FVector to Coordinate Axis */ + /* Opcode range: 0x04-0x05 */ + /* Stack: --> */ + /* */ + static void + Ins_SxyTCA( TT_ExecContext exc ) + { + FT_Short AA, BB; + + FT_Byte opcode = exc->opcode; + + + AA = (FT_Short)( ( opcode & 1 ) << 14 ); + BB = (FT_Short)( AA ^ 0x4000 ); + + if ( opcode < 4 ) + { + exc->GS.projVector.x = AA; + exc->GS.projVector.y = BB; + + exc->GS.dualVector.x = AA; + exc->GS.dualVector.y = BB; + } + + if ( ( opcode & 2 ) == 0 ) + { + exc->GS.freeVector.x = AA; + exc->GS.freeVector.y = BB; + } + + Compute_Funcs( exc ); + } + + + /*************************************************************************/ + /* */ + /* SPvTL[a]: Set PVector To Line */ + /* Opcode range: 0x06-0x07 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SPVTL( TT_ExecContext exc, + FT_Long* args ) + { + if ( Ins_SxVTL( exc, + (FT_UShort)args[1], + (FT_UShort)args[0], + &exc->GS.projVector ) == SUCCESS ) + { + exc->GS.dualVector = exc->GS.projVector; + Compute_Funcs( exc ); + } + } + + + /*************************************************************************/ + /* */ + /* SFvTL[a]: Set FVector To Line */ + /* Opcode range: 0x08-0x09 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SFVTL( TT_ExecContext exc, + FT_Long* args ) + { + if ( Ins_SxVTL( exc, + (FT_UShort)args[1], + (FT_UShort)args[0], + &exc->GS.freeVector ) == SUCCESS ) + { + Compute_Funcs( exc ); + } + } + + + /*************************************************************************/ + /* */ + /* SFvTPv[]: Set FVector To PVector */ + /* Opcode range: 0x0E */ + /* Stack: --> */ + /* */ + static void + Ins_SFVTPV( TT_ExecContext exc ) + { + exc->GS.freeVector = exc->GS.projVector; + Compute_Funcs( exc ); + } + + + /*************************************************************************/ + /* */ + /* SPvFS[]: Set PVector From Stack */ + /* Opcode range: 0x0A */ + /* Stack: f2.14 f2.14 --> */ + /* */ + static void + Ins_SPVFS( TT_ExecContext exc, + FT_Long* args ) + { + FT_Short S; + FT_Long X, Y; + + + /* Only use low 16bits, then sign extend */ + S = (FT_Short)args[1]; + Y = (FT_Long)S; + S = (FT_Short)args[0]; + X = (FT_Long)S; + + Normalize( X, Y, &exc->GS.projVector ); + + exc->GS.dualVector = exc->GS.projVector; + Compute_Funcs( exc ); + } + + + /*************************************************************************/ + /* */ + /* SFvFS[]: Set FVector From Stack */ + /* Opcode range: 0x0B */ + /* Stack: f2.14 f2.14 --> */ + /* */ + static void + Ins_SFVFS( TT_ExecContext exc, + FT_Long* args ) + { + FT_Short S; + FT_Long X, Y; + + + /* Only use low 16bits, then sign extend */ + S = (FT_Short)args[1]; + Y = (FT_Long)S; + S = (FT_Short)args[0]; + X = S; + + Normalize( X, Y, &exc->GS.freeVector ); + Compute_Funcs( exc ); + } + + + /*************************************************************************/ + /* */ + /* GPv[]: Get Projection Vector */ + /* Opcode range: 0x0C */ + /* Stack: ef2.14 --> ef2.14 */ + /* */ + static void + Ins_GPV( TT_ExecContext exc, + FT_Long* args ) + { + args[0] = exc->GS.projVector.x; + args[1] = exc->GS.projVector.y; + } + + + /*************************************************************************/ + /* */ + /* GFv[]: Get Freedom Vector */ + /* Opcode range: 0x0D */ + /* Stack: ef2.14 --> ef2.14 */ + /* */ + static void + Ins_GFV( TT_ExecContext exc, + FT_Long* args ) + { + args[0] = exc->GS.freeVector.x; + args[1] = exc->GS.freeVector.y; + } + + + /*************************************************************************/ + /* */ + /* SRP0[]: Set Reference Point 0 */ + /* Opcode range: 0x10 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP0( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.rp0 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SRP1[]: Set Reference Point 1 */ + /* Opcode range: 0x11 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP1( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.rp1 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SRP2[]: Set Reference Point 2 */ + /* Opcode range: 0x12 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP2( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.rp2 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SMD[]: Set Minimum Distance */ + /* Opcode range: 0x1A */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SMD( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.minimum_distance = args[0]; + } + + + /*************************************************************************/ + /* */ + /* SCVTCI[]: Set Control Value Table Cut In */ + /* Opcode range: 0x1D */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SCVTCI( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.control_value_cutin = (FT_F26Dot6)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SSWCI[]: Set Single Width Cut In */ + /* Opcode range: 0x1E */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SSWCI( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.single_width_cutin = (FT_F26Dot6)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SSW[]: Set Single Width */ + /* Opcode range: 0x1F */ + /* Stack: int32? --> */ + /* */ + static void + Ins_SSW( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.single_width_value = FT_MulFix( args[0], + exc->tt_metrics.scale ); + } + + + /*************************************************************************/ + /* */ + /* FLIPON[]: Set auto-FLIP to ON */ + /* Opcode range: 0x4D */ + /* Stack: --> */ /* */ + static void + Ins_FLIPON( TT_ExecContext exc ) + { + exc->GS.auto_flip = TRUE; + } + + /*************************************************************************/ + /* */ + /* FLIPOFF[]: Set auto-FLIP to OFF */ + /* Opcode range: 0x4E */ + /* Stack: --> */ + /* */ + static void + Ins_FLIPOFF( TT_ExecContext exc ) + { + exc->GS.auto_flip = FALSE; + } + + + /*************************************************************************/ + /* */ + /* SANGW[]: Set ANGle Weight */ + /* Opcode range: 0x7E */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SANGW( void ) + { + /* instruction not supported anymore */ + } + + + /*************************************************************************/ + /* */ + /* SDB[]: Set Delta Base */ + /* Opcode range: 0x5E */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SDB( TT_ExecContext exc, + FT_Long* args ) + { + exc->GS.delta_base = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SDS[]: Set Delta Shift */ + /* Opcode range: 0x5F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SDS( TT_ExecContext exc, + FT_Long* args ) + { + if ( (FT_ULong)args[0] > 6UL ) + exc->error = FT_THROW( Bad_Argument ); + else + exc->GS.delta_shift = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* RTHG[]: Round To Half Grid */ + /* Opcode range: 0x19 */ + /* Stack: --> */ + /* */ + static void + Ins_RTHG( TT_ExecContext exc ) + { + exc->GS.round_state = TT_Round_To_Half_Grid; + exc->func_round = (TT_Round_Func)Round_To_Half_Grid; + } + + + /*************************************************************************/ + /* */ + /* RTG[]: Round To Grid */ + /* Opcode range: 0x18 */ + /* Stack: --> */ + /* */ + static void + Ins_RTG( TT_ExecContext exc ) + { + exc->GS.round_state = TT_Round_To_Grid; + exc->func_round = (TT_Round_Func)Round_To_Grid; + } + + + /*************************************************************************/ + /* RTDG[]: Round To Double Grid */ + /* Opcode range: 0x3D */ + /* Stack: --> */ + /* */ + static void + Ins_RTDG( TT_ExecContext exc ) + { + exc->GS.round_state = TT_Round_To_Double_Grid; + exc->func_round = (TT_Round_Func)Round_To_Double_Grid; + } + + + /*************************************************************************/ + /* RUTG[]: Round Up To Grid */ + /* Opcode range: 0x7C */ + /* Stack: --> */ + /* */ + static void + Ins_RUTG( TT_ExecContext exc ) + { + exc->GS.round_state = TT_Round_Up_To_Grid; + exc->func_round = (TT_Round_Func)Round_Up_To_Grid; + } + + + /*************************************************************************/ + /* */ + /* RDTG[]: Round Down To Grid */ + /* Opcode range: 0x7D */ + /* Stack: --> */ + /* */ + static void + Ins_RDTG( TT_ExecContext exc ) + { + exc->GS.round_state = TT_Round_Down_To_Grid; + exc->func_round = (TT_Round_Func)Round_Down_To_Grid; + } + + + /*************************************************************************/ + /* */ + /* ROFF[]: Round OFF */ + /* Opcode range: 0x7A */ + /* Stack: --> */ + /* */ + static void + Ins_ROFF( TT_ExecContext exc ) + { + exc->GS.round_state = TT_Round_Off; + exc->func_round = (TT_Round_Func)Round_None; + } + + + /*************************************************************************/ + /* */ + /* SROUND[]: Super ROUND */ + /* Opcode range: 0x76 */ + /* Stack: Eint8 --> */ + /* */ + static void + Ins_SROUND( TT_ExecContext exc, + FT_Long* args ) + { + SetSuperRound( exc, 0x4000, args[0] ); + + exc->GS.round_state = TT_Round_Super; + exc->func_round = (TT_Round_Func)Round_Super; + } + + + /*************************************************************************/ + /* */ + /* S45ROUND[]: Super ROUND 45 degrees */ + /* Opcode range: 0x77 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_S45ROUND( TT_ExecContext exc, + FT_Long* args ) + { + SetSuperRound( exc, 0x2D41, args[0] ); + + exc->GS.round_state = TT_Round_Super_45; + exc->func_round = (TT_Round_Func)Round_Super_45; + } /*************************************************************************/ @@ -5189,7 +4664,8 @@ /* along the dual projection vector! */ /* */ static void - Ins_GC( INS_ARG ) + Ins_GC( TT_ExecContext exc, + FT_Long* args ) { FT_ULong L; FT_F26Dot6 R; @@ -5197,18 +4673,18 @@ L = (FT_ULong)args[0]; - if ( BOUNDSL( L, CUR.zp2.n_points ) ) + if ( BOUNDSL( L, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); R = 0; } else { - if ( CUR.opcode & 1 ) - R = CUR_fast_dualproj( &CUR.zp2.org[L] ); + if ( exc->opcode & 1 ) + R = FAST_DUALPROJ( &exc->zp2.org[L] ); else - R = CUR_fast_project( &CUR.zp2.cur[L] ); + R = FAST_PROJECT( &exc->zp2.cur[L] ); } args[0] = R; @@ -5226,7 +4702,8 @@ /* OA := OA + ( value - OA.p )/( f.p ) * f */ /* */ static void - Ins_SCFS( INS_ARG ) + Ins_SCFS( TT_ExecContext exc, + FT_Long* args ) { FT_Long K; FT_UShort L; @@ -5234,21 +4711,21 @@ L = (FT_UShort)args[0]; - if ( BOUNDS( L, CUR.zp2.n_points ) ) + if ( BOUNDS( L, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - K = CUR_fast_project( &CUR.zp2.cur[L] ); + K = FAST_PROJECT( &exc->zp2.cur[L] ); - CUR_Func_move( &CUR.zp2, L, args[1] - K ); + exc->func_move( exc, &exc->zp2, L, args[1] - K ); /* UNDOCUMENTED! The MS rasterizer does that with */ /* twilight points (confirmed by Greg Hitchcock) */ - if ( CUR.GS.gep2 == 0 ) - CUR.zp2.org[L] = CUR.zp2.cur[L]; + if ( exc->GS.gep2 == 0 ) + exc->zp2.org[L] = exc->zp2.cur[L]; } @@ -5268,7 +4745,8 @@ /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */ /* */ static void - Ins_MD( INS_ARG ) + Ins_MD( TT_ExecContext exc, + FT_Long* args ) { FT_UShort K, L; FT_F26Dot6 D; @@ -5277,61 +4755,62 @@ K = (FT_UShort)args[1]; L = (FT_UShort)args[0]; - if ( BOUNDS( L, CUR.zp0.n_points ) || - BOUNDS( K, CUR.zp1.n_points ) ) + if ( BOUNDS( L, exc->zp0.n_points ) || + BOUNDS( K, exc->zp1.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); D = 0; } else { - if ( CUR.opcode & 1 ) - D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); + if ( exc->opcode & 1 ) + D = PROJECT( exc->zp0.cur + L, exc->zp1.cur + K ); else { /* XXX: UNDOCUMENTED: twilight zone special case */ - if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) + if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 ) { - FT_Vector* vec1 = CUR.zp0.org + L; - FT_Vector* vec2 = CUR.zp1.org + K; + FT_Vector* vec1 = exc->zp0.org + L; + FT_Vector* vec2 = exc->zp1.org + K; - D = CUR_Func_dualproj( vec1, vec2 ); + D = DUALPROJ( vec1, vec2 ); } else { - FT_Vector* vec1 = CUR.zp0.orus + L; - FT_Vector* vec2 = CUR.zp1.orus + K; + FT_Vector* vec1 = exc->zp0.orus + L; + FT_Vector* vec2 = exc->zp1.orus + K; - if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + if ( exc->metrics.x_scale == exc->metrics.y_scale ) { /* this should be faster */ - D = CUR_Func_dualproj( vec1, vec2 ); - D = FT_MulFix( D, CUR.metrics.x_scale ); + D = DUALPROJ( vec1, vec2 ); + D = FT_MulFix( D, exc->metrics.x_scale ); } else { FT_Vector vec; - vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); - vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); + vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale ); + vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale ); - D = CUR_fast_dualproj( &vec ); + D = FAST_DUALPROJ( &vec ); } } } } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && FT_ABS( D ) == 64 ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + FT_ABS( D ) == 64 ) D += 1; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ args[0] = D; } @@ -5339,61 +4818,63 @@ /*************************************************************************/ /* */ - /* SDPVTL[a]: Set Dual PVector to Line */ + /* SDPvTL[a]: Set Dual PVector to Line */ /* Opcode range: 0x86-0x87 */ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_SDPVTL( INS_ARG ) + Ins_SDPVTL( TT_ExecContext exc, + FT_Long* args ) { FT_Long A, B, C; FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ - FT_Int aOpc = CUR.opcode; + + FT_Byte opcode = exc->opcode; p1 = (FT_UShort)args[1]; p2 = (FT_UShort)args[0]; - if ( BOUNDS( p2, CUR.zp1.n_points ) || - BOUNDS( p1, CUR.zp2.n_points ) ) + if ( BOUNDS( p2, exc->zp1.n_points ) || + BOUNDS( p1, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } { - FT_Vector* v1 = CUR.zp1.org + p2; - FT_Vector* v2 = CUR.zp2.org + p1; + FT_Vector* v1 = exc->zp1.org + p2; + FT_Vector* v2 = exc->zp2.org + p1; A = v1->x - v2->x; B = v1->y - v2->y; - /* If v1 == v2, SDPVTL behaves the same as */ + /* If v1 == v2, SDPvTL behaves the same as */ /* SVTCA[X], respectively. */ /* */ /* Confirmed by Greg Hitchcock. */ if ( A == 0 && B == 0 ) { - A = 0x4000; - aOpc = 0; + A = 0x4000; + opcode = 0; } } - if ( ( aOpc & 1 ) != 0 ) + if ( ( opcode & 1 ) != 0 ) { C = B; /* counter clockwise rotation */ B = A; A = -C; } - NORMalize( A, B, &CUR.GS.dualVector ); + Normalize( A, B, &exc->GS.dualVector ); { - FT_Vector* v1 = CUR.zp1.cur + p2; - FT_Vector* v2 = CUR.zp2.cur + p1; + FT_Vector* v1 = exc->zp1.cur + p2; + FT_Vector* v2 = exc->zp2.cur + p1; A = v1->x - v2->x; @@ -5401,23 +4882,20 @@ if ( A == 0 && B == 0 ) { - A = 0x4000; - aOpc = 0; + A = 0x4000; + opcode = 0; } } - if ( ( aOpc & 1 ) != 0 ) + if ( ( opcode & 1 ) != 0 ) { C = B; /* counter clockwise rotation */ B = A; A = -C; } - NORMalize( A, B, &CUR.GS.projVector ); - - GUESS_VECTOR( freeVector ); - - COMPUTE_Funcs(); + Normalize( A, B, &exc->GS.projVector ); + Compute_Funcs( exc ); } @@ -5428,25 +4906,26 @@ /* Stack: uint32 --> */ /* */ static void - Ins_SZP0( INS_ARG ) + Ins_SZP0( TT_ExecContext exc, + FT_Long* args ) { switch ( (FT_Int)args[0] ) { case 0: - CUR.zp0 = CUR.twilight; + exc->zp0 = exc->twilight; break; case 1: - CUR.zp0 = CUR.pts; + exc->zp0 = exc->pts; break; default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - CUR.GS.gep0 = (FT_UShort)args[0]; + exc->GS.gep0 = (FT_UShort)args[0]; } @@ -5457,25 +4936,26 @@ /* Stack: uint32 --> */ /* */ static void - Ins_SZP1( INS_ARG ) + Ins_SZP1( TT_ExecContext exc, + FT_Long* args ) { switch ( (FT_Int)args[0] ) { case 0: - CUR.zp1 = CUR.twilight; + exc->zp1 = exc->twilight; break; case 1: - CUR.zp1 = CUR.pts; + exc->zp1 = exc->pts; break; default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - CUR.GS.gep1 = (FT_UShort)args[0]; + exc->GS.gep1 = (FT_UShort)args[0]; } @@ -5486,25 +4966,26 @@ /* Stack: uint32 --> */ /* */ static void - Ins_SZP2( INS_ARG ) + Ins_SZP2( TT_ExecContext exc, + FT_Long* args ) { switch ( (FT_Int)args[0] ) { case 0: - CUR.zp2 = CUR.twilight; + exc->zp2 = exc->twilight; break; case 1: - CUR.zp2 = CUR.pts; + exc->zp2 = exc->pts; break; default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - CUR.GS.gep2 = (FT_UShort)args[0]; + exc->GS.gep2 = (FT_UShort)args[0]; } @@ -5515,60 +4996,93 @@ /* Stack: uint32 --> */ /* */ static void - Ins_SZPS( INS_ARG ) + Ins_SZPS( TT_ExecContext exc, + FT_Long* args ) { switch ( (FT_Int)args[0] ) { case 0: - CUR.zp0 = CUR.twilight; + exc->zp0 = exc->twilight; break; case 1: - CUR.zp0 = CUR.pts; + exc->zp0 = exc->pts; break; default: - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - CUR.zp1 = CUR.zp0; - CUR.zp2 = CUR.zp0; + exc->zp1 = exc->zp0; + exc->zp2 = exc->zp0; - CUR.GS.gep0 = (FT_UShort)args[0]; - CUR.GS.gep1 = (FT_UShort)args[0]; - CUR.GS.gep2 = (FT_UShort)args[0]; + exc->GS.gep0 = (FT_UShort)args[0]; + exc->GS.gep1 = (FT_UShort)args[0]; + exc->GS.gep2 = (FT_UShort)args[0]; } /*************************************************************************/ /* */ /* INSTCTRL[]: INSTruction ConTRoL */ - /* Opcode range: 0x8e */ + /* Opcode range: 0x8E */ /* Stack: int32 int32 --> */ /* */ static void - Ins_INSTCTRL( INS_ARG ) + Ins_INSTCTRL( TT_ExecContext exc, + FT_Long* args ) { - FT_Long K, L; + FT_ULong K, L, Kf; - K = args[1]; - L = args[0]; + K = (FT_ULong)args[1]; + L = (FT_ULong)args[0]; - if ( K < 1 || K > 2 ) + /* selector values cannot be `OR'ed; */ + /* they are indices starting with index 1, not flags */ + if ( K < 1 || K > 3 ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } + /* convert index to flag value */ + Kf = 1 << ( K - 1 ); + if ( L != 0 ) - L = K; + { + /* arguments to selectors look like flag values */ + if ( L != Kf ) + { + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); + return; + } + } + + exc->GS.instruct_control &= ~(FT_Byte)Kf; + exc->GS.instruct_control |= (FT_Byte)L; + + if ( K == 3 ) + { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* INSTCTRL modifying flag 3 also has an effect */ + /* outside of the CVT program */ + if ( SUBPIXEL_HINTING_INFINALITY ) + exc->ignore_x_mode = FT_BOOL( L == 4 ); +#endif - CUR.GS.instruct_control = FT_BOOL( - ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Native ClearType fonts sign a waiver that turns off all backwards */ + /* compatibility hacks and lets them program points to the grid like */ + /* it's 1996. They might sign a waiver for just one glyph, though. */ + if ( SUBPIXEL_HINTING_MINIMAL ) + exc->backwards_compatibility = !FT_BOOL( L == 4 ); +#endif + } } @@ -5579,7 +5093,8 @@ /* Stack: uint32? --> */ /* */ static void - Ins_SCANCTRL( INS_ARG ) + Ins_SCANCTRL( TT_ExecContext exc, + FT_Long* args ) { FT_Int A; @@ -5589,32 +5104,32 @@ if ( A == 0xFF ) { - CUR.GS.scan_control = TRUE; + exc->GS.scan_control = TRUE; return; } else if ( A == 0 ) { - CUR.GS.scan_control = FALSE; + exc->GS.scan_control = FALSE; return; } - if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A ) - CUR.GS.scan_control = TRUE; + if ( ( args[0] & 0x100 ) != 0 && exc->tt_metrics.ppem <= A ) + exc->GS.scan_control = TRUE; - if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated ) - CUR.GS.scan_control = TRUE; + if ( ( args[0] & 0x200 ) != 0 && exc->tt_metrics.rotated ) + exc->GS.scan_control = TRUE; - if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched ) - CUR.GS.scan_control = TRUE; + if ( ( args[0] & 0x400 ) != 0 && exc->tt_metrics.stretched ) + exc->GS.scan_control = TRUE; - if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A ) - CUR.GS.scan_control = FALSE; + if ( ( args[0] & 0x800 ) != 0 && exc->tt_metrics.ppem > A ) + exc->GS.scan_control = FALSE; - if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated ) - CUR.GS.scan_control = FALSE; + if ( ( args[0] & 0x1000 ) != 0 && exc->tt_metrics.rotated ) + exc->GS.scan_control = FALSE; - if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched ) - CUR.GS.scan_control = FALSE; + if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched ) + exc->GS.scan_control = FALSE; } @@ -5625,10 +5140,11 @@ /* Stack: uint32? --> */ /* */ static void - Ins_SCANTYPE( INS_ARG ) + Ins_SCANTYPE( TT_ExecContext exc, + FT_Long* args ) { if ( args[0] >= 0 ) - CUR.GS.scan_type = (FT_Int)args[0]; + exc->GS.scan_type = (FT_Int)args[0]; } @@ -5636,8 +5152,6 @@ /* */ /* MANAGING OUTLINES */ /* */ - /* Instructions appear in the specification's order. */ - /* */ /*************************************************************************/ @@ -5648,43 +5162,50 @@ /* Stack: uint32... --> */ /* */ static void - Ins_FLIPPT( INS_ARG ) + Ins_FLIPPT( TT_ExecContext exc ) { FT_UShort point; - FT_UNUSED_ARG; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) + goto Fail; +#endif - if ( CUR.top < CUR.GS.loop ) + if ( exc->top < exc->GS.loop ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Too_Few_Arguments ); goto Fail; } - while ( CUR.GS.loop > 0 ) + while ( exc->GS.loop > 0 ) { - CUR.args--; + exc->args--; - point = (FT_UShort)CUR.stack[CUR.args]; + point = (FT_UShort)exc->stack[exc->args]; - if ( BOUNDS( point, CUR.pts.n_points ) ) + if ( BOUNDS( point, exc->pts.n_points ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } } else - CUR.pts.tags[point] ^= FT_CURVE_TAG_ON; + exc->pts.tags[point] ^= FT_CURVE_TAG_ON; - CUR.GS.loop--; + exc->GS.loop--; } Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; + exc->GS.loop = 1; + exc->new_top = exc->args; } @@ -5695,24 +5216,34 @@ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_FLIPRGON( INS_ARG ) + Ins_FLIPRGON( TT_ExecContext exc, + FT_Long* args ) { FT_UShort I, K, L; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) + return; +#endif + K = (FT_UShort)args[1]; L = (FT_UShort)args[0]; - if ( BOUNDS( K, CUR.pts.n_points ) || - BOUNDS( L, CUR.pts.n_points ) ) + if ( BOUNDS( K, exc->pts.n_points ) || + BOUNDS( L, exc->pts.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } for ( I = L; I <= K; I++ ) - CUR.pts.tags[I] |= FT_CURVE_TAG_ON; + exc->pts.tags[I] |= FT_CURVE_TAG_ON; } @@ -5723,53 +5254,64 @@ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_FLIPRGOFF( INS_ARG ) + Ins_FLIPRGOFF( TT_ExecContext exc, + FT_Long* args ) { FT_UShort I, K, L; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) + return; +#endif + K = (FT_UShort)args[1]; L = (FT_UShort)args[0]; - if ( BOUNDS( K, CUR.pts.n_points ) || - BOUNDS( L, CUR.pts.n_points ) ) + if ( BOUNDS( K, exc->pts.n_points ) || + BOUNDS( L, exc->pts.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } for ( I = L; I <= K; I++ ) - CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON; + exc->pts.tags[I] &= ~FT_CURVE_TAG_ON; } static FT_Bool - Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, - FT_F26Dot6* y, - TT_GlyphZone zone, - FT_UShort* refp ) + Compute_Point_Displacement( TT_ExecContext exc, + FT_F26Dot6* x, + FT_F26Dot6* y, + TT_GlyphZone zone, + FT_UShort* refp ) { TT_GlyphZoneRec zp; FT_UShort p; FT_F26Dot6 d; - if ( CUR.opcode & 1 ) + if ( exc->opcode & 1 ) { - zp = CUR.zp0; - p = CUR.GS.rp1; + zp = exc->zp0; + p = exc->GS.rp1; } else { - zp = CUR.zp1; - p = CUR.GS.rp2; + zp = exc->zp1; + p = exc->GS.rp2; } if ( BOUNDS( p, zp.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); *refp = 0; return FAILURE; } @@ -5777,70 +5319,47 @@ *zone = zp; *refp = p; - d = CUR_Func_project( zp.cur + p, zp.org + p ); + d = PROJECT( zp.cur + p, zp.org + p ); -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - if ( CUR.GS.both_x_axis ) - { - *x = d; - *y = 0; - } - else - { - *x = 0; - *y = d; - } - } - else -#endif - { - *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P ); - *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P ); - } + *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P ); + *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P ); return SUCCESS; } + /* See `ttinterp.h' for details on backwards compatibility mode. */ static void - Move_Zp2_Point( EXEC_OP_ FT_UShort point, - FT_F26Dot6 dx, - FT_F26Dot6 dy, - FT_Bool touch ) + Move_Zp2_Point( TT_ExecContext exc, + FT_UShort point, + FT_F26Dot6 dx, + FT_F26Dot6 dy, + FT_Bool touch ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) + if ( exc->GS.freeVector.x != 0 ) { - if ( CUR.GS.both_x_axis ) - { - CUR.zp2.cur[point].x += dx; - if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; - } - else - { - CUR.zp2.cur[point].y += dy; - if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; - } - return; - } +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) ) #endif + exc->zp2.cur[point].x += dx; - if ( CUR.GS.freeVector.x != 0 ) - { - CUR.zp2.cur[point].x += dx; if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; } - if ( CUR.GS.freeVector.y != 0 ) + if ( exc->GS.freeVector.y != 0 ) { - CUR.zp2.cur[point].y += dy; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility && + exc->iupx_called && + exc->iupy_called ) ) +#endif + exc->zp2.cur[point].y += dy; + if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; } } @@ -5852,57 +5371,53 @@ /* Stack: uint32... --> */ /* */ static void - Ins_SHP( INS_ARG ) + Ins_SHP( TT_ExecContext exc ) { TT_GlyphZoneRec zp; FT_UShort refp; - FT_F26Dot6 dx, - dy; + FT_F26Dot6 dx, dy; FT_UShort point; - FT_UNUSED_ARG; - - if ( CUR.top < CUR.GS.loop ) + if ( exc->top < exc->GS.loop ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) ) return; - while ( CUR.GS.loop > 0 ) + while ( exc->GS.loop > 0 ) { - CUR.args--; - point = (FT_UShort)CUR.stack[CUR.args]; + exc->args--; + point = (FT_UShort)exc->stack[exc->args]; - if ( BOUNDS( point, CUR.zp2.n_points ) ) + if ( BOUNDS( point, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } } else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* doesn't follow Cleartype spec but produces better result */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode ) - MOVE_Zp2_Point( point, 0, dy, TRUE ); + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode ) + Move_Zp2_Point( exc, point, 0, dy, TRUE ); else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - MOVE_Zp2_Point( point, dx, dy, TRUE ); +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + Move_Zp2_Point( exc, point, dx, dy, TRUE ); - CUR.GS.loop--; + exc->GS.loop--; } Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; + exc->GS.loop = 1; + exc->new_top = exc->args; } @@ -5917,7 +5432,8 @@ /* zero which includes all points of it. */ /* */ static void - Ins_SHC( INS_ARG ) + Ins_SHC( TT_ExecContext exc, + FT_Long* args ) { TT_GlyphZoneRec zp; FT_UShort refp; @@ -5927,36 +5443,36 @@ FT_UShort start, limit, i; - contour = (FT_UShort)args[0]; - bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours; + contour = (FT_Short)args[0]; + bounds = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours; if ( BOUNDS( contour, bounds ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) ) return; if ( contour == 0 ) start = 0; else - start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 - - CUR.zp2.first_point ); + start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 - + exc->zp2.first_point ); /* we use the number of points if in the twilight zone */ - if ( CUR.GS.gep2 == 0 ) - limit = CUR.zp2.n_points; + if ( exc->GS.gep2 == 0 ) + limit = exc->zp2.n_points; else - limit = (FT_UShort)( CUR.zp2.contours[contour] - - CUR.zp2.first_point + 1 ); + limit = (FT_UShort)( exc->zp2.contours[contour] - + exc->zp2.first_point + 1 ); for ( i = start; i < limit; i++ ) { - if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, TRUE ); + if ( zp.cur != exc->zp2.cur || refp != i ) + Move_Zp2_Point( exc, i, dx, dy, TRUE ); } } @@ -5968,7 +5484,8 @@ /* Stack: uint32 --> */ /* */ static void - Ins_SHZ( INS_ARG ) + Ins_SHZ( TT_ExecContext exc, + FT_Long* args ) { TT_GlyphZoneRec zp; FT_UShort refp; @@ -5980,30 +5497,30 @@ if ( BOUNDS( args[0], 2 ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) ) return; /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */ /* Twilight zone has no real contours, so use `n_points'. */ /* Normal zone's `n_points' includes phantoms, so must */ /* use end of last contour. */ - if ( CUR.GS.gep2 == 0 ) - limit = (FT_UShort)CUR.zp2.n_points; - else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 ) - limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 ); + if ( exc->GS.gep2 == 0 ) + limit = (FT_UShort)exc->zp2.n_points; + else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 ) + limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 ); else limit = 0; /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */ for ( i = 0; i < limit; i++ ) { - if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, FALSE ); + if ( zp.cur != exc->zp2.cur || refp != i ) + Move_Zp2_Point( exc, i, dx, dy, FALSE ); } } @@ -6015,148 +5532,152 @@ /* Stack: f26.6 uint32... --> */ /* */ static void - Ins_SHPIX( INS_ARG ) + Ins_SHPIX( TT_ExecContext exc, + FT_Long* args ) { FT_F26Dot6 dx, dy; FT_UShort point; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Int B1, B2; #endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + FT_Bool in_twilight = exc->GS.gep0 == 0 || \ + exc->GS.gep1 == 0 || \ + exc->GS.gep2 == 0; +#endif - if ( CUR.top < CUR.GS.loop + 1 ) + + if ( exc->top < exc->GS.loop + 1 ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( CUR.face->unpatented_hinting ) - { - if ( CUR.GS.both_x_axis ) - { - dx = (FT_UInt32)args[0]; - dy = 0; - } - else - { - dx = 0; - dy = (FT_UInt32)args[0]; - } - } - else -#endif - { - dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); - dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); - } + dx = TT_MulFix14( args[0], exc->GS.freeVector.x ); + dy = TT_MulFix14( args[0], exc->GS.freeVector.y ); - while ( CUR.GS.loop > 0 ) + while ( exc->GS.loop > 0 ) { - CUR.args--; + exc->args--; - point = (FT_UShort)CUR.stack[CUR.args]; + point = (FT_UShort)exc->stack[exc->args]; - if ( BOUNDS( point, CUR.zp2.n_points ) ) + if ( BOUNDS( point, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } } else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { - /* If not using ignore_x_mode rendering, allow ZP2 move. */ - /* If inline deltas aren't allowed, skip ZP2 move. */ - /* If using ignore_x_mode rendering, allow ZP2 point move if: */ - /* - freedom vector is y and sph_compatibility_mode is off */ - /* - the glyph is composite and the move is in the Y direction */ - /* - the glyph is specifically set to allow SHPIX moves */ - /* - the move is on a previously Y-touched point */ - - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode ) + /* If not using ignore_x_mode rendering, allow ZP2 move. */ + /* If inline deltas aren't allowed, skip ZP2 move. */ + /* If using ignore_x_mode rendering, allow ZP2 point move if: */ + /* - freedom vector is y and sph_compatibility_mode is off */ + /* - the glyph is composite and the move is in the Y direction */ + /* - the glyph is specifically set to allow SHPIX moves */ + /* - the move is on a previously Y-touched point */ + + if ( exc->ignore_x_mode ) { /* save point for later comparison */ - if ( CUR.GS.freeVector.y != 0 ) - B1 = CUR.zp2.cur[point].y; + if ( exc->GS.freeVector.y != 0 ) + B1 = exc->zp2.cur[point].y; else - B1 = CUR.zp2.cur[point].x; + B1 = exc->zp2.cur[point].x; - if ( !CUR.face->sph_compatibility_mode && - CUR.GS.freeVector.y != 0 ) + if ( !exc->face->sph_compatibility_mode && + exc->GS.freeVector.y != 0 ) { - MOVE_Zp2_Point( point, dx, dy, TRUE ); + Move_Zp2_Point( exc, point, dx, dy, TRUE ); /* save new point */ - if ( CUR.GS.freeVector.y != 0 ) + if ( exc->GS.freeVector.y != 0 ) { - B2 = CUR.zp2.cur[point].y; + B2 = exc->zp2.cur[point].y; /* reverse any disallowed moves */ - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - ( B1 & 63 ) != 0 && - ( B2 & 63 ) != 0 && - B1 != B2 ) - MOVE_Zp2_Point( point, -dx, -dy, TRUE ); + if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && + ( B1 & 63 ) != 0 && + ( B2 & 63 ) != 0 && + B1 != B2 ) + Move_Zp2_Point( exc, point, -dx, -dy, TRUE ); } } - else if ( CUR.face->sph_compatibility_mode ) + else if ( exc->face->sph_compatibility_mode ) { - if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) + if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) { dx = FT_PIX_ROUND( B1 + dx ) - B1; dy = FT_PIX_ROUND( B1 + dy ) - B1; } /* skip post-iup deltas */ - if ( CUR.iup_called && - ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) || - ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) ) + if ( exc->iup_called && + ( ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) || + ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) ) goto Skip; - if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && - ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) || - ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || - ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) ) - MOVE_Zp2_Point( point, 0, dy, TRUE ); + if ( !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || + ( exc->sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) ) + Move_Zp2_Point( exc, point, 0, dy, TRUE ); /* save new point */ - if ( CUR.GS.freeVector.y != 0 ) + if ( exc->GS.freeVector.y != 0 ) { - B2 = CUR.zp2.cur[point].y; + B2 = exc->zp2.cur[point].y; /* reverse any disallowed moves */ if ( ( B1 & 63 ) == 0 && ( B2 & 63 ) != 0 && B1 != B2 ) - MOVE_Zp2_Point( point, 0, -dy, TRUE ); + Move_Zp2_Point( exc, point, 0, -dy, TRUE ); } } - else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) - MOVE_Zp2_Point( point, dx, dy, TRUE ); + else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) + Move_Zp2_Point( exc, point, dx, dy, TRUE ); } else - MOVE_Zp2_Point( point, dx, dy, TRUE ); + Move_Zp2_Point( exc, point, dx, dy, TRUE ); } + else +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) + { + /* Special case: allow SHPIX to move points in the twilight zone. */ + /* Otherwise, treat SHPIX the same as DELTAP. Unbreaks various */ + /* fonts such as older versions of Rokkitt and DTL Argo T Light */ + /* that would glitch severly after calling ALIGNRP after a blocked */ + /* SHPIX. */ + if ( in_twilight || + ( !( exc->iupx_called && exc->iupy_called ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ) ) ) + Move_Zp2_Point( exc, point, 0, dy, TRUE ); + } + else +#endif + Move_Zp2_Point( exc, point, dx, dy, TRUE ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY Skip: - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - MOVE_Zp2_Point( point, dx, dy, TRUE ); - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - CUR.GS.loop--; +#endif + exc->GS.loop--; } Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; + exc->GS.loop = 1; + exc->new_top = exc->args; } @@ -6167,65 +5688,63 @@ /* Stack: f26.6 uint32 --> */ /* */ static void - Ins_MSIRP( INS_ARG ) + Ins_MSIRP( TT_ExecContext exc, + FT_Long* args ) { - FT_UShort point; + FT_UShort point = 0; FT_F26Dot6 distance; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_F26Dot6 control_value_cutin = 0; /* pacify compiler */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + FT_F26Dot6 control_value_cutin = 0; - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { - control_value_cutin = CUR.GS.control_value_cutin; + control_value_cutin = exc->GS.control_value_cutin; - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) + if ( exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = 0; } - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ point = (FT_UShort)args[0]; - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + if ( BOUNDS( point, exc->zp1.n_points ) || + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } /* UNDOCUMENTED! The MS rasterizer does that with */ /* twilight points (confirmed by Greg Hitchcock) */ - if ( CUR.GS.gep1 == 0 ) + if ( exc->GS.gep1 == 0 ) { - CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; - CUR_Func_move_orig( &CUR.zp1, point, args[1] ); - CUR.zp1.cur[point] = CUR.zp1.org[point]; + exc->zp1.org[point] = exc->zp0.org[exc->GS.rp0]; + exc->func_move_orig( exc, &exc->zp1, point, args[1] ); + exc->zp1.cur[point] = exc->zp1.org[point]; } - distance = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); + distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* subpixel hinting - make MSIRP respect CVT cut-in; */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && FT_ABS( distance - args[1] ) >= control_value_cutin ) distance = args[1]; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - CUR_Func_move( &CUR.zp1, point, args[1] - distance ); + exc->func_move( exc, &exc->zp1, point, args[1] - distance ); - CUR.GS.rp1 = CUR.GS.rp0; - CUR.GS.rp2 = point; + exc->GS.rp1 = exc->GS.rp0; + exc->GS.rp2 = point; - if ( ( CUR.opcode & 1 ) != 0 ) - CUR.GS.rp0 = point; + if ( ( exc->opcode & 1 ) != 0 ) + exc->GS.rp0 = point; } @@ -6236,7 +5755,8 @@ /* Stack: uint32 --> */ /* */ static void - Ins_MDAP( INS_ARG ) + Ins_MDAP( TT_ExecContext exc, + FT_Long* args ) { FT_UShort point; FT_F26Dot6 cur_dist; @@ -6245,36 +5765,38 @@ point = (FT_UShort)args[0]; - if ( BOUNDS( point, CUR.zp0.n_points ) ) + if ( BOUNDS( point, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - if ( ( CUR.opcode & 1 ) != 0 ) + if ( ( exc->opcode & 1 ) != 0 ) { - cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 ) - distance = ROUND_None( + cur_dist = FAST_PROJECT( &exc->zp0.cur[point] ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) + distance = Round_None( + exc, cur_dist, - CUR.tt_metrics.compensations[0] ) - cur_dist; + exc->tt_metrics.compensations[0] ) - cur_dist; else #endif - distance = CUR_Func_round( + distance = exc->func_round( + exc, cur_dist, - CUR.tt_metrics.compensations[0] ) - cur_dist; + exc->tt_metrics.compensations[0] ) - cur_dist; } else distance = 0; - CUR_Func_move( &CUR.zp0, point, distance ); + exc->func_move( exc, &exc->zp0, point, distance ); - CUR.GS.rp0 = point; - CUR.GS.rp1 = point; + exc->GS.rp0 = point; + exc->GS.rp1 = point; } @@ -6285,7 +5807,8 @@ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_MIAP( INS_ARG ) + Ins_MIAP( TT_ExecContext exc, + FT_Long* args ) { FT_ULong cvtEntry; FT_UShort point; @@ -6294,24 +5817,24 @@ FT_F26Dot6 control_value_cutin; - control_value_cutin = CUR.GS.control_value_cutin; + control_value_cutin = exc->GS.control_value_cutin; cvtEntry = (FT_ULong)args[1]; point = (FT_UShort)args[0]; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - CUR.GS.freeVector.y == 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + exc->GS.freeVector.y == 0 && + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( BOUNDS( point, CUR.zp0.n_points ) || - BOUNDSL( cvtEntry, CUR.cvtSize ) ) + if ( BOUNDS( point, exc->zp0.n_points ) || + BOUNDSL( cvtEntry, exc->cvtSize ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } @@ -6335,56 +5858,58 @@ /* */ /* Confirmed by Greg Hitchcock. */ - distance = CUR_Func_read_cvt( cvtEntry ); + distance = exc->func_read_cvt( exc, cvtEntry ); - if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ + if ( exc->GS.gep0 == 0 ) /* If in twilight zone */ { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */ /* Determined via experimentation and may be incorrect... */ - if ( !SUBPIXEL_HINTING || - ( !CUR.ignore_x_mode || - !CUR.face->sph_compatibility_mode ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, - CUR.GS.freeVector.x ); - CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, - CUR.GS.freeVector.y ), - CUR.zp0.cur[point] = CUR.zp0.org[point]; - } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && - distance > 0 && - CUR.GS.freeVector.y != 0 ) + if ( !( SUBPIXEL_HINTING_INFINALITY && + ( exc->ignore_x_mode && + exc->face->sph_compatibility_mode ) ) ) +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + exc->zp0.org[point].x = TT_MulFix14( distance, + exc->GS.freeVector.x ); + exc->zp0.org[point].y = TT_MulFix14( distance, + exc->GS.freeVector.y ), + exc->zp0.cur[point] = exc->zp0.org[point]; + } +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && + distance > 0 && + exc->GS.freeVector.y != 0 ) distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); + org_dist = FAST_PROJECT( &exc->zp0.cur[point] ); - if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cut-in flag */ + if ( ( exc->opcode & 1 ) != 0 ) /* rounding and control cut-in flag */ { if ( FT_ABS( distance - org_dist ) > control_value_cutin ) distance = org_dist; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 ) - distance = ROUND_None( distance, - CUR.tt_metrics.compensations[0] ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) + distance = Round_None( exc, + distance, + exc->tt_metrics.compensations[0] ); else #endif - distance = CUR_Func_round( distance, - CUR.tt_metrics.compensations[0] ); + distance = exc->func_round( exc, + distance, + exc->tt_metrics.compensations[0] ); } - CUR_Func_move( &CUR.zp0, point, distance - org_dist ); + exc->func_move( exc, &exc->zp0, point, distance - org_dist ); Fail: - CUR.GS.rp0 = point; - CUR.GS.rp1 = point; + exc->GS.rp0 = point; + exc->GS.rp1 = point; } @@ -6395,29 +5920,30 @@ /* Stack: uint32 --> */ /* */ static void - Ins_MDRP( INS_ARG ) + Ins_MDRP( TT_ExecContext exc, + FT_Long* args ) { - FT_UShort point; + FT_UShort point = 0; FT_F26Dot6 org_dist, distance, minimum_distance; - minimum_distance = CUR.GS.minimum_distance; + minimum_distance = exc->GS.minimum_distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) minimum_distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ point = (FT_UShort)args[0]; - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + if ( BOUNDS( point, exc->zp1.n_points ) || + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } @@ -6426,74 +5952,77 @@ /* XXX: UNDOCUMENTED: twilight zone special case */ - if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) + if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 ) { - FT_Vector* vec1 = &CUR.zp1.org[point]; - FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0]; + FT_Vector* vec1 = &exc->zp1.org[point]; + FT_Vector* vec2 = &exc->zp0.org[exc->GS.rp0]; - org_dist = CUR_Func_dualproj( vec1, vec2 ); + org_dist = DUALPROJ( vec1, vec2 ); } else { - FT_Vector* vec1 = &CUR.zp1.orus[point]; - FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0]; + FT_Vector* vec1 = &exc->zp1.orus[point]; + FT_Vector* vec2 = &exc->zp0.orus[exc->GS.rp0]; - if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + if ( exc->metrics.x_scale == exc->metrics.y_scale ) { /* this should be faster */ - org_dist = CUR_Func_dualproj( vec1, vec2 ); - org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale ); + org_dist = DUALPROJ( vec1, vec2 ); + org_dist = FT_MulFix( org_dist, exc->metrics.x_scale ); } else { FT_Vector vec; - vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); - vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); + vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale ); + vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale ); - org_dist = CUR_fast_dualproj( &vec ); + org_dist = FAST_DUALPROJ( &vec ); } } /* single width cut-in test */ - if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < - CUR.GS.single_width_cutin ) + if ( FT_ABS( org_dist - exc->GS.single_width_value ) < + exc->GS.single_width_cutin ) { if ( org_dist >= 0 ) - org_dist = CUR.GS.single_width_value; + org_dist = exc->GS.single_width_value; else - org_dist = -CUR.GS.single_width_value; + org_dist = -exc->GS.single_width_value; } /* round flag */ - if ( ( CUR.opcode & 4 ) != 0 ) + if ( ( exc->opcode & 4 ) != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 ) - distance = ROUND_None( +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) + distance = Round_None( + exc, org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); + exc->tt_metrics.compensations[exc->opcode & 3] ); else #endif - distance = CUR_Func_round( - org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); + distance = exc->func_round( + exc, + org_dist, + exc->tt_metrics.compensations[exc->opcode & 3] ); } else - distance = ROUND_None( + distance = Round_None( + exc, org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); + exc->tt_metrics.compensations[exc->opcode & 3] ); /* minimum distance flag */ - if ( ( CUR.opcode & 8 ) != 0 ) + if ( ( exc->opcode & 8 ) != 0 ) { if ( org_dist >= 0 ) { @@ -6509,17 +6038,16 @@ /* now move the point */ - org_dist = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); + org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); - CUR_Func_move( &CUR.zp1, point, distance - org_dist ); + exc->func_move( exc, &exc->zp1, point, distance - org_dist ); Fail: - CUR.GS.rp1 = CUR.GS.rp0; - CUR.GS.rp2 = point; + exc->GS.rp1 = exc->GS.rp0; + exc->GS.rp2 = point; - if ( ( CUR.opcode & 16 ) != 0 ) - CUR.GS.rp0 = point; + if ( ( exc->opcode & 16 ) != 0 ) + exc->GS.rp0 = point; } @@ -6530,7 +6058,8 @@ /* Stack: int32? uint32 --> */ /* */ static void - Ins_MIRP( INS_ARG ) + Ins_MIRP( TT_ExecContext exc, + FT_Long* args ) { FT_UShort point; FT_ULong cvtEntry; @@ -6541,100 +6070,99 @@ org_dist, control_value_cutin, minimum_distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Int B1 = 0; /* pacify compiler */ FT_Int B2 = 0; FT_Bool reverse_move = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - minimum_distance = CUR.GS.minimum_distance; - control_value_cutin = CUR.GS.control_value_cutin; + minimum_distance = exc->GS.minimum_distance; + control_value_cutin = exc->GS.control_value_cutin; point = (FT_UShort)args[0]; cvtEntry = (FT_ULong)( args[1] + 1 ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = minimum_distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + if ( BOUNDS( point, exc->zp1.n_points ) || + BOUNDSL( cvtEntry, exc->cvtSize + 1 ) || + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } if ( !cvtEntry ) cvt_dist = 0; else - cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); + cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 ); /* single width test */ - if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) < - CUR.GS.single_width_cutin ) + if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) < + exc->GS.single_width_cutin ) { if ( cvt_dist >= 0 ) - cvt_dist = CUR.GS.single_width_value; + cvt_dist = exc->GS.single_width_value; else - cvt_dist = -CUR.GS.single_width_value; + cvt_dist = -exc->GS.single_width_value; } /* UNDOCUMENTED! The MS rasterizer does that with */ /* twilight points (confirmed by Greg Hitchcock) */ - if ( CUR.GS.gep1 == 0 ) + if ( exc->GS.gep1 == 0 ) { - CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + - TT_MulFix14( (FT_UInt32)cvt_dist, - CUR.GS.freeVector.x ); - CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + - TT_MulFix14( (FT_UInt32)cvt_dist, - CUR.GS.freeVector.y ); - CUR.zp1.cur[point] = CUR.zp1.org[point]; + exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x + + TT_MulFix14( cvt_dist, + exc->GS.freeVector.x ); + exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y + + TT_MulFix14( cvt_dist, + exc->GS.freeVector.y ); + exc->zp1.cur[point] = exc->zp1.org[point]; } - org_dist = CUR_Func_dualproj( &CUR.zp1.org[point], - &CUR.zp0.org[CUR.GS.rp0] ); - cur_dist = CUR_Func_project ( &CUR.zp1.cur[point], - &CUR.zp0.cur[CUR.GS.rp0] ); + org_dist = DUALPROJ( &exc->zp1.org[point], &exc->zp0.org[exc->GS.rp0] ); + cur_dist = PROJECT ( &exc->zp1.cur[point], &exc->zp0.cur[exc->GS.rp0] ); /* auto-flip test */ - if ( CUR.GS.auto_flip ) + if ( exc->GS.auto_flip ) { if ( ( org_dist ^ cvt_dist ) < 0 ) cvt_dist = -cvt_dist; } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.freeVector.y != 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.y != 0 && + ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) { if ( cur_dist < -64 ) cvt_dist -= 16; else if ( cur_dist > 64 && cur_dist < 84 ) cvt_dist += 32; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* control value cut-in and round */ - if ( ( CUR.opcode & 4 ) != 0 ) + if ( ( exc->opcode & 4 ) != 0 ) { /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ /* refer to the same zone. */ - if ( CUR.GS.gep0 == CUR.GS.gep1 ) + if ( exc->GS.gep0 == exc->GS.gep1 ) { /* XXX: According to Greg Hitchcock, the following wording is */ /* the right one: */ @@ -6652,32 +6180,34 @@ cvt_dist = org_dist; } - distance = CUR_Func_round( + distance = exc->func_round( + exc, cvt_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); + exc->tt_metrics.compensations[exc->opcode & 3] ); } else { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* do cvt cut-in always in MIRP for sph */ - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.GS.gep0 == CUR.GS.gep1 ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.gep0 == exc->GS.gep1 ) { if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) cvt_dist = org_dist; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - distance = ROUND_None( + distance = Round_None( + exc, cvt_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); + exc->tt_metrics.compensations[exc->opcode & 3] ); } /* minimum distance test */ - if ( ( CUR.opcode & 8 ) != 0 ) + if ( ( exc->opcode & 8 ) != 0 ) { if ( org_dist >= 0 ) { @@ -6691,62 +6221,62 @@ } } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { - B1 = CUR.zp1.cur[point].y; + B1 = exc->zp1.cur[point].y; /* Round moves if necessary */ - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.y != 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) + if ( exc->ignore_x_mode && + exc->GS.freeVector.y != 0 && + ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist; - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.y != 0 && - ( CUR.opcode & 16 ) == 0 && - ( CUR.opcode & 8 ) == 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) + if ( exc->ignore_x_mode && + exc->GS.freeVector.y != 0 && + ( exc->opcode & 16 ) == 0 && + ( exc->opcode & 8 ) == 0 && + ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) distance += 64; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); + exc->func_move( exc, &exc->zp1, point, distance - cur_dist ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { - B2 = CUR.zp1.cur[point].y; + B2 = exc->zp1.cur[point].y; /* Reverse move if necessary */ - if ( CUR.ignore_x_mode ) + if ( exc->ignore_x_mode ) { - if ( CUR.face->sph_compatibility_mode && - CUR.GS.freeVector.y != 0 && - ( B1 & 63 ) == 0 && - ( B2 & 63 ) != 0 ) + if ( exc->face->sph_compatibility_mode && + exc->GS.freeVector.y != 0 && + ( B1 & 63 ) == 0 && + ( B2 & 63 ) != 0 ) reverse_move = TRUE; - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - CUR.GS.freeVector.y != 0 && - ( B2 & 63 ) != 0 && - ( B1 & 63 ) != 0 ) + if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && + exc->GS.freeVector.y != 0 && + ( B2 & 63 ) != 0 && + ( B1 & 63 ) != 0 ) reverse_move = TRUE; } if ( reverse_move ) - CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) ); + exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ Fail: - CUR.GS.rp1 = CUR.GS.rp0; + exc->GS.rp1 = exc->GS.rp0; - if ( ( CUR.opcode & 16 ) != 0 ) - CUR.GS.rp0 = point; + if ( ( exc->opcode & 16 ) != 0 ) + exc->GS.rp0 = point; - CUR.GS.rp2 = point; + exc->GS.rp2 = point; } @@ -6757,61 +6287,59 @@ /* Stack: uint32 uint32... --> */ /* */ static void - Ins_ALIGNRP( INS_ARG ) + Ins_ALIGNRP( TT_ExecContext exc ) { FT_UShort point; FT_F26Dot6 distance; - FT_UNUSED_ARG; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.iup_called && - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->iup_called && + ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( CUR.top < CUR.GS.loop || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + if ( exc->top < exc->GS.loop || + BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } - while ( CUR.GS.loop > 0 ) + while ( exc->GS.loop > 0 ) { - CUR.args--; + exc->args--; - point = (FT_UShort)CUR.stack[CUR.args]; + point = (FT_UShort)exc->stack[exc->args]; - if ( BOUNDS( point, CUR.zp1.n_points ) ) + if ( BOUNDS( point, exc->zp1.n_points ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } } else { - distance = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); + distance = PROJECT( exc->zp1.cur + point, + exc->zp0.cur + exc->GS.rp0 ); - CUR_Func_move( &CUR.zp1, point, -distance ); + exc->func_move( exc, &exc->zp1, point, -distance ); } - CUR.GS.loop--; + exc->GS.loop--; } Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; + exc->GS.loop = 1; + exc->new_top = exc->args; } @@ -6822,7 +6350,8 @@ /* Stack: 5 * uint32 --> */ /* */ static void - Ins_ISECT( INS_ARG ) + Ins_ISECT( TT_ExecContext exc, + FT_Long* args ) { FT_UShort point, a0, a1, @@ -6846,29 +6375,27 @@ b0 = (FT_UShort)args[3]; b1 = (FT_UShort)args[4]; - if ( BOUNDS( b0, CUR.zp0.n_points ) || - BOUNDS( b1, CUR.zp0.n_points ) || - BOUNDS( a0, CUR.zp1.n_points ) || - BOUNDS( a1, CUR.zp1.n_points ) || - BOUNDS( point, CUR.zp2.n_points ) ) + if ( BOUNDS( b0, exc->zp0.n_points ) || + BOUNDS( b1, exc->zp0.n_points ) || + BOUNDS( a0, exc->zp1.n_points ) || + BOUNDS( a1, exc->zp1.n_points ) || + BOUNDS( point, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } /* Cramer's rule */ - dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; - dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; - - dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; - day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; + dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x; + dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y; - dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; - dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; + dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x; + day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y; - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; + dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x; + dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y; discriminant = FT_MulDiv( dax, -dby, 0x40 ) + FT_MulDiv( day, dbx, 0x40 ); @@ -6890,22 +6417,26 @@ R.x = FT_MulDiv( val, dax, discriminant ); R.y = FT_MulDiv( val, day, discriminant ); - CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; - CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; + /* XXX: Block in backwards_compatibility and/or post-IUP? */ + exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x; + exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y; } else { /* else, take the middle of the middles of A and B */ - CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + - CUR.zp1.cur[a1].x + - CUR.zp0.cur[b0].x + - CUR.zp0.cur[b1].x ) / 4; - CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y + - CUR.zp1.cur[a1].y + - CUR.zp0.cur[b0].y + - CUR.zp0.cur[b1].y ) / 4; + /* XXX: Block in backwards_compatibility and/or post-IUP? */ + exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x + + exc->zp1.cur[a1].x + + exc->zp0.cur[b0].x + + exc->zp0.cur[b1].x ) / 4; + exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y + + exc->zp1.cur[a1].y + + exc->zp0.cur[b0].y + + exc->zp0.cur[b1].y ) / 4; } + + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; } @@ -6916,7 +6447,8 @@ /* Stack: uint32 uint32 --> */ /* */ static void - Ins_ALIGNPTS( INS_ARG ) + Ins_ALIGNPTS( TT_ExecContext exc, + FT_Long* args ) { FT_UShort p1, p2; FT_F26Dot6 distance; @@ -6925,19 +6457,18 @@ p1 = (FT_UShort)args[0]; p2 = (FT_UShort)args[1]; - if ( BOUNDS( p1, CUR.zp1.n_points ) || - BOUNDS( p2, CUR.zp0.n_points ) ) + if ( BOUNDS( p1, exc->zp1.n_points ) || + BOUNDS( p2, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } - distance = CUR_Func_project( CUR.zp0.cur + p2, - CUR.zp1.cur + p1 ) / 2; + distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2; - CUR_Func_move( &CUR.zp1, p1, distance ); - CUR_Func_move( &CUR.zp0, p2, -distance ); + exc->func_move( exc, &exc->zp1, p1, distance ); + exc->func_move( exc, &exc->zp0, p2, -distance ); } @@ -6951,50 +6482,48 @@ /* SOMETIMES, DUMBER CODE IS BETTER CODE */ static void - Ins_IP( INS_ARG ) + Ins_IP( TT_ExecContext exc ) { FT_F26Dot6 old_range, cur_range; FT_Vector* orus_base; FT_Vector* cur_base; FT_Int twilight; - FT_UNUSED_ARG; - - if ( CUR.top < CUR.GS.loop ) + if ( exc->top < exc->GS.loop ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } /* * We need to deal in a special way with the twilight zone. - * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0), + * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0), * for every n. */ - twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0; + twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0; - if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ) + if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); goto Fail; } if ( twilight ) - orus_base = &CUR.zp0.org[CUR.GS.rp1]; + orus_base = &exc->zp0.org[exc->GS.rp1]; else - orus_base = &CUR.zp0.orus[CUR.GS.rp1]; + orus_base = &exc->zp0.orus[exc->GS.rp1]; - cur_base = &CUR.zp0.cur[CUR.GS.rp1]; + cur_base = &exc->zp0.cur[exc->GS.rp1]; /* XXX: There are some glyphs in some braindead but popular */ /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ /* calling IP[] with bad values of rp[12]. */ /* Do something sane when this odd thing happens. */ - if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) || - BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) + if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) || + BOUNDS( exc->GS.rp2, exc->zp1.n_points ) ) { old_range = 0; cur_range = 0; @@ -7002,62 +6531,60 @@ else { if ( twilight ) - old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2], - orus_base ); - else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) - old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2], - orus_base ); + old_range = DUALPROJ( &exc->zp1.org[exc->GS.rp2], orus_base ); + else if ( exc->metrics.x_scale == exc->metrics.y_scale ) + old_range = DUALPROJ( &exc->zp1.orus[exc->GS.rp2], orus_base ); else { FT_Vector vec; - vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x, - CUR.metrics.x_scale ); - vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y, - CUR.metrics.y_scale ); + vec.x = FT_MulFix( exc->zp1.orus[exc->GS.rp2].x - orus_base->x, + exc->metrics.x_scale ); + vec.y = FT_MulFix( exc->zp1.orus[exc->GS.rp2].y - orus_base->y, + exc->metrics.y_scale ); - old_range = CUR_fast_dualproj( &vec ); + old_range = FAST_DUALPROJ( &vec ); } - cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base ); + cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base ); } - for ( ; CUR.GS.loop > 0; --CUR.GS.loop ) + for ( ; exc->GS.loop > 0; --exc->GS.loop ) { - FT_UInt point = (FT_UInt)CUR.stack[--CUR.args]; + FT_UInt point = (FT_UInt)exc->stack[--exc->args]; FT_F26Dot6 org_dist, cur_dist, new_dist; /* check point bounds */ - if ( BOUNDS( point, CUR.zp2.n_points ) ) + if ( BOUNDS( point, exc->zp2.n_points ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } continue; } if ( twilight ) - org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base ); - else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) - org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); + org_dist = DUALPROJ( &exc->zp2.org[point], orus_base ); + else if ( exc->metrics.x_scale == exc->metrics.y_scale ) + org_dist = DUALPROJ( &exc->zp2.orus[point], orus_base ); else { FT_Vector vec; - vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x, - CUR.metrics.x_scale ); - vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y, - CUR.metrics.y_scale ); + vec.x = FT_MulFix( exc->zp2.orus[point].x - orus_base->x, + exc->metrics.x_scale ); + vec.y = FT_MulFix( exc->zp2.orus[point].y - orus_base->y, + exc->metrics.y_scale ); - org_dist = CUR_fast_dualproj( &vec ); + org_dist = FAST_DUALPROJ( &vec ); } - cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); + cur_dist = PROJECT( &exc->zp2.cur[point], cur_base ); if ( org_dist ) { @@ -7068,25 +6595,34 @@ /* This is the same as what MS does for the invalid case: */ /* */ /* delta = (Original_Pt - Original_RP1) - */ - /* (Current_Pt - Current_RP1) */ + /* (Current_Pt - Current_RP1) ; */ /* */ /* In FreeType speak: */ /* */ - /* new_dist = cur_dist - */ - /* org_dist - cur_dist; */ + /* delta = org_dist - cur_dist . */ + /* */ + /* We move `point' by `new_dist - cur_dist' after leaving */ + /* this block, thus we have */ + /* */ + /* new_dist - cur_dist = delta , */ + /* new_dist - cur_dist = org_dist - cur_dist , */ + /* new_dist = org_dist . */ - new_dist = -org_dist; + new_dist = org_dist; } } else new_dist = 0; - CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); + exc->func_move( exc, + &exc->zp2, + (FT_UShort)point, + new_dist - cur_dist ); } Fail: - CUR.GS.loop = 1; - CUR.new_top = CUR.args; + exc->GS.loop = 1; + exc->new_top = exc->args; } @@ -7097,7 +6633,8 @@ /* Stack: uint32 --> */ /* */ static void - Ins_UTP( INS_ARG ) + Ins_UTP( TT_ExecContext exc, + FT_Long* args ) { FT_UShort point; FT_Byte mask; @@ -7105,22 +6642,22 @@ point = (FT_UShort)args[0]; - if ( BOUNDS( point, CUR.zp0.n_points ) ) + if ( BOUNDS( point, exc->zp0.n_points ) ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); return; } mask = 0xFF; - if ( CUR.GS.freeVector.x != 0 ) + if ( exc->GS.freeVector.x != 0 ) mask &= ~FT_CURVE_TAG_TOUCH_X; - if ( CUR.GS.freeVector.y != 0 ) + if ( exc->GS.freeVector.y != 0 ) mask &= ~FT_CURVE_TAG_TOUCH_Y; - CUR.zp0.tags[point] &= mask; + exc->zp0.tags[point] &= mask; } @@ -7165,7 +6702,7 @@ FT_UInt ref2 ) { FT_UInt i; - FT_F26Dot6 orus1, orus2, org1, org2, delta1, delta2; + FT_F26Dot6 orus1, orus2, org1, org2, cur1, cur2, delta1, delta2; if ( p1 > p2 ) @@ -7195,12 +6732,15 @@ org1 = worker->orgs[ref1].x; org2 = worker->orgs[ref2].x; - delta1 = worker->curs[ref1].x - org1; - delta2 = worker->curs[ref2].x - org2; + cur1 = worker->curs[ref1].x; + cur2 = worker->curs[ref2].x; + delta1 = cur1 - org1; + delta2 = cur2 - org2; - if ( orus1 == orus2 ) + if ( cur1 == cur2 || orus1 == orus2 ) { - /* simple shift of untouched points */ + + /* trivial snap or shift of untouched points */ for ( i = p1; i <= p2; i++ ) { FT_F26Dot6 x = worker->orgs[i].x; @@ -7208,9 +6748,13 @@ if ( x <= org1 ) x += delta1; - else + + else if ( x >= org2 ) x += delta2; + else + x = cur1; + worker->curs[i].x = x; } } @@ -7237,12 +6781,10 @@ if ( !scale_valid ) { scale_valid = 1; - scale = FT_DivFix( org2 + delta2 - ( org1 + delta1 ), - orus2 - orus1 ); + scale = FT_DivFix( cur2 - cur1, orus2 - orus1 ); } - x = ( org1 + delta1 ) + - FT_MulFix( worker->orus[i].x - orus1, scale ); + x = cur1 + FT_MulFix( worker->orus[i].x - orus1, scale ); } worker->curs[i].x = x; } @@ -7257,7 +6799,7 @@ /* Stack: --> */ /* */ static void - Ins_IUP( INS_ARG ) + Ins_IUP( TT_ExecContext exc ) { IUP_WorkerRec V; FT_Byte mask; @@ -7271,51 +6813,66 @@ FT_UInt point; /* current point */ FT_Short contour; /* current contour */ - FT_UNUSED_ARG; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility mode. */ + /* Allow IUP until it has been called on both axes. Immediately */ + /* return on subsequent ones. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) + { + if ( exc->iupx_called && exc->iupy_called ) + return; + + if ( exc->opcode & 1 ) + exc->iupx_called = TRUE; + else + exc->iupy_called = TRUE; + } +#endif /* ignore empty outlines */ - if ( CUR.pts.n_contours == 0 ) + if ( exc->pts.n_contours == 0 ) return; - if ( CUR.opcode & 1 ) + if ( exc->opcode & 1 ) { mask = FT_CURVE_TAG_TOUCH_X; - V.orgs = CUR.pts.org; - V.curs = CUR.pts.cur; - V.orus = CUR.pts.orus; + V.orgs = exc->pts.org; + V.curs = exc->pts.cur; + V.orus = exc->pts.orus; } else { mask = FT_CURVE_TAG_TOUCH_Y; - V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); - V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); - V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 ); + V.orgs = (FT_Vector*)( (FT_Pos*)exc->pts.org + 1 ); + V.curs = (FT_Vector*)( (FT_Pos*)exc->pts.cur + 1 ); + V.orus = (FT_Vector*)( (FT_Pos*)exc->pts.orus + 1 ); } - V.max_points = CUR.pts.n_points; + V.max_points = exc->pts.n_points; contour = 0; point = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode ) { - CUR.iup_called = TRUE; - if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) + exc->iup_called = TRUE; + if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) return; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ do { - end_point = CUR.pts.contours[contour] - CUR.pts.first_point; + end_point = exc->pts.contours[contour] - exc->pts.first_point; first_point = point; - if ( BOUNDS ( end_point, CUR.pts.n_points ) ) - end_point = CUR.pts.n_points - 1; + if ( BOUNDS( end_point, exc->pts.n_points ) ) + end_point = exc->pts.n_points - 1; - while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) + while ( point <= end_point && ( exc->pts.tags[point] & mask ) == 0 ) point++; if ( point <= end_point ) @@ -7327,7 +6884,7 @@ while ( point <= end_point ) { - if ( ( CUR.pts.tags[point] & mask ) != 0 ) + if ( ( exc->pts.tags[point] & mask ) != 0 ) { _iup_worker_interpolate( &V, cur_touched + 1, @@ -7359,7 +6916,7 @@ } } contour++; - } while ( contour < CUR.pts.n_contours ); + } while ( contour < exc->pts.n_contours ); } @@ -7370,61 +6927,42 @@ /* Stack: uint32 (2 * uint32)... --> */ /* */ static void - Ins_DELTAP( INS_ARG ) + Ins_DELTAP( TT_ExecContext exc, + FT_Long* args ) { - FT_ULong k, nump; + FT_ULong nump, k; FT_UShort A; - FT_ULong C; + FT_ULong C, P; FT_Long B; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_UShort B1, B2; - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.iup_called && - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->iup_called && + ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) goto Fail; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ - if ( CUR.face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; - - - if ( CUR.args < n ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - n = CUR.args; - } - - CUR.args -= n; - CUR.new_top = CUR.args; - return; - } -#endif +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + P = (FT_ULong)exc->func_cur_ppem( exc ); nump = (FT_ULong)args[0]; /* some points theoretically may occur more than once, thus UShort isn't enough */ for ( k = 1; k <= nump; k++ ) { - if ( CUR.args < 2 ) + if ( exc->args < 2 ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - CUR.args = 0; + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Too_Few_Arguments ); + exc->args = 0; goto Fail; } - CUR.args -= 2; + exc->args -= 2; - A = (FT_UShort)CUR.stack[CUR.args + 1]; - B = CUR.stack[CUR.args]; + A = (FT_UShort)exc->stack[exc->args + 1]; + B = exc->stack[exc->args]; /* XXX: Because some popular fonts contain some invalid DeltaP */ /* instructions, we simply ignore them when the stacked */ @@ -7432,11 +6970,11 @@ /* error. As a delta instruction doesn't change a glyph */ /* in great ways, this shouldn't be a problem. */ - if ( !BOUNDS( A, CUR.zp0.n_points ) ) + if ( !BOUNDS( A, exc->zp0.n_points ) ) { C = ( (FT_ULong)B & 0xF0 ) >> 4; - switch ( CUR.opcode ) + switch ( exc->opcode ) { case 0x5D: break; @@ -7450,95 +6988,102 @@ break; } - C += CUR.GS.delta_base; + C += exc->GS.delta_base; - if ( CURRENT_Ppem() == (FT_Long)C ) + if ( P == C ) { B = ( (FT_ULong)B & 0xF ) - 8; if ( B >= 0 ) B++; - B = B * 64 / ( 1L << CUR.GS.delta_shift ); + B *= 1L << ( 6 - exc->GS.delta_shift ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { /* * Allow delta move if * - * - not using ignore_x_mode rendering - * - glyph is specifically set to allow it - * - glyph is composite and freedom vector is not subpixel - * vector + * - not using ignore_x_mode rendering, + * - glyph is specifically set to allow it, or + * - glyph is composite and freedom vector is not in subpixel + * direction. */ - if ( !CUR.ignore_x_mode || - ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || - ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ) - CUR_Func_move( &CUR.zp0, A, B ); - - /* Otherwise apply subpixel hinting and */ - /* compatibility mode rules */ - else if ( CUR.ignore_x_mode ) + if ( !exc->ignore_x_mode || + ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || + ( exc->is_composite && exc->GS.freeVector.y != 0 ) ) + exc->func_move( exc, &exc->zp0, A, B ); + + /* Otherwise, apply subpixel hinting and compatibility mode */ + /* rules, always skipping deltas in subpixel direction. */ + else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 ) { - if ( CUR.GS.freeVector.y != 0 ) - B1 = CUR.zp0.cur[A].y; - else - B1 = CUR.zp0.cur[A].x; - -#if 0 - /* Standard Subpixel Hinting: Allow y move. */ - /* This messes up dejavu and may not be needed... */ - if ( !CUR.face->sph_compatibility_mode && - CUR.GS.freeVector.y != 0 ) - CUR_Func_move( &CUR.zp0, A, B ); - else -#endif /* 0 */ - - /* Compatibility Mode: Allow x or y move if point touched in */ - /* Y direction. */ - if ( CUR.face->sph_compatibility_mode && - !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) ) + /* save the y value of the point now; compare after move */ + B1 = (FT_UShort)exc->zp0.cur[A].y; + + /* Standard subpixel hinting: Allow y move for y-touched */ + /* points. This messes up DejaVu ... */ + if ( !exc->face->sph_compatibility_mode && + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) + exc->func_move( exc, &exc->zp0, A, B ); + + /* compatibility mode */ + else if ( exc->face->sph_compatibility_mode && + !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) ) { - /* save the y value of the point now; compare after move */ - B1 = CUR.zp0.cur[A].y; - - if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) + if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) B = FT_PIX_ROUND( B1 + B ) - B1; /* Allow delta move if using sph_compatibility_mode, */ /* IUP has not been called, and point is touched on Y. */ - if ( !CUR.iup_called && - ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) - CUR_Func_move( &CUR.zp0, A, B ); + if ( !exc->iup_called && + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) + exc->func_move( exc, &exc->zp0, A, B ); } - B2 = CUR.zp0.cur[A].y; + B2 = (FT_UShort)exc->zp0.cur[A].y; /* Reverse this move if it results in a disallowed move */ - if ( CUR.GS.freeVector.y != 0 && - ( ( CUR.face->sph_compatibility_mode && + if ( exc->GS.freeVector.y != 0 && + ( ( exc->face->sph_compatibility_mode && ( B1 & 63 ) == 0 && ( B2 & 63 ) != 0 ) || - ( ( CUR.sph_tweak_flags & + ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) && ( B1 & 63 ) != 0 && ( B2 & 63 ) != 0 ) ) ) - CUR_Func_move( &CUR.zp0, A, -B ); + exc->func_move( exc, &exc->zp0, A, -B ); } } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - CUR_Func_move( &CUR.zp0, A, B ); + { + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backwards compatibility */ + /* mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backwards_compatibility ) + { + if ( !( exc->iupx_called && exc->iupy_called ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) ) + exc->func_move( exc, &exc->zp0, A, B ); + } + else +#endif + exc->func_move( exc, &exc->zp0, A, B ); + } } } else - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Invalid_Reference ); + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); } Fail: - CUR.new_top = CUR.args; + exc->new_top = exc->args; } @@ -7549,55 +7094,37 @@ /* Stack: uint32 (2 * uint32)... --> */ /* */ static void - Ins_DELTAC( INS_ARG ) + Ins_DELTAC( TT_ExecContext exc, + FT_Long* args ) { FT_ULong nump, k; - FT_ULong A, C; + FT_ULong A, C, P; FT_Long B; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ - if ( CUR.face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; - - - if ( CUR.args < n ) - { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - n = CUR.args; - } - - CUR.args -= n; - CUR.new_top = CUR.args; - return; - } -#endif - + P = (FT_ULong)exc->func_cur_ppem( exc ); nump = (FT_ULong)args[0]; for ( k = 1; k <= nump; k++ ) { - if ( CUR.args < 2 ) + if ( exc->args < 2 ) { - if ( CUR.pedantic_hinting ) - CUR.error = FT_THROW( Too_Few_Arguments ); - CUR.args = 0; + if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Too_Few_Arguments ); + exc->args = 0; goto Fail; } - CUR.args -= 2; + exc->args -= 2; - A = (FT_ULong)CUR.stack[CUR.args + 1]; - B = CUR.stack[CUR.args]; + A = (FT_ULong)exc->stack[exc->args + 1]; + B = exc->stack[exc->args]; - if ( BOUNDSL( A, CUR.cvtSize ) ) + if ( BOUNDSL( A, exc->cvtSize ) ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); return; } } @@ -7605,7 +7132,7 @@ { C = ( (FT_ULong)B & 0xF0 ) >> 4; - switch ( CUR.opcode ) + switch ( exc->opcode ) { case 0x73: break; @@ -7619,22 +7146,22 @@ break; } - C += CUR.GS.delta_base; + C += exc->GS.delta_base; - if ( CURRENT_Ppem() == (FT_Long)C ) + if ( P == C ) { B = ( (FT_ULong)B & 0xF ) - 8; if ( B >= 0 ) B++; - B = B * 64 / ( 1L << CUR.GS.delta_shift ); + B *= 1L << ( 6 - exc->GS.delta_shift ); - CUR_Func_move_cvt( A, B ); + exc->func_move_cvt( exc, A, B ); } } } Fail: - CUR.new_top = CUR.args; + exc->new_top = exc->args; } @@ -7651,39 +7178,56 @@ /* Opcode range: 0x88 */ /* Stack: uint32 --> uint32 */ /* */ + /* XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May */ + /* 2015) not documented in the OpenType specification. */ + /* */ + /* Selector bit 11 is incorrectly described as bit 8, while the */ + /* real meaning of bit 8 (vertical LCD subpixels) stays */ + /* undocumented. The same mistake can be found in Greg Hitchcock's */ + /* whitepaper. */ + /* */ static void - Ins_GETINFO( INS_ARG ) + Ins_GETINFO( TT_ExecContext exc, + FT_Long* args ) { - FT_Long K; + FT_Long K; + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( exc->face ); K = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /********************************/ /* RASTERIZER VERSION */ /* Selector Bit: 0 */ /* Return Bit(s): 0-7 */ /* */ - if ( SUBPIXEL_HINTING && - ( args[0] & 1 ) != 0 && - CUR.ignore_x_mode ) + if ( SUBPIXEL_HINTING_INFINALITY && + ( args[0] & 1 ) != 0 && + exc->subpixel_hinting ) { - K = CUR.rasterizer_version; - FT_TRACE7(( "Setting rasterizer version %d\n", - CUR.rasterizer_version )); + if ( exc->ignore_x_mode ) + { + /* if in ClearType backwards compatibility mode, */ + /* we sometimes change the TrueType version dynamically */ + K = exc->rasterizer_version; + FT_TRACE6(( "Setting rasterizer version %d\n", + exc->rasterizer_version )); + } + else + K = TT_INTERPRETER_VERSION_38; } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( ( args[0] & 1 ) != 0 ) - K = TT_INTERPRETER_VERSION_35; + K = driver->interpreter_version; /********************************/ /* GLYPH ROTATED */ /* Selector Bit: 1 */ /* Return Bit(s): 8 */ /* */ - if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) + if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated ) K |= 0x80; /********************************/ @@ -7691,43 +7235,85 @@ /* Selector Bit: 2 */ /* Return Bit(s): 9 */ /* */ - if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched ) + if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched ) K |= 1 << 8; /********************************/ - /* HINTING FOR GRAYSCALE */ + /* BI-LEVEL HINTING AND */ + /* GRAYSCALE RENDERING */ /* Selector Bit: 5 */ /* Return Bit(s): 12 */ /* */ - if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) + if ( ( args[0] & 32 ) != 0 && exc->grayscale ) K |= 1 << 12; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - if ( SUBPIXEL_HINTING && - CUR.ignore_x_mode && - CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL ) { /********************************/ - /* HINTING FOR GRAYSCALE */ - /* Selector Bit: 5 */ - /* Return Bit(s): 12 */ - /* */ - if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting ) - K |= 1 << 12; - - /********************************/ /* HINTING FOR SUBPIXEL */ /* Selector Bit: 6 */ /* Return Bit(s): 13 */ /* */ - if ( ( args[0] & 64 ) != 0 && - CUR.subpixel_hinting && - CUR.rasterizer_version >= 37 ) - { + /* v40 does subpixel hinting by default. */ + if ( ( args[0] & 64 ) != 0 ) K |= 1 << 13; - /* the stuff below is irrelevant if subpixel_hinting is not set */ + /********************************/ + /* VERTICAL LCD SUBPIXELS? */ + /* Selector Bit: 8 */ + /* Return Bit(s): 15 */ + /* */ + if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean ) + K |= 1 << 15; + + /********************************/ + /* SUBPIXEL POSITIONED? */ + /* Selector Bit: 10 */ + /* Return Bit(s): 17 */ + /* */ + /* XXX: FreeType supports it, dependent on what client does? */ + if ( ( args[0] & 1024 ) != 0 ) + K |= 1 << 17; + + /********************************/ + /* SYMMETRICAL SMOOTHING */ + /* Selector Bit: 11 */ + /* Return Bit(s): 18 */ + /* */ + /* The only smoothing method FreeType supports unless someone sets */ + /* FT_LOAD_TARGET_MONO. */ + if ( ( args[0] & 2048 ) != 0 ) + K |= 1 << 18; + + /********************************/ + /* CLEARTYPE HINTING AND */ + /* GRAYSCALE RENDERING */ + /* Selector Bit: 12 */ + /* Return Bit(s): 19 */ + /* */ + /* Grayscale rendering is what FreeType does anyway unless someone */ + /* sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) */ + if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype ) + K |= 1 << 19; + } +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + + if ( SUBPIXEL_HINTING_INFINALITY && + exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 ) + { + + if ( exc->rasterizer_version >= 37 ) + { + /********************************/ + /* HINTING FOR SUBPIXEL */ + /* Selector Bit: 6 */ + /* Return Bit(s): 13 */ + /* */ + if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting ) + K |= 1 << 13; /********************************/ /* COMPATIBLE WIDTHS ENABLED */ @@ -7735,16 +7321,16 @@ /* Return Bit(s): 14 */ /* */ /* Functionality still needs to be added */ - if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths ) + if ( ( args[0] & 128 ) != 0 && exc->compatible_widths ) K |= 1 << 14; /********************************/ - /* SYMMETRICAL SMOOTHING */ + /* VERTICAL LCD SUBPIXELS? */ /* Selector Bit: 8 */ /* Return Bit(s): 15 */ /* */ /* Functionality still needs to be added */ - if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing ) + if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd ) K |= 1 << 15; /********************************/ @@ -7753,10 +7339,10 @@ /* Return Bit(s): 16 */ /* */ /* Functionality still needs to be added */ - if ( ( args[0] & 512 ) != 0 && CUR.bgr ) + if ( ( args[0] & 512 ) != 0 && exc->bgr ) K |= 1 << 16; - if ( CUR.rasterizer_version >= 38 ) + if ( exc->rasterizer_version >= 38 ) { /********************************/ /* SUBPIXEL POSITIONED? */ @@ -7764,345 +7350,74 @@ /* Return Bit(s): 17 */ /* */ /* Functionality still needs to be added */ - if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned ) + if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned ) K |= 1 << 17; + + /********************************/ + /* SYMMETRICAL SMOOTHING */ + /* Selector Bit: 11 */ + /* Return Bit(s): 18 */ + /* */ + /* Functionality still needs to be added */ + if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing ) + K |= 1 << 18; + + /********************************/ + /* GRAY CLEARTYPE */ + /* Selector Bit: 12 */ + /* Return Bit(s): 19 */ + /* */ + /* Functionality still needs to be added */ + if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype ) + K |= 1 << 19; } } } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ args[0] = K; } static void - Ins_UNKNOWN( INS_ARG ) + Ins_UNKNOWN( TT_ExecContext exc ) { - TT_DefRecord* def = CUR.IDefs; - TT_DefRecord* limit = def + CUR.numIDefs; - - FT_UNUSED_ARG; + TT_DefRecord* def = exc->IDefs; + TT_DefRecord* limit = def + exc->numIDefs; for ( ; def < limit; def++ ) { - if ( (FT_Byte)def->opc == CUR.opcode && def->active ) + if ( (FT_Byte)def->opc == exc->opcode && def->active ) { TT_CallRec* call; - if ( CUR.callTop >= CUR.callSize ) + if ( exc->callTop >= exc->callSize ) { - CUR.error = FT_THROW( Stack_Overflow ); + exc->error = FT_THROW( Stack_Overflow ); return; } - call = CUR.callStack + CUR.callTop++; + call = exc->callStack + exc->callTop++; - call->Caller_Range = CUR.curRange; - call->Caller_IP = CUR.IP + 1; + call->Caller_Range = exc->curRange; + call->Caller_IP = exc->IP + 1; call->Cur_Count = 1; - call->Cur_Restart = def->start; - call->Cur_End = def->end; + call->Def = def; - INS_Goto_CodeRange( def->range, def->start ); + Ins_Goto_CodeRange( exc, def->range, def->start ); - CUR.step_ins = FALSE; + exc->step_ins = FALSE; return; } } - CUR.error = FT_THROW( Invalid_Opcode ); + exc->error = FT_THROW( Invalid_Opcode ); } -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH - - - static - TInstruction_Function Instruct_Dispatch[256] = - { - /* Opcodes are gathered in groups of 16. */ - /* Please keep the spaces as they are. */ - - /* SVTCA y */ Ins_SVTCA, - /* SVTCA x */ Ins_SVTCA, - /* SPvTCA y */ Ins_SPVTCA, - /* SPvTCA x */ Ins_SPVTCA, - /* SFvTCA y */ Ins_SFVTCA, - /* SFvTCA x */ Ins_SFVTCA, - /* SPvTL // */ Ins_SPVTL, - /* SPvTL + */ Ins_SPVTL, - /* SFvTL // */ Ins_SFVTL, - /* SFvTL + */ Ins_SFVTL, - /* SPvFS */ Ins_SPVFS, - /* SFvFS */ Ins_SFVFS, - /* GPV */ Ins_GPV, - /* GFV */ Ins_GFV, - /* SFvTPv */ Ins_SFVTPV, - /* ISECT */ Ins_ISECT, - - /* SRP0 */ Ins_SRP0, - /* SRP1 */ Ins_SRP1, - /* SRP2 */ Ins_SRP2, - /* SZP0 */ Ins_SZP0, - /* SZP1 */ Ins_SZP1, - /* SZP2 */ Ins_SZP2, - /* SZPS */ Ins_SZPS, - /* SLOOP */ Ins_SLOOP, - /* RTG */ Ins_RTG, - /* RTHG */ Ins_RTHG, - /* SMD */ Ins_SMD, - /* ELSE */ Ins_ELSE, - /* JMPR */ Ins_JMPR, - /* SCvTCi */ Ins_SCVTCI, - /* SSwCi */ Ins_SSWCI, - /* SSW */ Ins_SSW, - - /* DUP */ Ins_DUP, - /* POP */ Ins_POP, - /* CLEAR */ Ins_CLEAR, - /* SWAP */ Ins_SWAP, - /* DEPTH */ Ins_DEPTH, - /* CINDEX */ Ins_CINDEX, - /* MINDEX */ Ins_MINDEX, - /* AlignPTS */ Ins_ALIGNPTS, - /* INS_0x28 */ Ins_UNKNOWN, - /* UTP */ Ins_UTP, - /* LOOPCALL */ Ins_LOOPCALL, - /* CALL */ Ins_CALL, - /* FDEF */ Ins_FDEF, - /* ENDF */ Ins_ENDF, - /* MDAP[0] */ Ins_MDAP, - /* MDAP[1] */ Ins_MDAP, - - /* IUP[0] */ Ins_IUP, - /* IUP[1] */ Ins_IUP, - /* SHP[0] */ Ins_SHP, - /* SHP[1] */ Ins_SHP, - /* SHC[0] */ Ins_SHC, - /* SHC[1] */ Ins_SHC, - /* SHZ[0] */ Ins_SHZ, - /* SHZ[1] */ Ins_SHZ, - /* SHPIX */ Ins_SHPIX, - /* IP */ Ins_IP, - /* MSIRP[0] */ Ins_MSIRP, - /* MSIRP[1] */ Ins_MSIRP, - /* AlignRP */ Ins_ALIGNRP, - /* RTDG */ Ins_RTDG, - /* MIAP[0] */ Ins_MIAP, - /* MIAP[1] */ Ins_MIAP, - - /* NPushB */ Ins_NPUSHB, - /* NPushW */ Ins_NPUSHW, - /* WS */ Ins_WS, - /* RS */ Ins_RS, - /* WCvtP */ Ins_WCVTP, - /* RCvt */ Ins_RCVT, - /* GC[0] */ Ins_GC, - /* GC[1] */ Ins_GC, - /* SCFS */ Ins_SCFS, - /* MD[0] */ Ins_MD, - /* MD[1] */ Ins_MD, - /* MPPEM */ Ins_MPPEM, - /* MPS */ Ins_MPS, - /* FlipON */ Ins_FLIPON, - /* FlipOFF */ Ins_FLIPOFF, - /* DEBUG */ Ins_DEBUG, - - /* LT */ Ins_LT, - /* LTEQ */ Ins_LTEQ, - /* GT */ Ins_GT, - /* GTEQ */ Ins_GTEQ, - /* EQ */ Ins_EQ, - /* NEQ */ Ins_NEQ, - /* ODD */ Ins_ODD, - /* EVEN */ Ins_EVEN, - /* IF */ Ins_IF, - /* EIF */ Ins_EIF, - /* AND */ Ins_AND, - /* OR */ Ins_OR, - /* NOT */ Ins_NOT, - /* DeltaP1 */ Ins_DELTAP, - /* SDB */ Ins_SDB, - /* SDS */ Ins_SDS, - - /* ADD */ Ins_ADD, - /* SUB */ Ins_SUB, - /* DIV */ Ins_DIV, - /* MUL */ Ins_MUL, - /* ABS */ Ins_ABS, - /* NEG */ Ins_NEG, - /* FLOOR */ Ins_FLOOR, - /* CEILING */ Ins_CEILING, - /* ROUND[0] */ Ins_ROUND, - /* ROUND[1] */ Ins_ROUND, - /* ROUND[2] */ Ins_ROUND, - /* ROUND[3] */ Ins_ROUND, - /* NROUND[0] */ Ins_NROUND, - /* NROUND[1] */ Ins_NROUND, - /* NROUND[2] */ Ins_NROUND, - /* NROUND[3] */ Ins_NROUND, - - /* WCvtF */ Ins_WCVTF, - /* DeltaP2 */ Ins_DELTAP, - /* DeltaP3 */ Ins_DELTAP, - /* DeltaCn[0] */ Ins_DELTAC, - /* DeltaCn[1] */ Ins_DELTAC, - /* DeltaCn[2] */ Ins_DELTAC, - /* SROUND */ Ins_SROUND, - /* S45Round */ Ins_S45ROUND, - /* JROT */ Ins_JROT, - /* JROF */ Ins_JROF, - /* ROFF */ Ins_ROFF, - /* INS_0x7B */ Ins_UNKNOWN, - /* RUTG */ Ins_RUTG, - /* RDTG */ Ins_RDTG, - /* SANGW */ Ins_SANGW, - /* AA */ Ins_AA, - - /* FlipPT */ Ins_FLIPPT, - /* FlipRgON */ Ins_FLIPRGON, - /* FlipRgOFF */ Ins_FLIPRGOFF, - /* INS_0x83 */ Ins_UNKNOWN, - /* INS_0x84 */ Ins_UNKNOWN, - /* ScanCTRL */ Ins_SCANCTRL, - /* SDPVTL[0] */ Ins_SDPVTL, - /* SDPVTL[1] */ Ins_SDPVTL, - /* GetINFO */ Ins_GETINFO, - /* IDEF */ Ins_IDEF, - /* ROLL */ Ins_ROLL, - /* MAX */ Ins_MAX, - /* MIN */ Ins_MIN, - /* ScanTYPE */ Ins_SCANTYPE, - /* InstCTRL */ Ins_INSTCTRL, - /* INS_0x8F */ Ins_UNKNOWN, - - /* INS_0x90 */ Ins_UNKNOWN, - /* INS_0x91 */ Ins_UNKNOWN, - /* INS_0x92 */ Ins_UNKNOWN, - /* INS_0x93 */ Ins_UNKNOWN, - /* INS_0x94 */ Ins_UNKNOWN, - /* INS_0x95 */ Ins_UNKNOWN, - /* INS_0x96 */ Ins_UNKNOWN, - /* INS_0x97 */ Ins_UNKNOWN, - /* INS_0x98 */ Ins_UNKNOWN, - /* INS_0x99 */ Ins_UNKNOWN, - /* INS_0x9A */ Ins_UNKNOWN, - /* INS_0x9B */ Ins_UNKNOWN, - /* INS_0x9C */ Ins_UNKNOWN, - /* INS_0x9D */ Ins_UNKNOWN, - /* INS_0x9E */ Ins_UNKNOWN, - /* INS_0x9F */ Ins_UNKNOWN, - - /* INS_0xA0 */ Ins_UNKNOWN, - /* INS_0xA1 */ Ins_UNKNOWN, - /* INS_0xA2 */ Ins_UNKNOWN, - /* INS_0xA3 */ Ins_UNKNOWN, - /* INS_0xA4 */ Ins_UNKNOWN, - /* INS_0xA5 */ Ins_UNKNOWN, - /* INS_0xA6 */ Ins_UNKNOWN, - /* INS_0xA7 */ Ins_UNKNOWN, - /* INS_0xA8 */ Ins_UNKNOWN, - /* INS_0xA9 */ Ins_UNKNOWN, - /* INS_0xAA */ Ins_UNKNOWN, - /* INS_0xAB */ Ins_UNKNOWN, - /* INS_0xAC */ Ins_UNKNOWN, - /* INS_0xAD */ Ins_UNKNOWN, - /* INS_0xAE */ Ins_UNKNOWN, - /* INS_0xAF */ Ins_UNKNOWN, - - /* PushB[0] */ Ins_PUSHB, - /* PushB[1] */ Ins_PUSHB, - /* PushB[2] */ Ins_PUSHB, - /* PushB[3] */ Ins_PUSHB, - /* PushB[4] */ Ins_PUSHB, - /* PushB[5] */ Ins_PUSHB, - /* PushB[6] */ Ins_PUSHB, - /* PushB[7] */ Ins_PUSHB, - /* PushW[0] */ Ins_PUSHW, - /* PushW[1] */ Ins_PUSHW, - /* PushW[2] */ Ins_PUSHW, - /* PushW[3] */ Ins_PUSHW, - /* PushW[4] */ Ins_PUSHW, - /* PushW[5] */ Ins_PUSHW, - /* PushW[6] */ Ins_PUSHW, - /* PushW[7] */ Ins_PUSHW, - - /* MDRP[00] */ Ins_MDRP, - /* MDRP[01] */ Ins_MDRP, - /* MDRP[02] */ Ins_MDRP, - /* MDRP[03] */ Ins_MDRP, - /* MDRP[04] */ Ins_MDRP, - /* MDRP[05] */ Ins_MDRP, - /* MDRP[06] */ Ins_MDRP, - /* MDRP[07] */ Ins_MDRP, - /* MDRP[08] */ Ins_MDRP, - /* MDRP[09] */ Ins_MDRP, - /* MDRP[10] */ Ins_MDRP, - /* MDRP[11] */ Ins_MDRP, - /* MDRP[12] */ Ins_MDRP, - /* MDRP[13] */ Ins_MDRP, - /* MDRP[14] */ Ins_MDRP, - /* MDRP[15] */ Ins_MDRP, - - /* MDRP[16] */ Ins_MDRP, - /* MDRP[17] */ Ins_MDRP, - /* MDRP[18] */ Ins_MDRP, - /* MDRP[19] */ Ins_MDRP, - /* MDRP[20] */ Ins_MDRP, - /* MDRP[21] */ Ins_MDRP, - /* MDRP[22] */ Ins_MDRP, - /* MDRP[23] */ Ins_MDRP, - /* MDRP[24] */ Ins_MDRP, - /* MDRP[25] */ Ins_MDRP, - /* MDRP[26] */ Ins_MDRP, - /* MDRP[27] */ Ins_MDRP, - /* MDRP[28] */ Ins_MDRP, - /* MDRP[29] */ Ins_MDRP, - /* MDRP[30] */ Ins_MDRP, - /* MDRP[31] */ Ins_MDRP, - - /* MIRP[00] */ Ins_MIRP, - /* MIRP[01] */ Ins_MIRP, - /* MIRP[02] */ Ins_MIRP, - /* MIRP[03] */ Ins_MIRP, - /* MIRP[04] */ Ins_MIRP, - /* MIRP[05] */ Ins_MIRP, - /* MIRP[06] */ Ins_MIRP, - /* MIRP[07] */ Ins_MIRP, - /* MIRP[08] */ Ins_MIRP, - /* MIRP[09] */ Ins_MIRP, - /* MIRP[10] */ Ins_MIRP, - /* MIRP[11] */ Ins_MIRP, - /* MIRP[12] */ Ins_MIRP, - /* MIRP[13] */ Ins_MIRP, - /* MIRP[14] */ Ins_MIRP, - /* MIRP[15] */ Ins_MIRP, - - /* MIRP[16] */ Ins_MIRP, - /* MIRP[17] */ Ins_MIRP, - /* MIRP[18] */ Ins_MIRP, - /* MIRP[19] */ Ins_MIRP, - /* MIRP[20] */ Ins_MIRP, - /* MIRP[21] */ Ins_MIRP, - /* MIRP[22] */ Ins_MIRP, - /* MIRP[23] */ Ins_MIRP, - /* MIRP[24] */ Ins_MIRP, - /* MIRP[25] */ Ins_MIRP, - /* MIRP[26] */ Ins_MIRP, - /* MIRP[27] */ Ins_MIRP, - /* MIRP[28] */ Ins_MIRP, - /* MIRP[29] */ Ins_MIRP, - /* MIRP[30] */ Ins_MIRP, - /* MIRP[31] */ Ins_MIRP - }; - - -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - /*************************************************************************/ /* */ /* RUN */ @@ -8130,8 +7445,6 @@ /* */ /* THIS IS THE INTERPRETER'S MAIN LOOP. */ /* */ - /* Instructions appear in the specification's order. */ - /* */ /*************************************************************************/ @@ -8143,7 +7456,7 @@ FT_Long ins_counter = 0; /* executed instructions counter */ FT_UShort i; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Byte opcode_pattern[1][2] = { /* #8 TypeMan Talk Align */ { @@ -8154,106 +7467,136 @@ FT_UShort opcode_patterns = 1; FT_UShort opcode_pointer[1] = { 0 }; FT_UShort opcode_size[1] = { 1 }; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - cur = *exc; -#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + exc->iup_called = FALSE; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - CUR.iup_called = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Toggle backwards compatibility according to what font says, except */ + /* when it's a `tricky' font that heavily relies on the interpreter to */ + /* render glyphs correctly, e.g. DFKai-SB. Backwards compatibility */ + /* hacks may break it. */ + if ( SUBPIXEL_HINTING_MINIMAL && + !FT_IS_TRICKY( &exc->face->root ) ) + exc->backwards_compatibility = !( exc->GS.instruct_control & 4 ); + else + exc->backwards_compatibility = FALSE; - /* set CVT functions */ - CUR.tt_metrics.ratio = 0; - if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) + exc->iupx_called = FALSE; + exc->iupy_called = FALSE; +#endif + + /* set PPEM and CVT functions */ + exc->tt_metrics.ratio = 0; + if ( exc->metrics.x_ppem != exc->metrics.y_ppem ) { /* non-square pixels, use the stretched routines */ - CUR.func_read_cvt = Read_CVT_Stretched; - CUR.func_write_cvt = Write_CVT_Stretched; - CUR.func_move_cvt = Move_CVT_Stretched; + exc->func_cur_ppem = Current_Ppem_Stretched; + exc->func_read_cvt = Read_CVT_Stretched; + exc->func_write_cvt = Write_CVT_Stretched; + exc->func_move_cvt = Move_CVT_Stretched; } else { /* square pixels, use normal routines */ - CUR.func_read_cvt = Read_CVT; - CUR.func_write_cvt = Write_CVT; - CUR.func_move_cvt = Move_CVT; + exc->func_cur_ppem = Current_Ppem; + exc->func_read_cvt = Read_CVT; + exc->func_write_cvt = Write_CVT; + exc->func_move_cvt = Move_CVT; } - COMPUTE_Funcs(); - COMPUTE_Round( (FT_Byte)exc->GS.round_state ); + Compute_Funcs( exc ); + Compute_Round( exc, (FT_Byte)exc->GS.round_state ); do { - CUR.opcode = CUR.code[CUR.IP]; + exc->opcode = exc->code[exc->IP]; - FT_TRACE7(( " " )); - FT_TRACE7(( opcode_name[CUR.opcode] )); - FT_TRACE7(( "\n" )); +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_Long cnt = FT_MIN( 8, exc->top ); + FT_Long n; + + + /* if tracing level is 7, show current code position */ + /* and the first few stack elements also */ + FT_TRACE6(( " " )); + FT_TRACE7(( "%06d ", exc->IP )); + FT_TRACE6(( opcode_name[exc->opcode] + 2 )); + FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A' + ? 2 + : 12 - ( *opcode_name[exc->opcode] - '0' ), + "#" )); + for ( n = 1; n <= cnt; n++ ) + FT_TRACE7(( " %d", exc->stack[exc->top - n] )); + FT_TRACE6(( "\n" )); + } +#endif /* FT_DEBUG_LEVEL_TRACE */ - if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) + if ( ( exc->length = opcode_length[exc->opcode] ) < 0 ) { - if ( CUR.IP + 1 >= CUR.codeSize ) + if ( exc->IP + 1 >= exc->codeSize ) goto LErrorCodeOverflow_; - CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; + exc->length = 2 - exc->length * exc->code[exc->IP + 1]; } - if ( CUR.IP + CUR.length > CUR.codeSize ) + if ( exc->IP + exc->length > exc->codeSize ) goto LErrorCodeOverflow_; /* First, let's check for empty stack and overflow */ - CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); + exc->args = exc->top - ( Pop_Push_Count[exc->opcode] >> 4 ); /* `args' is the top of the stack once arguments have been popped. */ /* One can also interpret it as the index of the last argument. */ - if ( CUR.args < 0 ) + if ( exc->args < 0 ) { - if ( CUR.pedantic_hinting ) + if ( exc->pedantic_hinting ) { - CUR.error = FT_THROW( Too_Few_Arguments ); + exc->error = FT_THROW( Too_Few_Arguments ); goto LErrorLabel_; } /* push zeroes onto the stack */ - for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ ) - CUR.stack[i] = 0; - CUR.args = 0; + for ( i = 0; i < Pop_Push_Count[exc->opcode] >> 4; i++ ) + exc->stack[i] = 0; + exc->args = 0; } - CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); + exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 ); /* `new_top' is the new top of the stack, after the instruction's */ /* execution. `top' will be set to `new_top' after the `switch' */ /* statement. */ - if ( CUR.new_top > CUR.stackSize ) + if ( exc->new_top > exc->stackSize ) { - CUR.error = FT_THROW( Stack_Overflow ); + exc->error = FT_THROW( Stack_Overflow ); goto LErrorLabel_; } - CUR.step_ins = TRUE; - CUR.error = FT_Err_Ok; + exc->step_ins = TRUE; + exc->error = FT_Err_Ok; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { for ( i = 0; i < opcode_patterns; i++ ) { - if ( opcode_pointer[i] < opcode_size[i] && - CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) + if ( opcode_pointer[i] < opcode_size[i] && + exc->opcode == opcode_pattern[i][opcode_pointer[i]] ) { opcode_pointer[i] += 1; if ( opcode_pointer[i] == opcode_size[i] ) { - FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n", + FT_TRACE6(( "sph: opcode ptrn: %d, %s %s\n", i, - CUR.face->root.family_name, - CUR.face->root.style_name )); + exc->face->root.family_name, + exc->face->root.style_name )); switch ( i ) { @@ -8268,17 +7611,11 @@ } } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - -#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { - FT_Long* args = CUR.stack + CUR.args; - FT_Byte opcode = CUR.opcode; - - -#undef ARRAY_BOUND_ERROR -#define ARRAY_BOUND_ERROR goto Set_Invalid_Ref + FT_Long* args = exc->stack + exc->args; + FT_Byte opcode = exc->opcode; switch ( opcode ) @@ -8289,581 +7626,543 @@ case 0x03: /* SPvTCA x */ case 0x04: /* SFvTCA y */ case 0x05: /* SFvTCA x */ - { - FT_Short AA, BB; - - - AA = (FT_Short)( ( opcode & 1 ) << 14 ); - BB = (FT_Short)( AA ^ 0x4000 ); - - if ( opcode < 4 ) - { - CUR.GS.projVector.x = AA; - CUR.GS.projVector.y = BB; - - CUR.GS.dualVector.x = AA; - CUR.GS.dualVector.y = BB; - } - else - { - GUESS_VECTOR( projVector ); - } - - if ( ( opcode & 2 ) == 0 ) - { - CUR.GS.freeVector.x = AA; - CUR.GS.freeVector.y = BB; - } - else - { - GUESS_VECTOR( freeVector ); - } - - COMPUTE_Funcs(); - } + Ins_SxyTCA( exc ); break; case 0x06: /* SPvTL // */ case 0x07: /* SPvTL + */ - DO_SPVTL + Ins_SPVTL( exc, args ); break; case 0x08: /* SFvTL // */ case 0x09: /* SFvTL + */ - DO_SFVTL + Ins_SFVTL( exc, args ); break; case 0x0A: /* SPvFS */ - DO_SPVFS + Ins_SPVFS( exc, args ); break; case 0x0B: /* SFvFS */ - DO_SFVFS + Ins_SFVFS( exc, args ); break; - case 0x0C: /* GPV */ - DO_GPV + case 0x0C: /* GPv */ + Ins_GPV( exc, args ); break; - case 0x0D: /* GFV */ - DO_GFV + case 0x0D: /* GFv */ + Ins_GFV( exc, args ); break; case 0x0E: /* SFvTPv */ - DO_SFVTPV + Ins_SFVTPV( exc ); break; case 0x0F: /* ISECT */ - Ins_ISECT( EXEC_ARG_ args ); + Ins_ISECT( exc, args ); break; case 0x10: /* SRP0 */ - DO_SRP0 + Ins_SRP0( exc, args ); break; case 0x11: /* SRP1 */ - DO_SRP1 + Ins_SRP1( exc, args ); break; case 0x12: /* SRP2 */ - DO_SRP2 + Ins_SRP2( exc, args ); break; case 0x13: /* SZP0 */ - Ins_SZP0( EXEC_ARG_ args ); + Ins_SZP0( exc, args ); break; case 0x14: /* SZP1 */ - Ins_SZP1( EXEC_ARG_ args ); + Ins_SZP1( exc, args ); break; case 0x15: /* SZP2 */ - Ins_SZP2( EXEC_ARG_ args ); + Ins_SZP2( exc, args ); break; case 0x16: /* SZPS */ - Ins_SZPS( EXEC_ARG_ args ); + Ins_SZPS( exc, args ); break; case 0x17: /* SLOOP */ - DO_SLOOP + Ins_SLOOP( exc, args ); break; case 0x18: /* RTG */ - DO_RTG + Ins_RTG( exc ); break; case 0x19: /* RTHG */ - DO_RTHG + Ins_RTHG( exc ); break; case 0x1A: /* SMD */ - DO_SMD + Ins_SMD( exc, args ); break; case 0x1B: /* ELSE */ - Ins_ELSE( EXEC_ARG_ args ); + Ins_ELSE( exc ); break; case 0x1C: /* JMPR */ - DO_JMPR + Ins_JMPR( exc, args ); break; case 0x1D: /* SCVTCI */ - DO_SCVTCI + Ins_SCVTCI( exc, args ); break; case 0x1E: /* SSWCI */ - DO_SSWCI + Ins_SSWCI( exc, args ); break; case 0x1F: /* SSW */ - DO_SSW + Ins_SSW( exc, args ); break; case 0x20: /* DUP */ - DO_DUP + Ins_DUP( args ); break; case 0x21: /* POP */ - /* nothing :-) */ + Ins_POP(); break; case 0x22: /* CLEAR */ - DO_CLEAR + Ins_CLEAR( exc ); break; case 0x23: /* SWAP */ - DO_SWAP + Ins_SWAP( args ); break; case 0x24: /* DEPTH */ - DO_DEPTH + Ins_DEPTH( exc, args ); break; case 0x25: /* CINDEX */ - DO_CINDEX + Ins_CINDEX( exc, args ); break; case 0x26: /* MINDEX */ - Ins_MINDEX( EXEC_ARG_ args ); + Ins_MINDEX( exc, args ); break; case 0x27: /* ALIGNPTS */ - Ins_ALIGNPTS( EXEC_ARG_ args ); + Ins_ALIGNPTS( exc, args ); break; case 0x28: /* ???? */ - Ins_UNKNOWN( EXEC_ARG_ args ); + Ins_UNKNOWN( exc ); break; case 0x29: /* UTP */ - Ins_UTP( EXEC_ARG_ args ); + Ins_UTP( exc, args ); break; case 0x2A: /* LOOPCALL */ - Ins_LOOPCALL( EXEC_ARG_ args ); + Ins_LOOPCALL( exc, args ); break; case 0x2B: /* CALL */ - Ins_CALL( EXEC_ARG_ args ); + Ins_CALL( exc, args ); break; case 0x2C: /* FDEF */ - Ins_FDEF( EXEC_ARG_ args ); + Ins_FDEF( exc, args ); break; case 0x2D: /* ENDF */ - Ins_ENDF( EXEC_ARG_ args ); + Ins_ENDF( exc ); break; case 0x2E: /* MDAP */ case 0x2F: /* MDAP */ - Ins_MDAP( EXEC_ARG_ args ); + Ins_MDAP( exc, args ); break; case 0x30: /* IUP */ case 0x31: /* IUP */ - Ins_IUP( EXEC_ARG_ args ); + Ins_IUP( exc ); break; case 0x32: /* SHP */ case 0x33: /* SHP */ - Ins_SHP( EXEC_ARG_ args ); + Ins_SHP( exc ); break; case 0x34: /* SHC */ case 0x35: /* SHC */ - Ins_SHC( EXEC_ARG_ args ); + Ins_SHC( exc, args ); break; case 0x36: /* SHZ */ case 0x37: /* SHZ */ - Ins_SHZ( EXEC_ARG_ args ); + Ins_SHZ( exc, args ); break; case 0x38: /* SHPIX */ - Ins_SHPIX( EXEC_ARG_ args ); + Ins_SHPIX( exc, args ); break; case 0x39: /* IP */ - Ins_IP( EXEC_ARG_ args ); + Ins_IP( exc ); break; case 0x3A: /* MSIRP */ case 0x3B: /* MSIRP */ - Ins_MSIRP( EXEC_ARG_ args ); + Ins_MSIRP( exc, args ); break; case 0x3C: /* AlignRP */ - Ins_ALIGNRP( EXEC_ARG_ args ); + Ins_ALIGNRP( exc ); break; case 0x3D: /* RTDG */ - DO_RTDG + Ins_RTDG( exc ); break; case 0x3E: /* MIAP */ case 0x3F: /* MIAP */ - Ins_MIAP( EXEC_ARG_ args ); + Ins_MIAP( exc, args ); break; case 0x40: /* NPUSHB */ - Ins_NPUSHB( EXEC_ARG_ args ); + Ins_NPUSHB( exc, args ); break; case 0x41: /* NPUSHW */ - Ins_NPUSHW( EXEC_ARG_ args ); + Ins_NPUSHW( exc, args ); break; case 0x42: /* WS */ - DO_WS - break; - - Set_Invalid_Ref: - CUR.error = FT_THROW( Invalid_Reference ); + Ins_WS( exc, args ); break; case 0x43: /* RS */ - DO_RS + Ins_RS( exc, args ); break; case 0x44: /* WCVTP */ - DO_WCVTP + Ins_WCVTP( exc, args ); break; case 0x45: /* RCVT */ - DO_RCVT + Ins_RCVT( exc, args ); break; case 0x46: /* GC */ case 0x47: /* GC */ - Ins_GC( EXEC_ARG_ args ); + Ins_GC( exc, args ); break; case 0x48: /* SCFS */ - Ins_SCFS( EXEC_ARG_ args ); + Ins_SCFS( exc, args ); break; case 0x49: /* MD */ case 0x4A: /* MD */ - Ins_MD( EXEC_ARG_ args ); + Ins_MD( exc, args ); break; case 0x4B: /* MPPEM */ - DO_MPPEM + Ins_MPPEM( exc, args ); break; case 0x4C: /* MPS */ - DO_MPS + Ins_MPS( exc, args ); break; case 0x4D: /* FLIPON */ - DO_FLIPON + Ins_FLIPON( exc ); break; case 0x4E: /* FLIPOFF */ - DO_FLIPOFF + Ins_FLIPOFF( exc ); break; case 0x4F: /* DEBUG */ - DO_DEBUG + Ins_DEBUG( exc ); break; case 0x50: /* LT */ - DO_LT + Ins_LT( args ); break; case 0x51: /* LTEQ */ - DO_LTEQ + Ins_LTEQ( args ); break; case 0x52: /* GT */ - DO_GT + Ins_GT( args ); break; case 0x53: /* GTEQ */ - DO_GTEQ + Ins_GTEQ( args ); break; case 0x54: /* EQ */ - DO_EQ + Ins_EQ( args ); break; case 0x55: /* NEQ */ - DO_NEQ + Ins_NEQ( args ); break; case 0x56: /* ODD */ - DO_ODD + Ins_ODD( exc, args ); break; case 0x57: /* EVEN */ - DO_EVEN + Ins_EVEN( exc, args ); break; case 0x58: /* IF */ - Ins_IF( EXEC_ARG_ args ); + Ins_IF( exc, args ); break; case 0x59: /* EIF */ - /* do nothing */ + Ins_EIF(); break; case 0x5A: /* AND */ - DO_AND + Ins_AND( args ); break; case 0x5B: /* OR */ - DO_OR + Ins_OR( args ); break; case 0x5C: /* NOT */ - DO_NOT + Ins_NOT( args ); break; case 0x5D: /* DELTAP1 */ - Ins_DELTAP( EXEC_ARG_ args ); + Ins_DELTAP( exc, args ); break; case 0x5E: /* SDB */ - DO_SDB + Ins_SDB( exc, args ); break; case 0x5F: /* SDS */ - DO_SDS + Ins_SDS( exc, args ); break; case 0x60: /* ADD */ - DO_ADD + Ins_ADD( args ); break; case 0x61: /* SUB */ - DO_SUB + Ins_SUB( args ); break; case 0x62: /* DIV */ - DO_DIV + Ins_DIV( exc, args ); break; case 0x63: /* MUL */ - DO_MUL + Ins_MUL( args ); break; case 0x64: /* ABS */ - DO_ABS + Ins_ABS( args ); break; case 0x65: /* NEG */ - DO_NEG + Ins_NEG( args ); break; case 0x66: /* FLOOR */ - DO_FLOOR + Ins_FLOOR( args ); break; case 0x67: /* CEILING */ - DO_CEILING + Ins_CEILING( args ); break; case 0x68: /* ROUND */ case 0x69: /* ROUND */ case 0x6A: /* ROUND */ case 0x6B: /* ROUND */ - DO_ROUND + Ins_ROUND( exc, args ); break; case 0x6C: /* NROUND */ case 0x6D: /* NROUND */ case 0x6E: /* NRRUND */ case 0x6F: /* NROUND */ - DO_NROUND + Ins_NROUND( exc, args ); break; case 0x70: /* WCVTF */ - DO_WCVTF + Ins_WCVTF( exc, args ); break; case 0x71: /* DELTAP2 */ case 0x72: /* DELTAP3 */ - Ins_DELTAP( EXEC_ARG_ args ); + Ins_DELTAP( exc, args ); break; case 0x73: /* DELTAC0 */ case 0x74: /* DELTAC1 */ case 0x75: /* DELTAC2 */ - Ins_DELTAC( EXEC_ARG_ args ); + Ins_DELTAC( exc, args ); break; case 0x76: /* SROUND */ - DO_SROUND + Ins_SROUND( exc, args ); break; case 0x77: /* S45Round */ - DO_S45ROUND + Ins_S45ROUND( exc, args ); break; case 0x78: /* JROT */ - DO_JROT + Ins_JROT( exc, args ); break; case 0x79: /* JROF */ - DO_JROF + Ins_JROF( exc, args ); break; case 0x7A: /* ROFF */ - DO_ROFF + Ins_ROFF( exc ); break; case 0x7B: /* ???? */ - Ins_UNKNOWN( EXEC_ARG_ args ); + Ins_UNKNOWN( exc ); break; case 0x7C: /* RUTG */ - DO_RUTG + Ins_RUTG( exc ); break; case 0x7D: /* RDTG */ - DO_RDTG + Ins_RDTG( exc ); break; case 0x7E: /* SANGW */ - case 0x7F: /* AA */ - /* nothing - obsolete */ + Ins_SANGW(); + break; + + case 0x7F: /* AA */ + Ins_AA(); break; case 0x80: /* FLIPPT */ - Ins_FLIPPT( EXEC_ARG_ args ); + Ins_FLIPPT( exc ); break; case 0x81: /* FLIPRGON */ - Ins_FLIPRGON( EXEC_ARG_ args ); + Ins_FLIPRGON( exc, args ); break; case 0x82: /* FLIPRGOFF */ - Ins_FLIPRGOFF( EXEC_ARG_ args ); + Ins_FLIPRGOFF( exc, args ); break; case 0x83: /* UNKNOWN */ case 0x84: /* UNKNOWN */ - Ins_UNKNOWN( EXEC_ARG_ args ); + Ins_UNKNOWN( exc ); break; case 0x85: /* SCANCTRL */ - Ins_SCANCTRL( EXEC_ARG_ args ); + Ins_SCANCTRL( exc, args ); break; - case 0x86: /* SDPVTL */ - case 0x87: /* SDPVTL */ - Ins_SDPVTL( EXEC_ARG_ args ); + case 0x86: /* SDPvTL */ + case 0x87: /* SDPvTL */ + Ins_SDPVTL( exc, args ); break; case 0x88: /* GETINFO */ - Ins_GETINFO( EXEC_ARG_ args ); + Ins_GETINFO( exc, args ); break; case 0x89: /* IDEF */ - Ins_IDEF( EXEC_ARG_ args ); + Ins_IDEF( exc, args ); break; case 0x8A: /* ROLL */ - Ins_ROLL( EXEC_ARG_ args ); + Ins_ROLL( args ); break; case 0x8B: /* MAX */ - DO_MAX + Ins_MAX( args ); break; case 0x8C: /* MIN */ - DO_MIN + Ins_MIN( args ); break; case 0x8D: /* SCANTYPE */ - Ins_SCANTYPE( EXEC_ARG_ args ); + Ins_SCANTYPE( exc, args ); break; case 0x8E: /* INSTCTRL */ - Ins_INSTCTRL( EXEC_ARG_ args ); + Ins_INSTCTRL( exc, args ); break; case 0x8F: - Ins_UNKNOWN( EXEC_ARG_ args ); + Ins_UNKNOWN( exc ); break; default: if ( opcode >= 0xE0 ) - Ins_MIRP( EXEC_ARG_ args ); + Ins_MIRP( exc, args ); else if ( opcode >= 0xC0 ) - Ins_MDRP( EXEC_ARG_ args ); + Ins_MDRP( exc, args ); else if ( opcode >= 0xB8 ) - Ins_PUSHW( EXEC_ARG_ args ); + Ins_PUSHW( exc, args ); else if ( opcode >= 0xB0 ) - Ins_PUSHB( EXEC_ARG_ args ); + Ins_PUSHB( exc, args ); else - Ins_UNKNOWN( EXEC_ARG_ args ); + Ins_UNKNOWN( exc ); } - } -#else - - Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); - -#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - if ( CUR.error ) + if ( exc->error ) { - switch ( CUR.error ) + switch ( exc->error ) { /* looking for redefined instructions */ case FT_ERR( Invalid_Opcode ): { - TT_DefRecord* def = CUR.IDefs; - TT_DefRecord* limit = def + CUR.numIDefs; + TT_DefRecord* def = exc->IDefs; + TT_DefRecord* limit = def + exc->numIDefs; for ( ; def < limit; def++ ) { - if ( def->active && CUR.opcode == (FT_Byte)def->opc ) + if ( def->active && exc->opcode == (FT_Byte)def->opc ) { TT_CallRec* callrec; - if ( CUR.callTop >= CUR.callSize ) + if ( exc->callTop >= exc->callSize ) { - CUR.error = FT_THROW( Invalid_Reference ); + exc->error = FT_THROW( Invalid_Reference ); goto LErrorLabel_; } - callrec = &CUR.callStack[CUR.callTop]; + callrec = &exc->callStack[exc->callTop]; - callrec->Caller_Range = CUR.curRange; - callrec->Caller_IP = CUR.IP + 1; + callrec->Caller_Range = exc->curRange; + callrec->Caller_IP = exc->IP + 1; callrec->Cur_Count = 1; - callrec->Cur_Restart = def->start; - callrec->Cur_End = def->end; + callrec->Def = def; - if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) + if ( Ins_Goto_CodeRange( exc, + def->range, + def->start ) == FAILURE ) goto LErrorLabel_; goto LSuiteLabel_; @@ -8871,7 +8170,7 @@ } } - CUR.error = FT_THROW( Invalid_Opcode ); + exc->error = FT_THROW( Invalid_Opcode ); goto LErrorLabel_; #if 0 @@ -8889,56 +8188,49 @@ } } - CUR.top = CUR.new_top; + exc->top = exc->new_top; - if ( CUR.step_ins ) - CUR.IP += CUR.length; + if ( exc->step_ins ) + exc->IP += exc->length; /* increment instruction counter and check if we didn't */ /* run this program for too long (e.g. infinite loops). */ - if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) + if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) return FT_THROW( Execution_Too_Long ); LSuiteLabel_: - if ( CUR.IP >= CUR.codeSize ) + if ( exc->IP >= exc->codeSize ) { - if ( CUR.callTop > 0 ) + if ( exc->callTop > 0 ) { - CUR.error = FT_THROW( Code_Overflow ); + exc->error = FT_THROW( Code_Overflow ); goto LErrorLabel_; } else goto LNo_Error_; } - } while ( !CUR.instruction_trap ); + } while ( !exc->instruction_trap ); LNo_Error_: - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - return FT_Err_Ok; LErrorCodeOverflow_: - CUR.error = FT_THROW( Code_Overflow ); + exc->error = FT_THROW( Code_Overflow ); LErrorLabel_: - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - /* If any errors have occurred, function tables may be broken. */ /* Force a re-execution of `prep' and `fpgm' tables if no */ /* bytecode debugger is run. */ - if ( CUR.error && !CUR.instruction_trap ) + if ( exc->error && + !exc->instruction_trap && + exc->curRange == tt_coderange_glyph ) { - FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error )); - exc->size->cvt_ready = FALSE; + FT_TRACE1(( " The interpreter returned error 0x%x\n", exc->error )); + exc->size->bytecode_ready = -1; + exc->size->cvt_ready = -1; } - return CUR.error; + return exc->error; } diff --git a/drivers/freetype/freetype/src/truetype/ttinterp.h b/drivers/freetype/src/truetype/ttinterp.h index 69f5011ed4..df7ce51f1c 100644 --- a/drivers/freetype/freetype/src/truetype/ttinterp.h +++ b/drivers/freetype/src/truetype/ttinterp.h @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (specification). */ /* */ -/* Copyright 1996-2007, 2010, 2012-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTINTERP_H__ -#define __TTINTERP_H__ +#ifndef TTINTERP_H_ +#define TTINTERP_H_ #include <ft2build.h> #include "ttobjs.h" @@ -26,23 +26,6 @@ FT_BEGIN_HEADER -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ - -#define EXEC_OP_ TT_ExecContext exc, -#define EXEC_OP TT_ExecContext exc -#define EXEC_ARG_ exc, -#define EXEC_ARG exc - -#else /* static implementation */ - -#define EXEC_OP_ /* void */ -#define EXEC_OP /* void */ -#define EXEC_ARG_ /* void */ -#define EXEC_ARG /* void */ - -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ - - /*************************************************************************/ /* */ /* Rounding mode constants. */ @@ -67,29 +50,38 @@ FT_BEGIN_HEADER /* Rounding function */ typedef FT_F26Dot6 - (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ); + (*TT_Round_Func)( TT_ExecContext exc, + FT_F26Dot6 distance, + FT_F26Dot6 compensation ); /* Point displacement along the freedom vector routine */ typedef void - (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone zone, - FT_UShort point, - FT_F26Dot6 distance ); + (*TT_Move_Func)( TT_ExecContext exc, + TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ); /* Distance projection along one of the projection vectors */ typedef FT_F26Dot6 - (*TT_Project_Func)( EXEC_OP_ FT_Pos dx, - FT_Pos dy ); + (*TT_Project_Func)( TT_ExecContext exc, + FT_Pos dx, + FT_Pos dy ); + + /* getting current ppem. Take care of non-square pixels if necessary */ + typedef FT_Long + (*TT_Cur_Ppem_Func)( TT_ExecContext exc ); /* reading a cvt value. Take care of non-square pixels if necessary */ typedef FT_F26Dot6 - (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong idx ); + (*TT_Get_CVT_Func)( TT_ExecContext exc, + FT_ULong idx ); /* setting or moving a cvt value. Take care of non-square pixels */ /* if necessary */ typedef void - (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong idx, - FT_F26Dot6 value ); + (*TT_Set_CVT_Func)( TT_ExecContext exc, + FT_ULong idx, + FT_F26Dot6 value ); /*************************************************************************/ @@ -101,13 +93,13 @@ FT_BEGIN_HEADER FT_Int Caller_Range; FT_Long Caller_IP; FT_Long Cur_Count; - FT_Long Cur_Restart; - FT_Long Cur_End; + + TT_DefRecord *Def; /* either FDEF or IDEF */ } TT_CallRec, *TT_CallStack; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -146,7 +138,7 @@ FT_BEGIN_HEADER } SPH_Font_Class; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /*************************************************************************/ @@ -166,11 +158,11 @@ FT_BEGIN_HEADER FT_Long top; /* top of exec. stack */ - FT_UInt stackSize; /* size of exec. stack */ + FT_Long stackSize; /* size of exec. stack */ FT_Long* stack; /* current exec. stack */ FT_Long args; - FT_UInt new_top; /* new top after exec. */ + FT_Long new_top; /* new top after exec. */ TT_GlyphZoneRec zp0, /* zone records */ zp1, @@ -228,11 +220,6 @@ FT_BEGIN_HEADER FT_F26Dot6 phase; /* `SuperRounding' */ FT_F26Dot6 threshold; -#if 0 - /* this seems to be unused */ - FT_Int cur_ppem; /* ppem along the current proj vector */ -#endif - FT_Bool instruction_trap; /* If `True', the interpreter will */ /* exit after each instruction */ @@ -254,29 +241,159 @@ FT_BEGIN_HEADER TT_Move_Func func_move; /* current point move function */ TT_Move_Func func_move_orig; /* move original position function */ + TT_Cur_Ppem_Func func_cur_ppem; /* get current proj. ppem value */ + TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ - FT_Bool grayscale; /* are we hinting for grayscale? */ - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + FT_Bool grayscale; /* bi-level hinting and */ + /* grayscale rendering */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* + * Modern TrueType fonts are usually rendered through Microsoft's + * collection of rendering techniques called ClearType (e.g., subpixel + * rendering and subpixel hinting). When ClearType was introduced, most + * fonts were not ready. Microsoft decided to implement a backwards + * compatibility mode that employed several simple to complicated + * assumptions and tricks that modified the interpretation of the + * bytecode contained in these fonts to make them look ClearType-y + * somehow. Most (web)fonts that were released since then have come to + * rely on these hacks to render correctly, even some of Microsoft's + * flagship ClearType fonts (Calibri, Cambria, Segoe UI). + * + * The minimal subpixel hinting code (interpreter version 40) employs a + * small list of font-agnostic hacks to bludgeon non-native-ClearType + * fonts (except tricky ones[1]) into submission. It will not try to + * toggle hacks for specific fonts for performance and complexity + * reasons. The focus is on modern (web)fonts rather than legacy fonts + * that were made for black-and-white rendering. + * + * Major hacks + * + * - Any point movement on the x axis is ignored (cf. `Direct_Move' and + * `Direct_Move_X'). This has the smallest code footprint and single + * biggest effect. The ClearType way to increase resolution is + * supersampling the x axis, the FreeType way is ignoring instructions + * on the x axis, which gives the same result in the majority of + * cases. + * + * - Points are not moved post-IUP (neither on the x nor on the y axis), + * except the x component of diagonal moves post-IUP (cf. + * `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point'). Post-IUP + * changes are commonly used to `fix' pixel patterns which has little + * use outside monochrome rendering. + * + * - SHPIX and DELTAP don't execute unless moving a composite on the + * y axis or moving a previously y touched point. SHPIX additionally + * denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP'). + * Both instructions are commonly used to `fix' pixel patterns for + * monochrome or Windows's GDI rendering but make little sense for + * FreeType rendering. Both can distort the outline. See [2] for + * details. + * + * - The hdmx table and modifications to phantom points are ignored. + * Bearings and advance widths remain unchanged (except rounding them + * outside the interpreter!), cf. `compute_glyph_metrics' and + * `TT_Hint_Glyph'. Letting non-native-ClearType fonts modify spacing + * might mess up spacing. + * + * Minor hacks + * + * - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP. This + * prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at + * various sizes. + * + * (Post-IUP is the state after both IUP[x] and IUP[y] have been + * executed.) + * + * The best results are achieved for fonts that were from the outset + * designed with ClearType in mind, meaning they leave the x axis mostly + * alone and don't mess with the `final' outline to produce more + * pleasing pixel patterns. The harder the designer tried to produce + * very specific patterns (`superhinting') for pre-ClearType-displays, + * the worse the results. + * + * Microsoft defines a way to turn off backwards compatibility and + * interpret instructions as before (called `native ClearType')[2][3]. + * The font designer then regains full control and is responsible for + * making the font work correctly with ClearType without any + * hand-holding by the interpreter or rasterizer[4]. The v40 + * interpreter assumes backwards compatibility by default, which can be + * turned off the same way by executing the following in the control + * program (cf. `Ins_INSTCTRL'). + * + * #PUSH 4,3 + * INSTCTRL[] + * + * [1] Tricky fonts as FreeType defines them rely on the bytecode + * interpreter to display correctly. Hacks can interfere with them, + * so they get treated like native ClearType fonts (v40 with + * backwards compatibility turned off). Cf. `TT_RunIns'. + * + * [2] Proposed by Microsoft's Greg Hitchcock in + * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx + * + * [3] Beat Stamm describes it in more detail: + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec12 + * + * [4] The list of `native ClearType' fonts is small at the time of this + * writing; I found the following on a Windows 10 Update 1511 + * installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft + * JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold), + * SimSun, NSimSun, and Yu Gothic. + * + */ + + /* Using v40 implies subpixel hinting. Used to detect interpreter */ + /* version switches. `_lean' to differentiate from the Infinality */ + /* `subpixel_hinting', which is managed differently. */ + FT_Bool subpixel_hinting_lean; + + /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */ + /* `_lean' to differentiate from the Infinality `vertical_lcd', which */ + /* is managed differently. */ + FT_Bool vertical_lcd_lean; + + /* Default to backwards compatibility mode in v40 interpreter. If */ + /* this is false, it implies the interpreter is in v35 or in native */ + /* ClearType mode. */ + FT_Bool backwards_compatibility; + + /* Useful for detecting and denying post-IUP trickery that is usually */ + /* used to fix pixel patterns (`superhinting'). */ + FT_Bool iupx_called; + FT_Bool iupy_called; + + /* ClearType hinting and grayscale rendering, as used by Universal */ + /* Windows Platform apps (Windows 8 and above). Like the standard */ + /* colorful ClearType mode, it utilizes a vastly increased virtual */ + /* resolution on the x axis. Different from bi-level hinting and */ + /* grayscale rendering, the old mode from Win9x days that roughly */ + /* adheres to the physical pixel grid on both axes. */ + FT_Bool grayscale_cleartype; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY TT_Round_Func func_round_sphn; /* subpixel rounding function */ - FT_Bool grayscale_hinting; /* Using grayscale hinting? */ FT_Bool subpixel_hinting; /* Using subpixel hinting? */ - FT_Bool native_hinting; /* Using native hinting? */ FT_Bool ignore_x_mode; /* Standard rendering mode for */ /* subpixel hinting. On if gray */ - /* or subpixel hinting is on ) */ + /* or subpixel hinting is on. */ - /* The following 4 aren't fully implemented but here for MS rasterizer */ + /* The following 6 aren't fully implemented but here for MS rasterizer */ /* compatibility. */ FT_Bool compatible_widths; /* compatible widths? */ FT_Bool symmetrical_smoothing; /* symmetrical_smoothing? */ FT_Bool bgr; /* bgr instead of rgb? */ + FT_Bool vertical_lcd; /* long side of LCD subpixel */ + /* rectangles is horizontal */ FT_Bool subpixel_positioned; /* subpixel positioned */ /* (DirectWrite ClearType)? */ + FT_Bool gray_cleartype; /* ClearType hinting but */ + /* grayscale rendering */ FT_Int rasterizer_version; /* MS rasterizer version */ @@ -288,7 +405,7 @@ FT_BEGIN_HEADER FT_ULong sph_in_func_flags; /* flags to indicate if in */ /* special functions */ -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ } TT_ExecContextRec; @@ -297,18 +414,18 @@ FT_BEGIN_HEADER #ifdef TT_USE_BYTECODE_INTERPRETER - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) TT_Goto_CodeRange( TT_ExecContext exec, FT_Int range, FT_Long IP ); - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) TT_Set_CodeRange( TT_ExecContext exec, FT_Int range, void* base, FT_Long length ); - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) TT_Clear_CodeRange( TT_ExecContext exec, FT_Int range ); @@ -316,7 +433,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) Update_Max( FT_Memory memory, FT_ULong* size, - FT_Long multiplier, + FT_ULong multiplier, void* _pbuff, FT_ULong new_max ); #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -340,13 +457,14 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* Only the glyph loader and debugger should call this function. */ + /* (And right now only the glyph loader uses it.) */ /* */ FT_EXPORT( TT_ExecContext ) TT_New_Context( TT_Driver driver ); #ifdef TT_USE_BYTECODE_INTERPRETER - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) TT_Done_Context( TT_ExecContext exec ); FT_LOCAL( FT_Error ) @@ -354,13 +472,12 @@ FT_BEGIN_HEADER TT_Face face, TT_Size size ); - FT_LOCAL( FT_Error ) + FT_LOCAL( void ) TT_Save_Context( TT_ExecContext exec, TT_Size ins ); FT_LOCAL( FT_Error ) - TT_Run_Context( TT_ExecContext exec, - FT_Bool debug ); + TT_Run_Context( TT_ExecContext exec ); #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -391,7 +508,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTINTERP_H__ */ +#endif /* TTINTERP_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttobjs.c b/drivers/freetype/src/truetype/ttobjs.c index 7897efa77a..ed3be2dbee 100644 --- a/drivers/freetype/freetype/src/truetype/ttobjs.c +++ b/drivers/freetype/src/truetype/ttobjs.c @@ -4,7 +4,7 @@ /* */ /* Objects manager (body). */ /* */ -/* Copyright 1996-2013 */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,10 +32,6 @@ #include "ttinterp.h" #endif -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#include FT_TRUETYPE_UNPATENTED_H -#endif - #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include "ttgxvar.h" #endif @@ -150,20 +146,21 @@ tt_check_trickyness_family( FT_String* name ) { -#define TRICK_NAMES_MAX_CHARACTERS 16 -#define TRICK_NAMES_COUNT 8 +#define TRICK_NAMES_MAX_CHARACTERS 19 +#define TRICK_NAMES_COUNT 9 static const char trick_names[TRICK_NAMES_COUNT] [TRICK_NAMES_MAX_CHARACTERS + 1] = { - "DFKaiSho-SB", /* dfkaisb.ttf */ + "DFKaiSho-SB", /* dfkaisb.ttf */ "DFKaiShu", - "DFKai-SB", /* kaiu.ttf */ - "HuaTianKaiTi?", /* htkt2.ttf */ - "HuaTianSongTi?", /* htst3.ttf */ - "MingLiU", /* mingliu.ttf & mingliu.ttc */ - "PMingLiU", /* mingliu.ttc */ - "MingLi43", /* mingli.ttf */ + "DFKai-SB", /* kaiu.ttf */ + "HuaTianKaiTi?", /* htkt2.ttf */ + "HuaTianSongTi?", /* htst3.ttf */ + "Ming(for ISO10646)", /* hkscsiic.ttf & iicore.ttf */ + "MingLiU", /* mingliu.ttf & mingliu.ttc */ + "PMingLiU", /* mingliu.ttc */ + "MingLi43", /* mingli.ttf */ }; int nn; @@ -190,7 +187,7 @@ { FT_Error error; FT_UInt32 checksum = 0; - int i; + FT_UInt i; if ( FT_FRAME_ENTER( length ) ) @@ -199,8 +196,8 @@ for ( ; length > 3; length -= 4 ) checksum += (FT_UInt32)FT_GET_ULONG(); - for ( i = 3; length > 0; length --, i-- ) - checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) ); + for ( i = 3; length > 0; length--, i-- ) + checksum += (FT_UInt32)FT_GET_BYTE() << ( i * 8 ); FT_FRAME_EXIT(); @@ -245,7 +242,7 @@ tt_check_trickyness_sfnt_ids( TT_Face face ) { #define TRICK_SFNT_IDS_PER_FACE 3 -#define TRICK_SFNT_IDS_NUM_FACES 17 +#define TRICK_SFNT_IDS_NUM_FACES 18 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] [TRICK_SFNT_IDS_PER_FACE] = { @@ -255,89 +252,94 @@ #define TRICK_SFNT_ID_prep 2 { /* MingLiU 1995 */ - { 0x05bcf058, 0x000002e4 }, /* cvt */ - { 0x28233bf1, 0x000087c4 }, /* fpgm */ - { 0xa344a1ea, 0x000001e1 } /* prep */ + { 0x05BCF058UL, 0x000002E4UL }, /* cvt */ + { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */ + { 0xA344A1EAUL, 0x000001E1UL } /* prep */ }, { /* MingLiU 1996- */ - { 0x05bcf058, 0x000002e4 }, /* cvt */ - { 0x28233bf1, 0x000087c4 }, /* fpgm */ - { 0xa344a1eb, 0x000001e1 } /* prep */ + { 0x05BCF058UL, 0x000002E4UL }, /* cvt */ + { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */ + { 0xA344A1EBUL, 0x000001E1UL } /* prep */ }, { /* DFKaiShu */ - { 0x11e5ead4, 0x00000350 }, /* cvt */ - { 0x5a30ca3b, 0x00009063 }, /* fpgm */ - { 0x13a42602, 0x0000007e } /* prep */ + { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ + { 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */ + { 0x13A42602UL, 0x0000007EUL } /* prep */ + }, + { /* DFKaiShu2 */ + { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ + { 0xA6E78C01UL, 0x00008998UL }, /* fpgm */ + { 0x13A42602UL, 0x0000007EUL } /* prep */ }, { /* HuaTianKaiTi */ - { 0xfffbfffc, 0x00000008 }, /* cvt */ - { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */ - { 0x70020112, 0x00000008 } /* prep */ + { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */ + { 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */ + { 0x70020112UL, 0x00000008UL } /* prep */ }, { /* HuaTianSongTi */ - { 0xfffbfffc, 0x00000008 }, /* cvt */ - { 0x0a5a0483, 0x00017c39 }, /* fpgm */ - { 0x70020112, 0x00000008 } /* prep */ + { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */ + { 0x0A5A0483UL, 0x00017C39UL }, /* fpgm */ + { 0x70020112UL, 0x00000008UL } /* prep */ }, { /* NEC fadpop7.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x40c92555, 0x000000e5 }, /* fpgm */ - { 0xa39b58e3, 0x0000117c } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x40C92555UL, 0x000000E5UL }, /* fpgm */ + { 0xA39B58E3UL, 0x0000117CUL } /* prep */ }, { /* NEC fadrei5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x33c41652, 0x000000e5 }, /* fpgm */ - { 0x26d6c52a, 0x00000f6a } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x33C41652UL, 0x000000E5UL }, /* fpgm */ + { 0x26D6C52AUL, 0x00000F6AUL } /* prep */ }, { /* NEC fangot7.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x6db1651d, 0x0000019d }, /* fpgm */ - { 0x6c6e4b03, 0x00002492 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x6DB1651DUL, 0x0000019DUL }, /* fpgm */ + { 0x6C6E4B03UL, 0x00002492UL } /* prep */ }, { /* NEC fangyo5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x40c92555, 0x000000e5 }, /* fpgm */ - { 0xde51fad0, 0x0000117c } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x40C92555UL, 0x000000E5UL }, /* fpgm */ + { 0xDE51FAD0UL, 0x0000117CUL } /* prep */ }, { /* NEC fankyo5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x85e47664, 0x000000e5 }, /* fpgm */ - { 0xa6c62831, 0x00001caa } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x85E47664UL, 0x000000E5UL }, /* fpgm */ + { 0xA6C62831UL, 0x00001CAAUL } /* prep */ }, { /* NEC fanrgo5.ttf */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x2d891cfd, 0x0000019d }, /* fpgm */ - { 0xa0604633, 0x00001de8 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x2D891CFDUL, 0x0000019DUL }, /* fpgm */ + { 0xA0604633UL, 0x00001DE8UL } /* prep */ }, { /* NEC fangot5.ttc */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x40aa774c, 0x000001cb }, /* fpgm */ - { 0x9b5caa96, 0x00001f9a } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x40AA774CUL, 0x000001CBUL }, /* fpgm */ + { 0x9B5CAA96UL, 0x00001F9AUL } /* prep */ }, { /* NEC fanmin3.ttc */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x0d3de9cb, 0x00000141 }, /* fpgm */ - { 0xd4127766, 0x00002280 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x0D3DE9CBUL, 0x00000141UL }, /* fpgm */ + { 0xD4127766UL, 0x00002280UL } /* prep */ }, { /* NEC FA-Gothic, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x4a692698, 0x000001f0 }, /* fpgm */ - { 0x340d4346, 0x00001fca } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x4A692698UL, 0x000001F0UL }, /* fpgm */ + { 0x340D4346UL, 0x00001FCAUL } /* prep */ }, { /* NEC FA-Minchou, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0xcd34c604, 0x00000166 }, /* fpgm */ - { 0x6cf31046, 0x000022b0 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0xCD34C604UL, 0x00000166UL }, /* fpgm */ + { 0x6CF31046UL, 0x000022B0UL } /* prep */ }, { /* NEC FA-RoundGothicB, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0x5da75315, 0x0000019d }, /* fpgm */ - { 0x40745a5f, 0x000022e0 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0x5DA75315UL, 0x0000019DUL }, /* fpgm */ + { 0x40745A5FUL, 0x000022E0UL } /* prep */ }, { /* NEC FA-RoundGothicM, 1996 */ - { 0x00000000, 0x00000000 }, /* cvt */ - { 0xf055fc48, 0x000001c2 }, /* fpgm */ - { 0x3900ded3, 0x00001e18 } /* prep */ + { 0x00000000UL, 0x00000000UL }, /* cvt */ + { 0xF055FC48UL, 0x000001C2UL }, /* fpgm */ + { 0x3900DED3UL, 0x00001E18UL } /* prep */ } }; @@ -396,11 +398,11 @@ for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) { if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) return TRUE; } @@ -489,7 +491,10 @@ /* <Input> */ /* stream :: The source font stream. */ /* */ - /* face_index :: The index of the font face in the resource. */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ /* */ /* num_params :: Number of additional generic parameters. Ignored. */ /* */ @@ -532,6 +537,10 @@ /* check that we have a valid TrueType file */ error = sfnt->init_face( stream, face, face_index, num_params, params ); + + /* Stream may have changed. */ + stream = face->root.stream; + if ( error ) goto Exit; @@ -594,7 +603,7 @@ ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; } -#else +#else /* !FT_CONFIG_OPTION_INCREMENTAL */ if ( !error ) error = tt_face_load_loca( face, stream ); @@ -618,32 +627,55 @@ ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; } -#endif +#endif /* !FT_CONFIG_OPTION_INCREMENTAL */ } -#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ - !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT { - FT_Bool unpatented_hinting; - int i; - + FT_Int instance_index = face_index >> 16; - /* Determine whether unpatented hinting is to be used for this face. */ - unpatented_hinting = FT_BOOL - ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL ); - for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) - if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) - unpatented_hinting = TRUE; + if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && + instance_index > 0 ) + { + error = TT_Get_MM_Var( face, NULL ); + if ( error ) + goto Exit; - if ( !unpatented_hinting ) - ttface->internal->ignore_unpatented_hinter = TRUE; + if ( face->blend->mmvar->namedstyle ) + { + FT_Memory memory = ttface->memory; + + FT_Var_Named_Style* named_style; + FT_String* style_name; + + + /* in `face_index', the instance index starts with value 1 */ + named_style = face->blend->mmvar->namedstyle + instance_index - 1; + error = sfnt->get_name( face, + (FT_UShort)named_style->strid, + &style_name ); + if ( error ) + goto Exit; + + /* set style name; if already set, replace it */ + if ( face->root.style_name ) + FT_FREE( face->root.style_name ); + face->root.style_name = style_name; + + /* finally, select the named instance */ + error = TT_Set_Var_Design( face, + face->blend->mmvar->num_axis, + named_style->coords ); + if ( error ) + goto Exit; + } + } } -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && - !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /* initialize standard glyph loading routines */ TT_Init_Glyph_Loading( face ); @@ -746,16 +778,11 @@ FT_Error error; - /* debugging instances have their own context */ - if ( size->debug ) - exec = size->context; - else - exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; - - if ( !exec ) - return FT_THROW( Could_Not_Find_Context ); + exec = size->context; - TT_Load_Context( exec, face, size ); + error = TT_Load_Context( exec, face, size ); + if ( error ) + return error; exec->callTop = 0; exec->top = 0; @@ -788,7 +815,7 @@ TT_Set_CodeRange( exec, tt_coderange_font, face->font_program, - face->font_program_size ); + (FT_Long)face->font_program_size ); /* disable CVT and glyph programs coderange */ TT_Clear_CodeRange( exec, tt_coderange_cvt ); @@ -796,18 +823,16 @@ if ( face->font_program_size > 0 ) { - error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); + TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); - if ( !error ) - { - FT_TRACE4(( "Executing `fpgm' table.\n" )); - - error = face->interpreter( exec ); - } + FT_TRACE4(( "Executing `fpgm' table.\n" )); + error = face->interpreter( exec ); } else error = FT_Err_Ok; + size->bytecode_ready = error; + if ( !error ) TT_Save_Context( exec, size ); @@ -840,16 +865,11 @@ FT_Error error; - /* debugging instances have their own context */ - if ( size->debug ) - exec = size->context; - else - exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; - - if ( !exec ) - return FT_THROW( Could_Not_Find_Context ); + exec = size->context; - TT_Load_Context( exec, face, size ); + error = TT_Load_Context( exec, face, size ); + if ( error ) + return error; exec->callTop = 0; exec->top = 0; @@ -861,24 +881,23 @@ TT_Set_CodeRange( exec, tt_coderange_cvt, face->cvt_program, - face->cvt_program_size ); + (FT_Long)face->cvt_program_size ); TT_Clear_CodeRange( exec, tt_coderange_glyph ); if ( face->cvt_program_size > 0 ) { - error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); + TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); - if ( !error && !size->debug ) - { - FT_TRACE4(( "Executing `prep' table.\n" )); + FT_TRACE4(( "Executing `prep' table.\n" )); - error = face->interpreter( exec ); - } + error = face->interpreter( exec ); } else error = FT_Err_Ok; + size->cvt_ready = error; + /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */ /* graphics state variables to be modified by the CVT program. */ @@ -907,10 +926,6 @@ return error; } -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - -#ifdef TT_USE_BYTECODE_INTERPRETER static void tt_size_done_bytecode( FT_Size ftsize ) @@ -919,12 +934,10 @@ TT_Face face = (TT_Face)ftsize->face; FT_Memory memory = face->root.memory; - - if ( size->debug ) + if ( size->context ) { - /* the debug context must be deleted by the debugger itself */ + TT_Done_Context( size->context ); size->context = NULL; - size->debug = FALSE; } FT_FREE( size->cvt ); @@ -948,8 +961,8 @@ size->max_func = 0; size->max_ins = 0; - size->bytecode_ready = 0; - size->cvt_ready = 0; + size->bytecode_ready = -1; + size->cvt_ready = -1; } @@ -963,14 +976,25 @@ TT_Size size = (TT_Size)ftsize; TT_Face face = (TT_Face)ftsize->face; FT_Memory memory = face->root.memory; - FT_Int i; FT_UShort n_twilight; TT_MaxProfile* maxp = &face->max_profile; - size->bytecode_ready = 1; - size->cvt_ready = 0; + /* clean up bytecode related data */ + FT_FREE( size->function_defs ); + FT_FREE( size->instruction_defs ); + FT_FREE( size->cvt ); + FT_FREE( size->storage ); + + if ( size->context ) + TT_Done_Context( size->context ); + tt_glyphzone_done( &size->twilight ); + + size->bytecode_ready = -1; + size->cvt_ready = -1; + + size->context = TT_New_Context( (TT_Driver)face->root.driver ); size->max_function_defs = maxp->maxFunctionDefs; size->max_instruction_defs = maxp->maxInstructionDefs; @@ -992,9 +1016,11 @@ metrics->rotated = FALSE; metrics->stretched = FALSE; - /* set default compensation (all 0) */ - for ( i = 0; i < 4; i++ ) - metrics->compensations[i] = 0; + /* set default engine compensation */ + metrics->compensations[0] = 0; /* gray */ + metrics->compensations[1] = 0; /* black */ + metrics->compensations[2] = 0; /* white */ + metrics->compensations[3] = 0; /* reserved */ } /* allocate function defs, instruction defs, cvt, and storage area */ @@ -1030,7 +1056,15 @@ } /* Fine, now run the font program! */ + + /* In case of an error while executing `fpgm', we intentionally don't */ + /* clean up immediately – bugs in the `fpgm' are so fundamental that */ + /* all following hinting calls should fail. Additionally, `fpgm' is */ + /* to be executed just once; calling it again is completely useless */ + /* and might even lead to extremely slow behaviour if it is malformed */ + /* (containing an infinite loop, for example). */ error = tt_size_run_fpgm( size, pedantic ); + return error; Exit: if ( error ) @@ -1047,15 +1081,14 @@ FT_Error error = FT_Err_Ok; - if ( !size->bytecode_ready ) - { + if ( size->bytecode_ready < 0 ) error = tt_size_init_bytecode( (FT_Size)size, pedantic ); - if ( error ) - goto Exit; - } + + if ( error || size->bytecode_ready ) + goto Exit; /* rescale CVT when needed */ - if ( !size->cvt_ready ) + if ( size->cvt_ready < 0 ) { FT_UInt i; TT_Face face = (TT_Face)size->root.face; @@ -1082,8 +1115,6 @@ size->GS = tt_default_graphics_state; error = tt_size_run_prep( size, pedantic ); - if ( !error ) - size->cvt_ready = 1; } Exit: @@ -1113,9 +1144,10 @@ TT_Size size = (TT_Size)ttsize; FT_Error error = FT_Err_Ok; + #ifdef TT_USE_BYTECODE_INTERPRETER - size->bytecode_ready = 0; - size->cvt_ready = 0; + size->bytecode_ready = -1; + size->cvt_ready = -1; #endif size->ttmetrics.valid = FALSE; @@ -1143,8 +1175,7 @@ #ifdef TT_USE_BYTECODE_INTERPRETER - if ( size->bytecode_ready ) - tt_size_done_bytecode( ttsize ); + tt_size_done_bytecode( ttsize ); #endif size->ttmetrics.valid = FALSE; @@ -1224,7 +1255,7 @@ } #ifdef TT_USE_BYTECODE_INTERPRETER - size->cvt_ready = 0; + size->cvt_ready = -1; #endif /* TT_USE_BYTECODE_INTERPRETER */ if ( !error ) @@ -1256,14 +1287,12 @@ TT_Driver driver = (TT_Driver)ttdriver; - - if ( !TT_New_Context( driver ) ) - return FT_THROW( Could_Not_Find_Context ); - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - driver->interpreter_version = TT_INTERPRETER_VERSION_38; -#else driver->interpreter_version = TT_INTERPRETER_VERSION_35; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + driver->interpreter_version = TT_INTERPRETER_VERSION_38; +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + driver->interpreter_version = TT_INTERPRETER_VERSION_40; #endif #else /* !TT_USE_BYTECODE_INTERPRETER */ @@ -1290,20 +1319,7 @@ FT_LOCAL_DEF( void ) tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ { -#ifdef TT_USE_BYTECODE_INTERPRETER - TT_Driver driver = (TT_Driver)ttdriver; - - - /* destroy the execution context */ - if ( driver->context ) - { - TT_Done_Context( driver->context ); - driver->context = NULL; - } -#else FT_UNUSED( ttdriver ); -#endif - } diff --git a/drivers/freetype/freetype/src/truetype/ttobjs.h b/drivers/freetype/src/truetype/ttobjs.h index a11dd3752a..ed61a7d517 100644 --- a/drivers/freetype/freetype/src/truetype/ttobjs.h +++ b/drivers/freetype/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2009, 2011-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTOBJS_H__ -#define __TTOBJS_H__ +#ifndef TTOBJS_H_ +#define TTOBJS_H_ #include <ft2build.h> @@ -42,17 +42,6 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Type> */ - /* TT_Instance */ - /* */ - /* <Description> */ - /* A handle to a TrueType size object. */ - /* */ - typedef struct TT_SizeRec_* TT_Size; - - - /*************************************************************************/ - /* */ - /* <Type> */ /* TT_GlyphSlot */ /* */ /* <Description> */ @@ -83,10 +72,6 @@ FT_BEGIN_HEADER FT_UnitVector projVector; FT_UnitVector freeVector; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_Bool both_x_axis; -#endif - FT_Long loop; FT_F26Dot6 minimum_distance; FT_Int round_state; @@ -95,8 +80,8 @@ FT_BEGIN_HEADER FT_F26Dot6 control_value_cutin; FT_F26Dot6 single_width_cutin; FT_F26Dot6 single_width_value; - FT_Short delta_base; - FT_Short delta_shift; + FT_UShort delta_base; + FT_UShort delta_shift; FT_Byte instruct_control; /* According to Greg Hitchcock from Microsoft, the `scan_control' */ @@ -160,7 +145,7 @@ FT_BEGIN_HEADER typedef struct TT_CodeRange_ { FT_Byte* base; - FT_ULong size; + FT_Long size; } TT_CodeRange; @@ -324,17 +309,12 @@ FT_BEGIN_HEADER TT_GlyphZoneRec twilight; /* The instance's twilight zone */ - /* debugging variables */ - - /* When using the debugger, we must keep the */ - /* execution context tied to the instance */ - /* object rather than asking it on demand. */ - - FT_Bool debug; TT_ExecContext context; - FT_Bool bytecode_ready; - FT_Bool cvt_ready; + /* if negative, `fpgm' (resp. `prep'), wasn't executed yet; */ + /* otherwise it is the returned error code */ + FT_Error bytecode_ready; + FT_Error cvt_ready; #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -349,7 +329,6 @@ FT_BEGIN_HEADER { FT_DriverRec root; - TT_ExecContext context; /* execution context */ TT_GlyphZoneRec zone; /* glyph loader points zone */ FT_UInt interpreter_version; @@ -436,7 +415,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTOBJS_H__ */ +#endif /* TTOBJS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttpic.c b/drivers/freetype/src/truetype/ttpic.c index edefae72c5..54a5b8bed6 100644 --- a/drivers/freetype/freetype/src/truetype/ttpic.c +++ b/drivers/freetype/src/truetype/ttpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for truetype module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/truetype/ttpic.h b/drivers/freetype/src/truetype/ttpic.h index cfb4ee6281..f725865c5c 100644 --- a/drivers/freetype/freetype/src/truetype/ttpic.h +++ b/drivers/freetype/src/truetype/ttpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for truetype module. */ /* */ -/* Copyright 2009, 2012, 2013 by */ +/* Copyright 2009-2016 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,11 +16,12 @@ /***************************************************************************/ -#ifndef __TTPIC_H__ -#define __TTPIC_H__ +#ifndef TTPIC_H_ +#define TTPIC_H_ -FT_BEGIN_HEADER +#include FT_INTERNAL_PIC_H + #ifndef FT_CONFIG_OPTION_PIC @@ -37,6 +38,8 @@ FT_BEGIN_HEADER #include FT_SERVICE_PROPERTIES_H +FT_BEGIN_HEADER + typedef struct TTModulePIC_ { FT_ServiceDescRec* tt_services; @@ -68,14 +71,13 @@ FT_BEGIN_HEADER FT_Error tt_driver_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ - -FT_END_HEADER - -#endif /* __TTPIC_H__ */ +#endif /* TTPIC_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttpload.c b/drivers/freetype/src/truetype/ttpload.c index 9723a515b9..ca158ac50b 100644 --- a/drivers/freetype/freetype/src/truetype/ttpload.c +++ b/drivers/freetype/src/truetype/ttpload.c @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (body). */ /* */ -/* Copyright 1996-2002, 2004-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -118,40 +118,52 @@ /* we only handle the case where `maxp' gives a larger value */ if ( face->num_locations <= (FT_ULong)face->root.num_glyphs ) { - FT_Long new_loca_len = - ( (FT_Long)( face->root.num_glyphs ) + 1 ) << shift; + FT_ULong new_loca_len = + ( (FT_ULong)face->root.num_glyphs + 1 ) << shift; TT_Table entry = face->dir_tables; TT_Table limit = entry + face->num_tables; - FT_Long pos = FT_Stream_Pos( stream ); - FT_Long dist = 0x7FFFFFFFL; + FT_Long pos = (FT_Long)FT_STREAM_POS(); + FT_Long dist = 0x7FFFFFFFL; + FT_Bool found = 0; /* compute the distance to next table in font file */ for ( ; entry < limit; entry++ ) { - FT_Long diff = entry->Offset - pos; + FT_Long diff = (FT_Long)entry->Offset - pos; if ( diff > 0 && diff < dist ) - dist = diff; + { + dist = diff; + found = 1; + } } - if ( entry == limit ) + if ( !found ) { /* `loca' is the last table */ - dist = stream->size - pos; + dist = (FT_Long)stream->size - pos; } - if ( new_loca_len <= dist ) + if ( new_loca_len <= (FT_ULong)dist ) { - face->num_locations = face->root.num_glyphs + 1; + face->num_locations = (FT_ULong)face->root.num_glyphs + 1; table_len = new_loca_len; FT_TRACE2(( "adjusting num_locations to %d\n", face->num_locations )); } + else + { + face->root.num_glyphs = face->num_locations + ? (FT_Long)face->num_locations - 1 : 0; + + FT_TRACE2(( "adjusting num_glyphs to %d\n", + face->root.num_glyphs )); + } } } @@ -214,7 +226,8 @@ if ( pos1 > face->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," + " too large offset=0x%08lx found for gid=0x%04lx,\n" + " " " exceeding the end of glyf table (0x%08lx)\n", pos1, gindex, face->glyf_len )); *asize = 0; @@ -224,7 +237,8 @@ if ( pos2 > face->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," + " too large offset=0x%08lx found for gid=0x%04lx,\n" + " " " truncate at the end of glyf table (0x%08lx)\n", pos2, gindex + 1, face->glyf_len )); pos2 = face->glyf_len; @@ -508,9 +522,9 @@ record_size = FT_NEXT_ULONG( p ); /* The maximum number of bytes in an hdmx device record is the */ - /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */ - /* the reason why `record_size' is a long (which we read as */ - /* unsigned long for convenience). In practice, two bytes */ + /* maximum number of glyphs + 2; this is 0xFFFF + 2, thus */ + /* explaining why `record_size' is a long (which we read as */ + /* unsigned long for convenience). In practice, two bytes are */ /* sufficient to hold the size value. */ /* */ /* There are at least two fonts, HANNOM-A and HANNOM-B version */ @@ -522,8 +536,10 @@ record_size &= 0xFFFFU; /* The limit for `num_records' is a heuristic value. */ - - if ( version != 0 || num_records > 255 || record_size > 0x10001L ) + if ( version != 0 || + num_records > 255 || + record_size > 0x10001L || + record_size < 4 ) { error = FT_THROW( Invalid_File_Format ); goto Fail; diff --git a/drivers/freetype/freetype/src/truetype/ttpload.h b/drivers/freetype/src/truetype/ttpload.h index f61ac079ce..aa2e38e6e7 100644 --- a/drivers/freetype/freetype/src/truetype/ttpload.h +++ b/drivers/freetype/src/truetype/ttpload.h @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTPLOAD_H__ -#define __TTPLOAD_H__ +#ifndef TTPLOAD_H_ +#define TTPLOAD_H_ #include <ft2build.h> @@ -69,7 +69,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTPLOAD_H__ */ +#endif /* TTPLOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttsubpix.c b/drivers/freetype/src/truetype/ttsubpix.c index 28470ad655..03950960a4 100644 --- a/drivers/freetype/freetype/src/truetype/ttsubpix.c +++ b/drivers/freetype/src/truetype/ttsubpix.c @@ -4,7 +4,7 @@ /* */ /* TrueType Subpixel Hinting. */ /* */ -/* Copyright 2010-2013 by */ +/* Copyright 2010-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,7 +27,7 @@ #include "ttsubpix.h" -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -63,8 +63,8 @@ /* rules below. A blank entry "" is required at the end of these! */ #define FAMILY_CLASS_RULES_SIZE 7 - static const SPH_Font_Class FAMILY_CLASS_Rules - [FAMILY_CLASS_RULES_SIZE] = + static const SPH_Font_Class FAMILY_CLASS_Rules + [FAMILY_CLASS_RULES_SIZE] = { { "MS Legacy Fonts", { "Aharoni", @@ -223,8 +223,8 @@ /* rules below. A blank entry "" is required at the end of these! */ #define STYLE_CLASS_RULES_SIZE 5 - const SPH_Font_Class STYLE_CLASS_Rules - [STYLE_CLASS_RULES_SIZE] = + static const SPH_Font_Class STYLE_CLASS_Rules + [STYLE_CLASS_RULES_SIZE] = { { "Regular Class", { "Regular", @@ -279,18 +279,18 @@ /* Force special legacy fixes for fonts. */ #define COMPATIBILITY_MODE_RULES_SIZE 1 - const SPH_TweakRule COMPATIBILITY_MODE_Rules - [COMPATIBILITY_MODE_RULES_SIZE] = + static const SPH_TweakRule COMPATIBILITY_MODE_Rules + [COMPATIBILITY_MODE_RULES_SIZE] = { - { "-", 0, "", 0 }, + { "Verdana Clones", 0, "", 0 }, }; /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting. */ #define PIXEL_HINTING_RULES_SIZE 2 - const SPH_TweakRule PIXEL_HINTING_Rules - [PIXEL_HINTING_RULES_SIZE] = + static const SPH_TweakRule PIXEL_HINTING_Rules + [PIXEL_HINTING_RULES_SIZE] = { /* these characters are almost always safe */ { "Courier New", 12, "Italic", 'z' }, @@ -301,8 +301,8 @@ /* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */ #define DO_SHPIX_RULES_SIZE 1 - const SPH_TweakRule DO_SHPIX_Rules - [DO_SHPIX_RULES_SIZE] = + static const SPH_TweakRule DO_SHPIX_Rules + [DO_SHPIX_RULES_SIZE] = { { "-", 0, "", 0 }, }; @@ -312,8 +312,8 @@ /* boundary and don't move that point to a Y pixel boundary. */ #define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 4 - const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules - [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = + static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules + [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = { /* fix vwxyz thinness*/ { "Consolas", 0, "", 0 }, @@ -328,8 +328,8 @@ #define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions - [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = + static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions + [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = { /* Fixes < and > */ { "Courier New", 0, "Regular", 0 }, @@ -340,8 +340,8 @@ /* boundary and don't move that point to a Y pixel boundary. */ #define SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE 2 - const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules - [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] = + static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules + [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] = { /* Maintain thickness of diagonal in 'N' */ { "Times New Roman", 0, "Regular/Bold Class", 'N' }, @@ -352,8 +352,8 @@ /* Skip Y moves that move a point off a Y pixel boundary. */ #define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 1 - const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules - [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] = + static const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules + [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] = { { "-", 0, "", 0 }, }; @@ -361,8 +361,8 @@ #define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions - [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = + static const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions + [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = { { "-", 0, "", 0 }, }; @@ -371,8 +371,8 @@ /* Round moves that don't move a point to a Y pixel boundary. */ #define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE 2 - const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules - [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] = + static const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules + [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] = { /* Droid font instructions don't snap Y to pixels */ { "Droid Sans", 0, "Regular/Italic Class", 0 }, @@ -382,8 +382,8 @@ #define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions - [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = + static const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions + [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = { { "-", 0, "", 0 }, }; @@ -392,8 +392,8 @@ /* Allow a Direct_Move along X freedom vector if matched. */ #define ALLOW_X_DMOVE_RULES_SIZE 1 - const SPH_TweakRule ALLOW_X_DMOVE_Rules - [ALLOW_X_DMOVE_RULES_SIZE] = + static const SPH_TweakRule ALLOW_X_DMOVE_Rules + [ALLOW_X_DMOVE_RULES_SIZE] = { /* Fixes vanishing diagonal in 4 */ { "Verdana", 0, "Regular", '4' }, @@ -403,8 +403,8 @@ /* Return MS rasterizer version 35 if matched. */ #define RASTERIZER_35_RULES_SIZE 8 - const SPH_TweakRule RASTERIZER_35_Rules - [RASTERIZER_35_RULES_SIZE] = + static const SPH_TweakRule RASTERIZER_35_Rules + [RASTERIZER_35_RULES_SIZE] = { /* This seems to be the only way to make these look good */ { "Times New Roman", 0, "Regular", 'i' }, @@ -421,8 +421,8 @@ /* Don't round to the subpixel grid. Round to pixel grid. */ #define NORMAL_ROUND_RULES_SIZE 1 - const SPH_TweakRule NORMAL_ROUND_Rules - [NORMAL_ROUND_RULES_SIZE] = + static const SPH_TweakRule NORMAL_ROUND_Rules + [NORMAL_ROUND_RULES_SIZE] = { /* Fix serif thickness for certain ppems */ /* Can probably be generalized somehow */ @@ -433,8 +433,8 @@ /* Skip IUP instructions if matched. */ #define SKIP_IUP_RULES_SIZE 1 - const SPH_TweakRule SKIP_IUP_Rules - [SKIP_IUP_RULES_SIZE] = + static const SPH_TweakRule SKIP_IUP_Rules + [SKIP_IUP_RULES_SIZE] = { { "Arial", 13, "Regular", 'a' }, }; @@ -443,8 +443,8 @@ /* Skip MIAP Twilight hack if matched. */ #define MIAP_HACK_RULES_SIZE 1 - const SPH_TweakRule MIAP_HACK_Rules - [MIAP_HACK_RULES_SIZE] = + static const SPH_TweakRule MIAP_HACK_Rules + [MIAP_HACK_RULES_SIZE] = { { "Geneva", 12, "", 0 }, }; @@ -453,8 +453,8 @@ /* Skip DELTAP instructions if matched. */ #define ALWAYS_SKIP_DELTAP_RULES_SIZE 23 - const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules - [ALWAYS_SKIP_DELTAP_RULES_SIZE] = + static const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules + [ALWAYS_SKIP_DELTAP_RULES_SIZE] = { { "Georgia", 0, "Regular", 'k' }, /* fix various problems with e in different versions */ @@ -489,8 +489,8 @@ /* Always do DELTAP instructions if matched. */ #define ALWAYS_DO_DELTAP_RULES_SIZE 1 - const SPH_TweakRule ALWAYS_DO_DELTAP_Rules - [ALWAYS_DO_DELTAP_RULES_SIZE] = + static const SPH_TweakRule ALWAYS_DO_DELTAP_Rules + [ALWAYS_DO_DELTAP_RULES_SIZE] = { { "-", 0, "", 0 }, }; @@ -744,7 +744,7 @@ #endif /* FORCE_NATURAL_WIDTHS */ - FT_LOCAL_DEF( FT_Bool ) + static FT_Bool is_member_of_family_class( const FT_String* detected_font_name, const FT_String* rule_font_name ) { @@ -779,7 +779,7 @@ } - FT_LOCAL_DEF( FT_Bool ) + static FT_Bool is_member_of_style_class( const FT_String* detected_font_style, const FT_String* rule_font_style ) { @@ -903,9 +903,9 @@ sph_set_tweaks( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; FT_String* family = face->root.family_name; - int ppem = loader->size->metrics.x_ppem; + FT_UInt ppem = loader->size->metrics.x_ppem; FT_String* style = face->root.style_name; @@ -956,7 +956,7 @@ if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 ) { loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35; - loader->exec->size->cvt_ready = FALSE; + loader->exec->size->cvt_ready = -1; tt_size_ready_bytecode( loader->exec->size, @@ -971,7 +971,7 @@ SPH_OPTION_SET_RASTERIZER_VERSION ) { loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; - loader->exec->size->cvt_ready = FALSE; + loader->exec->size->cvt_ready = -1; tt_size_ready_bytecode( loader->exec->size, @@ -1000,12 +1000,12 @@ } } -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#else /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* ANSI C doesn't like empty source files */ typedef int _tt_subpix_dummy; -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* END */ diff --git a/drivers/freetype/freetype/src/truetype/ttsubpix.h b/drivers/freetype/src/truetype/ttsubpix.h index 8a54fc7cc7..86844da666 100644 --- a/drivers/freetype/freetype/src/truetype/ttsubpix.h +++ b/drivers/freetype/src/truetype/ttsubpix.h @@ -4,7 +4,7 @@ /* */ /* TrueType Subpixel Hinting. */ /* */ -/* Copyright 2010-2013 by */ +/* Copyright 2010-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTSUBPIX_H__ -#define __TTSUBPIX_H__ +#ifndef TTSUBPIX_H_ +#define TTSUBPIX_H_ #include <ft2build.h> #include "ttobjs.h" @@ -27,7 +27,7 @@ FT_BEGIN_HEADER -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -50,26 +50,26 @@ FT_BEGIN_HEADER /* Tweak flags that are set for each glyph by the below rules. */ /* */ /* */ -#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001 -#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002 -#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004 -#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000008 -#define SPH_TWEAK_DEEMBOLDEN 0x0000010 -#define SPH_TWEAK_DO_SHPIX 0x0000020 -#define SPH_TWEAK_EMBOLDEN 0x0000040 -#define SPH_TWEAK_MIAP_HACK 0x0000080 -#define SPH_TWEAK_NORMAL_ROUND 0x0000100 -#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0000200 -#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0000400 -#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0000800 -#define SPH_TWEAK_PIXEL_HINTING 0x0001000 -#define SPH_TWEAK_RASTERIZER_35 0x0002000 -#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0004000 -#define SPH_TWEAK_SKIP_IUP 0x0008000 -#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0010000 -#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0020000 -#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0040000 -#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP 0x0080000 +#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001UL +#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002UL +#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004UL +#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000008UL +#define SPH_TWEAK_DEEMBOLDEN 0x0000010UL +#define SPH_TWEAK_DO_SHPIX 0x0000020UL +#define SPH_TWEAK_EMBOLDEN 0x0000040UL +#define SPH_TWEAK_MIAP_HACK 0x0000080UL +#define SPH_TWEAK_NORMAL_ROUND 0x0000100UL +#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0000200UL +#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0000400UL +#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0000800UL +#define SPH_TWEAK_PIXEL_HINTING 0x0001000UL +#define SPH_TWEAK_RASTERIZER_35 0x0002000UL +#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0004000UL +#define SPH_TWEAK_SKIP_IUP 0x0008000UL +#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0010000UL +#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0020000UL +#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0040000UL +#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP 0x0080000UL FT_LOCAL( FT_Bool ) @@ -100,11 +100,12 @@ FT_BEGIN_HEADER #define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE #define SPH_OPTION_SET_RASTERIZER_VERSION 38 -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ FT_END_HEADER -#endif /* __TTSUBPIX_H__ */ +#endif /* TTSUBPIX_H_ */ + /* END */ diff --git a/drivers/freetype/freetype/src/type1/Jamfile b/drivers/freetype/src/type1/Jamfile index 8e366baae5..948b40854a 100644 --- a/drivers/freetype/freetype/src/type1/Jamfile +++ b/drivers/freetype/src/type1/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/type1 Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,13 @@ SubDir FT2_TOP $(FT2_SRC_DIR) type1 ; if $(FT2_MULTI) { - _sources = t1afm t1driver t1objs t1load t1gload t1parse ; + _sources = t1afm + t1driver + t1gload + t1load + t1objs + t1parse + ; } else { diff --git a/drivers/freetype/freetype/src/type1/module.mk b/drivers/freetype/src/type1/module.mk index ade0210d76..d7ab520c74 100644 --- a/drivers/freetype/freetype/src/type1/module.mk +++ b/drivers/freetype/src/type1/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/type1/rules.mk b/drivers/freetype/src/type1/rules.mk index 15087b0304..bdec29479f 100644 --- a/drivers/freetype/freetype/src/type1/rules.mk +++ b/drivers/freetype/src/type1/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ T1_DIR := $(SRC_DIR)/type1 # compilation flags for the driver # -T1_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(T1_DIR)) +T1_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(T1_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # Type1 driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/type1/t1afm.c b/drivers/freetype/src/type1/t1afm.c index de9c1997c4..bbd843c1c3 100644 --- a/drivers/freetype/freetype/src/type1/t1afm.c +++ b/drivers/freetype/src/type1/t1afm.c @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (body). */ /* */ -/* Copyright 1996-2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -169,8 +169,8 @@ goto Exit; /* now, read each kern pair */ - kp = fi->KernPairs; - limit = p + 4 * fi->NumKernPair; + kp = fi->KernPairs; + limit = p + 4 * fi->NumKernPair; /* PFM kerning data are stored by encoding rather than glyph index, */ /* so find the PostScript charmap of this font and install it */ @@ -197,7 +197,7 @@ /* encoding of first glyph (1 byte) */ /* encoding of second glyph (1 byte) */ /* offset (little-endian short) */ - for ( ; p < limit ; p += 4 ) + for ( ; p < limit; p += 4 ) { kp->index1 = FT_Get_Char_Index( t1_face, p[0] ); kp->index2 = FT_Get_Char_Index( t1_face, p[1] ); @@ -239,9 +239,19 @@ AFM_ParserRec parser; AFM_FontInfo fi = NULL; FT_Error error = FT_ERR( Unknown_File_Format ); - T1_Font t1_font = &( (T1_Face)t1_face )->type1; + T1_Face face = (T1_Face)t1_face; + T1_Font t1_font = &face->type1; + if ( face->afm_data ) + { + FT_TRACE1(( "T1_Read_Metrics:" + " Freeing previously attached metrics data.\n" )); + T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); + + face->afm_data = NULL; + } + if ( FT_NEW( fi ) || FT_FRAME_ENTER( stream->size ) ) goto Exit; @@ -250,7 +260,7 @@ fi->Ascender = t1_font->font_bbox.yMax; fi->Descender = t1_font->font_bbox.yMin; - psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux; + psaux = (PSAux_Service)face->psaux; if ( psaux->afm_parser_funcs ) { error = psaux->afm_parser_funcs->init( &parser, @@ -298,7 +308,7 @@ if ( fi->NumKernPair ) { t1_face->face_flags |= FT_FACE_FLAG_KERNING; - ( (T1_Face)t1_face )->afm_data = fi; + face->afm_data = fi; fi = NULL; } } @@ -362,7 +372,7 @@ FT_Fixed* kerning ) { AFM_FontInfo fi = (AFM_FontInfo)( (T1_Face)face )->afm_data; - FT_Int i; + FT_UInt i; if ( !fi ) diff --git a/drivers/freetype/freetype/src/type1/t1afm.h b/drivers/freetype/src/type1/t1afm.h index 8eb1764de7..3a864f2379 100644 --- a/drivers/freetype/freetype/src/type1/t1afm.h +++ b/drivers/freetype/src/type1/t1afm.h @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2006 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1AFM_H__ -#define __T1AFM_H__ +#ifndef T1AFM_H_ +#define T1AFM_H_ #include <ft2build.h> #include "t1objs.h" @@ -48,7 +48,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1AFM_H__ */ +#endif /* T1AFM_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type1/t1driver.c b/drivers/freetype/src/type1/t1driver.c index 697288d66d..f1e60d4523 100644 --- a/drivers/freetype/freetype/src/type1/t1driver.c +++ b/drivers/freetype/src/type1/t1driver.c @@ -4,7 +4,7 @@ /* */ /* Type 1 driver interface (body). */ /* */ -/* Copyright 1996-2004, 2006, 2007, 2009, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,10 +29,11 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_HASH_H #include FT_SERVICE_MULTIPLE_MASTERS_H #include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SERVICE_POSTSCRIPT_INFO_H @@ -87,8 +88,8 @@ static const FT_Service_GlyphDictRec t1_service_glyph_dict = { - (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)t1_get_name_index + (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)t1_get_name_index /* name_index */ }; @@ -106,7 +107,7 @@ static const FT_Service_PsFontNameRec t1_service_ps_name = { - (FT_PsName_GetFunc)t1_get_ps_name + (FT_PsName_GetFunc)t1_get_ps_name /* get_ps_font_name */ }; @@ -118,11 +119,11 @@ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = { - (FT_Get_MM_Func) T1_Get_Multi_Master, - (FT_Set_MM_Design_Func) T1_Set_MM_Design, - (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, - (FT_Get_MM_Var_Func) T1_Get_MM_Var, - (FT_Set_Var_Design_Func)T1_Set_Var_Design + (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ + (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ + (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)T1_Set_Var_Design /* set_var_design */ }; #endif @@ -176,9 +177,11 @@ PS_Dict_Keys key, FT_UInt idx, void *value, - FT_Long value_len ) + FT_Long value_len_ ) { - FT_Long retval = -1; + FT_ULong retval = 0; /* always >= 1 if valid */ + FT_ULong value_len = value_len_ < 0 ? 0 : (FT_ULong)value_len_; + T1_Face t1face = (T1_Face)face; T1_Font type1 = &t1face->type1; @@ -225,7 +228,7 @@ if ( idx < sizeof ( type1->font_bbox ) / sizeof ( type1->font_bbox.xMin ) ) { - FT_Fixed val = 0; + FT_Fixed val = 0; retval = sizeof ( val ); @@ -258,7 +261,7 @@ break; case PS_DICT_FONT_NAME: - retval = (FT_Long)( ft_strlen( type1->font_name ) + 1 ); + retval = ft_strlen( type1->font_name ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_name ), retval ); break; @@ -278,7 +281,7 @@ case PS_DICT_CHAR_STRING_KEY: if ( idx < (FT_UInt)type1->num_glyphs ) { - retval = (FT_Long)( ft_strlen( type1->glyph_names[idx] ) + 1 ); + retval = ft_strlen( type1->glyph_names[idx] ) + 1; if ( value && value_len >= retval ) { ft_memcpy( value, (void *)( type1->glyph_names[idx] ), retval ); @@ -290,7 +293,7 @@ case PS_DICT_CHAR_STRING: if ( idx < (FT_UInt)type1->num_glyphs ) { - retval = (FT_Long)( type1->charstrings_len[idx] + 1 ); + retval = type1->charstrings_len[idx] + 1; if ( value && value_len >= retval ) { ft_memcpy( value, (void *)( type1->charstrings[idx] ), @@ -310,7 +313,7 @@ if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY && idx < (FT_UInt)type1->encoding.num_chars ) { - retval = (FT_Long)( ft_strlen( type1->encoding.char_name[idx] ) + 1 ); + retval = ft_strlen( type1->encoding.char_name[idx] ) + 1; if ( value && value_len >= retval ) { ft_memcpy( value, (void *)( type1->encoding.char_name[idx] ), @@ -327,13 +330,37 @@ break; case PS_DICT_SUBR: - if ( idx < (FT_UInt)type1->num_subrs ) { - retval = (FT_Long)( type1->subrs_len[idx] + 1 ); - if ( value && value_len >= retval ) + FT_Bool ok = 0; + + + if ( type1->subrs_hash ) { - ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); - ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + /* convert subr index to array index */ + size_t* val = ft_hash_num_lookup( (FT_Int)idx, + type1->subrs_hash ); + + + if ( val ) + { + idx = *val; + ok = 1; + } + } + else + { + if ( idx < (FT_UInt)type1->num_subrs ) + ok = 1; + } + + if ( ok ) + { + retval = type1->subrs_len[idx] + 1; + if ( value && value_len >= retval ) + { + ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); + ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + } } } break; @@ -523,31 +550,31 @@ break; case PS_DICT_VERSION: - retval = (FT_Long)( ft_strlen( type1->font_info.version ) + 1 ); + retval = ft_strlen( type1->font_info.version ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_info.version ), retval ); break; case PS_DICT_NOTICE: - retval = (FT_Long)( ft_strlen( type1->font_info.notice ) + 1 ); + retval = ft_strlen( type1->font_info.notice ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_info.notice ), retval ); break; case PS_DICT_FULL_NAME: - retval = (FT_Long)( ft_strlen( type1->font_info.full_name ) + 1 ); + retval = ft_strlen( type1->font_info.full_name ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_info.full_name ), retval ); break; case PS_DICT_FAMILY_NAME: - retval = (FT_Long)( ft_strlen( type1->font_info.family_name ) + 1 ); + retval = ft_strlen( type1->font_info.family_name ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_info.family_name ), retval ); break; case PS_DICT_WEIGHT: - retval = (FT_Long)( ft_strlen( type1->font_info.weight ) + 1 ); + retval = ft_strlen( type1->font_info.weight ) + 1; if ( value && value_len >= retval ) ft_memcpy( value, (void *)( type1->font_info.weight ), retval ); break; @@ -557,29 +584,26 @@ if ( value && value_len >= retval ) *((FT_Long *)value) = type1->font_info.italic_angle; break; - - default: - break; } - return retval; + return retval == 0 ? -1 : (FT_Long)retval; } static const FT_Service_PsInfoRec t1_service_ps_info = { - (PS_GetFontInfoFunc) t1_ps_get_font_info, - (PS_GetFontExtraFunc) t1_ps_get_font_extra, - (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, - (PS_GetFontPrivateFunc)t1_ps_get_font_private, - (PS_GetFontValueFunc) t1_ps_get_font_value, + (PS_GetFontInfoFunc) t1_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) t1_ps_get_font_extra, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, /* ps_has_glyph_names */ + (PS_GetFontPrivateFunc)t1_ps_get_font_private, /* ps_get_font_private */ + (PS_GetFontValueFunc) t1_ps_get_font_value, /* ps_get_font_value */ }; #ifndef T1_CONFIG_OPTION_NO_AFM static const FT_Service_KerningRec t1_service_kerning = { - T1_Get_Track_Kerning, + T1_Get_Track_Kerning, /* get_track */ }; #endif @@ -593,7 +617,7 @@ { { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name }, { FT_SERVICE_ID_GLYPH_DICT, &t1_service_glyph_dict }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_1 }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TYPE_1 }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &t1_service_ps_info }, #ifndef T1_CONFIG_OPTION_NO_AFM @@ -690,36 +714,37 @@ 0x10000L, 0x20000L, - 0, /* format interface */ + 0, /* module-specific interface */ - T1_Driver_Init, - T1_Driver_Done, - Get_Interface, + T1_Driver_Init, /* FT_Module_Constructor module_init */ + T1_Driver_Done, /* FT_Module_Destructor module_done */ + Get_Interface, /* FT_Module_Requester get_interface */ }, sizeof ( T1_FaceRec ), sizeof ( T1_SizeRec ), sizeof ( T1_GlyphSlotRec ), - T1_Face_Init, - T1_Face_Done, - T1_Size_Init, - T1_Size_Done, - T1_GlyphSlot_Init, - T1_GlyphSlot_Done, + T1_Face_Init, /* FT_Face_InitFunc init_face */ + T1_Face_Done, /* FT_Face_DoneFunc done_face */ + T1_Size_Init, /* FT_Size_InitFunc init_size */ + T1_Size_Done, /* FT_Size_DoneFunc done_size */ + T1_GlyphSlot_Init, /* FT_Slot_InitFunc init_slot */ + T1_GlyphSlot_Done, /* FT_Slot_DoneFunc done_slot */ - T1_Load_Glyph, + T1_Load_Glyph, /* FT_Slot_LoadFunc load_glyph */ #ifdef T1_CONFIG_OPTION_NO_AFM - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ #else - Get_Kerning, - T1_Read_Metrics, + Get_Kerning, /* FT_Face_GetKerningFunc get_kerning */ + T1_Read_Metrics, /* FT_Face_AttachFunc attach_file */ #endif - T1_Get_Advances, - T1_Size_Request, - 0 /* FT_Size_SelectFunc */ + T1_Get_Advances, /* FT_Face_GetAdvancesFunc get_advances */ + + T1_Size_Request, /* FT_Size_RequestFunc request_size */ + 0 /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/freetype/src/type1/t1driver.h b/drivers/freetype/src/type1/t1driver.h index 639cd4a7ad..78d8e38aa9 100644 --- a/drivers/freetype/freetype/src/type1/t1driver.h +++ b/drivers/freetype/src/type1/t1driver.h @@ -4,7 +4,7 @@ /* */ /* High-level Type 1 driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1DRIVER_H__ -#define __T1DRIVER_H__ +#ifndef T1DRIVER_H_ +#define T1DRIVER_H_ #include <ft2build.h> @@ -36,7 +36,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1DRIVER_H__ */ +#endif /* T1DRIVER_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type1/t1errors.h b/drivers/freetype/src/type1/t1errors.h index 8740530eef..9ba470ed6c 100644 --- a/drivers/freetype/freetype/src/type1/t1errors.h +++ b/drivers/freetype/src/type1/t1errors.h @@ -4,7 +4,7 @@ /* */ /* Type 1 error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __T1ERRORS_H__ -#define __T1ERRORS_H__ +#ifndef T1ERRORS_H_ +#define T1ERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX T1_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __T1ERRORS_H__ */ +#endif /* T1ERRORS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type1/t1gload.c b/drivers/freetype/src/type1/t1gload.c index 23478d1288..ea36f64142 100644 --- a/drivers/freetype/freetype/src/type1/t1gload.c +++ b/drivers/freetype/src/type1/t1gload.c @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2006, 2008-2010, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -54,7 +54,7 @@ /*************************************************************************/ - FT_LOCAL_DEF( FT_Error ) + static FT_Error T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, FT_UInt glyph_index, FT_Data* char_string ) @@ -92,7 +92,7 @@ if ( !error ) error = decoder->funcs.parse_charstrings( decoder, (FT_Byte*)char_string->pointer, - char_string->length ); + (FT_UInt)char_string->length ); #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -183,6 +183,7 @@ decoder.num_subrs = type1->num_subrs; decoder.subrs = type1->subrs; decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; @@ -194,7 +195,7 @@ for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) { /* now get load the unscaled outline */ - error = T1_Parse_Glyph( &decoder, glyph_index ); + (void)T1_Parse_Glyph( &decoder, (FT_UInt)glyph_index ); if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) *max_advance = decoder.builder.advance.x; @@ -245,9 +246,10 @@ decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; - decoder.num_subrs = type1->num_subrs; - decoder.subrs = type1->subrs; - decoder.subrs_len = type1->subrs_len; + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; @@ -300,6 +302,8 @@ goto Exit; } + FT_TRACE1(( "T1_Load_Glyph: glyph index %d\n", glyph_index )); + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); if ( load_flags & FT_LOAD_NO_RECURSE ) @@ -344,6 +348,7 @@ decoder.num_subrs = type1->num_subrs; decoder.subrs = type1->subrs; decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; @@ -393,7 +398,6 @@ { FT_BBox cbox; FT_Glyph_Metrics* metrics = &t1glyph->metrics; - FT_Vector advance; /* copy the _unscaled_ advance width */ @@ -425,23 +429,26 @@ #if 1 /* apply the font matrix, if any */ - if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx || - font_matrix.xy != 0 || font_matrix.yx != 0 ) + if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L || + font_matrix.xy != 0 || font_matrix.yx != 0 ) + { FT_Outline_Transform( &t1glyph->outline, &font_matrix ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, + font_matrix.xx ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, + font_matrix.yy ); + } + if ( font_offset.x || font_offset.y ) + { FT_Outline_Translate( &t1glyph->outline, font_offset.x, font_offset.y ); - advance.x = metrics->horiAdvance; - advance.y = 0; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->horiAdvance = advance.x + font_offset.x; - advance.x = 0; - advance.y = metrics->vertAdvance; - FT_Vector_Transform( &advance, &font_matrix ); - metrics->vertAdvance = advance.y + font_offset.y; + metrics->horiAdvance += font_offset.x; + metrics->vertAdvance += font_offset.y; + } #endif if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) @@ -502,7 +509,7 @@ /* Set the control data to null - it is no longer available if */ /* loaded incrementally. */ - t1glyph->control_data = 0; + t1glyph->control_data = NULL; t1glyph->control_len = 0; } #endif diff --git a/drivers/freetype/freetype/src/type1/t1gload.h b/drivers/freetype/src/type1/t1gload.h index 0bdea3a8d5..975f227853 100644 --- a/drivers/freetype/freetype/src/type1/t1gload.h +++ b/drivers/freetype/src/type1/t1gload.h @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2008, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1GLOAD_H__ -#define __T1GLOAD_H__ +#ifndef T1GLOAD_H_ +#define T1GLOAD_H_ #include <ft2build.h> @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1GLOAD_H__ */ +#endif /* T1GLOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type1/t1load.c b/drivers/freetype/src/type1/t1load.c index 1c834a17bb..c981adcf2c 100644 --- a/drivers/freetype/freetype/src/type1/t1load.c +++ b/drivers/freetype/src/type1/t1load.c @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (body). */ /* */ -/* Copyright 1996-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -66,6 +66,7 @@ #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_TYPE1_TYPES_H #include FT_INTERNAL_CALC_H +#include FT_INTERNAL_HASH_H #include "t1load.h" #include "t1errors.h" @@ -226,7 +227,7 @@ /* Given a normalized (blend) coordinate, figure out the design */ /* coordinate appropriate for that value. */ /* */ - FT_LOCAL_DEF( FT_Fixed ) + static FT_Fixed mm_axis_unmap( PS_DesignMap axismap, FT_Fixed ncv ) { @@ -255,7 +256,7 @@ /* Given a vector of weights, one for each design, figure out the */ /* normalized axis coordinates which gave rise to those weights. */ /* */ - FT_LOCAL_DEF( void ) + static void mm_weights_unmap( FT_Fixed* weights, FT_Fixed* axiscoords, FT_UInt axis_count ) @@ -325,7 +326,7 @@ /* Point to axes after MM_Var struct */ mmvar->namedstyle = NULL; - for ( i = 0 ; i < mmaster.num_axis; ++i ) + for ( i = 0; i < mmaster.num_axis; ++i ) { mmvar->axis[i].name = mmaster.axis[i].name; mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); @@ -336,6 +337,9 @@ mmvar->axis[i].strid = ~0U; /* Does not apply */ mmvar->axis[i].tag = ~0U; /* Does not apply */ + if ( !mmvar->axis[i].name ) + continue; + if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 ) @@ -368,46 +372,43 @@ FT_Fixed* coords ) { PS_Blend blend = face->blend; - FT_Error error; FT_UInt n, m; - error = FT_ERR( Invalid_Argument ); + if ( !blend ) + return FT_THROW( Invalid_Argument ); - if ( blend && blend->num_axis == num_coords ) - { - /* recompute the weight vector from the blend coordinates */ - error = FT_Err_Ok; + if ( num_coords > blend->num_axis ) + num_coords = blend->num_axis; - for ( n = 0; n < blend->num_designs; n++ ) - { - FT_Fixed result = 0x10000L; /* 1.0 fixed */ + /* recompute the weight vector from the blend coordinates */ + for ( n = 0; n < blend->num_designs; n++ ) + { + FT_Fixed result = 0x10000L; /* 1.0 fixed */ - for ( m = 0; m < blend->num_axis; m++ ) - { - FT_Fixed factor; + for ( m = 0; m < blend->num_axis; m++ ) + { + FT_Fixed factor; - /* get current blend axis position */ - factor = coords[m]; - if ( factor < 0 ) - factor = 0; - if ( factor > 0x10000L ) - factor = 0x10000L; + /* get current blend axis position; */ + /* use a default value if we don't have a coordinate */ + factor = m < num_coords ? coords[m] : 0x8000; + if ( factor < 0 ) + factor = 0; + if ( factor > 0x10000L ) + factor = 0x10000L; - if ( ( n & ( 1 << m ) ) == 0 ) - factor = 0x10000L - factor; + if ( ( n & ( 1 << m ) ) == 0 ) + factor = 0x10000L - factor; - result = FT_MulFix( result, factor ); - } - blend->weight_vector[n] = result; + result = FT_MulFix( result, factor ); } - - error = FT_Err_Ok; + blend->weight_vector[n] = result; } - return error; + return FT_Err_Ok; } @@ -417,68 +418,72 @@ FT_Long* coords ) { PS_Blend blend = face->blend; - FT_Error error; FT_UInt n, p; + FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; - error = FT_ERR( Invalid_Argument ); - if ( blend && blend->num_axis == num_coords ) - { - /* compute the blend coordinates through the blend design map */ - FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; + if ( !blend ) + return FT_THROW( Invalid_Argument ); + if ( num_coords > blend->num_axis ) + num_coords = blend->num_axis; - for ( n = 0; n < blend->num_axis; n++ ) - { - FT_Long design = coords[n]; - FT_Fixed the_blend; - PS_DesignMap map = blend->design_map + n; - FT_Long* designs = map->design_points; - FT_Fixed* blends = map->blend_points; - FT_Int before = -1, after = -1; + /* compute the blend coordinates through the blend design map */ + for ( n = 0; n < blend->num_axis; n++ ) + { + FT_Long design; + FT_Fixed the_blend; + PS_DesignMap map = blend->design_map + n; + FT_Long* designs = map->design_points; + FT_Fixed* blends = map->blend_points; + FT_Int before = -1, after = -1; - for ( p = 0; p < (FT_UInt)map->num_points; p++ ) - { - FT_Long p_design = designs[p]; + /* use a default value if we don't have a coordinate */ + if ( n < num_coords ) + design = coords[n]; + else + design = ( designs[map->num_points - 1] - designs[0] ) / 2; - /* exact match? */ - if ( design == p_design ) - { - the_blend = blends[p]; - goto Found; - } + for ( p = 0; p < (FT_UInt)map->num_points; p++ ) + { + FT_Long p_design = designs[p]; - if ( design < p_design ) - { - after = p; - break; - } - before = p; + /* exact match? */ + if ( design == p_design ) + { + the_blend = blends[p]; + goto Found; } - /* now interpolate if necessary */ - if ( before < 0 ) - the_blend = blends[0]; + if ( design < p_design ) + { + after = (FT_Int)p; + break; + } - else if ( after < 0 ) - the_blend = blends[map->num_points - 1]; + before = (FT_Int)p; + } - else - the_blend = FT_MulDiv( design - designs[before], - blends [after] - blends [before], - designs[after] - designs[before] ); + /* now interpolate if necessary */ + if ( before < 0 ) + the_blend = blends[0]; - Found: - final_blends[n] = the_blend; - } + else if ( after < 0 ) + the_blend = blends[map->num_points - 1]; + + else + the_blend = FT_MulDiv( design - designs[before], + blends [after] - blends [before], + designs[after] - designs[before] ); - error = T1_Set_MM_Blend( face, num_coords, final_blends ); + Found: + final_blends[n] = the_blend; } - return error; + return T1_Set_MM_Blend( face, blend->num_axis, final_blends ); } @@ -492,20 +497,17 @@ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Long lcoords[4]; /* maximum axis count is 4 */ - FT_UInt i; - FT_Error error; + FT_Long lcoords[T1_MAX_MM_AXIS]; + FT_UInt i; + + if ( num_coords > T1_MAX_MM_AXIS ) + num_coords = T1_MAX_MM_AXIS; - error = FT_ERR( Invalid_Argument ); - if ( num_coords <= 4 && num_coords > 0 ) - { - for ( i = 0; i < num_coords; ++i ) - lcoords[i] = FIXED_TO_INT( coords[i] ); - error = T1_Set_MM_Design( face, num_coords, lcoords ); - } + for ( i = 0; i < num_coords; ++i ) + lcoords[i] = FIXED_TO_INT( coords[i] ); - return error; + return T1_Set_MM_Design( face, num_coords, lcoords ); } @@ -601,23 +603,32 @@ /* each token is an immediate containing the name of the axis */ for ( n = 0; n < num_axis; n++ ) { - T1_Token token = axis_tokens + n; - FT_Byte* name; - FT_PtrDist len; + T1_Token token = axis_tokens + n; + FT_Byte* name; + FT_UInt len; /* skip first slash, if any */ if ( token->start[0] == '/' ) token->start++; - len = token->limit - token->start; + len = (FT_UInt)( token->limit - token->start ); if ( len == 0 ) { error = FT_THROW( Invalid_File_Format ); goto Exit; } - if ( FT_ALLOC( blend->axis_names[n], (FT_Long)( len + 1 ) ) ) + name = (FT_Byte*)blend->axis_names[n]; + if ( name ) + { + FT_TRACE0(( "parse_blend_axis_types:" + " overwriting axis name `%s' with `%*.s'\n", + name, len, token->start )); + FT_FREE( name ); + } + + if ( FT_ALLOC( blend->axis_names[n], len + 1 ) ) goto Exit; name = (FT_Byte*)blend->axis_names[n]; @@ -694,7 +705,9 @@ } num_axis = n_axis; - error = t1_allocate_blend( face, num_designs, num_axis ); + error = t1_allocate_blend( face, + (FT_UInt)num_designs, + (FT_UInt)num_axis ); if ( error ) goto Exit; blend = face->blend; @@ -759,7 +772,7 @@ old_cursor = parser->root.cursor; old_limit = parser->root.limit; - error = t1_allocate_blend( face, 0, num_axis ); + error = t1_allocate_blend( face, 0, (FT_UInt)num_axis ); if ( error ) goto Exit; blend = face->blend; @@ -787,6 +800,13 @@ goto Exit; } + if ( map->design_points ) + { + FT_ERROR(( "parse_blend_design_map: duplicate table\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + /* allocate design map data */ if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) ) goto Exit; @@ -850,7 +870,7 @@ if ( !blend || !blend->num_designs ) { - error = t1_allocate_blend( face, num_designs, 0 ); + error = t1_allocate_blend( face, (FT_UInt)num_designs, 0 ); if ( error ) goto Exit; blend = face->blend; @@ -892,8 +912,8 @@ parse_buildchar( T1_Face face, T1_Loader loader ) { - face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 ); - + face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser, + 0, NULL, 0 ); return; } @@ -1040,9 +1060,11 @@ } + /* return 1 in case of success */ + static int read_binary_data( T1_Parser parser, - FT_Long* size, + FT_ULong* size, FT_Byte** base, FT_Bool incremental ) { @@ -1074,7 +1096,7 @@ if ( s >= 0 && s < limit - *base ) { parser->root.cursor += s + 1; - *size = s; + *size = (FT_ULong)s; return !parser->root.error; } } @@ -1105,9 +1127,10 @@ FT_Int result; + /* input is scaled by 1000 to accommodate default FontMatrix */ result = T1_ToFixedArray( parser, 6, temp, 3 ); - if ( result < 0 ) + if ( result < 6 ) { parser->root.error = FT_THROW( Invalid_File_Format ); return; @@ -1122,15 +1145,12 @@ return; } - /* Set Units per EM based on FontMatrix values. We set the value to */ - /* 1000 / temp_scale, because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed, from psobjs.c). */ - - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); - - /* we need to scale the values by 1.0/temp_scale */ + /* atypical case */ if ( temp_scale != 0x10000L ) { + /* set units per EM based on FontMatrix values */ + root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + temp[0] = FT_DivFix( temp[0], temp_scale ); temp[1] = FT_DivFix( temp[1], temp_scale ); temp[2] = FT_DivFix( temp[2], temp_scale ); @@ -1192,10 +1212,27 @@ else count = (FT_Int)T1_ToInt( parser ); + /* only composite fonts (which we don't support) */ + /* can have larger values */ + if ( count > 256 ) + { + FT_ERROR(( "parse_encoding: invalid encoding array size\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + T1_Skip_Spaces( parser ); if ( parser->root.cursor >= limit ) return; + /* PostScript happily allows overwriting of encoding arrays */ + if ( encode->char_index ) + { + FT_FREE( encode->char_index ); + FT_FREE( encode->char_name ); + T1_Release_Table( char_table ); + } + /* we use a T1_Table to store our charnames */ loader->num_chars = encode->num_chars = count; if ( FT_NEW_ARRAY( encode->char_index, count ) || @@ -1213,7 +1250,7 @@ char* notdef = (char *)".notdef"; - T1_Add_Table( char_table, n, notdef, 8 ); + (void)T1_Add_Table( char_table, n, notdef, 8 ); } /* Now we need to read records of the form */ @@ -1274,13 +1311,20 @@ { charcode = (FT_Int)T1_ToInt( parser ); T1_Skip_Spaces( parser ); + + /* protect against invalid charcode */ + if ( cur == parser->root.cursor ) + { + parser->root.error = FT_THROW( Unknown_File_Format ); + return; + } } cur = parser->root.cursor; if ( cur + 2 < limit && *cur == '/' && n < count ) { - FT_PtrDist len; + FT_UInt len; cur++; @@ -1292,7 +1336,7 @@ if ( parser->root.error ) return; - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); parser->root.error = T1_Add_Table( char_table, charcode, cur, len + 1 ); @@ -1361,6 +1405,8 @@ FT_Memory memory = parser->root.memory; FT_Error error; FT_Int num_subrs; + FT_UInt count; + FT_Hash hash = NULL; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -1380,6 +1426,49 @@ } num_subrs = (FT_Int)T1_ToInt( parser ); + if ( num_subrs < 0 ) + { + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + + /* we certainly need more than 8 bytes per subroutine */ + if ( parser->root.limit > parser->root.cursor && + num_subrs > ( parser->root.limit - parser->root.cursor ) >> 3 ) + { + /* + * There are two possibilities. Either the font contains an invalid + * value for `num_subrs', or we have a subsetted font where the + * subroutine indices are not adjusted, e.g. + * + * /Subrs 812 array + * dup 0 { ... } NP + * dup 51 { ... } NP + * dup 681 { ... } NP + * ND + * + * In both cases, we use a number hash that maps from subr indices to + * actual array elements. + */ + + FT_TRACE0(( "parse_subrs: adjusting number of subroutines" + " (from %d to %d)\n", + num_subrs, + ( parser->root.limit - parser->root.cursor ) >> 3 )); + num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3; + + if ( !hash ) + { + if ( FT_NEW( hash ) ) + goto Fail; + + loader->subrs_hash = hash; + + error = ft_hash_num_init( hash, memory ); + if ( error ) + goto Fail; + } + } /* position the parser right before the `dup' of the first subr */ T1_Skip_PS_Token( parser ); /* `array' */ @@ -1400,9 +1489,10 @@ /* */ /* `index' + binary data */ /* */ - for (;;) + for ( count = 0; ; count++ ) { - FT_Long idx, size; + FT_Long idx; + FT_ULong size; FT_Byte* base; @@ -1435,6 +1525,14 @@ T1_Skip_Spaces ( parser ); } + /* if we use a hash, the subrs index is the key, and a running */ + /* counter specified for `T1_Add_Table' acts as the value */ + if ( hash ) + { + ft_hash_num_insert( idx, count, hash, memory ); + idx = count; + } + /* with synthetic fonts it is possible we get here twice */ if ( loader->num_subrs ) continue; @@ -1446,13 +1544,13 @@ /* */ if ( face->type1.private_dict.lenIV >= 0 ) { - FT_Byte* temp; + FT_Byte* temp = NULL; /* some fonts define empty subr records -- this is not totally */ /* compliant to the specification (which says they should at */ /* least contain a `return'), but we support them anyway */ - if ( size < face->type1.private_dict.lenIV ) + if ( size < (FT_ULong)face->type1.private_dict.lenIV ) { error = FT_THROW( Invalid_File_Format ); goto Fail; @@ -1463,7 +1561,7 @@ goto Fail; FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); - size -= face->type1.private_dict.lenIV; + size -= (FT_ULong)face->type1.private_dict.lenIV; error = T1_Add_Table( table, (FT_Int)idx, temp + face->type1.private_dict.lenIV, size ); FT_FREE( temp ); @@ -1500,10 +1598,10 @@ PSAux_Service psaux = (PSAux_Service)face->psaux; - FT_Byte* cur; + FT_Byte* cur = parser->root.cursor; FT_Byte* limit = parser->root.limit; FT_Int n, num_glyphs; - FT_UInt notdef_index = 0; + FT_Int notdef_index = 0; FT_Byte notdef_found = 0; @@ -1514,6 +1612,15 @@ goto Fail; } + /* we certainly need more than 8 bytes per glyph */ + if ( num_glyphs > ( limit - cur ) >> 3 ) + { + FT_TRACE0(( "parse_charstrings: adjusting number of glyphs" + " (from %d to %d)\n", + num_glyphs, ( limit - cur ) >> 3 )); + num_glyphs = ( limit - cur ) >> 3; + } + /* some fonts like Optima-Oblique not only define the /CharStrings */ /* array but access it also */ if ( num_glyphs == 0 || parser->root.error ) @@ -1550,7 +1657,7 @@ for (;;) { - FT_Long size; + FT_ULong size; FT_Byte* base; @@ -1591,22 +1698,27 @@ } T1_Skip_PS_Token( parser ); + if ( parser->root.cursor >= limit ) + { + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } if ( parser->root.error ) return; if ( *cur == '/' ) { - FT_PtrDist len; + FT_UInt len; - if ( cur + 1 >= limit ) + if ( cur + 2 >= limit ) { error = FT_THROW( Invalid_File_Format ); goto Fail; } cur++; /* skip `/' */ - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) return; @@ -1636,10 +1748,10 @@ if ( face->type1.private_dict.lenIV >= 0 && n < num_glyphs + TABLE_EXTEND ) { - FT_Byte* temp; + FT_Byte* temp = NULL; - if ( size <= face->type1.private_dict.lenIV ) + if ( size <= (FT_ULong)face->type1.private_dict.lenIV ) { error = FT_THROW( Invalid_File_Format ); goto Fail; @@ -1650,7 +1762,7 @@ goto Fail; FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); - size -= face->type1.private_dict.lenIV; + size -= (FT_ULong)face->type1.private_dict.lenIV; error = T1_Add_Table( code_table, n, temp + face->type1.private_dict.lenIV, size ); FT_FREE( temp ); @@ -1828,15 +1940,11 @@ }; -#define T1_FIELD_COUNT \ - ( sizeof ( t1_keywords ) / sizeof ( t1_keywords[0] ) ) - - static FT_Error parse_dict( T1_Face face, T1_Loader loader, FT_Byte* base, - FT_Long size ) + FT_ULong size ) { T1_Parser parser = &loader->parser; FT_Byte *limit, *start_binary = NULL; @@ -1892,7 +2000,7 @@ else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' && have_integer ) { - FT_Long s; + FT_ULong s; FT_Byte* b; @@ -1905,7 +2013,7 @@ else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' && have_integer ) { - FT_Long s; + FT_ULong s; FT_Byte* b; @@ -1918,7 +2026,7 @@ /* look for immediates */ else if ( *cur == '/' && cur + 2 < limit ) { - FT_PtrDist len; + FT_UInt len; cur++; @@ -1928,7 +2036,7 @@ if ( parser->root.error ) goto Exit; - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); if ( len > 0 && len < 22 && parser->root.cursor < limit ) { @@ -1945,9 +2053,9 @@ if ( !name ) break; - if ( cur[0] == name[0] && - len == (FT_PtrDist)ft_strlen( (const char *)name ) && - ft_memcmp( cur, name, len ) == 0 ) + if ( cur[0] == name[0] && + len == ft_strlen( (const char *)name ) && + ft_memcmp( cur, name, len ) == 0 ) { /* We found it -- run the parsing callback! */ /* We record every instance of every field */ @@ -2036,17 +2144,6 @@ FT_UNUSED( face ); FT_MEM_ZERO( loader, sizeof ( *loader ) ); - loader->num_glyphs = 0; - loader->num_chars = 0; - - /* initialize the tables -- simply set their `init' field to 0 */ - loader->encoding_table.init = 0; - loader->charstrings.init = 0; - loader->glyph_names.init = 0; - loader->subrs.init = 0; - loader->swap_table.init = 0; - loader->fontdata = 0; - loader->keywords_encountered = 0; } @@ -2054,6 +2151,7 @@ t1_done_loader( T1_Loader loader ) { T1_Parser parser = &loader->parser; + FT_Memory memory = parser->root.memory; /* finalize tables */ @@ -2063,6 +2161,10 @@ T1_Release_Table( &loader->swap_table ); T1_Release_Table( &loader->subrs ); + /* finalize hash */ + ft_hash_num_free( loader->subrs_hash, memory ); + FT_FREE( loader->subrs_hash ); + /* finalize parser */ T1_Finalize_Parser( parser ); } @@ -2179,11 +2281,15 @@ if ( loader.subrs.init ) { - loader.subrs.init = 0; type1->num_subrs = loader.num_subrs; type1->subrs_block = loader.subrs.block; type1->subrs = loader.subrs.elements; type1->subrs_len = loader.subrs.lengths; + type1->subrs_hash = loader.subrs_hash; + + /* prevent `t1_done_loader' from freeing the propagated data */ + loader.subrs.init = 0; + loader.subrs_hash = NULL; } if ( !IS_INCREMENTAL ) @@ -2202,14 +2308,13 @@ /* the `lengths' field must be released later */ type1->glyph_names_block = loader.glyph_names.block; type1->glyph_names = (FT_String**)loader.glyph_names.elements; - loader.glyph_names.block = 0; - loader.glyph_names.elements = 0; + loader.glyph_names.block = NULL; + loader.glyph_names.elements = NULL; /* we must now build type1.encoding when we have a custom array */ if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) { FT_Int charcode, idx, min_char, max_char; - FT_Byte* char_name; FT_Byte* glyph_name; @@ -2224,6 +2329,9 @@ charcode = 0; for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) { + FT_Byte* char_name; + + type1->encoding.char_index[charcode] = 0; type1->encoding.char_name [charcode] = (char *)".notdef"; diff --git a/drivers/freetype/freetype/src/type1/t1load.h b/drivers/freetype/src/type1/t1load.h index 546fc33530..b96fe5a746 100644 --- a/drivers/freetype/freetype/src/type1/t1load.h +++ b/drivers/freetype/src/type1/t1load.h @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2006, 2007 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1LOAD_H__ -#define __T1LOAD_H__ +#ifndef T1LOAD_H_ +#define T1LOAD_H_ #include <ft2build.h> @@ -46,6 +46,7 @@ FT_BEGIN_HEADER FT_Int num_subrs; PS_TableRec subrs; + FT_Hash subrs_hash; FT_Bool fontdata; FT_UInt keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */ @@ -96,7 +97,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1LOAD_H__ */ +#endif /* T1LOAD_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type1/t1objs.c b/drivers/freetype/src/type1/t1objs.c index 837b7911d4..a009117133 100644 --- a/drivers/freetype/freetype/src/type1/t1objs.c +++ b/drivers/freetype/src/type1/t1objs.c @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (body). */ /* */ -/* Copyright 1996-2009, 2011, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,7 +67,7 @@ "pshinter" ); return ( module && pshinter && pshinter->get_globals_funcs ) ? pshinter->get_globals_funcs( module ) - : 0 ; + : 0; } @@ -86,7 +86,7 @@ if ( funcs ) funcs->destroy( (PSH_Globals)size->root.internal ); - size->root.internal = 0; + size->root.internal = NULL; } } @@ -144,7 +144,7 @@ FT_LOCAL_DEF( void ) T1_GlyphSlot_Done( FT_GlyphSlot slot ) { - slot->internal->glyph_hints = 0; + slot->internal->glyph_hints = NULL; } @@ -224,7 +224,7 @@ } T1_Done_Blend( face ); - face->blend = 0; + face->blend = NULL; #endif /* release font info strings */ @@ -247,6 +247,9 @@ FT_FREE( type1->subrs ); FT_FREE( type1->subrs_len ); + ft_hash_num_free( type1->subrs_hash, memory ); + FT_FREE( type1->subrs_hash ); + FT_FREE( type1->subrs_block ); FT_FREE( type1->charstrings_block ); FT_FREE( type1->glyph_names_block ); @@ -345,7 +348,7 @@ goto Exit; /* check the face index */ - if ( face_index > 0 ) + if ( ( face_index & 0xFFFF ) > 0 ) { FT_ERROR(( "T1_Face_Init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); @@ -364,10 +367,10 @@ root->num_glyphs = type1->num_glyphs; root->face_index = 0; - root->face_flags = FT_FACE_FLAG_SCALABLE | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_GLYPH_NAMES | - FT_FACE_FLAG_HINTER; + root->face_flags |= FT_FACE_FLAG_SCALABLE | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_GLYPH_NAMES | + FT_FACE_FLAG_HINTER; if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; @@ -375,9 +378,6 @@ if ( face->blend ) root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; - /* XXX: TODO -- add kerning with .afm support */ - - /* The following code to extract the family and the style is very */ /* simplistic and might get some things wrong. For a full-featured */ /* algorithm you might have a look at the whitepaper given at */ @@ -457,7 +457,7 @@ /* no embedded bitmap support */ root->num_fixed_sizes = 0; - root->available_sizes = 0; + root->available_sizes = NULL; root->bbox.xMin = type1->font_bbox.xMin >> 16; root->bbox.yMin = type1->font_bbox.yMin >> 16; diff --git a/drivers/freetype/freetype/src/type1/t1objs.h b/drivers/freetype/src/type1/t1objs.h index 54ccbb996a..94fbdee9ae 100644 --- a/drivers/freetype/freetype/src/type1/t1objs.h +++ b/drivers/freetype/src/type1/t1objs.h @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2006, 2011 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1OBJS_H__ -#define __T1OBJS_H__ +#ifndef T1OBJS_H_ +#define T1OBJS_H_ #include <ft2build.h> @@ -154,7 +154,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1OBJS_H__ */ +#endif /* T1OBJS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type1/t1parse.c b/drivers/freetype/src/type1/t1parse.c index 106e4e7ecd..563d9f37bb 100644 --- a/drivers/freetype/freetype/src/type1/t1parse.c +++ b/drivers/freetype/src/type1/t1parse.c @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2005, 2008, 2009, 2012, 2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -143,13 +143,13 @@ FT_ULong size; - psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + psaux->ps_parser_funcs->init( &parser->root, NULL, NULL, memory ); parser->stream = stream; parser->base_len = 0; - parser->base_dict = 0; + parser->base_dict = NULL; parser->private_len = 0; - parser->private_dict = 0; + parser->private_dict = NULL; parser->in_pfb = 0; parser->in_memory = 0; parser->single_block = 0; @@ -273,7 +273,7 @@ /* made of several segments. We thus first read the number of */ /* segments to compute the total size of the private dictionary */ /* then re-read them into memory. */ - FT_Long start_pos = FT_STREAM_POS(); + FT_ULong start_pos = FT_STREAM_POS(); FT_UShort tag; @@ -332,17 +332,18 @@ /* dictionary block in the heap. */ /* first of all, look at the `eexec' keyword */ - FT_Byte* cur = parser->base_dict; - FT_Byte* limit = cur + parser->base_len; - FT_Byte c; + FT_Byte* cur = parser->base_dict; + FT_Byte* limit = cur + parser->base_len; + FT_Pointer pos_lf; + FT_Bool test_cr; Again: for (;;) { - c = cur[0]; - if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ - /* whitespace + 4 chars */ + if ( cur[0] == 'e' && + cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ + /* whitespace + 4 chars */ { if ( cur[1] == 'e' && cur[2] == 'x' && @@ -372,8 +373,15 @@ while ( cur < limit ) { - if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) - goto Found; + if ( cur[0] == 'e' && + cur + 5 < limit ) + { + if ( cur[1] == 'e' && + cur[2] == 'x' && + cur[3] == 'e' && + cur[4] == 'c' ) + goto Found; + } T1_Skip_PS_Token( parser ); if ( parser->root.error ) @@ -387,6 +395,15 @@ cur = limit; limit = parser->base_dict + parser->base_len; + + if ( cur >= limit ) + { + FT_ERROR(( "T1_Get_Private_Dict:" + " premature end in private dictionary\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + goto Again; /* now determine where to write the _encrypted_ binary private */ @@ -400,15 +417,26 @@ cur = parser->root.cursor; limit = parser->root.limit; - /* according to the Type1 spec, the first cipher byte must not be */ + /* According to the Type 1 spec, the first cipher byte must not be */ /* an ASCII whitespace character code (blank, tab, carriage return */ /* or line feed). We have seen Type 1 fonts with two line feed */ /* characters... So skip now all whitespace character codes. */ - while ( cur < limit && - ( *cur == ' ' || - *cur == '\t' || - *cur == '\r' || - *cur == '\n' ) ) + /* */ + /* On the other hand, Adobe's Type 1 parser handles fonts just */ + /* fine that are violating this limitation, so we add a heuristic */ + /* test to stop at \r only if it is not used for EOL. */ + + pos_lf = ft_memchr( cur, '\n', (size_t)( limit - cur ) ); + test_cr = FT_BOOL( !pos_lf || + pos_lf > ft_memchr( cur, + '\r', + (size_t)( limit - cur ) ) ); + + while ( cur < limit && + ( *cur == ' ' || + *cur == '\t' || + (test_cr && *cur == '\r' ) || + *cur == '\n' ) ) ++cur; if ( cur >= limit ) { @@ -418,7 +446,7 @@ goto Exit; } - size = (FT_ULong)( parser->base_len - ( cur - parser->base_dict ) ); + size = parser->base_len - (FT_ULong)( cur - parser->base_dict ); if ( parser->in_memory ) { @@ -432,7 +460,7 @@ parser->single_block = 1; parser->private_dict = parser->base_dict; parser->private_len = size; - parser->base_dict = 0; + parser->base_dict = NULL; parser->base_len = 0; } @@ -448,7 +476,7 @@ ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) ) { /* ASCII hexadecimal encoding */ - FT_Long len; + FT_ULong len; parser->root.cursor = cur; diff --git a/drivers/freetype/freetype/src/type1/t1parse.h b/drivers/freetype/src/type1/t1parse.h index fb1c8a8830..affa818e63 100644 --- a/drivers/freetype/freetype/src/type1/t1parse.h +++ b/drivers/freetype/src/type1/t1parse.h @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2008 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1PARSE_H__ -#define __T1PARSE_H__ +#ifndef T1PARSE_H_ +#define T1PARSE_H_ #include <ft2build.h> @@ -77,12 +77,6 @@ FT_BEGIN_HEADER #define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) -#define T1_Done_Table( p ) \ - do \ - { \ - if ( (p)->funcs.done ) \ - (p)->funcs.done( p ); \ - } while ( 0 ) #define T1_Release_Table( p ) \ do \ { \ @@ -129,7 +123,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1PARSE_H__ */ +#endif /* T1PARSE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type1/t1tokens.h b/drivers/freetype/src/type1/t1tokens.h index e37276b908..a84f291a6b 100644 --- a/drivers/freetype/freetype/src/type1/t1tokens.h +++ b/drivers/freetype/src/type1/t1tokens.h @@ -4,7 +4,7 @@ /* */ /* Type 1 tokenizer (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/type1/type1.c b/drivers/freetype/src/type1/type1.c index ccc12be103..bb8aca97f9 100644 --- a/drivers/freetype/freetype/src/type1/type1.c +++ b/drivers/freetype/src/type1/type1.c @@ -4,7 +4,7 @@ /* */ /* FreeType Type 1 driver component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/type42/Jamfile b/drivers/freetype/src/type42/Jamfile index 00371d54f3..a504ad17d3 100644 --- a/drivers/freetype/freetype/src/type42/Jamfile +++ b/drivers/freetype/src/type42/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/type42 Jamfile # -# Copyright 2002 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,10 @@ SubDir FT2_TOP $(FT2_SRC_DIR) type42 ; if $(FT2_MULTI) { - _sources = t42objs t42parse t42drivr ; + _sources = t42drivr + t42objs + t42parse + ; } else { diff --git a/drivers/freetype/freetype/src/type42/module.mk b/drivers/freetype/src/type42/module.mk index b3f10a8d3c..a7e27b7236 100644 --- a/drivers/freetype/freetype/src/type42/module.mk +++ b/drivers/freetype/src/type42/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2002, 2006 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/type42/rules.mk b/drivers/freetype/src/type42/rules.mk index eac1081eb1..80710eff67 100644 --- a/drivers/freetype/freetype/src/type42/rules.mk +++ b/drivers/freetype/src/type42/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002, 2003, 2008 by +# Copyright 2002-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,10 @@ T42_DIR := $(SRC_DIR)/type42 # compilation flags for the driver # -T42_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(T42_DIR)) +T42_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(T42_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # Type42 driver source diff --git a/drivers/freetype/freetype/src/type42/t42drivr.c b/drivers/freetype/src/type42/t42drivr.c index 3ad1bde79f..c63ed0c812 100644 --- a/drivers/freetype/freetype/src/type42/t42drivr.c +++ b/drivers/freetype/src/type42/t42drivr.c @@ -4,7 +4,7 @@ /* */ /* High-level Type 42 driver interface (body). */ /* */ -/* Copyright 2002-2004, 2006, 2007, 2009, 2011, 2013 by */ +/* Copyright 2002-2016 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,7 +41,7 @@ #include "t42error.h" #include FT_INTERNAL_DEBUG_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_GLYPH_DICT_H #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_POSTSCRIPT_INFO_H @@ -90,8 +90,8 @@ static const FT_Service_GlyphDictRec t42_service_glyph_dict = { - (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)t42_get_name_index + (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)t42_get_name_index /* name_index */ }; @@ -110,7 +110,7 @@ static const FT_Service_PsFontNameRec t42_service_ps_font_name = { - (FT_PsName_GetFunc)t42_get_ps_font_name + (FT_PsName_GetFunc)t42_get_ps_font_name /* get_ps_font_name */ }; @@ -161,11 +161,12 @@ static const FT_Service_PsInfoRec t42_service_ps_info = { - (PS_GetFontInfoFunc) t42_ps_get_font_info, - (PS_GetFontExtraFunc) t42_ps_get_font_extra, - (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, - (PS_GetFontPrivateFunc)t42_ps_get_font_private, - (PS_GetFontValueFunc) NULL /* not implemented */ + (PS_GetFontInfoFunc) t42_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) t42_ps_get_font_extra, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, /* ps_has_glyph_names */ + (PS_GetFontPrivateFunc)t42_ps_get_font_private, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ }; @@ -180,7 +181,7 @@ { FT_SERVICE_ID_GLYPH_DICT, &t42_service_glyph_dict }, { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t42_service_ps_font_name }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &t42_service_ps_info }, - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_42 }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TYPE_42 }, { NULL, NULL } }; @@ -212,32 +213,32 @@ 0x10000L, 0x20000L, - 0, /* format interface */ + 0, /* module-specific interface */ - T42_Driver_Init, - T42_Driver_Done, - T42_Get_Interface, + T42_Driver_Init, /* FT_Module_Constructor module_init */ + T42_Driver_Done, /* FT_Module_Destructor module_done */ + T42_Get_Interface, /* FT_Module_Requester get_interface */ }, sizeof ( T42_FaceRec ), sizeof ( T42_SizeRec ), sizeof ( T42_GlyphSlotRec ), - T42_Face_Init, - T42_Face_Done, - T42_Size_Init, - T42_Size_Done, - T42_GlyphSlot_Init, - T42_GlyphSlot_Done, + T42_Face_Init, /* FT_Face_InitFunc init_face */ + T42_Face_Done, /* FT_Face_DoneFunc done_face */ + T42_Size_Init, /* FT_Size_InitFunc init_size */ + T42_Size_Done, /* FT_Size_DoneFunc done_size */ + T42_GlyphSlot_Init, /* FT_Slot_InitFunc init_slot */ + T42_GlyphSlot_Done, /* FT_Slot_DoneFunc done_slot */ - T42_GlyphSlot_Load, + T42_GlyphSlot_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - 0, /* FT_Face_GetAdvancesFunc */ - T42_Size_Request, - T42_Size_Select + T42_Size_Request, /* FT_Size_RequestFunc request_size */ + T42_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/freetype/src/type42/t42drivr.h b/drivers/freetype/src/type42/t42drivr.h index 9a1e97e30e..6ddfb639d5 100644 --- a/drivers/freetype/freetype/src/type42/t42drivr.h +++ b/drivers/freetype/src/type42/t42drivr.h @@ -4,7 +4,8 @@ /* */ /* High-level Type 42 driver interface (specification). */ /* */ -/* Copyright 2002 by Roberto Alameda. */ +/* Copyright 2002-2016 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42DRIVR_H__ -#define __T42DRIVR_H__ +#ifndef T42DRIVR_H_ +#define T42DRIVR_H_ #include <ft2build.h> @@ -36,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42DRIVR_H__ */ +#endif /* T42DRIVR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type42/t42error.h b/drivers/freetype/src/type42/t42error.h index 217ae8bd52..e1097cc81e 100644 --- a/drivers/freetype/freetype/src/type42/t42error.h +++ b/drivers/freetype/src/type42/t42error.h @@ -4,7 +4,7 @@ /* */ /* Type 42 error codes (specification only). */ /* */ -/* Copyright 2002, 2003, 2012 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __T42ERROR_H__ -#define __T42ERROR_H__ +#ifndef T42ERROR_H_ +#define T42ERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX T42_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __T42ERROR_H__ */ +#endif /* T42ERROR_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type42/t42objs.c b/drivers/freetype/src/type42/t42objs.c index 18e2c0b625..4672c6e164 100644 --- a/drivers/freetype/freetype/src/type42/t42objs.c +++ b/drivers/freetype/src/type42/t42objs.c @@ -4,8 +4,8 @@ /* */ /* Type 42 objects manager (body). */ /* */ -/* Copyright 2002-2009, 2011, 2013 */ -/* by Roberto Alameda. */ +/* Copyright 2002-2016 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -47,6 +47,12 @@ if ( FT_ALLOC( face->ttf_data, 12 ) ) goto Exit; + /* while parsing the font we always update `face->ttf_size' so that */ + /* even in case of buggy data (which might lead to premature end of */ + /* scanning without causing an error) the call to `FT_Open_Face' in */ + /* `T42_Face_Init' passes the correct size */ + face->ttf_size = 12; + error = t42_parser_init( parser, face->root.stream, memory, @@ -86,8 +92,8 @@ /* the `lengths' field must be released later */ type1->glyph_names_block = loader.glyph_names.block; type1->glyph_names = (FT_String**)loader.glyph_names.elements; - loader.glyph_names.block = 0; - loader.glyph_names.elements = 0; + loader.glyph_names.block = NULL; + loader.glyph_names.elements = NULL; /* we must now build type1.encoding when we have a custom array */ if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) @@ -171,7 +177,6 @@ FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_UNUSED( stream ); @@ -203,7 +208,7 @@ goto Exit; /* check the face index */ - if ( face_index > 0 ) + if ( ( face_index & 0xFFFF ) > 0 ) { FT_ERROR(( "T42_Face_Init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); @@ -219,16 +224,13 @@ root->num_charmaps = 0; root->face_index = 0; - root->face_flags = FT_FACE_FLAG_SCALABLE | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_GLYPH_NAMES; + root->face_flags |= FT_FACE_FLAG_SCALABLE | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_GLYPH_NAMES; if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - /* We only set this flag if we have the patented bytecode interpreter. */ - /* There are no known `tricky' Type42 fonts that could be loaded with */ - /* the unpatented interpreter. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER root->face_flags |= FT_FACE_FLAG_HINTER; #endif @@ -280,14 +282,16 @@ /* no embedded bitmap support */ root->num_fixed_sizes = 0; - root->available_sizes = 0; + root->available_sizes = NULL; /* Load the TTF font embedded in the T42 font */ { FT_Open_Args args; - args.flags = FT_OPEN_MEMORY; + args.flags = FT_OPEN_MEMORY | FT_OPEN_DRIVER; + args.driver = FT_Get_Module( FT_FACE_LIBRARY( face ), + "truetype" ); args.memory_base = face->ttf_data; args.memory_size = face->ttf_size; @@ -454,8 +458,8 @@ FT_FREE( face->unicode_map.maps ); face->unicode_map.num_maps = 0; - face->root.family_name = 0; - face->root.style_name = 0; + face->root.family_name = NULL; + face->root.style_name = NULL; } @@ -507,7 +511,7 @@ FT_Face face = size->face; T42_Face t42face = (T42_Face)face; FT_Size ttsize; - FT_Error error = FT_Err_Ok; + FT_Error error; error = FT_New_Size( t42face->ttf_face, &ttsize ); @@ -625,10 +629,10 @@ slot->bitmap_left = 0; slot->bitmap_top = 0; slot->num_subglyphs = 0; - slot->subglyphs = 0; - slot->control_data = 0; + slot->subglyphs = NULL; + slot->control_data = NULL; slot->control_len = 0; - slot->other = 0; + slot->other = NULL; slot->format = FT_GLYPH_FORMAT_NONE; slot->linearHoriAdvance = 0; @@ -645,9 +649,16 @@ FT_Error error; T42_GlyphSlot t42slot = (T42_GlyphSlot)glyph; T42_Size t42size = (T42_Size)size; + T42_Face t42face = (T42_Face)size->face; FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz; + FT_TRACE1(( "T42_GlyphSlot_Load: glyph index %d\n", glyph_index )); + + /* map T42 glyph index to embedded TTF's glyph index */ + glyph_index = (FT_UInt)ft_atol( + (const char *)t42face->type1.charstrings[glyph_index] ); + t42_glyphslot_clear( t42slot->ttslot ); error = ttclazz->load_glyph( t42slot->ttslot, t42size->ttsize, diff --git a/drivers/freetype/freetype/src/type42/t42objs.h b/drivers/freetype/src/type42/t42objs.h index 02d13259be..87a40452f4 100644 --- a/drivers/freetype/freetype/src/type42/t42objs.h +++ b/drivers/freetype/src/type42/t42objs.h @@ -4,7 +4,8 @@ /* */ /* Type 42 objects manager (specification). */ /* */ -/* Copyright 2002, 2003, 2006, 2007, 2011 by Roberto Alameda. */ +/* Copyright 2002-2016 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42OBJS_H__ -#define __T42OBJS_H__ +#ifndef T42OBJS_H_ +#define T42OBJS_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -55,7 +56,6 @@ FT_BEGIN_HEADER { FT_DriverRec root; FT_Driver_Class ttclazz; - void* extension_component; } T42_DriverRec, *T42_Driver; @@ -118,7 +118,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42OBJS_H__ */ +#endif /* T42OBJS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type42/t42parse.c b/drivers/freetype/src/type42/t42parse.c index 3cdd8a1acf..f948916afa 100644 --- a/drivers/freetype/freetype/src/type42/t42parse.c +++ b/drivers/freetype/src/type42/t42parse.c @@ -4,7 +4,7 @@ /* */ /* Type 42 font parser (body). */ /* */ -/* Copyright 2002-2013 by */ +/* Copyright 2002-2016 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -104,12 +104,6 @@ #define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) -#define T1_Done_Table( p ) \ - do \ - { \ - if ( (p)->funcs.done ) \ - (p)->funcs.done( p ); \ - } while ( 0 ) #define T1_Release_Table( p ) \ do \ { \ @@ -148,11 +142,11 @@ FT_Long size; - psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + psaux->ps_parser_funcs->init( &parser->root, NULL, NULL, memory ); parser->stream = stream; parser->base_len = 0; - parser->base_dict = 0; + parser->base_dict = NULL; parser->in_memory = 0; /*******************************************************************/ @@ -184,7 +178,7 @@ if ( error || FT_STREAM_SEEK( 0 ) ) goto Exit; - size = stream->size; + size = (FT_Long)stream->size; /* now, try to load `size' bytes of the `base' dictionary we */ /* found previously */ @@ -252,22 +246,29 @@ T42_Parser parser = &loader->parser; FT_Matrix* matrix = &face->type1.font_matrix; FT_Vector* offset = &face->type1.font_offset; - FT_Face root = (FT_Face)&face->root; FT_Fixed temp[6]; FT_Fixed temp_scale; + FT_Int result; - (void)T1_ToFixedArray( parser, 6, temp, 3 ); + result = T1_ToFixedArray( parser, 6, temp, 0 ); - temp_scale = FT_ABS( temp[3] ); + if ( result < 6 ) + { + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } - /* Set Units per EM based on FontMatrix values. We set the value to */ - /* 1000 / temp_scale, because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed, from psobjs.c). */ + temp_scale = FT_ABS( temp[3] ); - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + if ( temp_scale == 0 ) + { + FT_ERROR(( "t42_parse_font_matrix: invalid font matrix\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } - /* we need to scale the values by 1.0/temp_scale */ + /* atypical case */ if ( temp_scale != 0x10000L ) { temp[0] = FT_DivFix( temp[0], temp_scale ); @@ -275,7 +276,7 @@ temp[2] = FT_DivFix( temp[2], temp_scale ); temp[4] = FT_DivFix( temp[4], temp_scale ); temp[5] = FT_DivFix( temp[5], temp_scale ); - temp[3] = 0x10000L; + temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L; } matrix->xx = temp[0]; @@ -314,7 +315,7 @@ if ( ft_isdigit( *cur ) || *cur == '[' ) { T1_Encoding encode = &face->type1.encoding; - FT_UInt count, n; + FT_Int count, n; PS_Table char_table = &loader->encoding_table; FT_Memory memory = parser->root.memory; FT_Error error; @@ -329,12 +330,29 @@ parser->root.cursor++; } else - count = (FT_UInt)T1_ToInt( parser ); + count = (FT_Int)T1_ToInt( parser ); + + /* only composite fonts (which we don't support) */ + /* can have larger values */ + if ( count > 256 ) + { + FT_ERROR(( "t42_parse_encoding: invalid encoding array size\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } T1_Skip_Spaces( parser ); if ( parser->root.cursor >= limit ) return; + /* PostScript happily allows overwriting of encoding arrays */ + if ( encode->char_index ) + { + FT_FREE( encode->char_index ); + FT_FREE( encode->char_name ); + T1_Release_Table( char_table ); + } + /* we use a T1_Table to store our charnames */ loader->num_chars = encode->num_chars = count; if ( FT_NEW_ARRAY( encode->char_index, count ) || @@ -352,7 +370,7 @@ char* notdef = (char *)".notdef"; - T1_Add_Table( char_table, n, notdef, 8 ); + (void)T1_Add_Table( char_table, n, notdef, 8 ); } /* Now we need to read records of the form */ @@ -413,23 +431,32 @@ { charcode = (FT_Int)T1_ToInt( parser ); T1_Skip_Spaces( parser ); + + /* protect against invalid charcode */ + if ( cur == parser->root.cursor ) + { + parser->root.error = FT_THROW( Unknown_File_Format ); + return; + } } cur = parser->root.cursor; - if ( *cur == '/' && cur + 2 < limit && n < count ) + if ( cur + 2 < limit && *cur == '/' && n < count ) { - FT_PtrDist len; + FT_UInt len; cur++; parser->root.cursor = cur; T1_Skip_PS_Token( parser ); + if ( parser->root.cursor >= limit ) + return; if ( parser->root.error ) return; - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); parser->root.error = T1_Add_Table( char_table, charcode, cur, len + 1 ); @@ -439,6 +466,19 @@ n++; } + else if ( only_immediates ) + { + /* Since the current position is not updated for */ + /* immediates-only mode we would get an infinite loop if */ + /* we don't do anything here. */ + /* */ + /* This encoding array is not valid according to the */ + /* type42 specification (it might be an encoding for a CID */ + /* type42 font, however), so we conclude that this font is */ + /* NOT a type42 font. */ + parser->root.error = FT_THROW( Unknown_File_Format ); + return; + } } else { @@ -450,8 +490,8 @@ T1_Skip_Spaces( parser ); } - face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; - parser->root.cursor = cur; + face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + parser->root.cursor = cur; } /* Otherwise, we should have either `StandardEncoding', */ @@ -471,10 +511,7 @@ face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; else - { - FT_ERROR(( "t42_parse_encoding: invalid token\n" )); - parser->root.error = FT_THROW( Invalid_File_Format ); - } + parser->root.error = FT_ERR( Ignore ); } } @@ -498,9 +535,9 @@ FT_Byte* limit = parser->root.limit; FT_Error error; FT_Int num_tables = 0; - FT_ULong count, ttf_size = 0; + FT_Long count; - FT_Long n, string_size, old_string_size, real_size; + FT_ULong n, string_size, old_string_size, real_size; FT_Byte* string_buf = NULL; FT_Bool allocated = 0; @@ -538,6 +575,9 @@ while ( parser->root.cursor < limit ) { + FT_ULong size; + + cur = parser->root.cursor; if ( *cur == ']' ) @@ -553,7 +593,13 @@ goto Exit; /* don't include delimiters */ - string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 ); + string_size = (FT_ULong)( ( parser->root.cursor - cur - 2 + 1 ) / 2 ); + if ( !string_size ) + { + FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } if ( FT_REALLOC( string_buf, old_string_size, string_size ) ) goto Fail; @@ -562,11 +608,14 @@ parser->root.cursor = cur; (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 ); old_string_size = string_size; - string_size = real_size; + string_size = real_size; } else if ( ft_isdigit( *cur ) ) { + FT_Long tmp; + + if ( allocated ) { FT_ERROR(( "t42_parse_sfnts: " @@ -575,13 +624,15 @@ goto Fail; } - string_size = T1_ToInt( parser ); - if ( string_size < 0 ) + tmp = T1_ToInt( parser ); + if ( tmp < 0 ) { FT_ERROR(( "t42_parse_sfnts: invalid string size\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } + else + string_size = (FT_ULong)tmp; T1_Skip_PS_Token( parser ); /* `RD' */ if ( parser->root.error ) @@ -589,9 +640,9 @@ string_buf = parser->root.cursor + 1; /* one space after `RD' */ - if ( limit - parser->root.cursor < string_size ) + if ( (FT_ULong)( limit - parser->root.cursor ) <= string_size ) { - FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); + FT_ERROR(( "t42_parse_sfnts: too much binary data\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } @@ -618,6 +669,11 @@ goto Fail; } + /* The whole TTF is now loaded into `string_buf'. We are */ + /* checking its contents while copying it to `ttf_data'. */ + + size = (FT_ULong)( limit - parser->root.cursor ); + for ( n = 0; n < string_size; n++ ) { switch ( status ) @@ -631,18 +687,25 @@ } else { - num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; - status = BEFORE_TABLE_DIR; - ttf_size = 12 + 16 * num_tables; + num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; + status = BEFORE_TABLE_DIR; + face->ttf_size = 12 + 16 * num_tables; - if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) ) + if ( (FT_Long)size < face->ttf_size ) + { + FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + if ( FT_REALLOC( face->ttf_data, 12, face->ttf_size ) ) goto Fail; } /* fall through */ case BEFORE_TABLE_DIR: /* the offset table is read; read the table directory */ - if ( count < ttf_size ) + if ( count < face->ttf_size ) { face->ttf_data[count++] = string_buf[n]; continue; @@ -659,26 +722,32 @@ len = FT_PEEK_ULONG( p ); + if ( len > size || + face->ttf_size > (FT_Long)( size - len ) ) + { + FT_ERROR(( "t42_parse_sfnts:" + " invalid data in sfnts array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } /* Pad to a 4-byte boundary length */ - ttf_size += ( len + 3 ) & ~3; + face->ttf_size += (FT_Long)( ( len + 3 ) & ~3U ); } - status = OTHER_TABLES; - face->ttf_size = ttf_size; + status = OTHER_TABLES; - /* there are no more than 256 tables, so no size check here */ if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, - ttf_size + 1 ) ) + face->ttf_size + 1 ) ) goto Fail; } /* fall through */ case OTHER_TABLES: /* all other tables are just copied */ - if ( count >= ttf_size ) + if ( count >= face->ttf_size ) { - FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); + FT_ERROR(( "t42_parse_sfnts: too much binary data\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } @@ -716,8 +785,8 @@ FT_Byte* cur; FT_Byte* limit = parser->root.limit; - FT_UInt n; - FT_UInt notdef_index = 0; + FT_Int n; + FT_Int notdef_index = 0; FT_Byte notdef_found = 0; @@ -732,15 +801,32 @@ if ( ft_isdigit( *parser->root.cursor ) ) { - loader->num_glyphs = (FT_UInt)T1_ToInt( parser ); + loader->num_glyphs = T1_ToInt( parser ); if ( parser->root.error ) return; + if ( loader->num_glyphs < 0 ) + { + FT_ERROR(( "t42_parse_encoding: invalid number of glyphs\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* we certainly need more than 4 bytes per glyph */ + if ( loader->num_glyphs > ( limit - parser->root.cursor ) >> 2 ) + { + FT_TRACE0(( "t42_parse_charstrings: adjusting number of glyphs" + " (from %d to %d)\n", + loader->num_glyphs, + ( limit - parser->root.cursor ) >> 2 )); + loader->num_glyphs = ( limit - parser->root.cursor ) >> 2; + } + } else if ( *parser->root.cursor == '<' ) { /* We have `<< ... >>'. Count the number of `/' in the dictionary */ /* to get its size. */ - FT_UInt count = 0; + FT_Int count = 0; T1_Skip_PS_Token( parser ); @@ -781,6 +867,15 @@ /* initialize tables */ + /* contrary to Type1, we disallow multiple CharStrings arrays */ + if ( swap_table->init ) + { + FT_ERROR(( "t42_parse_charstrings:" + " only one CharStrings array allowed\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + error = psaux->ps_table_funcs->init( code_table, loader->num_glyphs, memory ); @@ -804,8 +899,13 @@ for (;;) { - /* The format is simple: */ - /* `/glyphname' + index [+ def] */ + /* We support two formats. */ + /* */ + /* `/glyphname' + index [+ `def'] */ + /* `(glyphname)' [+ `cvn'] + index [+ `def'] */ + /* */ + /* The latter format gets created by the */ + /* LilyPond typesetting program. */ T1_Skip_Spaces( parser ); @@ -824,15 +924,22 @@ break; T1_Skip_PS_Token( parser ); + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } if ( parser->root.error ) return; - if ( *cur == '/' ) + if ( *cur == '/' || *cur == '(' ) { - FT_PtrDist len; + FT_UInt len; + FT_Bool have_literal = ( *cur == '(' ); - if ( cur + 1 >= limit ) + if ( cur + ( have_literal ? 3 : 2 ) >= limit ) { FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = FT_THROW( Invalid_File_Format ); @@ -840,7 +947,9 @@ } cur++; /* skip `/' */ - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); + if ( have_literal ) + len--; error = T1_Add_Table( name_table, n, cur, len + 1 ); if ( error ) @@ -860,6 +969,9 @@ T1_Skip_Spaces( parser ); + if ( have_literal ) + T1_Skip_PS_Token( parser ); + cur = parser->root.cursor; (void)T1_ToInt( parser ); @@ -870,7 +982,7 @@ goto Fail; } - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); error = T1_Add_Table( code_table, n, cur, len + 1 ); if ( error ) @@ -1091,7 +1203,7 @@ /* look for immediates */ else if ( *cur == '/' && cur + 2 < limit ) { - FT_PtrDist len; + FT_UInt len; cur++; @@ -1101,7 +1213,7 @@ if ( parser->root.error ) goto Exit; - len = parser->root.cursor - cur; + len = (FT_UInt)( parser->root.cursor - cur ); if ( len > 0 && len < 22 && parser->root.cursor < limit ) { @@ -1120,9 +1232,9 @@ if ( !name ) continue; - if ( cur[0] == name[0] && - len == (FT_PtrDist)ft_strlen( (const char *)name ) && - ft_memcmp( cur, name, len ) == 0 ) + if ( cur[0] == name[0] && + len == ft_strlen( (const char *)name ) && + ft_memcmp( cur, name, len ) == 0 ) { /* we found it -- run the parsing callback! */ parser->root.error = t42_load_keyword( face, diff --git a/drivers/freetype/freetype/src/type42/t42parse.h b/drivers/freetype/src/type42/t42parse.h index f77ec4af4f..ba9e857190 100644 --- a/drivers/freetype/freetype/src/type42/t42parse.h +++ b/drivers/freetype/src/type42/t42parse.h @@ -4,7 +4,8 @@ /* */ /* Type 42 font parser (specification). */ /* */ -/* Copyright 2002, 2003 by Roberto Alameda. */ +/* Copyright 2002-2016 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42PARSE_H__ -#define __T42PARSE_H__ +#ifndef T42PARSE_H_ +#define T42PARSE_H_ #include "t42objs.h" @@ -42,11 +43,11 @@ FT_BEGIN_HEADER { T42_ParserRec parser; /* parser used to read the stream */ - FT_UInt num_chars; /* number of characters in encoding */ + FT_Int num_chars; /* number of characters in encoding */ PS_TableRec encoding_table; /* PS_Table used to store the */ /* encoding character names */ - FT_UInt num_glyphs; + FT_Int num_glyphs; PS_TableRec glyph_names; PS_TableRec charstrings; PS_TableRec swap_table; /* For moving .notdef glyph to index 0. */ @@ -84,7 +85,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42PARSE_H__ */ +#endif /* T42PARSE_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type42/t42types.h b/drivers/freetype/src/type42/t42types.h index c7c2db490d..850a156e45 100644 --- a/drivers/freetype/freetype/src/type42/t42types.h +++ b/drivers/freetype/src/type42/t42types.h @@ -4,7 +4,8 @@ /* */ /* Type 42 font data types (specification only). */ /* */ -/* Copyright 2002, 2003, 2006, 2008 by Roberto Alameda. */ +/* Copyright 2002-2016 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -15,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42TYPES_H__ -#define __T42TYPES_H__ +#ifndef T42TYPES_H_ +#define T42TYPES_H_ #include <ft2build.h> @@ -39,7 +40,7 @@ FT_BEGIN_HEADER const void* afm_data; #endif FT_Byte* ttf_data; - FT_ULong ttf_size; + FT_Long ttf_size; FT_Face ttf_face; FT_CharMapRec charmaprecs[2]; FT_CharMap charmaps[2]; @@ -50,7 +51,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42TYPES_H__ */ +#endif /* T42TYPES_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/type42/type42.c b/drivers/freetype/src/type42/type42.c index d13df56b10..0d17a9b1dc 100644 --- a/drivers/freetype/freetype/src/type42/type42.c +++ b/drivers/freetype/src/type42/type42.c @@ -4,7 +4,7 @@ /* */ /* FreeType Type 42 driver component. */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/drivers/freetype/freetype/src/winfonts/Jamfile b/drivers/freetype/src/winfonts/Jamfile index 71cf5678e8..d81165e921 100644 --- a/drivers/freetype/freetype/src/winfonts/Jamfile +++ b/drivers/freetype/src/winfonts/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/winfonts Jamfile # -# Copyright 2001 by +# Copyright 2001-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/winfonts/fnterrs.h b/drivers/freetype/src/winfonts/fnterrs.h index 463ba77ee2..6835d3e64f 100644 --- a/drivers/freetype/freetype/src/winfonts/fnterrs.h +++ b/drivers/freetype/src/winfonts/fnterrs.h @@ -4,7 +4,7 @@ /* */ /* Win FNT/FON error codes (specification only). */ /* */ -/* Copyright 2001, 2012 by */ +/* Copyright 2001-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __FNTERRS_H__ -#define __FNTERRS_H__ +#ifndef FNTERRS_H_ +#define FNTERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX FNT_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __FNTERRS_H__ */ +#endif /* FNTERRS_H_ */ /* END */ diff --git a/drivers/freetype/freetype/src/winfonts/module.mk b/drivers/freetype/src/winfonts/module.mk index b44d7f0570..83da5732f1 100644 --- a/drivers/freetype/freetype/src/winfonts/module.mk +++ b/drivers/freetype/src/winfonts/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2006 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/drivers/freetype/freetype/src/winfonts/rules.mk b/drivers/freetype/src/winfonts/rules.mk index 71a7df2d8a..2fd7b822a2 100644 --- a/drivers/freetype/freetype/src/winfonts/rules.mk +++ b/drivers/freetype/src/winfonts/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003 by +# Copyright 1996-2016 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -18,7 +18,10 @@ FNT_DIR := $(SRC_DIR)/winfonts -FNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(FNT_DIR)) +FNT_COMPILE := $(CC) $(ANSIFLAGS) \ + $I$(subst /,$(COMPILER_SEP),$(FNT_DIR)) \ + $(INCLUDE_FLAGS) \ + $(FT_CFLAGS) # Windows driver sources (i.e., C files) diff --git a/drivers/freetype/freetype/src/winfonts/winfnt.c b/drivers/freetype/src/winfonts/winfnt.c index e8055c0898..1c74ccd5ab 100644 --- a/drivers/freetype/freetype/src/winfonts/winfnt.c +++ b/drivers/freetype/src/winfonts/winfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2004, 2006-2013 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* Copyright 2003 Huw D M Davies for Codeweavers */ /* Copyright 2007 Dmitry Timoshkov for Codeweavers */ @@ -28,7 +28,7 @@ #include "winfnt.h" #include "fnterrs.h" #include FT_SERVICE_WINFNT_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H /*************************************************************************/ /* */ @@ -72,12 +72,12 @@ FT_FRAME_START( 248 ), FT_FRAME_ULONG_LE ( magic ), /* PE00 */ - FT_FRAME_USHORT_LE ( machine ), /* 0x014c - i386 */ + FT_FRAME_USHORT_LE ( machine ), /* 0x014C - i386 */ FT_FRAME_USHORT_LE ( number_of_sections ), FT_FRAME_SKIP_BYTES( 12 ), FT_FRAME_USHORT_LE ( size_of_optional_header ), FT_FRAME_SKIP_BYTES( 2 ), - FT_FRAME_USHORT_LE ( magic32 ), /* 0x10b */ + FT_FRAME_USHORT_LE ( magic32 ), /* 0x10B */ FT_FRAME_SKIP_BYTES( 110 ), FT_FRAME_ULONG_LE ( rsrc_virtual_address ), FT_FRAME_ULONG_LE ( rsrc_size ), @@ -201,7 +201,7 @@ FT_FREE( font->family_name ); FT_FREE( font ); - face->font = 0; + face->font = NULL; } @@ -269,15 +269,18 @@ static FT_Error fnt_face_get_dll_font( FNT_Face face, - FT_Int face_index ) + FT_Int face_instance_index ) { FT_Error error; FT_Stream stream = FT_FACE( face )->stream; FT_Memory memory = FT_FACE( face )->memory; WinMZ_HeaderRec mz_header; + FT_Long face_index; - face->font = 0; + face->font = NULL; + + face_index = FT_ABS( face_instance_index ) & 0xFFFF; /* does it begin with an MZ header? */ if ( FT_STREAM_SEEK( 0 ) || @@ -317,6 +320,21 @@ size_shift = FT_GET_USHORT_LE(); + /* Microsoft's specification of the executable-file header format */ + /* for `New Executable' (NE) doesn't give a limit for the */ + /* alignment shift count; however, in 1985, the year of the */ + /* specification release, only 32bit values were supported, thus */ + /* anything larger than 16 doesn't make sense in general, given */ + /* that file offsets are 16bit values, shifted by the alignment */ + /* shift count */ + if ( size_shift > 16 ) + { + FT_TRACE2(( "invalid alignment shift count for resource data\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + for (;;) { FT_UShort type_id, count; @@ -331,8 +349,8 @@ if ( type_id == 0x8008U ) { font_count = count; - font_offset = (FT_ULong)( FT_STREAM_POS() + 4 + - ( stream->cursor - stream->limit ) ); + font_offset = FT_STREAM_POS() + 4 + + (FT_ULong)( stream->cursor - stream->limit ); break; } @@ -359,19 +377,20 @@ face->root.num_faces = font_count; + if ( face_instance_index < 0 ) + goto Exit; + if ( face_index >= font_count ) { error = FT_THROW( Invalid_Argument ); goto Exit; } - else if ( face_index < 0 ) - goto Exit; if ( FT_NEW( face->font ) ) goto Exit; - if ( FT_STREAM_SEEK( font_offset + face_index * 12 ) || - FT_FRAME_ENTER( 12 ) ) + if ( FT_STREAM_SEEK( font_offset + (FT_ULong)face_index * 12 ) || + FT_FRAME_ENTER( 12 ) ) goto Fail; face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift; @@ -391,7 +410,7 @@ WinPE_RsrcDirEntryRec dir_entry1, dir_entry2, dir_entry3; WinPE_RsrcDataEntryRec data_entry; - FT_Long root_dir_offset, name_dir_offset, lang_dir_offset; + FT_ULong root_dir_offset, name_dir_offset, lang_dir_offset; FT_UShort i, j, k; @@ -412,9 +431,9 @@ pe32_header.rsrc_size )); if ( pe32_header.magic != WINFNT_PE_MAGIC /* check full signature */ || - pe32_header.machine != 0x014c /* i386 */ || - pe32_header.size_of_optional_header != 0xe0 /* FIXME */ || - pe32_header.magic32 != 0x10b ) + pe32_header.machine != 0x014C /* i386 */ || + pe32_header.size_of_optional_header != 0xE0 /* FIXME */ || + pe32_header.magic32 != 0x10B ) { FT_TRACE2(( "this file has an invalid PE header\n" )); error = FT_THROW( Invalid_File_Format ); @@ -591,11 +610,14 @@ static FT_Error - fnt_cmap_init( FNT_CMap cmap ) + fnt_cmap_init( FNT_CMap cmap, + FT_Pointer pointer ) { FNT_Face face = (FNT_Face)FT_CMAP_FACE( cmap ); FNT_Font font = face->font; + FT_UNUSED( pointer ); + cmap->first = (FT_UInt32) font->header.first_char; cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 ); @@ -686,13 +708,14 @@ static FT_Error FNT_Face_Init( FT_Stream stream, FT_Face fntface, /* FNT_Face */ - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { FNT_Face face = (FNT_Face)fntface; FT_Error error; FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Int face_index; FT_UNUSED( num_params ); FT_UNUSED( params ); @@ -700,9 +723,11 @@ FT_TRACE2(( "Windows FNT driver\n" )); + face_index = FT_ABS( face_instance_index ) & 0xFFFF; + /* try to load font from a DLL */ - error = fnt_face_get_dll_font( face, face_index ); - if ( !error && face_index < 0 ) + error = fnt_face_get_dll_font( face, face_instance_index ); + if ( !error && face_instance_index < 0 ) goto Exit; if ( FT_ERR_EQ( error, Unknown_File_Format ) ) @@ -723,10 +748,11 @@ if ( !error ) { + if ( face_instance_index < 0 ) + goto Exit; + if ( face_index > 0 ) error = FT_THROW( Invalid_Argument ); - else if ( face_index < 0 ) - goto Exit; } } @@ -736,15 +762,15 @@ /* we now need to fill the root FT_Face fields */ /* with relevant information */ { - FT_Face root = FT_FACE( face ); - FNT_Font font = face->font; - FT_PtrDist family_size; + FT_Face root = FT_FACE( face ); + FNT_Font font = face->font; + FT_ULong family_size; root->face_index = face_index; - root->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL; + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL; if ( font->header.avg_width == font->header.max_width ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; @@ -766,9 +792,9 @@ FT_UShort x_res, y_res; - bsize->width = font->header.avg_width; - bsize->height = (FT_Short)( - font->header.pixel_height + font->header.external_leading ); + bsize->width = (FT_Short)font->header.avg_width; + bsize->height = (FT_Short)( font->header.pixel_height + + font->header.external_leading ); bsize->size = font->header.nominal_point_size << 6; x_res = font->header.horizontal_resolution; @@ -961,7 +987,7 @@ FNT_Font font; FT_Error error = FT_Err_Ok; FT_Byte* p; - FT_Int len; + FT_UInt len; FT_Bitmap* bitmap = &slot->bitmap; FT_ULong offset; FT_Bool new_format; @@ -971,32 +997,44 @@ if ( !face ) { - error = FT_THROW( Invalid_Argument ); + error = FT_THROW( Invalid_Face_Handle ); goto Exit; } font = face->font; - if ( !font || + if ( !font || glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) ) { error = FT_THROW( Invalid_Argument ); goto Exit; } + FT_TRACE1(( "FNT_Load_Glyph: glyph index %d\n", glyph_index )); + if ( glyph_index > 0 ) glyph_index--; /* revert to real index */ else - glyph_index = font->header.default_char; /* the .notdef glyph */ + glyph_index = font->header.default_char; /* the `.notdef' glyph */ new_format = FT_BOOL( font->header.version == 0x300 ); len = new_format ? 6 : 4; - /* jump to glyph entry */ - p = font->fnt_frame + ( new_format ? 148 : 118 ) + len * glyph_index; + /* get glyph width and offset */ + offset = ( new_format ? 148 : 118 ) + len * glyph_index; - bitmap->width = FT_NEXT_SHORT_LE( p ); + if ( offset >= font->header.file_size - 2 - ( new_format ? 4 : 2 ) ) + { + FT_TRACE2(( "invalid FNT offset\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + p = font->fnt_frame + offset; + + bitmap->width = FT_NEXT_USHORT_LE( p ); + + /* jump to glyph entry */ if ( new_format ) offset = FT_NEXT_ULONG_LE( p ); else @@ -1015,16 +1053,16 @@ /* allocate and build bitmap */ { FT_Memory memory = FT_FACE_MEMORY( slot->face ); - FT_Int pitch = ( bitmap->width + 7 ) >> 3; + FT_UInt pitch = ( bitmap->width + 7 ) >> 3; FT_Byte* column; FT_Byte* write; - bitmap->pitch = pitch; + bitmap->pitch = (int)pitch; bitmap->rows = font->header.pixel_height; bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - if ( offset + pitch * bitmap->rows >= font->header.file_size ) + if ( offset + pitch * bitmap->rows > font->header.file_size ) { FT_TRACE2(( "invalid bitmap width\n" )); error = FT_THROW( Invalid_File_Format ); @@ -1054,14 +1092,14 @@ slot->format = FT_GLYPH_FORMAT_BITMAP; /* now set up metrics */ - slot->metrics.width = bitmap->width << 6; - slot->metrics.height = bitmap->rows << 6; - slot->metrics.horiAdvance = bitmap->width << 6; + slot->metrics.width = (FT_Pos)( bitmap->width << 6 ); + slot->metrics.height = (FT_Pos)( bitmap->rows << 6 ); + slot->metrics.horiAdvance = (FT_Pos)( bitmap->width << 6 ); slot->metrics.horiBearingX = 0; slot->metrics.horiBearingY = slot->bitmap_top << 6; ft_synthesize_vertical_metrics( &slot->metrics, - bitmap->rows << 6 ); + (FT_Pos)( bitmap->rows << 6 ) ); Exit: return error; @@ -1083,7 +1121,7 @@ static const FT_Service_WinFntRec winfnt_service_rec = { - winfnt_get_header + winfnt_get_header /* get_header */ }; /* @@ -1093,8 +1131,8 @@ static const FT_ServiceDescRec winfnt_services[] = { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_WINFNT }, - { FT_SERVICE_ID_WINFNT, &winfnt_service_rec }, + { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_WINFNT }, + { FT_SERVICE_ID_WINFNT, &winfnt_service_rec }, { NULL, NULL } }; @@ -1123,32 +1161,32 @@ 0x10000L, 0x20000L, - 0, + 0, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - winfnt_get_service + 0, /* FT_Module_Constructor module_init */ + 0, /* FT_Module_Destructor module_done */ + winfnt_get_service /* FT_Module_Requester get_interface */ }, sizeof ( FNT_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - FNT_Face_Init, - FNT_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ + FNT_Face_Init, /* FT_Face_InitFunc init_face */ + FNT_Face_Done, /* FT_Face_DoneFunc done_face */ + 0, /* FT_Size_InitFunc init_size */ + 0, /* FT_Size_DoneFunc done_size */ + 0, /* FT_Slot_InitFunc init_slot */ + 0, /* FT_Slot_DoneFunc done_slot */ - FNT_Load_Glyph, + FNT_Load_Glyph, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + 0, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + 0, /* FT_Face_GetAdvancesFunc get_advances */ - FNT_Size_Request, - FNT_Size_Select + FNT_Size_Request, /* FT_Size_RequestFunc request_size */ + FNT_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/drivers/freetype/freetype/src/winfonts/winfnt.h b/drivers/freetype/src/winfonts/winfnt.h index b7a80736d8..9a4f32d5b0 100644 --- a/drivers/freetype/freetype/src/winfonts/winfnt.h +++ b/drivers/freetype/src/winfonts/winfnt.h @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */ +/* Copyright 1996-2016 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* Copyright 2007 Dmitry Timoshkov for Codeweavers */ /* */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __WINFNT_H__ -#define __WINFNT_H__ +#ifndef WINFNT_H_ +#define WINFNT_H_ #include <ft2build.h> @@ -165,7 +165,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __WINFNT_H__ */ +#endif /* WINFNT_H_ */ /* END */ diff --git a/drivers/rtaudio/RtAudio.cpp b/drivers/rtaudio/RtAudio.cpp index 86981e56d2..04159776f7 100644 --- a/drivers/rtaudio/RtAudio.cpp +++ b/drivers/rtaudio/RtAudio.cpp @@ -1,4 +1,5 @@ -#ifdef RTAUDIO_ENABLED +#ifdef RTAUDIO_ENABLED // -GODOT- + /************************************************************************/ /*! \class RtAudio \brief Realtime audio i/o C++ classes. @@ -11,7 +12,7 @@ RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/ RtAudio: realtime audio i/o C++ classes - Copyright (c) 2001-2014 Gary P. Scavone + Copyright (c) 2001-2016 Gary P. Scavone Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -39,7 +40,7 @@ */ /************************************************************************/ -// RtAudio: Version 4.1.1 +// RtAudio: Version 4.1.2 #include "RtAudio.h" #include <iostream> @@ -56,11 +57,7 @@ const unsigned int RtApi::SAMPLE_RATES[] = { }; #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__) -#ifdef WINRT_ENABLED - #define MUTEX_INITIALIZE(A) InitializeCriticalSectionEx(A, 0, 0) -#else #define MUTEX_INITIALIZE(A) InitializeCriticalSection(A) -#endif #define MUTEX_DESTROY(A) DeleteCriticalSection(A) #define MUTEX_LOCK(A) EnterCriticalSection(A) #define MUTEX_UNLOCK(A) LeaveCriticalSection(A) @@ -139,7 +136,8 @@ void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis ) throw() void RtAudio :: openRtApi( RtAudio::Api api ) { - delete rtapi_; + if ( rtapi_ ) + delete rtapi_; rtapi_ = 0; #if defined(__UNIX_JACK__) @@ -215,7 +213,8 @@ RtAudio :: RtAudio( RtAudio::Api api ) RtAudio :: ~RtAudio() throw() { - delete rtapi_; + if ( rtapi_ ) + delete rtapi_; } void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters, @@ -418,7 +417,7 @@ double RtApi :: getStreamTime( void ) then = stream_.lastTickTimestamp; return stream_.streamTime + ((now.tv_sec + 0.000001 * now.tv_usec) - - (then.tv_sec + 0.000001 * then.tv_usec)); + (then.tv_sec + 0.000001 * then.tv_usec)); #else return stream_.streamTime; #endif @@ -1832,7 +1831,7 @@ bool RtApiCore :: callbackEvent( AudioDeviceID deviceId, channelsLeft -= streamChannels; } } - + if ( stream_.doConvertBuffer[1] ) { // convert from our internal "device" buffer convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, @@ -2719,7 +2718,7 @@ RtApiAsio :: RtApiAsio() // CoInitialize beforehand, but it must be for appartment threading // (in which case, CoInitilialize will return S_FALSE here). coInitialized_ = false; - HRESULT hr = CoInitialize( NULL ); + HRESULT hr = CoInitialize( NULL ); if ( FAILED(hr) ) { errorText_ = "RtApiAsio::ASIO requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)"; error( RtAudioError::WARNING ); @@ -3170,7 +3169,7 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne errorText_ = errorStream_.str(); goto error; } - buffersAllocated = true; + buffersAllocated = true; stream_.state = STREAM_STOPPED; // Set flags for buffer conversion. @@ -3644,13 +3643,13 @@ static long asioMessages( long selector, long value, void* /*message*/, double* static const char* getAsioErrorString( ASIOError result ) { - struct Messages + struct Messages { ASIOError value; const char*message; }; - static const Messages m[] = + static const Messages m[] = { { ASE_NotPresent, "Hardware input or output is not present or available." }, { ASE_HWMalfunction, "Hardware is malfunctioning." }, @@ -5161,10 +5160,10 @@ void RtApiWasapi::wasapiThread() // if the callback buffer was pushed renderBuffer reset callbackPulled flag if ( callbackPushed ) { callbackPulled = false; + // tick stream time + RtApi::tickStreamTime(); } - // tick stream time - RtApi::tickStreamTime(); } Exit: @@ -5192,7 +5191,7 @@ Exit: #if defined(__WINDOWS_DS__) // Windows DirectSound API // Modified by Robin Davies, October 2005 -// - Improvements to DirectX pointer chasing. +// - Improvements to DirectX pointer chasing. // - Bug fix for non-power-of-two Asio granularity used by Edirol PCR-A30. // - Auto-call CoInitialize for DSOUND and ASIO platforms. // Various revisions for RtAudio 4.0 by Gary Scavone, April 2007 @@ -5232,7 +5231,7 @@ struct DsHandle { void *id[2]; void *buffer[2]; bool xrun[2]; - UINT bufferPointer[2]; + UINT bufferPointer[2]; DWORD dsBufferSize[2]; DWORD dsPointerLeadTime[2]; // the number of bytes ahead of the safe pointer to lead by. HANDLE condition; @@ -6080,7 +6079,7 @@ void RtApiDs :: startStream() // Increase scheduler frequency on lesser windows (a side-effect of // increasing timer accuracy). On greater windows (Win2K or later), // this is already in effect. - timeBeginPeriod( 1 ); + timeBeginPeriod( 1 ); buffersRolling = false; duplexPrerollBytes = 0; @@ -6401,7 +6400,7 @@ void RtApiDs :: callbackEvent() } if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - + LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0]; if ( handle->drainCounter > 1 ) { // write zeros to the output stream @@ -6441,6 +6440,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6467,7 +6467,7 @@ void RtApiDs :: callbackEvent() } if ( dsPointerBetween( nextWritePointer, safeWritePointer, currentWritePointer, dsBufferSize ) - || dsPointerBetween( endWrite, safeWritePointer, currentWritePointer, dsBufferSize ) ) { + || dsPointerBetween( endWrite, safeWritePointer, currentWritePointer, dsBufferSize ) ) { // We've strayed into the forbidden zone ... resync the read pointer. handle->xrun[0] = true; nextWritePointer = safeWritePointer + handle->dsPointerLeadTime[0] - bufferBytes; @@ -6541,14 +6541,14 @@ void RtApiDs :: callbackEvent() if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset DWORD endRead = nextReadPointer + bufferBytes; - // Handling depends on whether we are INPUT or DUPLEX. + // Handling depends on whether we are INPUT or DUPLEX. // If we're in INPUT mode then waiting is a good thing. If we're in DUPLEX mode, // then a wait here will drag the write pointers into the forbidden zone. - // - // In DUPLEX mode, rather than wait, we will back off the read pointer until - // it's in a safe position. This causes dropouts, but it seems to be the only - // practical way to sync up the read and write pointers reliably, given the - // the very complex relationship between phase and increment of the read and write + // + // In DUPLEX mode, rather than wait, we will back off the read pointer until + // it's in a safe position. This causes dropouts, but it seems to be the only + // practical way to sync up the read and write pointers reliably, given the + // the very complex relationship between phase and increment of the read and write // pointers. // // In order to minimize audible dropouts in DUPLEX mode, we will @@ -6599,7 +6599,7 @@ void RtApiDs :: callbackEvent() error( RtAudioError::SYSTEM_ERROR ); return; } - + if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset } } @@ -7809,7 +7809,7 @@ void RtApiAlsa :: stopStream() AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle; snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles; if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - if ( apiInfo->synchronized ) + if ( apiInfo->synchronized ) result = snd_pcm_drop( handle[0] ); else result = snd_pcm_drain( handle[0] ); @@ -8073,7 +8073,7 @@ static void *alsaCallbackHandler( void *ptr ) bool *isRunning = &info->isRunning; #ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread) - if ( &info->doRealtime ) { + if ( info->doRealtime ) { pthread_t tID = pthread_self(); // ID of this thread sched_param prio = { info->priority }; // scheduling priority of thread pthread_setschedparam( tID, SCHED_RR, &prio ); @@ -8277,7 +8277,7 @@ void RtApiPulse::callbackEvent( void ) else bytes = stream_.nUserChannels[INPUT] * stream_.bufferSize * formatBytes( stream_.userFormat ); - + if ( pa_simple_read( pah->s_rec, pulse_in, bytes, &pa_error ) < 0 ) { errorStream_ << "RtApiPulse::callbackEvent: audio read error, " << pa_strerror( pa_error ) << "."; @@ -8525,7 +8525,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode, } break; case OUTPUT: - pah->s_play = pa_simple_new( NULL, "RtAudio", PA_STREAM_PLAYBACK, NULL, "Playback", &ss, NULL, NULL, &error ); + pah->s_play = pa_simple_new( NULL, streamName.c_str(), PA_STREAM_PLAYBACK, NULL, "Playback", &ss, NULL, NULL, &error ); if ( !pah->s_play ) { errorText_ = "RtApiPulse::probeDeviceOpen: error connecting output to PulseAudio server."; goto error; @@ -8553,7 +8553,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode, stream_.state = STREAM_STOPPED; return true; - + error: if ( pah && stream_.callbackInfo.isRunning ) { pthread_cond_destroy( &pah->runnable_cv ); @@ -10145,8 +10145,8 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format ) { - register char val; - register char *ptr; + char val; + char *ptr; ptr = buffer; if ( format == RTAUDIO_SINT16 ) { @@ -10229,4 +10229,4 @@ void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat // // vim: et sts=2 sw=2 -#endif +#endif // RTAUDIO_ENABLED -GODOT- diff --git a/drivers/rtaudio/RtAudio.h b/drivers/rtaudio/RtAudio.h index 7d45d36529..4392e95f32 100644 --- a/drivers/rtaudio/RtAudio.h +++ b/drivers/rtaudio/RtAudio.h @@ -1,26 +1,20 @@ +// -GODOT- Start + #ifdef RTAUDIO_ENABLED #if defined(OSX_ENABLED) - -#define __MACOSX_CORE__ - + #define __MACOSX_CORE__ #elif defined(UNIX_ENABLED) - -#define __LINUX_ALSA__ - + #define __LINUX_ALSA__ #elif defined(WINDOWS_ENABLED) - -#if defined(WINRT_ENABLED) - -#define __RTAUDIO_DUMMY__ - -#else - -#define __WINDOWS_DS__ - + #if defined(WINRT_ENABLED) + #define __RTAUDIO_DUMMY__ + #else + #define __WINDOWS_DS__ + #endif #endif -#endif +// -GODOT- End /************************************************************************/ /*! \class RtAudio @@ -34,7 +28,7 @@ RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/ RtAudio: realtime audio i/o C++ classes - Copyright (c) 2001-2014 Gary P. Scavone + Copyright (c) 2001-2016 Gary P. Scavone Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -69,7 +63,7 @@ #ifndef __RTAUDIO_H #define __RTAUDIO_H -#define RTAUDIO_VERSION "4.1.1" +#define RTAUDIO_VERSION "4.1.2" #include <string> #include <vector> @@ -135,7 +129,7 @@ static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/mi open the input and/or output stream device(s) for exclusive use. Note that this is not possible with all supported audio APIs. - If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt + If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt to select realtime scheduling (round-robin) for the callback thread. If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to @@ -239,7 +233,7 @@ class RtAudioError : public std::exception //! The constructor. RtAudioError( const std::string& message, Type type = RtAudioError::UNSPECIFIED ) throw() : message_(message), type_(type) {} - + //! The destructor. virtual ~RtAudioError( void ) throw() {} @@ -365,7 +359,7 @@ class RtAudio open the input and/or output stream device(s) for exclusive use. Note that this is not possible with all supported audio APIs. - If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt + If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt to select realtime scheduling (round-robin) for the callback thread. The \c priority parameter will only be used if the RTAUDIO_SCHEDULE_REALTIME flag is set. It defines the thread's realtime priority. @@ -434,7 +428,7 @@ class RtAudio /*! This function performs a system query of available devices each time it is called, thus supporting devices connected \e after instantiation. If - a system error occurs during processing, a warning will be issued. + a system error occurs during processing, a warning will be issued. */ unsigned int getDeviceCount( void ) throw(); @@ -501,7 +495,7 @@ class RtAudio from within the callback function. \param options An optional pointer to a structure containing various global stream options, including a list of OR'ed RtAudioStreamFlags - and a suggested number of stream buffers that can be used to + and a suggested number of stream buffers that can be used to control stream latency. More buffers typically result in more robust performance, though at a cost of greater latency. If a value of zero is specified, a system-specific median value is @@ -806,7 +800,7 @@ protected: "warning" message is reported and FAILURE is returned. A successful probe is indicated by a return value of SUCCESS. */ - virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -898,7 +892,7 @@ public: private: - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -932,7 +926,7 @@ public: private: - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -968,7 +962,7 @@ public: std::vector<RtAudio::DeviceInfo> devices_; void saveDeviceInfo( void ); bool coInitialized_; - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -1007,7 +1001,7 @@ public: bool buffersRolling; long duplexPrerollBytes; std::vector<struct DsDevice> dsDevices; - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -1078,7 +1072,7 @@ public: std::vector<RtAudio::DeviceInfo> devices_; void saveDeviceInfo( void ); - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -1142,7 +1136,7 @@ public: private: - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -1167,7 +1161,7 @@ public: private: - bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/, + bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/, unsigned int /*firstChannel*/, unsigned int /*sampleRate*/, RtAudioFormat /*format*/, unsigned int * /*bufferSize*/, RtAudio::StreamOptions * /*options*/ ) { return false; } @@ -1186,4 +1180,4 @@ public: // // vim: et sts=2 sw=2 -#endif +#endif // RTAUDIO_ENABLED -GODOT- diff --git a/drivers/rtaudio/RtError.h b/drivers/rtaudio/RtError.h deleted file mode 100644 index ac5c41498a..0000000000 --- a/drivers/rtaudio/RtError.h +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************/ -/*! \class RtError - \brief Exception handling class for RtAudio & RtMidi. - - The RtError class is quite simple but it does allow errors to be - "caught" by RtError::Type. See the RtAudio and RtMidi - documentation to know which methods can throw an RtError. - -*/ -/************************************************************************/ - -#ifndef RTERROR_H -#define RTERROR_H - -#include <exception> -#include <iostream> -#include <string> - -class RtError : public std::exception -{ - public: - //! Defined RtError types. - enum Type { - WARNING, /*!< A non-critical error. */ - DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */ - UNSPECIFIED, /*!< The default, unspecified error type. */ - NO_DEVICES_FOUND, /*!< No devices found on system. */ - INVALID_DEVICE, /*!< An invalid device ID was specified. */ - MEMORY_ERROR, /*!< An error occured during memory allocation. */ - INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */ - INVALID_USE, /*!< The function was called incorrectly. */ - DRIVER_ERROR, /*!< A system driver error occured. */ - SYSTEM_ERROR, /*!< A system error occured. */ - THREAD_ERROR /*!< A thread error occured. */ - }; - - //! The constructor. - RtError( const std::string& message, Type type = RtError::UNSPECIFIED ) throw() : message_(message), type_(type) {} - - //! The destructor. - virtual ~RtError( void ) throw() {} - - //! Prints thrown error message to stderr. - virtual void printMessage( void ) throw() { std::cerr << '\n' << message_ << "\n\n"; } - - //! Returns the thrown error message type. - virtual const Type& getType(void) throw() { return type_; } - - //! Returns the thrown error message string. - virtual const std::string& getMessage(void) throw() { return message_; } - - //! Returns the thrown error message as a c-style string. - virtual const char* what( void ) const throw() { return message_.c_str(); } - - protected: - std::string message_; - Type type_; -}; - -#endif diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 6a7cd5eb8c..e829fa86b4 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -226,6 +226,8 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_ Node *expr=NULL; + int op_line = tokenizer->get_token_line(); // when operators are created at the bottom, the line might have been changed (\n found) + while(true) { @@ -1051,6 +1053,7 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_ OperatorNode *op = alloc_node<OperatorNode>(); op->op=expression[i].op; op->arguments.push_back(expression[i+1].node); + op->line=op_line; //line might have been changed from a \n expression[i].is_op=false; expression[i].node=op; expression.remove(i+1); @@ -1066,6 +1069,7 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_ OperatorNode *op = alloc_node<OperatorNode>(); op->op=expression[next_op].op; + op->line=op_line; //line might have been changed from a \n if (expression[next_op-1].is_op) { @@ -1268,6 +1272,8 @@ GDParser::Node* GDParser::_reduce_expression(Node *p_node,bool p_to_const) { } break; } + error_line=op->line; + return p_node; } @@ -1303,6 +1309,7 @@ GDParser::Node* GDParser::_reduce_expression(Node *p_node,bool p_to_const) { Variant v = ca->value.get(cb->value,&valid); if (!valid) { _set_error("invalid index in constant expression"); + error_line=op->line; return op; } @@ -1340,6 +1347,7 @@ GDParser::Node* GDParser::_reduce_expression(Node *p_node,bool p_to_const) { Variant v = ca->value.get_named(ib->name,&valid); if (!valid) { _set_error("invalid index '"+String(ib->name)+"' in constant expression"); + error_line=op->line; return op; } @@ -1369,6 +1377,7 @@ GDParser::Node* GDParser::_reduce_expression(Node *p_node,bool p_to_const) { if (op->arguments[0]->type==Node::TYPE_CONSTANT) { _set_error("Can't assign to constant",tokenizer->get_token_line()-1); + error_line=op->line; return op; } @@ -1384,6 +1393,7 @@ GDParser::Node* GDParser::_reduce_expression(Node *p_node,bool p_to_const) { Variant::evaluate(m_vop,static_cast<ConstantNode*>(op->arguments[0])->value,Variant(),res,valid);\ if (!valid) {\ _set_error("Invalid operand for unary operator");\ + error_line=op->line;\ return p_node;\ }\ ConstantNode *cn = alloc_node<ConstantNode>();\ @@ -1396,6 +1406,7 @@ GDParser::Node* GDParser::_reduce_expression(Node *p_node,bool p_to_const) { Variant::evaluate(m_vop,static_cast<ConstantNode*>(op->arguments[0])->value,static_cast<ConstantNode*>(op->arguments[1])->value,res,valid);\ if (!valid) {\ _set_error("Invalid operands for operator");\ + error_line=op->line;\ return p_node;\ }\ ConstantNode *cn = alloc_node<ConstantNode>();\ diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java index fde752acc9..b7de31ada3 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java +++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java @@ -28,99 +28,94 @@ /*************************************************************************/ package org.godotengine.godot; -import org.godotengine.godot.Dictionary; import android.app.Activity; import android.util.Log; +import org.godotengine.godot.payments.PaymentsManager; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class GodotPaymentV3 extends Godot.SingletonBase { private Godot activity; - private Integer purchaseCallbackId = 0; - private String accessToken; - private String purchaseValidationUrlPrefix; - private String transactionId; + private PaymentsManager mPaymentManager; + private Dictionary mSkuDetails = new Dictionary(); - public void purchase( String _sku, String _transactionId) { - final String sku = _sku; - final String transactionId = _transactionId; - activity.getPaymentsManager().setBaseSingleton(this); + public void purchase(final String sku, final String transactionId) { activity.runOnUiThread(new Runnable() { @Override public void run() { - activity.getPaymentsManager().requestPurchase(sku, transactionId); + mPaymentManager.requestPurchase(sku, transactionId); } }); } - -/* public string requestPurchasedTicket(){ - activity.getPaymentsManager() - } -*/ - static public Godot.SingletonBase initialize(Activity p_activity) { + static public Godot.SingletonBase initialize(Activity p_activity) { - return new GodotPaymentV3(p_activity); - } + return new GodotPaymentV3(p_activity); + } - public GodotPaymentV3(Activity p_activity) { - registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume"}); - activity=(Godot) p_activity; + registerClass("GodotPayments", new String[]{"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume", "querySkuDetails"}); + activity = (Godot) p_activity; + mPaymentManager = activity.getPaymentsManager(); + mPaymentManager.setBaseSingleton(this); } - public void consumeUnconsumedPurchases(){ - activity.getPaymentsManager().setBaseSingleton(this); + public void consumeUnconsumedPurchases() { activity.runOnUiThread(new Runnable() { @Override public void run() { - activity.getPaymentsManager().consumeUnconsumedPurchases(); + mPaymentManager.consumeUnconsumedPurchases(); } }); } private String signature; - public String getSignature(){ - return this.signature; + + public String getSignature() { + return this.signature; } - - - public void callbackSuccess(String ticket, String signature, String sku){ -// Log.d(this.getClass().getName(), "PRE-Send callback to purchase success"); + + public void callbackSuccess(String ticket, String signature, String sku) { GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku}); -// Log.d(this.getClass().getName(), "POST-Send callback to purchase success"); -} + } + + public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku) { + Log.d(this.getClass().getName(), "callbackSuccessProductMassConsumed > " + ticket + "," + signature + "," + sku); + GodotLib.calldeferred(purchaseCallbackId, "consume_success", new Object[]{ticket, signature, sku}); + } - public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku){ -// Log.d(this.getClass().getName(), "PRE-Send callback to consume success"); - Log.d(this.getClass().getName(), "callbackSuccessProductMassConsumed > "+ticket+","+signature+","+sku); - GodotLib.calldeferred(purchaseCallbackId, "consume_success", new Object[]{ticket, signature, sku}); -// Log.d(this.getClass().getName(), "POST-Send callback to consume success"); + public void callbackSuccessNoUnconsumedPurchases() { + GodotLib.calldeferred(purchaseCallbackId, "consume_not_required", new Object[]{}); } - public void callbackSuccessNoUnconsumedPurchases(){ - GodotLib.calldeferred(purchaseCallbackId, "no_validation_required", new Object[]{}); + public void callbackFailConsume() { + GodotLib.calldeferred(purchaseCallbackId, "consume_fail", new Object[]{}); } - - public void callbackFail(){ + + public void callbackFail() { GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[]{}); -// GodotLib.callobject(purchaseCallbackId, "purchase_fail", new Object[]{}); } - - public void callbackCancel(){ + + public void callbackCancel() { GodotLib.calldeferred(purchaseCallbackId, "purchase_cancel", new Object[]{}); -// GodotLib.callobject(purchaseCallbackId, "purchase_cancel", new Object[]{}); } - - public void callbackAlreadyOwned(String sku){ + + public void callbackAlreadyOwned(String sku) { GodotLib.calldeferred(purchaseCallbackId, "purchase_owned", new Object[]{sku}); } - + public int getPurchaseCallbackId() { return purchaseCallbackId; } @@ -129,11 +124,11 @@ public class GodotPaymentV3 extends Godot.SingletonBase { this.purchaseCallbackId = purchaseCallbackId; } - public String getPurchaseValidationUrlPrefix(){ - return this.purchaseValidationUrlPrefix ; + public String getPurchaseValidationUrlPrefix() { + return this.purchaseValidationUrlPrefix; } - public void setPurchaseValidationUrlPrefix(String url){ + public void setPurchaseValidationUrlPrefix(String url) { this.purchaseValidationUrlPrefix = url; } @@ -144,39 +139,80 @@ public class GodotPaymentV3 extends Godot.SingletonBase { public void setAccessToken(String accessToken) { this.accessToken = accessToken; } - - public void setTransactionId(String transactionId){ + + public void setTransactionId(String transactionId) { this.transactionId = transactionId; } - - public String getTransactionId(){ + + public String getTransactionId() { return this.transactionId; } - + // request purchased items are not consumed - public void requestPurchased(){ - activity.getPaymentsManager().setBaseSingleton(this); + public void requestPurchased() { activity.runOnUiThread(new Runnable() { @Override public void run() { - activity.getPaymentsManager().requestPurchased(); + mPaymentManager.requestPurchased(); } }); } - + // callback for requestPurchased() - public void callbackPurchased(String receipt, String signature, String sku){ + public void callbackPurchased(String receipt, String signature, String sku) { GodotLib.calldeferred(purchaseCallbackId, "has_purchased", new Object[]{receipt, signature, sku}); } - + // consume item automatically after purchase. default is true. - public void setAutoConsume(boolean autoConsume){ - activity.getPaymentsManager().setAutoConsume(autoConsume); + public void setAutoConsume(boolean autoConsume) { + mPaymentManager.setAutoConsume(autoConsume); } - + // consume a specific item - public void consume(String sku){ - activity.getPaymentsManager().consume(sku); + public void consume(String sku) { + mPaymentManager.consume(sku); + } + + // query in app item detail info + public void querySkuDetails(String[] list) { + List<String> nKeys = Arrays.asList(list); + List<String> cKeys = Arrays.asList(mSkuDetails.get_keys()); + ArrayList<String> fKeys = new ArrayList<String>(); + for (String key : nKeys) { + if (!cKeys.contains(key)) { + fKeys.add(key); + } + } + if (fKeys.size() > 0) { + mPaymentManager.querySkuDetails(fKeys.toArray(new String[0])); + } else { + completeSkuDetail(); + } + } + + public void addSkuDetail(String itemJson) { + JSONObject o = null; + try { + o = new JSONObject(itemJson); + Dictionary item = new Dictionary(); + item.put("type", o.optString("type")); + item.put("product_id", o.optString("productId")); + item.put("title", o.optString("title")); + item.put("description", o.optString("description")); + item.put("price", o.optString("price")); + item.put("price_currency_code", o.optString("price_currency_code")); + item.put("price_amount", 0.000001d * o.optLong("price_amount_micros")); + mSkuDetails.put(item.get("product_id").toString(), item); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public void completeSkuDetail() { + GodotLib.calldeferred(purchaseCallbackId, "sku_details_complete", new Object[]{mSkuDetails}); + } + + public void errorSkuDetail(String errorMessage) { + GodotLib.calldeferred(purchaseCallbackId, "sku_details_error", new Object[]{errorMessage}); } } - diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java index eb33b37ecc..753c0a6f93 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java @@ -28,283 +28,370 @@ /*************************************************************************/ package org.godotengine.godot.payments; -import java.util.ArrayList; -import java.util.List; - -import android.os.RemoteException; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.os.Bundle; import android.os.IBinder; +import android.os.RemoteException; +import android.text.TextUtils; import android.util.Log; -import android.os.Bundle; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONStringer; +import com.android.vending.billing.IInAppBillingService; -import org.godotengine.godot.Dictionary; import org.godotengine.godot.Godot; import org.godotengine.godot.GodotPaymentV3; -import com.android.vending.billing.IInAppBillingService; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Arrays; public class PaymentsManager { public static final int BILLING_RESPONSE_RESULT_OK = 0; public static final int REQUEST_CODE_FOR_PURCHASE = 0x1001; private static boolean auto_consume = true; - + private Activity activity; IInAppBillingService mService; - public void setActivity(Activity activity){ + public void setActivity(Activity activity) { this.activity = activity; } - public static PaymentsManager createManager(Activity activity){ + public static PaymentsManager createManager(Activity activity) { PaymentsManager manager = new PaymentsManager(activity); return manager; } - - private PaymentsManager(Activity activity){ + + private PaymentsManager(Activity activity) { this.activity = activity; } - - public PaymentsManager initService(){ + + public PaymentsManager initService() { Intent intent = new Intent("com.android.vending.billing.InAppBillingService.BIND"); intent.setPackage("com.android.vending"); activity.bindService( - intent, - mServiceConn, + intent, + mServiceConn, Context.BIND_AUTO_CREATE); return this; } - public void destroy(){ + public void destroy() { if (mService != null) { - activity.unbindService(mServiceConn); - } + activity.unbindService(mServiceConn); + } } - + ServiceConnection mServiceConn = new ServiceConnection() { - @Override - public void onServiceDisconnected(ComponentName name) { - mService = null; - } + @Override + public void onServiceDisconnected(ComponentName name) { + mService = null; + } - @Override - public void onServiceConnected(ComponentName name, IBinder service) { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { mService = IInAppBillingService.Stub.asInterface(service); - } + } }; - - public void requestPurchase(final String sku, String transactionId){ + + public void requestPurchase(final String sku, String transactionId) { new PurchaseTask(mService, Godot.getInstance()) { - + @Override protected void error(String message) { godotPaymentV3.callbackFail(); - + } - + @Override protected void canceled() { godotPaymentV3.callbackCancel(); } - + @Override protected void alreadyOwned() { godotPaymentV3.callbackAlreadyOwned(sku); } - + }.purchase(sku, transactionId); } - public void consumeUnconsumedPurchases(){ + public void consumeUnconsumedPurchases() { new ReleaseAllConsumablesTask(mService, activity) { - + @Override protected void success(String sku, String receipt, String signature, String token) { godotPaymentV3.callbackSuccessProductMassConsumed(receipt, signature, sku); } - + @Override protected void error(String message) { - godotPaymentV3.callbackFail(); - + Log.d("godot", "consumeUnconsumedPurchases :" + message); + godotPaymentV3.callbackFailConsume(); + } @Override protected void notRequired() { + Log.d("godot", "callbackSuccessNoUnconsumedPurchases :"); godotPaymentV3.callbackSuccessNoUnconsumedPurchases(); - + } }.consumeItAll(); } - - public void requestPurchased(){ - try{ + + public void requestPurchased() { + try { PaymentsCache pc = new PaymentsCache(Godot.getInstance()); -// Log.d("godot", "requestPurchased for " + activity.getPackageName()); - Bundle bundle = mService.getPurchases(3, activity.getPackageName(), "inapp",null); + String continueToken = null; -/* - for (String key : bundle.keySet()) { - Object value = bundle.get(key); - Log.d("godot", String.format("%s %s (%s)", key, value.toString(), value.getClass().getName())); - } -*/ - - if (bundle.getInt("RESPONSE_CODE") == 0){ + do { + Bundle bundle = mService.getPurchases(3, activity.getPackageName(), "inapp", continueToken); - final ArrayList<String> myPurchases = bundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST"); - final ArrayList<String> mySignatures = bundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST"); - + if (bundle.getInt("RESPONSE_CODE") == 0) { - if (myPurchases == null || myPurchases.size() == 0){ -// Log.d("godot", "No purchases!"); - godotPaymentV3.callbackPurchased("", "", ""); - return; - } - -// Log.d("godot", "# products are purchased:" + myPurchases.size()); - for (int i=0;i<myPurchases.size();i++) - { - - try{ - String receipt = myPurchases.get(i); - JSONObject inappPurchaseData = new JSONObject(receipt); - String sku = inappPurchaseData.getString("productId"); - String token = inappPurchaseData.getString("purchaseToken"); - String signature = mySignatures.get(i); -// Log.d("godot", "purchased item:" + token + "\n" + receipt); - - pc.setConsumableValue("ticket_signautre", sku, signature); - pc.setConsumableValue("ticket", sku, receipt); - pc.setConsumableFlag("block", sku, true); - pc.setConsumableValue("token", sku, token); - - godotPaymentV3.callbackPurchased(receipt, signature, sku); - } catch (JSONException e) { + final ArrayList<String> myPurchases = bundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST"); + final ArrayList<String> mySignatures = bundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST"); + + if (myPurchases == null || myPurchases.size() == 0) { + godotPaymentV3.callbackPurchased("", "", ""); + return; } - } - } - }catch(Exception e){ + for (int i = 0; i < myPurchases.size(); i++) { + + try { + String receipt = myPurchases.get(i); + JSONObject inappPurchaseData = new JSONObject(receipt); + String sku = inappPurchaseData.getString("productId"); + String token = inappPurchaseData.getString("purchaseToken"); + String signature = mySignatures.get(i); + + pc.setConsumableValue("ticket_signautre", sku, signature); + pc.setConsumableValue("ticket", sku, receipt); + pc.setConsumableFlag("block", sku, true); + pc.setConsumableValue("token", sku, token); + + godotPaymentV3.callbackPurchased(receipt, signature, sku); + } catch (JSONException e) { + } + } + } + continueToken = bundle.getString("INAPP_CONTINUATION_TOKEN"); + Log.d("godot", "continue token = " + continueToken); + } while (!TextUtils.isEmpty(continueToken)); + } catch (Exception e) { Log.d("godot", "Error requesting purchased products:" + e.getClass().getName() + ":" + e.getMessage()); } } - + public void processPurchaseResponse(int resultCode, Intent data) { - new HandlePurchaseTask(activity){ + new HandlePurchaseTask(activity) { @Override protected void success(final String sku, final String signature, final String ticket) { godotPaymentV3.callbackSuccess(ticket, signature, sku); - if (auto_consume){ + if (auto_consume) { new ConsumeTask(mService, activity) { - + @Override protected void success(String ticket) { -// godotPaymentV3.callbackSuccess(""); } - + @Override protected void error(String message) { godotPaymentV3.callbackFail(); - + } }.consume(sku); } - -// godotPaymentV3.callbackSuccess(new PaymentsCache(activity).getConsumableValue("ticket", sku),signature); -// godotPaymentV3.callbackSuccess(ticket); - //validatePurchase(purchaseToken, sku); } @Override protected void error(String message) { godotPaymentV3.callbackFail(); - } @Override protected void canceled() { godotPaymentV3.callbackCancel(); - } }.handlePurchaseRequest(resultCode, data); } - - public void validatePurchase(String purchaseToken, final String sku){ - - new ValidateTask(activity, godotPaymentV3){ + + public void validatePurchase(String purchaseToken, final String sku) { + + new ValidateTask(activity, godotPaymentV3) { @Override protected void success() { - + new ConsumeTask(mService, activity) { - + @Override protected void success(String ticket) { godotPaymentV3.callbackSuccess(ticket, null, sku); - } - + @Override protected void error(String message) { godotPaymentV3.callbackFail(); - } }.consume(sku); - + } @Override protected void error(String message) { godotPaymentV3.callbackFail(); - } @Override protected void canceled() { godotPaymentV3.callbackCancel(); - } }.validatePurchase(sku); } - - public void setAutoConsume(boolean autoConsume){ + + public void setAutoConsume(boolean autoConsume) { auto_consume = autoConsume; } - - public void consume(final String sku){ + + public void consume(final String sku) { new ConsumeTask(mService, activity) { - + @Override protected void success(String ticket) { godotPaymentV3.callbackSuccessProductMassConsumed(ticket, "", sku); - } - + @Override protected void error(String message) { - godotPaymentV3.callbackFail(); - + godotPaymentV3.callbackFailConsume(); } }.consume(sku); } - + + // Workaround to bug where sometimes response codes come as Long instead of Integer + int getResponseCodeFromBundle(Bundle b) { + Object o = b.get("RESPONSE_CODE"); + if (o == null) { + //logDebug("Bundle with null response code, assuming OK (known issue)"); + return BILLING_RESPONSE_RESULT_OK; + } else if (o instanceof Integer) return ((Integer) o).intValue(); + else if (o instanceof Long) return (int) ((Long) o).longValue(); + else { + //logError("Unexpected type for bundle response code."); + //logError(o.getClass().getName()); + throw new RuntimeException("Unexpected type for bundle response code: " + o.getClass().getName()); + } + } + + /** + * Returns a human-readable description for the given response code. + * + * @param code The response code + * @return A human-readable string explaining the result code. + * It also includes the result code numerically. + */ + public static String getResponseDesc(int code) { + String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" + + "3:Billing Unavailable/4:Item unavailable/" + + "5:Developer Error/6:Error/7:Item Already Owned/" + + "8:Item not owned").split("/"); + String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" + + "-1002:Bad response received/" + + "-1003:Purchase signature verification failed/" + + "-1004:Send intent failed/" + + "-1005:User cancelled/" + + "-1006:Unknown purchase response/" + + "-1007:Missing token/" + + "-1008:Unknown error/" + + "-1009:Subscriptions not available/" + + "-1010:Invalid consumption attempt").split("/"); + + if (code <= -1000) { + int index = -1000 - code; + if (index >= 0 && index < iabhelper_msgs.length) return iabhelper_msgs[index]; + else return String.valueOf(code) + ":Unknown IAB Helper Error"; + } else if (code < 0 || code >= iab_msgs.length) + return String.valueOf(code) + ":Unknown"; + else + return iab_msgs[code]; + } + + public void querySkuDetails(final String[] list) { + (new Thread(new Runnable() { + @Override + public void run() { + ArrayList<String> skuList = new ArrayList<String>(Arrays.asList(list)); + if (skuList.size() == 0) { + return; + } + // Split the sku list in blocks of no more than 20 elements. + ArrayList<ArrayList<String>> packs = new ArrayList<ArrayList<String>>(); + ArrayList<String> tempList; + int n = skuList.size() / 20; + int mod = skuList.size() % 20; + for (int i = 0; i < n; i++) { + tempList = new ArrayList<String>(); + for (String s : skuList.subList(i * 20, i * 20 + 20)) { + tempList.add(s); + } + packs.add(tempList); + } + if (mod != 0) { + tempList = new ArrayList<String>(); + for (String s : skuList.subList(n * 20, n * 20 + mod)) { + tempList.add(s); + } + packs.add(tempList); + + for (ArrayList<String> skuPartList : packs) { + Bundle querySkus = new Bundle(); + querySkus.putStringArrayList("ITEM_ID_LIST", skuPartList); + Bundle skuDetails = null; + try { + skuDetails = mService.getSkuDetails(3, activity.getPackageName(), "inapp", querySkus); + if (!skuDetails.containsKey("DETAILS_LIST")) { + int response = getResponseCodeFromBundle(skuDetails); + if (response != BILLING_RESPONSE_RESULT_OK) { + godotPaymentV3.errorSkuDetail(getResponseDesc(response)); + } else { + godotPaymentV3.errorSkuDetail("No error but no detail list."); + } + return; + } + + ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST"); + + for (String thisResponse : responseList) { + Log.d("godot", "response = "+thisResponse); + godotPaymentV3.addSkuDetail(thisResponse); + } + } catch (RemoteException e) { + e.printStackTrace(); + godotPaymentV3.errorSkuDetail("RemoteException error!"); + } + } + godotPaymentV3.completeSkuDetail(); + } + } + })).start(); + } + private GodotPaymentV3 godotPaymentV3; - + public void setBaseSingleton(GodotPaymentV3 godotPaymentV3) { this.godotPaymentV3 = godotPaymentV3; } } - diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 2be8b01dc3..356de7b2bc 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -62,7 +62,6 @@ def get_opts(): ('use_leak_sanitizer','Use llvm compiler sanitize memory leaks','no'), ('pulseaudio','Detect & Use pulseaudio','yes'), ('udev','Use udev for gamepad connection callbacks','no'), - ('new_wm_api', 'Use experimental window management API','no'), ('debug_release', 'Add debug symbols to release version','no'), ] @@ -204,10 +203,6 @@ def configure(env): env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) #env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } ) - if(env["new_wm_api"]=="yes"): - env.Append(CPPFLAGS=['-DNEW_WM_API']) - env.ParseConfig('pkg-config xinerama --cflags --libs') - if (env["use_static_cpp"]=="yes"): env.Append(LINKFLAGS=['-static-libstdc++']) diff --git a/platform/x11/joystick_linux.cpp b/platform/x11/joystick_linux.cpp index 4a6a4f3a52..3b854a8d46 100644 --- a/platform/x11/joystick_linux.cpp +++ b/platform/x11/joystick_linux.cpp @@ -259,7 +259,7 @@ void joystick_linux::close_joystick(int p_id) { attached_devices.remove(attached_devices.find(joy.devpath)); input->joy_connection_changed(p_id, false, ""); }; -}; +} static String _hex_str(uint8_t p_byte) { @@ -271,7 +271,7 @@ static String _hex_str(uint8_t p_byte) { ret[1] = dict[p_byte & 0xF]; return ret; -}; +} void joystick_linux::setup_joystick_properties(int p_id) { diff --git a/platform/x11/key_mapping_x11.cpp b/platform/x11/key_mapping_x11.cpp index 190d6925dd..6443d14897 100644 --- a/platform/x11/key_mapping_x11.cpp +++ b/platform/x11/key_mapping_x11.cpp @@ -197,6 +197,7 @@ unsigned int KeyMappingX11::get_keycode(KeySym p_keysym) { return 0; } + KeySym KeyMappingX11::get_keysym(unsigned int p_code) { // kinda bruteforce.. could optimize. diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index a9a8c73a74..490030398e 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -216,8 +216,6 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD)); } -#if 1 - // NEW_WM_API // borderless fullscreen window mode if (current_videomode.fullscreen) { // needed for lxde/openbox, possibly others @@ -267,22 +265,6 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XSetWMNormalHints(x11_display, x11_window, xsh); XFree(xsh); } -#else - capture_idle = 0; - minimized = false; - maximized = false; - - if (current_videomode.fullscreen) { - //set_wm_border(false); - set_wm_fullscreen(true); - } - if (!current_videomode.resizable) { - int screen = get_current_screen(); - Size2i screen_size = get_screen_size(screen); - set_window_size(screen_size); - set_window_resizable(false); - } -#endif AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton(); @@ -440,7 +422,6 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XFreeGC(x11_display, gc); - if (cursor == None) { ERR_PRINT("FAILED CREATING CURSOR"); @@ -579,7 +560,7 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) { ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime) != - GrabSuccess) { + GrabSuccess) { ERR_PRINT("NO GRAB"); } @@ -643,22 +624,6 @@ OS::VideoMode OS_X11::get_video_mode(int p_screen) const { void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const { } -//#ifdef NEW_WM_API -#if 0 -// Just now not needed. Can be used for a possible OS.set_border(bool) method -void OS_X11::set_wm_border(bool p_enabled) { - // needed for lxde/openbox, possibly others - Hints hints; - Atom property; - hints.flags = 2; - hints.decorations = p_enabled ? 1L : 0L; - property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); - XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); - XMapRaised(x11_display, x11_window); - //XMoveResizeWindow(x11_display, x11_window, 0, 0, 800, 800); -} -#endif - void OS_X11::set_wm_fullscreen(bool p_enabled) { // Using EWMH -- Extened Window Manager Hints XEvent xev; @@ -811,54 +776,7 @@ Point2 OS_X11::get_window_position() const { } void OS_X11::set_window_position(const Point2& p_position) { - // Using EWMH -- Extended Window Manager Hints - // to get the size of the decoration -#if 0 - Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True); - Atom type; - int format; - unsigned long len; - unsigned long remaining; - unsigned char *data = NULL; - int result; - - result = XGetWindowProperty( - x11_display, - x11_window, - property, - 0, - 32, - False, - AnyPropertyType, - &type, - &format, - &len, - &remaining, - &data - ); - - long left = 0L; - long top = 0L; - - if( result == Success ) { - long *extends = (long *) data; - - left = extends[0]; - top = extends[2]; - - XFree(data); - } - - int screen = get_current_screen(); - Point2i screen_position = get_screen_position(screen); - - left -= screen_position.x; - top -= screen_position.y; - - XMoveWindow(x11_display,x11_window,p_position.x - left,p_position.y - top); -#else XMoveWindow(x11_display,x11_window,p_position.x,p_position.y); -#endif } Size2 OS_X11::get_window_size() const { @@ -902,20 +820,19 @@ bool OS_X11::is_window_resizable() const { } void OS_X11::set_window_minimized(bool p_enabled) { - // Using ICCCM -- Inter-Client Communication Conventions Manual - XEvent xev; - Atom wm_change = XInternAtom(x11_display, "WM_CHANGE_STATE", False); + // Using ICCCM -- Inter-Client Communication Conventions Manual + XEvent xev; + Atom wm_change = XInternAtom(x11_display, "WM_CHANGE_STATE", False); - memset(&xev, 0, sizeof(xev)); - xev.type = ClientMessage; - xev.xclient.window = x11_window; - xev.xclient.message_type = wm_change; - xev.xclient.format = 32; - xev.xclient.data.l[0] = p_enabled ? WM_IconicState : WM_NormalState; + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_change; + xev.xclient.format = 32; + xev.xclient.data.l[0] = p_enabled ? WM_IconicState : WM_NormalState; - XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); - //XEvent xev; Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); Atom wm_hidden = XInternAtom(x11_display, "_NET_WM_STATE_HIDDEN", False); @@ -979,47 +896,33 @@ void OS_X11::set_window_maximized(bool p_enabled) { xev.xclient.data.l[2] = wm_max_vert; XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); -/* sorry this does not fix it, fails on multi monitor - XWindowAttributes xwa; - XGetWindowAttributes(x11_display,DefaultRootWindow(x11_display),&xwa); - current_videomode.width = xwa.width; - current_videomode.height = xwa.height; -//*/ - -// current_videomode.width = wm_max_horz; -// current_videomode.height = wm_max_vert; - - //Size2 ss = get_screen_size(get_current_screen()); - //current_videomode.width=ss.width; - //current_videomode.height=ss.height; - maximized = p_enabled; } bool OS_X11::is_window_maximized() const { // Using EWMH -- Extended Window Manager Hints - Atom property = XInternAtom(x11_display,"_NET_WM_STATE",False ); - Atom type; - int format; - unsigned long len; - unsigned long remaining; - unsigned char *data = NULL; + Atom property = XInternAtom(x11_display,"_NET_WM_STATE",False ); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; - int result = XGetWindowProperty( - x11_display, - x11_window, - property, - 0, - 1024, - False, - XA_ATOM, - &type, - &format, - &len, - &remaining, - &data - ); + int result = XGetWindowProperty( + x11_display, + x11_window, + property, + 0, + 1024, + False, + XA_ATOM, + &type, + &format, + &len, + &remaining, + &data + ); if(result == Success) { Atom *atoms = (Atom*) data; @@ -1383,11 +1286,6 @@ void OS_X11::process_xevents() { } break; case FocusIn: minimized = false; -#ifdef NEW_WM_API - if(current_videomode.fullscreen) { - set_wm_fullscreen(true); - } -#endif main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); if (mouse_mode==MOUSE_MODE_CAPTURED) { XGrabPointer(x11_display, x11_window, True, @@ -1398,12 +1296,6 @@ void OS_X11::process_xevents() { break; case FocusOut: -#ifdef NEW_WM_API - if(current_videomode.fullscreen) { - set_wm_fullscreen(false); - set_window_minimized(true); - } -#endif main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); if (mouse_mode==MOUSE_MODE_CAPTURED) { //dear X11, I try, I really try, but you never work, you do whathever you want. @@ -1547,13 +1439,6 @@ void OS_X11::process_xevents() { Point2i rel = pos - last_mouse_pos; -#ifdef NEW_WM_API - if (mouse_mode==MOUSE_MODE_CAPTURED) { - pos.x = current_videomode.width / 2; - pos.y = current_videomode.height / 2; - } -#endif - InputEvent motion_event; motion_event.ID=++event_id; motion_event.type=InputEvent::MOUSE_MOTION; @@ -1836,7 +1721,7 @@ static String _get_clipboard(Atom p_source, Window x11_window, ::Display* x11_di return ret; -}; +} String OS_X11::get_clipboard() const { @@ -1848,7 +1733,7 @@ String OS_X11::get_clipboard() const { }; return ret; -}; +} String OS_X11::get_name() { @@ -2095,4 +1980,4 @@ OS_X11::OS_X11() { minimized = false; xim_style=0L; mouse_mode=MOUSE_MODE_VISIBLE; -}; +} diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index e9378b1d02..05136de5d6 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -123,26 +123,15 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2& p_offset,float p_sca Point2 new_ofs = ((orig_offset+p_offset)*motion_scale)*p_scale+motion_offset; if (mirroring.x) { - - while( new_ofs.x>=0) { - new_ofs.x -= mirroring.x*p_scale; - } - while(new_ofs.x < -mirroring.x*p_scale) { - new_ofs.x += mirroring.x*p_scale; - } + double den = mirroring.x*p_scale; + new_ofs.x -= den*ceil(new_ofs.x/den); } if (mirroring.y) { - - while( new_ofs.y>=0) { - new_ofs.y -= mirroring.y*p_scale; - } - while(new_ofs.y < -mirroring.y*p_scale) { - new_ofs.y += mirroring.y*p_scale; - } + double den = mirroring.y*p_scale; + new_ofs.y -= den*ceil(new_ofs.y/den); } - set_pos(new_ofs); set_scale(Vector2(1,1)*p_scale); diff --git a/scene/3d/immediate_geometry.cpp b/scene/3d/immediate_geometry.cpp index 4964582be4..e83fa69b4f 100644 --- a/scene/3d/immediate_geometry.cpp +++ b/scene/3d/immediate_geometry.cpp @@ -149,7 +149,7 @@ void ImmediateGeometry::add_sphere(int p_lats,int p_lons,float p_radius) { void ImmediateGeometry::_bind_methods() { - ObjectTypeDB::bind_method(_MD("begin","primitive","texture:Texture"),&ImmediateGeometry::begin); + ObjectTypeDB::bind_method(_MD("begin","primitive","texture:Texture"),&ImmediateGeometry::begin,DEFVAL(Ref<Texture>())); ObjectTypeDB::bind_method(_MD("set_normal","normal"),&ImmediateGeometry::set_normal); ObjectTypeDB::bind_method(_MD("set_tangent","tangent"),&ImmediateGeometry::set_tangent); ObjectTypeDB::bind_method(_MD("set_color","color"),&ImmediateGeometry::set_color); diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h index 28b5735ca8..c1cc4f87d5 100644 --- a/scene/3d/immediate_geometry.h +++ b/scene/3d/immediate_geometry.h @@ -38,6 +38,8 @@ class ImmediateGeometry : public GeometryInstance { RID im; + //a list of texures drawn need to be kept, to avoid references + // in VisualServer from becoming invalid if the texture is no longer used List<Ref<Texture> > cached_textures; bool empty; AABB aabb; @@ -47,7 +49,7 @@ protected: public: - void begin(Mesh::PrimitiveType p_primitive,const Ref<Texture>& p_texture); + void begin(Mesh::PrimitiveType p_primitive,const Ref<Texture>& p_texture=Ref<Texture>()); void set_normal(const Vector3& p_normal); void set_tangent(const Plane& p_tangent); void set_color(const Color& p_color); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index c8bd9749df..b69646432e 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -415,11 +415,12 @@ void ColorPicker::_screen_pick_pressed() if (!screen) { screen=memnew( Control ); r->add_child(screen); + screen->set_as_toplevel(true); screen->set_area_as_parent_rect(); screen->connect("input_event",this,"_screen_input"); } screen->raise(); - screen->show(); + screen->show_modal(); r->queue_screen_capture(); } diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index d335399caa..6b43425edc 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -475,7 +475,7 @@ void FileDialog::update_filters() { String flt=filters[i].get_slice(";",0).strip_edges(); String desc=filters[i].get_slice(";",1).strip_edges(); if (desc.length()) - filter->add_item(desc+" ( "+flt+" )"); + filter->add_item(String(XL_MESSAGE(desc))+" ( "+flt+" )"); else filter->add_item("( "+flt+" )"); } @@ -498,6 +498,16 @@ void FileDialog::add_filter(const String& p_filter) { } +void FileDialog::set_filters(const Vector<String>& p_filters){ + filters=p_filters; + update_filters(); + invalidate(); +} + +Vector<String> FileDialog::get_filters() const{ + return filters; +} + String FileDialog::get_current_dir() const { return dir->get_text(); @@ -686,6 +696,8 @@ void FileDialog::_bind_methods() { ObjectTypeDB::bind_method(_MD("clear_filters"),&FileDialog::clear_filters); ObjectTypeDB::bind_method(_MD("add_filter","filter"),&FileDialog::add_filter); + ObjectTypeDB::bind_method(_MD("set_filters","filters"),&FileDialog::set_filters); + ObjectTypeDB::bind_method(_MD("get_filters"),&FileDialog::get_filters); ObjectTypeDB::bind_method(_MD("get_current_dir"),&FileDialog::get_current_dir); ObjectTypeDB::bind_method(_MD("get_current_file"),&FileDialog::get_current_file); ObjectTypeDB::bind_method(_MD("get_current_path"),&FileDialog::get_current_path); @@ -722,6 +734,11 @@ void FileDialog::_bind_methods() { BIND_CONSTANT( ACCESS_USERDATA ); BIND_CONSTANT( ACCESS_FILESYSTEM ); + ADD_PROPERTY( PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Open one,Open many,Open folder,Open any,Save"),_SCS("set_mode"),_SCS("get_mode") ); + ADD_PROPERTY( PropertyInfo(Variant::INT, "access", PROPERTY_HINT_ENUM, "Resources,User data,File system"),_SCS("set_access"),_SCS("get_access") ); + ADD_PROPERTY( PropertyInfo(Variant::STRING_ARRAY, "filters"),_SCS("set_filters"),_SCS("get_filters") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "show_hidden_files"),_SCS("set_show_hidden_files"),_SCS("is_showing_hidden_files") ); + } diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 1fcf8387ce..150b24cb3f 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -131,6 +131,8 @@ public: void clear_filters(); void add_filter(const String& p_filter); + void set_filters(const Vector<String>& p_filters); + Vector<String> get_filters() const; void set_enable_multiple_selection(bool p_enable); Vector<String> get_selected_files() const; diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 94001b2ac1..3705541865 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -559,7 +559,12 @@ Color GraphNode::get_connection_output_color(int p_idx) { void GraphNode::_input_event(const InputEvent& p_ev) { if (p_ev.type==InputEvent::MOUSE_BUTTON) { + + ERR_EXPLAIN("GraphNode must be the child of a GraphEdit node."); + ERR_FAIL_COND(get_parent_control() == NULL); + get_parent_control()->grab_focus(); + if(p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 7d112d1492..105d919338 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -336,6 +336,7 @@ void ItemList::clear(){ current=-1; ensure_selected_visible=false; update(); + shape_changed=true; defer_select_single=-1; } @@ -461,7 +462,6 @@ void ItemList::_input_event(const InputEvent& p_event) { pos.y+=scroll_bar->get_val(); int closest = -1; - int closest_dist=0x7FFFFFFF; for(int i=0;i<items.size();i++) { @@ -474,12 +474,6 @@ void ItemList::_input_event(const InputEvent& p_event) { closest=i; break; } - - float dist = rc.distance_to(pos); - if (dist<closest_dist) { - closest=i; - closest_dist=dist; - } } if (closest!=-1) { @@ -546,6 +540,11 @@ void ItemList::_input_event(const InputEvent& p_event) { return; + } else { + Vector<int> sItems = get_selected_items(); + for(int i = 0; i < sItems.size(); i++) { + unselect(sItems[i]); + } } } if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_WHEEL_UP && p_event.mouse_button.pressed) { @@ -823,7 +822,7 @@ void ItemList::_notification(int p_what) { } if (shape_changed) { - + float max_column_width = 0; //1- compute item minimum sizes @@ -914,11 +913,11 @@ void ItemList::_notification(int p_what) { if (i<items.size()-1) separators.push_back(ofs.y+max_h+vseparation/2); - + for(int j=i;j>=0 && col>0;j--, col--) { items[j].rect_cache.size.y = max_h; } - + ofs.x=0; ofs.y+=max_h+vseparation; col=0; @@ -1211,8 +1210,11 @@ String ItemList::get_tooltip(const Point2& p_pos) const { } void ItemList::sort_items_by_text() { + items.sort(); update(); + shape_changed=true; + if (select_mode==SELECT_SINGLE) { for(int i=0;i<items.size();i++) { if (items[i].selected) { @@ -1304,7 +1306,7 @@ void ItemList::_bind_methods(){ ObjectTypeDB::bind_method(_MD("remove_item","idx"),&ItemList::remove_item); ObjectTypeDB::bind_method(_MD("clear"),&ItemList::clear); - ObjectTypeDB::bind_method(_MD("sort_items_by_text"),&ItemList::clear); + ObjectTypeDB::bind_method(_MD("sort_items_by_text"),&ItemList::sort_items_by_text); ObjectTypeDB::bind_method(_MD("set_fixed_column_width","width"),&ItemList::set_fixed_column_width); ObjectTypeDB::bind_method(_MD("get_fixed_column_width"),&ItemList::get_fixed_column_width); @@ -1383,4 +1385,3 @@ ItemList::ItemList() { ItemList::~ItemList() { } - diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 50b44c55a9..af04fbd201 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2993,6 +2993,34 @@ void TextEdit::adjust_viewport_to_cursor() { } +void TextEdit::center_viewport_to_cursor() { + + if (cursor.line_ofs>cursor.line) + cursor.line_ofs=cursor.line; + + int visible_width=cache.size.width-cache.style_normal->get_minimum_size().width-cache.line_number_w-cache.breakpoint_gutter_width; + if (v_scroll->is_visible()) + visible_width-=v_scroll->get_combined_minimum_size().width; + visible_width-=20; // give it a little more space + + int visible_rows = get_visible_rows(); + if (h_scroll->is_visible()) + visible_rows-=((h_scroll->get_combined_minimum_size().height-1)/get_row_height()); + + int max_ofs = text.size()-(scroll_past_end_of_file_enabled?1:visible_rows); + cursor.line_ofs=CLAMP(cursor.line-(visible_rows/2),0,max_ofs); + + int cursor_x = get_column_x_offset( cursor.column, text[cursor.line] ); + + if (cursor_x>(cursor.x_ofs+visible_width)) + cursor.x_ofs=cursor_x-visible_width+1; + + if (cursor_x < cursor.x_ofs) + cursor.x_ofs=cursor_x; + + update(); +} + void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) { if (p_col<0) diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 65e9615911..c3bdf7c856 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -396,6 +396,8 @@ public: } void set_auto_indent(bool p_auto_indent); + void center_viewport_to_cursor(); + void cursor_set_column(int p_col, bool p_adjust_viewport=true); void cursor_set_line(int p_row, bool p_adjust_viewport=true); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 8faee0c549..f182f2c96c 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2033,8 +2033,22 @@ void Viewport::_gui_input_event(InputEvent p_event) { } + bool is_tooltip_shown = false; - if (can_tooltip) { + if (gui.tooltip_popup) { + if (can_tooltip) { + String tooltip = over->get_tooltip(gui.tooltip->get_global_transform().xform_inv(mpos)); + + if (tooltip.length() == 0) + _gui_cancel_tooltip(); + else if (tooltip == gui.tooltip_label->get_text()) + is_tooltip_shown = true; + } + else + _gui_cancel_tooltip(); + } + + if (can_tooltip && !is_tooltip_shown) { gui.tooltip=over; gui.tooltip_pos=mpos;//(parent_xform * get_transform()).affine_inverse().xform(pos); diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 88ff09e961..29460790ff 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -644,7 +644,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset,bool p_cubic) const{ if (p_offset>=baked_max_ofs) return r[bpc-1]; - int idx = Math::floor(p_offset/bake_interval); + int idx = Math::floor((double)p_offset/(double)bake_interval); float frac = Math::fmod(p_offset,bake_interval); if (idx>=bpc-1) { @@ -1117,7 +1117,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset,bool p_cubic) const{ if (p_offset>=baked_max_ofs) return r[bpc-1]; - int idx = Math::floor(p_offset/bake_interval); + int idx = Math::floor((double)p_offset/(double)bake_interval); float frac = Math::fmod(p_offset,bake_interval); if (idx>=bpc-1) { @@ -1161,7 +1161,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const{ if (p_offset>=baked_max_ofs) return r[bpc-1]; - int idx = Math::floor(p_offset/bake_interval); + int idx = Math::floor((double)p_offset/(double)bake_interval); float frac = Math::fmod(p_offset,bake_interval); if (idx>=bpc-1) { diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index ae3f4c94a1..e1769d099b 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -860,6 +860,7 @@ void SurfaceTool::_bind_methods() { ObjectTypeDB::bind_method(_MD("deindex"),&SurfaceTool::deindex); ///ObjectTypeDB::bind_method(_MD("generate_flat_normals"),&SurfaceTool::generate_flat_normals); ObjectTypeDB::bind_method(_MD("generate_normals"),&SurfaceTool::generate_normals); + ObjectTypeDB::bind_method(_MD("add_index", "index"), &SurfaceTool::add_index); ObjectTypeDB::bind_method(_MD("commit:Mesh","existing:Mesh"),&SurfaceTool::commit,DEFVAL(Variant())); ObjectTypeDB::bind_method(_MD("clear"),&SurfaceTool::clear); diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp index 9eb6b4013f..aa0156b0c0 100644 --- a/tools/editor/animation_editor.cpp +++ b/tools/editor/animation_editor.cpp @@ -4075,12 +4075,22 @@ AnimationKeyEditor::AnimationKeyEditor() { track_editor->set_h_size_flags(SIZE_EXPAND_FILL); + track_pos = memnew( Control ); track_pos->set_area_as_parent_rect(); track_pos->set_ignore_mouse(true); track_editor->add_child(track_pos); track_pos->connect("draw",this,"_track_pos_draw"); + select_anim_warning = memnew( Label ); + track_editor->add_child(select_anim_warning); + select_anim_warning->set_area_as_parent_rect(); + select_anim_warning->set_text(TTR("Select an AnimationPlayer from the Scene Tree to edit animations.")); + select_anim_warning->set_autowrap(true); + select_anim_warning->set_align(Label::ALIGN_CENTER); + select_anim_warning->set_valign(Label::VALIGN_CENTER); + + v_scroll = memnew( VScrollBar ); hb->add_child(v_scroll); diff --git a/tools/editor/animation_editor.h b/tools/editor/animation_editor.h index 131100a205..3078b3288b 100644 --- a/tools/editor/animation_editor.h +++ b/tools/editor/animation_editor.h @@ -268,6 +268,7 @@ class AnimationKeyEditor : public VBoxContainer { EditorSelection *editor_selection; + Label *select_anim_warning; float _get_zoom_scale() const; @@ -343,6 +344,7 @@ public: void insert_value_key(const String& p_property, const Variant& p_value, bool p_advance); void insert_transform_key(Spatial *p_node,const String& p_sub,const Transform& p_xform); + void show_select_node_warning(bool p_show) { select_anim_warning->set_hidden(!p_show); } AnimationKeyEditor(); ~AnimationKeyEditor(); }; diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp index 71ae171dfe..6c8d25aa01 100644 --- a/tools/editor/code_editor.cpp +++ b/tools/editor/code_editor.cpp @@ -133,8 +133,9 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) if (found) { if (!preserve_cursor) { - text_edit->cursor_set_line(line); - text_edit->cursor_set_column(col+text.length()); + text_edit->cursor_set_line(line, false); + text_edit->cursor_set_column(col+text.length(), false); + text_edit->center_viewport_to_cursor(); } text_edit->set_search_text(text); diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp index cb7cefea26..582b9e2490 100644 --- a/tools/editor/editor_file_system.cpp +++ b/tools/editor/editor_file_system.cpp @@ -657,7 +657,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess da->change_dir(".."); } } else { - ERR_PRINTS(TTR("Cannot go into subdir:")+" "+E->get()); + ERR_PRINTS("Cannot go into subdir: "+E->get()); } p_progress.update(idx,total); diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 3f93c05919..30b89cacc5 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -565,8 +565,8 @@ void EditorNode::save_resource_in_path(const Ref<Resource>& p_resource,const Str int flg=0; if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources")) flg|=ResourceSaver::FLAG_COMPRESS; - if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) - flg|=ResourceSaver::FLAG_RELATIVE_PATHS; + //if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) + // flg|=ResourceSaver::FLAG_RELATIVE_PATHS; String path = Globals::get_singleton()->localize_path(p_path); Error err = ResourceSaver::save(path,p_resource,flg|ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); @@ -1012,8 +1012,8 @@ void EditorNode::_save_scene(String p_file, int idx) { int flg=0; if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources")) flg|=ResourceSaver::FLAG_COMPRESS; - if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) - flg|=ResourceSaver::FLAG_RELATIVE_PATHS; + //if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) + // flg|=ResourceSaver::FLAG_RELATIVE_PATHS; flg|=ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; @@ -3822,6 +3822,11 @@ void EditorNode::request_instance_scene(const String &p_path) { } +void EditorNode::request_instance_scenes(const Vector<String>& p_files) { + + scene_tree_dock->instance_scenes(p_files); +} + FileSystemDock *EditorNode::get_scenes_dock() { return scenes_dock; @@ -3831,10 +3836,9 @@ SceneTreeDock *EditorNode::get_scene_tree_dock() { return scene_tree_dock; } -void EditorNode::_instance_request(const String& p_path){ - +void EditorNode::_instance_request(const Vector<String>& p_files) { - request_instance_scene(p_path); + request_instance_scenes(p_files); } void EditorNode::_property_keyed(const String& p_keyed,const Variant& p_value,bool p_advance) { diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 9a227d3644..793c148671 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -452,7 +452,7 @@ private: void _save_scene(String p_file, int idx = -1); - void _instance_request(const String& p_path); + void _instance_request(const Vector<String>& p_files); void _property_keyed(const String& p_keyed, const Variant& p_value, bool p_advance); void _transform_keyed(Object *sp,const String& p_sub,const Transform& p_key); @@ -666,6 +666,7 @@ public: static VSplitContainer *get_top_split() { return singleton->top_split; } void request_instance_scene(const String &p_path); + void request_instance_scenes(const Vector<String>& p_files); FileSystemDock *get_scenes_dock(); SceneTreeDock *get_scene_tree_dock(); static UndoRedo* get_undo_redo() { return &singleton->editor_data.get_undo_redo(); } diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index c150e62754..9dcf71e256 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -611,8 +611,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { set("on_save/compress_binary_resources",true); set("on_save/save_modified_external_resources",true); - set("on_save/save_paths_as_relative",false); - set("on_save/save_paths_without_extension",false); + //set("on_save/save_paths_as_relative",false); + //set("on_save/save_paths_without_extension",false); set("text_editor/create_signal_callbacks",true); diff --git a/tools/editor/filesystem_dock.cpp b/tools/editor/filesystem_dock.cpp index 3be122cc7d..378edd6667 100644 --- a/tools/editor/filesystem_dock.cpp +++ b/tools/editor/filesystem_dock.cpp @@ -950,14 +950,20 @@ void FileSystemDock::_file_option(int p_option) { } break; case FILE_INSTANCE: { + Vector<String> paths; + for (int i = 0; i<files->get_item_count(); i++) { if (!files->is_selected(i)) continue; String path =files->get_item_metadata(i); if (EditorFileSystem::get_singleton()->get_file_type(path)=="PackedScene") { - emit_signal("instance",path); + paths.push_back(path); } } + + if (!paths.empty()) { + emit_signal("instance", paths); + } } break; case FILE_DEPENDENCIES: { @@ -1596,7 +1602,7 @@ void FileSystemDock::_bind_methods() { ObjectTypeDB::bind_method(_MD("_preview_invalidated"),&FileSystemDock::_preview_invalidated); - ADD_SIGNAL(MethodInfo("instance")); + ADD_SIGNAL(MethodInfo("instance", PropertyInfo(Variant::STRING_ARRAY, "files"))); ADD_SIGNAL(MethodInfo("open")); } diff --git a/tools/editor/icons/2x/icon_group.png b/tools/editor/icons/2x/icon_group.png Binary files differindex 062e1bf3fe..158efa5fe4 100644 --- a/tools/editor/icons/2x/icon_group.png +++ b/tools/editor/icons/2x/icon_group.png diff --git a/tools/editor/icons/2x/icon_object.png b/tools/editor/icons/2x/icon_object.png Binary files differindex 36ac3457bf..dc0a94aacd 100644 --- a/tools/editor/icons/2x/icon_object.png +++ b/tools/editor/icons/2x/icon_object.png diff --git a/tools/editor/icons/2x/icon_ungroup.png b/tools/editor/icons/2x/icon_ungroup.png Binary files differindex 8aaccb40a1..bb46185370 100644 --- a/tools/editor/icons/2x/icon_ungroup.png +++ b/tools/editor/icons/2x/icon_ungroup.png diff --git a/tools/editor/icons/icon_group.png b/tools/editor/icons/icon_group.png Binary files differindex e45ba2d892..5ffc90455e 100644 --- a/tools/editor/icons/icon_group.png +++ b/tools/editor/icons/icon_group.png diff --git a/tools/editor/icons/icon_object.png b/tools/editor/icons/icon_object.png Binary files differindex 7aef54bc05..f4f018c863 100644 --- a/tools/editor/icons/icon_object.png +++ b/tools/editor/icons/icon_object.png diff --git a/tools/editor/icons/icon_ungroup.png b/tools/editor/icons/icon_ungroup.png Binary files differindex 9553ef5654..b4c2e01814 100644 --- a/tools/editor/icons/icon_ungroup.png +++ b/tools/editor/icons/icon_ungroup.png diff --git a/tools/editor/icons/source/icon_group.svg b/tools/editor/icons/source/icon_group.svg index bccb23ade3..c8d20af9dd 100644 --- a/tools/editor/icons/source/icon_group.svg +++ b/tools/editor/icons/source/icon_group.svg @@ -15,7 +15,7 @@ id="svg2" version="1.1" inkscape:version="0.91 r13725" - inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_node.png" + inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_ungroup.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" sodipodi:docname="icon_group.svg"> @@ -28,9 +28,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="31.999999" - inkscape:cx="6.3400278" - inkscape:cy="8.8086774" + inkscape:zoom="22.627417" + inkscape:cx="10.459761" + inkscape:cy="9.5219725" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" @@ -46,7 +46,11 @@ inkscape:window-height="1016" inkscape:window-x="0" inkscape:window-y="27" - inkscape:window-maximized="1"> + inkscape:window-maximized="1" + inkscape:snap-midpoints="false" + inkscape:snap-smooth-nodes="false" + inkscape:object-nodes="false" + showguides="false"> <inkscape:grid type="xygrid" id="grid3336" @@ -70,9 +74,1044 @@ id="layer1" transform="translate(0,-1036.3622)"> <path - style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="M 8 1 C 4.1340068 1 1 4.134 1 8 C 1 11.866 4.1340068 15 8 15 C 11.865993 15 15 11.866 15 8 C 15 4.134 11.865993 1 8 1 z M 8 3 A 2 2 0 0 1 10 5 A 2 2 0 0 1 8 7 A 2 2 0 0 1 6 5 A 2 2 0 0 1 8 3 z M 5 8 A 2 2 0 0 1 7 10 A 2 2 0 0 1 5 12 A 2 2 0 0 1 3 10 A 2 2 0 0 1 5 8 z M 11 8 A 2 2 0 0 1 13 10 A 2 2 0 0 1 11 12 A 2 2 0 0 1 9 10 A 2 2 0 0 1 11 8 z " - transform="translate(0,1036.3622)" - id="path4154" /> + style="opacity:1;fill:#e0e0e0;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="M 7 1 L 7 3 L 7 7 L 3 7 C 3 6.9999766 2.554 7 2 7 C 1.446 7 1 6.9999766 1 7 L 1 9 L 1 13 C 1 13.000023 1.446 13 2 13 C 2.554 13 3 13.000023 3 13 L 3 9 L 7 9 L 7 13 L 3 13 C 2.9999766 13 3 13.446 3 14 C 3 14.554 2.9999766 15 3 15 L 7 15 C 7 15.000023 7.446 15 8 15 C 8.554 15 9 15.000023 9 15 L 9 13 L 9 9 L 13 9 C 13 9.0000234 13.446 9 14 9 C 14.554 9 15 9.0000234 15 9 L 15 7 L 15 3 C 15 2.9999766 14.554 3 14 3 C 13.446 3 13 2.9999766 13 3 L 13 7 L 9 7 L 9 3 L 13 3 C 13.000023 3 13 2.554 13 2 C 13 1.446 13.000023 1 13 1 L 9 1 C 9 0.99997659 8.554 1 8 1 C 7.446 1 7 0.99997659 7 1 z " + id="rect4697" + transform="translate(0,1036.3622)" /> + <rect + ry="4.3456585e-05" + rx="4.5000234" + y="996.36218" + x="-20.000004" + height="15.999995" + width="36.000008" + id="rect4379" + style="opacity:1;fill:#4b4b4b;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="8.6913296e-06" + rx="24" + y="17.999989" + x="998.36218" + height="1" + width="12" + id="rect4153" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4151" + width="12" + height="1" + x="-17.999989" + y="997.36218" + rx="24" + ry="8.6913296e-06" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4155" + width="12" + height="1" + x="998.36218" + y="4.99999" + rx="24" + ry="8.6913296e-06" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="8.6913296e-06" + rx="24" + y="1010.3622" + x="-17.999989" + height="1" + width="12" + id="rect4157" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4159" + width="4.9999809" + height="1.0000036" + x="1003.3622" + y="15.999995" + rx="9.9999619" + ry="8.6913606e-06" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="4.3456628e-05" + rx="2.0000134" + y="11.000003" + x="1002.3622" + height="4.9999976" + width="1.0000067" + id="rect4161" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="8.6913606e-06" + rx="9.9999619" + y="9.9999886" + x="1003.3622" + height="1.0000036" + width="4.9999809" + id="rect4163" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4165" + width="1.0000067" + height="4.9999976" + x="1008.3622" + y="11.000002" + rx="2.0000134" + ry="4.3456628e-05" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4167" + sodipodi:type="arc" + sodipodi:cx="-17.999989" + sodipodi:cy="998.36218" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m -17.999989,999.36218 a 1,1 0 0 1 -0.866025,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866025,-0.5 l 0,1 z" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + d="m 5.9999948,999.36218 a 1,1 0 0 1 -0.8660254,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.8660254,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="998.36218" + sodipodi:cx="5.9999948" + sodipodi:type="arc" + id="path4169" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="scale(-1,1)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + transform="scale(-1,1)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4171" + sodipodi:type="arc" + sodipodi:cx="5.9999948" + sodipodi:cy="1010.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m 5.9999948,1011.3622 a 1,1 0 0 1 -0.8660254,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.8660254,-0.5 l 0,1 z" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + d="m -17.999994,1011.3622 a 1,1 0 0 1 -0.866026,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866026,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1010.3622" + sodipodi:cx="-17.999994" + sodipodi:type="arc" + id="path4173" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4175" + sodipodi:type="arc" + sodipodi:cx="-15.999995" + sodipodi:cy="1008.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m -15.999995,1009.3622 a 1,1 0 0 1 -0.866026,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866026,-0.5 l 0,1 z" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + d="m -15.999995,1004.3622 a 1,1 0 0 1 -0.866026,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866026,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1003.3622" + sodipodi:cx="-15.999995" + sodipodi:type="arc" + id="path4177-3" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + d="m 10.999986,1009.3622 a 1,1 0 0 1 -0.866026,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866026,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1008.3622" + sodipodi:cx="10.999986" + sodipodi:type="arc" + id="path4179-6" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="scale(-1,1)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4181" + sodipodi:type="arc" + sodipodi:cx="10.999986" + sodipodi:cy="1003.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m 10.999986,1004.3622 a 1,1 0 0 1 -0.866026,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866026,-0.5 l 0,1 z" + transform="scale(-1,1)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + inkscape:connector-curvature="0" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m -12.99999,999.36232 a 1,1 0 0 0 -0.865235,0.5 1,1 0 0 0 -0.134765,0.52348 l 0,0.9765 c 0.361502,0 0.445997,0 1,0 l 0,-1 5,0 0,1 0,1.5 0,2.5 -1,0 0,1 1,0 a 1,1 0 0 0 0.865234,-0.5 1,1 0 0 0 0.134766,-0.5 l 0,-2.5 0,-2.4765 a 1,1 0 0 0 0,-0.024 1,1 0 0 0 -0.134766,-0.49998 1,1 0 0 0 -0.865234,-0.5 l -5,-10e-5 z" + id="rect4183" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="8.6913606e-06" + rx="9.9999619" + y="-4.0000043" + x="1003.3622" + height="1.0000036" + width="4.9999809" + id="rect4389" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4391" + width="1.0000067" + height="4.9999976" + x="1002.3622" + y="-8.9999962" + rx="2.0000134" + ry="4.3456628e-05" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4393" + width="4.9999809" + height="1.0000036" + x="1003.3622" + y="-10.00001" + rx="9.9999619" + ry="8.6913606e-06" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="4.3456628e-05" + rx="2.0000134" + y="-8.9999971" + x="1008.3622" + height="4.9999976" + width="1.0000067" + id="rect4395" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + d="m 4.0000043,1009.3622 a 1,1 0 0 1 -0.8660254,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.8660254,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1008.3622" + sodipodi:cx="4.0000043" + sodipodi:type="arc" + id="path4405" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4407" + sodipodi:type="arc" + sodipodi:cx="4.0000043" + sodipodi:cy="1003.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m 4.0000043,1004.3622 a 1,1 0 0 1 -0.8660254,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.8660254,-0.5 l 0,1 z" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + transform="scale(-1,1)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4409" + sodipodi:type="arc" + sodipodi:cx="-9.0000134" + sodipodi:cy="1008.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m -9.0000133,1009.3622 a 1,1 0 0 1 -0.8660254,-0.5 1,1 0 0 1 -10e-8,-1 1,1 0 0 1 0.8660255,-0.5 l -10e-8,1 z" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + transform="scale(-1,1)" + d="m -9.0000133,1004.3622 a 1,1 0 0 1 -0.8660254,-0.5 1,1 0 0 1 -10e-8,-1 1,1 0 0 1 0.8660255,-0.5 l -10e-8,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1003.3622" + sodipodi:cx="-9.0000134" + sodipodi:type="arc" + id="path4411" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + id="path4413" + d="m 7.0000094,999.36232 a 1,1 0 0 0 -0.865235,0.5 1,1 0 0 0 -0.134765,0.52348 l 0,0.9765 c 0.361502,0 0.445997,0 1,0 l 0,-1 5.0000006,0 0,1 0,1.5 0,2.5 -1,0 0,1 1,0 a 1,1 0 0 0 0.865234,-0.5 1,1 0 0 0 0.134766,-0.5 l 0,-2.5 0,-2.4765 a 1,1 0 0 0 0,-0.024 1,1 0 0 0 -0.134766,-0.49998 1,1 0 0 0 -0.865234,-0.5 l -5.0000006,-10e-5 z" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:connector-curvature="0" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + style="opacity:1;fill:#4b4b4b;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4415" + width="36.000008" + height="15.999995" + x="-19.999994" + y="1012.3622" + rx="4.5000234" + ry="4.3456585e-05" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + d="m -16.000053,1020.3622 a 1,1 0 0 1 -0.866026,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866026,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1019.3622" + sodipodi:cx="-16.000053" + sodipodi:type="arc" + id="path4417" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + d="m 11.000043,1025.3622 a 1,1 0 0 1 -0.866025,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866025,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1024.3622" + sodipodi:cx="11.000043" + sodipodi:type="arc" + id="path4419" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="scale(-1,1)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4421" + width="2" + height="5" + x="-19.000053" + y="1020.3622" + rx="2.00001" + ry="4.3456599e-05" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="1.7382426e-05" + rx="5.000021" + y="1018.3622" + x="-17.00005" + height="1.9999754" + width="4.9999962" + id="rect4423" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="4.3456599e-05" + rx="2.00001" + y="1020.3622" + x="-12.000043" + height="5" + width="2" + id="rect4425" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4427" + width="2" + height="5" + x="1025.3622" + y="12.000043" + rx="2.00001" + ry="4.3456599e-05" + transform="matrix(0,1,-1,0,0,0)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4429" + sodipodi:type="arc" + sodipodi:cx="-17.000048" + sodipodi:cy="1020.3622" + sodipodi:rx="2" + sodipodi:ry="2" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m -17.000048,1022.3622 a 2,2 0 0 1 -1.73205,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.73205,-1 l 0,2 z" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + d="m -17.000048,1027.3622 a 2,2 0 0 1 -1.73205,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.73205,-1 l 0,2 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="2" + sodipodi:rx="2" + sodipodi:cy="1025.3622" + sodipodi:cx="-17.000048" + sodipodi:type="arc" + id="path4431" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + d="m 12.000043,1022.3622 a 2,2 0 0 1 -1.732051,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.732051,-1 l 0,2 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="2" + sodipodi:rx="2" + sodipodi:cy="1020.3622" + sodipodi:cx="12.000043" + sodipodi:type="arc" + id="path4433" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="scale(-1,1)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4435" + sodipodi:type="arc" + sodipodi:cx="12.000043" + sodipodi:cy="1025.3622" + sodipodi:rx="2" + sodipodi:ry="2" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m 12.000043,1027.3622 a 2,2 0 0 1 -1.732051,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.732051,-1 l 0,2 z" + transform="scale(-1,1)" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + inkscape:connector-curvature="0" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m -12.000048,1013.3622 a 2,2 0 0 0 -1.732422,1 2,2 0 0 0 -0.265625,1 l -0.0019,0 0,1 2,0 0,-1 2.5000001,0 2.5,0 0,3 0,2 -1,0 0,2 1,0 a 2,2 0 0 0 1.732422,-1 2,2 0 0 0 0.265625,-1 l 0.002,0 0,-5 -0.002,0 a 2,2 0 0 0 -0.265625,-1 2,2 0 0 0 -1.732422,-1 l -2.5,0 -2.5000001,0 z" + id="path4437" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + inkscape:connector-curvature="0" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m -17.000048,1013.3622 a 2,2 0 0 0 -1.732422,1 2,2 0 0 0 -0.265625,1 c 0,0 -0.0019,0 -0.0019,0 l 0,7 c 0,0 0.446,0 1,0 0.554,0 1,0 1,0 l 0,-5 0,-2 5,0 5.0000001,0 0,-2 -5.0000001,0 -5,0 z m 10.0000001,5 0,7 -4.5000001,0 -4.5,0 0,2 4.5,0 4.5000001,0 a 2,2 0 0 0 1.732422,-1 2,2 0 0 0 0.265625,-1 c 0,0 0.002,0 0.002,0 l 0,-7 c 0,0 -0.446,0 -1,0 -0.554,0 -1,0 -1,0 z" + id="path4439" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4441" + width="2" + height="2" + x="-14.000048" + y="1016.3622" + rx="2.00001" + ry="3.3799501e-05" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="3.3799501e-05" + rx="2.00001" + y="1020.3622" + x="-10.000052" + height="2" + width="2" + id="rect4443" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4445" + sodipodi:type="arc" + sodipodi:cx="3.9999421" + sodipodi:cy="1019.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m 3.9999421,1020.3622 a 1,1 0 0 1 -0.8660254,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.8660254,-0.5 l 0,1 z" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + transform="scale(-1,1)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4447" + sodipodi:type="arc" + sodipodi:cx="-8.9999523" + sodipodi:cy="1024.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m -8.9999523,1025.3622 a 1,1 0 0 1 -0.8660254,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.8660254,-0.5 l 0,1 z" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="4.3456599e-05" + rx="2.00001" + y="1020.3622" + x="0.99994206" + height="5" + width="2" + id="rect4449" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4451" + width="4.9999962" + height="1.9999754" + x="2.9999459" + y="1018.3622" + rx="5.000021" + ry="1.7382426e-05" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4453" + width="2" + height="5" + x="7.9999528" + y="1020.3622" + rx="2.00001" + ry="4.3456599e-05" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + ry="4.3456599e-05" + rx="2.00001" + y="-7.9999528" + x="1025.3622" + height="5" + width="2" + id="rect4455" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + d="m 2.9999478,1022.3622 a 2,2 0 0 1 -1.7320508,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.7320508,-1 l 0,2 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="2" + sodipodi:rx="2" + sodipodi:cy="1020.3622" + sodipodi:cx="2.9999478" + sodipodi:type="arc" + id="path4457" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4459" + sodipodi:type="arc" + sodipodi:cx="2.9999478" + sodipodi:cy="1025.3622" + sodipodi:rx="2" + sodipodi:ry="2" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m 2.9999478,1027.3622 a 2,2 0 0 1 -1.7320508,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.7320508,-1 l 0,2 z" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + transform="scale(-1,1)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4461" + sodipodi:type="arc" + sodipodi:cx="-7.9999528" + sodipodi:cy="1020.3622" + sodipodi:rx="2" + sodipodi:ry="2" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m -7.9999527,1022.3622 a 2,2 0 0 1 -1.7320509,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.7320508,-1 l 0,2 z" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + transform="scale(-1,1)" + d="m -7.9999527,1027.3622 a 2,2 0 0 1 -1.7320509,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.7320508,-1 l 0,2 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="2" + sodipodi:rx="2" + sodipodi:cy="1025.3622" + sodipodi:cx="-7.9999528" + sodipodi:type="arc" + id="path4463" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <path + id="path4465" + d="m 7.9999475,1013.3622 a 2,2 0 0 0 -1.732422,1 2,2 0 0 0 -0.265625,1 l -0.0019,0 0,1 2,0 0,-1 2.5000005,0 2.5,0 0,3 0,2 -1,0 0,2 1,0 a 2,2 0 0 0 1.732422,-1 2,2 0 0 0 0.265625,-1 l 0.002,0 0,-5 -0.002,0 a 2,2 0 0 0 -0.265625,-1 2,2 0 0 0 -1.732422,-1 l -2.5,0 -2.5000005,0 z" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:connector-curvature="0" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + ry="3.3799501e-05" + rx="2.00001" + y="1016.3622" + x="5.999948" + height="2" + width="2" + id="rect4469" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4471" + width="2" + height="2" + x="9.9999428" + y="1020.3622" + rx="2.00001" + ry="3.3799501e-05" + inkscape:export-filename="/home/djrm/rect4471.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4473" + width="12" + height="1" + x="1038.3622" + y="-35.500008" + rx="24" + ry="8.6913296e-06" /> + <rect + ry="8.6913296e-06" + rx="24" + y="1037.3622" + x="35.500008" + height="1" + width="12" + id="rect4475" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + ry="8.6913296e-06" + rx="24" + y="-48.500004" + x="1038.3622" + height="1" + width="12" + id="rect4477" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4479" + width="12" + height="1" + x="35.500008" + y="1050.3622" + rx="24" + ry="8.6913296e-06" /> + <rect + ry="8.6913606e-06" + rx="9.9999619" + y="-37.5" + x="1043.3622" + height="1.0000036" + width="4.9999809" + id="rect4481" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4483" + width="1.0000067" + height="4.9999976" + x="1042.3622" + y="-42.499992" + rx="2.0000134" + ry="4.3456628e-05" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4485" + width="4.9999809" + height="1.0000036" + x="1043.3622" + y="-43.500008" + rx="9.9999619" + ry="8.6913606e-06" /> + <rect + ry="4.3456628e-05" + rx="2.0000134" + y="-42.499992" + x="1048.3622" + height="4.9999976" + width="1.0000067" + id="rect4487" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" /> + <path + d="m 35.500008,1039.3622 a 1,1 0 0 1 -0.866026,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866026,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1038.3622" + sodipodi:cx="35.500008" + sodipodi:type="arc" + id="path4489" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + transform="scale(-1,1)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4491" + sodipodi:type="arc" + sodipodi:cx="-47.5" + sodipodi:cy="1038.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m -47.5,1039.3622 a 1,1 0 0 1 -0.866025,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866025,-0.5 l 0,1 z" /> + <path + d="m -47.5,1051.3622 a 1,1 0 0 1 -0.866025,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866025,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1050.3622" + sodipodi:cx="-47.5" + sodipodi:type="arc" + id="path4493" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="scale(-1,1)" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4495" + sodipodi:type="arc" + sodipodi:cx="35.5" + sodipodi:cy="1050.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m 35.5,1051.3622 a 1,1 0 0 1 -0.866025,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866025,-0.5 l 0,1 z" /> + <path + d="m 37.5,1049.3622 a 1,1 0 0 1 -0.866025,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866025,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1048.3622" + sodipodi:cx="37.5" + sodipodi:type="arc" + id="path4497" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4499" + sodipodi:type="arc" + sodipodi:cx="37.5" + sodipodi:cy="1043.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m 37.5,1044.3622 a 1,1 0 0 1 -0.866025,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866025,-0.5 l 0,1 z" /> + <path + transform="scale(-1,1)" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4501" + sodipodi:type="arc" + sodipodi:cx="-42.500011" + sodipodi:cy="1048.3622" + sodipodi:rx="1" + sodipodi:ry="1" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m -42.500011,1049.3622 a 1,1 0 0 1 -0.866026,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866026,-0.5 l 0,1 z" /> + <path + transform="scale(-1,1)" + d="m -42.500011,1044.3622 a 1,1 0 0 1 -0.866026,-0.5 1,1 0 0 1 0,-1 1,1 0 0 1 0.866026,-0.5 l 0,1 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="1" + sodipodi:rx="1" + sodipodi:cy="1043.3622" + sodipodi:cx="-42.500011" + sodipodi:type="arc" + id="path4503" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + id="path4505" + d="m 40.500005,1039.3623 a 1,1 0 0 0 -0.865235,0.5 1,1 0 0 0 -0.134765,0.5235 l 0,0.9765 c 0.361502,0 0.445997,0 1,0 l 0,-1 5,0 0,1 0,1.5 0,2.5 -1,0 0,1 1,0 a 1,1 0 0 0 0.865234,-0.5 1,1 0 0 0 0.134766,-0.5 l 0,-2.5 0,-2.4765 a 1,1 0 0 0 0,-0.024 1,1 0 0 0 -0.134766,-0.5 1,1 0 0 0 -0.865234,-0.5 l -5,-10e-5 z" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <rect + inkscape:export-ydpi="180" + inkscape:export-xdpi="180" + inkscape:export-filename="/home/djrm/rect4471.png" + ry="4.3456599e-05" + rx="2.00001" + y="1044.3622" + x="-18.000057" + height="5" + width="2" + id="rect4536" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + inkscape:export-ydpi="180" + inkscape:export-xdpi="180" + inkscape:export-filename="/home/djrm/rect4471.png" + transform="matrix(0,1,-1,0,0,0)" + ry="4.3456599e-05" + rx="2.00001" + y="11.000047" + x="1049.3622" + height="5" + width="2" + id="rect4542" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + inkscape:export-ydpi="180" + inkscape:export-xdpi="180" + inkscape:export-filename="/home/djrm/rect4471.png" + d="m -16.00005,1046.3622 a 2,2 0 0 1 -1.73205,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.73205,-1 l 0,2 z" + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + sodipodi:ry="2" + sodipodi:rx="2" + sodipodi:cy="1044.3622" + sodipodi:cx="-16.00005" + sodipodi:type="arc" + id="path4544" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + inkscape:export-ydpi="180" + inkscape:export-xdpi="180" + inkscape:export-filename="/home/djrm/rect4471.png" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path4546" + sodipodi:type="arc" + sodipodi:cx="-16.00005" + sodipodi:cy="1049.3622" + sodipodi:rx="2" + sodipodi:ry="2" + sodipodi:start="1.5707963" + sodipodi:end="4.712389" + d="m -16.00005,1051.3622 a 2,2 0 0 1 -1.73205,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.73205,-1 l 0,2 z" /> + <path + inkscape:export-ydpi="180" + inkscape:export-xdpi="180" + inkscape:export-filename="/home/djrm/rect4471.png" + id="path4554" + d="m -16.000053,1037.3622 a 2,2 0 0 0 -1.732422,1 2,2 0 0 0 -0.265625,1 c 0,0 -0.0019,0 -0.0019,0 l 0,7 c 0,0 0.446,0 1,0 0.554,0 1,0 1,0 l 0,-5 0,-2 5.000001,0 5,0 0,-2 -5,0 -5.000001,0 z m 10.000001,5 0,7 -4.5,0 -4.500001,0 0,2 4.500001,0 4.5,0 a 2,2 0 0 0 1.732422,-1 2,2 0 0 0 0.265625,-1 c 0,0 0.002,0 0.002,0 l 0,-7 c 0,0 -0.446,0 -1,0 -0.554,0 -1,0 -1,0 z" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4560" + width="4" + height="4" + x="-14" + y="1041.3622" + rx="2.00001" + ry="3.3799501e-05" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m 33.000005,1021.3622 c 1.107999,0 2,0.892 2,2 l 0,5 c 0,1.108 -0.892001,2 -2,2 l -1,0 0,-3 a 2.9999926,2.9999926 0 0 0 -3,-3 l -3,0 0,-1 c 0,-1.108 0.892001,-2 2,-2 l 5,0 z m -7,6 a 2.9999926,2.9999926 0 0 0 3,3 l -1,0 c -1.107999,0 -2,-0.892 -2,-2 l 0,-1 z" + id="rect4562" + inkscape:connector-curvature="0" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4566" + width="8.9999924" + height="9.0000114" + x="-30.000002" + y="1026.3622" + rx="1.9999952" + ry="2.0000174" + transform="scale(-1,1)" /> + <rect + inkscape:export-ydpi="180" + inkscape:export-xdpi="180" + inkscape:export-filename="/home/djrm/rect4471.png" + style="opacity:1;fill:#4b4b4b;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4579" + width="36.000008" + height="15.999995" + x="-20.000004" + y="980.36218" + rx="4.5000234" + ry="4.3456585e-05" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m -32.000005,1037.3622 c -1.10801,0 -2,0.892 -2,2 l 0,10 c 0,1.108 0.89199,2 2,2 l 10,0 c 1.10801,0 2,-0.892 2,-2 l 0,-10 c 0,-1.108 -0.89199,-2 -2,-2 l -10,0 z m 0,2 10,0 0,10 -10,0 0,-10 z" + id="rect4601" + inkscape:connector-curvature="0" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m 21,1044.3622 a 3.4999881,3.4999881 0 0 0 -3.5,3.5 3.4999881,3.4999881 0 0 0 3.5,3.5 3.4999881,3.4999881 0 0 0 3.5,-3.5 3.4999881,3.4999881 0 0 0 -3.5,-3.5 z m 0,2 a 1.5000153,1.5000153 0 0 1 1.5,1.5 1.5000153,1.5000153 0 0 1 -1.5,1.5 1.5000153,1.5000153 0 0 1 -1.5,-1.5 1.5000153,1.5000153 0 0 1 1.5,-1.5 z" + id="path4644" + inkscape:connector-curvature="0" /> + <path + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m 28,1037.3622 a 3.4999881,3.4999881 0 0 0 -3.5,3.5 3.4999881,3.4999881 0 0 0 3.5,3.5 3.4999881,3.4999881 0 0 0 3.5,-3.5 3.4999881,3.4999881 0 0 0 -3.5,-3.5 z m 0,2 a 1.5000153,1.5000153 0 0 1 1.5,1.5 1.5000153,1.5000153 0 0 1 -1.5,1.5 1.5000153,1.5000153 0 0 1 -1.5,-1.5 1.5000153,1.5000153 0 0 1 1.5,-1.5 z" + id="circle4646" + inkscape:connector-curvature="0" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4679" + width="2" + height="1.9999826" + x="1" + y="1049.3622" + rx="2.5000134" + ry="4.2248896e-05" /> + <rect + ry="4.224963e-05" + rx="2.5000134" + y="1037.3622" + x="1" + height="2.0000174" + width="2" + id="rect4681" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4693" + width="2" + height="2.0000174" + x="13" + y="1037.3622" + rx="2.5000134" + ry="4.224963e-05" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4726" + width="2" + height="2.0000174" + x="13" + y="1049.3622" + rx="2.5000134" + ry="4.224963e-05" /> </g> </svg> diff --git a/tools/editor/icons/source/icon_object.svg b/tools/editor/icons/source/icon_object.svg index 6236f75c4d..6b36b61168 100644 --- a/tools/editor/icons/source/icon_object.svg +++ b/tools/editor/icons/source/icon_object.svg @@ -29,8 +29,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="32" - inkscape:cx="7.2827981" - inkscape:cy="6.8612677" + inkscape:cx="6.0308283" + inkscape:cy="7.6625569" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" @@ -74,27 +74,14 @@ id="layer1" transform="translate(0,-1036.3622)"> <path - style="fill:#cacad7;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" - d="m 8,1044.3622 6,-3 -6,-3 -6,3 z" - id="path4180" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> + style="fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 8,1043.8622 0,6 6,-3 0,-6 z" + id="path4135" + inkscape:connector-curvature="0" /> <path - style="fill:#cacad7;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" - d="m 2,1047.3622 6,3 0,-6 -6,-3 z" - id="path4176" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - <path - sodipodi:nodetypes="ccccc" - inkscape:connector-curvature="0" - id="path4178" - d="m 14,1047.3622 -6,3 0,-6 6,-3 z" - style="fill:#cacad7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#3b3a4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 7.9628906 1.0019531 A 1.0001 1.0001 0 0 0 7.5527344 1.1054688 L 1.5527344 4.1054688 A 1.0001 1.0001 0 0 0 1 5 L 1 11 A 1.0001 1.0001 0 0 0 1.5527344 11.894531 L 7.5527344 14.894531 A 1.0001 1.0001 0 0 0 8.4472656 14.894531 L 14.447266 11.894531 A 1.0001 1.0001 0 0 0 15 11 L 15 5 A 1.0001 1.0001 0 0 0 14.447266 4.1054688 L 8.4472656 1.1054688 A 1.0001 1.0001 0 0 0 7.9628906 1.0019531 z M 8 3.1191406 L 11.763672 5 L 8 6.8828125 L 4.2363281 5 L 8 3.1191406 z M 3 6.6171875 L 7 8.6171875 L 7 12.382812 L 3 10.382812 L 3 6.6171875 z M 13 6.6171875 L 13 10.382812 L 9 12.382812 L 9 8.6171875 L 13 6.6171875 z " - transform="translate(0,1036.3622)" - id="path4139" /> + id="path4139" + transform="translate(0,1036.3622)" /> </g> </svg> diff --git a/tools/editor/icons/source/icon_ungroup.svg b/tools/editor/icons/source/icon_ungroup.svg index c45e3e4cb9..f0b33465cd 100644 --- a/tools/editor/icons/source/icon_ungroup.svg +++ b/tools/editor/icons/source/icon_ungroup.svg @@ -29,8 +29,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="31.999999" - inkscape:cx="11.746278" - inkscape:cy="8.8711774" + inkscape:cx="2.9046561" + inkscape:cy="8.8085261" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" @@ -60,7 +60,7 @@ <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> + <dc:title /> </cc:Work> </rdf:RDF> </metadata> @@ -70,9 +70,72 @@ id="layer1" transform="translate(0,-1036.3622)"> <path + inkscape:connector-curvature="0" + style="opacity:1;fill:#e0e0e0;fill-opacity:0.39215686;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m 7,1037.3622 0,2 0,4 -4,0 c 0,0 -0.446,0 -1,0 -0.554,0 -1,0 -1,0 l 0,2 0,4 c 0,0 0.446,0 1,0 0.554,0 1,0 1,0 l 0,-4 4,0 0,4 -4,0 c -2.34e-5,0 0,0.446 0,1 0,0.554 -2.34e-5,1 0,1 l 4,0 c 0,0 0.446,0 1,0 0.554,0 1,0 1,0 l 0,-2 0,-4 4,0 c 0,0 0.446,0 1,0 0.554,0 1,0 1,0 l 0,-2 0,-4 c 0,0 -0.446,0 -1,0 -0.554,0 -1,0 -1,0 l 0,4 -4,0 0,-4 4,0 c 2.3e-5,0 0,-0.446 0,-1 0,-0.554 2.3e-5,-1 0,-1 l -4,0 c 0,0 -0.446,0 -1,0 -0.554,0 -1,0 -1,0 z" + id="rect4697" /> + <rect style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="M 8 3 A 2 2 0 0 0 6 5 A 2 2 0 0 0 8 7 A 2 2 0 0 0 10 5 A 2 2 0 0 0 8 3 z M 5 8 A 2 2 0 0 0 3 10 A 2 2 0 0 0 5 12 A 2 2 0 0 0 7 10 A 2 2 0 0 0 5 8 z M 11 8 A 2 2 0 0 0 9 10 A 2 2 0 0 0 11 12 A 2 2 0 0 0 13 10 A 2 2 0 0 0 11 8 z " - transform="translate(0,1036.3622)" - id="path4155" /> + id="rect4679" + width="2" + height="1.9999826" + x="1" + y="1049.3622" + rx="2.5000134" + ry="4.2248896e-05" /> + <rect + ry="4.224963e-05" + rx="2.5000134" + y="1043.3622" + x="1" + height="2.0000174" + width="2" + id="rect4681" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4693" + width="2" + height="2.0000174" + x="13" + y="1037.3622" + rx="2.5000134" + ry="4.224963e-05" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4726" + width="2" + height="2.0000174" + x="7" + y="1049.3622" + rx="2.5000134" + ry="4.224963e-05" /> + <rect + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4157" + width="2" + height="2.0000174" + x="7" + y="1037.3622" + rx="2.5000134" + ry="4.224963e-05" /> + <rect + ry="4.224963e-05" + rx="2.5000134" + y="1043.3622" + x="7" + height="2.0000174" + width="2" + id="rect4159" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + ry="4.224963e-05" + rx="2.5000134" + y="1043.3622" + x="13" + height="2.0000174" + width="2" + id="rect4161" + style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> </g> </svg> diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp index 2c3ed2afd6..da608292c1 100644 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp @@ -496,7 +496,6 @@ Error EditorMeshImportPlugin::import(const String& p_path, const Ref<ResourceImp } int vtx = face[idx][0].to_int()-1; - print_line("vtx: "+itos(vtx)+"/"+itos(vertices.size())); ERR_FAIL_INDEX_V(vtx,vertices.size(),ERR_PARSE_ERROR); Vector3 vertex = vertices[vtx]; diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp index 98ba25b482..b4d54c6b1e 100644 --- a/tools/editor/plugins/animation_player_editor_plugin.cpp +++ b/tools/editor/plugins/animation_player_editor_plugin.cpp @@ -43,6 +43,7 @@ void AnimationPlayerEditor::_node_removed(Node *p_node) { key_editor->set_animation(Ref<Animation>()); key_editor->set_root(NULL); + key_editor->show_select_node_warning(true); _update_player(); //editor->animation_editor_make_visible(false); @@ -376,8 +377,8 @@ void AnimationPlayerEditor::_animation_save_in_path(const Ref<Resource>& p_resou int flg = 0; if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources")) flg |= ResourceSaver::FLAG_COMPRESS; - if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) - flg |= ResourceSaver::FLAG_RELATIVE_PATHS; + //if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) + // flg |= ResourceSaver::FLAG_RELATIVE_PATHS; String path = Globals::get_singleton()->localize_path(p_path); Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); @@ -832,6 +833,7 @@ void AnimationPlayerEditor::_update_player() { remove_anim->set_disabled(animlist.size()==0); resource_edit_anim->set_disabled(animlist.size()==0); save_anim->set_disabled(animlist.size() == 0); + tool_anim->set_disabled(player==NULL); int active_idx=-1; @@ -889,9 +891,11 @@ void AnimationPlayerEditor::edit(AnimationPlayer *p_player) { return; //ignore, pinned player=p_player; - if (player) + if (player) { _update_player(); - else { + key_editor->show_select_node_warning(false); + } else { + key_editor->show_select_node_warning(true); // hide(); @@ -1123,6 +1127,7 @@ void AnimationPlayerEditor::_hide_anim_editors() { key_editor->set_animation(Ref<Animation>()); key_editor->set_root(NULL); + key_editor->show_select_node_warning(true); // editor->animation_editor_make_visible(false); } @@ -1531,6 +1536,8 @@ void AnimationPlayerEditorPlugin::edit(Object *p_object) { if (!p_object) return; anim_editor->edit(p_object->cast_to<AnimationPlayer>()); + + } bool AnimationPlayerEditorPlugin::handles(Object *p_object) const { diff --git a/tools/editor/plugins/texture_region_editor_plugin.cpp b/tools/editor/plugins/texture_region_editor_plugin.cpp index 63d8e2e1cf..db888208fb 100644 --- a/tools/editor/plugins/texture_region_editor_plugin.cpp +++ b/tools/editor/plugins/texture_region_editor_plugin.cpp @@ -703,14 +703,24 @@ void TextureRegionEditor::_edit_region() bool merged = true; while (merged) { merged = false; + bool queue_erase = false; for (List<Rect2>::Element *F = autoslice_cache.front(); F; F=F->next()) { + if (queue_erase){ + autoslice_cache.erase(F->prev()); + queue_erase = false; + } if (F==E) continue; if (E->get().grow(1).intersects(F->get())) { E->get().expand_to(F->get().pos); E->get().expand_to(F->get().pos+F->get().size); - F=F->prev(); - autoslice_cache.erase(F->next()); + if (F->prev()) { + F=F->prev(); + autoslice_cache.erase(F->next()); + } else { + queue_erase = true; + //Cant delete the first rect in the list. + } merged = true; } } diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index b7d3abfd5b..caf116523a 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -31,6 +31,7 @@ #include "os/os.h" #include "os/dir_access.h" #include "os/file_access.h" +#include "os/keyboard.h" #include "editor_settings.h" #include "scene/gui/separator.h" #include "scene/gui/tool_button.h" @@ -491,6 +492,10 @@ void ProjectManager::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { get_tree()->set_editor_hint(true); + + } else if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { + + set_process_unhandled_input(is_visible()); } } @@ -576,6 +581,134 @@ void ProjectManager::_panel_input(const InputEvent& p_ev,Node *p_hb) { } } +void ProjectManager::_unhandled_input(const InputEvent& p_ev) { + + if (p_ev.type==InputEvent::KEY) { + + const InputEventKey &k = p_ev.key; + + if (!k.pressed) + return; + + bool scancode_handled = true; + + switch (k.scancode) { + + case KEY_HOME: { + + for (int i=0; i<scroll_childs->get_child_count(); i++) { + + HBoxContainer *hb = scroll_childs->get_child(i)->cast_to<HBoxContainer>(); + if (hb) { + selected_list.clear(); + selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene")); + scroll->set_v_scroll(0); + break; + } + } + + } break; + case KEY_END: { + + for (int i=scroll_childs->get_child_count()-1; i>=0; i--) { + + HBoxContainer *hb = scroll_childs->get_child(i)->cast_to<HBoxContainer>(); + if (hb) { + selected_list.clear(); + selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene")); + scroll->set_v_scroll(scroll_childs->get_size().y); + break; + } + } + + } break; + case KEY_UP: { + + if (k.mod.shift) + break; + + if (selected_list.size()) { + + bool found = false; + + for (int i=scroll_childs->get_child_count()-1; i>=0; i--) { + + HBoxContainer *hb = scroll_childs->get_child(i)->cast_to<HBoxContainer>(); + if (!hb) continue; + + String current = hb->get_meta("name"); + + if (found) { + selected_list.clear(); + selected_list.insert(current, hb->get_meta("main_scene")); + + int offset_diff = scroll->get_v_scroll() - hb->get_pos().y; + + if (offset_diff > 0) + scroll->set_v_scroll(scroll->get_v_scroll() - offset_diff); + + break; + + } else if (current==selected_list.back()->key()) { + + found = true; + } + } + + break; + } + // else fallthrough to key_down + } + case KEY_DOWN: { + + if (k.mod.shift) + break; + + bool found = selected_list.empty(); + + for (int i=0; i<scroll_childs->get_child_count(); i++) { + + HBoxContainer *hb = scroll_childs->get_child(i)->cast_to<HBoxContainer>(); + if (!hb) continue; + + String current = hb->get_meta("name"); + + if (found) { + selected_list.clear(); + selected_list.insert(current, hb->get_meta("main_scene")); + + int last_y_visible = scroll->get_v_scroll() + scroll->get_size().y; + int offset_diff = (hb->get_pos().y + hb->get_size().y) - last_y_visible; + + if (offset_diff > 0) + scroll->set_v_scroll(scroll->get_v_scroll() + offset_diff); + + break; + + } else if (current==selected_list.back()->key()) { + + found = true; + } + } + + } break; + default: { + scancode_handled = false; + } break; + } + + if (scancode_handled) { + accept_event(); + + for(int i=0;i<scroll_childs->get_child_count();i++) { + CanvasItem *item = scroll_childs->get_child(i)->cast_to<CanvasItem>(); + if (item) + item->update(); + } + } + } +} + void ProjectManager::_favorite_pressed(Node *p_hb) { String clicked = p_hb->get_meta("name"); @@ -964,6 +1097,7 @@ void ProjectManager::_bind_methods() { ObjectTypeDB::bind_method("_load_recent_projects",&ProjectManager::_load_recent_projects); ObjectTypeDB::bind_method("_panel_draw",&ProjectManager::_panel_draw); ObjectTypeDB::bind_method("_panel_input",&ProjectManager::_panel_input); + ObjectTypeDB::bind_method("_unhandled_input",&ProjectManager::_unhandled_input); ObjectTypeDB::bind_method("_favorite_pressed",&ProjectManager::_favorite_pressed); ObjectTypeDB::bind_method("_install_project",&ProjectManager::_install_project); diff --git a/tools/editor/project_manager.h b/tools/editor/project_manager.h index 69467f50e7..74d1d3693c 100644 --- a/tools/editor/project_manager.h +++ b/tools/editor/project_manager.h @@ -92,6 +92,7 @@ class ProjectManager : public Control { void _panel_draw(Node *p_hb); void _panel_input(const InputEvent& p_ev,Node *p_hb); + void _unhandled_input(const InputEvent& p_ev); void _favorite_pressed(Node *p_hb); protected: diff --git a/tools/editor/resources_dock.cpp b/tools/editor/resources_dock.cpp index 10292ed10d..c73c8c081c 100644 --- a/tools/editor/resources_dock.cpp +++ b/tools/editor/resources_dock.cpp @@ -126,8 +126,8 @@ void ResourcesDock::save_resource(const String& p_path,const Ref<Resource>& p_re int flg=0; if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources")) flg|=ResourceSaver::FLAG_COMPRESS; - if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) - flg|=ResourceSaver::FLAG_RELATIVE_PATHS; + //if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) + // flg|=ResourceSaver::FLAG_RELATIVE_PATHS; String path = Globals::get_singleton()->localize_path(p_path); Error err = ResourceSaver::save(path,p_resource,flg|ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index e4dfcc0f62..35ddb49465 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -106,11 +106,30 @@ void SceneTreeDock::instance(const String& p_file) { Vector<String> scenes; scenes.push_back(p_file); - instance_scenes(scenes,parent,-1); + _perform_instance_scenes(scenes,parent,-1); } -void SceneTreeDock::instance_scenes(const Vector<String>& p_files,Node* parent,int p_pos) { +void SceneTreeDock::instance_scenes(const Vector<String>& p_files, Node *p_parent) { + + Node *parent = p_parent; + + if (!parent) { + parent = scene_tree->get_selected(); + } + + if (!parent || !edited_scene) { + + accept->get_ok()->set_text(TTR("OK")); + accept->set_text(TTR("No parent to instance the scenes at.")); + accept->popup_centered_minsize(); + return; + }; + + _perform_instance_scenes(p_files, parent, -1); +} + +void SceneTreeDock::_perform_instance_scenes(const Vector<String>& p_files,Node* parent,int p_pos) { @@ -1489,8 +1508,8 @@ void SceneTreeDock::_new_scene_from(String p_file) { int flg=0; if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources")) flg|=ResourceSaver::FLAG_COMPRESS; - if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) - flg|=ResourceSaver::FLAG_RELATIVE_PATHS; + //if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) + // flg|=ResourceSaver::FLAG_RELATIVE_PATHS; err = ResourceSaver::save(p_file,sdata,flg); @@ -1677,7 +1696,7 @@ void SceneTreeDock::_files_dropped(Vector<String> p_files,NodePath p_to,int p_ty int to_pos=-1; _normalize_drop(node,to_pos,p_type); - instance_scenes(p_files,node,to_pos); + _perform_instance_scenes(p_files,node,to_pos); } void SceneTreeDock::_nodes_dragged(Array p_nodes,NodePath p_to,int p_type) { diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index 51041a235b..04ed16967f 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -148,6 +148,8 @@ class SceneTreeDock : public VBoxContainer { void _filter_changed(const String& p_filter); + void _perform_instance_scenes(const Vector<String>& p_files,Node* parent,int p_pos); + protected: void _notification(int p_what); @@ -160,7 +162,7 @@ public: void import_subscene(); void set_edited_scene(Node* p_scene); void instance(const String& p_path); - void instance_scenes(const Vector<String>& p_files,Node* parent,int p_pos); + void instance_scenes(const Vector<String>& p_files, Node *p_parent=NULL); void set_selected(Node *p_node, bool p_emit_selected=false); void fill_path_renames(Node* p_node, Node *p_new_parent, List<Pair<NodePath,NodePath> > *p_renames); void perform_node_renames(Node* p_base,List<Pair<NodePath,NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims=NULL); |