507 lines
10 KiB
C++
507 lines
10 KiB
C++
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CryFont Source Code
|
|
//
|
|
// File: FBitmap.cpp
|
|
// Description: Bitmap class implementation.
|
|
//
|
|
// History:
|
|
// - August 17, 2001: Created by Alberto Demichelis
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "FBitmap.h"
|
|
//#include <Image.h>
|
|
#include <stdio.h>
|
|
//
|
|
/////////////////////////////////////////////////
|
|
//CFBitmap::CFBitmap(int nWidth, int nHeight)
|
|
//{
|
|
// m_bOK = false;
|
|
//
|
|
// m_nWidth = nWidth;
|
|
// m_nHeight = nHeight;
|
|
//
|
|
// m_pData = new unsigned long[m_nWidth*m_nHeight];
|
|
// if(!m_pData)
|
|
// {
|
|
// CryError( "<CryFont> Only 32bpp images are supported" );
|
|
// return; // only 32 bits image are supported
|
|
// }
|
|
//
|
|
// m_bOK = true;
|
|
// m_pIRenderData = NULL;
|
|
//}
|
|
//
|
|
/////////////////////////////////////////////////
|
|
///*CFBitmap::CFBitmap(CImage *pImg)
|
|
//{
|
|
// m_bOK = false;
|
|
//
|
|
// if(pImg->GetBpp() != 32)
|
|
// {
|
|
// _asm int 3 // <<FIXME>>
|
|
// return; // only 32 bits image are supported
|
|
// }
|
|
//
|
|
// m_nWidth = pImg->GetWidth();/
|
|
// m_nHeight = pImg->GetHeight();
|
|
//
|
|
// m_pData = new unsigned long[m_nWidth*m_nHeight];
|
|
// if(!m_pData)
|
|
// {
|
|
// _asm int 3 // <<FIXME>>
|
|
// return; // unable to allocate the memory, return immediatly so IsOK() will return false
|
|
// }
|
|
//
|
|
// memcpy(m_pData, pImg->GetData(), m_nWidth*m_nHeight*4);
|
|
//
|
|
// m_bOK;
|
|
// m_pIRenderData = NULL;
|
|
//}*/
|
|
//
|
|
/////////////////////////////////////////////////
|
|
//CFBitmap::~CFBitmap()
|
|
//{
|
|
// if(m_pData)
|
|
// {
|
|
// delete [] m_pData;
|
|
// m_pData = NULL;
|
|
// }
|
|
// m_nWidth = 0;
|
|
// m_nHeight = 0;
|
|
// m_bOK = false;
|
|
// m_pIRenderData = NULL;
|
|
//}
|
|
//
|
|
/////////////////////////////////////////////////
|
|
//void CFBitmap::Release()
|
|
//{
|
|
// delete this;
|
|
//}
|
|
//
|
|
/////////////////////////////////////////////////
|
|
//bool CFBitmap::SmoothAndScale1On4()
|
|
//{
|
|
// int i, j;
|
|
// int sum;
|
|
// int xoffset;
|
|
// int yoffset;
|
|
// unsigned long *ptr;
|
|
//
|
|
// // create the destination buffer
|
|
// int w = m_nWidth >> 2;
|
|
// int h = m_nHeight >> 2;
|
|
// unsigned long *pNew = new unsigned long[w*h];
|
|
// if(!pNew)
|
|
// return false;
|
|
//
|
|
// // fill it
|
|
// for (i = 0; i < w; i++)
|
|
// {
|
|
// for (j = 0; j < h; j++)
|
|
// {
|
|
// sum = 0;
|
|
// xoffset = i << 2;
|
|
// yoffset = j << 2;
|
|
//
|
|
// ptr = m_pData + (GetWidth()*yoffset++) + xoffset;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr)>>24;
|
|
//
|
|
// ptr = m_pData + (GetWidth()*yoffset++) + xoffset;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr)>>24;
|
|
//
|
|
// ptr = m_pData + (GetWidth()*yoffset++) + xoffset;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr)>>24;
|
|
//
|
|
// ptr = m_pData + (GetWidth()*yoffset) + xoffset;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr++)>>24;
|
|
// sum += (*ptr)>>24;
|
|
//
|
|
// pNew[(j*w) + i] = ((sum>>4) << 24) | ((sum>>4) << 16) | ((sum>>4) << 8) | (sum>>4);
|
|
// }
|
|
// }
|
|
//
|
|
// // set the new size
|
|
// delete [] m_pData;
|
|
// m_nWidth = w;
|
|
// m_nHeight = h;
|
|
// m_pData = pNew;
|
|
//
|
|
// return true;
|
|
//}
|
|
//
|
|
/////////////////////////////////////////////////
|
|
//void CFBitmap::BlitFrom(CFBitmap *pSrc, int iSX, int iSY, int iDX, int iDY, int iW, int iH)
|
|
//{
|
|
// int sy = iSY;
|
|
// int dy = iDY;
|
|
// while(iH--)
|
|
// {
|
|
// int w = iW;
|
|
// unsigned long *pS = pSrc->GetData() + (sy*pSrc->GetWidth()) + iSX;
|
|
// unsigned long *pD = m_pData + (dy*m_nWidth) + iDX;
|
|
// while(w--)
|
|
// {
|
|
// *(pD++) = *(pS++);
|
|
// }
|
|
// ++dy;
|
|
// ++sy;
|
|
// }
|
|
//}
|
|
|
|
///////////////////////////////////////////////
|
|
/*
|
|
bool CFBitmap::SaveBitmap(const char *szFile, bool bSaveRGB)
|
|
{
|
|
FILE *fp = fxopen(szFile, "wb");
|
|
if(!fp)
|
|
return false;
|
|
|
|
int bfSize = 54 + m_nWidth*m_nHeight*3;
|
|
int i, j;
|
|
unsigned long c;
|
|
unsigned char rgb[3];
|
|
unsigned short tmp16;
|
|
unsigned long tmp32;
|
|
|
|
#define W16(val) tmp16 = val; fwrite(&tmp16,2,1,fp);
|
|
#define W32(val) tmp32 = val; fwrite(&tmp32,4,1,fp);
|
|
|
|
W16(0x4D42);
|
|
W32(bfSize);
|
|
W16(0);
|
|
W16(0);
|
|
|
|
W32(54);
|
|
|
|
bfSize = m_nWidth * m_nHeight * 3;
|
|
|
|
W32(40);
|
|
W32(m_nWidth);
|
|
W32(m_nHeight);
|
|
W16(1);
|
|
W16(24);
|
|
W32(0);
|
|
W32(bfSize);
|
|
W32(0);
|
|
W32(0);
|
|
W32(0);
|
|
W32(0);
|
|
|
|
if(!bSaveRGB)
|
|
{
|
|
for(i = m_nHeight-1; i >= 0; i--)
|
|
{
|
|
for(j = 0; j < m_nWidth; j++)
|
|
{
|
|
c = (m_pData[(i*m_nWidth)+j]>>24)&0xFF;
|
|
rgb[0] = (unsigned char)c;
|
|
rgb[1] = (unsigned char)c;
|
|
rgb[2] = (unsigned char)c;
|
|
fwrite(rgb,3,1,fp);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(i = m_nHeight-1; i >= 0; i--)
|
|
{
|
|
for(j = 0; j < m_nWidth; j++)
|
|
{
|
|
c = m_pData[(i*m_nWidth)+j];
|
|
rgb[2] = (unsigned char)((c>>16)&0xFF);
|
|
rgb[1] = (unsigned char)((c>>8)&0xFF);
|
|
rgb[0] = (unsigned char)(c&0xFF);
|
|
fwrite(rgb,3,1,fp);
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
return true;
|
|
}
|
|
|
|
// puts the size of this structure and all its contained objects in bytes into the sizer
|
|
void CFBitmap::GetMemoryUsage (class ICrySizer* pSizer)
|
|
{
|
|
pSizer->Add (*this);
|
|
pSizer->Add (m_pData, m_nWidth*m_nHeight);
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------
|
|
CFBitmap::CFBitmap()
|
|
: m_iWidth(0), m_iHeight(0), m_pData(0), m_pIRenderData(0)
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------
|
|
CFBitmap::~CFBitmap()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------
|
|
int CFBitmap::Blur(int iIterations)
|
|
{
|
|
int cSum;
|
|
int yOffset;
|
|
int yupOffset;
|
|
int ydownOffset;
|
|
|
|
for (int i = 0; i < iIterations; i++)
|
|
{
|
|
for (int y = 0; y < m_iHeight; y++)
|
|
{
|
|
yOffset = y * m_iWidth;
|
|
|
|
if (y - 1 >= 0)
|
|
{
|
|
yupOffset = (y-1) * m_iWidth;
|
|
}
|
|
else
|
|
{
|
|
yupOffset = (y) * m_iWidth;
|
|
}
|
|
|
|
if (y + 1 <= m_iHeight)
|
|
{
|
|
ydownOffset = (y+1) * m_iWidth;
|
|
}
|
|
else
|
|
{
|
|
ydownOffset = (y) * m_iWidth;
|
|
}
|
|
|
|
for (int x = 0; x < m_iWidth; x++)
|
|
{
|
|
cSum = m_pData[yupOffset + x] + m_pData[ydownOffset + x];
|
|
|
|
if (x - 1 >= 0)
|
|
{
|
|
cSum += m_pData[yOffset + x - 1];
|
|
}
|
|
else
|
|
{
|
|
cSum += m_pData[yOffset + x];
|
|
}
|
|
|
|
if (x + 1 < m_iWidth)
|
|
{
|
|
cSum += m_pData[yOffset + x + 1];
|
|
}
|
|
else
|
|
{
|
|
cSum += m_pData[yOffset + x];
|
|
}
|
|
|
|
m_pData[yOffset + x] = cSum >> 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------
|
|
int CFBitmap::Scale(float fScaleX, float fScaleY)
|
|
{
|
|
int iNewWidth = (int)(m_iWidth * fScaleX);
|
|
int iNewHeight = (int)(m_iHeight * fScaleY);
|
|
|
|
unsigned char *pNewData = new unsigned char[iNewWidth * iNewHeight];
|
|
|
|
if (!pNewData)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
float xFactor = m_iWidth / (float)iNewWidth;
|
|
float yFactor = m_iHeight / (float)iNewHeight;
|
|
|
|
float xFractioned, yFractioned, xFraction, yFraction, oneMinusX, oneMinusY, fR0, fR1;
|
|
int xCeil, yCeil, xFloor, yFloor, yNewOffset;
|
|
|
|
unsigned char c0, c1, c2, c3;
|
|
|
|
for (int y = 0; y < iNewHeight; ++y)
|
|
{
|
|
yFractioned = y * yFactor;
|
|
yFloor = (int)floorf(yFractioned);
|
|
yCeil = yFloor + 1;
|
|
|
|
if (yCeil >= m_iHeight)
|
|
{
|
|
yCeil = yFloor;
|
|
}
|
|
|
|
yFraction = yFractioned - yFloor;
|
|
oneMinusY = 1.0f - yFraction;
|
|
|
|
// yOffset = y * m_iWidth;
|
|
yNewOffset = y * iNewWidth;
|
|
|
|
|
|
for (int x = 0; x < iNewWidth; ++x)
|
|
{
|
|
xFractioned = x * xFactor;
|
|
xFloor = (int)floorf(xFractioned);
|
|
xCeil = xFloor + 1;
|
|
|
|
if (xCeil >= m_iWidth)
|
|
{
|
|
xCeil = xFloor;
|
|
}
|
|
|
|
xFraction = xFractioned - xFloor;
|
|
oneMinusX = 1.0f - xFraction;
|
|
|
|
c0 = m_pData[yFloor * m_iWidth + xFloor];
|
|
c1 = m_pData[yFloor * m_iWidth + xCeil];
|
|
c2 = m_pData[yCeil * m_iWidth + xFloor];
|
|
c3 = m_pData[yCeil * m_iWidth + xCeil];
|
|
|
|
fR0 = (oneMinusX * c0 + xFraction * c1);
|
|
fR1 = (oneMinusX * c2 + xFraction * c3);
|
|
|
|
pNewData[yNewOffset + x] = (unsigned char)((oneMinusY * fR0) + (yFraction * fR1));
|
|
}
|
|
}
|
|
|
|
m_iWidth = iNewWidth;
|
|
m_iHeight = iNewHeight;
|
|
|
|
delete[] m_pData;
|
|
m_pData = pNewData;
|
|
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------
|
|
int CFBitmap::BlitFrom(CFBitmap *pSrc, int iSX, int iSY, int iDX, int iDY, int iW, int iH)
|
|
{
|
|
for (int y = 0; y < iH; y++)
|
|
{
|
|
for (int x = 0; x < iW; x++)
|
|
{
|
|
m_pData[(iDY + y) * m_iWidth + (iDX + x)] = pSrc->m_pData[(iSY + y) * pSrc->m_iWidth + (iSX + x)];
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------
|
|
int CFBitmap::BlitTo(CFBitmap *pDst, int iDX, int iDY, int iSX, int iSY, int iW, int iH)
|
|
{
|
|
for (int y = 0; y < iH; y++)
|
|
{
|
|
for (int x = 0; x < iW; x++)
|
|
{
|
|
pDst->m_pData[(iDY + y) * pDst->m_iWidth + (iDX + x)] = m_pData[(iSY + y) * m_iWidth + (iSX + x)];
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------
|
|
int CFBitmap::Create(int iWidth, int iHeight)
|
|
{
|
|
SAFE_DELETE_ARRAY(m_pData);
|
|
|
|
m_pData = new unsigned char [iWidth * iHeight];
|
|
|
|
m_iWidth = iWidth;
|
|
m_iHeight = iHeight;
|
|
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------
|
|
int CFBitmap::Release()
|
|
{
|
|
SAFE_DELETE_ARRAY(m_pData);
|
|
m_iWidth = m_iHeight = 0;
|
|
// m_pIRenderData = 0;
|
|
|
|
delete this;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------------------
|
|
#define W16(val) { unsigned short t16 = (val); fwrite(&t16, 2, 1, hFile); }
|
|
#define W32(val) { unsigned int t32 = (val); fwrite(&t32, 4, 1, hFile); }
|
|
//------------------------------------------------------------------------------------
|
|
int CFBitmap::SaveBitmap(const std::string &szFileName)
|
|
{
|
|
FILE *hFile = fopen(szFileName.c_str(), "wb");
|
|
|
|
if(!hFile)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int iFileSize = 54 + (m_iWidth * m_iHeight * 3);
|
|
|
|
W16(0x4D42);
|
|
W32(iFileSize);
|
|
W16(0);
|
|
W16(0);
|
|
|
|
W32(54);
|
|
|
|
W32(40);
|
|
|
|
W32(m_iWidth);
|
|
W32(m_iHeight);
|
|
|
|
iFileSize = m_iWidth * m_iHeight * 3;
|
|
|
|
W16(1);
|
|
W16(24);
|
|
W32(0);
|
|
W32(iFileSize);
|
|
W32(0);
|
|
W32(0);
|
|
W32(0);
|
|
W32(0);
|
|
|
|
for(int i = m_iHeight - 1; i >= 0; i--)
|
|
{
|
|
for(int j = 0; j < m_iWidth; j++)
|
|
{
|
|
fwrite(&m_pData[(i * m_iWidth) + j], 1, 1, hFile);
|
|
fwrite(&m_pData[(i * m_iWidth) + j], 1, 1, hFile);
|
|
fwrite(&m_pData[(i * m_iWidth) + j], 1, 1, hFile);
|
|
}
|
|
}
|
|
|
|
fclose(hFile);
|
|
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------
|
|
void CFBitmap::GetMemoryUsage (class ICrySizer *pSizer)
|
|
{
|
|
pSizer->Add (*this);
|
|
pSizer->Add (m_pData, m_iWidth * m_iHeight);
|
|
} |