Back to index

texmacs  1.0.7.15
unicode_math_font.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : unicode_math_font.cpp
00004 * DESCRIPTION: True Type math fonts (using FreeType II)
00005 * COPYRIGHT  : (C) 2010  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 "converter.hpp"
00014 
00015 #ifdef USE_FREETYPE
00016 
00017 /******************************************************************************
00018 * True Type fonts
00019 ******************************************************************************/
00020 
00021 struct unicode_math_font_rep: font_rep {
00022   font upright;
00023   font italic;
00024   font bold_upright;
00025   font bold_italic;
00026   font fall_back;
00027   hashmap<string,int> mapper;
00028   hashmap<string,string> rewriter;
00029 
00030   unicode_math_font_rep (string name,
00031                       font upright, font italic,
00032                       font bold_upright, font bold_italic,
00033                       font fall_back);
00034   int search_font_sub (string s);
00035   font search_font (string& s);
00036 
00037   void get_extents (string s, metric& ex);
00038   void get_xpositions (string s, SI* xpos);
00039   void draw (renderer ren, string s, SI x, SI y);
00040   glyph get_glyph (string s);
00041 
00042   double get_left_slope  (string s);
00043   double get_right_slope (string s);
00044   SI     get_left_correction  (string s);
00045   SI     get_right_correction (string s);
00046 };
00047 
00048 /******************************************************************************
00049 * Initialization of main font parameters
00050 ******************************************************************************/
00051 
00052 unicode_math_font_rep::unicode_math_font_rep
00053   (string name, font up, font it, font bup, font bit, font fb):
00054     font_rep (name, it),
00055     upright (up), italic (it),
00056     bold_upright (bup), bold_italic (bit), fall_back (fb),
00057     mapper (0), rewriter ("")
00058 {
00059   this->copy_math_pars (it);
00060 }
00061 
00062 /******************************************************************************
00063 * Find the font and the corresponding character
00064 ******************************************************************************/
00065 
00066 static bool
00067 unicode_provides (string s) {
00068   return cork_to_utf8 (s) != s;
00069 }
00070 
00071 static unsigned int
00072 cork_to_unicode (string s) {
00073   int i= 0;
00074   return decode_from_utf8 (cork_to_utf8 (s), i);
00075 }
00076 
00077 //static string
00078 //unicode_to_hexcode (unsigned int i) {
00079 //  return "<#" * as_hexadecimal (i) * ">";
00080 //}
00081 
00082 int
00083 unicode_math_font_rep::search_font_sub (string s) {
00084   //cout << "Searching " << s << "\n";
00085   if (N(s) == 0) return 1;
00086   else if (s == "*" || starts (s, "<big-.") ||
00087           s == "<noplus>" || s == "<nocomma>" || s == "<nospace>" ||
00088           s == "<nobracket>" || s == "<nosymbol>") {
00089     rewriter(s)= "";
00090     return 2;
00091   }
00092   else if (s == "-") { rewriter (s)= "<minus>"; return 2; }
00093   else if (s == "|") { rewriter (s)= "<mid>"; return 2; }
00094   else if (s == "'") { rewriter (s)= "<#2B9>"; return 2; }
00095   else if (s == "`") { rewriter (s)= "<backprime>"; return 2; }
00096   else if (N(s) == 1) {
00097     if (s[0] >= 'a' && s[0] <= 'z') return 3;
00098     if (s[0] >= 'A' && s[0] <= 'Z') return 3;
00099     return 1;
00100   }
00101   else if (s[0] == '<' && s[N(s)-1] == '>') {
00102     if (starts (s, "<cal-")) return 6; // Temporary fix
00103     if (starts (s, "<b-")) {
00104       string ss= s (3, N(s)-1);
00105       if (N(ss) != 1) ss= "<" * ss * ">";
00106       unsigned int c= search_font_sub (ss);
00107       rewriter (s)= ss;
00108       if (c == 1 || c == 2) return 4;
00109       if (c == 3) return 5;
00110       rewriter (s)= s;
00111       return 6;
00112     }
00113     if (starts (s, "<big-") && (ends (s, "-1>") || ends (s, "-2>"))) {
00114       string ss= s (0, N(s)-3) * ">";
00115       //cout << "Search " << ss << "\n";
00116       if (unicode_provides (ss)) {
00117        unsigned int c= search_font_sub (ss);
00118        rewriter (s)= ss;
00119        if (c == 1) return 2;
00120        return c;
00121       }
00122       ss= "<big" * s (5, N(s)-3) * ">";
00123       //cout << "Search " << ss << "\n";
00124       if (unicode_provides (ss)) {
00125        unsigned int c= search_font_sub (ss);
00126        rewriter (s)= ss;
00127        if (c == 1) return 2;
00128        return c;
00129       }
00130       ss= "<" * s (5, N(s)-3) * ">";
00131       if (ends (ss, "lim>")) ss= ss (0, N(ss)-4) * ">";
00132       //cout << "Search " << ss << "\n";
00133       if (unicode_provides (ss)) {
00134        unsigned int c= search_font_sub (ss);
00135        rewriter (s)= ss;
00136        if (c == 1) return 2;
00137        return c;
00138       }
00139     }
00140     if (!unicode_provides (s)) return 6;
00141     unsigned int c= cork_to_unicode (s);
00142     if (c >= 0x3ac && c <= 0x3d6 && !starts (s, "<math")) return 3;
00143     return 1;
00144   }
00145   else {
00146     return 1;
00147   }
00148 }
00149 
00150 font
00151 unicode_math_font_rep::search_font (string& s) {
00152   if (N(s) >= 2 && s[0] != '<') return upright;
00153   else switch (mapper[s]) {
00154     case 0:
00155       mapper(s)= search_font_sub (s);
00156       return search_font (s);
00157     case 1:
00158       return upright;
00159     case 2:
00160       s= rewriter[s];
00161       return upright;
00162     case 3:
00163       return italic;
00164     case 4:
00165       s= rewriter[s];
00166       return bold_upright;
00167     case 5:
00168       s= rewriter[s];
00169       return bold_italic;
00170     case 6:
00171       return fall_back;
00172     default:
00173       return upright;
00174     }
00175 }
00176 
00177 /******************************************************************************
00178 * Getting extents and drawing strings
00179 ******************************************************************************/
00180 
00181 void
00182 unicode_math_font_rep::get_extents (string s, metric& ex) {
00183   font fn= search_font (s);
00184   fn->get_extents (s, ex);
00185 }
00186 
00187 void
00188 unicode_math_font_rep::get_xpositions (string s, SI* xpos) {
00189   if (s == "") return;
00190   string r= s;
00191   font fn= search_font (r);
00192   if (r == s) fn->get_xpositions (s, xpos);
00193   else if (N(r) != 1) font_rep::get_xpositions (s, xpos);
00194   else {
00195     int i, n=N(s);
00196     for (i=1; i<n; i++) xpos[i]= 0;
00197     fn->get_xpositions (r, xpos+n-1);
00198   }
00199 }
00200 
00201 void
00202 unicode_math_font_rep::draw (renderer ren, string s, SI x, SI y) {
00203   font fn= search_font (s);
00204   fn->draw (ren, s, x, y);
00205 }
00206 
00207 glyph
00208 unicode_math_font_rep::get_glyph (string s) {
00209   font fn= search_font (s);
00210   return fn->get_glyph (s);
00211 }
00212 
00213 /******************************************************************************
00214 * Metric properties
00215 ******************************************************************************/
00216 
00217 double
00218 unicode_math_font_rep::get_left_slope  (string s) {
00219   font fn= search_font (s);
00220   return fn->get_left_slope (s);
00221 }
00222 
00223 double
00224 unicode_math_font_rep::get_right_slope (string s) {
00225   font fn= search_font (s);
00226   return fn->get_right_slope (s);
00227 }
00228 
00229 SI
00230 unicode_math_font_rep::get_left_correction  (string s) {
00231   font fn= search_font (s);
00232   return fn->get_left_correction (s);
00233 }
00234 
00235 SI
00236 unicode_math_font_rep::get_right_correction (string s) {
00237   font fn= search_font (s);
00238   return fn->get_right_correction (s);
00239 }
00240 
00241 /******************************************************************************
00242 * Interface
00243 ******************************************************************************/
00244 
00245 font
00246 unicode_math_font (font up, font it, font bup, font bit, font fb) {
00247   string name=
00248     "unimath[" *
00249     up->res_name * "," *
00250     it->res_name * "," *
00251     bup->res_name * "," *
00252     bit->res_name * "," *
00253     fb->res_name * "]";
00254   return make (font, name,
00255     tm_new<unicode_math_font_rep> (name, up, it, bup, bit, fb));
00256 }
00257 
00258 #else
00259 
00260 font
00261 unicode_math_font (font up, font it, font bup, font bit, font fb) {
00262   string name=
00263     "unimath[" *
00264     up->res_name * "," *
00265     it->res_name * "," *
00266     bup->res_name * "," *
00267     bit->res_name * "," *
00268     fb->res_name * "]";
00269   cerr << "\n\nFont name= " << name << "\n";
00270   FAILED ("true type support was disabled");
00271   return font ();
00272 }
00273 
00274 #endif