Hello, I would like to present an updated patch for native font rendering in the Qt port of TeXmacs.
The benefits include improved anti-aliasing and overall improved visual appearance as well as potentially better performance. Unfortunately, to get cross-platform support fonts have to converted into the .otf format. I have converted the base Computer Modern fonts, as well as some others covered under the GPL into the right format (and the right encoding). See a PDF font sampler http://dl.dropbox.com/u/384906/fonts-patch/sample3.pdf In order to use the fonts, you must get the font files: http://dl.dropbox.com/u/384906/fonts-patch/TeXmacs-fonts.tar.gz Do this to install them: cd ~ mv .TeXmacs/ TeXmacs-backup wget http://dl.dropbox.com/u/384906/fonts-patch/TeXmacs-fonts.tar.gz tar xf TeXmacs-fonts.tar.gz Now start TeXmacs and change the font in the new FreeFonts menu. The source code for the sampler: http://dl.dropbox.com/u/384906/fonts-patch/sample3.tm The patch is available here: http://dl.dropbox.com/u/384906/fonts-patch/native-fonts.patch Aleksandr Dobkin Index: src/Graphics/Bitmap_fonts/bitmap_font.cpp =================================================================== --- src/Graphics/Bitmap_fonts/bitmap_font.cpp (revision 2894) +++ src/Graphics/Bitmap_fonts/bitmap_font.cpp (working copy) @@ -65,7 +65,11 @@ ******************************************************************************/ font_glyphs_rep::font_glyphs_rep (string name): - rep<font_glyphs> (name), bad_font_glyphs (false) {} + rep<font_glyphs> (name), bad_font_glyphs (false) + #ifdef QTTEXMACS + ,is_qt_font(false) + #endif + {} font_glyphs_rep::~font_glyphs_rep () { FAILED ("not yet implemented"); } Index: src/Graphics/Bitmap_fonts/bitmap_font.hpp =================================================================== --- src/Graphics/Bitmap_fonts/bitmap_font.hpp (revision 2894) +++ src/Graphics/Bitmap_fonts/bitmap_font.hpp (working copy) @@ -13,6 +13,10 @@ #define BITMAP_FONT_H #include "resource.hpp" +#ifdef QTTEXMACS +#include <QFont> +#endif + RESOURCE(font_metric); RESOURCE(font_glyphs); @@ -101,6 +105,9 @@ font_glyphs_rep (string name); virtual ~font_glyphs_rep (); virtual glyph& get (int char_code) = 0; +#ifdef QTTEXMACS + bool is_qt_font; +#endif }; font_metric std_font_metric (string s, metric* fnm, int bc, int ec); Index: src/Graphics/Renderer/printer.cpp =================================================================== --- src/Graphics/Renderer/printer.cpp (revision 2894) +++ src/Graphics/Renderer/printer.cpp (working copy) @@ -458,16 +458,29 @@ string name = tex_fonts [fn_name], ttf; int pos = search_forwards (".", fn_name); string root = (pos==-1? fn_name: fn_name (0, pos)); -#ifndef OS_WIN32 // we need pfbtopfa + if ((pos!=-1) && ends (fn_name, "tt")) { int pos2= search_backwards (":", fn_name); root= fn_name (0, pos2); - url u= tt_font_find (root); - if (suffix (u) == "pfb") { - ttf = pfb_to_pfa (u); + + url u= tt_locate(root * ".pfa"); + if( !is_none(u) ) { + load_string(u, ttf, false); } + else if( !is_none( u = tt_locate(root * ".t42") ) ) { + load_string(u, ttf, false); + } + else { + //cout<<"falling back with font "<<root<<"\n"; + #ifndef OS_WIN32 // we need pfbtopfa // really, why? doesn't look like that to me + u=tt_font_find (root); + if (suffix (u) == "pfb") { + ttf = pfb_to_pfa (u); + } + #endif + } + } -#endif if (ttf != "") { string ttf_name= find_ps_font_name (root, ttf); Index: src/Plugins/Freetype/tt_face.cpp =================================================================== --- src/Plugins/Freetype/tt_face.cpp (revision 2894) +++ src/Plugins/Freetype/tt_face.cpp (working copy) @@ -16,6 +16,10 @@ #ifdef USE_FREETYPE +#ifdef QTTEXMACS +#include <QFontDatabase> +#endif + RESOURCE_CODE(tt_face); inline int tt_round (int l) { return ((l+0x400020) >> 6) - 0x10000; } @@ -118,9 +122,75 @@ face= load_tt_face (family); bad_font_glyphs= face->bad_face || ft_set_char_size (face->ft_face, 0, size<<6, dpi, dpi); - if (bad_font_glyphs) return; + +#ifdef QTTEXMACS +//cout << "tt_font_glyphs constructor: "; +//cout << "name: "<< name <<"; family: "<<family<<"; size:"<<size<<"; dpi: "<<dpi; + char *family_str = as_charp(family); + QString qt_family_str = QString("TeXmacs ")+QString(family_str); + qt_font = QFont(qt_family_str); + + if( qt_font.exactMatch() ) { + is_qt_font = true; + //cout << "Qt font "<<family<<" already loaded\n"; + } + else { + //try to load the font file + url url= tt_font_find (family); + char *filename = as_charp (concretize (url)); + int fonthandle = QFontDatabase::addApplicationFont(filename); + tm_delete_array (filename); + + qt_font = QFont(qt_family_str); + if( qt_font.exactMatch() ) { + is_qt_font = true; + // cout << "Qt font "<<family<<" loaded from "<<url<<"\n"; + } + else { + cout << "Qt font "<<family<<" not found\n"; + QFontDatabase::removeApplicationFont(fonthandle); + } + } + + tm_delete_array(family_str); + + if(is_qt_font & !bad_font_glyphs) { + qt_glyph_metrics = (qt_glyph_metrics_t*) malloc(sizeof(qt_glyph_metrics_t)*256); + set_sfactor(5); + + for(int i=0; i < 256; i++) { + if(!FT_Load_Glyph(face->ft_face, i, FT_LOAD_DEFAULT)) { + FT_GlyphSlot slot = face->ft_face->glyph; + + qt_glyph_metrics[i].width = tt_round(slot->metrics.width); + qt_glyph_metrics[i].height = tt_round(slot->metrics.height); + qt_glyph_metrics[i].xoff = -tt_round(slot->metrics.horiBearingX); + qt_glyph_metrics[i].yoff = tt_round(slot->metrics.horiBearingY); + + //printf("for char %c, width=%i, height=%i, xoff=%i, yoff=%i\n", +// i, qt_glyph_metrics[i].width, qt_glyph_metrics[i].height, +// qt_glyph_metrics[i].xoff, qt_glyph_metrics[i].yoff); + } + //else printf("could not load glyph %c\n", i); + + } + } +#endif } +#ifdef QTTEXMACS +void +tt_font_glyphs_rep::set_sfactor(int new_sfactor) { + if(sfactor != new_sfactor) { + sfactor = new_sfactor; + + qt_font.setPixelSize( (size * dpi) / (72 * sfactor) ); + } + +} +#endif + + glyph& tt_font_glyphs_rep::get (int i) { if (!fng->contains(i)) { Index: src/Plugins/Freetype/tt_file.cpp =================================================================== --- src/Plugins/Freetype/tt_file.cpp (revision 2894) +++ src/Plugins/Freetype/tt_file.cpp (working copy) @@ -26,9 +26,10 @@ return expand (dirs); } -static url +url tt_locate (string name) { - if (ends (name, ".pfb")) { + if (ends (name, ".pfb") || ends(name, ".otf") || ends(name, ".ttf") || + ends(name, ".pfa") || ends(name, ".t42")) { /* if (starts (name, "rpag")) name= "uag" * name (4, N (name) - 4) * "8a.pfb"; if (starts (name, "rpbk")) name= "ubk" * name (4, N (name) - 4) * "8a.pfb"; @@ -76,10 +77,13 @@ url tt_font_find (string name) { - url u= tt_locate (name * ".pfb"); - //if (!is_none (u)) cout << name << " -> " << u << "\n"; + url u = tt_locate(name * ".otf"); if (!is_none (u)) return u; + u= tt_locate (name * ".ttf"); + if (!is_none (u)) return u; + + u= tt_locate (name * ".pfb"); //if (!is_none (u)) cout << name << " -> " << u << "\n"; //else cout << name << " -> ???\n"; return u; @@ -96,6 +100,9 @@ string tt_find_name_sub (string name, int size) { + if(tt_font_exists(name)) + return name; + if (size == 0) { if (tt_font_exists (name)) return name; else return ""; Index: src/Plugins/Freetype/tt_face.hpp =================================================================== --- src/Plugins/Freetype/tt_face.hpp (revision 2894) +++ src/Plugins/Freetype/tt_face.hpp (working copy) @@ -15,6 +15,10 @@ #include "Freetype/free_type.hpp" #include "hashmap.hpp" +#ifdef QTTEXMACS +#include <QFont> +#endif + #ifdef USE_FREETYPE RESOURCE(tt_face); @@ -36,6 +40,12 @@ metric& get (int char_code); }; +#ifdef QTTEXMACS +struct qt_glyph_metrics_t { + int width, height, xoff, yoff; +}; +#endif + struct tt_font_glyphs_rep: font_glyphs_rep { bool bad_glyphs; tt_face face; @@ -45,6 +55,13 @@ //bool* done; tt_font_glyphs_rep (string name, string family, int size, int dpi); glyph& get (int char_code); + +#ifdef QTTEXMACS + qt_glyph_metrics_t *qt_glyph_metrics; + void set_sfactor(int new_sfactor); + QFont qt_font; + int sfactor; + #endif }; tt_face load_tt_face (string name); Index: src/Plugins/Freetype/tt_file.hpp =================================================================== --- src/Plugins/Freetype/tt_file.hpp (revision 2894) +++ src/Plugins/Freetype/tt_file.hpp (working copy) @@ -16,5 +16,6 @@ bool tt_font_exists (string name); url tt_font_find (string name); string tt_find_name (string name, int size); +url tt_locate(string name); #endif // TT_FILE_H Index: src/Plugins/Qt/qt_renderer.cpp =================================================================== --- src/Plugins/Qt/qt_renderer.cpp (revision 2894) +++ src/Plugins/Qt/qt_renderer.cpp (working copy) @@ -15,6 +15,8 @@ #include "qt_utilities.hpp" #include "file.hpp" +#include "Freetype/tt_face.hpp" + #ifdef MACOSX_EXTENSIONS #include "MacOS/mac_images.h" #endif @@ -419,6 +421,19 @@ void qt_renderer_rep::draw (int c, font_glyphs fng, SI x, SI y) { + if( fng->is_qt_font ) { + tt_font_glyphs_rep *ttfng = static_cast<tt_font_glyphs_rep*>(fng.rep); + ttfng->set_sfactor(sfactor); + + painter->setFont(ttfng->qt_font); + + decode(x, y); + QString str(c); + + painter->drawText(x, y, str); + return; + } + // get the pixmap basic_character xc (c, fng, sfactor, cur_fg, 0); qt_image mi = character_image [xc]; Index: src/Plugins/Metafont/load_tex.cpp =================================================================== --- src/Plugins/Metafont/load_tex.cpp (revision 2894) +++ src/Plugins/Metafont/load_tex.cpp (working copy) @@ -37,7 +37,8 @@ try_tfm (string family, int size, int osize, tex_font_metric& tfm, bool make) { // cout << "Try tfm " << family << size << " (" << osize << ")\n"; make= make && get_setting ("MAKETFM") != "false"; - string name_tfm = family * as_string (osize) * ".tfm"; + string name_tfm = (size != 0 ? family * as_string (osize) * ".tfm" : + family * ".tfm"); if (tex_font_metric::instances -> contains (name_tfm)) { tfm= tex_font_metric (name_tfm); return true; @@ -80,6 +81,8 @@ bool make) { //cout << "Load TeX tfm " << family << size << " (dsize= " << dsize << ")\n"; + if (try_tfm (family, 0, size, tfm, make)) + return true; if (try_tfm (family, size, size, tfm, make)) return true; if (size > 333) Index: src/Plugins/Metafont/tex_files.cpp =================================================================== --- src/Plugins/Metafont/tex_files.cpp (revision 2894) +++ src/Plugins/Metafont/tex_files.cpp (working copy) @@ -93,7 +93,10 @@ } if (ends (s, "tfm")) u= resolve_tfm (name); if (ends (s, "pk" )) u= resolve_pk (name); - if (ends (s, "pfb")) u= resolve_pfb (name); + else if (ends (s, "otf") || ends (s, "ttf") || ends (s, "pfb") || + ends (s, "pfa") || ends (s, "t42")) + u= resolve_pfb (name); + bench_cumul ("resolve tex"); if (!is_none (u)) cache_set ("font_cache.scm", s, as_string (u)); Index: src/Plugins/Metafont/tex_font.cpp =================================================================== --- src/Plugins/Metafont/tex_font.cpp (revision 2894) +++ src/Plugins/Metafont/tex_font.cpp (working copy) @@ -15,6 +15,8 @@ #include "iterator.hpp" #include "gui.hpp" +#include "Freetype/tt_face.hpp" + #define TEX_ANY 0 #define TEX_EC 1 #define TEX_LA 2 @@ -511,15 +513,44 @@ for (i=0; i<m; i++) { int c= buf[i]; - glyph gl= pk->get (c); - if (is_nil (gl)) continue; + int height, width, xoff, yoff; + + #ifdef QTTEXMACS + if(pk->is_qt_font) { + tt_font_glyphs_rep *ttfng = static_cast<tt_font_glyphs_rep*>(pk.rep); + qt_glyph_metrics_t *qt_glyph_metrics = ttfng->qt_glyph_metrics; + + height = qt_glyph_metrics[c].height; + width = qt_glyph_metrics[c].width; + xoff = qt_glyph_metrics[c].xoff; + yoff = qt_glyph_metrics[c].yoff; + + //printf("for char %c, width=%i, height=%i, xoff=%i, yoff=%i\n", + // c, qt_glyph_metrics[c].width, qt_glyph_metrics[c].height, + // qt_glyph_metrics[c].xoff, qt_glyph_metrics[c].yoff); + } + else + #endif + { + glyph gl= pk->get (c); + if (is_nil (gl)) continue; + height = gl->height; + width = gl->width; + xoff = gl->xoff; + yoff = gl->yoff; + + //printf("gl char %c, width=%i, height=%i, xoff=%i, yoff=%i\n", + // c, gl->width, gl->height, gl->xoff, gl->yoff); + } + y1= min (y1, -conv (tfm->d(c))); y2= max (y2, conv (tfm->h(c))); - x3= min (x3, x2- ((int) gl->xoff) * PIXEL); - x4= max (x4, x2+ ((int) (gl->width- gl->xoff)) * PIXEL); - y3= min (y3, ((int) (gl->yoff- gl->height)) * PIXEL); - y4= max (y4, ((int) gl->yoff) * PIXEL); + x3= min (x3, x2- ((int) xoff) * PIXEL); + x4= max (x4, x2+ ((int) (width - xoff)) * PIXEL); + y3= min (y3, ((int) (yoff - height)) * PIXEL); + y4= max (y4, ((int) yoff) * PIXEL); + x2 += conv (tfm->w(c)+ ker[i]); } @@ -623,8 +654,15 @@ for (i=0; i<m; i++) { register int c= buf[i]; - glyph gl= pk->get (c); - if (is_nil (gl)) continue; + +#ifdef QTTEXMACS + if(!pk->is_qt_font) +#endif + { + glyph gl= pk->get (c); + if (is_nil (gl)) continue; + } + ren->draw (c, pk, x, y); x += conv (tfm->w(c)+ ker[i]); } _______________________________________________ Texmacs-dev mailing list [email protected] http://lists.gnu.org/mailman/listinfo/texmacs-dev
