float CanvasRenderingContext2D::getFontBaseline( const FontMetrics& fontMetrics) const { // If the font is so tiny that the lroundf operations result in two // different types of text baselines to return the same baseline, use // floating point metrics (crbug.com/338908). // If you changed the heuristic here, for consistency please also change it // in SimpleFontData::platformInit(). bool useFloatAscentDescent = fontMetrics.ascent() < 3 || fontMetrics.height() < 2; switch (state().getTextBaseline()) { case TopTextBaseline: return useFloatAscentDescent ? fontMetrics.floatAscent() : fontMetrics.ascent(); case HangingTextBaseline: // According to // http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling // "FOP (Formatting Objects Processor) puts the hanging baseline at 80% of // the ascender height" return useFloatAscentDescent ? (fontMetrics.floatAscent() * 4.0) / 5.0 : (fontMetrics.ascent() * 4) / 5; case BottomTextBaseline: case IdeographicTextBaseline: return useFloatAscentDescent ? -fontMetrics.floatDescent() : -fontMetrics.descent(); case MiddleTextBaseline: return useFloatAscentDescent ? -fontMetrics.floatDescent() + fontMetrics.floatHeight() / 2.0 : -fontMetrics.descent() + fontMetrics.height() / 2; case AlphabeticTextBaseline: default: // Do nothing. break; } return 0; }
static inline float positionOffsetForDecoration(TextDecoration decoration, const FontMetrics& fontMetrics, float thickness) { // FIXME: For SVG Fonts we need to use the attributes defined in the <font-face> if specified. // Compatible with Batik/Opera. if (decoration == TextDecorationUnderline) return fontMetrics.floatAscent() + thickness * 1.5f; if (decoration == TextDecorationOverline) return thickness; if (decoration == TextDecorationLineThrough) return fontMetrics.floatAscent() * 5 / 8.0f; ASSERT_NOT_REACHED(); return 0.0f; }