26#if defined (HAVE_CONFIG_H)
33#if defined (HAVE_FREETYPE)
35#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
36# pragma GCC diagnostic push
37# pragma GCC diagnostic ignored "-Wold-style-cast"
44#if defined (HAVE_FONTCONFIG)
45# include <fontconfig/fontconfig.h>
48#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
49# pragma GCC diagnostic pop
74warn_missing_glyph (FT_ULong c)
77 "text_renderer: skipping missing glyph for character '%lx'", c);
81warn_glyph_render (FT_ULong c)
84 "text_renderer: unable to render glyph for character '%lx'", c);
98static void ft_face_destroyed (
void *
object);
105 : m_library (), m_freetype_initialized (false),
106 m_fontconfig_initialized (false)
108 if (FT_Init_FreeType (&m_library))
109 error (
"unable to initialize FreeType library");
111 m_freetype_initialized =
true;
113#if defined (HAVE_FONTCONFIG)
115 error (
"unable to initialize fontconfig library");
117 m_fontconfig_initialized =
true;
123 OCTAVE_DISABLE_COPY_MOVE (ft_manager)
129 if (m_freetype_initialized)
130 FT_Done_FreeType (m_library);
132#if defined (HAVE_FONTCONFIG)
144 static bool instance_ok ()
150 s_instance =
new ft_manager ();
157 static void cleanup_instance ()
158 {
delete s_instance; s_instance =
nullptr; }
160 static FT_Face get_font (
const std::string& name,
const std::string& weight,
161 const std::string& angle,
double size,
164 return (instance_ok ()
165 ? s_instance->do_get_font (name, weight, angle, size, c)
171 return (instance_ok ()
172 ? s_instance->do_get_system_fonts ()
176 static void font_destroyed (FT_Face face)
179 s_instance->do_font_destroyed (face);
184 typedef std::pair<std::string, double> ft_key;
185 typedef std::map<ft_key, FT_Face> ft_cache;
193#if defined (HAVE_FONTCONFIG)
194 FcConfig *config = FcConfigGetCurrent();
195 FcPattern *pat = FcPatternCreate ();
196 FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, FC_SLANT, FC_WEIGHT,
197 FC_CHARSET,
nullptr);
198 FcFontSet *fs = FcFontList (config, pat, os);
203 FcCharSet *minimal_charset = FcCharSetCreate ();
204 for (
int i = 32; i < 127; i++)
205 FcCharSetAddChar (minimal_charset,
static_cast<FcChar32
> (i));
208 fields(0) =
"family";
210 fields(2) =
"weight";
211 fields(3) =
"suitable";
219 unsigned char *family;
221 for (
int i = 0; fs && i < fs->nfont; i++)
223 FcPattern *font = fs->fonts[i];
224 if (FcPatternGetString (font, FC_FAMILY, 0, &family)
226 families(i) = std::string (
reinterpret_cast<char *
> (family));
228 families(i) =
"unknown";
230 if (FcPatternGetInteger (font, FC_SLANT, 0, &val)
232 angles(i) = (val == FC_SLANT_ITALIC
233 || val == FC_SLANT_OBLIQUE)
234 ?
"italic" :
"normal";
236 angles(i) =
"unknown";
238 if (FcPatternGetInteger (font, FC_WEIGHT, 0, &val)
240 weights(i) = (val == FC_WEIGHT_BOLD
241 || val == FC_WEIGHT_DEMIBOLD)
244 weights(i) =
"unknown";
247 if (FcPatternGetCharSet (font, FC_CHARSET, 0, &cset)
249 suitable(i) = (FcCharSetIsSubset (minimal_charset, cset)
257 font_map.
assign (
"family", families);
258 font_map.
assign (
"angle", angles);
259 font_map.
assign (
"weight", weights);
260 font_map.
assign (
"suitable", suitable);
264 FcFontSetDestroy (fs);
266 FcPatternDestroy (pat);
268 FcObjectSetDestroy (os);
270 FcCharSetDestroy (minimal_charset);
278 FT_Face do_get_font (
const std::string& name,
const std::string& weight,
279 const std::string& angle,
double size,
280 FT_ULong search_code_point)
282 FT_Face retval =
nullptr;
284#if defined (HAVE_FT_REFERENCE_FACE)
288 ft_key key (name +
':' + weight +
':' + angle +
':'
289 + std::to_string (search_code_point), size);
290 ft_cache::const_iterator it = m_cache.find (key);
292 if (it != m_cache.end ())
294 FT_Reference_Face (it->second);
299 static std::string fonts_dir;
301 if (fonts_dir.empty ())
303 fonts_dir = sys::env::getenv (
"OCTAVE_FONTS_DIR");
305 if (fonts_dir.empty ())
306#if defined (SYSTEM_FREEFONT_DIR)
307 fonts_dir = SYSTEM_FREEFONT_DIR;
309 fonts_dir = config::oct_fonts_dir ();
317 if (! fonts_dir.empty ())
319 file = fonts_dir + sys::file_ops::dir_sep_str () +
"FreeSans";
321 if (weight ==
"bold")
324 if (angle ==
"italic" || angle ==
"oblique")
330#if defined (HAVE_FONTCONFIG)
331 if ((search_code_point != 0 || name !=
"*") && m_fontconfig_initialized)
333 int fc_weight, fc_angle;
335 if (weight ==
"bold")
336 fc_weight = FC_WEIGHT_BOLD;
338 fc_weight = FC_WEIGHT_NORMAL;
340 if (angle ==
"italic")
341 fc_angle = FC_SLANT_ITALIC;
342 else if (angle ==
"oblique")
343 fc_angle = FC_SLANT_OBLIQUE;
345 fc_angle = FC_SLANT_ROMAN;
347 FcPattern *pat = FcPatternCreate ();
349 FcPatternAddString (pat, FC_FAMILY,
350 (
reinterpret_cast<const FcChar8 *
>
353 FcPatternAddInteger (pat, FC_WEIGHT, fc_weight);
354 FcPatternAddInteger (pat, FC_SLANT, fc_angle);
355 FcPatternAddDouble (pat, FC_PIXEL_SIZE, size);
357 if (search_code_point > 0)
359 FcCharSet *minimal_charset = FcCharSetCreate ();
360 FcCharSetAddChar (minimal_charset,
361 static_cast<FcChar32
> (search_code_point));
362 FcPatternAddCharSet (pat, FC_CHARSET, minimal_charset);
365 if (FcConfigSubstitute (
nullptr, pat, FcMatchPattern))
370 FcDefaultSubstitute (pat);
372 match = FcFontMatch (
nullptr, pat, &res);
380 FcPatternGetString (match, FC_FILE, 0, &tmp);
381 file =
reinterpret_cast<char *
> (tmp);
384 ::warning (
"could not match any font: %s-%s-%s-%g, using default font",
385 name.c_str (), weight.c_str (), angle.c_str (),
389 FcPatternDestroy (match);
392 FcPatternDestroy (pat);
397 ::warning (
"unable to find default font files");
400 std::string ascii_file = sys::get_ASCII_filename (file);
402 if (FT_New_Face (m_library, ascii_file.c_str (), 0, &retval))
403 ::warning (
"ft_manager: unable to load font: %s", file.c_str ());
404#if defined (HAVE_FT_REFERENCE_FACE)
411 retval->generic.data =
new ft_key (key);
412 retval->generic.finalizer = ft_face_destroyed;
415 if (FT_Reference_Face (retval) == 0)
416 m_cache[key] = retval;
424 void do_font_destroyed (FT_Face face)
426 if (face->generic.data)
428 ft_key *pkey =
reinterpret_cast<ft_key *
> (face->generic.data);
430 m_cache.erase (*pkey);
432 face->generic.data =
nullptr;
439 static ft_manager *s_instance;
446 FT_Library m_library;
447 bool m_freetype_initialized;
448 bool m_fontconfig_initialized;
451ft_manager *ft_manager::s_instance =
nullptr;
454ft_face_destroyed (
void *
object)
456 ft_manager::font_destroyed (
reinterpret_cast<FT_Face
> (
object));
473 m_xoffset (0), m_line_yoffset (0), m_yoffset (0), m_mode (MODE_BBOX),
474 m_color (
dim_vector (1, 3), 0), m_do_strlist (false), m_strlist (),
475 m_line_xoffset (0), m_ymin (0), m_ymax (0), m_deltax (0),
476 m_max_fontsize (0), m_antialias (true)
479 OCTAVE_DISABLE_COPY_MOVE (ft_text_renderer)
481 ~ft_text_renderer () =
default;
507 Matrix get_boundingbox ()
const {
return m_bbox; }
510 int rotation = ROTATION_0);
518 void set_font (
const std::string& name,
const std::string& weight,
519 const std::string& angle,
double size);
525 void set_mode (
int m);
529 int halign,
int valign,
double rotation,
531 bool handle_rotation);
545 ft_font (
const std::string& nm,
const std::string& wt,
546 const std::string& ang,
double sz, FT_Face
f =
nullptr)
550 ft_font (
const ft_font& ft);
555 FT_Done_Face (m_face);
558 ft_font& operator = (
const ft_font& ft);
560 bool is_valid ()
const {
return get_face (); }
562 FT_Face get_face ()
const;
566 mutable FT_Face m_face;
569 void push_new_line ();
571 void update_line_bbox ();
573 void compute_bbox ();
575 int compute_line_xoffset (
const Matrix& lb)
const;
577 FT_UInt process_character (FT_ULong code, FT_UInt previous,
578 std::string& sub_font);
583 std::list<text_renderer::string>& lst,
Matrix& bbox,
584 int halign,
int valign,
double rotation,
605 std::list<Matrix> m_line_bbox;
629 std::list<text_renderer::string> m_strlist;
642 double m_max_fontsize;
650ft_text_renderer::set_font (
const std::string& name,
651 const std::string& weight,
652 const std::string& angle,
double size)
655 m_font = ft_font (name, weight, angle, size,
nullptr);
659ft_text_renderer::get_system_fonts ()
661 return ft_manager::get_system_fonts ();
665ft_text_renderer::push_new_line ()
673 FT_Face face = m_font.get_face ();
679 m_line_bbox.push_back (bb);
681 m_xoffset = m_yoffset = 0;
682 m_ymin = m_ymax = m_deltax = 0;
692 Matrix old_bbox = m_line_bbox.front ();
693 m_line_bbox.pop_front ();
694 Matrix new_bbox = m_line_bbox.front ();
696 m_xoffset = m_line_xoffset = compute_line_xoffset (new_bbox);
697 m_line_yoffset -= (-old_bbox(1) + math::round (0.4 * m_max_fontsize)
698 + (new_bbox(3) + new_bbox(1)));
700 m_ymin = m_ymax = m_deltax = 0;
707ft_text_renderer::compute_line_xoffset (
const Matrix& lb)
const
709 if (! m_bbox.isempty ())
716 return (m_bbox(2) - lb(2)) / 2;
718 return (m_bbox(2) - lb(2));
726ft_text_renderer::compute_bbox ()
733 switch (m_line_bbox.size ())
739 m_bbox = m_line_bbox.front ().extract (0, 0, 0, 3);
743 for (
const auto& lbox : m_line_bbox)
745 if (m_bbox.isempty ())
746 m_bbox = lbox.extract (0, 0, 0, 3);
749 double delta = math::round (0.4 * m_max_fontsize) + lbox(3);
752 m_bbox(2) = math::max (m_bbox(2), lbox(2));
760ft_text_renderer::update_line_bbox ()
767 if (m_mode == MODE_BBOX)
769 Matrix& bb = m_line_bbox.back ();
773 bb(3) = (m_ymax + 1) - m_ymin;
780ft_text_renderer::set_mode (
int m)
787 m_xoffset = m_line_yoffset = m_yoffset = 0;
788 m_max_fontsize = 0.0;
789 m_bbox =
Matrix (1, 4, 0.0);
790 m_line_bbox.clear ();
795 if (m_bbox.numel () != 4)
797 ::error (
"ft_text_renderer: invalid bounding box, cannot render");
799 m_xoffset = m_line_yoffset = m_yoffset = 0;
807 m_xoffset = compute_line_xoffset (m_line_bbox.front ());
808 m_line_yoffset = -m_bbox(1);
814 error (
"ft_text_renderer: invalid mode '%d'", m_mode);
820is_opaque (
const FT_GlyphSlot& glyph,
const int x,
const int y)
824 int pitch = std::abs (glyph->bitmap.pitch);
825 unsigned char *row = &glyph->bitmap.buffer[pitch * y];
826 char cvalue = row[
x >> 3];
828 return ((cvalue & (128 >> (
x & 7))) != 0);
832ft_text_renderer::process_character (FT_ULong code, FT_UInt previous,
833 std::string& sub_name)
835 FT_Face face = m_font.get_face ();
837 sub_name = face->family_name;
839 FT_UInt glyph_index = 0;
843 glyph_index = FT_Get_Char_Index (face, code);
845 if (code !=
'\n' && code !=
'\t'
847 || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)))
849#if defined (HAVE_FONTCONFIG)
851 FT_Face sub_face = ft_manager::get_font (m_font.get_name (),
852 m_font.get_weight (),
859 FT_Set_Char_Size (sub_face, 0, m_font.get_size ()*64, 0, 0);
861 glyph_index = FT_Get_Char_Index (sub_face, code);
864 && (FT_Load_Glyph (sub_face, glyph_index, FT_LOAD_DEFAULT)
867 static std::string prev_sub_name;
869 if (prev_sub_name.empty ()
870 || prev_sub_name != std::string (sub_face->family_name))
872 prev_sub_name = sub_face->family_name;
874 "text_renderer: substituting font to '%s' for some characters",
875 sub_face->family_name);
878 ft_font saved_font = m_font;
880 m_font = ft_font (m_font.get_name (), m_font.get_weight (),
881 m_font.get_angle (), m_font.get_size (),
884 process_character (code, previous, sub_name);
891 warn_missing_glyph (code);
897 warn_missing_glyph (code);
901 warn_missing_glyph (code);
904 else if ((code ==
'\n') || (code ==
'\t'))
906 glyph_index = FT_Get_Char_Index (face,
' ');
908 || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT))
911 warn_missing_glyph (
' ');
913 else if (code ==
'\n')
919 int x_tab = 4 * (face->glyph->advance.x >> 6);
920 m_xoffset = (1 + std::floor (1. * m_xoffset / x_tab)) * x_tab;
928 if (FT_Render_Glyph (face->glyph, (m_antialias
929 ? FT_RENDER_MODE_NORMAL
930 : FT_RENDER_MODE_MONO)))
933 warn_glyph_render (code);
937 FT_Bitmap& bitmap = face->glyph->bitmap;
944 FT_Get_Kerning (face, previous, glyph_index,
945 FT_KERNING_DEFAULT, &delta);
947 m_xoffset += (delta.x >> 6);
950 x0 = m_xoffset + face->glyph->bitmap_left;
951 y0 = m_line_yoffset + m_yoffset
952 + (face->glyph->bitmap_top - 1);
961 for (
int r = 0;
static_cast<unsigned int> (r) < bitmap.rows; r++)
962 for (
int c = 0;
static_cast<unsigned int> (c) < bitmap.width; c++)
966 ? bitmap.buffer[r*bitmap.width+c]
967 : (
is_opaque (face->glyph, c, r) ? 255 : 0));
969 if (x0+c < 0 || x0+c >= m_pixels.dim2 ()
970 || y0-r < 0 || y0-r >= m_pixels.dim3 ())
975 else if (m_pixels(3, x0+c, y0-r).value () == 0)
977 m_pixels(0, x0+c, y0-r) = m_color(0);
978 m_pixels(1, x0+c, y0-r) = m_color(1);
979 m_pixels(2, x0+c, y0-r) = m_color(2);
980 m_pixels(3, x0+c, y0-r) = pix;
984 m_xoffset += (face->glyph->advance.x >> 6);
989 Matrix& bb = m_line_bbox.back ();
998 FT_Get_Kerning (face, previous, glyph_index,
999 FT_KERNING_DEFAULT, &delta);
1001 m_xoffset += (delta.x >> 6);
1007 m_xoffset += (face->glyph->advance.x >> 6);
1008 bb(2) = math::max (bb(2), m_xoffset);
1012 if (FT_Get_Glyph (face->glyph, &glyph))
1013 warn_glyph_render (code);
1017 FT_Glyph_Get_CBox (glyph, FT_GLYPH_BBOX_UNSCALED,
1019 m_deltax = (glyph_bbox.xMax - face->glyph->advance.x) >> 6;
1020 m_ymin = math::min ((glyph_bbox.yMin >> 6) + m_yoffset,
1022 m_ymax = math::max ((glyph_bbox.yMax >> 6) + m_yoffset,
1024 FT_Done_Glyph (glyph);
1025 update_line_bbox ();
1036ft_text_renderer::text_to_strlist (
const std::string& txt,
1037 std::list<text_renderer::string>& lst,
1039 int ha,
int va,
double rot,
1046 m_strlist = std::list<text_renderer::string> ();
1050 restore_var2 (m_strlist);
1052 m_do_strlist =
true;
1054 text_to_pixels (txt, pxls, box, ha, va, rot, interp,
false);
1062 if (m_font.is_valid ())
1064 m_max_fontsize = std::max (m_max_fontsize, m_font.get_size ());
1065 FT_UInt glyph_index, previous = 0;
1068 const uint8_t *c =
reinterpret_cast<const uint8_t *
> (str.c_str ());
1071 std::size_t n = str.size ();
1072 std::size_t icurr = 0;
1073 std::size_t ibegin = 0;
1078 std::string fname = m_font.get_face ()->family_name;
1080 if (fname.find (
" ") != std::string::npos)
1081 fname =
"'" + fname +
"'";
1083 fs.set_family (fname);
1085 std::vector<double> xdata;
1086 std::string sub_name;
1102 if (m_do_strlist && m_mode == MODE_RENDER)
1108 fs.set_y (m_line_yoffset + m_yoffset);
1109 fs.set_color (m_color);
1111 std::string s = str.substr (ibegin, icurr - ibegin);
1115 fs.set_y (m_line_yoffset + m_yoffset);
1116 fs.set_xdata (xdata);
1117 fs.set_family (fname);
1118 m_strlist.push_back (fs);
1122 xdata.push_back (m_xoffset);
1125 glyph_index = process_character (u32_c, previous, sub_name);
1127 if (m_do_strlist && m_mode == MODE_RENDER && ! sub_name.empty ())
1130 std::string tmp_family = fs.get_family ();
1132 if (tmp_family.find (sub_name) == std::string::npos)
1134 if (sub_name.find (
" ") != std::string::npos)
1135 sub_name =
"'" + sub_name +
"'";
1137 fs.set_family (tmp_family +
", " + sub_name);
1145 if (m_do_strlist && m_mode == MODE_RENDER)
1151 m_line_xoffset, m_yoffset);
1155 previous = glyph_index;
1160 if (m_do_strlist && m_mode == MODE_RENDER
1161 && ! fs.get_string ().empty ())
1163 fs.set_y (m_line_yoffset + m_yoffset);
1164 fs.set_color (m_color);
1165 fs.set_xdata (xdata);
1166 m_strlist.push_back (fs);
1176 ft_font saved_font (m_font);
1181 m_font = saved_font;
1182 m_color = saved_color;
1188 ft_font saved_font (m_font);
1189 int saved_line_yoffset = m_line_yoffset;
1190 int saved_yoffset = m_yoffset;
1192 double sz = m_font.get_size ();
1195 set_font (m_font.get_name (), m_font.get_weight (), m_font.get_angle (),
1196 std::max (5.0, sz * 0.7));
1198 if (m_font.is_valid ())
1201 m_yoffset -= std::ceil (sz * 0.15);
1203 if (m_mode == MODE_BBOX)
1204 update_line_bbox ();
1209 m_font = saved_font;
1212 if (m_line_yoffset == saved_line_yoffset)
1213 m_yoffset = saved_yoffset;
1219 ft_font saved_font (m_font);
1220 int saved_line_yoffset = m_line_yoffset;
1221 int saved_yoffset = m_yoffset;
1223 double sz = m_font.get_size ();
1226 set_font (m_font.get_name (), m_font.get_weight (), m_font.get_angle (),
1227 std::max (5.0, sz * 0.7));
1229 if (saved_font.is_valid ())
1232 m_yoffset += std::ceil (sz * 0.4);
1234 if (m_mode == MODE_BBOX)
1235 update_line_bbox ();
1240 m_font = saved_font;
1243 if (m_line_yoffset == saved_line_yoffset)
1244 m_yoffset = saved_yoffset;
1250 if (m_mode == MODE_RENDER)
1262 set_font (m_font.get_name (), m_font.get_weight (),
1263 m_font.get_angle (), sz);
1265 if (m_mode == MODE_BBOX)
1266 update_line_bbox ();
1272 set_font (e.
get_fontname (), m_font.get_weight (), m_font.get_angle (),
1273 m_font.get_size ());
1275 if (m_mode == MODE_BBOX)
1276 update_line_bbox ();
1285 set_font (m_font.get_name (),
"normal",
"normal", m_font.get_size ());
1289 set_font (m_font.get_name (),
"bold",
"normal", m_font.get_size ());
1293 set_font (m_font.get_name (),
"normal",
"italic", m_font.get_size ());
1297 set_font (m_font.get_name (),
"normal",
"oblique", m_font.get_size ());
1301 if (m_mode == MODE_BBOX)
1302 update_line_bbox ();
1310 std::vector<double> xdata (1, m_xoffset);
1315 std::string sub_name;
1317 process_character (code, 0, sub_name);
1319 if (m_do_strlist && m_mode == MODE_RENDER)
1321 if (! sub_name.empty ())
1324 std::string tmp_family = fs.get_family ();
1326 if (tmp_family.find (sub_name) == std::string::npos)
1328 if (sub_name.find (
" ") != std::string::npos)
1329 sub_name =
"'" + sub_name +
"'";
1331 fs.set_family (tmp_family +
", " + sub_name);
1336 fs.set_xdata (xdata);
1339 else if (m_font.is_valid ())
1342 if (m_do_strlist && m_mode == MODE_RENDER && fs.get_code ())
1344 fs.set_y (m_line_yoffset + m_yoffset);
1345 fs.set_color (m_color);
1346 fs.set_family (m_font.get_face ()->family_name);
1347 m_strlist.push_back (fs);
1354 int saved_xoffset = m_xoffset;
1355 int max_xoffset = m_xoffset;
1357 for (
auto *txt_elt : e)
1359 m_xoffset = saved_xoffset;
1360 txt_elt->accept (*
this);
1361 max_xoffset = math::max (m_xoffset, max_xoffset);
1364 m_xoffset = max_xoffset;
1368ft_text_renderer::reset ()
1370 set_mode (MODE_BBOX);
1371 set_color (
Matrix (1, 3, 0.0));
1372 m_strlist = std::list<text_renderer::string> ();
1376ft_text_renderer::set_color (
const Matrix& c)
1378 if (c.
numel () == 3)
1380 m_color(0) =
static_cast<uint8_t
> (c(0)*255);
1381 m_color(1) =
static_cast<uint8_t
> (c(1)*255);
1382 m_color(2) =
static_cast<uint8_t
> (c(2)*255);
1385 ::warning (
"ft_text_renderer::set_color: invalid color");
1391 set_mode (MODE_BBOX);
1396 set_mode (MODE_RENDER);
1398 if (m_pixels.numel () > 0)
1402 rotate_pixels (m_pixels, rotation);
1414ft_text_renderer::get_extent (
text_element *elt,
double rotation)
1416 set_mode (MODE_BBOX);
1420 Matrix extent (1, 2, 0.0);
1422 switch (rotation_to_mode (rotation))
1426 extent(0) = m_bbox(2);
1427 extent(1) = m_bbox(3);
1432 extent(0) = m_bbox(3);
1433 extent(1) = m_bbox(2);
1440ft_text_renderer::get_extent (
const std::string& txt,
double rotation,
1444 Matrix extent = get_extent (elt, rotation);
1451ft_text_renderer::text_to_pixels (
const std::string& txt,
1453 int _halign,
int valign,
double rotation,
1455 bool handle_rotation)
1457 int rot_mode = rotation_to_mode (rotation);
1462 pxls = render (elt, box, rot_mode);
1470 fix_bbox_anchor (box, m_halign, valign, rot_mode, handle_rotation);
1473ft_text_renderer::ft_font::ft_font (
const ft_font& ft)
1476#if defined (HAVE_FT_REFERENCE_FACE)
1477 FT_Face ft_face = ft.get_face ();
1479 if (ft_face && FT_Reference_Face (ft_face) == 0)
1484ft_text_renderer::ft_font&
1485ft_text_renderer::ft_font::operator = (
const ft_font& ft)
1493 FT_Done_Face (m_face);
1497#if defined (HAVE_FT_REFERENCE_FACE)
1498 FT_Face ft_face = ft.get_face ();
1500 if (ft_face && FT_Reference_Face (ft_face) == 0)
1509ft_text_renderer::ft_font::get_face ()
const
1511 if (! m_face && ! m_name.empty ())
1513 m_face = ft_manager::get_font (m_name, m_weight, m_angle, m_size);
1517 if (FT_Set_Char_Size (m_face, 0, m_size*64, 0, 0))
1518 ::warning (
"ft_text_renderer: unable to set font size to %g", m_size);
1521 ::warning (
"ft_text_renderer: unable to load appropriate font");
1527OCTAVE_END_NAMESPACE(octave)
1536#if defined (HAVE_FREETYPE)
1537 return new ft_text_renderer ();
1543OCTAVE_END_NAMESPACE(octave)
bool isempty() const
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
virtual Matrix get_extent(text_element *elt, double rotation)=0
virtual void text_to_pixels(const std::string &txt, uint8NDArray &pxls, Matrix &bbox, int halign, int valign, double rotation, const caseless_str &interpreter, bool handle_rotation)=0
virtual void text_to_strlist(const std::string &txt, std::list< text_renderer::string > &lst, Matrix &box, int halign, int valign, double rotation, const caseless_str &interpreter="tex")=0
virtual void set_color(const Matrix &c)=0
virtual void set_anti_aliasing(bool val)=0
virtual octave_map get_system_fonts()=0
virtual void set_font(const std::string &name, const std::string &weight, const std::string &angle, double size)=0
Vector representing the dimensions (size) of an Array.
void assign(const std::string &k, const Cell &val)
const std::string & get_fontname() const
double get_fontsize() const
fontstyle get_fontstyle() const
std::string string_value() const
uint32_t get_symbol_code() const
virtual void accept(text_processor &p)=0
virtual text_element * parse(const std::string &s)=0
virtual void visit(text_element_string &)
font & operator=(const font &ft)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
base_text_renderer * make_ft_text_renderer()
bool is_opaque(const FT_GlyphSlot &glyph, const int x, const int y)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
F77_RET_T const F77_DBLE const F77_DBLE * f
intNDArray< octave_uint8 > uint8NDArray
int octave_u8_strmbtouc_wrapper(uint32_t *puc, const uint8_t *src)