Browse Source

Fix so that it compiles and runs

master
A.Olokhtonov 2 years ago
parent
commit
4cd39aa6c5
  1. 59
      main.c
  2. 53
      ttf.h
  3. 22
      ttf_parse.c
  4. 49
      ttf_rasterize.c

59
main.c

@ -2,15 +2,11 @@ @@ -2,15 +2,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <wchar.h>
#include <assert.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@ -20,17 +16,6 @@ @@ -20,17 +16,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#define ASSERT(expr) if (!expr) { fprintf(stderr, "[ASSERT] Assertion fail %s:%d\n", __FILE__, __LINE__); abort(); }
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MAX_INTERSECTIONS 16
#define F32EPS 1e-5f
#define MAX_CONTOURS 256
#define TTF_ENGINE_STACK 4096
typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
@ -44,49 +29,11 @@ typedef uint8_t u8; @@ -44,49 +29,11 @@ typedef uint8_t u8;
typedef float f32;
typedef double f64;
static int
clamp_u32(u32 val, u32 cap)
{
u32 result = val;
if (val > cap) result = cap;
return(result);
}
static f32
abs_f32(f32 v)
{
f32 result = (v > 0 ? v : -v);
return(result);
}
static int
round_f32(f32 v)
{
int towards_zero = (int) v;
f32 diff = abs_f32(v - towards_zero);
if (diff >= 0.5f) {
return(v > 0 ? towards_zero + 1 : towards_zero - 1);
} else {
return(towards_zero);
}
}
static int
ceil_f32(f32 v)
{
int trunc = v;
if (v - trunc < F32EPS) {
return(trunc);
}
return(trunc + 1);
}
#include "ttf.h"
#include "ttf_engine.c"
#include "ttf-parse.c"
#include "ttf-rasterize.c"
#include "ttf_parse.c"
#include "ttf_rasterize.c"
static Display *display;
static Window window;
@ -148,7 +95,7 @@ main(int argc, char **argv) @@ -148,7 +95,7 @@ main(int argc, char **argv)
default_gc = DefaultGC(display, default_screen);
struct ttf_font font = parse_ttf_file(argv[1], "Inter");
struct ttf_font font = parse_ttf_file(argv[1]);
printf("Loaded font\n");
u32 *pixels = hc_vram;

53
ttf.h

