Browse Source

Adjusted code related to subscript/superscript

MarcinZiabek 3 years ago
parent
commit
1af7c0a144

+ 66 - 18
QuestPDF.Examples/TextExamples.cs

@@ -38,12 +38,11 @@ namespace QuestPDF.Examples
         }
 
         [Test]
-        public void SuperscriptSubscript()
+        public void SuperscriptSubscript_General()
         {
             RenderingTest
                .Create()
-               .PageSize(500, 300)
-
+               .PageSize(500, 500)
                .ProduceImages()
                .ShowResults()
                .Render(container =>
@@ -55,28 +54,77 @@ namespace QuestPDF.Examples
                         .Padding(10)
                         .Text(text =>
                         {
-                            text.Span("E=mc");
+                            text.DefaultTextStyle(x => x.FontSize(20));
+                            text.ParagraphSpacing(2);
+                            
+                            
+                            text.Span("In physics, mass–energy equivalence is the relationship between mass and energy in a system's rest frame, where the two values differ only by a constant and the units of measurement.");
+                            text.Span("[1][2]").Superscript();
+                            text.Span(" The principle is described by the physicist Albert Einstein's famous formula: E = mc");
                             text.Span("2").Superscript();
-
+                            text.Span(". ");
+                            text.Span("[3]").Superscript();
+                            
                             text.EmptyLine();
-
+                            
                             text.Span("H");
                             text.Span("2").Subscript();
-                            text.Span("O");
+                            text.Span("O is the chemical formula for water, meaning that each of its molecules contains one oxygen and two hydrogen atoms.");
 
                             text.EmptyLine();
 
-                            text.ParagraphSpacing(2);
-
-                            var style = TextStyle.Default.Underline();
-
-                            text.Span("Subscript").Style(style).Subscript().BackgroundColor(Colors.Green.Medium);
-                            text.Span("Normal").Style(style).NormalPosition().BackgroundColor(Colors.Blue.Medium);
-                            text.Line("Superscript").Style(style).Superscript().BackgroundColor(Colors.Red.Medium);
-
-                            text.Line("Superscript").Style(style).Superscript().BackgroundColor(Colors.Green.Medium);
-                            text.Line("Normal").Style(style).NormalPosition().BackgroundColor(Colors.Blue.Medium);
-                            text.Line("Subscript").Style(style).Subscript().BackgroundColor(Colors.Red.Medium);
+                            text.Span("H");
+                            text.Span("2").Subscript();
+                            text.Span("O");
+                        });
+               });
+        }
+        
+        [Test]
+        public void SuperscriptSubscript_Effects()
+        {
+            RenderingTest
+               .Create()
+               .PageSize(800, 400)
+               .ProduceImages()
+               .ShowResults()
+               .Render(container =>
+               {
+                   container
+                        .Padding(25)
+                        .DefaultTextStyle(x => x.FontSize(30))
+                        .Column(column =>
+                        {
+                            column.Spacing(25);
+                            
+                            column.Item().Text(text =>
+                            {
+                                text.DefaultTextStyle(x => x.Underline());
+                                
+                                text.Span("Underline of the superscript (E = mc");
+                                text.Span("2").Superscript();
+                                text.Span(") should be at the same height as for normal text.");
+                            });
+                            
+                            column.Item().Text(text =>
+                            {
+                                text.DefaultTextStyle(x => x.Underline());
+                                
+                                text.Span("Underline of the subscript(H");
+                                text.Span("2").Subscript();
+                                text.Span("O) should be slightly lower than a normal text.");
+                            });
+                            
+                            column.Item().Text(text =>
+                            {
+                                text.DefaultTextStyle(x => x.Strikethrough());
+                                
+                                text.Span("Strikethrough of both superscript (E=mc");
+                                text.Span("2").Superscript();
+                                text.Span(") and subscript(H");
+                                text.Span("2").Subscript();
+                                text.Span("O) should be visible in the middle of the text.");
+                            });
                         });
                });
         }

+ 19 - 11
QuestPDF/Drawing/FontManager.cs

@@ -78,9 +78,14 @@ namespace QuestPDF.Drawing
             {
                 var weight = (SKFontStyleWeight)(style.FontWeight ?? FontWeight.Normal);
 
-                //Extra weight for superscript and subscript
-                if (style.FontPosition == FontPosition.Superscript || style.FontPosition == FontPosition.Subscript)
-                    weight = (SKFontStyleWeight)((int)weight + 100);
+                // superscript and subscript use slightly bolder font to match visually line thickness
+                if (style.FontPosition is FontPosition.Superscript or FontPosition.Subscript)
+                {
+                    var weightValue = (int)weight;
+                    weightValue = Math.Min(weightValue + 100, 1000);
+                    
+                    weight = (SKFontStyleWeight) (weightValue);
+                }
 
                 var slant = (style.IsItalic ?? false) ? SKFontStyleSlant.Italic : SKFontStyleSlant.Upright;
 
@@ -100,19 +105,22 @@ namespace QuestPDF.Drawing
                     $"1) install the font on your operating system or execution environment. " +
                     $"2) load a font file specifically for QuestPDF usage via the QuestPDF.Drawing.FontManager.RegisterFontType(Stream fileContentStream) static method.");
             }
