mirror of
https://github.com/glest/glest-source.git
synced 2025-08-17 13:50:43 +02:00
- added freetype-gl rendered and set as default font renderer (see: http://code.google.com/p/freetype-gl/)
This commit is contained in:
@@ -188,6 +188,11 @@ IF(BUILD_MEGAGLEST_MODEL_VIEWER OR BUILD_MEGAGLEST_MAP_EDITOR OR BUILD_MEGAGLEST
|
|||||||
ADD_DEFINITIONS(-DMINIUPNPC_VERSION_PRE1_6)
|
ADD_DEFINITIONS(-DMINIUPNPC_VERSION_PRE1_6)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
OPTION(USE_FREETYPEGL "Use Freetype-GL for on-screen fonts" ON)
|
||||||
|
if(USE_FREETYPEGL)
|
||||||
|
ADD_DEFINITIONS(-DUSE_FREETYPEGL)
|
||||||
|
endif(USE_FREETYPEGL)
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# megaglest lib
|
# megaglest lib
|
||||||
|
|
||||||
@@ -195,6 +200,7 @@ IF(BUILD_MEGAGLEST_MODEL_VIEWER OR BUILD_MEGAGLEST_MAP_EDITOR OR BUILD_MEGAGLEST
|
|||||||
feathery_ftp
|
feathery_ftp
|
||||||
glew
|
glew
|
||||||
graphics
|
graphics
|
||||||
|
graphics/freetype-gl
|
||||||
graphics/gl
|
graphics/gl
|
||||||
graphics/md5
|
graphics/md5
|
||||||
lua
|
lua
|
||||||
|
96
source/shared_lib/include/graphics/freetype-gl/edtaa3func.h
Normal file
96
source/shared_lib/include/graphics/freetype-gl/edtaa3func.h
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Stefan Gustavson (stefan.gustavson@gmail.com)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY STEFAN GUSTAVSON ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL STEFAN GUSTAVSON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Stefan Gustavson.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* edtaa3()
|
||||||
|
*
|
||||||
|
* Sweep-and-update Euclidean distance transform of an
|
||||||
|
* image. Positive pixels are treated as object pixels,
|
||||||
|
* zero or negative pixels are treated as background.
|
||||||
|
* An attempt is made to treat antialiased edges correctly.
|
||||||
|
* The input image must have pixels in the range [0,1],
|
||||||
|
* and the antialiased image should be a box-filter
|
||||||
|
* sampling of the ideal, crisp edge.
|
||||||
|
* If the antialias region is more than 1 pixel wide,
|
||||||
|
* the result from this transform will be inaccurate.
|
||||||
|
*
|
||||||
|
* By Stefan Gustavson (stefan.gustavson@gmail.com).
|
||||||
|
*
|
||||||
|
* Originally written in 1994, based on a verbal
|
||||||
|
* description of the SSED8 algorithm published in the
|
||||||
|
* PhD dissertation of Ingemar Ragnemalm. This is his
|
||||||
|
* algorithm, I only implemented it in C.
|
||||||
|
*
|
||||||
|
* Updated in 2004 to treat border pixels correctly,
|
||||||
|
* and cleaned up the code to improve readability.
|
||||||
|
*
|
||||||
|
* Updated in 2009 to handle anti-aliased edges.
|
||||||
|
*
|
||||||
|
* Updated in 2011 to avoid a corner case infinite loop.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the local gradient at edge pixels using convolution filters.
|
||||||
|
* The gradient is computed only at edge pixels. At other places in the
|
||||||
|
* image, it is never used, and it's mostly zero anyway.
|
||||||
|
*/
|
||||||
|
void computegradient(double *img, int w, int h, double *gx, double *gy);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A somewhat tricky function to approximate the distance to an edge in a
|
||||||
|
* certain pixel, with consideration to either the local gradient (gx,gy)
|
||||||
|
* or the direction to the pixel (dx,dy) and the pixel greyscale value a.
|
||||||
|
* The latter alternative, using (dx,dy), is the metric used by edtaa2().
|
||||||
|
* Using a local estimate of the edge gradient (gx,gy) yields much better
|
||||||
|
* accuracy at and near edges, and reduces the error even at distant pixels
|
||||||
|
* provided that the gradient direction is accurately estimated.
|
||||||
|
*/
|
||||||
|
double edgedf(double gx, double gy, double a);
|
||||||
|
|
||||||
|
|
||||||
|
double distaa3(double *img, double *gximg, double *gyimg, int w, int c, int xc, int yc, int xi, int yi);
|
||||||
|
|
||||||
|
// Shorthand macro: add ubiquitous parameters dist, gx, gy, img and w and call distaa3()
|
||||||
|
#define DISTAA(c,xc,yc,xi,yi) (distaa3(img, gx, gy, w, c, xc, yc, xi, yi))
|
||||||
|
|
||||||
|
void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, short *disty, double *dist);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
131
source/shared_lib/include/graphics/freetype-gl/font-manager.h
Normal file
131
source/shared_lib/include/graphics/freetype-gl/font-manager.h
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#pragma once
|
||||||
|
#ifndef __FONT_MANAGER_H__
|
||||||
|
#define __FONT_MANAGER_H__
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
#include "markup.h"
|
||||||
|
#include "texture-font.h"
|
||||||
|
#include "texture-atlas.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
TextureAtlas * atlas;
|
||||||
|
Vector * fonts;
|
||||||
|
wchar_t * cache;
|
||||||
|
Region black;
|
||||||
|
} FontManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
FontManager *
|
||||||
|
font_manager_new( size_t width, size_t height, size_t depth );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
font_manager_delete( FontManager *self );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
TextureFont *
|
||||||
|
font_manager_get_from_filename( FontManager * self,
|
||||||
|
const char * filename,
|
||||||
|
const float size );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
TextureFont *
|
||||||
|
font_manager_get_from_description( FontManager * self,
|
||||||
|
const char * family,
|
||||||
|
const float size,
|
||||||
|
const int bold,
|
||||||
|
const int italic );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
TextureFont *
|
||||||
|
font_manager_get_from_markup( FontManager *self,
|
||||||
|
const Markup *markup );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
font_manager_match_description( FontManager * self,
|
||||||
|
const char * family,
|
||||||
|
const float size,
|
||||||
|
const int bold,
|
||||||
|
const int italic );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const wchar_t *
|
||||||
|
font_manager_get_cache( FontManager * self );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
font_manager_set_cache( FontManager * self,
|
||||||
|
const wchar_t * cache );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __FONT_MANAGER_H__ */
|
||||||
|
|
128
source/shared_lib/include/graphics/freetype-gl/markup.h
Normal file
128
source/shared_lib/include/graphics/freetype-gl/markup.h
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#pragma once
|
||||||
|
#ifndef __MARKUP_H__
|
||||||
|
#define __MARKUP_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float r,g,b,a;
|
||||||
|
} Color;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char * family;
|
||||||
|
float size;
|
||||||
|
int bold;
|
||||||
|
int italic;
|
||||||
|
float rise;
|
||||||
|
float spacing;
|
||||||
|
Color foreground_color;
|
||||||
|
Color background_color;
|
||||||
|
int outline;
|
||||||
|
Color outline_color;
|
||||||
|
int underline;
|
||||||
|
Color underline_color;
|
||||||
|
int overline;
|
||||||
|
Color overline_color;
|
||||||
|
int strikethrough;
|
||||||
|
Color strikethrough_color;
|
||||||
|
struct TextureFont_ * font;
|
||||||
|
} Markup;
|
||||||
|
|
||||||
|
|
||||||
|
Markup * markup_new( void );
|
||||||
|
Markup * markup_copy( const Markup *other );
|
||||||
|
|
||||||
|
|
||||||
|
int markup_cmp( const Markup *self,
|
||||||
|
const Markup *other );
|
||||||
|
|
||||||
|
void markup_delete( Markup *self );
|
||||||
|
const char * markup_get_family( Markup *self );
|
||||||
|
void markup_set_family( Markup *self,
|
||||||
|
const char *family );
|
||||||
|
int markup_get_italic( Markup *self );
|
||||||
|
void markup_set_italic( Markup *self,
|
||||||
|
const int italic );
|
||||||
|
int markup_get_bold( Markup *self );
|
||||||
|
void markup_set_bold( Markup *self,
|
||||||
|
const int bold );
|
||||||
|
float markup_get_size( Markup *self );
|
||||||
|
void markup_set_size( Markup *self,
|
||||||
|
const float size );
|
||||||
|
float markup_get_rise( Markup *self );
|
||||||
|
void markup_set_rise( Markup *self,
|
||||||
|
const float rise );
|
||||||
|
float markup_get_spacing( Markup *self );
|
||||||
|
void markup_set_spacing( Markup *self,
|
||||||
|
const float spacing );
|
||||||
|
Color markup_get_foreground_color( Markup *self );
|
||||||
|
void markup_set_foreground_color( Markup *self,
|
||||||
|
const Color * color );
|
||||||
|
Color markup_get_background_color( Markup *self );
|
||||||
|
void markup_set_background_color( Markup *self,
|
||||||
|
const Color * color );
|
||||||
|
int markup_get_outline( Markup *self );
|
||||||
|
void markup_set_outline( Markup *self,
|
||||||
|
const int outline );
|
||||||
|
Color markup_get_outline_color( Markup *self );
|
||||||
|
void markup_set_outline_color( Markup *self,
|
||||||
|
const Color * color );
|
||||||
|
int markup_get_underline( Markup *self );
|
||||||
|
void markup_set_underline( Markup *self,
|
||||||
|
const int underline );
|
||||||
|
Color markup_get_underline_color( Markup *self );
|
||||||
|
void markup_set_underline_color( Markup *self,
|
||||||
|
const Color * color );
|
||||||
|
int markup_get_overline( Markup *self );
|
||||||
|
void markup_set_overline( Markup *self,
|
||||||
|
const int overline );
|
||||||
|
Color markup_get_overline_color( Markup *self );
|
||||||
|
void markup_set_overline_color( Markup *self,
|
||||||
|
const Color * color );
|
||||||
|
int markup_get_strikethrough( Markup *self );
|
||||||
|
void markup_set_strikethrough( Markup *self,
|
||||||
|
const int strikethrough );
|
||||||
|
Color markup_get_strikethrough_color( Markup *self );
|
||||||
|
void markup_set_strikethrough_color( Markup *self,
|
||||||
|
const Color * color );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __MARKUP_H__ */
|
156
source/shared_lib/include/graphics/freetype-gl/texture-atlas.h
Normal file
156
source/shared_lib/include/graphics/freetype-gl/texture-atlas.h
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* =========================================================================
|
||||||
|
|
||||||
|
This source is based on the article by Jukka Jylänki :
|
||||||
|
"A Thousand Ways to Pack the Bin - A Practical Approach to
|
||||||
|
Two-Dimensional Rectangle Bin Packing", February 27, 2010.
|
||||||
|
|
||||||
|
More precisely, this is an implementation of the Skyline Bottom-Left
|
||||||
|
algorithm based on C++ sources provided by Jukka Jylänki at:
|
||||||
|
http://clb.demon.fi/files/RectangleBinPack/
|
||||||
|
|
||||||
|
========================================================================= */
|
||||||
|
#pragma once
|
||||||
|
#ifndef __TEXTURE_ATLAS_H__
|
||||||
|
#define __TEXTURE_ATLAS_H__
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Region describes
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} Region;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct { float x,y,z,w; } vec4;
|
||||||
|
typedef struct { float x,y,z; } vec3;
|
||||||
|
typedef struct { float x,y; } vec2;
|
||||||
|
typedef struct { int x,y,z,w; } ivec4;
|
||||||
|
typedef struct { int x,y,z; } ivec3;
|
||||||
|
typedef struct { int x,y; } ivec2;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/** Current allocated nodes */
|
||||||
|
Vector *nodes;
|
||||||
|
|
||||||
|
/** Width (in pixels) of the underlying texture */
|
||||||
|
size_t width;
|
||||||
|
|
||||||
|
/** Height (in pixels) of the underlying texture */
|
||||||
|
size_t height;
|
||||||
|
|
||||||
|
/** Texture format (1, 3 or 4) */
|
||||||
|
size_t depth;
|
||||||
|
|
||||||
|
/** Allocated surface */
|
||||||
|
size_t used;
|
||||||
|
|
||||||
|
/** Texture identity (OpenGL) */
|
||||||
|
unsigned int texid;
|
||||||
|
|
||||||
|
unsigned char *data;
|
||||||
|
|
||||||
|
/** A special region */
|
||||||
|
Region black;
|
||||||
|
|
||||||
|
} TextureAtlas;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
TextureAtlas *
|
||||||
|
texture_atlas_new( size_t width,
|
||||||
|
size_t height,
|
||||||
|
size_t depth );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
texture_atlas_delete( TextureAtlas *self );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
texture_atlas_upload( TextureAtlas *self );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Region
|
||||||
|
texture_atlas_get_region( TextureAtlas *self,
|
||||||
|
size_t width,
|
||||||
|
size_t height );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
texture_atlas_set_region( TextureAtlas *self,
|
||||||
|
size_t x,
|
||||||
|
size_t y,
|
||||||
|
size_t width,
|
||||||
|
size_t height,
|
||||||
|
unsigned char *data,
|
||||||
|
size_t stride );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
texture_atlas_clear( TextureAtlas *self );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __TEXTURE_ATLAS_H__ */
|
120
source/shared_lib/include/graphics/freetype-gl/texture-font.h
Normal file
120
source/shared_lib/include/graphics/freetype-gl/texture-font.h
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#pragma once
|
||||||
|
#ifndef __TEXTURE_FONT_H__
|
||||||
|
#define __TEXTURE_FONT_H__
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include "vector.h"
|
||||||
|
#include "texture-atlas.h"
|
||||||
|
#include "texture-glyph.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct TextureFont_
|
||||||
|
{
|
||||||
|
Vector * glyphs;
|
||||||
|
TextureAtlas * atlas;
|
||||||
|
char * filename;
|
||||||
|
int bold;
|
||||||
|
int italic;
|
||||||
|
float size;
|
||||||
|
float gamma;
|
||||||
|
Region black;
|
||||||
|
int antialias;
|
||||||
|
int subpixel;
|
||||||
|
int hinting;
|
||||||
|
float height;
|
||||||
|
float linegap;
|
||||||
|
float ascender;
|
||||||
|
float descender;
|
||||||
|
int lcd_filter;
|
||||||
|
unsigned char lcd_weights[5];
|
||||||
|
};
|
||||||
|
typedef struct TextureFont_ TextureFont;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
TextureFont *
|
||||||
|
texture_font_new( TextureAtlas * atlas,
|
||||||
|
const char * filename,
|
||||||
|
const float size );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
texture_font_delete( TextureFont * self );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
TextureGlyph *
|
||||||
|
texture_font_get_glyph( TextureFont * self,
|
||||||
|
wchar_t charcode );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
texture_font_cache_glyphs( TextureFont * self,
|
||||||
|
const wchar_t * charcodes );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
texture_font_load_face( FT_Library * library,
|
||||||
|
const char * filename,
|
||||||
|
const float size,
|
||||||
|
FT_Face * face );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __TEXTURE_FONT_H__ */
|
||||||
|
|
131
source/shared_lib/include/graphics/freetype-gl/texture-glyph.h
Normal file
131
source/shared_lib/include/graphics/freetype-gl/texture-glyph.h
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#pragma once
|
||||||
|
#ifndef __TEXTURE_GLYPH_H__
|
||||||
|
#define __TEXTURE_GLYPH_H__
|
||||||
|
|
||||||
|
#include <wchar.h>
|
||||||
|
#include "markup.h"
|
||||||
|
#include "vertex-buffer.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
wchar_t charcode;
|
||||||
|
float kerning;
|
||||||
|
} KerningPair;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
float x,y;
|
||||||
|
} Pen;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
wchar_t charcode;
|
||||||
|
int width, height;
|
||||||
|
int offset_x, offset_y;
|
||||||
|
float advance_x, advance_y;
|
||||||
|
float u0, v0, u1, v1;
|
||||||
|
KerningPair * kerning;
|
||||||
|
size_t kerning_count;
|
||||||
|
struct TextureFont_ *font;
|
||||||
|
} TextureGlyph;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
float x, y, z;
|
||||||
|
float u, v;
|
||||||
|
float r, g, b, a;
|
||||||
|
} TextureGlyphVertex;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
TextureGlyph *
|
||||||
|
texture_glyph_new( void );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
texture_glyph_delete( TextureGlyph * self );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
texture_glyph_render( TextureGlyph * self,
|
||||||
|
Markup * markup,
|
||||||
|
Pen * pen );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
texture_glyph_add_to_vertex_buffer( const TextureGlyph * self,
|
||||||
|
VertexBuffer * buffer,
|
||||||
|
const Markup * markup,
|
||||||
|
Pen * pen, int kerning );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
float
|
||||||
|
texture_glyph_get_kerning( TextureGlyph * self,
|
||||||
|
wchar_t charcode );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __TEXTURE_GLYPH_H__ */
|
289
source/shared_lib/include/graphics/freetype-gl/vector.h
Normal file
289
source/shared_lib/include/graphics/freetype-gl/vector.h
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#ifndef __VECTOR_H__
|
||||||
|
#define __VECTOR_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic vector structure.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/** Pointer to dynamically allocated items. */
|
||||||
|
void * items;
|
||||||
|
|
||||||
|
/** Number of items that can be held in currently allocated storage. */
|
||||||
|
size_t capacity;
|
||||||
|
|
||||||
|
/** Number of items. */
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
/** Size (in bytes) of a single item. */
|
||||||
|
size_t item_size;
|
||||||
|
} Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a vector.
|
||||||
|
*
|
||||||
|
* @param item_size item size in bytes
|
||||||
|
* @return a new empty vector
|
||||||
|
*/
|
||||||
|
Vector *
|
||||||
|
vector_new( size_t item_size );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a vector.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_delete( Vector *self );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a pointer to the item located at specified index.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param index the index of the item to be returned
|
||||||
|
* @return pointer on the specified item
|
||||||
|
*/
|
||||||
|
const void *
|
||||||
|
vector_get( const Vector *self,
|
||||||
|
size_t index );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a pointer to the first item.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @return pointer on the first item
|
||||||
|
*/
|
||||||
|
const void *
|
||||||
|
vector_front( const Vector *self );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a pointer to the last item
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @return pointer on the last item
|
||||||
|
*/
|
||||||
|
const void *
|
||||||
|
vector_back( const Vector *self );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an item is contained within the vector.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param item item to be searched in the vector
|
||||||
|
* @param cmp a pointer a comparison function
|
||||||
|
* @return 1 if item is contained within the vector, 0 otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vector_contains( const Vector *self,
|
||||||
|
const void *item,
|
||||||
|
int (*cmp)(const void *, const void *) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the vector is empty.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @return 1 if the vector is empty, 0 otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vector_empty( const Vector *self );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of items
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @return number of items
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
vector_size( const Vector *self );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reserve storage such that it can hold at last size items.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param size the new storage capacity
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_reserve( Vector *self,
|
||||||
|
const size_t size );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns current storage capacity
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @return storage capacity
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
vector_capacity( const Vector *self );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrease capacity to fit actual size.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_shrink( Vector *self );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all items.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_clear( Vector *self );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace an item.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param index the index of the item to be replaced
|
||||||
|
* @param item the new item
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_set( Vector *self,
|
||||||
|
const size_t index,
|
||||||
|
const void *item );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erase an item.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param index the index of the item to be erased
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_erase( Vector *self,
|
||||||
|
const size_t index );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erase a range of items.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param first the index of the first item to be erased
|
||||||
|
* @param last the index of the last item to be erased
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_erase_range( Vector *self,
|
||||||
|
const size_t first,
|
||||||
|
const size_t last );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends given item to the end of the vector.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param item the item to be inserted
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_push_back( Vector *self,
|
||||||
|
const void *item );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the last item of the vector.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_pop_back( Vector *self );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes the vector to contain size items
|
||||||
|
*
|
||||||
|
* If the current size is less than size, additional items are appended and
|
||||||
|
* initialized with value. If the current size is greater than size, the
|
||||||
|
* vector is reduced to its first size elements.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param size the new size
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_resize( Vector *self,
|
||||||
|
const size_t size );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a single item at specified index.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param index location before which to insert item
|
||||||
|
* @param item the item to be inserted
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_insert( Vector *self,
|
||||||
|
const size_t index,
|
||||||
|
const void *item );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert raw data at specified index.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param index location before which to insert item
|
||||||
|
* @param data a pointer to the items to be inserted
|
||||||
|
* @param count the number of items to be inserted
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_insert_data( Vector *self,
|
||||||
|
const size_t index,
|
||||||
|
const void * data,
|
||||||
|
const size_t count );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append raw data to the end of the vector.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param data a pointer to the items to be inserted
|
||||||
|
* @param count the number of items to be inserted
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_push_back_data( Vector *self,
|
||||||
|
const void * data,
|
||||||
|
const size_t count );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort vector items according to cmp function.
|
||||||
|
*
|
||||||
|
* @param self a vector structure
|
||||||
|
* @param cmp a pointer a comparison function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vector_sort( Vector *self,
|
||||||
|
int (*cmp)(const void *, const void *) );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __VECTOR_H__ */
|
477
source/shared_lib/include/graphics/freetype-gl/vertex-buffer.h
Normal file
477
source/shared_lib/include/graphics/freetype-gl/vertex-buffer.h
Normal file
@@ -0,0 +1,477 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#ifndef __VERTEX_BUFFER_H__
|
||||||
|
#define __VERTEX_BUFFER_H__
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <Glut/glut.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#endif
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
#define MAX_VERTEX_ATTRIBUTE 64
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic vertex attribute.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* a client-side capability.
|
||||||
|
*/
|
||||||
|
GLenum target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a translated client-side capability.
|
||||||
|
*/
|
||||||
|
GLchar ctarget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* index of the generic vertex attribute to be modified.
|
||||||
|
*/
|
||||||
|
GLuint index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of components per generic vertex attribute. Must be 1, 2, 3, or
|
||||||
|
* 4. The initial value is 4.
|
||||||
|
*/
|
||||||
|
GLint size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data type of each component in the array. Symbolic constants GL_BYTE,
|
||||||
|
* GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT,
|
||||||
|
* GL_FLOAT, or GL_DOUBLE are accepted. The initial value is GL_FLOAT.
|
||||||
|
*/
|
||||||
|
GLenum type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether fixed-point data values should be normalized (GL_TRUE) or
|
||||||
|
* converted directly as fixed-point values (GL_FALSE) when they are
|
||||||
|
* accessed.
|
||||||
|
*/
|
||||||
|
GLboolean normalized;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Byte offset between consecutive generic vertex attributes. If stride is
|
||||||
|
* 0, the generic vertex attributes are understood to be tightly packed in
|
||||||
|
* the array. The initial value is 0.
|
||||||
|
*/
|
||||||
|
GLsizei stride;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to the first component of the first attribute element in the
|
||||||
|
* array.
|
||||||
|
*/
|
||||||
|
GLvoid * pointer;
|
||||||
|
|
||||||
|
/** Pointer to the function that enable this attribute. */
|
||||||
|
void ( * enable )(void *);
|
||||||
|
|
||||||
|
} VertexAttribute;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic vertex buffer.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/** Format of the vertex buffer. */
|
||||||
|
char * format;
|
||||||
|
|
||||||
|
/** Vector of vertices. */
|
||||||
|
Vector * vertices;
|
||||||
|
|
||||||
|
/** GL identity of the vertices buffer. */
|
||||||
|
GLuint vertices_id;
|
||||||
|
|
||||||
|
/** Vector of indices. */
|
||||||
|
Vector * indices;
|
||||||
|
|
||||||
|
/** GL identity of the indices buffer. */
|
||||||
|
GLuint indices_id;
|
||||||
|
|
||||||
|
/** Whether the vertex buffer needs to be uploaded to GPU memory. */
|
||||||
|
char dirty;
|
||||||
|
|
||||||
|
/** Array of attributes. */
|
||||||
|
VertexAttribute *attributes[MAX_VERTEX_ATTRIBUTE];
|
||||||
|
} VertexBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty vertex buffer.
|
||||||
|
*
|
||||||
|
* @param format a string describing vertex format.
|
||||||
|
* @return an empty vertex buffer.
|
||||||
|
*/
|
||||||
|
VertexBuffer *
|
||||||
|
vertex_buffer_new( const char *format );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a vertex buffer from data.
|
||||||
|
*
|
||||||
|
* @param format a string describing vertex format.
|
||||||
|
* @param vcount number of vertices
|
||||||
|
* @param vertices raw vertices data
|
||||||
|
* @param icount number of vertices
|
||||||
|
* @param indices raw indices data
|
||||||
|
* @return an empty vertex buffer.
|
||||||
|
*/
|
||||||
|
VertexBuffer *
|
||||||
|
vertex_buffer_new_from_data( char *format,
|
||||||
|
size_t vcount,
|
||||||
|
void * vertices,
|
||||||
|
size_t icount,
|
||||||
|
GLuint * indices );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes vertex buffer and releases GPU memory.
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_delete( VertexBuffer * self );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print information about a vertex buffer
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_print( VertexBuffer * self );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immediate draw
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
* @param mode render mode
|
||||||
|
* @param what attributes to be rendered
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_draw ( const char * format,
|
||||||
|
const GLenum mode,
|
||||||
|
const void * vertices,
|
||||||
|
const size_t count );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immediate draw with indexed vertices
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
* @param mode render mode
|
||||||
|
* @param what attributes to be rendered
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_draw_indexed ( const char * format,
|
||||||
|
const GLenum mode,
|
||||||
|
const void * vertices,
|
||||||
|
const size_t vcount,
|
||||||
|
const GLuint * indices,
|
||||||
|
const size_t icount );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render vertex buffer.
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
* @param mode render mode
|
||||||
|
* @param what attributes to be rendered
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_render ( VertexBuffer *self,
|
||||||
|
GLenum mode,
|
||||||
|
const char *what );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload buffer to GPU memory.
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_upload( VertexBuffer *self );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all vertices and indices
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_clear( VertexBuffer *self );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a single index at the end of the buffer.
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
* @param index index to be appended
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_push_back_index ( VertexBuffer *self,
|
||||||
|
GLuint index );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a single vertex at the end of the buffer.
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
* @param vertex vertex to be appended
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_push_back_vertex ( VertexBuffer *self,
|
||||||
|
void *vertex );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends indices at the end of the buffer.
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
* @param indices indices to be appended
|
||||||
|
* @param count number of indices to be appended
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_push_back_indices ( VertexBuffer *self,
|
||||||
|
GLuint *indices,
|
||||||
|
size_t count );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends vertices at the end of the buffer.
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
* @param vertices vertices to be appended
|
||||||
|
* @param count number of vertices to be appended
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_push_back_vertices ( VertexBuffer *self,
|
||||||
|
void *vertices,
|
||||||
|
size_t count );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends indices at the end of the buffer.
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
* @param index location before which to insert indices
|
||||||
|
* @param indices indices to be appended
|
||||||
|
* @param count number of indices to be appended
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_insert_indices ( VertexBuffer *self,
|
||||||
|
size_t index,
|
||||||
|
GLuint *indices,
|
||||||
|
size_t count );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends indices at the end of the buffer.
|
||||||
|
*
|
||||||
|
* @param self a vertex buffer
|
||||||
|
* @param index location before which to insert vertices
|
||||||
|
* @param vertices vertices to be appended
|
||||||
|
* @param count number of vertices to be appended
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* Indices after index will be increased by count.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_buffer_add_vertices ( VertexBuffer *self,
|
||||||
|
size_t index,
|
||||||
|
void *vertices,
|
||||||
|
size_t count );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an attribute from the given parameters.
|
||||||
|
*
|
||||||
|
* @param target client-side capability
|
||||||
|
* @param index index of the generic vertex attribute to be modified.
|
||||||
|
* @param size number of component
|
||||||
|
* @param type data type
|
||||||
|
* @param normalized Whether fixed-point data values should be normalized
|
||||||
|
(GL_TRUE) or converted directly as fixed-point values
|
||||||
|
(GL_FALSE) when they are accessed.
|
||||||
|
* @param stride byte offset between consecutive attributes.
|
||||||
|
* @param pointer pointer to the first component of the first attribute
|
||||||
|
* element in the array.
|
||||||
|
* @return a new initialized vertex attribute.
|
||||||
|
*/
|
||||||
|
VertexAttribute *
|
||||||
|
vertex_attribute_new( GLenum target,
|
||||||
|
GLuint index,
|
||||||
|
GLint size,
|
||||||
|
GLenum type,
|
||||||
|
GLboolean normalized,
|
||||||
|
GLsizei stride,
|
||||||
|
GLvoid *pointer );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an attribute from the given description.
|
||||||
|
*
|
||||||
|
* @param format Format string specifies the format of a vertex attribute.
|
||||||
|
* @return an initialized vertex attribute
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
VertexAttribute *
|
||||||
|
vertex_attribute_parse( char *format );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the position vertex attribute.
|
||||||
|
*
|
||||||
|
* @param attr a vertex attribute
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_attribute_position_enable( VertexAttribute *attr );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the normal vertex attribute.
|
||||||
|
*
|
||||||
|
* @param attr a vertex attribute
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_attribute_normal_enable( VertexAttribute *attr );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the color vertex attribute.
|
||||||
|
*
|
||||||
|
* @param attr a vertex attribute
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_attribute_color_enable( VertexAttribute *attr );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the texture vertex attribute.
|
||||||
|
*
|
||||||
|
* @param attr a vertex attribute
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_attribute_tex_coord_enable( VertexAttribute *attr );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the fog vertex attribute.
|
||||||
|
*
|
||||||
|
* @param attr a vertex attribute
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_attribute_fog_coord_enable( VertexAttribute *attr );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the edge flag vertex attribute.
|
||||||
|
*
|
||||||
|
* @param attr a vertex attribute
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_attribute_edge_flag_enable( VertexAttribute *attr );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the secondary color vertex attribute.
|
||||||
|
*
|
||||||
|
* @param attr a vertex attribute
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_attribute_secondary_color_enable( VertexAttribute *attr );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable a generic vertex attribute.
|
||||||
|
*
|
||||||
|
* @param attr a vertex attribute
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vertex_attribute_generic_attribute_enable( VertexAttribute *attr );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the GL enum type correspond to given character.
|
||||||
|
*
|
||||||
|
* @param ctype character type
|
||||||
|
* @return GL enum type
|
||||||
|
*/
|
||||||
|
GLenum
|
||||||
|
GL_TYPE( char ctype );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the GL name of the given target.
|
||||||
|
*
|
||||||
|
* @param ctarget a char describing target ( one of v,c,e,f,n,s,t)
|
||||||
|
* @return the associated GL target
|
||||||
|
*/
|
||||||
|
GLenum
|
||||||
|
GL_VERTEX_ATTRIBUTE_TARGET( char ctarget );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of a given GL enum type.
|
||||||
|
*
|
||||||
|
* @param gtype a GL enum type
|
||||||
|
* @return the size of the given type
|
||||||
|
*/
|
||||||
|
GLuint
|
||||||
|
GL_TYPE_SIZE( GLenum gtype );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the literal string of given GL enum type.
|
||||||
|
*
|
||||||
|
* @param gtype a GL enum type
|
||||||
|
* @return the literal string describing the type
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
GL_TYPE_STRING( GLenum gtype );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __VERTEX_BUFFER_H__ */
|
280
source/shared_lib/include/graphics/gl/font_text_freetypegl.h
Normal file
280
source/shared_lib/include/graphics/gl/font_text_freetypegl.h
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
// ==============================================================
|
||||||
|
// This file is part of the MegaGlest Shared Library (www.megaglest.org)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2011 Mark Vejvoda and others
|
||||||
|
//
|
||||||
|
// You can redistribute this code and/or modify it under
|
||||||
|
// the terms of the GNU General Public License as published
|
||||||
|
// by the Free Software Foundation; either version 3 of the
|
||||||
|
// License, or (at your option) any later version
|
||||||
|
// ==============================================================
|
||||||
|
|
||||||
|
#ifndef TextFreetypeGL_h
|
||||||
|
#define TextFreetypeGL_h
|
||||||
|
|
||||||
|
#ifdef USE_FREETYPEGL
|
||||||
|
|
||||||
|
//#include <stdlib.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
//#include "vector.h"
|
||||||
|
#include "texture-font.h"
|
||||||
|
#include "texture-atlas.h"
|
||||||
|
#include "vertex-buffer.h"
|
||||||
|
#include "font-manager.h"
|
||||||
|
|
||||||
|
#include "font_text.h"
|
||||||
|
|
||||||
|
namespace Shared { namespace Graphics { namespace Gl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use Freetype-GL for rendering text in OpenGL
|
||||||
|
*/
|
||||||
|
//====================================================================
|
||||||
|
class TextFreetypeGL : public Text
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static string langHeightText;
|
||||||
|
static int faceResolution;
|
||||||
|
|
||||||
|
TextFreetypeGL(FontTextHandlerType type);
|
||||||
|
virtual ~TextFreetypeGL();
|
||||||
|
virtual void init(string fontName, int fontSize);
|
||||||
|
|
||||||
|
virtual void SetFaceSize(int);
|
||||||
|
virtual int GetFaceSize();
|
||||||
|
|
||||||
|
virtual void Render(const char*, const int = -1);
|
||||||
|
virtual float Advance(const char*, const int = -1);
|
||||||
|
virtual float LineHeight(const char*, const int = -1);
|
||||||
|
|
||||||
|
virtual void Render(const wchar_t*, const int = -1);
|
||||||
|
virtual float Advance(const wchar_t*, const int = -1);
|
||||||
|
virtual float LineHeight(const wchar_t* = L" ", const int = -1);
|
||||||
|
|
||||||
|
private:
|
||||||
|
//FTFont *ftFont;
|
||||||
|
VertexBuffer *buffer;
|
||||||
|
TextureAtlas *atlas;
|
||||||
|
TextureFont *font;
|
||||||
|
//TextureGlyph *glyph;
|
||||||
|
FontManager *manager;
|
||||||
|
//Markup markup;
|
||||||
|
int fontFaceSize;
|
||||||
|
|
||||||
|
string fontName;
|
||||||
|
const char* fontFile;
|
||||||
|
|
||||||
|
const char* findFont(const char *firstFontToTry=NULL);
|
||||||
|
|
||||||
|
void cleanupFont();
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}//end namespace
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a way to easily walk multibyte unicode strings in the various
|
||||||
|
* Unicode encodings (UTF-8, UTF-16, UTF-32, UCS-2, and UCS-4). Encodings
|
||||||
|
* with elements larger than one byte must already be in the correct endian
|
||||||
|
* order for the current architecture.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class FreetypeGLUnicodeStringItr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor. Also reads the first character and stores it.
|
||||||
|
*
|
||||||
|
* @param string The buffer to iterate. No copy is made.
|
||||||
|
*/
|
||||||
|
FreetypeGLUnicodeStringItr(const T* string) : curPos(string), nextPos(string)
|
||||||
|
{
|
||||||
|
(*this)++;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-increment operator. Reads the next unicode character and sets
|
||||||
|
* the state appropriately.
|
||||||
|
* Note - not protected against overruns.
|
||||||
|
*/
|
||||||
|
FreetypeGLUnicodeStringItr& operator++()
|
||||||
|
{
|
||||||
|
curPos = nextPos;
|
||||||
|
// unicode handling
|
||||||
|
switch (sizeof(T))
|
||||||
|
{
|
||||||
|
case 1: // UTF-8
|
||||||
|
// get this character
|
||||||
|
readUTF8(); break;
|
||||||
|
case 2: // UTF-16
|
||||||
|
readUTF16(); break;
|
||||||
|
case 4: // UTF-32
|
||||||
|
// fall through
|
||||||
|
default: // error condition really, but give it a shot anyway
|
||||||
|
curChar = *nextPos++;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post-increment operator. Reads the next character and sets
|
||||||
|
* the state appropriately.
|
||||||
|
* Note - not protected against overruns.
|
||||||
|
*/
|
||||||
|
FreetypeGLUnicodeStringItr operator++(int)
|
||||||
|
{
|
||||||
|
FreetypeGLUnicodeStringItr temp = *this;
|
||||||
|
++*this;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equality operator. Two FreetypeGLUnicodeStringItrs are considered equal
|
||||||
|
* if they have the same current buffer and buffer position.
|
||||||
|
*/
|
||||||
|
bool operator==(const FreetypeGLUnicodeStringItr& right) const
|
||||||
|
{
|
||||||
|
if (curPos == right.getBufferFromHere())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dereference operator.
|
||||||
|
*
|
||||||
|
* @return The unicode codepoint of the character currently pointed
|
||||||
|
* to by the FreetypeGLUnicodeStringItr.
|
||||||
|
*/
|
||||||
|
unsigned int operator*() const
|
||||||
|
{
|
||||||
|
return curChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer-fetching getter. You can use this to retreive the buffer
|
||||||
|
* starting at the currently-iterated character for functions which
|
||||||
|
* require a Unicode string as input.
|
||||||
|
*/
|
||||||
|
const T* getBufferFromHere() const { return curPos; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Helper function for reading a single UTF8 character from the string.
|
||||||
|
* Updates internal state appropriately.
|
||||||
|
*/
|
||||||
|
void readUTF8();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for reading a single UTF16 character from the string.
|
||||||
|
* Updates internal state appropriately.
|
||||||
|
*/
|
||||||
|
void readUTF16();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The buffer position of the first element in the current character.
|
||||||
|
*/
|
||||||
|
const T* curPos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The character stored at the current buffer position (prefetched on
|
||||||
|
* increment, so there's no penalty for dereferencing more than once).
|
||||||
|
*/
|
||||||
|
unsigned int curChar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The buffer position of the first element in the next character.
|
||||||
|
*/
|
||||||
|
const T* nextPos;
|
||||||
|
|
||||||
|
// unicode magic numbers
|
||||||
|
static const unsigned char utf8bytes[256];
|
||||||
|
static const unsigned long offsetsFromUTF8[6];
|
||||||
|
static const unsigned long highSurrogateStart;
|
||||||
|
static const unsigned long highSurrogateEnd;
|
||||||
|
static const unsigned long lowSurrogateStart;
|
||||||
|
static const unsigned long lowSurrogateEnd;
|
||||||
|
static const unsigned long highSurrogateShift;
|
||||||
|
static const unsigned long lowSurrogateBase;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The first character in a UTF8 sequence indicates how many bytes
|
||||||
|
* to read (among other things) */
|
||||||
|
template <typename T>
|
||||||
|
const unsigned char FreetypeGLUnicodeStringItr<T>::utf8bytes[256] = {
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||||
|
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Magic values subtracted from a buffer value during UTF8 conversion.
|
||||||
|
* This table contains as many values as there might be trailing bytes
|
||||||
|
* in a UTF-8 sequence. */
|
||||||
|
template <typename T>
|
||||||
|
const unsigned long FreetypeGLUnicodeStringItr<T>::offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
||||||
|
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
|
||||||
|
|
||||||
|
// get a UTF8 character; leave the tracking pointer at the start of the
|
||||||
|
// next character
|
||||||
|
// not protected against invalid UTF8
|
||||||
|
template <typename T>
|
||||||
|
inline void FreetypeGLUnicodeStringItr<T>::readUTF8()
|
||||||
|
{
|
||||||
|
unsigned int ch = 0;
|
||||||
|
unsigned int extraBytesToRead = utf8bytes[(unsigned char)(*nextPos)];
|
||||||
|
// falls through
|
||||||
|
switch (extraBytesToRead)
|
||||||
|
{
|
||||||
|
case 6: ch += *nextPos++; ch <<= 6; /* remember, illegal UTF-8 */
|
||||||
|
case 5: ch += *nextPos++; ch <<= 6; /* remember, illegal UTF-8 */
|
||||||
|
case 4: ch += *nextPos++; ch <<= 6;
|
||||||
|
case 3: ch += *nextPos++; ch <<= 6;
|
||||||
|
case 2: ch += *nextPos++; ch <<= 6;
|
||||||
|
case 1: ch += *nextPos++;
|
||||||
|
}
|
||||||
|
ch -= offsetsFromUTF8[extraBytesToRead-1];
|
||||||
|
curChar = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic numbers for UTF-16 conversions
|
||||||
|
template <typename T>
|
||||||
|
const unsigned long FreetypeGLUnicodeStringItr<T>::highSurrogateStart = 0xD800;
|
||||||
|
template <typename T>
|
||||||
|
const unsigned long FreetypeGLUnicodeStringItr<T>::highSurrogateEnd = 0xDBFF;
|
||||||
|
template <typename T>
|
||||||
|
const unsigned long FreetypeGLUnicodeStringItr<T>::lowSurrogateStart = 0xDC00;
|
||||||
|
template <typename T>
|
||||||
|
const unsigned long FreetypeGLUnicodeStringItr<T>::lowSurrogateEnd = 0xDFFF;
|
||||||
|
template <typename T>
|
||||||
|
const unsigned long FreetypeGLUnicodeStringItr<T>::highSurrogateShift = 10;
|
||||||
|
template <typename T>
|
||||||
|
const unsigned long FreetypeGLUnicodeStringItr<T>::lowSurrogateBase = 0x0010000UL;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void FreetypeGLUnicodeStringItr<T>::readUTF16()
|
||||||
|
{
|
||||||
|
unsigned int ch = *nextPos++;
|
||||||
|
// if we have the first half of the surrogate pair
|
||||||
|
if (ch >= highSurrogateStart && ch <= highSurrogateEnd)
|
||||||
|
{
|
||||||
|
unsigned int ch2 = *curPos;
|
||||||
|
// complete the surrogate pair
|
||||||
|
if (ch2 >= lowSurrogateStart && ch2 <= lowSurrogateEnd)
|
||||||
|
{
|
||||||
|
ch = ((ch - highSurrogateStart) << highSurrogateShift)
|
||||||
|
+ (ch2 - lowSurrogateStart) + lowSurrogateBase;
|
||||||
|
++nextPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curChar = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // USE_FREETYPEGL
|
||||||
|
|
||||||
|
#endif // TextFreetypeGL_h
|
@@ -23,6 +23,12 @@ using namespace Shared::Graphics::Gl;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_FREETYPEGL
|
||||||
|
|
||||||
|
#include "font_text_freetypegl.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "leak_dumper.h"
|
#include "leak_dumper.h"
|
||||||
|
|
||||||
@@ -153,10 +159,15 @@ Font::Font(FontTextHandlerType type) {
|
|||||||
size = 10;
|
size = 10;
|
||||||
textHandler = NULL;
|
textHandler = NULL;
|
||||||
|
|
||||||
#ifdef USE_FTGL
|
#if defined(USE_FTGL) || defined(USE_FREETYPEGL)
|
||||||
|
|
||||||
if(Font::forceLegacyFonts == false) {
|
if(Font::forceLegacyFonts == false) {
|
||||||
try {
|
try {
|
||||||
|
#if defined(USE_FREETYPEGL)
|
||||||
|
textHandler = NULL;
|
||||||
|
textHandler = new TextFreetypeGL(type);
|
||||||
|
|
||||||
|
#else
|
||||||
TextFTGL::faceResolution = Font::faceResolution;
|
TextFTGL::faceResolution = Font::faceResolution;
|
||||||
TextFTGL::langHeightText = Font::langHeightText;
|
TextFTGL::langHeightText = Font::langHeightText;
|
||||||
|
|
||||||
@@ -164,7 +175,7 @@ Font::Font(FontTextHandlerType type) {
|
|||||||
textHandler = new TextFTGL(type);
|
textHandler = new TextFTGL(type);
|
||||||
TextFTGL::faceResolution = Font::faceResolution;
|
TextFTGL::faceResolution = Font::faceResolution;
|
||||||
TextFTGL::langHeightText = Font::langHeightText;
|
TextFTGL::langHeightText = Font::langHeightText;
|
||||||
|
#endif
|
||||||
metrics.setTextHandler(this->textHandler);
|
metrics.setTextHandler(this->textHandler);
|
||||||
}
|
}
|
||||||
catch(exception &ex) {
|
catch(exception &ex) {
|
||||||
|
577
source/shared_lib/sources/graphics/freetype-gl/edtaa3func.c
Normal file
577
source/shared_lib/sources/graphics/freetype-gl/edtaa3func.c
Normal file
@@ -0,0 +1,577 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Stefan Gustavson (stefan.gustavson@gmail.com)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY STEFAN GUSTAVSON ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL STEFAN GUSTAVSON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Stefan Gustavson.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* edtaa3()
|
||||||
|
*
|
||||||
|
* Sweep-and-update Euclidean distance transform of an
|
||||||
|
* image. Positive pixels are treated as object pixels,
|
||||||
|
* zero or negative pixels are treated as background.
|
||||||
|
* An attempt is made to treat antialiased edges correctly.
|
||||||
|
* The input image must have pixels in the range [0,1],
|
||||||
|
* and the antialiased image should be a box-filter
|
||||||
|
* sampling of the ideal, crisp edge.
|
||||||
|
* If the antialias region is more than 1 pixel wide,
|
||||||
|
* the result from this transform will be inaccurate.
|
||||||
|
*
|
||||||
|
* By Stefan Gustavson (stefan.gustavson@gmail.com).
|
||||||
|
*
|
||||||
|
* Originally written in 1994, based on a verbal
|
||||||
|
* description of the SSED8 algorithm published in the
|
||||||
|
* PhD dissertation of Ingemar Ragnemalm. This is his
|
||||||
|
* algorithm, I only implemented it in C.
|
||||||
|
*
|
||||||
|
* Updated in 2004 to treat border pixels correctly,
|
||||||
|
* and cleaned up the code to improve readability.
|
||||||
|
*
|
||||||
|
* Updated in 2009 to handle anti-aliased edges.
|
||||||
|
*
|
||||||
|
* Updated in 2011 to avoid a corner case infinite loop.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the local gradient at edge pixels using convolution filters.
|
||||||
|
* The gradient is computed only at edge pixels. At other places in the
|
||||||
|
* image, it is never used, and it's mostly zero anyway.
|
||||||
|
*/
|
||||||
|
void computegradient(double *img, int w, int h, double *gx, double *gy)
|
||||||
|
{
|
||||||
|
int i,j,k;
|
||||||
|
double glength;
|
||||||
|
#define SQRT2 1.4142136
|
||||||
|
for(i = 1; i < h-1; i++) { // Avoid edges where the kernels would spill over
|
||||||
|
for(j = 1; j < w-1; j++) {
|
||||||
|
k = i*w + j;
|
||||||
|
if((img[k]>0.0) && (img[k]<1.0)) { // Compute gradient for edge pixels only
|
||||||
|
gx[k] = -img[k-w-1] - SQRT2*img[k-1] - img[k+w-1] + img[k-w+1] + SQRT2*img[k+1] + img[k+w+1];
|
||||||
|
gy[k] = -img[k-w-1] - SQRT2*img[k-w] - img[k+w-1] + img[k-w+1] + SQRT2*img[k+w] + img[k+w+1];
|
||||||
|
glength = gx[k]*gx[k] + gy[k]*gy[k];
|
||||||
|
if(glength > 0.0) { // Avoid division by zero
|
||||||
|
glength = sqrt(glength);
|
||||||
|
gx[k]=gx[k]/glength;
|
||||||
|
gy[k]=gy[k]/glength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: Compute reasonable values for gx, gy also around the image edges.
|
||||||
|
// (These are zero now, which reduces the accuracy for a 1-pixel wide region
|
||||||
|
// around the image edge.) 2x2 kernels would be suitable for this.
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A somewhat tricky function to approximate the distance to an edge in a
|
||||||
|
* certain pixel, with consideration to either the local gradient (gx,gy)
|
||||||
|
* or the direction to the pixel (dx,dy) and the pixel greyscale value a.
|
||||||
|
* The latter alternative, using (dx,dy), is the metric used by edtaa2().
|
||||||
|
* Using a local estimate of the edge gradient (gx,gy) yields much better
|
||||||
|
* accuracy at and near edges, and reduces the error even at distant pixels
|
||||||
|
* provided that the gradient direction is accurately estimated.
|
||||||
|
*/
|
||||||
|
double edgedf(double gx, double gy, double a)
|
||||||
|
{
|
||||||
|
double df, glength, temp, a1;
|
||||||
|
|
||||||
|
if ((gx == 0) || (gy == 0)) { // Either A) gu or gv are zero, or B) both
|
||||||
|
df = 0.5-a; // Linear approximation is A) correct or B) a fair guess
|
||||||
|
} else {
|
||||||
|
glength = sqrt(gx*gx + gy*gy);
|
||||||
|
if(glength>0) {
|
||||||
|
gx = gx/glength;
|
||||||
|
gy = gy/glength;
|
||||||
|
}
|
||||||
|
/* Everything is symmetric wrt sign and transposition,
|
||||||
|
* so move to first octant (gx>=0, gy>=0, gx>=gy) to
|
||||||
|
* avoid handling all possible edge directions.
|
||||||
|
*/
|
||||||
|
gx = fabs(gx);
|
||||||
|
gy = fabs(gy);
|
||||||
|
if(gx<gy) {
|
||||||
|
temp = gx;
|
||||||
|
gx = gy;
|
||||||
|
gy = temp;
|
||||||
|
}
|
||||||
|
a1 = 0.5*gy/gx;
|
||||||
|
if (a < a1) { // 0 <= a < a1
|
||||||
|
df = 0.5*(gx + gy) - sqrt(2.0*gx*gy*a);
|
||||||
|
} else if (a < (1.0-a1)) { // a1 <= a <= 1-a1
|
||||||
|
df = (0.5-a)*gx;
|
||||||
|
} else { // 1-a1 < a <= 1
|
||||||
|
df = -0.5*(gx + gy) + sqrt(2.0*gx*gy*(1.0-a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return df;
|
||||||
|
}
|
||||||
|
|
||||||
|
double distaa3(double *img, double *gximg, double *gyimg, int w, int c, int xc, int yc, int xi, int yi)
|
||||||
|
{
|
||||||
|
double di, df, dx, dy, gx, gy, a;
|
||||||
|
int closest;
|
||||||
|
|
||||||
|
closest = c-xc-yc*w; // Index to the edge pixel pointed to from c
|
||||||
|
a = img[closest]; // Grayscale value at the edge pixel
|
||||||
|
gx = gximg[closest]; // X gradient component at the edge pixel
|
||||||
|
gy = gyimg[closest]; // Y gradient component at the edge pixel
|
||||||
|
|
||||||
|
if(a > 1.0) a = 1.0;
|
||||||
|
if(a < 0.0) a = 0.0; // Clip grayscale values outside the range [0,1]
|
||||||
|
if(a == 0.0) return 1000000.0; // Not an object pixel, return "very far" ("don't know yet")
|
||||||
|
|
||||||
|
dx = (double)xi;
|
||||||
|
dy = (double)yi;
|
||||||
|
di = sqrt(dx*dx + dy*dy); // Length of integer vector, like a traditional EDT
|
||||||
|
if(di==0) { // Use local gradient only at edges
|
||||||
|
// Estimate based on local gradient only
|
||||||
|
df = edgedf(gx, gy, a);
|
||||||
|
} else {
|
||||||
|
// Estimate gradient based on direction to edge (accurate for large di)
|
||||||
|
df = edgedf(dx, dy, a);
|
||||||
|
}
|
||||||
|
return di + df; // Same metric as edtaa2, except at edges (where di=0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shorthand macro: add ubiquitous parameters dist, gx, gy, img and w and call distaa3()
|
||||||
|
#define DISTAA(c,xc,yc,xi,yi) (distaa3(img, gx, gy, w, c, xc, yc, xi, yi))
|
||||||
|
|
||||||
|
void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, short *disty, double *dist)
|
||||||
|
{
|
||||||
|
int x, y, i, c;
|
||||||
|
int offset_u, offset_ur, offset_r, offset_rd,
|
||||||
|
offset_d, offset_dl, offset_l, offset_lu;
|
||||||
|
double olddist, newdist;
|
||||||
|
int cdistx, cdisty, newdistx, newdisty;
|
||||||
|
int changed;
|
||||||
|
double epsilon = 1e-3;
|
||||||
|
|
||||||
|
/* Initialize index offsets for the current image width */
|
||||||
|
offset_u = -w;
|
||||||
|
offset_ur = -w+1;
|
||||||
|
offset_r = 1;
|
||||||
|
offset_rd = w+1;
|
||||||
|
offset_d = w;
|
||||||
|
offset_dl = w-1;
|
||||||
|
offset_l = -1;
|
||||||
|
offset_lu = -w-1;
|
||||||
|
|
||||||
|
/* Initialize the distance images */
|
||||||
|
for(i=0; i<w*h; i++) {
|
||||||
|
distx[i] = 0; // At first, all pixels point to
|
||||||
|
disty[i] = 0; // themselves as the closest known.
|
||||||
|
if(img[i] <= 0.0)
|
||||||
|
{
|
||||||
|
dist[i]= 1000000.0; // Big value, means "not set yet"
|
||||||
|
}
|
||||||
|
else if (img[i]<1.0) {
|
||||||
|
dist[i] = edgedf(gx[i], gy[i], img[i]); // Gradient-assisted estimate
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dist[i]= 0.0; // Inside the object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform the transformation */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
changed = 0;
|
||||||
|
|
||||||
|
/* Scan rows, except first row */
|
||||||
|
for(y=1; y<h; y++)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* move index to leftmost pixel of current row */
|
||||||
|
i = y*w;
|
||||||
|
|
||||||
|
/* scan right, propagate distances from above & left */
|
||||||
|
|
||||||
|
/* Leftmost pixel is special, has no left neighbors */
|
||||||
|
olddist = dist[i];
|
||||||
|
if(olddist > 0) // If non-zero distance or not set yet
|
||||||
|
{
|
||||||
|
c = i + offset_u; // Index of candidate for testing
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx;
|
||||||
|
newdisty = cdisty+1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_ur;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx-1;
|
||||||
|
newdisty = cdisty+1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
/* Middle pixels have all neighbors */
|
||||||
|
for(x=1; x<w-1; x++, i++)
|
||||||
|
{
|
||||||
|
olddist = dist[i];
|
||||||
|
if(olddist <= 0) continue; // No need to update further
|
||||||
|
|
||||||
|
c = i+offset_l;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx+1;
|
||||||
|
newdisty = cdisty;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_lu;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx+1;
|
||||||
|
newdisty = cdisty+1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_u;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx;
|
||||||
|
newdisty = cdisty+1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_ur;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx-1;
|
||||||
|
newdisty = cdisty+1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rightmost pixel of row is special, has no right neighbors */
|
||||||
|
olddist = dist[i];
|
||||||
|
if(olddist > 0) // If not already zero distance
|
||||||
|
{
|
||||||
|
c = i+offset_l;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx+1;
|
||||||
|
newdisty = cdisty;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_lu;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx+1;
|
||||||
|
newdisty = cdisty+1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_u;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx;
|
||||||
|
newdisty = cdisty+1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move index to second rightmost pixel of current row. */
|
||||||
|
/* Rightmost pixel is skipped, it has no right neighbor. */
|
||||||
|
i = y*w + w-2;
|
||||||
|
|
||||||
|
/* scan left, propagate distance from right */
|
||||||
|
for(x=w-2; x>=0; x--, i--)
|
||||||
|
{
|
||||||
|
olddist = dist[i];
|
||||||
|
if(olddist <= 0) continue; // Already zero distance
|
||||||
|
|
||||||
|
c = i+offset_r;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx-1;
|
||||||
|
newdisty = cdisty;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scan rows in reverse order, except last row */
|
||||||
|
for(y=h-2; y>=0; y--)
|
||||||
|
{
|
||||||
|
/* move index to rightmost pixel of current row */
|
||||||
|
i = y*w + w-1;
|
||||||
|
|
||||||
|
/* Scan left, propagate distances from below & right */
|
||||||
|
|
||||||
|
/* Rightmost pixel is special, has no right neighbors */
|
||||||
|
olddist = dist[i];
|
||||||
|
if(olddist > 0) // If not already zero distance
|
||||||
|
{
|
||||||
|
c = i+offset_d;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx;
|
||||||
|
newdisty = cdisty-1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_dl;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx+1;
|
||||||
|
newdisty = cdisty-1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
|
||||||
|
/* Middle pixels have all neighbors */
|
||||||
|
for(x=w-2; x>0; x--, i--)
|
||||||
|
{
|
||||||
|
olddist = dist[i];
|
||||||
|
if(olddist <= 0) continue; // Already zero distance
|
||||||
|
|
||||||
|
c = i+offset_r;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx-1;
|
||||||
|
newdisty = cdisty;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_rd;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx-1;
|
||||||
|
newdisty = cdisty-1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_d;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx;
|
||||||
|
newdisty = cdisty-1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_dl;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx+1;
|
||||||
|
newdisty = cdisty-1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Leftmost pixel is special, has no left neighbors */
|
||||||
|
olddist = dist[i];
|
||||||
|
if(olddist > 0) // If not already zero distance
|
||||||
|
{
|
||||||
|
c = i+offset_r;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx-1;
|
||||||
|
newdisty = cdisty;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_rd;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx-1;
|
||||||
|
newdisty = cdisty-1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = i+offset_d;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx;
|
||||||
|
newdisty = cdisty-1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move index to second leftmost pixel of current row. */
|
||||||
|
/* Leftmost pixel is skipped, it has no left neighbor. */
|
||||||
|
i = y*w + 1;
|
||||||
|
for(x=1; x<w; x++, i++)
|
||||||
|
{
|
||||||
|
/* scan right, propagate distance from left */
|
||||||
|
olddist = dist[i];
|
||||||
|
if(olddist <= 0) continue; // Already zero distance
|
||||||
|
|
||||||
|
c = i+offset_l;
|
||||||
|
cdistx = distx[c];
|
||||||
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx+1;
|
||||||
|
newdisty = cdisty;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon)
|
||||||
|
{
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(changed); // Sweep until no more updates are made
|
||||||
|
|
||||||
|
/* The transformation is completed. */
|
||||||
|
|
||||||
|
}
|
222
source/shared_lib/sources/graphics/freetype-gl/font-manager.c
Normal file
222
source/shared_lib/sources/graphics/freetype-gl/font-manager.c
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#include <fontconfig/fontconfig.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include "font-manager.h"
|
||||||
|
|
||||||
|
|
||||||
|
wchar_t *
|
||||||
|
wcsdup( const wchar_t *string )
|
||||||
|
{
|
||||||
|
wchar_t * result;
|
||||||
|
assert( string );
|
||||||
|
result = (wchar_t *) malloc( (wcslen(string) + 1) * sizeof(wchar_t) );
|
||||||
|
wcscpy( result, string );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FontManager *
|
||||||
|
font_manager_new( size_t width, size_t height, size_t depth )
|
||||||
|
{
|
||||||
|
static FontManager *self = 0;
|
||||||
|
if( !self )
|
||||||
|
{
|
||||||
|
TextureAtlas *atlas = texture_atlas_new( width, height, depth );
|
||||||
|
self = (FontManager *) malloc( sizeof(FontManager) );
|
||||||
|
if( !self )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->atlas = atlas;
|
||||||
|
self->fonts = vector_new( sizeof(TextureFont) );
|
||||||
|
self->cache = wcsdup( L" " );
|
||||||
|
/*
|
||||||
|
self->cache = wcsdup( L" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||||
|
L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||||
|
L"`abcdefghijklmnopqrstuvwxyz{|}~" );
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
font_manager_delete( FontManager *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
vector_delete( self->fonts );
|
||||||
|
texture_atlas_delete( self->atlas );
|
||||||
|
if( self->cache )
|
||||||
|
{
|
||||||
|
free( self->cache );
|
||||||
|
}
|
||||||
|
free( self );
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureFont *
|
||||||
|
font_manager_get_from_filename( FontManager *self,
|
||||||
|
const char * filename,
|
||||||
|
const float size )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
TextureFont *font;
|
||||||
|
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
for( i=0; i<self->fonts->size;++i )
|
||||||
|
{
|
||||||
|
font = (TextureFont *) vector_get( self->fonts, i );
|
||||||
|
if( (strcmp(font->filename, filename) == 0) && ( font->size == size) )
|
||||||
|
{
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
font = texture_font_new( self->atlas, filename, size );
|
||||||
|
texture_font_cache_glyphs( font, self->cache );
|
||||||
|
if( font )
|
||||||
|
{
|
||||||
|
vector_push_back( self->fonts, font );
|
||||||
|
}
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TextureFont *
|
||||||
|
font_manager_get_from_description( FontManager *self,
|
||||||
|
const char * family,
|
||||||
|
const float size,
|
||||||
|
const int bold,
|
||||||
|
const int italic )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
TextureFont *font;
|
||||||
|
char *filename = font_manager_match_description( self, family, size, bold, italic );
|
||||||
|
// fprintf(stderr, "Matched filename for %s: %s\n", family, filename);
|
||||||
|
if( !filename )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
font = font_manager_get_from_filename( self, filename, size );
|
||||||
|
free( filename );
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureFont *
|
||||||
|
font_manager_get_from_markup( FontManager *self,
|
||||||
|
const Markup *markup )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( markup );
|
||||||
|
TextureFont *font =
|
||||||
|
font_manager_get_from_description( self, markup->family, markup->size,
|
||||||
|
markup->bold, markup->italic );
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
font_manager_match_description( FontManager *self,
|
||||||
|
const char * family,
|
||||||
|
const float size,
|
||||||
|
const int bold,
|
||||||
|
const int italic )
|
||||||
|
{
|
||||||
|
char *filename = 0;
|
||||||
|
int weight = FC_WEIGHT_REGULAR;
|
||||||
|
int slant = FC_SLANT_ROMAN;
|
||||||
|
if ( bold )
|
||||||
|
{
|
||||||
|
weight = FC_WEIGHT_BOLD;
|
||||||
|
}
|
||||||
|
if( italic )
|
||||||
|
{
|
||||||
|
slant = FC_SLANT_ITALIC;
|
||||||
|
}
|
||||||
|
FcInit();
|
||||||
|
FcPattern *pattern = FcPatternCreate();
|
||||||
|
FcPatternAddDouble( pattern, FC_SIZE, size );
|
||||||
|
FcPatternAddInteger( pattern, FC_WEIGHT, weight );
|
||||||
|
FcPatternAddInteger( pattern, FC_SLANT, slant );
|
||||||
|
FcPatternAddString( pattern, FC_FAMILY, (FcChar8*) family );
|
||||||
|
FcConfigSubstitute( 0, pattern, FcMatchPattern );
|
||||||
|
FcDefaultSubstitute( pattern );
|
||||||
|
FcResult result;
|
||||||
|
FcPattern *match = FcFontMatch( 0, pattern, &result );
|
||||||
|
FcPatternDestroy( pattern );
|
||||||
|
|
||||||
|
if ( !match )
|
||||||
|
{
|
||||||
|
fprintf( stderr, "fontconfig error: could not match family '%s'", family );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FcValue value;
|
||||||
|
FcResult result = FcPatternGet( match, FC_FILE, 0, &value );
|
||||||
|
if ( result )
|
||||||
|
{
|
||||||
|
fprintf( stderr, "fontconfig error: could not match family '%s'", family );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filename = strdup( (char *)(value.u.s) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FcPatternDestroy( match );
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const wchar_t *
|
||||||
|
font_manager_get_cache( FontManager *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
font_manager_set_cache( FontManager *self,
|
||||||
|
const wchar_t * cache )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( cache );
|
||||||
|
|
||||||
|
if( self->cache )
|
||||||
|
{
|
||||||
|
free( self->cache );
|
||||||
|
}
|
||||||
|
self->cache = wcsdup( cache );
|
||||||
|
}
|
349
source/shared_lib/sources/graphics/freetype-gl/makefont.c
Normal file
349
source/shared_lib/sources/graphics/freetype-gl/makefont.c
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <Glut/glut.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include "vector.h"
|
||||||
|
#include "texture-font.h"
|
||||||
|
#include "texture-glyph.h"
|
||||||
|
#include "texture-atlas.h"
|
||||||
|
#include "font-manager.h"
|
||||||
|
|
||||||
|
|
||||||
|
void display( void )
|
||||||
|
{
|
||||||
|
int viewport[4];
|
||||||
|
glGetIntegerv( GL_VIEWPORT, viewport );
|
||||||
|
GLuint width = viewport[2];
|
||||||
|
GLuint height = viewport[3];
|
||||||
|
|
||||||
|
glClearColor(1,1,1,1);
|
||||||
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
glEnable( GL_BLEND );
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
glEnable( GL_TEXTURE_2D );
|
||||||
|
glColor4f(0,0,0,1);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f( 0, 1 ); glVertex2i( 0, 0 );
|
||||||
|
glTexCoord2f( 0, 0 ); glVertex2i( 0, height );
|
||||||
|
glTexCoord2f( 1, 0 ); glVertex2i( width, height );
|
||||||
|
glTexCoord2f( 1, 1 ); glVertex2i( width, 0 );
|
||||||
|
glEnd();
|
||||||
|
glutSwapBuffers( );
|
||||||
|
}
|
||||||
|
|
||||||
|
void reshape(int width, int height)
|
||||||
|
{
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glOrtho(0, width, 0, height, -1, 1);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyboard( unsigned char key, int x, int y )
|
||||||
|
{
|
||||||
|
if ( key == 27 )
|
||||||
|
{
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main( int argc, char **argv )
|
||||||
|
{
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
wchar_t * font_cache =
|
||||||
|
L" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||||
|
L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||||
|
L"`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||||
|
|
||||||
|
char * font_family = "arial";
|
||||||
|
float font_size = 16.0;
|
||||||
|
char * font_filename = "arial.ttf";
|
||||||
|
char * header_filename = "arial-16.h";
|
||||||
|
|
||||||
|
TextureAtlas * atlas = texture_atlas_new( 128, 128, 1 );
|
||||||
|
TextureFont * font = texture_font_new( atlas, font_filename, font_size );
|
||||||
|
|
||||||
|
|
||||||
|
glutInit( &argc, argv );
|
||||||
|
glutInitWindowSize( atlas->width, atlas->height );
|
||||||
|
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
|
||||||
|
glutCreateWindow( "Freetype OpenGL" );
|
||||||
|
glutReshapeFunc( reshape );
|
||||||
|
glutDisplayFunc( display );
|
||||||
|
glutKeyboardFunc( keyboard );
|
||||||
|
glBindTexture( GL_TEXTURE_2D, atlas->texid );
|
||||||
|
|
||||||
|
size_t missed = texture_font_cache_glyphs( font, font_cache );
|
||||||
|
|
||||||
|
wprintf( L"Font filename : %s\n", font_filename );
|
||||||
|
wprintf( L"Font size : %.1f\n", font_size );
|
||||||
|
wprintf( L"Number of glyphs : %ld\n", wcslen(font_cache) );
|
||||||
|
wprintf( L"Number of missed glyphs : %ld\n", missed );
|
||||||
|
wprintf( L"Texture size : %ldx%ldx%ld\n", atlas->width, atlas->height, atlas->depth );
|
||||||
|
wprintf( L"Texture occupancy : %.2f%%\n",
|
||||||
|
100.0*atlas->used/(float)(atlas->width*atlas->height) );
|
||||||
|
wprintf( L"\n" );
|
||||||
|
wprintf( L"Header filename : %s\n", header_filename );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// glutMainLoop();
|
||||||
|
|
||||||
|
|
||||||
|
size_t texture_size = atlas->width * atlas->height *atlas->depth;
|
||||||
|
size_t glyph_count = font->glyphs->size;
|
||||||
|
size_t max_kerning_count = 1;
|
||||||
|
for( i=0; i < glyph_count; ++i )
|
||||||
|
{
|
||||||
|
TextureGlyph *glyph = (TextureGlyph *) vector_get( font->glyphs, i );
|
||||||
|
if( glyph->kerning_count > max_kerning_count )
|
||||||
|
{
|
||||||
|
max_kerning_count = glyph->kerning_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *file = fopen( header_filename, "w" );
|
||||||
|
|
||||||
|
|
||||||
|
// -------------
|
||||||
|
// Header
|
||||||
|
// -------------
|
||||||
|
fwprintf( file,
|
||||||
|
L"/* =========================================================================\n"
|
||||||
|
L" * Freetype GL - A C OpenGL Freetype engine\n"
|
||||||
|
L" * Platform: Any\n"
|
||||||
|
L" * WWW: http://code.google.com/p/freetype-gl/\n"
|
||||||
|
L" * -------------------------------------------------------------------------\n"
|
||||||
|
L" * Copyright 2011 Nicolas P. Rougier. All rights reserved.\n"
|
||||||
|
L" *\n"
|
||||||
|
L" * Redistribution and use in source and binary forms, with or without\n"
|
||||||
|
L" * modification, are permitted provided that the following conditions are met:\n"
|
||||||
|
L" *\n"
|
||||||
|
L" * 1. Redistributions of source code must retain the above copyright notice,\n"
|
||||||
|
L" * this list of conditions and the following disclaimer.\n"
|
||||||
|
L" *\n"
|
||||||
|
L" * 2. Redistributions in binary form must reproduce the above copyright\n"
|
||||||
|
L" * notice, this list of conditions and the following disclaimer in the\n"
|
||||||
|
L" * documentation and/or other materials provided with the distribution.\n"
|
||||||
|
L" *\n"
|
||||||
|
L" * THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR\n"
|
||||||
|
L" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
|
||||||
|
L" * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n"
|
||||||
|
L" * EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n"
|
||||||
|
L" * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n"
|
||||||
|
L" * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n"
|
||||||
|
L" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n"
|
||||||
|
L" * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
|
||||||
|
L" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n"
|
||||||
|
L" * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||||
|
L" *\n"
|
||||||
|
L" * The views and conclusions contained in the software and documentation are\n"
|
||||||
|
L" * those of the authors and should not be interpreted as representing official\n"
|
||||||
|
L" * policies, either expressed or implied, of Nicolas P. Rougier.\n"
|
||||||
|
L" * ========================================================================= */\n" );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// Structure declarations
|
||||||
|
// ----------------------
|
||||||
|
fwprintf( file,
|
||||||
|
L"typedef struct\n"
|
||||||
|
L"{\n"
|
||||||
|
L" wchar_t charcode;\n"
|
||||||
|
L" float kerning;\n"
|
||||||
|
L"} Kerning;\n\n" );
|
||||||
|
|
||||||
|
fwprintf( file,
|
||||||
|
L"typedef struct\n"
|
||||||
|
L"{\n"
|
||||||
|
L" wchar_t charcode;\n"
|
||||||
|
L" int width, height;\n"
|
||||||
|
L" int offset_x, offset_y;\n"
|
||||||
|
L" float advance_x, advance_y;\n"
|
||||||
|
L" float u0, v0, u1, v1;\n"
|
||||||
|
L" size_t kerning_count;\n"
|
||||||
|
L" Kerning kerning[%d];\n"
|
||||||
|
L"} TextureGlyph;\n\n", max_kerning_count );
|
||||||
|
|
||||||
|
fwprintf( file,
|
||||||
|
L"typedef struct\n"
|
||||||
|
L"{\n"
|
||||||
|
L" size_t tex_width;\n"
|
||||||
|
L" size_t tex_height;\n"
|
||||||
|
L" size_t tex_depth;\n"
|
||||||
|
L" char tex_data[%d];\n"
|
||||||
|
L" float size;\n"
|
||||||
|
L" float height;\n"
|
||||||
|
L" float linegap;\n"
|
||||||
|
L" float ascender;\n"
|
||||||
|
L" float descender;\n"
|
||||||
|
L" size_t glyphs_count;\n"
|
||||||
|
L" TextureGlyph glyphs[%d];\n"
|
||||||
|
L"} TextureFont;\n\n", texture_size, glyph_count );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fwprintf( file, L"TextureFont font = {\n" );
|
||||||
|
|
||||||
|
|
||||||
|
// ------------
|
||||||
|
// Texture data
|
||||||
|
// ------------
|
||||||
|
fwprintf( file, L" %d, %d, %d, \n", atlas->width, atlas->height, atlas->depth );
|
||||||
|
fwprintf( file, L" {" );
|
||||||
|
for( i=0; i < texture_size; i+= 32 )
|
||||||
|
{
|
||||||
|
for( j=0; j < 32 && (j+i) < texture_size ; ++ j)
|
||||||
|
{
|
||||||
|
if( (j+i) < (texture_size-1) )
|
||||||
|
{
|
||||||
|
fwprintf( file, L"%d,", atlas->data[i+j] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fwprintf( file, L"%d", atlas->data[i+j] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( (j+i) < texture_size )
|
||||||
|
{
|
||||||
|
fwprintf( file, L"\n " );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fwprintf( file, L"}, \n" );
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Texture information
|
||||||
|
// -------------------
|
||||||
|
fwprintf( file, L" %f, %f, %f, %f, %f, %d, \n",
|
||||||
|
font->size, font->height,
|
||||||
|
font->linegap,font->ascender, font->descender,
|
||||||
|
glyph_count );
|
||||||
|
|
||||||
|
// --------------
|
||||||
|
// Texture glyphs
|
||||||
|
// --------------
|
||||||
|
fwprintf( file, L" {\n" );
|
||||||
|
for( i=0; i < glyph_count; ++i )
|
||||||
|
{
|
||||||
|
TextureGlyph *glyph = (TextureGlyph *) vector_get( font->glyphs, i );
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Debugging information
|
||||||
|
wprintf( L"glyph : '%lc'\n",
|
||||||
|
glyph->charcode );
|
||||||
|
wprintf( L" size : %dx%d\n",
|
||||||
|
glyph->width, glyph->height );
|
||||||
|
wprintf( L" offset : %+d%+d\n",
|
||||||
|
glyph->offset_x, glyph->offset_y );
|
||||||
|
wprintf( L" advance : %f, %f\n",
|
||||||
|
glyph->advance_x, glyph->advance_y );
|
||||||
|
wprintf( L" tex coords.: %f, %f, %f, %f\n",
|
||||||
|
glyph->u0, glyph->v0, glyph->u1, glyph->v1 );
|
||||||
|
|
||||||
|
wprintf( L" kerning : " );
|
||||||
|
if( glyph->kerning_count )
|
||||||
|
{
|
||||||
|
for( j=0; j < glyph->kerning_count; ++j )
|
||||||
|
{
|
||||||
|
wprintf( L"('%lc', %f)",
|
||||||
|
glyph->kerning[j].charcode, glyph->kerning[j].kerning );
|
||||||
|
if( j < (glyph->kerning_count-1) )
|
||||||
|
{
|
||||||
|
wprintf( L", " );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wprintf( L"None" );
|
||||||
|
}
|
||||||
|
wprintf( L"\n\n" );
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TextureFont
|
||||||
|
if( (glyph->charcode == L'\'' ) || (glyph->charcode == L'\\' ) )
|
||||||
|
{
|
||||||
|
fwprintf( file, L" {L'\\%lc', ", glyph->charcode );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fwprintf( file, L" {L'%lc', ", glyph->charcode );
|
||||||
|
}
|
||||||
|
fwprintf( file, L"%d, %d, ", glyph->width, glyph->height );
|
||||||
|
fwprintf( file, L"%d, %d, ", glyph->offset_x, glyph->offset_y );
|
||||||
|
fwprintf( file, L"%f, %f, ", glyph->advance_x, glyph->advance_y );
|
||||||
|
fwprintf( file, L"%f, %f, %f, %f, ", glyph->u0, glyph->v0, glyph->u1, glyph->v1 );
|
||||||
|
fwprintf( file, L"%d, ", max_kerning_count );
|
||||||
|
fwprintf( file, L"{ " );
|
||||||
|
for( j=0; j < glyph->kerning_count; ++j )
|
||||||
|
{
|
||||||
|
wchar_t charcode = glyph->kerning[j].charcode;
|
||||||
|
|
||||||
|
if( (charcode == L'\'' ) || (charcode == L'\\') )
|
||||||
|
{
|
||||||
|
fwprintf( file, L"{L'\\%lc', %f}", charcode, glyph->kerning[j].kerning );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fwprintf( file, L"{L'%lc', %f}", charcode, glyph->kerning[j].kerning );
|
||||||
|
}
|
||||||
|
if( j < (glyph->kerning_count-1) )
|
||||||
|
{
|
||||||
|
fwprintf( file, L", " );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( i < (glyph_count-1) )
|
||||||
|
{
|
||||||
|
fwprintf( file, L"} },\n" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fwprintf( file, L"} }\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fwprintf( file, L" }\n};\n" );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
294
source/shared_lib/sources/graphics/freetype-gl/markup.c
Normal file
294
source/shared_lib/sources/graphics/freetype-gl/markup.c
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "font-manager.h"
|
||||||
|
#include "markup.h"
|
||||||
|
|
||||||
|
Markup *
|
||||||
|
markup_new( void )
|
||||||
|
{
|
||||||
|
Color black = {0,0,0,1};
|
||||||
|
Color white = {1,1,1,1};
|
||||||
|
|
||||||
|
Markup *self = (Markup *) malloc( sizeof(Markup) );
|
||||||
|
if( !self )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->family = strdup("monotype");
|
||||||
|
self->italic = 0;
|
||||||
|
self->bold = 0;
|
||||||
|
self->size = 16;
|
||||||
|
self->rise = 0;
|
||||||
|
self->spacing= 0;
|
||||||
|
|
||||||
|
self->foreground_color = black;
|
||||||
|
self->background_color = white;
|
||||||
|
self->underline = 0;
|
||||||
|
self->underline_color = black;
|
||||||
|
self->overline = 0;
|
||||||
|
self->overline_color = black;
|
||||||
|
self->strikethrough = 0;
|
||||||
|
self->strikethrough_color = black;
|
||||||
|
|
||||||
|
self->font = 0;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_delete( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
free( self->family );
|
||||||
|
free( self );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
markup_cmp( const Markup *self,
|
||||||
|
const Markup *other )
|
||||||
|
{
|
||||||
|
size_t n = sizeof( Markup ) - sizeof( TextureFont * );
|
||||||
|
return memcmp( self, other, n );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
markup_get_family( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->family;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_family( Markup *self,
|
||||||
|
const char *family )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
markup_get_italic( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_italic( Markup *self,
|
||||||
|
const int italic )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
markup_get_bold( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_bold( Markup *self,
|
||||||
|
const int bold )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
markup_get_size( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
return self->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_size( Markup *self,
|
||||||
|
const float size )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
markup_get_rise( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->rise;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_rise( Markup *self, const float rise )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
markup_get_spacing( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_spacing( Markup *self, const float spacing )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Color
|
||||||
|
markup_get_foreground_color( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->foreground_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_foreground_color( Markup *self, const Color * color )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Color
|
||||||
|
markup_get_background_color( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->background_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_background_color( Markup *self, const Color * color )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
markup_get_outline( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->outline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_outline( Markup *self,
|
||||||
|
const int outline )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Color
|
||||||
|
markup_get_outline_color( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->outline_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_outline_color( Markup *self,
|
||||||
|
const Color * color )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
markup_get_underline( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_underline( Markup *self,
|
||||||
|
const int underline )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Color
|
||||||
|
markup_get_underline_color( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->underline_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_underline_color( Markup *self,
|
||||||
|
const Color * color )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
markup_get_overline( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->overline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_overline( Markup *self,
|
||||||
|
const int overline )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Color
|
||||||
|
markup_get_overline_color( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->overline_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_overline_color( Markup *self,
|
||||||
|
const Color * color )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
markup_get_strikethrough( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->strikethrough;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_strikethrough( Markup *self,
|
||||||
|
const int strikethrough )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Color
|
||||||
|
markup_get_strikethrough_color( Markup *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->strikethrough_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
markup_set_strikethrough_color( Markup *self,
|
||||||
|
const Color * color )
|
||||||
|
{
|
||||||
|
}
|
324
source/shared_lib/sources/graphics/freetype-gl/texture-atlas.c
Normal file
324
source/shared_lib/sources/graphics/freetype-gl/texture-atlas.c
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <Glut/glut.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "texture-atlas.h"
|
||||||
|
|
||||||
|
#define max(a,b) (a)>(b)?(a):(b)
|
||||||
|
#define min(a,b) (a)<(b)?(a):(b)
|
||||||
|
|
||||||
|
typedef struct { int x, y, width; } Node;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
TextureAtlas *
|
||||||
|
texture_atlas_new( size_t width, size_t height, size_t depth )
|
||||||
|
{
|
||||||
|
assert( (depth == 1) || (depth == 3) );
|
||||||
|
|
||||||
|
TextureAtlas *self = (TextureAtlas *) malloc( sizeof(TextureAtlas) );
|
||||||
|
if( !self )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
self->nodes = vector_new( sizeof(Node) );
|
||||||
|
self->used = 0;
|
||||||
|
self->width = width;
|
||||||
|
self->height = height;
|
||||||
|
self->depth = depth;
|
||||||
|
Node node = {0,0,width};
|
||||||
|
vector_push_back( self->nodes, &node );
|
||||||
|
self->texid = 0;
|
||||||
|
self->data = (unsigned char *)
|
||||||
|
calloc( width*height*depth, sizeof(unsigned char) );
|
||||||
|
|
||||||
|
|
||||||
|
// This is a special region that is used for background and underlined
|
||||||
|
// decorations of glyphs
|
||||||
|
int n = 4;
|
||||||
|
unsigned char buffer[n*n];
|
||||||
|
memset(buffer, 255, n*n);
|
||||||
|
Region r = texture_atlas_get_region( self, n, n );
|
||||||
|
texture_atlas_set_region( self, r.x, r.y, r.width, r.height, buffer, 1);
|
||||||
|
self->black.x = r.x + 1;
|
||||||
|
self->black.y = r.y + 1;
|
||||||
|
self->black.width = r.width - 2;
|
||||||
|
self->black.height= r.height - 2;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
texture_atlas_delete( TextureAtlas *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
vector_delete( self->nodes );
|
||||||
|
if( self->data )
|
||||||
|
{
|
||||||
|
free( self->data );
|
||||||
|
}
|
||||||
|
if( self->texid )
|
||||||
|
{
|
||||||
|
glDeleteTextures( 1, &self->texid );
|
||||||
|
}
|
||||||
|
free( self );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
texture_atlas_upload( TextureAtlas *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( self->data );
|
||||||
|
if( !self->texid )
|
||||||
|
{
|
||||||
|
glGenTextures( 1, &self->texid );
|
||||||
|
}
|
||||||
|
glBindTexture( GL_TEXTURE_2D, self->texid );
|
||||||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
|
||||||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
|
||||||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||||
|
if( self->depth == 3 )
|
||||||
|
{
|
||||||
|
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, self->width, self->height,
|
||||||
|
0, GL_RGB, GL_UNSIGNED_BYTE, self->data );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, self->width, self->height,
|
||||||
|
0, GL_ALPHA, GL_UNSIGNED_BYTE, self->data );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
texture_atlas_set_region( TextureAtlas *self,
|
||||||
|
size_t x, size_t y,
|
||||||
|
size_t width, size_t height,
|
||||||
|
unsigned char *data, size_t stride )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( x < self->width);
|
||||||
|
assert( (x + width) <= self->width);
|
||||||
|
assert( y < self->height);
|
||||||
|
assert( (y + height) <= self->height);
|
||||||
|
size_t i;
|
||||||
|
size_t depth = self->depth;
|
||||||
|
size_t charsize = sizeof(char);
|
||||||
|
for( i=0; i<height; ++i )
|
||||||
|
{
|
||||||
|
memcpy( self->data+((y+i)*self->width + x ) * charsize * depth,
|
||||||
|
data + (i*stride) * charsize, width * charsize * depth );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
int
|
||||||
|
texture_atlas_fit( TextureAtlas *self,
|
||||||
|
size_t index, size_t width, size_t height )
|
||||||
|
{
|
||||||
|
Node *node = (Node *) (vector_get( self->nodes, index ));
|
||||||
|
int x = node->x, y, width_left = width;
|
||||||
|
size_t i = index;
|
||||||
|
|
||||||
|
if ( (x + width) > self->width )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
y = node->y;
|
||||||
|
while( width_left > 0 )
|
||||||
|
{
|
||||||
|
node = (Node *) (vector_get( self->nodes, i ));
|
||||||
|
y = max( y, node->y );
|
||||||
|
if( (y + height) > self->height )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
width_left -= node->width;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
texture_atlas_merge( TextureAtlas *self )
|
||||||
|
{
|
||||||
|
Node *node, *next;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for( i=0; i< self->nodes->size-1; ++i )
|
||||||
|
{
|
||||||
|
node = (Node *) (vector_get( self->nodes, i ));
|
||||||
|
next = (Node *) (vector_get( self->nodes, i+1 ));
|
||||||
|
|
||||||
|
if( node->y == next->y )
|
||||||
|
{
|
||||||
|
node->width += next->width;
|
||||||
|
vector_erase( self->nodes, i+1 );
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
Region
|
||||||
|
texture_atlas_get_region( TextureAtlas *self,
|
||||||
|
size_t width, size_t height )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
/*
|
||||||
|
assert( width );
|
||||||
|
assert( height );
|
||||||
|
*/
|
||||||
|
int y, best_height, best_width, best_index;
|
||||||
|
Node *node, *prev;
|
||||||
|
Region region = {0,0,width,height};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
best_height = INT_MAX;
|
||||||
|
best_index = -1;
|
||||||
|
best_width = INT_MAX;
|
||||||
|
for( i=0; i<self->nodes->size; ++i )
|
||||||
|
{
|
||||||
|
y = texture_atlas_fit( self, i, width, height );
|
||||||
|
if( y >= 0 )
|
||||||
|
{
|
||||||
|
node = (Node *) vector_get( self->nodes, i );
|
||||||
|
if( ( y + height < best_height ) ||
|
||||||
|
( y + height == best_height && node->width < best_width) )
|
||||||
|
{
|
||||||
|
best_height = y + height;
|
||||||
|
best_index = i;
|
||||||
|
best_width = node->width;
|
||||||
|
region.x = node->x;
|
||||||
|
region.y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( best_index == -1 )
|
||||||
|
{
|
||||||
|
region.x = -1;
|
||||||
|
region.y = -1;
|
||||||
|
region.width = 0;
|
||||||
|
region.height = 0;
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = (Node *) malloc( sizeof(Node) );
|
||||||
|
node->x = region.x;
|
||||||
|
node->y = region.y + height;
|
||||||
|
node->width = width;
|
||||||
|
vector_insert( self->nodes, best_index, node );
|
||||||
|
free( node );
|
||||||
|
|
||||||
|
for(i = best_index+1; i < self->nodes->size; ++i)
|
||||||
|
{
|
||||||
|
node = (Node *) vector_get( self->nodes, i );
|
||||||
|
prev = (Node *) vector_get( self->nodes, i-1 );
|
||||||
|
|
||||||
|
if (node->x < (prev->x + prev->width) )
|
||||||
|
{
|
||||||
|
int shrink = prev->x + prev->width - node->x;
|
||||||
|
node->x += shrink;
|
||||||
|
node->width -= shrink;
|
||||||
|
if (node->width <= 0)
|
||||||
|
{
|
||||||
|
vector_erase( self->nodes, i );
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
texture_atlas_merge( self );
|
||||||
|
self->used += width * height;
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
texture_atlas_clear( TextureAtlas *self )
|
||||||
|
{
|
||||||
|
|
||||||
|
vector_clear( self->nodes );
|
||||||
|
self->used = 0;
|
||||||
|
Node node = {0,0,self->width};
|
||||||
|
vector_push_back( self->nodes, &node );
|
||||||
|
|
||||||
|
memset( self->data, 0, self->width*self->height*self->depth );
|
||||||
|
|
||||||
|
|
||||||
|
// This is a special region that is used for background and underlined
|
||||||
|
// decorations of glyphs
|
||||||
|
int n = 4;
|
||||||
|
unsigned char buffer[n*n];
|
||||||
|
memset(buffer, 255, n*n);
|
||||||
|
Region r = texture_atlas_get_region( self, n, n );
|
||||||
|
texture_atlas_set_region( self, r.x, r.y, r.width, r.height, buffer, 1);
|
||||||
|
self->black.x = r.x + 1;
|
||||||
|
self->black.y = r.y + 1;
|
||||||
|
self->black.width = r.width - 2;
|
||||||
|
self->black.height= r.height - 2;
|
||||||
|
}
|
422
source/shared_lib/sources/graphics/freetype-gl/texture-font.c
Normal file
422
source/shared_lib/sources/graphics/freetype-gl/texture-font.c
Normal file
@@ -0,0 +1,422 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
// #include FT_ADVANCES_H
|
||||||
|
#include FT_LCD_FILTER_H
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "texture-font.h"
|
||||||
|
#include "texture-glyph.h"
|
||||||
|
|
||||||
|
#undef __FTERRORS_H__
|
||||||
|
#define FT_ERRORDEF( e, v, s ) { e, s },
|
||||||
|
#define FT_ERROR_START_LIST {
|
||||||
|
#define FT_ERROR_END_LIST { 0, 0 } };
|
||||||
|
const struct {
|
||||||
|
int code;
|
||||||
|
const char* message;
|
||||||
|
} FT_Errors[] =
|
||||||
|
#include FT_ERRORS_H
|
||||||
|
|
||||||
|
#define max(a,b) (a)>(b)?(a):(b)
|
||||||
|
#define min(a,b) (a)<(b)?(a):(b)
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
TextureFont *
|
||||||
|
texture_font_new( TextureAtlas *atlas,
|
||||||
|
const char *filename,
|
||||||
|
const float size )
|
||||||
|
{
|
||||||
|
TextureFont *self = (TextureFont *) malloc( sizeof(TextureFont) );
|
||||||
|
if( !self )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
self->glyphs = vector_new( sizeof(TextureGlyph) );
|
||||||
|
self->filename = strdup( filename );
|
||||||
|
self->size = size;
|
||||||
|
self->gamma = 1.;
|
||||||
|
self->atlas = atlas;
|
||||||
|
self->height = 0;
|
||||||
|
self->ascender = 0;
|
||||||
|
self->descender = 0;
|
||||||
|
self->hinting = 1;
|
||||||
|
self->lcd_filter = 0;
|
||||||
|
self->lcd_weights[0] = 0;
|
||||||
|
self->lcd_weights[1] = 0;
|
||||||
|
self->lcd_weights[2] = 255;
|
||||||
|
self->lcd_weights[3] = 0;
|
||||||
|
self->lcd_weights[4] = 0;
|
||||||
|
|
||||||
|
/* Get font metrics at high resolution */
|
||||||
|
FT_Library library;
|
||||||
|
FT_Face face;
|
||||||
|
if( !texture_font_load_face( &library, self->filename, self->size*100, &face ) )
|
||||||
|
{
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_Size_Metrics metrics = face->size->metrics;
|
||||||
|
self->ascender = (metrics.ascender >> 6) / 100.0;
|
||||||
|
self->descender = (metrics.descender >> 6) / 100.0;
|
||||||
|
self->height = (metrics.height >> 6) / 100.0;
|
||||||
|
self->linegap = self->height - self->ascender + self->descender;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
texture_font_delete( TextureFont *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
if( self->filename )
|
||||||
|
{
|
||||||
|
free( self->filename );
|
||||||
|
}
|
||||||
|
vector_delete( self->glyphs );
|
||||||
|
free( self );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
texture_font_generate_kerning( TextureFont *self )
|
||||||
|
{
|
||||||
|
size_t i, j, k, count;
|
||||||
|
FT_Library library;
|
||||||
|
FT_Face face;
|
||||||
|
FT_UInt glyph_index, prev_index;
|
||||||
|
TextureGlyph *glyph, *prev_glyph;
|
||||||
|
FT_Vector kerning;
|
||||||
|
|
||||||
|
|
||||||
|
/* Load font */
|
||||||
|
if( !texture_font_load_face( &library, self->filename, self->size, &face ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For each glyph couple combination, check if kerning is necessary */
|
||||||
|
for( i=0; i<self->glyphs->size; ++i )
|
||||||
|
{
|
||||||
|
|
||||||
|
glyph = (TextureGlyph *) vector_get( self->glyphs, i );
|
||||||
|
|
||||||
|
/* Remove any old kerning information */
|
||||||
|
if( glyph->kerning )
|
||||||
|
{
|
||||||
|
free( glyph->kerning );
|
||||||
|
glyph->kerning = 0;
|
||||||
|
glyph->kerning_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count how many kerning pairs we need */
|
||||||
|
count = 0;
|
||||||
|
glyph_index = FT_Get_Char_Index( face, glyph->charcode );
|
||||||
|
for( j=0; j<self->glyphs->size; ++j )
|
||||||
|
{
|
||||||
|
prev_glyph = (TextureGlyph *) vector_get( self->glyphs, j );
|
||||||
|
prev_index = FT_Get_Char_Index( face, prev_glyph->charcode );
|
||||||
|
FT_Get_Kerning( face, prev_index, glyph_index, FT_KERNING_UNFITTED, &kerning );
|
||||||
|
if( kerning.x != 0.0 )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No kerning at all */
|
||||||
|
if( !count )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store kerning pairs */
|
||||||
|
glyph->kerning = (KerningPair *) malloc( count * sizeof(KerningPair) );
|
||||||
|
glyph->kerning_count = count;
|
||||||
|
k = 0;
|
||||||
|
for( j=0; j<self->glyphs->size; ++j )
|
||||||
|
{
|
||||||
|
prev_glyph = (TextureGlyph *) vector_get( self->glyphs, j );
|
||||||
|
prev_index = FT_Get_Char_Index( face, prev_glyph->charcode );
|
||||||
|
FT_Get_Kerning( face, prev_index, glyph_index, FT_KERNING_UNFITTED, &kerning );
|
||||||
|
if( kerning.x != 0.0 )
|
||||||
|
{
|
||||||
|
glyph->kerning[k].charcode = prev_glyph->charcode;
|
||||||
|
// 64 * 64 because of 26.6 encoding AND the transform matrix used
|
||||||
|
// in texture_font_load_face (hres = 64)
|
||||||
|
glyph->kerning[k].kerning = kerning.x/ (float)(64.0f*64.0f);
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_Done_Face( face );
|
||||||
|
FT_Done_FreeType( library );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
size_t
|
||||||
|
texture_font_cache_glyphs( TextureFont *self,
|
||||||
|
const wchar_t * charcodes )
|
||||||
|
{
|
||||||
|
size_t i, x, y, width, height, depth, w, h;
|
||||||
|
FT_Library library;
|
||||||
|
FT_Error error;
|
||||||
|
FT_Face face;
|
||||||
|
FT_GlyphSlot slot;
|
||||||
|
FT_UInt glyph_index;
|
||||||
|
TextureGlyph *glyph;
|
||||||
|
Region region;
|
||||||
|
unsigned char c;
|
||||||
|
size_t missed = 0;
|
||||||
|
width = self->atlas->width;
|
||||||
|
height = self->atlas->height;
|
||||||
|
depth = self->atlas->depth;
|
||||||
|
|
||||||
|
if( !texture_font_load_face( &library, self->filename, self->size, &face ) )
|
||||||
|
{
|
||||||
|
return wcslen(charcodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load each glyph */
|
||||||
|
for( i=0; i<wcslen(charcodes); ++i )
|
||||||
|
{
|
||||||
|
glyph_index = FT_Get_Char_Index( face, charcodes[i] );
|
||||||
|
|
||||||
|
// WARNING: We use texture-atlas depth to guess if user wants
|
||||||
|
// LCD subpixel rendering
|
||||||
|
FT_Int32 flags = FT_LOAD_RENDER;
|
||||||
|
|
||||||
|
if( !self->hinting )
|
||||||
|
{
|
||||||
|
flags |= FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flags |= FT_LOAD_FORCE_AUTOHINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( depth == 3 )
|
||||||
|
{
|
||||||
|
FT_Library_SetLcdFilter( library, FT_LCD_FILTER_LIGHT );
|
||||||
|
flags |= FT_LOAD_TARGET_LCD;
|
||||||
|
if( self->lcd_filter )
|
||||||
|
{
|
||||||
|
FT_Library_SetLcdFilterWeights( library, self->lcd_weights );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error = FT_Load_Glyph( face, glyph_index, flags );
|
||||||
|
|
||||||
|
if( error )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
|
||||||
|
__LINE__, FT_Errors[error].code, FT_Errors[error].message);
|
||||||
|
FT_Done_FreeType( library );
|
||||||
|
return wcslen(charcodes)-i;
|
||||||
|
}
|
||||||
|
slot = face->glyph;
|
||||||
|
|
||||||
|
/* Gamma correction (sort of) */
|
||||||
|
for( x=0; x<slot->bitmap.width; ++x )
|
||||||
|
{
|
||||||
|
for( y=0; y<slot->bitmap.rows; ++y )
|
||||||
|
{
|
||||||
|
c = *(unsigned char *)(slot->bitmap.buffer
|
||||||
|
+ y*slot->bitmap.pitch + x );
|
||||||
|
c = (unsigned char) ( pow(c/255.0, self->gamma) * 255);
|
||||||
|
*(unsigned char *)(slot->bitmap.buffer
|
||||||
|
+ y*slot->bitmap.pitch + x ) = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want each glyph to be separated by at least one black pixel
|
||||||
|
// (for example for shader used in demo-subpixel.c)
|
||||||
|
w = slot->bitmap.width/depth + 1;
|
||||||
|
h = slot->bitmap.rows + 1;
|
||||||
|
region = texture_atlas_get_region( self->atlas, w, h );
|
||||||
|
if ( region.x < 0 )
|
||||||
|
{
|
||||||
|
missed++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
w = w - 1;
|
||||||
|
h = h - 1;
|
||||||
|
x = region.x;
|
||||||
|
y = region.y;
|
||||||
|
texture_atlas_set_region( self->atlas, x, y, w, h,
|
||||||
|
slot->bitmap.buffer, slot->bitmap.pitch );
|
||||||
|
|
||||||
|
glyph = texture_glyph_new( );
|
||||||
|
glyph->font = self;
|
||||||
|
glyph->charcode = charcodes[i];
|
||||||
|
glyph->kerning = 0;
|
||||||
|
glyph->width = w;
|
||||||
|
glyph->height = h;
|
||||||
|
glyph->offset_x = slot->bitmap_left;
|
||||||
|
glyph->offset_y = slot->bitmap_top;
|
||||||
|
glyph->u0 = x/(float)width;
|
||||||
|
glyph->v0 = y/(float)height;
|
||||||
|
glyph->u1 = (x + glyph->width)/(float)width;
|
||||||
|
glyph->v1 = (y + glyph->height)/(float)height;
|
||||||
|
|
||||||
|
/* Discard hinting to get advance */
|
||||||
|
FT_Load_Glyph( face, glyph_index, FT_LOAD_RENDER | FT_LOAD_NO_HINTING);
|
||||||
|
slot = face->glyph;
|
||||||
|
glyph->advance_x = slot->advance.x/64.0;
|
||||||
|
glyph->advance_y = slot->advance.y/64.0;
|
||||||
|
|
||||||
|
vector_push_back( self->glyphs, glyph );
|
||||||
|
texture_glyph_delete( glyph );
|
||||||
|
}
|
||||||
|
FT_Done_Face( face );
|
||||||
|
FT_Done_FreeType( library );
|
||||||
|
texture_atlas_upload( self->atlas );
|
||||||
|
texture_font_generate_kerning( self );
|
||||||
|
return missed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
TextureGlyph *
|
||||||
|
texture_font_get_glyph( TextureFont *self,
|
||||||
|
wchar_t charcode )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
static wchar_t *buffer = 0;
|
||||||
|
TextureGlyph *glyph;
|
||||||
|
|
||||||
|
assert( self );
|
||||||
|
assert( self->filename );
|
||||||
|
assert( self->atlas );
|
||||||
|
|
||||||
|
/* Check if charcode has been already loaded */
|
||||||
|
for( i=0; i<self->glyphs->size; ++i )
|
||||||
|
{
|
||||||
|
glyph = (TextureGlyph *) vector_get( self->glyphs, i );
|
||||||
|
if( glyph->charcode == charcode )
|
||||||
|
{
|
||||||
|
return glyph;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If not, load it */
|
||||||
|
if( !buffer)
|
||||||
|
{
|
||||||
|
buffer = (wchar_t *) calloc( 2, sizeof(wchar_t) );
|
||||||
|
}
|
||||||
|
buffer[0] = charcode;
|
||||||
|
|
||||||
|
if( texture_font_cache_glyphs( self, buffer ) == 0 )
|
||||||
|
{
|
||||||
|
return (TextureGlyph *) vector_back( self->glyphs );
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
int
|
||||||
|
texture_font_load_face( FT_Library * library,
|
||||||
|
const char * filename,
|
||||||
|
const float size,
|
||||||
|
FT_Face * face )
|
||||||
|
{
|
||||||
|
size_t hres = 64;
|
||||||
|
FT_Error error;
|
||||||
|
FT_Matrix matrix = { (int)((1.0/hres) * 0x10000L),
|
||||||
|
(int)((0.0) * 0x10000L),
|
||||||
|
(int)((0.0) * 0x10000L),
|
||||||
|
(int)((1.0) * 0x10000L) };
|
||||||
|
|
||||||
|
/* Initialize library */
|
||||||
|
error = FT_Init_FreeType( library );
|
||||||
|
if( error )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "FT_Error (0x%02x) : %s\n",
|
||||||
|
FT_Errors[error].code, FT_Errors[error].message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load face */
|
||||||
|
error = FT_New_Face( *library, filename, 0, face );
|
||||||
|
if( error )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
|
||||||
|
__LINE__, FT_Errors[error].code, FT_Errors[error].message);
|
||||||
|
FT_Done_FreeType( *library );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select charmap */
|
||||||
|
error = FT_Select_Charmap( *face, FT_ENCODING_UNICODE );
|
||||||
|
if( error )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
|
||||||
|
__LINE__, FT_Errors[error].code, FT_Errors[error].message);
|
||||||
|
FT_Done_Face( *face );
|
||||||
|
FT_Done_FreeType( *library );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set char size */
|
||||||
|
error = FT_Set_Char_Size( *face, (int)(size*64), 0, 72*hres, 72 );
|
||||||
|
|
||||||
|
/* error = FT_Set_Char_Size( *face, size*64, 0, 72, 72 ); */
|
||||||
|
if( error )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
|
||||||
|
__LINE__, FT_Errors[error].code, FT_Errors[error].message);
|
||||||
|
FT_Done_Face( *face );
|
||||||
|
FT_Done_FreeType( *library );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set transform matrix */
|
||||||
|
FT_Set_Transform( *face, &matrix, NULL );
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
225
source/shared_lib/sources/graphics/freetype-gl/texture-glyph.c
Normal file
225
source/shared_lib/sources/graphics/freetype-gl/texture-glyph.c
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <Glut/glut.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#endif
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "texture-font.h"
|
||||||
|
#include "texture-glyph.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
TextureGlyph *
|
||||||
|
texture_glyph_new( void )
|
||||||
|
{
|
||||||
|
TextureGlyph *self = (TextureGlyph *) malloc( sizeof(TextureGlyph) );
|
||||||
|
if(! self )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
self->width = 0;
|
||||||
|
self->height = 0;
|
||||||
|
self->offset_x = 0;
|
||||||
|
self->offset_y = 0;
|
||||||
|
self->advance_x = 0.0;
|
||||||
|
self->advance_y = 0.0;
|
||||||
|
self->u0 = 0.0;
|
||||||
|
self->v0 = 0.0;
|
||||||
|
self->u1 = 0.0;
|
||||||
|
self->v1 = 0.0;
|
||||||
|
self->kerning_count = 0;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
texture_glyph_delete( TextureGlyph *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
free( self );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
texture_glyph_render( TextureGlyph *self,
|
||||||
|
Markup *markup,
|
||||||
|
Pen *pen )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
int x = pen->x + self->offset_x;
|
||||||
|
int y = pen->y + self->offset_y + markup->rise;
|
||||||
|
int w = self->width;
|
||||||
|
int h = self->height;
|
||||||
|
|
||||||
|
float u0 = self->u0;
|
||||||
|
float v0 = self->v0;
|
||||||
|
float u1 = self->u1;
|
||||||
|
float v1 = self->v1;
|
||||||
|
|
||||||
|
glBegin( GL_TRIANGLES );
|
||||||
|
{
|
||||||
|
glTexCoord2f( u0, v0 ); glVertex2i( x, y );
|
||||||
|
glTexCoord2f( u0, v1 ); glVertex2i( x, y-h );
|
||||||
|
glTexCoord2f( u1, v1 ); glVertex2i( x+w, y-h );
|
||||||
|
|
||||||
|
glTexCoord2f( u0, v0 ); glVertex2i( x, y );
|
||||||
|
glTexCoord2f( u1, v1 ); glVertex2i( x+w, y-h );
|
||||||
|
glTexCoord2f( u1, v0 ); glVertex2i( x+w, y );
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
pen->x += self->advance_x + markup->spacing;
|
||||||
|
pen->y += self->advance_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
texture_glyph_add_to_vertex_buffer( const TextureGlyph *self,
|
||||||
|
VertexBuffer *buffer,
|
||||||
|
const Markup *markup,
|
||||||
|
Pen *pen, int kerning )
|
||||||
|
{
|
||||||
|
TextureFont *font = self->font;
|
||||||
|
float r = 1;
|
||||||
|
float g = 1;
|
||||||
|
float b = 1;
|
||||||
|
float a = 1;
|
||||||
|
int rise = 0;
|
||||||
|
int spacing = 0;
|
||||||
|
|
||||||
|
if( markup )
|
||||||
|
{
|
||||||
|
rise = markup->rise;
|
||||||
|
spacing = markup->spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
pen->x += kerning;
|
||||||
|
|
||||||
|
// Background
|
||||||
|
if( markup && markup->background_color.a > 0 )
|
||||||
|
{
|
||||||
|
float u0 = font->atlas->black.x / (float) font->atlas->width;
|
||||||
|
float v0 = font->atlas->black.y / (float) font->atlas->height;
|
||||||
|
float u1 = u0 + font->atlas->black.width / (float) font->atlas->width;
|
||||||
|
float v1 = v0 + font->atlas->black.height / (float) font->atlas->height;
|
||||||
|
int x0 = pen->x - kerning;
|
||||||
|
int y0 = pen->y + font->descender;
|
||||||
|
int x1 = x0 + self->advance_x + markup->spacing + kerning;
|
||||||
|
int y1 = y0 + font->height - font->linegap;
|
||||||
|
r = markup->background_color.r;
|
||||||
|
g = markup->background_color.g;
|
||||||
|
b = markup->background_color.b;
|
||||||
|
a = markup->background_color.a;
|
||||||
|
GLuint index = buffer->vertices->size;
|
||||||
|
GLuint indices[] = {index, index+1, index+2,
|
||||||
|
index, index+2, index+3};
|
||||||
|
TextureGlyphVertex vertices[] = { { x0,y0,0, u0,v0, r,g,b,a },
|
||||||
|
{ x0,y1,0, u0,v1, r,g,b,a },
|
||||||
|
{ x1,y1,0, u1,v1, r,g,b,a },
|
||||||
|
{ x1,y0,0, u1,v0, r,g,b,a } };
|
||||||
|
vertex_buffer_push_back_indices( buffer, indices, 6 );
|
||||||
|
vertex_buffer_push_back_vertices( buffer, vertices, 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Underline
|
||||||
|
|
||||||
|
// Overline
|
||||||
|
|
||||||
|
// Outline
|
||||||
|
|
||||||
|
// Strikethrough
|
||||||
|
|
||||||
|
// Actual glyph
|
||||||
|
if( markup )
|
||||||
|
{
|
||||||
|
r = markup->foreground_color.r;
|
||||||
|
g = markup->foreground_color.g;
|
||||||
|
b = markup->foreground_color.b;
|
||||||
|
a = markup->foreground_color.a;
|
||||||
|
}
|
||||||
|
int x0 = (int)( pen->x + self->offset_x );
|
||||||
|
int y0 = (int)( pen->y + self->offset_y + rise );
|
||||||
|
int x1 = (int)( x0 + self->width );
|
||||||
|
int y1 = (int)( y0 - self->height );
|
||||||
|
float u0 = self->u0;
|
||||||
|
float v0 = self->v0;
|
||||||
|
float u1 = self->u1;
|
||||||
|
float v1 = self->v1;
|
||||||
|
GLuint index = buffer->vertices->size;
|
||||||
|
GLuint indices[] = {index, index+1, index+2,
|
||||||
|
index, index+2, index+3};
|
||||||
|
TextureGlyphVertex vertices[] = { { x0,y0,0, u0,v0, r,g,b,a },
|
||||||
|
{ x0,y1,0, u0,v1, r,g,b,a },
|
||||||
|
{ x1,y1,0, u1,v1, r,g,b,a },
|
||||||
|
{ x1,y0,0, u1,v0, r,g,b,a } };
|
||||||
|
vertex_buffer_push_back_indices( buffer, indices, 6 );
|
||||||
|
vertex_buffer_push_back_vertices( buffer, vertices, 4 );
|
||||||
|
|
||||||
|
pen->x += self->advance_x + spacing;
|
||||||
|
pen->y += self->advance_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
float
|
||||||
|
texture_glyph_get_kerning( TextureGlyph *self,
|
||||||
|
wchar_t charcode )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
assert( self );
|
||||||
|
if( !self->kerning )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i=0; i<self->kerning_count; ++i )
|
||||||
|
{
|
||||||
|
if( self->kerning[i].charcode == charcode )
|
||||||
|
{
|
||||||
|
return self->kerning[i].kerning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
362
source/shared_lib/sources/graphics/freetype-gl/vector.c
Normal file
362
source/shared_lib/sources/graphics/freetype-gl/vector.c
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
Vector *
|
||||||
|
vector_new( size_t item_size )
|
||||||
|
{
|
||||||
|
assert( item_size );
|
||||||
|
|
||||||
|
Vector *self = (Vector *) malloc( sizeof(Vector) );
|
||||||
|
if( !self )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
self->item_size = item_size;
|
||||||
|
self->size = 0;
|
||||||
|
self->capacity = 1;
|
||||||
|
self->items = malloc( self->item_size * self->capacity );
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_delete( Vector *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
free( self->items );
|
||||||
|
free( self );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
const void *
|
||||||
|
vector_get( const Vector *self,
|
||||||
|
size_t index )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( self->size );
|
||||||
|
assert( index < self->size );
|
||||||
|
return self->items + index * self->item_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
const void *
|
||||||
|
vector_front( const Vector *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( self->size );
|
||||||
|
return vector_get( self, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
const void *
|
||||||
|
vector_back( const Vector *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( self->size );
|
||||||
|
return vector_get( self, self->size-1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
int
|
||||||
|
vector_contains( const Vector *self,
|
||||||
|
const void *item,
|
||||||
|
int (*cmp)(const void *, const void *) )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
assert( self );
|
||||||
|
for( i=0; i<self->size; ++i )
|
||||||
|
{
|
||||||
|
if( (*cmp)(item, vector_get(self,i) ) == 0 )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
int
|
||||||
|
vector_empty( const Vector *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
size_t
|
||||||
|
vector_size( const Vector *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_reserve( Vector *self,
|
||||||
|
const size_t size )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
if( self->capacity < size);
|
||||||
|
{
|
||||||
|
self->items = realloc( self->items, size * self->item_size );
|
||||||
|
self->capacity = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
size_t
|
||||||
|
vector_capacity( const Vector *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
return self->capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_shrink( Vector *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
if( self->capacity > self->size )
|
||||||
|
{
|
||||||
|
self->items = realloc( self->items, self->size * self->item_size );
|
||||||
|
}
|
||||||
|
self->capacity = self->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_clear( Vector *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
self->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_set( Vector *self,
|
||||||
|
const size_t index,
|
||||||
|
const void *item )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( self->size );
|
||||||
|
assert( index < self->size );
|
||||||
|
memcpy( self->items + index * self->item_size,
|
||||||
|
item, self->item_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_insert( Vector *self,
|
||||||
|
const size_t index,
|
||||||
|
const void *item )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( index <= self->size);
|
||||||
|
|
||||||
|
if( self->capacity <= self->size )
|
||||||
|
{
|
||||||
|
vector_reserve(self, 2 * self->capacity );
|
||||||
|
}
|
||||||
|
if( index < self->size )
|
||||||
|
{
|
||||||
|
memmove( self->items + (index + 1) * self->item_size,
|
||||||
|
self->items + (index + 0) * self->item_size,
|
||||||
|
(self->size - index) * self->item_size);
|
||||||
|
}
|
||||||
|
self->size++;
|
||||||
|
vector_set( self, index, item );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_erase_range( Vector *self,
|
||||||
|
const size_t first,
|
||||||
|
const size_t last )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( first < self->size );
|
||||||
|
assert( last < self->size+1 );
|
||||||
|
assert( first < last );
|
||||||
|
memmove( self->items + first * self->item_size,
|
||||||
|
self->items + last * self->item_size,
|
||||||
|
(self->size - last) * self->item_size);
|
||||||
|
self->size -= (last-first);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_erase( Vector *self,
|
||||||
|
const size_t index )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( index < self->size );
|
||||||
|
|
||||||
|
vector_erase_range( self, index, index+1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_push_back( Vector *self,
|
||||||
|
const void *item )
|
||||||
|
{
|
||||||
|
vector_insert( self, self->size, item );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_pop_back( Vector *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( self->size );
|
||||||
|
self->size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_resize( Vector *self,
|
||||||
|
const size_t size )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
if( size > self->capacity)
|
||||||
|
{
|
||||||
|
vector_reserve( self, size );
|
||||||
|
self->size = self->capacity;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_push_back_data( Vector *self,
|
||||||
|
const void * data,
|
||||||
|
const size_t count )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( data );
|
||||||
|
assert( count );
|
||||||
|
|
||||||
|
if( self->capacity < (self->size+count) )
|
||||||
|
{
|
||||||
|
vector_reserve(self, self->size+count);
|
||||||
|
}
|
||||||
|
memmove( self->items + self->size * self->item_size, data,
|
||||||
|
count*self->item_size );
|
||||||
|
self->size += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_insert_data( Vector *self,
|
||||||
|
const size_t index,
|
||||||
|
const void * data,
|
||||||
|
const size_t count )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( index < self->size );
|
||||||
|
assert( data );
|
||||||
|
assert( count );
|
||||||
|
|
||||||
|
if( self->capacity < (self->size+count) )
|
||||||
|
{
|
||||||
|
vector_reserve(self, self->size+count);
|
||||||
|
}
|
||||||
|
memmove( self->items + (index + count ) * self->item_size,
|
||||||
|
self->items + (index ) * self->item_size,
|
||||||
|
count*self->item_size );
|
||||||
|
memmove( self->items + index * self->item_size, data,
|
||||||
|
count*self->item_size );
|
||||||
|
self->size += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
vector_sort( Vector *self,
|
||||||
|
int (*cmp)(const void *, const void *) )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
assert( self->size );
|
||||||
|
qsort(self->items, self->size, self->item_size, cmp);
|
||||||
|
}
|
722
source/shared_lib/sources/graphics/freetype-gl/vertex-buffer.c
Normal file
722
source/shared_lib/sources/graphics/freetype-gl/vertex-buffer.c
Normal file
@@ -0,0 +1,722 @@
|
|||||||
|
/* =========================================================================
|
||||||
|
* Freetype GL - A C OpenGL Freetype engine
|
||||||
|
* Platform: Any
|
||||||
|
* WWW: http://code.google.com/p/freetype-gl/
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright 2011 Nicolas P. Rougier. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are
|
||||||
|
* those of the authors and should not be interpreted as representing official
|
||||||
|
* policies, either expressed or implied, of Nicolas P. Rougier.
|
||||||
|
* ========================================================================= */
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "vertex-buffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
VertexBuffer *
|
||||||
|
vertex_buffer_new( const char *format )
|
||||||
|
{
|
||||||
|
size_t i, index = 0, stride = 0;
|
||||||
|
const char *start = 0, *end = 0;
|
||||||
|
GLvoid *pointer = 0;
|
||||||
|
|
||||||
|
VertexBuffer *self = (VertexBuffer *) malloc (sizeof(VertexBuffer));
|
||||||
|
if( !self )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->format = strdup( format );
|
||||||
|
|
||||||
|
for( i=0; i<MAX_VERTEX_ATTRIBUTE; ++i )
|
||||||
|
{
|
||||||
|
self->attributes[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = format;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
end = (char *) (strchr(start+1, ':'));
|
||||||
|
char *desc = 0;
|
||||||
|
if (end == NULL)
|
||||||
|
{
|
||||||
|
desc = strdup(start);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
desc = strndup(start, end-start);
|
||||||
|
}
|
||||||
|
VertexAttribute *attribute = vertex_attribute_parse( desc );
|
||||||
|
start = end+1;
|
||||||
|
free(desc);
|
||||||
|
attribute->pointer = pointer;
|
||||||
|
stride += attribute->size*GL_TYPE_SIZE( attribute->type );
|
||||||
|
pointer+= attribute->size*GL_TYPE_SIZE( attribute->type );
|
||||||
|
self->attributes[index] = attribute;
|
||||||
|
index++;
|
||||||
|
} while ( end && (index < MAX_VERTEX_ATTRIBUTE) );
|
||||||
|
|
||||||
|
for( i=0; i<index; ++i )
|
||||||
|
{
|
||||||
|
self->attributes[i]->stride = stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->vertices = vector_new( stride );
|
||||||
|
self->vertices_id = 0;
|
||||||
|
self->indices = vector_new( sizeof(GLuint) );
|
||||||
|
self->indices_id = 0;
|
||||||
|
self->dirty = 1;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
VertexBuffer *
|
||||||
|
vertex_buffer_new_from_data( char *format,
|
||||||
|
size_t vcount,
|
||||||
|
void *vertices,
|
||||||
|
size_t icount,
|
||||||
|
GLuint *indices )
|
||||||
|
{
|
||||||
|
VertexBuffer *self = vertex_buffer_new( format );
|
||||||
|
|
||||||
|
vector_resize( self->vertices, vcount );
|
||||||
|
assert( self->vertices->size == vcount);
|
||||||
|
memcpy( self->vertices->items, vertices, vcount*self->vertices->item_size );
|
||||||
|
vector_resize( self->indices, icount );
|
||||||
|
assert( self->indices->size == icount);
|
||||||
|
memcpy( self->indices->items, indices, icount*self->indices->item_size );
|
||||||
|
self->dirty = 1;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_delete( VertexBuffer *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
vector_delete( self->vertices );
|
||||||
|
self->vertices = 0;
|
||||||
|
if( self->vertices_id )
|
||||||
|
{
|
||||||
|
glDeleteBuffers( 1, &self->vertices_id );
|
||||||
|
}
|
||||||
|
self->vertices_id = 0;
|
||||||
|
|
||||||
|
vector_delete( self->indices );
|
||||||
|
self->indices = 0;
|
||||||
|
if( self->indices_id )
|
||||||
|
{
|
||||||
|
glDeleteBuffers( 1, &self->vertices_id );
|
||||||
|
}
|
||||||
|
self->indices_id = 0;
|
||||||
|
if( self->format )
|
||||||
|
{
|
||||||
|
free( self->format );
|
||||||
|
}
|
||||||
|
self->format = 0;
|
||||||
|
self->dirty = 0;
|
||||||
|
free( self );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_print( VertexBuffer * self )
|
||||||
|
{
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
fprintf( stderr, "%ld vertices, %ld indices\n",
|
||||||
|
vector_size( self->vertices ), vector_size( self->indices ) );
|
||||||
|
|
||||||
|
while( self->attributes[i] )
|
||||||
|
{
|
||||||
|
if( self->attributes[i]->target > 0 )
|
||||||
|
{
|
||||||
|
switch(self->attributes[i]->target )
|
||||||
|
{
|
||||||
|
case GL_VERTEX_ARRAY:
|
||||||
|
fprintf( stderr, " -> Position: ");
|
||||||
|
break;
|
||||||
|
case GL_NORMAL_ARRAY:
|
||||||
|
fprintf( stderr, " -> Normal: ");
|
||||||
|
break;
|
||||||
|
case GL_COLOR_ARRAY:
|
||||||
|
fprintf( stderr, " -> Color: ");
|
||||||
|
break;
|
||||||
|
case GL_TEXTURE_COORD_ARRAY:
|
||||||
|
fprintf( stderr, " -> Texture coord: ");
|
||||||
|
break;
|
||||||
|
case GL_FOG_COORD_ARRAY:
|
||||||
|
fprintf( stderr, " -> Fog coord: ");
|
||||||
|
break;
|
||||||
|
case GL_SECONDARY_COLOR_ARRAY:
|
||||||
|
fprintf( stderr, " -> Secondary color: ");
|
||||||
|
break;
|
||||||
|
case GL_EDGE_FLAG_ARRAY:
|
||||||
|
fprintf( stderr, " -> Edge flag: ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf( stderr, " -> Unknown: ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf( stderr, " -> Generic attribute n°%d: ",
|
||||||
|
self->attributes[i]->index );
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%dx%s (+%ld)\n",
|
||||||
|
self->attributes[i]->size,
|
||||||
|
GL_TYPE_STRING( self->attributes[i]->type ),
|
||||||
|
(long) self->attributes[i]->pointer);
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_upload ( VertexBuffer *self )
|
||||||
|
{
|
||||||
|
if( !self->vertices_id )
|
||||||
|
{
|
||||||
|
glGenBuffers( 1, &self->vertices_id );
|
||||||
|
}
|
||||||
|
if( !self->indices_id )
|
||||||
|
{
|
||||||
|
glGenBuffers( 1, &self->indices_id );
|
||||||
|
}
|
||||||
|
glBindBuffer( GL_ARRAY_BUFFER, self->vertices_id );
|
||||||
|
glBufferData( GL_ARRAY_BUFFER,
|
||||||
|
self->vertices->size*self->vertices->item_size,
|
||||||
|
self->vertices->items, GL_DYNAMIC_DRAW );
|
||||||
|
glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
||||||
|
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, self->indices_id );
|
||||||
|
glBufferData( GL_ELEMENT_ARRAY_BUFFER,
|
||||||
|
self->indices->size*self->indices->item_size,
|
||||||
|
self->indices->items, GL_DYNAMIC_DRAW );
|
||||||
|
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_clear( VertexBuffer *self )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
vector_clear( self->indices );
|
||||||
|
vector_clear( self->vertices );
|
||||||
|
self->dirty = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_render ( VertexBuffer *self,
|
||||||
|
GLenum mode,
|
||||||
|
const char *what )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
if( !self->vertices->size )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( self->dirty )
|
||||||
|
{
|
||||||
|
vertex_buffer_upload( self );
|
||||||
|
self->dirty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
|
||||||
|
glBindBuffer( GL_ARRAY_BUFFER, self->vertices_id );
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
for( i=0; i<MAX_VERTEX_ATTRIBUTE; ++i )
|
||||||
|
{
|
||||||
|
VertexAttribute *attribute = self->attributes[i];
|
||||||
|
if ( attribute == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (attribute->ctarget == 'g')
|
||||||
|
{
|
||||||
|
(*(attribute->enable))( attribute );
|
||||||
|
}
|
||||||
|
else if ( strchr(what, attribute->ctarget) )
|
||||||
|
{
|
||||||
|
(*(attribute->enable))( attribute );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( self->indices->size )
|
||||||
|
{
|
||||||
|
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, self->indices_id );
|
||||||
|
glDrawElements( mode, self->indices->size, GL_UNSIGNED_INT, 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glDrawArrays( mode, 0, self->vertices->size );
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
||||||
|
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
|
||||||
|
glPopClientAttrib( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_push_back_index ( VertexBuffer *self,
|
||||||
|
GLuint index )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
self->dirty = 1;
|
||||||
|
vector_push_back( self->indices, &index );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_push_back_vertex ( VertexBuffer *self,
|
||||||
|
void *vertex )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
self->dirty = 1;
|
||||||
|
vector_push_back( self->vertices, vertex );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_push_back_indices ( VertexBuffer *self,
|
||||||
|
GLuint *indices,
|
||||||
|
size_t count )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
self->dirty = 1;
|
||||||
|
vector_push_back_data( self->indices, indices, count );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_push_back_vertices ( VertexBuffer *self,
|
||||||
|
void *vertices,
|
||||||
|
size_t count )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
self->dirty = 1;
|
||||||
|
vector_push_back_data( self->vertices, vertices, count );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_insert_indices ( VertexBuffer *self,
|
||||||
|
size_t index,
|
||||||
|
GLuint *indices,
|
||||||
|
size_t count )
|
||||||
|
{
|
||||||
|
assert( self );
|
||||||
|
|
||||||
|
self->dirty = 1;
|
||||||
|
vector_insert_data( self->indices, index, indices, count );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_buffer_insert_vertices ( VertexBuffer *self,
|
||||||
|
size_t index,
|
||||||
|
void *vertices,
|
||||||
|
size_t count )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
assert( self );
|
||||||
|
assert( self->vertices );
|
||||||
|
assert( index < self->vertices->size+1 );
|
||||||
|
|
||||||
|
self->dirty = 1;
|
||||||
|
for( i=0; i<self->indices->size-index; ++i )
|
||||||
|
{
|
||||||
|
if( *(GLuint *)(vector_get( self->indices, i )) > index )
|
||||||
|
{
|
||||||
|
*(GLuint *)(vector_get( self->indices, i )) += index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector_insert_data( self->vertices, index, vertices, count );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_attribute_position_enable( VertexAttribute *attr )
|
||||||
|
{
|
||||||
|
glEnableClientState( attr->target );
|
||||||
|
glVertexPointer( attr->size, attr->type, attr->stride, attr->pointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_attribute_normal_enable( VertexAttribute *attr )
|
||||||
|
{
|
||||||
|
glEnableClientState( attr->target );
|
||||||
|
glNormalPointer( attr->type, attr->stride, attr->pointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_attribute_color_enable( VertexAttribute *attr )
|
||||||
|
{
|
||||||
|
glEnableClientState( attr->target );
|
||||||
|
glColorPointer( attr->size, attr->type, attr->stride, attr->pointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_attribute_tex_coord_enable( VertexAttribute *attr )
|
||||||
|
{
|
||||||
|
glEnableClientState( attr->target );
|
||||||
|
glTexCoordPointer( attr->size, attr->type, attr->stride, attr->pointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_attribute_fog_coord_enable( VertexAttribute *attr )
|
||||||
|
{
|
||||||
|
glEnableClientState( attr->target );
|
||||||
|
glFogCoordPointer( attr->type, attr->stride, attr->pointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_attribute_edge_flag_enable( VertexAttribute *attr )
|
||||||
|
{
|
||||||
|
glEnableClientState( attr->target );
|
||||||
|
glEdgeFlagPointer( attr->stride, attr->pointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_attribute_secondary_color_enable( VertexAttribute *attr )
|
||||||
|
{
|
||||||
|
glEnableClientState( attr->target );
|
||||||
|
glSecondaryColorPointer( attr->size, attr->type, attr->stride, attr->pointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
vertex_attribute_generic_enable( VertexAttribute *attr )
|
||||||
|
{
|
||||||
|
glEnableVertexAttribArray( attr->index );
|
||||||
|
glVertexAttribPointer( attr->index, attr->size, attr->type,
|
||||||
|
attr->normalized, attr->stride, attr->pointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
VertexAttribute *
|
||||||
|
vertex_attribute_parse( char *format )
|
||||||
|
{
|
||||||
|
// Generic attribute
|
||||||
|
char *p = strpbrk ( format, "0123456789" );
|
||||||
|
if (p == format)
|
||||||
|
{
|
||||||
|
// Normalized
|
||||||
|
p = strpbrk ( format, "n" );
|
||||||
|
if ( p != NULL )
|
||||||
|
{
|
||||||
|
int size, index;
|
||||||
|
char ctype;
|
||||||
|
sscanf( format, "%dgn%d%c", &index, &size, &ctype );
|
||||||
|
GLenum type = GL_TYPE( ctype );
|
||||||
|
return vertex_attribute_new( 0, index, size, type, GL_TRUE, 0, 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int size, index;
|
||||||
|
char ctype;
|
||||||
|
sscanf( format, "%dg%d%c", &index, &size, &ctype );
|
||||||
|
GLenum type = GL_TYPE( ctype );
|
||||||
|
return vertex_attribute_new( 0, index, size, type, GL_FALSE, 0, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Known attribute
|
||||||
|
p = strpbrk ( format, "vcntfse" );
|
||||||
|
if ( p != 0 )
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
char ctarget, ctype;
|
||||||
|
sscanf( format, "%c%d%c", &ctarget, &size, &ctype );
|
||||||
|
GLenum type = GL_TYPE( ctype );
|
||||||
|
GLenum target = GL_VERTEX_ATTRIBUTE_TARGET( ctarget );
|
||||||
|
return vertex_attribute_new( target, 0, size, type, GL_FALSE, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Vertex attribute format not understood\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
VertexAttribute *
|
||||||
|
vertex_attribute_new( GLenum target,
|
||||||
|
GLuint index,
|
||||||
|
GLint size,
|
||||||
|
GLenum type,
|
||||||
|
GLboolean normalized,
|
||||||
|
GLsizei stride,
|
||||||
|
GLvoid *pointer )
|
||||||
|
{
|
||||||
|
VertexAttribute *attribute = (VertexAttribute *) malloc (sizeof(VertexAttribute));
|
||||||
|
assert( size > 0 );
|
||||||
|
|
||||||
|
// Generic attribute
|
||||||
|
if (target == 0)
|
||||||
|
{
|
||||||
|
attribute->ctarget = 'g';
|
||||||
|
assert( (size < 4) );
|
||||||
|
assert( (type == GL_BYTE) || (type == GL_UNSIGNED_BYTE) ||
|
||||||
|
(type == GL_SHORT) || (type == GL_UNSIGNED_SHORT) ||
|
||||||
|
(type == GL_INT) || (type == GL_UNSIGNED_INT) ||
|
||||||
|
(type == GL_FLOAT) || (type == GL_DOUBLE) );
|
||||||
|
attribute->enable =
|
||||||
|
(void(*)(void *)) vertex_attribute_generic_enable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Standard attribute
|
||||||
|
switch( target )
|
||||||
|
{
|
||||||
|
case GL_VERTEX_ARRAY:
|
||||||
|
attribute->ctarget = 'v';
|
||||||
|
assert( size > 1 );
|
||||||
|
attribute->enable =
|
||||||
|
(void(*)(void *)) vertex_attribute_position_enable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_NORMAL_ARRAY:
|
||||||
|
attribute->ctarget = 'n';
|
||||||
|
assert (size == 3);
|
||||||
|
assert( (type == GL_BYTE) || (type == GL_SHORT) ||
|
||||||
|
(type == GL_INT) || (type == GL_FLOAT) ||
|
||||||
|
(type == GL_DOUBLE) );
|
||||||
|
attribute->enable =
|
||||||
|
(void(*)(void *)) vertex_attribute_normal_enable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_COLOR_ARRAY:
|
||||||
|
attribute->ctarget = 'c';
|
||||||
|
assert( (size == 3) || (size == 4) );
|
||||||
|
assert( (type == GL_BYTE) || (type == GL_UNSIGNED_BYTE) ||
|
||||||
|
(type == GL_SHORT) || (type == GL_UNSIGNED_SHORT) ||
|
||||||
|
(type == GL_INT) || (type == GL_UNSIGNED_INT) ||
|
||||||
|
(type == GL_FLOAT) || (type == GL_DOUBLE) );
|
||||||
|
attribute->enable =
|
||||||
|
(void(*)(void *)) vertex_attribute_color_enable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_TEXTURE_COORD_ARRAY:
|
||||||
|
attribute->ctarget = 't';
|
||||||
|
assert( (type == GL_SHORT) || (type == GL_INT) ||
|
||||||
|
(type == GL_FLOAT) || (type == GL_DOUBLE) );
|
||||||
|
attribute->enable =
|
||||||
|
(void(*)(void *)) vertex_attribute_tex_coord_enable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_FOG_COORD_ARRAY:
|
||||||
|
attribute->ctarget = 'f';
|
||||||
|
assert( size == 2 );
|
||||||
|
assert( (type == GL_FLOAT) || (type == GL_DOUBLE) );
|
||||||
|
attribute->enable =
|
||||||
|
(void(*)(void *)) vertex_attribute_fog_coord_enable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_EDGE_FLAG_ARRAY:
|
||||||
|
attribute->ctarget = 'e';
|
||||||
|
assert( size == 1 );
|
||||||
|
assert( type == GL_BOOL );
|
||||||
|
attribute->enable =
|
||||||
|
(void(*)(void *)) vertex_attribute_edge_flag_enable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_SECONDARY_COLOR_ARRAY:
|
||||||
|
attribute->ctarget = 's';
|
||||||
|
assert( size == 3 );
|
||||||
|
assert( (type == GL_BYTE) || (type == GL_UNSIGNED_BYTE) ||
|
||||||
|
(type == GL_SHORT) || (type == GL_UNSIGNED_SHORT) ||
|
||||||
|
(type == GL_INT) || (type == GL_UNSIGNED_INT) ||
|
||||||
|
(type == GL_FLOAT) || (type == GL_DOUBLE) );
|
||||||
|
attribute->enable =
|
||||||
|
(void(*)(void *)) vertex_attribute_secondary_color_enable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Vertex attribute format not understood\n");
|
||||||
|
attribute->enable = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute->target = target;
|
||||||
|
attribute->index = index;
|
||||||
|
attribute->size = size;
|
||||||
|
attribute->type = type;
|
||||||
|
attribute->normalized = normalized;
|
||||||
|
attribute->stride = stride;
|
||||||
|
attribute->pointer = pointer;
|
||||||
|
|
||||||
|
return attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
GLenum
|
||||||
|
GL_TYPE( char ctype )
|
||||||
|
{
|
||||||
|
switch( ctype )
|
||||||
|
{
|
||||||
|
case 'b': return GL_BYTE;
|
||||||
|
case 'B': return GL_UNSIGNED_BYTE;
|
||||||
|
case 's': return GL_SHORT;
|
||||||
|
case 'S': return GL_UNSIGNED_SHORT;
|
||||||
|
case 'i': return GL_INT;
|
||||||
|
case 'I': return GL_UNSIGNED_INT;
|
||||||
|
case 'f': return GL_FLOAT;
|
||||||
|
case 'd': return GL_DOUBLE;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
GLenum
|
||||||
|
GL_VERTEX_ATTRIBUTE_TARGET( char ctarget )
|
||||||
|
{
|
||||||
|
switch( ctarget )
|
||||||
|
{
|
||||||
|
case 'v': return GL_VERTEX_ARRAY;
|
||||||
|
case 'n': return GL_NORMAL_ARRAY;
|
||||||
|
case 'c': return GL_COLOR_ARRAY;
|
||||||
|
case 't': return GL_TEXTURE_COORD_ARRAY;
|
||||||
|
case 'f': return GL_FOG_COORD_ARRAY;
|
||||||
|
case 's': return GL_SECONDARY_COLOR_ARRAY;
|
||||||
|
case 'e': return GL_EDGE_FLAG_ARRAY;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
GLuint
|
||||||
|
GL_TYPE_SIZE( GLenum gtype )
|
||||||
|
{
|
||||||
|
switch( gtype )
|
||||||
|
{
|
||||||
|
case GL_BOOL: return sizeof(GLboolean);
|
||||||
|
case GL_BYTE: return sizeof(GLbyte);
|
||||||
|
case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
|
||||||
|
case GL_SHORT: return sizeof(GLshort);
|
||||||
|
case GL_UNSIGNED_SHORT: return sizeof(GLushort);
|
||||||
|
case GL_INT: return sizeof(GLint);
|
||||||
|
case GL_UNSIGNED_INT: return sizeof(GLuint);
|
||||||
|
case GL_FLOAT: return sizeof(GLfloat);
|
||||||
|
case GL_DOUBLE: return sizeof(GLdouble);
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
GL_TYPE_STRING( GLenum gtype )
|
||||||
|
{
|
||||||
|
switch( gtype )
|
||||||
|
{
|
||||||
|
case GL_BOOL: return "GL_BOOL";
|
||||||
|
case GL_BYTE: return "GL_BYTE";
|
||||||
|
case GL_UNSIGNED_BYTE: return "GL_UNSIGNED_BYTE";
|
||||||
|
case GL_SHORT: return "GL_SHORT";
|
||||||
|
case GL_UNSIGNED_SHORT: return "GL_UNSIGNED_SHORT";
|
||||||
|
case GL_INT: return "GL_INT";
|
||||||
|
case GL_UNSIGNED_INT: return "GL_UNSIGNED_INT";
|
||||||
|
case GL_FLOAT: return "GL_FLOAT";
|
||||||
|
case GL_DOUBLE: return "GL_DOUBLE";
|
||||||
|
default: return "GL_VOID";
|
||||||
|
}
|
||||||
|
}
|
336
source/shared_lib/sources/graphics/gl/font_text_freetypegl.cpp
Normal file
336
source/shared_lib/sources/graphics/gl/font_text_freetypegl.cpp
Normal file
@@ -0,0 +1,336 @@
|
|||||||
|
// ==============================================================
|
||||||
|
// This file is part of the MegaGlest Shared Library (www.megaglest.org)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2011 Mark Vejvoda and others
|
||||||
|
//
|
||||||
|
// You can redistribute this code and/or modify it under
|
||||||
|
// the terms of the GNU General Public License as published
|
||||||
|
// by the Free Software Foundation; either version 3 of the
|
||||||
|
// License, or (at your option) any later version
|
||||||
|
// ==============================================================
|
||||||
|
|
||||||
|
#ifdef USE_FREETYPEGL
|
||||||
|
|
||||||
|
#include "font_text_freetypegl.h"
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
//#include "opengl.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_FONTCONFIG
|
||||||
|
#include <fontconfig/fontconfig.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Shared::Util;
|
||||||
|
|
||||||
|
namespace Shared { namespace Graphics { namespace Gl {
|
||||||
|
|
||||||
|
|
||||||
|
//string TextFreetypeGL::langHeightText = "yW";
|
||||||
|
//int TextFreetypeGL::faceResolution = 72;
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
TextFreetypeGL::TextFreetypeGL(FontTextHandlerType type) : Text(type) {
|
||||||
|
buffer=NULL;
|
||||||
|
atlas=NULL;
|
||||||
|
font=NULL;
|
||||||
|
manager=NULL;
|
||||||
|
|
||||||
|
init("", 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFreetypeGL::~TextFreetypeGL() {
|
||||||
|
cleanupFont();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFreetypeGL::cleanupFont() {
|
||||||
|
if(font) {
|
||||||
|
texture_font_delete(font);
|
||||||
|
font = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFreetypeGL::init(string fontName, int fontSize) {
|
||||||
|
cleanupFont();
|
||||||
|
this->fontName = fontName;
|
||||||
|
this->fontFile = findFont(this->fontName.c_str());
|
||||||
|
this->fontFaceSize = fontSize;
|
||||||
|
|
||||||
|
const wchar_t *cache = L" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||||
|
|
||||||
|
this->manager = font_manager_new( 512, 512, 1 );
|
||||||
|
this->atlas = texture_atlas_new( 512, 512, 1 );
|
||||||
|
this->buffer = vertex_buffer_new( "v3f:t2f:c4f" );
|
||||||
|
|
||||||
|
//font = texture_font_new( atlas, "Verdana", minsize );
|
||||||
|
this->font = texture_font_new( atlas, fontFile, fontFaceSize );
|
||||||
|
//font = texture_font_new( atlas, font_manager_match_description( 0, "Verdana", minsize, bold, italic ), minsize );
|
||||||
|
|
||||||
|
int missed = texture_font_cache_glyphs( font, cache );
|
||||||
|
|
||||||
|
free((void*)this->fontFile);
|
||||||
|
this->fontFile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFreetypeGL::SetFaceSize(int value) {
|
||||||
|
this->fontFaceSize = value;
|
||||||
|
init(this->fontName,this->fontFaceSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextFreetypeGL::GetFaceSize() {
|
||||||
|
return this->fontFaceSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFreetypeGL::Render(const char* str, const int len) {
|
||||||
|
if(str == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pen pen ;
|
||||||
|
pen.x = 0; pen.y = 0;
|
||||||
|
|
||||||
|
vertex_buffer_clear( this->buffer );
|
||||||
|
|
||||||
|
float currentColor[4];
|
||||||
|
glGetFloatv(GL_CURRENT_COLOR,currentColor);
|
||||||
|
|
||||||
|
Markup markup = { 0, this->fontFaceSize, 0, 0, 0.0, 0.0,
|
||||||
|
{currentColor[0],currentColor[1],currentColor[2],currentColor[3]}, {0,0,0,0},
|
||||||
|
0, {0,0,0,1}, 0, {0,0,0,1},
|
||||||
|
0, {0,0,0,1}, 0, {0,0,0,1}, 0 };
|
||||||
|
|
||||||
|
// Add glyph one by one to the vertex buffer
|
||||||
|
// Expand totalBox by each glyph in string
|
||||||
|
|
||||||
|
// for multibyte - we can't rely on sizeof(T) == character
|
||||||
|
FreetypeGLUnicodeStringItr<unsigned char> ustr((const unsigned char *)str);
|
||||||
|
|
||||||
|
for(int i = 0; (len < 0 && *ustr) || (len >= 0 && i < len); i++) {
|
||||||
|
unsigned int prevChar = (i > 0 ? *ustr-1 : 0);
|
||||||
|
unsigned int thisChar = *ustr++;
|
||||||
|
unsigned int nextChar = *ustr;
|
||||||
|
|
||||||
|
// Get glyph (build it if needed
|
||||||
|
TextureGlyph *glyph = texture_font_get_glyph( this->font, thisChar );
|
||||||
|
|
||||||
|
// Take kerning into account if necessary
|
||||||
|
int kx = texture_glyph_get_kerning( glyph, prevChar );
|
||||||
|
|
||||||
|
// Add glyph to the vertex buffer
|
||||||
|
texture_glyph_add_to_vertex_buffer( glyph, this->buffer, &markup, &pen, kx );
|
||||||
|
}
|
||||||
|
|
||||||
|
//glBindTexture( GL_TEXTURE_2D, manager->atlas->texid );
|
||||||
|
glBindTexture( GL_TEXTURE_2D, this->atlas->texid );
|
||||||
|
|
||||||
|
glEnable( GL_BLEND );
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
glEnable( GL_TEXTURE_2D );
|
||||||
|
vertex_buffer_render( this->buffer, GL_TRIANGLES, "vtc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFreetypeGL::Render(const wchar_t* str, const int len) {
|
||||||
|
if(str == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wchar_t *text = str;
|
||||||
|
Pen pen ;
|
||||||
|
pen.x = 0; pen.y = 0;
|
||||||
|
|
||||||
|
vertex_buffer_clear( this->buffer );
|
||||||
|
|
||||||
|
float currentColor[4];
|
||||||
|
glGetFloatv(GL_CURRENT_COLOR,currentColor);
|
||||||
|
|
||||||
|
Markup markup = { 0, this->fontFaceSize, 0, 0, 0.0, 0.0,
|
||||||
|
{currentColor[0],currentColor[1],currentColor[2],currentColor[3]}, {0,0,0,0},
|
||||||
|
0, {0,0,0,1}, 0, {0,0,0,1},
|
||||||
|
0, {0,0,0,1}, 0, {0,0,0,1}, 0 };
|
||||||
|
|
||||||
|
// Add glyph one by one to the vertex buffer
|
||||||
|
for( size_t i = 0; i < wcslen(text); ++i ) {
|
||||||
|
// Get glyph (build it if needed
|
||||||
|
TextureGlyph *glyph = texture_font_get_glyph( this->font, text[i] );
|
||||||
|
|
||||||
|
// Take kerning into account if necessary
|
||||||
|
int kx = texture_glyph_get_kerning( glyph, text[i-1] );
|
||||||
|
|
||||||
|
// Add glyph to the vertex buffer
|
||||||
|
texture_glyph_add_to_vertex_buffer( glyph, this->buffer, &markup, &pen, kx );
|
||||||
|
}
|
||||||
|
|
||||||
|
//glBindTexture( GL_TEXTURE_2D, manager->atlas->texid );
|
||||||
|
glBindTexture( GL_TEXTURE_2D, this->atlas->texid );
|
||||||
|
|
||||||
|
glEnable( GL_BLEND );
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
glEnable( GL_TEXTURE_2D );
|
||||||
|
vertex_buffer_render( this->buffer, GL_TRIANGLES, "vtc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
float TextFreetypeGL::Advance(const wchar_t* str, const int len) {
|
||||||
|
float result = 0;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < wcslen(str); ++i) {
|
||||||
|
TextureGlyph *glyph = texture_font_get_glyph( font, str[i] );
|
||||||
|
result += glyph->width;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TextFreetypeGL::Advance(const char* str, const int len) {
|
||||||
|
float result = 0;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < strlen(str); ++i) {
|
||||||
|
TextureGlyph *glyph = texture_font_get_glyph( font, str[i] );
|
||||||
|
result += glyph->width;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TextFreetypeGL::LineHeight(const char* str, const int len) {
|
||||||
|
float result = 0;
|
||||||
|
if(strlen(str) > 0) {
|
||||||
|
TextureGlyph *glyph = texture_font_get_glyph( font, str[0] );
|
||||||
|
result = glyph->height;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TextFreetypeGL::LineHeight(const wchar_t* str, const int len) {
|
||||||
|
float result = 0;
|
||||||
|
if(wcslen(str) > 0) {
|
||||||
|
TextureGlyph *glyph = texture_font_get_glyph( font, str[0] );
|
||||||
|
result = glyph->height;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* TextFreetypeGL::findFont(const char *firstFontToTry) {
|
||||||
|
const char* font = NULL;
|
||||||
|
const char* path = NULL;
|
||||||
|
|
||||||
|
#define CHECK_FONT_PATH(filename) \
|
||||||
|
{ \
|
||||||
|
path = filename; \
|
||||||
|
if( !font && path && fileExists(path) == true ) \
|
||||||
|
font = strdup(path); \
|
||||||
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Found font file [%s]\n",font); \
|
||||||
|
}
|
||||||
|
|
||||||
|
string tryFont = "";
|
||||||
|
if(firstFontToTry) {
|
||||||
|
tryFont = firstFontToTry;
|
||||||
|
#ifdef WIN32
|
||||||
|
replaceAll(tryFont, "/", "\\");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CHECK_FONT_PATH(tryFont.c_str())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user-specified font path
|
||||||
|
if(getenv("MEGAGLEST_FONT") != NULL) {
|
||||||
|
tryFont = getenv("MEGAGLEST_FONT");
|
||||||
|
#ifdef WIN32
|
||||||
|
replaceAll(tryFont, "/", "\\");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CHECK_FONT_PATH(tryFont.c_str())
|
||||||
|
}
|
||||||
|
|
||||||
|
string data_path = Text::DEFAULT_FONT_PATH;
|
||||||
|
string defaultFont = data_path + "data/core/fonts/LinBiolinum_RB.ttf";//LinBiolinum_Re-0.6.4.ttf
|
||||||
|
tryFont = defaultFont;
|
||||||
|
#ifdef WIN32
|
||||||
|
replaceAll(tryFont, "/", "\\");
|
||||||
|
#endif
|
||||||
|
CHECK_FONT_PATH(tryFont.c_str())
|
||||||
|
|
||||||
|
#ifdef FONT_PATH
|
||||||
|
// Get distro-specified font path
|
||||||
|
CHECK_FONT_PATH(FONT_PATH)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_FONTCONFIG
|
||||||
|
// Get default font via fontconfig
|
||||||
|
if( !font && FcInit() ) {
|
||||||
|
FcResult result;
|
||||||
|
FcFontSet *fs;
|
||||||
|
FcPattern* pat;
|
||||||
|
FcPattern *match;
|
||||||
|
|
||||||
|
/*
|
||||||
|
TRANSLATORS: If using the FTGL backend, this should be the font
|
||||||
|
name of a font that contains all the Unicode characters in use in
|
||||||
|
your translation.
|
||||||
|
*/
|
||||||
|
pat = FcNameParse((FcChar8 *)"Gothic Uralic");
|
||||||
|
FcConfigSubstitute(0, pat, FcMatchPattern);
|
||||||
|
|
||||||
|
FcPatternDel(pat, FC_WEIGHT);
|
||||||
|
FcPatternAddInteger(pat, FC_WEIGHT, FC_WEIGHT_BOLD);
|
||||||
|
|
||||||
|
FcDefaultSubstitute(pat);
|
||||||
|
fs = FcFontSetCreate();
|
||||||
|
match = FcFontMatch(0, pat, &result);
|
||||||
|
|
||||||
|
if (match) FcFontSetAdd(fs, match);
|
||||||
|
if (pat) FcPatternDestroy(pat);
|
||||||
|
if(fs) {
|
||||||
|
FcChar8* file;
|
||||||
|
if( FcPatternGetString (fs->fonts[0], FC_FILE, 0, &file) == FcResultMatch ) {
|
||||||
|
CHECK_FONT_PATH((const char*)file)
|
||||||
|
}
|
||||||
|
FcFontSetDestroy(fs);
|
||||||
|
}
|
||||||
|
FcFini();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf")
|
||||||
|
|
||||||
|
// Check a couple of common paths for Gothic Uralic/bold as a last resort
|
||||||
|
// Debian
|
||||||
|
/*
|
||||||
|
TRANSLATORS: If using the FTGL backend, this should be the path of a bold
|
||||||
|
font that contains all the Unicode characters in use in your translation.
|
||||||
|
If the font is available in Debian it should be the Debian path.
|
||||||
|
*/
|
||||||
|
CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf")
|
||||||
|
/*
|
||||||
|
TRANSLATORS: If using the FTGL backend, this should be the path of a
|
||||||
|
font that contains all the Unicode characters in use in your translation.
|
||||||
|
If the font is available in Debian it should be the Debian path.
|
||||||
|
*/
|
||||||
|
CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothu___.ttf")
|
||||||
|
// Mandrake
|
||||||
|
/*
|
||||||
|
TRANSLATORS: If using the FTGL backend, this should be the path of a bold
|
||||||
|
font that contains all the Unicode characters in use in your translation.
|
||||||
|
If the font is available in Mandrake it should be the Mandrake path.
|
||||||
|
*/
|
||||||
|
CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHUB__.TTF")
|
||||||
|
/*
|
||||||
|
TRANSLATORS: If using the FTGL backend, this should be the path of a
|
||||||
|
font that contains all the Unicode characters in use in your translation.
|
||||||
|
If the font is available in Mandrake it should be the Mandrake path.
|
||||||
|
*/
|
||||||
|
CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHU___.TTF")
|
||||||
|
|
||||||
|
// Check the non-translated versions of the above
|
||||||
|
CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf")
|
||||||
|
CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothu___.ttf")
|
||||||
|
CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHUB__.TTF")
|
||||||
|
CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHU___.TTF")
|
||||||
|
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
}}}//end namespace
|
||||||
|
|
||||||
|
#endif // USE_FTGL
|
Reference in New Issue
Block a user