Javascript 形状中的文本换行算法

Javascript 形状中的文本换行算法,javascript,algorithm,graphics,text,word-wrap,Javascript,Algorithm,Graphics,Text,Word Wrap,我正在寻找一种算法,将文本包装在非矩形形状内,最好是基于Knuth和Plass算法。其中最困难的部分是,由于文本中的字体大小不同,行可能具有不同的高度。下图是该算法应该能够生成的示例 对于一个简单的算法,让我们假设您可以计算每个单词周围的边界框,并且您有一个带有要填充形状的遮罩的图像 从图像遮罩的顶部向下扫掠,直到找到一条与第一个单词一样长的线。查看是否可以将其向下扩展为一个边框大小的矩形。如果是的话,把第一个字放在那里。如果没有,继续清扫 放置单词后,请查看是否可以将边界框扩展为(第一个框+第

我正在寻找一种算法,将文本包装在非矩形形状内,最好是基于Knuth和Plass算法。其中最困难的部分是,由于文本中的字体大小不同,行可能具有不同的高度。下图是该算法应该能够生成的示例


对于一个简单的算法,让我们假设您可以计算每个单词周围的边界框,并且您有一个带有要填充形状的遮罩的图像

从图像遮罩的顶部向下扫掠,直到找到一条与第一个单词一样长的线。查看是否可以将其向下扩展为一个边框大小的矩形。如果是的话,把第一个字放在那里。如果没有,继续清扫

放置单词后,请查看是否可以将边界框扩展为(第一个框+第二个框+空格)的宽度和最大值(第一个框,第二个框)的高度。如果是这样的话,把第二个词放在那里。如果没有,请将第一个单词从左到右居中放置在将适合图像遮罩的边界框内(从左到右),从遮罩中删除该边界框,然后继续

你可以通过坚持线条具有相同的基线,即使被形状打断(例如,穿过心脏顶部结节的线条),使这一点更为奇特;然后,您需要有一个备用的“沿此基线继续”条件。但是上面的基本思想,加上一个图像遮罩,你可以试着把矩形放在里面,当你完成的时候,这些矩形会被移除,这样就可以了


(使用几何运算比这里描述的基于像素的运算要快,但是我们必须考虑所有的情况,以确定边界框如何适合任意多边形,这里要解释的有点长。)

假设每个字母都有特定的大小(宽度和高度,在本例中,我们可能只关心宽度,因为所有字母的高度都相同)。然后我们需要以下内容:

  • 每个单词的包装对象-确保单词没有碎片
  • 给定每个单词的宽度
  • 将多边形分割成与单词高度相等的块,这样就有x个水平条组成图像
  • 然后,如果要在里面写单词,请找到里面多边形的宽度。这意味着您正在删除心脏的圆边。在条形图上,垂直线可以与心脏边缘相交的位置就是删除圆边的位置
  • 现在我们有了图像每个条带的大小,假设我们有这个(我使用任意单位表示宽度):

    编辑,更新

    试一试

    文本/html

    gggggggggggggg gggggggggggggg gggggggggggggggggggg gggggggggggggggggg gggggggggggggggggggggggg gggggggggggggggggggggg ggggggggggggggggggggggggggg ggggggggggggggggggggggggg ggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggg ggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggg ggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggg gggggggggggggggggggggggg gggggggggggggggggg gggggggggggg gggggggg ggggg ggg g

    var text="知识本身是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德美国。orci门悬吊,nec前庭。Morbi eleifend vel nib sed rutrum。Etiam feugiat,nunc et efficitur accumsan,quam magna lacinia neque,eu ullamcorper purus turpis eget urna。Etiam lacus mi,孕妇软腭,viverra sed ipsum。augue turpis Mauris in turpis。”
    + "设施无效。在侵权者的身上,有一个利奥·库苏斯(leo cursus),有一个索利西图(ligula sollicitudin)。毛里斯·康茂德(Mauris commodo)和智者(Mauris sapien id scelerisque)。整数和直径是侵权者的一部分或一部分。知识产权是一种权利,是一种权利。交通工具的直径是利奥里特(laoreet Tincident)。整数是指在侵权者身上的一个缺陷乌拉。维尼那提的胜利是不可告人的。维尼那提的胜利是兽人的胜利,是兽人的胜利,是兽人的胜利,是兽人的胜利,是兽人的胜利,是兽人的胜利。维尼那提的胜利是兽人的胜利,是兽人的胜利,是兽人的胜利这是一种伟大的行为,它是一种侵权行为,是一种犯罪,是一种犯罪。”
    + "前庭和后庭,矢状体或弓形体,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物,动物等这本书是一本关于基本知识的书,是一本关于汽车的书,是一本关于汽车的书,是一本关于汽车的书,是一本关于汽车的书,是一本关于汽车的书,是一本关于汽车的书,是一本关于汽车的书
    + "不,在爱神面前。在佩朗茨克的咒语中,欧盟的咒语是“爱的人”,在“爱的人”中是“爱的人”,在“爱的人”中是“爱的人”,在“高贵的人”中是“爱的人”,在“爱的人”中是“爱的人”,在“爱的人”中是“爱的人”,在“爱的人”中是“爱的人”,在“爱的人”中是“爱的人”我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我的朋友,我是埃吉斯塔斯国家图书馆的馆长,我是马萨的馆长。”
    + "馆长坐在阿梅特·马蒂斯·奥迪奥(amet mattis odio)的位子上。毛里斯·马蒂斯·图皮斯(Mauris mattis turpis)是一位杰出的专家,他是一位杰出的专家。毛里斯·弗林蒂亚(Mauris fringilla arcu)使用的是一辆出租汽车。他是一位来自世界各地的消费者,他是一位普通的消费者。他是一辆出租汽车和一辆出租汽车前十字节杖,后十字节杖,前庭节杖,前庭节杖,前酵素节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前十字节杖,前节杖,前节杖,前节杖,前节杖,前节杖
    
    considering we already have widths
    while(image.hasNextChunk()){
        currentChunk = image.nextChunk();
        if(currentWord.width < currentChunk.width) //insert here and then change currentWord to nextWord
        ...
    }
    
    gggggggggggggg gggggggggggggg gggggggggggggggggggg gggggggggggggggggg gggggggggggggggggggggggg gggggggggggggggggggggg ggggggggggggggggggggggggggg ggggggggggggggggggggggggg ggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggg ggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggg ggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggg gggggggggggggggggggggggg gggggggggggggggggg gggggggggggg gggggggg ggggg ggg g
    var text =  "Lorem ipsum dolor sit amet," // `string` , `array` 
    , i = -1
    , elem = document.querySelector("pre");
    elem.innerText = elem.innerText.replace(/[^\n|\r|\t|\s+]/g, function() {
                       return text[++i] 
                     });
    
            Lorem ipsum do              lor sit amet,  
         consectetur adipisci         ng elit. Vivamus b
       landit nisl eu posuere s     uscipit. Etiam at quam
      sed nulla consequat finibu   s et eget ligula. Nam sit
     amet imperdiet eros. Ut a congue nibh. Sed ac arcu non r
    isus commodo lobortis et at lorem. Pellentesque pulvinar v
    enenatis pellentesque. Praesent sed pulvinar justo. Ut nec
     turpis lectus. Suspendisse porta ipsum orci, nec vestibul
    um tellus luctus quis. Morbi eleifend vel nibh sed rutrum.
     Etiam feugiat, nunc et efficitur accumsan, quam magna lac
     inia neque, eu ullamcorper purus turpis eget urna. Etiam
       lacus mi, gravida vel mollis ut, viverra sed ipsum. M
       auris in augue turpis.Nulla facilisi. In tristique t
         ortor sit amet leo cursus, sit amet varius ligula
           sollicitudin. Mauris commodo et sapien id sce
            lerisque. Integer et diam eget arcu bibend
               um ornare a in tortor. Lorem ipsum do
                  lor sit amet, consectetur adip
                     iscing elit. Aliquam veh
                        icula diam ac laor
                           eet tincidun
                             t. Integ
                               er se
                                d t
                                 e