15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/**
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *           (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTextControl.h"
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLTextFormControlElement.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/HitTestResult.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTheme.h"
28c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/rendering/TextRunConstructor.h"
29a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/scroll/ScrollbarTheme.h"
3002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/unicode/CharacterNames.h"
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
32c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
34521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)RenderTextControl::RenderTextControl(HTMLTextFormControlElement* element)
358abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    : RenderBlockFlow(element)
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
37521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    ASSERT(element);
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderTextControl::~RenderTextControl()
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLTextFormControlElement* RenderTextControl::textFormControlElement() const
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return toHTMLTextFormControlElement(node());
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)HTMLElement* RenderTextControl::innerEditorElement() const
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    return textFormControlElement()->innerEditorElement();
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
54c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)void RenderTextControl::addChild(RenderObject* newChild, RenderObject* beforeChild)
55c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){
56c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // FIXME: This is a terrible hack to get the caret over the placeholder text since it'll
57c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // make us paint the placeholder first. (See https://trac.webkit.org/changeset/118733)
58c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    Node* node = newChild->node();
5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (node && node->isElementNode() && toElement(node)->shadowPseudoId() == "-webkit-input-placeholder")
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        RenderBlockFlow::addChild(newChild, firstChild());
61c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    else
6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        RenderBlockFlow::addChild(newChild, beforeChild);
63c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
64c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RenderBlockFlow::styleDidChange(diff, oldStyle);
6876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    Element* innerEditor = innerEditorElement();
6976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (!innerEditor)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
7176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    RenderBlock* innerEditorRenderer = toRenderBlock(innerEditor->renderer());
7276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (innerEditorRenderer) {
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We may have set the width and the height in the old style in layout().
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Reset them now to avoid getting a spurious layout hint.
7576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        innerEditorRenderer->style()->setHeight(Length());
7676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        innerEditorRenderer->style()->setWidth(Length());
7776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        innerEditorRenderer->setStyle(createInnerEditorStyle(style()));
7876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        innerEditor->setNeedsStyleRecalc(SubtreeStyleChange);
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    textFormControlElement()->updatePlaceholderVisibility(false);
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
83521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)static inline void updateUserModifyProperty(HTMLTextFormControlElement* node, RenderStyle* style)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
85521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    style->setUserModify(node->isDisabledOrReadOnly() ? READ_ONLY : READ_WRITE_PLAINTEXT_ONLY);
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)void RenderTextControl::adjustInnerEditorStyle(RenderStyle* textBlockStyle) const
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The inner block, if present, always has its direction set to LTR,
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // so we need to inherit the direction and unicode-bidi style from the element.
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    textBlockStyle->setDirection(style()->direction());
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    textBlockStyle->setUnicodeBidi(style()->unicodeBidi());
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
95521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    updateUserModifyProperty(textFormControlElement(), textBlockStyle);
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)int RenderTextControl::textBlockLogicalHeight() const
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return logicalHeight() - borderAndPaddingLogicalHeight();
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)int RenderTextControl::textBlockLogicalWidth() const
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    Element* innerEditor = innerEditorElement();
10676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    ASSERT(innerEditor);
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    LayoutUnit unitWidth = logicalWidth() - borderAndPaddingLogicalWidth();
10976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (innerEditor->renderer())
11076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        unitWidth -= innerEditor->renderBox()->paddingStart() + innerEditor->renderBox()->paddingEnd();
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return unitWidth;
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTextControl::updateFromElement()
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    Element* innerEditor = innerEditorElement();
11876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (innerEditor && innerEditor->renderer())
11976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        updateUserModifyProperty(textFormControlElement(), innerEditor->renderer()->style());
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderTextControl::scrollbarThickness() const
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: We should get the size of the scrollbar from the RenderTheme instead.
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return ScrollbarTheme::theme()->scrollbarThickness();
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTextControl::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    HTMLElement* innerEditor = innerEditorElement();
13176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    ASSERT(innerEditor);
13276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (RenderBox* innerEditorBox = innerEditor->renderBox()) {
13376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        LayoutUnit nonContentHeight = innerEditorBox->borderAndPaddingHeight() + innerEditorBox->marginHeight();
13476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        logicalHeight = computeControlLogicalHeight(innerEditorBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight);
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
13776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        if ((isHorizontalWritingMode() && (style()->overflowX() == OSCROLL ||  (style()->overflowX() == OAUTO && innerEditor->renderer()->style()->overflowWrap() == NormalOverflowWrap)))
13876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)            || (!isHorizontalWritingMode() && (style()->overflowY() == OSCROLL ||  (style()->overflowY() == OAUTO && innerEditor->renderer()->style()->overflowWrap() == NormalOverflowWrap))))
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            logicalHeight += scrollbarThickness();
14010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch
14110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        // FIXME: The logical height of the inner text box should have been added before calling computeLogicalHeight to
14210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        // avoid this hack.
14310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        updateIntrinsicContentLogicalHeight(logicalHeight);
14410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch
14510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        logicalHeight += borderAndPaddingHeight();
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)void RenderTextControl::hitInnerEditorElement(HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset)
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    HTMLElement* innerEditor = innerEditorElement();
15476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (!innerEditor->renderer())
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutPoint adjustedLocation = accumulatedOffset + location();
15876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    LayoutPoint localPoint = pointInContainer - toLayoutSize(adjustedLocation + innerEditor->renderBox()->location());
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasOverflowClip())
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        localPoint += scrolledContentOffset();
16176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    result.setInnerNode(innerEditor);
16276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    result.setInnerNonSharedNode(innerEditor);
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result.setLocalPoint(localPoint);
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
166f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char* const fontFamiliesWithInvalidCharWidth[] = {
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "American Typewriter",
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Arial Hebrew",
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Chalkboard",
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Cochin",
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Corsiva Hebrew",
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Courier",
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Euphemia UCAS",
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Geneva",
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Gill Sans",
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Hei",
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Helvetica",
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Hoefler Text",
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "InaiMathi",
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Kai",
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Lucida Grande",
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Marker Felt",
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Monaco",
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Mshtakan",
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "New Peninim MT",
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Osaka",
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Raanana",
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "STHeiti",
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Symbol",
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Times",
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Apple Braille",
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Apple LiGothic",
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Apple LiSung",
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "Apple Symbols",
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "AppleGothic",
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "AppleMyungjo",
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "#GungSeo",
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "#HeadLineA",
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "#PCMyungjo",
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    "#PilGi",
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// For font families where any of the fonts don't have a valid entry in the OS/2 table
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// for avgCharWidth, fallback to the legacy webkit behavior of getting the avgCharWidth
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// from the width of a '0'. This only seems to apply to a fixed number of Mac fonts,
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// but, in order to get similar rendering across platforms, we do this check for
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// all platforms.
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderTextControl::hasValidAvgCharWidth(AtomicString family)
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static HashSet<AtomicString>* fontFamiliesWithInvalidCharWidthMap = 0;
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (family.isEmpty())
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!fontFamiliesWithInvalidCharWidthMap) {
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fontFamiliesWithInvalidCharWidthMap = new HashSet<AtomicString>;
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t i = 0; i < WTF_ARRAY_LENGTH(fontFamiliesWithInvalidCharWidth); ++i)
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fontFamiliesWithInvalidCharWidthMap->add(AtomicString(fontFamiliesWithInvalidCharWidth[i]));
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return !fontFamiliesWithInvalidCharWidthMap->contains(family);
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderTextControl::getAvgCharWidth(AtomicString family)
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasValidAvgCharWidth(family))
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return roundf(style()->font().primaryFont()->avgCharWidth());
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const UChar ch = '0';
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const String str = String(&ch, 1);
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Font& font = style()->font();
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TextRun textRun = constructTextRun(this, font, str, style(), TextRun::AllowTrailingExpansion);
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return font.width(textRun);
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float RenderTextControl::scaleEmToUnits(int x) const
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This matches the unitsPerEm value for MS Shell Dlg and Courier New from the "head" font table.
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float unitsPerEm = 2048.0f;
24109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return roundf(style()->font().fontDescription().computedSize() * x / unitsPerEm);
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
244926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RenderTextControl::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
246926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Use average character width. Matches IE.
24709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    AtomicString family = style()->font().fontDescription().family().family();
248926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    maxLogicalWidth = preferredContentLogicalWidth(const_cast<RenderTextControl*>(this)->getAvgCharWidth(family));
24976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (RenderBox* innerEditorRenderBox = innerEditorElement()->renderBox())
25076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        maxLogicalWidth += innerEditorRenderBox->paddingStart() + innerEditorRenderBox->paddingEnd();
251926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!style()->logicalWidth().isPercent())
252926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        minLogicalWidth = maxLogicalWidth;
253926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTextControl::computePreferredLogicalWidths()
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(preferredLogicalWidthsDirty());
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_minPreferredLogicalWidth = 0;
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_maxPreferredLogicalWidth = 0;
26110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    RenderStyle* styleToUse = style();
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
26310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (styleToUse->logicalWidth().isFixed() && styleToUse->logicalWidth().value() >= 0)
26410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalWidth().value());
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
266926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
267926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
26810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
269197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
270197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (styleToUse->logicalMaxWidth().isFixed()) {
274197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
275197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
278926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    LayoutUnit toAdd = borderAndPaddingLogicalWidth();
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_minPreferredLogicalWidth += toAdd;
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_maxPreferredLogicalWidth += toAdd;
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
283c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    clearPreferredLogicalWidthsDirty();
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RenderTextControl::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*) const
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!size().isEmpty())
2897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        rects.append(LayoutRect(additionalOffset, size()));
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
292e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)RenderObject* RenderTextControl::layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope& layoutScope)
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
294926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    HTMLElement* placeholder = toHTMLTextFormControlElement(node())->placeholderElement();
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* placeholderRenderer = placeholder ? placeholder->renderer() : 0;
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!placeholderRenderer)
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
298e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (relayoutChildren)
299e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        layoutScope.setChildNeedsLayout(placeholderRenderer);
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return placeholderRenderer;
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
303c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
304