texmacs-dev
[Top][All Lists]
Advanced

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

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


From: Gubinelli Massimiliano
Subject: Re: [Texmacs-dev] New Fonts + Native Font Rendering Patch
Date: Wed, 23 Dec 2009 15:38:42 +0100

Dear Aleksandr,
thanks for your contribution. Currently we are trying to iron out the Qt port (mantaining the same functionality of the X11 port so that to have a base for comparison of performances and regressions) and only when this will be finished and well tested we will start to move away to more drastic changes (including font handling). I like very much your approach to native fonts (which is better than what I tried to accomplish in the past) and I will study you code in view of future integration. Some thoughs: 1) What seems a bit odd to me is that the Qt font supporting code is scattered all along the codebase, I didn't had time to look at this more deeply but wouldn't be possible to define a new font class qt_font (like done with x11 fonts) implemented inside the src/Plugins/ Qt directory?) 2) An interesting thing to try is to add support for TeX-Gyre fonts and Latin Modern fonts which are open type free fonts designed for use with TeX. 3) With you experise with fontforge: could you try to reencode the standard computer modern pfb files needed by TeXmacs using as a base the Type 1 Latin modern fonts? the current pfb fonts distributed with TeXmacs are obtained by tracing the bitmapped fonts which produced quite not optimal bytecode. Moreover on some printer I have I experience some problems with these fonts.

Thanks again for the interesting work.

Massimiliano


On 22 déc. 09, at 00:23, Aleksandr Dobkin wrote:

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
address@hidden
http://lists.gnu.org/mailman/listinfo/texmacs-dev





reply via email to

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