这是一个很长的镜头,但有没有人知道根据其内容估算和分类文本宽度(对于可变宽度字体)的算法?
例如,我想知道 iiiiiiii 并不像 abcdefgh 那么宽,而 abcdefgh 又不如 WWWWWWWW 那么宽>,即使所有三个字符串的长度都是八个字符。
这实际上是尝试将一些智能构建到字符串截断方法中,该方法目前正在截断视觉上宽的字符串,但也不必要地截断视觉上狭窄的字符串,因为两个字符串包含相同数量的字符。算法可能足以将输入字符串分类为 narrow , normal 或 wide ,然后根据需要进行截断。
这个问题并不是特定于语言的,但如果有算法,那么我将用Java实现它。这适用于Web应用程序。我知道SO上有答案可以解决这个问题,使用JavaScript来获取包含div
元素的宽度,但我想知道服务器端解决方案是否可行。
答案 0 :(得分:15)
大多数GUI框架提供了一些计算给定输出设备上字体的文本度量的方法。
例如,使用java.awt.FontMetrics
,我相信你可以这样做:
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
public int measureText(Graphics g, String text) {
g.setFont(new Font("TimesRoman", Font.PLAIN, 12));
FontMetrics metrics = g.getFontMetrics();
return metrics.stringWidth(text);
}
未经测试,但您明白了。
在.Net下,您可以使用Graphics.MeasureString
方法。在C#中:
private void MeasureStringMin(PaintEventArgs e)
{
// Set up string.
string measureString = "Measure String";
Font stringFont = new Font("Arial", 16);
// Measure string.
SizeF stringSize = new SizeF();
stringSize = e.Graphics.MeasureString(measureString, stringFont);
// Draw rectangle representing size of string.
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);
// Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0));
}
答案 1 :(得分:5)
这对我有用:
AffineTransform af = new AffineTransform();
FontRenderContext fr = new FontRenderContext(af,true,true);
Font f = new Font("Arial", 0, 10); // use exact font
double width= f.getStringBounds("my string", fr).getWidth();
答案 2 :(得分:2)
对于Web应用程序,您无法(真正)获得正确的估算。不同的字体具有不同的宽度,因此这不仅取决于客户端(浏览器)及其缩放和DPI设置,还取决于该计算机(和操作系统)上存在的字体或其替换。
如果您需要精确测量,请创建一个图形(位图,SVG,甚至某些PDF或其他),这些图形将在服务器上而不是在客户端上进行布局和渲染。
答案 3 :(得分:2)
没有可靠的服务器端解决方案来计算文本宽度。(在创建文本图像和SVG之外)
如果你尝试使用像browser-shots这样的工具并在相对基本的页面上运行它,你会立即明白原因。很难预测即使最平凡的例子会变得多么广泛,更不用说如果用户决定放大浏览器等......
没有准确地说明你可能想要截断字符串(它可能有助于提供潜在的解决方案),但常见的是因为你想在某个点切断文本并提供一个椭圆。
This can be done reliably on many browser platforms by using a css property, and NO javascript:
http://www.jide.fr/emulate-text-overflowellipsis-in-firefox-with-css
答案 4 :(得分:2)
您真的无法知道客户端使用的浏览器,字体设置,屏幕大小等。 (好的,有时请求标头提供了指示,但实际上没有任何一致性或可靠性。)
所以,我会:
我通常发现这个“足够好”,例如,用于估算某些文本在浏览器上占用的行数,以便估计文本旁边显示的广告数量。
如果它对您真的非常重要,那么我可以想象一个复杂的方案,您最初向客户端发送一些Javascript,然后进行测量并将其发送回您的服务器,然后您将此信息用于将来该客户的页面。但我无法想象它通常值得付出努力。
答案 5 :(得分:1)
我认为您应该选择以下解决方案之一:
当然可能会有一些混合估计,但我认为这是在错误的方向上付出太多努力。
答案 6 :(得分:1)
这实际上是尝试将一些智能构建成字符串截断方法[...]
真的值得努力吗?我们遇到了这个问题。这是跨语言的。修复是保持原样。保持这种智能的复杂性随着您添加支持的每种语言而迅速(并且可能呈指数级)增加。因此我们的决定。
[...]根据内容估算和分类文本宽度(可变宽度字体)的算法?
大多数字体库都会为您提供此信息。但这是相当低级的东西。基本思想是传入一个字符串并以磅为单位返回宽度。
答案 7 :(得分:1)
对于一个不错的*客户端解决方案,您可以尝试RichieHindle's answer to my question建议的混合CSS和Javascript方法。
鉴于您不知道用户将看到该页面的字体(它们总是可以覆盖您的选择,Ctrl- +页面等),在浏览器上执行此操作的“正确”位置。虽然浏览器不容易!
*
当我说“好”时,我的意思是“可能很好但我还没有尝试过”。