initial commit, 4.5 stable
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
This commit is contained in:
779
thirdparty/freetype/src/autofit/afblue.c
vendored
Normal file
779
thirdparty/freetype/src/autofit/afblue.c
vendored
Normal file
@@ -0,0 +1,779 @@
|
||||
/* 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 (C) 2013-2024 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[] =
|
||||
{
|
||||
/* */
|
||||
'\xF0', '\x9E', '\xA4', '\x8C', ' ', '\xF0', '\x9E', '\xA4', '\x85', ' ', '\xF0', '\x9E', '\xA4', '\x88', ' ', '\xF0', '\x9E', '\xA4', '\x8F', ' ', '\xF0', '\x9E', '\xA4', '\x94', ' ', '\xF0', '\x9E', '\xA4', '\x9A', /* 𞤌 𞤅 𞤈 𞤏 𞤔 𞤚 */
|
||||
'\0',
|
||||
'\xF0', '\x9E', '\xA4', '\x82', ' ', '\xF0', '\x9E', '\xA4', '\x96', /* 𞤂 𞤖 */
|
||||
'\0',
|
||||
'\xF0', '\x9E', '\xA4', '\xAC', ' ', '\xF0', '\x9E', '\xA4', '\xAE', ' ', '\xF0', '\x9E', '\xA4', '\xBB', ' ', '\xF0', '\x9E', '\xA4', '\xBC', ' ', '\xF0', '\x9E', '\xA4', '\xBE', /* 𞤬 𞤮 𞤻 𞤼 𞤾 */
|
||||
'\0',
|
||||
'\xF0', '\x9E', '\xA4', '\xA4', ' ', '\xF0', '\x9E', '\xA4', '\xA8', ' ', '\xF0', '\x9E', '\xA4', '\xA9', ' ', '\xF0', '\x9E', '\xA4', '\xAD', ' ', '\xF0', '\x9E', '\xA4', '\xB4', ' ', '\xF0', '\x9E', '\xA4', '\xB8', ' ', '\xF0', '\x9E', '\xA4', '\xBA', ' ', '\xF0', '\x9E', '\xA5', '\x80', /* 𞤤 𞤨 𞤩 𞤭 𞤴 𞤸 𞤺 𞥀 */
|
||||
'\0',
|
||||
'\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', '\x8D', ' ', '\xD4', '\xB2', ' ', '\xD4', '\xB3', ' ', '\xD4', '\xB4', ' ', '\xD5', '\x95', /* Ա Մ Ւ Ս Բ Գ Դ Օ */
|
||||
'\0',
|
||||
'\xD5', '\x92', ' ', '\xD5', '\x88', ' ', '\xD4', '\xB4', ' ', '\xD5', '\x83', ' ', '\xD5', '\x87', ' ', '\xD5', '\x8D', ' ', '\xD5', '\x8F', ' ', '\xD5', '\x95', /* Ւ Ո Դ Ճ Շ Ս Տ Օ */
|
||||
'\0',
|
||||
'\xD5', '\xA5', ' ', '\xD5', '\xA7', ' ', '\xD5', '\xAB', ' ', '\xD5', '\xB4', ' ', '\xD5', '\xBE', ' ', '\xD6', '\x86', ' ', '\xD5', '\xB3', /* ե է ի մ վ ֆ ճ */
|
||||
'\0',
|
||||
'\xD5', '\xA1', ' ', '\xD5', '\xB5', ' ', '\xD6', '\x82', ' ', '\xD5', '\xBD', ' ', '\xD5', '\xA3', ' ', '\xD5', '\xB7', ' ', '\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',
|
||||
'\xF0', '\x90', '\xAC', '\x80', ' ', '\xF0', '\x90', '\xAC', '\x81', ' ', '\xF0', '\x90', '\xAC', '\x90', ' ', '\xF0', '\x90', '\xAC', '\x9B', /* 𐬀 𐬁 𐬐 𐬛 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\xAC', '\x80', ' ', '\xF0', '\x90', '\xAC', '\x81', /* 𐬀 𐬁 */
|
||||
'\0',
|
||||
'\xEA', '\x9A', '\xA7', ' ', '\xEA', '\x9A', '\xA8', ' ', '\xEA', '\x9B', '\x9B', ' ', '\xEA', '\x9B', '\x89', ' ', '\xEA', '\x9B', '\x81', ' ', '\xEA', '\x9B', '\x88', ' ', '\xEA', '\x9B', '\xAB', ' ', '\xEA', '\x9B', '\xAF', /* ꚧ ꚨ ꛛ ꛉ ꛁ ꛈ ꛫ ꛯ */
|
||||
'\0',
|
||||
'\xEA', '\x9A', '\xAD', ' ', '\xEA', '\x9A', '\xB3', ' ', '\xEA', '\x9A', '\xB6', ' ', '\xEA', '\x9B', '\xAC', ' ', '\xEA', '\x9A', '\xA2', ' ', '\xEA', '\x9A', '\xBD', ' ', '\xEA', '\x9B', '\xAF', ' ', '\xEA', '\x9B', '\xB2', /* ꚭ ꚳ ꚶ ꛬ ꚢ ꚽ ꛯ ꛲ */
|
||||
'\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', '\x9D', '\x90', ' ', '\xE1', '\x9D', '\x88', /* ᝐ ᝈ */
|
||||
'\0',
|
||||
'\xE1', '\x9D', '\x85', ' ', '\xE1', '\x9D', '\x8A', ' ', '\xE1', '\x9D', '\x8E', /* ᝅ ᝊ ᝎ */
|
||||
'\0',
|
||||
'\xE1', '\x9D', '\x82', ' ', '\xE1', '\x9D', '\x83', ' ', '\xE1', '\x9D', '\x89', ' ', '\xE1', '\x9D', '\x8C', /* ᝂ ᝃ ᝉ ᝌ */
|
||||
'\0',
|
||||
'\xE1', '\x9D', '\x80', ' ', '\xE1', '\x9D', '\x83', ' ', '\xE1', '\x9D', '\x86', ' ', '\xE1', '\x9D', '\x89', ' ', '\xE1', '\x9D', '\x8B', ' ', '\xE1', '\x9D', '\x8F', ' ', '\xE1', '\x9D', '\x91', /* ᝀ ᝃ ᝆ ᝉ ᝋ ᝏ ᝑ */
|
||||
'\0',
|
||||
'\xE1', '\x97', '\x9C', ' ', '\xE1', '\x96', '\xB4', ' ', '\xE1', '\x90', '\x81', ' ', '\xE1', '\x92', '\xA3', ' ', '\xE1', '\x91', '\xAB', ' ', '\xE1', '\x91', '\x8E', ' ', '\xE1', '\x94', '\x91', ' ', '\xE1', '\x97', '\xB0', /* ᗜ ᖴ ᐁ ᒣ ᑫ ᑎ ᔑ ᗰ */
|
||||
'\0',
|
||||
'\xE1', '\x97', '\xB6', ' ', '\xE1', '\x96', '\xB5', ' ', '\xE1', '\x92', '\xA7', ' ', '\xE1', '\x90', '\x83', ' ', '\xE1', '\x91', '\x8C', ' ', '\xE1', '\x92', '\x8D', ' ', '\xE1', '\x94', '\x91', ' ', '\xE1', '\x97', '\xA2', /* ᗶ ᖵ ᒧ ᐃ ᑌ ᒍ ᔑ ᗢ */
|
||||
'\0',
|
||||
'\xE1', '\x93', '\x93', ' ', '\xE1', '\x93', '\x95', ' ', '\xE1', '\x93', '\x80', ' ', '\xE1', '\x93', '\x82', ' ', '\xE1', '\x93', '\x84', ' ', '\xE1', '\x95', '\x84', ' ', '\xE1', '\x95', '\x86', ' ', '\xE1', '\x98', '\xA3', /* ᓓ ᓕ ᓀ ᓂ ᓄ ᕄ ᕆ ᘣ */
|
||||
'\0',
|
||||
'\xE1', '\x95', '\x83', ' ', '\xE1', '\x93', '\x82', ' ', '\xE1', '\x93', '\x80', ' ', '\xE1', '\x95', '\x82', ' ', '\xE1', '\x93', '\x97', ' ', '\xE1', '\x93', '\x9A', ' ', '\xE1', '\x95', '\x86', ' ', '\xE1', '\x98', '\xA3', /* ᕃ ᓂ ᓀ ᕂ ᓗ ᓚ ᕆ ᘣ */
|
||||
'\0',
|
||||
'\xE1', '\x90', '\xAA', ' ', '\xE1', '\x99', '\x86', ' ', '\xE1', '\xA3', '\x98', ' ', '\xE1', '\x90', '\xA2', ' ', '\xE1', '\x92', '\xBE', ' ', '\xE1', '\xA3', '\x97', ' ', '\xE1', '\x94', '\x86', /* ᐪ ᙆ ᣘ ᐢ ᒾ ᣗ ᔆ */
|
||||
'\0',
|
||||
'\xE1', '\x99', '\x86', ' ', '\xE1', '\x97', '\xAE', ' ', '\xE1', '\x92', '\xBB', ' ', '\xE1', '\x90', '\x9E', ' ', '\xE1', '\x94', '\x86', ' ', '\xE1', '\x92', '\xA1', ' ', '\xE1', '\x92', '\xA2', ' ', '\xE1', '\x93', '\x91', /* ᙆ ᗮ ᒻ ᐞ ᔆ ᒡ ᒢ ᓑ */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x8A', '\xA7', ' ', '\xF0', '\x90', '\x8A', '\xAB', ' ', '\xF0', '\x90', '\x8A', '\xAC', ' ', '\xF0', '\x90', '\x8A', '\xAD', ' ', '\xF0', '\x90', '\x8A', '\xB1', ' ', '\xF0', '\x90', '\x8A', '\xBA', ' ', '\xF0', '\x90', '\x8A', '\xBC', ' ', '\xF0', '\x90', '\x8A', '\xBF', /* 𐊧 𐊫 𐊬 𐊭 𐊱 𐊺 𐊼 𐊿 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x8A', '\xA3', ' ', '\xF0', '\x90', '\x8A', '\xA7', ' ', '\xF0', '\x90', '\x8A', '\xB7', ' ', '\xF0', '\x90', '\x8B', '\x80', ' ', '\xF0', '\x90', '\x8A', '\xAB', ' ', '\xF0', '\x90', '\x8A', '\xB8', ' ', '\xF0', '\x90', '\x8B', '\x89', /* 𐊣 𐊧 𐊷 𐋀 𐊫 𐊸 𐋉 */
|
||||
'\0',
|
||||
'\xF0', '\x91', '\x84', '\x83', ' ', '\xF0', '\x91', '\x84', '\x85', ' ', '\xF0', '\x91', '\x84', '\x89', ' ', '\xF0', '\x91', '\x84', '\x99', ' ', '\xF0', '\x91', '\x84', '\x97', /* 𑄃 𑄅 𑄉 𑄙 𑄗 */
|
||||
'\0',
|
||||
'\xF0', '\x91', '\x84', '\x85', ' ', '\xF0', '\x91', '\x84', '\x9B', ' ', '\xF0', '\x91', '\x84', '\x9D', ' ', '\xF0', '\x91', '\x84', '\x97', ' ', '\xF0', '\x91', '\x84', '\x93', /* 𑄅 𑄛 𑄝 𑄗 𑄓 */
|
||||
'\0',
|
||||
'\xF0', '\x91', '\x84', '\x96', '\xF0', '\x91', '\x84', '\xB3', '\xF0', '\x91', '\x84', '\xA2', ' ', '\xF0', '\x91', '\x84', '\x98', '\xF0', '\x91', '\x84', '\xB3', '\xF0', '\x91', '\x84', '\xA2', ' ', '\xF0', '\x91', '\x84', '\x99', '\xF0', '\x91', '\x84', '\xB3', '\xF0', '\x91', '\x84', '\xA2', ' ', '\xF0', '\x91', '\x84', '\xA4', '\xF0', '\x91', '\x84', '\xB3', '\xF0', '\x91', '\x84', '\xA2', ' ', '\xF0', '\x91', '\x84', '\xA5', '\xF0', '\x91', '\x84', '\xB3', '\xF0', '\x91', '\x84', '\xA2', /* 𑄖𑄳𑄢 𑄘𑄳𑄢 𑄙𑄳𑄢 𑄤𑄳𑄢 𑄥𑄳𑄢 */
|
||||
'\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',
|
||||
'\xE2', '\xB2', '\x8C', ' ', '\xE2', '\xB2', '\x8E', ' ', '\xE2', '\xB2', '\xA0', ' ', '\xE2', '\xB3', '\x9E', ' ', '\xE2', '\xB2', '\x9E', ' ', '\xE2', '\xB2', '\x90', ' ', '\xE2', '\xB2', '\xA4', ' ', '\xE2', '\xB3', '\x8A', /* Ⲍ Ⲏ Ⲡ Ⳟ Ⲟ Ⲑ Ⲥ Ⳋ */
|
||||
'\0',
|
||||
'\xE2', '\xB3', '\x90', ' ', '\xE2', '\xB3', '\x98', ' ', '\xE2', '\xB3', '\x9E', ' ', '\xE2', '\xB2', '\x8E', ' ', '\xE2', '\xB2', '\x9E', ' ', '\xE2', '\xB2', '\x90', ' ', '\xE2', '\xB3', '\x9C', ' ', '\xE2', '\xB2', '\xB0', /* Ⳑ Ⳙ Ⳟ Ⲏ Ⲟ Ⲑ Ⳝ Ⲱ */
|
||||
'\0',
|
||||
'\xE2', '\xB2', '\x8D', ' ', '\xE2', '\xB2', '\x8F', ' ', '\xE2', '\xB2', '\xA1', ' ', '\xE2', '\xB3', '\x9F', ' ', '\xE2', '\xB2', '\x9F', ' ', '\xE2', '\xB2', '\x91', ' ', '\xE2', '\xB2', '\xA5', ' ', '\xE2', '\xB3', '\x8B', /* ⲍ ⲏ ⲡ ⳟ ⲟ ⲑ ⲥ ⳋ */
|
||||
'\0',
|
||||
'\xE2', '\xB3', '\x91', ' ', '\xE2', '\xB3', '\x99', ' ', '\xE2', '\xB3', '\x9F', ' ', '\xE2', '\xB2', '\x8F', ' ', '\xE2', '\xB2', '\x9F', ' ', '\xE2', '\xB2', '\x91', ' ', '\xE2', '\xB3', '\x9D', ' ', '\xE2', '\xB3', '\x92', /* ⳑ ⳙ ⳟ ⲏ ⲟ ⲑ ⳝ Ⳓ */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\xA0', '\x8D', ' ', '\xF0', '\x90', '\xA0', '\x99', ' ', '\xF0', '\x90', '\xA0', '\xB3', ' ', '\xF0', '\x90', '\xA0', '\xB1', ' ', '\xF0', '\x90', '\xA0', '\x85', ' ', '\xF0', '\x90', '\xA0', '\x93', ' ', '\xF0', '\x90', '\xA0', '\xA3', ' ', '\xF0', '\x90', '\xA0', '\xA6', /* 𐠍 𐠙 𐠳 𐠱 𐠅 𐠓 𐠣 𐠦 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\xA0', '\x83', ' ', '\xF0', '\x90', '\xA0', '\x8A', ' ', '\xF0', '\x90', '\xA0', '\x9B', ' ', '\xF0', '\x90', '\xA0', '\xA3', ' ', '\xF0', '\x90', '\xA0', '\xB3', ' ', '\xF0', '\x90', '\xA0', '\xB5', ' ', '\xF0', '\x90', '\xA0', '\x90', /* 𐠃 𐠊 𐠛 𐠣 𐠳 𐠵 𐠐 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\xA0', '\x88', ' ', '\xF0', '\x90', '\xA0', '\x8F', ' ', '\xF0', '\x90', '\xA0', '\x96', /* 𐠈 𐠏 𐠖 */
|
||||
'\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',
|
||||
'\xF0', '\x90', '\x90', '\x82', ' ', '\xF0', '\x90', '\x90', '\x84', ' ', '\xF0', '\x90', '\x90', '\x8B', ' ', '\xF0', '\x90', '\x90', '\x97', ' ', '\xF0', '\x90', '\x90', '\x91', /* 𐐂 𐐄 𐐋 𐐗 𐐑 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x90', '\x80', ' ', '\xF0', '\x90', '\x90', '\x82', ' ', '\xF0', '\x90', '\x90', '\x84', ' ', '\xF0', '\x90', '\x90', '\x97', ' ', '\xF0', '\x90', '\x90', '\x9B', /* 𐐀 𐐂 𐐄 𐐗 𐐛 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x90', '\xAA', ' ', '\xF0', '\x90', '\x90', '\xAC', ' ', '\xF0', '\x90', '\x90', '\xB3', ' ', '\xF0', '\x90', '\x90', '\xBF', ' ', '\xF0', '\x90', '\x90', '\xB9', /* 𐐪 𐐬 𐐳 𐐿 𐐹 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x90', '\xA8', ' ', '\xF0', '\x90', '\x90', '\xAA', ' ', '\xF0', '\x90', '\x90', '\xAC', ' ', '\xF0', '\x90', '\x90', '\xBF', ' ', '\xF0', '\x90', '\x91', '\x83', /* 𐐨 𐐪 𐐬 𐐿 𐑃 */
|
||||
'\0',
|
||||
'\xE0', '\xA4', '\x95', ' ', '\xE0', '\xA4', '\xA8', ' ', '\xE0', '\xA4', '\xAE', ' ', '\xE0', '\xA4', '\x89', ' ', '\xE0', '\xA4', '\x9B', ' ', '\xE0', '\xA4', '\x9F', ' ', '\xE0', '\xA4', '\xA0', ' ', '\xE0', '\xA4', '\xA1', /* क न म उ छ ट ठ ड */
|
||||
'\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',
|
||||
'\xE1', '\xB2', '\x9C', ' ', '\xE1', '\xB2', '\x9F', ' ', '\xE1', '\xB2', '\xB3', ' ', '\xE1', '\xB2', '\xB8', ' ', '\xE1', '\xB2', '\x92', ' ', '\xE1', '\xB2', '\x94', ' ', '\xE1', '\xB2', '\x9D', ' ', '\xE1', '\xB2', '\xB4', /* Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ */
|
||||
'\0',
|
||||
'\xE1', '\xB2', '\x98', ' ', '\xE1', '\xB2', '\xB2', ' ', '\xE1', '\xB2', '\x9D', ' ', '\xE1', '\xB2', '\xA9', ' ', '\xE1', '\xB2', '\x9B', ' ', '\xE1', '\xB2', '\xA8', ' ', '\xE1', '\xB2', '\xAF', ' ', '\xE1', '\xB2', '\xBD', /* Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ */
|
||||
'\0',
|
||||
'\xE2', '\xB0', '\x85', ' ', '\xE2', '\xB0', '\x94', ' ', '\xE2', '\xB0', '\xAA', ' ', '\xE2', '\xB0', '\x84', ' ', '\xE2', '\xB0', '\x82', ' ', '\xE2', '\xB0', '\x8A', ' ', '\xE2', '\xB0', '\xAB', ' ', '\xE2', '\xB0', '\x8B', /* Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ */
|
||||
'\0',
|
||||
'\xE2', '\xB0', '\x85', ' ', '\xE2', '\xB0', '\x84', ' ', '\xE2', '\xB0', '\x82', ' ', '\xE2', '\xB0', '\xAA', ' ', '\xE2', '\xB0', '\x9E', ' ', '\xE2', '\xB0', '\xA1', ' ', '\xE2', '\xB0', '\x8A', ' ', '\xE2', '\xB0', '\x94', /* Ⰵ Ⰴ Ⰲ Ⱚ Ⱎ Ⱑ Ⰺ Ⱄ */
|
||||
'\0',
|
||||
'\xE2', '\xB0', '\xB5', ' ', '\xE2', '\xB1', '\x84', ' ', '\xE2', '\xB1', '\x9A', ' ', '\xE2', '\xB0', '\xB4', ' ', '\xE2', '\xB0', '\xB2', ' ', '\xE2', '\xB0', '\xBA', ' ', '\xE2', '\xB1', '\x9B', ' ', '\xE2', '\xB0', '\xBB', /* ⰵ ⱄ ⱚ ⰴ ⰲ ⰺ ⱛ ⰻ */
|
||||
'\0',
|
||||
'\xE2', '\xB0', '\xB5', ' ', '\xE2', '\xB0', '\xB4', ' ', '\xE2', '\xB0', '\xB2', ' ', '\xE2', '\xB1', '\x9A', ' ', '\xE2', '\xB1', '\x8E', ' ', '\xE2', '\xB1', '\x91', ' ', '\xE2', '\xB0', '\xBA', ' ', '\xE2', '\xB1', '\x84', /* ⰵ ⰴ ⰲ ⱚ ⱎ ⱑ ⰺ ⱄ */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x8C', '\xB2', ' ', '\xF0', '\x90', '\x8C', '\xB6', ' ', '\xF0', '\x90', '\x8D', '\x80', ' ', '\xF0', '\x90', '\x8D', '\x84', ' ', '\xF0', '\x90', '\x8C', '\xB4', ' ', '\xF0', '\x90', '\x8D', '\x83', ' ', '\xF0', '\x90', '\x8D', '\x88', ' ', '\xF0', '\x90', '\x8C', '\xBE', /* 𐌲 𐌶 𐍀 𐍄 𐌴 𐍃 𐍈 𐌾 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x8C', '\xB6', ' ', '\xF0', '\x90', '\x8C', '\xB4', ' ', '\xF0', '\x90', '\x8D', '\x83', ' ', '\xF0', '\x90', '\x8D', '\x88', /* 𐌶 𐌴 𐍃 𐍈 */
|
||||
'\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',
|
||||
'\xEA', '\xA4', '\x85', ' ', '\xEA', '\xA4', '\x8F', ' ', '\xEA', '\xA4', '\x81', ' ', '\xEA', '\xA4', '\x8B', ' ', '\xEA', '\xA4', '\x80', ' ', '\xEA', '\xA4', '\x8D', /* ꤅ ꤏ ꤁ ꤋ ꤀ ꤍ */
|
||||
'\0',
|
||||
'\xEA', '\xA4', '\x88', ' ', '\xEA', '\xA4', '\x98', ' ', '\xEA', '\xA4', '\x80', ' ', '\xEA', '\xA4', '\x8D', ' ', '\xEA', '\xA4', '\xA2', /* ꤈ ꤘ ꤀ ꤍ ꤢ */
|
||||
'\0',
|
||||
'\xEA', '\xA4', '\x96', ' ', '\xEA', '\xA4', '\xA1', /* ꤖ ꤡ */
|
||||
'\0',
|
||||
'\xEA', '\xA4', '\x91', ' ', '\xEA', '\xA4', '\x9C', ' ', '\xEA', '\xA4', '\x9E', /* ꤑ ꤜ ꤞ */
|
||||
'\0',
|
||||
'\xEA', '\xA4', '\x91', '\xEA', '\xA4', '\xAC', ' ', '\xEA', '\xA4', '\x9C', '\xEA', '\xA4', '\xAD', ' ', '\xEA', '\xA4', '\x94', '\xEA', '\xA4', '\xAC', /* ꤑ꤬ ꤜ꤭ ꤔ꤬ */
|
||||
'\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',
|
||||
'u', ' ', 'v', ' ', 'x', ' ', 'z', ' ', 'o', ' ', 'e', ' ', 's', ' ', 'c', /* u v x z o e s c */
|
||||
'\0',
|
||||
'n', ' ', 'r', ' ', 'x', ' ', 'z', ' ', 'o', ' ', 'e', ' ', 's', ' ', 'c', /* n r x z 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',
|
||||
'\xEA', '\x93', '\xA1', ' ', '\xEA', '\x93', '\xA7', ' ', '\xEA', '\x93', '\xB1', ' ', '\xEA', '\x93', '\xB6', ' ', '\xEA', '\x93', '\xA9', ' ', '\xEA', '\x93', '\x9A', ' ', '\xEA', '\x93', '\xB5', ' ', '\xEA', '\x93', '\xB3', /* ꓡ ꓧ ꓱ ꓶ ꓩ ꓚ ꓵ ꓳ */
|
||||
'\0',
|
||||
'\xEA', '\x93', '\x95', ' ', '\xEA', '\x93', '\x9C', ' ', '\xEA', '\x93', '\x9E', ' ', '\xEA', '\x93', '\xA1', ' ', '\xEA', '\x93', '\x9B', ' ', '\xEA', '\x93', '\xA2', ' ', '\xEA', '\x93', '\xB3', ' ', '\xEA', '\x93', '\xB4', /* ꓕ ꓜ ꓞ ꓡ ꓛ ꓢ ꓳ ꓴ */
|
||||
'\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',
|
||||
'\xF0', '\x96', '\xB9', '\x80', ' ', '\xF0', '\x96', '\xB9', '\x81', ' ', '\xF0', '\x96', '\xB9', '\x82', ' ', '\xF0', '\x96', '\xB9', '\x83', ' ', '\xF0', '\x96', '\xB9', '\x8F', ' ', '\xF0', '\x96', '\xB9', '\x9A', ' ', '\xF0', '\x96', '\xB9', '\x9F', /* 𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹟 */
|
||||
'\0',
|
||||
'\xF0', '\x96', '\xB9', '\x80', ' ', '\xF0', '\x96', '\xB9', '\x81', ' ', '\xF0', '\x96', '\xB9', '\x82', ' ', '\xF0', '\x96', '\xB9', '\x83', ' ', '\xF0', '\x96', '\xB9', '\x8F', ' ', '\xF0', '\x96', '\xB9', '\x9A', ' ', '\xF0', '\x96', '\xB9', '\x92', ' ', '\xF0', '\x96', '\xB9', '\x93', /* 𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹒 𖹓 */
|
||||
'\0',
|
||||
'\xF0', '\x96', '\xB9', '\xA4', ' ', '\xF0', '\x96', '\xB9', '\xAC', ' ', '\xF0', '\x96', '\xB9', '\xA7', ' ', '\xF0', '\x96', '\xB9', '\xB4', ' ', '\xF0', '\x96', '\xB9', '\xB6', ' ', '\xF0', '\x96', '\xB9', '\xBE', /* 𖹤 𖹬 𖹧 𖹴 𖹶 𖹾 */
|
||||
'\0',
|
||||
'\xF0', '\x96', '\xB9', '\xA0', ' ', '\xF0', '\x96', '\xB9', '\xA1', ' ', '\xF0', '\x96', '\xB9', '\xA2', ' ', '\xF0', '\x96', '\xB9', '\xB9', ' ', '\xF0', '\x96', '\xB9', '\xB3', ' ', '\xF0', '\x96', '\xB9', '\xAE', /* 𖹠 𖹡 𖹢 𖹹 𖹳 𖹮 */
|
||||
'\0',
|
||||
'\xF0', '\x96', '\xB9', '\xA0', ' ', '\xF0', '\x96', '\xB9', '\xA1', ' ', '\xF0', '\x96', '\xB9', '\xA2', ' ', '\xF0', '\x96', '\xB9', '\xB3', ' ', '\xF0', '\x96', '\xB9', '\xAD', ' ', '\xF0', '\x96', '\xB9', '\xBD', /* 𖹠 𖹡 𖹢 𖹳 𖹭 𖹽 */
|
||||
'\0',
|
||||
'\xF0', '\x96', '\xB9', '\xA5', ' ', '\xF0', '\x96', '\xB9', '\xA8', ' ', '\xF0', '\x96', '\xB9', '\xA9', /* 𖹥 𖹨 𖹩 */
|
||||
'\0',
|
||||
'\xF0', '\x96', '\xBA', '\x80', ' ', '\xF0', '\x96', '\xBA', '\x85', ' ', '\xF0', '\x96', '\xBA', '\x88', ' ', '\xF0', '\x96', '\xBA', '\x84', ' ', '\xF0', '\x96', '\xBA', '\x8D', /* 𖺀 𖺅 𖺈 𖺄 𖺍 */
|
||||
'\0',
|
||||
'\xE1', '\xA0', '\xB3', ' ', '\xE1', '\xA0', '\xB4', ' ', '\xE1', '\xA0', '\xB6', ' ', '\xE1', '\xA0', '\xBD', ' ', '\xE1', '\xA1', '\x82', ' ', '\xE1', '\xA1', '\x8A', ' ', '\xE2', '\x80', '\x8D', '\xE1', '\xA1', '\xA1', '\xE2', '\x80', '\x8D', ' ', '\xE2', '\x80', '\x8D', '\xE1', '\xA1', '\xB3', '\xE2', '\x80', '\x8D', /* ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ᡡ ᡳ */
|
||||
'\0',
|
||||
'\xE1', '\xA1', '\x83', /* ᡃ */
|
||||
'\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',
|
||||
'\xDF', '\x90', ' ', '\xDF', '\x89', ' ', '\xDF', '\x92', ' ', '\xDF', '\x9F', ' ', '\xDF', '\x96', ' ', '\xDF', '\x9C', ' ', '\xDF', '\xA0', ' ', '\xDF', '\xA5', /* ߐ ߉ ߒ ߟ ߖ ߜ ߠ ߥ */
|
||||
'\0',
|
||||
'\xDF', '\x80', ' ', '\xDF', '\x98', ' ', '\xDF', '\xA1', ' ', '\xDF', '\xA0', ' ', '\xDF', '\xA5', /* ߀ ߘ ߡ ߠ ߥ */
|
||||
'\0',
|
||||
'\xDF', '\x8F', ' ', '\xDF', '\x9B', ' ', '\xDF', '\x8B', /* ߏ ߛ ߋ */
|
||||
'\0',
|
||||
'\xDF', '\x8E', ' ', '\xDF', '\x8F', ' ', '\xDF', '\x9B', ' ', '\xDF', '\x8B', /* ߎ ߏ ߛ ߋ */
|
||||
'\0',
|
||||
'\xE1', '\xB1', '\x9B', ' ', '\xE1', '\xB1', '\x9C', ' ', '\xE1', '\xB1', '\x9D', ' ', '\xE1', '\xB1', '\xA1', ' ', '\xE1', '\xB1', '\xA2', ' ', '\xE1', '\xB1', '\xA5', /* ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\xB0', '\x97', ' ', '\xF0', '\x90', '\xB0', '\x98', ' ', '\xF0', '\x90', '\xB0', '\xA7', /* 𐰗 𐰘 𐰧 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\xB0', '\x89', ' ', '\xF0', '\x90', '\xB0', '\x97', ' ', '\xF0', '\x90', '\xB0', '\xA6', ' ', '\xF0', '\x90', '\xB0', '\xA7', /* 𐰉 𐰗 𐰦 𐰧 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x92', '\xBE', ' ', '\xF0', '\x90', '\x93', '\x8D', ' ', '\xF0', '\x90', '\x93', '\x92', ' ', '\xF0', '\x90', '\x93', '\x93', ' ', '\xF0', '\x90', '\x92', '\xBB', ' ', '\xF0', '\x90', '\x93', '\x82', ' ', '\xF0', '\x90', '\x92', '\xB5', ' ', '\xF0', '\x90', '\x93', '\x86', /* 𐒾 𐓍 𐓒 𐓓 𐒻 𐓂 𐒵 𐓆 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x92', '\xB0', ' ', '\xF0', '\x90', '\x93', '\x8D', ' ', '\xF0', '\x90', '\x93', '\x82', ' ', '\xF0', '\x90', '\x92', '\xBF', ' ', '\xF0', '\x90', '\x93', '\x8E', ' ', '\xF0', '\x90', '\x92', '\xB9', /* 𐒰 𐓍 𐓂 𐒿 𐓎 𐒹 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x92', '\xBC', ' ', '\xF0', '\x90', '\x92', '\xBD', ' ', '\xF0', '\x90', '\x92', '\xBE', /* 𐒼 𐒽 𐒾 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x93', '\xB5', ' ', '\xF0', '\x90', '\x93', '\xB6', ' ', '\xF0', '\x90', '\x93', '\xBA', ' ', '\xF0', '\x90', '\x93', '\xBB', ' ', '\xF0', '\x90', '\x93', '\x9D', ' ', '\xF0', '\x90', '\x93', '\xA3', ' ', '\xF0', '\x90', '\x93', '\xAA', ' ', '\xF0', '\x90', '\x93', '\xAE', /* 𐓵 𐓶 𐓺 𐓻 𐓝 𐓣 𐓪 𐓮 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x93', '\x98', ' ', '\xF0', '\x90', '\x93', '\x9A', ' ', '\xF0', '\x90', '\x93', '\xA3', ' ', '\xF0', '\x90', '\x93', '\xB5', ' ', '\xF0', '\x90', '\x93', '\xA1', ' ', '\xF0', '\x90', '\x93', '\xA7', ' ', '\xF0', '\x90', '\x93', '\xAA', ' ', '\xF0', '\x90', '\x93', '\xB6', /* 𐓘 𐓚 𐓣 𐓵 𐓡 𐓧 𐓪 𐓶 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x93', '\xA4', ' ', '\xF0', '\x90', '\x93', '\xA6', ' ', '\xF0', '\x90', '\x93', '\xB8', ' ', '\xF0', '\x90', '\x93', '\xB9', ' ', '\xF0', '\x90', '\x93', '\x9B', /* 𐓤 𐓦 𐓸 𐓹 𐓛 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x93', '\xA4', ' ', '\xF0', '\x90', '\x93', '\xA5', ' ', '\xF0', '\x90', '\x93', '\xA6', /* 𐓤 𐓥 𐓦 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x92', '\x86', ' ', '\xF0', '\x90', '\x92', '\x89', ' ', '\xF0', '\x90', '\x92', '\x90', ' ', '\xF0', '\x90', '\x92', '\x92', ' ', '\xF0', '\x90', '\x92', '\x98', ' ', '\xF0', '\x90', '\x92', '\x9B', ' ', '\xF0', '\x90', '\x92', '\xA0', ' ', '\xF0', '\x90', '\x92', '\xA3', /* 𐒆 𐒉 𐒐 𐒒 𐒘 𐒛 𐒠 𐒣 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x92', '\x80', ' ', '\xF0', '\x90', '\x92', '\x82', ' ', '\xF0', '\x90', '\x92', '\x86', ' ', '\xF0', '\x90', '\x92', '\x88', ' ', '\xF0', '\x90', '\x92', '\x8A', ' ', '\xF0', '\x90', '\x92', '\x92', ' ', '\xF0', '\x90', '\x92', '\xA0', ' ', '\xF0', '\x90', '\x92', '\xA9', /* 𐒀 𐒂 𐒆 𐒈 𐒊 𐒒 𐒠 𐒩 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\xB4', '\x83', ' ', '\xF0', '\x90', '\xB4', '\x80', ' ', '\xF0', '\x90', '\xB4', '\x86', ' ', '\xF0', '\x90', '\xB4', '\x96', ' ', '\xF0', '\x90', '\xB4', '\x95', /* 𐴃 𐴀 𐴆 𐴖 𐴕 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\xB4', '\x94', ' ', '\xF0', '\x90', '\xB4', '\x96', ' ', '\xF0', '\x90', '\xB4', '\x95', ' ', '\xF0', '\x90', '\xB4', '\x91', ' ', '\xF0', '\x90', '\xB4', '\x90', /* 𐴔 𐴖 𐴕 𐴑 𐴐 */
|
||||
'\0',
|
||||
'\xD9', '\x80', /* ـ */
|
||||
'\0',
|
||||
'\xEA', '\xA2', '\x9C', ' ', '\xEA', '\xA2', '\x9E', ' ', '\xEA', '\xA2', '\xB3', ' ', '\xEA', '\xA2', '\x82', ' ', '\xEA', '\xA2', '\x96', ' ', '\xEA', '\xA2', '\x92', ' ', '\xEA', '\xA2', '\x9D', ' ', '\xEA', '\xA2', '\x9B', /* ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ꢝ ꢛ */
|
||||
'\0',
|
||||
'\xEA', '\xA2', '\x82', ' ', '\xEA', '\xA2', '\xA8', ' ', '\xEA', '\xA2', '\xBA', ' ', '\xEA', '\xA2', '\xA4', ' ', '\xEA', '\xA2', '\x8E', /* ꢂ ꢨ ꢺ ꢤ ꢎ */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x91', '\x95', ' ', '\xF0', '\x90', '\x91', '\x99', /* 𐑕 𐑙 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x91', '\x94', ' ', '\xF0', '\x90', '\x91', '\x96', ' ', '\xF0', '\x90', '\x91', '\x97', ' ', '\xF0', '\x90', '\x91', '\xB9', ' ', '\xF0', '\x90', '\x91', '\xBB', /* 𐑔 𐑖 𐑗 𐑹 𐑻 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x91', '\x9F', ' ', '\xF0', '\x90', '\x91', '\xA3', /* 𐑟 𐑣 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x91', '\xB1', ' ', '\xF0', '\x90', '\x91', '\xB2', ' ', '\xF0', '\x90', '\x91', '\xB3', ' ', '\xF0', '\x90', '\x91', '\xB4', ' ', '\xF0', '\x90', '\x91', '\xB8', ' ', '\xF0', '\x90', '\x91', '\xBA', ' ', '\xF0', '\x90', '\x91', '\xBC', /* 𐑱 𐑲 𐑳 𐑴 𐑸 𐑺 𐑼 */
|
||||
'\0',
|
||||
'\xF0', '\x90', '\x91', '\xB4', ' ', '\xF0', '\x90', '\x91', '\xBB', ' ', '\xF0', '\x90', '\x91', '\xB9', /* 𐑴 𐑻 𐑹 */
|
||||
'\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',
|
||||
'\xE1', '\xAE', '\x8B', ' ', '\xE1', '\xAE', '\x9E', ' ', '\xE1', '\xAE', '\xAE', ' ', '\xE1', '\xAE', '\xBD', ' ', '\xE1', '\xAE', '\xB0', ' ', '\xE1', '\xAE', '\x88', /* ᮋ ᮞ ᮮ ᮽ ᮰ ᮈ */
|
||||
'\0',
|
||||
'\xE1', '\xAE', '\x84', ' ', '\xE1', '\xAE', '\x94', ' ', '\xE1', '\xAE', '\x95', ' ', '\xE1', '\xAE', '\x97', ' ', '\xE1', '\xAE', '\xB0', ' ', '\xE1', '\xAE', '\x86', ' ', '\xE1', '\xAE', '\x88', ' ', '\xE1', '\xAE', '\x89', /* ᮄ ᮔ ᮕ ᮗ ᮰ ᮆ ᮈ ᮉ */
|
||||
'\0',
|
||||
'\xE1', '\xAE', '\xBC', ' ', '\xE1', '\xB3', '\x84', /* ᮼ ᳄ */
|
||||
'\0',
|
||||
'\xEA', '\xAA', '\x86', ' ', '\xEA', '\xAA', '\x94', ' ', '\xEA', '\xAA', '\x92', ' ', '\xEA', '\xAA', '\x96', ' ', '\xEA', '\xAA', '\xAB', /* ꪆ ꪔ ꪒ ꪖ ꪫ */
|
||||
'\0',
|
||||
'\xEA', '\xAA', '\x89', ' ', '\xEA', '\xAA', '\xAB', ' ', '\xEA', '\xAA', '\xAE', /* ꪉ ꪫ ꪮ */
|
||||
'\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', /* ๐ ๑ ๓ */
|
||||
'\0',
|
||||
'\xE2', '\xB5', '\x94', ' ', '\xE2', '\xB5', '\x99', ' ', '\xE2', '\xB5', '\x9B', ' ', '\xE2', '\xB5', '\x9E', ' ', '\xE2', '\xB4', '\xB5', ' ', '\xE2', '\xB4', '\xBC', ' ', '\xE2', '\xB4', '\xB9', ' ', '\xE2', '\xB5', '\x8E', /* ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ */
|
||||
'\0',
|
||||
'\xEA', '\x97', '\x8D', ' ', '\xEA', '\x98', '\x96', ' ', '\xEA', '\x98', '\x99', ' ', '\xEA', '\x98', '\x9C', ' ', '\xEA', '\x96', '\x9C', ' ', '\xEA', '\x96', '\x9D', ' ', '\xEA', '\x94', '\x85', ' ', '\xEA', '\x95', '\xA2', /* ꗍ ꘖ ꘙ ꘜ ꖜ ꖝ ꔅ ꕢ */
|
||||
'\0',
|
||||
'\xEA', '\x97', '\x8D', ' ', '\xEA', '\x98', '\x96', ' ', '\xEA', '\x98', '\x99', ' ', '\xEA', '\x97', '\x9E', ' ', '\xEA', '\x94', '\x85', ' ', '\xEA', '\x95', '\xA2', ' ', '\xEA', '\x96', '\x9C', ' ', '\xEA', '\x94', '\x86', /* ꗍ ꘖ ꘙ ꗞ ꔅ ꕢ ꖜ ꔆ */
|
||||
#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_ADLAM_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_ADLAM_CAPITAL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_ADLAM_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_ADLAM_SMALL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ 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_AVESTAN_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_AVESTAN_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_BAMUM_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_BAMUM_BOTTOM, 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_BUHID_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_BUHID_LARGE, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_BUHID_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_BUHID_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_CHAKMA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_CHAKMA_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_CHAKMA_DESCENDER, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_CANADIAN_SYLLABICS_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_CANADIAN_SYLLABICS_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_CARIAN_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_CARIAN_BOTTOM, 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_COPTIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_COPTIC_CAPITAL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_COPTIC_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_COPTIC_SMALL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_CYPRIOT_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_CYPRIOT_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_CYPRIOT_SMALL, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_CYPRIOT_SMALL, 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_DESERET_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_DESERET_CAPITAL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_DESERET_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_DESERET_SMALL_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_GEORGIAN_MTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM, 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_GLAGOLITIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_GLAGOLITIC_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_GLAGOLITIC_SMALL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_GOTHIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_GOTHIC_BOTTOM, 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_KAYAH_LI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_KAYAH_LI_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_KAYAH_LI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_KAYAH_LI_DESCENDER, 0 },
|
||||
{ AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER, 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_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_LATIN_SMALL_BOTTOM, 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_LISU_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_LISU_BOTTOM, 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_MEDEFAIDRIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MEDEFAIDRIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_MEDEFAIDRIN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_MEDEFAIDRIN_SMALL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MEDEFAIDRIN_SMALL_DESCENDER, 0 },
|
||||
{ AF_BLUE_STRING_MEDEFAIDRIN_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_MONGOLIAN_TOP_BASE, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE, 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_NKO_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_NKO_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_NKO_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_NKO_SMALL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_OL_CHIKI, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_OL_CHIKI, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_OLD_TURKIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_OLD_TURKIC_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_OSAGE_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER, 0 },
|
||||
{ AF_BLUE_STRING_OSAGE_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_OSAGE_SMALL_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_OSAGE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_OSAGE_SMALL_DESCENDER, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_OSMANYA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_OSMANYA_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_ROHINGYA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_ROHINGYA_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_ROHINGYA_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_SAURASHTRA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_SAURASHTRA_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_SHAVIAN_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_SHAVIAN_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_SHAVIAN_DESCENDER, 0 },
|
||||
{ AF_BLUE_STRING_SHAVIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
|
||||
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
|
||||
{ AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM, 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_SUNDANESE_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_SUNDANESE_BOTTOM, 0 },
|
||||
{ AF_BLUE_STRING_SUNDANESE_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_TAI_VIET_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_TAI_VIET_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 },
|
||||
{ AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_TIFINAGH, 0 },
|
||||
{ AF_BLUE_STRING_MAX, 0 },
|
||||
{ AF_BLUE_STRING_VAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
|
||||
{ AF_BLUE_STRING_VAI_BOTTOM, 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 */
|
||||
39
thirdparty/freetype/src/autofit/afblue.cin
vendored
Normal file
39
thirdparty/freetype/src/autofit/afblue.cin
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afblue.c
|
||||
*
|
||||
* Auto-fitter data for blue strings (body).
|
||||
*
|
||||
* Copyright (C) 2013-2024 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[] =
|
||||
{
|
||||
/* */
|
||||
@AF_BLUE_STRINGS_ARRAY@
|
||||
};
|
||||
|
||||
|
||||
/* stringsets are specific to styles */
|
||||
FT_LOCAL_ARRAY_DEF( AF_Blue_StringRec )
|
||||
af_blue_stringsets[] =
|
||||
{
|
||||
/* */
|
||||
@AF_BLUE_STRINGSETS_ARRAY@
|
||||
};
|
||||
|
||||
|
||||
/* END */
|
||||
429
thirdparty/freetype/src/autofit/afblue.h
vendored
Normal file
429
thirdparty/freetype/src/autofit/afblue.h
vendored
Normal file
@@ -0,0 +1,429 @@
|
||||
/* 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 (C) 2013-2024 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_ADLAM_CAPITAL_TOP = 0,
|
||||
AF_BLUE_STRING_ADLAM_CAPITAL_BOTTOM = 30,
|
||||
AF_BLUE_STRING_ADLAM_SMALL_TOP = 40,
|
||||
AF_BLUE_STRING_ADLAM_SMALL_BOTTOM = 65,
|
||||
AF_BLUE_STRING_ARABIC_TOP = 105,
|
||||
AF_BLUE_STRING_ARABIC_BOTTOM = 123,
|
||||
AF_BLUE_STRING_ARABIC_JOIN = 138,
|
||||
AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP = 141,
|
||||
AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM = 165,
|
||||
AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER = 189,
|
||||
AF_BLUE_STRING_ARMENIAN_SMALL_TOP = 210,
|
||||
AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM = 234,
|
||||
AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER = 258,
|
||||
AF_BLUE_STRING_AVESTAN_TOP = 282,
|
||||
AF_BLUE_STRING_AVESTAN_BOTTOM = 302,
|
||||
AF_BLUE_STRING_BAMUM_TOP = 312,
|
||||
AF_BLUE_STRING_BAMUM_BOTTOM = 344,
|
||||
AF_BLUE_STRING_BENGALI_BASE = 376,
|
||||
AF_BLUE_STRING_BENGALI_TOP = 408,
|
||||
AF_BLUE_STRING_BENGALI_HEAD = 436,
|
||||
AF_BLUE_STRING_BUHID_TOP = 468,
|
||||
AF_BLUE_STRING_BUHID_LARGE = 476,
|
||||
AF_BLUE_STRING_BUHID_SMALL = 488,
|
||||
AF_BLUE_STRING_BUHID_BOTTOM = 504,
|
||||
AF_BLUE_STRING_CANADIAN_SYLLABICS_TOP = 532,
|
||||
AF_BLUE_STRING_CANADIAN_SYLLABICS_BOTTOM = 564,
|
||||
AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_TOP = 596,
|
||||
AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_BOTTOM = 628,
|
||||
AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_TOP = 660,
|
||||
AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_BOTTOM = 688,
|
||||
AF_BLUE_STRING_CARIAN_TOP = 720,
|
||||
AF_BLUE_STRING_CARIAN_BOTTOM = 760,
|
||||
AF_BLUE_STRING_CHAKMA_TOP = 795,
|
||||
AF_BLUE_STRING_CHAKMA_BOTTOM = 820,
|
||||
AF_BLUE_STRING_CHAKMA_DESCENDER = 845,
|
||||
AF_BLUE_STRING_CHEROKEE_CAPITAL = 910,
|
||||
AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER = 942,
|
||||
AF_BLUE_STRING_CHEROKEE_SMALL = 974,
|
||||
AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER = 1006,
|
||||
AF_BLUE_STRING_COPTIC_CAPITAL_TOP = 1022,
|
||||
AF_BLUE_STRING_COPTIC_CAPITAL_BOTTOM = 1054,
|
||||
AF_BLUE_STRING_COPTIC_SMALL_TOP = 1086,
|
||||
AF_BLUE_STRING_COPTIC_SMALL_BOTTOM = 1118,
|
||||
AF_BLUE_STRING_CYPRIOT_TOP = 1150,
|
||||
AF_BLUE_STRING_CYPRIOT_BOTTOM = 1190,
|
||||
AF_BLUE_STRING_CYPRIOT_SMALL = 1225,
|
||||
AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 1240,
|
||||
AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 1264,
|
||||
AF_BLUE_STRING_CYRILLIC_SMALL = 1288,
|
||||
AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 1312,
|
||||
AF_BLUE_STRING_DESERET_CAPITAL_TOP = 1321,
|
||||
AF_BLUE_STRING_DESERET_CAPITAL_BOTTOM = 1346,
|
||||
AF_BLUE_STRING_DESERET_SMALL_TOP = 1371,
|
||||
AF_BLUE_STRING_DESERET_SMALL_BOTTOM = 1396,
|
||||
AF_BLUE_STRING_DEVANAGARI_BASE = 1421,
|
||||
AF_BLUE_STRING_DEVANAGARI_TOP = 1453,
|
||||
AF_BLUE_STRING_DEVANAGARI_HEAD = 1485,
|
||||
AF_BLUE_STRING_DEVANAGARI_BOTTOM = 1517,
|
||||
AF_BLUE_STRING_ETHIOPIC_TOP = 1525,
|
||||
AF_BLUE_STRING_ETHIOPIC_BOTTOM = 1557,
|
||||
AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP = 1589,
|
||||
AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM = 1621,
|
||||
AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER = 1653,
|
||||
AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER = 1685,
|
||||
AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP = 1717,
|
||||
AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM = 1749,
|
||||
AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP = 1781,
|
||||
AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM = 1813,
|
||||
AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER = 1845,
|
||||
AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER = 1877,
|
||||
AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP = 1909,
|
||||
AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM = 1941,
|
||||
AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP = 1973,
|
||||
AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM = 2005,
|
||||
AF_BLUE_STRING_GLAGOLITIC_SMALL_TOP = 2037,
|
||||
AF_BLUE_STRING_GLAGOLITIC_SMALL_BOTTOM = 2069,
|
||||
AF_BLUE_STRING_GOTHIC_TOP = 2101,
|
||||
AF_BLUE_STRING_GOTHIC_BOTTOM = 2141,
|
||||
AF_BLUE_STRING_GREEK_CAPITAL_TOP = 2161,
|
||||
AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 2182,
|
||||
AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 2200,
|
||||
AF_BLUE_STRING_GREEK_SMALL = 2218,
|
||||
AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 2242,
|
||||
AF_BLUE_STRING_GUJARATI_TOP = 2266,
|
||||
AF_BLUE_STRING_GUJARATI_BOTTOM = 2298,
|
||||
AF_BLUE_STRING_GUJARATI_ASCENDER = 2330,
|
||||
AF_BLUE_STRING_GUJARATI_DESCENDER = 2380,
|
||||
AF_BLUE_STRING_GUJARATI_DIGIT_TOP = 2413,
|
||||
AF_BLUE_STRING_GURMUKHI_BASE = 2433,
|
||||
AF_BLUE_STRING_GURMUKHI_HEAD = 2465,
|
||||
AF_BLUE_STRING_GURMUKHI_TOP = 2497,
|
||||
AF_BLUE_STRING_GURMUKHI_BOTTOM = 2529,
|
||||
AF_BLUE_STRING_GURMUKHI_DIGIT_TOP = 2561,
|
||||
AF_BLUE_STRING_HEBREW_TOP = 2581,
|
||||
AF_BLUE_STRING_HEBREW_BOTTOM = 2605,
|
||||
AF_BLUE_STRING_HEBREW_DESCENDER = 2623,
|
||||
AF_BLUE_STRING_KANNADA_TOP = 2638,
|
||||
AF_BLUE_STRING_KANNADA_BOTTOM = 2682,
|
||||
AF_BLUE_STRING_KAYAH_LI_TOP = 2714,
|
||||
AF_BLUE_STRING_KAYAH_LI_BOTTOM = 2738,
|
||||
AF_BLUE_STRING_KAYAH_LI_ASCENDER = 2758,
|
||||
AF_BLUE_STRING_KAYAH_LI_DESCENDER = 2766,
|
||||
AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER = 2778,
|
||||
AF_BLUE_STRING_KHMER_TOP = 2799,
|
||||
AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 2823,
|
||||
AF_BLUE_STRING_KHMER_BOTTOM = 2863,
|
||||
AF_BLUE_STRING_KHMER_DESCENDER = 2895,
|
||||
AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 2929,
|
||||
AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 3016,
|
||||
AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 3024,
|
||||
AF_BLUE_STRING_LAO_TOP = 3032,
|
||||
AF_BLUE_STRING_LAO_BOTTOM = 3064,
|
||||
AF_BLUE_STRING_LAO_ASCENDER = 3096,
|
||||
AF_BLUE_STRING_LAO_LARGE_ASCENDER = 3112,
|
||||
AF_BLUE_STRING_LAO_DESCENDER = 3124,
|
||||
AF_BLUE_STRING_LATIN_CAPITAL_TOP = 3148,
|
||||
AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 3164,
|
||||
AF_BLUE_STRING_LATIN_SMALL_F_TOP = 3180,
|
||||
AF_BLUE_STRING_LATIN_SMALL_TOP = 3194,
|
||||
AF_BLUE_STRING_LATIN_SMALL_BOTTOM = 3210,
|
||||
AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 3226,
|
||||
AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 3236,
|
||||
AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 3256,
|
||||
AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 3276,
|
||||
AF_BLUE_STRING_LATIN_SUBS_SMALL = 3296,
|
||||
AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 3332,
|
||||
AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 3352,
|
||||
AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 3383,
|
||||
AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 3412,
|
||||
AF_BLUE_STRING_LATIN_SUPS_SMALL = 3438,
|
||||
AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 3463,
|
||||
AF_BLUE_STRING_LISU_TOP = 3474,
|
||||
AF_BLUE_STRING_LISU_BOTTOM = 3506,
|
||||
AF_BLUE_STRING_MALAYALAM_TOP = 3538,
|
||||
AF_BLUE_STRING_MALAYALAM_BOTTOM = 3582,
|
||||
AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_TOP = 3614,
|
||||
AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_BOTTOM = 3649,
|
||||
AF_BLUE_STRING_MEDEFAIDRIN_SMALL_F_TOP = 3689,
|
||||
AF_BLUE_STRING_MEDEFAIDRIN_SMALL_TOP = 3719,
|
||||
AF_BLUE_STRING_MEDEFAIDRIN_SMALL_BOTTOM = 3749,
|
||||
AF_BLUE_STRING_MEDEFAIDRIN_SMALL_DESCENDER = 3779,
|
||||
AF_BLUE_STRING_MEDEFAIDRIN_DIGIT_TOP = 3794,
|
||||
AF_BLUE_STRING_MONGOLIAN_TOP_BASE = 3819,
|
||||
AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE = 3863,
|
||||
AF_BLUE_STRING_MYANMAR_TOP = 3867,
|
||||
AF_BLUE_STRING_MYANMAR_BOTTOM = 3899,
|
||||
AF_BLUE_STRING_MYANMAR_ASCENDER = 3931,
|
||||
AF_BLUE_STRING_MYANMAR_DESCENDER = 3959,
|
||||
AF_BLUE_STRING_NKO_TOP = 3991,
|
||||
AF_BLUE_STRING_NKO_BOTTOM = 4015,
|
||||
AF_BLUE_STRING_NKO_SMALL_TOP = 4030,
|
||||
AF_BLUE_STRING_NKO_SMALL_BOTTOM = 4039,
|
||||
AF_BLUE_STRING_OL_CHIKI = 4051,
|
||||
AF_BLUE_STRING_OLD_TURKIC_TOP = 4075,
|
||||
AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 4090,
|
||||
AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 4110,
|
||||
AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 4150,
|
||||
AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 4180,
|
||||
AF_BLUE_STRING_OSAGE_SMALL_TOP = 4195,
|
||||
AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 4235,
|
||||
AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4275,
|
||||
AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4300,
|
||||
AF_BLUE_STRING_OSMANYA_TOP = 4315,
|
||||
AF_BLUE_STRING_OSMANYA_BOTTOM = 4355,
|
||||
AF_BLUE_STRING_ROHINGYA_TOP = 4395,
|
||||
AF_BLUE_STRING_ROHINGYA_BOTTOM = 4420,
|
||||
AF_BLUE_STRING_ROHINGYA_JOIN = 4445,
|
||||
AF_BLUE_STRING_SAURASHTRA_TOP = 4448,
|
||||
AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4480,
|
||||
AF_BLUE_STRING_SHAVIAN_TOP = 4500,
|
||||
AF_BLUE_STRING_SHAVIAN_BOTTOM = 4510,
|
||||
AF_BLUE_STRING_SHAVIAN_DESCENDER = 4535,
|
||||
AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4545,
|
||||
AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4580,
|
||||
AF_BLUE_STRING_SINHALA_TOP = 4595,
|
||||
AF_BLUE_STRING_SINHALA_BOTTOM = 4627,
|
||||
AF_BLUE_STRING_SINHALA_DESCENDER = 4659,
|
||||
AF_BLUE_STRING_SUNDANESE_TOP = 4703,
|
||||
AF_BLUE_STRING_SUNDANESE_BOTTOM = 4727,
|
||||
AF_BLUE_STRING_SUNDANESE_DESCENDER = 4759,
|
||||
AF_BLUE_STRING_TAI_VIET_TOP = 4767,
|
||||
AF_BLUE_STRING_TAI_VIET_BOTTOM = 4787,
|
||||
AF_BLUE_STRING_TAMIL_TOP = 4799,
|
||||
AF_BLUE_STRING_TAMIL_BOTTOM = 4831,
|
||||
AF_BLUE_STRING_TELUGU_TOP = 4863,
|
||||
AF_BLUE_STRING_TELUGU_BOTTOM = 4891,
|
||||
AF_BLUE_STRING_THAI_TOP = 4919,
|
||||
AF_BLUE_STRING_THAI_BOTTOM = 4943,
|
||||
AF_BLUE_STRING_THAI_ASCENDER = 4971,
|
||||
AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4983,
|
||||
AF_BLUE_STRING_THAI_DESCENDER = 4995,
|
||||
AF_BLUE_STRING_THAI_LARGE_DESCENDER = 5011,
|
||||
AF_BLUE_STRING_THAI_DIGIT_TOP = 5019,
|
||||
AF_BLUE_STRING_TIFINAGH = 5031,
|
||||
AF_BLUE_STRING_VAI_TOP = 5063,
|
||||
AF_BLUE_STRING_VAI_BOTTOM = 5095,
|
||||
af_blue_1_1 = 5126,
|
||||
#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_ADLM = 0,
|
||||
AF_BLUE_STRINGSET_ARAB = 5,
|
||||
AF_BLUE_STRINGSET_ARMN = 9,
|
||||
AF_BLUE_STRINGSET_AVST = 16,
|
||||
AF_BLUE_STRINGSET_BAMU = 19,
|
||||
AF_BLUE_STRINGSET_BENG = 22,
|
||||
AF_BLUE_STRINGSET_BUHD = 27,
|
||||
AF_BLUE_STRINGSET_CAKM = 32,
|
||||
AF_BLUE_STRINGSET_CANS = 36,
|
||||
AF_BLUE_STRINGSET_CARI = 43,
|
||||
AF_BLUE_STRINGSET_CHER = 46,
|
||||
AF_BLUE_STRINGSET_COPT = 53,
|
||||
AF_BLUE_STRINGSET_CPRT = 58,
|
||||
AF_BLUE_STRINGSET_CYRL = 63,
|
||||
AF_BLUE_STRINGSET_DEVA = 69,
|
||||
AF_BLUE_STRINGSET_DSRT = 75,
|
||||
AF_BLUE_STRINGSET_ETHI = 80,
|
||||
AF_BLUE_STRINGSET_GEOR = 83,
|
||||
AF_BLUE_STRINGSET_GEOK = 90,
|
||||
AF_BLUE_STRINGSET_GLAG = 97,
|
||||
AF_BLUE_STRINGSET_GOTH = 102,
|
||||
AF_BLUE_STRINGSET_GREK = 105,
|
||||
AF_BLUE_STRINGSET_GUJR = 112,
|
||||
AF_BLUE_STRINGSET_GURU = 118,
|
||||
AF_BLUE_STRINGSET_HEBR = 124,
|
||||
AF_BLUE_STRINGSET_KNDA = 128,
|
||||
AF_BLUE_STRINGSET_KALI = 131,
|
||||
AF_BLUE_STRINGSET_KHMR = 137,
|
||||
AF_BLUE_STRINGSET_KHMS = 143,
|
||||
AF_BLUE_STRINGSET_LAO = 146,
|
||||
AF_BLUE_STRINGSET_LATN = 152,
|
||||
AF_BLUE_STRINGSET_LATB = 159,
|
||||
AF_BLUE_STRINGSET_LATP = 166,
|
||||
AF_BLUE_STRINGSET_LISU = 173,
|
||||
AF_BLUE_STRINGSET_MLYM = 176,
|
||||
AF_BLUE_STRINGSET_MEDF = 179,
|
||||
AF_BLUE_STRINGSET_MONG = 187,
|
||||
AF_BLUE_STRINGSET_MYMR = 190,
|
||||
AF_BLUE_STRINGSET_NKOO = 195,
|
||||
AF_BLUE_STRINGSET_NONE = 200,
|
||||
AF_BLUE_STRINGSET_OLCK = 201,
|
||||
AF_BLUE_STRINGSET_ORKH = 204,
|
||||
AF_BLUE_STRINGSET_OSGE = 207,
|
||||
AF_BLUE_STRINGSET_OSMA = 215,
|
||||
AF_BLUE_STRINGSET_ROHG = 218,
|
||||
AF_BLUE_STRINGSET_SAUR = 222,
|
||||
AF_BLUE_STRINGSET_SHAW = 225,
|
||||
AF_BLUE_STRINGSET_SINH = 231,
|
||||
AF_BLUE_STRINGSET_SUND = 235,
|
||||
AF_BLUE_STRINGSET_TAML = 239,
|
||||
AF_BLUE_STRINGSET_TAVT = 242,
|
||||
AF_BLUE_STRINGSET_TELU = 245,
|
||||
AF_BLUE_STRINGSET_THAI = 248,
|
||||
AF_BLUE_STRINGSET_TFNG = 256,
|
||||
AF_BLUE_STRINGSET_VAII = 259,
|
||||
af_blue_2_1 = 262,
|
||||
#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 */
|
||||
146
thirdparty/freetype/src/autofit/afblue.hin
vendored
Normal file
146
thirdparty/freetype/src/autofit/afblue.hin
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afblue.h
|
||||
*
|
||||
* Auto-fitter data for blue strings (specification).
|
||||
*
|
||||
* Copyright (C) 2013-2024 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 */
|
||||
2383
thirdparty/freetype/src/autofit/afcjk.c
vendored
Normal file
2383
thirdparty/freetype/src/autofit/afcjk.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
141
thirdparty/freetype/src/autofit/afcjk.h
vendored
Normal file
141
thirdparty/freetype/src/autofit/afcjk.h
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afcjk.h
|
||||
*
|
||||
* Auto-fitter hinting routines for CJK writing system (specification).
|
||||
*
|
||||
* Copyright (C) 2006-2024 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 AFCJK_H_
|
||||
#define AFCJK_H_
|
||||
|
||||
#include "afhints.h"
|
||||
#include "aflatin.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* the CJK-specific writing system */
|
||||
|
||||
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 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.
|
||||
*/
|
||||
|
||||
#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_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_
|
||||
{
|
||||
AF_WidthRec ref;
|
||||
AF_WidthRec shoot; /* undershoot */
|
||||
FT_UInt flags;
|
||||
|
||||
} AF_CJKBlueRec, *AF_CJKBlue;
|
||||
|
||||
|
||||
typedef struct AF_CJKAxisRec_
|
||||
{
|
||||
FT_Fixed scale;
|
||||
FT_Pos delta;
|
||||
|
||||
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_BLUE_STRINGSET_MAX_LEN];
|
||||
|
||||
FT_Fixed org_scale;
|
||||
FT_Pos org_delta;
|
||||
|
||||
} AF_CJKAxisRec, *AF_CJKAxis;
|
||||
|
||||
|
||||
typedef struct AF_CJKMetricsRec_
|
||||
{
|
||||
AF_StyleMetricsRec root;
|
||||
FT_UInt units_per_em;
|
||||
AF_CJKAxisRec axis[AF_DIMENSION_MAX];
|
||||
|
||||
} AF_CJKMetricsRec, *AF_CJKMetrics;
|
||||
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_CJK
|
||||
FT_LOCAL( FT_Error )
|
||||
af_cjk_metrics_init( AF_StyleMetrics metrics,
|
||||
FT_Face face );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_cjk_metrics_scale( AF_StyleMetrics metrics,
|
||||
AF_Scaler scaler );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
af_cjk_hints_init( AF_GlyphHints hints,
|
||||
AF_StyleMetrics metrics );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
af_cjk_hints_apply( FT_UInt glyph_index,
|
||||
AF_GlyphHints hints,
|
||||
FT_Outline* outline,
|
||||
AF_StyleMetrics metrics );
|
||||
|
||||
/* shared; called from afindic.c */
|
||||
FT_LOCAL( void )
|
||||
af_cjk_metrics_check_digits( AF_CJKMetrics metrics,
|
||||
FT_Face face );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_cjk_metrics_init_widths( AF_CJKMetrics metrics,
|
||||
FT_Face face );
|
||||
#endif /* AF_CONFIG_OPTION_CJK */
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* AFCJK_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
105
thirdparty/freetype/src/autofit/afcover.h
vendored
Normal file
105
thirdparty/freetype/src/autofit/afcover.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afcover.h
|
||||
*
|
||||
* Auto-fitter coverages (specification only).
|
||||
*
|
||||
* Copyright (C) 2013-2024 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 */
|
||||
77
thirdparty/freetype/src/autofit/afdummy.c
vendored
Normal file
77
thirdparty/freetype/src/autofit/afdummy.c
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afdummy.c
|
||||
*
|
||||
* Auto-fitter dummy routines to be used if no hinting should be
|
||||
* performed (body).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 "afdummy.h"
|
||||
#include "afhints.h"
|
||||
#include "aferrors.h"
|
||||
|
||||
|
||||
static FT_Error
|
||||
af_dummy_hints_init( AF_GlyphHints hints,
|
||||
AF_StyleMetrics 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( FT_UInt glyph_index,
|
||||
AF_GlyphHints hints,
|
||||
FT_Outline* outline,
|
||||
AF_StyleMetrics metrics )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
FT_UNUSED( glyph_index );
|
||||
FT_UNUSED( metrics );
|
||||
|
||||
|
||||
error = af_glyph_hints_reload( hints, outline );
|
||||
if ( !error )
|
||||
af_glyph_hints_save( hints, outline );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
AF_DEFINE_WRITING_SYSTEM_CLASS(
|
||||
af_dummy_writing_system_class,
|
||||
|
||||
AF_WRITING_SYSTEM_DUMMY,
|
||||
|
||||
sizeof ( AF_StyleMetricsRec ),
|
||||
|
||||
(AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init */
|
||||
(AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale */
|
||||
(AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */
|
||||
(AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */
|
||||
|
||||
(AF_WritingSystem_InitHintsFunc) af_dummy_hints_init, /* style_hints_init */
|
||||
(AF_WritingSystem_ApplyHintsFunc) af_dummy_hints_apply /* style_hints_apply */
|
||||
)
|
||||
|
||||
|
||||
/* END */
|
||||
40
thirdparty/freetype/src/autofit/afdummy.h
vendored
Normal file
40
thirdparty/freetype/src/autofit/afdummy.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afdummy.h
|
||||
*
|
||||
* Auto-fitter dummy routines to be used if no hinting should be
|
||||
* performed (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 AFDUMMY_H_
|
||||
#define AFDUMMY_H_
|
||||
|
||||
#include "aftypes.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/* A dummy writing system used when no hinting should be performed. */
|
||||
|
||||
AF_DECLARE_WRITING_SYSTEM_CLASS( af_dummy_writing_system_class )
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* AFDUMMY_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
42
thirdparty/freetype/src/autofit/aferrors.h
vendored
Normal file
42
thirdparty/freetype/src/autofit/aferrors.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* aferrors.h
|
||||
*
|
||||
* Autofitter error codes (specification only).
|
||||
*
|
||||
* Copyright (C) 2005-2024 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 is used to define the Autofitter error enumeration
|
||||
* constants.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AFERRORS_H_
|
||||
#define AFERRORS_H_
|
||||
|
||||
#include <freetype/ftmoderr.h>
|
||||
|
||||
#undef FTERRORS_H_
|
||||
|
||||
#undef FT_ERR_PREFIX
|
||||
#define FT_ERR_PREFIX AF_Err_
|
||||
#define FT_ERR_BASE FT_Mod_Err_Autofit
|
||||
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
#endif /* AFERRORS_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
513
thirdparty/freetype/src/autofit/afglobal.c
vendored
Normal file
513
thirdparty/freetype/src/autofit/afglobal.c
vendored
Normal file
@@ -0,0 +1,513 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afglobal.c
|
||||
*
|
||||
* Auto-fitter routines to compute global hinting values (body).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 "afws-decl.h"
|
||||
#include <freetype/internal/ftdebug.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 afglobal
|
||||
|
||||
|
||||
#include "aferrors.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"
|
||||
|
||||
|
||||
#undef WRITING_SYSTEM
|
||||
#define WRITING_SYSTEM( ws, WS ) \
|
||||
&af_ ## ws ## _writing_system_class,
|
||||
|
||||
FT_LOCAL_ARRAY_DEF( AF_WritingSystemClass )
|
||||
af_writing_system_classes[] =
|
||||
{
|
||||
|
||||
#include "afws-iter.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 */
|
||||
};
|
||||
|
||||
|
||||
#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_UShort ss;
|
||||
FT_UShort dflt = 0xFFFFU; /* a non-valid value */
|
||||
FT_UInt i;
|
||||
|
||||
|
||||
/* the value AF_STYLE_UNASSIGNED means `uncovered glyph' */
|
||||
for ( i = 0; i < 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[ss]; ss++ )
|
||||
{
|
||||
AF_StyleClass style_class =
|
||||
af_style_classes[ss];
|
||||
AF_ScriptClass script_class =
|
||||
af_script_classes[style_class->script];
|
||||
AF_Script_UniRange range;
|
||||
|
||||
|
||||
if ( !script_class->script_uni_ranges )
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Scan all Unicode points in the range and set the corresponding
|
||||
* glyph style index.
|
||||
*/
|
||||
if ( style_class->coverage == AF_COVERAGE_DEFAULT )
|
||||
{
|
||||
if ( 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 < globals->glyph_count &&
|
||||
( gstyles[gindex] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED )
|
||||
gstyles[gindex] = ss;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
charcode = FT_Get_Next_Char( face, charcode, &gindex );
|
||||
|
||||
if ( gindex == 0 || charcode > range->last )
|
||||
break;
|
||||
|
||||
if ( gindex < globals->glyph_count &&
|
||||
( gstyles[gindex] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED )
|
||||
gstyles[gindex] = 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 < globals->glyph_count &&
|
||||
( gstyles[gindex] & AF_STYLE_MASK ) == ss )
|
||||
gstyles[gindex] |= AF_NONBASE;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
charcode = FT_Get_Next_Char( face, charcode, &gindex );
|
||||
|
||||
if ( gindex == 0 || charcode > range->last )
|
||||
break;
|
||||
|
||||
if ( gindex < globals->glyph_count &&
|
||||
( gstyles[gindex] & AF_STYLE_MASK ) == 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[ss]; ss++ )
|
||||
{
|
||||
AF_StyleClass style_class = af_style_classes[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[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 < 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_UInt 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" ));
|
||||
FT_TRACE4(( "style coverage\n" ));
|
||||
FT_TRACE4(( "==============\n" ));
|
||||
FT_TRACE4(( "\n" ));
|
||||
|
||||
for ( ss = 0; af_style_classes[ss]; ss++ )
|
||||
{
|
||||
AF_StyleClass style_class = af_style_classes[ss];
|
||||
FT_UInt count = 0;
|
||||
FT_UInt 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 */
|
||||
|
||||
face->charmap = 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_QALLOC( globals,
|
||||
sizeof ( *globals ) +
|
||||
(FT_ULong)face->num_glyphs * sizeof ( FT_UShort ) ) )
|
||||
goto Exit;
|
||||
|
||||
FT_ZERO( &globals->metrics );
|
||||
|
||||
globals->face = face;
|
||||
globals->glyph_count = (FT_UInt)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( void* globals_ )
|
||||
{
|
||||
AF_FaceGlobals globals = (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[nn];
|
||||
AF_WritingSystemClass writing_system_class =
|
||||
af_writing_system_classes[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 );
|
||||
hb_buffer_destroy( globals->hb_buf );
|
||||
#endif
|
||||
|
||||
/* no need to free `globals->glyph_styles'; */
|
||||
/* it is part of the `globals' array */
|
||||
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 >= 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 );
|
||||
|
||||
Again:
|
||||
style_class = af_style_classes[style];
|
||||
writing_system_class = af_writing_system_classes
|
||||
[style_class->writing_system];
|
||||
|
||||
metrics = globals->metrics[style];
|
||||
if ( !metrics )
|
||||
{
|
||||
/* 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 );
|
||||
|
||||
/* internal error code -1 indicates */
|
||||
/* that no blue zones have been found */
|
||||
if ( error == -1 )
|
||||
{
|
||||
style = (AF_Style)( globals->glyph_styles[gindex] &
|
||||
AF_STYLE_UNASSIGNED );
|
||||
/* IMPORTANT: Clear the error code, see
|
||||
* https://gitlab.freedesktop.org/freetype/freetype/-/issues/1063
|
||||
*/
|
||||
error = FT_Err_Ok;
|
||||
goto Again;
|
||||
}
|
||||
|
||||
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 < globals->glyph_count )
|
||||
return FT_BOOL( globals->glyph_styles[gindex] & AF_DIGIT );
|
||||
|
||||
return FT_BOOL( 0 );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
173
thirdparty/freetype/src/autofit/afglobal.h
vendored
Normal file
173
thirdparty/freetype/src/autofit/afglobal.h
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afglobal.h
|
||||
*
|
||||
* Auto-fitter routines to compute global hinting values
|
||||
* (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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_UInt glyph_count; /* unsigned 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( void* globals );
|
||||
|
||||
FT_LOCAL( FT_Bool )
|
||||
af_face_globals_is_digit( AF_FaceGlobals globals,
|
||||
FT_UInt gindex );
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* AFGLOBAL_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
1796
thirdparty/freetype/src/autofit/afhints.c
vendored
Normal file
1796
thirdparty/freetype/src/autofit/afhints.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
467
thirdparty/freetype/src/autofit/afhints.h
vendored
Normal file
467
thirdparty/freetype/src/autofit/afhints.h
vendored
Normal file
@@ -0,0 +1,467 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afhints.h
|
||||
*
|
||||
* Auto-fitter hinting routines (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 AFHINTS_H_
|
||||
#define AFHINTS_H_
|
||||
|
||||
#include "aftypes.h"
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/*
|
||||
* The definition of outline glyph hints. These are shared by all
|
||||
* writing system analysis routines (until now).
|
||||
*/
|
||||
|
||||
typedef enum AF_Dimension_
|
||||
{
|
||||
AF_DIMENSION_HORZ = 0, /* x coordinates, */
|
||||
/* i.e., vertical segments & edges */
|
||||
AF_DIMENSION_VERT = 1, /* y coordinates, */
|
||||
/* i.e., horizontal segments & edges */
|
||||
|
||||
AF_DIMENSION_MAX /* do not remove */
|
||||
|
||||
} AF_Dimension;
|
||||
|
||||
|
||||
/* hint directions -- the values are computed so that two vectors are */
|
||||
/* in opposite directions iff `dir1 + dir2 == 0' */
|
||||
typedef enum AF_Direction_
|
||||
{
|
||||
AF_DIR_NONE = 4,
|
||||
AF_DIR_RIGHT = 1,
|
||||
AF_DIR_LEFT = -1,
|
||||
AF_DIR_UP = 2,
|
||||
AF_DIR_DOWN = -2
|
||||
|
||||
} AF_Direction;
|
||||
|
||||
|
||||
/*
|
||||
* The following explanations are mostly taken from the article
|
||||
*
|
||||
* Real-Time Grid Fitting of Typographic Outlines
|
||||
*
|
||||
* by David Turner and Werner Lemberg
|
||||
*
|
||||
* https://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 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).
|
||||
*
|
||||
* 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
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* C | | F
|
||||
* +------<-----+ +-----<------+
|
||||
* | B G |
|
||||
* | |
|
||||
* | |
|
||||
* +--------------->------------------+
|
||||
* D E
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* vocabulary from the TrueType specification, stem segments form a
|
||||
* `black distance'.
|
||||
*
|
||||
* In the above ASCII drawing, the horizontal segments are BC, DE, and
|
||||
* FG; the vertical segments are AB, CD, EF, and GH.
|
||||
*
|
||||
* Each segment has at most one `best' candidate to form a black
|
||||
* distance, or no candidate at all. Notice that two distinct segments
|
||||
* can have the same candidate, which frequently means a serif.
|
||||
*
|
||||
* A stem is recognized by the following condition:
|
||||
*
|
||||
* best segment_1 = segment_2 && best segment_2 = segment_1
|
||||
*
|
||||
* The best candidate is stored in field `link' in structure
|
||||
* `AF_Segment'.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* where segment_1 corresponds to the serif segment (CD and EF in the
|
||||
* above ASCII drawing).
|
||||
*
|
||||
* The best candidate is stored in field `serif' in structure
|
||||
* `AF_Segment' (and `link' is set to NULL).
|
||||
*
|
||||
*
|
||||
* Touched points
|
||||
*
|
||||
* A point is called `touched' if it has been processed somehow by the
|
||||
* auto-hinter. It basically means that it shouldn't be moved again
|
||||
* (or moved only under certain constraints to preserve the already
|
||||
* applied processing).
|
||||
*
|
||||
*
|
||||
* Flat and round segments
|
||||
*
|
||||
* Segments are `round' or `flat', depending on the series of points
|
||||
* that define them. A segment is round if the next and previous point
|
||||
* of an extremum (which can be either a single point or sequence of
|
||||
* points) are both conic or cubic control points. Otherwise, a
|
||||
* segment with an extremum is flat.
|
||||
*
|
||||
*
|
||||
* Strong Points
|
||||
*
|
||||
* 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) [currently, such points
|
||||
* aren't handled specially in the auto-hinter]
|
||||
*
|
||||
* `af_glyph_hints_align_strong_points' is the function that takes
|
||||
* care of such situations; it is equivalent to the TrueType `IP'
|
||||
* hinting instruction.
|
||||
*
|
||||
*
|
||||
* Weak Points
|
||||
*
|
||||
* Other points in the outline must be interpolated using the
|
||||
* coordinates of their previous and next unfitted contour neighbours.
|
||||
* These are called `weak points' and are touched by the function
|
||||
* `af_glyph_hints_align_weak_points', equivalent to the TrueType `IUP'
|
||||
* hinting instruction. Typical candidates are control points and
|
||||
* points on the contour without a major direction.
|
||||
*
|
||||
* The major effect is to reduce possible distortion caused by
|
||||
* alignment of edges and strong points, thus weak points are processed
|
||||
* after strong points.
|
||||
*/
|
||||
|
||||
|
||||
/* point hint flags */
|
||||
#define AF_FLAG_NONE 0
|
||||
|
||||
/* 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 */
|
||||
#define AF_FLAG_TOUCH_X ( 1U << 2 )
|
||||
#define AF_FLAG_TOUCH_Y ( 1U << 3 )
|
||||
|
||||
/* candidates for weak interpolation have this flag set */
|
||||
#define AF_FLAG_WEAK_INTERPOLATION ( 1U << 4 )
|
||||
|
||||
/* the distance to the next point is very small */
|
||||
#define AF_FLAG_NEAR ( 1U << 5 )
|
||||
|
||||
|
||||
/* edge hint 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;
|
||||
typedef struct AF_SegmentRec_* AF_Segment;
|
||||
typedef struct AF_EdgeRec_* AF_Edge;
|
||||
|
||||
|
||||
typedef struct AF_PointRec_
|
||||
{
|
||||
FT_UShort flags; /* point flags used by hinter */
|
||||
FT_Char in_dir; /* direction of inwards vector */
|
||||
FT_Char out_dir; /* direction of outwards vector */
|
||||
|
||||
FT_Pos ox, oy; /* original, scaled position */
|
||||
FT_Short fx, fy; /* original, unscaled position (in font units) */
|
||||
FT_Pos x, y; /* current position */
|
||||
FT_Pos u, v; /* current (x,y) or (y,x) depending on context */
|
||||
|
||||
AF_Point next; /* next point in contour */
|
||||
AF_Point prev; /* previous point in contour */
|
||||
|
||||
#ifdef FT_DEBUG_AUTOFIT
|
||||
/* track `before' and `after' edges for strong points */
|
||||
AF_Edge before[2];
|
||||
AF_Edge after[2];
|
||||
#endif
|
||||
|
||||
} AF_PointRec;
|
||||
|
||||
|
||||
typedef struct AF_SegmentRec_
|
||||
{
|
||||
FT_Byte flags; /* edge/segment flags for this segment */
|
||||
FT_Char dir; /* segment direction */
|
||||
FT_Short pos; /* position of segment */
|
||||
FT_Short delta; /* deviation from segment position */
|
||||
FT_Short min_coord; /* minimum coordinate of segment */
|
||||
FT_Short max_coord; /* maximum coordinate of segment */
|
||||
FT_Short height; /* the hinted segment height */
|
||||
|
||||
AF_Edge edge; /* the segment's parent edge */
|
||||
AF_Segment edge_next; /* link to next segment in parent edge */
|
||||
|
||||
AF_Segment link; /* (stem) link segment */
|
||||
AF_Segment serif; /* primary segment for serifs */
|
||||
FT_Pos score; /* used during stem matching */
|
||||
FT_Pos len; /* used during stem matching */
|
||||
|
||||
AF_Point first; /* first point in edge segment */
|
||||
AF_Point last; /* last point in edge segment */
|
||||
|
||||
} AF_SegmentRec;
|
||||
|
||||
|
||||
typedef struct AF_EdgeRec_
|
||||
{
|
||||
FT_Short fpos; /* original, unscaled position (in font units) */
|
||||
FT_Pos opos; /* original, scaled position */
|
||||
FT_Pos pos; /* current position */
|
||||
|
||||
FT_Byte flags; /* edge flags */
|
||||
FT_Char dir; /* edge direction */
|
||||
FT_Fixed scale; /* used to speed up interpolation between edges */
|
||||
|
||||
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_Int score; /* used during stem matching */
|
||||
|
||||
AF_Segment first; /* first segment in edge */
|
||||
AF_Segment last; /* last segment in edge */
|
||||
|
||||
} AF_EdgeRec;
|
||||
|
||||
#define AF_SEGMENTS_EMBEDDED 18 /* number of embedded segments */
|
||||
#define AF_EDGES_EMBEDDED 12 /* number of embedded edges */
|
||||
|
||||
typedef struct AF_AxisHintsRec_
|
||||
{
|
||||
FT_UInt num_segments; /* number of used segments */
|
||||
FT_UInt max_segments; /* number of allocated segments */
|
||||
AF_Segment segments; /* segments array */
|
||||
|
||||
FT_UInt num_edges; /* number of used edges */
|
||||
FT_UInt max_edges; /* number of allocated edges */
|
||||
AF_Edge edges; /* edges array */
|
||||
|
||||
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_Fixed x_scale;
|
||||
FT_Pos x_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_contours; /* number of allocated contours */
|
||||
FT_Int num_contours; /* number of used contours */
|
||||
AF_Point* contours; /* contours array */
|
||||
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
|
||||
|
||||
#define AF_HINTS_TEST_SCALER( h, f ) ( (h)->scaler_flags & (f) )
|
||||
#define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) )
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_AUTOFIT
|
||||
|
||||
#define AF_HINTS_DO_HORIZONTAL( h ) \
|
||||
( !af_debug_disable_horz_hints_ && \
|
||||
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
|
||||
|
||||
#define AF_HINTS_DO_VERTICAL( h ) \
|
||||
( !af_debug_disable_vert_hints_ && \
|
||||
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
|
||||
|
||||
#define AF_HINTS_DO_BLUES( h ) ( !af_debug_disable_blue_hints_ )
|
||||
|
||||
#else /* !FT_DEBUG_AUTOFIT */
|
||||
|
||||
#define AF_HINTS_DO_HORIZONTAL( h ) \
|
||||
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
|
||||
|
||||
#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 )
|
||||
|
||||
|
||||
FT_LOCAL( AF_Direction )
|
||||
af_direction_compute( FT_Pos dx,
|
||||
FT_Pos dy );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
af_axis_hints_new_segment( AF_AxisHints axis,
|
||||
FT_Memory memory,
|
||||
AF_Segment *asegment );
|
||||
|
||||
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 *edge );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_init( AF_GlyphHints hints,
|
||||
FT_Memory memory );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_rescale( AF_GlyphHints hints,
|
||||
AF_StyleMetrics metrics );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
af_glyph_hints_reload( AF_GlyphHints hints,
|
||||
FT_Outline* outline );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_save( AF_GlyphHints hints,
|
||||
FT_Outline* outline );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_align_strong_points( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_done( AF_GlyphHints hints );
|
||||
|
||||
/* */
|
||||
|
||||
#define AF_SEGMENT_LEN( seg ) ( (seg)->max_coord - (seg)->min_coord )
|
||||
|
||||
#define AF_SEGMENT_DIST( seg1, seg2 ) ( ( (seg1)->pos > (seg2)->pos ) \
|
||||
? (seg1)->pos - (seg2)->pos \
|
||||
: (seg2)->pos - (seg1)->pos )
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* AFHINTS_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
157
thirdparty/freetype/src/autofit/afindic.c
vendored
Normal file
157
thirdparty/freetype/src/autofit/afindic.c
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afindic.c
|
||||
*
|
||||
* Auto-fitter hinting routines for Indic writing system (body).
|
||||
*
|
||||
* Copyright (C) 2007-2024 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,
|
||||
* 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"
|
||||
#include "aflatin.h"
|
||||
#include "afcjk.h"
|
||||
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_INDIC
|
||||
|
||||
#include "afindic.h"
|
||||
#include "aferrors.h"
|
||||
|
||||
|
||||
static FT_Error
|
||||
af_indic_metrics_init( AF_StyleMetrics metrics_, /* AF_CJKMetrics */
|
||||
FT_Face face )
|
||||
{
|
||||
AF_CJKMetrics metrics = (AF_CJKMetrics)metrics_;
|
||||
|
||||
|
||||
/* skip blue zone init in CJK routines */
|
||||
FT_CharMap oldmap = face->charmap;
|
||||
|
||||
|
||||
metrics->units_per_em = face->units_per_EM;
|
||||
|
||||
if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
|
||||
face->charmap = NULL;
|
||||
else
|
||||
{
|
||||
af_cjk_metrics_init_widths( metrics, face );
|
||||
#if 0
|
||||
/* either need indic specific blue_chars[] or just skip blue zones */
|
||||
af_cjk_metrics_init_blues( metrics, face, af_cjk_blue_chars );
|
||||
#endif
|
||||
af_cjk_metrics_check_digits( metrics, face );
|
||||
}
|
||||
|
||||
face->charmap = oldmap;
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
af_indic_metrics_scale( AF_StyleMetrics metrics,
|
||||
AF_Scaler scaler )
|
||||
{
|
||||
/* use CJK routines */
|
||||
af_cjk_metrics_scale( metrics, scaler );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
af_indic_hints_init( AF_GlyphHints hints,
|
||||
AF_StyleMetrics metrics )
|
||||
{
|
||||
/* use CJK routines */
|
||||
return af_cjk_hints_init( hints, metrics );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
af_indic_hints_apply( FT_UInt glyph_index,
|
||||
AF_GlyphHints hints,
|
||||
FT_Outline* outline,
|
||||
AF_StyleMetrics metrics )
|
||||
{
|
||||
/* use CJK routines */
|
||||
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_StyleMetrics metrics_, /* AF_CJKMetrics */
|
||||
FT_Pos* stdHW,
|
||||
FT_Pos* stdVW )
|
||||
{
|
||||
AF_CJKMetrics metrics = (AF_CJKMetrics)metrics_;
|
||||
|
||||
|
||||
if ( stdHW )
|
||||
*stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width;
|
||||
|
||||
if ( stdVW )
|
||||
*stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** I N D I C S C R I P T C L A S S *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
AF_DEFINE_WRITING_SYSTEM_CLASS(
|
||||
af_indic_writing_system_class,
|
||||
|
||||
AF_WRITING_SYSTEM_INDIC,
|
||||
|
||||
sizeof ( AF_CJKMetricsRec ),
|
||||
|
||||
(AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init, /* style_metrics_init */
|
||||
(AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale, /* style_metrics_scale */
|
||||
(AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */
|
||||
(AF_WritingSystem_GetStdWidthsFunc)af_indic_get_standard_widths, /* style_metrics_getstdw */
|
||||
|
||||
(AF_WritingSystem_InitHintsFunc) af_indic_hints_init, /* style_hints_init */
|
||||
(AF_WritingSystem_ApplyHintsFunc) af_indic_hints_apply /* style_hints_apply */
|
||||
)
|
||||
|
||||
|
||||
#else /* !AF_CONFIG_OPTION_INDIC */
|
||||
|
||||
|
||||
AF_DEFINE_WRITING_SYSTEM_CLASS(
|
||||
af_indic_writing_system_class,
|
||||
|
||||
AF_WRITING_SYSTEM_INDIC,
|
||||
|
||||
sizeof ( AF_CJKMetricsRec ),
|
||||
|
||||
(AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init */
|
||||
(AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale */
|
||||
(AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */
|
||||
(AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */
|
||||
|
||||
(AF_WritingSystem_InitHintsFunc) NULL, /* style_hints_init */
|
||||
(AF_WritingSystem_ApplyHintsFunc) NULL /* style_hints_apply */
|
||||
)
|
||||
|
||||
|
||||
#endif /* !AF_CONFIG_OPTION_INDIC */
|
||||
|
||||
|
||||
/* END */
|
||||
41
thirdparty/freetype/src/autofit/afindic.h
vendored
Normal file
41
thirdparty/freetype/src/autofit/afindic.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afindic.h
|
||||
*
|
||||
* Auto-fitter hinting routines for Indic writing system
|
||||
* (specification).
|
||||
*
|
||||
* Copyright (C) 2007-2024 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,
|
||||
* 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 AFINDIC_H_
|
||||
#define AFINDIC_H_
|
||||
|
||||
#include "afhints.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* the `indic' writing system */
|
||||
|
||||
AF_DECLARE_WRITING_SYSTEM_CLASS( af_indic_writing_system_class )
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* AFINDIC_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
3643
thirdparty/freetype/src/autofit/aflatin.c
vendored
Normal file
3643
thirdparty/freetype/src/autofit/aflatin.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
194
thirdparty/freetype/src/autofit/aflatin.h
vendored
Normal file
194
thirdparty/freetype/src/autofit/aflatin.h
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* aflatin.h
|
||||
*
|
||||
* Auto-fitter hinting routines for latin writing system
|
||||
* (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 AFLATIN_H_
|
||||
#define AFLATIN_H_
|
||||
|
||||
#include "afhints.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/* the `latin' writing system */
|
||||
|
||||
AF_DECLARE_WRITING_SYSTEM_CLASS( af_latin_writing_system_class )
|
||||
|
||||
|
||||
/* constants are given with units_per_em == 2048 in mind */
|
||||
#define AF_LATIN_CONSTANT( metrics, c ) \
|
||||
( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** L A T I N G L O B A L M E T R I C S *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* The following declarations could be embedded in the file `aflatin.c';
|
||||
* they have been made semi-public to allow alternate writing system
|
||||
* hinters to re-use some of them.
|
||||
*/
|
||||
|
||||
|
||||
#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_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;
|
||||
|
||||
|
||||
typedef struct AF_LatinAxisRec_
|
||||
{
|
||||
FT_Fixed scale;
|
||||
FT_Pos delta;
|
||||
|
||||
FT_UInt width_count; /* number of used widths */
|
||||
AF_WidthRec widths[AF_LATIN_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? */
|
||||
|
||||
/* ignored for horizontal metrics */
|
||||
FT_UInt blue_count;
|
||||
AF_LatinBlueRec blues[AF_BLUE_STRINGSET_MAX_LEN];
|
||||
|
||||
FT_Fixed org_scale;
|
||||
FT_Pos org_delta;
|
||||
|
||||
} AF_LatinAxisRec, *AF_LatinAxis;
|
||||
|
||||
|
||||
typedef struct AF_LatinMetricsRec_
|
||||
{
|
||||
AF_StyleMetricsRec root;
|
||||
FT_UInt units_per_em;
|
||||
AF_LatinAxisRec axis[AF_DIMENSION_MAX];
|
||||
|
||||
} AF_LatinMetricsRec, *AF_LatinMetrics;
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
af_latin_metrics_init( AF_StyleMetrics metrics,
|
||||
FT_Face face );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_latin_metrics_scale( AF_StyleMetrics metrics,
|
||||
AF_Scaler scaler );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_latin_metrics_init_widths( AF_LatinMetrics metrics,
|
||||
FT_Face face );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_latin_metrics_check_digits( AF_LatinMetrics metrics,
|
||||
FT_Face face );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** L A T I N G L Y P H A N A L Y S I S *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
#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 ) \
|
||||
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_HORZ_SNAP )
|
||||
|
||||
#define AF_LATIN_HINTS_DO_VERT_SNAP( h ) \
|
||||
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_VERT_SNAP )
|
||||
|
||||
#define AF_LATIN_HINTS_DO_STEM_ADJUST( h ) \
|
||||
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_STEM_ADJUST )
|
||||
|
||||
#define AF_LATIN_HINTS_DO_MONO( h ) \
|
||||
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_MONO )
|
||||
|
||||
|
||||
/*
|
||||
* The next functions shouldn't normally be exported. However, other
|
||||
* writing systems might like to use these functions as-is.
|
||||
*/
|
||||
FT_LOCAL( FT_Error )
|
||||
af_latin_hints_compute_segments( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
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 )
|
||||
af_latin_hints_compute_edges( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
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_ */
|
||||
|
||||
|
||||
/* END */
|
||||
706
thirdparty/freetype/src/autofit/afloader.c
vendored
Normal file
706
thirdparty/freetype/src/autofit/afloader.c
vendored
Normal file
@@ -0,0 +1,706 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afloader.c
|
||||
*
|
||||
* Auto-fitter glyph loading routines (body).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 <freetype/internal/ftcalc.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 )
|
||||
{
|
||||
error = af_face_globals_new( face, &loader->globals, module );
|
||||
if ( !error )
|
||||
{
|
||||
face->autohint.data = (FT_Pointer)loader->globals;
|
||||
face->autohint.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 ) )
|
||||
|
||||
|
||||
static FT_Error
|
||||
af_loader_embolden_glyph_in_slot( AF_Loader loader,
|
||||
FT_Face face,
|
||||
AF_StyleMetrics style_metrics )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
FT_GlyphSlot slot = face->glyph;
|
||||
AF_FaceGlobals globals = loader->globals;
|
||||
AF_WritingSystemClass writing_system_class;
|
||||
|
||||
FT_Size_Metrics* size_metrics = &face->size->internal->autohint_metrics;
|
||||
|
||||
FT_Pos stdVW = 0;
|
||||
FT_Pos stdHW = 0;
|
||||
|
||||
FT_Bool size_changed = size_metrics->x_ppem !=
|
||||
globals->stem_darkening_for_ppem;
|
||||
|
||||
FT_Fixed em_size = af_intToFixed( face->units_per_EM );
|
||||
|
||||
FT_Matrix scale_down_matrix = { 0x10000L, 0, 0, 0x10000L };
|
||||
|
||||
|
||||
/* Skip stem darkening for broken fonts. */
|
||||
if ( !face->units_per_EM )
|
||||
{
|
||||
error = FT_ERR( Corrupted_Font_Header );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 disabled.
|
||||
*/
|
||||
writing_system_class =
|
||||
af_writing_system_classes[style_metrics->style_class->writing_system];
|
||||
|
||||
if ( writing_system_class->style_metrics_getstdw )
|
||||
writing_system_class->style_metrics_getstdw( style_metrics,
|
||||
&stdHW,
|
||||
&stdVW );
|
||||
else
|
||||
{
|
||||
error = FT_ERR( Unimplemented_Feature );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
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_loader_compute_darkening( loader,
|
||||
face,
|
||||
stdVW ) ;
|
||||
darken_x = FT_MulFix( darken_by_font_units_x,
|
||||
size_metrics->x_scale );
|
||||
|
||||
globals->standard_vertical_width = stdVW;
|
||||
globals->stem_darkening_for_ppem = 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_loader_compute_darkening( loader,
|
||||
face,
|
||||
stdHW ) ;
|
||||
darken_y = FT_MulFix( darken_by_font_units_y,
|
||||
size_metrics->y_scale );
|
||||
|
||||
globals->standard_horizontal_width = stdHW;
|
||||
globals->stem_darkening_for_ppem = 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 );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Load the glyph at index into the current slot of a face and hint it. */
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_loader_load_glyph( AF_Loader loader,
|
||||
AF_Module module,
|
||||
FT_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_Int32 load_flags )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
FT_Size size = face->size;
|
||||
FT_Size_Internal size_internal = size->internal;
|
||||
FT_GlyphSlot slot = face->glyph;
|
||||
FT_Slot_Internal slot_internal = slot->internal;
|
||||
FT_GlyphLoader gloader = slot_internal->loader;
|
||||
|
||||
AF_GlyphHints hints = loader->hints;
|
||||
AF_ScalerRec scaler;
|
||||
AF_StyleMetrics style_metrics;
|
||||
FT_UInt style_options = AF_STYLE_NONE_DFLT;
|
||||
AF_StyleClass style_class;
|
||||
AF_WritingSystemClass writing_system_class;
|
||||
|
||||
|
||||
FT_ZERO( &scaler );
|
||||
|
||||
if ( !size_internal->autohint_metrics.x_scale ||
|
||||
size_internal->autohint_mode != FT_LOAD_TARGET_MODE( load_flags ) )
|
||||
{
|
||||
/* switching between hinting modes usually means different scaling */
|
||||
/* values; this later on enforces recomputation of everything */
|
||||
/* related to the current size */
|
||||
|
||||
size_internal->autohint_mode = FT_LOAD_TARGET_MODE( load_flags );
|
||||
size_internal->autohint_metrics = size->metrics;
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_TT_SIZE_METRICS
|
||||
{
|
||||
FT_Size_Metrics* size_metrics = &size_internal->autohint_metrics;
|
||||
|
||||
|
||||
/* set metrics to integer values and adjust scaling accordingly; */
|
||||
/* this is the same setup as with TrueType fonts, cf. function */
|
||||
/* `tt_size_reset' in file `ttobjs.c' */
|
||||
size_metrics->ascender = FT_PIX_ROUND(
|
||||
FT_MulFix( face->ascender,
|
||||
size_metrics->y_scale ) );
|
||||
size_metrics->descender = FT_PIX_ROUND(
|
||||
FT_MulFix( face->descender,
|
||||
size_metrics->y_scale ) );
|
||||
size_metrics->height = FT_PIX_ROUND(
|
||||
FT_MulFix( face->height,
|
||||
size_metrics->y_scale ) );
|
||||
|
||||
size_metrics->x_scale = FT_DivFix( size_metrics->x_ppem << 6,
|
||||
face->units_per_EM );
|
||||
size_metrics->y_scale = FT_DivFix( size_metrics->y_ppem << 6,
|
||||
face->units_per_EM );
|
||||
size_metrics->max_advance = FT_PIX_ROUND(
|
||||
FT_MulFix( face->max_advance_width,
|
||||
size_metrics->x_scale ) );
|
||||
}
|
||||
#endif /* AF_CONFIG_OPTION_TT_SIZE_METRICS */
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: This code currently doesn't support fractional advance widths,
|
||||
* i.e., placing hinted glyphs at anything other than integer
|
||||
* x-positions. This is only relevant for the warper code, which
|
||||
* scales and shifts glyphs to optimize blackness of stems (hinting on
|
||||
* the x-axis by nature places things on pixel integers, hinting on the
|
||||
* y-axis only, i.e., LIGHT mode, doesn't touch the x-axis). The delta
|
||||
* values of the scaler would need to be adjusted.
|
||||
*/
|
||||
scaler.face = face;
|
||||
scaler.x_scale = size_internal->autohint_metrics.x_scale;
|
||||
scaler.x_delta = 0;
|
||||
scaler.y_scale = size_internal->autohint_metrics.y_scale;
|
||||
scaler.y_delta = 0;
|
||||
|
||||
scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
|
||||
scaler.flags = 0;
|
||||
|
||||
/* note that the fallback style can't be changed anymore */
|
||||
/* after the first call of `af_loader_load_glyph' */
|
||||
error = af_loader_reset( loader, module, face );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/*
|
||||
* Glyphs (really code points) are assigned to scripts. Script
|
||||
* analysis is done lazily: For each glyph that passes through here,
|
||||
* the corresponding script analyzer is called, but returns immediately
|
||||
* if it has been run already.
|
||||
*/
|
||||
error = af_face_globals_get_metrics( loader->globals, glyph_index,
|
||||
style_options, &style_metrics );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
style_class = style_metrics->style_class;
|
||||
writing_system_class =
|
||||
af_writing_system_classes[style_class->writing_system];
|
||||
|
||||
loader->metrics = style_metrics;
|
||||
|
||||
if ( writing_system_class->style_metrics_scale )
|
||||
writing_system_class->style_metrics_scale( style_metrics, &scaler );
|
||||
else
|
||||
style_metrics->scaler = scaler;
|
||||
|
||||
if ( writing_system_class->style_hints_init )
|
||||
{
|
||||
error = writing_system_class->style_hints_init( hints,
|
||||
style_metrics );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
load_flags |= FT_LOAD_NO_SCALE |
|
||||
FT_LOAD_IGNORE_TRANSFORM |
|
||||
FT_LOAD_LINEAR_DESIGN;
|
||||
load_flags &= ~FT_LOAD_RENDER;
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, load_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.
|
||||
*
|
||||
* Ignore errors and carry on without emboldening.
|
||||
*
|
||||
*/
|
||||
|
||||
/* stem darkening only works well in `light' mode */
|
||||
if ( scaler.render_mode == FT_RENDER_MODE_LIGHT &&
|
||||
( !face->internal->no_stem_darkening ||
|
||||
( face->internal->no_stem_darkening < 0 &&
|
||||
!module->no_stem_darkening ) ) )
|
||||
af_loader_embolden_glyph_in_slot( loader, face, style_metrics );
|
||||
|
||||
loader->transformed = slot_internal->glyph_transformed;
|
||||
if ( loader->transformed )
|
||||
{
|
||||
FT_Matrix inverse;
|
||||
|
||||
|
||||
loader->trans_matrix = slot_internal->glyph_matrix;
|
||||
loader->trans_delta = slot_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 */
|
||||
if ( writing_system_class->style_hints_apply )
|
||||
{
|
||||
error = writing_system_class->style_hints_apply(
|
||||
glyph_index,
|
||||
hints,
|
||||
&gloader->base.outline,
|
||||
style_metrics );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ];
|
||||
|
||||
|
||||
if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) )
|
||||
{
|
||||
AF_Edge edge1 = axis->edges; /* leftmost edge */
|
||||
AF_Edge edge2 = edge1 +
|
||||
axis->num_edges - 1; /* rightmost edge */
|
||||
|
||||
FT_Pos old_rsb = loader->pp2.x - edge2->opos;
|
||||
/* loader->pp1.x is always zero at this point of time */
|
||||
FT_Pos old_lsb = edge1->opos; /* - loader->pp1.x */
|
||||
FT_Pos new_lsb = edge1->pos;
|
||||
|
||||
/* remember unhinted values to later account */
|
||||
/* for rounding errors */
|
||||
FT_Pos pp1x_uh = new_lsb - old_lsb;
|
||||
FT_Pos 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;
|
||||
}
|
||||
}
|
||||
/* `light' mode uses integer advance widths */
|
||||
/* but sets `lsb_delta' and `rsb_delta' */
|
||||
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;
|
||||
}
|
||||
|
||||
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, style_metrics->scaler.x_scale );
|
||||
vvector.y = FT_MulFix( vvector.y, style_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 );
|
||||
}
|
||||
|
||||
/* 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 );
|
||||
|
||||
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 ( scaler.render_mode != FT_RENDER_MODE_LIGHT &&
|
||||
( FT_IS_FIXED_WIDTH( slot->face ) ||
|
||||
( af_face_globals_is_digit( loader->globals, glyph_index ) &&
|
||||
style_metrics->digits_have_same_width ) ) )
|
||||
{
|
||||
slot->metrics.horiAdvance =
|
||||
FT_MulFix( slot->metrics.horiAdvance,
|
||||
style_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;
|
||||
}
|
||||
|
||||
slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
|
||||
style_metrics->scaler.y_scale );
|
||||
|
||||
slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
|
||||
slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
|
||||
|
||||
slot->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
}
|
||||
|
||||
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_Fixed )
|
||||
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 FT_DivFix( darken_amount, em_ratio );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
91
thirdparty/freetype/src/autofit/afloader.h
vendored
Normal file
91
thirdparty/freetype/src/autofit/afloader.h
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afloader.h
|
||||
*
|
||||
* Auto-fitter glyph loading routines (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 AFLOADER_H_
|
||||
#define AFLOADER_H_
|
||||
|
||||
#include "afhints.h"
|
||||
#include "afmodule.h"
|
||||
#include "afglobal.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/*
|
||||
* The autofitter module's (global) data structure to communicate with
|
||||
* actual fonts. If necessary, `local' data like the current face, the
|
||||
* current face's auto-hint data, or the current glyph's parameters
|
||||
* relevant to auto-hinting are `swapped in'. Cf. functions like
|
||||
* `af_loader_reset' and `af_loader_load_g'.
|
||||
*/
|
||||
|
||||
typedef struct AF_LoaderRec_
|
||||
{
|
||||
/* current face data */
|
||||
FT_Face face;
|
||||
AF_FaceGlobals globals;
|
||||
|
||||
/* current glyph data */
|
||||
AF_GlyphHints hints;
|
||||
AF_StyleMetrics metrics;
|
||||
FT_Bool transformed;
|
||||
FT_Matrix trans_matrix;
|
||||
FT_Vector trans_delta;
|
||||
FT_Vector pp1;
|
||||
FT_Vector pp2;
|
||||
/* we don't handle vertical phantom points */
|
||||
|
||||
} AF_LoaderRec, *AF_Loader;
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_loader_init( AF_Loader loader,
|
||||
AF_GlyphHints hints );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
af_loader_reset( AF_Loader loader,
|
||||
AF_Module module,
|
||||
FT_Face face );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_loader_done( AF_Loader loader );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
af_loader_load_glyph( AF_Loader loader,
|
||||
AF_Module module,
|
||||
FT_Face face,
|
||||
FT_UInt gindex,
|
||||
FT_Int32 load_flags );
|
||||
|
||||
FT_LOCAL( FT_Fixed )
|
||||
af_loader_compute_darkening( AF_Loader loader,
|
||||
FT_Face face,
|
||||
FT_Pos standard_width );
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* AFLOADER_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
527
thirdparty/freetype/src/autofit/afmodule.c
vendored
Normal file
527
thirdparty/freetype/src/autofit/afmodule.c
vendored
Normal file
@@ -0,0 +1,527 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afmodule.c
|
||||
*
|
||||
* Auto-fitter module implementation (body).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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"
|
||||
|
||||
#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 */
|
||||
static AF_GlyphHintsRec af_debug_hints_rec_[1];
|
||||
|
||||
void* af_debug_hints_ = af_debug_hints_rec_;
|
||||
#endif
|
||||
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/ftdriver.h>
|
||||
#include <freetype/internal/services/svprop.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 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 = 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_Bool value_is_string )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
AF_Module module = (AF_Module)ft_module;
|
||||
|
||||
#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
FT_UNUSED( value_is_string );
|
||||
#endif
|
||||
|
||||
|
||||
if ( !ft_strcmp( property_name, "fallback-script" ) )
|
||||
{
|
||||
AF_Script* fallback_script;
|
||||
FT_UInt ss;
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
if ( value_is_string )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
#endif
|
||||
|
||||
fallback_script = (AF_Script*)value;
|
||||
|
||||
/* 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[ss]; ss++ )
|
||||
{
|
||||
AF_StyleClass style_class = af_style_classes[ss];
|
||||
|
||||
|
||||
if ( style_class->script == *fallback_script &&
|
||||
style_class->coverage == AF_COVERAGE_DEFAULT )
|
||||
{
|
||||
module->fallback_style = ss;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !af_style_classes[ss] )
|
||||
{
|
||||
FT_TRACE2(( "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" ) )
|
||||
{
|
||||
AF_Script* default_script;
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
if ( value_is_string )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
#endif
|
||||
|
||||
default_script = (AF_Script*)value;
|
||||
|
||||
module->default_script = *default_script;
|
||||
|
||||
return error;
|
||||
}
|
||||
else if ( !ft_strcmp( property_name, "increase-x-height" ) )
|
||||
{
|
||||
FT_Prop_IncreaseXHeight* prop;
|
||||
AF_FaceGlobals globals;
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
if ( value_is_string )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
#endif
|
||||
|
||||
prop = (FT_Prop_IncreaseXHeight*)value;
|
||||
|
||||
error = af_property_get_face_globals( prop->face, &globals, module );
|
||||
if ( !error )
|
||||
globals->increase_x_height = prop->limit;
|
||||
|
||||
return error;
|
||||
}
|
||||
else if ( !ft_strcmp( property_name, "darkening-parameters" ) )
|
||||
{
|
||||
FT_Int* darken_params;
|
||||
FT_Int x1, y1, x2, y2, x3, y3, x4, y4;
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
FT_Int dp[8];
|
||||
|
||||
|
||||
if ( value_is_string )
|
||||
{
|
||||
const char* s = (const char*)value;
|
||||
char* ep;
|
||||
int i;
|
||||
|
||||
|
||||
/* eight comma-separated numbers */
|
||||
for ( i = 0; i < 7; i++ )
|
||||
{
|
||||
dp[i] = (FT_Int)ft_strtol( s, &ep, 10 );
|
||||
if ( *ep != ',' || s == ep )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
s = ep + 1;
|
||||
}
|
||||
|
||||
dp[7] = (FT_Int)ft_strtol( s, &ep, 10 );
|
||||
if ( !( *ep == '\0' || *ep == ' ' ) || s == ep )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
darken_params = dp;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
darken_params = (FT_Int*)value;
|
||||
|
||||
x1 = darken_params[0];
|
||||
y1 = darken_params[1];
|
||||
x2 = darken_params[2];
|
||||
y2 = darken_params[3];
|
||||
x3 = darken_params[4];
|
||||
y3 = darken_params[5];
|
||||
x4 = darken_params[6];
|
||||
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" ) )
|
||||
{
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
if ( value_is_string )
|
||||
{
|
||||
const char* s = (const char*)value;
|
||||
long nsd = ft_strtol( s, NULL, 10 );
|
||||
|
||||
|
||||
if ( !nsd )
|
||||
module->no_stem_darkening = FALSE;
|
||||
else
|
||||
module->no_stem_darkening = TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
FT_Bool* no_stem_darkening = (FT_Bool*)value;
|
||||
|
||||
|
||||
module->no_stem_darkening = *no_stem_darkening;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FT_TRACE2(( "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;
|
||||
|
||||
|
||||
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" ) )
|
||||
{
|
||||
AF_Script* val = (AF_Script*)value;
|
||||
|
||||
AF_StyleClass style_class = af_style_classes[module->fallback_style];
|
||||
|
||||
|
||||
*val = style_class->script;
|
||||
|
||||
return error;
|
||||
}
|
||||
else if ( !ft_strcmp( property_name, "default-script" ) )
|
||||
{
|
||||
AF_Script* val = (AF_Script*)value;
|
||||
|
||||
|
||||
*val = module->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;
|
||||
}
|
||||
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_TRACE2(( "af_property_get: missing property `%s'\n",
|
||||
property_name ));
|
||||
return FT_THROW( Missing_Property );
|
||||
}
|
||||
|
||||
|
||||
FT_DEFINE_SERVICE_PROPERTIESREC(
|
||||
af_service_properties,
|
||||
|
||||
af_property_set, /* FT_Properties_SetFunc set_property */
|
||||
af_property_get /* FT_Properties_GetFunc get_property */
|
||||
)
|
||||
|
||||
|
||||
FT_DEFINE_SERVICEDESCREC1(
|
||||
af_services,
|
||||
|
||||
FT_SERVICE_ID_PROPERTIES, &af_service_properties )
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Module_Interface )
|
||||
af_get_interface( FT_Module module,
|
||||
const char* module_interface )
|
||||
{
|
||||
FT_UNUSED( module );
|
||||
|
||||
return ft_service_list_lookup( af_services, 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;
|
||||
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( FT_AutoHinter module_,
|
||||
FT_GlyphSlot slot,
|
||||
FT_Size size,
|
||||
FT_UInt glyph_index,
|
||||
FT_Int32 load_flags )
|
||||
{
|
||||
AF_Module module = (AF_Module)module_;
|
||||
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Memory memory = module->root.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 );
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] )
|
||||
{
|
||||
#endif
|
||||
af_glyph_hints_dump_points( hints, 0 );
|
||||
af_glyph_hints_dump_segments( hints, 0 );
|
||||
af_glyph_hints_dump_edges( hints, 0 );
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
}
|
||||
#endif
|
||||
|
||||
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, /* FT_AutoHinter_GlobalResetFunc reset_face */
|
||||
NULL, /* FT_AutoHinter_GlobalGetFunc get_global_hints */
|
||||
NULL, /* FT_AutoHinter_GlobalDoneFunc done_global_hints */
|
||||
af_autofitter_load_glyph /* FT_AutoHinter_GlyphLoadFunc 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_autofitter_interface,
|
||||
|
||||
af_autofitter_init, /* FT_Module_Constructor module_init */
|
||||
af_autofitter_done, /* FT_Module_Destructor module_done */
|
||||
af_get_interface /* FT_Module_Requester get_interface */
|
||||
)
|
||||
|
||||
|
||||
/* END */
|
||||
55
thirdparty/freetype/src/autofit/afmodule.h
vendored
Normal file
55
thirdparty/freetype/src/autofit/afmodule.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afmodule.h
|
||||
*
|
||||
* Auto-fitter module implementation (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 AFMODULE_H_
|
||||
#define AFMODULE_H_
|
||||
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/ftmodapi.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/*
|
||||
* This is the `extended' FT_Module structure that holds the
|
||||
* autofitter's global data.
|
||||
*/
|
||||
|
||||
typedef struct AF_ModuleRec_
|
||||
{
|
||||
FT_ModuleRec root;
|
||||
|
||||
FT_UInt fallback_style;
|
||||
AF_Script default_script;
|
||||
FT_Bool no_stem_darkening;
|
||||
FT_Int darken_params[8];
|
||||
|
||||
} AF_ModuleRec, *AF_Module;
|
||||
|
||||
|
||||
FT_DECLARE_AUTOHINTER_INTERFACE( af_autofitter_interface )
|
||||
FT_DECLARE_MODULE( autofit_module_class )
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* AFMODULE_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
1072
thirdparty/freetype/src/autofit/afranges.c
vendored
Normal file
1072
thirdparty/freetype/src/autofit/afranges.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
47
thirdparty/freetype/src/autofit/afranges.h
vendored
Normal file
47
thirdparty/freetype/src/autofit/afranges.h
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afranges.h
|
||||
*
|
||||
* Auto-fitter Unicode script ranges (specification).
|
||||
*
|
||||
* Copyright (C) 2013-2024 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 */
|
||||
408
thirdparty/freetype/src/autofit/afscript.h
vendored
Normal file
408
thirdparty/freetype/src/autofit/afscript.h
vendored
Normal file
@@ -0,0 +1,408 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afscript.h
|
||||
*
|
||||
* Auto-fitter scripts (specification only).
|
||||
*
|
||||
* Copyright (C) 2013-2024 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( adlm, ADLM,
|
||||
"Adlam",
|
||||
HB_SCRIPT_ADLAM,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x9E\xA4\x8C \xF0\x9E\xA4\xAE" ) /* 𞤌 𞤮 */
|
||||
|
||||
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,
|
||||
"\xD5\xBD \xD5\x8D" ) /* ս Ս */
|
||||
|
||||
SCRIPT( avst, AVST,
|
||||
"Avestan",
|
||||
HB_SCRIPT_AVESTAN,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x90\xAC\x9A" ) /* 𐬚 */
|
||||
|
||||
SCRIPT( bamu, BAMU,
|
||||
"Bamum",
|
||||
HB_SCRIPT_BAMUM,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xEA\x9B\x81 \xEA\x9B\xAF" ) /* ꛁ ꛯ */
|
||||
|
||||
/* 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( buhd, BUHD,
|
||||
"Buhid",
|
||||
HB_SCRIPT_BUHID,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE1\x9D\x8B \xE1\x9D\x8F" ) /* ᝋ ᝏ */
|
||||
|
||||
SCRIPT( cakm, CAKM,
|
||||
"Chakma",
|
||||
HB_SCRIPT_CHAKMA,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x91\x84\xA4 \xF0\x91\x84\x89 \xF0\x91\x84\x9B" ) /* 𑄤 𑄉 𑄛 */
|
||||
|
||||
SCRIPT( cans, CANS,
|
||||
"Canadian Syllabics",
|
||||
HB_SCRIPT_CANADIAN_SYLLABICS,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE1\x91\x8C \xE1\x93\x9A" ) /* ᑌ ᓚ */
|
||||
|
||||
SCRIPT( cari, CARI,
|
||||
"Carian",
|
||||
HB_SCRIPT_CARIAN,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x90\x8A\xAB \xF0\x90\x8B\x89" ) /* 𐊫 𐋉 */
|
||||
|
||||
SCRIPT( cher, CHER,
|
||||
"Cherokee",
|
||||
HB_SCRIPT_CHEROKEE,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE1\x8E\xA4 \xE1\x8F\x85 \xEA\xAE\x95" ) /* Ꭴ Ꮕ ꮕ */
|
||||
|
||||
SCRIPT( copt, COPT,
|
||||
"Coptic",
|
||||
HB_SCRIPT_COPTIC,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE2\xB2\x9E \xE2\xB2\x9F" ) /* Ⲟ ⲟ */
|
||||
|
||||
SCRIPT( cprt, CPRT,
|
||||
"Cypriot",
|
||||
HB_SCRIPT_CYPRIOT,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x90\xA0\x85 \xF0\x90\xA0\xA3" ) /* 𐠅 𐠣 */
|
||||
|
||||
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( dsrt, DSRT,
|
||||
"Deseret",
|
||||
HB_SCRIPT_DESERET,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x90\x90\x84 \xF0\x90\x90\xAC" ) /* 𐐄 𐐬 */
|
||||
|
||||
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 \xE1\xB2\xBF" ) /* ი ე ა Ი */
|
||||
|
||||
SCRIPT( geok, GEOK,
|
||||
"Georgian (Khutsuri)",
|
||||
HB_SCRIPT_INVALID,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE1\x82\xB6 \xE1\x82\xB1 \xE2\xB4\x99" ) /* Ⴖ Ⴑ ⴙ */
|
||||
|
||||
SCRIPT( glag, GLAG,
|
||||
"Glagolitic",
|
||||
HB_SCRIPT_GLAGOLITIC,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE2\xB0\x95 \xE2\xB1\x85" ) /* Ⱅ ⱅ */
|
||||
|
||||
SCRIPT( goth, GOTH,
|
||||
"Gothic",
|
||||
HB_SCRIPT_GOTHIC,
|
||||
HINTING_TOP_TO_BOTTOM,
|
||||
"\xF0\x90\x8C\xB4 \xF0\x90\x8C\xBE \xF0\x90\x8D\x83" ) /* 𐌴 𐌾 𐍃 */
|
||||
|
||||
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( kali, KALI,
|
||||
"Kayah Li",
|
||||
HB_SCRIPT_KAYAH_LI,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xEA\xA4\x8D \xEA\xA4\x80" ) /* ꤍ ꤀ */
|
||||
|
||||
/* 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" ) /* ᧡ ᧪ */
|
||||
|
||||
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 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( lisu, LISU,
|
||||
"Lisu",
|
||||
HB_SCRIPT_LISU,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xEA\x93\xB3" ) /* ꓳ */
|
||||
|
||||
SCRIPT( mlym, MLYM,
|
||||
"Malayalam",
|
||||
HB_SCRIPT_MALAYALAM,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE0\xB4\xA0 \xE0\xB4\xB1" ) /* ഠ റ */
|
||||
|
||||
SCRIPT( medf, MEDF,
|
||||
"Medefaidrin",
|
||||
HB_SCRIPT_MEDEFAIDRIN,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x96\xB9\xA1 \xF0\x96\xB9\x9B \xF0\x96\xB9\xAF" ) /* 𖹡 𖹛 𖹯 */
|
||||
|
||||
SCRIPT( mong, MONG,
|
||||
"Mongolian",
|
||||
HB_SCRIPT_MONGOLIAN,
|
||||
HINTING_TOP_TO_BOTTOM,
|
||||
"\xE1\xA1\x82 \xE1\xA0\xAA" ) /* ᡂ ᠪ */
|
||||
|
||||
SCRIPT( mymr, MYMR,
|
||||
"Myanmar",
|
||||
HB_SCRIPT_MYANMAR,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE1\x80\x9D \xE1\x80\x84 \xE1\x80\x82" ) /* ဝ င ဂ */
|
||||
|
||||
SCRIPT( nkoo, NKOO,
|
||||
"N'Ko",
|
||||
HB_SCRIPT_NKO,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xDF\x8B \xDF\x80" ) /* ߋ ߀ */
|
||||
|
||||
SCRIPT( none, NONE,
|
||||
"no script",
|
||||
HB_SCRIPT_INVALID,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"" )
|
||||
|
||||
SCRIPT( olck, OLCK,
|
||||
"Ol Chiki",
|
||||
HB_SCRIPT_OL_CHIKI,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE1\xB1\x9B" ) /* ᱛ */
|
||||
|
||||
SCRIPT( orkh, ORKH,
|
||||
"Old Turkic",
|
||||
HB_SCRIPT_OLD_TURKIC,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x90\xB0\x97" ) /* 𐰗 */
|
||||
|
||||
SCRIPT( osge, OSGE,
|
||||
"Osage",
|
||||
HB_SCRIPT_OSAGE,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x90\x93\x82 \xF0\x90\x93\xAA" ) /* 𐓂 𐓪 */
|
||||
|
||||
SCRIPT( osma, OSMA,
|
||||
"Osmanya",
|
||||
HB_SCRIPT_OSMANYA,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x90\x92\x86 \xF0\x90\x92\xA0" ) /* 𐒆 𐒠 */
|
||||
|
||||
SCRIPT( rohg, ROHG,
|
||||
"Hanifi Rohingya",
|
||||
HB_SCRIPT_HANIFI_ROHINGYA,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x90\xB4\xB0" ) /* 𐴰 */
|
||||
|
||||
SCRIPT( saur, SAUR,
|
||||
"Saurashtra",
|
||||
HB_SCRIPT_SAURASHTRA,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xEA\xA2\x9D \xEA\xA3\x90" ) /* ꢝ ꣐ */
|
||||
|
||||
SCRIPT( shaw, SHAW,
|
||||
"Shavian",
|
||||
HB_SCRIPT_SHAVIAN,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xF0\x90\x91\xB4" ) /* 𐑴 */
|
||||
|
||||
SCRIPT( sinh, SINH,
|
||||
"Sinhala",
|
||||
HB_SCRIPT_SINHALA,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE0\xB6\xA7" ) /* ට */
|
||||
|
||||
/* only digit zero has a simple (round) shape in the Sundanese script */
|
||||
SCRIPT( sund, SUND,
|
||||
"Sundanese",
|
||||
HB_SCRIPT_SUNDANESE,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE1\xAE\xB0" ) /* ᮰ */
|
||||
|
||||
/* 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" ) /* ௦ */
|
||||
|
||||
SCRIPT( tavt, TAVT,
|
||||
"Tai Viet",
|
||||
HB_SCRIPT_TAI_VIET,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xEA\xAA\x92 \xEA\xAA\xAB" ) /* ꪒ ꪫ */
|
||||
|
||||
/* 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( tfng, TFNG,
|
||||
"Tifinagh",
|
||||
HB_SCRIPT_TIFINAGH,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE2\xB5\x94" ) /* ⵔ */
|
||||
|
||||
SCRIPT( thai, THAI,
|
||||
"Thai",
|
||||
HB_SCRIPT_THAI,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xE0\xB8\xB2 \xE0\xB9\x85 \xE0\xB9\x90" ) /* า ๅ ๐ */
|
||||
|
||||
SCRIPT( vaii, VAII,
|
||||
"Vai",
|
||||
HB_SCRIPT_VAI,
|
||||
HINTING_BOTTOM_TO_TOP,
|
||||
"\xEA\x98\x93 \xEA\x96\x9C \xEA\x96\xB4" ) /* ꘓ ꖜ ꖴ */
|
||||
|
||||
#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( 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 */
|
||||
690
thirdparty/freetype/src/autofit/afshaper.c
vendored
Normal file
690
thirdparty/freetype/src/autofit/afshaper.c
vendored
Normal file
@@ -0,0 +1,690 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afshaper.c
|
||||
*
|
||||
* HarfBuzz interface for accessing OpenType features (body).
|
||||
*
|
||||
* Copyright (C) 2013-2024 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 <freetype/freetype.h>
|
||||
#include <freetype/ftadvanc.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 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 = NULL; /* GSUB lookups for a given script */
|
||||
hb_set_t* gsub_glyphs = NULL; /* glyphs covered by GSUB lookups */
|
||||
hb_set_t* gpos_lookups = NULL; /* GPOS lookups for a given script */
|
||||
hb_set_t* gpos_glyphs = NULL; /* 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 );
|
||||
|
||||
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. */
|
||||
{
|
||||
unsigned int tags_count = 3;
|
||||
hb_tag_t tags[3];
|
||||
|
||||
|
||||
hb_ot_tags_from_script_and_language( script,
|
||||
HB_LANGUAGE_INVALID,
|
||||
&tags_count,
|
||||
tags,
|
||||
NULL,
|
||||
NULL );
|
||||
script_tags[0] = tags_count > 0 ? tags[0] : HB_TAG_NONE;
|
||||
script_tags[1] = tags_count > 1 ? tags[1] : HB_TAG_NONE;
|
||||
script_tags[2] = tags_count > 2 ? tags[2] : HB_TAG_NONE;
|
||||
}
|
||||
|
||||
/* If the second tag is HB_OT_TAG_DEFAULT_SCRIPT, 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;
|
||||
}
|
||||
|
||||
gsub_lookups = hb_set_create();
|
||||
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 */
|
||||
|
||||
FT_TRACE4(( "GSUB lookups (style `%s'):\n",
|
||||
af_style_names[style_class->style] ));
|
||||
FT_TRACE4(( " " ));
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
count = 0;
|
||||
#endif
|
||||
|
||||
gsub_glyphs = hb_set_create();
|
||||
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" ));
|
||||
FT_TRACE4(( "\n" ));
|
||||
#endif
|
||||
|
||||
FT_TRACE4(( "GPOS lookups (style `%s'):\n",
|
||||
af_style_names[style_class->style] ));
|
||||
FT_TRACE4(( " " ));
|
||||
|
||||
gpos_lookups = hb_set_create();
|
||||
hb_ot_layout_collect_lookups( face,
|
||||
HB_OT_TAG_GPOS,
|
||||
script_tags,
|
||||
NULL,
|
||||
coverage_tags,
|
||||
gpos_lookups );
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
count = 0;
|
||||
#endif
|
||||
|
||||
gpos_glyphs = hb_set_create();
|
||||
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" ));
|
||||
FT_TRACE4(( "\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
|
||||
* (that 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', that is, they have a zero vertical offset, but
|
||||
* most of them are small caps glyphs shifted up to the superscript
|
||||
* position (that 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(( " " ));
|
||||
}
|
||||
|
||||
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" ));
|
||||
FT_TRACE4(( " (none)" ));
|
||||
}
|
||||
FT_TRACE4(( "\n" ));
|
||||
FT_TRACE4(( "\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_UNUSED( face );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
af_shaper_buf_destroy( FT_Face face,
|
||||
void* buf )
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( 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 */
|
||||
71
thirdparty/freetype/src/autofit/afshaper.h
vendored
Normal file
71
thirdparty/freetype/src/autofit/afshaper.h
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afshaper.h
|
||||
*
|
||||
* HarfBuzz interface for accessing OpenType features (specification).
|
||||
*
|
||||
* Copyright (C) 2013-2024 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 <freetype/freetype.h>
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
|
||||
|
||||
#include <hb.h>
|
||||
#include <hb-ot.h>
|
||||
#include "ft-hb.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 */
|
||||
487
thirdparty/freetype/src/autofit/afstyles.h
vendored
Normal file
487
thirdparty/freetype/src/autofit/afstyles.h
vendored
Normal file
@@ -0,0 +1,487 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afstyles.h
|
||||
*
|
||||
* Auto-fitter styles (specification only).
|
||||
*
|
||||
* Copyright (C) 2013-2024 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( adlm_dflt, ADLM_DFLT,
|
||||
"Adlam default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_ADLM,
|
||||
AF_BLUE_STRINGSET_ADLM,
|
||||
AF_COVERAGE_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( avst_dflt, AVST_DFLT,
|
||||
"Avestan default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_AVST,
|
||||
AF_BLUE_STRINGSET_AVST,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( bamu_dflt, BAMU_DFLT,
|
||||
"Bamum default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_BAMU,
|
||||
AF_BLUE_STRINGSET_BAMU,
|
||||
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( buhd_dflt, BUHD_DFLT,
|
||||
"Buhid default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_BUHD,
|
||||
AF_BLUE_STRINGSET_BUHD,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( cakm_dflt, CAKM_DFLT,
|
||||
"Chakma default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_CAKM,
|
||||
AF_BLUE_STRINGSET_CAKM,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( cans_dflt, CANS_DFLT,
|
||||
"Canadian Syllabics default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_CANS,
|
||||
AF_BLUE_STRINGSET_CANS,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( cari_dflt, CARI_DFLT,
|
||||
"Carian default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_CARI,
|
||||
AF_BLUE_STRINGSET_CARI,
|
||||
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 )
|
||||
|
||||
STYLE( copt_dflt, COPT_DFLT,
|
||||
"Coptic default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_COPT,
|
||||
AF_BLUE_STRINGSET_COPT,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( cprt_dflt, CPRT_DFLT,
|
||||
"Cypriot default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_CPRT,
|
||||
AF_BLUE_STRINGSET_CPRT,
|
||||
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( dsrt_dflt, DSRT_DFLT,
|
||||
"Deseret default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_DSRT,
|
||||
AF_BLUE_STRINGSET_DSRT,
|
||||
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 )
|
||||
|
||||
STYLE( glag_dflt, GLAG_DFLT,
|
||||
"Glagolitic default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_GLAG,
|
||||
AF_BLUE_STRINGSET_GLAG,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( goth_dflt, GOTH_DFLT,
|
||||
"Gothic default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_GOTH,
|
||||
AF_BLUE_STRINGSET_GOTH,
|
||||
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( kali_dflt, KALI_DFLT,
|
||||
"Kayah Li default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_KALI,
|
||||
AF_BLUE_STRINGSET_KALI,
|
||||
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( knda_dflt, KNDA_DFLT,
|
||||
"Kannada default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_KNDA,
|
||||
AF_BLUE_STRINGSET_KNDA,
|
||||
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 )
|
||||
|
||||
STYLE( lisu_dflt, LISU_DFLT,
|
||||
"Lisu default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_LISU,
|
||||
AF_BLUE_STRINGSET_LISU,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( mlym_dflt, MLYM_DFLT,
|
||||
"Malayalam default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_MLYM,
|
||||
AF_BLUE_STRINGSET_MLYM,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( medf_dflt, MEDF_DFLT,
|
||||
"Medefaidrin default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_MEDF,
|
||||
AF_BLUE_STRINGSET_MEDF,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( mong_dflt, MONG_DFLT,
|
||||
"Mongolian default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_MONG,
|
||||
AF_BLUE_STRINGSET_MONG,
|
||||
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( nkoo_dflt, NKOO_DFLT,
|
||||
"N'Ko default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_NKOO,
|
||||
AF_BLUE_STRINGSET_NKOO,
|
||||
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( olck_dflt, OLCK_DFLT,
|
||||
"Ol Chiki default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_OLCK,
|
||||
AF_BLUE_STRINGSET_OLCK,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( orkh_dflt, ORKH_DFLT,
|
||||
"Old Turkic default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_ORKH,
|
||||
AF_BLUE_STRINGSET_ORKH,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( osge_dflt, OSGE_DFLT,
|
||||
"Osage default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_OSGE,
|
||||
AF_BLUE_STRINGSET_OSGE,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( osma_dflt, OSMA_DFLT,
|
||||
"Osmanya default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_OSMA,
|
||||
AF_BLUE_STRINGSET_OSMA,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( rohg_dflt, ROHG_DFLT,
|
||||
"Hanifi Rohingya default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_ROHG,
|
||||
AF_BLUE_STRINGSET_ROHG,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( saur_dflt, SAUR_DFLT,
|
||||
"Saurashtra default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_SAUR,
|
||||
AF_BLUE_STRINGSET_SAUR,
|
||||
AF_COVERAGE_DEFAULT )
|
||||
|
||||
STYLE( shaw_dflt, SHAW_DFLT,
|
||||
"Shavian default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_SHAW,
|
||||
AF_BLUE_STRINGSET_SHAW,
|
||||
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( sund_dflt, SUND_DFLT,
|
||||
"Sundanese default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_SUND,
|
||||
AF_BLUE_STRINGSET_SUND,
|
||||
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( tavt_dflt, TAVT_DFLT,
|
||||
"Tai Viet default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_TAVT,
|
||||
AF_BLUE_STRINGSET_TAVT,
|
||||
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( tfng_dflt, TFNG_DFLT,
|
||||
"Tifinagh default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_TFNG,
|
||||
AF_BLUE_STRINGSET_TFNG,
|
||||
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 )
|
||||
|
||||
STYLE( vaii_dflt, VAII_DFLT,
|
||||
"Vai default style",
|
||||
AF_WRITING_SYSTEM_LATIN,
|
||||
AF_SCRIPT_VAII,
|
||||
AF_BLUE_STRINGSET_VAII,
|
||||
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( 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 */
|
||||
511
thirdparty/freetype/src/autofit/aftypes.h
vendored
Normal file
511
thirdparty/freetype/src/autofit/aftypes.h
vendored
Normal file
@@ -0,0 +1,511 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* aftypes.h
|
||||
*
|
||||
* Auto-fitter types (specification only).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 <freetype/freetype.h>
|
||||
#include <freetype/ftoutln.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftdebug.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 subpixels */
|
||||
FT_Pos fit; /* current/fitted position/width in device subpixels */
|
||||
|
||||
} 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 );
|
||||
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
|
||||
typedef struct AF_ScalerRec_
|
||||
{
|
||||
FT_Face face; /* source font face */
|
||||
FT_Fixed x_scale; /* from font units to 1/64 device pixels */
|
||||
FT_Fixed y_scale; /* from font units to 1/64 device pixels */
|
||||
FT_Pos x_delta; /* in 1/64 device pixels */
|
||||
FT_Pos y_delta; /* in 1/64 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 FT_Error
|
||||
(*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.
|
||||
*/
|
||||
|
||||
#undef WRITING_SYSTEM
|
||||
#define WRITING_SYSTEM( ws, WS ) \
|
||||
AF_WRITING_SYSTEM_ ## WS,
|
||||
|
||||
/* The list of known writing systems. */
|
||||
typedef enum AF_WritingSystem_
|
||||
{
|
||||
|
||||
#include "afws-iter.h"
|
||||
|
||||
AF_WRITING_SYSTEM_MAX /* do not remove */
|
||||
|
||||
} AF_WritingSystem;
|
||||
|
||||
|
||||
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 */
|
||||
#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 \
|
||||
};
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* AFTYPES_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
33
thirdparty/freetype/src/autofit/afws-decl.h
vendored
Normal file
33
thirdparty/freetype/src/autofit/afws-decl.h
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afws-decl.h
|
||||
*
|
||||
* Auto-fitter writing system declarations (specification only).
|
||||
*
|
||||
* Copyright (C) 2013-2024 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 AFWS_DECL_H_
|
||||
#define AFWS_DECL_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"
|
||||
|
||||
#endif /* AFWS_DECL_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
31
thirdparty/freetype/src/autofit/afws-iter.h
vendored
Normal file
31
thirdparty/freetype/src/autofit/afws-iter.h
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* afws-iter.h
|
||||
*
|
||||
* Auto-fitter writing systems iterator (specification only).
|
||||
*
|
||||
* Copyright (C) 2013-2024 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 may 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 )
|
||||
|
||||
|
||||
/* END */
|
||||
35
thirdparty/freetype/src/autofit/autofit.c
vendored
Normal file
35
thirdparty/freetype/src/autofit/autofit.c
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* autofit.c
|
||||
*
|
||||
* Auto-fitter module (body).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#include "ft-hb.c"
|
||||
#include "afblue.c"
|
||||
#include "afcjk.c"
|
||||
#include "afdummy.c"
|
||||
#include "afglobal.c"
|
||||
#include "afhints.c"
|
||||
#include "afindic.c"
|
||||
#include "aflatin.c"
|
||||
#include "afloader.c"
|
||||
#include "afmodule.c"
|
||||
#include "afranges.c"
|
||||
#include "afshaper.c"
|
||||
|
||||
|
||||
/* END */
|
||||
115
thirdparty/freetype/src/autofit/ft-hb.c
vendored
Normal file
115
thirdparty/freetype/src/autofit/ft-hb.c
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright © 2009, 2023 Red Hat, Inc.
|
||||
* Copyright © 2015 Google, Inc.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod, Matthias Clasen
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include <freetype/freetype.h>
|
||||
#include <freetype/tttables.h>
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
|
||||
|
||||
#include "ft-hb.h"
|
||||
|
||||
/* The following three functions are a more or less verbatim
|
||||
* copy of corresponding HarfBuzz code from hb-ft.cc
|
||||
*/
|
||||
|
||||
static hb_blob_t *
|
||||
hb_ft_reference_table_ (hb_face_t *face, hb_tag_t tag, void *user_data)
|
||||
{
|
||||
FT_Face ft_face = (FT_Face) user_data;
|
||||
FT_Byte *buffer;
|
||||
FT_ULong length = 0;
|
||||
FT_Error error;
|
||||
|
||||
FT_UNUSED (face);
|
||||
|
||||
/* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */
|
||||
|
||||
error = FT_Load_Sfnt_Table (ft_face, tag, 0, NULL, &length);
|
||||
if (error)
|
||||
return NULL;
|
||||
|
||||
buffer = (FT_Byte *) ft_smalloc (length);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length);
|
||||
if (error)
|
||||
{
|
||||
free (buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return hb_blob_create ((const char *) buffer, length,
|
||||
HB_MEMORY_MODE_WRITABLE,
|
||||
buffer, ft_sfree);
|
||||
}
|
||||
|
||||
static hb_face_t *
|
||||
hb_ft_face_create_ (FT_Face ft_face,
|
||||
hb_destroy_func_t destroy)
|
||||
{
|
||||
hb_face_t *face;
|
||||
|
||||
if (!ft_face->stream->read) {
|
||||
hb_blob_t *blob;
|
||||
|
||||
blob = hb_blob_create ((const char *) ft_face->stream->base,
|
||||
(unsigned int) ft_face->stream->size,
|
||||
HB_MEMORY_MODE_READONLY,
|
||||
ft_face, destroy);
|
||||
face = hb_face_create (blob, ft_face->face_index);
|
||||
hb_blob_destroy (blob);
|
||||
} else {
|
||||
face = hb_face_create_for_tables (hb_ft_reference_table_, ft_face, destroy);
|
||||
}
|
||||
|
||||
hb_face_set_index (face, ft_face->face_index);
|
||||
hb_face_set_upem (face, ft_face->units_per_EM);
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
FT_LOCAL_DEF(hb_font_t *)
|
||||
hb_ft_font_create_ (FT_Face ft_face,
|
||||
hb_destroy_func_t destroy)
|
||||
{
|
||||
hb_font_t *font;
|
||||
hb_face_t *face;
|
||||
|
||||
face = hb_ft_face_create_ (ft_face, destroy);
|
||||
font = hb_font_create (face);
|
||||
hb_face_destroy (face);
|
||||
return font;
|
||||
}
|
||||
|
||||
#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
|
||||
|
||||
/* ANSI C doesn't like empty source files */
|
||||
typedef int ft_hb_dummy_;
|
||||
|
||||
#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
|
||||
|
||||
/* END */
|
||||
48
thirdparty/freetype/src/autofit/ft-hb.h
vendored
Normal file
48
thirdparty/freetype/src/autofit/ft-hb.h
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright © 2009, 2023 Red Hat, Inc.
|
||||
* Copyright © 2015 Google, Inc.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod, Matthias Clasen
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef FT_HB_H
|
||||
#define FT_HB_H
|
||||
|
||||
#include <hb.h>
|
||||
|
||||
#include <freetype/internal/compiler-macros.h>
|
||||
#include <freetype/freetype.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
FT_LOCAL(hb_font_t *)
|
||||
hb_ft_font_create_ (FT_Face ft_face,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* FT_HB_H */
|
||||
|
||||
|
||||
/* END */
|
||||
174
thirdparty/freetype/src/base/ftadvanc.c
vendored
Normal file
174
thirdparty/freetype/src/base/ftadvanc.c
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftadvanc.c
|
||||
*
|
||||
* Quick computation of advance widths (body).
|
||||
*
|
||||
* Copyright (C) 2008-2024 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 <freetype/internal/ftdebug.h>
|
||||
|
||||
#include <freetype/ftadvanc.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_face_scale_advances_( FT_Face face,
|
||||
FT_Fixed* advances,
|
||||
FT_UInt count,
|
||||
FT_Int32 flags )
|
||||
{
|
||||
FT_Fixed scale;
|
||||
FT_UInt nn;
|
||||
|
||||
|
||||
if ( flags & FT_LOAD_NO_SCALE )
|
||||
return FT_Err_Ok;
|
||||
|
||||
if ( !face->size )
|
||||
return FT_THROW( Invalid_Size_Handle );
|
||||
|
||||
if ( flags & FT_LOAD_VERTICAL_LAYOUT )
|
||||
scale = face->size->metrics.y_scale;
|
||||
else
|
||||
scale = face->size->metrics.x_scale;
|
||||
|
||||
/* this must be the same scaling as to get linear{Hori,Vert}Advance */
|
||||
/* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c) */
|
||||
|
||||
for ( nn = 0; nn < count; nn++ )
|
||||
advances[nn] = FT_MulDiv( advances[nn], scale, 64 );
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* at the moment, we can perform fast advance retrieval only in */
|
||||
/* the following cases: */
|
||||
/* */
|
||||
/* - unscaled load */
|
||||
/* - unhinted load */
|
||||
/* - light-hinted load */
|
||||
/* - if a variations font, it must have an `HVAR' or `VVAR' */
|
||||
/* table (thus the old MM or GX fonts don't qualify; this */
|
||||
/* gets checked by the driver-specific functions) */
|
||||
|
||||
#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 )
|
||||
|
||||
|
||||
/* documentation is in ftadvanc.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Advance( FT_Face face,
|
||||
FT_UInt gindex,
|
||||
FT_Int32 flags,
|
||||
FT_Fixed *padvance )
|
||||
{
|
||||
FT_Face_GetAdvancesFunc func;
|
||||
|
||||
|
||||
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( face, flags ) )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
error = func( face, gindex, 1, flags, padvance );
|
||||
if ( !error )
|
||||
return ft_face_scale_advances_( face, padvance, 1, flags );
|
||||
|
||||
if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
|
||||
return error;
|
||||
}
|
||||
|
||||
return FT_Get_Advances( face, gindex, 1, flags, padvance );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftadvanc.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Advances( FT_Face face,
|
||||
FT_UInt start,
|
||||
FT_UInt count,
|
||||
FT_Int32 flags,
|
||||
FT_Fixed *padvances )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
FT_Face_GetAdvancesFunc func;
|
||||
|
||||
FT_UInt num, end, nn;
|
||||
FT_Int factor;
|
||||
|
||||
|
||||
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 )
|
||||
return FT_THROW( Invalid_Glyph_Index );
|
||||
|
||||
if ( count == 0 )
|
||||
return FT_Err_Ok;
|
||||
|
||||
func = face->driver->clazz->get_advances;
|
||||
if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) )
|
||||
{
|
||||
error = func( face, start, count, flags, padvances );
|
||||
if ( !error )
|
||||
return ft_face_scale_advances_( face, padvances, count, flags );
|
||||
|
||||
if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
|
||||
return error;
|
||||
}
|
||||
|
||||
error = FT_Err_Ok;
|
||||
|
||||
if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
|
||||
flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
|
||||
factor = ( flags & FT_LOAD_NO_SCALE ) ? 1 : 1024;
|
||||
for ( nn = 0; nn < count; nn++ )
|
||||
{
|
||||
error = FT_Load_Glyph( face, start + nn, flags );
|
||||
if ( error )
|
||||
break;
|
||||
|
||||
/* scale from 26.6 to 16.16, unless NO_SCALE was requested */
|
||||
padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
|
||||
? face->glyph->advance.y * factor
|
||||
: face->glyph->advance.x * factor;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
41
thirdparty/freetype/src/base/ftbase.c
vendored
Normal file
41
thirdparty/freetype/src/base/ftbase.c
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftbase.c
|
||||
*
|
||||
* Single object library component (body only).
|
||||
*
|
||||
* Copyright (C) 1996-2024 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#include "ftadvanc.c"
|
||||
#include "ftcalc.c"
|
||||
#include "ftcolor.c"
|
||||
#include "ftdbgmem.c"
|
||||
#include "fterrors.c"
|
||||
#include "ftfntfmt.c"
|
||||
#include "ftgloadr.c"
|
||||
#include "fthash.c"
|
||||
#include "ftlcdfil.c"
|
||||
#include "ftmac.c"
|
||||
#include "ftobjs.c"
|
||||
#include "ftoutln.c"
|
||||
#include "ftpsprop.c"
|
||||
#include "ftrfork.c"
|
||||
#include "ftsnames.c"
|
||||
#include "ftstream.c"
|
||||
#include "fttrigon.c"
|
||||
#include "ftutil.c"
|
||||
|
||||
|
||||
/* END */
|
||||
82
thirdparty/freetype/src/base/ftbase.h
vendored
Normal file
82
thirdparty/freetype/src/base/ftbase.h
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftbase.h
|
||||
*
|
||||
* Private functions used in the `base' module (specification).
|
||||
*
|
||||
* Copyright (C) 2008-2024 by
|
||||
* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya.
|
||||
*
|
||||
* 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 FTBASE_H_
|
||||
#define FTBASE_H_
|
||||
|
||||
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_DECLARE_GLYPH( ft_bitmap_glyph_class )
|
||||
FT_DECLARE_GLYPH( ft_outline_glyph_class )
|
||||
FT_DECLARE_GLYPH( ft_svg_glyph_class )
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_MAC_FONTS
|
||||
|
||||
/* 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 )
|
||||
open_face_PS_from_sfnt_stream( FT_Library library,
|
||||
FT_Stream stream,
|
||||
FT_Long face_index,
|
||||
FT_Int num_params,
|
||||
FT_Parameter *params,
|
||||
FT_Face *aface );
|
||||
|
||||
|
||||
/* Create a new FT_Face given a buffer and a driver name. */
|
||||
/* From ftmac.c. */
|
||||
FT_LOCAL( FT_Error )
|
||||
open_face_from_buffer( FT_Library library,
|
||||
FT_Byte* base,
|
||||
FT_ULong size,
|
||||
FT_Long face_index,
|
||||
const char* driver_name,
|
||||
FT_Face *aface );
|
||||
|
||||
|
||||
#if defined( FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK ) && \
|
||||
!defined( FT_MACINTOSH )
|
||||
/* Mac OS X/Darwin kernel often changes recommended method to access */
|
||||
/* the resource fork and older methods makes the kernel issue the */
|
||||
/* warning of deprecated method. To calm it down, the methods based */
|
||||
/* on Darwin VFS should be grouped and skip the rest methods after */
|
||||
/* the case the resource is opened but found to lack a font in it. */
|
||||
FT_LOCAL( FT_Bool )
|
||||
ft_raccess_rule_by_darwin_vfs( FT_Library library, FT_UInt rule_index );
|
||||
#endif
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_MAC_FONTS */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* FTBASE_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
542
thirdparty/freetype/src/base/ftbbox.c
vendored
Normal file
542
thirdparty/freetype/src/base/ftbbox.c
vendored
Normal file
@@ -0,0 +1,542 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftbbox.c
|
||||
*
|
||||
* FreeType bbox computation (body).
|
||||
*
|
||||
* Copyright (C) 1996-2024 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 component has a _single_ role: to compute exact outline bounding
|
||||
* boxes.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
|
||||
#include <freetype/ftbbox.h>
|
||||
#include <freetype/ftimage.h>
|
||||
#include <freetype/ftoutln.h>
|
||||
#include <freetype/internal/ftcalc.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
|
||||
|
||||
typedef struct TBBox_Rec_
|
||||
{
|
||||
FT_Vector last;
|
||||
FT_BBox bbox;
|
||||
|
||||
} 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' emitter during
|
||||
* FT_Outline_Decompose(). It simply records the destination point
|
||||
* in `user->last'. We also update bbox in case contour starts with
|
||||
* an implicit `on' point.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
FT_CALLBACK_DEF( int )
|
||||
BBox_Move_To( const FT_Vector* to,
|
||||
void* user_ )
|
||||
{
|
||||
TBBox_Rec* user = (TBBox_Rec*)user_;
|
||||
|
||||
|
||||
FT_UPDATE_BBOX( to, user->bbox );
|
||||
|
||||
user->last = *to;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
FT_CALLBACK_DEF( int )
|
||||
BBox_Line_To( const FT_Vector* to,
|
||||
void* user_ )
|
||||
{
|
||||
TBBox_Rec* user = (TBBox_Rec*)user_;
|
||||
|
||||
|
||||
user->last = *to;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* BBox_Conic_Check
|
||||
*
|
||||
* @Description:
|
||||
* 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.
|
||||
*
|
||||
* @Input:
|
||||
* y1 ::
|
||||
* The start coordinate.
|
||||
*
|
||||
* y2 ::
|
||||
* The coordinate of the control point.
|
||||
*
|
||||
* y3 ::
|
||||
* The end coordinate.
|
||||
*
|
||||
* @InOut:
|
||||
* min ::
|
||||
* The address of the current minimum.
|
||||
*
|
||||
* max ::
|
||||
* The address of the current maximum.
|
||||
*/
|
||||
static void
|
||||
BBox_Conic_Check( FT_Pos y1,
|
||||
FT_Pos y2,
|
||||
FT_Pos y3,
|
||||
FT_Pos* min,
|
||||
FT_Pos* max )
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* BBox_Conic_To
|
||||
*
|
||||
* @Description:
|
||||
* This function is used as a `conic_to' emitter during
|
||||
* FT_Outline_Decompose(). It checks a conic Bezier curve with the
|
||||
* current bounding box, and computes its extrema if necessary to
|
||||
* update it.
|
||||
*
|
||||
* @Input:
|
||||
* control ::
|
||||
* A pointer to a control point.
|
||||
*
|
||||
* to ::
|
||||
* A pointer to the destination vector.
|
||||
*
|
||||
* @InOut:
|
||||
* user ::
|
||||
* The address of the current walk context.
|
||||
*
|
||||
* @Return:
|
||||
* Always 0. Needed for the interface only.
|
||||
*
|
||||
* @Note:
|
||||
* In the case of a non-monotonous arc, we compute directly the
|
||||
* extremum coordinates, as it is sufficiently fast.
|
||||
*/
|
||||
FT_CALLBACK_DEF( int )
|
||||
BBox_Conic_To( const FT_Vector* control,
|
||||
const FT_Vector* to,
|
||||
void* user_ )
|
||||
{
|
||||
TBBox_Rec* user = (TBBox_Rec*)user_;
|
||||
|
||||
|
||||
/* 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,
|
||||
control->x,
|
||||
to->x,
|
||||
&user->bbox.xMin,
|
||||
&user->bbox.xMax );
|
||||
|
||||
if ( CHECK_Y( control, user->bbox ) )
|
||||
BBox_Conic_Check( user->last.y,
|
||||
control->y,
|
||||
to->y,
|
||||
&user->bbox.yMin,
|
||||
&user->bbox.yMax );
|
||||
|
||||
user->last = *to;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* BBox_Cubic_Check
|
||||
*
|
||||
* @Description:
|
||||
* 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.
|
||||
*
|
||||
* p2 ::
|
||||
* The coordinate of the first control point.
|
||||
*
|
||||
* p3 ::
|
||||
* The coordinate of the second control point.
|
||||
*
|
||||
* p4 ::
|
||||
* The end coordinate.
|
||||
*
|
||||
* @InOut:
|
||||
* min ::
|
||||
* The address of the current minimum.
|
||||
*
|
||||
* 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;
|
||||
|
||||
|
||||
/* 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 ) ) );
|
||||
|
||||
if ( shift > 0 )
|
||||
{
|
||||
/* upscaling too much just wastes time */
|
||||
if ( shift > 2 )
|
||||
shift = 2;
|
||||
|
||||
q1 *= 1 << shift;
|
||||
q2 *= 1 << shift;
|
||||
q3 *= 1 << shift;
|
||||
q4 *= 1 << shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
q1 >>= -shift;
|
||||
q2 >>= -shift;
|
||||
q3 >>= -shift;
|
||||
q4 >>= -shift;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
{
|
||||
q4 = q4 + q3;
|
||||
q3 = q3 + q2;
|
||||
q2 = q2 + q1;
|
||||
q4 = q4 + q3;
|
||||
q3 = q3 + q2;
|
||||
q4 = ( q4 + q3 ) >> 3;
|
||||
q3 = q3 >> 2;
|
||||
q2 = q2 >> 1;
|
||||
}
|
||||
else /* second half */
|
||||
{
|
||||
q1 = q1 + q2;
|
||||
q2 = q2 + q3;
|
||||
q3 = q3 + q4;
|
||||
q1 = q1 + q2;
|
||||
q2 = q2 + q3;
|
||||
q1 = ( q1 + q2 ) >> 3;
|
||||
q2 = q2 >> 2;
|
||||
q3 = q3 >> 1;
|
||||
}
|
||||
|
||||
/* check whether either end reached the maximum */
|
||||
if ( q1 == q2 && q1 >= q3 )
|
||||
{
|
||||
peak = q1;
|
||||
break;
|
||||
}
|
||||
if ( q3 == q4 && q2 <= q4 )
|
||||
{
|
||||
peak = q4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( shift > 0 )
|
||||
peak >>= shift;
|
||||
else
|
||||
peak <<= -shift;
|
||||
|
||||
return peak;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
BBox_Cubic_Check( FT_Pos p1,
|
||||
FT_Pos p2,
|
||||
FT_Pos p3,
|
||||
FT_Pos p4,
|
||||
FT_Pos* min,
|
||||
FT_Pos* max )
|
||||
{
|
||||
/* 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. */
|
||||
|
||||
if ( p2 > *max || p3 > *max )
|
||||
*max += cubic_peak( p1 - *max, p2 - *max, p3 - *max, p4 - *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 );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* BBox_Cubic_To
|
||||
*
|
||||
* @Description:
|
||||
* This function is used as a `cubic_to' emitter during
|
||||
* FT_Outline_Decompose(). It checks a cubic Bezier curve with the
|
||||
* current bounding box, and computes its extrema if necessary to
|
||||
* update it.
|
||||
*
|
||||
* @Input:
|
||||
* control1 ::
|
||||
* A pointer to the first control point.
|
||||
*
|
||||
* control2 ::
|
||||
* A pointer to the second control point.
|
||||
*
|
||||
* to ::
|
||||
* A pointer to the destination vector.
|
||||
*
|
||||
* @InOut:
|
||||
* user ::
|
||||
* The address of the current walk context.
|
||||
*
|
||||
* @Return:
|
||||
* Always 0. Needed for the interface only.
|
||||
*
|
||||
* @Note:
|
||||
* In the case of a non-monotonous arc, we don't compute directly
|
||||
* extremum coordinates, we subdivide instead.
|
||||
*/
|
||||
FT_CALLBACK_DEF( int )
|
||||
BBox_Cubic_To( const FT_Vector* control1,
|
||||
const FT_Vector* control2,
|
||||
const FT_Vector* to,
|
||||
void* user_ )
|
||||
{
|
||||
TBBox_Rec* user = (TBBox_Rec*)user_;
|
||||
|
||||
|
||||
/* 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 ) )
|
||||
BBox_Cubic_Check( user->last.x,
|
||||
control1->x,
|
||||
control2->x,
|
||||
to->x,
|
||||
&user->bbox.xMin,
|
||||
&user->bbox.xMax );
|
||||
|
||||
if ( CHECK_Y( control1, user->bbox ) ||
|
||||
CHECK_Y( control2, user->bbox ) )
|
||||
BBox_Cubic_Check( user->last.y,
|
||||
control1->y,
|
||||
control2->y,
|
||||
to->y,
|
||||
&user->bbox.yMin,
|
||||
&user->bbox.yMax );
|
||||
|
||||
user->last = *to;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_DEFINE_OUTLINE_FUNCS(
|
||||
bbox_interface,
|
||||
|
||||
(FT_Outline_MoveTo_Func) BBox_Move_To, /* move_to */
|
||||
(FT_Outline_LineTo_Func) BBox_Line_To, /* line_to */
|
||||
(FT_Outline_ConicTo_Func)BBox_Conic_To, /* conic_to */
|
||||
(FT_Outline_CubicTo_Func)BBox_Cubic_To, /* cubic_to */
|
||||
0, /* shift */
|
||||
0 /* delta */
|
||||
)
|
||||
|
||||
|
||||
/* documentation is in ftbbox.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Outline_Get_BBox( FT_Outline* outline,
|
||||
FT_BBox *abbox )
|
||||
{
|
||||
FT_BBox cbox = { 0x7FFFFFFFL, 0x7FFFFFFFL,
|
||||
-0x7FFFFFFFL, -0x7FFFFFFFL };
|
||||
FT_BBox bbox = { 0x7FFFFFFFL, 0x7FFFFFFFL,
|
||||
-0x7FFFFFFFL, -0x7FFFFFFFL };
|
||||
FT_Vector* vec;
|
||||
FT_UShort n;
|
||||
|
||||
|
||||
if ( !abbox )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
if ( !outline )
|
||||
return FT_THROW( Invalid_Outline );
|
||||
|
||||
/* if outline is empty, return (0,0,0,0) */
|
||||
if ( outline->n_points == 0 || outline->n_contours == 0 )
|
||||
{
|
||||
abbox->xMin = abbox->xMax = 0;
|
||||
abbox->yMin = abbox->yMax = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We compute the control box as well as the bounding box of */
|
||||
/* all `on' points in the outline. Then, if the two boxes */
|
||||
/* coincide, we exit immediately. */
|
||||
|
||||
vec = outline->points;
|
||||
|
||||
for ( n = 0; n < outline->n_points; n++ )
|
||||
{
|
||||
FT_UPDATE_BBOX( vec, cbox );
|
||||
|
||||
if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON )
|
||||
FT_UPDATE_BBOX( vec, bbox );
|
||||
|
||||
vec++;
|
||||
}
|
||||
|
||||
/* test two boxes for equality */
|
||||
if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax ||
|
||||
cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax )
|
||||
{
|
||||
/* the two boxes are different, now walk over the outline to */
|
||||
/* get the Bezier arc extrema. */
|
||||
|
||||
FT_Error error;
|
||||
TBBox_Rec user;
|
||||
|
||||
|
||||
user.bbox = bbox;
|
||||
|
||||
error = FT_Outline_Decompose( outline, &bbox_interface, &user );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
*abbox = user.bbox;
|
||||
}
|
||||
else
|
||||
*abbox = bbox;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
90
thirdparty/freetype/src/base/ftbdf.c
vendored
Normal file
90
thirdparty/freetype/src/base/ftbdf.c
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftbdf.c
|
||||
*
|
||||
* FreeType API for accessing BDF-specific strings (body).
|
||||
*
|
||||
* Copyright (C) 2002-2024 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 <freetype/internal/ftdebug.h>
|
||||
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/services/svbdf.h>
|
||||
|
||||
|
||||
/* documentation is in ftbdf.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_BDF_Charset_ID( FT_Face face,
|
||||
const char* *acharset_encoding,
|
||||
const char* *acharset_registry )
|
||||
{
|
||||
FT_Error error;
|
||||
const char* encoding = NULL;
|
||||
const char* registry = NULL;
|
||||
|
||||
FT_Service_BDF service;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
FT_FACE_FIND_SERVICE( face, service, BDF );
|
||||
|
||||
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;
|
||||
|
||||
if ( acharset_registry )
|
||||
*acharset_registry = registry;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftbdf.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_BDF_Property( FT_Face face,
|
||||
const char* prop_name,
|
||||
BDF_PropertyRec *aproperty )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
FT_Service_BDF service;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
if ( !aproperty )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
aproperty->type = BDF_PROPERTY_TYPE_NONE;
|
||||
|
||||
FT_FACE_FIND_SERVICE( face, service, BDF );
|
||||
|
||||
if ( service && service->get_property )
|
||||
error = service->get_property( face, prop_name, aproperty );
|
||||
else
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
1144
thirdparty/freetype/src/base/ftbitmap.c
vendored
Normal file
1144
thirdparty/freetype/src/base/ftbitmap.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1126
thirdparty/freetype/src/base/ftcalc.c
vendored
Normal file
1126
thirdparty/freetype/src/base/ftcalc.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
117
thirdparty/freetype/src/base/ftcid.c
vendored
Normal file
117
thirdparty/freetype/src/base/ftcid.c
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcid.c
|
||||
*
|
||||
* FreeType API for accessing CID font information.
|
||||
*
|
||||
* Copyright (C) 2007-2024 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
|
||||
* 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 <freetype/ftcid.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/services/svcid.h>
|
||||
|
||||
|
||||
/* documentation is in ftcid.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_CID_Registry_Ordering_Supplement( FT_Face face,
|
||||
const char* *registry,
|
||||
const char* *ordering,
|
||||
FT_Int *supplement)
|
||||
{
|
||||
FT_Error error;
|
||||
const char* r = NULL;
|
||||
const char* o = NULL;
|
||||
FT_Int s = 0;
|
||||
|
||||
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
|
||||
if ( face )
|
||||
{
|
||||
FT_Service_CID service;
|
||||
|
||||
|
||||
FT_FACE_FIND_SERVICE( face, service, CID );
|
||||
|
||||
if ( service && service->get_ros )
|
||||
error = service->get_ros( face, &r, &o, &s );
|
||||
}
|
||||
|
||||
if ( registry )
|
||||
*registry = r;
|
||||
|
||||
if ( ordering )
|
||||
*ordering = o;
|
||||
|
||||
if ( supplement )
|
||||
*supplement = s;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face,
|
||||
FT_Bool *is_cid )
|
||||
{
|
||||
FT_Error error = FT_ERR( Invalid_Argument );
|
||||
FT_Bool ic = 0;
|
||||
|
||||
|
||||
if ( face )
|
||||
{
|
||||
FT_Service_CID service;
|
||||
|
||||
|
||||
FT_FACE_FIND_SERVICE( face, service, CID );
|
||||
|
||||
if ( service && service->get_is_cid )
|
||||
error = service->get_is_cid( face, &ic);
|
||||
}
|
||||
|
||||
if ( is_cid )
|
||||
*is_cid = ic;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_CID_From_Glyph_Index( FT_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_UInt *cid )
|
||||
{
|
||||
FT_Error error = FT_ERR( Invalid_Argument );
|
||||
FT_UInt c = 0;
|
||||
|
||||
|
||||
if ( face )
|
||||
{
|
||||
FT_Service_CID service;
|
||||
|
||||
|
||||
FT_FACE_FIND_SERVICE( face, service, CID );
|
||||
|
||||
if ( service && service->get_cid_from_glyph_index )
|
||||
error = service->get_cid_from_glyph_index( face, glyph_index, &c);
|
||||
}
|
||||
|
||||
if ( cid )
|
||||
*cid = c;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
156
thirdparty/freetype/src/base/ftcolor.c
vendored
Normal file
156
thirdparty/freetype/src/base/ftcolor.c
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcolor.c
|
||||
*
|
||||
* FreeType's glyph color management (body).
|
||||
*
|
||||
* Copyright (C) 2018-2024 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 <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/sfnt.h>
|
||||
#include <freetype/internal/tttypes.h>
|
||||
#include <freetype/ftcolor.h>
|
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
|
||||
|
||||
static
|
||||
const FT_Palette_Data null_palette_data = { 0, NULL, NULL, 0, NULL };
|
||||
|
||||
|
||||
/* documentation is in ftcolor.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Palette_Data_Get( FT_Face face,
|
||||
FT_Palette_Data *apalette_data )
|
||||
{
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
if ( !apalette_data)
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
if ( FT_IS_SFNT( face ) )
|
||||
*apalette_data = ( (TT_Face)face )->palette_data;
|
||||
else
|
||||
*apalette_data = null_palette_data;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcolor.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Palette_Select( FT_Face face,
|
||||
FT_UShort palette_index,
|
||||
FT_Color* *apalette )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
TT_Face ttface;
|
||||
SFNT_Service sfnt;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
if ( !FT_IS_SFNT( face ) )
|
||||
{
|
||||
if ( apalette )
|
||||
*apalette = NULL;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
ttface = (TT_Face)face;
|
||||
sfnt = (SFNT_Service)ttface->sfnt;
|
||||
|
||||
error = sfnt->set_palette( ttface, palette_index );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
ttface->palette_index = palette_index;
|
||||
|
||||
if ( apalette )
|
||||
*apalette = ttface->palette;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcolor.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Palette_Set_Foreground_Color( FT_Face face,
|
||||
FT_Color foreground_color )
|
||||
{
|
||||
TT_Face ttface;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
if ( !FT_IS_SFNT( face ) )
|
||||
return FT_Err_Ok;
|
||||
|
||||
ttface = (TT_Face)face;
|
||||
|
||||
ttface->foreground_color = foreground_color;
|
||||
ttface->have_foreground_color = 1;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
#else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Palette_Data_Get( FT_Face face,
|
||||
FT_Palette_Data *apalette_data )
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( apalette_data );
|
||||
|
||||
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Palette_Select( FT_Face face,
|
||||
FT_UShort palette_index,
|
||||
FT_Color* *apalette )
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( palette_index );
|
||||
FT_UNUSED( apalette );
|
||||
|
||||
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Palette_Set_Foreground_Color( FT_Face face,
|
||||
FT_Color foreground_color )
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( foreground_color );
|
||||
|
||||
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
#endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
|
||||
|
||||
|
||||
/* END */
|
||||
971
thirdparty/freetype/src/base/ftdbgmem.c
vendored
Normal file
971
thirdparty/freetype/src/base/ftdbgmem.c
vendored
Normal file
@@ -0,0 +1,971 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftdbgmem.c
|
||||
*
|
||||
* Memory debugger (body).
|
||||
*
|
||||
* Copyright (C) 2001-2024 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_CONFIG_CONFIG_H
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftmemory.h>
|
||||
#include <freetype/ftsystem.h>
|
||||
#include <freetype/fterrors.h>
|
||||
#include <freetype/fttypes.h>
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
|
||||
#define KEEPALIVE /* `Keep alive' means that freed blocks aren't released
|
||||
* to the heap. This is useful to detect double-frees
|
||||
* or weird heap corruption, but it uses large amounts of
|
||||
* memory, however.
|
||||
*/
|
||||
|
||||
#include FT_CONFIG_STANDARD_LIBRARY_H
|
||||
|
||||
FT_BASE_DEF( const char* ) ft_debug_file_ = NULL;
|
||||
FT_BASE_DEF( long ) ft_debug_lineno_ = 0;
|
||||
|
||||
extern void
|
||||
FT_DumpMemory( FT_Memory memory );
|
||||
|
||||
|
||||
typedef struct FT_MemSourceRec_* FT_MemSource;
|
||||
typedef struct FT_MemNodeRec_* FT_MemNode;
|
||||
typedef struct FT_MemTableRec_* FT_MemTable;
|
||||
|
||||
|
||||
#define FT_MEM_VAL( addr ) ( (FT_PtrDist)(FT_Pointer)( addr ) )
|
||||
|
||||
/*
|
||||
* This structure holds statistics for a single allocation/release
|
||||
* site. This is useful to know where memory operations happen the
|
||||
* most.
|
||||
*/
|
||||
typedef struct FT_MemSourceRec_
|
||||
{
|
||||
const char* file_name;
|
||||
long line_no;
|
||||
|
||||
FT_Long cur_blocks; /* current number of allocated blocks */
|
||||
FT_Long max_blocks; /* max. number of allocated blocks */
|
||||
FT_Long all_blocks; /* total number of blocks allocated */
|
||||
|
||||
FT_Long cur_size; /* current cumulative allocated size */
|
||||
FT_Long max_size; /* maximum cumulative allocated size */
|
||||
FT_Long all_size; /* total cumulative allocated size */
|
||||
|
||||
FT_Long cur_max; /* current maximum allocated size */
|
||||
|
||||
FT_UInt32 hash;
|
||||
FT_MemSource link;
|
||||
|
||||
} FT_MemSourceRec;
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* 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 a large memory footprint during execution.
|
||||
*/
|
||||
typedef struct FT_MemNodeRec_
|
||||
{
|
||||
FT_Byte* address;
|
||||
FT_Long size; /* < 0 if the block was freed */
|
||||
|
||||
FT_MemSource source;
|
||||
|
||||
#ifdef KEEPALIVE
|
||||
const char* free_file_name;
|
||||
FT_Long free_line_no;
|
||||
#endif
|
||||
|
||||
FT_MemNode link;
|
||||
|
||||
} FT_MemNodeRec;
|
||||
|
||||
|
||||
/*
|
||||
* The global structure, containing compound statistics and all hash
|
||||
* tables.
|
||||
*/
|
||||
typedef struct FT_MemTableRec_
|
||||
{
|
||||
FT_Long size;
|
||||
FT_Long nodes;
|
||||
FT_MemNode* buckets;
|
||||
|
||||
FT_Long alloc_total;
|
||||
FT_Long alloc_current;
|
||||
FT_Long alloc_max;
|
||||
FT_Long alloc_count;
|
||||
|
||||
FT_Bool bound_total;
|
||||
FT_Long alloc_total_max;
|
||||
|
||||
FT_Bool bound_count;
|
||||
FT_Long alloc_count_max;
|
||||
|
||||
FT_MemSource sources[FT_MEM_SOURCE_BUCKETS];
|
||||
|
||||
FT_Bool keep_alive;
|
||||
|
||||
FT_Memory memory;
|
||||
FT_Pointer memory_user;
|
||||
FT_Alloc_Func alloc;
|
||||
FT_Free_Func free;
|
||||
FT_Realloc_Func realloc;
|
||||
|
||||
} FT_MemTableRec;
|
||||
|
||||
|
||||
#define FT_MEM_SIZE_MIN 7
|
||||
#define FT_MEM_SIZE_MAX 13845163
|
||||
|
||||
#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_Int ft_mem_primes[] =
|
||||
{
|
||||
7,
|
||||
11,
|
||||
19,
|
||||
37,
|
||||
73,
|
||||
109,
|
||||
163,
|
||||
251,
|
||||
367,
|
||||
557,
|
||||
823,
|
||||
1237,
|
||||
1861,
|
||||
2777,
|
||||
4177,
|
||||
6247,
|
||||
9371,
|
||||
14057,
|
||||
21089,
|
||||
31627,
|
||||
47431,
|
||||
71143,
|
||||
106721,
|
||||
160073,
|
||||
240101,
|
||||
360163,
|
||||
540217,
|
||||
810343,
|
||||
1215497,
|
||||
1823231,
|
||||
2734867,
|
||||
4102283,
|
||||
6153409,
|
||||
9230113,
|
||||
13845163,
|
||||
};
|
||||
|
||||
|
||||
static FT_Long
|
||||
ft_mem_closest_prime( FT_Long num )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
||||
for ( i = 0;
|
||||
i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ )
|
||||
if ( ft_mem_primes[i] > num )
|
||||
return ft_mem_primes[i];
|
||||
|
||||
return FT_MEM_SIZE_MAX;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_debug_panic( const char* fmt,
|
||||
... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
printf( "FreeType.Debug: " );
|
||||
|
||||
va_start( ap, fmt );
|
||||
vprintf( fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
printf( "\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
|
||||
static FT_Pointer
|
||||
ft_mem_table_alloc( FT_MemTable table,
|
||||
FT_Long size )
|
||||
{
|
||||
FT_Memory memory = table->memory;
|
||||
FT_Pointer block;
|
||||
|
||||
|
||||
memory->user = table->memory_user;
|
||||
block = table->alloc( memory, size );
|
||||
memory->user = table;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_table_free( FT_MemTable table,
|
||||
FT_Pointer block )
|
||||
{
|
||||
FT_Memory memory = table->memory;
|
||||
|
||||
|
||||
memory->user = table->memory_user;
|
||||
table->free( memory, block );
|
||||
memory->user = table;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_table_resize( FT_MemTable table )
|
||||
{
|
||||
FT_Long new_size;
|
||||
|
||||
|
||||
new_size = ft_mem_closest_prime( table->nodes );
|
||||
if ( new_size != table->size )
|
||||
{
|
||||
FT_MemNode* new_buckets;
|
||||
FT_Long i;
|
||||
|
||||
|
||||
new_buckets = (FT_MemNode *)
|
||||
ft_mem_table_alloc(
|
||||
table,
|
||||
new_size * (FT_Long)sizeof ( FT_MemNode ) );
|
||||
if ( !new_buckets )
|
||||
return;
|
||||
|
||||
FT_ARRAY_ZERO( new_buckets, new_size );
|
||||
|
||||
for ( i = 0; i < table->size; i++ )
|
||||
{
|
||||
FT_MemNode node, next, *pnode;
|
||||
FT_PtrDist hash;
|
||||
|
||||
|
||||
node = table->buckets[i];
|
||||
while ( node )
|
||||
{
|
||||
next = node->link;
|
||||
hash = FT_MEM_VAL( node->address ) % (FT_PtrDist)new_size;
|
||||
pnode = new_buckets + hash;
|
||||
|
||||
node->link = pnode[0];
|
||||
pnode[0] = node;
|
||||
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
|
||||
if ( table->buckets )
|
||||
ft_mem_table_free( table, table->buckets );
|
||||
|
||||
table->buckets = new_buckets;
|
||||
table->size = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_table_destroy( FT_MemTable table )
|
||||
{
|
||||
FT_Long i;
|
||||
FT_Long leak_count = 0;
|
||||
FT_Long leaks = 0;
|
||||
|
||||
|
||||
/* remove all blocks from the table, revealing leaked ones */
|
||||
for ( i = 0; i < table->size; i++ )
|
||||
{
|
||||
FT_MemNode *pnode = table->buckets + i, next, node = *pnode;
|
||||
|
||||
|
||||
while ( node )
|
||||
{
|
||||
next = node->link;
|
||||
node->link = NULL;
|
||||
|
||||
if ( node->size > 0 )
|
||||
{
|
||||
printf(
|
||||
"leaked memory block at address %p, size %8ld in (%s:%ld)\n",
|
||||
(void*)node->address,
|
||||
node->size,
|
||||
FT_FILENAME( node->source->file_name ),
|
||||
node->source->line_no );
|
||||
|
||||
leak_count++;
|
||||
leaks += node->size;
|
||||
|
||||
ft_mem_table_free( table, node->address );
|
||||
}
|
||||
|
||||
node->address = NULL;
|
||||
node->size = 0;
|
||||
|
||||
ft_mem_table_free( table, node );
|
||||
node = next;
|
||||
}
|
||||
table->buckets[i] = NULL;
|
||||
}
|
||||
|
||||
ft_mem_table_free( table, table->buckets );
|
||||
table->buckets = NULL;
|
||||
|
||||
table->size = 0;
|
||||
table->nodes = 0;
|
||||
|
||||
/* remove all sources */
|
||||
for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ )
|
||||
{
|
||||
FT_MemSource source, next;
|
||||
|
||||
|
||||
for ( source = table->sources[i]; source != NULL; source = next )
|
||||
{
|
||||
next = source->link;
|
||||
ft_mem_table_free( table, source );
|
||||
}
|
||||
|
||||
table->sources[i] = NULL;
|
||||
}
|
||||
|
||||
printf( "FreeType: total memory allocations = %ld\n",
|
||||
table->alloc_total );
|
||||
printf( "FreeType: maximum memory footprint = %ld\n",
|
||||
table->alloc_max );
|
||||
|
||||
if ( leak_count > 0 )
|
||||
ft_mem_debug_panic(
|
||||
"FreeType: %ld bytes of memory leaked in %ld blocks\n",
|
||||
leaks, leak_count );
|
||||
|
||||
printf( "FreeType: no memory leaks detected\n" );
|
||||
}
|
||||
|
||||
|
||||
static FT_MemNode*
|
||||
ft_mem_table_get_nodep( FT_MemTable table,
|
||||
FT_Byte* address )
|
||||
{
|
||||
FT_PtrDist hash;
|
||||
FT_MemNode *pnode, node;
|
||||
|
||||
|
||||
hash = FT_MEM_VAL( address );
|
||||
pnode = table->buckets + ( hash % (FT_PtrDist)table->size );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
node = pnode[0];
|
||||
if ( !node )
|
||||
break;
|
||||
|
||||
if ( node->address == address )
|
||||
break;
|
||||
|
||||
pnode = &node->link;
|
||||
}
|
||||
return pnode;
|
||||
}
|
||||
|
||||
|
||||
static FT_MemSource
|
||||
ft_mem_table_get_source( FT_MemTable table )
|
||||
{
|
||||
FT_UInt32 hash;
|
||||
FT_MemSource node, *pnode;
|
||||
|
||||
|
||||
/* cast to FT_PtrDist first since void* can be larger */
|
||||
/* than FT_UInt32 and GCC 4.1.1 emits a warning */
|
||||
hash = (FT_UInt32)(FT_PtrDist)(void*)ft_debug_file_ +
|
||||
(FT_UInt32)( 5 * ft_debug_lineno_ );
|
||||
pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
node = *pnode;
|
||||
if ( !node )
|
||||
break;
|
||||
|
||||
if ( node->file_name == ft_debug_file_ &&
|
||||
node->line_no == ft_debug_lineno_ )
|
||||
goto Exit;
|
||||
|
||||
pnode = &node->link;
|
||||
}
|
||||
|
||||
node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) );
|
||||
if ( !node )
|
||||
ft_mem_debug_panic(
|
||||
"not enough memory to perform memory debugging\n" );
|
||||
|
||||
node->file_name = ft_debug_file_;
|
||||
node->line_no = ft_debug_lineno_;
|
||||
|
||||
node->cur_blocks = 0;
|
||||
node->max_blocks = 0;
|
||||
node->all_blocks = 0;
|
||||
|
||||
node->cur_size = 0;
|
||||
node->max_size = 0;
|
||||
node->all_size = 0;
|
||||
|
||||
node->cur_max = 0;
|
||||
|
||||
node->link = NULL;
|
||||
node->hash = hash;
|
||||
*pnode = node;
|
||||
|
||||
Exit:
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_table_set( FT_MemTable table,
|
||||
FT_Byte* address,
|
||||
FT_Long size,
|
||||
FT_Long delta )
|
||||
{
|
||||
FT_MemNode *pnode, node;
|
||||
|
||||
|
||||
if ( table )
|
||||
{
|
||||
FT_MemSource source;
|
||||
|
||||
|
||||
pnode = ft_mem_table_get_nodep( table, address );
|
||||
node = *pnode;
|
||||
if ( node )
|
||||
{
|
||||
if ( node->size < 0 )
|
||||
{
|
||||
/* This block was already freed. Our memory is now completely */
|
||||
/* corrupted! */
|
||||
/* This can only happen in keep-alive mode. */
|
||||
ft_mem_debug_panic(
|
||||
"memory heap corrupted (allocating freed block)" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This block was already allocated. This means that our memory */
|
||||
/* is also corrupted! */
|
||||
ft_mem_debug_panic(
|
||||
"memory heap corrupted (re-allocating allocated block at"
|
||||
" %p, of size %ld)\n"
|
||||
"org=%s:%d new=%s:%d\n",
|
||||
node->address, node->size,
|
||||
FT_FILENAME( node->source->file_name ), node->source->line_no,
|
||||
FT_FILENAME( ft_debug_file_ ), ft_debug_lineno_ );
|
||||
}
|
||||
}
|
||||
|
||||
/* we need to create a new node in this table */
|
||||
node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) );
|
||||
if ( !node )
|
||||
ft_mem_debug_panic( "not enough memory to run memory tests" );
|
||||
|
||||
node->address = address;
|
||||
node->size = size;
|
||||
node->source = source = ft_mem_table_get_source( table );
|
||||
|
||||
if ( delta == 0 )
|
||||
{
|
||||
/* this is an allocation */
|
||||
source->all_blocks++;
|
||||
source->cur_blocks++;
|
||||
if ( source->cur_blocks > source->max_blocks )
|
||||
source->max_blocks = source->cur_blocks;
|
||||
}
|
||||
|
||||
if ( size > source->cur_max )
|
||||
source->cur_max = size;
|
||||
|
||||
if ( delta != 0 )
|
||||
{
|
||||
/* we are growing or shrinking a reallocated block */
|
||||
source->cur_size += delta;
|
||||
table->alloc_current += delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we are allocating a new block */
|
||||
source->cur_size += size;
|
||||
table->alloc_current += size;
|
||||
}
|
||||
|
||||
source->all_size += size;
|
||||
|
||||
if ( source->cur_size > source->max_size )
|
||||
source->max_size = source->cur_size;
|
||||
|
||||
node->free_file_name = NULL;
|
||||
node->free_line_no = 0;
|
||||
|
||||
node->link = pnode[0];
|
||||
|
||||
pnode[0] = node;
|
||||
table->nodes++;
|
||||
|
||||
table->alloc_total += size;
|
||||
|
||||
if ( table->alloc_current > table->alloc_max )
|
||||
table->alloc_max = table->alloc_current;
|
||||
|
||||
if ( table->nodes * 3 < table->size ||
|
||||
table->size * 3 < table->nodes )
|
||||
ft_mem_table_resize( table );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_table_remove( FT_MemTable table,
|
||||
FT_Byte* address,
|
||||
FT_Long delta )
|
||||
{
|
||||
if ( table )
|
||||
{
|
||||
FT_MemNode *pnode, node;
|
||||
|
||||
|
||||
pnode = ft_mem_table_get_nodep( table, address );
|
||||
node = *pnode;
|
||||
if ( node )
|
||||
{
|
||||
FT_MemSource source;
|
||||
|
||||
|
||||
if ( node->size < 0 )
|
||||
ft_mem_debug_panic(
|
||||
"freeing memory block at %p more than once\n"
|
||||
" at (%s:%ld)!\n"
|
||||
" Block was allocated at (%s:%ld)\n"
|
||||
" and released at (%s:%ld).",
|
||||
address,
|
||||
FT_FILENAME( ft_debug_file_ ), ft_debug_lineno_,
|
||||
FT_FILENAME( node->source->file_name ), node->source->line_no,
|
||||
FT_FILENAME( node->free_file_name ), node->free_line_no );
|
||||
|
||||
/* scramble the node's content for additional safety */
|
||||
FT_MEM_SET( address, 0xF3, node->size );
|
||||
|
||||
if ( delta == 0 )
|
||||
{
|
||||
source = node->source;
|
||||
|
||||
source->cur_blocks--;
|
||||
source->cur_size -= node->size;
|
||||
|
||||
table->alloc_current -= node->size;
|
||||
}
|
||||
|
||||
if ( table->keep_alive )
|
||||
{
|
||||
/* we simply invert the node's size to indicate that the node */
|
||||
/* was freed. */
|
||||
node->size = -node->size;
|
||||
node->free_file_name = ft_debug_file_;
|
||||
node->free_line_no = ft_debug_lineno_;
|
||||
}
|
||||
else
|
||||
{
|
||||
table->nodes--;
|
||||
|
||||
*pnode = node->link;
|
||||
|
||||
node->size = 0;
|
||||
node->source = NULL;
|
||||
|
||||
ft_mem_table_free( table, node );
|
||||
|
||||
if ( table->nodes * 3 < table->size ||
|
||||
table->size * 3 < table->nodes )
|
||||
ft_mem_table_resize( table );
|
||||
}
|
||||
}
|
||||
else
|
||||
ft_mem_debug_panic(
|
||||
"trying to free unknown block at %p in (%s:%ld)\n",
|
||||
address,
|
||||
FT_FILENAME( ft_debug_file_ ), ft_debug_lineno_ );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static FT_Pointer
|
||||
ft_mem_debug_alloc( FT_Memory memory,
|
||||
FT_Long size )
|
||||
{
|
||||
FT_MemTable table = (FT_MemTable)memory->user;
|
||||
FT_Byte* block;
|
||||
|
||||
|
||||
if ( size <= 0 )
|
||||
ft_mem_debug_panic( "negative block size allocation (%ld)", size );
|
||||
|
||||
/* return NULL if the maximum number of allocations was reached */
|
||||
if ( table->bound_count &&
|
||||
table->alloc_count >= table->alloc_count_max )
|
||||
return NULL;
|
||||
|
||||
/* return NULL if this allocation would overflow the maximum heap 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, size, 0 );
|
||||
|
||||
table->alloc_count++;
|
||||
}
|
||||
|
||||
ft_debug_file_ = "<unknown>";
|
||||
ft_debug_lineno_ = 0;
|
||||
|
||||
return (FT_Pointer)block;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_mem_debug_free( FT_Memory memory,
|
||||
FT_Pointer block )
|
||||
{
|
||||
FT_MemTable table = (FT_MemTable)memory->user;
|
||||
|
||||
|
||||
if ( !block )
|
||||
ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
|
||||
FT_FILENAME( ft_debug_file_ ),
|
||||
ft_debug_lineno_ );
|
||||
|
||||
ft_mem_table_remove( table, (FT_Byte*)block, 0 );
|
||||
|
||||
if ( !table->keep_alive )
|
||||
ft_mem_table_free( table, block );
|
||||
|
||||
table->alloc_count--;
|
||||
|
||||
ft_debug_file_ = "<unknown>";
|
||||
ft_debug_lineno_ = 0;
|
||||
}
|
||||
|
||||
|
||||
static FT_Pointer
|
||||
ft_mem_debug_realloc( FT_Memory memory,
|
||||
FT_Long cur_size,
|
||||
FT_Long new_size,
|
||||
FT_Pointer block )
|
||||
{
|
||||
FT_MemTable table = (FT_MemTable)memory->user;
|
||||
FT_MemNode node, *pnode;
|
||||
FT_Pointer new_block;
|
||||
FT_Long delta;
|
||||
|
||||
const char* file_name = FT_FILENAME( ft_debug_file_ );
|
||||
FT_Long line_no = ft_debug_lineno_;
|
||||
|
||||
|
||||
/* unlikely, but possible */
|
||||
if ( new_size == cur_size )
|
||||
return block;
|
||||
|
||||
/* the following is valid according to ANSI C */
|
||||
#if 0
|
||||
if ( !block || !cur_size )
|
||||
ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)",
|
||||
file_name, line_no );
|
||||
#endif
|
||||
|
||||
/* while the following is allowed in ANSI C also, we abort since */
|
||||
/* such case should be handled by FreeType. */
|
||||
if ( new_size <= 0 )
|
||||
ft_mem_debug_panic(
|
||||
"trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)",
|
||||
block, cur_size, file_name, line_no );
|
||||
|
||||
/* check `cur_size' value */
|
||||
pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block );
|
||||
node = *pnode;
|
||||
if ( !node )
|
||||
ft_mem_debug_panic(
|
||||
"trying to reallocate unknown block at %p in (%s:%ld)",
|
||||
block, file_name, line_no );
|
||||
|
||||
if ( node->size <= 0 )
|
||||
ft_mem_debug_panic(
|
||||
"trying to reallocate freed block at %p in (%s:%ld)",
|
||||
block, file_name, line_no );
|
||||
|
||||
if ( node->size != cur_size )
|
||||
ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is "
|
||||
"%ld instead of %ld in (%s:%ld)",
|
||||
block, cur_size, node->size, file_name, line_no );
|
||||
|
||||
/* return NULL if the maximum number of allocations was reached */
|
||||
if ( table->bound_count &&
|
||||
table->alloc_count >= table->alloc_count_max )
|
||||
return NULL;
|
||||
|
||||
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 + delta > table->alloc_total_max )
|
||||
return NULL;
|
||||
|
||||
new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size );
|
||||
if ( !new_block )
|
||||
return NULL;
|
||||
|
||||
ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta );
|
||||
|
||||
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 );
|
||||
|
||||
ft_debug_file_ = "<unknown>";
|
||||
ft_debug_lineno_ = 0;
|
||||
|
||||
if ( !table->keep_alive )
|
||||
ft_mem_table_free( table, block );
|
||||
|
||||
return new_block;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
ft_mem_debug_init( FT_Memory memory )
|
||||
{
|
||||
FT_MemTable table;
|
||||
|
||||
|
||||
if ( !ft_getenv( "FT2_DEBUG_MEMORY" ) )
|
||||
return;
|
||||
|
||||
table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) );
|
||||
|
||||
if ( table )
|
||||
{
|
||||
FT_ZERO( table );
|
||||
|
||||
table->memory = memory;
|
||||
table->memory_user = memory->user;
|
||||
table->alloc = memory->alloc;
|
||||
table->realloc = memory->realloc;
|
||||
table->free = memory->free;
|
||||
|
||||
ft_mem_table_resize( table );
|
||||
|
||||
if ( table->size )
|
||||
{
|
||||
const char* p;
|
||||
|
||||
|
||||
memory->user = table;
|
||||
memory->alloc = ft_mem_debug_alloc;
|
||||
memory->realloc = ft_mem_debug_realloc;
|
||||
memory->free = ft_mem_debug_free;
|
||||
|
||||
p = ft_getenv( "FT2_ALLOC_TOTAL_MAX" );
|
||||
if ( p )
|
||||
{
|
||||
FT_Long total_max = ft_strtol( p, NULL, 10 );
|
||||
|
||||
|
||||
if ( total_max > 0 )
|
||||
{
|
||||
table->bound_total = 1;
|
||||
table->alloc_total_max = total_max;
|
||||
}
|
||||
}
|
||||
|
||||
p = ft_getenv( "FT2_ALLOC_COUNT_MAX" );
|
||||
if ( p )
|
||||
{
|
||||
FT_Long total_count = ft_strtol( p, NULL, 10 );
|
||||
|
||||
|
||||
if ( total_count > 0 )
|
||||
{
|
||||
table->bound_count = 1;
|
||||
table->alloc_count_max = total_count;
|
||||
}
|
||||
}
|
||||
|
||||
p = ft_getenv( "FT2_KEEP_ALIVE" );
|
||||
if ( p )
|
||||
{
|
||||
FT_Long keep_alive = ft_strtol( p, NULL, 10 );
|
||||
|
||||
|
||||
if ( keep_alive > 0 )
|
||||
table->keep_alive = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
memory->free( memory, table );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
ft_mem_debug_done( FT_Memory memory )
|
||||
{
|
||||
if ( memory->free == ft_mem_debug_free )
|
||||
{
|
||||
FT_MemTable table = (FT_MemTable)memory->user;
|
||||
|
||||
|
||||
FT_DumpMemory( memory );
|
||||
|
||||
ft_mem_table_destroy( table );
|
||||
|
||||
memory->free = table->free;
|
||||
memory->realloc = table->realloc;
|
||||
memory->alloc = table->alloc;
|
||||
memory->user = table->memory_user;
|
||||
|
||||
memory->free( memory, table );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_COMPARE_DEF( int )
|
||||
ft_mem_source_compare( const void* p1,
|
||||
const void* p2 )
|
||||
{
|
||||
FT_MemSource s1 = *(FT_MemSource*)p1;
|
||||
FT_MemSource s2 = *(FT_MemSource*)p2;
|
||||
|
||||
|
||||
if ( s2->max_size > s1->max_size )
|
||||
return 1;
|
||||
else if ( s2->max_size < s1->max_size )
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
FT_DumpMemory( FT_Memory memory )
|
||||
{
|
||||
if ( memory->free == ft_mem_debug_free )
|
||||
{
|
||||
FT_MemTable table = (FT_MemTable)memory->user;
|
||||
FT_MemSource* bucket = table->sources;
|
||||
FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS;
|
||||
FT_MemSource* sources;
|
||||
FT_Int nn, count;
|
||||
const char* fmt;
|
||||
|
||||
|
||||
count = 0;
|
||||
for ( ; bucket < limit; bucket++ )
|
||||
{
|
||||
FT_MemSource source = *bucket;
|
||||
|
||||
|
||||
for ( ; source; source = source->link )
|
||||
count++;
|
||||
}
|
||||
|
||||
sources = (FT_MemSource*)
|
||||
ft_mem_table_alloc(
|
||||
table, count * (FT_Long)sizeof ( *sources ) );
|
||||
|
||||
count = 0;
|
||||
for ( bucket = table->sources; bucket < limit; bucket++ )
|
||||
{
|
||||
FT_MemSource source = *bucket;
|
||||
|
||||
|
||||
for ( ; source; source = source->link )
|
||||
sources[count++] = source;
|
||||
}
|
||||
|
||||
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",
|
||||
table->alloc_current, table->alloc_max,
|
||||
table->alloc_total, table->alloc_count );
|
||||
printf( " block block sizes sizes sizes source\n" );
|
||||
printf( " count high sum highsum max location\n" );
|
||||
printf( "-------------------------------------------------\n" );
|
||||
|
||||
fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n";
|
||||
|
||||
for ( nn = 0; nn < count; nn++ )
|
||||
{
|
||||
FT_MemSource source = sources[nn];
|
||||
|
||||
|
||||
printf( fmt,
|
||||
source->cur_blocks, source->max_blocks,
|
||||
source->cur_size, source->max_size, source->cur_max,
|
||||
FT_FILENAME( source->file_name ),
|
||||
source->line_no );
|
||||
}
|
||||
printf( "------------------------------------------------\n" );
|
||||
|
||||
ft_mem_table_free( table, sources );
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !FT_DEBUG_MEMORY */
|
||||
|
||||
/* ANSI C doesn't like empty source files */
|
||||
typedef int debug_mem_dummy_;
|
||||
|
||||
#endif /* !FT_DEBUG_MEMORY */
|
||||
|
||||
|
||||
/* END */
|
||||
644
thirdparty/freetype/src/base/ftdebug.c
vendored
Normal file
644
thirdparty/freetype/src/base/ftdebug.c
vendored
Normal file
@@ -0,0 +1,644 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftdebug.c
|
||||
*
|
||||
* Debugging and logging component (body).
|
||||
*
|
||||
* Copyright (C) 1996-2024 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 component contains various macros and functions used to ease the
|
||||
* debugging of the FreeType engine. Its main purpose is in assertion
|
||||
* checking, tracing, and error detection.
|
||||
*
|
||||
* There are now three debugging modes:
|
||||
*
|
||||
* - trace mode
|
||||
*
|
||||
* Error and trace messages are sent to the log file (which can be the
|
||||
* standard error output).
|
||||
*
|
||||
* - error mode
|
||||
*
|
||||
* Only error messages are generated.
|
||||
*
|
||||
* - release mode:
|
||||
*
|
||||
* No error message is sent or generated. The code is free from any
|
||||
* debugging parts.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <freetype/freetype.h>
|
||||
#include <freetype/ftlogging.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LOGGING
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Variables used to control logging.
|
||||
*
|
||||
* 1. `ft_default_trace_level` stores the value of trace levels, which are
|
||||
* provided to FreeType using the `FT2_DEBUG` environment variable.
|
||||
*
|
||||
* 2. `ft_fileptr` stores the `FILE*` handle.
|
||||
*
|
||||
* 3. `ft_component` is a string that holds the name of `FT_COMPONENT`.
|
||||
*
|
||||
* 4. The flag `ft_component_flag` prints the name of `FT_COMPONENT` along
|
||||
* with the actual log message if set to true.
|
||||
*
|
||||
* 5. The flag `ft_timestamp_flag` prints time along with the actual log
|
||||
* message if set to ture.
|
||||
*
|
||||
* 6. `ft_have_newline_char` is used to differentiate between a log
|
||||
* message with and without a trailing newline character.
|
||||
*
|
||||
* 7. `ft_custom_trace_level` stores the custom trace level value, which
|
||||
* is provided by the user at run-time.
|
||||
*
|
||||
* We use `static` to avoid 'unused variable' warnings.
|
||||
*
|
||||
*/
|
||||
static const char* ft_default_trace_level = NULL;
|
||||
static FILE* ft_fileptr = NULL;
|
||||
static const char* ft_component = NULL;
|
||||
static FT_Bool ft_component_flag = FALSE;
|
||||
static FT_Bool ft_timestamp_flag = FALSE;
|
||||
static FT_Bool ft_have_newline_char = TRUE;
|
||||
static const char* ft_custom_trace_level = NULL;
|
||||
|
||||
/* declared in ftdebug.h */
|
||||
|
||||
dlg_handler ft_default_log_handler = NULL;
|
||||
FT_Custom_Log_Handler custom_output_handler = NULL;
|
||||
|
||||
#endif /* FT_DEBUG_LOGGING */
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_ERROR
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Message( const char* fmt,
|
||||
... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start( ap, fmt );
|
||||
vfprintf( stderr, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Panic( const char* fmt,
|
||||
... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start( ap, fmt );
|
||||
vfprintf( stderr, fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
|
||||
FT_BASE_DEF( int )
|
||||
FT_Throw( FT_Error error,
|
||||
int line,
|
||||
const char* file )
|
||||
{
|
||||
#if 0
|
||||
/* activating the code in this block makes FreeType very chatty */
|
||||
fprintf( stderr,
|
||||
"%s:%d: error 0x%02x: %s\n",
|
||||
file,
|
||||
line,
|
||||
error,
|
||||
FT_Error_String( error ) );
|
||||
#else
|
||||
FT_UNUSED( error );
|
||||
FT_UNUSED( line );
|
||||
FT_UNUSED( file );
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* FT_DEBUG_LEVEL_ERROR */
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
|
||||
/* array of trace levels, initialized to 0; */
|
||||
/* this gets adjusted at run-time */
|
||||
static int ft_trace_levels_enabled[trace_count];
|
||||
|
||||
/* array of trace levels, always initialized to 0 */
|
||||
static int ft_trace_levels_disabled[trace_count];
|
||||
|
||||
/* a pointer to either `ft_trace_levels_enabled' */
|
||||
/* or `ft_trace_levels_disabled' */
|
||||
int* ft_trace_levels;
|
||||
|
||||
/* define array of trace toggle names */
|
||||
#define FT_TRACE_DEF( x ) #x ,
|
||||
|
||||
static const char* ft_trace_toggles[trace_count + 1] =
|
||||
{
|
||||
#include <freetype/internal/fttrace.h>
|
||||
NULL
|
||||
};
|
||||
|
||||
#undef FT_TRACE_DEF
|
||||
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
|
||||
FT_BASE_DEF( FT_Int )
|
||||
FT_Trace_Get_Count( void )
|
||||
{
|
||||
return trace_count;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
|
||||
FT_BASE_DEF( const char * )
|
||||
FT_Trace_Get_Name( FT_Int idx )
|
||||
{
|
||||
int max = FT_Trace_Get_Count();
|
||||
|
||||
|
||||
if ( idx < max )
|
||||
return ft_trace_toggles[idx];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Trace_Disable( void )
|
||||
{
|
||||
ft_trace_levels = ft_trace_levels_disabled;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Trace_Enable( void )
|
||||
{
|
||||
ft_trace_levels = ft_trace_levels_enabled;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Initialize the tracing sub-system. This is done by retrieving the
|
||||
* value of the `FT2_DEBUG' environment variable. It must be a list of
|
||||
* toggles, separated by spaces, `;', or `,'. Example:
|
||||
*
|
||||
* export FT2_DEBUG="any:3 memory:7 stream:5"
|
||||
*
|
||||
* This requests that all levels be set to 3, except the trace level for
|
||||
* 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.
|
||||
*
|
||||
* The level must be between 0 and 7; 0 means quiet (except for serious
|
||||
* runtime errors), and 7 means _very_ verbose.
|
||||
*/
|
||||
FT_BASE_DEF( void )
|
||||
ft_debug_init( void )
|
||||
{
|
||||
const char* ft2_debug = NULL;
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LOGGING
|
||||
if ( ft_custom_trace_level != NULL )
|
||||
ft2_debug = ft_custom_trace_level;
|
||||
else
|
||||
ft2_debug = ft_default_trace_level;
|
||||
#else
|
||||
ft2_debug = ft_getenv( "FT2_DEBUG" );
|
||||
#endif
|
||||
|
||||
if ( ft2_debug )
|
||||
{
|
||||
const char* p = ft2_debug;
|
||||
const char* q;
|
||||
|
||||
|
||||
for ( ; *p; p++ )
|
||||
{
|
||||
/* skip leading whitespace and separators */
|
||||
if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )
|
||||
continue;
|
||||
|
||||
#ifdef FT_DEBUG_LOGGING
|
||||
|
||||
/* check extra arguments for logging */
|
||||
if ( *p == '-' )
|
||||
{
|
||||
const char* r = ++p;
|
||||
|
||||
|
||||
if ( *r == 'v' )
|
||||
{
|
||||
const char* s = ++r;
|
||||
|
||||
|
||||
ft_component_flag = TRUE;
|
||||
|
||||
if ( *s == 't' )
|
||||
{
|
||||
ft_timestamp_flag = TRUE;
|
||||
p++;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
else if ( *r == 't' )
|
||||
{
|
||||
const char* s = ++r;
|
||||
|
||||
|
||||
ft_timestamp_flag = TRUE;
|
||||
|
||||
if ( *s == 'v' )
|
||||
{
|
||||
ft_component_flag = TRUE;
|
||||
p++;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FT_DEBUG_LOGGING */
|
||||
|
||||
/* read toggle name, followed by ':' */
|
||||
q = p;
|
||||
while ( *p && *p != ':' )
|
||||
p++;
|
||||
|
||||
if ( !*p )
|
||||
break;
|
||||
|
||||
if ( *p == ':' && p > q )
|
||||
{
|
||||
FT_Int n, i, len = (FT_Int)( p - q );
|
||||
FT_Int level = -1, found = -1;
|
||||
|
||||
|
||||
for ( n = 0; n < trace_count; n++ )
|
||||
{
|
||||
const char* toggle = ft_trace_toggles[n];
|
||||
|
||||
|
||||
for ( i = 0; i < len; i++ )
|
||||
{
|
||||
if ( toggle[i] != q[i] )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( i == len && toggle[i] == 0 )
|
||||
{
|
||||
found = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* read level */
|
||||
p++;
|
||||
if ( *p )
|
||||
{
|
||||
level = *p - '0';
|
||||
if ( level < 0 || level > 7 )
|
||||
level = -1;
|
||||
}
|
||||
|
||||
if ( found >= 0 && level >= 0 )
|
||||
{
|
||||
if ( found == trace_any )
|
||||
{
|
||||
/* special case for `any' */
|
||||
for ( n = 0; n < trace_count; n++ )
|
||||
ft_trace_levels_enabled[n] = level;
|
||||
}
|
||||
else
|
||||
ft_trace_levels_enabled[found] = level;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ft_trace_levels = ft_trace_levels_enabled;
|
||||
}
|
||||
|
||||
|
||||
#else /* !FT_DEBUG_LEVEL_TRACE */
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
ft_debug_init( void )
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Int )
|
||||
FT_Trace_Get_Count( void )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( const char * )
|
||||
FT_Trace_Get_Name( FT_Int idx )
|
||||
{
|
||||
FT_UNUSED( idx );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Trace_Disable( void )
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Trace_Enable( void )
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
#endif /* !FT_DEBUG_LEVEL_TRACE */
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LOGGING
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Initialize and de-initialize 'dlg' library.
|
||||
*
|
||||
*/
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
ft_logging_init( void )
|
||||
{
|
||||
ft_default_log_handler = ft_log_handler;
|
||||
ft_default_trace_level = ft_getenv( "FT2_DEBUG" );
|
||||
|
||||
if ( ft_getenv( "FT_LOGGING_FILE" ) )
|
||||
ft_fileptr = ft_fopen( ft_getenv( "FT_LOGGING_FILE" ), "w" );
|
||||
else
|
||||
ft_fileptr = stderr;
|
||||
|
||||
ft_debug_init();
|
||||
|
||||
/* Set the default output handler for 'dlg'. */
|
||||
dlg_set_handler( ft_default_log_handler, NULL );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
ft_logging_deinit( void )
|
||||
{
|
||||
if ( ft_fileptr != stderr )
|
||||
ft_fclose( ft_fileptr );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* An output log handler for FreeType.
|
||||
*
|
||||
*/
|
||||
FT_BASE_DEF( void )
|
||||
ft_log_handler( const struct dlg_origin* origin,
|
||||
const char* string,
|
||||
void* data )
|
||||
{
|
||||
char features_buf[128];
|
||||
char* bufp = features_buf;
|
||||
|
||||
FT_UNUSED( data );
|
||||
|
||||
|
||||
if ( ft_have_newline_char )
|
||||
{
|
||||
const char* features = NULL;
|
||||
size_t features_length = 0;
|
||||
|
||||
|
||||
#define FEATURES_TIMESTAMP "[%h:%m] "
|
||||
#define FEATURES_COMPONENT "[%t] "
|
||||
#define FEATURES_TIMESTAMP_COMPONENT "[%h:%m %t] "
|
||||
|
||||
if ( ft_timestamp_flag && ft_component_flag )
|
||||
{
|
||||
features = FEATURES_TIMESTAMP_COMPONENT;
|
||||
features_length = sizeof ( FEATURES_TIMESTAMP_COMPONENT );
|
||||
}
|
||||
else if ( ft_timestamp_flag )
|
||||
{
|
||||
features = FEATURES_TIMESTAMP;
|
||||
features_length = sizeof ( FEATURES_TIMESTAMP );
|
||||
}
|
||||
else if ( ft_component_flag )
|
||||
{
|
||||
features = FEATURES_COMPONENT;
|
||||
features_length = sizeof ( FEATURES_COMPONENT );
|
||||
}
|
||||
|
||||
if ( ft_component_flag || ft_timestamp_flag )
|
||||
{
|
||||
ft_strncpy( features_buf, features, features_length );
|
||||
bufp += features_length - 1;
|
||||
}
|
||||
|
||||
if ( ft_component_flag )
|
||||
{
|
||||
size_t tag_length = ft_strlen( *origin->tags );
|
||||
size_t i;
|
||||
|
||||
|
||||
/* To vertically align tracing messages we compensate the */
|
||||
/* different FT_COMPONENT string lengths by inserting an */
|
||||
/* appropriate amount of space characters. */
|
||||
for ( i = 0;
|
||||
i < FT_MAX_TRACE_LEVEL_LENGTH - tag_length;
|
||||
i++ )
|
||||
*bufp++ = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally add the format string for the tracing message. */
|
||||
*bufp++ = '%';
|
||||
*bufp++ = 'c';
|
||||
*bufp = '\0';
|
||||
|
||||
dlg_generic_outputf_stream( ft_fileptr,
|
||||
(const char*)features_buf,
|
||||
origin,
|
||||
string,
|
||||
dlg_default_output_styles,
|
||||
true );
|
||||
|
||||
if ( ft_strrchr( string, '\n' ) )
|
||||
ft_have_newline_char = TRUE;
|
||||
else
|
||||
ft_have_newline_char = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
FT_BASE_DEF( void )
|
||||
ft_add_tag( const char* tag )
|
||||
{
|
||||
ft_component = tag;
|
||||
|
||||
dlg_add_tag( tag, NULL );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
FT_BASE_DEF( void )
|
||||
ft_remove_tag( const char* tag )
|
||||
{
|
||||
dlg_remove_tag( tag, NULL );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlogging.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Trace_Set_Level( const char* level )
|
||||
{
|
||||
ft_component_flag = FALSE;
|
||||
ft_timestamp_flag = FALSE;
|
||||
ft_custom_trace_level = level;
|
||||
|
||||
ft_debug_init();
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlogging.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Trace_Set_Default_Level( void )
|
||||
{
|
||||
ft_component_flag = FALSE;
|
||||
ft_timestamp_flag = FALSE;
|
||||
ft_custom_trace_level = NULL;
|
||||
|
||||
ft_debug_init();
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Functions to handle a custom log handler.
|
||||
*
|
||||
*/
|
||||
|
||||
/* documentation is in ftlogging.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Set_Log_Handler( FT_Custom_Log_Handler handler )
|
||||
{
|
||||
custom_output_handler = handler;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlogging.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Set_Default_Log_Handler( void )
|
||||
{
|
||||
custom_output_handler = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftdebug.h */
|
||||
FT_BASE_DEF( void )
|
||||
FT_Logging_Callback( const char* fmt,
|
||||
... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start( ap, fmt );
|
||||
custom_output_handler( ft_component, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
#else /* !FT_DEBUG_LOGGING */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Trace_Set_Level( const char* level )
|
||||
{
|
||||
FT_UNUSED( level );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Trace_Set_Default_Level( void )
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Set_Log_Handler( FT_Custom_Log_Handler handler )
|
||||
{
|
||||
FT_UNUSED( handler );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Set_Default_Log_Handler( void )
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
#endif /* !FT_DEBUG_LOGGING */
|
||||
|
||||
|
||||
/* END */
|
||||
45
thirdparty/freetype/src/base/fterrors.c
vendored
Normal file
45
thirdparty/freetype/src/base/fterrors.c
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* fterrors.c
|
||||
*
|
||||
* FreeType API for error code handling.
|
||||
*
|
||||
* Copyright (C) 2018-2024 by
|
||||
* Armin Hasitzka, 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 <freetype/internal/ftdebug.h>
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
|
||||
/* documentation is in fterrors.h */
|
||||
|
||||
FT_EXPORT_DEF( const char* )
|
||||
FT_Error_String( FT_Error error_code )
|
||||
{
|
||||
if ( error_code < 0 ||
|
||||
error_code >= FT_ERR_CAT( FT_ERR_PREFIX, Max ) )
|
||||
return NULL;
|
||||
|
||||
#if defined( FT_CONFIG_OPTION_ERROR_STRINGS ) || \
|
||||
defined( FT_DEBUG_LEVEL_ERROR )
|
||||
|
||||
#undef FTERRORS_H_
|
||||
#define FT_ERROR_START_LIST switch ( FT_ERROR_BASE( error_code ) ) {
|
||||
#define FT_ERRORDEF( e, v, s ) case v: return s;
|
||||
#define FT_ERROR_END_LIST }
|
||||
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
#endif /* defined( FT_CONFIG_OPTION_ERROR_STRINGS ) || ... */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
54
thirdparty/freetype/src/base/ftfntfmt.c
vendored
Normal file
54
thirdparty/freetype/src/base/ftfntfmt.c
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftfntfmt.c
|
||||
*
|
||||
* FreeType utility file for font formats (body).
|
||||
*
|
||||
* Copyright (C) 2002-2024 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 <freetype/ftfntfmt.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/services/svfntfmt.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 )
|
||||
{
|
||||
const char* result = NULL;
|
||||
|
||||
|
||||
if ( face )
|
||||
FT_FACE_FIND_SERVICE( face, result, FONT_FORMAT );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
61
thirdparty/freetype/src/base/ftfstype.c
vendored
Normal file
61
thirdparty/freetype/src/base/ftfstype.c
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftfstype.c
|
||||
*
|
||||
* FreeType utility file to access FSType data (body).
|
||||
*
|
||||
* Copyright (C) 2008-2024 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 <freetype/t1tables.h>
|
||||
#include <freetype/tttables.h>
|
||||
#include <freetype/internal/ftserv.h>
|
||||
#include <freetype/internal/services/svpsinfo.h>
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_UShort )
|
||||
FT_Get_FSType_Flags( FT_Face face )
|
||||
{
|
||||
TT_OS2* os2;
|
||||
|
||||
|
||||
/* first, try to get the fs_type directly from the font */
|
||||
if ( face )
|
||||
{
|
||||
FT_Service_PsInfo service = NULL;
|
||||
|
||||
|
||||
FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
|
||||
|
||||
if ( service && service->ps_get_font_extra )
|
||||
{
|
||||
PS_FontExtraRec extra;
|
||||
|
||||
|
||||
if ( !service->ps_get_font_extra( face, &extra ) &&
|
||||
extra.fs_type != 0 )
|
||||
return extra.fs_type;
|
||||
}
|
||||
}
|
||||
|
||||
/* look at FSType before fsType for Type42 */
|
||||
|
||||
if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, FT_SFNT_OS2 ) ) != NULL &&
|
||||
os2->version != 0xFFFFU )
|
||||
return os2->fsType;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
60
thirdparty/freetype/src/base/ftgasp.c
vendored
Normal file
60
thirdparty/freetype/src/base/ftgasp.c
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftgasp.c
|
||||
*
|
||||
* Access of TrueType's `gasp' table (body).
|
||||
*
|
||||
* Copyright (C) 2007-2024 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 <freetype/ftgasp.h>
|
||||
#include <freetype/internal/tttypes.h>
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Int )
|
||||
FT_Get_Gasp( FT_Face face,
|
||||
FT_UInt ppem )
|
||||
{
|
||||
FT_Int result = FT_GASP_NO_TABLE;
|
||||
|
||||
|
||||
if ( face && FT_IS_SFNT( face ) )
|
||||
{
|
||||
TT_Face ttface = (TT_Face)face;
|
||||
|
||||
|
||||
if ( ttface->gasp.numRanges > 0 )
|
||||
{
|
||||
TT_GaspRange range = ttface->gasp.gaspRanges;
|
||||
TT_GaspRange range_end = range + ttface->gasp.numRanges;
|
||||
|
||||
|
||||
while ( ppem > range->maxPPEM )
|
||||
{
|
||||
range++;
|
||||
if ( range >= range_end )
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
result = range->gaspFlag;
|
||||
|
||||
/* ensure that we don't have spurious bits */
|
||||
if ( ttface->gasp.version == 0 )
|
||||
result &= 3;
|
||||
}
|
||||
}
|
||||
Exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
383
thirdparty/freetype/src/base/ftgloadr.c
vendored
Normal file
383
thirdparty/freetype/src/base/ftgloadr.c
vendored
Normal file
@@ -0,0 +1,383 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftgloadr.c
|
||||
*
|
||||
* The FreeType glyph loader (body).
|
||||
*
|
||||
* Copyright (C) 2002-2024 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 <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftgloadr.h>
|
||||
#include <freetype/internal/ftmemory.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT gloader
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** *****/
|
||||
/***** G L Y P H L O A D E R *****/
|
||||
/***** *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* The glyph loader is a simple object which is used to load a set of
|
||||
* glyphs easily. It is critical for the correct loading of composites.
|
||||
*
|
||||
* Ideally, one can see it as a stack of abstract `glyph' objects.
|
||||
*
|
||||
* loader.base Is really the bottom of the stack. It describes a
|
||||
* single glyph image made of the juxtaposition of
|
||||
* several glyphs (those `in the stack').
|
||||
*
|
||||
* loader.current Describes the top of the stack, on which a new
|
||||
* glyph can be loaded.
|
||||
*
|
||||
* Rewind Clears the stack.
|
||||
* Prepare Set up `loader.current' for addition of a new glyph
|
||||
* image.
|
||||
* Add Add the `current' glyph image to the `base' one,
|
||||
* and prepare for another one.
|
||||
*
|
||||
* The glyph loader is now a base object. Each driver used to
|
||||
* re-implement it in one way or the other, which wasted code and
|
||||
* energy.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* create a new glyph loader */
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_GlyphLoader_New( FT_Memory memory,
|
||||
FT_GlyphLoader *aloader )
|
||||
{
|
||||
FT_GlyphLoader loader = NULL;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
if ( !FT_NEW( loader ) )
|
||||
{
|
||||
loader->memory = memory;
|
||||
*aloader = loader;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* rewind the glyph loader - reset counters to 0 */
|
||||
FT_BASE_DEF( void )
|
||||
FT_GlyphLoader_Rewind( FT_GlyphLoader loader )
|
||||
{
|
||||
FT_GlyphLoad base = &loader->base;
|
||||
FT_GlyphLoad current = &loader->current;
|
||||
|
||||
|
||||
base->outline.n_points = 0;
|
||||
base->outline.n_contours = 0;
|
||||
base->outline.flags = 0;
|
||||
base->num_subglyphs = 0;
|
||||
|
||||
*current = *base;
|
||||
}
|
||||
|
||||
|
||||
/* reset glyph loader, free all allocated tables, */
|
||||
/* and start from zero */
|
||||
FT_BASE_DEF( void )
|
||||
FT_GlyphLoader_Reset( FT_GlyphLoader loader )
|
||||
{
|
||||
FT_Memory memory = loader->memory;
|
||||
|
||||
|
||||
FT_FREE( loader->base.outline.points );
|
||||
FT_FREE( loader->base.outline.tags );
|
||||
FT_FREE( loader->base.outline.contours );
|
||||
FT_FREE( loader->base.extra_points );
|
||||
FT_FREE( loader->base.subglyphs );
|
||||
|
||||
loader->base.extra_points2 = NULL;
|
||||
|
||||
loader->max_points = 0;
|
||||
loader->max_contours = 0;
|
||||
loader->max_subglyphs = 0;
|
||||
|
||||
FT_GlyphLoader_Rewind( loader );
|
||||
}
|
||||
|
||||
|
||||
/* delete a glyph loader */
|
||||
FT_BASE_DEF( void )
|
||||
FT_GlyphLoader_Done( FT_GlyphLoader loader )
|
||||
{
|
||||
if ( loader )
|
||||
{
|
||||
FT_Memory memory = loader->memory;
|
||||
|
||||
|
||||
FT_GlyphLoader_Reset( loader );
|
||||
FT_FREE( loader );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* re-adjust the `current' outline fields */
|
||||
static void
|
||||
FT_GlyphLoader_Adjust_Points( FT_GlyphLoader loader )
|
||||
{
|
||||
FT_Outline* base = &loader->base.outline;
|
||||
FT_Outline* current = &loader->current.outline;
|
||||
|
||||
|
||||
current->points = FT_OFFSET( base->points, base->n_points );
|
||||
current->tags = FT_OFFSET( base->tags, base->n_points );
|
||||
current->contours = FT_OFFSET( base->contours, base->n_contours );
|
||||
|
||||
/* handle extra points table - if any */
|
||||
if ( loader->use_extra )
|
||||
{
|
||||
loader->current.extra_points = loader->base.extra_points +
|
||||
base->n_points;
|
||||
|
||||
loader->current.extra_points2 = loader->base.extra_points2 +
|
||||
base->n_points;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory = loader->memory;
|
||||
|
||||
|
||||
if ( loader->max_points == 0 ||
|
||||
loader->base.extra_points != NULL )
|
||||
return FT_Err_Ok;
|
||||
|
||||
if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
|
||||
{
|
||||
loader->use_extra = 1;
|
||||
loader->base.extra_points2 = loader->base.extra_points +
|
||||
loader->max_points;
|
||||
|
||||
FT_GlyphLoader_Adjust_Points( loader );
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* re-adjust the `current' subglyphs field */
|
||||
static void
|
||||
FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader loader )
|
||||
{
|
||||
FT_GlyphLoad base = &loader->base;
|
||||
FT_GlyphLoad current = &loader->current;
|
||||
|
||||
|
||||
current->subglyphs = FT_OFFSET( base->subglyphs, base->num_subglyphs );
|
||||
}
|
||||
|
||||
|
||||
/* Ensure that we can add `n_points' and `n_contours' to our glyph. */
|
||||
/* This function reallocates its outline tables if necessary. Note that */
|
||||
/* it DOESN'T change the number of points within the loader! */
|
||||
/* */
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader,
|
||||
FT_UInt n_points,
|
||||
FT_UInt n_contours )
|
||||
{
|
||||
FT_Memory memory = loader->memory;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Outline* base = &loader->base.outline;
|
||||
FT_Outline* current = &loader->current.outline;
|
||||
FT_Bool adjust = 0;
|
||||
|
||||
FT_UInt new_max, old_max, min_new_max;
|
||||
|
||||
|
||||
error = FT_GlyphLoader_CreateExtra( loader );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* check points & tags */
|
||||
new_max = (FT_UInt)base->n_points + (FT_UInt)current->n_points +
|
||||
n_points;
|
||||
old_max = loader->max_points;
|
||||
|
||||
if ( new_max > old_max )
|
||||
{
|
||||
if ( new_max > FT_OUTLINE_POINTS_MAX )
|
||||
{
|
||||
error = FT_THROW( Array_Too_Large );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
min_new_max = old_max + ( old_max >> 1 );
|
||||
if ( new_max < min_new_max )
|
||||
new_max = min_new_max;
|
||||
new_max = FT_PAD_CEIL( new_max, 8 );
|
||||
if ( new_max > FT_OUTLINE_POINTS_MAX )
|
||||
new_max = FT_OUTLINE_POINTS_MAX;
|
||||
|
||||
if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
|
||||
FT_RENEW_ARRAY( base->tags, old_max, new_max ) )
|
||||
goto Exit;
|
||||
|
||||
if ( loader->use_extra )
|
||||
{
|
||||
if ( FT_RENEW_ARRAY( loader->base.extra_points,
|
||||
old_max * 2, new_max * 2 ) )
|
||||
goto Exit;
|
||||
|
||||
FT_ARRAY_MOVE( loader->base.extra_points + new_max,
|
||||
loader->base.extra_points + old_max,
|
||||
old_max );
|
||||
|
||||
loader->base.extra_points2 = loader->base.extra_points + new_max;
|
||||
}
|
||||
|
||||
adjust = 1;
|
||||
loader->max_points = new_max;
|
||||
}
|
||||
|
||||
error = FT_GlyphLoader_CreateExtra( loader );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* check contours */
|
||||
old_max = loader->max_contours;
|
||||
new_max = (FT_UInt)base->n_contours + (FT_UInt)current->n_contours +
|
||||
n_contours;
|
||||
if ( new_max > old_max )
|
||||
{
|
||||
if ( new_max > FT_OUTLINE_CONTOURS_MAX )
|
||||
{
|
||||
error = FT_THROW( Array_Too_Large );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
min_new_max = old_max + ( old_max >> 1 );
|
||||
if ( new_max < min_new_max )
|
||||
new_max = min_new_max;
|
||||
new_max = FT_PAD_CEIL( new_max, 4 );
|
||||
if ( new_max > FT_OUTLINE_CONTOURS_MAX )
|
||||
new_max = FT_OUTLINE_CONTOURS_MAX;
|
||||
|
||||
if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
|
||||
goto Exit;
|
||||
|
||||
adjust = 1;
|
||||
loader->max_contours = new_max;
|
||||
}
|
||||
|
||||
if ( adjust )
|
||||
FT_GlyphLoader_Adjust_Points( loader );
|
||||
|
||||
Exit:
|
||||
if ( error )
|
||||
FT_GlyphLoader_Reset( loader );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Ensure that we can add `n_subglyphs' to our glyph. this function */
|
||||
/* reallocates its subglyphs table if necessary. Note that it DOES */
|
||||
/* NOT change the number of subglyphs within the loader! */
|
||||
/* */
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader,
|
||||
FT_UInt n_subs )
|
||||
{
|
||||
FT_Memory memory = loader->memory;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_UInt new_max, old_max;
|
||||
|
||||
FT_GlyphLoad base = &loader->base;
|
||||
FT_GlyphLoad current = &loader->current;
|
||||
|
||||
|
||||
new_max = base->num_subglyphs + current->num_subglyphs + n_subs;
|
||||
old_max = loader->max_subglyphs;
|
||||
if ( new_max > old_max )
|
||||
{
|
||||
new_max = FT_PAD_CEIL( new_max, 2 );
|
||||
if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) )
|
||||
goto Exit;
|
||||
|
||||
loader->max_subglyphs = new_max;
|
||||
|
||||
FT_GlyphLoader_Adjust_Subglyphs( loader );
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* prepare loader for the addition of a new glyph on top of the base one */
|
||||
FT_BASE_DEF( void )
|
||||
FT_GlyphLoader_Prepare( FT_GlyphLoader loader )
|
||||
{
|
||||
FT_GlyphLoad current = &loader->current;
|
||||
|
||||
|
||||
current->outline.n_points = 0;
|
||||
current->outline.n_contours = 0;
|
||||
current->num_subglyphs = 0;
|
||||
|
||||
FT_GlyphLoader_Adjust_Points ( loader );
|
||||
FT_GlyphLoader_Adjust_Subglyphs( loader );
|
||||
}
|
||||
|
||||
|
||||
/* add current glyph to the base image -- and prepare for another */
|
||||
FT_BASE_DEF( void )
|
||||
FT_GlyphLoader_Add( FT_GlyphLoader loader )
|
||||
{
|
||||
FT_Outline* base;
|
||||
FT_Outline* current;
|
||||
FT_Int n;
|
||||
|
||||
|
||||
if ( !loader )
|
||||
return;
|
||||
|
||||
base = &loader->base.outline;
|
||||
current = &loader->current.outline;
|
||||
|
||||
/* adjust contours count in newest outline */
|
||||
for ( n = 0; n < current->n_contours; n++ )
|
||||
current->contours[n] += base->n_points;
|
||||
|
||||
base->n_points += current->n_points;
|
||||
base->n_contours += current->n_contours;
|
||||
|
||||
loader->base.num_subglyphs += loader->current.num_subglyphs;
|
||||
|
||||
/* prepare for another new glyph image */
|
||||
FT_GlyphLoader_Prepare( loader );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
911
thirdparty/freetype/src/base/ftglyph.c
vendored
Normal file
911
thirdparty/freetype/src/base/ftglyph.c
vendored
Normal file
@@ -0,0 +1,911 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftglyph.c
|
||||
*
|
||||
* FreeType convenience functions to handle glyphs (body).
|
||||
*
|
||||
* Copyright (C) 1996-2024 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 the definition of several convenience functions
|
||||
* that can be used by client applications to easily retrieve glyph
|
||||
* bitmaps and outlines from a given face.
|
||||
*
|
||||
* These functions should be optional if you are writing a font server
|
||||
* or text layout engine on top of FreeType. However, they are pretty
|
||||
* handy for many other simple uses of the library.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
|
||||
#include <freetype/ftglyph.h>
|
||||
#include <freetype/ftoutln.h>
|
||||
#include <freetype/ftbitmap.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/otsvg.h>
|
||||
|
||||
#include "ftbase.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 glyph
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** FT_BitmapGlyph support ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ft_bitmap_glyph_init( FT_Glyph bitmap_glyph,
|
||||
FT_GlyphSlot slot )
|
||||
{
|
||||
FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Library library = FT_GLYPH( glyph )->library;
|
||||
|
||||
|
||||
if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
|
||||
{
|
||||
error = FT_THROW( Invalid_Glyph_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
glyph->left = slot->bitmap_left;
|
||||
glyph->top = slot->bitmap_top;
|
||||
|
||||
/* do lazy copying whenever possible */
|
||||
if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
|
||||
{
|
||||
glyph->bitmap = slot->bitmap;
|
||||
slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Bitmap_Init( &glyph->bitmap );
|
||||
error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap );
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ft_bitmap_glyph_copy( FT_Glyph bitmap_source,
|
||||
FT_Glyph bitmap_target )
|
||||
{
|
||||
FT_Library library = bitmap_source->library;
|
||||
FT_BitmapGlyph source = (FT_BitmapGlyph)bitmap_source;
|
||||
FT_BitmapGlyph target = (FT_BitmapGlyph)bitmap_target;
|
||||
|
||||
|
||||
target->left = source->left;
|
||||
target->top = source->top;
|
||||
|
||||
return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_bitmap_glyph_done( FT_Glyph bitmap_glyph )
|
||||
{
|
||||
FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
|
||||
FT_Library library = FT_GLYPH( glyph )->library;
|
||||
|
||||
|
||||
FT_Bitmap_Done( library, &glyph->bitmap );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph,
|
||||
FT_BBox* cbox )
|
||||
{
|
||||
FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
|
||||
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
FT_DEFINE_GLYPH(
|
||||
ft_bitmap_glyph_class,
|
||||
|
||||
sizeof ( FT_BitmapGlyphRec ),
|
||||
FT_GLYPH_FORMAT_BITMAP,
|
||||
|
||||
ft_bitmap_glyph_init, /* FT_Glyph_InitFunc glyph_init */
|
||||
ft_bitmap_glyph_done, /* FT_Glyph_DoneFunc glyph_done */
|
||||
ft_bitmap_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */
|
||||
NULL, /* FT_Glyph_TransformFunc glyph_transform */
|
||||
ft_bitmap_glyph_bbox, /* FT_Glyph_GetBBoxFunc glyph_bbox */
|
||||
NULL /* FT_Glyph_PrepareFunc glyph_prepare */
|
||||
)
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** FT_OutlineGlyph support ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ft_outline_glyph_init( FT_Glyph outline_glyph,
|
||||
FT_GlyphSlot slot )
|
||||
{
|
||||
FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Library library = FT_GLYPH( glyph )->library;
|
||||
FT_Outline* source = &slot->outline;
|
||||
FT_Outline* target = &glyph->outline;
|
||||
|
||||
|
||||
/* check format in glyph slot */
|
||||
if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
|
||||
{
|
||||
error = FT_THROW( Invalid_Glyph_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* allocate new outline */
|
||||
error = FT_Outline_New( library,
|
||||
(FT_UInt)source->n_points,
|
||||
source->n_contours,
|
||||
&glyph->outline );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
FT_Outline_Copy( source, target );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_outline_glyph_done( FT_Glyph outline_glyph )
|
||||
{
|
||||
FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
|
||||
|
||||
|
||||
FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ft_outline_glyph_copy( FT_Glyph outline_source,
|
||||
FT_Glyph outline_target )
|
||||
{
|
||||
FT_OutlineGlyph source = (FT_OutlineGlyph)outline_source;
|
||||
FT_OutlineGlyph target = (FT_OutlineGlyph)outline_target;
|
||||
FT_Error error;
|
||||
FT_Library library = FT_GLYPH( source )->library;
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_outline_glyph_transform( FT_Glyph outline_glyph,
|
||||
const FT_Matrix* matrix,
|
||||
const FT_Vector* delta )
|
||||
{
|
||||
FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
|
||||
|
||||
|
||||
if ( matrix )
|
||||
FT_Outline_Transform( &glyph->outline, matrix );
|
||||
|
||||
if ( delta )
|
||||
FT_Outline_Translate( &glyph->outline, delta->x, delta->y );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_outline_glyph_bbox( FT_Glyph outline_glyph,
|
||||
FT_BBox* bbox )
|
||||
{
|
||||
FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
|
||||
|
||||
|
||||
FT_Outline_Get_CBox( &glyph->outline, bbox );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ft_outline_glyph_prepare( FT_Glyph outline_glyph,
|
||||
FT_GlyphSlot slot )
|
||||
{
|
||||
FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
|
||||
|
||||
|
||||
slot->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
slot->outline = glyph->outline;
|
||||
slot->outline.flags &= ~FT_OUTLINE_OWNER;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
FT_DEFINE_GLYPH(
|
||||
ft_outline_glyph_class,
|
||||
|
||||
sizeof ( FT_OutlineGlyphRec ),
|
||||
FT_GLYPH_FORMAT_OUTLINE,
|
||||
|
||||
ft_outline_glyph_init, /* FT_Glyph_InitFunc glyph_init */
|
||||
ft_outline_glyph_done, /* FT_Glyph_DoneFunc glyph_done */
|
||||
ft_outline_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */
|
||||
ft_outline_glyph_transform, /* FT_Glyph_TransformFunc glyph_transform */
|
||||
ft_outline_glyph_bbox, /* FT_Glyph_GetBBoxFunc glyph_bbox */
|
||||
ft_outline_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */
|
||||
)
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_SVG
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** FT_SvgGlyph support ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ft_svg_glyph_init( FT_Glyph svg_glyph,
|
||||
FT_GlyphSlot slot )
|
||||
{
|
||||
FT_ULong doc_length;
|
||||
FT_SVG_Document document;
|
||||
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
|
||||
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Memory memory = FT_GLYPH( glyph )->library->memory;
|
||||
|
||||
|
||||
if ( slot->format != FT_GLYPH_FORMAT_SVG )
|
||||
{
|
||||
error = FT_THROW( Invalid_Glyph_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( slot->other == NULL )
|
||||
{
|
||||
error = FT_THROW( Invalid_Slot_Handle );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
document = (FT_SVG_Document)slot->other;
|
||||
|
||||
if ( document->svg_document_length == 0 )
|
||||
{
|
||||
error = FT_THROW( Invalid_Slot_Handle );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* allocate a new document */
|
||||
doc_length = document->svg_document_length;
|
||||
if ( FT_QALLOC( glyph->svg_document, doc_length ) )
|
||||
goto Exit;
|
||||
glyph->svg_document_length = doc_length;
|
||||
|
||||
glyph->glyph_index = slot->glyph_index;
|
||||
|
||||
glyph->metrics = document->metrics;
|
||||
glyph->units_per_EM = document->units_per_EM;
|
||||
|
||||
glyph->start_glyph_id = document->start_glyph_id;
|
||||
glyph->end_glyph_id = document->end_glyph_id;
|
||||
|
||||
glyph->transform = document->transform;
|
||||
glyph->delta = document->delta;
|
||||
|
||||
/* copy the document into glyph */
|
||||
FT_MEM_COPY( glyph->svg_document, document->svg_document, doc_length );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_svg_glyph_done( FT_Glyph svg_glyph )
|
||||
{
|
||||
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
|
||||
FT_Memory memory = svg_glyph->library->memory;
|
||||
|
||||
|
||||
/* just free the memory */
|
||||
FT_FREE( glyph->svg_document );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ft_svg_glyph_copy( FT_Glyph svg_source,
|
||||
FT_Glyph svg_target )
|
||||
{
|
||||
FT_SvgGlyph source = (FT_SvgGlyph)svg_source;
|
||||
FT_SvgGlyph target = (FT_SvgGlyph)svg_target;
|
||||
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Memory memory = FT_GLYPH( source )->library->memory;
|
||||
|
||||
|
||||
if ( svg_source->format != FT_GLYPH_FORMAT_SVG )
|
||||
{
|
||||
error = FT_THROW( Invalid_Glyph_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( source->svg_document_length == 0 )
|
||||
{
|
||||
error = FT_THROW( Invalid_Slot_Handle );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
target->glyph_index = source->glyph_index;
|
||||
|
||||
target->svg_document_length = source->svg_document_length;
|
||||
|
||||
target->metrics = source->metrics;
|
||||
target->units_per_EM = source->units_per_EM;
|
||||
|
||||
target->start_glyph_id = source->start_glyph_id;
|
||||
target->end_glyph_id = source->end_glyph_id;
|
||||
|
||||
target->transform = source->transform;
|
||||
target->delta = source->delta;
|
||||
|
||||
/* allocate space for the SVG document */
|
||||
if ( FT_QALLOC( target->svg_document, target->svg_document_length ) )
|
||||
goto Exit;
|
||||
|
||||
/* copy the document */
|
||||
FT_MEM_COPY( target->svg_document,
|
||||
source->svg_document,
|
||||
target->svg_document_length );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_svg_glyph_transform( FT_Glyph svg_glyph,
|
||||
const FT_Matrix* _matrix,
|
||||
const FT_Vector* _delta )
|
||||
{
|
||||
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
|
||||
FT_Matrix* matrix = (FT_Matrix*)_matrix;
|
||||
FT_Vector* delta = (FT_Vector*)_delta;
|
||||
|
||||
FT_Matrix tmp_matrix;
|
||||
FT_Vector tmp_delta;
|
||||
|
||||
FT_Matrix a, b;
|
||||
FT_Pos x, y;
|
||||
|
||||
|
||||
if ( !matrix )
|
||||
{
|
||||
tmp_matrix.xx = 0x10000;
|
||||
tmp_matrix.xy = 0;
|
||||
tmp_matrix.yx = 0;
|
||||
tmp_matrix.yy = 0x10000;
|
||||
|
||||
matrix = &tmp_matrix;
|
||||
}
|
||||
|
||||
if ( !delta )
|
||||
{
|
||||
tmp_delta.x = 0;
|
||||
tmp_delta.y = 0;
|
||||
|
||||
delta = &tmp_delta;
|
||||
}
|
||||
|
||||
a = glyph->transform;
|
||||
b = *matrix;
|
||||
FT_Matrix_Multiply( &b, &a );
|
||||
|
||||
x = ADD_LONG( ADD_LONG( FT_MulFix( matrix->xx, glyph->delta.x ),
|
||||
FT_MulFix( matrix->xy, glyph->delta.y ) ),
|
||||
delta->x );
|
||||
y = ADD_LONG( ADD_LONG( FT_MulFix( matrix->yx, glyph->delta.x ),
|
||||
FT_MulFix( matrix->yy, glyph->delta.y ) ),
|
||||
delta->y );
|
||||
|
||||
glyph->delta.x = x;
|
||||
glyph->delta.y = y;
|
||||
|
||||
glyph->transform = a;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ft_svg_glyph_prepare( FT_Glyph svg_glyph,
|
||||
FT_GlyphSlot slot )
|
||||
{
|
||||
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
|
||||
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Memory memory = svg_glyph->library->memory;
|
||||
|
||||
FT_SVG_Document document = NULL;
|
||||
|
||||
|
||||
if ( FT_NEW( document ) )
|
||||
return error;
|
||||
|
||||
document->svg_document = glyph->svg_document;
|
||||
document->svg_document_length = glyph->svg_document_length;
|
||||
|
||||
document->metrics = glyph->metrics;
|
||||
document->units_per_EM = glyph->units_per_EM;
|
||||
|
||||
document->start_glyph_id = glyph->start_glyph_id;
|
||||
document->end_glyph_id = glyph->end_glyph_id;
|
||||
|
||||
document->transform = glyph->transform;
|
||||
document->delta = glyph->delta;
|
||||
|
||||
slot->format = FT_GLYPH_FORMAT_SVG;
|
||||
slot->glyph_index = glyph->glyph_index;
|
||||
slot->other = document;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_DEFINE_GLYPH(
|
||||
ft_svg_glyph_class,
|
||||
|
||||
sizeof ( FT_SvgGlyphRec ),
|
||||
FT_GLYPH_FORMAT_SVG,
|
||||
|
||||
ft_svg_glyph_init, /* FT_Glyph_InitFunc glyph_init */
|
||||
ft_svg_glyph_done, /* FT_Glyph_DoneFunc glyph_done */
|
||||
ft_svg_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */
|
||||
ft_svg_glyph_transform, /* FT_Glyph_TransformFunc glyph_transform */
|
||||
NULL, /* FT_Glyph_GetBBoxFunc glyph_bbox */
|
||||
ft_svg_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */
|
||||
)
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_SVG */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** FT_Glyph class and API ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static FT_Error
|
||||
ft_new_glyph( FT_Library library,
|
||||
const FT_Glyph_Class* clazz,
|
||||
FT_Glyph* aglyph )
|
||||
{
|
||||
FT_Memory memory = library->memory;
|
||||
FT_Error error;
|
||||
FT_Glyph glyph = NULL;
|
||||
|
||||
|
||||
*aglyph = NULL;
|
||||
|
||||
if ( !FT_ALLOC( glyph, clazz->glyph_size ) )
|
||||
{
|
||||
glyph->library = library;
|
||||
glyph->clazz = clazz;
|
||||
glyph->format = clazz->glyph_format;
|
||||
|
||||
*aglyph = glyph;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Glyph_Copy( FT_Glyph source,
|
||||
FT_Glyph *target )
|
||||
{
|
||||
FT_Glyph copy;
|
||||
FT_Error error;
|
||||
const FT_Glyph_Class* clazz;
|
||||
|
||||
|
||||
/* check arguments */
|
||||
if ( !target || !source || !source->clazz )
|
||||
{
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*target = NULL;
|
||||
|
||||
if ( !source || !source->clazz )
|
||||
{
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
clazz = source->clazz;
|
||||
error = ft_new_glyph( source->library, clazz, © );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
copy->advance = source->advance;
|
||||
copy->format = source->format;
|
||||
|
||||
if ( clazz->glyph_copy )
|
||||
error = clazz->glyph_copy( source, copy );
|
||||
|
||||
if ( error )
|
||||
FT_Done_Glyph( copy );
|
||||
else
|
||||
*target = copy;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT( FT_Error )
|
||||
FT_New_Glyph( FT_Library library,
|
||||
FT_Glyph_Format format,
|
||||
FT_Glyph *aglyph )
|
||||
{
|
||||
const FT_Glyph_Class* clazz = NULL;
|
||||
|
||||
if ( !library || !aglyph )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
/* if it is a bitmap, that's easy :-) */
|
||||
if ( format == FT_GLYPH_FORMAT_BITMAP )
|
||||
clazz = &ft_bitmap_glyph_class;
|
||||
|
||||
/* if it is an outline */
|
||||
else if ( format == FT_GLYPH_FORMAT_OUTLINE )
|
||||
clazz = &ft_outline_glyph_class;
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_SVG
|
||||
/* if it is an SVG glyph */
|
||||
else if ( format == FT_GLYPH_FORMAT_SVG )
|
||||
clazz = &ft_svg_glyph_class;
|
||||
#endif
|
||||
|
||||
else
|
||||
{
|
||||
/* try to find a renderer that supports the glyph image format */
|
||||
FT_Renderer render = FT_Lookup_Renderer( library, format, 0 );
|
||||
|
||||
|
||||
if ( render )
|
||||
clazz = &render->glyph_class;
|
||||
}
|
||||
|
||||
if ( !clazz )
|
||||
return FT_THROW( Invalid_Glyph_Format );
|
||||
|
||||
/* create FT_Glyph object */
|
||||
return ft_new_glyph( library, clazz, aglyph );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Glyph( FT_GlyphSlot slot,
|
||||
FT_Glyph *aglyph )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Glyph glyph;
|
||||
|
||||
|
||||
if ( !slot )
|
||||
return FT_THROW( Invalid_Slot_Handle );
|
||||
|
||||
if ( !aglyph )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
/* create FT_Glyph object */
|
||||
error = FT_New_Glyph( slot->library, slot->format, &glyph );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* copy advance while converting 26.6 to 16.16 format */
|
||||
if ( slot->advance.x >= 0x8000L * 64 ||
|
||||
slot->advance.x <= -0x8000L * 64 )
|
||||
{
|
||||
FT_ERROR(( "FT_Get_Glyph: advance width too large\n" ));
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit2;
|
||||
}
|
||||
if ( slot->advance.y >= 0x8000L * 64 ||
|
||||
slot->advance.y <= -0x8000L * 64 )
|
||||
{
|
||||
FT_ERROR(( "FT_Get_Glyph: advance height too large\n" ));
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit2;
|
||||
}
|
||||
|
||||
glyph->advance.x = slot->advance.x * 1024;
|
||||
glyph->advance.y = slot->advance.y * 1024;
|
||||
|
||||
/* now import the image from the glyph slot */
|
||||
error = glyph->clazz->glyph_init( glyph, slot );
|
||||
|
||||
Exit2:
|
||||
/* if an error occurred, destroy the glyph */
|
||||
if ( error )
|
||||
{
|
||||
FT_Done_Glyph( glyph );
|
||||
*aglyph = NULL;
|
||||
}
|
||||
else
|
||||
*aglyph = glyph;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Glyph_Transform( FT_Glyph glyph,
|
||||
const FT_Matrix* matrix,
|
||||
const FT_Vector* delta )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
if ( !glyph || !glyph->clazz )
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
else
|
||||
{
|
||||
const FT_Glyph_Class* clazz = glyph->clazz;
|
||||
|
||||
|
||||
if ( clazz->glyph_transform )
|
||||
{
|
||||
/* transform glyph image */
|
||||
clazz->glyph_transform( glyph, matrix, delta );
|
||||
|
||||
/* transform advance vector */
|
||||
if ( matrix )
|
||||
FT_Vector_Transform( &glyph->advance, matrix );
|
||||
}
|
||||
else
|
||||
error = FT_THROW( Invalid_Glyph_Format );
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Glyph_Get_CBox( FT_Glyph glyph,
|
||||
FT_UInt bbox_mode,
|
||||
FT_BBox *acbox )
|
||||
{
|
||||
const FT_Glyph_Class* clazz;
|
||||
|
||||
|
||||
if ( !acbox )
|
||||
return;
|
||||
|
||||
acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0;
|
||||
|
||||
if ( !glyph || !glyph->clazz )
|
||||
return;
|
||||
|
||||
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 )
|
||||
{
|
||||
acbox->xMin = FT_PIX_FLOOR( acbox->xMin );
|
||||
acbox->yMin = FT_PIX_FLOOR( acbox->yMin );
|
||||
acbox->xMax = FT_PIX_CEIL_LONG( acbox->xMax );
|
||||
acbox->yMax = FT_PIX_CEIL_LONG( 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Glyph_To_Bitmap( FT_Glyph* the_glyph,
|
||||
FT_Render_Mode render_mode,
|
||||
const FT_Vector* origin,
|
||||
FT_Bool destroy )
|
||||
{
|
||||
FT_GlyphSlotRec dummy;
|
||||
FT_GlyphSlot_InternalRec dummy_internal;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Glyph b, glyph;
|
||||
FT_BitmapGlyph bitmap = NULL;
|
||||
const FT_Glyph_Class* clazz;
|
||||
|
||||
FT_Library library;
|
||||
|
||||
|
||||
/* check argument */
|
||||
if ( !the_glyph )
|
||||
goto Bad;
|
||||
glyph = *the_glyph;
|
||||
if ( !glyph )
|
||||
goto Bad;
|
||||
|
||||
clazz = glyph->clazz;
|
||||
library = glyph->library;
|
||||
if ( !library || !clazz )
|
||||
goto Bad;
|
||||
|
||||
/* when called with a bitmap glyph, do nothing and return successfully */
|
||||
if ( clazz == &ft_bitmap_glyph_class )
|
||||
goto Exit;
|
||||
|
||||
if ( !clazz->glyph_prepare )
|
||||
goto Bad;
|
||||
|
||||
/* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
|
||||
/* then calling FT_Render_Glyph_Internal() */
|
||||
|
||||
FT_ZERO( &dummy );
|
||||
FT_ZERO( &dummy_internal );
|
||||
dummy.internal = &dummy_internal;
|
||||
dummy.library = library;
|
||||
dummy.format = clazz->glyph_format;
|
||||
|
||||
/* create result bitmap glyph */
|
||||
error = ft_new_glyph( library, &ft_bitmap_glyph_class, &b );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
bitmap = (FT_BitmapGlyph)b;
|
||||
|
||||
#if 1
|
||||
/* if `origin' is set, translate the glyph image */
|
||||
if ( origin )
|
||||
FT_Glyph_Transform( glyph, NULL, origin );
|
||||
#else
|
||||
FT_UNUSED( origin );
|
||||
#endif
|
||||
|
||||
/* prepare dummy slot for rendering */
|
||||
error = clazz->glyph_prepare( glyph, &dummy );
|
||||
if ( !error )
|
||||
error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_SVG
|
||||
if ( clazz == &ft_svg_glyph_class )
|
||||
{
|
||||
FT_Memory memory = library->memory;
|
||||
|
||||
|
||||
FT_FREE( dummy.other );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
if ( !destroy && origin )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
v.x = -origin->x;
|
||||
v.y = -origin->y;
|
||||
FT_Glyph_Transform( glyph, NULL, &v );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* in case of success, copy the bitmap to the glyph bitmap */
|
||||
error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* copy advance */
|
||||
bitmap->root.advance = glyph->advance;
|
||||
|
||||
if ( destroy )
|
||||
FT_Done_Glyph( glyph );
|
||||
|
||||
*the_glyph = FT_GLYPH( bitmap );
|
||||
|
||||
Exit:
|
||||
if ( error && bitmap )
|
||||
FT_Done_Glyph( FT_GLYPH( bitmap ) );
|
||||
|
||||
return error;
|
||||
|
||||
Bad:
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftglyph.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Done_Glyph( FT_Glyph glyph )
|
||||
{
|
||||
if ( glyph )
|
||||
{
|
||||
FT_Memory memory = glyph->library->memory;
|
||||
const FT_Glyph_Class* clazz = glyph->clazz;
|
||||
|
||||
|
||||
if ( clazz->glyph_done )
|
||||
clazz->glyph_done( glyph );
|
||||
|
||||
FT_FREE( glyph );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
141
thirdparty/freetype/src/base/ftgxval.c
vendored
Normal file
141
thirdparty/freetype/src/base/ftgxval.c
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftgxval.c
|
||||
*
|
||||
* FreeType API for validating TrueTypeGX/AAT tables (body).
|
||||
*
|
||||
* Copyright (C) 2004-2024 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,
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* gxvalid is derived from both gxlayout module and otvalid module.
|
||||
* Development of gxlayout is supported by the Information-technology
|
||||
* Promotion Agency(IPA), Japan.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/services/svgxval.h>
|
||||
|
||||
|
||||
/* documentation is in ftgxval.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_TrueTypeGX_Validate( FT_Face face,
|
||||
FT_UInt validation_flags,
|
||||
FT_Bytes tables[FT_VALIDATE_GX_LENGTH],
|
||||
FT_UInt table_length )
|
||||
{
|
||||
FT_Service_GXvalidate service;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
if ( !face )
|
||||
{
|
||||
error = FT_THROW( Invalid_Face_Handle );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( !tables )
|
||||
{
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
FT_FACE_FIND_GLOBAL_SERVICE( face, service, GX_VALIDATE );
|
||||
|
||||
if ( service )
|
||||
error = service->validate( face,
|
||||
validation_flags,
|
||||
tables,
|
||||
table_length );
|
||||
else
|
||||
error = FT_THROW( Unimplemented_Feature );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_TrueTypeGX_Free( FT_Face face,
|
||||
FT_Bytes table )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return;
|
||||
|
||||
memory = FT_FACE_MEMORY( face );
|
||||
|
||||
FT_FREE( table );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_ClassicKern_Validate( FT_Face face,
|
||||
FT_UInt validation_flags,
|
||||
FT_Bytes *ckern_table )
|
||||
{
|
||||
FT_Service_CKERNvalidate service;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
if ( !face )
|
||||
{
|
||||
error = FT_THROW( Invalid_Face_Handle );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( !ckern_table )
|
||||
{
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
FT_FACE_FIND_GLOBAL_SERVICE( face, service, CLASSICKERN_VALIDATE );
|
||||
|
||||
if ( service )
|
||||
error = service->validate( face,
|
||||
validation_flags,
|
||||
ckern_table );
|
||||
else
|
||||
error = FT_THROW( Unimplemented_Feature );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_ClassicKern_Free( FT_Face face,
|
||||
FT_Bytes table )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return;
|
||||
|
||||
memory = FT_FACE_MEMORY( face );
|
||||
|
||||
|
||||
FT_FREE( table );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
338
thirdparty/freetype/src/base/fthash.c
vendored
Normal file
338
thirdparty/freetype/src/base/fthash.c
vendored
Normal file
@@ -0,0 +1,338 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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 <freetype/internal/fthash.h>
|
||||
#include <freetype/internal/ftmemory.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_QNEW( 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 */
|
||||
263
thirdparty/freetype/src/base/ftinit.c
vendored
Normal file
263
thirdparty/freetype/src/base/ftinit.c
vendored
Normal file
@@ -0,0 +1,263 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftinit.c
|
||||
*
|
||||
* FreeType initialization layer (body).
|
||||
*
|
||||
* Copyright (C) 1996-2024 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 purpose of this file is to implement the following two
|
||||
* functions:
|
||||
*
|
||||
* FT_Add_Default_Modules():
|
||||
* This function is used to add the set of default modules to a
|
||||
* fresh new library object. The set is taken from the header file
|
||||
* `freetype/config/ftmodule.h'. See the document `FreeType 2.0
|
||||
* Build System' for more information.
|
||||
*
|
||||
* FT_Init_FreeType():
|
||||
* This function creates a system object for the current platform,
|
||||
* builds a library out of it, then calls FT_Default_Drivers().
|
||||
*
|
||||
* Note that even if FT_Init_FreeType() uses the implementation of the
|
||||
* system object defined at build time, client applications are still
|
||||
* able to provide their own `ftsystem.c'.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/ftmodapi.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 init
|
||||
|
||||
|
||||
#undef FT_USE_MODULE
|
||||
#ifdef __cplusplus
|
||||
#define FT_USE_MODULE( type, x ) extern "C" const type x;
|
||||
#else
|
||||
#define FT_USE_MODULE( type, x ) extern const type x;
|
||||
#endif
|
||||
|
||||
#include FT_CONFIG_MODULES_H
|
||||
|
||||
#undef FT_USE_MODULE
|
||||
#define FT_USE_MODULE( type, x ) (const FT_Module_Class*)&(x),
|
||||
|
||||
static
|
||||
const FT_Module_Class* const ft_default_modules[] =
|
||||
{
|
||||
#include FT_CONFIG_MODULES_H
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftmodapi.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Add_Default_Modules( FT_Library library )
|
||||
{
|
||||
FT_Error error;
|
||||
const FT_Module_Class* const* cur;
|
||||
|
||||
|
||||
/* GCC 4.6 warns the type difference:
|
||||
* FT_Module_Class** != const FT_Module_Class* const*
|
||||
*/
|
||||
cur = (const FT_Module_Class* const*)ft_default_modules;
|
||||
|
||||
/* test for valid `library' delayed to FT_Add_Module() */
|
||||
while ( *cur )
|
||||
{
|
||||
error = FT_Add_Module( library, *cur );
|
||||
/* notify errors, but don't stop */
|
||||
if ( error )
|
||||
FT_TRACE0(( "FT_Add_Default_Module:"
|
||||
" Cannot install `%s', error = 0x%x\n",
|
||||
(*cur)->module_name, error ));
|
||||
cur++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
|
||||
#define MAX_LENGTH 128
|
||||
|
||||
/* documentation is in ftmodapi.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Set_Default_Properties( FT_Library library )
|
||||
{
|
||||
const char* env;
|
||||
const char* p;
|
||||
const char* q;
|
||||
|
||||
char module_name[MAX_LENGTH + 1];
|
||||
char property_name[MAX_LENGTH + 1];
|
||||
char property_value[MAX_LENGTH + 1];
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
env = ft_getenv( "FREETYPE_PROPERTIES" );
|
||||
if ( !env )
|
||||
return;
|
||||
|
||||
for ( p = env; *p; p++ )
|
||||
{
|
||||
/* skip leading whitespace and separators */
|
||||
if ( *p == ' ' || *p == '\t' )
|
||||
continue;
|
||||
|
||||
/* read module name, followed by `:' */
|
||||
q = p;
|
||||
for ( i = 0; i < MAX_LENGTH; i++ )
|
||||
{
|
||||
if ( !*p || *p == ':' )
|
||||
break;
|
||||
module_name[i] = *p++;
|
||||
}
|
||||
module_name[i] = '\0';
|
||||
|
||||
if ( !*p || *p != ':' || p == q )
|
||||
break;
|
||||
|
||||
/* read property name, followed by `=' */
|
||||
q = ++p;
|
||||
for ( i = 0; i < MAX_LENGTH; i++ )
|
||||
{
|
||||
if ( !*p || *p == '=' )
|
||||
break;
|
||||
property_name[i] = *p++;
|
||||
}
|
||||
property_name[i] = '\0';
|
||||
|
||||
if ( !*p || *p != '=' || p == q )
|
||||
break;
|
||||
|
||||
/* read property value, followed by whitespace (if any) */
|
||||
q = ++p;
|
||||
for ( i = 0; i < MAX_LENGTH; i++ )
|
||||
{
|
||||
if ( !*p || *p == ' ' || *p == '\t' )
|
||||
break;
|
||||
property_value[i] = *p++;
|
||||
}
|
||||
property_value[i] = '\0';
|
||||
|
||||
if ( !( *p == '\0' || *p == ' ' || *p == '\t' ) || p == q )
|
||||
break;
|
||||
|
||||
/* we completely ignore errors */
|
||||
ft_property_string_set( library,
|
||||
module_name,
|
||||
property_name,
|
||||
property_value );
|
||||
|
||||
if ( !*p )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Set_Default_Properties( FT_Library library )
|
||||
{
|
||||
FT_UNUSED( library );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Init_FreeType( FT_Library *alibrary )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LOGGING
|
||||
ft_logging_init();
|
||||
#endif
|
||||
|
||||
/* 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'. */
|
||||
|
||||
memory = FT_New_Memory();
|
||||
if ( !memory )
|
||||
{
|
||||
FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" ));
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
/* build a library out of it, then fill it with the set of */
|
||||
/* default drivers. */
|
||||
|
||||
error = FT_New_Library( memory, alibrary );
|
||||
if ( error )
|
||||
FT_Done_Memory( memory );
|
||||
else
|
||||
FT_Add_Default_Modules( *alibrary );
|
||||
|
||||
FT_Set_Default_Properties( *alibrary );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Done_FreeType( FT_Library library )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
if ( !library )
|
||||
return FT_THROW( Invalid_Library_Handle );
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
/* Discard the library object */
|
||||
FT_Done_Library( library );
|
||||
|
||||
/* discard memory manager */
|
||||
FT_Done_Memory( memory );
|
||||
|
||||
#ifdef FT_DEBUG_LOGGING
|
||||
ft_logging_deinit();
|
||||
#endif
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
437
thirdparty/freetype/src/base/ftlcdfil.c
vendored
Normal file
437
thirdparty/freetype/src/base/ftlcdfil.c
vendored
Normal file
@@ -0,0 +1,437 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftlcdfil.c
|
||||
*
|
||||
* FreeType API for color filtering of subpixel bitmap glyphs (body).
|
||||
*
|
||||
* Copyright (C) 2006-2024 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 <freetype/internal/ftdebug.h>
|
||||
|
||||
#include <freetype/ftlcdfil.h>
|
||||
#include <freetype/ftimage.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
||||
|
||||
/* define USE_LEGACY to implement the legacy filter */
|
||||
#define USE_LEGACY
|
||||
|
||||
#define FT_SHIFTCLAMP( x ) ( x >>= 8, (FT_Byte)( x > 255 ? 255 : x ) )
|
||||
|
||||
|
||||
/* add padding according to filter weights */
|
||||
FT_BASE_DEF( void )
|
||||
ft_lcd_padding( FT_BBox* cbox,
|
||||
FT_GlyphSlot slot,
|
||||
FT_Render_Mode mode )
|
||||
{
|
||||
FT_Byte* lcd_weights;
|
||||
FT_Bitmap_LcdFilterFunc lcd_filter_func;
|
||||
|
||||
|
||||
/* Per-face LCD filtering takes priority if set up. */
|
||||
if ( slot->face && slot->face->internal->lcd_filter_func )
|
||||
{
|
||||
lcd_weights = slot->face->internal->lcd_weights;
|
||||
lcd_filter_func = slot->face->internal->lcd_filter_func;
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd_weights = slot->library->lcd_weights;
|
||||
lcd_filter_func = slot->library->lcd_filter_func;
|
||||
}
|
||||
|
||||
if ( lcd_filter_func == ft_lcd_filter_fir )
|
||||
{
|
||||
if ( mode == FT_RENDER_MODE_LCD )
|
||||
{
|
||||
cbox->xMin -= lcd_weights[0] ? 43 :
|
||||
lcd_weights[1] ? 22 : 0;
|
||||
cbox->xMax += lcd_weights[4] ? 43 :
|
||||
lcd_weights[3] ? 22 : 0;
|
||||
}
|
||||
else if ( mode == FT_RENDER_MODE_LCD_V )
|
||||
{
|
||||
cbox->yMin -= lcd_weights[0] ? 43 :
|
||||
lcd_weights[1] ? 22 : 0;
|
||||
cbox->yMax += lcd_weights[4] ? 43 :
|
||||
lcd_weights[3] ? 22 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* FIR filter used by the default and light filters */
|
||||
FT_BASE_DEF( void )
|
||||
ft_lcd_filter_fir( FT_Bitmap* bitmap,
|
||||
FT_LcdFiveTapFilter weights )
|
||||
{
|
||||
FT_UInt width = (FT_UInt)bitmap->width;
|
||||
FT_UInt height = (FT_UInt)bitmap->rows;
|
||||
FT_Int pitch = bitmap->pitch;
|
||||
FT_Byte* origin = bitmap->buffer;
|
||||
FT_Byte mode = bitmap->pixel_mode;
|
||||
|
||||
|
||||
/* take care of bitmap flow */
|
||||
if ( pitch > 0 && height > 0 )
|
||||
origin += pitch * (FT_Int)( height - 1 );
|
||||
|
||||
/* horizontal in-place FIR filter */
|
||||
if ( mode == FT_PIXEL_MODE_LCD && width >= 2 )
|
||||
{
|
||||
FT_Byte* line = origin;
|
||||
|
||||
|
||||
/* `fir' must be at least 32 bit wide, since the sum of */
|
||||
/* the values in `weights' can exceed 0xFF */
|
||||
|
||||
for ( ; height > 0; height--, line -= pitch )
|
||||
{
|
||||
FT_UInt fir[5];
|
||||
FT_UInt val, xx;
|
||||
|
||||
|
||||
val = line[0];
|
||||
fir[2] = weights[2] * val;
|
||||
fir[3] = weights[3] * val;
|
||||
fir[4] = weights[4] * val;
|
||||
|
||||
val = line[1];
|
||||
fir[1] = fir[2] + weights[1] * val;
|
||||
fir[2] = fir[3] + weights[2] * val;
|
||||
fir[3] = fir[4] + weights[3] * val;
|
||||
fir[4] = weights[4] * val;
|
||||
|
||||
for ( xx = 2; xx < width; xx++ )
|
||||
{
|
||||
val = line[xx];
|
||||
fir[0] = fir[1] + weights[0] * val;
|
||||
fir[1] = fir[2] + weights[1] * val;
|
||||
fir[2] = fir[3] + weights[2] * val;
|
||||
fir[3] = fir[4] + weights[3] * val;
|
||||
fir[4] = weights[4] * val;
|
||||
|
||||
line[xx - 2] = FT_SHIFTCLAMP( fir[0] );
|
||||
}
|
||||
|
||||
line[xx - 2] = FT_SHIFTCLAMP( fir[1] );
|
||||
line[xx - 1] = FT_SHIFTCLAMP( fir[2] );
|
||||
}
|
||||
}
|
||||
|
||||
/* vertical in-place FIR filter */
|
||||
else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 2 )
|
||||
{
|
||||
FT_Byte* column = origin;
|
||||
|
||||
|
||||
for ( ; width > 0; width--, column++ )
|
||||
{
|
||||
FT_Byte* col = column;
|
||||
FT_UInt fir[5];
|
||||
FT_UInt val, yy;
|
||||
|
||||
|
||||
val = col[0];
|
||||
fir[2] = weights[2] * val;
|
||||
fir[3] = weights[3] * val;
|
||||
fir[4] = weights[4] * val;
|
||||
col -= pitch;
|
||||
|
||||
val = col[0];
|
||||
fir[1] = fir[2] + weights[1] * val;
|
||||
fir[2] = fir[3] + weights[2] * val;
|
||||
fir[3] = fir[4] + weights[3] * val;
|
||||
fir[4] = weights[4] * val;
|
||||
col -= pitch;
|
||||
|
||||
for ( yy = 2; yy < height; yy++, col -= pitch )
|
||||
{
|
||||
val = col[0];
|
||||
fir[0] = fir[1] + weights[0] * val;
|
||||
fir[1] = fir[2] + weights[1] * val;
|
||||
fir[2] = fir[3] + weights[2] * val;
|
||||
fir[3] = fir[4] + weights[3] * val;
|
||||
fir[4] = weights[4] * val;
|
||||
|
||||
col[pitch * 2] = FT_SHIFTCLAMP( fir[0] );
|
||||
}
|
||||
|
||||
col[pitch * 2] = FT_SHIFTCLAMP( fir[1] );
|
||||
col[pitch] = FT_SHIFTCLAMP( fir[2] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_LEGACY
|
||||
|
||||
/* intra-pixel filter used by the legacy filter */
|
||||
static void
|
||||
_ft_lcd_filter_legacy( FT_Bitmap* bitmap,
|
||||
FT_Byte* weights )
|
||||
{
|
||||
FT_UInt width = (FT_UInt)bitmap->width;
|
||||
FT_UInt height = (FT_UInt)bitmap->rows;
|
||||
FT_Int pitch = bitmap->pitch;
|
||||
FT_Byte* origin = bitmap->buffer;
|
||||
FT_Byte mode = bitmap->pixel_mode;
|
||||
|
||||
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 },
|
||||
{ 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 }
|
||||
};
|
||||
|
||||
FT_UNUSED( weights );
|
||||
|
||||
|
||||
/* take care of bitmap flow */
|
||||
if ( pitch > 0 && height > 0 )
|
||||
origin += pitch * (FT_Int)( height - 1 );
|
||||
|
||||
/* horizontal in-place intra-pixel filter */
|
||||
if ( mode == FT_PIXEL_MODE_LCD && width >= 3 )
|
||||
{
|
||||
FT_Byte* line = origin;
|
||||
|
||||
|
||||
for ( ; height > 0; height--, line -= pitch )
|
||||
{
|
||||
FT_UInt xx;
|
||||
|
||||
|
||||
for ( xx = 0; xx < width; xx += 3 )
|
||||
{
|
||||
FT_UInt r, g, b;
|
||||
FT_UInt p;
|
||||
|
||||
|
||||
p = line[xx];
|
||||
r = filters[0][0] * p;
|
||||
g = filters[0][1] * p;
|
||||
b = filters[0][2] * p;
|
||||
|
||||
p = line[xx + 1];
|
||||
r += filters[1][0] * p;
|
||||
g += filters[1][1] * p;
|
||||
b += filters[1][2] * p;
|
||||
|
||||
p = line[xx + 2];
|
||||
r += filters[2][0] * p;
|
||||
g += filters[2][1] * p;
|
||||
b += filters[2][2] * p;
|
||||
|
||||
line[xx] = (FT_Byte)( r / 65536 );
|
||||
line[xx + 1] = (FT_Byte)( g / 65536 );
|
||||
line[xx + 2] = (FT_Byte)( b / 65536 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 3 )
|
||||
{
|
||||
FT_Byte* column = origin;
|
||||
|
||||
|
||||
for ( ; width > 0; width--, column++ )
|
||||
{
|
||||
FT_Byte* col = column - 2 * pitch;
|
||||
|
||||
|
||||
for ( ; height > 0; height -= 3, col -= 3 * pitch )
|
||||
{
|
||||
FT_UInt r, g, b;
|
||||
FT_UInt p;
|
||||
|
||||
|
||||
p = col[0];
|
||||
r = filters[0][0] * p;
|
||||
g = filters[0][1] * p;
|
||||
b = filters[0][2] * p;
|
||||
|
||||
p = col[pitch];
|
||||
r += filters[1][0] * p;
|
||||
g += filters[1][1] * p;
|
||||
b += filters[1][2] * p;
|
||||
|
||||
p = col[pitch * 2];
|
||||
r += filters[2][0] * p;
|
||||
g += filters[2][1] * p;
|
||||
b += filters[2][2] * p;
|
||||
|
||||
col[0] = (FT_Byte)( r / 65536 );
|
||||
col[pitch] = (FT_Byte)( g / 65536 );
|
||||
col[pitch * 2] = (FT_Byte)( b / 65536 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_LEGACY */
|
||||
|
||||
|
||||
/* documentation in ftlcdfil.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Library_SetLcdFilterWeights( FT_Library library,
|
||||
unsigned char *weights )
|
||||
{
|
||||
if ( !library )
|
||||
return FT_THROW( Invalid_Library_Handle );
|
||||
|
||||
if ( !weights )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
ft_memcpy( library->lcd_weights, weights, FT_LCD_FILTER_FIVE_TAPS );
|
||||
library->lcd_filter_func = ft_lcd_filter_fir;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* documentation in ftlcdfil.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Library_SetLcdFilter( FT_Library library,
|
||||
FT_LcdFilter filter )
|
||||
{
|
||||
static const FT_LcdFiveTapFilter default_weights =
|
||||
{ 0x08, 0x4d, 0x56, 0x4d, 0x08 };
|
||||
static const FT_LcdFiveTapFilter light_weights =
|
||||
{ 0x00, 0x55, 0x56, 0x55, 0x00 };
|
||||
|
||||
|
||||
if ( !library )
|
||||
return FT_THROW( Invalid_Library_Handle );
|
||||
|
||||
switch ( filter )
|
||||
{
|
||||
case FT_LCD_FILTER_NONE:
|
||||
library->lcd_filter_func = NULL;
|
||||
break;
|
||||
|
||||
case FT_LCD_FILTER_DEFAULT:
|
||||
ft_memcpy( library->lcd_weights,
|
||||
default_weights,
|
||||
FT_LCD_FILTER_FIVE_TAPS );
|
||||
library->lcd_filter_func = ft_lcd_filter_fir;
|
||||
break;
|
||||
|
||||
case FT_LCD_FILTER_LIGHT:
|
||||
ft_memcpy( library->lcd_weights,
|
||||
light_weights,
|
||||
FT_LCD_FILTER_FIVE_TAPS );
|
||||
library->lcd_filter_func = ft_lcd_filter_fir;
|
||||
break;
|
||||
|
||||
#ifdef USE_LEGACY
|
||||
|
||||
case FT_LCD_FILTER_LEGACY:
|
||||
case FT_LCD_FILTER_LEGACY1:
|
||||
library->lcd_filter_func = _ft_lcd_filter_legacy;
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
default:
|
||||
return FT_THROW( Invalid_Argument );
|
||||
}
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Library_SetLcdGeometry( FT_Library library,
|
||||
FT_Vector sub[3] )
|
||||
{
|
||||
FT_UNUSED( library );
|
||||
FT_UNUSED( sub );
|
||||
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
|
||||
|
||||
/* add padding to accommodate outline shifts */
|
||||
FT_BASE_DEF( void )
|
||||
ft_lcd_padding( FT_BBox* cbox,
|
||||
FT_GlyphSlot slot,
|
||||
FT_Render_Mode mode )
|
||||
{
|
||||
FT_Vector* sub = slot->library->lcd_geometry;
|
||||
|
||||
if ( mode == FT_RENDER_MODE_LCD )
|
||||
{
|
||||
cbox->xMin -= FT_MAX( FT_MAX( sub[0].x, sub[1].x ), sub[2].x );
|
||||
cbox->xMax -= FT_MIN( FT_MIN( sub[0].x, sub[1].x ), sub[2].x );
|
||||
cbox->yMin -= FT_MAX( FT_MAX( sub[0].y, sub[1].y ), sub[2].y );
|
||||
cbox->yMax -= FT_MIN( FT_MIN( sub[0].y, sub[1].y ), sub[2].y );
|
||||
}
|
||||
else if ( mode == FT_RENDER_MODE_LCD_V )
|
||||
{
|
||||
cbox->xMin -= FT_MAX( FT_MAX( sub[0].y, sub[1].y ), sub[2].y );
|
||||
cbox->xMax -= FT_MIN( FT_MIN( sub[0].y, sub[1].y ), sub[2].y );
|
||||
cbox->yMin += FT_MIN( FT_MIN( sub[0].x, sub[1].x ), sub[2].x );
|
||||
cbox->yMax += FT_MAX( FT_MAX( sub[0].x, sub[1].x ), sub[2].x );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Library_SetLcdFilterWeights( FT_Library library,
|
||||
unsigned char *weights )
|
||||
{
|
||||
FT_UNUSED( library );
|
||||
FT_UNUSED( weights );
|
||||
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Library_SetLcdFilter( FT_Library library,
|
||||
FT_LcdFilter filter )
|
||||
{
|
||||
FT_UNUSED( library );
|
||||
FT_UNUSED( filter );
|
||||
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
|
||||
/* documentation in ftlcdfil.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Library_SetLcdGeometry( FT_Library library,
|
||||
FT_Vector sub[3] )
|
||||
{
|
||||
if ( !library )
|
||||
return FT_THROW( Invalid_Library_Handle );
|
||||
|
||||
if ( !sub )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
ft_memcpy( library->lcd_geometry, sub, 3 * sizeof( FT_Vector ) );
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
|
||||
|
||||
|
||||
/* END */
|
||||
1099
thirdparty/freetype/src/base/ftmac.c
vendored
Normal file
1099
thirdparty/freetype/src/base/ftmac.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
704
thirdparty/freetype/src/base/ftmm.c
vendored
Normal file
704
thirdparty/freetype/src/base/ftmm.c
vendored
Normal file
@@ -0,0 +1,704 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftmm.c
|
||||
*
|
||||
* Multiple Master font support (body).
|
||||
*
|
||||
* Copyright (C) 1996-2024 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 <freetype/internal/ftdebug.h>
|
||||
|
||||
#include <freetype/ftmm.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/services/svmm.h>
|
||||
#include <freetype/internal/services/svmetric.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 mm
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_face_get_mm_service( FT_Face face,
|
||||
FT_Service_MultiMasters *aservice )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
*aservice = NULL;
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
|
||||
if ( FT_HAS_MULTIPLE_MASTERS( face ) )
|
||||
{
|
||||
FT_FACE_LOOKUP_SERVICE( face,
|
||||
*aservice,
|
||||
MULTI_MASTERS );
|
||||
|
||||
if ( *aservice )
|
||||
error = FT_Err_Ok;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_face_get_mvar_service( FT_Face face,
|
||||
FT_Service_MetricsVariations *aservice )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
*aservice = NULL;
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
|
||||
if ( FT_HAS_MULTIPLE_MASTERS( face ) )
|
||||
{
|
||||
FT_FACE_LOOKUP_SERVICE( face,
|
||||
*aservice,
|
||||
METRICS_VARIATIONS );
|
||||
|
||||
if ( *aservice )
|
||||
error = FT_Err_Ok;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Multi_Master( FT_Face face,
|
||||
FT_Multi_Master *amaster )
|
||||
{
|
||||
FT_Error error;
|
||||
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 )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service->get_mm )
|
||||
error = service->get_mm( face, amaster );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_MM_Var( FT_Face face,
|
||||
FT_MM_Var* *amaster )
|
||||
{
|
||||
FT_Error error;
|
||||
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 )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service->get_mm_var )
|
||||
error = service->get_mm_var( face, amaster );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Done_MM_Var( FT_Library library,
|
||||
FT_MM_Var* amaster )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
if ( !library )
|
||||
return FT_THROW( Invalid_Library_Handle );
|
||||
|
||||
memory = library->memory;
|
||||
FT_FREE( amaster );
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Set_MM_Design_Coordinates( FT_Face face,
|
||||
FT_UInt num_coords,
|
||||
FT_Long* coords )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Service_MultiMasters service;
|
||||
|
||||
|
||||
/* check of `face' delayed to `ft_face_get_mm_service' */
|
||||
|
||||
if ( num_coords && !coords )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
error = ft_face_get_mm_service( face, &service );
|
||||
if ( !error )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service->set_mm_design )
|
||||
error = service->set_mm_design( face, num_coords, coords );
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
if ( num_coords )
|
||||
face->face_flags |= FT_FACE_FLAG_VARIATION;
|
||||
else
|
||||
face->face_flags &= ~FT_FACE_FLAG_VARIATION;
|
||||
}
|
||||
}
|
||||
|
||||
/* enforce recomputation of auto-hinting data */
|
||||
if ( !error && face->autohint.finalizer )
|
||||
{
|
||||
face->autohint.finalizer( face->autohint.data );
|
||||
face->autohint.data = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Set_MM_WeightVector( FT_Face face,
|
||||
FT_UInt len,
|
||||
FT_Fixed* weightvector )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Service_MultiMasters service;
|
||||
|
||||
|
||||
/* check of `face' delayed to `ft_face_get_mm_service' */
|
||||
|
||||
if ( len && !weightvector )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
error = ft_face_get_mm_service( face, &service );
|
||||
if ( !error )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service->set_mm_weightvector )
|
||||
error = service->set_mm_weightvector( face, len, weightvector );
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
if ( len )
|
||||
face->face_flags |= FT_FACE_FLAG_VARIATION;
|
||||
else
|
||||
face->face_flags &= ~FT_FACE_FLAG_VARIATION;
|
||||
}
|
||||
}
|
||||
|
||||
/* enforce recomputation of auto-hinting data */
|
||||
if ( !error && face->autohint.finalizer )
|
||||
{
|
||||
face->autohint.finalizer( face->autohint.data );
|
||||
face->autohint.data = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_MM_WeightVector( FT_Face face,
|
||||
FT_UInt* len,
|
||||
FT_Fixed* weightvector )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Service_MultiMasters service;
|
||||
|
||||
|
||||
/* check of `face' delayed to `ft_face_get_mm_service' */
|
||||
|
||||
if ( len && !weightvector )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
error = ft_face_get_mm_service( face, &service );
|
||||
if ( !error )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service->get_mm_weightvector )
|
||||
error = service->get_mm_weightvector( face, len, weightvector );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Set_Var_Design_Coordinates( FT_Face face,
|
||||
FT_UInt num_coords,
|
||||
FT_Fixed* coords )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Service_MultiMasters service_mm = NULL;
|
||||
FT_Service_MetricsVariations service_mvar = NULL;
|
||||
|
||||
|
||||
/* check of `face' delayed to `ft_face_get_mm_service' */
|
||||
|
||||
if ( num_coords && !coords )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
error = ft_face_get_mm_service( face, &service_mm );
|
||||
if ( !error )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service_mm->set_var_design )
|
||||
error = service_mm->set_var_design( face, num_coords, coords );
|
||||
|
||||
if ( !error || error == -1 )
|
||||
{
|
||||
FT_Bool is_variation_old = FT_IS_VARIATION( face );
|
||||
|
||||
|
||||
if ( num_coords )
|
||||
face->face_flags |= FT_FACE_FLAG_VARIATION;
|
||||
else
|
||||
face->face_flags &= ~FT_FACE_FLAG_VARIATION;
|
||||
|
||||
if ( service_mm->construct_ps_name )
|
||||
{
|
||||
if ( error == -1 )
|
||||
{
|
||||
/* The PS name of a named instance and a non-named instance */
|
||||
/* usually differs, even if the axis values are identical. */
|
||||
if ( is_variation_old != FT_IS_VARIATION( face ) )
|
||||
service_mm->construct_ps_name( face );
|
||||
}
|
||||
else
|
||||
service_mm->construct_ps_name( face );
|
||||
}
|
||||
}
|
||||
|
||||
/* internal error code -1 means `no change'; we can exit immediately */
|
||||
if ( error == -1 )
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
(void)ft_face_get_mvar_service( face, &service_mvar );
|
||||
|
||||
if ( service_mvar && service_mvar->metrics_adjust )
|
||||
service_mvar->metrics_adjust( face );
|
||||
}
|
||||
|
||||
/* enforce recomputation of auto-hinting data */
|
||||
if ( !error && face->autohint.finalizer )
|
||||
{
|
||||
face->autohint.finalizer( face->autohint.data );
|
||||
face->autohint.data = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Var_Design_Coordinates( FT_Face face,
|
||||
FT_UInt num_coords,
|
||||
FT_Fixed* coords )
|
||||
{
|
||||
FT_Error error;
|
||||
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 )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service->get_var_design )
|
||||
error = service->get_var_design( face, num_coords, coords );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Set_MM_Blend_Coordinates( FT_Face face,
|
||||
FT_UInt num_coords,
|
||||
FT_Fixed* coords )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Service_MultiMasters service_mm = NULL;
|
||||
FT_Service_MetricsVariations service_mvar = NULL;
|
||||
|
||||
|
||||
/* check of `face' delayed to `ft_face_get_mm_service' */
|
||||
|
||||
if ( num_coords && !coords )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
error = ft_face_get_mm_service( face, &service_mm );
|
||||
if ( !error )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service_mm->set_mm_blend )
|
||||
error = service_mm->set_mm_blend( face, num_coords, coords );
|
||||
|
||||
if ( !error || error == -1 )
|
||||
{
|
||||
FT_Bool is_variation_old = FT_IS_VARIATION( face );
|
||||
|
||||
|
||||
if ( num_coords )
|
||||
face->face_flags |= FT_FACE_FLAG_VARIATION;
|
||||
else
|
||||
face->face_flags &= ~FT_FACE_FLAG_VARIATION;
|
||||
|
||||
if ( service_mm->construct_ps_name )
|
||||
{
|
||||
if ( error == -1 )
|
||||
{
|
||||
/* The PS name of a named instance and a non-named instance */
|
||||
/* usually differs, even if the axis values are identical. */
|
||||
if ( is_variation_old != FT_IS_VARIATION( face ) )
|
||||
service_mm->construct_ps_name( face );
|
||||
}
|
||||
else
|
||||
service_mm->construct_ps_name( face );
|
||||
}
|
||||
}
|
||||
|
||||
/* internal error code -1 means `no change'; we can exit immediately */
|
||||
if ( error == -1 )
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
(void)ft_face_get_mvar_service( face, &service_mvar );
|
||||
|
||||
if ( service_mvar && service_mvar->metrics_adjust )
|
||||
service_mvar->metrics_adjust( face );
|
||||
}
|
||||
|
||||
/* enforce recomputation of auto-hinting data */
|
||||
if ( !error && face->autohint.finalizer )
|
||||
{
|
||||
face->autohint.finalizer( face->autohint.data );
|
||||
face->autohint.data = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
/* This is exactly the same as the previous function. It exists for */
|
||||
/* orthogonality. */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Set_Var_Blend_Coordinates( FT_Face face,
|
||||
FT_UInt num_coords,
|
||||
FT_Fixed* coords )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Service_MultiMasters service_mm = NULL;
|
||||
FT_Service_MetricsVariations service_mvar = NULL;
|
||||
|
||||
|
||||
/* check of `face' delayed to `ft_face_get_mm_service' */
|
||||
|
||||
if ( num_coords && !coords )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
error = ft_face_get_mm_service( face, &service_mm );
|
||||
if ( !error )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service_mm->set_mm_blend )
|
||||
error = service_mm->set_mm_blend( face, num_coords, coords );
|
||||
|
||||
if ( !error || error == -1 )
|
||||
{
|
||||
FT_Bool is_variation_old = FT_IS_VARIATION( face );
|
||||
|
||||
|
||||
if ( num_coords )
|
||||
face->face_flags |= FT_FACE_FLAG_VARIATION;
|
||||
else
|
||||
face->face_flags &= ~FT_FACE_FLAG_VARIATION;
|
||||
|
||||
if ( service_mm->construct_ps_name )
|
||||
{
|
||||
if ( error == -1 )
|
||||
{
|
||||
/* The PS name of a named instance and a non-named instance */
|
||||
/* usually differs, even if the axis values are identical. */
|
||||
if ( is_variation_old != FT_IS_VARIATION( face ) )
|
||||
service_mm->construct_ps_name( face );
|
||||
}
|
||||
else
|
||||
service_mm->construct_ps_name( face );
|
||||
}
|
||||
}
|
||||
|
||||
/* internal error code -1 means `no change'; we can exit immediately */
|
||||
if ( error == -1 )
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
(void)ft_face_get_mvar_service( face, &service_mvar );
|
||||
|
||||
if ( service_mvar && service_mvar->metrics_adjust )
|
||||
service_mvar->metrics_adjust( face );
|
||||
}
|
||||
|
||||
/* enforce recomputation of auto-hinting data */
|
||||
if ( !error && face->autohint.finalizer )
|
||||
{
|
||||
face->autohint.finalizer( face->autohint.data );
|
||||
face->autohint.data = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_MM_Blend_Coordinates( FT_Face face,
|
||||
FT_UInt num_coords,
|
||||
FT_Fixed* coords )
|
||||
{
|
||||
FT_Error error;
|
||||
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 )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service->get_mm_blend )
|
||||
error = service->get_mm_blend( face, num_coords, coords );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
/* This is exactly the same as the previous function. It exists for */
|
||||
/* orthogonality. */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Var_Blend_Coordinates( FT_Face face,
|
||||
FT_UInt num_coords,
|
||||
FT_Fixed* coords )
|
||||
{
|
||||
FT_Error error;
|
||||
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 )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service->get_mm_blend )
|
||||
error = service->get_mm_blend( face, num_coords, coords );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Var_Axis_Flags( FT_MM_Var* master,
|
||||
FT_UInt axis_index,
|
||||
FT_UInt* flags )
|
||||
{
|
||||
FT_UShort* axis_flags;
|
||||
|
||||
|
||||
if ( !master || !flags )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
if ( axis_index >= master->num_axis )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
/* the axis flags array immediately follows the data of `master' */
|
||||
axis_flags = (FT_UShort*)&( master[1] );
|
||||
*flags = axis_flags[axis_index];
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Set_Named_Instance( FT_Face face,
|
||||
FT_UInt instance_index )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
FT_Service_MultiMasters service_mm = NULL;
|
||||
FT_Service_MetricsVariations service_mvar = NULL;
|
||||
|
||||
|
||||
/* check of `face' delayed to `ft_face_get_mm_service' */
|
||||
|
||||
error = ft_face_get_mm_service( face, &service_mm );
|
||||
if ( !error )
|
||||
{
|
||||
error = FT_ERR( Invalid_Argument );
|
||||
if ( service_mm->set_named_instance )
|
||||
error = service_mm->set_named_instance( face, instance_index );
|
||||
|
||||
if ( !error || error == -1 )
|
||||
{
|
||||
FT_Bool is_variation_old = FT_IS_VARIATION( face );
|
||||
|
||||
|
||||
face->face_flags &= ~FT_FACE_FLAG_VARIATION;
|
||||
face->face_index = ( instance_index << 16 ) |
|
||||
( face->face_index & 0xFFFFL );
|
||||
|
||||
if ( service_mm->construct_ps_name )
|
||||
{
|
||||
if ( error == -1 )
|
||||
{
|
||||
/* The PS name of a named instance and a non-named instance */
|
||||
/* usually differs, even if the axis values are identical. */
|
||||
if ( is_variation_old != FT_IS_VARIATION( face ) )
|
||||
service_mm->construct_ps_name( face );
|
||||
}
|
||||
else
|
||||
service_mm->construct_ps_name( face );
|
||||
}
|
||||
}
|
||||
|
||||
/* internal error code -1 means `no change'; we can exit immediately */
|
||||
if ( error == -1 )
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
(void)ft_face_get_mvar_service( face, &service_mvar );
|
||||
|
||||
if ( service_mvar && service_mvar->metrics_adjust )
|
||||
service_mvar->metrics_adjust( face );
|
||||
}
|
||||
|
||||
/* enforce recomputation of auto-hinting data */
|
||||
if ( !error && face->autohint.finalizer )
|
||||
{
|
||||
face->autohint.finalizer( face->autohint.data );
|
||||
face->autohint.data = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Default_Named_Instance( FT_Face face,
|
||||
FT_UInt *instance_index )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
FT_Service_MultiMasters service_mm = NULL;
|
||||
|
||||
|
||||
/* check of `face' delayed to `ft_face_get_mm_service' */
|
||||
|
||||
error = ft_face_get_mm_service( face, &service_mm );
|
||||
if ( !error )
|
||||
{
|
||||
/* no error if `get_default_named_instance` is not available */
|
||||
if ( service_mm->get_default_named_instance )
|
||||
error = service_mm->get_default_named_instance( face,
|
||||
instance_index );
|
||||
else
|
||||
error = FT_Err_Ok;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
5917
thirdparty/freetype/src/base/ftobjs.c
vendored
Normal file
5917
thirdparty/freetype/src/base/ftobjs.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
90
thirdparty/freetype/src/base/ftotval.c
vendored
Normal file
90
thirdparty/freetype/src/base/ftotval.c
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftotval.c
|
||||
*
|
||||
* FreeType API for validating OpenType tables (body).
|
||||
*
|
||||
* Copyright (C) 2004-2024 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 <freetype/internal/ftdebug.h>
|
||||
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/services/svotval.h>
|
||||
#include <freetype/ftotval.h>
|
||||
|
||||
|
||||
/* documentation is in ftotval.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_OpenType_Validate( FT_Face face,
|
||||
FT_UInt validation_flags,
|
||||
FT_Bytes *BASE_table,
|
||||
FT_Bytes *GDEF_table,
|
||||
FT_Bytes *GPOS_table,
|
||||
FT_Bytes *GSUB_table,
|
||||
FT_Bytes *JSTF_table )
|
||||
{
|
||||
FT_Service_OTvalidate service;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
if ( !face )
|
||||
{
|
||||
error = FT_THROW( Invalid_Face_Handle );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( !( BASE_table &&
|
||||
GDEF_table &&
|
||||
GPOS_table &&
|
||||
GSUB_table &&
|
||||
JSTF_table ) )
|
||||
{
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
FT_FACE_FIND_GLOBAL_SERVICE( face, service, OPENTYPE_VALIDATE );
|
||||
|
||||
if ( service )
|
||||
error = service->validate( face,
|
||||
validation_flags,
|
||||
BASE_table,
|
||||
GDEF_table,
|
||||
GPOS_table,
|
||||
GSUB_table,
|
||||
JSTF_table );
|
||||
else
|
||||
error = FT_THROW( Unimplemented_Feature );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_OpenType_Free( FT_Face face,
|
||||
FT_Bytes table )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return;
|
||||
|
||||
memory = FT_FACE_MEMORY( face );
|
||||
|
||||
FT_FREE( table );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
1120
thirdparty/freetype/src/base/ftoutln.c
vendored
Normal file
1120
thirdparty/freetype/src/base/ftoutln.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
50
thirdparty/freetype/src/base/ftpatent.c
vendored
Normal file
50
thirdparty/freetype/src/base/ftpatent.c
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftpatent.c
|
||||
*
|
||||
* FreeType API for checking patented TrueType bytecode instructions
|
||||
* (body). Obsolete, retained for backward compatibility.
|
||||
*
|
||||
* Copyright (C) 2007-2024 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 <freetype/freetype.h>
|
||||
#include <freetype/tttags.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftstream.h>
|
||||
#include <freetype/internal/services/svsfnt.h>
|
||||
#include <freetype/internal/services/svttglyf.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 */
|
||||
152
thirdparty/freetype/src/base/ftpfr.c
vendored
Normal file
152
thirdparty/freetype/src/base/ftpfr.c
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftpfr.c
|
||||
*
|
||||
* FreeType API for accessing PFR-specific data (body).
|
||||
*
|
||||
* Copyright (C) 2002-2024 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 <freetype/internal/ftdebug.h>
|
||||
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/services/svpfr.h>
|
||||
|
||||
|
||||
/* check the format */
|
||||
static FT_Service_PfrMetrics
|
||||
ft_pfr_check( FT_Face face )
|
||||
{
|
||||
FT_Service_PfrMetrics service = NULL;
|
||||
|
||||
|
||||
if ( face )
|
||||
FT_FACE_LOOKUP_SERVICE( face, service, PFR_METRICS );
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftpfr.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_PFR_Metrics( FT_Face face,
|
||||
FT_UInt *aoutline_resolution,
|
||||
FT_UInt *ametrics_resolution,
|
||||
FT_Fixed *ametrics_x_scale,
|
||||
FT_Fixed *ametrics_y_scale )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Service_PfrMetrics service;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
service = ft_pfr_check( face );
|
||||
if ( service )
|
||||
{
|
||||
error = service->get_metrics( face,
|
||||
aoutline_resolution,
|
||||
ametrics_resolution,
|
||||
ametrics_x_scale,
|
||||
ametrics_y_scale );
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Fixed x_scale, y_scale;
|
||||
|
||||
|
||||
/* this is not a PFR font */
|
||||
if ( aoutline_resolution )
|
||||
*aoutline_resolution = face->units_per_EM;
|
||||
|
||||
if ( ametrics_resolution )
|
||||
*ametrics_resolution = face->units_per_EM;
|
||||
|
||||
x_scale = y_scale = 0x10000L;
|
||||
if ( face->size )
|
||||
{
|
||||
x_scale = face->size->metrics.x_scale;
|
||||
y_scale = face->size->metrics.y_scale;
|
||||
}
|
||||
|
||||
if ( ametrics_x_scale )
|
||||
*ametrics_x_scale = x_scale;
|
||||
|
||||
if ( ametrics_y_scale )
|
||||
*ametrics_y_scale = y_scale;
|
||||
|
||||
error = FT_THROW( Unknown_File_Format );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftpfr.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_PFR_Kerning( FT_Face face,
|
||||
FT_UInt left,
|
||||
FT_UInt right,
|
||||
FT_Vector *avector )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Service_PfrMetrics service;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
if ( !avector )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
service = ft_pfr_check( face );
|
||||
if ( service )
|
||||
error = service->get_kerning( face, left, right, avector );
|
||||
else
|
||||
error = FT_Get_Kerning( face, left, right,
|
||||
FT_KERNING_UNSCALED, avector );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftpfr.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_PFR_Advance( FT_Face face,
|
||||
FT_UInt gindex,
|
||||
FT_Pos *aadvance )
|
||||
{
|
||||
FT_Error error;
|
||||
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 );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
284
thirdparty/freetype/src/base/ftpsprop.c
vendored
Normal file
284
thirdparty/freetype/src/base/ftpsprop.c
vendored
Normal file
@@ -0,0 +1,284 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftpsprop.c
|
||||
*
|
||||
* Get and set properties of PostScript drivers (body).
|
||||
* See `ftdriver.h' for available properties.
|
||||
*
|
||||
* Copyright (C) 2017-2024 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 <freetype/ftdriver.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/psaux.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftpsprop.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 psprops
|
||||
|
||||
|
||||
FT_BASE_CALLBACK_DEF( FT_Error )
|
||||
ps_property_set( FT_Module module, /* PS_Driver */
|
||||
const char* property_name,
|
||||
const void* value,
|
||||
FT_Bool value_is_string )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
PS_Driver driver = (PS_Driver)module;
|
||||
|
||||
#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
FT_UNUSED( value_is_string );
|
||||
#endif
|
||||
|
||||
|
||||
if ( !ft_strcmp( property_name, "darkening-parameters" ) )
|
||||
{
|
||||
FT_Int* darken_params;
|
||||
FT_Int x1, y1, x2, y2, x3, y3, x4, y4;
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
FT_Int dp[8];
|
||||
|
||||
|
||||
if ( value_is_string )
|
||||
{
|
||||
const char* s = (const char*)value;
|
||||
char* ep;
|
||||
int i;
|
||||
|
||||
|
||||
/* eight comma-separated numbers */
|
||||
for ( i = 0; i < 7; i++ )
|
||||
{
|
||||
dp[i] = (FT_Int)ft_strtol( s, &ep, 10 );
|
||||
if ( *ep != ',' || s == ep )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
s = ep + 1;
|
||||
}
|
||||
|
||||
dp[7] = (FT_Int)ft_strtol( s, &ep, 10 );
|
||||
if ( !( *ep == '\0' || *ep == ' ' ) || s == ep )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
darken_params = dp;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
darken_params = (FT_Int*)value;
|
||||
|
||||
x1 = darken_params[0];
|
||||
y1 = darken_params[1];
|
||||
x2 = darken_params[2];
|
||||
y2 = darken_params[3];
|
||||
x3 = darken_params[4];
|
||||
y3 = darken_params[5];
|
||||
x4 = darken_params[6];
|
||||
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" ) )
|
||||
{
|
||||
#if defined( CFF_CONFIG_OPTION_OLD_ENGINE ) || \
|
||||
defined( T1_CONFIG_OPTION_OLD_ENGINE )
|
||||
const char* module_name = module->clazz->module_name;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
if ( value_is_string )
|
||||
{
|
||||
const char* s = (const char*)value;
|
||||
|
||||
|
||||
if ( !ft_strcmp( s, "adobe" ) )
|
||||
driver->hinting_engine = FT_HINTING_ADOBE;
|
||||
|
||||
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
||||
else if ( !ft_strcmp( module_name, "cff" ) &&
|
||||
!ft_strcmp( s, "freetype" ) )
|
||||
driver->hinting_engine = FT_HINTING_FREETYPE;
|
||||
#endif
|
||||
|
||||
#ifdef T1_CONFIG_OPTION_OLD_ENGINE
|
||||
else if ( ( !ft_strcmp( module_name, "type1" ) ||
|
||||
!ft_strcmp( module_name, "t1cid" ) ) &&
|
||||
!ft_strcmp( s, "freetype" ) )
|
||||
driver->hinting_engine = FT_HINTING_FREETYPE;
|
||||
#endif
|
||||
|
||||
else
|
||||
return FT_THROW( Invalid_Argument );
|
||||
}
|
||||
else
|
||||
#endif /* FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES */
|
||||
{
|
||||
FT_UInt* hinting_engine = (FT_UInt*)value;
|
||||
|
||||
|
||||
if ( *hinting_engine == FT_HINTING_ADOBE
|
||||
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
||||
|| ( *hinting_engine == FT_HINTING_FREETYPE &&
|
||||
!ft_strcmp( module_name, "cff" ) )
|
||||
#endif
|
||||
#ifdef T1_CONFIG_OPTION_OLD_ENGINE
|
||||
|| ( *hinting_engine == FT_HINTING_FREETYPE &&
|
||||
( !ft_strcmp( module_name, "type1" ) ||
|
||||
!ft_strcmp( module_name, "t1cid" ) ) )
|
||||
#endif
|
||||
)
|
||||
driver->hinting_engine = *hinting_engine;
|
||||
else
|
||||
error = FT_ERR( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
|
||||
{
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
if ( value_is_string )
|
||||
{
|
||||
const char* s = (const char*)value;
|
||||
long nsd = ft_strtol( s, NULL, 10 );
|
||||
|
||||
|
||||
if ( !nsd )
|
||||
driver->no_stem_darkening = FALSE;
|
||||
else
|
||||
driver->no_stem_darkening = TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
FT_Bool* no_stem_darkening = (FT_Bool*)value;
|
||||
|
||||
|
||||
driver->no_stem_darkening = *no_stem_darkening;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
else if ( !ft_strcmp( property_name, "random-seed" ) )
|
||||
{
|
||||
FT_Int32 random_seed;
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
if ( value_is_string )
|
||||
{
|
||||
const char* s = (const char*)value;
|
||||
|
||||
|
||||
random_seed = (FT_Int32)ft_strtol( s, NULL, 10 );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
random_seed = *(FT_Int32*)value;
|
||||
|
||||
if ( random_seed < 0 )
|
||||
random_seed = 0;
|
||||
|
||||
driver->random_seed = random_seed;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FT_TRACE2(( "ps_property_set: missing property `%s'\n",
|
||||
property_name ));
|
||||
return FT_THROW( Missing_Property );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_CALLBACK_DEF( FT_Error )
|
||||
ps_property_get( FT_Module module, /* PS_Driver */
|
||||
const char* property_name,
|
||||
void* value )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
PS_Driver driver = (PS_Driver)module;
|
||||
|
||||
|
||||
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];
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
else if ( !ft_strcmp( property_name, "hinting-engine" ) )
|
||||
{
|
||||
FT_UInt hinting_engine = driver->hinting_engine;
|
||||
FT_UInt* val = (FT_UInt*)value;
|
||||
|
||||
|
||||
*val = hinting_engine;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
|
||||
{
|
||||
FT_Bool no_stem_darkening = driver->no_stem_darkening;
|
||||
FT_Bool* val = (FT_Bool*)value;
|
||||
|
||||
|
||||
*val = no_stem_darkening;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FT_TRACE2(( "ps_property_get: missing property `%s'\n",
|
||||
property_name ));
|
||||
return FT_THROW( Missing_Property );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
934
thirdparty/freetype/src/base/ftrfork.c
vendored
Normal file
934
thirdparty/freetype/src/base/ftrfork.c
vendored
Normal file
@@ -0,0 +1,934 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftrfork.c
|
||||
*
|
||||
* Embedded resource forks accessor (body).
|
||||
*
|
||||
* Copyright (C) 2004-2024 by
|
||||
* Masatake YAMATO and Redhat K.K.
|
||||
*
|
||||
* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are
|
||||
* derived from ftobjs.c.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Development of the code in this file is support of
|
||||
* Information-technology Promotion Agency, Japan.
|
||||
*/
|
||||
|
||||
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftstream.h>
|
||||
#include <freetype/internal/ftrfork.h>
|
||||
|
||||
#include "ftbase.h"
|
||||
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT raccess
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/**** Resource fork directory access ****/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Raccess_Get_HeaderInfo( FT_Library library,
|
||||
FT_Stream stream,
|
||||
FT_Long rfork_offset,
|
||||
FT_Long *map_offset,
|
||||
FT_Long *rdata_pos )
|
||||
{
|
||||
FT_Error error;
|
||||
unsigned char head[16], head2[16];
|
||||
FT_Long map_pos, map_len, rdata_len;
|
||||
int allzeros, allmatch, i;
|
||||
FT_Long type_list;
|
||||
|
||||
FT_UNUSED( library );
|
||||
|
||||
|
||||
error = FT_Stream_Seek( stream, (FT_ULong)rfork_offset );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
error = FT_Stream_Read( stream, (FT_Byte*)head, 16 );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
/* ensure positive values */
|
||||
if ( head[0] >= 0x80 ||
|
||||
head[4] >= 0x80 ||
|
||||
head[8] >= 0x80 ||
|
||||
head[12] >= 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] << 24 ) |
|
||||
( head[13] << 16 ) |
|
||||
( head[14] << 8 ) |
|
||||
head[15];
|
||||
|
||||
/* the map must not be empty */
|
||||
if ( !map_pos )
|
||||
return FT_THROW( Unknown_File_Format );
|
||||
|
||||
/* check whether rdata and map overlap */
|
||||
if ( *rdata_pos < map_pos )
|
||||
{
|
||||
if ( *rdata_pos > map_pos - rdata_len )
|
||||
return FT_THROW( Unknown_File_Format );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( map_pos > *rdata_pos - map_len )
|
||||
return FT_THROW( Unknown_File_Format );
|
||||
}
|
||||
|
||||
/* check whether end of rdata or map exceeds stream size */
|
||||
if ( FT_LONG_MAX - rdata_len < *rdata_pos ||
|
||||
FT_LONG_MAX - map_len < map_pos ||
|
||||
|
||||
FT_LONG_MAX - ( *rdata_pos + rdata_len ) < rfork_offset ||
|
||||
FT_LONG_MAX - ( map_pos + map_len ) < rfork_offset ||
|
||||
|
||||
(FT_ULong)( rfork_offset + *rdata_pos + rdata_len ) > stream->size ||
|
||||
(FT_ULong)( rfork_offset + map_pos + map_len ) > stream->size )
|
||||
return FT_THROW( Unknown_File_Format );
|
||||
|
||||
*rdata_pos += rfork_offset;
|
||||
map_pos += rfork_offset;
|
||||
|
||||
error = FT_Stream_Seek( stream, (FT_ULong)map_pos );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */
|
||||
|
||||
error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
allzeros = 1;
|
||||
allmatch = 1;
|
||||
for ( i = 0; i < 16; i++ )
|
||||
{
|
||||
if ( head2[i] != 0 )
|
||||
allzeros = 0;
|
||||
if ( head2[i] != head[i] )
|
||||
allmatch = 0;
|
||||
}
|
||||
if ( !allzeros && !allmatch )
|
||||
return FT_THROW( Unknown_File_Format );
|
||||
|
||||
/* If we have reached this point then it is probably a mac resource */
|
||||
/* file. Now, does it contain any interesting resources? */
|
||||
|
||||
(void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */
|
||||
+ 2 /* skip file resource number */
|
||||
+ 2 ); /* skip attributes */
|
||||
|
||||
if ( FT_READ_SHORT( type_list ) )
|
||||
return error;
|
||||
if ( type_list < 0 )
|
||||
return FT_THROW( Unknown_File_Format );
|
||||
|
||||
error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
*map_offset = map_pos + type_list;
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
FT_COMPARE_DEF( int )
|
||||
ft_raccess_sort_ref_by_id( const void* a,
|
||||
const void* b )
|
||||
{
|
||||
return ( (FT_RFork_Ref*)a )->res_id - ( (FT_RFork_Ref*)b )->res_id;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Raccess_Get_DataOffsets( FT_Library library,
|
||||
FT_Stream stream,
|
||||
FT_Long map_offset,
|
||||
FT_Long rdata_pos,
|
||||
FT_Long tag,
|
||||
FT_Bool sort_by_res_id,
|
||||
FT_Long **offsets,
|
||||
FT_Long *count )
|
||||
{
|
||||
FT_Error error;
|
||||
int i, j, cnt, subcnt;
|
||||
FT_Long tag_internal, rpos;
|
||||
FT_Memory memory = library->memory;
|
||||
FT_Long temp;
|
||||
FT_Long *offsets_internal = NULL;
|
||||
FT_RFork_Ref *ref = NULL;
|
||||
|
||||
|
||||
FT_TRACE3(( "\n" ));
|
||||
error = FT_Stream_Seek( stream, (FT_ULong)map_offset );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
if ( FT_READ_SHORT( cnt ) )
|
||||
return error;
|
||||
cnt++;
|
||||
|
||||
/* `rpos' is a signed 16bit integer offset to resource records; the */
|
||||
/* size of a resource record is 12 bytes. The map header is 28 bytes, */
|
||||
/* and a type list needs 10 bytes or more. If we assume that the name */
|
||||
/* list is empty and we have only a single entry in the type list, */
|
||||
/* there can be at most */
|
||||
/* */
|
||||
/* (32768 - 28 - 10) / 12 = 2727 */
|
||||
/* */
|
||||
/* resources. */
|
||||
/* */
|
||||
/* A type list starts with a two-byte counter, followed by 10-byte */
|
||||
/* type records. Assuming that there are no resources, the number of */
|
||||
/* type records can be at most */
|
||||
/* */
|
||||
/* (32768 - 28 - 2) / 8 = 4079 */
|
||||
/* */
|
||||
if ( cnt > 4079 )
|
||||
return FT_THROW( Invalid_Table );
|
||||
|
||||
for ( i = 0; i < cnt; i++ )
|
||||
{
|
||||
if ( FT_READ_LONG( tag_internal ) ||
|
||||
FT_READ_SHORT( subcnt ) ||
|
||||
FT_READ_SHORT( rpos ) )
|
||||
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 ) ) ));
|
||||
FT_TRACE3(( " : subcount=%d, suboffset=0x%04lx\n",
|
||||
subcnt, rpos ));
|
||||
|
||||
if ( tag_internal == tag )
|
||||
{
|
||||
*count = subcnt + 1;
|
||||
rpos += map_offset;
|
||||
|
||||
/* a zero count might be valid in the resource specification, */
|
||||
/* however, it is completely useless to us */
|
||||
if ( *count < 1 || *count > 2727 )
|
||||
return FT_THROW( Invalid_Table );
|
||||
|
||||
error = FT_Stream_Seek( stream, (FT_ULong)rpos );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
if ( FT_QNEW_ARRAY( ref, *count ) )
|
||||
return error;
|
||||
|
||||
for ( j = 0; j < *count; j++ )
|
||||
{
|
||||
if ( FT_READ_SHORT( ref[j].res_id ) )
|
||||
goto Exit;
|
||||
if ( FT_STREAM_SKIP( 2 ) ) /* resource name offset */
|
||||
goto Exit;
|
||||
if ( FT_READ_LONG( temp ) ) /* attributes (8bit), offset (24bit) */
|
||||
goto Exit;
|
||||
if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
|
||||
goto Exit;
|
||||
|
||||
/*
|
||||
* According to Inside Macintosh: More Macintosh Toolbox,
|
||||
* "Resource IDs" (1-46), there are some reserved IDs.
|
||||
* However, FreeType2 is not a font synthesizer, no need
|
||||
* to check the acceptable resource ID.
|
||||
*/
|
||||
if ( temp < 0 )
|
||||
{
|
||||
error = FT_THROW( Invalid_Table );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
ref[j].offset = temp & 0xFFFFFFL;
|
||||
|
||||
FT_TRACE3(( " [%d]:"
|
||||
" resource_id=0x%04x, offset=0x%08lx\n",
|
||||
j, (FT_UShort)ref[j].res_id, ref[j].offset ));
|
||||
}
|
||||
|
||||
if ( sort_by_res_id )
|
||||
{
|
||||
ft_qsort( ref,
|
||||
(size_t)*count,
|
||||
sizeof ( FT_RFork_Ref ),
|
||||
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%08lx\n",
|
||||
j, ref[j].res_id, ref[j].offset ));
|
||||
}
|
||||
|
||||
if ( FT_QNEW_ARRAY( offsets_internal, *count ) )
|
||||
goto Exit;
|
||||
|
||||
/* XXX: duplicated reference ID,
|
||||
* gap between reference IDs are acceptable?
|
||||
* further investigation on Apple implementation is needed.
|
||||
*/
|
||||
for ( j = 0; j < *count; j++ )
|
||||
offsets_internal[j] = rdata_pos + ref[j].offset;
|
||||
|
||||
*offsets = offsets_internal;
|
||||
error = FT_Err_Ok;
|
||||
|
||||
Exit:
|
||||
FT_FREE( ref );
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return FT_THROW( Cannot_Open_Resource );
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/**** Guessing functions ****/
|
||||
/**** ****/
|
||||
/**** When you add a new guessing function, ****/
|
||||
/**** update FT_RACCESS_N_RULES in ftrfork.h. ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_apple_double( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset );
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_apple_single( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset );
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_darwin_ufs_export( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset );
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_darwin_newvfs( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset );
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_darwin_hfsplus( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset );
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_vfat( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset );
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_linux_cap( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset );
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_linux_double( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset );
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_linux_netatalk( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset );
|
||||
|
||||
|
||||
CONST_FT_RFORK_RULE_ARRAY_BEGIN( ft_raccess_guess_table,
|
||||
ft_raccess_guess_rec )
|
||||
CONST_FT_RFORK_RULE_ARRAY_ENTRY( apple_double, apple_double )
|
||||
CONST_FT_RFORK_RULE_ARRAY_ENTRY( apple_single, apple_single )
|
||||
CONST_FT_RFORK_RULE_ARRAY_ENTRY( darwin_ufs_export, darwin_ufs_export )
|
||||
CONST_FT_RFORK_RULE_ARRAY_ENTRY( darwin_newvfs, darwin_newvfs )
|
||||
CONST_FT_RFORK_RULE_ARRAY_ENTRY( darwin_hfsplus, darwin_hfsplus )
|
||||
CONST_FT_RFORK_RULE_ARRAY_ENTRY( vfat, vfat )
|
||||
CONST_FT_RFORK_RULE_ARRAY_ENTRY( linux_cap, linux_cap )
|
||||
CONST_FT_RFORK_RULE_ARRAY_ENTRY( linux_double, linux_double )
|
||||
CONST_FT_RFORK_RULE_ARRAY_ENTRY( linux_netatalk, linux_netatalk )
|
||||
CONST_FT_RFORK_RULE_ARRAY_END
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** Helper functions ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_apple_generic( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
FT_Int32 magic,
|
||||
FT_Long *result_offset );
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_linux_double_from_file_name( FT_Library library,
|
||||
char* file_name,
|
||||
FT_Long *result_offset );
|
||||
|
||||
static char *
|
||||
raccess_make_file_name( FT_Memory memory,
|
||||
const char *original_name,
|
||||
const char *insertion );
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Raccess_Guess( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char* base_name,
|
||||
char **new_names,
|
||||
FT_Long *offsets,
|
||||
FT_Error *errors )
|
||||
{
|
||||
FT_Int i;
|
||||
|
||||
|
||||
for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
|
||||
{
|
||||
new_names[i] = NULL;
|
||||
if ( NULL != stream )
|
||||
errors[i] = FT_Stream_Seek( stream, 0 );
|
||||
else
|
||||
errors[i] = FT_Err_Ok;
|
||||
|
||||
if ( errors[i] )
|
||||
continue;
|
||||
|
||||
errors[i] = ft_raccess_guess_table[i].func( library,
|
||||
stream, base_name,
|
||||
&(new_names[i]),
|
||||
&(offsets[i]) );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#if defined( FT_CONFIG_OPTION_MAC_FONTS ) && !defined( FT_MACINTOSH )
|
||||
static FT_RFork_Rule
|
||||
raccess_get_rule_type_from_rule_index( FT_Library library,
|
||||
FT_UInt rule_index )
|
||||
{
|
||||
FT_UNUSED( library );
|
||||
|
||||
if ( rule_index >= FT_RACCESS_N_RULES )
|
||||
return FT_RFork_Rule_invalid;
|
||||
|
||||
return ft_raccess_guess_table[rule_index].type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* For this function, refer ftbase.h.
|
||||
*/
|
||||
FT_LOCAL_DEF( FT_Bool )
|
||||
ft_raccess_rule_by_darwin_vfs( FT_Library library,
|
||||
FT_UInt rule_index )
|
||||
{
|
||||
switch( raccess_get_rule_type_from_rule_index( library, rule_index ) )
|
||||
{
|
||||
case FT_RFork_Rule_darwin_newvfs:
|
||||
case FT_RFork_Rule_darwin_hfsplus:
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_apple_double( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
FT_Int32 magic = ( 0x00 << 24 ) |
|
||||
( 0x05 << 16 ) |
|
||||
( 0x16 << 8 ) |
|
||||
0x07;
|
||||
|
||||
|
||||
*result_file_name = NULL;
|
||||
if ( NULL == stream )
|
||||
return FT_THROW( Cannot_Open_Stream );
|
||||
|
||||
return raccess_guess_apple_generic( library, stream, base_file_name,
|
||||
magic, result_offset );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_apple_single( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
FT_Int32 magic = ( 0x00 << 24 ) |
|
||||
( 0x05 << 16 ) |
|
||||
( 0x16 << 8 ) |
|
||||
0x00;
|
||||
|
||||
|
||||
*result_file_name = NULL;
|
||||
if ( NULL == stream )
|
||||
return FT_THROW( Cannot_Open_Stream );
|
||||
|
||||
return raccess_guess_apple_generic( library, stream, base_file_name,
|
||||
magic, result_offset );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_darwin_ufs_export( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
char* newpath;
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
memory = library->memory;
|
||||
newpath = raccess_make_file_name( memory, base_file_name, "._" );
|
||||
if ( !newpath )
|
||||
return FT_THROW( Out_Of_Memory );
|
||||
|
||||
error = raccess_guess_linux_double_from_file_name( library, newpath,
|
||||
result_offset );
|
||||
if ( !error )
|
||||
*result_file_name = newpath;
|
||||
else
|
||||
FT_FREE( newpath );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_darwin_hfsplus( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
/*
|
||||
Only meaningful on systems with hfs+ drivers (or Macs).
|
||||
*/
|
||||
FT_Error error;
|
||||
char* newpath = NULL;
|
||||
FT_Memory memory;
|
||||
FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name );
|
||||
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
if ( base_file_len + 6 > FT_INT_MAX )
|
||||
return FT_THROW( Array_Too_Large );
|
||||
|
||||
if ( FT_QALLOC( newpath, base_file_len + 6 ) )
|
||||
return error;
|
||||
|
||||
FT_MEM_COPY( newpath, base_file_name, base_file_len );
|
||||
FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );
|
||||
|
||||
*result_file_name = newpath;
|
||||
*result_offset = 0;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_darwin_newvfs( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
/*
|
||||
Only meaningful on systems with Mac OS X (> 10.1).
|
||||
*/
|
||||
FT_Error error;
|
||||
char* newpath = NULL;
|
||||
FT_Memory memory;
|
||||
FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name );
|
||||
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
if ( base_file_len + 18 > FT_INT_MAX )
|
||||
return FT_THROW( Array_Too_Large );
|
||||
|
||||
if ( FT_QALLOC( newpath, base_file_len + 18 ) )
|
||||
return error;
|
||||
|
||||
FT_MEM_COPY( newpath, base_file_name, base_file_len );
|
||||
FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 );
|
||||
|
||||
*result_file_name = newpath;
|
||||
*result_offset = 0;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_vfat( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
char* newpath;
|
||||
FT_Memory memory;
|
||||
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
newpath = raccess_make_file_name( memory, base_file_name,
|
||||
"resource.frk/" );
|
||||
if ( !newpath )
|
||||
return FT_THROW( Out_Of_Memory );
|
||||
|
||||
*result_file_name = newpath;
|
||||
*result_offset = 0;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_linux_cap( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
char* newpath;
|
||||
FT_Memory memory;
|
||||
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
newpath = raccess_make_file_name( memory, base_file_name, ".resource/" );
|
||||
if ( !newpath )
|
||||
return FT_THROW( Out_Of_Memory );
|
||||
|
||||
*result_file_name = newpath;
|
||||
*result_offset = 0;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_linux_double( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
char* newpath;
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
newpath = raccess_make_file_name( memory, base_file_name, "%" );
|
||||
if ( !newpath )
|
||||
return FT_THROW( Out_Of_Memory );
|
||||
|
||||
error = raccess_guess_linux_double_from_file_name( library, newpath,
|
||||
result_offset );
|
||||
if ( !error )
|
||||
*result_file_name = newpath;
|
||||
else
|
||||
FT_FREE( newpath );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_linux_netatalk( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
char **result_file_name,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
char* newpath;
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
newpath = raccess_make_file_name( memory, base_file_name,
|
||||
".AppleDouble/" );
|
||||
if ( !newpath )
|
||||
return FT_THROW( Out_Of_Memory );
|
||||
|
||||
error = raccess_guess_linux_double_from_file_name( library, newpath,
|
||||
result_offset );
|
||||
if ( !error )
|
||||
*result_file_name = newpath;
|
||||
else
|
||||
FT_FREE( newpath );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_apple_generic( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_file_name,
|
||||
FT_Int32 magic,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
FT_Int32 magic_from_stream;
|
||||
FT_Error error;
|
||||
FT_Int32 version_number = 0;
|
||||
FT_UShort n_of_entries;
|
||||
|
||||
int i;
|
||||
FT_Int32 entry_id, entry_offset, entry_length = 0;
|
||||
|
||||
const FT_Int32 resource_fork_entry_id = 0x2;
|
||||
|
||||
FT_UNUSED( library );
|
||||
FT_UNUSED( base_file_name );
|
||||
FT_UNUSED( version_number );
|
||||
FT_UNUSED( entry_length );
|
||||
|
||||
|
||||
if ( FT_READ_LONG( magic_from_stream ) )
|
||||
return error;
|
||||
if ( magic_from_stream != magic )
|
||||
return FT_THROW( Unknown_File_Format );
|
||||
|
||||
if ( FT_READ_LONG( version_number ) )
|
||||
return error;
|
||||
|
||||
/* filler */
|
||||
error = FT_Stream_Skip( stream, 16 );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
if ( FT_READ_USHORT( n_of_entries ) )
|
||||
return error;
|
||||
if ( n_of_entries == 0 )
|
||||
return FT_THROW( Unknown_File_Format );
|
||||
|
||||
for ( i = 0; i < n_of_entries; i++ )
|
||||
{
|
||||
if ( FT_READ_LONG( entry_id ) )
|
||||
return error;
|
||||
if ( entry_id == resource_fork_entry_id )
|
||||
{
|
||||
if ( FT_READ_LONG( entry_offset ) ||
|
||||
FT_READ_LONG( entry_length ) )
|
||||
continue;
|
||||
*result_offset = entry_offset;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */
|
||||
if ( error )
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return FT_THROW( Unknown_File_Format );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
raccess_guess_linux_double_from_file_name( FT_Library library,
|
||||
char *file_name,
|
||||
FT_Long *result_offset )
|
||||
{
|
||||
FT_Open_Args args2;
|
||||
FT_Stream stream2;
|
||||
char* nouse = NULL;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
args2.flags = FT_OPEN_PATHNAME;
|
||||
args2.pathname = file_name;
|
||||
error = FT_Stream_New( library, &args2, &stream2 );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
error = raccess_guess_apple_double( library, stream2, file_name,
|
||||
&nouse, result_offset );
|
||||
|
||||
FT_Stream_Free( stream2, 0 );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static char*
|
||||
raccess_make_file_name( FT_Memory memory,
|
||||
const char *original_name,
|
||||
const char *insertion )
|
||||
{
|
||||
char* new_name = NULL;
|
||||
const char* tmp;
|
||||
const char* slash;
|
||||
size_t new_length;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
new_length = ft_strlen( original_name ) + ft_strlen( insertion );
|
||||
if ( FT_QALLOC( new_name, new_length + 1 ) )
|
||||
return NULL;
|
||||
|
||||
tmp = ft_strrchr( original_name, '/' );
|
||||
if ( tmp )
|
||||
{
|
||||
ft_strncpy( new_name,
|
||||
original_name,
|
||||
(size_t)( tmp - original_name + 1 ) );
|
||||
new_name[tmp - original_name + 1] = '\0';
|
||||
slash = tmp + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
slash = original_name;
|
||||
new_name[0] = '\0';
|
||||
}
|
||||
|
||||
ft_strcat( new_name, insertion );
|
||||
ft_strcat( new_name, slash );
|
||||
|
||||
return new_name;
|
||||
}
|
||||
|
||||
|
||||
#else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Dummy function; just sets errors
|
||||
*/
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Raccess_Guess( FT_Library library,
|
||||
FT_Stream stream,
|
||||
char *base_name,
|
||||
char **new_names,
|
||||
FT_Long *offsets,
|
||||
FT_Error *errors )
|
||||
{
|
||||
FT_Int i;
|
||||
|
||||
FT_UNUSED( library );
|
||||
FT_UNUSED( stream );
|
||||
FT_UNUSED( base_name );
|
||||
|
||||
|
||||
for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
|
||||
{
|
||||
new_names[i] = NULL;
|
||||
offsets[i] = 0;
|
||||
errors[i] = FT_ERR( Unimplemented_Feature );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
|
||||
|
||||
|
||||
/* END */
|
||||
185
thirdparty/freetype/src/base/ftsnames.c
vendored
Normal file
185
thirdparty/freetype/src/base/ftsnames.c
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftsnames.c
|
||||
*
|
||||
* Simple interface to access SFNT name tables (which are used
|
||||
* to hold font names, copyright info, notices, etc.) (body).
|
||||
*
|
||||
* This is _not_ used to retrieve glyph names!
|
||||
*
|
||||
* Copyright (C) 1996-2024 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 <freetype/internal/ftdebug.h>
|
||||
|
||||
#include <freetype/ftsnames.h>
|
||||
#include <freetype/internal/tttypes.h>
|
||||
#include <freetype/internal/ftstream.h>
|
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_SFNT_NAMES
|
||||
|
||||
|
||||
/* documentation is in ftsnames.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_UInt )
|
||||
FT_Get_Sfnt_Name_Count( FT_Face face )
|
||||
{
|
||||
return ( face && FT_IS_SFNT( face ) ) ? ((TT_Face)face)->num_names : 0;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftsnames.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Sfnt_Name( FT_Face face,
|
||||
FT_UInt idx,
|
||||
FT_SfntName *aname )
|
||||
{
|
||||
FT_Error error = FT_ERR( Invalid_Argument );
|
||||
|
||||
|
||||
if ( aname && face && FT_IS_SFNT( face ) )
|
||||
{
|
||||
TT_Face ttface = (TT_Face)face;
|
||||
|
||||
|
||||
if ( idx < (FT_UInt)ttface->num_names )
|
||||
{
|
||||
TT_Name entry = ttface->name_table.names + idx;
|
||||
|
||||
|
||||
/* load name on demand */
|
||||
if ( entry->stringLength > 0 && !entry->string )
|
||||
{
|
||||
FT_Memory memory = face->memory;
|
||||
FT_Stream stream = face->stream;
|
||||
|
||||
|
||||
if ( FT_QNEW_ARRAY ( entry->string, entry->stringLength ) ||
|
||||
FT_STREAM_SEEK( entry->stringOffset ) ||
|
||||
FT_STREAM_READ( entry->string, entry->stringLength ) )
|
||||
{
|
||||
FT_FREE( entry->string );
|
||||
entry->stringLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
aname->platform_id = entry->platformID;
|
||||
aname->encoding_id = entry->encodingID;
|
||||
aname->language_id = entry->languageID;
|
||||
aname->name_id = entry->nameID;
|
||||
aname->string = (FT_Byte*)entry->string;
|
||||
aname->string_len = entry->stringLength;
|
||||
|
||||
error = FT_Err_Ok;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftsnames.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Sfnt_LangTag( FT_Face face,
|
||||
FT_UInt langID,
|
||||
FT_SfntLangTag *alangTag )
|
||||
{
|
||||
FT_Error error = FT_ERR( Invalid_Argument );
|
||||
|
||||
|
||||
if ( alangTag && face && FT_IS_SFNT( face ) )
|
||||
{
|
||||
TT_Face ttface = (TT_Face)face;
|
||||
|
||||
|
||||
if ( ttface->name_table.format != 1 )
|
||||
return FT_THROW( Invalid_Table );
|
||||
|
||||
if ( langID > 0x8000U &&
|
||||
langID - 0x8000U < ttface->name_table.numLangTagRecords )
|
||||
{
|
||||
TT_LangTag entry = ttface->name_table.langTags +
|
||||
( langID - 0x8000U );
|
||||
|
||||
|
||||
/* load name on demand */
|
||||
if ( entry->stringLength > 0 && !entry->string )
|
||||
{
|
||||
FT_Memory memory = face->memory;
|
||||
FT_Stream stream = face->stream;
|
||||
|
||||
|
||||
if ( FT_QNEW_ARRAY ( entry->string, entry->stringLength ) ||
|
||||
FT_STREAM_SEEK( entry->stringOffset ) ||
|
||||
FT_STREAM_READ( entry->string, entry->stringLength ) )
|
||||
{
|
||||
FT_FREE( entry->string );
|
||||
entry->stringLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
alangTag->string = (FT_Byte*)entry->string;
|
||||
alangTag->string_len = entry->stringLength;
|
||||
|
||||
error = FT_Err_Ok;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#else /* !TT_CONFIG_OPTION_SFNT_NAMES */
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_UInt )
|
||||
FT_Get_Sfnt_Name_Count( FT_Face face )
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Sfnt_Name( FT_Face face,
|
||||
FT_UInt idx,
|
||||
FT_SfntName *aname )
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( idx );
|
||||
FT_UNUSED( aname );
|
||||
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_Sfnt_LangTag( FT_Face face,
|
||||
FT_UInt langID,
|
||||
FT_SfntLangTag *alangTag )
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( langID );
|
||||
FT_UNUSED( alangTag );
|
||||
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
|
||||
#endif /* !TT_CONFIG_OPTION_SFNT_NAMES */
|
||||
|
||||
|
||||
/* END */
|
||||
872
thirdparty/freetype/src/base/ftstream.c
vendored
Normal file
872
thirdparty/freetype/src/base/ftstream.c
vendored
Normal file
@@ -0,0 +1,872 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftstream.c
|
||||
*
|
||||
* I/O stream support (body).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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 <freetype/internal/ftstream.h>
|
||||
#include <freetype/internal/ftdebug.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 stream
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Stream_OpenMemory( FT_Stream stream,
|
||||
const FT_Byte* base,
|
||||
FT_ULong size )
|
||||
{
|
||||
stream->base = (FT_Byte*) base;
|
||||
stream->size = size;
|
||||
stream->pos = 0;
|
||||
stream->cursor = NULL;
|
||||
stream->read = NULL;
|
||||
stream->close = NULL;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Stream_Close( FT_Stream stream )
|
||||
{
|
||||
if ( stream && stream->close )
|
||||
stream->close( stream );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Stream_Seek( FT_Stream stream,
|
||||
FT_ULong pos )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, pos, NULL, 0 ) )
|
||||
{
|
||||
FT_ERROR(( "FT_Stream_Seek:"
|
||||
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
pos, stream->size ));
|
||||
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
}
|
||||
}
|
||||
/* note that seeking to the first position after the file is valid */
|
||||
else if ( pos > stream->size )
|
||||
{
|
||||
FT_ERROR(( "FT_Stream_Seek:"
|
||||
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
pos, stream->size ));
|
||||
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
}
|
||||
|
||||
if ( !error )
|
||||
stream->pos = pos;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Stream_Skip( FT_Stream stream,
|
||||
FT_Long distance )
|
||||
{
|
||||
if ( distance < 0 )
|
||||
return FT_THROW( Invalid_Stream_Operation );
|
||||
|
||||
return FT_Stream_Seek( stream, stream->pos + (FT_ULong)distance );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_ULong )
|
||||
FT_Stream_Pos( FT_Stream stream )
|
||||
{
|
||||
return stream->pos;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Stream_Read( FT_Stream stream,
|
||||
FT_Byte* buffer,
|
||||
FT_ULong count )
|
||||
{
|
||||
return FT_Stream_ReadAt( stream, stream->pos, buffer, count );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Stream_ReadAt( FT_Stream stream,
|
||||
FT_ULong pos,
|
||||
FT_Byte* buffer,
|
||||
FT_ULong count )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_ULong read_bytes;
|
||||
|
||||
|
||||
if ( pos >= stream->size )
|
||||
{
|
||||
FT_ERROR(( "FT_Stream_ReadAt:"
|
||||
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
pos, stream->size ));
|
||||
|
||||
return FT_THROW( Invalid_Stream_Operation );
|
||||
}
|
||||
|
||||
if ( stream->read )
|
||||
read_bytes = stream->read( stream, pos, buffer, count );
|
||||
else
|
||||
{
|
||||
read_bytes = stream->size - pos;
|
||||
if ( read_bytes > count )
|
||||
read_bytes = count;
|
||||
|
||||
/* Allow "reading" zero bytes without UB even if buffer is NULL */
|
||||
if ( count )
|
||||
FT_MEM_COPY( buffer, stream->base + pos, read_bytes );
|
||||
}
|
||||
|
||||
stream->pos = pos + read_bytes;
|
||||
|
||||
if ( read_bytes < count )
|
||||
{
|
||||
FT_ERROR(( "FT_Stream_ReadAt:"
|
||||
" invalid read; expected %lu bytes, got %lu\n",
|
||||
count, read_bytes ));
|
||||
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_ULong )
|
||||
FT_Stream_TryRead( FT_Stream stream,
|
||||
FT_Byte* buffer,
|
||||
FT_ULong count )
|
||||
{
|
||||
FT_ULong read_bytes = 0;
|
||||
|
||||
|
||||
if ( stream->pos >= stream->size )
|
||||
goto Exit;
|
||||
|
||||
if ( stream->read )
|
||||
read_bytes = stream->read( stream, stream->pos, buffer, count );
|
||||
else
|
||||
{
|
||||
read_bytes = stream->size - stream->pos;
|
||||
if ( read_bytes > count )
|
||||
read_bytes = count;
|
||||
|
||||
/* Allow "reading" zero bytes without UB even if buffer is NULL */
|
||||
if ( count )
|
||||
FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes );
|
||||
}
|
||||
|
||||
stream->pos += read_bytes;
|
||||
|
||||
Exit:
|
||||
return read_bytes;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Stream_ExtractFrame( FT_Stream stream,
|
||||
FT_ULong count,
|
||||
FT_Byte** pbytes )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
error = FT_Stream_EnterFrame( stream, count );
|
||||
if ( !error )
|
||||
{
|
||||
*pbytes = (FT_Byte*)stream->cursor;
|
||||
|
||||
/* equivalent to FT_Stream_ExitFrame(), with no memory block release */
|
||||
stream->cursor = NULL;
|
||||
stream->limit = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Stream_ReleaseFrame( FT_Stream stream,
|
||||
FT_Byte** pbytes )
|
||||
{
|
||||
if ( stream && stream->read )
|
||||
{
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
ft_mem_free( memory, *pbytes );
|
||||
#else
|
||||
FT_FREE( *pbytes );
|
||||
#endif
|
||||
}
|
||||
|
||||
*pbytes = NULL;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Stream_EnterFrame( FT_Stream stream,
|
||||
FT_ULong count )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_ULong read_bytes;
|
||||
|
||||
|
||||
FT_TRACE7(( "FT_Stream_EnterFrame: %ld bytes\n", count ));
|
||||
|
||||
/* check for nested frame access */
|
||||
FT_ASSERT( stream && stream->cursor == 0 );
|
||||
|
||||
if ( stream->read )
|
||||
{
|
||||
/* allocate the frame in memory */
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
/* simple sanity check */
|
||||
if ( count > stream->size )
|
||||
{
|
||||
FT_ERROR(( "FT_Stream_EnterFrame:"
|
||||
" frame size (%lu) larger than stream size (%lu)\n",
|
||||
count, stream->size ));
|
||||
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
/* assume `ft_debug_file_` and `ft_debug_lineno_` are already set */
|
||||
stream->base = (unsigned char*)ft_mem_qalloc( memory,
|
||||
(FT_Long)count,
|
||||
&error );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
#else
|
||||
if ( FT_QALLOC( stream->base, count ) )
|
||||
goto Exit;
|
||||
#endif
|
||||
/* read it */
|
||||
read_bytes = stream->read( stream, stream->pos,
|
||||
stream->base, count );
|
||||
if ( read_bytes < count )
|
||||
{
|
||||
FT_ERROR(( "FT_Stream_EnterFrame:"
|
||||
" invalid read; expected %lu bytes, got %lu\n",
|
||||
count, read_bytes ));
|
||||
|
||||
FT_FREE( stream->base );
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
}
|
||||
|
||||
stream->cursor = stream->base;
|
||||
stream->limit = FT_OFFSET( stream->cursor, count );
|
||||
stream->pos += read_bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* check current and new position */
|
||||
if ( stream->pos >= stream->size ||
|
||||
stream->size - stream->pos < count )
|
||||
{
|
||||
FT_ERROR(( "FT_Stream_EnterFrame:"
|
||||
" invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
|
||||
stream->pos, count, stream->size ));
|
||||
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* set cursor */
|
||||
stream->cursor = stream->base + stream->pos;
|
||||
stream->limit = stream->cursor + count;
|
||||
stream->pos += count;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
FT_Stream_ExitFrame( FT_Stream stream )
|
||||
{
|
||||
/* IMPORTANT: The assertion stream->cursor != 0 was removed, given */
|
||||
/* that it is possible to access a frame of length 0 in */
|
||||
/* some weird fonts (usually, when accessing an array of */
|
||||
/* 0 records, like in some strange kern tables). */
|
||||
/* */
|
||||
/* In this case, the loader code handles the 0-length table */
|
||||
/* gracefully; however, stream.cursor is really set to 0 by the */
|
||||
/* FT_Stream_EnterFrame() call, and this is not an error. */
|
||||
|
||||
FT_TRACE7(( "FT_Stream_ExitFrame\n" ));
|
||||
|
||||
FT_ASSERT( stream );
|
||||
|
||||
if ( stream->read )
|
||||
{
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
ft_mem_free( memory, stream->base );
|
||||
stream->base = NULL;
|
||||
#else
|
||||
FT_FREE( stream->base );
|
||||
#endif
|
||||
}
|
||||
|
||||
stream->cursor = NULL;
|
||||
stream->limit = NULL;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Byte )
|
||||
FT_Stream_GetByte( FT_Stream stream )
|
||||
{
|
||||
FT_Byte result;
|
||||
|
||||
|
||||
FT_ASSERT( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
if ( stream->cursor < stream->limit )
|
||||
result = *stream->cursor++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_UInt16 )
|
||||
FT_Stream_GetUShort( FT_Stream stream )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_UInt16 result;
|
||||
|
||||
|
||||
FT_ASSERT( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
p = stream->cursor;
|
||||
if ( p + 1 < stream->limit )
|
||||
result = FT_NEXT_USHORT( p );
|
||||
stream->cursor = p;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_UInt16 )
|
||||
FT_Stream_GetUShortLE( FT_Stream stream )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_UInt16 result;
|
||||
|
||||
|
||||
FT_ASSERT( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
p = stream->cursor;
|
||||
if ( p + 1 < stream->limit )
|
||||
result = FT_NEXT_USHORT_LE( p );
|
||||
stream->cursor = p;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_UInt32 )
|
||||
FT_Stream_GetUOffset( FT_Stream stream )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_UInt32 result;
|
||||
|
||||
|
||||
FT_ASSERT( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
p = stream->cursor;
|
||||
if ( p + 2 < stream->limit )
|
||||
result = FT_NEXT_UOFF3( p );
|
||||
stream->cursor = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_UInt32 )
|
||||
FT_Stream_GetULong( FT_Stream stream )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_UInt32 result;
|
||||
|
||||
|
||||
FT_ASSERT( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
p = stream->cursor;
|
||||
if ( p + 3 < stream->limit )
|
||||
result = FT_NEXT_ULONG( p );
|
||||
stream->cursor = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_UInt32 )
|
||||
FT_Stream_GetULongLE( FT_Stream stream )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_UInt32 result;
|
||||
|
||||
|
||||
FT_ASSERT( stream && stream->cursor );
|
||||
|
||||
result = 0;
|
||||
p = stream->cursor;
|
||||
if ( p + 3 < stream->limit )
|
||||
result = FT_NEXT_ULONG_LE( p );
|
||||
stream->cursor = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Byte )
|
||||
FT_Stream_ReadByte( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte result = 0;
|
||||
|
||||
|
||||
FT_ASSERT( stream );
|
||||
|
||||
if ( stream->pos < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
|
||||
goto Fail;
|
||||
}
|
||||
else
|
||||
result = stream->base[stream->pos];
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos++;
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
*error = FT_THROW( Invalid_Stream_Operation );
|
||||
FT_ERROR(( "FT_Stream_ReadByte:"
|
||||
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_UInt16 )
|
||||
FT_Stream_ReadUShort( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte reads[2];
|
||||
FT_Byte* p;
|
||||
FT_UInt16 result = 0;
|
||||
|
||||
|
||||
FT_ASSERT( stream );
|
||||
|
||||
if ( stream->pos + 1 < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
|
||||
goto Fail;
|
||||
|
||||
p = reads;
|
||||
}
|
||||
else
|
||||
p = stream->base + stream->pos;
|
||||
|
||||
if ( p )
|
||||
result = FT_NEXT_USHORT( p );
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos += 2;
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
*error = FT_THROW( Invalid_Stream_Operation );
|
||||
FT_ERROR(( "FT_Stream_ReadUShort:"
|
||||
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_UInt16 )
|
||||
FT_Stream_ReadUShortLE( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte reads[2];
|
||||
FT_Byte* p;
|
||||
FT_UInt16 result = 0;
|
||||
|
||||
|
||||
FT_ASSERT( stream );
|
||||
|
||||
if ( stream->pos + 1 < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
|
||||
goto Fail;
|
||||
|
||||
p = reads;
|
||||
}
|
||||
else
|
||||
p = stream->base + stream->pos;
|
||||
|
||||
if ( p )
|
||||
result = FT_NEXT_USHORT_LE( p );
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos += 2;
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
*error = FT_THROW( Invalid_Stream_Operation );
|
||||
FT_ERROR(( "FT_Stream_ReadUShortLE:"
|
||||
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_ULong )
|
||||
FT_Stream_ReadUOffset( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte reads[3];
|
||||
FT_Byte* p;
|
||||
FT_ULong result = 0;
|
||||
|
||||
|
||||
FT_ASSERT( stream );
|
||||
|
||||
if ( stream->pos + 2 < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if (stream->read( stream, stream->pos, reads, 3L ) != 3L )
|
||||
goto Fail;
|
||||
|
||||
p = reads;
|
||||
}
|
||||
else
|
||||
p = stream->base + stream->pos;
|
||||
|
||||
if ( p )
|
||||
result = FT_NEXT_UOFF3( p );
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos += 3;
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
*error = FT_THROW( Invalid_Stream_Operation );
|
||||
FT_ERROR(( "FT_Stream_ReadUOffset:"
|
||||
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_UInt32 )
|
||||
FT_Stream_ReadULong( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte reads[4];
|
||||
FT_Byte* p;
|
||||
FT_UInt32 result = 0;
|
||||
|
||||
|
||||
FT_ASSERT( stream );
|
||||
|
||||
if ( stream->pos + 3 < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
|
||||
goto Fail;
|
||||
|
||||
p = reads;
|
||||
}
|
||||
else
|
||||
p = stream->base + stream->pos;
|
||||
|
||||
if ( p )
|
||||
result = FT_NEXT_ULONG( p );
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos += 4;
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
*error = FT_THROW( Invalid_Stream_Operation );
|
||||
FT_ERROR(( "FT_Stream_ReadULong:"
|
||||
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_UInt32 )
|
||||
FT_Stream_ReadULongLE( FT_Stream stream,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_Byte reads[4];
|
||||
FT_Byte* p;
|
||||
FT_UInt32 result = 0;
|
||||
|
||||
|
||||
FT_ASSERT( stream );
|
||||
|
||||
if ( stream->pos + 3 < stream->size )
|
||||
{
|
||||
if ( stream->read )
|
||||
{
|
||||
if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
|
||||
goto Fail;
|
||||
|
||||
p = reads;
|
||||
}
|
||||
else
|
||||
p = stream->base + stream->pos;
|
||||
|
||||
if ( p )
|
||||
result = FT_NEXT_ULONG_LE( p );
|
||||
}
|
||||
else
|
||||
goto Fail;
|
||||
|
||||
stream->pos += 4;
|
||||
|
||||
*error = FT_Err_Ok;
|
||||
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
*error = FT_THROW( Invalid_Stream_Operation );
|
||||
FT_ERROR(( "FT_Stream_ReadULongLE:"
|
||||
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
|
||||
stream->pos, stream->size ));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Stream_ReadFields( FT_Stream stream,
|
||||
const FT_Frame_Field* fields,
|
||||
void* structure )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Bool frame_accessed = 0;
|
||||
FT_Byte* cursor;
|
||||
|
||||
|
||||
if ( !fields )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
if ( !stream )
|
||||
return FT_THROW( Invalid_Stream_Handle );
|
||||
|
||||
cursor = stream->cursor;
|
||||
|
||||
error = FT_Err_Ok;
|
||||
do
|
||||
{
|
||||
FT_ULong value;
|
||||
FT_Int sign_shift;
|
||||
FT_Byte* p;
|
||||
|
||||
|
||||
switch ( fields->value )
|
||||
{
|
||||
case ft_frame_start: /* access a new frame */
|
||||
error = FT_Stream_EnterFrame( stream, fields->offset );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
frame_accessed = 1;
|
||||
cursor = stream->cursor;
|
||||
fields++;
|
||||
continue; /* loop! */
|
||||
|
||||
case ft_frame_bytes: /* read a byte sequence */
|
||||
case ft_frame_skip: /* skip some bytes */
|
||||
{
|
||||
FT_Offset len = fields->size;
|
||||
|
||||
|
||||
if ( len > (FT_Offset)( stream->limit - cursor ) )
|
||||
{
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( fields->value == ft_frame_bytes )
|
||||
{
|
||||
p = (FT_Byte*)structure + fields->offset;
|
||||
FT_MEM_COPY( p, cursor, len );
|
||||
}
|
||||
cursor += len;
|
||||
fields++;
|
||||
continue;
|
||||
}
|
||||
|
||||
case ft_frame_byte:
|
||||
case ft_frame_schar: /* read a single byte */
|
||||
value = FT_NEXT_BYTE( cursor );
|
||||
sign_shift = 24;
|
||||
break;
|
||||
|
||||
case ft_frame_short_be:
|
||||
case ft_frame_ushort_be: /* read a 2-byte big-endian short */
|
||||
value = FT_NEXT_USHORT( cursor );
|
||||
sign_shift = 16;
|
||||
break;
|
||||
|
||||
case ft_frame_short_le:
|
||||
case ft_frame_ushort_le: /* read a 2-byte little-endian short */
|
||||
value = FT_NEXT_USHORT_LE( cursor );
|
||||
sign_shift = 16;
|
||||
break;
|
||||
|
||||
case ft_frame_long_be:
|
||||
case ft_frame_ulong_be: /* read a 4-byte big-endian long */
|
||||
value = FT_NEXT_ULONG( cursor );
|
||||
sign_shift = 0;
|
||||
break;
|
||||
|
||||
case ft_frame_long_le:
|
||||
case ft_frame_ulong_le: /* read a 4-byte little-endian long */
|
||||
value = FT_NEXT_ULONG_LE( cursor );
|
||||
sign_shift = 0;
|
||||
break;
|
||||
|
||||
case ft_frame_off3_be:
|
||||
case ft_frame_uoff3_be: /* read a 3-byte big-endian long */
|
||||
value = FT_NEXT_UOFF3( cursor );
|
||||
sign_shift = 8;
|
||||
break;
|
||||
|
||||
case ft_frame_off3_le:
|
||||
case ft_frame_uoff3_le: /* read a 3-byte little-endian long */
|
||||
value = FT_NEXT_UOFF3_LE( cursor );
|
||||
sign_shift = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* otherwise, exit the loop */
|
||||
stream->cursor = cursor;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* now, compute the signed value if necessary */
|
||||
if ( fields->value & FT_FRAME_OP_SIGNED )
|
||||
value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );
|
||||
|
||||
/* finally, store the value in the object */
|
||||
|
||||
p = (FT_Byte*)structure + fields->offset;
|
||||
switch ( fields->size )
|
||||
{
|
||||
case ( 8 / FT_CHAR_BIT ):
|
||||
*(FT_Byte*)p = (FT_Byte)value;
|
||||
break;
|
||||
|
||||
case ( 16 / FT_CHAR_BIT ):
|
||||
*(FT_UShort*)p = (FT_UShort)value;
|
||||
break;
|
||||
|
||||
case ( 32 / FT_CHAR_BIT ):
|
||||
*(FT_UInt32*)p = (FT_UInt32)value;
|
||||
break;
|
||||
|
||||
default: /* for 64-bit systems */
|
||||
*(FT_ULong*)p = (FT_ULong)value;
|
||||
}
|
||||
|
||||
/* go to next field */
|
||||
fields++;
|
||||
}
|
||||
while ( 1 );
|
||||
|
||||
Exit:
|
||||
/* close the frame if it was opened by this read */
|
||||
if ( frame_accessed )
|
||||
FT_Stream_ExitFrame( stream );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
2403
thirdparty/freetype/src/base/ftstroke.c
vendored
Normal file
2403
thirdparty/freetype/src/base/ftstroke.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
180
thirdparty/freetype/src/base/ftsynth.c
vendored
Normal file
180
thirdparty/freetype/src/base/ftsynth.c
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftsynth.c
|
||||
*
|
||||
* FreeType synthesizing code for emboldening and slanting (body).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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 <freetype/ftsynth.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/ftoutln.h>
|
||||
#include <freetype/ftbitmap.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 synth
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** EXPERIMENTAL OBLIQUING SUPPORT ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* documentation is in ftsynth.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_GlyphSlot_Oblique( FT_GlyphSlot slot )
|
||||
{
|
||||
/* Value '0x0366A' corresponds to a shear angle of about 12 degrees. */
|
||||
FT_GlyphSlot_Slant( slot, 0x0366A, 0 );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftsynth.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_GlyphSlot_Slant( FT_GlyphSlot slot,
|
||||
FT_Fixed xslant,
|
||||
FT_Fixed yslant )
|
||||
{
|
||||
FT_Matrix transform;
|
||||
FT_Outline* outline;
|
||||
|
||||
|
||||
if ( !slot )
|
||||
return;
|
||||
|
||||
outline = &slot->outline;
|
||||
|
||||
/* only oblique outline glyphs */
|
||||
if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
|
||||
return;
|
||||
|
||||
/* we don't touch the advance width */
|
||||
|
||||
/* For italic, simply apply a shear transform */
|
||||
transform.xx = 0x10000L;
|
||||
transform.yx = -yslant;
|
||||
|
||||
transform.xy = xslant;
|
||||
transform.yy = 0x10000L;
|
||||
|
||||
FT_Outline_Transform( outline, &transform );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** EXPERIMENTAL EMBOLDENING SUPPORT ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* documentation is in ftsynth.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_GlyphSlot_Embolden( FT_GlyphSlot slot )
|
||||
{
|
||||
FT_GlyphSlot_AdjustWeight( slot, 0x0AAA, 0x0AAA );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_GlyphSlot_AdjustWeight( FT_GlyphSlot slot,
|
||||
FT_Fixed xdelta,
|
||||
FT_Fixed ydelta )
|
||||
{
|
||||
FT_Library library;
|
||||
FT_Size size;
|
||||
FT_Error error;
|
||||
FT_Pos xstr, ystr;
|
||||
|
||||
|
||||
if ( !slot )
|
||||
return;
|
||||
|
||||
library = slot->library;
|
||||
size = slot->face->size;
|
||||
|
||||
if ( slot->format != FT_GLYPH_FORMAT_OUTLINE &&
|
||||
slot->format != FT_GLYPH_FORMAT_BITMAP )
|
||||
return;
|
||||
|
||||
/* express deltas in pixels in 26.6 format */
|
||||
xstr = (FT_Pos)size->metrics.x_ppem * xdelta / 1024;
|
||||
ystr = (FT_Pos)size->metrics.y_ppem * ydelta / 1024;
|
||||
|
||||
if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
|
||||
FT_Outline_EmboldenXY( &slot->outline, xstr, ystr );
|
||||
|
||||
else /* slot->format == FT_GLYPH_FORMAT_BITMAP */
|
||||
{
|
||||
/* round to full pixels */
|
||||
xstr &= ~63;
|
||||
if ( xstr == 0 )
|
||||
xstr = 1 << 6;
|
||||
ystr &= ~63;
|
||||
|
||||
/*
|
||||
* XXX: overflow check for 16-bit system, for compatibility
|
||||
* with FT_GlyphSlot_Embolden() since FreeType 2.1.10.
|
||||
* unfortunately, this function return no informations
|
||||
* about the cause of error.
|
||||
*/
|
||||
if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN )
|
||||
{
|
||||
FT_TRACE1(( "FT_GlyphSlot_Embolden:" ));
|
||||
FT_TRACE1(( "too strong emboldening parameter ystr=%ld\n", ystr ));
|
||||
return;
|
||||
}
|
||||
error = FT_GlyphSlot_Own_Bitmap( slot );
|
||||
if ( error )
|
||||
return;
|
||||
|
||||
error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );
|
||||
if ( error )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( slot->advance.x )
|
||||
slot->advance.x += xstr;
|
||||
|
||||
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.horiBearingY += ystr;
|
||||
|
||||
/* XXX: 16-bit overflow case must be excluded before here */
|
||||
if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
|
||||
slot->bitmap_top += (FT_Int)( ystr >> 6 );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
338
thirdparty/freetype/src/base/ftsystem.c
vendored
Normal file
338
thirdparty/freetype/src/base/ftsystem.c
vendored
Normal file
@@ -0,0 +1,338 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftsystem.c
|
||||
*
|
||||
* ANSI-specific FreeType low-level system interface (body).
|
||||
*
|
||||
* Copyright (C) 1996-2024 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 the default interface used by FreeType to access
|
||||
* low-level, i.e. memory management, i/o access as well as thread
|
||||
* synchronisation. It can be replaced by user-specific routines if
|
||||
* necessary.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftstream.h>
|
||||
#include <freetype/ftsystem.h>
|
||||
#include <freetype/fterrors.h>
|
||||
#include <freetype/fttypes.h>
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* MEMORY MANAGEMENT INTERFACE
|
||||
*
|
||||
*/
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* It is not necessary to do any error checking for the
|
||||
* allocation-related functions. This will be done by the higher level
|
||||
* routines like ft_mem_alloc() or ft_mem_realloc().
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* ft_alloc
|
||||
*
|
||||
* @Description:
|
||||
* The memory allocation function.
|
||||
*
|
||||
* @Input:
|
||||
* memory ::
|
||||
* A pointer to the memory object.
|
||||
*
|
||||
* 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 ft_smalloc( (size_t)size );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* ft_realloc
|
||||
*
|
||||
* @Description:
|
||||
* The memory reallocation function.
|
||||
*
|
||||
* @Input:
|
||||
* memory ::
|
||||
* A pointer to the memory object.
|
||||
*
|
||||
* cur_size ::
|
||||
* The current size of the allocated memory block.
|
||||
*
|
||||
* new_size ::
|
||||
* The newly requested size in bytes.
|
||||
*
|
||||
* 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 ft_srealloc( block, (size_t)new_size );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* ft_free
|
||||
*
|
||||
* @Description:
|
||||
* The memory release function.
|
||||
*
|
||||
* @Input:
|
||||
* memory ::
|
||||
* A pointer to the memory object.
|
||||
*
|
||||
* block ::
|
||||
* The address of block in memory to be freed.
|
||||
*/
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_free( FT_Memory memory,
|
||||
void* block )
|
||||
{
|
||||
FT_UNUSED( memory );
|
||||
|
||||
ft_sfree( block );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* RESOURCE MANAGEMENT INTERFACE
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* 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 ) ( (FT_FILE*)stream->descriptor.pointer )
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* ft_ansi_stream_close
|
||||
*
|
||||
* @Description:
|
||||
* The function to close a stream.
|
||||
*
|
||||
* @Input:
|
||||
* stream ::
|
||||
* A pointer to the stream object.
|
||||
*/
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_ansi_stream_close( FT_Stream stream )
|
||||
{
|
||||
ft_fclose( STREAM_FILE( stream ) );
|
||||
|
||||
stream->descriptor.pointer = NULL;
|
||||
stream->size = 0;
|
||||
stream->base = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* ft_ansi_stream_io
|
||||
*
|
||||
* @Description:
|
||||
* The function to open a stream.
|
||||
*
|
||||
* @Input:
|
||||
* stream ::
|
||||
* A pointer to the stream object.
|
||||
*
|
||||
* offset ::
|
||||
* The position in the data stream to start reading.
|
||||
*
|
||||
* buffer ::
|
||||
* The address of buffer to store the read data.
|
||||
*
|
||||
* count ::
|
||||
* The number of bytes to read from the stream.
|
||||
*
|
||||
* @Return:
|
||||
* The number of bytes actually read. If `count' is zero (that is,
|
||||
* the function is used for seeking), a non-zero return value
|
||||
* indicates an error.
|
||||
*/
|
||||
FT_CALLBACK_DEF( unsigned long )
|
||||
ft_ansi_stream_io( FT_Stream stream,
|
||||
unsigned long offset,
|
||||
unsigned char* buffer,
|
||||
unsigned long count )
|
||||
{
|
||||
FT_FILE* file;
|
||||
|
||||
|
||||
if ( offset > stream->size && !count )
|
||||
return 1;
|
||||
|
||||
file = STREAM_FILE( stream );
|
||||
|
||||
if ( stream->pos != offset )
|
||||
ft_fseek( file, (long)offset, SEEK_SET );
|
||||
|
||||
/* Avoid calling `fread` with `buffer=NULL` and `count=0`, */
|
||||
/* which is undefined behaviour. */
|
||||
if ( !count )
|
||||
return 0;
|
||||
|
||||
return (unsigned long)ft_fread( buffer, 1, count, file );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftstream.h */
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Stream_Open( FT_Stream stream,
|
||||
const char* filepathname )
|
||||
{
|
||||
FT_FILE* 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;
|
||||
|
||||
file = ft_fopen( filepathname, "rb" );
|
||||
if ( !file )
|
||||
{
|
||||
FT_ERROR(( "FT_Stream_Open:"
|
||||
" could not open `%s'\n", filepathname ));
|
||||
|
||||
return FT_THROW( Cannot_Open_Resource );
|
||||
}
|
||||
|
||||
ft_fseek( file, 0, SEEK_END );
|
||||
stream->size = (unsigned long)ft_ftell( file );
|
||||
if ( !stream->size )
|
||||
{
|
||||
FT_ERROR(( "FT_Stream_Open:" ));
|
||||
FT_ERROR(( " opened `%s' but zero-sized\n", filepathname ));
|
||||
ft_fclose( file );
|
||||
return FT_THROW( Cannot_Open_Stream );
|
||||
}
|
||||
ft_fseek( file, 0, SEEK_SET );
|
||||
|
||||
stream->descriptor.pointer = file;
|
||||
stream->read = ft_ansi_stream_io;
|
||||
stream->close = ft_ansi_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 */
|
||||
|
||||
#ifdef FT_DEBUG_MEMORY
|
||||
|
||||
extern FT_Int
|
||||
ft_mem_debug_init( FT_Memory memory );
|
||||
|
||||
extern void
|
||||
ft_mem_debug_done( FT_Memory memory );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* documentation is in ftobjs.h */
|
||||
|
||||
FT_BASE_DEF( FT_Memory )
|
||||
FT_New_Memory( void )
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
memory = (FT_Memory)ft_smalloc( 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
|
||||
ft_sfree( memory );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
517
thirdparty/freetype/src/base/fttrigon.c
vendored
Normal file
517
thirdparty/freetype/src/base/fttrigon.c
vendored
Normal file
@@ -0,0 +1,517 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* fttrigon.c
|
||||
*
|
||||
* FreeType trigonometric functions (body).
|
||||
*
|
||||
* Copyright (C) 2001-2024 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 is a fixed-point CORDIC implementation of trigonometric
|
||||
* functions as well as transformations between Cartesian and polar
|
||||
* coordinates. The angles are represented as 16.16 fixed-point values
|
||||
* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that
|
||||
* only vectors longer than 2^16*180/pi (or at least 22 bits) on a
|
||||
* discrete Cartesian grid can have the same or better angular
|
||||
* resolution. Therefore, to maintain this precision, some functions
|
||||
* require an interim upscaling of the vectors, whereas others operate
|
||||
* with 24-bit long vectors directly.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftcalc.h>
|
||||
#include <freetype/fttrigon.h>
|
||||
|
||||
|
||||
/* the Cordic shrink factor 0.858785336480436 * 2^32 */
|
||||
#define FT_TRIG_SCALE 0xDBD95B16UL
|
||||
|
||||
/* the highest bit in overflow-safe vector components, */
|
||||
/* MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */
|
||||
#define FT_TRIG_SAFE_MSB 29
|
||||
|
||||
/* this table was generated for FT_PI = 180L << 16, i.e. degrees */
|
||||
#define FT_TRIG_MAX_ITERS 23
|
||||
|
||||
static const FT_Angle
|
||||
ft_trig_arctan_table[] =
|
||||
{
|
||||
1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L,
|
||||
14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
|
||||
57L, 29L, 14L, 7L, 4L, 2L, 1L
|
||||
};
|
||||
|
||||
|
||||
#ifdef FT_INT64
|
||||
|
||||
/* multiply a given value by the CORDIC shrink factor */
|
||||
static FT_Fixed
|
||||
ft_trig_downscale( FT_Fixed val )
|
||||
{
|
||||
FT_Int s = 1;
|
||||
|
||||
|
||||
if ( val < 0 )
|
||||
{
|
||||
val = -val;
|
||||
s = -1;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
#else /* !FT_INT64 */
|
||||
|
||||
/* multiply a given value by the CORDIC shrink factor */
|
||||
static FT_Fixed
|
||||
ft_trig_downscale( FT_Fixed val )
|
||||
{
|
||||
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;
|
||||
|
||||
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 );
|
||||
|
||||
/* 0x40000000 comes from regression analysis between true */
|
||||
/* and CORDIC hypotenuse, so it minimizes the error */
|
||||
|
||||
/* Check carry overflow of lo + 0x40000000 */
|
||||
lo += 0x40000000UL;
|
||||
hi += ( lo < 0x40000000UL );
|
||||
|
||||
val = (FT_Fixed)hi;
|
||||
|
||||
return s < 0 ? -val : val;
|
||||
}
|
||||
|
||||
#endif /* !FT_INT64 */
|
||||
|
||||
|
||||
/* undefined and never called for zero vector */
|
||||
static FT_Int
|
||||
ft_trig_prenorm( FT_Vector* vec )
|
||||
{
|
||||
FT_Pos x, y;
|
||||
FT_Int shift;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
shift = FT_MSB( (FT_UInt32)( FT_ABS( x ) | FT_ABS( y ) ) );
|
||||
|
||||
if ( shift <= FT_TRIG_SAFE_MSB )
|
||||
{
|
||||
shift = FT_TRIG_SAFE_MSB - shift;
|
||||
vec->x = (FT_Pos)( (FT_ULong)x << shift );
|
||||
vec->y = (FT_Pos)( (FT_ULong)y << shift );
|
||||
}
|
||||
else
|
||||
{
|
||||
shift -= FT_TRIG_SAFE_MSB;
|
||||
vec->x = x >> shift;
|
||||
vec->y = y >> shift;
|
||||
shift = -shift;
|
||||
}
|
||||
|
||||
return shift;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_trig_pseudo_rotate( FT_Vector* vec,
|
||||
FT_Angle theta )
|
||||
{
|
||||
FT_Int i;
|
||||
FT_Fixed x, y, xtemp, b;
|
||||
const FT_Angle *arctanptr;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
/* Rotate inside [-PI/4,PI/4] sector */
|
||||
while ( theta < -FT_ANGLE_PI4 )
|
||||
{
|
||||
xtemp = y;
|
||||
y = -x;
|
||||
x = xtemp;
|
||||
theta += FT_ANGLE_PI2;
|
||||
}
|
||||
|
||||
while ( theta > FT_ANGLE_PI4 )
|
||||
{
|
||||
xtemp = -y;
|
||||
y = x;
|
||||
x = xtemp;
|
||||
theta -= FT_ANGLE_PI2;
|
||||
}
|
||||
|
||||
arctanptr = ft_trig_arctan_table;
|
||||
|
||||
/* Pseudorotations, with right shifts */
|
||||
for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ )
|
||||
{
|
||||
if ( theta < 0 )
|
||||
{
|
||||
xtemp = x + ( ( y + b ) >> i );
|
||||
y = y - ( ( x + b ) >> i );
|
||||
x = xtemp;
|
||||
theta += *arctanptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
xtemp = x - ( ( y + b ) >> i );
|
||||
y = y + ( ( x + b ) >> i );
|
||||
x = xtemp;
|
||||
theta -= *arctanptr++;
|
||||
}
|
||||
}
|
||||
|
||||
vec->x = x;
|
||||
vec->y = y;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_trig_pseudo_polarize( FT_Vector* vec )
|
||||
{
|
||||
FT_Angle theta;
|
||||
FT_Int i;
|
||||
FT_Fixed x, y, xtemp, b;
|
||||
const FT_Angle *arctanptr;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
/* Get the vector into [-PI/4,PI/4] sector */
|
||||
if ( y > x )
|
||||
{
|
||||
if ( y > -x )
|
||||
{
|
||||
theta = FT_ANGLE_PI2;
|
||||
xtemp = y;
|
||||
y = -x;
|
||||
x = xtemp;
|
||||
}
|
||||
else
|
||||
{
|
||||
theta = y > 0 ? FT_ANGLE_PI : -FT_ANGLE_PI;
|
||||
x = -x;
|
||||
y = -y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( y < -x )
|
||||
{
|
||||
theta = -FT_ANGLE_PI2;
|
||||
xtemp = -y;
|
||||
y = x;
|
||||
x = xtemp;
|
||||
}
|
||||
else
|
||||
{
|
||||
theta = 0;
|
||||
}
|
||||
}
|
||||
|
||||
arctanptr = ft_trig_arctan_table;
|
||||
|
||||
/* Pseudorotations, with right shifts */
|
||||
for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ )
|
||||
{
|
||||
if ( y > 0 )
|
||||
{
|
||||
xtemp = x + ( ( y + b ) >> i );
|
||||
y = y - ( ( x + b ) >> i );
|
||||
x = xtemp;
|
||||
theta += *arctanptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
xtemp = x - ( ( y + b ) >> i );
|
||||
y = y + ( ( x + b ) >> i );
|
||||
x = xtemp;
|
||||
theta -= *arctanptr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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, 16 );
|
||||
else
|
||||
theta = -FT_PAD_ROUND( -theta, 16 );
|
||||
|
||||
vec->x = x;
|
||||
vec->y = theta;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_Cos( FT_Angle angle )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
FT_Vector_Unit( &v, angle );
|
||||
|
||||
return v.x;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_Sin( FT_Angle angle )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
FT_Vector_Unit( &v, angle );
|
||||
|
||||
return v.y;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_Tan( FT_Angle angle )
|
||||
{
|
||||
FT_Vector v = { 1 << 24, 0 };
|
||||
|
||||
|
||||
ft_trig_pseudo_rotate( &v, angle );
|
||||
|
||||
return FT_DivFix( v.y, v.x );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Angle )
|
||||
FT_Atan2( FT_Fixed dx,
|
||||
FT_Fixed dy )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
if ( dx == 0 && dy == 0 )
|
||||
return 0;
|
||||
|
||||
v.x = dx;
|
||||
v.y = dy;
|
||||
ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_polarize( &v );
|
||||
|
||||
return v.y;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
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 );
|
||||
vec->x = ( vec->x + 0x80L ) >> 8;
|
||||
vec->y = ( vec->y + 0x80L ) >> 8;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Vector_Rotate( FT_Vector* vec,
|
||||
FT_Angle angle )
|
||||
{
|
||||
FT_Int shift;
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
if ( !vec || !angle )
|
||||
return;
|
||||
|
||||
v = *vec;
|
||||
|
||||
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 );
|
||||
|
||||
if ( shift > 0 )
|
||||
{
|
||||
FT_Int32 half = (FT_Int32)1L << ( shift - 1 );
|
||||
|
||||
|
||||
vec->x = ( v.x + half - ( v.x < 0 ) ) >> shift;
|
||||
vec->y = ( v.y + half - ( v.y < 0 ) ) >> shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = -shift;
|
||||
vec->x = (FT_Pos)( (FT_ULong)v.x << shift );
|
||||
vec->y = (FT_Pos)( (FT_ULong)v.y << shift );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Fixed )
|
||||
FT_Vector_Length( FT_Vector* vec )
|
||||
{
|
||||
FT_Int shift;
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
if ( !vec )
|
||||
return 0;
|
||||
|
||||
v = *vec;
|
||||
|
||||
/* handle trivial cases */
|
||||
if ( v.x == 0 )
|
||||
{
|
||||
return FT_ABS( v.y );
|
||||
}
|
||||
else if ( v.y == 0 )
|
||||
{
|
||||
return FT_ABS( v.x );
|
||||
}
|
||||
|
||||
/* general case */
|
||||
shift = ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_polarize( &v );
|
||||
|
||||
v.x = ft_trig_downscale( v.x );
|
||||
|
||||
if ( shift > 0 )
|
||||
return ( v.x + ( 1L << ( shift - 1 ) ) ) >> shift;
|
||||
|
||||
return (FT_Fixed)( (FT_UInt32)v.x << -shift );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Vector_Polarize( FT_Vector* vec,
|
||||
FT_Fixed *length,
|
||||
FT_Angle *angle )
|
||||
{
|
||||
FT_Int shift;
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
if ( !vec || !length || !angle )
|
||||
return;
|
||||
|
||||
v = *vec;
|
||||
|
||||
if ( v.x == 0 && v.y == 0 )
|
||||
return;
|
||||
|
||||
shift = ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_polarize( &v );
|
||||
|
||||
v.x = ft_trig_downscale( v.x );
|
||||
|
||||
*length = shift >= 0 ? ( v.x >> shift )
|
||||
: (FT_Fixed)( (FT_UInt32)v.x << -shift );
|
||||
*angle = v.y;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_Vector_From_Polar( FT_Vector* vec,
|
||||
FT_Fixed length,
|
||||
FT_Angle angle )
|
||||
{
|
||||
if ( !vec )
|
||||
return;
|
||||
|
||||
vec->x = length;
|
||||
vec->y = 0;
|
||||
|
||||
FT_Vector_Rotate( vec, angle );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in fttrigon.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Angle )
|
||||
FT_Angle_Diff( FT_Angle angle1,
|
||||
FT_Angle angle2 )
|
||||
{
|
||||
FT_Angle delta = angle2 - angle1;
|
||||
|
||||
|
||||
while ( delta <= -FT_ANGLE_PI )
|
||||
delta += FT_ANGLE_2PI;
|
||||
|
||||
while ( delta > FT_ANGLE_PI )
|
||||
delta -= FT_ANGLE_2PI;
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
126
thirdparty/freetype/src/base/fttype1.c
vendored
Normal file
126
thirdparty/freetype/src/base/fttype1.c
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* fttype1.c
|
||||
*
|
||||
* FreeType utility file for PS names support (body).
|
||||
*
|
||||
* Copyright (C) 2002-2024 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 <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftserv.h>
|
||||
#include <freetype/internal/services/svpsinfo.h>
|
||||
|
||||
|
||||
/* documentation is in t1tables.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_PS_Font_Info( FT_Face face,
|
||||
PS_FontInfoRec* afont_info )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Service_PsInfo service;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
if ( !afont_info )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_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;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in t1tables.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Int )
|
||||
FT_Has_PS_Glyph_Names( FT_Face face )
|
||||
{
|
||||
FT_Int result = 0;
|
||||
FT_Service_PsInfo service;
|
||||
|
||||
|
||||
if ( face )
|
||||
{
|
||||
FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
|
||||
|
||||
if ( service && service->ps_has_glyph_names )
|
||||
result = service->ps_has_glyph_names( face );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in t1tables.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_PS_Font_Private( FT_Face face,
|
||||
PS_PrivateRec* afont_private )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Service_PsInfo service;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
if ( !afont_private )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
|
||||
|
||||
if ( service && service->ps_get_font_private )
|
||||
error = service->ps_get_font_private( face, afont_private );
|
||||
else
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in t1tables.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Long )
|
||||
FT_Get_PS_Font_Value( FT_Face face,
|
||||
PS_Dict_Keys key,
|
||||
FT_UInt idx,
|
||||
void *value,
|
||||
FT_Long value_len )
|
||||
{
|
||||
FT_Int result = 0;
|
||||
FT_Service_PsInfo service = NULL;
|
||||
|
||||
|
||||
if ( face )
|
||||
{
|
||||
FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
|
||||
|
||||
if ( service && service->ps_get_font_value )
|
||||
result = service->ps_get_font_value( face, key, idx,
|
||||
value, value_len );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
442
thirdparty/freetype/src/base/ftutil.c
vendored
Normal file
442
thirdparty/freetype/src/base/ftutil.c
vendored
Normal file
@@ -0,0 +1,442 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftutil.c
|
||||
*
|
||||
* FreeType utility file for memory and list management (body).
|
||||
*
|
||||
* Copyright (C) 2002-2024 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 <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftmemory.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/ftlist.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 memory
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** *****/
|
||||
/***** M E M O R Y M A N A G E M E N T *****/
|
||||
/***** *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Pointer )
|
||||
ft_mem_alloc( FT_Memory memory,
|
||||
FT_Long size,
|
||||
FT_Error *p_error )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Pointer block = ft_mem_qalloc( memory, size, &error );
|
||||
|
||||
if ( !error && block && size > 0 )
|
||||
FT_MEM_ZERO( block, size );
|
||||
|
||||
*p_error = error;
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Pointer )
|
||||
ft_mem_qalloc( FT_Memory memory,
|
||||
FT_Long size,
|
||||
FT_Error *p_error )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Pointer block = NULL;
|
||||
|
||||
|
||||
if ( size > 0 )
|
||||
{
|
||||
block = memory->alloc( memory, size );
|
||||
if ( !block )
|
||||
error = FT_THROW( Out_Of_Memory );
|
||||
}
|
||||
else if ( size < 0 )
|
||||
{
|
||||
/* may help catch/prevent security issues */
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
}
|
||||
|
||||
*p_error = error;
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Pointer )
|
||||
ft_mem_realloc( FT_Memory memory,
|
||||
FT_Long item_size,
|
||||
FT_Long cur_count,
|
||||
FT_Long new_count,
|
||||
void* block,
|
||||
FT_Error *p_error )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
block = ft_mem_qrealloc( memory, item_size,
|
||||
cur_count, new_count, block, &error );
|
||||
if ( !error && block && new_count > cur_count )
|
||||
FT_MEM_ZERO( (char*)block + cur_count * item_size,
|
||||
( new_count - cur_count ) * item_size );
|
||||
|
||||
*p_error = error;
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Pointer )
|
||||
ft_mem_qrealloc( FT_Memory memory,
|
||||
FT_Long item_size,
|
||||
FT_Long cur_count,
|
||||
FT_Long new_count,
|
||||
void* block,
|
||||
FT_Error *p_error )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
/* Note that we now accept `item_size == 0' as a valid parameter, in
|
||||
* order to cover very weird cases where an ALLOC_MULT macro would be
|
||||
* called.
|
||||
*/
|
||||
if ( cur_count < 0 || new_count < 0 || item_size < 0 )
|
||||
{
|
||||
/* may help catch/prevent nasty security issues */
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
}
|
||||
else if ( new_count == 0 || item_size == 0 )
|
||||
{
|
||||
ft_mem_free( memory, block );
|
||||
block = NULL;
|
||||
}
|
||||
else if ( new_count > FT_INT_MAX / item_size )
|
||||
{
|
||||
error = FT_THROW( Array_Too_Large );
|
||||
}
|
||||
else if ( cur_count == 0 )
|
||||
{
|
||||
FT_ASSERT( !block );
|
||||
|
||||
block = memory->alloc( memory, new_count * item_size );
|
||||
if ( block == NULL )
|
||||
error = FT_THROW( Out_Of_Memory );
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Pointer block2;
|
||||
FT_Long cur_size = cur_count * item_size;
|
||||
FT_Long new_size = new_count * item_size;
|
||||
|
||||
|
||||
block2 = memory->realloc( memory, cur_size, new_size, block );
|
||||
if ( !block2 )
|
||||
error = FT_THROW( Out_Of_Memory );
|
||||
else
|
||||
block = block2;
|
||||
}
|
||||
|
||||
*p_error = error;
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
ft_mem_free( FT_Memory memory,
|
||||
const void *P )
|
||||
{
|
||||
if ( P )
|
||||
memory->free( memory, (void*)P );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Pointer )
|
||||
ft_mem_dup( FT_Memory memory,
|
||||
const void* address,
|
||||
FT_ULong size,
|
||||
FT_Error *p_error )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Pointer p = ft_mem_qalloc( memory, (FT_Long)size, &error );
|
||||
|
||||
|
||||
if ( !error && address && size > 0 )
|
||||
ft_memcpy( p, address, size );
|
||||
|
||||
*p_error = error;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Pointer )
|
||||
ft_mem_strdup( FT_Memory memory,
|
||||
const char* str,
|
||||
FT_Error *p_error )
|
||||
{
|
||||
FT_ULong len = str ? (FT_ULong)ft_strlen( str ) + 1
|
||||
: 0;
|
||||
|
||||
|
||||
return ft_mem_dup( memory, str, len, p_error );
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Int )
|
||||
ft_mem_strcpyn( char* dst,
|
||||
const char* src,
|
||||
FT_ULong size )
|
||||
{
|
||||
while ( size > 1 && *src != 0 )
|
||||
{
|
||||
*dst++ = *src++;
|
||||
size--;
|
||||
}
|
||||
|
||||
*dst = 0; /* always zero-terminate */
|
||||
|
||||
return *src != 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** *****/
|
||||
/***** D O U B L Y L I N K E D L I S T S *****/
|
||||
/***** *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT list
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_ListNode )
|
||||
FT_List_Find( FT_List list,
|
||||
void* data )
|
||||
{
|
||||
FT_ListNode cur;
|
||||
|
||||
|
||||
if ( !list )
|
||||
return NULL;
|
||||
|
||||
cur = list->head;
|
||||
while ( cur )
|
||||
{
|
||||
if ( cur->data == data )
|
||||
return cur;
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_List_Add( FT_List list,
|
||||
FT_ListNode node )
|
||||
{
|
||||
FT_ListNode before;
|
||||
|
||||
|
||||
if ( !list || !node )
|
||||
return;
|
||||
|
||||
before = list->tail;
|
||||
|
||||
node->next = NULL;
|
||||
node->prev = before;
|
||||
|
||||
if ( before )
|
||||
before->next = node;
|
||||
else
|
||||
list->head = node;
|
||||
|
||||
list->tail = node;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_List_Insert( FT_List list,
|
||||
FT_ListNode node )
|
||||
{
|
||||
FT_ListNode after;
|
||||
|
||||
|
||||
if ( !list || !node )
|
||||
return;
|
||||
|
||||
after = list->head;
|
||||
|
||||
node->next = after;
|
||||
node->prev = NULL;
|
||||
|
||||
if ( !after )
|
||||
list->tail = node;
|
||||
else
|
||||
after->prev = node;
|
||||
|
||||
list->head = node;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_List_Remove( FT_List list,
|
||||
FT_ListNode node )
|
||||
{
|
||||
FT_ListNode before, after;
|
||||
|
||||
|
||||
if ( !list || !node )
|
||||
return;
|
||||
|
||||
before = node->prev;
|
||||
after = node->next;
|
||||
|
||||
if ( before )
|
||||
before->next = after;
|
||||
else
|
||||
list->head = after;
|
||||
|
||||
if ( after )
|
||||
after->prev = before;
|
||||
else
|
||||
list->tail = before;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_List_Up( FT_List list,
|
||||
FT_ListNode node )
|
||||
{
|
||||
FT_ListNode before, after;
|
||||
|
||||
|
||||
if ( !list || !node )
|
||||
return;
|
||||
|
||||
before = node->prev;
|
||||
after = node->next;
|
||||
|
||||
/* check whether we are already on top of the list */
|
||||
if ( !before )
|
||||
return;
|
||||
|
||||
before->next = after;
|
||||
|
||||
if ( after )
|
||||
after->prev = before;
|
||||
else
|
||||
list->tail = before;
|
||||
|
||||
node->prev = NULL;
|
||||
node->next = list->head;
|
||||
list->head->prev = node;
|
||||
list->head = node;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_List_Iterate( FT_List list,
|
||||
FT_List_Iterator iterator,
|
||||
void* user )
|
||||
{
|
||||
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;
|
||||
|
||||
|
||||
error = iterator( cur, user );
|
||||
if ( error )
|
||||
break;
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftlist.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FT_List_Finalize( FT_List list,
|
||||
FT_List_Destructor destroy,
|
||||
FT_Memory memory,
|
||||
void* user )
|
||||
{
|
||||
FT_ListNode cur;
|
||||
|
||||
|
||||
if ( !list || !memory )
|
||||
return;
|
||||
|
||||
cur = list->head;
|
||||
while ( cur )
|
||||
{
|
||||
FT_ListNode next = cur->next;
|
||||
void* data = cur->data;
|
||||
|
||||
|
||||
if ( destroy )
|
||||
destroy( memory, data, user );
|
||||
|
||||
FT_FREE( cur );
|
||||
cur = next;
|
||||
}
|
||||
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
52
thirdparty/freetype/src/base/ftwinfnt.c
vendored
Normal file
52
thirdparty/freetype/src/base/ftwinfnt.c
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftwinfnt.c
|
||||
*
|
||||
* FreeType API for accessing Windows FNT specific info (body).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 <freetype/internal/ftdebug.h>
|
||||
#include <freetype/ftwinfnt.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/services/svwinfnt.h>
|
||||
|
||||
|
||||
/* documentation is in ftwinfnt.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_WinFNT_Header( FT_Face face,
|
||||
FT_WinFNT_HeaderRec *header )
|
||||
{
|
||||
FT_Service_WinFnt service;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return FT_THROW( Invalid_Face_Handle );
|
||||
|
||||
if ( !header )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
FT_FACE_LOOKUP_SERVICE( face, service, WINFNT );
|
||||
|
||||
if ( service )
|
||||
error = service->get_header( face, header );
|
||||
else
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
291
thirdparty/freetype/src/base/md5.c
vendored
Normal file
291
thirdparty/freetype/src/base/md5.c
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||
* MD5 Message-Digest Algorithm (RFC 1321).
|
||||
*
|
||||
* Homepage:
|
||||
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
|
||||
*
|
||||
* Author:
|
||||
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||
*
|
||||
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||
* claimed, and the software is hereby placed in the public domain.
|
||||
* In case this attempt to disclaim copyright and place the software in the
|
||||
* public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* (This is a heavily cut-down "BSD license".)
|
||||
*
|
||||
* This differs from Colin Plumb's older public domain implementation in that
|
||||
* no exactly 32-bit integer data type is required (any 32-bit or wider
|
||||
* unsigned integer data type will do), there's no compile-time endianness
|
||||
* configuration, and the function prototypes match OpenSSL's. No code from
|
||||
* Colin Plumb's implementation has been reused; this comment merely compares
|
||||
* the properties of the two independent implementations.
|
||||
*
|
||||
* The primary goals of this implementation are portability and ease of use.
|
||||
* It is meant to be fast, but not as fast as possible. Some known
|
||||
* optimizations are not included to reduce source code size and avoid
|
||||
* compile-time configuration.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_OPENSSL
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
/*
|
||||
* The basic MD5 functions.
|
||||
*
|
||||
* F and G are optimized compared to their RFC 1321 definitions for
|
||||
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
|
||||
* implementation.
|
||||
*/
|
||||
#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 H2(x, y, z) ((x) ^ ((y) ^ (z)))
|
||||
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
|
||||
/*
|
||||
* The MD5 transformation for all four rounds.
|
||||
*/
|
||||
#define STEP(f, a, b, c, d, x, t, s) \
|
||||
(a) += f((b), (c), (d)) + (x) + (t); \
|
||||
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
|
||||
(a) += (b);
|
||||
|
||||
/*
|
||||
* 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 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) \
|
||||
(*(MD5_u32plus *)&ptr[(n) * 4])
|
||||
#define GET(n) \
|
||||
SET(n)
|
||||
#else
|
||||
#define SET(n) \
|
||||
(ctx->block[(n)] = \
|
||||
(MD5_u32plus)ptr[(n) * 4] | \
|
||||
((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
|
||||
((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
|
||||
((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
|
||||
#define GET(n) \
|
||||
(ctx->block[(n)])
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This processes one or more 64-byte data blocks, but does NOT update the bit
|
||||
* counters. There are no alignment requirements.
|
||||
*/
|
||||
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
const unsigned char *ptr;
|
||||
MD5_u32plus a, b, c, d;
|
||||
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||
|
||||
ptr = (const unsigned char *)data;
|
||||
|
||||
a = ctx->a;
|
||||
b = ctx->b;
|
||||
c = ctx->c;
|
||||
d = ctx->d;
|
||||
|
||||
do {
|
||||
saved_a = a;
|
||||
saved_b = b;
|
||||
saved_c = c;
|
||||
saved_d = d;
|
||||
|
||||
/* Round 1 */
|
||||
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
|
||||
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
|
||||
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
|
||||
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
|
||||
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
|
||||
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
|
||||
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
|
||||
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
|
||||
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
|
||||
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
|
||||
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
|
||||
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
|
||||
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
|
||||
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
|
||||
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
|
||||
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
|
||||
|
||||
/* Round 2 */
|
||||
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
|
||||
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
|
||||
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
|
||||
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
|
||||
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
|
||||
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
|
||||
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
|
||||
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
|
||||
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
|
||||
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
|
||||
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
|
||||
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
|
||||
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
|
||||
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
|
||||
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
|
||||
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
|
||||
|
||||
/* Round 3 */
|
||||
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
|
||||
STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
|
||||
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
|
||||
STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
|
||||
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
|
||||
STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
|
||||
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
|
||||
STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
|
||||
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
|
||||
STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
|
||||
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
|
||||
STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
|
||||
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
|
||||
STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
|
||||
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
|
||||
STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
|
||||
|
||||
/* Round 4 */
|
||||
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
|
||||
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
|
||||
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
|
||||
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
|
||||
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
|
||||
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
|
||||
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
|
||||
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
|
||||
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
|
||||
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
|
||||
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
|
||||
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
|
||||
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
|
||||
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
|
||||
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
|
||||
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
|
||||
|
||||
a += saved_a;
|
||||
b += saved_b;
|
||||
c += saved_c;
|
||||
d += saved_d;
|
||||
|
||||
ptr += 64;
|
||||
} while (size -= 64);
|
||||
|
||||
ctx->a = a;
|
||||
ctx->b = b;
|
||||
ctx->c = c;
|
||||
ctx->d = d;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void MD5_Init(MD5_CTX *ctx)
|
||||
{
|
||||
ctx->a = 0x67452301;
|
||||
ctx->b = 0xefcdab89;
|
||||
ctx->c = 0x98badcfe;
|
||||
ctx->d = 0x10325476;
|
||||
|
||||
ctx->lo = 0;
|
||||
ctx->hi = 0;
|
||||
}
|
||||
|
||||
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
MD5_u32plus saved_lo;
|
||||
unsigned long used, available;
|
||||
|
||||
saved_lo = ctx->lo;
|
||||
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
|
||||
ctx->hi++;
|
||||
ctx->hi += size >> 29;
|
||||
|
||||
used = saved_lo & 0x3f;
|
||||
|
||||
if (used) {
|
||||
available = 64 - used;
|
||||
|
||||
if (size < available) {
|
||||
memcpy(&ctx->buffer[used], data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&ctx->buffer[used], data, available);
|
||||
data = (const unsigned char *)data + available;
|
||||
size -= available;
|
||||
body(ctx, ctx->buffer, 64);
|
||||
}
|
||||
|
||||
if (size >= 64) {
|
||||
data = body(ctx, data, size & ~(unsigned long)0x3f);
|
||||
size &= 0x3f;
|
||||
}
|
||||
|
||||
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, available;
|
||||
|
||||
used = ctx->lo & 0x3f;
|
||||
|
||||
ctx->buffer[used++] = 0x80;
|
||||
|
||||
available = 64 - used;
|
||||
|
||||
if (available < 8) {
|
||||
memset(&ctx->buffer[used], 0, available);
|
||||
body(ctx, ctx->buffer, 64);
|
||||
used = 0;
|
||||
available = 64;
|
||||
}
|
||||
|
||||
memset(&ctx->buffer[used], 0, available - 8);
|
||||
|
||||
ctx->lo <<= 3;
|
||||
OUT(&ctx->buffer[56], ctx->lo)
|
||||
OUT(&ctx->buffer[60], ctx->hi)
|
||||
|
||||
body(ctx, ctx->buffer, 64);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
#endif
|
||||
45
thirdparty/freetype/src/base/md5.h
vendored
Normal file
45
thirdparty/freetype/src/base/md5.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||
* MD5 Message-Digest Algorithm (RFC 1321).
|
||||
*
|
||||
* Homepage:
|
||||
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
|
||||
*
|
||||
* Author:
|
||||
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||
*
|
||||
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||
* claimed, and the software is hereby placed in the public domain.
|
||||
* In case this attempt to disclaim copyright and place the software in the
|
||||
* public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* See md5.c for more information.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/md5.h>
|
||||
#elif !defined(_MD5_H)
|
||||
#define _MD5_H
|
||||
|
||||
/* Any 32-bit or wider unsigned integer data type will do */
|
||||
typedef unsigned int MD5_u32plus;
|
||||
|
||||
typedef struct {
|
||||
MD5_u32plus lo, hi;
|
||||
MD5_u32plus a, b, c, d;
|
||||
unsigned char buffer[64];
|
||||
MD5_u32plus block[16];
|
||||
} MD5_CTX;
|
||||
|
||||
extern void MD5_Init(MD5_CTX *ctx);
|
||||
extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
|
||||
extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
|
||||
|
||||
#endif
|
||||
34
thirdparty/freetype/src/bdf/bdf.c
vendored
Normal file
34
thirdparty/freetype/src/bdf/bdf.c
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/* bdf.c
|
||||
|
||||
FreeType font driver for bdf files
|
||||
|
||||
Copyright (C) 2001, 2002 by
|
||||
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
|
||||
AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*/
|
||||
|
||||
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#include "bdflib.c"
|
||||
#include "bdfdrivr.c"
|
||||
|
||||
|
||||
/* END */
|
||||
253
thirdparty/freetype/src/bdf/bdf.h
vendored
Normal file
253
thirdparty/freetype/src/bdf/bdf.h
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright 2000 Computing Research Labs, New Mexico State University
|
||||
* Copyright 2001-2004, 2011 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BDF_H_
|
||||
#define BDF_H_
|
||||
|
||||
|
||||
/*
|
||||
* Based on bdf.h,v 1.16 2000/03/16 20:08:51 mleisher
|
||||
*/
|
||||
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftstream.h>
|
||||
#include <freetype/internal/fthash.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* Imported from bdfP.h */
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* BDF font options macros and types.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define BDF_CORRECT_METRICS 0x01 /* Correct invalid metrics when loading. */
|
||||
#define BDF_KEEP_COMMENTS 0x02 /* Preserve the font comments. */
|
||||
#define BDF_KEEP_UNENCODED 0x04 /* Keep the unencoded glyphs. */
|
||||
#define BDF_PROPORTIONAL 0x08 /* Font has proportional spacing. */
|
||||
#define BDF_MONOWIDTH 0x10 /* Font has mono width. */
|
||||
#define BDF_CHARCELL 0x20 /* Font has charcell spacing. */
|
||||
|
||||
#define BDF_ALL_SPACING ( BDF_PROPORTIONAL | \
|
||||
BDF_MONOWIDTH | \
|
||||
BDF_CHARCELL )
|
||||
|
||||
#define BDF_DEFAULT_LOAD_OPTIONS ( BDF_CORRECT_METRICS | \
|
||||
BDF_KEEP_COMMENTS | \
|
||||
BDF_KEEP_UNENCODED | \
|
||||
BDF_PROPORTIONAL )
|
||||
|
||||
|
||||
typedef struct bdf_options_t_
|
||||
{
|
||||
int correct_metrics;
|
||||
int keep_unencoded;
|
||||
int keep_comments;
|
||||
int font_spacing;
|
||||
|
||||
} bdf_options_t;
|
||||
|
||||
|
||||
/* Callback function type for unknown configuration options. */
|
||||
typedef int
|
||||
(*bdf_options_callback_t)( bdf_options_t* opts,
|
||||
char** params,
|
||||
unsigned long nparams,
|
||||
void* client_data );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* BDF font property macros and types.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define BDF_ATOM 1
|
||||
#define BDF_INTEGER 2
|
||||
#define BDF_CARDINAL 3
|
||||
|
||||
|
||||
/* This structure represents a particular property of a font. */
|
||||
/* There are a set of defaults and each font has their own. */
|
||||
typedef struct bdf_property_t_
|
||||
{
|
||||
const char* name; /* Name of the property. */
|
||||
int format; /* Format of the property. */
|
||||
int builtin; /* A builtin property. */
|
||||
union
|
||||
{
|
||||
char* atom;
|
||||
long l;
|
||||
unsigned long ul;
|
||||
|
||||
} value; /* Value of the property. */
|
||||
|
||||
} bdf_property_t;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* BDF font metric and glyph types.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
typedef struct bdf_bbx_t_
|
||||
{
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
|
||||
short x_offset;
|
||||
short y_offset;
|
||||
|
||||
short ascent;
|
||||
short descent;
|
||||
|
||||
} bdf_bbx_t;
|
||||
|
||||
|
||||
typedef struct bdf_glyph_t_
|
||||
{
|
||||
char* name; /* Glyph name. */
|
||||
unsigned long encoding; /* Glyph encoding. */
|
||||
unsigned short swidth; /* Scalable width. */
|
||||
unsigned short dwidth; /* Device width. */
|
||||
bdf_bbx_t bbx; /* Glyph bounding box. */
|
||||
unsigned char* bitmap; /* Glyph bitmap. */
|
||||
unsigned long bpr; /* Number of bytes used per row. */
|
||||
unsigned short bytes; /* Number of bytes used for the bitmap. */
|
||||
|
||||
} bdf_glyph_t;
|
||||
|
||||
|
||||
typedef struct bdf_font_t_
|
||||
{
|
||||
char* name; /* Name of the font. */
|
||||
bdf_bbx_t bbx; /* Font bounding box. */
|
||||
|
||||
unsigned long point_size; /* Point size of the font. */
|
||||
unsigned long resolution_x; /* Font horizontal resolution. */
|
||||
unsigned long resolution_y; /* Font vertical resolution. */
|
||||
|
||||
int spacing; /* Font spacing value. */
|
||||
|
||||
unsigned short monowidth; /* Logical width for monowidth font. */
|
||||
|
||||
unsigned long default_char; /* Encoding of the default glyph. */
|
||||
|
||||
long font_ascent; /* Font ascent. */
|
||||
long font_descent; /* Font descent. */
|
||||
|
||||
unsigned long glyphs_size; /* Glyph structures allocated. */
|
||||
unsigned long glyphs_used; /* Glyph structures used. */
|
||||
bdf_glyph_t* glyphs; /* Glyphs themselves. */
|
||||
|
||||
unsigned long unencoded_size; /* Unencoded glyph struct. allocated. */
|
||||
unsigned long unencoded_used; /* Unencoded glyph struct. used. */
|
||||
bdf_glyph_t* unencoded; /* Unencoded glyphs themselves. */
|
||||
|
||||
unsigned long props_size; /* Font properties allocated. */
|
||||
unsigned long props_used; /* Font properties used. */
|
||||
bdf_property_t* props; /* Font properties themselves. */
|
||||
|
||||
char* comments; /* Font comments. */
|
||||
unsigned long comments_len; /* Length of comment string. */
|
||||
|
||||
void* internal; /* Internal data for the font. */
|
||||
|
||||
unsigned short bpp; /* Bits per pixel. */
|
||||
|
||||
FT_Memory memory;
|
||||
|
||||
bdf_property_t* user_props;
|
||||
unsigned long nuser_props;
|
||||
FT_HashRec proptbl;
|
||||
|
||||
} bdf_font_t;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Types for load/save callbacks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* Error codes. */
|
||||
#define BDF_MISSING_START -1
|
||||
#define BDF_MISSING_FONTNAME -2
|
||||
#define BDF_MISSING_SIZE -3
|
||||
#define BDF_MISSING_CHARS -4
|
||||
#define BDF_MISSING_STARTCHAR -5
|
||||
#define BDF_MISSING_ENCODING -6
|
||||
#define BDF_MISSING_BBX -7
|
||||
|
||||
#define BDF_OUT_OF_MEMORY -20
|
||||
|
||||
#define BDF_INVALID_LINE -100
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* BDF font API.
|
||||
*
|
||||
*/
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
bdf_load_font( FT_Stream stream,
|
||||
FT_Memory memory,
|
||||
bdf_options_t* opts,
|
||||
bdf_font_t* *font );
|
||||
|
||||
FT_LOCAL( void )
|
||||
bdf_free_font( bdf_font_t* font );
|
||||
|
||||
FT_LOCAL( bdf_property_t * )
|
||||
bdf_get_font_property( bdf_font_t* font,
|
||||
const char* name );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* BDF_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
1013
thirdparty/freetype/src/bdf/bdfdrivr.c
vendored
Normal file
1013
thirdparty/freetype/src/bdf/bdfdrivr.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
72
thirdparty/freetype/src/bdf/bdfdrivr.h
vendored
Normal file
72
thirdparty/freetype/src/bdf/bdfdrivr.h
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
/* bdfdrivr.h
|
||||
|
||||
FreeType font driver for bdf fonts
|
||||
|
||||
Copyright (C) 2001, 2002, 2003, 2004 by
|
||||
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
|
||||
AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BDFDRIVR_H_
|
||||
#define BDFDRIVR_H_
|
||||
|
||||
#include <freetype/internal/ftdrv.h>
|
||||
|
||||
#include "bdf.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
typedef struct BDF_encoding_el_
|
||||
{
|
||||
FT_ULong enc;
|
||||
FT_UShort glyph;
|
||||
|
||||
} BDF_encoding_el;
|
||||
|
||||
|
||||
typedef struct BDF_FaceRec_
|
||||
{
|
||||
FT_FaceRec root;
|
||||
|
||||
char* charset_encoding;
|
||||
char* charset_registry;
|
||||
|
||||
bdf_font_t* bdffont;
|
||||
|
||||
BDF_encoding_el* en_table;
|
||||
|
||||
FT_UInt default_glyph;
|
||||
|
||||
} BDF_FaceRec, *BDF_Face;
|
||||
|
||||
|
||||
FT_EXPORT_VAR( const FT_Driver_ClassRec ) bdf_driver_class;
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* BDFDRIVR_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
45
thirdparty/freetype/src/bdf/bdferror.h
vendored
Normal file
45
thirdparty/freetype/src/bdf/bdferror.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2001, 2002, 2012 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 used to define the BDF error enumeration constants.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BDFERROR_H_
|
||||
#define BDFERROR_H_
|
||||
|
||||
#include <freetype/ftmoderr.h>
|
||||
|
||||
#undef FTERRORS_H_
|
||||
|
||||
#undef FT_ERR_PREFIX
|
||||
#define FT_ERR_PREFIX BDF_Err_
|
||||
#define FT_ERR_BASE FT_Mod_Err_BDF
|
||||
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
#endif /* BDFERROR_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
2378
thirdparty/freetype/src/bdf/bdflib.c
vendored
Normal file
2378
thirdparty/freetype/src/bdf/bdflib.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
535
thirdparty/freetype/src/bzip2/ftbzip2.c
vendored
Normal file
535
thirdparty/freetype/src/bzip2/ftbzip2.c
vendored
Normal file
@@ -0,0 +1,535 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftbzip2.c
|
||||
*
|
||||
* FreeType support for .bz2 compressed files.
|
||||
*
|
||||
* This optional component relies on libbz2. It should mainly be used to
|
||||
* parse compressed PCF fonts, as found with many X11 server
|
||||
* distributions.
|
||||
*
|
||||
* Copyright (C) 2010-2024 by
|
||||
* Joel Klinghed.
|
||||
*
|
||||
* based on `src/gzip/ftgzip.c'
|
||||
*
|
||||
* 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 <freetype/internal/ftmemory.h>
|
||||
#include <freetype/internal/ftstream.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/ftbzip2.h>
|
||||
#include FT_CONFIG_STANDARD_LIBRARY_H
|
||||
|
||||
|
||||
#include <freetype/ftmoderr.h>
|
||||
|
||||
#undef FTERRORS_H_
|
||||
|
||||
#undef FT_ERR_PREFIX
|
||||
#define FT_ERR_PREFIX Bzip2_Err_
|
||||
#define FT_ERR_BASE FT_Mod_Err_Bzip2
|
||||
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_USE_BZIP2
|
||||
|
||||
#define BZ_NO_STDIO /* Do not need FILE */
|
||||
#include <bzlib.h>
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
/***** *****/
|
||||
/***** B Z I P 2 M E M O R Y M A N A G E M E N T *****/
|
||||
/***** *****/
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
|
||||
/* it is better to use FreeType memory routines instead of raw
|
||||
'malloc/free' */
|
||||
|
||||
typedef void* (*alloc_func)( void*, int, int );
|
||||
typedef void (*free_func) ( void*, void* );
|
||||
|
||||
|
||||
static void*
|
||||
ft_bzip2_alloc( void* memory_, /* FT_Memory */
|
||||
int items,
|
||||
int size )
|
||||
{
|
||||
FT_Memory memory = (FT_Memory)memory_;
|
||||
|
||||
FT_ULong sz = (FT_ULong)size * (FT_ULong)items;
|
||||
FT_Error error;
|
||||
FT_Pointer p = NULL;
|
||||
|
||||
|
||||
FT_MEM_QALLOC( p, sz );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_bzip2_free( void* memory_, /* FT_Memory */
|
||||
void* address )
|
||||
{
|
||||
FT_Memory memory = (FT_Memory)memory_;
|
||||
|
||||
|
||||
FT_MEM_FREE( address );
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
/***** *****/
|
||||
/***** B Z I P 2 F I L E D E S C R I P T O R *****/
|
||||
/***** *****/
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
|
||||
#define FT_BZIP2_BUFFER_SIZE 4096
|
||||
|
||||
typedef struct FT_BZip2FileRec_
|
||||
{
|
||||
FT_Stream source; /* parent/source stream */
|
||||
FT_Stream stream; /* embedding stream */
|
||||
FT_Memory memory; /* memory allocator */
|
||||
bz_stream bzstream; /* bzlib input stream */
|
||||
|
||||
FT_Byte input[FT_BZIP2_BUFFER_SIZE]; /* input read buffer */
|
||||
|
||||
FT_Byte buffer[FT_BZIP2_BUFFER_SIZE]; /* output buffer */
|
||||
FT_ULong pos; /* position in output */
|
||||
FT_Byte* cursor;
|
||||
FT_Byte* limit;
|
||||
FT_Bool reset; /* reset before next read */
|
||||
|
||||
} FT_BZip2FileRec, *FT_BZip2File;
|
||||
|
||||
|
||||
/* check and skip .bz2 header - we don't support `transparent' compression */
|
||||
static FT_Error
|
||||
ft_bzip2_check_header( FT_Stream stream )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Byte head[4];
|
||||
|
||||
|
||||
if ( FT_STREAM_SEEK( 0 ) ||
|
||||
FT_STREAM_READ( head, 4 ) )
|
||||
goto Exit;
|
||||
|
||||
/* head[0] && head[1] are the magic numbers; */
|
||||
/* head[2] is the version, and head[3] the blocksize */
|
||||
if ( head[0] != 0x42 ||
|
||||
head[1] != 0x5A ||
|
||||
head[2] != 0x68 ) /* only support bzip2 (huffman) */
|
||||
{
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_bzip2_file_init( FT_BZip2File zip,
|
||||
FT_Stream stream,
|
||||
FT_Stream source )
|
||||
{
|
||||
bz_stream* bzstream = &zip->bzstream;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
zip->stream = stream;
|
||||
zip->source = source;
|
||||
zip->memory = stream->memory;
|
||||
|
||||
zip->limit = zip->buffer + FT_BZIP2_BUFFER_SIZE;
|
||||
zip->cursor = zip->limit;
|
||||
zip->pos = 0;
|
||||
zip->reset = 0;
|
||||
|
||||
/* check .bz2 header */
|
||||
{
|
||||
stream = source;
|
||||
|
||||
error = ft_bzip2_check_header( stream );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
if ( FT_STREAM_SEEK( 0 ) )
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* initialize bzlib */
|
||||
bzstream->bzalloc = ft_bzip2_alloc;
|
||||
bzstream->bzfree = ft_bzip2_free;
|
||||
bzstream->opaque = zip->memory;
|
||||
|
||||
bzstream->avail_in = 0;
|
||||
bzstream->next_in = (char*)zip->buffer;
|
||||
|
||||
if ( BZ2_bzDecompressInit( bzstream, 0, 0 ) != BZ_OK ||
|
||||
!bzstream->next_in )
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_bzip2_file_done( FT_BZip2File zip )
|
||||
{
|
||||
bz_stream* bzstream = &zip->bzstream;
|
||||
|
||||
|
||||
BZ2_bzDecompressEnd( bzstream );
|
||||
|
||||
/* clear the rest */
|
||||
bzstream->bzalloc = NULL;
|
||||
bzstream->bzfree = NULL;
|
||||
bzstream->opaque = NULL;
|
||||
bzstream->next_in = NULL;
|
||||
bzstream->next_out = NULL;
|
||||
bzstream->avail_in = 0;
|
||||
bzstream->avail_out = 0;
|
||||
|
||||
zip->memory = NULL;
|
||||
zip->source = NULL;
|
||||
zip->stream = NULL;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_bzip2_file_reset( FT_BZip2File zip )
|
||||
{
|
||||
FT_Stream stream = zip->source;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
if ( !FT_STREAM_SEEK( 0 ) )
|
||||
{
|
||||
bz_stream* bzstream = &zip->bzstream;
|
||||
|
||||
|
||||
BZ2_bzDecompressEnd( bzstream );
|
||||
|
||||
bzstream->avail_in = 0;
|
||||
bzstream->next_in = (char*)zip->input;
|
||||
bzstream->avail_out = 0;
|
||||
bzstream->next_out = (char*)zip->buffer;
|
||||
|
||||
zip->limit = zip->buffer + FT_BZIP2_BUFFER_SIZE;
|
||||
zip->cursor = zip->limit;
|
||||
zip->pos = 0;
|
||||
zip->reset = 0;
|
||||
|
||||
BZ2_bzDecompressInit( bzstream, 0, 0 );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_bzip2_file_fill_input( FT_BZip2File zip )
|
||||
{
|
||||
bz_stream* bzstream = &zip->bzstream;
|
||||
FT_Stream stream = zip->source;
|
||||
FT_ULong size;
|
||||
|
||||
|
||||
if ( stream->read )
|
||||
{
|
||||
size = stream->read( stream, stream->pos, zip->input,
|
||||
FT_BZIP2_BUFFER_SIZE );
|
||||
if ( size == 0 )
|
||||
{
|
||||
zip->limit = zip->cursor;
|
||||
return FT_THROW( Invalid_Stream_Operation );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size = stream->size - stream->pos;
|
||||
if ( size > FT_BZIP2_BUFFER_SIZE )
|
||||
size = FT_BZIP2_BUFFER_SIZE;
|
||||
|
||||
if ( size == 0 )
|
||||
{
|
||||
zip->limit = zip->cursor;
|
||||
return FT_THROW( Invalid_Stream_Operation );
|
||||
}
|
||||
|
||||
FT_MEM_COPY( zip->input, stream->base + stream->pos, size );
|
||||
}
|
||||
stream->pos += size;
|
||||
|
||||
bzstream->next_in = (char*)zip->input;
|
||||
bzstream->avail_in = size;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_bzip2_file_fill_output( FT_BZip2File zip )
|
||||
{
|
||||
bz_stream* bzstream = &zip->bzstream;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
zip->cursor = zip->buffer;
|
||||
bzstream->next_out = (char*)zip->cursor;
|
||||
bzstream->avail_out = FT_BZIP2_BUFFER_SIZE;
|
||||
|
||||
while ( bzstream->avail_out > 0 )
|
||||
{
|
||||
int err;
|
||||
|
||||
|
||||
if ( bzstream->avail_in == 0 )
|
||||
{
|
||||
error = ft_bzip2_file_fill_input( zip );
|
||||
if ( error )
|
||||
break;
|
||||
}
|
||||
|
||||
err = BZ2_bzDecompress( bzstream );
|
||||
|
||||
if ( err != BZ_OK )
|
||||
{
|
||||
zip->reset = 1;
|
||||
|
||||
if ( err == BZ_STREAM_END )
|
||||
{
|
||||
zip->limit = (FT_Byte*)bzstream->next_out;
|
||||
if ( zip->limit == zip->cursor )
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
zip->limit = zip->cursor;
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* fill output buffer; `count' must be <= FT_BZIP2_BUFFER_SIZE */
|
||||
static FT_Error
|
||||
ft_bzip2_file_skip_output( FT_BZip2File zip,
|
||||
FT_ULong count )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
FT_ULong delta = (FT_ULong)( zip->limit - zip->cursor );
|
||||
|
||||
|
||||
if ( delta >= count )
|
||||
delta = count;
|
||||
|
||||
zip->cursor += delta;
|
||||
zip->pos += delta;
|
||||
|
||||
count -= delta;
|
||||
if ( count == 0 )
|
||||
break;
|
||||
|
||||
error = ft_bzip2_file_fill_output( zip );
|
||||
if ( error )
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static FT_ULong
|
||||
ft_bzip2_file_io( FT_BZip2File zip,
|
||||
FT_ULong pos,
|
||||
FT_Byte* buffer,
|
||||
FT_ULong count )
|
||||
{
|
||||
FT_ULong result = 0;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
/* Reset inflate stream if seeking backwards or bzip reported an error. */
|
||||
/* Yes, that is not too efficient, but it saves memory :-) */
|
||||
if ( pos < zip->pos || zip->reset )
|
||||
{
|
||||
error = ft_bzip2_file_reset( zip );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* skip unwanted bytes */
|
||||
if ( pos > zip->pos )
|
||||
{
|
||||
error = ft_bzip2_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( count == 0 )
|
||||
goto Exit;
|
||||
|
||||
/* now read the data */
|
||||
for (;;)
|
||||
{
|
||||
FT_ULong delta;
|
||||
|
||||
|
||||
delta = (FT_ULong)( zip->limit - zip->cursor );
|
||||
if ( delta >= count )
|
||||
delta = count;
|
||||
|
||||
FT_MEM_COPY( buffer, zip->cursor, delta );
|
||||
buffer += delta;
|
||||
result += delta;
|
||||
zip->cursor += delta;
|
||||
zip->pos += delta;
|
||||
|
||||
count -= delta;
|
||||
if ( count == 0 )
|
||||
break;
|
||||
|
||||
error = ft_bzip2_file_fill_output( zip );
|
||||
if ( error )
|
||||
break;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
/***** *****/
|
||||
/***** B Z E M B E D D I N G S T R E A M *****/
|
||||
/***** *****/
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
|
||||
static void
|
||||
ft_bzip2_stream_close( FT_Stream stream )
|
||||
{
|
||||
FT_BZip2File zip = (FT_BZip2File)stream->descriptor.pointer;
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
if ( zip )
|
||||
{
|
||||
/* finalize bzip file descriptor */
|
||||
ft_bzip2_file_done( zip );
|
||||
|
||||
FT_FREE( zip );
|
||||
|
||||
stream->descriptor.pointer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static unsigned long
|
||||
ft_bzip2_stream_io( FT_Stream stream,
|
||||
unsigned long offset,
|
||||
unsigned char* buffer,
|
||||
unsigned long count )
|
||||
{
|
||||
FT_BZip2File zip = (FT_BZip2File)stream->descriptor.pointer;
|
||||
|
||||
|
||||
return ft_bzip2_file_io( zip, offset, buffer, count );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Stream_OpenBzip2( FT_Stream stream,
|
||||
FT_Stream source )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
FT_BZip2File zip = NULL;
|
||||
|
||||
|
||||
if ( !stream || !source )
|
||||
{
|
||||
error = FT_THROW( Invalid_Stream_Handle );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
memory = source->memory;
|
||||
|
||||
/*
|
||||
* check the header right now; this prevents allocating unnecessary
|
||||
* objects when we don't need them
|
||||
*/
|
||||
error = ft_bzip2_check_header( source );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
FT_ZERO( stream );
|
||||
stream->memory = memory;
|
||||
|
||||
if ( !FT_QNEW( zip ) )
|
||||
{
|
||||
error = ft_bzip2_file_init( zip, stream, source );
|
||||
if ( error )
|
||||
{
|
||||
FT_FREE( zip );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
stream->descriptor.pointer = zip;
|
||||
}
|
||||
|
||||
stream->size = 0x7FFFFFFFL; /* don't know the real size! */
|
||||
stream->pos = 0;
|
||||
stream->base = NULL;
|
||||
stream->read = ft_bzip2_stream_io;
|
||||
stream->close = ft_bzip2_stream_close;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#else /* !FT_CONFIG_OPTION_USE_BZIP2 */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Stream_OpenBzip2( FT_Stream stream,
|
||||
FT_Stream source )
|
||||
{
|
||||
FT_UNUSED( stream );
|
||||
FT_UNUSED( source );
|
||||
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
}
|
||||
|
||||
#endif /* !FT_CONFIG_OPTION_USE_BZIP2 */
|
||||
|
||||
|
||||
/* END */
|
||||
31
thirdparty/freetype/src/cache/ftcache.c
vendored
Normal file
31
thirdparty/freetype/src/cache/ftcache.c
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcache.c
|
||||
*
|
||||
* The FreeType Caching sub-system (body only).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#include "ftcbasic.c"
|
||||
#include "ftccache.c"
|
||||
#include "ftccmap.c"
|
||||
#include "ftcglyph.c"
|
||||
#include "ftcimage.c"
|
||||
#include "ftcmanag.c"
|
||||
#include "ftcmru.c"
|
||||
#include "ftcsbits.c"
|
||||
|
||||
|
||||
/* END */
|
||||
598
thirdparty/freetype/src/cache/ftcbasic.c
vendored
Normal file
598
thirdparty/freetype/src/cache/ftcbasic.c
vendored
Normal file
@@ -0,0 +1,598 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcbasic.c
|
||||
*
|
||||
* The FreeType basic cache interface (body).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/ftcache.h>
|
||||
#include "ftcglyph.h"
|
||||
#include "ftcimage.h"
|
||||
#include "ftcsbits.h"
|
||||
|
||||
#include "ftccback.h"
|
||||
#include "ftcerror.h"
|
||||
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT cache
|
||||
|
||||
|
||||
/*
|
||||
* Basic Families
|
||||
*
|
||||
*/
|
||||
typedef struct FTC_BasicAttrRec_
|
||||
{
|
||||
FTC_ScalerRec scaler;
|
||||
FT_Int32 load_flags;
|
||||
|
||||
} FTC_BasicAttrRec, *FTC_BasicAttrs;
|
||||
|
||||
#define FTC_BASIC_ATTR_COMPARE( a, b ) \
|
||||
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 ) + \
|
||||
(FT_Offset)( 31 * (a)->load_flags ) )
|
||||
|
||||
|
||||
typedef struct FTC_BasicQueryRec_
|
||||
{
|
||||
FTC_GQueryRec gquery;
|
||||
FTC_BasicAttrRec attrs;
|
||||
|
||||
} FTC_BasicQueryRec, *FTC_BasicQuery;
|
||||
|
||||
|
||||
typedef struct FTC_BasicFamilyRec_
|
||||
{
|
||||
FTC_FamilyRec family;
|
||||
FTC_BasicAttrRec attrs;
|
||||
|
||||
} FTC_BasicFamilyRec, *FTC_BasicFamily;
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_basic_family_compare( FTC_MruNode ftcfamily,
|
||||
FT_Pointer ftcquery )
|
||||
{
|
||||
FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
|
||||
FTC_BasicQuery query = (FTC_BasicQuery)ftcquery;
|
||||
|
||||
|
||||
return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_basic_family_init( FTC_MruNode ftcfamily,
|
||||
FT_Pointer ftcquery,
|
||||
FT_Pointer ftccache )
|
||||
{
|
||||
FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
|
||||
FTC_BasicQuery query = (FTC_BasicQuery)ftcquery;
|
||||
FTC_Cache cache = (FTC_Cache)ftccache;
|
||||
|
||||
|
||||
FTC_Family_Init( FTC_FAMILY( family ), cache );
|
||||
family->attrs = query->attrs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_UInt )
|
||||
ftc_basic_family_get_count( FTC_Family ftcfamily,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
|
||||
FT_Error error;
|
||||
FT_Face face;
|
||||
FT_UInt result = 0;
|
||||
|
||||
|
||||
error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id,
|
||||
&face );
|
||||
|
||||
if ( error || !face )
|
||||
return result;
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs )
|
||||
{
|
||||
FT_TRACE1(( "ftc_basic_family_get_count:"
|
||||
" the number of glyphs in this face is %ld,\n",
|
||||
face->num_glyphs ));
|
||||
FT_TRACE1(( " "
|
||||
" which is too much and thus truncated\n" ));
|
||||
}
|
||||
#endif
|
||||
|
||||
result = (FT_UInt)face->num_glyphs;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_basic_family_load_bitmap( FTC_Family ftcfamily,
|
||||
FT_UInt gindex,
|
||||
FTC_Manager manager,
|
||||
FT_Face *aface )
|
||||
{
|
||||
FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
|
||||
FT_Error error;
|
||||
FT_Size size;
|
||||
|
||||
|
||||
error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size );
|
||||
if ( !error )
|
||||
{
|
||||
FT_Face face = size->face;
|
||||
|
||||
|
||||
error = FT_Load_Glyph( face,
|
||||
gindex,
|
||||
family->attrs.load_flags | FT_LOAD_RENDER );
|
||||
if ( !error )
|
||||
*aface = face;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_basic_family_load_glyph( FTC_Family ftcfamily,
|
||||
FT_UInt gindex,
|
||||
FTC_Cache cache,
|
||||
FT_Glyph *aglyph )
|
||||
{
|
||||
FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily;
|
||||
FT_Error error;
|
||||
FTC_Scaler scaler = &family->attrs.scaler;
|
||||
FT_Face face;
|
||||
FT_Size size;
|
||||
|
||||
|
||||
/* we will now load the glyph image */
|
||||
error = FTC_Manager_LookupSize( cache->manager,
|
||||
scaler,
|
||||
&size );
|
||||
if ( !error )
|
||||
{
|
||||
face = size->face;
|
||||
|
||||
error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );
|
||||
if ( !error )
|
||||
{
|
||||
if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP ||
|
||||
face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ||
|
||||
face->glyph->format == FT_GLYPH_FORMAT_SVG )
|
||||
{
|
||||
/* ok, copy it */
|
||||
FT_Glyph glyph;
|
||||
|
||||
|
||||
error = FT_Get_Glyph( face->glyph, &glyph );
|
||||
if ( !error )
|
||||
{
|
||||
*aglyph = glyph;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode,
|
||||
FT_Pointer ftcface_id,
|
||||
FTC_Cache cache,
|
||||
FT_Bool* list_changed )
|
||||
{
|
||||
FTC_GNode gnode = (FTC_GNode)ftcgnode;
|
||||
FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
|
||||
FTC_BasicFamily family = (FTC_BasicFamily)gnode->family;
|
||||
FT_Bool result;
|
||||
|
||||
|
||||
if ( list_changed )
|
||||
*list_changed = FALSE;
|
||||
result = FT_BOOL( family->attrs.scaler.face_id == face_id );
|
||||
if ( result )
|
||||
{
|
||||
/* we must call this function to avoid this node from appearing
|
||||
* in later lookups with the same face_id!
|
||||
*/
|
||||
FTC_GNode_UnselectFamily( gnode, cache );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* basic image cache
|
||||
*
|
||||
*/
|
||||
|
||||
static
|
||||
const FTC_IFamilyClassRec ftc_basic_image_family_class =
|
||||
{
|
||||
{
|
||||
sizeof ( FTC_BasicFamilyRec ),
|
||||
|
||||
ftc_basic_family_compare, /* FTC_MruNode_CompareFunc node_compare */
|
||||
ftc_basic_family_init, /* FTC_MruNode_InitFunc node_init */
|
||||
NULL /* FTC_MruNode_DoneFunc node_done */
|
||||
},
|
||||
|
||||
ftc_basic_family_load_glyph /* FTC_IFamily_LoadGlyphFunc family_load_glyph */
|
||||
};
|
||||
|
||||
|
||||
static
|
||||
const FTC_GCacheClassRec ftc_basic_image_cache_class =
|
||||
{
|
||||
{
|
||||
ftc_inode_new, /* FTC_Node_NewFunc node_new */
|
||||
ftc_inode_weight, /* FTC_Node_WeightFunc node_weight */
|
||||
ftc_gnode_compare, /* FTC_Node_CompareFunc node_compare */
|
||||
ftc_basic_gnode_compare_faceid, /* FTC_Node_CompareFunc node_remove_faceid */
|
||||
ftc_inode_free, /* FTC_Node_FreeFunc node_free */
|
||||
|
||||
sizeof ( FTC_GCacheRec ),
|
||||
ftc_gcache_init, /* FTC_Cache_InitFunc cache_init */
|
||||
ftc_gcache_done /* FTC_Cache_DoneFunc cache_done */
|
||||
},
|
||||
|
||||
(FTC_MruListClass)&ftc_basic_image_family_class
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_ImageCache_New( FTC_Manager manager,
|
||||
FTC_ImageCache *acache )
|
||||
{
|
||||
return FTC_GCache_New( manager, &ftc_basic_image_cache_class,
|
||||
(FTC_GCache*)acache );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_ImageCache_Lookup( FTC_ImageCache cache,
|
||||
FTC_ImageType type,
|
||||
FT_UInt gindex,
|
||||
FT_Glyph *aglyph,
|
||||
FTC_Node *anode )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_BasicQueryRec query;
|
||||
FTC_Node node = NULL; /* make compiler happy */
|
||||
FT_Offset hash;
|
||||
|
||||
|
||||
/* other argument checks delayed to `FTC_Cache_Lookup' */
|
||||
if ( !aglyph )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
*aglyph = NULL;
|
||||
if ( anode )
|
||||
*anode = NULL;
|
||||
|
||||
query.attrs.scaler.face_id = type->face_id;
|
||||
query.attrs.scaler.width = type->width;
|
||||
query.attrs.scaler.height = type->height;
|
||||
query.attrs.load_flags = type->flags;
|
||||
|
||||
query.attrs.scaler.pixel = 1;
|
||||
query.attrs.scaler.x_res = 0; /* make compilers happy */
|
||||
query.attrs.scaler.y_res = 0;
|
||||
|
||||
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
|
||||
|
||||
#ifdef FTC_INLINE /* inlining is about 50% faster! */
|
||||
FTC_GCACHE_LOOKUP_CMP( cache,
|
||||
ftc_basic_family_compare,
|
||||
ftc_gnode_compare,
|
||||
hash, gindex,
|
||||
&query,
|
||||
node,
|
||||
error );
|
||||
#else
|
||||
error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
|
||||
hash, gindex,
|
||||
FTC_GQUERY( &query ),
|
||||
&node );
|
||||
#endif
|
||||
if ( !error )
|
||||
{
|
||||
*aglyph = FTC_INODE( node )->glyph;
|
||||
|
||||
if ( anode )
|
||||
{
|
||||
*anode = node;
|
||||
node->ref_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_ImageCache_LookupScaler( FTC_ImageCache cache,
|
||||
FTC_Scaler scaler,
|
||||
FT_ULong load_flags,
|
||||
FT_UInt gindex,
|
||||
FT_Glyph *aglyph,
|
||||
FTC_Node *anode )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_BasicQueryRec query;
|
||||
FTC_Node node = NULL; /* make compiler happy */
|
||||
FT_Offset hash;
|
||||
|
||||
|
||||
/* other argument checks delayed to `FTC_Cache_Lookup' */
|
||||
if ( !aglyph || !scaler )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
*aglyph = NULL;
|
||||
if ( anode )
|
||||
*anode = NULL;
|
||||
|
||||
/*
|
||||
* Internal `FTC_BasicAttr->load_flags' is of type `FT_Int32',
|
||||
* but public `FT_Face->face_flags' is of type `FT_Long'.
|
||||
*
|
||||
* On long > int systems, higher bits of load_flags cannot be handled.
|
||||
*/
|
||||
#if FT_ULONG_MAX > 0xFFFFFFFFUL
|
||||
if ( load_flags > 0xFFFFFFFFUL )
|
||||
FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
|
||||
" higher bits in load_flags 0x%lx are dropped\n",
|
||||
load_flags & ~0xFFFFFFFFUL ));
|
||||
#endif
|
||||
|
||||
query.attrs.scaler = scaler[0];
|
||||
query.attrs.load_flags = (FT_Int32)load_flags;
|
||||
|
||||
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
|
||||
|
||||
FTC_GCACHE_LOOKUP_CMP( cache,
|
||||
ftc_basic_family_compare,
|
||||
ftc_gnode_compare,
|
||||
hash, gindex,
|
||||
&query,
|
||||
node,
|
||||
error );
|
||||
if ( !error )
|
||||
{
|
||||
*aglyph = FTC_INODE( node )->glyph;
|
||||
|
||||
if ( anode )
|
||||
{
|
||||
*anode = node;
|
||||
node->ref_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* basic small bitmap cache
|
||||
*
|
||||
*/
|
||||
|
||||
static
|
||||
const FTC_SFamilyClassRec ftc_basic_sbit_family_class =
|
||||
{
|
||||
{
|
||||
sizeof ( FTC_BasicFamilyRec ),
|
||||
ftc_basic_family_compare, /* FTC_MruNode_CompareFunc node_compare */
|
||||
ftc_basic_family_init, /* FTC_MruNode_InitFunc node_init */
|
||||
NULL /* FTC_MruNode_DoneFunc node_done */
|
||||
},
|
||||
|
||||
ftc_basic_family_get_count,
|
||||
ftc_basic_family_load_bitmap
|
||||
};
|
||||
|
||||
|
||||
static
|
||||
const FTC_GCacheClassRec ftc_basic_sbit_cache_class =
|
||||
{
|
||||
{
|
||||
ftc_snode_new, /* FTC_Node_NewFunc node_new */
|
||||
ftc_snode_weight, /* FTC_Node_WeightFunc node_weight */
|
||||
ftc_snode_compare, /* FTC_Node_CompareFunc node_compare */
|
||||
ftc_basic_gnode_compare_faceid, /* FTC_Node_CompareFunc node_remove_faceid */
|
||||
ftc_snode_free, /* FTC_Node_FreeFunc node_free */
|
||||
|
||||
sizeof ( FTC_GCacheRec ),
|
||||
ftc_gcache_init, /* FTC_Cache_InitFunc cache_init */
|
||||
ftc_gcache_done /* FTC_Cache_DoneFunc cache_done */
|
||||
},
|
||||
|
||||
(FTC_MruListClass)&ftc_basic_sbit_family_class
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_SBitCache_New( FTC_Manager manager,
|
||||
FTC_SBitCache *acache )
|
||||
{
|
||||
return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class,
|
||||
(FTC_GCache*)acache );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_SBitCache_Lookup( FTC_SBitCache cache,
|
||||
FTC_ImageType type,
|
||||
FT_UInt gindex,
|
||||
FTC_SBit *ansbit,
|
||||
FTC_Node *anode )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_BasicQueryRec query;
|
||||
FTC_Node node = NULL; /* make compiler happy */
|
||||
FT_Offset hash;
|
||||
|
||||
|
||||
/* other argument checks delayed to `FTC_Cache_Lookup' */
|
||||
if ( !ansbit )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
*ansbit = NULL;
|
||||
if ( anode )
|
||||
*anode = NULL;
|
||||
|
||||
query.attrs.scaler.face_id = type->face_id;
|
||||
query.attrs.scaler.width = type->width;
|
||||
query.attrs.scaler.height = type->height;
|
||||
query.attrs.load_flags = type->flags;
|
||||
|
||||
query.attrs.scaler.pixel = 1;
|
||||
query.attrs.scaler.x_res = 0; /* make compilers happy */
|
||||
query.attrs.scaler.y_res = 0;
|
||||
|
||||
/* beware, the hash must be the same for all glyph ranges! */
|
||||
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
|
||||
gindex / FTC_SBIT_ITEMS_PER_NODE;
|
||||
|
||||
#ifdef FTC_INLINE /* inlining is about 50% faster! */
|
||||
FTC_GCACHE_LOOKUP_CMP( cache,
|
||||
ftc_basic_family_compare,
|
||||
ftc_snode_compare,
|
||||
hash, gindex,
|
||||
&query,
|
||||
node,
|
||||
error );
|
||||
#else
|
||||
error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
|
||||
hash,
|
||||
gindex,
|
||||
FTC_GQUERY( &query ),
|
||||
&node );
|
||||
#endif
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
*ansbit = FTC_SNODE( node )->sbits +
|
||||
( gindex - FTC_GNODE( node )->gindex );
|
||||
|
||||
if ( anode )
|
||||
{
|
||||
*anode = node;
|
||||
node->ref_count++;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_SBitCache_LookupScaler( FTC_SBitCache cache,
|
||||
FTC_Scaler scaler,
|
||||
FT_ULong load_flags,
|
||||
FT_UInt gindex,
|
||||
FTC_SBit *ansbit,
|
||||
FTC_Node *anode )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_BasicQueryRec query;
|
||||
FTC_Node node = NULL; /* make compiler happy */
|
||||
FT_Offset hash;
|
||||
|
||||
|
||||
/* other argument checks delayed to `FTC_Cache_Lookup' */
|
||||
if ( !ansbit || !scaler )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
*ansbit = NULL;
|
||||
if ( anode )
|
||||
*anode = NULL;
|
||||
|
||||
/*
|
||||
* Internal `FTC_BasicAttr->load_flags' is of type `FT_Int32',
|
||||
* but public `FT_Face->face_flags' is of type `FT_Long'.
|
||||
*
|
||||
* On long > int systems, higher bits of load_flags cannot be handled.
|
||||
*/
|
||||
#if FT_ULONG_MAX > 0xFFFFFFFFUL
|
||||
if ( load_flags > 0xFFFFFFFFUL )
|
||||
FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
|
||||
" higher bits in load_flags 0x%lx are dropped\n",
|
||||
load_flags & ~0xFFFFFFFFUL ));
|
||||
#endif
|
||||
|
||||
query.attrs.scaler = scaler[0];
|
||||
query.attrs.load_flags = (FT_Int32)load_flags;
|
||||
|
||||
/* beware, the hash must be the same for all glyph ranges! */
|
||||
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) +
|
||||
gindex / FTC_SBIT_ITEMS_PER_NODE;
|
||||
|
||||
FTC_GCACHE_LOOKUP_CMP( cache,
|
||||
ftc_basic_family_compare,
|
||||
ftc_snode_compare,
|
||||
hash, gindex,
|
||||
&query,
|
||||
node,
|
||||
error );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
*ansbit = FTC_SNODE( node )->sbits +
|
||||
( gindex - FTC_GNODE( node )->gindex );
|
||||
|
||||
if ( anode )
|
||||
{
|
||||
*anode = node;
|
||||
node->ref_count++;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
584
thirdparty/freetype/src/cache/ftccache.c
vendored
Normal file
584
thirdparty/freetype/src/cache/ftccache.c
vendored
Normal file
@@ -0,0 +1,584 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftccache.c
|
||||
*
|
||||
* The FreeType internal cache interface (body).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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 "ftcmanag.h"
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
|
||||
#include "ftccback.h"
|
||||
#include "ftcerror.h"
|
||||
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT cache
|
||||
|
||||
|
||||
#define FTC_HASH_MAX_LOAD 2
|
||||
#define FTC_HASH_MIN_LOAD 1
|
||||
#define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD )
|
||||
|
||||
/* this one _must_ be a power of 2! */
|
||||
#define FTC_HASH_INITIAL_SIZE 8
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CACHE NODE DEFINITIONS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* add a new node to the head of the manager's circular MRU list */
|
||||
static void
|
||||
ftc_node_mru_link( FTC_Node node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
void *nl = &manager->nodes_list;
|
||||
|
||||
|
||||
FTC_MruNode_Prepend( (FTC_MruNode*)nl,
|
||||
(FTC_MruNode)node );
|
||||
manager->num_nodes++;
|
||||
}
|
||||
|
||||
|
||||
/* remove a node from the manager's MRU list */
|
||||
static void
|
||||
ftc_node_mru_unlink( FTC_Node node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
void *nl = &manager->nodes_list;
|
||||
|
||||
|
||||
FTC_MruNode_Remove( (FTC_MruNode*)nl,
|
||||
(FTC_MruNode)node );
|
||||
manager->num_nodes--;
|
||||
}
|
||||
|
||||
|
||||
#ifndef FTC_INLINE
|
||||
|
||||
/* move a node to the head of the manager's MRU list */
|
||||
static void
|
||||
ftc_node_mru_up( FTC_Node node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list,
|
||||
(FTC_MruNode)node );
|
||||
}
|
||||
|
||||
|
||||
/* get a top bucket for specified hash from cache,
|
||||
* body for FTC_NODE_TOP_FOR_HASH( cache, hash )
|
||||
*/
|
||||
FT_LOCAL_DEF( FTC_Node* )
|
||||
ftc_get_top_node_for_hash( FTC_Cache cache,
|
||||
FT_Offset hash )
|
||||
{
|
||||
FT_Offset idx;
|
||||
|
||||
|
||||
idx = hash & cache->mask;
|
||||
if ( idx >= cache->p )
|
||||
idx = hash & ( cache->mask >> 1 );
|
||||
|
||||
return cache->buckets + idx;
|
||||
}
|
||||
|
||||
#endif /* !FTC_INLINE */
|
||||
|
||||
|
||||
/* Note that this function cannot fail. If we cannot re-size the
|
||||
* buckets array appropriately, we simply degrade the hash table's
|
||||
* performance!
|
||||
*/
|
||||
static void
|
||||
ftc_cache_resize( FTC_Cache cache )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
FTC_Node node, *pnode;
|
||||
FT_UFast p = cache->p;
|
||||
FT_UFast size = cache->mask + 1; /* available size */
|
||||
FT_UFast half = size >> 1;
|
||||
|
||||
|
||||
/* do we need to expand the buckets array? */
|
||||
if ( cache->slack < 0 )
|
||||
{
|
||||
FTC_Node new_list = NULL;
|
||||
|
||||
|
||||
/* try to expand the buckets array _before_ splitting
|
||||
* the bucket lists
|
||||
*/
|
||||
if ( p == size )
|
||||
{
|
||||
FT_Memory memory = cache->memory;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
/* if we can't expand the array, leave immediately */
|
||||
if ( FT_QRENEW_ARRAY( cache->buckets, size, size * 2 ) )
|
||||
break;
|
||||
|
||||
cache->mask = 2 * size - 1;
|
||||
half = size;
|
||||
}
|
||||
|
||||
/* the bucket to split */
|
||||
pnode = cache->buckets + p - half;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
node = *pnode;
|
||||
if ( !node )
|
||||
break;
|
||||
|
||||
if ( node->hash & half )
|
||||
{
|
||||
*pnode = node->link;
|
||||
node->link = new_list;
|
||||
new_list = node;
|
||||
}
|
||||
else
|
||||
pnode = &node->link;
|
||||
}
|
||||
|
||||
cache->buckets[p] = new_list;
|
||||
|
||||
cache->slack += FTC_HASH_MAX_LOAD;
|
||||
cache->p = p + 1;
|
||||
|
||||
FT_TRACE2(( "ftc_cache_resize: cache %u increased to %u hashes\n",
|
||||
cache->index, cache->p ));
|
||||
}
|
||||
|
||||
/* do we need to shrink the buckets array? */
|
||||
else if ( cache->slack > (FT_Long)p * FTC_HASH_SUB_LOAD )
|
||||
{
|
||||
FTC_Node old_list = cache->buckets[--p];
|
||||
|
||||
|
||||
if ( p < FTC_HASH_INITIAL_SIZE )
|
||||
break;
|
||||
|
||||
if ( p == half )
|
||||
{
|
||||
FT_Memory memory = cache->memory;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
/* if we can't shrink the array, leave immediately */
|
||||
if ( FT_QRENEW_ARRAY( cache->buckets, size, half ) )
|
||||
break;
|
||||
|
||||
cache->mask = half - 1;
|
||||
}
|
||||
|
||||
/* the bucket to merge */
|
||||
pnode = cache->buckets + p - half;
|
||||
|
||||
while ( *pnode )
|
||||
pnode = &(*pnode)->link;
|
||||
|
||||
*pnode = old_list;
|
||||
|
||||
cache->slack -= FTC_HASH_MAX_LOAD;
|
||||
cache->p = p;
|
||||
|
||||
FT_TRACE2(( "ftc_cache_resize: cache %u decreased to %u hashes\n",
|
||||
cache->index, cache->p ));
|
||||
}
|
||||
|
||||
/* otherwise, the hash table is balanced */
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* remove a node from its cache's hash table */
|
||||
static void
|
||||
ftc_node_hash_unlink( FTC_Node node0,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node0->hash );
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
FTC_Node node = *pnode;
|
||||
|
||||
|
||||
if ( !node )
|
||||
{
|
||||
FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" ));
|
||||
return;
|
||||
}
|
||||
|
||||
if ( node == node0 )
|
||||
break;
|
||||
|
||||
pnode = &node->link;
|
||||
}
|
||||
|
||||
*pnode = node0->link;
|
||||
node0->link = NULL;
|
||||
|
||||
cache->slack++;
|
||||
ftc_cache_resize( cache );
|
||||
}
|
||||
|
||||
|
||||
/* add a node to the `top' of its cache's hash table */
|
||||
static void
|
||||
ftc_node_hash_link( FTC_Node node,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node->hash );
|
||||
|
||||
|
||||
node->link = *pnode;
|
||||
*pnode = node;
|
||||
|
||||
cache->slack--;
|
||||
ftc_cache_resize( cache );
|
||||
}
|
||||
|
||||
|
||||
/* remove a node from the cache manager */
|
||||
FT_LOCAL_DEF( void )
|
||||
ftc_node_destroy( FTC_Node node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
FTC_Cache cache;
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
/* find node's cache */
|
||||
if ( node->cache_index >= manager->num_caches )
|
||||
{
|
||||
FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" ));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
cache = manager->caches[node->cache_index];
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
if ( !cache )
|
||||
{
|
||||
FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" ));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
manager->cur_weight -= cache->clazz.node_weight( node, cache );
|
||||
|
||||
/* remove node from mru list */
|
||||
ftc_node_mru_unlink( node, manager );
|
||||
|
||||
/* remove node from cache's hash table */
|
||||
ftc_node_hash_unlink( node, cache );
|
||||
|
||||
/* now finalize it */
|
||||
cache->clazz.node_free( node, cache );
|
||||
|
||||
#if 0
|
||||
/* check, just in case of general corruption :-) */
|
||||
if ( manager->num_nodes == 0 )
|
||||
FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%u)\n",
|
||||
manager->num_nodes ));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** ABSTRACT CACHE CLASS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
ftc_cache_init( FTC_Cache cache )
|
||||
{
|
||||
FT_Memory memory = cache->memory;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
cache->p = FTC_HASH_INITIAL_SIZE;
|
||||
cache->mask = FTC_HASH_INITIAL_SIZE - 1;
|
||||
cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD;
|
||||
|
||||
FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_Cache_Init( FTC_Cache cache )
|
||||
{
|
||||
return ftc_cache_init( cache );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
ftc_cache_done( FTC_Cache cache )
|
||||
{
|
||||
FT_Memory memory = cache->memory;
|
||||
|
||||
|
||||
if ( cache->buckets )
|
||||
{
|
||||
FTC_Manager manager = cache->manager;
|
||||
FT_UFast count = cache->p;
|
||||
FT_UFast i;
|
||||
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
FTC_Node node = cache->buckets[i], next;
|
||||
|
||||
|
||||
while ( node )
|
||||
{
|
||||
next = node->link;
|
||||
node->link = NULL;
|
||||
|
||||
/* remove node from mru list */
|
||||
ftc_node_mru_unlink( node, manager );
|
||||
|
||||
/* now finalize it */
|
||||
manager->cur_weight -= cache->clazz.node_weight( node, cache );
|
||||
|
||||
cache->clazz.node_free( node, cache );
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FT_FREE( cache->buckets );
|
||||
|
||||
cache->p = 0;
|
||||
cache->mask = 0;
|
||||
cache->slack = 0;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_Cache_Done( FTC_Cache cache )
|
||||
{
|
||||
ftc_cache_done( cache );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ftc_cache_add( FTC_Cache cache,
|
||||
FT_Offset hash,
|
||||
FTC_Node node )
|
||||
{
|
||||
node->hash = hash;
|
||||
node->cache_index = (FT_UShort)cache->index;
|
||||
node->ref_count = 0;
|
||||
|
||||
ftc_node_hash_link( node, cache );
|
||||
ftc_node_mru_link( node, cache->manager );
|
||||
|
||||
{
|
||||
FTC_Manager manager = cache->manager;
|
||||
|
||||
|
||||
manager->cur_weight += cache->clazz.node_weight( node, cache );
|
||||
|
||||
if ( manager->cur_weight >= manager->max_weight )
|
||||
{
|
||||
node->ref_count++;
|
||||
FTC_Manager_Compress( manager );
|
||||
node->ref_count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_Cache_NewNode( FTC_Cache cache,
|
||||
FT_Offset hash,
|
||||
FT_Pointer query,
|
||||
FTC_Node *anode )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_Node node;
|
||||
|
||||
|
||||
/*
|
||||
* We use the FTC_CACHE_TRYLOOP macros to support out-of-memory
|
||||
* errors (OOM) correctly, i.e., by flushing the cache progressively
|
||||
* in order to make more room.
|
||||
*/
|
||||
|
||||
FTC_CACHE_TRYLOOP( cache )
|
||||
{
|
||||
error = cache->clazz.node_new( &node, query, cache );
|
||||
}
|
||||
FTC_CACHE_TRYLOOP_END( NULL )
|
||||
|
||||
if ( error )
|
||||
node = NULL;
|
||||
else
|
||||
{
|
||||
/* don't assume that the cache has the same number of buckets, since
|
||||
* our allocation request might have triggered global cache flushing
|
||||
*/
|
||||
ftc_cache_add( cache, hash, node );
|
||||
}
|
||||
|
||||
*anode = node;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#ifndef FTC_INLINE
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_Cache_Lookup( FTC_Cache cache,
|
||||
FT_Offset hash,
|
||||
FT_Pointer query,
|
||||
FTC_Node *anode )
|
||||
{
|
||||
FTC_Node* bucket;
|
||||
FTC_Node* pnode;
|
||||
FTC_Node node;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Bool list_changed = FALSE;
|
||||
|
||||
FTC_Node_CompareFunc compare = cache->clazz.node_compare;
|
||||
|
||||
|
||||
if ( !cache || !anode )
|
||||
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 );
|
||||
|
||||
/* Lookup a node with exactly same hash and queried properties. */
|
||||
/* NOTE: _nodcomp() may change the linked list to reduce memory. */
|
||||
for (;;)
|
||||
{
|
||||
node = *pnode;
|
||||
if ( !node )
|
||||
goto NewNode;
|
||||
|
||||
if ( node->hash == hash &&
|
||||
compare( node, query, cache, &list_changed ) )
|
||||
break;
|
||||
|
||||
pnode = &node->link;
|
||||
}
|
||||
|
||||
if ( list_changed )
|
||||
{
|
||||
/* Update bucket by modified linked list */
|
||||
bucket = pnode = FTC_NODE_TOP_FOR_HASH( cache, hash );
|
||||
|
||||
/* Update pnode by modified linked list */
|
||||
while ( *pnode != node )
|
||||
{
|
||||
if ( !*pnode )
|
||||
{
|
||||
FT_ERROR(( "FTC_Cache_Lookup: oops!!! node missing\n" ));
|
||||
goto NewNode;
|
||||
}
|
||||
else
|
||||
pnode = &(*pnode)->link;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reorder the list to move the found node to the `top' */
|
||||
if ( node != *bucket )
|
||||
{
|
||||
*pnode = node->link;
|
||||
node->link = *bucket;
|
||||
*bucket = node;
|
||||
}
|
||||
|
||||
/* move to head of MRU list */
|
||||
{
|
||||
FTC_Manager manager = cache->manager;
|
||||
|
||||
|
||||
if ( node != manager->nodes_list )
|
||||
ftc_node_mru_up( node, manager );
|
||||
}
|
||||
*anode = node;
|
||||
|
||||
return error;
|
||||
|
||||
NewNode:
|
||||
return FTC_Cache_NewNode( cache, hash, query, anode );
|
||||
}
|
||||
|
||||
#endif /* !FTC_INLINE */
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_Cache_RemoveFaceID( FTC_Cache cache,
|
||||
FTC_FaceID face_id )
|
||||
{
|
||||
FTC_Manager manager = cache->manager;
|
||||
FT_UFast count = cache->p;
|
||||
FT_UFast i;
|
||||
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
FTC_Node* pnode = cache->buckets + i;
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
FTC_Node node = *pnode;
|
||||
|
||||
|
||||
if ( !node )
|
||||
break;
|
||||
|
||||
if ( cache->clazz.node_remove_faceid( node, face_id, cache, NULL ) )
|
||||
{
|
||||
*pnode = node->link;
|
||||
|
||||
manager->cur_weight -= cache->clazz.node_weight( node, cache );
|
||||
ftc_node_mru_unlink( node, manager );
|
||||
|
||||
cache->clazz.node_free( node, cache );
|
||||
|
||||
cache->slack++;
|
||||
}
|
||||
else
|
||||
pnode = &node->link;
|
||||
}
|
||||
}
|
||||
|
||||
ftc_cache_resize( cache );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
359
thirdparty/freetype/src/cache/ftccache.h
vendored
Normal file
359
thirdparty/freetype/src/cache/ftccache.h
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftccache.h
|
||||
*
|
||||
* FreeType internal cache interface (specification).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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 FTCCACHE_H_
|
||||
#define FTCCACHE_H_
|
||||
|
||||
#include <freetype/internal/compiler-macros.h>
|
||||
#include "ftcmru.h"
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
#define FTC_FACE_ID_HASH( i ) \
|
||||
( ( (FT_Offset)(i) >> 3 ) ^ ( (FT_Offset)(i) << 7 ) )
|
||||
|
||||
/* handle to cache object */
|
||||
typedef struct FTC_CacheRec_* FTC_Cache;
|
||||
|
||||
/* handle to cache class */
|
||||
typedef const struct FTC_CacheClassRec_* FTC_CacheClass;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CACHE NODE DEFINITIONS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Each cache controls one or more cache nodes. Each node is part of
|
||||
* the global_lru list of the manager. Its `data' field however is used
|
||||
* as a reference count for now.
|
||||
*
|
||||
* A node can be anything, depending on the type of information held by
|
||||
* the cache. It can be an individual glyph image, a set of bitmaps
|
||||
* glyphs for a given size, some metrics, etc.
|
||||
*
|
||||
*/
|
||||
|
||||
/* structure size should be 20 bytes on 32-bits machines */
|
||||
typedef struct FTC_NodeRec_
|
||||
{
|
||||
FTC_MruNodeRec mru; /* circular mru list pointer */
|
||||
FTC_Node link; /* used for hashing */
|
||||
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 */
|
||||
|
||||
} FTC_NodeRec;
|
||||
|
||||
|
||||
#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 )
|
||||
|
||||
/* address the hash table entries */
|
||||
#ifdef FTC_INLINE
|
||||
#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \
|
||||
( ( cache )->buckets + \
|
||||
( ( ( ( hash ) & ( cache )->mask ) >= ( cache )->p ) \
|
||||
? ( ( hash ) & ( ( cache )->mask >> 1 ) ) \
|
||||
: ( ( hash ) & ( cache )->mask ) ) )
|
||||
#else
|
||||
FT_LOCAL( FTC_Node* )
|
||||
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
|
||||
|
||||
FT_LOCAL( void )
|
||||
ftc_node_destroy( FTC_Node node,
|
||||
FTC_Manager manager );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CACHE DEFINITIONS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* initialize a new cache node */
|
||||
typedef FT_Error
|
||||
(*FTC_Node_NewFunc)( FTC_Node *pnode,
|
||||
FT_Pointer query,
|
||||
FTC_Cache cache );
|
||||
|
||||
typedef FT_Offset
|
||||
(*FTC_Node_WeightFunc)( FTC_Node node,
|
||||
FTC_Cache cache );
|
||||
|
||||
/* compare a node to a given key pair */
|
||||
typedef FT_Bool
|
||||
(*FTC_Node_CompareFunc)( FTC_Node node,
|
||||
FT_Pointer key,
|
||||
FTC_Cache cache,
|
||||
FT_Bool* list_changed );
|
||||
|
||||
|
||||
typedef void
|
||||
(*FTC_Node_FreeFunc)( FTC_Node node,
|
||||
FTC_Cache cache );
|
||||
|
||||
typedef FT_Error
|
||||
(*FTC_Cache_InitFunc)( FTC_Cache cache );
|
||||
|
||||
typedef void
|
||||
(*FTC_Cache_DoneFunc)( FTC_Cache cache );
|
||||
|
||||
|
||||
typedef struct FTC_CacheClassRec_
|
||||
{
|
||||
FTC_Node_NewFunc node_new;
|
||||
FTC_Node_WeightFunc node_weight;
|
||||
FTC_Node_CompareFunc node_compare;
|
||||
FTC_Node_CompareFunc node_remove_faceid;
|
||||
FTC_Node_FreeFunc node_free;
|
||||
|
||||
FT_Offset cache_size;
|
||||
FTC_Cache_InitFunc cache_init;
|
||||
FTC_Cache_DoneFunc cache_done;
|
||||
|
||||
} FTC_CacheClassRec;
|
||||
|
||||
|
||||
/* each cache really implements a hash table to manage its nodes */
|
||||
/* the number of the table entries (buckets) can change dynamically */
|
||||
/* each bucket contains a linked lists of nodes for a given hash */
|
||||
typedef struct FTC_CacheRec_
|
||||
{
|
||||
FT_UFast p; /* hash table counter */
|
||||
FT_UFast mask; /* hash table index range */
|
||||
FT_Long slack;
|
||||
FTC_Node* buckets;
|
||||
|
||||
FTC_CacheClassRec clazz; /* local copy, for speed */
|
||||
|
||||
FTC_Manager manager;
|
||||
FT_Memory memory;
|
||||
FT_UInt index; /* in manager's table */
|
||||
|
||||
FTC_CacheClass org_class; /* original class pointer */
|
||||
|
||||
} FTC_CacheRec;
|
||||
|
||||
|
||||
#define FTC_CACHE( x ) ( (FTC_Cache)(x) )
|
||||
#define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) )
|
||||
|
||||
|
||||
/* default cache initialize */
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_Cache_Init( FTC_Cache cache );
|
||||
|
||||
/* default cache finalizer */
|
||||
FT_LOCAL( void )
|
||||
FTC_Cache_Done( FTC_Cache cache );
|
||||
|
||||
/* Call this function to look up the cache. If no corresponding
|
||||
* node is found, a new one is automatically created. This function
|
||||
* is capable of flushing the cache adequately to make room for the
|
||||
* new cache object.
|
||||
*/
|
||||
|
||||
#ifndef FTC_INLINE
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_Cache_Lookup( FTC_Cache cache,
|
||||
FT_Offset hash,
|
||||
FT_Pointer query,
|
||||
FTC_Node *anode );
|
||||
#endif
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_Cache_NewNode( FTC_Cache cache,
|
||||
FT_Offset hash,
|
||||
FT_Pointer query,
|
||||
FTC_Node *anode );
|
||||
|
||||
/* Remove all nodes that relate to a given face_id. This is useful
|
||||
* when un-installing fonts. Note that if a cache node relates to
|
||||
* the face_id but is locked (i.e., has `ref_count > 0'), the node
|
||||
* will _not_ be destroyed, but its internal face_id reference will
|
||||
* be modified.
|
||||
*
|
||||
* The final result will be that the node will never come back
|
||||
* in further lookup requests, and will be flushed on demand from
|
||||
* the cache normally when its reference count reaches 0.
|
||||
*/
|
||||
FT_LOCAL( void )
|
||||
FTC_Cache_RemoveFaceID( FTC_Cache cache,
|
||||
FTC_FaceID face_id );
|
||||
|
||||
|
||||
#ifdef FTC_INLINE
|
||||
|
||||
#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \
|
||||
FT_BEGIN_STMNT \
|
||||
FTC_Node *_bucket, *_pnode, _node; \
|
||||
FTC_Cache _cache = FTC_CACHE( cache ); \
|
||||
FT_Offset _hash = (FT_Offset)(hash); \
|
||||
FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \
|
||||
FT_Bool _list_changed = FALSE; \
|
||||
\
|
||||
\
|
||||
error = FT_Err_Ok; \
|
||||
node = NULL; \
|
||||
\
|
||||
/* Go to the `top' node of the list sharing same masked 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. */ \
|
||||
for (;;) \
|
||||
{ \
|
||||
_node = *_pnode; \
|
||||
if ( !_node ) \
|
||||
goto NewNode_; \
|
||||
\
|
||||
if ( _node->hash == _hash && \
|
||||
_nodcomp( _node, query, _cache, &_list_changed ) ) \
|
||||
break; \
|
||||
\
|
||||
_pnode = &_node->link; \
|
||||
} \
|
||||
\
|
||||
if ( _list_changed ) \
|
||||
{ \
|
||||
/* Update _bucket by possibly modified linked list */ \
|
||||
_bucket = _pnode = FTC_NODE_TOP_FOR_HASH( _cache, _hash ); \
|
||||
\
|
||||
/* Update _pnode by possibly modified linked list */ \
|
||||
while ( *_pnode != _node ) \
|
||||
{ \
|
||||
if ( !*_pnode ) \
|
||||
{ \
|
||||
FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" )); \
|
||||
goto NewNode_; \
|
||||
} \
|
||||
else \
|
||||
_pnode = &(*_pnode)->link; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
/* Reorder the list to move the found node to the `top' */ \
|
||||
if ( _node != *_bucket ) \
|
||||
{ \
|
||||
*_pnode = _node->link; \
|
||||
_node->link = *_bucket; \
|
||||
*_bucket = _node; \
|
||||
} \
|
||||
\
|
||||
/* Update MRU list */ \
|
||||
{ \
|
||||
FTC_Manager _manager = _cache->manager; \
|
||||
void* _nl = &_manager->nodes_list; \
|
||||
\
|
||||
\
|
||||
if ( _node != _manager->nodes_list ) \
|
||||
FTC_MruNode_Up( (FTC_MruNode*)_nl, \
|
||||
(FTC_MruNode)_node ); \
|
||||
} \
|
||||
goto Ok_; \
|
||||
\
|
||||
NewNode_: \
|
||||
error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \
|
||||
\
|
||||
Ok_: \
|
||||
node = _node; \
|
||||
FT_END_STMNT
|
||||
|
||||
#else /* !FTC_INLINE */
|
||||
|
||||
#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \
|
||||
FT_BEGIN_STMNT \
|
||||
error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, \
|
||||
(FTC_Node*)&(node) ); \
|
||||
FT_END_STMNT
|
||||
|
||||
#endif /* !FTC_INLINE */
|
||||
|
||||
|
||||
/*
|
||||
* This macro, together with FTC_CACHE_TRYLOOP_END, defines a retry
|
||||
* loop to flush the cache repeatedly in case of memory overflows.
|
||||
*
|
||||
* It is used when creating a new cache node, or within a lookup
|
||||
* that needs to allocate data (e.g. the sbit cache lookup).
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {
|
||||
* FTC_CACHE_TRYLOOP( cache )
|
||||
* error = load_data( ... );
|
||||
* FTC_CACHE_TRYLOOP_END()
|
||||
* }
|
||||
*
|
||||
*/
|
||||
#define FTC_CACHE_TRYLOOP( cache ) \
|
||||
{ \
|
||||
FTC_Manager _try_manager = FTC_CACHE( cache )->manager; \
|
||||
FT_UInt _try_count = 4; \
|
||||
\
|
||||
\
|
||||
for (;;) \
|
||||
{ \
|
||||
FT_UInt _try_done;
|
||||
|
||||
|
||||
#define FTC_CACHE_TRYLOOP_END( list_changed ) \
|
||||
if ( !error || FT_ERR_NEQ( error, Out_Of_Memory ) ) \
|
||||
break; \
|
||||
\
|
||||
_try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \
|
||||
if ( _try_done > 0 && list_changed != NULL ) \
|
||||
*(FT_Bool*)( list_changed ) = TRUE; \
|
||||
\
|
||||
if ( _try_done == 0 ) \
|
||||
break; \
|
||||
\
|
||||
if ( _try_done == _try_count ) \
|
||||
{ \
|
||||
_try_count *= 2; \
|
||||
if ( _try_count < _try_done || \
|
||||
_try_count > _try_manager->num_nodes ) \
|
||||
_try_count = _try_manager->num_nodes; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* FTCCACHE_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
85
thirdparty/freetype/src/cache/ftccback.h
vendored
Normal file
85
thirdparty/freetype/src/cache/ftccback.h
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftccback.h
|
||||
*
|
||||
* Callback functions of the caching sub-system (specification only).
|
||||
*
|
||||
* Copyright (C) 2004-2024 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 FTCCBACK_H_
|
||||
#define FTCCBACK_H_
|
||||
|
||||
#include <freetype/ftcache.h>
|
||||
#include "ftccache.h"
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
FT_LOCAL( void )
|
||||
ftc_inode_free( FTC_Node inode,
|
||||
FTC_Cache cache );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
ftc_inode_new( FTC_Node *pinode,
|
||||
FT_Pointer gquery,
|
||||
FTC_Cache cache );
|
||||
|
||||
FT_LOCAL( FT_Offset )
|
||||
ftc_inode_weight( FTC_Node inode,
|
||||
FTC_Cache cache );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
ftc_snode_free( FTC_Node snode,
|
||||
FTC_Cache cache );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
ftc_snode_new( FTC_Node *psnode,
|
||||
FT_Pointer gquery,
|
||||
FTC_Cache cache );
|
||||
|
||||
FT_LOCAL( FT_Offset )
|
||||
ftc_snode_weight( FTC_Node snode,
|
||||
FTC_Cache cache );
|
||||
|
||||
FT_LOCAL( FT_Bool )
|
||||
ftc_snode_compare( FTC_Node snode,
|
||||
FT_Pointer gquery,
|
||||
FTC_Cache cache,
|
||||
FT_Bool* list_changed );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Bool )
|
||||
ftc_gnode_compare( FTC_Node gnode,
|
||||
FT_Pointer gquery,
|
||||
FTC_Cache cache,
|
||||
FT_Bool* list_changed );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
ftc_gcache_init( FTC_Cache cache );
|
||||
|
||||
FT_LOCAL( void )
|
||||
ftc_gcache_done( FTC_Cache cache );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
ftc_cache_init( FTC_Cache cache );
|
||||
|
||||
FT_LOCAL( void )
|
||||
ftc_cache_done( FTC_Cache cache );
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* FTCCBACK_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
323
thirdparty/freetype/src/cache/ftccmap.c
vendored
Normal file
323
thirdparty/freetype/src/cache/ftccmap.c
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftccmap.c
|
||||
*
|
||||
* FreeType CharMap cache (body)
|
||||
*
|
||||
* Copyright (C) 2000-2024 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 <freetype/freetype.h>
|
||||
#include <freetype/ftcache.h>
|
||||
#include "ftcmanag.h"
|
||||
#include <freetype/internal/ftmemory.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
|
||||
#include "ftccback.h"
|
||||
#include "ftcerror.h"
|
||||
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT cache
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Each FTC_CMapNode contains a simple array to map a range of character
|
||||
* codes to equivalent glyph indices.
|
||||
*
|
||||
* For now, the implementation is very basic: Each node maps a range of
|
||||
* 128 consecutive character codes to their corresponding glyph indices.
|
||||
*
|
||||
* We could do more complex things, but I don't think it is really very
|
||||
* useful.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* number of glyph indices / character code per node */
|
||||
#define FTC_CMAP_INDICES_MAX 128
|
||||
|
||||
/* compute a query/node hash */
|
||||
#define FTC_CMAP_HASH( faceid, index, charcode ) \
|
||||
( FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \
|
||||
( (charcode) / FTC_CMAP_INDICES_MAX ) )
|
||||
|
||||
/* the charmap query */
|
||||
typedef struct FTC_CMapQueryRec_
|
||||
{
|
||||
FTC_FaceID face_id;
|
||||
FT_UInt cmap_index;
|
||||
FT_UInt32 char_code;
|
||||
|
||||
} FTC_CMapQueryRec, *FTC_CMapQuery;
|
||||
|
||||
#define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x))
|
||||
|
||||
/* the cmap cache node */
|
||||
typedef struct FTC_CMapNodeRec_
|
||||
{
|
||||
FTC_NodeRec node;
|
||||
FTC_FaceID face_id;
|
||||
FT_UInt cmap_index;
|
||||
FT_UInt32 first; /* first character in node */
|
||||
FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */
|
||||
|
||||
} FTC_CMapNodeRec, *FTC_CMapNode;
|
||||
|
||||
#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
|
||||
|
||||
/* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
|
||||
/* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */
|
||||
#define FTC_CMAP_UNKNOWN (FT_UInt16)~0
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CHARMAP NODES *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ftc_cmap_node_free( FTC_Node ftcnode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_CMapNode node = (FTC_CMapNode)ftcnode;
|
||||
FT_Memory memory = cache->memory;
|
||||
|
||||
|
||||
FT_FREE( node );
|
||||
}
|
||||
|
||||
|
||||
/* initialize a new cmap node */
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_cmap_node_new( FTC_Node *ftcanode,
|
||||
FT_Pointer ftcquery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode;
|
||||
FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
|
||||
FT_Error error;
|
||||
FT_Memory memory = cache->memory;
|
||||
FTC_CMapNode node = NULL;
|
||||
FT_UInt nn;
|
||||
|
||||
|
||||
if ( !FT_QNEW( node ) )
|
||||
{
|
||||
node->face_id = query->face_id;
|
||||
node->cmap_index = query->cmap_index;
|
||||
node->first = (query->char_code / FTC_CMAP_INDICES_MAX) *
|
||||
FTC_CMAP_INDICES_MAX;
|
||||
|
||||
for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )
|
||||
node->indices[nn] = FTC_CMAP_UNKNOWN;
|
||||
}
|
||||
|
||||
*anode = node;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* compute the weight of a given cmap node */
|
||||
FT_CALLBACK_DEF( FT_Offset )
|
||||
ftc_cmap_node_weight( FTC_Node cnode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FT_UNUSED( cnode );
|
||||
FT_UNUSED( cache );
|
||||
|
||||
return sizeof ( *cnode );
|
||||
}
|
||||
|
||||
|
||||
/* compare a cmap node to a given query */
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_cmap_node_compare( FTC_Node ftcnode,
|
||||
FT_Pointer ftcquery,
|
||||
FTC_Cache cache,
|
||||
FT_Bool* list_changed )
|
||||
{
|
||||
FTC_CMapNode node = (FTC_CMapNode)ftcnode;
|
||||
FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
|
||||
FT_UNUSED( cache );
|
||||
|
||||
|
||||
if ( list_changed )
|
||||
*list_changed = FALSE;
|
||||
if ( node->face_id == query->face_id &&
|
||||
node->cmap_index == query->cmap_index )
|
||||
{
|
||||
FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first );
|
||||
|
||||
|
||||
return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_cmap_node_remove_faceid( FTC_Node ftcnode,
|
||||
FT_Pointer ftcface_id,
|
||||
FTC_Cache cache,
|
||||
FT_Bool* list_changed )
|
||||
{
|
||||
FTC_CMapNode node = (FTC_CMapNode)ftcnode;
|
||||
FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
|
||||
FT_UNUSED( cache );
|
||||
|
||||
|
||||
if ( list_changed )
|
||||
*list_changed = FALSE;
|
||||
return FT_BOOL( node->face_id == face_id );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** GLYPH IMAGE CACHE *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
static
|
||||
const FTC_CacheClassRec ftc_cmap_cache_class =
|
||||
{
|
||||
ftc_cmap_node_new, /* FTC_Node_NewFunc node_new */
|
||||
ftc_cmap_node_weight, /* FTC_Node_WeightFunc node_weight */
|
||||
ftc_cmap_node_compare, /* FTC_Node_CompareFunc node_compare */
|
||||
ftc_cmap_node_remove_faceid, /* FTC_Node_CompareFunc node_remove_faceid */
|
||||
ftc_cmap_node_free, /* FTC_Node_FreeFunc node_free */
|
||||
|
||||
sizeof ( FTC_CacheRec ),
|
||||
ftc_cache_init, /* FTC_Cache_InitFunc cache_init */
|
||||
ftc_cache_done, /* FTC_Cache_DoneFunc cache_done */
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_CMapCache_New( FTC_Manager manager,
|
||||
FTC_CMapCache *acache )
|
||||
{
|
||||
return FTC_Manager_RegisterCache( manager,
|
||||
&ftc_cmap_cache_class,
|
||||
FTC_CACHE_P( acache ) );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_UInt )
|
||||
FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache,
|
||||
FTC_FaceID face_id,
|
||||
FT_Int cmap_index,
|
||||
FT_UInt32 char_code )
|
||||
{
|
||||
FTC_Cache cache = FTC_CACHE( cmap_cache );
|
||||
FTC_CMapQueryRec query;
|
||||
FTC_Node node;
|
||||
FT_Error error;
|
||||
FT_UInt gindex = 0;
|
||||
FT_Offset hash;
|
||||
FT_Int no_cmap_change = 0;
|
||||
|
||||
|
||||
if ( cmap_index < 0 )
|
||||
{
|
||||
/* Treat a negative cmap index as a special value, meaning that you */
|
||||
/* don't want to change the FT_Face's character map through this */
|
||||
/* call. This can be useful if the face requester callback already */
|
||||
/* sets the face's charmap to the appropriate value. */
|
||||
|
||||
no_cmap_change = 1;
|
||||
cmap_index = 0;
|
||||
}
|
||||
|
||||
if ( !cache )
|
||||
{
|
||||
FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" ));
|
||||
return 0;
|
||||
}
|
||||
|
||||
query.face_id = face_id;
|
||||
query.cmap_index = (FT_UInt)cmap_index;
|
||||
query.char_code = char_code;
|
||||
|
||||
hash = FTC_CMAP_HASH( face_id, (FT_UInt)cmap_index, char_code );
|
||||
|
||||
#ifdef FTC_INLINE
|
||||
FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
|
||||
node, error );
|
||||
#else
|
||||
error = FTC_Cache_Lookup( cache, hash, &query, &node );
|
||||
#endif
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
FT_ASSERT( char_code - FTC_CMAP_NODE( node )->first <
|
||||
FTC_CMAP_INDICES_MAX );
|
||||
|
||||
/* something rotten can happen with rogue clients */
|
||||
if ( char_code - FTC_CMAP_NODE( node )->first >= FTC_CMAP_INDICES_MAX )
|
||||
return 0; /* XXX: should return appropriate error */
|
||||
|
||||
gindex = FTC_CMAP_NODE( node )->indices[char_code -
|
||||
FTC_CMAP_NODE( node )->first];
|
||||
if ( gindex == FTC_CMAP_UNKNOWN )
|
||||
{
|
||||
FT_Face face;
|
||||
|
||||
|
||||
gindex = 0;
|
||||
|
||||
error = FTC_Manager_LookupFace( cache->manager,
|
||||
FTC_CMAP_NODE( node )->face_id,
|
||||
&face );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
if ( cmap_index < face->num_charmaps )
|
||||
{
|
||||
FT_CharMap old = face->charmap;
|
||||
FT_CharMap cmap = face->charmaps[cmap_index];
|
||||
|
||||
|
||||
if ( !no_cmap_change )
|
||||
face->charmap = cmap;
|
||||
|
||||
gindex = FT_Get_Char_Index( face, char_code );
|
||||
|
||||
if ( !no_cmap_change )
|
||||
face->charmap = old;
|
||||
}
|
||||
|
||||
FTC_CMAP_NODE( node )->indices[char_code -
|
||||
FTC_CMAP_NODE( node )->first]
|
||||
= (FT_UShort)gindex;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return gindex;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
42
thirdparty/freetype/src/cache/ftcerror.h
vendored
Normal file
42
thirdparty/freetype/src/cache/ftcerror.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcerror.h
|
||||
*
|
||||
* Caching sub-system error codes (specification only).
|
||||
*
|
||||
* Copyright (C) 2001-2024 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 is used to define the caching sub-system error enumeration
|
||||
* constants.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FTCERROR_H_
|
||||
#define FTCERROR_H_
|
||||
|
||||
#include <freetype/ftmoderr.h>
|
||||
|
||||
#undef FTERRORS_H_
|
||||
|
||||
#undef FT_ERR_PREFIX
|
||||
#define FT_ERR_PREFIX FTC_Err_
|
||||
#define FT_ERR_BASE FT_Mod_Err_Cache
|
||||
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
#endif /* FTCERROR_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
204
thirdparty/freetype/src/cache/ftcglyph.c
vendored
Normal file
204
thirdparty/freetype/src/cache/ftcglyph.c
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcglyph.c
|
||||
*
|
||||
* FreeType Glyph Image (FT_Glyph) cache (body).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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 <freetype/internal/ftobjs.h>
|
||||
#include <freetype/ftcache.h>
|
||||
#include "ftcglyph.h"
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
#include "ftccback.h"
|
||||
#include "ftcerror.h"
|
||||
|
||||
|
||||
/* create a new chunk node, setting its cache index and ref count */
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_GNode_Init( FTC_GNode gnode,
|
||||
FT_UInt gindex,
|
||||
FTC_Family family )
|
||||
{
|
||||
gnode->family = family;
|
||||
gnode->gindex = gindex;
|
||||
family->num_nodes++;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_GNode_UnselectFamily( FTC_GNode gnode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_Family family = gnode->family;
|
||||
|
||||
|
||||
gnode->family = NULL;
|
||||
if ( family && --family->num_nodes == 0 )
|
||||
FTC_FAMILY_FREE( family, cache );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_GNode_Done( FTC_GNode gnode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
/* finalize the node */
|
||||
gnode->gindex = 0;
|
||||
|
||||
FTC_GNode_UnselectFamily( gnode, cache );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Bool )
|
||||
ftc_gnode_compare( FTC_Node ftcgnode,
|
||||
FT_Pointer ftcgquery,
|
||||
FTC_Cache cache,
|
||||
FT_Bool* list_changed )
|
||||
{
|
||||
FTC_GNode gnode = (FTC_GNode)ftcgnode;
|
||||
FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
|
||||
FT_UNUSED( cache );
|
||||
|
||||
|
||||
if ( list_changed )
|
||||
*list_changed = FALSE;
|
||||
return FT_BOOL( gnode->family == gquery->family &&
|
||||
gnode->gindex == gquery->gindex );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CHUNK SETS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_Family_Init( FTC_Family family,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_GCacheClass clazz = FTC_CACHE_GCACHE_CLASS( cache );
|
||||
|
||||
|
||||
family->clazz = clazz->family_class;
|
||||
family->num_nodes = 0;
|
||||
family->cache = cache;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
ftc_gcache_init( FTC_Cache cache )
|
||||
{
|
||||
FTC_GCache gcache = (FTC_GCache)cache;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
error = FTC_Cache_Init( cache );
|
||||
if ( !error )
|
||||
{
|
||||
FTC_GCacheClass clazz = (FTC_GCacheClass)cache->org_class;
|
||||
|
||||
FTC_MruList_Init( &gcache->families,
|
||||
clazz->family_class,
|
||||
0, /* no maximum here! */
|
||||
cache,
|
||||
cache->memory );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_GCache_Init( FTC_GCache gcache )
|
||||
{
|
||||
return ftc_gcache_init( FTC_CACHE( gcache ) );
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
ftc_gcache_done( FTC_Cache cache )
|
||||
{
|
||||
FTC_GCache gcache = (FTC_GCache)cache;
|
||||
|
||||
|
||||
FTC_Cache_Done( cache );
|
||||
FTC_MruList_Done( &gcache->families );
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_GCache_Done( FTC_GCache gcache )
|
||||
{
|
||||
ftc_gcache_done( FTC_CACHE( gcache ) );
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_GCache_New( FTC_Manager manager,
|
||||
FTC_GCacheClass clazz,
|
||||
FTC_GCache *acache )
|
||||
{
|
||||
return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz,
|
||||
(FTC_Cache*)acache );
|
||||
}
|
||||
|
||||
|
||||
#ifndef FTC_INLINE
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_GCache_Lookup( FTC_GCache gcache,
|
||||
FT_Offset hash,
|
||||
FT_UInt gindex,
|
||||
FTC_GQuery query,
|
||||
FTC_Node *anode )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
query->gindex = gindex;
|
||||
|
||||
FTC_MRULIST_LOOKUP( &gcache->families, query, query->family, error );
|
||||
if ( !error )
|
||||
{
|
||||
FTC_Family family = query->family;
|
||||
|
||||
|
||||
/* prevent the family from being destroyed too early when an */
|
||||
/* out-of-memory condition occurs during glyph node initialization. */
|
||||
family->num_nodes++;
|
||||
|
||||
error = FTC_Cache_Lookup( FTC_CACHE( gcache ), hash, query, anode );
|
||||
|
||||
if ( --family->num_nodes == 0 )
|
||||
FTC_FAMILY_FREE( family, FTC_CACHE( gcache ) );
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif /* !FTC_INLINE */
|
||||
|
||||
|
||||
/* END */
|
||||
314
thirdparty/freetype/src/cache/ftcglyph.h
vendored
Normal file
314
thirdparty/freetype/src/cache/ftcglyph.h
vendored
Normal file
@@ -0,0 +1,314 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcglyph.h
|
||||
*
|
||||
* FreeType abstract glyph cache (specification).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* FTC_GCache is an _abstract_ cache object optimized to store glyph
|
||||
* data. It works as follows:
|
||||
*
|
||||
* - It manages FTC_GNode objects. Each one of them can hold one or more
|
||||
* glyph `items'. Item types are not specified in the FTC_GCache but
|
||||
* in classes that extend it.
|
||||
*
|
||||
* - Glyph attributes, like face ID, character size, render mode, etc.,
|
||||
* can be grouped into abstract `glyph families'. This avoids storing
|
||||
* the attributes within the FTC_GCache, since it is likely that many
|
||||
* FTC_GNodes will belong to the same family in typical uses.
|
||||
*
|
||||
* - Each FTC_GNode is thus an FTC_Node with two additional fields:
|
||||
*
|
||||
* * gindex: A glyph index, or the first index in a glyph range.
|
||||
* * family: A pointer to a glyph `family'.
|
||||
*
|
||||
* - Family types are not fully specific in the FTC_Family type, but
|
||||
* by classes that extend it.
|
||||
*
|
||||
* Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache.
|
||||
* They share an FTC_Family sub-class called FTC_BasicFamily which is
|
||||
* used to store the following data: face ID, pixel/point sizes, load
|
||||
* flags. For more details see the file `src/cache/ftcbasic.c'.
|
||||
*
|
||||
* Client applications can extend FTC_GNode with their own FTC_GNode
|
||||
* and FTC_Family sub-classes to implement more complex caches (e.g.,
|
||||
* handling automatic synthesis, like obliquing & emboldening, colored
|
||||
* glyphs, etc.).
|
||||
*
|
||||
* See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and
|
||||
* `ftcsbits.h', which both extend FTC_GCache with additional
|
||||
* optimizations.
|
||||
*
|
||||
* A typical FTC_GCache implementation must provide at least the
|
||||
* following:
|
||||
*
|
||||
* - FTC_GNode sub-class, e.g. MyNode, with relevant methods:
|
||||
* my_node_new (must call FTC_GNode_Init)
|
||||
* my_node_free (must call FTC_GNode_Done)
|
||||
* my_node_compare (must call ftc_gnode_compare)
|
||||
* my_node_remove_faceid (must call ftc_gnode_unselect in case
|
||||
* of match)
|
||||
*
|
||||
* - FTC_Family sub-class, e.g. MyFamily, with relevant methods:
|
||||
* my_family_compare
|
||||
* my_family_init
|
||||
* my_family_done
|
||||
*
|
||||
* - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query
|
||||
* data.
|
||||
*
|
||||
* - Constant structures for a FTC_GNodeClass.
|
||||
*
|
||||
* - MyCacheNew() can be implemented easily as a call to the convenience
|
||||
* function FTC_GCache_New.
|
||||
*
|
||||
* - MyCacheLookup with a call to FTC_GCache_Lookup. This function will
|
||||
* automatically:
|
||||
*
|
||||
* - Search for the corresponding family in the cache, or create
|
||||
* a new one if necessary. Put it in FTC_GQUERY(myquery).family
|
||||
*
|
||||
* - Call FTC_Cache_Lookup.
|
||||
*
|
||||
* If it returns NULL, you should create a new node, then call
|
||||
* ftc_cache_add as usual.
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Important: The functions defined in this file are only used to
|
||||
* implement an abstract glyph cache class. You need to
|
||||
* provide additional logic to implement a complete cache.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/********* *********/
|
||||
/********* WARNING, THIS IS BETA CODE. *********/
|
||||
/********* *********/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#ifndef FTCGLYPH_H_
|
||||
#define FTCGLYPH_H_
|
||||
|
||||
|
||||
#include "ftcmanag.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/*
|
||||
* We can group glyphs into `families'. Each family correspond to a
|
||||
* given face ID, character size, transform, etc.
|
||||
*
|
||||
* Families are implemented as MRU list nodes. They are
|
||||
* reference-counted.
|
||||
*/
|
||||
|
||||
typedef struct FTC_FamilyRec_
|
||||
{
|
||||
FTC_MruNodeRec mrunode;
|
||||
FT_UInt num_nodes; /* current number of nodes in this family */
|
||||
FTC_Cache cache;
|
||||
FTC_MruListClass clazz;
|
||||
|
||||
} FTC_FamilyRec, *FTC_Family;
|
||||
|
||||
#define FTC_FAMILY( x ) ( (FTC_Family)(x) )
|
||||
#define FTC_FAMILY_P( x ) ( (FTC_Family*)(x) )
|
||||
|
||||
|
||||
typedef struct FTC_GNodeRec_
|
||||
{
|
||||
FTC_NodeRec node;
|
||||
FTC_Family family;
|
||||
FT_UInt gindex;
|
||||
|
||||
} FTC_GNodeRec, *FTC_GNode;
|
||||
|
||||
#define FTC_GNODE( x ) ( (FTC_GNode)(x) )
|
||||
#define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) )
|
||||
|
||||
|
||||
typedef struct FTC_GQueryRec_
|
||||
{
|
||||
FT_UInt gindex;
|
||||
FTC_Family family;
|
||||
|
||||
} FTC_GQueryRec, *FTC_GQuery;
|
||||
|
||||
#define FTC_GQUERY( x ) ( (FTC_GQuery)(x) )
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* These functions are exported so that they can be called from
|
||||
* user-provided cache classes; otherwise, they are really part of the
|
||||
* cache sub-system internals.
|
||||
*/
|
||||
|
||||
/* must be called by derived FTC_Node_InitFunc routines */
|
||||
FT_LOCAL( void )
|
||||
FTC_GNode_Init( FTC_GNode node,
|
||||
FT_UInt gindex, /* glyph index for node */
|
||||
FTC_Family family );
|
||||
|
||||
/* call this function to clear a node's family -- this is necessary */
|
||||
/* to implement the `node_remove_faceid' cache method correctly */
|
||||
FT_LOCAL( void )
|
||||
FTC_GNode_UnselectFamily( FTC_GNode gnode,
|
||||
FTC_Cache cache );
|
||||
|
||||
/* must be called by derived FTC_Node_DoneFunc routines */
|
||||
FT_LOCAL( void )
|
||||
FTC_GNode_Done( FTC_GNode node,
|
||||
FTC_Cache cache );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
FTC_Family_Init( FTC_Family family,
|
||||
FTC_Cache cache );
|
||||
|
||||
typedef struct FTC_GCacheRec_
|
||||
{
|
||||
FTC_CacheRec cache;
|
||||
FTC_MruListRec families;
|
||||
|
||||
} FTC_GCacheRec, *FTC_GCache;
|
||||
|
||||
#define FTC_GCACHE( x ) ((FTC_GCache)(x))
|
||||
|
||||
|
||||
#if 0
|
||||
/* can be used as @FTC_Cache_InitFunc */
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_GCache_Init( FTC_GCache cache );
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* can be used as @FTC_Cache_DoneFunc */
|
||||
FT_LOCAL( void )
|
||||
FTC_GCache_Done( FTC_GCache cache );
|
||||
#endif
|
||||
|
||||
|
||||
/* the glyph cache class adds fields for the family implementation */
|
||||
typedef struct FTC_GCacheClassRec_
|
||||
{
|
||||
FTC_CacheClassRec clazz;
|
||||
FTC_MruListClass family_class;
|
||||
|
||||
} FTC_GCacheClassRec;
|
||||
|
||||
typedef const FTC_GCacheClassRec* FTC_GCacheClass;
|
||||
|
||||
#define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(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 )
|
||||
|
||||
|
||||
/* convenience function; use it instead of FTC_Manager_Register_Cache */
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_GCache_New( FTC_Manager manager,
|
||||
FTC_GCacheClass clazz,
|
||||
FTC_GCache *acache );
|
||||
|
||||
#ifndef FTC_INLINE
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_GCache_Lookup( FTC_GCache cache,
|
||||
FT_Offset hash,
|
||||
FT_UInt gindex,
|
||||
FTC_GQuery query,
|
||||
FTC_Node *anode );
|
||||
#endif
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
#define FTC_FAMILY_FREE( family, cache ) \
|
||||
FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \
|
||||
(FTC_MruNode)(family) )
|
||||
|
||||
|
||||
#ifdef FTC_INLINE
|
||||
|
||||
#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \
|
||||
gindex, query, node, error ) \
|
||||
FT_BEGIN_STMNT \
|
||||
FTC_GCache _gcache = FTC_GCACHE( cache ); \
|
||||
FTC_GQuery _gquery = (FTC_GQuery)( query ); \
|
||||
FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \
|
||||
FTC_MruNode _mrunode; \
|
||||
\
|
||||
\
|
||||
_gquery->gindex = (gindex); \
|
||||
\
|
||||
FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \
|
||||
_mrunode, error ); \
|
||||
_gquery->family = FTC_FAMILY( _mrunode ); \
|
||||
if ( !error ) \
|
||||
{ \
|
||||
FTC_Family _gqfamily = _gquery->family; \
|
||||
\
|
||||
\
|
||||
_gqfamily->num_nodes++; \
|
||||
\
|
||||
FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \
|
||||
\
|
||||
if ( --_gqfamily->num_nodes == 0 ) \
|
||||
FTC_FAMILY_FREE( _gqfamily, _gcache ); \
|
||||
} \
|
||||
FT_END_STMNT
|
||||
/* */
|
||||
|
||||
#else /* !FTC_INLINE */
|
||||
|
||||
#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \
|
||||
gindex, query, node, error ) \
|
||||
FT_BEGIN_STMNT \
|
||||
\
|
||||
error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \
|
||||
FTC_GQUERY( query ), &node ); \
|
||||
\
|
||||
FT_END_STMNT
|
||||
|
||||
#endif /* !FTC_INLINE */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* FTCGLYPH_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
158
thirdparty/freetype/src/cache/ftcimage.c
vendored
Normal file
158
thirdparty/freetype/src/cache/ftcimage.c
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcimage.c
|
||||
*
|
||||
* FreeType Image cache (body).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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 <freetype/ftcache.h>
|
||||
#include "ftcimage.h"
|
||||
#include <freetype/internal/ftmemory.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
|
||||
#include "ftccback.h"
|
||||
#include "ftcerror.h"
|
||||
|
||||
|
||||
/* finalize a given glyph image node */
|
||||
FT_LOCAL_DEF( void )
|
||||
ftc_inode_free( FTC_Node ftcinode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_INode inode = (FTC_INode)ftcinode;
|
||||
FT_Memory memory = cache->memory;
|
||||
|
||||
|
||||
FT_Done_Glyph( inode->glyph );
|
||||
|
||||
FTC_GNode_Done( FTC_GNODE( inode ), cache );
|
||||
FT_FREE( inode );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_INode_Free( FTC_INode inode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
ftc_inode_free( FTC_NODE( inode ), cache );
|
||||
}
|
||||
|
||||
|
||||
/* initialize a new glyph image node */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_INode_New( FTC_INode *pinode,
|
||||
FTC_GQuery gquery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FT_Memory memory = cache->memory;
|
||||
FT_Error error;
|
||||
FTC_INode inode = NULL;
|
||||
|
||||
|
||||
if ( !FT_QNEW( inode ) )
|
||||
{
|
||||
FTC_GNode gnode = FTC_GNODE( inode );
|
||||
FTC_Family family = gquery->family;
|
||||
FT_UInt gindex = gquery->gindex;
|
||||
FTC_IFamilyClass clazz = FTC_CACHE_IFAMILY_CLASS( cache );
|
||||
|
||||
|
||||
/* initialize its inner fields */
|
||||
FTC_GNode_Init( gnode, gindex, family );
|
||||
inode->glyph = NULL;
|
||||
|
||||
/* we will now load the glyph image */
|
||||
error = clazz->family_load_glyph( family, gindex, cache,
|
||||
&inode->glyph );
|
||||
if ( error )
|
||||
{
|
||||
FTC_INode_Free( inode, cache );
|
||||
inode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*pinode = inode;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
ftc_inode_new( FTC_Node *ftcpinode,
|
||||
FT_Pointer ftcgquery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_INode *pinode = (FTC_INode*)ftcpinode;
|
||||
FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
|
||||
|
||||
|
||||
return FTC_INode_New( pinode, gquery, cache );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Offset )
|
||||
ftc_inode_weight( FTC_Node ftcinode,
|
||||
FTC_Cache ftccache )
|
||||
{
|
||||
FTC_INode inode = (FTC_INode)ftcinode;
|
||||
FT_Offset size = 0;
|
||||
FT_Glyph glyph = inode->glyph;
|
||||
|
||||
FT_UNUSED( ftccache );
|
||||
|
||||
|
||||
switch ( glyph->format )
|
||||
{
|
||||
case FT_GLYPH_FORMAT_BITMAP:
|
||||
{
|
||||
FT_BitmapGlyph bitg = (FT_BitmapGlyph)glyph;
|
||||
|
||||
|
||||
size = bitg->bitmap.rows * (FT_Offset)FT_ABS( bitg->bitmap.pitch ) +
|
||||
sizeof ( *bitg );
|
||||
}
|
||||
break;
|
||||
|
||||
case FT_GLYPH_FORMAT_OUTLINE:
|
||||
{
|
||||
FT_OutlineGlyph outg = (FT_OutlineGlyph)glyph;
|
||||
|
||||
|
||||
size = (FT_Offset)outg->outline.n_points *
|
||||
( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) +
|
||||
(FT_Offset)outg->outline.n_contours * sizeof ( FT_Short ) +
|
||||
sizeof ( *outg );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
size += sizeof ( *inode );
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
FT_LOCAL_DEF( FT_Offset )
|
||||
FTC_INode_Weight( FTC_INode inode )
|
||||
{
|
||||
return ftc_inode_weight( FTC_NODE( inode ), NULL );
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
/* END */
|
||||
106
thirdparty/freetype/src/cache/ftcimage.h
vendored
Normal file
106
thirdparty/freetype/src/cache/ftcimage.h
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcimage.h
|
||||
*
|
||||
* FreeType Generic Image cache (specification)
|
||||
*
|
||||
* Copyright (C) 2000-2024 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* FTC_ICache is an _abstract_ cache used to store a single FT_Glyph
|
||||
* image per cache node.
|
||||
*
|
||||
* FTC_ICache extends FTC_GCache. For an implementation example,
|
||||
* see FTC_ImageCache in `src/cache/ftbasic.c'.
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Each image cache really manages FT_Glyph objects.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FTCIMAGE_H_
|
||||
#define FTCIMAGE_H_
|
||||
|
||||
|
||||
#include <freetype/ftcache.h>
|
||||
#include "ftcglyph.h"
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* the FT_Glyph image node type - we store only 1 glyph per node */
|
||||
typedef struct FTC_INodeRec_
|
||||
{
|
||||
FTC_GNodeRec gnode;
|
||||
FT_Glyph glyph;
|
||||
|
||||
} FTC_INodeRec, *FTC_INode;
|
||||
|
||||
#define FTC_INODE( x ) ( (FTC_INode)( x ) )
|
||||
#define FTC_INODE_GINDEX( x ) FTC_GNODE( x )->gindex
|
||||
#define FTC_INODE_FAMILY( x ) FTC_GNODE( x )->family
|
||||
|
||||
typedef FT_Error
|
||||
(*FTC_IFamily_LoadGlyphFunc)( FTC_Family family,
|
||||
FT_UInt gindex,
|
||||
FTC_Cache cache,
|
||||
FT_Glyph *aglyph );
|
||||
|
||||
typedef struct FTC_IFamilyClassRec_
|
||||
{
|
||||
FTC_MruListClassRec clazz;
|
||||
FTC_IFamily_LoadGlyphFunc family_load_glyph;
|
||||
|
||||
} FTC_IFamilyClassRec;
|
||||
|
||||
typedef const FTC_IFamilyClassRec* FTC_IFamilyClass;
|
||||
|
||||
#define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x))
|
||||
|
||||
#define FTC_CACHE_IFAMILY_CLASS( x ) \
|
||||
FTC_IFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS( x )->family_class )
|
||||
|
||||
|
||||
/* can be used as a @FTC_Node_FreeFunc */
|
||||
FT_LOCAL( void )
|
||||
FTC_INode_Free( FTC_INode inode,
|
||||
FTC_Cache cache );
|
||||
|
||||
/* Can be used as @FTC_Node_NewFunc. `gquery.index' and `gquery.family'
|
||||
* must be set correctly. This function will call the `family_load_glyph'
|
||||
* method to load the FT_Glyph into the cache node.
|
||||
*/
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_INode_New( FTC_INode *pinode,
|
||||
FTC_GQuery gquery,
|
||||
FTC_Cache cache );
|
||||
|
||||
#if 0
|
||||
/* can be used as @FTC_Node_WeightFunc */
|
||||
FT_LOCAL( FT_ULong )
|
||||
FTC_INode_Weight( FTC_INode inode );
|
||||
#endif
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* FTCIMAGE_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
677
thirdparty/freetype/src/cache/ftcmanag.c
vendored
Normal file
677
thirdparty/freetype/src/cache/ftcmanag.c
vendored
Normal file
@@ -0,0 +1,677 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcmanag.c
|
||||
*
|
||||
* FreeType Cache Manager (body).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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 <freetype/ftcache.h>
|
||||
#include "ftcmanag.h"
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/ftsizes.h>
|
||||
|
||||
#include "ftcerror.h"
|
||||
|
||||
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT cache
|
||||
|
||||
|
||||
static FT_Error
|
||||
ftc_scaler_lookup_size( FTC_Manager manager,
|
||||
FTC_Scaler scaler,
|
||||
FT_Size *asize )
|
||||
{
|
||||
FT_Face face;
|
||||
FT_Size size = NULL;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
error = FTC_Manager_LookupFace( manager, scaler->face_id, &face );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
error = FT_New_Size( face, &size );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
FT_Activate_Size( size );
|
||||
|
||||
if ( scaler->pixel )
|
||||
error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height );
|
||||
else
|
||||
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 );
|
||||
size = NULL;
|
||||
}
|
||||
|
||||
Exit:
|
||||
*asize = size;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
typedef struct FTC_SizeNodeRec_
|
||||
{
|
||||
FTC_MruNodeRec node;
|
||||
FT_Size size;
|
||||
FTC_ScalerRec scaler;
|
||||
|
||||
} FTC_SizeNodeRec, *FTC_SizeNode;
|
||||
|
||||
#define FTC_SIZE_NODE( x ) ( (FTC_SizeNode)( x ) )
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ftc_size_node_done( FTC_MruNode ftcnode,
|
||||
FT_Pointer data )
|
||||
{
|
||||
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
|
||||
FT_UNUSED( data );
|
||||
|
||||
|
||||
FT_Done_Size( node->size );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_size_node_compare( FTC_MruNode ftcnode,
|
||||
FT_Pointer ftcscaler )
|
||||
{
|
||||
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
|
||||
FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
|
||||
FTC_Scaler scaler0 = &node->scaler;
|
||||
|
||||
|
||||
if ( FTC_SCALER_COMPARE( scaler0, scaler ) )
|
||||
{
|
||||
FT_Activate_Size( node->size );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_size_node_init( FTC_MruNode ftcnode,
|
||||
FT_Pointer ftcscaler,
|
||||
FT_Pointer ftcmanager )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Size size;
|
||||
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
|
||||
FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
|
||||
FTC_Manager manager = (FTC_Manager)ftcmanager;
|
||||
|
||||
|
||||
error = ftc_scaler_lookup_size( manager, scaler, &size );
|
||||
if ( !error )
|
||||
{
|
||||
node->size = size;
|
||||
node->scaler = scaler[0];
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
const FTC_MruListClassRec ftc_size_list_class =
|
||||
{
|
||||
sizeof ( FTC_SizeNodeRec ),
|
||||
|
||||
ftc_size_node_compare, /* FTC_MruNode_CompareFunc node_compare */
|
||||
ftc_size_node_init, /* FTC_MruNode_InitFunc node_init */
|
||||
ftc_size_node_done /* FTC_MruNode_DoneFunc node_done */
|
||||
};
|
||||
|
||||
|
||||
/* helper function used by ftc_face_node_done */
|
||||
static FT_Bool
|
||||
ftc_size_node_compare_faceid( FTC_MruNode ftcnode,
|
||||
FT_Pointer ftcface_id )
|
||||
{
|
||||
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
|
||||
FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
|
||||
|
||||
|
||||
return FT_BOOL( node->scaler.face_id == face_id );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_Manager_LookupSize( FTC_Manager manager,
|
||||
FTC_Scaler scaler,
|
||||
FT_Size *asize )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_MruNode mrunode;
|
||||
|
||||
|
||||
if ( !asize || !scaler )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
*asize = NULL;
|
||||
|
||||
if ( !manager )
|
||||
return FT_THROW( Invalid_Cache_Handle );
|
||||
|
||||
#ifdef FTC_INLINE
|
||||
|
||||
FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare,
|
||||
mrunode, error );
|
||||
|
||||
#else
|
||||
error = FTC_MruList_Lookup( &manager->sizes, scaler, &mrunode );
|
||||
#endif
|
||||
|
||||
if ( !error )
|
||||
*asize = FTC_SIZE_NODE( mrunode )->size;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** FACE MRU IMPLEMENTATION *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
typedef struct FTC_FaceNodeRec_
|
||||
{
|
||||
FTC_MruNodeRec node;
|
||||
FTC_FaceID face_id;
|
||||
FT_Face face;
|
||||
|
||||
} FTC_FaceNodeRec, *FTC_FaceNode;
|
||||
|
||||
#define FTC_FACE_NODE( x ) ( ( FTC_FaceNode )( x ) )
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_face_node_init( FTC_MruNode ftcnode,
|
||||
FT_Pointer ftcface_id,
|
||||
FT_Pointer ftcmanager )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Face face;
|
||||
FTC_FaceNode node = (FTC_FaceNode)ftcnode;
|
||||
FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
|
||||
FTC_Manager manager = (FTC_Manager)ftcmanager;
|
||||
|
||||
|
||||
error = manager->request_face( face_id,
|
||||
manager->library,
|
||||
manager->request_data,
|
||||
&face );
|
||||
if ( !error )
|
||||
{
|
||||
/* destroy initial size object; it will be re-created later */
|
||||
if ( face->size )
|
||||
FT_Done_Size( face->size );
|
||||
|
||||
node->face = face;
|
||||
node->face_id = face_id;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ftc_face_node_done( FTC_MruNode ftcnode,
|
||||
FT_Pointer ftcmanager )
|
||||
{
|
||||
FTC_FaceNode node = (FTC_FaceNode)ftcnode;
|
||||
FTC_Manager manager = (FTC_Manager)ftcmanager;
|
||||
|
||||
|
||||
/* we must begin by removing all scalers for the target face */
|
||||
/* from the manager's list */
|
||||
FTC_MruList_RemoveSelection( &manager->sizes,
|
||||
ftc_size_node_compare_faceid,
|
||||
node->face_id );
|
||||
|
||||
/* all right, we can discard the face now */
|
||||
FT_Done_Face( node->face );
|
||||
node->face = NULL;
|
||||
node->face_id = NULL;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Bool )
|
||||
ftc_face_node_compare( FTC_MruNode ftcnode,
|
||||
FT_Pointer ftcface_id )
|
||||
{
|
||||
FTC_FaceNode node = (FTC_FaceNode)ftcnode;
|
||||
FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
|
||||
|
||||
|
||||
return FT_BOOL( node->face_id == face_id );
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
const FTC_MruListClassRec ftc_face_list_class =
|
||||
{
|
||||
sizeof ( FTC_FaceNodeRec),
|
||||
|
||||
ftc_face_node_compare, /* FTC_MruNode_CompareFunc node_compare */
|
||||
ftc_face_node_init, /* FTC_MruNode_InitFunc node_init */
|
||||
ftc_face_node_done /* FTC_MruNode_DoneFunc node_done */
|
||||
};
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_Manager_LookupFace( FTC_Manager manager,
|
||||
FTC_FaceID face_id,
|
||||
FT_Face *aface )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_MruNode mrunode;
|
||||
|
||||
|
||||
if ( !aface )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
*aface = NULL;
|
||||
|
||||
if ( !manager )
|
||||
return FT_THROW( Invalid_Cache_Handle );
|
||||
|
||||
/* we break encapsulation for the sake of speed */
|
||||
#ifdef FTC_INLINE
|
||||
|
||||
FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare,
|
||||
mrunode, error );
|
||||
|
||||
#else
|
||||
error = FTC_MruList_Lookup( &manager->faces, face_id, &mrunode );
|
||||
#endif
|
||||
|
||||
if ( !error )
|
||||
*aface = FTC_FACE_NODE( mrunode )->face;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CACHE MANAGER ROUTINES *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FTC_Manager_New( FT_Library library,
|
||||
FT_UInt max_faces,
|
||||
FT_UInt max_sizes,
|
||||
FT_ULong max_bytes,
|
||||
FTC_Face_Requester requester,
|
||||
FT_Pointer req_data,
|
||||
FTC_Manager *amanager )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
FTC_Manager manager = NULL;
|
||||
|
||||
|
||||
if ( !library )
|
||||
return FT_THROW( Invalid_Library_Handle );
|
||||
|
||||
if ( !amanager || !requester )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
if ( FT_QNEW( manager ) )
|
||||
goto Exit;
|
||||
|
||||
if ( max_faces == 0 )
|
||||
max_faces = FTC_MAX_FACES_DEFAULT;
|
||||
|
||||
if ( max_sizes == 0 )
|
||||
max_sizes = FTC_MAX_SIZES_DEFAULT;
|
||||
|
||||
if ( max_bytes == 0 )
|
||||
max_bytes = FTC_MAX_BYTES_DEFAULT;
|
||||
|
||||
manager->library = library;
|
||||
manager->memory = memory;
|
||||
manager->max_weight = max_bytes;
|
||||
manager->cur_weight = 0;
|
||||
|
||||
manager->request_face = requester;
|
||||
manager->request_data = req_data;
|
||||
|
||||
FTC_MruList_Init( &manager->faces,
|
||||
&ftc_face_list_class,
|
||||
max_faces,
|
||||
manager,
|
||||
memory );
|
||||
|
||||
FTC_MruList_Init( &manager->sizes,
|
||||
&ftc_size_list_class,
|
||||
max_sizes,
|
||||
manager,
|
||||
memory );
|
||||
|
||||
manager->nodes_list = NULL;
|
||||
manager->num_nodes = 0;
|
||||
manager->num_caches = 0;
|
||||
|
||||
*amanager = manager;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FTC_Manager_Done( FTC_Manager manager )
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_UInt idx;
|
||||
|
||||
|
||||
if ( !manager || !manager->library )
|
||||
return;
|
||||
|
||||
memory = manager->memory;
|
||||
|
||||
/* now discard all caches */
|
||||
for ( idx = manager->num_caches; idx-- > 0; )
|
||||
{
|
||||
FTC_Cache cache = manager->caches[idx];
|
||||
|
||||
|
||||
if ( cache )
|
||||
{
|
||||
cache->clazz.cache_done( cache );
|
||||
FT_FREE( cache );
|
||||
}
|
||||
}
|
||||
|
||||
/* discard faces and sizes */
|
||||
FTC_MruList_Done( &manager->sizes );
|
||||
FTC_MruList_Done( &manager->faces );
|
||||
|
||||
FT_FREE( manager );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FTC_Manager_Reset( FTC_Manager manager )
|
||||
{
|
||||
if ( !manager )
|
||||
return;
|
||||
|
||||
FTC_MruList_Reset( &manager->sizes );
|
||||
FTC_MruList_Reset( &manager->faces );
|
||||
|
||||
FTC_Manager_FlushN( manager, manager->num_nodes );
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
|
||||
static void
|
||||
FTC_Manager_Check( FTC_Manager manager )
|
||||
{
|
||||
FTC_Node node, first;
|
||||
|
||||
|
||||
first = manager->nodes_list;
|
||||
|
||||
/* check node weights */
|
||||
if ( first )
|
||||
{
|
||||
FT_Offset weight = 0;
|
||||
|
||||
|
||||
node = first;
|
||||
|
||||
do
|
||||
{
|
||||
FTC_Cache cache = manager->caches[node->cache_index];
|
||||
|
||||
|
||||
if ( node->cache_index >= manager->num_caches )
|
||||
FT_TRACE0(( "FTC_Manager_Check: invalid node (cache index = %hu\n",
|
||||
node->cache_index ));
|
||||
else
|
||||
weight += cache->clazz.node_weight( node, cache );
|
||||
|
||||
node = FTC_NODE_NEXT( node );
|
||||
|
||||
} while ( node != first );
|
||||
|
||||
if ( weight != manager->cur_weight )
|
||||
FT_TRACE0(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n",
|
||||
manager->cur_weight, weight ));
|
||||
}
|
||||
|
||||
/* check circular list */
|
||||
if ( first )
|
||||
{
|
||||
FT_UFast count = 0;
|
||||
|
||||
|
||||
node = first;
|
||||
do
|
||||
{
|
||||
count++;
|
||||
node = FTC_NODE_NEXT( node );
|
||||
|
||||
} while ( node != first );
|
||||
|
||||
if ( count != manager->num_nodes )
|
||||
FT_TRACE0(( "FTC_Manager_Check:"
|
||||
" invalid cache node count %u instead of %u\n",
|
||||
manager->num_nodes, count ));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FT_DEBUG_ERROR */
|
||||
|
||||
|
||||
/* `Compress' the manager's data, i.e., get rid of old cache nodes */
|
||||
/* that are not referenced anymore in order to limit the total */
|
||||
/* memory used by the cache. */
|
||||
|
||||
/* documentation is in ftcmanag.h */
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_Manager_Compress( FTC_Manager manager )
|
||||
{
|
||||
FTC_Node node, prev, first;
|
||||
|
||||
|
||||
if ( !manager )
|
||||
return;
|
||||
|
||||
first = manager->nodes_list;
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
FTC_Manager_Check( manager );
|
||||
|
||||
FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %u\n",
|
||||
manager->cur_weight, manager->max_weight,
|
||||
manager->num_nodes ));
|
||||
#endif
|
||||
|
||||
if ( manager->cur_weight < manager->max_weight || !first )
|
||||
return;
|
||||
|
||||
/* go to last node -- it's a circular list */
|
||||
prev = FTC_NODE_PREV( first );
|
||||
do
|
||||
{
|
||||
node = prev;
|
||||
prev = FTC_NODE_PREV( node );
|
||||
|
||||
if ( node->ref_count <= 0 )
|
||||
ftc_node_destroy( node, manager );
|
||||
|
||||
} while ( node != first && manager->cur_weight > manager->max_weight );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcmanag.h */
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_Manager_RegisterCache( FTC_Manager manager,
|
||||
FTC_CacheClass clazz,
|
||||
FTC_Cache *acache )
|
||||
{
|
||||
FT_Error error = FT_ERR( Invalid_Argument );
|
||||
FTC_Cache cache = NULL;
|
||||
|
||||
|
||||
if ( manager && clazz && acache )
|
||||
{
|
||||
FT_Memory memory = manager->memory;
|
||||
|
||||
|
||||
if ( manager->num_caches >= FTC_MAX_CACHES )
|
||||
{
|
||||
error = FT_THROW( Too_Many_Caches );
|
||||
FT_ERROR(( "FTC_Manager_RegisterCache:"
|
||||
" too many registered caches\n" ));
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( !FT_QALLOC( cache, clazz->cache_size ) )
|
||||
{
|
||||
cache->manager = manager;
|
||||
cache->memory = memory;
|
||||
cache->clazz = clazz[0];
|
||||
cache->org_class = clazz;
|
||||
|
||||
/* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */
|
||||
/* IF IT IS NOT SET CORRECTLY */
|
||||
cache->index = manager->num_caches;
|
||||
|
||||
error = clazz->cache_init( cache );
|
||||
if ( error )
|
||||
{
|
||||
clazz->cache_done( cache );
|
||||
FT_FREE( cache );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
manager->caches[manager->num_caches++] = cache;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
if ( acache )
|
||||
*acache = cache;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_UInt )
|
||||
FTC_Manager_FlushN( FTC_Manager manager,
|
||||
FT_UInt count )
|
||||
{
|
||||
FTC_Node first = manager->nodes_list;
|
||||
FTC_Node prev, node;
|
||||
FT_UInt result = 0;
|
||||
|
||||
|
||||
/* try to remove `count' nodes from the list */
|
||||
if ( !first || !count )
|
||||
return result;
|
||||
|
||||
/* go to last node -- it's a circular list */
|
||||
prev = FTC_NODE_PREV( first );
|
||||
do
|
||||
{
|
||||
node = prev;
|
||||
prev = FTC_NODE_PREV( node );
|
||||
|
||||
/* don't touch locked nodes */
|
||||
if ( node->ref_count <= 0 )
|
||||
{
|
||||
ftc_node_destroy( node, manager );
|
||||
result++;
|
||||
}
|
||||
} while ( node != first && result < count );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FTC_Manager_RemoveFaceID( FTC_Manager manager,
|
||||
FTC_FaceID face_id )
|
||||
{
|
||||
FT_UInt nn;
|
||||
|
||||
|
||||
if ( !manager )
|
||||
return;
|
||||
|
||||
/* this will remove all FTC_SizeNode that correspond to
|
||||
* the face_id as well
|
||||
*/
|
||||
FTC_MruList_RemoveSelection( &manager->faces,
|
||||
ftc_face_node_compare,
|
||||
face_id );
|
||||
|
||||
for ( nn = 0; nn < manager->num_caches; nn++ )
|
||||
FTC_Cache_RemoveFaceID( manager->caches[nn], face_id );
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcache.h */
|
||||
|
||||
FT_EXPORT_DEF( void )
|
||||
FTC_Node_Unref( FTC_Node node,
|
||||
FTC_Manager manager )
|
||||
{
|
||||
if ( node &&
|
||||
manager &&
|
||||
node->cache_index < manager->num_caches )
|
||||
node->ref_count--;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
175
thirdparty/freetype/src/cache/ftcmanag.h
vendored
Normal file
175
thirdparty/freetype/src/cache/ftcmanag.h
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcmanag.h
|
||||
*
|
||||
* FreeType Cache Manager (specification).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* A cache manager is in charge of the following:
|
||||
*
|
||||
* - Maintain a mapping between generic FTC_FaceIDs and live FT_Face
|
||||
* objects. The mapping itself is performed through a user-provided
|
||||
* callback. However, the manager maintains a small cache of FT_Face
|
||||
* and FT_Size objects in order to speed up things considerably.
|
||||
*
|
||||
* - Manage one or more cache objects. Each cache is in charge of
|
||||
* holding a varying number of `cache nodes'. Each cache node
|
||||
* represents a minimal amount of individually accessible cached
|
||||
* data. For example, a cache node can be an FT_Glyph image
|
||||
* containing a vector outline, or some glyph metrics, or anything
|
||||
* else.
|
||||
*
|
||||
* Each cache node has a certain size in bytes that is added to the
|
||||
* total amount of `cache memory' within the manager.
|
||||
*
|
||||
* All cache nodes are located in a global LRU list, where the oldest
|
||||
* node is at the tail of the list.
|
||||
*
|
||||
* Each node belongs to a single cache, and includes a reference
|
||||
* count to avoid destroying it (due to caching).
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/********* *********/
|
||||
/********* WARNING, THIS IS BETA CODE. *********/
|
||||
/********* *********/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#ifndef FTCMANAG_H_
|
||||
#define FTCMANAG_H_
|
||||
|
||||
|
||||
#include <freetype/ftcache.h>
|
||||
#include "ftcmru.h"
|
||||
#include "ftccache.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Section:
|
||||
* cache_subsystem
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define FTC_MAX_FACES_DEFAULT 2
|
||||
#define FTC_MAX_SIZES_DEFAULT 4
|
||||
#define FTC_MAX_BYTES_DEFAULT 200000L /* ~200kByte by default */
|
||||
|
||||
/* maximum number of caches registered in a single manager */
|
||||
#define FTC_MAX_CACHES 16
|
||||
|
||||
|
||||
typedef struct FTC_ManagerRec_
|
||||
{
|
||||
FT_Library library;
|
||||
FT_Memory memory;
|
||||
|
||||
FTC_Node nodes_list;
|
||||
FT_Offset max_weight;
|
||||
FT_Offset cur_weight;
|
||||
FT_UInt num_nodes;
|
||||
|
||||
FTC_Cache caches[FTC_MAX_CACHES];
|
||||
FT_UInt num_caches;
|
||||
|
||||
FTC_MruListRec faces;
|
||||
FTC_MruListRec sizes;
|
||||
|
||||
FT_Pointer request_data;
|
||||
FTC_Face_Requester request_face;
|
||||
|
||||
} FTC_ManagerRec;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* FTC_Manager_Compress
|
||||
*
|
||||
* @Description:
|
||||
* This function is used to check the state of the cache manager if
|
||||
* its `num_bytes' field is greater than its `max_bytes' field. It
|
||||
* will flush as many old cache nodes as possible (ignoring cache
|
||||
* nodes with a non-zero reference count).
|
||||
*
|
||||
* @InOut:
|
||||
* manager ::
|
||||
* A handle to the cache manager.
|
||||
*
|
||||
* @Note:
|
||||
* Client applications should not call this function directly. It is
|
||||
* normally invoked by specific cache implementations.
|
||||
*
|
||||
* The reason this function is exported is to allow client-specific
|
||||
* cache classes.
|
||||
*/
|
||||
FT_LOCAL( void )
|
||||
FTC_Manager_Compress( FTC_Manager manager );
|
||||
|
||||
|
||||
/* try to flush `count' old nodes from the cache; return the number
|
||||
* of really flushed nodes
|
||||
*/
|
||||
FT_LOCAL( FT_UInt )
|
||||
FTC_Manager_FlushN( FTC_Manager manager,
|
||||
FT_UInt count );
|
||||
|
||||
|
||||
/* this must be used internally for the moment */
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_Manager_RegisterCache( FTC_Manager manager,
|
||||
FTC_CacheClass clazz,
|
||||
FTC_Cache *acache );
|
||||
|
||||
/* */
|
||||
|
||||
#define FTC_SCALER_COMPARE( a, b ) \
|
||||
( (a)->face_id == (b)->face_id && \
|
||||
(a)->width == (b)->width && \
|
||||
(a)->height == (b)->height && \
|
||||
((a)->pixel != 0) == ((b)->pixel != 0) && \
|
||||
( (a)->pixel || \
|
||||
( (a)->x_res == (b)->x_res && \
|
||||
(a)->y_res == (b)->y_res ) ) )
|
||||
|
||||
#define FTC_SCALER_HASH( q ) \
|
||||
( FTC_FACE_ID_HASH( (q)->face_id ) + \
|
||||
(q)->width + (q)->height*7 + \
|
||||
( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) )
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* FTCMANAG_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
341
thirdparty/freetype/src/cache/ftcmru.c
vendored
Normal file
341
thirdparty/freetype/src/cache/ftcmru.c
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcmru.c
|
||||
*
|
||||
* FreeType MRU support (body).
|
||||
*
|
||||
* Copyright (C) 2003-2024 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 <freetype/ftcache.h>
|
||||
#include "ftcmru.h"
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
|
||||
#include "ftcerror.h"
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_MruNode_Prepend( FTC_MruNode *plist,
|
||||
FTC_MruNode node )
|
||||
{
|
||||
FTC_MruNode first = *plist;
|
||||
|
||||
|
||||
if ( first )
|
||||
{
|
||||
FTC_MruNode last = first->prev;
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
{
|
||||
FTC_MruNode cnode = first;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
if ( cnode == node )
|
||||
{
|
||||
fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" );
|
||||
exit( 2 );
|
||||
}
|
||||
cnode = cnode->next;
|
||||
|
||||
} while ( cnode != first );
|
||||
}
|
||||
#endif
|
||||
|
||||
first->prev = node;
|
||||
last->next = node;
|
||||
node->next = first;
|
||||
node->prev = last;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->next = node;
|
||||
node->prev = node;
|
||||
}
|
||||
*plist = node;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_MruNode_Up( FTC_MruNode *plist,
|
||||
FTC_MruNode node )
|
||||
{
|
||||
FTC_MruNode first = *plist;
|
||||
|
||||
|
||||
FT_ASSERT( first );
|
||||
|
||||
if ( first != node )
|
||||
{
|
||||
FTC_MruNode prev, next, last;
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
{
|
||||
FTC_MruNode cnode = first;
|
||||
do
|
||||
{
|
||||
if ( cnode == node )
|
||||
goto Ok;
|
||||
cnode = cnode->next;
|
||||
|
||||
} while ( cnode != first );
|
||||
|
||||
fprintf( stderr, "FTC_MruNode_Up: invalid action\n" );
|
||||
exit( 2 );
|
||||
Ok:
|
||||
}
|
||||
#endif
|
||||
prev = node->prev;
|
||||
next = node->next;
|
||||
|
||||
prev->next = next;
|
||||
next->prev = prev;
|
||||
|
||||
last = first->prev;
|
||||
|
||||
last->next = node;
|
||||
first->prev = node;
|
||||
|
||||
node->next = first;
|
||||
node->prev = last;
|
||||
|
||||
*plist = node;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_MruNode_Remove( FTC_MruNode *plist,
|
||||
FTC_MruNode node )
|
||||
{
|
||||
FTC_MruNode first = *plist;
|
||||
FTC_MruNode prev, next;
|
||||
|
||||
|
||||
FT_ASSERT( first );
|
||||
|
||||
#ifdef FT_DEBUG_ERROR
|
||||
{
|
||||
FTC_MruNode cnode = first;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
if ( cnode == node )
|
||||
goto Ok;
|
||||
cnode = cnode->next;
|
||||
|
||||
} while ( cnode != first );
|
||||
|
||||
fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" );
|
||||
exit( 2 );
|
||||
Ok:
|
||||
}
|
||||
#endif
|
||||
|
||||
prev = node->prev;
|
||||
next = node->next;
|
||||
|
||||
prev->next = next;
|
||||
next->prev = prev;
|
||||
|
||||
if ( node == next )
|
||||
{
|
||||
FT_ASSERT( first == node );
|
||||
FT_ASSERT( prev == node );
|
||||
|
||||
*plist = NULL;
|
||||
}
|
||||
else if ( node == first )
|
||||
*plist = next;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_MruList_Init( FTC_MruList list,
|
||||
FTC_MruListClass clazz,
|
||||
FT_UInt max_nodes,
|
||||
FT_Pointer data,
|
||||
FT_Memory memory )
|
||||
{
|
||||
list->num_nodes = 0;
|
||||
list->max_nodes = max_nodes;
|
||||
list->nodes = NULL;
|
||||
list->clazz = *clazz;
|
||||
list->data = data;
|
||||
list->memory = memory;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_MruList_Reset( FTC_MruList list )
|
||||
{
|
||||
while ( list->nodes )
|
||||
FTC_MruList_Remove( list, list->nodes );
|
||||
|
||||
FT_ASSERT( list->num_nodes == 0 );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_MruList_Done( FTC_MruList list )
|
||||
{
|
||||
FTC_MruList_Reset( list );
|
||||
}
|
||||
|
||||
|
||||
#ifndef FTC_INLINE
|
||||
FT_LOCAL_DEF( FTC_MruNode )
|
||||
FTC_MruList_Find( FTC_MruList list,
|
||||
FT_Pointer key )
|
||||
{
|
||||
FTC_MruNode_CompareFunc compare = list->clazz.node_compare;
|
||||
FTC_MruNode first, node;
|
||||
|
||||
|
||||
first = list->nodes;
|
||||
node = NULL;
|
||||
|
||||
if ( first )
|
||||
{
|
||||
node = first;
|
||||
do
|
||||
{
|
||||
if ( compare( node, key ) )
|
||||
{
|
||||
if ( node != first )
|
||||
FTC_MruNode_Up( &list->nodes, node );
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
node = node->next;
|
||||
|
||||
} while ( node != first);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_MruList_New( FTC_MruList list,
|
||||
FT_Pointer key,
|
||||
FTC_MruNode *anode )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_MruNode node = NULL;
|
||||
FTC_MruNode prev = NULL;
|
||||
FT_Memory memory = list->memory;
|
||||
|
||||
|
||||
/* zero new node in case of node_init failure */
|
||||
if ( FT_ALLOC( node, list->clazz.node_size ) )
|
||||
goto Exit;
|
||||
|
||||
error = list->clazz.node_init( node, key, list->data );
|
||||
if ( error )
|
||||
{
|
||||
prev = node;
|
||||
node = NULL;
|
||||
|
||||
goto Clean;
|
||||
}
|
||||
else if ( list->max_nodes > 0 && list->num_nodes >= list->max_nodes )
|
||||
prev = list->nodes->prev;
|
||||
|
||||
FTC_MruNode_Prepend( &list->nodes, node );
|
||||
list->num_nodes++;
|
||||
|
||||
if ( !prev )
|
||||
goto Exit;
|
||||
|
||||
FTC_MruNode_Remove( &list->nodes, prev );
|
||||
list->num_nodes--;
|
||||
|
||||
Clean:
|
||||
if ( list->clazz.node_done )
|
||||
list->clazz.node_done( prev, list->data );
|
||||
|
||||
FT_FREE( prev );
|
||||
|
||||
Exit:
|
||||
*anode = node;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#ifndef FTC_INLINE
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_MruList_Lookup( FTC_MruList list,
|
||||
FT_Pointer key,
|
||||
FTC_MruNode *anode )
|
||||
{
|
||||
FTC_MruNode node;
|
||||
|
||||
|
||||
node = FTC_MruList_Find( list, key );
|
||||
if ( !node )
|
||||
return FTC_MruList_New( list, key, anode );
|
||||
|
||||
*anode = node;
|
||||
return 0;
|
||||
}
|
||||
#endif /* FTC_INLINE */
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_MruList_Remove( FTC_MruList list,
|
||||
FTC_MruNode node )
|
||||
{
|
||||
FT_Memory memory = list->memory;
|
||||
|
||||
|
||||
FTC_MruNode_Remove( &list->nodes, node );
|
||||
list->num_nodes--;
|
||||
|
||||
if ( list->clazz.node_done )
|
||||
list->clazz.node_done( node, list->data );
|
||||
|
||||
FT_FREE( node );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_MruList_RemoveSelection( FTC_MruList list,
|
||||
FTC_MruNode_CompareFunc selection,
|
||||
FT_Pointer key )
|
||||
{
|
||||
FTC_MruNode first = list->nodes;
|
||||
FTC_MruNode prev, node;
|
||||
|
||||
|
||||
if ( !first || !selection )
|
||||
return;
|
||||
|
||||
prev = first->prev;
|
||||
do
|
||||
{
|
||||
node = prev;
|
||||
prev = node->prev;
|
||||
|
||||
if ( selection( node, key ) )
|
||||
FTC_MruList_Remove( list, node );
|
||||
|
||||
} while ( node != first );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
242
thirdparty/freetype/src/cache/ftcmru.h
vendored
Normal file
242
thirdparty/freetype/src/cache/ftcmru.h
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcmru.h
|
||||
*
|
||||
* Simple MRU list-cache (specification).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* An MRU is a list that cannot hold more than a certain number of
|
||||
* elements (`max_elements'). All elements in the list are sorted in
|
||||
* least-recently-used order, i.e., the `oldest' element is at the tail
|
||||
* of the list.
|
||||
*
|
||||
* When doing a lookup (either through `Lookup()' or `Lookup_Node()'),
|
||||
* the list is searched for an element with the corresponding key. If
|
||||
* it is found, the element is moved to the head of the list and is
|
||||
* returned.
|
||||
*
|
||||
* If no corresponding element is found, the lookup routine will try to
|
||||
* obtain a new element with the relevant key. If the list is already
|
||||
* full, the oldest element from the list is discarded and replaced by a
|
||||
* new one; a new element is added to the list otherwise.
|
||||
*
|
||||
* Note that it is possible to pre-allocate the element list nodes.
|
||||
* This is handy if `max_elements' is sufficiently small, as it saves
|
||||
* allocations/releases during the lookup process.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FTCMRU_H_
|
||||
#define FTCMRU_H_
|
||||
|
||||
|
||||
#include <freetype/freetype.h>
|
||||
#include <freetype/internal/compiler-macros.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
|
||||
|
||||
#define xxFT_DEBUG_ERROR
|
||||
#define FTC_INLINE
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
typedef struct FTC_MruNodeRec_* FTC_MruNode;
|
||||
|
||||
typedef struct FTC_MruNodeRec_
|
||||
{
|
||||
FTC_MruNode next;
|
||||
FTC_MruNode prev;
|
||||
|
||||
} FTC_MruNodeRec;
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
FTC_MruNode_Prepend( FTC_MruNode *plist,
|
||||
FTC_MruNode node );
|
||||
|
||||
FT_LOCAL( void )
|
||||
FTC_MruNode_Up( FTC_MruNode *plist,
|
||||
FTC_MruNode node );
|
||||
|
||||
FT_LOCAL( void )
|
||||
FTC_MruNode_Remove( FTC_MruNode *plist,
|
||||
FTC_MruNode node );
|
||||
|
||||
|
||||
typedef struct FTC_MruListRec_* FTC_MruList;
|
||||
|
||||
typedef struct FTC_MruListClassRec_ const * FTC_MruListClass;
|
||||
|
||||
|
||||
typedef FT_Bool
|
||||
(*FTC_MruNode_CompareFunc)( FTC_MruNode node,
|
||||
FT_Pointer key );
|
||||
|
||||
typedef FT_Error
|
||||
(*FTC_MruNode_InitFunc)( FTC_MruNode node,
|
||||
FT_Pointer key,
|
||||
FT_Pointer data );
|
||||
|
||||
typedef void
|
||||
(*FTC_MruNode_DoneFunc)( FTC_MruNode node,
|
||||
FT_Pointer data );
|
||||
|
||||
|
||||
typedef struct FTC_MruListClassRec_
|
||||
{
|
||||
FT_Offset node_size;
|
||||
|
||||
FTC_MruNode_CompareFunc node_compare;
|
||||
FTC_MruNode_InitFunc node_init;
|
||||
FTC_MruNode_DoneFunc node_done;
|
||||
|
||||
} FTC_MruListClassRec;
|
||||
|
||||
|
||||
typedef struct FTC_MruListRec_
|
||||
{
|
||||
FT_UInt num_nodes;
|
||||
FT_UInt max_nodes;
|
||||
FTC_MruNode nodes;
|
||||
FT_Pointer data;
|
||||
FTC_MruListClassRec clazz;
|
||||
FT_Memory memory;
|
||||
|
||||
} FTC_MruListRec;
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
FTC_MruList_Init( FTC_MruList list,
|
||||
FTC_MruListClass clazz,
|
||||
FT_UInt max_nodes,
|
||||
FT_Pointer data,
|
||||
FT_Memory memory );
|
||||
|
||||
FT_LOCAL( void )
|
||||
FTC_MruList_Reset( FTC_MruList list );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
FTC_MruList_Done( FTC_MruList list );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_MruList_New( FTC_MruList list,
|
||||
FT_Pointer key,
|
||||
FTC_MruNode *anode );
|
||||
|
||||
FT_LOCAL( void )
|
||||
FTC_MruList_Remove( FTC_MruList list,
|
||||
FTC_MruNode node );
|
||||
|
||||
FT_LOCAL( void )
|
||||
FTC_MruList_RemoveSelection( FTC_MruList list,
|
||||
FTC_MruNode_CompareFunc selection,
|
||||
FT_Pointer key );
|
||||
|
||||
|
||||
#ifdef FTC_INLINE
|
||||
|
||||
#define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error ) \
|
||||
FT_BEGIN_STMNT \
|
||||
FTC_MruNode* _pfirst = &(list)->nodes; \
|
||||
FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \
|
||||
FTC_MruNode _first, _node; \
|
||||
\
|
||||
\
|
||||
error = FT_Err_Ok; \
|
||||
_first = *(_pfirst); \
|
||||
_node = NULL; \
|
||||
\
|
||||
if ( _first ) \
|
||||
{ \
|
||||
_node = _first; \
|
||||
do \
|
||||
{ \
|
||||
if ( _compare( _node, (key) ) ) \
|
||||
{ \
|
||||
if ( _node != _first ) \
|
||||
FTC_MruNode_Up( _pfirst, _node ); \
|
||||
\
|
||||
node = _node; \
|
||||
goto MruOk_; \
|
||||
} \
|
||||
_node = _node->next; \
|
||||
\
|
||||
} while ( _node != _first); \
|
||||
} \
|
||||
\
|
||||
error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \
|
||||
MruOk_: \
|
||||
; \
|
||||
FT_END_STMNT
|
||||
|
||||
#define FTC_MRULIST_LOOKUP( list, key, node, error ) \
|
||||
FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error )
|
||||
|
||||
#else /* !FTC_INLINE */
|
||||
|
||||
FT_LOCAL( FTC_MruNode )
|
||||
FTC_MruList_Find( FTC_MruList list,
|
||||
FT_Pointer key );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_MruList_Lookup( FTC_MruList list,
|
||||
FT_Pointer key,
|
||||
FTC_MruNode *pnode );
|
||||
|
||||
#define FTC_MRULIST_LOOKUP( list, key, node, error ) \
|
||||
error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) )
|
||||
|
||||
#endif /* !FTC_INLINE */
|
||||
|
||||
|
||||
#define FTC_MRULIST_LOOP( list, node ) \
|
||||
FT_BEGIN_STMNT \
|
||||
FTC_MruNode _first = (list)->nodes; \
|
||||
\
|
||||
\
|
||||
if ( _first ) \
|
||||
{ \
|
||||
FTC_MruNode _node = _first; \
|
||||
\
|
||||
\
|
||||
do \
|
||||
{ \
|
||||
*(FTC_MruNode*)&(node) = _node;
|
||||
|
||||
|
||||
#define FTC_MRULIST_LOOP_END() \
|
||||
_node = _node->next; \
|
||||
\
|
||||
} while ( _node != _first ); \
|
||||
} \
|
||||
FT_END_STMNT
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* FTCMRU_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
413
thirdparty/freetype/src/cache/ftcsbits.c
vendored
Normal file
413
thirdparty/freetype/src/cache/ftcsbits.c
vendored
Normal file
@@ -0,0 +1,413 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcsbits.c
|
||||
*
|
||||
* FreeType sbits manager (body).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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 <freetype/ftcache.h>
|
||||
#include "ftcsbits.h"
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
#include "ftccback.h"
|
||||
#include "ftcerror.h"
|
||||
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT cache
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** SBIT CACHE NODES *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
static FT_Error
|
||||
ftc_sbit_copy_bitmap( FTC_SBit sbit,
|
||||
FT_Bitmap* bitmap,
|
||||
FT_Memory memory )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Int pitch = bitmap->pitch;
|
||||
FT_ULong size;
|
||||
|
||||
|
||||
if ( pitch < 0 )
|
||||
pitch = -pitch;
|
||||
|
||||
size = (FT_ULong)pitch * bitmap->rows;
|
||||
|
||||
FT_MEM_DUP( sbit->buffer, bitmap->buffer, size );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
ftc_snode_free( FTC_Node ftcsnode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_SNode snode = (FTC_SNode)ftcsnode;
|
||||
FTC_SBit sbit = snode->sbits;
|
||||
FT_UInt count = snode->count;
|
||||
FT_Memory memory = cache->memory;
|
||||
|
||||
|
||||
for ( ; count > 0; sbit++, count-- )
|
||||
FT_FREE( sbit->buffer );
|
||||
|
||||
FTC_GNode_Done( FTC_GNODE( snode ), cache );
|
||||
|
||||
FT_FREE( snode );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
FTC_SNode_Free( FTC_SNode snode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
ftc_snode_free( FTC_NODE( snode ), cache );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function tries to load a small bitmap within a given FTC_SNode.
|
||||
* Note that it returns a non-zero error code _only_ in the case of
|
||||
* out-of-memory condition. For all other errors (e.g., corresponding
|
||||
* to a bad font file), this function will mark the sbit as `unavailable'
|
||||
* and return a value of 0.
|
||||
*
|
||||
* You should also read the comment within the @ftc_snode_compare
|
||||
* function below to see how out-of-memory is handled during a lookup.
|
||||
*/
|
||||
static FT_Error
|
||||
ftc_snode_load( FTC_SNode snode,
|
||||
FTC_Manager manager,
|
||||
FT_UInt gindex,
|
||||
FT_ULong *asize )
|
||||
{
|
||||
FT_Error error;
|
||||
FTC_GNode gnode = FTC_GNODE( snode );
|
||||
FTC_Family family = gnode->family;
|
||||
FT_Face face;
|
||||
FTC_SBit sbit;
|
||||
FTC_SFamilyClass clazz;
|
||||
|
||||
|
||||
if ( gindex - gnode->gindex >= snode->count )
|
||||
{
|
||||
FT_ERROR(( "ftc_snode_load: invalid glyph index" ));
|
||||
return FT_THROW( Invalid_Argument );
|
||||
}
|
||||
|
||||
sbit = snode->sbits + ( gindex - gnode->gindex );
|
||||
clazz = (FTC_SFamilyClass)family->clazz;
|
||||
|
||||
error = clazz->family_load_glyph( family, gindex, manager, &face );
|
||||
if ( error )
|
||||
goto BadGlyph;
|
||||
|
||||
{
|
||||
FT_Int temp;
|
||||
FT_GlyphSlot slot = face->glyph;
|
||||
FT_Bitmap* bitmap = &slot->bitmap;
|
||||
FT_Pos xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */
|
||||
|
||||
|
||||
if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
|
||||
{
|
||||
FT_TRACE0(( "ftc_snode_load:"
|
||||
" glyph loaded didn't return a bitmap\n" ));
|
||||
goto BadGlyph;
|
||||
}
|
||||
|
||||
/* Check whether our values fit into 8/16-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, (FT_Int) temp == (FT_Int) d )
|
||||
#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, (FT_UInt)temp == (FT_UInt)d )
|
||||
#define CHECK_SHRT( d ) ( temp = (FT_Short)d, (FT_Int)temp == (FT_Int) d )
|
||||
|
||||
/* horizontal advance in pixels */
|
||||
xadvance = ( slot->advance.x + 32 ) >> 6;
|
||||
yadvance = ( slot->advance.y + 32 ) >> 6;
|
||||
|
||||
if ( !CHECK_BYTE( bitmap->rows ) ||
|
||||
!CHECK_BYTE( bitmap->width ) ||
|
||||
!CHECK_SHRT( bitmap->pitch ) ||
|
||||
!CHECK_CHAR( slot->bitmap_left ) ||
|
||||
!CHECK_CHAR( slot->bitmap_top ) ||
|
||||
!CHECK_CHAR( xadvance ) ||
|
||||
!CHECK_CHAR( yadvance ) )
|
||||
{
|
||||
FT_TRACE2(( "ftc_snode_load:"
|
||||
" glyph too large for small bitmap cache\n"));
|
||||
goto BadGlyph;
|
||||
}
|
||||
|
||||
sbit->width = (FT_Byte)bitmap->width;
|
||||
sbit->height = (FT_Byte)bitmap->rows;
|
||||
sbit->pitch = (FT_Short)bitmap->pitch;
|
||||
sbit->left = (FT_Char)slot->bitmap_left;
|
||||
sbit->top = (FT_Char)slot->bitmap_top;
|
||||
sbit->xadvance = (FT_Char)xadvance;
|
||||
sbit->yadvance = (FT_Char)yadvance;
|
||||
sbit->format = (FT_Byte)bitmap->pixel_mode;
|
||||
sbit->max_grays = (FT_Byte)( bitmap->num_grays - 1 );
|
||||
|
||||
if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
|
||||
{
|
||||
/* take the bitmap ownership */
|
||||
sbit->buffer = bitmap->buffer;
|
||||
slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* copy the bitmap into a new buffer -- ignore error */
|
||||
error = ftc_sbit_copy_bitmap( sbit, bitmap, manager->memory );
|
||||
}
|
||||
|
||||
/* now, compute size */
|
||||
if ( asize )
|
||||
*asize = (FT_ULong)FT_ABS( sbit->pitch ) * sbit->height;
|
||||
|
||||
} /* glyph loading successful */
|
||||
|
||||
/* ignore the errors that might have occurred -- */
|
||||
/* we mark unloaded glyphs with `sbit.buffer == 0' */
|
||||
/* and `width == 255', `height == 0' */
|
||||
/* */
|
||||
if ( error && FT_ERR_NEQ( error, Out_Of_Memory ) )
|
||||
{
|
||||
BadGlyph:
|
||||
sbit->width = 255;
|
||||
sbit->height = 0;
|
||||
sbit->buffer = NULL;
|
||||
error = FT_Err_Ok;
|
||||
if ( asize )
|
||||
*asize = 0;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
FTC_SNode_New( FTC_SNode *psnode,
|
||||
FTC_GQuery gquery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FT_Memory memory = cache->memory;
|
||||
FT_Error error;
|
||||
FTC_SNode snode = NULL;
|
||||
FT_UInt gindex = gquery->gindex;
|
||||
FTC_Family family = gquery->family;
|
||||
|
||||
FTC_SFamilyClass clazz = FTC_CACHE_SFAMILY_CLASS( cache );
|
||||
FT_UInt total;
|
||||
FT_UInt node_count;
|
||||
|
||||
|
||||
total = clazz->family_get_count( family, cache->manager );
|
||||
if ( total == 0 || gindex >= total )
|
||||
{
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( !FT_QNEW( snode ) )
|
||||
{
|
||||
FT_UInt count, start;
|
||||
|
||||
|
||||
start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE );
|
||||
count = total - start;
|
||||
if ( count > FTC_SBIT_ITEMS_PER_NODE )
|
||||
count = FTC_SBIT_ITEMS_PER_NODE;
|
||||
|
||||
FTC_GNode_Init( FTC_GNODE( snode ), start, family );
|
||||
|
||||
snode->count = count;
|
||||
for ( node_count = 0; node_count < count; node_count++ )
|
||||
{
|
||||
snode->sbits[node_count].width = 255;
|
||||
snode->sbits[node_count].height = 0;
|
||||
snode->sbits[node_count].buffer = NULL;
|
||||
}
|
||||
|
||||
error = ftc_snode_load( snode,
|
||||
cache->manager,
|
||||
gindex,
|
||||
NULL );
|
||||
if ( error )
|
||||
{
|
||||
FTC_SNode_Free( snode, cache );
|
||||
snode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
*psnode = snode;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
ftc_snode_new( FTC_Node *ftcpsnode,
|
||||
FT_Pointer ftcgquery,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_SNode *psnode = (FTC_SNode*)ftcpsnode;
|
||||
FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
|
||||
|
||||
|
||||
return FTC_SNode_New( psnode, gquery, cache );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Offset )
|
||||
ftc_snode_weight( FTC_Node ftcsnode,
|
||||
FTC_Cache cache )
|
||||
{
|
||||
FTC_SNode snode = (FTC_SNode)ftcsnode;
|
||||
FT_UInt count = snode->count;
|
||||
FTC_SBit sbit = snode->sbits;
|
||||
FT_Int pitch;
|
||||
FT_Offset size;
|
||||
|
||||
FT_UNUSED( cache );
|
||||
|
||||
|
||||
FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE );
|
||||
|
||||
/* the node itself */
|
||||
size = sizeof ( *snode );
|
||||
|
||||
for ( ; count > 0; count--, sbit++ )
|
||||
{
|
||||
if ( sbit->buffer )
|
||||
{
|
||||
pitch = sbit->pitch;
|
||||
if ( pitch < 0 )
|
||||
pitch = -pitch;
|
||||
|
||||
/* add the size of a given glyph image */
|
||||
size += (FT_Offset)pitch * sbit->height;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
FT_LOCAL_DEF( FT_Offset )
|
||||
FTC_SNode_Weight( FTC_SNode snode )
|
||||
{
|
||||
return ftc_snode_weight( FTC_NODE( snode ), NULL );
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Bool )
|
||||
ftc_snode_compare( FTC_Node ftcsnode,
|
||||
FT_Pointer ftcgquery,
|
||||
FTC_Cache cache,
|
||||
FT_Bool* list_changed )
|
||||
{
|
||||
FTC_SNode snode = (FTC_SNode)ftcsnode;
|
||||
FTC_GQuery gquery = (FTC_GQuery)ftcgquery;
|
||||
FTC_GNode gnode = FTC_GNODE( snode );
|
||||
FT_UInt gindex = gquery->gindex;
|
||||
FT_Bool result;
|
||||
|
||||
|
||||
if ( list_changed )
|
||||
*list_changed = FALSE;
|
||||
result = FT_BOOL( gnode->family == gquery->family &&
|
||||
gindex - gnode->gindex < snode->count );
|
||||
if ( result )
|
||||
{
|
||||
/* check if we need to load the glyph bitmap now */
|
||||
FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex );
|
||||
|
||||
|
||||
/*
|
||||
* The following code illustrates what to do when you want to
|
||||
* perform operations that may fail within a lookup function.
|
||||
*
|
||||
* Here, we want to load a small bitmap on-demand; we thus
|
||||
* need to call the `ftc_snode_load' function which may return
|
||||
* a non-zero error code only when we are out of memory (OOM).
|
||||
*
|
||||
* The correct thing to do is to use @FTC_CACHE_TRYLOOP and
|
||||
* @FTC_CACHE_TRYLOOP_END in order to implement a retry loop
|
||||
* that is capable of flushing the cache incrementally when
|
||||
* an OOM errors occur.
|
||||
*
|
||||
* However, we need to `lock' the node before this operation to
|
||||
* prevent it from being flushed within the loop.
|
||||
*
|
||||
* When we exit the loop, we unlock the node, then check the `error'
|
||||
* variable. If it is non-zero, this means that the cache was
|
||||
* completely flushed and that no usable memory was found to load
|
||||
* the bitmap.
|
||||
*
|
||||
* We then prefer to return a value of 0 (i.e., NO MATCH). This
|
||||
* ensures that the caller will try to allocate a new node.
|
||||
* This operation consequently _fail_ and the lookup function
|
||||
* returns the appropriate OOM error code.
|
||||
*
|
||||
* Note that `buffer == NULL && width == 255' is a hack used to
|
||||
* tag `unavailable' bitmaps in the array. We should never try
|
||||
* to load these.
|
||||
*
|
||||
*/
|
||||
|
||||
if ( !sbit->buffer && sbit->width == 255 )
|
||||
{
|
||||
FT_ULong size;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
ftcsnode->ref_count++; /* lock node to prevent flushing */
|
||||
/* in retry loop */
|
||||
|
||||
FTC_CACHE_TRYLOOP( cache )
|
||||
{
|
||||
error = ftc_snode_load( snode, cache->manager, gindex, &size );
|
||||
}
|
||||
FTC_CACHE_TRYLOOP_END( list_changed )
|
||||
|
||||
ftcsnode->ref_count--; /* unlock the node */
|
||||
|
||||
if ( error )
|
||||
result = 0;
|
||||
else
|
||||
cache->manager->cur_weight += size;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* END */
|
||||
91
thirdparty/freetype/src/cache/ftcsbits.h
vendored
Normal file
91
thirdparty/freetype/src/cache/ftcsbits.h
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* ftcsbits.h
|
||||
*
|
||||
* A small-bitmap cache (specification).
|
||||
*
|
||||
* Copyright (C) 2000-2024 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 FTCSBITS_H_
|
||||
#define FTCSBITS_H_
|
||||
|
||||
|
||||
#include <freetype/ftcache.h>
|
||||
#include "ftcglyph.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
#define FTC_SBIT_ITEMS_PER_NODE 16
|
||||
|
||||
typedef struct FTC_SNodeRec_
|
||||
{
|
||||
FTC_GNodeRec gnode;
|
||||
FT_UInt count;
|
||||
FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE];
|
||||
|
||||
} FTC_SNodeRec, *FTC_SNode;
|
||||
|
||||
|
||||
#define FTC_SNODE( x ) ( (FTC_SNode)( x ) )
|
||||
#define FTC_SNODE_GINDEX( x ) FTC_GNODE( x )->gindex
|
||||
#define FTC_SNODE_FAMILY( x ) FTC_GNODE( x )->family
|
||||
|
||||
typedef FT_UInt
|
||||
(*FTC_SFamily_GetCountFunc)( FTC_Family family,
|
||||
FTC_Manager manager );
|
||||
|
||||
typedef FT_Error
|
||||
(*FTC_SFamily_LoadGlyphFunc)( FTC_Family family,
|
||||
FT_UInt gindex,
|
||||
FTC_Manager manager,
|
||||
FT_Face *aface );
|
||||
|
||||
typedef struct FTC_SFamilyClassRec_
|
||||
{
|
||||
FTC_MruListClassRec clazz;
|
||||
FTC_SFamily_GetCountFunc family_get_count;
|
||||
FTC_SFamily_LoadGlyphFunc family_load_glyph;
|
||||
|
||||
} FTC_SFamilyClassRec;
|
||||
|
||||
typedef const FTC_SFamilyClassRec* FTC_SFamilyClass;
|
||||
|
||||
#define FTC_SFAMILY_CLASS( x ) ( (FTC_SFamilyClass)(x) )
|
||||
|
||||
#define FTC_CACHE_SFAMILY_CLASS( x ) \
|
||||
FTC_SFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS( x )->family_class )
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
FTC_SNode_Free( FTC_SNode snode,
|
||||
FTC_Cache cache );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
FTC_SNode_New( FTC_SNode *psnode,
|
||||
FTC_GQuery gquery,
|
||||
FTC_Cache cache );
|
||||
|
||||
#if 0
|
||||
FT_LOCAL( FT_ULong )
|
||||
FTC_SNode_Weight( FTC_SNode inode );
|
||||
#endif
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* FTCSBITS_H_ */
|
||||
|
||||
|
||||
/* END */
|
||||
28
thirdparty/freetype/src/cff/cff.c
vendored
Normal file
28
thirdparty/freetype/src/cff/cff.c
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* cff.c
|
||||
*
|
||||
* FreeType OpenType driver component (body only).
|
||||
*
|
||||
* Copyright (C) 1996-2024 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#include "cffcmap.c"
|
||||
#include "cffdrivr.c"
|
||||
#include "cffgload.c"
|
||||
#include "cffparse.c"
|
||||
#include "cffload.c"
|
||||
#include "cffobjs.c"
|
||||
|
||||
/* END */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user