Home > database >  QRawFont/QPainterPath reproducing icon
QRawFont/QPainterPath reproducing icon

Time:07-19

I`m trying to reproduce an icon from FontAwesome.

First I load the font and get the points:

int fa = QFontDatabase::addApplicationFont(":/fonts/fa-solid-900.ttf");
auto fas = QFontDatabase::applicationFontFamilies(fa).at(0);

QRawFont rfont = QRawFont::fromFont(fas);

qDebug() << rfont.pathForGlyph(0);

Result being:

QPainterPath: Element count=45
 -> MoveTo(x=10.5, y=-14)
 -> LineTo(x=1.5, y=-14)
 -> CurveTo(x=1.08333, y=-13.9792)
 -> CurveToData(x=0.729167, y=-13.8333)
 -> CurveToData(x=0.4375, y=-13.5625)
 -> CurveTo(x=0.166667, y=-13.2708)
 -> CurveToData(x=0.0208333, y=-12.9167)
 -> CurveToData(x=0, y=-12.5)
 -> LineTo(x=0, y=0.5)
 -> CurveTo(x=0.0208333, y=0.916667)
 -> CurveToData(x=0.166667, y=1.27083)
 -> CurveToData(x=0.4375, y=1.5625)
 -> CurveTo(x=0.729167, y=1.83333)
 -> CurveToData(x=1.08333, y=1.97917)
 -> CurveToData(x=1.5, y=2)
 -> LineTo(x=10.5, y=2)
 -> CurveTo(x=10.9167, y=1.97917)
 -> CurveToData(x=11.2708, y=1.83333)
 -> CurveToData(x=11.5625, y=1.5625)
 -> CurveTo(x=11.8333, y=1.27083)
 -> CurveToData(x=11.9792, y=0.916667)
 -> CurveToData(x=12, y=0.5)
 -> LineTo(x=12, y=-12.5)
 -> CurveTo(x=11.9792, y=-12.9167)
 -> CurveToData(x=11.8333, y=-13.2708)
 -> CurveToData(x=11.5625, y=-13.5625)
 -> CurveTo(x=11.2708, y=-13.8333)
 -> CurveToData(x=10.9167, y=-13.9792)
 -> CurveToData(x=10.5, y=-14)
 -> MoveTo(x=8.8125, y=-12)
 -> LineTo(x=6, y=-7.8125)
 -> LineTo(x=3.21875, y=-12)
 -> LineTo(x=8.8125, y=-12)
 -> MoveTo(x=2, y=-10.1875)
 -> LineTo(x=4.8125, y=-6)
 -> LineTo(x=2, y=-1.8125)
 -> LineTo(x=2, y=-10.1875)
 -> MoveTo(x=3.21875, y=0)
 -> LineTo(x=6, y=-4.1875)
 -> LineTo(x=8.8125, y=0)
 -> LineTo(x=3.21875, y=0)
 -> MoveTo(x=10, y=-1.8125)
 -> LineTo(x=7.21875, y=-6)
 -> LineTo(x=10, y=-10.1875)
 -> LineTo(x=10, y=-1.8125)

Then I am trying to reproduce it:

QPainterPath* polygonPath = new QPainterPath();

polygonPath->moveTo(10.5, -14);
polygonPath->lineTo(1.5, -14);
polygonPath->CurveTo(1.08333, -13.9792);
polygonPath->CurveToData(0.729167, -13.8333);
polygonPath->CurveToData(0.4375, -13.5625);
polygonPath->CurveTo(0.166667, -13.2708);
polygonPath->CurveToData(0.0208333, -12.9167);
polygonPath->CurveToData(0, -12.5);
polygonPath->lineTo(0, 0.5);
polygonPath->CurveTo(0.0208333, 0.916667);
polygonPath->CurveToData(0.166667, 1.27083);
polygonPath->CurveToData(0.4375, 1.5625);
polygonPath->CurveTo(0.729167, 1.83333);
polygonPath->CurveToData(1.08333, 1.97917);
polygonPath->CurveToData(1.5, 2);
polygonPath->lineTo(10.5, 2);
polygonPath->CurveTo(10.9167, 1.97917);
polygonPath->CurveToData(11.2708, 1.83333);
polygonPath->CurveToData(11.5625, 1.5625);
polygonPath->CurveTo(11.8333, 1.27083);
polygonPath->CurveToData(11.9792, 0.916667);
polygonPath->CurveToData(12, 0.5);
polygonPath->lineTo(12, -12.5);
polygonPath->CurveTo(11.9792, -12.9167);
polygonPath->CurveToData(11.8333, -13.2708);
polygonPath->CurveToData(11.5625, -13.5625);
polygonPath->CurveTo(11.2708, -13.8333);
polygonPath->CurveToData(10.9167, -13.9792);
polygonPath->CurveToData(10.5, -14);
polygonPath->moveTo(8.8125, -12);
polygonPath->lineTo(6, -7.8125);
polygonPath->lineTo(3.21875, -12);
polygonPath->lineTo(8.8125, -12);
polygonPath->moveTo(2, -10.1875);
polygonPath->lineTo(4.8125, -6);
polygonPath->lineTo(2, -1.8125);
polygonPath->lineTo(2, -10.1875);
polygonPath->moveTo(3.21875, 0);
polygonPath->lineTo(6, -4.1875);
polygonPath->lineTo(8.8125, 0);
polygonPath->lineTo(3.21875, 0);
polygonPath->moveTo(10, -1.8125);
polygonPath->lineTo(7.21875, -6);
polygonPath->lineTo(10, -10.1875);
polygonPath->lineTo(10, -1.8125);
polygonPath->closeSubpath();

Unfortunately I have no idea what to use instead of CurveTo and CurveToData. I have been reading the docs but just cannot understand it.

What I want to achieve is to obtain the icon points so I can draw it as a polygon. Similar to this:

QPolygon symbol;

symbol << QPoint(0.65, -9.75)
    << QPoint(5.85, -9.75)
    << QPoint(5.85, 0)
    << QPoint(0.65, 0);

painter.drawPolygon(symbol);

If someone would be so kind to provide a solution that would be amazing.

CodePudding user response:

For MS Character Table - Skull

The relevant info is the Unicode code point shown in the bottom status line: U 2620.

Then I modified the makeSample() to use that character for retrieval of the corresponding painter path:

QPainterPath makeSample()
{
  // get a font which should be able to provide most of the Unicode code points
  QFont qFont("Arial Unicode MS");
  // transform font into a raw font
  QRawFont qRawFont = QRawFont::fromFont(qFont);
  // build a Qt string with the intended character
  QString qText(1, QChar(0x2620)); // 0x2620 is the Unicode code point for Skull
  // retrieve the glyph index for the character
  QVector<quint32> qGlyphIndices = qRawFont.glyphIndexesForString(qText);
  // build the Qt painter path
  QPainterPath qPainterPath;
  for (quint32 qGlyphIndex : qGlyphIndices) {
    qPainterPath  = qRawFont.pathForGlyph(qGlyphIndex);
  }
  // done
  return qPainterPath;
}

The first result was a Chinese glyph until I realized that the glyph index has nothing to do with the Unicode code point. (I had used 0x2620 (the Unicode code point) as glyph index.) Thus, I introduced the conversion with Snapshot of testQRawFontQPainterPath

There is for sure a similarity though the rendering might not be perfect.

CodePudding user response:

I must admit that all the guessing in my comments could have been prevented as the doc. about QPainterPath mentions explicitly how it works:

Snapshot of testQPainterPath (Original)

This is the output for the original sample (taken from Qt doc.).

Snapshot of testQPainterPath (Dumped)

This is the output for the source code dumped in the lower left text view and copied into the source.

(Some kind of bootstrap? ;-))

  •  Tags:  
  • c qt
  • Related