1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
10 nscoord
Baseline::SynthesizeBOffsetFromMarginBox(const nsIFrame
* aFrame
,
12 BaselineSharingGroup aGroup
) {
13 MOZ_ASSERT(!aWM
.IsOrthogonalTo(aFrame
->GetWritingMode()));
14 auto margin
= aFrame
->GetLogicalUsedMargin(aWM
);
15 if (aGroup
== BaselineSharingGroup::First
) {
16 if (aWM
.IsAlphabeticalBaseline()) {
17 // First baseline for inverted-line content is the block-start margin
18 // edge, as the frame is in effect "flipped" for alignment purposes.
19 return MOZ_UNLIKELY(aWM
.IsLineInverted())
21 : aFrame
->BSize(aWM
) + margin
.BEnd(aWM
);
23 nscoord marginBoxCenter
= (aFrame
->BSize(aWM
) + margin
.BStartEnd(aWM
)) / 2;
24 return marginBoxCenter
- margin
.BStart(aWM
);
26 MOZ_ASSERT(aGroup
== BaselineSharingGroup::Last
);
27 if (aWM
.IsAlphabeticalBaseline()) {
28 // Last baseline for inverted-line content is the block-start margin edge,
29 // as the frame is in effect "flipped" for alignment purposes.
30 return MOZ_UNLIKELY(aWM
.IsLineInverted())
31 ? aFrame
->BSize(aWM
) + margin
.BStart(aWM
)
34 // Round up for central baseline offset, to be consistent with ::First.
35 nscoord marginBoxSize
= aFrame
->BSize(aWM
) + margin
.BStartEnd(aWM
);
36 nscoord marginBoxCenter
= (marginBoxSize
/ 2) + (marginBoxSize
% 2);
37 return marginBoxCenter
- margin
.BEnd(aWM
);
40 enum class BoxType
{ Border
, Padding
, Content
};
42 template <BoxType aType
>
43 static nscoord
SynthesizeBOffsetFromInnerBox(const nsIFrame
* aFrame
,
45 BaselineSharingGroup aGroup
) {
46 WritingMode wm
= aFrame
->GetWritingMode();
47 MOZ_ASSERT_IF(aType
!= BoxType::Border
, !aWM
.IsOrthogonalTo(wm
));
48 const nscoord borderBoxSize
= MOZ_UNLIKELY(aWM
.IsOrthogonalTo(wm
))
51 const LogicalMargin bp
= ([&] {
54 return LogicalMargin(aWM
);
55 case BoxType::Padding
:
56 return aFrame
->GetLogicalUsedBorder(wm
)
57 .ApplySkipSides(aFrame
->GetLogicalSkipSides())
59 case BoxType::Content
:
60 return aFrame
->GetLogicalUsedBorderAndPadding(wm
)
61 .ApplySkipSides(aFrame
->GetLogicalSkipSides())
66 if (MOZ_UNLIKELY(aWM
.IsCentralBaseline())) {
67 nscoord boxBSize
= borderBoxSize
- bp
.BStartEnd(aWM
);
68 if (aGroup
== BaselineSharingGroup::First
) {
69 return boxBSize
/ 2 + bp
.BStart(aWM
);
71 // Return the same center position as for ::First, but as offset from end:
72 nscoord halfBoxBSize
= (boxBSize
/ 2) + (boxBSize
% 2);
73 return halfBoxBSize
+ bp
.BEnd(aWM
);
75 if (aGroup
== BaselineSharingGroup::First
) {
76 // First baseline for inverted-line content is the block-start content
77 // edge, as the frame is in effect "flipped" for alignment purposes.
78 return MOZ_UNLIKELY(aWM
.IsLineInverted()) ? bp
.BStart(aWM
)
79 : borderBoxSize
- bp
.BEnd(aWM
);
81 // Last baseline for inverted-line content is the block-start content edge,
82 // as the frame is in effect "flipped" for alignment purposes.
83 return MOZ_UNLIKELY(aWM
.IsLineInverted()) ? borderBoxSize
- bp
.BStart(aWM
)
87 nscoord
Baseline::SynthesizeBOffsetFromContentBox(const nsIFrame
* aFrame
,
89 BaselineSharingGroup aGroup
) {
90 return SynthesizeBOffsetFromInnerBox
<BoxType::Content
>(aFrame
, aWM
, aGroup
);
93 nscoord
Baseline::SynthesizeBOffsetFromPaddingBox(const nsIFrame
* aFrame
,
95 BaselineSharingGroup aGroup
) {
96 return SynthesizeBOffsetFromInnerBox
<BoxType::Padding
>(aFrame
, aWM
, aGroup
);
99 nscoord
Baseline::SynthesizeBOffsetFromBorderBox(const nsIFrame
* aFrame
,
101 BaselineSharingGroup aGroup
) {
102 return SynthesizeBOffsetFromInnerBox
<BoxType::Border
>(aFrame
, aWM
, aGroup
);
105 } // namespace mozilla