summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorKhaled Hosny <khaledhosny@eglug.org>2014-03-14 21:23:32 +0000
committerKhaled Hosny <khaledhosny@eglug.org>2014-03-14 21:23:32 +0000
commit0af7dc6b7a6b59b735efb25e93dd4e62be2126d5 (patch)
treec08c1b55d7ae0793a37a9e621a1adebb740f12c8 /Build
parent97f7834d79c2ef1a3a7a3d0ed038881a2fb1f459 (diff)
Sync XeTeX
git-svn-id: svn://tug.org/texlive/trunk@33175 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp545
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontInst.h102
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp54
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h10
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp1047
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h272
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp548
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.h36
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h38
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm306
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp1101
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h24
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp844
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXOTMath.h30
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeX_ext.c4713
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeX_ext.h321
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeX_mac.c1362
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeX_pic.c11
-rw-r--r--Build/source/texk/web2c/xetexdir/am/xetex.am71
-rw-r--r--Build/source/texk/web2c/xetexdir/pdfimage.cpp14
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex.ch4
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex.h108
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex.web2265
-rw-r--r--Build/source/texk/web2c/xetexdir/xetexextra.h2
24 files changed, 6902 insertions, 6926 deletions
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp
index a6cd3785c4c..cc8267b91bf 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.cpp
@@ -35,8 +35,8 @@ authorization from the copyright holders.
*
* created on: 2005-10-22
* created by: Jonathan Kew
- *
- * originally based on PortableFontInstance.cpp from ICU
+ *
+ * originally based on PortableFontInstance.cpp from ICU
*/
#ifdef __cplusplus
@@ -57,6 +57,8 @@ extern "C" {
FT_Library gFreeTypeLibrary = 0;
+static hb_font_funcs_t* hbFontFuncs = NULL;
+
XeTeXFontInst::XeTeXFontInst(const char* pathname, int index, float pointSize, int &status)
: fPointSize(pointSize)
, fUnitsPerEM(0)
@@ -71,17 +73,19 @@ XeTeXFontInst::XeTeXFontInst(const char* pathname, int index, float pointSize, i
, hbFont(NULL)
, fMath(NULL)
{
- if (pathname != NULL)
- initialize(pathname, index, status);
+ if (pathname != NULL)
+ initialize(pathname, index, status);
}
XeTeXFontInst::~XeTeXFontInst()
{
- if (ftFace != 0) {
- FT_Done_Face(ftFace);
- ftFace = 0;
- }
- hb_font_destroy(hbFont);
+ if (ftFace != 0) {
+ FT_Done_Face(ftFace);
+ ftFace = 0;
+ }
+ hb_font_destroy(hbFont);
+ delete[] fFilename;
+ free((void*) fMath);
}
/* HarfBuzz font functions */
@@ -89,198 +93,198 @@ XeTeXFontInst::~XeTeXFontInst()
static hb_bool_t
_get_glyph(hb_font_t*, void *font_data, hb_codepoint_t ch, hb_codepoint_t vs, hb_codepoint_t *gid, void*)
{
- FT_Face face = (FT_Face) font_data;
- *gid = 0;
+ FT_Face face = (FT_Face) font_data;
+ *gid = 0;
- if (vs)
- *gid = FT_Face_GetCharVariantIndex (face, ch, vs);
+ if (vs)
+ *gid = FT_Face_GetCharVariantIndex (face, ch, vs);
- if (*gid == 0)
- *gid = FT_Get_Char_Index (face, ch);
+ if (*gid == 0)
+ *gid = FT_Get_Char_Index (face, ch);
- return *gid != 0;
+ return *gid != 0;
}
static FT_Fixed
_get_glyph_advance(FT_Face face, FT_UInt gid, bool vertical)
{
- FT_Error error;
- FT_Fixed advance;
- int flags = FT_LOAD_NO_SCALE;
+ FT_Error error;
+ FT_Fixed advance;
+ int flags = FT_LOAD_NO_SCALE;
- if (vertical)
- flags |= FT_LOAD_VERTICAL_LAYOUT;
+ if (vertical)
+ flags |= FT_LOAD_VERTICAL_LAYOUT;
- error = FT_Get_Advance(face, gid, flags, &advance);
- if (error)
- advance = 0;
- else
- advance = advance;
+ error = FT_Get_Advance(face, gid, flags, &advance);
+ if (error)
+ advance = 0;
+ else
+ advance = advance;
- /* FreeType's vertical metrics grows downward */
- if (vertical)
- advance = -advance;
+ /* FreeType's vertical metrics grows downward */
+ if (vertical)
+ advance = -advance;
- return advance;
+ return advance;
}
static hb_position_t
_get_glyph_h_advance(hb_font_t*, void *font_data, hb_codepoint_t gid, void*)
{
- return _get_glyph_advance((FT_Face) font_data, gid, false);
+ return _get_glyph_advance((FT_Face) font_data, gid, false);
}
static hb_position_t
_get_glyph_v_advance(hb_font_t*, void *font_data, hb_codepoint_t gid, void*)
{
- return _get_glyph_advance((FT_Face) font_data, gid, true);
+ return _get_glyph_advance((FT_Face) font_data, gid, true);
}
static hb_bool_t
_get_glyph_h_origin(hb_font_t*, void *font_data, hb_codepoint_t gid, hb_position_t *x, hb_position_t *y, void*)
{
- // horizontal origin is (0, 0)
- return true;
+ // horizontal origin is (0, 0)
+ return true;
}
static hb_bool_t
_get_glyph_v_origin(hb_font_t*, void *font_data, hb_codepoint_t gid, hb_position_t *x, hb_position_t *y, void*)
{
- // vertical origin is (0, 0) for now
- return true;
-
- // TODO
- // Keep the code below for reference, for now we want to keep vertical
- // origin at (0, 0) for compatibility with pre-0.9999.
- // Reconsider this (e.g. using BASE table) when we get around overhauling
- // the text directionality model and implementing real vertical typesetting.
-
- FT_Face face = (FT_Face) font_data;
- FT_Error error;
-
- error = FT_Load_Glyph (face, gid, FT_LOAD_NO_SCALE);
- if (!error) {
- *x = face->glyph->metrics.horiBearingX - face->glyph->metrics.vertBearingX;
- *y = face->glyph->metrics.horiBearingY - (-face->glyph->metrics.vertBearingY);
- }
+ // vertical origin is (0, 0) for now
+ return true;
+
+ // TODO
+ // Keep the code below for reference, for now we want to keep vertical
+ // origin at (0, 0) for compatibility with pre-0.9999.
+ // Reconsider this (e.g. using BASE table) when we get around overhauling
+ // the text directionality model and implementing real vertical typesetting.
+
+ FT_Face face = (FT_Face) font_data;
+ FT_Error error;
+
+ error = FT_Load_Glyph (face, gid, FT_LOAD_NO_SCALE);
+ if (!error) {
+ *x = face->glyph->metrics.horiBearingX - face->glyph->metrics.vertBearingX;
+ *y = face->glyph->metrics.horiBearingY - (-face->glyph->metrics.vertBearingY);
+ }
- return !error;
+ return !error;
}
static hb_position_t
_get_glyph_h_kerning(hb_font_t*, void *font_data, hb_codepoint_t gid1, hb_codepoint_t gid2, void*)
{
- FT_Face face = (FT_Face) font_data;
- FT_Error error;
- FT_Vector kerning;
- hb_position_t ret;
+ FT_Face face = (FT_Face) font_data;
+ FT_Error error;
+ FT_Vector kerning;
+ hb_position_t ret;
- error = FT_Get_Kerning (face, gid1, gid2, FT_KERNING_UNFITTED, &kerning);
- if (error)
- ret = 0;
- else
- ret = kerning.x;
- return ret;
+ error = FT_Get_Kerning (face, gid1, gid2, FT_KERNING_UNFITTED, &kerning);
+ if (error)
+ ret = 0;
+ else
+ ret = kerning.x;
+ return ret;
}
static hb_position_t
_get_glyph_v_kerning(hb_font_t*, void *font_data, hb_codepoint_t gid1, hb_codepoint_t gid2, void*)
{
- /* FreeType does not support vertical kerning */
- return 0;
+ /* FreeType does not support vertical kerning */
+ return 0;
}
static hb_bool_t
_get_glyph_extents(hb_font_t*, void *font_data, hb_codepoint_t gid, hb_glyph_extents_t *extents, void*)
{
- FT_Face face = (FT_Face) font_data;
- FT_Error error;
-
- error = FT_Load_Glyph (face, gid, FT_LOAD_NO_SCALE);
- if (!error) {
- extents->x_bearing = face->glyph->metrics.horiBearingX;
- extents->y_bearing = face->glyph->metrics.horiBearingY;
- extents->width = face->glyph->metrics.width;
- extents->height = -face->glyph->metrics.height;
- }
+ FT_Face face = (FT_Face) font_data;
+ FT_Error error;
+
+ error = FT_Load_Glyph (face, gid, FT_LOAD_NO_SCALE);
+ if (!error) {
+ extents->x_bearing = face->glyph->metrics.horiBearingX;
+ extents->y_bearing = face->glyph->metrics.horiBearingY;
+ extents->width = face->glyph->metrics.width;
+ extents->height = -face->glyph->metrics.height;
+ }
- return !error;
+ return !error;
}
static hb_bool_t
_get_glyph_contour_point(hb_font_t*, void *font_data, hb_codepoint_t gid, unsigned int point_index, hb_position_t *x, hb_position_t *y, void*)
{
- FT_Face face = (FT_Face) font_data;
- FT_Error error;
- bool ret = false;
-
- error = FT_Load_Glyph (face, gid, FT_LOAD_NO_SCALE);
- if (!error) {
- if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
- if (point_index < (unsigned int) face->glyph->outline.n_points) {
- *x = face->glyph->outline.points[point_index].x;
- *y = face->glyph->outline.points[point_index].y;
- ret = true;
- }
- }
- }
+ FT_Face face = (FT_Face) font_data;
+ FT_Error error;
+ bool ret = false;
+
+ error = FT_Load_Glyph (face, gid, FT_LOAD_NO_SCALE);
+ if (!error) {
+ if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
+ if (point_index < (unsigned int) face->glyph->outline.n_points) {
+ *x = face->glyph->outline.points[point_index].x;
+ *y = face->glyph->outline.points[point_index].y;
+ ret = true;
+ }
+ }
+ }
- return ret;
+ return ret;
}
static hb_bool_t
_get_glyph_name(hb_font_t *, void *font_data, hb_codepoint_t gid, char *name, unsigned int size, void *)
{
- FT_Face face = (FT_Face) font_data;
- bool ret = false;
+ FT_Face face = (FT_Face) font_data;
+ bool ret = false;
- ret = !FT_Get_Glyph_Name (face, gid, name, size);
- if (ret && (size && !*name))
- ret = false;
+ ret = !FT_Get_Glyph_Name (face, gid, name, size);
+ if (ret && (size && !*name))
+ ret = false;
- return ret;
+ return ret;
}
static hb_font_funcs_t *
_get_font_funcs(void)
{
- static hb_font_funcs_t* funcs = hb_font_funcs_create();
+ static hb_font_funcs_t* funcs = hb_font_funcs_create();
- hb_font_funcs_set_glyph_func (funcs, _get_glyph, NULL, NULL);
- hb_font_funcs_set_glyph_h_advance_func (funcs, _get_glyph_h_advance, NULL, NULL);
- hb_font_funcs_set_glyph_v_advance_func (funcs, _get_glyph_v_advance, NULL, NULL);
- hb_font_funcs_set_glyph_h_origin_func (funcs, _get_glyph_h_origin, NULL, NULL);
- hb_font_funcs_set_glyph_v_origin_func (funcs, _get_glyph_v_origin, NULL, NULL);
- hb_font_funcs_set_glyph_h_kerning_func (funcs, _get_glyph_h_kerning, NULL, NULL);
- hb_font_funcs_set_glyph_v_kerning_func (funcs, _get_glyph_v_kerning, NULL, NULL);
- hb_font_funcs_set_glyph_extents_func (funcs, _get_glyph_extents, NULL, NULL);
- hb_font_funcs_set_glyph_contour_point_func (funcs, _get_glyph_contour_point, NULL, NULL);
- hb_font_funcs_set_glyph_name_func (funcs, _get_glyph_name, NULL, NULL);
+ hb_font_funcs_set_glyph_func (funcs, _get_glyph, NULL, NULL);
+ hb_font_funcs_set_glyph_h_advance_func (funcs, _get_glyph_h_advance, NULL, NULL);
+ hb_font_funcs_set_glyph_v_advance_func (funcs, _get_glyph_v_advance, NULL, NULL);
+ hb_font_funcs_set_glyph_h_origin_func (funcs, _get_glyph_h_origin, NULL, NULL);
+ hb_font_funcs_set_glyph_v_origin_func (funcs, _get_glyph_v_origin, NULL, NULL);
+ hb_font_funcs_set_glyph_h_kerning_func (funcs, _get_glyph_h_kerning, NULL, NULL);
+ hb_font_funcs_set_glyph_v_kerning_func (funcs, _get_glyph_v_kerning, NULL, NULL);
+ hb_font_funcs_set_glyph_extents_func (funcs, _get_glyph_extents, NULL, NULL);
+ hb_font_funcs_set_glyph_contour_point_func (funcs, _get_glyph_contour_point, NULL, NULL);
+ hb_font_funcs_set_glyph_name_func (funcs, _get_glyph_name, NULL, NULL);
- return funcs;
+ return funcs;
}
static hb_blob_t *
_get_table(hb_face_t *, hb_tag_t tag, void *user_data)
{
- FT_Face face = (FT_Face) user_data;
- FT_ULong length = 0;
- FT_Byte *table;
- FT_Error error;
- hb_blob_t* blob = NULL;
-
- error = FT_Load_Sfnt_Table(face, tag, 0, NULL, &length);
- if (!error) {
- table = (FT_Byte *) xmalloc(length * sizeof(char));
- if (table != NULL) {
- error = FT_Load_Sfnt_Table(face, tag, 0, (FT_Byte*)table, &length);
- if (!error) {
- blob = hb_blob_create((const char*) table, length, HB_MEMORY_MODE_WRITABLE, table, free);
- } else {
- free(table);
- }
- }
- }
+ FT_Face face = (FT_Face) user_data;
+ FT_ULong length = 0;
+ FT_Byte *table;
+ FT_Error error;
+ hb_blob_t* blob = NULL;
+
+ error = FT_Load_Sfnt_Table(face, tag, 0, NULL, &length);
+ if (!error) {
+ table = (FT_Byte *) xmalloc(length * sizeof(char));
+ if (table != NULL) {
+ error = FT_Load_Sfnt_Table(face, tag, 0, (FT_Byte*)table, &length);
+ if (!error) {
+ blob = hb_blob_create((const char*) table, length, HB_MEMORY_MODE_WRITABLE, table, free);
+ } else {
+ free(table);
+ }
+ }
+ }
return blob;
}
@@ -288,76 +292,79 @@ _get_table(hb_face_t *, hb_tag_t tag, void *user_data)
void
XeTeXFontInst::initialize(const char* pathname, int index, int &status)
{
- TT_Postscript *postTable;
- TT_OS2* os2Table;
- FT_Error error;
- hb_face_t *hbFace;
-
- if (!gFreeTypeLibrary) {
- error = FT_Init_FreeType(&gFreeTypeLibrary);
- if (error) {
- fprintf(stderr, "FreeType initialization failed! (%d)\n", error);
- exit(1);
- }
- }
-
- error = FT_New_Face(gFreeTypeLibrary, (char*)pathname, index, &ftFace);
- if (error) {
+ TT_Postscript *postTable;
+ TT_OS2* os2Table;
+ FT_Error error;
+ hb_face_t *hbFace;
+
+ if (!gFreeTypeLibrary) {
+ error = FT_Init_FreeType(&gFreeTypeLibrary);
+ if (error) {
+ fprintf(stderr, "FreeType initialization failed! (%d)\n", error);
+ exit(1);
+ }
+ }
+
+ error = FT_New_Face(gFreeTypeLibrary, (char*)pathname, index, &ftFace);
+ if (error) {
+ status = 1;
+ return;
+ }
+
+ if (!FT_IS_SCALABLE(ftFace)) {
status = 1;
return;
}
- if (!FT_IS_SCALABLE(ftFace)) {
- status = 1;
- return;
- }
-
- /* for non-sfnt-packaged fonts (presumably Type 1), see if there is an AFM file we can attach */
- if (index == 0 && !FT_IS_SFNT(ftFace)) {
- char* afm = new char[strlen((const char*)pathname) + 5]; // room to append ".afm"
- strcpy(afm, (const char*)pathname);
- char* p = strrchr(afm, '.');
- if (p == NULL || strlen(p) != 4 || tolower(*(p+1)) != 'p' || tolower(*(p+2)) != 'f')
- strcat(afm, ".afm"); // append .afm if the extension didn't seem to be .pf[ab]
- else
- strcpy(p, ".afm"); // else replace extension with .afm
- FT_Attach_File(ftFace, afm); // ignore error code; AFM might not exist
- delete[] afm;
- }
-
- char buf[20];
- if (index > 0)
- sprintf(buf, ":%d", index);
- else
- buf[0] = 0;
- fFilename = new char[strlen(pathname) + 2 + strlen(buf) + 1];
- sprintf(fFilename, "[%s%s]", pathname, buf);
- fUnitsPerEM = ftFace->units_per_EM;
- fAscent = unitsToPoints(ftFace->ascender);
- fDescent = unitsToPoints(ftFace->descender);
-
- postTable = (TT_Postscript *) getFontTable(ft_sfnt_post);
- if (postTable != NULL) {
- fItalicAngle = Fix2D(postTable->italicAngle);
- }
-
- os2Table = (TT_OS2*) getFontTable(ft_sfnt_os2);
- if (os2Table) {
- fCapHeight = unitsToPoints(os2Table->sCapHeight);
- fXHeight = unitsToPoints(os2Table->sxHeight);
- }
-
- // Set up HarfBuzz font
- hbFace = hb_face_create_for_tables(_get_table, ftFace, NULL);
- hb_face_set_index(hbFace, index);
- hb_face_set_upem(hbFace, fUnitsPerEM);
- hbFont = hb_font_create(hbFace);
- hb_face_destroy(hbFace);
-
- hb_font_set_funcs(hbFont, _get_font_funcs(), ftFace, NULL);
- hb_font_set_scale(hbFont, fUnitsPerEM, fUnitsPerEM);
- // We don’t want device tables adjustments
- hb_font_set_ppem(hbFont, 0, 0);
+ /* for non-sfnt-packaged fonts (presumably Type 1), see if there is an AFM file we can attach */
+ if (index == 0 && !FT_IS_SFNT(ftFace)) {
+ char* afm = new char[strlen((const char*)pathname) + 5]; // room to append ".afm"
+ strcpy(afm, (const char*)pathname);
+ char* p = strrchr(afm, '.');
+ if (p == NULL || strlen(p) != 4 || tolower(*(p+1)) != 'p' || tolower(*(p+2)) != 'f')
+ strcat(afm, ".afm"); // append .afm if the extension didn't seem to be .pf[ab]
+ else
+ strcpy(p, ".afm"); // else replace extension with .afm
+ FT_Attach_File(ftFace, afm); // ignore error code; AFM might not exist
+ delete[] afm;
+ }
+
+ char buf[20];
+ if (index > 0)
+ sprintf(buf, ":%d", index);
+ else
+ buf[0] = 0;
+ fFilename = new char[strlen(pathname) + 2 + strlen(buf) + 1];
+ sprintf(fFilename, "[%s%s]", pathname, buf);
+ fUnitsPerEM = ftFace->units_per_EM;
+ fAscent = unitsToPoints(ftFace->ascender);
+ fDescent = unitsToPoints(ftFace->descender);
+
+ postTable = (TT_Postscript *) getFontTable(ft_sfnt_post);
+ if (postTable != NULL) {
+ fItalicAngle = Fix2D(postTable->italicAngle);
+ }
+
+ os2Table = (TT_OS2*) getFontTable(ft_sfnt_os2);
+ if (os2Table) {
+ fCapHeight = unitsToPoints(os2Table->sCapHeight);
+ fXHeight = unitsToPoints(os2Table->sxHeight);
+ }
+
+ // Set up HarfBuzz font
+ hbFace = hb_face_create_for_tables(_get_table, ftFace, NULL);
+ hb_face_set_index(hbFace, index);
+ hb_face_set_upem(hbFace, fUnitsPerEM);
+ hbFont = hb_font_create(hbFace);
+ hb_face_destroy(hbFace);
+
+ if (hbFontFuncs == NULL)
+ hbFontFuncs = _get_font_funcs();
+
+ hb_font_set_funcs(hbFont, hbFontFuncs, ftFace, NULL);
+ hb_font_set_scale(hbFont, fUnitsPerEM, fUnitsPerEM);
+ // We don’t want device tables adjustments
+ hb_font_set_ppem(hbFont, 0, 0);
return;
}
@@ -365,25 +372,25 @@ XeTeXFontInst::initialize(const char* pathname, int index, int &status)
void
XeTeXFontInst::setLayoutDirVertical(bool vertical)
{
- fVertical = vertical;
+ fVertical = vertical;
}
const void *
XeTeXFontInst::getFontTable(OTTag tag) const
{
- FT_ULong tmpLength = 0;
- FT_Error error = FT_Load_Sfnt_Table(ftFace, tag, 0, NULL, &tmpLength);
- if (error)
- return NULL;
-
- void* table = xmalloc(tmpLength * sizeof(char));
- if (table != NULL) {
- error = FT_Load_Sfnt_Table(ftFace, tag, 0, (FT_Byte*)table, &tmpLength);
- if (error) {
- free((void *) table);
- return NULL;
- }
- }
+ FT_ULong tmpLength = 0;
+ FT_Error error = FT_Load_Sfnt_Table(ftFace, tag, 0, NULL, &tmpLength);
+ if (error)
+ return NULL;
+
+ void* table = xmalloc(tmpLength * sizeof(char));
+ if (table != NULL) {
+ error = FT_Load_Sfnt_Table(ftFace, tag, 0, (FT_Byte*)table, &tmpLength);
+ if (error) {
+ free((void *) table);
+ return NULL;
+ }
+ }
return table;
}
@@ -391,136 +398,136 @@ XeTeXFontInst::getFontTable(OTTag tag) const
const char *
XeTeXFontInst::getMathTable()
{
- if (fMath == NULL)
- fMath = (const char*) getFontTable(MATH_TAG);
- return fMath;
+ if (fMath == NULL)
+ fMath = (const char*) getFontTable(MATH_TAG);
+ return fMath;
}
const void *
XeTeXFontInst::getFontTable(FT_Sfnt_Tag tag) const
{
- return FT_Get_Sfnt_Table(ftFace, tag);
+ return FT_Get_Sfnt_Table(ftFace, tag);
}
void
XeTeXFontInst::getGlyphBounds(GlyphID gid, GlyphBBox* bbox)
{
- bbox->xMin = bbox->yMin = bbox->xMax = bbox->yMax = 0.0;
+ bbox->xMin = bbox->yMin = bbox->xMax = bbox->yMax = 0.0;
- FT_Error error = FT_Load_Glyph(ftFace, gid, FT_LOAD_NO_SCALE);
- if (error)
- return;
+ FT_Error error = FT_Load_Glyph(ftFace, gid, FT_LOAD_NO_SCALE);
+ if (error)
+ return;
FT_Glyph glyph;
error = FT_Get_Glyph(ftFace->glyph, &glyph);
- if (error == 0) {
- FT_BBox ft_bbox;
- FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_UNSCALED, &ft_bbox);
- bbox->xMin = unitsToPoints(ft_bbox.xMin);
- bbox->yMin = unitsToPoints(ft_bbox.yMin);
- bbox->xMax = unitsToPoints(ft_bbox.xMax);
- bbox->yMax = unitsToPoints(ft_bbox.yMax);
- FT_Done_Glyph(glyph);
- }
+ if (error == 0) {
+ FT_BBox ft_bbox;
+ FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_UNSCALED, &ft_bbox);
+ bbox->xMin = unitsToPoints(ft_bbox.xMin);
+ bbox->yMin = unitsToPoints(ft_bbox.yMin);
+ bbox->xMax = unitsToPoints(ft_bbox.xMax);
+ bbox->yMax = unitsToPoints(ft_bbox.yMax);
+ FT_Done_Glyph(glyph);
+ }
}
GlyphID
XeTeXFontInst::mapCharToGlyph(UChar32 ch) const
{
- return FT_Get_Char_Index(ftFace, ch);
+ return FT_Get_Char_Index(ftFace, ch);
}
uint16_t
XeTeXFontInst::getNumGlyphs() const
{
- return ftFace->num_glyphs;
+ return ftFace->num_glyphs;
}
float
XeTeXFontInst::getGlyphWidth(GlyphID gid)
{
- return unitsToPoints(_get_glyph_advance(ftFace, gid, false));
+ return unitsToPoints(_get_glyph_advance(ftFace, gid, false));
}
void
XeTeXFontInst::getGlyphHeightDepth(GlyphID gid, float* ht, float* dp)
{
- GlyphBBox bbox;
- getGlyphBounds(gid, &bbox);
+ GlyphBBox bbox;
+ getGlyphBounds(gid, &bbox);
- if (ht)
- *ht = bbox.yMax;
- if (dp)
- *dp = -bbox.yMin;
+ if (ht)
+ *ht = bbox.yMax;
+ if (dp)
+ *dp = -bbox.yMin;
}
void
XeTeXFontInst::getGlyphSidebearings(GlyphID gid, float* lsb, float* rsb)
{
- float width = getGlyphWidth(gid);
+ float width = getGlyphWidth(gid);
- GlyphBBox bbox;
- getGlyphBounds(gid, &bbox);
+ GlyphBBox bbox;
+ getGlyphBounds(gid, &bbox);
- if (lsb)
- *lsb = bbox.xMin;
- if (rsb)
- *rsb = width - bbox.xMax;
+ if (lsb)
+ *lsb = bbox.xMin;
+ if (rsb)
+ *rsb = width - bbox.xMax;
}
float
XeTeXFontInst::getGlyphItalCorr(GlyphID gid)
{
- float rval = 0.0;
+ float rval = 0.0;
+
+ float width = getGlyphWidth(gid);
- float width = getGlyphWidth(gid);
+ GlyphBBox bbox;
+ getGlyphBounds(gid, &bbox);
- GlyphBBox bbox;
- getGlyphBounds(gid, &bbox);
-
- if (bbox.xMax > width)
- rval = bbox.xMax - width;
-
- return rval;
+ if (bbox.xMax > width)
+ rval = bbox.xMax - width;
+
+ return rval;
}
GlyphID
XeTeXFontInst::mapGlyphToIndex(const char* glyphName) const
{
- return FT_Get_Name_Index(ftFace, const_cast<char*>(glyphName));
+ return FT_Get_Name_Index(ftFace, const_cast<char*>(glyphName));
}
const char*
XeTeXFontInst::getGlyphName(GlyphID gid, int& nameLen)
{
- if (FT_HAS_GLYPH_NAMES(ftFace)) {
- static char buffer[256];
- FT_Get_Glyph_Name(ftFace, gid, buffer, 256);
- nameLen = strlen(buffer);
- return &buffer[0];
- }
- else {
- nameLen = 0;
- return NULL;
- }
+ if (FT_HAS_GLYPH_NAMES(ftFace)) {
+ static char buffer[256];
+ FT_Get_Glyph_Name(ftFace, gid, buffer, 256);
+ nameLen = strlen(buffer);
+ return &buffer[0];
+ }
+ else {
+ nameLen = 0;
+ return NULL;
+ }
}
UChar32
XeTeXFontInst::getFirstCharCode()
{
- FT_UInt gindex;
- return FT_Get_First_Char(ftFace, &gindex);
+ FT_UInt gindex;
+ return FT_Get_First_Char(ftFace, &gindex);
}
UChar32
XeTeXFontInst::getLastCharCode()
{
- FT_UInt gindex;
- UChar32 ch = FT_Get_First_Char(ftFace, &gindex);
- UChar32 prev = ch;
- while (gindex != 0) {
- prev = ch;
- ch = FT_Get_Next_Char(ftFace, ch, &gindex);
- }
- return prev;
+ FT_UInt gindex;
+ UChar32 ch = FT_Get_First_Char(ftFace, &gindex);
+ UChar32 prev = ch;
+ while (gindex != 0) {
+ prev = ch;
+ ch = FT_Get_Next_Char(ftFace, ch, &gindex);
+ }
+ return prev;
}
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h
index 119f42808a9..49e0cbe58d9 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst.h
@@ -35,8 +35,8 @@ authorization from the copyright holders.
*
* created on: 2005-10-22
* created by: Jonathan Kew
- *
- * originally based on PortableFontInstance.h from ICU
+ *
+ * originally based on PortableFontInstance.h from ICU
*/
@@ -57,72 +57,72 @@ authorization from the copyright holders.
class XeTeXFontInst
{
protected:
- unsigned short fUnitsPerEM;
- float fPointSize;
- float fAscent;
- float fDescent;
- float fCapHeight;
- float fXHeight;
- float fItalicAngle;
+ unsigned short fUnitsPerEM;
+ float fPointSize;
+ float fAscent;
+ float fDescent;
+ float fCapHeight;
+ float fXHeight;
+ float fItalicAngle;
- bool fVertical; // false = horizontal, true = vertical
+ bool fVertical; // false = horizontal, true = vertical
- char *fFilename; // actually holds [filename:index], as used in xetex
+ char *fFilename; // actually holds [filename:index], as used in xetex
- FT_Face ftFace;
- hb_font_t* hbFont;
- const char *fMath;
+ FT_Face ftFace;
+ hb_font_t* hbFont;
+ const char *fMath;
public:
- XeTeXFontInst(float pointSize, int &status);
- XeTeXFontInst(const char* filename, int index, float pointSize, int &status);
+ XeTeXFontInst(float pointSize, int &status);
+ XeTeXFontInst(const char* filename, int index, float pointSize, int &status);
+
+ virtual ~XeTeXFontInst();
- virtual ~XeTeXFontInst();
+ void initialize(const char* pathname, int index, int &status);
- void initialize(const char* pathname, int index, int &status);
+ const void *getFontTable(OTTag tableTag) const;
+ const void *getFontTable(FT_Sfnt_Tag tableTag) const;
+ const char *getMathTable();
- const void *getFontTable(OTTag tableTag) const;
- const void *getFontTable(FT_Sfnt_Tag tableTag) const;
- const char *getMathTable();
+ const char *getFilename() const { return fFilename; }
+ hb_font_t *getHbFont() const { return hbFont; }
+ void setLayoutDirVertical(bool vertical);
+ bool getLayoutDirVertical() const { return fVertical; };
- const char *getFilename() const { return fFilename; }
- hb_font_t *getHbFont() const { return hbFont; }
- void setLayoutDirVertical(bool vertical);
- bool getLayoutDirVertical() const { return fVertical; };
+ float getPointSize() const { return fPointSize; };
+ float getAscent() const { return fAscent; }
+ float getDescent() const { return fDescent; }
+ float getCapHeight() const { return fCapHeight; }
+ float getXHeight() const { return fXHeight; }
+ float getItalicAngle() const { return fItalicAngle; }
- float getPointSize() const { return fPointSize; };
- float getAscent() const { return fAscent; }
- float getDescent() const { return fDescent; }
- float getCapHeight() const { return fCapHeight; }
- float getXHeight() const { return fXHeight; }
- float getItalicAngle() const { return fItalicAngle; }
+ GlyphID mapCharToGlyph(UChar32 ch) const;
+ GlyphID mapGlyphToIndex(const char* glyphName) const;
- GlyphID mapCharToGlyph(UChar32 ch) const;
- GlyphID mapGlyphToIndex(const char* glyphName) const;
+ uint16_t getNumGlyphs() const;
- uint16_t getNumGlyphs() const;
+ void getGlyphBounds(GlyphID glyph, GlyphBBox* bbox);
- void getGlyphBounds(GlyphID glyph, GlyphBBox* bbox);
+ float getGlyphWidth(GlyphID glyph);
+ void getGlyphHeightDepth(GlyphID glyph, float *ht, float* dp);
+ void getGlyphSidebearings(GlyphID glyph, float* lsb, float* rsb);
+ float getGlyphItalCorr(GlyphID glyph);
- float getGlyphWidth(GlyphID glyph);
- void getGlyphHeightDepth(GlyphID glyph, float *ht, float* dp);
- void getGlyphSidebearings(GlyphID glyph, float* lsb, float* rsb);
- float getGlyphItalCorr(GlyphID glyph);
+ const char* getGlyphName(GlyphID gid, int& nameLen);
- const char* getGlyphName(GlyphID gid, int& nameLen);
-
- UChar32 getFirstCharCode();
- UChar32 getLastCharCode();
+ UChar32 getFirstCharCode();
+ UChar32 getLastCharCode();
- float unitsToPoints(float units) const
- {
- return (units * fPointSize) / (float) fUnitsPerEM;
- }
+ float unitsToPoints(float units) const
+ {
+ return (units * fPointSize) / (float) fUnitsPerEM;
+ }
- float pointsToUnits(float points) const
- {
- return (points * (float) fUnitsPerEM) / fPointSize;
- }
+ float pointsToUnits(float points) const
+ {
+ return (points * (float) fUnitsPerEM) / fPointSize;
+ }
};
#endif
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp
index 895e5432f36..b79ba144dc7 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.cpp
@@ -55,15 +55,15 @@ XeTeXFontInst_Mac::XeTeXFontInst_Mac(CTFontDescriptorRef descriptor, float point
, fDescriptor(descriptor)
, fFontRef(0)
{
- initialize(status);
+ initialize(status);
}
XeTeXFontInst_Mac::~XeTeXFontInst_Mac()
{
- if (fDescriptor != 0)
- CFRelease(fDescriptor);
- if (fFontRef != 0)
- CFRelease(fFontRef);
+ if (fDescriptor != 0)
+ CFRelease(fDescriptor);
+ if (fFontRef != 0)
+ CFRelease(fFontRef);
}
void
@@ -74,29 +74,29 @@ XeTeXFontInst_Mac::initialize(int &status)
return;
}
- if (status != 0)
- fDescriptor = 0;
+ if (status != 0)
+ fDescriptor = 0;
- // Create a copy of original font descriptor with font cascading (fallback) disabled
- CFArrayRef emptyCascadeList = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
- const void* values[] = { emptyCascadeList };
- static const void* attributeKeys[] = { kCTFontCascadeListAttribute };
- CFDictionaryRef attributes = CFDictionaryCreate(NULL, attributeKeys, values, 1,
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFRelease(emptyCascadeList);
+ // Create a copy of original font descriptor with font cascading (fallback) disabled
+ CFArrayRef emptyCascadeList = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
+ const void* values[] = { emptyCascadeList };
+ static const void* attributeKeys[] = { kCTFontCascadeListAttribute };
+ CFDictionaryRef attributes = CFDictionaryCreate(NULL, attributeKeys, values, 1,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFRelease(emptyCascadeList);
- fDescriptor = CTFontDescriptorCreateCopyWithAttributes(fDescriptor, attributes);
- CFRelease(attributes);
- fFontRef = CTFontCreateWithFontDescriptor(fDescriptor, fPointSize * 72.0 / 72.27, NULL);
- if (fFontRef) {
- char *pathname;
- int index;
- pathname = getFileNameFromCTFont(fFontRef, &index);
+ fDescriptor = CTFontDescriptorCreateCopyWithAttributes(fDescriptor, attributes);
+ CFRelease(attributes);
+ fFontRef = CTFontCreateWithFontDescriptor(fDescriptor, fPointSize * 72.0 / 72.27, NULL);
+ if (fFontRef) {
+ char *pathname;
+ int index;
+ pathname = getFileNameFromCTFont(fFontRef, &index);
- XeTeXFontInst::initialize(pathname, index, status);
- } else {
- status = 1;
- CFRelease(fDescriptor);
- fDescriptor = 0;
- }
+ XeTeXFontInst::initialize(pathname, index, status);
+ } else {
+ status = 1;
+ CFRelease(fDescriptor);
+ fDescriptor = 0;
+ }
}
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h
index 293613a517b..875414b942f 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_Mac.h
@@ -49,15 +49,15 @@ authorization from the copyright holders.
class XeTeXFontInst_Mac : public XeTeXFontInst
{
protected:
- CTFontDescriptorRef fDescriptor;
- CTFontRef fFontRef;
+ CTFontDescriptorRef fDescriptor;
+ CTFontRef fFontRef;
public:
- XeTeXFontInst_Mac(CTFontDescriptorRef descriptor, float pointSize, int &status);
+ XeTeXFontInst_Mac(CTFontDescriptorRef descriptor, float pointSize, int &status);
- virtual ~XeTeXFontInst_Mac();
+ virtual ~XeTeXFontInst_Mac();
- virtual void initialize(int &status);
+ virtual void initialize(int &status);
};
#endif
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp
index 27eb5782d2e..dcc4a2fba46 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.cpp
@@ -45,17 +45,19 @@ extern "C" {
#endif
#include "XeTeXFontInst.h"
+#include <hb-ot.h>
+
extern "C" {
extern Fixed loadedfontdesignsize;
}
// functions from the Pascal/WEB side
extern "C" {
- void zprintnl(int s);
- void zprintchar(int c);
- void begindiagnostic();
- void zenddiagnostic(int nl);
- int gettracingfontsstate();
+ void zprintnl(int s);
+ void zprintchar(int c);
+ void begindiagnostic();
+ void zenddiagnostic(int nl);
+ int gettracingfontsstate();
};
// see cpascal.h
@@ -66,7 +68,7 @@ extern "C" {
zprintchar(*(ch_ptr++)); \
} while (0)
-XeTeXFontMgr* XeTeXFontMgr::sFontManager = NULL;
+XeTeXFontMgr* XeTeXFontMgr::sFontManager = NULL;
char XeTeXFontMgr::sReqEngine = 0;
/* use our own fmax function because it seems to be missing on certain platforms
@@ -74,606 +76,607 @@ char XeTeXFontMgr::sReqEngine = 0;
static inline double
my_fmax(double x, double y)
{
- return (x > y) ? x : y;
+ return (x > y) ? x : y;
}
XeTeXFontMgr*
XeTeXFontMgr::GetFontManager()
{
- if (sFontManager == NULL) {
+ if (sFontManager == NULL) {
#ifdef XETEX_MAC
- sFontManager = new XeTeXFontMgr_Mac;
+ sFontManager = new XeTeXFontMgr_Mac;
#else
- sFontManager = new XeTeXFontMgr_FC;
+ sFontManager = new XeTeXFontMgr_FC;
#endif
- sFontManager->initialize();
- }
-
- return sFontManager;
+ sFontManager->initialize();
+ }
+
+ return sFontManager;
}
void
XeTeXFontMgr::Terminate()
{
- if (sFontManager != NULL) {
- sFontManager->terminate();
- // we don't actually deallocate the manager, just ask it to clean up
- // any auxiliary data such as the cocoa pool or freetype/fontconfig stuff
- // as we still need to access font names after this is called
- }
+ if (sFontManager != NULL) {
+ sFontManager->terminate();
+ // we don't actually deallocate the manager, just ask it to clean up
+ // any auxiliary data such as the cocoa pool or freetype/fontconfig stuff
+ // as we still need to access font names after this is called
+ }
}
PlatformFontRef
XeTeXFontMgr::findFont(const char* name, char* variant, double ptSize)
- // ptSize is in TeX points, or negative for 'scaled' factor
- // "variant" string will be shortened (in-place) by removal of /B and /I if present
+ // ptSize is in TeX points, or negative for 'scaled' factor
+ // "variant" string will be shortened (in-place) by removal of /B and /I if present
{
- std::string nameStr(name);
- Font* font = NULL;
- int dsize = 100;
- loadedfontdesignsize = 655360L;
-
- for (int pass = 0; pass < 2; ++pass) {
- // try full name as given
- std::map<std::string,Font*>::iterator i = nameToFont.find(nameStr);
- if (i != nameToFont.end()) {
- font = i->second;
- if (font->opSizeInfo.designSize != 0)
- dsize = font->opSizeInfo.designSize;
- break;
- }
-
- // if there's a hyphen, split there and try Family-Style
- int hyph = nameStr.find('-');
- if (hyph > 0 && hyph < nameStr.length() - 1) {
- std::string family(nameStr.begin(), nameStr.begin() + hyph);
- std::map<std::string,Family*>::iterator f = nameToFamily.find(family);
- if (f != nameToFamily.end()) {
- std::string style(nameStr.begin() + hyph + 1, nameStr.end());
- i = f->second->styles->find(style);
- if (i != f->second->styles->end()) {
- font = i->second;
- if (font->opSizeInfo.designSize != 0)
- dsize = font->opSizeInfo.designSize;
- break;
- }
- }
- }
-
- // try as PostScript name
- i = psNameToFont.find(nameStr);
- if (i != psNameToFont.end()) {
- font = i->second;
- if (font->opSizeInfo.designSize != 0)
- dsize = font->opSizeInfo.designSize;
- break;
- }
-
- // try for the name as a family name
- std::map<std::string,Family*>::iterator f = nameToFamily.find(nameStr);
-
- if (f != nameToFamily.end()) {
- // look for a family member with the "regular" bit set in OS/2
- int regFonts = 0;
- for (i = f->second->styles->begin(); i != f->second->styles->end(); ++i)
- if (i->second->isReg) {
- if (regFonts == 0)
- font = i->second;
- ++regFonts;
- }
-
- // families with Ornament or similar fonts may flag those as Regular,
- // which confuses the search above... so try some known names
- if (font == NULL || regFonts > 1) {
- // try for style "Regular", "Plain", "Normal", "Roman"
- i = f->second->styles->find("Regular");
- if (i != f->second->styles->end())
- font = i->second;
- else {
- i = f->second->styles->find("Plain");
- if (i != f->second->styles->end())
- font = i->second;
- else {
- i = f->second->styles->find("Normal");
- if (i != f->second->styles->end())
- font = i->second;
- else {
- i = f->second->styles->find("Roman");
- if (i != f->second->styles->end())
- font = i->second;
- }
- }
- }
- }
-
- if (font == NULL) {
- // look through the family for the (weight, width, slant) nearest to (80, 100, 0)
- font = bestMatchFromFamily(f->second, 80, 100, 0);
- }
-
- if (font != NULL)
- break;
- }
-
- if (pass == 0) {
- // didn't find it in our caches, so do a platform search (may be relatively expensive);
- // this will update the caches with any fonts that seem to match the name given,
- // so that the second pass might find it
- searchForHostPlatformFonts(nameStr);
- }
- }
-
- if (font == NULL)
- return 0;
-
- Family* parent = font->parent;
-
- // if there are variant requests, try to apply them
- // and delete B, I, and S=... codes from the string, just retain /engine option
- sReqEngine = 0;
- bool reqBold = false;
- bool reqItal = false;
- if (variant != NULL) {
- std::string varString;
- char* cp = variant;
- while (*cp) {
- if (strncmp(cp, "AAT", 3) == 0) {
- sReqEngine = 'A';
- cp += 3;
- if (varString.length() > 0 && *(varString.end() - 1) != '/')
- varString.append("/");
- varString.append("AAT");
- goto skip_to_slash;
- }
- if (strncmp(cp, "ICU", 3) == 0) { // for backword compatability
- sReqEngine = 'O';
- cp += 3;
- if (varString.length() > 0 && *(varString.end() - 1) != '/')
- varString.append("/");
- varString.append("OT");
- goto skip_to_slash;
- }
- if (strncmp(cp, "OT", 2) == 0) {
- sReqEngine = 'O';
- cp += 2;
- if (varString.length() > 0 && *(varString.end() - 1) != '/')
- varString.append("/");
- varString.append("OT");
- goto skip_to_slash;
- }
- if (strncmp(cp, "GR", 2) == 0) {
- sReqEngine = 'G';
- cp += 2;
- if (varString.length() > 0 && *(varString.end() - 1) != '/')
- varString.append("/");
- varString.append("GR");
- goto skip_to_slash;
- }
- if (*cp == 'S') {
- char* start = cp;
- ++cp;
- if (*cp == '=')
- ++cp;
- ptSize = 0.0;
- while (*cp >= '0' && *cp <= '9') {
- ptSize = ptSize * 10 + *cp - '0';
- ++cp;
- }
- if (*cp == '.') {
- double dec = 1.0;
- ++cp;
- while (*cp >= '0' && *cp <= '9') {
- dec = dec * 10.0;
- ptSize = ptSize + (*cp - '0') / dec;
- ++cp;
- }
- }
- goto skip_to_slash;
- }
-
- /* if the code is "B" or "I", we skip putting it in varString */
- while (1) {
- if (*cp == 'B') {
- reqBold = true;
- ++cp;
- continue;
- }
- if (*cp == 'I') {
- reqItal = true;
- ++cp;
- continue;
- }
- break;
- }
-
- skip_to_slash:
- while (*cp && *cp != '/')
- ++cp;
- if (*cp == '/')
- ++cp;
- }
- strcpy(variant, varString.c_str());
-
- std::map<std::string,Font*>::iterator i;
- if (reqItal) {
- Font* bestMatch = font;
- if (font->slant < parent->maxSlant)
- // try for a face with more slant
- bestMatch = bestMatchFromFamily(parent, font->weight, font->width, parent->maxSlant);
-
- if (bestMatch == font && font->slant > parent->minSlant)
- // maybe the slant is negated, or maybe this was something like "Times-Italic/I"
- bestMatch = bestMatchFromFamily(parent, font->weight, font->width, parent->minSlant);
-
- if (parent->minWeight == parent->maxWeight && bestMatch->isBold != font->isBold) {
- // try again using the bold flag, as we can't trust weight values
- Font* newBest = NULL;
- for (i = parent->styles->begin(); i != parent->styles->end(); ++i) {
- if (i->second->isBold == font->isBold) {
- if (newBest == NULL && i->second->isItalic != font->isItalic) {
- newBest = i->second;
- break;
- }
- }
- }
- if (newBest != NULL)
- bestMatch = newBest;
- }
-
- if (bestMatch == font) {
- // maybe slant values weren't present; try the style bits as a fallback
- bestMatch = NULL;
- for (i = parent->styles->begin(); i != parent->styles->end(); ++i)
- if (i->second->isItalic == !font->isItalic)
- if (parent->minWeight != parent->maxWeight) {
- // weight info was available, so try to match that
- if (bestMatch == NULL || weightAndWidthDiff(i->second, font) < weightAndWidthDiff(bestMatch, font))
- bestMatch = i->second;
- }
- else {
- // no weight info, so try matching style bits
- if (bestMatch == NULL && i->second->isBold == font->isBold) {
- bestMatch = i->second;
- break; // found a match, no need to look further as we can't distinguish!
- }
- }
- }
- if (bestMatch != NULL)
- font = bestMatch;
- }
-
- if (reqBold) {
- // try for more boldness, with the same width and slant
- Font* bestMatch = font;
- if (font->weight < parent->maxWeight) {
- // try to increase weight by 1/2 x (max - min), rounding up
- bestMatch = bestMatchFromFamily(parent,
- font->weight + (parent->maxWeight - parent->minWeight) / 2 + 1,
- font->width, font->slant);
- if (parent->minSlant == parent->maxSlant) {
- // double-check the italic flag, as we can't trust slant values
- Font* newBest = NULL;
- for (i = parent->styles->begin(); i != parent->styles->end(); ++i) {
- if (i->second->isItalic == font->isItalic) {
- if (newBest == NULL || weightAndWidthDiff(i->second, bestMatch) < weightAndWidthDiff(newBest, bestMatch))
- newBest = i->second;
- }
- }
- if (newBest != NULL)
- bestMatch = newBest;
- }
- }
- if (bestMatch == font && !font->isBold) {
- for (i = parent->styles->begin(); i != parent->styles->end(); ++i) {
- if (i->second->isItalic == font->isItalic && i->second->isBold) {
- bestMatch = i->second;
- break;
- }
- }
- }
- font = bestMatch;
- }
- }
-
- // if there's optical size info, try to apply it
- if (ptSize < 0.0)
- ptSize = dsize / 10.0;
- if (font != NULL && font->opSizeInfo.subFamilyID != 0 && ptSize > 0.0) {
- ptSize = ptSize * 10.0; // convert to decipoints for comparison with the opSize values
- double bestMismatch = my_fmax(font->opSizeInfo.minSize - ptSize, ptSize - font->opSizeInfo.maxSize);
- if (bestMismatch > 0.0) {
- Font* bestMatch = font;
- for (std::map<std::string,Font*>::iterator i = parent->styles->begin(); i != parent->styles->end(); ++i) {
- if (i->second->opSizeInfo.subFamilyID != font->opSizeInfo.subFamilyID)
- continue;
- double mismatch = my_fmax(i->second->opSizeInfo.minSize - ptSize, ptSize - i->second->opSizeInfo.maxSize);
- if (mismatch < bestMismatch) {
- bestMatch = i->second;
- bestMismatch = mismatch;
- }
- if (bestMismatch <= 0.0)
- break;
- }
- font = bestMatch;
- }
- }
-
- if (font != NULL && font->opSizeInfo.designSize != 0)
- loadedfontdesignsize = (font->opSizeInfo.designSize << 16L) / 10;
-
- if (gettracingfontsstate() > 0) {
- begindiagnostic();
- zprintnl(' ');
- printcstring("-> ");
- printcstring(getPlatformFontDesc(font->fontRef).c_str());
- zenddiagnostic(0);
- }
-
- return font->fontRef;
+ std::string nameStr(name);
+ Font* font = NULL;
+ int dsize = 100;
+ loadedfontdesignsize = 655360L;
+
+ for (int pass = 0; pass < 2; ++pass) {
+ // try full name as given
+ std::map<std::string,Font*>::iterator i = nameToFont.find(nameStr);
+ if (i != nameToFont.end()) {
+ font = i->second;
+ if (font->opSizeInfo.designSize != 0)
+ dsize = font->opSizeInfo.designSize;
+ break;
+ }
+
+ // if there's a hyphen, split there and try Family-Style
+ int hyph = nameStr.find('-');
+ if (hyph > 0 && hyph < nameStr.length() - 1) {
+ std::string family(nameStr.begin(), nameStr.begin() + hyph);
+ std::map<std::string,Family*>::iterator f = nameToFamily.find(family);
+ if (f != nameToFamily.end()) {
+ std::string style(nameStr.begin() + hyph + 1, nameStr.end());
+ i = f->second->styles->find(style);
+ if (i != f->second->styles->end()) {
+ font = i->second;
+ if (font->opSizeInfo.designSize != 0)
+ dsize = font->opSizeInfo.designSize;
+ break;
+ }
+ }
+ }
+
+ // try as PostScript name
+ i = psNameToFont.find(nameStr);
+ if (i != psNameToFont.end()) {
+ font = i->second;
+ if (font->opSizeInfo.designSize != 0)
+ dsize = font->opSizeInfo.designSize;
+ break;
+ }
+
+ // try for the name as a family name
+ std::map<std::string,Family*>::iterator f = nameToFamily.find(nameStr);
+
+ if (f != nameToFamily.end()) {
+ // look for a family member with the "regular" bit set in OS/2
+ int regFonts = 0;
+ for (i = f->second->styles->begin(); i != f->second->styles->end(); ++i)
+ if (i->second->isReg) {
+ if (regFonts == 0)
+ font = i->second;
+ ++regFonts;
+ }
+
+ // families with Ornament or similar fonts may flag those as Regular,
+ // which confuses the search above... so try some known names
+ if (font == NULL || regFonts > 1) {
+ // try for style "Regular", "Plain", "Normal", "Roman"
+ i = f->second->styles->find("Regular");
+ if (i != f->second->styles->end())
+ font = i->second;
+ else {
+ i = f->second->styles->find("Plain");
+ if (i != f->second->styles->end())
+ font = i->second;
+ else {
+ i = f->second->styles->find("Normal");
+ if (i != f->second->styles->end())
+ font = i->second;
+ else {
+ i = f->second->styles->find("Roman");
+ if (i != f->second->styles->end())
+ font = i->second;
+ }
+ }
+ }
+ }
+
+ if (font == NULL) {
+ // look through the family for the (weight, width, slant) nearest to (80, 100, 0)
+ font = bestMatchFromFamily(f->second, 80, 100, 0);
+ }
+
+ if (font != NULL)
+ break;
+ }
+
+ if (pass == 0) {
+ // didn't find it in our caches, so do a platform search (may be relatively expensive);
+ // this will update the caches with any fonts that seem to match the name given,
+ // so that the second pass might find it
+ searchForHostPlatformFonts(nameStr);
+ }
+ }
+
+ if (font == NULL)
+ return 0;
+
+ Family* parent = font->parent;
+
+ // if there are variant requests, try to apply them
+ // and delete B, I, and S=... codes from the string, just retain /engine option
+ sReqEngine = 0;
+ bool reqBold = false;
+ bool reqItal = false;
+ if (variant != NULL) {
+ std::string varString;
+ char* cp = variant;
+ while (*cp) {
+ if (strncmp(cp, "AAT", 3) == 0) {
+ sReqEngine = 'A';
+ cp += 3;
+ if (varString.length() > 0 && *(varString.end() - 1) != '/')
+ varString.append("/");
+ varString.append("AAT");
+ goto skip_to_slash;
+ }
+ if (strncmp(cp, "ICU", 3) == 0) { // for backword compatability
+ sReqEngine = 'O';
+ cp += 3;
+ if (varString.length() > 0 && *(varString.end() - 1) != '/')
+ varString.append("/");
+ varString.append("OT");
+ goto skip_to_slash;
+ }
+ if (strncmp(cp, "OT", 2) == 0) {
+ sReqEngine = 'O';
+ cp += 2;
+ if (varString.length() > 0 && *(varString.end() - 1) != '/')
+ varString.append("/");
+ varString.append("OT");
+ goto skip_to_slash;
+ }
+ if (strncmp(cp, "GR", 2) == 0) {
+ sReqEngine = 'G';
+ cp += 2;
+ if (varString.length() > 0 && *(varString.end() - 1) != '/')
+ varString.append("/");
+ varString.append("GR");
+ goto skip_to_slash;
+ }
+ if (*cp == 'S') {
+ char* start = cp;
+ ++cp;
+ if (*cp == '=')
+ ++cp;
+ ptSize = 0.0;
+ while (*cp >= '0' && *cp <= '9') {
+ ptSize = ptSize * 10 + *cp - '0';
+ ++cp;
+ }
+ if (*cp == '.') {
+ double dec = 1.0;
+ ++cp;
+ while (*cp >= '0' && *cp <= '9') {
+ dec = dec * 10.0;
+ ptSize = ptSize + (*cp - '0') / dec;
+ ++cp;
+ }
+ }
+ goto skip_to_slash;
+ }
+
+ /* if the code is "B" or "I", we skip putting it in varString */
+ while (1) {
+ if (*cp == 'B') {
+ reqBold = true;
+ ++cp;
+ continue;
+ }
+ if (*cp == 'I') {
+ reqItal = true;
+ ++cp;
+ continue;
+ }
+ break;
+ }
+
+ skip_to_slash:
+ while (*cp && *cp != '/')
+ ++cp;
+ if (*cp == '/')
+ ++cp;
+ }
+ strcpy(variant, varString.c_str());
+
+ std::map<std::string,Font*>::iterator i;
+ if (reqItal) {
+ Font* bestMatch = font;
+ if (font->slant < parent->maxSlant)
+ // try for a face with more slant
+ bestMatch = bestMatchFromFamily(parent, font->weight, font->width, parent->maxSlant);
+
+ if (bestMatch == font && font->slant > parent->minSlant)
+ // maybe the slant is negated, or maybe this was something like "Times-Italic/I"
+ bestMatch = bestMatchFromFamily(parent, font->weight, font->width, parent->minSlant);
+
+ if (parent->minWeight == parent->maxWeight && bestMatch->isBold != font->isBold) {
+ // try again using the bold flag, as we can't trust weight values
+ Font* newBest = NULL;
+ for (i = parent->styles->begin(); i != parent->styles->end(); ++i) {
+ if (i->second->isBold == font->isBold) {
+ if (newBest == NULL && i->second->isItalic != font->isItalic) {
+ newBest = i->second;
+ break;
+ }
+ }
+ }
+ if (newBest != NULL)
+ bestMatch = newBest;
+ }
+
+ if (bestMatch == font) {
+ // maybe slant values weren't present; try the style bits as a fallback
+ bestMatch = NULL;
+ for (i = parent->styles->begin(); i != parent->styles->end(); ++i) {
+ if (i->second->isItalic == !font->isItalic) {
+ if (parent->minWeight != parent->maxWeight) {
+ // weight info was available, so try to match that
+ if (bestMatch == NULL || weightAndWidthDiff(i->second, font) < weightAndWidthDiff(bestMatch, font))
+ bestMatch = i->second;
+ } else {
+ // no weight info, so try matching style bits
+ if (bestMatch == NULL && i->second->isBold == font->isBold) {
+ bestMatch = i->second;
+ break; // found a match, no need to look further as we can't distinguish!
+ }
+ }
+ }
+ }
+ }
+ if (bestMatch != NULL)
+ font = bestMatch;
+ }
+
+ if (reqBold) {
+ // try for more boldness, with the same width and slant
+ Font* bestMatch = font;
+ if (font->weight < parent->maxWeight) {
+ // try to increase weight by 1/2 x (max - min), rounding up
+ bestMatch = bestMatchFromFamily(parent,
+ font->weight + (parent->maxWeight - parent->minWeight) / 2 + 1,
+ font->width, font->slant);
+ if (parent->minSlant == parent->maxSlant) {
+ // double-check the italic flag, as we can't trust slant values
+ Font* newBest = NULL;
+ for (i = parent->styles->begin(); i != parent->styles->end(); ++i) {
+ if (i->second->isItalic == font->isItalic) {
+ if (newBest == NULL || weightAndWidthDiff(i->second, bestMatch) < weightAndWidthDiff(newBest, bestMatch))
+ newBest = i->second;
+ }
+ }
+ if (newBest != NULL)
+ bestMatch = newBest;
+ }
+ }
+ if (bestMatch == font && !font->isBold) {
+ for (i = parent->styles->begin(); i != parent->styles->end(); ++i) {
+ if (i->second->isItalic == font->isItalic && i->second->isBold) {
+ bestMatch = i->second;
+ break;
+ }
+ }
+ }
+ font = bestMatch;
+ }
+ }
+
+ // if there's optical size info, try to apply it
+ if (ptSize < 0.0)
+ ptSize = dsize / 10.0;
+ if (font != NULL && font->opSizeInfo.subFamilyID != 0 && ptSize > 0.0) {
+ ptSize = ptSize * 10.0; // convert to decipoints for comparison with the opSize values
+ double bestMismatch = my_fmax(font->opSizeInfo.minSize - ptSize, ptSize - font->opSizeInfo.maxSize);
+ if (bestMismatch > 0.0) {
+ Font* bestMatch = font;
+ for (std::map<std::string,Font*>::iterator i = parent->styles->begin(); i != parent->styles->end(); ++i) {
+ if (i->second->opSizeInfo.subFamilyID != font->opSizeInfo.subFamilyID)
+ continue;
+ double mismatch = my_fmax(i->second->opSizeInfo.minSize - ptSize, ptSize - i->second->opSizeInfo.maxSize);
+ if (mismatch < bestMismatch) {
+ bestMatch = i->second;
+ bestMismatch = mismatch;
+ }
+ if (bestMismatch <= 0.0)
+ break;
+ }
+ font = bestMatch;
+ }
+ }
+
+ if (font != NULL && font->opSizeInfo.designSize != 0)
+ loadedfontdesignsize = (font->opSizeInfo.designSize << 16L) / 10;
+
+ if (gettracingfontsstate() > 0) {
+ begindiagnostic();
+ zprintnl(' ');
+ printcstring("-> ");
+ printcstring(getPlatformFontDesc(font->fontRef).c_str());
+ zenddiagnostic(0);
+ }
+
+ return font->fontRef;
}
const char*
XeTeXFontMgr::getFullName(PlatformFontRef font) const
{
- std::map<PlatformFontRef,Font*>::const_iterator i = platformRefToFont.find(font);
- if (i == platformRefToFont.end())
- die("internal error %d in XeTeXFontMgr", 2);
- if (i->second->fullName != NULL)
- return i->second->fullName->c_str();
- else
- return i->second->psName->c_str();
+ std::map<PlatformFontRef,Font*>::const_iterator i = platformRefToFont.find(font);
+ if (i == platformRefToFont.end())
+ die("internal error %d in XeTeXFontMgr", 2);
+ if (i->second->fullName != NULL)
+ return i->second->fullName->c_str();
+ else
+ return i->second->psName->c_str();
}
void
XeTeXFontMgr::getNames(PlatformFontRef font, const char** psName,
- const char** famName, const char** styName) const
+ const char** famName, const char** styName) const
{
- std::map<PlatformFontRef,Font*>::const_iterator i = platformRefToFont.find(font);
- if (i == platformRefToFont.end())
- die("internal error %d in XeTeXFontMgr", 3);
- *psName = i->second->psName->c_str();
- *famName = i->second->familyName->c_str();
- *styName = i->second->styleName->c_str();
+ std::map<PlatformFontRef,Font*>::const_iterator i = platformRefToFont.find(font);
+ if (i == platformRefToFont.end())
+ die("internal error %d in XeTeXFontMgr", 3);
+ *psName = xstrdup(i->second->psName->c_str());
+ *famName = xstrdup(i->second->familyName->c_str());
+ *styName = xstrdup(i->second->styleName->c_str());
}
int
XeTeXFontMgr::weightAndWidthDiff(const Font* a, const Font* b) const
{
- if (a->weight == 0 && a->width == 0) {
- // assume there was no OS/2 info
- if (a->isBold == b->isBold)
- return 0;
- else
- return 10000;
- }
-
- int widDiff = labs(a->width - b->width);
- if (widDiff < 10)
- widDiff *= 50;
-
- return labs(a->weight - b->weight) + widDiff;
+ if (a->weight == 0 && a->width == 0) {
+ // assume there was no OS/2 info
+ if (a->isBold == b->isBold)
+ return 0;
+ else
+ return 10000;
+ }
+
+ int widDiff = labs(a->width - b->width);
+ if (widDiff < 10)
+ widDiff *= 50;
+
+ return labs(a->weight - b->weight) + widDiff;
}
int
XeTeXFontMgr::styleDiff(const Font* a, int wt, int wd, int slant) const
{
- int widDiff = labs(a->width - wd);
- if (widDiff < 10)
- widDiff *= 200;
-
- return labs(labs(a->slant) - labs(slant)) * 2 + labs(a->weight - wt) + widDiff;
+ int widDiff = labs(a->width - wd);
+ if (widDiff < 10)
+ widDiff *= 200;
+
+ return labs(labs(a->slant) - labs(slant)) * 2 + labs(a->weight - wt) + widDiff;
}
XeTeXFontMgr::Font*
XeTeXFontMgr::bestMatchFromFamily(const Family* fam, int wt, int wd, int slant) const
{
- Font* bestMatch = NULL;
- for (std::map<std::string,Font*>::iterator s = fam->styles->begin(); s != fam->styles->end(); ++s)
- if (bestMatch == NULL || styleDiff(s->second, wt, wd, slant) < styleDiff(bestMatch, wt, wd, slant))
- bestMatch = s->second;
- return bestMatch;
+ Font* bestMatch = NULL;
+ for (std::map<std::string,Font*>::iterator s = fam->styles->begin(); s != fam->styles->end(); ++s)
+ if (bestMatch == NULL || styleDiff(s->second, wt, wd, slant) < styleDiff(bestMatch, wt, wd, slant))
+ bestMatch = s->second;
+ return bestMatch;
}
const XeTeXFontMgr::OpSizeRec*
XeTeXFontMgr::getOpSize(XeTeXFont font)
{
- hb_font_t* hbFont = ((XeTeXFontInst*)font)->getHbFont();
- if (hbFont != NULL) {
- hb_face_t* face = hb_font_get_face(hbFont);
- OpSizeRec* pSizeRec = (OpSizeRec*) xmalloc(sizeof(OpSizeRec));
-
- bool ok = hb_ot_layout_get_size_params(face,
- &pSizeRec->designSize,
- &pSizeRec->subFamilyID,
- &pSizeRec->nameCode,
- &pSizeRec->minSize,
- &pSizeRec->maxSize);
-
- if (ok)
- return pSizeRec;
-
- free(pSizeRec);
- return NULL;
- }
-
- return NULL;
+ hb_font_t* hbFont = ((XeTeXFontInst*)font)->getHbFont();
+ if (hbFont != NULL) {
+ hb_face_t* face = hb_font_get_face(hbFont);
+ OpSizeRec* pSizeRec = (OpSizeRec*) xmalloc(sizeof(OpSizeRec));
+
+ bool ok = hb_ot_layout_get_size_params(face,
+ &pSizeRec->designSize,
+ &pSizeRec->subFamilyID,
+ &pSizeRec->nameCode,
+ &pSizeRec->minSize,
+ &pSizeRec->maxSize);
+
+ if (ok)
+ return pSizeRec;
+
+ free(pSizeRec);
+ return NULL;
+ }
+
+ return NULL;
}
double
XeTeXFontMgr::getDesignSize(XeTeXFont font)
{
- const OpSizeRec* pSizeRec = getOpSize(font);
- if (pSizeRec != NULL)
- return pSizeRec->designSize / 10.0;
- else
- return 10.0;
+ const OpSizeRec* pSizeRec = getOpSize(font);
+ if (pSizeRec != NULL)
+ return pSizeRec->designSize / 10.0;
+ else
+ return 10.0;
}
void
XeTeXFontMgr::getOpSizeRecAndStyleFlags(Font* theFont)
{
- XeTeXFont font = createFont(theFont->fontRef, 655360);
- XeTeXFontInst* fontInst = (XeTeXFontInst*) font;
- if (font != 0) {
- const OpSizeRec* pSizeRec = getOpSize(font);
- if (pSizeRec != NULL) {
- theFont->opSizeInfo.designSize = pSizeRec->designSize;
- if (pSizeRec->subFamilyID == 0
- && pSizeRec->nameCode == 0
- && pSizeRec->minSize == 0
- && pSizeRec->maxSize == 0)
- goto done_size; // feature is valid, but no 'size' range
- theFont->opSizeInfo.subFamilyID = pSizeRec->subFamilyID;
- theFont->opSizeInfo.nameCode = pSizeRec->nameCode;
- theFont->opSizeInfo.minSize = pSizeRec->minSize;
- theFont->opSizeInfo.maxSize = pSizeRec->maxSize;
- }
- done_size:
-
- const TT_OS2* os2Table = (TT_OS2*) fontInst->getFontTable(ft_sfnt_os2);
- if (os2Table != NULL) {
- theFont->weight = os2Table->usWeightClass;
- theFont->width = os2Table->usWidthClass;
- uint16_t sel = os2Table->fsSelection;
- theFont->isReg = (sel & (1 << 6)) != 0;
- theFont->isBold = (sel & (1 << 5)) != 0;
- theFont->isItalic = (sel & (1 << 0)) != 0;
- }
-
- const TT_Header* headTable = (TT_Header*) fontInst->getFontTable(ft_sfnt_head);
- if (headTable != NULL) {
- uint16_t ms = headTable->Mac_Style;
- if ((ms & (1 << 0)) != 0)
- theFont->isBold = true;
- if ((ms & (1 << 1)) != 0)
- theFont->isItalic = true;
- }
-
- const TT_Postscript* postTable = (const TT_Postscript*) fontInst->getFontTable(ft_sfnt_post);
- if (postTable != NULL) {
- theFont->slant = (int)(1000 * (tan(Fix2D(-postTable->italicAngle) * M_PI / 180.0)));
- }
- deleteFont(font);
- }
+ XeTeXFont font = createFont(theFont->fontRef, 655360);
+ XeTeXFontInst* fontInst = (XeTeXFontInst*) font;
+ if (font != 0) {
+ const OpSizeRec* pSizeRec = getOpSize(font);
+ if (pSizeRec != NULL) {
+ theFont->opSizeInfo.designSize = pSizeRec->designSize;
+ if (pSizeRec->subFamilyID == 0
+ && pSizeRec->nameCode == 0
+ && pSizeRec->minSize == 0
+ && pSizeRec->maxSize == 0)
+ goto done_size; // feature is valid, but no 'size' range
+ theFont->opSizeInfo.subFamilyID = pSizeRec->subFamilyID;
+ theFont->opSizeInfo.nameCode = pSizeRec->nameCode;
+ theFont->opSizeInfo.minSize = pSizeRec->minSize;
+ theFont->opSizeInfo.maxSize = pSizeRec->maxSize;
+ }
+ done_size:
+
+ const TT_OS2* os2Table = (TT_OS2*) fontInst->getFontTable(ft_sfnt_os2);
+ if (os2Table != NULL) {
+ theFont->weight = os2Table->usWeightClass;
+ theFont->width = os2Table->usWidthClass;
+ uint16_t sel = os2Table->fsSelection;
+ theFont->isReg = (sel & (1 << 6)) != 0;
+ theFont->isBold = (sel & (1 << 5)) != 0;
+ theFont->isItalic = (sel & (1 << 0)) != 0;
+ }
+
+ const TT_Header* headTable = (TT_Header*) fontInst->getFontTable(ft_sfnt_head);
+ if (headTable != NULL) {
+ uint16_t ms = headTable->Mac_Style;
+ if ((ms & (1 << 0)) != 0)
+ theFont->isBold = true;
+ if ((ms & (1 << 1)) != 0)
+ theFont->isItalic = true;
+ }
+
+ const TT_Postscript* postTable = (const TT_Postscript*) fontInst->getFontTable(ft_sfnt_post);
+ if (postTable != NULL) {
+ theFont->slant = (int)(1000 * (tan(Fix2D(-postTable->italicAngle) * M_PI / 180.0)));
+ }
+ deleteFont(font);
+ }
}
// append a name but only if it's not already in the list
void
XeTeXFontMgr::appendToList(std::list<std::string>* list, const char* str)
{
- for (std::list<std::string>::const_iterator i = list->begin(); i != list->end(); ++i)
- if (*i == str)
- return;
- list->push_back(str);
+ for (std::list<std::string>::const_iterator i = list->begin(); i != list->end(); ++i)
+ if (*i == str)
+ return;
+ list->push_back(str);
}
// prepend a name, removing it from later in the list if present
void
XeTeXFontMgr::prependToList(std::list<std::string>* list, const char* str)
{
- for (std::list<std::string>::iterator i = list->begin(); i != list->end(); ++i)
- if (*i == str) {
- list->erase(i);
- break;
- }
- list->push_front(str);
+ for (std::list<std::string>::iterator i = list->begin(); i != list->end(); ++i)
+ if (*i == str) {
+ list->erase(i);
+ break;
+ }
+ list->push_front(str);
}
void
XeTeXFontMgr::addToMaps(PlatformFontRef platformFont, const NameCollection* names)
{
- if (platformRefToFont.find(platformFont) != platformRefToFont.end())
- return; // this font has already been cached
-
- if (names->psName.length() == 0)
- return; // can't use a font that lacks a PostScript name
-
- if (psNameToFont.find(names->psName) != psNameToFont.end())
- return; // duplicates an earlier PS name, so skip
-
- Font* thisFont = new Font(platformFont);
- thisFont->psName = new std::string(names->psName);
- getOpSizeRecAndStyleFlags(thisFont);
-
- psNameToFont[names->psName] = thisFont;
- platformRefToFont[platformFont] = thisFont;
-
- if (names->fullNames.size() > 0)
- thisFont->fullName = new std::string(*(names->fullNames.begin()));
-
- if (names->familyNames.size() > 0)
- thisFont->familyName = new std::string(*(names->familyNames.begin()));
- else
- thisFont->familyName = new std::string(names->psName);
-
- if (names->styleNames.size() > 0)
- thisFont->styleName = new std::string(*(names->styleNames.begin()));
- else
- thisFont->styleName = new std::string;
-
- std::list<std::string>::const_iterator i;
- for (i = names->familyNames.begin(); i != names->familyNames.end(); ++i) {
- std::map<std::string,Family*>::iterator iFam = nameToFamily.find(*i);
- Family* family;
- if (iFam == nameToFamily.end()) {
- family = new Family;
- nameToFamily[*i] = family;
- family->minWeight = thisFont->weight;
- family->maxWeight = thisFont->weight;
- family->minWidth = thisFont->width;
- family->maxWidth = thisFont->width;
- family->minSlant = thisFont->slant;
- family->maxSlant = thisFont->slant;
- } else {
- family = iFam->second;
- if (thisFont->weight < family->minWeight)
- family->minWeight = thisFont->weight;
- if (thisFont->weight > family->maxWeight)
- family->maxWeight = thisFont->weight;
- if (thisFont->width < family->minWidth)
- family->minWidth = thisFont->width;
- if (thisFont->width > family->maxWidth)
- family->maxWidth = thisFont->width;
- if (thisFont->slant < family->minSlant)
- family->minSlant = thisFont->slant;
- if (thisFont->slant > family->maxSlant)
- family->maxSlant = thisFont->slant;
- }
-
- if (thisFont->parent == NULL)
- thisFont->parent = family;
-
- // ensure all style names in the family point to thisFont
- for (std::list<std::string>::const_iterator j = names->styleNames.begin(); j != names->styleNames.end(); ++j) {
- std::map<std::string,Font*>::iterator iFont = family->styles->find(*j);
- if (iFont == family->styles->end())
- (*family->styles)[*j] = thisFont;
+ if (platformRefToFont.find(platformFont) != platformRefToFont.end())
+ return; // this font has already been cached
+
+ if (names->psName.length() == 0)
+ return; // can't use a font that lacks a PostScript name
+
+ if (psNameToFont.find(names->psName) != psNameToFont.end())
+ return; // duplicates an earlier PS name, so skip
+
+ Font* thisFont = new Font(platformFont);
+ thisFont->psName = new std::string(names->psName);
+ getOpSizeRecAndStyleFlags(thisFont);
+
+ psNameToFont[names->psName] = thisFont;
+ platformRefToFont[platformFont] = thisFont;
+
+ if (names->fullNames.size() > 0)
+ thisFont->fullName = new std::string(*(names->fullNames.begin()));
+
+ if (names->familyNames.size() > 0)
+ thisFont->familyName = new std::string(*(names->familyNames.begin()));
+ else
+ thisFont->familyName = new std::string(names->psName);
+
+ if (names->styleNames.size() > 0)
+ thisFont->styleName = new std::string(*(names->styleNames.begin()));
+ else
+ thisFont->styleName = new std::string;
+
+ std::list<std::string>::const_iterator i;
+ for (i = names->familyNames.begin(); i != names->familyNames.end(); ++i) {
+ std::map<std::string,Family*>::iterator iFam = nameToFamily.find(*i);
+ Family* family;
+ if (iFam == nameToFamily.end()) {
+ family = new Family;
+ nameToFamily[*i] = family;
+ family->minWeight = thisFont->weight;
+ family->maxWeight = thisFont->weight;
+ family->minWidth = thisFont->width;
+ family->maxWidth = thisFont->width;
+ family->minSlant = thisFont->slant;
+ family->maxSlant = thisFont->slant;
+ } else {
+ family = iFam->second;
+ if (thisFont->weight < family->minWeight)
+ family->minWeight = thisFont->weight;
+ if (thisFont->weight > family->maxWeight)
+ family->maxWeight = thisFont->weight;
+ if (thisFont->width < family->minWidth)
+ family->minWidth = thisFont->width;
+ if (thisFont->width > family->maxWidth)
+ family->maxWidth = thisFont->width;
+ if (thisFont->slant < family->minSlant)
+ family->minSlant = thisFont->slant;
+ if (thisFont->slant > family->maxSlant)
+ family->maxSlant = thisFont->slant;
+ }
+
+ if (thisFont->parent == NULL)
+ thisFont->parent = family;
+
+ // ensure all style names in the family point to thisFont
+ for (std::list<std::string>::const_iterator j = names->styleNames.begin(); j != names->styleNames.end(); ++j) {
+ std::map<std::string,Font*>::iterator iFont = family->styles->find(*j);
+ if (iFont == family->styles->end())
+ (*family->styles)[*j] = thisFont;
/*
- else if (iFont->second != thisFont)
- fprintf(stderr, "# Font name warning: ambiguous Style \"%s\" in Family \"%s\" (PSNames \"%s\" and \"%s\")\n",
- j->c_str(), i->c_str(), iFont->second->psName->c_str(), thisFont->psName->c_str());
+ else if (iFont->second != thisFont)
+ fprintf(stderr, "# Font name warning: ambiguous Style \"%s\" in Family \"%s\" (PSNames \"%s\" and \"%s\")\n",
+ j->c_str(), i->c_str(), iFont->second->psName->c_str(), thisFont->psName->c_str());
*/
- }
- }
-
- for (i = names->fullNames.begin(); i != names->fullNames.end(); ++i) {
- std::map<std::string,Font*>::iterator iFont = nameToFont.find(*i);
- if (iFont == nameToFont.end())
- nameToFont[*i] = thisFont;
+ }
+ }
+
+ for (i = names->fullNames.begin(); i != names->fullNames.end(); ++i) {
+ std::map<std::string,Font*>::iterator iFont = nameToFont.find(*i);
+ if (iFont == nameToFont.end())
+ nameToFont[*i] = thisFont;
/*
- else if (iFont->second != thisFont)
- fprintf(stderr, "# Font name warning: ambiguous FullName \"%s\" (PSNames \"%s\" and \"%s\")\n",
- i->c_str(), iFont->second->psName->c_str(), thisFont->psName->c_str());
+ else if (iFont->second != thisFont)
+ fprintf(stderr, "# Font name warning: ambiguous FullName \"%s\" (PSNames \"%s\" and \"%s\")\n",
+ i->c_str(), iFont->second->psName->c_str(), thisFont->psName->c_str());
*/
- }
+ }
}
void
XeTeXFontMgr::die(const char*s, int i) const
{
- fprintf(stderr, s, i);
- fprintf(stderr, " - exiting\n");
- exit(3);
+ fprintf(stderr, s, i);
+ fprintf(stderr, " - exiting\n");
+ exit(3);
}
void
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h
index 599fbe97d47..1535eff9db3 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr.h
@@ -41,14 +41,14 @@ typedef CTFontDescriptorRef PlatformFontRef;
#include <fontconfig/fontconfig.h>
#include <ft2build.h>
#include FT_FREETYPE_H
-typedef FcPattern* PlatformFontRef;
+typedef FcPattern* PlatformFontRef;
#endif
#include "XeTeX_ext.h"
#include "XeTeXLayoutInterface.h"
-#ifdef __cplusplus /* allow inclusion in plain C files just to get the typedefs above */
+#ifdef __cplusplus /* allow inclusion in plain C files just to get the typedefs above */
#include <string>
#include <map>
@@ -58,151 +58,151 @@ typedef FcPattern* PlatformFontRef;
class XeTeXFontMgr
{
public:
- static XeTeXFontMgr* GetFontManager();
- // returns the global fontmanager (creating it if necessary)
- static void Terminate();
- // clean up (may be required if using the cocoa implementation)
+ static XeTeXFontMgr* GetFontManager();
+ // returns the global fontmanager (creating it if necessary)
+ static void Terminate();
+ // clean up (may be required if using the cocoa implementation)
- PlatformFontRef findFont(const char* name, char* variant, double ptSize);
- // 1st arg is name as specified by user (C string, UTF-8)
- // 2nd is /B/I/AAT/OT/ICU/GR/S=## qualifiers
- // 1. try name given as "full name"
- // 2. if there's a hyphen, split and try "family-style"
- // 3. try as PostScript name
- // 4. try name as family with "Regular/Plain/Normal" style
- // apply style qualifiers and optical sizing if present
+ PlatformFontRef findFont(const char* name, char* variant, double ptSize);
+ // 1st arg is name as specified by user (C string, UTF-8)
+ // 2nd is /B/I/AAT/OT/ICU/GR/S=## qualifiers
+ // 1. try name given as "full name"
+ // 2. if there's a hyphen, split and try "family-style"
+ // 3. try as PostScript name
+ // 4. try name as family with "Regular/Plain/Normal" style
+ // apply style qualifiers and optical sizing if present
- // SIDE EFFECT: sets sReqEngine to 'A' or 'O' or 'G' if appropriate,
- // else clears it to 0
+ // SIDE EFFECT: sets sReqEngine to 'A' or 'O' or 'G' if appropriate,
+ // else clears it to 0
- // SIDE EFFECT: updates TeX variables /nameoffile/ and /namelength/,
- // to match the actual font found
+ // SIDE EFFECT: updates TeX variables /nameoffile/ and /namelength/,
+ // to match the actual font found
- // SIDE EFFECT: edits /variant/ string in-place removing /B or /I
-
- const char* getFullName(PlatformFontRef font) const;
- // return the full name of the font, suitable for use in XeTeX source
- // without requiring style qualifiers
+ // SIDE EFFECT: edits /variant/ string in-place removing /B or /I
- void getNames(PlatformFontRef font, const char** psName,
- const char** famName, const char** styName) const;
- // return Postscript, family, and style names, for use in .xdv
+ const char* getFullName(PlatformFontRef font) const;
+ // return the full name of the font, suitable for use in XeTeX source
+ // without requiring style qualifiers
- double getDesignSize(XeTeXFont font);
+ void getNames(PlatformFontRef font, const char** psName,
+ const char** famName, const char** styName) const;
+ // return Postscript, family, and style names, for use in .xdv
- char getReqEngine() const { return sReqEngine; };
- // return the requested rendering technology for the most recent findFont
- // or 0 if no specific technology was requested
+ double getDesignSize(XeTeXFont font);
- void setReqEngine(char reqEngine) const { sReqEngine = reqEngine; };
+ char getReqEngine() const { return sReqEngine; };
+ // return the requested rendering technology for the most recent findFont
+ // or 0 if no specific technology was requested
+
+ void setReqEngine(char reqEngine) const { sReqEngine = reqEngine; };
protected:
- static XeTeXFontMgr* sFontManager;
- static char sReqEngine;
-
- XeTeXFontMgr()
- { }
- virtual ~XeTeXFontMgr()
- { }
-
- virtual void initialize() = 0;
- virtual void terminate();
-
- virtual std::string getPlatformFontDesc(PlatformFontRef font) const = 0;
-
- class Font;
- class Family;
-
- struct OpSizeRec {
- unsigned int designSize;
- unsigned int subFamilyID;
- unsigned int nameCode;
- unsigned int minSize;
- unsigned int maxSize;
- };
-
- class Font {
- public:
- Font(PlatformFontRef ref)
- : fullName(NULL), psName(NULL), familyName(NULL), styleName(NULL)
- , parent(NULL)
- , fontRef(ref), weight(0), width(0), slant(0)
- , isReg(false), isBold(false), isItalic(false)
- { opSizeInfo.subFamilyID = 0;
- opSizeInfo.designSize = 100; } /* default to 10bp */
- ~Font()
- { delete fullName; delete psName; }
-
- std::string* fullName;
- std::string* psName;
- std::string* familyName; // default family and style names that should locate this font
- std::string* styleName;
- Family* parent;
- PlatformFontRef fontRef;
- OpSizeRec opSizeInfo;
- uint16_t weight;
- uint16_t width;
- int16_t slant;
- bool isReg;
- bool isBold;
- bool isItalic;
- };
-
- class Family {
- public:
- Family()
- : minWeight(0), maxWeight(0)
- , minWidth(0), maxWidth(0)
- , minSlant(0), maxSlant(0)
- {
- styles = new std::map<std::string,Font*>;
- }
- ~Family()
- {
- delete styles;
- }
-
- std::map<std::string,Font*>* styles;
- uint16_t minWeight;
- uint16_t maxWeight;
- uint16_t minWidth;
- uint16_t maxWidth;
- int16_t minSlant;
- int16_t maxSlant;
- };
-
- class NameCollection {
- public:
- std::list<std::string> familyNames;
- std::list<std::string> styleNames;
- std::list<std::string> fullNames;
- std::string psName;
- std::string subFamily;
- };
-
- std::map<std::string,Font*> nameToFont; // maps full name (as used in TeX source) to font record
- std::map<std::string,Family*> nameToFamily;
- std::map<PlatformFontRef,Font*> platformRefToFont;
- std::map<std::string,Font*> psNameToFont; // maps PS name (as used in .xdv) to font record
-
- int weightAndWidthDiff(const Font* a, const Font* b) const;
- int styleDiff(const Font* a, int wt, int wd, int slant) const;
- Font* bestMatchFromFamily(const Family* fam, int wt, int wd, int slant) const;
- void appendToList(std::list<std::string>* list, const char* str);
- void prependToList(std::list<std::string>* list, const char* str);
- void addToMaps(PlatformFontRef platformFont, const NameCollection* names);
-
- const OpSizeRec* getOpSize(XeTeXFont font);
-
- virtual void getOpSizeRecAndStyleFlags(Font* theFont);
- virtual void searchForHostPlatformFonts(const std::string& name) = 0;
-
- virtual NameCollection* readNames(PlatformFontRef fontRef) = 0;
-
- void die(const char*s, int i) const; /* for fatal internal errors! */
+ static XeTeXFontMgr* sFontManager;
+ static char sReqEngine;
+
+ XeTeXFontMgr()
+ { }
+ virtual ~XeTeXFontMgr()
+ { }
+
+ virtual void initialize() = 0;
+ virtual void terminate();
+
+ virtual std::string getPlatformFontDesc(PlatformFontRef font) const = 0;
+
+ class Font;
+ class Family;
+
+ struct OpSizeRec {
+ unsigned int designSize;
+ unsigned int subFamilyID;
+ unsigned int nameCode;
+ unsigned int minSize;
+ unsigned int maxSize;
+ };
+
+ class Font {
+ public:
+ Font(PlatformFontRef ref)
+ : fullName(NULL), psName(NULL), familyName(NULL), styleName(NULL)
+ , parent(NULL)
+ , fontRef(ref), weight(0), width(0), slant(0)
+ , isReg(false), isBold(false), isItalic(false)
+ { opSizeInfo.subFamilyID = 0;
+ opSizeInfo.designSize = 100; } /* default to 10bp */
+ ~Font()
+ { delete fullName; delete psName; }
+
+ std::string* fullName;
+ std::string* psName;
+ std::string* familyName; // default family and style names that should locate this font
+ std::string* styleName;
+ Family* parent;
+ PlatformFontRef fontRef;
+ OpSizeRec opSizeInfo;
+ uint16_t weight;
+ uint16_t width;
+ int16_t slant;
+ bool isReg;
+ bool isBold;
+ bool isItalic;
+ };
+
+ class Family {
+ public:
+ Family()
+ : minWeight(0), maxWeight(0)
+ , minWidth(0), maxWidth(0)
+ , minSlant(0), maxSlant(0)
+ {
+ styles = new std::map<std::string,Font*>;
+ }
+ ~Family()
+ {
+ delete styles;
+ }
+
+ std::map<std::string,Font*>* styles;
+ uint16_t minWeight;
+ uint16_t maxWeight;
+ uint16_t minWidth;
+ uint16_t maxWidth;
+ int16_t minSlant;
+ int16_t maxSlant;
+ };
+
+ class NameCollection {
+ public:
+ std::list<std::string> familyNames;
+ std::list<std::string> styleNames;
+ std::list<std::string> fullNames;
+ std::string psName;
+ std::string subFamily;
+ };
+
+ std::map<std::string,Font*> nameToFont; // maps full name (as used in TeX source) to font record
+ std::map<std::string,Family*> nameToFamily;
+ std::map<PlatformFontRef,Font*> platformRefToFont;
+ std::map<std::string,Font*> psNameToFont; // maps PS name (as used in .xdv) to font record
+
+ int weightAndWidthDiff(const Font* a, const Font* b) const;
+ int styleDiff(const Font* a, int wt, int wd, int slant) const;
+ Font* bestMatchFromFamily(const Family* fam, int wt, int wd, int slant) const;
+ void appendToList(std::list<std::string>* list, const char* str);
+ void prependToList(std::list<std::string>* list, const char* str);
+ void addToMaps(PlatformFontRef platformFont, const NameCollection* names);
+
+ const OpSizeRec* getOpSize(XeTeXFont font);
+
+ virtual void getOpSizeRecAndStyleFlags(Font* theFont);
+ virtual void searchForHostPlatformFonts(const std::string& name) = 0;
+
+ virtual NameCollection* readNames(PlatformFontRef fontRef) = 0;
+
+ void die(const char*s, int i) const; /* for fatal internal errors! */
};
-#endif /* __cplusplus */
+#endif /* __cplusplus */
-#endif /* __XETEX_FONT_MANAGER_H */
+#endif /* __XETEX_FONT_MANAGER_H */
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp
index f7c64d16f4b..f7253f1faa3 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp
@@ -50,318 +50,320 @@ extern "C" {
#include <unicode/ucnv.h>
-#define kFontFamilyName 1
-#define kFontStyleName 2
-#define kFontFullName 4
-#define kPreferredFamilyName 16
-#define kPreferredSubfamilyName 17
+#define kFontFamilyName 1
+#define kFontStyleName 2
+#define kFontFullName 4
+#define kPreferredFamilyName 16
+#define kPreferredSubfamilyName 17
-static UConverter* macRomanConv = NULL;
-static UConverter* utf16beConv = NULL;
-static UConverter* utf8Conv = NULL;
+static UConverter* macRomanConv = NULL;
+static UConverter* utf16beConv = NULL;
+static UConverter* utf8Conv = NULL;
static char*
convertToUtf8(UConverter* conv, const unsigned char* name, int len)
{
- char* buffer1 = NULL;
- char* buffer2 = NULL;
- int bufSize = -1;
-
- if (2 * (len + 1) > bufSize) {
- if (buffer1 != NULL) {
- delete[] buffer1;
- delete[] buffer2;
- }
- bufSize = 2 * len + 100;
- buffer1 = new char[bufSize];
- buffer2 = new char[bufSize];
- }
-
- UErrorCode status = U_ZERO_ERROR;
- len = ucnv_toUChars(conv, (UChar*)buffer1, bufSize, (const char*)name, len, &status);
- len = ucnv_fromUChars(utf8Conv, buffer2, bufSize, (UChar*)buffer1, len, &status);
- buffer2[len] = 0;
-
- return buffer2;
+ char* buffer1 = NULL;
+ char* buffer2 = NULL;
+ int bufSize = -1;
+
+ if (2 * (len + 1) > bufSize) {
+ if (buffer1 != NULL) {
+ delete[] buffer1;
+ delete[] buffer2;
+ }
+ bufSize = 2 * len + 100;
+ buffer1 = new char[bufSize];
+ buffer2 = new char[bufSize];
+ }
+
+ UErrorCode status = U_ZERO_ERROR;
+ len = ucnv_toUChars(conv, (UChar*)buffer1, bufSize, (const char*)name, len, &status);
+ len = ucnv_fromUChars(utf8Conv, buffer2, bufSize, (UChar*)buffer1, len, &status);
+ buffer2[len] = 0;
+
+ delete[] buffer1;
+ return buffer2;
}
XeTeXFontMgr::NameCollection*
XeTeXFontMgr_FC::readNames(FcPattern* pat)
{
- NameCollection* names = new NameCollection;
-
- char* pathname;
- if (FcPatternGetString(pat, FC_FILE, 0, (FcChar8**)&pathname) != FcResultMatch)
- return names;
- int index;
- if (FcPatternGetInteger(pat, FC_INDEX, 0, &index) != FcResultMatch)
- return names;
-
- FT_Face face;
- if (FT_New_Face(gFreeTypeLibrary, pathname, index, &face) != 0)
- return names;
-
- const char* name = FT_Get_Postscript_Name(face);
- if (name == NULL)
- return names;
- names->psName = name;
-
- // for sfnt containers, we'll read the name table ourselves, not rely on Fontconfig
- if (FT_IS_SFNT(face)) {
- std::list<std::string> familyNames;
- std::list<std::string> subFamilyNames;
- FT_SfntName nameRec;
- for (index = 0; index < FT_Get_Sfnt_Name_Count(face); ++index) {
- char* utf8name = NULL;
- if (FT_Get_Sfnt_Name(face, index, &nameRec) != 0)
- continue;
- switch (nameRec.name_id) {
- case kFontFullName:
- case kFontFamilyName:
- case kFontStyleName:
- case kPreferredFamilyName:
- case kPreferredSubfamilyName:
- {
- bool preferredName = false;
- if (nameRec.platform_id == TT_PLATFORM_MACINTOSH
- && nameRec.encoding_id == TT_MAC_ID_ROMAN && nameRec.language_id == 0) {
- utf8name = convertToUtf8(macRomanConv, nameRec.string, nameRec.string_len);
- preferredName = true;
- }
- else if ((nameRec.platform_id == TT_PLATFORM_APPLE_UNICODE)
- || (nameRec.platform_id == TT_PLATFORM_MICROSOFT))
- utf8name = convertToUtf8(utf16beConv, nameRec.string, nameRec.string_len);
-
- if (utf8name != NULL) {
- std::list<std::string>* nameList = NULL;
- switch (nameRec.name_id) {
- case kFontFullName:
- nameList = &names->fullNames;
- break;
- case kFontFamilyName:
- nameList = &names->familyNames;
- break;
- case kFontStyleName:
- nameList = &names->styleNames;
- break;
- case kPreferredFamilyName:
- nameList = &familyNames;
- break;
- case kPreferredSubfamilyName:
- nameList = &subFamilyNames;
- break;
- }
- if (preferredName)
- prependToList(nameList, utf8name);
- else
- appendToList(nameList, utf8name);
- }
- }
- break;
- }
- }
- if (familyNames.size() > 0)
- names->familyNames = familyNames;
- if (subFamilyNames.size() > 0)
- names->styleNames = subFamilyNames;
- } else {
- index = 0;
- while (FcPatternGetString(pat, FC_FULLNAME, index++, (FcChar8**)&name) == FcResultMatch)
- appendToList(&names->fullNames, name);
- index = 0;
- while (FcPatternGetString(pat, FC_FAMILY, index++, (FcChar8**)&name) == FcResultMatch)
- appendToList(&names->familyNames, name);
- index = 0;
- while (FcPatternGetString(pat, FC_STYLE, index++, (FcChar8**)&name) == FcResultMatch)
- appendToList(&names->styleNames, name);
-
- if (names->fullNames.size() == 0) {
- std::string fullName(names->familyNames.front());
- if (names->styleNames.size() > 0) {
- fullName += " ";
- fullName += names->styleNames.front();
- }
- names->fullNames.push_back(fullName);
- }
- }
-
- FT_Done_Face(face);
-
- return names;
+ NameCollection* names = new NameCollection;
+
+ char* pathname;
+ if (FcPatternGetString(pat, FC_FILE, 0, (FcChar8**)&pathname) != FcResultMatch)
+ return names;
+ int index;
+ if (FcPatternGetInteger(pat, FC_INDEX, 0, &index) != FcResultMatch)
+ return names;
+
+ FT_Face face;
+ if (FT_New_Face(gFreeTypeLibrary, pathname, index, &face) != 0)
+ return names;
+
+ const char* name = FT_Get_Postscript_Name(face);
+ if (name == NULL)
+ return names;
+ names->psName = name;
+
+ // for sfnt containers, we'll read the name table ourselves, not rely on Fontconfig
+ if (FT_IS_SFNT(face)) {
+ std::list<std::string> familyNames;
+ std::list<std::string> subFamilyNames;
+ FT_SfntName nameRec;
+ for (index = 0; index < FT_Get_Sfnt_Name_Count(face); ++index) {
+ char* utf8name = NULL;
+ if (FT_Get_Sfnt_Name(face, index, &nameRec) != 0)
+ continue;
+ switch (nameRec.name_id) {
+ case kFontFullName:
+ case kFontFamilyName:
+ case kFontStyleName:
+ case kPreferredFamilyName:
+ case kPreferredSubfamilyName:
+ {
+ bool preferredName = false;
+ if (nameRec.platform_id == TT_PLATFORM_MACINTOSH
+ && nameRec.encoding_id == TT_MAC_ID_ROMAN && nameRec.language_id == 0) {
+ utf8name = convertToUtf8(macRomanConv, nameRec.string, nameRec.string_len);
+ preferredName = true;
+ }
+ else if ((nameRec.platform_id == TT_PLATFORM_APPLE_UNICODE)
+ || (nameRec.platform_id == TT_PLATFORM_MICROSOFT))
+ utf8name = convertToUtf8(utf16beConv, nameRec.string, nameRec.string_len);
+
+ if (utf8name != NULL) {
+ std::list<std::string>* nameList = NULL;
+ switch (nameRec.name_id) {
+ case kFontFullName:
+ nameList = &names->fullNames;
+ break;
+ case kFontFamilyName:
+ nameList = &names->familyNames;
+ break;
+ case kFontStyleName:
+ nameList = &names->styleNames;
+ break;
+ case kPreferredFamilyName:
+ nameList = &familyNames;
+ break;
+ case kPreferredSubfamilyName:
+ nameList = &subFamilyNames;
+ break;
+ }
+ if (preferredName)
+ prependToList(nameList, utf8name);
+ else
+ appendToList(nameList, utf8name);
+ delete[] utf8name;
+ }
+ }
+ break;
+ }
+ }
+ if (familyNames.size() > 0)
+ names->familyNames = familyNames;
+ if (subFamilyNames.size() > 0)
+ names->styleNames = subFamilyNames;
+ } else {
+ index = 0;
+ while (FcPatternGetString(pat, FC_FULLNAME, index++, (FcChar8**)&name) == FcResultMatch)
+ appendToList(&names->fullNames, name);
+ index = 0;
+ while (FcPatternGetString(pat, FC_FAMILY, index++, (FcChar8**)&name) == FcResultMatch)
+ appendToList(&names->familyNames, name);
+ index = 0;
+ while (FcPatternGetString(pat, FC_STYLE, index++, (FcChar8**)&name) == FcResultMatch)
+ appendToList(&names->styleNames, name);
+
+ if (names->fullNames.size() == 0) {
+ std::string fullName(names->familyNames.front());
+ if (names->styleNames.size() > 0) {
+ fullName += " ";
+ fullName += names->styleNames.front();
+ }
+ names->fullNames.push_back(fullName);
+ }
+ }
+
+ FT_Done_Face(face);
+
+ return names;
}
void
XeTeXFontMgr_FC::getOpSizeRecAndStyleFlags(Font* theFont)
{
- XeTeXFontMgr::getOpSizeRecAndStyleFlags(theFont);
-
- if (theFont->weight == 0 && theFont->width == 0) {
- // try to get values from FontConfig, as it apparently wasn't an sfnt
- FcPattern* pat = theFont->fontRef;
- int value;
- if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &value) == FcResultMatch)
- theFont->weight = value;
- if (FcPatternGetInteger(pat, FC_WIDTH, 0, &value) == FcResultMatch)
- theFont->width = value;
- if (FcPatternGetInteger(pat, FC_SLANT, 0, &value) == FcResultMatch)
- theFont->slant = value;
- }
+ XeTeXFontMgr::getOpSizeRecAndStyleFlags(theFont);
+
+ if (theFont->weight == 0 && theFont->width == 0) {
+ // try to get values from FontConfig, as it apparently wasn't an sfnt
+ FcPattern* pat = theFont->fontRef;
+ int value;
+ if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &value) == FcResultMatch)
+ theFont->weight = value;
+ if (FcPatternGetInteger(pat, FC_WIDTH, 0, &value) == FcResultMatch)
+ theFont->width = value;
+ if (FcPatternGetInteger(pat, FC_SLANT, 0, &value) == FcResultMatch)
+ theFont->slant = value;
+ }
}
void
XeTeXFontMgr_FC::cacheFamilyMembers(const std::list<std::string>& familyNames)
{
- if (familyNames.size() == 0)
- return;
- for (int f = 0; f < allFonts->nfont; ++f) {
- FcPattern* pat = allFonts->fonts[f];
- if (platformRefToFont.find(pat) != platformRefToFont.end())
- continue;
- char* s;
- for (int i = 0; FcPatternGetString(pat, FC_FAMILY, i, (FcChar8**)&s) == FcResultMatch; ++i) {
- for (std::list<std::string>::const_iterator j = familyNames.begin(); j != familyNames.end(); ++j) {
- if (*j == s) {
- NameCollection* names = readNames(pat);
- addToMaps(pat, names);
- delete names;
- goto cached;
- }
- }
- }
- cached:
- ;
- }
+ if (familyNames.size() == 0)
+ return;
+ for (int f = 0; f < allFonts->nfont; ++f) {
+ FcPattern* pat = allFonts->fonts[f];
+ if (platformRefToFont.find(pat) != platformRefToFont.end())
+ continue;
+ char* s;
+ for (int i = 0; FcPatternGetString(pat, FC_FAMILY, i, (FcChar8**)&s) == FcResultMatch; ++i) {
+ for (std::list<std::string>::const_iterator j = familyNames.begin(); j != familyNames.end(); ++j) {
+ if (*j == s) {
+ NameCollection* names = readNames(pat);
+ addToMaps(pat, names);
+ delete names;
+ goto cached;
+ }
+ }
+ }
+ cached:
+ ;
+ }
}
void
XeTeXFontMgr_FC::searchForHostPlatformFonts(const std::string& name)
{
- if (cachedAll) // we've already loaded everything on an earlier search
- return;
-
- std::string famName;
- int hyph = name.find('-');
- if (hyph > 0 && hyph < name.length() - 1)
- famName.assign(name.begin(), name.begin() + hyph);
- else
- hyph = 0;
-
- bool found = false;
- while (1) {
- for (int f = 0; f < allFonts->nfont; ++f) {
- restart:
- FcPattern* pat = allFonts->fonts[f];
- if (platformRefToFont.find(pat) != platformRefToFont.end())
- continue;
-
- if (cachedAll) {
- // failed to find it via FC; add everything to our maps (potentially slow) as a last resort
- NameCollection* names = readNames(pat);
- addToMaps(pat, names);
- delete names;
- continue;
- }
-
- char* s;
- int i;
- for (i = 0; FcPatternGetString(pat, FC_FULLNAME, i, (FcChar8**)&s) == FcResultMatch; ++i) {
- if (name == s) {
- NameCollection* names = readNames(pat);
- addToMaps(pat, names);
- cacheFamilyMembers(names->familyNames);
- delete names;
- found = true;
- goto next_font;
- }
- }
-
- for (i = 0; FcPatternGetString(pat, FC_FAMILY, i, (FcChar8**)&s) == FcResultMatch; ++i) {
- if (name == s || (hyph && famName == s)) {
- NameCollection* names = readNames(pat);
- addToMaps(pat, names);
- cacheFamilyMembers(names->familyNames);
- delete names;
- found = true;
- goto next_font;
- }
- char* t;
- for (int j = 0; FcPatternGetString(pat, FC_STYLE, j, (FcChar8**)&t) == FcResultMatch; ++j) {
- std::string full(s);
- full += " ";
- full += t;
- if (name == full) {
- NameCollection* names = readNames(pat);
- addToMaps(pat, names);
- cacheFamilyMembers(names->familyNames);
- delete names;
- found = true;
- goto next_font;
- }
- }
- }
-
- next_font:
- ;
- }
-
- if (found || cachedAll)
- break;
- cachedAll = true;
- }
+ if (cachedAll) // we've already loaded everything on an earlier search
+ return;
+
+ std::string famName;
+ int hyph = name.find('-');
+ if (hyph > 0 && hyph < name.length() - 1)
+ famName.assign(name.begin(), name.begin() + hyph);
+ else
+ hyph = 0;
+
+ bool found = false;
+ while (1) {
+ for (int f = 0; f < allFonts->nfont; ++f) {
+ restart:
+ FcPattern* pat = allFonts->fonts[f];
+ if (platformRefToFont.find(pat) != platformRefToFont.end())
+ continue;
+
+ if (cachedAll) {
+ // failed to find it via FC; add everything to our maps (potentially slow) as a last resort
+ NameCollection* names = readNames(pat);
+ addToMaps(pat, names);
+ delete names;
+ continue;
+ }
+
+ char* s;
+ int i;
+ for (i = 0; FcPatternGetString(pat, FC_FULLNAME, i, (FcChar8**)&s) == FcResultMatch; ++i) {
+ if (name == s) {
+ NameCollection* names = readNames(pat);
+ addToMaps(pat, names);
+ cacheFamilyMembers(names->familyNames);
+ delete names;
+ found = true;
+ goto next_font;
+ }
+ }
+
+ for (i = 0; FcPatternGetString(pat, FC_FAMILY, i, (FcChar8**)&s) == FcResultMatch; ++i) {
+ if (name == s || (hyph && famName == s)) {
+ NameCollection* names = readNames(pat);
+ addToMaps(pat, names);
+ cacheFamilyMembers(names->familyNames);
+ delete names;
+ found = true;
+ goto next_font;
+ }
+ char* t;
+ for (int j = 0; FcPatternGetString(pat, FC_STYLE, j, (FcChar8**)&t) == FcResultMatch; ++j) {
+ std::string full(s);
+ full += " ";
+ full += t;
+ if (name == full) {
+ NameCollection* names = readNames(pat);
+ addToMaps(pat, names);
+ cacheFamilyMembers(names->familyNames);
+ delete names;
+ found = true;
+ goto next_font;
+ }
+ }
+ }
+
+ next_font:
+ ;
+ }
+
+ if (found || cachedAll)
+ break;
+ cachedAll = true;
+ }
}
void
XeTeXFontMgr_FC::initialize()
{
- if (FcInit() == FcFalse) {
- fprintf(stderr, "fontconfig initialization failed!\n");
- exit(9);
- }
-
- if (gFreeTypeLibrary == 0 && FT_Init_FreeType(&gFreeTypeLibrary) != 0) {
- fprintf(stderr, "FreeType initialization failed!\n");
- exit(9);
- }
-
- UErrorCode err = U_ZERO_ERROR;
- macRomanConv = ucnv_open("macintosh", &err);
- utf16beConv = ucnv_open("UTF16BE", &err);
- utf8Conv = ucnv_open("UTF8", &err);
- if (err != 0) {
- fprintf(stderr, "internal error; cannot read font names\n");
- exit(3);
- }
-
- FcPattern* pat = FcNameParse((const FcChar8*)":outline=true");
- FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, FC_INDEX,
- FC_FULLNAME, FC_WEIGHT, FC_WIDTH, FC_SLANT, FC_FONTFORMAT, NULL);
- allFonts = FcFontList(FcConfigGetCurrent(), pat, os);
- FcObjectSetDestroy(os);
- FcPatternDestroy(pat);
-
- cachedAll = false;
+ if (FcInit() == FcFalse) {
+ fprintf(stderr, "fontconfig initialization failed!\n");
+ exit(9);
+ }
+
+ if (gFreeTypeLibrary == 0 && FT_Init_FreeType(&gFreeTypeLibrary) != 0) {
+ fprintf(stderr, "FreeType initialization failed!\n");
+ exit(9);
+ }
+
+ UErrorCode err = U_ZERO_ERROR;
+ macRomanConv = ucnv_open("macintosh", &err);
+ utf16beConv = ucnv_open("UTF16BE", &err);
+ utf8Conv = ucnv_open("UTF8", &err);
+ if (err != 0) {
+ fprintf(stderr, "internal error; cannot read font names\n");
+ exit(3);
+ }
+
+ FcPattern* pat = FcNameParse((const FcChar8*)":outline=true");
+ FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, FC_INDEX,
+ FC_FULLNAME, FC_WEIGHT, FC_WIDTH, FC_SLANT, FC_FONTFORMAT, NULL);
+ allFonts = FcFontList(FcConfigGetCurrent(), pat, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pat);
+
+ cachedAll = false;
}
void
XeTeXFontMgr_FC::terminate()
{
- if (macRomanConv != NULL)
- ucnv_close(macRomanConv);
- if (utf16beConv != NULL)
- ucnv_close(utf16beConv);
- if (utf8Conv != NULL)
- ucnv_close(utf8Conv);
+ if (macRomanConv != NULL)
+ ucnv_close(macRomanConv);
+ if (utf16beConv != NULL)
+ ucnv_close(utf16beConv);
+ if (utf8Conv != NULL)
+ ucnv_close(utf8Conv);
}
std::string
XeTeXFontMgr_FC::getPlatformFontDesc(PlatformFontRef font) const
{
- std::string path;
- FcChar8* s;
- if (FcPatternGetString(font, FC_FILE, 0, (FcChar8**)&s) == FcResultMatch)
- path = (char*)s;
- else
- path = "[unknown]";
- return path;
+ std::string path;
+ FcChar8* s;
+ if (FcPatternGetString(font, FC_FILE, 0, (FcChar8**)&s) == FcResultMatch)
+ path = (char*)s;
+ else
+ path = "[unknown]";
+ return path;
}
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.h b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.h
index 6187523027e..72889b3c971 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.h
@@ -36,30 +36,30 @@ authorization from the copyright holders.
#include "XeTeXFontMgr.h"
class XeTeXFontMgr_FC
- : public XeTeXFontMgr
+ : public XeTeXFontMgr
{
public:
- XeTeXFontMgr_FC()
- { }
- virtual ~XeTeXFontMgr_FC()
- { }
+ XeTeXFontMgr_FC()
+ { }
+ virtual ~XeTeXFontMgr_FC()
+ { }
protected:
-
- virtual void initialize();
- virtual void terminate();
- virtual void getOpSizeRecAndStyleFlags(Font* theFont);
- virtual void searchForHostPlatformFonts(const std::string& name);
-
- virtual NameCollection* readNames(FcPattern* pat);
+ virtual void initialize();
+ virtual void terminate();
- std::string getPlatformFontDesc(PlatformFontRef font) const;
-
- void cacheFamilyMembers(const std::list<std::string>& familyNames);
+ virtual void getOpSizeRecAndStyleFlags(Font* theFont);
+ virtual void searchForHostPlatformFonts(const std::string& name);
- FcFontSet* allFonts;
- bool cachedAll;
+ virtual NameCollection* readNames(FcPattern* pat);
+
+ std::string getPlatformFontDesc(PlatformFontRef font) const;
+
+ void cacheFamilyMembers(const std::list<std::string>& familyNames);
+
+ FcFontSet* allFonts;
+ bool cachedAll;
};
-#endif /* __XETEX_FONT_MGR_FC_H */
+#endif /* __XETEX_FONT_MGR_FC_H */
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h
index fe19cef7c97..f6f8a824a7d 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.h
@@ -39,35 +39,35 @@ authorization from the copyright holders.
#include <CoreFoundation/CoreFoundation.h>
class XeTeXFontMgr_Mac
- : public XeTeXFontMgr
+ : public XeTeXFontMgr
{
public:
- XeTeXFontMgr_Mac()
- { }
- virtual ~XeTeXFontMgr_Mac()
- { }
+ XeTeXFontMgr_Mac()
+ { }
+ virtual ~XeTeXFontMgr_Mac()
+ { }
protected:
-
- virtual void initialize();
- virtual void terminate();
- virtual void searchForHostPlatformFonts(const std::string& name);
-
- virtual NameCollection* readNames(CTFontDescriptorRef fontRef);
+ virtual void initialize();
+ virtual void terminate();
- virtual std::string getPlatformFontDesc(PlatformFontRef font) const;
+ virtual void searchForHostPlatformFonts(const std::string& name);
+
+ virtual NameCollection* readNames(CTFontDescriptorRef fontRef);
+
+ virtual std::string getPlatformFontDesc(PlatformFontRef font) const;
private:
- void addFontsToCaches(CFArrayRef fonts);
+ void addFontsToCaches(CFArrayRef fonts);
- void addFamilyToCaches(CTFontDescriptorRef familyRef);
+ void addFamilyToCaches(CTFontDescriptorRef familyRef);
- void addFontAndSiblingsToCaches(CTFontDescriptorRef fontRef);
+ void addFontAndSiblingsToCaches(CTFontDescriptorRef fontRef);
- void appendNameToList(CTFontRef font,
- std::list<std::string>* nameList,
- CFStringRef nameKey);
+ void appendNameToList(CTFontRef font,
+ std::list<std::string>* nameList,
+ CFStringRef nameKey);
};
-#endif /* __XETEX_FONT_MGR_MAC_H */
+#endif /* __XETEX_FONT_MGR_MAC_H */
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm
index 6d818a0f386..92b11245a7e 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_Mac.mm
@@ -45,168 +45,168 @@ extern "C" {
CTFontDescriptorRef findFontWithName(CFStringRef name, CFStringRef key)
{
- CFStringRef keys[] = { key };
- CFTypeRef values[] = { name };
- CFDictionaryRef attributes = CFDictionaryCreate(NULL, (const void **) &keys, (const void **) &values, 1,
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes(attributes);
- CFRelease(attributes);
-
- CFSetRef mandatoryAttributes = CFSetCreate(NULL, (const void **) &keys, 1, &kCFTypeSetCallBacks);
- CFArrayRef matches = CTFontDescriptorCreateMatchingFontDescriptors(descriptor, mandatoryAttributes);
- CFRelease(mandatoryAttributes);
- CFRelease(descriptor);
-
- CTFontDescriptorRef matched = NULL;
- if (matches) {
- if (CFArrayGetCount(matches)) {
- matched = (CTFontDescriptorRef) CFArrayGetValueAtIndex(matches, 0);
- CFRetain(matched);
- }
- CFRelease(matches);
- }
- return matched;
+ CFStringRef keys[] = { key };
+ CFTypeRef values[] = { name };
+ CFDictionaryRef attributes = CFDictionaryCreate(NULL, (const void **) &keys, (const void **) &values, 1,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes(attributes);
+ CFRelease(attributes);
+
+ CFSetRef mandatoryAttributes = CFSetCreate(NULL, (const void **) &keys, 1, &kCFTypeSetCallBacks);
+ CFArrayRef matches = CTFontDescriptorCreateMatchingFontDescriptors(descriptor, mandatoryAttributes);
+ CFRelease(mandatoryAttributes);
+ CFRelease(descriptor);
+
+ CTFontDescriptorRef matched = NULL;
+ if (matches) {
+ if (CFArrayGetCount(matches)) {
+ matched = (CTFontDescriptorRef) CFArrayGetValueAtIndex(matches, 0);
+ CFRetain(matched);
+ }
+ CFRelease(matches);
+ }
+ return matched;
}
void
XeTeXFontMgr_Mac::appendNameToList(CTFontRef font,
- std::list<std::string>* nameList,
- CFStringRef nameKey)
+ std::list<std::string>* nameList,
+ CFStringRef nameKey)
{
- CFStringRef name = CTFontCopyName(font, nameKey);
- if (name) {
- appendToList(nameList, [(NSString *) name UTF8String]);
- CFRelease(name);
- }
- CFStringRef language;
- name = CTFontCopyLocalizedName(font, nameKey, &language);
- if (name) {
- appendToList(nameList, [(NSString *) name UTF8String]);
- CFRelease(name);
- }
+ CFStringRef name = CTFontCopyName(font, nameKey);
+ if (name) {
+ appendToList(nameList, [(NSString *) name UTF8String]);
+ CFRelease(name);
+ }
+ CFStringRef language;
+ name = CTFontCopyLocalizedName(font, nameKey, &language);
+ if (name) {
+ appendToList(nameList, [(NSString *) name UTF8String]);
+ CFRelease(name);
+ }
}
XeTeXFontMgr::NameCollection*
XeTeXFontMgr_Mac::readNames(CTFontDescriptorRef fontRef)
{
- NameCollection* names = new NameCollection;
+ NameCollection* names = new NameCollection;
- CFStringRef psName = (CFStringRef) CTFontDescriptorCopyAttribute(fontRef, kCTFontNameAttribute);
- if (!psName)
- return names;
+ CFStringRef psName = (CFStringRef) CTFontDescriptorCopyAttribute(fontRef, kCTFontNameAttribute);
+ if (!psName)
+ return names;
- NSAutoreleasePool *pool = [NSAutoreleasePool new];
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
- names->psName = [(NSString *) psName UTF8String];
- CFRelease(psName);
+ names->psName = [(NSString *) psName UTF8String];
+ CFRelease(psName);
- CTFontRef font = CTFontCreateWithFontDescriptor(fontRef, 0.0, 0);
- appendNameToList(font, &names->fullNames, kCTFontFullNameKey);
- appendNameToList(font, &names->familyNames, kCTFontFamilyNameKey);
- appendNameToList(font, &names->styleNames, kCTFontStyleNameKey);
- CFRelease(font);
+ CTFontRef font = CTFontCreateWithFontDescriptor(fontRef, 0.0, 0);
+ appendNameToList(font, &names->fullNames, kCTFontFullNameKey);
+ appendNameToList(font, &names->familyNames, kCTFontFamilyNameKey);
+ appendNameToList(font, &names->styleNames, kCTFontStyleNameKey);
+ CFRelease(font);
- [pool release];
+ [pool release];
- return names;
+ return names;
}
void
XeTeXFontMgr_Mac::addFontsToCaches(CFArrayRef fonts)
{
- NSEnumerator* enumerator = [(NSArray*)fonts objectEnumerator];
- while (id aFont = [enumerator nextObject]) {
- CTFontDescriptorRef fontRef = findFontWithName((CFStringRef)[aFont objectAtIndex: 0], kCTFontNameAttribute);
- NameCollection* names = readNames(fontRef);
- addToMaps(fontRef, names);
- delete names;
- }
+ NSEnumerator* enumerator = [(NSArray*)fonts objectEnumerator];
+ while (id aFont = [enumerator nextObject]) {
+ CTFontDescriptorRef fontRef = findFontWithName((CFStringRef)[aFont objectAtIndex: 0], kCTFontNameAttribute);
+ NameCollection* names = readNames(fontRef);
+ addToMaps(fontRef, names);
+ delete names;
+ }
}
void
XeTeXFontMgr_Mac::addFamilyToCaches(CTFontDescriptorRef familyRef)
{
- CFStringRef nameStr = (CFStringRef) CTFontDescriptorCopyAttribute(familyRef, kCTFontFamilyNameAttribute);
- if (nameStr) {
- NSArray* members = [[NSFontManager sharedFontManager]
- availableMembersOfFontFamily: (NSString*)nameStr];
- CFRelease(nameStr);
- addFontsToCaches((CFArrayRef)members);
- }
+ CFStringRef nameStr = (CFStringRef) CTFontDescriptorCopyAttribute(familyRef, kCTFontFamilyNameAttribute);
+ if (nameStr) {
+ NSArray* members = [[NSFontManager sharedFontManager]
+ availableMembersOfFontFamily: (NSString*)nameStr];
+ CFRelease(nameStr);
+ addFontsToCaches((CFArrayRef)members);
+ }
}
void
XeTeXFontMgr_Mac::addFontAndSiblingsToCaches(CTFontDescriptorRef fontRef)
{
- CFStringRef name = (CFStringRef) CTFontDescriptorCopyAttribute(fontRef, kCTFontNameAttribute);
- if (name) {
- NSFont* font = [NSFont fontWithName:(NSString*)name size:10.0];
- CFRelease(name);
- NSArray* members = [[NSFontManager sharedFontManager]
- availableMembersOfFontFamily: [font familyName]];
- addFontsToCaches((CFArrayRef)members);
- }
+ CFStringRef name = (CFStringRef) CTFontDescriptorCopyAttribute(fontRef, kCTFontNameAttribute);
+ if (name) {
+ NSFont* font = [NSFont fontWithName:(NSString*)name size:10.0];
+ CFRelease(name);
+ NSArray* members = [[NSFontManager sharedFontManager]
+ availableMembersOfFontFamily: [font familyName]];
+ addFontsToCaches((CFArrayRef)members);
+ }
}
void
XeTeXFontMgr_Mac::searchForHostPlatformFonts(const std::string& name)
{
- // the name might be:
- // FullName
- // Family-Style (if there's a hyphen)
- // PSName
- // Family
- // ...so we need to try it as each of these
-
- CFStringRef nameStr = CFStringCreateWithCString(kCFAllocatorDefault, name.c_str(), kCFStringEncodingUTF8);
- CTFontDescriptorRef matched = findFontWithName(nameStr, kCTFontDisplayNameAttribute);
- if (matched) {
- // found it, so locate the family, and add all members to the caches
- addFontAndSiblingsToCaches(matched);
- CFRelease(matched);
- return;
- }
-
- int hyph = name.find('-');
- if (hyph > 0 && hyph < name.length() - 1) {
- std::string family(name.begin(), name.begin() + hyph);
- CFStringRef familyStr = CFStringCreateWithCString(kCFAllocatorDefault, family.c_str(), kCFStringEncodingUTF8);
-
- NSArray* familyMembers = [[NSFontManager sharedFontManager]
- availableMembersOfFontFamily: (NSString*)familyStr];
- if ([familyMembers count] > 0) {
- addFontsToCaches((CFArrayRef)familyMembers);
- return;
- }
-
- matched = findFontWithName(familyStr, kCTFontFamilyNameAttribute);
- if (matched) {
- addFamilyToCaches(matched);
- CFRelease(matched);
- return;
- }
- }
-
- matched = findFontWithName(nameStr, kCTFontNameAttribute);
- if (matched) {
- addFontAndSiblingsToCaches(matched);
- CFRelease(matched);
- return;
- }
-
- NSArray* familyMembers = [[NSFontManager sharedFontManager]
- availableMembersOfFontFamily: (NSString*)nameStr];
- if ([familyMembers count] > 0) {
- addFontsToCaches((CFArrayRef)familyMembers);
- return;
- }
-
- matched = findFontWithName(nameStr, kCTFontFamilyNameAttribute);
- if (matched) {
- addFamilyToCaches(matched);
- CFRelease(matched);
- return;
- }
+ // the name might be:
+ // FullName
+ // Family-Style (if there's a hyphen)
+ // PSName
+ // Family
+ // ...so we need to try it as each of these
+
+ CFStringRef nameStr = CFStringCreateWithCString(kCFAllocatorDefault, name.c_str(), kCFStringEncodingUTF8);
+ CTFontDescriptorRef matched = findFontWithName(nameStr, kCTFontDisplayNameAttribute);
+ if (matched) {
+ // found it, so locate the family, and add all members to the caches
+ addFontAndSiblingsToCaches(matched);
+ CFRelease(matched);
+ return;
+ }
+
+ int hyph = name.find('-');
+ if (hyph > 0 && hyph < name.length() - 1) {
+ std::string family(name.begin(), name.begin() + hyph);
+ CFStringRef familyStr = CFStringCreateWithCString(kCFAllocatorDefault, family.c_str(), kCFStringEncodingUTF8);
+
+ NSArray* familyMembers = [[NSFontManager sharedFontManager]
+ availableMembersOfFontFamily: (NSString*)familyStr];
+ if ([familyMembers count] > 0) {
+ addFontsToCaches((CFArrayRef)familyMembers);
+ return;
+ }
+
+ matched = findFontWithName(familyStr, kCTFontFamilyNameAttribute);
+ if (matched) {
+ addFamilyToCaches(matched);
+ CFRelease(matched);
+ return;
+ }
+ }
+
+ matched = findFontWithName(nameStr, kCTFontNameAttribute);
+ if (matched) {
+ addFontAndSiblingsToCaches(matched);
+ CFRelease(matched);
+ return;
+ }
+
+ NSArray* familyMembers = [[NSFontManager sharedFontManager]
+ availableMembersOfFontFamily: (NSString*)nameStr];
+ if ([familyMembers count] > 0) {
+ addFontsToCaches((CFArrayRef)familyMembers);
+ return;
+ }
+
+ matched = findFontWithName(nameStr, kCTFontFamilyNameAttribute);
+ if (matched) {
+ addFamilyToCaches(matched);
+ CFRelease(matched);
+ return;
+ }
}
NSAutoreleasePool* pool = NULL;
@@ -214,44 +214,44 @@ NSAutoreleasePool* pool = NULL;
void
XeTeXFontMgr_Mac::initialize()
{
- pool = [[NSAutoreleasePool alloc] init];
+ pool = [[NSAutoreleasePool alloc] init];
}
void
XeTeXFontMgr_Mac::terminate()
{
- if (pool != NULL) {
- [pool release];
- }
+ if (pool != NULL) {
+ [pool release];
+ }
}
std::string
XeTeXFontMgr_Mac::getPlatformFontDesc(PlatformFontRef descriptor) const
{
- std::string path;
- CTFontRef ctFont = CTFontCreateWithFontDescriptor(descriptor, 0.0, 0);
- if (ctFont) {
- CFURLRef url = NULL;
+ std::string path;
+ CTFontRef ctFont = CTFontCreateWithFontDescriptor(descriptor, 0.0, 0);
+ if (ctFont) {
+ CFURLRef url = NULL;
#if !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
- /* kCTFontURLAttribute was not avialable before 10.6 */
- FSRef fsref;
- ATSFontRef atsFont = CTFontGetPlatformFont(ctFont, NULL);
- OSStatus status = ATSFontGetFileReference(atsFont, &fsref);
- if (status == noErr)
- url = CFURLCreateFromFSRef(NULL, &fsref);
+ /* kCTFontURLAttribute was not avialable before 10.6 */
+ FSRef fsref;
+ ATSFontRef atsFont = CTFontGetPlatformFont(ctFont, NULL);
+ OSStatus status = ATSFontGetFileReference(atsFont, &fsref);
+ if (status == noErr)
+ url = CFURLCreateFromFSRef(NULL, &fsref);
#else
- url = (CFURLRef) CTFontCopyAttribute(ctFont, kCTFontURLAttribute);
+ url = (CFURLRef) CTFontCopyAttribute(ctFont, kCTFontURLAttribute);
#endif
- if (url) {
- UInt8 posixPath[PATH_MAX];
- if (CFURLGetFileSystemRepresentation(url, true, posixPath, PATH_MAX)) {
- path = (char*)posixPath;
- }
- CFRelease(url);
- }
- CFRelease(ctFont);
- }
- if (path.length() == 0)
- path = "[unknown]";
- return path;
+ if (url) {
+ UInt8 posixPath[PATH_MAX];
+ if (CFURLGetFileSystemRepresentation(url, true, posixPath, PATH_MAX)) {
+ path = (char*)posixPath;
+ }
+ CFRelease(url);
+ }
+ CFRelease(ctFont);
+ }
+ if (path.length() == 0)
+ path = "[unknown]";
+ return path;
}
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp
index 0e99efa88ec..dc1d1067f3e 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp
@@ -39,10 +39,16 @@ extern "C" {
}
#endif
-#include <unicode/platform.h> // We need this first
+#include <unicode/platform.h> // We need this first
#include <unicode/ubidi.h>
#include <unicode/utext.h>
+#include <graphite2/Font.h>
+#include <graphite2/Segment.h>
+#include <hb-graphite2.h>
+#include <hb-icu.h>
+#include <hb-ot.h>
+
#include "XeTeXLayoutInterface.h"
#include "XeTeXFontInst.h"
#ifdef XETEX_MAC
@@ -50,21 +56,28 @@ extern "C" {
#endif
#include "XeTeXFontMgr.h"
+typedef void* voidptr;
+
+extern "C" {
+ extern voidptr* fontlayoutengine;
+ extern integer* fontarea;
+}
+
struct XeTeXLayoutEngine_rec
{
- XeTeXFontInst* font;
- PlatformFontRef fontRef;
- hb_tag_t script;
- hb_tag_t language;
- hb_feature_t* features;
- char** ShaperList; // the requested shapers
- char* shaper; // the actually used shaper
- int nFeatures;
- uint32_t rgbValue;
- float extend;
- float slant;
- float embolden;
- hb_buffer_t* hbBuffer;
+ XeTeXFontInst* font;
+ PlatformFontRef fontRef;
+ hb_tag_t script;
+ hb_language_t language;
+ hb_feature_t* features;
+ char** ShaperList; // the requested shapers
+ char* shaper; // the actually used shaper
+ int nFeatures;
+ uint32_t rgbValue;
+ float extend;
+ float slant;
+ float embolden;
+ hb_buffer_t* hbBuffer;
};
/*******************************************************************/
@@ -74,815 +87,860 @@ struct XeTeXLayoutEngine_rec
// key is combined value representing (font_id << 16) + glyph
// value is glyph bounding box in TeX points
-static std::map<uint32_t,GlyphBBox> sGlyphBoxes;
+static std::map<uint32_t,GlyphBBox> sGlyphBoxes;
int
getCachedGlyphBBox(uint16_t fontID, uint16_t glyphID, GlyphBBox* bbox)
{
- uint32_t key = ((uint32_t)fontID << 16) + glyphID;
- std::map<uint32_t,GlyphBBox>::const_iterator i = sGlyphBoxes.find(key);
- if (i == sGlyphBoxes.end()) {
- return 0;
- }
- *bbox = i->second;
- return 1;
+ uint32_t key = ((uint32_t)fontID << 16) + glyphID;
+ std::map<uint32_t,GlyphBBox>::const_iterator i = sGlyphBoxes.find(key);
+ if (i == sGlyphBoxes.end()) {
+ return 0;
+ }
+ *bbox = i->second;
+ return 1;
}
void
cacheGlyphBBox(uint16_t fontID, uint16_t glyphID, const GlyphBBox* bbox)
{
- uint32_t key = ((uint32_t)fontID << 16) + glyphID;
- sGlyphBoxes[key] = *bbox;
+ uint32_t key = ((uint32_t)fontID << 16) + glyphID;
+ sGlyphBoxes[key] = *bbox;
}
/*******************************************************************/
void
terminatefontmanager()
{
- XeTeXFontMgr::Terminate();
+ XeTeXFontMgr::Terminate();
}
XeTeXFont
createFont(PlatformFontRef fontRef, Fixed pointSize)
{
- int status = 0;
+ int status = 0;
#ifdef XETEX_MAC
- XeTeXFontInst* font = new XeTeXFontInst_Mac(fontRef, Fix2D(pointSize), status);
+ XeTeXFontInst* font = new XeTeXFontInst_Mac(fontRef, Fix2D(pointSize), status);
#else
- FcChar8* pathname = 0;
- FcPatternGetString(fontRef, FC_FILE, 0, &pathname);
- int index;
- FcPatternGetInteger(fontRef, FC_INDEX, 0, &index);
- XeTeXFontInst* font = new XeTeXFontInst((const char*)pathname, index, Fix2D(pointSize), status);
+ FcChar8* pathname = 0;
+ FcPatternGetString(fontRef, FC_FILE, 0, &pathname);
+ int index;
+ FcPatternGetInteger(fontRef, FC_INDEX, 0, &index);
+ XeTeXFontInst* font = new XeTeXFontInst((const char*)pathname, index, Fix2D(pointSize), status);
#endif
- if (status != 0) {
- delete font;
- return NULL;
- }
- return (XeTeXFont)font;
+ if (status != 0) {
+ delete font;
+ return NULL;
+ }
+ return (XeTeXFont)font;
}
XeTeXFont
createFontFromFile(const char* filename, int index, Fixed pointSize)
{
- int status = 0;
- XeTeXFontInst* font = new XeTeXFontInst(filename, index, Fix2D(pointSize), status);
- if (status != 0) {
- delete font;
- return NULL;
- }
- return (XeTeXFont)font;
+ int status = 0;
+ XeTeXFontInst* font = new XeTeXFontInst(filename, index, Fix2D(pointSize), status);
+ if (status != 0) {
+ delete font;
+ return NULL;
+ }
+ return (XeTeXFont)font;
}
void
setFontLayoutDir(XeTeXFont font, int vertical)
{
- ((XeTeXFontInst*)font)->setLayoutDirVertical(vertical != 0);
+ ((XeTeXFontInst*)font)->setLayoutDirVertical(vertical != 0);
}
PlatformFontRef
findFontByName(const char* name, char* var, double size)
{
- return (XeTeXFontMgr::GetFontManager()->findFont(name, var, size));
+ return (XeTeXFontMgr::GetFontManager()->findFont(name, var, size));
}
char
getReqEngine()
{
- return XeTeXFontMgr::GetFontManager()->getReqEngine();
+ return XeTeXFontMgr::GetFontManager()->getReqEngine();
}
void
setReqEngine(char reqEngine)
{
- XeTeXFontMgr::GetFontManager()->setReqEngine(reqEngine);
+ XeTeXFontMgr::GetFontManager()->setReqEngine(reqEngine);
}
const char*
getFullName(PlatformFontRef fontRef)
{
- return XeTeXFontMgr::GetFontManager()->getFullName(fontRef);
+ return XeTeXFontMgr::GetFontManager()->getFullName(fontRef);
}
double
getDesignSize(XeTeXFont font)
{
- return XeTeXFontMgr::GetFontManager()->getDesignSize(font);
+ return XeTeXFontMgr::GetFontManager()->getDesignSize(font);
}
const char*
getFontFilename(XeTeXLayoutEngine engine)
{
- return engine->font->getFilename();
+ return engine->font->getFilename();
}
void
getNames(PlatformFontRef fontRef, const char** psName, const char** famName, const char** styName)
{
- XeTeXFontMgr::GetFontManager()->getNames(fontRef, psName, famName, styName);
+ XeTeXFontMgr::GetFontManager()->getNames(fontRef, psName, famName, styName);
}
PlatformFontRef
getFontRef(XeTeXLayoutEngine engine)
{
- return engine->fontRef;
+ return engine->fontRef;
}
void
deleteFont(XeTeXFont font)
{
- delete (XeTeXFontInst*)font;
+ delete (XeTeXFontInst*)font;
}
void*
getFontTablePtr(XeTeXFont font, uint32_t tableTag)
{
- return const_cast<void*>(((XeTeXFontInst*)font)->getFontTable(tableTag));
+ return const_cast<void*>(((XeTeXFontInst*)font)->getFontTable(tableTag));
}
Fixed
getSlant(XeTeXFont font)
{
- float italAngle = ((XeTeXFontInst*)font)->getItalicAngle();
- return D2Fix(tan(-italAngle * M_PI / 180.0));
+ float italAngle = ((XeTeXFontInst*)font)->getItalicAngle();
+ return D2Fix(tan(-italAngle * M_PI / 180.0));
}
static unsigned int
getLargerScriptListTable(XeTeXFont font, hb_tag_t** scriptList)
{
- unsigned int rval = 0;
+ unsigned int rval = 0;
- hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
+ hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
- hb_tag_t* scriptListSub = NULL;
- hb_tag_t* scriptListPos = NULL;
+ hb_tag_t* scriptListSub = NULL;
+ hb_tag_t* scriptListPos = NULL;
- unsigned int scriptCountSub = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, NULL, NULL);
- scriptListSub = (hb_tag_t*) xmalloc(scriptCountSub * sizeof(hb_tag_t*));
- hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCountSub, scriptListSub);
+ unsigned int scriptCountSub = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, NULL, NULL);
+ scriptListSub = (hb_tag_t*) xcalloc(scriptCountSub, sizeof(hb_tag_t*));
+ hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCountSub, scriptListSub);
- unsigned int scriptCountPos = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GPOS, 0, NULL, NULL);
- scriptListPos = (hb_tag_t*) xmalloc(scriptCountPos * sizeof(hb_tag_t*));
- hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCountPos, scriptListPos);
+ unsigned int scriptCountPos = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GPOS, 0, NULL, NULL);
+ scriptListPos = (hb_tag_t*) xcalloc(scriptCountPos, sizeof(hb_tag_t*));
+ hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCountPos, scriptListPos);
- if (scriptCountSub > scriptCountPos) {
- if (scriptList != NULL)
- *scriptList = scriptListSub;
- rval = scriptCountSub;
- } else {
- if (scriptList != NULL)
- *scriptList = scriptListPos;
- rval = scriptCountPos;
- }
+ if (scriptCountSub > scriptCountPos) {
+ if (scriptList != NULL)
+ *scriptList = scriptListSub;
+ rval = scriptCountSub;
+ } else {
+ if (scriptList != NULL)
+ *scriptList = scriptListPos;
+ rval = scriptCountPos;
+ }
- return rval;
+ return rval;
}
unsigned int
countScripts(XeTeXFont font)
{
- return getLargerScriptListTable(font, NULL);
+ return getLargerScriptListTable(font, NULL);
}
hb_tag_t
getIndScript(XeTeXFont font, unsigned int index)
{
- hb_tag_t rval = 0;
+ hb_tag_t rval = 0;
- hb_tag_t* scriptList;
+ hb_tag_t* scriptList;
- unsigned int scriptCount = getLargerScriptListTable(font, &scriptList);
- if (scriptList != NULL) {
- if (index < scriptCount)
- rval = scriptList[index];
- }
+ unsigned int scriptCount = getLargerScriptListTable(font, &scriptList);
+ if (scriptList != NULL) {
+ if (index < scriptCount)
+ rval = scriptList[index];
+ }
- return rval;
+ return rval;
}
unsigned int
countLanguages(XeTeXFont font, hb_tag_t script)
{
- unsigned int rval = 0;
+ unsigned int rval = 0;
- hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
- hb_tag_t* scriptList;
+ hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
+ hb_tag_t* scriptList;
- unsigned int scriptCount = getLargerScriptListTable(font, &scriptList);
- if (scriptList != NULL) {
- for (int i = 0; i < scriptCount; i++) {
- if (scriptList[i] == script) {
- rval += hb_ot_layout_script_get_language_tags (face, HB_OT_TAG_GSUB, i, 0, NULL, NULL);
- rval += hb_ot_layout_script_get_language_tags (face, HB_OT_TAG_GPOS, i, 0, NULL, NULL);
- break;
- }
- }
- }
+ unsigned int scriptCount = getLargerScriptListTable(font, &scriptList);
+ if (scriptList != NULL) {
+ for (int i = 0; i < scriptCount; i++) {
+ if (scriptList[i] == script) {
+ rval += hb_ot_layout_script_get_language_tags (face, HB_OT_TAG_GSUB, i, 0, NULL, NULL);
+ rval += hb_ot_layout_script_get_language_tags (face, HB_OT_TAG_GPOS, i, 0, NULL, NULL);
+ break;
+ }
+ }
+ }
- return rval;
+ return rval;
}
hb_tag_t
getIndLanguage(XeTeXFont font, hb_tag_t script, unsigned int index)
{
- hb_tag_t rval = 0;
+ hb_tag_t rval = 0;
- hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
- hb_tag_t* scriptList;
+ hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
+ hb_tag_t* scriptList;
- unsigned int scriptCount = getLargerScriptListTable(font, &scriptList);
- if (scriptList != NULL) {
- for (int i = 0; i < scriptCount; i++) {
- if (scriptList[i] == script) {
- unsigned int langCount;
- hb_tag_t* langList;
+ unsigned int scriptCount = getLargerScriptListTable(font, &scriptList);
+ if (scriptList != NULL) {
+ for (int i = 0; i < scriptCount; i++) {
+ if (scriptList[i] == script) {
+ unsigned int langCount;
+ hb_tag_t* langList;
- langCount = hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, NULL, NULL);
- langList = (hb_tag_t*) xcalloc(langCount, sizeof(hb_tag_t*));
- hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, &langCount, langList);
+ langCount = hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, NULL, NULL);
+ langList = (hb_tag_t*) xcalloc(langCount, sizeof(hb_tag_t*));
+ hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, &langCount, langList);
- if (index < langCount) {
- rval = langList[index];
- break;
- }
+ if (index < langCount) {
+ rval = langList[index];
+ break;
+ }
- free(langList);
+ free(langList);
- langCount = hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GPOS, i, 0, NULL, NULL);
- langList = (hb_tag_t*) xcalloc(langCount, sizeof(hb_tag_t*));
- hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GPOS, i, 0, &langCount, langList);
+ langCount = hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GPOS, i, 0, NULL, NULL);
+ langList = (hb_tag_t*) xcalloc(langCount, sizeof(hb_tag_t*));
+ hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GPOS, i, 0, &langCount, langList);
- if (index < langCount) {
- rval = langList[index];
- break;
- }
+ if (index < langCount) {
+ rval = langList[index];
+ break;
+ }
- free(langList);
- }
- }
- }
+ free(langList);
+ }
+ }
+ }
- return rval;
+ return rval;
}
unsigned int
countFeatures(XeTeXFont font, hb_tag_t script, hb_tag_t language)
{
- unsigned int rval = 0;
+ unsigned int rval = 0;
- hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
+ hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
- for (int i = 0; i < 2; ++i) {
- unsigned int scriptIndex, langIndex = 0;
- hb_tag_t tableTag = i == 0 ? HB_OT_TAG_GSUB : HB_OT_TAG_GPOS;
- if (hb_ot_layout_table_find_script(face, tableTag, script, &scriptIndex)) {
- if (hb_ot_layout_script_find_language(face, tableTag, scriptIndex, language, &langIndex) || language == 0) {
- rval += hb_ot_layout_language_get_feature_tags(face, tableTag, scriptIndex, langIndex, 0, NULL, NULL);
- }
- }
- }
+ for (int i = 0; i < 2; ++i) {
+ unsigned int scriptIndex, langIndex = 0;
+ hb_tag_t tableTag = i == 0 ? HB_OT_TAG_GSUB : HB_OT_TAG_GPOS;
+ if (hb_ot_layout_table_find_script(face, tableTag, script, &scriptIndex)) {
+ if (hb_ot_layout_script_find_language(face, tableTag, scriptIndex, language, &langIndex) || language == 0) {
+ rval += hb_ot_layout_language_get_feature_tags(face, tableTag, scriptIndex, langIndex, 0, NULL, NULL);
+ }
+ }
+ }
- return rval;
+ return rval;
}
hb_tag_t
getIndFeature(XeTeXFont font, hb_tag_t script, hb_tag_t language, unsigned int index)
{
- hb_tag_t rval = 0;
+ hb_tag_t rval = 0;
- hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
+ hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
- for (int i = 0; i < 2; ++i) {
- unsigned int scriptIndex, langIndex = 0;
- hb_tag_t tableTag = i == 0 ? HB_OT_TAG_GSUB : HB_OT_TAG_GPOS;
- if (hb_ot_layout_table_find_script(face, tableTag, script, &scriptIndex)) {
- if (hb_ot_layout_script_find_language(face, tableTag, scriptIndex, language, &langIndex) || language == 0) {
- unsigned int featCount = hb_ot_layout_language_get_feature_tags(face, tableTag, scriptIndex, langIndex, 0, NULL, NULL);
- hb_tag_t* featList = (hb_tag_t*) xmalloc(featCount * sizeof(hb_tag_t*));
- hb_ot_layout_language_get_feature_tags(face, tableTag, scriptIndex, langIndex, 0, &featCount, featList);
+ for (int i = 0; i < 2; ++i) {
+ unsigned int scriptIndex, langIndex = 0;
+ hb_tag_t tableTag = i == 0 ? HB_OT_TAG_GSUB : HB_OT_TAG_GPOS;
+ if (hb_ot_layout_table_find_script(face, tableTag, script, &scriptIndex)) {
+ if (hb_ot_layout_script_find_language(face, tableTag, scriptIndex, language, &langIndex) || language == 0) {
+ unsigned int featCount = hb_ot_layout_language_get_feature_tags(face, tableTag, scriptIndex, langIndex, 0, NULL, NULL);
+ hb_tag_t* featList = (hb_tag_t*) xcalloc(featCount, sizeof(hb_tag_t*));
+ hb_ot_layout_language_get_feature_tags(face, tableTag, scriptIndex, langIndex, 0, &featCount, featList);
- if (index < featCount) {
- rval = featList[index];
- break;
- }
+ if (index < featCount) {
+ rval = featList[index];
+ break;
+ }
- index -= featCount;
- }
- }
- }
+ index -= featCount;
+ }
+ }
+ }
- return rval;
+ return rval;
}
uint32_t
countGraphiteFeatures(XeTeXLayoutEngine engine)
{
- uint32_t rval = 0;
+ uint32_t rval = 0;
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
+ hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
+ gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- if (grFace != NULL)
- rval = gr_face_n_fref(grFace);
+ if (grFace != NULL)
+ rval = gr_face_n_fref(grFace);
- return rval;
+ return rval;
}
uint32_t
getGraphiteFeatureCode(XeTeXLayoutEngine engine, uint32_t index)
{
- uint32_t rval = 0;
+ uint32_t rval = 0;
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
+ hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
+ gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_fref(grFace, index);
- rval = gr_fref_id(feature);
- }
+ if (grFace != NULL) {
+ const gr_feature_ref* feature = gr_face_fref(grFace, index);
+ rval = gr_fref_id(feature);
+ }
- return rval;
+ return rval;
}
uint32_t
countGraphiteFeatureSettings(XeTeXLayoutEngine engine, uint32_t featureID)
{
- uint32_t rval = 0;
+ uint32_t rval = 0;
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
+ hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
+ gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
- rval = gr_fref_n_values(feature);
- }
+ if (grFace != NULL) {
+ const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
+ rval = gr_fref_n_values(feature);
+ }
- return rval;
+ return rval;
}
uint32_t
getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, uint32_t featureID, uint32_t index)
{
- uint32_t rval = 0;
+ uint32_t rval = 0;
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
+ hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
+ gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
- rval = gr_fref_value(feature, index);
- }
+ if (grFace != NULL) {
+ const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
+ rval = gr_fref_value(feature, index);
+ }
- return rval;
+ return rval;
}
+#define tag_from_lang(x) hb_tag_from_string(hb_language_to_string(x), strlen(hb_language_to_string(x)))
+
uint32_t
getGraphiteFeatureDefaultSetting(XeTeXLayoutEngine engine, uint32_t featureID)
{
- uint32_t rval = 0;
+ uint32_t rval = 0;
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
+ hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
+ gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
- gr_feature_val *featureValues = gr_face_featureval_for_lang (grFace, engine->language);
+ if (grFace != NULL) {
+ const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
+ gr_feature_val *featureValues = gr_face_featureval_for_lang (grFace, tag_from_lang(engine->language));
- rval = gr_fref_feature_value(feature, featureValues);
- }
+ rval = gr_fref_feature_value(feature, featureValues);
+ }
- return rval;
+ return rval;
}
char *
getGraphiteFeatureLabel(XeTeXLayoutEngine engine, uint32_t featureID)
{
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
+ hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
+ gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
- uint32_t len = 0;
- uint16_t langID = 0x409;
+ if (grFace != NULL) {
+ const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
+ uint32_t len = 0;
+ uint16_t langID = 0x409;
- return (char *) gr_fref_label(feature, &langID, gr_utf8, &len);
- }
+ return (char *) gr_fref_label(feature, &langID, gr_utf8, &len);
+ }
- return NULL;
+ return NULL;
}
char *
getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, uint32_t featureID, uint32_t settingID)
{
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
+ hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
+ gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
- for (int i = 0; i < gr_fref_n_values(feature); i++) {
- if (settingID == gr_fref_value(feature, i)) {
- uint32_t len = 0;
- uint16_t langID = 0x409;
+ if (grFace != NULL) {
+ const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
+ for (int i = 0; i < gr_fref_n_values(feature); i++) {
+ if (settingID == gr_fref_value(feature, i)) {
+ uint32_t len = 0;
+ uint16_t langID = 0x409;
- return (char *) gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
- }
- }
- }
+ return (char *) gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
+ }
+ }
+ }
- return NULL;
+ return NULL;
}
bool
findGraphiteFeature(XeTeXLayoutEngine engine, const char* s, const char* e, hb_tag_t* f, int* v)
- /* s...e is a "feature=setting" string; look for this in the font */
+ /* s...e is a "feature=setting" string; look for this in the font */
{
- *f = 0;
- *v = 0;
- while (*s == ' ' || *s == '\t')
- ++s;
- const char* cp = s;
- while (cp < e && *cp != '=')
- ++cp;
+ *f = 0;
+ *v = 0;
+ while (*s == ' ' || *s == '\t')
+ ++s;
+ const char* cp = s;
+ while (cp < e && *cp != '=')
+ ++cp;
- *f = findGraphiteFeatureNamed(engine, s, cp - s);
- if (*f == -1)
- return false;
+ *f = findGraphiteFeatureNamed(engine, s, cp - s);
+ if (*f == -1)
+ return false;
- ++cp;
- while (cp < e && (*cp == ' ' || *cp == '\t'))
- ++cp;
+ ++cp;
+ while (cp < e && (*cp == ' ' || *cp == '\t'))
+ ++cp;
- if (cp == e)
- /* no setting was specified */
- return false;
+ if (cp == e)
+ /* no setting was specified */
+ return false;
- *v = findGraphiteFeatureSettingNamed(engine, *f, cp, e - cp);
- if (*v == -1)
- return false;
+ *v = findGraphiteFeatureSettingNamed(engine, *f, cp, e - cp);
+ if (*v == -1)
+ return false;
- return true;
+ return true;
}
long
findGraphiteFeatureNamed(XeTeXLayoutEngine engine, const char* name, int namelength)
{
- long rval = -1;
+ long rval = -1;
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
+ hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
+ gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- if (grFace != NULL) {
- for (int i = 0; i < gr_face_n_fref(grFace); i++) {
- const gr_feature_ref* feature = gr_face_fref(grFace, i);
- uint32_t len = 0;
- uint16_t langID = 0x409;
+ if (grFace != NULL) {
+ for (int i = 0; i < gr_face_n_fref(grFace); i++) {
+ const gr_feature_ref* feature = gr_face_fref(grFace, i);
+ uint32_t len = 0;
+ uint16_t langID = 0x409;
- // the first call is to get the length of the string
- gr_fref_label(feature, &langID, gr_utf8, &len);
- char* label = (char*) xmalloc(len);
- label = (char*) gr_fref_label(feature, &langID, gr_utf8, &len);
+ // the first call is to get the length of the string
+ gr_fref_label(feature, &langID, gr_utf8, &len);
+ char* label = (char*) xmalloc(len);
+ label = (char*) gr_fref_label(feature, &langID, gr_utf8, &len);
- if (strncmp(label, name, namelength) == 0) {
- rval = gr_fref_id(feature);
- gr_label_destroy(label);
- break;
- }
+ if (strncmp(label, name, namelength) == 0) {
+ rval = gr_fref_id(feature);
+ gr_label_destroy(label);
+ break;
+ }
- gr_label_destroy(label);
- }
- }
+ gr_label_destroy(label);
+ }
+ }
- return rval;
+ return rval;
}
long
findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, uint32_t id, const char* name, int namelength)
{
- long rval = -1;
+ long rval = -1;
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
+ hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
+ gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, id);
- for (int i = 0; i < gr_fref_n_values(feature); i++) {
- uint32_t len = 0;
- uint16_t langID = 0x409;
+ if (grFace != NULL) {
+ const gr_feature_ref* feature = gr_face_find_fref(grFace, id);
+ for (int i = 0; i < gr_fref_n_values(feature); i++) {
+ uint32_t len = 0;
+ uint16_t langID = 0x409;
- // the first call is to get the length of the string
- gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
- char* label = (char*) xmalloc(len);
- label = (char*) gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
+ // the first call is to get the length of the string
+ gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
+ char* label = (char*) xmalloc(len);
+ label = (char*) gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
- if (strncmp(label, name, namelength) == 0) {
- rval = gr_fref_value(feature, i);
- gr_label_destroy(label);
- break;
- }
+ if (strncmp(label, name, namelength) == 0) {
+ rval = gr_fref_value(feature, i);
+ gr_label_destroy(label);
+ break;
+ }
- gr_label_destroy(label);
- }
- }
+ gr_label_destroy(label);
+ }
+ }
- return rval;
+ return rval;
}
float
getGlyphWidth(XeTeXFont font, uint32_t gid)
{
- return ((XeTeXFontInst*)font)->getGlyphWidth(gid);
+ return ((XeTeXFontInst*)font)->getGlyphWidth(gid);
}
unsigned int
countGlyphs(XeTeXFont font)
{
- return ((XeTeXFontInst*)font)->getNumGlyphs();
+ return ((XeTeXFontInst*)font)->getNumGlyphs();
}
XeTeXFont
getFont(XeTeXLayoutEngine engine)
{
- return (XeTeXFont)(engine->font);
+ return (XeTeXFont)(engine->font);
}
float
getExtendFactor(XeTeXLayoutEngine engine)
{
- return engine->extend;
+ return engine->extend;
}
float
getSlantFactor(XeTeXLayoutEngine engine)
{
- return engine->slant;
+ return engine->slant;
}
float
getEmboldenFactor(XeTeXLayoutEngine engine)
{
- return engine->embolden;
+ return engine->embolden;
}
XeTeXLayoutEngine
-createLayoutEngine(PlatformFontRef fontRef, XeTeXFont font, hb_tag_t script, hb_tag_t language,
- hb_feature_t* features, int nFeatures, char **shapers, uint32_t rgbValue,
- float extend, float slant, float embolden)
-{
- XeTeXLayoutEngine result = new XeTeXLayoutEngine_rec;
- result->fontRef = fontRef;
- result->font = (XeTeXFontInst*)font;
- result->script = script;
- result->language = language;
- result->features = features;
- result->ShaperList = shapers;
- result->shaper = NULL;
- result->nFeatures = nFeatures;
- result->rgbValue = rgbValue;
- result->extend = extend;
- result->slant = slant;
- result->embolden = embolden;
- result->hbBuffer = hb_buffer_create();
-
- return result;
+createLayoutEngine(PlatformFontRef fontRef, XeTeXFont font, hb_tag_t script, char *language,
+ hb_feature_t* features, int nFeatures, char **shapers, uint32_t rgbValue,
+ float extend, float slant, float embolden)
+{
+ XeTeXLayoutEngine result = new XeTeXLayoutEngine_rec;
+ result->fontRef = fontRef;
+ result->font = (XeTeXFontInst*)font;
+ result->script = script;
+ result->features = features;
+ result->ShaperList = shapers;
+ result->shaper = NULL;
+ result->nFeatures = nFeatures;
+ result->rgbValue = rgbValue;
+ result->extend = extend;
+ result->slant = slant;
+ result->embolden = embolden;
+ result->hbBuffer = hb_buffer_create();
+
+ // For Graphite fonts treat the language as BCP 47 tag, for OpenType we
+ // treat it as a OT language tag for backward compatibility with pre-0.9999
+ // XeTeX.
+ if (getReqEngine() == 'G')
+ result->language = hb_language_from_string(language, -1);
+ else
+ result->language = hb_ot_tag_to_language(hb_tag_from_string(language, -1));
+
+ free(language);
+
+ return result;
}
void
deleteLayoutEngine(XeTeXLayoutEngine engine)
{
- hb_buffer_destroy(engine->hbBuffer);
- delete engine->font;
+ hb_buffer_destroy(engine->hbBuffer);
+ delete engine->font;
+ free(engine->shaper);
+}
+
+static unsigned int
+_decompose_compat(hb_unicode_funcs_t* ufuncs,
+ hb_codepoint_t u,
+ hb_codepoint_t* decomposed,
+ void* user_data)
+{
+ return 0;
+}
+
+static hb_unicode_funcs_t*
+_get_unicode_funcs(void)
+{
+ static hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_create(hb_icu_get_unicode_funcs());
+ hb_unicode_funcs_set_decompose_compatibility_func(ufuncs, _decompose_compat, NULL, NULL);
+ return ufuncs;
}
+static hb_unicode_funcs_t* hbUnicodeFuncs = NULL;
+
int
layoutChars(XeTeXLayoutEngine engine, uint16_t chars[], int32_t offset, int32_t count, int32_t max,
- bool rightToLeft)
-{
- bool res;
- hb_script_t script = HB_SCRIPT_INVALID;
- hb_language_t language = HB_LANGUAGE_INVALID;
- hb_direction_t direction = HB_DIRECTION_LTR;
- hb_segment_properties_t segment_props;
- hb_shape_plan_t *shape_plan;
- hb_font_t* hbFont = engine->font->getHbFont();
- hb_face_t* hbFace = hb_font_get_face(hbFont);
-
- if (engine->font->getLayoutDirVertical())
- direction = HB_DIRECTION_TTB;
- else if (rightToLeft)
- direction = HB_DIRECTION_RTL;
-
- script = hb_ot_tag_to_script (engine->script);
- language = hb_ot_tag_to_language (engine->language);
-
- hb_buffer_reset(engine->hbBuffer);
- hb_buffer_add_utf16(engine->hbBuffer, chars, max, offset, count);
- hb_buffer_set_direction(engine->hbBuffer, direction);
- hb_buffer_set_script(engine->hbBuffer, script);
- hb_buffer_set_language(engine->hbBuffer, language);
-
- hb_buffer_guess_segment_properties(engine->hbBuffer);
- hb_buffer_get_segment_properties(engine->hbBuffer, &segment_props);
-
- shape_plan = hb_shape_plan_create_cached(hbFace, &segment_props, engine->features, engine->nFeatures, engine->ShaperList);
- res = hb_shape_plan_execute(shape_plan, hbFont, engine->hbBuffer, engine->features, engine->nFeatures);
-
- if (res) {
- engine->shaper = strdup(hb_shape_plan_get_shaper(shape_plan));
- hb_buffer_set_content_type(engine->hbBuffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
- } else {
- // all selected shapers failed, retrying with default
- // we don't use _cached here as the cached plain will always fail.
- hb_shape_plan_destroy(shape_plan);
- shape_plan = hb_shape_plan_create(hbFace, &segment_props, engine->features, engine->nFeatures, NULL);
- res = hb_shape_plan_execute(shape_plan, hbFont, engine->hbBuffer, engine->features, engine->nFeatures);
-
- if (res) {
- engine->shaper = strdup(hb_shape_plan_get_shaper(shape_plan));
- hb_buffer_set_content_type(engine->hbBuffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
- } else {
- fprintf(stderr, "\nERROR: all shapers failed\n");
- exit(3);
- }
- }
+ bool rightToLeft)
+{
+ bool res;
+ hb_script_t script = HB_SCRIPT_INVALID;
+ hb_direction_t direction = HB_DIRECTION_LTR;
+ hb_segment_properties_t segment_props;
+ hb_shape_plan_t *shape_plan;
+ hb_font_t* hbFont = engine->font->getHbFont();
+ hb_face_t* hbFace = hb_font_get_face(hbFont);
+
+ if (engine->font->getLayoutDirVertical())
+ direction = HB_DIRECTION_TTB;
+ else if (rightToLeft)
+ direction = HB_DIRECTION_RTL;
+
+ script = hb_ot_tag_to_script (engine->script);
+
+ if (hbUnicodeFuncs == NULL)
+ hbUnicodeFuncs = _get_unicode_funcs();
+
+ hb_buffer_reset(engine->hbBuffer);
+ hb_buffer_set_unicode_funcs(engine->hbBuffer, hbUnicodeFuncs);
+ hb_buffer_add_utf16(engine->hbBuffer, chars, max, offset, count);
+ hb_buffer_set_direction(engine->hbBuffer, direction);
+ hb_buffer_set_script(engine->hbBuffer, script);
+ hb_buffer_set_language(engine->hbBuffer, engine->language);
+
+ hb_buffer_guess_segment_properties(engine->hbBuffer);
+ hb_buffer_get_segment_properties(engine->hbBuffer, &segment_props);
+
+ if (engine->ShaperList == NULL) {
+ // HarfBuzz gives graphite2 shaper a priority, so that for hybrid
+ // Graphite/OpenType fonts, Graphite will be used. However, pre-0.9999
+ // XeTeX preferred OpenType over Graphite, so we are doing the same
+ // here for sake of backward compatibility.
+ engine->ShaperList = (char**) xcalloc(4, sizeof(char*));
+ engine->ShaperList[0] = (char*) "ot";
+ engine->ShaperList[1] = (char*) "graphite2";
+ engine->ShaperList[2] = (char*) "fallback";
+ engine->ShaperList[3] = NULL;
+ }
- hb_shape_plan_destroy(shape_plan);
+ shape_plan = hb_shape_plan_create_cached(hbFace, &segment_props, engine->features, engine->nFeatures, engine->ShaperList);
+ res = hb_shape_plan_execute(shape_plan, hbFont, engine->hbBuffer, engine->features, engine->nFeatures);
+
+ if (res) {
+ engine->shaper = strdup(hb_shape_plan_get_shaper(shape_plan));
+ hb_buffer_set_content_type(engine->hbBuffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
+ } else {
+ // all selected shapers failed, retrying with default
+ // we don't use _cached here as the cached plain will always fail.
+ hb_shape_plan_destroy(shape_plan);
+ shape_plan = hb_shape_plan_create(hbFace, &segment_props, engine->features, engine->nFeatures, NULL);
+ res = hb_shape_plan_execute(shape_plan, hbFont, engine->hbBuffer, engine->features, engine->nFeatures);
+
+ if (res) {
+ engine->shaper = strdup(hb_shape_plan_get_shaper(shape_plan));
+ hb_buffer_set_content_type(engine->hbBuffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
+ } else {
+ fprintf(stderr, "\nERROR: all shapers failed\n");
+ exit(3);
+ }
+ }
+
+ hb_shape_plan_destroy(shape_plan);
- int glyphCount = hb_buffer_get_length(engine->hbBuffer);
+ int glyphCount = hb_buffer_get_length(engine->hbBuffer);
#ifdef DEBUG
- char buf[1024];
- unsigned int consumed;
+ char buf[1024];
+ unsigned int consumed;
- printf ("shaper: %s\n", engine->shaper);
+ printf ("shaper: %s\n", engine->shaper);
- hb_buffer_serialize_flags_t flags = HB_BUFFER_SERIALIZE_FLAGS_DEFAULT;
- hb_buffer_serialize_format_t format = HB_BUFFER_SERIALIZE_FORMAT_JSON;
+ hb_buffer_serialize_flags_t flags = HB_BUFFER_SERIALIZE_FLAGS_DEFAULT;
+ hb_buffer_serialize_format_t format = HB_BUFFER_SERIALIZE_FORMAT_JSON;
- hb_buffer_serialize_glyphs (engine->hbBuffer, 0, glyphCount, buf, sizeof(buf), &consumed, hbFont, format, flags);
- if (consumed)
- printf ("buffer glyphs: %s\n", buf);
+ hb_buffer_serialize_glyphs (engine->hbBuffer, 0, glyphCount, buf, sizeof(buf), &consumed, hbFont, format, flags);
+ if (consumed)
+ printf ("buffer glyphs: %s\n", buf);
#endif
- return glyphCount;
+ return glyphCount;
}
void
getGlyphs(XeTeXLayoutEngine engine, uint32_t glyphs[])
{
- int glyphCount = hb_buffer_get_length(engine->hbBuffer);
- hb_glyph_info_t *hbGlyphs = hb_buffer_get_glyph_infos(engine->hbBuffer, NULL);
+ int glyphCount = hb_buffer_get_length(engine->hbBuffer);
+ hb_glyph_info_t *hbGlyphs = hb_buffer_get_glyph_infos(engine->hbBuffer, NULL);
- for (int i = 0; i < glyphCount; i++)
- glyphs[i] = hbGlyphs[i].codepoint;
+ for (int i = 0; i < glyphCount; i++)
+ glyphs[i] = hbGlyphs[i].codepoint;
}
void
getGlyphAdvances(XeTeXLayoutEngine engine, float advances[])
{
- int glyphCount = hb_buffer_get_length(engine->hbBuffer);
- hb_glyph_position_t *hbPositions = hb_buffer_get_glyph_positions(engine->hbBuffer, NULL);
+ int glyphCount = hb_buffer_get_length(engine->hbBuffer);
+ hb_glyph_position_t *hbPositions = hb_buffer_get_glyph_positions(engine->hbBuffer, NULL);
- for (int i = 0; i < glyphCount; i++) {
- if (engine->font->getLayoutDirVertical())
- advances[i] = engine->font->unitsToPoints(hbPositions[i].y_advance);
- else
- advances[i] = engine->font->unitsToPoints(hbPositions[i].x_advance);
- }
+ for (int i = 0; i < glyphCount; i++) {
+ if (engine->font->getLayoutDirVertical())
+ advances[i] = engine->font->unitsToPoints(hbPositions[i].y_advance);
+ else
+ advances[i] = engine->font->unitsToPoints(hbPositions[i].x_advance);
+ }
}
void
getGlyphPositions(XeTeXLayoutEngine engine, float positions[])
{
- int glyphCount = hb_buffer_get_length(engine->hbBuffer);
- hb_glyph_position_t *hbPositions = hb_buffer_get_glyph_positions(engine->hbBuffer, NULL);
-
- int i = 0;
- float x = 0, y = 0;
-
- if (engine->font->getLayoutDirVertical()) {
- for (i = 0; i < glyphCount; i++) {
- positions[2*i] = - engine->font->unitsToPoints(x + hbPositions[i].y_offset); /* negative is forwards */
- positions[2*i+1] = engine->font->unitsToPoints(y - hbPositions[i].x_offset);
- x += hbPositions[i].y_advance;
- y += hbPositions[i].x_advance;
- }
- positions[2*i] = - engine->font->unitsToPoints(x);
- positions[2*i+1] = engine->font->unitsToPoints(y);
- } else {
- for (i = 0; i < glyphCount; i++) {
- positions[2*i] = engine->font->unitsToPoints(x + hbPositions[i].x_offset);
- positions[2*i+1] = - engine->font->unitsToPoints(y + hbPositions[i].y_offset); /* negative is upwards */
- x += hbPositions[i].x_advance;
- y += hbPositions[i].y_advance;
- }
- positions[2*i] = engine->font->unitsToPoints(x);
- positions[2*i+1] = - engine->font->unitsToPoints(y);
- }
+ int glyphCount = hb_buffer_get_length(engine->hbBuffer);
+ hb_glyph_position_t *hbPositions = hb_buffer_get_glyph_positions(engine->hbBuffer, NULL);
+
+ int i = 0;
+ float x = 0, y = 0;
+
+ if (engine->font->getLayoutDirVertical()) {
+ for (i = 0; i < glyphCount; i++) {
+ positions[2*i] = - engine->font->unitsToPoints(x + hbPositions[i].y_offset); /* negative is forwards */
+ positions[2*i+1] = engine->font->unitsToPoints(y - hbPositions[i].x_offset);
+ x += hbPositions[i].y_advance;
+ y += hbPositions[i].x_advance;
+ }
+ positions[2*i] = - engine->font->unitsToPoints(x);
+ positions[2*i+1] = engine->font->unitsToPoints(y);
+ } else {
+ for (i = 0; i < glyphCount; i++) {
+ positions[2*i] = engine->font->unitsToPoints(x + hbPositions[i].x_offset);
+ positions[2*i+1] = - engine->font->unitsToPoints(y + hbPositions[i].y_offset); /* negative is upwards */
+ x += hbPositions[i].x_advance;
+ y += hbPositions[i].y_advance;
+ }
+ positions[2*i] = engine->font->unitsToPoints(x);
+ positions[2*i+1] = - engine->font->unitsToPoints(y);
+ }
- if (engine->extend != 1.0 || engine->slant != 0.0)
- for (int i = 0; i <= glyphCount; ++i)
- positions[2*i] = positions[2*i] * engine->extend - positions[2*i+1] * engine->slant;
+ if (engine->extend != 1.0 || engine->slant != 0.0)
+ for (int i = 0; i <= glyphCount; ++i)
+ positions[2*i] = positions[2*i] * engine->extend - positions[2*i+1] * engine->slant;
}
float
getPointSize(XeTeXLayoutEngine engine)
{
- return engine->font->getPointSize();
+ return engine->font->getPointSize();
}
void
getAscentAndDescent(XeTeXLayoutEngine engine, float* ascent, float* descent)
{
- *ascent = engine->font->getAscent();
- *descent = engine->font->getDescent();
+ *ascent = engine->font->getAscent();
+ *descent = engine->font->getDescent();
}
void
getCapAndXHeight(XeTeXLayoutEngine engine, float* capheight, float* xheight)
{
- *capheight = engine->font->getCapHeight();
- *xheight = engine->font->getXHeight();
+ *capheight = engine->font->getCapHeight();
+ *xheight = engine->font->getXHeight();
}
int
getDefaultDirection(XeTeXLayoutEngine engine)
{
- hb_script_t script = hb_buffer_get_script(engine->hbBuffer);
- if (hb_script_get_horizontal_direction (script) == HB_DIRECTION_RTL)
- return UBIDI_DEFAULT_RTL;
- else
- return UBIDI_DEFAULT_LTR;
+ hb_script_t script = hb_buffer_get_script(engine->hbBuffer);
+ if (hb_script_get_horizontal_direction (script) == HB_DIRECTION_RTL)
+ return UBIDI_DEFAULT_RTL;
+ else
+ return UBIDI_DEFAULT_LTR;
}
uint32_t
getRgbValue(XeTeXLayoutEngine engine)
{
- return engine->rgbValue;
+ return engine->rgbValue;
}
void
getGlyphBounds(XeTeXLayoutEngine engine, uint32_t glyphID, GlyphBBox* bbox)
{
- engine->font->getGlyphBounds(glyphID, bbox);
- if (engine->extend != 0.0) {
- bbox->xMin *= engine->extend;
- bbox->xMax *= engine->extend;
+ engine->font->getGlyphBounds(glyphID, bbox);
+ if (engine->extend != 0.0) {
+ bbox->xMin *= engine->extend;
+ bbox->xMax *= engine->extend;
}
}
float
getGlyphWidthFromEngine(XeTeXLayoutEngine engine, uint32_t glyphID)
{
- return engine->extend * engine->font->getGlyphWidth(glyphID);
+ return engine->extend * engine->font->getGlyphWidth(glyphID);
}
void
getGlyphHeightDepth(XeTeXLayoutEngine engine, uint32_t glyphID, float* height, float* depth)
{
- engine->font->getGlyphHeightDepth(glyphID, height, depth);
+ engine->font->getGlyphHeightDepth(glyphID, height, depth);
}
void
getGlyphSidebearings(XeTeXLayoutEngine engine, uint32_t glyphID, float* lsb, float* rsb)
{
- engine->font->getGlyphSidebearings(glyphID, lsb, rsb);
- if (engine->extend != 0.0) {
- *lsb *= engine->extend;
- *rsb *= engine->extend;
- }
+ engine->font->getGlyphSidebearings(glyphID, lsb, rsb);
+ if (engine->extend != 0.0) {
+ *lsb *= engine->extend;
+ *rsb *= engine->extend;
+ }
}
float
getGlyphItalCorr(XeTeXLayoutEngine engine, uint32_t glyphID)
{
- return engine->extend * engine->font->getGlyphItalCorr(glyphID);
+ return engine->extend * engine->font->getGlyphItalCorr(glyphID);
}
uint32_t
mapCharToGlyph(XeTeXLayoutEngine engine, uint32_t charCode)
{
- return engine->font->mapCharToGlyph(charCode);
+ return engine->font->mapCharToGlyph(charCode);
}
int
getFontCharRange(XeTeXLayoutEngine engine, int reqFirst)
{
- if (reqFirst)
- return engine->font->getFirstCharCode();
- else
- return engine->font->getLastCharCode();
+ if (reqFirst)
+ return engine->font->getFirstCharCode();
+ else
+ return engine->font->getLastCharCode();
}
const char*
getGlyphName(XeTeXFont font, uint16_t gid, int* len)
{
- return ((XeTeXFontInst*)font)->getGlyphName(gid, *len);
+ return ((XeTeXFontInst*)font)->getGlyphName(gid, *len);
}
int
mapGlyphToIndex(XeTeXLayoutEngine engine, const char* glyphName)
{
- return engine->font->mapGlyphToIndex(glyphName);
+ return engine->font->mapGlyphToIndex(glyphName);
}
static gr_segment* grSegment = NULL;
@@ -892,95 +950,110 @@ static int grTextLen;
bool
initGraphiteBreaking(XeTeXLayoutEngine engine, const uint16_t* txtPtr, int txtLen)
{
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- gr_font* grFont = hb_graphite2_font_get_gr_font(engine->font->getHbFont());
- if (grFace != NULL && grFont != NULL) {
- if (grSegment != NULL) {
- gr_seg_destroy(grSegment);
- grSegment = NULL;
- grPrevSlot = NULL;
- }
-
- gr_feature_val *grFeatureValues = gr_face_featureval_for_lang (grFace, engine->language);
-
- int nFeatures = engine->nFeatures;
- hb_feature_t *features = engine->features;
- while (nFeatures--) {
- const gr_feature_ref *fref = gr_face_find_fref (grFace, features->tag);
- if (fref)
- gr_fref_set_feature_value (fref, features->value, grFeatureValues);
- features++;
- }
-
- grSegment = gr_make_seg(grFont, grFace, engine->script, grFeatureValues, gr_utf16, txtPtr, txtLen, 0);
- grPrevSlot = gr_seg_first_slot(grSegment);
- grTextLen = txtLen;
-
- return true;
- }
+ hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
+ gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
+ gr_font* grFont = hb_graphite2_font_get_gr_font(engine->font->getHbFont());
+ if (grFace != NULL && grFont != NULL) {
+ if (grSegment != NULL) {
+ gr_seg_destroy(grSegment);
+ grSegment = NULL;
+ grPrevSlot = NULL;
+ }
+
+ gr_feature_val *grFeatureValues = gr_face_featureval_for_lang (grFace, tag_from_lang(engine->language));
+
+ int nFeatures = engine->nFeatures;
+ hb_feature_t *features = engine->features;
+ while (nFeatures--) {
+ const gr_feature_ref *fref = gr_face_find_fref (grFace, features->tag);
+ if (fref)
+ gr_fref_set_feature_value (fref, features->value, grFeatureValues);
+ features++;
+ }
+
+ grSegment = gr_make_seg(grFont, grFace, engine->script, grFeatureValues, gr_utf16, txtPtr, txtLen, 0);
+ grPrevSlot = gr_seg_first_slot(grSegment);
+ grTextLen = txtLen;
+
+ return true;
+ }
- return false;
+ return false;
}
int
findNextGraphiteBreak(void)
{
- int ret = -1;
-
- if (grSegment != NULL) {
- if (grPrevSlot && grPrevSlot != gr_seg_last_slot(grSegment)) {
- for (const gr_slot* s = gr_slot_next_in_segment(grPrevSlot); s != NULL; s = gr_slot_next_in_segment(s)) {
- const gr_char_info* ci = NULL;
- int bw;
-
- ci = gr_seg_cinfo(grSegment, gr_slot_index(s));
- bw = gr_cinfo_break_weight(ci);
- if (bw < gr_breakNone && bw >= gr_breakBeforeWord) {
- grPrevSlot = s;
- ret = gr_cinfo_base(ci);
- } else if (bw > gr_breakNone && bw <= gr_breakWord) {
- grPrevSlot = gr_slot_next_in_segment(s);
- ret = gr_cinfo_base(ci) + 1;
- }
-
- if (ret != -1)
- break;
- }
-
- if (ret == -1) {
- grPrevSlot = gr_seg_last_slot(grSegment);
- ret = grTextLen;
- }
- }
- }
+ int ret = -1;
+
+ if (grSegment != NULL) {
+ if (grPrevSlot && grPrevSlot != gr_seg_last_slot(grSegment)) {
+ for (const gr_slot* s = gr_slot_next_in_segment(grPrevSlot); s != NULL; s = gr_slot_next_in_segment(s)) {
+ const gr_char_info* ci = NULL;
+ int bw;
+
+ ci = gr_seg_cinfo(grSegment, gr_slot_index(s));
+ bw = gr_cinfo_break_weight(ci);
+ if (bw < gr_breakNone && bw >= gr_breakBeforeWord) {
+ grPrevSlot = s;
+ ret = gr_cinfo_base(ci);
+ } else if (bw > gr_breakNone && bw <= gr_breakWord) {
+ grPrevSlot = gr_slot_next_in_segment(s);
+ ret = gr_cinfo_base(ci) + 1;
+ }
+
+ if (ret != -1)
+ break;
+ }
+
+ if (ret == -1) {
+ grPrevSlot = gr_seg_last_slot(grSegment);
+ ret = grTextLen;
+ }
+ }
+ }
- return ret;
+ return ret;
}
bool
-usingGraphite(XeTeXLayoutEngine engine)
+usingGraphite(int font)
{
- if (engine->shaper != NULL && (strcmp("graphite2", engine->shaper) == 0))
- return true;
- else
- return false;
+ bool ret = false;
+ if (fontarea[font] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
+ if (engine->shaper != NULL && (strcmp("graphite2", engine->shaper) == 0)) {
+ ret = true;
+ }
+ }
+
+ return ret;
}
bool
-usingOpenType(XeTeXLayoutEngine engine)
+usingOpenType(int font)
{
- if (engine->shaper == NULL || (strcmp("ot", engine->shaper) == 0))
- return true;
- else
- return false;
+ bool ret = false;
+ if (fontarea[font] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
+ if (engine->shaper == NULL || (strcmp("ot", engine->shaper) == 0)) {
+ ret = true;
+ }
+ }
+
+ return ret;
}
bool
-isOpenTypeMathFont(XeTeXLayoutEngine engine)
+isOpenTypeMathFont(int font)
{
- if (engine->font->getMathTable() != NULL)
- return true;
- else
- return false;
+ bool ret = false;
+ if (fontarea[font] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
+ if (engine->font->getMathTable() != NULL) {
+ ret = true;
+ }
+ }
+
+ return ret;
}
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h
index 4b2b8e2dde3..d7f598f8f58 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.h
@@ -48,12 +48,6 @@ typedef struct XeTeXLayoutEngine_rec* XeTeXLayoutEngine;
#include FT_TRUETYPE_TABLES_H
#include <hb.h>
-#include <hb-ot.h>
-#include <hb-icu.h>
-
-#include <graphite2/Font.h>
-#include <graphite2/Segment.h>
-#include <hb-graphite2.h>
#include "XeTeX_ext.h"
#include "XeTeXFontMgr.h"
@@ -62,7 +56,7 @@ typedef struct XeTeXLayoutEngine_rec* XeTeXLayoutEngine;
extern "C" {
#endif
-extern char gPrefEngine;
+extern char gPrefEngine;
int getCachedGlyphBBox(uint16_t fontID, uint16_t glyphID, GlyphBBox* bbox);
void cacheGlyphBBox(uint16_t fontID, uint16_t glyphID, const GlyphBBox* bbox);
@@ -102,9 +96,9 @@ hb_tag_t getIndFeature(XeTeXFont font, hb_tag_t script, hb_tag_t language, unsig
float getGlyphWidth(XeTeXFont font, uint32_t gid);
-XeTeXLayoutEngine createLayoutEngine(PlatformFontRef fontRef, XeTeXFont font, hb_tag_t script, hb_tag_t language,
- hb_feature_t* features, int nFeatures, char **shapers, uint32_t rgbValue,
- float extend, float slant, float embolden);
+XeTeXLayoutEngine createLayoutEngine(PlatformFontRef fontRef, XeTeXFont font, hb_tag_t script, char *language,
+ hb_feature_t* features, int nFeatures, char **shapers, uint32_t rgbValue,
+ float extend, float slant, float embolden);
void deleteLayoutEngine(XeTeXLayoutEngine engine);
@@ -116,7 +110,7 @@ float getSlantFactor(XeTeXLayoutEngine engine);
float getEmboldenFactor(XeTeXLayoutEngine engine);
int layoutChars(XeTeXLayoutEngine engine, uint16_t* chars, int32_t offset, int32_t count, int32_t max,
- bool rightToLeft);
+ bool rightToLeft);
void getGlyphs(XeTeXLayoutEngine engine, uint32_t* glyphs);
void getGlyphAdvances(XeTeXLayoutEngine engine, float *advances);
@@ -143,7 +137,7 @@ float getGlyphItalCorr(XeTeXLayoutEngine engine, uint32_t glyphID);
uint32_t mapCharToGlyph(XeTeXLayoutEngine engine, uint32_t charCode);
-int mapGlyphToIndex(XeTeXLayoutEngine engine, const char* glyphName);
+int mapGlyphToIndex(XeTeXLayoutEngine engine, const char* glyphName);
const char* getGlyphName(XeTeXFont font, uint16_t gid, int* len);
@@ -153,9 +147,9 @@ int getFontCharRange(XeTeXLayoutEngine engine, int reqFirst);
bool initGraphiteBreaking(XeTeXLayoutEngine engine, const uint16_t* txtPtr, int txtLen);
int findNextGraphiteBreak(void);
-bool usingOpenType(XeTeXLayoutEngine engine);
-bool usingGraphite(XeTeXLayoutEngine engine);
-bool isOpenTypeMathFont(XeTeXLayoutEngine engine);
+bool usingOpenType(int);
+bool usingGraphite(int);
+bool isOpenTypeMathFont(int);
bool findGraphiteFeature(XeTeXLayoutEngine engine, const char* s, const char* e, hb_tag_t* f, int* v);
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp b/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp
index 3f43d6272c5..f66a23c6fe6 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXOTMath.cpp
@@ -48,455 +48,455 @@ extern "C" {
#include "XeTeXFontInst.h"
#include "XeTeXswap.h"
-typedef void* voidptr;
+typedef void* voidptr;
extern "C" {
- extern voidptr* fontlayoutengine;
- extern integer* fontarea;
- extern integer* fontsize;
+ extern voidptr* fontlayoutengine;
+ extern integer* fontarea;
+ extern integer* fontsize;
}
static int32_t getCoverage(const Coverage* coverage, GlyphID g)
{
- if (SWAP(coverage->format) == 1) {
- const CoverageFormat1 *table = (const CoverageFormat1 *) coverage;
- for (int i = 0; i < SWAP(table->glyphCount); i++) {
- if (SWAP(table->glyphArray[i]) == g)
- return i;
- }
- } else if (SWAP(coverage->format) == 2) {
- const CoverageFormat2 *table = (const CoverageFormat2 *) coverage;
- for (int i = 0; i < SWAP(table->rangeCount); i++) {
- if (SWAP(table->rangeArray[i].start) <= g && SWAP(table->rangeArray[i].end) >= g)
- return SWAP(table->rangeArray[i].startCoverageIndex) + (g - SWAP(table->rangeArray[i].start));
- }
- }
-
- return -1;
+ if (SWAP(coverage->format) == 1) {
+ const CoverageFormat1 *table = (const CoverageFormat1 *) coverage;
+ for (int i = 0; i < SWAP(table->glyphCount); i++) {
+ if (SWAP(table->glyphArray[i]) == g)
+ return i;
+ }
+ } else if (SWAP(coverage->format) == 2) {
+ const CoverageFormat2 *table = (const CoverageFormat2 *) coverage;
+ for (int i = 0; i < SWAP(table->rangeCount); i++) {
+ if (SWAP(table->rangeArray[i].start) <= g && SWAP(table->rangeArray[i].end) >= g)
+ return SWAP(table->rangeArray[i].startCoverageIndex) + (g - SWAP(table->rangeArray[i].start));
+ }
+ }
+
+ return -1;
}
static int16_t getMathConstant(XeTeXFontInst* fontInst, mathConstantIndex whichConstant)
{
- const char* table = fontInst->getMathTable();
- if (table == NULL)
- return 0;
-
- const uint16_t* constants = (const uint16_t*)(table + SWAP(((const MathTableHeader*)table)->mathConstants));
-
- if (whichConstant < firstMathValueRecord) {
- /* it's a simple 16-bit value */
- return SWAP(constants[whichConstant]);
- }
- else if (whichConstant <= lastMathValueRecord) {
- const MathValueRecord* valueRecords = (const MathValueRecord*)
- ((char*)constants + firstMathValueRecord * sizeof(uint16_t) - firstMathValueRecord * sizeof(MathValueRecord));
- return SWAP(valueRecords[whichConstant].value);
- }
- else if (whichConstant <= lastMathConstant) {
- return SWAP(constants[whichConstant + (lastMathValueRecord - firstMathValueRecord + 1)]);
- }
- else
- return 0; /* or abort, with "internal error" or something */
+ const char* table = fontInst->getMathTable();
+ if (table == NULL)
+ return 0;
+
+ const uint16_t* constants = (const uint16_t*)(table + SWAP(((const MathTableHeader*)table)->mathConstants));
+
+ if (whichConstant < firstMathValueRecord) {
+ /* it's a simple 16-bit value */
+ return SWAP(constants[whichConstant]);
+ }
+ else if (whichConstant <= lastMathValueRecord) {
+ const MathValueRecord* valueRecords = (const MathValueRecord*)
+ ((char*)constants + firstMathValueRecord * sizeof(uint16_t) - firstMathValueRecord * sizeof(MathValueRecord));
+ return SWAP(valueRecords[whichConstant].value);
+ }
+ else if (whichConstant <= lastMathConstant) {
+ return SWAP(constants[whichConstant + (lastMathValueRecord - firstMathValueRecord + 1)]);
+ }
+ else
+ return 0; /* or abort, with "internal error" or something */
}
int
get_ot_math_constant(int f, int n)
{
- int rval = 0;
-
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
- rval = getMathConstant(font, (mathConstantIndex)n);
- /* scale according to font size, except the ones that are percentages */
- if (n > scriptScriptPercentScaleDown && n < radicalDegreeBottomRaisePercent)
- rval = D2Fix(font->unitsToPoints(rval));
- }
- return rval;
+ int rval = 0;
+
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+ rval = getMathConstant(font, (mathConstantIndex)n);
+ /* scale according to font size, except the ones that are percentages */
+ if (n > scriptScriptPercentScaleDown && n < radicalDegreeBottomRaisePercent)
+ rval = D2Fix(font->unitsToPoints(rval));
+ }
+ return rval;
}
/* fontdimen IDs for math symbols font (family 2) */
-#define math_x_height 5
-#define math_quad 6
-#define num1 8 /* numerator shift-up in display styles */
-#define num2 9 /* numerator shift-up in non-display, non-\.{\\atop} */
-#define num3 10 /* numerator shift-up in non-display \.{\\atop} */
-#define denom1 11 /* denominator shift-down in display styles */
-#define denom2 12 /* denominator shift-down in non-display styles */
-#define sup1 13 /* superscript shift-up in uncramped display style */
-#define sup2 14 /* superscript shift-up in uncramped non-display */
-#define sup3 15 /* superscript shift-up in cramped styles */
-#define sub1 16 /* subscript shift-down if superscript is absent */
-#define sub2 17 /* subscript shift-down if superscript is present */
-#define sup_drop 18 /* superscript baseline below top of large box */
-#define sub_drop 19 /* subscript baseline below bottom of large box */
-#define delim1 20 /* size of \.{\\atopwithdelims} delimiters */
-#define delim2 21 /* size of \.{\\atopwithdelims} delimiters in non-displays */
-#define axis_height 22 /* height of fraction lines above the baseline */
+#define math_x_height 5
+#define math_quad 6
+#define num1 8 /* numerator shift-up in display styles */
+#define num2 9 /* numerator shift-up in non-display, non-\.{\\atop} */
+#define num3 10 /* numerator shift-up in non-display \.{\\atop} */
+#define denom1 11 /* denominator shift-down in display styles */
+#define denom2 12 /* denominator shift-down in non-display styles */
+#define sup1 13 /* superscript shift-up in uncramped display style */
+#define sup2 14 /* superscript shift-up in uncramped non-display */
+#define sup3 15 /* superscript shift-up in cramped styles */
+#define sub1 16 /* subscript shift-down if superscript is absent */
+#define sub2 17 /* subscript shift-down if superscript is present */
+#define sup_drop 18 /* superscript baseline below top of large box */
+#define sub_drop 19 /* subscript baseline below bottom of large box */
+#define delim1 20 /* size of \.{\\atopwithdelims} delimiters */
+#define delim2 21 /* size of \.{\\atopwithdelims} delimiters in non-displays */
+#define axis_height 22 /* height of fraction lines above the baseline */
const mathConstantIndex TeX_sym_to_OT_map[] = {
- unknown,
- unknown,
- unknown,
- unknown,
- unknown,
- accentBaseHeight, // x-height
- unknown, // quad
- unknown,
- fractionNumeratorDisplayStyleShiftUp,
- fractionNumeratorShiftUp,
- stackTopShiftUp,
- fractionDenominatorDisplayStyleShiftDown,
- fractionDenominatorShiftDown,
- superscriptShiftUp, // ??
- superscriptShiftUp, // ??
- superscriptShiftUpCramped,
- subscriptShiftDown, // ??
- subscriptShiftDown, // ??
- superscriptBaselineDropMax, // ??
- subscriptBaselineDropMin, // ??
- delimitedSubFormulaMinHeight,
- unknown, // using quad instead for now
- axisHeight
+ unknown,
+ unknown,
+ unknown,
+ unknown,
+ unknown,
+ accentBaseHeight, // x-height
+ unknown, // quad
+ unknown,
+ fractionNumeratorDisplayStyleShiftUp,
+ fractionNumeratorShiftUp,
+ stackTopShiftUp,
+ fractionDenominatorDisplayStyleShiftDown,
+ fractionDenominatorShiftDown,
+ superscriptShiftUp, // ??
+ superscriptShiftUp, // ??
+ superscriptShiftUpCramped,
+ subscriptShiftDown, // ??
+ subscriptShiftDown, // ??
+ superscriptBaselineDropMax, // ??
+ subscriptBaselineDropMin, // ??
+ delimitedSubFormulaMinHeight,
+ unknown, // using quad instead for now
+ axisHeight
};
int
get_native_mathsy_param(int f, int n)
{
- int rval = 0;
-
- if (n == math_quad || n == delim2)
- rval = fontsize[f];
- else {
- if (n < sizeof(TeX_sym_to_OT_map) / sizeof(mathConstantIndex)) {
- mathConstantIndex ot_index = TeX_sym_to_OT_map[n];
- if (ot_index != unknown)
- rval = get_ot_math_constant(f, (int)ot_index);
- }
- }
-// fprintf(stderr, " math_sy(%d, %d) returns %.3f\n", f, n, Fix2D(rval));
-
- return rval;
+ int rval = 0;
+
+ if (n == math_quad || n == delim2)
+ rval = fontsize[f];
+ else {
+ if (n < sizeof(TeX_sym_to_OT_map) / sizeof(mathConstantIndex)) {
+ mathConstantIndex ot_index = TeX_sym_to_OT_map[n];
+ if (ot_index != unknown)
+ rval = get_ot_math_constant(f, (int)ot_index);
+ }
+ }
+// fprintf(stderr, " math_sy(%d, %d) returns %.3f\n", f, n, Fix2D(rval));
+
+ return rval;
}
/* fontdimen IDs for math extension font (family 3) */
-#define default_rule_thickness 8 /* thickness of \.{\\over} bars */
-#define big_op_spacing1 9 /* minimum clearance above a displayed op */
-#define big_op_spacing2 10 /* minimum clearance below a displayed op */
-#define big_op_spacing3 11 /* minimum baselineskip above displayed op */
-#define big_op_spacing4 12 /* minimum baselineskip below displayed op */
-#define big_op_spacing5 13 /* padding above and below displayed limits */
+#define default_rule_thickness 8 /* thickness of \.{\\over} bars */
+#define big_op_spacing1 9 /* minimum clearance above a displayed op */
+#define big_op_spacing2 10 /* minimum clearance below a displayed op */
+#define big_op_spacing3 11 /* minimum baselineskip above displayed op */
+#define big_op_spacing4 12 /* minimum baselineskip below displayed op */
+#define big_op_spacing5 13 /* padding above and below displayed limits */
const mathConstantIndex TeX_ext_to_OT_map[] = {
- unknown,
- unknown,
- unknown,
- unknown,
- unknown,
- accentBaseHeight, // x-height
- unknown, // quad
- unknown,
- fractionRuleThickness, // default_rule_thickness
- upperLimitGapMin, // big_op_spacing1
- lowerLimitGapMin, // big_op_spacing2
- upperLimitBaselineRiseMin, // big_op_spacing3
- lowerLimitBaselineDropMin, // big_op_spacing4
- stackGapMin // big_op_spacing5
+ unknown,
+ unknown,
+ unknown,
+ unknown,
+ unknown,
+ accentBaseHeight, // x-height
+ unknown, // quad
+ unknown,
+ fractionRuleThickness, // default_rule_thickness
+ upperLimitGapMin, // big_op_spacing1
+ lowerLimitGapMin, // big_op_spacing2
+ upperLimitBaselineRiseMin, // big_op_spacing3
+ lowerLimitBaselineDropMin, // big_op_spacing4
+ stackGapMin // big_op_spacing5
};
int
get_native_mathex_param(int f, int n)
{
- int rval = 0;
-
- if (n == math_quad)
- rval = fontsize[f];
- else {
- if (n < sizeof(TeX_ext_to_OT_map) / sizeof(mathConstantIndex)) {
- mathConstantIndex ot_index = TeX_ext_to_OT_map[n];
- if (ot_index != unknown)
- rval = get_ot_math_constant(f, (int)ot_index);
- }
- }
-// fprintf(stderr, " math_ex(%d, %d) returns %.3f\n", f, n, Fix2D(rval));
-
- return rval;
+ int rval = 0;
+
+ if (n == math_quad)
+ rval = fontsize[f];
+ else {
+ if (n < sizeof(TeX_ext_to_OT_map) / sizeof(mathConstantIndex)) {
+ mathConstantIndex ot_index = TeX_ext_to_OT_map[n];
+ if (ot_index != unknown)
+ rval = get_ot_math_constant(f, (int)ot_index);
+ }
+ }
+// fprintf(stderr, " math_ex(%d, %d) returns %.3f\n", f, n, Fix2D(rval));
+
+ return rval;
}
int
get_ot_math_variant(int f, int g, int v, integer* adv, int horiz)
{
- int rval = g;
- *adv = -1;
-
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
-
- const char* table = font->getMathTable();
- if (table == NULL)
- return rval;
-
- uint16_t offset = SWAP(((const MathTableHeader*)table)->mathVariants);
- if (offset == 0)
- return rval;
- const MathVariants* variants = (const MathVariants*)(table + offset);
-
- offset = horiz ? SWAP(variants->horizGlyphCoverage) : SWAP(variants->vertGlyphCoverage);
- if (offset == 0)
- return rval;
- const Coverage* coverage = (const Coverage*)(((const char*)variants) + offset);
-
- int32_t index = getCoverage(coverage, g);
- if (index >= 0) {
- if (horiz)
- index += SWAP(variants->vertGlyphCount);
- const MathGlyphConstruction* construction = (const MathGlyphConstruction*)(((const char*)variants)
- + SWAP(variants->vertGlyphConstruction[index]));
- if (v < SWAP(construction->variantCount)) {
- rval = SWAP(construction->mathGlyphVariantRecord[v].variantGlyph);
- *adv = D2Fix(font->unitsToPoints(SWAP(construction->mathGlyphVariantRecord[v].advanceMeasurement)));
- }
- }
- }
-
- return rval;
+ int rval = g;
+ *adv = -1;
+
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+
+ const char* table = font->getMathTable();
+ if (table == NULL)
+ return rval;
+
+ uint16_t offset = SWAP(((const MathTableHeader*)table)->mathVariants);
+ if (offset == 0)
+ return rval;
+ const MathVariants* variants = (const MathVariants*)(table + offset);
+
+ offset = horiz ? SWAP(variants->horizGlyphCoverage) : SWAP(variants->vertGlyphCoverage);
+ if (offset == 0)
+ return rval;
+ const Coverage* coverage = (const Coverage*)(((const char*)variants) + offset);
+
+ int32_t index = getCoverage(coverage, g);
+ if (index >= 0) {
+ if (horiz)
+ index += SWAP(variants->vertGlyphCount);
+ const MathGlyphConstruction* construction = (const MathGlyphConstruction*)(((const char*)variants)
+ + SWAP(variants->vertGlyphConstruction[index]));
+ if (v < SWAP(construction->variantCount)) {
+ rval = SWAP(construction->mathGlyphVariantRecord[v].variantGlyph);
+ *adv = D2Fix(font->unitsToPoints(SWAP(construction->mathGlyphVariantRecord[v].advanceMeasurement)));
+ }
+ }
+ }
+
+ return rval;
}
void*
get_ot_assembly_ptr(int f, int g, int horiz)
{
- void* rval = NULL;
-
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
-
- const char* table = font->getMathTable();
- if (table == NULL)
- return rval;
-
- uint16_t offset = SWAP(((const MathTableHeader*)table)->mathVariants);
- if (offset == 0)
- return rval;
- const MathVariants* variants = (const MathVariants*)(table + offset);
-
- offset = horiz ? SWAP(variants->horizGlyphCoverage) : SWAP(variants->vertGlyphCoverage);
- if (offset == 0)
- return rval;
- const Coverage* coverage = (const Coverage*)(((const char*)variants) + offset);
-
- int32_t index = getCoverage(coverage, g);
- if (index >= 0) {
- if (horiz)
- index += SWAP(variants->vertGlyphCount);
- const MathGlyphConstruction* construction = (const MathGlyphConstruction*)(((const char*)variants)
- + SWAP(variants->vertGlyphConstruction[index]));
- offset = SWAP(construction->glyphAssembly);
- if (offset != 0)
- rval = (void*)(((const char*)construction) + offset);
- }
- }
-
- return rval;
+ void* rval = NULL;
+
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+
+ const char* table = font->getMathTable();
+ if (table == NULL)
+ return rval;
+
+ uint16_t offset = SWAP(((const MathTableHeader*)table)->mathVariants);
+ if (offset == 0)
+ return rval;
+ const MathVariants* variants = (const MathVariants*)(table + offset);
+
+ offset = horiz ? SWAP(variants->horizGlyphCoverage) : SWAP(variants->vertGlyphCoverage);
+ if (offset == 0)
+ return rval;
+ const Coverage* coverage = (const Coverage*)(((const char*)variants) + offset);
+
+ int32_t index = getCoverage(coverage, g);
+ if (index >= 0) {
+ if (horiz)
+ index += SWAP(variants->vertGlyphCount);
+ const MathGlyphConstruction* construction = (const MathGlyphConstruction*)(((const char*)variants)
+ + SWAP(variants->vertGlyphConstruction[index]));
+ offset = SWAP(construction->glyphAssembly);
+ if (offset != 0)
+ rval = (void*)(((const char*)construction) + offset);
+ }
+ }
+
+ return rval;
}
int
get_ot_math_ital_corr(int f, int g)
{
- int rval = 0;
-
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
-
- const char* table = font->getMathTable();
- if (table == NULL)
- return rval;
-
- uint16_t offset = SWAP(((const MathTableHeader*)table)->mathGlyphInfo);
- if (offset == 0)
- return rval;
- const MathGlyphInfo* glyphInfo = (const MathGlyphInfo*)(table + offset);
-
- offset = SWAP(glyphInfo->mathItalicsCorrectionInfo);
- if (offset == 0)
- return rval;
- const MathItalicsCorrectionInfo* italCorrInfo = (const MathItalicsCorrectionInfo*)(((const char*)glyphInfo) + offset);
-
- offset = SWAP(italCorrInfo->coverage);
- if (offset == 0)
- return rval;
- const Coverage* coverage = (const Coverage*)(((const char*)italCorrInfo) + offset);
-
- int32_t index = getCoverage(coverage, g);
- if (index >= 0 && index < SWAP(italCorrInfo->italicsCorrectionCount))
- rval = D2Fix(font->unitsToPoints(SWAP(italCorrInfo->italicsCorrection[index].value)));
- }
-
- return rval;
+ int rval = 0;
+
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+
+ const char* table = font->getMathTable();
+ if (table == NULL)
+ return rval;
+
+ uint16_t offset = SWAP(((const MathTableHeader*)table)->mathGlyphInfo);
+ if (offset == 0)
+ return rval;
+ const MathGlyphInfo* glyphInfo = (const MathGlyphInfo*)(table + offset);
+
+ offset = SWAP(glyphInfo->mathItalicsCorrectionInfo);
+ if (offset == 0)
+ return rval;
+ const MathItalicsCorrectionInfo* italCorrInfo = (const MathItalicsCorrectionInfo*)(((const char*)glyphInfo) + offset);
+
+ offset = SWAP(italCorrInfo->coverage);
+ if (offset == 0)
+ return rval;
+ const Coverage* coverage = (const Coverage*)(((const char*)italCorrInfo) + offset);
+
+ int32_t index = getCoverage(coverage, g);
+ if (index >= 0 && index < SWAP(italCorrInfo->italicsCorrectionCount))
+ rval = D2Fix(font->unitsToPoints(SWAP(italCorrInfo->italicsCorrection[index].value)));
+ }
+
+ return rval;
}
int
get_ot_math_accent_pos(int f, int g)
{
- int rval = 0x7fffffffUL;
-
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
-
- const char* table = font->getMathTable();
- if (table == NULL)
- return rval;
-
- uint16_t offset = SWAP(((const MathTableHeader*)table)->mathGlyphInfo);
- if (offset == 0)
- return rval;
- const MathGlyphInfo* glyphInfo = (const MathGlyphInfo*)(table + offset);
-
- offset = SWAP(glyphInfo->mathTopAccentAttachment);
- if (offset == 0)
- return rval;
- const MathTopAccentAttachment* accentAttachment = (const MathTopAccentAttachment*)(((const char*)glyphInfo) + offset);
-
- offset = SWAP(accentAttachment->coverage);
- if (offset == 0)
- return rval;
- const Coverage* coverage = (const Coverage*)(((const char*)accentAttachment) + offset);
-
- int32_t index = getCoverage(coverage, g);
- if (index >= 0 && index < SWAP(accentAttachment->topAccentAttachmentCount)) {
- rval = (int16_t)SWAP(accentAttachment->topAccentAttachment[index].value);
- rval = D2Fix(font->unitsToPoints(rval));
- }
- }
-
- return rval;
+ int rval = 0x7fffffffUL;
+
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+
+ const char* table = font->getMathTable();
+ if (table == NULL)
+ return rval;
+
+ uint16_t offset = SWAP(((const MathTableHeader*)table)->mathGlyphInfo);
+ if (offset == 0)
+ return rval;
+ const MathGlyphInfo* glyphInfo = (const MathGlyphInfo*)(table + offset);
+
+ offset = SWAP(glyphInfo->mathTopAccentAttachment);
+ if (offset == 0)
+ return rval;
+ const MathTopAccentAttachment* accentAttachment = (const MathTopAccentAttachment*)(((const char*)glyphInfo) + offset);
+
+ offset = SWAP(accentAttachment->coverage);
+ if (offset == 0)
+ return rval;
+ const Coverage* coverage = (const Coverage*)(((const char*)accentAttachment) + offset);
+
+ int32_t index = getCoverage(coverage, g);
+ if (index >= 0 && index < SWAP(accentAttachment->topAccentAttachmentCount)) {
+ rval = (int16_t)SWAP(accentAttachment->topAccentAttachment[index].value);
+ rval = D2Fix(font->unitsToPoints(rval));
+ }
+ }
+
+ return rval;
}
int
ot_min_connector_overlap(int f)
{
- int rval = 0;
-
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+ int rval = 0;
- const char* table = font->getMathTable();
- if (table == NULL)
- return rval;
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
- uint16_t offset = SWAP(((const MathTableHeader*)table)->mathVariants);
- if (offset == 0)
- return rval;
- const MathVariants* variants = (const MathVariants*)(table + offset);
+ const char* table = font->getMathTable();
+ if (table == NULL)
+ return rval;
- rval = D2Fix(font->unitsToPoints(SWAP(variants->minConnectorOverlap)));
- }
+ uint16_t offset = SWAP(((const MathTableHeader*)table)->mathVariants);
+ if (offset == 0)
+ return rval;
+ const MathVariants* variants = (const MathVariants*)(table + offset);
- return rval;
+ rval = D2Fix(font->unitsToPoints(SWAP(variants->minConnectorOverlap)));
+ }
+
+ return rval;
}
typedef enum {
- topRight,
- topLeft,
- bottomRight,
- bottomLeft,
+ topRight,
+ topLeft,
+ bottomRight,
+ bottomLeft,
} MathKernSide;
static int
getMathKernAt(int f, int g, MathKernSide side, int height)
{
- int rval = 0;
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
-
- const char* table = font->getMathTable();
- if (table == NULL)
- return rval;
-
- uint16_t offset = SWAP(((const MathTableHeader*)table)->mathGlyphInfo);
- if (offset == 0)
- return rval;
-
- const MathGlyphInfo* glyphInfo = (const MathGlyphInfo*)(table + offset);
-
- offset = SWAP(glyphInfo->mathKernInfo);
- if (offset == 0)
- return rval;
-
- const MathKernInfo* mathKernInfo = (const MathKernInfo*)(((const char*)glyphInfo) + offset);
-
- offset = SWAP(mathKernInfo->coverage);
- if (offset == 0)
- return rval;
-
- const Coverage* coverage = (const Coverage*)(((const char*)mathKernInfo) + offset);
-
- int32_t index = getCoverage(coverage, g);
- if (index >= 0 && index < SWAP(mathKernInfo->kernInfoCount)) {
- if (side == topRight)
- offset = SWAP(mathKernInfo->kernInfo[index].topRight);
- else if (side == bottomRight)
- offset = SWAP(mathKernInfo->kernInfo[index].bottomRight);
- else if (side == topLeft)
- offset = SWAP(mathKernInfo->kernInfo[index].topLeft);
- else if (side == bottomLeft)
- offset = SWAP(mathKernInfo->kernInfo[index].bottomLeft);
- else
- assert(0); // we should not reach here
-
- if (offset == 0)
- return rval;
-
- const MathKernTable* kernTable = (const MathKernTable*)(((const char*)mathKernInfo) + offset);
-
- uint16_t count = SWAP(kernTable->heightCount);
-
- // XXX: the following makes no sense WRT my understanding of the
- // spec! it is just how things worked for me.
- if (count == 0)
- rval = SWAP(kernTable->kern[-1].value);
- else if (height < SWAP(kernTable->height[0].value))
- rval = SWAP(kernTable->kern[1].value);
- else if (height > SWAP(kernTable->height[count].value))
- rval = SWAP(kernTable->kern[count+1].value);
- else {
- for (int i = 0; i < count; i++) {
- if (height > SWAP(kernTable->height[i].value)) {
- rval = SWAP(kernTable->kern[i+1].value);
- break;
- }
- }
- }
-
- //fprintf(stderr, " kern: %f %f\n", font->unitsToPoints(height), font->unitsToPoints(rval));
- }
- }
-
- return rval;
+ int rval = 0;
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+
+ const char* table = font->getMathTable();
+ if (table == NULL)
+ return rval;
+
+ uint16_t offset = SWAP(((const MathTableHeader*)table)->mathGlyphInfo);
+ if (offset == 0)
+ return rval;
+
+ const MathGlyphInfo* glyphInfo = (const MathGlyphInfo*)(table + offset);
+
+ offset = SWAP(glyphInfo->mathKernInfo);
+ if (offset == 0)
+ return rval;
+
+ const MathKernInfo* mathKernInfo = (const MathKernInfo*)(((const char*)glyphInfo) + offset);
+
+ offset = SWAP(mathKernInfo->coverage);
+ if (offset == 0)
+ return rval;
+
+ const Coverage* coverage = (const Coverage*)(((const char*)mathKernInfo) + offset);
+
+ int32_t index = getCoverage(coverage, g);
+ if (index >= 0 && index < SWAP(mathKernInfo->kernInfoCount)) {
+ if (side == topRight)
+ offset = SWAP(mathKernInfo->kernInfo[index].topRight);
+ else if (side == bottomRight)
+ offset = SWAP(mathKernInfo->kernInfo[index].bottomRight);
+ else if (side == topLeft)
+ offset = SWAP(mathKernInfo->kernInfo[index].topLeft);
+ else if (side == bottomLeft)
+ offset = SWAP(mathKernInfo->kernInfo[index].bottomLeft);
+ else
+ assert(0); // we should not reach here
+
+ if (offset == 0)
+ return rval;
+
+ const MathKernTable* kernTable = (const MathKernTable*)(((const char*)mathKernInfo) + offset);
+
+ uint16_t count = SWAP(kernTable->heightCount);
+
+ // XXX: the following makes no sense WRT my understanding of the
+ // spec! it is just how things worked for me.
+ if (count == 0)
+ rval = SWAP(kernTable->kern[-1].value);
+ else if (height < SWAP(kernTable->height[0].value))
+ rval = SWAP(kernTable->kern[1].value);
+ else if (height > SWAP(kernTable->height[count].value))
+ rval = SWAP(kernTable->kern[count+1].value);
+ else {
+ for (int i = 0; i < count; i++) {
+ if (height > SWAP(kernTable->height[i].value)) {
+ rval = SWAP(kernTable->kern[i+1].value);
+ break;
+ }
+ }
+ }
+
+ //fprintf(stderr, " kern: %f %f\n", font->unitsToPoints(height), font->unitsToPoints(rval));
+ }
+ }
+
+ return rval;
}
static float
glyph_height(int f, int g)
{
- float rval = 0.0;
+ float rval = 0.0;
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[f];
- getGlyphHeightDepth(engine, g, &rval, NULL);
- }
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[f];
+ getGlyphHeightDepth(engine, g, &rval, NULL);
+ }
- return rval;
+ return rval;
}
static float
glyph_depth(int f, int g)
{
- float rval = 0.0;
+ float rval = 0.0;
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[f];
- getGlyphHeightDepth(engine, g, NULL, &rval);
- }
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[f];
+ getGlyphHeightDepth(engine, g, NULL, &rval);
+ }
- return rval;
+ return rval;
}
// keep in sync with xetex.web
@@ -506,104 +506,104 @@ glyph_depth(int f, int g)
int
get_ot_math_kern(int f, int g, int sf, int sg, int cmd, int shift)
{
- int rval = 0;
+ int rval = 0;
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
- int kern = 0, skern = 0;
- float corr_height_top = 0.0, corr_height_bot = 0.0;
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+ int kern = 0, skern = 0;
+ float corr_height_top = 0.0, corr_height_bot = 0.0;
- shift = Fix2D(shift);
+ shift = Fix2D(shift);
- if (cmd == sup_cmd) { // superscript
- corr_height_top = font->pointsToUnits(glyph_height(f, g));
- corr_height_bot = -font->pointsToUnits(glyph_depth(sf, sg) + shift);
+ if (cmd == sup_cmd) { // superscript
+ corr_height_top = font->pointsToUnits(glyph_height(f, g));
+ corr_height_bot = -font->pointsToUnits(glyph_depth(sf, sg) + shift);
- kern = getMathKernAt(f, g, topRight, corr_height_top);
- skern = getMathKernAt(sf, sg, bottomLeft, corr_height_top);
- rval = kern + skern;
+ kern = getMathKernAt(f, g, topRight, corr_height_top);
+ skern = getMathKernAt(sf, sg, bottomLeft, corr_height_top);
+ rval = kern + skern;
- kern = getMathKernAt(f, g, topRight, corr_height_bot);
- skern = getMathKernAt(sf, sg, bottomLeft, corr_height_bot);
- if ((kern + skern) < rval)
- rval = kern + skern;
+ kern = getMathKernAt(f, g, topRight, corr_height_bot);
+ skern = getMathKernAt(sf, sg, bottomLeft, corr_height_bot);
+ if ((kern + skern) < rval)
+ rval = kern + skern;
- } else if (cmd == sub_cmd) { // subscript
- corr_height_top = font->pointsToUnits(glyph_height(sf, sg) - shift);
- corr_height_bot = -font->pointsToUnits(glyph_depth(f, g));
+ } else if (cmd == sub_cmd) { // subscript
+ corr_height_top = font->pointsToUnits(glyph_height(sf, sg) - shift);
+ corr_height_bot = -font->pointsToUnits(glyph_depth(f, g));
- kern = getMathKernAt(f, g, bottomRight, corr_height_top);
- skern = getMathKernAt(sf, sg, topLeft, corr_height_top);
- rval = kern + skern;
+ kern = getMathKernAt(f, g, bottomRight, corr_height_top);
+ skern = getMathKernAt(sf, sg, topLeft, corr_height_top);
+ rval = kern + skern;
- kern = getMathKernAt(f, g, bottomRight, corr_height_bot);
- skern = getMathKernAt(sf, sg, topLeft, corr_height_bot);
- if ((kern + skern) < rval)
- rval = kern + skern;
+ kern = getMathKernAt(f, g, bottomRight, corr_height_bot);
+ skern = getMathKernAt(sf, sg, topLeft, corr_height_bot);
+ if ((kern + skern) < rval)
+ rval = kern + skern;
- } else {
- assert(0); // we should not reach here
- }
+ } else {
+ assert(0); // we should not reach here
+ }
- rval = D2Fix(font->unitsToPoints(rval));
- }
+ rval = D2Fix(font->unitsToPoints(rval));
+ }
- return rval;
+ return rval;
}
int
ot_part_count(const GlyphAssembly* a)
{
- return SWAP(a->partCount);
+ return SWAP(a->partCount);
}
int
ot_part_glyph(const GlyphAssembly* a, int i)
{
- return SWAP(a->partRecords[i].glyph);
+ return SWAP(a->partRecords[i].glyph);
}
int
ot_part_is_extender(const GlyphAssembly* a, int i)
{
- return (SWAP(a->partRecords[i].partFlags) & fExtender) != 0;
+ return (SWAP(a->partRecords[i].partFlags) & fExtender) != 0;
}
int
ot_part_start_connector(int f, const GlyphAssembly* a, int i)
{
- int rval = 0;
-
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
- rval = D2Fix(font->unitsToPoints(SWAP(a->partRecords[i].startConnectorLength)));
- }
-
- return rval;
+ int rval = 0;
+
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+ rval = D2Fix(font->unitsToPoints(SWAP(a->partRecords[i].startConnectorLength)));
+ }
+
+ return rval;
}
int
ot_part_end_connector(int f, const GlyphAssembly* a, int i)
{
- int rval = 0;
-
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
- rval = D2Fix(font->unitsToPoints(SWAP(a->partRecords[i].endConnectorLength)));
- }
-
- return rval;
+ int rval = 0;
+
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+ rval = D2Fix(font->unitsToPoints(SWAP(a->partRecords[i].endConnectorLength)));
+ }
+
+ return rval;
}
int
ot_part_full_advance(int f, const GlyphAssembly* a, int i)
{
- int rval = 0;
-
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
- rval = D2Fix(font->unitsToPoints(SWAP(a->partRecords[i].fullAdvance)));
- }
-
- return rval;
+ int rval = 0;
+
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXFontInst* font = (XeTeXFontInst*)getFont((XeTeXLayoutEngine)fontlayoutengine[f]);
+ rval = D2Fix(font->unitsToPoints(SWAP(a->partRecords[i].fullAdvance)));
+ }
+
+ return rval;
}
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXOTMath.h b/Build/source/texk/web2c/xetexdir/XeTeXOTMath.h
index 1304c84e76e..ba2cc873041 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXOTMath.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeXOTMath.h
@@ -40,21 +40,21 @@ authorization from the copyright holders.
#ifdef __cplusplus
extern "C" {
#endif
- int get_native_mathsy_param(int f, int n);
- int get_native_mathex_param(int f, int n);
- int get_ot_math_constant(int f, int n);
- int get_ot_math_variant(int f, int g, int v, integer* adv, int horiz);
- void* get_ot_assembly_ptr(int f, int g, int horiz);
- int get_ot_math_ital_corr(int f, int g);
- int get_ot_math_accent_pos(int f, int g);
- int get_ot_math_kern(int f, int g, int sf, int sg, int cmd, int shift);
- int ot_part_count(const GlyphAssembly* a);
- int ot_part_glyph(const GlyphAssembly* a, int i);
- int ot_part_is_extender(const GlyphAssembly* a, int i);
- int ot_part_start_connector(int f, const GlyphAssembly* a, int i);
- int ot_part_end_connector(int f, const GlyphAssembly* a, int i);
- int ot_part_full_advance(int f, const GlyphAssembly* a, int i);
- int ot_min_connector_overlap(int f);
+ int get_native_mathsy_param(int f, int n);
+ int get_native_mathex_param(int f, int n);
+ int get_ot_math_constant(int f, int n);
+ int get_ot_math_variant(int f, int g, int v, integer* adv, int horiz);
+ void* get_ot_assembly_ptr(int f, int g, int horiz);
+ int get_ot_math_ital_corr(int f, int g);
+ int get_ot_math_accent_pos(int f, int g);
+ int get_ot_math_kern(int f, int g, int sf, int sg, int cmd, int shift);
+ int ot_part_count(const GlyphAssembly* a);
+ int ot_part_glyph(const GlyphAssembly* a, int i);
+ int ot_part_is_extender(const GlyphAssembly* a, int i);
+ int ot_part_start_connector(int f, const GlyphAssembly* a, int i);
+ int ot_part_end_connector(int f, const GlyphAssembly* a, int i);
+ int ot_part_full_advance(int f, const GlyphAssembly* a, int i);
+ int ot_min_connector_overlap(int f);
#ifdef __cplusplus
};
#endif
diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_ext.c b/Build/source/texk/web2c/xetexdir/XeTeX_ext.c
index afbce0bd4f1..721ab678724 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeX_ext.c
+++ b/Build/source/texk/web2c/xetexdir/XeTeX_ext.c
@@ -38,12 +38,10 @@ authorization from the copyright holders.
#include <w2c/config.h>
-#ifdef XETEX_OTHER
-#include "poppler-config.h"
-#include "png.h"
-#endif
-
-#include "zlib.h"
+#include <poppler-config.h>
+#include <png.h>
+#include <zlib.h>
+#include <graphite2/Font.h>
#ifdef _MSC_VER
#undef timezone
@@ -90,45 +88,45 @@ authorization from the copyright holders.
#include <assert.h>
-/* tables/values used in UTF-8 interpretation -
+/* tables/values used in UTF-8 interpretation -
code is based on ConvertUTF.[ch] sample code
published by the Unicode consortium */
const uint32_t
-offsetsFromUTF8[6] = {
- 0x00000000UL,
- 0x00003080UL,
- 0x000E2080UL,
- 0x03C82080UL,
- 0xFA082080UL,
- 0x82082080UL
+offsetsFromUTF8[6] = {
+ 0x00000000UL,
+ 0x00003080UL,
+ 0x000E2080UL,
+ 0x03C82080UL,
+ 0xFA082080UL,
+ 0x82082080UL
};
const uint8_t
bytesFromUTF8[256] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
const uint8_t
firstByteMark[7] = {
- 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
+ 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
};
-const int halfShift = 10;
-const uint32_t halfBase = 0x0010000UL;
-const uint32_t halfMask = 0x3FFUL;
-const uint32_t kSurrogateHighStart = 0xD800UL;
-const uint32_t kSurrogateHighEnd = 0xDBFFUL;
-const uint32_t kSurrogateLowStart = 0xDC00UL;
-const uint32_t kSurrogateLowEnd = 0xDFFFUL;
-const uint32_t byteMask = 0x000000BFUL;
-const uint32_t byteMark = 0x00000080UL;
+const int halfShift = 10;
+const uint32_t halfBase = 0x0010000UL;
+const uint32_t halfMask = 0x3FFUL;
+const uint32_t kSurrogateHighStart = 0xD800UL;
+const uint32_t kSurrogateHighEnd = 0xDBFFUL;
+const uint32_t kSurrogateLowStart = 0xDC00UL;
+const uint32_t kSurrogateLowEnd = 0xDFFFUL;
+const uint32_t byteMask = 0x000000BFUL;
+const uint32_t byteMark = 0x00000080UL;
/* if the user specifies a paper size or output driver program */
@@ -138,184 +136,184 @@ const char *outputdriver = "xdvipdfmx -q -E"; /* default to portable xdvipdfmx d
void initversionstring(char **versions)
{
-#ifdef XETEX_OTHER
- int fc_version = FcGetVersion();
+#ifndef XETEX_MAC
+ int fc_version = FcGetVersion();
#endif
- FT_Int ftMajor, ftMinor, ftPatch;
- int grMajor, grMinor, grBugfix;
- UVersionInfo icuVersion;
- char icu_version[U_MAX_VERSION_STRING_LENGTH] = "";
-
- const_string fmt =
- "Compiled with ICU version %s; using %s\n"
- "Compiled with zlib version %s; using %s\n"
- "Compiled with FreeType2 version %d.%d.%d; using %d.%d.%d\n"
- "Compiled with Graphite2 version %d.%d.%d; using %d.%d.%d\n"
- "Compiled with HarfBuzz version %s; using %s\n"
+ FT_Int ftMajor, ftMinor, ftPatch;
+ int grMajor, grMinor, grBugfix;
+ UVersionInfo icuVersion;
+ char icu_version[U_MAX_VERSION_STRING_LENGTH] = "";
+
+ const_string fmt =
+ "Compiled with ICU version %s; using %s\n"
+ "Compiled with zlib version %s; using %s\n"
+ "Compiled with FreeType2 version %d.%d.%d; using %d.%d.%d\n"
+ "Compiled with Graphite2 version %d.%d.%d; using %d.%d.%d\n"
+ "Compiled with HarfBuzz version %s; using %s\n"
+ "Compiled with libpng version %s; using %s\n"
+ "Compiled with poppler version %s\n"
#ifdef XETEX_MAC
- "Using Mac OS X Core Text, Cocoa & ImageIO frameworks\n"
+ "Using Mac OS X Core Text and Cocoa frameworks\n"
#else
- "Compiled with fontconfig version %d.%d.%d; using %d.%d.%d\n"
- "Compiled with libpng version %s; using %s\n"
- "Compiled with poppler version %s\n"
+ "Compiled with fontconfig version %d.%d.%d; using %d.%d.%d\n"
#endif
- ;
-
- int len = strlen(fmt)
- + strlen(U_ICU_VERSION)
- + strlen(icu_version)
- + strlen(ZLIB_VERSION)
- + strlen(zlib_version)
- + strlen(HB_VERSION_STRING)
- + strlen(hb_version_string())
-#ifdef XETEX_OTHER
- + strlen(PNG_LIBPNG_VER_STRING)
- + strlen(png_libpng_ver)
- + strlen(POPPLER_VERSION)
- + 6 * 3 /* for fontconfig version #s (won't really need 3 digits per field!) */
+ ;
+
+ int len = strlen(fmt)
+ + strlen(U_ICU_VERSION)
+ + strlen(icu_version)
+ + strlen(ZLIB_VERSION)
+ + strlen(zlib_version)
+ + strlen(HB_VERSION_STRING)
+ + strlen(hb_version_string())
+ + strlen(PNG_LIBPNG_VER_STRING)
+ + strlen(png_libpng_ver)
+ + strlen(POPPLER_VERSION)
+#ifndef XETEX_MAC
+ + 6 * 3 /* for fontconfig version #s (won't really need 3 digits per field!) */
#endif
- + 6 * 3 /* for graphite2 version #s (ditto) */
- + 6 * 3; /* for freetype version #s (ditto) */
+ + 6 * 3 /* for graphite2 version #s (ditto) */
+ + 6 * 3; /* for freetype version #s (ditto) */
- *versions = xmalloc(len + 1);
- /* len will be more than enough, because of the placeholder chars in fmt
- that get replaced by the arguments */
+ *versions = (char *) xmalloc(len + 1);
+ /* len will be more than enough, because of the placeholder chars in fmt
+ that get replaced by the arguments */
- u_getVersion(icuVersion);
- u_versionToString(icuVersion, icu_version);
+ u_getVersion(icuVersion);
+ u_versionToString(icuVersion, icu_version);
- if (gFreeTypeLibrary == 0 && FT_Init_FreeType(&gFreeTypeLibrary) != 0) {
- fprintf(stderr, "FreeType initialization failed!\n");
- exit(9);
- }
- FT_Library_Version(gFreeTypeLibrary, &ftMajor, &ftMinor, &ftPatch);
+ if (gFreeTypeLibrary == 0 && FT_Init_FreeType(&gFreeTypeLibrary) != 0) {
+ fprintf(stderr, "FreeType initialization failed!\n");
+ exit(9);
+ }
+ FT_Library_Version(gFreeTypeLibrary, &ftMajor, &ftMinor, &ftPatch);
- gr_engine_version(&grMajor, &grMinor, &grBugfix);
+ gr_engine_version(&grMajor, &grMinor, &grBugfix);
(void)sprintf(*versions, fmt,
- U_ICU_VERSION, icu_version,
- ZLIB_VERSION, zlib_version,
- FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH,
- ftMajor, ftMinor, ftPatch,
- GR2_VERSION_MAJOR, GR2_VERSION_MINOR, GR2_VERSION_BUGFIX,
- grMajor, grMinor, grBugfix,
- HB_VERSION_STRING, hb_version_string()
-#ifdef XETEX_OTHER
- ,
- FC_VERSION / 10000, (FC_VERSION % 10000) / 100, FC_VERSION % 100,
- fc_version / 10000, (fc_version % 10000) / 100, fc_version % 100,
- PNG_LIBPNG_VER_STRING, png_libpng_ver, POPPLER_VERSION
+ U_ICU_VERSION, icu_version,
+ ZLIB_VERSION, zlib_version,
+ FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH,
+ ftMajor, ftMinor, ftPatch,
+ GR2_VERSION_MAJOR, GR2_VERSION_MINOR, GR2_VERSION_BUGFIX,
+ grMajor, grMinor, grBugfix,
+ HB_VERSION_STRING, hb_version_string(),
+ PNG_LIBPNG_VER_STRING, png_libpng_ver, POPPLER_VERSION
+#ifndef XETEX_MAC
+ ,
+ FC_VERSION / 10000, (FC_VERSION % 10000) / 100, FC_VERSION % 100,
+ fc_version / 10000, (fc_version % 10000) / 100, fc_version % 100
#endif
- );
+ );
}
void
setinputfileencoding(UFILE* f, integer mode, integer encodingData)
{
- if ((f->encodingMode == ICUMAPPING) && (f->conversionData != NULL))
- ucnv_close((UConverter*)(f->conversionData));
- f->conversionData = 0;
-
- switch (mode) {
- case UTF8:
- case UTF16BE:
- case UTF16LE:
- case RAW:
- f->encodingMode = mode;
- break;
-
- case ICUMAPPING:
- {
- char* name = gettexstring(encodingData);
- UErrorCode err = 0;
- UConverter* cnv = ucnv_open(name, &err);
- if (cnv == NULL) {
- begindiagnostic();
- printnl('E');
- printcstring("rror ");
- printint(err);
- printcstring(" creating Unicode converter for `");
- printcstring(name);
- printcstring("'; reading as raw bytes");
- enddiagnostic(1);
- f->encodingMode = RAW;
- } else {
- f->encodingMode = ICUMAPPING;
- f->conversionData = cnv;
- }
- free(name);
- }
- break;
- }
+ if ((f->encodingMode == ICUMAPPING) && (f->conversionData != NULL))
+ ucnv_close((UConverter*)(f->conversionData));
+ f->conversionData = 0;
+
+ switch (mode) {
+ case UTF8:
+ case UTF16BE:
+ case UTF16LE:
+ case RAW:
+ f->encodingMode = mode;
+ break;
+
+ case ICUMAPPING:
+ {
+ char* name = gettexstring(encodingData);
+ UErrorCode err = U_ZERO_ERROR;
+ UConverter* cnv = ucnv_open(name, &err);
+ if (cnv == NULL) {
+ begindiagnostic();
+ printnl('E');
+ printcstring("rror ");
+ printint(err);
+ printcstring(" creating Unicode converter for `");
+ printcstring(name);
+ printcstring("'; reading as raw bytes");
+ enddiagnostic(1);
+ f->encodingMode = RAW;
+ } else {
+ f->encodingMode = ICUMAPPING;
+ f->conversionData = cnv;
+ }
+ free(name);
+ }
+ break;
+ }
}
void
uclose(UFILE* f)
{
- if (f != 0) {
- fclose(f->f);
- if ((f->encodingMode == ICUMAPPING) && (f->conversionData != NULL))
- ucnv_close((UConverter*)(f->conversionData));
- free((void*)f);
- }
+ if (f != 0) {
+ fclose(f->f);
+ if ((f->encodingMode == ICUMAPPING) && (f->conversionData != NULL))
+ ucnv_close((UConverter*)(f->conversionData));
+ free((void*)f);
+ }
}
static void
buffer_overflow()
{
- fprintf (stderr, "! Unable to read an entire line---bufsize=%u.\n",
- (unsigned) bufsize);
- fputs ("Please increase buf_size in texmf.cnf.\n", stderr);
- uexit (1);
+ fprintf (stderr, "! Unable to read an entire line---bufsize=%u.\n",
+ (unsigned) bufsize);
+ fputs ("Please increase buf_size in texmf.cnf.\n", stderr);
+ uexit (1);
}
static void
conversion_error(int errcode)
{
- begindiagnostic();
- printnl('U');
- printcstring("nicode conversion failed (ICU error code = ");
- printint(errcode);
- printcstring(") discarding any remaining text");
- enddiagnostic(1);
+ begindiagnostic();
+ printnl('U');
+ printcstring("nicode conversion failed (ICU error code = ");
+ printint(errcode);
+ printcstring(") discarding any remaining text");
+ enddiagnostic(1);
}
#ifdef WORDS_BIGENDIAN
-#define NATIVE_UTF32 kForm_UTF32BE
+#define NATIVE_UTF32 kForm_UTF32BE
#else
-#define NATIVE_UTF32 kForm_UTF32LE
+#define NATIVE_UTF32 kForm_UTF32LE
#endif
static void
apply_normalization(uint32_t* buf, int len, int norm)
{
- static TECkit_Converter normalizers[2] = { NULL, NULL };
-
- TECkit_Status status;
- UInt32 inUsed, outUsed;
- TECkit_Converter *normPtr = &normalizers[norm - 1];
- if (*normPtr == NULL) {
- status = TECkit_CreateConverter(NULL, 0, 1,
- NATIVE_UTF32, NATIVE_UTF32 | (norm == 1 ? kForm_NFC : kForm_NFD),
- &*normPtr);
- if (status != kStatus_NoError) {
- fprintf(stderr, "! Failed to create normalizer: error code = %d\n", (int)status);
- uexit (1);
- }
- }
+ static TECkit_Converter normalizers[2] = { NULL, NULL };
+
+ TECkit_Status status;
+ UInt32 inUsed, outUsed;
+ TECkit_Converter *normPtr = &normalizers[norm - 1];
+ if (*normPtr == NULL) {
+ status = TECkit_CreateConverter(NULL, 0, 1,
+ NATIVE_UTF32, NATIVE_UTF32 | (norm == 1 ? kForm_NFC : kForm_NFD),
+ &*normPtr);
+ if (status != kStatus_NoError) {
+ fprintf(stderr, "! Failed to create normalizer: error code = %d\n", (int)status);
+ uexit (1);
+ }
+ }
- status = TECkit_ConvertBuffer(*normPtr, (Byte*)buf, len * sizeof(UInt32), &inUsed,
- (Byte*)&buffer[first], sizeof(*buffer) * (bufsize - first), &outUsed, 1);
- if (status != kStatus_NoError)
- buffer_overflow();
- last = first + outUsed / sizeof(*buffer);
+ status = TECkit_ConvertBuffer(*normPtr, (Byte*)buf, len * sizeof(UInt32), &inUsed,
+ (Byte*)&buffer[first], sizeof(*buffer) * (bufsize - first), &outUsed, 1);
+ if (status != kStatus_NoError)
+ buffer_overflow();
+ last = first + outUsed / sizeof(*buffer);
}
#ifdef WORDS_BIGENDIAN
-#define UCNV_UTF32_NativeEndian UCNV_UTF32_BigEndian
+#define UCNV_UTF32_NativeEndian UCNV_UTF32_BigEndian
#else
-#define UCNV_UTF32_NativeEndian UCNV_UTF32_LittleEndian
+#define UCNV_UTF32_NativeEndian UCNV_UTF32_LittleEndian
#endif
int
@@ -323,267 +321,265 @@ input_line(UFILE* f)
{
static char* byteBuffer = NULL;
static uint32_t *utf32Buf = NULL;
- int i, tmpLen;
- int norm = getinputnormalizationstate();
+ int i, tmpLen;
+ int norm = getinputnormalizationstate();
#ifdef WIN32
- const int fd = fileno(f->f);
- if (fd == _fileno(stdin) && _isatty(fd)) {
- f->encodingMode = WIN32CONSOLE;
- }
+ const int fd = fileno(f->f);
+ if (fd == _fileno(stdin) && _isatty(fd)) {
+ f->encodingMode = WIN32CONSOLE;
+ }
#endif
- last = first;
-
- if (f->encodingMode == ICUMAPPING) {
- uint32_t bytesRead = 0;
- UConverter* cnv;
- int outLen;
- UErrorCode errorCode = 0;
-
- if (byteBuffer == NULL)
- byteBuffer = xmalloc(bufsize + 1);
-
- /* Recognize either LF or CR as a line terminator; skip initial LF if prev line ended with CR. */
- i = getc(f->f);
- if (f->skipNextLF) {
- f->skipNextLF = 0;
- if (i == '\n')
- i = getc(f->f);
- }
-
- if (i != EOF && i != '\n' && i != '\r')
- byteBuffer[bytesRead++] = i;
- if (i != EOF && i != '\n' && i != '\r')
- while (bytesRead < bufsize && (i = getc(f->f)) != EOF && i != '\n' && i != '\r')
- byteBuffer[bytesRead++] = i;
-
- if (i == EOF && errno != EINTR && bytesRead == 0)
- return false;
-
- if (i != EOF && i != '\n' && i != '\r')
- buffer_overflow();
-
- /* now apply the mapping to turn external bytes into Unicode characters in buffer */
- cnv = (UConverter*)(f->conversionData);
- switch (norm) {
- case 1: // NFC
- case 2: // NFD
- if (utf32Buf == NULL)
- utf32Buf = (uint32_t*)xmalloc(bufsize * sizeof(*utf32Buf));
- tmpLen = ucnv_toAlgorithmic(UCNV_UTF32_NativeEndian, cnv,
- (char*)utf32Buf, bufsize * sizeof(*utf32Buf),
- byteBuffer, bytesRead, &errorCode);
- if (errorCode != 0) {
- conversion_error((int)errorCode);
- return false;
- }
- apply_normalization(utf32Buf, tmpLen / sizeof(*utf32Buf), norm); // sets 'last' correctly
- break;
-
- default: // none
- outLen = ucnv_toAlgorithmic(UCNV_UTF32_NativeEndian, cnv,
- (char*)&buffer[first], sizeof(*buffer) * (bufsize - first),
- byteBuffer, bytesRead, &errorCode);
- if (errorCode != 0) {
- conversion_error((int)errorCode);
- return false;
- }
- outLen /= sizeof(*buffer);
- last = first + outLen;
- break;
- }
- } else {
- /* Recognize either LF or CR as a line terminator; skip initial LF if prev line ended with CR. */
- i = get_uni_c(f);
- if (f->skipNextLF) {
- f->skipNextLF = 0;
- if (i == '\n')
- i = get_uni_c(f);
- }
-
- switch (norm) {
- case 1: // NFC
- case 2: // NFD
- // read Unicode chars into utf32Buf as UTF32
- if (utf32Buf == NULL)
- utf32Buf = xmalloc(bufsize * sizeof(*utf32Buf));
- tmpLen = 0;
- if (i != EOF && i != '\n' && i != '\r')
- utf32Buf[tmpLen++] = i;
- if (i != EOF && i != '\n' && i != '\r')
- while (tmpLen < bufsize && (i = get_uni_c(f)) != EOF && i != '\n' && i != '\r')
- utf32Buf[tmpLen++] = i;
-
- if (i == EOF && errno != EINTR && tmpLen == 0)
- return false;
-
- /* We didn't get the whole line because our buffer was too small. */
- if (i != EOF && i != '\n' && i != '\r')
- buffer_overflow();
- apply_normalization(utf32Buf, tmpLen, norm);
- break;
-
- default: // none
- if (last < bufsize && i != EOF && i != '\n' && i != '\r')
- buffer[last++] = i;
- if (i != EOF && i != '\n' && i != '\r')
- while (last < bufsize && (i = get_uni_c(f)) != EOF && i != '\n' && i != '\r')
- buffer[last++] = i;
-
- if (i == EOF && errno != EINTR && last == first)
- return false;
-
- /* We didn't get the whole line because our buffer was too small. */
- if (i != EOF && i != '\n' && i != '\r')
- buffer_overflow();
- break;
- }
- }
-
- /* If line ended with CR, remember to skip following LF. */
- if (i == '\r')
- f->skipNextLF = 1;
-
- buffer[last] = ' ';
- if (last >= maxbufstack)
- maxbufstack = last;
-
- /* Trim trailing whitespace. */
- while (last > first && ISBLANK(buffer[last - 1]))
- --last;
-
- return true;
+ last = first;
+
+ if (f->encodingMode == ICUMAPPING) {
+ uint32_t bytesRead = 0;
+ UConverter* cnv;
+ int outLen;
+ UErrorCode errorCode = U_ZERO_ERROR;
+
+ if (byteBuffer == NULL)
+ byteBuffer = (char*) xmalloc(bufsize + 1);
+
+ /* Recognize either LF or CR as a line terminator; skip initial LF if prev line ended with CR. */
+ i = getc(f->f);
+ if (f->skipNextLF) {
+ f->skipNextLF = 0;
+ if (i == '\n')
+ i = getc(f->f);
+ }
+
+ if (i != EOF && i != '\n' && i != '\r')
+ byteBuffer[bytesRead++] = i;
+ if (i != EOF && i != '\n' && i != '\r')
+ while (bytesRead < bufsize && (i = getc(f->f)) != EOF && i != '\n' && i != '\r')
+ byteBuffer[bytesRead++] = i;
+
+ if (i == EOF && errno != EINTR && bytesRead == 0)
+ return false;
+
+ if (i != EOF && i != '\n' && i != '\r')
+ buffer_overflow();
+
+ /* now apply the mapping to turn external bytes into Unicode characters in buffer */
+ cnv = (UConverter*)(f->conversionData);
+ switch (norm) {
+ case 1: // NFC
+ case 2: // NFD
+ if (utf32Buf == NULL)
+ utf32Buf = (uint32_t*) xcalloc(bufsize, sizeof(uint32_t));
+ tmpLen = ucnv_toAlgorithmic(UCNV_UTF32_NativeEndian, cnv,
+ (char*)utf32Buf, bufsize * sizeof(*utf32Buf),
+ byteBuffer, bytesRead, &errorCode);
+ if (errorCode != 0) {
+ conversion_error((int)errorCode);
+ return false;
+ }
+ apply_normalization(utf32Buf, tmpLen / sizeof(*utf32Buf), norm); // sets 'last' correctly
+ break;
+
+ default: // none
+ outLen = ucnv_toAlgorithmic(UCNV_UTF32_NativeEndian, cnv,
+ (char*)&buffer[first], sizeof(*buffer) * (bufsize - first),
+ byteBuffer, bytesRead, &errorCode);
+ if (errorCode != 0) {
+ conversion_error((int)errorCode);
+ return false;
+ }
+ outLen /= sizeof(*buffer);
+ last = first + outLen;
+ break;
+ }
+ } else {
+ /* Recognize either LF or CR as a line terminator; skip initial LF if prev line ended with CR. */
+ i = get_uni_c(f);
+ if (f->skipNextLF) {
+ f->skipNextLF = 0;
+ if (i == '\n')
+ i = get_uni_c(f);
+ }
+
+ switch (norm) {
+ case 1: // NFC
+ case 2: // NFD
+ // read Unicode chars into utf32Buf as UTF32
+ if (utf32Buf == NULL)
+ utf32Buf = (uint32_t*) xcalloc(bufsize, sizeof(uint32_t));
+ tmpLen = 0;
+ if (i != EOF && i != '\n' && i != '\r')
+ utf32Buf[tmpLen++] = i;
+ if (i != EOF && i != '\n' && i != '\r')
+ while (tmpLen < bufsize && (i = get_uni_c(f)) != EOF && i != '\n' && i != '\r')
+ utf32Buf[tmpLen++] = i;
+
+ if (i == EOF && errno != EINTR && tmpLen == 0)
+ return false;
+
+ /* We didn't get the whole line because our buffer was too small. */
+ if (i != EOF && i != '\n' && i != '\r')
+ buffer_overflow();
+ apply_normalization(utf32Buf, tmpLen, norm);
+ break;
+
+ default: // none
+ if (last < bufsize && i != EOF && i != '\n' && i != '\r')
+ buffer[last++] = i;
+ if (i != EOF && i != '\n' && i != '\r')
+ while (last < bufsize && (i = get_uni_c(f)) != EOF && i != '\n' && i != '\r')
+ buffer[last++] = i;
+
+ if (i == EOF && errno != EINTR && last == first)
+ return false;
+
+ /* We didn't get the whole line because our buffer was too small. */
+ if (i != EOF && i != '\n' && i != '\r')
+ buffer_overflow();
+ break;
+ }
+ }
+
+ /* If line ended with CR, remember to skip following LF. */
+ if (i == '\r')
+ f->skipNextLF = 1;
+
+ buffer[last] = ' ';
+ if (last >= maxbufstack)
+ maxbufstack = last;
+
+ /* Trim trailing whitespace. */
+ while (last > first && ISBLANK(buffer[last - 1]))
+ --last;
+
+ return true;
}
static void die(const_string s, int i)
{
- fprintf(stderr, s, i);
- fprintf(stderr, " - exiting\n");
- exit(3);
+ fprintf(stderr, s, i);
+ fprintf(stderr, " - exiting\n");
+ exit(3);
}
-static UBreakIterator* brkIter = NULL;
-static int brkLocaleStrNum = 0;
+static UBreakIterator* brkIter = NULL;
+static int brkLocaleStrNum = 0;
void
linebreakstart(int f, integer localeStrNum, const uint16_t* text, integer textLength)
{
- UErrorCode status;
- char* locale = (char*)gettexstring(localeStrNum);
-
- if (fontarea[f] == OTGR_FONT_FLAG && strcmp(locale, "G") == 0) {
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine) fontlayoutengine[f];
- if (initGraphiteBreaking(engine, text, textLength))
- /* user asked for Graphite line breaking and the font supports it */
- return;
- }
-
- status = 0;
-
- if ((localeStrNum != brkLocaleStrNum) && (brkIter != NULL)) {
- ubrk_close(brkIter);
- brkIter = NULL;
- }
-
- if (brkIter == NULL) {
- brkIter = ubrk_open(UBRK_LINE, locale, NULL, 0, &status);
- if (U_FAILURE(status)) {
- begindiagnostic();
- printnl('E');
- printcstring("rror ");
- printint(status);
- printcstring(" creating linebreak iterator for locale `");
- printcstring(locale);
- printcstring("'; trying default locale `en_us'.");
- enddiagnostic(1);
- if (brkIter != NULL)
- ubrk_close(brkIter);
- status = 0;
- brkIter = ubrk_open(UBRK_LINE, "en_us", NULL, 0, &status);
- }
- free(locale);
- brkLocaleStrNum = localeStrNum;
- }
-
- if (brkIter == NULL) {
- die("! failed to create linebreak iterator, status=%d", (int)status);
- }
-
- ubrk_setText(brkIter, text, textLength, &status);
+ UErrorCode status = U_ZERO_ERROR;
+ char* locale = (char*)gettexstring(localeStrNum);
+
+ if (fontarea[f] == OTGR_FONT_FLAG && strcmp(locale, "G") == 0) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine) fontlayoutengine[f];
+ if (initGraphiteBreaking(engine, text, textLength))
+ /* user asked for Graphite line breaking and the font supports it */
+ return;
+ }
+
+ if ((localeStrNum != brkLocaleStrNum) && (brkIter != NULL)) {
+ ubrk_close(brkIter);
+ brkIter = NULL;
+ }
+
+ if (brkIter == NULL) {
+ brkIter = ubrk_open(UBRK_LINE, locale, NULL, 0, &status);
+ if (U_FAILURE(status)) {
+ begindiagnostic();
+ printnl('E');
+ printcstring("rror ");
+ printint(status);
+ printcstring(" creating linebreak iterator for locale `");
+ printcstring(locale);
+ printcstring("'; trying default locale `en_us'.");
+ enddiagnostic(1);
+ if (brkIter != NULL)
+ ubrk_close(brkIter);
+ status = U_ZERO_ERROR;
+ brkIter = ubrk_open(UBRK_LINE, "en_us", NULL, 0, &status);
+ }
+ free(locale);
+ brkLocaleStrNum = localeStrNum;
+ }
+
+ if (brkIter == NULL) {
+ die("! failed to create linebreak iterator, status=%d", (int)status);
+ }
+
+ ubrk_setText(brkIter, (UChar*) text, textLength, &status);
}
int
linebreaknext()
{
- if (brkIter != NULL)
- return ubrk_next((UBreakIterator*)brkIter);
- else
- return findNextGraphiteBreak();
+ if (brkIter != NULL)
+ return ubrk_next((UBreakIterator*)brkIter);
+ else
+ return findNextGraphiteBreak();
}
int
getencodingmodeandinfo(integer* info)
{
- /* \XeTeXinputencoding "enc-name"
- * -> name is packed in |nameoffile| as a C string, starting at [1]
- * Check if it's a built-in name; if not, try to open an ICU converter by that name
- */
- UErrorCode err = 0;
- UConverter* cnv;
- char* name = (char*)nameoffile + 1;
- *info = 0;
- if (strcasecmp(name, "auto") == 0) {
- return AUTO;
- }
- if (strcasecmp(name, "utf8") == 0) {
- return UTF8;
- }
- if (strcasecmp(name, "utf16") == 0) { /* depends on host platform */
+ /* \XeTeXinputencoding "enc-name"
+ * -> name is packed in |nameoffile| as a C string, starting at [1]
+ * Check if it's a built-in name; if not, try to open an ICU converter by that name
+ */
+ UErrorCode err = U_ZERO_ERROR;
+ UConverter* cnv;
+ char* name = (char*)nameoffile + 1;
+ *info = 0;
+ if (strcasecmp(name, "auto") == 0) {
+ return AUTO;
+ }
+ if (strcasecmp(name, "utf8") == 0) {
+ return UTF8;
+ }
+ if (strcasecmp(name, "utf16") == 0) { /* depends on host platform */
#ifdef WORDS_BIGENDIAN
- return UTF16BE;
+ return UTF16BE;
#else
- return UTF16LE;
+ return UTF16LE;
#endif
- }
- if (strcasecmp(name, "utf16be") == 0) {
- return UTF16BE;
- }
- if (strcasecmp(name, "utf16le") == 0) {
- return UTF16LE;
- }
- if (strcasecmp(name, "bytes") == 0) {
- return RAW;
- }
-
- /* try for an ICU converter */
- cnv = ucnv_open(name, &err);
- if (cnv == NULL) {
- begindiagnostic();
- printnl('U'); /* ensure message starts on a new line */
- printcstring("nknown encoding `");
- printcstring(name);
- printcstring("'; reading as raw bytes");
- enddiagnostic(1);
- return RAW;
- } else {
- ucnv_close(cnv);
- *info = maketexstring(name);
- return ICUMAPPING;
- }
+ }
+ if (strcasecmp(name, "utf16be") == 0) {
+ return UTF16BE;
+ }
+ if (strcasecmp(name, "utf16le") == 0) {
+ return UTF16LE;
+ }
+ if (strcasecmp(name, "bytes") == 0) {
+ return RAW;
+ }
+
+ /* try for an ICU converter */
+ cnv = ucnv_open(name, &err);
+ if (cnv == NULL) {
+ begindiagnostic();
+ printnl('U'); /* ensure message starts on a new line */
+ printcstring("nknown encoding `");
+ printcstring(name);
+ printcstring("'; reading as raw bytes");
+ enddiagnostic(1);
+ return RAW;
+ } else {
+ ucnv_close(cnv);
+ *info = maketexstring(name);
+ return ICUMAPPING;
+ }
}
void
printutf8str(const unsigned char* str, int len)
{
- while (len-- > 0)
- printrawchar(*(str++), true); /* bypass utf-8 encoding done in print_char() */
+ while (len-- > 0)
+ printrawchar(*(str++), true); /* bypass utf-8 encoding done in print_char() */
}
void
printchars(const unsigned short* str, int len)
{
- while (len-- > 0)
- printchar(*(str++));
+ while (len-- > 0)
+ printchar(*(str++));
}
#ifdef WORDS_BIGENDIAN
@@ -595,1728 +591,1737 @@ printchars(const unsigned short* str, int len)
static void*
load_mapping_file(const char* s, const char* e, char byteMapping)
{
- char* mapPath;
- TECkit_Converter cnv = 0;
- char* buffer = xmalloc(e - s + 5);
- strncpy(buffer, s, e - s);
- buffer[e - s] = 0;
- strcat(buffer, ".tec");
- mapPath = kpse_find_file(buffer, kpse_miscfonts_format, 1);
-
- if (mapPath) {
- FILE* mapFile = fopen(mapPath, FOPEN_RBIN_MODE);
- free(mapPath);
- if (mapFile) {
- uint32_t mappingSize;
- Byte* mapping;
- TECkit_Status status;
- fseek(mapFile, 0, SEEK_END);
- mappingSize = ftell(mapFile);
- fseek(mapFile, 0, SEEK_SET);
- mapping = xmalloc(mappingSize);
- fread(mapping, 1, mappingSize, mapFile);
- fclose(mapFile);
- if (byteMapping != 0)
- status = TECkit_CreateConverter(mapping, mappingSize,
- false,
- UTF16_NATIVE, kForm_Bytes,
- &cnv);
- else
- status = TECkit_CreateConverter(mapping, mappingSize,
- true,
- UTF16_NATIVE, UTF16_NATIVE,
- &cnv);
- free(mapping);
- }
- if (cnv == NULL)
- fontmappingwarning(buffer, strlen(buffer), 2); /* not loadable */
- else if (gettracingfontsstate() > 1)
- fontmappingwarning(buffer, strlen(buffer), 0); /* tracing */
- } else {
- fontmappingwarning(buffer, strlen(buffer), 1); /* not found */
- }
-
- free(buffer);
-
- return cnv;
+ char* mapPath;
+ TECkit_Converter cnv = 0;
+ char* buffer = (char*) xmalloc(e - s + 5);
+ strncpy(buffer, s, e - s);
+ buffer[e - s] = 0;
+ strcat(buffer, ".tec");
+ mapPath = kpse_find_file(buffer, kpse_miscfonts_format, 1);
+
+ if (mapPath) {
+ FILE* mapFile = fopen(mapPath, FOPEN_RBIN_MODE);
+ free(mapPath);
+ if (mapFile) {
+ uint32_t mappingSize;
+ Byte* mapping;
+ TECkit_Status status;
+ fseek(mapFile, 0, SEEK_END);
+ mappingSize = ftell(mapFile);
+ fseek(mapFile, 0, SEEK_SET);
+ mapping = (Byte*) xmalloc(mappingSize);
+ fread(mapping, 1, mappingSize, mapFile);
+ fclose(mapFile);
+ if (byteMapping != 0)
+ status = TECkit_CreateConverter(mapping, mappingSize,
+ false,
+ UTF16_NATIVE, kForm_Bytes,
+ &cnv);
+ else
+ status = TECkit_CreateConverter(mapping, mappingSize,
+ true,
+ UTF16_NATIVE, UTF16_NATIVE,
+ &cnv);
+ free(mapping);
+ }
+ if (cnv == NULL)
+ fontmappingwarning(buffer, strlen(buffer), 2); /* not loadable */
+ else if (gettracingfontsstate() > 1)
+ fontmappingwarning(buffer, strlen(buffer), 0); /* tracing */
+ } else {
+ fontmappingwarning(buffer, strlen(buffer), 1); /* not found */
+ }
+
+ free(buffer);
+
+ return cnv;
}
char *saved_mapping_name = NULL;
void
checkfortfmfontmapping()
{
- char* cp = strstr((char*)nameoffile + 1, ":mapping=");
- if (saved_mapping_name != NULL) {
- free(saved_mapping_name);
- saved_mapping_name = NULL;
- }
- if (cp != NULL) {
- *cp = 0;
- cp += 9;
- while (*cp && *cp <= ' ')
- ++cp;
- if (*cp)
- saved_mapping_name = xstrdup(cp);
- }
+ char* cp = strstr((char*)nameoffile + 1, ":mapping=");
+ if (saved_mapping_name != NULL) {
+ free(saved_mapping_name);
+ saved_mapping_name = NULL;
+ }
+ if (cp != NULL) {
+ *cp = 0;
+ cp += 9;
+ while (*cp && *cp <= ' ')
+ ++cp;
+ if (*cp)
+ saved_mapping_name = xstrdup(cp);
+ }
}
void*
loadtfmfontmapping()
{
- void* rval = NULL;
- if (saved_mapping_name != NULL) {
- rval = load_mapping_file(saved_mapping_name,
- saved_mapping_name + strlen(saved_mapping_name), 1);
- free(saved_mapping_name);
- saved_mapping_name = NULL;
- }
- return rval;
+ void* rval = NULL;
+ if (saved_mapping_name != NULL) {
+ rval = load_mapping_file(saved_mapping_name,
+ saved_mapping_name + strlen(saved_mapping_name), 1);
+ free(saved_mapping_name);
+ saved_mapping_name = NULL;
+ }
+ return rval;
}
int
applytfmfontmapping(void* cnv, int c)
{
- UniChar in = c;
- Byte out[2];
- UInt32 inUsed, outUsed;
- TECkit_Status status = TECkit_ConvertBuffer((TECkit_Converter)cnv,
- (const Byte*)&in, sizeof(in), &inUsed, out, sizeof(out), &outUsed, 1);
- if (outUsed < 1)
- return 0;
- else
- return out[0];
+ UniChar in = c;
+ Byte out[2];
+ UInt32 inUsed, outUsed;
+ TECkit_Status status = TECkit_ConvertBuffer((TECkit_Converter)cnv,
+ (const Byte*)&in, sizeof(in), &inUsed, out, sizeof(out), &outUsed, 1);
+ if (outUsed < 1)
+ return 0;
+ else
+ return out[0];
}
double
read_double(const char** s)
{
- int neg = 0;
- double val = 0.0;
- const char* cp = *s;
-
- while (*cp == ' '|| *cp == '\t')
- ++cp;
- if (*cp == '-') {
- neg = 1;
- ++cp;
- } else if (*cp == '+') {
- ++cp;
- }
-
- while (*cp >= '0' && *cp <= '9') {
- val = val * 10.0 + *cp - '0';
- ++cp;
- }
- if (*cp == '.') {
- double dec = 10.0;
- ++cp;
- while (*cp >= '0' && *cp <= '9') {
- val = val + (*cp - '0') / dec;
- ++cp;
- dec = dec * 10.0;
- }
- }
- *s = cp;
-
- return neg ? -val : val;
+ int neg = 0;
+ double val = 0.0;
+ const char* cp = *s;
+
+ while (*cp == ' '|| *cp == '\t')
+ ++cp;
+ if (*cp == '-') {
+ neg = 1;
+ ++cp;
+ } else if (*cp == '+') {
+ ++cp;
+ }
+
+ while (*cp >= '0' && *cp <= '9') {
+ val = val * 10.0 + *cp - '0';
+ ++cp;
+ }
+ if (*cp == '.') {
+ double dec = 10.0;
+ ++cp;
+ while (*cp >= '0' && *cp <= '9') {
+ val = val + (*cp - '0') / dec;
+ ++cp;
+ dec = dec * 10.0;
+ }
+ }
+ *s = cp;
+
+ return neg ? -val : val;
}
static hb_tag_t
read_tag_with_param(const char* cp, int* param)
{
- const char* cp2;
- hb_tag_t tag;
-
- cp2 = cp;
- while (*cp2 && (*cp2 != ':') && (*cp2 != ';') && (*cp2 != ',') && (*cp2 != '='))
- ++cp2;
-
- tag = hb_tag_from_string(cp, cp2 - cp);
-
- cp = cp2;
- if (*cp == '=') {
- int neg = 0;
- ++cp;
- if (*cp == '-') {
- ++neg;
- ++cp;
- }
- while (*cp >= '0' && *cp <= '9') {
- *param = *param * 10 + *cp - '0';
- ++cp;
- }
- if (neg)
- *param = -(*param);
- }
+ const char* cp2;
+ hb_tag_t tag;
+
+ cp2 = cp;
+ while (*cp2 && (*cp2 != ':') && (*cp2 != ';') && (*cp2 != ',') && (*cp2 != '='))
+ ++cp2;
+
+ tag = hb_tag_from_string(cp, cp2 - cp);
+
+ cp = cp2;
+ if (*cp == '=') {
+ int neg = 0;
+ ++cp;
+ if (*cp == '-') {
+ ++neg;
+ ++cp;
+ }
+ while (*cp >= '0' && *cp <= '9') {
+ *param = *param * 10 + *cp - '0';
+ ++cp;
+ }
+ if (neg)
+ *param = -(*param);
+ }
- return tag;
+ return tag;
}
unsigned int
read_rgb_a(const char** cp)
{
- uint32_t rgbValue = 0;
- uint32_t alpha = 0;
- int i;
- for (i = 0; i < 6; ++i) {
- if ((**cp >= '0') && (**cp <= '9'))
- rgbValue = (rgbValue << 4) + **cp - '0';
- else if ((**cp >= 'A') && (**cp <= 'F'))
- rgbValue = (rgbValue << 4) + **cp - 'A' + 10;
- else if ((**cp >= 'a') && (**cp <= 'f'))
- rgbValue = (rgbValue << 4) + **cp - 'a' + 10;
- else
- return 0x000000FF;
- (*cp)++;
- }
- rgbValue <<= 8;
- for (i = 0; i < 2; ++i) {
- if ((**cp >= '0') && (**cp <= '9'))
- alpha = (alpha << 4) + **cp - '0';
- else if ((**cp >= 'A') && (**cp <= 'F'))
- alpha = (alpha << 4) + **cp - 'A' + 10;
- else if ((**cp >= 'a') && (**cp <= 'f'))
- alpha = (alpha << 4) + **cp - 'a' + 10;
- else
- break;
- (*cp)++;
- }
- if (i == 2)
- rgbValue += alpha;
- else
- rgbValue += 0xFF;
- return rgbValue;
+ uint32_t rgbValue = 0;
+ uint32_t alpha = 0;
+ int i;
+ for (i = 0; i < 6; ++i) {
+ if ((**cp >= '0') && (**cp <= '9'))
+ rgbValue = (rgbValue << 4) + **cp - '0';
+ else if ((**cp >= 'A') && (**cp <= 'F'))
+ rgbValue = (rgbValue << 4) + **cp - 'A' + 10;
+ else if ((**cp >= 'a') && (**cp <= 'f'))
+ rgbValue = (rgbValue << 4) + **cp - 'a' + 10;
+ else
+ return 0x000000FF;
+ (*cp)++;
+ }
+ rgbValue <<= 8;
+ for (i = 0; i < 2; ++i) {
+ if ((**cp >= '0') && (**cp <= '9'))
+ alpha = (alpha << 4) + **cp - '0';
+ else if ((**cp >= 'A') && (**cp <= 'F'))
+ alpha = (alpha << 4) + **cp - 'A' + 10;
+ else if ((**cp >= 'a') && (**cp <= 'f'))
+ alpha = (alpha << 4) + **cp - 'a' + 10;
+ else
+ break;
+ (*cp)++;
+ }
+ if (i == 2)
+ rgbValue += alpha;
+ else
+ rgbValue += 0xFF;
+ return rgbValue;
}
int
readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, uint32_t* rgbValue)
- // returns 1 to go to next_option, -1 for bad_option, 0 to continue
-{
- const char* sep;
- if (strncmp(feat, "mapping", 7) == 0) {
- sep = feat + 7;
- if (*sep != '=')
- return -1;
- loadedfontmapping = load_mapping_file(sep + 1, end, 0);
- return 1;
- }
-
- if (strncmp(feat, "extend", 6) == 0) {
- sep = feat + 6;
- if (*sep != '=')
- return -1;
- ++sep;
- *extend = read_double(&sep);
- return 1;
- }
-
- if (strncmp(feat, "slant", 5) == 0) {
- sep = feat + 5;
- if (*sep != '=')
- return -1;
- ++sep;
- *slant = read_double(&sep);
- return 1;
- }
-
- if (strncmp(feat, "embolden", 8) == 0) {
- sep = feat + 8;
- if (*sep != '=')
- return -1;
- ++sep;
- *embolden = read_double(&sep);
- return 1;
- }
-
- if (strncmp(feat, "letterspace", 11) == 0) {
- sep = feat + 11;
- if (*sep != '=')
- return -1;
- ++sep;
- *letterspace = read_double(&sep);
- return 1;
- }
-
- if (strncmp(feat, "color", 5) == 0) {
- const char* s;
- sep = feat + 5;
- if (*sep != '=')
- return -1;
- ++sep;
- s = sep;
- *rgbValue = read_rgb_a(&sep);
- if ((sep == s+6) || (sep == s+8))
- loadedfontflags |= FONT_FLAGS_COLORED;
- else
- return -1;
- return 1;
- }
-
- return 0;
+ // returns 1 to go to next_option, -1 for bad_option, 0 to continue
+{
+ const char* sep;
+ if (strncmp(feat, "mapping", 7) == 0) {
+ sep = feat + 7;
+ if (*sep != '=')
+ return -1;
+ loadedfontmapping = load_mapping_file(sep + 1, end, 0);
+ return 1;
+ }
+
+ if (strncmp(feat, "extend", 6) == 0) {
+ sep = feat + 6;
+ if (*sep != '=')
+ return -1;
+ ++sep;
+ *extend = read_double(&sep);
+ return 1;
+ }
+
+ if (strncmp(feat, "slant", 5) == 0) {
+ sep = feat + 5;
+ if (*sep != '=')
+ return -1;
+ ++sep;
+ *slant = read_double(&sep);
+ return 1;
+ }
+
+ if (strncmp(feat, "embolden", 8) == 0) {
+ sep = feat + 8;
+ if (*sep != '=')
+ return -1;
+ ++sep;
+ *embolden = read_double(&sep);
+ return 1;
+ }
+
+ if (strncmp(feat, "letterspace", 11) == 0) {
+ sep = feat + 11;
+ if (*sep != '=')
+ return -1;
+ ++sep;
+ *letterspace = read_double(&sep);
+ return 1;
+ }
+
+ if (strncmp(feat, "color", 5) == 0) {
+ const char* s;
+ sep = feat + 5;
+ if (*sep != '=')
+ return -1;
+ ++sep;
+ s = sep;
+ *rgbValue = read_rgb_a(&sep);
+ if ((sep == s+6) || (sep == s+8))
+ loadedfontflags |= FONT_FLAGS_COLORED;
+ else
+ return -1;
+ return 1;
+ }
+
+ return 0;
}
static bool
readFeatureNumber(const char* s, const char* e, hb_tag_t* f, int* v)
- /* s...e is a "id=setting" string; */
-{
- *f = 0;
- *v = 0;
- if (*s < '0' || *s > '9')
- return false;
- while (*s >= '0' && *s <= '9')
- *f = *f * 10 + *s++ - '0';
- while ((*s == ' ') || (*s == '\t'))
- ++s;
- if (*s++ != '=')
- /* no setting was specified */
- return false;
-
- if (*s < '0' || *s > '9')
- return false;
- while (*s >= '0' && *s <= '9')
- *v = *v * 10 + *s++ - '0';
- while ((*s == ' ') || (*s == '\t'))
- ++s;
- if (s != e)
- return false;
- return true;
+ /* s...e is a "id=setting" string; */
+{
+ *f = 0;
+ *v = 0;
+ if (*s < '0' || *s > '9')
+ return false;
+ while (*s >= '0' && *s <= '9')
+ *f = *f * 10 + *s++ - '0';
+ while ((*s == ' ') || (*s == '\t'))
+ ++s;
+ if (*s++ != '=')
+ /* no setting was specified */
+ return false;
+
+ if (*s < '0' || *s > '9')
+ return false;
+ while (*s >= '0' && *s <= '9')
+ *v = *v * 10 + *s++ - '0';
+ while ((*s == ' ') || (*s == '\t'))
+ ++s;
+ if (s != e)
+ return false;
+ return true;
}
static void*
loadOTfont(PlatformFontRef fontRef, XeTeXFont font, Fixed scaled_size, const char* cp1)
{
- XeTeXLayoutEngine engine;
- hb_tag_t script = HB_TAG_NONE;
- hb_tag_t language = HB_TAG_NONE;
- hb_feature_t* features = NULL;
- char** shapers = NULL; /* NULL-terminated array */
- int nFeatures = 0;
- int nShapers = 0;
-
- const char* cp2;
- const char* cp3;
-
- hb_tag_t tag;
-
- uint32_t rgbValue = 0x000000FF;
-
- float extend = 1.0;
- float slant = 0.0;
- float embolden = 0.0;
- float letterspace = 0.0;
-
- int i;
-
- char reqEngine = getReqEngine();
-
- if (reqEngine == 'O' || reqEngine == 'G') {
- shapers = xrealloc(shapers, (nShapers + 1) * sizeof(char *));
- if (reqEngine == 'O')
- shapers[nShapers] = strdup("ot");
- else if (reqEngine == 'G')
- shapers[nShapers] = strdup("graphite2");
- nShapers++;
- }
-
- if (reqEngine == 'G') {
- char* tmpShapers[] = {shapers[0]};
- /* create a default engine so we can query the font for Graphite features;
- * because of font caching, it's cheap to discard this and create the real one later */
- engine = createLayoutEngine(fontRef, font, script, language,
- features, nFeatures, tmpShapers, rgbValue, extend, slant, embolden);
-
- if (engine == NULL)
- return NULL;
- }
-
- /* scan the feature string (if any) */
- if (cp1 != NULL) {
- while (*cp1) {
- if ((*cp1 == ':') || (*cp1 == ';') || (*cp1 == ','))
- ++cp1;
- while ((*cp1 == ' ') || (*cp1 == '\t')) /* skip leading whitespace */
- ++cp1;
- if (*cp1 == 0) /* break if end of string */
- break;
-
- cp2 = cp1;
- while (*cp2 && (*cp2 != ':') && (*cp2 != ';') && (*cp2 != ','))
- ++cp2;
-
- if (strncmp(cp1, "script", 6) == 0) {
- cp3 = cp1 + 6;
- if (*cp3 != '=')
- goto bad_option;
- ++cp3;
- script = hb_tag_from_string(cp3, cp2 - cp3);
- goto next_option;
- }
-
- if (strncmp(cp1, "language", 8) == 0) {
- cp3 = cp1 + 8;
- if (*cp3 != '=')
- goto bad_option;
- ++cp3;
- language = hb_tag_from_string(cp3, cp2 - cp3);
- goto next_option;
- }
-
- if (strncmp(cp1, "shaper", 6) == 0) {
- cp3 = cp1 + 6;
- if (*cp3 != '=')
- goto bad_option;
- ++cp3;
- shapers = xrealloc(shapers, (nShapers + 1) * sizeof(char *));
- /* some dumb systems have no strndup() */
- shapers[nShapers] = strdup(cp3);
- shapers[nShapers][cp2 - cp3] = '\0';
- nShapers++;
- goto next_option;
- }
-
- i = readCommonFeatures(cp1, cp2, &extend, &slant, &embolden, &letterspace, &rgbValue);
- if (i == 1)
- goto next_option;
- else if (i == -1)
- goto bad_option;
-
- if (reqEngine == 'G') {
- int value = 0;
- if (readFeatureNumber(cp1, cp2, &tag, &value)
- || findGraphiteFeature(engine, cp1, cp2, &tag, &value)) {
- features = xrealloc(features, (nFeatures + 1) * sizeof(hb_feature_t));
- features[nFeatures].tag = tag;
- features[nFeatures].value = value;
- features[nFeatures].start = 0;
- features[nFeatures].end = (unsigned int) -1;
- nFeatures++;
- goto next_option;
- }
- }
-
- if (*cp1 == '+') {
- int param = 0;
- tag = read_tag_with_param(cp1 + 1, &param);
- features = xrealloc(features, (nFeatures + 1) * sizeof(hb_feature_t));
- features[nFeatures].tag = tag;
- features[nFeatures].start = 0;
- features[nFeatures].end = (unsigned int) -1;
- // for backward compatibility with pre-0.9999 where feature
- // indices started from 0
- if (param >= 0)
- param++;
- features[nFeatures].value = param;
- nFeatures++;
- goto next_option;
- }
-
- if (*cp1 == '-') {
- ++cp1;
- tag = hb_tag_from_string(cp1, cp2 - cp1);
- features = xrealloc(features, (nFeatures + 1) * sizeof(hb_feature_t));
- features[nFeatures].tag = tag;
- features[nFeatures].start = 0;
- features[nFeatures].end = (unsigned int) -1;
- features[nFeatures].value = 0;
- nFeatures++;
- goto next_option;
- }
-
- if (strncmp(cp1, "vertical", 8) == 0) {
- cp3 = cp2;
- if (*cp3 == ';' || *cp3 == ':' || *cp3 == ',')
- --cp3;
- while (*cp3 == '\0' || *cp3 == ' ' || *cp3 == '\t')
- --cp3;
- if (*cp3)
- ++cp3;
- if (cp3 == cp1 + 8) {
- loadedfontflags |= FONT_FLAGS_VERTICAL;
- goto next_option;
- }
- }
-
- bad_option:
- fontfeaturewarning(cp1, cp2 - cp1, 0, 0);
-
- next_option:
- cp1 = cp2;
- }
- }
-
- if (shapers != NULL) {
- shapers = xrealloc(shapers, (nShapers + 1) * sizeof(char *));
- shapers[nShapers] = NULL;
- }
-
- if (embolden != 0.0)
- embolden = embolden * Fix2D(scaled_size) / 100.0;
-
- if (letterspace != 0.0)
- loadedfontletterspace = (letterspace / 100.0) * scaled_size;
-
- if ((loadedfontflags & FONT_FLAGS_COLORED) == 0)
- rgbValue = 0x000000FF;
-
- if ((loadedfontflags & FONT_FLAGS_VERTICAL) != 0)
- setFontLayoutDir(font, 1);
-
- engine = createLayoutEngine(fontRef, font, script, language,
- features, nFeatures, shapers, rgbValue, extend, slant, embolden);
-
- if (engine == 0) {
- // only free these if creation failed, otherwise the engine now owns them
- free(features);
- free(shapers);
- } else {
- nativefonttypeflag = OTGR_FONT_FLAG;
- }
-
- return engine;
+ XeTeXLayoutEngine engine;
+ hb_tag_t script = HB_TAG_NONE;
+ char * language = NULL;
+ hb_feature_t* features = NULL;
+ char** shapers = NULL; /* NULL-terminated array */
+ int nFeatures = 0;
+ int nShapers = 0;
+
+ const char* cp2;
+ const char* cp3;
+
+ hb_tag_t tag;
+
+ uint32_t rgbValue = 0x000000FF;
+
+ float extend = 1.0;
+ float slant = 0.0;
+ float embolden = 0.0;
+ float letterspace = 0.0;
+
+ int i;
+
+ char reqEngine = getReqEngine();
+
+ if (reqEngine == 'O' || reqEngine == 'G') {
+ shapers = (char**) xrealloc(shapers, (nShapers + 1) * sizeof(char *));
+ if (reqEngine == 'O')
+ shapers[nShapers] = "ot";
+ else if (reqEngine == 'G')
+ shapers[nShapers] = "graphite2";
+ nShapers++;
+ }
+
+ if (reqEngine == 'G') {
+ char* tmpShapers[] = {shapers[0]};
+ /* create a default engine so we can query the font for Graphite features;
+ * because of font caching, it's cheap to discard this and create the real one later */
+ engine = createLayoutEngine(fontRef, font, script, language,
+ features, nFeatures, tmpShapers, rgbValue, extend, slant, embolden);
+
+ if (engine == NULL)
+ return NULL;
+ }
+
+ /* scan the feature string (if any) */
+ if (cp1 != NULL) {
+ while (*cp1) {
+ if ((*cp1 == ':') || (*cp1 == ';') || (*cp1 == ','))
+ ++cp1;
+ while ((*cp1 == ' ') || (*cp1 == '\t')) /* skip leading whitespace */
+ ++cp1;
+ if (*cp1 == 0) /* break if end of string */
+ break;
+
+ cp2 = cp1;
+ while (*cp2 && (*cp2 != ':') && (*cp2 != ';') && (*cp2 != ','))
+ ++cp2;
+
+ if (strncmp(cp1, "script", 6) == 0) {
+ cp3 = cp1 + 6;
+ if (*cp3 != '=')
+ goto bad_option;
+ ++cp3;
+ script = hb_tag_from_string(cp3, cp2 - cp3);
+ goto next_option;
+ }
+
+ if (strncmp(cp1, "language", 8) == 0) {
+ cp3 = cp1 + 8;
+ if (*cp3 != '=')
+ goto bad_option;
+ ++cp3;
+ language = (char*)xmalloc(cp2 - cp3 + 1);
+ language[cp2 - cp3] = '\0';
+ memcpy(language, cp3, cp2 - cp3);
+ goto next_option;
+ }
+
+ if (strncmp(cp1, "shaper", 6) == 0) {
+ cp3 = cp1 + 6;
+ if (*cp3 != '=')
+ goto bad_option;
+ ++cp3;
+ shapers = (char**) xrealloc(shapers, (nShapers + 1) * sizeof(char *));
+ /* some dumb systems have no strndup() */
+ shapers[nShapers] = strdup(cp3);
+ shapers[nShapers][cp2 - cp3] = '\0';
+ nShapers++;
+ goto next_option;
+ }
+
+ i = readCommonFeatures(cp1, cp2, &extend, &slant, &embolden, &letterspace, &rgbValue);
+ if (i == 1)
+ goto next_option;
+ else if (i == -1)
+ goto bad_option;
+
+ if (reqEngine == 'G') {
+ int value = 0;
+ if (readFeatureNumber(cp1, cp2, &tag, &value)
+ || findGraphiteFeature(engine, cp1, cp2, &tag, &value)) {
+ features = (hb_feature_t*) xrealloc(features, (nFeatures + 1) * sizeof(hb_feature_t));
+ features[nFeatures].tag = tag;
+ features[nFeatures].value = value;
+ features[nFeatures].start = 0;
+ features[nFeatures].end = (unsigned int) -1;
+ nFeatures++;
+ goto next_option;
+ }
+ }
+
+ if (*cp1 == '+') {
+ int param = 0;
+ tag = read_tag_with_param(cp1 + 1, &param);
+ features = (hb_feature_t*) xrealloc(features, (nFeatures + 1) * sizeof(hb_feature_t));
+ features[nFeatures].tag = tag;
+ features[nFeatures].start = 0;
+ features[nFeatures].end = (unsigned int) -1;
+ // for backward compatibility with pre-0.9999 where feature
+ // indices started from 0
+ if (param >= 0)
+ param++;
+ features[nFeatures].value = param;
+ nFeatures++;
+ goto next_option;
+ }
+
+ if (*cp1 == '-') {
+ ++cp1;
+ tag = hb_tag_from_string(cp1, cp2 - cp1);
+ features = (hb_feature_t*) xrealloc(features, (nFeatures + 1) * sizeof(hb_feature_t));
+ features[nFeatures].tag = tag;
+ features[nFeatures].start = 0;
+ features[nFeatures].end = (unsigned int) -1;
+ features[nFeatures].value = 0;
+ nFeatures++;
+ goto next_option;
+ }
+
+ if (strncmp(cp1, "vertical", 8) == 0) {
+ cp3 = cp2;
+ if (*cp3 == ';' || *cp3 == ':' || *cp3 == ',')
+ --cp3;
+ while (*cp3 == '\0' || *cp3 == ' ' || *cp3 == '\t')
+ --cp3;
+ if (*cp3)
+ ++cp3;
+ if (cp3 == cp1 + 8) {
+ loadedfontflags |= FONT_FLAGS_VERTICAL;
+ goto next_option;
+ }
+ }
+
+ bad_option:
+ fontfeaturewarning((void*) cp1, cp2 - cp1, 0, 0);
+
+ next_option:
+ cp1 = cp2;
+ }
+ }
+
+ if (shapers != NULL) {
+ shapers = (char**) xrealloc(shapers, (nShapers + 1) * sizeof(char *));
+ shapers[nShapers] = NULL;
+ }
+
+ if (embolden != 0.0)
+ embolden = embolden * Fix2D(scaled_size) / 100.0;
+
+ if (letterspace != 0.0)
+ loadedfontletterspace = (letterspace / 100.0) * scaled_size;
+
+ if ((loadedfontflags & FONT_FLAGS_COLORED) == 0)
+ rgbValue = 0x000000FF;
+
+ if ((loadedfontflags & FONT_FLAGS_VERTICAL) != 0)
+ setFontLayoutDir(font, 1);
+
+ engine = createLayoutEngine(fontRef, font, script, language,
+ features, nFeatures, shapers, rgbValue, extend, slant, embolden);
+
+ if (engine == 0) {
+ // only free these if creation failed, otherwise the engine now owns them
+ free(features);
+ free(shapers);
+ } else {
+ nativefonttypeflag = OTGR_FONT_FLAG;
+ }
+
+ return engine;
}
static void
splitFontName(char* name, char** var, char** feat, char** end, int* index)
{
- *var = NULL;
- *feat = NULL;
- *index = 0;
- if (*name == '[') {
- int withinFileName = 1;
+ *var = NULL;
+ *feat = NULL;
+ *index = 0;
+ if (*name == '[') {
+ int withinFileName = 1;
#ifdef WIN32
- char* start = name + 1;
+ char* start = name + 1;
#endif
- ++name;
- while (*name) {
- if (withinFileName && *name == ']') {
- withinFileName = 0;
- if (*var == NULL)
- *var = name;
- } else if (*name == ':') {
- if (withinFileName && *var == NULL
+ ++name;
+ while (*name) {
+ if (withinFileName && *name == ']') {
+ withinFileName = 0;
+ if (*var == NULL)
+ *var = name;
+ } else if (*name == ':') {
+ if (withinFileName && *var == NULL
#ifdef WIN32
- && !((name - start == 1) && isalpha(*start))
+ && !((name - start == 1) && isalpha(*start))
#endif
- ) {
- *var = name;
- ++name;
- while (*name >= '0' && *name <= '9')
- *index = *index * 10 + *name++ - '0';
- --name;
- } else if (!withinFileName && *feat == NULL)
- *feat = name;
- }
- ++name;
- }
- *end = name;
- } else {
- while (*name) {
- if (*name == '/' && *var == NULL && *feat == NULL)
- *var = name;
- else if (*name == ':' && *feat == NULL)
- *feat = name;
- ++name;
- }
- *end = name;
- }
- if (*feat == NULL)
- *feat = name;
- if (*var == NULL)
- *var = *feat;
+ ) {
+ *var = name;
+ ++name;
+ while (*name >= '0' && *name <= '9')
+ *index = *index * 10 + *name++ - '0';
+ --name;
+ } else if (!withinFileName && *feat == NULL)
+ *feat = name;
+ }
+ ++name;
+ }
+ *end = name;
+ } else {
+ while (*name) {
+ if (*name == '/' && *var == NULL && *feat == NULL)
+ *var = name;
+ else if (*name == ':' && *feat == NULL)
+ *feat = name;
+ ++name;
+ }
+ *end = name;
+ }
+ if (*feat == NULL)
+ *feat = name;
+ if (*var == NULL)
+ *var = *feat;
}
void*
findnativefont(unsigned char* uname, integer scaled_size)
- /* scaled_size here is in TeX points, or is a negative integer for 'scaled' */
-{
- void* rval = NULL;
- char* nameString;
- char* var;
- char* feat;
- char* end;
- char* name = (char*)uname;
- char* varString = NULL;
- char* featString = NULL;
- PlatformFontRef fontRef;
- XeTeXFont font = NULL;
- int index = 0;
-
- loadedfontmapping = NULL;
- loadedfontflags = 0;
- loadedfontletterspace = 0;
-
- splitFontName(name, &var, &feat, &end, &index);
- nameString = xmalloc(var - name + 1);
- strncpy(nameString, name, var - name);
- nameString[var - name] = 0;
-
- if (feat > var) {
- varString = xmalloc(feat - var);
- strncpy(varString, var + 1, feat - var - 1);
- varString[feat - var - 1] = 0;
- }
-
- if (end > feat) {
- featString = xmalloc(end - feat);
- strncpy(featString, feat + 1, end - feat - 1);
- featString[end - feat - 1] = 0;
- }
-
- // check for "[filename]" form, don't search maps in this case
- if (nameString[0] == '[') {
- char* path = kpse_find_file(nameString + 1, kpse_opentype_format, 0);
- if (path == NULL)
- path = kpse_find_file(nameString + 1, kpse_truetype_format, 0);
- if (path == NULL)
- path = kpse_find_file(nameString + 1, kpse_type1_format, 0);
- if (path != NULL) {
- if (scaled_size < 0) {
- font = createFontFromFile(path, index, 655360L);
- if (font != NULL) {
- Fixed dsize = D2Fix(getDesignSize(font));
- if (scaled_size == -1000)
- scaled_size = dsize;
- else
- scaled_size = zxnoverd(dsize, -scaled_size, 1000);
- deleteFont(font);
- }
- }
- font = createFontFromFile(path, index, scaled_size);
- if (font != NULL) {
- loadedfontdesignsize = D2Fix(getDesignSize(font));
-
- /* This is duplicated in XeTeXFontMgr::findFont! */
- setReqEngine(0);
- if (varString) {
- if (strncmp(varString, "/AAT", 4) == 0)
- setReqEngine('A');
- else if ((strncmp(varString, "/OT", 3) == 0) || (strncmp(varString, "/ICU", 4) == 0))
- setReqEngine('O');
- else if (strncmp(varString, "/GR", 3) == 0)
- setReqEngine('G');
- }
-
- rval = loadOTfont(0, font, scaled_size, featString);
- if (rval == NULL)
- deleteFont(font);
- if (rval != NULL && gettracingfontsstate() > 0) {
- begindiagnostic();
- zprintnl(' ');
- printcstring("-> ");
- printcstring(path);
- zenddiagnostic(0);
- }
- }
- }
- } else {
- fontRef = findFontByName(nameString, varString, Fix2D(scaled_size));
-
- if (fontRef != 0) {
- /* update nameoffile to the full name of the font, for error messages during font loading */
- const char* fullName = getFullName(fontRef);
- namelength = strlen(fullName);
- if (featString != NULL)
- namelength += strlen(featString) + 1;
- if (varString != NULL)
- namelength += strlen(varString) + 1;
- free(nameoffile);
- nameoffile = xmalloc(namelength + 4); /* +2 would be correct: initial space, final NUL */
- nameoffile[0] = ' ';
- strcpy((char*)nameoffile + 1, fullName);
-
- if (scaled_size < 0) {
- font = createFont(fontRef, scaled_size);
- if (font != NULL) {
- Fixed dsize = D2Fix(getDesignSize(font));
- if (scaled_size == -1000)
- scaled_size = dsize;
- else
- scaled_size = zxnoverd(dsize, -scaled_size, 1000);
- deleteFont(font);
- }
- }
-
- font = createFont(fontRef, scaled_size);
- if (font != NULL) {
+ /* scaled_size here is in TeX points, or is a negative integer for 'scaled' */
+{
+ void* rval = NULL;
+ char* nameString;
+ char* var;
+ char* feat;
+ char* end;
+ char* name = (char*)uname;
+ char* varString = NULL;
+ char* featString = NULL;
+ PlatformFontRef fontRef;
+ XeTeXFont font = NULL;
+ int index = 0;
+
+ loadedfontmapping = NULL;
+ loadedfontflags = 0;
+ loadedfontletterspace = 0;
+
+ splitFontName(name, &var, &feat, &end, &index);
+ nameString = (char*) xmalloc(var - name + 1);
+ strncpy(nameString, name, var - name);
+ nameString[var - name] = 0;
+
+ if (feat > var) {
+ varString = (char*) xmalloc(feat - var);
+ strncpy(varString, var + 1, feat - var - 1);
+ varString[feat - var - 1] = 0;
+ }
+
+ if (end > feat) {
+ featString = (char*) xmalloc(end - feat);
+ strncpy(featString, feat + 1, end - feat - 1);
+ featString[end - feat - 1] = 0;
+ }
+
+ // check for "[filename]" form, don't search maps in this case
+ if (nameString[0] == '[') {
+ char* path = kpse_find_file(nameString + 1, kpse_opentype_format, 0);
+ if (path == NULL)
+ path = kpse_find_file(nameString + 1, kpse_truetype_format, 0);
+ if (path == NULL)
+ path = kpse_find_file(nameString + 1, kpse_type1_format, 0);
+ if (path != NULL) {
+ if (scaled_size < 0) {
+ font = createFontFromFile(path, index, 655360L);
+ if (font != NULL) {
+ Fixed dsize = D2Fix(getDesignSize(font));
+ if (scaled_size == -1000)
+ scaled_size = dsize;
+ else
+ scaled_size = zxnoverd(dsize, -scaled_size, 1000);
+ deleteFont(font);
+ }
+ }
+ font = createFontFromFile(path, index, scaled_size);
+ if (font != NULL) {
+ loadedfontdesignsize = D2Fix(getDesignSize(font));
+
+ /* This is duplicated in XeTeXFontMgr::findFont! */
+ setReqEngine(0);
+ if (varString) {
+ if (strncmp(varString, "/AAT", 4) == 0)
+ setReqEngine('A');
+ else if ((strncmp(varString, "/OT", 3) == 0) || (strncmp(varString, "/ICU", 4) == 0))
+ setReqEngine('O');
+ else if (strncmp(varString, "/GR", 3) == 0)
+ setReqEngine('G');
+ }
+
+ rval = loadOTfont(0, font, scaled_size, featString);
+ if (rval == NULL)
+ deleteFont(font);
+ if (rval != NULL && gettracingfontsstate() > 0) {
+ begindiagnostic();
+ zprintnl(' ');
+ printcstring("-> ");
+ printcstring(path);
+ zenddiagnostic(0);
+ }
+ }
+ }
+ } else {
+ fontRef = findFontByName(nameString, varString, Fix2D(scaled_size));
+
+ if (fontRef != 0) {
+ /* update nameoffile to the full name of the font, for error messages during font loading */
+ const char* fullName = getFullName(fontRef);
+ namelength = strlen(fullName);
+ if (featString != NULL)
+ namelength += strlen(featString) + 1;
+ if (varString != NULL)
+ namelength += strlen(varString) + 1;
+ free(nameoffile);
+ nameoffile = xmalloc(namelength + 4); /* +2 would be correct: initial space, final NUL */
+ nameoffile[0] = ' ';
+ strcpy((char*)nameoffile + 1, fullName);
+
+ if (scaled_size < 0) {
+ font = createFont(fontRef, scaled_size);
+ if (font != NULL) {
+ Fixed dsize = D2Fix(getDesignSize(font));
+ if (scaled_size == -1000)
+ scaled_size = dsize;
+ else
+ scaled_size = zxnoverd(dsize, -scaled_size, 1000);
+ deleteFont(font);
+ }
+ }
+
+ font = createFont(fontRef, scaled_size);
+ if (font != NULL) {
#ifdef XETEX_MAC
- /* decide whether to use AAT or OpenType rendering with this font */
- if (getReqEngine() == 'A') {
- rval = loadAATfont(fontRef, scaled_size, featString);
- if (rval == NULL)
- deleteFont(font);
- } else {
- if (getReqEngine() == 'O' || getReqEngine() == 'G' ||
- getFontTablePtr(font, kGSUB) != NULL || getFontTablePtr(font, kGPOS) != NULL)
- rval = loadOTfont(fontRef, font, scaled_size, featString);
-
- /* loadOTfont failed or the above check was false */
- if (rval == NULL)
- rval = loadAATfont(fontRef, scaled_size, featString);
-
- if (rval == NULL)
- deleteFont(font);
- }
+ /* decide whether to use AAT or OpenType rendering with this font */
+ if (getReqEngine() == 'A') {
+ rval = loadAATfont(fontRef, scaled_size, featString);
+ if (rval == NULL)
+ deleteFont(font);
+ } else {
+ if (getReqEngine() == 'O' || getReqEngine() == 'G' ||
+ getFontTablePtr(font, kGSUB) != NULL || getFontTablePtr(font, kGPOS) != NULL)
+ rval = loadOTfont(fontRef, font, scaled_size, featString);
+
+ /* loadOTfont failed or the above check was false */
+ if (rval == NULL)
+ rval = loadAATfont(fontRef, scaled_size, featString);
+
+ if (rval == NULL)
+ deleteFont(font);
+ }
#else
- rval = loadOTfont(fontRef, font, scaled_size, featString);
- if (rval == NULL)
- deleteFont(font);
+ rval = loadOTfont(fontRef, font, scaled_size, featString);
+ if (rval == NULL)
+ deleteFont(font);
#endif
- }
-
- /* append the style and feature strings, so that \show\fontID will give a full result */
- if (varString != NULL && *varString != 0) {
- strcat((char*)nameoffile + 1, "/");
- strcat((char*)nameoffile + 1, varString);
- }
- if (featString != NULL && *featString != 0) {
- strcat((char*)nameoffile + 1, ":");
- strcat((char*)nameoffile + 1, featString);
- }
- namelength = strlen((char*)nameoffile + 1);
- }
- }
-
- if (varString != NULL)
- free(varString);
-
- if (featString != NULL)
- free(featString);
-
- free(nameString);
-
- return rval;
+ }
+
+ /* append the style and feature strings, so that \show\fontID will give a full result */
+ if (varString != NULL && *varString != 0) {
+ strcat((char*)nameoffile + 1, "/");
+ strcat((char*)nameoffile + 1, varString);
+ }
+ if (featString != NULL && *featString != 0) {
+ strcat((char*)nameoffile + 1, ":");
+ strcat((char*)nameoffile + 1, featString);
+ }
+ namelength = strlen((char*)nameoffile + 1);
+ }
+ }
+
+ if (varString != NULL)
+ free(varString);
+
+ if (featString != NULL)
+ free(featString);
+
+ free(nameString);
+
+ return rval;
}
void
releasefontengine(void* engine, int type_flag)
{
#ifdef XETEX_MAC
- if (type_flag == AAT_FONT_FLAG) {
- CFRelease((CFDictionaryRef)engine);
- } else
+ if (type_flag == AAT_FONT_FLAG) {
+ CFRelease((CFDictionaryRef)engine);
+ } else
#endif
- if (type_flag == OTGR_FONT_FLAG) {
- deleteLayoutEngine((XeTeXLayoutEngine)engine);
- }
+ if (type_flag == OTGR_FONT_FLAG) {
+ deleteLayoutEngine((XeTeXLayoutEngine)engine);
+ }
}
/* params are given as 'integer' in the header file, but are really TeX scaled integers */
void
otgetfontmetrics(void* pEngine, scaled* ascent, scaled* descent, scaled* xheight, scaled* capheight, scaled* slant)
{
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
- float a, d;
-
- getAscentAndDescent(engine, &a, &d);
- *ascent = D2Fix(a);
- *descent = D2Fix(d);
-
- *slant = D2Fix(Fix2D(getSlant(getFont(engine))) * getExtendFactor(engine)
- + getSlantFactor(engine));
-
- /* get cap and x height from OS/2 table */
- getCapAndXHeight(engine, &a, &d);
- *capheight = D2Fix(a);
- *xheight = D2Fix(d);
-
- /* fallback in case the font does not have OS/2 table */
- if (*xheight == 0) {
- int glyphID = mapCharToGlyph(engine, 'x');
- if (glyphID != 0) {
- getGlyphHeightDepth(engine, glyphID, &a, &d);
- *xheight = D2Fix(a);
- } else {
- *xheight = *ascent / 2; /* arbitrary figure if there's no 'x' in the font */
- }
- }
-
- if (*capheight == 0) {
- int glyphID = mapCharToGlyph(engine, 'X');
- if (glyphID != 0) {
- getGlyphHeightDepth(engine, glyphID, &a, &d);
- *capheight = D2Fix(a);
- } else {
- *capheight = *ascent; /* arbitrary figure if there's no 'X' in the font */
- }
- }
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
+ float a, d;
+
+ getAscentAndDescent(engine, &a, &d);
+ *ascent = D2Fix(a);
+ *descent = D2Fix(d);
+
+ *slant = D2Fix(Fix2D(getSlant(getFont(engine))) * getExtendFactor(engine)
+ + getSlantFactor(engine));
+
+ /* get cap and x height from OS/2 table */
+ getCapAndXHeight(engine, &a, &d);
+ *capheight = D2Fix(a);
+ *xheight = D2Fix(d);
+
+ /* fallback in case the font does not have OS/2 table */
+ if (*xheight == 0) {
+ int glyphID = mapCharToGlyph(engine, 'x');
+ if (glyphID != 0) {
+ getGlyphHeightDepth(engine, glyphID, &a, &d);
+ *xheight = D2Fix(a);
+ } else {
+ *xheight = *ascent / 2; /* arbitrary figure if there's no 'x' in the font */
+ }
+ }
+
+ if (*capheight == 0) {
+ int glyphID = mapCharToGlyph(engine, 'X');
+ if (glyphID != 0) {
+ getGlyphHeightDepth(engine, glyphID, &a, &d);
+ *capheight = D2Fix(a);
+ } else {
+ *capheight = *ascent; /* arbitrary figure if there's no 'X' in the font */
+ }
+ }
}
integer
otfontget(integer what, void* pEngine)
{
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
- XeTeXFont fontInst = getFont(engine);
- switch (what) {
- case XeTeX_count_glyphs:
- return countGlyphs(fontInst);
- break;
-
- case XeTeX_count_features: /* ie Graphite features */
- return countGraphiteFeatures(engine);
- break;
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
+ XeTeXFont fontInst = getFont(engine);
+ switch (what) {
+ case XeTeX_count_glyphs:
+ return countGlyphs(fontInst);
+ break;
- case XeTeX_OT_count_scripts:
- return countScripts(fontInst);
- break;
- }
- return 0;
+ case XeTeX_count_features: /* ie Graphite features */
+ return countGraphiteFeatures(engine);
+ break;
+
+ case XeTeX_OT_count_scripts:
+ return countScripts(fontInst);
+ break;
+ }
+ return 0;
}
integer
otfontget1(integer what, void* pEngine, integer param)
{
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
- XeTeXFont fontInst = getFont(engine);
- switch (what) {
- case XeTeX_OT_count_languages:
- return countLanguages(fontInst, param);
- break;
-
- case XeTeX_OT_script_code:
- return getIndScript(fontInst, param);
- break;
-
- /* for graphite fonts...*/
- case XeTeX_feature_code:
- return getGraphiteFeatureCode(engine, param);
- break;
- case XeTeX_is_exclusive_feature:
- return 1;
- break;
- case XeTeX_count_selectors:
- return countGraphiteFeatureSettings(engine, param);
- break;
- }
- return 0;
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
+ XeTeXFont fontInst = getFont(engine);
+ switch (what) {
+ case XeTeX_OT_count_languages:
+ return countLanguages(fontInst, param);
+ break;
+
+ case XeTeX_OT_script_code:
+ return getIndScript(fontInst, param);
+ break;
+
+ /* for graphite fonts...*/
+ case XeTeX_feature_code:
+ return getGraphiteFeatureCode(engine, param);
+ break;
+ case XeTeX_is_exclusive_feature:
+ return 1;
+ break;
+ case XeTeX_count_selectors:
+ return countGraphiteFeatureSettings(engine, param);
+ break;
+ }
+ return 0;
}
integer
otfontget2(integer what, void* pEngine, integer param1, integer param2)
{
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
- XeTeXFont fontInst = getFont(engine);
- switch (what) {
- case XeTeX_OT_language_code:
- return getIndLanguage(fontInst, param1, param2);
- break;
-
- case XeTeX_OT_count_features:
- return countFeatures(fontInst, param1, param2);
- break;
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
+ XeTeXFont fontInst = getFont(engine);
+ switch (what) {
+ case XeTeX_OT_language_code:
+ return getIndLanguage(fontInst, param1, param2);
+ break;
+
+ case XeTeX_OT_count_features:
+ return countFeatures(fontInst, param1, param2);
+ break;
+
+ /* for graphite fonts */
+ case XeTeX_selector_code:
+ return getGraphiteFeatureSettingCode(engine, param1, param2);
+ break;
+ case XeTeX_is_default_selector:
+ return getGraphiteFeatureDefaultSetting(engine, param1) == param2;
+ break;
+ }
- /* for graphite fonts */
- case XeTeX_selector_code:
- return getGraphiteFeatureSettingCode(engine, param1, param2);
- break;
- case XeTeX_is_default_selector:
- return getGraphiteFeatureDefaultSetting(engine, param1) == param2;
- break;
- }
-
- return 0;
+ return 0;
}
integer
otfontget3(integer what, void* pEngine, integer param1, integer param2, integer param3)
{
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
- XeTeXFont fontInst = getFont(engine);
- switch (what) {
- case XeTeX_OT_feature_code:
- return getIndFeature(fontInst, param1, param2, param3);
- break;
- }
-
- return 0;
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
+ XeTeXFont fontInst = getFont(engine);
+ switch (what) {
+ case XeTeX_OT_feature_code:
+ return getIndFeature(fontInst, param1, param2, param3);
+ break;
+ }
+
+ return 0;
}
void
grprintfontname(integer what, void* pEngine, integer param1, integer param2)
{
- char* name = NULL;
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
- switch (what) {
- case XeTeX_feature_name:
- name = getGraphiteFeatureLabel(engine, param1);
- break;
- case XeTeX_selector_name:
- name = getGraphiteFeatureSettingLabel(engine, param1, param2);
- break;
- }
+ char* name = NULL;
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
+ switch (what) {
+ case XeTeX_feature_name:
+ name = getGraphiteFeatureLabel(engine, param1);
+ break;
+ case XeTeX_selector_name:
+ name = getGraphiteFeatureSettingLabel(engine, param1, param2);
+ break;
+ }
- if (name != NULL) {
- printcstring(name);
- gr_label_destroy(name);
- }
+ if (name != NULL) {
+ printcstring(name);
+ gr_label_destroy(name);
+ }
}
integer
grfontgetnamed(integer what, void* pEngine)
{
- long rval = -1;
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
- switch (what) {
- case XeTeX_find_feature_by_name:
- rval = findGraphiteFeatureNamed(engine, (const char*)nameoffile + 1, namelength);
- break;
- }
- return rval;
+ long rval = -1;
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
+ switch (what) {
+ case XeTeX_find_feature_by_name:
+ rval = findGraphiteFeatureNamed(engine, (const char*)nameoffile + 1, namelength);
+ break;
+ }
+ return rval;
}
integer
grfontgetnamed1(integer what, void* pEngine, integer param)
{
- long rval = -1;
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
- switch (what) {
- case XeTeX_find_selector_by_name:
- rval = findGraphiteFeatureSettingNamed(engine, param, (const char*)nameoffile + 1, namelength);
- break;
- }
- return rval;
+ long rval = -1;
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)pEngine;
+ switch (what) {
+ case XeTeX_find_selector_by_name:
+ rval = findGraphiteFeatureSettingNamed(engine, param, (const char*)nameoffile + 1, namelength);
+ break;
+ }
+ return rval;
}
-#define XDV_FLAG_FONTTYPE_AAT 0x0001
-#define XDV_FLAG_FONTTYPE_OT 0x0002
+#define XDV_FLAG_FONTTYPE_AAT 0x0001
+#define XDV_FLAG_FONTTYPE_OT 0x0002
-#define XDV_FLAG_VERTICAL 0x0100
-#define XDV_FLAG_COLORED 0x0200
-#define XDV_FLAG_FEATURES 0x0400
-#define XDV_FLAG_VARIATIONS 0x0800
-#define XDV_FLAG_EXTEND 0x1000
-#define XDV_FLAG_SLANT 0x2000
-#define XDV_FLAG_EMBOLDEN 0x4000
+#define XDV_FLAG_VERTICAL 0x0100
+#define XDV_FLAG_COLORED 0x0200
+#define XDV_FLAG_FEATURES 0x0400
+#define XDV_FLAG_VARIATIONS 0x0800
+#define XDV_FLAG_EXTEND 0x1000
+#define XDV_FLAG_SLANT 0x2000
+#define XDV_FLAG_EMBOLDEN 0x4000
#ifdef XETEX_MAC
static UInt32
cgColorToRGBA32(CGColorRef color)
{
- const CGFloat *components = CGColorGetComponents(color);
+ const CGFloat *components = CGColorGetComponents(color);
- UInt32 rval = (UInt8)(components[0] * 255.0 + 0.5);
- rval <<= 8;
- rval += (UInt8)(components[1] * 255.0 + 0.5);
- rval <<= 8;
- rval += (UInt8)(components[2] * 255.0 + 0.5);
- rval <<= 8;
- rval += (UInt8)(components[3] * 255.0 + 0.5);
- return rval;
+ UInt32 rval = (UInt8)(components[0] * 255.0 + 0.5);
+ rval <<= 8;
+ rval += (UInt8)(components[1] * 255.0 + 0.5);
+ rval <<= 8;
+ rval += (UInt8)(components[2] * 255.0 + 0.5);
+ rval <<= 8;
+ rval += (UInt8)(components[3] * 255.0 + 0.5);
+ return rval;
}
#endif
-static int xdvBufSize = 0;
+static int xdvBufSize = 0;
int
makeXDVGlyphArrayData(void* pNode)
{
- unsigned char* cp;
- uint16_t* glyphIDs;
- memoryword* p = pNode;
- void* glyph_info;
- FixedPoint* locations;
- int opcode;
- Fixed width;
- uint16_t glyphCount = native_glyph_count(p);
-
- int i = glyphCount * native_glyph_info_size + 8; /* to guarantee enough space in the buffer */
- if (i > xdvBufSize) {
- if (xdvbuffer != NULL)
- free(xdvbuffer);
- xdvBufSize = ((i / 1024) + 1) * 1024;
- xdvbuffer = (char*)xmalloc(xdvBufSize);
- }
-
- glyph_info = native_glyph_info_ptr(p);
- locations = (FixedPoint*)glyph_info;
- glyphIDs = (uint16_t*)(locations + glyphCount);
-
- opcode = XDV_GLYPH_STRING;
- for (i = 0; i < glyphCount; ++i)
- if (locations[i].y != 0) {
- opcode = XDV_GLYPH_ARRAY;
- break;
- }
-
- cp = (unsigned char*)xdvbuffer;
- *cp++ = opcode;
-
- width = node_width(p);
- *cp++ = (width >> 24) & 0xff;
- *cp++ = (width >> 16) & 0xff;
- *cp++ = (width >> 8) & 0xff;
- *cp++ = width & 0xff;
-
- *cp++ = (glyphCount >> 8) & 0xff;
- *cp++ = glyphCount & 0xff;
-
- for (i = 0; i < glyphCount; ++i) {
- Fixed x = locations[i].x;
- *cp++ = (x >> 24) & 0xff;
- *cp++ = (x >> 16) & 0xff;
- *cp++ = (x >> 8) & 0xff;
- *cp++ = x & 0xff;
- if (opcode == XDV_GLYPH_ARRAY) {
- Fixed y = locations[i].y;
- *cp++ = (y >> 24) & 0xff;
- *cp++ = (y >> 16) & 0xff;
- *cp++ = (y >> 8) & 0xff;
- *cp++ = y & 0xff;
- }
- }
-
- for (i = 0; i < glyphCount; ++i) {
- uint16_t g = glyphIDs[i];
- *cp++ = (g >> 8) & 0xff;
- *cp++ = g & 0xff;
- }
-
- return ((char*)cp - xdvbuffer);
+ unsigned char* cp;
+ uint16_t* glyphIDs;
+ memoryword* p = (memoryword*) pNode;
+ void* glyph_info;
+ FixedPoint* locations;
+ int opcode;
+ Fixed width;
+ uint16_t glyphCount = native_glyph_count(p);
+
+ int i = glyphCount * native_glyph_info_size + 8; /* to guarantee enough space in the buffer */
+ if (i > xdvBufSize) {
+ if (xdvbuffer != NULL)
+ free(xdvbuffer);
+ xdvBufSize = ((i / 1024) + 1) * 1024;
+ xdvbuffer = (char*) xmalloc(xdvBufSize);
+ }
+
+ glyph_info = native_glyph_info_ptr(p);
+ locations = (FixedPoint*)glyph_info;
+ glyphIDs = (uint16_t*)(locations + glyphCount);
+
+ opcode = XDV_GLYPH_STRING;
+ for (i = 0; i < glyphCount; ++i)
+ if (locations[i].y != 0) {
+ opcode = XDV_GLYPH_ARRAY;
+ break;
+ }
+
+ cp = (unsigned char*)xdvbuffer;
+ *cp++ = opcode;
+
+ width = node_width(p);
+ *cp++ = (width >> 24) & 0xff;
+ *cp++ = (width >> 16) & 0xff;
+ *cp++ = (width >> 8) & 0xff;
+ *cp++ = width & 0xff;
+
+ *cp++ = (glyphCount >> 8) & 0xff;
+ *cp++ = glyphCount & 0xff;
+
+ for (i = 0; i < glyphCount; ++i) {
+ Fixed x = locations[i].x;
+ *cp++ = (x >> 24) & 0xff;
+ *cp++ = (x >> 16) & 0xff;
+ *cp++ = (x >> 8) & 0xff;
+ *cp++ = x & 0xff;
+ if (opcode == XDV_GLYPH_ARRAY) {
+ Fixed y = locations[i].y;
+ *cp++ = (y >> 24) & 0xff;
+ *cp++ = (y >> 16) & 0xff;
+ *cp++ = (y >> 8) & 0xff;
+ *cp++ = y & 0xff;
+ }
+ }
+
+ for (i = 0; i < glyphCount; ++i) {
+ uint16_t g = glyphIDs[i];
+ *cp++ = (g >> 8) & 0xff;
+ *cp++ = g & 0xff;
+ }
+
+ return ((char*)cp - xdvbuffer);
}
int
makefontdef(integer f)
{
- uint16_t flags = 0;
- uint32_t variationCount = 0;
- uint32_t rgba;
- Fixed size;
- const char* psName;
- const char* famName;
- const char* styName;
- uint8_t psLen;
- uint8_t famLen;
- uint8_t styLen;
- int fontDefLength;
- char* cp;
- PlatformFontRef fontRef = 0;
- float extend = 1.0;
- float slant = 0.0;
- float embolden = 0.0;
+ uint16_t flags = 0;
+ uint32_t variationCount = 0;
+ uint32_t rgba;
+ Fixed size;
+ const char* psName;
+ const char* famName;
+ const char* styName;
+ uint8_t psLen;
+ uint8_t famLen;
+ uint8_t styLen;
+ int fontDefLength;
+ char* cp;
+ PlatformFontRef fontRef = 0;
+ float extend = 1.0;
+ float slant = 0.0;
+ float embolden = 0.0;
#ifdef XETEX_MAC
- CFDictionaryRef attributes = NULL;
- CFDictionaryRef variation = NULL;
-
- if (fontarea[f] == AAT_FONT_FLAG) {
- CTFontRef font;
- CGColorRef color;
- CGAffineTransform t;
- CFNumberRef emboldenNumber;
- CGFloat fSize;
- char *pathname;
- int index;
-
- flags = XDV_FLAG_FONTTYPE_AAT;
- attributes = (CFDictionaryRef) fontlayoutengine[f];
- font = CFDictionaryGetValue(attributes, kCTFontAttributeName);
- variation = CTFontCopyVariation(font);
- if (variation) {
- variationCount = CFDictionaryGetCount(variation);
- CFRelease(variation);
- }
-
- pathname = getFileNameFromCTFont(font, &index);
- if (pathname) {
- char buf[20];
-
- if (index > 0)
- sprintf(buf, ":%d", index);
- else
- buf[0] = '\0';
-
- psName = xmalloc(strlen((char*) pathname) + 2 + strlen(buf) + 1);
- sprintf((char*) psName, "[%s%s]", pathname, buf);
- famName = "";
- styName = "";
- } else {
- psName = getNameFromCTFont(font, kCTFontPostScriptNameKey);
- famName = getNameFromCTFont(font, kCTFontFamilyNameKey);
- styName = getNameFromCTFont(font, kCTFontStyleNameKey);
- }
-
- if (CFDictionaryGetValue(attributes, kCTVerticalFormsAttributeName))
- flags |= XDV_FLAG_VERTICAL;
-
- color = (CGColorRef) CFDictionaryGetValue(attributes, kCTForegroundColorAttributeName);
- if (color)
- rgba = cgColorToRGBA32(color);
-
- t = CTFontGetMatrix(font);
- extend = t.a;
- slant = t.b;
-
- emboldenNumber = CFDictionaryGetValue(attributes, kXeTeXEmboldenAttributeName);
- if (emboldenNumber)
- CFNumberGetValue(emboldenNumber, kCFNumberFloatType, &embolden);
-
- fSize = CTFontGetSize(font);
- size = D2Fix(fSize);
- } else
+ CFDictionaryRef attributes = NULL;
+ CFDictionaryRef variation = NULL;
+
+ if (fontarea[f] == AAT_FONT_FLAG) {
+ CTFontRef font;
+ CGColorRef color;
+ CGAffineTransform t;
+ CFNumberRef emboldenNumber;
+ CGFloat fSize;
+ char *pathname;
+ int index;
+
+ flags = XDV_FLAG_FONTTYPE_AAT;
+ attributes = (CFDictionaryRef) fontlayoutengine[f];
+ font = CFDictionaryGetValue(attributes, kCTFontAttributeName);
+ variation = CTFontCopyVariation(font);
+ if (variation) {
+ variationCount = CFDictionaryGetCount(variation);
+ CFRelease(variation);
+ }
+
+ pathname = getFileNameFromCTFont(font, &index);
+ if (pathname) {
+ char buf[20];
+
+ if (index > 0)
+ sprintf(buf, ":%d", index);
+ else
+ buf[0] = '\0';
+
+ psName = xmalloc(strlen((char*) pathname) + 2 + strlen(buf) + 1);
+ sprintf((char*) psName, "[%s%s]", pathname, buf);
+ famName = xstrdup("");
+ styName = xstrdup("");
+ } else {
+ psName = getNameFromCTFont(font, kCTFontPostScriptNameKey);
+ famName = getNameFromCTFont(font, kCTFontFamilyNameKey);
+ styName = getNameFromCTFont(font, kCTFontStyleNameKey);
+ }
+
+ if (CFDictionaryGetValue(attributes, kCTVerticalFormsAttributeName))
+ flags |= XDV_FLAG_VERTICAL;
+
+ color = (CGColorRef) CFDictionaryGetValue(attributes, kCTForegroundColorAttributeName);
+ if (color)
+ rgba = cgColorToRGBA32(color);
+
+ t = CTFontGetMatrix(font);
+ extend = t.a;
+ slant = t.b;
+
+ emboldenNumber = CFDictionaryGetValue(attributes, kXeTeXEmboldenAttributeName);
+ if (emboldenNumber)
+ CFNumberGetValue(emboldenNumber, kCFNumberFloatType, &embolden);
+
+ fSize = CTFontGetSize(font);
+ size = D2Fix(fSize);
+ } else
#endif
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXLayoutEngine engine;
- flags = XDV_FLAG_FONTTYPE_OT;
-
- engine = (XeTeXLayoutEngine)fontlayoutengine[f];
- fontRef = getFontRef(engine);
- psName = getFontFilename(engine);
- if (psName) {
- famName = "";
- styName = "";
- } else {
- getNames(getFontRef(engine), &psName, &famName, &styName);
- }
-
- rgba = getRgbValue(engine);
- if ((fontflags[f] & FONT_FLAGS_VERTICAL) != 0)
- flags |= XDV_FLAG_VERTICAL;
-
- extend = getExtendFactor(engine);
- slant = getSlantFactor(engine);
- embolden = getEmboldenFactor(engine);
-
- size = D2Fix(getPointSize(engine));
- } else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `make_font_def'\n");
- exit(3);
- }
-
- psLen = strlen(psName);
- famLen = strlen(famName);
- styLen = strlen(styName);
-
- /* parameters after internal font ID:
- // size[4]
- // flags[2]
- // lp[1] lf[1] ls[1] ps[lp] fam[lf] sty[ls]
- // if flags & COLORED:
- // c[4]
- // if flags & VARIATIONS:
- // nv[2]
- // a[4nv]
- // v[4nv]
- */
-
- fontDefLength
- = 4 /* size */
- + 2 /* flags */
- + 3 /* name length */
- + psLen + famLen + styLen;
-
- if ((fontflags[f] & FONT_FLAGS_COLORED) != 0) {
- fontDefLength += 4; /* 32-bit RGBA value */
- flags |= XDV_FLAG_COLORED;
- }
-
- if (extend != 1.0) {
- fontDefLength += 4;
- flags |= XDV_FLAG_EXTEND;
- }
- if (slant != 0.0) {
- fontDefLength += 4;
- flags |= XDV_FLAG_SLANT;
- }
- if (embolden != 0.0) {
- fontDefLength += 4;
- flags |= XDV_FLAG_EMBOLDEN;
- }
-
- if (fontDefLength > xdvBufSize) {
- if (xdvbuffer != NULL)
- free(xdvbuffer);
- xdvBufSize = ((fontDefLength / 1024) + 1) * 1024;
- xdvbuffer = (char*)xmalloc(xdvBufSize);
- }
- cp = xdvbuffer;
-
- *(Fixed*)cp = SWAP32(size);
- cp += 4;
-
- *(uint16_t*)cp = SWAP16(flags);
- cp += 2;
-
- *(uint8_t*)cp = psLen;
- cp += 1;
- *(uint8_t*)cp = famLen;
- cp += 1;
- *(uint8_t*)cp = styLen;
- cp += 1;
- memcpy(cp, psName, psLen);
- cp += psLen;
- memcpy(cp, famName, famLen);
- cp += famLen;
- memcpy(cp, styName, styLen);
- cp += styLen;
-
- if ((fontflags[f] & FONT_FLAGS_COLORED) != 0) {
- *(uint32_t*)cp = SWAP32(rgba);
- cp += 4;
- }
-
- if (flags & XDV_FLAG_EXTEND) {
- Fixed f = D2Fix(extend);
- *(uint32_t*)(cp) = SWAP32(f);
- cp += 4;
- }
- if (flags & XDV_FLAG_SLANT) {
- Fixed f = D2Fix(slant);
- *(uint32_t*)(cp) = SWAP32(f);
- cp += 4;
- }
- if (flags & XDV_FLAG_EMBOLDEN) {
- Fixed f = D2Fix(embolden);
- *(uint32_t*)(cp) = SWAP32(f);
- cp += 4;
- }
-
- return fontDefLength;
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine;
+ flags = XDV_FLAG_FONTTYPE_OT;
+
+ engine = (XeTeXLayoutEngine)fontlayoutengine[f];
+ fontRef = getFontRef(engine);
+ psName = xstrdup(getFontFilename(engine));
+ if (psName) {
+ famName = xstrdup("");
+ styName = xstrdup("");
+ } else {
+ getNames(getFontRef(engine), &psName, &famName, &styName);
+ }
+
+ rgba = getRgbValue(engine);
+ if ((fontflags[f] & FONT_FLAGS_VERTICAL) != 0)
+ flags |= XDV_FLAG_VERTICAL;
+
+ extend = getExtendFactor(engine);
+ slant = getSlantFactor(engine);
+ embolden = getEmboldenFactor(engine);
+
+ size = D2Fix(getPointSize(engine));
+ } else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `make_font_def'\n");
+ exit(3);
+ }
+
+ psLen = strlen(psName);
+ famLen = strlen(famName);
+ styLen = strlen(styName);
+
+ /* parameters after internal font ID:
+ // size[4]
+ // flags[2]
+ // lp[1] lf[1] ls[1] ps[lp] fam[lf] sty[ls]
+ // if flags & COLORED:
+ // c[4]
+ // if flags & VARIATIONS:
+ // nv[2]
+ // a[4nv]
+ // v[4nv]
+ */
+
+ fontDefLength
+ = 4 /* size */
+ + 2 /* flags */
+ + 3 /* name length */
+ + psLen + famLen + styLen;
+
+ if ((fontflags[f] & FONT_FLAGS_COLORED) != 0) {
+ fontDefLength += 4; /* 32-bit RGBA value */
+ flags |= XDV_FLAG_COLORED;
+ }
+
+ if (extend != 1.0) {
+ fontDefLength += 4;
+ flags |= XDV_FLAG_EXTEND;
+ }
+ if (slant != 0.0) {
+ fontDefLength += 4;
+ flags |= XDV_FLAG_SLANT;
+ }
+ if (embolden != 0.0) {
+ fontDefLength += 4;
+ flags |= XDV_FLAG_EMBOLDEN;
+ }
+
+ if (fontDefLength > xdvBufSize) {
+ if (xdvbuffer != NULL)
+ free(xdvbuffer);
+ xdvBufSize = ((fontDefLength / 1024) + 1) * 1024;
+ xdvbuffer = (char*) xmalloc(xdvBufSize);
+ }
+ cp = xdvbuffer;
+
+ *(Fixed*)cp = SWAP32(size);
+ cp += 4;
+
+ *(uint16_t*)cp = SWAP16(flags);
+ cp += 2;
+
+ *(uint8_t*)cp = psLen;
+ cp += 1;
+ *(uint8_t*)cp = famLen;
+ cp += 1;
+ *(uint8_t*)cp = styLen;
+ cp += 1;
+ memcpy(cp, psName, psLen);
+ cp += psLen;
+ memcpy(cp, famName, famLen);
+ cp += famLen;
+ memcpy(cp, styName, styLen);
+ cp += styLen;
+
+ if ((fontflags[f] & FONT_FLAGS_COLORED) != 0) {
+ *(uint32_t*)cp = SWAP32(rgba);
+ cp += 4;
+ }
+
+ if (flags & XDV_FLAG_EXTEND) {
+ Fixed f = D2Fix(extend);
+ *(uint32_t*)(cp) = SWAP32(f);
+ cp += 4;
+ }
+ if (flags & XDV_FLAG_SLANT) {
+ Fixed f = D2Fix(slant);
+ *(uint32_t*)(cp) = SWAP32(f);
+ cp += 4;
+ }
+ if (flags & XDV_FLAG_EMBOLDEN) {
+ Fixed f = D2Fix(embolden);
+ *(uint32_t*)(cp) = SWAP32(f);
+ cp += 4;
+ }
+
+ free((char*) psName);
+ free((char*) famName);
+ free((char*) styName);
+
+ return fontDefLength;
}
int
applymapping(void* pCnv, const uint16_t* txtPtr, int txtLen)
{
- TECkit_Converter cnv = (TECkit_Converter)pCnv;
- UInt32 inUsed, outUsed;
- TECkit_Status status;
- static UInt32 outLength = 0;
-
- /* allocate outBuffer if not big enough */
- if (outLength < txtLen * sizeof(UniChar) + 32) {
- if (mappedtext != 0)
- free(mappedtext);
- outLength = txtLen * sizeof(UniChar) + 32;
- mappedtext = xmalloc(outLength);
- }
-
- /* try the mapping */
+ TECkit_Converter cnv = (TECkit_Converter)pCnv;
+ UInt32 inUsed, outUsed;
+ TECkit_Status status;
+ static UInt32 outLength = 0;
+
+ /* allocate outBuffer if not big enough */
+ if (outLength < txtLen * sizeof(UniChar) + 32) {
+ if (mappedtext != 0)
+ free(mappedtext);
+ outLength = txtLen * sizeof(UniChar) + 32;
+ mappedtext = xmalloc(outLength);
+ }
+
+ /* try the mapping */
retry:
- status = TECkit_ConvertBuffer(cnv,
- (Byte*)txtPtr, txtLen * sizeof(UniChar), &inUsed,
- (Byte*)mappedtext, outLength, &outUsed, true);
-
- switch (status) {
- case kStatus_NoError:
- txtPtr = (const UniChar*)mappedtext;
- return outUsed / sizeof(UniChar);
-
- case kStatus_OutputBufferFull:
- outLength += (txtLen * sizeof(UniChar)) + 32;
- free(mappedtext);
- mappedtext = xmalloc(outLength);
- goto retry;
-
- default:
- return 0;
- }
+ status = TECkit_ConvertBuffer(cnv,
+ (Byte*)txtPtr, txtLen * sizeof(UniChar), &inUsed,
+ (Byte*)mappedtext, outLength, &outUsed, true);
+
+ switch (status) {
+ case kStatus_NoError:
+ txtPtr = (const UniChar*)mappedtext;
+ return outUsed / sizeof(UniChar);
+
+ case kStatus_OutputBufferFull:
+ outLength += (txtLen * sizeof(UniChar)) + 32;
+ free(mappedtext);
+ mappedtext = xmalloc(outLength);
+ goto retry;
+
+ default:
+ return 0;
+ }
}
static void
snap_zone(scaled* value, scaled snap_value, scaled fuzz)
{
- scaled difference = *value - snap_value;
- if (difference <= fuzz && difference >= -fuzz)
- *value = snap_value;
+ scaled difference = *value - snap_value;
+ if (difference <= fuzz && difference >= -fuzz)
+ *value = snap_value;
}
void
getnativecharheightdepth(integer font, integer ch, scaled* height, scaled* depth)
{
-#define QUAD(f) fontinfo[6+parambase[f]].cint
-#define X_HEIGHT(f) fontinfo[5+parambase[f]].cint
-#define CAP_HEIGHT(f) fontinfo[8+parambase[f]].cint
+#define QUAD(f) fontinfo[6+parambase[f]].cint
+#define X_HEIGHT(f) fontinfo[5+parambase[f]].cint
+#define CAP_HEIGHT(f) fontinfo[8+parambase[f]].cint
- float ht = 0.0;
- float dp = 0.0;
- Fixed fuzz;
+ float ht = 0.0;
+ float dp = 0.0;
+ Fixed fuzz;
#ifdef XETEX_MAC
- if (fontarea[font] == AAT_FONT_FLAG) {
- CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]);
- int gid = MapCharToGlyph_AAT(attributes, ch);
- GetGlyphHeightDepth_AAT(attributes, gid, &ht, &dp);
- } else
+ if (fontarea[font] == AAT_FONT_FLAG) {
+ CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]);
+ int gid = MapCharToGlyph_AAT(attributes, ch);
+ GetGlyphHeightDepth_AAT(attributes, gid, &ht, &dp);
+ } else
#endif
- if (fontarea[font] == OTGR_FONT_FLAG) {
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
- int gid = mapCharToGlyph(engine, ch);
- getGlyphHeightDepth(engine, gid, &ht, &dp);
- } else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `get_native_char_height_depth`\n");
- exit(3);
- }
-
- *height = D2Fix(ht);
- *depth = D2Fix(dp);
-
- /* snap to "known" zones for baseline, x-height, cap-height if within 4% of em-size */
- fuzz = QUAD(font) / 25;
- snap_zone(depth, 0, fuzz);
- snap_zone(height, 0, fuzz);
- snap_zone(height, X_HEIGHT(font), fuzz);
- snap_zone(height, CAP_HEIGHT(font), fuzz);
+ if (fontarea[font] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
+ int gid = mapCharToGlyph(engine, ch);
+ getGlyphHeightDepth(engine, gid, &ht, &dp);
+ } else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `get_native_char_height_depth`\n");
+ exit(3);
+ }
+
+ *height = D2Fix(ht);
+ *depth = D2Fix(dp);
+
+ /* snap to "known" zones for baseline, x-height, cap-height if within 4% of em-size */
+ fuzz = QUAD(font) / 25;
+ snap_zone(depth, 0, fuzz);
+ snap_zone(height, 0, fuzz);
+ snap_zone(height, X_HEIGHT(font), fuzz);
+ snap_zone(height, CAP_HEIGHT(font), fuzz);
}
scaled
getnativecharht(integer f, integer c)
{
- scaled h, d;
- getnativecharheightdepth(f, c, &h, &d);
- return h;
+ scaled h, d;
+ getnativecharheightdepth(f, c, &h, &d);
+ return h;
}
scaled
getnativechardp(integer f, integer c)
{
- scaled h, d;
- getnativecharheightdepth(f, c, &h, &d);
- return d;
+ scaled h, d;
+ getnativecharheightdepth(f, c, &h, &d);
+ return d;
}
void
getnativecharsidebearings(integer font, integer ch, scaled* lsb, scaled* rsb)
{
- float l, r;
+ float l, r;
#ifdef XETEX_MAC
- if (fontarea[font] == AAT_FONT_FLAG) {
- CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]);
- int gid = MapCharToGlyph_AAT(attributes, ch);
- GetGlyphSidebearings_AAT(attributes, gid, &l, &r);
- } else
+ if (fontarea[font] == AAT_FONT_FLAG) {
+ CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]);
+ int gid = MapCharToGlyph_AAT(attributes, ch);
+ GetGlyphSidebearings_AAT(attributes, gid, &l, &r);
+ } else
#endif
- if (fontarea[font] == OTGR_FONT_FLAG) {
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
- int gid = mapCharToGlyph(engine, ch);
- getGlyphSidebearings(engine, gid, &l, &r);
- } else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `get_native_char_side_bearings'\n");
- exit(3);
- }
+ if (fontarea[font] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
+ int gid = mapCharToGlyph(engine, ch);
+ getGlyphSidebearings(engine, gid, &l, &r);
+ } else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `get_native_char_side_bearings'\n");
+ exit(3);
+ }
- *lsb = D2Fix(l);
- *rsb = D2Fix(r);
+ *lsb = D2Fix(l);
+ *rsb = D2Fix(r);
}
scaled
getglyphbounds(integer font, integer edge, integer gid)
{
/* edge codes 1,2,3,4 => L T R B */
- float a, b;
-
+ float a, b;
+
#ifdef XETEX_MAC
- if (fontarea[font] == AAT_FONT_FLAG) {
- CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]);
- if (edge & 1)
- GetGlyphSidebearings_AAT(attributes, gid, &a, &b);
- else
- GetGlyphHeightDepth_AAT(attributes, gid, &a, &b);
- } else
+ if (fontarea[font] == AAT_FONT_FLAG) {
+ CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[font]);
+ if (edge & 1)
+ GetGlyphSidebearings_AAT(attributes, gid, &a, &b);
+ else
+ GetGlyphHeightDepth_AAT(attributes, gid, &a, &b);
+ } else
#endif
- if (fontarea[font] == OTGR_FONT_FLAG) {
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
- if (edge & 1)
- getGlyphSidebearings(engine, gid, &a, &b);
- else
- getGlyphHeightDepth(engine, gid, &a, &b);
- } else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `get_glyph_bounds'\n");
- exit(3);
- }
- return D2Fix((edge <= 2) ? a : b);
+ if (fontarea[font] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
+ if (edge & 1)
+ getGlyphSidebearings(engine, gid, &a, &b);
+ else
+ getGlyphHeightDepth(engine, gid, &a, &b);
+ } else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `get_glyph_bounds'\n");
+ exit(3);
+ }
+ return D2Fix((edge <= 2) ? a : b);
}
scaled
getnativecharic(integer f, integer c)
{
- scaled lsb, rsb;
- getnativecharsidebearings(f, c, &lsb, &rsb);
- if (rsb < 0)
- return fontletterspace[f] - rsb;
- else
- return fontletterspace[f];
+ scaled lsb, rsb;
+ getnativecharsidebearings(f, c, &lsb, &rsb);
+ if (rsb < 0)
+ return fontletterspace[f] - rsb;
+ else
+ return fontletterspace[f];
}
scaled
getnativecharwd(integer f, integer c)
{
- scaled wd = 0;
+ scaled wd = 0;
#ifdef XETEX_MAC
- if (fontarea[f] == AAT_FONT_FLAG) {
- CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[f]);
- int gid = MapCharToGlyph_AAT(attributes, c);
- wd = D2Fix(GetGlyphWidth_AAT(attributes, gid));
- } else
+ if (fontarea[f] == AAT_FONT_FLAG) {
+ CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[f]);
+ int gid = MapCharToGlyph_AAT(attributes, c);
+ wd = D2Fix(GetGlyphWidth_AAT(attributes, gid));
+ } else
#endif
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[f];
- int gid = mapCharToGlyph(engine, c);
- wd = D2Fix(getGlyphWidthFromEngine(engine, gid));
- } else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `get_native_char_wd'\n");
- exit(3);
- }
- return wd;
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[f];
+ int gid = mapCharToGlyph(engine, c);
+ wd = D2Fix(getGlyphWidthFromEngine(engine, gid));
+ } else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `get_native_char_wd'\n");
+ exit(3);
+ }
+ return wd;
}
uint16_t
get_native_glyph(void* pNode, unsigned index)
{
- memoryword* node = (memoryword*)pNode;
- FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
- uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node));
- if (index >= native_glyph_count(node))
- return 0;
- else
- return glyphIDs[index];
+ memoryword* node = (memoryword*)pNode;
+ FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
+ uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node));
+ if (index >= native_glyph_count(node))
+ return 0;
+ else
+ return glyphIDs[index];
}
void
store_justified_native_glyphs(void* node)
{
#ifdef XETEX_MAC /* this is only called for AAT fonts */
- (void)DoAATLayout(node, 1);
+ (void)DoAATLayout(node, 1);
#endif
}
void
measure_native_node(void* pNode, int use_glyph_metrics)
{
- memoryword* node = (memoryword*)pNode;
- int txtLen = native_length(node);
- uint16_t* txtPtr = (uint16_t*)(node + native_node_size);
+ memoryword* node = (memoryword*)pNode;
+ int txtLen = native_length(node);
+ uint16_t* txtPtr = (uint16_t*)(node + native_node_size);
- unsigned f = native_font(node);
+ unsigned f = native_font(node);
#ifdef XETEX_MAC
- if (fontarea[f] == AAT_FONT_FLAG) {
- /* we're using this font in AAT mode, so fontlayoutengine[f] is actually a CFDictionaryRef */
- DoAATLayout(node, 0);
- } else
+ if (fontarea[f] == AAT_FONT_FLAG) {
+ /* we're using this font in AAT mode, so fontlayoutengine[f] is actually a CFDictionaryRef */
+ DoAATLayout(node, 0);
+ } else
#endif
- if (fontarea[f] == OTGR_FONT_FLAG) {
- /* using this font in OT Layout mode, so fontlayoutengine[f] is actually a XeTeXLayoutEngine */
-
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)(fontlayoutengine[f]);
-
- FixedPoint* locations;
- uint16_t* glyphIDs;
- Fixed* glyphAdvances;
- int totalGlyphCount = 0;
-
- /* need to find direction runs within the text, and call layoutChars separately for each */
-
- UBiDiDirection dir;
- void* glyph_info = 0;
- static float* positions = 0;
- static float* advances = 0;
- static uint32_t* glyphs = 0;
-
- UBiDi* pBiDi = ubidi_open();
-
- UErrorCode errorCode = (UErrorCode)0;
- ubidi_setPara(pBiDi, txtPtr, txtLen, getDefaultDirection(engine), NULL, &errorCode);
-
- dir = ubidi_getDirection(pBiDi);
- if (dir == UBIDI_MIXED) {
- /* we actually do the layout twice here, once to count glyphs and then again to get them;
- which is inefficient, but i figure that MIXED is a relatively rare occurrence, so i can't be
- bothered to deal with the memory reallocation headache of doing it differently
- */
- int nRuns = ubidi_countRuns(pBiDi, &errorCode);
- double width = 0;
- int i, runIndex;
- int32_t logicalStart, length;
- for (runIndex = 0; runIndex < nRuns; ++runIndex) {
- dir = ubidi_getVisualRun(pBiDi, runIndex, &logicalStart, &length);
- totalGlyphCount += layoutChars(engine, txtPtr, logicalStart, length, txtLen, (dir == UBIDI_RTL));
- }
-
- if (totalGlyphCount > 0) {
- double x, y;
- glyph_info = xmalloc(totalGlyphCount * native_glyph_info_size);
- locations = (FixedPoint*)glyph_info;
- glyphIDs = (uint16_t*)(locations + totalGlyphCount);
- glyphAdvances = xmalloc(totalGlyphCount * sizeof(Fixed));
- totalGlyphCount = 0;
-
- x = y = 0.0;
- for (runIndex = 0; runIndex < nRuns; ++runIndex) {
- int nGlyphs;
- dir = ubidi_getVisualRun(pBiDi, runIndex, &logicalStart, &length);
- nGlyphs = layoutChars(engine, txtPtr, logicalStart, length, txtLen,
- (dir == UBIDI_RTL));
-
- glyphs = xmalloc(nGlyphs * sizeof(uint32_t));
- positions = xmalloc((nGlyphs * 2 + 2) * sizeof(float));
- advances = xmalloc(nGlyphs * sizeof(float));
-
- getGlyphs(engine, glyphs);
- getGlyphAdvances(engine, advances);
- getGlyphPositions(engine, positions);
-
- for (i = 0; i < nGlyphs; ++i) {
- glyphIDs[totalGlyphCount] = glyphs[i];
- locations[totalGlyphCount].x = D2Fix(positions[2*i] + x);
- locations[totalGlyphCount].y = D2Fix(positions[2*i+1] + y);
- glyphAdvances[totalGlyphCount] = D2Fix(advances[i]);
- ++totalGlyphCount;
- }
- x += positions[2*i];
- y += positions[2*i+1];
-
- free(glyphs);
- free(positions);
- }
- width = x;
- }
-
- node_width(node) = D2Fix(width);
- native_glyph_count(node) = totalGlyphCount;
- native_glyph_info_ptr(node) = glyph_info;
- } else {
- double width = 0;
- totalGlyphCount = layoutChars(engine, txtPtr, 0, txtLen, txtLen, (dir == UBIDI_RTL));
-
- glyphs = xmalloc(totalGlyphCount * sizeof(uint32_t));
- positions = xmalloc((totalGlyphCount * 2 + 2) * sizeof(float));
- advances = xmalloc(totalGlyphCount * sizeof(float));
-
- getGlyphs(engine, glyphs);
- getGlyphAdvances(engine, advances);
- getGlyphPositions(engine, positions);
-
- if (totalGlyphCount > 0) {
- int i;
- glyph_info = xmalloc(totalGlyphCount * native_glyph_info_size);
- locations = (FixedPoint*)glyph_info;
- glyphIDs = (uint16_t*)(locations + totalGlyphCount);
- glyphAdvances = xmalloc(totalGlyphCount * sizeof(Fixed));
- for (i = 0; i < totalGlyphCount; ++i) {
- glyphIDs[i] = glyphs[i];
- glyphAdvances[i] = D2Fix(advances[i]);
- locations[i].x = D2Fix(positions[2*i]);
- locations[i].y = D2Fix(positions[2*i+1]);
- }
- width = D2Fix(positions[2*i]);
- }
-
- node_width(node) = width;
- native_glyph_count(node) = totalGlyphCount;
- native_glyph_info_ptr(node) = glyph_info;
-
- free(glyphs);
- free(positions);
- }
-
- ubidi_close(pBiDi);
-
-
- if (fontletterspace[f] != 0) {
- Fixed lsDelta = 0;
- Fixed lsUnit = fontletterspace[f];
- int i;
- for (i = 0; i < totalGlyphCount; ++i) {
- if (glyphAdvances[i] == 0 && lsDelta != 0)
- lsDelta -= lsUnit;
- locations[i].x += lsDelta;
- lsDelta += lsUnit;
- }
- if (lsDelta != 0) {
- lsDelta -= lsUnit;
- node_width(node) += lsDelta;
- }
- }
- } else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `measure_native_node'\n");
- exit(3);
- }
-
- if (use_glyph_metrics == 0 || native_glyph_count(node) == 0) {
- /* for efficiency, height and depth are the font's ascent/descent,
- not true values based on the actual content of the word,
- unless use_glyph_metrics is non-zero */
- node_height(node) = heightbase[f];
- node_depth(node) = depthbase[f];
- } else {
- /* this iterates over the glyph data whether it comes from AAT or OT layout */
- FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
- uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node));
- float yMin = 65536.0;
- float yMax = -65536.0;
- int i;
- for (i = 0; i < native_glyph_count(node); ++i) {
- float ht, dp;
- float y = Fix2D(-locations[i].y); /* NB negative is upwards in locations[].y! */
-
- GlyphBBox bbox;
- if (getCachedGlyphBBox(f, glyphIDs[i], &bbox) == 0) {
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ /* using this font in OT Layout mode, so fontlayoutengine[f] is actually a XeTeXLayoutEngine */
+
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)(fontlayoutengine[f]);
+
+ FixedPoint* locations;
+ uint16_t* glyphIDs;
+ Fixed* glyphAdvances;
+ int totalGlyphCount = 0;
+
+ /* need to find direction runs within the text, and call layoutChars separately for each */
+
+ UBiDiDirection dir;
+ void* glyph_info = 0;
+ static float* positions = 0;
+ static float* advances = 0;
+ static uint32_t* glyphs = 0;
+
+ UBiDi* pBiDi = ubidi_open();
+
+ UErrorCode errorCode = U_ZERO_ERROR;
+ ubidi_setPara(pBiDi, (const UChar*) txtPtr, txtLen, getDefaultDirection(engine), NULL, &errorCode);
+
+ dir = ubidi_getDirection(pBiDi);
+ if (dir == UBIDI_MIXED) {
+ /* we actually do the layout twice here, once to count glyphs and then again to get them;
+ which is inefficient, but i figure that MIXED is a relatively rare occurrence, so i can't be
+ bothered to deal with the memory reallocation headache of doing it differently
+ */
+ int nRuns = ubidi_countRuns(pBiDi, &errorCode);
+ double width = 0;
+ int i, runIndex;
+ int32_t logicalStart, length;
+ for (runIndex = 0; runIndex < nRuns; ++runIndex) {
+ dir = ubidi_getVisualRun(pBiDi, runIndex, &logicalStart, &length);
+ totalGlyphCount += layoutChars(engine, txtPtr, logicalStart, length, txtLen, (dir == UBIDI_RTL));
+ }
+
+ if (totalGlyphCount > 0) {
+ double x, y;
+ glyph_info = xcalloc(totalGlyphCount, native_glyph_info_size);
+ locations = (FixedPoint*)glyph_info;
+ glyphIDs = (uint16_t*)(locations + totalGlyphCount);
+ glyphAdvances = (Fixed*) xcalloc(totalGlyphCount, sizeof(Fixed));
+ totalGlyphCount = 0;
+
+ x = y = 0.0;
+ for (runIndex = 0; runIndex < nRuns; ++runIndex) {
+ int nGlyphs;
+ dir = ubidi_getVisualRun(pBiDi, runIndex, &logicalStart, &length);
+ nGlyphs = layoutChars(engine, txtPtr, logicalStart, length, txtLen,
+ (dir == UBIDI_RTL));
+
+ glyphs = (uint32_t*) xcalloc(nGlyphs, sizeof(uint32_t));
+ positions = (float*) xcalloc(nGlyphs * 2 + 2, sizeof(float));
+ advances = (float*) xcalloc(nGlyphs, sizeof(float));
+
+ getGlyphs(engine, glyphs);
+ getGlyphAdvances(engine, advances);
+ getGlyphPositions(engine, positions);
+
+ for (i = 0; i < nGlyphs; ++i) {
+ glyphIDs[totalGlyphCount] = glyphs[i];
+ locations[totalGlyphCount].x = D2Fix(positions[2*i] + x);
+ locations[totalGlyphCount].y = D2Fix(positions[2*i+1] + y);
+ glyphAdvances[totalGlyphCount] = D2Fix(advances[i]);
+ ++totalGlyphCount;
+ }
+ x += positions[2*i];
+ y += positions[2*i+1];
+
+ free(glyphs);
+ free(positions);
+ free(advances);
+ }
+ width = x;
+ }
+
+ node_width(node) = D2Fix(width);
+ native_glyph_count(node) = totalGlyphCount;
+ native_glyph_info_ptr(node) = glyph_info;
+ } else {
+ double width = 0;
+ totalGlyphCount = layoutChars(engine, txtPtr, 0, txtLen, txtLen, (dir == UBIDI_RTL));
+
+ glyphs = (uint32_t*) xcalloc(totalGlyphCount, sizeof(uint32_t));
+ positions = (float*) xcalloc(totalGlyphCount * 2 + 2, sizeof(float));
+ advances = (float*) xcalloc(totalGlyphCount, sizeof(float));
+
+ getGlyphs(engine, glyphs);
+ getGlyphAdvances(engine, advances);
+ getGlyphPositions(engine, positions);
+
+ if (totalGlyphCount > 0) {
+ int i;
+ glyph_info = xcalloc(totalGlyphCount, native_glyph_info_size);
+ locations = (FixedPoint*)glyph_info;
+ glyphIDs = (uint16_t*)(locations + totalGlyphCount);
+ glyphAdvances = (Fixed*) xcalloc(totalGlyphCount, sizeof(Fixed));
+ for (i = 0; i < totalGlyphCount; ++i) {
+ glyphIDs[i] = glyphs[i];
+ glyphAdvances[i] = D2Fix(advances[i]);
+ locations[i].x = D2Fix(positions[2*i]);
+ locations[i].y = D2Fix(positions[2*i+1]);
+ }
+ width = D2Fix(positions[2*i]);
+ }
+
+ node_width(node) = width;
+ native_glyph_count(node) = totalGlyphCount;
+ native_glyph_info_ptr(node) = glyph_info;
+
+ free(glyphs);
+ free(positions);
+ free(advances);
+ }
+
+ ubidi_close(pBiDi);
+
+
+ if (fontletterspace[f] != 0) {
+ Fixed lsDelta = 0;
+ Fixed lsUnit = fontletterspace[f];
+ int i;
+ for (i = 0; i < totalGlyphCount; ++i) {
+ if (glyphAdvances[i] == 0 && lsDelta != 0)
+ lsDelta -= lsUnit;
+ locations[i].x += lsDelta;
+ lsDelta += lsUnit;
+ }
+ if (lsDelta != 0) {
+ lsDelta -= lsUnit;
+ node_width(node) += lsDelta;
+ }
+ }
+ free(glyphAdvances);
+ } else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `measure_native_node'\n");
+ exit(3);
+ }
+
+ if (use_glyph_metrics == 0 || native_glyph_count(node) == 0) {
+ /* for efficiency, height and depth are the font's ascent/descent,
+ not true values based on the actual content of the word,
+ unless use_glyph_metrics is non-zero */
+ node_height(node) = heightbase[f];
+ node_depth(node) = depthbase[f];
+ } else {
+ /* this iterates over the glyph data whether it comes from AAT or OT layout */
+ FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
+ uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node));
+ float yMin = 65536.0;
+ float yMax = -65536.0;
+ int i;
+ for (i = 0; i < native_glyph_count(node); ++i) {
+ float ht, dp;
+ float y = Fix2D(-locations[i].y); /* NB negative is upwards in locations[].y! */
+
+ GlyphBBox bbox;
+ if (getCachedGlyphBBox(f, glyphIDs[i], &bbox) == 0) {
#ifdef XETEX_MAC
- if (fontarea[f] == AAT_FONT_FLAG)
- GetGlyphBBox_AAT((CFDictionaryRef)(fontlayoutengine[f]), glyphIDs[i], &bbox);
- else
+ if (fontarea[f] == AAT_FONT_FLAG)
+ GetGlyphBBox_AAT((CFDictionaryRef)(fontlayoutengine[f]), glyphIDs[i], &bbox);
+ else
#endif
- if (fontarea[f] == OTGR_FONT_FLAG)
- getGlyphBounds((XeTeXLayoutEngine)(fontlayoutengine[f]), glyphIDs[i], &bbox);
-
- cacheGlyphBBox(f, glyphIDs[i], &bbox);
- }
-
- ht = bbox.yMax;
- dp = -bbox.yMin;
-
- if (y + ht > yMax)
- yMax = y + ht;
- if (y - dp < yMin)
- yMin = y - dp;
- }
- node_height(node) = D2Fix(yMax);
- node_depth(node) = -D2Fix(yMin);
- }
+ if (fontarea[f] == OTGR_FONT_FLAG)
+ getGlyphBounds((XeTeXLayoutEngine)(fontlayoutengine[f]), glyphIDs[i], &bbox);
+
+ cacheGlyphBBox(f, glyphIDs[i], &bbox);
+ }
+
+ ht = bbox.yMax;
+ dp = -bbox.yMin;
+
+ if (y + ht > yMax)
+ yMax = y + ht;
+ if (y - dp < yMin)
+ yMin = y - dp;
+ }
+ node_height(node) = D2Fix(yMax);
+ node_depth(node) = -D2Fix(yMin);
+ }
}
Fixed
get_native_italic_correction(void* pNode)
{
- memoryword* node = pNode;
- unsigned f = native_font(node);
- unsigned n = native_glyph_count(node);
- if (n > 0) {
- FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
- uint16_t* glyphIDs = (uint16_t*)(locations + n);
+ memoryword* node = (memoryword*) pNode;
+ unsigned f = native_font(node);
+ unsigned n = native_glyph_count(node);
+ if (n > 0) {
+ FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
+ uint16_t* glyphIDs = (uint16_t*)(locations + n);
#ifdef XETEX_MAC
- if (fontarea[f] == AAT_FONT_FLAG)
- return D2Fix(GetGlyphItalCorr_AAT((CFDictionaryRef)(fontlayoutengine[f]), glyphIDs[n-1]))
- + fontletterspace[f];
+ if (fontarea[f] == AAT_FONT_FLAG)
+ return D2Fix(GetGlyphItalCorr_AAT((CFDictionaryRef)(fontlayoutengine[f]), glyphIDs[n-1]))
+ + fontletterspace[f];
#endif
- if (fontarea[f] == OTGR_FONT_FLAG)
- return D2Fix(getGlyphItalCorr((XeTeXLayoutEngine)(fontlayoutengine[f]), glyphIDs[n-1]))
- + fontletterspace[f];
- }
+ if (fontarea[f] == OTGR_FONT_FLAG)
+ return D2Fix(getGlyphItalCorr((XeTeXLayoutEngine)(fontlayoutengine[f]), glyphIDs[n-1]))
+ + fontletterspace[f];
+ }
- return 0;
+ return 0;
}
Fixed
get_native_glyph_italic_correction(void* pNode)
{
- memoryword* node = pNode;
- uint16_t gid = native_glyph(node);
- unsigned f = native_font(node);
+ memoryword* node = (memoryword*) pNode;
+ uint16_t gid = native_glyph(node);
+ unsigned f = native_font(node);
#ifdef XETEX_MAC
- if (fontarea[f] == AAT_FONT_FLAG)
- return D2Fix(GetGlyphItalCorr_AAT((CFDictionaryRef)(fontlayoutengine[f]), gid));
+ if (fontarea[f] == AAT_FONT_FLAG)
+ return D2Fix(GetGlyphItalCorr_AAT((CFDictionaryRef)(fontlayoutengine[f]), gid));
#endif
- if (fontarea[f] == OTGR_FONT_FLAG)
- return D2Fix(getGlyphItalCorr((XeTeXLayoutEngine)(fontlayoutengine[f]), gid));
+ if (fontarea[f] == OTGR_FONT_FLAG)
+ return D2Fix(getGlyphItalCorr((XeTeXLayoutEngine)(fontlayoutengine[f]), gid));
- return 0; /* can't actually happen */
+ return 0; /* can't actually happen */
}
void
measure_native_glyph(void* pNode, int use_glyph_metrics)
{
- memoryword* node = pNode;
- uint16_t gid = native_glyph(node);
- unsigned f = native_font(node);
+ memoryword* node = (memoryword*) pNode;
+ uint16_t gid = native_glyph(node);
+ unsigned f = native_font(node);
- float ht = 0.0;
- float dp = 0.0;
+ float ht = 0.0;
+ float dp = 0.0;
#ifdef XETEX_MAC
- if (fontarea[f] == AAT_FONT_FLAG) {
- CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[f]);
- node_width(node) = D2Fix(GetGlyphWidth_AAT(attributes, gid));
- if (use_glyph_metrics)
- GetGlyphHeightDepth_AAT(attributes, gid, &ht, &dp);
- } else
+ if (fontarea[f] == AAT_FONT_FLAG) {
+ CFDictionaryRef attributes = (CFDictionaryRef)(fontlayoutengine[f]);
+ node_width(node) = D2Fix(GetGlyphWidth_AAT(attributes, gid));
+ if (use_glyph_metrics)
+ GetGlyphHeightDepth_AAT(attributes, gid, &ht, &dp);
+ } else
#endif
- if (fontarea[f] == OTGR_FONT_FLAG) {
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[f];
- XeTeXFont fontInst = getFont(engine);
- node_width(node) = D2Fix(getGlyphWidth(fontInst, gid));
- if (use_glyph_metrics)
- getGlyphHeightDepth(engine, gid, &ht, &dp);
- } else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `measure_native_glyph'\n");
- exit(3);
- }
-
- if (use_glyph_metrics) {
- node_height(node) = D2Fix(ht);
- node_depth(node) = D2Fix(dp);
- } else {
- node_height(node) = heightbase[f];
- node_depth(node) = depthbase[f];
- }
+ if (fontarea[f] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[f];
+ XeTeXFont fontInst = getFont(engine);
+ node_width(node) = D2Fix(getGlyphWidth(fontInst, gid));
+ if (use_glyph_metrics)
+ getGlyphHeightDepth(engine, gid, &ht, &dp);
+ } else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `measure_native_glyph'\n");
+ exit(3);
+ }
+
+ if (use_glyph_metrics) {
+ node_height(node) = D2Fix(ht);
+ node_depth(node) = D2Fix(dp);
+ } else {
+ node_height(node) = heightbase[f];
+ node_depth(node) = depthbase[f];
+ }
}
integer
mapchartoglyph(integer font, integer ch)
{
- if (ch > 0x10ffff || ((ch >= 0xd800) && (ch <= 0xdfff)))
- return 0;
+ if (ch > 0x10ffff || ((ch >= 0xd800) && (ch <= 0xdfff)))
+ return 0;
#ifdef XETEX_MAC
- if (fontarea[font] == AAT_FONT_FLAG)
- return MapCharToGlyph_AAT((CFDictionaryRef)(fontlayoutengine[font]), ch);
- else
+ if (fontarea[font] == AAT_FONT_FLAG)
+ return MapCharToGlyph_AAT((CFDictionaryRef)(fontlayoutengine[font]), ch);
+ else
#endif
- if (fontarea[font] == OTGR_FONT_FLAG)
- return mapCharToGlyph((XeTeXLayoutEngine)(fontlayoutengine[font]), ch);
- else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `map_char_to_glyph'\n");
- exit(3);
- }
+ if (fontarea[font] == OTGR_FONT_FLAG)
+ return mapCharToGlyph((XeTeXLayoutEngine)(fontlayoutengine[font]), ch);
+ else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `map_char_to_glyph'\n");
+ exit(3);
+ }
}
integer
mapglyphtoindex(integer font)
- /* glyph name is at nameoffile+1 */
+ /* glyph name is at nameoffile+1 */
{
#ifdef XETEX_MAC
- if (fontarea[font] == AAT_FONT_FLAG)
- return MapGlyphToIndex_AAT((CFDictionaryRef)(fontlayoutengine[font]), (const char*)nameoffile + 1);
- else
+ if (fontarea[font] == AAT_FONT_FLAG)
+ return MapGlyphToIndex_AAT((CFDictionaryRef)(fontlayoutengine[font]), (const char*)nameoffile + 1);
+ else
#endif
- if (fontarea[font] == OTGR_FONT_FLAG)
- return mapGlyphToIndex((XeTeXLayoutEngine)(fontlayoutengine[font]), (const char*)nameoffile + 1);
- else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `map_glyph_to_index'\n");
- exit(3);
- }
+ if (fontarea[font] == OTGR_FONT_FLAG)
+ return mapGlyphToIndex((XeTeXLayoutEngine)(fontlayoutengine[font]), (const char*)nameoffile + 1);
+ else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `map_glyph_to_index'\n");
+ exit(3);
+ }
}
integer
getfontcharrange(integer font, int first)
{
#ifdef XETEX_MAC
- if (fontarea[font] == AAT_FONT_FLAG)
- return GetFontCharRange_AAT((CFDictionaryRef)(fontlayoutengine[font]), first);
- else
+ if (fontarea[font] == AAT_FONT_FLAG)
+ return GetFontCharRange_AAT((CFDictionaryRef)(fontlayoutengine[font]), first);
+ else
#endif
- if (fontarea[font] == OTGR_FONT_FLAG)
- return getFontCharRange((XeTeXLayoutEngine)(fontlayoutengine[font]), first);
- else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `get_font_char_range'\n");
- exit(3);
- }
+ if (fontarea[font] == OTGR_FONT_FLAG)
+ return getFontCharRange((XeTeXLayoutEngine)(fontlayoutengine[font]), first);
+ else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `get_font_char_range'\n");
+ exit(3);
+ }
}
Fixed D2Fix(double d)
{
- Fixed rval = (int)(d * 65536.0 + 0.5);
- return rval;
+ Fixed rval = (int)(d * 65536.0 + 0.5);
+ return rval;
}
double Fix2D(Fixed f)
{
- double rval = f / 65536.0;
- return rval;
+ double rval = f / 65536.0;
+ return rval;
}
/* these are here, not XeTeX_mac.c, because we need stubs on other platforms */
@@ -2324,633 +2329,633 @@ void
aatgetfontmetrics(CFDictionaryRef attributes, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant)
{
#ifdef XETEX_MAC
- CTFontRef font = fontFromAttributes(attributes);
+ CTFontRef font = fontFromAttributes(attributes);
- *ascent = D2Fix(CTFontGetAscent(font));
- *descent = D2Fix(CTFontGetDescent(font));
- *xheight = D2Fix(CTFontGetXHeight(font));
- *capheight = D2Fix(CTFontGetCapHeight(font));
- *slant = D2Fix(tan(-CTFontGetSlantAngle(font) * M_PI / 180.0));
+ *ascent = D2Fix(CTFontGetAscent(font));
+ *descent = D2Fix(CTFontGetDescent(font));
+ *xheight = D2Fix(CTFontGetXHeight(font));
+ *capheight = D2Fix(CTFontGetCapHeight(font));
+ *slant = D2Fix(tan(-CTFontGetSlantAngle(font) * M_PI / 180.0));
#endif
}
int
aatfontget(int what, CFDictionaryRef attributes)
{
- int rval = -1;
+ int rval = -1;
#ifdef XETEX_MAC
- CTFontRef font = fontFromAttributes(attributes);
- CFArrayRef list;
-
- switch (what) {
- case XeTeX_count_glyphs:
- rval = CTFontGetGlyphCount(font);
- break;
-
- case XeTeX_count_variations:
- case XeTeX_count_features:
- list = (what == XeTeX_count_variations ? CTFontCopyVariationAxes(font)
- : CTFontCopyFeatures(font));
- if (list) {
- rval = CFArrayGetCount(list);
- CFRelease(list);
- }
- break;
- }
+ CTFontRef font = fontFromAttributes(attributes);
+ CFArrayRef list;
+
+ switch (what) {
+ case XeTeX_count_glyphs:
+ rval = CTFontGetGlyphCount(font);
+ break;
+
+ case XeTeX_count_variations:
+ case XeTeX_count_features:
+ list = (what == XeTeX_count_variations ? CTFontCopyVariationAxes(font)
+ : CTFontCopyFeatures(font));
+ if (list) {
+ rval = CFArrayGetCount(list);
+ CFRelease(list);
+ }
+ break;
+ }
#endif
- return rval;
+ return rval;
}
int
aatfontget1(int what, CFDictionaryRef attributes, int param)
{
- int rval = -1;
+ int rval = -1;
#ifdef XETEX_MAC
- CTFontRef font = fontFromAttributes(attributes);
-
- switch (what) {
- case XeTeX_variation:
- {
- CFArrayRef axes = CTFontCopyVariationAxes(font);
- if (axes) {
- if (CFArrayGetCount(axes) > param) {
- CFDictionaryRef variation = CFArrayGetValueAtIndex(axes, param);
- CFNumberRef identifier = CFDictionaryGetValue(variation, kCTFontVariationAxisIdentifierKey);
- if (identifier)
- CFNumberGetValue(identifier, kCFNumberIntType, &rval);
- }
- CFRelease(axes);
- }
- break;
- }
-
- case XeTeX_variation_min:
- case XeTeX_variation_max:
- case XeTeX_variation_default:
- {
- CFArrayRef axes = CTFontCopyVariationAxes(font);
- if (axes) {
- CFDictionaryRef variation = findDictionaryInArrayWithIdentifier(axes, kCTFontVariationAxisIdentifierKey, param);
- CFStringRef key = (what == XeTeX_variation_min ? kCTFontVariationAxisMinimumValueKey :
- (what == XeTeX_variation_max ? kCTFontVariationAxisMaximumValueKey :
- kCTFontVariationAxisDefaultValueKey));
- CFNumberRef value = CFDictionaryGetValue(variation, key);
- if (value)
- CFNumberGetValue(value, kCFNumberIntType, &rval);
- CFRelease(axes);
- }
- break;
- }
-
- case XeTeX_feature_code:
- {
- CFArrayRef features = CTFontCopyFeatures(font);
- if (features) {
- if (CFArrayGetCount(features) > param) {
- CFDictionaryRef feature = CFArrayGetValueAtIndex(features, param);
- CFNumberRef identifier = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey);
- if (identifier)
- CFNumberGetValue(identifier, kCFNumberIntType, &rval);
- }
- CFRelease(features);
- }
- break;
- }
-
- case XeTeX_is_exclusive_feature:
- {
- CFArrayRef features = CTFontCopyFeatures(font);
- if (features) {
- CFBooleanRef value;
- CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param);
- Boolean found = CFDictionaryGetValueIfPresent(feature, kCTFontFeatureTypeExclusiveKey, (const void **)&value);
- if (found)
- rval = CFBooleanGetValue(value);
- CFRelease(features);
- }
- break;
- }
-
- case XeTeX_count_selectors:
- {
- CFArrayRef features = CTFontCopyFeatures(font);
- if (features) {
- CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param);
- if (feature) {
- CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
- if (selectors)
- rval = CFArrayGetCount(selectors);
- }
- CFRelease(features);
- }
- break;
- }
- }
+ CTFontRef font = fontFromAttributes(attributes);
+
+ switch (what) {
+ case XeTeX_variation:
+ {
+ CFArrayRef axes = CTFontCopyVariationAxes(font);
+ if (axes) {
+ if (CFArrayGetCount(axes) > param) {
+ CFDictionaryRef variation = CFArrayGetValueAtIndex(axes, param);
+ CFNumberRef identifier = CFDictionaryGetValue(variation, kCTFontVariationAxisIdentifierKey);
+ if (identifier)
+ CFNumberGetValue(identifier, kCFNumberIntType, &rval);
+ }
+ CFRelease(axes);
+ }
+ break;
+ }
+
+ case XeTeX_variation_min:
+ case XeTeX_variation_max:
+ case XeTeX_variation_default:
+ {
+ CFArrayRef axes = CTFontCopyVariationAxes(font);
+ if (axes) {
+ CFDictionaryRef variation = findDictionaryInArrayWithIdentifier(axes, kCTFontVariationAxisIdentifierKey, param);
+ CFStringRef key = (what == XeTeX_variation_min ? kCTFontVariationAxisMinimumValueKey :
+ (what == XeTeX_variation_max ? kCTFontVariationAxisMaximumValueKey :
+ kCTFontVariationAxisDefaultValueKey));
+ CFNumberRef value = CFDictionaryGetValue(variation, key);
+ if (value)
+ CFNumberGetValue(value, kCFNumberIntType, &rval);
+ CFRelease(axes);
+ }
+ break;
+ }
+
+ case XeTeX_feature_code:
+ {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (features) {
+ if (CFArrayGetCount(features) > param) {
+ CFDictionaryRef feature = CFArrayGetValueAtIndex(features, param);
+ CFNumberRef identifier = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey);
+ if (identifier)
+ CFNumberGetValue(identifier, kCFNumberIntType, &rval);
+ }
+ CFRelease(features);
+ }
+ break;
+ }
+
+ case XeTeX_is_exclusive_feature:
+ {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (features) {
+ CFBooleanRef value;
+ CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param);
+ Boolean found = CFDictionaryGetValueIfPresent(feature, kCTFontFeatureTypeExclusiveKey, (const void **)&value);
+ if (found)
+ rval = CFBooleanGetValue(value);
+ CFRelease(features);
+ }
+ break;
+ }
+
+ case XeTeX_count_selectors:
+ {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (features) {
+ CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param);
+ if (feature) {
+ CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
+ if (selectors)
+ rval = CFArrayGetCount(selectors);
+ }
+ CFRelease(features);
+ }
+ break;
+ }
+ }
#endif
-
- return rval;
+
+ return rval;
}
int
aatfontget2(int what, CFDictionaryRef attributes, int param1, int param2)
{
- int rval = -1;
+ int rval = -1;
#ifdef XETEX_MAC
- CTFontRef font = fontFromAttributes(attributes);
- CFArrayRef features = CTFontCopyFeatures(font);
- if (features) {
- CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param1);
- if (feature) {
- CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
- if (selectors) {
- CFDictionaryRef selector;
- switch (what) {
- case XeTeX_selector_code:
- if (CFArrayGetCount(selectors) > param2) {
- CFNumberRef identifier;
- selector = CFArrayGetValueAtIndex(selectors, param2);
- identifier = CFDictionaryGetValue(selector, kCTFontFeatureSelectorIdentifierKey);
- if (identifier)
- CFNumberGetValue(identifier, kCFNumberIntType, &rval);
- }
- break;
- case XeTeX_is_default_selector:
- selector = findDictionaryInArrayWithIdentifier(selectors, kCTFontFeatureSelectorIdentifierKey, param2);
- if (selector) {
- CFBooleanRef isDefault;
- Boolean found = CFDictionaryGetValueIfPresent(selector, kCTFontFeatureSelectorDefaultKey, (const void **)&isDefault);
- if (found)
- rval = CFBooleanGetValue(isDefault);
- }
- break;
- }
- }
- }
- CFRelease(features);
- }
+ CTFontRef font = fontFromAttributes(attributes);
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (features) {
+ CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param1);
+ if (feature) {
+ CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
+ if (selectors) {
+ CFDictionaryRef selector;
+ switch (what) {
+ case XeTeX_selector_code:
+ if (CFArrayGetCount(selectors) > param2) {
+ CFNumberRef identifier;
+ selector = CFArrayGetValueAtIndex(selectors, param2);
+ identifier = CFDictionaryGetValue(selector, kCTFontFeatureSelectorIdentifierKey);
+ if (identifier)
+ CFNumberGetValue(identifier, kCFNumberIntType, &rval);
+ }
+ break;
+ case XeTeX_is_default_selector:
+ selector = findDictionaryInArrayWithIdentifier(selectors, kCTFontFeatureSelectorIdentifierKey, param2);
+ if (selector) {
+ CFBooleanRef isDefault;
+ Boolean found = CFDictionaryGetValueIfPresent(selector, kCTFontFeatureSelectorDefaultKey, (const void **)&isDefault);
+ if (found)
+ rval = CFBooleanGetValue(isDefault);
+ }
+ break;
+ }
+ }
+ }
+ CFRelease(features);
+ }
#endif
-
- return rval;
+
+ return rval;
}
int
aatfontgetnamed(int what, CFDictionaryRef attributes)
{
- int rval = -1;
+ int rval = -1;
#ifdef XETEX_MAC
- CTFontRef font = fontFromAttributes(attributes);
-
- switch (what) {
- case XeTeX_find_variation_by_name:
- {
- CFArrayRef axes = CTFontCopyVariationAxes(font);
- if (axes) {
- CFDictionaryRef variation = findDictionaryInArray(axes, kCTFontVariationAxisNameKey,
- (const char*)nameoffile + 1, namelength);
- if (variation) {
- CFNumberRef identifier = CFDictionaryGetValue(variation, kCTFontVariationAxisIdentifierKey);
- if (identifier)
- CFNumberGetValue(identifier, kCFNumberIntType, &rval);
- }
- CFRelease(axes);
- }
- break;
- }
-
- case XeTeX_find_feature_by_name:
- {
- CFArrayRef features = CTFontCopyFeatures(font);
- if (features) {
- CFDictionaryRef feature = findDictionaryInArray(features, kCTFontFeatureTypeNameKey,
- (const char*)nameoffile + 1, namelength);
- if (feature) {
- CFNumberRef identifier = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey);
- CFNumberGetValue(identifier, kCFNumberIntType, &rval);
- }
- CFRelease(features);
- }
- break;
- }
- }
+ CTFontRef font = fontFromAttributes(attributes);
+
+ switch (what) {
+ case XeTeX_find_variation_by_name:
+ {
+ CFArrayRef axes = CTFontCopyVariationAxes(font);
+ if (axes) {
+ CFDictionaryRef variation = findDictionaryInArray(axes, kCTFontVariationAxisNameKey,
+ (const char*)nameoffile + 1, namelength);
+ if (variation) {
+ CFNumberRef identifier = CFDictionaryGetValue(variation, kCTFontVariationAxisIdentifierKey);
+ if (identifier)
+ CFNumberGetValue(identifier, kCFNumberIntType, &rval);
+ }
+ CFRelease(axes);
+ }
+ break;
+ }
+
+ case XeTeX_find_feature_by_name:
+ {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (features) {
+ CFDictionaryRef feature = findDictionaryInArray(features, kCTFontFeatureTypeNameKey,
+ (const char*)nameoffile + 1, namelength);
+ if (feature) {
+ CFNumberRef identifier = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey);
+ CFNumberGetValue(identifier, kCFNumberIntType, &rval);
+ }
+ CFRelease(features);
+ }
+ break;
+ }
+ }
#endif
-
- return rval;
+
+ return rval;
}
int
aatfontgetnamed1(int what, CFDictionaryRef attributes, int param)
{
- int rval = -1;
+ int rval = -1;
#ifdef XETEX_MAC
- CTFontRef font = fontFromAttributes(attributes);
-
- if (what == XeTeX_find_selector_by_name) {
- CFArrayRef features = CTFontCopyFeatures(font);
- if (features) {
- CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param);
- if (feature) {
- CFNumberRef selector = findSelectorByName(feature, (const char*)nameoffile + 1, namelength);
- if (selector)
- CFNumberGetValue(selector, kCFNumberIntType, &rval);
- }
- CFRelease(features);
- }
- }
+ CTFontRef font = fontFromAttributes(attributes);
+
+ if (what == XeTeX_find_selector_by_name) {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (features) {
+ CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features, kCTFontFeatureTypeIdentifierKey, param);
+ if (feature) {
+ CFNumberRef selector = findSelectorByName(feature, (const char*)nameoffile + 1, namelength);
+ if (selector)
+ CFNumberGetValue(selector, kCFNumberIntType, &rval);
+ }
+ CFRelease(features);
+ }
+ }
#endif
-
- return rval;
+
+ return rval;
}
void
aatprintfontname(int what, CFDictionaryRef attributes, int param1, int param2)
{
#ifdef XETEX_MAC
- CTFontRef font = fontFromAttributes(attributes);
- CFStringRef name = NULL;
- if (what == XeTeX_variation_name) {
- CFArrayRef axes = CTFontCopyVariationAxes(font);
- if (axes) {
- CFDictionaryRef variation = findDictionaryInArrayWithIdentifier(axes,
- kCTFontVariationAxisIdentifierKey,
- param1);
- if (variation)
- name = CFDictionaryGetValue(variation, kCTFontVariationAxisNameKey);
- CFRelease(axes);
- }
- } else if (what == XeTeX_feature_name || what == XeTeX_selector_name) {
- CFArrayRef features = CTFontCopyFeatures(font);
- if (features) {
- CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features,
- kCTFontFeatureTypeIdentifierKey,
- param1);
- if (feature) {
- if (what == XeTeX_feature_name)
- name = CFDictionaryGetValue(feature, kCTFontFeatureTypeNameKey);
- else {
- CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
- CFDictionaryRef selector = findDictionaryInArrayWithIdentifier(selectors,
- kCTFontFeatureSelectorIdentifierKey,
- param2);
- if (selector)
- name = CFDictionaryGetValue(selector, kCTFontFeatureSelectorNameKey);
- }
- }
- CFRelease(features);
- }
- }
-
- if (name) {
- CFIndex len = CFStringGetLength(name);
- UniChar* buf = xmalloc(len * sizeof(UniChar));
- CFStringGetCharacters(name, CFRangeMake(0, len), buf);
- printchars(buf, len);
- free(buf);
- }
+ CTFontRef font = fontFromAttributes(attributes);
+ CFStringRef name = NULL;
+ if (what == XeTeX_variation_name) {
+ CFArrayRef axes = CTFontCopyVariationAxes(font);
+ if (axes) {
+ CFDictionaryRef variation = findDictionaryInArrayWithIdentifier(axes,
+ kCTFontVariationAxisIdentifierKey,
+ param1);
+ if (variation)
+ name = CFDictionaryGetValue(variation, kCTFontVariationAxisNameKey);
+ CFRelease(axes);
+ }
+ } else if (what == XeTeX_feature_name || what == XeTeX_selector_name) {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ if (features) {
+ CFDictionaryRef feature = findDictionaryInArrayWithIdentifier(features,
+ kCTFontFeatureTypeIdentifierKey,
+ param1);
+ if (feature) {
+ if (what == XeTeX_feature_name)
+ name = CFDictionaryGetValue(feature, kCTFontFeatureTypeNameKey);
+ else {
+ CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
+ CFDictionaryRef selector = findDictionaryInArrayWithIdentifier(selectors,
+ kCTFontFeatureSelectorIdentifierKey,
+ param2);
+ if (selector)
+ name = CFDictionaryGetValue(selector, kCTFontFeatureSelectorNameKey);
+ }
+ }
+ CFRelease(features);
+ }
+ }
+
+ if (name) {
+ CFIndex len = CFStringGetLength(name);
+ UniChar* buf = xcalloc(len, sizeof(UniChar));
+ CFStringGetCharacters(name, CFRangeMake(0, len), buf);
+ printchars(buf, len);
+ free(buf);
+ }
#endif
}
void
printglyphname(integer font, integer gid)
{
- char* s;
- int len = 0;
+ char* s;
+ int len = 0;
#ifdef XETEX_MAC
- if (fontarea[font] == AAT_FONT_FLAG) {
- s = GetGlyphNameFromCTFont(fontFromInteger(font), gid, &len);
- } else
+ if (fontarea[font] == AAT_FONT_FLAG) {
+ s = GetGlyphNameFromCTFont(fontFromInteger(font), gid, &len);
+ } else
#endif
- if (fontarea[font] == OTGR_FONT_FLAG) {
- XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
- s = (char*)getGlyphName(getFont(engine), gid, &len);
- } else {
- fprintf(stderr, "\n! Internal error: bad native font flag in `print_glyph_name'\n");
- exit(3);
- }
- while (len-- > 0)
- printchar(*s++);
+ if (fontarea[font] == OTGR_FONT_FLAG) {
+ XeTeXLayoutEngine engine = (XeTeXLayoutEngine)fontlayoutengine[font];
+ s = (char*)getGlyphName(getFont(engine), gid, &len);
+ } else {
+ fprintf(stderr, "\n! Internal error: bad native font flag in `print_glyph_name'\n");
+ exit(3);
+ }
+ while (len-- > 0)
+ printchar(*s++);
}
int
u_open_in(unicodefile* f, integer filefmt, const_string fopen_mode, integer mode, integer encodingData)
{
- boolean rval;
- *f = xmalloc(sizeof(UFILE));
- (*f)->encodingMode = 0;
- (*f)->conversionData = 0;
- (*f)->savedChar = -1;
- (*f)->skipNextLF = 0;
- rval = open_input (&((*f)->f), filefmt, fopen_mode);
- if (rval) {
- int B1, B2;
- if (mode == AUTO) {
- /* sniff encoding form */
- B1 = getc((*f)->f);
- B2 = getc((*f)->f);
- if (B1 == 0xfe && B2 == 0xff)
- mode = UTF16BE;
- else if (B2 == 0xfe && B1 == 0xff)
- mode = UTF16LE;
- else if (B1 == 0 && B2 != 0) {
- mode = UTF16BE;
- rewind((*f)->f);
- } else if (B2 == 0 && B1 != 0) {
- mode = UTF16LE;
- rewind((*f)->f);
- } else if (B1 == 0xef && B2 == 0xbb) {
- int B3 = getc((*f)->f);
- if (B3 == 0xbf)
- mode = UTF8;
- }
- if (mode == AUTO) {
- rewind((*f)->f);
- mode = UTF8;
- }
- }
-
- setinputfileencoding(*f, mode, encodingData);
- }
- return rval;
+ boolean rval;
+ *f = (unicodefile) xmalloc(sizeof(UFILE));
+ (*f)->encodingMode = 0;
+ (*f)->conversionData = 0;
+ (*f)->savedChar = -1;
+ (*f)->skipNextLF = 0;
+ rval = open_input (&((*f)->f), filefmt, fopen_mode);
+ if (rval) {
+ int B1, B2;
+ if (mode == AUTO) {
+ /* sniff encoding form */
+ B1 = getc((*f)->f);
+ B2 = getc((*f)->f);
+ if (B1 == 0xfe && B2 == 0xff)
+ mode = UTF16BE;
+ else if (B2 == 0xfe && B1 == 0xff)
+ mode = UTF16LE;
+ else if (B1 == 0 && B2 != 0) {
+ mode = UTF16BE;
+ rewind((*f)->f);
+ } else if (B2 == 0 && B1 != 0) {
+ mode = UTF16LE;
+ rewind((*f)->f);
+ } else if (B1 == 0xef && B2 == 0xbb) {
+ int B3 = getc((*f)->f);
+ if (B3 == 0xbf)
+ mode = UTF8;
+ }
+ if (mode == AUTO) {
+ rewind((*f)->f);
+ mode = UTF8;
+ }
+ }
+
+ setinputfileencoding(*f, mode, encodingData);
+ }
+ return rval;
}
#if defined(WIN32)
static int
Isspace(char c)
{
- return (c == ' ' || c == '\t');
+ return (c == ' ' || c == '\t');
}
#endif
int
open_dvi_output(FILE** fptr)
{
- if (nopdfoutput) {
- return open_output(fptr, FOPEN_WBIN_MODE);
- } else {
- const char *p = (const char*)nameoffile+1;
- char *cmd, *q;
- int len = strlen(p);
- while (*p)
- if (*p++ == '\"')
- ++len;
- len += strlen(outputdriver);
- if (output_directory)
- len += strlen(output_directory);
- len += 10; /* space for -o flag, quotes, NUL */
- for (p = (const char*)nameoffile+1; *p; p++)
- if (*p == '\"')
- ++len; /* allow extra space to escape quotes in filename */
- cmd = xmalloc(len);
- strcpy(cmd, outputdriver);
- strcat(cmd, " -o \"");
- if (output_directory) {
- len = strlen(output_directory);
- if (IS_DIR_SEP(output_directory[len-1]))
- output_directory[len-1] = '\0';
- strcat(cmd, output_directory);
- strcat(cmd, "/");
- }
- q = cmd + strlen(cmd);
- for (p = (const char*)nameoffile+1; *p; p++) {
- if (*p == '\"')
- *q++ = '\\';
- *q++ = *p;
- }
- *q++ = '\"';
- *q = '\0';
- if (papersize != 0) {
- char* cmd2 = concat3(cmd, " -p ", papersize);
- free(cmd);
- cmd = cmd2;
- }
- if (output_directory) {
- char *fullname = concat3(output_directory, "/", (const char*)nameoffile+1);
- free(nameoffile);
- namelength = strlen(fullname);
- nameoffile = (unsigned char*)xmalloc(namelength+2);
- strcpy((char*)nameoffile+1, fullname);
- free(fullname);
- }
+ if (nopdfoutput) {
+ return open_output(fptr, FOPEN_WBIN_MODE);
+ } else {
+ const char *p = (const char*)nameoffile+1;
+ char *cmd, *q;
+ int len = strlen(p);
+ while (*p)
+ if (*p++ == '\"')
+ ++len;
+ len += strlen(outputdriver);
+ if (output_directory)
+ len += strlen(output_directory);
+ len += 10; /* space for -o flag, quotes, NUL */
+ for (p = (const char*)nameoffile+1; *p; p++)
+ if (*p == '\"')
+ ++len; /* allow extra space to escape quotes in filename */
+ cmd = xmalloc(len);
+ strcpy(cmd, outputdriver);
+ strcat(cmd, " -o \"");
+ if (output_directory) {
+ len = strlen(output_directory);
+ if (IS_DIR_SEP(output_directory[len-1]))
+ output_directory[len-1] = '\0';
+ strcat(cmd, output_directory);
+ strcat(cmd, "/");
+ }
+ q = cmd + strlen(cmd);
+ for (p = (const char*)nameoffile+1; *p; p++) {
+ if (*p == '\"')
+ *q++ = '\\';
+ *q++ = *p;
+ }
+ *q++ = '\"';
+ *q = '\0';
+ if (papersize != 0) {
+ char* cmd2 = concat3(cmd, " -p ", papersize);
+ free(cmd);
+ cmd = cmd2;
+ }
+ if (output_directory) {
+ char *fullname = concat3(output_directory, "/", (const char*)nameoffile+1);
+ free(nameoffile);
+ namelength = strlen(fullname);
+ nameoffile = (unsigned char*) xmalloc(namelength + 2);
+ strcpy((char*)nameoffile+1, fullname);
+ free(fullname);
+ }
#if defined(WIN32)
- {
- wchar_t *tmp1w;
- char *p, *pp, *bindir, *fullcmd, *prgnam;
- bindir = kpse_var_value("SELFAUTOLOC");
- for(pp = bindir; *pp; pp++) {
- if(*pp == '/') *pp = '\\';
- }
- pp = cmd;
- while(Isspace(*pp))
- pp++;
- prgnam = xmalloc(strlen(cmd));
- p = prgnam;
- while(!Isspace(*pp)) {
- *p++ = *pp++;
- }
- *p = '\0';
- fullcmd = concatn("\"\"", bindir, "\\", prgnam, "\"", pp, "\"", NULL);
- tmp1w = get_wstring_from_mbstring(CP_UTF8, (const char *)fullcmd, tmp1w=NULL);
- *fptr = _wpopen(tmp1w, L"wb");
- free(bindir);
- free(prgnam);
- free(fullcmd);
- free(tmp1w);
- }
+ {
+ wchar_t *tmp1w;
+ char *p, *pp, *bindir, *fullcmd, *prgnam;
+ bindir = kpse_var_value("SELFAUTOLOC");
+ for(pp = bindir; *pp; pp++) {
+ if(*pp == '/') *pp = '\\';
+ }
+ pp = cmd;
+ while(Isspace(*pp))
+ pp++;
+ prgnam = xmalloc(strlen(cmd));
+ p = prgnam;
+ while(!Isspace(*pp)) {
+ *p++ = *pp++;
+ }
+ *p = '\0';
+ fullcmd = concatn("\"\"", bindir, "\\", prgnam, "\"", pp, "\"", NULL);
+ tmp1w = get_wstring_from_mbstring(CP_UTF8, (const char *)fullcmd, tmp1w=NULL);
+ *fptr = _wpopen(tmp1w, L"wb");
+ free(bindir);
+ free(prgnam);
+ free(fullcmd);
+ free(tmp1w);
+ }
#else
- *fptr = popen(cmd, "w");
+ *fptr = popen(cmd, "w");
#endif
- free(cmd);
- return (*fptr != 0);
- }
+ free(cmd);
+ return (*fptr != 0);
+ }
}
int
dviclose(FILE* fptr)
{
- if (nopdfoutput) {
- if (fclose(fptr) != 0)
- return errno;
- } else {
- return pclose(fptr);
- }
- return 0;
+ if (nopdfoutput) {
+ if (fclose(fptr) != 0)
+ return errno;
+ } else {
+ return pclose(fptr);
+ }
+ return 0;
}
int
get_uni_c(UFILE* f)
{
- int rval;
- int c;
+ int rval;
+ int c;
#ifdef WIN32
- HANDLE hStdin;
- DWORD ret;
- wint_t wc[1];
+ HANDLE hStdin;
+ DWORD ret;
+ wint_t wc[1];
#endif
- if (f->savedChar != -1) {
- rval = f->savedChar;
- f->savedChar = -1;
- return rval;
- }
-
- switch (f->encodingMode) {
- case UTF8:
- c = rval = getc(f->f);
- if (rval != EOF) {
- uint16_t extraBytes = bytesFromUTF8[rval];
- switch (extraBytes) { /* note: code falls through cases! */
- case 3: c = getc(f->f);
- if (c < 0x80 || c >= 0xc0) goto bad_utf8;
- rval <<= 6; rval += c;
- case 2: c = getc(f->f);
- if (c < 0x80 || c >= 0xc0) goto bad_utf8;
- rval <<= 6; rval += c;
- case 1: c = getc(f->f);
- if (c < 0x80 || c >= 0xc0) goto bad_utf8;
- rval <<= 6; rval += c;
- case 0:
- break;
-
- bad_utf8:
- if (c != EOF)
- ungetc(c, f->f);
- case 5:
- case 4:
- badutf8warning();
- return 0xfffd; /* return without adjusting by offsetsFromUTF8 */
- };
- rval -= offsetsFromUTF8[extraBytes];
- }
- break;
-
- case UTF16BE:
- rval = getc(f->f);
- if (rval != EOF) {
- rval <<= 8;
- rval += getc(f->f);
- if (rval >= 0xd800 && rval <= 0xdbff) {
- int lo = getc(f->f);
- lo <<= 8;
- lo += getc(f->f);
- if (lo >= 0xdc00 && lo <= 0xdfff)
- rval = 0x10000 + (rval - 0xd800) * 0x400 + (lo - 0xdc00);
- else {
- rval = 0xfffd;
- f->savedChar = lo;
- }
- } else if (rval >= 0xdc00 && rval <= 0xdfff)
- rval = 0xfffd;
- }
- break;
-
- case UTF16LE:
- rval = getc(f->f);
- if (rval != EOF) {
- rval += (getc(f->f) << 8);
- if (rval >= 0xd800 && rval <= 0xdbff) {
- int lo = getc(f->f);
- lo += (getc(f->f) << 8);
- if (lo >= 0xdc00 && lo <= 0xdfff)
- rval = 0x10000 + (rval - 0xd800) * 0x400 + (lo - 0xdc00);
- else {
- rval = 0xfffd;
- f->savedChar = lo;
- }
- } else if (rval >= 0xdc00 && rval <= 0xdfff)
- rval = 0xfffd;
- }
- break;
+ if (f->savedChar != -1) {
+ rval = f->savedChar;
+ f->savedChar = -1;
+ return rval;
+ }
+
+ switch (f->encodingMode) {
+ case UTF8:
+ c = rval = getc(f->f);
+ if (rval != EOF) {
+ uint16_t extraBytes = bytesFromUTF8[rval];
+ switch (extraBytes) { /* note: code falls through cases! */
+ case 3: c = getc(f->f);
+ if (c < 0x80 || c >= 0xc0) goto bad_utf8;
+ rval <<= 6; rval += c;
+ case 2: c = getc(f->f);
+ if (c < 0x80 || c >= 0xc0) goto bad_utf8;
+ rval <<= 6; rval += c;
+ case 1: c = getc(f->f);
+ if (c < 0x80 || c >= 0xc0) goto bad_utf8;
+ rval <<= 6; rval += c;
+ case 0:
+ break;
+
+ bad_utf8:
+ if (c != EOF)
+ ungetc(c, f->f);
+ case 5:
+ case 4:
+ badutf8warning();
+ return 0xfffd; /* return without adjusting by offsetsFromUTF8 */
+ };
+ rval -= offsetsFromUTF8[extraBytes];
+ }
+ break;
+
+ case UTF16BE:
+ rval = getc(f->f);
+ if (rval != EOF) {
+ rval <<= 8;
+ rval += getc(f->f);
+ if (rval >= 0xd800 && rval <= 0xdbff) {
+ int lo = getc(f->f);
+ lo <<= 8;
+ lo += getc(f->f);
+ if (lo >= 0xdc00 && lo <= 0xdfff)
+ rval = 0x10000 + (rval - 0xd800) * 0x400 + (lo - 0xdc00);
+ else {
+ rval = 0xfffd;
+ f->savedChar = lo;
+ }
+ } else if (rval >= 0xdc00 && rval <= 0xdfff)
+ rval = 0xfffd;
+ }
+ break;
+
+ case UTF16LE:
+ rval = getc(f->f);
+ if (rval != EOF) {
+ rval += (getc(f->f) << 8);
+ if (rval >= 0xd800 && rval <= 0xdbff) {
+ int lo = getc(f->f);
+ lo += (getc(f->f) << 8);
+ if (lo >= 0xdc00 && lo <= 0xdfff)
+ rval = 0x10000 + (rval - 0xd800) * 0x400 + (lo - 0xdc00);
+ else {
+ rval = 0xfffd;
+ f->savedChar = lo;
+ }
+ } else if (rval >= 0xdc00 && rval <= 0xdfff)
+ rval = 0xfffd;
+ }
+ break;
#ifdef WIN32
- case WIN32CONSOLE:
- hStdin = GetStdHandle(STD_INPUT_HANDLE);
- if (ReadConsoleW(hStdin, wc, 1, &ret, NULL) == 0) {
- rval = EOF;
- break;
- }
- rval = wc[0];
- if (rval >= 0xd800 && rval <= 0xdbff) {
- int lo;
- if (ReadConsoleW(hStdin, wc, 1, &ret, NULL) == 0) {
- rval = EOF;
- break;
- }
- lo = wc[0];
- if (lo >= 0xdc00 && lo <= 0xdfff)
- rval = 0x10000 + (rval - 0xd800) * 0x400 + (lo - 0xdc00);
- else {
- rval = 0xfffd;
- f->savedChar = lo;
- }
- } else if (rval >= 0xdc00 && rval <= 0xdfff)
- rval = 0xfffd;
- break;
+ case WIN32CONSOLE:
+ hStdin = GetStdHandle(STD_INPUT_HANDLE);
+ if (ReadConsoleW(hStdin, wc, 1, &ret, NULL) == 0) {
+ rval = EOF;
+ break;
+ }
+ rval = wc[0];
+ if (rval >= 0xd800 && rval <= 0xdbff) {
+ int lo;
+ if (ReadConsoleW(hStdin, wc, 1, &ret, NULL) == 0) {
+ rval = EOF;
+ break;
+ }
+ lo = wc[0];
+ if (lo >= 0xdc00 && lo <= 0xdfff)
+ rval = 0x10000 + (rval - 0xd800) * 0x400 + (lo - 0xdc00);
+ else {
+ rval = 0xfffd;
+ f->savedChar = lo;
+ }
+ } else if (rval >= 0xdc00 && rval <= 0xdfff)
+ rval = 0xfffd;
+ break;
#endif
- case RAW:
- rval = getc(f->f);
- break;
+ case RAW:
+ rval = getc(f->f);
+ break;
- default:
- /* this can't happen */
- fprintf(stderr, "! Internal error---file input mode=%d.\n", f->encodingMode);
- uexit(3);
- }
+ default:
+ /* this can't happen */
+ fprintf(stderr, "! Internal error---file input mode=%d.\n", f->encodingMode);
+ uexit(3);
+ }
- return rval;
+ return rval;
}
void
makeutf16name()
{
- unsigned char* s = nameoffile + 1;
- uint32_t rval;
- uint16_t* t;
- static int name16len = 0;
- if (name16len <= namelength) {
- if (nameoffile16 != 0)
- free(nameoffile16);
- name16len = namelength + 10;
- nameoffile16 = xmalloc(name16len * sizeof(uint16_t));
- }
- t = nameoffile16;
- while (s <= nameoffile + namelength) {
- uint16_t extraBytes;
- rval = *(s++);
- extraBytes = bytesFromUTF8[rval];
- switch (extraBytes) { /* note: code falls through cases! */
- case 5: rval <<= 6; if (*s) rval += *(s++);
- case 4: rval <<= 6; if (*s) rval += *(s++);
- case 3: rval <<= 6; if (*s) rval += *(s++);
- case 2: rval <<= 6; if (*s) rval += *(s++);
- case 1: rval <<= 6; if (*s) rval += *(s++);
- case 0: ;
- };
- rval -= offsetsFromUTF8[extraBytes];
- if (rval > 0xffff) {
- rval -= 0x10000;
- *(t++) = 0xd800 + rval / 0x0400;
- *(t++) = 0xdc00 + rval % 0x0400;
- } else {
- *(t++) = rval;
- }
- }
- namelength16 = t - nameoffile16;
+ unsigned char* s = nameoffile + 1;
+ uint32_t rval;
+ uint16_t* t;
+ static int name16len = 0;
+ if (name16len <= namelength) {
+ if (nameoffile16 != 0)
+ free(nameoffile16);
+ name16len = namelength + 10;
+ nameoffile16 = (uint16_t*) xcalloc(name16len, sizeof(uint16_t));
+ }
+ t = nameoffile16;
+ while (s <= nameoffile + namelength) {
+ uint16_t extraBytes;
+ rval = *(s++);
+ extraBytes = bytesFromUTF8[rval];
+ switch (extraBytes) { /* note: code falls through cases! */
+ case 5: rval <<= 6; if (*s) rval += *(s++);
+ case 4: rval <<= 6; if (*s) rval += *(s++);
+ case 3: rval <<= 6; if (*s) rval += *(s++);
+ case 2: rval <<= 6; if (*s) rval += *(s++);
+ case 1: rval <<= 6; if (*s) rval += *(s++);
+ case 0: ;
+ };
+ rval -= offsetsFromUTF8[extraBytes];
+ if (rval > 0xffff) {
+ rval -= 0x10000;
+ *(t++) = 0xd800 + rval / 0x0400;
+ *(t++) = 0xdc00 + rval % 0x0400;
+ } else {
+ *(t++) = rval;
+ }
+ }
+ namelength16 = t - nameoffile16;
}
integer get_native_word_cp(void* pNode, int side)
{
- memoryword* node = (memoryword*)pNode;
- FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
- uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node));
- uint16_t glyphCount = native_glyph_count(node);
- integer f = native_font(node);
- uint16_t actual_glyph;
+ memoryword* node = (memoryword*)pNode;
+ FixedPoint* locations = (FixedPoint*)native_glyph_info_ptr(node);
+ uint16_t* glyphIDs = (uint16_t*)(locations + native_glyph_count(node));
+ uint16_t glyphCount = native_glyph_count(node);
+ integer f = native_font(node);
+ uint16_t actual_glyph;
if (glyphCount == 0)
return 0;
diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_ext.h b/Build/source/texk/web2c/xetexdir/XeTeX_ext.h
index e81b8781373..b0c42fe3060 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeX_ext.h
+++ b/Build/source/texk/web2c/xetexdir/XeTeX_ext.h
@@ -41,11 +41,11 @@ authorization from the copyright holders.
typedef struct UFILE* unicodefile;
#endif
-#define AAT_FONT_FLAG 0xFFFFU
-#define OTGR_FONT_FLAG 0xFFFEU
+#define AAT_FONT_FLAG 0xFFFFU
+#define OTGR_FONT_FLAG 0xFFFEU
-#define FONT_FLAGS_COLORED 0x01
-#define FONT_FLAGS_VERTICAL 0x02
+#define FONT_FLAGS_COLORED 0x01
+#define FONT_FLAGS_VERTICAL 0x02
/* some typedefs that XeTeX uses - on Mac OS, we get these from Apple headers,
but otherwise we'll need these substitute definitions */
@@ -54,10 +54,10 @@ typedef struct UFILE* unicodefile;
#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
#else
-typedef int32_t Fixed;
+typedef int32_t Fixed;
typedef struct {
- Fixed x;
- Fixed y;
+ Fixed x;
+ Fixed y;
} FixedPoint;
#endif
@@ -67,76 +67,76 @@ typedef uint16_t GlyphID;
/* these are also in xetex.web and must correspond! */
-#define pdfbox_crop 1
-#define pdfbox_media 2
-#define pdfbox_bleed 3
-#define pdfbox_trim 4
-#define pdfbox_art 5
+#define pdfbox_crop 1
+#define pdfbox_media 2
+#define pdfbox_bleed 3
+#define pdfbox_trim 4
+#define pdfbox_art 5
-#define XeTeX_count_glyphs 1
+#define XeTeX_count_glyphs 1
-#define XeTeX_count_variations 2
-#define XeTeX_variation 3
-#define XeTeX_find_variation_by_name 4
-#define XeTeX_variation_min 5
-#define XeTeX_variation_max 6
-#define XeTeX_variation_default 7
+#define XeTeX_count_variations 2
+#define XeTeX_variation 3
+#define XeTeX_find_variation_by_name 4
+#define XeTeX_variation_min 5
+#define XeTeX_variation_max 6
+#define XeTeX_variation_default 7
-#define XeTeX_count_features 8
-#define XeTeX_feature_code 9
-#define XeTeX_find_feature_by_name 10
-#define XeTeX_is_exclusive_feature 11
-#define XeTeX_count_selectors 12
-#define XeTeX_selector_code 13
-#define XeTeX_find_selector_by_name 14
-#define XeTeX_is_default_selector 15
+#define XeTeX_count_features 8
+#define XeTeX_feature_code 9
+#define XeTeX_find_feature_by_name 10
+#define XeTeX_is_exclusive_feature 11
+#define XeTeX_count_selectors 12
+#define XeTeX_selector_code 13
+#define XeTeX_find_selector_by_name 14
+#define XeTeX_is_default_selector 15
-#define XeTeX_OT_count_scripts 16
-#define XeTeX_OT_count_languages 17
-#define XeTeX_OT_count_features 18
-#define XeTeX_OT_script_code 19
-#define XeTeX_OT_language_code 20
-#define XeTeX_OT_feature_code 21
+#define XeTeX_OT_count_scripts 16
+#define XeTeX_OT_count_languages 17
+#define XeTeX_OT_count_features 18
+#define XeTeX_OT_script_code 19
+#define XeTeX_OT_language_code 20
+#define XeTeX_OT_feature_code 21
-#define XeTeX_map_char_to_glyph_code 22
+#define XeTeX_map_char_to_glyph_code 22
-#define XeTeX_variation_name 7 /* must match xetex.web */
-#define XeTeX_feature_name 8
-#define XeTeX_selector_name 9
+#define XeTeX_variation_name 7 /* must match xetex.web */
+#define XeTeX_feature_name 8
+#define XeTeX_selector_name 9
/* definitions used to access info in a native_word_node; must correspond with defines in xetex.web */
-#define width_offset 1
-#define depth_offset 2
-#define height_offset 3
-#define native_info_offset 4
-#define native_glyph_info_offset 5
-
-#define node_width(node) node[width_offset].cint
-#define node_depth(node) node[depth_offset].cint
-#define node_height(node) node[height_offset].cint
-#define native_length(node) node[native_info_offset].qqqq.b2
-#define native_font(node) node[native_info_offset].qqqq.b1
-#define native_glyph_count(node) node[native_info_offset].qqqq.b3
-#define native_glyph_info_ptr(node) node[native_glyph_info_offset].ptr
-#define native_glyph_info_size 10 /* info for each glyph is location (FixedPoint) + glyph ID (uint16_t) */
-
-#define native_glyph(p) native_length(p) /* glyph ID field in a glyph_node */
-
-#define XDV_GLYPH_STRING 254
-#define XDV_GLYPH_ARRAY 253
+#define width_offset 1
+#define depth_offset 2
+#define height_offset 3
+#define native_info_offset 4
+#define native_glyph_info_offset 5
+
+#define node_width(node) node[width_offset].cint
+#define node_depth(node) node[depth_offset].cint
+#define node_height(node) node[height_offset].cint
+#define native_length(node) node[native_info_offset].qqqq.b2
+#define native_font(node) node[native_info_offset].qqqq.b1
+#define native_glyph_count(node) node[native_info_offset].qqqq.b3
+#define native_glyph_info_ptr(node) node[native_glyph_info_offset].ptr
+#define native_glyph_info_size 10 /* info for each glyph is location (FixedPoint) + glyph ID (uint16_t) */
+
+#define native_glyph(p) native_length(p) /* glyph ID field in a glyph_node */
+
+#define XDV_GLYPH_STRING 254
+#define XDV_GLYPH_ARRAY 253
/* OT-related constants we need */
-#define kGSUB HB_TAG('G','S','U','B')
-#define kGPOS HB_TAG('G','P','O','S')
+#define kGSUB HB_TAG('G','S','U','B')
+#define kGPOS HB_TAG('G','P','O','S')
typedef struct
{
- float xMin;
- float yMin;
- float xMax;
- float yMax;
+ float xMin;
+ float yMin;
+ float xMax;
+ float yMax;
} GlyphBBox;
@@ -200,110 +200,111 @@ extern const CFStringRef kXeTeXEmboldenAttributeName;
#ifdef __cplusplus
extern "C" {
#endif
- void initversionstring(char **versions);
-
- void setinputfileencoding(unicodefile f, integer mode, integer encodingData);
- void uclose(unicodefile f);
- void linebreakstart(int f, integer localeStrNum, const uint16_t* text, integer textLength);
- int linebreaknext();
- int getencodingmodeandinfo(integer* info);
- void printutf8str(const unsigned char* str, int len);
- void printchars(const unsigned short* str, int len);
- void* findnativefont(unsigned char* name, integer scaled_size);
- void releasefontengine(void* engine, int type_flag);
- int readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, uint32_t* rgbValue);
-
- /* the metrics params here are really TeX 'scaled' values, but that typedef isn't available every place this is included */
- void otgetfontmetrics(void* engine, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant);
- void getnativecharheightdepth(integer font, integer ch, integer* height, integer* depth);
- void getnativecharsidebearings(integer font, integer ch, integer* lsb, integer* rsb);
-
- /* single-purpose metrics accessors */
- integer getnativecharwd(integer font, integer ch);
- integer getnativecharht(integer font, integer ch);
- integer getnativechardp(integer font, integer ch);
- integer getnativecharic(integer font, integer ch);
-
- integer getglyphbounds(integer font, integer edge, integer gid);
-
- integer otfontget(integer what, void* engine);
- integer otfontget1(integer what, void* engine, integer param);
- integer otfontget2(integer what, void* engine, integer param1, integer param2);
- integer otfontget3(integer what, void* engine, integer param1, integer param2, integer param3);
- int makeXDVGlyphArrayData(void* p);
- int makefontdef(integer f);
- int applymapping(void* cnv, const uint16_t* txtPtr, int txtLen);
- void store_justified_native_glyphs(void* node);
- void measure_native_node(void* node, int use_glyph_metrics);
- Fixed get_native_italic_correction(void* node);
- Fixed get_native_glyph_italic_correection(void* node);
- void measure_native_glyph(void* node, int use_glyph_metrics);
- integer mapchartoglyph(integer font, integer ch);
- integer mapglyphtoindex(integer font);
- integer getfontcharrange(integer font, int first);
- void printglyphname(integer font, integer gid);
- uint16_t get_native_glyph(void* pNode, unsigned index);
-
- void grprintfontname(integer what, void* pEngine, integer param1, integer param2);
- integer grfontgetnamed(integer what, void* pEngine);
- integer grfontgetnamed1(integer what, void* pEngine, integer param);
-
- double read_double(const char** s);
- unsigned int read_rgb_a(const char** cp);
-
- int countpdffilepages();
- int find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page);
- int u_open_in(unicodefile* f, integer filefmt, const char* fopen_mode, integer mode, integer encodingData);
- int open_dvi_output(FILE** fptr);
- int dviclose(FILE* fptr);
- int get_uni_c(UFILE* f);
- int input_line(UFILE* f);
- void makeutf16name();
-
- void terminatefontmanager();
- int maketexstring(const char* s);
-
- void checkfortfmfontmapping();
- void* loadtfmfontmapping();
- int applytfmfontmapping(void* mapping, int c);
+ void initversionstring(char **versions);
+
+ void setinputfileencoding(unicodefile f, integer mode, integer encodingData);
+ void uclose(unicodefile f);
+ void linebreakstart(int f, integer localeStrNum, const uint16_t* text, integer textLength);
+ int linebreaknext();
+ int getencodingmodeandinfo(integer* info);
+ void printutf8str(const unsigned char* str, int len);
+ void printchars(const unsigned short* str, int len);
+ void* findnativefont(unsigned char* name, integer scaled_size);
+ void releasefontengine(void* engine, int type_flag);
+ int readCommonFeatures(const char* feat, const char* end, float* extend, float* slant, float* embolden, float* letterspace, uint32_t* rgbValue);
+
+ /* the metrics params here are really TeX 'scaled' values, but that typedef isn't available every place this is included */
+ void otgetfontmetrics(void* engine, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant);
+ void getnativecharheightdepth(integer font, integer ch, integer* height, integer* depth);
+ void getnativecharsidebearings(integer font, integer ch, integer* lsb, integer* rsb);
+
+ /* single-purpose metrics accessors */
+ integer getnativecharwd(integer font, integer ch);
+ integer getnativecharht(integer font, integer ch);
+ integer getnativechardp(integer font, integer ch);
+ integer getnativecharic(integer font, integer ch);
+
+ integer getglyphbounds(integer font, integer edge, integer gid);
+
+ integer otfontget(integer what, void* engine);
+ integer otfontget1(integer what, void* engine, integer param);
+ integer otfontget2(integer what, void* engine, integer param1, integer param2);
+ integer otfontget3(integer what, void* engine, integer param1, integer param2, integer param3);
+ int makeXDVGlyphArrayData(void* p);
+ int makefontdef(integer f);
+ int applymapping(void* cnv, const uint16_t* txtPtr, int txtLen);
+ void store_justified_native_glyphs(void* node);
+ void measure_native_node(void* node, int use_glyph_metrics);
+ Fixed get_native_italic_correction(void* node);
+ Fixed get_native_glyph_italic_correction(void* node);
+ integer get_native_word_cp(void* node, int side);
+ void measure_native_glyph(void* node, int use_glyph_metrics);
+ integer mapchartoglyph(integer font, integer ch);
+ integer mapglyphtoindex(integer font);
+ integer getfontcharrange(integer font, int first);
+ void printglyphname(integer font, integer gid);
+ uint16_t get_native_glyph(void* pNode, unsigned index);
+
+ void grprintfontname(integer what, void* pEngine, integer param1, integer param2);
+ integer grfontgetnamed(integer what, void* pEngine);
+ integer grfontgetnamed1(integer what, void* pEngine, integer param);
+
+ double read_double(const char** s);
+ unsigned int read_rgb_a(const char** cp);
+
+ int countpdffilepages();
+ int find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page);
+ int u_open_in(unicodefile* f, integer filefmt, const char* fopen_mode, integer mode, integer encodingData);
+ int open_dvi_output(FILE** fptr);
+ int dviclose(FILE* fptr);
+ int get_uni_c(UFILE* f);
+ int input_line(UFILE* f);
+ void makeutf16name();
+
+ void terminatefontmanager();
+ int maketexstring(const char* s);
+
+ void checkfortfmfontmapping();
+ void* loadtfmfontmapping();
+ int applytfmfontmapping(void* mapping, int c);
#ifndef XETEX_MAC
typedef void* CFDictionaryRef; /* dummy declaration just so the stubs can compile */
#endif
- int aatfontget(int what, CFDictionaryRef attrs);
- int aatfontget1(int what, CFDictionaryRef attrs, int param);
- int aatfontget2(int what, CFDictionaryRef attrs, int param1, int param2);
- int aatfontgetnamed(int what, CFDictionaryRef attrs);
- int aatfontgetnamed1(int what, CFDictionaryRef attrs, int param);
- void aatprintfontname(int what, CFDictionaryRef attrs, int param1, int param2);
- /* the metrics params here are really TeX 'scaled' (or MacOS 'Fixed') values, but that typedef isn't available every place this is included */
- void aatgetfontmetrics(CFDictionaryRef attrs, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant);
+ int aatfontget(int what, CFDictionaryRef attrs);
+ int aatfontget1(int what, CFDictionaryRef attrs, int param);
+ int aatfontget2(int what, CFDictionaryRef attrs, int param1, int param2);
+ int aatfontgetnamed(int what, CFDictionaryRef attrs);
+ int aatfontgetnamed1(int what, CFDictionaryRef attrs, int param);
+ void aatprintfontname(int what, CFDictionaryRef attrs, int param1, int param2);
+ /* the metrics params here are really TeX 'scaled' (or MacOS 'Fixed') values, but that typedef isn't available every place this is included */
+ void aatgetfontmetrics(CFDictionaryRef attrs, integer* ascent, integer* descent, integer* xheight, integer* capheight, integer* slant);
- void set_cp_code(int fontNum, unsigned int code, int side, int value);
- int get_cp_code(int fontNum, unsigned int code, int side);
+ void set_cp_code(int fontNum, unsigned int code, int side, int value);
+ int get_cp_code(int fontNum, unsigned int code, int side);
#ifdef XETEX_MAC
/* functions in XeTeX_mac.c */
- void* loadAATfont(CTFontDescriptorRef descriptor, integer scaled_size, const char* cp1);
- void DoAATLayout(void* node, int justify);
- void GetGlyphBBox_AAT(CFDictionaryRef fontAttrs, uint16_t gid, GlyphBBox* bbox);
- double GetGlyphWidth_AAT(CFDictionaryRef fontAttrs, uint16_t gid);
- void GetGlyphHeightDepth_AAT(CFDictionaryRef fontAttrs, uint16_t gid, float* ht, float* dp);
- void GetGlyphSidebearings_AAT(CFDictionaryRef fontAttrs, uint16_t gid, float* lsb, float* rsb);
- double GetGlyphItalCorr_AAT(CFDictionaryRef fontAttrs, uint16_t gid);
- int MapCharToGlyph_AAT(CFDictionaryRef fontAttrs, UInt32 ch);
- int MapGlyphToIndex_AAT(CFDictionaryRef attributes, const char* glyphName);
- char* GetGlyphNameFromCTFont(CTFontRef ctFontRef, uint16_t gid, int* len);
- CFDictionaryRef findDictionaryInArray(CFArrayRef array, const void* nameKey, const char* name, int nameLength);
- CFDictionaryRef findDictionaryInArrayWithIdentifier(CFArrayRef array, const void* identifierKey, int identifier);
- CFNumberRef findSelectorByName(CFDictionaryRef feature, const char* name, int nameLength);
- char* getNameFromCTFont(CTFontRef ctFontRef, CFStringRef nameKey);
- char* getFileNameFromCTFont(CTFontRef ctFontRef, int* index);
- int GetFontCharRange_AAT(CFDictionaryRef fontAttrs, int reqFirst);
- CTFontRef fontFromAttributes(CFDictionaryRef fontAttrs);
- CTFontRef fontFromInteger(integer font);
+ void* loadAATfont(CTFontDescriptorRef descriptor, integer scaled_size, const char* cp1);
+ void DoAATLayout(void* node, int justify);
+ void GetGlyphBBox_AAT(CFDictionaryRef fontAttrs, uint16_t gid, GlyphBBox* bbox);
+ double GetGlyphWidth_AAT(CFDictionaryRef fontAttrs, uint16_t gid);
+ void GetGlyphHeightDepth_AAT(CFDictionaryRef fontAttrs, uint16_t gid, float* ht, float* dp);
+ void GetGlyphSidebearings_AAT(CFDictionaryRef fontAttrs, uint16_t gid, float* lsb, float* rsb);
+ double GetGlyphItalCorr_AAT(CFDictionaryRef fontAttrs, uint16_t gid);
+ int MapCharToGlyph_AAT(CFDictionaryRef fontAttrs, UInt32 ch);
+ int MapGlyphToIndex_AAT(CFDictionaryRef attributes, const char* glyphName);
+ char* GetGlyphNameFromCTFont(CTFontRef ctFontRef, uint16_t gid, int* len);
+ CFDictionaryRef findDictionaryInArray(CFArrayRef array, const void* nameKey, const char* name, int nameLength);
+ CFDictionaryRef findDictionaryInArrayWithIdentifier(CFArrayRef array, const void* identifierKey, int identifier);
+ CFNumberRef findSelectorByName(CFDictionaryRef feature, const char* name, int nameLength);
+ char* getNameFromCTFont(CTFontRef ctFontRef, CFStringRef nameKey);
+ char* getFileNameFromCTFont(CTFontRef ctFontRef, int* index);
+ int GetFontCharRange_AAT(CFDictionaryRef fontAttrs, int reqFirst);
+ CTFontRef fontFromAttributes(CFDictionaryRef fontAttrs);
+ CTFontRef fontFromInteger(integer font);
#endif
#ifdef __cplusplus
};
@@ -312,14 +313,14 @@ typedef void* CFDictionaryRef; /* dummy declaration just so the stubs can compil
#ifdef __cplusplus
extern "C" {
#endif
- double Fix2D(Fixed f);
- Fixed D2Fix(double d);
+ double Fix2D(Fixed f);
+ Fixed D2Fix(double d);
#ifdef __cplusplus
};
#endif
// copied from xetex.web
-#define LEFT_SIDE 0
-#define RIGHT_SIDE 1
+#define LEFT_SIDE 0
+#define RIGHT_SIDE 1
#endif /* __XETEX_EXT_H */
diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_mac.c b/Build/source/texk/web2c/xetexdir/XeTeX_mac.c
index 02fdc428c05..f3e78cb588b 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeX_mac.c
+++ b/Build/source/texk/web2c/xetexdir/XeTeX_mac.c
@@ -48,496 +48,497 @@ authorization from the copyright holders.
static inline double
TeXtoPSPoints(double pts)
{
- return pts * 72.0 / 72.27;
+ return pts * 72.0 / 72.27;
}
static inline double
PStoTeXPoints(double pts)
{
- return pts * 72.27 / 72.0;
+ return pts * 72.27 / 72.0;
}
static inline Fixed
FixedPStoTeXPoints(double pts)
{
- return D2Fix(PStoTeXPoints(pts));
+ return D2Fix(PStoTeXPoints(pts));
}
CTFontRef
fontFromAttributes(CFDictionaryRef attributes)
{
- return CFDictionaryGetValue(attributes, kCTFontAttributeName);
+ return CFDictionaryGetValue(attributes, kCTFontAttributeName);
}
CTFontRef
fontFromInteger(integer font)
{
- CFDictionaryRef attributes = (CFDictionaryRef) fontlayoutengine[font];
- return fontFromAttributes(attributes);
+ CFDictionaryRef attributes = (CFDictionaryRef) fontlayoutengine[font];
+ return fontFromAttributes(attributes);
}
void
DoAATLayout(void* p, int justify)
{
- CFArrayRef glyphRuns;
- CFIndex i, j, runCount;
- CFIndex totalGlyphCount = 0;
- UInt16* glyphIDs;
- Fixed* glyphAdvances;
- void* glyph_info;
- FixedPoint* locations;
- Fixed lsUnit, lsDelta;
- CGFloat width;
-
- long txtLen;
- const UniChar* txtPtr;
-
- CFDictionaryRef attributes;
- CFStringRef string;
- CFAttributedStringRef attrString;
- CTTypesetterRef typesetter;
- CTLineRef line;
-
- memoryword* node = (memoryword*)p;
-
- unsigned f = native_font(node);
- if (fontarea[f] != AAT_FONT_FLAG) {
- fprintf(stderr, "internal error: DoAATLayout called for non-AAT font\n");
- exit(1);
- }
-
- txtLen = native_length(node);
- txtPtr = (UniChar*)(node + native_node_size);
-
- attributes = fontlayoutengine[native_font(node)];
- string = CFStringCreateWithCharactersNoCopy(NULL, txtPtr, txtLen, kCFAllocatorNull);
- attrString = CFAttributedStringCreate(NULL, string, attributes);
- CFRelease(string);
-
- typesetter = CTTypesetterCreateWithAttributedString(attrString);
- line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, txtLen));
- if (justify) {
- CGFloat lineWidth = TeXtoPSPoints(Fix2D(node_width(node)));
- CTLineRef justifiedLine = CTLineCreateJustifiedLine(line, TeXtoPSPoints(Fix2D(fract1)), lineWidth);
- // TODO(jjgod): how to handle the case when justification failed? for
- // now we just fallback to use the original line.
- if (justifiedLine) {
- CFRelease(line);
- line = justifiedLine;
- }
- }
-
- glyphRuns = CTLineGetGlyphRuns(line);
- runCount = CFArrayGetCount(glyphRuns);
- totalGlyphCount = CTLineGetGlyphCount(line);
-
- if (totalGlyphCount > 0) {
- glyph_info = xmalloc(totalGlyphCount * native_glyph_info_size);
- locations = (FixedPoint*)glyph_info;
- glyphIDs = (UInt16*)(locations + totalGlyphCount);
- glyphAdvances = xmalloc(totalGlyphCount * sizeof(Fixed));
- totalGlyphCount = 0;
-
- width = 0;
- for (i = 0; i < runCount; i++) {
- CTRunRef run = CFArrayGetValueAtIndex(glyphRuns, i);
- CFIndex count = CTRunGetGlyphCount(run);
- CFDictionaryRef runAttributes = CTRunGetAttributes(run);
- CFBooleanRef vertical = CFDictionaryGetValue(runAttributes, kCTVerticalFormsAttributeName);
- // TODO(jjgod): Avoid unnecessary allocation with CTRunGetFoosPtr().
- CGGlyph* glyphs = (CGGlyph*) xmalloc(count * sizeof(CGGlyph));
- CGPoint* positions = (CGPoint*) xmalloc(count * sizeof(CGPoint));
- CGSize* advances = (CGSize*) xmalloc(count * sizeof(CGSize));
- CGFloat runWidth = CTRunGetTypographicBounds(run, CFRangeMake(0, 0), NULL, NULL, NULL);
- CTRunGetGlyphs(run, CFRangeMake(0, 0), glyphs);
- CTRunGetPositions(run, CFRangeMake(0, 0), positions);
- CTRunGetAdvances(run, CFRangeMake(0, 0), advances);
- for (j = 0; j < count; j++) {
- // XXX Core Text has that font cascading thing that will do
- // font substitution for missing glyphs, which we do not want
- // but I can not find a way to disable it yet, so if the font
- // of the resulting run is not the same font we asked for, use
- // the glyph at index 0 (usually .notdef) instead or we will be
- // showing garbage or even invalid glyphs
- char *ps_name1 = getNameFromCTFont(fontFromAttributes(attributes), kCTFontPostScriptNameKey);
- char *ps_name2 = getNameFromCTFont(fontFromAttributes(runAttributes), kCTFontPostScriptNameKey);
- if (strcmp(ps_name1, ps_name2) != 0)
- glyphIDs[totalGlyphCount] = 0;
- else
- glyphIDs[totalGlyphCount] = glyphs[j];
-
- // Swap X and Y when doing vertical layout
- if (vertical == kCFBooleanTrue) {
- locations[totalGlyphCount].x = FixedPStoTeXPoints(-positions[j].y);
- // XXX trasformation matrix changes y positions!
- //locations[totalGlyphCount].y = FixedPStoTeXPoints(-positions[j].x);
- locations[totalGlyphCount].y = 0;
- } else {
- locations[totalGlyphCount].x = FixedPStoTeXPoints(positions[j].x);
- // XXX trasformation matrix changes y positions!
- //locations[totalGlyphCount].y = FixedPStoTeXPoints(positions[j].y);
- locations[totalGlyphCount].y = 0;
- }
- glyphAdvances[totalGlyphCount] = advances[j].width;
- totalGlyphCount++;
- }
- width += FixedPStoTeXPoints(runWidth);
- free(glyphs);
- free(positions);
- }
- }
-
- native_glyph_count(node) = totalGlyphCount;
- native_glyph_info_ptr(node) = glyph_info;
-
- if (!justify) {
- node_width(node) = width;
-
- if (totalGlyphCount > 0) {
- /* this is essentially a copy from similar code in XeTeX_ext.c, easier
- * to be done here */
- if (fontletterspace[f] != 0) {
- Fixed lsDelta = 0;
- Fixed lsUnit = fontletterspace[f];
- int i;
- for (i = 0; i < totalGlyphCount; ++i) {
- if (glyphAdvances[i] == 0 && lsDelta != 0)
- lsDelta -= lsUnit;
- locations[i].x += lsDelta;
- lsDelta += lsUnit;
- }
- if (lsDelta != 0) {
- lsDelta -= lsUnit;
- node_width(node) += lsDelta;
- }
- }
- }
- }
-
- CFRelease(line);
- CFRelease(typesetter);
+ CFArrayRef glyphRuns;
+ CFIndex i, j, runCount;
+ CFIndex totalGlyphCount = 0;
+ UInt16* glyphIDs;
+ Fixed* glyphAdvances;
+ void* glyph_info;
+ FixedPoint* locations;
+ Fixed lsUnit, lsDelta;
+ CGFloat width;
+
+ long txtLen;
+ const UniChar* txtPtr;
+
+ CFDictionaryRef attributes;
+ CFStringRef string;
+ CFAttributedStringRef attrString;
+ CTTypesetterRef typesetter;
+ CTLineRef line;
+
+ memoryword* node = (memoryword*)p;
+
+ unsigned f = native_font(node);
+ if (fontarea[f] != AAT_FONT_FLAG) {
+ fprintf(stderr, "internal error: DoAATLayout called for non-AAT font\n");
+ exit(1);
+ }
+
+ txtLen = native_length(node);
+ txtPtr = (UniChar*)(node + native_node_size);
+
+ attributes = fontlayoutengine[native_font(node)];
+ string = CFStringCreateWithCharactersNoCopy(NULL, txtPtr, txtLen, kCFAllocatorNull);
+ attrString = CFAttributedStringCreate(NULL, string, attributes);
+ CFRelease(string);
+
+ typesetter = CTTypesetterCreateWithAttributedString(attrString);
+ CFRelease(attrString);
+ line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, txtLen));
+ if (justify) {
+ CGFloat lineWidth = TeXtoPSPoints(Fix2D(node_width(node)));
+ CTLineRef justifiedLine = CTLineCreateJustifiedLine(line, TeXtoPSPoints(Fix2D(fract1)), lineWidth);
+ // TODO(jjgod): how to handle the case when justification failed? for
+ // now we just fallback to use the original line.
+ if (justifiedLine) {
+ CFRelease(line);
+ line = justifiedLine;
+ }
+ }
+
+ glyphRuns = CTLineGetGlyphRuns(line);
+ runCount = CFArrayGetCount(glyphRuns);
+ totalGlyphCount = CTLineGetGlyphCount(line);
+
+ if (totalGlyphCount > 0) {
+ glyph_info = xmalloc(totalGlyphCount * native_glyph_info_size);
+ locations = (FixedPoint*)glyph_info;
+ glyphIDs = (UInt16*)(locations + totalGlyphCount);
+ glyphAdvances = xmalloc(totalGlyphCount * sizeof(Fixed));
+ totalGlyphCount = 0;
+
+ width = 0;
+ for (i = 0; i < runCount; i++) {
+ CTRunRef run = CFArrayGetValueAtIndex(glyphRuns, i);
+ CFIndex count = CTRunGetGlyphCount(run);
+ CFDictionaryRef runAttributes = CTRunGetAttributes(run);
+ CFBooleanRef vertical = CFDictionaryGetValue(runAttributes, kCTVerticalFormsAttributeName);
+ // TODO(jjgod): Avoid unnecessary allocation with CTRunGetFoosPtr().
+ CGGlyph* glyphs = (CGGlyph*) xmalloc(count * sizeof(CGGlyph));
+ CGPoint* positions = (CGPoint*) xmalloc(count * sizeof(CGPoint));
+ CGSize* advances = (CGSize*) xmalloc(count * sizeof(CGSize));
+ CGFloat runWidth = CTRunGetTypographicBounds(run, CFRangeMake(0, 0), NULL, NULL, NULL);
+ CTRunGetGlyphs(run, CFRangeMake(0, 0), glyphs);
+ CTRunGetPositions(run, CFRangeMake(0, 0), positions);
+ CTRunGetAdvances(run, CFRangeMake(0, 0), advances);
+ for (j = 0; j < count; j++) {
+ // XXX Core Text has that font cascading thing that will do
+ // font substitution for missing glyphs, which we do not want
+ // but I can not find a way to disable it yet, so if the font
+ // of the resulting run is not the same font we asked for, use
+ // the glyph at index 0 (usually .notdef) instead or we will be
+ // showing garbage or even invalid glyphs
+ if (!CFEqual(fontFromAttributes(attributes), fontFromAttributes(runAttributes)))
+ glyphIDs[totalGlyphCount] = 0;
+ else
+ glyphIDs[totalGlyphCount] = glyphs[j];
+
+ // Swap X and Y when doing vertical layout
+ if (vertical == kCFBooleanTrue) {
+ locations[totalGlyphCount].x = FixedPStoTeXPoints(-positions[j].y);
+ // XXX trasformation matrix changes y positions!
+ //locations[totalGlyphCount].y = FixedPStoTeXPoints(-positions[j].x);
+ locations[totalGlyphCount].y = 0;
+ } else {
+ locations[totalGlyphCount].x = FixedPStoTeXPoints(positions[j].x);
+ // XXX trasformation matrix changes y positions!
+ //locations[totalGlyphCount].y = FixedPStoTeXPoints(positions[j].y);
+ locations[totalGlyphCount].y = 0;
+ }
+ glyphAdvances[totalGlyphCount] = advances[j].width;
+ totalGlyphCount++;
+ }
+ width += FixedPStoTeXPoints(runWidth);
+ free(glyphs);
+ free(positions);
+ free(advances);
+ }
+ }
+
+ native_glyph_count(node) = totalGlyphCount;
+ native_glyph_info_ptr(node) = glyph_info;
+
+ if (!justify) {
+ node_width(node) = width;
+
+ if (totalGlyphCount > 0) {
+ /* this is essentially a copy from similar code in XeTeX_ext.c, easier
+ * to be done here */
+ if (fontletterspace[f] != 0) {
+ Fixed lsDelta = 0;
+ Fixed lsUnit = fontletterspace[f];
+ int i;
+ for (i = 0; i < totalGlyphCount; ++i) {
+ if (glyphAdvances[i] == 0 && lsDelta != 0)
+ lsDelta -= lsUnit;
+ locations[i].x += lsDelta;
+ lsDelta += lsUnit;
+ }
+ if (lsDelta != 0) {
+ lsDelta -= lsUnit;
+ node_width(node) += lsDelta;
+ }
+ }
+ }
+ }
+
+ free(glyphAdvances);
+ CFRelease(line);
+ CFRelease(typesetter);
}
static void
getGlyphBBoxFromCTFont(CTFontRef font, UInt16 gid, GlyphBBox* bbox)
{
- CGRect rect;
-
- bbox->xMin = 65536.0;
- bbox->yMin = 65536.0;
- bbox->xMax = -65536.0;
- bbox->yMax = -65536.0;
-
- rect = CTFontGetBoundingRectsForGlyphs(font,
- 0, /* Use default orientation for now, handle vertical later */
- (const CGGlyph *) &gid, NULL, 1);
-
- if (CGRectIsNull(rect))
- bbox->xMin = bbox->yMin = bbox->xMax = bbox->yMax = 0;
- else {
- bbox->yMin = PStoTeXPoints(rect.origin.y);
- bbox->yMax = PStoTeXPoints(rect.origin.y + rect.size.height);
- bbox->xMin = PStoTeXPoints(rect.origin.x);
- bbox->xMax = PStoTeXPoints(rect.origin.x + rect.size.width);
- }
+ CGRect rect;
+
+ bbox->xMin = 65536.0;
+ bbox->yMin = 65536.0;
+ bbox->xMax = -65536.0;
+ bbox->yMax = -65536.0;
+
+ rect = CTFontGetBoundingRectsForGlyphs(font,
+ 0, /* Use default orientation for now, handle vertical later */
+ (const CGGlyph *) &gid, NULL, 1);
+
+ if (CGRectIsNull(rect))
+ bbox->xMin = bbox->yMin = bbox->xMax = bbox->yMax = 0;
+ else {
+ bbox->yMin = PStoTeXPoints(rect.origin.y);
+ bbox->yMax = PStoTeXPoints(rect.origin.y + rect.size.height);
+ bbox->xMin = PStoTeXPoints(rect.origin.x);
+ bbox->xMax = PStoTeXPoints(rect.origin.x + rect.size.width);
+ }
}
void
GetGlyphBBox_AAT(CFDictionaryRef attributes, UInt16 gid, GlyphBBox* bbox)
- /* returns glyph bounding box in TeX points */
+ /* returns glyph bounding box in TeX points */
{
- CTFontRef font = fontFromAttributes(attributes);
- return getGlyphBBoxFromCTFont(font, gid, bbox);
+ CTFontRef font = fontFromAttributes(attributes);
+ return getGlyphBBoxFromCTFont(font, gid, bbox);
}
static double
getGlyphWidthFromCTFont(CTFontRef font, UInt16 gid)
{
- CGSize advances[1] = { CGSizeMake(0, 0) };
- return PStoTeXPoints(CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1));
+ return PStoTeXPoints(CTFontGetAdvancesForGlyphs(font, kCTFontHorizontalOrientation, &gid, NULL, 1));
}
double
GetGlyphWidth_AAT(CFDictionaryRef attributes, UInt16 gid)
- /* returns TeX points */
+ /* returns TeX points */
{
- CTFontRef font = fontFromAttributes(attributes);
- return getGlyphWidthFromCTFont(font, gid);
+ CTFontRef font = fontFromAttributes(attributes);
+ return getGlyphWidthFromCTFont(font, gid);
}
void
GetGlyphHeightDepth_AAT(CFDictionaryRef attributes, UInt16 gid, float* ht, float* dp)
- /* returns TeX points */
+ /* returns TeX points */
{
- GlyphBBox bbox;
-
- GetGlyphBBox_AAT(attributes, gid, &bbox);
+ GlyphBBox bbox;
- *ht = bbox.yMax;
- *dp = -bbox.yMin;
+ GetGlyphBBox_AAT(attributes, gid, &bbox);
+
+ *ht = bbox.yMax;
+ *dp = -bbox.yMin;
}
void
GetGlyphSidebearings_AAT(CFDictionaryRef attributes, UInt16 gid, float* lsb, float* rsb)
- /* returns TeX points */
+ /* returns TeX points */
{
- CTFontRef font = fontFromAttributes(attributes);
- CGSize advances[1] = { CGSizeMake(0, 0) };
- double advance = CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1);
- GlyphBBox bbox;
- getGlyphBBoxFromCTFont(font, gid, &bbox);
- *lsb = bbox.xMin;
- *rsb = PStoTeXPoints(advance) - bbox.xMax;
+ CTFontRef font = fontFromAttributes(attributes);
+ CGSize advances[1] = { CGSizeMake(0, 0) };
+ double advance = CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1);
+ GlyphBBox bbox;
+ getGlyphBBoxFromCTFont(font, gid, &bbox);
+ *lsb = bbox.xMin;
+ *rsb = PStoTeXPoints(advance) - bbox.xMax;
}
double
GetGlyphItalCorr_AAT(CFDictionaryRef attributes, UInt16 gid)
{
- CTFontRef font = fontFromAttributes(attributes);
- CGSize advances[1] = { CGSizeMake(0, 0) };
- double advance = CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1);
+ CTFontRef font = fontFromAttributes(attributes);
+ CGSize advances[1] = { CGSizeMake(0, 0) };
+ double advance = CTFontGetAdvancesForGlyphs(font, 0, &gid, advances, 1);
- GlyphBBox bbox;
- getGlyphBBoxFromCTFont(font, gid, &bbox);
+ GlyphBBox bbox;
+ getGlyphBBoxFromCTFont(font, gid, &bbox);
- if (bbox.xMax > PStoTeXPoints(advance))
- return bbox.xMax - PStoTeXPoints(advance);
- return 0;
+ if (bbox.xMax > PStoTeXPoints(advance))
+ return bbox.xMax - PStoTeXPoints(advance);
+ return 0;
}
static int
mapCharToGlyphFromCTFont(CTFontRef font, UInt32 ch)
{
- CGGlyph glyphs[2] = { 0 };
- UniChar txt[2];
- int len = 1;
-
- if (ch > 0xffff) {
- ch -= 0x10000;
- txt[0] = 0xd800 + ch / 1024;
- txt[1] = 0xdc00 + ch % 1024;
- len = 2;
- } else {
- txt[0] = ch;
- }
-
- if (CTFontGetGlyphsForCharacters(font, txt, glyphs, len))
- return glyphs[0];
-
- return 0;
+ CGGlyph glyphs[2] = { 0 };
+ UniChar txt[2];
+ int len = 1;
+
+ if (ch > 0xffff) {
+ ch -= 0x10000;
+ txt[0] = 0xd800 + ch / 1024;
+ txt[1] = 0xdc00 + ch % 1024;
+ len = 2;
+ } else {
+ txt[0] = ch;
+ }
+
+ if (CTFontGetGlyphsForCharacters(font, txt, glyphs, len))
+ return glyphs[0];
+
+ return 0;
}
int
MapCharToGlyph_AAT(CFDictionaryRef attributes, UInt32 ch)
{
- CTFontRef font = fontFromAttributes(attributes);
- return mapCharToGlyphFromCTFont(font, ch);
+ CTFontRef font = fontFromAttributes(attributes);
+ return mapCharToGlyphFromCTFont(font, ch);
}
static int
GetGlyphIDFromCTFont(CTFontRef ctFontRef, const char* glyphName)
{
- CFStringRef glyphname = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
- glyphName,
- kCFStringEncodingUTF8,
- kCFAllocatorNull);
- int rval = CTFontGetGlyphWithName(ctFontRef, glyphname);
- CFRelease(glyphname);
- return rval;
+ CFStringRef glyphname = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
+ glyphName,
+ kCFStringEncodingUTF8,
+ kCFAllocatorNull);
+ int rval = CTFontGetGlyphWithName(ctFontRef, glyphname);
+ CFRelease(glyphname);
+ return rval;
}
int
MapGlyphToIndex_AAT(CFDictionaryRef attributes, const char* glyphName)
{
- CTFontRef font = fontFromAttributes(attributes);
- return GetGlyphIDFromCTFont(font, glyphName);
+ CTFontRef font = fontFromAttributes(attributes);
+ return GetGlyphIDFromCTFont(font, glyphName);
}
char*
GetGlyphNameFromCTFont(CTFontRef ctFontRef, UInt16 gid, int* len)
{
- CGFontRef cgfont;
- static char buffer[256];
- buffer[0] = 0;
- *len = 0;
-
- cgfont = CTFontCopyGraphicsFont(ctFontRef, 0);
- if (cgfont && gid < CGFontGetNumberOfGlyphs(cgfont)) {
- CFStringRef glyphname = CGFontCopyGlyphNameForGlyph(cgfont, gid);
- if (glyphname) {
- if (CFStringGetCString(glyphname, buffer, 256, kCFStringEncodingUTF8)) {
- *len = strlen(buffer);
- }
- CFRelease(glyphname);
- }
- CGFontRelease(cgfont);
- }
-
- return &buffer[0];
+ CGFontRef cgfont;
+ static char buffer[256];
+ buffer[0] = 0;
+ *len = 0;
+
+ cgfont = CTFontCopyGraphicsFont(ctFontRef, 0);
+ if (cgfont && gid < CGFontGetNumberOfGlyphs(cgfont)) {
+ CFStringRef glyphname = CGFontCopyGlyphNameForGlyph(cgfont, gid);
+ if (glyphname) {
+ if (CFStringGetCString(glyphname, buffer, 256, kCFStringEncodingUTF8)) {
+ *len = strlen(buffer);
+ }
+ CFRelease(glyphname);
+ }
+ CGFontRelease(cgfont);
+ }
+
+ return &buffer[0];
}
int
GetFontCharRange_AAT(CFDictionaryRef attributes, int reqFirst)
{
- if (reqFirst) {
- int ch = 0;
- while (MapCharToGlyph_AAT(attributes, ch) == 0 && ch < 0x10ffff)
- ++ch;
- return ch;
- } else {
- int ch = 0x10ffff;
- while (MapCharToGlyph_AAT(attributes, ch) == 0 && ch > 0)
- --ch;
- return ch;
- }
+ if (reqFirst) {
+ int ch = 0;
+ while (MapCharToGlyph_AAT(attributes, ch) == 0 && ch < 0x10ffff)
+ ++ch;
+ return ch;
+ } else {
+ int ch = 0x10ffff;
+ while (MapCharToGlyph_AAT(attributes, ch) == 0 && ch > 0)
+ --ch;
+ return ch;
+ }
}
char*
getNameFromCTFont(CTFontRef ctFontRef, CFStringRef nameKey)
{
- char *buf;
- CFStringRef name = CTFontCopyName(ctFontRef, nameKey);
- CFIndex len = CFStringGetLength(name);
- len = len * 6 + 1;
- buf = xmalloc(len);
- if (CFStringGetCString(name, buf, len, kCFStringEncodingUTF8))
- return buf;
- free(buf);
- return 0;
+ char *buf;
+ CFStringRef name = CTFontCopyName(ctFontRef, nameKey);
+ CFIndex len = CFStringGetLength(name);
+ len = len * 6 + 1;
+ buf = xmalloc(len);
+ if (CFStringGetCString(name, buf, len, kCFStringEncodingUTF8))
+ return buf;
+ free(buf);
+ return NULL;
}
char*
getFileNameFromCTFont(CTFontRef ctFontRef, int *index)
{
- char *ret = NULL;
- CFURLRef url = NULL;
+ char *ret = NULL;
+ CFURLRef url = NULL;
#if !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
- /* kCTFontURLAttribute was not avialable before 10.6 */
- ATSFontRef atsFont;
- FSRef fsref;
- OSStatus status;
- atsFont = CTFontGetPlatformFont(ctFontRef, NULL);
- status = ATSFontGetFileReference(atsFont, &fsref);
- if (status == noErr)
- url = CFURLCreateFromFSRef(NULL, &fsref);
+ /* kCTFontURLAttribute was not avialable before 10.6 */
+ ATSFontRef atsFont;
+ FSRef fsref;
+ OSStatus status;
+ atsFont = CTFontGetPlatformFont(ctFontRef, NULL);
+ status = ATSFontGetFileReference(atsFont, &fsref);
+ if (status == noErr)
+ url = CFURLCreateFromFSRef(NULL, &fsref);
#else
- url = (CFURLRef) CTFontCopyAttribute(ctFontRef, kCTFontURLAttribute);
+ url = (CFURLRef) CTFontCopyAttribute(ctFontRef, kCTFontURLAttribute);
#endif
- if (url) {
- UInt8 pathname[PATH_MAX];
- if (CFURLGetFileSystemRepresentation(url, true, pathname, PATH_MAX)) {
- FT_Error error;
- FT_Face face;
-
- *index = 0;
-
- if (!gFreeTypeLibrary) {
- error = FT_Init_FreeType(&gFreeTypeLibrary);
- if (error) {
- fprintf(stderr, "FreeType initialization failed! (%d)\n", error);
- exit(1);
- }
- }
-
- error = FT_New_Face(gFreeTypeLibrary, (char *) pathname, 0, &face);
- if (!error) {
- if (face->num_faces > 1) {
- int num_faces = face->num_faces;
- char *ps_name1 = getNameFromCTFont(ctFontRef, kCTFontPostScriptNameKey);
- int i;
- *index = -1;
- FT_Done_Face (face);
- for (i = 0; i < num_faces; i++) {
- error = FT_New_Face (gFreeTypeLibrary, (char *) pathname, i, &face);
- if (!error) {
- const char *ps_name2 = FT_Get_Postscript_Name(face);
- if (strcmp(ps_name1, ps_name2) == 0) {
- *index = i;
- break;
- }
- FT_Done_Face (face);
- }
- }
- }
- }
-
- if (*index != -1)
- ret = strdup((char *) pathname);
- }
- CFRelease(url);
- }
-
- return ret;
+ if (url) {
+ UInt8 pathname[PATH_MAX];
+ if (CFURLGetFileSystemRepresentation(url, true, pathname, PATH_MAX)) {
+ FT_Error error;
+ FT_Face face;
+
+ *index = 0;
+
+ if (!gFreeTypeLibrary) {
+ error = FT_Init_FreeType(&gFreeTypeLibrary);
+ if (error) {
+ fprintf(stderr, "FreeType initialization failed! (%d)\n", error);
+ exit(1);
+ }
+ }
+
+ error = FT_New_Face(gFreeTypeLibrary, (char *) pathname, 0, &face);
+ if (!error) {
+ if (face->num_faces > 1) {
+ int num_faces = face->num_faces;
+ char *ps_name1 = getNameFromCTFont(ctFontRef, kCTFontPostScriptNameKey);
+ int i;
+ *index = -1;
+ FT_Done_Face (face);
+ for (i = 0; i < num_faces; i++) {
+ error = FT_New_Face (gFreeTypeLibrary, (char *) pathname, i, &face);
+ if (!error) {
+ const char *ps_name2 = FT_Get_Postscript_Name(face);
+ if (strcmp(ps_name1, ps_name2) == 0) {
+ *index = i;
+ break;
+ }
+ FT_Done_Face (face);
+ }
+ }
+ free(ps_name1);
+ }
+ }
+
+ if (*index != -1)
+ ret = strdup((char *) pathname);
+ }
+ CFRelease(url);
+ }
+
+ return ret;
}
CFDictionaryRef
findDictionaryInArrayWithIdentifier(CFArrayRef array, const void* identifierKey, int identifier)
{
- CFDictionaryRef dict = NULL;
-
- if (array) {
- int value = -1;
- CFIndex i;
- for (i = 0; i < CFArrayGetCount(array); i++) {
- CFDictionaryRef item = CFArrayGetValueAtIndex(array, i);
- CFNumberRef itemId = CFDictionaryGetValue(item, identifierKey);
- if (itemId) {
- CFNumberGetValue(itemId, kCFNumberIntType, &value);
- if (value == identifier) {
- dict = item;
- break;
- }
- }
- }
- }
- return dict;
+ CFDictionaryRef dict = NULL;
+
+ if (array) {
+ int value = -1;
+ CFIndex i;
+ for (i = 0; i < CFArrayGetCount(array); i++) {
+ CFDictionaryRef item = CFArrayGetValueAtIndex(array, i);
+ CFNumberRef itemId = CFDictionaryGetValue(item, identifierKey);
+ if (itemId) {
+ CFNumberGetValue(itemId, kCFNumberIntType, &value);
+ if (value == identifier) {
+ dict = item;
+ break;
+ }
+ }
+ }
+ }
+ return dict;
}
CFDictionaryRef
findDictionaryInArray(CFArrayRef array, const void* nameKey, const char* name, int nameLength)
{
- CFDictionaryRef dict = NULL;
-
- if (array) {
- CFStringRef itemName;
- CFIndex i;
- itemName = CFStringCreateWithBytes(NULL, (UInt8 *) name, nameLength,
- kCFStringEncodingUTF8, false);
- for (i = 0; i < CFArrayGetCount(array); i++) {
- CFDictionaryRef item = CFArrayGetValueAtIndex(array, i);
- CFStringRef iName = CFDictionaryGetValue(item, nameKey);
- if (iName && !CFStringCompare(itemName, iName, kCFCompareCaseInsensitive)) {
- dict = item;
- break;
- }
- }
- CFRelease(itemName);
- }
- return dict;
+ CFDictionaryRef dict = NULL;
+
+ if (array) {
+ CFStringRef itemName;
+ CFIndex i;
+ itemName = CFStringCreateWithBytes(NULL, (UInt8 *) name, nameLength,
+ kCFStringEncodingUTF8, false);
+ for (i = 0; i < CFArrayGetCount(array); i++) {
+ CFDictionaryRef item = CFArrayGetValueAtIndex(array, i);
+ CFStringRef iName = CFDictionaryGetValue(item, nameKey);
+ if (iName && !CFStringCompare(itemName, iName, kCFCompareCaseInsensitive)) {
+ dict = item;
+ break;
+ }
+ }
+ CFRelease(itemName);
+ }
+ return dict;
}
CFNumberRef
findSelectorByName(CFDictionaryRef feature, const char* name, int nameLength)
{
- CFNumberRef selector = NULL;
- CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
- if (selectors) {
- CFDictionaryRef s = findDictionaryInArray(selectors, kCTFontFeatureSelectorNameKey, name, nameLength);
- if (s)
- selector = CFDictionaryGetValue(s, kCTFontFeatureSelectorIdentifierKey);
- }
- return selector;
+ CFNumberRef selector = NULL;
+ CFArrayRef selectors = CFDictionaryGetValue(feature, kCTFontFeatureTypeSelectorsKey);
+ if (selectors) {
+ CFDictionaryRef s = findDictionaryInArray(selectors, kCTFontFeatureSelectorNameKey, name, nameLength);
+ if (s)
+ selector = CFDictionaryGetValue(s, kCTFontFeatureSelectorIdentifierKey);
+ }
+ return selector;
}
static CFDictionaryRef
createFeatureSettingDictionary(CFNumberRef featureTypeIdentifier, CFNumberRef featureSelectorIdentifier)
{
- const void* settingKeys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatureSelectorIdentifierKey };
- const void* settingValues[] = { featureTypeIdentifier, featureSelectorIdentifier };
+ const void* settingKeys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatureSelectorIdentifierKey };
+ const void* settingValues[] = { featureTypeIdentifier, featureSelectorIdentifier };
- return CFDictionaryCreate(kCFAllocatorDefault, settingKeys, settingValues, 2,
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ return CFDictionaryCreate(kCFAllocatorDefault, settingKeys, settingValues, 2,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
}
const CFStringRef kXeTeXEmboldenAttributeName = CFSTR("XeTeXEmbolden");
@@ -545,385 +546,260 @@ const CFStringRef kXeTeXEmboldenAttributeName = CFSTR("XeTeXEmbolden");
void*
loadAATfont(CTFontDescriptorRef descriptor, integer scaled_size, const char* cp1)
{
- CTFontRef font, actualFont;
- CGFloat ctSize;
- CFMutableDictionaryRef stringAttributes, attributes;
- CGAffineTransform matrix;
- CFMutableArrayRef cascadeList;
- CTFontDescriptorRef lastResort;
- double tracking = 0.0;
- float extend = 1.0;
- float slant = 0.0;
- float embolden = 0.0;
- float letterspace = 0.0;
- uint32_t rgbValue;
-
- // create a base font instance for applying further attributes
- ctSize = TeXtoPSPoints(Fix2D(scaled_size));
- font = CTFontCreateWithFontDescriptor(descriptor, ctSize, NULL);
- if (!font)
- return NULL;
-
- stringAttributes = CFDictionaryCreateMutable(NULL, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- attributes = CFDictionaryCreateMutable(NULL, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- if (cp1) {
- CFArrayRef features = CTFontCopyFeatures(font);
- CFArrayRef axes = CTFontCopyVariationAxes(font);
- CFMutableArrayRef featureSettings =
- CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- CFMutableDictionaryRef variation =
- CFDictionaryCreateMutable(NULL, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- // interpret features & variations following ":"
- while (*cp1) {
- CFDictionaryRef feature, axis;
- int ret;
- const char* cp2;
- const char* cp3;
- // locate beginning of name=value pair
- if (*cp1 == ':' || *cp1 == ';') // skip over separator
- ++cp1;
- while (*cp1 == ' ' || *cp1 == '\t') // skip leading whitespace
- ++cp1;
- if (*cp1 == 0) // break if end of string
- break;
-
- // scan to end of pair
- cp2 = cp1;
- while (*cp2 && (*cp2 != ';') && (*cp2 != ':'))
- ++cp2;
-
- // look for the '=' separator
- cp3 = cp1;
- while ((cp3 < cp2) && (*cp3 != '='))
- ++cp3;
- if (cp3 == cp2)
- goto bad_option;
-
- // now cp1 points to option name, cp3 to '=', cp2 to ';' or null
-
- // first try for a feature by this name
- feature = findDictionaryInArray(features, kCTFontFeatureTypeNameKey, cp1, cp3 - cp1);
- if (feature) {
- // look past the '=' separator for setting names
- int featLen = cp3 - cp1;
- int zeroInteger = 0;
- CFNumberRef zero = CFNumberCreate(NULL, kCFNumberIntType, &zeroInteger);
- ++cp3;
- while (cp3 < cp2) {
- CFNumberRef selector;
- int disable = 0;
- const char* cp4;
- // skip leading whitespace
- while (*cp3 == ' ' || *cp3 == '\t')
- ++cp3;
-
- // possibly multiple settings...
- if (*cp3 == '!') { // check for negation
- disable = 1;
- ++cp3;
- }
-
- // scan for end of setting name
- cp4 = cp3;
- while (cp4 < cp2 && *cp4 != ',')
- ++cp4;
-
- // now cp3 points to name, cp4 to ',' or ';' or null
- selector = findSelectorByName(feature, cp3, cp4 - cp3);
- if (selector && CFNumberCompare(selector, zero, NULL) >= 0) {
- CFNumberRef featureType = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey);
- CFDictionaryRef featureSetting = createFeatureSettingDictionary(featureType, selector);
- CFArrayAppendValue(featureSettings, featureSetting);
- CFRelease(featureSetting);
- } else {
- fontfeaturewarning(cp1, featLen, cp3, cp4 - cp3);
- }
-
- // point beyond setting name terminator
- cp3 = cp4 + 1;
- }
- CFRelease(zero);
-
- goto next_option;
- }
-
- // try to find a variation by this name
- axis = findDictionaryInArray(axes, kCTFontVariationAxisNameKey, cp1, cp3 - cp1);
- if (axis) {
- CFNumberRef axisIdentifier, axisValue;
- double value = 0.0, decimal = 1.0;
- bool negate = false;
- // look past the '=' separator for the value
- ++cp3;
- if (*cp3 == '-') {
- ++cp3;
- negate = true;
- }
- while (cp3 < cp2) {
- int v = *cp3 - '0';
- if (v >= 0 && v <= 9) {
- if (decimal != 1.0) {
- value += v / decimal;
- decimal *= 10.0;
- } else {
- value = value * 10.0 + v;
- }
- } else if (*cp3 == '.') {
- if (decimal != 1.0)
- break;
- decimal = 10.0;
- } else {
- break;
- }
- ++cp3;
- }
- if (negate)
- value = -value;
-
- axisIdentifier = CFDictionaryGetValue(axis, kCTFontVariationAxisIdentifierKey);
- axisValue = CFNumberCreate(NULL, kCFNumberDoubleType, &value);
- CFDictionaryAddValue(variation, axisIdentifier, axisValue);
- CFRelease(axisValue);
-
- goto next_option;
- }
-
- // didn't find feature or variation, try other options...
- ret = readCommonFeatures(cp1, cp2, &extend, &slant, &embolden, &letterspace, &rgbValue);
- if (ret == 1)
- goto next_option;
- else if (ret == -1)
- goto bad_option;
-
- if (strncmp(cp1, "tracking", 8) == 0) {
- CFNumberRef trackingNumber;
- cp3 = cp1 + 8;
- if (*cp3 != '=')
- goto bad_option;
- ++cp3;
- tracking = read_double(&cp3);
- trackingNumber = CFNumberCreate(NULL, kCFNumberDoubleType, &tracking);
- CFDictionaryAddValue(stringAttributes, kCTKernAttributeName, trackingNumber);
- CFRelease(trackingNumber);
- goto next_option;
- }
-
- bad_option:
- // not a name=value pair, or not recognized....
- // check for plain "vertical" before complaining
- if (strncmp(cp1, "vertical", 8) == 0) {
- cp3 = cp2;
- if (*cp3 == ';' || *cp3 == ':')
- --cp3;
- while (*cp3 == '\0' || *cp3 == ' ' || *cp3 == '\t')
- --cp3;
- if (*cp3)
- ++cp3;
- if (cp3 == cp1 + 8) {
- int orientation = kCTFontVerticalOrientation;
- CFNumberRef orientationNumber = CFNumberCreate(NULL, kCFNumberIntType, &orientation);
- CFDictionaryAddValue(attributes, kCTFontOrientationAttribute, orientationNumber);
- CFRelease(orientationNumber);
- CFDictionaryAddValue(stringAttributes, kCTVerticalFormsAttributeName, kCFBooleanTrue);
- goto next_option;
- }
- }
-
- fontfeaturewarning(cp1, cp2 - cp1, 0, 0);
-
- next_option:
- // go to next name=value pair
- cp1 = cp2;
- }
-
- if (features)
- CFRelease(features);
- if (axes)
- CFRelease(axes);
-
- if (CFArrayGetCount(featureSettings))
- CFDictionaryAddValue(attributes, kCTFontFeatureSettingsAttribute, featureSettings);
- CFRelease(featureSettings);
-
- if (CFDictionaryGetCount(variation))
- CFDictionaryAddValue(attributes, kCTFontVariationAttribute, variation);
- CFRelease(variation);
- }
-
- if ((loadedfontflags & FONT_FLAGS_COLORED) != 0) {
- CGFloat red = ((rgbValue & 0xFF000000) >> 24) / 255.0;
- CGFloat green = ((rgbValue & 0x00FF0000) >> 16) / 255.0;
- CGFloat blue = ((rgbValue & 0x0000FF00) >> 8 ) / 255.0;
- CGFloat alpha = ((rgbValue & 0x000000FF) ) / 255.0;
- CGColorRef color = CGColorCreateGenericRGB(red, green, blue, alpha);
- CFDictionaryAddValue(stringAttributes, kCTForegroundColorAttributeName, color);
- CGColorRelease(color);
- }
-
- matrix = CGAffineTransformIdentity;
- // XXX this breaks y glyph positioning
- if (extend != 1.0 || slant != 0.0)
- matrix = CGAffineTransformMake(extend, slant, 0, 1.0, 0, 0);
-
- if (embolden != 0.0) {
- CFNumberRef emboldenNumber;
- embolden = embolden * Fix2D(scaled_size) / 100.0;
- emboldenNumber = CFNumberCreate(NULL, kCFNumberFloatType, &embolden);
- CFDictionaryAddValue(stringAttributes, kXeTeXEmboldenAttributeName, emboldenNumber);
- CFRelease(emboldenNumber);
- }
-
- if (letterspace != 0.0)
- loadedfontletterspace = (letterspace / 100.0) * scaled_size;
-
- // Disable Core Text font fallback (cascading) with only the last resort font
- // in the cascade list.
- cascadeList = CFArrayCreateMutable(NULL, 1, &kCFTypeArrayCallBacks);
- lastResort = CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0);
- CFArrayAppendValue(cascadeList, lastResort);
- CFRelease(lastResort);
- CFDictionaryAddValue(attributes, kCTFontCascadeListAttribute, cascadeList);
- CFRelease(cascadeList);
-
- descriptor = CTFontDescriptorCreateWithAttributes(attributes);
- CFRelease(attributes);
- actualFont = CTFontCreateCopyWithAttributes(font, ctSize, &matrix, descriptor);
- CFRelease(font);
- CFDictionaryAddValue(stringAttributes, kCTFontAttributeName, actualFont);
- CFRelease(actualFont);
-
- nativefonttypeflag = AAT_FONT_FLAG;
- return (void *) stringAttributes;
-}
-
-int
-countpdffilepages()
-{
- int rval = 0;
-
- char* pic_path = kpse_find_file((char*)nameoffile + 1, kpse_pict_format, 1);
- CFURLRef picFileURL = NULL;
- if (pic_path) {
- picFileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8*)pic_path, strlen(pic_path), false);
- if (picFileURL != NULL) {
- FSRef picFileRef;
- CGPDFDocumentRef document;
- CFURLGetFSRef(picFileURL, &picFileRef);
- document = CGPDFDocumentCreateWithURL(picFileURL);
- if (document != NULL) {
- rval = CGPDFDocumentGetNumberOfPages(document);
- CGPDFDocumentRelease(document);
- }
- CFRelease(picFileURL);
- }
- free(pic_path);
- }
-
- return rval;
-}
-
-int
-find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page)
- /* returns bounds in TeX points */
-{
- OSStatus result = fnfErr;
- char* pic_path = kpse_find_file((char*)nameoffile + 1, kpse_pict_format, 1);
- CFURLRef picFileURL = NULL;
-
- *path = NULL;
-
- if (pic_path) {
- picFileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8*)pic_path, strlen(pic_path), false);
-
- if (picFileURL != NULL) {
- if (pdfBoxType > 0) {
- CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(picFileURL);
- if (document != NULL) {
- CGPDFPageRef pageRef;
- CGRect r;
- CGPDFBox boxType;
- int nPages = CGPDFDocumentGetNumberOfPages(document);
- if (page < 0)
- page = nPages + 1 + page;
- if (page < 1)
- page = 1;
- if (page > nPages)
- page = nPages;
-
- pageRef = CGPDFDocumentGetPage(document, page);
- switch (pdfBoxType) {
- case pdfbox_crop:
- default:
- boxType = kCGPDFCropBox;
- break;
- case pdfbox_media:
- boxType = kCGPDFMediaBox;
- break;
- case pdfbox_bleed:
- boxType = kCGPDFBleedBox;
- break;
- case pdfbox_trim:
- boxType = kCGPDFTrimBox;
- break;
- case pdfbox_art:
- boxType = kCGPDFArtBox;
- break;
- }
- r = CGPDFPageGetBoxRect(pageRef, boxType);
-
- bounds->x = r.origin.x * 72.27 / 72.0;
- bounds->y = r.origin.y * 72.27 / 72.0;
- bounds->wd = r.size.width * 72.27 / 72.0;
- bounds->ht = r.size.height * 72.27 / 72.0;
- CGPDFDocumentRelease(document);
- result = noErr;
- }
- } else {
- CGImageSourceRef picFileSource = CGImageSourceCreateWithURL(picFileURL, NULL);
- if (picFileSource) {
- CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(picFileSource, 0, NULL);
-
- CFNumberRef imageWidth = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth);
- CFNumberRef imageHeight = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight);
- CFNumberRef DPIWidth = CFDictionaryGetValue(properties, kCGImagePropertyDPIWidth);
- CFNumberRef DPIHeight = CFDictionaryGetValue(properties, kCGImagePropertyDPIHeight);
-
- if (imageWidth && imageHeight) {
- int w = 0, h = 0, hRes = 72, vRes = 72;
- CFNumberGetValue(imageWidth, kCFNumberIntType, &w);
- CFNumberGetValue(imageHeight, kCFNumberIntType, &h);
- if (DPIWidth)
- CFNumberGetValue(DPIWidth, kCFNumberIntType, &hRes);
- if (DPIHeight)
- CFNumberGetValue(DPIHeight, kCFNumberIntType, &vRes);
-
- bounds->x = 0;
- bounds->y = 0;
- bounds->wd = w * 72.27 / hRes;
- bounds->ht = h * 72.27 / vRes;
- CFRelease(properties);
- CFRelease(picFileSource);
- result = noErr;
- }
- }
- }
-
- CFRelease(picFileURL);
- }
-
- /* if we couldn't import it, toss the pathname as we'll be returning an error */
- if (result != noErr)
- free(pic_path);
- else
- *path = (char*)pic_path;
- }
-
- return result;
+ CTFontRef font, actualFont;
+ CGFloat ctSize;
+ CFMutableDictionaryRef stringAttributes, attributes;
+ CGAffineTransform matrix;
+ CFMutableArrayRef cascadeList;
+ CTFontDescriptorRef lastResort;
+ double tracking = 0.0;
+ float extend = 1.0;
+ float slant = 0.0;
+ float embolden = 0.0;
+ float letterspace = 0.0;
+ uint32_t rgbValue;
+
+ // create a base font instance for applying further attributes
+ ctSize = TeXtoPSPoints(Fix2D(scaled_size));
+ font = CTFontCreateWithFontDescriptor(descriptor, ctSize, NULL);
+ if (!font)
+ return NULL;
+
+ stringAttributes = CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ attributes = CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (cp1) {
+ CFArrayRef features = CTFontCopyFeatures(font);
+ CFArrayRef axes = CTFontCopyVariationAxes(font);
+ CFMutableArrayRef featureSettings =
+ CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ CFMutableDictionaryRef variation =
+ CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ // interpret features & variations following ":"
+ while (*cp1) {
+ CFDictionaryRef feature, axis;
+ int ret;
+ const char* cp2;
+ const char* cp3;
+ // locate beginning of name=value pair
+ if (*cp1 == ':' || *cp1 == ';') // skip over separator
+ ++cp1;
+ while (*cp1 == ' ' || *cp1 == '\t') // skip leading whitespace
+ ++cp1;
+ if (*cp1 == 0) // break if end of string
+ break;
+
+ // scan to end of pair
+ cp2 = cp1;
+ while (*cp2 && (*cp2 != ';') && (*cp2 != ':'))
+ ++cp2;
+
+ // look for the '=' separator
+ cp3 = cp1;
+ while ((cp3 < cp2) && (*cp3 != '='))
+ ++cp3;
+ if (cp3 == cp2)
+ goto bad_option;
+
+ // now cp1 points to option name, cp3 to '=', cp2 to ';' or null
+
+ // first try for a feature by this name
+ feature = findDictionaryInArray(features, kCTFontFeatureTypeNameKey, cp1, cp3 - cp1);
+ if (feature) {
+ // look past the '=' separator for setting names
+ int featLen = cp3 - cp1;
+ int zeroInteger = 0;
+ CFNumberRef zero = CFNumberCreate(NULL, kCFNumberIntType, &zeroInteger);
+ ++cp3;
+ while (cp3 < cp2) {
+ CFNumberRef selector;
+ int disable = 0;
+ const char* cp4;
+ // skip leading whitespace
+ while (*cp3 == ' ' || *cp3 == '\t')
+ ++cp3;
+
+ // possibly multiple settings...
+ if (*cp3 == '!') { // check for negation
+ disable = 1;
+ ++cp3;
+ }
+
+ // scan for end of setting name
+ cp4 = cp3;
+ while (cp4 < cp2 && *cp4 != ',')
+ ++cp4;
+
+ // now cp3 points to name, cp4 to ',' or ';' or null
+ selector = findSelectorByName(feature, cp3, cp4 - cp3);
+ if (selector && CFNumberCompare(selector, zero, NULL) >= 0) {
+ CFNumberRef featureType = CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey);
+ CFDictionaryRef featureSetting = createFeatureSettingDictionary(featureType, selector);
+ CFArrayAppendValue(featureSettings, featureSetting);
+ CFRelease(featureSetting);
+ } else {
+ fontfeaturewarning(cp1, featLen, cp3, cp4 - cp3);
+ }
+
+ // point beyond setting name terminator
+ cp3 = cp4 + 1;
+ }
+ CFRelease(zero);
+
+ goto next_option;
+ }
+
+ // try to find a variation by this name
+ axis = findDictionaryInArray(axes, kCTFontVariationAxisNameKey, cp1, cp3 - cp1);
+ if (axis) {
+ CFNumberRef axisIdentifier, axisValue;
+ double value = 0.0, decimal = 1.0;
+ bool negate = false;
+ // look past the '=' separator for the value
+ ++cp3;
+ if (*cp3 == '-') {
+ ++cp3;
+ negate = true;
+ }
+ while (cp3 < cp2) {
+ int v = *cp3 - '0';
+ if (v >= 0 && v <= 9) {
+ if (decimal != 1.0) {
+ value += v / decimal;
+ decimal *= 10.0;
+ } else {
+ value = value * 10.0 + v;
+ }
+ } else if (*cp3 == '.') {
+ if (decimal != 1.0)
+ break;
+ decimal = 10.0;
+ } else {
+ break;
+ }
+ ++cp3;
+ }
+ if (negate)
+ value = -value;
+
+ axisIdentifier = CFDictionaryGetValue(axis, kCTFontVariationAxisIdentifierKey);
+ axisValue = CFNumberCreate(NULL, kCFNumberDoubleType, &value);
+ CFDictionaryAddValue(variation, axisIdentifier, axisValue);
+ CFRelease(axisValue);
+
+ goto next_option;
+ }
+
+ // didn't find feature or variation, try other options...
+ ret = readCommonFeatures(cp1, cp2, &extend, &slant, &embolden, &letterspace, &rgbValue);
+ if (ret == 1)
+ goto next_option;
+ else if (ret == -1)
+ goto bad_option;
+
+ if (strncmp(cp1, "tracking", 8) == 0) {
+ CFNumberRef trackingNumber;
+ cp3 = cp1 + 8;
+ if (*cp3 != '=')
+ goto bad_option;
+ ++cp3;
+ tracking = read_double(&cp3);
+ trackingNumber = CFNumberCreate(NULL, kCFNumberDoubleType, &tracking);
+ CFDictionaryAddValue(stringAttributes, kCTKernAttributeName, trackingNumber);
+ CFRelease(trackingNumber);
+ goto next_option;
+ }
+
+ bad_option:
+ // not a name=value pair, or not recognized....
+ // check for plain "vertical" before complaining
+ if (strncmp(cp1, "vertical", 8) == 0) {
+ cp3 = cp2;
+ if (*cp3 == ';' || *cp3 == ':')
+ --cp3;
+ while (*cp3 == '\0' || *cp3 == ' ' || *cp3 == '\t')
+ --cp3;
+ if (*cp3)
+ ++cp3;
+ if (cp3 == cp1 + 8) {
+ int orientation = kCTFontVerticalOrientation;
+ CFNumberRef orientationNumber = CFNumberCreate(NULL, kCFNumberIntType, &orientation);
+ CFDictionaryAddValue(attributes, kCTFontOrientationAttribute, orientationNumber);
+ CFRelease(orientationNumber);
+ CFDictionaryAddValue(stringAttributes, kCTVerticalFormsAttributeName, kCFBooleanTrue);
+ goto next_option;
+ }
+ }
+
+ fontfeaturewarning(cp1, cp2 - cp1, 0, 0);
+
+ next_option:
+ // go to next name=value pair
+ cp1 = cp2;
+ }
+
+ if (features)
+ CFRelease(features);
+ if (axes)
+ CFRelease(axes);
+
+ if (CFArrayGetCount(featureSettings))
+ CFDictionaryAddValue(attributes, kCTFontFeatureSettingsAttribute, featureSettings);
+ CFRelease(featureSettings);
+
+ if (CFDictionaryGetCount(variation))
+ CFDictionaryAddValue(attributes, kCTFontVariationAttribute, variation);
+ CFRelease(variation);
+ }
+
+ if ((loadedfontflags & FONT_FLAGS_COLORED) != 0) {
+ CGFloat red = ((rgbValue & 0xFF000000) >> 24) / 255.0;
+ CGFloat green = ((rgbValue & 0x00FF0000) >> 16) / 255.0;
+ CGFloat blue = ((rgbValue & 0x0000FF00) >> 8 ) / 255.0;
+ CGFloat alpha = ((rgbValue & 0x000000FF) ) / 255.0;
+ CGColorRef color = CGColorCreateGenericRGB(red, green, blue, alpha);
+ CFDictionaryAddValue(stringAttributes, kCTForegroundColorAttributeName, color);
+ CGColorRelease(color);
+ }
+
+ matrix = CGAffineTransformIdentity;
+ // XXX this breaks y glyph positioning
+ if (extend != 1.0 || slant != 0.0)
+ matrix = CGAffineTransformMake(extend, slant, 0, 1.0, 0, 0);
+
+ if (embolden != 0.0) {
+ CFNumberRef emboldenNumber;
+ embolden = embolden * Fix2D(scaled_size) / 100.0;
+ emboldenNumber = CFNumberCreate(NULL, kCFNumberFloatType, &embolden);
+ CFDictionaryAddValue(stringAttributes, kXeTeXEmboldenAttributeName, emboldenNumber);
+ CFRelease(emboldenNumber);
+ }
+
+ if (letterspace != 0.0)
+ loadedfontletterspace = (letterspace / 100.0) * scaled_size;
+
+ // Disable Core Text font fallback (cascading) with only the last resort font
+ // in the cascade list.
+ cascadeList = CFArrayCreateMutable(NULL, 1, &kCFTypeArrayCallBacks);
+ lastResort = CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0);
+ CFArrayAppendValue(cascadeList, lastResort);
+ CFRelease(lastResort);
+ CFDictionaryAddValue(attributes, kCTFontCascadeListAttribute, cascadeList);
+ CFRelease(cascadeList);
+
+ descriptor = CTFontDescriptorCreateWithAttributes(attributes);
+ CFRelease(attributes);
+ actualFont = CTFontCreateCopyWithAttributes(font, ctSize, &matrix, descriptor);
+ CFRelease(font);
+ CFDictionaryAddValue(stringAttributes, kCTFontAttributeName, actualFont);
+ CFRelease(actualFont);
+
+ nativefonttypeflag = AAT_FONT_FLAG;
+ return (void *) stringAttributes;
}
diff --git a/Build/source/texk/web2c/xetexdir/XeTeX_pic.c b/Build/source/texk/web2c/xetexdir/XeTeX_pic.c
index ff4266be280..92233654232 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeX_pic.c
+++ b/Build/source/texk/web2c/xetexdir/XeTeX_pic.c
@@ -33,7 +33,6 @@ authorization from the copyright holders.
/*
XeTeX_pic.c
interface between xetex and graphics files
- (not used on OS X -- we use ImageIO graphics importers instead)
only needs to get image dimensions, not actually load/process the file
*/
@@ -110,7 +109,7 @@ find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page)
}
goto done;
}
-
+
if (check_for_bmp(fp)) {
struct bmp_info info;
err = bmp_scan_file(&info, fp);
@@ -120,7 +119,7 @@ find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page)
}
goto done;
}
-
+
if (check_for_png(fp)) {
struct png_info info;
err = png_scan_file(&info, fp);
@@ -129,10 +128,10 @@ find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page)
bounds->ht = (info.height * 72.27) / info.ydpi;
}
goto done;
- }
+ }
/* could support other file types here (TIFF, WMF, etc?) */
-
+
done:
if (fp != NULL)
fclose(fp);
@@ -143,6 +142,6 @@ done:
if (pic_path != NULL)
free(pic_path);
}
-
+
return err;
}
diff --git a/Build/source/texk/web2c/xetexdir/am/xetex.am b/Build/source/texk/web2c/xetexdir/am/xetex.am
index ef7683209c7..4bdc8b63e5c 100644
--- a/Build/source/texk/web2c/xetexdir/am/xetex.am
+++ b/Build/source/texk/web2c/xetexdir/am/xetex.am
@@ -26,9 +26,28 @@ xetex_cppflags += $(FREETYPE2_INCLUDES)
xetex_cppflags += $(TECKIT_INCLUDES)
xetex_cppflags += $(HARFBUZZ_INCLUDES)
xetex_cppflags += $(GRAPHITE2_INCLUDES)
-xetex_ldadd = $(libxetex) $(HARFBUZZ_LIBS) $(GRAPHITE2_LIBS) $(ICU_LIBS) $(TECKIT_LIBS)
-xetex_dependencies = $(proglib) $(KPATHSEA_DEPEND)
-xetex_dependencies += $(ICU_DEPEND) $(TECKIT_DEPEND) $(HARFBUZZ_DEPEND) $(GRAPHITE2_DEPEND)
+xetex_cppflags += $(POPPLER_INCLUDES)
+xetex_cppflags += $(LIBPNG_INCLUDES)
+xetex_cppflags += $(ZLIB_INCLUDES)
+xetex_ldadd = $(libxetex)
+xetex_ldadd += $(HARFBUZZ_LIBS)
+xetex_ldadd += $(GRAPHITE2_LIBS)
+xetex_ldadd += $(ICU_LIBS)
+xetex_ldadd += $(TECKIT_LIBS)
+xetex_ldadd += $(POPPLER_LIBS)
+xetex_ldadd += $(LIBPNG_LIBS)
+xetex_ldadd += $(FREETYPE2_LIBS)
+xetex_ldadd += $(ZLIB_LIBS)
+xetex_dependencies = $(proglib)
+xetex_dependencies += $(KPATHSEA_DEPEND)
+xetex_dependencies += $(ICU_DEPEND)
+xetex_dependencies += $(TECKIT_DEPEND)
+xetex_dependencies += $(HARFBUZZ_DEPEND)
+xetex_dependencies += $(GRAPHITE2_DEPEND)
+xetex_dependencies += $(POPPLER_DEPEND)
+xetex_dependencies += $(LIBPNG_DEPEND)
+xetex_dependencies += $(FREETYPE2_DEPEND)
+xetex_dependencies += $(ZLIB_DEPEND)
if XETEX_MACOSX
@@ -37,16 +56,11 @@ xetex_LDFLAGS = -framework ApplicationServices -framework Cocoa
else !XETEX_MACOSX
-xetex_cppflags += -DXETEX_OTHER
-xetex_cppflags += $(POPPLER_INCLUDES) $(LIBPNG_INCLUDES) $(FONTCONFIG_INCLUDES)
-xetex_ldadd += $(POPPLER_LIBS) $(LIBPNG_LIBS) $(FONTCONFIG_LIBS)
-xetex_dependencies += $(POPPLER_DEPEND) $(LIBPNG_DEPEND)
+xetex_cppflags += $(FONTCONFIG_INCLUDES)
+xetex_ldadd += $(FONTCONFIG_LIBS)
endif !XETEX_MACOSX
-xetex_cppflags += $(ZLIB_INCLUDES)
-xetex_ldadd += $(FREETYPE2_LIBS) $(ZLIB_LIBS)
-xetex_dependencies += $(FREETYPE2_DEPEND) $(ZLIB_DEPEND)
xetex_CPPFLAGS = $(xetex_cppflags)
xetex_CFLAGS = # $(WARNING_CFLAGS)
@@ -107,8 +121,6 @@ EXTRA_DIST += $(xetex_web_srcs) $(xetex_ch_srcs) xetexdir/xetex.defines
DISTCLEANFILES += $(nodist_xetex_SOURCES) xetex.web xetex.ch xetex-web2c \
xetex.p xetex.pool xetex-tangle
-EXTRA_DIST += \
- xetexdir/unicode-char-prep.pl
## libxetex
##
@@ -131,11 +143,24 @@ libxetex_a_SOURCES = \
xetexdir/XeTeXOTMath.h \
xetexdir/XeTeX_ext.c \
xetexdir/XeTeX_ext.h \
+ xetexdir/XeTeX_pic.c \
xetexdir/XeTeXswap.h \
xetexdir/trans.c \
xetexdir/trans.h \
xetexdir/hz.cpp \
- xetexdir/xetex.h
+ xetexdir/xetex.h \
+ xetexdir/pdfimage.cpp \
+ xetexdir/pdfimage.h \
+ xetexdir/image/bmpimage.c \
+ xetexdir/image/bmpimage.h \
+ xetexdir/image/jpegimage.c \
+ xetexdir/image/jpegimage.h \
+ xetexdir/image/mfileio.c \
+ xetexdir/image/mfileio.h \
+ xetexdir/image/numbers.c \
+ xetexdir/image/numbers.h \
+ xetexdir/image/pngimage.c \
+ xetexdir/image/pngimage.h
if XETEX_MACOSX
@@ -150,20 +175,7 @@ else !XETEX_MACOSX
libxetex_a_SOURCES += \
xetexdir/XeTeXFontMgr_FC.cpp \
- xetexdir/XeTeXFontMgr_FC.h \
- xetexdir/XeTeX_pic.c \
- xetexdir/pdfimage.cpp \
- xetexdir/pdfimage.h \
- xetexdir/image/bmpimage.c \
- xetexdir/image/bmpimage.h \
- xetexdir/image/jpegimage.c \
- xetexdir/image/jpegimage.h \
- xetexdir/image/mfileio.c \
- xetexdir/image/mfileio.h \
- xetexdir/image/numbers.c \
- xetexdir/image/numbers.h \
- xetexdir/image/pngimage.c \
- xetexdir/image/pngimage.h
+ xetexdir/XeTeXFontMgr_FC.h
endif !XETEX_MACOSX
@@ -171,7 +183,6 @@ endif !XETEX_MACOSX
libxetex_prereq = xetexd.h $(xetex_dependencies)
$(libxetex_a_OBJECTS): $(libxetex_prereq)
-EXTRA_DIST += xetexdir/ChangeLog
# XeTeX Tests
#
@@ -183,9 +194,9 @@ if XETEX
TESTS += $(xetex_tests)
endif XETEX
-## Not used
-##
EXTRA_DIST += \
+ xetexdir/unicode-char-prep.pl \
+ xetexdir/ChangeLog \
xetexdir/COPYING \
xetexdir/NEWS \
xetexdir/image/README \
diff --git a/Build/source/texk/web2c/xetexdir/pdfimage.cpp b/Build/source/texk/web2c/xetexdir/pdfimage.cpp
index fac84953c5f..a9ccbd02e77 100644
--- a/Build/source/texk/web2c/xetexdir/pdfimage.cpp
+++ b/Build/source/texk/web2c/xetexdir/pdfimage.cpp
@@ -61,19 +61,19 @@ pdf_get_rect(char* filename, int page_num, int pdf_box, realrect* box)
{
GooString* name = new GooString(filename);
PDFDoc* doc = new PDFDoc(name);
-
+
if (!doc) {
delete name;
return -1;
}
-
+
/* if the doc got created, it now owns name, so we mustn't delete it! */
-
+
if (!doc->isOk()) {
delete doc;
return -1;
}
-
+
int pages = doc->getNumPages();
if (page_num > pages)
page_num = pages;
@@ -120,14 +120,14 @@ pdf_count_pages(char* filename)
int pages = 0;
GooString* name = new GooString(filename);
PDFDoc* doc = new PDFDoc(name);
-
+
if (!doc) {
delete name;
return 0;
}
-
+
/* if the doc got created, it now owns name, so we mustn't delete it! */
-
+
if (doc->isOk())
pages = doc->getNumPages();
diff --git a/Build/source/texk/web2c/xetexdir/xetex.ch b/Build/source/texk/web2c/xetexdir/xetex.ch
index 304a3831307..1c389489fc9 100644
--- a/Build/source/texk/web2c/xetexdir/xetex.ch
+++ b/Build/source/texk/web2c/xetexdir/xetex.ch
@@ -277,7 +277,7 @@ if #<>0 then begin
if #<>0 then begin
j:=str_start_macro(#);
while ((not must_quote) or (quote_char=0)) and (j<str_start_macro(#+1)) do begin
- if (str_pool[j]=" ") then must_quote:=true
+ if str_pool[j]=" " then must_quote:=true
else if (str_pool[j]="""") or (str_pool[j]="'") then begin
must_quote:=true;
quote_char:="""" + "'" - str_pool[j];
@@ -773,7 +773,7 @@ var i,@!j,@!k:integer; {all-purpose integers}
@x [53a.1379] l.??? -etex command line switch
incr(loc); eTeX_mode:=1; {enter extended mode}
@y
- if (buffer[loc]="*") then incr(loc);
+ if buffer[loc]="*" then incr(loc);
eTeX_mode:=1; {enter extended mode}
@z
diff --git a/Build/source/texk/web2c/xetexdir/xetex.h b/Build/source/texk/web2c/xetexdir/xetex.h
index 73d8f95502d..bcd5d0cfed8 100644
--- a/Build/source/texk/web2c/xetexdir/xetex.h
+++ b/Build/source/texk/web2c/xetexdir/xetex.h
@@ -32,11 +32,11 @@ authorization from the copyright holders.
/* additional declarations we want to slip in for xetex */
-#define native_node_size 6
-#define native_node_text(p) ((unsigned short*)(&(mem[(p) + native_node_size])))
+#define native_node_size 6
+#define native_node_text(p) ((unsigned short*)(&(mem[(p) + native_node_size])))
-#define getnativechar(p,i) native_node_text(p)[i]
-#define setnativechar(p,i,v) native_node_text(p)[i] = v
+#define getnativechar(p,i) native_node_text(p)[i]
+#define setnativechar(p,i,v) native_node_text(p)[i] = v
#define getnativeusv(p,i) \
((native_node_text(p)[i] >= 0xd800 && native_node_text(p)[i] < 0xdc00) ? \
@@ -44,84 +44,84 @@ authorization from the copyright holders.
native_node_text(p)[i])
/* p is native_word node; g is XeTeX_use_glyph_metrics flag */
-#define setnativemetrics(p,g) measure_native_node(&(mem[p]), g)
+#define setnativemetrics(p,g) measure_native_node(&(mem[p]), g)
-#define setnativeglyphmetrics(p,g) measure_native_glyph(&(mem[p]), g)
+#define setnativeglyphmetrics(p,g) measure_native_glyph(&(mem[p]), g)
-#define setjustifiednativeglyphs(p) store_justified_native_glyphs(&(mem[p]))
+#define setjustifiednativeglyphs(p) store_justified_native_glyphs(&(mem[p]))
-#define getnativeitaliccorrection(p) get_native_italic_correction(&(mem[p]))
-#define getnativeglyphitaliccorrection(p) get_native_glyph_italic_correction(&(mem[p]))
+#define getnativeitaliccorrection(p) get_native_italic_correction(&(mem[p]))
+#define getnativeglyphitaliccorrection(p) get_native_glyph_italic_correction(&(mem[p]))
-#define getnativeglyph(p,i) get_native_glyph(&(mem[p]), i)
+#define getnativeglyph(p,i) get_native_glyph(&(mem[p]), i)
-#define makexdvglypharraydata(p) makeXDVGlyphArrayData(&(mem[p]))
-#define xdvbufferbyte(i) xdvbuffer[i]
+#define makexdvglypharraydata(p) makeXDVGlyphArrayData(&(mem[p]))
+#define xdvbufferbyte(i) xdvbuffer[i]
-#define getcpcode get_cp_code
-#define setcpcode set_cp_code
-#define getnativewordcp(p,s) get_native_word_cp(&(mem[p]), s)
+#define getcpcode get_cp_code
+#define setcpcode set_cp_code
+#define getnativewordcp(p,s) get_native_word_cp(&(mem[p]), s)
-#define pic_node_size 8
+#define pic_node_size 8
-#define deref(p) (*(p))
+#define deref(p) (*(p))
-#define findpicfile(a,b,c,d) find_pic_file(a, b, c, d)
+#define findpicfile(a,b,c,d) find_pic_file(a, b, c, d)
-#define picpathbyte(p,i) ((unsigned char*)&(mem[p+pic_node_size]))[i]
+#define picpathbyte(p,i) ((unsigned char*)&(mem[p+pic_node_size]))[i]
-#define dviopenout(f) open_dvi_output(&(f))
+#define dviopenout(f) open_dvi_output(&(f))
-#define nullptr (NULL)
-#define glyphinfobyte(p,k) ((unsigned char*)p)[k]
-#define casttoushort(x) (unsigned short)(x)
+#define nullptr (NULL)
+#define glyphinfobyte(p,k) ((unsigned char*)p)[k]
+#define casttoushort(x) (unsigned short)(x)
/* easier to do the bit-twiddling here than in Pascal */
/* read fields from a 32-bit math code */
-#define mathfamfield(x) (((unsigned)(x) >> 24) & 0xFF)
-#define mathclassfield(x) (((unsigned)(x) >> 21) & 0x07)
-#define mathcharfield(x) ((unsigned)(x) & 0x1FFFFF)
+#define mathfamfield(x) (((unsigned)(x) >> 24) & 0xFF)
+#define mathclassfield(x) (((unsigned)(x) >> 21) & 0x07)
+#define mathcharfield(x) ((unsigned)(x) & 0x1FFFFF)
/* calculate pieces to assign to a math code */
-#define setfamilyfield(x) (((unsigned)(x) & 0xFF) << 24)
-#define setclassfield(x) (((unsigned)(x) & 0x07) << 21)
+#define setfamilyfield(x) (((unsigned)(x) & 0xFF) << 24)
+#define setclassfield(x) (((unsigned)(x) & 0x07) << 21)
/* aliases */
-#define getnativemathsyparam get_native_mathsy_param
-#define getnativemathexparam get_native_mathex_param
-#define getotmathconstant get_ot_math_constant
-#define getotmathvariant get_ot_math_variant
-#define getotassemblyptr get_ot_assembly_ptr
-#define getotmathitalcorr get_ot_math_ital_corr
-#define getotmathaccentpos get_ot_math_accent_pos
-#define getotmathkern get_ot_math_kern
-#define otpartcount ot_part_count
-#define otpartglyph ot_part_glyph
-#define otpartisextender ot_part_is_extender
-#define otpartstartconnector ot_part_start_connector
-#define otpartendconnector ot_part_end_connector
-#define otpartfulladvance ot_part_full_advance
-#define otminconnectoroverlap ot_min_connector_overlap
+#define getnativemathsyparam get_native_mathsy_param
+#define getnativemathexparam get_native_mathex_param
+#define getotmathconstant get_ot_math_constant
+#define getotmathvariant get_ot_math_variant
+#define getotassemblyptr get_ot_assembly_ptr
+#define getotmathitalcorr get_ot_math_ital_corr
+#define getotmathaccentpos get_ot_math_accent_pos
+#define getotmathkern get_ot_math_kern
+#define otpartcount ot_part_count
+#define otpartglyph ot_part_glyph
+#define otpartisextender ot_part_is_extender
+#define otpartstartconnector ot_part_start_connector
+#define otpartendconnector ot_part_end_connector
+#define otpartfulladvance ot_part_full_advance
+#define otminconnectoroverlap ot_min_connector_overlap
/* prototypes used in xetex.web */
#include "XeTeXOTMath.h"
/* Unicode file reading modes */
-#define AUTO 0 /* default: will become one of 1..3 at file open time, after sniffing */
-#define UTF8 1
-#define UTF16BE 2
-#define UTF16LE 3
-#define RAW 4
-#define ICUMAPPING 5
+#define AUTO 0 /* default: will become one of 1..3 at file open time, after sniffing */
+#define UTF8 1
+#define UTF16BE 2
+#define UTF16LE 3
+#define RAW 4
+#define ICUMAPPING 5
#ifdef WIN32
-#define WIN32CONSOLE 6
+#define WIN32CONSOLE 6
#endif
/* we don't use xchr, so change the cpascal.h definition of this... */
#undef Xchr
-#define Xchr(x) (x)
+#define Xchr(x) (x)
-#include "trans.h" /* functions for affine transform operations */
-#include <teckit/TECkit_Common.h> /* include this before XeTeX_ext.h */
-#include "XeTeX_ext.h" /* other extension functions */
+#include "trans.h" /* functions for affine transform operations */
+#include <teckit/TECkit_Common.h> /* include this before XeTeX_ext.h */
+#include "XeTeX_ext.h" /* other extension functions */
#include <math.h>
/* apparently M_PI isn't defined by <math.h> under VC++ */
diff --git a/Build/source/texk/web2c/xetexdir/xetex.web b/Build/source/texk/web2c/xetexdir/xetex.web
index 63dec34b229..9ad16b235a9 100644
--- a/Build/source/texk/web2c/xetexdir/xetex.web
+++ b/Build/source/texk/web2c/xetexdir/xetex.web
@@ -324,8 +324,8 @@ known as `\eTeX'.
@d eTeX_version_string=='-2.6' {current \eTeX\ version}
@#
@d XeTeX_version=0 { \.{\\XeTeXversion} }
-@d XeTeX_revision==".9999" { \.{\\XeTeXrevision} }
-@d XeTeX_version_string=='-0.9999.3' {current \XeTeX\ version}
+@d XeTeX_revision==".99991" { \.{\\XeTeXrevision} }
+@d XeTeX_version_string=='-0.99991' {current \XeTeX\ version}
@#
@d XeTeX_banner=='This is XeTeX, Version 3.14159265',eTeX_version_string,XeTeX_version_string
{printed when \XeTeX\ starts}
@@ -1676,49 +1676,49 @@ label exit;
var l: small_number;
begin if (selector>pseudo) and (not doing_special) then
{``printing'' to a new string, encode as UTF-16 rather than UTF-8}
- begin if s>=@"10000 then begin
- print_visible_char(@"D800 + (s - @"10000) div @"400);
- print_visible_char(@"DC00 + (s - @"10000) mod @"400);
- end else print_visible_char(s);
- return;
+ begin if s>=@"10000 then
+ begin print_visible_char(@"D800 + (s - @"10000) div @"400);
+ print_visible_char(@"DC00 + (s - @"10000) mod @"400);
+ end else print_visible_char(s);
+ return;
end;
if @<Character |s| is the current new-line character@> then
if selector<pseudo then
begin print_ln; return;
end;
-if (s < 32) and (eight_bit_p = 0) and (not doing_special) then {control char: \.{\^\^X}}
- begin
- print_visible_char("^"); print_visible_char("^"); print_visible_char(s+64);
-end else if s < 127 then
- { printable ASCII }
- print_visible_char(s)
-else if (s = 127) then begin
- { DEL }
- if (eight_bit_p = 0) and (not doing_special) then begin
- print_visible_char("^"); print_visible_char("^"); print_visible_char("?")
- end else
- print_visible_char(s)
-end else if (s < @"A0) and (eight_bit_p = 0) and (not doing_special) then {C1 controls: \.{\^\^xx}}
- begin
- print_visible_char("^"); print_visible_char("^");
- print_lc_hex((s mod @"100) div @"10); print_lc_hex(s mod @"10);
-end else begin
- { |char >= 128|: encode as UTF8 }
- if s<@"800 then begin
- print_raw_char(@"C0 + s div @"40, false);
- print_raw_char(@"80 + s mod @"40, true);
- end
- else if s<@"10000 then begin
- print_raw_char(@"E0 + (s div @"1000), false);
- print_raw_char(@"80 + (s mod @"1000) div @"40, false);
- print_raw_char(@"80 + (s mod @"40), true);
- end else begin
- print_raw_char(@"F0 + (s div @"40000), false);
- print_raw_char(@"80 + (s mod @"40000) div @"1000, false);
- print_raw_char(@"80 + (s mod @"1000) div @"40, false);
- print_raw_char(@"80 + (s mod @"40), true);
- end
-end;
+ if (s < 32) and (eight_bit_p = 0) and (not doing_special) then {control char: \.{\^\^X}}
+ begin print_visible_char("^"); print_visible_char("^"); print_visible_char(s+64);
+ end
+ else if s<127 then { printable ASCII }
+ print_visible_char(s)
+ else if s=127 then { DEL }
+ begin if (eight_bit_p = 0) and (not doing_special) then
+ begin print_visible_char("^"); print_visible_char("^"); print_visible_char("?")
+ end else
+ print_visible_char(s)
+ end
+ else if (s < @"A0) and (eight_bit_p = 0) and (not doing_special) then {C1 controls: \.{\^\^xx}}
+ begin print_visible_char("^"); print_visible_char("^");
+ print_lc_hex((s mod @"100) div @"10); print_lc_hex(s mod @"10);
+ end
+ else begin
+ { |char >= 128|: encode as UTF8 }
+ if s<@"800 then begin
+ print_raw_char(@"C0 + s div @"40, false);
+ print_raw_char(@"80 + s mod @"40, true);
+ end
+ else if s<@"10000 then begin
+ print_raw_char(@"E0 + (s div @"1000), false);
+ print_raw_char(@"80 + (s mod @"1000) div @"40, false);
+ print_raw_char(@"80 + (s mod @"40), true);
+ end
+ else begin
+ print_raw_char(@"F0 + (s div @"40000), false);
+ print_raw_char(@"80 + (s mod @"40000) div @"1000, false);
+ print_raw_char(@"80 + (s mod @"1000) div @"40, false);
+ print_raw_char(@"80 + (s mod @"40), true);
+ end
+ end;
exit:end;
@ @d native_room(#)==while native_text_size <= native_len+# do begin
@@ -1759,7 +1759,7 @@ else if s<biggest_char then
else begin if selector>pseudo then
begin print_char(s); return; {internal strings are not expanded}
end;
- if (@<Character |s| is the current new-line character@>) then
+ if @<Character |s| is the current new-line character@> then
if selector<pseudo then
begin print_ln; return;
end;
@@ -2904,7 +2904,7 @@ of its other fields and its other words.
when |max_halfword| appears in the |link| field of a nonempty node.)
@d empty_flag == max_halfword {the |link| of an empty variable-size node}
-@d is_empty(#) == (link(#)=empty_flag) {tests for empty node}
+@d is_empty(#) == link(#)=empty_flag {tests for empty node}
@d node_size == info {the size field in empty variable-size nodes}
@d llink(#) == info(#+1) {left link in doubly-linked list of empty nodes}
@d rlink(#) == link(#+1) {right link in doubly-linked list of empty nodes}
@@ -3171,7 +3171,7 @@ an hlist; the |height| and |depth| are never running in a~vlist.
@d rule_node=2 {|type| of rule nodes}
@d rule_node_size=4 {number of words to allocate for a rule node}
@d null_flag==-@'10000000000 {$-2^{30}$, signifies a missing item}
-@d is_running(#) == (#=null_flag) {tests for a running dimension}
+@d is_running(#) == #=null_flag {tests for a running dimension}
@ A new rule node is delivered by the |new_rule| function. It
makes all the dimensions ``running,'' so you have to change the
@@ -3973,13 +3973,13 @@ whatsit_node:
case subtype(p) of
native_word_node: begin
if native_font(p)<>font_in_short_display then begin
- print_esc(font_id_text(native_font(p)));
- print_char(" ");
- font_in_short_display:=native_font(p);
- end;
- print_native_word(p);
- end;
- othercases print("[]")
+ print_esc(font_id_text(native_font(p)));
+ print_char(" ");
+ font_in_short_display:=native_font(p);
+ end;
+ print_native_word(p);
+ end;
+ othercases print("[]")
endcases;
rule_node: print_char("|");
glue_node: if glue_ptr(p)<>zero_glue then print_char(" ");
@@ -6064,7 +6064,7 @@ A global boolean variable called |no_new_control_sequence| is set to
@d next(#) == hash[#].lh {link for coalesced lists}
@d text(#) == hash[#].rh {string number for control sequence name}
-@d hash_is_full == (hash_used=hash_base) {test if all positions are occupied}
+@d hash_is_full == hash_used=hash_base {test if all positions are occupied}
@d font_id_text(#) == text(font_id_base+#) {a frozen font identifier's name}
@<Glob...@>=
@@ -6081,7 +6081,7 @@ A global boolean variable called |no_new_control_sequence| is set to
@d prim_base=1
@d prim_next(#) == prim[#].lh {link for coalesced lists}
@d prim_text(#) == prim[#].rh {string number for control sequence name}
-@d prim_is_full == (prim_used=prim_base) {test if all positions are occupied}
+@d prim_is_full == prim_used=prim_base {test if all positions are occupied}
@d prim_eq_level_field(#)==#.hh.b1
@d prim_eq_type_field(#)==#.hh.b0
@d prim_equiv_field(#)==#.hh.rh
@@ -6710,7 +6710,7 @@ the call, since |eq_save| makes the necessary test.
@p procedure eq_define(@!p:pointer;@!t:quarterword;@!e:halfword);
{new data for |eqtb|}
label exit;
-begin if eTeX_ex and(eq_type(p)=t)and(equiv(p)=e) then
+begin if (eTeX_ex)and(eq_type(p)=t)and(equiv(p)=e) then
begin assign_trace(p,"reassigning")@;@/
eq_destroy(eqtb[p]); return;
end;
@@ -6727,7 +6727,7 @@ exit:end;
@p procedure eq_word_define(@!p:pointer;@!w:integer);
label exit;
-begin if eTeX_ex and(eqtb[p].int=w) then
+begin if (eTeX_ex)and(eqtb[p].int=w) then
begin assign_trace(p,"reassigning")@;@/
return;
end;
@@ -7330,7 +7330,7 @@ put into a variable |@!page|, maintained for enclosing levels in
by analogy with |line_stack|.
@^system dependencies@>
-@d terminal_input==(name=0) {are we reading from the terminal?}
+@d terminal_input==name=0 {are we reading from the terminal?}
@d cur_file==input_file[index] {the current |alpha_file| variable}
@<Glob...@>=
@@ -7558,7 +7558,7 @@ begin base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input;
{store current state}
nn:=-1; bottom_line:=false;
loop@+begin cur_input:=input_stack[base_ptr]; {enter into the context}
- if (state<>token_list) then
+ if state<>token_list then
if (name>19) or (base_ptr=0) then bottom_line:=true;
if (base_ptr=input_ptr)or bottom_line or(nn<error_context_lines) then
@<Display the current context@>
@@ -7882,7 +7882,7 @@ inserted `\.{\\show}' commands, the following routine removes completed
error-inserted lines from memory.
@p procedure clear_for_error_prompt;
-begin while (state<>token_list)and terminal_input and@|
+begin while (state<>token_list)and(terminal_input)and@|
(input_ptr>0)and(loc>limit) do end_file_reading;
print_ln; clear_terminal;
end;
@@ -8381,7 +8381,7 @@ There is one more branch.
@<Move to next line of file, or |goto restart|...@>=
if name>17 then @<Read next line of file into |buffer|, or
|goto restart| if the file has ended@>
-else begin if not terminal_input then {\.{\\read} line has ended}
+else begin if not (terminal_input) then {\.{\\read} line has ended}
begin cur_cmd:=0; cur_chr:=0; return;
end;
if input_ptr>0 then {text was inserted during error recovery}
@@ -12062,14 +12062,14 @@ the font.
@d otgr_font_flag=@"FFFE
@d aat_font_flag=@"FFFF
-@d is_aat_font(#)==(font_area[#]=aat_font_flag)
-@d is_ot_font(#)==((font_area[#]=otgr_font_flag) and (usingOpenType(font_layout_engine[#])))
-@d is_gr_font(#)==((font_area[#]=otgr_font_flag) and (usingGraphite(font_layout_engine[#])))
-@d is_otgr_font(#)==(font_area[#]=otgr_font_flag)
-@d is_native_font(#)==(is_aat_font(#) or is_otgr_font(#))
- {native fonts have |font_area| = 65534 or 65535,
- which would be a string containing an invalid Unicode character}
-@d is_new_mathfont(#)==((font_area[#]=otgr_font_flag) and (isOpenTypeMathFont(font_layout_engine[#])))
+@d is_aat_font(#)==font_area[#]=aat_font_flag
+@d is_otgr_font(#)==font_area[#]=otgr_font_flag
+@d is_ot_font(#)==usingOpenType(#)
+@d is_gr_font(#)==usingGraphite(#)
+@d is_native_font(#)==(is_aat_font(#)) or (is_otgr_font(#))
+ {native fonts have |font_area| = 65534 or 65535,
+ which would be a string containing an invalid Unicode character}
+@d is_new_mathfont(#)==isOpenTypeMathFont(#)
@d non_char==qi(too_big_char) {a |halfword| code that can't match a real character}
@d non_address=0 {a spurious |bchar_label|}
@@ -12712,7 +12712,7 @@ procedure char_warning(@!f:internal_font_number;@!c:integer);
var old_setting: integer; {saved value of |tracing_online|}
begin if tracing_lost_chars>0 then
begin old_setting:=tracing_online;
- if eTeX_ex and(tracing_lost_chars>1) then tracing_online:=1;
+ if (eTeX_ex) and(tracing_lost_chars>1) then tracing_online:=1;
begin begin_diagnostic;
print_nl("Missing character: There is no ");
@.Missing character@>
@@ -13059,11 +13059,11 @@ file. Parameters |i|, |num|, |den|, |mag|, |k|, and |x| are explained below.
\yskip\hang|post_post| 249. Ending of the postamble, see below.
\yskip\hang|pic_file| 251 |flags[1]| |t[4][6]| |p[2]| |len[2]| |path[l]|.
- |flags=0| for raster image, and |1| for \.{PDF}.
- |t| is transform matrix.
- |p| is page number from the graphic file (0-based).
- |len| is length of pathname.
- |path| is pathname of graphic file.
+ |flags=0| for raster image, and |1| for \.{PDF}.
+ |t| is transform matrix.
+ |p| is page number from the graphic file (0-based).
+ |len| is length of pathname.
+ |path| is pathname of graphic file.
\yskip\hang\vbox{\halign{#&#\hfil\cr
|define_native_font| 252 & |k[4]| |s[4]| |flags[2]| |lenps[1]| |lenfam[1]| |lensty[1]| |ps[lenps]| |fam[lenfam]| |sty[lensty]|\cr
@@ -13116,11 +13116,11 @@ produced by \XeTeX. p\TeX\ uses 255.
@ The preamble contains basic information about the file as a whole. As
stated above, there are six parameters:
$$\hbox{|@!i[1]| |@!num[4]| |@!den[4]| |@!mag[4]| |@!k[1]| |@!x[k]|.}$$
-The |i| byte identifies \.{DVI} format; currently this byte is always set
-to~2. (The value |i=3| is currently used for an extended format that
-allows a mixture of right-to-left and left-to-right typesetting.
-Some day we will set |i=4|, when \.{DVI} format makes another
-incompatible change---perhaps in the year 2048.)
+The |i| byte identifies \.{DVI} format; in \XeTeX\ this byte is set to~5, as we
+have new \.{DVI} opcodes, while in \TeX82 it is always set to~2. (The value
+|i=3| is used for an extended format that allows a mixture of right-to-left and
+left-to-right typesetting. Prre-1.0 \XeTeX\ releases using Mac~OS~X-specific
+data types used |i=4|.)
The next two parameters, |num| and |den|, are positive integers that define
the units of measurement; they are the numerator and denominator of a
@@ -13143,11 +13143,6 @@ users to override the |mag|~setting when a \.{DVI} file is being printed.)
Finally, |k| and |x| allow the \.{DVI} writer to include a comment, which is not
interpreted further. The length of comment |x| is |k|, where |0<=k<256|.
-XeTeX changes the DVI version to 5,
-as we have new DVI opcodes like |set_glyph_array| for native font text;
-I used version 3 in an earlier extension of TeX,
-and 4 in pre-1.0 XeTeX releases using Mac OS-specific data types.
-
@d id_byte=5 {identifies the kind of \.{DVI} files described here}
@ Font definitions for a given font number |k| contain further parameters
@@ -13418,8 +13413,8 @@ end;
procedure dvi_two(s: UTF16_code);
begin
- dvi_out(s div @'400);
- dvi_out(s mod @'400);
+ dvi_out(s div @'400);
+ dvi_out(s mod @'400);
end;
@ A mild optimization of the output is performed by the |dvi_pop|
@@ -13437,12 +13432,12 @@ most 256 different fonts per job, |fnt_def1| is always used as the command code.
@p procedure dvi_native_font_def(@!f:internal_font_number);
var
- font_def_length, i: integer;
+ font_def_length, i: integer;
begin
- dvi_out(define_native_font);
- dvi_four(f-font_base-1);
- font_def_length := make_font_def(f);
- for i := 0 to font_def_length - 1 do dvi_out(xdv_buffer[i]);
+ dvi_out(define_native_font);
+ dvi_four(f-font_base-1);
+ font_def_length := make_font_def(f);
+ for i := 0 to font_def_length - 1 do dvi_out(xdv_buffer[i]);
end;
procedure dvi_font_def(@!f:internal_font_number);
@@ -15588,65 +15583,65 @@ macro capabilities. This seems a bit ugly, but it works.
@d total_mathsy_params=22
{the following are OpenType MATH constant indices for use with OT math fonts}
-@d scriptPercentScaleDown = 0
-@d scriptScriptPercentScaleDown = 1
-@d delimitedSubFormulaMinHeight = 2
-@d displayOperatorMinHeight = 3
-@d mathLeading = 4
-@d firstMathValueRecord = mathLeading
-@d axisHeight = 5
-@d accentBaseHeight = 6
-@d flattenedAccentBaseHeight = 7
-@d subscriptShiftDown = 8
-@d subscriptTopMax = 9
-@d subscriptBaselineDropMin = 10
-@d superscriptShiftUp = 11
-@d superscriptShiftUpCramped = 12
-@d superscriptBottomMin = 13
-@d superscriptBaselineDropMax = 14
-@d subSuperscriptGapMin = 15
-@d superscriptBottomMaxWithSubscript = 16
-@d spaceAfterScript = 17
-@d upperLimitGapMin = 18
-@d upperLimitBaselineRiseMin = 19
-@d lowerLimitGapMin = 20
-@d lowerLimitBaselineDropMin = 21
-@d stackTopShiftUp = 22
-@d stackTopDisplayStyleShiftUp = 23
-@d stackBottomShiftDown = 24
-@d stackBottomDisplayStyleShiftDown = 25
-@d stackGapMin = 26
-@d stackDisplayStyleGapMin = 27
-@d stretchStackTopShiftUp = 28
-@d stretchStackBottomShiftDown = 29
-@d stretchStackGapAboveMin = 30
-@d stretchStackGapBelowMin = 31
-@d fractionNumeratorShiftUp = 32
-@d fractionNumeratorDisplayStyleShiftUp = 33
-@d fractionDenominatorShiftDown = 34
-@d fractionDenominatorDisplayStyleShiftDown = 35
-@d fractionNumeratorGapMin = 36
-@d fractionNumDisplayStyleGapMin = 37
-@d fractionRuleThickness = 38
-@d fractionDenominatorGapMin = 39
-@d fractionDenomDisplayStyleGapMin = 40
-@d skewedFractionHorizontalGap = 41
-@d skewedFractionVerticalGap = 42
-@d overbarVerticalGap = 43
-@d overbarRuleThickness = 44
-@d overbarExtraAscender = 45
-@d underbarVerticalGap = 46
-@d underbarRuleThickness = 47
-@d underbarExtraDescender = 48
-@d radicalVerticalGap = 49
-@d radicalDisplayStyleVerticalGap = 50
-@d radicalRuleThickness = 51
-@d radicalExtraAscender = 52
-@d radicalKernBeforeDegree = 53
-@d radicalKernAfterDegree = 54
-@d lastMathValueRecord = radicalKernAfterDegree
-@d radicalDegreeBottomRaisePercent = 55
-@d lastMathConstant = radicalDegreeBottomRaisePercent
+@d scriptPercentScaleDown = 0
+@d scriptScriptPercentScaleDown = 1
+@d delimitedSubFormulaMinHeight = 2
+@d displayOperatorMinHeight = 3
+@d mathLeading = 4
+@d firstMathValueRecord = mathLeading
+@d axisHeight = 5
+@d accentBaseHeight = 6
+@d flattenedAccentBaseHeight = 7
+@d subscriptShiftDown = 8
+@d subscriptTopMax = 9
+@d subscriptBaselineDropMin = 10
+@d superscriptShiftUp = 11
+@d superscriptShiftUpCramped = 12
+@d superscriptBottomMin = 13
+@d superscriptBaselineDropMax = 14
+@d subSuperscriptGapMin = 15
+@d superscriptBottomMaxWithSubscript = 16
+@d spaceAfterScript = 17
+@d upperLimitGapMin = 18
+@d upperLimitBaselineRiseMin = 19
+@d lowerLimitGapMin = 20
+@d lowerLimitBaselineDropMin = 21
+@d stackTopShiftUp = 22
+@d stackTopDisplayStyleShiftUp = 23
+@d stackBottomShiftDown = 24
+@d stackBottomDisplayStyleShiftDown = 25
+@d stackGapMin = 26
+@d stackDisplayStyleGapMin = 27
+@d stretchStackTopShiftUp = 28
+@d stretchStackBottomShiftDown = 29
+@d stretchStackGapAboveMin = 30
+@d stretchStackGapBelowMin = 31
+@d fractionNumeratorShiftUp = 32
+@d fractionNumeratorDisplayStyleShiftUp = 33
+@d fractionDenominatorShiftDown = 34
+@d fractionDenominatorDisplayStyleShiftDown = 35
+@d fractionNumeratorGapMin = 36
+@d fractionNumDisplayStyleGapMin = 37
+@d fractionRuleThickness = 38
+@d fractionDenominatorGapMin = 39
+@d fractionDenomDisplayStyleGapMin = 40
+@d skewedFractionHorizontalGap = 41
+@d skewedFractionVerticalGap = 42
+@d overbarVerticalGap = 43
+@d overbarRuleThickness = 44
+@d overbarExtraAscender = 45
+@d underbarVerticalGap = 46
+@d underbarRuleThickness = 47
+@d underbarExtraDescender = 48
+@d radicalVerticalGap = 49
+@d radicalDisplayStyleVerticalGap = 50
+@d radicalRuleThickness = 51
+@d radicalExtraAscender = 52
+@d radicalKernBeforeDegree = 53
+@d radicalKernAfterDegree = 54
+@d lastMathValueRecord = radicalKernAfterDegree
+@d radicalDegreeBottomRaisePercent = 55
+@d lastMathConstant = radicalDegreeBottomRaisePercent
@d mathsy(#)==font_info[#+param_base[f]].sc
@@ -15725,348 +15720,348 @@ call |set_native_metrics(node)| if that is required.
@<Declare subroutines for |new_character|@>=
function new_native_word_node(@!f:internal_font_number;@!n:integer):pointer;
var
- l: integer;
- q: pointer;
+ l: integer;
+ q: pointer;
begin
- l := native_node_size + (n * sizeof(UTF16_code) + sizeof(memory_word) - 1) div sizeof(memory_word);
+ l := native_node_size + (n * sizeof(UTF16_code) + sizeof(memory_word) - 1) div sizeof(memory_word);
- q := get_node(l);
- type(q) := whatsit_node;
- subtype(q) := native_word_node;
+ q := get_node(l);
+ type(q) := whatsit_node;
+ subtype(q) := native_word_node;
- native_size(q) := l;
- native_font(q) := f;
- native_length(q) := n;
+ native_size(q) := l;
+ native_font(q) := f;
+ native_length(q) := n;
- native_glyph_count(q) := 0;
- native_glyph_info_ptr(q) := null_ptr;
+ native_glyph_count(q) := 0;
+ native_glyph_info_ptr(q) := null_ptr;
- new_native_word_node := q;
+ new_native_word_node := q;
end;
function new_native_character(@!f:internal_font_number;@!c:UnicodeScalar):pointer;
var
- p: pointer;
- i, len: integer;
+ p: pointer;
+ i, len: integer;
begin
- if font_mapping[f] <> 0 then begin
- if c > @"FFFF then begin
- str_room(2);
- append_char((c - @"10000) div 1024 + @"D800);
- append_char((c - @"10000) mod 1024 + @"DC00);
- end
- else begin
- str_room(1);
- append_char(c);
- end;
- len := apply_mapping(font_mapping[f], addressof(str_pool[str_start_macro(str_ptr)]), cur_length);
- pool_ptr := str_start_macro(str_ptr); { flush the string, as we'll be using the mapped text instead }
-
- i := 0;
- while i < len do begin
- if (mapped_text[i] >= @"D800) and (mapped_text[i] < @"DC00) then begin
- c := (mapped_text[i] - @"D800) * 1024 + mapped_text[i+1] - @"DC00 + @"10000;
- if map_char_to_glyph(f, c) = 0 then begin
- char_warning(f, c);
- end;
- i := i + 2;
- end
- else begin
- if map_char_to_glyph(f, mapped_text[i]) = 0 then begin
- char_warning(f, mapped_text[i]);
- end;
- i := i + 1;
- end;
- end;
-
- p := new_native_word_node(f, len);
- for i := 0 to len-1 do begin
- set_native_char(p, i, mapped_text[i]);
- end
- end
- else begin
- if tracing_lost_chars > 0 then
- if map_char_to_glyph(f, c) = 0 then begin
- char_warning(f, c);
- end;
-
- p := get_node(native_node_size + 1);
- type(p) := whatsit_node;
- subtype(p) := native_word_node;
-
- native_size(p) := native_node_size + 1;
- native_glyph_count(p) := 0;
- native_glyph_info_ptr(p) := null_ptr;
- native_font(p) := f;
-
- if c > @"FFFF then begin
- native_length(p) := 2;
- set_native_char(p, 0, (c - @"10000) div 1024 + @"D800);
- set_native_char(p, 1, (c - @"10000) mod 1024 + @"DC00);
- end
- else begin
- native_length(p) := 1;
- set_native_char(p, 0, c);
- end;
- end;
-
- set_native_metrics(p, XeTeX_use_glyph_metrics);
-
- new_native_character := p;
+ if font_mapping[f] <> 0 then begin
+ if c > @"FFFF then begin
+ str_room(2);
+ append_char((c - @"10000) div 1024 + @"D800);
+ append_char((c - @"10000) mod 1024 + @"DC00);
+ end
+ else begin
+ str_room(1);
+ append_char(c);
+ end;
+ len := apply_mapping(font_mapping[f], addressof(str_pool[str_start_macro(str_ptr)]), cur_length);
+ pool_ptr := str_start_macro(str_ptr); { flush the string, as we'll be using the mapped text instead }
+
+ i := 0;
+ while i < len do begin
+ if (mapped_text[i] >= @"D800) and (mapped_text[i] < @"DC00) then begin
+ c := (mapped_text[i] - @"D800) * 1024 + mapped_text[i+1] - @"DC00 + @"10000;
+ if map_char_to_glyph(f, c) = 0 then begin
+ char_warning(f, c);
+ end;
+ i := i + 2;
+ end
+ else begin
+ if map_char_to_glyph(f, mapped_text[i]) = 0 then begin
+ char_warning(f, mapped_text[i]);
+ end;
+ i := i + 1;
+ end;
+ end;
+
+ p := new_native_word_node(f, len);
+ for i := 0 to len-1 do begin
+ set_native_char(p, i, mapped_text[i]);
+ end
+ end
+ else begin
+ if tracing_lost_chars > 0 then
+ if map_char_to_glyph(f, c) = 0 then begin
+ char_warning(f, c);
+ end;
+
+ p := get_node(native_node_size + 1);
+ type(p) := whatsit_node;
+ subtype(p) := native_word_node;
+
+ native_size(p) := native_node_size + 1;
+ native_glyph_count(p) := 0;
+ native_glyph_info_ptr(p) := null_ptr;
+ native_font(p) := f;
+
+ if c > @"FFFF then begin
+ native_length(p) := 2;
+ set_native_char(p, 0, (c - @"10000) div 1024 + @"D800);
+ set_native_char(p, 1, (c - @"10000) mod 1024 + @"DC00);
+ end
+ else begin
+ native_length(p) := 1;
+ set_native_char(p, 0, c);
+ end;
+ end;
+
+ set_native_metrics(p, XeTeX_use_glyph_metrics);
+
+ new_native_character := p;
end;
procedure font_feature_warning(featureNameP:void_pointer; featLen:integer;
- settingNameP:void_pointer; setLen:integer);
+ settingNameP:void_pointer; setLen:integer);
var
- i: integer;
+ i: integer;
begin
- begin_diagnostic;
- print_nl("Unknown ");
- if setLen > 0 then begin
- print("selector `");
- print_utf8_str(settingNameP, setLen);
- print("' for ");
- end;
- print("feature `");
- print_utf8_str(featureNameP, featLen);
- print("' in font `");
- i := 1;
- while ord(name_of_file[i]) <> 0 do begin
- print_visible_char(name_of_file[i]); { this is already UTF-8 }
- incr(i);
- end;
- print("'.");
- end_diagnostic(false);
+ begin_diagnostic;
+ print_nl("Unknown ");
+ if setLen > 0 then begin
+ print("selector `");
+ print_utf8_str(settingNameP, setLen);
+ print("' for ");
+ end;
+ print("feature `");
+ print_utf8_str(featureNameP, featLen);
+ print("' in font `");
+ i := 1;
+ while ord(name_of_file[i]) <> 0 do begin
+ print_visible_char(name_of_file[i]); { this is already UTF-8 }
+ incr(i);
+ end;
+ print("'.");
+ end_diagnostic(false);
end;
procedure font_mapping_warning(mappingNameP:void_pointer;
- mappingNameLen:integer;
- warningType:integer); { 0: just logging; 1: file not found; 2: can't load }
+ mappingNameLen:integer;
+ warningType:integer); { 0: just logging; 1: file not found; 2: can't load }
var
- i: integer;
+ i: integer;
begin
- begin_diagnostic;
- if warningType=0 then print_nl("Loaded mapping `")
- else print_nl("Font mapping `");
- print_utf8_str(mappingNameP, mappingNameLen);
- print("' for font `");
- i := 1;
- while ord(name_of_file[i]) <> 0 do begin
- print_visible_char(name_of_file[i]); { this is already UTF-8 }
- incr(i);
- end;
- case warningType of
- 1: print("' not found.");
- 2: begin print("' not usable;");
- print_nl("bad mapping file or incorrect mapping type.");
- end;
- othercases print("'.")
- endcases;
- end_diagnostic(false);
+ begin_diagnostic;
+ if warningType=0 then print_nl("Loaded mapping `")
+ else print_nl("Font mapping `");
+ print_utf8_str(mappingNameP, mappingNameLen);
+ print("' for font `");
+ i := 1;
+ while ord(name_of_file[i]) <> 0 do begin
+ print_visible_char(name_of_file[i]); { this is already UTF-8 }
+ incr(i);
+ end;
+ case warningType of
+ 1: print("' not found.");
+ 2: begin print("' not usable;");
+ print_nl("bad mapping file or incorrect mapping type.");
+ end;
+ othercases print("'.")
+ endcases;
+ end_diagnostic(false);
end;
procedure graphite_warning;
var
- i: integer;
+ i: integer;
begin
- begin_diagnostic;
- print_nl("Font `");
- i := 1;
- while ord(name_of_file[i]) <> 0 do begin
- print_visible_char(name_of_file[i]); { this is already UTF-8 }
- incr(i);
- end;
- print("' does not support Graphite. Trying OpenType layout instead.");
- end_diagnostic(false);
+ begin_diagnostic;
+ print_nl("Font `");
+ i := 1;
+ while ord(name_of_file[i]) <> 0 do begin
+ print_visible_char(name_of_file[i]); { this is already UTF-8 }
+ incr(i);
+ end;
+ print("' does not support Graphite. Trying OpenType layout instead.");
+ end_diagnostic(false);
end;
function load_native_font(u: pointer; nom, aire:str_number; s: scaled): internal_font_number;
label
- done;
+ done;
const
- first_math_fontdimen = 10;
+ first_math_fontdimen = 10;
var
- k, num_font_dimens: integer;
- font_engine: void_pointer; {really an CFDictionaryRef or XeTeXLayoutEngine}
- actual_size: scaled; {|s| converted to real size, if it was negative}
- p: pointer; {for temporary |native_char| node we'll create}
- ascent, descent, font_slant, x_ht, cap_ht: scaled;
- f: internal_font_number;
- full_name: str_number;
+ k, num_font_dimens: integer;
+ font_engine: void_pointer; {really an CFDictionaryRef or XeTeXLayoutEngine}
+ actual_size: scaled; {|s| converted to real size, if it was negative}
+ p: pointer; {for temporary |native_char| node we'll create}
+ ascent, descent, font_slant, x_ht, cap_ht: scaled;
+ f: internal_font_number;
+ full_name: str_number;
begin
- { on entry here, the full name is packed into |name_of_file| in UTF8 form }
-
- load_native_font := null_font;
-
- font_engine := find_native_font(name_of_file + 1, s);
- if font_engine = 0 then goto done;
-
- if s>=0 then
- actual_size := s
- else begin
- if (s <> -1000) then
- actual_size := xn_over_d(loaded_font_design_size,-s,1000)
- else
- actual_size := loaded_font_design_size;
- end;
-
- { look again to see if the font is already loaded, now that we know its canonical name }
- str_room(name_length);
- for k := 1 to name_length do
- append_char(name_of_file[k]);
+ { on entry here, the full name is packed into |name_of_file| in UTF8 form }
+
+ load_native_font := null_font;
+
+ font_engine := find_native_font(name_of_file + 1, s);
+ if font_engine = 0 then goto done;
+
+ if s>=0 then
+ actual_size := s
+ else begin
+ if (s <> -1000) then
+ actual_size := xn_over_d(loaded_font_design_size,-s,1000)
+ else
+ actual_size := loaded_font_design_size;
+ end;
+
+ { look again to see if the font is already loaded, now that we know its canonical name }
+ str_room(name_length);
+ for k := 1 to name_length do
+ append_char(name_of_file[k]);
full_name := make_string; { not |slow_make_string| because we'll flush it if the font was already loaded }
- for f:=font_base+1 to font_ptr do
- if (font_area[f] = native_font_type_flag) and str_eq_str(font_name[f], full_name) and (font_size[f] = actual_size) then begin
- release_font_engine(font_engine, native_font_type_flag);
- flush_string;
- load_native_font := f;
- goto done;
+ for f:=font_base+1 to font_ptr do
+ if (font_area[f] = native_font_type_flag) and str_eq_str(font_name[f], full_name) and (font_size[f] = actual_size) then begin
+ release_font_engine(font_engine, native_font_type_flag);
+ flush_string;
+ load_native_font := f;
+ goto done;
end;
- if (native_font_type_flag = otgr_font_flag) and isOpenTypeMathFont(font_engine) then
- num_font_dimens := first_math_fontdimen + lastMathConstant
- else
- num_font_dimens := 8;
-
- if (font_ptr = font_max) or (fmem_ptr + num_font_dimens > font_mem_size) then begin
- @<Apologize for not loading the font, |goto done|@>;
- end;
-
- { we've found a valid installed font, and have room }
- incr(font_ptr);
- font_area[font_ptr] := native_font_type_flag; { set by |find_native_font| to either |aat_font_flag| or |ot_font_flag| }
-
- { store the canonical name }
- font_name[font_ptr] := full_name;
-
- font_check[font_ptr].b0 := 0;
- font_check[font_ptr].b1 := 0;
- font_check[font_ptr].b2 := 0;
- font_check[font_ptr].b3 := 0;
- font_glue[font_ptr] := null;
- font_dsize[font_ptr] := loaded_font_design_size;
- font_size[font_ptr] := actual_size;
-
- if (native_font_type_flag = aat_font_flag) then begin
- aat_get_font_metrics(font_engine, addressof(ascent), addressof(descent),
- addressof(x_ht), addressof(cap_ht), addressof(font_slant))
- end else begin
- ot_get_font_metrics(font_engine, addressof(ascent), addressof(descent),
- addressof(x_ht), addressof(cap_ht), addressof(font_slant));
- end;
-
- height_base[font_ptr] := ascent;
- depth_base[font_ptr] := -descent;
-
- font_params[font_ptr] := num_font_dimens; {we add an extra \.{\\fontdimen8} |:= cap_height|; then OT math fonts have a bunch more}
- font_bc[font_ptr] := 0;
- font_ec[font_ptr] := 65535;
- font_used[font_ptr] := false;
- hyphen_char[font_ptr] := default_hyphen_char;
- skew_char[font_ptr] := default_skew_char;
- param_base[font_ptr] := fmem_ptr-1;
-
- font_layout_engine[font_ptr] := font_engine;
- font_mapping[font_ptr] := 0; {don't use the mapping, if any, when measuring space here}
- font_letter_space[font_ptr] := loaded_font_letter_space;
+ if (font_ptr = font_max) or (fmem_ptr + num_font_dimens > font_mem_size) then begin
+ @<Apologize for not loading the font, |goto done|@>;
+ end;
+
+ { we've found a valid installed font, and have room }
+ incr(font_ptr);
+ font_area[font_ptr] := native_font_type_flag; { set by |find_native_font| to either |aat_font_flag| or |ot_font_flag| }
+
+ { store the canonical name }
+ font_name[font_ptr] := full_name;
+
+ font_check[font_ptr].b0 := 0;
+ font_check[font_ptr].b1 := 0;
+ font_check[font_ptr].b2 := 0;
+ font_check[font_ptr].b3 := 0;
+ font_glue[font_ptr] := null;
+ font_dsize[font_ptr] := loaded_font_design_size;
+ font_size[font_ptr] := actual_size;
+
+ if native_font_type_flag = aat_font_flag then begin
+ aat_get_font_metrics(font_engine, addressof(ascent), addressof(descent),
+ addressof(x_ht), addressof(cap_ht), addressof(font_slant))
+ end else begin
+ ot_get_font_metrics(font_engine, addressof(ascent), addressof(descent),
+ addressof(x_ht), addressof(cap_ht), addressof(font_slant));
+ end;
+
+ height_base[font_ptr] := ascent;
+ depth_base[font_ptr] := -descent;
+
+ font_layout_engine[font_ptr] := font_engine;
+ if isOpenTypeMathFont(font_ptr) then
+ num_font_dimens := first_math_fontdimen + lastMathConstant
+ else
+ num_font_dimens := 8;
+
+ font_params[font_ptr] := num_font_dimens; {we add an extra \.{\\fontdimen8} |:= cap_height|; then OT math fonts have a bunch more}
+ font_bc[font_ptr] := 0;
+ font_ec[font_ptr] := 65535;
+ font_used[font_ptr] := false;
+ hyphen_char[font_ptr] := default_hyphen_char;
+ skew_char[font_ptr] := default_skew_char;
+ param_base[font_ptr] := fmem_ptr-1;
+
+ font_mapping[font_ptr] := 0; {don't use the mapping, if any, when measuring space here}
+ font_letter_space[font_ptr] := loaded_font_letter_space;
@# {measure the width of the space character and set up font parameters}
- p := new_native_character(font_ptr, " ");
- s := width(p) + loaded_font_letter_space;
- free_node(p, native_size(p));
-
- font_info[fmem_ptr].sc := font_slant; {|slant|}
- incr(fmem_ptr);
- font_info[fmem_ptr].sc := s; {|space| = width of space character}
- incr(fmem_ptr);
- font_info[fmem_ptr].sc := s div 2; {|space_stretch| = 1/2 * space}
- incr(fmem_ptr);
- font_info[fmem_ptr].sc := s div 3; {|space_shrink| = 1/3 * space}
- incr(fmem_ptr);
- font_info[fmem_ptr].sc := x_ht; {|x_height|}
- incr(fmem_ptr);
- font_info[fmem_ptr].sc := font_size[font_ptr]; {|quad| = font size}
- incr(fmem_ptr);
- font_info[fmem_ptr].sc := s div 3; {|extra_space| = 1/3 * space}
- incr(fmem_ptr);
- font_info[fmem_ptr].sc := cap_ht; {|cap_height|}
- incr(fmem_ptr);
-
- if num_font_dimens = first_math_fontdimen + lastMathConstant then begin
- font_info[fmem_ptr].int := num_font_dimens; { \.{\\fontdimen9} |:=| number of assigned fontdimens }
- incr(fmem_ptr);
- for k := 0 to lastMathConstant do begin
- font_info[fmem_ptr].sc := get_ot_math_constant(font_ptr, k);
- incr(fmem_ptr);
- end;
- end;
-
- font_mapping[font_ptr] := loaded_font_mapping;
- font_flags[font_ptr] := loaded_font_flags;
-
- load_native_font := font_ptr;
+ p := new_native_character(font_ptr, " ");
+ s := width(p) + loaded_font_letter_space;
+ free_node(p, native_size(p));
+
+ font_info[fmem_ptr].sc := font_slant; {|slant|}
+ incr(fmem_ptr);
+ font_info[fmem_ptr].sc := s; {|space| = width of space character}
+ incr(fmem_ptr);
+ font_info[fmem_ptr].sc := s div 2; {|space_stretch| = 1/2 * space}
+ incr(fmem_ptr);
+ font_info[fmem_ptr].sc := s div 3; {|space_shrink| = 1/3 * space}
+ incr(fmem_ptr);
+ font_info[fmem_ptr].sc := x_ht; {|x_height|}
+ incr(fmem_ptr);
+ font_info[fmem_ptr].sc := font_size[font_ptr]; {|quad| = font size}
+ incr(fmem_ptr);
+ font_info[fmem_ptr].sc := s div 3; {|extra_space| = 1/3 * space}
+ incr(fmem_ptr);
+ font_info[fmem_ptr].sc := cap_ht; {|cap_height|}
+ incr(fmem_ptr);
+
+ if num_font_dimens = first_math_fontdimen + lastMathConstant then begin
+ font_info[fmem_ptr].int := num_font_dimens; { \.{\\fontdimen9} |:=| number of assigned fontdimens }
+ incr(fmem_ptr);
+ for k := 0 to lastMathConstant do begin
+ font_info[fmem_ptr].sc := get_ot_math_constant(font_ptr, k);
+ incr(fmem_ptr);
+ end;
+ end;
+
+ font_mapping[font_ptr] := loaded_font_mapping;
+ font_flags[font_ptr] := loaded_font_flags;
+
+ load_native_font := font_ptr;
done:
end;
procedure do_locale_linebreaks(s: integer; len: integer);
var
- offs, prevOffs, i: integer;
- use_penalty, use_skip: boolean;
+ offs, prevOffs, i: integer;
+ use_penalty, use_skip: boolean;
begin
- if (XeTeX_linebreak_locale = 0) or (len = 1) then begin
- link(tail) := new_native_word_node(main_f, len);
- tail := link(tail);
- for i := 0 to len - 1 do
- set_native_char(tail, i, native_text[s + i]);
- set_native_metrics(tail, XeTeX_use_glyph_metrics);
- end else begin
- use_skip := XeTeX_linebreak_skip <> zero_glue;
- use_penalty := XeTeX_linebreak_penalty <> 0 or not use_skip;
- linebreak_start(main_f, XeTeX_linebreak_locale, native_text + s, len);
- offs := 0;
- repeat
- prevOffs := offs;
- offs := linebreak_next;
- if offs > 0 then begin
- if prevOffs <> 0 then begin
- if use_penalty then
- tail_append(new_penalty(XeTeX_linebreak_penalty));
- if use_skip then
- tail_append(new_param_glue(XeTeX_linebreak_skip_code));
- end;
- link(tail) := new_native_word_node(main_f, offs - prevOffs);
- tail := link(tail);
- for i := prevOffs to offs - 1 do
- set_native_char(tail, i - prevOffs, native_text[s + i]);
- set_native_metrics(tail, XeTeX_use_glyph_metrics);
- end;
- until offs < 0;
- end
+ if (XeTeX_linebreak_locale = 0) or (len = 1) then begin
+ link(tail) := new_native_word_node(main_f, len);
+ tail := link(tail);
+ for i := 0 to len - 1 do
+ set_native_char(tail, i, native_text[s + i]);
+ set_native_metrics(tail, XeTeX_use_glyph_metrics);
+ end else begin
+ use_skip := XeTeX_linebreak_skip <> zero_glue;
+ use_penalty := XeTeX_linebreak_penalty <> 0 or not use_skip;
+ linebreak_start(main_f, XeTeX_linebreak_locale, native_text + s, len);
+ offs := 0;
+ repeat
+ prevOffs := offs;
+ offs := linebreak_next;
+ if offs > 0 then begin
+ if prevOffs <> 0 then begin
+ if use_penalty then
+ tail_append(new_penalty(XeTeX_linebreak_penalty));
+ if use_skip then
+ tail_append(new_param_glue(XeTeX_linebreak_skip_code));
+ end;
+ link(tail) := new_native_word_node(main_f, offs - prevOffs);
+ tail := link(tail);
+ for i := prevOffs to offs - 1 do
+ set_native_char(tail, i - prevOffs, native_text[s + i]);
+ set_native_metrics(tail, XeTeX_use_glyph_metrics);
+ end;
+ until offs < 0;
+ end
end;
procedure bad_utf8_warning;
begin
- begin_diagnostic;
- print_nl("Invalid UTF-8 byte or sequence");
- if terminal_input then print(" in terminal input")
- else begin
- print(" at line ");
- print_int(line);
- end;
- print(" replaced by U+FFFD.");
- end_diagnostic(false);
+ begin_diagnostic;
+ print_nl("Invalid UTF-8 byte or sequence");
+ if terminal_input then print(" in terminal input")
+ else begin
+ print(" at line ");
+ print_int(line);
+ end;
+ print(" replaced by U+FFFD.");
+ end_diagnostic(false);
end;
function get_input_normalization_state: integer;
begin
- if eqtb=nil then get_input_normalization_state:=0 { may be called before eqtb is initialized }
- else get_input_normalization_state:=XeTeX_input_normalization_state;
+ if eqtb=nil then get_input_normalization_state:=0 { may be called before eqtb is initialized }
+ else get_input_normalization_state:=XeTeX_input_normalization_state;
end;
function get_tracing_fonts_state: integer;
begin
- get_tracing_fonts_state:=XeTeX_tracing_fonts_state;
+ get_tracing_fonts_state:=XeTeX_tracing_fonts_state;
end;
@ We also need to compute the change in style between mlists and their
@@ -16939,13 +16934,13 @@ var
@!q,@!r:pointer;
@!s,@!g:scaled;
begin
- if (math_type(nucleus(p))=math_char) then begin
+ if math_type(nucleus(p))=math_char then begin
fetch(nucleus(p));
q:=new_native_character(cur_f, qo(cur_c));
g:=get_native_glyph(q, 0);
s:=get_ot_math_accent_pos(cur_f, g);
end else begin
- if (math_type(nucleus(p))=sub_mlist) then begin
+ if math_type(nucleus(p))=sub_mlist then begin
r:=info(nucleus(p));
if (r<>null) and (type(r)=accent_noad) then
s:=compute_ot_math_accent_pos(r)
@@ -17461,7 +17456,7 @@ if is_native_font(cur_f) then begin
set_native_glyph_metrics(p, 1);
free_node(z, native_size(z));
delta:=get_ot_math_ital_corr(cur_f, native_glyph(p));
- if (math_type(nucleus(q))=math_text_char)and(not is_new_mathfont(cur_f)<>0) then
+ if (math_type(nucleus(q))=math_text_char)and(not (is_new_mathfont(cur_f))<>0) then
delta:=0; {no italic correction in mid-word of text font}
if (math_type(subscr(q))=empty)and(delta<>0) then
begin link(p):=new_kern(delta); delta:=0;
@@ -17500,12 +17495,13 @@ end;
procedure make_scripts(@!q:pointer;@!delta:scaled);
var p,@!x,@!y,@!z:pointer; {temporary registers for box construction}
@!shift_up,@!shift_down,@!clr,@!sub_kern,@!sup_kern:scaled; {dimensions in the calculation}
-@!g:quarterword; {temporary register for native glyph id}
+@!script_c:pointer; {temprary native character for sub/superscript}
+@!script_g:quarterword; {temporary register for sub/superscript native glyph id}
+@!script_f:internal_font_number; {temporary register for sub/superscript font}
@!t:integer; {subsidiary size code}
@!save_f:internal_font_number;
-@!s:pointer; {temprary native character for sub/superscript}
begin p:=new_hlist(q);
-s:=null; sup_kern:=0; sub_kern:=0; g:=0;
+script_c:=null; script_g:=0; script_f:=0; sup_kern:=0; sub_kern:=0;
if is_char_node(p) or is_glyph_node(p) then
begin shift_up:=0; shift_down:=0;
end
@@ -17615,33 +17611,43 @@ The following definitions should be kept in sync with \.{XeTeXOTMath.cpp}.
@d sub_cmd=1 {subscript kern type for |get_ot_math_kern|}
@<Attach subscript OpenType math kerning@>=
-begin save_f:=cur_f;@/
-fetch(subscr(q));
-if is_new_mathfont(cur_f) then begin
- s:=new_native_character(cur_f, qo(cur_c));
- g:=get_native_glyph(s, 0);
+begin if math_type(subscr(q))=math_char then
+ begin save_f:=cur_f;
+ fetch(subscr(q));
+ if is_new_mathfont(cur_f) then
+ begin script_c:=new_native_character(cur_f, qo(cur_c));
+ script_g:=get_native_glyph(script_c, 0);
+ script_f:=cur_f;
+ end else
+ begin script_g:=0; script_f:=0
+ end;
+ cur_f:=save_f;
end;
if is_glyph_node(p) then
- sub_kern:=get_ot_math_kern(native_font(p), native_glyph(p), cur_f, g, sub_cmd, shift_down);
+ sub_kern:=get_ot_math_kern(native_font(p), native_glyph(p), script_f, script_g, sub_cmd, shift_down);
if sub_kern<>0 then p:=attach_hkern_to_new_hlist(q, sub_kern);
-cur_f:=save_f;
end;
@ @<Attach superscript OpenType math kerning@>=
-begin save_f:=cur_f;@/
-fetch(supscr(q));
-if is_new_mathfont(cur_f) then begin
- s:=new_native_character(cur_f, qo(cur_c));
- g:=get_native_glyph(s, 0);
+begin if math_type(supscr(q))=math_char then
+ begin save_f:=cur_f;
+ fetch(supscr(q));
+ if is_new_mathfont(cur_f) then
+ begin script_c:=new_native_character(cur_f, qo(cur_c));
+ script_g:=get_native_glyph(script_c, 0);
+ script_f:=cur_f;
+ end else
+ begin script_g:=0; script_f:=0
+ end;
+ cur_f:=save_f;
end;
if is_glyph_node(p) then
- sup_kern:=get_ot_math_kern(native_font(p), native_glyph(p), cur_f, g, sup_cmd, shift_up);
+ sup_kern:=get_ot_math_kern(native_font(p), native_glyph(p), script_f, script_g, sup_cmd, shift_up);
if (sup_kern<>0) and (math_type(subscr(q))=empty) then
{if there is a superscript the kern will be added to |shift_amount(x)|}
p:=attach_hkern_to_new_hlist(q, sup_kern);
-cur_f:=save_f;
end;
@ We have now tied up all the loose ends of the first pass of |mlist_to_hlist|.
@@ -19439,7 +19445,7 @@ else case type(v) of
or (subtype(v)=pic_node)
or (subtype(v)=pdf_node)
then break_width[1]:=break_width[1]-width(v)
- else confusion("disc1a");
+ else confusion("disc1a");
othercases confusion("disc1")
@:this can't happen disc1}{\quad disc1@>
endcases
@@ -19463,7 +19469,7 @@ else case type(s) of
or (subtype(s)=pic_node)
or (subtype(s)=pdf_node)
then break_width[1]:=break_width[1]+width(s)
- else confusion("disc2a");
+ else confusion("disc2a");
othercases confusion("disc2")
@:this can't happen disc2}{\quad disc2@>
endcases
@@ -20049,7 +20055,7 @@ else case type(s) of
or (subtype(s)=pic_node)
or (subtype(s)=pdf_node)
then disc_width:=disc_width+width(s)
- else confusion("disc3a");
+ else confusion("disc3a");
othercases confusion("disc3")
@:this can't happen disc3}{\quad disc3@>
endcases
@@ -20073,7 +20079,7 @@ else case type(s) of
or (subtype(s)=pic_node)
or (subtype(s)=pdf_node)
then act_width:=act_width+width(s)
- else confusion("disc4a");
+ else confusion("disc4a");
othercases confusion("disc4")
@:this can't happen disc4}{\quad disc4@>
endcases
@@ -20298,7 +20304,7 @@ if XeTeX_protrude_chars > 0 then begin
k := new_margin_kern(-w, last_rightmost_char, right_side);
link(k) := link(ptmp);
link(ptmp) := k;
- if (ptmp = q) then
+ if ptmp = q then
q := link(q);
end;
end;
@@ -20585,8 +20591,8 @@ restart:
for l := 0 to native_length(ha)-1 do begin
c := get_native_usv(ha, l);
set_lc_code(c);
- if (hc[0] = 0) then begin
- if (hn > 0) then begin
+ if hc[0]=0 then begin
+ if hn>0 then begin
{ we've got some letters, and now found a non-letter, so break off the tail of the |native_word|
and link it after this node, and goto done3 }
@<Split the |native_word_node| at |l| and link the second part after |ha|@>;
@@ -20597,7 +20603,7 @@ for l := 0 to native_length(ha)-1 do begin
@<Split the |native_word_node| at |l| and link the second part after |ha|@>;
ha := link(ha);
goto restart;
- end else if (hn = 63) then
+ end else if hn = 63 then
{ reached max hyphenatable length }
goto done3
else begin
@@ -20826,21 +20832,21 @@ for j := l_hyf to hn - r_hyf do begin
{ if this is a valid break.... }
if odd(hyf[j]) then begin
- { make a |native_word_node| for the fragment before the hyphen }
- q := new_native_word_node(hf, j - hyphen_passed);
- for i := 0 to j - hyphen_passed - 1 do
- set_native_char(q, i, get_native_char(ha, i + hyphen_passed));
- set_native_metrics(q, XeTeX_use_glyph_metrics);
- link(s) := q; { append the new node }
- s := q;
+ { make a |native_word_node| for the fragment before the hyphen }
+ q := new_native_word_node(hf, j - hyphen_passed);
+ for i := 0 to j - hyphen_passed - 1 do
+ set_native_char(q, i, get_native_char(ha, i + hyphen_passed));
+ set_native_metrics(q, XeTeX_use_glyph_metrics);
+ link(s) := q; { append the new node }
+ s := q;
- { make the |disc_node| for the hyphenation point }
+ { make the |disc_node| for the hyphenation point }
q := new_disc;
- pre_break(q) := new_native_character(hf, hyf_char);
- link(s) := q;
- s := q;
+ pre_break(q) := new_native_character(hf, hyf_char);
+ link(s) := q;
+ s := q;
- hyphen_passed := j;
+ hyphen_passed := j;
end
end;
@@ -23339,49 +23345,49 @@ are inside the individual sections.
@d check_for_inter_char_toks(#)=={check for a spacing token list, goto |#| if found,
or |big_switch| in case of the initial letter of a run}
- cur_ptr:=null;
- space_class:=sf_code(cur_chr) div @"10000;
-
- if XeTeX_inter_char_tokens_en and space_class <> 256 then begin {class 256 = ignored (for combining marks etc)}
- if prev_class = 255 then begin {boundary}
- if (state<>token_list) or (token_type<>backed_up_char) then begin
- find_sa_element(inter_char_val, 255*@"100 + space_class, false);
- if cur_ptr<>null then begin
- if cur_cmd<>letter then cur_cmd:=other_char;
- cur_tok:=(cur_cmd*max_char_val)+cur_chr;
- back_input; token_type:=backed_up_char;
- begin_token_list(sa_ptr(cur_ptr), inter_char_text);
- goto big_switch;
- end
- end
- end else begin
- find_sa_element(inter_char_val, prev_class*@"100 + space_class, false);
- if cur_ptr<>null then begin
- if cur_cmd<>letter then cur_cmd:=other_char;
- cur_tok:=(cur_cmd*max_char_val)+cur_chr;
- back_input; token_type:=backed_up_char;
- begin_token_list(sa_ptr(cur_ptr), inter_char_text);
- prev_class:=255;
- goto #;
- end;
- end;
- prev_class:=space_class;
- end
+ cur_ptr:=null;
+ space_class:=sf_code(cur_chr) div @"10000;
+
+ if XeTeX_inter_char_tokens_en and space_class <> 256 then begin {class 256 = ignored (for combining marks etc)}
+ if prev_class = 255 then begin {boundary}
+ if (state<>token_list) or (token_type<>backed_up_char) then begin
+ find_sa_element(inter_char_val, 255*@"100 + space_class, false);
+ if cur_ptr<>null then begin
+ if cur_cmd<>letter then cur_cmd:=other_char;
+ cur_tok:=(cur_cmd*max_char_val)+cur_chr;
+ back_input; token_type:=backed_up_char;
+ begin_token_list(sa_ptr(cur_ptr), inter_char_text);
+ goto big_switch;
+ end
+ end
+ end else begin
+ find_sa_element(inter_char_val, prev_class*@"100 + space_class, false);
+ if cur_ptr<>null then begin
+ if cur_cmd<>letter then cur_cmd:=other_char;
+ cur_tok:=(cur_cmd*max_char_val)+cur_chr;
+ back_input; token_type:=backed_up_char;
+ begin_token_list(sa_ptr(cur_ptr), inter_char_text);
+ prev_class:=255;
+ goto #;
+ end;
+ end;
+ prev_class:=space_class;
+ end
@d check_for_post_char_toks(#)==
- if XeTeX_inter_char_tokens_en and (space_class<>256) and (prev_class<>255) then begin
- prev_class:=255;
- find_sa_element(inter_char_val, space_class*@"100 + 255, false); {boundary}
- if cur_ptr<>null then begin
- if cur_cs=0 then begin
- if cur_cmd=char_num then cur_cmd:=other_char;
- cur_tok:=(cur_cmd*max_char_val)+cur_chr;
- end else cur_tok:=cs_token_flag+cur_cs;
- back_input;
- begin_token_list(sa_ptr(cur_ptr), inter_char_text);
- goto #;
- end;
- end
+ if XeTeX_inter_char_tokens_en and (space_class<>256) and (prev_class<>255) then begin
+ prev_class:=255;
+ find_sa_element(inter_char_val, space_class*@"100 + 255, false); {boundary}
+ if cur_ptr<>null then begin
+ if cur_cs=0 then begin
+ if cur_cmd=char_num then cur_cmd:=other_char;
+ cur_tok:=(cur_cmd*max_char_val)+cur_chr;
+ end else cur_tok:=cs_token_flag+cur_cs;
+ back_input;
+ begin_token_list(sa_ptr(cur_ptr), inter_char_text);
+ goto #;
+ end;
+ end
@<Append character |cur_chr|...@>=
@@ -23389,201 +23395,201 @@ prev_class := 255; {boundary}
{ added code for native font support }
if is_native_font(cur_font) then begin
- if mode>0 then if language<>clang then fix_language;
+ if mode>0 then if language<>clang then fix_language;
- main_h := 0;
- main_f := cur_font;
- native_len := 0;
+ main_h := 0;
+ main_f := cur_font;
+ native_len := 0;
collect_native:
- adjust_space_factor;
-
- check_for_inter_char_toks(collected);
-
- if (cur_chr > @"FFFF) then begin
- native_room(2);
- append_native((cur_chr - @"10000) div 1024 + @"D800);
- append_native((cur_chr - @"10000) mod 1024 + @"DC00);
- end else begin
- native_room(1);
- append_native(cur_chr);
- end;
- is_hyph := (cur_chr = hyphen_char[main_f])
- or (XeTeX_dash_break_en and ((cur_chr = @"2014) or (cur_chr = @"2013)));
- if (main_h = 0) and is_hyph then main_h := native_len;
-
- {try to collect as many chars as possible in the same font}
- get_next;
- if (cur_cmd=letter) or (cur_cmd=other_char) or (cur_cmd=char_given) then goto collect_native;
- x_token;
- if (cur_cmd=letter) or (cur_cmd=other_char) or (cur_cmd=char_given) then goto collect_native;
- if cur_cmd=char_num then begin
- scan_usv_num;
- cur_chr:=cur_val;
- goto collect_native;
- end;
-
- check_for_post_char_toks(collected);
+ adjust_space_factor;
+
+ check_for_inter_char_toks(collected);
+
+ if (cur_chr > @"FFFF) then begin
+ native_room(2);
+ append_native((cur_chr - @"10000) div 1024 + @"D800);
+ append_native((cur_chr - @"10000) mod 1024 + @"DC00);
+ end else begin
+ native_room(1);
+ append_native(cur_chr);
+ end;
+ is_hyph := (cur_chr = hyphen_char[main_f])
+ or (XeTeX_dash_break_en and ((cur_chr = @"2014) or (cur_chr = @"2013)));
+ if (main_h = 0) and is_hyph then main_h := native_len;
+
+ {try to collect as many chars as possible in the same font}
+ get_next;
+ if (cur_cmd=letter) or (cur_cmd=other_char) or (cur_cmd=char_given) then goto collect_native;
+ x_token;
+ if (cur_cmd=letter) or (cur_cmd=other_char) or (cur_cmd=char_given) then goto collect_native;
+ if cur_cmd=char_num then begin
+ scan_usv_num;
+ cur_chr:=cur_val;
+ goto collect_native;
+ end;
+
+ check_for_post_char_toks(collected);
collected:
- if (font_mapping[main_f] <> 0) then begin
- main_k := apply_mapping(font_mapping[main_f], native_text, native_len);
- native_len := 0;
- native_room(main_k);
- main_h := 0;
- for main_p := 0 to main_k - 1 do begin
- append_native(mapped_text[main_p]);
- if (main_h = 0) and ((mapped_text[main_p] = hyphen_char[main_f])
- or (XeTeX_dash_break_en and ((mapped_text[main_p] = @"2014) or (mapped_text[main_p] = @"2013)) ) )
- then main_h := native_len;
- end
- end;
-
- if tracing_lost_chars > 0 then begin
- temp_ptr := 0;
- while (temp_ptr < native_len) do begin
- main_k := native_text[temp_ptr];
- incr(temp_ptr);
- if (main_k >= @"D800) and (main_k < @"DC00) then begin
- main_k := @"10000 + (main_k - @"D800) * 1024;
- main_k := main_k + native_text[temp_ptr] - @"DC00;
- incr(temp_ptr);
- end;
- if map_char_to_glyph(main_f, main_k) = 0 then
- char_warning(main_f, main_k);
- end
- end;
-
- main_k := native_len;
- main_pp := tail;
-
- if mode=hmode then begin
-
- main_ppp := head;
- if main_ppp<>main_pp then { find node preceding tail, skipping discretionaries }
- while (link(main_ppp)<>main_pp) do begin
- if (not is_char_node(main_ppp)) and (type(main_ppp=disc_node)) then begin
- temp_ptr:=main_ppp;
- for main_p:=1 to replace_count(temp_ptr) do main_ppp:=link(main_ppp);
- end;
- if main_ppp<>main_pp then main_ppp:=link(main_ppp);
- end;
-
- temp_ptr := 0;
- repeat
- if main_h = 0 then main_h := main_k;
-
- if is_native_word_node(main_pp)
- and (native_font(main_pp)=main_f)
- and (main_ppp<>main_pp)
- and (not is_char_node(main_ppp))
- and (type(main_ppp)<>disc_node)
- then begin
-
- { make a new temp string that contains the concatenated text of |tail| + the current word/fragment }
- main_k := main_h + native_length(main_pp);
- native_room(main_k);
-
- save_native_len := native_len;
- for main_p := 0 to native_length(main_pp) - 1 do
- append_native(get_native_char(main_pp, main_p));
- for main_p := 0 to main_h - 1 do
- append_native(native_text[temp_ptr + main_p]);
-
- do_locale_linebreaks(save_native_len, main_k);
-
- native_len := save_native_len; { discard the temp string }
- main_k := native_len - main_h - temp_ptr; { and set |main_k| to remaining length of new word }
- temp_ptr := main_h; { pointer to remaining fragment }
-
- main_h := 0;
- while (main_h < main_k) and (native_text[temp_ptr + main_h] <> hyphen_char[main_f])
- and ( (not XeTeX_dash_break_en)
- or ((native_text[temp_ptr + main_h] <> @"2014) and (native_text[temp_ptr + main_h] <> @"2013)) )
- do incr(main_h); { look for next hyphen or end of text }
- if (main_h < main_k) then incr(main_h);
-
- { remove the preceding node from the list }
- link(main_ppp) := link(main_pp);
- link(main_pp) := null;
- flush_node_list(main_pp);
- main_pp := tail;
- while (link(main_ppp)<>main_pp) do
- main_ppp:=link(main_ppp);
-
- end else begin
-
- do_locale_linebreaks(temp_ptr, main_h); { append fragment of current word }
-
- temp_ptr := temp_ptr + main_h; { advance ptr to remaining fragment }
- main_k := main_k - main_h; { decrement remaining length }
-
- main_h := 0;
- while (main_h < main_k) and (native_text[temp_ptr + main_h] <> hyphen_char[main_f])
- and ( (not XeTeX_dash_break_en)
- or ((native_text[temp_ptr + main_h] <> @"2014) and (native_text[temp_ptr + main_h] <> @"2013)) )
- do incr(main_h); { look for next hyphen or end of text }
- if (main_h < main_k) then incr(main_h);
-
- end;
-
- if (main_k > 0) or is_hyph then begin
- tail_append(new_disc); { add a break if we aren't at end of text (must be a hyphen),
- or if last char in original text was a hyphen }
- main_pp:=tail;
- end;
- until main_k = 0;
-
- end else begin
- { must be restricted hmode, so no need for line-breaking or discretionaries }
- { but there might already be explicit |disc_node|s in the list }
- main_ppp := head;
- if main_ppp<>main_pp then { find node preceding tail, skipping discretionaries }
- while (link(main_ppp)<>main_pp) do begin
- if (not is_char_node(main_ppp)) and (type(main_ppp=disc_node)) then begin
- temp_ptr:=main_ppp;
- for main_p:=1 to replace_count(temp_ptr) do main_ppp:=link(main_ppp);
- end;
- if main_ppp<>main_pp then main_ppp:=link(main_ppp);
- end;
- if is_native_word_node(main_pp)
- and (native_font(main_pp)=main_f)
- and (main_ppp<>main_pp)
- and (not is_char_node(main_ppp))
- and (type(main_ppp)<>disc_node)
- then begin
- { total string length for the new merged whatsit }
- link(main_pp) := new_native_word_node(main_f, main_k + native_length(main_pp));
- tail := link(main_pp);
-
- { copy text from the old one into the new }
- for main_p := 0 to native_length(main_pp) - 1 do
- set_native_char(tail, main_p, get_native_char(main_pp, main_p));
- { append the new text }
- for main_p := 0 to main_k - 1 do
- set_native_char(tail, main_p + native_length(main_pp), native_text[main_p]);
- set_native_metrics(tail, XeTeX_use_glyph_metrics);
-
- { remove the preceding node from the list }
- main_p := head;
- if main_p<>main_pp then
- while link(main_p)<>main_pp do
- main_p := link(main_p);
- link(main_p) := link(main_pp);
- link(main_pp) := null;
- flush_node_list(main_pp);
- end else begin
- { package the current string into a |native_word| whatsit }
- link(main_pp) := new_native_word_node(main_f, main_k);
- tail := link(main_pp);
- for main_p := 0 to main_k - 1 do
- set_native_char(tail, main_p, native_text[main_p]);
- set_native_metrics(tail, XeTeX_use_glyph_metrics);
- end
- end;
-
- if cur_ptr<>null then goto big_switch
- else goto reswitch;
+ if (font_mapping[main_f] <> 0) then begin
+ main_k := apply_mapping(font_mapping[main_f], native_text, native_len);
+ native_len := 0;
+ native_room(main_k);
+ main_h := 0;
+ for main_p := 0 to main_k - 1 do begin
+ append_native(mapped_text[main_p]);
+ if (main_h = 0) and ((mapped_text[main_p] = hyphen_char[main_f])
+ or (XeTeX_dash_break_en and ((mapped_text[main_p] = @"2014) or (mapped_text[main_p] = @"2013)) ) )
+ then main_h := native_len;
+ end
+ end;
+
+ if tracing_lost_chars > 0 then begin
+ temp_ptr := 0;
+ while (temp_ptr < native_len) do begin
+ main_k := native_text[temp_ptr];
+ incr(temp_ptr);
+ if (main_k >= @"D800) and (main_k < @"DC00) then begin
+ main_k := @"10000 + (main_k - @"D800) * 1024;
+ main_k := main_k + native_text[temp_ptr] - @"DC00;
+ incr(temp_ptr);
+ end;
+ if map_char_to_glyph(main_f, main_k) = 0 then
+ char_warning(main_f, main_k);
+ end
+ end;
+
+ main_k := native_len;
+ main_pp := tail;
+
+ if mode=hmode then begin
+
+ main_ppp := head;
+ if main_ppp<>main_pp then { find node preceding tail, skipping discretionaries }
+ while (link(main_ppp)<>main_pp) do begin
+ if (not is_char_node(main_ppp)) and (type(main_ppp=disc_node)) then begin
+ temp_ptr:=main_ppp;
+ for main_p:=1 to replace_count(temp_ptr) do main_ppp:=link(main_ppp);
+ end;
+ if main_ppp<>main_pp then main_ppp:=link(main_ppp);
+ end;
+
+ temp_ptr := 0;
+ repeat
+ if main_h = 0 then main_h := main_k;
+
+ if is_native_word_node(main_pp)
+ and (native_font(main_pp)=main_f)
+ and (main_ppp<>main_pp)
+ and (not is_char_node(main_ppp))
+ and (type(main_ppp)<>disc_node)
+ then begin
+
+ { make a new temp string that contains the concatenated text of |tail| + the current word/fragment }
+ main_k := main_h + native_length(main_pp);
+ native_room(main_k);
+
+ save_native_len := native_len;
+ for main_p := 0 to native_length(main_pp) - 1 do
+ append_native(get_native_char(main_pp, main_p));
+ for main_p := 0 to main_h - 1 do
+ append_native(native_text[temp_ptr + main_p]);
+
+ do_locale_linebreaks(save_native_len, main_k);
+
+ native_len := save_native_len; { discard the temp string }
+ main_k := native_len - main_h - temp_ptr; { and set |main_k| to remaining length of new word }
+ temp_ptr := main_h; { pointer to remaining fragment }
+
+ main_h := 0;
+ while (main_h < main_k) and (native_text[temp_ptr + main_h] <> hyphen_char[main_f])
+ and ( (not XeTeX_dash_break_en)
+ or ((native_text[temp_ptr + main_h] <> @"2014) and (native_text[temp_ptr + main_h] <> @"2013)) )
+ do incr(main_h); { look for next hyphen or end of text }
+ if (main_h < main_k) then incr(main_h);
+
+ { remove the preceding node from the list }
+ link(main_ppp) := link(main_pp);
+ link(main_pp) := null;
+ flush_node_list(main_pp);
+ main_pp := tail;
+ while (link(main_ppp)<>main_pp) do
+ main_ppp:=link(main_ppp);
+
+ end else begin
+
+ do_locale_linebreaks(temp_ptr, main_h); { append fragment of current word }
+
+ temp_ptr := temp_ptr + main_h; { advance ptr to remaining fragment }
+ main_k := main_k - main_h; { decrement remaining length }
+
+ main_h := 0;
+ while (main_h < main_k) and (native_text[temp_ptr + main_h] <> hyphen_char[main_f])
+ and ( (not XeTeX_dash_break_en)
+ or ((native_text[temp_ptr + main_h] <> @"2014) and (native_text[temp_ptr + main_h] <> @"2013)) )
+ do incr(main_h); { look for next hyphen or end of text }
+ if (main_h < main_k) then incr(main_h);
+
+ end;
+
+ if (main_k > 0) or is_hyph then begin
+ tail_append(new_disc); { add a break if we aren't at end of text (must be a hyphen),
+ or if last char in original text was a hyphen }
+ main_pp:=tail;
+ end;
+ until main_k = 0;
+
+ end else begin
+ { must be restricted hmode, so no need for line-breaking or discretionaries }
+ { but there might already be explicit |disc_node|s in the list }
+ main_ppp := head;
+ if main_ppp<>main_pp then { find node preceding tail, skipping discretionaries }
+ while (link(main_ppp)<>main_pp) do begin
+ if (not is_char_node(main_ppp)) and (type(main_ppp=disc_node)) then begin
+ temp_ptr:=main_ppp;
+ for main_p:=1 to replace_count(temp_ptr) do main_ppp:=link(main_ppp);
+ end;
+ if main_ppp<>main_pp then main_ppp:=link(main_ppp);
+ end;
+ if is_native_word_node(main_pp)
+ and (native_font(main_pp)=main_f)
+ and (main_ppp<>main_pp)
+ and (not is_char_node(main_ppp))
+ and (type(main_ppp)<>disc_node)
+ then begin
+ { total string length for the new merged whatsit }
+ link(main_pp) := new_native_word_node(main_f, main_k + native_length(main_pp));
+ tail := link(main_pp);
+
+ { copy text from the old one into the new }
+ for main_p := 0 to native_length(main_pp) - 1 do
+ set_native_char(tail, main_p, get_native_char(main_pp, main_p));
+ { append the new text }
+ for main_p := 0 to main_k - 1 do
+ set_native_char(tail, main_p + native_length(main_pp), native_text[main_p]);
+ set_native_metrics(tail, XeTeX_use_glyph_metrics);
+
+ { remove the preceding node from the list }
+ main_p := head;
+ if main_p<>main_pp then
+ while link(main_p)<>main_pp do
+ main_p := link(main_p);
+ link(main_p) := link(main_pp);
+ link(main_pp) := null;
+ flush_node_list(main_pp);
+ end else begin
+ { package the current string into a |native_word| whatsit }
+ link(main_pp) := new_native_word_node(main_f, main_k);
+ tail := link(main_pp);
+ for main_p := 0 to main_k - 1 do
+ set_native_char(tail, main_p, native_text[main_p]);
+ set_native_metrics(tail, XeTeX_use_glyph_metrics);
+ end
+ end;
+
+ if cur_ptr<>null then goto big_switch
+ else goto reswitch;
end;
{ End of added code for native fonts }
@@ -24904,11 +24910,11 @@ var p:pointer; {|char_node| at the tail of the current list}
begin if tail<>head then
begin if is_char_node(tail) then p:=tail
else if type(tail)=ligature_node then p:=lig_char(tail)
- else if (type(tail)=whatsit_node) then begin
- if (subtype(tail)=native_word_node) then begin
+ else if type(tail)=whatsit_node then begin
+ if subtype(tail)=native_word_node then begin
tail_append(new_kern(get_native_italic_correction(tail))); subtype(tail):=explicit;
end
- else if (subtype(tail)=glyph_node) then begin
+ else if subtype(tail)=glyph_node then begin
tail_append(new_kern(get_native_glyph_italic_correction(tail))); subtype(tail):=explicit;
end;
return;
@@ -25007,8 +25013,8 @@ q:=head; p:=link(q); n:=0;
while p<>null do
begin if not is_char_node(p) then if type(p)>rule_node then
if type(p)<>kern_node then if type(p)<>ligature_node then
- if (type(p)<>whatsit_node) or ((subtype(p)<>native_word_node)
- and (subtype(p)<>glyph_node)) then
+ if (type(p)<>whatsit_node) or ((subtype(p)<>native_word_node)
+ and (subtype(p)<>glyph_node)) then
begin print_err("Improper discretionary list");
@.Improper discretionary list@>
help1("Discretionary lists must contain only boxes and kerns.");@/
@@ -25094,7 +25100,7 @@ end;
if h<>x then {the accent must be shifted up or down}
begin p:=hpack(p,natural); shift_amount(p):=x-h;
end;
-if is_native_font(f) and (a=0) then { special case for non-spacing marks }
+if (is_native_font(f)) and (a=0) then { special case for non-spacing marks }
delta:=round((w-lsb+rsb)/float_constant(2)+h*t-x*s)
else delta:=round((w-a)/float_constant(2)+h*t-x*s);
@^real multiplication@>
@@ -26120,11 +26126,11 @@ end;
@ @<Check that the necessary fonts...@>=
if ((font_params[fam_fnt(2+text_size)]<total_mathsy_params)
- and (not is_new_mathfont(fam_fnt(2+text_size)))) or@|
+ and (not (is_new_mathfont(fam_fnt(2+text_size))))) or@|
((font_params[fam_fnt(2+script_size)]<total_mathsy_params)
- and (not is_new_mathfont(fam_fnt(2+script_size)))) or@|
+ and (not (is_new_mathfont(fam_fnt(2+script_size))))) or@|
((font_params[fam_fnt(2+script_script_size)]<total_mathsy_params)
- and (not is_new_mathfont(fam_fnt(2+script_script_size)))) then
+ and (not (is_new_mathfont(fam_fnt(2+script_script_size))))) then
begin print_err("Math formula deleted: Insufficient symbol fonts");@/
@.Math formula deleted...@>
help3("Sorry, but I can't typeset math unless \textfont 2")@/
@@ -26133,11 +26139,11 @@ if ((font_params[fam_fnt(2+text_size)]<total_mathsy_params)
error; flush_math; danger:=true;
end
else if ((font_params[fam_fnt(3+text_size)]<total_mathex_params)
- and (not is_new_mathfont(fam_fnt(3+text_size)))) or@|
+ and (not (is_new_mathfont(fam_fnt(3+text_size))))) or@|
((font_params[fam_fnt(3+script_size)]<total_mathex_params)
- and (not is_new_mathfont(fam_fnt(3+script_size)))) or@|
+ and (not (is_new_mathfont(fam_fnt(3+script_size))))) or@|
((font_params[fam_fnt(3+script_script_size)]<total_mathex_params)
- and (not is_new_mathfont(fam_fnt(3+script_script_size)))) then
+ and (not (is_new_mathfont(fam_fnt(3+script_script_size))))) then
begin print_err("Math formula deleted: Insufficient extension fonts");@/
help3("Sorry, but I can't typeset math unless \textfont 3")@/
("and \scriptfont 3 and \scriptscriptfont 3 have all")@/
@@ -26849,7 +26855,7 @@ XeTeX_def_code: begin
if cur_chr = sf_code_base then begin
p:=cur_chr; scan_usv_num;
p:=p+cur_val;
- n:=sf_code(cur_val) mod @"10000;
+ n:=sf_code(cur_val) mod @"10000;
scan_optional_equals;
scan_char_class;
define(p,data,cur_val*@"10000 + n);
@@ -27307,7 +27313,7 @@ the new name becomes the font identifier of record. Font names `\.{xyz}' and
flushable_string:=str_ptr-1;
for f:=font_base+1 to font_ptr do begin
if str_eq_str(font_name[f],cur_name) and
- (((cur_area = "") and is_native_font(f)) or str_eq_str(font_area[f],cur_area)) then
+ (((cur_area = "") and (is_native_font(f))) or str_eq_str(font_area[f],cur_area)) then
begin if cur_name=flushable_string then
begin flush_string; cur_name:=font_name[f];
end;
@@ -28712,11 +28718,10 @@ p:=scan_toks(false,true); write_tokens(tail):=def_ref;
end
@ @d call_func(#) == begin if # <> 0 then do_nothing end
-@d flushable(#) == (# = str_ptr - 1)
@p procedure flush_str(s: str_number); {flush a string if possible}
begin
- if flushable(s) then
+ if s = str_ptr-1 then
flush_string;
end;
@@ -28787,22 +28792,22 @@ end;
procedure print_native_word(@!p:pointer);
var i,c,cc:integer;
begin
- for i:=0 to native_length(p) - 1 do begin
- c:=get_native_char(p,i);
- if (c >= @"D800) and (c <= @"DBFF) then begin
- if i < native_length(p) - 1 then begin
- cc:=get_native_char(p, i+1);
- if (cc >= @"DC00) and (cc <= @"DFFF) then begin
- c := @"10000 + (c - @"D800) * @"400 + (cc - @"DC00);
- print_char(c);
- incr(i);
- end else
- print(".");
- end else
- print(".");
- end else
- print_char(c);
- end
+ for i:=0 to native_length(p) - 1 do begin
+ c:=get_native_char(p,i);
+ if (c >= @"D800) and (c <= @"DBFF) then begin
+ if i < native_length(p) - 1 then begin
+ cc:=get_native_char(p, i+1);
+ if (cc >= @"DC00) and (cc <= @"DFFF) then begin
+ c := @"10000 + (c - @"D800) * @"400 + (cc - @"DC00);
+ print_char(c);
+ incr(i);
+ end else
+ print(".");
+ end else
+ print(".");
+ end else
+ print_char(c);
+ end
end;
@ @<Display the whatsit...@>=
@@ -28823,9 +28828,9 @@ language_node:begin print_esc("setlanguage");
print_int(what_rhm(p)); print_char(")");
end;
native_word_node:begin
- print_esc(font_id_text(native_font(p)));
- print_char(" ");
- print_native_word(p);
+ print_esc(font_id_text(native_font(p)));
+ print_char(" ");
+ print_native_word(p);
end;
glyph_node:begin
print_esc(font_id_text(native_font(p)));
@@ -28833,12 +28838,12 @@ glyph_node:begin
print_int(native_glyph(p));
end;
pic_node,pdf_node: begin
- if subtype(p) = pic_node then print_esc("XeTeXpicfile")
- else print_esc("XeTeXpdffile");
- print(" """);
- for i:=0 to pic_path_length(p)-1 do
- print_visible_char(pic_path_byte(p, i));
- print("""");
+ if subtype(p) = pic_node then print_esc("XeTeXpicfile")
+ else print_esc("XeTeXpdffile");
+ print(" """);
+ for i:=0 to pic_path_length(p)-1 do
+ print_visible_char(pic_path_byte(p, i));
+ print("""");
end;
pdf_save_pos_node: print_esc("pdfsavepos");
othercases print("whatsit?")
@@ -28896,107 +28901,107 @@ end
@ @<Incorporate a whatsit node into a vbox@>=
begin
- if (subtype(p)=pic_node)
- or (subtype(p)=pdf_node)
- then begin
- x := x + d + height(p);
- d := depth(p);
- if width(p) > w then w := width(p);
- end;
+ if (subtype(p)=pic_node)
+ or (subtype(p)=pdf_node)
+ then begin
+ x := x + d + height(p);
+ d := depth(p);
+ if width(p) > w then w := width(p);
+ end;
end
@ @<Incorporate a whatsit node into an hbox@>=
begin
- case subtype(p) of
-
- native_word_node:
- begin
- { merge with any following word fragments in same font, discarding discretionary breaks }
- if type(q) = disc_node then k:=replace_count(q) else k:=0;
- while (link(q) <> p) do begin
- decr(k);
- q := link(q); { bring q up in preparation for deletion of nodes starting at p }
- if type(q) = disc_node then k:=replace_count(q);
- end;
- pp := link(p);
- restart:
- if (k <= 0) and (pp <> null) and (not is_char_node(pp)) then begin
- if (type(pp) = whatsit_node)
- and (subtype(pp) = native_word_node)
- and (native_font(pp) = native_font(p)) then begin
- pp := link(pp);
- goto restart;
- end
- else if (type(pp) = disc_node) then begin
- ppp := link(pp);
- if is_native_word_node(ppp)
- and (native_font(ppp) = native_font(p)) then begin
- pp := link(ppp);
- goto restart;
- end
- end
- end;
-
- { now pp points to the non-|native_word| node that ended the chain, or null }
-
- { we can just check type(p)=|whatsit_node| below, as we know that the chain
- contains only discretionaries and |native_word| nodes, no other whatsits or |char_node|s }
-
- if (pp <> link(p)) then begin
- { found a chain of at least two pieces starting at p }
- total_chars := 0;
- p := link(q); { the first fragment }
- while (p <> pp) do begin
- if (type(p) = whatsit_node) then
- total_chars := total_chars + native_length(p); { accumulate char count }
- ppp := p; { remember last node seen }
- p := link(p); { point to next fragment or discretionary or terminator }
- end;
-
- p := link(q); { the first fragment again }
- pp := new_native_word_node(native_font(p), total_chars); { make new node for merged word }
- link(q) := pp; { link to preceding material }
- link(pp) := link(ppp); { attach remainder of hlist to it }
- link(ppp) := null; { and detach from the old fragments }
-
- { copy the chars into new node }
- total_chars := 0;
- ppp := p;
- repeat
- if (type(ppp) = whatsit_node) then
- for k := 0 to native_length(ppp)-1 do begin
- set_native_char(pp, total_chars, get_native_char(ppp, k));
- incr(total_chars);
- end;
- ppp := link(ppp);
- until (ppp = null);
-
- flush_node_list(p); { delete the fragments }
- p := link(q); { update p to point to the new node }
- set_native_metrics(p, XeTeX_use_glyph_metrics); { and measure it (i.e., re-do the OT layout) }
- end;
-
- { now incorporate the |native_word| node measurements into the box we're packing }
- if height(p) > h then
- h := height(p);
- if depth(p) > d then
- d := depth(p);
- x := x + width(p);
- end;
-
- glyph_node, pic_node, pdf_node:
- begin
- if height(p) > h then
- h := height(p);
- if depth(p) > d then
- d := depth(p);
- x := x + width(p);
- end;
-
- othercases
- do_nothing
-
- endcases
+ case subtype(p) of
+
+ native_word_node:
+ begin
+ { merge with any following word fragments in same font, discarding discretionary breaks }
+ if type(q) = disc_node then k:=replace_count(q) else k:=0;
+ while (link(q) <> p) do begin
+ decr(k);
+ q := link(q); { bring q up in preparation for deletion of nodes starting at p }
+ if type(q) = disc_node then k:=replace_count(q);
+ end;
+ pp := link(p);
+ restart:
+ if (k <= 0) and (pp <> null) and (not is_char_node(pp)) then begin
+ if (type(pp) = whatsit_node)
+ and (subtype(pp) = native_word_node)
+ and (native_font(pp) = native_font(p)) then begin
+ pp := link(pp);
+ goto restart;
+ end
+ else if type(pp) = disc_node then begin
+ ppp := link(pp);
+ if is_native_word_node(ppp)
+ and (native_font(ppp) = native_font(p)) then begin
+ pp := link(ppp);
+ goto restart;
+ end
+ end
+ end;
+
+ { now pp points to the non-|native_word| node that ended the chain, or null }
+
+ { we can just check type(p)=|whatsit_node| below, as we know that the chain
+ contains only discretionaries and |native_word| nodes, no other whatsits or |char_node|s }
+
+ if (pp <> link(p)) then begin
+ { found a chain of at least two pieces starting at p }
+ total_chars := 0;
+ p := link(q); { the first fragment }
+ while p <> pp do begin
+ if type(p) = whatsit_node then
+ total_chars := total_chars + native_length(p); { accumulate char count }
+ ppp := p; { remember last node seen }
+ p := link(p); { point to next fragment or discretionary or terminator }
+ end;
+
+ p := link(q); { the first fragment again }
+ pp := new_native_word_node(native_font(p), total_chars); { make new node for merged word }
+ link(q) := pp; { link to preceding material }
+ link(pp) := link(ppp); { attach remainder of hlist to it }
+ link(ppp) := null; { and detach from the old fragments }
+
+ { copy the chars into new node }
+ total_chars := 0;
+ ppp := p;
+ repeat
+ if type(ppp) = whatsit_node then
+ for k := 0 to native_length(ppp)-1 do begin
+ set_native_char(pp, total_chars, get_native_char(ppp, k));
+ incr(total_chars);
+ end;
+ ppp := link(ppp);
+ until (ppp = null);
+
+ flush_node_list(p); { delete the fragments }
+ p := link(q); { update p to point to the new node }
+ set_native_metrics(p, XeTeX_use_glyph_metrics); { and measure it (i.e., re-do the OT layout) }
+ end;
+
+ { now incorporate the |native_word| node measurements into the box we're packing }
+ if height(p) > h then
+ h := height(p);
+ if depth(p) > d then
+ d := depth(p);
+ x := x + width(p);
+ end;
+
+ glyph_node, pic_node, pdf_node:
+ begin
+ if height(p) > h then
+ h := height(p);
+ if depth(p) > d then
+ d := depth(p);
+ x := x + width(p);
+ end;
+
+ othercases
+ do_nothing
+
+ endcases
end
@ @<Let |d| be the width of the whatsit |p|, and |goto found| if ``visible''@>=
@@ -29005,8 +29010,8 @@ or (subtype(p)=glyph_node)
or (subtype(p)=pic_node)
or (subtype(p)=pdf_node)
then begin
- d:=width(p);
- goto found;
+ d:=width(p);
+ goto found;
end else
d := 0
@@ -29034,67 +29039,67 @@ adv_past_prehyph(s)
@ @<Prepare to move whatsit |p| to the current page, then |goto contribute|@>=
begin
- if (subtype(p)=pic_node)
- or (subtype(p)=pdf_node)
- then begin
- page_total := page_total + page_depth + height(p);
- page_depth := depth(p);
- end;
- goto contribute;
+ if (subtype(p)=pic_node)
+ or (subtype(p)=pdf_node)
+ then begin
+ page_total := page_total + page_depth + height(p);
+ page_depth := depth(p);
+ end;
+ goto contribute;
end
@ @<Process whatsit |p| in |vert_break| loop, |goto not_found|@>=
begin
- if (subtype(p)=pic_node)
- or (subtype(p)=pdf_node)
- then begin
- cur_height := cur_height + prev_dp + height(p); prev_dp := depth(p);
- end;
- goto not_found;
+ if (subtype(p)=pic_node)
+ or (subtype(p)=pdf_node)
+ then begin
+ cur_height := cur_height + prev_dp + height(p); prev_dp := depth(p);
+ end;
+ goto not_found;
end
@ @<Output the whatsit node |p| in a vlist@>=
begin
- case subtype(p) of
- glyph_node: begin
- cur_v:=cur_v+height(p);
- cur_h:=left_edge;
-
- { synch DVI state to TeX state }
- synch_h; synch_v;
- f := native_font(p);
- if f<>dvi_f then @<Change font |dvi_f| to |f|@>;
-
- dvi_out(set_glyph_string);
- dvi_four(0); { width }
- dvi_two(1); { glyph count }
- dvi_four(0); { x-offset as fixed point }
- dvi_two(native_glyph(p));
-
- cur_v:=cur_v+depth(p);
- cur_h:=left_edge;
- end;
- pic_node, pdf_node: begin
- save_h:=dvi_h; save_v:=dvi_v;
- cur_v:=cur_v+height(p);
- pic_out(p, subtype(p) = pdf_node);
- dvi_h:=save_h; dvi_v:=save_v;
- cur_v:=save_v+depth(p); cur_h:=left_edge;
- end;
-
- pdf_save_pos_node:
- @<Save current position to |pdf_last_x_pos|, |pdf_last_y_pos|@>;
-
- othercases
- out_what(p)
-
- endcases
+ case subtype(p) of
+ glyph_node: begin
+ cur_v:=cur_v+height(p);
+ cur_h:=left_edge;
+
+ { synch DVI state to TeX state }
+ synch_h; synch_v;
+ f := native_font(p);
+ if f<>dvi_f then @<Change font |dvi_f| to |f|@>;
+
+ dvi_out(set_glyph_string);
+ dvi_four(0); { width }
+ dvi_two(1); { glyph count }
+ dvi_four(0); { x-offset as fixed point }
+ dvi_two(native_glyph(p));
+
+ cur_v:=cur_v+depth(p);
+ cur_h:=left_edge;
+ end;
+ pic_node, pdf_node: begin
+ save_h:=dvi_h; save_v:=dvi_v;
+ cur_v:=cur_v+height(p);
+ pic_out(p, subtype(p) = pdf_node);
+ dvi_h:=save_h; dvi_v:=save_v;
+ cur_v:=save_v+depth(p); cur_h:=left_edge;
+ end;
+
+ pdf_save_pos_node:
+ @<Save current position to |pdf_last_x_pos|, |pdf_last_y_pos|@>;
+
+ othercases
+ out_what(p)
+
+ endcases
end
@ @<Save current position to |pdf_last_x_pos|, |pdf_last_y_pos|@>=
begin
pdf_last_x_pos := cur_h + cur_h_offset;
- pdf_last_y_pos := cur_page_height - cur_v - cur_v_offset
+ pdf_last_y_pos := cur_page_height - cur_v - cur_v_offset
end
@ @<Calculate page dimensions and margins@>=
@@ -29117,49 +29122,49 @@ else
@ @<Output the whatsit node |p| in an hlist@>=
begin
- case subtype(p) of
- native_word_node, glyph_node: begin
- { synch DVI state to TeX state }
- synch_h; synch_v;
- f := native_font(p);
- if f<>dvi_f then @<Change font |dvi_f| to |f|@>;
-
- if subtype(p) = glyph_node then begin
- dvi_out(set_glyph_string);
- dvi_four(width(p));
- dvi_two(1); { glyph count }
- dvi_four(0); { x-offset as fixed point }
- dvi_two(native_glyph(p));
- cur_h := cur_h + width(p);
- end else begin
- if native_glyph_info_ptr(p) <> null_ptr then begin
- len := make_xdv_glyph_array_data(p);
- for k := 0 to len-1 do
- dvi_out(xdv_buffer_byte(k));
- end;
- cur_h := cur_h + width(p);
- end;
-
- dvi_h := cur_h;
- end;
-
- pic_node, pdf_node: begin
- save_h:=dvi_h; save_v:=dvi_v;
- cur_v:=base_line;
- edge:=cur_h+width(p);
- if cur_dir=right_to_left then cur_h:=edge;
- pic_out(p, subtype(p) = pdf_node);
- dvi_h:=save_h; dvi_v:=save_v;
- cur_h:=edge; cur_v:=base_line;
- end;
-
- pdf_save_pos_node:
- @<Save current position to |pdf_last_x_pos|, |pdf_last_y_pos|@>;
-
- othercases
- out_what(p)
-
- endcases
+ case subtype(p) of
+ native_word_node, glyph_node: begin
+ { synch DVI state to TeX state }
+ synch_h; synch_v;
+ f := native_font(p);
+ if f<>dvi_f then @<Change font |dvi_f| to |f|@>;
+
+ if subtype(p) = glyph_node then begin
+ dvi_out(set_glyph_string);
+ dvi_four(width(p));
+ dvi_two(1); { glyph count }
+ dvi_four(0); { x-offset as fixed point }
+ dvi_two(native_glyph(p));
+ cur_h := cur_h + width(p);
+ end else begin
+ if native_glyph_info_ptr(p) <> null_ptr then begin
+ len := make_xdv_glyph_array_data(p);
+ for k := 0 to len-1 do
+ dvi_out(xdv_buffer_byte(k));
+ end;
+ cur_h := cur_h + width(p);
+ end;
+
+ dvi_h := cur_h;
+ end;
+
+ pic_node, pdf_node: begin
+ save_h:=dvi_h; save_v:=dvi_v;
+ cur_v:=base_line;
+ edge:=cur_h+width(p);
+ if cur_dir=right_to_left then cur_h:=edge;
+ pic_out(p, subtype(p) = pdf_node);
+ dvi_h:=save_h; dvi_v:=save_v;
+ cur_h:=edge; cur_v:=base_line;
+ end;
+
+ pdf_save_pos_node:
+ @<Save current position to |pdf_last_x_pos|, |pdf_last_y_pos|@>;
+
+ othercases
+ out_what(p)
+
+ endcases
end
@ After all this preliminary shuffling, we come finally to the routines
@@ -29263,9 +29268,9 @@ begin
synch_h; synch_v;
dvi_out(pic_file);
if is_pdf then
- dvi_out(pic_box_type(p))
+ dvi_out(pic_box_type(p))
else
- dvi_out(0);
+ dvi_out(0);
dvi_four(pic_transform1(p));
dvi_four(pic_transform2(p));
dvi_four(pic_transform3(p));
@@ -29395,224 +29400,224 @@ end
@ Load a picture file and handle following keywords.
@d calc_min_and_max==
- begin
- xmin := 1000000.0;
- xmax := -xmin;
- ymin := xmin;
- ymax := xmax;
- for i := 0 to 3 do begin
- if xCoord(corners[i]) < xmin then xmin := xCoord(corners[i]);
- if xCoord(corners[i]) > xmax then xmax := xCoord(corners[i]);
- if yCoord(corners[i]) < ymin then ymin := yCoord(corners[i]);
- if yCoord(corners[i]) > ymax then ymax := yCoord(corners[i]);
- end;
- end
+ begin
+ xmin := 1000000.0;
+ xmax := -xmin;
+ ymin := xmin;
+ ymax := xmax;
+ for i := 0 to 3 do begin
+ if xCoord(corners[i]) < xmin then xmin := xCoord(corners[i]);
+ if xCoord(corners[i]) > xmax then xmax := xCoord(corners[i]);
+ if yCoord(corners[i]) < ymin then ymin := yCoord(corners[i]);
+ if yCoord(corners[i]) > ymax then ymax := yCoord(corners[i]);
+ end;
+ end
@d update_corners==
- for i := 0 to 3 do
- transform_point(addressof(corners[i]), addressof(t2))
+ for i := 0 to 3 do
+ transform_point(addressof(corners[i]), addressof(t2))
@d do_size_requests==begin
- { calculate current width and height }
- calc_min_and_max;
- if x_size_req = 0.0 then begin
- make_scale(addressof(t2), y_size_req / (ymax - ymin), y_size_req / (ymax - ymin));
- end else if y_size_req = 0.0 then begin
- make_scale(addressof(t2), x_size_req / (xmax - xmin), x_size_req / (xmax - xmin));
- end else begin
- make_scale(addressof(t2), x_size_req / (xmax - xmin), y_size_req / (ymax - ymin));
- end;
- update_corners;
- x_size_req := 0.0;
- y_size_req := 0.0;
- transform_concat(addressof(t), addressof(t2));
+ { calculate current width and height }
+ calc_min_and_max;
+ if x_size_req = 0.0 then begin
+ make_scale(addressof(t2), y_size_req / (ymax - ymin), y_size_req / (ymax - ymin));
+ end else if y_size_req = 0.0 then begin
+ make_scale(addressof(t2), x_size_req / (xmax - xmin), x_size_req / (xmax - xmin));
+ end else begin
+ make_scale(addressof(t2), x_size_req / (xmax - xmin), y_size_req / (ymax - ymin));
+ end;
+ update_corners;
+ x_size_req := 0.0;
+ y_size_req := 0.0;
+ transform_concat(addressof(t), addressof(t2));
end
@<Declare procedures needed in |do_extension|@>=
procedure load_picture(@!is_pdf:boolean);
var
- pic_path: ^char;
- bounds: real_rect;
- t, t2: transform;
- corners: array[0..3] of real_point;
- x_size_req,y_size_req: real;
- check_keywords: boolean;
- xmin,xmax,ymin,ymax: real;
- i: small_number;
- page: integer;
- pdf_box_type: integer;
- result: integer;
+ pic_path: ^char;
+ bounds: real_rect;
+ t, t2: transform;
+ corners: array[0..3] of real_point;
+ x_size_req,y_size_req: real;
+ check_keywords: boolean;
+ xmin,xmax,ymin,ymax: real;
+ i: small_number;
+ page: integer;
+ pdf_box_type: integer;
+ result: integer;
begin
- { scan the filename and pack into |name_of_file| }
- scan_file_name;
- pack_cur_name;
+ { scan the filename and pack into |name_of_file| }
+ scan_file_name;
+ pack_cur_name;
pdf_box_type := 0;
- page := 0;
- if is_pdf then begin
- if scan_keyword("page") then begin
- scan_int;
- page := cur_val;
- end;
- pdf_box_type := pdfbox_crop;
- if scan_keyword("crop") then do_nothing
- else if scan_keyword("media") then pdf_box_type := pdfbox_media
- else if scan_keyword("bleed") then pdf_box_type := pdfbox_bleed
- else if scan_keyword("trim") then pdf_box_type := pdfbox_trim
- else if scan_keyword("art") then pdf_box_type := pdfbox_art;
- end;
-
- { access the picture file and check its size }
- result := find_pic_file(addressof(pic_path), addressof(bounds), pdf_box_type, page);
-
- setPoint(corners[0], xField(bounds), yField(bounds));
- setPoint(corners[1], xField(corners[0]), yField(bounds) + htField(bounds));
- setPoint(corners[2], xField(bounds) + wdField(bounds), yField(corners[1]));
- setPoint(corners[3], xField(corners[2]), yField(corners[0]));
-
- x_size_req := 0.0;
- y_size_req := 0.0;
-
- { look for any scaling requests for this picture }
- make_identity(addressof(t));
-
- check_keywords := true;
- while check_keywords do begin
- if scan_keyword("scaled") then begin
- scan_int;
- if (x_size_req = 0.0) and (y_size_req = 0.0) then begin
- make_scale(addressof(t2), float(cur_val) / 1000.0, float(cur_val) / 1000.0);
- update_corners;
- transform_concat(addressof(t), addressof(t2));
- end
- end else if scan_keyword("xscaled") then begin
- scan_int;
- if (x_size_req = 0.0) and (y_size_req = 0.0) then begin
- make_scale(addressof(t2), float(cur_val) / 1000.0, 1.0);
- update_corners;
- transform_concat(addressof(t), addressof(t2));
- end
- end else if scan_keyword("yscaled") then begin
- scan_int;
- if (x_size_req = 0.0) and (y_size_req = 0.0) then begin
- make_scale(addressof(t2), 1.0, float(cur_val) / 1000.0);
- update_corners;
- transform_concat(addressof(t), addressof(t2));
- end
- end else if scan_keyword("width") then begin
- scan_normal_dimen;
- if cur_val <= 0 then begin
- print_err("Improper image ");
- print("size (");
- print_scaled(cur_val);
- print("pt) will be ignored");
- help2("I can't scale images to zero or negative sizes,")@/
- ("so I'm ignoring this.");
- error;
- end else
- x_size_req := Fix2D(cur_val);
- end else if scan_keyword("height") then begin
- scan_normal_dimen;
- if cur_val <= 0 then begin
- print_err("Improper image ");
- print("size (");
- print_scaled(cur_val);
- print("pt) will be ignored");
- help2("I can't scale images to zero or negative sizes,")@/
- ("so I'm ignoring this.");
- error;
- end else
- y_size_req := Fix2D(cur_val);
- end else if scan_keyword("rotated") then begin
- scan_decimal;
- if (x_size_req <> 0.0) or (y_size_req <> 0.0) then do_size_requests;
- make_rotation(addressof(t2), Fix2D(cur_val) * 3.141592653589793 / 180.0);
- update_corners;
- calc_min_and_max;
- setPoint(corners[0], xmin, ymin);
- setPoint(corners[1], xmin, ymax);
- setPoint(corners[2], xmax, ymax);
- setPoint(corners[3], xmax, ymin);
- transform_concat(addressof(t), addressof(t2));
- end else
- check_keywords := false;
- end;
-
- if (x_size_req <> 0.0) or (y_size_req <> 0.0) then do_size_requests;
-
- calc_min_and_max;
- make_translation(addressof(t2), -xmin * 72 / 72.27, -ymin * 72 / 72.27);
- transform_concat(addressof(t), addressof(t2));
-
- if result = 0 then begin
-
- new_whatsit(pic_node, pic_node_size + (strlen(pic_path) + sizeof(memory_word) - 1) div sizeof(memory_word));
- if is_pdf then begin
- subtype(tail) := pdf_node;
- pic_box_type(tail) := pdf_box_type;
- end;
- pic_path_length(tail) := strlen(pic_path);
- pic_page(tail) := page;
-
- width(tail) := D2Fix(xmax - xmin);
- height(tail) := D2Fix(ymax - ymin);
- depth(tail) := 0;
-
- pic_transform1(tail) := D2Fix(aField(t));
- pic_transform2(tail) := D2Fix(bField(t));
- pic_transform3(tail) := D2Fix(cField(t));
- pic_transform4(tail) := D2Fix(dField(t));
- pic_transform5(tail) := D2Fix(xField(t));
- pic_transform6(tail) := D2Fix(yField(t));
-
- memcpy(addressof(mem[tail + pic_node_size]), pic_path, strlen(pic_path));
- libc_free(pic_path);
-
- end else begin
-
- print_err("Unable to load picture or PDF file '");
- print_file_name(cur_name,cur_area,cur_ext); print("'");
- if result = -43 then begin { Mac OS file not found error }
- help2("The requested image couldn't be read because")@/
- ("the file was not found.");
- end
- else begin { otherwise assume GraphicImport failed }
- help2("The requested image couldn't be read because")@/
- ("it was not a recognized image format.");
- end;
- error;
-
- end;
+ page := 0;
+ if is_pdf then begin
+ if scan_keyword("page") then begin
+ scan_int;
+ page := cur_val;
+ end;
+ pdf_box_type := pdfbox_crop;
+ if scan_keyword("crop") then do_nothing
+ else if scan_keyword("media") then pdf_box_type := pdfbox_media
+ else if scan_keyword("bleed") then pdf_box_type := pdfbox_bleed
+ else if scan_keyword("trim") then pdf_box_type := pdfbox_trim
+ else if scan_keyword("art") then pdf_box_type := pdfbox_art;
+ end;
+
+ { access the picture file and check its size }
+ result := find_pic_file(addressof(pic_path), addressof(bounds), pdf_box_type, page);
+
+ setPoint(corners[0], xField(bounds), yField(bounds));
+ setPoint(corners[1], xField(corners[0]), yField(bounds) + htField(bounds));
+ setPoint(corners[2], xField(bounds) + wdField(bounds), yField(corners[1]));
+ setPoint(corners[3], xField(corners[2]), yField(corners[0]));
+
+ x_size_req := 0.0;
+ y_size_req := 0.0;
+
+ { look for any scaling requests for this picture }
+ make_identity(addressof(t));
+
+ check_keywords := true;
+ while check_keywords do begin
+ if scan_keyword("scaled") then begin
+ scan_int;
+ if (x_size_req = 0.0) and (y_size_req = 0.0) then begin
+ make_scale(addressof(t2), float(cur_val) / 1000.0, float(cur_val) / 1000.0);
+ update_corners;
+ transform_concat(addressof(t), addressof(t2));
+ end
+ end else if scan_keyword("xscaled") then begin
+ scan_int;
+ if (x_size_req = 0.0) and (y_size_req = 0.0) then begin
+ make_scale(addressof(t2), float(cur_val) / 1000.0, 1.0);
+ update_corners;
+ transform_concat(addressof(t), addressof(t2));
+ end
+ end else if scan_keyword("yscaled") then begin
+ scan_int;
+ if (x_size_req = 0.0) and (y_size_req = 0.0) then begin
+ make_scale(addressof(t2), 1.0, float(cur_val) / 1000.0);
+ update_corners;
+ transform_concat(addressof(t), addressof(t2));
+ end
+ end else if scan_keyword("width") then begin
+ scan_normal_dimen;
+ if cur_val <= 0 then begin
+ print_err("Improper image ");
+ print("size (");
+ print_scaled(cur_val);
+ print("pt) will be ignored");
+ help2("I can't scale images to zero or negative sizes,")@/
+ ("so I'm ignoring this.");
+ error;
+ end else
+ x_size_req := Fix2D(cur_val);
+ end else if scan_keyword("height") then begin
+ scan_normal_dimen;
+ if cur_val <= 0 then begin
+ print_err("Improper image ");
+ print("size (");
+ print_scaled(cur_val);
+ print("pt) will be ignored");
+ help2("I can't scale images to zero or negative sizes,")@/
+ ("so I'm ignoring this.");
+ error;
+ end else
+ y_size_req := Fix2D(cur_val);
+ end else if scan_keyword("rotated") then begin
+ scan_decimal;
+ if (x_size_req <> 0.0) or (y_size_req <> 0.0) then do_size_requests;
+ make_rotation(addressof(t2), Fix2D(cur_val) * 3.141592653589793 / 180.0);
+ update_corners;
+ calc_min_and_max;
+ setPoint(corners[0], xmin, ymin);
+ setPoint(corners[1], xmin, ymax);
+ setPoint(corners[2], xmax, ymax);
+ setPoint(corners[3], xmax, ymin);
+ transform_concat(addressof(t), addressof(t2));
+ end else
+ check_keywords := false;
+ end;
+
+ if (x_size_req <> 0.0) or (y_size_req <> 0.0) then do_size_requests;
+
+ calc_min_and_max;
+ make_translation(addressof(t2), -xmin * 72 / 72.27, -ymin * 72 / 72.27);
+ transform_concat(addressof(t), addressof(t2));
+
+ if result = 0 then begin
+
+ new_whatsit(pic_node, pic_node_size + (strlen(pic_path) + sizeof(memory_word) - 1) div sizeof(memory_word));
+ if is_pdf then begin
+ subtype(tail) := pdf_node;
+ pic_box_type(tail) := pdf_box_type;
+ end;
+ pic_path_length(tail) := strlen(pic_path);
+ pic_page(tail) := page;
+
+ width(tail) := D2Fix(xmax - xmin);
+ height(tail) := D2Fix(ymax - ymin);
+ depth(tail) := 0;
+
+ pic_transform1(tail) := D2Fix(aField(t));
+ pic_transform2(tail) := D2Fix(bField(t));
+ pic_transform3(tail) := D2Fix(cField(t));
+ pic_transform4(tail) := D2Fix(dField(t));
+ pic_transform5(tail) := D2Fix(xField(t));
+ pic_transform6(tail) := D2Fix(yField(t));
+
+ memcpy(addressof(mem[tail + pic_node_size]), pic_path, strlen(pic_path));
+ libc_free(pic_path);
+
+ end else begin
+
+ print_err("Unable to load picture or PDF file '");
+ print_file_name(cur_name,cur_area,cur_ext); print("'");
+ if result = -43 then begin { Mac OS file not found error }
+ help2("The requested image couldn't be read because")@/
+ ("the file was not found.");
+ end
+ else begin { otherwise assume GraphicImport failed }
+ help2("The requested image couldn't be read because")@/
+ ("it was not a recognized image format.");
+ end;
+ error;
+
+ end;
end;
@ @<Implement \.{\\XeTeXinputencoding}@>=
begin
- scan_and_pack_name; {scan a filename-like arg for the input encoding}
+ scan_and_pack_name; {scan a filename-like arg for the input encoding}
- i := get_encoding_mode_and_info(addressof(j)); {convert it to |mode| and |encoding| values}
- if i = XeTeX_input_mode_auto then begin
- print_err("Encoding mode `auto' is not valid for \XeTeXinputencoding");
+ i := get_encoding_mode_and_info(addressof(j)); {convert it to |mode| and |encoding| values}
+ if i = XeTeX_input_mode_auto then begin
+ print_err("Encoding mode `auto' is not valid for \XeTeXinputencoding");
help2("You can't use `auto' encoding here, only for \XeTeXdefaultencoding.")@/
("I'll ignore this and leave the current encoding unchanged.");@/
- error;
- end else set_input_file_encoding(input_file[in_open], i, j); {apply them to the current input file}
+ error;
+ end else set_input_file_encoding(input_file[in_open], i, j); {apply them to the current input file}
end
@ @<Implement \.{\\XeTeXdefaultencoding}@>=
begin
- scan_and_pack_name; {scan a filename-like arg for the input encoding}
+ scan_and_pack_name; {scan a filename-like arg for the input encoding}
- i := get_encoding_mode_and_info(addressof(j)); {convert it to |mode| and |encoding| values}
- XeTeX_default_input_mode := i; {store them as defaults for new input files}
- XeTeX_default_input_encoding := j;
+ i := get_encoding_mode_and_info(addressof(j)); {convert it to |mode| and |encoding| values}
+ XeTeX_default_input_mode := i; {store them as defaults for new input files}
+ XeTeX_default_input_encoding := j;
end
@ @<Implement \.{\\XeTeXlinebreaklocale}@>=
begin
- scan_file_name; {scan a filename-like arg for the locale name}
- if length(cur_name) = 0 then XeTeX_linebreak_locale := 0
- else XeTeX_linebreak_locale := cur_name; {we ignore the area and extension!}
+ scan_file_name; {scan a filename-like arg for the locale name}
+ if length(cur_name) = 0 then XeTeX_linebreak_locale := 0
+ else XeTeX_linebreak_locale := cur_name; {we ignore the area and extension!}
end
@ @<Glob...@>=
@@ -30084,7 +30089,7 @@ XeTeX_variation_name_code:
XeTeX_feature_name_code:
begin
scan_font_ident; fnt:=cur_val;
- if is_aat_font(fnt) or is_gr_font(fnt) then begin
+ if (is_aat_font(fnt)) or (is_gr_font(fnt)) then begin
scan_int; arg1:=cur_val; arg2:=0;
end else
not_aat_gr_font_error(convert, c, fnt);
@@ -30093,7 +30098,7 @@ XeTeX_feature_name_code:
XeTeX_selector_name_code:
begin
scan_font_ident; fnt:=cur_val;
- if is_aat_font(fnt) or is_gr_font(fnt) then begin
+ if (is_aat_font(fnt)) or (is_gr_font(fnt)) then begin
scan_int; arg1:=cur_val; scan_int; arg2:=cur_val;
end else
not_aat_gr_font_error(convert, c, fnt);
@@ -30165,7 +30170,7 @@ right_margin_kern_code: begin
print("pt");
end;
-@ @d eTeX_ex==(eTeX_mode=1) {is this extended mode?}
+@ @d eTeX_ex==eTeX_mode=1 {is this extended mode?}
@<Glob...@>=
@!eTeX_mode: 0..1; {identifies compatibility and extended mode}
diff --git a/Build/source/texk/web2c/xetexdir/xetexextra.h b/Build/source/texk/web2c/xetexdir/xetexextra.h
index 0751fbfe4d8..6fb91423fa0 100644
--- a/Build/source/texk/web2c/xetexdir/xetexextra.h
+++ b/Build/source/texk/web2c/xetexdir/xetexextra.h
@@ -57,7 +57,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <xetexdir/xetex_version.h> /* for XETEX_VERSION */
#define BANNER "This is XeTeX, Version 3.14159265-" ETEX_VERSION "-" XETEX_VERSION
-#define COPYRIGHT_HOLDER "SIL International and Jonathan Kew"
+#define COPYRIGHT_HOLDER "SIL International, Jonathan Kew and Khaled Hosny"
#define AUTHOR "Jonathan Kew"
#define PROGRAM_HELP XETEXHELP
#define BUG_ADDRESS "xetex@tug.org"