*** empty log message ***
authorhanda <handa>
Wed, 17 Mar 2004 12:56:57 +0000 (12:56 +0000)
committerhanda <handa>
Wed, 17 Mar 2004 12:56:57 +0000 (12:56 +0000)
src/face.c
src/font-ft.c
src/font.c
src/font.h
src/internal-gui.h

index 216eafa..14d5cd0 100644 (file)
@@ -386,6 +386,8 @@ deserialize_face (MPlist *plist)
   return face;
 }
 
+static MGlyphString work_gstring;
+
 \f
 
 /* Internal API */
@@ -515,6 +517,11 @@ mface__init ()
   mface_yellow->property[MFACE_FOREGROUND] = (void *) msymbol ("yellow");
   mface_magenta = mface ();
   mface_magenta->property[MFACE_FOREGROUND] = (void *) msymbol ("magenta");
+
+  work_gstring.glyphs = malloc (sizeof (MGlyph) * 2);
+  work_gstring.size = 2;
+  work_gstring.used = 0;
+  work_gstring.inc = 1;
   return 0;
 }
 
@@ -608,12 +615,14 @@ mface__realize (MFrame *frame, MFace **faces, int num,
     {
       rface->rfont = rfont;
       g.otf_encoded = 0;
-      mfont__get_metric (rfont, &g);
-      rface->space_width = g.width;
-      g.code = MCHAR_INVALID_CODE;
-      mfont__get_metric (rface->rfont, &g);
-      rface->ascent = g.ascent;
-      rface->descent = g.descent;
+      work_gstring.glyphs[0] = g;
+      work_gstring.glyphs[0].rface = rface;
+      work_gstring.glyphs[1].code = MCHAR_INVALID_CODE;
+      work_gstring.glyphs[1].rface = rface;
+      mfont__get_metric (&work_gstring, 0, 2);
+      rface->space_width = work_gstring.glyphs[0].width;
+      rface->ascent = work_gstring.glyphs[1].ascent;
+      rface->descent = work_gstring.glyphs[1].descent;
     }
   else
     {
@@ -664,12 +673,11 @@ mface__for_chars (MSymbol script, MSymbol language, MSymbol charset,
       *rface = *from_g->rface->ascii_rface;
       rface->rfont = rfont;
       {
-       MGlyph tmp;
-
-       tmp.code = MCHAR_INVALID_CODE;
-       mfont__get_metric (rfont, &tmp);
-       rface->ascent = tmp.ascent;
-       rface->descent = tmp.descent;
+       work_gstring.glyphs[0].code = MCHAR_INVALID_CODE;
+       work_gstring.glyphs[0].rface = rface;
+       mfont__get_metric (&work_gstring, 0, 1);
+       rface->ascent = work_gstring.glyphs[0].ascent;
+       rface->descent = work_gstring.glyphs[0].descent;
       }
       mwin__realize_face (rface);
       mplist_add (from_g->rface->frame->realized_face_list, Mt, rface);
index 0733afe..e93fb04 100644 (file)
@@ -261,7 +261,7 @@ build_font_list ()
 static MRealizedFont *ft_select (MFrame *, MFont *, MFont *, int);
 static int ft_open (MRealizedFont *);
 static void ft_close (MRealizedFont *);
-static void ft_find_metric (MRealizedFont *, MGlyph *);
+static void ft_find_metric (MRealizedFont *, MGlyphString *, int, int);
 static unsigned ft_encode_char (MRealizedFont *, int, unsigned);
 static void ft_render (MDrawWindow, int, int, MGlyphString *,
                       MGlyph *, MGlyph *, int, MDrawRegion);
@@ -400,39 +400,54 @@ ft_close (MRealizedFont *rfont)
 /* The FreeType font driver function FIND_METRIC.  */
 
 static void
-ft_find_metric (MRealizedFont *rfont, MGlyph *g)
+ft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
+               int from, int to)
 {
   MFTInfo *ft_info = (MFTInfo *) rfont->info;
   FT_Face ft_face = ft_info->ft_face;
+  MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
+  FT_Int32 load_flags = FT_LOAD_RENDER;
 
-  if (g->code == MCHAR_INVALID_CODE)
+  if (! gstring->anti_alias)
     {
-      unsigned unitsPerEm = ft_face->units_per_EM;
-      int size = rfont->font.property[MFONT_SIZE] / 10;
-
-      g->lbearing = 0;
-      g->rbearing = ft_face->max_advance_width * size / unitsPerEm;
-      g->width = ft_face->max_advance_width * size / unitsPerEm;
-      g->ascent = ft_face->ascender * size / unitsPerEm;
-      g->descent = (- ft_face->descender) * size / unitsPerEm;
+#ifdef FT_LOAD_TARGET_MONO
+      load_flags |= FT_LOAD_TARGET_MONO;
+#else
+      load_flags |= FT_LOAD_MONOCHROME;
+#endif
     }
-  else
-    {
-      FT_Glyph_Metrics *metrics;
-      FT_UInt code;
 
-      if (g->otf_encoded)
-       code = g->code;
+  for (; g != gend; g++)
+    {
+      if (g->code == MCHAR_INVALID_CODE)
+       {
+         unsigned unitsPerEm = ft_face->units_per_EM;
+         int size = rfont->font.property[MFONT_SIZE] / 10;
+
+         g->lbearing = 0;
+         g->rbearing = ft_face->max_advance_width * size / unitsPerEm;
+         g->width = ft_face->max_advance_width * size / unitsPerEm;
+         g->ascent = ft_face->ascender * size / unitsPerEm;
+         g->descent = (- ft_face->descender) * size / unitsPerEm;
+       }
       else
-       code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code);
-
-      FT_Load_Glyph (ft_face, code, FT_LOAD_RENDER);
-      metrics = &ft_face->glyph->metrics;
-      g->lbearing = (metrics->horiBearingX >> 6);
-      g->rbearing = (metrics->horiBearingX + metrics->width) >> 6;
-      g->width = metrics->horiAdvance >> 6;
-      g->ascent = metrics->horiBearingY >> 6;
-      g->descent = (metrics->height - metrics->horiBearingY) >> 6;
+       {
+         FT_Glyph_Metrics *metrics;
+         FT_UInt code;
+
+         if (g->otf_encoded)
+           code = g->code;
+         else
+           code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code);
+
+         FT_Load_Glyph (ft_face, code, FT_LOAD_RENDER);
+         metrics = &ft_face->glyph->metrics;
+         g->lbearing = (metrics->horiBearingX >> 6);
+         g->rbearing = (metrics->horiBearingX + metrics->width) >> 6;
+         g->width = metrics->horiAdvance >> 6;
+         g->ascent = metrics->horiBearingY >> 6;
+         g->descent = (metrics->height - metrics->horiBearingY) >> 6;
+       }
     }
 }
 
@@ -464,28 +479,31 @@ ft_encode_char (MRealizedFont *rfont, int c, unsigned ignored)
 
 /* The FreeType font driver function RENDER.  */
 
-struct {
-  int size, inc, used;
-  MDrawPoint *points;
-} point_table[8];
+#define NUM_POINTS 0x1000
+
+typedef struct {
+  MDrawPoint points[NUM_POINTS];
+  MDrawPoint *p;
+} MPointTable;
 
 static void
 ft_render (MDrawWindow win, int x, int y,
           MGlyphString *gstring, MGlyph *from, MGlyph *to,
           int reverse, MDrawRegion region)
 {
-  MRealizedFace *rface;
-  MFrame *frame;
+  MRealizedFace *rface = from->rface;
+  MFrame *frame = rface->frame;
   MFTInfo *ft_info;
   FT_Face ft_face = NULL;
   FT_Int32 load_flags = FT_LOAD_RENDER;
   MGlyph *g;
   int i, j;
+  MPointTable point_table[8];
 
   if (from == to)
     return;
 
-  if (! gstring->control.anti_alias)
+  if (! gstring->anti_alias)
     {
 #ifdef FT_LOAD_TARGET_MONO
       load_flags |= FT_LOAD_TARGET_MONO;
@@ -496,74 +514,91 @@ ft_render (MDrawWindow win, int x, int y,
 
   /* It is assured that the all glyphs in the current range use the
      same realized face.  */
-  rface = from->rface;
-  frame = rface->frame;
   ft_info = (MFTInfo *) rface->rfont->info;
   ft_face = ft_info->ft_face;
 
   for (i = 0; i < 8; i++)
-    MLIST_RESET (point_table + i);
+    point_table[i].p = point_table[i].points;
 
   for (g = from; g < to; x += g++->width)
     {
       FT_UInt code;
       unsigned char *bmp;
-      MDrawPoint p;
       int intensity;
+      MPointTable *ptable;
+      int xoff, yoff;
 
       if (g->otf_encoded)
        code = g->code;
       else
        code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code);
       FT_Load_Glyph (ft_face, code, load_flags);
+      yoff = y - ft_face->glyph->bitmap_top + g->yoff;
       bmp = ft_face->glyph->bitmap.buffer;
-      if (gstring->control.anti_alias)
-       {
-         for (i = 0; i < ft_face->glyph->bitmap.rows;
-              i++, bmp += ft_face->glyph->bitmap.pitch)
-           for (j = 0; j < ft_face->glyph->bitmap.width; j++)
+      if (gstring->anti_alias)
+       for (i = 0; i < ft_face->glyph->bitmap.rows;
+            i++, bmp += ft_face->glyph->bitmap.pitch, yoff++)
+         {
+           xoff = x + ft_face->glyph->bitmap_left + g->xoff;
+           for (j = 0; j < ft_face->glyph->bitmap.width; j++, xoff++)
              {
                intensity = bmp[j] >> 5;
                if (intensity)
                  {
-                   p.x = x + ft_face->glyph->bitmap_left + g->xoff + j;
-                   p.y = y - ft_face->glyph->bitmap_top + g->yoff + i;
-                   MLIST_APPEND1 (point_table + intensity, points, p,
-                                  MERROR_FONT_FT);
+                   ptable = point_table + intensity;
+                   ptable->p->x = xoff;
+                   ptable->p->y = yoff;
+                   ptable->p++;
+                   if (ptable->p - ptable->points == NUM_POINTS)
+                     {
+                       mwin__draw_points (frame, win, rface,
+                                          reverse ? 7 - intensity : intensity,
+                                          ptable->points, NUM_POINTS, region);
+                       ptable->p = ptable->points;
+                     }
                  }
              }
-       }
+         }
       else
-       {
-         for (i = 0; i < ft_face->glyph->bitmap.rows;
-              i++, bmp += ft_face->glyph->bitmap.pitch)
-           for (j = 0; j < ft_face->glyph->bitmap.width; j++)
+       for (i = 0; i < ft_face->glyph->bitmap.rows;
+            i++, bmp += ft_face->glyph->bitmap.pitch, yoff++)
+         {
+           xoff = x + ft_face->glyph->bitmap_left + g->xoff;
+           for (j = 0; j < ft_face->glyph->bitmap.width; j++, xoff++)
              {
                intensity = bmp[j / 8] & (1 << (7 - (j % 8)));
                if (intensity)
                  {
-                   p.x = x + ft_face->glyph->bitmap_left + g->xoff + j;
-                   p.y = y - ft_face->glyph->bitmap_top + g->yoff + i;
-                   MLIST_APPEND1 (point_table, points, p,
-                                  MERROR_FONT_FT);
+                   ptable = point_table;
+                   ptable->p->x = xoff;
+                   ptable->p->y = yoff;
+                   ptable->p++;
+                   if (ptable->p - ptable->points == NUM_POINTS)
+                     {
+                       mwin__draw_points (frame, win, rface,
+                                          reverse ? 0 : 7,
+                                          ptable->points, NUM_POINTS, region);
+                       ptable->p = ptable->points;
+                     }             
                  }
              }
        }
     }
 
-  if (gstring->control.anti_alias)
+  if (gstring->anti_alias)
     {
       for (i = 1; i < 8; i++)
-       if (point_table[i].used)
+       if (point_table[i].p != point_table[i].points)
          mwin__draw_points (frame, win, rface, reverse ? 7 - i : i,
-                            point_table[i].points, point_table[i].used,
-                            gstring->control.anti_alias);
+                            point_table[i].points,
+                            point_table[i].p - point_table[i].points, region);
     }
   else
     {
-      mwin__draw_points (frame, win, rface, reverse ? 7 : 0,
-                        point_table[0].points, point_table[0].used,
-                        gstring->control.anti_alias);
+      if (point_table[0].p != point_table[0].points)
+       mwin__draw_points (frame, win, rface, reverse ? 0 : 7,
+                          point_table[0].points,
+                          point_table[0].p - point_table[0].points, region);
     }
 }
 
@@ -603,9 +638,6 @@ mfont__ft_init ()
 
   mfont__driver_list[MFONT_TYPE_FT] = &ft_driver;
 
-  for (i = 0; i < 8; i++)
-    MLIST_INIT1 (point_table + i, points, 0x1000);
-
   return 0;
 }
 
index 645f8e8..2cc4f55 100644 (file)
@@ -957,9 +957,22 @@ mfont__encode_char (MRealizedFont *rfont, int c)
 }
 
 void
