svg · SVG 形状助手
svgwrite 形状助手。
为什么需要它
tkfluent 里原先每个组件都手写一遍圆角矩形的 SVG 拼装,几何写法各不相同, 并且普遍踩了同一个坑:
.. code-block:: python
dwg.rect((x1, y1), (x2 - x1, y2 - y1), rx, ry,
stroke="#000", stroke_width=1,
transform="translate(0.500000 0.500000)")
SVG 的描边是以路径为中心线向两侧各画半个线宽。上面这种写法把矩形放到
(0.5, 0.5)、尺寸仍然是整宽整高,于是矩形右边界正好落在 x = w + 0.5:
右边和下边的描边被整个推到画布之外,完全不可见——按钮看起来只有上边框和
左边框。frame / listbox 用的是不加 translate 的版本,四边各被削掉一半厚度。
正确做法是把几何向内收缩半个线宽,让描边的外沿正好贴合画布边缘。 栅格引擎(skia / pillow / cairo)本来就是这么算的,本模块让 SVG 引擎与之对齐。
add_roundrect(dwg, x1, y1, x2, y2, radius, radiusy=None, *, fill='transparent', fill_opacity=1, outline='black', outline2=None, outline_opacity=1, outline2_opacity=1, width=1, gradient=True, gradient_id='DButton.Border', gradient_stop1=0.9, gradient_stop2=1.0, **extra)
往 svgwrite 的 Drawing 里加一个四边描边都完整的圆角矩形。
:param dwg: svgwrite.Drawing 对象(:meth:tkdeft.windows.draw.DSvgDraw.create_drawing
返回的第二个元素;各组件的历史写法是 drawing[1])
:param fill: 填充色,"transparent" 表示不填充
:param fill_opacity: 填充透明度
:param outline: 描边色
:param outline2: 渐变描边的第二个颜色;为空则用纯色描边
:param outline_opacity: 描边透明度
:param outline2_opacity: 渐变描边第二个颜色的透明度
:param width: 描边宽度(描边以路径为中心线,几何会自动内缩半个线宽)
:param gradient: 允许使用渐变描边;置 False 可强制纯色
:param gradient_id: 渐变定义的 id
:param gradient_stop1: 第一个 stop 的位置(0-1)
:param gradient_stop2: 第二个 stop 的位置(0-1)
:param extra: 其余关键字直接透传给 rect()(例如 id=".Badge")
:returns: (insert, size, rx, ry)
源代码位于: tkdeft\svg.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
gradient_stop(color, opacity)
把渐变 stop 归一成 (颜色, 透明度)。
SVG 里没有 transparent 这个关键字,渐变要"淡出到透明"只能写成
「某个颜色 + stop-opacity="0"」,所以这里把"不绘制"翻译成
("#000000", 0.0);其余颜色原样返回。
:returns: (颜色, 透明度)
源代码位于: tkdeft\svg.py
56 57 58 59 60 61 62 63 64 65 66 67 | |
roundrect_geometry(x1, y1, x2, y2, radius, radiusy=None, stroke_width=1)
按"描边居中"规则把圆角矩形几何内缩。
对退化尺寸做了保护:控件在布局完成之前宽高可能是 0、1 甚至负数
(FluSlider 构造时 winfo_width() 就是 1)。SVG 里
width / height 一旦 <= 0,tksvg 会直接抛
couldn't recognize image data,所以这里把边长和内缩量都夹到安全范围。
返回:
| 类型 | 描述 |
|---|---|
Geometry
|
|
源代码位于: tkdeft\svg.py
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | |
svg_paint(value, default='none')
把"没有颜色"的写法统一成 svgwrite 认识的 "none"。
:param value: 颜色,可能是 None / "transparent" / "none" / 真颜色
:param default: 不绘制时返回什么(默认 "none")
:returns: 可直接交给 svgwrite 的取值
没有这一步时,同一份规格在两条路径上的行为并不一致——
RoundRectSpec(outline=None) 用 skia 渲染正常,换到 tksvg 就抛
TypeError;"transparent" 也一样。这里统一之后,
"描边 / 填充留空"的写法在五个引擎上都能跑。
源代码位于: tkdeft\svg.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |