int get_ot_math_kern(int f, int g, int sf, int sg, int cmd, int shift) { 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 (cmd == sup_cmd) { // superscript corr_height_top = font->pointsToUnits(glyph_height(f, g)); corr_height_bot = -font->pointsToUnits(glyph_depth(sf, sg) + Fix2D(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_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) - Fix2D(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_bot); skern = getMathKernAt(sf, sg, topLeft, corr_height_bot); if ((kern + skern) < rval) rval = kern + skern; } else { assert(0); // we should not reach here } return D2Fix(font->unitsToPoints(rval)); } return 0; }
XeTeXFont createFont(PlatformFontRef fontRef, Fixed pointSize) { int status = 0; #ifdef XETEX_MAC 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); #endif 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; }
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); } }
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, pathname, index, &m_ftFace); if (error) { status = 1; return; } if (!FT_IS_SCALABLE(m_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(m_ftFace)) { char* afm = xstrdup (xbasename (pathname)); char* p = strrchr (afm, '.'); if (p != NULL && strlen(p) == 4 && tolower(*(p+1)) == 'p' && tolower(*(p+2)) == 'f') strcpy(p, ".afm"); char *fullafm = kpse_find_file (afm, kpse_afm_format, 0); free (afm); if (fullafm) { FT_Attach_File(m_ftFace, fullafm); free (fullafm); } } m_filename = xstrdup(pathname); m_index = index; m_unitsPerEM = m_ftFace->units_per_EM; m_ascent = unitsToPoints(m_ftFace->ascender); m_descent = unitsToPoints(m_ftFace->descender); postTable = (TT_Postscript *) getFontTable(ft_sfnt_post); if (postTable != NULL) { m_italicAngle = Fix2D(postTable->italicAngle); } os2Table = (TT_OS2*) getFontTable(ft_sfnt_os2); if (os2Table) { m_capHeight = unitsToPoints(os2Table->sCapHeight); m_xHeight = unitsToPoints(os2Table->sxHeight); } // Set up HarfBuzz font hbFace = hb_face_create_for_tables(_get_table, m_ftFace, NULL); hb_face_set_index(hbFace, index); hb_face_set_upem(hbFace, m_unitsPerEM); m_hbFont = hb_font_create(hbFace); hb_face_destroy(hbFace); if (hbFontFuncs == NULL) hbFontFuncs = _get_font_funcs(); hb_font_set_funcs(m_hbFont, hbFontFuncs, m_ftFace, NULL); hb_font_set_scale(m_hbFont, m_unitsPerEM, m_unitsPerEM); // We don’t want device tables adjustments hb_font_set_ppem(m_hbFont, 0, 0); return; }