zoukankan      html  css  js  c++  java
  • xps坐标计算

    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的为即有偏移又有宽度比的情况

    小结

    有了这些,我们就可一提取到每个字符的坐标信息了, 今儿为后续进展作准备。

  • 相关阅读:
    C# List<T>用法(转)
    任务列表 (Visual Studio)
    TSQL行转列、列转行
    HRESULT:0x80070057 (E_INVALIDARG)的异常的解决方案(转)
    JS正则表达式详解(转)
    Windows远程登录命令
    JavaScript中的try...catch和异常处理(转)
    javascript如何触发button 的click事件
    在ASP.NET中利JavaScript实现控件的聚焦(转)
    输入一个字符串,将其逆序后输出。(使用C++,不建议用伪码)
  • 原文地址:https://www.cnblogs.com/monkey-moon/p/9260642.html
Copyright © 2011-2022 走看看