changeset 24496:541ff963ba80

Merged patches from Meadow.
author Geoff Voelker <voelker@cs.washington.edu>
date Wed, 17 Mar 1999 22:03:43 +0000
parents 14e1df6e60a8
children b09ceba3d319
files src/w32bdf.c src/w32bdf.h
diffstat 2 files changed, 233 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/src/w32bdf.c	Wed Mar 17 11:29:05 1999 +0000
+++ b/src/w32bdf.c	Wed Mar 17 22:03:43 1999 +0000
@@ -37,6 +37,12 @@
 void w32_free_bdf_font(bdffont *fontp);
 bdffont *w32_init_bdf_font(char *filename);
 
+cache_bitmap cached_bitmap_slots[BDF_FONT_CACHE_SIZE];
+cache_bitmap *pcached_bitmap_latest = cached_bitmap_slots;
+
+#define FONT_CACHE_SLOT_OVER_P(p) \
+   ((p) >= cached_bitmap_slots + BDF_FONT_CACHE_SIZE)
+
 static int 
 search_file_line(char *key, char *start, int len, char **val, char **next)
 {
@@ -75,6 +81,27 @@
   return 1;
 }
    
+char*
+get_quoted_string(char *start, char *end)
+{
+  char *p, *q, *result;
+
+  p = memchr(start, '\"', end - start);
+  q = 0;
+
+  if (!p) return NULL;
+  p++;
+  q = memchr(p, '\"', end - q);
+  if (!q) return NULL;
+
+  result = (char*) xmalloc(q - p + 1);
+
+  memcpy(result, p, q - p);
+  result[q - p] = '\0';
+
+  return result;
+}
+
 static int
 set_bdf_font_info(bdffont *fontp)
 {
@@ -89,6 +116,10 @@
   fontp->yoffset = 0;
   fontp->relative_compose = 0;
   fontp->default_ascent = 0;
+  fontp->registry = NULL;
+  fontp->encoding = NULL;
+  fontp->slant = NULL;
+/*  fontp->width = NULL; */
 
   flag = proceed_file_line("FONTBOUNDINGBOX", start, &len, &p, &q);
   if (!flag) return 0;
@@ -110,6 +141,8 @@
   flag = proceed_file_line("STARTPROPERTIES", start, &len, &p, &q);
   if (!flag) return 1;
 
+  flag = 0;
+
   do {
     start = q;
     if (search_file_line("PIXEL_SIZE", start, len, &p, &q) == 1)
@@ -142,6 +175,24 @@
 	val1 = atoi(p);
 	fontp->default_ascent = val1;
       }
+    else if (search_file_line("CHARSET_REGISTRY", start, len, &p, &q) == 1)
+      {
+        fontp->registry = get_quoted_string(p, q);
+      }
+    else if (search_file_line("CHARSET_ENCODING", start, len, &p, &q) == 1)
+      {
+        fontp->encoding = get_quoted_string(p, q);
+      }
+    else if (search_file_line("SLANT", start, len, &p, &q) == 1)
+      {
+        fontp->slant = get_quoted_string(p, q);
+      }
+/*
+    else if (search_file_line("SETWIDTH_NAME", start, len, &p, &q) == 1)
+      {
+        fontp->width = get_quoted_string(p, q);
+      }
+*/
     else
       {
 	flag = search_file_line("ENDPROPERTIES", start, len, &p, &q);
@@ -195,7 +246,7 @@
   bdffontp = (bdffont *) xmalloc(sizeof(bdffont));
   
   for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++)
-    bdffontp->offset[i] = NULL;
+    bdffontp->chtbl[i] = NULL;
   bdffontp->size = fileinfo.nFileSizeLow;
   bdffontp->font = font;
   bdffontp->hfile = hfile;
@@ -214,64 +265,83 @@
 void
 w32_free_bdf_font(bdffont *fontp)
 {
-  int i;
+  int i, j;
+  font_char *pch;
+  cache_bitmap *pcb;
 
   UnmapViewOfFile(fontp->hfilemap);
   CloseHandle(fontp->hfilemap);
   CloseHandle(fontp->hfile);
+
+  if (fontp->registry) xfree(fontp->registry);
+  if (fontp->encoding) xfree(fontp->encoding);
+  if (fontp->slant) xfree(fontp->slant);
+/*  if (fontp->width) xfree(fontp->width); */
+
   xfree(fontp->filename);
   for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++)
     {
-      if (fontp->offset[i]) xfree(fontp->offset[i]);
+      pch = fontp->chtbl[i];
+      if (pch)
+	{
+	  for (j = 0;j < BDF_SECOND_OFFSET_TABLE;j++)
+	    {
+	      pcb = pch[j].pcbmp;
+	      if (pcb) pcb->psrc = NULL;
+	    }
+	  xfree(pch);
+        }
     }
   xfree(fontp);
 }
 
