summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/xetexdir/XeTeXFontInst_FC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/xetexdir/XeTeXFontInst_FC.cpp')
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontInst_FC.cpp217
1 files changed, 217 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontInst_FC.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_FC.cpp
new file mode 100644
index 00000000000..499ed7d19b0
--- /dev/null
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontInst_FC.cpp
@@ -0,0 +1,217 @@
+/****************************************************************************\
+ 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_FC.cpp
+ *
+ * created on: 2005-10-25
+ * created by: Jonathan Kew
+ */
+
+
+#include "XeTeXFontInst_FC.h"
+
+#include FT_TRUETYPE_TABLES_H
+#include FT_TYPE1_TABLES_H
+#include FT_GLYPH_H
+
+static FT_Library gLibrary = 0;
+
+
+XeTeXFontInst_FC::XeTeXFontInst_FC(FcPattern* pattern, float pointSize, LEErrorCode &status)
+ : XeTeXFontInst(pattern, pointSize, status)
+ , face(0)
+ , fFreeTypeOnly(false)
+{
+ if (LE_FAILURE(status)) {
+ return;
+ }
+
+ FT_Error err;
+ if (!gLibrary) {
+ err = FT_Init_FreeType(&gLibrary);
+ if (err != 0) {
+ fprintf(stderr, "FreeType initialization failed! (%d)\n", err);
+ exit(1);
+ }
+ }
+
+ FcChar8* pathname = 0;
+ FcPatternGetString(pattern, FC_FILE, 0, &pathname);
+ int index;
+ FcPatternGetInteger(pattern, FC_INDEX, 0, &index);
+
+ err = FT_New_Face(gLibrary, (char*)pathname, index, &face);
+
+ if (err != 0) {
+ status = LE_FONT_FILE_NOT_FOUND_ERROR;
+ return;
+ }
+
+ initialize(status);
+}
+
+XeTeXFontInst_FC::~XeTeXFontInst_FC()
+{
+ if (face != 0) {
+ FT_Done_Face(face);
+ face = 0;
+ }
+}
+
+void XeTeXFontInst_FC::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_FC::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;
+}
+
+char* XeTeXFontInst_FC::getPSName() const
+{
+ if (face == NULL)
+ return NULL;
+
+ const char* facePSName = FT_Get_Postscript_Name(face);
+ if (facePSName == NULL)
+ return NULL;
+
+ le_uint32 length = strlen(facePSName);
+ char* name = (char*)xmalloc(length + 1);
+ strcpy(name, facePSName);
+
+ return name;
+}
+
+void
+XeTeXFontInst_FC::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_FC::mapCharToGlyph(LEUnicode32 ch) const
+{
+ if (!fFreeTypeOnly)
+ return XeTeXFontInst::mapCharToGlyph(ch);
+
+ return FT_Get_Char_Index(face, ch);
+}
+
+le_uint16
+XeTeXFontInst_FC::getNumGlyphs() const
+{
+ return face->num_glyphs;
+}
+
+void
+XeTeXFontInst_FC::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_FC::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;
+}