Steema Issues Database

Note: This database is for bugs and wishes only. For technical support help, if you are a customer please visit our online forums;
otherwise you can use StackOverflow.
Before using this bug-tracker we recommend a look at this document, Steema Bug Fixing Policy.



Bug 2449

Summary: Font Size returns different size between NET5 Headless and Winform version
Product: .NET TeeChart Reporter: marc meumann <marc>
Component: CanvasAssignee: Steema Issue Manager <issuemanager>
Status: RESOLVED NOTABUG    
Severity: normal CC: bkohrs, chris
Priority: ---    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows   
Chart Series: --- Delphi / C++ Builder RAD IDE Version:
Attachments: servchart
winchart
servchart2
winchart2

Description marc meumann 2021-07-12 11:10:43 EDT
The following code, when run from a Console application (TeeChart.Server dll)  and from a Winform TeeChart (TeeChart.Winform.dll), gives different results.

Test code:

Winform:
tChart1.Header.Font.Name = "Tahoma";
tChart1.Header.Font.SizeFloat = 10.0f;
tChart1.Draw();
var size = tChart1.Graphics3D.MeasureString(tChart1.Header.Font, "TeeChart");
tChart1.Header.Text = tChart1.Header.Text + size.ToString();

Console:
var chart = new TChart();
Steema.TeeChart.Drawing.ChartFont.FontCollection.Install(@"C:\windows\fonts\Tahoma.ttf");

chart.Header.Font.Name = "Tahoma";
chart.Header.Font.SizeFloat = 10.0f;
var size = chart.Graphics3D.MeasureString(chart.Header.Font, "TeeChart");

chart.Header.Text = chart.Header.Text + size.ToString();

chart.Export.Image.PNG.Width = 690;
chart.Export.Image.PNG.Height = 584;
chart.Export.Image.PNG.Save(@"d:\testfolder\testchart.png");
Comment 1 christopher ireland 2021-07-21 11:05:55 EDT
Created attachment 976 [details]
servchart

Produced using TeeChart.Server.dll and the following code:

    static void Main(string[] args)
    {
      var chart = new TChart();

      void Chart_AfterDraw(object sender, IGraphics3D g)
      {
        var size = chart.Graphics3D.MeasureString(chart.Header.Font, "TeeChart");
        g.TextOut(100, 100, $"Size: {size}");
      }

      Steema.TeeChart.Drawing.ChartFont.FontCollection.Install(@"C:\windows\fonts\Tahoma.ttf");

      chart.Header.Font.Name = "Tahoma";
      chart.Header.Font.Size = 10;
      chart.AfterDraw += Chart_AfterDraw;

      chart.Export.Image.PNG.Width = 800;
      chart.Export.Image.PNG.Height = 600;
      var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "servchart.png");

      chart.Export.Image.PNG.Save(path);

      new Process
      {
        StartInfo = new ProcessStartInfo(path)
        {
          UseShellExecute = true
        }
      }.Start();
    }
Comment 2 christopher ireland 2021-07-21 11:07:26 EDT
Created attachment 977 [details]
winchart

Produced using TeeChart.WinForm.dll and the following code:

    public Form1()
    {
      var chart = new TChart();

      void Chart_AfterDraw(object sender, IGraphics3D g)
      {
        var size = chart.Graphics3D.MeasureString(chart.Header.Font, "TeeChart");
        g.TextOut(100, 100, $"Size: {size}");
      }

      InitializeComponent();

      chart.Header.Font.Name = "Tahoma";
      chart.Header.Font.Size = 10;
      chart.AfterDraw += Chart_AfterDraw;

      chart.Export.Image.PNG.Width = 800;
      chart.Export.Image.PNG.Height = 600;
      var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "winchart.png");
      chart.Export.Image.PNG.Save(path);


      new Process
      {
        StartInfo = new ProcessStartInfo(path)
        {
          UseShellExecute = true
        }
      }.Start();
    }
Comment 3 christopher ireland 2021-07-21 11:11:21 EDT
As we can see in the two attachments:
1) TeeChart.Server: http://bugs.teechart.net/attachment.cgi?id=976
2) TeeChart.WinForm: http://bugs.teechart.net/attachment.cgi?id=977

