2 *******************************************************************************
4 * © 2016 and later: Unicode, Inc. and others.
5 * License & terms of use: http://www.unicode.org/copyright.html#License
7 *******************************************************************************
8 *******************************************************************************
10 * Copyright (C) 1999-2007, International Business Machines
11 * Corporation and others. All Rights Reserved.
13 *******************************************************************************
14 * file name: GnomeFontInstance.cpp
16 * created on: 08/30/2001
17 * created by: Eric R. Mader
22 #include FT_FREETYPE_H
25 #include FT_TRUETYPE_TABLES_H
29 #include "layout/LETypes.h"
30 #include "layout/LESwaps.h"
32 #include "GnomeFontInstance.h"
36 GnomeSurface::GnomeSurface(GtkWidget
*theWidget
)
39 fCairo
= gdk_cairo_create(fWidget
->window
);
42 GnomeSurface::~GnomeSurface()
44 cairo_destroy(fCairo
);
47 void GnomeSurface::drawGlyphs(const LEFontInstance
*font
, const LEGlyphID
*glyphs
, le_int32 count
,
48 const float *positions
, le_int32 x
, le_int32 y
, le_int32
/*width*/, le_int32
/*height*/)
50 GnomeFontInstance
*gFont
= (GnomeFontInstance
*) font
;
52 gFont
->rasterizeGlyphs(fCairo
, glyphs
, count
, positions
, x
, y
);
55 GnomeFontInstance::GnomeFontInstance(FT_Library engine
, const char *fontPathName
, le_int16 pointSize
, LEErrorCode
&status
)
56 : FontTableCache(), fPointSize(pointSize
), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0),
57 fDeviceScaleX(1), fDeviceScaleY(1), fMapper(NULL
)
64 error
= FT_New_Face(engine
, fontPathName
, 0, &fFace
);
67 printf("OOPS! Got error code %d\n", error
);
68 status
= LE_FONT_FILE_NOT_FOUND_ERROR
;
72 // FIXME: what about the display resolution?
73 fDeviceScaleX
= ((float) 96) / 72;
74 fDeviceScaleY
= ((float) 96) / 72;
76 error
= FT_Set_Char_Size(fFace
, 0, pointSize
<< 6, 92, 92);
78 fCairoFace
= cairo_ft_font_face_create_for_ft_face(fFace
, 0);
80 fUnitsPerEM
= fFace
->units_per_EM
;
82 fAscent
= (le_int32
) (yUnitsToPoints(fFace
->ascender
) * fDeviceScaleY
);
83 fDescent
= (le_int32
) -(yUnitsToPoints(fFace
->descender
) * fDeviceScaleY
);
84 fLeading
= (le_int32
) (yUnitsToPoints(fFace
->height
) * fDeviceScaleY
) - fAscent
- fDescent
;
86 // printf("Face = %s, unitsPerEM = %d, ascent = %d, descent = %d\n", fontPathName, fUnitsPerEM, fAscent, fDescent);
89 status
= LE_MEMORY_ALLOCATION_ERROR
;
93 status
= initMapper();
96 GnomeFontInstance::~GnomeFontInstance()
98 cairo_font_face_destroy(fCairoFace
);
105 LEErrorCode
GnomeFontInstance::initMapper()
107 LETag cmapTag
= LE_CMAP_TABLE_TAG
;
108 const CMAPTable
*cmap
= (const CMAPTable
*) readFontTable(cmapTag
);
111 return LE_MISSING_FONT_TABLE_ERROR
;
114 fMapper
= CMAPMapper::createUnicodeMapper(cmap
);
116 if (fMapper
== NULL
) {
117 return LE_MISSING_FONT_TABLE_ERROR
;
123 const void *GnomeFontInstance::getFontTable(LETag tableTag
) const
125 return FontTableCache::find(tableTag
);
128 const void *GnomeFontInstance::readFontTable(LETag tableTag
) const
131 FT_Byte
*result
= NULL
;
133 FT_Load_Sfnt_Table(fFace
, tableTag
, 0, NULL
, &len
);
136 result
= LE_NEW_ARRAY(FT_Byte
, len
);
137 FT_Load_Sfnt_Table(fFace
, tableTag
, 0, result
, &len
);
143 void GnomeFontInstance::getGlyphAdvance(LEGlyphID glyph
, LEPoint
&advance
) const
148 if (glyph
>= 0xFFFE) {
154 error
= FT_Load_Glyph(fFace
, glyph
, FT_LOAD_DEFAULT
);
160 advance
.fX
= fFace
->glyph
->metrics
.horiAdvance
>> 6;
164 le_bool
GnomeFontInstance::getGlyphPoint(LEGlyphID glyph
, le_int32 pointNumber
, LEPoint
&point
) const
168 error
= FT_Load_Glyph(fFace
, glyph
, FT_LOAD_DEFAULT
);
174 if (pointNumber
>= fFace
->glyph
->outline
.n_points
) {
178 point
.fX
= fFace
->glyph
->outline
.points
[pointNumber
].x
>> 6;
179 point
.fY
= fFace
->glyph
->outline
.points
[pointNumber
].y
>> 6;
184 void GnomeFontInstance::rasterizeGlyphs(cairo_t
*cairo
, const LEGlyphID
*glyphs
, le_int32 glyphCount
, const float *positions
,
185 le_int32 x
, le_int32 y
) const
187 cairo_glyph_t
*glyph_t
= LE_NEW_ARRAY(cairo_glyph_t
, glyphCount
);
190 for (in
= 0, out
= 0; in
< glyphCount
; in
+= 1) {
191 TTGlyphID glyph
= LE_GET_GLYPH(glyphs
[in
]);
193 if (glyph
< 0xFFFE) {
194 glyph_t
[out
].index
= glyph
;
195 glyph_t
[out
].x
= x
+ positions
[in
*2];
196 glyph_t
[out
].y
= y
+ positions
[in
*2 + 1];
202 cairo_set_font_face(cairo
, fCairoFace
);
203 cairo_set_font_size(cairo
, getXPixelsPerEm() * getScaleFactorX());
204 cairo_show_glyphs(cairo
, glyph_t
, out
);
206 LE_DELETE_ARRAY(glyph_t
);