BloggerAds廣告

相關文章

2017年4月13日 星期四

createjs TextField CJK text wrapping support

The TextField of official createjs supports only very basic text wrapping. It sucks when the content is CJK characters like Chinese, Korean & Japanese.

Here you are the workaround:

find the private method p._drawText in createjs (or easeljs for non combinded) and replace with the following code
this code has been well tested with one of my projects for half year

/**
  * Draws multiline text.
  * @method _drawText
  * @param {CanvasRenderingContext2D} ctx
  * @param {Object} o
  * @param {Array} lines
  * @return {Object}
  * @protected
  **/
 p._drawText = function(ctx, o, lines) {
  var paint = !!ctx;
  if (!paint) {
   ctx = Text._workingContext;
   ctx.save();
   this._prepContext(ctx);
  }
  var lineHeight = this.lineHeight || this.getMeasuredLineHeight();

  var maxW = 0,
   count = 0;
  var hardLines = String(this.text).split(/(?:\r\n|\r|\n)/);
  for (var i = 0, l = hardLines.length; i < l; i++) {
   var str = hardLines[i];
   var w = null;

   if (this.lineWidth != null && (w = ctx.measureText(str).width) > this.lineWidth) {
    // text wrapping:
    // hanyeah CJK wrapping
    var words0;
    var words;
    if ((/[\u4e00-\u9fa5]+/).test(str)) { //contains CJK characters
     words0 = str.split(/(\s)/);
     words = [];
     for (var hi = 0; hi < words0.length; hi++) {
      var hs = "";
      for (var hj = 0; hj < words0[hi].length; hj++) {
       var hjs = words0[hi][hj];
       if (hjs.charCodeAt(0) > 255) {
        if (hs != "") {
         words.push(hs);
        }
        words.push(hjs);
        hs = "";
       } else {
        hs += hjs;
       }
      }
      if (hs != "") {
       words.push(hs);
      }
     }
    } else {
     words = str.split(/(\s)/);
    }
    str = words[0];
    w = ctx.measureText(str).width;

    for (var j = 1, jl = words.length; j < jl; j += 1) {
     // Line needs to wrap:
     var wordW = ctx.measureText(words[j]).width;
     if (w + wordW > this.lineWidth) {
      if (paint) {
       this._drawTextLine(ctx, str, count * lineHeight);
      }
      if (lines) {
       lines.push(str);
      }
      if (w > maxW) {
       maxW = w;
      }
      str = words[j];
      w = ctx.measureText(str).width;
      count++;
     } else {
      str += words[j];
      w += wordW;
     }
    }
   }
   //end hanyeah CJK wrapping
   if (paint) {
    this._drawTextLine(ctx, str, count * lineHeight);
   }
   if (lines) {
    lines.push(str);
   }
   if (o && w == null) {
    w = ctx.measureText(str).width;
   }
   if (w > maxW) {
    maxW = w;
   }
   count++;
  }

  if (o) {
   o.width = maxW;
   o.height = count * lineHeight;
  }
  if (!paint) {
   ctx.restore();
  }
  return o;
 };