[a / b / c / d / e / f / g / gif / h / hr / k / m / o / p / r / s / t / u / v / vg / vm / vmg / vr / vrpg / vst / w / wg] [i / ic] [r9k / s4s / vip] [cm / hm / lgbt / y] [3 / aco / adv / an / bant / biz / cgl / ck / co / diy / fa / fit / gd / hc / his / int / jp / lit / mlp / mu / n / news / out / po / pol / pw / qst / sci / soc / sp / tg / toy / trv / tv / vp / vt / wsg / wsr / x / xs] [Settings] [Search] [Mobile] [Home]
Board
Settings Mobile Home
/g/ - Technology

Name
Options
Comment
Verification
4chan Pass users can bypass this verification. [Learn More] [Login]
File
  • Please read the Rules and FAQ before posting.
  • You may highlight syntax and preserve whitespace by using [code] tags.

08/21/20New boards added: /vrpg/, /vmg/, /vst/ and /vm/
05/04/17New trial board added: /bant/ - International/Random
10/04/16New board for 4chan Pass users: /vip/ - Very Important Posts
[Hide] [Show All]


[Advertise on 4chan]


File: 1760287171.png (104 KB, 1498x708)
104 KB
104 KB PNG
I just wanted to render some fonts to a png file ...
>>
>>106866126
you should have more than a 64 GB eMMC if you're developing software
>>
rookies, try building aosp instead
>>
>>106866170
good meme, i'll save it
>>
meanwhile in C
$ curl -O https://raw.githubusercontent.com/nothings/stb/refs/heads/master/stb_truetype.h
$ curl -O https://github.com/nothings/stb/blob/master/stb_image_write.h
$ gcc -Wall -Wextra -g3 -Og main.c -lm
$ du -sh a.out
756K a.out
>>
>>106866170
generally agree but I kind of hate that having 30-40GB worth of dependencies in ~/.conan or node_modules or whatever is the norm now.
>>
File: t3.webm (1.74 MB, 1400x660)
1.74 MB
1.74 MB WEBM
>>106866126
<====
the swash crate might be of interest to you btw
>>
>>106866642
>--release
>>
>>106866170
criminal that crapbooks still have 256GB soldered
>>
>>106866642
that's 1GB without --release
>>
>>106866642
Anon, that is still bloated. Probably with lots of CP hidden there and ready to be deployed if you talk shit about certain tribe.
>>106866547
Nice.
>>
>>106866656
>>106866701
>that's 1GB without --release
<====
>>106866547
cargo new render-0
cd render-0
cargo add image --no-default-features --features=png
cargo add swash


and code
use std::str::FromStr;
use std::{env, fs, path::PathBuf};

use image::{GrayImage, ImageFormat};
use swash::FontRef;
use swash::scale::{Render, ScaleContext, Source};

fn main() {
let font_path = env::args().nth(1)
.expect("pass font path");

let font_path = PathBuf::from_str(&font_path)
.expect("valid path");

let font_bytes = fs::read(&font_path)
.expect("failed to read font data");

let font = FontRef::from_index(&font_bytes, 0)
.expect("no fontref from font bytes");

let mut ctx = ScaleContext::new();

let mut scaler = ctx.builder(font)
.size(128.0)
.hint(true)
.build();

let sources = [Source::default()];
let render = Render::new(&sources);
let glyph_id = font.charmap().map('0');

let swash_image = render.render(&mut scaler, glyph_id)
.expect("rendered glyph");

let p = swash_image.placement;


let image = GrayImage::from_raw(p.width, p.height, swash_image.data)
.expect("gray image from swash image data");

image.save_with_format("0.png", ImageFormat::Png)
.expect("save gray image as png");
}


and the binary
cargo build --release
% du -sh target/release/render-0
1.9M target/release/render-0
% strip target/release/render-0
% du -sh target/release/render-0
1.5M target/release/render-0


swash uses some google libraries under the hood which will become universally used.

share your equivalent C program with the sizes of the non-libc libraries required if any.
>>
File: t.png (43 KB, 1786x103)
43 KB
43 KB PNG
>>106866886
><====
forgot picrel
>>
>>106866126
>just
1. Styling (parse markup, query system for fonts)
2. Layout (break text into lines)
3. Shaping (compute the glyphs in a line and their positions)
4. Rasterization (rasterize needed glyphs into an atlas/cache)
6. Composition (copy glyphs from the atlas to their desired positions)
>>
>>106866954
let's look at swash
>Non goals
>Due to the intention of being generally useful and easy to integrate, the following areas of related interest are specifically avoided:
>Text layout. This is highly application specific and the requirements for both features and performance differ greatly among web browsers, word processors, text editors, game engines, etc. There is a sibling crate in development that does provide general purpose text layout based on this library.
>Composition. Like layout, this is also application specific in addition to being hardware dependent. Glyph caching, geometry batching and rendering all belong here and should integrate well with the application and the hardware environment.
>>
>>106866126
Vector fonts were a mistake.
>>
>>106867017
The idea is fine the implementation is bad, font formats are the transvestite of formats, they are the prostitute of Adobe, Apple and Microsoft designed to be portable to no systems (they chose to used BE).
>>
>>106867017
Actually, the font library only adds 17M. It is the image library that adds 500MB
>>
>>106866886
so this renders a single glyph, not layed out text? with stb_truetype it would be something like
#define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype.h>

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb_image_write.h>


