summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc
blob: 0446cfb67346326455880e6d620a6f29d26612eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.h"

#include "third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/platform/fonts/font_metrics.h"

namespace blink {

int NGTextDecorationOffset::ComputeUnderlineOffsetForUnder(
    float text_decoration_thickness,
    FontVerticalPositionType position_type) const {
  LayoutUnit offset = LayoutUnit::Max();
  const ComputedStyle& style = text_fragment_.Style();
  FontBaseline baseline_type = style.GetFontBaseline();

  if (decorating_box_) {
    // TODO(eae): Replace with actual baseline once available.
    NGBaselineRequest baseline_request = {
        NGBaselineAlgorithmType::kAtomicInline,
        FontBaseline::kIdeographicBaseline};

    if (base::Optional<LayoutUnit> baseline =
            decorating_box_->Baseline(baseline_request))
      offset = baseline.value();
  }

  if (offset == LayoutUnit::Max()) {
    // TODO(layout-dev): How do we compute the baseline offset with a
    // decorating_box?
    const SimpleFontData* font_data = style.GetFont().PrimaryFont();
    if (!font_data)
      return 0;
    offset = font_data->GetFontMetrics().Ascent(baseline_type) -
             font_data->VerticalPosition(position_type, baseline_type);
  }

  // Compute offset to the farthest position of the decorating box.
  // TODO(layout-dev): This does not take farthest offset within the decorating
  // box into account, only the position within this text fragment.
  int offset_int = offset.Floor();

  // Gaps are not needed for TextTop because it generally has internal
  // leadings.
  if (position_type == FontVerticalPositionType::TextTop)
    return offset_int;
  return !IsLineOverSide(position_type) ? offset_int + 1 : offset_int - 1;
}

}  // namespace blink