📄 udbmffnt.c
字号:
} else if(pBMFFontDriver->textOrigin == UGL_FONT_TEXT_BASELINE) { point.x = x; point.y = y - (UGL_POS)pCacheElement->ascent; (*pDriver->monoBitmapBlt)(pDriver, pCacheElement->bitmapID, &pCacheElement->bitmapRect, UGL_DEFAULT_ID, &point); x += pCacheElement->width; } else { status = UGL_STATUS_ERROR; break; } } /* Restore gc */ pGc->backgroundColor = saveColor; pGc->changed |= UGL_GC_BACKGROUND_COLOR_CHANGED; UGL_GC_CHANGED_SET(pGc); UGL_GC_SET(pDriver, pGc); return (status); }/***************************************************************************** uglBMFTextSizeGet - Get the width and height of a text string** NOMANUAL**/UGL_LOCAL UGL_STATUS uglBMFTextSizeGet ( UGL_FONT * pFont, UGL_SIZE * pWidth, UGL_SIZE * pHeight, UGL_SIZE length, const UGL_CHAR *text ) { UGL_BMF_FONT *pBMFFont = (UGL_BMF_FONT *)pFont; int textWidth = 0; void ** ppPageZero = pBMFFont->pageZero; UGL_UINT8 *pGlyphData; int i; /* Check for null text */ if (text == UGL_NULL || text[0] == 0) return (UGL_STATUS_ERROR); /* Set a large text length, if -1 is specified */ if (length <= 0) length = 0x0fff; /* Compute the text height */ if (UGL_NULL != pHeight) { if ( ( * ( text + 2 ) == '^' ) && ( ( * text ) & 0x80 ) && ( ( * ( text + 1 ) ) & 0x80 ) ){ *pHeight = 24 + 3; }else if ( ( * ( text + 2 ) == '~' ) && ( ( * text ) & 0x80 ) && ( ( * ( text + 1 ) ) & 0x80 ) ){ *pHeight = 12 + 2; }else if ( ( ( * text ) & 0x80 ) && ( ( * ( text + 1 ) ) & 0x80 ) ) { *pHeight = 16 + 2; }else{ *pHeight = pBMFFont->pBMFFontDesc->maxAscent + pBMFFont->pBMFFontDesc->maxDescent; } } /* Compute the text width */ if (UGL_NULL != pWidth) { for (i = 0; UGL_NULL != *text && i < length; i++) { if ( ( * ( text + 2 ) == '^' ) && ( ( * text ) & 0x80 ) && ( ( * ( text + 1 ) ) & 0x80 ) ){ textWidth += 24; text += 3; }else if ( ( * ( text + 2 ) == '~' ) && ( ( * text ) & 0x80 ) && ( ( * ( text + 1 ) ) & 0x80 ) ){ textWidth += 12; text += 3; }else if ( ( ( * text ) & 0x80 ) && ( ( * ( text + 1 ) ) & 0x80 ) ) { textWidth += 16; text += 2; } else { pGlyphData = (UGL_UINT8 *)ppPageZero[(UGL_UINT8)*(text++)]; if (UGL_NULL != pGlyphData) { textWidth += pGlyphData[1]; } } } *pWidth = textWidth; } return (UGL_STATUS_OK); }#ifdef INCLUDE_UGL_UNICODE/***************************************************************************** uglBMFTextDrawW - draw double-wide text** NOMANUAL**/UGL_LOCAL UGL_STATUS uglBMFTextDrawW ( UGL_GC * pGc, UGL_POS x, UGL_POS y, UGL_SIZE length, const UGL_WCHAR * text ) { UGL_UGI_DRIVER * pDriver = pGc->pDriver; UGL_BMF_FONT * pBMFFont = (UGL_BMF_FONT *)pGc->pFont; UGL_BMF_FONT_DRIVER * pBMFFontDriver = (UGL_BMF_FONT_DRIVER *)pBMFFont->header.pFontDriver; UGL_FONT_DRIVER * pFontDriver = (UGL_FONT_DRIVER *)pBMFFont->header.pFontDriver; UGL_GLYPH_CACHE_ELEMENT *pCacheElement; UGL_FONT_PAGE ** ppPageTable = pBMFFont->pageTable; UGL_FONT_PAGE * pPageZero = ppPageTable[0]; UGL_FONT_PAGE * pPage; void ** ppPageElement; UGL_SIZE maxAscent = pBMFFont->pBMFFontDesc->maxAscent; UGL_STATUS status = UGL_STATUS_OK; UGL_COLOR saveColor; UGL_POINT point; int i; /* Make sure the font and text are valid */ if (pBMFFont == UGL_NULL || text == UGL_NULL || text[0] == 0) return (UGL_STATUS_ERROR); /* Set a large text length, if -1 is specified */ if (length <= 0) length = 0x0fff; /* Draw the text background */ if (pGc->backgroundColor != UGL_COLOR_TRANSPARENT) { UGL_SIZE width, height; UGL_RECT rect; UGL_POS tmpY; (*pFontDriver->textSizeGetW)(pGc->pFont, &width, &height, length, text); if(pBMFFontDriver->textOrigin == UGL_FONT_TEXT_UPPER_LEFT) { rect.right = x + width - 1; rect.bottom = y + height - 1; rect.left = x; rect.top = y; } else if(pBMFFontDriver->textOrigin == UGL_FONT_TEXT_BASELINE) { tmpY = y - maxAscent; rect.right = x + width - 1; rect.bottom = tmpY + height - 1; rect.left = x; rect.top = tmpY; } else return(UGL_STATUS_ERROR); saveColor = pGc->foregroundColor; pGc->foregroundColor = UGL_COLOR_TRANSPARENT; pGc->changed |= UGL_GC_FOREGROUND_COLOR_CHANGED; UGL_GC_CHANGED_SET(pGc); UGL_GC_SET(pDriver, pGc); (*pDriver->rectangle)(pDriver, &rect); pGc->foregroundColor = saveColor; pGc->changed |= UGL_GC_FOREGROUND_COLOR_CHANGED; UGL_GC_CHANGED_SET(pGc); UGL_GC_SET(pDriver, pGc); } saveColor = pGc->backgroundColor; pGc->backgroundColor = UGL_COLOR_TRANSPARENT; pGc->changed |= UGL_GC_BACKGROUND_COLOR_CHANGED; UGL_GC_CHANGED_SET(pGc); UGL_GC_SET(pDriver, pGc); /* Blit each character to the screen */ for (i = 0; UGL_NULL != *text && i < length; i++ ) { pPage = ppPageTable[((UGL_UINT16)*text) >> 8]; /* Find page */ if (UGL_NULL == pPage) { ppPageElement = (void**) &(*pPageZero)[0]; } else { ppPageElement = (void**) &(*pPage)[*text & 0xFF]; } text++; pCacheElement = (UGL_GLYPH_CACHE_ELEMENT *)*ppPageElement; /* If encoding doesn't map to a glyph, don't do anything */ if (UGL_NULL == pCacheElement) { continue; } /* Check to see if glyph is in cache or not */ if (UGL_BMF_GLYPH_IN_CACHE != pCacheElement->cacheFlag) { pCacheElement = uglBMFGlyphCacheAlloc(pFontDriver, ppPageElement); if (UGL_NULL == pCacheElement) { status = UGL_STATUS_ERROR; break; } } /* Blit glyph to the screen */ if(pBMFFontDriver->textOrigin == UGL_FONT_TEXT_UPPER_LEFT) { point.x = x; point.y = y + maxAscent - (UGL_POS)pCacheElement->ascent; (*pDriver->monoBitmapBlt)(pDriver, pCacheElement->bitmapID, &pCacheElement->bitmapRect, UGL_DEFAULT_ID, &point); x += pCacheElement->width; } else if(pBMFFontDriver->textOrigin == UGL_FONT_TEXT_BASELINE) { point.x = x; point.y = y - (UGL_POS)pCacheElement->ascent; (*pDriver->monoBitmapBlt)(pDriver, pCacheElement->bitmapID, &pCacheElement->bitmapRect, UGL_DEFAULT_ID, &point); x += pCacheElement->width; } else { status = UGL_STATUS_ERROR; break; } } pGc->backgroundColor = saveColor; pGc->changed |= UGL_GC_BACKGROUND_COLOR_CHANGED; UGL_GC_CHANGED_SET(pGc); UGL_GC_SET(pDriver, pGc); return (status); }/***************************************************************************** uglBMFTextSizeGetW - get the width of double-byte text** NOMANUAL**/UGL_LOCAL UGL_STATUS uglBMFTextSizeGetW ( UGL_FONT * pFont, UGL_SIZE * pWidth, UGL_SIZE * pHeight, UGL_SIZE length, const UGL_WCHAR *text ) { UGL_BMF_FONT * pBMFFont = (UGL_BMF_FONT *)pFont; UGL_FONT_PAGE **ppPageTable = pBMFFont->pageTable; UGL_FONT_PAGE *pPageZero = ppPageTable[0]; UGL_FONT_PAGE *pPage; UGL_UINT8 *pGlyphData; int textWidth = 0; int i; /* Check for null text */ if (text == UGL_NULL || text[0] == 0) return (UGL_STATUS_ERROR); /* Set a large text length, if -1 is specified */ if (length <= 0) length = 0x0fff; /* Compute the text width */ if (UGL_NULL != pWidth) { for (i = 0; UGL_NULL != *text && i < length; i++) { pPage = ppPageTable[((UGL_UINT16)*text) >> 8]; if (UGL_NULL == pPage) { pGlyphData = (UGL_UINT8 *)(*pPageZero)[0]; } else { pGlyphData = (UGL_UINT8 *)(*pPage)[*text & 0xFF]; } text++; if (UGL_NULL != pGlyphData) { textWidth += pGlyphData[1]; } } *pWidth = textWidth; } /* Compute the text height */ if (UGL_NULL != pHeight) { *pHeight = pBMFFont->pBMFFontDesc->maxAscent + pBMFFont->pBMFFontDesc->maxDescent; } return (UGL_STATUS_OK); }#endif /* INCLUDE_UGL_UNICODE *//********************************************************************************* uglBMFGlyphCacheAlloc** NOMANUAL**/UGL_LOCAL UGL_GLYPH_CACHE_ELEMENT * uglBMFGlyphCacheAlloc ( UGL_FONT_DRIVER * pFontDriver, void ** ppPageElement ) { UGL_BMF_FONT_DRIVER *pBMFFontDriver = (UGL_BMF_FONT_DRIVER *)pFontDriver; UGL_UGI_DRIVER * pDriver = pFontDriver->pDriver; UGL_GLYPH_CACHE_ELEMENT * pCacheElement; UGL_MDIB mDib; UGL_MEM_POOL_ID glyphCachePoolId = pBMFFontDriver->glyphCachePoolId; UGL_UINT8 *pGlyphData = (UGL_UINT8 *)*ppPageElement; if (pBMFFontDriver->glyphCacheSize >= 0 && pBMFFontDriver->numCachedGlyphs >= pBMFFontDriver->glyphCacheSize) { uglBMFGlyphCacheFree(pFontDriver, pBMFFontDriver->pLastCacheElement->ppPageElement); } /* Allocate new element */ pCacheElement = (UGL_GLYPH_CACHE_ELEMENT *)uglMemCalloc(glyphCachePoolId, 1, sizeof(UGL_GLYPH_CACHE_ELEMENT)); if(pCacheElement == UGL_NULL) { int i = 0; /* Make sure there is enough room in cache for new element */ while(pCacheElement == UGL_NULL) { uglBMFGlyphCacheFree(pFontDriver, pBMFFontDriver->pLastCacheElement->ppPageElement); pCacheElement = (UGL_GLYPH_CACHE_ELEMENT *)uglMemCalloc(glyphCachePoolId, 1, sizeof(UGL_GLYPH_CACHE_ELEMENT)); /* something to prevent endless loops */ if(pCacheElement == UGL_NULL && i++ > 1000) return(UGL_NULL); } } pCacheElement->pGlyphData = pGlyphData; pCacheElement->ppPageElement = ppPageElement; pCacheElement->width = pGlyphData[1]; pCacheElement->height = pGlyphData[2]; pCacheElement->ascent = pGlyphData[3]; pCacheElement->bitmapRect.left = 0; pCacheElement->bitmapRect.top = 0; pCacheElement->bitmapRect.right = pCacheElement->width - 1; pCacheElement->bitmapRect.bottom = pCacheElement->height - 1; mDib.width = (UGL_SIZE)pCacheElement->width; mDib.height = (UGL_SIZE)pCacheElement->height; mDib.stride = (UGL_SIZE)pCacheElement->width; mDib.pImage = &pGlyphData[4]; pCacheElement->bitmapID = (*pDriver->monoBitmapCreate) (pDriver, &mDib, UGL_DIB_INIT_DATA, 0, glyphCachePoolId); if (pCacheElement->bitmapID == UGL_NULL) { /* Make sure enough room in cache for the bitmap */ while(pCacheElement->bitmapID == UGL_NULL) { int i = 0; uglBMFGlyphCacheFree(pFontDriver, pBMFFontDriver->pLastCacheElement->ppPageElement); pCacheElement->bitmapID = (*pDriver->monoBitmapCreate) (pDriver, &mDib, UGL_DIB_INIT_DATA, 0, glyphCachePoolId); /* something to prevent endless loops */ if(pCacheElement->bitmapID == UGL_NULL && i++ > 100) { uglMemFree(pCacheElement); return(UGL_NULL); } } } /* Add element to the list */ pCacheElement->pNext = pBMFFontDriver->pFirstCacheElement; /* If a first element exists, link it to the new first element before replacing the first element with the new cache element. */ if (UGL_NULL != pBMFFontDriver->pFirstCacheElement) { pBMFFontDriver->pFirstCacheElement->pPrev = pCacheElement; } pBMFFontDriver->pFirstCacheElement = pCacheElement; /* update last cache element */ if (UGL_NULL == pBMFFontDriver->pLastCacheElement) { pBMFFontDriver->pLastCacheElement = pCacheElement; } /* Point the entry in the page to the cacheElement */ *ppPageElement = pCacheElement; pBMFFontDriver->numCachedGlyphs++; return (pCacheElement); }/********************************************************************************* uglBMFGlyphCacheFree** NOMANUAL**/UGL_LOCAL void uglBMFGlyphCacheFree ( UGL_FONT_DRIVER * pFontDriver, void ** ppPageElement ) { UGL_BMF_FONT_DRIVER * pBMFFontDriver = (UGL_BMF_FONT_DRIVER *)pFontDriver; UGL_GLYPH_CACHE_ELEMENT *pCacheElement = (UGL_GLYPH_CACHE_ELEMENT *)*ppPageElement; UGL_UGI_DRIVER * pDriver = pFontDriver->pDriver; /* remove link to predecessor */ if (UGL_NULL != pCacheElement->pPrev) { pCacheElement->pPrev->pNext = pCacheElement->pNext; } /* no prev indicates element is head of list, make next element head */ else { pBMFFontDriver->pFirstCacheElement = pCacheElement->pNext; } /* remove link to sucessor */ if (UGL_NULL != pCacheElement->pNext) { pCacheElement->pNext->pPrev = pCacheElement->pPrev; } /* no next indicates element is tail of list, make prev new tail */ else { pBMFFontDriver->pLastCacheElement = pCacheElement->pPrev; } if (UGL_NULL != pCacheElement->bitmapID) { (*pDriver->monoBitmapDestroy)(pDriver, pCacheElement->bitmapID); } if (UGL_NULL != pCacheElement) { *ppPageElement = pCacheElement->pGlyphData; pBMFFontDriver->numCachedGlyphs--; uglMemFree(pCacheElement); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -