Hi,
first what I'm doing.
I'm coding a small GUI system for a game I'm writing. The existing GUI Toolkits usable on Ogre3D don't convince me enought that I use them. I'd like to use Qt, I even tried it but had some major issues doing so (major performance loss, Mouse/Keyboard events not working, etc.). So I decided to write my own toolkit. I already did write one, but it was very dirty and I didn't write it as an own library but coded it directly to the game. So I decided to re-write it.

Now my issue.
When rendering the Widgets, everything is fine, until I add a border radius. I guess, an image showing it is way easier than explaining:
click me
I'm rendering directly on a QImage, using QPainter/QPainterPath.
The Pen is defined as follows:
Qt Code:
  1. painter.setPen(QPen(b, wB, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
To copy to clipboard, switch view to plain text mode 
The Brush is either a QColor or a QLinearGradient.
As render hint I only use Antialiasing.
The QImage is in the ARGB32 format.
I tried both approaches for the border radius, arcTo and cubicTo. Both ways have the same issue.

The problem occurs on different Graphics Systems.

here is the code I use for the rendering:
Qt Code:
  1. QImage AWidget::paint()
  2. {
  3. if (!visible())
  4. {
  5. cHasChange = false;
  6. return QImage();
  7. }
  8. if (!hasChange())
  9. {
  10. cHasChange = false;
  11. if (cLastImage != 0)
  12. {
  13. return *cLastImage;
  14. }
  15. }
  16. cHasChange = false;
  17.  
  18. short w = width();
  19. short h = height();
  20. short radTL = 10;
  21. short radTR = 10;
  22. short radBR = 10;
  23. short radBL = 10;
  24.  
  25. QBrush bg(QColor(100, 200, 100, 100));
  26.  
  27. QColor b(0, 0, 0, 255);
  28.  
  29. short wB = 1;
  30.  
  31.  
  32. if (cHasStyle)
  33. {
  34. if (cBorder->radius()->isValid())
  35. {
  36. radTL = cBorder->radius()->tl();
  37. radTR = cBorder->radius()->tr();
  38. radBR = cBorder->radius()->br();
  39. radBL = cBorder->radius()->bl();
  40. }
  41. if (cBackground->color()->isValid())
  42. {
  43. bg = QBrush(cBackground->color()->toQColor());
  44. }
  45. else if (cBackground->gradient()->isValid())
  46. {
  47. bg = QBrush(cBackground->gradient()->toQGradient());
  48. }
  49. if (cBorder->color()->isValid())
  50. {
  51. b = (cBorder->color()->toQColor());
  52. }
  53. if (cBorder->size()->isValid())
  54. {
  55. wB = cBorder->size()->left();
  56. }
  57. }
  58.  
  59. bool useCubic = false;
  60.  
  61. path.moveTo(radTL, 0);
  62. path.lineTo(w - radTR, 0);
  63. if (radTR > 0)
  64. {
  65. if (useCubic)
  66. {
  67. path.cubicTo(w, 0, w, radTR, w, radTR);
  68. }
  69. else
  70. {
  71. path.arcTo(w - radTR * 2, 0, radTR * 2, radTR * 2, 90, -90);
  72. }
  73. }
  74. path.lineTo(w, h - radBR);
  75. if (radBR > 0)
  76. {
  77. if (useCubic)
  78. {
  79. path.cubicTo(w, h, w - radBR, h, w - radBR, h);
  80. }
  81. else
  82. {
  83. path.arcTo(w - radBR * 2, h - radBR * 2, radBR * 2, radBR * 2, 0, -90);
  84. }
  85. }
  86. path.lineTo(radBL, h);
  87. if (radBL > 0)
  88. {
  89. if (useCubic)
  90. {
  91. path.cubicTo(0, h, 0, h - radBL, 0, h - radBL);
  92. }
  93. else
  94. {
  95. path.arcTo(0, h - radBL * 2, radBL * 2, radBL * 2, -90, -90);
  96. }
  97. }
  98. path.lineTo(0, radTL);
  99. if (radTL > 0)
  100. {
  101. if (useCubic)
  102. {
  103. path.cubicTo(0, radTL, 0, 0, radTL, 0);
  104. }
  105. else
  106. {
  107. path.arcTo(0, 0, radTL * 2, radTL * 2, -180, -90);
  108. }
  109. }
  110. path.closeSubpath();
  111.  
  112.  
  113. QImage *img = new QImage(w, h, QImage::Format_ARGB32);
  114. img->fill(0);
  115. QPainter painter;
  116. painter.begin(img);
  117. painter.setRenderHints(QPainter::Antialiasing);
  118. painter.setPen(QPen(b, wB, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
  119. painter.setBrush(bg);
  120.  
  121. painter.drawPath(path);
  122.  
  123. paintEvent(&painter);
  124.  
  125. // +++ draw children
  126. if (children().length() > 0)
  127. {
  128. for (int i = 0; i < children().length(); i++)
  129. {
  130. painter.drawImage(child(i)->x(), child(i)->y(), child(i)->paint());
  131. }
  132. }
  133. // --- draw children
  134.  
  135. painter.end();
  136.  
  137. cLastImage = img;
  138.  
  139. return *img;
  140. }
To copy to clipboard, switch view to plain text mode 

Furthermore would I like to ask, what the better way to render the border radius is - an arc or a bezier curve?

If some information is missing, feel free to tell.

cheers