diff options
author | Jonathan Kew <jfkthame@googlemail.com> | 2006-09-07 10:00:56 +0000 |
---|---|---|
committer | Jonathan Kew <jfkthame@googlemail.com> | 2006-09-07 10:00:56 +0000 |
commit | bc784de6a2b45e06374f41e4c658fb7d77fa04b8 (patch) | |
tree | 849bb11cd3b3cfd0bb5a703506382ad374d8fd37 /Build/source/texk/web2c/xetexdir/XeTeXFontInst_FT2.cpp | |
parent | 9a4cd922ac26125fc6de1f680a8ffca74af04956 (diff) |
xetex source update, synced with xetex repo rev.365
git-svn-id: svn://tug.org/texlive/trunk@2093 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/xetexdir/XeTeXFontInst_FT2.cpp')
-rw-r--r-- | Build/source/texk/web2c/xetexdir/XeTeXFontInst_FT2.cpp | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_FT2.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_FT2.cpp new file mode 100644 index 00000000000..cc56442be24 --- /dev/null +++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_FT2.cpp @@ -0,0 +1,234 @@ +/****************************************************************************\ + Part of the XeTeX typesetting system + copyright (c) 1994-2006 by SIL International + written by Jonathan Kew + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL SIL INTERNATIONAL BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of SIL International +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in this Software without prior written +authorization from SIL International. +\****************************************************************************/ + +/* + * file name: XeTeXFontInst_FT2.cpp + * + * created on: 2005-10-25 + * created by: Jonathan Kew + */ + + +#include "XeTeXFontInst_FT2.h" + +#include FT_TRUETYPE_TABLES_H +#include FT_TYPE1_TABLES_H +#include FT_GLYPH_H + +#include <string.h> + +FT_Library gFreeTypeLibrary = 0; + +XeTeXFontInst_FT2::XeTeXFontInst_FT2(const char* pathname, int index, float pointSize, LEErrorCode &status) + : XeTeXFontInst(pointSize, status) + , face(0) + , fFreeTypeOnly(false) +{ + if (LE_FAILURE(status)) { + return; + } + + FT_Error err; + if (!gFreeTypeLibrary) { + err = FT_Init_FreeType(&gFreeTypeLibrary); + if (err != 0) { + fprintf(stderr, "FreeType initialization failed! (%d)\n", err); + exit(1); + } + } + + err = FT_New_Face(gFreeTypeLibrary, (char*)pathname, index, &face); + + if (err != 0) { + status = LE_FONT_FILE_NOT_FOUND_ERROR; + 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(face)) { + 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(face, afm); // ignore error code; AFM might not exist + delete[] afm; + fFreeTypeOnly = true; + } + + initialize(status); + + if (LE_FAILURE(status)) + return; + + 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); +} + +XeTeXFontInst_FT2::~XeTeXFontInst_FT2() +{ + if (face != 0) { + FT_Done_Face(face); + face = 0; + } +} + +void XeTeXFontInst_FT2::initialize(LEErrorCode &status) +{ + if (face == 0) { + status = LE_FONT_FILE_NOT_FOUND_ERROR; + return; + } + + XeTeXFontInst::initialize(status); + + if (LE_FAILURE(status)) { + /* font can ONLY be used via FreeType APIs, not direct table access */ + fFreeTypeOnly = true; + status = LE_NO_ERROR; + + /* fill in fields that XeTeXFontInst::initialize failed to get for us */ + fUnitsPerEM = face->units_per_EM; + fAscent = yUnitsToPoints(face->ascender); + fDescent = yUnitsToPoints(face->descender); +// fLeading = ; + fItalicAngle = 0; + PS_FontInfoRec font_info; + if (FT_Get_PS_Font_Info(face, &font_info) == 0) { + // will return error if it wasn't a PS font + fItalicAngle = font_info.italic_angle; + } + } + + return; +} + +const void *XeTeXFontInst_FT2::readTable(LETag tag, le_uint32 *length) const +{ + *length = 0; + FT_ULong tmpLength = 0; + FT_Error err = FT_Load_Sfnt_Table(face, tag, 0, NULL, &tmpLength); + if (err != 0) + return NULL; + + void* table = LE_NEW_ARRAY(char, tmpLength); + if (table != NULL) { + err = FT_Load_Sfnt_Table(face, tag, 0, (FT_Byte*)table, &tmpLength); + if (err != 0) { + LE_DELETE_ARRAY(table); + return NULL; + } + *length = tmpLength; + } + + return table; +} + +void +XeTeXFontInst_FT2::getGlyphBounds(LEGlyphID gid, GlyphBBox* bbox) +{ + bbox->xMin = bbox->yMin = bbox->xMax = bbox->yMax = 0.0; + + FT_Error err = FT_Load_Glyph(face, gid, FT_LOAD_NO_SCALE); + if (err != 0) + return; + + FT_Glyph glyph; + err = FT_Get_Glyph(face->glyph, &glyph); + if (err == 0) { + FT_BBox ft_bbox; + FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_UNSCALED, &ft_bbox); + bbox->xMin = ft_bbox.xMin * fPointSize / fUnitsPerEM; + bbox->yMin = ft_bbox.yMin * fPointSize / fUnitsPerEM; + bbox->xMax = ft_bbox.xMax * fPointSize / fUnitsPerEM; + bbox->yMax = ft_bbox.yMax * fPointSize / fUnitsPerEM; + FT_Done_Glyph(glyph); + } +} + +LEGlyphID +XeTeXFontInst_FT2::mapCharToGlyph(LEUnicode32 ch) const +{ + if (!fFreeTypeOnly) + return XeTeXFontInst::mapCharToGlyph(ch); + + return FT_Get_Char_Index(face, ch); +} + +le_uint16 +XeTeXFontInst_FT2::getNumGlyphs() const +{ + return face->num_glyphs; +} + +void +XeTeXFontInst_FT2::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const +{ + if (!fFreeTypeOnly) + XeTeXFontInst::getGlyphAdvance(glyph, advance); + else { + FT_Error err = FT_Load_Glyph(face, glyph, FT_LOAD_NO_SCALE); + if (err != 0) { + advance.fX = advance.fY = 0; + } + else { + advance.fX = fVertical ? 0 : face->glyph->metrics.horiAdvance * fPointSize / fUnitsPerEM; + advance.fY = fVertical ? face->glyph->metrics.vertAdvance * fPointSize / fUnitsPerEM : 0; + } + } +} + +LEGlyphID +XeTeXFontInst_FT2::mapGlyphToIndex(const char* glyphName) const +{ + LEGlyphID rval = FT_Get_Name_Index(face, const_cast<char*>(glyphName)); + if (rval == 0) + rval = XeTeXFontInst::mapGlyphToIndex(glyphName); + return rval; +} + +void +XeTeXFontInst_FT2::getKernPair(LEGlyphID leftGlyph, LEGlyphID rightGlyph, LEPoint &kern) const +{ + FT_Vector kerning; + if (FT_Get_Kerning(face, leftGlyph, rightGlyph, FT_KERNING_UNSCALED, &kerning) == 0) { + kern.fX = kerning.x; + kern.fY = kerning.y; + } + else + kern.fX = kern.fY = 0; +} |