#include "graphics/TextDisplay.h" #include #include #include "graphics/FontTexture.h" #include "graphics/GLIncludes.h" #include "graphics/Image.h" #include "graphics/Texture.h" #include "graphics/TextureManager.h" void TextDisplay_drawString(const char * string, FontTexture * fontTexture, float emHeight, float x, float y) { GLfloat * texCoords; GLfloat * vertices; size_t length; unsigned int charIndex; float offsetX; struct FontTexture_characterDimensions characterDimensions; float glyphX, glyphWidth; unsigned int entryIndex; float kerningOffset; if (fontTexture == NULL || fontTexture->texture == NULL || fontTexture->texture->image == NULL) { return; } length = strlen(string); texCoords = malloc(sizeof(GLfloat) * length * 12); vertices = malloc(sizeof(GLfloat) * length * 12); offsetX = 0; for (charIndex = 0; charIndex < length; charIndex++) { if (string[charIndex] >= ' ' && string[charIndex] <= '~') { characterDimensions = fontTexture->characters[string[charIndex] - ' ']; kerningOffset = 0.0f; if (charIndex > 0) { for (entryIndex = 0; entryIndex < characterDimensions.kerningTable.numberOfEntries; entryIndex++) { if (characterDimensions.kerningTable.entries[entryIndex].previous == string[charIndex - 1]) { kerningOffset = characterDimensions.kerningTable.entries[entryIndex].offset; break; } } } texCoords[charIndex * 12 + 0] = characterDimensions.textureLeft; texCoords[charIndex * 12 + 1] = characterDimensions.textureBottom; texCoords[charIndex * 12 + 2] = characterDimensions.textureRight; texCoords[charIndex * 12 + 3] = characterDimensions.textureBottom; texCoords[charIndex * 12 + 4] = characterDimensions.textureLeft; texCoords[charIndex * 12 + 5] = characterDimensions.textureTop; texCoords[charIndex * 12 + 6] = characterDimensions.textureLeft; texCoords[charIndex * 12 + 7] = characterDimensions.textureTop; texCoords[charIndex * 12 + 8] = characterDimensions.textureRight; texCoords[charIndex * 12 + 9] = characterDimensions.textureBottom; texCoords[charIndex * 12 + 10] = characterDimensions.textureRight; texCoords[charIndex * 12 + 11] = characterDimensions.textureTop; glyphX = (characterDimensions.offset + kerningOffset) * emHeight; glyphWidth = (characterDimensions.textureRight - characterDimensions.textureLeft) * fontTexture->texture->image->width / fontTexture->emHeight * emHeight; vertices[charIndex * 12 + 0] = x + offsetX + glyphX; vertices[charIndex * 12 + 1] = y; vertices[charIndex * 12 + 2] = x + offsetX + glyphX + glyphWidth; vertices[charIndex * 12 + 3] = y; vertices[charIndex * 12 + 4] = x + offsetX + glyphX; vertices[charIndex * 12 + 5] = y + emHeight; vertices[charIndex * 12 + 6] = x + offsetX + glyphX; vertices[charIndex * 12 + 7] = y + emHeight; vertices[charIndex * 12 + 8] = x + offsetX + glyphX + glyphWidth; vertices[charIndex * 12 + 9] = y; vertices[charIndex * 12 + 10] = x + offsetX + glyphX + glyphWidth; vertices[charIndex * 12 + 11] = y + emHeight; offsetX += (characterDimensions.advancement + kerningOffset) * emHeight; } } Texture_activate(fontTexture->texture); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glVertexPointer(2, GL_FLOAT, 0, vertices); glDrawArrays(GL_TRIANGLES, 0, length * 6); glDisableClientState(GL_TEXTURE_COORD_ARRAY); Texture_deactivate(fontTexture->texture); free(texCoords); free(vertices); } float TextDisplay_measureString(const char * string, struct FontTexture * fontTexture, float emHeight) { size_t length; unsigned int charIndex; float measuredLength = 0.0f; unsigned int entryIndex; float kerningOffset; if (fontTexture == NULL || fontTexture->texture == NULL || fontTexture->texture->image == NULL) { return 0.0f; } length = strlen(string); for (charIndex = 0; charIndex < length; charIndex++) { if (string[charIndex] >= ' ' && string[charIndex] <= '~') { kerningOffset = 0.0f; if (charIndex > 0) { for (entryIndex = 0; entryIndex < fontTexture->characters[string[charIndex] - ' '].kerningTable.numberOfEntries; entryIndex++) { if (fontTexture->characters[string[charIndex] - ' '].kerningTable.entries[entryIndex].previous == string[charIndex - 1]) { kerningOffset = fontTexture->characters[string[charIndex] - ' '].kerningTable.entries[entryIndex].offset; break; } } } measuredLength += (fontTexture->characters[string[charIndex] - ' '].advancement + kerningOffset) * emHeight; } } return measuredLength; }