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

Add new canvas.RecolorSVG API #5345

Merged
merged 9 commits into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion canvas/canvas.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package canvas

import "fyne.io/fyne/v2"
import (
"image/color"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/internal/svg"
)

// Refresh instructs the containing canvas to refresh the specified obj.
func Refresh(obj fyne.CanvasObject) {
Expand All @@ -15,6 +20,19 @@ func Refresh(obj fyne.CanvasObject) {
}
}

// RecolorSVG takes a fyne.Resource containing SVG content, and returns
// the raw SVG content, re-colorized to be monochrome with the given color.
// The content can be assigned to a new fyne.StaticResource with an appropriate name
// to be used in a widget.Button, canvas.Image, etc.
//
// If an error occurs, the returned content will be the content of the input Resource,
// and a non-nil error is returned.
//
// Since: 2.6
func RecolorSVG(resource fyne.Resource, color color.Color) ([]byte, error) {
dweymouth marked this conversation as resolved.
Show resolved Hide resolved
return svg.ColorizeError(resource.Content(), color)
}

// repaint instructs the containing canvas to redraw, even if nothing changed.
func repaint(obj fyne.CanvasObject) {
app := fyne.CurrentApp()
Expand Down
20 changes: 13 additions & 7 deletions internal/svg/svg.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,28 @@ import (

// Colorize creates a new SVG from a given one by replacing all fill colors by the given color.
func Colorize(src []byte, clr color.Color) []byte {
content, err := ColorizeError(src, clr)
if err != nil {
fyne.LogError("", err)
}
return content
}

// ColorizeError is the same as Colorize, except returning instead of logging any error.
func ColorizeError(src []byte, clr color.Color) ([]byte, error) {
dweymouth marked this conversation as resolved.
Show resolved Hide resolved
rdr := bytes.NewReader(src)
s, err := svgFromXML(rdr)
if err != nil {
fyne.LogError("could not load SVG, falling back to static content:", err)
return src
return src, fmt.Errorf("could not load SVG, falling back to static content: %v", err)
}
if err := s.replaceFillColor(clr); err != nil {
fyne.LogError("could not replace fill color, falling back to static content:", err)
return src
return src, fmt.Errorf("could not replace fill color, falling back to static content: %v", err)
}
colorized, err := xml.Marshal(s)
if err != nil {
fyne.LogError("could not marshal svg, falling back to static content:", err)
return src
return src, fmt.Errorf("could not marshal svg, falling back to static content: %v", err)
}
return colorized
return colorized, nil
}

type Decoder struct {
Expand Down
Loading