xps 之Positioning Content
1. RenderTransform and Transform
-
RenderTransform 和 Transform指定一个矩阵,表示做表空间变换
-
该矩阵含6个元素,表示如下:
[xScale,sin Θ,-sin Θ,yScale,offsetX,offsetY]
-
xScale,yScale表示尺度变化,offsetX,offsetY表示偏移
-
glyphs节点的每个字符的坐标信息计算时,其坐标值由canvasRenderTransformMatrix和glyphRenderTransformMatrix共同决定
1.1 canvasRenderTransformMatrix计算
def extractGlyphs(glyphs,dstPageDic):
global order
canvasRenderTransformMatrix = [1,0,0,1,0,0]
glyphsParent = glyphs.getparent()
if 'Canvas' in glyphsParent.tag:
attribDic = glyphsParent.attrib
if attribDic.has_key('RenderTransform'):
canvasRenderTransformMatrix = [float(item) for item in attribDic['RenderTransform'].split(',')]
- 即父节点含'Canvas'标签,且有RenderTransform属性,则用父节点的RenderTransform值,否则为[1 0 0 1 0 0]
1.2 glyphRenderTransformMatrix计算
glyphRenderTransformMatrix = [float(item) for item in attribDic['RenderTransform'].split(',')] if attribDic.has_key('RenderTransform') else [1,0,0,1,0,0]
- 即自身节点有RenderTransform属性,则用自身节点的RenderTransform值,不含RenderTransform属性,则为[1 0 0 1 0 0]
2. Indices
计算宽度占比用
Indices含义如下:
一个glyphs节点如下:
<Glyphs Fill="#ff000000"
FontUri="/Documents/1/Resources/Fonts/584FF68E-07BF-4D9B-954B-30DACA51E97E.odttf"
FontRenderingEmSize="12.0005"
StyleSimulations="None"
OriginX="58.88"
OriginY="73.28"
Indices="5627;2047;29"
UnicodeString="性别:" />
其中,OriginX,OriginY为首字符左下角的原始坐标系的x,y,需要转化到变换后的坐标系,计算思路如下:
2.1 对于该节点的第一个字符:性
- 如果其len(indices) == 1:即只有一个索引,
x = canvasRenderTransformMatrix[0]*(glyphRenderTransformMatrix[0]*OriginX+glyphRenderTransformMatrix[4])+canvasRenderTransformMatrix[4]
y = canvasRenderTransformMatrix[3]*(glyphRenderTransformMatrix[3]*OriginY+glyphRenderTransformMatrix[5])+canvasRenderTransformMatrix[5]
w = w * glyphRenderTransformMatrix[0] * (50 if ord(UnicodeString[i].decode()) >=32 and ord(UnicodeString[i].decode())<=126 else 100)/100
h = h * glyphRenderTransformMatrix[3]
-
多个索引的时候,w,h的计算分别要考虑宽度百分比
-
x,y为变换后的起始点坐标,w,h,为字宽
2.2 对于后边的字符,需要通过计算前边所有字符的宽度之和来计算当前字的x,y,w,h: 别:
其中前边字符宽度和算法为:
widthSum = widthSum + float(( IndicesList[j].split(',')[1] if len(IndicesList[j].split(','))>1 else (50 if ord(UnicodeString[j].decode()) >=32 and ord(UnicodeString[j].decode())<=126 else 100) ))
其中,每个字符宽算法为:
float(( IndicesList[j].split(',')[1] if len(IndicesList[j].split(','))>1 else (50 if ord(UnicodeString[j].decode()) >=32 and ord(UnicodeString[j].decode())<=126 else 100) ))
即:
- 若果只有一个索引,则看当前字符是全角还是半角,全角宽占比100,半角50
- 若有多个索引,则用indiceList[1],即宽度
然后需要通过宽度百分比和FontRenderingEmSize算出前边字符宽之和,以得到当前的x,y,w,h,其中,w,h的算法要看indices的长度而定
如:
widthSum = widthSum/100 * FontRenderingEmSize
if len(indices) == 1:
x = canvasRenderTransformMatrix[0]*(glyphRenderTransformMatrix[0]*(OriginX+widthSum)+glyphRenderTransformMatrix[4])+canvasRenderTransformMatrix[4]
y = canvasRenderTransformMatrix[3]*(glyphRenderTransformMatrix[3]*OriginY+glyphRenderTransformMatrix[5])+canvasRenderTransformMatrix[5]
。。。
elif len(indices) == 4:
x = canvasRenderTransformMatrix[0]*(glyphRenderTransformMatrix[0]*(OriginX+FontRenderingEmSize*float(indices[2])/100)+glyphRenderTransformMatrix[4])+canvasRenderTransformMatrix[4]
y = canvasRenderTransformMatrix[3]*(glyphRenderTransformMatrix[3]*(OriginY-FontRenderingEmSize*float(indices[3])/100)+glyphRenderTransformMatrix[5])+canvasRenderTransformMatrix[5] #加上voffset
w = w * glyphRenderTransformMatrix[0] * float(indices[1])/100
h = h * glyphRenderTransformMatrix[3]
aw = float(indices[1])
- 其中len(indices) == 4的为即有偏移又有宽度比的情况
小结
有了这些,我们就可一提取到每个字符的坐标信息了, 今儿为后续进展作准备。