www.pudn.com > helpview.zip > Fontbuff.c, change:1997-10-15,size:10108b


/* 
  
Copyright 1997 Willows Software, Inc.  
 
This library is free software; you can redistribute it and/or 
modify it under the terms of the GNU Library General Public License as 
published by the Free Software Foundation; either version 2 of the 
License, or (at your option) any later version. 
 
This library is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
Library General Public License for more details. 
 
You should have received a copy of the GNU Library General Public 
License along with this library; see the file COPYING.LIB.  If 
not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
Cambridge, MA 02139, USA. 
 
*/ 
 
/************************************************************************* 
* 
*	FONTBUFF.C 
*   Font creation and buffering routines.      
* 
*	Author: Paul E. Kissel 
* 
**************************************************************************/ 
 
 
/*********************************** 
** 
**  System Includes 
** 
***********************************/ 
 
 
/*********************************** 
** 
**  App. Includes 
** 
***********************************/ 
 
#include "fontbuff.h" 
#include "winmem.h" 
#include "wnddata.h" 
 
 
/*********************************** 
** 
**  Private File Defines 
** 
***********************************/ 
 
typedef struct tagFONTBUFFER 
{ 
  WORD    wNumFonts;  /* Number of fonts in the buffer. */ 
  HGLOBAL hFontInfo;  /* Handle to the first FONTINFO record in the buffer. */ 
}  
FONTBUFFER; 
typedef FONTBUFFER * FPFONTBUFFER; 
 
 
/* Maximum number of fonts held in the buffer. */ 
#define MAX_FONTS  30 
 
typedef struct tagFONTINFO 
{ 
  WORD  wFontNumber;    /* Font index number in FontInfo list. */ 
  HFONT hFont;          /* Handle to the font. */ 
  DWORD dwTickCount;    /* Tickcount when the font was created or last used. */ 
}  
FONTINFO; 
typedef FONTINFO * FPFONTINFO; 
 
 
 
/*********************************************************************************** 
** 
**                              Shared Functions 
** 
************************************************************************************/ 
 
 
/********************************************************* 
** 
**  Allocates the buffer's structure. 
** 
**  Initially, only the first slot is allocated. 
**  It will be used to hold a count of the number of fonts 
**  in the buffer in the dwTickCount variable.  
** 
**********************************************************/ 
HFONTBUFFER AllocFontBuffer( HWND hWnd ) 
{ 
  HFONTBUFFER hFontBuffer; 
  FPFONTBUFFER fpFontBuffer; 
 
  /*  
  ** Allocate the font buffer.  
  */ 
  if( ! GlobalAllocMem( hWnd, &hFontBuffer, sizeof(FONTBUFFER) ) ) 
  { 
    /* Failure. */ 
    return( NULL ); 
  } 
   
  /* Get pointer to the font buffer. */ 
  fpFontBuffer = ( FPFONTBUFFER ) GlobalLock( hFontBuffer ); 
   
  /* Allocate the FONTINFO nodes. */ 
  if( ! GlobalAllocMem( hWnd, &(fpFontBuffer)->hFontInfo, sizeof(FONTINFO) * MAX_FONTS ) ) 
  { 
    /* Unlock the font buffer. */ 
    GlobalUnlock( hFontBuffer ); 
     
    /* Free the font buffer. */ 
    MyGlobalFree( hFontBuffer ); 
     
    /* Failure. */ 
    return( NULL ); 
  } 
   
  /* No fonts in the buffer. */ 
  fpFontBuffer->wNumFonts = 0; 
   
  /* Unlock the font buffer. */ 
  GlobalUnlock( hFontBuffer ); 
 
  /* Success. */ 
  return( hFontBuffer ); 
} 
 
 
 
