8 #define SURFACE_WIDTH (256)
9 #define SURFACE_HEIGHT (SURFACE_WIDTH)
11 #define CHAR_START ' '
12 #define CHAR_END ('~' + 2)
14 void GenerateFontFiles (char const * szFilePrefix
, char const * szFontname
, int nPoints
, bool boItalic
, bool boBold
, bool boAntialiase
);
16 int main (int argc
, char *argv
[])
18 GenerateFontFiles ("font01", "sans", 12, false, false, true);
19 GenerateFontFiles ("font02", "sans", 20, false, false, true);
24 // "serif", "sans-serif", "cursive", "fantasy", "monospace"
25 void GenerateFontFiles (char const * szFilePrefix
, char const * szFontname
, int nPoints
, bool boItalic
, bool boBold
, bool boAntialiase
) {
26 unsigned char cCharacter
;
39 cairo_font_options_t
* psFontOptions
;
40 char szAll
[(CHAR_END
- CHAR_START
+ 1)];
42 cairo_format_t eFormat
= CAIRO_FORMAT_ARGB32
;
43 unsigned char * pucData
;
44 unsigned char ucAlpha
;
45 unsigned char ucColour
;
47 cairo_font_slant_t eSlant
;
48 cairo_font_weight_t eWeight
;
52 nPrefixLen
= strlen (szFilePrefix
);
53 szFilename
= (char *)malloc (nPrefixLen
+ 5);
54 strncpy (szFilename
, szFilePrefix
, nPrefixLen
);
56 eSlant
= (boItalic
? CAIRO_FONT_SLANT_ITALIC
: CAIRO_FONT_SLANT_NORMAL
);
57 eWeight
= (boBold
? CAIRO_FONT_WEIGHT_BOLD
: CAIRO_FONT_WEIGHT_NORMAL
);
59 // Establish the texture size needed
60 cairo_surface_t
* psSurface
= cairo_image_surface_create (eFormat
, SURFACE_WIDTH
, SURFACE_HEIGHT
);
61 cairo_t
* psContext
= cairo_create (psSurface
);
62 cairo_text_extents_t sExtents
;
63 cairo_font_extents_t sFontExtents
;
65 // "serif", "sans-serif", "cursive", "fantasy", "monospace"
66 cairo_select_font_face (psContext
, szFontname
, eSlant
, eWeight
);
67 cairo_set_font_size (psContext
, nPoints
);
68 cairo_set_source_rgb (psContext
, 1.0, 1.0, 0.0);
71 psFontOptions
= cairo_font_options_create ();
72 // CAIRO_ANTIALIAS_BEST
73 // CAIRO_ANTIALIAS_NONE
74 cairo_font_options_set_antialias (psFontOptions
, CAIRO_ANTIALIAS_NONE
);
75 //cairo_set_font_options (psContext, psFontOptions);
76 cairo_font_options_destroy (psFontOptions
);
79 for (cCharacter
= 0; cCharacter
< (CHAR_END
- CHAR_START
); cCharacter
++) {
80 szAll
[cCharacter
] = cCharacter
+ CHAR_START
;
82 szAll
[cCharacter
] = 0;
83 cairo_text_extents (psContext
, szAll
, & sExtents
);
84 fArea
= sExtents
.height
* sExtents
.width
;
86 cairo_font_extents (psContext
, & sFontExtents
);
87 fMaxHeight
= sFontExtents
.height
;
88 fDescent
= sFontExtents
.descent
;
90 printf ("Max width: %f\n", sFontExtents
.max_x_advance
);
91 printf ("Max height: %f\n", fMaxHeight
);
93 fDimension
= sqrt (fArea
);
94 nDimension
= (fDimension
+ 1.0f
);
95 fPower
= ceil (log (fDimension
) / log (2.0));
96 nPower
= (fPower
+ 0.5f
);
97 //printf ("Power: %d\n", nPower);
98 nDimension
= pow (2, nPower
);
99 printf ("Dimension: %d x %d\n", nDimension
, nDimension
);
101 cairo_destroy (psContext
);
102 cairo_surface_destroy (psSurface
);
106 // Recrease the surface but this time with a suitable size
107 psSurface
= cairo_image_surface_create (eFormat
, nDimension
, nDimension
);
108 psContext
= cairo_create (psSurface
);
110 cairo_select_font_face (psContext
, szFontname
, eSlant
, eWeight
);
111 cairo_set_font_size (psContext
, nPoints
);
112 cairo_set_source_rgb (psContext
, 1.0, 1.0, 1.0);
115 psFontOptions
= cairo_font_options_create ();
116 cairo_font_options_set_antialias (psFontOptions
, CAIRO_ANTIALIAS_NONE
);
117 //cairo_set_font_options (psContext, psFontOptions);
118 cairo_font_options_destroy (psFontOptions
);
121 // Open the CSV file for the character details
122 strncpy (szFilename
+ nPrefixLen
, ".csv", 5);
123 fhPositions
= fopen (szFilename
, "w");
125 // Render the characters to the texture
129 for (cCharacter
= CHAR_START
; cCharacter
< CHAR_END
; cCharacter
++) {
130 szPrint
[0] = cCharacter
;
131 cairo_text_extents (psContext
, szPrint
, & sExtents
);
132 if ((fXPos
+ sExtents
.x_advance
) > nDimension
) {
137 cairo_move_to (psContext
, fXPos
, fYPos
- fDescent
);
138 cairo_show_text (psContext
, szPrint
);
140 fprintf (fhPositions
, "%d, %d, %d, %d\n", (int)fXPos
, (int)(fYPos
- fMaxHeight
), (int)sExtents
.x_advance
, (int)fMaxHeight
);
142 fXPos
+= sExtents
.x_advance
;
143 fYPos
+= sExtents
.y_advance
;
149 //cairo_text_extents (psContext, "Hello, world ", & sExtents);
150 //printf ("X bearing: %f\n", sExtents.x_bearing);
151 //printf ("Y bearing: %f\n", sExtents.y_bearing);
152 //printf ("Width: %f\n", sExtents.width);
153 //printf ("Height: %f\n", sExtents.height);
154 //printf ("X advance: %f\n", sExtents.x_advance);
155 //printf ("Y advance: %f\n", sExtents.y_advance);
157 cairo_surface_flush (psSurface
);
159 // Output the texture as raw
160 pucData
= cairo_image_surface_get_data (psSurface
);
161 strncpy (szFilename
+ nPrefixLen
, ".raw", 5);
162 fhData
= fopen (szFilename
, "wb");
163 for (nPos
= 0; nPos
< (nDimension
* nDimension
); nPos
++) {
164 ucAlpha
= pucData
[(nPos
* 4) + 3];
173 // Convert 'pre-multiplied alpha' to 'post-multiplied alpha'
176 ucColour
= pucData
[(nPos
* 4) + 2];
177 fScaled
= round (((float)ucColour
) / (((float)ucAlpha
) / 255.0f
));
178 //printf ("R: %f, %u, %u\n", fScaled, ucColour, ucAlpha);
179 fputc (((unsigned char)fScaled
), fhData
);
182 ucColour
= pucData
[(nPos
* 4) + 1];
183 fScaled
= round (((float)ucColour
) / (((float)ucAlpha
) / 255.0f
));
184 //printf ("G: %f, %u, %u\n", fScaled, ucColour, ucAlpha);
185 fputc (((unsigned char)fScaled
), fhData
);
188 ucColour
= pucData
[(nPos
* 4) + 0];
189 fScaled
= round (((float)ucColour
) / (((float)ucAlpha
) / 255.0f
));
190 //printf ("B: %f, %u, %u\n", fScaled, ucColour, ucAlpha);
191 fputc (((unsigned char)fScaled
), fhData
);
193 fputc (ucAlpha
, fhData
);
198 // Output the texture as a PNG
199 cairo_destroy (psContext
);
200 strncpy (szFilename
+ nPrefixLen
, ".png", 5);
201 cairo_surface_write_to_png (psSurface
, szFilename
);
202 cairo_surface_destroy (psSurface
);