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"
41 #include FT_FREETYPE_H
44 #if defined (HAVE_FONTCONFIG)
45 # include <fontconfig/fontconfig.h>
48 #if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
49 # pragma GCC diagnostic pop
74 warn_missing_glyph (FT_ULong c)
77 "text_renderer: skipping missing glyph for character '%lx'", c);
81 warn_glyph_render (FT_ULong c)
84 "text_renderer: unable to render glyph for character '%lx'", c);
87 #if defined (_MSC_VER)
98 static void ft_face_destroyed (
void *
object);
106 : m_library (), m_freetype_initialized (false),
107 m_fontconfig_initialized (false)
109 if (FT_Init_FreeType (&m_library))
110 error (
"unable to initialize FreeType library");
112 m_freetype_initialized =
true;
114 #if defined (HAVE_FONTCONFIG)
116 error (
"unable to initialize fontconfig library");
118 m_fontconfig_initialized =
true;
124 OCTAVE_DISABLE_COPY_MOVE (ft_manager)
130 if (m_freetype_initialized)
131 FT_Done_FreeType (m_library);
133 #if defined (HAVE_FONTCONFIG)
145 static bool instance_ok ()
151 s_instance =
new ft_manager ();
158 static void cleanup_instance ()
159 {
delete s_instance; s_instance =
nullptr; }
161 static FT_Face get_font (
const std::string& name,
const std::string& weight,
162 const std::string& angle,
double size,
165 return (instance_ok ()
166 ? s_instance->do_get_font (name, weight, angle, size, c)
172 return (instance_ok ()
173 ? s_instance->do_get_system_fonts ()
177 static void font_destroyed (FT_Face face)
180 s_instance->do_font_destroyed (face);
185 typedef std::pair<std::string, double> ft_key;
186 typedef std::map<ft_key, FT_Face> ft_cache;
194 #if defined (HAVE_FONTCONFIG)
195 FcConfig *config = FcConfigGetCurrent();
196 FcPattern *pat = FcPatternCreate ();
197 FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, FC_SLANT, FC_WEIGHT,
198 FC_CHARSET,
nullptr);
199 FcFontSet *fs = FcFontList (config, pat, os);
204 FcCharSet *minimal_charset = FcCharSetCreate ();
205 for (
int i = 32; i < 127; i++)
206 FcCharSetAddChar (minimal_charset,
static_cast<FcChar32
> (i));
209 fields(0) =
"family";
211 fields(2) =
"weight";
212 fields(3) =
"suitable";
220 unsigned char *family;
222 for (
int i = 0; fs && i < fs->nfont; i++)
224 FcPattern *font = fs->fonts[i];
225 if (FcPatternGetString (font, FC_FAMILY, 0, &family)
227 families(i) = std::string (
reinterpret_cast<char *
> (family));
229 families(i) =
"unknown";
231 if (FcPatternGetInteger (font, FC_SLANT, 0, &val)
233 angles(i) = (val == FC_SLANT_ITALIC
234 || val == FC_SLANT_OBLIQUE)
235 ?
"italic" :
"normal";
237 angles(i) =
"unknown";
239 if (FcPatternGetInteger (font, FC_WEIGHT, 0, &val)
241 weights(i) = (val == FC_WEIGHT_BOLD
242 || val == FC_WEIGHT_DEMIBOLD)
245 weights(i) =
"unknown";
248 if (FcPatternGetCharSet (font, FC_CHARSET, 0, &cset)
250 suitable(i) = (FcCharSetIsSubset (minimal_charset, cset)
258 font_map.
assign (
"family", families);
259 font_map.
assign (
"angle", angles);
260 font_map.
assign (
"weight", weights);
261 font_map.
assign (
"suitable", suitable);
265 FcFontSetDestroy (fs);
267 FcPatternDestroy (pat);
269 FcObjectSetDestroy (os);
271 FcCharSetDestroy (minimal_charset);
279 FT_Face do_get_font (
const std::string& name,
const std::string& weight,
280 const std::string& angle,
double size,
281 FT_ULong search_code_point)
283 FT_Face retval =
nullptr;
285 #if defined (HAVE_FT_REFERENCE_FACE)
289 ft_key key (name +
':' + weight +
':' + angle +
':'
290 + std::to_string (search_code_point), size);
291 ft_cache::const_iterator it = m_cache.find (key);
293 if (it != m_cache.end ())
295 FT_Reference_Face (it->second);
300 static std::string fonts_dir;
302 if (fonts_dir.empty ())
304 fonts_dir = sys::env::getenv (
"OCTAVE_FONTS_DIR");
306 if (fonts_dir.empty ())
307 #if defined (SYSTEM_FREEFONT_DIR)
308 fonts_dir = SYSTEM_FREEFONT_DIR;
318 if (! fonts_dir.empty ())
322 if (weight ==
"bold")
325 if (angle ==
"italic" || angle ==
"oblique")
331 #if defined (HAVE_FONTCONFIG)
332 if ((search_code_point != 0 || name !=
"*") && m_fontconfig_initialized)
334 int fc_weight, fc_angle;
336 if (weight ==
"bold")
337 fc_weight = FC_WEIGHT_BOLD;
339 fc_weight = FC_WEIGHT_NORMAL;
341 if (angle ==
"italic")
342 fc_angle = FC_SLANT_ITALIC;
343 else if (angle ==
"oblique")
344 fc_angle = FC_SLANT_OBLIQUE;
346 fc_angle = FC_SLANT_ROMAN;
348 FcPattern *pat = FcPatternCreate ();
350 FcPatternAddString (pat, FC_FAMILY,
351 (
reinterpret_cast<const FcChar8 *
>
354 FcPatternAddInteger (pat, FC_WEIGHT, fc_weight);
355 FcPatternAddInteger (pat, FC_SLANT, fc_angle);
356 FcPatternAddDouble (pat, FC_PIXEL_SIZE, size);
358 if (search_code_point > 0)
360 FcCharSet *minimal_charset = FcCharSetCreate ();
361 FcCharSetAddChar (minimal_charset,
362 static_cast<FcChar32
> (search_code_point));
363 FcPatternAddCharSet (pat, FC_CHARSET, minimal_charset);
366 if (FcConfigSubstitute (
nullptr, pat, FcMatchPattern))
371 FcDefaultSubstitute (pat);
373 match = FcFontMatch (
nullptr, pat, &res);
381 FcPatternGetString (match, FC_FILE, 0, &tmp);
382 file =
reinterpret_cast<char *
> (tmp);
385 ::warning (
"could not match any font: %s-%s-%s-%g, using default font",
386 name.c_str (), weight.c_str (), angle.c_str (),
390 FcPatternDestroy (match);
393 FcPatternDestroy (pat);
398 ::warning (
"unable to find default font files");
403 if (FT_New_Face (m_library, ascii_file.c_str (), 0, &retval))
404 ::warning (
"ft_manager: unable to load font: %s", file.c_str ());
405 #if defined (HAVE_FT_REFERENCE_FACE)
412 retval->generic.data =
new ft_key (key);
413 retval->generic.finalizer = ft_face_destroyed;
416 if (FT_Reference_Face (retval) == 0)
417 m_cache[key] = retval;
425 void do_font_destroyed (FT_Face face)
427 if (face->generic.data)
429 ft_key *pkey =
reinterpret_cast<ft_key *
> (face->generic.data);
431 m_cache.erase (*pkey);
433 face->generic.data =
nullptr;
440 static ft_manager *s_instance;
447 FT_Library m_library;
448 bool m_freetype_initialized;
449 bool m_fontconfig_initialized;
452 ft_manager *ft_manager::s_instance =
nullptr;
455 ft_face_destroyed (
void *
object)
457 ft_manager::font_destroyed (
reinterpret_cast<FT_Face
> (
object));
476 m_xoffset (0), m_line_yoffset (0), m_yoffset (0), m_mode (MODE_BBOX),
477 m_color (
dim_vector (1, 3), 0), m_do_strlist (false), m_strlist (),
478 m_line_xoffset (0), m_ymin (0), m_ymax (0), m_deltax (0),
479 m_max_fontsize (0), m_antialias (true)
482 OCTAVE_DISABLE_COPY_MOVE (ft_text_renderer)
484 ~ft_text_renderer () =
default;
510 Matrix get_boundingbox ()
const {
return m_bbox; }
513 int rotation = ROTATION_0);
516 Matrix get_extent (
const std::string& txt,
double rotation,
519 void set_anti_aliasing (
bool val) { m_antialias = val; };
521 void set_font (
const std::string& name,
const std::string& weight,
522 const std::string& angle,
double size);
526 void set_color (
const Matrix& c);
528 void set_mode (
int m);
530 void text_to_pixels (
const std::string& txt,
532 int halign,
int valign,
double rotation,
534 bool handle_rotation);
548 ft_font (
const std::string& nm,
const std::string& wt,
549 const std::string& ang,
double sz, FT_Face
f =
nullptr)
553 ft_font (
const ft_font& ft);
558 FT_Done_Face (m_face);
561 ft_font& operator = (
const ft_font& ft);
563 bool is_valid ()
const {
return get_face (); }
565 FT_Face get_face ()
const;
569 mutable FT_Face m_face;
572 void push_new_line ();
574 void update_line_bbox ();
576 void compute_bbox ();
578 int compute_line_xoffset (
const Matrix& lb)
const;
580 FT_UInt process_character (FT_ULong code, FT_UInt previous,
581 std::string& sub_font);
585 void text_to_strlist (
const std::string& txt,
586 std::list<text_renderer::string>& lst,
Matrix& bbox,
587 int halign,
int valign,
double rotation,
608 std::list<Matrix> m_line_bbox;
632 std::list<text_renderer::string> m_strlist;
645 double m_max_fontsize;
653 ft_text_renderer::set_font (
const std::string& name,
654 const std::string& weight,
655 const std::string& angle,
double size)
658 m_font = ft_font (name, weight, angle, size,
nullptr);
662 ft_text_renderer::get_system_fonts ()
664 return ft_manager::get_system_fonts ();
668 ft_text_renderer::push_new_line ()
676 FT_Face face = m_font.get_face ();
682 m_line_bbox.push_back (bb);
684 m_xoffset = m_yoffset = 0;
685 m_ymin = m_ymax = m_deltax = 0;
695 Matrix old_bbox = m_line_bbox.front ();
696 m_line_bbox.pop_front ();
697 Matrix new_bbox = m_line_bbox.front ();
699 m_xoffset = m_line_xoffset = compute_line_xoffset (new_bbox);
700 m_line_yoffset -= (-old_bbox(1) +
math::round (0.4 * m_max_fontsize)
701 + (new_bbox(3) + new_bbox(1)));
703 m_ymin = m_ymax = m_deltax = 0;
710 ft_text_renderer::compute_line_xoffset (
const Matrix& lb)
const
712 if (! m_bbox.isempty ())
719 return (m_bbox(2) - lb(2)) / 2;
721 return (m_bbox(2) - lb(2));
729 ft_text_renderer::compute_bbox ()
736 switch (m_line_bbox.size ())
742 m_bbox = m_line_bbox.front ().extract (0, 0, 0, 3);
746 for (
const auto& lbox : m_line_bbox)
748 if (m_bbox.isempty ())
749 m_bbox = lbox.extract (0, 0, 0, 3);
752 double delta =
math::round (0.4 * m_max_fontsize) + lbox(3);
755 m_bbox(2) =
math::max (m_bbox(2), lbox(2));
763 ft_text_renderer::update_line_bbox ()
770 if (m_mode == MODE_BBOX)
772 Matrix& bb = m_line_bbox.back ();
776 bb(3) = (m_ymax + 1) - m_ymin;
783 ft_text_renderer::set_mode (
int m)
790 m_xoffset = m_line_yoffset = m_yoffset = 0;
791 m_max_fontsize = 0.0;
792 m_bbox =
Matrix (1, 4, 0.0);
793 m_line_bbox.clear ();
798 if (m_bbox.numel () != 4)
800 ::error (
"ft_text_renderer: invalid bounding box, cannot render");
802 m_xoffset = m_line_yoffset = m_yoffset = 0;
810 m_xoffset = compute_line_xoffset (m_line_bbox.front ());
811 m_line_yoffset = -m_bbox(1);
817 error (
"ft_text_renderer: invalid mode '%d'", m_mode);
823 is_opaque (
const FT_GlyphSlot& glyph,
const int x,
const int y)
827 int pitch = std::abs (glyph->bitmap.pitch);
828 unsigned char *row = &glyph->bitmap.buffer[pitch * y];
829 char cvalue = row[
x >> 3];
831 return ((cvalue & (128 >> (
x & 7))) != 0);
835 ft_text_renderer::process_character (FT_ULong code, FT_UInt previous,
836 std::string& sub_name)
838 FT_Face face = m_font.get_face ();
840 sub_name = face->family_name;
842 FT_UInt glyph_index = 0;
846 glyph_index = FT_Get_Char_Index (face, code);
848 if (code !=
'\n' && code !=
'\t'
850 || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)))
852 #if defined (HAVE_FONTCONFIG)
854 FT_Face sub_face = ft_manager::get_font (m_font.get_name (),
855 m_font.get_weight (),
862 FT_Set_Char_Size (sub_face, 0, m_font.get_size ()*64, 0, 0);
864 glyph_index = FT_Get_Char_Index (sub_face, code);
867 && (FT_Load_Glyph (sub_face, glyph_index, FT_LOAD_DEFAULT)
870 static std::string prev_sub_name;
872 if (prev_sub_name.empty ()
873 || prev_sub_name != std::string (sub_face->family_name))
875 prev_sub_name = sub_face->family_name;
877 "text_renderer: substituting font to '%s' for some characters",
878 sub_face->family_name);
881 ft_font saved_font = m_font;
883 m_font = ft_font (m_font.get_name (), m_font.get_weight (),
884 m_font.get_angle (), m_font.get_size (),
887 process_character (code, previous, sub_name);
894 warn_missing_glyph (code);
900 warn_missing_glyph (code);
904 warn_missing_glyph (code);
907 else if ((code ==
'\n') || (code ==
'\t'))
909 glyph_index = FT_Get_Char_Index (face,
' ');
911 || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT))
914 warn_missing_glyph (
' ');
916 else if (code ==
'\n')
922 int x_tab = 4 * (face->glyph->advance.x >> 6);
923 m_xoffset = (1 +
std::floor (1. * m_xoffset / x_tab)) * x_tab;
931 if (FT_Render_Glyph (face->glyph, (m_antialias
932 ? FT_RENDER_MODE_NORMAL
933 : FT_RENDER_MODE_MONO)))
936 warn_glyph_render (code);
940 FT_Bitmap& bitmap = face->glyph->bitmap;
947 FT_Get_Kerning (face, previous, glyph_index,
948 FT_KERNING_DEFAULT, &delta);
950 m_xoffset += (delta.x >> 6);
953 x0 = m_xoffset + face->glyph->bitmap_left;
954 y0 = m_line_yoffset + m_yoffset
955 + (face->glyph->bitmap_top - 1);
964 for (
int r = 0;
static_cast<unsigned int> (
r) < bitmap.rows;
r++)
965 for (
int c = 0;
static_cast<unsigned int> (c) < bitmap.width; c++)
969 ? bitmap.buffer[
r*bitmap.width+c]
972 if (x0+c < 0 || x0+c >= m_pixels.dim2 ()
973 || y0-
r < 0 || y0-
r >= m_pixels.dim3 ())
978 else if (m_pixels(3, x0+c, y0-
r).value () == 0)
980 m_pixels(0, x0+c, y0-
r) = m_color(0);
981 m_pixels(1, x0+c, y0-
r) = m_color(1);
982 m_pixels(2, x0+c, y0-
r) = m_color(2);
983 m_pixels(3, x0+c, y0-
r) = pix;
987 m_xoffset += (face->glyph->advance.x >> 6);
992 Matrix& bb = m_line_bbox.back ();
1001 FT_Get_Kerning (face, previous, glyph_index,
1002 FT_KERNING_DEFAULT, &delta);
1004 m_xoffset += (delta.x >> 6);
1010 m_xoffset += (face->glyph->advance.x >> 6);
1015 if (FT_Get_Glyph (face->glyph, &glyph))
1016 warn_glyph_render (code);
1020 FT_Glyph_Get_CBox (glyph, FT_GLYPH_BBOX_UNSCALED,
1022 m_deltax = (glyph_bbox.xMax - face->glyph->advance.x) >> 6;
1023 m_ymin =
math::min ((glyph_bbox.yMin >> 6) + m_yoffset,
1025 m_ymax =
math::max ((glyph_bbox.yMax >> 6) + m_yoffset,
1027 FT_Done_Glyph (glyph);
1028 update_line_bbox ();
1039 ft_text_renderer::text_to_strlist (
const std::string& txt,
1040 std::list<text_renderer::string>& lst,
1042 int ha,
int va,
double rot,
1049 m_strlist = std::list<text_renderer::string> ();
1053 restore_var2 (m_strlist);
1055 m_do_strlist =
true;
1057 text_to_pixels (txt, pxls, box, ha, va, rot, interp,
false);
1065 if (m_font.is_valid ())
1067 m_max_fontsize =
std::max (m_max_fontsize, m_font.get_size ());
1068 FT_UInt glyph_index, previous = 0;
1071 const uint8_t *c =
reinterpret_cast<const uint8_t *
> (str.c_str ());
1074 std::size_t
n = str.size ();
1075 std::size_t icurr = 0;
1076 std::size_t ibegin = 0;
1081 std::string fname = m_font.get_face ()->family_name;
1083 if (fname.find (
" ") != std::string::npos)
1084 fname =
"'" + fname +
"'";
1086 fs.set_family (fname);
1088 std::vector<double> xdata;
1089 std::string sub_name;
1105 if (m_do_strlist && m_mode == MODE_RENDER)
1111 fs.set_y (m_line_yoffset + m_yoffset);
1112 fs.set_color (m_color);
1114 std::string s = str.substr (ibegin, icurr - ibegin);
1118 fs.set_y (m_line_yoffset + m_yoffset);
1119 fs.set_xdata (xdata);
1120 fs.set_family (fname);
1121 m_strlist.push_back (fs);
1125 xdata.push_back (m_xoffset);
1128 glyph_index = process_character (u32_c, previous, sub_name);
1130 if (m_do_strlist && m_mode == MODE_RENDER && ! sub_name.empty ())
1133 std::string tmp_family = fs.get_family ();
1135 if (tmp_family.find (sub_name) == std::string::npos)
1137 if (sub_name.find (
" ") != std::string::npos)
1138 sub_name =
"'" + sub_name +
"'";
1140 fs.set_family (tmp_family +
", " + sub_name);
1148 if (m_do_strlist && m_mode == MODE_RENDER)
1154 m_line_xoffset, m_yoffset);
1158 previous = glyph_index;
1163 if (m_do_strlist && m_mode == MODE_RENDER
1164 && ! fs.get_string ().empty ())
1166 fs.set_y (m_line_yoffset + m_yoffset);
1167 fs.set_color (m_color);
1168 fs.set_xdata (xdata);
1169 m_strlist.push_back (fs);
1179 ft_font saved_font (m_font);
1184 m_font = saved_font;
1185 m_color = saved_color;
1191 ft_font saved_font (m_font);
1192 int saved_line_yoffset = m_line_yoffset;
1193 int saved_yoffset = m_yoffset;
1195 double sz = m_font.get_size ();
1198 set_font (m_font.get_name (), m_font.get_weight (), m_font.get_angle (),
1201 if (m_font.is_valid ())
1206 if (m_mode == MODE_BBOX)
1207 update_line_bbox ();
1212 m_font = saved_font;
1215 if (m_line_yoffset == saved_line_yoffset)
1216 m_yoffset = saved_yoffset;
1222 ft_font saved_font (m_font);
1223 int saved_line_yoffset = m_line_yoffset;
1224 int saved_yoffset = m_yoffset;
1226 double sz = m_font.get_size ();
1229 set_font (m_font.get_name (), m_font.get_weight (), m_font.get_angle (),
1232 if (saved_font.is_valid ())
1237 if (m_mode == MODE_BBOX)
1238 update_line_bbox ();
1243 m_font = saved_font;
1246 if (m_line_yoffset == saved_line_yoffset)
1247 m_yoffset = saved_yoffset;
1253 if (m_mode == MODE_RENDER)
1265 set_font (m_font.get_name (), m_font.get_weight (),
1266 m_font.get_angle (), sz);
1268 if (m_mode == MODE_BBOX)
1269 update_line_bbox ();
1275 set_font (e.
get_fontname (), m_font.get_weight (), m_font.get_angle (),
1276 m_font.get_size ());
1278 if (m_mode == MODE_BBOX)
1279 update_line_bbox ();
1288 set_font (m_font.get_name (),
"normal",
"normal", m_font.get_size ());
1292 set_font (m_font.get_name (),
"bold",
"normal", m_font.get_size ());
1296 set_font (m_font.get_name (),
"normal",
"italic", m_font.get_size ());
1300 set_font (m_font.get_name (),
"normal",
"oblique", m_font.get_size ());
1304 if (m_mode == MODE_BBOX)
1305 update_line_bbox ();
1313 std::vector<double> xdata (1, m_xoffset);
1318 std::string sub_name;
1320 process_character (code, 0, sub_name);
1322 if (m_do_strlist && m_mode == MODE_RENDER)
1324 if (! sub_name.empty ())
1327 std::string tmp_family = fs.get_family ();
1329 if (tmp_family.find (sub_name) == std::string::npos)
1331 if (sub_name.find (
" ") != std::string::npos)
1332 sub_name =
"'" + sub_name +
"'";
1334 fs.set_family (tmp_family +
", " + sub_name);
1339 fs.set_xdata (xdata);
1342 else if (m_font.is_valid ())
1345 if (m_do_strlist && m_mode == MODE_RENDER && fs.get_code ())
1347 fs.set_y (m_line_yoffset + m_yoffset);
1348 fs.set_color (m_color);
1349 fs.set_family (m_font.get_face ()->family_name);
1350 m_strlist.push_back (fs);
1357 int saved_xoffset = m_xoffset;
1358 int max_xoffset = m_xoffset;
1360 for (
auto *txt_elt : e)
1362 m_xoffset = saved_xoffset;
1363 txt_elt->accept (*
this);
1364 max_xoffset =
math::max (m_xoffset, max_xoffset);
1367 m_xoffset = max_xoffset;
1371 ft_text_renderer::reset ()
1373 set_mode (MODE_BBOX);
1374 set_color (
Matrix (1, 3, 0.0));
1375 m_strlist = std::list<text_renderer::string> ();
1379 ft_text_renderer::set_color (
const Matrix& c)
1381 if (c.
numel () == 3)
1383 m_color(0) =
static_cast<uint8_t
> (c(0)*255);
1384 m_color(1) =
static_cast<uint8_t
> (c(1)*255);
1385 m_color(2) =
static_cast<uint8_t
> (c(2)*255);
1388 ::warning (
"ft_text_renderer::set_color: invalid color");
1394 set_mode (MODE_BBOX);
1399 set_mode (MODE_RENDER);
1401 if (m_pixels.numel () > 0)
1405 rotate_pixels (m_pixels, rotation);
1417 ft_text_renderer::get_extent (
text_element *elt,
double rotation)
1419 set_mode (MODE_BBOX);
1423 Matrix extent (1, 2, 0.0);
1425 switch (rotation_to_mode (rotation))
1429 extent(0) = m_bbox(2);
1430 extent(1) = m_bbox(3);
1435 extent(0) = m_bbox(3);
1436 extent(1) = m_bbox(2);
1443 ft_text_renderer::get_extent (
const std::string& txt,
double rotation,
1447 Matrix extent = get_extent (elt, rotation);
1454 ft_text_renderer::text_to_pixels (
const std::string& txt,
1456 int _halign,
int valign,
double rotation,
1458 bool handle_rotation)
1460 int rot_mode = rotation_to_mode (rotation);
1465 pxls = render (elt, box, rot_mode);
1473 fix_bbox_anchor (box, m_halign, valign, rot_mode, handle_rotation);
1476 ft_text_renderer::ft_font::ft_font (
const ft_font& ft)
1479 #if defined (HAVE_FT_REFERENCE_FACE)
1480 FT_Face ft_face = ft.get_face ();
1482 if (ft_face && FT_Reference_Face (ft_face) == 0)
1487 ft_text_renderer::ft_font&
1488 ft_text_renderer::ft_font::operator = (
const ft_font& ft)
1496 FT_Done_Face (m_face);
1500 #if defined (HAVE_FT_REFERENCE_FACE)
1501 FT_Face ft_face = ft.get_face ();
1503 if (ft_face && FT_Reference_Face (ft_face) == 0)
1512 ft_text_renderer::ft_font::get_face ()
const
1514 if (! m_face && ! m_name.empty ())
1516 m_face = ft_manager::get_font (m_name, m_weight, m_angle, m_size);
1520 if (FT_Set_Char_Size (m_face, 0, m_size*64, 0, 0))
1521 ::warning (
"ft_text_renderer: unable to set font size to %g", m_size);
1524 ::warning (
"ft_text_renderer: unable to load appropriate font");
1530 OCTAVE_END_NAMESPACE(
octave)
1539 #if defined (HAVE_FREETYPE)
1540 return new ft_text_renderer ();
1546 OCTAVE_END_NAMESPACE(
octave)
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
bool isempty() const
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
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
std::string oct_fonts_dir()
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void() error(const char *fmt,...)
std::string dir_sep_str()
base_text_renderer * make_ft_text_renderer()
std::complex< T > floor(const std::complex< T > &x)
std::complex< T > ceil(const std::complex< T > &x)
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
std::string get_ASCII_filename(const std::string &orig_file_name, const bool allow_locale)
bool is_opaque(const FT_GlyphSlot &glyph, const int x, const int y)
intNDArray< octave_uint8 > uint8NDArray
int octave_u8_strmbtouc_wrapper(uint32_t *puc, const uint8_t *src)