Index: third_party/WebKit/Source/platform/fonts/SimpleFontData.cpp |
diff --git a/third_party/WebKit/Source/platform/fonts/SimpleFontData.cpp b/third_party/WebKit/Source/platform/fonts/SimpleFontData.cpp |
index d3224097198037903690caeb0d420a23b89898bf..d422288b92e5dbaf61536c2e2d4a46c26725a51d 100644 |
--- a/third_party/WebKit/Source/platform/fonts/SimpleFontData.cpp |
+++ b/third_party/WebKit/Source/platform/fonts/SimpleFontData.cpp |
@@ -39,6 +39,7 @@ |
#include "platform/fonts/VDMXParser.h" |
#include "platform/fonts/skia/SkiaTextMetrics.h" |
#include "platform/geometry/FloatRect.h" |
+#include "platform/wtf/ByteOrder.h" |
#include "platform/wtf/MathExtras.h" |
#include "platform/wtf/PtrUtil.h" |
#include "platform/wtf/allocator/Partitions.h" |
@@ -379,6 +380,90 @@ PassRefPtr<SimpleFontData> SimpleFontData::CreateScaledFontData( |
IsCustomFont() ? CustomFontData::Create() : nullptr); |
} |
+// Internal leadings can be distributed to ascent and descent. |
+// ------------------------------------------- |
+// | - Internal Leading (in ascent) |
+// |-------------------------------- |
+// Ascent - | | |
+// | | |
+// | | - Em height |
+// ----------|--------------| |
+// | | |
+// Descent - |-------------------------------- |
+// | - Internal Leading (in descent) |
+// ------------------------------------------- |
+LayoutUnit SimpleFontData::EmHeightAscent(FontBaseline baseline_type) const { |
+ if (baseline_type == kAlphabeticBaseline) { |
+ if (!em_height_ascent_) |
+ ComputeEmHeightMetrics(); |
+ return em_height_ascent_; |
+ } |
+ LayoutUnit em_height = LayoutUnit::FromFloatRound(PlatformData().size()); |
+ return em_height - em_height / 2; |
+} |
+ |
+LayoutUnit SimpleFontData::EmHeightDescent(FontBaseline baseline_type) const { |
+ if (baseline_type == kAlphabeticBaseline) { |
+ if (!em_height_descent_) |
+ ComputeEmHeightMetrics(); |
+ return em_height_descent_; |
+ } |
+ LayoutUnit em_height = LayoutUnit::FromFloatRound(PlatformData().size()); |
+ return em_height / 2; |
+} |
+ |
+static std::pair<int16_t, int16_t> TypoAscenderAndDescender( |
+ SkTypeface* typeface) { |
+ // TODO(kojii): This should move to Skia once finalized. We can then move |
bungeman-chromium
2017/05/03 13:56:37
What is the reason for not using SkPaint::getFontM
|
+ // EmHeightAscender/Descender to FontMetrics. |
+ int16_t buffer[2]; |
+ size_t size = typeface->getTableData(SkSetFourByteTag('O', 'S', '/', '2'), 68, |
drott
2017/05/08 08:04:00
What's 68 here? Could you make a constant for this
kojii
2017/05/09 04:37:16
It's the offset. Skia has access to os2table so th
|
+ sizeof(buffer), buffer); |
+ if (size == sizeof(buffer)) { |
+ return std::make_pair(static_cast<int16_t>(ntohs(buffer[0])), |
+ -static_cast<int16_t>(ntohs(buffer[1]))); |
+ } |
+ return std::make_pair(0, 0); |
+} |
+ |
+void SimpleFontData::ComputeEmHeightMetrics() const { |
+ // Compute em height metrics from OS/2 sTypoAscender and sTypoDescender. |
+ SkTypeface* typeface = platform_data_.Typeface(); |
+ int16_t typo_ascender, typo_descender; |
+ std::tie(typo_ascender, typo_descender) = TypoAscenderAndDescender(typeface); |
+ if (typo_ascender > 0 && |
+ NormalizeEmHeightMetrics(typo_ascender, typo_ascender + typo_descender)) { |
+ return; |
+ } |
+ |
+ // As the last resort, compute em height metrics from our ascent/descent. |
+ const FontMetrics& font_metrics = GetFontMetrics(); |
+ if (NormalizeEmHeightMetrics(font_metrics.FloatAscent(), |
+ font_metrics.FloatHeight())) { |
+ return; |
+ } |
+ NOTREACHED(); |
+} |
+ |
+bool SimpleFontData::NormalizeEmHeightMetrics(float ascent, |
+ float height) const { |
+ if (height <= 0 || ascent < 0 || ascent > height) |
+ return false; |
+ // While the OpenType specification recommends the sum of sTypoAscender and |
+ // sTypoDescender to equal 1em, most fonts do not follow. Most Latin fonts |
+ // set to smaller than 1em, and many tall scripts set to larger than 1em. |
+ // https://www.microsoft.com/typography/otspec/recom.htm#OS2 |
+ // To ensure the sum of ascent and descent is the "em height", normalize by |
+ // keeping the ratio of sTypoAscender:sTypoDescender. |
+ // This matches to how Gecko computes "em height": |
drott
2017/05/08 08:04:00
Would be great if you had a Mozilla DXR link to wh
kojii
2017/05/09 04:37:16
Yeah, not great at reading Mozilla code yet...
|
+ // https://github.com/whatwg/html/issues/2470#issuecomment-291425136 |
+ float em_height = PlatformData().size(); |
+ em_height_ascent_ = LayoutUnit::FromFloatRound(ascent * em_height / height); |
+ em_height_descent_ = |
+ LayoutUnit::FromFloatRound(em_height) - em_height_ascent_; |
+ return true; |
+} |
+ |
FloatRect SimpleFontData::PlatformBoundsForGlyph(Glyph glyph) const { |
if (!platform_data_.size()) |
return FloatRect(); |