-mfont__get_metric (MRealizedFont *rfont, MGlyph *g)
+mfont__get_metric (MGlyphString *gstring, int from, int to)
 {
-  (rfont->driver->find_metric) (rfont, g);
+  MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
+  MRealizedFont *rfont = from_g->rface->rfont;
+
+  for (g = from_g; g != to_g; g++)
+    if (g->rface->rfont != rfont)
+      {
+       int idx = GLYPH_INDEX (g);
+
+       (rfont->driver->find_metric) (rfont, gstring, from, idx);
+       from_g = g;
+       rfont = g->rface->rfont;
+       from = idx;
+      }
+  (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
 }
 
 
index 6c77228..2053328 100644 (file)
@@ -169,7 +169,9 @@ struct MFontDriver
   /** Close a font specified by RFONT.   */
   void (*close) (MRealizedFont *rfont);
 
-  void (*find_metric) (MRealizedFont *rfont, MGlyph *g);
+  /** Set metrics of glyphs in GSTRING from FROM to TO.  */
+  void (*find_metric) (MRealizedFont *rfont, MGlyphString *gstring,
+                      int from, int to);
 
   /** Encode C into the glyph code the font.  CODE is a code point of
       C in rfont->encoder->encoding_charset.  If the font has no glyph
@@ -233,7 +235,7 @@ extern int mfont__open (MRealizedFont *rfont);
 
 extern void mfont__close (MRealizedFont *rfont);
 
-extern void mfont__get_metric (MRealizedFont *rfont, MGlyph *g);
+extern void mfont__get_metric (MGlyphString *gstring, int from, int to);
 
 extern void mfont__set_property (MFont *font, enum MFontProperty key,
                                 MSymbol val);
index bda0e20..656bfb6 100644 (file)
@@ -115,6 +115,10 @@ struct MGlyphString
   /* Members to keep temporary data while layouting.  */
   short sub_width, sub_lbearing, sub_rbearing;
 
+  /* Copied for <control>.anti_alias but never set if the frame's
+     depth is less than 8.  */
+  unsigned anti_alias : 1;
+
   MDrawControl control;
 
   MDrawRegion region;
@@ -239,14 +243,7 @@ extern void mwin__draw_box (MFrame *frame, MDrawWindow win,
 extern void mwin__draw_points (MFrame *frame, MDrawWindow win,
                               MRealizedFace *rface,
                               int intensity, MDrawPoint *points, int num,
-                              int pixmap);
-
-extern void mwin__draw_bitmap (MFrame *frame, MDrawWindow win,
-                              MRealizedFace *rface, int reverse,
-                              int x, int y,
-                              int width, int height, int row_bytes,
-                              unsigned char *bmp,
-                              MDrawRegion region, int pixmap);
+                              MDrawRegion region);
 
 extern MDrawRegion mwin__region_from_rect (MDrawMetric *rect);