@ -1,3 +1,18 @@ @@ -1,3 +1,18 @@
#include <math.h>
#include <wchar.h> // wchar_t, wcslen
#include <stdbool.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MAX_INTERSECTIONS 16
#define F32EPS 1e-5f
#define MAX_CONTOURS 256
#define TTF_ENGINE_STACK 4096
#define ASSERT(expr) if (!(expr)) { fprintf(stderr, "[ASSERT] Assertion fail %s:%d\n", __FILE__, __LINE__); abort(); }
struct v2 {
int x;
int y;
@ -152,3 +167,41 @@ struct ttf_font { @@ -152,3 +167,41 @@ struct ttf_font {
char *name;
};
static int
clamp_u32(u32 val, u32 cap)
{
u32 result = val;
if (val > cap) result = cap;
return(result);
}
static f32
abs_f32(f32 v)
{
f32 result = (v > 0 ? v : -v);
return(result);
}
static int
round_f32(f32 v)
{
int towards_zero = (int) v;
f32 diff = abs_f32(v - towards_zero);
if (diff >= 0.5f) {
return(v > 0 ? towards_zero + 1 : towards_zero - 1);
} else {
return(towards_zero);
}
}
static int
ceil_f32(f32 v)
{
int trunc = v;
if (v - trunc < F32EPS) {
return(trunc);
}
return(trunc + 1);
}

22
ttf-parse.c → ttf_parse.c

@ -485,7 +485,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o @@ -485,7 +485,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o
u32 value = pop(state);
u32 location = pop(state);
s16 cvt_value = value;
assert(location <= font->dir.cvt_size / sizeof(s16));
ASSERT(location <= font->dir.cvt_size / sizeof(s16));
font->cvt[location] = cvt_value;
break;
}
@ -494,14 +494,14 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o @@ -494,14 +494,14 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o
u32 value = pop(state);
u32 location = pop(state);
s16 cvt_value = funits_to_pixels(value);
assert(location <= font->dir.cvt_size / sizeof(s16));
ASSERT(location <= font->dir.cvt_size / sizeof(s16));
font->cvt[location] = cvt_value;
break;
}
case RCVT: {
u32 location = pop(state);
assert(location <= font->dir.cvt_size / sizeof(s16));
ASSERT(location <= font->dir.cvt_size / sizeof(s16));
s16 integer = font->cvt[location];
push(state, integer);
break;
@ -793,7 +793,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o @@ -793,7 +793,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o
// 1: round the distance and look at the control_value_cut_in
int a = inst - MIAP;
assert(state->stack_head >= 2);
ASSERT(state->stack_head >= 2);
u32 n = pop(state); // CVT entry number
u32 p = pop(state); // point number
@ -918,7 +918,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o @@ -918,7 +918,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o
}
case SWAP: {
assert(state->stack_head >= 2);
ASSERT(state->stack_head >= 2);
u32 last = state->stack[state->stack_head - 1];
u32 prelast = state->stack[state->stack_head - 2];
@ -951,7 +951,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o @@ -951,7 +951,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o
if_true = pop(state);
if (!if_true) {
assert(pair.x != (u32) -1 || pair.y != (u32) -1);
ASSERT(pair.x != (u32) -1 || pair.y != (u32) -1);
offset = MIN(pair.x, pair.y);
}
@ -961,7 +961,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o @@ -961,7 +961,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o
case ELSE: {
if (if_true) {
offset = skip_until(font_file, offset, size - (offset - base_offset), EIF);
assert(offset != (u32) -1);
ASSERT(offset != (u32) -1);
}
break;
@ -1171,7 +1171,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o @@ -1171,7 +1171,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o
case CALL: {
int f = state->stack[--state->stack_head];
assert(f <= font->maxp.max_fdefs);
ASSERT(f <= font->maxp.max_fdefs);
struct ttf_function proc = font->functions[f];
iterate_instructions(font, font_file, proc.from, proc.to - proc.from, state);
break;
@ -1678,7 +1678,7 @@ read_post(struct font_directory font_dir, struct ttf_font *font) @@ -1678,7 +1678,7 @@ read_post(struct font_directory font_dir, struct ttf_font *font)
}
static struct ttf_font
parse_ttf_file(char *filename, char *fontname)
parse_ttf_file(char *filename)
{
struct ttf_font result = { 0 };
struct font_buffer font_file = read_file(filename);
@ -1713,7 +1713,5 @@ parse_ttf_file(char *filename, char *fontname) @@ -1713,7 +1713,5 @@ parse_ttf_file(char *filename, char *fontname)
//read_cvt(&result, &font_file, font_dir, &prep_state); // the cvt program
//printf("------------- CVT END -------------\n");
result.name = fontname;
return(result);
}
}

49
ttf-rasterize.c → ttf_rasterize.c

@ -1,4 +1,3 @@ @@ -1,4 +1,3 @@
static int
scanline_intersects_line(f32 y, struct v2f p0, struct v2f p1, f32 lasty, f32 *vx)
{
@ -74,7 +73,7 @@ sort_intersections(struct intersection *intersections, int size) @@ -74,7 +73,7 @@ sort_intersections(struct intersection *intersections, int size)
static void
render_glyph(struct glyph g, int px_size, struct line_contour *lines,
f32 scale, u32 *pixels, int width, int at_x, int at_y)
f32 scale, u32 *pixels, int width, int at_x, int at_y, u32 color)
{
int oversample_y = 4;
if (px_size <= 12) {
@ -131,10 +130,15 @@ render_glyph(struct glyph g, int px_size, struct line_contour *lines, @@ -131,10 +130,15 @@ render_glyph(struct glyph g, int px_size, struct line_contour *lines,
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;
if (brightness > 0) {
pixels[(at_y + (gheight - 1 - y)) * width + (at_x + x)] = white;
f32 alpha = brightness / 256.0f;
u32 bg = pixels[(at_y + (gheight - 1 - y)) * width + (at_x + x)];
u8 r = ((bg & 0xff0000) >> 16) * (1.0f - alpha) + alpha * ((color & 0xff0000) >> 16);
u8 g = ((bg & 0x00ff00) >> 8) * (1.0f - alpha) + alpha * ((color & 0x00ff00) >> 8);
u8 b = ((bg & 0x0000ff) >> 0) * (1.0f - alpha) + alpha * ((color & 0x0000ff) >> 0);
u32 value = 0xFF000000 | r << 16 | g << 8 | b;
pixels[(at_y + (gheight - 1 - y)) * width + (at_x + x)] = value;
} else {
//pixels[(at_y + (gheight - 1 - y)) * width + (at_x + x)] = 0xFFFF0000;
}
@ -242,10 +246,11 @@ outline_to_lines(struct glyph g, f32 scale, int max_descent, struct line_contour @@ -242,10 +246,11 @@ outline_to_lines(struct glyph g, f32 scale, int max_descent, struct line_contour
static struct v2
render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wchar_t *string, u32 fit_width, int at_x, int at_y)
render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wchar_t *string, int fit_width, int at_x, int at_y)
{
u32 offset_x = at_x;
u32 offset_y = at_y;
u32 color = 0xffffffff;
s32 offset_x = at_x;
s32 offset_y = at_y;
f32 scale = (f32) px_size / ((f32) (font.hhea.ascent - font.hhea.descent));
u32 len = wcslen(string);
@ -257,7 +262,25 @@ render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wch @@ -257,7 +262,25 @@ render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wch
for (u32 i = 0; i < len; ++i) {
u16 codepoint = string[i];
int advance;
if (codepoint != ' ') {
if (codepoint == ' ') {
if (offset_x > 0) {
advance = get_codepoint_width(&font, scale, codepoint);
} else {
advance = 0;
}
} else if (codepoint == '\t') {
advance = get_codepoint_width(&font, scale, codepoint);
advance *= 4;
} else if (codepoint == '\n') {
if (offset_x > box.x) {
box.x = offset_x;
}
advance = 0;
offset_x = at_x;
offset_y += px_size;
box.y += px_size;
} else {
struct glyph g = get_outline(&font, codepoint);
//exit(0);
@ -268,23 +291,25 @@ render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wch @@ -268,23 +291,25 @@ render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wch
lines.data = malloc(nlines * sizeof(struct line));
outline_to_lines(g, scale, font.hhea.descent, &lines, 0);
render_glyph(g, px_size, &lines, scale, pixels, width, offset_x, offset_y);
render_glyph(g, px_size, &lines, scale, pixels, width, offset_x, offset_y, color);
advance = ceil_f32(scale * g.advance);
free(lines.data);
} else {
advance = get_codepoint_width(&font, scale, codepoint);
}
offset_x += advance;
box.x += advance;
if (offset_x - at_x >= fit_width) {
offset_x = at_x;
offset_y += px_size;
box.y += px_size;
box.x = fit_width;
}
}
if (offset_x > box.x) {
box.x = offset_x - at_x;
}
return(box);
}
Loading…
Cancel
Save