Results 1 to 5 of 5

Thread: How to make svg painters measure text correctly

  1. #1
    Join Date
    Apr 2012
    Posts
    17
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default How to make svg painters measure text correctly

    I'm writing a program to create scientific plots on screen, and to produce Scalable Vector Graphics (SVG) copies on the hard disk.
    I came across an issue on SVG's. To show it I've created the following code.
    I know that to create the SVG in the paintEvent method is silly, but I just wanted to show the issue in a very compact code.

    Qt Code:
    1. #include "mainwindow.h"
    2. #include <QPainter>
    3. #include <QSvgGenerator>
    4. #include <QMainWindow>
    5.  
    6. MainWindow::MainWindow(QWidget *parent)
    7. : QMainWindow(parent)
    8. {
    9. }
    10.  
    11. MainWindow::~MainWindow()
    12. {
    13.  
    14. }
    15. void MainWindow::paintEvent(QPaintEvent *){
    16. int xPos;
    17. QRect r;
    18. QString s="This is some significant text";
    19.  
    20. //Writing on MainWindow:
    21. p.begin(this);
    22. p.drawText(0,0,0,0,0,s,&r);
    23. p.drawText(r,s);
    24. p.drawRect(r);
    25.  
    26. p.drawText(0,40,s);
    27. QFontMetrics m=p.fontMetrics();
    28. xPos=m.width(s);
    29. p.drawLine(QPoint(xPos,40),QPoint(xPos,40-m.height()));
    30. p.end();
    31.  
    32. //Creating and writing on the svg:
    33. QSvgGenerator generator;
    34. generator.setFileName("svgIssue.svg");
    35. p.begin(&generator);
    36. p.drawText(0,0,0,0,0,s,&r);
    37. p.drawText(r,s);
    38. p.drawRect(r);
    39.  
    40. p.drawText(0,40,s);
    41. QFontMetrics m1=p.fontMetrics();
    42. xPos=m1.width(s);
    43. p.drawLine(QPoint(xPos,40),QPoint(xPos,40-m.height()));
    44. p.end();
    45. }
    To copy to clipboard, switch view to plain text mode 


    This is what I see on screen (i.e. it is correct)
    winScreen.jpg

    And this is what I see when I browse the svg file using google chrome (i.e. the right part of the rectangle and the vertical bar are misplaced:
    svgToChrome.jpg

    I.e. my software computes correctly the text width on screen, but DOES NOT inside the SVG.
    You can imagine what such an error can cause on a program that creates scientific plots!

    Can anyone suggest a workaround for this issue?
    Thanks a lot in advance.
    MC

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to make svg painters measure text correctly

    The metrics are calculated using the font information returned by the system for the screen, and the text is rendered from the same data.

    When the same is painted to the SVG generator the line is drawn based on the screen rendering, but only the font name and size are output for the text (read you SVG file). How the SVG renderer maps the font name to a font it knows about, and how it determines the size of that font, is up to the renderer. This is where the discrepancy comes from. I was able to manufacture examples where the text spilled past the line in the SVG as rendered by Inkscape. If I use the Qt SVG renderer I get the expected result because it is using the same font information as the generator.

    Qt Code:
    1. #include <QApplication>
    2. #include <QPixmap>
    3. #include <QPainter>
    4. #include <QSvgGenerator>
    5. #include <QSvgRenderer>
    6.  
    7. void draw(QPainter &p) {
    8. const QString s("This is some significant text");
    9. QRect r;
    10. p.setFont(QFont("Comic Sans MS", 15));
    11. p.drawText(0,0,0,0,0,s,&r);
    12. p.drawText(r,s);
    13. p.drawRect(r);
    14.  
    15. p.drawText(0,40,s);
    16. QFontMetrics m=p.fontMetrics();
    17. int xPos=m.width(s);
    18. p.drawLine(QPoint(xPos,40),QPoint(xPos,40-m.height()));
    19. }
    20.  
    21. int main(int argc, char **argv) {
    22. QApplication app(argc, argv);
    23.  
    24. QPixmap pixmap(320,240);
    25. pixmap.fill(Qt::white);
    26. QPainter p(&pixmap);
    27. draw(p);
    28. p.end();
    29. pixmap.save("test.png");
    30.  
    31. QSvgGenerator gen;
    32. gen.setFileName("test.svg");
    33. gen.setSize(QSize(320,240));
    34. QPainter p2(&gen);
    35. draw(p2);
    36. p2.end();
    37.  
    38. QSvgRenderer render(QString("test.svg"));
    39. pixmap.fill(Qt::white);
    40. QPainter p3(&pixmap);
    41. draw(p3);
    42. p3.end();
    43. pixmap.save("test_via_svg.png");
    44.  
    45. return 0;
    46. }
    To copy to clipboard, switch view to plain text mode 
    If you want pixel based reproduction then you should use a raster format.

  3. #3
    Join Date
    Apr 2012
    Posts
    17
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: How to make svg painters measure text correctly

    Hi,
    your conclusion confirms my suspects.
    when thinking that the SVG renderer might use fonts that are only approximately equivalent to those I used to create the SVG, I expected that one of the two following workarounds could be used to better the text-graphics alignment issue.

    1) Storing the font. It might have been possible that people defining SVG standard would have envisaged the possibility of storing the font definition inside the SVG. Something similar to what is done in some PDF's. This would ensure that the renderer can reproduce text exactly using the same algorithm to display on screen. Unfortunately I did not find such option in Qt SVG library

    2) using right alignment. Indeed in my case what I best need is the right alignment of the text (think of the numbers of the vertical axis on a plot). I mean, if the text is in the right right position, but is a bit longer or shorter than on screen, this would not be a big issue. So I tried a code that wrote text with right vertical alignment and I expected that the rightmost pixel would be in an accurately evaluated position. Unfortunately I tested this and it did not work.

    It is really strange to me that the people that have worked on SVG standard or library have not dealt with this important issue in a systematic way.
    My two workarounds above seem to me to be reasonable and easy to implement.

    MC

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to make svg painters measure text correctly

    There is font support in SVG 1.1 (http://www.w3.org/TR/SVG/fonts.html) but support is patchy in browsers (not so bad in dedicated SVG viewers/editors). That font support is not supported at all in SVG Tiny (Qt implements this) AFAICT.

  5. #5
    Join Date
    Apr 2012
    Posts
    17
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: How to make svg painters measure text correctly

    I understand.
    However, QT should guarantee the starting position of text, I think. So, when I say some text is to be right aligned, the its right position should be correct (and now is not).
    If this was correctly behaving, a scientific plot could be made satisfactorily even without font support: The numbers on the left-aligned vertical axis could be right-aligned and the numbers on the horizontal axis centre-aligned.
    The incorrect right position of a right-aligned text can be viewed as a Qt bug, I think.
    I've posted something on this topic on the Qt bug reporting site. We will see if something happens.
    In the meanwhile I'm going to change my software so that it always creates both SVG and PNG outputs. The user will use which one is better or he likes.

    MC

Similar Threads

  1. How do you make android applications display correctly on android phone?
    By Cyrebo in forum Qt for Embedded and Mobile
    Replies: 1
    Last Post: 17th August 2013, 07:31
  2. Replies: 2
    Last Post: 17th July 2013, 09:26
  3. Measure Qt Application Performance
    By JcPep in forum Newbie
    Replies: 0
    Last Post: 16th July 2013, 10:50
  4. Replies: 1
    Last Post: 1st June 2011, 18:37
  5. Replies: 0
    Last Post: 15th November 2009, 09:40

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.