--- /dev/null
+#include <cairo.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define SURFACE_WIDTH (256)
+#define SURFACE_HEIGHT (SURFACE_WIDTH)
+
+#define CHAR_START ' '
+#define CHAR_END ('~' + 2)
+
+void GenerateFontFiles (char const * szFilePrefix, char const * szFontname, int nPoints, bool boItalic, bool boBold, bool boAntialiase);
+
+int main (int argc, char *argv[])
+{
+ GenerateFontFiles ("font01", "sans", 12, false, false, true);
+ GenerateFontFiles ("font02", "sans", 20, false, false, true);
+
+ return 0;
+}
+
+// "serif", "sans-serif", "cursive", "fantasy", "monospace"
+void GenerateFontFiles (char const * szFilePrefix, char const * szFontname, int nPoints, bool boItalic, bool boBold, bool boAntialiase) {
+ unsigned char cCharacter;
+ float fXPos;
+ float fYPos;
+ float fMaxHeight;
+ char szPrint[2];
+ int nPos;
+ float fArea;
+ float fDimension;
+ int nDimension;
+ float fPower;
+ int nPower;
+ FILE * fhPositions;
+ FILE * fhData;
+ cairo_font_options_t * psFontOptions;
+ char szAll[(CHAR_END - CHAR_START + 1)];
+ float fDescent;
+ cairo_format_t eFormat = CAIRO_FORMAT_ARGB32;
+ unsigned char * pucData;
+ unsigned char ucAlpha;
+ unsigned char ucColour;
+ float fScaled;
+ cairo_font_slant_t eSlant;
+ cairo_font_weight_t eWeight;
+ char * szFilename;
+ int nPrefixLen;
+
+ nPrefixLen = strlen (szFilePrefix);
+ szFilename = (char *)malloc (nPrefixLen + 5);
+ strncpy (szFilename, szFilePrefix, nPrefixLen);
+
+ eSlant = (boItalic ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL);
+ eWeight = (boBold ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL);
+
+ // Establish the texture size needed
+ cairo_surface_t * psSurface = cairo_image_surface_create (eFormat, SURFACE_WIDTH, SURFACE_HEIGHT);
+ cairo_t * psContext = cairo_create (psSurface);
+ cairo_text_extents_t sExtents;
+ cairo_font_extents_t sFontExtents;
+
+ // "serif", "sans-serif", "cursive", "fantasy", "monospace"
+ cairo_select_font_face (psContext, szFontname, eSlant, eWeight);
+ cairo_set_font_size (psContext, nPoints);
+ cairo_set_source_rgb (psContext, 1.0, 1.0, 0.0);
+
+ if (!boAntialiase) {
+ psFontOptions = cairo_font_options_create ();
+ // CAIRO_ANTIALIAS_BEST
+ // CAIRO_ANTIALIAS_NONE
+ cairo_font_options_set_antialias (psFontOptions, CAIRO_ANTIALIAS_NONE);
+ //cairo_set_font_options (psContext, psFontOptions);
+ cairo_font_options_destroy (psFontOptions);
+ }
+
+ for (cCharacter = 0; cCharacter < (CHAR_END - CHAR_START); cCharacter++) {
+ szAll[cCharacter] = cCharacter + CHAR_START;
+ }
+ szAll[cCharacter] = 0;
+ cairo_text_extents (psContext, szAll, & sExtents);
+ fArea = sExtents.height * sExtents.width;
+
+ cairo_font_extents (psContext, & sFontExtents);
+ fMaxHeight = sFontExtents.height;
+ fDescent = sFontExtents.descent;
+
+ printf ("Max width: %f\n", sFontExtents.max_x_advance);
+ printf ("Max height: %f\n", fMaxHeight);
+
+ fDimension = sqrt (fArea);
+ nDimension = (fDimension + 1.0f);
+ fPower = ceil (log (fDimension) / log (2.0));
+ nPower = (fPower + 0.5f);
+ //printf ("Power: %d\n", nPower);
+ nDimension = pow (2, nPower);
+ printf ("Dimension: %d x %d\n", nDimension, nDimension);
+
+ cairo_destroy (psContext);
+ cairo_surface_destroy (psSurface);
+
+
+
+ // Recrease the surface but this time with a suitable size
+ psSurface = cairo_image_surface_create (eFormat, nDimension, nDimension);
+ psContext = cairo_create (psSurface);
+
+ cairo_select_font_face (psContext, szFontname, eSlant, eWeight);
+ cairo_set_font_size (psContext, nPoints);
+ cairo_set_source_rgb (psContext, 1.0, 1.0, 1.0);
+
+ if (!boAntialiase) {
+ psFontOptions = cairo_font_options_create ();
+ cairo_font_options_set_antialias (psFontOptions, CAIRO_ANTIALIAS_NONE);
+ //cairo_set_font_options (psContext, psFontOptions);
+ cairo_font_options_destroy (psFontOptions);
+ }
+
+ // Open the CSV file for the character details
+ strncpy (szFilename + nPrefixLen, ".csv", 5);
+ fhPositions = fopen (szFilename, "w");
+
+ // Render the characters to the texture
+ szPrint[1] = 0;
+ fXPos = 0.0f;
+ fYPos = fMaxHeight;
+ for (cCharacter = CHAR_START; cCharacter < CHAR_END; cCharacter++) {
+ szPrint[0] = cCharacter;
+ cairo_text_extents (psContext, szPrint, & sExtents);
+ if ((fXPos + sExtents.x_advance) > nDimension) {
+ fXPos = 0.0f;
+ fYPos += fMaxHeight;
+ }
+
+ cairo_move_to (psContext, fXPos, fYPos - fDescent);
+ cairo_show_text (psContext, szPrint);
+
+ fprintf (fhPositions, "%d, %d, %d, %d\n", (int)fXPos, (int)(fYPos - fMaxHeight), (int)sExtents.x_advance, (int)fMaxHeight);
+
+ fXPos += sExtents.x_advance;
+ fYPos += sExtents.y_advance;
+ }
+
+
+ close (fhPositions);
+
+ //cairo_text_extents (psContext, "Hello, world ", & sExtents);
+ //printf ("X bearing: %f\n", sExtents.x_bearing);
+ //printf ("Y bearing: %f\n", sExtents.y_bearing);
+ //printf ("Width: %f\n", sExtents.width);
+ //printf ("Height: %f\n", sExtents.height);
+ //printf ("X advance: %f\n", sExtents.x_advance);
+ //printf ("Y advance: %f\n", sExtents.y_advance);
+
+ cairo_surface_flush (psSurface);
+
+ // Output the texture as raw
+ pucData = cairo_image_surface_get_data (psSurface);
+ strncpy (szFilename + nPrefixLen, ".raw", 5);
+ fhData = fopen (szFilename, "wb");
+ for (nPos = 0; nPos < (nDimension * nDimension); nPos++) {
+ ucAlpha = pucData[(nPos * 4) + 3];
+
+ if (ucAlpha == 0u) {
+ fputc (0u, fhData);
+ fputc (0u, fhData);
+ fputc (0u, fhData);
+ fputc (0u, fhData);
+ }
+ else {
+ // Convert 'pre-multiplied alpha' to 'post-multiplied alpha'
+
+ // Red
+ ucColour = pucData[(nPos * 4) + 2];
+ fScaled = round (((float)ucColour) / (((float)ucAlpha) / 255.0f));
+ //printf ("R: %f, %u, %u\n", fScaled, ucColour, ucAlpha);
+ fputc (((unsigned char)fScaled), fhData);
+
+ // Green
+ ucColour = pucData[(nPos * 4) + 1];
+ fScaled = round (((float)ucColour) / (((float)ucAlpha) / 255.0f));
+ //printf ("G: %f, %u, %u\n", fScaled, ucColour, ucAlpha);
+ fputc (((unsigned char)fScaled), fhData);
+
+ // Blue
+ ucColour = pucData[(nPos * 4) + 0];
+ fScaled = round (((float)ucColour) / (((float)ucAlpha) / 255.0f));
+ //printf ("B: %f, %u, %u\n", fScaled, ucColour, ucAlpha);
+ fputc (((unsigned char)fScaled), fhData);
+
+ fputc (ucAlpha, fhData);
+ }
+ }
+ close (fhData);
+
+ // Output the texture as a PNG
+ cairo_destroy (psContext);
+ strncpy (szFilename + nPrefixLen, ".png", 5);
+ cairo_surface_write_to_png (psSurface, szFilename);
+ cairo_surface_destroy (psSurface);
+}
+
+