diff --git a/lib/measureText.js b/lib/measureText.js index c0a8426..520342f 100644 --- a/lib/measureText.js +++ b/lib/measureText.js @@ -2,6 +2,7 @@ var FontFace = require('./FontFace'); var FontUtils = require('./FontUtils'); +var LineBreaker = require('linebreak'); var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); @@ -13,10 +14,6 @@ var _zeroMetrics = { lines: [] }; -function splitText (text) { - return text.split(' '); -} - function getCacheKey (text, width, fontFace, fontSize, lineHeight) { return text + width + fontFace.id + fontSize + lineHeight; } @@ -49,6 +46,9 @@ module.exports = function measureText (text, width, fontFace, fontSize, lineHeig var words; var tryLine; var currentLine; + var breaker; + var bk; + var lastBreak; ctx.font = fontFace.attributes.style + ' ' + fontFace.attributes.weight + ' ' + fontSize + 'px ' + fontFace.family; textMetrics = ctx.measureText(text); @@ -63,27 +63,31 @@ module.exports = function measureText (text, width, fontFace, fontSize, lineHeig } else { // Break into multiple lines. measuredSize.width = width; - words = splitText(text); currentLine = ''; - - // This needs to be optimized! - while (words.length) { - tryLine = currentLine + words[0] + ' '; + breaker = new LineBreaker(text); + + while (bk = breaker.nextBreak()) { + var word = text.slice(lastBreak ? lastBreak.position : 0, bk.position); + + tryLine = currentLine + word; textMetrics = ctx.measureText(tryLine); - if (textMetrics.width > width) { + if (textMetrics.width > width || (lastBreak && lastBreak.required)) { measuredSize.height += lineHeight; measuredSize.lines.push({width: lastMeasuredWidth, text: currentLine.trim()}); - currentLine = words[0] + ' '; + currentLine = word; lastMeasuredWidth = ctx.measureText(currentLine.trim()).width; } else { currentLine = tryLine; lastMeasuredWidth = textMetrics.width; } - if (words.length === 1) { - textMetrics = ctx.measureText(currentLine.trim()); - measuredSize.lines.push({width: textMetrics.width, text: currentLine.trim()}); - } - words.shift(); + + lastBreak = bk; + } + + currentLine = currentLine.trim(); + if (currentLine.length > 0) { + textMetrics = ctx.measureText(currentLine); + measuredSize.lines.push({width: textMetrics, text: currentLine}); } } diff --git a/package.json b/package.json index 7d67544..c538186 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "url": "https://github.com/Flipboard/react-canvas/issues" }, "devDependencies": { + "brfs": "^1.4.0", "del": "^1.1.1", "envify": "^3.2.0", "gulp": "^3.8.10", @@ -37,6 +38,7 @@ "react": "^0.13.0" }, "dependencies": { + "linebreak": "^0.3.0", "scroller": "git://github.com/mjohnston/scroller" } } diff --git a/webpack.config.js b/webpack.config.js index b82ceef..00231d6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -16,6 +16,9 @@ module.exports = { module: { loaders: [ { test: /\.js$/, loader: 'jsx-loader!transform/cacheable?envify' }, + ], + postLoaders: [ + { loader: "transform?brfs" } ] },