charSpace issue

by Steve Eberhardt

HTML

<script src="https://rawgit.com/fabricjs/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="300"></canvas>
<div>
  <div>
    <input type="text" id="textInput" value="" placeholder="Enter text here">
  </div>
  <div>
    <span>Start Offset: </span>
    <input type="range" id="startOffsetInput" step="1" min="-50" max="50">
    <h2 id="offsetAmount">0</h2>
  </div>
  <div>
    <span>Character Spacing: </span>
    <input type="range" id="charSpacingInput" step="1" min="-100" max="200">
    <h2 id="spacingAmount">0</h2>
  </div>
  <div>
    <span>Font Size: </span>
    <input type="range" id="fontSizeInput" step="1" min="10" max="100">
    <h2 id="fontSize">0</h2>
  </div>
  <div>
    <span>Text Align: </span>
    <button onclick="setProp('textAlign','left')">
      Left
    </button>
    <button onclick="setProp('textAlign','center')">
      Center
    </button>
    <button onclick="setProp('textAlign','right')">
      Right
    </button>
  </div>
  <div>
    <span>Side: </span>
    <button onclick="setProp('side','left')">
      Left
    </button>
    <button onclick="setProp('side','right')">
      Right
    </button>
  </div>
</div>

CSS

canvas {
    border: 1px solid #999;
}

div > * {
  display: inline-block;
}

h2 {
  width: 30px;
  margin: 0 20px 0 0;
}

div > div {
  display: block;
  padding: 4px;
}

input {
  margin-top: 10px;
}

JavaScript

var canvas = new fabric.Canvas('c');

var pathStringEllipse = "M 50 0 a 50 100 0 1 1 1 0 Z";
var path = new fabric.Path(pathStringEllipse, {
  	strokeWidth: 2,
  	stroke: 'red',
    left: 100,
    top: 50,
    fill: 'transparent',
    scaleX: 1,
    strokeUniform: true
  });
  
var text = new fabric.Text('............', {
  path: path,
  fontSize: 80,
  left: 100,
  top: 50,
  textAlign: 'center',
  charSpacing: 200,
  padding: 20,
  pathStartOffset: 0,
  pathSide: "left"
});

canvas.add(path);
canvas.add(text);

document.getElementById('pathStartOffsetInput').addEventListener("input", function() {
		setProp('pathStartOffset', parseInt(this.value));
    document.getElementById('offsetAmount').innerHTML = this.value;
});

document.getElementById('charSpacingInput').addEventListener("input", function() {
		setProp('charSpacing', parseInt(this.value));
    document.getElementById('spacingAmount').innerHTML = this.value;
});

document.getElementById('fontSizeInput').addEventListener("input", function() {
		setProp('fontSize', parseInt(this.value));
    document.getElementById('fontSize').innerHTML = this.value;
});

document.getElementById('textInput').addEventListener("input", function() {
		setProp('text', this.value);
});

function setProp(prop, value) {
    var objects = canvas.getObjects();
    objects.forEach(function(obj) {
    	obj.set(prop, value);
      canvas.renderAll();
    });
}
  
  fabric.Text.prototype._measureLine = function(lineIndex) {
      var width = 0, i, grapheme, line = this._textLines[lineIndex], prevGrapheme,
          graphemeInfo, numOfSpaces = 0, lineBounds = new Array(line.length),
          positionInPath = 0, startingPoint, totalPathLength, path = this.path,
          reverse = this.pathSide === 'right';

      this.__charBounds[lineIndex] = lineBounds;
      for (i = 0; i < line.length; i++) {
        grapheme = line[i];
        graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);
        lineBounds[i] =...