⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udbmffnt.c

📁 S1D13506windml下的驱动程序,支持vxworks5.4 支持tornado2.0 windml2.0
💻 C
📖 第 1 页 / 共 3 页
字号:
/* udbmffnt.c - Bitmapped Monochrome Font (BMF) driver for UGL */

/* Copyright 2000 Wind River Systems, Inc. All Rights Reserved */

/*
modification history
--------------------
01g,20nov00,msr  Fixed bug with drawing glyph from page that doesn't exist.
01f,10nov00,rfm  Fixed pageZero reference
01e,10nov00,jlb  Change INCLUDE_UGL_BMF_UNICODE to INCLUDE_UGL_UNICODE
01d,23oct00,msr  Fixed fontFindFisrt()/Next() to be re-entrant.
01c,15sep00,rfm  Fixed SPR #34479
01b,06sep00,rbp  Modifications for refgen added.
01a,11feb00,rfm  Created
*/

/* 

DESCRIPTION

The Bitmapped Monochrome Font (BMF) driver is contained in this file.

NOMANUAL

*/

/* includes */
#define BUILD_DRIVER
#include <ugl/driver/font/udbmffnt.h>
#include <ugl/uglmem.h>
#include <string.h>

/* Local funtion prototypes */
UGL_LOCAL UGL_STATUS uglBMFFontDriverDestroy (UGL_FONT_DRIVER * pFontDriver);
UGL_LOCAL UGL_FONT * uglBMFFontCreate (UGL_FONT_DRIVER * pFontDriver,
				       UGL_FONT_DEF * pFontDefinition);
UGL_LOCAL UGL_STATUS uglBMFFontDestroy (UGL_FONT * pFont);
UGL_LOCAL UGL_SEARCH_ID uglBMFFontFindFirst (UGL_FONT_DRIVER * pFontDriver, 
					     UGL_FONT_DESC * pFontDescriptor);
UGL_LOCAL UGL_STATUS uglBMFFontFindNext (UGL_FONT_DRIVER * pFontDriver, 
					UGL_FONT_DESC * pFontDescriptor, 
					UGL_SEARCH_ID searchId);
UGL_LOCAL UGL_STATUS uglBMFFontFindClose (UGL_FONT_DRIVER * pFontDriver, 
					  UGL_SEARCH_ID searchId);
UGL_LOCAL UGL_STATUS uglBMFFontDriverInfo (UGL_FONT_DRIVER * pFontDriver, 
					   UGL_INFO_REQ infoRequest, 
					   void * pInfo);
UGL_LOCAL UGL_STATUS uglBMFFontMetricsGet (UGL_FONT * pFont,
					   UGL_FONT_METRICS * pFontMetrics);
UGL_LOCAL UGL_STATUS uglBMFFontRotationAngleSet (UGL_FONT * pFont, 
						 UGL_ORD angle);
UGL_LOCAL UGL_STATUS uglBMFFontSizeSet (UGL_FONT * pFont, 
					UGL_SIZE size);
UGL_LOCAL UGL_STATUS uglBMFFontWeightSet (UGL_FONT * pFont, 
					  UGL_SIZE weight);
UGL_LOCAL UGL_STATUS uglBMFTextDraw (UGL_GC * pGc, UGL_POS x, UGL_POS y,
				     UGL_SIZE length, const UGL_CHAR * text);
UGL_LOCAL UGL_STATUS uglBMFTextSizeGet (UGL_FONT * pFont, UGL_SIZE * pWidth,
					UGL_SIZE * pHeight, UGL_SIZE length,
					const UGL_CHAR *text);
#ifdef INCLUDE_UGL_UNICODE
UGL_LOCAL UGL_STATUS uglBMFTextDrawW (UGL_GC * pGc, UGL_POS x, UGL_POS y,
				      UGL_SIZE length, const UGL_WCHAR * text);
UGL_LOCAL UGL_STATUS uglBMFTextSizeGetW (UGL_FONT * pFont, UGL_SIZE * pWidth, 
					 UGL_SIZE * pHeight, UGL_SIZE length,
					 const UGL_WCHAR *text);
#endif /* INCLUDE_UGL_UNICODE */

UGL_LOCAL UGL_GLYPH_CACHE_ELEMENT * 
    uglBMFGlyphCacheAlloc (UGL_FONT_DRIVER * pFontDriver, 
			   void ** pPageElement);
UGL_LOCAL void uglBMFGlyphCacheFree(UGL_FONT_DRIVER * pFontDriver, 
				 void ** pPageElement);

/* This global is declared in the UGL configuration file */
extern const UGL_BMF_FONT_DESC * uglBMFFontData[];

UGL_LOCAL UGL_BOOL uglBMFCacheConfig = UGL_FALSE;

