warzone2100/3rdparty/quesoglc/oglyph.c

234 lines
5.5 KiB
C

/* QuesoGLC
* A free implementation of the OpenGL Character Renderer (GLC)
* Copyright (c) 2002, 2004-2008, Bertrand Coconnier
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
/* Defines the methods of an object that is intended to managed glyphs */
/** \file
* defines the object __GLCglyph which caches all the data needed for a given
* glyph : display list, texture, bounding box, advance, index in the font
* file, etc.
*/
#include "internal.h"
#include "texture.h"
/* Constructor of the object : it allocates memory and initializes the member
* of the new object.
* The user must give the index of the glyph in the font file and its Unicode
* codepoint.
*/
__GLCglyph* __glcGlyphCreate(const GLCulong inIndex, const GLCulong inCode)
{
__GLCglyph* This = NULL;
This = (__GLCglyph*)__glcMalloc(sizeof(__GLCglyph));
if (!This) {
__glcRaiseError(GLC_RESOURCE_ERROR);
return NULL;
}
memset(This, 0, sizeof(__GLCglyph));
This->node.data = This;
This->index = inIndex;
This->codepoint = inCode;
This->isSpacingChar = GL_FALSE;
This->advanceCached = GL_FALSE;
This->boundingBoxCached = GL_FALSE;
return This;
}
/* Destructor of the object */
void __glcGlyphDestroy(__GLCglyph* This, __GLCcontext* inContext)
{
__glcGlyphDestroyGLObjects(This, inContext);
__glcFree(This);
}
/* Remove all GL objects related to the texture of the glyph */
void __glcGlyphDestroyTexture(__GLCglyph* This, const __GLCcontext* inContext)
{
if (!inContext->isInGlobalCommand && !GLEW_ARB_vertex_buffer_object)
glDeleteLists(This->glObject[1], 1);
This->glObject[1] = 0;
This->textureObject = NULL;
}
/* This function destroys the display lists and the texture objects that
* are associated with a glyph.
*/
void __glcGlyphDestroyGLObjects(__GLCglyph* This, __GLCcontext* inContext)
{
if (This->glObject[1]) {
__glcReleaseAtlasElement(This->textureObject, inContext);
__glcGlyphDestroyTexture(This, inContext);
}
if (!inContext->isInGlobalCommand) {
if (This->glObject[0]) {
if (GLEW_ARB_vertex_buffer_object) {
glDeleteBuffersARB(1, &This->glObject[0]);
if (This->contours)
__glcFree(This->contours);
This->nContour = 0;
This->contours = NULL;
}
else
glDeleteLists(This->glObject[0], 1);
}
if (This->glObject[2]) {
if (GLEW_ARB_vertex_buffer_object) {
glDeleteBuffersARB(1, &This->glObject[2]);
if (This->geomBatches)
__glcFree(This->geomBatches);
This->nGeomBatch = 0;
This->geomBatches = NULL;
}
else
glDeleteLists(This->glObject[2], 1);
}
if (This->glObject[3]) {
if (GLEW_ARB_vertex_buffer_object)
glDeleteBuffersARB(1, &This->glObject[3]);
else
glDeleteLists(This->glObject[3], 1);
}
memset(This->glObject, 0, 4 * sizeof(GLuint));
}
}
/* Returns the number of display that has been built for a glyph */
int __glcGlyphGetDisplayListCount(const __GLCglyph* This)
{
int i = 0;
int count = 0;
if (GLEW_ARB_vertex_buffer_object)
return 0;
for (i = 0; i < 4; i++) {
if (This->glObject[i])
count++;
}
return count;
}
/* Returns the ID of the inCount-th display list that has been built for a
* glyph.
*/
GLuint __glcGlyphGetDisplayList(const __GLCglyph* This, const int inCount)
{
int i = 0;
int count = inCount;
assert(inCount >= 0);
assert(inCount < __glcGlyphGetDisplayListCount(This));
if (GLEW_ARB_vertex_buffer_object)
return 0;
for (i = 0; i < 4; i++) {
GLuint displayList = This->glObject[i];
if (displayList) {
if (!count)
return displayList;
count--;
}
}
/* The program is not supposed to reach the end of the function.
* The following return is there to prevent the compiler to issue
* a warning about 'control reaching the end of a non-void function'.
*/
return 0xdeadbeef;
}
/* Returns the number of buffer objects that has been built for a glyph */
int __glcGlyphGetBufferObjectCount(const __GLCglyph* This)
{
int i = 0;
int count = 0;
assert(GLEW_ARB_vertex_buffer_object);
for (i = 0; i < 4; i++) {
if (i == 1)
continue;
if (This->glObject[i])
count++;
}
return count;
}
/* Returns the ID of the inCount-th buffer object that has been built for a
* glyph.
*/
GLuint __glcGlyphGetBufferObject(const __GLCglyph* This, const int inCount)
{
int i = 0;
int count = inCount;
assert(GLEW_ARB_vertex_buffer_object);
assert(inCount >= 0);
assert(inCount < __glcGlyphGetBufferObjectCount(This));
for (i = 0; i < 4; i++) {
GLuint bufferObject = This->glObject[i];
if (i == 1)
continue;
if (bufferObject) {
if (!count)
return bufferObject;
count--;
}
}
/* The program is not supposed to reach the end of the function.
* The following return is there to prevent the compiler to issue
* a warning about 'control reaching the end of a non-void function'.
*/
return 0xdeadbeef;
}