3

現在、単純な 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.jsライブラリを使用して、レンダリング プロセスをここまで進めることができました。

  1. パス情報とSVG.pathメソッドを使用してキャラクターを描く
  2. キャラクターに固定高さを適用する
  3. 文字パスのバウンディング ボックスを取得する
  4. y が下向きになるように座標系を変換します (SVG フォントの座標系は「上下逆」です)
  5. 前の文字の幅をオフセットとして使用して次の文字を描画します
  6. 繰り返す

これはテキストを描画します。このjsfiddleでこれが機能しているのを見ることができます:

http://jsfiddle.net/dormisher/KVs7E/2/

問題は、すべてが同じ高さで、まったく同じ距離にあるということです。正しい水平方向と垂直方向の位置を取得するために、SVG フォント ファイルにある属性などhoriz-adv-xを使用する方法を知る必要があります。unites-per-em

最初は単純に見えますが、horiz-adv-xこれは単にフォント サイズに使用されるスケーリング値であるため、それを水平オフセットに使用してください。しかし、いいえ、それを行うと、次のようになります。

http://jsfiddle.net/dormisher/KVs7E/3/

私が理解する必要があるのは、horizAdvX と残りの類似値の組み合わせを使用して、水平方向の前進と垂直方向の位置決めを行う方法です。私はW3C仕様を読みましたが、この点に関してはほとんど意味がありません。

誰かが私を助けることができれば素晴らしいです!

4

1 に答える 1

3

トリックは、それに応じてグリフをスケーリングしてから、正しい位置に移動することです。svg-font からもグリフを取得する svg.js 用のテキストモーフィング拡張機能を実現しました。

私はこのように行きました:

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;

}

コードの多く。理解を助けるためにコメントを追加しようとしました。基本的に、グリフとサイズをループし、スケール ファクターに従って配置します。がパスに対して何をするかはわかりflip()ませんが、それにはいくつかの問題があると確信しています。自動的に実行している新しいパス ポイントを計算するsize()ことをお勧めします。

于 2015-10-23T01:25:01.587 に答える