The text is actually of a different size, the issue is not as if MeasureString was returning an incorrect value. It seems that MeasureString is returning a correct value, but that this value corresponds to text which is actually of a different size. This is very likely to be an issue of the difference in graphics library than a problem with our code.
Comment 4 christopher ireland 2021-07-21 11:49:32 EDT
Created attachment 978 [details]
servchart2

Produced using TeeChart.Server and the following code:

    static void Main(string[] args)
    {
      var chart = new TChart();

      void Chart_AfterDraw(object sender, IGraphics3D g)
      {
        var size = chart.Graphics3D.MeasureString(chart.Header.Font, "TeeChart");
        g.TextOut(100, 100, $"FontSize: {chart.Header.Font.Size}, Size: {size}");
      }

      chart.AfterDraw += Chart_AfterDraw;

      chart.Export.Image.PNG.Width = 800;
      chart.Export.Image.PNG.Height = 600;
      var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "servchart2.png");

      chart.Export.Image.PNG.Save(path);

      new Process
      {
        StartInfo = new ProcessStartInfo(path)
        {
          UseShellExecute = true
        }
      }.Start();
    }
Comment 5 christopher ireland 2021-07-21 11:50:51 EDT
Created attachment 979 [details]
winchart2

Produced using TeeChart.WinForm and the following code:

    public Form1()
    {
      var chart = new TChart();

      void Chart_AfterDraw(object sender, IGraphics3D g)
      {
        var size = chart.Graphics3D.MeasureString(chart.Header.Font, "TeeChart");
        g.TextOut(100, 100, $"FontSize: {chart.Header.Font.Size}, Size: {size}");
      }

      InitializeComponent();

      chart.AfterDraw += Chart_AfterDraw;

      chart.Export.Image.PNG.Width = 800;
      chart.Export.Image.PNG.Height = 600;
      var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "winchart2.png");
      chart.Export.Image.PNG.Save(path);


      new Process
      {
        StartInfo = new ProcessStartInfo(path)
        {
          UseShellExecute = true
        }
      }.Start();
    }
Comment 6 christopher ireland 2021-07-21 11:54:55 EDT
Looking at these two images:
1) TeeChart.Server: http://bugs.teechart.net/attachment.cgi?id=978
2) TeeChart.WinForm: http://bugs.teechart.net/attachment.cgi?id=979

We can see that to obtain text of a similar size we have to use different Font sizes - 16 for the SixLabors graphics library, and 12 for the .NET 5 GDI+ library.

As this has been the case since the TeeChart.Server was written, I don't think we can consider this issue as a defect.
Comment 7 Brian Kohrs 2021-07-23 11:37:27 EDT
While I understand that this might not be in your code, you do have two versions of your product that come up with different results depending on which version of .NET that is being targeted. I think that would be considered a defect.

Here is my real world example that prompted the issue being raised. I have a WinForms application that allows a user to customize some aspects of a chart. This includes the font size of certain elements. Those settings are saved, and then in a separate non-WinForms application we use that information to generate a chart that is included in a report. Because of the size difference of the fonts, the resulting image looks significantly different between the two applications.
Comment 8 christopher ireland 2021-07-23 11:50:15 EDT
Both WPF and Windows Forms form part of the .NET Framework, yet despite the fact that TeeChart code written for the first can't be ported without correction to the second, we have yet to have received reports affirming this lack of direct portability as a defect. 

TeeChart.Server.dll, TeeChart.WinForm.dll, and TeeChart.WPF.dll all target .NET 5, but just as TeeChart code can't be written for either of the last two and ported without correction between them, so code written for the first assembly can't be ported without correction to each of the other two. This is essentially because of the Graphics Library underpinning the TeeChart.Server.dll, a Library which in fact is not yet completely out of beta.

What we might consider is a 'helper' property on the Graphics class of TeeChart.Server.dll - say FontSizeMultiplier - of type double which applies a multiple to the value of all Font.Size instances specified in client code. In that way a client could set a multiplier of their choice, so saving them the work of having to apply one in their own code.