You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
5.5 KiB
192 lines
5.5 KiB
#include <stdint.h> |
|
#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> |
|
|
|
#include <sys/ioctl.h> |
|
#include <sys/mman.h> |
|
#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; |
|
typedef int8_t s8; |
|
|
|
typedef uint64_t u64; |
|
typedef uint32_t u32; |
|
typedef uint16_t u16; |
|
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" |
|
|
|
static Display *display; |
|
static Window window; |
|
static GC default_gc; |
|
static XImage* xwindow_buffer; |
|
|
|
int |
|
main(int argc, char **argv) |
|
{ |
|
if (argc != 2) { |
|
fprintf(stderr, "Usage: %s filename.ttf\n", argv[0]); |
|
return(1); |
|
} |
|
|
|
display = XOpenDisplay(0); |
|
Window root_window = DefaultRootWindow(display); |
|
|
|
int default_screen = DefaultScreen(display); |
|
int screen_bit_depth = 24; |
|
int width = 1280; |
|
int height = 720; |
|
|
|
XVisualInfo visinfo = { 0 }; |
|
XMatchVisualInfo(display, default_screen, screen_bit_depth, TrueColor, &visinfo); |
|
|
|
XSetWindowAttributes window_attr; |
|
window_attr.bit_gravity = StaticGravity; |
|
window_attr.background_pixel = 0; |
|
window_attr.colormap = XCreateColormap(display, root_window, visinfo.visual, AllocNone); |
|
window_attr.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask; |
|
|
|
unsigned long attribute_mask = CWBitGravity | CWBackPixel | CWColormap | CWEventMask; |
|
|
|
window = XCreateWindow(display, root_window, |
|
0, 0, |
|
width, height, 0, |
|
visinfo.depth, InputOutput, |
|
visinfo.visual, attribute_mask, &window_attr); |
|
|
|
XGrabPointer(display, window, False, ButtonPressMask | PointerMotionMask, |
|
GrabModeAsync, GrabModeAsync, None, None, CurrentTime); |
|
|
|
XSelectInput(display, window, KeyPress | KeyRelease | ButtonRelease | PointerMotionMask); |
|
|
|
XStoreName(display, window, "ttf"); |
|
XMapWindow(display, window); |
|
XFlush(display); |
|
|
|
Atom WM_DELETE_WINDOW = XInternAtom(display, "WM_DELETE_WINDOW", False); |
|
XSetWMProtocols(display, window, &WM_DELETE_WINDOW, 1); |
|
|
|
int pixel_bits = 32; |
|
int pixel_bytes = pixel_bits / 8; |
|
int window_buffer_size = width * height * pixel_bytes; |
|
void *hc_vram = malloc(window_buffer_size); |
|
|
|
xwindow_buffer = XCreateImage(display, visinfo.visual, visinfo.depth, ZPixmap, 0, hc_vram, width, height, |
|
pixel_bits, 0); |
|
|
|
default_gc = DefaultGC(display, default_screen); |
|
|
|
struct ttf_font font = parse_ttf_file(argv[1], "Inter"); |
|
printf("Loaded font\n"); |
|
|
|
u32 *pixels = hc_vram; |
|
int t = 0; |
|
|
|
for (;;) { |
|
//memset(pixels, 0xFF, width * height * 4); |
|
//memset(pixels, 0xFF, width * height * 4); |
|
memset(pixels, 0x00, width * height * 4); |
|
|
|
int at = 75; |
|
//render_utf_string(font, 18, pixels, width, L"The quick brown fox jumps over the lazy dog", 100, 150); |
|
//render_utf_string(font, 12, pixels, width, L"This text is seriously small", 100, at); at += 12; |
|
//render_utf_string(font, 13, pixels, width, L"This text is seriously small", 100, at); at += 13; |
|
render_utf_string(font, 12, pixels, width, L"This text is seriously small", 100, at); at += 12; |
|
render_utf_string(font, 18, pixels, width, L"aolo2@avx:~/Documents/code/ttf-test (master) $", 100, at); at += 20; |
|
render_utf_string(font, 26, pixels, width, L"render_utf_string(font, 32, pixels, width, string3, 10 + w1 + w2, at);", 10, at); at += 24; |
|
render_utf_string(font, 24, pixels, width, L"The quick brown fox jumps over the lazy dog", 10, at); at += 24; |
|
|
|
wchar_t *string1 = L"iiiiiiiiiiiiiiiiiii"; |
|
wchar_t *string2 = L"something-some"; |
|
wchar_t *string3 = L"MORE MORE"; |
|
|
|
int w1 = get_string_width(&font, 32, string1, wcslen(string1)); |
|
int w2 = get_string_width(&font, 32, string2, wcslen(string2)); |
|
|
|
render_utf_string(font, 32, pixels, width, string1, 10, at); |
|
render_utf_string(font, 32, pixels, width, string2, 10 + w1, at); |
|
render_utf_string(font, 32, pixels, width, string3, 10 + w1 + w2, at); |
|
at += 80; |
|
render_utf_string(font, 80, pixels, width, L"~!@#$%^&*()_+;:,./\\||||", 10, at); |
|
|
|
XPutImage(display, window, default_gc, xwindow_buffer, 0, 0, 0, 0, width, height); |
|
|
|
sleep(1); |
|
|
|
++t; |
|
} |
|
|
|
return(0); |
|
}
|
|
|