Recolor a monochrome icon SVG to the active theme's ink. Local copy of widget_binding.cpp::recolorSvgInk (kept local because pj_widgets/SvgUtil.h is not on this module's include path): swaps #3D3D3D<->#E0E0E0 so the icon authored for one theme renders in the other's ink, plus legacy black/white.
| 101 | // not on this module's include path): swaps #3D3D3D<->#E0E0E0 so the icon |
| 102 | // authored for one theme renders in the other's ink, plus legacy black/white. |
| 103 | void recolorSvgInk(QByteArray& svg_data, bool light_theme) { |
| 104 | const QByteArray ink = light_theme ? QByteArray("#3D3D3D") : QByteArray("#E0E0E0"); |
| 105 | const QByteArray opposite = light_theme ? QByteArray("#E0E0E0") : QByteArray("#3D3D3D"); |
| 106 | svg_data.replace(opposite, ink); // palette swap (icon authored for the other theme) |
| 107 | svg_data.replace("#000000", ink); // legacy black -> ink |
| 108 | svg_data.replace("#ffffff", opposite); |
| 109 | const qsizetype svg_open = svg_data.indexOf("<svg"); |
| 110 | if (svg_open < 0) { |
| 111 | return; |
| 112 | } |
| 113 | const qsizetype tag_end = svg_data.indexOf('>', svg_open); |
| 114 | if (tag_end <= svg_open) { |
| 115 | return; |
| 116 | } |
| 117 | // Inject a root fill only when none is present, so fill-less Material paths |
| 118 | // inherit the theme ink. |
| 119 | if (svg_data.mid(svg_open, tag_end - svg_open).contains("fill=\"")) { |
| 120 | return; |
| 121 | } |
| 122 | svg_data.insert(tag_end, " fill=\"" + ink + "\""); |
| 123 | } |
| 124 | |
| 125 | // Rasterize already-prepared SVG bytes into a px-logical QIcon at size*DPR so it |
| 126 | // stays crisp on HiDPI. Callers own the theming/recoloring of `svg_data`; this is |
no test coverage detected