Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sdf sprites via additional apis #1492

Merged
merged 18 commits into from
Oct 22, 2024

Conversation

CommanderStorm
Copy link
Collaborator

@CommanderStorm CommanderStorm commented Aug 30, 2024

Resolves #1075

I am not quite right if I have made everything correctly.
The project has lots of places to configure things and it was not always clear where I need an Option.

Another thing which is likely wrong:
I'd assume as far as I read the blessing that should require new files...
Something is really odd here => need to debug that before public review makes sense

I fucked up the testcase a bit. This is now fixed

@CommanderStorm CommanderStorm marked this pull request as draft August 30, 2024 03:12
@CommanderStorm CommanderStorm changed the title Implemented sdf file conversion feat: implements sdf file conversion Aug 30, 2024
@CommanderStorm CommanderStorm marked this pull request as ready for review September 25, 2024 17:06
@nyurik
Copy link
Member

nyurik commented Oct 20, 2024

Thanks, this is an awesome feature to have. One thing I kept thinking while reviewing: would it be possible to NOT have any of the associated config values, and instead simply allow both sdf and non-sdf usage? It's not very difficult to run through the spreet crate twice and generate two spritesheets, and this would simplify usage -- either use /sprite or /sdf (or some other prefix)?

TBD:

  • does it makes any business sense to do this?
  • are there are any cases where sdf would fail to generate, while regular sprites would work?
  • do we ever want to support non-svg files for sprites, and how would that work?

@CommanderStorm
Copy link
Collaborator Author

CommanderStorm commented Oct 20, 2024

Honestly:
I have not see a difference between the pngs and sdf images, except for the sdf: true metadata.

I need to look into if this is possible, but I think we could just activate this automatically if users are using monochrome icons.

Using a different url is fine too.
You likely don't want to mix the monochrome, but color-configurable sdf images and the regularly colored pngs, but that solution achieves the goal.
What do you think about /sprites/sdf/.. instead? They are still sprites, so having that under this url is likely better.

Will have to test if this would be a breaking change though ^^
=> Will rework this today

Answering your questions:

  • does it makes any business sense to do this?

Yes, thinking about it, I can see a reason why one would want both (multi colored and dynamically colored icons on the same map)

  • are there are any cases where sdf would fail to generate, while regular sprites would work?

    I have not come across cases where this, fails to generate, but sdfs don't support multiple colors
    => the output here is black, unless colored in the map

  • do we ever want to support non-svg files for sprites, and how would that work?

    generating sdf from pngs is not possible (we are missing the distances) => users would need to supply sdf+png images to have both functionality.
    If we have such images, we should likely only support adding pngs to the pngs, not sdfs.
    Reasoning: for an sdf to exist, you would need to have a svg file (or other vector format) at some point (unless I am missing something)
    => just add the svg instead.

In any case, I need to make this more clear in the docs, why one would choose the one or the other image format.

@hiddewie
Copy link
Contributor

Hi 👋🏻, chipping into this nice PR because it would be very helpful for improving the symbol rendering one of my projects using the MapLibre stack (https://github.com/hiddewie/OpenRailwayMap-vector).

I have not see a difference between the pngs and sdf images, except for the sdf: true metadata.

Testing the output from the spreet commandline shows a difference for me when rendering the same directory

spreet symbols/general sprites

gives me
sprites

while

spreet symbols/general sprites --sdf

gives me
sprites

(colorless and with the distance field visible).

So the Martin SDF sprites should output something similar when using the spreet library.

One thing I kept thinking while reviewing: would it be possible to NOT have any of the associated config values, and instead simply allow both sdf and non-sdf usage?

It would be useful for me to have both normal and SDF sprites output and available for map rendering. The first thing I can think of is rendering the same symbol twice, one SDF with the icon outline, and the colorful icon on top to automatically generate a (fixed color) halo around a symbol.

And the other reason mentioned above, to render both colored and monochrome variants of the same image on the map is also useful.


The combination of a colorful image together with the SDF data would be ideal, but I don't think that is supported in a single sprite image by any of the libraries or SDF sprite consumers.

Maybe there could be a way to change the consuming map rendering libraries to accept two paths of the same sprite resource, one for a colorful image, and one for the SDF image, and the rendering library could combine the information to render colorful icons together with an icon halo.

@CommanderStorm CommanderStorm marked this pull request as draft October 20, 2024 13:02
@CommanderStorm CommanderStorm changed the title feat: implements sdf file conversion feat: add sdf sprites via additional apis Oct 20, 2024
@CommanderStorm
Copy link
Collaborator Author

CommanderStorm commented Oct 20, 2024

I have not see a difference between the pngs and sdf images, except for the sdf: true metadata.

That was user error. Thanks for noticing, that feature would have not worked.

I have raised a PR documenting the behaviour upstream flother/spreet#85 and fixed the bug in my code ^^


Ok((name, sprite))
}

