Javascript 手动渲染SVG图示符

Javascript 手动渲染SVG图示符,javascript,html,svg,fonts,svg.js,Javascript,Html,Svg,Fonts,Svg.js,我目前正在实现一个简单的SVG文本渲染器。我正在从SVG文件中提取需要绘制的字符的路径信息 以下是存储在JSON对象中的字体/字符的所有适当信息: window.font = { horizAdvX: 487, unitsPerEm: 2048, ascent: 1638, descent: -410, glyphs: { H: { horizAdvX

我目前正在实现一个简单的SVG文本渲染器。我正在从SVG文件中提取需要绘制的字符的路径信息

以下是存储在JSON对象中的字体/字符的所有适当信息:

     window.font = {
        horizAdvX: 487,
        unitsPerEm: 2048,
        ascent: 1638,
        descent: -410,
        glyphs: {
            H: {
                horizAdvX: 1382,
                path: 'M147 14q64 133 244 604q-68 29 -90 80q19 14 135 37l27 66q85 217 115 327.5t81 391.5q81 -14 153 -73t126 -147q-8 -11 -17.5 -26t-22 -38.5t-23 -43.5t-27 -55.5t-27 -58.5l-31.5 -69t-32 -71t-35.5 -80.5t-36.5 -81.5q282 39 488 51q77 223 157.5 399.5t136.5 235.5 q42 -3 124.5 -47.5t101.5 -79.5q-69 -65 -143 -210.5t-140 -336.5q41 -38 41 -92q0 -39 -16 -71q-28 4 -76 8q-69 -219 -111.5 -425t-42.5 -319q0 -33 4 -53q-41 2 -65 15t-31 28.5t-18 32t-27 22.5q-26 9 -44.5 74.5t-18.5 110.5q0 160 104 510q-75 -5 -255 -24.5 t-253 -20.5q-166 -392 -231 -750q-73 18 -126 62.5t-98 117.5z'
            },
            u: {
                horizAdvX: 1011,
                path: 'M174 119q0 98 16 174q43 181 146 386.5t221 291.5q44 0 99 -16t83 -48q-18 -19 -51 -68t-93 -161t-116 -244q-24 -55 -55 -162.5t-31 -156.5q0 -22 15 -37q29 11 73.5 62.5t134.5 174.5q6 9 36 49t47 64t42.5 63t44 75.5t31.5 70.5q19 51 33 84.5t49.5 91.5t77.5 98 q53 0 114 -20.5t80 -44.5q-28 -68 -104.5 -220.5t-115 -259.5t-38.5 -204q0 -51 11.5 -92t22.5 -64.5t11 -32.5q0 -3 -2 -5t-4 -2l-2 -1q-28 0 -88 24t-106 56q-35 29 -50.5 76t-15.5 90q0 44 10 74q-10 1 -52.5 -51t-95.5 -123t-67 -88q-57 -61 -88 -64q-70 3 -138.5 47.5 t-84.5 112.5z'
            },
            // rest of chars ...
使用优秀的库,我成功地在渲染过程中实现了这一点:

  • 使用路径信息&
    SVG.path
    方法绘制字符
  • 将固定高度应用于角色
  • 获取角色路径的边界框
  • 变换坐标系,使y点向下(SVG字体中的坐标系为“倒置”)
  • 使用上一个字符的宽度作为偏移量绘制下一个字符
  • 重复
  • 这确实可以绘制文本。您可以在这个JSFIDLE上看到这一点:

    问题是所有的东西都是一样的高度,和完全一样的距离。我需要知道如何使用SVG字体文件中的属性
    horiz-adv-x
    每个em的单位数
    等来获得正确的水平和垂直定位

    起初它看起来很简单,
    horiz-adv-x
    只是一个用于字体大小的缩放值,所以在水平偏移量上使用它,嘿!但不,这样做的结果是这样的:

    我需要弄清楚的是horizAdvX和其他类似值的组合如何用于计算水平前进和垂直定位。我已经通读了规范,但是它对我来说没有什么意义


    如果有人能帮我,那就太好了

    诀窍是,相应地缩放图示符,然后将其移动到正确的位置。我刚刚为svg.js重新设计了一个字体,它也从svg字体中提取了字形

    我这样说:

    var glyphs = 'My Text'
      , uPerEm = faceElement.getAttribute('units-per-em')
      , h = fontElement.getAttribute('horiz-adv-x')
      , x = 0
      , scale = fontsize / uPerEm
    
    
    for(var i = 0, len = glyphs.length; i < len; ++i){
    
      // check if there is kerning for this and the letter before
      // hkern specifies if the 2 letter move together because of to much space(example: Ya)
      if(glyphs[i-1]){
        hkern = this.source.querySelector('hkern[u1="'+glyphs[i-1]+'"][u2="'+glyphs[i]+'"]')
        if(hkern){
          // substract the value from our current x position
          x -= parseFloat(hkern.getAttribute('k')) * scale
        }
      }
    
      // create a new path array with the d-attribute
      // in cache, all my loaded glyphs are saved
      var p = new SVG.PathArray(cache[glyphs[i]].d)
        , box = p.bbox()
    
      // scale AND mirror the glyph (note the minus)
      if(box.height && box.width)
        p.size(box.width * scale, -box.height * scale)
    
      // move the glyph to its position
      p.move(x,(uPerEm - box.y - box.height)*scale)
    
      // draw the path
      yourSvgRoot.path(p)
    
      // add up the horiz-adv-x from the glyph or the horiz-adv-x from the font-node if no horiz-adv-x is present
      x += parseFloat(cache[glyphs[i]]['horiz-adv-x'] || h) * scale;
    
    }
    
    var glyphs='My Text'
    ,uPerEm=faceElement.getAttribute('units-per-em')
    ,h=fontElement.getAttribute('horiz-adv-x')
    ,x=0
    ,比例=字体大小/uPerEm
    对于(变量i=0,len=glyphs.length;i
    大部分代码。我试图添加注释以帮助理解。
    基本上,我循环我的字形和大小,并根据scalefactor定位它们。我现在不知道
    flip()
    会对路径造成什么影响,但我很确定这会有一些问题。最好是计算新的路径点,这是
    size()
    自动为您做的。

    感谢您回答这个问题,尽管它有点古老:D,经过大量的尝试和错误,我最终解决了这个问题…我仍然在使用svgjs,所以我将检查您的插件