Mercurial > hg > octave-lyh
changeset 9616:2093499ec9f4
avoid crash if default font can't be found
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 04 Sep 2009 17:47:03 -0400 |
parents | ee3a5e9a381c |
children | 7c628fb04fd0 |
files | src/ChangeLog src/genprops.awk src/gl-render.cc src/graphics.h.in src/txt-eng-ft.cc |
diffstat | 5 files changed, 123 insertions(+), 106 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2009-09-04 John W. Eaton <jwe@octave.org> + + * txt-eng-ft.cc (ft_manager::do_get_font, ft_render::set_font, + ft_render::set_mode, ft_render::visit, ft_render::set_color): + Issue warnings instead of errors for non-fatal problems. + (ft_render::visit): If face is null, then return without warning. + * genprops.awk: Also generate const std::string& and const char* + versions of the get member functions. + * gl-render.cc (opengl_renderer::draw): Omit caseless_str + constructor in call to get method. + * ft_render::set_font (): Likewise. + 2009-09-03 John W. Eaton <jwe@octave.org> * pr-output.cc (set_format (const Complex&, int&, int&)):
--- a/src/genprops.awk +++ b/src/genprops.awk @@ -246,6 +246,8 @@ printf (" void set (const caseless_str& pname, const octave_value& val);\n\n"); printf (" octave_value get (bool all = false) const;\n\n"); printf (" octave_value get (const caseless_str& pname) const;\n\n"); + printf (" octave_value get (const std::string& pname) const\n {\n return get (caseless_str (pname)); }\n\n"); + printf (" octave_value get (const char *pname) const\n {\n return get (caseless_str (pname)); }\n\n"); printf (" property get_property (const caseless_str& pname);\n\n"); printf (" std::string graphics_object_name (void) const { return go_name; }\n\n"); printf (" static property_list::pval_map_type factory_defaults (void);\n\n");
--- a/src/gl-render.cc +++ b/src/gl-render.cc @@ -1644,15 +1644,15 @@ graphics_object go = (*it); // FIXME: check whether object has "units" property and it is set to "data" - if (! go.isa ("text") || go.get (caseless_str ("units")).string_value () == "data") + if (! go.isa ("text") || go.get ("units").string_value () == "data") { set_clipping (go.get_properties ().is_clipping ()); draw (go); it = obj_list.erase (it); - } + } else - it++; + it++; } // 3rd pass: draw remaining objects
--- a/src/graphics.h.in +++ b/src/graphics.h.in @@ -1652,6 +1652,16 @@ virtual octave_value get (const caseless_str& pname) const; + virtual octave_value get (const std::string& pname) const + { + return get (caseless_str (pname)); + } + + virtual octave_value get (const char *pname) const + { + return get (caseless_str (pname)); + } + virtual octave_value get (bool all = false) const; virtual property get_property (const caseless_str& pname);
--- a/src/txt-eng-ft.cc +++ b/src/txt-eng-ft.cc @@ -125,7 +125,10 @@ FcPattern *pat = FcPatternCreate (); - FcPatternAddString (pat, FC_FAMILY, reinterpret_cast<const FcChar8*> (name == "*" ? "sans" : name.c_str ())); + FcPatternAddString (pat, FC_FAMILY, + (reinterpret_cast<const FcChar8*> + (name == "*" ? "sans" : name.c_str ()))); + FcPatternAddInteger (pat, FC_WEIGHT, fc_weight); FcPatternAddInteger (pat, FC_SLANT, fc_angle); FcPatternAddDouble (pat, FC_PIXEL_SIZE, size); @@ -137,6 +140,7 @@ FcDefaultSubstitute (pat); match = FcFontMatch (0, pat, &res); + match = 0; if (match && res != FcResultNoMatch) { @@ -146,7 +150,7 @@ file = reinterpret_cast<char*> (tmp); } else - ::error ("could not match any font: %s-%s-%s-%g", + ::warning ("could not match any font: %s-%s-%s-%g", name.c_str (), weight.c_str (), angle.c_str (), size); @@ -167,11 +171,8 @@ #endif } - if (FT_New_Face (library, file.c_str (), 0, &retval)) - { - ::error ("ft_manager: unable to load font: %s", file.c_str ()); - } - + if (! file.empty () && FT_New_Face (library, file.c_str (), 0, &retval)) + ::warning ("ft_manager: unable to load font: %s", file.c_str ()); return retval; } @@ -207,22 +208,20 @@ FT_Done_Face (face); // FIXME: take "fontunits" into account - double font_size = props.get (caseless_str ("fontsize")).double_value (); + double font_size = props.get ("fontsize").double_value (); - face = ft_manager::get_font (props.get (caseless_str ("fontname")).string_value (), - props.get (caseless_str ("fontweight")).string_value (), - props.get (caseless_str ("fontangle")).string_value (), + face = ft_manager::get_font (props.get ("fontname").string_value (), + props.get ("fontweight").string_value (), + props.get ("fontangle").string_value (), font_size); if (face) { if (FT_Set_Char_Size (face, 0, font_size*64, 0, 0)) - { - ::error ("ft_render: unable to set font size to %d", font_size); - } + ::warning ("ft_render: unable to set font size to %d", font_size); } else - ::error ("ft_render: unable to load appropriate font"); + ::warning ("ft_render: unable to load appropriate font"); } void @@ -239,7 +238,7 @@ case MODE_RENDER: if (bbox.numel () != 4) { - ::error ("ft_render: invalid bounding box, cannot render"); + ::warning ("ft_render: invalid bounding box, cannot render"); xoffset = yoffset = 0; pixels = uint8NDArray (); @@ -261,109 +260,103 @@ void ft_render::visit (text_element_string& e) { - if (! face) + if (face) { - ::error ("ft_render: font not initialized"); - return; - } + std::string str = e.string_value (); + FT_UInt glyph_index, previous = 0; - std::string str = e.string_value (); - FT_UInt glyph_index, previous = 0; - - for (int i = 0; i < str.length (); i++) - { - glyph_index = FT_Get_Char_Index (face, str[i]); - - if (! glyph_index || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)) + for (int i = 0; i < str.length (); i++) { - ::error ("ft_render: unable to load glyph from font for character `%c', skipping", - str[i]); - } - else - { - switch (mode) + glyph_index = FT_Get_Char_Index (face, str[i]); + + if (! glyph_index + || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)) + ::warning ("ft_render: skipping missing glyph for character `%c'", + str[i]); + else { - case MODE_RENDER: - if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL)) + switch (mode) { - ::error ("ft_render: unable to render glyph for character `%c', skipping", - str[i]); - } - else - { - FT_Bitmap& bitmap = face->glyph->bitmap; - int x0, y0; + case MODE_RENDER: + if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL)) + ::warning ("ft_render: unable to render glyph for character `%c'", + str[i]); + else + { + FT_Bitmap& bitmap = face->glyph->bitmap; + int x0, y0; + + if (previous) + { + FT_Vector delta; + + FT_Get_Kerning (face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); + xoffset += (delta.x >> 6); + } + x0 = xoffset+face->glyph->bitmap_left; + y0 = yoffset+face->glyph->bitmap_top; + for (int r = 0; r < bitmap.rows; r++) + for (int c = 0; c < bitmap.width; c++) + { + unsigned char pix = bitmap.buffer[r*bitmap.width+c]; + if (x0+c < 0 || x0+c >= pixels.dim2() + || y0-r < 0 || y0-r >= pixels.dim3()) + { + //::error ("out-of-bound indexing!!"); + } + else if (pixels(3, x0+c, y0-r).value () == 0) + { + pixels(0, x0+c, y0-r) = red; + pixels(1, x0+c, y0-r) = green; + pixels(2, x0+c, y0-r) = blue; + pixels(3, x0+c, y0-r) = pix; + } + } + + xoffset += (face->glyph->advance.x >> 6); + } + break; + + case MODE_BBOX: + // width if (previous) { FT_Vector delta; FT_Get_Kerning (face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); - xoffset += (delta.x >> 6); + bbox(2) += (delta.x >> 6); + } + bbox(2) += (face->glyph->advance.x >> 6); + + int asc, desc; + + if (false /*tight*/) + { + desc = face->glyph->metrics.horiBearingY - face->glyph->metrics.height; + asc = face->glyph->metrics.horiBearingY; + } + else + { + asc = face->size->metrics.ascender; + desc = face->size->metrics.descender; } - x0 = xoffset+face->glyph->bitmap_left; - y0 = yoffset+face->glyph->bitmap_top; - for (int r = 0; r < bitmap.rows; r++) - for (int c = 0; c < bitmap.width; c++) - { - unsigned char pix = bitmap.buffer[r*bitmap.width+c]; - if (x0+c < 0 || x0+c >= pixels.dim2() - || y0-r < 0 || y0-r >= pixels.dim3()) - { - //::error ("out-of-bound indexing!!"); - } - else if (pixels(3, x0+c, y0-r).value () == 0) - { - pixels(0, x0+c, y0-r) = red; - pixels(1, x0+c, y0-r) = green; - pixels(2, x0+c, y0-r) = blue; - pixels(3, x0+c, y0-r) = pix; - } - } + asc = yoffset + (asc >> 6); + desc = yoffset + (desc >> 6); - xoffset += (face->glyph->advance.x >> 6); - } - break; - - case MODE_BBOX: - // width - if (previous) - { - FT_Vector delta; - - FT_Get_Kerning (face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); - bbox(2) += (delta.x >> 6); - } - bbox(2) += (face->glyph->advance.x >> 6); - - int asc, desc; - - if (false /*tight*/) - { - desc = face->glyph->metrics.horiBearingY - face->glyph->metrics.height; - asc = face->glyph->metrics.horiBearingY; - } - else - { - asc = face->size->metrics.ascender; - desc = face->size->metrics.descender; + if (desc < bbox(1)) + { + bbox(3) += (bbox(1) - desc); + bbox(1) = desc; + } + if (asc > (bbox(3)+bbox(1))) + bbox(3) = asc-bbox(1); + break; } - asc = yoffset + (asc >> 6); - desc = yoffset + (desc >> 6); - - if (desc < bbox(1)) - { - bbox(3) += (bbox(1) - desc); - bbox(1) = desc; - } - if (asc > (bbox(3)+bbox(1))) - bbox(3) = asc-bbox(1); - break; + previous = glyph_index; } - - previous = glyph_index; } } } @@ -385,7 +378,7 @@ blue = static_cast<uint8_t> (c(2)*255); } else - ::error ("ft_render::set_color: invalid color"); + ::warning ("ft_render::set_color: invalid color"); } uint8NDArray