Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
flightmansam opened this issue Jan 10, 2024 · 6 comments
Labels
Bug This tag is applied to issues which reports bugs.

Comments

@flightmansam
Copy link

flightmansam commented Jan 10, 2024

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 flightmansam added the Bug This tag is applied to issues which reports bugs. label Jan 10, 2024
@flightmansam
Copy link
Author

flightmansam commented Jan 10, 2024

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

@JalonSolov
Copy link
Contributor

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 JalonSolov changed the title gg.draw_text() Font size + long string causes text corruption (missing characters) mac: gg.draw_text() Font size + long string causes text corruption (missing characters) Jan 10, 2024
@flightmansam
Copy link
Author

flightmansam commented Jan 10, 2024

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
Copy link
Author

flightmansam commented Jan 10, 2024

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
Copy link
Author

flightmansam commented Jan 10, 2024

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 ??

@JalonSolov
Copy link
Contributor

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+.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug This tag is applied to issues which reports bugs.
Projects
None yet
Development

No branches or pull requests

2 participants