-static unsigned char*
-get_cached_char_offset(bdffont *fontp, int index)
+static font_char*
+get_cached_font_char(bdffont *fontp, int index)
 {
-  unsigned char **offset1;
-  unsigned char *offset2;
+  font_char *pch, *result;
   int i;
 
   if (index > 0xffff)
     return NULL;
 
-  offset1 = fontp->offset[BDF_FIRST_OFFSET(index)];
-  if (!offset1)
+  pch = fontp->chtbl[BDF_FIRST_OFFSET(index)];
+  if (!pch)
     return NULL;
-  offset2 = offset1[BDF_SECOND_OFFSET(index)];
+  result = &pch[BDF_SECOND_OFFSET(index)];
 
-  if (offset2) return offset2;
+  if (!result->offset) return NULL;
 
-  return NULL;
+  return result;
 }
 
-static void
+static font_char*
 cache_char_offset(bdffont *fontp, int index, unsigned char *offset)
 {
-  unsigned char **offset1;
+  font_char *pch, *result;
   int i;
 
   if (index > 0xffff)
-    return;
+    return NULL;
 
-  offset1 = fontp->offset[BDF_FIRST_OFFSET(index)];
-  if (!offset1)
+  pch = fontp->chtbl[BDF_FIRST_OFFSET(index)];
+  if (!pch)
     {
-      offset1 = fontp->offset[BDF_FIRST_OFFSET(index)] =
-	(unsigned char **) xmalloc(sizeof(unsigned char*) *
+      pch = fontp->chtbl[BDF_FIRST_OFFSET(index)] =
+	(font_char*) xmalloc(sizeof(font_char) *
 				   BDF_SECOND_OFFSET_TABLE);
-      memset(offset1, 0, sizeof(unsigned char*) * BDF_SECOND_OFFSET_TABLE);
+      memset(pch, 0, sizeof(font_char) * BDF_SECOND_OFFSET_TABLE);
     }
-  offset1[BDF_SECOND_OFFSET(index)] = offset;
 
-  return;
+  result = &pch[BDF_SECOND_OFFSET(index)];
+  result->offset = offset;
+
+  return result;
 }
 
-static unsigned char*
-seek_char_offset(bdffont *fontp, int index)
+static font_char*
+seek_char(bdffont *fontp, int index)
 {
+  font_char *result;
   int len, flag, font_index;
   unsigned char *start, *p, *q;
 
@@ -288,12 +358,35 @@
 	return NULL;
       }
     font_index = atoi(p);
-    cache_char_offset(fontp, font_index, q);
-    start = q;
+    result = cache_char_offset(fontp, font_index, q);
+    if (!result) return NULL;
+
+    start = result->offset;
   } while (font_index != index);
-  fontp->seeked = q;
+  fontp->seeked = start;
+
+  return result;
+}
+
+void
+clear_cached_bitmap_slots()
+{
+  int i;
+  cache_bitmap *p;
 
-  return q;
+  p = pcached_bitmap_latest;
+  for (i = 0;i < BDF_FONT_CLEAR_SIZE;i++)
+    {
+      if (p->psrc)
+	{
+	  DeleteObject(p->hbmp);
+	  p->psrc->pcbmp = NULL;
+	  p->psrc = NULL;
+	}
+      p++;
+      if (FONT_CACHE_SLOT_OVER_P(p))
+	p = cached_bitmap_slots;
+    }
 }
 
 #define GET_HEX_VAL(x) ((isdigit(x)) ? ((x) - '0') : \
