Mercurial > otakunoraifu
diff font/font_face.cc @ 52:15a18fbe6f21
* Known bugs added to the README
* Code cleaning (0 -> NULL when needed, indentation, spaces, ...)
author | thib |
---|---|
date | Sat, 18 Apr 2009 18:35:39 +0000 |
parents | fa8511a21d05 |
children | 4416cfac86ae |
line wrap: on
line diff
--- a/font/font_face.cc +++ b/font/font_face.cc @@ -27,135 +27,135 @@ #include <stdlib.h> #include <stdio.h> -#include"font.h" -#include"font_peer.h" +#include "font.h" +#include "font_peer.h" #include <map> #include <string> #include <iostream> namespace XKFont { -class Cache : public std::map<unsigned int, Glyph*> { -public: - Cache() {} - ~Cache() { - iterator it; - for (it = begin(); it != end(); it++) - delete (it->second); + class Cache : public std::map<unsigned int, Glyph*> { + public: + Cache() {} + ~Cache() { + iterator it; + for (it = begin(); it != end(); it++) + delete (it->second); + } + }; + + Face::Face(const char *name_orig, int index, int hsize, int vsize) + { + cache = new Cache; + + /* name: ';' 区切りで複数指定可能 */ + char* name = new char[strlen(name_orig)+1]; + while(*name_orig != 0) { + const char* next_name = strchr(name_orig, ';'); + if (next_name) { + strncpy(name, name_orig, next_name - name_orig); + name[next_name-name_orig] = 0; + name_orig = next_name + 1; + } else { + strcpy(name, name_orig); + name_orig += strlen(name_orig); + } + if (strstr(name, "fn.dat")) { + peer.push_back(new PeerFn(name, index, hsize, vsize)); + } else if (strstr(name, ".ttf") || strstr(name, ".ttc")) { + peer.push_back(new PeerFt2(name, index, hsize, vsize)); +#if USE_X11 + } else { + peer.push_back(new PeerX11(name, index, hsize, vsize)); +#endif + } + } + delete[] name; + return; } -}; -Face::Face(const char *name_orig, int index, int hsize, int vsize) -{ - cache = new Cache; + Face::~Face() { + delete cache; + } + + Glyph* Face::GlyphLoad(unsigned int code) { + if (cache->count(code)) + return (*cache)[code]; - /* name: ';' 区切りで複数指定可能 */ - char* name = new char[strlen(name_orig)+1]; - while(*name_orig != 0) { - const char* next_name = strchr(name_orig, ';'); - if (next_name) { - strncpy(name, name_orig, next_name - name_orig); - name[next_name-name_orig] = 0; - name_orig = next_name + 1; - } else { - strcpy(name, name_orig); - name_orig += strlen(name_orig); + Glyph* g = new Glyph; + iterator it; + for (it=peer.begin(); it != peer.end(); it++) { + if ( (*it)->GlyphCreate(code, g)) break; + } + if (it == peer.end()) { + fprintf(stderr,"Cannot find glyph, code %04x\n",code); + g->bitmap_left = 0; + g->bitmap_top = 0; + g->bitmap.width = 0; + g->bitmap.rows = 0; + g->bitmap.buffer = new unsigned char[1]; + g->bitmap.buffer[0] = 0; + g->advance.x = 0; + g->advance.y = 0; } - if (strstr(name, "fn.dat")) { - peer.push_back(new PeerFn(name, index, hsize, vsize)); - } else if (strstr(name, ".ttf") || strstr(name, ".ttc")) { - peer.push_back(new PeerFt2(name, index, hsize, vsize)); -#if USE_X11 - } else { - peer.push_back(new PeerX11(name, index, hsize, vsize)); -#endif + (*cache)[code] = g; + return g; + } + + class FontImpl { + public: + std::map<int, Face*> cache; + std::string fontname; + int size; + ~FontImpl(); + }; + + FontImpl::~FontImpl() { + std::map<int,Face*>::iterator it; + for (it=cache.begin(); it!=cache.end(); it++) delete it->second; + } + + Font::Font(const char* name, int size) { + pimpl = new FontImpl; + pimpl->fontname = name; + pimpl->size = size; + vsize = size; + }; + + Font::~Font() { + delete pimpl; + } + + Face* Font::FaceLoad(double scale) { + std::map<int, Face*>& cache = pimpl->cache; + int size = int(scale * pimpl->size); + if (cache.find(size) != cache.end()) return cache[size]; + try { + Face* face = new Face(pimpl->fontname.c_str(), 0, size, size); + cache[size] = face; + return face; + } catch(...) { + std::cerr << "Cannot create font face; font "<<pimpl->fontname<<", size "<<size<<std::endl; + /* 別の大きさを探す */ + int i; + for (i=0; i<size; i++) { + if (cache.find(size-i) != cache.end()) return cache[size-i]; + if (cache.find(size+i) != cache.end()) return cache[size+i]; + try { + Face* face = new Face(pimpl->fontname.c_str(), 0, size-i, size-i); + cache[size-i] = face; + return face; + } catch(...) {}; + try { + Face* face = new Face(pimpl->fontname.c_str(), 0, size+i, size+i); + cache[size+i] = face; + return face; + } catch(...) {}; + } + /* 見つからない */ + throw; } } - delete[] name; - return; -} - -Face::~Face() { - delete cache; -} - -Glyph* -Face::GlyphLoad(unsigned int code) { - if (cache->count(code)) - return (*cache)[code]; - - Glyph* g = new Glyph; - iterator it; - for (it=peer.begin(); it != peer.end(); it++) { - if ( (*it)->GlyphCreate(code, g)) break; - } - if (it == peer.end()) { - fprintf(stderr,"Cannot find glyph, code %04x\n",code); - g->bitmap_left = 0; - g->bitmap_top = 0; - g->bitmap.width = 0; - g->bitmap.rows = 0; - g->bitmap.buffer = new unsigned char[1]; - g->bitmap.buffer[0] = 0; - g->advance.x = 0; - g->advance.y = 0; - } - (*cache)[code] = g; - return g; -} - -class FontImpl { -public: - std::map<int, Face*> cache; - std::string fontname; - int size; - ~FontImpl(); -}; - -FontImpl::~FontImpl() { - std::map<int,Face*>::iterator it; - for (it=cache.begin(); it!=cache.end(); it++) delete it->second; -} - -Font::Font(const char* name, int size) { - pimpl = new FontImpl; - pimpl->fontname = name; - pimpl->size = size; - vsize = size; -}; -Font::~Font() { - delete pimpl; -} -Face* -Font::FaceLoad(double scale) { - std::map<int, Face*>& cache = pimpl->cache; - int size = int(scale * pimpl->size); - if (cache.find(size) != cache.end()) return cache[size]; - try { - Face* face = new Face(pimpl->fontname.c_str(), 0, size, size); - cache[size] = face; - return face; - } catch(...) { - std::cerr << "Cannot create font face; font "<<pimpl->fontname<<", size "<<size<<std::endl; - /* 別の大きさを探す */ - int i; - for (i=0; i<size; i++) { - if (cache.find(size-i) != cache.end()) return cache[size-i]; - if (cache.find(size+i) != cache.end()) return cache[size+i]; - try { - Face* face = new Face(pimpl->fontname.c_str(), 0, size-i, size-i); - cache[size-i] = face; - return face; - } catch(...) {}; - try { - Face* face = new Face(pimpl->fontname.c_str(), 0, size+i, size+i); - cache[size+i] = face; - return face; - } catch(...) {}; - } - /* 見つからない */ - throw; - } -} } /* namespace XKFont */