mirror of
https://github.com/QB64-Phoenix-Edition/QB64pe.git
synced 2024-07-04 04:50:22 +00:00
Merge pull request #431 from a740g/freetype-upgrade
Update FreeType to v2.13.2
This commit is contained in:
commit
4c820fba21
2
Makefile
2
Makefile
|
@ -263,7 +263,7 @@ else
|
|||
endif
|
||||
|
||||
ifneq ($(filter y,$(DEP_FONT)),)
|
||||
EXE_LIBS += $(FREETYPE_OBJS) $(FONT_OBJS)
|
||||
EXE_LIBS += $(FONT_OBJS) $(FREETYPE_EXE_LIBS)
|
||||
|
||||
LICENSE_IN_USE += freetype_ftl
|
||||
else
|
||||
|
|
|
@ -1,22 +1,40 @@
|
|||
FREETYPE_SRCS := \
|
||||
freetypeamalgam.c
|
||||
|
||||
FONT_SRCS := \
|
||||
font.cpp
|
||||
# We use the flat-directory compilation for FreeType as explained in:
|
||||
# https://github.com/freetype/freetype/blob/master/docs/INSTALL.ANY
|
||||
#
|
||||
# When updating the library:
|
||||
# 1. Flatten all directories inside "src" except "tools". Omit contents of "tools" entirely.
|
||||
# 2. Then only copy all .c & .h files except:
|
||||
# autofit.c, bdf.c, cff.c, ftbase.c, ftcache.c, gxvalid.c, gxvfgen.c,
|
||||
# otvalid.c, pcf.c, pfr.c, pshinter.c, psnames.c, raster.c, sdf.c, sfnt.c,
|
||||
# smooth.c, svg.c, truetype.c, type1.c, type1cid.c, type42.c
|
||||
# 3. Copy the FreeType "include" directory *without* flattening!
|
||||
# 4. Include <freetype/internal/compiler-macros.h> in "ftzopen.h".
|
||||
# 5. Include <freetype/config/ftstdlib.h> in "zutil.h".
|
||||
|
||||
FONT_STUB_SRCS := \
|
||||
stub_font.cpp
|
||||
FREETYPE_SRCS := $(wildcard $(PATH_INTERNAL_C)/parts/video/font/freetype/*.c)
|
||||
|
||||
FREETYPE_OBJS := $(patsubst %.c,$(PATH_INTERNAL_C)/parts/video/font/%.o,$(FREETYPE_SRCS))
|
||||
FREETYPE_INCLUDE := -I$(PATH_INTERNAL_C)/parts/video/font/freetype/include
|
||||
|
||||
FREETYPE_OBJS := $(FREETYPE_SRCS:.c=.o)
|
||||
|
||||
FREETYPE_LIB := $(PATH_INTERNAL_C)/parts/video/font/freetype/freetype.a
|
||||
|
||||
FONT_SRCS := font.cpp
|
||||
FONT_STUB_SRCS := stub_font.cpp
|
||||
|
||||
FONT_OBJS := $(patsubst %.cpp,$(PATH_INTERNAL_C)/parts/video/font/%.o,$(FONT_SRCS))
|
||||
|
||||
FONT_STUB_OBJS := $(patsubst %.cpp,$(PATH_INTERNAL_C)/parts/video/font/%.o,$(FONT_STUB_SRCS))
|
||||
|
||||
$(PATH_INTERNAL_C)/parts/video/font/%.o: $(PATH_INTERNAL_C)/parts/video/font/%.c
|
||||
$(CC) -O2 $(CFLAGS) -DDEPENDENCY_CONSOLE_ONLY -Wall $< -c -o $@
|
||||
|
||||
$(PATH_INTERNAL_C)/parts/video/font/%.o: $(PATH_INTERNAL_C)/parts/video/font/%.cpp
|
||||
$(CXX) -O2 $(CXXFLAGS) -DDEPENDENCY_CONSOLE_ONLY -Wall $< -c -o $@
|
||||
$(CXX) -O2 $(CXXFLAGS) $(FREETYPE_INCLUDE) -DDEPENDENCY_CONSOLE_ONLY -Wall $< -c -o $@
|
||||
|
||||
CLEAN_LIST += $(FREETYPE_OBJS) $(FONT_OBJS) $(FONT_STUB_OBJS)
|
||||
$(PATH_INTERNAL_C)/parts/video/font/freetype/%.o: $(PATH_INTERNAL_C)/parts/video/font/freetype/%.c
|
||||
$(CC) -O3 $(CFLAGS) $(FREETYPE_INCLUDE) -DFT2_BUILD_LIBRARY -Wall $< -c -o $@
|
||||
|
||||
$(FREETYPE_LIB): $(FREETYPE_OBJS)
|
||||
$(AR) rcs $@ $(FREETYPE_OBJS)
|
||||
|
||||
FREETYPE_EXE_LIBS := $(FREETYPE_LIB)
|
||||
|
||||
CLEAN_LIST += $(FREETYPE_LIB) $(FREETYPE_OBJS) $(FONT_OBJS) $(FONT_STUB_OBJS)
|
||||
|
|
|
@ -6,13 +6,14 @@
|
|||
#define FONT_DEBUG 0
|
||||
#include "font.h"
|
||||
#include "../../../libqb.h"
|
||||
#include "freetypeamalgam.h"
|
||||
#include "gui.h"
|
||||
#include "image.h"
|
||||
#include "libqb-common.h"
|
||||
#include "mutex.h"
|
||||
#include "rounding.h"
|
||||
#include <cstdio>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
|
|
192
internal/c/parts/video/font/freetype/adler32.c
Normal file
192
internal/c/parts/video/font/freetype/adler32.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||
* Copyright (C) 1995-2011, 2016 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#include "zutil.h"
|
||||
|
||||
#ifndef Z_FREETYPE
|
||||
local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
|
||||
#endif
|
||||
|
||||
#define BASE 65521U /* largest prime smaller than 65536 */
|
||||
#define NMAX 5552
|
||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
|
||||
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
|
||||
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
||||
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware --
|
||||
try it both ways to see which is faster */
|
||||
#ifdef NO_DIVIDE
|
||||
/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
|
||||
(thank you to John Reiser for pointing this out) */
|
||||
# define CHOP(a) \
|
||||
do { \
|
||||
unsigned long tmp = a >> 16; \
|
||||
a &= 0xffffUL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
} while (0)
|
||||
# define MOD28(a) \
|
||||
do { \
|
||||
CHOP(a); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
# define MOD(a) \
|
||||
do { \
|
||||
CHOP(a); \
|
||||
MOD28(a); \
|
||||
} while (0)
|
||||
# define MOD63(a) \
|
||||
do { /* this assumes a is not negative */ \
|
||||
z_off64_t tmp = a >> 32; \
|
||||
a &= 0xffffffffL; \
|
||||
a += (tmp << 8) - (tmp << 5) + tmp; \
|
||||
tmp = a >> 16; \
|
||||
a &= 0xffffL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
tmp = a >> 16; \
|
||||
a &= 0xffffL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
#else
|
||||
# define MOD(a) a %= BASE
|
||||
# define MOD28(a) a %= BASE
|
||||
# define MOD63(a) a %= BASE
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32_z(
|
||||
uLong adler,
|
||||
const Bytef *buf,
|
||||
z_size_t len)
|
||||
{
|
||||
unsigned long sum2;
|
||||
unsigned n;
|
||||
|
||||
/* split Adler-32 into component sums */
|
||||
sum2 = (adler >> 16) & 0xffff;
|
||||
adler &= 0xffff;
|
||||
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
if (len == 1) {
|
||||
adler += buf[0];
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
sum2 += adler;
|
||||
if (sum2 >= BASE)
|
||||
sum2 -= BASE;
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* initial Adler-32 value (deferred check for len == 1 speed) */
|
||||
if (buf == Z_NULL)
|
||||
return 1L;
|
||||
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
if (len < 16) {
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
MOD28(sum2); /* only added so many BASE's */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while (len >= NMAX) {
|
||||
len -= NMAX;
|
||||
n = NMAX / 16; /* NMAX is divisible by 16 */
|
||||
do {
|
||||
DO16(buf); /* 16 sums unrolled */
|
||||
buf += 16;
|
||||
} while (--n);
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if (len) { /* avoid modulos if none remaining */
|
||||
while (len >= 16) {
|
||||
len -= 16;
|
||||
DO16(buf);
|
||||
buf += 16;
|
||||
}
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* return recombined sums */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32(
|
||||
uLong adler,
|
||||
const Bytef *buf,
|
||||
uInt len)
|
||||
{
|
||||
return adler32_z(adler, buf, len);
|
||||
}
|
||||
|
||||
#ifndef Z_FREETYPE
|
||||
|
||||
/* ========================================================================= */
|
||||
local uLong adler32_combine_(
|
||||
uLong adler1,
|
||||
uLong adler2,
|
||||
z_off64_t len2)
|
||||
{
|
||||
unsigned long sum1;
|
||||
unsigned long sum2;
|
||||
unsigned rem;
|
||||
|
||||
/* for negative len, return invalid adler32 as a clue for debugging */
|
||||
if (len2 < 0)
|
||||
return 0xffffffffUL;
|
||||
|
||||
/* the derivation of this formula is left as an exercise for the reader */
|
||||
MOD63(len2); /* assumes len2 >= 0 */
|
||||
rem = (unsigned)len2;
|
||||
sum1 = adler1 & 0xffff;
|
||||
sum2 = rem * sum1;
|
||||
MOD(sum2);
|
||||
sum1 += (adler2 & 0xffff) + BASE - 1;
|
||||
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
|
||||
if (sum1 >= BASE) sum1 -= BASE;
|
||||
if (sum1 >= BASE) sum1 -= BASE;
|
||||
if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
|
||||
if (sum2 >= BASE) sum2 -= BASE;
|
||||
return sum1 | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32_combine(
|
||||
uLong adler1,
|
||||
uLong adler2,
|
||||
z_off_t len2)
|
||||
{
|
||||
return adler32_combine_(adler1, adler2, len2);
|
||||
}
|
||||
|
||||
uLong ZEXPORT adler32_combine64(
|
||||
uLong adler1,
|
||||
uLong adler2,
|
||||
z_off64_t len2)
|
||||
{
|
||||
return adler32_combine_(adler1, adler2, len2);
|
||||
}
|
||||
|
||||
#endif /* !Z_FREETYPE */
|
779
internal/c/parts/video/font/freetype/afblue.c
Normal file
779
internal/c/parts/video/font/freetype/afblue.c
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-2023 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 */
|
429
internal/c/parts/video/font/freetype/afblue.h
Normal file
429
internal/c/parts/video/font/freetype/afblue.h
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-2023 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 */
|
2383
internal/c/parts/video/font/freetype/afcjk.c
Normal file
2383
internal/c/parts/video/font/freetype/afcjk.c
Normal file
File diff suppressed because it is too large
Load diff
141
internal/c/parts/video/font/freetype/afcjk.h
Normal file
141
internal/c/parts/video/font/freetype/afcjk.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afcjk.h
|
||||
*
|
||||
* Auto-fitter hinting routines for CJK writing system (specification).
|
||||
*
|
||||
* Copyright (C) 2006-2023 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];
|
||||
|
||||
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
internal/c/parts/video/font/freetype/afcover.h
Normal file
105
internal/c/parts/video/font/freetype/afcover.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afcover.h
|
||||
*
|
||||
* Auto-fitter coverages (specification only).
|
||||
*
|
||||
* Copyright (C) 2013-2023 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
internal/c/parts/video/font/freetype/afdummy.c
Normal file
77
internal/c/parts/video/font/freetype/afdummy.c
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-2023 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
internal/c/parts/video/font/freetype/afdummy.h
Normal file
40
internal/c/parts/video/font/freetype/afdummy.h
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-2023 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
internal/c/parts/video/font/freetype/aferrors.h
Normal file
42
internal/c/parts/video/font/freetype/aferrors.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* aferrors.h
|
||||
*
|
||||
* Autofitter error codes (specification only).
|
||||
*
|
||||
* Copyright (C) 2005-2023 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
internal/c/parts/video/font/freetype/afglobal.c
Normal file
513
internal/c/parts/video/font/freetype/afglobal.c
Normal file
|
@ -0,0 +1,513 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afglobal.c
|
||||
*
|
||||
* Auto-fitter routines to compute global hinting values (body).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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
internal/c/parts/video/font/freetype/afglobal.h
Normal file
173
internal/c/parts/video/font/freetype/afglobal.h
Normal file
|
@ -0,0 +1,173 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afglobal.h
|
||||
*
|
||||
* Auto-fitter routines to compute global hinting values
|
||||
* (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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
internal/c/parts/video/font/freetype/afhints.c
Normal file
1796
internal/c/parts/video/font/freetype/afhints.c
Normal file
File diff suppressed because it is too large
Load diff
467
internal/c/parts/video/font/freetype/afhints.h
Normal file
467
internal/c/parts/video/font/freetype/afhints.h
Normal file
|
@ -0,0 +1,467 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afhints.h
|
||||
*
|
||||
* Auto-fitter hinting routines (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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
internal/c/parts/video/font/freetype/afindic.c
Normal file
157
internal/c/parts/video/font/freetype/afindic.c
Normal file
|
@ -0,0 +1,157 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afindic.c
|
||||
*
|
||||
* Auto-fitter hinting routines for Indic writing system (body).
|
||||
*
|
||||
* Copyright (C) 2007-2023 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
internal/c/parts/video/font/freetype/afindic.h
Normal file
41
internal/c/parts/video/font/freetype/afindic.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afindic.h
|
||||
*
|
||||
* Auto-fitter hinting routines for Indic writing system
|
||||
* (specification).
|
||||
*
|
||||
* Copyright (C) 2007-2023 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 */
|
3644
internal/c/parts/video/font/freetype/aflatin.c
Normal file
3644
internal/c/parts/video/font/freetype/aflatin.c
Normal file
File diff suppressed because it is too large
Load diff
194
internal/c/parts/video/font/freetype/aflatin.h
Normal file
194
internal/c/parts/video/font/freetype/aflatin.h
Normal file
|
@ -0,0 +1,194 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* aflatin.h
|
||||
*
|
||||
* Auto-fitter hinting routines for latin writing system
|
||||
* (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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];
|
||||
|
||||
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
internal/c/parts/video/font/freetype/afloader.c
Normal file
706
internal/c/parts/video/font/freetype/afloader.c
Normal file
|
@ -0,0 +1,706 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afloader.c
|
||||
*
|
||||
* Auto-fitter glyph loading routines (body).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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
internal/c/parts/video/font/freetype/afloader.h
Normal file
91
internal/c/parts/video/font/freetype/afloader.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afloader.h
|
||||
*
|
||||
* Auto-fitter glyph loading routines (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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
internal/c/parts/video/font/freetype/afmodule.c
Normal file
527
internal/c/parts/video/font/freetype/afmodule.c
Normal file
|
@ -0,0 +1,527 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afmodule.c
|
||||
*
|
||||
* Auto-fitter module implementation (body).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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.library->memory;
|
||||
|
||||
#ifdef FT_DEBUG_AUTOFIT
|
||||
|
||||
/* in debug mode, we use a global object that survives this routine */
|
||||
|
||||
AF_GlyphHints hints = af_debug_hints_rec_;
|
||||
AF_LoaderRec loader[1];
|
||||
|
||||
FT_UNUSED( size );
|
||||
|
||||
|
||||
if ( hints->memory )
|
||||
af_glyph_hints_done( hints );
|
||||
|
||||
af_glyph_hints_init( hints, memory );
|
||||
af_loader_init( loader, hints );
|
||||
|
||||
error = af_loader_load_glyph( loader, module, slot->face,
|
||||
glyph_index, load_flags );
|
||||
|
||||
#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
internal/c/parts/video/font/freetype/afmodule.h
Normal file
55
internal/c/parts/video/font/freetype/afmodule.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afmodule.h
|
||||
*
|
||||
* Auto-fitter module implementation (specification).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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 */
|
1094
internal/c/parts/video/font/freetype/afmparse.c
Normal file
1094
internal/c/parts/video/font/freetype/afmparse.c
Normal file
File diff suppressed because it is too large
Load diff
88
internal/c/parts/video/font/freetype/afmparse.h
Normal file
88
internal/c/parts/video/font/freetype/afmparse.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afmparse.h
|
||||
*
|
||||
* AFM parser (specification).
|
||||
*
|
||||
* Copyright (C) 2006-2023 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 AFMPARSE_H_
|
||||
#define AFMPARSE_H_
|
||||
|
||||
|
||||
#include <freetype/internal/psaux.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
afm_parser_init( AFM_Parser parser,
|
||||
FT_Memory memory,
|
||||
FT_Byte* base,
|
||||
FT_Byte* limit );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
afm_parser_done( AFM_Parser parser );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
afm_parser_parse( AFM_Parser parser );
|
||||
|
||||
|
||||
enum AFM_ValueType_
|
||||
{
|
||||
AFM_VALUE_TYPE_STRING,
|
||||
AFM_VALUE_TYPE_NAME,
|
||||
AFM_VALUE_TYPE_FIXED, /* real number */
|
||||
AFM_VALUE_TYPE_INTEGER,
|
||||
AFM_VALUE_TYPE_BOOL,
|
||||
AFM_VALUE_TYPE_INDEX /* glyph index */
|
||||
};
|
||||
|
||||
|
||||
typedef struct AFM_ValueRec_
|
||||
{
|
||||
enum AFM_ValueType_ type;
|
||||
union
|
||||
{
|
||||
char* s;
|
||||
FT_Fixed f;
|
||||
FT_Int i;
|
||||
FT_UInt u;
|
||||
FT_Bool b;
|
||||
|
||||
} u;
|
||||
|
||||
} AFM_ValueRec, *AFM_Value;
|
||||
|
||||
#define AFM_MAX_ARGUMENTS 5
|
||||
|
||||
FT_LOCAL( FT_Int )
|
||||
afm_parser_read_vals( AFM_Parser parser,
|
||||
AFM_Value vals,
|
||||
FT_Int n );
|
||||
|
||||
/* read the next key from the next line or column */
|
||||
FT_LOCAL( char* )
|
||||
afm_parser_next_key( AFM_Parser parser,
|
||||
FT_Bool line,
|
||||
FT_Offset* len );
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* AFMPARSE_H_ */
|
||||
|
||||
|
||||
/* END */
|
1072
internal/c/parts/video/font/freetype/afranges.c
Normal file
1072
internal/c/parts/video/font/freetype/afranges.c
Normal file
File diff suppressed because it is too large
Load diff
47
internal/c/parts/video/font/freetype/afranges.h
Normal file
47
internal/c/parts/video/font/freetype/afranges.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afranges.h
|
||||
*
|
||||
* Auto-fitter Unicode script ranges (specification).
|
||||
*
|
||||
* Copyright (C) 2013-2023 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
internal/c/parts/video/font/freetype/afscript.h
Normal file
408
internal/c/parts/video/font/freetype/afscript.h
Normal file
|
@ -0,0 +1,408 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afscript.h
|
||||
*
|
||||
* Auto-fitter scripts (specification only).
|
||||
*
|
||||
* Copyright (C) 2013-2023 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
internal/c/parts/video/font/freetype/afshaper.c
Normal file
690
internal/c/parts/video/font/freetype/afshaper.c
Normal file
|
@ -0,0 +1,690 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afshaper.c
|
||||
*
|
||||
* HarfBuzz interface for accessing OpenType features (body).
|
||||
*
|
||||
* Copyright (C) 2013-2023 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
internal/c/parts/video/font/freetype/afshaper.h
Normal file
71
internal/c/parts/video/font/freetype/afshaper.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afshaper.h
|
||||
*
|
||||
* HarfBuzz interface for accessing OpenType features (specification).
|
||||
*
|
||||
* Copyright (C) 2013-2023 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
internal/c/parts/video/font/freetype/afstyles.h
Normal file
487
internal/c/parts/video/font/freetype/afstyles.h
Normal file
|
@ -0,0 +1,487 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afstyles.h
|
||||
*
|
||||
* Auto-fitter styles (specification only).
|
||||
*
|
||||
* Copyright (C) 2013-2023 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
internal/c/parts/video/font/freetype/aftypes.h
Normal file
511
internal/c/parts/video/font/freetype/aftypes.h
Normal file
|
@ -0,0 +1,511 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* aftypes.h
|
||||
*
|
||||
* Auto-fitter types (specification only).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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
internal/c/parts/video/font/freetype/afws-decl.h
Normal file
33
internal/c/parts/video/font/freetype/afws-decl.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afws-decl.h
|
||||
*
|
||||
* Auto-fitter writing system declarations (specification only).
|
||||
*
|
||||
* Copyright (C) 2013-2023 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
internal/c/parts/video/font/freetype/afws-iter.h
Normal file
31
internal/c/parts/video/font/freetype/afws-iter.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afws-iter.h
|
||||
*
|
||||
* Auto-fitter writing systems iterator (specification only).
|
||||
*
|
||||
* Copyright (C) 2013-2023 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 */
|
253
internal/c/parts/video/font/freetype/bdf.h
Normal file
253
internal/c/parts/video/font/freetype/bdf.h
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
internal/c/parts/video/font/freetype/bdfdrivr.c
Normal file
1013
internal/c/parts/video/font/freetype/bdfdrivr.c
Normal file
File diff suppressed because it is too large
Load diff
72
internal/c/parts/video/font/freetype/bdfdrivr.h
Normal file
72
internal/c/parts/video/font/freetype/bdfdrivr.h
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
internal/c/parts/video/font/freetype/bdferror.h
Normal file
45
internal/c/parts/video/font/freetype/bdferror.h
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 */
|
2387
internal/c/parts/video/font/freetype/bdflib.c
Normal file
2387
internal/c/parts/video/font/freetype/bdflib.c
Normal file
File diff suppressed because it is too large
Load diff
230
internal/c/parts/video/font/freetype/cffcmap.c
Normal file
230
internal/c/parts/video/font/freetype/cffcmap.c
Normal file
|
@ -0,0 +1,230 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cffcmap.c
|
||||
*
|
||||
* CFF character mapping table (cmap) support (body).
|
||||
*
|
||||
* Copyright (C) 2002-2023 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 "cffcmap.h"
|
||||
#include "cffload.h"
|
||||
|
||||
#include "cfferrs.h"
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CFF STANDARD (AND EXPERT) ENCODING CMAPS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cff_cmap_encoding_init( FT_CMap cmap,
|
||||
FT_Pointer pointer )
|
||||
{
|
||||
CFF_CMapStd cffcmap = (CFF_CMapStd)cmap;
|
||||
TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
|
||||
CFF_Font cff = (CFF_Font)face->extra.data;
|
||||
CFF_Encoding encoding = &cff->encoding;
|
||||
|
||||
FT_UNUSED( pointer );
|
||||
|
||||
|
||||
cffcmap->gids = encoding->codes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
cff_cmap_encoding_done( FT_CMap cmap )
|
||||
{
|
||||
CFF_CMapStd cffcmap = (CFF_CMapStd)cmap;
|
||||
|
||||
|
||||
cffcmap->gids = NULL;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_UInt )
|
||||
cff_cmap_encoding_char_index( FT_CMap cmap,
|
||||
FT_UInt32 char_code )
|
||||
{
|
||||
CFF_CMapStd cffcmap = (CFF_CMapStd)cmap;
|
||||
FT_UInt result = 0;
|
||||
|
||||
|
||||
if ( char_code < 256 )
|
||||
result = cffcmap->gids[char_code];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_UInt )
|
||||
cff_cmap_encoding_char_next( FT_CMap cmap,
|
||||
FT_UInt32 *pchar_code )
|
||||
{
|
||||
CFF_CMapStd cffcmap = (CFF_CMapStd)cmap;
|
||||
FT_UInt result = 0;
|
||||
FT_UInt32 char_code = *pchar_code;
|
||||
|
||||
|
||||
while ( char_code < 255 )
|
||||
{
|
||||
result = cffcmap->gids[++char_code];
|
||||
if ( result )
|
||||
{
|
||||
*pchar_code = char_code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_DEFINE_CMAP_CLASS(
|
||||
cff_cmap_encoding_class_rec,
|
||||
|
||||
sizeof ( CFF_CMapStdRec ),
|
||||
|
||||
(FT_CMap_InitFunc) cff_cmap_encoding_init, /* init */
|
||||
(FT_CMap_DoneFunc) cff_cmap_encoding_done, /* done */
|
||||
(FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, /* char_index */
|
||||
(FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, /* char_next */
|
||||
|
||||
(FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
|
||||
(FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
|
||||
(FT_CMap_VariantListFunc) NULL, /* variant_list */
|
||||
(FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
|
||||
(FT_CMap_VariantCharListFunc) NULL /* variantchar_list */
|
||||
)
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
FT_CALLBACK_DEF( const char* )
|
||||
cff_sid_to_glyph_name( void* face_, /* TT_Face */
|
||||
FT_UInt idx )
|
||||
{
|
||||
TT_Face face = (TT_Face)face_;
|
||||
CFF_Font cff = (CFF_Font)face->extra.data;
|
||||
CFF_Charset charset = &cff->charset;
|
||||
FT_UInt sid = charset->sids[idx];
|
||||
|
||||
|
||||
return cff_index_get_sid_string( cff, sid );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cff_cmap_unicode_init( FT_CMap cmap, /* PS_Unicodes */
|
||||
FT_Pointer pointer )
|
||||
{
|
||||
PS_Unicodes unicodes = (PS_Unicodes)cmap;
|
||||
TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
|
||||
FT_Memory memory = FT_FACE_MEMORY( face );
|
||||
CFF_Font cff = (CFF_Font)face->extra.data;
|
||||
CFF_Charset charset = &cff->charset;
|
||||
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
|
||||
|
||||
FT_UNUSED( pointer );
|
||||
|
||||
|
||||
/* can't build Unicode map for CID-keyed font */
|
||||
/* because we don't know glyph names. */
|
||||
if ( !charset->sids )
|
||||
return FT_THROW( No_Unicode_Glyph_Name );
|
||||
|
||||
if ( !psnames->unicodes_init )
|
||||
return FT_THROW( Unimplemented_Feature );
|
||||
|
||||
return psnames->unicodes_init( memory,
|
||||
unicodes,
|
||||
cff->num_glyphs,
|
||||
&cff_sid_to_glyph_name,
|
||||
(PS_FreeGlyphNameFunc)NULL,
|
||||
(FT_Pointer)face );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
cff_cmap_unicode_done( FT_CMap cmap ) /* PS_Unicodes */
|
||||
{
|
||||
PS_Unicodes unicodes = (PS_Unicodes)cmap;
|
||||
FT_Face face = FT_CMAP_FACE( cmap );
|
||||
FT_Memory memory = FT_FACE_MEMORY( face );
|
||||
|
||||
|
||||
FT_FREE( unicodes->maps );
|
||||
unicodes->num_maps = 0;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_UInt )
|
||||
cff_cmap_unicode_char_index( FT_CMap cmap, /* PS_Unicodes */
|
||||
FT_UInt32 char_code )
|
||||
{
|
||||
PS_Unicodes unicodes = (PS_Unicodes)cmap;
|
||||
TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
|
||||
CFF_Font cff = (CFF_Font)face->extra.data;
|
||||
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
|
||||
|
||||
|
||||
return psnames->unicodes_char_index( unicodes, char_code );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_UInt )
|
||||
cff_cmap_unicode_char_next( FT_CMap cmap, /* PS_Unicodes */
|
||||
FT_UInt32 *pchar_code )
|
||||
{
|
||||
PS_Unicodes unicodes = (PS_Unicodes)cmap;
|
||||
TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
|
||||
CFF_Font cff = (CFF_Font)face->extra.data;
|
||||
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
|
||||
|
||||
|
||||
return psnames->unicodes_char_next( unicodes, pchar_code );
|
||||
}
|
||||
|
||||
|
||||
FT_DEFINE_CMAP_CLASS(
|
||||
cff_cmap_unicode_class_rec,
|
||||
|
||||
sizeof ( PS_UnicodesRec ),
|
||||
|
||||
(FT_CMap_InitFunc) cff_cmap_unicode_init, /* init */
|
||||
(FT_CMap_DoneFunc) cff_cmap_unicode_done, /* done */
|
||||
(FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, /* char_index */
|
||||
(FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, /* char_next */
|
||||
|
||||
(FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
|
||||
(FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
|
||||
(FT_CMap_VariantListFunc) NULL, /* variant_list */
|
||||
(FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
|
||||
(FT_CMap_VariantCharListFunc) NULL /* variantchar_list */
|
||||
)
|
||||
|
||||
|
||||
/* END */
|
67
internal/c/parts/video/font/freetype/cffcmap.h
Normal file
67
internal/c/parts/video/font/freetype/cffcmap.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cffcmap.h
|
||||
*
|
||||
* CFF character mapping table (cmap) support (specification).
|
||||
*
|
||||
* Copyright (C) 2002-2023 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 CFFCMAP_H_
|
||||
#define CFFCMAP_H_
|
||||
|
||||
#include <freetype/internal/cffotypes.h>
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* standard (and expert) encoding cmaps */
|
||||
typedef struct CFF_CMapStdRec_* CFF_CMapStd;
|
||||
|
||||
typedef struct CFF_CMapStdRec_
|
||||
{
|
||||
FT_CMapRec cmap;
|
||||
FT_UShort* gids; /* up to 256 elements */
|
||||
|
||||
} CFF_CMapStdRec;
|
||||
|
||||
|
||||
FT_DECLARE_CMAP_CLASS( cff_cmap_encoding_class_rec )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* unicode (synthetic) cmaps */
|
||||
|
||||
FT_DECLARE_CMAP_CLASS( cff_cmap_unicode_class_rec )
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CFFCMAP_H_ */
|
||||
|
||||
|
||||
/* END */
|
2423
internal/c/parts/video/font/freetype/cffdecode.c
Normal file
2423
internal/c/parts/video/font/freetype/cffdecode.c
Normal file
File diff suppressed because it is too large
Load diff
63
internal/c/parts/video/font/freetype/cffdecode.h
Normal file
63
internal/c/parts/video/font/freetype/cffdecode.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cffdecode.h
|
||||
*
|
||||
* PostScript CFF (Type 2) decoding routines (specification).
|
||||
*
|
||||
* Copyright (C) 2017-2023 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 CFFDECODE_H_
|
||||
#define CFFDECODE_H_
|
||||
|
||||
|
||||
#include <freetype/internal/psaux.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
FT_LOCAL( void )
|
||||
cff_decoder_init( CFF_Decoder* decoder,
|
||||
TT_Face face,
|
||||
CFF_Size size,
|
||||
CFF_GlyphSlot slot,
|
||||
FT_Bool hinting,
|
||||
FT_Render_Mode hint_mode,
|
||||
CFF_Decoder_Get_Glyph_Callback get_callback,
|
||||
CFF_Decoder_Free_Glyph_Callback free_callback );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_decoder_prepare( CFF_Decoder* decoder,
|
||||
CFF_Size size,
|
||||
FT_UInt glyph_index );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Int )
|
||||
cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
|
||||
FT_Int charcode );
|
||||
|
||||
|
||||
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_decoder_parse_charstrings( CFF_Decoder* decoder,
|
||||
FT_Byte* charstring_base,
|
||||
FT_ULong charstring_len,
|
||||
FT_Bool in_dict );
|
||||
#endif
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* END */
|
1263
internal/c/parts/video/font/freetype/cffdrivr.c
Normal file
1263
internal/c/parts/video/font/freetype/cffdrivr.c
Normal file
File diff suppressed because it is too large
Load diff
35
internal/c/parts/video/font/freetype/cffdrivr.h
Normal file
35
internal/c/parts/video/font/freetype/cffdrivr.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cffdrivr.h
|
||||
*
|
||||
* High-level OpenType driver interface (specification).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 CFFDRIVER_H_
|
||||
#define CFFDRIVER_H_
|
||||
|
||||
|
||||
#include <freetype/internal/ftdrv.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
FT_DECLARE_DRIVER( cff_driver_class )
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CFFDRIVER_H_ */
|
||||
|
||||
|
||||
/* END */
|
42
internal/c/parts/video/font/freetype/cfferrs.h
Normal file
42
internal/c/parts/video/font/freetype/cfferrs.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cfferrs.h
|
||||
*
|
||||
* CFF error codes (specification only).
|
||||
*
|
||||
* Copyright (C) 2001-2023 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 CFF error enumeration constants.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CFFERRS_H_
|
||||
#define CFFERRS_H_
|
||||
|
||||
#include <freetype/ftmoderr.h>
|
||||
|
||||
#undef FTERRORS_H_
|
||||
|
||||
#undef FT_ERR_PREFIX
|
||||
#define FT_ERR_PREFIX CFF_Err_
|
||||
#define FT_ERR_BASE FT_Mod_Err_CFF
|
||||
|
||||
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
#endif /* CFFERRS_H_ */
|
||||
|
||||
|
||||
/* END */
|
762
internal/c/parts/video/font/freetype/cffgload.c
Normal file
762
internal/c/parts/video/font/freetype/cffgload.c
Normal file
|
@ -0,0 +1,762 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cffgload.c
|
||||
*
|
||||
* OpenType Glyph Loader (body).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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/ftstream.h>
|
||||
#include <freetype/internal/sfnt.h>
|
||||
#include <freetype/internal/ftcalc.h>
|
||||
#include <freetype/internal/psaux.h>
|
||||
#include <freetype/ftoutln.h>
|
||||
#include <freetype/ftdriver.h>
|
||||
|
||||
#include "cffload.h"
|
||||
#include "cffgload.h"
|
||||
|
||||
#include "cfferrs.h"
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
|
||||
#define IS_DEFAULT_INSTANCE( _face ) \
|
||||
( !( FT_IS_NAMED_INSTANCE( _face ) || \
|
||||
FT_IS_VARIATION( _face ) ) )
|
||||
#else
|
||||
#define IS_DEFAULT_INSTANCE( _face ) 1
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* 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 cffgload
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cff_get_glyph_data( TT_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_Byte** pointer,
|
||||
FT_ULong* length )
|
||||
{
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
/* For incremental fonts get the character data using the */
|
||||
/* callback function. */
|
||||
if ( face->root.internal->incremental_interface )
|
||||
{
|
||||
FT_Data data;
|
||||
FT_Error error =
|
||||
face->root.internal->incremental_interface->funcs->get_glyph_data(
|
||||
face->root.internal->incremental_interface->object,
|
||||
glyph_index, &data );
|
||||
|
||||
|
||||
*pointer = (FT_Byte*)data.pointer;
|
||||
*length = data.length;
|
||||
|
||||
return error;
|
||||
}
|
||||
else
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
|
||||
{
|
||||
CFF_Font cff = (CFF_Font)( face->extra.data );
|
||||
|
||||
|
||||
return cff_index_access_element( &cff->charstrings_index, glyph_index,
|
||||
pointer, length );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cff_free_glyph_data( TT_Face face,
|
||||
FT_Byte** pointer,
|
||||
FT_ULong length )
|
||||
{
|
||||
#ifndef FT_CONFIG_OPTION_INCREMENTAL
|
||||
FT_UNUSED( length );
|
||||
#endif
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
/* For incremental fonts get the character data using the */
|
||||
/* callback function. */
|
||||
if ( face->root.internal->incremental_interface )
|
||||
{
|
||||
FT_Data data;
|
||||
|
||||
|
||||
data.pointer = *pointer;
|
||||
data.length = (FT_UInt)length;
|
||||
|
||||
face->root.internal->incremental_interface->funcs->free_glyph_data(
|
||||
face->root.internal->incremental_interface->object, &data );
|
||||
}
|
||||
else
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
|
||||
{
|
||||
CFF_Font cff = (CFF_Font)( face->extra.data );
|
||||
|
||||
|
||||
cff_index_forget_element( &cff->charstrings_index, pointer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/********** *********/
|
||||
/********** *********/
|
||||
/********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
|
||||
/********** *********/
|
||||
/********** The following code is in charge of computing *********/
|
||||
/********** the maximum advance width of the font. It *********/
|
||||
/********** quickly processes each glyph charstring to *********/
|
||||
/********** extract the value from either a `sbw' or `seac' *********/
|
||||
/********** operator. *********/
|
||||
/********** *********/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#if 0 /* unused until we support pure CFF fonts */
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cff_compute_max_advance( TT_Face face,
|
||||
FT_Int* max_advance )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
CFF_Decoder decoder;
|
||||
FT_Int glyph_index;
|
||||
CFF_Font cff = (CFF_Font)face->other;
|
||||
|
||||
PSAux_Service psaux = (PSAux_Service)face->psaux;
|
||||
const CFF_Decoder_Funcs decoder_funcs = psaux->cff_decoder_funcs;
|
||||
|
||||
|
||||
*max_advance = 0;
|
||||
|
||||
/* Initialize load decoder */
|
||||
decoder_funcs->init( &decoder, face, 0, 0, 0, 0, 0, 0 );
|
||||
|
||||
decoder.builder.metrics_only = 1;
|
||||
decoder.builder.load_points = 0;
|
||||
|
||||
/* For each glyph, parse the glyph charstring and extract */
|
||||
/* the advance width. */
|
||||
for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
|
||||
glyph_index++ )
|
||||
{
|
||||
FT_Byte* charstring;
|
||||
FT_ULong charstring_len;
|
||||
|
||||
|
||||
/* now get load the unscaled outline */
|
||||
error = cff_get_glyph_data( face, glyph_index,
|
||||
&charstring, &charstring_len );
|
||||
if ( !error )
|
||||
{
|
||||
error = decoder_funcs->prepare( &decoder, size, glyph_index );
|
||||
if ( !error )
|
||||
error = decoder_funcs->parse_charstrings_old( &decoder,
|
||||
charstring,
|
||||
charstring_len,
|
||||
0 );
|
||||
|
||||
cff_free_glyph_data( face, &charstring, &charstring_len );
|
||||
}
|
||||
|
||||
/* ignore the error if one has occurred -- skip to next glyph */
|
||||
error = FT_Err_Ok;
|
||||
}
|
||||
|
||||
*max_advance = decoder.builder.advance.x;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cff_slot_load( CFF_GlyphSlot glyph,
|
||||
CFF_Size size,
|
||||
FT_UInt glyph_index,
|
||||
FT_Int32 load_flags )
|
||||
{
|
||||
FT_Error error;
|
||||
CFF_Decoder decoder;
|
||||
PS_Decoder psdecoder;
|
||||
TT_Face face = (TT_Face)glyph->root.face;
|
||||
FT_Bool hinting, scaled, force_scaling;
|
||||
CFF_Font cff = (CFF_Font)face->extra.data;
|
||||
|
||||
PSAux_Service psaux = (PSAux_Service)face->psaux;
|
||||
const CFF_Decoder_Funcs decoder_funcs = psaux->cff_decoder_funcs;
|
||||
|
||||
FT_Matrix font_matrix;
|
||||
FT_Vector font_offset;
|
||||
|
||||
|
||||
force_scaling = FALSE;
|
||||
|
||||
/* in a CID-keyed font, consider `glyph_index' as a CID and map */
|
||||
/* it immediately to the real glyph_index -- if it isn't a */
|
||||
/* subsetted font, glyph_indices and CIDs are identical, though */
|
||||
if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
|
||||
cff->charset.cids )
|
||||
{
|
||||
/* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
|
||||
if ( glyph_index != 0 )
|
||||
{
|
||||
glyph_index = cff_charset_cid_to_gindex( &cff->charset,
|
||||
glyph_index );
|
||||
if ( glyph_index == 0 )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
}
|
||||
}
|
||||
else if ( glyph_index >= cff->num_glyphs )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
if ( load_flags & FT_LOAD_NO_RECURSE )
|
||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
||||
|
||||
glyph->x_scale = 0x10000L;
|
||||
glyph->y_scale = 0x10000L;
|
||||
if ( size )
|
||||
{
|
||||
glyph->x_scale = size->root.metrics.x_scale;
|
||||
glyph->y_scale = size->root.metrics.y_scale;
|
||||
}
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
||||
|
||||
/* try to load embedded bitmap if any */
|
||||
/* */
|
||||
/* XXX: The convention should be emphasized in */
|
||||
/* the documents because it can be confusing. */
|
||||
if ( size )
|
||||
{
|
||||
CFF_Face cff_face = (CFF_Face)size->root.face;
|
||||
SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt;
|
||||
FT_Stream stream = cff_face->root.stream;
|
||||
|
||||
|
||||
if ( size->strike_index != 0xFFFFFFFFUL &&
|
||||
( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
|
||||
IS_DEFAULT_INSTANCE( size->root.face ) )
|
||||
{
|
||||
TT_SBit_MetricsRec metrics;
|
||||
|
||||
|
||||
error = sfnt->load_sbit_image( face,
|
||||
size->strike_index,
|
||||
glyph_index,
|
||||
(FT_UInt)load_flags,
|
||||
stream,
|
||||
&glyph->root.bitmap,
|
||||
&metrics );
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
FT_Bool has_vertical_info;
|
||||
FT_UShort advance;
|
||||
FT_Short dummy;
|
||||
|
||||
|
||||
glyph->root.outline.n_points = 0;
|
||||
glyph->root.outline.n_contours = 0;
|
||||
|
||||
glyph->root.metrics.width = (FT_Pos)metrics.width * 64;
|
||||
glyph->root.metrics.height = (FT_Pos)metrics.height * 64;
|
||||
|
||||
glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX * 64;
|
||||
glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY * 64;
|
||||
glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance * 64;
|
||||
|
||||
glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX * 64;
|
||||
glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY * 64;
|
||||
glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance * 64;
|
||||
|
||||
glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
|
||||
|
||||
if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
|
||||
{
|
||||
glyph->root.bitmap_left = metrics.vertBearingX;
|
||||
glyph->root.bitmap_top = metrics.vertBearingY;
|
||||
}
|
||||
else
|
||||
{
|
||||
glyph->root.bitmap_left = metrics.horiBearingX;
|
||||
glyph->root.bitmap_top = metrics.horiBearingY;
|
||||
}
|
||||
|
||||
/* compute linear advance widths */
|
||||
|
||||
(void)( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
|
||||
glyph_index,
|
||||
&dummy,
|
||||
&advance );
|
||||
glyph->root.linearHoriAdvance = advance;
|
||||
|
||||
has_vertical_info = FT_BOOL(
|
||||
face->vertical_info &&
|
||||
face->vertical.number_Of_VMetrics > 0 );
|
||||
|
||||
/* get the vertical metrics from the vmtx table if we have one */
|
||||
if ( has_vertical_info )
|
||||
{
|
||||
(void)( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
|
||||
glyph_index,
|
||||
&dummy,
|
||||
&advance );
|
||||
glyph->root.linearVertAdvance = advance;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* make up vertical ones */
|
||||
if ( face->os2.version != 0xFFFFU )
|
||||
glyph->root.linearVertAdvance = (FT_Pos)
|
||||
( face->os2.sTypoAscender - face->os2.sTypoDescender );
|
||||
else
|
||||
glyph->root.linearVertAdvance = (FT_Pos)
|
||||
( face->horizontal.Ascender - face->horizontal.Descender );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
||||
|
||||
/* return immediately if we only want the embedded bitmaps */
|
||||
if ( load_flags & FT_LOAD_SBITS_ONLY )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_SVG
|
||||
/* check for OT-SVG */
|
||||
if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 &&
|
||||
( load_flags & FT_LOAD_COLOR ) &&
|
||||
face->svg )
|
||||
{
|
||||
/*
|
||||
* We load the SVG document and try to grab the advances from the
|
||||
* table. For the bearings we rely on the presetting hook to do that.
|
||||
*/
|
||||
|
||||
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
|
||||
|
||||
|
||||
if ( size && (size->root.metrics.x_ppem < 1 ||
|
||||
size->root.metrics.y_ppem < 1 ) )
|
||||
{
|
||||
error = FT_THROW( Invalid_Size_Handle );
|
||||
return error;
|
||||
}
|
||||
|
||||
FT_TRACE3(( "Trying to load SVG glyph\n" ));
|
||||
|
||||
error = sfnt->load_svg_doc( (FT_GlyphSlot)glyph, glyph_index );
|
||||
if ( !error )
|
||||
{
|
||||
FT_Fixed x_scale = size->root.metrics.x_scale;
|
||||
FT_Fixed y_scale = size->root.metrics.y_scale;
|
||||
|
||||
FT_Short dummy;
|
||||
FT_UShort advanceX;
|
||||
FT_UShort advanceY;
|
||||
|
||||
|
||||
FT_TRACE3(( "Successfully loaded SVG glyph\n" ));
|
||||
|
||||
glyph->root.format = FT_GLYPH_FORMAT_SVG;
|
||||
|
||||
/*
|
||||
* If horizontal or vertical advances are not present in the table,
|
||||
* this is a problem with the font since the standard requires them.
|
||||
* However, we are graceful and calculate the values by ourselves
|
||||
* for the vertical case.
|
||||
*/
|
||||
sfnt->get_metrics( face,
|
||||
FALSE,
|
||||
glyph_index,
|
||||
&dummy,
|
||||
&advanceX );
|
||||
sfnt->get_metrics( face,
|
||||
TRUE,
|
||||
glyph_index,
|
||||
&dummy,
|
||||
&advanceY );
|
||||
|
||||
glyph->root.linearHoriAdvance = advanceX;
|
||||
glyph->root.linearVertAdvance = advanceY;
|
||||
|
||||
glyph->root.metrics.horiAdvance = FT_MulFix( advanceX, x_scale );
|
||||
glyph->root.metrics.vertAdvance = FT_MulFix( advanceY, y_scale );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FT_TRACE3(( "Failed to load SVG glyph\n" ));
|
||||
}
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_SVG */
|
||||
|
||||
/* if we have a CID subfont, use its matrix (which has already */
|
||||
/* been multiplied with the root matrix) */
|
||||
|
||||
/* this scaling is only relevant if the PS hinter isn't active */
|
||||
if ( cff->num_subfonts )
|
||||
{
|
||||
FT_Long top_upm, sub_upm;
|
||||
FT_Byte fd_index = cff_fd_select_get( &cff->fd_select,
|
||||
glyph_index );
|
||||
|
||||
|
||||
if ( fd_index >= cff->num_subfonts )
|
||||
fd_index = (FT_Byte)( cff->num_subfonts - 1 );
|
||||
|
||||
top_upm = (FT_Long)cff->top_font.font_dict.units_per_em;
|
||||
sub_upm = (FT_Long)cff->subfonts[fd_index]->font_dict.units_per_em;
|
||||
|
||||
font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
|
||||
font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
|
||||
|
||||
if ( top_upm != sub_upm )
|
||||
{
|
||||
glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm );
|
||||
glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm );
|
||||
|
||||
force_scaling = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
font_matrix = cff->top_font.font_dict.font_matrix;
|
||||
font_offset = cff->top_font.font_dict.font_offset;
|
||||
}
|
||||
|
||||
glyph->root.outline.n_points = 0;
|
||||
glyph->root.outline.n_contours = 0;
|
||||
|
||||
/* top-level code ensures that FT_LOAD_NO_HINTING is set */
|
||||
/* if FT_LOAD_NO_SCALE is active */
|
||||
hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
|
||||
scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
|
||||
|
||||
glyph->hint = hinting;
|
||||
glyph->scaled = scaled;
|
||||
glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */
|
||||
|
||||
{
|
||||
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
||||
PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face );
|
||||
#endif
|
||||
|
||||
FT_Byte* charstring;
|
||||
FT_ULong charstring_len;
|
||||
|
||||
|
||||
decoder_funcs->init( &decoder, face, size, glyph, hinting,
|
||||
FT_LOAD_TARGET_MODE( load_flags ),
|
||||
cff_get_glyph_data,
|
||||
cff_free_glyph_data );
|
||||
|
||||
/* this is for pure CFFs */
|
||||
if ( load_flags & FT_LOAD_ADVANCE_ONLY )
|
||||
decoder.width_only = TRUE;
|
||||
|
||||
decoder.builder.no_recurse =
|
||||
FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
|
||||
|
||||
/* this function also checks for a valid subfont index */
|
||||
error = decoder_funcs->prepare( &decoder, size, glyph_index );
|
||||
if ( error )
|
||||
goto Glyph_Build_Finished;
|
||||
|
||||
/* now load the unscaled outline */
|
||||
error = cff_get_glyph_data( face, glyph_index,
|
||||
&charstring, &charstring_len );
|
||||
if ( error )
|
||||
goto Glyph_Build_Finished;
|
||||
|
||||
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
||||
/* choose which CFF renderer to use */
|
||||
if ( driver->hinting_engine == FT_HINTING_FREETYPE )
|
||||
error = decoder_funcs->parse_charstrings_old( &decoder,
|
||||
charstring,
|
||||
charstring_len,
|
||||
0 );
|
||||
else
|
||||
#endif
|
||||
{
|
||||
psaux->ps_decoder_init( &psdecoder, &decoder, FALSE );
|
||||
|
||||
error = decoder_funcs->parse_charstrings( &psdecoder,
|
||||
charstring,
|
||||
charstring_len );
|
||||
|
||||
/* Adobe's engine uses 16.16 numbers everywhere; */
|
||||
/* as a consequence, glyphs larger than 2000ppem get rejected */
|
||||
if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
|
||||
{
|
||||
/* this time, we retry unhinted and scale up the glyph later on */
|
||||
/* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
|
||||
/* 0x400 for both `x_scale' and `y_scale' in this case) */
|
||||
hinting = FALSE;
|
||||
force_scaling = TRUE;
|
||||
glyph->hint = hinting;
|
||||
|
||||
error = decoder_funcs->parse_charstrings( &psdecoder,
|
||||
charstring,
|
||||
charstring_len );
|
||||
}
|
||||
}
|
||||
|
||||
cff_free_glyph_data( face, &charstring, charstring_len );
|
||||
|
||||
if ( error )
|
||||
goto Glyph_Build_Finished;
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
/* Control data and length may not be available for incremental */
|
||||
/* fonts. */
|
||||
if ( face->root.internal->incremental_interface )
|
||||
{
|
||||
glyph->root.control_data = NULL;
|
||||
glyph->root.control_len = 0;
|
||||
}
|
||||
else
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
|
||||
/* We set control_data and control_len if charstrings is loaded. */
|
||||
/* See how charstring loads at cff_index_access_element() in */
|
||||
/* cffload.c. */
|
||||
{
|
||||
CFF_Index csindex = &cff->charstrings_index;
|
||||
|
||||
|
||||
if ( csindex->offsets )
|
||||
{
|
||||
glyph->root.control_data = csindex->bytes +
|
||||
csindex->offsets[glyph_index] - 1;
|
||||
glyph->root.control_len = (FT_Long)charstring_len;
|
||||
}
|
||||
}
|
||||
|
||||
Glyph_Build_Finished:
|
||||
/* save new glyph tables, if no error */
|
||||
if ( !error )
|
||||
decoder.builder.funcs.done( &decoder.builder );
|
||||
/* XXX: anything to do for broken glyph entry? */
|
||||
}
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
|
||||
/* Incremental fonts can optionally override the metrics. */
|
||||
if ( !error &&
|
||||
face->root.internal->incremental_interface &&
|
||||
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
|
||||
{
|
||||
FT_Incremental_MetricsRec metrics;
|
||||
|
||||
|
||||
metrics.bearing_x = decoder.builder.left_bearing.x;
|
||||
metrics.bearing_y = 0;
|
||||
metrics.advance = decoder.builder.advance.x;
|
||||
metrics.advance_v = decoder.builder.advance.y;
|
||||
|
||||
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
|
||||
face->root.internal->incremental_interface->object,
|
||||
glyph_index, FALSE, &metrics );
|
||||
|
||||
decoder.builder.left_bearing.x = metrics.bearing_x;
|
||||
decoder.builder.advance.x = metrics.advance;
|
||||
decoder.builder.advance.y = metrics.advance_v;
|
||||
}
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
/* Now, set the metrics -- this is rather simple, as */
|
||||
/* the left side bearing is the xMin, and the top side */
|
||||
/* bearing the yMax. */
|
||||
|
||||
/* For composite glyphs, return only left side bearing and */
|
||||
/* advance width. */
|
||||
if ( load_flags & FT_LOAD_NO_RECURSE )
|
||||
{
|
||||
FT_Slot_Internal internal = glyph->root.internal;
|
||||
|
||||
|
||||
glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
|
||||
glyph->root.metrics.horiAdvance = decoder.glyph_width;
|
||||
internal->glyph_matrix = font_matrix;
|
||||
internal->glyph_delta = font_offset;
|
||||
internal->glyph_transformed = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_BBox cbox;
|
||||
FT_Glyph_Metrics* metrics = &glyph->root.metrics;
|
||||
FT_Bool has_vertical_info;
|
||||
|
||||
|
||||
if ( face->horizontal.number_Of_HMetrics )
|
||||
{
|
||||
FT_Short horiBearingX = 0;
|
||||
FT_UShort horiAdvance = 0;
|
||||
|
||||
|
||||
( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
|
||||
glyph_index,
|
||||
&horiBearingX,
|
||||
&horiAdvance );
|
||||
metrics->horiAdvance = horiAdvance;
|
||||
metrics->horiBearingX = horiBearingX;
|
||||
glyph->root.linearHoriAdvance = horiAdvance;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* copy the _unscaled_ advance width */
|
||||
metrics->horiAdvance = decoder.glyph_width;
|
||||
glyph->root.linearHoriAdvance = decoder.glyph_width;
|
||||
}
|
||||
|
||||
glyph->root.internal->glyph_transformed = 0;
|
||||
|
||||
has_vertical_info = FT_BOOL( face->vertical_info &&
|
||||
face->vertical.number_Of_VMetrics > 0 );
|
||||
|
||||
/* get the vertical metrics from the vmtx table if we have one */
|
||||
if ( has_vertical_info )
|
||||
{
|
||||
FT_Short vertBearingY = 0;
|
||||
FT_UShort vertAdvance = 0;
|
||||
|
||||
|
||||
( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
|
||||
glyph_index,
|
||||
&vertBearingY,
|
||||
&vertAdvance );
|
||||
metrics->vertBearingY = vertBearingY;
|
||||
metrics->vertAdvance = vertAdvance;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* make up vertical ones */
|
||||
if ( face->os2.version != 0xFFFFU )
|
||||
metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender -
|
||||
face->os2.sTypoDescender );
|
||||
else
|
||||
metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender -
|
||||
face->horizontal.Descender );
|
||||
}
|
||||
|
||||
glyph->root.linearVertAdvance = metrics->vertAdvance;
|
||||
|
||||
glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
|
||||
glyph->root.outline.flags = 0;
|
||||
if ( size && size->root.metrics.y_ppem < 24 )
|
||||
glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
|
||||
|
||||
glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
|
||||
|
||||
/* apply the font matrix, if any */
|
||||
if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
|
||||
font_matrix.xy != 0 || font_matrix.yx != 0 )
|
||||
{
|
||||
FT_Outline_Transform( &glyph->root.outline, &font_matrix );
|
||||
|
||||
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
|
||||
font_matrix.xx );
|
||||
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance,
|
||||
font_matrix.yy );
|
||||
}
|
||||
|
||||
if ( font_offset.x || font_offset.y )
|
||||
{
|
||||
FT_Outline_Translate( &glyph->root.outline,
|
||||
font_offset.x,
|
||||
font_offset.y );
|
||||
|
||||
metrics->horiAdvance += font_offset.x;
|
||||
metrics->vertAdvance += font_offset.y;
|
||||
}
|
||||
|
||||
if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
|
||||
{
|
||||
/* scale the outline and the metrics */
|
||||
FT_Int n;
|
||||
FT_Outline* cur = &glyph->root.outline;
|
||||
FT_Vector* vec = cur->points;
|
||||
FT_Fixed x_scale = glyph->x_scale;
|
||||
FT_Fixed y_scale = glyph->y_scale;
|
||||
|
||||
|
||||
/* First of all, scale the points */
|
||||
if ( !hinting || !decoder.builder.hints_funcs )
|
||||
for ( n = cur->n_points; n > 0; n--, vec++ )
|
||||
{
|
||||
vec->x = FT_MulFix( vec->x, x_scale );
|
||||
vec->y = FT_MulFix( vec->y, y_scale );
|
||||
}
|
||||
|
||||
/* Then scale the metrics */
|
||||
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
|
||||
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
|
||||
}
|
||||
|
||||
/* compute the other metrics */
|
||||
FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
|
||||
|
||||
metrics->width = cbox.xMax - cbox.xMin;
|
||||
metrics->height = cbox.yMax - cbox.yMin;
|
||||
|
||||
metrics->horiBearingX = cbox.xMin;
|
||||
metrics->horiBearingY = cbox.yMax;
|
||||
|
||||
if ( has_vertical_info )
|
||||
{
|
||||
metrics->vertBearingX = metrics->horiBearingX -
|
||||
metrics->horiAdvance / 2;
|
||||
metrics->vertBearingY = FT_MulFix( metrics->vertBearingY,
|
||||
glyph->y_scale );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
|
||||
ft_synthesize_vertical_metrics( metrics,
|
||||
metrics->vertAdvance );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
62
internal/c/parts/video/font/freetype/cffgload.h
Normal file
62
internal/c/parts/video/font/freetype/cffgload.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cffgload.h
|
||||
*
|
||||
* OpenType Glyph Loader (specification).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 CFFGLOAD_H_
|
||||
#define CFFGLOAD_H_
|
||||
|
||||
|
||||
#include <freetype/freetype.h>
|
||||
#include <freetype/internal/cffotypes.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_get_glyph_data( TT_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_Byte** pointer,
|
||||
FT_ULong* length );
|
||||
FT_LOCAL( void )
|
||||
cff_free_glyph_data( TT_Face face,
|
||||
FT_Byte** pointer,
|
||||
FT_ULong length );
|
||||
|
||||
|
||||
#if 0 /* unused until we support pure CFF fonts */
|
||||
|
||||
/* Compute the maximum advance width of a font through quick parsing */
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_compute_max_advance( TT_Face face,
|
||||
FT_Int* max_advance );
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_slot_load( CFF_GlyphSlot glyph,
|
||||
CFF_Size size,
|
||||
FT_UInt glyph_index,
|
||||
FT_Int32 load_flags );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CFFGLOAD_H_ */
|
||||
|
||||
|
||||
/* END */
|
2579
internal/c/parts/video/font/freetype/cffload.c
Normal file
2579
internal/c/parts/video/font/freetype/cffload.c
Normal file
File diff suppressed because it is too large
Load diff
124
internal/c/parts/video/font/freetype/cffload.h
Normal file
124
internal/c/parts/video/font/freetype/cffload.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cffload.h
|
||||
*
|
||||
* OpenType & CFF data/program tables loader (specification).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 CFFLOAD_H_
|
||||
#define CFFLOAD_H_
|
||||
|
||||
|
||||
#include <freetype/internal/cfftypes.h>
|
||||
#include "cffparse.h"
|
||||
#include <freetype/internal/cffotypes.h> /* for CFF_Face */
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
FT_LOCAL( FT_UShort )
|
||||
cff_get_standard_encoding( FT_UInt charcode );
|
||||
|
||||
|
||||
FT_LOCAL( FT_String* )
|
||||
cff_index_get_string( CFF_Font font,
|
||||
FT_UInt element );
|
||||
|
||||
FT_LOCAL( FT_String* )
|
||||
cff_index_get_sid_string( CFF_Font font,
|
||||
FT_UInt sid );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_index_access_element( CFF_Index idx,
|
||||
FT_UInt element,
|
||||
FT_Byte** pbytes,
|
||||
FT_ULong* pbyte_len );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cff_index_forget_element( CFF_Index idx,
|
||||
FT_Byte** pbytes );
|
||||
|
||||
FT_LOCAL( FT_String* )
|
||||
cff_index_get_name( CFF_Font font,
|
||||
FT_UInt element );
|
||||
|
||||
|
||||
FT_LOCAL( FT_UInt )
|
||||
cff_charset_cid_to_gindex( CFF_Charset charset,
|
||||
FT_UInt cid );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_font_load( FT_Library library,
|
||||
FT_Stream stream,
|
||||
FT_Int face_index,
|
||||
CFF_Font font,
|
||||
CFF_Face face,
|
||||
FT_Bool pure_cff,
|
||||
FT_Bool cff2 );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cff_font_done( CFF_Font font );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_load_private_dict( CFF_Font font,
|
||||
CFF_SubFont subfont,
|
||||
FT_UInt lenNDV,
|
||||
FT_Fixed* NDV );
|
||||
|
||||
FT_LOCAL( FT_Byte )
|
||||
cff_fd_select_get( CFF_FDSelect fdselect,
|
||||
FT_UInt glyph_index );
|
||||
|
||||
FT_LOCAL( FT_Bool )
|
||||
cff_blend_check_vector( CFF_Blend blend,
|
||||
FT_UInt vsindex,
|
||||
FT_UInt lenNDV,
|
||||
FT_Fixed* NDV );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_blend_build_vector( CFF_Blend blend,
|
||||
FT_UInt vsindex,
|
||||
FT_UInt lenNDV,
|
||||
FT_Fixed* NDV );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cff_blend_clear( CFF_SubFont subFont );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_blend_doBlend( CFF_SubFont subfont,
|
||||
CFF_Parser parser,
|
||||
FT_UInt numBlends );
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_get_var_blend( FT_Face face,
|
||||
FT_UInt *num_coords,
|
||||
FT_Fixed* *coords,
|
||||
FT_Fixed* *normalizedcoords,
|
||||
FT_MM_Var* *mm_var );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cff_done_blend( FT_Face face );
|
||||
#endif
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CFFLOAD_H_ */
|
||||
|
||||
|
||||
/* END */
|
1204
internal/c/parts/video/font/freetype/cffobjs.c
Normal file
1204
internal/c/parts/video/font/freetype/cffobjs.c
Normal file
File diff suppressed because it is too large
Load diff
84
internal/c/parts/video/font/freetype/cffobjs.h
Normal file
84
internal/c/parts/video/font/freetype/cffobjs.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cffobjs.h
|
||||
*
|
||||
* OpenType objects manager (specification).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 CFFOBJS_H_
|
||||
#define CFFOBJS_H_
|
||||
|
||||
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_size_init( FT_Size size ); /* CFF_Size */
|
||||
|
||||
FT_LOCAL( void )
|
||||
cff_size_done( FT_Size size ); /* CFF_Size */
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_size_request( FT_Size size,
|
||||
FT_Size_Request req );
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_size_select( FT_Size size,
|
||||
FT_ULong strike_index );
|
||||
|
||||
#endif
|
||||
|
||||
FT_LOCAL( void )
|
||||
cff_slot_done( FT_GlyphSlot slot );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_slot_init( FT_GlyphSlot slot );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Face functions
|
||||
*/
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_face_init( FT_Stream stream,
|
||||
FT_Face face, /* CFF_Face */
|
||||
FT_Int face_index,
|
||||
FT_Int num_params,
|
||||
FT_Parameter* params );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cff_face_done( FT_Face face ); /* CFF_Face */
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Driver functions
|
||||
*/
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_driver_init( FT_Module module ); /* PS_Driver */
|
||||
|
||||
FT_LOCAL( void )
|
||||
cff_driver_done( FT_Module module ); /* PS_Driver */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CFFOBJS_H_ */
|
||||
|
||||
|
||||
/* END */
|
1513
internal/c/parts/video/font/freetype/cffparse.c
Normal file
1513
internal/c/parts/video/font/freetype/cffparse.c
Normal file
File diff suppressed because it is too large
Load diff
143
internal/c/parts/video/font/freetype/cffparse.h
Normal file
143
internal/c/parts/video/font/freetype/cffparse.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cffparse.h
|
||||
*
|
||||
* CFF token stream parser (specification)
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 CFFPARSE_H_
|
||||
#define CFFPARSE_H_
|
||||
|
||||
|
||||
#include <freetype/internal/cfftypes.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* CFF uses constant parser stack size; */
|
||||
/* CFF2 can increase from default 193 */
|
||||
#define CFF_MAX_STACK_DEPTH 96
|
||||
|
||||
/*
|
||||
* There are plans to remove the `maxstack' operator in a forthcoming
|
||||
* revision of the CFF2 specification, increasing the (then static) stack
|
||||
* size to 513. By making the default stack size equal to the maximum
|
||||
* stack size, the operator is essentially disabled, which has the
|
||||
* desired effect in FreeType.
|
||||
*/
|
||||
#define CFF2_MAX_STACK 513
|
||||
#define CFF2_DEFAULT_STACK 513
|
||||
|
||||
#define CFF_CODE_TOPDICT 0x1000
|
||||
#define CFF_CODE_PRIVATE 0x2000
|
||||
#define CFF2_CODE_TOPDICT 0x3000
|
||||
#define CFF2_CODE_FONTDICT 0x4000
|
||||
#define CFF2_CODE_PRIVATE 0x5000
|
||||
|
||||
|
||||
typedef struct CFF_ParserRec_
|
||||
{
|
||||
FT_Library library;
|
||||
FT_Byte* start;
|
||||
FT_Byte* limit;
|
||||
FT_Byte* cursor;
|
||||
|
||||
FT_Byte** stack;
|
||||
FT_Byte** top;
|
||||
FT_UInt stackSize; /* allocated size */
|
||||
|
||||
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
||||
FT_ListRec t2_strings;
|
||||
#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
|
||||
|
||||
FT_UInt object_code;
|
||||
void* object;
|
||||
|
||||
FT_UShort num_designs; /* a copy of `CFF_FontRecDict->num_designs' */
|
||||
FT_UShort num_axes; /* a copy of `CFF_FontRecDict->num_axes' */
|
||||
|
||||
} CFF_ParserRec, *CFF_Parser;
|
||||
|
||||
|
||||
FT_LOCAL( FT_Long )
|
||||
cff_parse_num( CFF_Parser parser,
|
||||
FT_Byte** d );
|
||||
|
||||
FT_LOCAL( FT_Fixed )
|
||||
cff_parse_fixed( CFF_Parser parser,
|
||||
FT_Byte** d );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_parser_init( CFF_Parser parser,
|
||||
FT_UInt code,
|
||||
void* object,
|
||||
FT_Library library,
|
||||
FT_UInt stackSize,
|
||||
FT_UShort num_designs,
|
||||
FT_UShort num_axes );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cff_parser_done( CFF_Parser parser );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_parser_run( CFF_Parser parser,
|
||||
FT_Byte* start,
|
||||
FT_Byte* limit );
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
cff_kind_none = 0,
|
||||
cff_kind_num,
|
||||
cff_kind_fixed,
|
||||
cff_kind_fixed_thousand,
|
||||
cff_kind_string,
|
||||
cff_kind_bool,
|
||||
cff_kind_delta,
|
||||
cff_kind_callback,
|
||||
cff_kind_blend,
|
||||
|
||||
cff_kind_max /* do not remove */
|
||||
};
|
||||
|
||||
|
||||
/* now generate handlers for the most simple fields */
|
||||
typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser );
|
||||
|
||||
typedef struct CFF_Field_Handler_
|
||||
{
|
||||
int kind;
|
||||
int code;
|
||||
FT_UInt offset;
|
||||
FT_Byte size;
|
||||
CFF_Field_Reader reader;
|
||||
FT_UInt array_max;
|
||||
FT_UInt count_offset;
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
const char* id;
|
||||
#endif
|
||||
|
||||
} CFF_Field_Handler;
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* CFFPARSE_H_ */
|
||||
|
||||
|
||||
/* END */
|
150
internal/c/parts/video/font/freetype/cfftoken.h
Normal file
150
internal/c/parts/video/font/freetype/cfftoken.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cfftoken.h
|
||||
*
|
||||
* CFF token definitions (specification only).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CFF_FontRecDictRec
|
||||
|
||||
#undef CFFCODE
|
||||
#define CFFCODE CFF_CODE_TOPDICT
|
||||
|
||||
CFF_FIELD_STRING ( 0, version, "Version" )
|
||||
CFF_FIELD_STRING ( 1, notice, "Notice" )
|
||||
CFF_FIELD_STRING ( 0x100, copyright, "Copyright" )
|
||||
CFF_FIELD_STRING ( 2, full_name, "FullName" )
|
||||
CFF_FIELD_STRING ( 3, family_name, "FamilyName" )
|
||||
CFF_FIELD_STRING ( 4, weight, "Weight" )
|
||||
CFF_FIELD_BOOL ( 0x101, is_fixed_pitch, "isFixedPitch" )
|
||||
CFF_FIELD_FIXED ( 0x102, italic_angle, "ItalicAngle" )
|
||||
CFF_FIELD_FIXED ( 0x103, underline_position, "UnderlinePosition" )
|
||||
CFF_FIELD_FIXED ( 0x104, underline_thickness, "UnderlineThickness" )
|
||||
CFF_FIELD_NUM ( 0x105, paint_type, "PaintType" )
|
||||
CFF_FIELD_NUM ( 0x106, charstring_type, "CharstringType" )
|
||||
CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" )
|
||||
CFF_FIELD_NUM ( 13, unique_id, "UniqueID" )
|
||||
CFF_FIELD_CALLBACK( 5, font_bbox, "FontBBox" )
|
||||
CFF_FIELD_NUM ( 0x108, stroke_width, "StrokeWidth" )
|
||||
#if 0
|
||||
CFF_FIELD_DELTA ( 14, xuid, 16, "XUID" )
|
||||
#endif
|
||||
CFF_FIELD_NUM ( 15, charset_offset, "charset" )
|
||||
CFF_FIELD_NUM ( 16, encoding_offset, "Encoding" )
|
||||
CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" )
|
||||
CFF_FIELD_CALLBACK( 18, private_dict, "Private" )
|
||||
CFF_FIELD_NUM ( 0x114, synthetic_base, "SyntheticBase" )
|
||||
CFF_FIELD_STRING ( 0x115, embedded_postscript, "PostScript" )
|
||||
|
||||
#if 0
|
||||
CFF_FIELD_STRING ( 0x116, base_font_name, "BaseFontName" )
|
||||
CFF_FIELD_DELTA ( 0x117, base_font_blend, 16, "BaseFontBlend" )
|
||||
#endif
|
||||
|
||||
/* the next two operators were removed from the Type2 specification */
|
||||
/* in version 16-March-2000 */
|
||||
CFF_FIELD_CALLBACK( 0x118, multiple_master, "MultipleMaster" )
|
||||
#if 0
|
||||
CFF_FIELD_CALLBACK( 0x11A, blend_axis_types, "BlendAxisTypes" )
|
||||
#endif
|
||||
|
||||
CFF_FIELD_CALLBACK( 0x11E, cid_ros, "ROS" )
|
||||
CFF_FIELD_NUM ( 0x11F, cid_font_version, "CIDFontVersion" )
|
||||
CFF_FIELD_NUM ( 0x120, cid_font_revision, "CIDFontRevision" )
|
||||
CFF_FIELD_NUM ( 0x121, cid_font_type, "CIDFontType" )
|
||||
CFF_FIELD_NUM ( 0x122, cid_count, "CIDCount" )
|
||||
CFF_FIELD_NUM ( 0x123, cid_uid_base, "UIDBase" )
|
||||
CFF_FIELD_NUM ( 0x124, cid_fd_array_offset, "FDArray" )
|
||||
CFF_FIELD_NUM ( 0x125, cid_fd_select_offset, "FDSelect" )
|
||||
CFF_FIELD_STRING ( 0x126, cid_font_name, "FontName" )
|
||||
|
||||
#if 0
|
||||
CFF_FIELD_NUM ( 0x127, chameleon, "Chameleon" )
|
||||
#endif
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CFF_PrivateRec
|
||||
#undef CFFCODE
|
||||
#define CFFCODE CFF_CODE_PRIVATE
|
||||
|
||||
CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" )
|
||||
CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" )
|
||||
CFF_FIELD_DELTA ( 8, family_blues, 14, "FamilyBlues" )
|
||||
CFF_FIELD_DELTA ( 9, family_other_blues, 10, "FamilyOtherBlues" )
|
||||
CFF_FIELD_FIXED_1000( 0x109, blue_scale, "BlueScale" )
|
||||
CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" )
|
||||
CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" )
|
||||
CFF_FIELD_NUM ( 10, standard_width, "StdHW" )
|
||||
CFF_FIELD_NUM ( 11, standard_height, "StdVW" )
|
||||
CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" )
|
||||
CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" )
|
||||
CFF_FIELD_BOOL ( 0x10E, force_bold, "ForceBold" )
|
||||
CFF_FIELD_FIXED ( 0x10F, force_bold_threshold, "ForceBoldThreshold" )
|
||||
CFF_FIELD_NUM ( 0x110, lenIV, "lenIV" )
|
||||
CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" )
|
||||
CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" )
|
||||
CFF_FIELD_NUM ( 0x113, initial_random_seed, "initialRandomSeed" )
|
||||
CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" )
|
||||
CFF_FIELD_NUM ( 20, default_width, "defaultWidthX" )
|
||||
CFF_FIELD_NUM ( 21, nominal_width, "nominalWidthX" )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CFF_FontRecDictRec
|
||||
#undef CFFCODE
|
||||
#define CFFCODE CFF2_CODE_TOPDICT
|
||||
|
||||
CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" )
|
||||
CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" )
|
||||
CFF_FIELD_NUM ( 0x124, cid_fd_array_offset, "FDArray" )
|
||||
CFF_FIELD_NUM ( 0x125, cid_fd_select_offset, "FDSelect" )
|
||||
CFF_FIELD_NUM ( 24, vstore_offset, "vstore" )
|
||||
CFF_FIELD_CALLBACK( 25, maxstack, "maxstack" )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CFF_FontRecDictRec
|
||||
#undef CFFCODE
|
||||
#define CFFCODE CFF2_CODE_FONTDICT
|
||||
|
||||
CFF_FIELD_CALLBACK( 18, private_dict, "Private" )
|
||||
CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CFF_PrivateRec
|
||||
#undef CFFCODE
|
||||
#define CFFCODE CFF2_CODE_PRIVATE
|
||||
|
||||
CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" )
|
||||
CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" )
|
||||
CFF_FIELD_DELTA ( 8, family_blues, 14, "FamilyBlues" )
|
||||
CFF_FIELD_DELTA ( 9, family_other_blues, 10, "FamilyOtherBlues" )
|
||||
CFF_FIELD_FIXED_1000( 0x109, blue_scale, "BlueScale" )
|
||||
CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" )
|
||||
CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" )
|
||||
CFF_FIELD_NUM ( 10, standard_width, "StdHW" )
|
||||
CFF_FIELD_NUM ( 11, standard_height, "StdVW" )
|
||||
CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" )
|
||||
CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" )
|
||||
CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" )
|
||||
CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" )
|
||||
CFF_FIELD_CALLBACK ( 22, vsindex, "vsindex" )
|
||||
CFF_FIELD_BLEND ( 23, "blend" )
|
||||
CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" )
|
||||
|
||||
|
||||
/* END */
|
41
internal/c/parts/video/font/freetype/ciderrs.h
Normal file
41
internal/c/parts/video/font/freetype/ciderrs.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ciderrs.h
|
||||
*
|
||||
* CID error codes (specification only).
|
||||
*
|
||||
* Copyright (C) 2001-2023 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 CID error enumeration constants.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CIDERRS_H_
|
||||
#define CIDERRS_H_
|
||||
|
||||
#include <freetype/ftmoderr.h>
|
||||
|
||||
#undef FTERRORS_H_
|
||||
|
||||
#undef FT_ERR_PREFIX
|
||||
#define FT_ERR_PREFIX CID_Err_
|
||||
#define FT_ERR_BASE FT_Mod_Err_CID
|
||||
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
#endif /* CIDERRS_H_ */
|
||||
|
||||
|
||||
/* END */
|
618
internal/c/parts/video/font/freetype/cidgload.c
Normal file
618
internal/c/parts/video/font/freetype/cidgload.c
Normal file
|
@ -0,0 +1,618 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidgload.c
|
||||
*
|
||||
* CID-keyed Type1 Glyph Loader (body).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 "cidload.h"
|
||||
#include "cidgload.h"
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftstream.h>
|
||||
#include <freetype/ftoutln.h>
|
||||
#include <freetype/internal/ftcalc.h>
|
||||
|
||||
#include <freetype/internal/psaux.h>
|
||||
#include <freetype/internal/cfftypes.h>
|
||||
#include <freetype/ftdriver.h>
|
||||
|
||||
#include "ciderrs.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 cidgload
|
||||
|
||||
|
||||
/*
|
||||
* A helper function to compute FD number (`fd_select`), the offset to the
|
||||
* head of the glyph data (`off1`), and the offset to the and of the glyph
|
||||
* data (`off2`).
|
||||
*
|
||||
* The number how many times `cid_get_offset` is invoked can be controlled
|
||||
* by the number of non-NULL arguments. If `fd_select` is non-NULL but
|
||||
* `off1` and `off2` are NULL, `cid_get_offset` is invoked only for
|
||||
* `fd_select`; `off1` and `off2` are not validated.
|
||||
*
|
||||
*/
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_compute_fd_and_offsets( CID_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_ULong* fd_select_p,
|
||||
FT_ULong* off1_p,
|
||||
FT_ULong* off2_p )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
CID_FaceInfo cid = &face->cid;
|
||||
FT_Stream stream = face->cid_stream;
|
||||
FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
|
||||
|
||||
FT_Byte* p;
|
||||
FT_Bool need_frame_exit = 0;
|
||||
FT_ULong fd_select, off1, off2;
|
||||
|
||||
|
||||
/* For ordinary fonts, read the CID font dictionary index */
|
||||
/* and charstring offset from the CIDMap. */
|
||||
|
||||
if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
|
||||
glyph_index * entry_len ) ||
|
||||
FT_FRAME_ENTER( 2 * entry_len ) )
|
||||
goto Exit;
|
||||
|
||||
need_frame_exit = 1;
|
||||
|
||||
p = (FT_Byte*)stream->cursor;
|
||||
fd_select = cid_get_offset( &p, cid->fd_bytes );
|
||||
off1 = cid_get_offset( &p, cid->gd_bytes );
|
||||
|
||||
p += cid->fd_bytes;
|
||||
off2 = cid_get_offset( &p, cid->gd_bytes );
|
||||
|
||||
if ( fd_select_p )
|
||||
*fd_select_p = fd_select;
|
||||
if ( off1_p )
|
||||
*off1_p = off1;
|
||||
if ( off2_p )
|
||||
*off2_p = off2;
|
||||
|
||||
if ( fd_select >= cid->num_dicts )
|
||||
{
|
||||
/*
|
||||
* fd_select == 0xFF is often used to indicate that the CID
|
||||
* has no charstring to be rendered, similar to GID = 0xFFFF
|
||||
* in TrueType fonts.
|
||||
*/
|
||||
if ( ( cid->fd_bytes == 1 && fd_select == 0xFFU ) ||
|
||||
( cid->fd_bytes == 2 && fd_select == 0xFFFFU ) )
|
||||
{
|
||||
FT_TRACE1(( "cid_load_glyph: fail for glyph index %d:\n",
|
||||
glyph_index ));
|
||||
FT_TRACE1(( " FD number %ld is the maximum\n",
|
||||
fd_select ));
|
||||
FT_TRACE1(( " integer fitting into %d byte%s\n",
|
||||
cid->fd_bytes, cid->fd_bytes == 1 ? "" : "s" ));
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n",
|
||||
glyph_index ));
|
||||
FT_TRACE0(( " FD number %ld is larger\n",
|
||||
fd_select ));
|
||||
FT_TRACE0(( " than number of dictionaries (%d)\n",
|
||||
cid->num_dicts ));
|
||||
}
|
||||
|
||||
error = FT_THROW( Invalid_Offset );
|
||||
goto Exit;
|
||||
}
|
||||
else if ( off2 > stream->size )
|
||||
{
|
||||
FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n",
|
||||
glyph_index ));
|
||||
FT_TRACE0(( " end of the glyph data\n" ));
|
||||
FT_TRACE0(( " is beyond the data stream\n" ));
|
||||
|
||||
error = FT_THROW( Invalid_Offset );
|
||||
goto Exit;
|
||||
}
|
||||
else if ( off1 > off2 )
|
||||
{
|
||||
FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n",
|
||||
glyph_index ));
|
||||
FT_TRACE0(( " the end position of glyph data\n" ));
|
||||
FT_TRACE0(( " is set before the start position\n" ));
|
||||
|
||||
error = FT_THROW( Invalid_Offset );
|
||||
}
|
||||
|
||||
Exit:
|
||||
if ( need_frame_exit )
|
||||
FT_FRAME_EXIT();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cid_load_glyph( T1_Decoder decoder,
|
||||
FT_UInt glyph_index )
|
||||
{
|
||||
CID_Face face = (CID_Face)decoder->builder.face;
|
||||
CID_FaceInfo cid = &face->cid;
|
||||
FT_Byte* p;
|
||||
FT_ULong fd_select;
|
||||
FT_Stream stream = face->cid_stream;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Byte* charstring = NULL;
|
||||
FT_Memory memory = face->root.memory;
|
||||
FT_ULong glyph_length = 0;
|
||||
PSAux_Service psaux = (PSAux_Service)face->psaux;
|
||||
|
||||
FT_Bool force_scaling = FALSE;
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
FT_Incremental_InterfaceRec *inc =
|
||||
face->root.internal->incremental_interface;
|
||||
#endif
|
||||
|
||||
|
||||
FT_TRACE1(( "cid_load_glyph: glyph index %u\n", glyph_index ));
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
|
||||
/* For incremental fonts get the character data using */
|
||||
/* the callback function. */
|
||||
if ( inc )
|
||||
{
|
||||
FT_Data glyph_data;
|
||||
|
||||
|
||||
error = inc->funcs->get_glyph_data( inc->object,
|
||||
glyph_index, &glyph_data );
|
||||
if ( error || glyph_data.length < cid->fd_bytes )
|
||||
goto Exit;
|
||||
|
||||
p = (FT_Byte*)glyph_data.pointer;
|
||||
fd_select = cid_get_offset( &p, cid->fd_bytes );
|
||||
|
||||
glyph_length = glyph_data.length - cid->fd_bytes;
|
||||
|
||||
if ( !FT_QALLOC( charstring, glyph_length ) )
|
||||
FT_MEM_COPY( charstring, glyph_data.pointer + cid->fd_bytes,
|
||||
glyph_length );
|
||||
|
||||
inc->funcs->free_glyph_data( inc->object, &glyph_data );
|
||||
|
||||
if ( error )
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
{
|
||||
FT_ULong off1, off2;
|
||||
|
||||
|
||||
error = cid_compute_fd_and_offsets( face, glyph_index,
|
||||
&fd_select, &off1, &off2 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
glyph_length = off2 - off1;
|
||||
|
||||
if ( glyph_length == 0 ||
|
||||
FT_QALLOC( charstring, glyph_length ) ||
|
||||
FT_STREAM_READ_AT( cid->data_offset + off1,
|
||||
charstring, glyph_length ) )
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Now set up the subrs array and parse the charstrings. */
|
||||
{
|
||||
CID_FaceDict dict;
|
||||
CID_Subrs cid_subrs = face->subrs + fd_select;
|
||||
FT_UInt cs_offset;
|
||||
|
||||
|
||||
/* Set up subrs */
|
||||
decoder->num_subrs = cid_subrs->num_subrs;
|
||||
decoder->subrs = cid_subrs->code;
|
||||
decoder->subrs_len = 0;
|
||||
decoder->subrs_hash = NULL;
|
||||
|
||||
/* Set up font matrix */
|
||||
dict = cid->font_dicts + fd_select;
|
||||
|
||||
decoder->font_matrix = dict->font_matrix;
|
||||
decoder->font_offset = dict->font_offset;
|
||||
decoder->lenIV = dict->private_dict.lenIV;
|
||||
|
||||
/* Decode the charstring. */
|
||||
|
||||
/* Adjustment for seed bytes. */
|
||||
cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0;
|
||||
if ( cs_offset > glyph_length )
|
||||
{
|
||||
FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
||||
"offset to the charstring is beyond glyph length\n",
|
||||
glyph_index ));
|
||||
error = FT_THROW( Invalid_Offset );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Decrypt only if lenIV >= 0. */
|
||||
if ( decoder->lenIV >= 0 )
|
||||
psaux->t1_decrypt( charstring, glyph_length, 4330 );
|
||||
|
||||
/* choose which renderer to use */
|
||||
#ifdef T1_CONFIG_OPTION_OLD_ENGINE
|
||||
if ( ( (PS_Driver)FT_FACE_DRIVER( face ) )->hinting_engine ==
|
||||
FT_HINTING_FREETYPE ||
|
||||
decoder->builder.metrics_only )
|
||||
error = psaux->t1_decoder_funcs->parse_charstrings_old(
|
||||
decoder,
|
||||
charstring + cs_offset,
|
||||
glyph_length - cs_offset );
|
||||
#else
|
||||
if ( decoder->builder.metrics_only )
|
||||
error = psaux->t1_decoder_funcs->parse_metrics(
|
||||
decoder,
|
||||
charstring + cs_offset,
|
||||
glyph_length - cs_offset );
|
||||
#endif
|
||||
else
|
||||
{
|
||||
PS_Decoder psdecoder;
|
||||
CFF_SubFontRec subfont;
|
||||
|
||||
|
||||
psaux->ps_decoder_init( &psdecoder, decoder, TRUE );
|
||||
|
||||
psaux->t1_make_subfont( FT_FACE( face ),
|
||||
&dict->private_dict,
|
||||
&subfont );
|
||||
psdecoder.current_subfont = &subfont;
|
||||
|
||||
error = psaux->t1_decoder_funcs->parse_charstrings(
|
||||
&psdecoder,
|
||||
charstring + cs_offset,
|
||||
glyph_length - cs_offset );
|
||||
|
||||
/* Adobe's engine uses 16.16 numbers everywhere; */
|
||||
/* as a consequence, glyphs larger than 2000ppem get rejected */
|
||||
if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
|
||||
{
|
||||
/* this time, we retry unhinted and scale up the glyph later on */
|
||||
/* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
|
||||
/* 0x400 for both `x_scale' and `y_scale' in this case) */
|
||||
((CID_GlyphSlot)decoder->builder.glyph)->hint = FALSE;
|
||||
|
||||
force_scaling = TRUE;
|
||||
|
||||
error = psaux->t1_decoder_funcs->parse_charstrings(
|
||||
&psdecoder,
|
||||
charstring + cs_offset,
|
||||
glyph_length - cs_offset );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
|
||||
/* Incremental fonts can optionally override the metrics. */
|
||||
if ( !error && inc && inc->funcs->get_glyph_metrics )
|
||||
{
|
||||
FT_Incremental_MetricsRec metrics;
|
||||
|
||||
|
||||
metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
|
||||
metrics.bearing_y = 0;
|
||||
metrics.advance = FIXED_TO_INT( decoder->builder.advance.x );
|
||||
metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );
|
||||
|
||||
error = inc->funcs->get_glyph_metrics( inc->object,
|
||||
glyph_index, FALSE, &metrics );
|
||||
|
||||
decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
|
||||
decoder->builder.advance.x = INT_TO_FIXED( metrics.advance );
|
||||
decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v );
|
||||
}
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
|
||||
Exit:
|
||||
FT_FREE( charstring );
|
||||
|
||||
((CID_GlyphSlot)decoder->builder.glyph)->scaled = force_scaling;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/********** *********/
|
||||
/********** *********/
|
||||
/********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
|
||||
/********** *********/
|
||||
/********** The following code is in charge of computing *********/
|
||||
/********** the maximum advance width of the font. It *********/
|
||||
/********** quickly processes each glyph charstring to *********/
|
||||
/********** extract the value from either a `sbw' or `seac' *********/
|
||||
/********** operator. *********/
|
||||
/********** *********/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_face_compute_max_advance( CID_Face face,
|
||||
FT_Int* max_advance )
|
||||
{
|
||||
FT_Error error;
|
||||
T1_DecoderRec decoder;
|
||||
FT_Int glyph_index;
|
||||
|
||||
PSAux_Service psaux = (PSAux_Service)face->psaux;
|
||||
|
||||
|
||||
*max_advance = 0;
|
||||
|
||||
/* Initialize load decoder */
|
||||
error = psaux->t1_decoder_funcs->init( &decoder,
|
||||
(FT_Face)face,
|
||||
0, /* size */
|
||||
0, /* glyph slot */
|
||||
0, /* glyph names! XXX */
|
||||
0, /* blend == 0 */
|
||||
0, /* hinting == 0 */
|
||||
cid_load_glyph );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
/* TODO: initialize decoder.len_buildchar and decoder.buildchar */
|
||||
/* if we ever support CID-keyed multiple master fonts */
|
||||
|
||||
decoder.builder.metrics_only = 1;
|
||||
decoder.builder.load_points = 0;
|
||||
|
||||
/* for each glyph, parse the glyph charstring and extract */
|
||||
/* the advance width */
|
||||
for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
|
||||
glyph_index++ )
|
||||
{
|
||||
/* now get load the unscaled outline */
|
||||
error = cid_load_glyph( &decoder, glyph_index );
|
||||
/* ignore the error if one occurred - skip to next glyph */
|
||||
}
|
||||
|
||||
*max_advance = FIXED_TO_INT( decoder.builder.advance.x );
|
||||
|
||||
psaux->t1_decoder_funcs->done( &decoder );
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_slot_load_glyph( FT_GlyphSlot cidglyph, /* CID_GlyphSlot */
|
||||
FT_Size cidsize, /* CID_Size */
|
||||
FT_UInt glyph_index,
|
||||
FT_Int32 load_flags )
|
||||
{
|
||||
CID_GlyphSlot glyph = (CID_GlyphSlot)cidglyph;
|
||||
FT_Error error;
|
||||
T1_DecoderRec decoder;
|
||||
CID_Face face = (CID_Face)cidglyph->face;
|
||||
FT_Bool hinting;
|
||||
FT_Bool scaled;
|
||||
|
||||
PSAux_Service psaux = (PSAux_Service)face->psaux;
|
||||
FT_Matrix font_matrix;
|
||||
FT_Vector font_offset;
|
||||
FT_Bool must_finish_decoder = FALSE;
|
||||
|
||||
|
||||
if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
|
||||
{
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( load_flags & FT_LOAD_NO_RECURSE )
|
||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
||||
|
||||
glyph->x_scale = cidsize->metrics.x_scale;
|
||||
glyph->y_scale = cidsize->metrics.y_scale;
|
||||
|
||||
cidglyph->outline.n_points = 0;
|
||||
cidglyph->outline.n_contours = 0;
|
||||
|
||||
hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
|
||||
( load_flags & FT_LOAD_NO_HINTING ) == 0 );
|
||||
scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
|
||||
|
||||
glyph->hint = hinting;
|
||||
glyph->scaled = scaled;
|
||||
cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
|
||||
error = psaux->t1_decoder_funcs->init( &decoder,
|
||||
cidglyph->face,
|
||||
cidsize,
|
||||
cidglyph,
|
||||
0, /* glyph names -- XXX */
|
||||
0, /* blend == 0 */
|
||||
hinting,
|
||||
FT_LOAD_TARGET_MODE( load_flags ),
|
||||
cid_load_glyph );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* TODO: initialize decoder.len_buildchar and decoder.buildchar */
|
||||
/* if we ever support CID-keyed multiple master fonts */
|
||||
|
||||
must_finish_decoder = TRUE;
|
||||
|
||||
/* set up the decoder */
|
||||
decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
|
||||
|
||||
error = cid_load_glyph( &decoder, glyph_index );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* copy flags back for forced scaling */
|
||||
hinting = glyph->hint;
|
||||
scaled = glyph->scaled;
|
||||
|
||||
font_matrix = decoder.font_matrix;
|
||||
font_offset = decoder.font_offset;
|
||||
|
||||
/* save new glyph tables */
|
||||
psaux->t1_decoder_funcs->done( &decoder );
|
||||
|
||||
must_finish_decoder = FALSE;
|
||||
|
||||
/* now set the metrics -- this is rather simple, as */
|
||||
/* the left side bearing is the xMin, and the top side */
|
||||
/* bearing the yMax */
|
||||
cidglyph->outline.flags &= FT_OUTLINE_OWNER;
|
||||
cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
|
||||
|
||||
/* for composite glyphs, return only left side bearing and */
|
||||
/* advance width */
|
||||
if ( load_flags & FT_LOAD_NO_RECURSE )
|
||||
{
|
||||
FT_Slot_Internal internal = cidglyph->internal;
|
||||
|
||||
|
||||
cidglyph->metrics.horiBearingX =
|
||||
FIXED_TO_INT( decoder.builder.left_bearing.x );
|
||||
cidglyph->metrics.horiAdvance =
|
||||
FIXED_TO_INT( decoder.builder.advance.x );
|
||||
|
||||
internal->glyph_matrix = font_matrix;
|
||||
internal->glyph_delta = font_offset;
|
||||
internal->glyph_transformed = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_BBox cbox;
|
||||
FT_Glyph_Metrics* metrics = &cidglyph->metrics;
|
||||
|
||||
|
||||
/* copy the _unscaled_ advance width */
|
||||
metrics->horiAdvance =
|
||||
FIXED_TO_INT( decoder.builder.advance.x );
|
||||
cidglyph->linearHoriAdvance =
|
||||
FIXED_TO_INT( decoder.builder.advance.x );
|
||||
cidglyph->internal->glyph_transformed = 0;
|
||||
|
||||
/* make up vertical ones */
|
||||
metrics->vertAdvance = ( face->cid.font_bbox.yMax -
|
||||
face->cid.font_bbox.yMin ) >> 16;
|
||||
cidglyph->linearVertAdvance = metrics->vertAdvance;
|
||||
|
||||
cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
|
||||
if ( cidsize->metrics.y_ppem < 24 )
|
||||
cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
|
||||
|
||||
/* apply the font matrix, if any */
|
||||
if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
|
||||
font_matrix.xy != 0 || font_matrix.yx != 0 )
|
||||
{
|
||||
FT_Outline_Transform( &cidglyph->outline, &font_matrix );
|
||||
|
||||
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
|
||||
font_matrix.xx );
|
||||
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance,
|
||||
font_matrix.yy );
|
||||
}
|
||||
|
||||
if ( font_offset.x || font_offset.y )
|
||||
{
|
||||
FT_Outline_Translate( &cidglyph->outline,
|
||||
font_offset.x,
|
||||
font_offset.y );
|
||||
|
||||
metrics->horiAdvance += font_offset.x;
|
||||
metrics->vertAdvance += font_offset.y;
|
||||
}
|
||||
|
||||
if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || scaled )
|
||||
{
|
||||
/* scale the outline and the metrics */
|
||||
FT_Int n;
|
||||
FT_Outline* cur = decoder.builder.base;
|
||||
FT_Vector* vec = cur->points;
|
||||
FT_Fixed x_scale = glyph->x_scale;
|
||||
FT_Fixed y_scale = glyph->y_scale;
|
||||
|
||||
|
||||
/* First of all, scale the points */
|
||||
if ( !hinting || !decoder.builder.hints_funcs )
|
||||
for ( n = cur->n_points; n > 0; n--, vec++ )
|
||||
{
|
||||
vec->x = FT_MulFix( vec->x, x_scale );
|
||||
vec->y = FT_MulFix( vec->y, y_scale );
|
||||
}
|
||||
|
||||
/* Then scale the metrics */
|
||||
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
|
||||
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
|
||||
}
|
||||
|
||||
/* compute the other metrics */
|
||||
FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
|
||||
|
||||
metrics->width = cbox.xMax - cbox.xMin;
|
||||
metrics->height = cbox.yMax - cbox.yMin;
|
||||
|
||||
metrics->horiBearingX = cbox.xMin;
|
||||
metrics->horiBearingY = cbox.yMax;
|
||||
|
||||
if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
|
||||
{
|
||||
/* make up vertical ones */
|
||||
ft_synthesize_vertical_metrics( metrics,
|
||||
metrics->vertAdvance );
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
|
||||
if ( must_finish_decoder )
|
||||
psaux->t1_decoder_funcs->done( &decoder );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
58
internal/c/parts/video/font/freetype/cidgload.h
Normal file
58
internal/c/parts/video/font/freetype/cidgload.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidgload.h
|
||||
*
|
||||
* OpenType Glyph Loader (specification).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 CIDGLOAD_H_
|
||||
#define CIDGLOAD_H_
|
||||
|
||||
|
||||
#include "cidobjs.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* Compute the maximum advance width of a font through quick parsing */
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_face_compute_max_advance( CID_Face face,
|
||||
FT_Int* max_advance );
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_slot_load_glyph( FT_GlyphSlot glyph, /* CID_Glyph_Slot */
|
||||
FT_Size size, /* CID_Size */
|
||||
FT_UInt glyph_index,
|
||||
FT_Int32 load_flags );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_compute_fd_and_offsets( CID_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_ULong* fd_select_p,
|
||||
FT_ULong* off1_p,
|
||||
FT_ULong* off2_p );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CIDGLOAD_H_ */
|
||||
|
||||
|
||||
/* END */
|
950
internal/c/parts/video/font/freetype/cidload.c
Normal file
950
internal/c/parts/video/font/freetype/cidload.c
Normal file
|
@ -0,0 +1,950 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidload.c
|
||||
*
|
||||
* CID-keyed Type1 font loader (body).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 <freetype/internal/ftdebug.h>
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include <freetype/ftmm.h>
|
||||
#include <freetype/internal/t1types.h>
|
||||
#include <freetype/internal/psaux.h>
|
||||
|
||||
#include "cidload.h"
|
||||
|
||||
#include "ciderrs.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 cidload
|
||||
|
||||
|
||||
/* read a single offset */
|
||||
FT_LOCAL_DEF( FT_ULong )
|
||||
cid_get_offset( FT_Byte* *start,
|
||||
FT_UInt offsize )
|
||||
{
|
||||
FT_ULong result;
|
||||
FT_Byte* p = *start;
|
||||
|
||||
|
||||
for ( result = 0; offsize > 0; offsize-- )
|
||||
{
|
||||
result <<= 8;
|
||||
result |= *p++;
|
||||
}
|
||||
|
||||
*start = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** TYPE 1 SYMBOL PARSING *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
static FT_Error
|
||||
cid_load_keyword( CID_Face face,
|
||||
CID_Loader* loader,
|
||||
const T1_Field keyword )
|
||||
{
|
||||
FT_Error error;
|
||||
CID_Parser* parser = &loader->parser;
|
||||
FT_Byte* object;
|
||||
void* dummy_object;
|
||||
CID_FaceInfo cid = &face->cid;
|
||||
|
||||
|
||||
/* if the keyword has a dedicated callback, call it */
|
||||
if ( keyword->type == T1_FIELD_TYPE_CALLBACK )
|
||||
{
|
||||
FT_TRACE4(( " %s", keyword->ident ));
|
||||
|
||||
keyword->reader( (FT_Face)face, parser );
|
||||
error = parser->root.error;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* we must now compute the address of our target object */
|
||||
switch ( keyword->location )
|
||||
{
|
||||
case T1_FIELD_LOCATION_CID_INFO:
|
||||
object = (FT_Byte*)cid;
|
||||
break;
|
||||
|
||||
case T1_FIELD_LOCATION_FONT_INFO:
|
||||
object = (FT_Byte*)&cid->font_info;
|
||||
break;
|
||||
|
||||
case T1_FIELD_LOCATION_FONT_EXTRA:
|
||||
object = (FT_Byte*)&face->font_extra;
|
||||
break;
|
||||
|
||||
case T1_FIELD_LOCATION_BBOX:
|
||||
object = (FT_Byte*)&cid->font_bbox;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
CID_FaceDict dict;
|
||||
|
||||
|
||||
if ( parser->num_dict >= cid->num_dicts )
|
||||
{
|
||||
FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n",
|
||||
keyword->ident ));
|
||||
error = FT_THROW( Syntax_Error );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
dict = cid->font_dicts + parser->num_dict;
|
||||
switch ( keyword->location )
|
||||
{
|
||||
case T1_FIELD_LOCATION_PRIVATE:
|
||||
object = (FT_Byte*)&dict->private_dict;
|
||||
break;
|
||||
|
||||
default:
|
||||
object = (FT_Byte*)dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FT_TRACE4(( " %s", keyword->ident ));
|
||||
|
||||
dummy_object = object;
|
||||
|
||||
/* now, load the keyword data in the object's field(s) */
|
||||
if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY ||
|
||||
keyword->type == T1_FIELD_TYPE_FIXED_ARRAY )
|
||||
error = cid_parser_load_field_table( &loader->parser, keyword,
|
||||
&dummy_object );
|
||||
else
|
||||
error = cid_parser_load_field( &loader->parser,
|
||||
keyword, &dummy_object );
|
||||
|
||||
FT_TRACE4(( "\n" ));
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
cid_parse_font_matrix( FT_Face face, /* CID_Face */
|
||||
void* parser_ )
|
||||
{
|
||||
CID_Face cidface = (CID_Face)face;
|
||||
CID_Parser* parser = (CID_Parser*)parser_;
|
||||
CID_FaceDict dict;
|
||||
FT_Fixed temp[6];
|
||||
FT_Fixed temp_scale;
|
||||
|
||||
|
||||
if ( parser->num_dict < cidface->cid.num_dicts )
|
||||
{
|
||||
FT_Matrix* matrix;
|
||||
FT_Vector* offset;
|
||||
FT_Int result;
|
||||
|
||||
|
||||
dict = cidface->cid.font_dicts + parser->num_dict;
|
||||
matrix = &dict->font_matrix;
|
||||
offset = &dict->font_offset;
|
||||
|
||||
/* input is scaled by 1000 to accommodate default FontMatrix */
|
||||
result = cid_parser_to_fixed_array( parser, 6, temp, 3 );
|
||||
|
||||
if ( result < 6 )
|
||||
{
|
||||
FT_ERROR(( "cid_parse_font_matrix: not enough matrix elements\n" ));
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
FT_TRACE4(( " [%f %f %f %f %f %f]\n",
|
||||
(double)temp[0] / 65536 / 1000,
|
||||
(double)temp[1] / 65536 / 1000,
|
||||
(double)temp[2] / 65536 / 1000,
|
||||
(double)temp[3] / 65536 / 1000,
|
||||
(double)temp[4] / 65536 / 1000,
|
||||
(double)temp[5] / 65536 / 1000 ));
|
||||
|
||||
temp_scale = FT_ABS( temp[3] );
|
||||
|
||||
if ( temp_scale == 0 )
|
||||
{
|
||||
FT_ERROR(( "cid_parse_font_matrix: invalid font matrix\n" ));
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* atypical case */
|
||||
if ( temp_scale != 0x10000L )
|
||||
{
|
||||
/* set units per EM based on FontMatrix values */
|
||||
face->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
|
||||
|
||||
temp[0] = FT_DivFix( temp[0], temp_scale );
|
||||
temp[1] = FT_DivFix( temp[1], temp_scale );
|
||||
temp[2] = FT_DivFix( temp[2], temp_scale );
|
||||
temp[4] = FT_DivFix( temp[4], temp_scale );
|
||||
temp[5] = FT_DivFix( temp[5], temp_scale );
|
||||
temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
|
||||
}
|
||||
|
||||
matrix->xx = temp[0];
|
||||
matrix->yx = temp[1];
|
||||
matrix->xy = temp[2];
|
||||
matrix->yy = temp[3];
|
||||
|
||||
if ( !FT_Matrix_Check( matrix ) )
|
||||
{
|
||||
FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" ));
|
||||
parser->root.error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* note that the font offsets are expressed in integer font units */
|
||||
offset->x = temp[4] >> 16;
|
||||
offset->y = temp[5] >> 16;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
parse_fd_array( FT_Face face, /* CID_Face */
|
||||
void* parser_ )
|
||||
{
|
||||
CID_Face cidface = (CID_Face)face;
|
||||
CID_Parser* parser = (CID_Parser*)parser_;
|
||||
CID_FaceInfo cid = &cidface->cid;
|
||||
FT_Memory memory = FT_FACE_MEMORY( face );
|
||||
FT_Stream stream = parser->stream;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Long num_dicts, max_dicts;
|
||||
|
||||
|
||||
num_dicts = cid_parser_to_int( parser );
|
||||
if ( num_dicts < 0 || num_dicts > FT_INT_MAX )
|
||||
{
|
||||
FT_ERROR(( "parse_fd_array: invalid number of dictionaries\n" ));
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
FT_TRACE4(( " %ld\n", num_dicts ));
|
||||
|
||||
/*
|
||||
* A single entry in the FDArray must (at least) contain the following
|
||||
* structure elements.
|
||||
*
|
||||
* %ADOBeginFontDict 18
|
||||
* X dict begin 13
|
||||
* /FontMatrix [X X X X] 22
|
||||
* /Private X dict begin 22
|
||||
* end 4
|
||||
* end 4
|
||||
* %ADOEndFontDict 16
|
||||
*
|
||||
* This needs 18+13+22+22+4+4+16=99 bytes or more. Normally, you also
|
||||
* need a `dup X' at the very beginning and a `put' at the end, so a
|
||||
* rough guess using 100 bytes as the minimum is justified.
|
||||
*/
|
||||
max_dicts = (FT_Long)( stream->size / 100 );
|
||||
if ( num_dicts > max_dicts )
|
||||
{
|
||||
FT_TRACE0(( "parse_fd_array: adjusting FDArray size"
|
||||
" (from %ld to %ld)\n",
|
||||
num_dicts, max_dicts ));
|
||||
num_dicts = max_dicts;
|
||||
}
|
||||
|
||||
if ( !cid->font_dicts )
|
||||
{
|
||||
FT_UInt n;
|
||||
|
||||
|
||||
if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) )
|
||||
goto Exit;
|
||||
|
||||
cid->num_dicts = num_dicts;
|
||||
|
||||
/* set some default values (the same as for Type 1 fonts) */
|
||||
for ( n = 0; n < cid->num_dicts; n++ )
|
||||
{
|
||||
CID_FaceDict dict = cid->font_dicts + n;
|
||||
|
||||
|
||||
dict->private_dict.blue_shift = 7;
|
||||
dict->private_dict.blue_fuzz = 1;
|
||||
dict->private_dict.lenIV = 4;
|
||||
dict->private_dict.expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
|
||||
dict->private_dict.blue_scale = (FT_Fixed)(
|
||||
0.039625 * 0x10000L * 1000 );
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* By mistake, `expansion_factor' appears both in PS_PrivateRec */
|
||||
/* and CID_FaceDictRec (both are public header files and can't */
|
||||
/* be thus changed). We simply copy the value. */
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
parse_expansion_factor( FT_Face face, /* CID_Face */
|
||||
void* parser_ )
|
||||
{
|
||||
CID_Face cidface = (CID_Face)face;
|
||||
CID_Parser* parser = (CID_Parser*)parser_;
|
||||
CID_FaceDict dict;
|
||||
|
||||
|
||||
if ( parser->num_dict < cidface->cid.num_dicts )
|
||||
{
|
||||
dict = cidface->cid.font_dicts + parser->num_dict;
|
||||
|
||||
dict->expansion_factor = cid_parser_to_fixed( parser, 0 );
|
||||
dict->private_dict.expansion_factor = dict->expansion_factor;
|
||||
|
||||
FT_TRACE4(( "%ld\n", dict->expansion_factor ));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* By mistake, `CID_FaceDictRec' doesn't contain a field for the */
|
||||
/* `FontName' keyword. FreeType doesn't need it, but it is nice */
|
||||
/* to catch it for producing better trace output. */
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
parse_font_name( FT_Face face, /* CID_Face */
|
||||
void* parser_ )
|
||||
{
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
CID_Face cidface = (CID_Face)face;
|
||||
CID_Parser* parser = (CID_Parser*)parser_;
|
||||
|
||||
|
||||
if ( parser->num_dict < cidface->cid.num_dicts )
|
||||
{
|
||||
T1_TokenRec token;
|
||||
FT_UInt len;
|
||||
|
||||
|
||||
cid_parser_to_token( parser, &token );
|
||||
|
||||
len = (FT_UInt)( token.limit - token.start );
|
||||
if ( len )
|
||||
FT_TRACE4(( " %.*s\n", len, token.start ));
|
||||
else
|
||||
FT_TRACE4(( " <no value>\n" ));
|
||||
}
|
||||
#else
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( parser_ );
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
const T1_FieldRec cid_field_records[] =
|
||||
{
|
||||
|
||||
#include "cidtoken.h"
|
||||
|
||||
T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 )
|
||||
T1_FIELD_CALLBACK( "FontMatrix", cid_parse_font_matrix, 0 )
|
||||
T1_FIELD_CALLBACK( "ExpansionFactor", parse_expansion_factor, 0 )
|
||||
T1_FIELD_CALLBACK( "FontName", parse_font_name, 0 )
|
||||
|
||||
{ 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static FT_Error
|
||||
cid_parse_dict( CID_Face face,
|
||||
CID_Loader* loader,
|
||||
FT_Byte* base,
|
||||
FT_ULong size )
|
||||
{
|
||||
CID_Parser* parser = &loader->parser;
|
||||
|
||||
|
||||
parser->root.cursor = base;
|
||||
parser->root.limit = base + size;
|
||||
parser->root.error = FT_Err_Ok;
|
||||
|
||||
{
|
||||
FT_Byte* cur = base;
|
||||
FT_Byte* limit = cur + size;
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
FT_Byte* newlimit;
|
||||
|
||||
|
||||
parser->root.cursor = cur;
|
||||
cid_parser_skip_spaces( parser );
|
||||
|
||||
if ( parser->root.cursor >= limit )
|
||||
newlimit = limit - 1 - 17;
|
||||
else
|
||||
newlimit = parser->root.cursor - 17;
|
||||
|
||||
/* look for `%ADOBeginFontDict' */
|
||||
for ( ; cur < newlimit; cur++ )
|
||||
{
|
||||
if ( *cur == '%' &&
|
||||
ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 )
|
||||
{
|
||||
/* if /FDArray was found, then cid->num_dicts is > 0, and */
|
||||
/* we can start increasing parser->num_dict */
|
||||
if ( face->cid.num_dicts > 0 )
|
||||
{
|
||||
parser->num_dict++;
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
FT_TRACE4(( " FontDict %u", parser->num_dict ));
|
||||
if ( parser->num_dict > face->cid.num_dicts )
|
||||
FT_TRACE4(( " (ignored)" ));
|
||||
FT_TRACE4(( "\n" ));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur = parser->root.cursor;
|
||||
/* no error can occur in cid_parser_skip_spaces */
|
||||
if ( cur >= limit )
|
||||
break;
|
||||
|
||||
cid_parser_skip_PS_token( parser );
|
||||
if ( parser->root.cursor >= limit || parser->root.error )
|
||||
break;
|
||||
|
||||
/* look for immediates */
|
||||
if ( *cur == '/' && cur + 2 < limit )
|
||||
{
|
||||
FT_UInt len;
|
||||
|
||||
|
||||
cur++;
|
||||
len = (FT_UInt)( parser->root.cursor - cur );
|
||||
|
||||
if ( len > 0 && len < 22 )
|
||||
{
|
||||
/* now compare the immediate name to the keyword table */
|
||||
T1_Field keyword = (T1_Field)cid_field_records;
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
FT_Byte* name;
|
||||
|
||||
|
||||
name = (FT_Byte*)keyword->ident;
|
||||
if ( !name )
|
||||
break;
|
||||
|
||||
if ( cur[0] == name[0] &&
|
||||
len == ft_strlen( (const char*)name ) )
|
||||
{
|
||||
FT_UInt n;
|
||||
|
||||
|
||||
for ( n = 1; n < len; n++ )
|
||||
if ( cur[n] != name[n] )
|
||||
break;
|
||||
|
||||
if ( n >= len )
|
||||
{
|
||||
/* we found it - run the parsing callback */
|
||||
parser->root.error = cid_load_keyword( face,
|
||||
loader,
|
||||
keyword );
|
||||
if ( parser->root.error )
|
||||
return parser->root.error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
keyword++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur = parser->root.cursor;
|
||||
}
|
||||
|
||||
if ( !face->cid.num_dicts )
|
||||
{
|
||||
FT_ERROR(( "cid_parse_dict: No font dictionary found\n" ));
|
||||
return FT_THROW( Invalid_File_Format );
|
||||
}
|
||||
}
|
||||
|
||||
return parser->root.error;
|
||||
}
|
||||
|
||||
|
||||
/* read the subrmap and the subrs of each font dict */
|
||||
static FT_Error
|
||||
cid_read_subrs( CID_Face face )
|
||||
{
|
||||
CID_FaceInfo cid = &face->cid;
|
||||
FT_Memory memory = face->root.memory;
|
||||
FT_Stream stream = face->cid_stream;
|
||||
FT_Error error;
|
||||
FT_UInt n;
|
||||
CID_Subrs subr;
|
||||
FT_UInt max_offsets = 0;
|
||||
FT_ULong* offsets = NULL;
|
||||
PSAux_Service psaux = (PSAux_Service)face->psaux;
|
||||
|
||||
|
||||
if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) )
|
||||
goto Exit;
|
||||
|
||||
subr = face->subrs;
|
||||
for ( n = 0; n < cid->num_dicts; n++, subr++ )
|
||||
{
|
||||
CID_FaceDict dict = cid->font_dicts + n;
|
||||
FT_Int lenIV = dict->private_dict.lenIV;
|
||||
FT_UInt count, num_subrs = dict->num_subrs;
|
||||
FT_ULong data_len;
|
||||
FT_Byte* p;
|
||||
|
||||
|
||||
if ( !num_subrs )
|
||||
continue;
|
||||
|
||||
/* reallocate offsets array if needed */
|
||||
if ( num_subrs + 1 > max_offsets )
|
||||
{
|
||||
FT_UInt new_max = FT_PAD_CEIL( num_subrs + 1, 4 );
|
||||
|
||||
|
||||
if ( new_max <= max_offsets )
|
||||
{
|
||||
error = FT_THROW( Syntax_Error );
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if ( FT_QRENEW_ARRAY( offsets, max_offsets, new_max ) )
|
||||
goto Fail;
|
||||
|
||||
max_offsets = new_max;
|
||||
}
|
||||
|
||||
/* read the subrmap's offsets */
|
||||
if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) ||
|
||||
FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) )
|
||||
goto Fail;
|
||||
|
||||
p = (FT_Byte*)stream->cursor;
|
||||
for ( count = 0; count <= num_subrs; count++ )
|
||||
offsets[count] = cid_get_offset( &p, dict->sd_bytes );
|
||||
|
||||
FT_FRAME_EXIT();
|
||||
|
||||
/* offsets must be ordered */
|
||||
for ( count = 1; count <= num_subrs; count++ )
|
||||
if ( offsets[count - 1] > offsets[count] )
|
||||
{
|
||||
FT_ERROR(( "cid_read_subrs: offsets are not ordered\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if ( offsets[num_subrs] > stream->size - cid->data_offset )
|
||||
{
|
||||
FT_ERROR(( "cid_read_subrs: too large `subrs' offsets\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
/* now, compute the size of subrs charstrings, */
|
||||
/* allocate, and read them */
|
||||
data_len = offsets[num_subrs] - offsets[0];
|
||||
|
||||
if ( FT_QNEW_ARRAY( subr->code, num_subrs + 1 ) ||
|
||||
FT_QALLOC( subr->code[0], data_len ) )
|
||||
goto Fail;
|
||||
|
||||
if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) ||
|
||||
FT_STREAM_READ( subr->code[0], data_len ) )
|
||||
goto Fail;
|
||||
|
||||
/* set up pointers */
|
||||
for ( count = 1; count <= num_subrs; count++ )
|
||||
{
|
||||
FT_ULong len;
|
||||
|
||||
|
||||
len = offsets[count] - offsets[count - 1];
|
||||
subr->code[count] = subr->code[count - 1] + len;
|
||||
}
|
||||
|
||||
/* decrypt subroutines, but only if lenIV >= 0 */
|
||||
if ( lenIV >= 0 )
|
||||
{
|
||||
for ( count = 0; count < num_subrs; count++ )
|
||||
{
|
||||
FT_ULong len;
|
||||
|
||||
|
||||
len = offsets[count + 1] - offsets[count];
|
||||
psaux->t1_decrypt( subr->code[count], len, 4330 );
|
||||
}
|
||||
}
|
||||
|
||||
subr->num_subrs = (FT_Int)num_subrs;
|
||||
}
|
||||
|
||||
Exit:
|
||||
FT_FREE( offsets );
|
||||
return error;
|
||||
|
||||
Fail:
|
||||
if ( face->subrs )
|
||||
{
|
||||
for ( n = 0; n < cid->num_dicts; n++ )
|
||||
{
|
||||
if ( face->subrs[n].code )
|
||||
FT_FREE( face->subrs[n].code[0] );
|
||||
|
||||
FT_FREE( face->subrs[n].code );
|
||||
}
|
||||
FT_FREE( face->subrs );
|
||||
}
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cid_init_loader( CID_Loader* loader,
|
||||
CID_Face face )
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
|
||||
FT_ZERO( loader );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cid_done_loader( CID_Loader* loader )
|
||||
{
|
||||
CID_Parser* parser = &loader->parser;
|
||||
|
||||
|
||||
/* finalize parser */
|
||||
cid_parser_done( parser );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
cid_hex_to_binary( FT_Byte* data,
|
||||
FT_ULong data_len,
|
||||
FT_ULong offset,
|
||||
CID_Face face,
|
||||
FT_ULong* data_written )
|
||||
{
|
||||
FT_Stream stream = face->root.stream;
|
||||
FT_Error error;
|
||||
|
||||
FT_Byte buffer[256];
|
||||
FT_Byte *p, *plimit;
|
||||
FT_Byte *d = data, *dlimit;
|
||||
FT_Byte val;
|
||||
|
||||
FT_Bool upper_nibble, done;
|
||||
|
||||
|
||||
if ( FT_STREAM_SEEK( offset ) )
|
||||
goto Exit;
|
||||
|
||||
dlimit = d + data_len;
|
||||
p = buffer;
|
||||
plimit = p;
|
||||
|
||||
upper_nibble = 1;
|
||||
done = 0;
|
||||
|
||||
while ( d < dlimit )
|
||||
{
|
||||
if ( p >= plimit )
|
||||
{
|
||||
FT_ULong oldpos = FT_STREAM_POS();
|
||||
FT_ULong size = stream->size - oldpos;
|
||||
|
||||
|
||||
if ( size == 0 )
|
||||
{
|
||||
error = FT_THROW( Syntax_Error );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( FT_STREAM_READ( buffer, 256 > size ? size : 256 ) )
|
||||
goto Exit;
|
||||
p = buffer;
|
||||
plimit = p + FT_STREAM_POS() - oldpos;
|
||||
}
|
||||
|
||||
if ( ft_isdigit( *p ) )
|
||||
val = (FT_Byte)( *p - '0' );
|
||||
else if ( *p >= 'a' && *p <= 'f' )
|
||||
val = (FT_Byte)( *p - 'a' + 10 );
|
||||
else if ( *p >= 'A' && *p <= 'F' )
|
||||
val = (FT_Byte)( *p - 'A' + 10 );
|
||||
else if ( *p == ' ' ||
|
||||
*p == '\t' ||
|
||||
*p == '\r' ||
|
||||
*p == '\n' ||
|
||||
*p == '\f' ||
|
||||
*p == '\0' )
|
||||
{
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
else if ( *p == '>' )
|
||||
{
|
||||
val = 0;
|
||||
done = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = FT_THROW( Syntax_Error );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( upper_nibble )
|
||||
*d = (FT_Byte)( val << 4 );
|
||||
else
|
||||
{
|
||||
*d = (FT_Byte)( *d + val );
|
||||
d++;
|
||||
}
|
||||
|
||||
upper_nibble = (FT_Byte)( 1 - upper_nibble );
|
||||
|
||||
if ( done )
|
||||
break;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
error = FT_Err_Ok;
|
||||
|
||||
Exit:
|
||||
*data_written = (FT_ULong)( d - data );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_face_open( CID_Face face,
|
||||
FT_Int face_index )
|
||||
{
|
||||
CID_Loader loader;
|
||||
CID_Parser* parser;
|
||||
FT_Memory memory = face->root.memory;
|
||||
FT_Error error;
|
||||
FT_UInt n;
|
||||
|
||||
CID_FaceInfo cid = &face->cid;
|
||||
|
||||
FT_ULong binary_length;
|
||||
|
||||
|
||||
cid_init_loader( &loader, face );
|
||||
|
||||
parser = &loader.parser;
|
||||
error = cid_parser_new( parser, face->root.stream, face->root.memory,
|
||||
(PSAux_Service)face->psaux );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
error = cid_parse_dict( face, &loader,
|
||||
parser->postscript,
|
||||
parser->postscript_len );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
if ( face_index < 0 )
|
||||
goto Exit;
|
||||
|
||||
if ( FT_NEW( face->cid_stream ) )
|
||||
goto Exit;
|
||||
|
||||
if ( parser->binary_length )
|
||||
{
|
||||
if ( parser->binary_length >
|
||||
face->root.stream->size - parser->data_offset )
|
||||
{
|
||||
FT_TRACE0(( "cid_face_open: adjusting length of binary data\n" ));
|
||||
FT_TRACE0(( " (from %lu to %lu bytes)\n",
|
||||
parser->binary_length,
|
||||
face->root.stream->size - parser->data_offset ));
|
||||
parser->binary_length = face->root.stream->size -
|
||||
parser->data_offset;
|
||||
}
|
||||
|
||||
/* we must convert the data section from hexadecimal to binary */
|
||||
if ( FT_QALLOC( face->binary_data, parser->binary_length ) ||
|
||||
FT_SET_ERROR( cid_hex_to_binary( face->binary_data,
|
||||
parser->binary_length,
|
||||
parser->data_offset,
|
||||
face,
|
||||
&binary_length ) ) )
|
||||
goto Exit;
|
||||
|
||||
FT_Stream_OpenMemory( face->cid_stream,
|
||||
face->binary_data, binary_length );
|
||||
cid->data_offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*face->cid_stream = *face->root.stream;
|
||||
cid->data_offset = loader.parser.data_offset;
|
||||
}
|
||||
|
||||
/* sanity tests */
|
||||
|
||||
if ( cid->gd_bytes == 0 )
|
||||
{
|
||||
FT_ERROR(( "cid_face_open:"
|
||||
" Invalid `GDBytes' value\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* allow at most 32bit offsets */
|
||||
if ( cid->fd_bytes > 4 || cid->gd_bytes > 4 )
|
||||
{
|
||||
FT_ERROR(( "cid_face_open:"
|
||||
" Values of `FDBytes' or `GDBytes' larger than 4\n" ));
|
||||
FT_ERROR(( " "
|
||||
" are not supported\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
binary_length = face->cid_stream->size - cid->data_offset;
|
||||
|
||||
if ( cid->cidmap_offset > binary_length )
|
||||
{
|
||||
FT_ERROR(( "cid_face_open: Invalid `CIDMapOffset' value\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* the initial pre-check prevents the multiplication overflow */
|
||||
if ( cid->cid_count > FT_ULONG_MAX / 8 ||
|
||||
cid->cid_count * ( cid->fd_bytes + cid->gd_bytes ) >
|
||||
binary_length - cid->cidmap_offset )
|
||||
{
|
||||
FT_ERROR(( "cid_face_open: Invalid `CIDCount' value\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
for ( n = 0; n < cid->num_dicts; n++ )
|
||||
{
|
||||
CID_FaceDict dict = cid->font_dicts + n;
|
||||
|
||||
|
||||
/* the upper limits are ad-hoc values */
|
||||
if ( dict->private_dict.blue_shift > 1000 ||
|
||||
dict->private_dict.blue_shift < 0 )
|
||||
{
|
||||
FT_TRACE2(( "cid_face_open:"
|
||||
" setting unlikely BlueShift value %d to default (7)\n",
|
||||
dict->private_dict.blue_shift ));
|
||||
dict->private_dict.blue_shift = 7;
|
||||
}
|
||||
|
||||
if ( dict->private_dict.blue_fuzz > 1000 ||
|
||||
dict->private_dict.blue_fuzz < 0 )
|
||||
{
|
||||
FT_TRACE2(( "cid_face_open:"
|
||||
" setting unlikely BlueFuzz value %d to default (1)\n",
|
||||
dict->private_dict.blue_fuzz ));
|
||||
dict->private_dict.blue_fuzz = 1;
|
||||
}
|
||||
|
||||
if ( dict->num_subrs && dict->sd_bytes == 0 )
|
||||
{
|
||||
FT_ERROR(( "cid_face_open: Invalid `SDBytes' value\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( dict->sd_bytes > 4 )
|
||||
{
|
||||
FT_ERROR(( "cid_face_open:"
|
||||
" Values of `SDBytes' larger than 4"
|
||||
" are not supported\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( dict->subrmap_offset > binary_length )
|
||||
{
|
||||
FT_ERROR(( "cid_face_open: Invalid `SubrMapOffset' value\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* the initial pre-check prevents the multiplication overflow */
|
||||
if ( dict->num_subrs > FT_UINT_MAX / 4 ||
|
||||
dict->num_subrs * dict->sd_bytes >
|
||||
binary_length - dict->subrmap_offset )
|
||||
{
|
||||
FT_ERROR(( "cid_face_open: Invalid `SubrCount' value\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* we can now safely proceed */
|
||||
error = cid_read_subrs( face );
|
||||
|
||||
Exit:
|
||||
cid_done_loader( &loader );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
52
internal/c/parts/video/font/freetype/cidload.h
Normal file
52
internal/c/parts/video/font/freetype/cidload.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidload.h
|
||||
*
|
||||
* CID-keyed Type1 font loader (specification).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 CIDLOAD_H_
|
||||
#define CIDLOAD_H_
|
||||
|
||||
|
||||
#include <freetype/internal/ftstream.h>
|
||||
#include "cidparse.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
typedef struct CID_Loader_
|
||||
{
|
||||
CID_Parser parser; /* parser used to read the stream */
|
||||
FT_Int num_chars; /* number of characters in encoding */
|
||||
|
||||
} CID_Loader;
|
||||
|
||||
|
||||
FT_LOCAL( FT_ULong )
|
||||
cid_get_offset( FT_Byte** start,
|
||||
FT_UInt offsize );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_face_open( CID_Face face,
|
||||
FT_Int face_index );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CIDLOAD_H_ */
|
||||
|
||||
|
||||
/* END */
|
543
internal/c/parts/video/font/freetype/cidobjs.c
Normal file
543
internal/c/parts/video/font/freetype/cidobjs.c
Normal file
|
@ -0,0 +1,543 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidobjs.c
|
||||
*
|
||||
* CID objects manager (body).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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/ftstream.h>
|
||||
|
||||
#include "cidgload.h"
|
||||
#include "cidload.h"
|
||||
|
||||
#include <freetype/internal/services/svpscmap.h>
|
||||
#include <freetype/internal/psaux.h>
|
||||
#include <freetype/internal/pshints.h>
|
||||
#include <freetype/ftdriver.h>
|
||||
|
||||
#include "ciderrs.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 cidobjs
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* SLOT FUNCTIONS
|
||||
*
|
||||
*/
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cid_slot_done( FT_GlyphSlot slot )
|
||||
{
|
||||
if ( slot->internal )
|
||||
slot->internal->glyph_hints = NULL;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_slot_init( FT_GlyphSlot slot )
|
||||
{
|
||||
CID_Face face;
|
||||
PSHinter_Service pshinter;
|
||||
|
||||
|
||||
face = (CID_Face)slot->face;
|
||||
pshinter = (PSHinter_Service)face->pshinter;
|
||||
|
||||
if ( pshinter )
|
||||
{
|
||||
FT_Module module;
|
||||
|
||||
|
||||
module = FT_Get_Module( slot->library, "pshinter" );
|
||||
if ( module )
|
||||
{
|
||||
T1_Hints_Funcs funcs;
|
||||
|
||||
|
||||
funcs = pshinter->get_t1_funcs( module );
|
||||
slot->internal->glyph_hints = (void*)funcs;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* SIZE FUNCTIONS
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
static PSH_Globals_Funcs
|
||||
cid_size_get_globals_funcs( CID_Size size )
|
||||
{
|
||||
CID_Face face = (CID_Face)size->root.face;
|
||||
PSHinter_Service pshinter = (PSHinter_Service)face->pshinter;
|
||||
FT_Module module;
|
||||
|
||||
|
||||
module = FT_Get_Module( size->root.face->driver->root.library,
|
||||
"pshinter" );
|
||||
return ( module && pshinter && pshinter->get_globals_funcs )
|
||||
? pshinter->get_globals_funcs( module )
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cid_size_done( FT_Size cidsize ) /* CID_Size */
|
||||
{
|
||||
CID_Size size = (CID_Size)cidsize;
|
||||
|
||||
|
||||
if ( cidsize->internal->module_data )
|
||||
{
|
||||
PSH_Globals_Funcs funcs;
|
||||
|
||||
|
||||
funcs = cid_size_get_globals_funcs( size );
|
||||
if ( funcs )
|
||||
funcs->destroy( (PSH_Globals)cidsize->internal->module_data );
|
||||
|
||||
cidsize->internal->module_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_size_init( FT_Size cidsize ) /* CID_Size */
|
||||
{
|
||||
CID_Size size = (CID_Size)cidsize;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
PSH_Globals_Funcs funcs = cid_size_get_globals_funcs( size );
|
||||
|
||||
|
||||
if ( funcs )
|
||||
{
|
||||
PSH_Globals globals;
|
||||
CID_Face face = (CID_Face)cidsize->face;
|
||||
CID_FaceDict dict = face->cid.font_dicts + face->root.face_index;
|
||||
PS_Private priv = &dict->private_dict;
|
||||
|
||||
|
||||
error = funcs->create( cidsize->face->memory, priv, &globals );
|
||||
if ( !error )
|
||||
cidsize->internal->module_data = globals;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_size_request( FT_Size size,
|
||||
FT_Size_Request req )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
PSH_Globals_Funcs funcs;
|
||||
|
||||
|
||||
error = FT_Request_Metrics( size->face, req );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
funcs = cid_size_get_globals_funcs( (CID_Size)size );
|
||||
|
||||
if ( funcs )
|
||||
funcs->set_scale( (PSH_Globals)size->internal->module_data,
|
||||
size->metrics.x_scale,
|
||||
size->metrics.y_scale,
|
||||
0, 0 );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* FACE FUNCTIONS
|
||||
*
|
||||
*/
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* cid_face_done
|
||||
*
|
||||
* @Description:
|
||||
* Finalizes a given face object.
|
||||
*
|
||||
* @Input:
|
||||
* face ::
|
||||
* A pointer to the face object to destroy.
|
||||
*/
|
||||
FT_LOCAL_DEF( void )
|
||||
cid_face_done( FT_Face cidface ) /* CID_Face */
|
||||
{
|
||||
CID_Face face = (CID_Face)cidface;
|
||||
FT_Memory memory;
|
||||
CID_FaceInfo cid;
|
||||
PS_FontInfo info;
|
||||
|
||||
|
||||
if ( !face )
|
||||
return;
|
||||
|
||||
cid = &face->cid;
|
||||
info = &cid->font_info;
|
||||
memory = cidface->memory;
|
||||
|
||||
/* release subrs */
|
||||
if ( face->subrs )
|
||||
{
|
||||
FT_UInt n;
|
||||
|
||||
|
||||
for ( n = 0; n < cid->num_dicts; n++ )
|
||||
{
|
||||
CID_Subrs subr = face->subrs + n;
|
||||
|
||||
|
||||
if ( subr->code )
|
||||
{
|
||||
FT_FREE( subr->code[0] );
|
||||
FT_FREE( subr->code );
|
||||
}
|
||||
}
|
||||
|
||||
FT_FREE( face->subrs );
|
||||
}
|
||||
|
||||
/* release FontInfo strings */
|
||||
FT_FREE( info->version );
|
||||
FT_FREE( info->notice );
|
||||
FT_FREE( info->full_name );
|
||||
FT_FREE( info->family_name );
|
||||
FT_FREE( info->weight );
|
||||
|
||||
/* release font dictionaries */
|
||||
FT_FREE( cid->font_dicts );
|
||||
cid->num_dicts = 0;
|
||||
|
||||
/* release other strings */
|
||||
FT_FREE( cid->cid_font_name );
|
||||
FT_FREE( cid->registry );
|
||||
FT_FREE( cid->ordering );
|
||||
|
||||
cidface->family_name = NULL;
|
||||
cidface->style_name = NULL;
|
||||
|
||||
FT_FREE( face->binary_data );
|
||||
FT_FREE( face->cid_stream );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* cid_face_init
|
||||
*
|
||||
* @Description:
|
||||
* Initializes a given CID face object.
|
||||
*
|
||||
* @Input:
|
||||
* stream ::
|
||||
* Dummy argument for compatibility with the `FT_Face_InitFunc` API.
|
||||
* Ignored. The stream should be passed through `face->root.stream`.
|
||||
*
|
||||
* face_index ::
|
||||
* The index of the font face in the resource.
|
||||
*
|
||||
* num_params ::
|
||||
* Number of additional generic parameters. Ignored.
|
||||
*
|
||||
* params ::
|
||||
* Additional generic parameters. Ignored.
|
||||
*
|
||||
* @InOut:
|
||||
* face ::
|
||||
* The newly built face object.
|
||||
*
|
||||
* @Return:
|
||||
* FreeType error code. 0 means success.
|
||||
*/
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_face_init( FT_Stream stream,
|
||||
FT_Face cidface, /* CID_Face */
|
||||
FT_Int face_index,
|
||||
FT_Int num_params,
|
||||
FT_Parameter* params )
|
||||
{
|
||||
CID_Face face = (CID_Face)cidface;
|
||||
FT_Error error;
|
||||
PSAux_Service psaux;
|
||||
PSHinter_Service pshinter;
|
||||
|
||||
FT_UNUSED( num_params );
|
||||
FT_UNUSED( params );
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
cidface->num_faces = 1;
|
||||
|
||||
psaux = (PSAux_Service)face->psaux;
|
||||
if ( !psaux )
|
||||
{
|
||||
psaux = (PSAux_Service)FT_Get_Module_Interface(
|
||||
FT_FACE_LIBRARY( face ), "psaux" );
|
||||
|
||||
if ( !psaux )
|
||||
{
|
||||
FT_ERROR(( "cid_face_init: cannot access `psaux' module\n" ));
|
||||
error = FT_THROW( Missing_Module );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
face->psaux = psaux;
|
||||
}
|
||||
|
||||
pshinter = (PSHinter_Service)face->pshinter;
|
||||
if ( !pshinter )
|
||||
{
|
||||
pshinter = (PSHinter_Service)FT_Get_Module_Interface(
|
||||
FT_FACE_LIBRARY( face ), "pshinter" );
|
||||
|
||||
face->pshinter = pshinter;
|
||||
}
|
||||
|
||||
FT_TRACE2(( "CID driver\n" ));
|
||||
|
||||
/* open the tokenizer; this will also check the font format */
|
||||
if ( FT_STREAM_SEEK( 0 ) )
|
||||
goto Exit;
|
||||
|
||||
error = cid_face_open( face, face_index );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* if we just wanted to check the format, leave successfully now */
|
||||
if ( face_index < 0 )
|
||||
goto Exit;
|
||||
|
||||
/* check the face index */
|
||||
/* XXX: handle CID fonts with more than a single face */
|
||||
if ( ( face_index & 0xFFFF ) != 0 )
|
||||
{
|
||||
FT_ERROR(( "cid_face_init: invalid face index\n" ));
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* now load the font program into the face object */
|
||||
|
||||
/* initialize the face object fields */
|
||||
|
||||
/* set up root face fields */
|
||||
{
|
||||
CID_FaceInfo cid = &face->cid;
|
||||
PS_FontInfo info = &cid->font_info;
|
||||
|
||||
|
||||
cidface->num_glyphs = (FT_Long)cid->cid_count;
|
||||
cidface->num_charmaps = 0;
|
||||
|
||||
cidface->face_index = face_index & 0xFFFF;
|
||||
|
||||
cidface->face_flags |= FT_FACE_FLAG_SCALABLE | /* scalable outlines */
|
||||
FT_FACE_FLAG_HORIZONTAL | /* horizontal data */
|
||||
FT_FACE_FLAG_HINTER; /* has native hinter */
|
||||
|
||||
if ( info->is_fixed_pitch )
|
||||
cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
|
||||
|
||||
/*
|
||||
* For the sfnt-wrapped CID fonts for MacOS, currently,
|
||||
* its `cmap' tables are ignored, and the content in
|
||||
* its `CID ' table is treated the same as naked CID-keyed
|
||||
* font. See ft_lookup_PS_in_sfnt_stream().
|
||||
*/
|
||||
cidface->face_flags |= FT_FACE_FLAG_CID_KEYED;
|
||||
|
||||
/* XXX: TODO: add kerning with .afm support */
|
||||
|
||||
/* get style name -- be careful, some broken fonts only */
|
||||
/* have a /FontName dictionary entry! */
|
||||
cidface->family_name = info->family_name;
|
||||
/* assume "Regular" style if we don't know better */
|
||||
cidface->style_name = (char *)"Regular";
|
||||
if ( cidface->family_name )
|
||||
{
|
||||
char* full = info->full_name;
|
||||
char* family = cidface->family_name;
|
||||
|
||||
|
||||
if ( full )
|
||||
{
|
||||
while ( *full )
|
||||
{
|
||||
if ( *full == *family )
|
||||
{
|
||||
family++;
|
||||
full++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( *full == ' ' || *full == '-' )
|
||||
full++;
|
||||
else if ( *family == ' ' || *family == '-' )
|
||||
family++;
|
||||
else
|
||||
{
|
||||
if ( !*family )
|
||||
cidface->style_name = full;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* do we have a `/FontName'? */
|
||||
if ( cid->cid_font_name )
|
||||
cidface->family_name = cid->cid_font_name;
|
||||
}
|
||||
|
||||
/* compute style flags */
|
||||
cidface->style_flags = 0;
|
||||
if ( info->italic_angle )
|
||||
cidface->style_flags |= FT_STYLE_FLAG_ITALIC;
|
||||
if ( info->weight )
|
||||
{
|
||||
if ( !ft_strcmp( info->weight, "Bold" ) ||
|
||||
!ft_strcmp( info->weight, "Black" ) )
|
||||
cidface->style_flags |= FT_STYLE_FLAG_BOLD;
|
||||
}
|
||||
|
||||
/* no embedded bitmap support */
|
||||
cidface->num_fixed_sizes = 0;
|
||||
cidface->available_sizes = NULL;
|
||||
|
||||
cidface->bbox.xMin = cid->font_bbox.xMin >> 16;
|
||||
cidface->bbox.yMin = cid->font_bbox.yMin >> 16;
|
||||
/* no `U' suffix here to 0xFFFF! */
|
||||
cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFF ) >> 16;
|
||||
cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFF ) >> 16;
|
||||
|
||||
if ( !cidface->units_per_EM )
|
||||
cidface->units_per_EM = 1000;
|
||||
|
||||
cidface->ascender = (FT_Short)( cidface->bbox.yMax );
|
||||
cidface->descender = (FT_Short)( cidface->bbox.yMin );
|
||||
|
||||
cidface->height = (FT_Short)( ( cidface->units_per_EM * 12 ) / 10 );
|
||||
if ( cidface->height < cidface->ascender - cidface->descender )
|
||||
cidface->height = (FT_Short)( cidface->ascender - cidface->descender );
|
||||
|
||||
cidface->underline_position = (FT_Short)info->underline_position;
|
||||
cidface->underline_thickness = (FT_Short)info->underline_thickness;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* cid_driver_init
|
||||
*
|
||||
* @Description:
|
||||
* Initializes a given CID driver object.
|
||||
*
|
||||
* @Input:
|
||||
* driver ::
|
||||
* A handle to the target driver object.
|
||||
*
|
||||
* @Return:
|
||||
* FreeType error code. 0 means success.
|
||||
*/
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_driver_init( FT_Module module )
|
||||
{
|
||||
PS_Driver driver = (PS_Driver)module;
|
||||
|
||||
FT_UInt32 seed;
|
||||
|
||||
|
||||
/* set default property values, cf. `ftt1drv.h' */
|
||||
driver->hinting_engine = FT_HINTING_ADOBE;
|
||||
|
||||
driver->no_stem_darkening = TRUE;
|
||||
|
||||
driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
|
||||
driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1;
|
||||
driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2;
|
||||
driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2;
|
||||
driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3;
|
||||
driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3;
|
||||
driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4;
|
||||
driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4;
|
||||
|
||||
/* compute random seed from some memory addresses */
|
||||
seed = (FT_UInt32)( (FT_Offset)(char*)&seed ^
|
||||
(FT_Offset)(char*)&module ^
|
||||
(FT_Offset)(char*)module->memory );
|
||||
seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 );
|
||||
|
||||
driver->random_seed = (FT_Int32)seed;
|
||||
if ( driver->random_seed < 0 )
|
||||
driver->random_seed = -driver->random_seed;
|
||||
else if ( driver->random_seed == 0 )
|
||||
driver->random_seed = 123456789;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
* cid_driver_done
|
||||
*
|
||||
* @Description:
|
||||
* Finalizes a given CID driver.
|
||||
*
|
||||
* @Input:
|
||||
* driver ::
|
||||
* A handle to the target CID driver.
|
||||
*/
|
||||
FT_LOCAL_DEF( void )
|
||||
cid_driver_done( FT_Module driver )
|
||||
{
|
||||
FT_UNUSED( driver );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
154
internal/c/parts/video/font/freetype/cidobjs.h
Normal file
154
internal/c/parts/video/font/freetype/cidobjs.h
Normal file
|
@ -0,0 +1,154 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidobjs.h
|
||||
*
|
||||
* CID objects manager (specification).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 CIDOBJS_H_
|
||||
#define CIDOBJS_H_
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include <freetype/internal/t1types.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* The following structures must be defined by the hinter */
|
||||
typedef struct CID_Size_Hints_ CID_Size_Hints;
|
||||
typedef struct CID_Glyph_Hints_ CID_Glyph_Hints;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Type:
|
||||
* CID_Driver
|
||||
*
|
||||
* @Description:
|
||||
* A handle to a Type 1 driver object.
|
||||
*/
|
||||
typedef struct CID_DriverRec_* CID_Driver;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Type:
|
||||
* CID_Size
|
||||
*
|
||||
* @Description:
|
||||
* A handle to a Type 1 size object.
|
||||
*/
|
||||
typedef struct CID_SizeRec_* CID_Size;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Type:
|
||||
* CID_GlyphSlot
|
||||
*
|
||||
* @Description:
|
||||
* A handle to a Type 1 glyph slot object.
|
||||
*/
|
||||
typedef struct CID_GlyphSlotRec_* CID_GlyphSlot;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Type:
|
||||
* CID_CharMap
|
||||
*
|
||||
* @Description:
|
||||
* A handle to a Type 1 character mapping object.
|
||||
*
|
||||
* @Note:
|
||||
* The Type 1 format doesn't use a charmap but an encoding table.
|
||||
* The driver is responsible for making up charmap objects
|
||||
* corresponding to these tables.
|
||||
*/
|
||||
typedef struct CID_CharMapRec_* CID_CharMap;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* HERE BEGINS THE TYPE 1 SPECIFIC STUFF
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
typedef struct CID_SizeRec_
|
||||
{
|
||||
FT_SizeRec root;
|
||||
FT_Bool valid;
|
||||
|
||||
} CID_SizeRec;
|
||||
|
||||
|
||||
typedef struct CID_GlyphSlotRec_
|
||||
{
|
||||
FT_GlyphSlotRec root;
|
||||
|
||||
FT_Bool hint;
|
||||
FT_Bool scaled;
|
||||
|
||||
FT_Fixed x_scale;
|
||||
FT_Fixed y_scale;
|
||||
|
||||
} CID_GlyphSlotRec;
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
cid_slot_done( FT_GlyphSlot slot );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_slot_init( FT_GlyphSlot slot );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
cid_size_done( FT_Size size ); /* CID_Size */
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_size_init( FT_Size size ); /* CID_Size */
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_size_request( FT_Size size, /* CID_Size */
|
||||
FT_Size_Request req );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_face_init( FT_Stream stream,
|
||||
FT_Face face, /* CID_Face */
|
||||
FT_Int face_index,
|
||||
FT_Int num_params,
|
||||
FT_Parameter* params );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cid_face_done( FT_Face face ); /* CID_Face */
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_driver_init( FT_Module driver );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cid_driver_done( FT_Module driver );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CIDOBJS_H_ */
|
||||
|
||||
|
||||
/* END */
|
286
internal/c/parts/video/font/freetype/cidparse.c
Normal file
286
internal/c/parts/video/font/freetype/cidparse.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidparse.c
|
||||
*
|
||||
* CID-keyed Type1 parser (body).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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/ftstream.h>
|
||||
|
||||
#include "cidparse.h"
|
||||
|
||||
#include "ciderrs.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 cidparse
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** INPUT STREAM PARSER *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#define STARTDATA "StartData"
|
||||
#define STARTDATA_LEN ( sizeof ( STARTDATA ) - 1 )
|
||||
#define SFNTS "/sfnts"
|
||||
#define SFNTS_LEN ( sizeof ( SFNTS ) - 1 )
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_parser_new( CID_Parser* parser,
|
||||
FT_Stream stream,
|
||||
FT_Memory memory,
|
||||
PSAux_Service psaux )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_ULong base_offset, offset, ps_len;
|
||||
FT_Byte *cur, *limit;
|
||||
FT_Byte *arg1, *arg2;
|
||||
|
||||
|
||||
FT_ZERO( parser );
|
||||
psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
|
||||
|
||||
parser->stream = stream;
|
||||
|
||||
base_offset = FT_STREAM_POS();
|
||||
|
||||
/* first of all, check the font format in the header */
|
||||
if ( FT_FRAME_ENTER( 31 ) )
|
||||
{
|
||||
FT_TRACE2(( " not a CID-keyed font\n" ));
|
||||
error = FT_THROW( Unknown_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( ft_strncmp( (char *)stream->cursor,
|
||||
"%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
|
||||
{
|
||||
FT_TRACE2(( " not a CID-keyed font\n" ));
|
||||
error = FT_THROW( Unknown_File_Format );
|
||||
}
|
||||
|
||||
FT_FRAME_EXIT();
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
Again:
|
||||
/* now, read the rest of the file until we find */
|
||||
/* `StartData' or `/sfnts' */
|
||||
{
|
||||
/*
|
||||
* The algorithm is as follows (omitting the case with less than 256
|
||||
* bytes to fill for simplicity).
|
||||
*
|
||||
* 1. Fill the buffer with 256 + STARTDATA_LEN bytes.
|
||||
*
|
||||
* 2. Search for the STARTDATA and SFNTS strings at positions
|
||||
* buffer[0], buffer[1], ...,
|
||||
* buffer[255 + STARTDATA_LEN - SFNTS_LEN].
|
||||
*
|
||||
* 3. Move the last STARTDATA_LEN bytes to buffer[0].
|
||||
*
|
||||
* 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN.
|
||||
*
|
||||
* 5. Repeat with step 2.
|
||||
*
|
||||
*/
|
||||
FT_Byte buffer[256 + STARTDATA_LEN + 1];
|
||||
|
||||
/* values for the first loop */
|
||||
FT_ULong read_len = 256 + STARTDATA_LEN;
|
||||
FT_ULong read_offset = 0;
|
||||
FT_Byte* p = buffer;
|
||||
|
||||
|
||||
for ( offset = FT_STREAM_POS(); ; offset += 256 )
|
||||
{
|
||||
FT_ULong stream_len;
|
||||
|
||||
|
||||
stream_len = stream->size - FT_STREAM_POS();
|
||||
|
||||
read_len = FT_MIN( read_len, stream_len );
|
||||
if ( FT_STREAM_READ( p, read_len ) )
|
||||
goto Exit;
|
||||
|
||||
/* ensure that we do not compare with data beyond the buffer */
|
||||
p[read_len] = '\0';
|
||||
|
||||
limit = p + read_len - SFNTS_LEN;
|
||||
|
||||
for ( p = buffer; p < limit; p++ )
|
||||
{
|
||||
if ( p[0] == 'S' &&
|
||||
ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 )
|
||||
{
|
||||
/* save offset of binary data after `StartData' */
|
||||
offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN + 1;
|
||||
goto Found;
|
||||
}
|
||||
else if ( p[1] == 's' &&
|
||||
ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 )
|
||||
{
|
||||
offset += (FT_ULong)( p - buffer ) + SFNTS_LEN + 1;
|
||||
goto Found;
|
||||
}
|
||||
}
|
||||
|
||||
if ( read_offset + read_len < STARTDATA_LEN )
|
||||
{
|
||||
FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
FT_MEM_MOVE( buffer,
|
||||
buffer + read_offset + read_len - STARTDATA_LEN,
|
||||
STARTDATA_LEN );
|
||||
|
||||
/* values for the next loop */
|
||||
read_len = 256;
|
||||
read_offset = STARTDATA_LEN;
|
||||
p = buffer + read_offset;
|
||||
}
|
||||
}
|
||||
|
||||
Found:
|
||||
/* We have found the start of the binary data or the `/sfnts' token. */
|
||||
/* Now rewind and extract the frame corresponding to this PostScript */
|
||||
/* section. */
|
||||
|
||||
ps_len = offset - base_offset;
|
||||
if ( FT_STREAM_SEEK( base_offset ) ||
|
||||
FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
|
||||
goto Exit;
|
||||
|
||||
parser->data_offset = offset;
|
||||
parser->postscript_len = ps_len;
|
||||
parser->root.base = parser->postscript;
|
||||
parser->root.cursor = parser->postscript;
|
||||
parser->root.limit = parser->root.cursor + ps_len;
|
||||
parser->num_dict = FT_UINT_MAX;
|
||||
|
||||
/* Finally, we check whether `StartData' or `/sfnts' was real -- */
|
||||
/* it could be in a comment or string. We also get the arguments */
|
||||
/* of `StartData' to find out whether the data is represented in */
|
||||
/* binary or hex format. */
|
||||
|
||||
arg1 = parser->root.cursor;
|
||||
cid_parser_skip_PS_token( parser );
|
||||
cid_parser_skip_spaces ( parser );
|
||||
arg2 = parser->root.cursor;
|
||||
cid_parser_skip_PS_token( parser );
|
||||
cid_parser_skip_spaces ( parser );
|
||||
|
||||
limit = parser->root.limit;
|
||||
cur = parser->root.cursor;
|
||||
|
||||
while ( cur <= limit - SFNTS_LEN )
|
||||
{
|
||||
if ( parser->root.error )
|
||||
{
|
||||
error = parser->root.error;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( cur[0] == 'S' &&
|
||||
cur <= limit - STARTDATA_LEN &&
|
||||
ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
|
||||
{
|
||||
T1_TokenRec type_token;
|
||||
FT_Long binary_length;
|
||||
|
||||
|
||||
parser->root.cursor = arg1;
|
||||
cid_parser_to_token( parser, &type_token );
|
||||
if ( type_token.limit - type_token.start == 5 &&
|
||||
ft_memcmp( (char*)type_token.start, "(Hex)", 5 ) == 0 )
|
||||
{
|
||||
parser->root.cursor = arg2;
|
||||
binary_length = cid_parser_to_int( parser );
|
||||
if ( binary_length < 0 )
|
||||
{
|
||||
FT_ERROR(( "cid_parser_new: invalid length of hex data\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
}
|
||||
else
|
||||
parser->binary_length = (FT_ULong)binary_length;
|
||||
}
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
else if ( cur[1] == 's' &&
|
||||
ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 )
|
||||
{
|
||||
FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
|
||||
error = FT_THROW( Unknown_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
cid_parser_skip_PS_token( parser );
|
||||
cid_parser_skip_spaces ( parser );
|
||||
arg1 = arg2;
|
||||
arg2 = cur;
|
||||
cur = parser->root.cursor;
|
||||
}
|
||||
|
||||
/* we haven't found the correct `StartData'; go back and continue */
|
||||
/* searching */
|
||||
FT_FRAME_RELEASE( parser->postscript );
|
||||
if ( !FT_STREAM_SEEK( offset ) )
|
||||
goto Again;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#undef STARTDATA
|
||||
#undef STARTDATA_LEN
|
||||
#undef SFNTS
|
||||
#undef SFNTS_LEN
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cid_parser_done( CID_Parser* parser )
|
||||
{
|
||||
/* always free the private dictionary */
|
||||
if ( parser->postscript )
|
||||
{
|
||||
FT_Stream stream = parser->stream;
|
||||
|
||||
|
||||
FT_FRAME_RELEASE( parser->postscript );
|
||||
}
|
||||
parser->root.funcs.done( &parser->root );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
130
internal/c/parts/video/font/freetype/cidparse.h
Normal file
130
internal/c/parts/video/font/freetype/cidparse.h
Normal file
|
@ -0,0 +1,130 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidparse.h
|
||||
*
|
||||
* CID-keyed Type1 parser (specification).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 CIDPARSE_H_
|
||||
#define CIDPARSE_H_
|
||||
|
||||
|
||||
#include <freetype/internal/t1types.h>
|
||||
#include <freetype/internal/ftstream.h>
|
||||
#include <freetype/internal/psaux.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Struct:
|
||||
* CID_Parser
|
||||
*
|
||||
* @Description:
|
||||
* A CID_Parser is an object used to parse a Type 1 fonts very
|
||||
* quickly.
|
||||
*
|
||||
* @Fields:
|
||||
* root ::
|
||||
* The root PS_ParserRec fields.
|
||||
*
|
||||
* stream ::
|
||||
* The current input stream.
|
||||
*
|
||||
* postscript ::
|
||||
* A pointer to the data to be parsed.
|
||||
*
|
||||
* postscript_len ::
|
||||
* The length of the data to be parsed.
|
||||
*
|
||||
* data_offset ::
|
||||
* The start position of the binary data (i.e., the
|
||||
* end of the data to be parsed.
|
||||
*
|
||||
* binary_length ::
|
||||
* The length of the data after the `StartData'
|
||||
* command if the data format is hexadecimal.
|
||||
*
|
||||
* cid ::
|
||||
* A structure which holds the information about
|
||||
* the current font.
|
||||
*
|
||||
* num_dict ::
|
||||
* The number of font dictionaries.
|
||||
*/
|
||||
typedef struct CID_Parser_
|
||||
{
|
||||
PS_ParserRec root;
|
||||
FT_Stream stream;
|
||||
|
||||
FT_Byte* postscript;
|
||||
FT_ULong postscript_len;
|
||||
|
||||
FT_ULong data_offset;
|
||||
|
||||
FT_ULong binary_length;
|
||||
|
||||
CID_FaceInfo cid;
|
||||
FT_UInt num_dict;
|
||||
|
||||
} CID_Parser;
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_parser_new( CID_Parser* parser,
|
||||
FT_Stream stream,
|
||||
FT_Memory memory,
|
||||
PSAux_Service psaux );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cid_parser_done( CID_Parser* parser );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* PARSING ROUTINES
|
||||
*
|
||||
*/
|
||||
|
||||
#define cid_parser_skip_spaces( p ) \
|
||||
(p)->root.funcs.skip_spaces( &(p)->root )
|
||||
#define cid_parser_skip_PS_token( p ) \
|
||||
(p)->root.funcs.skip_PS_token( &(p)->root )
|
||||
|
||||
#define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root )
|
||||
#define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t )
|
||||
|
||||
#define cid_parser_to_coord_array( p, m, c ) \
|
||||
(p)->root.funcs.to_coord_array( &(p)->root, m, c )
|
||||
#define cid_parser_to_fixed_array( p, m, f, t ) \
|
||||
(p)->root.funcs.to_fixed_array( &(p)->root, m, f, t )
|
||||
#define cid_parser_to_token( p, t ) \
|
||||
(p)->root.funcs.to_token( &(p)->root, t )
|
||||
#define cid_parser_to_token_array( p, t, m, c ) \
|
||||
(p)->root.funcs.to_token_array( &(p)->root, t, m, c )
|
||||
|
||||
#define cid_parser_load_field( p, f, o ) \
|
||||
(p)->root.funcs.load_field( &(p)->root, f, o, 0, 0 )
|
||||
#define cid_parser_load_field_table( p, f, o ) \
|
||||
(p)->root.funcs.load_field_table( &(p)->root, f, o, 0, 0 )
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CIDPARSE_H_ */
|
||||
|
||||
|
||||
/* END */
|
274
internal/c/parts/video/font/freetype/cidriver.c
Normal file
274
internal/c/parts/video/font/freetype/cidriver.c
Normal file
|
@ -0,0 +1,274 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidriver.c
|
||||
*
|
||||
* CID driver interface (body).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 "cidriver.h"
|
||||
#include "cidgload.h"
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftpsprop.h>
|
||||
|
||||
#include "ciderrs.h"
|
||||
|
||||
#include <freetype/internal/services/svpostnm.h>
|
||||
#include <freetype/internal/services/svfntfmt.h>
|
||||
#include <freetype/internal/services/svpsinfo.h>
|
||||
#include <freetype/internal/services/svcid.h>
|
||||
#include <freetype/internal/services/svprop.h>
|
||||
#include <freetype/ftdriver.h>
|
||||
|
||||
#include <freetype/internal/psaux.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 ciddriver
|
||||
|
||||
|
||||
/*
|
||||
* POSTSCRIPT NAME SERVICE
|
||||
*
|
||||
*/
|
||||
|
||||
FT_CALLBACK_DEF( const char* )
|
||||
cid_get_postscript_name( FT_Face face ) /* CID_Face */
|
||||
{
|
||||
CID_Face cidface = (CID_Face)face;
|
||||
const char* result = cidface->cid.cid_font_name;
|
||||
|
||||
|
||||
if ( result && result[0] == '/' )
|
||||
result++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static const FT_Service_PsFontNameRec cid_service_ps_name =
|
||||
{
|
||||
(FT_PsName_GetFunc)cid_get_postscript_name /* get_ps_font_name */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* POSTSCRIPT INFO SERVICE
|
||||
*
|
||||
*/
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cid_ps_get_font_info( FT_Face face, /* CID_Face */
|
||||
PS_FontInfoRec* afont_info )
|
||||
{
|
||||
*afont_info = ( (CID_Face)face )->cid.font_info;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cid_ps_get_font_extra( FT_Face face, /* CID_Face */
|
||||
PS_FontExtraRec* afont_extra )
|
||||
{
|
||||
*afont_extra = ( (CID_Face)face )->font_extra;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static const FT_Service_PsInfoRec cid_service_ps_info =
|
||||
{
|
||||
cid_ps_get_font_info, /* PS_GetFontInfoFunc ps_get_font_info */
|
||||
cid_ps_get_font_extra, /* PS_GetFontExtraFunc ps_get_font_extra */
|
||||
/* unsupported with CID fonts */
|
||||
NULL, /* PS_HasGlyphNamesFunc ps_has_glyph_names */
|
||||
/* unsupported */
|
||||
NULL, /* PS_GetFontPrivateFunc ps_get_font_private */
|
||||
/* not implemented */
|
||||
NULL /* PS_GetFontValueFunc ps_get_font_value */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* CID INFO SERVICE
|
||||
*
|
||||
*/
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cid_get_ros( FT_Face face, /* CID_Face */
|
||||
const char* *registry,
|
||||
const char* *ordering,
|
||||
FT_Int *supplement )
|
||||
{
|
||||
CID_Face cidface = (CID_Face)face;
|
||||
CID_FaceInfo cid = &cidface->cid;
|
||||
|
||||
|
||||
if ( registry )
|
||||
*registry = cid->registry;
|
||||
|
||||
if ( ordering )
|
||||
*ordering = cid->ordering;
|
||||
|
||||
if ( supplement )
|
||||
*supplement = cid->supplement;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cid_get_is_cid( FT_Face face, /* CID_Face */
|
||||
FT_Bool *is_cid )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_UNUSED( face );
|
||||
|
||||
|
||||
/*
|
||||
* XXX: If the ROS is Adobe-Identity-H or -V,
|
||||
* the font has no reliable information about
|
||||
* its glyph collection. Should we not set
|
||||
* *is_cid in such cases?
|
||||
*/
|
||||
if ( is_cid )
|
||||
*is_cid = 1;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cid_get_cid_from_glyph_index( FT_Face face, /* CID_Face */
|
||||
FT_UInt glyph_index,
|
||||
FT_UInt *cid )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
CID_Face cidface = (CID_Face)face;
|
||||
|
||||
|
||||
/*
|
||||
* Currently, FreeType does not support incrementally-defined, CID-keyed
|
||||
* fonts that store the glyph description data in a `/GlyphDirectory`
|
||||
* array or dictionary. Fonts loaded by the incremental loading feature
|
||||
* are thus not handled here.
|
||||
*/
|
||||
error = cid_compute_fd_and_offsets( cidface, glyph_index,
|
||||
NULL, NULL, NULL );
|
||||
if ( error )
|
||||
*cid = 0;
|
||||
else
|
||||
*cid = glyph_index;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static const FT_Service_CIDRec cid_service_cid_info =
|
||||
{
|
||||
cid_get_ros,
|
||||
/* FT_CID_GetRegistryOrderingSupplementFunc get_ros */
|
||||
cid_get_is_cid,
|
||||
/* FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid */
|
||||
cid_get_cid_from_glyph_index
|
||||
/* FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* PROPERTY SERVICE
|
||||
*
|
||||
*/
|
||||
|
||||
FT_DEFINE_SERVICE_PROPERTIESREC(
|
||||
cid_service_properties,
|
||||
|
||||
ps_property_set, /* FT_Properties_SetFunc set_property */
|
||||
ps_property_get /* FT_Properties_GetFunc get_property */
|
||||
)
|
||||
|
||||
/*
|
||||
* SERVICE LIST
|
||||
*
|
||||
*/
|
||||
|
||||
static const FT_ServiceDescRec cid_services[] =
|
||||
{
|
||||
{ FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CID },
|
||||
{ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name },
|
||||
{ FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info },
|
||||
{ FT_SERVICE_ID_CID, &cid_service_cid_info },
|
||||
{ FT_SERVICE_ID_PROPERTIES, &cid_service_properties },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Module_Interface )
|
||||
cid_get_interface( FT_Module module,
|
||||
const char* cid_interface )
|
||||
{
|
||||
FT_UNUSED( module );
|
||||
|
||||
return ft_service_list_lookup( cid_services, cid_interface );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const FT_Driver_ClassRec t1cid_driver_class =
|
||||
{
|
||||
{
|
||||
FT_MODULE_FONT_DRIVER |
|
||||
FT_MODULE_DRIVER_SCALABLE |
|
||||
FT_MODULE_DRIVER_HAS_HINTER,
|
||||
sizeof ( PS_DriverRec ),
|
||||
|
||||
"t1cid", /* module name */
|
||||
0x10000L, /* version 1.0 of driver */
|
||||
0x20000L, /* requires FreeType 2.0 */
|
||||
|
||||
NULL, /* module-specific interface */
|
||||
|
||||
cid_driver_init, /* FT_Module_Constructor module_init */
|
||||
cid_driver_done, /* FT_Module_Destructor module_done */
|
||||
cid_get_interface /* FT_Module_Requester get_interface */
|
||||
},
|
||||
|
||||
sizeof ( CID_FaceRec ),
|
||||
sizeof ( CID_SizeRec ),
|
||||
sizeof ( CID_GlyphSlotRec ),
|
||||
|
||||
cid_face_init, /* FT_Face_InitFunc init_face */
|
||||
cid_face_done, /* FT_Face_DoneFunc done_face */
|
||||
cid_size_init, /* FT_Size_InitFunc init_size */
|
||||
cid_size_done, /* FT_Size_DoneFunc done_size */
|
||||
cid_slot_init, /* FT_Slot_InitFunc init_slot */
|
||||
cid_slot_done, /* FT_Slot_DoneFunc done_slot */
|
||||
|
||||
cid_slot_load_glyph, /* FT_Slot_LoadFunc load_glyph */
|
||||
|
||||
NULL, /* FT_Face_GetKerningFunc get_kerning */
|
||||
NULL, /* FT_Face_AttachFunc attach_file */
|
||||
NULL, /* FT_Face_GetAdvancesFunc get_advances */
|
||||
|
||||
cid_size_request, /* FT_Size_RequestFunc request_size */
|
||||
NULL /* FT_Size_SelectFunc select_size */
|
||||
};
|
||||
|
||||
|
||||
/* END */
|
36
internal/c/parts/video/font/freetype/cidriver.h
Normal file
36
internal/c/parts/video/font/freetype/cidriver.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidriver.h
|
||||
*
|
||||
* High-level CID driver interface (specification).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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 CIDRIVER_H_
|
||||
#define CIDRIVER_H_
|
||||
|
||||
|
||||
#include <freetype/internal/ftdrv.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
FT_CALLBACK_TABLE
|
||||
const FT_Driver_ClassRec t1cid_driver_class;
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CIDRIVER_H_ */
|
||||
|
||||
|
||||
/* END */
|
115
internal/c/parts/video/font/freetype/cidtoken.h
Normal file
115
internal/c/parts/video/font/freetype/cidtoken.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* cidtoken.h
|
||||
*
|
||||
* CID token definitions (specification only).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CID_FaceInfoRec
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_CID_INFO
|
||||
|
||||
T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 )
|
||||
T1_FIELD_FIXED ( "CIDFontVersion", cid_version, 0 )
|
||||
T1_FIELD_NUM ( "CIDFontType", cid_font_type, 0 )
|
||||
T1_FIELD_STRING ( "Registry", registry, 0 )
|
||||
T1_FIELD_STRING ( "Ordering", ordering, 0 )
|
||||
T1_FIELD_NUM ( "Supplement", supplement, 0 )
|
||||
T1_FIELD_NUM ( "UIDBase", uid_base, 0 )
|
||||
|
||||
T1_FIELD_NUM_TABLE( "XUID", xuid, 16, 0 )
|
||||
|
||||
T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset, 0 )
|
||||
T1_FIELD_NUM ( "FDBytes", fd_bytes, 0 )
|
||||
T1_FIELD_NUM ( "GDBytes", gd_bytes, 0 )
|
||||
T1_FIELD_NUM ( "CIDCount", cid_count, 0 )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PS_FontInfoRec
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_FONT_INFO
|
||||
|
||||
T1_FIELD_STRING( "version", version, 0 )
|
||||
T1_FIELD_STRING( "Notice", notice, 0 )
|
||||
T1_FIELD_STRING( "FullName", full_name, 0 )
|
||||
T1_FIELD_STRING( "FamilyName", family_name, 0 )
|
||||
T1_FIELD_STRING( "Weight", weight, 0 )
|
||||
T1_FIELD_NUM ( "ItalicAngle", italic_angle, 0 )
|
||||
T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, 0 )
|
||||
T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 )
|
||||
T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 )
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PS_FontExtraRec
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA
|
||||
|
||||
T1_FIELD_NUM ( "FSType", fs_type, 0 )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE CID_FaceDictRec
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_FONT_DICT
|
||||
|
||||
T1_FIELD_NUM ( "PaintType", paint_type, 0 )
|
||||
T1_FIELD_NUM ( "FontType", font_type, 0 )
|
||||
T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset, 0 )
|
||||
T1_FIELD_NUM ( "SDBytes", sd_bytes, 0 )
|
||||
T1_FIELD_NUM ( "SubrCount", num_subrs, 0 )
|
||||
T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar, 0 )
|
||||
T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold, 0 )
|
||||
T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PS_PrivateRec
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_PRIVATE
|
||||
|
||||
T1_FIELD_NUM ( "UniqueID", unique_id, 0 )
|
||||
T1_FIELD_NUM ( "lenIV", lenIV, 0 )
|
||||
T1_FIELD_NUM ( "LanguageGroup", language_group, 0 )
|
||||
T1_FIELD_NUM ( "password", password, 0 )
|
||||
|
||||
T1_FIELD_FIXED_1000( "BlueScale", blue_scale, 0 )
|
||||
T1_FIELD_NUM ( "BlueShift", blue_shift, 0 )
|
||||
T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, 0 )
|
||||
|
||||
T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, 0 )
|
||||
T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, 0 )
|
||||
T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, 0 )
|
||||
T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, 0 )
|
||||
|
||||
T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1, 0 )
|
||||
T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, 0 )
|
||||
T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, 0 )
|
||||
|
||||
T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, 0 )
|
||||
T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, 0 )
|
||||
|
||||
T1_FIELD_BOOL ( "ForceBold", force_bold, 0 )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE FT_BBox
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_BBOX
|
||||
|
||||
T1_FIELD_BBOX( "FontBBox", xMin, 0 )
|
||||
|
||||
|
||||
/* END */
|
1135
internal/c/parts/video/font/freetype/crc32.c
Normal file
1135
internal/c/parts/video/font/freetype/crc32.c
Normal file
File diff suppressed because it is too large
Load diff
9446
internal/c/parts/video/font/freetype/crc32.h
Normal file
9446
internal/c/parts/video/font/freetype/crc32.h
Normal file
File diff suppressed because it is too large
Load diff
803
internal/c/parts/video/font/freetype/dlg.c
Normal file
803
internal/c/parts/video/font/freetype/dlg.c
Normal file
|
@ -0,0 +1,803 @@
|
|||
// Copyright (c) 2019 nyorain
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#define _XOPEN_SOURCE 600
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#define _WIN32_WINNT 0x0600
|
||||
|
||||
// Needed on windows so that we can use sprintf without warning.
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <dlg/output.h>
|
||||
#include <dlg/dlg.h>
|
||||
#include <wchar.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
const char* const dlg_reset_sequence = "\033[0m";
|
||||
const struct dlg_style dlg_default_output_styles[] = {
|
||||
{dlg_text_style_italic, dlg_color_green, dlg_color_none},
|
||||
{dlg_text_style_dim, dlg_color_gray, dlg_color_none},
|
||||
{dlg_text_style_none, dlg_color_cyan, dlg_color_none},
|
||||
{dlg_text_style_none, dlg_color_yellow, dlg_color_none},
|
||||
{dlg_text_style_none, dlg_color_red, dlg_color_none},
|
||||
{dlg_text_style_bold, dlg_color_red, dlg_color_none}
|
||||
};
|
||||
|
||||
static void* xalloc(size_t size) {
|
||||
void* ret = calloc(size, 1);
|
||||
if(!ret) fprintf(stderr, "dlg: calloc returned NULL, probably crashing (size: %zu)\n", size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void* xrealloc(void* ptr, size_t size) {
|
||||
void* ret = realloc(ptr, size);
|
||||
if(!ret) fprintf(stderr, "dlg: realloc returned NULL, probably crashing (size: %zu)\n", size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct dlg_tag_func_pair {
|
||||
const char* tag;
|
||||
const char* func;
|
||||
};
|
||||
|
||||
struct dlg_data {
|
||||
const char** tags; // vec
|
||||
struct dlg_tag_func_pair* pairs; // vec
|
||||
char* buffer;
|
||||
size_t buffer_size;
|
||||
};
|
||||
|
||||
static dlg_handler g_handler = dlg_default_output;
|
||||
static void* g_data = NULL;
|
||||
|
||||
static void dlg_free_data(void* data);
|
||||
static struct dlg_data* dlg_create_data(void);
|
||||
|
||||
// platform-specific
|
||||
#if defined(__unix__) || defined(__unix) || defined(__linux__) || defined(__APPLE__) || defined(__MACH__)
|
||||
#define DLG_OS_UNIX
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static pthread_key_t dlg_data_key;
|
||||
|
||||
static void dlg_main_cleanup(void) {
|
||||
void* data = pthread_getspecific(dlg_data_key);
|
||||
if(data) {
|
||||
dlg_free_data(data);
|
||||
pthread_setspecific(dlg_data_key, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void init_data_key(void) {
|
||||
pthread_key_create(&dlg_data_key, dlg_free_data);
|
||||
atexit(dlg_main_cleanup);
|
||||
}
|
||||
|
||||
static struct dlg_data* dlg_data(void) {
|
||||
static pthread_once_t key_once = PTHREAD_ONCE_INIT;
|
||||
pthread_once(&key_once, init_data_key);
|
||||
|
||||
void* data = pthread_getspecific(dlg_data_key);
|
||||
if(!data) {
|
||||
data = dlg_create_data();
|
||||
pthread_setspecific(dlg_data_key, data);
|
||||
}
|
||||
|
||||
return (struct dlg_data*) data;
|
||||
}
|
||||
|
||||
static void lock_file(FILE* file) {
|
||||
flockfile(file);
|
||||
}
|
||||
|
||||
static void unlock_file(FILE* file) {
|
||||
funlockfile(file);
|
||||
}
|
||||
|
||||
bool dlg_is_tty(FILE* stream) {
|
||||
return isatty(fileno(stream));
|
||||
}
|
||||
|
||||
static unsigned get_msecs(void) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_usec;
|
||||
}
|
||||
|
||||
// platform switch -- end unix
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(_WIN64)
|
||||
#define DLG_OS_WIN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define DEFINE_CONSOLEV2_PROPERTIES
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
|
||||
// thanks for nothing, microsoft
|
||||
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
|
||||
#endif
|
||||
|
||||
// the max buffer size we will convert on the stack
|
||||
#define DLG_MAX_STACK_BUF_SIZE 1024
|
||||
|
||||
static void WINAPI dlg_fls_destructor(void* data) {
|
||||
dlg_free_data(data);
|
||||
}
|
||||
|
||||
// TODO: error handling
|
||||
static BOOL CALLBACK dlg_init_fls(PINIT_ONCE io, void* param, void** lpContext) {
|
||||
(void) io;
|
||||
(void) param;
|
||||
**((DWORD**) lpContext) = FlsAlloc(dlg_fls_destructor);
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct dlg_data* dlg_data(void) {
|
||||
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
|
||||
static DWORD fls = 0;
|
||||
void* flsp = (void*) &fls;
|
||||
InitOnceExecuteOnce(&init_once, dlg_init_fls, NULL, &flsp);
|
||||
void* data = FlsGetValue(fls);
|
||||
if(!data) {
|
||||
data = dlg_create_data();
|
||||
FlsSetValue(fls, data);
|
||||
}
|
||||
|
||||
return (struct dlg_data*) data;
|
||||
}
|
||||
|
||||
static void lock_file(FILE* file) {
|
||||
_lock_file(file);
|
||||
}
|
||||
|
||||
static void unlock_file(FILE* file) {
|
||||
_unlock_file(file);
|
||||
}
|
||||
|
||||
bool dlg_is_tty(FILE* stream) {
|
||||
return _isatty(_fileno(stream));
|
||||
}
|
||||
|
||||
#ifdef DLG_WIN_CONSOLE
|
||||
static bool init_ansi_console(void) {
|
||||
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
HANDLE err = GetStdHandle(STD_ERROR_HANDLE);
|
||||
if(out == INVALID_HANDLE_VALUE || err == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
DWORD outMode, errMode;
|
||||
if(!GetConsoleMode(out, &outMode) || !GetConsoleMode(err, &errMode))
|
||||
return false;
|
||||
|
||||
outMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
errMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
if(!SetConsoleMode(out, outMode) || !SetConsoleMode(out, errMode))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool win_write_heap(void* handle, int needed, const char* format, va_list args) {
|
||||
char* buf1 = xalloc(3 * needed + 3 + (needed % 2));
|
||||
wchar_t* buf2 = (wchar_t*) (buf1 + needed + 1 + (needed % 2));
|
||||
vsnprintf(buf1, needed + 1, format, args);
|
||||
needed = MultiByteToWideChar(CP_UTF8, 0, buf1, needed, buf2, needed + 1);
|
||||
bool ret = (needed != 0 && WriteConsoleW(handle, buf2, needed, NULL, NULL) != 0);
|
||||
free(buf1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool win_write_stack(void* handle, int needed, const char* format, va_list args) {
|
||||
char buf1[DLG_MAX_STACK_BUF_SIZE];
|
||||
wchar_t buf2[DLG_MAX_STACK_BUF_SIZE];
|
||||
vsnprintf(buf1, needed + 1, format, args);
|
||||
needed = MultiByteToWideChar(CP_UTF8, 0, buf1, needed, buf2, needed + 1);
|
||||
return (needed != 0 && WriteConsoleW(handle, buf2, needed, NULL, NULL) != 0);
|
||||
}
|
||||
#endif // DLG_WIN_CONSOLE
|
||||
|
||||
static unsigned get_msecs() {
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
return st.wMilliseconds;
|
||||
}
|
||||
|
||||
#else // platform switch -- end windows
|
||||
#error Cannot determine platform (needed for color and utf-8 and stuff)
|
||||
#endif
|
||||
|
||||
// general
|
||||
void dlg_escape_sequence(struct dlg_style style, char buf[12]) {
|
||||
int nums[3];
|
||||
unsigned int count = 0;
|
||||
|
||||
if(style.fg != dlg_color_none) {
|
||||
nums[count++] = style.fg + 30;
|
||||
}
|
||||
|
||||
if(style.bg != dlg_color_none) {
|
||||
nums[count++] = style.fg + 40;
|
||||
}
|
||||
|
||||
if(style.style != dlg_text_style_none) {
|
||||
nums[count++] = style.style;
|
||||
}
|
||||
|
||||
switch(count) {
|
||||
case 1: snprintf(buf, 12, "\033[%dm", nums[0]); break;
|
||||
case 2: snprintf(buf, 12, "\033[%d;%dm", nums[0], nums[1]); break;
|
||||
case 3: snprintf(buf, 12, "\033[%d;%d;%dm", nums[0], nums[1], nums[2]); break;
|
||||
default: buf[0] = '\0'; break;
|
||||
}
|
||||
}
|
||||
|
||||
int dlg_vfprintf(FILE* stream, const char* format, va_list args) {
|
||||
#if defined(DLG_OS_WIN) && defined(DLG_WIN_CONSOLE)
|
||||
void* handle = NULL;
|
||||
if(stream == stdout) {
|
||||
handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
} else if(stream == stderr) {
|
||||
handle = GetStdHandle(STD_ERROR_HANDLE);
|
||||
}
|
||||
|
||||
if(handle) {
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
int needed = vsnprintf(NULL, 0, format, args_copy);
|
||||
va_end(args_copy);
|
||||
|
||||
if(needed < 0) {
|
||||
return needed;
|
||||
}
|
||||
|
||||
// We don't allocate too much on the stack
|
||||
// but we also don't want to call alloc every logging call
|
||||
// or use another cached buffer
|
||||
if(needed >= DLG_MAX_STACK_BUF_SIZE) {
|
||||
if(win_write_heap(handle, needed, format, args)) {
|
||||
return needed;
|
||||
}
|
||||
} else {
|
||||
if(win_write_stack(handle, needed, format, args)) {
|
||||
return needed;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return vfprintf(stream, format, args);
|
||||
}
|
||||
|
||||
int dlg_fprintf(FILE* stream, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = dlg_vfprintf(stream, format, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dlg_styled_fprintf(FILE* stream, struct dlg_style style, const char* format, ...) {
|
||||
char buf[12];
|
||||
dlg_escape_sequence(style, buf);
|
||||
|
||||
fprintf(stream, "%s", buf);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = dlg_vfprintf(stream, format, args);
|
||||
va_end(args);
|
||||
fprintf(stream, "%s", dlg_reset_sequence);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dlg_generic_output(dlg_generic_output_handler output, void* data,
|
||||
unsigned int features, const struct dlg_origin* origin, const char* string,
|
||||
const struct dlg_style styles[6]) {
|
||||
// We never print any dynamic content below so we can be sure at compile
|
||||
// time that a buffer of size 64 is large enough.
|
||||
char format_buf[64];
|
||||
char* format = format_buf;
|
||||
|
||||
if(features & dlg_output_style) {
|
||||
format += sprintf(format, "%%s");
|
||||
}
|
||||
|
||||
if(features & (dlg_output_time | dlg_output_file_line | dlg_output_tags | dlg_output_func)) {
|
||||
format += sprintf(format, "[");
|
||||
}
|
||||
|
||||
bool first_meta = true;
|
||||
if(features & dlg_output_time) {
|
||||
format += sprintf(format, "%%h");
|
||||
first_meta = false;
|
||||
}
|
||||
|
||||
if(features & dlg_output_time_msecs) {
|
||||
if(!first_meta) {
|
||||
format += sprintf(format, ":");
|
||||
}
|
||||
|
||||
format += sprintf(format, "%%m");
|
||||
first_meta = false;
|
||||
}
|
||||
|
||||
if(features & dlg_output_file_line) {
|
||||
if(!first_meta) {
|
||||
format += sprintf(format, " ");
|
||||
}
|
||||
|
||||
format += sprintf(format, "%%o");
|
||||
first_meta = false;
|
||||
}
|
||||
|
||||
if(features & dlg_output_func) {
|
||||
if(!first_meta) {
|
||||
format += sprintf(format, " ");
|
||||
}
|
||||
|
||||
format += sprintf(format, "%%f");
|
||||
first_meta = false;
|
||||
}
|
||||
|
||||
if(features & dlg_output_tags) {
|
||||
if(!first_meta) {
|
||||
format += sprintf(format, " ");
|
||||
}
|
||||
|
||||
format += sprintf(format, "{%%t}");
|
||||
first_meta = false;
|
||||
}
|
||||
|
||||
if(features & (dlg_output_time | dlg_output_file_line | dlg_output_tags | dlg_output_func)) {
|
||||
format += sprintf(format, "] ");
|
||||
}
|
||||
|
||||
format += sprintf(format, "%%c");
|
||||
|
||||
if(features & dlg_output_newline) {
|
||||
format += sprintf(format, "\n");
|
||||
}
|
||||
|
||||
*format = '\0';
|
||||
dlg_generic_outputf(output, data, format_buf, origin, string, styles);
|
||||
}
|
||||
|
||||
void dlg_generic_outputf(dlg_generic_output_handler output, void* data,
|
||||
const char* format_string, const struct dlg_origin* origin, const char* string,
|
||||
const struct dlg_style styles[6]) {
|
||||
bool reset_style = false;
|
||||
for(const char* it = format_string; *it; it++) {
|
||||
if(*it != '%') {
|
||||
output(data, "%c", *it);
|
||||
continue;
|
||||
}
|
||||
|
||||
char next = *(it + 1); // must be valid since *it is not '\0'
|
||||
if(next == 'h') {
|
||||
time_t t = time(NULL);
|
||||
struct tm tm_info;
|
||||
|
||||
#ifdef DLG_OS_WIN
|
||||
if(localtime_s(&tm_info, &t)) {
|
||||
#else
|
||||
if(!localtime_r(&t, &tm_info)) {
|
||||
#endif
|
||||
output(data, "<DATE ERROR>");
|
||||
} else {
|
||||
char timebuf[32];
|
||||
strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm_info);
|
||||
output(data, "%s", timebuf);
|
||||
}
|
||||
it++;
|
||||
} else if(next == 'm') {
|
||||
output(data, "%06d", get_msecs());
|
||||
it++;
|
||||
} else if(next == 't') {
|
||||
bool first_tag = true;
|
||||
for(const char** tags = origin->tags; *tags; ++tags) {
|
||||
if(!first_tag) {
|
||||
output(data, ", ");
|
||||
}
|
||||
|
||||
output(data, "%s", *tags);
|
||||
first_tag = false;
|
||||
}
|
||||
++it;
|
||||
} else if(next == 'f') {
|
||||
output(data, "%s", origin->func);
|
||||
++it;
|
||||
} else if(next == 'o') {
|
||||
output(data, "%s:%u", origin->file, origin->line);
|
||||
++it;
|
||||
} else if(next == 's') {
|
||||
char buf[12];
|
||||
dlg_escape_sequence(styles[origin->level], buf);
|
||||
output(data, "%s", buf);
|
||||
reset_style = true;
|
||||
++it;
|
||||
} else if(next == 'r') {
|
||||
output(data, "%s", dlg_reset_sequence);
|
||||
reset_style = false;
|
||||
++it;
|
||||
} else if(next == 'c') {
|
||||
if(origin->expr && string) {
|
||||
output(data, "assertion '%s' failed: '%s'", origin->expr, string);
|
||||
} else if(origin->expr) {
|
||||
output(data, "assertion '%s' failed", origin->expr);
|
||||
} else if(string) {
|
||||
output(data, "%s", string);
|
||||
}
|
||||
++it;
|
||||
} else if(next == '%') {
|
||||
output(data, "%s", "%");
|
||||
++it;
|
||||
} else {
|
||||
// in this case it's a '%' without known format specifier following
|
||||
output(data, "%s", "%");
|
||||
}
|
||||
}
|
||||
|
||||
if(reset_style) {
|
||||
output(data, "%s", dlg_reset_sequence);
|
||||
}
|
||||
}
|
||||
|
||||
struct buf {
|
||||
char* buf;
|
||||
size_t* size;
|
||||
};
|
||||
|
||||
static void print_size(void* size, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
int ret = vsnprintf(NULL, 0, format, args);
|
||||
va_end(args);
|
||||
|
||||
if(ret > 0) {
|
||||
*((size_t*) size) += ret;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_buf(void* dbuf, const char* format, ...) {
|
||||
struct buf* buf = (struct buf*) dbuf;
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
int printed = vsnprintf(buf->buf, *buf->size, format, args);
|
||||
va_end(args);
|
||||
|
||||
if(printed > 0) {
|
||||
*buf->size -= printed;
|
||||
buf->buf += printed;
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_generic_output_buf(char* buf, size_t* size, unsigned int features,
|
||||
const struct dlg_origin* origin, const char* string,
|
||||
const struct dlg_style styles[6]) {
|
||||
if(buf) {
|
||||
struct buf mbuf;
|
||||
mbuf.buf = buf;
|
||||
mbuf.size = size;
|
||||
dlg_generic_output(print_buf, &mbuf, features, origin, string, styles);
|
||||
} else {
|
||||
*size = 0;
|
||||
dlg_generic_output(print_size, size, features, origin, string, styles);
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_generic_outputf_buf(char* buf, size_t* size, const char* format_string,
|
||||
const struct dlg_origin* origin, const char* string,
|
||||
const struct dlg_style styles[6]) {
|
||||
if(buf) {
|
||||
struct buf mbuf;
|
||||
mbuf.buf = buf;
|
||||
mbuf.size = size;
|
||||
dlg_generic_outputf(print_buf, &mbuf, format_string, origin, string, styles);
|
||||
} else {
|
||||
*size = 0;
|
||||
dlg_generic_outputf(print_size, size, format_string, origin, string, styles);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_stream(void* stream, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
dlg_vfprintf((FILE*) stream, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void dlg_generic_output_stream(FILE* stream, unsigned int features,
|
||||
const struct dlg_origin* origin, const char* string,
|
||||
const struct dlg_style styles[6]) {
|
||||
stream = stream ? stream : stdout;
|
||||
if(features & dlg_output_threadsafe) {
|
||||
lock_file(stream);
|
||||
}
|
||||
|
||||
dlg_generic_output(print_stream, stream, features, origin, string, styles);
|
||||
if(features & dlg_output_threadsafe) {
|
||||
unlock_file(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_generic_outputf_stream(FILE* stream, const char* format_string,
|
||||
const struct dlg_origin* origin, const char* string,
|
||||
const struct dlg_style styles[6], bool lock_stream) {
|
||||
stream = stream ? stream : stdout;
|
||||
if(lock_stream) {
|
||||
lock_file(stream);
|
||||
}
|
||||
|
||||
dlg_generic_outputf(print_stream, stream, format_string, origin, string, styles);
|
||||
if(lock_stream) {
|
||||
unlock_file(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_default_output(const struct dlg_origin* origin, const char* string, void* data) {
|
||||
FILE* stream = data ? (FILE*) data : stdout;
|
||||
unsigned int features = dlg_output_file_line |
|
||||
dlg_output_newline |
|
||||
dlg_output_threadsafe;
|
||||
|
||||
#ifdef DLG_DEFAULT_OUTPUT_ALWAYS_COLOR
|
||||
dlg_win_init_ansi();
|
||||
features |= dlg_output_style;
|
||||
#else
|
||||
if(dlg_is_tty(stream) && dlg_win_init_ansi()) {
|
||||
features |= dlg_output_style;
|
||||
}
|
||||
#endif
|
||||
|
||||
dlg_generic_output_stream(stream, features, origin, string, dlg_default_output_styles);
|
||||
fflush(stream);
|
||||
}
|
||||
|
||||
bool dlg_win_init_ansi(void) {
|
||||
#if defined(DLG_OS_WIN) && defined(DLG_WIN_CONSOLE)
|
||||
// TODO: use init once
|
||||
static volatile LONG status = 0;
|
||||
LONG res = InterlockedCompareExchange(&status, 1, 0);
|
||||
if(res == 0) { // not initialized
|
||||
InterlockedExchange(&status, 3 + init_ansi_console());
|
||||
}
|
||||
|
||||
while(status == 1); // currently initialized in another thread, spinlock
|
||||
return (status == 4);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// small dynamic vec/array implementation
|
||||
// Since the macros vec_init and vec_add[c]/vec_push might
|
||||
// change the pointers value it must not be referenced somewhere else.
|
||||
#define vec__raw(vec) (((unsigned int*) vec) - 2)
|
||||
|
||||
static void* vec_do_create(unsigned int typesize, unsigned int cap, unsigned int size) {
|
||||
unsigned long a = (size > cap) ? size : cap;
|
||||
void* ptr = xalloc(2 * sizeof(unsigned int) + a * typesize);
|
||||
unsigned int* begin = (unsigned int*) ptr;
|
||||
begin[0] = size * typesize;
|
||||
begin[1] = a * typesize;
|
||||
return begin + 2;
|
||||
}
|
||||
|
||||
// NOTE: can be more efficient if we are allowed to reorder vector
|
||||
static void vec_do_erase(void* vec, unsigned int pos, unsigned int size) {
|
||||
unsigned int* begin = vec__raw(vec);
|
||||
begin[0] -= size;
|
||||
char* buf = (char*) vec;
|
||||
memcpy(buf + pos, buf + pos + size, size);
|
||||
}
|
||||
|
||||
static void* vec_do_add(void** vec, unsigned int size) {
|
||||
unsigned int* begin = vec__raw(*vec);
|
||||
unsigned int needed = begin[0] + size;
|
||||
if(needed >= begin[1]) {
|
||||
void* ptr = xrealloc(begin, sizeof(unsigned int) * 2 + needed * 2);
|
||||
begin = (unsigned int*) ptr;
|
||||
begin[1] = needed * 2;
|
||||
(*vec) = begin + 2;
|
||||
}
|
||||
|
||||
void* ptr = ((char*) (*vec)) + begin[0];
|
||||
begin[0] += size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#define vec_create(type, size) (type*) vec_do_create(sizeof(type), size * 2, size)
|
||||
#define vec_create_reserve(type, size, capacity) (type*) vec_do_create(sizeof(type), capcity, size)
|
||||
#define vec_init(array, size) array = vec_do_create(sizeof(*array), size * 2, size)
|
||||
#define vec_init_reserve(array, size, capacity) *((void**) &array) = vec_do_create(sizeof(*array), capacity, size)
|
||||
#define vec_free(vec) (free((vec) ? vec__raw(vec) : NULL), vec = NULL)
|
||||
#define vec_erase_range(vec, pos, count) vec_do_erase(vec, pos * sizeof(*vec), count * sizeof(*vec))
|
||||
#define vec_erase(vec, pos) vec_do_erase(vec, pos * sizeof(*vec), sizeof(*vec))
|
||||
#define vec_size(vec) (vec__raw(vec)[0] / sizeof(*vec))
|
||||
#define vec_capacity(vec) (vec_raw(vec)[1] / sizeof(*vec))
|
||||
#define vec_add(vec) vec_do_add((void**) &vec, sizeof(*vec))
|
||||
#define vec_addc(vec, count) (vec_do_add((void**) &vec, sizeof(*vec) * count))
|
||||
#define vec_push(vec, value) (vec_do_add((void**) &vec, sizeof(*vec)), vec_last(vec) = (value))
|
||||
#define vec_pop(vec) (vec__raw(vec)[0] -= sizeof(*vec))
|
||||
#define vec_popc(vec, count) (vec__raw(vec)[0] -= sizeof(*vec) * count)
|
||||
#define vec_clear(vec) (vec__raw(vec)[0] = 0)
|
||||
#define vec_last(vec) (vec[vec_size(vec) - 1])
|
||||
|
||||
static struct dlg_data* dlg_create_data(void) {
|
||||
struct dlg_data* data = (struct dlg_data*) xalloc(sizeof(struct dlg_data));
|
||||
vec_init_reserve(data->tags, 0, 20);
|
||||
vec_init_reserve(data->pairs, 0, 20);
|
||||
data->buffer_size = 100;
|
||||
data->buffer = (char*) xalloc(data->buffer_size);
|
||||
return data;
|
||||
}
|
||||
|
||||
static void dlg_free_data(void* ddata) {
|
||||
struct dlg_data* data = (struct dlg_data*) ddata;
|
||||
if(data) {
|
||||
vec_free(data->pairs);
|
||||
vec_free(data->tags);
|
||||
free(data->buffer);
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_add_tag(const char* tag, const char* func) {
|
||||
struct dlg_data* data = dlg_data();
|
||||
struct dlg_tag_func_pair* pair =
|
||||
(struct dlg_tag_func_pair*) vec_add(data->pairs);
|
||||
pair->tag = tag;
|
||||
pair->func = func;
|
||||
}
|
||||
|
||||
bool dlg_remove_tag(const char* tag, const char* func) {
|
||||
struct dlg_data* data = dlg_data();
|
||||
for(unsigned int i = 0; i < vec_size(data->pairs); ++i) {
|
||||
if(data->pairs[i].func == func && data->pairs[i].tag == tag) {
|
||||
vec_erase(data->pairs, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char** dlg_thread_buffer(size_t** size) {
|
||||
struct dlg_data* data = dlg_data();
|
||||
if(size) {
|
||||
*size = &data->buffer_size;
|
||||
}
|
||||
return &data->buffer;
|
||||
}
|
||||
|
||||
void dlg_set_handler(dlg_handler handler, void* data) {
|
||||
g_handler = handler;
|
||||
g_data = data;
|
||||
}
|
||||
|
||||
dlg_handler dlg_get_handler(void** data) {
|
||||
*data = g_data;
|
||||
return g_handler;
|
||||
}
|
||||
|
||||
const char* dlg__printf_format(const char* str, ...) {
|
||||
va_list vlist;
|
||||
va_start(vlist, str);
|
||||
|
||||
va_list vlistcopy;
|
||||
va_copy(vlistcopy, vlist);
|
||||
int needed = vsnprintf(NULL, 0, str, vlist);
|
||||
if(needed < 0) {
|
||||
printf("dlg__printf_format: invalid format given\n");
|
||||
va_end(vlist);
|
||||
va_end(vlistcopy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
va_end(vlist);
|
||||
|
||||
size_t* buf_size;
|
||||
char** buf = dlg_thread_buffer(&buf_size);
|
||||
if(*buf_size <= (unsigned int) needed) {
|
||||
*buf_size = (needed + 1) * 2;
|
||||
*buf = (char*) xrealloc(*buf, *buf_size);
|
||||
}
|
||||
|
||||
vsnprintf(*buf, *buf_size, str, vlistcopy);
|
||||
va_end(vlistcopy);
|
||||
|
||||
return *buf;
|
||||
}
|
||||
|
||||
void dlg__do_log(enum dlg_level lvl, const char* const* tags, const char* file, int line,
|
||||
const char* func, const char* string, const char* expr) {
|
||||
struct dlg_data* data = dlg_data();
|
||||
unsigned int tag_count = 0;
|
||||
|
||||
// push default tags
|
||||
while(tags[tag_count]) {
|
||||
vec_push(data->tags, tags[tag_count++]);
|
||||
}
|
||||
|
||||
// push current global tags
|
||||
for(size_t i = 0; i < vec_size(data->pairs); ++i) {
|
||||
const struct dlg_tag_func_pair pair = data->pairs[i];
|
||||
if(pair.func == NULL || !strcmp(pair.func, func)) {
|
||||
vec_push(data->tags, pair.tag);
|
||||
}
|
||||
}
|
||||
|
||||
// push call-specific tags, skip first terminating NULL
|
||||
++tag_count;
|
||||
while(tags[tag_count]) {
|
||||
vec_push(data->tags, tags[tag_count++]);
|
||||
}
|
||||
|
||||
vec_push(data->tags, NULL); // terminating NULL
|
||||
struct dlg_origin origin;
|
||||
origin.level = lvl;
|
||||
origin.file = file;
|
||||
origin.line = line;
|
||||
origin.func = func;
|
||||
origin.expr = expr;
|
||||
origin.tags = data->tags;
|
||||
|
||||
g_handler(&origin, string, g_data);
|
||||
vec_clear(data->tags);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// shitty msvc compatbility
|
||||
// meson gives us sane paths (separated by '/') while on MSVC,
|
||||
// __FILE__ contains a '\\' separator.
|
||||
static bool path_same(char a, char b) {
|
||||
return (a == b) ||
|
||||
(a == '/' && b == '\\') ||
|
||||
(a == '\\' && b == '/');
|
||||
}
|
||||
#else
|
||||
|
||||
static inline bool path_same(char a, char b) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const char* dlg__strip_root_path(const char* file, const char* base) {
|
||||
if(!file) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* saved = file;
|
||||
if(*file == '.') { // relative path detected
|
||||
while(*(++file) == '.' || *file == '/' || *file == '\\');
|
||||
if(*file == '\0') { // weird case: purely relative path without file
|
||||
return saved;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
// strip base from file if it is given
|
||||
if(base) {
|
||||
char fn = *file;
|
||||
char bn = *base;
|
||||
while(bn != '\0' && path_same(fn, bn)) {
|
||||
fn = *(++file);
|
||||
bn = *(++base);
|
||||
}
|
||||
|
||||
if(fn == '\0' || bn != '\0') { // weird case: base isn't prefix of file
|
||||
return saved;
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
32
internal/c/parts/video/font/freetype/dlgwrap.c
Normal file
32
internal/c/parts/video/font/freetype/dlgwrap.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* dlgwrap.c
|
||||
*
|
||||
* Wrapper file for the 'dlg' library (body only)
|
||||
*
|
||||
* Copyright (C) 2020-2023 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_OPTIONS_H
|
||||
|
||||
|
||||
#ifdef FT_DEBUG_LOGGING
|
||||
#define DLG_STATIC
|
||||
#include "dlg.c"
|
||||
#else
|
||||
/* ANSI C doesn't like empty source files */
|
||||
typedef int dlg_dummy_;
|
||||
#endif
|
||||
|
||||
|
||||
/* END */
|
42
internal/c/parts/video/font/freetype/fnterrs.h
Normal file
42
internal/c/parts/video/font/freetype/fnterrs.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* fnterrs.h
|
||||
*
|
||||
* Win FNT/FON error codes (specification only).
|
||||
*
|
||||
* Copyright (C) 2001-2023 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 Windows FNT/FON error enumeration
|
||||
* constants.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FNTERRS_H_
|
||||
#define FNTERRS_H_
|
||||
|
||||
#include <freetype/ftmoderr.h>
|
||||
|
||||
#undef FTERRORS_H_
|
||||
|
||||
#undef FT_ERR_PREFIX
|
||||
#define FT_ERR_PREFIX FNT_Err_
|
||||
#define FT_ERR_BASE FT_Mod_Err_Winfonts
|
||||
|
||||
#include <freetype/fterrors.h>
|
||||
|
||||
#endif /* FNTERRS_H_ */
|
||||
|
||||
|
||||
/* END */
|
115
internal/c/parts/video/font/freetype/ft-hb.c
Normal file
115
internal/c/parts/video/font/freetype/ft-hb.c
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
internal/c/parts/video/font/freetype/ft-hb.h
Normal file
48
internal/c/parts/video/font/freetype/ft-hb.h
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
internal/c/parts/video/font/freetype/ftadvanc.c
Normal file
174
internal/c/parts/video/font/freetype/ftadvanc.c
Normal file
|
@ -0,0 +1,174 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftadvanc.c
|
||||
*
|
||||
* Quick computation of advance widths (body).
|
||||
*
|
||||
* Copyright (C) 2008-2023 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 */
|
82
internal/c/parts/video/font/freetype/ftbase.h
Normal file
82
internal/c/parts/video/font/freetype/ftbase.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftbase.h
|
||||
*
|
||||
* Private functions used in the `base' module (specification).
|
||||
*
|
||||
* Copyright (C) 2008-2023 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
internal/c/parts/video/font/freetype/ftbbox.c
Normal file
542
internal/c/parts/video/font/freetype/ftbbox.c
Normal file
|
@ -0,0 +1,542 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftbbox.c
|
||||
*
|
||||
* FreeType bbox computation (body).
|
||||
*
|
||||
* Copyright (C) 1996-2023 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
internal/c/parts/video/font/freetype/ftbdf.c
Normal file
90
internal/c/parts/video/font/freetype/ftbdf.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftbdf.c
|
||||
*
|
||||
* FreeType API for accessing BDF-specific strings (body).
|
||||
*
|
||||
* Copyright (C) 2002-2023 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
internal/c/parts/video/font/freetype/ftbitmap.c
Normal file
1144
internal/c/parts/video/font/freetype/ftbitmap.c
Normal file
File diff suppressed because it is too large
Load diff
1350
internal/c/parts/video/font/freetype/ftbsdf.c
Normal file
1350
internal/c/parts/video/font/freetype/ftbsdf.c
Normal file
File diff suppressed because it is too large
Load diff
535
internal/c/parts/video/font/freetype/ftbzip2.c
Normal file
535
internal/c/parts/video/font/freetype/ftbzip2.c
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-2023 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 */
|
1127
internal/c/parts/video/font/freetype/ftcalc.c
Normal file
1127
internal/c/parts/video/font/freetype/ftcalc.c
Normal file
File diff suppressed because it is too large
Load diff
638
internal/c/parts/video/font/freetype/ftcbasic.c
Normal file
638
internal/c/parts/video/font/freetype/ftcbasic.c
Normal file
|
@ -0,0 +1,638 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcbasic.c
|
||||
*
|
||||
* The FreeType basic cache interface (body).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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_UInt 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 ) + 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,
|
||||
(FT_Int)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,
|
||||
(FT_Int)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_ResetFunc node_reset */
|
||||
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 )
|
||||
{
|
||||
FTC_BasicQueryRec query;
|
||||
FTC_Node node = 0; /* make compiler happy */
|
||||
FT_Error error;
|
||||
FT_Offset hash;
|
||||
|
||||
|
||||
/* some argument checks are delayed to `FTC_Cache_Lookup' */
|
||||
if ( !aglyph )
|
||||
{
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*aglyph = NULL;
|
||||
if ( anode )
|
||||
*anode = NULL;
|
||||
|
||||
/*
|
||||
* Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
|
||||
* but public `FT_ImageType->flags' is of type `FT_Int32'.
|
||||
*
|
||||
* On 16bit systems, higher bits of type->flags cannot be handled.
|
||||
*/
|
||||
#if 0xFFFFFFFFUL > FT_UINT_MAX
|
||||
if ( (type->flags & (FT_ULong)FT_UINT_MAX) )
|
||||
FT_TRACE1(( "FTC_ImageCache_Lookup:"
|
||||
" higher bits in load_flags 0x%lx are dropped\n",
|
||||
(FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
|
||||
#endif
|
||||
|
||||
query.attrs.scaler.face_id = type->face_id;
|
||||
query.attrs.scaler.width = type->width;
|
||||
query.attrs.scaler.height = type->height;
|
||||
query.attrs.load_flags = (FT_UInt)type->flags;
|
||||
|
||||
query.attrs.scaler.pixel = 1;
|
||||
query.attrs.scaler.x_res = 0; /* make compilers happy */
|
||||
query.attrs.scaler.y_res = 0;
|
||||
|
||||
hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;
|
||||
|
||||
#if 1 /* 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++;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
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 )
|
||||
{
|
||||
FTC_BasicQueryRec query;
|
||||
FTC_Node node = 0; /* make compiler happy */
|
||||
FT_Error error;
|
||||
FT_Offset hash;
|
||||
|
||||
|
||||
/* some argument checks are delayed to `FTC_Cache_Lookup' */
|
||||
if ( !aglyph || !scaler )
|
||||
{
|
||||
error = FT_THROW( Invalid_Argument );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*aglyph = NULL;
|
||||
if ( anode )
|
||||
*anode = NULL;
|
||||
|
||||
/*
|
||||
* Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
|
||||
* 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 > FT_UINT_MAX
|
||||
if ( load_flags > FT_UINT_MAX )
|
||||
FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
|
||||
" higher bits in load_flags 0x%lx are dropped\n",
|
||||
load_flags & ~((FT_ULong)FT_UINT_MAX) ));
|
||||
#endif
|
||||
|
||||
query.attrs.scaler = scaler[0];
|
||||
query.attrs.load_flags = (FT_UInt)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++;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
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_ResetFunc node_reset */
|
||||
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 = 0; /* make compiler happy */
|
||||
FT_Offset hash;
|
||||
|
||||
|
||||
if ( anode )
|
||||
*anode = NULL;
|
||||
|
||||
/* other argument checks delayed to `FTC_Cache_Lookup' */
|
||||
if ( !ansbit )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
*ansbit = NULL;
|
||||
|
||||
/*
|
||||
* Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
|
||||
* but public `FT_ImageType->flags' is of type `FT_Int32'.
|
||||
*
|
||||
* On 16bit systems, higher bits of type->flags cannot be handled.
|
||||
*/
|
||||
#if 0xFFFFFFFFUL > FT_UINT_MAX
|
||||
if ( (type->flags & (FT_ULong)FT_UINT_MAX) )
|
||||
FT_TRACE1(( "FTC_ImageCache_Lookup:"
|
||||
" higher bits in load_flags 0x%lx are dropped\n",
|
||||
(FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
|
||||
#endif
|
||||
|
||||
query.attrs.scaler.face_id = type->face_id;
|
||||
query.attrs.scaler.width = type->width;
|
||||
query.attrs.scaler.height = type->height;
|
||||
query.attrs.load_flags = (FT_UInt)type->flags;
|
||||
|
||||
query.attrs.scaler.pixel = 1;
|
||||
query.attrs.scaler.x_res = 0; /* make compilers happy */
|
||||
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;
|
||||
|
||||
#if 1 /* 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 = 0; /* make compiler happy */
|
||||
FT_Offset hash;
|
||||
|
||||
|
||||
if ( anode )
|
||||
*anode = NULL;
|
||||
|
||||
/* other argument checks delayed to `FTC_Cache_Lookup' */
|
||||
if ( !ansbit || !scaler )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
*ansbit = NULL;
|
||||
|
||||
/*
|
||||
* Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt',
|
||||
* 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 > FT_UINT_MAX
|
||||
if ( load_flags > FT_UINT_MAX )
|
||||
FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
|
||||
" higher bits in load_flags 0x%lx are dropped\n",
|
||||
load_flags & ~((FT_ULong)FT_UINT_MAX) ));
|
||||
#endif
|
||||
|
||||
query.attrs.scaler = scaler[0];
|
||||
query.attrs.load_flags = (FT_UInt)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 */
|
599
internal/c/parts/video/font/freetype/ftccache.c
Normal file
599
internal/c/parts/video/font/freetype/ftccache.c
Normal file
|
@ -0,0 +1,599 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftccache.c
|
||||
*
|
||||
* The FreeType internal cache interface (body).
|
||||
*
|
||||
* Copyright (C) 2000-2023 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;
|
||||
FTC_Node frees = NULL;
|
||||
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;
|
||||
FT_Bool list_changed = FALSE;
|
||||
|
||||
|
||||
if ( !node )
|
||||
break;
|
||||
|
||||
if ( cache->clazz.node_remove_faceid( node, face_id,
|
||||
cache, &list_changed ) )
|
||||
{
|
||||
*pnode = node->link;
|
||||
node->link = frees;
|
||||
frees = node;
|
||||
}
|
||||
else
|
||||
pnode = &node->link;
|
||||
}
|
||||
}
|
||||
|
||||
/* remove all nodes in the free list */
|
||||
while ( frees )
|
||||
{
|
||||
FTC_Node node;
|
||||
|
||||
|
||||
node = frees;
|
||||
frees = 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++;
|
||||
}
|
||||
|
||||
ftc_cache_resize( cache );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
355
internal/c/parts/video/font/freetype/ftccache.h
Normal file
355
internal/c/parts/video/font/freetype/ftccache.h
Normal file
|
@ -0,0 +1,355 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftccache.h
|
||||
*
|
||||
* FreeType internal cache interface (specification).
|
||||
*
|
||||
* Copyright (C) 2000-2023 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
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** 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 */
|
93
internal/c/parts/video/font/freetype/ftccback.h
Normal file
93
internal/c/parts/video/font/freetype/ftccback.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftccback.h
|
||||
*
|
||||
* Callback functions of the caching sub-system (specification only).
|
||||
*
|
||||
* Copyright (C) 2004-2023 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 "ftcmru.h"
|
||||
#include "ftcimage.h"
|
||||
#include "ftcmanag.h"
|
||||
#include "ftcglyph.h"
|
||||
#include "ftcsbits.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_LOCAL( void )
|
||||
ftc_node_destroy( FTC_Node node,
|
||||
FTC_Manager manager );
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* FTCCBACK_H_ */
|
||||
|
||||
|
||||
/* END */
|
323
internal/c/parts/video/font/freetype/ftccmap.c
Normal file
323
internal/c/parts/video/font/freetype/ftccmap.c
Normal file
|
@ -0,0 +1,323 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftccmap.c
|
||||
*
|
||||
* FreeType CharMap cache (body)
|
||||
*
|
||||
* Copyright (C) 2000-2023 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 );
|
||||
|
||||
#if 1
|
||||
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
internal/c/parts/video/font/freetype/ftcerror.h
Normal file
42
internal/c/parts/video/font/freetype/ftcerror.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcerror.h
|
||||
*
|
||||
* Caching sub-system error codes (specification only).
|
||||
*
|
||||
* Copyright (C) 2001-2023 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
internal/c/parts/video/font/freetype/ftcglyph.c
Normal file
204
internal/c/parts/video/font/freetype/ftcglyph.c
Normal file
|
@ -0,0 +1,204 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcglyph.c
|
||||
*
|
||||
* FreeType Glyph Image (FT_Glyph) cache (body).
|
||||
*
|
||||
* Copyright (C) 2000-2023 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( &cache->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, cache );
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif /* !FTC_INLINE */
|
||||
|
||||
|
||||
/* END */
|
315
internal/c/parts/video/font/freetype/ftcglyph.h
Normal file
315
internal/c/parts/video/font/freetype/ftcglyph.h
Normal file
|
@ -0,0 +1,315 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcglyph.h
|
||||
*
|
||||
* FreeType abstract glyph cache (specification).
|
||||
*
|
||||
* Copyright (C) 2000-2023 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_reset (optional)
|
||||
* 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 */
|
117
internal/c/parts/video/font/freetype/ftcid.c
Normal file
117
internal/c/parts/video/font/freetype/ftcid.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcid.c
|
||||
*
|
||||
* FreeType API for accessing CID font information.
|
||||
*
|
||||
* Copyright (C) 2007-2023 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 */
|
164
internal/c/parts/video/font/freetype/ftcimage.c
Normal file
164
internal/c/parts/video/font/freetype/ftcimage.c
Normal file
|
@ -0,0 +1,164 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcimage.c
|
||||
*
|
||||
* FreeType Image cache (body).
|
||||
*
|
||||
* Copyright (C) 2000-2023 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;
|
||||
|
||||
|
||||
if ( inode->glyph )
|
||||
{
|
||||
FT_Done_Glyph( inode->glyph );
|
||||
inode->glyph = NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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
internal/c/parts/video/font/freetype/ftcimage.h
Normal file
106
internal/c/parts/video/font/freetype/ftcimage.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcimage.h
|
||||
*
|
||||
* FreeType Generic Image cache (specification)
|
||||
*
|
||||
* Copyright (C) 2000-2023 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 */
|
696
internal/c/parts/video/font/freetype/ftcmanag.c
Normal file
696
internal/c/parts/video/font/freetype/ftcmanag.c
Normal file
|
@ -0,0 +1,696 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcmanag.c
|
||||
*
|
||||
* FreeType Cache Manager (body).
|
||||
*
|
||||
* Copyright (C) 2000-2023 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 "ftccback.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_Size size = node->size;
|
||||
FT_UNUSED( data );
|
||||
|
||||
|
||||
if ( size )
|
||||
FT_Done_Size( 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 )
|
||||
{
|
||||
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
|
||||
FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
|
||||
FTC_Manager manager = (FTC_Manager)ftcmanager;
|
||||
|
||||
|
||||
node->scaler = scaler[0];
|
||||
|
||||
return ftc_scaler_lookup_size( manager, scaler, &node->size );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
ftc_size_node_reset( FTC_MruNode ftcnode,
|
||||
FT_Pointer ftcscaler,
|
||||
FT_Pointer ftcmanager )
|
||||
{
|
||||
FTC_SizeNode node = (FTC_SizeNode)ftcnode;
|
||||
FTC_Scaler scaler = (FTC_Scaler)ftcscaler;
|
||||
FTC_Manager manager = (FTC_Manager)ftcmanager;
|
||||
|
||||
|
||||
FT_Done_Size( node->size );
|
||||
|
||||
node->scaler = scaler[0];
|
||||
|
||||
return ftc_scaler_lookup_size( manager, scaler, &node->size );
|
||||
}
|
||||
|
||||
|
||||
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_reset, /* FTC_MruNode_ResetFunc node_reset */
|
||||
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 )
|
||||
{
|
||||
FTC_FaceNode node = (FTC_FaceNode)ftcnode;
|
||||
FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
|
||||
FTC_Manager manager = (FTC_Manager)ftcmanager;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
node->face_id = face_id;
|
||||
|
||||
error = manager->request_face( face_id,
|
||||
manager->library,
|
||||
manager->request_data,
|
||||
&node->face );
|
||||
if ( !error )
|
||||
{
|
||||
/* destroy initial size object; it will be re-created later */
|
||||
if ( node->face->size )
|
||||
FT_Done_Size( node->face->size );
|
||||
}
|
||||
|
||||
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 */
|
||||
NULL, /* FTC_MruNode_ResetFunc node_reset */
|
||||
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 );
|
||||
manager->caches[idx] = NULL;
|
||||
}
|
||||
}
|
||||
manager->num_caches = 0;
|
||||
|
||||
/* discard faces and sizes */
|
||||
FTC_MruList_Done( &manager->sizes );
|
||||
FTC_MruList_Done( &manager->faces );
|
||||
|
||||
manager->library = NULL;
|
||||
manager->memory = NULL;
|
||||
|
||||
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
internal/c/parts/video/font/freetype/ftcmanag.h
Normal file
175
internal/c/parts/video/font/freetype/ftcmanag.h
Normal file
|
@ -0,0 +1,175 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcmanag.h
|
||||
*
|
||||
* FreeType Cache Manager (specification).
|
||||
*
|
||||
* Copyright (C) 2000-2023 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 */
|
352
internal/c/parts/video/font/freetype/ftcmru.c
Normal file
352
internal/c/parts/video/font/freetype/ftcmru.c
Normal file
|
@ -0,0 +1,352 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcmru.c
|
||||
*
|
||||
* FreeType MRU support (body).
|
||||
*
|
||||
* Copyright (C) 2003-2023 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;
|
||||
FT_Memory memory = list->memory;
|
||||
|
||||
|
||||
if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )
|
||||
{
|
||||
node = list->nodes->prev;
|
||||
|
||||
FT_ASSERT( node );
|
||||
|
||||
if ( list->clazz.node_reset )
|
||||
{
|
||||
FTC_MruNode_Up( &list->nodes, node );
|
||||
|
||||
error = list->clazz.node_reset( node, key, list->data );
|
||||
if ( !error )
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
FTC_MruNode_Remove( &list->nodes, node );
|
||||
list->num_nodes--;
|
||||
|
||||
if ( list->clazz.node_done )
|
||||
list->clazz.node_done( node, list->data );
|
||||
}
|
||||
|
||||
/* zero new node in case of node_init failure */
|
||||
else if ( FT_ALLOC( node, list->clazz.node_size ) )
|
||||
goto Exit;
|
||||
|
||||
error = list->clazz.node_init( node, key, list->data );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
|
||||
FTC_MruNode_Prepend( &list->nodes, node );
|
||||
list->num_nodes++;
|
||||
|
||||
Exit:
|
||||
*anode = node;
|
||||
return error;
|
||||
|
||||
Fail:
|
||||
if ( list->clazz.node_done )
|
||||
list->clazz.node_done( node, list->data );
|
||||
|
||||
FT_FREE( node );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
#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 )
|
||||
{
|
||||
FTC_MruNode_Remove( &list->nodes, node );
|
||||
list->num_nodes--;
|
||||
|
||||
{
|
||||
FT_Memory memory = list->memory;
|
||||
|
||||
|
||||
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 */
|
248
internal/c/parts/video/font/freetype/ftcmru.h
Normal file
248
internal/c/parts/video/font/freetype/ftcmru.h
Normal file
|
@ -0,0 +1,248 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcmru.h
|
||||
*
|
||||
* Simple MRU list-cache (specification).
|
||||
*
|
||||
* Copyright (C) 2000-2023 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 FT_Error
|
||||
(*FTC_MruNode_ResetFunc)( 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_ResetFunc node_reset;
|
||||
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 */
|
156
internal/c/parts/video/font/freetype/ftcolor.c
Normal file
156
internal/c/parts/video/font/freetype/ftcolor.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcolor.c
|
||||
*
|
||||
* FreeType's glyph color management (body).
|
||||
*
|
||||
* Copyright (C) 2018-2023 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 */
|
414
internal/c/parts/video/font/freetype/ftcsbits.c
Normal file
414
internal/c/parts/video/font/freetype/ftcsbits.c
Normal file
|
@ -0,0 +1,414 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftcsbits.c
|
||||
*
|
||||
* FreeType sbits manager (body).
|
||||
*
|
||||
* Copyright (C) 2000-2023 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;
|
||||
|
||||
if ( !FT_QALLOC( sbit->buffer, size ) )
|
||||
FT_MEM_COPY( 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 */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue