Load and render ttf fonts
This commit is contained in:
parent
178b31822a
commit
6df76c20df
10 changed files with 145 additions and 21 deletions
|
@ -22,6 +22,9 @@
|
|||
|
||||
#include "common/endian.h"
|
||||
|
||||
#include "graphics/fonts/ttf.h"
|
||||
#include "graphics/font.h"
|
||||
|
||||
#include "engines/grim/debug.h"
|
||||
#include "engines/grim/grim.h"
|
||||
#include "engines/grim/savegame.h"
|
||||
|
@ -82,6 +85,8 @@ void Font::load(const Common::String &filename, Common::SeekableReadStream *data
|
|||
g_driver->createFont(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint16 Font::getCharIndex(unsigned char c) const {
|
||||
uint16 c2 = uint16(c);
|
||||
|
||||
|
@ -160,6 +165,12 @@ void Font::restoreState(SaveGame *state) {
|
|||
delete stream;
|
||||
}
|
||||
|
||||
void FontTTF::loadTTF(const Common::String &filename, Common::SeekableReadStream *data, int size) {
|
||||
_font = Graphics::loadTTFFont(*data, size);
|
||||
|
||||
//f->
|
||||
}
|
||||
|
||||
// Hardcoded default font for GUI, etc
|
||||
const uint8 Font::emerFont[][13] = {
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include "engines/grim/pool.h"
|
||||
|
||||
#include "graphics/font.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
}
|
||||
|
@ -42,23 +44,24 @@ public:
|
|||
|
||||
void load(const Common::String &filename, Common::SeekableReadStream *data);
|
||||
|
||||
|
||||
const Common::String &getFilename() const { return _filename; }
|
||||
int32 getKernedHeight() const { return _kernedHeight; }
|
||||
int32 getBaseOffsetY() const { return _baseOffsetY; }
|
||||
int32 getCharBitmapWidth(unsigned char c) const { return _charHeaders[getCharIndex(c)].bitmapWidth; }
|
||||
int32 getCharBitmapHeight(unsigned char c) const { return _charHeaders[getCharIndex(c)].bitmapHeight; }
|
||||
int32 getCharKernedWidth(unsigned char c) const { return _charHeaders[getCharIndex(c)].kernedWidth; }
|
||||
int32 getCharStartingCol(unsigned char c) const { return _charHeaders[getCharIndex(c)].startingCol; }
|
||||
int32 getCharStartingLine(unsigned char c) const { return _charHeaders[getCharIndex(c)].startingLine; }
|
||||
int32 getCharOffset(unsigned char c) const { return _charHeaders[getCharIndex(c)].offset; }
|
||||
virtual int32 getKernedHeight() const { return _kernedHeight; }
|
||||
virtual int32 getBaseOffsetY() const { return _baseOffsetY; }
|
||||
virtual int32 getCharBitmapWidth(unsigned char c) const { return _charHeaders[getCharIndex(c)].bitmapWidth; }
|
||||
virtual int32 getCharBitmapHeight(unsigned char c) const { return _charHeaders[getCharIndex(c)].bitmapHeight; }
|
||||
virtual int32 getCharKernedWidth(unsigned char c) const { return _charHeaders[getCharIndex(c)].kernedWidth; }
|
||||
virtual int32 getCharStartingCol(unsigned char c) const { return _charHeaders[getCharIndex(c)].startingCol; }
|
||||
virtual int32 getCharStartingLine(unsigned char c) const { return _charHeaders[getCharIndex(c)].startingLine; }
|
||||
virtual int32 getCharOffset(unsigned char c) const { return _charHeaders[getCharIndex(c)].offset; }
|
||||
const byte *getCharData(unsigned char c) const { return _fontData + (_charHeaders[getCharIndex(c)].offset); }
|
||||
|
||||
const byte *getFontData() const { return _fontData; }
|
||||
uint32 getDataSize() const { return _dataSize; }
|
||||
|
||||
int getKernedStringLength(const Common::String &text) const;
|
||||
int getBitmapStringLength(const Common::String &text) const;
|
||||
int getStringHeight(const Common::String &text) const;
|
||||
virtual int getKernedStringLength(const Common::String &text) const;
|
||||
virtual int getBitmapStringLength(const Common::String &text) const;
|
||||
virtual int getStringHeight(const Common::String &text) const;
|
||||
|
||||
const void *getUserData() const { return _userData; }
|
||||
void setUserData(void *data) { _userData = data; }
|
||||
|
@ -90,6 +93,20 @@ private:
|
|||
void *_userData;
|
||||
};
|
||||
|
||||
class FontTTF : public Font
|
||||
{
|
||||
public:
|
||||
void loadTTF(const Common::String &filename, Common::SeekableReadStream *data, int size);
|
||||
|
||||
int32 getKernedHeight() const override { return _font->getFontHeight(); }
|
||||
int32 getBaseOffsetY() const override { return 0; }
|
||||
int32 getCharKernedWidth(unsigned char c) const override { return _font->getCharWidth(c); }
|
||||
|
||||
int getKernedStringLength(const Common::String &text) const override { return _font->getStringWidth(text); }
|
||||
|
||||
Graphics::Font *_font;
|
||||
};
|
||||
|
||||
} // end of namespace Grim
|
||||
|
||||
#endif
|
||||
|
|
|
@ -292,7 +292,10 @@ protected:
|
|||
Texture _specialtyTextures[_numSpecialtyTextures];
|
||||
static const int _gameHeight = 480;
|
||||
static const int _gameWidth = 640;
|
||||
static const int _globalHeight = 1080;
|
||||
static const int _globalWidth = 1920;
|
||||
float _scaleW, _scaleH;
|
||||
float _globalScaleW, _globalScaleH;
|
||||
int _screenWidth, _screenHeight;
|
||||
bool _isFullscreen;
|
||||
Shadow *_currentShadowArray;
|
||||
|
|
|
@ -138,6 +138,9 @@ byte *GfxOpenGL::setupScreen(int screenW, int screenH, bool fullscreen) {
|
|||
_scaleW = _screenWidth / (float)_gameWidth;
|
||||
_scaleH = _screenHeight / (float)_gameHeight;
|
||||
|
||||
_globalScaleW = _screenWidth / (float)_globalWidth;
|
||||
_globalScaleH = _screenHeight / (float)_globalHeight;
|
||||
|
||||
_isFullscreen = g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
|
||||
_useDepthShader = false;
|
||||
_useDimShader = false;
|
||||
|
@ -1456,8 +1459,76 @@ void GfxOpenGL::drawTextObject(const TextObject *text) {
|
|||
|
||||
glColor3ub(color.getRed(), color.getGreen(), color.getBlue());
|
||||
const FontUserData *userData = (const FontUserData *)font->getUserData();
|
||||
if (!userData)
|
||||
error("Could not get font userdata");
|
||||
if (!userData) {
|
||||
//error("Could not get font userdata");
|
||||
const FontTTF *f = static_cast<const FontTTF *>(font);
|
||||
Graphics::Font *gf = f->_font;
|
||||
Graphics::Surface surface;
|
||||
int height = 1024;
|
||||
int width = 1024;
|
||||
surface.create(height, width, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
||||
gf->drawString(&surface, text->getLines()[0], 0, 0, 1024, 0xFFFFFFFF);
|
||||
|
||||
|
||||
byte *bitmap = (byte *)surface.getPixels();
|
||||
|
||||
|
||||
GLuint texid;
|
||||
glGenTextures(1, &texid);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texid);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
|
||||
|
||||
float x = text->getX();
|
||||
|
||||
float y = text->getY();
|
||||
|
||||
if (!text->isGlobal()) {
|
||||
x -= gf->getStringWidth(text->getLines()[0]);
|
||||
x *= _globalScaleW;
|
||||
y *= _globalScaleH;
|
||||
|
||||
width *= _globalScaleW;
|
||||
height *= _globalScaleH;
|
||||
} else {
|
||||
x *= _scaleW;
|
||||
y *= _scaleH;
|
||||
|
||||
width *= _scaleW;
|
||||
height *= _scaleH;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texid);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(x, y);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex2f((x + width), y);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex2f((x + width), (y + height));
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex2f(x, (y + height));
|
||||
glEnd();
|
||||
|
||||
|
||||
glDeleteTextures(1, &texid);
|
||||
|
||||
surface.free();
|
||||
|
||||
glColor3f(1, 1, 1);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
glDepthMask(GL_TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
float sizeW = userData->size * _scaleW;
|
||||
float sizeH = userData->size * _scaleH;
|
||||
GLuint texture = userData->texture;
|
||||
|
@ -1473,9 +1544,8 @@ void GfxOpenGL::drawTextObject(const TextObject *text) {
|
|||
if (g_grim->getGameType() == GType_GRIM)
|
||||
w += font->getBaseOffsetY();
|
||||
float z = x + font->getCharStartingCol(character);
|
||||
// TODO: We can't scale in the remastered version
|
||||
//z *= _scaleW;
|
||||
//w *= _scaleH;
|
||||
z *= _scaleW;
|
||||
w *= _scaleH;
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
float width = 1 / 16.f;
|
||||
float cx = ((character - 1) % 16) / 16.0f;
|
||||
|
|
|
@ -693,7 +693,7 @@ void Lua_V1::GetFontDimensions() {
|
|||
Font *font = Font::getPool().getObject(lua_getuserdata(fontObj));
|
||||
|
||||
if (font) {
|
||||
int32 h = font->getBaseOffsetY();
|
||||
int32 h = font->getKernedHeight();
|
||||
int32 w = font->getCharKernedWidth('w');
|
||||
lua_pushnumber(w);
|
||||
lua_pushnumber(h);
|
||||
|
|
|
@ -361,7 +361,6 @@ void Lua_V1::ChangePrimitive() {
|
|||
if (lua_isnumber(height))
|
||||
/*y = (int)*/lua_getnumber(height);
|
||||
// TODO pmodify->setSize(x, y);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -132,8 +132,8 @@ void Lua_V1::GetTextObjectDimensions() {
|
|||
TextObject *textObject = gettextobject(textObj);
|
||||
lua_pushnumber(textObject->getBitmapWidth());
|
||||
lua_pushnumber(textObject->getBitmapHeight());
|
||||
lua_pushnumber(1);
|
||||
lua_pushnumber(1);
|
||||
lua_pushnumber(textObject->getX());
|
||||
lua_pushnumber(textObject->getY());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -361,6 +361,27 @@ Costume *ResourceLoader::loadCostume(const Common::String &filename, Actor *owne
|
|||
Font *ResourceLoader::loadFont(const Common::String &filename) {
|
||||
Common::SeekableReadStream *stream;
|
||||
|
||||
Common::String name = "FontsHD/" + filename + ".txt";
|
||||
stream = openNewStreamFile(name, true);
|
||||
if (stream) {
|
||||
Common::String line = stream->readLine();
|
||||
Common::String font;
|
||||
Common::String size;
|
||||
for (int i = 0; i < line.size(); ++i) {
|
||||
if (line[i] == ' ') {
|
||||
font = "FontsHD/" + Common::String(line.c_str(), i);
|
||||
size = Common::String(line.c_str() + i + 1, line.size() - i - 2);
|
||||
}
|
||||
}
|
||||
|
||||
int s = atoi(size.c_str());
|
||||
delete stream;
|
||||
stream = openNewStreamFile(font.c_str(), true);
|
||||
FontTTF *result = new FontTTF();
|
||||
result->loadTTF(font, stream, s);
|
||||
return result;
|
||||
}
|
||||
|
||||
stream = openNewStreamFile(filename.c_str(), true);
|
||||
if (!stream)
|
||||
error("Could not find font file %s", filename.c_str());
|
||||
|
|
|
@ -47,7 +47,7 @@ void TextObjectCommon::setLayer(int layer) {
|
|||
TextObject::TextObject() :
|
||||
TextObjectCommon(), _numberLines(1), _textID(""), _elapsedTime(0),
|
||||
_maxLineWidth(0), _lines(nullptr), _userData(nullptr), _created(false),
|
||||
_blastDraw(false), _isSpeech(false), _stackLevel(0) {
|
||||
_blastDraw(false), _isSpeech(false), _stackLevel(0), _global(false) {
|
||||
}
|
||||
|
||||
TextObject::~TextObject() {
|
||||
|
|
|
@ -101,6 +101,8 @@ public:
|
|||
void setBlastDraw() { _blastDraw = true; }
|
||||
bool isBlastDraw() { return _blastDraw; }
|
||||
|
||||
bool isGlobal() const { return _global; }
|
||||
|
||||
const void *getUserData() const { return _userData; }
|
||||
void setUserData(void *data) { _userData = data; }
|
||||
|
||||
|
@ -143,6 +145,7 @@ protected:
|
|||
bool _blastDraw;
|
||||
bool _isSpeech;
|
||||
bool _created;
|
||||
bool _global;
|
||||
|
||||
int _stackLevel;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue