2010-01-05  Ojan Vafai  <ojan@chromium.org>

        Reviewed by Eric Seidel.

        Improve text control instrinsic widths.
        https://bugs.webkit.org/show_bug.cgi?id=25566
        https://bugs.webkit.org/show_bug.cgi?id=25581
        https://bugs.webkit.org/show_bug.cgi?id=25958

        Excluding list of updated results as the list is so long.
2010-01-05  Ojan Vafai  <ojan@chromium.org>

        Reviewed by Dan Bernstein.

        Improve text control intrinsic widths.
        https://bugs.webkit.org/show_bug.cgi?id=25566
        https://bugs.webkit.org/show_bug.cgi?id=25581
        https://bugs.webkit.org/show_bug.cgi?id=25958

        For Mac fonts that have invalid avgCharWidth entries in the OS/2 table,
        fallback to the Safari 4- behavior of using the width of a zero. For other
        fonts, make Mac match Windows (and thus IE) metrics.

        Lucida Grande is hard-coded to match MS Shell Dlg for inputs and
        Courier New for textareas in order to match Safari Win, Firefox and, in
        some cases IE (IE uses different default fonts depending on encoding).

        The only case where we still don't match Windows is if no font-size is
        set. The default font-size for form controls on the Mac is smaller and
        thus text-control widths will be slightly smaller.

        No new tests. Covered by existing tests.

        * platform/graphics/mac/SimpleFontDataMac.mm:
        (WebCore::SimpleFontData::platformCharWidthInit):
        * rendering/RenderTextControl.cpp:
        (WebCore::):
        (WebCore::RenderTextControl::hasValidAvgCharWidth):
        (WebCore::RenderTextControl::getAvgCharWidth):
        (WebCore::RenderTextControl::calcPrefWidths):
        * rendering/RenderTextControl.h:
        (WebCore::RenderTextControl::scaleEmToUnits):
        * rendering/RenderTextControlMultiLine.cpp:
        (WebCore::RenderTextControlMultiLine::getAvgCharWidth):
        * rendering/RenderTextControlMultiLine.h:
        * rendering/RenderTextControlSingleLine.cpp:
        (WebCore::RenderTextControlSingleLine::getAvgCharWidth):
        (WebCore::RenderTextControlSingleLine::preferredContentWidth):
        * rendering/RenderTextControlSingleLine.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54748 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index 1c83466..a762ac5 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -374,7 +374,19 @@
 
     return width;
 }
+    
+float RenderTextControlSingleLine::getAvgCharWidth(AtomicString family)
+{
+    // Since Lucida Grande is the default font, we want this to match the width
+    // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
+    // IE for some encodings (in IE, the default font is encoding specific).
+    // 901 is the avgCharWidth value in the OS/2 table for MS Shell Dlg.
+    if (family == AtomicString("Lucida Grande"))
+        return scaleEmToUnits(901);
 
+    return RenderTextControl::getAvgCharWidth(family);
+}
+    
 int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
 {
     int factor = inputElement()->size();
@@ -383,8 +395,20 @@
 
     int result = static_cast<int>(ceilf(charWidth * factor));
 
+    float maxCharWidth = 0.f;
+    AtomicString family = style()->font().family().family();
+    // Since Lucida Grande is the default font, we want this to match the width
+    // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
+    // IE for some encodings (in IE, the default font is encoding specific).
+    // 4027 is the (xMax - xMin) value in the "head" font table for MS Shell Dlg.
+    if (family == AtomicString("Lucida Grande"))
+        maxCharWidth = scaleEmToUnits(4027);
+    else if (hasValidAvgCharWidth(family))
+        maxCharWidth = roundf(style()->font().primaryFont()->maxCharWidth());
+
     // For text inputs, IE adds some extra width.
-    result += style()->font().primaryFont()->maxCharWidth() - charWidth;
+    if (maxCharWidth > 0.f)
+        result += maxCharWidth - charWidth;
 
     if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0)
         result += resultsRenderer->borderLeft() + resultsRenderer->borderRight() +