You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
396 lines
11 KiB
C++
396 lines
11 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
// Purpose:
|
|
// - Hold a glyph bitmap and blit it to the main texture
|
|
|
|
#include "CryFont_precompiled.h"
|
|
#include "GlyphBitmap.h"
|
|
#include <math.h>
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
CGlyphBitmap::CGlyphBitmap()
|
|
: m_iWidth(0)
|
|
, m_iHeight(0)
|
|
, m_pBuffer(0)
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
CGlyphBitmap::~CGlyphBitmap()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
int CGlyphBitmap::Create(int iWidth, int iHeight)
|
|
{
|
|
Release();
|
|
|
|
m_pBuffer = new unsigned char[iWidth * iHeight];
|
|
|
|
if (!m_pBuffer)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
m_iWidth = iWidth;
|
|
m_iHeight = iHeight;
|
|
|
|
return 1;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
int CGlyphBitmap::Release()
|
|
{
|
|
if (m_pBuffer)
|
|
{
|
|
delete[] m_pBuffer;
|
|
}
|
|
m_pBuffer = 0;
|
|
m_iWidth = m_iHeight = 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
int CGlyphBitmap::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_pBuffer[yupOffset + x] + m_pBuffer[ydownOffset + x];
|
|
|
|
if (x - 1 >= 0)
|
|
{
|
|
cSum += m_pBuffer[yOffset + x - 1];
|
|
}
|
|
else
|
|
{
|
|
cSum += m_pBuffer[yOffset + x];
|
|
}
|
|
|
|
if (x + 1 < m_iWidth)
|
|
{
|
|
cSum += m_pBuffer[yOffset + x + 1];
|
|
}
|
|
else
|
|
{
|
|
cSum += m_pBuffer[yOffset + x];
|
|
}
|
|
|
|
m_pBuffer[yOffset + x] = cSum >> 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
int CGlyphBitmap::Scale(float fScaleX, float fScaleY)
|
|
{
|
|
int iNewWidth = (int)(m_iWidth * fScaleX);
|
|
int iNewHeight = (int)(m_iHeight * fScaleY);
|
|
|
|
unsigned char* pNewBuffer = new unsigned char[iNewWidth * iNewHeight];
|
|
|
|
if (!pNewBuffer)
|
|
{
|
|
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)floor_tpl(yFractioned);
|
|
yCeil = yFloor + 1;
|
|
|
|
if (yCeil >= m_iHeight)
|
|
{
|
|
yCeil = yFloor;
|
|
}
|
|
|
|
yFraction = yFractioned - yFloor;
|
|
oneMinusY = 1.0f - yFraction;
|
|
|
|
yNewOffset = y * iNewWidth;
|
|
|
|
for (int x = 0; x < iNewWidth; ++x)
|
|
{
|
|
xFractioned = x * xFactor;
|
|
xFloor = (int)floor_tpl(xFractioned);
|
|
xCeil = xFloor + 1;
|
|
|
|
if (xCeil >= m_iWidth)
|
|
{
|
|
xCeil = xFloor;
|
|
}
|
|
|
|
xFraction = xFractioned - xFloor;
|
|
oneMinusX = 1.0f - xFraction;
|
|
|
|
c0 = m_pBuffer[yFloor * m_iWidth + xFloor];
|
|
c1 = m_pBuffer[yFloor * m_iWidth + xCeil];
|
|
c2 = m_pBuffer[yCeil * m_iWidth + xFloor];
|
|
c3 = m_pBuffer[yCeil * m_iWidth + xCeil];
|
|
|
|
fR0 = (oneMinusX * c0 + xFraction * c1);
|
|
fR1 = (oneMinusX * c2 + xFraction * c3);
|
|
|
|
pNewBuffer[yNewOffset + x] = (unsigned char)((oneMinusY * fR0) + (yFraction * fR1));
|
|
}
|
|
}
|
|
|
|
m_iWidth = iNewWidth;
|
|
m_iHeight = iNewHeight;
|
|
|
|
delete[] m_pBuffer;
|
|
m_pBuffer = pNewBuffer;
|
|
|
|
return 1;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
int CGlyphBitmap::Clear()
|
|
{
|
|
memset(m_pBuffer, 0, m_iWidth * m_iHeight);
|
|
|
|
return 1;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
int CGlyphBitmap::BlitTo8(unsigned char* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth)
|
|
{
|
|
int ySrcOffset, yDestOffset;
|
|
|
|
for (int y = 0; y < iSrcHeight; y++)
|
|
{
|
|
ySrcOffset = (iSrcY + y) * m_iWidth;
|
|
yDestOffset = (iDestY + y) * iDestWidth;
|
|
|
|
for (int x = 0; x < iSrcWidth; x++)
|
|
{
|
|
pBuffer[yDestOffset + iDestX + x] = m_pBuffer[ySrcOffset + iSrcX + x];
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
int CGlyphBitmap::BlitTo32(unsigned int* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth)
|
|
{
|
|
int ySrcOffset, yDestOffset;
|
|
char cColor;
|
|
|
|
for (int y = 0; y < iSrcHeight; y++)
|
|
{
|
|
ySrcOffset = (iSrcY + y) * m_iWidth;
|
|
yDestOffset = (iDestY + y) * iDestWidth;
|
|
|
|
for (int x = 0; x < iSrcWidth; x++)
|
|
{
|
|
cColor = m_pBuffer[ySrcOffset + iSrcX + x];
|
|
|
|
pBuffer[yDestOffset + iDestX + x] = (cColor << 24) | (255 << 16) | (255 << 8) | 255;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
int CGlyphBitmap::BlitScaledTo8(unsigned char* pBuffer, [[maybe_unused]] int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, [[maybe_unused]] int iDestY, int iDestWidth, int iDestHeight, int iDestBufferWidth)
|
|
{
|
|
int iNewWidth = (int)iDestWidth;
|
|
int iNewHeight = (int)iDestHeight;
|
|
|
|
unsigned char* pNewBuffer = pBuffer;
|
|
|
|
float xFactor = iSrcWidth / (float)iNewWidth;
|
|
float yFactor = iSrcHeight / (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)floor_tpl(yFractioned);
|
|
yCeil = yFloor + 1;
|
|
|
|
yFraction = yFractioned - yFloor;
|
|
oneMinusY = 1.0f - yFraction;
|
|
|
|
yNewOffset = y * iDestBufferWidth;
|
|
|
|
yFloor += iSrcY;
|
|
yCeil += iSrcY;
|
|
|
|
if (yCeil >= m_iHeight)
|
|
{
|
|
yCeil = yFloor;
|
|
}
|
|
|
|
for (int x = 0; x < iNewWidth; ++x)
|
|
{
|
|
xFractioned = x * xFactor;
|
|
xFloor = (int)floor_tpl(xFractioned);
|
|
xCeil = xFloor + 1;
|
|
|
|
xFraction = xFractioned - xFloor;
|
|
oneMinusX = 1.0f - xFraction;
|
|
|
|
xFloor += iSrcY;
|
|
xCeil += iSrcY;
|
|
|
|
if (xCeil >= m_iWidth)
|
|
{
|
|
xCeil = xFloor;
|
|
}
|
|
|
|
c0 = m_pBuffer[yFloor * m_iWidth + xFloor];
|
|
c1 = m_pBuffer[yFloor * m_iWidth + xCeil];
|
|
c2 = m_pBuffer[yCeil * m_iWidth + xFloor];
|
|
c3 = m_pBuffer[yCeil * m_iWidth + xCeil];
|
|
|
|
fR0 = (oneMinusX * c0 + xFraction * c1);
|
|
fR1 = (oneMinusX * c2 + xFraction * c3);
|
|
|
|
pNewBuffer[yNewOffset + x + iDestX] = (unsigned char)((oneMinusY * fR0) + (yFraction * fR1));
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
#if defined(__GNUC__)
|
|
#if __GNUC__ >= 4 && __GNUC__MINOR__ < 7
|
|
#pragma GCC diagnostic ignored "-Woverflow"
|
|
#endif
|
|
#endif
|
|
//-------------------------------------------------------------------------------------------------
|
|
int CGlyphBitmap::BlitScaledTo32(unsigned char* pBuffer, [[maybe_unused]] int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, [[maybe_unused]] int iDestY, int iDestWidth, int iDestHeight, int iDestBufferWidth)
|
|
{
|
|
int iNewWidth = (int)iDestWidth;
|
|
int iNewHeight = (int)iDestHeight;
|
|
|
|
unsigned char* pNewBuffer = pBuffer;
|
|
|
|
float xFactor = iSrcWidth / (float)iNewWidth;
|
|
float yFactor = iSrcHeight / (float)iNewHeight;
|
|
|
|
float xFractioned, yFractioned, xFraction, yFraction, oneMinusX, oneMinusY, fR0, fR1;
|
|
int xCeil, yCeil, xFloor, yFloor, yNewOffset;
|
|
|
|
unsigned char c0, c1, c2, c3, cColor;
|
|
|
|
for (int y = 0; y < iNewHeight; ++y)
|
|
{
|
|
yFractioned = y * yFactor;
|
|
yFloor = (int)floor_tpl(yFractioned);
|
|
yCeil = yFloor + 1;
|
|
|
|
yFraction = yFractioned - yFloor;
|
|
oneMinusY = 1.0f - yFraction;
|
|
|
|
yNewOffset = y * iDestBufferWidth;
|
|
|
|
yFloor += iSrcY;
|
|
yCeil += iSrcY;
|
|
|
|
if (yCeil >= m_iHeight)
|
|
{
|
|
yCeil = yFloor;
|
|
}
|
|
|
|
for (int x = 0; x < iNewWidth; ++x)
|
|
{
|
|
xFractioned = x * xFactor;
|
|
xFloor = (int)floor_tpl(xFractioned);
|
|
xCeil = xFloor + 1;
|
|
|
|
xFraction = xFractioned - xFloor;
|
|
oneMinusX = 1.0f - xFraction;
|
|
|
|
xFloor += iSrcY;
|
|
xCeil += iSrcY;
|
|
|
|
if (xCeil >= m_iWidth)
|
|
{
|
|
xCeil = xFloor;
|
|
}
|
|
|
|
c0 = m_pBuffer[yFloor * m_iWidth + xFloor];
|
|
c1 = m_pBuffer[yFloor * m_iWidth + xCeil];
|
|
c2 = m_pBuffer[yCeil * m_iWidth + xFloor];
|
|
c3 = m_pBuffer[yCeil * m_iWidth + xCeil];
|
|
|
|
fR0 = (oneMinusX * c0 + xFraction * c1);
|
|
fR1 = (oneMinusX * c2 + xFraction * c3);
|
|
|
|
cColor = (unsigned char)((oneMinusY * fR0) + (yFraction * fR1));
|
|
|
|
pNewBuffer[yNewOffset + x + iDestX] = 0xffffff | (cColor << 24);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
#if defined(__GNUC__)
|
|
#if __GNUC__ >= 4 && __GNUC__MINOR__ < 7
|
|
#pragma GCC diagnostic error "-Woverflow"
|
|
#endif
|
|
#endif
|
|
//-------------------------------------------------------------------------------------------------
|