[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]

[MD:826]BDF font manager



椿本@シセン堂です。

 古いスレッドへのレスでごめんなさい。^_^;

In message "[MD:802]BDF font manager"
    <u90llxbp8.fsf@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> on 98/07/23,
    Miyashita Hisashi(宮下 尚:HIMI) <himi@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
> 
> このぶんだと、CreateDIBSectionパッチも出来上がるのもすぐかな。^^;;;
> 

 全然「すぐ」じゃ無くなりましたが作ってみました。
 元のhimiさんのmw32bdf.h, mw32bdf.cに対するパッチになってます。

 色々試したのですが、ほとんど速くはなりませんでした。
(遅くもなっていませんが...。^_^;;)

# 根本的にやり方が間違ってるのかしら?

 で、特に速くもなっていないパッチですが、ビットマップを直接キャッシュ
しない様になってますので、システムリソースの消費が少ない点だけは有効か
と思います。特にWin95では。

# 「参考出品」程度に考えて下さい。^_^;;;
# 少しでも速くしようとしてゴチャゴチャしたものになってしまいました。

----------------v-------------ここから-------------v---------------
*** mw32bdf.h.orig	Fri Jul 17 01:39:14 1998
--- mw32bdf.h	Tue Aug 04 15:20:40 1998
***************
*** 30,36 ****
  {
    glyph_metric metric;
    pfont_char psrc;
!   HBITMAP hbmp;
  }cache_bitmap;
  
  typedef struct fchar
--- 30,36 ----
  {
    glyph_metric metric;
    pfont_char psrc;
!   unsigned char *pbmp;
  }cache_bitmap;
  
  typedef struct fchar
*** mw32bdf.c.orig	Fri Jul 17 02:26:06 1998
--- mw32bdf.c	Wed Aug 12 15:13:48 1998
***************
*** 46,52 ****
    if (!p) return -1;
    for (;start < p;start++)
      {
!       if ((*start != ' ') || (*start != '\t')) break;
      }
    linelen = p - start + 1;
    *next = p + 1;
--- 46,52 ----
    if (!p) return -1;
    for (;start < p;start++)
      {
!       if ((*start != ' ') && (*start != '\t')) break;
      }
    linelen = p - start + 1;
    *next = p + 1;
***************
*** 276,282 ****
  	  for (j = 0;j < BDF_SECOND_OFFSET_TABLE;j++)
  	    {
  	      pcb = pch[j].pcbmp;
! 	      if (pcb) pcb->psrc = NULL;
  	    }
  	  xfree(pch);
  	}
--- 276,287 ----
  	  for (j = 0;j < BDF_SECOND_OFFSET_TABLE;j++)
  	    {
  	      pcb = pch[j].pcbmp;
! 	      if (pcb)
! 		{
! 		  if (pcb->pbmp)
! 		    xfree(pcb->pbmp);
! 		  pcb->psrc = NULL;
! 		}
  	    }
  	  xfree(pch);
  	}
***************
*** 409,415 ****
      {
        if (p->psrc)
  	{
! 	  DeleteObject(p->hbmp);
  	  p->psrc->pcbmp = NULL;
  	  p->psrc = NULL;
  	}
--- 414,421 ----
      {
        if (p->psrc)
  	{
! 	  if (p->pbmp)
! 	    xfree(p->pbmp);
  	  p->psrc->pcbmp = NULL;
  	  p->psrc = NULL;
  	}
***************
*** 490,502 ****
  	  p++;
  	  size--;
  	  if (size <= 0) return 0;
! 	  /* NAND Operation.  */
! 	  *bitmapp++ = (unsigned char)~((val1 << 4) | val2);
! 	}
!       /* CreateBitmap requires WORD alignment.  */
!       if (j % 2)
! 	{
! 	  *bitmapp++ = 0xff;
  	}
        p = q + 1;
      }
--- 496,502 ----
  	  p++;
  	  size--;
  	  if (size <= 0) return 0;
! 	  *bitmapp++ = (unsigned char)((val1 << 4) | val2);
  	}
        p = q + 1;
      }
