Back to index

texmacs  1.0.7.15
unicode_font.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : unicode_font.cpp
00004 * DESCRIPTION: True Type fonts (using FreeType II)
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 "Freetype/free_type.hpp"
00014 #include "Freetype/tt_file.hpp"
00015 #include "Freetype/tt_face.hpp"
00016 #include "analyze.hpp"
00017 #include "converter.hpp"
00018 
00019 #ifdef USE_FREETYPE
00020 
00021 /******************************************************************************
00022 * True Type fonts
00023 ******************************************************************************/
00024 
00025 struct unicode_font_rep: font_rep {
00026   font_metric fnm;
00027   font_glyphs fng;
00028 
00029   unicode_font_rep (string name, string family, int size, int dpi);
00030 
00031   void get_extents (string s, metric& ex);
00032   void get_xpositions (string s, SI* xpos);
00033   void draw (renderer ren, string s, SI x, SI y);
00034   glyph get_glyph (string s);
00035   SI get_left_correction  (string s);
00036   SI get_right_correction  (string s);
00037 };
00038 
00039 /******************************************************************************
00040 * Initialization of main font parameters
00041 ******************************************************************************/
00042 
00043 #define conv(x) ((SI) (((double) (x))*unit))
00044 
00045 unicode_font_rep::unicode_font_rep (string name,
00046   string family, int size2, int dpi):
00047   font_rep (name)
00048 {
00049   type= FONT_TYPE_UNICODE;
00050   size= size2;
00051   fnm = tt_font_metric (family, size, dpi);
00052   fng = tt_font_glyphs (family, size, dpi);
00053   if (fnm->bad_font_metric || fng->bad_font_glyphs) {
00054     fnm= std_font_metric (res_name, NULL, 0, -1);
00055     fng= std_font_glyphs (res_name, NULL, 0, -1);
00056     if (DEBUG_AUTO)
00057       cout << "TeXmacs] Font " << family << " " << size
00058           << "pt at " << dpi << " dpi could not be loaded\n";
00059     
00060   }
00061 
00062   // get main font parameters
00063   metric ex;
00064   get_extents ("f", ex);
00065   y1= ex->y1;
00066   y2= ex->y2;
00067   get_extents ("p", ex);
00068   y1= min (y1, ex->y1);
00069   y2= max (y2, ex->y2);
00070   get_extents ("d", ex);
00071   y1= min (y1, ex->y1);
00072   y2= max (y2, ex->y2);
00073   display_size = y2-y1;
00074   design_size  = size << 8;
00075 
00076   // get character dimensions
00077   get_extents ("x", ex);
00078   yx           = ex->y2;
00079   get_extents ("M", ex);
00080   wquad        = ex->x2;
00081 
00082   // compute other heights
00083   yfrac        = yx >> 1;
00084   ysub_lo_base = -yx/3;
00085   ysub_hi_lim  = (5*yx)/6;
00086   ysup_lo_lim  = yx/2;
00087   ysup_lo_base = (5*yx)/6;
00088   ysup_hi_lim  = yx;
00089   yshift       = yx/6;
00090 
00091   // compute other widths
00092   wpt          = (dpi*PIXEL)/72;
00093   wfn          = (wpt*design_size) >> 8;
00094   wline        = wfn/20;
00095 
00096   // get fraction bar parameters
00097   get_extents ("-", ex);
00098   yfrac= (ex->y3 + ex->y4) >> 1;
00099 
00100   // get space length
00101   get_extents (" ", ex);
00102   spc  = space ((3*(ex->x2-ex->x1))>>2, ex->x2-ex->x1, (ex->x2-ex->x1)<<1);
00103   extra= spc;
00104   sep  = wfn/10;
00105 
00106   // get_italic space
00107   get_extents ("f", ex);
00108   SI italic_spc= (ex->x4-ex->x3)-(ex->x2-ex->x1);
00109   slope= ((double) italic_spc) / ((double) display_size);
00110   if (slope<0.15) slope= 0.0;
00111 }
00112 
00113 /******************************************************************************
00114 * Routines for font
00115 ******************************************************************************/
00116 
00117 static unsigned int
00118 read_unicode_char (string s, int& i) {
00119   if (s[i] == '<') {
00120     i++;
00121     int start= i;
00122     while (s[i] != '>') i++;
00123     if (s[start] == '#') {
00124       start++;
00125       return (unsigned int) from_hexadecimal (s (start, i++));
00126     }
00127     else {
00128       string ss= s (start-1, ++i);
00129       string uu= cork_to_utf8 (ss);
00130       if (uu == ss) {
00131        cout << "TeXmacs] warning: invalid symbol " << ss
00132             << " in unicode string\n";
00133        return '?';
00134       }
00135       int j= 0;
00136       return decode_from_utf8 (uu, j);
00137     }
00138   }
00139   else {
00140     unsigned int c= (unsigned int) s[i++];
00141     if (c >= 32 && c <= 127) return c;
00142     string ss= s (i-1, i);
00143     string uu= cork_to_utf8 (ss);
00144     int j= 0;
00145     return decode_from_utf8 (uu, j);
00146   }
00147 }
00148 
00149 void
00150 unicode_font_rep::get_extents (string s, metric& ex) {
00151   if (N(s)==0) {
00152     ex->x1= ex->x3= ex->x2= ex->x4=0;
00153     ex->y3= ex->y1= 0; ex->y4= ex->y2= yx;
00154   }
00155   else {
00156     int i= 0, n= N(s);
00157     unsigned int uc= read_unicode_char (s, i);
00158     metric_struct* first= fnm->get (uc);
00159     ex->x1= first->x1; ex->y1= first->y1;
00160     ex->x2= first->x2; ex->y2= first->y2;
00161     ex->x3= first->x3; ex->y3= first->y3;
00162     ex->x4= first->x4; ex->y4= first->y4;
00163     SI x= first->x2;
00164 
00165     while (i<n) {
00166       uc= read_unicode_char (s, i);
00167       metric_struct* next= fnm->get (uc);
00168       ex->x1= min (ex->x1, x+ next->x1); ex->y1= min (ex->y1, next->y1);
00169       ex->x2= max (ex->x2, x+ next->x2); ex->y2= max (ex->y2, next->y2);
00170       ex->x3= min (ex->x3, x+ next->x3); ex->y3= min (ex->y3, next->y3);
00171       ex->x4= max (ex->x4, x+ next->x4); ex->y4= max (ex->y4, next->y4);
00172       x += next->x2;
00173     }
00174   }
00175 }
00176 
00177 void
00178 unicode_font_rep::get_xpositions (string s, SI* xpos) {
00179   int i= 0, n= N(s);
00180   if (n == 0) return;
00181   
00182   register SI x= 0;
00183   while (i<n) {
00184     int start= i;
00185     metric_struct* next= fnm->get (read_unicode_char (s, i));
00186     for (int j= start; j<i; j++) xpos[j]= x;
00187     x += next->x2;
00188   }
00189   xpos[n]= x;
00190 }
00191 
00192 void
00193 unicode_font_rep::draw (renderer ren, string s, SI x, SI y) {
00194   int i= 0, n= N(s);
00195   while (i<n) {
00196     unsigned int uc= read_unicode_char (s, i);
00197     ren->draw (uc, fng, x, y);
00198     metric_struct* ex= fnm->get (uc);
00199     x += ex->x2;
00200   }
00201 }
00202 
00203 glyph
00204 unicode_font_rep::get_glyph (string s) {
00205   int i= 0, n= N(s);
00206   unsigned int uc= read_unicode_char (s, i);
00207   if (i != n) return font_rep::get_glyph (s);
00208   glyph gl= fng->get (uc);
00209   if (is_nil (gl)) return font_rep::get_glyph (s);
00210   return gl;
00211 }
00212 
00213 SI
00214 unicode_font_rep::get_left_correction  (string s) {
00215   metric ex;
00216   get_extents (s, ex);
00217   if (ex->x3 < ex->x1) return ex->x1 - ex->x3;
00218   return 0;
00219 }
00220 
00221 SI
00222 unicode_font_rep::get_right_correction (string s) {
00223   metric ex;
00224   get_extents (s, ex);
00225   if (ex->x4 > ex->x2) return ex->x4 - ex->x2;
00226   return 0;
00227 }
00228 
00229 /******************************************************************************
00230 * Interface
00231 ******************************************************************************/
00232 
00233 font
00234 unicode_font (string family, int size, int dpi) {
00235   string name= "unicode:" * family * as_string (size) * "@" * as_string(dpi);
00236   return make (font, name,
00237     tm_new<unicode_font_rep> (name, family, size, dpi));
00238 }
00239 
00240 #else
00241 
00242 font
00243 unicode_font (string family, int size, int dpi) {
00244   string name= "unicode:" * family * as_string (size) * "@" * as_string(dpi);
00245   cerr << "\n\nFont name= " << name << "\n";
00246   FAILED ("true type support was disabled");
00247   return font ();
00248 }
00249 
00250 #endif