void RS_ActionDrawLineRectangle::trigger() {
	RS_PreviewActionInterface::trigger();

	RS_Polyline* polyline = new RS_Polyline(container);

	// create and add rectangle:
	polyline->addVertex(pPoints->corner1);
	polyline->setLayerToActive();
	polyline->setPenToActive();
	polyline->addVertex({pPoints->corner2.x, pPoints->corner1.y});
	polyline->addVertex(pPoints->corner2);
	polyline->addVertex({pPoints->corner1.x, pPoints->corner2.y});
	polyline->setClosed(true);
	polyline->endPolyline();
	container->addEntity(polyline);

    // upd. undo list:
    if (document) {
        document->startUndoCycle();
		document->addUndoable(polyline);
        document->endUndoCycle();
    }

    // upd. view
	graphicView->redraw(RS2::RedrawDrawing);
	graphicView->moveRelativeZero(pPoints->corner2);
}
void Plugin_Entity::updatePolylineData(QList<Plug_VertexData> *data){
    if (entity == NULL) return;
    RS2::EntityType et = entity->rtti();
    if (et != RS2::EntityPolyline) return;
    if (data->size()<2) return; //At least two vertex
    RS_Vector vec(false);
    RS_Polyline *pl = static_cast<RS_Polyline*>(entity);
//    vec.x = data->at(0).point.x();
//    vec.y = data->at(0).point.y();
    pl->clear();
    pl->setEndpoint(vec);
    pl->setStartpoint(vec);
    vec.valid = true;
    for (int i = 0; i < data->size(); ++i) {
        vec.x = data->at(i).point.x();
        vec.y = data->at(i).point.y();
        pl->addVertex(vec, data->at(i).bulge );
    }


}
bool RS_ActionPolylineEquidistant::makeContour() {
	if (container==NULL) {
		RS_DEBUG->print("RS_ActionPolylineEquidistant::makeContour: no valid container",
						RS_Debug::D_WARNING);
		return false;
	}

	RS_Vector offset(false);
        QList<RS_Entity*> addList;

	if (document!=NULL) {
		document->startUndoCycle();
	}
	double neg = 1.0;
	if(bRightSide)
		neg = -1.0;
	// Create new entites
	RS_Line line1(NULL, RS_LineData(RS_Vector(true), RS_Vector(true)));
	RS_Line line2(NULL, RS_LineData(RS_Vector(true), RS_Vector(true)));
	for (int num=1;
			num<=number || (number==0 && num<=1);
			num++) {
		RS_Polyline* newPolyline = new RS_Polyline(container);
		newPolyline->setClosed(((RS_Polyline*)originalEntity)->isClosed());
//		newPolyline->setSelected((RS_Polyline*)originalEntity)->isSelected());
		newPolyline->setLayer(((RS_Polyline*)originalEntity)->getLayer());
		newPolyline->setPen(((RS_Polyline*)originalEntity)->getPen());

		bool first = true;
		RS_Entity* lastEntity = ((RS_Polyline*)originalEntity)->lastEntity();
		for (RS_Entity* en=((RS_Polyline*)originalEntity)->firstEntity(); en!=NULL; en=((RS_Polyline*)originalEntity)->nextEntity()) {
			double bulge = 0.0;
			if (en->rtti()==RS2::EntityArc) {
				double r0 = ((RS_Arc*)en)->getRadius();
				double r = r0 - dist*neg;
				if(r < 0)
					break;
				((RS_Arc*)en)->setRadius(r);
				bulge = ((RS_Arc*)en)->getBulge();
				((RS_Arc*)en)->setRadius(r0);
			} else {
				bulge = 0.0;
			}
			RS_Vector v1 = ((RS_AtomicEntity*)en)->getStartpoint();
			RS_Vector v2 = ((RS_AtomicEntity*)en)->getEndpoint();
			offset.set(dist * cos(v1.angleTo(v2)+M_PI*0.5*neg), dist * sin(v1.angleTo(v2)+M_PI*0.5*neg));
			v1.move(offset*num);
			v2.move(offset*num);
			if (first) {
				line1.setStartpoint(v1);
				line1.setEndpoint(v2);
				if(newPolyline->isClosed()){
					RS_Vector v01 = ((RS_AtomicEntity*)lastEntity)->getStartpoint();
					RS_Vector v02 = ((RS_AtomicEntity*)en)->getStartpoint();
					offset.set(dist * cos(v01.angleTo(v02)+M_PI*0.5*neg), dist * sin(v01.angleTo(v02)+M_PI*0.5*neg));
					v01.move(offset*num);
					v02.move(offset*num);
					line2.setStartpoint(v01);
					line2.setEndpoint(v02);
					RS_VectorSolutions vsol = RS_Information::getIntersection(&line1, &line2, false);
					v1 = vsol.get(0);
				}
				newPolyline->setStartpoint(v1);
				newPolyline->addVertex(v1, bulge);
				first = false;
			}else{
				line2.setStartpoint(v1);
				line2.setEndpoint(v2);
				RS_VectorSolutions vsol = RS_Information::getIntersection(&line1, &line2, false);
				RS_Vector v = vsol.get(0);
				newPolyline->addVertex(v, bulge);
				newPolyline->setEndpoint(v);
				line1.setStartpoint(v1);
				line1.setEndpoint(v2);
				if (en==lastEntity/* && newPolyline->isClosed()==false*/){
					newPolyline->addVertex(v2, bulge);
				}
			}
		}
		double bulge = lastEntity->rtti() == RS2::EntityArc? ((RS_Arc*)lastEntity)->getBulge():0.0;
//		newPolyline->setNextBulge(bulge);
		newPolyline->endPolyline();
		container->addEntity(newPolyline);
		document->addUndoable(newPolyline);
	}
	if (document!=NULL) {
		document->endUndoCycle();
	}

	if (graphicView!=NULL) {
		graphicView->redraw();
	}

	return true;
}
/**
 * Rearranges the lines, arcs or opened polylines entities
 *  in this container, non-recoursive.
 * document can not be null
 *
 * @retval true contour are closed
 * @retval false if the contour is not closed
 *
 * @author Rallaz
 */
