Generate shaping table based on unicode if source font has none
This commit is contained in:
parent
c0420b76b0
commit
3f11c7131e
4 changed files with 135 additions and 15 deletions
|
@ -82,7 +82,7 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \
|
|||
# For grub-mkfont.
|
||||
ifeq ($(enable_grub_mkfont), yes)
|
||||
bin_UTILITIES += grub-mkfont
|
||||
grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c
|
||||
grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c unidata.c
|
||||
grub_mkfont_CFLAGS = $(freetype_cflags)
|
||||
grub_mkfont_LDFLAGS = $(freetype_libs)
|
||||
endif
|
||||
|
|
|
@ -39,6 +39,19 @@ struct grub_unicode_compact_range
|
|||
grub_uint8_t join_type:3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Old-style Arabic shaping. Used for "visual UTF-8" and
|
||||
in grub-mkfont to find variant glyphs in absence of GPOS tables. */
|
||||
struct grub_unicode_arabic_shape
|
||||
{
|
||||
grub_uint32_t code;
|
||||
grub_uint32_t isolated;
|
||||
grub_uint32_t right_linked;
|
||||
grub_uint32_t both_linked;
|
||||
grub_uint32_t left_linked;
|
||||
};
|
||||
|
||||
extern struct grub_unicode_arabic_shape grub_unicode_arabic_shapes[];
|
||||
|
||||
enum grub_bidi_type
|
||||
{
|
||||
GRUB_BIDI_TYPE_L = 0,
|
||||
|
@ -150,6 +163,8 @@ struct grub_unicode_glyph
|
|||
#define GRUB_UNICODE_HEBREW_WAW 0x05d5
|
||||
#define GRUB_UNICODE_ZWNJ 0x200c
|
||||
#define GRUB_UNICODE_ZWJ 0x200d
|
||||
#define GRUB_UNICODE_ARABIC_START 0x600
|
||||
#define GRUB_UNICODE_ARABIC_END 0x700
|
||||
|
||||
extern struct grub_unicode_compact_range grub_unicode_compact[];
|
||||
extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[];
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <grub/i18n.h>
|
||||
#include <grub/fontformat.h>
|
||||
#include <grub/font.h>
|
||||
#include <grub/unicode.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -184,12 +185,18 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face,
|
|||
err = FT_Load_Glyph (face, glyph_idx, flag);
|
||||
if (err)
|
||||
{
|
||||
if (err < ARRAY_SIZE (ft_errmsgs))
|
||||
printf ("Freetype Error %d loading glyph 0x%x for U+0x%x: %s\n",
|
||||
err, glyph_idx, char_code, ft_errmsgs[err]);
|
||||
printf ("Freetype Error %d loading glyph 0x%x for U+0x%x%s",
|
||||
err, glyph_idx, char_code & GRUB_FONT_CODE_CHAR_MASK,
|
||||
char_code & GRUB_FONT_CODE_RIGHT_JOINED
|
||||
? ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (medial)":
|
||||
" (leftmost)")
|
||||
: ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (rightmost)":
|
||||
""));
|
||||
|
||||
if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs))
|
||||
printf (": %s\n", ft_errmsgs[err]);
|
||||
else
|
||||
printf ("Freetype Error %d loading glyph 0x%x for U+0x%x\n",
|
||||
err, glyph_idx, char_code);
|
||||
printf ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -268,6 +275,25 @@ add_char (struct grub_font_info *font_info, FT_Face face,
|
|||
char_code | GRUB_FONT_CODE_RIGHT_JOINED);
|
||||
break;
|
||||
}
|
||||
if (!cur && char_code >= GRUB_UNICODE_ARABIC_START
|
||||
&& char_code < GRUB_UNICODE_ARABIC_END)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; grub_unicode_arabic_shapes[i].code; i++)
|
||||
if (grub_unicode_arabic_shapes[i].code == char_code
|
||||
&& grub_unicode_arabic_shapes[i].right_linked)
|
||||
{
|
||||
FT_UInt idx2;
|
||||
idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i]
|
||||
.right_linked);
|
||||
if (idx2)
|
||||
add_glyph (font_info, idx2, face,
|
||||
char_code | GRUB_FONT_CODE_RIGHT_JOINED);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (cur = subst_leftjoin; cur; cur = cur->next)
|
||||
if (cur->from == glyph_idx)
|
||||
{
|
||||
|
@ -275,6 +301,24 @@ add_char (struct grub_font_info *font_info, FT_Face face,
|
|||
char_code | GRUB_FONT_CODE_LEFT_JOINED);
|
||||
break;
|
||||
}
|
||||
if (!cur && char_code >= GRUB_UNICODE_ARABIC_START
|
||||
&& char_code < GRUB_UNICODE_ARABIC_END)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; grub_unicode_arabic_shapes[i].code; i++)
|
||||
if (grub_unicode_arabic_shapes[i].code == char_code
|
||||
&& grub_unicode_arabic_shapes[i].left_linked)
|
||||
{
|
||||
FT_UInt idx2;
|
||||
idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i]
|
||||
.left_linked);
|
||||
if (idx2)
|
||||
add_glyph (font_info, idx2, face,
|
||||
char_code | GRUB_FONT_CODE_LEFT_JOINED);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
for (cur = subst_medijoin; cur; cur = cur->next)
|
||||
if (cur->from == glyph_idx)
|
||||
{
|
||||
|
@ -283,6 +327,25 @@ add_char (struct grub_font_info *font_info, FT_Face face,
|
|||
| GRUB_FONT_CODE_RIGHT_JOINED);
|
||||
break;
|
||||
}
|
||||
if (!cur && char_code >= GRUB_UNICODE_ARABIC_START
|
||||
&& char_code < GRUB_UNICODE_ARABIC_END)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; grub_unicode_arabic_shapes[i].code; i++)
|
||||
if (grub_unicode_arabic_shapes[i].code == char_code
|
||||
&& grub_unicode_arabic_shapes[i].both_linked)
|
||||
{
|
||||
FT_UInt idx2;
|
||||
idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i]
|
||||
.both_linked);
|
||||
if (idx2)
|
||||
add_glyph (font_info, idx2, face,
|
||||
char_code | GRUB_FONT_CODE_LEFT_JOINED
|
||||
| GRUB_FONT_CODE_RIGHT_JOINED);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct gsub_header
|
||||
|
|
|
@ -35,15 +35,15 @@ for line in infile:
|
|||
sp = line.split (";")
|
||||
curcode = int (sp[0], 16)
|
||||
if sp[2] == "U":
|
||||
joining[curcode] = "GRUB_JOIN_TYPE_NONJOINING"
|
||||
joining[curcode] = "NONJOINING"
|
||||
elif sp[2] == "L":
|
||||
joining[curcode] = "GRUB_JOIN_TYPE_LEFT"
|
||||
joining[curcode] = "LEFT"
|
||||
elif sp[2] == "R":
|
||||
joining[curcode] = "GRUB_JOIN_TYPE_RIGHT"
|
||||
joining[curcode] = "RIGHT"
|
||||
elif sp[2] == "D":
|
||||
joining[curcode] = "GRUB_JOIN_TYPE_DUAL"
|
||||
joining[curcode] = "DUAL"
|
||||
elif sp[2] == "C":
|
||||
joining[curcode] = "GRUB_JOIN_TYPE_CAUSING"
|
||||
joining[curcode] = "CAUSING"
|
||||
else:
|
||||
print ("Unknown joining type '%s'" % sp[2])
|
||||
exit (1)
|
||||
|
@ -60,6 +60,7 @@ lastcode = -2
|
|||
lastbiditype = "X"
|
||||
lastmirrortype = False
|
||||
lastcombtype = -1
|
||||
arabicsubst = {}
|
||||
for line in infile:
|
||||
sp = line.split (";")
|
||||
curcode = int (sp[0], 16)
|
||||
|
@ -102,15 +103,35 @@ for line in infile:
|
|||
if curcode in joining:
|
||||
curjoin = joining[curcode]
|
||||
elif sp[2] == "Me" or sp[2] == "Mn" or sp[2] == "Cf":
|
||||
curjoin = "GRUB_JOIN_TYPE_TRANSPARENT"
|
||||
curjoin = "TRANSPARENT"
|
||||
else:
|
||||
curjoin = "GRUB_JOIN_TYPE_NONJOINING"
|
||||
curjoin = "NONJOINING"
|
||||
if sp[1].startswith ("ARABIC LETTER "):
|
||||
arabname = sp[1][len ("ARABIC LETTER "):]
|
||||
form = 0
|
||||
if arabname.endswith (" ISOLATED FORM"):
|
||||
arabname = arabname[0:len (arabname) - len (" ISOLATED FORM")]
|
||||
form = 1
|
||||
if arabname.endswith (" FINAL FORM"):
|
||||
arabname = arabname[0:len (arabname) - len (" FINAL FORM")]
|
||||
form = 2
|
||||
if arabname.endswith (" MEDIAL FORM"):
|
||||
arabname = arabname[0:len (arabname) - len (" MEDIAL FORM")]
|
||||
form = 3
|
||||
if arabname.endswith (" INITIAL FORM"):
|
||||
arabname = arabname[0:len (arabname) - len (" INITIAL FORM")]
|
||||
form = 4
|
||||
if arabname not in arabicsubst:
|
||||
arabicsubst[arabname]={}
|
||||
arabicsubst[arabname][form] = curcode;
|
||||
if form == 0:
|
||||
arabicsubst[arabname]['join'] = curjoin
|
||||
if lastcode + 1 != curcode or curbiditype != lastbiditype \
|
||||
or curcombtype != lastcombtype or curmirrortype != lastmirrortype \
|
||||
or curjoin != lastjoin:
|
||||
if begincode != -2 and (lastbiditype != "L" or lastcombtype != 0 or \
|
||||
lastmirrortype):
|
||||
outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, %s},\n" \
|
||||
outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, GRUB_JOIN_TYPE_%s},\n" \
|
||||
% (begincode, lastcode, lastbiditype, \
|
||||
lastcombtype, lastmirrortype, \
|
||||
lastjoin)))
|
||||
|
@ -121,7 +142,7 @@ for line in infile:
|
|||
lastcombtype = curcombtype
|
||||
lastmirrortype = curmirrortype
|
||||
if lastbiditype != "L" or lastcombtype != 0 or lastmirrortype:
|
||||
outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, %s},\n" \
|
||||
outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, GRUB_JOIN_TYPE_%s},\n" \
|
||||
% (begincode, lastcode, lastbiditype, lastcombtype, \
|
||||
lastmirrortype, lastjoin)))
|
||||
outfile.write ("{0, 0, 0, 0, 0, 0},\n")
|
||||
|
@ -147,3 +168,24 @@ for line in infile:
|
|||
outfile.write ("{0, 0},\n")
|
||||
outfile.write ("};\n")
|
||||
|
||||
infile.close ()
|
||||
|
||||
outfile.write ("struct grub_unicode_arabic_shape grub_unicode_arabic_shapes[] = {\n ")
|
||||
|
||||
for x in arabicsubst:
|
||||
try:
|
||||
if arabicsubst[x]['join'] == "DUAL":
|
||||
outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], arabicsubst[x][2], arabicsubst[x][3], arabicsubst[x][4]))
|
||||
elif arabicsubst[x]['join'] == "RIGHT":
|
||||
outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], arabicsubst[x][2], 0, 0))
|
||||
elif arabicsubst[x]['join'] == "LEFT":
|
||||
outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], 0, 0, arabicsubst[x][4]))
|
||||
except:
|
||||
pass
|
||||
|
||||
outfile.write ("{0, 0, 0, 0, 0},\n")
|
||||
outfile.write ("};\n")
|
||||
|
||||
|
||||
outfile.close ()
|
||||
|
||||
|
|
Loading…
Reference in a new issue