我有一个蓝色容器,它是我文本的画布。我正在尝试做的是调整字体大小,以便整个文本尽可能多地填充蓝色容器。
我可以访问文本内容的高度,这是段落和它们之间的行。另外,我有蓝色容器的高度,每行的高度,行数和单词数。
我尝试使用线条的高度,基于默认字体大小,使用线条数量来确定我需要增加多少字体,以便填充蓝色容器。然而,这样做也会改变线条数量,破坏我成功的机会,同时让我的头脑游泳。
我应该使用什么公式,以便字体大小填充蓝色容器?
这是我的数字:
Content height: 342.46
Content/Container Width: 400
Font Size: 11
Line Height: 11 * 1.2 //120% of the font size gives the line height
Number of Lines: 24
Number of Words: 2055
此外,文本内容可能很长并且可以延伸到容器之外,因此理想情况下,增加或减少字体大小的公式(或建议)是我想要实现的目标。 / p>
alt text http://www.freeimagehosting.net/uploads/c1a4f77c5f.jpg
答案 0 :(得分:1)
如果您可以使用固定宽度的字体,事情会变得简单得多。然后像:字距调整,不同的字符宽度等因素消失。
假设您不能 - 或者不会 - 使用等宽字体,那么问题看起来很像重复浏览器所做的渲染 - 或打印机驱动程序的“打印预览”功能。您可以调查这种方法。
一个应该足够好的快速而肮脏的方案可能是:
在文本末尾添加<span id="CanYouSeeMe">.</span>
。
测量相对于容器高度(SpanOffset
)的跨度偏移量(ContainerHeight
)。
将字体大小(FS
)设置为:FS *= ContainerHeight / SpanOffset;
衡量新的SpanOffset
。
如果SpanOffset
仍然小于ContainerHeight
,请在循环中增加FS
一个微小的增量,直到SpanOffset
离开容器,然后备份1增量。
同样,如果SpanOffset
超出ContainerHeight
,请在循环中减少FS
一个微小的增量,直到SpanOffset
进入容器。
答案 1 :(得分:1)
我认为这个问题没有一个完美的解决方案。
基本上,每行和段落末尾的“浪费”空间量很大程度上取决于所讨论的文本。字符宽度和字距调整导致平均微小差异(但在最坏的情况下主要差异)。
所以你必须通过一些启发式方法。如果可能,请让软件“猜测”字体大小,测试文本是否适合(如何完成取决于您使用的是哪种语言/ API),如果不合适,请稍微向上或向下调整。
这是一种可能的启发式方法:
#numBreaks is the number of line breaks in the text
#numChars is the number of chars (excluding breaks) in the text
#avgCharWidth and lineHeight (pixels) are derived from font size
#avgWrapWidth is the width of the container minus a bit to
#account for the wasted space on the right. I would suggest:
#avgWrapWidth = realWidth - avgCharWidth * 6
totalLength = numChars * avgCharWidth
numLines = totalLength / avgWrapWidth + numBreaks
textHeight = numLines * lineHeight
textHeight是文本在包装到容器时应采用的高度(以像素为单位)。您可以通过二进制搜索字体大小来找到具有最佳估计高度的字体。
答案 2 :(得分:1)
这实际上是一个相当困难的问题,因为线条在字边界处断裂并且字长变化,实际上字符大小也是如此。另外,您可以拥有任意数量的显式换行符。所以要正确地做到这一点需要考虑到文本的许多细节,而且一般的分析解决方案将会非常复杂。
(在“真实”排版中,还有一些技巧用于通过调整字母和单词间距来调整布局,以便在保持良好外观的同时适应一切,但我们肯定不会去进入那里。)
但是,让我们放下准确性,而是考虑一个简化的模型,它可能会帮助你进入正确的球场。
可用区域为width * height
。鉴于给定length
的一段文字,我们希望确定合适的fontsize
,以使文字的包裹高度接近height
。
目前,我们只是掩盖单位的所有细节和文本内容的变幻莫测,并想象我们可以仅从length
和fontsize
计算文本的整体大小:< / p>
textWidth = A * fontsize * length
lineHeight = B * fontsize
其中A
和B
是一些缩放常量。 (B
应该很容易计算,实际上你有1.2。A
有点棘手,取决于你选择如何衡量length
,例如字符数或数字或者你。但是你这样做,A
只能是一个近似值,但是如果你处理的是合理数量的合理表现良好的文本,那么近似值可能非常好。)
然后文本占用的区域是:
textArea = A * fontsize * length * B * fontsize
= A * B * length * fontsize ^ 2
将此设置等于可用区域为字体大小提供了一个上限,即:
fontsize <= sqrt(width * height/(A * B * length))
显然,这会大大高估,因为它假定文本包完美,但它没有 - 在行的末尾和屏幕的底部会有区域丢失,即使没有明确的行休息。然而,很可能通过在我们的缩放常量A
中添加适当的软糖因子(即,通过提高我们的估计文本宽度以包括丢失的区域),我们可以获得足够好的fontsize
来进行随着。
我们可以通过考虑更多文本细节来使分析更加复杂。例如,如果计算文本中的硬换行符数,则可以将它们视为单独的,因为它们在不添加宽度的情况下添加高度。这会产生一个稍微复杂的二次方程,你需要quadratic formula才能解决一个简单的平方根。这是否值得,可能主要取决于您正在处理的文本中显式换行率的变化程度。
另外需要注意的是,您通常可以通过仅调整行间距来作弊,因为这样可以更改垂直跨度而不会冒任何文本重排的风险。你可能不希望大量这样做,因为它看起来很傻。但是如果你有正确的包装但是文字没有完全达到底部,那么当然值得考虑添加一点垂直填充。
答案 3 :(得分:1)
在TeX排版系统中,这个问题通常是通过一个简单的二分算法解决的(在TeXbook中由Knuth提供),这里是伪python:
def findsize:
maxsize=100pt
minsize=8pt
epsilon=0.5pt
while (maxsize-minsize>epsilon):
triedsize=(maxsize+minsize)/2
setfontsize(triedsize)
if boxisoverfull():
maxsize=triedsize
else:
minsize=triedsize
return minsize
请注意,如果不尝试每个尺寸,您可能无法做到这一点,因为每个浏览器都可能以不同的方式排版文本,制作不同的字间,间隔间距;通过使用用户设置的最小字体大小(我看到很多网页因为这个而显示不正确),使用连字(可能不是现在,但将来有可能)。
这里的问题是webbrowser可能会重新编写每次尝试,因此这可能会很慢。您可以通过使计算机时间框消失(f.e.display:none)来克服此问题。我记得我曾经这样做过,甚至在IE6中都有效。