***************
*** 510,518 ****
  {
    int bitmap_size;
    font_char *pch;
!   cache_bitmap* pcb;
!   HBITMAP hbmp;
    glyph_struct glyph;
  
    pch = get_cached_font_char(fontp, index);
    if (pch)
--- 510,520 ----
  {
    int bitmap_size;
    font_char *pch;
!   cache_bitmap *pcb;
!   unsigned char *pbmp = NULL;
    glyph_struct glyph;
+   int count;
+   unsigned char *p;
  
    pch = get_cached_font_char(fontp, index);
    if (pch)
***************
*** 531,537 ****
    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)
--- 533,547 ----
    pch = get_cached_font_char(fontp, index);
    if (!pch) return NULL;
  
!   bitmap_size = ((glyph.metric.bbw + 7) >> 3) * glyph.metric.bbh;
!   p = glyph.bitmap;
!   for (count = bitmap_size; count--;)
!     if (*p++) break;
!   if (count >= 0)
!     {
!       pbmp = (unsigned char*) xmalloc(bitmap_size);
!       memcpy(pbmp, glyph.bitmap, bitmap_size);
!     }
  
    pcb = pcached_bitmap_latest;
    if (pcb->psrc)
***************
*** 539,548 ****
  
    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;
--- 549,558 ----
  
    pcb->psrc = pch;
    pcb->metric = glyph.metric;
!   pcb->pbmp = pbmp;
  
    pch->pcbmp = pcb;
! 
    pcached_bitmap_latest++;
    if (FONT_CACHE_SLOT_OVER_P(pcached_bitmap_latest))
      pcached_bitmap_latest = cached_bitmap_slots;
***************
*** 550,636 ****
    return pcb;
  }
  
  int
  mw32_BDF_TextOut(bdffont *fontp, HDC hdc, int left,
  		 int top, unsigned char *text, int dim, int bytelen,
  		 int fixed_pitch_size)
  {
!   int index, btop;
!   unsigned char *textp;
    HDC hCompatDC = 0;
    cache_bitmap *pcb;
    HBITMAP hBMP;
    HBRUSH hFgBrush, hOrgBrush;
!   HANDLE horgobj = 0;
    UINT textalign;
!   int flag = 0;
  
!   hCompatDC = CreateCompatibleDC(hdc);
  
    textalign = GetTextAlign(hdc);
-   
-   SaveDC(hdc);
- 
-   hFgBrush = CreateSolidBrush(GetTextColor(hdc));
-   hOrgBrush = SelectObject(hdc, hFgBrush);
-   SetTextColor(hdc, RGB(0, 0, 0));
-   SetBkColor(hdc, RGB(0xff, 0xff, 0xff));
  
!   textp = text;
!   while(bytelen > 0)
      {
!       if (dim == 1)
  	{
! 	  index = *textp++;
! 	  bytelen--;
  	}
        else
  	{
! 	  bytelen -= 2;
! 	  if (bytelen < 0) break;
! 	  index = MAKELENDSHORT(textp[1], textp[0]);
! 	  textp += 2;
! 	}
!       pcb = get_bitmap_with_cache(fontp, index);
!       if (!pcb)
! 	{
! 	  if (horgobj)
  	    {
- 	      SelectObject(hCompatDC, horgobj);
  	      DeleteObject(hBMP);
  	    }
! 	  DeleteDC(hCompatDC);
! 	  return 0;
  	}
-       hBMP = pcb->hbmp;
  
        if (textalign & TA_BASELINE)
! 	btop = top - (pcb->metric.bbh + pcb->metric.bboy);
        else if (textalign & TA_BOTTOM)
! 	btop = top - pcb->metric.bbh;
        else
! 	btop = top;
  
!       if (horgobj)
! 	SelectObject(hCompatDC, hBMP);
!       else
! 	horgobj = SelectObject(hCompatDC, hBMP);
! #if 0
!       BitBlt(hdc, left, btop, pcb->metric.bbw, pcb->metric.bbh, hCompatDC, 0, 0, SRCCOPY);
! #else
!       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 += pcb->metric.dwidth;
      }
  
-   SelectObject(hCompatDC, horgobj);
    SelectObject(hdc, hOrgBrush);
    DeleteObject(hFgBrush);
    DeleteDC(hCompatDC);
-   RestoreDC(hdc, -1);
  
    return 1;
  }
