+
Skip to content

renderer: support shape-rendering="crispEdges" for aliased shapes #2499

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

OverloadedOrama
Copy link
Collaborator

Implements #1869 for the software renderer. If the shape-rendering="crispEdges" attribute is used in the SVG, the software renderer does not use anti-aliasing for the shape's lines. The rest of the shape-rendering values just default to anti-aliasing, I'm not sure how else to handle them. I tested it with svg2png and Godot and it seems to be working as intended.

Tested using the following svg file:

<svg width="460" height="200">
  <rect width="140" height="30" x="10" y="10" rx="20" ry="20" style="fill:rgb(0,0,255)" />
  <rect width="140" height="30" x="160" y="10" rx="20" ry="20" style="fill:rgb(0,0,255);stroke-width:1;stroke:red" />
  <rect width="140" height="30" x="310" y="10" rx="20" ry="20" shape-rendering="crispEdges" style="fill:rgb(0,0,255);stroke-width:1;stroke:red" />
  <rect width="140" height="30" x="10" y="60" rx="20" ry="20" fill="none" style="stroke-width:1;stroke:red" />
  <rect width="140" height="30" x="160" y="60" rx="20" ry="20" fill="none" shape-rendering="crispEdges" style="stroke-width:1;stroke:red" />
  <ellipse cx="210" cy="110" rx="170" ry="15" shape-rendering="crispEdges" style="fill:lime" />
  <ellipse cx="210" cy="160" rx="200" ry="30" style="fill:purple" />
  <polyline points="20,20 40,25 60,40 80,120 120,140 200,180"
    style="fill:none;stroke:white;stroke-width:3" shape-rendering="crispEdges" />
  <polyline points="60,20 80,25 100,40 120,120 160,140 240,180"
    style="fill:none;stroke:white;stroke-width:3" />
  <path d="M 10 10 C 20 20, 40 20, 50 10" stroke="black" shape-rendering="crispEdges" fill="transparent"/>
</svg>

Result png:
Result png

This is the first time I'm contributing to ThorVG, hopefully I did everything right. 😅

@hermet hermet added the feature New feature additions label Jul 1, 2024
@hermet
Copy link
Member

hermet commented Jul 1, 2024

@OverloadedOrama Hello, Thanks for your contribution. I am curious about the practical use of this feature in user applications. Could you provide some tips on use cases?

@hermet
Copy link
Member

hermet commented Jul 1, 2024

@OverloadedOrama One more question, do you really need to apply this per shape or scene? or is it applied to the full screen in the ThorVG canvas?

@OverloadedOrama
Copy link
Collaborator Author

@hermet Hello! I am working on a pixel art editor made with Godot, and I want to implement support for vector layers in order to have non-destructive shapes, and my idea is to construct a SVG behind the scenes that gets rasterized by Godot/ThorVG in order to be drawn in the canvas. This already can work fine, but all shapes are currently anti-aliased, with no option to turn it off, which doesn't work well with pixel art. So I thought to use the shape-rendering SVG attribute to control whether a shape is anti-aliased or not.

I think this needs to be applied per-shape, just like the attribute is per-shape in SVG, in order to allow users to choose which shapes are anti-aliased and which ones are not.

@hermet
Copy link
Member

hermet commented Jul 1, 2024

@RuiwenTang @SergeyLebedkin Hello, could you please confirm with the GL/WG engine side if they can allow the AA option per shape?

@OverloadedOrama OverloadedOrama force-pushed the crisp-edges branch 2 times, most recently from 49972ae to 25cf78c Compare July 3, 2024 20:13
@OverloadedOrama
Copy link
Collaborator Author

I'm not sure why unit tests are failing. For some reason, if I uncomment either line 90 or line 91 on tvgSwShape.cpp, the unit tests pass fine, but I don't understand why adding line 90 makes them fail.

@github-actions github-actions bot added svg SVG features APIs Update / Revise APIs cpu Software render backend renderer Core rendering labels Oct 24, 2024
@hermet hermet force-pushed the main branch 6 times, most recently from 87ee4f3 to 9b43b93 Compare December 18, 2024 05:37
@hermet hermet changed the title Support shape-rendering="crispEdges" for aliased shapes in the software renderer renderer: support shape-rendering="crispEdges" for aliased shapes Feb 13, 2025
@hermet
Copy link
Member

hermet commented Mar 31, 2025

Thanks for your contribution. Still some considerations:

  • ThorVG can probably support anti-aliasing toggle internally through the SVG loader and renderer, without exposing specific APIs because I don't think AA toggle per shape is a general requirement.
  • Because of that reason, I'm not sure whether adding a flag for each shape is a good idea in sake of optimal memory usage, because it would harm the general use-cases, a global option is good though.
  • @OverloadedOrama It would be nice if you have a practical demo in production.

@OverloadedOrama
Copy link
Collaborator Author

Hello @hermet, apologies for the late reply. I don't have a practical demo ready at the moment, but as I mentioned the reason I need this is because I want to add vector layers in my pixel art software, which is made with Godot, and I'd like to give users the option to disable AA so the shapes can look better for pixel art. If you think that adding a per-shape flag for AA is not needed and it can increase memory usage, then I completely understand and I'd be okay with a more global solution.

What I'd ideally want though is for a way to toggle AA with SVG code. The idea for vector layers is to pass an SVG string and use Godot's Image.load_svg_from_string to turn SVG into a rasterized image. From what I understand, this uses ThorVG's software renderer behind the scenes. Using the shape-rendering tag for each shape is the closest thing I could find to this, and when I compiled Godot with this PR's version of ThorVG, it was working as expected. If there's a better solution for this, I'm of course open to it! If a global option is implemented, perhaps it could be passed as an extra parameter for Image.load_svg_from_string and Image.load_svg_from_buffer, like it happens with the scale parameter, but I suppose that needs to be done in Godot's side.

@hermet hermet force-pushed the main branch 5 times, most recently from 9b6c8bc to a6ffb7a Compare June 23, 2025 07:12
@hermet hermet force-pushed the main branch 5 times, most recently from 7ceb794 to 43923a5 Compare June 25, 2025 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
APIs Update / Revise APIs cpu Software render backend feature New feature additions renderer Core rendering svg SVG features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载