v icon indicating copy to clipboard operation
v copied to clipboard

mac: `gg.draw_text()` Font size + long string causes text corruption (missing characters)

Open flightmansam opened this issue 1 year ago • 6 comments

Describe the bug

If the string that is being passed to the draw_text() function is above a certain font size the text to be drawn for that font size will be corrupted (missing characters). The threshold for corruption seems to be based on the string length. Smaller length strings wont corrupt until higher font sizes.

~~Only tested on MacOS Arm so far, will try again on my x86 Windows machine when I have the time unless someone beats me to it!~~

Reproduction Steps

module main

import gg
import gx

struct Context {
mut:
	gg &gg.Context = unsafe { nil }
}

fn main() {
	mut context := &Context{
		gg: unsafe {0}
	}
	context.gg = gg.new_context(
		width: 1000
		height: 1000
		user_data: context
		window_title: 'GG error'
		create_window: true
		frame_fn: frame
	)
	context.gg.run()
}

fn frame(mut ctx Context) {
	ctx.gg.begin()
	ctx.draw()
	ctx.gg.end()
}

fn (ctx &Context) draw() {
	text_cfg := gx.TextCfg{
		color: gx.white
		align: .center
		vertical_align: .middle
		size: 50
	}

	s := gg.window_size()
	w := s.width
	h := s.height
	h_spacing := int(f32(h)/10.0)
	max_font := 100.0
	min_font := 10.0
	font_scale := (max_font-min_font)/10.0
	
	for i in 0 .. 10 {
		word := "Some very long text here"
		font_size := int(min_font+ f32(i)*font_scale) 
		ctx.gg.draw_text(2*w/3, 25+h_spacing*i, word, gx.TextCfg{...text_cfg size: font_size })
		ctx.gg.draw_text(w/4,   25+h_spacing*i, 'Font size: ${font_size}', text_cfg)
	}
}

Expected Behavior

I expect there to be no corrupted text in the above example.

