D
Deno

help

Deno SDL2 Default Text Render Example (FFI problem w 1.29)

Ccaptainbuckkets12/21/2022
Trying to get the font render example in the Deno SDL2 repo https://github.com/littledivy/deno_sdl2/blob/main/examples/font/font.ts to work but it perpetually complains about a pointer to buffer issue. I've read through the issues that were proposed to fix this solution and tried modifications of my own to solve this issue based on this PR here https://github.com/littledivy/deno_sdl2/pull/58 but the issue still remained in my own modifications. Wondering if anybody has any ideas on how to resolve this as it pertains specifically to FFI problems which I thought would be resolved in Deno 1.29 since that seemed to caused breaking changes. I've already tried the v3 released of SDL2 and it did not resolve the problem either. I have a large and mature project I want to port over to desktop but cannot use this solution until I can draw font. I am not seeking alternative solutions such as Electron :) Error:
Uncaught TypeError: Invalid FFI buffer type, expected null, ArrayBuffer, or ArrayBufferView
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
Uncaught TypeError: Invalid FFI buffer type, expected null, ArrayBuffer, or ArrayBufferView
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
GitHub
deno_sdl2/font.ts at main · littledivy/deno_sdl2
SDL2 module for Deno. Contribute to littledivy/deno_sdl2 development by creating an account on GitHub.
AAapoAlas12/21/2022
What's the exact error?
Ccaptainbuckkets12/21/2022
Forgot to include: @aapoalas
Uncaught TypeError: Invalid FFI buffer type, expected null, ArrayBuffer, or ArrayBufferView
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
Uncaught TypeError: Invalid FFI buffer type, expected null, ArrayBuffer, or ArrayBufferView
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
Ccaptainbuckkets12/21/2022
You can read a similar error here which could be resolved by changing the expected parameter to "buffer" instead of "pointer" but making those changes for the font render doesn't resolve the error for me https://github.com/littledivy/deno_sdl2/issues/55
GitHub
Uncaught TypeError: Invalid FFI pointer type, expected null, intege...
Trying to run the hello.ts example, but getting an error, pasted below. This happens on multiple machines on the latest deno. The most recent version of deno I have laying around where the code wor...
Ccaptainbuckkets12/21/2022
This would be the code I'm working out of
import { Color, EventType, WindowBuilder } from "./old_mod.ts";
import { FPS } from "./utils.ts";

const stepFrame = FPS();
const window = new WindowBuilder("deno_sdl2 Font", 800, 600).build();
const canvas = window.canvas();

const font = canvas.loadFont(".\\jetbrains-mono.ttf", 128);
const color = new Color(0, 0, 0);

const surface = font.renderSolid("Hello there!", color);

const creator = canvas.textureCreator();
const texture = creator.createTextureFromSurface(surface);

async function frame() {
canvas.clear();
canvas.copy(texture);
canvas.present();
stepFrame();
}

for (const event of window.events()) {
if (event.type == EventType.Quit) Deno.exit(0);
else if (event.type == EventType.Draw) frame();
}
import { Color, EventType, WindowBuilder } from "./old_mod.ts";
import { FPS } from "./utils.ts";

const stepFrame = FPS();
const window = new WindowBuilder("deno_sdl2 Font", 800, 600).build();
const canvas = window.canvas();

const font = canvas.loadFont(".\\jetbrains-mono.ttf", 128);
const color = new Color(0, 0, 0);

const surface = font.renderSolid("Hello there!", color);

const creator = canvas.textureCreator();
const texture = creator.createTextureFromSurface(surface);

async function frame() {
canvas.clear();
canvas.copy(texture);
canvas.present();
stepFrame();
}

