//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // See implementation agg_font_freetype.cpp // //---------------------------------------------------------------------------- #ifndef AGG_FONT_FREETYPE_INCLUDED #define AGG_FONT_FREETYPE_INCLUDED #include #include FT_FREETYPE_H #include #include "agg_scanline_storage_aa.h" #include "agg_scanline_storage_bin.h" #include "agg_scanline_u.h" #include "agg_scanline_bin.h" #include "agg_path_storage_integer.h" #include "agg_rasterizer_scanline_aa.h" #include "agg_conv_curve.h" #include "agg_font_cache_manager.h" #include "agg_font_cache_manager2.h" #include "agg_trans_affine.h" namespace agg { namespace fman { //-----------------------------------------------font_engine_freetype_base class font_engine_freetype_base { public: struct prepared_glyph { unsigned glyph_code; unsigned glyph_index; unsigned data_size; glyph_data_type data_type; rect_i bounds; double advance_x; double advance_y; }; class loaded_face { public: loaded_face( font_engine_freetype_base &engine, FT_Face face ) : m_engine( engine ) , m_ft_face( face ) , m_dpi( 0 ) , m_height( 0 ) , m_width( 0 ) , m_rendering( glyph_ren_native_gray8 ) , m_hinting( false ) , m_flip_y( true ) , m_char_map( FT_ENCODING_NONE ) { set_face_name(); } ~loaded_face() { FT_Done_Face( m_ft_face); delete[] m_face_name; } unsigned num_faces() const { return m_ft_face->num_faces; } const char *name() const { return m_face_name; } unsigned resolution() const { return m_dpi; } double height() const { return m_height; } double width() const { return m_width; } double ascent() const { return m_ft_face->ascender*height()/m_ft_face->height; } double descent() const { return m_ft_face->descender*height()/m_ft_face->height; } double ascent_b() const { return m_ft_face->bbox.yMax*height()/m_ft_face->height; } double descent_b() const { return m_ft_face->bbox.yMin*height()/m_ft_face->height; } bool hinting() const { return m_hinting; } bool flip_y() const { return m_flip_y; } const trans_affine &transform() const { return m_affine; } FT_Encoding char_map() const { return m_char_map; } void set_hinting( bool h ) { m_hinting=h; } /* void set_resolution(int dpi) { m_dpi=dpi; update_char_size(); } void set_height( double h ) { m_height=int(h*64.0); update_char_size(); } void set_width( double w ) { m_width=int(w*64.0); update_char_size(); } void set_flip_y(bool f) { m_flip_y=f; } void set_transform(const trans_affine& affine) { m_affine=affine; } int set_char_map(FT_Encoding char_map) { FT_Select_Charmap(m_ft_face, char_map); } */ void select_instance( double height, double width, bool hinting, glyph_rendering rendering ) { rendering=capable_rendering(rendering); if( m_height != height || m_width != width || m_hinting != hinting || m_rendering != rendering ) { m_height = height; m_width = width; m_hinting = hinting; m_rendering = rendering; update_char_size(); } } glyph_rendering capable_rendering( glyph_rendering rendering ) const { switch(rendering) { case glyph_ren_native_mono: case glyph_ren_native_gray8: break; case glyph_ren_outline: if(!FT_IS_SCALABLE(m_ft_face)) rendering = glyph_ren_native_gray8; break; case glyph_ren_agg_mono: if(!FT_IS_SCALABLE(m_ft_face)) rendering = glyph_ren_native_mono; break; case glyph_ren_agg_gray8: if(!FT_IS_SCALABLE(m_ft_face)) rendering = glyph_ren_native_gray8; break; }; return rendering; } void update_char_size() { if( m_dpi ) FT_Set_Char_Size( m_ft_face, int(m_width*64), int(m_height*64), m_dpi, m_dpi ); else FT_Set_Pixel_Sizes( m_ft_face, int(m_width), int(m_height) ); } bool prepare_glyph(unsigned glyph_code, prepared_glyph *prepared ) const; bool add_kerning(unsigned first, unsigned second, double* x, double* y); void write_glyph_to(prepared_glyph *prepared, int8u* data) const; private: void set_face_name(); loaded_face(const loaded_face &); loaded_face &operator=(const loaded_face &); private: font_engine_freetype_base &m_engine; FT_Face m_ft_face; char *m_face_name; int m_dpi; double m_height; double m_width; glyph_rendering m_rendering; bool m_hinting; bool m_flip_y; trans_affine m_affine; FT_Encoding m_char_map; }; //-------------------------------------------------------------------- typedef serialized_scanlines_adaptor_aa gray8_adaptor_type; typedef serialized_scanlines_adaptor_bin mono_adaptor_type; typedef scanline_storage_aa8 scanlines_aa_type; typedef scanline_storage_bin scanlines_bin_type; //-------------------------------------------------------------------- ~font_engine_freetype_base(); font_engine_freetype_base(bool flag32, void *ftMemory=0); // Load families and faces //-------------------------------------------------------------------- loaded_face *load_face(const void* buffer, std::size_t bytes); loaded_face *load_face_file(const char* file_name); loaded_face *create_loaded_face(FT_Face ft_face); // internal void unload_face(loaded_face *face); // Set Gamma //-------------------------------------------------------------------- template void gamma(const GammaF& f) { m_rasterizer.gamma(f); } private: font_engine_freetype_base(const font_engine_freetype_base&); const font_engine_freetype_base& operator = (const font_engine_freetype_base&); bool m_flag32; int m_last_error; bool m_library_initialized; FT_Library m_library; // handle to library path_storage_integer m_path16; path_storage_integer m_path32; conv_curve > m_curves16; conv_curve > m_curves32; scanline_u8 m_scanline_aa; scanline_bin m_scanline_bin; scanlines_aa_type m_scanlines_aa; scanlines_bin_type m_scanlines_bin; rasterizer_scanline_aa<> m_rasterizer; }; //------------------------------------------------font_engine_freetype_int16 // This class uses values of type int16 (10.6 format) for the vector cache. // The vector cache is compact, but when rendering glyphs of height // more that 200 there integer overflow can occur. // class font_engine_freetype_int16 : public font_engine_freetype_base { public: typedef serialized_integer_path_adaptor path_adaptor_type; typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type; typedef font_engine_freetype_base::mono_adaptor_type mono_adaptor_type; typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type; typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type; font_engine_freetype_int16(void *ftMemory = 0) : font_engine_freetype_base(false, ftMemory) {} }; //------------------------------------------------font_engine_freetype_int32 // This class uses values of type int32 (26.6 format) for the vector cache. // The vector cache is twice larger than in font_engine_freetype_int16, // but it allows you to render glyphs of very large sizes. // class font_engine_freetype_int32 : public font_engine_freetype_base { public: typedef serialized_integer_path_adaptor path_adaptor_type; typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type; typedef font_engine_freetype_base::mono_adaptor_type mono_adaptor_type; typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type; typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type; font_engine_freetype_int32(void *ftMemory = 0) : font_engine_freetype_base(true, ftMemory) {} }; } } #endif