FILE* f = fopen(path, "rb");
if (!f) { err(1, "fopen"); }
fseek(f, 0, SEEK_END);
long size = ftell(f);
fseek(f, 0, SEEK_SET);
void* data = malloc(size);
fread(data, 1, size, f);
fclose(f);

stbtt_fontinfo font_info;
stbtt_InitFont(&font_info, data, stbtt_GetFontOffsetForIndex(data, 0));

float scale = stbtt_ScaleForMappingEmToPixels(&font_info, emsize);

int width, height, offx, offy;
uint8_t* bitmap = stbtt_GetCodepointBitmap(&font_info, scale, scale, codepoint, &width, &height, &xoff, &yoff);

stbi_write_png("output.png", width, height, 1, bitmap, 0);

stbtt_FreeBitmap(bitmap, NULL);
free(data);
>>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define STB_TRUETYPE_IMPLEMENTATION
#define STBTT_STATIC
#define STB_IMAGE_WRITE_STATIC
#include <stb/stb_image_write.h>
#include <stb/stb_truetype.h>

#include <stdio.h>
#include <stdint.h>


int main(int argc, char *argv[]) {
if (argc != 2) {
printf("USAGE: %s <font-file>\n", argv[0]);
return 1;
}

FILE *fp = fopen(argv[1], "rb");
if (!fp) {
perror("fopen");
return 1;
}
size_t bufsz = 16384 * 16;
uint8_t *fontdata = malloc(bufsz);
size_t fontlen = 0;
while (true) {
size_t toread = bufsz - fontlen;
size_t len = fread(&fontdata[fontlen], 1, bufsz - fontlen, fp);
fontlen += len;
if (len == toread) {
bufsz *= 2;
fontdata = realloc(fontdata, bufsz);
} else break;
}
fclose(fp);

struct stbtt_fontinfo font = {0};
if (!stbtt_InitFont(&font, fontdata, 0)) {
puts("Failed to load font");
return 1;
}

float scale = stbtt_ScaleForMappingEmToPixels(&font, 128);
int w, h;
uint8_t *rendered = stbtt_GetCodepointBitmap(&font, scale, scale, '0', &w, &h, NULL, NULL);

if (!stbi_write_png("out.png", w, h, 1, rendered, 0)) {
puts("Failed to save image\n");
return 1;
}

stbtt_FreeBitmap(rendered, NULL);
free(fontdata);

return 0;
}

Perhaps more verbose, but the program is much smaller.
$ time gcc -lm -O3 ftoimg.c
gcc -lm -O3 ftoimg.c 1.03s user 0.01s system 99% cpu 1.045 total
$ du -sh a.out
56K a.out
$ strip a.out
$ du -sh a.out
52K a.out
>>
>>106866547
>stb_truetype.h
// =======================================================================
//
// NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES
//
// This library does no range checking of the offsets found in the file,
// meaning an attacker can use it to read arbitrary memory.
//
// =======================================================================

OHNONONONO
CENILE BROS
HOW DO WE COPE
This is for performance reasons, right? RIGHT?! Surely it is MUCH faster than rust!!! IT HAS TO BE!
>>
>>106868231
>>106867965
>>106867476
>>106866547
C is one of the oldest languages, its too old and there are far better, I mean just use rust and stop spreading 'trannie psyop' bullfuckery. Its safer, faster, and literally better. 200 megs and ya'll crying, there are 120+ gb games. Grow up ffs
>>
>>106868231
usecase for untrusted font files?
>>
>>106868231
>HOW DO WE COPE
by not using it on untrusted font files? I don't understand the question.
>>
>>106866642
...lol
>>
>>106868321
500M to translate to png. Does your game only write to a png? Odd game
>>
>>106868321
you do realize that your program is not the only thing on a computer, right? you understand that this shit adds up? right??
>>
>>106866954
>>106867001
>>106867476
you get EVERYTHING with cosmic-text, including advanced shaping of course.
cargo new render-cosmic
cargo add image --no-default-features --features=png
cargo add cosmic-text


main

use cosmic_text::{Attrs, Buffer, Color, Family, FontSystem, Metrics, Shaping, SwashCache, Weight};
use image::{RgbaImage, GenericImage, ImageFormat, Rgba};