/********************************************************* 
** 
**  Destroys the fonts in the buffer and frees the 
**  memory associated with the buffer's structure. 
** 
**  NOTE: The function selects the SYSTEM font into the 
**        given HDC so that it can be sure that the fonts  
**        being deleted are not currently selected. 
** 
**********************************************************/ 
void  FreeFontBuffer( HWND hWnd, HFONTBUFFER hFontBuffer ) 
{ 
  FPFONTBUFFER fpFontBuffer; 
 
  /* No font buffer.  */ 
  if( hFontBuffer == NULL ) return; 
   
  /* Destroy the fonts in the buffer. */ 
  ClearFontBuffer( hWnd, hFontBuffer ); 
 
  /* Get pointer to the font buffer. */ 
  fpFontBuffer = ( FPFONTBUFFER ) GlobalLock( hFontBuffer ); 
   
  /* Free the font info area. */ 
  MyGlobalFree( fpFontBuffer->hFontInfo ); 
 
  /* Unlock the font buffer. */ 
  GlobalUnlock( hFontBuffer ); 
     
  /* Free the buffer. */ 
  MyGlobalFree( hFontBuffer ); 
} 
 
 
 
/********************************************************* 
** 
**  Destroys the fonts in the buffer. 
** 
**  NOTE: The function selects the SYSTEM font into the 
**        given HDC so that it can be sure that the fonts  
**        being deleted are not currently selected. 
** 
**********************************************************/ 
void ClearFontBuffer( HWND hWnd, HFONTBUFFER hFontBuffer ) 
{ 
  FPFONTBUFFER fpFontBuffer; 
  FPFONTINFO   fpFontInfo; 
  WORD         wIndex; 
  HDC          hDC; 
 
 
  /* No font buffer.  */ 
  if( hFontBuffer == NULL ) return; 
   
  /* Get pointer to the font buffer. */ 
  fpFontBuffer = ( FPFONTBUFFER ) GlobalLock( hFontBuffer ); 
   
  /* If there are fonts in the buffer. */ 
  if( fpFontBuffer->wNumFonts != 0 ) 
  { 
    /* Get pointer to the first font. */ 
    fpFontInfo = ( FPFONTINFO ) GlobalLock( fpFontBuffer->hFontInfo ); 
     
    /* Make sure none of the fonts in the font buffer are selected. */ 
    hDC = GetDC( hWnd ); 
    SelectObject( hDC, GetStockObject( SYSTEM_FONT ) );  
    ReleaseDC( hWnd, hDC ); 
 
    /* Destroy all fonts in the buffer. */ 
    for( wIndex = 0; wIndex < fpFontBuffer->wNumFonts; wIndex++ ) 
    { 
      /* Free the font. */ 
      DeleteObject( fpFontInfo->hFont ); 
             
      /* Goto next node. */ 
      fpFontInfo++; 
    } 
 
    /* Unlock the font info. */ 
    GlobalUnlock( fpFontBuffer->hFontInfo ); 
 
    /* No fonts in the buffer. */ 
    fpFontBuffer->wNumFonts = 0; 
   
  } 
   
  /* Unlock the font buffer. */ 
  GlobalUnlock( hFontBuffer ); 
} 
 
 
/********************************************************* 
** 
**  Adds a new font to the buffer. 
** 
**  If no space is available, the least used font is  
**  replaced. 
** 
**  NOTE: If an existing font is being replaced,  
**        the function selects the SYSTEM font into the 
**        given HDC so that it can be sure that the font  
**        being deleted is not currently selected. 
** 
**********************************************************/ 
BOOL AddFont( HWND hWnd, HFONTBUFFER hFontBuffer, HFONT hFont, WORD wFontNumber ) 
{ 
  FPFONTBUFFER fpFontBuffer; 
  FPFONTINFO   fpFontInfo,  
               fpFontLeastUsed; 
  WORD         wIndex; 
  HDC          hDC; 
    
 
  /* No font buffer.  */ 
  if( hFontBuffer == NULL ) return FALSE; 
   
  /* Get pointer to the font buffer. */ 
  fpFontBuffer = ( FPFONTBUFFER ) GlobalLock( hFontBuffer ); 
   
  /* Get pointer to the first font info node. */ 
  fpFontInfo = GlobalLock( fpFontBuffer->hFontInfo ); 
 
  /* If we haven't reached - add space for the new font to the buffer. */ 
  if( fpFontBuffer->wNumFonts < MAX_FONTS ) 
  { 
    /* Skip to the next unused slot.*/ 
    fpFontInfo = fpFontInfo + fpFontBuffer->wNumFonts; 
 
    /*  
    ** Increment the count of how many fonts are 
    ** in the font buffer. 
    */ 
    fpFontBuffer->wNumFonts = fpFontBuffer->wNumFonts + 1; 
  } 
 
 
  /* We've reached maximum buffer space. */ 
  else 
  { 
    /* 1st font will be replaced. */ 
    fpFontLeastUsed = fpFontInfo; 
     
    /* Find the font that hasn't been used for the longest time. */ 
    for( wIndex = 0; wIndex < fpFontBuffer->wNumFonts; wIndex++ ) 
    { 
      /* Last time font used. */ 
      if( fpFontInfo->dwTickCount < fpFontLeastUsed->dwTickCount )  
      { 
        /* New replacement font. */ 
        fpFontLeastUsed = fpFontInfo; 
      } 
           
      /* Goto next node. */ 
      fpFontInfo++; 
    } 
   
    /* Make sure the font is not selected. */ 
    hDC = GetDC( hWnd ); 
    SelectObject( hDC, GetStockObject( SYSTEM_FONT ) );  
    ReleaseDC( hWnd, hDC ); 
 
    /* Free the least used font. */ 
    DeleteObject( fpFontInfo->hFont ); 
     
    /* Point to the least used slot. */ 
    fpFontInfo = fpFontLeastUsed; 
  } 
 
  /* Modify the data. */ 
  fpFontInfo->wFontNumber  = wFontNumber;  
  fpFontInfo->hFont        = hFont; 
  fpFontInfo->dwTickCount  = GetTickCount();  
 
  /* Unlock the font info. */ 
  GlobalUnlock( fpFontBuffer->hFontInfo ); 
   
  /* Unlock the font buffer. */ 
  GlobalUnlock( hFontBuffer ); 
 
  /* Success. */ 
  return( TRUE ); 
} 
 
 
 