/*******************************************************************************
* uglBMFFontDriverCreate - create the BMF font driver
*
* This function creates a BMF driver that interfaces with UGL font APIs.
*
* RETURNS: Identifier for the created font driver, if successful. Otherwise 
*          UGL_NULL when the driver cannot be created.
*
* SEE ALSO: 
*
*/

UGL_FONT_DRIVER * uglBMFFontDriverCreate
    (
    UGL_UGI_DRIVER * pDriver 
    )
    {
    UGL_BMF_FONT_DRIVER * pBMFFontDriver = UGL_NULL;
    UGL_FONT_DRIVER * pFontDriver = UGL_NULL;
    UGL_SIZE numFonts;

    /* Verify that fonts are available */
    if (uglBMFFontData == UGL_NULL) 
	{
	return(UGL_NULL);
	}

    /* Count the number of available fonts */
    for(numFonts = 0; UGL_NULL != uglBMFFontData[numFonts]; numFonts++);

    /* If there are no fonts available, return */
    if (numFonts == 0) 
	{
	return(UGL_NULL);
	}

    pBMFFontDriver = 
	(UGL_BMF_FONT_DRIVER *)UGL_CALLOC(1, sizeof(UGL_BMF_FONT_DRIVER));
					  

    if (UGL_NULL != pBMFFontDriver) 
	{
	pFontDriver = (UGL_FONT_DRIVER *)pBMFFontDriver;

	pFontDriver->fontCreate 	= uglBMFFontCreate;
	pFontDriver->fontDestroy 	= uglBMFFontDestroy;
	pFontDriver->fontDriverDestroy 	= uglBMFFontDriverDestroy;
	pFontDriver->fontFindFirst	= uglBMFFontFindFirst;
	pFontDriver->fontFindNext	= uglBMFFontFindNext;
	pFontDriver->fontFindClose	= uglBMFFontFindClose;
	pFontDriver->fontDriverInfo	= uglBMFFontDriverInfo;
	pFontDriver->fontMetricsGet 	= uglBMFFontMetricsGet;
	pFontDriver->fontRotationAngleSet = uglBMFFontRotationAngleSet;
	pFontDriver->fontSizeSet	= uglBMFFontSizeSet;
	pFontDriver->fontWeightSet	= uglBMFFontWeightSet;
	pFontDriver->textDraw		= uglBMFTextDraw;
	pFontDriver->textSizeGet	= uglBMFTextSizeGet;
#ifdef INCLUDE_UGL_UNICODE
	pFontDriver->textDrawW		= uglBMFTextDrawW;
	pFontDriver->textSizeGetW 	= uglBMFTextSizeGetW;
#endif /* INCLUDE_UGL_UNICODE */
	pFontDriver->pDriver 		= pDriver;
	pBMFFontDriver->lockId 		= uglOSLockCreate ();
	pBMFFontDriver->textOrigin 	= UGL_FONT_TEXT_BASELINE;
	pBMFFontDriver->pFirstFont	= UGL_NULL;
	pBMFFontDriver->pLastFont	= UGL_NULL;
	pBMFFontDriver->glyphCacheSize	= UGL_BMF_GLYPH_CACHE_SIZE_MAX;
	pBMFFontDriver->glyphCachePoolId= UGL_DEFAULT_MEM_POOL_ID;
	}

    return ((UGL_FONT_DRIVER *)pBMFFontDriver);
    }

/***************************************************************************
*
* uglBMFFontCreate - create a font 
*
* NOMANUAL
*
*/