bool RS_ActionPolylineSegment::convertPolyline(RS_Entity* selectedEntity) {

    RS_DEBUG->print("RS_ActionPolylineSegment::convertPolyline");

    QList<RS_Entity*> remaining;
    QList<RS_Entity*> completed;
    RS_Vector start = selectedEntity->getStartpoint();
    RS_Vector end = selectedEntity->getEndpoint();
    completed.append(selectedEntity);
//get list with useful entities
    for (uint i=0; i<container->count(); ++i) {
        RS_Entity* e1 = container->entityAt(i);
        if (e1->isLocked() || !e1->isVisible() || e1 == selectedEntity) continue;
        if (e1->rtti()==RS2::EntityLine || e1->rtti()==RS2::EntityArc
                || e1->rtti()==RS2::EntityPolyline) {
            if (targetEntity->rtti()==RS2::EntityPolyline && ((RS_Polyline*)targetEntity)->isClosed())
                continue;
            if (e1 == selectedEntity)
                continue;
            remaining.append(e1);
        }
    }

    // find all connected entities:
    bool done = true;
    do {
        done = true;
        for (int i=(remaining.size() -1) ; i>=0; --i) {
            RS_Entity* e=remaining.at(i);
            if (e->getEndpoint().distanceTo(start) < 1.0e-4) {
                completed.prepend( e);
                start = e->getStartpoint();
                remaining.removeAt(i);
                done = false;
            } else if (e->getStartpoint().distanceTo(start) < 1.0e-4) {
                completed.prepend( e);
                start = e->getEndpoint();
                remaining.removeAt(i);
                done = false;
            } else if (e->getEndpoint().distanceTo(end) < 1.0e-4) {
                completed.append( e);
                end = e->getStartpoint();
                remaining.removeAt(i);
                done = false;
            } else if (e->getStartpoint().distanceTo(end) < 1.0e-4) {
                completed.append( e);
                end = e->getEndpoint();
                remaining.removeAt(i);
                done = false;
            }
        }
    } while (!done);

//cleanup for no more needed list
    remaining.clear();

    bool closed = false;
    if (document!=NULL) {
        document->startUndoCycle();

        bool revert = false;
        double bulge = 0.0;
        if (end.distanceTo(start) < 1.0e-4)
            closed = true;

        RS_Polyline* newPolyline = new RS_Polyline(container, RS_PolylineData(RS_Vector(false), RS_Vector(false), closed));
        newPolyline->setLayerToActive();
        newPolyline->setPenToActive();

//complete polyline
        end =start;
        while (!completed.isEmpty()) {
            RS_Entity* e2= completed.takeFirst();
            e2->setUndoState(true);
            document->addUndoable(e2);
            if (e2->getStartpoint().distanceTo(end) < 1.0e-4) {
                revert = false;
                start = e2->getStartpoint();
                end = e2->getEndpoint();
            } else {
                revert = true;
                start = e2->getEndpoint();
                end = e2->getStartpoint();
            }
            if (e2->rtti()==RS2::EntityArc) {
                if (revert)
                    bulge = ((RS_Arc*)e2)->getBulge()*-1;
                else
                    bulge = ((RS_Arc*)e2)->getBulge();
            } else
                bulge = 0.0;
            if (e2->rtti()==RS2::EntityPolyline) {
                newPolyline->addVertex(start, bulge);
                end = appendPol(newPolyline, (RS_Polyline*)e2, revert);
            } else
                newPolyline->addVertex(start, bulge);
        }

        if (closed)
            newPolyline->setClosed(true);
        else
            newPolyline->addVertex(end, bulge);
        newPolyline->endPolyline();
        container->addEntity(newPolyline);

        if (graphicView!=NULL) {
                graphicView->drawEntity(newPolyline);
        }

        document->addUndoable(newPolyline);
        document->endUndoCycle();
    }
    RS_DEBUG->print("RS_ActionPolylineSegment::convertPolyline: OK");
    return closed;
}
Exemple #5
0
/**
 * Loads the font into memory.
 *
 * @retval true font was already loaded or is loaded now.
 * @retval false font could not be loaded.
 */