for (const event of window.events()) {
if (event.type == EventType.Quit) Deno.exit(0);
else if (event.type == EventType.Draw) frame();
}
const sdl2Font = Deno.dlopen(getLibraryPath("SDL2_ttf"), {
"TTF_Init": {...},
"TTF_OpenFont": {...},
"TTF_RenderText_Solid": {
"parameters": ["buffer", "buffer", "buffer"],
"result": "pointer",
},
const sdl2Font = Deno.dlopen(getLibraryPath("SDL2_ttf"), {
"TTF_Init": {...},
"TTF_OpenFont": {...},
"TTF_RenderText_Solid": {
"parameters": ["buffer", "buffer", "buffer"],
"result": "pointer",
},
You can see the relevant section its failing on here
AAapoAlas12/21/2022
Catch the error, check parameters. It seems like the code is probably being called with a pointer number somewhere.
Ccaptainbuckkets12/21/2022
Okay, I wrapped it in try catch and added additional logging around the function it goes into
export class Font {
[_raw]: Deno.UnsafePointer;
constructor(raw: Deno.UnsafePointer) {
this[_raw] = raw;
}

renderSolid(text: string, color: Color) {
try {
console.log("text", text, "color", color)
console.log(
"this[_raw]", this[_raw],
"asCString(text)", asCString(text),
"color[_raw]", color[_raw],
)
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
this[_raw],
asCString(text),
color[_raw],
);
return new Texture(raw);
} catch (error) {
console.log("error", error)
}
}
...
}
export class Font {
[_raw]: Deno.UnsafePointer;
constructor(raw: Deno.UnsafePointer) {
this[_raw] = raw;
}

renderSolid(text: string, color: Color) {
try {
console.log("text", text, "color", color)
console.log(
"this[_raw]", this[_raw],
"asCString(text)", asCString(text),
"color[_raw]", color[_raw],
)
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
this[_raw],
asCString(text),
color[_raw],
);
return new Texture(raw);
} catch (error) {
console.log("error", error)
}
}
...
}
// Console.log output
text Hello there! color Color { [Symbol(raw)]: 2643565591888 }
this[_raw] 2644682958720 asCString(text) Uint8Array(13) [
72, 101, 108, 108, 111,
32, 116, 104, 101, 114,
101, 33, 0
] color[_raw] 2643565591888
// Console.log output
text Hello there! color Color { [Symbol(raw)]: 2643565591888 }
this[_raw] 2644682958720 asCString(text) Uint8Array(13) [
72, 101, 108, 108, 111,
32, 116, 104, 101, 114,
101, 33, 0
] color[_raw] 2643565591888
How can I identify a pointer in JS? Must be the this[_raw] since thats a Deno.UnsafePointer I tried to cast it as an array buffer but it said allocation failed
renderSolid(text: string, color: Color) {
try {
console.log("text", text, "color", color)
console.log(
"this[_raw]", this[_raw],
"asCString(text)", asCString(text),
"color[_raw]", color[_raw],
)
const pointer = this[_raw];
const buffer = new ArrayBuffer(pointer);
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
buffer,
asCString(text),
color[_raw],
);
return new Texture(raw);
} catch (error) {
console.log("error", error)
}
}
renderSolid(text: string, color: Color) {
try {
console.log("text", text, "color", color)
console.log(
"this[_raw]", this[_raw],
"asCString(text)", asCString(text),
"color[_raw]", color[_raw],
)
const pointer = this[_raw];
const buffer = new ArrayBuffer(pointer);
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
buffer,
asCString(text),
color[_raw],
);
return new Texture(raw);
} catch (error) {
console.log("error", error)
}
}
Error
error RangeError: Array buffer allocation failed
error RangeError: Array buffer allocation failed
Very bad because that means it cant allocate enough Could be either the this[_raw] or the Color since that might be being passed in as a pointer. Casting both using the asCString did not fix, nor did changing the type expectations in the relevant section
Ccaptainbuckkets12/21/2022
Tried casting color and the pointer to BigInt and tried using TextEncoder but no change https://stackoverflow.com/questions/61813646/whats-deno-equivalent-of-node-js-buffer-fromstring
Stack Overflow
What's Deno equivalent of Node.js Buffer.from(string)
How can I convert a string to a buffer? I tried: Uint8Array.from('hello world') but it isn't working
Ccaptainbuckkets12/21/2022
I've seen this so many I can try to adjust it
Ccaptainbuckkets12/21/2022
I've changed every value in here to null and identified the text as the problem it seems
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
this[_raw],
null, // asCString(text)
color[_raw],
);
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
this[_raw],
null, // asCString(text)
color[_raw],
);
This will atleast not result in an error Okay so this
renderSolid(text: string, color: Color) {
try {
const encoder = new TextEncoder()
const buffer = encoder.encode(text);
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
this[_raw],
buffer,
color[_raw],
);
return new Texture(raw);
} catch (error) {
console.log("error", error)
}
}
renderSolid(text: string, color: Color) {
try {
const encoder = new TextEncoder()
const buffer = encoder.encode(text);
const raw = sdl2Font.symbols.TTF_RenderText_Solid(
this[_raw],
buffer,
color[_raw],
);
return new Texture(raw);
} catch (error) {
console.log("error", error)
}
}
with
"TTF_RenderText_Solid": {
"parameters": ["pointer", "buffer", "pointer"],
"result": "pointer",
},
"TTF_RenderText_Solid": {
"parameters": ["pointer", "buffer", "pointer"],
"result": "pointer",
},
is acceptable and doesn't error out
Ccaptainbuckkets12/21/2022
Ccaptainbuckkets12/21/2022
Now just to figure out how to draw a rect in SDL and copy the texture to it so its predictable
AAapoAlas12/22/2022
Good that you got it figured out. The logging here shows that the first and third parameters are indeed numbers (pointer) and not buffers, so that was the issue as you found out. The asCstring method will probably automatically add a null character at the end of your string, whereas doing a direct encode() does not and will probably eventually lead to the native code reading beyond the bounds of your string buffer. Better to use the asCstring helper method.
Ccaptainbuckkets12/22/2022
I did the encode and it did remove the null character but I see that as a serious concern. How then, can one draw font without those characters in a cross platform way? Also it did kinda seem that playing with the encoding of the test made the color application not stick to the font consistently
AAapoAlas12/22/2022
By adding the null character. Encode '${string}\0' or just use the asCstring helper which does that for you
Ccaptainbuckkets12/22/2022
Interesting. Will try again tomorrow and see what it does
AAapoAlas12/22/2022
It will essentially just make the resulting Uint8Array 1 byte longer. eg. above your "Hello there!" logged:
asCString(text) Uint8Array(13) [
72, 101, 108, 108, 111,
32, 116, 104, 101, 114,
101, 33, 0
]
asCString(text) Uint8Array(13) [
72, 101, 108, 108, 111,
32, 116, 104, 101, 114,
101, 33, 0
]
With a direct encode it'd log
encoder.encode(text) Uint8Array(12) [
72, 101, 108, 108, 111,
32, 116, 104, 101, 114,
101, 33
]
encoder.encode(text) Uint8Array(12) [
72, 101, 108, 108, 111,
32, 116, 104, 101, 114,
101, 33
]
So, you're just missing the singlar null byte from the end.
Ccaptainbuckkets12/24/2022
I see. That seemed to resolve it. Still have inconsistent color results which is really odd

