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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Baseline.h"
#include "nsIFrame.h"
namespace mozilla {
nscoord Baseline::SynthesizeBOffsetFromMarginBox(const nsIFrame* aFrame,
WritingMode aWM,
BaselineSharingGroup aGroup) {
MOZ_ASSERT(!aWM.IsOrthogonalTo(aFrame->GetWritingMode()));
auto margin = aFrame->GetLogicalUsedMargin(aWM);
if (aGroup == BaselineSharingGroup::First) {
if (aWM.IsAlphabeticalBaseline()) {
// First baseline for inverted-line content is the block-start margin
// edge, as the frame is in effect "flipped" for alignment purposes.
return MOZ_UNLIKELY(aWM.IsLineInverted())
? -margin.BStart(aWM)
: aFrame->BSize(aWM) + margin.BEnd(aWM);
}
nscoord marginBoxCenter = (aFrame->BSize(aWM) + margin.BStartEnd(aWM)) / 2;
return marginBoxCenter - margin.BStart(aWM);
}
MOZ_ASSERT(aGroup == BaselineSharingGroup::Last);
if (aWM.IsAlphabeticalBaseline()) {
// Last baseline for inverted-line content is the block-start margin edge,
// as the frame is in effect "flipped" for alignment purposes.
return MOZ_UNLIKELY(aWM.IsLineInverted())
? aFrame->BSize(aWM) + margin.BStart(aWM)
: -margin.BEnd(aWM);
}
// Round up for central baseline offset, to be consistent with ::First.
nscoord marginBoxSize = aFrame->BSize(aWM) + margin.BStartEnd(aWM);
nscoord marginBoxCenter = (marginBoxSize / 2) + (marginBoxSize % 2);
return marginBoxCenter - margin.BEnd(aWM);
}
nscoord Baseline::SynthesizeBOffsetFromBorderBox(const nsIFrame* aFrame,
WritingMode aWM,
BaselineSharingGroup aGroup) {
nscoord borderBoxSize =
MOZ_UNLIKELY(aWM.IsOrthogonalTo(aFrame->GetWritingMode()))
? aFrame->ISize(aWM)
: aFrame->BSize(aWM);
if (aGroup == BaselineSharingGroup::First) {
return MOZ_LIKELY(aWM.IsAlphabeticalBaseline()) ? borderBoxSize
: borderBoxSize / 2;
}
MOZ_ASSERT(aGroup == BaselineSharingGroup::Last);
// Round up for central baseline offset, to be consistent with ::First.
auto borderBoxCenter = (borderBoxSize / 2) + (borderBoxSize % 2);
return MOZ_LIKELY(aWM.IsAlphabeticalBaseline()) ? 0 : borderBoxCenter;
}
nscoord Baseline::SynthesizeBOffsetFromContentBox(const nsIFrame* aFrame,
WritingMode aWM,
BaselineSharingGroup aGroup) {
WritingMode wm = aFrame->GetWritingMode();
MOZ_ASSERT(!aWM.IsOrthogonalTo(wm));
const auto bp = aFrame->GetLogicalUsedBorderAndPadding(wm)
.ApplySkipSides(aFrame->GetLogicalSkipSides())
.ConvertTo(aWM, wm);
if (MOZ_UNLIKELY(aWM.IsCentralBaseline())) {
nscoord contentBoxBSize = aFrame->BSize(aWM) - bp.BStartEnd(aWM);
if (aGroup == BaselineSharingGroup::First) {
return contentBoxBSize / 2 + bp.BStart(aWM);
}
// Return the same center position as for ::First, but as offset from end:
nscoord halfContentBoxBSize = (contentBoxBSize / 2) + (contentBoxBSize % 2);
return halfContentBoxBSize + bp.BEnd(aWM);
}
if (aGroup == BaselineSharingGroup::First) {
// First baseline for inverted-line content is the block-start content
// edge, as the frame is in effect "flipped" for alignment purposes.
return MOZ_UNLIKELY(aWM.IsLineInverted())
? bp.BStart(aWM)
: aFrame->BSize(aWM) - bp.BEnd(aWM);
}
// Last baseline for inverted-line content is the block-start content edge,
// as the frame is in effect "flipped" for alignment purposes.
return MOZ_UNLIKELY(aWM.IsLineInverted())
? aFrame->BSize(aWM) - bp.BStart(aWM)
: bp.BEnd(aWM);
}
} // namespace mozilla
|