Comments (26)
Although DOME doesn't have it built in, this issue resulted in the necessary features to make it possible for someone to implement it themselves, or adapt my code linked above to do so.
from dome.
It would be useful, although quite complicated to get right.
What I'd prefer to do is provide the tools for people to build wrapping stuff themselves. The built in font is 8 pixels wide, so wrapping isn't hard to devise, but there isn't the right components for TTF fonts currently to know how wide some text will be until you've printed it, which makes wrapping hard.
from dome.
With the current PR #167 providing support for newline in printing text. It would be easier for a person to make text-wrapping themselves by adding newlines at specific places. So this could probably be closed?
from dome.
Not quite. As I said, there's no way for the developer to know how wide a character or string will be to render until it has already been drawn to the display, especially if the font isn't monospace, so we will need some kind of calculateStringWidth
method.
from dome.
Ah, that's true.
calculateStringWidth(text, font)
so something like that right? Which makes use of stb_ttf
from dome.
It'd probably be an instance method on the Font object.
Eg: Font["SomeFontId"].stringWidth(text)
from dome.
Yeah but how would you calculate the width of a non-monotype font, unless you plan on calculating it each time for each letter?
from dome.
You'd have to do it at run time. The documentation should suggest caching the result (or we could do it internally).
from dome.
Yeah but doing it internally would mean having a list, map or something else with sizes of every single symbol in the font.
Since it's UTF-8 data and the font set could be with extended characters, that could be a lot data being stored no?
from dome.
Not necessarily. I mean that we would cache the result of widths of different strings, so that it doesn't have to compute widths and kerning repeatedly across frames.
Most of the time, the text being checked seems unlikely to change.
So when you call var w = Font["SomeFontId"].stringWidth(text)
, we have an internal map that goes:
stringWidth(text) {
if (!_cache[text]) {
_cache[text] = f_stringWidth(text) // Foreign method to call the true calculation method.
}
return _cache[text]
}
from dome.
Ah yeah, but let's say there's a lot of dialogue and different strings. Caching the letters being used in those specific strings might be better. Since strings like:
"Hello There World"
"Hey There World"
Probably shouldn't be cached separately, since they use a lot of common characters.
from dome.
The problem is kerning. Different combinations of letters produce different spacings, so you can't just cache letters or words.
from dome.
Hmm, I guess separating words might be more efficient then.
from dome.
Spaces between words may also differ depending on the letters at the end of the previous and start of the next word.
from dome.
Yeah but the space could be calculated based on the last letter of the first word, and the first letter of the second word right?
from dome.
It could. my point is just that we'd have to calculate that every time, even if we cache individual word lengths.
Doesn't seem like there is any perfect solution.
from dome.
Yeah, I guess it's really a balance between the memory usage and the CPU usage.
from dome.
In which case, we should implement the naive non-caching version first and see how it performs, and then we can profile different caching strategies to see if they are worth having.
from dome.
Implemented the area calculations in #182 now.
from dome.
So how would something like text wrapping be implemented efficiently? If the character width / height is known beforehand this becomes quite easy.
But for something like a textbox it would require you to calculate the width / height each time a character has been entered which I don't imagine to be a good way of doing it.
If I were to limit the character set in the textbox, so that only the characters from A-Z are allowed, then I could create a map with the dimensions of each letter (which could be done during something like a loading screen).
There are of course also non-optimal ways of doing this like calculating the average width of all letters in the font and then multiply that by length of the string. Or get the max letter width and then multiply that by the string length.
Do you have any other thoughts on how to do it? Because I don't think any of my suggestions are that optimal.
from dome.
This isn't really about wrapping though, this is more about calculating the width efficiently. Which I guess goes back to the same things we talked about above with CPU vs RAM
from dome.
I think that the "efficient" solution would require supplying data to the "print" system which defines how wide it should be allowed to draw before wrapping/clipping.
I'm imagining a TextSettings object which defines stuff like line spacing, wrapping by pixel width, line breaks based on word or characters, etc. This is quite a sophisticated thing though
from dome.
When I was working on Cartomancer I put together a function which does the bulk of these things, and could serve as a good template:
Here's an example call from the game code:
Display.print(_card.description, {
"position": Vec.new(x + b, y),
"font": "m5x7",
"align": "left",
"color": EDG32[24],
"size": Vec.new(w - b * 2, h - 8 - b * 2),
"overflow": true
})
from dome.
Should this issue be closed or is in-built text wrapping support being considered?
from dome.
I was trying to decide whether it belonged in the core engine as a utility, or whether it belongs in a library or external code snippet.
It's definitely something that I might want in multiple projects, but it's not useful in every project.
from dome.
Yeah, this doesn't seem like a need-to-have thing.
from dome.
Related Issues (20)
- Expose SDL Keycodes HOT 3
- `Canvas.offset` for retrieving the current offset HOT 3
- `Canvas.clip` for accessing the current clip settings
- DOME relies on glibc2.29 on linux
- Update to Wren 0.4.0 proper
- Update `math` module to use new Num methods HOT 6
- Update function not having a delta time parameter HOT 4
- `Canvas.font` for retrieving the current font HOT 2
- Error dialogs can be annoying during development
- Update random module to accommodate algorithm updates HOT 2
- Possible Memory Leak in Canvas HOT 1
- Linking fails on ElementaryOS / Raspberry PI HOT 4
- graphicsApi: Canvas does not resize after init HOT 1
- Add `justReleased` to get when a key has been released
- DOME doesn't handle absolute paths correctly for an entry point
- Canvas.clip crashes if the Canvas has been resized
- Plugin: DOME_Color.value seems to be ordered as 0xAABBGGRR but docs say It's 0xAARRGGBB HOT 5
- Modules with a filename the same as internal modules aren't read HOT 1
- When using offsets and clipping regions, an x less than 0 underflows to the previous row
- Scale dome.html viewport HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dome.