Looking for more? Join the community!

Recommended Posts
third party module - edit webhook subdirectoryHi, I just published a module https://deno.land/x/sqlite_native@0.1.0 but the actual library contentPermissions dumpIs there a way to dump permissions to console or to a shell file after answering the prompts interacRemove trailing commasUsing the `deno.json` feature, how can I remove trailing commas? I can't find anything related to tharch linux deno package might be brokenInstalling deno on arch linux appears to 404 on all the mirrors. I just synchronized them all as wel500 error in httpsdeno.landxfresh1.1.2srcserverhtmlescape.tsI'm having problems on my CI because this dependency returns a 500 error from deno.land. How can I dDisable Deno VSCode TS typesThis is a recent updates. I like to code in Javascript and the new types are incredibly distracting-Can I programatically trigger a SIGINT event?I would like to trigger a SIGINT event from a file, is there a way to do this? For example in Node, i think the language server is brokenwas working perfectly fine last night, and im not sure how to fixHow to forward a reference to a componentI created this sample to exemplify what I don't understand. Using the Fresh framework, I created the[Fixed] Package cannot read a file from itself when loaded from urlI have a package A, which has to read an html file located at the package's root, such as the followhow can I enable Deno vscode all inlay hints at once?There seem to be too many config options that I have to set to `true`. Is there a way to just enable--max-stack-sizeI can set the maximum call stack size on deno?Deno Deploy --cert flagI am using deno fresh and supabase postgres. When in local environment I use --cert flag to set ssl What is the best database service to plug into your application hosted on Deno Deploy?Deno Deploy is hosted on Google Cloud, but I was wondering: is a database service from another compa