📄 udbmffnt.c
字号:
/* 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 reference01e,10nov00,jlb Change INCLUDE_UGL_BMF_UNICODE to INCLUDE_UGL_UNICODE01d,23oct00,msr Fixed fontFindFisrt()/Next() to be re-entrant.01c,15sep00,rfm Fixed SPR #3447901b,06sep00,rbp Modifications for refgen added.01a,11feb00,rfm Created*//* DESCRIPTIONThe Bitmapped Monochrome Font (BMF) driver is contained in this file.NOMANUAL*/#define GB2312_FONT_12/*12X12 字库*/#define GB2312_FONT_16/*16X16 字库*/#define GB2312_FONT_24/*24X24 字库*//* includes */#include <stdlib.h>#include <ctype.h>#include <iolib.h>#include <ugl/ugl.h>/* 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_UNICODEUGL_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 UGL_BMF_FONT_DESC * uglBMFFontData[];UGL_LOCAL UGL_BOOL uglBMFCacheConfig = UGL_FALSE;char *p12FontInRAM;char *p16FontInRAM;char *p24FontInRAM;/* Add by Li Ran to draw 16x16 Chinese char*/#ifdef GB2312_FONT_16void installHZK( char * directory){ int fd; /* Add for Chinese char*/ p16FontInRAM = (unsigned char *)malloc(268000); fd = open(directory, O_RDONLY, 0); read(fd, p16FontInRAM, 267616); close(fd);}void font16Draw(UGL_GC_ID gc, int x, int y,unsigned char color, int page, int fontInPage){ int i, j, k; unsigned char * byteNo; unsigned char font; byteNo = p16FontInRAM + ( ( page - 0xa1 ) * 94 + fontInPage - 0xa1 ) * 32 ; for (i = 0 ; i < 16 ; i++ ) for ( j = 0 ; j < 2 ; j++ ) { font = *byteNo; for ( k = 0 ; k < 8 ; k++ ) { if ( ( font >> ( 7 - k ) ) & 1 ) uglPixelSet(gc, x + j * 8 + k, y + i, color); } byteNo ++; }}#endif#ifdef GB2312_FONT_12void installHZK12( char * directory){ int fd; /* Add for Chinese char*/ p12FontInRAM = (unsigned char *)malloc(200000); fd = open(directory, O_RDONLY, 0); read(fd, p12FontInRAM, 196272); close(fd);}void font12Draw(UGL_GC_ID gc, int x, int y,unsigned char color, int page, int fontInPage){ int i, k; unsigned char * byteNo; unsigned char font; byteNo = p12FontInRAM + ( ( page - 0xa1 ) * 94 + fontInPage - 0xa1 ) * 24 ; for (i = 0 ; i < 12 ; i++ ) { font = *byteNo; for ( k = 0 ; k < 8 ; k++ ) { if ( ( font >> ( 7 - k ) ) & 1 ) uglPixelSet(gc, x + k, y + i, color); } byteNo ++; font = *byteNo; for ( k = 0 ; k < 4 ; k++ ) { if ( ( font >> ( 7 - k ) ) & 1 ) uglPixelSet(gc, x + 8 + k, y + i, color); } byteNo ++; }}#endif#ifdef GB2312_FONT_24void installHZK24( char * directory){ int fd; /* Add for Chinese char*/ p24FontInRAM = (unsigned char *)malloc(500000); fd = open(directory, O_RDONLY, 0); read(fd, p24FontInRAM, 498528); close(fd);}void font24Draw(UGL_GC_ID gc, int x, int y,unsigned char color, int page, int fontInPage){ int i, j, k; unsigned char * byteNo; unsigned char font; byteNo = p24FontInRAM + ( ( page - 0xb0 ) * 94 + fontInPage - 0xa1 ) * 72 ; for (i = 0 ; i < 24 ; i++ ) for ( j = 0 ; j < 3 ; j++ ) { font = *byteNo; for ( k = 0 ; k < 8 ; k++ ) { if ( ( font >> ( 7 - k ) ) & 1 ) uglPixelSet(gc, x + i, y + j * 8 + k, color); } byteNo ++; }}#endif/******************************************************************************** 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -