# HG changeset patch # User Michael Goffioul # Date 1377437197 14400 # Node ID 219552139c185d5ac53ddc1fd069758837399f8a # Parent 352b442a72a51453b6460f3a6094b7c32acbf925 Allow to compile with older freetype on RHEL5 (bug #39823). * configure.ac: Check for FT_Reference_Face in freetype. * libinterp/corefcn/txt-eng-ft.h (ft_render::ft_font::name, ft_render::ft_font::weight, ft_render::ft_font::angle, ft_render::ft_font::size, ft_render::ft_font::face): Make members private. (ft_render::ft_font::ft_font(ft_font), ft_render::ft_font::operator=): Move implementation to source file. (ft_render::ft_font::ft_font(string,string,string,double,FT_Face)): Add default value for last argument. (ft_render::ft_font::get_name, ft_render::ft_font::get_weight, ft_render::ft_font::get_angle, ft_render::ft_font::get_size, ft_render::ft_font::get_face): New methods. * libinterp/corefcn/txt-eng-ft.cc (ft_render::ft_font::ft_font(ft_font), ft_render::ft_font::operator=): Moved implementation from header file. Use FT_Reference_Face conditionally. (ft_render::ft_font::get_face): New method to lazy-load the font structure, implementation from ft_render::set_font. (ft_render::process_character, ft_render::visit(text_element_subscript), ft_render::visit(text_element_superscript), ft_render::visit(text_element_fontsize), ft_render::visit(text_element_fontname), ft_render::visit(text_element_fontstyle), ft_render::update_line_bbox, ft_render::push_new_line): Use ft_render::ft_font accessors. (ft_render::set_font): Move implementation to ft_render::ft_font::get_face. (ft_manager::do_get_font): Use font sharing conditionally, when FT_Reference_Face is present. diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -1069,6 +1069,10 @@ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_FREETYPE, 1, [Define to 1 if you have Freetype library.]) XTRA_CXXFLAGS="$XTRA_CXXFLAGS $FT2_CFLAGS" + save_LIBS="$LIBS" + LIBS="$FT2_LIBS $LIBS" + AC_CHECK_FUNCS([FT_Reference_Face]) + LIBS="$save_LIBS" else AC_MSG_RESULT(no) warn_freetype="FreeType library not found. Native graphics will be disabled." diff --git a/libinterp/corefcn/txt-eng-ft.cc b/libinterp/corefcn/txt-eng-ft.cc --- a/libinterp/corefcn/txt-eng-ft.cc +++ b/libinterp/corefcn/txt-eng-ft.cc @@ -168,6 +168,7 @@ { FT_Face retval = 0; +#if HAVE_FT_REFERENCE_FACE // Look first into the font cache, then use fontconfig. If the font // is present in the cache, simply add a reference and return it. @@ -179,6 +180,7 @@ FT_Reference_Face (it->second); return it->second; } +#endif std::string file; @@ -256,6 +258,7 @@ { if (FT_New_Face (library, file.c_str (), 0, &retval)) ::warning ("ft_manager: unable to load font: %s", file.c_str ()); +#if HAVE_FT_REFERENCE_FACE else { // Install a finalizer to notify ft_manager that the font is @@ -269,6 +272,7 @@ cache[key] = retval; } +#endif } return retval; @@ -317,17 +321,8 @@ const std::string& angle, double size) { // FIXME: take "fontunits" into account - FT_Face face = ft_manager::get_font (name, weight, angle, size); - if (face) - { - if (FT_Set_Char_Size (face, 0, size*64, 0, 0)) - ::warning ("ft_render: unable to set font size to %g", size); - - font = ft_font (name, weight, angle, size, face); - } - else - ::warning ("ft_render: unable to load appropriate font"); + font = ft_font (name, weight, angle, size, 0); } void @@ -339,7 +334,7 @@ { // Create a new bbox entry based on the current font. - FT_Face face = font.face; + FT_Face face = font.get_face (); if (face) { @@ -438,8 +433,8 @@ if (mode == MODE_BBOX) { - int asc = font.face->size->metrics.ascender >> 6; - int desc = font.face->size->metrics.descender >> 6; + int asc = font.get_face ()->size->metrics.ascender >> 6; + int desc = font.get_face ()->size->metrics.descender >> 6; Matrix& bb = line_bbox.front (); @@ -503,7 +498,7 @@ FT_UInt ft_render::process_character (FT_ULong code, FT_UInt previous) { - FT_Face face = font.face; + FT_Face face = font.get_face (); FT_UInt glyph_index = 0; if (face) @@ -670,10 +665,12 @@ int saved_line_yoffset = line_yoffset; int saved_yoffset = yoffset; - set_font (font.name, font.weight, font.angle, font.size - 2); + set_font (font.get_name (), font.get_weight (), font.get_angle (), + font.get_size () - 2); + if (font.is_valid ()) { - int h = font.face->size->metrics.height >> 6; + int h = font.get_face ()->size->metrics.height >> 6; // Shifting the baseline by 2/3 the font height seems to produce // decent result. @@ -699,10 +696,12 @@ int saved_line_yoffset = line_yoffset; int saved_yoffset = yoffset; - set_font (font.name, font.weight, font.angle, font.size - 2); - if (saved_font.is_valid () && font.is_valid ()) + set_font (font.get_name (), font.get_weight (), font.get_angle (), + font.get_size () - 2); + + if (saved_font.is_valid ()) { - int s_asc = saved_font.face->size->metrics.ascender >> 6; + int s_asc = saved_font.get_face ()->size->metrics.ascender >> 6; // Shifting the baseline by 2/3 base font ascender seems to produce // decent result. @@ -736,7 +735,7 @@ // FIXME: Matlab documentation says that the font size is expressed // in the text object FontUnit. - set_font (font.name, font.weight, font.angle, sz); + set_font (font.get_name (), font.get_weight (), font.get_angle (), sz); if (mode == MODE_BBOX) update_line_bbox (); @@ -745,7 +744,8 @@ void ft_render::visit (text_element_fontname& e) { - set_font (e.get_fontname (), font.weight, font.angle, font.size); + set_font (e.get_fontname (), font.get_weight (), font.get_angle (), + font.get_size ()); if (mode == MODE_BBOX) update_line_bbox (); @@ -757,16 +757,16 @@ switch (e.get_fontstyle ()) { case text_element_fontstyle::normal: - set_font (font.name, "normal", "normal", font.size); + set_font (font.get_name (), "normal", "normal", font.get_size ()); break; case text_element_fontstyle::bold: - set_font (font.name, "bold", "normal", font.size); + set_font (font.get_name (), "bold", "normal", font.get_size ()); break; case text_element_fontstyle::italic: - set_font (font.name, "normal", "italic", font.size); + set_font (font.get_name (), "normal", "italic", font.get_size ()); break; case text_element_fontstyle::oblique: - set_font (font.name, "normal", "oblique", font.size); + set_font (font.get_name (), "normal", "oblique", font.get_size ()); break; } @@ -994,4 +994,61 @@ } } +ft_render::ft_font::ft_font (const ft_font& ft) + : name (ft.name), weight (ft.weight), angle (ft.angle), size (ft.size), + face (0) +{ +#if HAVE_FT_REFERENCE_FACE + FT_Face ft_face = ft.get_face (); + + if (ft_face && FT_Reference_Face (ft_face) == 0) + face = ft_face; +#endif +} + +ft_render::ft_font& +ft_render::ft_font::operator = (const ft_font& ft) +{ + if (&ft != this) + { + name = ft.name; + weight = ft.weight; + angle = ft.angle; + size = ft.size; + if (face) + { + FT_Done_Face (face); + face = 0; + } + +#if HAVE_FT_REFERENCE_FACE + FT_Face ft_face = ft.get_face (); + + if (ft_face && FT_Reference_Face (ft_face) == 0) + face = ft_face; +#endif + } + + return *this; +} + +FT_Face +ft_render::ft_font::get_face (void) const +{ + if (! face && ! name.empty ()) + { + face = ft_manager::get_font (name, weight, angle, size); + + if (face) + { + if (FT_Set_Char_Size (face, 0, size*64, 0, 0)) + ::warning ("ft_render: unable to set font size to %g", size); + } + else + ::warning ("ft_render: unable to load appropriate font"); + } + + return face; +} + #endif // HAVE_FREETYPE diff --git a/libinterp/corefcn/txt-eng-ft.h b/libinterp/corefcn/txt-eng-ft.h --- a/libinterp/corefcn/txt-eng-ft.h +++ b/libinterp/corefcn/txt-eng-ft.h @@ -116,26 +116,14 @@ class ft_font { public: - std::string name; - std::string weight; - std::string angle; - double size; - FT_Face face; - ft_font (void) : name (), weight (), angle (), size (0), face (0) { } ft_font (const std::string& nm, const std::string& wt, - const std::string& ang, double sz, FT_Face f) + const std::string& ang, double sz, FT_Face f = 0) : name (nm), weight (wt), angle (ang), size (sz), face (f) { } - ft_font (const ft_font& ft) - : name (ft.name), weight (ft.weight), angle (ft.angle), - size (ft.size), face (0) - { - if (FT_Reference_Face (ft.face) == 0) - face = ft.face; - } + ft_font (const ft_font& ft); ~ft_font (void) { @@ -143,25 +131,26 @@ FT_Done_Face (face); } - ft_font& operator = (const ft_font& ft) - { - if (&ft != this) - { - name = ft.name; - weight = ft.weight; - angle = ft.angle; - size = ft.size; - FT_Done_Face (face); - if (FT_Reference_Face (ft.face) == 0) - face = ft.face; - else - face = 0; - } + ft_font& operator = (const ft_font& ft); + + bool is_valid (void) const { return get_face (); } + + std::string get_name (void) const { return name; } + + std::string get_weight (void) const { return weight; } + + std::string get_angle (void) const { return angle; } - return *this; - } + double get_size (void) const { return size; } + + FT_Face get_face (void) const; - bool is_valid (void) const { return face; } + private: + std::string name; + std::string weight; + std::string angle; + double size; + mutable FT_Face face; }; void push_new_line (void);