bool RS_Font::loadFont() {
    RS_DEBUG->print("RS_Font::loadFont");

    if (loaded) {
        return true;
    }

    QString path;

    // Search for the appropriate font if we have only the name of the font:
    if (!fileName.toLower().contains(".cxf") &&
            !fileName.toLower().contains(".lff")) {
        QStringList fonts = RS_SYSTEM->getNewFontList();
#if QT_VERSION < 0x040500
        emu_qt45_QList_append(fonts, RS_SYSTEM->getFontList());
#else
        fonts.append(RS_SYSTEM->getFontList());
#endif

        QFileInfo file;
        for (QStringList::Iterator it = fonts.begin();
             it!=fonts.end();
             it++) {

            if (QFileInfo(*it).baseName().toLower()==fileName.toLower()) {
                path = *it;
                break;
            }
        }
    }

    // We have the full path of the font:
    else {
        path = fileName;
    }

    // No font paths found:
    if (path.isEmpty()) {
        RS_DEBUG->print(RS_Debug::D_WARNING,
                        "RS_Font::loadFont: No fonts available.");
        return false;
    }

    // Open cxf file:
    QFile f(path);
    if (!f.open(QIODevice::ReadOnly)) {
        RS_DEBUG->print(RS_Debug::D_WARNING,
                        "RS_Font::loadFont: Cannot open font file: %s",
                        path.toLatin1().data());
        return false;
    } else {
        RS_DEBUG->print("RS_Font::loadFont: "
                        "Successfully opened font file: %s",
                        path.toLatin1().data());
    }
    f.close();

    if (path.contains(".cxf"))
        readCXF(path);
    if (path.contains(".lff"))
        readLFF(path);

    RS_Block* bk = letterList.find(QChar(0xfffd));
	if (!bk) {
        // create new letter:
		RS_FontChar* letter = new RS_FontChar(nullptr, QChar(0xfffd), RS_Vector(0.0, 0.0));
        RS_Polyline* pline = new RS_Polyline(letter, RS_PolylineData());
        pline->setPen(RS_Pen(RS2::FlagInvalid));
		pline->setLayer(nullptr);
        pline->addVertex(RS_Vector(1, 0), 0);
        pline->addVertex(RS_Vector(0, 2), 0);
        pline->addVertex(RS_Vector(1, 4), 0);
        pline->addVertex(RS_Vector(2, 2), 0);
        pline->addVertex(RS_Vector(1, 0), 0);
        letter->addEntity(pline);
        letter->calculateBorders();
        letterList.add(letter);
    }

    loaded = true;

    RS_DEBUG->print("RS_Font::loadFont OK");

    return true;
}
Exemple #6
0
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;
    }
}
bool RS_ActionPolylineEquidistant::makeContour() {
    if (container==NULL) {
        RS_DEBUG->print("RS_ActionPolylineEquidistant::makeContour: no valid container",
                        RS_Debug::D_WARNING);
        return false;
    }

    RS_Polyline* originalPolyline = (RS_Polyline*)originalEntity;
//create a list of entities to offset without length = 0
    QList<RS_Entity*> entities;
    for (RS_Entity* en=originalPolyline->firstEntity(); en!=NULL; en=originalPolyline->nextEntity()) {
        if (en->getLength() > 1.0e-12)
            entities.append(en);
    }
    if (entities.isEmpty()) {
        return false;
    }
    if (document!=NULL) {
        document->startUndoCycle();
    }
    double neg = 1.0;
    if(bRightSide)
        neg = -1.0;

    // Create new helper entities
    RS_Line line1(NULL, RS_LineData(RS_Vector(true), RS_Vector(true)));//current line
    RS_Line lineFirst(NULL, RS_LineData(RS_Vector(true), RS_Vector(true)));//previous line
    RS_Arc arc1(NULL, RS_ArcData(RS_Vector(true), 0,0,0,false));//current arc
    RS_Arc arcFirst(NULL, RS_ArcData(RS_Vector(true), 0,0,0,false));//previous arc

    for (int num=1; num<=number || (number==0 && num<=1); num++) {
        RS_Polyline* newPolyline = new RS_Polyline(container);
        newPolyline->setLayer(((RS_Polyline*)originalEntity)->getLayer());
        newPolyline->setPen(((RS_Polyline*)originalEntity)->getPen());

        bool first = true;
        bool closed = originalPolyline->isClosed();
        double bulge = 0.0;
        RS_Entity* en;
        RS_Entity* prevEntity = entities.last();
        RS_Entity* currEntity;
        for (int i = 0; i < entities.size(); ++i) {
            en = entities.at(i);
            RS_Vector v(false);
            if (en->rtti()==RS2::EntityArc) {
                currEntity = &arc1;
                calculateOffset(currEntity, en, dist*num*neg);
                bulge = arc1.getBulge();
            } else {
                currEntity = &line1;
                bulge = 0.0;
                calculateOffset(currEntity, en, dist*num*neg);
            }
            if (first) {
                if (closed) {
                    if (prevEntity->rtti()==RS2::EntityArc) {
                        prevEntity = calculateOffset(&arcFirst, prevEntity, dist*num*neg);
                    } else {
                        prevEntity = calculateOffset(&lineFirst, prevEntity, dist*num*neg);
                    }
                    v = calculateIntersection(prevEntity, currEntity);
                }
                if (!v.valid) {
                    v = currEntity->getStartpoint();
                    closed = false;
                } else if (currEntity->rtti()==RS2::EntityArc) {
                    //update bulge
                    arc1.setAngle1(arc1.getCenter().angleTo(v));
                    arc1.calculateEndpoints();
                    bulge = arc1.getBulge();
                }
                first = false;
                if (!prevEntity) break; //prevent crash if not exist offset for prevEntity
            } else {
                v = calculateIntersection(prevEntity, currEntity);
                if (!v.valid) {
                    v= prevEntity->getEndpoint();
                    double dess = currEntity->getStartpoint().distanceTo(prevEntity->getEndpoint());
                    if (dess > 1.0e-12) {
                        newPolyline->addVertex(v, bulge);
                        prevEntity = NULL;
                        break;
                    }
                }
                double startAngle = prevEntity->getStartpoint().angleTo(prevEntity->getEndpoint());
                if (prevEntity->rtti()==RS2::EntityArc) {
                    arcFirst.setAngle2(arcFirst.getCenter().angleTo(v));
                    arcFirst.calculateEndpoints();
                    newPolyline->setNextBulge(arcFirst.getBulge());
                }
                //check if the entity are reverted
                if (abs (prevEntity->getStartpoint().angleTo(prevEntity->getEndpoint())- startAngle) > 0.785) {
                    prevEntity = newPolyline->lastEntity();
                    RS_Vector v0 = calculateIntersection(prevEntity, currEntity);
                    if (prevEntity->rtti()==RS2::EntityArc) {
                        ((RS_Arc*)prevEntity)->setAngle2(arcFirst.getCenter().angleTo(v0));
                        ((RS_Arc*)prevEntity)->calculateEndpoints();
                        newPolyline->setNextBulge( ((RS_Arc*)prevEntity)->getBulge() );
                    } else {
                        ((RS_Line*)prevEntity)->setEndpoint(v0);
                        newPolyline->setNextBulge( 0.0 );
                    }
                    newPolyline->setEndpoint(v0);
                }
                if (currEntity->rtti()==RS2::EntityArc) {
                    arc1.setAngle1(arc1.getCenter().angleTo(v));
                    arc1.calculateEndpoints();
                    bulge = arc1.getBulge();
                } else
                    bulge = 0.0;
            }
            if (prevEntity) {
                newPolyline->addVertex(v, bulge, false);
                if (currEntity->rtti()==RS2::EntityArc) {
                    arcFirst.setData(arc1.getData());
                    arcFirst.calculateEndpoints();
                    prevEntity = &arcFirst;
                } else {
                    lineFirst.setStartpoint(line1.getStartpoint());
                    lineFirst.setEndpoint(line1.getEndpoint());
                    prevEntity = &lineFirst;
                }
            }
        }
        //properly terminated, check closed
        if (prevEntity) {
            if (closed) {
                if (currEntity->rtti()==RS2::EntityArc) {
                    arc1.setAngle2(arc1.getCenter().angleTo(newPolyline->getStartpoint()));
                    arc1.calculateEndpoints();
                    newPolyline->setNextBulge(arc1.getBulge());
                    bulge = arc1.getBulge();
                }
                newPolyline->setClosed(true, bulge);
            } else {
                newPolyline->addVertex(currEntity->getEndpoint(), bulge);
            }
        }
        if (!newPolyline->isEmpty()) {
            container->addEntity(newPolyline);
            document->addUndoable(newPolyline);
        }
    }
    if (document!=NULL) {
        document->endUndoCycle();
    }

    if (graphicView!=NULL) {
        graphicView->redraw();
    }

    return true;
}
/**
 * Rearranges the atomic entities in this container in a way that connected
 * entities are stored in the right order and direction.
 * Non-recoursive. Only affects atomic entities in this container.
 *
 * @retval true all contours were closed
 * @retval false at least one contour is not closed
 */
