RS_Block* RS_Font::generateLffFont(const QString& ch){ if(rawLffFontList.contains(ch) == false ){ RS_DEBUG->print("RS_Font::generateLffFont(QChar %s ) : can not find the letter in given lff font file",qPrintable(ch)); return nullptr; } // create new letter: RS_FontChar* letter = new RS_FontChar(nullptr, ch, RS_Vector(0.0, 0.0)); // Read entities of this letter: QStringList vertex; QStringList coords; QStringList fontData=rawLffFontList[ch]; QString line; while(fontData.isEmpty() == false) { line = fontData.takeFirst(); if (line.isEmpty()) { continue; } // Defined char: if (line.at(0)=='C') { line.remove(0,1); int uCode = line.toInt(nullptr, 16); QChar ch = QChar(uCode); RS_Block* bk = letterList.find(ch); if (!bk && rawLffFontList.contains(ch)) { generateLffFont(ch); bk = letterList.find(ch); } if (bk) { RS_Entity* bk2 = bk->clone(); bk2->setPen(RS_Pen(RS2::FlagInvalid)); bk2->setLayer(nullptr); letter->addEntity(bk2); } } //sequence: else { vertex = line.split(';', QString::SkipEmptyParts); //at least is required two vertex if (vertex.size()<2) continue; RS_Polyline* pline = new RS_Polyline(letter, RS_PolylineData()); pline->setPen(RS_Pen(RS2::FlagInvalid)); pline->setLayer(nullptr); for (int i = 0; i < vertex.size(); ++i) { double x1, y1; double bulge = 0; coords = vertex.at(i).split(',', QString::SkipEmptyParts); //at least X,Y is required if (coords.size()<2) continue; x1 = coords.at(0).toDouble(); y1 = coords.at(1).toDouble(); //check presence of bulge if (coords.size() == 3 && coords.at(2).at(0) == QChar('A')){ QString bulgeStr = coords.at(2); bulge = bulgeStr.remove(0,1).toDouble(); } pline->setNextBulge(bulge); pline->addVertex(RS_Vector(x1, y1), bulge); } letter->addEntity(pline); } } if (letter->isEmpty()) { delete letter; return nullptr; } else { letter->calculateBorders(); letterList.add(letter); return letter; } }
void RS_Font::readCXF(QString path) { QString line; QFile f(path); f.open(QIODevice::ReadOnly); QTextStream ts(&f); // Read line by line until we find a new letter: while (!ts.atEnd()) { line = ts.readLine(); if (line.isEmpty()) continue; // Read font settings: if (line.at(0)=='#') { QStringList lst = ( line.right(line.length()-1) ).split(':', QString::SkipEmptyParts); QStringList::Iterator it3 = lst.begin(); // RVT_PORT sometimes it happens that the size is < 2 if (lst.size()<2) continue; QString identifier = (*it3).trimmed(); it3++; QString value = (*it3).trimmed(); if (identifier.toLower()=="letterspacing") { letterSpacing = value.toDouble(); } else if (identifier.toLower()=="wordspacing") { wordSpacing = value.toDouble(); } else if (identifier.toLower()=="linespacingfactor") { lineSpacingFactor = value.toDouble(); } else if (identifier.toLower()=="author") { authors.append(value); } else if (identifier.toLower()=="name") { names.append(value); } else if (identifier.toLower()=="encoding") { ts.setCodec(QTextCodec::codecForName(value.toLatin1())); encoding = value; } } // Add another letter to this font: else if (line.at(0)=='[') { // uniode character: QChar ch; // read unicode: QRegExp regexp("[0-9A-Fa-f]{4,4}"); regexp.indexIn(line); QString cap = regexp.cap(); if (!cap.isNull()) { int uCode = cap.toInt(nullptr, 16); ch = QChar(uCode); } // read UTF8 (LibreCAD 1 compatibility) else if (line.indexOf(']')>=3) { int i = line.indexOf(']'); QString mid = line.mid(1, i-1); ch = QString::fromUtf8(mid.toLatin1()).at(0); } // read normal ascii character: else { ch = line.at(1); } // create new letter: RS_FontChar* letter = new RS_FontChar(nullptr, ch, RS_Vector(0.0, 0.0)); // Read entities of this letter: QString coordsStr; QStringList coords; QStringList::Iterator it2; do { line = ts.readLine(); if (line.isEmpty()) { continue; } coordsStr = line.right(line.length()-2); // coords = QStringList::split(',', coordsStr); coords = coordsStr.split(',', QString::SkipEmptyParts); it2 = coords.begin(); // Line: if (line.at(0)=='L') { double x1 = (*it2++).toDouble(); double y1 = (*it2++).toDouble(); double x2 = (*it2++).toDouble(); double y2 = (*it2).toDouble(); RS_Line* line = new RS_Line{letter, {{x1, y1}, {x2, y2}}}; line->setPen(RS_Pen(RS2::FlagInvalid)); line->setLayer(nullptr); letter->addEntity(line); } // Arc: else if (line.at(0)=='A') { double cx = (*it2++).toDouble(); double cy = (*it2++).toDouble(); double r = (*it2++).toDouble(); double a1 = RS_Math::deg2rad((*it2++).toDouble()); double a2 = RS_Math::deg2rad((*it2).toDouble()); bool reversed = (line.at(1)=='R'); RS_ArcData ad(RS_Vector(cx,cy), r, a1, a2, reversed); RS_Arc* arc = new RS_Arc(letter, ad); arc->setPen(RS_Pen(RS2::FlagInvalid)); arc->setLayer(nullptr); letter->addEntity(arc); } } while (!line.isEmpty()); if (letter->isEmpty()) { delete letter; } else { letter->calculateBorders(); letterList.add(letter); } } } f.close(); }