import QtQuick import QtQuick.Shapes import qs.Commons // One provider logo, drawn as a vector path and filled with whatever colour it // is handed - which is what lets these follow the theme the way a font glyph // would, instead of being a fixed-colour bitmap that looks pasted on. // // Every mark is authored in a 24x24 viewBox (see Modes.js) and scaled to the // requested size from there. // // Two things about how that scaling is done, both of which matter at bar sizes: // // 1. No `layer.enabled`. A layer renders the Shape into a texture at the item's // own size and then scales the *texture*, so a 24x24 buffer minified to 16px // resamples 1.5 pixels into 1. On the Claude burst, whose rays are under a // pixel wide at that size, that is not softening - rays merge, drop out, and // come back at uneven weights as the widget moves. Without the layer the // scale is a transform on the geometry instead, so rasterisation happens // once, at final resolution. // // 2. CurveRenderer rather than the default geometry renderer. It rasterises // curves analytically with its own antialiasing instead of tessellating them // into AA'd triangles, which is what keeps sub-pixel detail smooth rather // than stair-stepped. Qt 6.6+; this ships against 6.11. Item { id: root property string pathData: "" property real iconSize: Style.font.icon property color color: Color.foreground // Per-mark optical correction; see LOGO_SCALE in Modes.js for why equal // nominal size is not equal apparent size. property real opticalScale: 1.0 // Rounded so the mark is laid out on whole pixels. Thin strokes straddling a // pixel boundary lose half their coverage to each side and read as grey. readonly property int box: Math.round(iconSize) implicitWidth: box implicitHeight: box visible: pathData !== "" Shape { id: shape width: 24 height: 24 anchors.centerIn: parent antialiasing: true preferredRendererType: Shape.CurveRenderer scale: root.box * root.opticalScale / 24 ShapePath { // No fillRule set on purpose: these marks are authored for nonzero // winding, which is the default, and LM Studio's bars are knocked out // of its container by winding direction alone. fillColor: root.color strokeWidth: 0 PathSvg { path: root.pathData } } } }