如何将SVG变换矩阵应用于文本字号?(Inkscape inkex场景)
如何将SVG变换矩阵应用到文本字号
我有一个带transform属性的SVG文本元素,需要将该变换应用到文本上。已通过将矩阵应用于坐标,成功得到元素正确变换后的x、y值,但无法将矩阵应用于单一值(即文本字号)。尝试将字号作为两个参数传入变换,但结果不正确。
使用的是Inkscape的inkex.transform模块中的apply_to_point函数。
补充代码片段:
selections = self.svg.selection for s in selections: transStr = s.get('transform') if(transStr is not None): tr = inkex.transform.Transform(transStr) x = s.get('x') y = s.get('y') if(x is not None and y is not None): # apply transform to coordinates co = tr.apply_to_point((x, y)) s.pop('transform') s.set('x', str(co[0])) s.set('y', str(co[1])) stStr = s.get('style') if(stStr is not None): style = inkex.styles.Style.parse_str(stStr) sizeStr = style.get('font-size') if(sizeStr is not None): m = re.match('([0-9.]+)(.*)', sizeStr) if(len(m.groups()) > 1): size = m[1] # apply transform to size # but this returns a tuple of 2 # we need only one. # And even taking one element from tuple # this doesn't work. style['font-size'] = str(tr.apply_to_point((size, size))) s.set('style', style)
解决方案
apply_to_point是用来变换坐标点的,不能直接用来计算字号的缩放。要正确将变换矩阵的缩放效果应用到文本字号,需要提取变换矩阵中的缩放因子,再用该因子乘以原始字号。
SVG变换矩阵的结构为[a, b, c, d, e, f],其中:
- x方向的缩放因子:
scale_x = √(a² + c²) - y方向的缩放因子:
scale_y = √(b² + d²)
对于水平文本,font-size控制的是文本的em高度,对应y方向的缩放,因此使用scale_y计算新字号即可;如果是均匀缩放,scale_x和scale_y数值相同,用任意一个均可。
修改后的代码
import re import math from inkex.transform import Transform from inkex.styles import Style selections = self.svg.selection for s in selections: transStr = s.get('transform') if transStr is not None: tr = Transform(transStr) x = s.get('x') y = s.get('y') if x is not None and y is not None: # 应用变换到坐标 co = tr.apply_to_point((x, y)) s.pop('transform') s.set('x', str(co[0])) s.set('y', str(co[1])) stStr = s.get('style') if stStr is not None: style = Style.parse_str(stStr) sizeStr = style.get('font-size') if sizeStr is not None: m = re.match(r'([0-9.]+)(.*)', sizeStr) if m and len(m.groups()) > 1: size_num = float(m[1]) unit = m[2] # 计算y方向的缩放因子(对应文本高度) scale_y = math.sqrt(tr.b ** 2 + tr.d ** 2) # 计算新字号 new_size = size_num * scale_y # 更新样式中的字号 style['font-size'] = f"{new_size}{unit}" s.set('style', style)
内容的提问来源于stack exchange,提问作者Loma Harshana
相关产品推荐
相关产品推荐

