ecere/gfx/fontRendering: Improved rendering of some fonts e.g. MS Sans Serif having...
[sdk] / ecere / src / gfx / fontRendering.ec
index 3286ed3..8cdf1d6 100644 (file)
@@ -6,6 +6,8 @@ import "fontManagement"
 #define ECERE_NOTRUETYPE
 #endif
 
+#define _Noreturn
+
 #undef __BLOCKS__
 #define uint _uint
 #define strlen _strlen
@@ -30,6 +32,8 @@ static uint16 * utf16 = null;
 
 #if !defined(ECERE_VANILLA)
 import "imgDistMap"
+import "immediate"
+#include "gl123es.h"
 #endif
 
 #define MAX_FONT_LINK_ENTRIES   10
@@ -701,9 +705,17 @@ class GlyphPack : BTNode
                )
 #endif
             {
+#if !defined(ECERE_VANILLA)
+               if(displaySystem.driver == class(OpenGLDisplayDriver) && lastBlitTex)
+                  GLEnd();
+#endif
                bitmap.MakeDD(displaySystem);
                if(outline)
                   outline.MakeDD(displaySystem);
+#if !defined(ECERE_VANILLA)
+               if(displaySystem.driver == class(OpenGLDisplayDriver) && lastBlitTex)
+                  GLBegin(GLIMTKMode::quads);
+#endif
             }
             displaySystem.Unlock();
          }
@@ -793,18 +805,16 @@ public class Font : struct
 
    ~Font()
    {
+#if !defined(ECERE_NOTRUETYPE)
       int entry;
 
-#if !defined(ECERE_NOTRUETYPE)
       GlyphPack pack;
       while((pack = (GlyphPack)glyphPacks.root))
       {
          glyphPacks.Remove(pack);
          delete pack;
       }
-#endif
 
-#if !defined(ECERE_NOTRUETYPE)
       for(entry = 0; entry<MAX_FONT_LINK_ENTRIES; entry++)
       {
          FontEntry fontEntry = fontEntries[entry];
@@ -842,6 +852,7 @@ public class Font : struct
    bool LoadEntry(FaceInfo info)
    {
       bool result = false;
+#if !defined(ECERE_NOTRUETYPE)
       if(numEntries < MAX_FONT_LINK_ENTRIES)
       {
          FontEntry fontEntry = FontEntry::Load(info);
@@ -868,6 +879,8 @@ public class Font : struct
                FT_Set_Transform(fontEntry.face, &matrix, &pen );
                FaceSetCharSize(fontEntry.face, size);
                height = (int)((fontEntry.face->size->metrics.height) >> 6); //* y_scale;
+               if(!height)
+                  height = size * 96 / 72 + 4;
                // printf("Font height is %d\n", height);
                this.fakeItalic = info.fakeItalic;
             }
@@ -877,6 +890,7 @@ public class Font : struct
             result = true;
          }
       }
+#endif
       return result;
    }
 
@@ -1143,16 +1157,16 @@ public class Font : struct
             }
             if(pack)
             {
+               FT_Face face = curFontEntry ? curFontEntry.face : null;
                int index = rightToLeft ? (glyphIndex + 1) : (glyphIndex-1);
                Glyph * glyph = &pack.glyphs[glyphNo & 0x7F];
 
                int ax = (int)((numGlyphs ? shaper_item.advances[index] : glyph->ax) * glyph->scale);
                int offset = numGlyphs ? shaper_item.offsets[index].x : 0;
-               int oy = 0;//numGlyphs ? shaper_item.offsets[index].y : 0;
 
                ax += offset;
 
-               if(previousGlyph && curFontEntry && (curFontEntry.face == previousFace || !previousFace)) // TO IMPROVE: Assuming same face for now for multiple calls...
+               if(previousGlyph && curFontEntry && (face == previousFace || !previousFace)) // TO IMPROVE: Assuming same face for now for multiple calls...
                {
                   FT_Vector delta = { 0, 0 };
                   FT_Get_Kerning(curFontEntry.face, previousGlyph, glyph->glyphNo, FT_KERNING_UNFITTED, &delta );
@@ -1161,14 +1175,26 @@ public class Font : struct
                   *x += delta.x * glyph->scale;
                }
                else if(curFontEntry)
-                  FaceSetCharSize(curFontEntry.face, size);
+                  FaceSetCharSize(face, size);
 
                previousGlyph = glyph->glyphNo;
-               previousFace = curFontEntry ? curFontEntry.face : null;
+               previousFace = face;
 
-               if(output)
-                  surface.driver.Blit(display, surface, bitmap, ((*x) >> 6) + glyph->left - writingOutline * padding, y + (oy >> 6) + glyph->top - writingOutline * padding,
+               if(output && face)
+               {
+                  int h = (int)face->size->metrics.height;
+                  int desc = (int)face->size->metrics.descender;
+                  int oy = (numGlyphs ? shaper_item.offsets[index].y : 0);
+                  if(!h)
+                     h = height * 64;
+
+                  oy += h + desc - glyph->by;
+                  oy >>= 6;
+                  //oy += glyph->top;
+
+                  surface.driver.Blit(display, surface, bitmap, ((*x) >> 6) + glyph->left - writingOutline * padding, y + oy - writingOutline * padding,
                      writingOutline ? glyph->ox : glyph->x, writingOutline ? glyph->oy : glyph->y, glyph->w + writingOutline + 2 * padding, glyph->h + writingOutline + 2 * padding);
+               }
                *x += ax;
 
                lastGlyph = glyph;
@@ -1181,7 +1207,7 @@ public class Font : struct
          {
             int w = (lastGlyph->w + lastGlyph->left) * (1 << 6);
             // Fix for advance != width + left (e.g. italic fonts)
-            if(w > lastAX)
+            if(w > lastAX && advance)
                *advance = w - lastAX;
          }
          if(rPrevGlyph) *rPrevGlyph = previousGlyph;