15 #include "freetypeFont.h" 19 #include "config_pnmtext.h" 20 #include "config_util.h" 21 #include "config_express.h" 22 #include "virtualFileSystem.h" 27 const PN_stdfloat FreetypeFont::_points_per_unit = 10.0f;
30 const PN_stdfloat FreetypeFont::_points_per_inch = 72.0f;
41 _point_size = text_point_size;
42 _requested_pixels_per_unit = text_pixels_per_unit;
43 _tex_pixels_per_unit = text_pixels_per_unit;
44 _requested_scale_factor = text_scale_factor;
45 _scale_factor = text_scale_factor;
46 _native_antialias = text_native_antialias;
49 _space_advance = 0.25f;
63 FreetypeFont(
const FreetypeFont ©) :
65 _point_size(copy._point_size),
66 _requested_pixels_per_unit(copy._requested_pixels_per_unit),
67 _tex_pixels_per_unit(copy._tex_pixels_per_unit),
68 _requested_scale_factor(copy._requested_scale_factor),
69 _scale_factor(copy._scale_factor),
70 _native_antialias(copy._native_antialias),
71 _font_pixels_per_unit(copy._font_pixels_per_unit),
72 _line_height(copy._line_height),
73 _space_advance(copy._space_advance),
75 _char_size(copy._char_size),
77 _pixel_width(copy._pixel_width),
78 _pixel_height(copy._pixel_height)
91 load_font(
const Filename &font_filename,
int face_index) {
93 _face =
new FreetypeFace;
96 <<
"Unable to read font " << font_filename
97 <<
": FreeType library not initialized properly.\n";
107 exists = vfs->read_file(path, _face->_font_data,
true);
110 error = FT_New_Memory_Face(_face->_ft_library,
111 (
const FT_Byte *)_face->_font_data.data(),
112 _face->_font_data.length(),
114 _face->set_face(face);
120 <<
"Unable to find font file " << font_filename <<
"\n";
122 if (error == FT_Err_Unknown_File_Format) {
124 <<
"Unable to read font " << font_filename <<
": unknown file format.\n";
127 <<
"Unable to read font " << font_filename <<
": invalid.\n";
130 okflag = reset_scale();
149 load_font(
const char *font_data,
int data_length,
int face_index) {
151 _face =
new FreetypeFace;
153 if (!_face->_ft_ok) {
155 <<
"Unable to read font: FreeType library not initialized properly.\n";
162 error = FT_New_Memory_Face(_face->_ft_library,
163 (
const FT_Byte *)font_data, data_length,
165 _face->set_face(face);
168 if (error == FT_Err_Unknown_File_Format) {
170 <<
"Unable to read font: unknown file format.\n";
173 <<
"Unable to read font: invalid.\n";
176 okflag = reset_scale();
204 load_glyph(FT_Face face,
int glyph_index,
bool prerender) {
205 int flags = FT_LOAD_RENDER;
206 if (!_native_antialias) {
207 flags |= FT_LOAD_MONOCHROME;
216 int error = FT_Load_Glyph(face, glyph_index, flags);
219 <<
"Unable to render glyph " << glyph_index <<
"\n";
232 copy_bitmap_to_pnmimage(
const FT_Bitmap &bitmap,
PNMImage &image) {
233 if (bitmap.pixel_mode == ft_pixel_mode_grays &&
234 bitmap.num_grays == (
int)image.
get_maxval() + 1) {
237 unsigned char *buffer_row = bitmap.buffer;
238 for (
int yi = 0; yi < bitmap.rows; yi++) {
239 for (
int xi = 0; xi < bitmap.width; xi++) {
242 buffer_row += bitmap.pitch;
245 }
else if (bitmap.pixel_mode == ft_pixel_mode_mono) {
248 unsigned char *buffer_row = bitmap.buffer;
249 for (
int yi = 0; yi < bitmap.rows; yi++) {
252 unsigned char *b = buffer_row;
253 for (
int xi = 0; xi < bitmap.width; xi++) {
266 buffer_row += bitmap.pitch;
270 }
else if (bitmap.pixel_mode == ft_pixel_mode_grays) {
273 unsigned char *buffer_row = bitmap.buffer;
274 for (
int yi = 0; yi < bitmap.rows; yi++) {
275 for (
int xi = 0; xi < bitmap.width; xi++) {
276 image.
set_gray(xi, yi, (PN_stdfloat)buffer_row[xi] / (bitmap.num_grays - 1));
278 buffer_row += bitmap.pitch;
283 <<
"Unexpected pixel mode in bitmap: " << (int)bitmap.pixel_mode <<
"\n";
302 FT_Face face = _face->acquire_face(0, 0, 0, 0);
307 _tex_pixels_per_unit = _requested_pixels_per_unit;
308 _scale_factor = _requested_scale_factor;
309 _font_pixels_per_unit = _tex_pixels_per_unit * _scale_factor;
313 PN_stdfloat units_per_inch = (_points_per_inch / _points_per_unit);
314 _dpi = (int)(_font_pixels_per_unit * units_per_inch);
315 _char_size = (int)(_point_size * 64);
317 int error = FT_Set_Char_Size(face, _char_size, _char_size, _dpi, _dpi);
323 int desired_height = (int)(_font_pixels_per_unit * _point_size / _points_per_unit + 0.5f);
325 int largest_size = -1;
326 if (face->num_fixed_sizes > 0) {
329 for (
int i = 0; i < face->num_fixed_sizes; i++) {
330 int diff = face->available_sizes[i].height - desired_height;
331 if (diff > 0 && (best_size == -1 || diff < best_diff)) {
335 if (face->available_sizes[i].height > face->available_sizes[largest_size].height) {
341 best_size = largest_size;
344 if (best_size >= 0) {
345 _pixel_height = face->available_sizes[best_size].height;
346 _pixel_width = face->available_sizes[best_size].width;
347 error = FT_Set_Pixel_Sizes(face, _pixel_width, _pixel_height);
349 _font_pixels_per_unit = _pixel_height * _points_per_unit / _point_size;
350 _scale_factor = _font_pixels_per_unit / _tex_pixels_per_unit;
352 if (_scale_factor < 1.0) {
355 _tex_pixels_per_unit = _font_pixels_per_unit;
362 pnmtext_cat.warning()
363 <<
"Unable to set " << get_name()
364 <<
" to " << _point_size <<
"pt at " << _dpi <<
" dpi.\n";
366 _face->release_face(face);
370 _line_height = face->size->metrics.height / (_font_pixels_per_unit * 64.0f);
373 error = FT_Load_Char(face,
' ', FT_LOAD_DEFAULT);
376 _space_advance = 0.25f * _line_height;
379 _space_advance = face->glyph->advance.x / (_font_pixels_per_unit * 64.0f);
382 _face->release_face(face);
386 #endif // HAVE_FREETYPE void set_gray_val(int x, int y, xelval gray)
Sets the gray component color at the indicated pixel.
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const string &default_extension=string()) const
Searches the given search path for the filename.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
A hierarchy of directories and files that appears to be one continuous file system, even though the files may originate from several different sources that may not be related to the actual OS's file system.
A base class for all things which can have a name.
The name of a file, such as a texture file or an Egg file.
void set_gray(int x, int y, float gray)
Sets the gray component color at the indicated pixel.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.