@@ -304,34 +397,45 @@
 int
 w32_get_bdf_glyph(bdffont *fontp, int index, int size, glyph_struct *glyph)
 {
+  font_char *pch;
   unsigned char *start, *p, *q, *bitmapp;
   unsigned char val1, val2;
   int i, j, len, flag;
 
-  start = get_cached_char_offset(fontp, index);
-  if (!start)
-    start = seek_char_offset(fontp, index);
-  if (!start)
-    return 0;
+  pch = get_cached_font_char(fontp, index);
+  if (!pch)
+    {
+      pch = seek_char(fontp, index);
+      if (!pch)
+        return 0;
+    }
+
+  start = pch->offset;
+
+  if ((size == 0) && pch->pcbmp)
+    {
+      glyph->metric = pch->pcbmp->metric;
+      return 1;
+    }
 
   len = fontp->size - (start - fontp->font);
 
   flag = proceed_file_line("DWIDTH", start, &len, &p, &q);
   if (!flag)
     return 0;
-  glyph->dwidth = atoi(p);
+  glyph->metric.dwidth = atoi(p);
 
   start = q;
   flag = proceed_file_line("BBX", start, &len, &p, &q);
   if (!flag)
     return 0;
-  glyph->bbw = strtol(p, &start, 10);
+  glyph->metric.bbw = strtol(p, &start, 10);
   p = start;
-  glyph->bbh = strtol(p, &start, 10);
+  glyph->metric.bbh = strtol(p, &start, 10);
   p = start;
-  glyph->bbox = strtol(p, &start, 10);
+  glyph->metric.bbox = strtol(p, &start, 10);
   p = start;
-  glyph->bboy = strtol(p, &start, 10);
+  glyph->metric.bboy = strtol(p, &start, 10);
 
   if (size == 0) return 1;
 
@@ -342,11 +446,11 @@
 
   p = q;
   bitmapp = glyph->bitmap;
-  for(i = 0;i < glyph->bbh;i++)
+  for(i = 0;i < glyph->metric.bbh;i++)
     {
       q = memchr(p, '\n', len);
       if (!q) return 0;
-      for(j = 0;((q > p) && (j < ((glyph->bbw + 7) / 8 )));j++)
+      for(j = 0;((q > p) && (j < ((glyph->metric.bbw + 7) / 8 )));j++)
 	{
 	  val1 = GET_HEX_VAL(*p);
 	  if (val1 == -1) return 0;
@@ -370,26 +474,67 @@
   return 1;
 }
 
+static
+cache_bitmap*
+get_bitmap_with_cache(bdffont *fontp, int index)
+{
+  int bitmap_size;
+  font_char *pch;
+  cache_bitmap* pcb;
+  HBITMAP hbmp;
+  glyph_struct glyph;
+
+  pch = get_cached_font_char(fontp, index);
+  if (pch)
+    {
+      pcb = pch->pcbmp;
+      if (pcb) return pcb;
+    }
+
+  bitmap_size = ((fontp->urx - fontp->llx) / 8 + 2) * (fontp->ury - fontp->lly)
+    + 256;
+  glyph.bitmap = (unsigned char*) alloca(sizeof(unsigned char) * bitmap_size);
+
+  if (!w32_get_bdf_glyph(fontp, index, bitmap_size, &glyph))
+    return NULL;
+
+  pch = get_cached_font_char(fontp, index);
+  if (!pch) return NULL;
+
+  hbmp = CreateBitmap(glyph.metric.bbw, glyph.metric.bbh, 1, 1, glyph.bitmap);
+
+  pcb = pcached_bitmap_latest;
+  if (pcb->psrc)
+    clear_cached_bitmap_slots();
+
+  pcb->psrc = pch;
+  pcb->metric = glyph.metric;
+  pcb->hbmp = hbmp;
+
+  pch->pcbmp = pcb;
+  
+  pcached_bitmap_latest++;
+  if (FONT_CACHE_SLOT_OVER_P(pcached_bitmap_latest))
+    pcached_bitmap_latest = cached_bitmap_slots;
+
+  return pcb;
+}
+
 int
 w32_BDF_TextOut(bdffont *fontp, HDC hdc, int left,
 		 int top, unsigned char *text, int dim, int bytelen,
 		 int fixed_pitch_size)
 {
-  int bitmap_size, index, btop;
+  int index, btop;
   unsigned char *textp;
-  glyph_struct glyph;
   HDC hCompatDC = 0;
+  cache_bitmap *pcb;
   HBITMAP hBMP;
   HBRUSH hFgBrush, hOrgBrush;
-  HANDLE holdobj, horgobj = 0;
+  HANDLE horgobj = 0;
   UINT textalign;
   int flag = 0;
 
-  bitmap_size = ((fontp->urx - fontp->llx) / 8 + 2) * (fontp->ury - fontp->lly)
-    + 256;
-
-  glyph.bitmap = (unsigned char*) alloca(sizeof(unsigned char) * bitmap_size);
-
   hCompatDC = CreateCompatibleDC(hdc);
 
   textalign = GetTextAlign(hdc);
@@ -416,7 +561,8 @@
 	  index = MAKELENDSHORT(textp[1], textp[0]);
 	  textp += 2;
 	}
-      if (!w32_get_bdf_glyph(fontp, index, bitmap_size, &glyph))
+      pcb = get_bitmap_with_cache(fontp, index);
+      if (!pcb)
 	{
 	  if (horgobj)
 	    {
@@ -426,45 +572,32 @@
 	  DeleteDC(hCompatDC);
 	  return 0;
 	}
-      hBMP = CreateBitmap(glyph.bbw, glyph.bbh, 1, 1, glyph.bitmap);
+      hBMP = pcb->hbmp;
+
       if (textalign & TA_BASELINE)
-	{
-	  btop = top - (glyph.bbh + glyph.bboy);
-	}
+	  btop = top - (pcb->metric.bbh + pcb->metric.bboy);
       else if (textalign & TA_BOTTOM)
-	{
-	  btop = top - glyph.bbh;
-	}
+	  btop = top - pcb->metric.bbh;
       else
-	{
 	  btop = top;
-	}
 
       if (horgobj)
-	{
 	  SelectObject(hCompatDC, hBMP);
-	  DeleteObject(holdobj);
-	  holdobj = hBMP;
-	}
       else
-	{
 	  horgobj = SelectObject(hCompatDC, hBMP);
-	  holdobj = hBMP;
-	}
 #if 0
-      BitBlt(hdc, left, btop, glyph.bbw, glyph.bbh, hCompatDC, 0, 0, SRCCOPY);
+      BitBlt(hdc, left, btop, pcb->metric.bbw, pcb->metric.bbh, hCompatDC, 0, 0, SRCCOPY);
 #else
-      BitBlt(hdc, left, btop, glyph.bbw, glyph.bbh, hCompatDC, 0, 0, 0xB8074A);
+      BitBlt(hdc, left, btop, pcb->metric.bbw, pcb->metric.bbh, hCompatDC, 0, 0, 0xB8074A);
 #endif
       if (fixed_pitch_size)
 	left += fixed_pitch_size;
       else
-	left += glyph.dwidth;
+	left += pcb->metric.dwidth;
     }
   SelectObject(hCompatDC, horgobj);
   SelectObject(hdc, hOrgBrush);
   DeleteObject(hFgBrush);
-  DeleteObject(hBMP);
   DeleteDC(hCompatDC);
   RestoreDC(hdc, -1);
 
--- a/src/w32bdf.h	Wed Mar 17 11:29:05 1999 +0000
+++ b/src/w32bdf.h	Wed Mar 17 22:03:43 1999 +0000
@@ -29,15 +29,38 @@
 #define BDF_SECOND_OFFSET(x) ((x) & 0x7f)
 #define BDF_FIRST_OFFSET(x) (((x) >> 8) | (((x) & 0x80) << 1))
 
+#define BDF_FONT_CACHE_SIZE 5000
+#define BDF_FONT_CLEAR_SIZE 1000
+
 /* Structure of glyph information of one character.  */
 typedef struct
 {
   int dwidth;			/* width in pixels */
   int bbw, bbh, bbox, bboy;	/* bounding box in pixels */
+} glyph_metric;
+
+typedef struct
+{
+  glyph_metric metric;
   int bitmap_size;		/* byte lengh of the following slots */
   unsigned char *bitmap;	/*  */
 } glyph_struct;
 
+typedef struct fchar *pfont_char;
+
+typedef struct
+{
+  glyph_metric metric;
+  pfont_char psrc;
+  HBITMAP hbmp;
+} cache_bitmap;
+
+typedef struct fchar
+{
+  unsigned char *offset;
+  cache_bitmap *pcbmp;
+} font_char;
+
 typedef struct
 {
   char *filename;
@@ -46,12 +69,19 @@
   unsigned char *font;
   unsigned char *seeked;
   DWORD size;
-  unsigned char **offset[BDF_FIRST_OFFSET_TABLE];
+
+  font_char *chtbl[BDF_FIRST_OFFSET_TABLE];
   int llx, lly, urx, ury;	/* Font bounding box */
 
   int yoffset;
   int relative_compose;
   int default_ascent;
+
+  unsigned char *registry;
+  unsigned char *encoding;
+  unsigned char *slant;
+/*  unsigned char *width; */
+
   int width;
   int height;
   int pixsz;