bool RS_ActionPolylineSegment::convertPolyline(RS_Entity* selectedEntity) {

        RS_DEBUG->print("RS_ActionPolylineSegment::convertPolyline");

        RS_Vector current(false);
        RS_Vector start(false);
        RS_Vector end(false);
        RS_EntityContainer tmp;

        bool closed = true;

        int pos = container->findEntity(selectedEntity);
        RS_Entity* e1=container->entityAt(pos);
        if (!e1) return false;

        if (document!=NULL) {
                document->startUndoCycle();
        }
        if (document!=NULL) {
                if (e1!=NULL && e1->isEdge() && !e1->isContainer() &&
                                        !e1->isProcessed()) {

                        RS_AtomicEntity* ce = (RS_AtomicEntity*)e1;

///////////////////////////////////////////////////
                        ce->setUndoState(true);
                        document->addUndoable(ce);
///////////////////////////////////////////////////

                        // next contour start:
                        ce->setProcessed(true);
                        tmp.addEntity(ce->clone());
                        current = ce->getStartpoint();
                        end = ce->getEndpoint();

                        // find first connected entities:
                        for (int ei=pos-1; ei>=0; --ei) {
                                RS_Entity* e2=container->entityAt(ei);

                                if (e2!=NULL && e2->isEdge() && !e2->isContainer() &&
                                                !e2->isProcessed()) {

                                        RS_AtomicEntity* e = (RS_AtomicEntity*)e2;
///////////////////////////////////////////////////
                                        e->setUndoState(true);
                                        document->addUndoable(e);
///////////////////////////////////////////////////
                                        if (e->getEndpoint().distanceTo(current) <
                                                        1.0e-4) {
                                                e->setProcessed(true);
                                                tmp.insertEntity(0,e->clone());
                                                current = e->getStartpoint();
                                        } else if (e->getStartpoint().distanceTo(current) <
                                                           1.0e-4) {
                                                e->setProcessed(true);
                                                RS_AtomicEntity* cl = (RS_AtomicEntity*)e->clone();
                                                cl->reverse();
                                                tmp.insertEntity(0,cl);
                                                current = cl->getStartpoint();
                                        }else
                                                break;
                                }
                        }

                        if (current.distanceTo(end)>1.0e-4) {
                                closed = false;
                        }

                        current = ce->getEndpoint();
                        start = ce->getStartpoint();
                        // find last connected entities:
                        for (uint ei=pos+1; ei<container->count(); ++ei) {
                                RS_Entity* e2=container->entityAt(ei);
///////////////////////////////////////////////////
                                e2->setUndoState(true);
                                document->addUndoable(e2);
///////////////////////////////////////////////////
                                if (e2!=NULL && e2->isEdge() && !e2->isContainer() &&
                                                !e2->isProcessed()) {
                                        RS_AtomicEntity* e = (RS_AtomicEntity*)e2;
                                        if (e->getStartpoint().distanceTo(current) <
                                                        1.0e-4) {
                                                e->setProcessed(true);
                                                tmp.addEntity(e->clone());
                                                current = e->getEndpoint();
                                        } else if (e->getEndpoint().distanceTo(current) <
                                                           1.0e-4) {
                                                e->setProcessed(true);
                                                RS_AtomicEntity* cl = (RS_AtomicEntity*)e->clone();
                                                cl->reverse();
                                                tmp.addEntity(cl);
                                                current = cl->getEndpoint();
                                        }else
                                                break;
                                }
                        }
                        if (current.distanceTo(start)>1.0e-4) {
                                closed = false;
                        }
                }
        }
        if (document!=NULL) {
                document->endUndoCycle();
        }

        RS_Polyline* newPolyline = new RS_Polyline(container, RS_PolylineData(RS_Vector(false), RS_Vector(false), closed));
        newPolyline->setLayerToActive();
        newPolyline->setPenToActive();
        // add new polyline:
        bool first = true;
        RS_Entity* lastEntity = tmp.lastEntity();
        for (RS_Entity* en=tmp.firstEntity(); en!=NULL; en=tmp.nextEntity()) {
                en->setProcessed(false);
                double bulge = 0.0;
                if (en->rtti()==RS2::EntityArc) {
                        bulge = ((RS_Arc*)en)->getBulge();
                } else {
                        bulge = 0.0;
                }
                if (first) {
                        newPolyline->setNextBulge(bulge);
                        newPolyline->addVertex(((RS_AtomicEntity*)en)->getStartpoint());
                        first = false;
                }
                if (en!=lastEntity || closed==false){
                        newPolyline->setNextBulge(bulge);
                        newPolyline->addVertex(((RS_AtomicEntity*)en)->getEndpoint());
                }
        }
        double bulge = lastEntity->rtti() == RS2::EntityArc? ((RS_Arc*)lastEntity)->getBulge():0.0;
        newPolyline->setNextBulge(bulge);
        newPolyline->endPolyline();
        container->addEntity(newPolyline);

        if (graphicView!=NULL) {
                graphicView->drawEntity(newPolyline);
        }

        if (document!=NULL) {
                document->startUndoCycle();
                document->addUndoable(newPolyline);
                document->endUndoCycle();
        }
        RS_DEBUG->print("RS_ActionPolylineSegment::convertPolyline: OK");
        return closed;
}
Exemple #9
0
void RS_Font::readLFF(QString path) {
    QString line;
    QFile f(path);
    encoding = "UTF-8";
    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.remove(0,1).split(':', QString::SkipEmptyParts);
            //if size is < 2 is a comentary not parameter
            if (lst.size()<2)
                continue;

            QString identifier = lst.at(0).trimmed();
            QString value = lst.at(1).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()=="license") {
                fileLicense = 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(NULL, 16);
                ch = QChar(uCode);
            }
            // only unicode allowed
            else {
                continue;
            }

            // create new letter:
            RS_FontChar* letter =
                new RS_FontChar(NULL, ch, RS_Vector(0.0, 0.0));

            // Read entities of this letter:
            QStringList vertex;
            QStringList coords;

            do {
                line = ts.readLine();

                if (line.isEmpty()) {
                    continue;
                }

                // Defined char:
                if (line.at(0)=='C') {
                    line.remove(0,1);
                    int uCode = line.toInt(NULL, 16);
                    QChar ch = QChar(uCode);
                    RS_Block* bk = letterList.find(ch);
                    if (bk != NULL) {
                        RS_Entity* bk2 = bk->clone();
                        bk2->setPen(RS_Pen(RS2::FlagInvalid));
                        bk2->setLayer(NULL);
                        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(NULL);
                    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);
                }

            } while (!line.isEmpty());

            letter->calculateBorders();
            letterList.add(letter);
        }
    }
    f.close();
}