24 #if defined (HAVE_CONFIG_H)
30 #if defined (HAVE_FREETYPE)
32 #if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
33 #pragma GCC diagnostic push
34 #pragma GCC diagnostic ignored "-Wold-style-cast"
38 #include FT_FREETYPE_H
40 #if defined (HAVE_FONTCONFIG)
41 # include <fontconfig/fontconfig.h>
44 #if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
45 #pragma GCC diagnostic pop
67 "text_renderer: skipping missing glyph for character '%x'", c);
74 "text_renderer: unable to render glyph for character '%x'", c);
77 #if defined (_MSC_VER)
109 error (
"unable to create ft_manager!");
119 return (instance_ok ()
120 ? instance->do_get_font (name, weight, angle, size)
127 instance->do_font_destroyed (face);
134 typedef std::pair<std::string, double>
ft_key;
151 : library (), freetype_initialized (
false), fontconfig_initialized (
false)
153 if (FT_Init_FreeType (&library))
154 error (
"unable to initialize FreeType library");
156 freetype_initialized =
true;
158 #if defined (HAVE_FONTCONFIG)
160 error (
"unable to initialize fontconfig library");
162 fontconfig_initialized =
true;
168 if (freetype_initialized)
169 FT_Done_FreeType (library);
171 #if defined (HAVE_FONTCONFIG)
186 #if defined (HAVE_FT_REFERENCE_FACE)
190 ft_key key (name +
":" + weight +
":" + angle, size);
191 ft_cache::const_iterator it = cache.find (key);
193 if (it != cache.end ())
195 FT_Reference_Face (it->second);
202 #if defined (HAVE_FONTCONFIG)
203 if (fontconfig_initialized)
205 int fc_weight, fc_angle;
207 if (weight ==
"bold")
208 fc_weight = FC_WEIGHT_BOLD;
209 else if (weight ==
"light")
210 fc_weight = FC_WEIGHT_LIGHT;
211 else if (weight ==
"demi")
212 fc_weight = FC_WEIGHT_DEMIBOLD;
214 fc_weight = FC_WEIGHT_NORMAL;
216 if (angle ==
"italic")
217 fc_angle = FC_SLANT_ITALIC;
218 else if (angle ==
"oblique")
219 fc_angle = FC_SLANT_OBLIQUE;
221 fc_angle = FC_SLANT_ROMAN;
223 FcPattern *pat = FcPatternCreate ();
225 FcPatternAddString (pat, FC_FAMILY,
226 (reinterpret_cast<const FcChar8*>
227 (name ==
"*" ?
"sans" : name.c_str ())));
229 FcPatternAddInteger (pat, FC_WEIGHT, fc_weight);
230 FcPatternAddInteger (pat, FC_SLANT, fc_angle);
231 FcPatternAddDouble (pat, FC_PIXEL_SIZE, size);
233 if (FcConfigSubstitute (0, pat, FcMatchPattern))
238 FcDefaultSubstitute (pat);
239 match = FcFontMatch (0, pat, &res);
247 FcPatternGetString (match, FC_FILE, 0, &tmp);
248 file =
reinterpret_cast<char*
> (
tmp);
251 ::warning (
"could not match any font: %s-%s-%s-%g",
252 name.c_str (), weight.c_str (), angle.c_str (),
256 FcPatternDestroy (match);
259 FcPatternDestroy (pat);
265 #if defined (OCTAVE_USE_WINDOWS_API)
266 file =
"C:/WINDOWS/Fonts/verdana.ttf";
274 if (FT_New_Face (library, file.c_str (), 0, &
retval))
275 ::warning (
"ft_manager: unable to load font: %s", file.c_str ());
276 #if defined (HAVE_FT_REFERENCE_FACE)
283 retval->generic.data =
new ft_key (key);
298 if (face->generic.data)
300 ft_key *pkey =
reinterpret_cast<ft_key*
> (face->generic.data);
304 face->generic.data = 0;
350 xoffset (0), line_yoffset (0), yoffset (0),
mode (MODE_BBOX),
383 int rotation = ROTATION_0);
392 void set_color (
const Matrix&
c);
394 void set_mode (
int m);
398 int halign,
int valign,
double rotation,
400 bool handle_rotation);
404 int rotation_to_mode (
double rotation)
const;
439 FT_Face get_face (
void)
const;
446 void push_new_line (
void);
448 void update_line_bbox (
void);
450 void compute_bbox (
void);
452 int compute_line_xoffset (
const Matrix& lb)
const;
454 FT_UInt process_character (FT_ULong
code, FT_UInt previous = 0);
459 std::list<text_renderer::string>& lst,
Matrix& bbox,
460 int halign,
int valign,
double rotation,
533 int asc = face->size->metrics.ascender >> 6;
534 int desc = face->size->metrics.descender >> 6;
535 int h = face->size->metrics.height >> 6;
560 line_yoffset += (old_bbox(1) - (new_bbox(1) + new_bbox(3)));
577 return (
bbox(2) - lb(2)) / 2;
579 return (
bbox(2) - lb(2));
604 for (std::list<Matrix>::const_iterator it =
line_bbox.begin ();
630 int asc =
font.
get_face ()->size->metrics.ascender >> 6;
631 int desc =
font.
get_face ()->size->metrics.descender >> 6;
639 int delta = bb(1) - (
yoffset + desc);
645 if ((
yoffset + asc) > (bb(1) + bb(3)))
649 int delta = (
yoffset + asc) - (bb(1) + bb(3));
673 ::error (
"ft_text_renderer: invalid bounding box, cannot render");
690 error (
"ft_text_renderer: invalid mode '%d'",
mode);
699 FT_UInt glyph_index = 0;
703 glyph_index = FT_Get_Char_Index (face, code);
707 || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)))
719 glyph_index = FT_Get_Char_Index (face,
' ');
721 || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT))
729 else if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL))
736 FT_Bitmap& bitmap = face->glyph->bitmap;
743 FT_Get_Kerning (face, previous, glyph_index,
744 FT_KERNING_DEFAULT, &delta);
748 x0 =
xoffset + face->glyph->bitmap_left;
758 for (
int r = 0;
static_cast<unsigned int> (r) < bitmap.rows; r++)
759 for (
int c = 0;
static_cast<unsigned int> (
c) < bitmap.width;
c++)
761 unsigned char pix = bitmap.buffer[r*bitmap.width+
c];
768 else if (
pixels(3, x0+
c, y0-r).value () == 0)
777 xoffset += (face->glyph->advance.x >> 6);
784 glyph_index = FT_Get_Char_Index (face,
' ');
786 || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT))
805 FT_Get_Kerning (face, previous, glyph_index,
806 FT_KERNING_DEFAULT, &delta);
814 xoffset += (face->glyph->advance.x >> 6);
827 std::list<text_renderer::string>& lst,
829 int ha,
int va,
double rot,
846 FT_UInt glyph_index, previous = 0;
849 size_t n = str.length ();
853 memset (&ps, 0,
sizeof (ps));
860 size_t r = std::mbrtowc (&wc, str.data () + curr, n, &ps);
863 && r != static_cast<size_t> (-1)
864 && r !=
static_cast<size_t> (-2))
895 previous = glyph_index;
900 ::warning (
"ft_text_renderer: failed to decode string `%s' with "
901 "locale `%s'", str.c_str (),
902 std::setlocale (LC_CTYPE, 0));
973 int s_asc = saved_font.
get_face ()->size->metrics.ascender >> 6;
1081 (*it)->accept (*
this);
1098 if (c.
numel () == 3)
1100 color(0) =
static_cast<uint8_t
> (
c(0)*255);
1101 color(1) =
static_cast<uint8_t
> (
c(1)*255);
1102 color(2) =
static_cast<uint8_t
> (
c(2)*255);
1105 ::warning (
"ft_text_renderer::set_color: invalid color");
1188 Matrix extent (1, 2, 0.0);
1194 extent(0) =
bbox(2);
1195 extent(1) =
bbox(3);
1200 extent(0) =
bbox(3);
1201 extent(1) =
bbox(2);
1222 while (rotation < 0)
1224 while (rotation > 360.0)
1227 if (rotation == 0.0)
1229 else if (rotation == 90.0)
1231 else if (rotation == 180.0)
1233 else if (rotation == 270.0)
1242 int _halign,
int valign,
double rotation,
1244 bool handle_rotation)
1251 pxls =
render (elt, box, rot_mode);
1294 if (handle_rotation)
1321 #if defined (HAVE_FT_REFERENCE_FACE)
1324 if (ft_face && FT_Reference_Face (ft_face) == 0)
1338 FT_Done_Face (face);
1342 #if defined (HAVE_FT_REFERENCE_FACE)
1345 if (ft_face && FT_Reference_Face (ft_face) == 0)
1362 if (FT_Set_Char_Size (face, 0,
size*64, 0, 0))
1363 ::warning (
"ft_text_renderer: unable to set font size to %g",
size);
1366 ::warning (
"ft_text_renderer: unable to load appropriate font");
1380 #if defined (HAVE_FREETYPE)
ft_font & operator=(const ft_font &ft)
void warning_with_id(const char *id, const char *fmt,...)
bool is_empty(void) const
static FT_Face get_font(const std::string &name, const std::string &weight, const std::string &angle, double size)
Octave interface to the compression and uncompression libraries.
For example cd octave end example noindent changes the current working directory to file
MArray< T > permute(const Array< octave_idx_type > &vec, bool inv=false) const
Matrix extract(octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
static void ft_face_destroyed(void *object)
uint8NDArray render(text_element *elt, Matrix &box, int rotation=ROTATION_0)
octave_idx_type numel(void) const
Number of elements in the array.
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE * f
std::pair< std::string, double > ft_key
Return the CPU time used by your Octave session The first output is the total time spent executing your process and is equal to the sum of second and third which are the number of CPU seconds spent executing in user mode and the number of CPU seconds spent executing in system mode
std::map< ft_key, FT_Face > ft_cache
intNDArray< octave_uint8 > uint8NDArray
octave_idx_type dim2(void) const
std::list< Matrix > line_bbox
fontstyle get_fontstyle(void) const
static ft_manager * instance
std::string get_name(void) const
uint32_t get_code(void) const
void text_to_strlist(const std::string &txt, std::list< text_renderer::string > &lst, Matrix &bbox, int halign, int valign, double rotation, const caseless_str &interp)
void set_color(const Matrix &c)
void error(const char *fmt,...)
std::list< text_element * >::iterator iterator
double get_fontsize(void) const
uint8NDArray get_pixels(void) const
std::string get_string(void) const
void set_string(const std::string &s)
FT_Face do_get_font(const std::string &name, const std::string &weight, const std::string &angle, double size)
bool is_valid(void) const
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
static void warn_glyph_render(FT_ULong c)
int get_symbol(void) const
std::list< text_renderer::string > strlist
void set_color(const uint8NDArray &c)
void set_code(const uint32_t c)
octave_idx_type dim3(void) const
base_text_renderer * make_ft_text_renderer(void)
int rotation_to_mode(double rotation) const
OCTAVE_EXPORT octave_value_list isdir nd deftypefn *std::string nm
octave_idx_type index(const T *src, octave_idx_type n, T *dest) const
std::string get_weight(void) const
ft_font(const std::string &nm, const std::string &wt, const std::string &ang, double sz, FT_Face f=0)
nd deftypefn *octave_map m
uint32_t get_symbol_code(void) const
double get_size(void) const
virtual void accept(text_processor &p)=0
void visit(text_element_string &e)
Matrix get_extent(text_element *elt, double rotation=0.0)
static void warn_missing_glyph(FT_ULong c)
std::string string_value(void) const
virtual text_element * parse(const std::string &s)=0
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)
Matrix get_boundingbox(void) const
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the c
int compute_line_xoffset(const Matrix &lb) const
void warning(const char *fmt,...)
std::string get_angle(void) const
bool fontconfig_initialized
static octave_value box(JNIEnv *jni_env, void *jobj, void *jcls_arg=0)
Convert the Java object pointed to by jobj_arg with class jcls_arg to an Octave value.
void do_font_destroyed(FT_Face face)
font & operator=(const font &ft)
FT_UInt process_character(FT_ULong code, FT_UInt previous=0)
static bool instance_ok(void)
octave::sys::file_stat fs(filename)
void set_font(const std::string &name, const std::string &weight, const std::string &angle, double size)
void set_y(const double y0)
static void cleanup_instance(void)
virtual void visit(text_element_string &e)=0
Vector representing the dimensions (size) of an Array.
static void font_destroyed(FT_Face face)
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
void update_line_bbox(void)
const std::string & get_fontname(void) const
Array< T > index(const idx_vector &i) const
Indexing without resizing.
FT_Face get_face(void) const
bool freetype_initialized