UGL_LOCAL UGL_FONT * uglBMFFontCreate
    (
    UGL_FONT_DRIVER * pFontDriver,
    UGL_FONT_DEF * pFontDefinition
    )
    {
    UGL_FONT * pFont = UGL_NULL;
    UGL_BMF_FONT * pBMFFont;
    UGL_BMF_FONT_DRIVER * pBMFFontDriver = 
	(UGL_BMF_FONT_DRIVER *)pFontDriver;
    int i;

    /* Make sure font hasn't all ready been created */
    uglOSLock(pBMFFontDriver->lockId);
    pBMFFont = pBMFFontDriver->pFirstFont;

    if (UGL_NULL != pBMFFont) 
	{
	for(pFont = (UGL_FONT *)pBMFFont; UGL_NULL != pFont;
	    pFont = (UGL_FONT *)pBMFFont = pBMFFont->pNextFont)
	    {
	    /* Find only an exact match */
	    if((pFontDefinition->structSize == sizeof(UGL_FONT_DEF))
	       && (pFontDefinition->pixelSize == pBMFFont->pBMFFontDesc->header.pixelSize.min)
	       && (pFontDefinition->weight == pBMFFont->pBMFFontDesc->header.weight.min)
	       && (pFontDefinition->italic == pBMFFont->pBMFFontDesc->header.italic)
	       && (pFontDefinition->charSet == pBMFFont->pBMFFontDesc->header.charSet)
	       && !strncmp(pFontDefinition->faceName, 
			   pBMFFont->pBMFFontDesc->header.faceName,
			   UGL_FONT_FACE_NAME_MAX_LENGTH - 1)
	       && !strncmp(pFontDefinition->familyName, 
			   pBMFFont->pBMFFontDesc->header.familyName, 
			   UGL_FONT_FAMILY_NAME_MAX_LENGTH - 1))
		{
		pBMFFont = (UGL_BMF_FONT *)pFont;
		pBMFFont->referenceCount++;
		uglOSUnlock(pBMFFontDriver->lockId);
		return((UGL_FONT *)pBMFFont);
		}
	    }
	}

    /* Hasn't been created yet, need to create it */
    pBMFFont = (UGL_BMF_FONT *)UGL_CALLOC(1, sizeof(UGL_BMF_FONT));

    if (UGL_NULL != pBMFFont) 
	{
	int pageIndex = 0;

	pFont = (UGL_FONT *)pBMFFont;

	/* Look at each font in the uglBMFFontData array to find a match */
	for(i = 0; UGL_NULL != uglBMFFontData[i]; i++)
	    {
	    /* Find only an exact match */
	    if (pFontDefinition->structSize == sizeof(UGL_FONT_DEF)
		&& uglBMFFontData[i]->header.pixelSize.min == 
		    pFontDefinition->pixelSize
		&& uglBMFFontData[i]->header.weight.min == 
		    pFontDefinition->weight
		&& uglBMFFontData[i]->header.italic == 
		    pFontDefinition->italic
		&& uglBMFFontData[i]->header.charSet == 
		    pFontDefinition->charSet
		&& !strncmp(uglBMFFontData[i]->header.faceName, 
			    pFontDefinition->faceName,
			    UGL_FONT_FACE_NAME_MAX_LENGTH - 1) 
		&& !strncmp(uglBMFFontData[i]->header.familyName, 
			    pFontDefinition->familyName,
			    UGL_FONT_FAMILY_NAME_MAX_LENGTH - 1)) 
		{
		pBMFFont->pBMFFontDesc = uglBMFFontData[i];
		pFont->pFontDriver = pFontDriver;
		pBMFFont->referenceCount = 1;
#ifdef INCLUDE_UGL_UNICODE
		/*
				       ------
				|----->|    |
				|      ------
		------          |      |    |
		|    | ----------      ------
		------                   ...
		|    |		       ------
		------		       |    |
		  ...		       ------
		------			pageZero
		|    |
		------
		pageTable
		
		A "page" and a "pageTable" are both arrays of 256
		void pointers. Thus, you can have up to 256 glyphs per
		page (each glyph in a page is pointed to by an entry in
		the page) and up to 256 pages (each page is
		pointed to by an entry in the pageTable).
		*/
		pBMFFont->pageTable[0] = &pBMFFont->pageZero;
#endif	/* INCLUDE_UGL_UNICODE */

		/* Map each glyph in each page */
		while (UGL_NULL != uglBMFFontData[i]->pageData[pageIndex])
		    {
		    /* Get the pointer to the page */
		    const UGL_UINT8 *pageData = 
			uglBMFFontData[i]->pageData[pageIndex];

		    UGL_FOREVER
			{
			UGL_UINT32 size = 0;
			int page;
			int offset;
		    
			/* page and pageIndex do not have to
			   be equal. pageIndex is simply the index
			   into the pageData array, while page
			   could be discontinuous between  pages.
			   For example, a pageIndex of 1 could 
			   actually coorespond to data from page
			   100. */
			page = *(pageData++); 
			/* offset = encoding */
			offset = *(pageData++);

			/* Read size of glyph data */	
			size = *(pageData++) << 8;
			size += *pageData;

			/* Test for end of data */
			if (size == 0)
			    break;

			/* Save the glyph location. */
#ifdef INCLUDE_UGL_UNICODE
			/* Allocate the page if it isn't allocated yet. 
			   Make sure the proper entry in the page table
			   points to the newly created page */
			if (UGL_NULL == pBMFFont->pageTable[page])
			    {
			    pBMFFont->pageTable[page] = 
				(UGL_FONT_PAGE *)UGL_CALLOC(1, sizeof(UGL_FONT_PAGE));
			    }

			/* Point the entry in the page cooresponding 
			   to the offset (ie. encoding) at the glyph data 
			   (The glyph data is not cached. It could still
			   be in ROM) */
			if (UGL_NULL != pBMFFont->pageTable[page])
			    {
			    (*pBMFFont->pageTable[page])[offset] = 
				(UGL_UINT8 *) pageData;
			    }
#else /* INCLUDE_UGL_UNICODE */
			/* Non-Unicode data only requires page zero,
			   thus, no page table is necessary. */
			if (page == 0)
			    {
			    pBMFFont->pageZero[offset] = (UGL_UINT8 *)pageData;
			    }
#endif /* INCLUDE_UGL_UNICODE */
			/* Advance pageData to the next glyph */
			pageData += size;
			}

		    /* Advance pageIndex to point at the next array of
		       glyphs */ 
		    pageIndex++;
		    }

		/* Add the newly font to the list of available fonts */
		if (pBMFFontDriver->pFirstFont)
		    {
		    /* Append it to the end of the list */
		    pBMFFont->pPrevFont = pBMFFontDriver->pLastFont;
		    pBMFFontDriver->pLastFont->pNextFont = pBMFFont;
		    pBMFFontDriver->pLastFont = pBMFFont;
		    }
		else
		    {
		    pBMFFontDriver->pFirstFont = 
			pBMFFontDriver->pLastFont = pBMFFont;
		    }

		uglOSUnlock(pBMFFontDriver->lockId);
		return((UGL_FONT *)pBMFFont);
		}
	    }
	}
    uglOSUnlock(pBMFFontDriver->lockId);
    return(UGL_NULL);
    }

