Back to index

texmacs  1.0.7.15
tt_face.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tt_face.cpp
00004 * DESCRIPTION: resources for true type faces, gliefs and metrics
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "font.hpp"
00013 #include "tt_face.hpp"
00014 #include "tt_file.hpp"
00015 #include "timer.hpp"
00016 
00017 #ifdef USE_FREETYPE
00018 
00019 RESOURCE_CODE(tt_face);
00020 
00021 inline int tt_round (int l) { return ((l+0x400020) >> 6) - 0x10000; }
00022 inline SI tt_si (int l) { return l<<2; }
00023 
00024 /******************************************************************************
00025 * Freetype faces
00026 ******************************************************************************/
00027 
00028 tt_face_rep::tt_face_rep (string name): rep<tt_face> (name) {
00029   bad_face= true;
00030   if (ft_initialize ()) return;
00031   if (DEBUG_VERBOSE)
00032     cout << "TeXmacs] Loading True Type font " << name << "\n";
00033   url u= tt_font_find (name);
00034   if (is_none (u)) return;
00035   char* _name= as_charp (concretize (u));
00036   if (ft_new_face (ft_library, _name, 0, &ft_face)) { tm_delete_array (_name); return; }
00037   ft_select_charmap (ft_face, ft_encoding_adobe_custom);
00038   tm_delete_array (_name);
00039   bad_face= false;
00040 }
00041 
00042 tt_face
00043 load_tt_face (string name) {
00044   bench_start ("load tt face");
00045   tt_face face= make (tt_face, name, tm_new<tt_face_rep> (name));
00046   bench_cumul ("load tt face");
00047   return face;
00048 }
00049 
00050 /******************************************************************************
00051 * Font metrics
00052 ******************************************************************************/
00053 
00054 static metric error_metric;
00055 
00056 tt_font_metric_rep::tt_font_metric_rep (
00057   string name, string family, int size2, int dpi2):
00058   font_metric_rep (name), size (size2), dpi (dpi2), fnm (NULL)
00059 {
00060   face= load_tt_face (family);
00061   bad_font_metric= face->bad_face ||
00062     ft_set_char_size (face->ft_face, 0, size<<6, dpi, dpi);
00063   if (bad_font_metric) return;
00064 
00065   error_metric->x1= error_metric->y1= 0;
00066   error_metric->x2= error_metric->y2= 0;
00067   error_metric->x3= error_metric->y3= 0;
00068   error_metric->x4= error_metric->y4= 0;
00069 }
00070 
00071 metric&
00072 tt_font_metric_rep::get (int i) {
00073   if (!fnm->contains(i)) {
00074     ft_set_char_size (face->ft_face, 0, size<<6, dpi, dpi);
00075     FT_UInt glyph_index= ft_get_char_index (face->ft_face, i);
00076     if (ft_load_glyph (face->ft_face, glyph_index, FT_LOAD_DEFAULT))
00077       return error_metric;
00078     FT_GlyphSlot slot= face->ft_face->glyph;
00079     if (ft_render_glyph (slot, ft_render_mode_mono)) return error_metric;
00080     metric_struct* M= tm_new<metric_struct> ();
00081     fnm(i)= (pointer) M;
00082     int w= slot->bitmap.width;
00083     int h= slot->bitmap.rows;
00084     SI ww= w * PIXEL;
00085     SI hh= h * PIXEL;
00086     SI dx= tt_si (slot->metrics.horiBearingX);
00087     SI dy= tt_si (slot->metrics.horiBearingY);
00088     SI ll= tt_si (slot->metrics.horiAdvance);
00089     M->x1= 0;
00090     M->y1= dy - hh;
00091     M->x2= ll;
00092     M->y2= dy;
00093     M->x3= dx;
00094     M->y3= dy - hh;
00095     M->x4= dx + ww;
00096     M->y4= dy;
00097   }
00098   return *((metric*) ((void*) fnm [i]));
00099 }
00100 
00101 font_metric
00102 tt_font_metric (string family, int size, int dpi) {
00103   string name= family * as_string (size) * "@" * as_string (dpi);
00104   return make (font_metric, name,
00105               tm_new<tt_font_metric_rep> (name, family, size, dpi));
00106 }
00107 
00108 /******************************************************************************
00109 * Font glyphs
00110 ******************************************************************************/
00111 
00112 static glyph error_glyph;
00113 
00114 tt_font_glyphs_rep::tt_font_glyphs_rep (
00115   string name, string family, int size2, int dpi2):
00116   font_glyphs_rep (name), size (size2), dpi (dpi2), fng (glyph ())
00117 {
00118   face= load_tt_face (family);
00119   bad_font_glyphs= face->bad_face ||
00120     ft_set_char_size (face->ft_face, 0, size<<6, dpi, dpi);
00121   if (bad_font_glyphs) return;
00122 }
00123 
00124 glyph&
00125 tt_font_glyphs_rep::get (int i) {
00126   if (!fng->contains(i)) {
00127     ft_set_char_size (face->ft_face, 0, size<<6, dpi, dpi);
00128     FT_UInt glyph_index= ft_get_char_index (face->ft_face, i);
00129     if (ft_load_glyph (face->ft_face, glyph_index, FT_LOAD_DEFAULT))
00130       return error_glyph;
00131     FT_GlyphSlot slot= face->ft_face->glyph;
00132     if (ft_render_glyph (slot, ft_render_mode_mono)) return error_glyph;
00133 
00134     int w= slot->bitmap.width;
00135     int h= slot->bitmap.rows;
00136     int ox= tt_round (slot->metrics.horiBearingX);
00137     int oy= tt_round (slot->metrics.horiBearingY);
00138     int pitch= slot->bitmap.pitch;
00139     unsigned char *buf= slot->bitmap.buffer;
00140     if (pitch<0) buf -= pitch*h;
00141     int x, y;
00142     glyph G (w, h, -ox, oy);
00143     for (y=0; y<h; y++) {
00144       for (x=0; x<w; x++) {
00145        unsigned char c= buf[x>>3];
00146        G->set_1 (x, y, (c >> (7-(x&7))) & 1);
00147       }
00148       buf += pitch;
00149     }
00150     //cout << "Glyph " << i << " of " << res_name << "\n";
00151     //cout << G << "\n";
00152     if (G->width * G->height == 0) G= error_glyph;
00153     fng(i)= G;
00154   }
00155   return fng(i);
00156 }
00157 
00158 font_glyphs
00159 tt_font_glyphs (string family, int size, int dpi) {
00160   string name=
00161     family * ":" * as_string (size) * "." * as_string (dpi) * "tt";
00162   return make (font_glyphs, name,
00163               tm_new<tt_font_glyphs_rep> (name, family, size, dpi));
00164 }
00165 
00166 #endif // USE_FREETYPE