pub async fn get_spritesheet(
sources: impl Iterator<Item = &SpriteSource>,
pixel_ratio: u8,
as_sdf: bool,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attention: There are 2-3 semver-breaking changes here.

Without reworking the API completely, I don't see how this can be avoided.

=> @nyurik would a major version bump be okay?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are totally ok to keep bumping major for martin - no biggie

@CommanderStorm CommanderStorm marked this pull request as ready for review October 20, 2024 19:13
Copy link
Member

@nyurik nyurik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks better with each pass!

WRT url - i'm still a bit on the fence on the API... /sprite/sdf/... does make sense, but then you have to handle if the user gives a sprite source named sdf (which probably is not that unusual)... On the other hand, a source called /sprite_sdf/... or /sdf/... or /sdf_sprite/... keeps naming collision resolution in one place (we already do this for sources), and keeps overall pattern consistent (no URL sub-branches). I would prefer to keep API flatter, just not sure of the naming.

martin/src/sprites/mod.rs Outdated Show resolved Hide resolved

Ok((name, sprite))
}

pub async fn get_spritesheet(
sources: impl Iterator<Item = &SpriteSource>,
pixel_ratio: u8,
as_sdf: bool,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are totally ok to keep bumping major for martin - no biggie

@CommanderStorm
Copy link
Collaborator Author

CommanderStorm commented Oct 21, 2024

Have changed it to /sdf_sprite/.. as far as the choices prefered by you, that is the best imo.

The reason why I introduced it as /sprite/sdf/.. without any backwards compatibiltiy considerations is the following:

The default regular expression associated with a replacement marker [^/]+ matches one or more characters which are not a slash. For example, under the hood, the replacement marker {foo} can more verbosely be spelled as {foo:[^/]+}.

https://actix.rs/docs/url-dispatch/#generating-resource-urls

=> even if a sprite was previously named "sdf", it could not match the new routes

@CommanderStorm CommanderStorm requested a review from nyurik October 21, 2024 20:14
@nyurik
Copy link
Member

nyurik commented Oct 22, 2024

Thx for changing - i do think it looks a bit better now, but if anyone has other thoughts, please chime in. @CommanderStorm could you add some tests to the test.sh? Make sure to run just bless afterwards.

@CommanderStorm
Copy link
Collaborator Author

could you add some tests to the test.sh?

Shure thing, have added it

Copy link
Member

@nyurik nyurik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome work!!!

@nyurik nyurik merged commit b134cb2 into maplibre:main Oct 22, 2024
18 of 19 checks passed
@CommanderStorm CommanderStorm deleted the sprite-dataformat branch October 22, 2024 16:50
@hiddewie
Copy link
Contributor

Great work @CommanderStorm, this gives nice results on my maps!

hiddewie added a commit to hiddewie/OpenRailwayMap-vector that referenced this pull request Oct 26, 2024
Uses maplibre/martin#1492

Unfortunately, SDF sprites cannot be layered right below each image,
they have to be in their own layer below the icons.

Symbols with outline:


![image](https://github.com/user-attachments/assets/da290ed7-441a-4c88-881a-88ee845d3acf)

Hovering on rail lines in their native color:


![image](https://github.com/user-attachments/assets/79556b75-e6ab-4c37-95d6-87c9d22264ab)

Railway direction including hover:


![image](https://github.com/user-attachments/assets/fe071904-2e9d-450f-8f63-e0613c8ac515)
@CommanderStorm
Copy link
Collaborator Author

We finally also had the time to finish the refactoring.
A bit of eye candy:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support SDF sprites
3 participants