mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 16:44:36 +00:00
STB Memory functions for fonts
Add the ability to read and write to a stream.
This commit is contained in:
parent
7216ba8530
commit
106346630d
4 changed files with 129 additions and 15 deletions
|
|
@ -1206,6 +1206,20 @@ bool GBitmap::readBitmap(const String& bmType, const Torque::Path& path)
|
||||||
return regInfo->readFunc(path, this);
|
return regInfo->readFunc(path, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GBitmap::readBitmapStream(const String& bmType, Stream& ioStream, U32 len)
|
||||||
|
{
|
||||||
|
PROFILE_SCOPE(ResourceGBitmap_readBitmapStream);
|
||||||
|
const GBitmap::Registration* regInfo = GBitmap::sFindRegInfo(bmType);
|
||||||
|
|
||||||
|
if (regInfo == NULL)
|
||||||
|
{
|
||||||
|
Con::errorf("[GBitmap::readBitmap] unable to find registration for extension [%s]", bmType.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return regInfo->readStreamFunc(ioStream, this, len);
|
||||||
|
}
|
||||||
|
|
||||||
bool GBitmap::writeBitmap( const String &bmType, const Torque::Path& path, U32 compressionLevel )
|
bool GBitmap::writeBitmap( const String &bmType, const Torque::Path& path, U32 compressionLevel )
|
||||||
{
|
{
|
||||||
FileStream stream;
|
FileStream stream;
|
||||||
|
|
@ -1230,6 +1244,19 @@ bool GBitmap::writeBitmap( const String &bmType, const Torque::Path& path, U32
|
||||||
return regInfo->writeFunc(path, this, (compressionLevel == U32_MAX) ? regInfo->defaultCompression : compressionLevel );
|
return regInfo->writeFunc(path, this, (compressionLevel == U32_MAX) ? regInfo->defaultCompression : compressionLevel );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GBitmap::writeBitmapStream(const String& bmType, Stream& ioStream, U32 compressionLevel)
|
||||||
|
{
|
||||||
|
const GBitmap::Registration* regInfo = GBitmap::sFindRegInfo(bmType);
|
||||||
|
|
||||||
|
if (regInfo == NULL)
|
||||||
|
{
|
||||||
|
Con::errorf("[GBitmap::writeBitmap] unable to find registration for extension [%s]", bmType.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return regInfo->writeStreamFunc(ioStream, this, (compressionLevel == U32_MAX) ? regInfo->defaultCompression : compressionLevel);
|
||||||
|
}
|
||||||
|
|
||||||
template<> void *Resource<GBitmap>::create(const Torque::Path &path)
|
template<> void *Resource<GBitmap>::create(const Torque::Path &path)
|
||||||
{
|
{
|
||||||
PROFILE_SCOPE( ResourceGBitmap_create );
|
PROFILE_SCOPE( ResourceGBitmap_create );
|
||||||
|
|
|
||||||
|
|
@ -70,26 +70,31 @@ public:
|
||||||
|
|
||||||
struct Registration
|
struct Registration
|
||||||
{
|
{
|
||||||
/// The read function prototype.
|
/// The read functions prototype.
|
||||||
typedef bool(*ReadFunc)(const Torque::Path& path, GBitmap* bitmap);
|
typedef bool(*ReadFunc)(const Torque::Path& path, GBitmap* bitmap);
|
||||||
|
typedef bool(*ReadStreamFunc)(Stream& stream, GBitmap* bitmap, U32 len);
|
||||||
/// The write function prototype. Compression levels are image-specific - see their registration declaration for details.
|
/// The write functions prototype. Compression levels are image-specific - see their registration declaration for details.
|
||||||
typedef bool(*WriteFunc)(const Torque::Path& path, GBitmap* bitmap, U32 compressionLevel);
|
typedef bool(*WriteFunc)(const Torque::Path& path, GBitmap* bitmap, U32 compressionLevel);
|
||||||
|
typedef bool(*WriteStreamFunc)(Stream& stream, GBitmap* bitmap, U32 compressionLevel);
|
||||||
|
|
||||||
/// Used to sort the registrations so that
|
/// Used to sort the registrations so that
|
||||||
/// lookups occur in a fixed order.
|
/// lookups occur in a fixed order.
|
||||||
U32 priority;
|
U32 priority;
|
||||||
|
|
||||||
Vector<String> extensions; ///< the list of file extensions for this bitmap type [these should be lower case]
|
Vector<String> extensions; ///< the list of file extensions for this bitmap type [these should be lower case]
|
||||||
|
|
||||||
ReadFunc readFunc; ///< the read function to call for this bitmap type
|
ReadFunc readFunc; ///< the read function to read from a file.
|
||||||
WriteFunc writeFunc; ///< the write function to call for this bitmap type
|
WriteFunc writeFunc; ///< the write function to write to a file.
|
||||||
U32 defaultCompression; ///< the default compression level [levels are image-specific - see their registration declaration for details]
|
ReadStreamFunc readStreamFunc; ///< the read function to read from a stream.
|
||||||
|
WriteStreamFunc writeStreamFunc; ///< the write function to write to a stream.
|
||||||
|
|
||||||
|
U32 defaultCompression; ///< the default compression level [levels are image-specific - see their registration declaration for details]
|
||||||
|
|
||||||
Registration()
|
Registration()
|
||||||
{
|
{
|
||||||
readFunc = NULL;
|
readFunc = NULL;
|
||||||
writeFunc = NULL;
|
writeFunc = NULL;
|
||||||
|
readStreamFunc = NULL;
|
||||||
|
writeStreamFunc = NULL;
|
||||||
defaultCompression = 0;
|
defaultCompression = 0;
|
||||||
priority = 0;
|
priority = 0;
|
||||||
VECTOR_SET_ASSOCIATION( extensions );
|
VECTOR_SET_ASSOCIATION( extensions );
|
||||||
|
|
@ -238,19 +243,24 @@ public:
|
||||||
|
|
||||||
//-------------------------------------- Input/Output interface
|
//-------------------------------------- Input/Output interface
|
||||||
|
|
||||||
/// Read a bitmap from a stream
|
/// Read a bitmap from a file
|
||||||
/// @param bmType This is a file extension to describe the type of the data [i.e. "png" for PNG file, etc]
|
/// @param bmType This is a file extension to describe the type of the data [i.e. "png" for PNG file, etc]
|
||||||
/// @param ioStream The stream to read from
|
/// @param ioStream The stream to read from
|
||||||
bool readBitmap(const String& bmType, const Torque::Path& path);
|
bool readBitmap(const String& bmType, const Torque::Path& path);
|
||||||
|
|
||||||
/// Write a bitmap to a stream
|
/// Sane as above but reads from a stream.
|
||||||
|
bool readBitmapStream(const String& bmType, Stream& ioStream, U32 len);
|
||||||
|
|
||||||
|
/// Write a bitmap to a file
|
||||||
/// @param bmType This is a file extension to describe the type of the data [i.e. "png" for PNG file, etc]
|
/// @param bmType This is a file extension to describe the type of the data [i.e. "png" for PNG file, etc]
|
||||||
/// @param ioStream The stream to read from
|
/// @param ioStream The stream to read from
|
||||||
/// @param compressionLevel Image format specific compression level. For JPEG sets the quality level percentage, range 0 to 100.
|
/// @param compressionLevel Image format specific compression level. For JPEG sets the quality level percentage, range 0 to 100.
|
||||||
/// For PNG compression level is 0 - 10
|
/// For PNG compression level is 0 - 10
|
||||||
/// Not used for other image formats.
|
/// Not used for other image formats.
|
||||||
|
bool writeBitmap( const String &bmType, const Torque::Path& path, U32 compressionLevel = U32_MAX );
|
||||||
|
|
||||||
bool writeBitmap( const String &bmType, const Torque::Path& path, U32 compressionLevel = U32_MAX );
|
/// Sane as above but writes to a stream.
|
||||||
|
bool writeBitmapStream(const String& bmType, Stream& ioStream, U32 compressionLevel = U32_MAX);
|
||||||
|
|
||||||
bool readMNG(Stream& io_rStream); // located in bitmapMng.cc
|
bool readMNG(Stream& io_rStream); // located in bitmapMng.cc
|
||||||
bool writeMNG(Stream& io_rStream) const;
|
bool writeMNG(Stream& io_rStream) const;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
#include "console/console.h"
|
||||||
|
|
||||||
#include "core/stream/fileStream.h"
|
#include "core/stream/fileStream.h"
|
||||||
#include "core/stream/memStream.h"
|
#include "core/stream/memStream.h"
|
||||||
|
|
@ -40,7 +41,10 @@
|
||||||
#include "stb_image_write.h"
|
#include "stb_image_write.h"
|
||||||
|
|
||||||
static bool sReadSTB(const Torque::Path& path, GBitmap* bitmap);
|
static bool sReadSTB(const Torque::Path& path, GBitmap* bitmap);
|
||||||
|
static bool sReadStreamSTB(Stream& stream, GBitmap* bitmap, U32 len);
|
||||||
|
|
||||||
static bool sWriteSTB(const Torque::Path& path, GBitmap* bitmap, U32 compressionLevel);
|
static bool sWriteSTB(const Torque::Path& path, GBitmap* bitmap, U32 compressionLevel);
|
||||||
|
static bool sWriteStreamSTB(Stream& stream, GBitmap* bitmap, U32 compressionLevel);
|
||||||
|
|
||||||
static struct _privateRegisterSTB
|
static struct _privateRegisterSTB
|
||||||
{
|
{
|
||||||
|
|
@ -58,8 +62,10 @@ static struct _privateRegisterSTB
|
||||||
reg.extensions.push_back("tga");
|
reg.extensions.push_back("tga");
|
||||||
|
|
||||||
reg.readFunc = sReadSTB;
|
reg.readFunc = sReadSTB;
|
||||||
|
reg.readStreamFunc = sReadStreamSTB;
|
||||||
|
|
||||||
reg.writeFunc = sWriteSTB;
|
reg.writeFunc = sWriteSTB;
|
||||||
|
reg.writeStreamFunc = sWriteStreamSTB;
|
||||||
|
|
||||||
// for png only.
|
// for png only.
|
||||||
reg.defaultCompression = 6;
|
reg.defaultCompression = 6;
|
||||||
|
|
@ -194,6 +200,41 @@ bool sReadSTB(const Torque::Path& path, GBitmap* bitmap)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sReadStreamSTB(Stream& stream, GBitmap* bitmap, U32 len)
|
||||||
|
{
|
||||||
|
PROFILE_SCOPE(sReadStreamSTB);
|
||||||
|
// only used for font at the moment.
|
||||||
|
|
||||||
|
U8* data = new U8[len];
|
||||||
|
stream.read(len, data);
|
||||||
|
|
||||||
|
S32 width, height, comp = 0;
|
||||||
|
|
||||||
|
unsigned char* pixelData = stbi_load_from_memory((const U8*)data, (int)len, &width, &height, &comp, 1);
|
||||||
|
if (!pixelData)
|
||||||
|
{
|
||||||
|
const char* stbErr = stbi_failure_reason();
|
||||||
|
|
||||||
|
if (!stbErr)
|
||||||
|
stbErr = "Unknown Error!";
|
||||||
|
|
||||||
|
Con::printf("sReadStreamSTB Error: %s", stbErr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bitmap->deleteImage();
|
||||||
|
|
||||||
|
bitmap->allocateBitmap(256, 256, false, GFXFormatA8);
|
||||||
|
|
||||||
|
U8* pBase = bitmap->getWritableBits(0);
|
||||||
|
U32 rowBytes = bitmap->getByteSize();
|
||||||
|
dMemcpy(pBase, pixelData, rowBytes);
|
||||||
|
|
||||||
|
dFree(data);
|
||||||
|
dFree(pixelData);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write bitmap to an image file.
|
* Write bitmap to an image file.
|
||||||
*
|
*
|
||||||
|
|
@ -269,3 +310,28 @@ bool sWriteSTB(const Torque::Path& path, GBitmap* bitmap, U32 compressionLevel)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sWriteStreamSTB(Stream& stream, GBitmap* bitmap, U32 compressionLevel)
|
||||||
|
{
|
||||||
|
S32 len;
|
||||||
|
const U8* pData = bitmap->getBits();
|
||||||
|
|
||||||
|
unsigned char* png = stbi_write_png_to_mem(pData, 0, bitmap->getWidth(), bitmap->getHeight(), 1, &len);
|
||||||
|
|
||||||
|
if (!png)
|
||||||
|
{
|
||||||
|
const char* stbErr = stbi_failure_reason();
|
||||||
|
|
||||||
|
if (!stbErr)
|
||||||
|
stbErr = "Unknown Error!";
|
||||||
|
|
||||||
|
Con::printf("sReadStreamSTB Error: %s", stbErr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.write(len);
|
||||||
|
stream.write(len, png);
|
||||||
|
|
||||||
|
dFree(png);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -699,12 +699,21 @@ bool GFont::read(Stream& io_rStream)
|
||||||
for(i = 0; i < numSheets; i++)
|
for(i = 0; i < numSheets; i++)
|
||||||
{
|
{
|
||||||
GBitmap *bmp = new GBitmap;
|
GBitmap *bmp = new GBitmap;
|
||||||
String path = String::ToString("%s/%s %d %d (%s).png", Con::getVariable("$GUI::fontCacheDirectory"), mFaceName.c_str(), mSize, i, getCharSetName(mCharSet));
|
/*String path = String::ToString("%s/%s %d %d (%s).png", Con::getVariable("$GUI::fontCacheDirectory"), mFaceName.c_str(), mSize, i, getCharSetName(mCharSet));
|
||||||
if(!bmp->readBitmap("png", path))
|
if(!bmp->readBitmap("png", path))
|
||||||
{
|
{
|
||||||
delete bmp;
|
delete bmp;
|
||||||
return false;
|
return false;
|
||||||
|
}*/
|
||||||
|
U32 len;
|
||||||
|
io_rStream.read(&len);
|
||||||
|
|
||||||
|
if (!bmp->readBitmapStream("png", io_rStream, len))
|
||||||
|
{
|
||||||
|
delete bmp;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXTexHandle handle = GFXTexHandle(bmp, &GFXFontTextureProfile, true, avar("%s() - Read Font Sheet for %s %d (line %d)", __FUNCTION__, mFaceName.c_str(), mSize, __LINE__));
|
GFXTexHandle handle = GFXTexHandle(bmp, &GFXFontTextureProfile, true, avar("%s() - Read Font Sheet for %s %d (line %d)", __FUNCTION__, mFaceName.c_str(), mSize, __LINE__));
|
||||||
//handle.setFilterNearest();
|
//handle.setFilterNearest();
|
||||||
mTextureSheets.push_back(handle);
|
mTextureSheets.push_back(handle);
|
||||||
|
|
@ -779,7 +788,9 @@ bool GFont::write(Stream& stream)
|
||||||
for (i = 0; i < mTextureSheets.size(); i++)
|
for (i = 0; i < mTextureSheets.size(); i++)
|
||||||
{
|
{
|
||||||
String path = String::ToString("%s/%s %d %d (%s).png", Con::getVariable("$GUI::fontCacheDirectory"), mFaceName.c_str(), mSize, i, getCharSetName(mCharSet));
|
String path = String::ToString("%s/%s %d %d (%s).png", Con::getVariable("$GUI::fontCacheDirectory"), mFaceName.c_str(), mSize, i, getCharSetName(mCharSet));
|
||||||
mTextureSheets[i].getBitmap()->writeBitmap("png", path);
|
//mTextureSheets[i].getBitmap()->writeBitmap("png", path);
|
||||||
|
|
||||||
|
mTextureSheets[i].getBitmap()->writeBitmapStream("png", stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.write(mCurX);
|
stream.write(mCurX);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue