123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- /* Copyright (c) 2002-2012 Croteam Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as published by
- the Free Software Foundation
- This program 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 General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
- #include "stdh.h"
- #include <Engine/Graphics/Font.h>
- #include <Engine/Base/Stream.h>
- #include <Engine/Graphics/Texture.h>
- #include <Engine/Graphics/Color.h>
- #include <Engine/Templates/Stock_CTextureData.h>
- // some default fonts
- CFontData *_pfdDisplayFont;
- CFontData *_pfdConsoleFont;
- // constructor deletes letter data
- CFontCharData::CFontCharData(void)
- {
- fcd_pixXOffset = 0;
- fcd_pixYOffset = 0;
- fcd_pixStart = 0;
- fcd_pixEnd = 0;
- }
- // simple stream functions
- void CFontCharData::Read_t( CTStream *inFile)
- {
- *inFile>>fcd_pixXOffset;
- *inFile>>fcd_pixYOffset;
- *inFile>>fcd_pixStart;
- *inFile>>fcd_pixEnd;
- }
- void CFontCharData::Write_t( CTStream *outFile)
- {
- *outFile<<fcd_pixXOffset;
- *outFile<<fcd_pixYOffset;
- *outFile<<fcd_pixStart;
- *outFile<<fcd_pixEnd;
- }
- CFontData::CFontData()
- {
- fd_ptdTextureData = NULL;
- fd_fnTexture = CTString("");
- }
- CFontData::~CFontData()
- {
- Clear();
- }
- void CFontData::Clear()
- {
- if( fd_ptdTextureData != NULL) {
- fd_fnTexture = CTString("");
- _pTextureStock->Release(fd_ptdTextureData);
- fd_ptdTextureData = NULL;
- }
- }
- void CFontData::Read_t( CTStream *inFile) // throw char *
- {
- // clear current font data (if needed)
- Clear();
- // read the filename of the corresponding texture file.
- inFile->ExpectID_t( CChunkID("FTTF"));
- *inFile >> fd_fnTexture;
- // read maximum width and height of all letters
- *inFile >> fd_pixCharWidth;
- *inFile >> fd_pixCharHeight;
- // read entire letter data table
- for( INDEX iLetterData=0; iLetterData<256; iLetterData ++) {
- fd_fcdFontCharData[ iLetterData].Read_t( inFile);
- }
- // load corresponding texture file
- fd_ptdTextureData = _pTextureStock->Obtain_t(fd_fnTexture);
- // reload corresponding texture if not loaded in largest mip-map
- fd_ptdTextureData->Force( TEX_CONSTANT);
- // initialize default font variables
- SetVariableWidth();
- SetCharSpacing(+1);
- SetLineSpacing(+1);
- SetSpaceWidth(0.5f);
- fd_fcdFontCharData[' '].fcd_pixStart = 0;
- }
- void CFontData::Write_t( CTStream *outFile) // throw char *
- {
- ASSERT( fd_ptdTextureData != NULL);
- // write the filename of the corresponding texture file
- outFile->WriteID_t( CChunkID("FTTF"));
- *outFile << fd_fnTexture;
- // write max letter width and height of all letters
- *outFile << fd_pixCharWidth;
- *outFile << fd_pixCharHeight;
- // write entire letter data table
- for( INDEX iLetterData=0; iLetterData<256; iLetterData ++) {
- fd_fcdFontCharData[ iLetterData].Write_t( outFile);
- }
- }
- /*
- * Function used for creating font data object
- */
- void CFontData::Make_t( const CTFileName &fnTexture, PIX pixCharWidth, PIX pixCharHeight,
- CTFileName &fnOrderFile, BOOL bUseAlpha)
- {
- // do it only if font has not been created already
- ASSERT( fd_ptdTextureData == NULL);
- // remember texture name
- fd_fnTexture = fnTexture;
- // load texture and cache width
- fd_ptdTextureData = _pTextureStock->Obtain_t(fd_fnTexture);
- fd_ptdTextureData->Force( TEX_STATIC|TEX_CONSTANT);
- PIX pixTexWidth = fd_ptdTextureData->GetPixWidth();
- // load ascii order file (no application path necessary)
- CTString strLettersOrder;
- IgnoreApplicationPath();
- strLettersOrder.Load_t( fnOrderFile);
- UseApplicationPath();
- // remember letter width and height
- fd_pixCharWidth = pixCharWidth;
- fd_pixCharHeight = pixCharHeight;
- // determine address in memory where font definition begins in its larger mip-map
- ULONG *pulFont = fd_ptdTextureData->td_pulFrames;
- ASSERT( pulFont!=NULL);
- // find number of letters in line (assuming that the 1st line represents the width of every line)
- INDEX iLettersInLine=0;
- while( (strLettersOrder[iLettersInLine]!='\n') && iLettersInLine<strlen(strLettersOrder)) iLettersInLine++;
- if( iLettersInLine<=0) FatalError( "Invalid font definition ASCII file.");
- // determine pixelcheck mast depending of alpha channel usage
- COLOR colPixMask = 0xFFFFFF00; // FC is because of small tolerance for black
- if( bUseAlpha) colPixMask = 0xFFFFFFFF;
- // how much we must add to jump to character down
- PIX pixFontCharModulo = pixTexWidth * fd_pixCharHeight;
- // for all letters in font (ranging from space to last letter that user defined)
- INDEX iLetter=0;
- INDEX iCurrentLetterLine = 0;
- while( iLetter<strlen(strLettersOrder))
- { // for letters in one line
- for( INDEX iCurrentLetterColumn=0; iCurrentLetterColumn<iLettersInLine; iCurrentLetterColumn++)
- { // test if we at the end of whole array
- if( iLetter>=strlen(strLettersOrder)) break;
- // get char params
- unsigned char chrLetter = strLettersOrder[iLetter++];
- // reset current letter's width
- PIX pixCurrentStart = fd_pixCharWidth;
- PIX pixCurrentEnd = 0;
- // for all of the letter's lines
- for( INDEX iPixelLine=0; iPixelLine<fd_pixCharHeight; iPixelLine++)
- { // for all of the letter's pixels
- for( INDEX iPixelColumn=0; iPixelColumn<fd_pixCharWidth; iPixelColumn++)
- { // calculate current pixel's adress in font's texture
- ULONG *puwPixel = (ULONG*)( pulFont + pixFontCharModulo * iCurrentLetterLine + // calc right letter line
- fd_pixCharWidth * iCurrentLetterColumn + // move to right letter column
- pixTexWidth * iPixelLine + // move trough pixel lines of one letter
- iPixelColumn); // move trough pixel columns of one letter
- // if we test alpha channel and alpha value is not 0
- if( ByteSwap(*puwPixel) & colPixMask) {
- // if examined pixel is narrower in letter than last opaque pixel found, remember it as left-most pixel
- if( iPixelColumn < pixCurrentStart) pixCurrentStart = iPixelColumn;
- // if examined pixel is wider in letter than last opaque pixel found, remember it as right-most pixel
- if( iPixelColumn > pixCurrentEnd) pixCurrentEnd = iPixelColumn;
- }
- }
- }
- // letter's data is stored into table on appropriate place
- fd_fcdFontCharData[chrLetter].fcd_pixXOffset = iCurrentLetterColumn * fd_pixCharWidth;
- fd_fcdFontCharData[chrLetter].fcd_pixYOffset = iCurrentLetterLine * fd_pixCharHeight;
- fd_fcdFontCharData[chrLetter].fcd_pixStart = pixCurrentStart;
- fd_fcdFontCharData[chrLetter].fcd_pixEnd = pixCurrentEnd +1;
- }
- // advance to next line in text file
- iCurrentLetterLine++;
- iLetter++; // skip carriage return
- }
- // set default space width
- fd_fcdFontCharData[' '].fcd_pixStart = 0;
- SetSpaceWidth(0.5f);
- // all done
- SetVariableWidth();
- _pTextureStock->Release( fd_ptdTextureData);
- }
|