--- 560,770 ----
    return pcb;
  }
  
+ static HBITMAP
+ create_offscreen_bitmap(HDC hdc, int width, int height, unsigned char **bitsp)
+ {
+   HBITMAP hBMP;
+   struct {
+     BITMAPINFOHEADER h;
+     RGBQUAD c[2];
+   } info;
+ 
+   memset(&info, 0, sizeof(info));
+   info.h.biSize = sizeof(BITMAPINFOHEADER);
+   info.h.biWidth = width;
+   info.h.biHeight = -height;
+   info.h.biPlanes = 1;
+   info.h.biBitCount = 1;
+   info.h.biCompression = BI_RGB;
+   info.c[1].rgbRed = info.c[1].rgbGreen = info.c[1].rgbBlue = 255;
+ 
+   return CreateDIBSection(hdc, (LPBITMAPINFO)&info,
+ 			  DIB_RGB_COLORS, bitsp, NULL, 0);
+ }
+ 
  int
  mw32_BDF_TextOut(bdffont *fontp, HDC hdc, int left,
  		 int top, unsigned char *text, int dim, int bytelen,
  		 int fixed_pitch_size)
  {
!   int index, btop, bleft;
    HDC hCompatDC = 0;
    cache_bitmap *pcb;
    HBITMAP hBMP;
    HBRUSH hFgBrush, hOrgBrush;
!   HANDLE horgobj;
    UINT textalign;
!   int width, height;
!   unsigned char *bits, *srcbp, *dstbp;
!   int rowBytes, cwb, cw, ch;
  
!   if (bytelen <= 0) return 1;
  
    textalign = GetTextAlign(hdc);
  
!   if (dim == bytelen)
      {
!       index = (dim == 1 ? *text : MAKELENDSHORT(text[1], text[0]));
!       pcb = get_bitmap_with_cache(fontp, index);
!       if (!pcb) return 0;
!       if (!pcb->pbmp) return 1;
! 
!       width = pcb->metric.bbw;
!       height = pcb->metric.bbh;
!       hBMP = create_offscreen_bitmap(hdc, width, height, &bits);
!       if (!hBMP) return 0;
! 
!       rowBytes = ((width + 31) >> 3) & ~3;
!       cwb = (pcb->metric.bbw + 7) >> 3;
! 
!       dstbp = bits;
!       srcbp = pcb->pbmp;
!       for (ch = pcb->metric.bbh; ch--;)
  	{
! 	  for (cw = cwb; cw--;)
! 	    *dstbp++ = *srcbp++;
! 	  dstbp += rowBytes - cwb;
  	}
+ 
+       if (textalign & TA_BASELINE)
+ 	top -= pcb->metric.bbh + pcb->metric.bboy;
+       else if (textalign & TA_BOTTOM)
+ 	top -= pcb->metric.bbh + pcb->metric.bboy - fontp->lly;
        else
+ 	top -= pcb->metric.bbh + pcb->metric.bboy - fontp->ury;
+       left += pcb->metric.bbox - fontp->llx;
+       btop = bleft = 0;
+     }
+   else
+     {
+       int orgx, orgy, x, y, cx, cy;
+       int bright, bbottom;
+       int shift;
+ 
+       width = (fixed_pitch_size ? fixed_pitch_size : fontp->urx - fontp->llx)
+ 	* (bytelen / dim) + (fontp->urx - fontp->llx) * 2;
+       height = (fontp->ury - fontp->lly) * 2;
+       hBMP = create_offscreen_bitmap(hdc, width, height, &bits);
+       if (!hBMP) return 0;
+ 
+       rowBytes = ((width + 31) >> 3) & ~3;
+       memset(bits, 0, height * rowBytes);
+       orgx = (fontp->urx - fontp->llx) - fontp->llx;
+       orgy = height / 4 + fontp->ury;
+ 
+       bleft = width;
+       bright = 0;
+       btop = height;
+       bbottom = 0;
+ 
+       while(bytelen > 0)
  	{
! 	  if (dim == 1)
! 	    {
! 	      index = *text++;
! 	      bytelen--;
! 	    }
! 	  else
! 	    {
! 	      bytelen -= 2;
! 	      if (bytelen < 0) break;
! 	      index = MAKELENDSHORT(text[1], text[0]);
! 	      text += 2;
! 	    }
! 	  pcb = get_bitmap_with_cache(fontp, index);
! 	  if (!pcb)
  	    {
  	      DeleteObject(hBMP);
+ 	      return 0;
+ 	    }
+ 
+ 	  if (pcb->pbmp)
+ 	    {
+ 	      x = orgx + pcb->metric.bbox;
+ 	      y = orgy - (pcb->metric.bboy + pcb->metric.bbh);
+ 	      cx = x + pcb->metric.bbw;
+ 	      cy = y + pcb->metric.bbh;
+ 	      if (x >= 0 && y >= 0 && cx <= width && cy <= height)
+ 		{
+ 		  if (x < bleft) bleft = x;
+ 		  if (cx > bright) bright = cx;
+ 		  if (y < btop) btop = y;
+ 		  if (cy > bbottom) bbottom = cy;
+ 
+ 		  cwb = (pcb->metric.bbw + 7) >> 3;
+ 		  dstbp = bits + y * rowBytes + (x >> 3);
+ 		  srcbp = pcb->pbmp;
+ 		  shift = 8 - (x & 7);
+ 		  if (shift < 8)
+ 		    {
+ 		      for (ch = pcb->metric.bbh; ch--;)
+ 			{
+ 			  int dots = 0;
+ 			  for (cw = cwb; cw--;)
+ 			    {
+ 			      dots = (dots << 8) | (*srcbp++ << shift);
+ 			      *dstbp++ |= (unsigned char)(dots >> 8);
+ 			    }
+ 			  *dstbp |= (unsigned char)dots;
+ 			  dstbp += rowBytes - cwb;
+ 			}
+ 		    }
+ 		  else
+ 		    {
+ 		      for (ch = pcb->metric.bbh; ch--;)
+ 			{
+ 			  for (cw = cwb; cw--;)
+ 			    *dstbp++ |= (unsigned char)*srcbp++;
+ 			  dstbp += rowBytes - cwb;
+ 			}
+ 		    }
+ 		}
  	    }
! 	  if (fixed_pitch_size)
! 	    orgx += fixed_pitch_size;
! 	  else
! 	    orgx += pcb->metric.dwidth;
! 	}
!       if (bleft >= bright || btop >= bbottom)
! 	{
! 	  DeleteObject(hBMP);
! 	  return 1;
  	}
  
        if (textalign & TA_BASELINE)
! 	top -= height / 4 + fontp->ury - btop;
        else if (textalign & TA_BOTTOM)
! 	top -= height / 4 + fontp->ury - fontp->lly - btop;
        else
! 	top -= height / 4 - btop;
!       left -= (fontp->urx - fontp->llx) - bleft;
!       width = bright - bleft;
!       height = bbottom - btop;
!     }
  
!   hCompatDC = CreateCompatibleDC(hdc);
!   if (!hCompatDC)
!     {
!       DeleteObject(hBMP);
!       return 0;
!     }
!   hFgBrush = CreateSolidBrush(GetTextColor(hdc));
!   if (!hFgBrush)
!     {
!       DeleteDC(hCompatDC);
!       DeleteObject(hBMP);
!       return 0;
      }
+   hOrgBrush = SelectObject(hdc, hFgBrush);
+   horgobj = SelectObject(hCompatDC, hBMP);
+ 
+   BitBlt(hdc, left, top, width, height, hCompatDC, bleft, btop, 0xE20746);
  
    SelectObject(hdc, hOrgBrush);
    DeleteObject(hFgBrush);
+   SelectObject(hCompatDC, horgobj);
+   DeleteObject(hBMP);
    DeleteDC(hCompatDC);
  
    return 1;
  }
----------------^-------------ここまで-------------^---------------
-- 
椿本 浩也 (Hiroya Tsubakimoto)
Office: <zorac@xxxxxxxxxxxx> 有限会社シセン堂
Home: <zorac@xxxxxxxxxxxxxxxxxxxxx>