texmacs-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Texmacs-dev] New Fonts + Native Font Rendering Patch


From: Aleksandr Dobkin
Subject: [Texmacs-dev] New Fonts + Native Font Rendering Patch
Date: Mon, 21 Dec 2009 17:23:22 -0600

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]);
   }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]