Browse Source

Oversampling with 1 channel kinda works

master
A.Olokhtonov 4 years ago
parent
commit
bbf0ed67fb
  1. 89
      main.c

89
main.c

@ -206,6 +206,14 @@ static Window window; @@ -206,6 +206,14 @@ static Window window;
static GC default_gc;
static XImage* xwindow_buffer;
static int
clamp_u32(u32 val, u32 cap)
{
u32 result = val;
if (val > cap) result = cap;
return(result);
}
static f32
abs_f32(f32 v)
{
@ -438,38 +446,79 @@ render_glyph(struct glyph g, struct line_contour *lines, @@ -438,38 +446,79 @@ render_glyph(struct glyph g, struct line_contour *lines,
{
int gwidth = round_f32((g.xmax - g.xmin) * scale) + 1;
int gheight = round_f32((g.ymax - g.ymin) * scale) + 1;
int oversample_y = 4;
f32 norm = 1.0f / (oversample_y + 1);
struct intersection *intersections = malloc(lines->from[lines->ncontours] * sizeof(struct intersection));
for (int y = 0; y < gheight && (at_y + y < height); ++y) {
u32 ncross = intersect_glyph(lines, y, intersections);
if (ncross) {
sort_intersections(intersections, ncross);
int state = 0;
for (int yy = 1; yy <= oversample_y; ++yy) {
for (int i = 0; i < ncross - 1; ++i) {
struct intersection inter = intersections[i];
struct intersection next_inter = intersections[i + 1];
u32 ncross = intersect_glyph(lines, y + norm * yy, intersections);
if (ncross) {
sort_intersections(intersections, ncross);
state += inter.dir;
int state = 0;
if (state != 0) {
f32 x0 = inter.x;
f32 x1 = next_inter.x;
for (int i = 0; i < ncross - 1; ++i) {
struct intersection inter = intersections[i];
struct intersection next_inter = intersections[i + 1];
state += inter.dir;
for (int x = x0; x < x1; ++x) {
pixels[(y + at_y) * width + (at_x + x)] = 0x00;
if (state != 0) {
f32 x0 = inter.x;
f32 x1 = next_inter.x;
int x_from = x0;
int x_to = x1;
int start_enter = (state - inter.dir == 0);
int end_enter = (state + next_inter.dir != 0);
u32 start_brightness;
u32 end_brightness;
if (start_enter) {
start_brightness = (x_from + 1 - x0) * (255.99f / oversample_y);
} else {
start_brightness = (x0 - x_from) * (255.99f / oversample_y);
}
if (end_enter) {
end_brightness = (x_to + 1 - x1) * (255.99f / oversample_y);
} else {
end_brightness = (x1 - x_to) * (255.99f / oversample_y);
}
for (int x = x_from; x < x_to; ++x) {
pixels[(y + at_y) * width + (at_x + x)] += 255.99f / oversample_y;
pixels[(y + at_y) * width + (at_x + x)] = clamp_u32(pixels[(y + at_y) * width + (at_x + x)], 255);
}
u32 new_start_brightness = clamp_u32(pixels[(y + at_y) * width + (at_x + x_from)] + start_brightness, 255);
u32 new_end_brightness = clamp_u32(pixels[(y + at_y) * width + (at_x + x_to)] + end_brightness, 255);
pixels[(y + at_y) * width + (at_x + x_from)] = new_start_brightness;
pixels[(y + at_y) * width + (at_x + x_to)] = new_end_brightness;
}
}
}
}
#if DEBUG_SHOW_POINTS
_D_render_glyph_points(g, scale, pixels, width, height);
#endif
}
#if 0
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
if (pixels[y * width + x] <= 255) {
u32 brightness = 255 - pixels[y * width + x];
u32 white = 0xFF000000 | brightness << 16 | brightness << 8 | brightness;
pixels[y * width + x] = white;
}
}
}
#endif
free(intersections);
}
@ -662,9 +711,9 @@ main(int argc, char **argv) @@ -662,9 +711,9 @@ main(int argc, char **argv)
for (;;) {
memset(pixels, 0xFFFFFFFF, width * height * 4);
memset(pixels, 0x00, width * height * 4);
render_utf_string(font, 32, pixels, width, height, L"Привет, батя! Как поживаешь? Hello, Batya. Wazzaaap", 100, 100);
render_utf_string(font, 32, pixels, width, height, L"QQQQqqqqq", 100, 200);
render_utf_string(font, 20, pixels, width, height, L"QQQQqqqqq", 100, 200);
XPutImage(display, window, default_gc, xwindow_buffer, 0, 0, 0, 0, width, height);

Loading…
Cancel
Save