* renderer: rewrite glyph cache
This commit splits the current GlyphSet-based system into 2 caches,
CharMap and GlyphMap, which maps codepoints -> glyph IDs and glyph IDs -> glyphs respectively.
Each GlyphMap contains a number of GlyphAtlas mapped by their width,
and each GlyphAtlas has a list of surfaces with the same width.
Surfaces within the GlyphAtlas acts like a bump allocator, but is flexible
enough to allow older GlyphAtlas surfaces to be recycled.
GlyphMetric now contains atlas_idx and surface_idx, which points to the correct surface.
Since GlyphAtlas supports rudimentary packing & allocation, we no longer render whole
GlyphSets and this speeds up rendering in most cases.
Tab width is no longer set with the hacky "modify the GlyphMetric" hack.
* renderer: set natlas to 0 after freeing
* renderer: fix printf warning
* renderer: fix memory leak
* renderer: better whitespace rendering
* renderer: fix ubsan warning when casting ints
* renderer: fix tab handling
There's a bug with inconsistent tab widths caused by fontgroups.
* renderer: fix glyphs being loaded over and over
* renderer: add glyphmap size
* renderer: store per-surface offset_y and use it to find best-fitting surface
* renderer: fix MSVC compiler error
* renderer: remove return value from ren_font_glyph
* renderer: refactor xadvance calculation
* renderer: fix double free SDL_RWops if FT_Set_Pixel_Size fail
* renderer: always try .notdef before U+25A1
* renderer: disable ren_font_dump yet again
Accidentally commited this change.
* renderer: remove unused imports
* renderer: fix double free with FT_Open_Face
* renderer: return SDL_Surface in font_find_glyph_surface
* renderer: bring back metric flags for future extension
* renderer: refactor xadvance calculation into macro
* renderer: fix comment
* renderer: store GlyphMetric directly in the surface
* renderer: remove duplicated comment
* renderer: rename font_find_glyph_surface to font_allocate_glyph_surface
* renderer: refactor glyphmetric retrieval into an inline function
* renderer: do not render glyphs with bitmap set to null
This is a weird edge case, but at least it shouldn't crash
* renderer: refactor face metric code into its own function
* renderer: actually check if glyph fits in surface
* renderer: rudimentary support for non-scalable faces
At least it won't render nothing on the screen
* renderer: check for font_surface instead of metric directly
This is safe and shorter
* renderer: fix indentation
* renderer: rename GLYPH_PER_ATLAS to GLYPHS_PER_ATLAS
* renderer: rename all GLYPH_PER_ATLAS correctly
* renderer: make utf8_to_codepoint slightly more durable
* renderer: fix compiler unsigned cast warning
* remove scaling logic from font code
for the time being its been hardcoded to 1 for the non SDL Renderer basewin setup, so nothing is lost for non MacOS users.
will be revisited in the future when scaling is improved with SDL3 and moved into scripts.
* remove unused window_renderer argument from font functions
* move window logic to lua, pass window via argument
* rename window creation functions `*_create`, `*_destroy`, add real init
* Set active window when processing frame
* get size directly from RenWindow, get active window size from renderer
* correct reverted draw calls
* fix window not reappearing on restart
* add simple logic to persist the core window
* fix style
* add renwindow documentation
* make windows hidden by default again
* reorder ren_update_rects execution, add comment to note future work
* Update font scale on monitor scale change for `RENDERER` backend (macOS)
* fix(renderer): check every font of a fontgroup for scale changes in `update_font_scale`
It is needed because fonts can be reused between groups and outside of them.
So if the first font of a group has already been scaled, we still need to check if the others still needs to be scaled.
* add system.setenv
* document system.setenv
* system.setenv: use wide versions of functions on windows
* do not include processenv.h
* system.setenv: report failure, including of utfconv
* system.setenv: free utfconv output
* fix: free-before-init in renwin_init_surface when using sdl renderer
`ren->rensurface.surface` presupposes zero-initialized rensurface.
Rensurface was not actually zero-initialized.
It is now.
* fix: heap buffer overflow in process_env_free
`process_env_free` presupposed that it was null-terminated.
Pass length to free instead.
* use calloc instead of memset for zero-init
Co-authored-by: Guldoman <giulio.lettieri@gmail.com>
---------
Co-authored-by: Guldoman <giulio.lettieri@gmail.com>
* feat(process): allow commands and envs on proces_start
* refactor(process): copy process arguments once whenever possible
Refactors the code to use an arglist type which is just lpCmdline on Windows
and a list in Linux.
The function automatically escapes the command when it is needed, avoiding
a second copy.
This also allows UTF-8 commands btw.
* fix(process): fix invalid dereference
* refactor(process): mark xstrdup as potentially unused
* feat(process): add parent process environment when launching process
* fix(process): fix operator precedence with array operators
* fix(process): fix segfault when freeing random memory
* fix(process): fix wrong check for setenv()
* fix(process): fix accidentally initializing an array by assignment
* fix(process): clear return value if success
* Use `PATHSEP` in path-related functions
* Don't stop on digits when getting the common part in `system.path_compare`
* Avoid sorting multiple times in `dirwatch.get_directory_files`
This also fixes the timeout detection in `recurse_pred`.
* feat(src/renderer): stream fonts with SDL_RWops on all platforms
This fixes#1529 where the font itself carries the font file, which gets copied around.
This commit streams the file, so the file is not entirely in memory.
* style(src/renderer): use standard C types
* refactor(src/renderer): implement FT_Stream.close
* fix(src/renderer): fix SDL_RWops double free
* Close lua state when exiting on a runtime error
* This change allows calling the garbage collector before exiting the
application for a cleaner shutdown.
* Components like the shared memory object on #1486 will have a better
chance at destroying no longer needed resources.
* Overriden os.exit to always close the state
* Allow setting close param on os.exit override
* Simplified the os.exit override a bit more
Co-authored-by: Guldoman <giulio.lettieri@gmail.com>
---------
Co-authored-by: Guldoman <giulio.lettieri@gmail.com>