|
|
|
@ -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); |
|
|
|
|
|
|
|
|
|