|
|
|
@ -446,15 +446,18 @@ render_glyph(struct glyph g, struct line_contour *lines,
@@ -446,15 +446,18 @@ 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) { |
|
|
|
|
f32 *accumulator = calloc(1, gwidth * gheight * sizeof(f32)); |
|
|
|
|
|
|
|
|
|
int oversample_y = 5; |
|
|
|
|
f32 oversample_step = 1.0f / (oversample_y + 1); |
|
|
|
|
f32 oversample_norm = 1.0f / oversample_y; |
|
|
|
|
|
|
|
|
|
for (int y = 0; y < gheight; ++y) { |
|
|
|
|
for (int yy = 1; yy <= oversample_y; ++yy) { |
|
|
|
|
|
|
|
|
|
u32 ncross = intersect_glyph(lines, y + norm * yy, intersections); |
|
|
|
|
u32 ncross = intersect_glyph(lines, y + oversample_step * yy, intersections); |
|
|
|
|
if (ncross) { |
|
|
|
|
sort_intersections(intersections, ncross); |
|
|
|
|
|
|
|
|
@ -473,52 +476,37 @@ render_glyph(struct glyph g, struct line_contour *lines,
@@ -473,52 +476,37 @@ render_glyph(struct glyph g, struct line_contour *lines,
|
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
f32 start_brightness = (x_from + 1 - x0); |
|
|
|
|
f32 end_brightness = (x1 - x_to); |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
for (int x = x_from + 1; x < x_to; ++x) { |
|
|
|
|
accumulator[y * gwidth + x] += oversample_norm; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
accumulator[y * gwidth + x_from] += start_brightness * oversample_norm; |
|
|
|
|
accumulator[y * gwidth + x_to] += end_brightness * oversample_norm; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#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; |
|
|
|
|
} |
|
|
|
|
#if 1 |
|
|
|
|
for (int y = 0; y < gheight; ++y) { |
|
|
|
|
for (int x = 0; x < gwidth; ++x) { |
|
|
|
|
//printf(" %.2f", accumulator[y * gwidth + x]);
|
|
|
|
|
u32 brightness = clamp_u32(accumulator[y * gwidth + x] * 255.99f, 255); |
|
|
|
|
u32 white = 0xFF000000 | brightness << 16 | brightness << 8 | brightness; |
|
|
|
|
pixels[(at_y + y) * width + (at_x + x)] = white; |
|
|
|
|
} |
|
|
|
|
//printf("\n");
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(accumulator); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
//exit(1);
|
|
|
|
|
|
|
|
|
|
free(intersections); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -635,7 +623,7 @@ render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, u32
@@ -635,7 +623,7 @@ render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, u32
|
|
|
|
|
outline_to_lines(g, scale, &lines, 0); |
|
|
|
|
|
|
|
|
|
int baseline_correction = round_f32(scale * g.ymax); |
|
|
|
|
render_glyph(g, &lines, scale, pixels, width, height, offset_x + g.lsb * scale, offset_y - baseline_correction); |
|
|
|
|
render_glyph(g, &lines, scale, pixels, width, height, offset_x + round_f32(g.lsb * scale), offset_y - baseline_correction); |
|
|
|
|
offset_x += scale * g.advance; |
|
|
|
|
|
|
|
|
|
free(lines.data); |
|
|
|
@ -709,18 +697,21 @@ main(int argc, char **argv)
@@ -709,18 +697,21 @@ main(int argc, char **argv)
|
|
|
|
|
u32 *pixels = hc_vram; |
|
|
|
|
int t = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
|
//memset(pixels, 0xFF, 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, 20, pixels, width, height, L"QQQQqqqqq", 100, 200); |
|
|
|
|
|
|
|
|
|
#if 1 |
|
|
|
|
render_utf_string(font, 24, pixels, width, height, L"Пельмени - это очень просто! Много фарша, мало мяса...", 100, 100); |
|
|
|
|
render_utf_string(font, 24, pixels, width, height, L"Good pelmeni are very simple! Much meat, little dough...", 100, 150); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
XPutImage(display, window, default_gc, xwindow_buffer, 0, 0, 0, 0, width, height); |
|
|
|
|
|
|
|
|
|
//sleep(1);
|
|
|
|
|
usleep(100000); |
|
|
|
|
|
|
|
|
|
++t; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return(0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|