use iced_widget::image::Handle; use include_dir::{Dir, include_dir}; use resvg::tiny_skia; use std::collections::HashMap; use std::sync::{LazyLock, Mutex}; static BRANDING: Dir<'static> = include_dir!("$CARGO_MANIFEST_DIR/../../branding/assets"); const RASTER_SCALE: f32 = 2.0; static CACHE: LazyLock>> = LazyLock::new(|| Mutex::new(HashMap::new())); pub fn icon_handle(name: &str) -> Option { let (key, path, size) = lookup(name)?; if let Some(cached) = CACHE.lock().ok().and_then(|c| c.get(key).cloned()) { return Some(cached); } let bytes = BRANDING.get_file(path)?.contents(); let handle = if path.ends_with(".svg") { rasterize_svg(bytes, size)? } else { decode_raster(bytes)? }; if let Ok(mut cache) = CACHE.lock() { cache.insert(key, handle.clone()); } Some(handle) } fn rasterize_svg(bytes: &[u8], size: Option) -> Option { let opt = usvg::Options::default(); let tree = usvg::Tree::from_data(bytes, &opt).ok()?; let svg_size = tree.size(); let (width, height) = match size { Some(s) => { let s_f = s as f32 * RASTER_SCALE; (s_f.max(1.0).round() as u32, s_f.max(1.0).round() as u32) } None => { let w = (svg_size.width() * RASTER_SCALE).max(1.0).round() as u32; let h = (svg_size.height() * RASTER_SCALE).max(1.0).round() as u32; (w, h) } }; let scale_x = width as f32 / svg_size.width(); let scale_y = height as f32 / svg_size.height(); let transform = tiny_skia::Transform::from_scale(scale_x, scale_y); let mut pixmap = tiny_skia::Pixmap::new(width, height)?; resvg::render(&tree, transform, &mut pixmap.as_mut()); let rgba = pixmap.take_demultiplied(); Some(Handle::from_rgba(width, height, rgba)) } fn decode_raster(bytes: &[u8]) -> Option { let img = image::load_from_memory(bytes).ok()?.to_rgba8(); let (w, h) = img.dimensions(); Some(Handle::from_rgba(w, h, img.into_raw())) } fn lookup(name: &str) -> Option<(&'static str, &'static str, Option)> { for &(n, path, size) in ICONS { if n == name { return Some((n, path, size)); } } None } const ICONS: &[(&str, &str, Option)] = &[ ("GraphiteLogotypeSolid", "graphics/graphite-logotype-solid.svg", None), ("Add", "icon-12px-solid/add.svg", Some(12)), ("Checkmark", "icon-12px-solid/checkmark.svg", Some(12)), ("Clipped", "icon-12px-solid/clipped.svg", Some(12)), ("CloseX", "icon-12px-solid/close-x.svg", Some(12)), ("Delay", "icon-12px-solid/delay.svg", Some(12)), ("Dot", "icon-12px-solid/dot.svg", Some(12)), ("DotThick", "icon-12px-solid/dot-thick.svg", Some(12)), ("DropdownArrow", "icon-12px-solid/dropdown-arrow.svg", Some(12)), ("Edit12px", "icon-12px-solid/edit-12px.svg", Some(12)), ("Empty12px", "icon-12px-solid/empty-12px.svg", Some(12)), ("Failure", "icon-12px-solid/failure.svg", Some(12)), ("FullscreenEnter", "icon-12px-solid/fullscreen-enter.svg", Some(12)), ("FullscreenExit", "icon-12px-solid/fullscreen-exit.svg", Some(12)), ("Grid", "icon-12px-solid/grid.svg", Some(12)), ("GridDotted", "icon-12px-solid/grid-dotted.svg", Some(12)), ("Info", "icon-12px-solid/info.svg", Some(12)), ("KeyboardArrowDown", "icon-12px-solid/keyboard-arrow-down.svg", Some(12)), ("KeyboardArrowLeft", "icon-12px-solid/keyboard-arrow-left.svg", Some(12)), ("KeyboardArrowRight", "icon-12px-solid/keyboard-arrow-right.svg", Some(12)), ("KeyboardArrowUp", "icon-12px-solid/keyboard-arrow-up.svg", Some(12)), ("KeyboardBackspace", "icon-12px-solid/keyboard-backspace.svg", Some(12)), ("KeyboardCommand", "icon-12px-solid/keyboard-command.svg", Some(12)), ("KeyboardControl", "icon-12px-solid/keyboard-control.svg", Some(12)), ("KeyboardEnter", "icon-12px-solid/keyboard-enter.svg", Some(12)), ("KeyboardOption", "icon-12px-solid/keyboard-option.svg", Some(12)), ("KeyboardShift", "icon-12px-solid/keyboard-shift.svg", Some(12)), ("KeyboardSpace", "icon-12px-solid/keyboard-space.svg", Some(12)), ("KeyboardTab", "icon-12px-solid/keyboard-tab.svg", Some(12)), ("License12px", "icon-12px-solid/license-12px.svg", Some(12)), ("Link", "icon-12px-solid/link.svg", Some(12)), ("Overlays", "icon-12px-solid/overlays.svg", Some(12)), ("Remove", "icon-12px-solid/remove.svg", Some(12)), ("RenderModeNormal", "icon-12px-solid/render-mode-normal.svg", Some(12)), ("RenderModeOutline", "icon-12px-solid/render-mode-outline.svg", Some(12)), ("RenderModePixels", "icon-12px-solid/render-mode-pixels.svg", Some(12)), ("RenderModeSvg", "icon-12px-solid/render-mode-svg.svg", Some(12)), ("Snapping", "icon-12px-solid/snapping.svg", Some(12)), ("SwapHorizontal", "icon-12px-solid/swap-horizontal.svg", Some(12)), ("SwapVertical", "icon-12px-solid/swap-vertical.svg", Some(12)), ("VerticalEllipsis", "icon-12px-solid/vertical-ellipsis.svg", Some(12)), ("Warning", "icon-12px-solid/warning.svg", Some(12)), ("WindowButtonWinClose", "icon-12px-solid/window-button-win-close.svg", Some(12)), ("WindowButtonWinMaximize", "icon-12px-solid/window-button-win-maximize.svg", Some(12)), ("WindowButtonWinMinimize", "icon-12px-solid/window-button-win-minimize.svg", Some(12)), ("WindowButtonWinRestoreDown", "icon-12px-solid/window-button-win-restore-down.svg", Some(12)), ("WorkingColors", "icon-12px-solid/working-colors.svg", Some(12)), ("AlignBottom", "icon-16px-solid/align-bottom.svg", Some(16)), ("AlignHorizontalCenter", "icon-16px-solid/align-horizontal-center.svg", Some(16)), ("AlignLeft", "icon-16px-solid/align-left.svg", Some(16)), ("AlignRight", "icon-16px-solid/align-right.svg", Some(16)), ("AlignTop", "icon-16px-solid/align-top.svg", Some(16)), ("AlignVerticalCenter", "icon-16px-solid/align-vertical-center.svg", Some(16)), ("Artboard", "icon-16px-solid/artboard.svg", Some(16)), ("BooleanDifference", "icon-16px-solid/boolean-difference.svg", Some(16)), ("BooleanDivide", "icon-16px-solid/boolean-divide.svg", Some(16)), ("BooleanIntersect", "icon-16px-solid/boolean-intersect.svg", Some(16)), ("BooleanSubtractBack", "icon-16px-solid/boolean-subtract-back.svg", Some(16)), ("BooleanSubtractFront", "icon-16px-solid/boolean-subtract-front.svg", Some(16)), ("BooleanUnion", "icon-16px-solid/boolean-union.svg", Some(16)), ("Bug", "icon-16px-solid/bug.svg", Some(16)), ("CheckboxChecked", "icon-16px-solid/checkbox-checked.svg", Some(16)), ("CheckboxUnchecked", "icon-16px-solid/checkbox-unchecked.svg", Some(16)), ("Close", "icon-16px-solid/close.svg", Some(16)), ("CloseAll", "icon-16px-solid/close-all.svg", Some(16)), ("Code", "icon-16px-solid/code.svg", Some(16)), ("Copy", "icon-16px-solid/copy.svg", Some(16)), ("Credits", "icon-16px-solid/credits.svg", Some(16)), ("CustomColor", "icon-16px-solid/custom-color.svg", Some(16)), ("Cut", "icon-16px-solid/cut.svg", Some(16)), ("DeselectAll", "icon-16px-solid/deselect-all.svg", Some(16)), ("Edit", "icon-16px-solid/edit.svg", Some(16)), ("Empty", "icon-16px-solid/empty.svg", Some(16)), ("ExpandFillStroke", "icon-16px-solid/expand-fill-stroke.svg", Some(16)), ("Eyedropper", "icon-16px-solid/eyedropper.svg", Some(16)), ("EyeHidden", "icon-16px-solid/eye-hidden.svg", Some(16)), ("EyeHide", "icon-16px-solid/eye-hide.svg", Some(16)), ("EyeShow", "icon-16px-solid/eye-show.svg", Some(16)), ("EyeVisible", "icon-16px-solid/eye-visible.svg", Some(16)), ("File", "icon-16px-solid/file.svg", Some(16)), ("FileExport", "icon-16px-solid/file-export.svg", Some(16)), ("FileImport", "icon-16px-solid/file-import.svg", Some(16)), ("FlipHorizontal", "icon-16px-solid/flip-horizontal.svg", Some(16)), ("FlipVertical", "icon-16px-solid/flip-vertical.svg", Some(16)), ("Folder", "icon-16px-solid/folder.svg", Some(16)), ("FolderOpen", "icon-16px-solid/folder-open.svg", Some(16)), ("FrameAll", "icon-16px-solid/frame-all.svg", Some(16)), ("FrameSelected", "icon-16px-solid/frame-selected.svg", Some(16)), ("GraphiteLogo", "icon-16px-solid/graphite-logo.svg", Some(16)), ("GraphViewClosed", "icon-16px-solid/graph-view-closed.svg", Some(16)), ("GraphViewOpen", "icon-16px-solid/graph-view-open.svg", Some(16)), ("HandleVisibilityAll", "icon-16px-solid/handle-visibility-all.svg", Some(16)), ("HandleVisibilityFrontier", "icon-16px-solid/handle-visibility-frontier.svg", Some(16)), ("HandleVisibilitySelected", "icon-16px-solid/handle-visibility-selected.svg", Some(16)), ("Heart", "icon-16px-solid/heart.svg", Some(16)), ("HistoryRedo", "icon-16px-solid/history-redo.svg", Some(16)), ("HistoryUndo", "icon-16px-solid/history-undo.svg", Some(16)), ("IconsGrid", "icon-16px-solid/icons-grid.svg", Some(16)), ("Image", "icon-16px-solid/image.svg", Some(16)), ("InterpolationBlend", "icon-16px-solid/interpolation-blend.svg", Some(16)), ("InterpolationMorph", "icon-16px-solid/interpolation-morph.svg", Some(16)), ("Layer", "icon-16px-solid/layer.svg", Some(16)), ("License", "icon-16px-solid/license.svg", Some(16)), ("NewLayer", "icon-16px-solid/new-layer.svg", Some(16)), ("Node", "icon-16px-solid/node.svg", Some(16)), ("NodeBlur", "icon-16px-solid/node-blur.svg", Some(16)), ("NodeBrushwork", "icon-16px-solid/node-brushwork.svg", Some(16)), ("NodeColorCorrection", "icon-16px-solid/node-color-correction.svg", Some(16)), ("NodeGradient", "icon-16px-solid/node-gradient.svg", Some(16)), ("NodeMagicWand", "icon-16px-solid/node-magic-wand.svg", Some(16)), ("NodeMask", "icon-16px-solid/node-mask.svg", Some(16)), ("NodeMotionBlur", "icon-16px-solid/node-motion-blur.svg", Some(16)), ("NodeNodes", "icon-16px-solid/node-nodes.svg", Some(16)), ("NodeOutput", "icon-16px-solid/node-output.svg", Some(16)), ("NodeShape", "icon-16px-solid/node-shape.svg", Some(16)), ("NodeText", "icon-16px-solid/node-text.svg", Some(16)), ("NodeTransform", "icon-16px-solid/node-transform.svg", Some(16)), ("PadlockLocked", "icon-16px-solid/padlock-locked.svg", Some(16)), ("PadlockUnlocked", "icon-16px-solid/padlock-unlocked.svg", Some(16)), ("Paste", "icon-16px-solid/paste.svg", Some(16)), ("PinActive", "icon-16px-solid/pin-active.svg", Some(16)), ("PinInactive", "icon-16px-solid/pin-inactive.svg", Some(16)), ("PlaybackPause", "icon-16px-solid/playback-pause.svg", Some(16)), ("PlaybackPlay", "icon-16px-solid/playback-play.svg", Some(16)), ("PlaybackToEnd", "icon-16px-solid/playback-to-end.svg", Some(16)), ("PlaybackToStart", "icon-16px-solid/playback-to-start.svg", Some(16)), ("Random", "icon-16px-solid/random.svg", Some(16)), ("Reload", "icon-16px-solid/reload.svg", Some(16)), ("Reset", "icon-16px-solid/reset.svg", Some(16)), ("Resync", "icon-16px-solid/resync.svg", Some(16)), ("Reverse", "icon-16px-solid/reverse.svg", Some(16)), ("ReverseRadialGradientToLeft", "icon-16px-solid/reverse-radial-gradient-to-left.svg", Some(16)), ("ReverseRadialGradientToRight", "icon-16px-solid/reverse-radial-gradient-to-right.svg", Some(16)), ("Save", "icon-16px-solid/save.svg", Some(16)), ("SelectAll", "icon-16px-solid/select-all.svg", Some(16)), ("SelectParent", "icon-16px-solid/select-parent.svg", Some(16)), ("Settings", "icon-16px-solid/settings.svg", Some(16)), ("SmallDot", "icon-16px-solid/small-dot.svg", Some(16)), ("Stack", "icon-16px-solid/stack.svg", Some(16)), ("StackBottom", "icon-16px-solid/stack-bottom.svg", Some(16)), ("StackHollow", "icon-16px-solid/stack-hollow.svg", Some(16)), ("StackLower", "icon-16px-solid/stack-lower.svg", Some(16)), ("StackRaise", "icon-16px-solid/stack-raise.svg", Some(16)), ("StackReverse", "icon-16px-solid/stack-reverse.svg", Some(16)), ("StrokeAlignCenter", "icon-16px-solid/stroke-align-center.svg", Some(16)), ("StrokeAlignInside", "icon-16px-solid/stroke-align-inside.svg", Some(16)), ("StrokeAlignOutside", "icon-16px-solid/stroke-align-outside.svg", Some(16)), ("StrokeCapButt", "icon-16px-solid/stroke-cap-butt.svg", Some(16)), ("StrokeCapRound", "icon-16px-solid/stroke-cap-round.svg", Some(16)), ("StrokeCapSquare", "icon-16px-solid/stroke-cap-square.svg", Some(16)), ("StrokeJoinBevel", "icon-16px-solid/stroke-join-bevel.svg", Some(16)), ("StrokeJoinMiter", "icon-16px-solid/stroke-join-miter.svg", Some(16)), ("StrokeJoinRound", "icon-16px-solid/stroke-join-round.svg", Some(16)), ("StrokeOrderAbove", "icon-16px-solid/stroke-order-above.svg", Some(16)), ("StrokeOrderBelow", "icon-16px-solid/stroke-order-below.svg", Some(16)), ("TextAlignCenter", "icon-16px-solid/text-align-center.svg", Some(16)), ("TextAlignLeft", "icon-16px-solid/text-align-left.svg", Some(16)), ("TextAlignRight", "icon-16px-solid/text-align-right.svg", Some(16)), ("TextAlignSpineAway", "icon-16px-solid/text-align-spine-away.svg", Some(16)), ("TextAlignSpineTowards", "icon-16px-solid/text-align-spine-towards.svg", Some(16)), ("TextJustifyAll", "icon-16px-solid/text-justify-all.svg", Some(16)), ("TextJustifyCenter", "icon-16px-solid/text-justify-center.svg", Some(16)), ("TextJustifyLeft", "icon-16px-solid/text-justify-left.svg", Some(16)), ("TextJustifyRight", "icon-16px-solid/text-justify-right.svg", Some(16)), ("Tilt", "icon-16px-solid/tilt.svg", Some(16)), ("TiltReset", "icon-16px-solid/tilt-reset.svg", Some(16)), ("TransformationGrab", "icon-16px-solid/transformation-grab.svg", Some(16)), ("TransformationRotate", "icon-16px-solid/transformation-rotate.svg", Some(16)), ("TransformationScale", "icon-16px-solid/transformation-scale.svg", Some(16)), ("Trash", "icon-16px-solid/trash.svg", Some(16)), ("TurnNegative90", "icon-16px-solid/turn-negative-90.svg", Some(16)), ("TurnPositive90", "icon-16px-solid/turn-positive-90.svg", Some(16)), ("UserManual", "icon-16px-solid/user-manual.svg", Some(16)), ("ViewportDesignMode", "icon-16px-solid/viewport-design-mode.svg", Some(16)), ("ViewportGuideMode", "icon-16px-solid/viewport-guide-mode.svg", Some(16)), ("ViewportSelectMode", "icon-16px-solid/viewport-select-mode.svg", Some(16)), ("Volunteer", "icon-16px-solid/volunteer.svg", Some(16)), ("Website", "icon-16px-solid/website.svg", Some(16)), ("WorkingColorsPrimary", "icon-16px-solid/working-colors-primary.svg", Some(16)), ("WorkingColorsSecondary", "icon-16px-solid/working-colors-secondary.svg", Some(16)), ("Zoom1x", "icon-16px-solid/zoom-1x.svg", Some(16)), ("Zoom2x", "icon-16px-solid/zoom-2x.svg", Some(16)), ("ZoomIn", "icon-16px-solid/zoom-in.svg", Some(16)), ("ZoomOut", "icon-16px-solid/zoom-out.svg", Some(16)), ("ZoomReset", "icon-16px-solid/zoom-reset.svg", Some(16)), ("MouseHintDrag", "icon-16px-two-tone/mouse-hint-drag.svg", Some(16)), ("MouseHintLmb", "icon-16px-two-tone/mouse-hint-lmb.svg", Some(16)), ("MouseHintLmbDouble", "icon-16px-two-tone/mouse-hint-lmb-double.svg", Some(16)), ("MouseHintLmbDrag", "icon-16px-two-tone/mouse-hint-lmb-drag.svg", Some(16)), ("MouseHintMmb", "icon-16px-two-tone/mouse-hint-mmb.svg", Some(16)), ("MouseHintMmbDrag", "icon-16px-two-tone/mouse-hint-mmb-drag.svg", Some(16)), ("MouseHintNone", "icon-16px-two-tone/mouse-hint-none.svg", Some(16)), ("MouseHintRmb", "icon-16px-two-tone/mouse-hint-rmb.svg", Some(16)), ("MouseHintRmbDouble", "icon-16px-two-tone/mouse-hint-rmb-double.svg", Some(16)), ("MouseHintRmbDrag", "icon-16px-two-tone/mouse-hint-rmb-drag.svg", Some(16)), ("MouseHintScrollDown", "icon-16px-two-tone/mouse-hint-scroll-down.svg", Some(16)), ("MouseHintScrollUp", "icon-16px-two-tone/mouse-hint-scroll-up.svg", Some(16)), ("GeneralArtboardTool", "icon-24px-two-tone/general-artboard-tool.svg", Some(24)), ("GeneralEyedropperTool", "icon-24px-two-tone/general-eyedropper-tool.svg", Some(24)), ("GeneralFillTool", "icon-24px-two-tone/general-fill-tool.svg", Some(24)), ("GeneralGradientTool", "icon-24px-two-tone/general-gradient-tool.svg", Some(24)), ("GeneralNavigateTool", "icon-24px-two-tone/general-navigate-tool.svg", Some(24)), ("GeneralSelectTool", "icon-24px-two-tone/general-select-tool.svg", Some(24)), ("RasterBrushTool", "icon-24px-two-tone/raster-brush-tool.svg", Some(24)), ("RasterCloneTool", "icon-24px-two-tone/raster-clone-tool.svg", Some(24)), ("RasterDetailTool", "icon-24px-two-tone/raster-detail-tool.svg", Some(24)), ("RasterHealTool", "icon-24px-two-tone/raster-heal-tool.svg", Some(24)), ("RasterPatchTool", "icon-24px-two-tone/raster-patch-tool.svg", Some(24)), ("RasterRelightTool", "icon-24px-two-tone/raster-relight-tool.svg", Some(24)), ("VectorEllipseTool", "icon-24px-two-tone/vector-ellipse-tool.svg", Some(24)), ("VectorFreehandTool", "icon-24px-two-tone/vector-freehand-tool.svg", Some(24)), ("VectorLineTool", "icon-24px-two-tone/vector-line-tool.svg", Some(24)), ("VectorPathTool", "icon-24px-two-tone/vector-path-tool.svg", Some(24)), ("VectorPenTool", "icon-24px-two-tone/vector-pen-tool.svg", Some(24)), ("VectorPolygonTool", "icon-24px-two-tone/vector-polygon-tool.svg", Some(24)), ("VectorRectangleTool", "icon-24px-two-tone/vector-rectangle-tool.svg", Some(24)), ("VectorSplineTool", "icon-24px-two-tone/vector-spline-tool.svg", Some(24)), ("VectorTextTool", "icon-24px-two-tone/vector-text-tool.svg", Some(24)), ];