326 lines
No EOL
8.6 KiB
C++
326 lines
No EOL
8.6 KiB
C++
#include "TRACK.h"
|
|
#include "MEDIA.h"
|
|
|
|
#define NB_CHARS 256
|
|
#define MAX_FONT_BOUND 63
|
|
class FONT_Grabber:public INPUT_IO
|
|
{
|
|
SIZE CharBounds[NB_CHARS];
|
|
SIZE CharPos[NB_CHARS];
|
|
ABC CharABC[NB_CHARS];
|
|
u32 FontMask;
|
|
HFONT hFont;
|
|
TEXTMETRIC FontMetrix;
|
|
|
|
public:
|
|
int INIT (class WORLD*);
|
|
int FRAME (void);
|
|
int END (void){return 0;};
|
|
IOTYPE GetType() {return IOtype_FONT;};
|
|
void * GetData(int dataIdx);
|
|
};
|
|
|
|
PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp)
|
|
{
|
|
BITMAP bmp;
|
|
PBITMAPINFO pbmi;
|
|
WORD cClrBits;
|
|
|
|
// Retrieve the bitmap color format, width, and height.
|
|
if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
|
|
return NULL;
|
|
|
|
// Convert the color format to a count of bits.
|
|
cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
|
|
if (cClrBits == 1)
|
|
cClrBits = 1;
|
|
else if (cClrBits <= 4)
|
|
cClrBits = 4;
|
|
else if (cClrBits <= 8)
|
|
cClrBits = 8;
|
|
else if (cClrBits <= 16)
|
|
cClrBits = 16;
|
|
else if (cClrBits <= 24)
|
|
cClrBits = 24;
|
|
else cClrBits = 32;
|
|
|
|
// Allocate memory for the BITMAPINFO structure. (This structure
|
|
// contains a BITMAPINFOHEADER structure and an array of RGBQUAD
|
|
// data structures.)
|
|
|
|
if (cClrBits != 24)
|
|
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
|
|
sizeof(BITMAPINFOHEADER) +
|
|
sizeof(RGBQUAD) * (1<< cClrBits));
|
|
|
|
// There is no RGBQUAD array for the 24-bit-per-pixel format.
|
|
|
|
else
|
|
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
|
|
sizeof(BITMAPINFOHEADER));
|
|
|
|
// Initialize the fields in the BITMAPINFO structure.
|
|
|
|
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
pbmi->bmiHeader.biWidth = bmp.bmWidth;
|
|
pbmi->bmiHeader.biHeight = bmp.bmHeight;
|
|
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
|
|
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
|
|
if (cClrBits < 24)
|
|
pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
|
|
|
|
// If the bitmap is not compressed, set the BI_RGB flag.
|
|
pbmi->bmiHeader.biCompression = BI_RGB;
|
|
|
|
// Compute the number of bytes in the array of color
|
|
// indices and store the result in biSizeImage.
|
|
// For Windows NT, the width must be DWORD aligned unless
|
|
// the bitmap is RLE compressed. This example shows this.
|
|
// For Windows 95/98/Me, the width must be WORD aligned unless the
|
|
// bitmap is RLE compressed.
|
|
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
|
|
* pbmi->bmiHeader.biHeight;
|
|
// Set biClrImportant to 0, indicating that all of the
|
|
// device colors are important.
|
|
pbmi->bmiHeader.biClrImportant = 0;
|
|
return pbmi;
|
|
}
|
|
|
|
BOOL FONT_Grabber::INIT(WORLD *pScene)
|
|
{
|
|
LOGFONT fontStruct;
|
|
char tmpStr[512];
|
|
char *fontHeightInfo;
|
|
int len;
|
|
HWND hWnd;
|
|
HDC hDC , hDCBuff;
|
|
HBITMAP imgFont;
|
|
PBITMAPINFO imgInfo;
|
|
|
|
/* Load camcam font */
|
|
static u32 res = -1;
|
|
if (res == -1) res = AddFontResourceEx("./Fonts/HouseHolidayTT-Sans.ttf",FR_PRIVATE,0);
|
|
|
|
|
|
memset(&fontStruct, 0, sizeof(fontStruct));
|
|
len = (int)strlen((char *)MediaName) - 4;
|
|
MediaName[len] = 0;
|
|
FontMask = 0;
|
|
while ((MediaName[len - 1] <= 32 ||
|
|
MediaName[len - 1] == 'A'||
|
|
MediaName[len - 1] == 'B'||
|
|
MediaName[len - 1] == 'I'||
|
|
MediaName[len - 1] == 'U'||
|
|
MediaName[len - 1] == 'C'||
|
|
MediaName[len - 1] == 'T') && len > 0)
|
|
{
|
|
if (MediaName[len - 1] == 'A') FontMask |= 1<<0;
|
|
if (MediaName[len - 1] == 'B') FontMask |= 1<<1;
|
|
if (MediaName[len - 1] == 'I') FontMask |= 1<<2;
|
|
if (MediaName[len - 1] == 'U') FontMask |= 1<<3;
|
|
if (MediaName[len - 1] == 'C') FontMask |= 1<<4;
|
|
if (MediaName[len - 1] == 'T') FontMask |= 1<<5;
|
|
MediaName[len-- - 1] = 0;
|
|
}
|
|
|
|
|
|
fontHeightInfo = (char *)MediaName;
|
|
while (strchr(fontHeightInfo, ' ') != NULL)
|
|
fontHeightInfo = strchr(fontHeightInfo, ' ') + 1;
|
|
|
|
|
|
hWnd = GetDesktopWindow();
|
|
hDC = GetDC(hWnd);
|
|
|
|
fontStruct.lfHeight = - MulDiv(atoi(fontHeightInfo), GetDeviceCaps(hDC,LOGPIXELSY), 72);;
|
|
//fontStruct.lfWidth = 0;
|
|
//fontStruct.lfEscapement = 0;
|
|
//fontStruct.lfOrientation = 0;
|
|
if (FontMask & 1<<1)
|
|
fontStruct.lfWeight = FW_BOLD;
|
|
else
|
|
fontStruct.lfWeight = FW_NORMAL;
|
|
//fontStruct.lfStrikeOut = 0;
|
|
fontStruct.lfItalic = (FontMask & 1<<2) != 0;
|
|
fontStruct.lfUnderline = (FontMask & 1<<3) != 0;
|
|
fontStruct.lfCharSet = DEFAULT_CHARSET;
|
|
fontStruct.lfOutPrecision = OUT_DEFAULT_PRECIS;
|
|
fontStruct.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
|
if (FontMask & 1<<0)
|
|
fontStruct.lfQuality = CLEARTYPE_NATURAL_QUALITY;
|
|
else
|
|
fontStruct.lfQuality = NONANTIALIASED_QUALITY;
|
|
fontStruct.lfPitchAndFamily = FF_DONTCARE;
|
|
if (fontHeightInfo != (char *)MediaName)
|
|
strncpy(fontStruct.lfFaceName, (char *)MediaName, fontHeightInfo - (char *)MediaName- 1);
|
|
else
|
|
strcpy(fontStruct.lfFaceName, (char *)MediaName);
|
|
|
|
|
|
hFont = CreateFontIndirect(&fontStruct);
|
|
if (hFont == NULL)
|
|
return false;
|
|
hDCBuff = CreateCompatibleDC(hDC);
|
|
SelectObject(hDCBuff, hFont);
|
|
|
|
int imgXPos = 0, imgYPos = 0, asciiPos = 0;
|
|
int maxWidth = 0, maxHeight;
|
|
|
|
int xPos, yPos, pos;
|
|
|
|
|
|
GetTextMetrics(hDCBuff, &FontMetrix);
|
|
|
|
char oneChar = 0;
|
|
|
|
memset(CharABC, 0, sizeof(CharABC));
|
|
if (!GetCharABCWidths(hDCBuff, 0, 255, CharABC))
|
|
{
|
|
int width[256];
|
|
GetCharWidth32(hDCBuff, 0, 255, width);
|
|
for (int i=0; i<256; i++)
|
|
CharABC[i].abcB = width[i];
|
|
}
|
|
|
|
for (yPos=0; yPos<16; yPos++)
|
|
{
|
|
imgXPos = 1;
|
|
for (xPos=0; xPos<16; xPos++, oneChar++, asciiPos++)
|
|
{
|
|
GetTextExtentPoint32(hDCBuff, &oneChar, 1, CharBounds + asciiPos);
|
|
CharBounds[asciiPos].cx = abs(CharABC[asciiPos].abcA) + CharABC[asciiPos].abcB + abs(CharABC[asciiPos].abcC);
|
|
|
|
CharPos[asciiPos].cx = imgXPos;
|
|
CharPos[asciiPos].cy = imgYPos;
|
|
if (CharBounds[asciiPos].cx > MAX_FONT_BOUND)
|
|
CharBounds[asciiPos].cx = MAX_FONT_BOUND;
|
|
if (CharBounds[asciiPos].cy > MAX_FONT_BOUND)
|
|
CharBounds[asciiPos].cy = MAX_FONT_BOUND;
|
|
imgXPos += CharBounds[asciiPos].cx+1;
|
|
if (maxWidth < imgXPos) maxWidth = imgXPos;
|
|
}
|
|
imgYPos += FontMetrix.tmHeight + 1;
|
|
}
|
|
|
|
u32 ISX, ISY;
|
|
ISX = maxWidth;
|
|
ISY = imgYPos;
|
|
|
|
if (ISX & 3)
|
|
ISX += 4 - (ISX & 3);
|
|
if (ISY & 3)
|
|
ISY += 4 - (ISY & 3);
|
|
|
|
if (ISX == 0 ||
|
|
ISY == 0)
|
|
{
|
|
ReleaseDC(hWnd, hDC);
|
|
DeleteObject(hDCBuff);
|
|
DeleteObject(hFont);
|
|
return false;
|
|
}
|
|
|
|
Image.SetSize(ISX, ISY);
|
|
memset(Image.GetBase(), 0xFF, Image.PITCH*Image.SY*sizeof(s32));
|
|
|
|
imgFont = CreateCompatibleBitmap ( hDC, Image.SX, Image.SY );
|
|
SelectObject(hDCBuff, imgFont);
|
|
SetBkMode(hDCBuff, TRANSPARENT);
|
|
|
|
RECT charRect;
|
|
SetRect(&charRect, 0, 0, Image.SX, Image.SY);
|
|
|
|
SetTextColor(hDCBuff, RGB(255,255,255));
|
|
|
|
u32 colors[3];
|
|
HBRUSH colorsBrush[3];
|
|
|
|
colors[0] = RGB(255,0,0);
|
|
colors[1] = RGB(0,255,0);
|
|
colors[2] = RGB(0,0,255);
|
|
for (int y=0; y<3; y++)
|
|
colorsBrush[y] = CreateSolidBrush(colors[y]);
|
|
|
|
for (pos=0; pos<256; pos++, oneChar++)
|
|
{
|
|
charRect.left = CharPos[pos].cx;
|
|
charRect.top = CharPos[pos].cy;
|
|
charRect.right = charRect.left + CharBounds[pos].cx;
|
|
charRect.bottom = charRect.top + CharBounds[pos].cy;
|
|
|
|
//FillRect(hDCBuff, &charRect, colorsBrush[pos % 3]);
|
|
if (CharABC[pos].abcA < 0)
|
|
TextOut(hDCBuff, CharPos[pos].cx - CharABC[pos].abcA, CharPos[pos].cy, &oneChar, 1);
|
|
else
|
|
TextOut(hDCBuff, CharPos[pos].cx, CharPos[pos].cy, &oneChar, 1);
|
|
}
|
|
|
|
imgInfo = CreateBitmapInfoStruct(hWnd, imgFont);
|
|
imgInfo->bmiHeader.biPlanes = 1;
|
|
imgInfo->bmiHeader.biBitCount = 32;
|
|
imgInfo->bmiHeader.biCompression = BI_RGB;
|
|
GetDIBits(hDCBuff, imgFont, 0, Image.SY, Image.GetBase(), imgInfo, DIB_RGB_COLORS);
|
|
|
|
int counter = Image.SX * Image.SY;
|
|
s32 *pBASE = Image.GetBase();
|
|
|
|
//while (counter--)
|
|
// Image.BASE[counter] = (0xFF << 24) | (Image.BASE[counter] & 0xFFFFFF);
|
|
|
|
|
|
if (FontMask & 1<<5)
|
|
{
|
|
while (counter--)
|
|
pBASE[counter] = (pBASE[counter] & 0xFF) << 24 | 0xFFFFFF;
|
|
} else {
|
|
while (counter--)
|
|
pBASE[counter] = (pBASE[counter] & 0xFF) << 24 | (pBASE[counter] & 0xFFFFFF);
|
|
}
|
|
ReleaseDC(hWnd, hDC);
|
|
|
|
DeleteObject(imgInfo);
|
|
DeleteObject(imgFont);
|
|
DeleteObject(hDCBuff);
|
|
DeleteObject(hFont);
|
|
return true;
|
|
}
|
|
|
|
|
|
int FONT_Grabber::FRAME(void)
|
|
{
|
|
return 0;
|
|
};
|
|
|
|
|
|
void *FONT_Grabber::GetData(int dataIdx)
|
|
{
|
|
switch(dataIdx)
|
|
{
|
|
case 0:
|
|
return (void *)CharBounds;
|
|
case 1:
|
|
return (void *)CharPos;
|
|
case 2:
|
|
return (void *)FontMask;
|
|
case 3:
|
|
return (void *)&FontMetrix;
|
|
case 4:
|
|
return (void *)&CharABC;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
INPUT_IO *FONT_CREATE(WORLD *pScene,char *Filename)
|
|
{
|
|
INPUT_IO *Ret;
|
|
Ret = (INPUT_IO *)new(FONT_Grabber);
|
|
strcpy((char*)Ret->MediaName,Filename);
|
|
if (!Ret->INIT(pScene))
|
|
{
|
|
delete Ret;
|
|
return NULL;
|
|
}
|
|
Ret->dTotalTime = 0;
|
|
Ret->dAvgFramePerSecond = 30.0;
|
|
return Ret;
|
|
} |