【发布时间】:2015-02-21 06:26:16
【问题描述】:
我需要一个简单的换行算法,所以我求助于维基百科:
http://en.wikipedia.org/wiki/Line_wrap_and_word_wrap#Minimum_number_of_lines
贪心算法:
1. | SpaceLeft := 线宽 2. |对于文本中的每个单词 3. | if (Width(Word) + SpaceWidth) > SpaceLeft 4. |在文本中的 Word 之前插入换行符 5. | SpaceLeft := LineWidth - 宽度(字) 6. |别的 7. | SpaceLeft := SpaceLeft - (Width(Word) + SpaceWidth)在第5行,当我们开始一个新行并从可用宽度中减去单词宽度时,我们不应该也减去空格宽度吗?
5. | SpaceLeft := LineWidth - (Width(Word) + SpaceWidth)为什么第 5 行没有考虑空间宽度?
-- 更新--
一些简单的测试。
在每张图片中,第一段由 JavaScript 使用上述环绕算法创建(橙色轮廓),第二段由浏览器原生渲染(蓝色轮廓)。
有趣的是,这种极其简单的算法确实产生了与浏览器渲染完全相同的结果,对于没有边缘情况的文本。
第一张图片显示,当我们使用时
SpaceLeft := LineWidth - Width(Word)
JS渲染和浏览器渲染完全一样。
但是下图(不同的线宽)展示了我们使用时JS和浏览器渲染的细微差别:
SpaceLeft := LineWidth - (Width(Word) + SpaceWidth)
代码
// 函数 getWidth() 使用画布计算宽度 // http://stackoverflow.com/questions/118241/calculate-text-width-with-javascript var wrap = function(container, text, lineWidth) { var words = text.split(' '); 变量 w, x, i, l; var spaceWidth = getWidth(' '); var spaceLeft = lineWidth; var arr = [],行 = []; arr.push(line); for ( i = 0, l = words.length; i spaceLeft ) { 线 = []; arr.push(line); line.push(w); // 这是维基百科算法的情况 // spaceLeft = lineWidth - getWidth(w); spaceLeft = lineWidth - x; } 别的 { 左空间 = 左空间 - x; line.push(w); } } for ( i = 0, l = arr.length; i ').text(arr[i].join('')) ); } };【问题讨论】:
-
我很困惑为什么你甚至需要在第 5 行定义 spaceLeft。到那时似乎换行已经发生并且无关紧要。下次你运行循环时,它会被设置回默认的
SpaceLeft := LineWidth -
除非剩余空间对于每一行都是唯一的,在这种情况下,它们只减去宽度(单词)的原因是因为当你将单词分解到下一行时,剩余的空间量就是它已经减去刚刚删除的单词。
SpaceLeft-=Width(word) -
在第 4 行,我们插入一个换行符,然后在第 5 行我们开始一个新行。请注意,在单词之前插入了中断 - 并且单词被放置在新行上。空格不应该和这个词一起吗?因为在
else部分,我们总是用单词放置空格。 -
好的,我明白了。除非他们键入空格,否则我认为空格也不应该与它一起使用。
-
新行到目前为止只有你刚刚输入的单词,所以剩下的空间是该行的宽度减去单词的宽度。