diff --git a/binding-mri/bitmap-binding.cpp b/binding-mri/bitmap-binding.cpp index 4454bd1..ad06d6f 100644 --- a/binding-mri/bitmap-binding.cpp +++ b/binding-mri/bitmap-binding.cpp @@ -52,12 +52,14 @@ RB_METHOD(bitmapInitialize) setPrivateData(self, b); /* Wrap properties */ - Font *font = new Font(); - b->setFont(font); - font->setColor(new Color(*font->getColor())); + VALUE fontKlass = rb_const_get(rb_cObject, rb_intern("Font")); + VALUE fontObj = rb_obj_alloc(fontKlass); + rb_obj_call_init(fontObj, 0, 0); - VALUE fontProp = wrapProperty(self, font, "font", FontType); - wrapProperty(fontProp, font->getColor(), "color", ColorType); + Font *font = getPrivateData(fontObj); + b->setFont(font); + + rb_iv_set(self, "font", fontObj); return self; } diff --git a/binding-mri/font-binding.cpp b/binding-mri/font-binding.cpp index eacea9a..b270170 100644 --- a/binding-mri/font-binding.cpp +++ b/binding-mri/font-binding.cpp @@ -23,6 +23,9 @@ #include "binding-util.h" #include "binding-types.h" #include "exception.h" +#include "sharedstate.h" + +#include DEF_TYPE(Font); @@ -36,14 +39,16 @@ RB_METHOD(fontDoesExist) return rb_bool_new(Font::doesExist(name)); } +RB_METHOD(FontSetName); + RB_METHOD(fontInitialize) { - const char *name = 0; + VALUE name = Qnil; int size = 0; - rb_get_args(argc, argv, "|zi", &name, &size RB_ARG_END); + rb_get_args(argc, argv, "|oi", &name, &size RB_ARG_END); - Font *f = new Font(name, size); + Font *f = new Font(0, size); setPrivateData(self, f); @@ -51,6 +56,13 @@ RB_METHOD(fontInitialize) f->setColor(new Color(*f->getColor())); wrapProperty(self, f->getColor(), "color", ColorType); + if (NIL_P(name)) + name = rb_iv_get(rb_obj_class(self), "default_name"); + + /* Going over the 'name=' function automatically causes + * a possbile name array to be re-verified for existing fonts */ + FontSetName(1, &name, self); + return self; } @@ -77,21 +89,63 @@ RB_METHOD(FontGetName) { RB_UNUSED_PARAM; - Font *f = getPrivateData(self); + return rb_iv_get(self, "name"); +} - return rb_str_new_cstr(f->getName()); +static void +fontSetNameHelper(VALUE self, int argc, VALUE *argv, + const char *nameIv, char *outBuf, size_t outLen) +{ + rb_check_argc(argc, 1); + + VALUE arg = argv[0]; + int type = rb_type(arg); + + // Fixme: in RGSS3, specifying "" (and only that) as font name results in + // no text being drawn (everything else is substituted with Arial I think) + strncpy(outBuf, "", outLen); + + if (type == RUBY_T_STRING) + { + strncpy(outBuf, RSTRING_PTR(arg), outLen); + } + else if (type == RUBY_T_ARRAY) + { + for (long i = 0; i < RARRAY_LEN(arg); ++i) + { + VALUE str = rb_ary_entry(arg, i); + + /* Non-string objects are tolerated (ignored) */ + if (rb_type(str) != RUBY_T_STRING) + continue; + + const char *family = RSTRING_PTR(str); + + /* We only set the core Font object's name attribute + * to the actually existing font name */ + if (!shState->fontState().fontPresent(family)) + continue; + + strncpy(outBuf, family, outLen); + } + } + + /* RMXP doesn't even care if the argument type is + * something other than string/array. Whatever... */ + rb_iv_set(self, nameIv, arg); } RB_METHOD(FontSetName) { Font *f = getPrivateData(self); - VALUE name; - rb_get_args(argc, argv, "S", &name RB_ARG_END); + char result[256]; + fontSetNameHelper(self, argc, argv, "default_name", + result, sizeof(result)); - f->setName(RSTRING_PTR(name)); + f->setName(result); - return name; + return argv[0]; } #undef DEF_PROP_CHK_DISP @@ -124,18 +178,19 @@ DEF_KLASS_PROP(Font, bool, DefaultItalic, "b", rb_bool_new) RB_METHOD(FontGetDefaultName) { RB_UNUSED_PARAM; - return rb_str_new_cstr(Font::getDefaultName()); + + return rb_iv_get(self, "default_name"); } RB_METHOD(FontSetDefaultName) { - RB_UNUSED_PARAM; - VALUE nameObj; - rb_get_args(argc, argv, "S", &nameObj RB_ARG_END); + char result[256]; + fontSetNameHelper(self, argc, argv, "default_name", + result, sizeof(result)); - Font::setDefaultName(RSTRING_PTR(nameObj)); + Font::setDefaultName(result); - return nameObj; + return argv[0]; } RB_METHOD(FontGetDefaultColor) @@ -174,6 +229,7 @@ fontBindingInit() Font::setDefaultColor(new Color(*Font::getDefaultColor())); wrapProperty(klass, Font::getDefaultColor(), "default_color", ColorType); + rb_iv_set(klass, "default_name", rb_str_new_cstr(Font::getDefaultName())); INIT_KLASS_PROP_BIND(Font, DefaultName, "default_name"); INIT_KLASS_PROP_BIND(Font, DefaultSize, "default_size"); diff --git a/mkxp.conf.sample b/mkxp.conf.sample index 11fb146..bdf1a1b 100644 --- a/mkxp.conf.sample +++ b/mkxp.conf.sample @@ -113,3 +113,18 @@ # RTP=/path/to/rtp1 # RTP=/path/to/rtp2.zip # RTP=/path/to/game.rgssad + + +# Font substitutions allow drop-in replacements of fonts +# to be used without changing the RGSS scripts, +# eg. providing 'Open Sans' when the game thinkgs it's +# using 'Arial'. Font family to be substituted and +# replacement family are separated by one sole '>'. +# Be careful not to include any spaces. +# This is not connected to the built-in font, which is +# always used when a non-existing font family is +# requested by RGSS. +# (default: none) +# +# fontSub=Arial>Open Sans +# fontSub=Times New Roman>Liberation Serif diff --git a/src/config.cpp b/src/config.cpp index 7e3091f..4f15a51 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -83,6 +83,7 @@ void Config::read(int argc, char *argv[]) podesc.add_options() PO_DESC_ALL ("RTP", po::value()->composing()) + ("fontSub", po::value()->composing()) ; po::variables_map vm; @@ -115,6 +116,8 @@ void Config::read(int argc, char *argv[]) GUARD_ALL( rtps = vm["RTP"].as(); ); + GUARD_ALL( fontSubs = vm["fontSub"].as(); ); + #undef PO_DESC #undef PO_DESC_ALL } diff --git a/src/config.h b/src/config.h index 411ce51..2854672 100644 --- a/src/config.h +++ b/src/config.h @@ -54,6 +54,8 @@ struct Config std::string customScript; std::vector rtps; + std::vector fontSubs; + /* Game INI contents */ struct { std::string scripts; diff --git a/src/filesystem.cpp b/src/filesystem.cpp index bf38cea..6a731ce 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -21,6 +21,7 @@ #include "filesystem.h" +#include "font.h" #include "util.h" #include "exception.h" #include "boost-hash.h" @@ -498,6 +499,99 @@ static const PHYSFS_Archiver RGSS_Archiver = RGSS_closeArchive }; + +static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops) +{ + return static_cast(ops->hidden.unknown.data1); +} + +static Sint64 SDL_RWopsSize(SDL_RWops *ops) +{ + PHYSFS_File *f = sdlPHYS(ops); + + if (!f) + return -1; + + return PHYSFS_fileLength(f); +} + +static Sint64 SDL_RWopsSeek(SDL_RWops *ops, int64_t offset, int whence) +{ + PHYSFS_File *f = sdlPHYS(ops); + + if (!f) + return -1; + + int64_t base; + + switch (whence) + { + default: + case RW_SEEK_SET : + base = 0; + break; + case RW_SEEK_CUR : + base = PHYSFS_tell(f); + break; + case RW_SEEK_END : + base = PHYSFS_fileLength(f); + break; + } + + int result = PHYSFS_seek(f, base + offset); + + return (result != 0) ? PHYSFS_tell(f) : -1; +} + +static size_t SDL_RWopsRead(SDL_RWops *ops, void *buffer, size_t size, size_t maxnum) +{ + PHYSFS_File *f = sdlPHYS(ops); + + if (!f) + return 0; + + PHYSFS_sint64 result = PHYSFS_readBytes(f, buffer, size*maxnum); + + return (result != -1) ? (result / size) : 0; +} + +static size_t SDL_RWopsWrite(SDL_RWops *ops, const void *buffer, size_t size, size_t num) +{ + PHYSFS_File *f = sdlPHYS(ops); + + if (!f) + return 0; + + PHYSFS_sint64 result = PHYSFS_writeBytes(f, buffer, size*num); + + return (result != -1) ? (result / size) : 0; +} + +static int SDL_RWopsClose(SDL_RWops *ops) +{ + PHYSFS_File *f = sdlPHYS(ops); + + if (!f) + return -1; + + int result = PHYSFS_close(f); + + f = 0; + + return (result != 0) ? 0 : -1; +} + +static int SDL_RWopsCloseFree(SDL_RWops *ops) +{ + int result = SDL_RWopsClose(ops); + + SDL_FreeRW(ops); + + return result; +} + +const Uint32 SDL_RWOPS_PHYSFS = SDL_RWOPS_UNKNOWN+10; + struct FileSystemPrivate { /* Maps: lower case filename, To: actual (mixed case) filename. @@ -650,6 +744,24 @@ struct FileSystemPrivate return handle; } + + void initReadOps(PHYSFS_File *handle, + SDL_RWops &ops, + bool freeOnClose) + { + ops.size = SDL_RWopsSize; + ops.seek = SDL_RWopsSeek; + ops.read = SDL_RWopsRead; + ops.write = SDL_RWopsWrite; + + if (freeOnClose) + ops.close = SDL_RWopsCloseFree; + else + ops.close = SDL_RWopsClose; + + ops.type = SDL_RWOPS_PHYSFS; + ops.hidden.unknown.data1 = handle; + } }; FileSystem::FileSystem(const char *argv0, @@ -746,98 +858,59 @@ void FileSystem::createPathCache() p->havePathCache = true; } -static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops) +static void strToLower(std::string &str) { - return static_cast(ops->hidden.unknown.data1); + for (size_t i = 0; i < str.size(); ++i) + str[i] = tolower(str[i]); } -static Sint64 SDL_RWopsSize(SDL_RWops *ops) +struct FontSetsCBData { - PHYSFS_File *f = sdlPHYS(ops); + FileSystemPrivate *p; + SharedFontState *sfs; +}; - if (!f) - return -1; +static void fontSetEnumCB(void *data, const char *, + const char *fname) +{ + FontSetsCBData *d = static_cast(data); + FileSystemPrivate *p = d->p; - return PHYSFS_fileLength(f); + /* Only consider filenames with font extensions */ + const char *ext = p->findExt(fname); + + if (!ext) + return; + + std::string lower(ext); + strToLower(lower); + + if (!contains(p->extensions[FileSystem::Font], lower)) + return; + + std::string filename("Fonts/"); + filename += fname; + + PHYSFS_File *handle = PHYSFS_openRead(filename.c_str()); + + if (!handle) + return; + + SDL_RWops ops; + p->initReadOps(handle, ops, false); + + d->sfs->initFontSetCB(ops, filename); + + SDL_RWclose(&ops); } -static Sint64 SDL_RWopsSeek(SDL_RWops *ops, int64_t offset, int whence) +void FileSystem::initFontSets(SharedFontState &sfs) { - PHYSFS_File *f = sdlPHYS(ops); + FontSetsCBData d = { p, &sfs }; - if (!f) - return -1; - - int64_t base; - - switch (whence) - { - default: - case RW_SEEK_SET : - base = 0; - break; - case RW_SEEK_CUR : - base = PHYSFS_tell(f); - break; - case RW_SEEK_END : - base = PHYSFS_fileLength(f); - break; - } - - int result = PHYSFS_seek(f, base + offset); - - return (result != 0) ? PHYSFS_tell(f) : -1; + PHYSFS_enumerateFilesCallback("Fonts", fontSetEnumCB, &d); } -static size_t SDL_RWopsRead(SDL_RWops *ops, void *buffer, size_t size, size_t maxnum) -{ - PHYSFS_File *f = sdlPHYS(ops); - - if (!f) - return 0; - - PHYSFS_sint64 result = PHYSFS_readBytes(f, buffer, size*maxnum); - - return (result != -1) ? (result / size) : 0; -} - -static size_t SDL_RWopsWrite(SDL_RWops *ops, const void *buffer, size_t size, size_t num) -{ - PHYSFS_File *f = sdlPHYS(ops); - - if (!f) - return 0; - - PHYSFS_sint64 result = PHYSFS_writeBytes(f, buffer, size*num); - - return (result != -1) ? (result / size) : 0; -} - -static int SDL_RWopsClose(SDL_RWops *ops) -{ - PHYSFS_File *f = sdlPHYS(ops); - - if (!f) - return -1; - - int result = PHYSFS_close(f); - - f = 0; - - return (result != 0) ? 0 : -1; -} - -static int SDL_RWopsCloseFree(SDL_RWops *ops) -{ - int result = SDL_RWopsClose(ops); - - SDL_FreeRW(ops); - - return result; -} - -const Uint32 SDL_RWOPS_PHYSFS = SDL_RWOPS_UNKNOWN+10; - void FileSystem::openRead(SDL_RWops &ops, const char *filename, FileType type, @@ -846,18 +919,17 @@ void FileSystem::openRead(SDL_RWops &ops, { PHYSFS_File *handle = p->openReadHandle(filename, type, foundExt); - ops.size = SDL_RWopsSize; - ops.seek = SDL_RWopsSeek; - ops.read = SDL_RWopsRead; - ops.write = SDL_RWopsWrite; + p->initReadOps(handle, ops, freeOnClose); +} - if (freeOnClose) - ops.close = SDL_RWopsCloseFree; - else - ops.close = SDL_RWopsClose; +void FileSystem::openReadRaw(SDL_RWops &ops, + const char *filename, + bool freeOnClose) +{ + PHYSFS_File *handle = PHYSFS_openRead(filename); + assert(handle); - ops.type = SDL_RWOPS_PHYSFS; - ops.hidden.unknown.data1 = handle; + p->initReadOps(handle, ops, freeOnClose); } bool FileSystem::exists(const char *filename, FileType type) diff --git a/src/filesystem.h b/src/filesystem.h index a9ab2ef..b2230c8 100644 --- a/src/filesystem.h +++ b/src/filesystem.h @@ -25,6 +25,7 @@ #include struct FileSystemPrivate; +struct SharedFontState; class FileSystem { @@ -35,9 +36,13 @@ public: void addPath(const char *path); - /* Call this after the last 'addPath()' */ + /* Call these after the last 'addPath()' */ void createPathCache(); + /* Scans "Fonts/" and creates inventory of + * available font assets */ + void initFontSets(SharedFontState &sfs); + /* For extension supplementing */ enum FileType { @@ -53,6 +58,11 @@ public: bool freeOnClose = false, const char **foundExt = 0); + /* Circumvents extension supplementing */ + void openReadRaw(SDL_RWops &ops, + const char *filename, + bool freeOnClose = false); + bool exists(const char *filename, FileType type = Undefined); diff --git a/src/font.cpp b/src/font.cpp index 3dc8c10..a5dbed5 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -26,6 +26,7 @@ #include "exception.h" #include "boost-hash.h" #include "util.h" +#include "config.h" #include #include @@ -45,88 +46,151 @@ typedef std::pair FontKey; -static void strToLower(std::string &str) -{ - for (size_t i = 0; i < str.size(); ++i) - str[i] = tolower(str[i]); -} - -struct FontPoolPrivate -{ - BoostHash hash; -}; - -FontPool::FontPool() -{ - p = new FontPoolPrivate; -} - -FontPool::~FontPool() -{ - BoostHash::const_iterator iter; - for (iter = p->hash.cbegin(); iter != p->hash.cend(); ++iter) - TTF_CloseFont(iter->second); - - delete p; -} - static SDL_RWops *openBundledFont() { return SDL_RWFromConstMem(BNDL_F_D(BUNDLED_FONT), BNDL_F_L(BUNDLED_FONT)); } -_TTF_Font *FontPool::request(const char *filename, - int size) +struct FontSet { - // FIXME Find out how font path resolution is done in VX/Ace - std::string nameKey(filename); - strToLower(nameKey); - strReplace(nameKey, ' ', '_'); + /* 'Regular' style */ + std::string regular; - bool useBundled = false; - std::string path = std::string("Fonts/") + nameKey; - if (!shState->fileSystem().exists(path.c_str(), FileSystem::Font)) + /* Any other styles (used in case no 'Regular' exists) */ + std::string other; +}; + +struct SharedFontStatePrivate +{ + /* Maps: font family name, To: substituted family name, + * as specified via configuration file / arguments */ + BoostHash subs; + + /* Maps: font family name, To: set of physical + * font filenames located in "Fonts/" */ + BoostHash sets; + + /* Pool of already opened fonts; once opened, they are reused + * and never closed until the termination of the program */ + BoostHash pool; +}; + +SharedFontState::SharedFontState(const Config &conf) +{ + p = new SharedFontStatePrivate; + + /* Parse font substitutions */ + for (size_t i = 0; i < conf.fontSubs.size(); ++i) { - /* Use the same name key for the bundled font - * even when it resulted from multiple different - * font name requests. The space at the front is - * to prevent collisions (spaces are normally - * replaced with '_' */ - useBundled = true; - nameKey = " bundled"; + const std::string &raw = conf.fontSubs[i]; + size_t sepPos = raw.find_first_of('>'); + + if (sepPos == std::string::npos) + continue; + + std::string from = raw.substr(0, sepPos); + std::string to = raw.substr(sepPos+1); + + p->subs.insert(from, to); + } +} + +SharedFontState::~SharedFontState() +{ + BoostHash::const_iterator iter; + for (iter = p->pool.cbegin(); iter != p->pool.cend(); ++iter) + TTF_CloseFont(iter->second); + + delete p; +} + +void SharedFontState::initFontSetCB(SDL_RWops &ops, + const std::string &filename) +{ + TTF_Font *font = TTF_OpenFontRW(&ops, 0, 0); + + if (!font) + return; + + std::string family = TTF_FontFaceFamilyName(font); + std::string style = TTF_FontFaceStyleName(font); + + TTF_CloseFont(font); + + FontSet &set = p->sets[family]; + + if (style == "Regular") + set.regular = filename; + else + set.other = filename; +} + +_TTF_Font *SharedFontState::getFont(std::string family, + int size) +{ + /* Check for substitutions */ + if (p->subs.contains(family)) + family = p->subs[family]; + + /* Find out if the font asset exists */ + const FontSet &req = p->sets[family]; + + if (req.regular.empty() && req.other.empty()) + { + /* Doesn't exist; use built-in font */ + family = ""; } - FontKey key(nameKey, size); + FontKey key(family, size); - TTF_Font *font = p->hash.value(key, 0); + TTF_Font *font = p->pool.value(key); if (font) return font; - /* Not in hash, open */ + /* Not in pool; open new handle */ SDL_RWops *ops; - if (useBundled) + if (family.empty()) { + /* Built-in font */ ops = openBundledFont(); } else { + /* Use 'other' path as alternative in case + * we have no 'regular' styled font asset */ + const char *path = !req.regular.empty() + ? req.regular.c_str() : req.other.c_str(); + ops = SDL_AllocRW(); - shState->fileSystem().openRead(*ops, path.c_str(), FileSystem::Font, true); + shState->fileSystem().openReadRaw(*ops, path, true); } // FIXME 0.9 is guesswork at this point - font = TTF_OpenFontRW(ops, 1, (float) size * .90); +// float gamma = (96.0/45.0)*(5.0/14.0)*(size-5); +// font = TTF_OpenFontRW(ops, 1, gamma /** .90*/); + font = TTF_OpenFontRW(ops, 1, size* .90); if (!font) - throw Exception(Exception::SDLError, "SDL: %s", SDL_GetError()); + throw Exception(Exception::SDLError, "%s", SDL_GetError()); - p->hash.insert(key, font); + p->pool.insert(key, font); return font; } +bool SharedFontState::fontPresent(std::string family) +{ + /* Check for substitutions */ + if (p->subs.contains(family)) + family = p->subs[family]; + + const FontSet &set = p->sets[family]; + + return !(set.regular.empty() && set.other.empty()); +} + struct FontPrivate { @@ -183,9 +247,7 @@ Color FontPrivate::defaultColorTmp(255, 255, 255, 255); bool Font::doesExist(const char *name) { - std::string path = std::string("Fonts/") + std::string(name); - - return shState->fileSystem().exists(path.c_str(), FileSystem::Font); + return shState->fontState().fontPresent(name); } Font::Font(const char *name, @@ -223,6 +285,10 @@ void Font::setSize(int value) if (p->size == value) return; + /* Catch illegal values (according to RMXP) */ + if (value < 6 || value > 96) + throw Exception(Exception::ArgumentError, "%s", "bad value for size"); + p->size = value; p->sdlFont = 0; } @@ -253,8 +319,8 @@ void Font::setDefaultName(const char *value) _TTF_Font *Font::getSdlFont() { if (!p->sdlFont) - p->sdlFont = shState->fontPool().request(p->name.c_str(), - p->size); + p->sdlFont = shState->fontState().getFont(p->name.c_str(), + p->size); int style = TTF_STYLE_NORMAL; diff --git a/src/font.h b/src/font.h index 3c73b54..df25001 100644 --- a/src/font.h +++ b/src/font.h @@ -25,22 +25,50 @@ #include "etc.h" #include "util.h" +struct SDL_RWops; struct _TTF_Font; -struct FontPoolPrivate; +struct Config; -class FontPool +struct SharedFontStatePrivate; + +class SharedFontState { public: - FontPool(); - ~FontPool(); + SharedFontState(const Config &conf); + ~SharedFontState(); - _TTF_Font *request(const char *filename, + /* Called from FileSystem during font cache initialization + * (when "Fonts/" is scanned for available assets). + * 'ops' is an opened handle to a possible font file, + * 'filename' is the corresponding path */ + void initFontSetCB(SDL_RWops &ops, + const std::string &filename); + + _TTF_Font *getFont(std::string family, int size); + bool fontPresent(std::string family); + private: - FontPoolPrivate *p; + SharedFontStatePrivate *p; }; +/* Concerning Font::name/defaultName : + * In RGSS, this is not actually a string; any type of + * object is accepted, however anything but strings and + * arrays is ignored (and text drawing turns blank). + * Single strings are interpreted as font family names, + * and directly passed to the underlying C++ object; + * arrays however are searched for the first string + * object corresponding to a valid font family name, + * and rendering is done with that. In mkxp, we pass + * this first valid font family as the 'name' attribute + * back to the C++ object on assignment and object + * creation (in case Font.default_name is also an array). + * Invalid parameters (things other than strings or + * arrays not containing any valid family name) are + * passed back as "". */ + struct FontPrivate; class Font @@ -57,9 +85,9 @@ public: const char *getName() const; void setName(const char *value); - DECL_ATTR( Size, int ) - DECL_ATTR( Bold, bool ) - DECL_ATTR( Italic, bool ) + DECL_ATTR( Size, int ) + DECL_ATTR( Bold, bool ) + DECL_ATTR( Italic, bool ) DECL_ATTR( Color, Color* ) DECL_ATTR_STATIC( DefaultName, const char* ) diff --git a/src/sharedstate.cpp b/src/sharedstate.cpp index 7d0b587..c681776 100644 --- a/src/sharedstate.cpp +++ b/src/sharedstate.cpp @@ -67,8 +67,8 @@ struct SharedStatePrivate ShaderSet shaders; TexPool texPool; - FontPool fontPool; + SharedFontState fontState; Font *defaultFont; TEX::ID globalTex; @@ -90,6 +90,7 @@ struct SharedStatePrivate rtData(*threadData), config(threadData->config), graphics(threadData), + fontState(threadData->config), stampCounter(0) { if (!config.gameFolder.empty()) @@ -121,6 +122,8 @@ struct SharedStatePrivate if (config.pathCache) fileSystem.createPathCache(); + fileSystem.initFontSets(fontState); + globalTexW = 128; globalTexH = 64; @@ -206,8 +209,8 @@ GSATT(Audio&, audio) GSATT(GLState&, _glState) GSATT(ShaderSet&, shaders) GSATT(TexPool&, texPool) -GSATT(FontPool&, fontPool) GSATT(Quad&, gpQuad) +GSATT(SharedFontState&, fontState) void SharedState::setBindingData(void *data) { diff --git a/src/sharedstate.h b/src/sharedstate.h index c389f1f..9b1c22a 100644 --- a/src/sharedstate.h +++ b/src/sharedstate.h @@ -43,8 +43,8 @@ class Input; class Audio; class GLState; class TexPool; -class FontPool; class Font; +class SharedFontState; struct GlobalIBO; struct Config; struct Vec2i; @@ -74,8 +74,8 @@ struct SharedState ShaderSet &shaders(); TexPool &texPool(); - FontPool &fontPool(); + SharedFontState &fontState(); Font &defaultFont(); sigc::signal prepareDraw; diff --git a/src/tilemap.cpp b/src/tilemap.cpp index 88cab6e..2cdf6ba 100644 --- a/src/tilemap.cpp +++ b/src/tilemap.cpp @@ -48,13 +48,6 @@ extern const StaticRect autotileRects[]; typedef std::vector SVVector; typedef struct { SVVector v[4]; } TileVBuffer; -/* Check if [C]ontainer contains [V]alue */ -template -inline bool contains(const C &c, const V &v) -{ - return std::find(c.begin(), c.end(), v) != c.end(); -} - static const int tilesetW = 8 * 32; static const int autotileW = 3 * 32; static const int autotileH = 4 * 32; diff --git a/src/util.h b/src/util.h index 6a77ac2..17f76e4 100644 --- a/src/util.h +++ b/src/util.h @@ -24,6 +24,7 @@ #include #include +#include static inline int wrapRange(int value, int min, int max) @@ -93,6 +94,13 @@ inline void strReplace(std::string &str, str[i] = after; } +/* Check if [C]ontainer contains [V]alue */ +template +inline bool contains(const C &c, const V &v) +{ + return std::find(c.begin(), c.end(), v) != c.end(); +} + #define ARRAY_SIZE(obj) (sizeof(obj) / sizeof((obj)[0])) #define elementsN(obj) const int obj##N = ARRAY_SIZE(obj)