truetype: more floats -> better rendering

This commit is contained in:
Nic Limper
2023-07-31 20:22:50 +02:00
parent 21a52e9b17
commit 8daff632ba
2 changed files with 33 additions and 77 deletions

View File

@@ -139,8 +139,8 @@ typedef struct {
} ttKernFormat0_t;
typedef struct {
int16_t x;
int16_t y;
float x;
float y;
} ttCoordinate_t;
typedef struct {
@@ -258,7 +258,6 @@ class truetypeClass {
ttWindIntersect_t *pointsToFill = nullptr;
void generateOutline(int16_t _x, int16_t _y, uint16_t characterSize);
void freePointsAll();
bool isInside(int16_t _x, int16_t _y);
void fillGlyph(int16_t _x_min, int16_t _y_min, uint16_t characterSize);
uint8_t readGlyph(uint16_t code, uint8_t _justSize = 0);
void freeGlyph();
@@ -270,8 +269,7 @@ class truetypeClass {
void freeBeginPoints();
void addEndPoint(uint16_t _ep);
void freeEndPoints();
int32_t isLeft(ttCoordinate_t *_p0, ttCoordinate_t *_p1, ttCoordinate_t *_point);
float isLeftFloat(ttCoordinate_t *_p0, ttCoordinate_t *_p1, ttCoordinate_t *_point);
float isLeft(ttCoordinate_t *_p0, ttCoordinate_t *_p1, ttCoordinate_t *_point);
// write user framebuffer
uint16_t characterSize = 20;

View File

@@ -703,9 +703,6 @@ void truetypeClass::generateOutline(int16_t _x, int16_t _y, uint16_t characterSi
uint16_t j = 0;
float stepsize = .1;
if (characterSize > 50) stepsize = .05;
for (uint16_t i = 0; i < glyph.numberOfContours; i++) {
uint8_t firstPointOfContour = j;
uint8_t lastPointOfContour = glyph.endPtsOfContours[i];
@@ -766,7 +763,8 @@ void truetypeClass::generateOutline(int16_t _x, int16_t _y, uint16_t characterSi
x0 = pointsOfCurve[0].x;
y0 = pointsOfCurve[0].y;
for (float t = 0; t <= 1.0; t += stepsize) {
for (int step = 0; step <= 8; step += 1) {
float t = (float)step / 8.0;
x1 = (1.0 - t) * (1.0 - t) * x0 + 2.0 * t * (1.0 - t) * pointsOfCurve[1].x + t * t * pointsOfCurve[2].x;
y1 = (1.0 - t) * (1.0 - t) * y0 + 2.0 * t * (1.0 - t) * pointsOfCurve[1].y + t * t * pointsOfCurve[2].y;
@@ -789,75 +787,35 @@ void truetypeClass::generateOutline(int16_t _x, int16_t _y, uint16_t characterSi
void truetypeClass::addLine(float _x0, float _y0, float _x1, float _y1) {
int16_t x0 = round(_x0);
int16_t y0 = round(_y0);
int16_t x1 = round(_x1);
int16_t y1 = round(_y1);
if (numPoints == 0) {
addPoint(x0, y0);
addPoint(_x0, _y0);
addBeginPoint(0);
}
addPoint(x1,y1);
addPoint(_x1, _y1);
int16_t dx = abs(x1 - x0);
int16_t dy = abs(y1 - y0);
int16_t sx = (x0 < x1) ? 1 : -1;
int16_t sy = (y0 < y1) ? 1 : -1;
int16_t err = dx - dy;
/*
int16_t dx = abs(x1 - x0);
int16_t dy = abs(y1 - y0);
int16_t sx = (x0 < x1) ? 1 : -1;
int16_t sy = (y0 < y1) ? 1 : -1;
int16_t err = dx - dy;
while (true) {
addPixel(x0, y0, colorLine);
if (x0 == x1 && y0 == y1) {
break;
}
int16_t e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
x0 += sx;
}
if (e2 < dx) {
err += dx;
y0 += sy;
}
}
}
bool truetypeClass::isInside(int16_t _x, int16_t _y) {
int16_t windingNumber = 0;
uint16_t bpCounter = 0, epCounter = 0;
ttCoordinate_t point = {_x, _y};
ttCoordinate_t point1;
ttCoordinate_t point2;
for (uint16_t i = 0; i < numPoints; i++) {
point1 = points[i];
// Wrap?
if (i == endPoints[epCounter]) {
point2 = points[beginPoints[bpCounter]];
epCounter++;
bpCounter++;
} else {
point2 = points[i + 1];
}
if (point1.y <= point.y) {
if (point2.y > point.y) {
if (isLeft(&point1, &point2, &point) > 0) {
windingNumber++;
}
while (true) {
addPixel(x0, y0, colorLine);
if (x0 == x1 && y0 == y1) {
break;
}
} else {
// start y > point.y (no test needed)
if (point2.y <= point.y) {
if (isLeft(&point1, &point2, &point) < 0) {
windingNumber--;
}
int16_t e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
x0 += sx;
}
if (e2 < dx) {
err += dx;
y0 += sy;
}
}
}
return (windingNumber != 0);
*/
}
void truetypeClass::fillGlyph(int16_t _x_min, int16_t _y_min, uint16_t characterSize) {
@@ -866,7 +824,7 @@ void truetypeClass::fillGlyph(int16_t _x_min, int16_t _y_min, uint16_t character
y++) {
ttCoordinate_t point1, point2;
ttCoordinate_t point;
point.y = y;
point.y = (float)y;
uint16_t intersectPointsNum = 0;
uint16_t bpCounter = 0;
@@ -885,8 +843,8 @@ void truetypeClass::fillGlyph(int16_t _x_min, int16_t _y_min, uint16_t character
}
point2 = points[p2Num];
if (point1.y <= y) {
if (point2.y > y) {
if (point1.y <= (float)y) {
if (point2.y > (float)y) {
// Have a valid up intersect
intersectPointsNum++;
pointsToFill = (ttWindIntersect_t *)realloc(pointsToFill, sizeof(ttWindIntersect_t) * intersectPointsNum);
@@ -896,7 +854,7 @@ void truetypeClass::fillGlyph(int16_t _x_min, int16_t _y_min, uint16_t character
}
} else {
// start y > point.y (no test needed)
if (point2.y <= y) {
if (point2.y <= (float)y) {
// Have a valid down intersect
intersectPointsNum++;
pointsToFill = (ttWindIntersect_t *)realloc(pointsToFill, sizeof(ttWindIntersect_t) * intersectPointsNum);
@@ -911,14 +869,14 @@ void truetypeClass::fillGlyph(int16_t _x_min, int16_t _y_min, uint16_t character
x < _x_min + round((float)glyph.xMax * (float)characterSize / (float)headTable.unitsPerEm);
x++) {
int16_t windingNumber = 0;
point.x = x;
point.x = (float)x;
for (uint16_t i = 0; i < intersectPointsNum; i++) {
point1 = points[pointsToFill[i].p1];
point2 = points[pointsToFill[i].p2];
if (pointsToFill[i].up == 1) {
if (isLeft(&point1, &point2, &point) >= 0) {
if (isLeft(&point1, &point2, &point) > 0) {
windingNumber++;
}
} else {
@@ -938,7 +896,7 @@ void truetypeClass::fillGlyph(int16_t _x_min, int16_t _y_min, uint16_t character
}
}
int32_t truetypeClass::isLeft(ttCoordinate_t *_p0, ttCoordinate_t *_p1, ttCoordinate_t *_point) {
float truetypeClass::isLeft(ttCoordinate_t *_p0, ttCoordinate_t *_p1, ttCoordinate_t *_point) {
return ((_p1->x - _p0->x) * (_point->y - _p0->y) - (_point->x - _p0->x) * (_p1->y - _p0->y));
}