fn main() {
let mut font_system = FontSystem::new();
let mut swash_cache = SwashCache::new();

let metrics = Metrics::new(128.0, 128.0);

let mut buffer = Buffer::new(&mut font_system, metrics);
let mut buffer = buffer.borrow_with(&mut font_system);

let (w,h) = (1400, 400);
let mut image = RgbaImage::new(w, h);
buffer.set_size(Some(w as f32), Some(h as f32));

let attrs = Attrs::new()
.family(Family::Name("Noto Sans"))
.weight(Weight::MEDIUM);

buffer.set_text(" 0 1 2 3 4 5 6 7 8 9 0 -+=\n Joined RTL text below:\n اللغة العربية\n", &attrs, Shaping::Advanced);
buffer.shape_until_scroll(true);

let def_color = Color::rgb(0xFF, 0x00, 0x00);


buffer.draw(&mut swash_cache, def_color, |x, y, w, h, c| {
if x >= 0 && y >= 0 {
let c = Rgba([c.r(), c.g(), c.b(), c.a()]);
let (x, y) = (u32::try_from(x).unwrap(), u32::try_from(y).unwrap());
let mut sub_image = image.sub_image(x, y, w, h);
(0..w) .for_each(|i_x| {
(0..h).for_each(|i_y| {
sub_image.put_pixel(i_x, i_y, c)
})
});
}
});

image.save_with_format("cosmic.png", ImageFormat::Png)
.expect("save gray image as png");
}


and sizes

cargo build --release
% du -sh target
161M target
% du -sh target/release/render-cosmic
3.3M target/release/render-cosmic
% strip target/release/render-cosmic
% du -sh target/release/render-cosmic
2.8M target/release/render-cosmic


loaded libraries...
>>
>>106868333
How do you come to trust font files? Make them yourself?
>>
the funniest thing about all of this is that rust spends all this binary size and compile time on including debug info even though most rust programmers are the kind that doesn't use a debugger and just does printf debugging + constantly recompiling so effectively you're just making their debugging experience worse not better LMFAO
>>
>>106868450
>loaded libraries...

ldd target/release/render-cosmic | rg -r '$1' '.*=> ([^ ]+) .*'|sort -u | xargs realpath | xargs du -sh
2.1M /usr/lib/libc.so.6
888K /usr/lib/libgcc_s.so.1
1.1M /usr/lib/libm.so.6
244K /usr/lib/ld-linux-x86-64.so.2


for comparison, if you need harfbuzz and freetype and nothing else:

% ldd /usr/lib/libharfbuzz.so /usr/lib/libfreetype.so | rg -r '$1' '.*=> ([^ ]+) .*'|sort -u | xargs realpath | xargs du -sh
140K /usr/lib/libbrotlicommon.so.1.1.0
56K /usr/lib/libbrotlidec.so.1.1.0
76K /usr/lib/libbz2.so.1.0.8
2.1M /usr/lib/libc.so.6
832K /usr/lib/libfreetype.so.6.20.4
1.4M /usr/lib/libglib-2.0.so.0.8600.0
136K /usr/lib/libgraphite2.so.3.2.1
1.1M /usr/lib/libm.so.6
684K /usr/lib/libpcre2-8.so.0.14.0
228K /usr/lib/libpng16.so.16.50.0
100K /usr/lib/libz.so.1.3.1


and i'm deliberately not "ricing" sizes here, i could compile against shared rust std, use full lto, a single codegen unit, and use the equivalent of -Os or -Oz, but all that would be retarded, as is all discourse around binary sizes.

but in any case, op was 10x off as shown in >>106866642. which is very usual for /g/ (some claims are 100x off lol).
>>
>>106866126
Just use the gd graphics library, or get the 10x20 gnu unifont and bitblt the characters onto a bitmap and dump the bitmap into whatever (i.e. png) you want.
Mac and Windows can do this pretty much natively.
>>
>>106868479
Rust guarantees that programs don’t have any memory bugs (which is pretty much all bugs, who ever heard of a computer that didn’t have memory).
So you really don’t need a debugger with rust, and testing itself is pretty much not needed since that is all handled with the compiler.
>>
>>106868791
HAHAHAHAHAHHAHAHAHHAH incredible bait
>>
>>106868231
the purpose of that library is to convert ttfs to font atlus textures for video games. this is clearly for an intermediary compilation step. why would it matter if it was insecure?
>>
>>106866547
ok. now show me comparable C and Rust code using these deps.



[Advertise on 4chan]

Delete Post: [File Only] Style:
[Disable Mobile View / Use Desktop Site]

[Enable Mobile View / Use Mobile Site]

All trademarks and copyrights on this page are owned by their respective parties. Images uploaded are the responsibility of the Poster. Comments are owned by the Poster.