@@ -688,29 +688,30 @@ void AtlasEngine::_resolveFontMetrics(const wchar_t* requestedFaceName, const Fo
688
688
const auto underlineWidth = std::max (1 .0f , std::roundf (underlineThickness));
689
689
const auto strikethroughPos = std::roundf (baseline + strikethroughPosition);
690
690
const auto strikethroughWidth = std::max (1 .0f , std::roundf (strikethroughThickness));
691
- const auto thinLineWidth = std::max (1 .0f , std::roundf (underlineThickness / 2 .0f ));
691
+ const auto doubleUnderlineWidth = std::max (1 .0f , std::roundf (underlineThickness / 2 .0f ));
692
+ const auto thinLineWidth = std::max (1 .0f , std::roundf (std::max (adjustedWidth / 16 .0f , adjustedHeight / 32 .0f )));
692
693
693
694
// For double underlines we loosely follow what Word does:
694
- // 1. The lines are half the width of an underline (= thinLineWidth )
695
+ // 1. The lines are half the width of an underline (= doubleUnderlineWidth )
695
696
// 2. Ideally the bottom line is aligned with the bottom of the underline
696
697
// 3. The top underline is vertically in the middle between baseline and ideal bottom underline
697
698
// 4. If the top line gets too close to the baseline the underlines are shifted downwards
698
699
// 5. The minimum gap between the two lines appears to be similar to Tex (1.2pt)
699
700
// (Additional notes below.)
700
701
701
702
// 2.
702
- auto doubleUnderlinePosBottom = underlinePos + underlineWidth - thinLineWidth ;
703
+ auto doubleUnderlinePosBottom = underlinePos + underlineWidth - doubleUnderlineWidth ;
703
704
// 3. Since we don't align the center of our two lines, but rather the top borders
704
705
// we need to subtract half a line width from our center point.
705
- auto doubleUnderlinePosTop = std::roundf ((baseline + doubleUnderlinePosBottom - thinLineWidth ) / 2 .0f );
706
+ auto doubleUnderlinePosTop = std::roundf ((baseline + doubleUnderlinePosBottom - doubleUnderlineWidth ) / 2 .0f );
706
707
// 4.
707
- doubleUnderlinePosTop = std::max (doubleUnderlinePosTop, baseline + thinLineWidth );
708
+ doubleUnderlinePosTop = std::max (doubleUnderlinePosTop, baseline + doubleUnderlineWidth );
708
709
// 5. The gap is only the distance _between_ the lines, but we need the distance from the
709
710
// top border of the top and bottom lines, which includes an additional line width.
710
711
const auto doubleUnderlineGap = std::max (1 .0f , std::roundf (1 .2f / 72 .0f * dpi));
711
- doubleUnderlinePosBottom = std::max (doubleUnderlinePosBottom, doubleUnderlinePosTop + doubleUnderlineGap + thinLineWidth );
712
+ doubleUnderlinePosBottom = std::max (doubleUnderlinePosBottom, doubleUnderlinePosTop + doubleUnderlineGap + doubleUnderlineWidth );
712
713
// Our cells can't overlap each other so we additionally clamp the bottom line to be inside the cell boundaries.
713
- doubleUnderlinePosBottom = std::min (doubleUnderlinePosBottom, adjustedHeight - thinLineWidth );
714
+ doubleUnderlinePosBottom = std::min (doubleUnderlinePosBottom, adjustedHeight - doubleUnderlineWidth );
714
715
715
716
const auto cellWidth = gsl::narrow<u16>(lrintf (adjustedWidth));
716
717
const auto cellHeight = gsl::narrow<u16>(lrintf (adjustedHeight));
@@ -749,6 +750,7 @@ void AtlasEngine::_resolveFontMetrics(const wchar_t* requestedFaceName, const Fo
749
750
const auto strikethroughWidthU16 = gsl::narrow_cast<u16>(lrintf (strikethroughWidth));
750
751
const auto doubleUnderlinePosTopU16 = gsl::narrow_cast<u16>(lrintf (doubleUnderlinePosTop));
751
752
const auto doubleUnderlinePosBottomU16 = gsl::narrow_cast<u16>(lrintf (doubleUnderlinePosBottom));
753
+ const auto doubleUnderlineWidthU16 = gsl::narrow_cast<u16>(lrintf (doubleUnderlineWidth));
752
754
753
755
// NOTE: From this point onward no early returns or throwing code should exist,
754
756
// as we might cause _api to be in an inconsistent state otherwise.
@@ -771,8 +773,8 @@ void AtlasEngine::_resolveFontMetrics(const wchar_t* requestedFaceName, const Fo
771
773
772
774
fontMetrics->underline = { underlinePosU16, underlineWidthU16 };
773
775
fontMetrics->strikethrough = { strikethroughPosU16, strikethroughWidthU16 };
774
- fontMetrics->doubleUnderline [0 ] = { doubleUnderlinePosTopU16, thinLineWidthU16 };
775
- fontMetrics->doubleUnderline [1 ] = { doubleUnderlinePosBottomU16, thinLineWidthU16 };
776
+ fontMetrics->doubleUnderline [0 ] = { doubleUnderlinePosTopU16, doubleUnderlineWidthU16 };
777
+ fontMetrics->doubleUnderline [1 ] = { doubleUnderlinePosBottomU16, doubleUnderlineWidthU16 };
776
778
fontMetrics->overline = { 0 , underlineWidthU16 };
777
779
778
780
fontMetrics->builtinGlyphs = fontInfoDesired.GetEnableBuiltinGlyphs ();
0 commit comments