+            
+            static float GetTextScale(TextStyle style)
+            {
+                return style.FontPosition switch
+                {
+                    FontPosition.Normal => 1f,
+                    FontPosition.Subscript => 0.625f,
+                    FontPosition.Superscript => 0.625f,
+                    _ => throw new ArgumentOutOfRangeException()
+                };
+            }
         }
 
         internal static SKFontMetrics ToFontMetrics(this TextStyle style)
         {
             return FontMetrics.GetOrAdd(style.FontMetricsKey, key => style.NormalPosition().ToPaint().FontMetrics);
         }
-
-        private static float GetTextScale(TextStyle style)
-        {
-            if (style.FontPosition == FontPosition.Superscript || style.FontPosition == FontPosition.Subscript)
-                return 0.65f;
-
-            return 1;
-        }
     }
 }

+ 27 - 15
QuestPDF/Elements/Text/Items/TextBlockSpan.cs

@@ -126,35 +126,47 @@ namespace QuestPDF.Elements.Text.Items
         {
             var fontMetrics = Style.ToFontMetrics();
 
-            var glyphOffsetY = GetVerticalGlyphOffsetForStyle(Style);
-
+            var glyphOffset = GetGlyphOffset();
             var text = Text.Substring(request.StartIndex, request.EndIndex - request.StartIndex);
             
             request.Canvas.DrawRectangle(new Position(0, request.TotalAscent), new Size(request.TextSize.Width, request.TextSize.Height), Style.BackgroundColor);
-            request.Canvas.DrawText(text, new Position(0, glyphOffsetY), Style);
+            request.Canvas.DrawText(text, new Position(0, glyphOffset), Style);
 
             // draw underline
             if ((Style.HasUnderline ?? false) && fontMetrics.UnderlinePosition.HasValue)
-                DrawLine(glyphOffsetY + fontMetrics.UnderlinePosition.Value, fontMetrics.UnderlineThickness ?? 1);
+            {
+                var underlineOffset = Style.FontPosition == FontPosition.Superscript ? 0 : glyphOffset;
+                DrawLine(fontMetrics.UnderlinePosition.Value + underlineOffset, fontMetrics.UnderlineThickness ?? 1);
+            }
             
             // draw stroke
             if ((Style.HasStrikethrough ?? false) && fontMetrics.StrikeoutPosition.HasValue)
-                DrawLine(glyphOffsetY + fontMetrics.StrikeoutPosition.Value, fontMetrics.StrikeoutThickness ?? 1);
-
+            {
+                var strikeoutThickness = fontMetrics.StrikeoutThickness ?? 1;
+                strikeoutThickness *= Style.FontPosition == FontPosition.Normal ? 1f : 0.625f;
+                
+                DrawLine(fontMetrics.StrikeoutPosition.Value + glyphOffset, strikeoutThickness);
+            }
+            
             void DrawLine(float offset, float thickness)
             {
-                request.Canvas.DrawRectangle(new Position(0, offset - thickness / 2f), new Size(request.TextSize.Width, thickness), Style.Color);
+                request.Canvas.DrawRectangle(new Position(0, offset), new Size(request.TextSize.Width, thickness), Style.Color);
             }
-        }
 
-        private static float GetVerticalGlyphOffsetForStyle(TextStyle style)
-        {
-            if (style.FontPosition == FontPosition.Superscript)
-                return (style.Size ?? 12f) * -0.35f;
-            if (style.FontPosition == FontPosition.Subscript)
-                return (style.Size ?? 12f) * 0.1f;
+            float GetGlyphOffset()
+            {
+                var fontSize = Style.Size ?? 12f;
 
-            return 0;
+                var offsetFactor = Style.FontPosition switch
+                {
+                    FontPosition.Normal => 0,
+                    FontPosition.Subscript => 0.1f,
+                    FontPosition.Superscript => -0.35f,
+                    _ => throw new ArgumentOutOfRangeException()
+                };
+
+                return fontSize * offsetFactor;
+            }
         }
     }
 }

+ 1 - 1
QuestPDF/Infrastructure/FontPosition.cs

@@ -2,7 +2,7 @@
 {
     internal enum FontPosition
     {
-        Normal = 0,
+        Normal,
         Subscript,
         Superscript,
     }