I have attached the following which is expected output from 10 to 50 (which doesn't corrupt): Screenshot 2024-01-10 at 14 31 14

Current Behavior

If plotting from 10 to 100 we get this: Screenshot 2024-01-10 at 14 31 53

Refining thresholds it seems to be about 63-64 which triggers this corruption. You can see that other text (like the "Font size: X") is corrupted as well even though it is kept at size: 50 the whole time. Screenshot 2024-01-10 at 14 30 50

Using smaller length text string: Screenshot 2024-01-10 at 14 44 02

Possible Solution

No response

Additional Information/Context

No response

V version

V 0.4.3 e19b2dd

Environment details (OS name and version, etc.)

V full version: V 0.4.3 e19b2dd OS: macos, macOS, 14.1.2, 23B92 Processor: 10 cpus, 64bit, little endian, Apple M1 Pro

getwd: /Users/samuel/Desktop/v_test vexe: /Users/samuel/Documents/GitHub/v/v vexe mtime: 2024-01-05 05:25:03

vroot: OK, value: /Users/samuel/Documents/GitHub/v VMODULES: OK, value: /Users/samuel/.vmodules VTMP: OK, value: /tmp/v_501

Git version: git version 2.39.0 Git vroot status: 0.4.2-732-ge19b2dd4 (35 commit(s) behind V master) .git/config present: true

CC version: Apple clang version 15.0.0 (clang-1500.1.0.2.5) thirdparty/tcc status: thirdparty-macos-arm64 a668e5a0

[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.

flightmansam avatar Jan 10 '24 03:01 flightmansam

Can confirm that this seems to be a MacOS issue, as I just tested and there is no bug on my Windows PC.

Screenshot 2024-01-10 at 15 29 34

V full version: V 0.4.4 be4f717 OS: windows, Microsoft Windows 10 Pro v19045 64-bit Processor: 12 cpus, 64bit, little endian,

getwd: C:\Users\Samuel\Documents vexe: C:\Users\Samuel\Documents\GitHub\v\v.exe vexe mtime: 2024-01-10 04:24:36

vroot: OK, value: C:\Users\Samuel\Documents\GitHub\v VMODULES: OK, value: C:\Users\Samuel.vmodules VTMP: OK, value: C:\Users\Samuel\AppData\Local\Temp\v_0

Git version: git version 2.37.1.windows.1 Git vroot status: 0.4.4-1-gbe4f7176 .git/config present: true

CC version: Error: 'cc' is not recognized as an internal or external command, operable program or batch file.

thirdparty/tcc status: thirdparty-windows-amd64 b99a453d

flightmansam avatar Jan 10 '24 04:01 flightmansam

I can confirm it works on Linux, though there is definitely some overlap on the default width window... image

but if I expand the window size, it looks fine image

JalonSolov avatar Jan 10 '24 04:01 JalonSolov

Yeah I am using a highdpi monitor so expanding out in your case makes sense.

I think my troubles lie in the darwin specific text functions in vlib.gg.

void darwin_draw_string(int x, int y, string s, gx__TextCfg cfg) {
	NSFont* font = [NSFont userFontOfSize:0]; // cfg.size];
	// # NSFont*    font = [NSFont fontWithName:@"Roboto Mono" size:cfg.size];
	if (cfg.mono) {
		// # font = [NSFont fontWithName:@"Roboto Mono" size:cfg.size];
		font = [NSFont fontWithName:@"Menlo" size:cfg.size - 5];
	}
	if (cfg.bold) {
		font = [[NSFontManager sharedFontManager] convertFont:font toHaveTrait:NSBoldFontMask];
	}

	NSDictionary* attr = @{
		NSForegroundColorAttributeName : nscolor(cfg.color),
		// NSParagraphStyleAttributeName: paragraphStyle,
		NSFontAttributeName : font,
	};
	[nsstring(s) drawAtPoint:NSMakePoint(x, y - 15) withAttributes:attr];
}

int darwin_text_width(string s) {
	// println('text_width "$s" len=$s.len')
	NSString* n = @"";
	if (s.len == 1) {
		// println('len=1')
		n = [NSString stringWithFormat:@"%c", s.str[0]];
	} else {
		n = nsstring(s);
	}
	/*
	# if (!defaultFont){
	# defaultFont = [NSFont userFontOfSize: ui__DEFAULT_FONT_SIZE];
	# }
	# NSDictionary *attrs = @{
	# NSFontAttributeName: defaultFont,
	# };
	*/
	NSSize size = [n sizeWithAttributes:nil];
	// # printf("!!!%f\n", ceil(size.width));
	return (int)(ceil(size.width));
}

flightmansam avatar Jan 10 '24 05:01 flightmansam

I can confirm it works on Linux, though there is definitely some overlap on the default width window...

BTW this is going to sound very silly but I was trying to run this example on my linux vm (stock Debian Arm) and I could not for the life of me get the thing running. I blindly installed a bunch of libs to make it sorta compile but at runtime I get a GLX crash:

sokol.memory.slog | user_data: (nil), const_tag: sapp, level: 0, item_id: 35, fname: /home/samuel/v/thirdparty/sokol/sokol_app.h, line: 10011, message: LINUX_GLX_CREATE_CONTEXT_FAILED: Failed to create GL context via glXCreateContextAttribsARB
X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  149 (GLX)
  Minor opcode of failed request:  5 (X_GLXMakeCurrent)
  Serial number of failed request:  159
  Current serial number in output stream:  159

What libs do I need to install for linux to use sokol/gg/gx ? :)

flightmansam avatar Jan 10 '24 05:01 flightmansam

I think my troubles lie in the darwin specific text functions in vlib.gg.

. . .

This was a false lead. After some quick debugging with some print statements I found sokol/gg is not using the macOS native pipeline, so the bug isn't anything to do with the objc stuff.

I'll start looking into the fontstash wrapper, although the on the c side of things the repo is 10/11 years dry so no wonder things get weird with MacOS. There also seems to be like.. a completely different version of fontstash out there which seems to have provisions for differentiating macOS OpenGL/vs GL libraries ??

flightmansam avatar Jan 10 '24 05:01 flightmansam

I can confirm it works on Linux, though there is definitely some overlap on the default width window...

BTW this is going to sound very silly but I was trying to run this example on my linux vm (stock Debian Arm) and I could not for the life of me get the thing running. I blindly installed a bunch of libs to make it sorta compile but at runtime I get a GLX crash:

sokol.memory.slog | user_data: (nil), const_tag: sapp, level: 0, item_id: 35, fname: /home/samuel/v/thirdparty/sokol/sokol_app.h, line: 10011, message: LINUX_GLX_CREATE_CONTEXT_FAILED: Failed to create GL context via glXCreateContextAttribsARB
X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  149 (GLX)
  Minor opcode of failed request:  5 (X_GLXMakeCurrent)
  Serial number of failed request:  159
  Current serial number in output stream:  159

What libs do I need to install for linux to use sokol/gg/gx ? :)

Nothing special, except that you do need a video driver that supports OpenGL 3.3+.

JalonSolov avatar Jan 18 '24 02:01 JalonSolov