/***************************************************************************
*
* uglBMFFontDestroy - destroy a font 
*
* NOMANUAL
*
*/

UGL_LOCAL UGL_STATUS uglBMFFontDestroy
    (
    UGL_FONT * pFont
    )
    {
    UGL_BMF_FONT_DRIVER * pBMFFontDriver = 
	    (UGL_BMF_FONT_DRIVER *)pFont->pFontDriver;
    UGL_BMF_FONT * pBMFFont = (UGL_BMF_FONT *)pFont;
    UGL_STATUS status = UGL_STATUS_OK;

    /* If the font has been created more than once, simply decrement
       the referenceCount variable and return */
    uglOSLock(pBMFFontDriver->lockId);

    if (pBMFFont->referenceCount > 1)
	{
	pBMFFont->referenceCount--;
	}
    /* Only one instance of the font, so it has to be "removed" */
    else
	{
	/* Find the font in the list of fonts and remove it */
	if (pBMFFont == pBMFFontDriver->pFirstFont)
	    {
	    pBMFFontDriver->pFirstFont = pBMFFont->pNextFont;

	    if (UGL_NULL != pBMFFontDriver->pFirstFont)
		{
		pBMFFontDriver->pFirstFont->pPrevFont = UGL_NULL;
		}
	    }
	else if (pBMFFont == pBMFFontDriver->pLastFont)
	    {
	    pBMFFontDriver->pLastFont = pBMFFont->pPrevFont;

	    if (UGL_NULL != pBMFFontDriver->pLastFont)
		{
		pBMFFontDriver->pLastFont->pNextFont = UGL_NULL;
		}
	    }
	else
	    {
	    UGL_BMF_FONT * pBMFFont = pBMFFontDriver->pFirstFont;

	    while (UGL_NULL != pBMFFont && 
		   pBMFFont->pNextFont != (UGL_BMF_FONT *)pFont)
		{
		pBMFFont = pBMFFont->pNextFont;
		}

	    if (UGL_NULL != pBMFFont)
		{
		pBMFFont->pNextFont = ((UGL_BMF_FONT *)pFont)->pNextFont;

		if (UGL_NULL != pBMFFont->pNextFont)
		    {
		    pBMFFont->pNextFont->pPrevFont = pBMFFont;
		    }
		}
	    else
		{
		status = UGL_STATUS_ERROR;
		}
	    }

	/* Free up the glyph cache entrys */
	if (UGL_STATUS_OK == status)
	    {
#ifdef INCLUDE_UGL_UNICODE
	    int i;
	    for (i = 0; i < 256; i++)
		if (pBMFFont->pageTable[i])
		    {
		    int j;
		    for (j = 0; j < 256; j++)
			{
			void ** ppPageData = &(*pBMFFont->pageTable[i])[j];
			/* Make sure element is in cache first */
			if (*ppPageData && 0 == *(UGL_UINT8 *)*ppPageData)
			    uglBMFGlyphCacheFree((UGL_FONT_DRIVER *)pBMFFontDriver, 
					      ppPageData);
			}
		    }
#else /*INCLUDE_UGL_UNICODE */
		int j;
		for (j = 0; j < 256; j++)
		    {
		    void ** ppPageData = &pBMFFont->pageZero[j];
		    if (*ppPageData && 0 == *(UGL_UINT8 *)*ppPageData)
			uglBMFGlyphCacheFree((UGL_FONT_DRIVER *)pBMFFontDriver, 
					  ppPageData);
		    }
#endif /*INCLUDE_UGL_UNICODE */
	    UGL_FREE(pFont);
	    pFont = UGL_NULL;
	    }
	}
    uglOSUnlock(pBMFFontDriver->lockId);
    return(status);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -