Giter Club home page Giter Club logo

Comments (26)

avivbeeri avatar avivbeeri commented on June 14, 2024 1

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.

avivbeeri avatar avivbeeri commented on June 14, 2024

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.

BenStigsen avatar BenStigsen commented on June 14, 2024

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.

avivbeeri avatar avivbeeri commented on June 14, 2024

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.

BenStigsen avatar BenStigsen commented on June 14, 2024

Ah, that's true.
calculateStringWidth(text, font) so something like that right? Which makes use of stb_ttf

from dome.

avivbeeri avatar avivbeeri commented on June 14, 2024

It'd probably be an instance method on the Font object.

Eg: Font["SomeFontId"].stringWidth(text)

from dome.

BenStigsen avatar BenStigsen commented on June 14, 2024

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.

avivbeeri avatar avivbeeri commented on June 14, 2024

You'd have to do it at run time. The documentation should suggest caching the result (or we could do it internally).

from dome.

BenStigsen avatar BenStigsen commented on June 14, 2024

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.

avivbeeri avatar avivbeeri commented on June 14, 2024

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.

BenStigsen avatar BenStigsen commented on June 14, 2024

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.

avivbeeri avatar avivbeeri commented on June 14, 2024

The problem is kerning. Different combinations of letters produce different spacings, so you can't just cache letters or words.

from dome.

BenStigsen avatar BenStigsen commented on June 14, 2024

Hmm, I guess separating words might be more efficient then.

from dome.

avivbeeri avatar avivbeeri commented on June 14, 2024

Spaces between words may also differ depending on the letters at the end of the previous and start of the next word.

from dome.

BenStigsen avatar BenStigsen commented on June 14, 2024

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.

avivbeeri avatar avivbeeri commented on June 14, 2024

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.

BenStigsen avatar BenStigsen commented on June 14, 2024

Yeah, I guess it's really a balance between the memory usage and the CPU usage.

from dome.

avivbeeri avatar avivbeeri commented on June 14, 2024

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.

avivbeeri avatar avivbeeri commented on June 14, 2024

Implemented the area calculations in #182 now.

from dome.

BenStigsen avatar BenStigsen commented on June 14, 2024

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.

BenStigsen avatar BenStigsen commented on June 14, 2024

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.

avivbeeri avatar avivbeeri commented on June 14, 2024

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.

avivbeeri avatar avivbeeri commented on June 14, 2024

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:

https://github.com/avivbeeri/cartomancer/blob/8a460ddacf375dc9dfd769aa3fe8a1701d76853a/core/display.wren#L22

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.

BenStigsen avatar BenStigsen commented on June 14, 2024

Should this issue be closed or is in-built text wrapping support being considered?

from dome.

avivbeeri avatar avivbeeri commented on June 14, 2024

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.

BenStigsen avatar BenStigsen commented on June 14, 2024

Yeah, this doesn't seem like a need-to-have thing.

from dome.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.