davewx7 / citadel

A turn based strategy game based on the Anura engine
Other
99 stars 25 forks source link

Missing non-breaking spaces at the deck preview widget. #234

Open ghost opened 6 years ago

ghost commented 6 years ago

Example: pic at https://github.com/davewx7/citadel/issues/230#issuecomment-401637291, the creature icon is separated from the 30 by a standard space, a breaking is required, and happens at a wrong place.


Future proof explanation.

It currently can arrange as:

[...] 🌳 17 πŸ”΄πŸ“œ 16 πŸ‘ΌπŸ”ͺ 6 🐺
30 πŸ“œ 15 β›° 5

That's ugly. It should better arrange as either:

[...] 🌳 17 πŸ”΄πŸ“œ 16 πŸ‘ΌπŸ”ͺ 6 🐺 30
πŸ“œ 15 β›° 5

Or better yet, if possible:

[...] 🌳 17 πŸ”΄πŸ“œ 16 πŸ‘ΌπŸ”ͺ 6
🐺 30 πŸ“œ 15 β›° 5
HarryMichal commented 6 years ago

Looks like this could be solved by just adding non-breaking space markup entry to cairo.cpp and use it in deck_preview_widget.cfg

EDIT: Nope, taking that back. It's not that simple :sweat_smile:

ghost commented 6 years ago

Looks like this could be solved by just adding non-breaking space markup entry to cairo.cpp and use it in deck_preview_widget.cfg

EDIT: Nope, taking that back. It's not that simple πŸ˜…

I'd try to create two strings, one for the school analysis and the other for spell-creature-land analysis, then replace all spaces by U+00A0 non-breaking space inside (via anonymous FFL function) in both the strings, then paste both strings with a standard [U+0020] space.

It'll break anyway once added RTL languages. πŸ˜…

HarryMichal commented 6 years ago

I already split the big string into two separate strings. I just don't know how to properly implement non-breaking space. The strings use anura's own markup languag implementation and I'm not sure if it supports non-breaking space.

ghost commented 6 years ago

I never did before. I tried to create a non breaking space by passing   to the markup processor. That did't work well, but as you can read in the Wikipedia on Non-breaking space,   is an alternative expression. Look what happens when passing  :

--> c.markup_text(' ', 40) where c = canvas()
[(object at address 0x7fce...){path...,
path_no_translate: ...
translate_x: 0.0,
...
get_slice: (0x7fce...)(, )}]
--> _

It seems the engine eats the input, hopefully doing the wanted thing.

What do we do here?

If you try both c.markup_text('a a', 40) where c = canvas() and c.markup_text('a a', 40) where c = canvas(), I think it looks consistent.

I think that could be a right clue.

Ask any doubt it still remains or this raises...

HarryMichal commented 6 years ago

What kind of problem using   raised? I tried it using the command you suggested and it produces vaild response.

Also all these markup expressions of non-breaking space seem to produce a space with various sizes, but all these spaces are not the non-breaking ones.

And I tried both the commands you suggested at the end of your comment and they seem to produce slightly different result. After using   the space appears to be wider even though the number of characters is the same.

ghost commented 6 years ago

What kind of problem using   raised? I tried it using the command you suggested and it produces vaild response.

I get:

--> c.markup_text(' ', 100) where c = canvas()
error parsing formula: cairo.cpp:718 ASSERTION FAILED: Could not find markup: 'nbsp'

--> _

Also all these markup expressions of non-breaking space seem to produce a space with various sizes, but all these spaces are not the non-breaking ones.

Oops, bad idea then. Maybe use two texts instead of only one, unless everything fits in one line?

HarryMichal commented 6 years ago

Right now the text on the widget is separated into 4 parts:

All of these fit well except for the second one (we know that) and I'm not sure how to fix this really.

ghost commented 6 years ago

I think there are a number of ways:

# 1: I was hoping we can create any number of canvases. Maybe this is worth trying. But canvases are large to work with, I'd say also not the easiest part of the FFL toolset.

# 2: If canvases overlap is not supported, or is not working for some other reason, we could use an implementation of the line break HTML tag I believe to read in https://github.com/anura-engine/anura/blame/trunk/src/xhtml/xhtml_element.cpp#L176-L180. I can't make it work. Maybe it worked but broke, maybe it's half baked, I don't know.

# 3: I still think the plan could work. Look at this larger example:

--> c.markup_text('Catherine, Lady of the Blade', 100) where c = canvas()
[...]
text: 'Catherine, Lady ',
[...]
text: 'of the Blade',
[...]
--> _

That's breaking, OK it's surely working as it should. Let's insert a non-breaking space:

--> c.markup_text('Catherine, Lady‚of the Blade', 100) where c = canvas()
[...]
text: 'Catherine, '
[...]
text: 'Lady  of the Blade',
[...]
--> _

The non breaking space prevented the break, that's nice. So the idea could work!

Alright, I get one of your points now. The space is doubled. That's no good.

Maybe that's simply a rendering issue of the console. Been sighting similar cases because, we know, our own locale only nonASCII characters (as č or ñ)... console doesn't handle them perfectly. I suspect of something about wide chars being interpreted as plain old chars, but I don't know.

Maybe the issue is not actually occurring to a canvas printing text using a TTF with typical large Unicode support? Did you try this?

Let's suppose the worst case and the space is rendering doubly, or badly for some other reason, when actually rendering the text in the canvas, while running the game.

# 3.1: Then there would be a simple FFL fast workaround to it. What about..?

--> c.markup_text('Catherine, Lady‚of the Blade', 100)[1].text where c = canvas()
'Lady  of the Blade'
--> melt_spaces(c.markup_text('Catherine, Lady‚of the Blade', 100)[1].text)
    where c = canvas()
    where melt_spaces = def (string s) -> string
        fold(map(s, replace_spaces(value)), a + b)
    where replace_spaces = def (string s) -> string
        if(s != 'B' and s != 'L' and s != 'a' and s != 'd' and s != 'e' and s != 'f'
                and s != 'h' and s != 'l' and s != 'o' and s != 't' and s != 'y',
           /* then */
           ' ',
           /* else */
           s
        )
'Lady of the Blade'
--> _

https://www.youtube.com/watch?v=bjxf-eQWKoo

Tada! Double space gone. This is quite unoptimal, maybe a bit convoluted, surely not the tersest way, worst of all taking advantage of an excessively simplistic example; but to illustrate a possible last resort alternative. Many times there is an easy-to-code FFL block you can use for temporarily fixing whatever ugly stuff obstructing.

He dared call me Cat once. I soon reminded him that cats have claws.

ghost commented 6 years ago

There was an error I fixed and now the example can be run in the console without getting a brackets balance error.