可以参考官网的另外一个c++实现的版本 : https://www.freetype.org/freetype2/docs/tutorial/example2.cpp
我把它转化为C代码如下:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include<malloc.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_STROKER_H
#include FT_IMAGE_H
#define WIDTH 80
#define HEIGHT 60
#define uint8 unsigned char
#define uint16 unsigned short
/* origin is the upper left corner */
unsigned char image[HEIGHT][WIDTH];
struct Pixel32
{
uint8 a;
uint8 r;
uint8 g;
uint8 b;
};
struct Span {
int x;
int y;
int width;
int coverage;
};
typedef struct Lspan {
struct Span node;
struct Lspan *next;
}Node, *PNode;
struct Rect {
float xmin;
float xmax;
float ymin;
float ymax;
};
struct vec2 {
float x;
float y;
};
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
void Include(const struct vec2 *r, struct Rect *rect)
{
rect->xmin = MIN(rect->xmin, r->x);
rect->ymin = MIN(rect->ymin, r->y);
rect->xmax = MAX(rect->xmax, r->x);
rect->ymax = MAX(rect->ymax, r->y);
}
void RasterCallback(const int y,
const int count,
const FT_Span * const spans,
void * const user)
{
PNode sptr = (PNode)user;
while (sptr->next != NULL)
sptr = sptr->next;
int i;
for (i = 0; i < count; ++i) {
PNode new = calloc(sizeof(Node), 1);
if (!new) {
printf("failed to alloc new node\n");
break;
}
new->next = NULL;
new->node.x = spans[i].x;
new->node.y = y;
new->node.width = spans[i].len;
new->node.coverage = spans[i].coverage;
sptr->next = new;
sptr = sptr->next;
}
}
void RenderSpans(FT_Library *library,
FT_Outline *const outl