Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
22 KB
Referenced Files
None
Subscribers
None
diff --git a/util/font.cpp b/util/font.cpp
index 2cc68e5d..71f70c06 100644
--- a/util/font.cpp
+++ b/util/font.cpp
@@ -1,148 +1,153 @@
#include <allegro.h>
#include "font.h"
#include "init.h"
#include "factory/font_factory.h"
using namespace std;
Font::Font(){
}
Font::~Font(){
}
AllegroFont::AllegroFont( const FONT * const font ):
font( font ){
}
AllegroFont::AllegroFont( const AllegroFont & copy ):
font( copy.getInternalFont() ){
}
AllegroFont::~AllegroFont(){
}
int AllegroFont::textLength( const char * text ) const{
return text_length( getInternalFont(), text );
}
int AllegroFont::getHeight( const string & str ) const {
return getHeight();
}
int AllegroFont::getHeight() const {
return text_height( getInternalFont() );
}
void AllegroFont::setSize( const int x, const int y ){
}
int AllegroFont::getSizeX() const {
return 0;
}
int AllegroFont::getSizeY() const {
return 0;
}
void AllegroFont::printf( int x, int y, int xSize, int ySize, int color, const Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
uvszprintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
textout_ex( work.getBitmap(), getInternalFont(), buf, x, y, color, -1 );
}
void AllegroFont::printf( int x, int y, int color, const Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
uvszprintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
textout_ex( work.getBitmap(), getInternalFont(), buf, x, y, color, -1 );
}
const Font & Font::getDefaultFont(){
// return getFont( "tmp/comic.ttf" );
return getFont( "bios", 16, 16 );
}
const Font & Font::getFont( const string & name, const int x, const int y ){
- return *FontFactory::getFont( name, x, y );
+ Font & font = *FontFactory::getFont(name, x, y);
+ /* sanity check */
+ if (font.getHeight("A") == 0){
+ return getDefaultFont();
+ }
+ return font;
}
FreeTypeFont::FreeTypeFont( const string & str ):
sizeX( 16 ),
sizeY( 16 ),
own(true){
this->font = new ftalleg::freetype( str, getSizeX(), getSizeY() );
}
int FreeTypeFont::getHeight( const string & str ) const {
return this->font->getHeight( str );
}
int FreeTypeFont::getHeight() const {
return getHeight( "A" );
}
int FreeTypeFont::textLength( const char * text ) const {
return this->font->getLength( string( text ) );
}
void FreeTypeFont::printf( int x, int y, int xSize, int ySize, int color, const Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
vsnprintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
int old_x = 0;
int old_y = 0;
this->font->getSize(&old_x, &old_y);
this->font->setSize(xSize, ySize);
this->font->render( x, y, color, work.getBitmap(), ftalleg::freetype::ftLeft, string( buf ), 0 );
this->font->setSize(old_x, old_y);
}
void FreeTypeFont::printf( int x, int y, int color, const Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
vsnprintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
this->font->render( x, y, color, work.getBitmap(), ftalleg::freetype::ftLeft, string( buf ), 0 );
}
void FreeTypeFont::setSize( const int x, const int y ){
this->sizeX = x;
this->sizeY = y;
this->font->setSize( this->sizeX, this->sizeY );
}
int FreeTypeFont::getSizeX() const {
return this->sizeX;
}
int FreeTypeFont::getSizeY() const {
return this->sizeY;
}
FreeTypeFont::~FreeTypeFont(){
// cout << "Delete font " << this->font << endl;
if (own){
delete this->font;
}
}
diff --git a/util/ftalleg.cpp b/util/ftalleg.cpp
index e1ed6f02..b9dc0524 100644
--- a/util/ftalleg.cpp
+++ b/util/ftalleg.cpp
@@ -1,500 +1,521 @@
/*
--------------
About
--------------
A Freetype wrapper for use with allegro
Feel free to do whatever you like with this, by all means enjoy!
Just add it to your project
--------------
Linking
--------------
on linux:
g++ `freetype-config --cflags` ftalleg.cpp myfiles.cpp `freetype-config --libs` `allegro-config --libs`
on windows (you may need to include the freetype dir location, ie -Ic:/mingw/include):
g++ ftalleg.cpp myfiles.cpp -lfreetype -lalleg
--------------
Disclaimer
--------------
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE
SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef FT_FONT_CPP
#define FT_FONT_CPP
#include <allegro.h>
#ifdef _WIN32
#include <winalleg.h>
#endif
#include "ftalleg.h"
#include <iostream>
#include <sstream>
#include <cassert>
+#include <exception>
namespace ftalleg{
+ Exception::Exception():
+ std::exception(){
+ }
+
+ Exception::Exception(const std::string reason):
+ std::exception(),
+ reason(reason){
+ }
+
+ Exception::~Exception() throw(){
+ }
+
typedef void (*pixeler)( BITMAP * bitmap, int x, int y, int color );
static int fixColor(const unsigned char *c,short grays){
// Safety checks
assert(c != 0);
assert(grays != 1);
// invariant: c can be dereferenced safely
// invariant: (grays - 1) != 0, thus it can be used as divisor.
int red = *c * 255 / (grays - 1);
int green = *c * 255 / (grays - 1);
int blue = *c * 255 / (grays - 1);
//alpha = *c * 255 / (grays - 1);
return makecol(red,green,blue);
}
// Static count of instances of fonts to track library
static int instances=0;
static FT_Library ftLibrary = 0;
character::character() {
}
character::~character() {
// if(line)delete [] line;
}
fontSize::fontSize() {
- width = height = italics = 0;
+ width = height = italics = angle = 0;
}
fontSize::~fontSize() {
}
bool fontSize::operator<(const fontSize &fs) const {
return (width<fs.width || height<fs.height || italics<fs.italics);
}
+ /* im not sure this is a very unique key.. */
int fontSize::createKey() const {
return ((width+10) * (height+20) * (italics+250));
}
//! Constructor
freetype::freetype( const std::string & str, const int x, const int y ){
//Load library
if ( !ftLibrary ){
FT_Init_FreeType(&ftLibrary);
}
instances++;
faceLoaded = kerning = false;
currentIndex=0;
currentFilename="";
faceName="";
currentChar = new character;
systemName="";
internalFix = false;
this->load( str, 0, x, y );
}
//! Destructor
freetype::~freetype(){
//if(face!=NULL)FT_Done_Face(face);
if ( instances > 0 ){
instances--;
}
if ( instances == 0 ){
FT_Done_FreeType( ftLibrary );
}
if ( currentChar ){
delete currentChar;
}
}
// Extract glyph
character freetype::extractGlyph(signed long unicode){
int w, h, ew;
character tempChar;
// Translate it according to the given italics
double italics = (double)(size.italics)*GLYPH_PI/180;
FT_Matrix matrix;
matrix.xx = 0x10000L;
matrix.xy = (FT_Fixed)( sin( italics ) * (GLYPH_SQRT2*0x10000L) );
matrix.yx = 0;
matrix.yy = 0x10000L;
FT_Set_Transform( face, &matrix, 0 );
FT_Load_Char(face, unicode, FT_LOAD_TARGET_NORMAL | FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT);
w = face->glyph->bitmap.width;
h = face->glyph->bitmap.rows;
ew = 0;
if (!w)ew = 1;
if (!h)h = 1;
tempChar.width = (w + ew);
tempChar.height = h;
tempChar.rows = face->glyph->bitmap.rows;
tempChar.grays = face->glyph->bitmap.num_grays;
tempChar.pitch = face->glyph->bitmap.pitch;
tempChar.line = new unsigned char[tempChar.rows * tempChar.pitch];
memcpy(tempChar.line,face->glyph->bitmap.buffer,tempChar.rows * tempChar.pitch);
tempChar.left = face->glyph->bitmap_left;
tempChar.top = face->glyph->bitmap_top;
tempChar.right = face->glyph->advance.x >> 6;
tempChar.unicode = unicode;
tempChar.length = ((w + ew)+face->glyph->advance.x) >> 6;
return tempChar;
}
// Create single index
void freetype::createIndex(){
std::map<int, std::map<signed long, character> >::iterator p;
p = fontTable.find(size.createKey());
if ( p == fontTable.end() ){
FT_Set_Pixel_Sizes(face, size.width, size.height);
FT_UInt g;
FT_ULong unicode = FT_Get_First_Char(face, &g);
std::map<signed long, character>tempMap;
while ( g ){
tempMap.insert(std::make_pair(unicode,extractGlyph(unicode)));
unicode = FT_Get_Next_Char(face, unicode, &g);
}
fontTable.insert(std::make_pair(size.createKey(),tempMap));
}
+
+ if (fontTable.find(size.createKey()) == fontTable.end()){
+ printf("ftalleg: inconsistency error\n");
+ throw std::exception();
+ }
}
pixeler getPutPixel(){
switch( get_color_depth() ){
case 8 : return _putpixel;
case 15 : return _putpixel15;
case 16 : return _putpixel16;
case 24 : return _putpixel24;
case 32 : return _putpixel32;
default : return putpixel;
}
}
// Render a character from the lookup table
void freetype::drawCharacter(signed long unicode, int &x1, int &y1, BITMAP *bitmap, const int &color){
pixeler putter = getPutPixel();
std::map<int, std::map<signed long, character> >::iterator ft;
ft = fontTable.find(size.createKey());
if ( ft!=fontTable.end() ){
std::map<signed long, character>::iterator p;
p = (ft->second).find(unicode);
if(p!=(ft->second).end())
{
const character & tempChar = p->second;
unsigned char *line = tempChar.line;
for (int y = 0; y < tempChar.rows; y++)
{
unsigned char *buffer = line;
for (int x = 0; x < tempChar.width; x++)
{
int col = fixColor(buffer++,tempChar.grays);
if((getr(col)< 50) || (getg(col)< 50) || (getb(col)< 50))continue;
int red = getr(col) * getr(color) / 255;
int green = getg(col) * getg(color) / 255;
int blue = getb(col) * getb(color) / 255;
//col.alpha= col.alpha * color.alpha / 255;
// putpixel(bitmap,x1+tempChar.left+x,y1 - tempChar.top+y + size.height,makecol(red,blue,green));
/* dangerous! putter is probably one of the _putpixel* routines so if x or y are off the bitmap
* you will get a segfault
*/
// putter(bitmap,x1+tempChar.left+x,y1 - tempChar.top+y + size.height,makecol(red,blue,green));
putter = 0;
putpixel(bitmap,x1+tempChar.left+x,y1 - tempChar.top + y + size.height, makecol(red,green,blue));
}
line += tempChar.pitch;
}
x1+=tempChar.right;
}
}
}
//! Load font from memory
bool freetype::load(const unsigned char *memoryFont, unsigned int length, int index, unsigned int width, unsigned int height)
{
if(!FT_New_Memory_Face(ftLibrary,memoryFont, length,index,&face))
{
currentFilename = "memoryFont";
currentIndex = index;
faceLoaded = true;
size.italics = 0;
setSize(width, height);
if(FT_HAS_GLYPH_NAMES(face))
{
char buff[1024];
if(!FT_Get_Glyph_Name(face,currentIndex,buff,sizeof(buff)))
{
faceName = currentFilename;
}
else faceName = std::string(buff);
}
else
{
faceName = currentFilename;
}
if(FT_HAS_KERNING(face))kerning=true;
else kerning = false;
}
else
{
faceLoaded=false;
std::cout << "Load system font failed\n";
}
return faceLoaded;
}
//! Load font from file
bool freetype::load(const std::string & filename, int index, unsigned int width, unsigned int height)
{
if(!FT_New_Face(ftLibrary,filename.c_str(),index,&face))
{
currentFilename = filename;
currentIndex = index;
faceLoaded = true;
size.italics = 0;
setSize(width, height);
if(FT_HAS_GLYPH_NAMES(face))
{
char buff[1024];
if(!FT_Get_Glyph_Name(face,currentIndex,buff,sizeof(buff)))
{
faceName = currentFilename;
}
else faceName = std::string(buff);
}
else
{
faceName = currentFilename;
}
if(FT_HAS_KERNING(face))kerning=true;
else kerning = false;
}
else
{
faceLoaded=false;
}
return faceLoaded;
}
//! Get text length
int freetype::getLength(const std::string & text)
{
int length=0;
std::map<int, std::map<signed long, character> >::iterator ft;
ft = fontTable.find(size.createKey());
if(ft!=fontTable.end())
{
for(unsigned int i = 0; i<text.length();++i)
{
std::map<signed long, character>::iterator p;
p = (ft->second).find(text[i]);
if(p!=(ft->second).end())
{
if(p!=fontTable[size.createKey()].end())
{
length+=(p->second).length;
}
}
}
}
return length;
}
//! Render font to a bitmap
void freetype::render(int x, int y, const int & color, BITMAP *bmp, ftAlign alignment, const std::string & text, int marker ...)
{
if(faceLoaded)
{
int rend_x=0;
int rend_y=0;
std::ostringstream str;
// Get extra arguments
va_list ap;
va_start(ap,marker);
for(unsigned int i = 0; i<text.length();++i)
{
if(text[i]=='%')
{
if(text[i+1]=='s')
{
str << va_arg(ap,char *);
++i;
}
else if(text[i+1]=='d'||text[i+1]=='i')
{
str << va_arg(ap,signed int);
++i;
}
else if(text[i+1]=='c')
{
str << (char)va_arg(ap,int);
++i;
}
else str << text[i];
}
else
{
str << text[i];
}
}
va_end(ap);
std::string fixedText(str.str());
switch(alignment)
{
case ftLeft:
rend_x=x;
rend_y=y;
break;
case ftCenter:
rend_x = x - getLength(fixedText)/2;
rend_y=y;
break;
case ftRight:
rend_x = x - getLength(fixedText);
rend_y=y;
break;
default:
rend_x=x;
rend_y=y;
break;
}
int previous = 0;
int next = 0;
for(unsigned int i = 0; i<fixedText.length();++i){
if(kerning && previous && next){
next = FT_Get_Char_Index( face, fixedText[i] );
FT_Vector delta;
FT_Get_Kerning( face, previous, next, FT_KERNING_DEFAULT, &delta );
rend_x += delta.x >> 6;
previous = next;
}
drawCharacter(fixedText[i],rend_x, rend_y, bmp, color);
}
}
}
int freetype::calculateMaximumHeight(){
std::map<int, std::map<signed long, character> >::iterator ft;
ft = fontTable.find(size.createKey());
int top = 0;
long code = 0;
if ( ft != fontTable.end() ){
std::map<signed long, character>::iterator p;
std::map< signed long, character > & map = ft->second;
for ( p = map.begin(); p != map.end(); p++ ){
const character & ch = p->second;
printf( "%c( %ld ). top = %d. rows = %d. total = %d\n", (char) ch.unicode, ch.unicode, ch.top, ch.rows, ch.top + ch.rows );
if ( ch.top + ch.rows > top ){
code = ch.unicode;
top = ch.top + ch.rows;
}
}
}
printf( "Largest letter = %ld\n", code );
return top;
}
int freetype::height( long code ) const {
std::map<int, std::map<signed long, character> >::const_iterator ft;
ft = fontTable.find( size.createKey() );
if ( ft != fontTable.end() ){
std::map<signed long, character>::const_iterator p;
p = (ft->second).find( code );
if ( p != (ft->second).end() ){
const character & temp = p->second;
// printf( "%c top = %d rows = %d\n", (char) code, temp.top, temp.rows );
return temp.top + temp.rows;
}
- }
- return 0;
+ } else {
+ throw Exception("Internal inconsistency");
+ }
+
+ return 0;
}
int freetype::calculateHeight( const std::string & str ) const {
int max = 0;
for ( unsigned int i = 0; i < str.length(); i++ ){
int q = height( str[ i ] );
// printf( "Height of %c is %d\n", str[ i ], q );
if ( q > max ){
max = q;
}
}
return max;
}
//! Set size
void freetype::setSize( unsigned int w, unsigned int h){
if ( w != size.width || h != size.height ){
- if(internalFix)return;
- if(w<=0 || h<=0)return;
- size.width=w;
- size.height=h;
+ if (internalFix)return;
+ if (w<=0 || h<=0)return;
+ size.width = w;
+ size.height = h;
createIndex();
// maximumHeight = calculateMaximumHeight();
}
}
//! Set italics
- void freetype::setItalics(int i)
- {
+ void freetype::setItalics(int i){
if(internalFix)return;
if(i<-45)i=(-45);
else if(i>45)i=45;
size.italics = i;
createIndex();
}
void freetype::getSize(int * w, int * h) const {
*w = size.width;
*h = size.height;
}
//! Get Width
int freetype::getWidth() const {
return size.width;
}
//! Get Height
int freetype::getHeight( const std::string & str ) const {
// return size.height;
return calculateHeight( str );
}
//! Get Italics
int freetype::getItalics()
{
return size.italics;
}
}
#endif /* FONT_BASE_CPP */
diff --git a/util/ftalleg.h b/util/ftalleg.h
index e88d1eb5..7aea0456 100644
--- a/util/ftalleg.h
+++ b/util/ftalleg.h
@@ -1,220 +1,236 @@
/*
--------------
About
--------------
A Freetype wrapper for use with allegro
Feel free to do whatever you like with this, by all means enjoy!
Just add it to your project
--------------
Linking
--------------
on linux:
g++ `freetype-config --cflags` ftalleg.cpp myfiles.cpp `freetype-config --libs` `allegro-config --libs`
on windows (you may need to include the freetype dir location, ie -Ic:/mingw/include):
g++ ftalleg.cpp myfiles.cpp -lfreetype -lalleg
--------------
Disclaimer
--------------
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE
SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef FT_FONT_H
#define FT_FONT_H
#ifdef _WIN32
#define BITMAP dummyBITMAP
#include <windows.h>
#undef BITMAP
#endif
// #include <allegro.h>
#include <map>
#include <string>
#include <math.h>
+#include <exception>
#include <ft2build.h>
#include FT_FREETYPE_H
#define GLYPH_PI 3.14159265358979323846
#define GLYPH_SQRT2 1.41421356237309504880
struct BITMAP;
-namespace ftalleg
-{
+namespace ftalleg {
+
+ class Exception: public std::exception {
+ public:
+ Exception();
+ Exception(const std::string reason);
+
+ inline const std::string & getReason() const {
+ return reason;
+ }
+
+ virtual ~Exception() throw();
+
+ protected:
+ std::string reason;
+ };
+
//! Internal class for freetype to use
/*!
* This holds necessary information regarding a character \n
* from Freetype.
*/
class character
{
public:
//! Constructor
character();
//! Destructor
~character();
//! Unicode representation of character
signed long unicode;
//! Width of character
int width;
//! Height of character
int height;
//! Space on the left of a character (assists on positioning the character)
int left;
//! Space on top of the character (assists on positioning the character)
int top;
//! Space on the right of a character (assists on positioning the character)
int right;
//! Pitch of a character (assists on positioning the character)
int pitch;
//! Amount of shades of grays the FT_Bitmap holds
int grays;
//! Entire rows of the FT_Bitmap
int rows;
//! Entire length of the character with spacing and all
int length;
//! FT_Bitmap raw data
unsigned char *line;
};
//! Internal class for freetype to use
/*!
* Properties used for indexing a given font according to its size and matrix \n
*/
class fontSize
{
public:
fontSize();
~fontSize();
FT_UInt width;
FT_UInt height;
int italics;
int angle;
bool operator<(const fontSize &fs) const;
int createKey() const;
};
//! Freetype based font system
/*!
* Allows us to use freetype in allegro
*/
class freetype
{
private:
//! Filename
std::string currentFilename;
//! Is the face loaded
bool faceLoaded;
//! Does the face have kerning
bool kerning;
//! Current index default 0
int currentIndex;
//! for internal use disregard
bool internalFix;
int maximumHeight;
//! Font size
fontSize size;
//! Current Set system name
std::string systemName;
//! Face
FT_Face face;
//! Face Name
std::string faceName;
//! Current character
character *currentChar;
//! Lookup Table by size
std::map<int, std::map<signed long, character> >fontTable;
//! Extract glyph
character extractGlyph(signed long unicode);
int calculateMaximumHeight();
//! Create single index
void createIndex();
//! Render a character from the lookup table (utilizing the workBitmap)
void drawCharacter(signed long unicode, int &x1, int &y1, BITMAP *bitmap, const int & color);
int height( long code ) const;
int calculateHeight( const std::string & str ) const;
public:
//! Constructor
freetype( const std::string & str, const int x, const int y );
//! Destructor
~freetype();
//! Enum list of alignments
enum ftAlign
{
ftLeft = 0,
ftCenter = 1,
ftRight = 2
};
//! Load font from memory
bool load(const unsigned char *memoryFont, unsigned int length, int index, unsigned int width, unsigned int height);
//! Load font from file
bool load(const std::string & filename, int index, unsigned int width, unsigned int height);
//! Get text length
int getLength(const std::string & text);
//! Render font to a bitmap
void render(int x, int y, const int & color, BITMAP *bmp, ftAlign alignment, const std::string & text, int marker, ...);
//! Set size
void setSize( unsigned int w, unsigned int h);
//! Set italics
void setItalics(int i);
/* get the size attributes (close to width/height) */
void getSize(int * w, int * h) const;
//! Get Width
int getWidth() const;
//! Get Height
int getHeight( const std::string & str ) const;
//! Get Italics
int getItalics();
};
}
#endif /* FT_FONT_H */

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 1:34 PM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
69269
Default Alt Text
(22 KB)

Event Timeline