lvgl / lv_web_emscripten

LVGL ported to Emscripten to be converted to JavaScript
MIT License
80 stars 28 forks source link

How to use MEMFS correctly in lv_web_emscripten? #23

Open xxzling opened 6 months ago

xxzling commented 6 months ago

define LV_USE_FS_MEMFS 1

I have seen the relevant macro definitions, but there are no relevant examples. I would like to inquire about how to use the mem file system, such as having the img control display a png image?

kisvegabor commented 6 months ago

To display a PNG image you don't need MEMFS as a PNG image can be directly loaded from an array too. See here.

However, something is not clear to me either. @Xuneo, can we use LVGLImage.py to create a raw image (e.g. PNG data as it is) as a C array with lv_image_dsc_t?

xxzling commented 6 months ago

@kisvegabor Thank you for your reply, but my requirement is to be able to load font bin files from memfs or other file systems without the need for precompilation. Displaying png images is an example

kisvegabor commented 6 months ago

As you have opened the issue in the Emsripten repo, I assume you are using Emspripten. If so, from JS you can't open arbitrary files from your file system. (Else any website could read any files on your computer)

So first, you need to push the files to JS's local file system storage. Does it already work on your end? If not, I suggest taking a look at this part of Emsripten's docs. Sorry for I cannot be more specific but it's an unknown territory for me too.

xxzling commented 6 months ago

Thank you. The reason why I raised this question is because I saw File Explorer in the latest LVgl document, and its web example seems to be loaded through the memfs file system. I want to learn, but I haven't found the source code for this part, so I am asking here

I saw something like this in the HTML source code of the example

https://docs.lvgl.io/master/others/file_explorer.html

MEMFS = { ops_table: null, mount: function(A) { return MEMFS.createNode(null, "/", 16895, 0) }, createNode: function(A, B, Q, I) { if (FS.isBlkdev(Q) || FS.isFIFO(Q)) throw new FS.ErrnoError(63); MEMFS.ops_table || (MEMFS.ops_table = { dir: { node: { getattr: MEMFS.node_ops.getattr, setattr: MEMFS.node_ops.setattr, lookup: MEMFS.node_ops.lookup, mknod: MEMFS.node_ops.mknod, rename: MEMFS.node_ops.rename, unlink: MEMFS.node_ops.unlink, rmdir: MEMFS.node_ops.rmdir, readdir: MEMFS.node_ops.readdir, symlink: MEMFS.node_ops.symlink }, stream: { llseek: MEMFS.stream_ops.llseek } }, file: { node: { getattr: MEMFS.node_ops.getattr, setattr: MEMFS.node_ops.setattr }, stream: { llseek: MEMFS.stream_ops.llseek, read: MEMFS.stream_ops.read, write: MEMFS.stream_ops.write, allocate: MEMFS.stream_ops.allocate, mmap: MEMFS.stream_ops.mmap, msync: MEMFS.stream_ops.msync } }, link: { node: { getattr: MEMFS.node_ops.getattr, setattr: MEMFS.node_ops.setattr, readlink: MEMFS.node_ops.readlink }, stream: {} }, chrdev: { node: { getattr: MEMFS.node_ops.getattr, setattr: MEMFS.node_ops.setattr }, stream: FS.chrdev_stream_ops } }); var g = FS.createNode(A, B, Q, I); return FS.isDir(g.mode) ? (g.node_ops = MEMFS.ops_table.dir.node, g.stream_ops = MEMFS.ops_table.dir.stream, g.contents = {}) : FS.isFile(g.mode) ? (g.node_ops = MEMFS.ops_table.file.node, g.stream_ops = MEMFS.ops_table.file.stream, g.usedBytes = 0, g.contents = null) : FS.isLink(g.mode) ? (g.node_ops = MEMFS.ops_table.link.node, g.stream_ops = MEMFS.ops_table.link.stream) : FS.isChrdev(g.mode) && (g.node_ops = MEMFS.ops_table.chrdev.node, g.stream_ops = MEMFS.ops_table.chrdev.stream), g.timestamp = Date.now(), A && (A.contents[B] = g), g },

kisvegabor commented 6 months ago

Really there are some files and folder in the JS filesystem that you can see in the file explorer example. However these not added by us, but they are there by default. So custom images and fonts needs to added explicitly as described here.

xxzling commented 6 months ago

Thank you, I will try. I just want to inquire about how to initialize memfs in lvgl here

kisvegabor commented 6 months ago

Once LV_USE_MEMFS is enabled you can use it like this

lv_fs_path_ex_t mempath;
lv_fs_make_path_from_buffer(&mempath, LV_FS_MEMFS_LETTER, buffer, size);

lv_fs_file_t file;
lv_fs_res_t fs_res = lv_fs_open(&file, (const char *)&mempath, LV_FS_MODE_RD);

cc @zjanosy I think it's really not documented.