/********************************************************* 
** 
**  Finds a font in the buffer that has the given  
**  wFontNumber. 
** 
**********************************************************/ 
HFONT  FindFont( HFONTBUFFER hFontBuffer, WORD wFontNumber ) 
{ 
  FPFONTBUFFER fpFontBuffer; 
  FPFONTINFO   fpFontInfo; 
  WORD         wIndex; 
  HFONT        hFont = NULL; 
   
 
  /* No font buffer.  */ 
  if( hFontBuffer == NULL ) return NULL; 
   
  /* Get pointer to the font buffer. */ 
  fpFontBuffer = ( FPFONTBUFFER ) GlobalLock( hFontBuffer ); 
   
  /* If there are fonts in the buffer. */ 
  if( fpFontBuffer->wNumFonts != 0 ) 
  { 
    /* Get pointer to the first font info node. */ 
    fpFontInfo = ( FPFONTINFO ) GlobalLock( fpFontBuffer->hFontInfo ); 
     
    /* Find a font in the buffer with the attributres. */ 
    for( wIndex = 0; wIndex < fpFontBuffer->wNumFonts; wIndex++ ) 
    { 
      /* Found font? */ 
      if( fpFontInfo->wFontNumber == wFontNumber ) 
      { 
        /* Save font's handle. */ 
        hFont = fpFontInfo->hFont; 
 
        /* Update the usage info. */ 
        fpFontInfo->dwTickCount = GetTickCount(); 
         
        break; 
      } 
             
      /* Goto next node. */ 
      fpFontInfo++; 
    } 
 
    /* Unlock the font info. */ 
    GlobalUnlock( fpFontBuffer->hFontInfo ); 
  } 
   
  /* Unlock the font buffer. */ 
  GlobalUnlock( hFontBuffer ); 
 
  /* Failure. */ 
  return( hFont ); 
}