+2014-11-18 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r176263 and r176273.
+ https://bugs.webkit.org/show_bug.cgi?id=138854
+
+ Underlines are hideous. (Requested by litherum on #webkit).
+
+ Reverted changesets:
+
+ "Use underlining metrics from the font file"
+ https://bugs.webkit.org/show_bug.cgi?id=138762
+ http://trac.webkit.org/changeset/176263
+
+ "iOS build fix."
+ http://trac.webkit.org/changeset/176273
+
2014-11-18 David Hyatt <hyatt@apple.com>
REGRESSION (r167210): Invalid cast in WebCore::RenderBlock::blockSelectionGaps
the text so that the underline should fill a box if the underline grows in proportion
to text size. The comparison is to a box that has its background color set.
<div style="position: relative; width: 600px; height: 600px; overflow: hidden;">
-<div style="font-family: Ahem; text-decoration: underline; font-size: 31000px; position: absolute; left: 0px; top: -28925px;"> </div>
+<div style="font-family: Ahem; text-decoration: underline; font-size: 10000px; position: absolute; left: 0px; top: -8350px;"> </div>
</div>
</body>
</html>
+2014-11-18 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r176263 and r176273.
+ https://bugs.webkit.org/show_bug.cgi?id=138854
+
+ Underlines are hideous. (Requested by litherum on #webkit).
+
+ Reverted changesets:
+
+ "Use underlining metrics from the font file"
+ https://bugs.webkit.org/show_bug.cgi?id=138762
+ http://trac.webkit.org/changeset/176263
+
+ "iOS build fix."
+ http://trac.webkit.org/changeset/176273
+
2014-11-18 Chris Dumez <cdumez@apple.com>
Add a setting to toggle DOMTimer throttling support
, m_lineSpacing(0)
, m_xHeight(0)
, m_zeroWidth(0)
- , m_decorationThickness(1)
- , m_underlinePosition(1)
, m_hasXHeight(false)
, m_hasZeroWidth(false)
{
bool hasZeroWidth() const { return m_hasZeroWidth; }
void setHasZeroWidth(bool hasZeroWidth) { m_hasZeroWidth = hasZeroWidth; }
- float decorationThickness() const { return m_decorationThickness; }
- void setDecorationThickness(float decorationThickness) { m_decorationThickness = decorationThickness; }
-
- float underlinePosition() const { return m_underlinePosition; }
- void setUnderlinePosition(float underlinePosition) { m_underlinePosition = underlinePosition; }
-
private:
friend class SimpleFontData;
float m_xHeight;
float m_capHeight;
float m_zeroWidth;
- float m_decorationThickness;
- float m_underlinePosition;
bool m_hasXHeight;
bool m_hasCapHeight;
bool m_hasZeroWidth;
return width;
}
-static inline void populateDecorationMetrics(float fontSize, float& decorationThickness, float& underlinePosition)
-{
- // Decoration underlines should be proportional to the font size
- decorationThickness = fontSize / 16.0f;
- // An amount to lower the underline below the baseline
- underlinePosition = std::max(1.0f, ceilf(decorationThickness / 2.0));
-}
-
} // namespace WebCore
SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SimpleFontData)
float descent = narrowPrecisionToFloat(fontExtents.descent);
float capHeight = narrowPrecisionToFloat(fontExtents.height);
float lineGap = narrowPrecisionToFloat(fontExtents.height - fontExtents.ascent - fontExtents.descent);
- float decorationThickness;
- float underlinePosition;
- populateDecorationMetrics(m_platformData.m_size, decorationThickness, underlinePosition);
m_fontMetrics.setAscent(ascent);
m_fontMetrics.setDescent(descent);
m_fontMetrics.setCapHeight(capHeight);
- m_fontMetrics.setDecorationThickness(decorationThickness);
- m_fontMetrics.setUnderlinePosition(underlinePosition);
#if PLATFORM(EFL)
m_fontMetrics.setLineSpacing(ascent + descent + lineGap);
float lineGap;
float lineSpacing;
float xHeight;
- float decorationThickness;
- float underlinePosition;
RetainPtr<CFStringRef> familyName;
if (CTFontRef ctFont = m_platformData.font()) {
FontServicesIOS fontService(ctFont);
lineSpacing = fontService.lineSpacing();
lineGap = fontService.lineGap();
xHeight = fontService.xHeight();
- decorationThickness = CTFontGetUnderlineThickness(ctFont);
- underlinePosition = -CTFontGetUnderlinePosition(ctFont);
capHeight = fontService.capHeight();
unitsPerEm = fontService.unitsPerEm();
familyName = adoptCF(CTFontCopyFamilyName(ctFont));
lineGap = lroundf(scaleEmToUnits(CGFontGetLeading(cgFont), unitsPerEm) * pointSize);
xHeight = scaleEmToUnits(CGFontGetXHeight(cgFont), unitsPerEm) * pointSize;
capHeight = scaleEmToUnits(CGFontGetCapHeight(cgFont), unitsPerEm) * pointSize;
- populateDecorationMetrics(m_platformData.size(), decorationThickness, underlinePosition);
lineSpacing = ascent + descent + lineGap;
familyName = adoptCF(CGFontCopyFamilyName(cgFont));
m_fontMetrics.setLineSpacing(lineSpacing);
m_fontMetrics.setXHeight(xHeight);
m_fontMetrics.setCapHeight(capHeight);
- m_fontMetrics.setDecorationThickness(decorationThickness);
- m_fontMetrics.setUnderlinePosition(underlinePosition);
m_shouldNotBeUsedForArabic = fontFamilyShouldNotBeUsedForArabic(familyName.get());
if (platformData().orientation() == Vertical && !isTextOrientationFallback())
float capHeight = scaleEmToUnits(iCapHeight, unitsPerEm) * pointSize;
float lineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
- float decorationThickness = CTFontGetUnderlineThickness(m_platformData.ctFont());
- float underlinePosition = -CTFontGetUnderlinePosition(m_platformData.ctFont());
// We need to adjust Times, Helvetica, and Courier to closely match the
// vertical metrics of their Microsoft counterparts that are the de facto
m_fontMetrics.setCapHeight(capHeight);
m_fontMetrics.setLineGap(lineGap);
m_fontMetrics.setXHeight(xHeight);
- m_fontMetrics.setDecorationThickness(decorationThickness);
- m_fontMetrics.setUnderlinePosition(underlinePosition);
}
static CFDataRef copyFontTableForTag(FontPlatformData& platformData, FourCharCode tableName)
float fDescent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
float fCapHeight = scaleEmToUnits(iCapHeight, unitsPerEm) * pointSize;
float fLineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
- float decorationThickness;
- float underlinePosition;
- populateDecorationMetrics(m_platformData.size(), decorationThickness, underlinePosition);
if (!isCustomFont()) {
HWndDC dc(0);
m_fontMetrics.setCapHeight(fCapHeight);
m_fontMetrics.setLineGap(fLineGap);
m_fontMetrics.setLineSpacing(lroundf(fAscent) + lroundf(fDescent) + lroundf(fLineGap));
- m_fontMetrics.setDecorationThickness(decorationThickness);
- m_fontMetrics.setUnderlinePosition(underlinePosition);
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
Glyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
float descent = textMetrics.tmDescent * metricsMultiplier;
float xHeight = ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts.
float lineGap = textMetrics.tmExternalLeading * metricsMultiplier;
- float decorationThickness;
- float underlinePosition;
- populateDecorationMetrics(m_platformData.size(), decorationThickness, underlinePosition);
int faceLength = ::GetTextFace(dc, 0, 0);
Vector<WCHAR> faceName(faceLength);
m_fontMetrics.setDescent(descent);
m_fontMetrics.setLineGap(lineGap);
m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
- m_fontMetrics.setDecorationThickness(decorationThickness);
- m_fontMetrics.setUnderlinePosition(underlinePosition);
m_avgCharWidth = textMetrics.tmAveCharWidth * metricsMultiplier;
m_maxCharWidth = textMetrics.tmMaxCharWidth * metricsMultiplier;
float ascent = textMetrics.tmAscent;
float descent = textMetrics.tmDescent;
float lineGap = textMetrics.tmExternalLeading;
- float decorationThickness;
- float underlinePosition;
- populateDecorationMetrics(m_platformData.size(), decorationThickness, underlinePosition);
m_fontMetrics.setAscent(ascent);
m_fontMetrics.setDescent(descent);
m_fontMetrics.setLineGap(lineGap);
m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
- m_fontMetrics.setDecorationThickness(decorationThickness);
- m_fontMetrics.setUnderlinePosition(underlinePosition);
m_avgCharWidth = textMetrics.tmAveCharWidth;
m_maxCharWidth = textMetrics.tmMaxCharWidth;
float xHeight = ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
// Use a special function for underlines to get the positioning exactly right.
bool isPrinting = renderer().document().printing();
- float textDecorationThickness = renderer().style().fontMetrics().decorationThickness();
+ float textDecorationThickness = textDecorationStrokeThickness(renderer().style().fontSize());
context.setStrokeThickness(textDecorationThickness);
bool linesAreOpaque = !isPrinting && (!(decoration & TextDecorationUnderline) || underline.alpha() == 255) && (!(decoration & TextDecorationOverline) || overline.alpha() == 255) && (!(decoration & TextDecorationLineThrough) || linethrough.alpha() == 255);
// These decorations should match the visual overflows computed in visualOverflowForDecorations()
if (decoration & TextDecorationUnderline) {
context.setStrokeColor(underline, colorSpace);
- const int underlineOffset = computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), this);
+ const int underlineOffset = computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), this, textDecorationThickness);
switch (decorationStyle) {
case TextDecorationStyleWavy: {
namespace WebCore {
-int computeUnderlineOffset(TextUnderlinePosition underlinePosition, const FontMetrics& fontMetrics, InlineTextBox* inlineTextBox)
+int computeUnderlineOffset(TextUnderlinePosition underlinePosition, const FontMetrics& fontMetrics, InlineTextBox* inlineTextBox, int textDecorationThickness)
{
// This represents the gap between the baseline and the closest edge of the underline.
- float gap = fontMetrics.underlinePosition();
+ int gap = std::max<int>(1, ceilf(textDecorationThickness / 2.0));
// According to the specification TextUnderlinePositionAuto should default to 'alphabetic' for horizontal text
// and to 'under Left' for vertical text (e.g. japanese). We support only horizontal text for now.
if (decoration == TextDecorationNone)
return GlyphOverflow();
- float strokeThickness = lineStyle.fontMetrics().decorationThickness();
+ float strokeThickness = textDecorationStrokeThickness(lineStyle.fontSize());
float controlPointDistance;
float step;
float wavyOffset;
// These metrics must match where underlines get drawn.
if (decoration & TextDecorationUnderline) {
- float underlineOffset = computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), inlineTextBox);
+ float underlineOffset = computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), inlineTextBox, strokeThickness);
if (decorationStyle == TextDecorationStyleWavy) {
extendIntToFloat(overflowResult.bottom, underlineOffset + wavyOffset + controlPointDistance + strokeThickness - height);
extendIntToFloat(overflowResult.top, -(underlineOffset + wavyOffset - controlPointDistance - strokeThickness));
class InlineTextBox;
+inline float textDecorationStrokeThickness(float fontSize)
+{
+ const float textDecorationBaseFontSize = 16;
+ return fontSize / textDecorationBaseFontSize;
+}
+
inline float wavyOffsetFromDecoration()
{
return 2;
GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, InlineTextBox*);
void getWavyStrokeParameters(float strokeThickness, float& controlPointDistance, float& step);
-int computeUnderlineOffset(TextUnderlinePosition, const FontMetrics&, InlineTextBox*);
+int computeUnderlineOffset(TextUnderlinePosition, const FontMetrics&, InlineTextBox*, int textDecorationThickness);
}
float ascent = svgFontFaceElement->ascent() * scale;
float descent = svgFontFaceElement->descent() * scale;
float lineGap = 0.1f * fontSize;
- float decorationThickness;
- float underlinePosition;
- populateDecorationMetrics(fontSize, decorationThickness, underlinePosition);
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(fontData, 0)->page();
fontMetrics.setLineGap(lineGap);
fontMetrics.setLineSpacing(roundf(ascent) + roundf(descent) + roundf(lineGap));
fontMetrics.setXHeight(xHeight);
- fontMetrics.setDecorationThickness(decorationThickness);
- fontMetrics.setUnderlinePosition(underlinePosition);
if (!glyphPageZero) {
fontData->setSpaceGlyph(0);