diff --git a/Kconfig b/Kconfig index e07d680a7..acf7974d0 100644 --- a/Kconfig +++ b/Kconfig @@ -956,19 +956,20 @@ menu "LVGL configuration" if LV_USE_FREETYPE menu "FreeType cache config" config LV_FREETYPE_CACHE_SIZE - int "Memory used by FreeType to cache characters [bytes] (-1: no caching)" - default 16384 - if LV_FREETYPE_CACHE_SIZE >= 0 - config LV_FREETYPE_SBIT_CACHE - bool "enable sbit cache" - default n - config LV_FREETYPE_CACHE_FT_FACES - int "The maximum number of FT_Face(0: use defaults)" - default 0 - config LV_FREETYPE_CACHE_FT_SIZES - int "The maximum number of FT_Size(0: use defaults)" - default 0 - endif + int "Memory used by FreeType to cache characters [bytes]" + default 65535 + config LV_FREETYPE_USE_LVGL_PORT + bool "Let FreeType to use LVGL memory and file porting" + default n + config LV_FREETYPE_SBIT_CACHE + bool "enable sbit cache" + default n + config LV_FREETYPE_CACHE_FT_FACES + int "The maximum number of FT_Face(0: use defaults)" + default 4 + config LV_FREETYPE_CACHE_FT_SIZES + int "The maximum number of FT_Size(0: use defaults)" + default 4 endmenu endif diff --git a/docs/libs/freetype.md b/docs/libs/freetype.md index 0a98c46e1..8597ab0a9 100644 --- a/docs/libs/freetype.md +++ b/docs/libs/freetype.md @@ -2,37 +2,72 @@ # FreeType support Interface to [FreeType](https://www.freetype.org/) to generate font bitmaps run time. -## Install FreeType -- Download Freetype from [here](https://sourceforge.net/projects/freetype/files/) +## Add FreeType to your project + +First, Download FreeType from [here](https://sourceforge.net/projects/freetype/files/). + +There are two ways to use FreeType: +### For UNIX +For UNIX systems, it is recommended to use the way of compiling and installing libraries. +- Enter the FreeType source code directory. - `make` - `sudo make install` - -## Add FreeType to your project - Add include path: `/usr/include/freetype2` (for GCC: `-I/usr/include/freetype2 -L/usr/local/lib`) -- Add library: `freetype` (for GCC: `-L/usr/local/lib -lfreetype`) +- Link library: `freetype` (for GCC: `-L/usr/local/lib -lfreetype`) + +### For Embedded Devices +For embedded devices, it is more recommended to use the FreeType configuration file provided by LVGL, which only includes the most commonly used functions, which is very meaningful for saving limited FLASH space. + +- Copy the FreeType source code to your project directory. +- Refer to the following `Makefile` for configuration: + +```make +# FreeType custom configuration header file +CFLAGS += -DFT2_BUILD_LIBRARY +CFLAGS += -DFT_CONFIG_MODULES_H= +CFLAGS += -DFT_CONFIG_OPTIONS_H= + +# FreeType include path +CFLAGS += -Ifreetype/include + +# FreeType C source file +FT_CSRCS += freetype/src/base/ftbase.c +FT_CSRCS += freetype/src/base/ftbitmap.c +FT_CSRCS += freetype/src/base/ftdebug.c +FT_CSRCS += freetype/src/base/ftglyph.c +FT_CSRCS += freetype/src/base/ftinit.c +FT_CSRCS += freetype/src/cache/ftcache.c +FT_CSRCS += freetype/src/gzip/ftgzip.c +FT_CSRCS += freetype/src/sfnt/sfnt.c +FT_CSRCS += freetype/src/smooth/smooth.c +FT_CSRCS += freetype/src/truetype/truetype.c +CSRCS += $(FT_CSRCS) +``` ## Usage Enable `LV_USE_FREETYPE` in `lv_conf.h`. -To cache the glyphs from the opened fonts, set `LV_FREETYPE_CACHE_SIZE >= 0` and then use the following macros for detailed configuration: -1. `LV_FREETYPE_CACHE_SIZE`:maximum memory(bytes) used to cache font bitmap, outline, character maps, etc. 0 means use the system default value, less than 0 means disable cache. Note: that this value does not account for managed FT_Face and FT_Size objects. -1. `LV_FREETYPE_CACHE_FT_FACES`:maximum number of opened FT_Face objects managed by this cache instance.0 means use the system default value. Only useful when LV_FREETYPE_CACHE_SIZE >= 0. -1. `LV_FREETYPE_CACHE_FT_SIZES`:maximum number of opened FT_Size objects managed by this cache instance. 0 means use the system default value. Only useful when LV_FREETYPE_CACHE_SIZE >= 0. +Cache configuration: +- `LV_FREETYPE_CACHE_SIZE` - Maximum memory(Bytes) used to cache font bitmap, outline, character maps, etc. **Note:** This value does not include the memory used by 'FT_Face' and 'FT_Size' objects +- `LV_FREETYPE_CACHE_FT_FACES` - Maximum open number of `FT_Face` objects. +- `LV_FREETYPE_CACHE_FT_SIZES` - Maximum open number of `FT_Size` objects. When you are sure that all the used font sizes will not be greater than 256, you can enable `LV_FREETYPE_SBIT_CACHE`, which is much more memory efficient for small bitmaps. -You can use `lv_ft_font_init()` to create FreeType fonts. It returns `true` to indicate success, at the same time, the `font` member of `lv_ft_info_t` will be filled with a pointer to an LVGL font, and you can use it like any LVGL font. - -Font style supports bold and italic, you can use the following macros to set: -1. `FT_FONT_STYLE_NORMAL`:default style. -1. `FT_FONT_STYLE_ITALIC`:Italic style -1. `FT_FONT_STYLE_BOLD`:bold style - -They can be combined.eg:`FT_FONT_STYLE_BOLD | FT_FONT_STYLE_ITALIC`. - -Note that, the FreeType extension doesn't use LVGL's file system. +By default, the FreeType extension doesn't use LVGL's file system. You can simply pass the path to the font as usual on your operating system or platform. +If you want FreeType to use lvgl's memory allocation and file system interface, you can enable `LV_FREETYPE_USE_LVGL_PORT` in `lv_conf.h`, convenient for unified management. + +The font style supports *Italic* and **Bold** fonts processed by software, and can be set with reference to the following values: +- `LV_FREETYPE_FONT_STYLE_NORMAL` - Default style. +- `LV_FREETYPE_FONT_STYLE_ITALIC` - Italic style. +- `LV_FREETYPE_FONT_STYLE_BOLD` - Bold style. + +They can be combined.eg: `LV_FREETYPE_FONT_STYLE_BOLD | LV_FREETYPE_FONT_STYLE_ITALIC`. + +Use the `lv_freetype_font_create()` function to create a font. To delete a font, use `lv_freetype_font_del()`. For more detailed usage, please refer to example code. + ## Example ```eval_rst .. include:: ../../examples/libs/freetype/index.rst diff --git a/examples/libs/freetype/lv_example_freetype_1.c b/examples/libs/freetype/lv_example_freetype_1.c index 0b2b6cb27..9b13aa558 100644 --- a/examples/libs/freetype/lv_example_freetype_1.c +++ b/examples/libs/freetype/lv_example_freetype_1.c @@ -2,26 +2,31 @@ #if LV_BUILD_EXAMPLES #if LV_USE_FREETYPE +#if LV_FREETYPE_USE_LVGL_PORT + #define PATH_PREFIX "A:" +#else + #define PATH_PREFIX "./" +#endif + /** * Load a font with FreeType */ void lv_example_freetype_1(void) { /*Create a font*/ - static lv_ft_info_t info; - /*FreeType uses C standard file system, so no driver letter is required.*/ - info.name = "./lvgl/examples/libs/freetype/Lato-Regular.ttf"; - info.weight = 24; - info.style = FT_FONT_STYLE_NORMAL; - info.mem = NULL; - if(!lv_ft_font_init(&info)) { - LV_LOG_ERROR("create failed."); + lv_font_t * font = lv_freetype_font_create(PATH_PREFIX "lvgl/examples/libs/freetype/Lato-Regular.ttf", + 24, + LV_FREETYPE_FONT_STYLE_NORMAL); + + if(!font) { + LV_LOG_ERROR("freetype font create failed."); + return; } /*Create style with the new font*/ static lv_style_t style; lv_style_init(&style); - lv_style_set_text_font(&style, info.font); + lv_style_set_text_font(&style, font); lv_style_set_text_align(&style, LV_TEXT_ALIGN_CENTER); /*Create a label with the new style*/ diff --git a/examples/libs/freetype/lv_example_freetype_1.py b/examples/libs/freetype/lv_example_freetype_1.py index 84085cac5..17e0b8210 100755 --- a/examples/libs/freetype/lv_example_freetype_1.py +++ b/examples/libs/freetype/lv_example_freetype_1.py @@ -3,16 +3,12 @@ import lvgl as lv import display_driver import fs_driver -info = lv.ft_info_t() -info.name ="./Lato-Regular.ttf" -info.weight = 24 -info.style = lv.FT_FONT_STYLE.NORMAL -info.font_init() +font = lv.freetype_font_create("./Lato-Regular.ttf", 24, lv.FREETYPE_FONT_STYLE.NORMAL) # Create style with the new font style = lv.style_t() style.init() -style.set_text_font(info.font) +style.set_text_font(font) style.set_text_align(lv.TEXT_ALIGN.CENTER) # Create a label with the new style diff --git a/lv_conf_template.h b/lv_conf_template.h index bb5991505..8ad8a0729 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -636,18 +636,21 @@ /*FreeType library*/ #define LV_USE_FREETYPE 0 #if LV_USE_FREETYPE - /*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/ - #define LV_FREETYPE_CACHE_SIZE (16 * 1024) - #if LV_FREETYPE_CACHE_SIZE >= 0 - /* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */ - /* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */ - /* if font size >= 256, must be configured as image cache */ - #define LV_FREETYPE_SBIT_CACHE 0 - /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */ - /* (0:use system defaults) */ - #define LV_FREETYPE_CACHE_FT_FACES 0 - #define LV_FREETYPE_CACHE_FT_SIZES 0 - #endif + /*Memory used by FreeType to cache characters [bytes]*/ + #define LV_FREETYPE_CACHE_SIZE (64 * 1024) + + /*Let FreeType to use LVGL memory and file porting*/ + #define LV_FREETYPE_USE_LVGL_PORT 0 + + /* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */ + /* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */ + /* if font size >= 256, must be configured as image cache */ + #define LV_FREETYPE_SBIT_CACHE 0 + + /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */ + /* (0:use system defaults) */ + #define LV_FREETYPE_CACHE_FT_FACES 4 + #define LV_FREETYPE_CACHE_FT_SIZES 4 #endif /* Built-in TTF decoder */ diff --git a/src/libs/freetype/ftmodule.h b/src/libs/freetype/ftmodule.h new file mode 100644 index 000000000..b804b6e30 --- /dev/null +++ b/src/libs/freetype/ftmodule.h @@ -0,0 +1,33 @@ +/* + * This file registers the FreeType modules compiled into the library. + * + * If you use GNU make, this file IS NOT USED! Instead, it is created in + * the objects directory (normally `/objs/`) based on information + * from `/modules.cfg`. + * + * Please read `docs/INSTALL.ANY` and `docs/CUSTOMIZE` how to compile + * FreeType without GNU make. + * + */ + +/* FT_USE_MODULE( FT_Module_Class, autofit_module_class ) */ +FT_USE_MODULE(FT_Driver_ClassRec, tt_driver_class) +/* FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) */ +/* FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) */ +/* FT_USE_MODULE( FT_Module_Class, psaux_module_class ) */ +/* FT_USE_MODULE( FT_Module_Class, psnames_module_class ) */ +/* FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) */ +FT_USE_MODULE(FT_Module_Class, sfnt_module_class) +FT_USE_MODULE(FT_Renderer_Class, ft_smooth_renderer_class) +/* FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) */ +/* FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class ) */ +/* FT_USE_MODULE( FT_Renderer_Class, ft_bitmap_sdf_renderer_class ) */ +/* FT_USE_MODULE( FT_Renderer_Class, ft_svg_renderer_class ) */ + +/* EOF */ diff --git a/src/libs/freetype/ftoption.h b/src/libs/freetype/ftoption.h new file mode 100644 index 000000000..694e26e80 --- /dev/null +++ b/src/libs/freetype/ftoption.h @@ -0,0 +1,1029 @@ +/**************************************************************************** + * + * ftoption.h + * + * User-selectable configuration macros (specification only). + * + * Copyright (C) 1996-2022 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 + + +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 use the build directory + * `builds/` by default, but you can easily change that for your + * own projects. + * + * - Copy the file 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 + * #include + * ``` + * + * 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 ``. + * + * 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 ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + + +/*#************************************************************************ + * + * If you enable this configuration option, FreeType recognizes an + * environment variable called `FREETYPE_PROPERTIES`, which can be used to + * control the various font drivers and modules. The controllable + * properties are listed in the section @properties. + * + * You have to undefine this configuration option on platforms that lack + * the concept of environment variables (and thus don't have the `getenv` + * function), for example Windows CE. + * + * `FREETYPE_PROPERTIES` has the following syntax form (broken here into + * multiple lines for better readability). + * + * ``` + * + * ':' + * '=' + * + * ':' + * '=' + * ... + * ``` + * + * Example: + * + * ``` + * FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ + * cff:no-stem-darkening=1 + * ``` + * + */ +#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + + +/************************************************************************** + * + * Uncomment the line below if you want to activate LCD rendering + * technology similar to ClearType in this build of the library. This + * technology triples the resolution in the direction color subpixels. To + * mitigate color fringes inherent to this technology, you also need to + * explicitly set up LCD filtering. + * + * When this macro is not defined, FreeType offers alternative LCD + * rendering technology that produces excellent output. + */ +/* #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'. + */ +#define 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. + */ +#define 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. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + * + * If you use the GNU make build system directly (that is, without the + * `configure` script) and you define this macro, you also have to pass + * `SYSTEM_ZLIB=yes` as an argument to make. + */ +/* #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'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ +/* #define FT_CONFIG_OPTION_USE_BZIP2 */ + + +/************************************************************************** + * + * 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 */ + + +/************************************************************************** + * + * 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'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ +/* #define FT_CONFIG_OPTION_USE_PNG */ + + +/************************************************************************** + * + * 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'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ +/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */ + + +/************************************************************************** + * + * Brotli support. + * + * FreeType uses the Brotli library to provide support for decompressing + * WOFF2 streams. + * + * Define this macro if you want to enable this 'feature'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ +/* #define FT_CONFIG_OPTION_USE_BROTLI */ + + +/************************************************************************** + * + * 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, + * but will not synthesize a missing Unicode charmap. + * + * - 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. + */ +#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 */ + + +/************************************************************************** + * + * Logging + * + * Compiling FreeType in debug or trace mode makes FreeType write error + * and trace log messages to `stderr`. Enabling this macro + * automatically forces the `FT_DEBUG_LEVEL_ERROR` and + * `FT_DEBUG_LEVEL_TRACE` macros and allows FreeType to write error and + * trace log messages to a file instead of `stderr`. For writing logs + * to a file, FreeType uses an the external `dlg` library (the source + * code is in `src/dlg`). + * + * This option needs a C99 compiler. + */ +/* #define FT_DEBUG_LOGGING */ + + +/************************************************************************** + * + * 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 + * af_glyph_hints_get_num_segments + * af_glyph_hints_get_segment_offset + * ``` + * + * 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 + + +/************************************************************************** + * + * OpenType SVG Glyph Support + * + * Setting this macro enables support for OpenType SVG glyphs. By + * default, FreeType can only fetch SVG documents. However, it can also + * render them if external rendering hook functions are plugged in at + * runtime. + * + * More details on the hooks can be found in file `otsvg.h`. + */ +#define FT_CONFIG_OPTION_SVG + + +/************************************************************************** + * + * Error Strings + * + * If this macro is set, `FT_Error_String` will return meaningful + * descriptions. This is not enabled by default to reduce the overall + * size of FreeType. + * + * More details can be found in the file `fterrors.h`. + */ +#define FT_CONFIG_OPTION_ERROR_STRINGS + + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** 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_COLOR_LAYERS` if you want to support colored + * outlines (from the 'COLR'/'CPAL' tables) in all formats using the 'sfnt' + * module (namely TrueType~& OpenType). + */ +#define TT_CONFIG_OPTION_COLOR_LAYERS + + +/************************************************************************** + * + * 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 + * `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 + * subpixel hinting support into the TrueType driver. This modifies the + * TrueType hinting mechanism when anything but `FT_RENDER_MODE_MONO` is + * requested. + * + * 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. + * + * There are three possible values. + * + * Value 1: + * This value 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. + * + * The corresponding interpreter version is v38. + * + * Value 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. + * + * The corresponding interpreter version is v40. + * + * Value 3: + * Compile both, making both v38 and v40 available (the latter is the + * default). + * + * 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 (using `FT_Property_Set`). + * + * This option requires `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` to be + * defined. + * + * [1] + * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx + */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ +#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ + + +/************************************************************************** + * + * 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. + * + * https://www.microsoft.com/typography/otspec/glyf.htm + * https://developer.apple.com/fonts/TrueType-Reference-Manual/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). Tagged 'Font Variations', this is now part of OpenType + * also. 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 + + +/************************************************************************** + * + * 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 ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + + +/************************************************************************** + * + * `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' (covering the CNS 11643 character + * set) needs 256. + */ +#define T1_MAX_CHARSTRINGS_OPERANDS 256 + + +/************************************************************************** + * + * Define this configuration macro if you want to prevent the compilation + * of the 't1afm' module, which is in charge of reading Type~1 AFM files + * into an existing face. Note that if set, the Type~1 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 + + +/************************************************************************** + * + * `T1_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe Type~1 + * engine gets compiled into FreeType. If defined, it is possible to + * switch between the two engines using the `hinting-engine` property of + * the 'type1' driver module. + */ +/* #define T1_CONFIG_OPTION_OLD_ENGINE */ + + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** C F F D R I V E R C O N F I G U R A T I O N ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + + +/************************************************************************** + * + * 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 (file `ftdriver.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 */ + + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** P C F D R I V E R C O N F I G U R A T I O N ****/ +/**** ****/ +/*************************************************************************/ +/*************************************************************************/ + + +/************************************************************************** + * + * There are many PCF fonts just called 'Fixed' which look completely + * different, and which have nothing to do with each other. When selecting + * 'Fixed' in KDE or Gnome one gets results that appear rather random, the + * style changes often if one changes the size and one cannot select some + * fonts at all. This option makes the 'pcf' module prepend the foundry + * name (plus a space) to the family name. + * + * We also check whether we have 'wide' characters; all put together, we + * get family names like 'Sony Fixed' or 'Misc Fixed Wide'. + * + * If this option is activated, it can be controlled with the + * `no-long-family-names` property of the 'pcf' driver module. + */ +/* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ + + +/*************************************************************************/ +/*************************************************************************/ +/**** ****/ +/**** 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 fallback Indic script support, covering + * some scripts that the 'latin' submodule of the 'autofit' module doesn't + * (yet) handle. Currently, this needs option `AF_CONFIG_OPTION_CJK`. + */ +#ifdef AF_CONFIG_OPTION_CJK + #define AF_CONFIG_OPTION_INDIC +#endif + + +/************************************************************************** + * + * Use TrueType-like size metrics for 'light' auto-hinting. + * + * It is strongly recommended to avoid this option, which exists only to + * help some legacy applications retain its appearance and behaviour with + * respect to auto-hinted TrueType fonts. + * + * The very reason this option exists at all are GNU/Linux distributions + * like Fedora that did not un-patch the following change (which was + * present in FreeType between versions 2.4.6 and 2.7.1, inclusive). + * + * ``` + * 2011-07-16 Steven Chu + * + * [truetype] Fix metrics on size request for scalable fonts. + * ``` + * + * This problematic commit is now reverted (more or less). + */ +/* #define AF_CONFIG_OPTION_TT_SIZE_METRICS */ + +/* */ + + +/* + * This macro is obsolete. Support has been removed in FreeType version + * 2.5. + */ +/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ + + +/* + * The next three macros are defined if native TrueType hinting is + * requested by the definitions above. Don't change this. + */ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + #define TT_USE_BYTECODE_INTERPRETER + + #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + #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 +#endif + + +/* + * The TT_SUPPORT_COLRV1 macro is defined to indicate to clients that this + * version of FreeType has support for 'COLR' v1 API. This definition is + * useful to FreeType clients that want to build in support for 'COLR' v1 + * depending on a tip-of-tree checkout before it is officially released in + * FreeType, and while the feature cannot yet be tested against using + * version macros. Don't change this macro. This may be removed once the + * feature is in a FreeType release version and version macros can be used + * to test for availability. + */ +#ifdef TT_CONFIG_OPTION_COLOR_LAYERS + #define TT_SUPPORT_COLRV1 +#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_ */ + + +/* END */ diff --git a/src/libs/freetype/lv_freetype.c b/src/libs/freetype/lv_freetype.c index 284811c8d..cd4c1d528 100644 --- a/src/libs/freetype/lv_freetype.c +++ b/src/libs/freetype/lv_freetype.c @@ -20,74 +20,66 @@ /********************* * DEFINES *********************/ +#ifdef FT_CONFIG_OPTION_ERROR_STRINGS +#define FT_ERROR_MSG(msg, error_code) \ + LV_LOG_ERROR(msg " error(%d): %s", (int)error_code, FT_Error_String(error_code)) +#else +#define FT_ERROR_MSG(msg, error_code) \ + LV_LOG_ERROR(msg " error(%d)", (int)error_code) +#endif + +#if LV_FREETYPE_CACHE_SIZE <= 0 + #error "LV_FREETYPE_CACHE_SIZE must > 0" +#endif /********************** * TYPEDEFS **********************/ -typedef struct { - lv_ll_t face_ll; -} lv_faces_control_t; - -typedef struct name_refer_t { - const char * name; /* point to font name string */ - int32_t cnt; /* reference count */ -} name_refer_t; - -typedef struct { - const void * mem; - const char * name; - size_t mem_size; -#if LV_FREETYPE_CACHE_SIZE < 0 - FT_Size size; -#endif +typedef struct _lv_freetype_font_dsc_t { lv_font_t * font; - uint16_t style; - uint16_t height; -} lv_font_fmt_ft_dsc_t; + char * pathname; + uint16_t size; + uint16_t style; +} lv_freetype_font_dsc_t; + +typedef struct _lv_freetype_context_t { + FT_Library library; + FTC_Manager cache_manager; + FTC_CMapCache cmap_cache; + FT_Face current_face; +#if LV_FREETYPE_SBIT_CACHE + FTC_SBitCache sbit_cache; + FTC_SBit sbit; +#else + FTC_ImageCache image_cache; + FT_Glyph image_glyph; +#endif +} lv_freetype_context_t; /********************** * STATIC PROTOTYPES **********************/ -#if LV_FREETYPE_CACHE_SIZE >= 0 -static FT_Error font_face_requester(FTC_FaceID face_id, - FT_Library library_is, FT_Pointer req_data, FT_Face * aface); -static bool lv_ft_font_init_cache(lv_ft_info_t * info); -static void lv_ft_font_destroy_cache(lv_font_t * font); -#else -static FT_Face face_find_in_list(lv_ft_info_t * info); -static void face_add_to_list(FT_Face face); -static void face_remove_from_list(FT_Face face); -static void face_generic_finalizer(void * object); -static bool lv_ft_font_init_nocache(lv_ft_info_t * info); -static void lv_ft_font_destroy_nocache(lv_font_t * font); -#endif -static const char * name_refer_save(const char * name); -static void name_refer_del(const char * name); -static const char * name_refer_find(const char * name); +static FT_Error freetpye_face_requester(FTC_FaceID face_id, + FT_Library library, + FT_Pointer req_data, + FT_Face * aface); +static FT_Error freetype_get_bold_glyph(const lv_font_t * font, + FT_Face face, + FT_UInt glyph_index, + lv_font_glyph_dsc_t * dsc_out); +static bool freetype_get_glyph_dsc_cb(const lv_font_t * font, + lv_font_glyph_dsc_t * dsc_out, + uint32_t unicode_letter, + uint32_t unicode_letter_next); +static const uint8_t * freetype_get_glyph_bitmap_cb(const lv_font_t * font, + uint32_t unicode_letter); /********************** * STATIC VARIABLES **********************/ -static FT_Library library; -static lv_ll_t names_ll; -#if LV_FREETYPE_CACHE_SIZE >= 0 - static FTC_Manager cache_manager; - static FTC_CMapCache cmap_cache; - static FT_Face current_face = NULL; - - #if LV_FREETYPE_SBIT_CACHE - static FTC_SBitCache sbit_cache; - static FTC_SBit sbit; - #else - static FTC_ImageCache image_cache; - static FT_Glyph image_glyph; - #endif - -#else - static lv_faces_control_t face_control; -#endif +static lv_freetype_context_t ft_ctx; /********************** * MACROS @@ -97,143 +89,205 @@ static lv_ll_t names_ll; * GLOBAL FUNCTIONS **********************/ -bool lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes) +lv_res_t lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes) { - FT_Error error = FT_Init_FreeType(&library); + FT_Error error; + + error = FT_Init_FreeType(&ft_ctx.library); if(error) { - LV_LOG_ERROR("init freeType error(%d)", error); - return false; + FT_ERROR_MSG("FT_Init_FreeType", error); + return LV_RES_INV; } - _lv_ll_init(&names_ll, sizeof(name_refer_t)); - -#if LV_FREETYPE_CACHE_SIZE >= 0 - error = FTC_Manager_New(library, max_faces, max_sizes, - max_bytes, font_face_requester, NULL, &cache_manager); + error = FTC_Manager_New(ft_ctx.library, + max_faces, + max_sizes, + max_bytes, + freetpye_face_requester, + NULL, + &ft_ctx.cache_manager); if(error) { - FT_Done_FreeType(library); - LV_LOG_ERROR("Failed to open cache manager"); - return false; + FT_Done_FreeType(ft_ctx.library); + FT_ERROR_MSG("FTC_Manager_New", error); + return LV_RES_INV; } - error = FTC_CMapCache_New(cache_manager, &cmap_cache); + error = FTC_CMapCache_New(ft_ctx.cache_manager, &ft_ctx.cmap_cache); if(error) { - LV_LOG_ERROR("Failed to open Cmap Cache"); - goto Fail; + FT_ERROR_MSG("FTC_CMapCache_New", error); + goto failed; } #if LV_FREETYPE_SBIT_CACHE - error = FTC_SBitCache_New(cache_manager, &sbit_cache); + error = FTC_SBitCache_New(ft_ctx.cache_manager, &ft_ctx.sbit_cache); if(error) { - LV_LOG_ERROR("Failed to open sbit cache"); - goto Fail; + FT_ERROR_MSG("FTC_SBitCache_New", error); + goto failed; } #else - error = FTC_ImageCache_New(cache_manager, &image_cache); + error = FTC_ImageCache_New(ft_ctx.cache_manager, &ft_ctx.image_cache); if(error) { - LV_LOG_ERROR("Failed to open image cache"); - goto Fail; + FT_ERROR_MSG("FTC_ImageCache_New", error); + goto failed; } #endif - return true; -Fail: - FTC_Manager_Done(cache_manager); - FT_Done_FreeType(library); - return false; -#else - LV_UNUSED(max_faces); - LV_UNUSED(max_sizes); - LV_UNUSED(max_bytes); - _lv_ll_init(&face_control.face_ll, sizeof(FT_Face *)); - return true; -#endif/* LV_FREETYPE_CACHE_SIZE */ + return LV_RES_OK; +failed: + FTC_Manager_Done(ft_ctx.cache_manager); + FT_Done_FreeType(ft_ctx.library); + return LV_RES_INV; } -void lv_freetype_destroy(void) +void lv_freetype_uninit(void) { -#if LV_FREETYPE_CACHE_SIZE >= 0 - FTC_Manager_Done(cache_manager); -#endif - FT_Done_FreeType(library); + FTC_Manager_Done(ft_ctx.cache_manager); + FT_Done_FreeType(ft_ctx.library); } -bool lv_ft_font_init(lv_ft_info_t * info) +lv_font_t * lv_freetype_font_create(const char * pathname, uint16_t size, uint16_t style) { -#if LV_FREETYPE_CACHE_SIZE >= 0 - return lv_ft_font_init_cache(info); -#else - return lv_ft_font_init_nocache(info); -#endif + LV_ASSERT_NULL(pathname); + LV_ASSERT(size > 0); + + size_t pathname_len = lv_strlen(pathname); + if(pathname_len == 0) { + LV_LOG_ERROR("pathname is empty"); + return NULL; + } + + size_t need_size = sizeof(lv_freetype_font_dsc_t) + sizeof(lv_font_t); + lv_freetype_font_dsc_t * dsc = lv_malloc(need_size); + LV_ASSERT_MALLOC(dsc); + if(!dsc) { + LV_LOG_ERROR("malloc failed for lv_freetype_font_dsc"); + return NULL; + } + lv_memzero(dsc, need_size); + + dsc->font = (lv_font_t *)(((uint8_t *)dsc) + sizeof(lv_freetype_font_dsc_t)); + + dsc->pathname = lv_malloc(pathname_len + 1); + LV_ASSERT_MALLOC(dsc->pathname); + if(!dsc->pathname) { + LV_LOG_ERROR("malloc failed for dsc->pathname"); + lv_free(dsc); + return NULL; + } + strcpy(dsc->pathname, pathname); + + dsc->size = size; + dsc->style = style; + + /* use to get font info */ + FT_Size face_size; + struct FTC_ScalerRec_ scaler; + scaler.face_id = (FTC_FaceID)dsc; + scaler.width = size; + scaler.height = size; + scaler.pixel = 1; + FT_Error error = FTC_Manager_LookupSize(ft_ctx.cache_manager, + &scaler, + &face_size); + if(error) { + FT_ERROR_MSG("FTC_Manager_LookupSize", error); + lv_free(dsc->pathname); + lv_free(dsc); + return NULL; + } + + lv_font_t * font = dsc->font; + font->dsc = dsc; + font->get_glyph_dsc = freetype_get_glyph_dsc_cb; + font->get_glyph_bitmap = freetype_get_glyph_bitmap_cb; + font->subpx = LV_FONT_SUBPX_NONE; + font->line_height = (face_size->face->size->metrics.height >> 6); + font->base_line = -(face_size->face->size->metrics.descender >> 6); + + FT_Fixed scale = face_size->face->size->metrics.y_scale; + int8_t thickness = FT_MulFix(scale, face_size->face->underline_thickness) >> 6; + font->underline_position = FT_MulFix(scale, face_size->face->underline_position) >> 6; + font->underline_thickness = thickness < 1 ? 1 : thickness; + + return font; } -void lv_ft_font_destroy(lv_font_t * font) +void lv_freetype_font_del(lv_font_t * font) { -#if LV_FREETYPE_CACHE_SIZE >= 0 - lv_ft_font_destroy_cache(font); -#else - lv_ft_font_destroy_nocache(font); -#endif + LV_ASSERT_NULL(font); + lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)(font->dsc); + LV_ASSERT_NULL(dsc); + FTC_Manager_RemoveFaceID(ft_ctx.cache_manager, (FTC_FaceID)dsc); + lv_free(dsc->pathname); + lv_free(dsc); } /********************** * STATIC FUNCTIONS **********************/ -#if LV_FREETYPE_CACHE_SIZE >= 0 -static FT_Error font_face_requester(FTC_FaceID face_id, - FT_Library library_is, FT_Pointer req_data, FT_Face * aface) +static FT_Error freetpye_face_requester(FTC_FaceID face_id, + FT_Library library, + FT_Pointer req_data, + FT_Face * aface) { - LV_UNUSED(library_is); + LV_UNUSED(library); LV_UNUSED(req_data); - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)face_id; + lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)face_id; FT_Error error; - if(dsc->mem) { - error = FT_New_Memory_Face(library, dsc->mem, dsc->mem_size, 0, aface); - } - else { - error = FT_New_Face(library, dsc->name, 0, aface); - } + + error = FT_New_Face(ft_ctx.library, dsc->pathname, 0, aface); if(error) { - LV_LOG_ERROR("FT_New_Face error:%d\n", error); - return error; + FT_ERROR_MSG("FT_New_Face", error); } - return FT_Err_Ok; + return error; } -static bool get_bold_glyph(const lv_font_t * font, FT_Face face, - FT_UInt glyph_index, lv_font_glyph_dsc_t * dsc_out) +static FT_Error freetype_get_bold_glyph(const lv_font_t * font, + FT_Face face, + FT_UInt glyph_index, + lv_font_glyph_dsc_t * dsc_out) { - if(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT)) { - return false; + FT_Error error; + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); + if(error) { + FT_ERROR_MSG("FT_Load_Glyph", error); + return error; } - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); + lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)(font->dsc); if(face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { - if(dsc->style & FT_FONT_STYLE_BOLD) { + if(dsc->style & LV_FREETYPE_FONT_STYLE_BOLD) { int strength = 1 << 6; - FT_Outline_Embolden(&face->glyph->outline, strength); + error = FT_Outline_Embolden(&face->glyph->outline, strength); + if(error) { + FT_ERROR_MSG("FT_Outline_Embolden", error); + } } } - if(FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL)) { - return false; + error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); + if(error) { + FT_ERROR_MSG("FT_Render_Glyph", error); + return error; } dsc_out->adv_w = (face->glyph->metrics.horiAdvance >> 6); dsc_out->box_h = face->glyph->bitmap.rows; /*Height of the bitmap in [px]*/ - dsc_out->box_w = face->glyph->bitmap.width; /*Width of the bitmap in [px]*/ + dsc_out->box_w = face->glyph->bitmap.width; /*Width of the bitmap in [px]*/ dsc_out->ofs_x = face->glyph->bitmap_left; /*X offset of the bitmap in [pf]*/ dsc_out->ofs_y = face->glyph->bitmap_top - face->glyph->bitmap.rows; /*Y offset of the bitmap measured from the as line*/ - dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/ + dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/ - return true; + return FT_Err_Ok; } -static bool get_glyph_dsc_cb_cache(const lv_font_t * font, - lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) +static bool freetype_get_glyph_dsc_cb(const lv_font_t * font, + lv_font_glyph_dsc_t * dsc_out, + uint32_t unicode_letter, + uint32_t unicode_letter_next) { LV_UNUSED(unicode_letter_next); if(unicode_letter < 0x20) { @@ -246,25 +300,28 @@ static bool get_glyph_dsc_cb_cache(const lv_font_t * font, return true; } - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); + lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)(font->dsc); FTC_FaceID face_id = (FTC_FaceID)dsc; FT_Size face_size; + FT_Error error; struct FTC_ScalerRec_ scaler; scaler.face_id = face_id; - scaler.width = dsc->height; - scaler.height = dsc->height; + scaler.width = dsc->size; + scaler.height = dsc->size; scaler.pixel = 1; - if(FTC_Manager_LookupSize(cache_manager, &scaler, &face_size) != 0) { + error = FTC_Manager_LookupSize(ft_ctx.cache_manager, &scaler, &face_size); + if(error) { + FT_ERROR_MSG("FTC_Manager_LookupSize", error); return false; } FT_Face face = face_size->face; FT_UInt charmap_index = FT_Get_Charmap_Index(face->charmap); - FT_UInt glyph_index = FTC_CMapCache_Lookup(cmap_cache, face_id, charmap_index, unicode_letter); + FT_UInt glyph_index = FTC_CMapCache_Lookup(ft_ctx.cmap_cache, face_id, charmap_index, unicode_letter); dsc_out->is_placeholder = glyph_index == 0; - if(dsc->style & FT_FONT_STYLE_ITALIC) { + if(dsc->style & LV_FREETYPE_FONT_STYLE_ITALIC) { FT_Matrix italic_matrix; italic_matrix.xx = 1 << 16; italic_matrix.xy = 0x5800; @@ -273,10 +330,11 @@ static bool get_glyph_dsc_cb_cache(const lv_font_t * font, FT_Set_Transform(face, &italic_matrix, NULL); } - if(dsc->style & FT_FONT_STYLE_BOLD) { - current_face = face; - if(!get_bold_glyph(font, face, glyph_index, dsc_out)) { - current_face = NULL; + if(dsc->style & LV_FREETYPE_FONT_STYLE_BOLD) { + ft_ctx.current_face = face; + error = freetype_get_bold_glyph(font, face, glyph_index, dsc_out); + if(error) { + ft_ctx.current_face = NULL; return false; } goto end; @@ -285,16 +343,21 @@ static bool get_glyph_dsc_cb_cache(const lv_font_t * font, FTC_ImageTypeRec desc_type; desc_type.face_id = face_id; desc_type.flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL; - desc_type.height = dsc->height; - desc_type.width = dsc->height; + desc_type.height = dsc->size; + desc_type.width = dsc->size; #if LV_FREETYPE_SBIT_CACHE - FT_Error error = FTC_SBitCache_Lookup(sbit_cache, &desc_type, glyph_index, &sbit, NULL); + error = FTC_SBitCache_Lookup(ft_ctx.sbit_cache, + &desc_type, + glyph_index, + &ft_ctx.sbit, + NULL); if(error) { - LV_LOG_ERROR("SBitCache_Lookup error"); + FT_ERROR_MSG("FTC_SBitCache_Lookup", error); return false; } + FTC_SBit sbit = ft_ctx.sbit; dsc_out->adv_w = sbit->xadvance; dsc_out->box_h = sbit->height; /*Height of the bitmap in [px]*/ dsc_out->box_w = sbit->width; /*Width of the bitmap in [px]*/ @@ -302,17 +365,21 @@ static bool get_glyph_dsc_cb_cache(const lv_font_t * font, dsc_out->ofs_y = sbit->top - sbit->height; /*Y offset of the bitmap measured from the as line*/ dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/ #else - FT_Error error = FTC_ImageCache_Lookup(image_cache, &desc_type, glyph_index, &image_glyph, NULL); + error = FTC_ImageCache_Lookup(ft_ctx.image_cache, + &desc_type, + glyph_index, + &ft_ctx.image_glyph, + NULL); if(error) { - LV_LOG_ERROR("ImageCache_Lookup error"); + FT_ERROR_MSG("ImageCache_Lookup", error); return false; } - if(image_glyph->format != FT_GLYPH_FORMAT_BITMAP) { - LV_LOG_ERROR("Glyph_To_Bitmap error"); + if(ft_ctx.image_glyph->format != FT_GLYPH_FORMAT_BITMAP) { + LV_LOG_ERROR("image_glyph->format != FT_GLYPH_FORMAT_BITMAP"); return false; } - FT_BitmapGlyph glyph_bitmap = (FT_BitmapGlyph)image_glyph; + FT_BitmapGlyph glyph_bitmap = (FT_BitmapGlyph)ft_ctx.image_glyph; dsc_out->adv_w = (glyph_bitmap->root.advance.x >> 16); dsc_out->box_h = glyph_bitmap->bitmap.rows; /*Height of the bitmap in [px]*/ dsc_out->box_w = glyph_bitmap->bitmap.width; /*Width of the bitmap in [px]*/ @@ -323,365 +390,31 @@ static bool get_glyph_dsc_cb_cache(const lv_font_t * font, #endif end: - if((dsc->style & FT_FONT_STYLE_ITALIC) && (unicode_letter_next == '\0')) { + if((dsc->style & LV_FREETYPE_FONT_STYLE_ITALIC) && (unicode_letter_next == '\0')) { dsc_out->adv_w = dsc_out->box_w + dsc_out->ofs_x; } return true; } -static const uint8_t * get_glyph_bitmap_cb_cache(const lv_font_t * font, uint32_t unicode_letter) +static const uint8_t * freetype_get_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter) { LV_UNUSED(unicode_letter); - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); - if(dsc->style & FT_FONT_STYLE_BOLD) { - if(current_face && current_face->glyph->format == FT_GLYPH_FORMAT_BITMAP) { - return (const uint8_t *)(current_face->glyph->bitmap.buffer); + lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc; + if(dsc->style & LV_FREETYPE_FONT_STYLE_BOLD) { + if(ft_ctx.current_face && ft_ctx.current_face->glyph->format == FT_GLYPH_FORMAT_BITMAP) { + return (const uint8_t *)(ft_ctx.current_face->glyph->bitmap.buffer); } return NULL; } #if LV_FREETYPE_SBIT_CACHE - return (const uint8_t *)sbit->buffer; + return (const uint8_t *)ft_ctx.sbit->buffer; #else - FT_BitmapGlyph glyph_bitmap = (FT_BitmapGlyph)image_glyph; + FT_BitmapGlyph glyph_bitmap = (FT_BitmapGlyph)ft_ctx.image_glyph; return (const uint8_t *)glyph_bitmap->bitmap.buffer; #endif } -static bool lv_ft_font_init_cache(lv_ft_info_t * info) -{ - size_t need_size = sizeof(lv_font_fmt_ft_dsc_t) + sizeof(lv_font_t); - lv_font_fmt_ft_dsc_t * dsc = lv_malloc(need_size); - if(dsc == NULL) return false; - lv_memzero(dsc, need_size); - - dsc->font = (lv_font_t *)(((char *)dsc) + sizeof(lv_font_fmt_ft_dsc_t)); - dsc->mem = info->mem; - dsc->mem_size = info->mem_size; - dsc->name = name_refer_save(info->name); - dsc->height = info->weight; - dsc->style = info->style; - - /* use to get font info */ - FT_Size face_size; - struct FTC_ScalerRec_ scaler; - scaler.face_id = (FTC_FaceID)dsc; - scaler.width = info->weight; - scaler.height = info->weight; - scaler.pixel = 1; - FT_Error error = FTC_Manager_LookupSize(cache_manager, &scaler, &face_size); - if(error) { - LV_LOG_ERROR("Failed to LookupSize"); - goto Fail; - } - - lv_font_t * font = dsc->font; - font->dsc = dsc; - font->get_glyph_dsc = get_glyph_dsc_cb_cache; - font->get_glyph_bitmap = get_glyph_bitmap_cb_cache; - font->subpx = LV_FONT_SUBPX_NONE; - font->line_height = (face_size->face->size->metrics.height >> 6); - font->base_line = -(face_size->face->size->metrics.descender >> 6); - - FT_Fixed scale = face_size->face->size->metrics.y_scale; - int8_t thickness = FT_MulFix(scale, face_size->face->underline_thickness) >> 6; - font->underline_position = FT_MulFix(scale, face_size->face->underline_position) >> 6; - font->underline_thickness = thickness < 1 ? 1 : thickness; - - /* return to user */ - info->font = font; - - return true; - -Fail: - lv_free(dsc); - return false; -} - -void lv_ft_font_destroy_cache(lv_font_t * font) -{ - if(font == NULL) { - return; - } - - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); - if(dsc) { - FTC_Manager_RemoveFaceID(cache_manager, (FTC_FaceID)dsc); - name_refer_del(dsc->name); - lv_free(dsc); - } -} -#else/* LV_FREETYPE_CACHE_SIZE */ - -static FT_Face face_find_in_list(lv_ft_info_t * info) -{ - lv_font_fmt_ft_dsc_t * dsc; - FT_Face * pface = _lv_ll_get_head(&face_control.face_ll); - while(pface) { - dsc = (lv_font_fmt_ft_dsc_t *)(*pface)->generic.data; - if(strcmp(dsc->name, info->name) == 0) { - return *pface; - } - pface = _lv_ll_get_next(&face_control.face_ll, pface); - } - - return NULL; -} - -static void face_add_to_list(FT_Face face) -{ - FT_Face * pface; - pface = (FT_Face *)_lv_ll_ins_tail(&face_control.face_ll); - *pface = face; -} - -static void face_remove_from_list(FT_Face face) -{ - FT_Face * pface = _lv_ll_get_head(&face_control.face_ll); - while(pface) { - if(*pface == face) { - _lv_ll_remove(&face_control.face_ll, pface); - lv_free(pface); - break; - } - pface = _lv_ll_get_next(&face_control.face_ll, pface); - } -} - -static void face_generic_finalizer(void * object) -{ - FT_Face face = (FT_Face)object; - face_remove_from_list(face); - LV_LOG_INFO("face finalizer(%p)\n", face); -} - -static bool get_glyph_dsc_cb_nocache(const lv_font_t * font, - lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) -{ - LV_UNUSED(unicode_letter_next); - if(unicode_letter < 0x20) { - dsc_out->adv_w = 0; - dsc_out->box_h = 0; - dsc_out->box_w = 0; - dsc_out->ofs_x = 0; - dsc_out->ofs_y = 0; - dsc_out->bpp = 0; - return true; - } - - FT_Error error; - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); - FT_Face face = dsc->size->face; - - FT_UInt glyph_index = FT_Get_Char_Index(face, unicode_letter); - - if(face->size != dsc->size) { - FT_Activate_Size(dsc->size); - } - dsc_out->is_placeholder = glyph_index == 0; - - error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); - if(error) { - return false; - } - - if(face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { - if(dsc->style & FT_FONT_STYLE_BOLD) { - int strength = 1 << 6; - FT_Outline_Embolden(&face->glyph->outline, strength); - } - - if(dsc->style & FT_FONT_STYLE_ITALIC) { - FT_Matrix italic_matrix; - italic_matrix.xx = 1 << 16; - italic_matrix.xy = 0x5800; - italic_matrix.yx = 0; - italic_matrix.yy = 1 << 16; - FT_Outline_Transform(&face->glyph->outline, &italic_matrix); - } - } - - error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); - if(error) { - return false; - } - - dsc_out->adv_w = (face->glyph->metrics.horiAdvance >> 6); - dsc_out->box_h = face->glyph->bitmap.rows; /*Height of the bitmap in [px]*/ - dsc_out->box_w = face->glyph->bitmap.width; /*Width of the bitmap in [px]*/ - dsc_out->ofs_x = face->glyph->bitmap_left; /*X offset of the bitmap in [pf]*/ - dsc_out->ofs_y = face->glyph->bitmap_top - - face->glyph->bitmap.rows; /*Y offset of the bitmap measured from the as line*/ - dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/ - - if((dsc->style & FT_FONT_STYLE_ITALIC) && (unicode_letter_next == '\0')) { - dsc_out->adv_w = dsc_out->box_w + dsc_out->ofs_x; - } - - return true; -} - -static const uint8_t * get_glyph_bitmap_cb_nocache(const lv_font_t * font, uint32_t unicode_letter) -{ - LV_UNUSED(unicode_letter); - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); - FT_Face face = dsc->size->face; - return (const uint8_t *)(face->glyph->bitmap.buffer); -} - -static bool lv_ft_font_init_nocache(lv_ft_info_t * info) -{ - size_t need_size = sizeof(lv_font_fmt_ft_dsc_t) + sizeof(lv_font_t); - lv_font_fmt_ft_dsc_t * dsc = lv_malloc(need_size); - if(dsc == NULL) return false; - lv_memzero(dsc, need_size); - - dsc->font = (lv_font_t *)(((char *)dsc) + sizeof(lv_font_fmt_ft_dsc_t)); - dsc->mem = info->mem; - dsc->mem_size = info->mem_size; - dsc->name = name_refer_save(info->name); - dsc->height = info->weight; - dsc->style = info->style; - - FT_Face face = face_find_in_list(info); - if(face == NULL) { - FT_Error error; - if(dsc->mem) { - error = FT_New_Memory_Face(library, dsc->mem, (FT_Long) dsc->mem_size, 0, &face); - } - else { - error = FT_New_Face(library, dsc->name, 0, &face); - } - if(error) { - LV_LOG_WARN("create face error(%d)", error); - goto Fail; - } - - /* link face and face info */ - face->generic.data = dsc; - face->generic.finalizer = face_generic_finalizer; - face_add_to_list(face); - } - else { - FT_Size size; - FT_Error error = FT_New_Size(face, &size); - if(error) { - goto Fail; - } - FT_Activate_Size(size); - FT_Reference_Face(face); - } - - FT_Set_Pixel_Sizes(face, 0, info->weight); - dsc->size = face->size; - - lv_font_t * font = dsc->font; - font->dsc = dsc; - font->get_glyph_dsc = get_glyph_dsc_cb_nocache; - font->get_glyph_bitmap = get_glyph_bitmap_cb_nocache; - font->line_height = (face->size->metrics.height >> 6); - font->base_line = -(face->size->metrics.descender >> 6); - font->subpx = LV_FONT_SUBPX_NONE; - - FT_Fixed scale = face->size->metrics.y_scale; - int8_t thickness = FT_MulFix(scale, face->underline_thickness) >> 6; - font->underline_position = FT_MulFix(scale, face->underline_position) >> 6; - font->underline_thickness = thickness < 1 ? 1 : thickness; - - info->font = font; - return true; - -Fail: - lv_free(dsc); - return false; -} - -static void lv_ft_font_destroy_nocache(lv_font_t * font) -{ - if(font == NULL) { - return; - } - - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); - if(dsc) { - FT_Face face = dsc->size->face; - FT_Done_Size(dsc->size); - FT_Done_Face(face); - name_refer_del(dsc->name); - lv_free(dsc); - } -} - -#endif/* LV_FREETYPE_CACHE_SIZE */ - -/** - * find name string in names list.name string cnt += 1 if find. - * @param name name string - * @return the string pointer of name. - */ -static const char * name_refer_find(const char * name) -{ - name_refer_t * refer = _lv_ll_get_head(&names_ll); - while(refer) { - if(strcmp(refer->name, name) == 0) { - refer->cnt += 1; - return refer->name; - } - refer = _lv_ll_get_next(&names_ll, refer); - } - return NULL; -} - -/** - * del name string from list. - */ -static void name_refer_del(const char * name) -{ - name_refer_t * refer = _lv_ll_get_head(&names_ll); - while(refer) { - if(strcmp(refer->name, name) == 0) { - refer->cnt -= 1; - if(refer->cnt <= 0) { - _lv_ll_remove(&names_ll, refer); - lv_free((void *)refer->name); - lv_free(refer); - } - return; - } - refer = _lv_ll_get_next(&names_ll, refer); - } - - LV_LOG_WARN("name_in_names_del error(not find:%p).", name); -} - -/** - * save name string to list. - * @param name name string - * @return Saved string pointer - */ -static const char * name_refer_save(const char * name) -{ - const char * pos = name_refer_find(name); - if(pos) { - return pos; - } - - name_refer_t * refer = _lv_ll_ins_tail(&names_ll); - if(refer) { - uint32_t len = strlen(name) + 1; - refer->name = lv_malloc(len); - if(refer->name) { - lv_memcpy((void *)refer->name, name, len); - refer->cnt = 1; - return refer->name; - } - _lv_ll_remove(&names_ll, refer); - lv_free(refer); - } - LV_LOG_WARN("save_name_to_names error(not memory)."); - return ""; -} - #endif /*LV_USE_FREETYPE*/ diff --git a/src/libs/freetype/lv_freetype.h b/src/libs/freetype/lv_freetype.h index 247a7fb7f..2f3058985 100644 --- a/src/libs/freetype/lv_freetype.h +++ b/src/libs/freetype/lv_freetype.h @@ -22,53 +22,46 @@ extern "C" { /********************** * TYPEDEFS **********************/ -typedef enum { - FT_FONT_STYLE_NORMAL = 0, - FT_FONT_STYLE_ITALIC = 1 << 0, - FT_FONT_STYLE_BOLD = 1 << 1 -} LV_FT_FONT_STYLE; -typedef struct { - const char * name; /* The name of the font file */ - const void * mem; /* The pointer of the font file */ - size_t mem_size; /* The size of the memory */ - lv_font_t * font; /* point to lvgl font */ - uint16_t weight; /* font size */ - uint16_t style; /* font style */ -} lv_ft_info_t; +typedef enum { + LV_FREETYPE_FONT_STYLE_NORMAL = 0, + LV_FREETYPE_FONT_STYLE_ITALIC = 1 << 0, + LV_FREETYPE_FONT_STYLE_BOLD = 1 << 1 +} lv_freetype_font_style_t; /********************** * GLOBAL PROTOTYPES **********************/ /** - * init freetype library + * Initialize the freetype library. * @param max_faces Maximum number of opened FT_Face objects managed by this cache instance. Use 0 for defaults. * @param max_sizes Maximum number of opened FT_Size objects managed by this cache instance. Use 0 for defaults. * @param max_bytes Maximum number of bytes to use for cached data nodes. Use 0 for defaults. * Note that this value does not account for managed FT_Face and FT_Size objects. - * @return true on success, otherwise false. + * @return LV_RES_OK on success, otherwise LV_RES_INV. */ -bool lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes); +lv_res_t lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes); /** - * Destroy freetype library + * Uninitialize the freetype library */ -void lv_freetype_destroy(void); +void lv_freetype_uninit(void); /** - * Creates a font with info parameter specified. - * @param info See lv_ft_info_t for details. - * when success, lv_ft_info_t->font point to the font you created. - * @return true on success, otherwise false. + * Create a freetype font. + * @param pathname font file path. + * @param size font size. + * @param style font style(see lv_freetype_font_style_t for details). + * @return Created font, or NULL on failure. */ -bool lv_ft_font_init(lv_ft_info_t * info); +lv_font_t * lv_freetype_font_create(const char * pathname, uint16_t size, uint16_t style); /** - * Destroy a font that has been created. - * @param font pointer to font. + * Delete a freetype font. + * @param font freetype font to be deleted. */ -void lv_ft_font_destroy(lv_font_t * font); +void lv_freetype_font_del(lv_font_t * font); /********************** * MACROS diff --git a/src/libs/freetype/lv_ftsystem.c b/src/libs/freetype/lv_ftsystem.c new file mode 100644 index 000000000..18248ae74 --- /dev/null +++ b/src/libs/freetype/lv_ftsystem.c @@ -0,0 +1,292 @@ +/** + * @file lv_ftsystem.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../../lvgl.h" +#if LV_USE_FREETYPE && LV_FREETYPE_USE_LVGL_PORT + +#include +#include FT_CONFIG_CONFIG_H +#include +#include +#include +#include +#include + +/********************* + * DEFINES + *********************/ + +/* 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 io + +/* We use the macro STREAM_FILE for convenience to extract the */ +/* system-specific stream handle from a given FreeType stream object */ +#define STREAM_FILE( stream ) ( (lv_fs_file_t*)stream->descriptor.pointer ) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +FT_CALLBACK_DEF(unsigned long) +ft_lv_fs_stream_io(FT_Stream stream, + unsigned long offset, + unsigned char * buffer, + unsigned long count); +FT_CALLBACK_DEF(void) +ft_lv_fs_stream_close(FT_Stream stream); +FT_CALLBACK_DEF(void *) +ft_alloc(FT_Memory memory, + long size); +FT_CALLBACK_DEF(void *) +ft_realloc(FT_Memory memory, + long cur_size, + long new_size, + void * block); +FT_CALLBACK_DEF(void) +ft_free(FT_Memory memory, + void * block); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef FT_DEBUG_MEMORY + + extern FT_Int + ft_mem_debug_init(FT_Memory memory); + + extern void + ft_mem_debug_done(FT_Memory memory); + +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT + +/* documentation is in ftstream.h */ + +FT_BASE_DEF(FT_Error) +FT_Stream_Open(FT_Stream stream, + const char * filepathname) +{ + lv_fs_file_t file; + + if(!stream) + return FT_THROW(Invalid_Stream_Handle); + + stream->descriptor.pointer = NULL; + stream->pathname.pointer = (char *)filepathname; + stream->base = NULL; + stream->pos = 0; + stream->read = NULL; + stream->close = NULL; + + lv_fs_res_t res = lv_fs_open(&file, filepathname, LV_FS_MODE_RD); + + if(res != LV_FS_RES_OK) { + FT_ERROR(("FT_Stream_Open:" + " could not open `%s'\n", filepathname)); + + return FT_THROW(Cannot_Open_Resource); + } + + lv_fs_seek(&file, 0, LV_FS_SEEK_END); + + uint32_t pos; + res = lv_fs_tell(&file, &pos); + if(res != LV_FS_RES_OK) { + FT_ERROR(("FT_Stream_Open:")); + FT_ERROR((" opened `%s' but zero-sized\n", filepathname)); + lv_fs_close(&file); + return FT_THROW(Cannot_Open_Stream); + } + stream->size = pos; + lv_fs_seek(&file, 0, LV_FS_SEEK_SET); + + lv_fs_file_t * file_p = lv_malloc(sizeof(lv_fs_file_t)); + LV_ASSERT_MALLOC(file_p); + + if(!file_p) { + FT_ERROR(("FT_Stream_Open: malloc failed for file_p")); + lv_fs_close(&file); + return FT_THROW(Cannot_Open_Stream); + } + + *file_p = file; + + stream->descriptor.pointer = file_p; + stream->read = ft_lv_fs_stream_io; + stream->close = ft_lv_fs_stream_close; + + FT_TRACE1(("FT_Stream_Open:")); + FT_TRACE1((" opened `%s' (%ld bytes) successfully\n", + filepathname, stream->size)); + + return FT_Err_Ok; +} + +#endif /* !FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ + +/* documentation is in ftobjs.h */ + +FT_BASE_DEF(FT_Memory) +FT_New_Memory(void) +{ + FT_Memory memory; + + + memory = (FT_Memory)lv_malloc(sizeof(*memory)); + if(memory) { + memory->user = NULL; + memory->alloc = ft_alloc; + memory->realloc = ft_realloc; + memory->free = ft_free; +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_init(memory); +#endif + } + + return memory; +} + +/* documentation is in ftobjs.h */ + +FT_BASE_DEF(void) +FT_Done_Memory(FT_Memory memory) +{ +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_done(memory); +#endif + lv_free(memory); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * The memory allocation function. + * @param memory A pointer to the memory object. + * @param size The requested size in bytes. + * @return The address of newly allocated block. + */ +FT_CALLBACK_DEF(void *) +ft_alloc(FT_Memory memory, + long size) +{ + FT_UNUSED(memory); + + return lv_malloc((size_t)size); +} + +/** + * The memory reallocation function. + * @param memory A pointer to the memory object. + * @param cur_size The current size of the allocated memory block. + * @param new_size The newly requested size in bytes. + * @param block The current address of the block in memory. + * @return The address of the reallocated memory block. + */ +FT_CALLBACK_DEF(void *) +ft_realloc(FT_Memory memory, + long cur_size, + long new_size, + void * block) +{ + FT_UNUSED(memory); + FT_UNUSED(cur_size); + + return lv_realloc(block, (size_t)new_size); +} + +/** + * The memory release function. + * @param memory A pointer to the memory object. + * @param block The address of block in memory to be freed. + */ +FT_CALLBACK_DEF(void) +ft_free(FT_Memory memory, + void * block) +{ + FT_UNUSED(memory); + + lv_free(block); +} + +#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT + +/** + * The function to close a stream. + * @param stream A pointer to the stream object. + */ +FT_CALLBACK_DEF(void) +ft_lv_fs_stream_close(FT_Stream stream) +{ + lv_fs_file_t * file_p = STREAM_FILE(stream); + lv_fs_close(file_p); + lv_free(file_p); + + stream->descriptor.pointer = NULL; + stream->size = 0; + stream->base = NULL; +} + +/** + * The function to open a stream. + * @param stream A pointer to the stream object. + * @param offset The position in the data stream to start reading. + * @param buffer The address of buffer to store the read data. + * @param count The number of bytes to read from the stream. + * @return The number of bytes actually read. If `count' is zero (this is, + * the function is used for seeking), a non-zero return value + * indicates an error. + */ +FT_CALLBACK_DEF(unsigned long) +ft_lv_fs_stream_io(FT_Stream stream, + unsigned long offset, + unsigned char * buffer, + unsigned long count) +{ + lv_fs_file_t * file_p; + + if(!count && offset > stream->size) + return 1; + + file_p = STREAM_FILE(stream); + + if(stream->pos != offset) + lv_fs_seek(file_p, (long)offset, LV_FS_SEEK_SET); + + if(count == 0) + return 0; + + uint32_t br; + lv_fs_res_t res = lv_fs_read(file_p, buffer, count, &br); + + return res == LV_FS_RES_OK ? br : 0; +} + +#endif /* !FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ + +#endif/*LV_FREETYPE_USE_LV_FTSYSTEM*/ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 3284e31d5..df23f325a 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -2162,40 +2162,49 @@ #endif #endif #if LV_USE_FREETYPE - /*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/ + /*Memory used by FreeType to cache characters [bytes]*/ #ifndef LV_FREETYPE_CACHE_SIZE #ifdef CONFIG_LV_FREETYPE_CACHE_SIZE #define LV_FREETYPE_CACHE_SIZE CONFIG_LV_FREETYPE_CACHE_SIZE #else - #define LV_FREETYPE_CACHE_SIZE (16 * 1024) + #define LV_FREETYPE_CACHE_SIZE (64 * 1024) #endif #endif - #if LV_FREETYPE_CACHE_SIZE >= 0 - /* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */ - /* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */ - /* if font size >= 256, must be configured as image cache */ - #ifndef LV_FREETYPE_SBIT_CACHE - #ifdef CONFIG_LV_FREETYPE_SBIT_CACHE - #define LV_FREETYPE_SBIT_CACHE CONFIG_LV_FREETYPE_SBIT_CACHE - #else - #define LV_FREETYPE_SBIT_CACHE 0 - #endif + + /*Let FreeType to use LVGL memory and file porting*/ + #ifndef LV_FREETYPE_USE_LVGL_PORT + #ifdef CONFIG_LV_FREETYPE_USE_LVGL_PORT + #define LV_FREETYPE_USE_LVGL_PORT CONFIG_LV_FREETYPE_USE_LVGL_PORT + #else + #define LV_FREETYPE_USE_LVGL_PORT 0 #endif - /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */ - /* (0:use system defaults) */ - #ifndef LV_FREETYPE_CACHE_FT_FACES - #ifdef CONFIG_LV_FREETYPE_CACHE_FT_FACES - #define LV_FREETYPE_CACHE_FT_FACES CONFIG_LV_FREETYPE_CACHE_FT_FACES - #else - #define LV_FREETYPE_CACHE_FT_FACES 0 - #endif + #endif + + /* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */ + /* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */ + /* if font size >= 256, must be configured as image cache */ + #ifndef LV_FREETYPE_SBIT_CACHE + #ifdef CONFIG_LV_FREETYPE_SBIT_CACHE + #define LV_FREETYPE_SBIT_CACHE CONFIG_LV_FREETYPE_SBIT_CACHE + #else + #define LV_FREETYPE_SBIT_CACHE 0 #endif - #ifndef LV_FREETYPE_CACHE_FT_SIZES - #ifdef CONFIG_LV_FREETYPE_CACHE_FT_SIZES - #define LV_FREETYPE_CACHE_FT_SIZES CONFIG_LV_FREETYPE_CACHE_FT_SIZES - #else - #define LV_FREETYPE_CACHE_FT_SIZES 0 - #endif + #endif + + /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */ + /* (0:use system defaults) */ + #ifndef LV_FREETYPE_CACHE_FT_FACES + #ifdef CONFIG_LV_FREETYPE_CACHE_FT_FACES + #define LV_FREETYPE_CACHE_FT_FACES CONFIG_LV_FREETYPE_CACHE_FT_FACES + #else + #define LV_FREETYPE_CACHE_FT_FACES 4 + #endif + #endif + #ifndef LV_FREETYPE_CACHE_FT_SIZES + #ifdef CONFIG_LV_FREETYPE_CACHE_FT_SIZES + #define LV_FREETYPE_CACHE_FT_SIZES CONFIG_LV_FREETYPE_CACHE_FT_SIZES + #else + #define LV_FREETYPE_CACHE_FT_SIZES 4 #endif #endif #endif