2 *******************************************************************************
4 * Copyright (C) 1999-2007, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: GnomeFontInstance.cpp
10 * created on: 08/30/2001
11 * created by: Eric R. Mader
16 #include FT_FREETYPE_H
19 #include FT_TRUETYPE_TABLES_H
23 #include "layout/LETypes.h"
24 #include "layout/LESwaps.h"
26 #include "GnomeFontInstance.h"
30 GnomeSurface::GnomeSurface(GtkWidget
*theWidget
)
33 fCairo
= gdk_cairo_create(fWidget
->window
);
36 GnomeSurface::~GnomeSurface()
38 cairo_destroy(fCairo
);
41 void GnomeSurface::drawGlyphs(const LEFontInstance
*font
, const LEGlyphID
*glyphs
, le_int32 count
,
42 const float *positions
, le_int32 x
, le_int32 y
, le_int32
/*width*/, le_int32
/*height*/)
44 GnomeFontInstance
*gFont
= (GnomeFontInstance
*) font
;
46 gFont
->rasterizeGlyphs(fCairo
, glyphs
, count
, positions
, x
, y
);
49 GnomeFontInstance::GnomeFontInstance(FT_Library engine
, const char *fontPathName
, le_int16 pointSize
, LEErrorCode
&status
)
50 : FontTableCache(), fPointSize(pointSize
), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0),
51 fDeviceScaleX(1), fDeviceScaleY(1), fMapper(NULL
)
58 error
= FT_New_Face(engine
, fontPathName
, 0, &fFace
);
61 printf("OOPS! Got error code %d\n", error
);
62 status
= LE_FONT_FILE_NOT_FOUND_ERROR
;
66 // FIXME: what about the display resolution?
67 fDeviceScaleX
= ((float) 96) / 72;
68 fDeviceScaleY
= ((float) 96) / 72;
70 error
= FT_Set_Char_Size(fFace
, 0, pointSize
<< 6, 92, 92);
72 fCairoFace
= cairo_ft_font_face_create_for_ft_face(fFace
, 0);
74 fUnitsPerEM
= fFace
->units_per_EM
;
76 fAscent
= (le_int32
) (yUnitsToPoints(fFace
->ascender
) * fDeviceScaleY
);
77 fDescent
= (le_int32
) -(yUnitsToPoints(fFace
->descender
) * fDeviceScaleY
);
78 fLeading
= (le_int32
) (yUnitsToPoints(fFace
->height
) * fDeviceScaleY
) - fAscent
- fDescent
;
80 // printf("Face = %s, unitsPerEM = %d, ascent = %d, descent = %d\n", fontPathName, fUnitsPerEM, fAscent, fDescent);
83 status
= LE_MEMORY_ALLOCATION_ERROR
;
87 status
= initMapper();
90 GnomeFontInstance::~GnomeFontInstance()
92 cairo_font_face_destroy(fCairoFace
);
99 LEErrorCode
GnomeFontInstance::initMapper()
101 LETag cmapTag
= LE_CMAP_TABLE_TAG
;
102 const CMAPTable
*cmap
= (const CMAPTable
*) readFontTable(cmapTag
);
105 return LE_MISSING_FONT_TABLE_ERROR
;
108 fMapper
= CMAPMapper::createUnicodeMapper(cmap
);
110 if (fMapper
== NULL
) {
111 return LE_MISSING_FONT_TABLE_ERROR
;
117 const void *GnomeFontInstance::getFontTable(LETag tableTag
) const
119 return FontTableCache::find(tableTag
);
122 const void *GnomeFontInstance::readFontTable(LETag tableTag
) const
125 FT_Byte
*result
= NULL
;
127 FT_Load_Sfnt_Table(fFace
, tableTag
, 0, NULL
, &len
);
130 result
= LE_NEW_ARRAY(FT_Byte
, len
);
131 FT_Load_Sfnt_Table(fFace
, tableTag
, 0, result
, &len
);
137 void GnomeFontInstance::getGlyphAdvance(LEGlyphID glyph
, LEPoint
&advance
) const
142 if (glyph
>= 0xFFFE) {
148 error
= FT_Load_Glyph(fFace
, glyph
, FT_LOAD_DEFAULT
);
154 advance
.fX
= fFace
->glyph
->metrics
.horiAdvance
>> 6;
158 le_bool
GnomeFontInstance::getGlyphPoint(LEGlyphID glyph
, le_int32 pointNumber
, LEPoint
&point
) const
162 error
= FT_Load_Glyph(fFace
, glyph
, FT_LOAD_DEFAULT
);
168 if (pointNumber
>= fFace
->glyph
->outline
.n_points
) {
172 point
.fX
= fFace
->glyph
->outline
.points
[pointNumber
].x
>> 6;
173 point
.fY
= fFace
->glyph
->outline
.points
[pointNumber
].y
>> 6;
178 void GnomeFontInstance::rasterizeGlyphs(cairo_t
*cairo
, const LEGlyphID
*glyphs
, le_int32 glyphCount
, const float *positions
,
179 le_int32 x
, le_int32 y
) const
181 cairo_glyph_t
*glyph_t
= LE_NEW_ARRAY(cairo_glyph_t
, glyphCount
);
184 for (in
= 0, out
= 0; in
< glyphCount
; in
+= 1) {
185 TTGlyphID glyph
= LE_GET_GLYPH(glyphs
[in
]);
187 if (glyph
< 0xFFFE) {
188 glyph_t
[out
].index
= glyph
;
189 glyph_t
[out
].x
= x
+ positions
[in
*2];
190 glyph_t
[out
].y
= y
+ positions
[in
*2 + 1];
196 cairo_set_font_face(cairo
, fCairoFace
);
197 cairo_set_font_size(cairo
, getXPixelsPerEm() * getScaleFactorX());
198 cairo_show_glyphs(cairo
, glyph_t
, out
);
200 LE_DELETE_ARRAY(glyph_t
);